Таким образом, вам нужно обработать общий термин (т.е. древовидную структуру) и получить список его атомарных конечных узлов без дубликатов. Должен ли список результатов иметь определенный порядок (например, слева направо по глубине) или это не важно?
Если у вас есть возможность использовать переменные вместо атомов в формулах, тогда вы можете использовать встроенную (SWI-Prolog) term_variables/2
, например,
?- term_variables(and(X, and(X, Y), Z), Vars).
Vars = [X, Y, Z].
В противном случае вам нужно использовать решение, подобное:
term_atoms(Term, AtomSet) :-
term_to_atomlist(Term, AtomList),
list_to_set(AtomList, AtomSet).
term_to_atomlist(Atom, [Atom]) :-
atom(Atom),
!.
term_to_atomlist(Term, AtomList) :-
compound(Term),
Term =.. [_ | SubTerms],
terms_to_atomlist(SubTerms, AtomList).
terms_to_atomlist([], []).
terms_to_atomlist([Term | Terms], AtomList) :-
term_to_atomlist(Term, AtomList1),
terms_to_atomlist(Terms, AtomList2),
append(AtomList1, AtomList2, AtomList).
Пример использования:
?- term_atoms(f(x^a1+a3*a3/a4)='P'-l, Atoms).
Atoms = [x, a1, a3, a4, 'P', l].
Возможно, вы захотите расширить его для работы с числами и переменными в конечных узлах.