如何从Prolog中的术语获取原子变量列表

时间:2017-05-08 05:42:26

标签: prolog

如何从术语

获取原子变量列表

例如 -

Term = (h-5)* (h-5)+ (k- -2)* (k- -2)- (h-3)* (h-3)- (k-4)* (k-4)=0,
get_variables(Term, Var_list).

对于上述学期,答案为Var_list = [h,k].

2 个答案:

答案 0 :(得分:3)

以下代码与SICStus Prolog 4.5.0和SWI-Prolog 8.0.0一起运行。

它基于library(terms)iwhen/2

:- use_module(library(terms)).

atoms_in(As, T) :-
   (  \+ acyclic_term(T)
   -> throw(error(type_error(acyclic_term, T), _))
   ;  iwhen(ground(T), setof(A, (sub_term(A,T),atom(A)), As))
   -> true
   ;  As = []
   ).

使用SWI-Prolog 8.0.0:

?- atoms_in(Xs, (h-5)*(h-5)+(k- -2)*(k- -2)-(h-3)*(h-3)-(k-4)*(k-4)=0).
Xs = [h, k].

?- atoms_in(Xs, f(g(a,b),h(c,d))).
Xs = [a, b, c, d].

?- atoms_in(Xs, f(g(1,2),3)).
Xs = [].

?- atoms_in(Xs, 1).
Xs = [].

请注意如何捕获和报告无效使用:

?- atoms_in(_, _).
ERROR: Arguments are not sufficiently instantiated

?- atoms_in(_, f(_)).
ERROR: Arguments are not sufficiently instantiated

?- Term = f(a,Term), atoms_in(_, Term).
ERROR: Type error: `acyclic_term' expected, found `@(S_1,[S_1=f(a,S_1)])' (a cyclic)

答案 1 :(得分:0)

这应该有效(顺便说一句好问题):

variables(T,V):-
    variables(T,[],V1),
    sort(V1,V).

variables(T,Acc,[T|V]):-
    var(T), !,
    variables(Acc,[],V).
variables([],[],[]).
variables([],Acc,V):-
    variables(Acc,[],V).
variables([H|T],Acc,V):-
    append(T,Acc,NewAcc),
    variables(H,NewAcc,V).
variables(T,Acc,V):-
    atom(T),
    variables(Acc,[],V).
variables(T,Acc,V):-
    T=.. [_F|AL],
    variables(AL,Acc,V).

您的查询将是

?- variables((H-5)* (H-5)+ (K- -2)* (K- -2)- (H-3)* (H-3)- (K-4)* (K-4)=0,VL).