Created
February 7, 2025 18:24
-
-
Save dnmfarrell/919c9f3a1c24b6ac9bec332d2b046587 to your computer and use it in GitHub Desktop.
A layered meta-interpreter which handles disjunction, cut, negation and more.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Explaining Prolog Based Expert Systems Using a Layered Meta-interpreter | |
% Leon Sterling and L. Umit Yalcinalp | |
% https://www.ijcai.org/Proceedings/89-1/Papers/011.pdf | |
% | |
% GOAL LAYER | |
solve_goal(Goal,Result) :- | |
copy_term(Goal,Copy), | |
solve_branch(Copy,Branch_Result), | |
(Branch_Result = commit -> !;true), | |
filter_failure(Branch_Result,Result,Goal,Copy). | |
solve_goal(_,no). | |
filter_failure(yes,yes,Goal,Goal). | |
filter_failure(commit,commit,Goal,_) :- | |
non_singular(Goal),!. | |
filter_failure(commit,no,_,_). % for single goals | |
filter_failure(no,_,_,_) :- fail. | |
% BRANCH LAYER | |
solve_branch(true,yes) :- !. | |
solve_branch((A,B),Result) :- !, % A and B | |
solve_goal(A,RA), | |
solve_branch_and(RA,A,Result,B). | |
solve_branch((A->B;C),Result) :- | |
solve_goal(A,ResultA),!, | |
solve_branch_if(ResultA,Result,B,C). | |
solve_branch((A->B),Result) :- | |
solve_goal(A,ResultA),!, | |
solve_branch_if_one(ResultA,Result,B). | |
solve_branch((A;B),Result) :- !, % A or B | |
solve_goal(A,RA), | |
solve_branch_or(RA,Result,B). | |
solve_branch(\+ Goal,Result) :- | |
solve_goal(Goal,Result_Not),!, | |
invert(Result_Not,Result). | |
solve_branch(findall(X,P,L),Result) :- | |
findall(X-R,solve_goal(R,P),AList), | |
eliminate(Result,AList,L). | |
solve_branch(!,yes). | |
solve_branch(!,commit) :- !. | |
solve_branch(A,Result) :- | |
sys(A),A,Result = yes. | |
solve_branch(A,Result) :- | |
sys(A),Result = no,!. | |
solve_branch(A,no) :- | |
\+ clause(A,_),!. | |
solve_branch(A,Result) :- | |
clause(A,Body), | |
solve_goal(Body,Result). | |
% these are undefined in the paper | |
%solve_branch(A,Result) :- | |
% askable(A), | |
% investigate_goal(A,Result). | |
invert(yes,no). | |
invert(no,yes). | |
% HANDLING CONJUNCTION | |
solve_branch_and(yes,!,Result,B) :- !, | |
solve_goal(B,ResultB), | |
((ResultB = no; ResultB = commit) -> | |
Result = commit; Result = yes). | |
solve_branch_and(yes,_,Result,B) :- !, | |
% when A is not a cut | |
solve_goal(B,Result). | |
solve_branch_and(no,_,no,_). | |
% HANDLING DISJUNCTION | |
solve_branch_or(yes,yes,_) :- !. | |
solve_branch_or(no,Result,B) :- !, | |
solve_goal(B,Result). | |
solve_branch_or(commit,commit,_) :- !. | |
% HANDLING IF BRANCHES | |
solve_branch_if_one(yes,Result,B) :- !, | |
solve_goal(B,Result). | |
solve_branch_if_one(NoResult,NoResult,_) :- | |
(NoResult = commit ; NoResult = no),!. | |
solve_branch_if(yes,Result,B,_) :- !, | |
solve_goal(B,Result). | |
solve_branch_if(no,Result,_,C) :- !, | |
solve_goal(C,Result). | |
solve_branch_if(commit,commit,_,_) :- !. | |
sys(A) :- | |
predicate_property(A,built_in). | |
% N.B. non_singular/1 is described, but not implemented in the paper | |
non_singular((_;_)). | |
non_singular((_,_)). | |
non_singular((_->_)). | |
non_singular((_->_;_)). | |
non_singular((!)). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment