find all partially grounded rules such as

equivalent(A,B) :- eq_from_shared_xref(A,B,'UBERON',z,x)

A and B are always unground, but remaining arguments may be a mix

*/

   14:- module(rule_inference,
   15          [equivalent/2,
   16           ground_rules/1,
   17           ground_rules/2]).   18
   19:- use_module(library(rdf_matcher)).   20
   21
   22% assume first two args are class pair
   23erule(eq_from_match/7).
   24erule(eq_from_shared_xref/5).
   25
   26
   27postulated_rule(equivalent(A,B),Body,P-Rest2,Opts) :-
   28                erule(P/Ar),
   29                functor(Body,P,Ar),
   30                Body =.. [P,A,B|Rest],
   31                (   option(ontA(OntA),Opts)
   32                ->  reverse(Rest,[_,OntA|_])
   33                ;   true),
   34                (   option(ontB(OntB),Opts)
   35                ->  reverse(Rest,[OntB|_])
   36                ;   true),
   37                debug(rdf_matcher,'Candidate Rule: ~q :- ~q',[eq(A,B),Body]),        
   38                subset_nd(Rest,Rest2),
   39                debug(rdf_matcher,'PRule: ~w Body=~q // tmpl= ~q',[P,Body,Rest2]).
   40
   41
   42
   43subset_nd([],[]).
   44subset_nd([H|T],[H|T2]) :-
   45        subset_nd(T,T2).
   46subset_nd([H|T],['__ANY__'|T2]) :-
   47        var(H),
   48        subset_nd(T,T2).
   49
   50
   51
   52ground_rules(Rules) :-
   53        ground_rules(Rules,[]).
   54ground_rules(Rules, Opts) :-
   55        debug(rdf_matcher,'Grounding rules',[]),
   56        setof(FreeVars,H^B^(postulated_rule(H,B,FreeVars,Opts),B),AllFreeVars),
   57        length(AllFreeVars, Num),
   58        debug(rdf_matcher,'Finding ground rules;  freevars = ~d',[Num]),
   59        setof((H:-B),BFree^(postulated_rule(H,B,BFree,Opts),member(BFree,AllFreeVars)),Rules).
   60
   61/*
   62genrule(equivalent(A,B),Body,Opts) :-
   63                erule(P/Ar),
   64                functor(Body,P,Ar),
   65                Body =.. [P,A,B|Rest],
   66                (   option(ontA(OntA),Opts)
   67                ->  reverse(Rest,[_,OntA|_])
   68                ;   true),
   69                (   option(ontB(OntB),Opts)
   70                ->  reverse(Rest,[OntB|_])
   71                ;   true),
   72                debug(rdf_matcher,'Candidate Rule:~q',[Body]).
   73
   74ground_rule(Rule) :-
   75        postulated_rule(H,B,FreeVars,Opts),
   76        B,
   77*/