@ <Prolog中的符号

par*_*isa 5 prolog

我想知道@<Prolog的含义是什么?在阅读有关Bridge和Torch问题时,我在这行代码中遇到了这个符号:

select_one_or_two(L,[Sel1,Sel2],L2) :- 
   select(Sel1,L,NewL),
   select(Sel2,NewL,L2),
   Sel1@<Sel2.
Run Code Online (Sandbox Code Playgroud)

lur*_*ker 6

开始时的比较运算符@比没有运算符的运算符更通用.对于运算符</2,您只能比较数值和表达式(涉及字面数字和用数值实例化的变量).所以,</2你可以这样做:

?-  X = 2, Y = 3, X + Y < 2*Y.
X = 2,
Y = 3.

?- X = 2, Y = 3, X + Y > 2*Y.
false.

?-
Run Code Online (Sandbox Code Playgroud)

但是,如果表达式不计算为已知数字,则在以下情况下会出错:

?- Y = 3, X + Y < 2*Y.
ERROR: </2: Arguments are not sufficiently instantiated
Run Code Online (Sandbox Code Playgroud)

要么:

?- a < b.
ERROR: </2: Arithmetic: `a/0' is not a function
Run Code Online (Sandbox Code Playgroud)

但是,使用@</2你可以在prolog中比较许多不同类型的对象.比较评估遵循@Ankur给出的链接中描述的规则.要了解这些规则,你需要知道什么Prolog的术语是指,如term,functor,atom,等(参见,例如,Prolog的条款)

看一些例子:

?- a @< b.
true.

?- a(1) @< a(2).
true.

?- b(1) @< a(2).
false.

?- 20 @< a.
true.
Run Code Online (Sandbox Code Playgroud)

根据规则,这些非常简单.这是一个更有趣的案例(从上面):

?- Y = 3, X + Y @< 2*Y.
false.
Run Code Online (Sandbox Code Playgroud)

为什么X + Y被认为是"不低于" 2*Y?Prolog会在内部将其视为:

`+(X,3) @< *(2,3).`
Run Code Online (Sandbox Code Playgroud)

(注意Y实例化为3.)这些是复合术语(它们不是单独的原子或变量).如果我们查看比较规则,匹配规则是:

复合术语首先在他们的arity上检查,然后在他们的functor 名称上(按字母顺序)检查,最后在他们的参数上递归检查,最左边的参数首先检查.

元数两个方面是2. 仿函数名称+*分别.那些是不同的.并且在ASCII整理顺序中,+来之后*.因此,+"小于" *并不是真的,+(X,3) @< *(2,3).因此,并非如此,因此,事实并非如此Y = 3, X + Y @< 2 * Y.

另请注意,@</2不会计算数值表达式.因此,即使使用XY实例化为值,您将获得:

?- X = 2, Y = 3, X + Y @< 2*Y.
false.
Run Code Online (Sandbox Code Playgroud)

然而,当我们在</2这里时,这是真的,因为表达式X + Y < 2*Y在评估时是真实的.当变量简单统一时,它会理解这一点,所以你会有:

| ?- X @< Y.

yes
Run Code Online (Sandbox Code Playgroud)

但另一方面:

| ?- X = 2, Y = 1, X @< Y.

no
Run Code Online (Sandbox Code Playgroud)

在这种情况下X @< Y被视为2 @< 1由于Xwith 2Ywith 的统一1以及数字规则的启动.

说了这么多,@</2在谓词中的使用select_one_or_two使谓词可以在各种对象的列表上使用,而不仅仅是数字或完全实例化的数值表达式.如果已经使用过</2,那么以下内容可行:

?- select_one_or_two([2,1,3], X, Y).
X = [2, 3],
Y = [1] ;
X = [1, 2],
Y = [3] ;
X = [1, 3],
Y = [2] ;
false.
Run Code Online (Sandbox Code Playgroud)

但是以下失败了:

?- select_one_or_two([b,a,c], X, Y).
ERROR: </2: Arithmetic: `b/0' is not a function
?-
Run Code Online (Sandbox Code Playgroud)

但是,对于@<运营商,它的工作原理是:

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