我有一个术语,说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
,它会正确看到变量,但term_variables/2
仍然无法提取它们:
?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),term_variables(Term,Vars).
Term = a(A, B, D),
Vars = [].
有谁知道我做错了什么?我真的被困了,因为这个原因,我无法在我正在开发的程序中进一步工作。
非常感谢你。
答案 0 :(得分:4)
我不确定你是如何使用numbervars/3
的,这是为了实现“ ...将{a term]的自由变量与术语$VAR(N)
统一起来” ,除非a(t1,t2,t3)
,a('$VAR'(0),'$VAR'(1),'$VAR'(2))
和t1
为t2
,否则无法直接将t3
一词转换为'$VAR'(N)
。你的占位符是不同的变量。
SWI numbervars/3
生成的术语?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term).
Term = a(A, B, D).
确实是术语,而不是变量(如手册中所述),因此不能视为变量。
请注意,如果你看到这个:
Term = a(A, B, D).
正在发生的是'$VAR'(N)
行正在通过类似write_term/2
之类的东西写入控制台,可以将其配置为将某些术语(如?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),
write_term(Term, [numbervars(false)]).
a($VAR(0), $VAR(1), $VAR(3))
Term = a(A, B, D).
)描述为命名变量(可以误导)。请注意,如果您尝试这样做:
numbervars
此处对write_term/2
的调用显式禁用了a/3
选项,并打印出$VAR(N)
项的参数的 true 绑定,这些绑定确实是Term = a(A, B, D)
条款。打印到控制台的下一行(即numbervars
)正在执行类似启用 % takes a term T, a list of [Term:Variable] replacements R, and makes V:
variablize(T, R, V) :-
member(R0:V, R),
R0 == T, !.
variablize([T|Ts], R, [NT|NTs]) :-
!,
variablize(T, R, NT),
variablize(Ts, R, NTs).
variablize(T, R, NT) :-
compound(T), !,
T =.. [F|As],
variablize(As, R, NAs),
NT =.. [F|NAs].
variablize(T, _, T).
选项的操作(可能是为了提高可读性)。
如果你需要“变量化”一个术语,我可以建议这些内容:
?- variablize(a(t1,t2,t3), [t1:X, t2:Y, t3:Z], T).
T = a(X, Y, Z).
示例:
t2
这假定您知道要替换哪些子元素(例如replace/3
)以及哪些变量。这个特定的实现可以更准确地被称为{{1}},因为它将在输入术语中找到并替换任何子元素出现(即使它们是其他变量!)。