我的任务是在Prolog中创建一个通用专家系统,你可以插入不同的知识库,所以它必须是通用的。我必须在专家系统中提供的知识库是Farmer Goat Wolf和Cabbage Puzzle。我在设计知识库和一般推理引擎时非常困难。
经过几天的搜索,我找到了一系列专家系统的例子,用于鸟类等级和其他一些可能的结果,但它们似乎无法帮助我解决这个问题。一起投射。
我只是想知道是否有人有一些很好的例子或材料如何在Prolog中设计专家系统或者哪里有好看的地方?
感谢您的帮助,非常感谢。
PS。我宁愿不购买材料,因为这是我上学的最后一个月,在这门课程结束后,我不大可能会做很多Prolog编程。
谢谢和问候,
d
修改
这是我的知识库。
% Order is Farmer, Goat, Wolf, Cabbage
start_state :: state(west_side, west_side, west_side, west_side).
fact :: current(X, X, X, X) :-
end_state :: state(X, X, X, X),
X = east_side.
move_goat ::
if
state(X, X, W, C) and
opp(X, Y) and
(unsafe(state(Y, Y, W, C)))
then
current(Y, Y, W, C).
move_wolf ::
if
state(X, G, X, C) and
opp(X, Y) and
(unsafe(state(Y, G, Y, C)))
then
current(Y, G, Y, C).
move_cabbage ::
if
state(X, G, W, X) and
opp(X, Y) and
(unsafe(state(Y, G, W, Y)))
then
current(Y, G, W, Y).
% Move the object to the other side of the river
opp(west_side, east_side).
opp(east_side, west_side).
% Is the new state unsafe
fact :: unsafe(state(X,Y,Y,C)) :- opp(X,Y).
fact :: unsafe(state(X,Y,W,Y)) :- opp(X,Y).
这是专家系统我试图改进我的知识库。
:-op(900, xfx, ::).
:-op(800, xfx, was).
:-op(880, xfx, then).
:-op(870, fx, if).
:-op(600, xfx, from).
:-op(600, xfx, by).
:-op(550, xfy, or).
:-op(540, xfy, and).
:-op(300, fx, 'derived by').
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
main :-
consult('FarmerKB.pl'),
assertz(lastindex(0)),
assertz(wastold(dummy, false, 0)),
assertz(end_answers(dummy)),
expert.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
expert :-
getquestion(Question),
( answeryes(Question)
;
answerno(Question)
).
answeryes(Question) :-
markstatus(negative),
explore(Question, [], Answer),
positive(Answer),
markstatus(positive),
present(Answer), nl,
write('More Solutions?'),
getreply(Reply),
Reply = no.
answerno(Question) :-
retract(no_positive_answer_yet), !,
explore(Question, [], Answer),
negative(Answer),
present(Answer), nl,
write('More Negative Solutions?'),
getreply(Reply),
Reply = no.
markstatus(negative) :-
assertz(no_positive_answer_yet).
markstatus(positive) :-
retract(no_positive_answer_yet), !
;
true.
getquestion(Question) :-
nl, write('Question Please'), nl,
read(Question).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
explore(Goal, Trace, Goal is true was 'found as a fact') :-
fact :: Goal.
explore(Goal, Trace, Goal is TruthValue was 'derived by' Rule from Answer) :-
Rule :: if Condition then Goal,
explore(Condition, [Goal by Rule | Trace], Answer),
truth(Answer, TruthValue).
explore(Goal1 and Goal2, Trace, Answer) :- !,
explore(Goal1, Trace, Answer1),
continue(Answer1, Goal1 and Goal2, Trace, Answer).
explore(Goal1 or Goal2, Trace, Answer) :-
exploreyes(Goal1, Trace, Answer)
;
exploreyes(Goal2, Trace, Answer).
explore(Goal1 or Goal2, Trace, Answer1 and Answer2) :- !,
not(exploreyes(Goal1, Trace, _)),
not(exploreyes(Goal2, Trace, _)),
explore(Goal1, Trace, Answer1),
explore(Goal2, Trace, Answer2).
explore(Goal, Trace, Goal is Answer was told) :-
useranswer(Goal, Trace, Answer).
exploreyes(Goal, Trace, Answer) :-
explore(Goal, Trace, Answer),
positive(Answer).
continue(Answer1, Goal1 and Goal2, Trace, Answer) :-
positive(Answer1),
explore(Goal2, Trace, Answer2),
( positive(Answer2),
Answer = Answer1 and Answer2
;
negative(Answer2),
Answer = Answer2
).
continue(Answer1, Goal1 and Goal2, _, Answer1) :-
negative(Answer1).
truth(Question is TruthValue was found, TruthValue) :- !.
truth(Answer1 and Answer2, TruthValue) :-
truth(Answer1, true),
truth(Answer2, true), !,
TruthValue = true
;
TruthValue = false.
positive(Answer) :-
truth(Answer, true).
negative(Answer) :-
truth(Answer, false).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
getreply(Reply) :-
read(Answer),
means(Answer, Reply), !
;
nl, write('Answer unknown, try again please'), nl,
getreply(Reply).
means(yes, yes).
means(y, yes).
means(no, no).
means(n, no).
means(why, why).
means(w, why).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
useranswer(Goal, Trace, Answer) :-
askable(Goal, _),
freshcopy(Goal, Copy),
useranswer(Goal, Copy, Trace, Answer, 1).
useranswer(Goal, _, _, _, N) :-
N > 1,
instantiated(Goal), !,
fail.
useranswer(Goal, Copy, _, Answer, _) :-
wastold(Copy, Answer, _),
instance_of(Copy, Goal), !.
useranswer(Goal, _, _, true, N) :-
wastold(Goal, true, M),
M >= N.
useranswer(Goal, Copy, _, Answer, _) :-
end_answers(Copy),
instance_of(Copy, Goal), !,
fail.
useranswer(Goal, _, Trace, Answer, N) :-
askuser(Goal, Trace, Answer, N).
askuser(Goal, Trace, Answer, N) :-
askable(Goal, ExternFormat),
format(Goal, ExternFormat, Question, [], Variables),
ask(Goal, Question, Variables, Trace, Answer, N).
ask(Goal, Question, Variables, Trace, Answer, N) :-
nl,
( Variables = [], !,
write('Is it true:')
;
write('Any (more) solution to:')
),
write(Question), write('?'),
getreply(Reply), !,
process(Reply, Goal, Question, Variables, Trace, Answer, N).
process(why, Goal, Question, Variables, Trace, Answer, N) :-
showtrace(Trace),
ask(Goal, Question, Variables, Trace, Answer, N).
process(yes, Goal, _, Variables, Trace, true, N) :-
nextindex(Next),
Next1 is Next + 1,
( askvars(Variables),
assertz(wastold(Goal, true, Next))
;
freshcopy(Goal, Copy),
useranswer(Goal, Copy, Trace, Answer, Next1)
).
process(no, Goal, _, _, _, false, N) :-
freshcopy(Goal, Copy),
wastold(Copy, true, _), !,
assertz(end_answers(Goal)),
fail
;
nextindex(Next),
assertz(wastold(Goal, false, Next)).
format(Var, Name, Name, Vars, [Var/Name | Vars]) :-
var(Var), !.
format(Atom, Name, Atom, Vars, Vars) :-
atomic(Atom), !,
atomic(Name).
format(Goal, Form, Question, Vars0, Vars) :-
Goal =..[Functor | Args1],
Form =..[Functor | Forms],
formatall(Args1, Forms, Args2, Vars0, Vars),
Question =..[Functor | Args2].
formatall([], [], [], Vars, Vars).
formatall([X | XL], [F | FL], [Q | QL], Vars0, Vars) :-
formatall(XL, FL, QL, Vars0, Vars1),
format(X, F, Q, Vars1, Vars).
askvars([]).
askvars([Variable/Name | Variables]) :-
nl, write(Name), write(' = '),
read(Variable),
askvars(Variables).
showtrace([]) :-
nl, write('This was you question'), nl.
showtrace([Goal by Rule | Trace]) :-
nl, write('To investigate, by'),
write(Rule), write(','),
write(Goal),
showtrace(Trace).
instantiated(Term) :-
numbervars(Term, 0, 0).
instance_of(Term, Term1) :-
freshcopy(Term1, Term2),
numbervars(Term2, 0, _), !,
Term = Term2.
freshcopy(Term, FreshTerm) :-
asserta(copy(Term)),
retract(copy(FreshTerm)), !.
nextindex(Next) :-
retract(lastindex(Last)), !,
Next is Last + 1,
assertz(lastindex(Next)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
present(Answer) :-
nl, showconclusion(Answer),
nl, write('Would you like to see how?'),
getreply(Reply),
( Reply = yes, !,
show(Answer)
;
true
).
showconclusion(Answer1 and Answer2) :- !,
showconclusion(Answer1), write('and '),
showconclusion(Answer2).
showconclusion(Conclusion was Found) :-
write(Conclusion).
show(Solution) :-
nl, show(Solution0), !.
show(Answer1 and Answer2, H) :- !,
show(Answer1, H),
tab(H), write(and), nl,
show(Answer2, H).
show(Answer was Found, H) :-
tab(H), writeans(Answer),
nl, tab(H),
write('was '),
show1(Found, H).
show1(Derived from Answer, H) :- !,
write(Derived), write('from'),
nl, H1 is H + 4,
show(Answer, H1).
show1(Found, _) :-
write(Found), nl.
writeans(Goal is true) :- !,
write(Goal).
writeans(Answer) :-
write(Answer).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Negate the current statement
not(P) :-
P, !, fail
;
true.
谢谢,
d
答案 0 :(得分:0)
对于那些正在努力解决类似问题的人,我能够使用amzi.com和George Luger的例子中的教程,为农民和山羊问题提供一个有效的知识库/专家系统。
http://www.amzi.com/ExpertSystemsInProlog/xsiptop.php
http://www.cs.unm.edu/~luger/
http://www.cs.unm.edu/~luger/ai-final/code/
由于这是最艰难的部分,我只发布知识库。
rule((move(St1, Cu1) :-
(start(state(St1, St2, St3, St4)),
switch(state(St1, St2, St3, St4), state(Cu1, Cu2, Cu3, Cu4), [state(St1, St2, St3, St4)]))), 100).
start(state(east_side, east_side, east_side, east_side)).
end(state(west_side, west_side, west_side, west_side)).
switch(state(F1, G1, W1, C1), state(F2, G2, W2, C2), History) :-
is_end(state(F1, G1, W1, C1))
;
move_state(state(F1, G1, W1, C1), state(F2, G2, W2, C2)),
not(is_history(state(F2, G2, W2, C2), History)),
switch(state(F2, G2, W2, C2), state(F3, G3, W3, C3), [state(F2, G2, W2, C2)|History]).
move_state(state(X,X,W,C), state(Y,Y,W,C)) :-
opp(X,Y), not(unsafe(state(Y,Y,W,C))).
move_state(state(X,G,X,C), state(Y,G,Y,C)) :-
opp(X,Y), not(unsafe(state(Y,G,Y,C))).
move_state(state(X,G,W,X), state(Y,G,W,Y)) :-
opp(X,Y), not(unsafe(state(Y,G,W,Y))).
move_state(state(X,G,W,C), state(Y,G,W,C)) :-
opp(X,Y), not(unsafe(state(Y,G,W,C))).
opp(east_side, west_side).
opp(west_side, east_side).
unsafe(state(X, Y, Y, C)) :- opp(X, Y).
unsafe(state(X, Y, W, Y)) :- opp(X, Y).
is_end(state(F1, G1, W1, C1)) :-
end(state(Side1, Side2, Side3, Side4)),
Side1 == F1, Side2 == G1,
Side3 == W1, Side4 == C1.
is_history(state(F1, G1, W1, C1), []) :-
fail.
is_history(state(F1, G1, W1, C1), [HisHead|HisTail]) :-
state(F1, G1, W1, C1) == HisHead
;
is_history(state(F1, G1, W1, C1), HisTail).
% This has to be added if there are no ask-able questions otherwise the program will fail
askable(test).