使用dynamic / 1和var / 1创建允许以下内容的Prolog子句

时间:2018-05-13 21:45:58

标签: prolog

?- say([the, capital, of, switzerland, is, bern]). 
Thank you. 
?- say([the, capital, of, switzerland, is, bern]). 
I already know that. 
?- say([the, capital, of, switzerland, is, zurich]). 
No, you said the capital of switzerland is bern. 
?- say([the, capital, of, france, is, bern]). 
No, you said bern is the capital of switzerland. 
?- say([the, capital, of, What, is, bern]). 
What = switzerland. 
?- say([the, capital, of, switzerland, is, What]). 
What = Bern. 

最后两个很容易,我说([,资本,瑞士,是,伯恩])。 但是如何制作Prolog输出谢谢你而不是真的?那其他的句子怎么样?非常感谢。

我尝试编写一些代码,但效果不好。

:- dynamic say/1.
say([the, capital, of, switzerland, is, bern]) :- write('Thank you').
say([the, capital, of, switzerland, is, bern]) :- write('I already know that.').
say([the, capital, of, switzerland, is, X]):-
    X\==bern, write('No, you said the capital of switzerland is bern.').
say([the, capital, of, X, is, bern]):-
    X\==switzerland, write('No, you said bern is the capital of switzerland.').

1 个答案:

答案 0 :(得分:1)

我认为演习的重点不是让节目说“#34;谢谢你"当输入句子[the,capital,of Switzerland,is,bern]时,而是使用变量,断言和查询来使其学习和回忆事物,并做一些模糊的事情。

您的规则的标题应该是say([the, capital, of, Subj, is, Obj]),其中SubjObj是主题的变量和该关系的对象,因此您的规则可以匹配多个句子

动态谓词不应该是say/1。这是知识存储/召回的手工制作的谓词。你应该有一个不同的谓词来存储你的知识,让我们称之为capital/2

:- dynamic capital/2.

您将使用assertz(capital(a, b)).在知识库中插入事实,并使用capital(X, Y)进行查询。

在第一个用例中,检查变量是否为基础(这意味着我们被指示了什么),并检查我们是否已经知道相同的事实,然后将事实插入知识库:< / p>

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    \+ capital(Subj, Obj), !,
    assertz(capital(Subj, Obj)),
    write([thank, you]).

对于第二种情况,我们再次检查变量是否为基础,但是我们进行了相反的检查,并说我们已经知道:

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj, Obj), !,
    write([i, already, know, that]).

第三和第四种情况以类似的方式工作,带有地面变量,但寻找指令与知识库中的内容之间的不匹配:

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj, Obj1),
    Obj1 \= Obj, !,
    write([no, you, said, the, capital, of, Subj, is, Obj1]).

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj1, Obj),
    Subj1 \= Subj, !,
    write([no, you, said, Obj, is, the, capital, of, Subj1]).

最后,最后一个案例是查询回答,因此SubjObj(或两者)必须是非地面变量,我们打印知识库中的内容:< / p>

say([the, capital, of, Subj, is, Obj]) :-
    (var(Subj) ; var(Obj)),
    capital(Subj, Obj), !,
    write([the, capital, of, Subj, is, Obj]).

请注意,由于该程序使用剪切(!)和assertz/1,因此规则的顺序非常重要。更改订单会产生错误的结果。

这是完整的程序:

:- dynamic capital/2.

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj, Obj1),
    Obj1 \= Obj, !,
    write([no, you, said, the, capital, of, Subj, is, Obj1]).

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj1, Obj),
    Subj1 \= Subj, !,
    write([no, you, said, Obj, is, the, capital, of, Subj1]).

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    \+ capital(Subj, Obj), !,
    assertz(capital(Subj, Obj)),
    write([thank, you]).

say([the, capital, of, Subj, is, Obj]) :-
    ground((Subj, Obj)),
    capital(Subj, Obj), !,
    write([i, already, know, that]).

say([the, capital, of, Subj, is, Obj]) :-
    (var(Subj) ; var(Obj)),
    capital(Subj, Obj), !,
    write([the, capital, of, Subj, is, Obj]).

和测试运行:

?- say([the, capital, of, switzerland, is, bern]).
[thank,you]
true.

?- say([the, capital, of, switzerland, is, bern]).
[i,already,know,that]
true.

?- say([the, capital, of, switzerland, is, zurich]).
[no,you,said,the,capital,of,switzerland,is,bern]
true.

?- say([the, capital, of, france, is, bern]).
[no,you,said,bern,is,the,capital,of,switzerland]
true.

?- say([the, capital, of, What, is, bern]).
[the,capital,of,switzerland,is,bern]
What = switzerland.

?- say([the, capital, of, switzerland, is, What]).
[the,capital,of,switzerland,is,bern]
What = bern.