Did you know ... Search Documentation:
Pack logicmoo_base -- t/examples/pfc/pfc_test1.pl.txt

/* Part of LogicMOO Base mpred_mpred_testing % Tests a prolog database replacent that uses PFC % % % Logicmoo Project PrologMUD: A MUD server written in Prolog % Maintainer: Douglas Miles % Dec 13, 2035 % */

:- include('mpred_header.pi').

% user:term_expansion(A,B):- \+ t_l:disable_px, current_predicate(pfcExpansion_loaded/0),loop_check(mpred_file_expansion(A,B)),A\=@=B.

:- mpred_trace. %:- pfcWatch. :- mpred_warn.

next_test :- sleep(1),pfcReset.

% :-dynamic((species/2)).

:- mpred_setting_change(add,default,ain).

species(fred,human). species(rover,dog). species(felix,cat). species(house1, house). species(house2, house). species(house3, house). species(house4, house). species(car1, car). species(car2, car). species(car3, car).

male(fred). male(joe). male(jed). male(sam). male(george). male(jack). male(rover). male(felix). male(rover). male(felix). male(tramp). male(snoopy). %male(tim). male(harry). male(jason). female(mary). female(sally). female(jane). female(jill). female(mavis). female(lady). female(lassie). female(freida). female(jane). %female(terry).

hasChild(fred, jed). hasChild(fred, sally). hasChild(joe, jane). hasChild(mary, jed). hasChild(mary, sally). hasChild(mary, jane). hasChild(jane, george). hasChild(jane, jack). hasChild(sam, george). hasChild(sam, jack). hasChild(jill, mavis). hasChild(george, mavis). hasChild(lady, rover). hasChild(lady, lassie). hasChild(tramp, lassie). hasChild(rover, snoopy). hasChild(lassie, snoopy). hasChild(tim, jason). hasChild(freida, jason). hasChild(jane, terry). hasChild(harry, terry). hasChild(jason, jill). hasChild(terry, jill).

owns(sam, rover). owns(jane, rover). owns(jack, felix). owns(joe, snoopy). owns(tim, car2). owns(jane, house2). owns(harry, house2). owns(joe, car3). owns(terry, house4). owns(terry, car1). owns(jason, house4). owns(jason, car1). owns(jill, house1). owns(mavis, house3). owns(jane, lady).

:- mpred_setting_change(neck,default,(<-)).

parentOf(X,Y) :- hasChild(X,Y).

motherOf(X,Y) :- parentOf(X,Y), female(X). motherOf(X,Y) :- parentOf(B,Y), parentOf(X,Y), X \= B, male(B).

fatherOf(X,Y) :- parentOf(X,Y), male(X). fatherOf(X,Y) :- parentOf(B,Y), parentOf(X,Y), X \= B, female(B).

grandparentOf(X,Y) :- parentOf(X,Z), parentOf(Z,Y).

grandmotherOf(X,Y) :- grandparentOf(X,Y), female(X). grandmotherOf(X,Y) :- grandparentOf(X,Y), isFemale(X).

grandfatherOf(X,Y) :- grandparentOf(X,Y), male(X). grandfatherOf(X,Y) :- grandparentOf(X,Y), isMale(X).

greatgrandparentOf(X,Y) :- parentOf(X,Z), parentOf(Z,A), parentOf(A,Y).

greatgrandmotherOf(X,Y) :- greatgrandparentOf(X,Y), female(X). greatgrandmotherOf(X,Y) :- greatgrandparentOf(X,Y), isFemale(X).

greatgrandfatherOf(X,Y) :- greatgrandparentOf(X,Y), male(X). greatgrandfatherOf(X,Y) :- greatgrandparentOf(X,Y), isMale(X).

childOf(X,Y) :- parentOf(Y,X).

daughterOf(X,Y) :- parentOf(Y,X), isFemale(X).

sonOf(X,Y) :- parentOf(Y,X), isMale(X).

grandchildOf(X,Y) :- parentOf(Y,Z), parentOf(Z,X).

granddaughterOf(X,Y) :- female(X), grandparentOf(Y,X). granddaughterOf(X,Y) :- isFemale(X), grandparentOf(Y,X).

grandsonOf(X,Y) :- male(X), grandparentOf(Y,X). grandsonOf(X,Y) :- isMale(X), grandparentOf(Y,X).

greatgrandchildOf(X,Y) :- greatgrandparentOf(Y,X).

greatgranddaughterOf(X,Y) :- female(X), greatgrandparentOf(Y,X). greatgranddaughterOf(X,Y) :- isFemale(X), greatgrandparentOf(Y,X).

greatgrandsonOf(X,Y) :- male(X), greatgrandparentOf(Y,X). greatgrandsonOf(X,Y) :- isMale(X), greatgrandparentOf(Y,X).

ancestorOf(X,Y) :- parentOf(X, Y). ancestorOf(X,Y) :- parentOf(X, Z), ancestorOf(Z,Y).

ancestorOf(X,Y,0) :- X =Y,true. ancestorOf(X,Y,1) :- parentOf(X,Y). ancestorOf(X,Y,N) :- number(N),!,N>1, N1 is N -1, ancestorOf(X,Y,N1).

parent(X) :- hasChild(X,Y).

%helper function descendantOf(X,Y) :- childOf(X,Y). descendantOf(X,Y) :- childOf(X,Z), childOf(Z,Y). related(X,X). related(X,Y) :- ancestorOf(X,Y). related(X,Y) :- ancestorOf(Y,X). related(X,Y) :- descendantOf(X,Y). related(X,Y) :- descendantOf(Y,X).

sibling(X,Y) :- motherOf(Z,X), motherOf(Z,Y), fatherOf(W,X), fatherOf(W,Y), \+pet(X), \+pet(Y), X \= Y.

sisterOf(X,Y) :- sibling(X,Y), female(X). sisterOf(X,Y) :- sibling(X,Y), isFemale(X).

brotherOf(X,Y) :- sibling(X,Y), male(X). brotherOf(X,Y) :- sibling(X,Y), isMale(X).

%helping function atLeastOneParent(X,Y) :- (motherOf(Z,X), motherOf(Z,Y) ; fatherOf(W,X), fatherOf(W,Y) ). atLeastTwoParents(X,Y) :- (motherOf(Z,X), motherOf(Z,Y) , fatherOf(W,X), fatherOf(W,Y) ). stepSibling(X,Y) :- atLeastOneParent(X,Y), \+atLeastTwoParents(X,Y), \+pet(X), \+pet(Y), X \= Y.

getSpecies(X,Y) :- species(X,Y).

:- mpred_setting_change(neck,default,(==>)).

isMale(A) :- male(A). isMale(A) :- parentOf(B, Y), parentOf(A, Y), A \= B, female(B).

isFemale(A) :- female(A). isFemale(A) :- parentOf(B, Y), parentOf(A, Y), A \= B, male(B).

pet(X) :- owns(Y,X), ( isMale(X) ; isFemale(X) ).

(species(I,C) <==> (isa(I,C),isa(C,tCol))).

t(Pred,A1,A2):- atom(Pred),Call=..[Pred,A1,A2],call(Call). % t(Pred,A1,A2,A3):- atom(Pred),Call=..[Pred,A1,A2,A3],(Call).

((argIsa(Pred,1,Col),t(Pred,Arg,_)) ==> isa(Arg,Col)).

((argIsa(Pred,2,Col),t(Pred,_,Arg)) ==> isa(Arg,Col)).

argIsa(owns,1,human). argIsa(owns,2,notHuman).

% :-mpred_set_forward(parent/1).

end_of_file.

:- dynamic((disjointWith/2,genls/2,isa/2)).

%(disjointWith(P1,P2) , genls(C1,P1)) ==> disjointWith(C1,P2). disjointWith(Sub, Super) ==> disjointWith( Super, Sub). disjointWith(tObj,tRegion). disjointWith(ttSpatialType,ttAbstractType).

tCol(Col) <==> isa(Col,tCol).

% (isa(I,Sub), genls(Sub, Super)) ==> isa(I,Super).

(isa(I,Sub), disjointWith(Sub, Super)) ==> neg(isa(I,Super)).

genls(tPartofObj,tItem).

% dividesBetween(tItem,tPathways). dividesBetween(tItem,tMassfull,tMassless). dividesBetween(tObj,tItem,tAgent). dividesBetween(tObj,tMassfull,tMassless). dividesBetween(tSpatialThing,tObj,tRegion). dividesBetween(tAgent,tHumanControlled,tNpcPlayer).

dividesBetween(S,C1,C2) ==> (disjointWith(C1,C2) , genls(C1,S) ,genls(C2,S)).

disjointWith(P1,P2) ==> (neg(isa(C,P1)) <==> isa(C,P2)).

isa(Col1, ttObjectType) ==> ~isa(Col1, ttExpressionType).

==> tCol(tCol). ==> tCol(tPred). ==> tCol(tFunction). ==> tCol(tRelation). ==> tCol(ttSpatialType). ==> tCol(ttExpressionType). ==> tCol(functorDeclares). % tCol(ArgsIsa):-ttPredType(ArgsIsa). % TODO decide if OK %tCol(F):-t(functorDeclares,F). ==> tCol(ttExpressionType). ==> tSpec(vtActionTemplate). ==> tCol(tRegion). ==> tCol(tContainer).

isa(tRegion,ttSpatialType). isa(tRelation,ttAbstractType).

:- dynamic(mpred_default/1). % -*-Prolog-*- % here is an example which defines mpred_default facts and rules. Will it work?

(((mpred_default(P)/mpred_literal(P)) ==> (~neg(P) ==> P))).

((mpred_default((P ==> Q))/mpred_literal(Q) ==> (P, ~neg(Q) ==> Q))).

:- dynamic(conflict/1). % a conflict triggers a Prolog action to resolve it. ((conflict(C) ==> {resolveConflict(C)})).

:- dynamic(resolveConflict/1). % this isnt written yet. resolveConflict(C) :- format("~NHalting with conflict ~w", [C]), pfcJustification_L(C), mpred_negate(C,N), pfcJustification_L(N), mpred_halt.

% meta rules to schedule inferencing.

% resolve conflicts asap mpred_select(conflict(X),S) :- mpred_queue(conflict(X),S).

% a pretty basic conflict. {mpred_literal(P)}, neg(P), P ==> conflict(P).

/* % reflexive equality equal(A,B) ==> equal(B,A). equal(A,B),{ \\+ (A=B}),equal(B,C),{ \\+ (A=C)} ==> equal(A,C).

notequal(A,B) <- notequal(B,A). notequal(C,B) <- equal(A,C),notequal(A,B). */

% is this how to define constraints? % either(P,Q) ==> (neg(P) ==> Q), (neg(Q) ==> P). % (P,Q ==> false) ==> (P ==> neg(Q)), (Q ==> neg(P)).

:- dynamic((fly/1,bird/1,penguin/1)).

% birds fly by mpred_default. (mpred_default((bird(X) ==> fly(X)))).

% heres one way to do an subclass hierarchy.

(((genls_test(C1,C2) ==> {P1 =.. [C1,X], P2 =.. [C2,X]}, (P1 ==> P2)))).

(genls_test(canary,bird)). (genls_test(penguin,bird)).

% penguins do neg fly. (penguin(X) ==> neg(fly(X))).

% chilly is a penguin. (penguin(chilly)).

% tweety is a canary. (canary(tweety)).

:- prolog.

end_of_file.

% asserting mpred_sv(p) cuases p/2 to be treated as a mpred_sv, i.e. % if p(foo,1)) is a fact and we ain_db p(foo,2), then the forrmer assertion % is retracted.

mpred_sv(Pred,Arity) ==> { dynamic(Pred/Arity), length(AfterList,Arity), append(Left,[A],AfterList), append(Left,[B],BeforeList), After =.. [Pred|AfterList], Before =.. [Pred|BeforeList]}, (After,{Before, \==(A , B)} ==> {rem2(Before)}).

% rem assertions about satisfied goals. action(Goal), Goal, {format("~n Doing ~q.~n",[Goal])} ==> {rem2(action(Goal))}.

% if someone picks up an object, then it is no longer "on" anything. grasping(_Actor,Object) ==> {rem2(on(Object,_))}.

% objects that arent being held or on something end up on the floor.

object(Object), ~on(Object,X)/( \==(X , floor)), ~grasping(_,Object) ==> {on(Object,floor);format("~n~w falls to the floor.",[Object])}, on(Object,floor).

% This accomplishes moving an actor from XY1 to XY2, taking a help % object along.

action(moveto(Actor,From,To)) ==> {rem2(at(Actor,From)), ain(at(Actor,To)), (grasping(Actor,Object) -> ain(at(Object,To)) ; true), rem2(action(moveto(Actor,From,To)))}.

% if X is reported to be on some new object Obj2, rem the assertion % that it was on Obj1.

==> mpred_sv(at,2).

at(X,Y) ==> {format("~n~w now at ~w",[X,Y])}.

==> mpred_sv(grasping,2).

==> mpred_sv(on,2).

on(X,Y) ==> {format("~n~w now on ~w",[X,Y])}.

% monkey and bananas problem in Pfc

% jump to the floor. action(on(Actor,floor)) ==> { format("~n~w jumps onto the floor",[Actor]), ain(on(Actor,floor)) }.

action(on(Actor,X)), at(Actor,Loc), at(X,Loc), ~grasping(Actor,_) ==> { format("~n~w climbs onto ~w.",[Actor,X]), ain(on(Actor,X)) }.

action(grasping(Actor,Object)), weight(Object,light), at(Object,XY) ==>

(~at(Actor,XY) ==> {ain(action(at(Actor,XY)))}),

(~on(Object,ceiling),at(Actor,XY) ==> {format("~n~w picks up ~w.",[Actor,Object])}, {ain(grasping(Actor,Object))}),

(on(Object,ceiling), at(ladder,XY) ==> (~on(Actor, ladder) ==> {format("~n~w wants to climb ladder to get to ~w.",[Actor,Object]), ain(action(on(Actor,ladder)))}),

(on(Actor,ladder) ==> {format("~n~w climbs ladder and grabs ~w.",[Actor,Object]), grasping(Actor,Object)})),

(on(Object,ceiling), ~at(ladder,XY) ==> {format("~n~w wants to move ladder to ~w.",[Actor,XY]), ain(action(move(Actor,ladder,XY)))}).

action(at(Actor,XY)), at(Actor,XY2)/( \==(XY , XY2)) ==> {format("~n~w wants to move from ~w to ~w",[Actor,XY2,XY]), ain(action(moveto(Actor,XY2,XY)))}.

(action(on(Actor,Object)) ; action(grasping(Actor,Object))), at(Object,XY), at(Actor,XY), grasping(Actor,Object2)/( \==(Object2 , Object)) ==> {format("~n~w releases ~w.",[Actor,Object2]), rem2(grasping(Actor,Object2))}.

action(move(Actor,Object,Destination)), grasping(Actor,Object), at(Actor,XY)/( \==(XY , Destination)) ==> action(moveto(Actor,XY,Destination)).

action(move(Actor,Object,Destination)), ~grasping(Actor,Object) ==> action(grasping(Actor,Object)).

% predicates to describe whats going on. % action(...

% here''s how to do it: start :-

ain(object(bananas)), ain(weight(bananas,light)), ain(at(bananas,xy(9,9))), ain(on(bananas,ceiling)),

ain(object(couch)), ain(wieght(couch,heavy)), ain(at(couch,xy(7,7))), ain(on(couch,floor)),

ain(object(ladder)), ain(weight(ladder,light)), ain(at(ladder,xy(4,3))), ain(on(ladder,floor)),

ain(object(blanket)), ain(weight(blanket,light)), ain(at(blanket,xy(7,7))),

ain(object(monkey)), ain(on(monkey,couch)), ain(at(monkey,xy(7,7))), ain(grasping(monkey,blanket)).

:- dynamic(go/0). % go. to get started. go :- ain(action(grasping(monkey,bananas))).

db :- listing([object,at,on,grasping,weight,action]).

% -*-Prolog-*-

==> factoral(0,1). ==> factoral(1,1). ==> factoral(2,2). factoral(N,M) <- {N>0,N1 is N-1}, factoral(N1,M1), {M is N*M1}.

==> fibonacci(1,1). ==> fibonacci(2,1). fibonacci(N,M) <- {N>2,N1 is N-1,N2 is N-2}, fibonacci(N1,M1), fibonacci(N2,M2), {M is M1+M2}.

end_of_file.

% -*-Prolog-*-

:- dynamic ('-->>')/2. :- dynamic ('--*>>')/2.

% a simple pfc dcg grammar. requires dcg_mpred.pl

% backward grammar rules. s(s(Np,Vp)) -->> np(Np), vp(Vp).

vp(vp(V,Np)) -->> verb(V), np(Np). vp(vp(V)) -->> verb(V). vp(vp(VP,X)) -->> vp(VP), pp(X).

np(np(N,D)) -->> det(D), noun(N). np(np(N)) -->> noun(N). np(np(Np,pp(Pp))) -->> np(Np), pp(Pp).

pp(pp(P,Np)) -->> prep(P), np(Np).

% forward grammar rules. P --*>> [W],{cat(W,Cat),P =.. [Cat,W]}.

% simple facts. cat(the,det). cat(a,det). cat(man,noun). cat(fish,noun). cat(eats,verb). cat(catches,verb). cat(in,prep). cat(on,prep). cat(house,noun). cat(table,noun).

:- compile_mpredg.

% -*-Prolog-*-

or(P,Q) ==> (neg(P) ==> Q), (neg(Q) ==> P).

prove_by_contradiction(P) :- P. prove_by_contradiction(P) :- \+ (neg(P) ; P), ain(neg(P)), P -> rem1(neg(P)) ; (rem1(neg(P)),fail).

/* ==> or(p,q). ==> (p ===> x). ==> (q ===> x). */

% try :- prove_by_contradiction(x).

or(P1,P2,P3) ==> (neg(P1), neg(P2) ==> P3), (neg(P1), neg(P3) ==> P2), (neg(P2), neg(P3) ==> P1).

%% some simple tests to see if Pfc is working properly

:- mpred_trace.

time(Call,Time) :- statistics(runtime,_), call_pl(Call), statistics(runtime,[_,Time]).

test0 :- ain([(p(X) ==> q), p(1), (p(X), ~r(X) ==> s(X)), (t(X), {X>0} ==> r(X)), (t(X), {X<0} ==> minusr(X)), t(-2), t(1)]).

test1 :- consult('kinship.pfc'), consult('finin.pfc').

% test2 :- ain([(a(X),~b(Y)/(Y>X) ==> biggest(a)), (b(X),~a(Y)/(Y>X) ==> biggest(b)), a(5)]).

%test3 :- % ain([(a(X),\+(b(Y))/(Y>X) ==> biggest(a)), % (b(X),\+a((Y))/(Y>X) ==> biggest(b)), % a(5)]).

% test4 :- ain([(foo(X), bar(Y)/{X=:=Y} ==> foobar(X)), (foobar(X), go ==> found(X)), (found(X), {X>=100} ==> big(X)), (found(X), {X>=10,X<100} ==> medium(X)), (found(X), {X<10} ==> little(X)), foo(1), bar(2), bar(1), foo(100), goAhead, bar(100) ]).

% test5 :- ain([(faz(X), ~baz(Y)/{X=:=Y} ==> fazbaz(X)), (fazbaz(X), go ==> found(X)), (found(X), {X>=100} ==> big(X)), (found(X), {X>=10,X<100} ==> medium(X)), (found(X), {X<10} ==> little(X)), faz(1), goAhead, baz(2), baz(1) ]).

% test6 :- ain([(d(X), ~f(Y)/{X=:=Y} ==> justD(X)), (justD(X), go ==> dGo(X)), d(1), go, f(1) ]).

% test7 :- ain([(g(X), h(Y)/{X=:=Y} ==> justG(X)), (justG(X), go ==> gGo(X)), g(1), go, h(1) ]).

% test8 :- ain([(j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y), go ==> jkGo(X,Y)), j(1), go, k(2) ]).

% test9 :- ain([(j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y) ==> jkGo(X,Y)), j(1), k(2) ]).

% test10 :- ain([ (j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y), go ==> jkGo(X,Y)), j(1), go, k(2) ]).

% -*-Prolog-*-

%% meta rules

/*

:- op(1050,xfx, ('===>') ).

:- dynamic ( ('===>') /2).

% ops5-like production:

(Lsh ===> Rhs) ==> (Lsh ==> {Rhs}).

:- op(1050,xfx,('===>')).

(P ===> Q) ==> (P ==> Q), (neg(Q) ==> neg(P)).

*/

% -*-Prolog-*- % here is an example which defines mpred_default facts and rules. Will it work?

(mpred_default(P)/mpred_literal(P)) ==> (~neg(P) ==> P).

mpred_default((P ==> Q))/mpred_literal(Q) ==> (P, ~neg(Q) ==> Q).

% birds fly by mpred_default. ==> mpred_default((bird(X) ==> fly(X))).

% here's one way to do an isa hierarchy. % isa = genls.

isa(C1,C2) ==> {P1 =.. [C1,X], P2 =.. [C2,X]}, (P1 ==> P2).

==> isa(canary,bird). ==> isa(penguin,bird).

% penguins do neg fly. penguin(X) ==> neg(fly(X)).

% chilly is a penguin. :- (ain(==> penguin(chilly))).

% rtrace(Goal):- Goal. % (quietly((visible(+all),visible(+unify),visible(+exception),leash(-all),leash(+exception))),(trace,Goal),leash(+all)).

% :- gutracer.

:- prolog. end_of_file.

:- next_test. :- debug.

end_of_file.

% dcg_mpred: translation of dcg-like grammar rules into pfc rules.

:- op(1200,xfx,'-->>'). :- op(1200,xfx,'--*>>'). % :- op(1200,xfx,'<<--'). :- op(400,yfx,'\').

% :- use_module(library(strings)), use_module(library(lists)).

term_expansion((P -->> Q),(:- fcAdd(Rule))) :- mpred_translate_rule((P -->> Q), Rule). term_expansion((P --*>> Q),(:- fcAdd(Rule))) :- mpred_translate_rule((P --*>> Q), Rule).

mpred_translate_rule((LP-->>[]),H) :- !, mpred_t_lp(LP,Id,S,S,H). mpred_translate_rule((LP-->>RP),(H <- B)):- mpred_t_lp(LP,Id,S,SR,H), mpred_t_rp(RP,Id,S,SR,B1), mpred_tidy(B1,B).

mpred_translate_rule((LP--*>>[]),H) :- !, mpred_t_lp(LP,Id,S,S,H). mpred_translate_rule((LP--*>>RP),(B ==> H)):- mpred_t_lp(LP,Id,S,SR,H), mpred_t_rp(RP,Id,S,SR,B1), mpred_tidy(B1,B).

mpred_t_lp(X,Id,S,SR,ss(X,Id,(S\SR))) :- var(X),!.

mpred_t_lp((LP,List),Id,S,SR,ss(LP,Id,(S\List2))):- !, pfcAppend(List,SR,List2).

mpred_t_lp(LP,Id,S,SR,ss(LP,Id,(S\SR))).

mpred_t_rp(!,Id,S,S,!) :- !. mpred_t_rp([],Id,S,S1,S=S1) :- !. mpred_t_rp([X],Id,S,SR,ss(word(X),Id,(S\SR))) :- !. mpred_t_rp([X|R],Id,S,SR,(ss(word(X),Id,(S\SR1)),RB)) :- !, mpred_t_rp(R,Id,SR1,SR,RB). mpred_t_rp({T},Id,S,S,{T}) :- !. mpred_t_rp((T,R),Id,S,SR,(Tt,Rt)) :- !, mpred_t_rp(T,Id,S,SR1,Tt), mpred_t_rp(R,Id,SR1,SR,Rt). mpred_t_rp((T;R),Id,S,SR,(Tt;Rt)) :- !, mpred_t_or(T,Id,S,SR,Tt), mpred_t_or(R,Id,S,SR,Rt). mpred_t_rp(T,Id,S,SR,ss(T,Id,(S\SR))).

mpred_t_or(X,Id,S0,S,P) :- mpred_t_rp(X,Id,S0a,S,Pa), ( var(S0a), S0a \== S, !, S0=S0a, P=Pa; P=(S0=S0a,Pa) ).

mpred_tidy((P1;P2),(Q1;Q2)) :- !, mpred_tidy(P1,Q1), mpred_tidy(P2,Q2). mpred_tidy(((P1,P2),P3),Q) :- mpred_tidy((P1,(P2,P3)),Q). mpred_tidy((P1,P2),(Q1,Q2)) :- !, mpred_tidy(P1,Q1), mpred_tidy(P2,Q2). mpred_tidy(A,A) :- !.

compile_mpredg :- ((retract((L -->> R)), mpred_translate_rule((L -->> R), PfcRule)); (retract((L --*>> R)), mpred_translate_rule((L --*>> R), PfcRule))), fcAdd(PfcRule), fail. compile_mpredg.

parse(Words) :- parse(Words,Id), format("~Nsentence id = ~w",Id), show(Id,sentence(X)).

parse(Words,Id) :- gen_s_tag(Id), parse1(Words,Id), fcAdd(sentence(Id,Words)).

parse1([],_) :- !. parse1([H|T],Id) :- do(fcAdd(ss(word(H),Id,([H|T]\T)))), parse1(T,Id).

showSentences(Id) :- showSentences(Id,_).

showSentences(Id,Words) :- sentence(Id,Words), pfc(ss(s(S),Id,(Words\[]))), nl,write(S), fail. showSentences(_,_).

do(X) :- call(X) -> true;true.

show(Id,C) :- pfc(ss(C,Id,A\B)), append(Words,B,A), format("~n ~w : ~w",[C,Words]), fail.

gen_s_tag(s(N2)) :- var(V), (retract(s_tag(N)); N=0), N2 is N+1, assert(s_tag(N2)).

make_term(ss(Constituent,Id,String),Term) :- Constituent =.. [Name|Args], name(Name,Name_string), name(Name2,[36|Name_string]), append([Name2|Args],[Id,String],Term_string), Term =.. Term_string. append([],X,X). append([H|T],L2,[H|L3]) :- append(T,L2,L3).

% -*-Prolog-*-

:- dynamic ('-->>')/2. :- dynamic ('--*>>')/2.

% a simple pfc dcg grammar. requires dcg_mpred.pl

% backward grammar rules. s(s(Np,Vp)) -->> np(Np), vp(Vp).

vp(vp(V,Np)) -->> verb(V), np(Np). vp(vp(V)) -->> verb(V). vp(vp(VP,X)) -->> vp(VP), pp(X).

np(np(N,D)) -->> det(D), noun(N). np(np(N)) -->> noun(N). np(np(Np,pp(Pp))) -->> np(Np), pp(Pp).

pp(pp(P,Np)) -->> prep(P), np(Np).

% forward grammar rules. P --*>> [W],{cat(W,Cat),P =.. [Cat,W]}.

% simple facts. cat(the,det). cat(a,det). cat(man,noun). cat(fish,noun). cat(eats,verb). cat(catches,verb). cat(in,prep). cat(on,prep). cat(house,noun). cat(table,noun).

% tweety is a canary. ==> canary(tweety).

%% some simple tests to see if Pfc is working properly

time(Call,Time) :- statistics(runtime,_), db_call(Call), statistics(runtime,[_,Time]).

%test0 :- ain([(p(X) ==> q), p(1), (p(X), ~r(X) ==> s(X)), (t(X), {X>0} ==> r(X)), (t(X), {X<0} ==> minusr(X)), t(-2), t(1)]).

%test1 :- consult('pfc/kinship.pfc'), consult('pfc/finin.pfc').

:- dynamic((a/2,b/2,found/1)).

%test2 :- ain([(a(X),~b(Y)/(Y>X) ==> biggest(a)), (b(X),~a(Y)/(Y>X) ==> biggest(b)), a(5)]).

test3 :- ain([(a(X),\+(b(Y))/(Y>X) ==> biggest(a)), (b(X),\+a((Y))/(Y>X) ==> biggest(b)), a(5)]).

%test4 :- ain([(foo(X), bar(Y)/{X=:=Y} ==> foobar(X)), (foobar(X), go ==> found(X)), (found(X), {X>=100} ==> big(X)), (found(X), {X>=10,X<100} ==> medium(X)), (found(X), {X<10} ==> little(X)), foo(1), bar(2), bar(1), foo(100), goAhead, bar(100) ]).

%test5 :- ain([(faz(X), ~baz(Y)/{X=:=Y} ==> fazbaz(X)), (fazbaz(X), go ==> found(X)), (found(X), {X>=100} ==> big(X)), (found(X), {X>=10,X<100} ==> medium(X)), (found(X), {X<10} ==> little(X)), faz(1), goAhead, baz(2), baz(1) ]).

%test6 :- ain([(d(X), ~f(Y)/{X=:=Y} ==> justD(X)), (justD(X), go ==> dGo(X)), d(1), go, f(1) ]).

%test7 :- ain([(g(X), h(Y)/{X=:=Y} ==> justG(X)), (justG(X), go ==> gGo(X)), g(1), go, h(1) ]).

test8 :- ain([(j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y), go ==> jkGo(X,Y)), j(1), go, k(2) ]).

test9 :- ain([(j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y) ==> jkGo(X,Y)), j(1), k(2) ]).

test10 :- ain([ (j(X), k(Y) ==> bothJK(X,Y)), (bothJK(X,Y), go ==> jkGo(X,Y)), j(1), go, k(2) ]).

:- next_test. % ==

% if we learn that someone has a full name, then we know they are a 'lmcode'. full_name(U,_) ==> 'lmcode'(U).

% if we learn that someone has a host name, then we know they are a 'lmcode'. host_name(U,_) ==> 'lmcode'(U).

% when we know a 'lmcode''s full name and host name, make a 'lmcode'/3 assertion. 'lmcode'(User), full_name(User,Name), host_name(User,Host) ==> 'lmcode'(User,Name,Host).

% the mpred_default full_name for a 'lmcode' is 'unknown'. 'lmcode'(User), ~full_name(User,X)/(X\==unknown) ==> full_name(User,unknown).

% the mpred_default host_name for a 'lmcode' is 'unknown'. 'lmcode'(User), ~host_name(User,X)/(X\==unknown) ==> host_name(User,unknown).

==> full_name(finin,'Tim Finin').

==> host_name(finin,antares).

==> full_name(robin,'Robin,McEntire').

==> host_name(fritzson,hamlet).

:- next_test. % ==

skCheck(eq(_,_),[]) :- !.

skCheck(P,Rules) :- sk(P,L), bagof(Rule, S^(member(S,L), skNoticer(P,S,Rule)), Rules).

% L is a list of the skolem constants found in the term P. sk(P,L) :- sk1(P,[],L).

sk1(P,L,[P|L]) :- skolemConstant(P), !, \+member(P,L), !.

sk1(P,L,L) :- skolemConstant(P), !.

sk1(P,L,L) :- atomic(P),!.

sk1([Head|Tail], Lin, Lout) :- !, sk1(Head,Lin,Ltemp), sk1(Tail,Ltemp,Lout).

sk1(P,Lin,Lout) :- P =.. Plist, sk1(Plist,Lin,Lout).

% a skolem constant is any term sk/1. skolemConstant(sk(_)).

% make a Pfc rule to add new facts based on equality info about skolem terms. skNoticer(P,Sk,(eq(Sk,X)==>P2)) :- termSubst(Sk,X,P,P2).

% list Lisp's subst, but for terms.

termSubst(Old,New,Old,New) :- !.

termSubst(_,_,Term,Term) :- atomic(Term),!.

termSubst(Old,New,[Head|Tail],[Head2|Tail2]) :- !, termSubst(Old,New,Head,Head2), termSubst(Old,New,Tail,Tail2).

termSubst(Old,New,Term,Term2) :- Term =.. TermList, termSubst(Old,New,TermList,TermList2), Term2 =.. TermList2.

%:- ain((P/( \+P=eq(_,_)) ==> {skCheck(P,Rules)}, Rules)). :- ain((P ==> {skCheck(P,Rules)}, Rules)).

:- ain((eq(X,Y) <==> eq(Y,X))).

:- next_test. % == %% a simple Knowledge Representation Language: %% class(Class) %% isa(Individual,Class) %% genls(SuperClass,SubClass) %% role(Class,Role) %% type(Class,Role,Type) %% range(Class,Role,Range)

% roles are inherited. role(Super,R), genls(Super,Sub) ==> role(Sub,R).

% types are inherited. type(Super,Role,Type), genls(Super,Sub) ==> type(Sub,Role,Type).

% classification rule genls(Super,Sub), genls(Super,SubSub), {Sub \== SubSub}, \+ neg(subsumes(Sub,SubSub)), \+ neg(primitive(SubSub)) ==> genls(Sub,SubSub).

disjoint(C1,C2) ==> disjoint(C2,C1).

neg(subsume(C1,C2)) <- genls(C2,C1).

neg(subsumes(C1,C2)) <- disjoint(C1,C2).

neg(subsumes(C1,C2)) <- % we can't infer that C1 subsumes C2 if C1 has a role that C2 doen't. role(C1,R), \+ role(C2,R).

neg(subsumes(C1,C2)) <- % we can't infer that C1 subsumes C2 if C1 has a role a type that... type(C1,R,T1), type(C2,R,T2), neg(subsume(T1,T2)).

:- export otherGender/2. :- next_test. % ==

% kinship domain example.

spouse(P1,P2) <==> spouse(P2,P1).

spouse(P1,P2), gender(P1,G1), {otherGender(G1,G2)} ==> gender(P2,G2).

==>otherGender(male,female). ==>otherGender(female,male).

gender(P,male) <==> male(P).

gender(P,female) <==> female(P).

parent(X,Y), female(X) <==> mother(X,Y).

parent(P1,P2), parent(P2,P3) ==> grandParent(P1,P3).

grandParent(P1,P2), male(P1) <==> grandFather(P1,P2).

grandParent(P1,P2), female(P1) <==> grandMother(P1,P2).

mother(Ma,Kid), parent(Kid,GrandKid) ==> grandMother(Ma,GrandKid).

parent(X,Y), male(X) <==> father(X,Y).

parent(Ma,P1), parent(Ma,P2), {P1\==P2} ==> sibling(P1,P2).

spouse(P1,P2), spouse(P1,P3), {P2\==P3} ==> bigamist(P1), {format("~N~w is a bigamist, married to both ~w and ~w~n",[P1,P2,P3])}.

% here is an example of a mpred_default rule

parent(P1,X), parent(P2,X)/(P1\==P2), \+ spouse(P1,P3)/(P3\==P2), \+ spouse(P2,P4)/(P4\==P1) ==> spouse(P1,P2).

uncle(U,P1), parent(U,P2) ==> cousin(P1,P2).

aunt(U,P1), parent(U,P2) ==> cousin(P1,P2).

parent(P,K), sibling(P,P2)

==>

(female(P2) ==> aunt(P2,K), (spouse(P2,P3) ==> uncle(P3,K))),

(male(P2) ==> uncle(P2,K), (spouse(P2,P3) ==> aunt(P3,K))).

:- next_test. % ==

%% equality axiomm

equal(A,B) ==> equal(B,A).

equal(A,B),{\+A=B},equal(B,C),{\+A=C} ==> equal(A,C).

notequal(A,B) ==> notequal(B,A).

notequal(A,B),equal(A,C) ==> notequal(C,B).

show_mpred_fact(P) :- send_editor(['(show-assertion "',P,'")']).

hide_mpred_fact(P) :- send_editor(['(hide-assertion "',P,'")']).

demons(P, WhenAdded, WhenRemoved) ==> (P ==> {WhenAdded}), fcUndoMethod(WhenAdded,WhenRemoved).

show(P) ==> demons(P,show_mpred_fact(P),hide_mpred_fact(P)).

:- next_test. % ==

:- op(1050,xfx,('===>')).

(P ===> Q) ==> (P ==> Q), (neg(Q) ==> neg(P)).

or(P,Q) ==> (neg(P) ==> Q), (neg(Q) ==> P).

prove_by_contradiction(P) :- P. prove_by_contradiction(P) :- \+ (neg(P) ; P), ain(neg(P)), P -> pfcRem(neg(P)) ; (pfcRem(neg(P)),fail).

==> or(p,q). ==> (p ===> x). ==> (q ===> x).

% try :- prove_by_contradiction(x).

:- prolog.

:- next_test. % == % here is an example which defines mpred_default facts and rules. Will it work?

(mpred_default(P)/mpred_literal(P)) ==> (~neg(P) ==> P).

mpred_default((P ==> Q))/mpred_literal(Q) ==> (P, ~neg(Q) ==> Q).

% birds fly by mpred_default. ==> mpred_default((bird(X) ==> fly(X))).

% here's one way to do an scl hierarchy. % scl = genls.

scl(C1,C2) ==> {P1 =.. [C1,X], P2 =.. [C2,X]}, (P1 ==> P2).

==> scl(canary,bird). ==> scl(penguin,bird).

% penguins do neg fly. penguin(X) ==> neg(fly(X)).

% chilly is a penguin. ==> penguin(chilly).

% tweety is a canary. ==> canary(tweety).

% is this how to define constraints?

either(P,Q) ==> (neg(P) ==> Q), (neg(Q) ==> P).

(P,Q ==> false) ==> (P ==> neg(Q)), (Q ==> neg(P)).

:- next_test. % == % here is an interesting rule!

neg(P), P ==> contradiction(P).

contradiction(P) ==> {format('~n% contradiction - both ~w and neg(~w) added.~n',[P,P])}.

% this means that both P and Q can't be true. disjoint(P,Q) ==> (P ==> neg(Q)), (Q ==> neg(P)).

==> disjoint(male(P), female(P)).

==> male(shirley).

==> mother(shirley,mary).

mother(X,_Y) ==> female(X).

bel(A1,desire(A2,know(A2,bel(A1,P)))), self(A1), bel(A1,P) ==> tell(A1,A2,P).

bel(A1,desire(A2,knowif(A2,P))), self(A1), bel(A1,neg(P)) ==> tell(A1,A2,neg(P)).

==> fact(0,1). ==> fact(1,1). ==> fact(2,2). fact(N,M) <- {N>0,N1 is N-1}, fact(N1,M1), {M is N*M1}.

==> fib(1,1). ==> fib(2,1). fib(N,M) <- {N>2,N1 is N-1,N2 is N-2}, fib(N1,M1), fib(N2,M2), {M is M1+M2}.

:- next_test. % ==

mudAtLoc(Obj,NewLoc), {(mudAtLoc(Obj,OldLoc), OldLoc\==NewLoc)} ==> ~mudAtLoc(Obj,OldLoc).

localityOfObject(Obj,NewLoc), {(localityOfObject(Obj,OldLoc), OldLoc\==NewLoc)} ==> ~localityOfObject(Obj,OldLoc).

function(P) ==> {P1 =.. [P,X,Y], P2 =.. [P,X,Z]}, (P1,{(P2,Y\==Z)} ==> ~P2).

==> function(age).

function(Name,Arity) ==> {functor(P1,Name,Arity), functor(P2,Name,Arity), arg(Arity,P1,PV1), arg(Arity,P2,PV2), N is Arity-1, merge(P1,P2,N)}, (P1,{(P2,PV1\==PV2)} ==> ~P2).

merge(_,_,N) :- N<1. merge(T1,T2,N) :- N>0, arg(N,T1,X), arg(N,T2,X), N1 is N-1, merge(T1,T2,N1).

neg(P),P ==> contrradiction.

bird(X), ~neg(fly(X)) ==> fly(X).

penguin(X) ==> bird(X).

penguin(X) ==> neg(fly(X)).

bird(X), injured(X) ==> neg(fly(X)).

bird(X), dead(X) ==> neg(fly(X)).

:- pfcPrintDB.

:- next_test.

% dcg_mpred: translation of dcg-like grammar rules into pfc rules.

:- op(1200,xfx,'-->>'). :- op(1200,xfx,'--*>>'). % :- op(1200,xfx,'<<--'). :- op(400,yfx,'^^').

% :- use_module(library(strings)), use_module(library(lists)).

term_expansion((P -->> Q),(:- ain(Rule))) :- mpred_translate_rule((P -->> Q), Rule). term_expansion((P --*>> Q),(:- ain(Rule))) :- mpred_translate_rule((P --*>> Q), Rule).

mpred_translate_rule((LP-->>[]),H) :- !, mpred_t_lp(LP,Id,S,S,H). mpred_translate_rule((LP-->>RP),(H <- B)):- mpred_t_lp(LP,Id,S,SR,H), mpred_t_rp(RP,Id,S,SR,B1), mpred_tidy(B1,B).

mpred_translate_rule((LP--*>>[]),H) :- !, mpred_t_lp(LP,Id,S,S,H). mpred_translate_rule((LP--*>>RP),(B ==> H)):- mpred_t_lp(LP,Id,S,SR,H), mpred_t_rp(RP,Id,S,SR,B1), mpred_tidy(B1,B).

mpred_t_lp(X,Id,S,SR,ss(X,Id,(S ^^ SR))) :- var(X),!.

mpred_t_lp((LP,List),Id,S,SR,ss(LP,Id,(S ^^ List2))):- !, pfcAppend(List,SR,List2).

mpred_t_lp(LP,Id,S,SR,ss(LP,Id,(S ^^ SR))).

mpred_t_rp(!,Id,S,S,!) :- !. mpred_t_rp([],Id,S,S1,S=S1) :- !. mpred_t_rp([X],Id,S,SR,ss(word(X),Id,(S ^^ SR))) :- !. mpred_t_rp([X|R],Id,S,SR,(ss(word(X),Id,(S ^^ SR1)),RB)) :- !, mpred_t_rp(R,Id,SR1,SR,RB). mpred_t_rp({T},Id,S,S,{T}) :- !. mpred_t_rp((T,R),Id,S,SR,(Tt,Rt)) :- !, mpred_t_rp(T,Id,S,SR1,Tt), mpred_t_rp(R,Id,SR1,SR,Rt). mpred_t_rp((T;R),Id,S,SR,(Tt;Rt)) :- !, mpred_t_or(T,Id,S,SR,Tt), mpred_t_or(R,Id,S,SR,Rt). mpred_t_rp(T,Id,S,SR,ss(T,Id,(S ^^ SR))).

mpred_t_or(X,Id,S0,S,P) :- mpred_t_rp(X,Id,S0a,S,Pa), ( var(S0a), S0a \== S, !, S0=S0a, P=Pa; P=(S0=S0a,Pa) ).

mpred_tidy((P1;P2),(Q1;Q2)) :- !, mpred_tidy(P1,Q1), mpred_tidy(P2,Q2). mpred_tidy(((P1,P2),P3),Q) :- mpred_tidy((P1,(P2,P3)),Q). mpred_tidy((P1,P2),(Q1,Q2)) :- !, mpred_tidy(P1,Q1), mpred_tidy(P2,Q2). mpred_tidy(A,A) :- !.

compile_mpredg :- ((retract((L -->> R)), mpred_translate_rule((L -->> R), PfcRule)); (retract((L --*>> R)), mpred_translate_rule((L --*>> R), PfcRule))), ain(PfcRule), fail. compile_mpredg.

parse(Words) :- parse(Words,Id), format("~Nsentence id = ~w",Id), show(Id,sentence(X)).

parse(Words,Id) :- gen_s_tag(Id), parse1(Words,Id), ain(sentence(Id,Words)).

parse1([],_) :- !. parse1([H|T],Id) :- do_or_ignore(ain(ss(word(H),Id,([H|T] ^^ T)))), parse1(T,Id).

showSentences(Id) :- showSentences(Id,_).

showSentences(Id,Words) :- sentence(Id,Words), pfc(ss(s(S),Id,(Words ^^ []))), nl,write(S), fail. showSentences(_,_).

do_or_ignore(X) :- db_call(X) -> true;true.

show(Id,C) :- pfc(ss(C,Id,A ^^ B)), append(Words,B,A), format("~n ~w : ~w",[C,Words]), fail.

gen_s_tag(s(N2)) :- var(V), (retract(s_tag(N)); N=0), N2 is N+1, assert(s_tag(N2)).

make_term(ss(Constituent,Id,String),Term) :- Constituent =.. [Name|Args], name(Name,Name_string), name(Name2,[36|Name_string]), append([Name2|Args],[Id,String],Term_string), Term =.. Term_string. %append([],X,X). %append([H|T],L2,[H|L3]) :- append(T,L2,L3).

:- next_test. % ==

:- dynamic ('-->>')/2. :- dynamic ('--*>>')/2.

% a simple pfc dcg grammar. requires dcg_mpred.pl

% backward grammar rules. s(s(Np,Vp)) -->> np(Np), vp(Vp).

vp(vp(V,Np)) -->> verb(V), np(Np). vp(vp(V)) -->> verb(V). vp(vp(VP,X)) -->> vp(VP), pp(X).

np(np(N,D)) -->> det(D), noun(N). np(np(N)) -->> noun(N). np(np(Np,pp(Pp))) -->> np(Np), pp(Pp).

pp(pp(P,Np)) -->> prep(P), np(Np).

% forward grammar rules. P --*>> [W],{cat(W,Cat),P =.. [Cat,W]}.

% simple facts. cat(the,det). cat(a,det). cat(man,noun). cat(fish,noun). cat(eats,verb). cat(catches,verb). cat(in,prep). cat(on,prep). cat(house,noun). cat(table,noun).

end_of_file.

:- next_test. % ==

%% a simple Pfc example - the three bulb problem (see DeKleer and %% Williams, IJCAI89) %% %% Tim Finin, finin@prc.unisys.com, 8/89

% Devices behave as intended unless they are faulty. isa(X,Class), ~faulty(X) ==> behave(X,Class).

% connecting two terminals means their voltages are equal. connect(T1,T2) ==> (voltage(T1,V) <==> voltage(T2,V)).

equal(voltage(T1),voltage(T2)) <- connect(T1,T2).

% a wire behaves by connecting its two terminals. behave(X,wire) ==> connect(t1(X),t2(X)).

% a battery's behaviour behave(X,battery), rating(X,V) ==> voltage(t1(X),V), voltage(t2(X),0).

% a bulb's behaviour. behave(X,bulb) ==> (voltage(t1(X),V1),voltage(t2(X),V2), {V1\==V2} ==> lit(X)), (notequal(voltage(t1(X)),voltage(t2(X))) ==> lit(X)).

lit(X) ==> notequal(voltage(t1(X)),voltage(t2(X))).

% a pretty basic conflict. neg(P), P ==> conflict(P).

% this doesn't work anyomore. twf. % voltage(T,V) ==> (neg(voltage(T,V2)) <- {\+V=:=V2}).

% It is a conflict if a terminal has two different voltages. voltage(T,V1), voltage(T,V2)/( \+V1=:=V2) ==> conflict(two_voltages(T,V1,V2)).

% assume an observation is true. observed(P), ~false_observation(P) ==> P.

% a conflict triggers a Prolog action to resolve it. conflict(C) ==> {resolveConflict(C)}.

% this isn't written yet. resolveConflict(C) :- format("~NHalting with conflict ~w", [C]), mpred_halt.

% meta rules to schedule inferencing.

% resolve conflicts asap mpred_select(conflict(X),S) :- mpred_queue(conflict(X),S).

%% * here is a particular test case. *

% here is a particular circuit - a gizmo.

isa(X,gizmo) ==> isa(battery(X),battery), rating(battery(X),6),

isa(b1(X),bulb), isa(b2(X),bulb), isa(b3(X),bulb),

isa(w1(X),wire), isa(w2(X),wire), isa(w3(X),wire), isa(w4(X),wire), isa(w5(X),wire), isa(w6(X),wire),

connect(t1(battery(X)),t1(w1(X))), connect(t2(w1(X)),t1(b1(X))), connect(t2(w1(X)),t1(w2(X))), connect(t2(w2(X)),t1(b2(X))), connect(t2(w2(X)),t1(w3(X))), connect(t2(w3(X)),t1(b3(X))),

connect(t2(battery(X)),t1(w4(X))), connect(t2(w4(X)),t2(b2(X))), connect(t2(w4(X)),t1(w5(X))), connect(t2(w5(X)),t2(b2(X))), connect(t2(w5(X)),t1(w6(X))), connect(t2(w6(X)),t2(b3(X))).

%% here is a diagnostic problem for a gizmo.

test_bs(X) :- ain([isa(X,gizmo), observed(neg(lit(b1(X)))), observed(neg(lit(b2(X)))), observed(lit(b3(X)))]).

:- next_test. % ==

%% a simple Pfc example - the one bulb problem (see DeKleer and %% Williams, IJCAI89) %% %% Tim Finin, finin@prc.unisys.com, 8/89

% Devices behave as intended unless they are faulty. isa(X,Class), ~faulty(X) ==> behave(X,Class).

% assume an observation is true. observed(P), ~false_observation(P) ==> P.

% connecting two terminals means their voltages are equal. con(T1,T2) ==> (volt(T1,V) <==> volt(T2,V)).

% a wire behaves by connecting its two terminals. behave(X,wire) ==> con(t1(X),t2(X)).

% a battery's behaviour behave(X,battery) ==> volt(t1(X),1.5), volt(t2(X),0).

% a bulb's behaviour. behave(X,bulb), volt(t1(X),V1), volt(t2(X),V2), {V1\==V2} ==> lit(X).

% It is a conflict if a terminal has two different voltages. % volt(T,V1), volt(T,V2)/( \+V1=:=V2) ==> conflict(two_voltages(T,V1,V2)).

%% * here is a particular test case. *

% here is a particular circuit - a gizmo.

isa(X,gizmo) ==> isa(battery(X),battery), isa(bulb(X),bulb),

isa(w1(X),wire), isa(w2(X),wire),

con(t1(battery(X)),t1(w1(X))), con(t2(battery(X)),t1(w2(X))), con(t2(w1(X)),t1(bulb(X))), con(t2(bulb(X)),t2(w2(X))).

%% here is a diagnostic problem for a gizmo.

test_b1(X) :- ain([isa(X,gizmo), observed(neg(lit(bulb(X))))]).

:- next_test. % ==

%% a simple Pfc example - the standard circuit diagnosis problem. %% %% Tim Finin, finin@prc.unisys.com, 9/29/88

% Devices behave as intended unless they are faulty. isa(X,Class), ~faulty(X) ==> behave(X,Class).

% a wire equates the values mudAtLoc each end. wire(T1,T2) ==> (value(T1,V) <==> value(T2,V)).

% It is a conflict if a terminal has two different values. value(T,V1), value(T,V2)/( \+V1=:=V2) ==> conflict(two_values(T,V1,V2)).

% assume an observation is true. observed(P), ~false_observation(P) ==> P.

% a conflict triggers a Prolog action to resolve it. conflict(C) ==> {resolveConflict(C)}.

% this isn't written yet. resolveConflict(C) :- format("~NHalting with conflict ~w", [C]), mpred_halt.

% an adder's behaviour behave(X,adder) ==> (value(in(1,X),I1), value(in(2,X),I2) ==> {O is I1+I2}, value(out(X),O)), (value(in(2,X),I2) <- value(in(1,X),I1), value(out(X),O), {I2 is O-I1}), ( value(in(1,X),I1) <- value(in(2,X),I2), value(out(X),O), {I1 is O-I2}).

% a multiplier's behaviour. behave(X,multiplier) ==> (value(in(1,X),I1), value(in(2,X),I2) ==> {O is I1*I2}, value(out(X),O)), (value(in(2,X),I2) <- value(in(1,X),I1), value(out(X),O), {I2 is O/I1}), ( value(in(1,X),I1) <- value(in(2,X),I2), value(out(X),O), {I1 is O/I2}).

% meta rules to schedule inferencing.

% resolve conflicts asap mpred_select(conflict(X),S) :- mpred_queue(conflict(X),S).

%% * here is a particular test case. *

% here is a particular circuit - a gizmo.

isa(X,gizmo) ==> isa(m1(X),multiplier), isa(m2(X),multiplier), isa(m3(X),multiplier), isa(a1(X),adder), isa(a2(X),adder), wire(out(m1(X)),in(1,a1(X))), wire(out(m2(X)),in(2,a1(X))), wire(out(m2(X)),in(1,a2(X))), wire(out(m3(X)),in(2,a2(X))).

%% here is a diagnostic problem for a gizmo.

test(X) :- ain(isa(X,gizmo)), ain(value(in(1,m1(X)),3.0)), ain(value(in(2,m1(X)),2.0)), ain(value(in(1,m2(X)),3.0)), ain(value(in(2,m2(X)),2.0)), ain(value(in(1,m3(X)),2.0)), ain(value(in(2,m3(X)),3.0)), ain(observed(value(out(a1(X)),10.0))), ain(observed(value(out(a2(X)),12.0))).