Пролог: получение уникальных атомов из пропозициональных формул - PullRequest
1 голос
/ 17 октября 2010

Я могу легко написать предикат для получения уникальных элементов из заданного списка в Прологе, например,

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 (and (x, and (x, y), z), [x, y, z]).доволен.Используете ли вы рекурсию так же, как в моем примере no_doubles, но для такой формулы?

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

Ответы [ 2 ]

2 голосов
/ 18 октября 2010

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

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

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

1 голос
/ 17 октября 2010
?- 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).

Более прямым способом является использование комплектов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...