Prolog的算术的foreach(Prolog arithmetic in foreach)

2019-09-26 21:09发布

所以我学习的Prolog。 其中一个我发现是真的讨厌被证明在下面的示例中的事情:

foreach(
  between(1,10,X),
  somePredicate(X,X+Y,Result)
).

这是行不通的。 我清楚地知道,X + Y不计算,在这里,而是我必须做的:

foreach(
  between(1,10,X),
  (
    XPlusY is X + Y,
    somePredicate(X, XPlusY, Result)
  )
).

除此之外,不工作,要么。 由于靠近我可以告诉大家,范围XPlusY扩展之外foreach -即XPlusY is 1 + Y, XPlusY is 2 + Y,等等都必须是真实的同时,并没有XPlusY对于这即是如此。 所以,我必须要做到以下几点:

innerCode(X, Result) :-
  XPlusY is X + Y,
  somePredicate(X, XPlusY, Result).
...

foreach(
  between(1,10,X),
  innerCode(X, Result)
).

这,最后,工作。 (至少我是这么认为的。我没试过这个确切的代码,但是这是我从“不工作”到“工作”。早些时候所采取的方法),这很好,所有,但它是非常讨厌的。 如果我在在线评估算术运算的一种方式,我可以减少一半的代码行,使其更具可读性,并没有创造一次使用的混乱谓语。

问:有没有办法来评估行算术运算,不宣而一个新的变量?

如果做不到这一点,这是可以接受的(并且,在某些情况下,还是其他的东西很有用),如果有限制的新变量的作用域的方式。 假设,例如,你可以在中定义一个块foreach ,其中从外部可见的变量进行了标记,并在块中的任何其他变量被认为是新的块的执行。 (我知道我的术语可能是不正确的,但希望它横跨得到点。)例如,类似的东西:

foreach(
  between(1,10,X),
  (X, Result){
    XPlusY is X + Y,
    somePredicate(X, XPlusY, Result)
  }
).

一种可能的解决办法可能是,如果我们可以声明在线拉姆达并立即调用它。 总结:

备选问题:有没有办法来限制谓词中新变量的范围,同时保持在一个或多个现有变量进行持久unifications的能力吗?

(第二半予添加作为澄清响应于关于一个答案forall 。)

一种解决这两个问题是优选的,但无论是溶液就足够了。

Answer 1:

库( 亚勒 )允许您定义lambda表达式。 例如

?- foreach(between(1,3,X),call([Y]>>(Z is Y+1,writeln(Z)),X)).
2
3
4
true.

备选地,文库( 拉姆达 )提供了构建体:

?- [library(lambda)].
true.

?- foreach(between(1,3,X),call(\Y^(Z is Y+1,writeln(Z)),X)).
2
3
4
true.

在SWI-Prolog的,库(亚勒)被自动加载,而让库(拉姆达),你应该安装相关的包:

?- pack_install(lambda).


Answer 2:

在使用替代的forall/2事实上的标准谓词:

forall(
  between(1,10,X),
  somePredicate(X,X+Y,Result)
).

虽然foreach/2谓词在你所描述的方式通常是落实, forall/2谓词被定义为:

% forall(@callable, @callable)

forall(Generate, Test) :-
    \+ (Generate, \+ Test).

请注意,使用否定的暗示,当谓词调用成功,没有绑定将被退回。

更新

LAMBDA库允许两个拉姆达全球(又名拉姆达免费)和拉姆达局部变量(又名拉姆达参数)的规范。 在使用Logtalk lambda表达式语法(也可用在SWI-Prolog的library(yall) ,你可以写(重用卡罗的例子)如

?- G = 2, foreach(between(1,3,X),call({G}/[Y]>>(Z is Y+G,writeln(Z)),X)).
3
4
5
G = 2.

?- G = 4, foreach(between(1,3,X),call({G}/[Y]>>(Z is Y+G,writeln(Z)),X)).
5
6
7
G = 4.

因此,它可以使用lambda表达式来限制目标中的一些变量的作用域而没有限制在每一个目标统一的范围。



文章来源: Prolog arithmetic in foreach