猜猜Prolog中的人喜欢游戏

时间:2012-05-12 16:06:49

标签: prolog

我正在使用Prolog开发Guess Who?游戏。游戏的机制非常简单。玩家(在这种情况下,人类)在许多可能的人中选择一个人,而另一个玩家(计算机)开始询问关于该人的某些属性的是/否问题。最终,根据给定的答案,只有一个可能的人。

到目前为止,我已经能够制定一套规则和谓词,以便计算机可以根据到目前为止提出的问题猜测这个人。我有一组嫌犯 - 那些有可用线索的人可以适应。

suspect('Person 1') :- eyes(blue) , age(old) , gender(male).

定义属性的谓词,以便在尚未询问有关该属性的问题时,或者是否已询问问题且答案与嫌疑人的属性匹配时,它们将为真。

gender(X) :- not(asked_gender) ; value_of(gender, X).

这样,如果两个嫌疑人拥有相同的眼睛,年龄和性别,只要性别保持不变,他们两个都是合理的嫌疑人。

然而,现在困难的部分是自动化提出这些问题的过程。基本上,我期待一个解决方案,Prolog能够从嫌疑人的谓词中获取属性的可能值,而不是在其他地方列出主题。我很确定必须有这样做的方法,因为prolog能够将程序的代码用作数据本身。

我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

这适用于SWI-Prolog:

:- dynamic value/1.

suspect('Person 1') :- eyes(blue) , age(old) , gender(male).

suspect('Person 2') :- eyes(green) , age(young) , gender(male).

suspect('Person 3') :- eyes(brown) , age(young) , gender(male).


fetch(Criterion, Value) :-
    retractall(value(_)),
    assert(value([])),
    forall(clause(suspect(_), Body),
    check(Body, Criterion)),
    retract(value(Value)).

check((F, T), Criterion) :-
    F =..[Criterion, V1],
    retract(value(V2)),
    (   member(V1, V2) -> V3 = V2; V3 = [V1 | V2]),
    assert(value(V3)).
    check(T, Criterion).


check((_F, T), Criterion) :-
    check(T, Criterion).

check((F), Criterion) :-
    F =..[Criterion, V1],
    retract(value(V2)),
    (   member(V1, V2) -> V3 = V2; V3 = [V1 | V2]),
    assert(value(V3)).

check((_F), _Criterion).

例如: ? - 获取(性别,价值)。 价值= [男]。

? - 获取(眼睛,价值)。 值= [棕色,绿色,蓝色]。

答案 1 :(得分:0)

好吧,我想象一下这样的结构:

go :-
    findall(People,suspect(People),SuspectList),
    length(SuspectList,1),
    member(Perb,SuspectList),
    write('It is '),write(Perb),write('!!'),nl,!.

go :-
    askQuestion,
    go.

在askQuestion / 0中你会用read / 1谓词提出问题并断言/ 1答案。 这是您可以尝试使其“智能”的地方,或者您可以迭代不同的问题。