| 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))).