我正在阅读"7周内七种语言"的内容,我对Prolog的一些问题感到困惑,因为我不理解'不'的回应.
该friends.pl文件如下所示:
likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).
friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z).
Run Code Online (Sandbox Code Playgroud)
我可以对它做一些简单的查询,例如:
| ?- ['friends'].
compiling /home/marc/btlang-code/code/prolog/friends.pl for byte code...
/home/marc/btlang-code/code/prolog/friends.pl compiled, 12 lines read - 994 bytes written, 8 ms
yes
| ?- friend(wallace,grommit).
yes
| ?- friend(wallace,wendolene).
no
Run Code Online (Sandbox Code Playgroud)
这一切都符合预期.现在,我想在查询中引入一个变量.我的意图是Prolog会给我一份华莱士所有朋友的名单.我期待X = grommit,但我得到no:
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- friend(wallace,X).
1 1 Call: friend(wallace,_16) ?
2 2 …Run Code Online (Sandbox Code Playgroud) 我是prolog的新手,想要将所有查询保存在文件中,而不是手动输入.
我有这些事实facts.pl:
likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).
friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z).
Run Code Online (Sandbox Code Playgroud)
在阅读了这个问题的答案后,我想出了以下代码queries.pl:
main :-
write(likes(wallace, cheese)),
halt.
:- initialization(['facts.pl']).
:- initialization(main).
Run Code Online (Sandbox Code Playgroud)
在这里,我想检查是否likes(wallace, cheese)保持,我期望输出类似yes或no实际输出的东西likes(wallace, cheese)
我已经google了很多次尝试
X = likes(wallace, cheese), write(X).
X is likes(wallace, cheese), write(X).
X := likes(wallace, cheese), write(X).
但它们都不起作用.
对你来说这可能是一个非常简单的问题,但我不知道如何把事情弄清楚.
顺便说一下,我正在使用GNU Prolog 1.4.1
我正在尝试编写一个 gprolog 程序,该程序确认,鉴于这首歌的一些“合理”背景(在这里听:-)),当我查询时会回答“是” grandpa(me, me)(即,我真的是我自己的爷爷吗?)。这是我的 AI 课程的作业,由我们自己决定要包含哪些事实和谓词。虽然它充满了冗余和一些我不使用的条款(有些只是为了歌曲),但这是我拼凑起来的,必要的假设是继子女被认为是完整的/一般的孩子:
3 male(me).
4 male(mydad).
5 male(mybaby).
6 female(widow).
7 female(redhead).
8 grandma(Z, X) :- female(Z), child(Z, Y), child(Y, X).
9 grandpa(Z, X) :- male(Z), child(Z, Y), child(Y, X).
10 child(me, mydad).
11 child(redhead, widow).
12 child(mybaby, me).
13 child(A, B) :- married(B, C), married(A, D), child(D, C).
14 child(C, A) :- married(A, B), child(C, B). %step children as children
15 married(me, widow).
16 married(widow, me).
17 married(mydad, redhead). …Run Code Online (Sandbox Code Playgroud) 我一直在使用gprolog thingy在prolog中做一些事情.但现在在测试更多代码时,我发现它不支持"假".哪个是swi支持的?
让我们定义自定义运算符 - 让它成为++,equals
:- op(900, yfx, equals).
:- op(800, xfy, ++).
Run Code Online (Sandbox Code Playgroud)
事实上:
check(A equals A).
Run Code Online (Sandbox Code Playgroud)
我尝试制作谓词,让它成为check/1,在以下所有情况下都会返回:
check( a ++ b ++ c ++ d equals c ++ d ++ b ++ a ),
check( a ++ b ++ c ++ d equals d ++ a ++ c ++ b),
check( a ++ b ++ c ++ d equals d ++ b ++ c ++ a ),
% and all permutations... of any amount of atoms …Run Code Online (Sandbox Code Playgroud) 我在Prolog中写了一个快速谓词,尝试了CLP(FD)及其求解方程组的能力。
problem(A, B) :-
A-B #= 320,
A #= 21*B.
Run Code Online (Sandbox Code Playgroud)
当我在SWI中调用它时,我得到:
?- problem(A,B).
320+B#=A,
21*B#=A.
Run Code Online (Sandbox Code Playgroud)
而在GNU中,我得到以下正确答案:
| ?- problem(A,B).
A = 336
B = 16
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?理想情况下,我希望在SWI中获得正确的结果,因为它是一个更加健壮的环境。
目前正在研究《七周内的七种语言》一书,并且一直坚持要运行第一个序言示例。这涉及相同的代码片作为这个问题 ; 但是我相信我的问题是完全不同的。
我已经定义likes并friend如书中所述;我的friends.pl:
likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).
friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z).
Run Code Online (Sandbox Code Playgroud)
我使用GNU序言(v1.4.5,在Ubuntu 18.10),我可以加载friends.pl consultfile,无论是通过| ?- [friends.pl]或| ?- ['friends.pl']或通过调用其gprolog --consult-file参数:gprolog --consult-file friends.pl就好了
询问likes事实或friend规则的第一部分很好:
| ?- likes(grommit, cheese).
yes
| ?- friend(grommit, grommit).
no
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试查询涉及规则第二部分的查询时,会得到以下信息:
| ?- friend(grommit, wendolene).
uncaught exception: error(existence_error(procedure,likes/0),friend/0)
Run Code Online (Sandbox Code Playgroud)
当我阅读错误消息时,它告诉我没有使用“ 0”参数的过程“喜欢”,对吗?但是在我的规则中,哪里引用了这样的0参数过程?我在这里做错了什么?不能相信这是我序言中的错误;)?
是否有任何最新的 Prolog 实现基准(带有结果)?
我在汞网站上找到了这个。令人惊讶的是,它显示了swi-prolog和 Aquarius之间的 20 倍差距。我怀疑这些结果已经很老了。这个差距还成立吗?就我个人而言,我还希望看到一些与启用发生检查的比较,因为它对性能有重大影响,并且某些编译器在优化它方面可能比其他编译器更好。
最近比较,我发现这个要求是GNU的序言是2X比SWI更快,YAP为4x比SWI快于一个特定的代码库。
编辑:
实际问题需要发生检查的特定情况
当然:在 Haskell、OCaml、Swift或定理证明器(例如this one)中进行类型推断。我还认为程序员有责任证明他的代码不需要发生检查。测试只能证明你确实需要它,而不是你不需要它。
以下是来自top命令:
size res
1127 *** 1 20 0 117M 2196K ttyin 0 0:00 0.00% gprolog
1149 *** 1 23 0 10700K 3728K ttyin 0 0:00 0.00% swipl
Run Code Online (Sandbox Code Playgroud)
它的RES是合理的,但与swipl相比,它的尺寸太大了.
操作系统是freebsd 9.0.
祝商祺!