4

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

到目前为止,我已经能够制定一套规则和谓词,以便计算机可以根据迄今为止提出的问题来猜测这个人。我有一组嫌疑人——这些人只要有可用的线索,就可能适合。

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

属性的谓词被定义为,如果关于该属性的问题还没有被问到,或者如果问题已经被问过并且答案与嫌疑人的属性相匹配,它们就会为真。

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

这样一来,如果两个嫌疑人的眼睛、年龄相同、性别不同,只要不问性别,他们都是合理的嫌疑人。

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

我怎么能那样做?

4

2 回答 2

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).

例如:?- fetch(gender, Value)。值 = [男性]。

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

于 2012-05-13T21:49:18.383 回答
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 谓词和 assert/1 提出问题的答案。这是您可以尝试使其“智能”的地方,或者您可以迭代不同的问题。

于 2012-05-12T20:52:31.353 回答