【问题标题】:Guess who-like game in Prolog在 Prolog 中猜猜喜欢谁的游戏
【发布时间】:2012-05-12 16:06:48
【问题描述】:

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

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

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

属性的谓词被定义为,如果关于该属性的问题尚未被提出,或者如果问题已被提出并且答案与嫌疑人的属性相匹配,则它们将为真。

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

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

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

我怎么能这样做?

【问题讨论】:

    标签: prolog


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢。我很难理解代码,你能评论一下吗?
    • 好吧,我试试,我英语不是很流利。诀窍是 predicate Clause/2 ,它在 tuple 中给出了谓词的主体。 forall/2 检查所有谓词疑点/2,将元组提供给 check/2。要理解该机制,您必须知道元组类似于列表,例如 (1,2,3) 可以与 (A,B) 统一,其中 A = 1 和 B = (2,3)。希望这可以帮助。您应该使用 trace/0 或 gtrace 来查看 Prolog 的工作情况。
    【解决方案2】:

    好吧,我想像这样的结构:

    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 提出问题的答案。 这是您可以尝试使其“智能”的地方,或者您可以迭代不同的问题。

    【讨论】:

    • 这正是我要问的,如何让它“智能”,以便它可以获取属性的不同值,所以我不必手动创建一个具有所有不同眼睛的列表颜色等等。
    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多