2010-10-17 3 views
1

Я могу легко написать предикат, чтобы получить уникальные элементы из данного списка в Prolog, например.Пролог: Получение уникальных атомов из формул предложений

no_doubles([], []). 
no_doubles([H|T], F) :- 
member(H, T), 
no_doubles(T, F). 
no_doubles([H|T], [H|F]) :- 
\+ member(H, T), 
no_doubles(T, F). 

Однако, как вы можете сделать то же самое, но для чего-то другого, чем обычный список, т.е. не что-то вроде [а, Ь, с ...]? Поэтому в моем случае я хочу извлечь уникальные атомы для пропозициональной формулы, например. unique_atoms (и (х, и (х, у), г), [х, у, г]). выполняется. Вы используете рекурсию так же, как в моем примере no_doubles, но для такой формулы?

Любые идеи приветствуются :). Благодарю.

ответ

1
?- setof(X, member(X,[a,b,c,a,b,c]), L). 
L = [a, b, c]. 

?- sort([a,b,c,a,b,c], L). 
L = [a, b, c]. 

Пропозициональные формулы:

get_atoms(X,[X]) :- 
    atom(X). 
get_atoms(and(P,Q),Atoms) :- 
    get_atoms(P,Left), 
    get_atoms(Q,Right), 
    append(Left,Right,Atoms). 

и т.д. Оптимизировать с использованием разностных списков, если это необходимо.

unique_atoms(P,UniqueAtoms) :- get_atoms(P,Atoms), sort(Atoms,UniqueAtoms). 

Более прямой способ заключается в использовании sets.

+0

Спасибо larsmans, ваш предикат get_atoms дал мне приблизительное представление о том, что я должен делать, и я решил проблему сейчас, поэтому спасибо :). Я также посмотрю на ссылку, которую вы разместили. – ale

2

Так что вам нужно обработать общий термин (т. Е. Древовидную структуру) и получить список его атомных листовых узлов без дубликатов. Должен ли список результатов иметь определенный порядок (например, глубина с первого взгляда слева направо), или это не важно?

Если у вас есть возможность использовать переменные вместо атомов в ваших формулах, вы можете использовать встроенный (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]. 

Вы можете продлить его, чтобы иметь дело с числами и переменными в листе узлы.

Смежные вопросы