我有一个术语,例如 a(t1,t2,t3)
,我使用 numbervars/3
对其进行变量化。然后我需要提取该术语的变量,但变量显示为:
a('$VAR'(0),'$VAR'(1),'$VAR'(2))
问题是 prolog 似乎无法将这些术语识别为变量:
?- term_variables(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),L).
L = [].
或者更简单:
?- var('$VAR'(0)).
false.
另一方面,如果我使用copy_term/2,它可以正确地看到变量,但仍然无法提取它们:
?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),term_variables(Term,Vars).
Term = a(A, B, D),
Vars = [].
有人知道我做错了什么吗?我真的陷入困境,因此无法在我正在开发的程序中进一步工作。
预先非常感谢您。
I have a term, say a(t1,t2,t3)
which I variabilize using numbervars/3
. Then I need to extract the variables of the term, but the variables appear as:
a('$VAR'(0),'$VAR'(1),'$VAR'(2))
The problem is that prolog
doesn't seem to recognize these terms as variables:
?- term_variables(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),L).
L = [].
Or even simpler:
?- var('$VAR'(0)).
false.
On the other hand, if I use copy_term/2
, it sees the variables correctly, but still term_variables/2
won't extract them:
?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),term_variables(Term,Vars).
Term = a(A, B, D),
Vars = [].
Does anyone has any idea what I am doing wrong? I'm really stuck and I can't work further in the program I'm developing because of this.
Thank you very much in advance.
发布评论
评论(1)
我不确定您如何使用
numbervars/3< /code>
,其实现是为了“...将 [a term] 的自由变量与术语
$VAR(N)
统一” ,不能直接用来转动术语将a(t1,t2,t3)
转换为a('$VAR'(0),'$VAR'(1),'$VAR'(2))
作为您建议,除非t1
、t2
和t3
是不同变量的占位符。SWI 的 '$VAR'(N) >
numbervars/3
生成的确实是术语,而不是变量(如手册中所述),因此不能将其视为变量。请注意,如果您看到以下内容:
发生的情况是行
Term = a(A, B, D).
是通过类似write_term/2
到控制台,可以将其配置为描绘某些术语,例如 <代码>'$VAR'(N)作为命名变量(这可能会产生误导)。请注意,如果您尝试这样做:调用
write_term/2
此处显式禁用numbervars
选项,并打印出a/3
参数的 true 绑定术语,这确实是$VAR(N)
术语。打印到控制台的下一行(即Term = a(A, B, D)
)正在执行类似于启用 numbervars 的操作选项(也许是为了可读性)。如果您需要“变量化”一个术语,我可以建议按照以下方式进行操作:
示例:
假设您知道要替换哪些子元素(例如,
t2
)以及替换为哪些变量。这个特定的实现可以更准确地称为“replace/3”,因为它将查找并替换输入项中出现的任何子元素(即使它们是其他变量!)。I'm unsure about how you're using
numbervars/3
, which is implemented so as to "...unify the free variables of [a term] with a term$VAR(N)
", which can't be used directly to turn the terma(t1,t2,t3)
intoa('$VAR'(0),'$VAR'(1),'$VAR'(2))
as you suggest, unlesst1
,t2
andt3
are your place-holders for distinct variables.The terms
'$VAR'(N)
that SWI'snumbervars/3
generates are indeed terms, and not variables (as described in the manual), so can't be treated as variables.Note that, if you see this:
What is happening is that the line
Term = a(A, B, D).
is being written via something likewrite_term/2
to the console, which can be configured to portray certain terms like'$VAR'(N)
as named variables (which can be misleading). Notice that if you try this instead:The call to
write_term/2
here explicitly disables thenumbervars
option, and prints out the true bindings of the arguments of thea/3
term, which are indeed$VAR(N)
terms. The next line printed to the console (i.e.,Term = a(A, B, D)
) is doing something akin to enabling thenumbervars
option instead (perhaps for readability).If you need to 'variablize' a term, I can suggest something along these lines instead:
Example:
This assumes that you know which sub-elements (e.g.,
t2
) you want replaced, and with which variables. This particular implementation could more accurately be calledreplace/3
, as it will find-and-replace any sub-element occurrence in the input term (even if they are other variables!).