:- op(700, xfx, \=). A \= B :- \+ A = B. % Define `\=' % ====================================================================== % For Demoing the execution of goals: % ====================================================================== demo_goals([]). demo_goals([Goal|Goals]) :- demo_goal(Goal), demo_goals(Goals). demo_goal(Pred) :- Pred \= _-_-_, write('| ?- '), pretty_write(Pred), write('.'), getnl, call(Pred), !, nl, write(yes), nl. demo_goal(Pred-Vars-Style) :- copy(Pred-Vars, CPred-CVars), assign_names(CVars), write('| ?- '), pretty_write(CPred), write('.'), getnl, call(Pred), nl, show_vars(CVars, Vars), ( Style = allsolns -> write(' ;'), getnl, fail ; nl, nl ), !. demo_goal(_) :- nl, write(no), nl. assign_names([]). assign_names([Var/Name|Vars]) :- Var=Name, assign_names(Vars). show_vars([V/_], [Val/_]) :- !, write(V), write(' = '), write(Val). show_vars([V/_|Vs], [Val/_|Vals]) :- write(V), write(' = '), write(Val), write(','), nl, show_vars(Vs, Vals). getnl :- repeat, get0(NL), is_nl_char(NL), !. is_nl_char(10). % -------------------- Pretty term writing facility -------------------- pretty_write(Term) :- underscore_vars(Term), write(Term), fail. pretty_write(_). underscore_vars(Term) :- bagof_variables(Term, Vars), underscore_vars(Vars, Vars), numbervars(Term, 0, _). underscore_vars([], _). underscore_vars([V|Vs], AllVs) :- unique_var(V, AllVs), !, V = '_', underscore_vars(Vs, AllVs). underscore_vars([_|Vs], AllVs) :- underscore_vars(Vs, AllVs). unique_var(Var, Vars) :- eq_remove(Var, Vars, RestVars), \+ eq_remove(Var, RestVars, _), !. bagof_variables(Term, Vlist) :- bagof_variables(Term, [], Vlist). bagof_variables(V, Sofar, [V|Sofar]) :- var(V), !. bagof_variables(A, Sofar, Sofar ) :- atomic(A), !. bagof_variables([HD|TL], Sofar, Result) :- !, bagof_variables(HD, Sofar, Inter), bagof_variables(TL, Inter, Result). bagof_variables(Term, Sofar, Result) :- Term =.. [_|Args], bagof_variables(Args, Sofar, Result). eq_remove(A, [C|B], B) :- A == C, !. eq_remove(A, [C|B], [C|NewB]) :- eq_remove(A, B, NewB). % ----------------------------------------------------------------- % Copied from library(types), renamed ground/1 -> is_ground/1 to avoid % illegal re-definition errors when running under Q3.* % is_ground(+Term). Succeeds if Term contains no variables is_ground(Term) :- nonvar(Term), functor(Term,_,Arity), is_ground(Arity,Term). is_ground(0, _) :- !. is_ground(N, Term) :- arg(N, Term, Arg), nonvar(Arg), functor(Arg, _, Arity), is_ground(Arity, Arg), M is N-1, is_ground(M, Term). % ---------------------------------------------------------------------- :- dynamic 'gensym counter'/2. gensym(Prefix, Sym) :- ( retract('gensym counter'(Prefix,OldN)) -> true ; OldN = 0 ), N is OldN + 1, assertz('gensym counter'(Prefix,N)), number_chars(N, NCh), atom_chars(Prefix, PCh), myappend(PCh, NCh, SymCh), atom_chars(Sym, SymCh). % same as append/3: call this myappend/3 so as not to clash with built-in % append/3 under Quintus3.1.1. myappend([], A, A). myappend([A|B], C, [A|D]) :- myappend(B, C, D). member(X, [X|_]). member(X, [_|Y]) :- member(X, Y). memberchk(X, [X|_]) :- !. memberchk(X, [_|Y]) :- memberchk(X, Y). % From library(sets) union([], Union, Union). union([Element|Elements], Set, Union) :- memberchk(Element, Set), !, union(Elements, Set, Union). union([Element|Elements], Set, [Element|Union]) :- union(Elements, Set, Union). % nlist(5, X) => X = [1,2,3,4,5] nlist(N, []) :- N < 1, !. nlist(N, List) :- nlist(1, N, List). nlist(N, N, [N]) :- !. nlist(N, Max, [N|Ns]) :- NewN is N + 1, nlist(NewN, Max, Ns). nmemberchk(Elem, List, N) :- nmember(Elem, List, N), !. nmember(Elem, List, N) :- nmember(Elem, List, 1, N). nmember(Elem, [Elem|_], N, N). nmember(Elem, [_|List], NSoFar, N) :- NewN is NSoFar + 1, nmember(Elem, List, NewN, N). append([], []). % library(lists) append([L|Ls], List0) :- myappend(L, List1, List0), append(Ls, List1). % ====================================================================== % COPYING A PROLOG TERM % Rather crude copying mechanism, but works % copy(A, CopyA) :- asserta('copy of'(A)), retract('copy of'(CopyA)), !. % Faster: copy(In, Out) :- copy(In, Out, _, []). % Copy (In) to (Out) keeping track of the variables copy(In, Out, Swaps , Swaps ) :- var(In), vmem(In/Out, Swaps), !. copy(In, Out, [In/Out|Swaps], Swaps ) :- var(In), !, var(Out). copy(In, Out, SwapsOut, SwapsIn) :- functor(In, F, N), functor(Out, F, N), copy_args(N, In, Out, SwapsOut, SwapsIn). copy_args(0, _, _, S, S) :- !. copy_args(N, In, Out, Sout, Sin) :- arg(N, In, InN), arg(N, Out, OutN), copy(InN, OutN, Sinter, Sin), N1 is N-1, copy_args(N1, In, Out, Sout, Sinter). vmem(A/B, [Am/B|_]) :- A == Am, !. vmem( X, [ _|R]) :- vmem(X, R).