Prolog专家系统:显示具有某些属性的谓词

时间:2017-05-27 16:10:46

标签: prolog expert-system

该程序询问用户有关动物属性的问题,并期待答案为“是/否”#34;时尚。它使用其识别规则来确定您选择的动物。

我想知道prolog如何显示/列出具有某种属性的谓词。

例如:可以询问什么查询' SWI-prolog列出所有哺乳动物?

查询的预期答案是:猎豹,老虎。

请考虑以下代码示例:

/* animal.pro
  animal identification game.  

    start with ?- go.     */

go :- hypothesize(Animal),
      write('I guess that the animal is: '),
      write(Animal),
      nl,
      undo.

/* hypotheses to be tested */
hypothesize(cheetah)   :- cheetah, !.
hypothesize(tiger)     :- tiger, !.
hypothesize(giraffe)   :- giraffe, !.
hypothesize(zebra)     :- zebra, !.
hypothesize(ostrich)   :- ostrich, !.
hypothesize(penguin)   :- penguin, !.
hypothesize(albatross) :- albatross, !.
hypothesize(unknown).             /* no diagnosis */

/* animal identification rules */
cheetah :- mammal, 
           carnivore, 
           verify(has_tawny_color),
           verify(has_dark_spots).
tiger :- mammal,  
         carnivore,
         verify(has_tawny_color), 
         verify(has_black_stripes).
giraffe :- ungulate, 
           verify(has_long_neck), 
           verify(has_long_legs).
zebra :- ungulate,  
         verify(has_black_stripes).

ostrich :- bird,  
           verify(does_not_fly), 
           verify(has_long_neck).
penguin :- bird, 
           verify(does_not_fly), 
           verify(swims),
           verify(is_black_and_white).
albatross :- bird,
             verify(appears_in_story_Ancient_Mariner),
             verify(flys_well).

/* classification rules */
mammal    :- verify(has_hair), !.
mammal    :- verify(gives_milk).
bird      :- verify(has_feathers), !.
bird      :- verify(flys), 
             verify(lays_eggs).
carnivore :- verify(eats_meat), !.
carnivore :- verify(has_pointed_teeth), 
             verify(has_claws),
             verify(has_forward_eyes).
ungulate :- mammal, 
            verify(has_hooves), !.
ungulate :- mammal, 
            verify(chews_cud).

/* how to ask questions */
ask(Question) :-
    write('Does the animal 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.

原始教程的来源: https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_17.html

1 个答案:

答案 0 :(得分:2)

我同意@lurker这个数据库的设计很糟糕,但这并不意味着你无法从中获得一些价值。例如,此查询将告诉您所有哺乳动物的“动物”:

  ?- current_predicate(Animal, _), 
     clause(Animal, Clause), 
     Clause = ','(mammal, _).
Animal = ungulate,
Clause =  (mammal, verify(has_hooves), !) ;

Animal = ungulate,
Clause =  (mammal, verify(chews_cud)) ;

Animal = tiger,
Clause =  (mammal, carnivore, verify(has_tawny_color), verify(has_black_stripes)) ;

Animal = cheetah,
Clause =  (mammal, carnivore, verify(has_tawny_color), verify(has_dark_spots)) ;

false.

本手册包含examining the program部分,您可以使用该部分来发现有关您的计划的事实。如果您只想自己仔细阅读,也可以使用listing/1,但使用clause/2current_predicate/2进行结构化分解可以让您以编程方式检查它们,这可能就是您想要的。< / p>

编程中的一半是弄清楚你的数据结构。确实,可以将谓词视为Prolog中的数据;正如您在此处看到的,它不是一种特别符合人体工程学的结构数据的方式。我认为最好通过检查数据库来实现一般搜索策略。这对我来说就像“老派”Prolog一样有很多州。我肯定会考虑重新设计。