Skip to content

Instantly share code, notes, and snippets.

@jarble
Last active September 25, 2019 00:50
Show Gist options
  • Save jarble/77d1f818b390a4b5668b55a190172639 to your computer and use it in GitHub Desktop.
Save jarble/77d1f818b390a4b5668b55a190172639 to your computer and use it in GitHub Desktop.
A partial evaluator for non-recursive Prolog programs
:- initialization(main).
:- set_prolog_flag(double_quotes,chars).
main :- recursive_partial_eval((is_between(3,4,5) -> false,is_between(1,C,3);is_between(3,4,5);is_between(3,D,4)),B),writeln(B).
recursive_partial_eval(A,B) :-
find_all_clauses_(A,A1),
(A==A1,A1=B;recursive_partial_eval(A1,B)).
find_all_clauses_(A,A) :- var(A).
find_all_clauses_(A,B) :- nonvar(A),find_all_clauses(A,B).
find_all_clauses(A==B,true) :- A==B.
%find_all_clauses(A==B,(A1==B1,A2==B2)) :-
% is_list(A),is_list(B),length(A,L),length(B,L),A=[A1|A2],B=[B1|B2].
find_all_clauses((false,A),false).
find_all_clauses((A,false),false).
find_all_clauses((true,A),A).
find_all_clauses((A,true),A).
find_all_clauses((B;A),A) :- B==true;B==false.
find_all_clauses((A;B),A) :- B==true;B==false.
find_all_clauses(A,true) :- ground(A),callable(A),call(A).
find_all_clauses(A,false) :- ground(A),callable(A),(\+call(A)).
find_all_clauses(A>B,A>B).
find_all_clauses(B<A,B<A).
find_all_clauses(forall(A,B),forall(A1,B1)) :-
find_all_clauses(A,A1),find_all_clauses(B,B1).
find_all_clauses(foreach(A,B),foreach(A1,B1)) :-
find_all_clauses(A,A1),find_all_clauses(B,B1).
find_all_clauses(A,true) :-
callable(A),ground(A),call(A).
find_all_clauses(true->B,B).
find_all_clauses(false->B,false).
find_all_clauses(A->B,A1->B1) :-
find_all_clauses(A,A1),find_all_clauses(B,B1).
find_all_clauses(A\==B,A\==B).
find_all_clauses(A=B,A=B).
find_all_clauses(A==B,A==B).
find_all_clauses(A\=B,A\=B).
find_all_clauses(P,P) :-
number(P);atom(P).
find_all_clauses((P1,P2),(P1_,P2_)) :-
recursive_partial_eval(P1,P1_),find_all_clauses(P2,P2_).
find_all_clauses((P1;P2),(P1_;P2_)) :-
find_all_clauses(P1,P1_),find_all_clauses(P2,P2_).
find_all_clauses(Predicate,Output) :-
findall(Predicate1,expand_without_unify(Predicate,Predicate1),Output1),
list_to_disjunction(Output1,Output2),find_all_clauses(Output2,Output).
list_to_disjunction([A],A).
list_to_disjunction([A|B],(A;B1)) :- list_to_disjunction(B,B1).
is_between(A,B,C) :- A<B,C>B.
is_between(A,B,C) :- B>A,B<C.
is_not(A,B) :- A \= B.
thingy([A,B]) :- A == 1.
expand_without_unify(A,((A_==A1_),A2)) :-
copy_term(A,A1),clause(A1,A2),
A =.. [_|A_],A1 =.. [_|A1_],expand_without_unify_(A_,A1_).
expand_without_unify_([],[]).
expand_without_unify_([List1|List1_],[List2|List2_]) :-
(var(List2),List1=List2;nonvar(List2)),expand_without_unify_(List1_,List2_).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment