标签: prolog

归因变量:库接口/实现/可移植性

当我撇了一些最近相关的问题,我偶然发现这个答案通过@mat质疑如何在Prolog中表示定向循环图,可直接通往邻居verticies.

到目前为止,我在Prolog中对属性变量的个人经验非常有限.但@mat给出的用例激发了我的兴趣.所以我尝试用它来回答另一个问题,用约束逻辑编程排序列表.

首先,好消息:我第一次使用归因变量就像我想要的那样.

然后,不是那么好的消息:当我通过回答发布时,我意识到在Prolog中有几个API和属性变量的实现.

我觉得我在这里过头了......特别是我想知道以下内容:

  • 什么API广泛使用?到目前为止,我发现了两个:SICStus和SWI.
  • 不同的属性变量实现提供哪些功能?同样的?或者一个包含另一个?
  • 语义上有差异吗?
  • 实际实施怎么样?有些比其他人更有效吗?
  • 可以(或是)使用属性变量进行可移植性问题吗?

很多问号,这里......请分享你的经验/立场?先感谢您!


编辑2015-04-22

这是上面提到的答案的代码片段:

init_att_var(X,Z) :-
    put_attr(Z,value,X).

get_att_value(Var,Value) :-
    get_attr(Var,value,Value).
Run Code Online (Sandbox Code Playgroud)

到目前为止,我"只"使用put_attr/3get_attr/3,但是 - 根据SICStus Prolog文档中的属性变量--- SICStus提供put_attr/2get_attr/2.

因此,即使是非常浅的用例也 需要一些仿真层(一种方式或另一种方式).

prolog

43
推荐指数
4
解决办法
740
查看次数

网球比赛安排

球员数量有限,网球场数量有限.在每轮比赛中,最多可以有比赛更多的比赛.没有休息,没有人打2轮.每个人都与其他人比赛.制定尽可能少轮次的计划.(由于每个人的轮次之间必须休息的规则,可以有一轮没有比赛.)5名球员和2个球场的输出可以是:

 |  1   2   3   4   5
-|------------------- 
2|  1   - 
3|  5   3   - 
4|  7   9   1   - 
5|  3   7   9   5   -
Run Code Online (Sandbox Code Playgroud)

在此输出中,列和行是播放器编号,矩阵内的数字是这两个玩家竞争的圆形数字.

问题是找到一种算法,可以在可行的时间内为更大的实例执行此操作.我们被要求在Prolog中这样做,但任何语言的(伪)代码都是有用的.

我的第一次尝试是一种贪婪的算法,但这会产生太多轮次的结果.然后我建议迭代加深深度优先搜索,我的一个朋友实现了,但是仍然花了太多时间在小到7个玩家的实例上.

(这是一个旧的考试问题.我接触过的任何人都没有任何解决方案.)

algorithm scheduling prolog clpfd

42
推荐指数
3
解决办法
8354
查看次数

Prolog中'和'有什么区别?

我是Prolog的新手并注意到'和'给出了不同的行为,但我很好奇为什么.具体来说,加载文件时,?- ['test1.pl'].工作,而?- ["test1.pl"].不是.

prolog double-quotes dcg iso-prolog

41
推荐指数
2
解决办法
5536
查看次数

Prolog继承符号表示不完整的结果和无限循环

我开始学习Prolog,并首先了解了继承符号.

这就是我在Prolog中发现编写Peano公理的地方.

参见PDF的第12页:

sum(0, M, M).
sum(s(N), M, s(K)) :-
    sum(N,M,K).

prod(0,M,0).
prod(s(N), M, P) :-
    prod(N,M,K),
    sum(K,M,P).
Run Code Online (Sandbox Code Playgroud)

我把乘法规则放到了Prolog中.然后我做查询:

?- prod(X,Y,s(s(s(s(s(s(0))))))).
Run Code Online (Sandbox Code Playgroud)

这意味着基本上找到6的因子.

结果如下.

X = s(0),
Y = s(s(s(s(s(s(0)))))) ? ;
X = s(s(0)),
Y = s(s(s(0))) ? ;
X = s(s(s(0))),
Y = s(s(0)) ? ;
infinite loop
Run Code Online (Sandbox Code Playgroud)

这个结果有两个问题:

  1. 并非所有结果都显示,请注意结果X = 6,Y = 1缺失.
  2. 它不会停止,除非我按Ctrl + C然后选择中止.

所以...我的问题是:

  1. 这是为什么?我尝试转换"prod"和"sum".结果代码给了我所有结果.再说一遍,为什么?它仍然是死循环.
  2. 如何解决?

我在无限循环中阅读了另一个答案.但我很感激有人根据这个场景做出回答.这对我很有帮助.

prolog infinite-loop successor-arithmetics non-termination failure-slice

41
推荐指数
2
解决办法
2855
查看次数

术语平等/不平等的具体化

纯粹的Prolog程序以清晰的方式区分术语的平等和不平等,导致执行效率低下; 即使所有相关术语都是基础的.

关于SO的最近一个例子是这个答案.在此定义中,所有答案和所有失败都是正确的.考虑:

?- Es = [E1,E2], occurrences(E, Es, Fs).
Es = Fs, Fs = [E, E],
E1 = E2, E2 = E ;
Es = [E, E2],
E1 = E,
Fs = [E],
dif(E, E2) ;
Es = [E1, E],
E2 = E,
Fs = [E],
dif(E, E1) ;
Es = [E1, E2],
Fs = [],
dif(E, E1),
dif(E, E2).
Run Code Online (Sandbox Code Playgroud)

虽然程序从声明的角度来看是完美无缺的,但它在B,SICStus,SWI,YAP等当前系统上的直接执行效率却不必要地低效.对于以下目标,列表的每个元素保留一个选择点.

?- occurrences(a,[a,a,a,a,a],M).
M = [a, a, a, a, a] ;
false. …

prolog prolog-dif

40
推荐指数
3
解决办法
1328
查看次数

知道何时使用cut in prolog

我参加了一门课程,学习了一些序言.我无法弄清楚如何/何时使用削减.即使我得到了切割的一般概念,我也似乎无法正确使用它们.任何人都可以简单地解释一下,或者给出一个他们可以推荐的"削减"的好教程(那不是learnprolognow.org)吗?

prolog prolog-cut

38
推荐指数
3
解决办法
1万
查看次数

与STO检测统一

在ISO Prolog中,仅针对NSTO(不受发生检查)的情况定义统一.背后的想法是涵盖那些主要用于程序并且实际上得到所有Prolog系统支持的统一案例.更具体地说,ISO/IEC 13211-1:1995读取:

7.3.3发生检查(STO)但不受
发生检查(NSTO)


如果存在通过
Herbrand算法的步骤以便
发生7.3.2g 的方式,则一组方程(或两个项)是"经历发生 - 检查"(STO).


如果没有办法继续
Herbrand算法的步骤使得7.3.2g发生,则一组方程(或两个项)"不受发生检查"(NSTO)
.

...

此步骤7.3.2 g读取:

克)如果存在形式的公式X =吨这样
X是一个变量,是非可变术语
包含该变量,然后用失败(退出
unifiable
,正发生检查).

完整的算法被称为Herbrand算法,并且通常被称为Martelli-Montanari统一算法 - 其基本上通过以非确定性方式重写方程组进行.

请注意,引入了新的方程式:

d)如果存在形式为f(a 1,a 2,... a N)=
f(b 1,b 2,... b N)
的等式,则将其替换为等式集
a i = b .

这意味着具有相同算符但具有不同arity的两个复合词将永远不会对STO-ness做出贡献.

这种非确定性使得STO测试难以实现.毕竟,仅仅测试是否需要发生检查是不够的,但为了证明对于执行算法的所有可能方式,这种情况永远不会发生.

这是一个案例来说明情况:

?- A/B+C*D = 1/2+3*4.
Run Code Online (Sandbox Code Playgroud)

统一可以从A = 1,也可以是任何其他对开始,并以任何顺序继续.为了确保NSTO属性,必须确保没有可能产生STO情况的路径.考虑一个对当前实现没有问题的情况,但仍然是STO:

?- 1+A = …
Run Code Online (Sandbox Code Playgroud)

algorithm prolog unification iso-prolog

38
推荐指数
4
解决办法
627
查看次数

路径/步道/步行的定义

许多谓词定义了某种通过二元关系定义的边构建的非循环路径,与定义传递闭包非常相似.因此需要通用定义.

请注意,图论中定义的概念不容易与通常预期的匹配.最值得注意的是,我们对边缘的名称不感兴趣.

更糟糕的是,图论也发生了一些变化,引入了步行的概念,注意到了

传统上,路径指的是现在通常称为开放式步行的路径.如今,当没有任何限定地陈述时,路径通常被理解为简单,意味着没有重复顶点(因此没有边缘).(术语链也用于指代所有顶点和边缘都不同的步行.)

所以我的问题是:如何命名和定义此功能?

到目前为止我所做的是定义:

path(Rel_2, Path, X0,X)
Run Code Online (Sandbox Code Playgroud)

第一个论点必须是关系的延续.然后是Path顶点或顶点.

用法示例

n(a, b).
n(b, c).
n(b, a).

?- path(n,Xs, a,X).
Xs = [a], X = a ;
Xs = [a, b], X = b ;
Xs = [a, b, c], X = c ;
false.
Run Code Online (Sandbox Code Playgroud)

履行

:- meta_predicate path(2,?,?,?).

:- meta_predicate path(2,?,?,?,+).

path(R_2, [X0|Ys], X0,X) :-
   path(R_2, Ys, X0,X, [X0]).

path(_R_2, [], X,X, _).
path(R_2, [X1|Ys], X0,X, Xs) :-
   call(R_2, X0,X1),
   non_member(X1, Xs),
   path(R_2, …
Run Code Online (Sandbox Code Playgroud)

graph prolog transitive-closure meta-predicate

37
推荐指数
3
解决办法
2463
查看次数

Prolog约束处理:包装正方形

我正在尝试解决prolog中的约束处理问题.

我需要在10x10的网格中打包4个5x5,4x4,3x3和2x2的正方形.它们可能不重叠.

我的变量看起来像这样:

Name: SqX(i), i=1..10, domain: 1..10
Run Code Online (Sandbox Code Playgroud)

其中X是5,4,3或2.索引i表示行,域表示网格中的列.

我的第一个约束试图定义正方形的宽度和高度.我这样制定它:

Constraint: SqX(i) > SqX(j)-X /\ i>j-X, range: i>0 /\ j>0
Run Code Online (Sandbox Code Playgroud)

这样可能的点被约束在彼此的X行和列之内.然而,Prolog会停止这些约束并给出以下结果:

Adding constraint "(Sq5_I > Sq5_J-5) /\ (I>J-5)" for values:
        I=1, J=1, 
        I=1, J=2, 
        I=1, J=3, 
        I=1, J=4, 
        I=1, J=5, 
        I=1, J=6, 
=======================[ End Solutions ]=======================
Run Code Online (Sandbox Code Playgroud)

所以它停在那里,甚至没有检查其他方块.我的约束很可能太紧张,但我不明白为什么或如何.有什么建议?

constraints prolog sicstus-prolog clpfd clpb

36
推荐指数
3
解决办法
3356
查看次数

模式匹配 - Prolog与Haskell

这不是一个家庭作业问题,而是一个考试学习指导问题.Prolog Vs Haskell中的模式匹配有什么区别?

我做了一些研究,阅读背后的理论并没有真正让我对两者有充分的理解.我在Prolog中看到,模式匹配是不同的,因为它具有统一变量的能力,因此能够通过分辨率推断并吐出可能的答案

eg ?- [a,b] = [a,X]
   X = b
Run Code Online (Sandbox Code Playgroud)

现在我不确定如何在Haskell中显示模式匹配.我知道Prolog中显示的上述相同查询在Haskell中不起作用,因为Haskell无法像Prolog那样统一.我记得在Haskell得到相同答案的地方,你必须通过警卫明确告诉它.

我知道我非常接近理解它,但是我需要有人为我打破Barney风格所以我可以完全理解它并向12岁的人解释它.这已经困扰了我很长一段时间,我似乎无法找到一个可靠的解释.

顺便说一句,上面显示的例子只是向你们展示我到目前为止所学到的东西,而我实际上是想找到答案.我的主要问题与上述例子无关,而是完全理解两者之间的差异.

haskell prolog pattern-matching

35
推荐指数
5
解决办法
9867
查看次数