专家系统中的 Prolog 和 "reverse" 输出
Prolog and "reverse" output in expert system
我是 Prolog 的新手。我想知道如何做简单的专家系统,比如
go :- hypothesize(Vehicle),
write('I guess that the Vehicle is: '),
write(Vehicle), nl, undo.
hypothesize(car) :- car, !.
hypothesize(van) :- van,!.
hypothesize(bike) :- bike, !.
hypothesize(mini) :- mini, !.
hypothesize(tank) :-tank, !.
hypothesize(sau) :- sau, !.
hypothesize(excavator) :- excavator, !.
hypothesize(bulldozer) :- bulldozer, !.
hypothesize(rocket) :- rocket, !.
hypothesize(shuttle) :- shuttle , !.
hypothesize(destroyer) :- destroyer, !.
hypothesize(civil_plane) :- civil_plane, !.
hypothesize(unknown).
/* Vehicle identification rules */
sau :- grounder,
verify(has_gun),
verify(long_fire).
tank :- grounder,
verify(has_gun),
verify(short_fire).
excavator :- grounder,
verify(no_gun),
verify(have_ladle).
bulldozer :- grounder,
verify(no_gun),
verify(no_ladle).
car :- grounder,
verify(big_body),
verify(for_passengers).
van :- grounder,
verify(big_body),
verify(for_cargo).
bike :- grounder,
verify(small_body),
verify(two_wheels).
mini :- grounder,
verify(small_body),
verify(four_wheels).
rocket :- flying,
verify(cosmos_flying),
verify(can_return).
shuttle :- flying,
verify(cosmos_flying),
verify(cant_return).
destroyer :- flying,
verify(air_flying),
verify(warmade).
civil_plane :- flying,
verify(air_flying),
verify(civil).
/* classification rules */
grounder :- verify(has_wheels), !.
grounder :- verify(have_engine).
flying :- verify(has_wings), !.
flying :- verify(has_jets).
/* how to ask questions */
ask(Question) :-
write('Does the vehicle have the following attribute: '),
write(Question), write('? '),
read(Response), nl,
( (Response == yes ; Response == y)
-> assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/* How to verify something */
verify(S) :- (yes(S) -> true ; (no(S) -> fail ; ask(S))).
/* undo all yes/no assertions */
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
这很好,但问题是 - 如何进行 "back" 输出,例如,我将在序言 window 中键入 "tank",他将给出所有部分这个坦克包括 - 像,枪 - 是的,短步枪 - 是的,机翼 - 不,e.t.c
是否可以在专家系统中这样做,或者我必须做另一个程序?
感谢您的回复
因为你的子句很简单,我想你可以像这样使用 clause/2
来做到这一点:
?- clause(grounder, X).
X = (verify(has_wheels), !) ;
X = verify(have_engine).
这看起来像这样:
part(Vehicle, Part) :-
clause(Vehicle, Body),
part_of_body(Body, Part).
part_of_body(verify(Part), Part).
part_of_body(X, Part) :-
atom(X), X \= '!', part(X, Part).
part_of_body((X,Y), Part) :-
part_of_body(X, Part)
; part_of_body(Y, Part).
这有点像元解释器。 clause/2
允许您以编程方式检查 Prolog 的规则。这是一种反射机制。 clause(Head, Body)
将 Head 与规则的名称统一起来,将 Body 与其主体统一起来——换句话说,Head :- Body
。所以当我们说 clause(tank, Body)
时,我们得到:
Body = (grounder, verify(has_gun), verify(short_fire)).
分解这个有点费力;毕竟,您必须遍历与您在规则中使用的一样多的 Prolog 本身。但这就是其余代码所做的。首先,我们获取 part/2
中的子句:请注意,我期望 Part 中的类型是车辆类型原子的类型。一旦我们获取了子句,我们就将它交给 part_of_body 来分解 Prolog 的结构。
从这里开始,基本情况类似于 verify(has_gun)
,它似乎包括您感兴趣的部分 (has_gun
),这就是规则 part_of_body(verify(Part), Part)
所说的.
递归情况是处理结构其余部分的情况,例如,如果我看到一个原子 grounder
,我会递归地查找那些部分,这就是 part_of_body(X, Part)
做。我对必须专门针对 !
进行测试并不感到兴奋,但我的方法存在一个我尚未修复的弱点。
主要的递归案例是处理连词的案例:(X,Y)
。这里我就说一下,在连词的第一部分找一些部分再试试第二部分
?- part(tank, Part).
Part = has_wheels ;
Part = have_engine ;
Part = has_gun ;
Part = short_fire.
所以这个数据库是可以反向操作的,就是不是特别方便。 :) 更好的数据模型将大大改善这种情况。
我是 Prolog 的新手。我想知道如何做简单的专家系统,比如
go :- hypothesize(Vehicle),
write('I guess that the Vehicle is: '),
write(Vehicle), nl, undo.
hypothesize(car) :- car, !.
hypothesize(van) :- van,!.
hypothesize(bike) :- bike, !.
hypothesize(mini) :- mini, !.
hypothesize(tank) :-tank, !.
hypothesize(sau) :- sau, !.
hypothesize(excavator) :- excavator, !.
hypothesize(bulldozer) :- bulldozer, !.
hypothesize(rocket) :- rocket, !.
hypothesize(shuttle) :- shuttle , !.
hypothesize(destroyer) :- destroyer, !.
hypothesize(civil_plane) :- civil_plane, !.
hypothesize(unknown).
/* Vehicle identification rules */
sau :- grounder,
verify(has_gun),
verify(long_fire).
tank :- grounder,
verify(has_gun),
verify(short_fire).
excavator :- grounder,
verify(no_gun),
verify(have_ladle).
bulldozer :- grounder,
verify(no_gun),
verify(no_ladle).
car :- grounder,
verify(big_body),
verify(for_passengers).
van :- grounder,
verify(big_body),
verify(for_cargo).
bike :- grounder,
verify(small_body),
verify(two_wheels).
mini :- grounder,
verify(small_body),
verify(four_wheels).
rocket :- flying,
verify(cosmos_flying),
verify(can_return).
shuttle :- flying,
verify(cosmos_flying),
verify(cant_return).
destroyer :- flying,
verify(air_flying),
verify(warmade).
civil_plane :- flying,
verify(air_flying),
verify(civil).
/* classification rules */
grounder :- verify(has_wheels), !.
grounder :- verify(have_engine).
flying :- verify(has_wings), !.
flying :- verify(has_jets).
/* how to ask questions */
ask(Question) :-
write('Does the vehicle have the following attribute: '),
write(Question), write('? '),
read(Response), nl,
( (Response == yes ; Response == y)
-> assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/* How to verify something */
verify(S) :- (yes(S) -> true ; (no(S) -> fail ; ask(S))).
/* undo all yes/no assertions */
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
这很好,但问题是 - 如何进行 "back" 输出,例如,我将在序言 window 中键入 "tank",他将给出所有部分这个坦克包括 - 像,枪 - 是的,短步枪 - 是的,机翼 - 不,e.t.c
是否可以在专家系统中这样做,或者我必须做另一个程序?
感谢您的回复
因为你的子句很简单,我想你可以像这样使用 clause/2
来做到这一点:
?- clause(grounder, X).
X = (verify(has_wheels), !) ;
X = verify(have_engine).
这看起来像这样:
part(Vehicle, Part) :-
clause(Vehicle, Body),
part_of_body(Body, Part).
part_of_body(verify(Part), Part).
part_of_body(X, Part) :-
atom(X), X \= '!', part(X, Part).
part_of_body((X,Y), Part) :-
part_of_body(X, Part)
; part_of_body(Y, Part).
这有点像元解释器。 clause/2
允许您以编程方式检查 Prolog 的规则。这是一种反射机制。 clause(Head, Body)
将 Head 与规则的名称统一起来,将 Body 与其主体统一起来——换句话说,Head :- Body
。所以当我们说 clause(tank, Body)
时,我们得到:
Body = (grounder, verify(has_gun), verify(short_fire)).
分解这个有点费力;毕竟,您必须遍历与您在规则中使用的一样多的 Prolog 本身。但这就是其余代码所做的。首先,我们获取 part/2
中的子句:请注意,我期望 Part 中的类型是车辆类型原子的类型。一旦我们获取了子句,我们就将它交给 part_of_body 来分解 Prolog 的结构。
从这里开始,基本情况类似于 verify(has_gun)
,它似乎包括您感兴趣的部分 (has_gun
),这就是规则 part_of_body(verify(Part), Part)
所说的.
递归情况是处理结构其余部分的情况,例如,如果我看到一个原子 grounder
,我会递归地查找那些部分,这就是 part_of_body(X, Part)
做。我对必须专门针对 !
进行测试并不感到兴奋,但我的方法存在一个我尚未修复的弱点。
主要的递归案例是处理连词的案例:(X,Y)
。这里我就说一下,在连词的第一部分找一些部分再试试第二部分
?- part(tank, Part).
Part = has_wheels ;
Part = have_engine ;
Part = has_gun ;
Part = short_fire.
所以这个数据库是可以反向操作的,就是不是特别方便。 :) 更好的数据模型将大大改善这种情况。