簡體   English   中英

序言:從命題公式中獲得唯一原子

[英]Prolog: Getting unique atoms from propositional formulas

我可以輕松地編寫一個謂詞以從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 ).

但是,除了正常列表以外,您如何才能做同樣的事情,即不是[a,b,c ...]之類的事情? 因此,在我的情況下,我想為命題公式提取唯一原子,例如unique_atoms(and(x,and(x,y),z),[x,y,z])。 很滿意。 您是否像我的no_doubles示例中那樣使用遞歸,但是否使用了這樣的公式?

任何想法都歡迎:)。 謝謝。

因此,您需要處理一個通用術語(即樹結構),並獲取其原子葉節點的列表,且不能重復。 結果列表是否必須具有特定的順序(例如,深度從左到右)?這不重要嗎?

如果您可以選擇在公式中使用變量而不是原子,則可以使用(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].

您可能需要擴展它以處理葉節點中的數字和變量。

?- 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).

一種更直接的方法是使用集合

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM