1193323Sed 2193323Sed% File : METUTL.PL 3193323Sed% Author : R.A.O'Keefe 4193323Sed% Updated: 15 September 1984 5193323Sed% Purpose: meta-logical operations as described in my note 6193323Sed 7193323Sed:- module(metutl). % SEPIA header 8193323Sed:- local unify/3. 9193323Sed:- export 10193323Sed% compound/1, % is a Sepia builtin 11193323Sed copy/2, % use copy_term/2 instead 12193323Sed ground/1, % better use \+ nonground 13193323Sed occurs_check/2, % better use \+ occurs 14193323Sed occurs_in/2, % use occurs/2 instead 15193323Sed simple/1, 16193323Sed subsumes/2, 17193323Sed subsumes_chk/2, 18193323Sed subterm/2, 19193323Sed unify/2, 20193323Sed variables_of/2, 21193323Sed variant/2, % less restricted than the builtin 22193323Sed var_member_chk/2. 23249423Sdim 24249423Sdim:- lib(numbervars). 25249423Sdim 26198090Srdivacky/* the declarations are partially wrong for SEPIA 27193323Sed:- mode 28198892Srdivacky copy(+, ?), 29193323Sed ground(+), 30249423Sdim ground(+, +), 31193323Sed occurs_check(+, ?), 32198892Srdivacky occurs_check(+, +, ?), 33193323Sed occurs_in(+, +), 34193323Sed occurs_in(+, +, +), 35193323Sed subterm(+, ?), 36193323Sed subterm(+, +, ?), 37249423Sdim subsumes(+, +), 38263508Sdim subsumes(+, +, +), 39239462Sdim subsumes(+, +, +, +), 40193323Sed subsumes_chk(+, +), 41239462Sdim unify(+, +), 42193323Sed unify(+, +, +), 43193323Sed var_member_chk(+, +), 44193323Sed variables_of(+, -), 45193323Sed variables_of(+, +, -), 46193323Sed variables_of(+, +, +, -), 47193323Sed variant(+, +). 48212904Sdim*/ 49193323Sed 50239462Sdim 51239462Sdim% compound(Term) :- 52239462Sdim% nonvar(Term), % not a variable 53239462Sdim% functor(Term, _, Arity), 54239462Sdim% Arity > 0. % not atomic 55239462Sdim 56239462Sdim 57239462Sdim% simple(?T) 58239462Sdim% True if T is an uninstantiated variable or an atom. 59193323Sed 60193323Sedsimple(Term) :- 61193323Sed var(Term), !. % is a variable 62206083Srdivackysimple(Term) :- % -or- 63193323Sed atomic(Term). % is a number or an atom. 64239462Sdim 65239462Sdim 66193323Sed% ground(+Term) 67234353Sdim% True if Term is ground, that is, it contains no 68234353Sdim% uninstantiated variables. 69234353Sdim 70234353Sdimground(Term) :- 71234353Sdim nonvar(Term), 72234353Sdim functor(Term, _, N), 73234353Sdim ground(N, Term). 74234353Sdim 75234353Sdimground(0, _) :- 76234353Sdim !. 77234353Sdim 78234353Sdimground(N, Term) :- 79234353Sdim arg(N, Term, Arg), 80234353Sdim ground(Arg), 81234353Sdim M is N-1, !, 82234353Sdim ground(M, Term). 83234353Sdim 84234353Sdim 85234353Sdim% occurs_in(-Var,+Term) 86234353Sdim% True if the variable Var occurs somewhere in Term 87234353Sdim% For instance 88234353Sdim% occurs_in(X,foo(X)) is true. 89234353Sdim 90234353Sdimoccurs_in(Var, Term) :- occurs(Var, Term). % SEPIA 91234353Sdim 92234353Sdim% occurs_in(Var, Term) :- 93263508Sdim% var(Term), 94263508Sdim% !, 95263508Sdim% Var == Term. 96239462Sdim% 97193323Sed% occurs_in(Var, Term) :- 98193323Sed% functor(Term, _, N), 99239462Sdim% occurs_in(N, Var, Term). 100239462Sdim% 101193323Sed% occurs_in(N, Var, Term) :- 102204642Srdivacky% arg(N, Term, Arg), 103263508Sdim% occurs_in(Var, Arg), 104204642Srdivacky% !. 105239462Sdim% 106263508Sdim% occurs_in(N, Var, Term) :- 107263508Sdim% N > 1, 108263508Sdim% M is N-1, 109263508Sdim% occurs_in(M, Var, Term). 110193323Sed 111193323Sed 112239462Sdim% subterm(+S,+T) 113239462Sdim% true if S is a subterm of T (including if S = T) 114193323Sed 115193323Sedsubterm(Term, Term). 116239462Sdim 117239462Sdimsubterm(SubTerm, Term) :- 118193323Sed nonvar(Term), 119193323Sed functor(Term, _, N), 120239462Sdim subterm(N, SubTerm, Term). 121263508Sdim 122263508Sdimsubterm(N, SubTerm, Term) :- 123263508Sdim arg(N, Term, Arg), 124263508Sdim subterm(SubTerm, Arg). 125263508Sdim 126193323Sedsubterm(N, SubTerm, Term) :- 127207618Srdivacky N > 1, 128263508Sdim M is N-1, 129263508Sdim subterm(M, SubTerm, Term). 130263508Sdim 131263508Sdim 132263508Sdim% copy(+Old,-New) 133263508Sdim% Makes a fresh copy of the term Old. A bit hacky... 134239462Sdim 135239462Sdimcopy(Old, New) :- copy_term(Old, New). % SEPIA 136239462Sdim 137239462Sdim% copy(Old, New) :- % Altered to use data base 138207618Srdivacky% record(copy,Old,Key), % KJ 21-5-87 139212904Sdim% recorded(copy,Mid,Key), 140263508Sdim% erase(Key), 141263508Sdim% !, 142263508Sdim% New = Mid. 143263508Sdim 144193323Sed 145218893Sdim% unify(?X, ?Y) 146218893Sdim% Try to unify X and Y, wih occurs check. 147218893Sdim% Further down in this file is the Occurs Check. 148218893Sdim 149221345Sdimunify(X, Y) :- 150221345Sdim var(X), 151221345Sdim var(Y), 152221345Sdim !, 153221345Sdim X = Y. % want unify(X,X) 154218893Sdim 155243830Sdimunify(X, Y) :- 156243830Sdim var(X), 157243830Sdim !, 158243830Sdim occurs_check(Y, X), % X is not in Y 159243830Sdim X = Y. 160243830Sdim 161243830Sdimunify(X, Y) :- 162243830Sdim var(Y), 163263508Sdim !, 164243830Sdim occurs_check(X, Y), % Y is not in X 165243830Sdim X = Y. 166243830Sdim 167243830Sdimunify(X, Y) :- 168243830Sdim atomic(X), 169243830Sdim !, 170243830Sdim X = Y. 171243830Sdim 172243830Sdimunify(X, Y) :- 173243830Sdim functor(X, F, N), 174243830Sdim functor(Y, F, N), 175239462Sdim unify(N, X, Y). 176239462Sdim 177193323Sedunify(0, _, _) :- !. 178193323Sed 179239462Sdimunify(N, X, Y) :- 180239462Sdim arg(N, X, Xn), 181218893Sdim arg(N, Y, Yn), 182218893Sdim unify(Xn, Yn), 183193323Sed M is N-1, 184193323Sed !, 185198892Srdivacky unify(M, X, Y). 186239462Sdim 187193323Sedoccurs_check(Term, Var) :- \+ occurs(Var, Term). % SEPIA 188193323Sed 189198892Srdivacky% occurs_check(Term, Var) :- 190198892Srdivacky% var(Term), 191239462Sdim% !, 192198892Srdivacky% Term \== Var. 193212904Sdim% 194198892Srdivacky% occurs_check(Term, Var) :- 195198892Srdivacky% functor(Term, _, Arity), 196239462Sdim% occurs_check(Arity, Term, Var). 197198892Srdivacky% 198198892Srdivacky% occurs_check(0, _, _) :- !. 199198892Srdivacky% 200198892Srdivacky% occurs_check(N, Term, Var) :- 201239462Sdim% arg(N, Term, Arg), 202212904Sdim% occurs_check(Arg, Var), 203198892Srdivacky% M is N-1, 204198892Srdivacky% !, 205198892Srdivacky% occurs_check(M, Term, Var). 206239462Sdim 207212904Sdimvar_member_chk(Var, [Head|_]) :- 208198892Srdivacky Head == Var, 209263508Sdim !. 210212904Sdimvar_member_chk(Var, [_|Tail]) :- 211263508Sdim var_member_chk(Var, Tail). 212212904Sdim 213212904Sdim 214263508Sdimvariables_of(Term, Vars) :- 215212904Sdim variables_of(Term, [], Vars). 216263508Sdim 217212904Sdimvariables_of(Term, Sofar, Sofar) :- 218212904Sdim var(Term), 219198892Srdivacky var_member_chk(Term, Sofar), 220239462Sdim !. 221198892Srdivackyvariables_of(Term, Sofar, [Term|Sofar]) :- 222198892Srdivacky var(Term), 223249423Sdim !. 224249423Sdimvariables_of(Term, Sofar, Vars) :- 225249423Sdim functor(Term, _, N), 226249423Sdim variables_of(N, Term, Sofar, Vars). 227249423Sdim 228249423Sdimvariables_of(0, _, Vars, Vars) :- !. 229249423Sdimvariables_of(N, Term, Sofar, Vars) :- 230199481Srdivacky arg(N, Term, Arg), 231239462Sdim variables_of(Arg, Sofar, Mid), 232198892Srdivacky M is N-1, !, 233198892Srdivacky variables_of(M, Term, Mid, Vars). 234263508Sdim 235263508Sdim 236263508Sdim% subsumes(+General, +Specific) 237263508Sdim% True if Specific can be found by instantiating variables in General 238263508Sdim% for instance, subsumes(foo(X), foo(bar)) is true. 239263508Sdim 240193323Sedsubsumes(General, Specific) :- 241239462Sdim variables_of(Specific, Vars), 242193323Sed subsumes(General, Specific, Vars). 243193323Sed 244193323Sedsubsumes(General, Specific, Vars) :- 245239462Sdim var(General), 246193323Sed var_member_chk(General, Vars), 247193323Sed !, 248198892Srdivacky General == Specific. 249198892Srdivacky 250239462Sdimsubsumes(General, Specific, _) :- 251198892Srdivacky var(General), 252198892Srdivacky !, 253206083Srdivacky General = Specific. % binds 254193323Sed 255193323Sedsubsumes(General, Specific, Vars) :- 256193323Sed nonvar(Specific), % mustn't bind it 257193323Sed functor(General, FunctionSymbol, Arity), 258193323Sed functor(Specific, FunctionSymbol, Arity), 259193323Sed subsumes(Arity, General, Specific, Vars). 260193323Sed 261193323Sedsubsumes(0, _, _, _) :- !. 262198090Srdivacky 263193323Sedsubsumes(N, General, Specific, Vars) :- 264234353Sdim arg(N, General, GenArg), 265234353Sdim arg(N, Specific, SpeArg), 266234353Sdim subsumes(GenArg, SpeArg, Vars), 267234353Sdim M is N-1, !, 268193323Sed subsumes(M, General, Specific, Vars). 269239462Sdim 270239462Sdim 271239462Sdimvariant(A, B) :- 272239462Sdim subsumes_chk(A, B), 273234353Sdim subsumes_chk(B, A). 274234353Sdim 275243830Sdimsubsumes_chk(General, Specific) :- 276193323Sed \+ ( numbervars(Specific, 0, _), 277234353Sdim \+ General = Specific 278234353Sdim ). 279234353Sdim 280234353Sdim