专家系统中的 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.

所以这个数据库是可以反向操作的,就是不是特别方便。 :) 更好的数据模型将大大改善这种情况。