Prolog 变量表示

Prolog 变量表示,prolog,Prolog,我有一个术语,比如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\u term/2,它可以

我有一个术语,比如
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\u term/2
,它可以正确地看到变量,但仍然
term\u variables/2
无法提取它们:

?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),term_variables(Term,Vars).
Term = a(A, B, D),
Vars = [].
有人知道我做错了什么吗?我真的被卡住了,因为这个原因,我不能在我正在开发的程序中继续工作


非常感谢您。

我不确定您是如何使用的,它的实现是为了“…将[a term]的自由变量统一为一个术语
$VAR(N)
”,而这个术语不能直接用于将
a(t1,t2,t3)
转换为
a('$VAR'(0),'$VAR'(1),'$VAR'(2))
,除非
t1
t2
t3
是不同变量的占位符

SWI生成的术语
'$VAR'(N)
实际上是术语,而不是变量(如手册中所述),因此不能被视为变量

请注意,如果您看到以下内容:

?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term).
Term = a(A, B, D).
发生的情况是,
Term=a(a,B,D)。
行是通过类似控制台的方式写入的,控制台可以配置为将某些术语(如
“$VAR”(N)
)描述为命名变量(这可能会产生误导)。请注意,如果您尝试以下方法:

?- 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).
% 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).
对此处的调用显式禁用了
numbervars
选项,并打印出
a/3
术语的参数的真实绑定,它们实际上是
$VAR(N)
术语。打印到控制台的下一行(即,
Term=a(a,B,D)
)执行类似于启用
numbervars
选项的操作(可能是为了可读性)

如果您需要对一个术语进行“变量化”,我可以提出以下建议:

?- 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).
% 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
,因为它将查找并替换输入项中出现的任何子元素(即使它们是其他变量!)。

我不确定您是如何使用它的,它的实现是为了“…将[a term]的自由变量与
$VAR(N)
”统一起来,它不能直接用于将术语
a(t1,t2,t3)
转换为
a('$VAR'(0),'$VAR'(1),'$VAR'(2))
,除非
t1
t2
t3
是不同变量的占位符

SWI生成的术语
'$VAR'(N)
实际上是术语,而不是变量(如手册中所述),因此不能被视为变量

请注意,如果您看到以下内容:

?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term).
Term = a(A, B, D).
发生的情况是,
Term=a(a,B,D)。
行是通过类似控制台的方式写入的,控制台可以配置为将某些术语(如
“$VAR”(N)
)描述为命名变量(这可能会产生误导)。请注意,如果您尝试以下方法:

?- 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).
% 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).
对此处的调用显式禁用了
numbervars
选项,并打印出
a/3
术语的参数的真实绑定,它们实际上是
$VAR(N)
术语。打印到控制台的下一行(即,
Term=a(a,B,D)
)执行类似于启用
numbervars
选项的操作(可能是为了可读性)

如果您需要对一个术语进行“变量化”,我可以提出以下建议:

?- 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).
% 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
,因为它将查找并替换输入项中出现的任何子元素(即使它们是其他变量!)。

非常感谢您的回复。你的建议没有多大帮助,因为我不知道我必须变量化的术语。我必须从知识中构造符合某些句法偏见的子句,然后进行变量化和泛化。我使用numbervars(,N,),其中N对于第一个变量为0,并且对于每个新变量都递增,然后使用初始函子创建一个变量项。但是我需要从变量项中获取变量。我采用了一种愚蠢的方法,将变量项写入文件,然后读取并获取变量。您的
variablize
是一段非常简洁的代码。我希望我能达到这样的Prolog熟练程度!谢谢我希望这会有帮助。我专职编程Prolog已经有好几年了;)非常感谢您的回复。你的建议没有多大帮助,因为我不知道我必须变量化的术语。我必须从知识中构造符合某些句法偏见的子句,然后进行变量化和泛化。我使用numbervars(,N,),其中N对于第一个变量为0,并且对于每个新变量都递增,然后使用初始函子创建一个变量项。但是我需要从变量项中获取变量。我采用了一种愚蠢的方法,将变量项写入文件,然后读取并获取变量。您的
variablize
是一段非常简洁的代码。我希望我能达到这样的Prolog熟练程度!谢谢我希望这会有帮助。我专职编程Prolog已经有好几年了;)