% Unordered Base Module :- module(ubase,[ ... / 2, % ... //0 seq/3, % seq//1 seqq/3, % seqq//1 closure0/3, closure/3, path/4 ]). % Useful non-terminals ... --> [] | [_], ... . seq([]) --> []. seq([E|Es]) --> [E], seq(Es). % seqq is the plural of seq seqq([]) --> []. seqq([Es|Ess]) --> seq(Es), seqq(Ess). :- meta_predicate closure0(2,?,?). :- meta_predicate closure(2,?,?). :- meta_predicate closure0(2,?,?,+). % internal closure0(R_2, X0,X) :- closure0(R_2, X0,X, [X0]). closure(R_2, X0,X) :- call(R_2, X0,X1), closure0(R_2, X1,X, [X1,X0]). closure0(_R_2, X,X, _). closure0(R_2, X0,X, Xs) :- call(R_2, X0,X1), list_non_member(Xs, X1), closure0(R_2, X1,X, [X1|Xs]). non_member(X, Es) :- list_non_member(Es, X). list_non_member([], _X). list_non_member([E|Es], X) :- dif(E, X), list_non_member(Es, X). :- meta_predicate path(2,?,?,?). :- meta_predicate path(2,?,?,?,+). path(R_2, [X0|Ys], X0,X) :- path(R_2, Ys, X0,X, [X0]). path(_R_2, [], X,X, _). path(R_2, [X1|Ys], X0,X, Xs) :- call(R_2, X0,X1), list_non_member(Xs, X1), path(R_2, Ys, X1,X, [X1|Xs]). :- meta_predicate symm(2, ?, ?). symm(P_2, A, B) :- call(P_2, A, B). symm(P_2, A, B) :- call(P_2, B, A).