Prolog 专家系统:显示具有某些 属性 的谓词
Prolog expert system: show predicates with certain property
此程序向用户询问有关动物属性的问题,并期望以 "yes/no" 方式得到答案。它使用其识别规则来确定您选择的动物。
我想知道 prolog 如何 show/list 谓词与某个 属性。
例如:什么查询可以 'asked' 到 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
我同意@lurker 的观点,这个数据库设计得很糟糕,但这并不意味着你不能从中获得一些价值。例如,此查询将告诉您所有 "animals" 是哺乳动物:
?- 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/2
和 current_predicate/2
的结构化分解将使您能够以编程方式检查它们,这可能正是您想要的。
编程的一半成功在于弄清楚您的数据结构。的确,您 可以 在 Prolog 中将谓词视为数据;正如您在此处看到的,这并不是一种特别符合人体工程学 的数据结构方式。我认为,最好有一个通过检查数据库来工作的通用搜索策略。在我看来,这就像 "old school" Prolog 有很多状态。我肯定会考虑重新设计。
此程序向用户询问有关动物属性的问题,并期望以 "yes/no" 方式得到答案。它使用其识别规则来确定您选择的动物。
我想知道 prolog 如何 show/list 谓词与某个 属性。
例如:什么查询可以 'asked' 到 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
我同意@lurker 的观点,这个数据库设计得很糟糕,但这并不意味着你不能从中获得一些价值。例如,此查询将告诉您所有 "animals" 是哺乳动物:
?- 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/2
和 current_predicate/2
的结构化分解将使您能够以编程方式检查它们,这可能正是您想要的。
编程的一半成功在于弄清楚您的数据结构。的确,您 可以 在 Prolog 中将谓词视为数据;正如您在此处看到的,这并不是一种特别符合人体工程学 的数据结构方式。我认为,最好有一个通过检查数据库来工作的通用搜索策略。在我看来,这就像 "old school" Prolog 有很多状态。我肯定会考虑重新设计。