标签: prolog

Prolog中的可逆数值计算

在阅读SICP时,我遇到了逻辑编程第4.4章.然后我开始研究Prolog编程语言并尝试理解Prolog中的一些简单的任务.我发现Prolog似乎在数值计算方面遇到麻烦.

这是标准Prolog中的阶乘计算:

f(0, 1).
f(A, B) :- A > 0, C is A-1, f(C, D), B is A*D.
Run Code Online (Sandbox Code Playgroud)

我发现的问题是我需要引入两个辅助变量(CD),一个新的语法(is),并且问题是不可逆的(即,f(5,X)按预期工作,但f(X,120)不能).

天真的,我希望至少C is A-1, f(C, D)可以用上面的东西代替f(A-1,D),但即使这样也行不通.

我的问题是:为什么我需要在数值计算中做这些额外的"东西",而不是在其他查询中呢?

我明白(并且SICP非常清楚),一般来说,"做什么"的信息不足以回答"如何做"的问题.因此,(至少一些)数学问题的陈述性知识不足以真正解决这些问题.但这引出了下一个问题:Prolog中这些额外的"东西"如何帮助我将制定局限于那些"做什么"足以回答"如何做"的问题?

prolog factorial clpfd

13
推荐指数
3
解决办法
1558
查看次数

Prolog GNU - Univ运营商?解释它

所以univ运营商.我并不完全理解.

例如:

foo(PredList,[H|_]) :- bar(PredList,H).
foo(PredList,[_|T]) :- foo(PredList,T),!.

bar([H|_],Item) :- G =.. [H,Item],G.
bar([_|T],Item) :- bar(T,Item).
Run Code Online (Sandbox Code Playgroud)

这是做什么的?这样可以查看另一个谓词是否为真.我不明白".."的作用.

如果没有univ运算符,你会如何重写它?

prolog backtracking operator-keyword meta-predicate

13
推荐指数
1
解决办法
4829
查看次数

Prolog中列表的连接

有人可以帮助在此规则中找到错误吗?

concat([], List, List).
concat([Head|[]], List, [Head|List]).
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat(Head, C, Concat).
Run Code Online (Sandbox Code Playgroud)

尝试连接2个列表失败:

| ?- concat([1,2], [4,7,0], What).

no
Run Code Online (Sandbox Code Playgroud)

list prolog

13
推荐指数
2
解决办法
4万
查看次数

Prolog中有哪些数据类型?

根据维基百科,Prolog中的单一数据类型是术语.文还提到,"序言的单个数据taype是术语",但随后继续解释"序言中的数据类型的分类"(但我认为,只有一个类型......)现在,这些幻灯片何况不同的数据类型:"数字,字符和字符串".

那么,Prolog中的数据类型究竟是什么?

types prolog

13
推荐指数
3
解决办法
8788
查看次数

Prolog匿名变量

以下是我对Prolog变量的理解.

  1. 单个下划线代表匿名变量,每次发生时都像一个新变量.

  2. 以_W这样的下划线开头的变量名不是匿名变量.或者,Prolog内部生成的变量名称(如_G189)不被视为匿名:

?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
Run Code Online (Sandbox Code Playgroud)

你能帮我理解一下吗?

顺便说一下,我从一些教程中得到了上面的例子,但是当我在SWI-Prolog版本6中运行它时,我得到以下内容:

?- append([1,2],X,Y).
Y = [1, 2|X].
Run Code Online (Sandbox Code Playgroud)

感谢您.

prolog prolog-toplevel

13
推荐指数
1
解决办法
8146
查看次数

什么是最好的Prolog编程实践和风格指南?

好的,我知道这是一个非常普遍的问题,并且已经写了一些关于这个主题的论文,但我觉得这些出版物涵盖了非常基本的材料,我正在寻找更先进的东西来改善风格和效率.这就是我的论文:

  • "研究报告AI-1989-08 Efficient Prolog:A Practical Guide",Michael A. Covington,1989年
  • "高效的Prolog编程",Timo Knuutila,1992年
  • Coomington编写的"Prolog编码指南",Bagnara,O'Keefe,Wielemaker,Price,2011

这些主题涵盖的示例主题包括:尾递归和差异列表,正确使用索引,正确使用剪切,避免断言和缩回,避免CONSing,代码格式化指南(缩进,if-then-elses等),命名约定,代码记录,参数顺序,测试.

您将从Prolog的个人经历中添加什么?是否有适用于CLP编程的特殊风格指南?你知道一些常见的效率问题,知道如何处理它们吗?

更新:

这里有一些有趣的(但仍然太基础和太笼统)点:Lifeware团队的Prolog编程指南

为了突出整个问题,我想问一下"Prolog的编码指南"(Covington等人):

据我们所知,Prolog的一套连贯且相当完整的编码指南从未发布过.此外,当我们查看已发布的Prolog程序的语料库时,我们看不到事实上的标准出现.这一明显遗漏背后的最重要原因是,由于缺乏全面的语言标准,小型Prolog社区进一步分散为以个体Prolog系统为中心的子社区,其中没有一个具有支配地位.

prolog iso-prolog

13
推荐指数
1
解决办法
1817
查看次数

PROLOG:如果顺序无关紧要,确定列表中的元素是否相等

我试图找出一种方法来检查两个列表是否相等,无论它们的元素顺序如何.

我的第一次尝试是:

areq([],[]).
areq([],[_|_]).
areq([H1|T1], L):- member(H1, L), areq(T1, L).
Run Code Online (Sandbox Code Playgroud)

但是,这只检查左侧列表中的所有元素是否都存在于右侧列表中; 意思areq([1,2,3],[1,2,3,4]) => true.在这一点上,我需要找到一种能够以双向意义测试事物的方法.我的第二次尝试如下:

areq([],[]).
areq([],[_|_]).
areq([H1|T1], L):- member(H1, L), areq(T1, L), append([H1], T1, U), areq(U, L).
Run Code Online (Sandbox Code Playgroud)

在哪里我会尝试重建左边的那个以及最后的交换列表; 但这次失败了.

我对递归的感觉非常差,根本不知道如何改进它,尤其是Prolog.任何提示或建议都将在此时受到赞赏.

prolog

13
推荐指数
4
解决办法
3721
查看次数

删除Prolog中列表中的前导零

我有一个列表,在它的开头有一个未知数量的零,例如[0,0,0,1,2,0,3].我需要将这个列表去掉前导零,以便它看起来像[1,2,0,3].

这就是我所拥有的:

lead([Head | _], _) :- Head =\= 0.
lead([0 | Tail], _) :- 
  lead(Tail, Tail).
Run Code Online (Sandbox Code Playgroud)

其输出只是True.读取跟踪显示它正在运行,直到它有一个没有前导零的列表,但随后答案不会传播回堆栈.我对Prolog很新,所以我无法弄清楚如何做到这一点.

list prolog prolog-dif

13
推荐指数
4
解决办法
535
查看次数

DCG和Prolog中列表的反转

我试图在列表中计算反转的数量.谓词inversion(+L,-N)统一N了该列表中的反转次数.甲反转被定义为X > YX之前出现Y在列表中(除非XY0).例如:

?- inversions([1,2,3,4,0,5,6,7,8],N).
N = 0.

?- inversions([1,2,3,0,4,6,8,5,7],N).
N = 3.
Run Code Online (Sandbox Code Playgroud)

对于我正在使用的内容,列表将始终包含9个元素,并且始终包含0-8唯一的数字.

我对Prolog很新,我试图尽可能简洁,优雅; 似乎DCG可能会有很大帮助.我读了官方定义和一些教程网站,但仍然没有放弃了解它是什么.任何帮助将不胜感激.

list prolog clpfd

13
推荐指数
2
解决办法
448
查看次数

Prolog中的逻辑否定

我已经阅读了很多关于Prolog的失败否定的内容,其中Prolog是为了证明\+Goal持有试图证明Goal失败.

这与CWA(近距离世界假设)高度相关,例如,如果我们查询\+P(a)(在哪里P是arity 1的谓词),并且我们没有线索导致证明P(a)Prolog假定(由于CWA)not P(a)如此\+P(a)成功.

从我所搜索的内容来看,这是一种解决经典逻辑弱点的方法,如果我们对此毫无头绪,P(a)那么我们无法回答是否\+P(a)持有.

上面描述的是在Prolog中引入非单调推理的方法.此外,有趣的部分是Clark证明Negation by Failure与经典否定相容/类似仅适用于地面条款.我明白这个例子:

X=1, \+X==1.:应该在Prolog中返回false(在经典逻辑中).

\+X==1, X=1.:应该在经典逻辑中返回false,但是在检查NF的时候它在Prolog中成功,X不受约束,这与classic-Pure Logic不同.

\+X==1.:在X绑定之前,不应该给经典逻辑中的任何答案,但在Prolog中它返回false(可能打破经典逻辑的弱点),这与纯逻辑不相同/兼容.

我的尝试是模拟经典否定,感谢评论中的@false的建议,目前的实施是:

\\+(Goal) :- when(ground(Goal), \+Goal). 
Run Code Online (Sandbox Code Playgroud)

一些测试:

?- \\+(X==1).
when(ground(X), \+X==1).

?- X=1, \\+(X==1).
false.

?- \\+(X==1), X=1.
false. 
Run Code Online (Sandbox Code Playgroud)

我的问题:

以上是对经典否定的正确解释吗?(是否有任何明显的极端情况,它错过了?当使用/ 2时我也关注逻辑纯度,可以安全地假设上面是纯粹的吗??).

prolog negation logical-purity prolog-coroutining

13
推荐指数
1
解决办法
1044
查看次数