[英]What is the Prolog operator `^` ("caret")?
What is the Prolog operator ^
?什么是 Prolog 运算符
^
?
Looking at The Prolog Built-in Directive op gives a list of the built-in operators.查看Prolog 内置指令 op给出了内置运算符的列表。
I see我懂了
**
is exponentiation **
是求幂/\\
is or /\\
是或but what is ^
?但什么是
^
?
Each of the three current answers are of value and I learned something:当前三个答案中的每一个都很有价值,我学到了一些东西:
The operator (^)/2
serves several purposes:运算符
(^)/2
多种用途:
setof/3
, bagof/3
setof/3
, bagof/3
Here it is used to denote the existential variables (set) of a term .这里它用来表示一个术语的存在变量(集合) 。 Like in
setof(Ch, P^child_of(Ch,P), Chs)
where P
is declared as an existential variable.就像在
setof(Ch, P^child_of(Ch,P), Chs)
,其中P
被声明为存在变量。
As a non-standard side effect to this, many systems have defined it as predicate with the following definition:作为对此的非标准副作用,许多系统将其定义为具有以下定义的谓词:
_^Goal :- Goal
But then, others do not have such a definition.但是,其他人没有这样的定义。 It is in any case a good idea to avoid to define a predicate
(^)/2
.在任何情况下,避免定义谓词
(^)/2
都是一个好主意。
(^)/2
- power (^)/2
- 功率This is an evaluable functor accessible via (is)/2
and arithmetic comparison like (=:=)/2
and (>)/2
.这是一个可评估的函子,可通过
(is)/2
和算术比较(=:=)/2
如(=:=)/2
和(>)/2
。 Also library(clpfd)
uses it with this meaning. library(clpfd)
也用这个意思来使用它。 In contrast to (**)/2
which always results in a float, 2^2
is an integer - thereby permitting arithmetics with bigints.与总是产生浮点数的
(**)/2
相比, 2^2
是一个整数 - 从而允许使用 bigint 进行算术运算。 Just try ?- X is 7^7^7.
试试
?- X is 7^7^7.
to see if your system supports them.看看你的系统是否支持它们。
Finally, there are user defined uses for (^)/2
that do not collide with above uses like lambda expressions via library(lambda)
(source ).最后,用户定义的
(^)/2
使用不会与上述使用相冲突,例如通过library(lambda)
(source ) 使用 lambda 表达式。
There are a few general remarks about its use.关于它的使用有一些一般性的说明。
(^)/2
associates to the right which means that: (7^7^7) = (7^(7^7))
. (^)/2
与右侧相关联,这意味着: (7^7^7) = (7^(7^7))
。 It has a very low priority which means that you have to use brackets for arguments with standard operators.它的优先级非常低,这意味着您必须使用方括号作为标准运算符的参数。
In math expressions, ^ is exponentiation, it's just different notation for **.在数学表达式中,^ 是取幂,它只是 ** 的不同表示法。
In lambda expressions, it is a parameter-passing operator.在 lambda 表达式中,它是一个参数传递运算符。
As in Pereira and Shieber's book:正如 Pereira 和 Shieber 的书中所说:
Thus the lambda expression λ x.因此 lambda 表达式 λ x。 x + 1 would be encoded in Prolog as X^(X+1).
x + 1 将在 Prolog 中编码为 X^(X+1)。 Similarly, the lambda expression λ x.
类似地,lambda 表达式 λ x。 λ y.wrote(y, x) would be encoded as the Prolog term X^Y^wrote(Y,X), assuming right associativity of "^"
λ y.wrote(y, x) 将被编码为 Prolog 项 X^Y^wrote(Y,X),假设“^”的右结合
In Prolog, most symbols can be used 'uninterpreted', at syntactic level, in particular after an op/3
declaration, any atom can be used as operator .在 Prolog 中,大多数符号都可以“未解释”地使用,在语法级别,特别是在
op/3
声明之后,任何原子都可以用作operator 。 Then you can use, for instance, ^/2
as a function constructor for a domain specific language (a DSL), with a semantic specified from your rules.然后,例如,您可以使用
^/2
作为域特定语言(DSL)的函数构造函数,并根据您的规则指定语义。
Is SWI-Prolog (or more generally in ISO Prolog), current_op/3
gives you information about declared operators:是 SWI-Prolog(或更一般地在 ISO Prolog 中),
current_op/3
为您提供有关声明运算符的信息:
?- current_op(X,Y,^).
X = 200,
Y = xfy.
That said, any Prolog implementing setof/3
is expected to interpret ^/2
as a quantification specifier, when put to decorate the 2 nd argument.也就是说,当用于装饰第二个参数时,任何实现
setof/3
Prolog 都应该将^/2
解释为量化说明符。 As well, any Prolog implementing is/2
is expected to interpret ^/2
as exponentiation, when occurring on the right side of the is/2
expression.同样,当出现在
is/2
表达式的右侧时,任何实现is/2
Prolog 都应将^/2
解释为幂运算。
Here's my addition to the use of ^
in setof/3
and bagof/3
.这是我在
setof/3
和bagof/3
使用^
bagof/3
。
Upfront note :前期注意:
Personally, I consider the semantics of ^
to be a failure, because it looks as if this were an "existential quantification" and is even described as such sometimes (for example: GNU Prolog , SWI-Prolog library(yall) ) but it actually is NOT .就个人而言,我认为
^
的语义是失败的,因为它看起来好像是“存在量化”,有时甚至被描述为这样(例如: GNU Prolog , SWI-Prolog library(yall) )但实际上不是。 Avoid this misfeature , write a separate predicate to be called by setof/3
and bagof/3
instead.避免这种错误功能,编写一个单独的谓词由
setof/3
和bagof/3
调用。 An ISO Prolog-2, if it ever happens, should really clean this up. ISO Prolog-2,如果发生的话,应该真正清理它。
We start with an overview ASCII Image:我们从概览 ASCII 图像开始:
Clause-wide variable
|
|
+------------------------+------------------------+
| |
| Clause-wide variables |
| that are collected via the |
| template at arg-position 1 by |
| setof/3 (NOT local to setof/3) |
| thus can be constrained elsewhere |
| in the clause (possibly accidentally) |
| | |
| | |
| +-+--------+----------+-+ |
| | | | | |
| | | | | |
get_closed_set(Set,K) :- setof( [X,Y] , P^R^search(P,R,X,Y,K) , Set).
| | | | | |
| <-------------------> Goal expression
| | | | | |
| | | | | |
+---------------------------------------+-----+
| | | | |
| | | | |
+-+----+---+-+ Clause-wide variable.
| Backtracking over this
| is done by the caller
| of get_closed_set/2.
|
Variables marked as "free for
backtracking if fresh".
This is NEARLY the same as "being
local to the goal expression" or
"being existentially quantified."
Backtracking over these is done by setof/3.
If these appear elsewhere in the clause,
they be constrained (possibly accidentally)!
search(1,n,a,g).
search(2,m,a,g).
search(2,m,a,j).
search(1,m,a,j).
search(3,w,a,j).
search(3,v,a,j).
search(2,v,b,g).
search(3,m,b,g).
search(5,m,b,g).
search(2,w,b,h).
% ===
% HATTY EXPRESSIONS ("CLOSED EXPRESSIONS")
% ===
% If P and R do not appear anywhere else than in the goal expression.
% "P^R^" (not quite) closes off variables P,R: they are not (not quite)
% invisible outside of the goal expression "P^R^search(P,R,X,Y)"
get_closed_set(Set) :- setof( [X,Y] , P^R^search(P,R,X,Y) , Set).
get_closed_bag(Bag) :- bagof( [X,Y] , P^R^search(P,R,X,Y) , Bag).
% The above is the same as this (which I recommend for clarity and
% to avoid annoying bug searches):
indirect_search(X,Y) :- search(_P,_R,X,Y).
get_closed_set_indirect(Set) :- setof( [X,Y] , indirect_search(X,Y) , Set).
get_closed_bag_indirect(Bag) :- bagof( [X,Y] , indirect_search(X,Y) , Bag).
% ===
% NONHATTY EXPRESSIONS ("OPEN EXPRESSIONS")
% ===
get_open_set(Set,P,R) :- setof( [X,Y] , search(P,R,X,Y) , Set).
get_open_bag(Bag,P,R) :- bagof( [X,Y] , search(P,R,X,Y) , Bag).
% ===
% TESTING
% ===
:- begin_tests(hat_operator).
test(clo_set) :- get_closed_set(Set),
format("Closed Set:\n ~q\n",[Set]),
Set = [[a,g],[a,j],[b,g],[b,h]].
test(clo_bag) :- get_closed_bag(Bag),
format("Closed Bag:\n ~q\n",[Bag]),
Bag = [[a,g],[a,g],[a,j],[a,j],[a,j],[a,j],[b,g],[b,g],[b,g],[b,h]].
test(clo_set_ind) :- get_closed_set_indirect(Set),
format("Closed Set, indirect:\n ~q\n",[Set]),
Set = [[a,g],[a,j],[b,g],[b,h]].
test(clo_bag_ind) :- get_closed_bag_indirect(Bag),
format("Closed Bag, indirect:\n ~q\n",[Bag]),
Bag = [[a,g],[a,g],[a,j],[a,j],[a,j],[a,j],[b,g],[b,g],[b,g],[b,h]].
test(opn_set) :- bagof(solution(Set,P,R), get_open_set(Set,P,R), OuterBag),
format("Bag for get_open_set/3:\n ~q\n",[OuterBag]).
test(opn_bag) :- bagof(solution(Bag,P,R), get_open_bag(Bag,P,R), OuterBag),
format("Bag for get_open_bag/3:\n ~q\n",[OuterBag]).
:- end_tests(hat_operator).
rt :- run_tests(hat_operator).
When we run rt
, nothing unexpected occurs, we are like Fonzi with existential quantifiers:当我们运行
rt
,没有任何意外发生,我们就像带有存在量词的 Fonzi:
Closed Set: [[a,g],[a,j],[b,g],[b,h]]
Closed Bag: [[a,g],[a,g],[a,j],[a,j],[a,j],[a,j],
[b,g],[b,g],[b,g],[b,h]]
Closed Set, indirect: [[a,g],[a,j],[b,g],[b,h]]
Closed Bag, indirect: [[a,g],[a,g],[a,j],[a,j],[a,j],[a,j],
[b,g],[b,g],[b,g],[b,h]]
Bag for get_open_set/3: [solution([[a,j]],1,m),solution([[a,g]],1,n),
solution([[a,g],[a,j]],2,m),solution([[b,g]],2,v),
solution([[b,h]],2,w),solution([[b,g]],3,m),
solution([[a,j]],3,v),solution([[a,j]],3,w),
solution([[b,g]],5,m)]
Bag for get_open_bag/3: [solution([[a,j]],1,m),solution([[a,g]],1,n),
solution([[a,g],[a,j]],2,m),solution([[b,g]],2,v),
solution([[b,h]],2,w),solution([[b,g]],3,m),
solution([[a,j]],3,v),solution([[a,j]],3,w),
solution([[b,g]],5,m)]
You may have to run this to see more list output (case of SWI-Prolog):您可能必须运行它才能看到更多列表输出(SWI-Prolog 的情况):
set_prolog_flag(answer_write_options,[max_depth(100)]).
set_prolog_flag(debugger_write_options,[max_depth(100)]).
If you enter the following, Prolog correctly warns about "singleton variables P,R".如果输入以下内容,Prolog 会正确警告“单个变量 P,R”。 Good.
好的。
get_open_set(Set) :- setof([X,Y],search(P,R,X,Y),Set).
This is accepted and could be given a meaning, but Prolog will be looking for procedure ^/2
on call and say that "^/2 can only appear as the 2nd argument of setof/3 and bagof/3" .这是可以接受的并且可以赋予含义,但是 Prolog 将在调用时查找过程
^/2
并说"^/2 只能作为 setof/3 和 bagof/3 的第二个参数出现" 。 Okay.好的。
get_outerly_closed_set(Set) :- P^R^setof([X,Y],search(P,R,X,Y),Set).
A possible meaning for the above might be the utterly mundane:上述可能的含义可能是完全平凡的:
get_outerly_closed_set(Set) :- close_it_off(Set).
close_it_off(Set) :- setof([X,Y],search(_P,X,_R,Y),Set).
Now we are getting into "failure of semantics" territory: Prolog does not consider the outside P
as a variable different from the P
in P^
.现在,我们正在进入领土“的语义失败”:序言不考虑外部
P
从一个变量不同的P
在P^
。 This is why P^
does NOT mean "∃P such that" :这就是为什么
P^
不意味着“∃P 使得” :
get_closed_set_weird_1(Set,P) :-
setof( [X,Y] , P^R^search(P,R,X,Y) , Set),
format("P=~q\n",[P]).
?- get_closed_set_weird_1(Set,P).
P=_14996
Set = [[a, g], [a, j], [b, g], [b, h]].
?- get_closed_set_weird_1(Set,1).
P=1
Set = [[a, g], [a, j]].
No warnings occur if you write such a thing:如果你写这样的东西,不会出现警告:
get_closed_set_weird_2(Set) :-
setof( [X,Y,P], P^R^search(P,R,X,Y), Set).
?- get_closed_set_weird_2(Set).
Set = [[a, g, 1], [a, g, 2], [a, j, 1], [a, j, 2], [a, j, 3], ...
In fact, P^
ends up being ignored.事实上,
P^
最终被忽略。 The above is the same as:上面是一样的:
get_closed_set_weird_2e(Set) :-
setof( [X,Y,P], R^search(P,R,X,Y), Set).
This is entirely expected behaviour, but a casual reading of setof([X,Y], ...
would lead one to think that [X,Y]
are free variables over which setof/3
ranges. This is not the case: [X,Y]
is just a template and X
and Y
are actually clause-wide variables, which can be constrained elsewhere:这完全是预期的行为,但是对
setof([X,Y], ...
的随意阅读会让人认为[X,Y]
是setof/3
范围内的自由变量。事实并非如此: [X,Y]
只是一个模板, X
和Y
实际上是子句范围的变量,可以在其他地方进行约束:
get_closed_set_weird_2(Set,X) :-
setof( [X,Y], P^R^search(P,R,X,Y) , Set),
format("X=~q\n",[X]).
?- get_closed_set_weird_2(Set,X).
X=_20346
Set = [[a, g], [a, j], [b, g], [b, h]].
?- get_closed_set_weird_2(Set,b).
X=b
Set = [[b, g], [b, h]].
The above would have been more clear as上面的会更清楚,因为
get_closed_set_weird_2c(Set,V) :-
setof( [V,Y], close_it_off(V,Y), Set),
format("V=~q\n",[V]).
close_it_off(X,Y) :- search(_P,_R,X,Y).
?- get_closed_set_weird_2c(Set,V).
V=_21682
Set = [[a, g], [a, j], [b, g], [b, h]].
but note that this is absolutely not the same as this, where we backtrack over V
outside of setof/3
:但请注意,这绝对与此不同,我们在
setof/3
之外回溯V
:
get_closed_set_weird_2x(Set,V) :-
setof( [X,Y], close_it_off(V,X,Y), Set),
format("V=~q\n",[V]).
close_it_off(V,X,Y) :- V=X,search(_P,_R,X,Y).
?- get_closed_set_weird_2x(Set,V).
V=a
Set = [[a, g], [a, j]], V = a ;
V=b
Set = [[b, g], [b, h]], V = b.
One would like to have a clean way of indicating which variables of the goal expression are visible outside of the goal expression, which ones are not, and which ones to range over.人们希望有一种干净的方式来指示目标表达式的哪些变量在目标表达式之外可见,哪些不可见,以及哪些变量可以覆盖。
How about this:这个怎么样:
λX.
λX.
at the head of the goal expression, the X
is visible outside the goal expression.X
在目标表达式之外可见。 Any X
elsewhere in the clause is the same X
.X
都是相同的X
。∃X.
∃X.
at the head of the goal expression, the X
is invisible outside the goal expression.X
在目标表达式之外是不可见的。 Any X
elsewhere in the clause is a different X
(you are then invited to proceed to rename by the editor).X
都是不同的X
(然后编辑邀请您继续重命名)。X
that appears in the goal expression without a preceding λX.
X
前面没有λX.
or a ∃X.
∃X.
is a compiler error .λX.
λX.
and any variables appearing as ∃X.
∃X.
变量∃X.
(Don't complain about the lowercase x
above; it just looks that way. λX. ∃X. Xx
) (不要抱怨上面的小写
x
;它看起来就是这样λX. ∃X. Xx
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.