/* Backward Chaining OAV Expert System Shell Please report all bugs to koppel@ee.lsu.edu. Technical support: 14:00 - 16:30 T,Th; 14:00-16:30 TT (except during tests). */ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Load some needed procedures and define operators. % :-reconsult('ask.pro'). :-op(950,xfx,:). :-op(945,fx,if). :-op(940,xfx,then). :-op(800,xfy,or). :-op(750,xfy,and). :-op(700,fy,not). :-op(100,xfx,':='). :-op(90,xfx,':.'). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedures for initialization and starting. % % Remove old instance name counters and facts used for quantified expressions. % wipe:-abolish(nameList,2),abolish(doAllRec,2),fail. % Remove old facts, except for initial facts. % wipe:- D=data(_,_,_,X),D,not(X=init),retract(D),fail ; true. % Start expert system by finding value of root goal. % rootGoal(RG):- wipe,deduce(RG,TV), sOut<<"The root goal has value "<<0,H<128. % Probably an ASCII string. % Check for truth value. If none found, print error message. % isTV(true):-!. isTV(false):-!. isTV(X):- sOut<<"Warning, truth value expected, "<<_,_=<_,_>=_,_ is _ ,newName(_,_),_ << _,_ <<< _ ,conclude(_,_,_),call(_)]),!, once ( Goal,!,Result=true % If so, execute and return ; Result=false % appropriate result. ). % Handle quantified expressions. % % Parts of this clause: % 1. Parse goal. % 2. Get list of candidate objects, Os. % (An object, say x, is a candidate if M is true when O=x.) % 3. For each candidate in Os, test if G is true. % 4. Unify Val to true or false, depending on how many times G was true. % deduce(Goal,Val):- Goal=..[Amt,O:.isa=Class,M,G], % Extract parts of quantifier cmd. var(O),atom(Class), member(Amt,[forAll,forEach % Check for valid quantifier. ,forSome,forNone]), !, % (Below) Get list of objects. setof(O,[M,From]^(data(O,isa,Class,From),deduce(M,true)),Os), newName(doAll,Name), % Make a outcome str. name. T=doAllRec(Name,Outcome), % Make an outcome structure. ( member(O,Os), % Get an object. once (deduce(G,Outcome)), % Test condition on object. once ( T ; asserta(T) ),fail % Update outcome if new; ; % get next object. true ), % (Below) Check outcomes. once ( retract(doAllRec(Name,true)),S=t ; true ), once ( retract(doAllRec(Name,false)),F=t ; true ), once ( ( Amt=forNone,var(S) ; Amt=forSome,not((var(S),nonvar(T))) ; Amt=forAll,var(F) ; Amt=forEach ),!,Val=true ; Val=false ). % Existential Quantifier. % deduce(thereExist(O:.isa=Class,SuchThat),TV):-!, (data(O,isa,Class,Val), % Find an object. deduce(SuchThat,true),!, % See if condition true. TV=true % Is true. ; TV=false % Condition false. ),!. % Make a new instance of Class. % deduce(new(Class,Inst),Res):- var(Inst), % Check for error condition. props(Class,_,_,_), % Make sure class is a class. newName(Class,Inst), % Make a name for the instance. % (Below) Assert "isa" link. conclude(Inst:.isa,Class,newClause),!,Res=true ; Res=false. % Unify two items. % deduce(X=Y,Val):-!, % (Below) Get values. ( nonvar(X),deduce(X,Vx) ; Vx=X ), ( nonvar(Y),deduce(Y,Vy) ; Vy=Y ), ( Vx=Vy,!,Val=true % Try to unify. Set result. ; Val=false ),!. % Retreive known data for OAV. % deduce(Term,Val):- parseOAV(Term,Obj,Attr), % Make sure term is OAV. data(Obj,Attr,V,_),!,Val=V. % Retreive data, unify with return. % Use a rule. % deduce(Term,V):- getTermType(Term,TermType), % Make sure term is OAV or command. ( Rule:if Ante then Term, % Consequent a proposition by default. Value=true ; Rule:if Ante then Term:=Value % Consequent value shown explicitly. ), deduce(Ante,TV), traceRule(Rule,Term,TV,Value), % Print a trace (debug) message. isTV(TV),TV=true,!, % Evaluate ante., backtrack if false. ( TermType=global, conclude(global:.Term,Value,rule(Rule)) ; TermType=oav, conclude(Term,Value,rule(Rule)) ; TermType=command % Data not saved for commands. ), V=Value. % Ask user about OAV. % deduce(Term,Val):- getClass(Term,ClassOrObj,Object,Attr), % Get class. props(ClassOrObj,Attr,Question,Valid), % Get question for attribute. askAndCheck(Question,Object,Valid,Ans), % Ask user... conclude(Object:.Attr,Ans,user), % ...and assert answer. !,Val=Ans. % If execution reaches this point and Term is a proposition which % appears in the consequent of at least one rule, then Term is assumed false. % deduce(Term,false):- getTermType(Term,TermType), ( TermType=oav ; TermType=global ), _:if _ then Term,!, parseOAV(Term,Obj,Attr), conclude(Obj:.Attr,false,assumption). % If a value, just return value. % deduce(Term,Term):-isValue(Term),!. % Term is something that can't be handled. % deduce(Term,error):- sOut<<"Cannot handle expression "<<