這是我的臨時解決方案。它仍然不理想,它會在第一個深度級別上「平滑」函數,因此如果公式中有更深入的其他AND或OR,則不會達到它們。如何使它工作?
simplify(A, B, Functor) :- A=..[Name, Arg1, Arg2], Name == Functor,
not(compound(Arg1)), not(compound(Arg2)), B = A.
simplify(A, B, Functor) :- A=..[Name, Arg1, Arg2], Name == Functor,
Arg1=..[Name|_], Arg2=..[Name|_],
simplify(Arg1, C, Functor), simplify(Arg2, D, Functor),
C=..[_|ArgsC], D=..[_|ArgsD],
append(ArgsC, ArgsD, ArgsB),
B =.. [Functor|ArgsB].
simplify(A, B, Functor) :- A=..[Name, Arg1, Arg2], Name == Functor,
Arg1=..[Name|_],
simplify(Arg1, C, Functor),
C=..[_|ArgsC],
append(ArgsC, [Arg2], ArgsB),
B =.. [Functor|ArgsB].
simplify(A, B, Functor) :- A=..[Name, Arg1, Arg2], Name == Functor,
Arg2=..[Name|_],
simplify(Arg2, C, Functor),
C=..[_|ArgsC],
append([Arg1], ArgsC, ArgsB),
B =.. [Functor|ArgsB].
編輯:此解決方案應該工作(不完整,我仍然寫每個案件)。如果將公式看作二叉樹結構,它會將具有相同鍵(AND或OR)的每個節點放到一個節點中,同時保留具有不同鍵的分離節點(不要與OR混合使用AND參數)。儘管如此,由於我正在爲每種情況編寫一個案例(例如,[Arg1 is not a compound, Arg2 is an AND]
,[Arg1 is not a compound, Arg2 is an OR]
等),但我不知道您是否可以更優雅地做到這一點。如果可能的話,告訴我!
% Case X(a, b) => X(a, b)
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
not(compound(Arg1)), not(compound(Arg2)), B = A, !.
% Case X(X(a, b), c) => X(a, b, c)
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
Arg1=..[Name|_], not(compound(Arg2)),
simplify(Arg1, C), C=..[_|ArgsC],
append(ArgsC, [Arg2], ArgsB),
B =.. [Name|ArgsB], !.
% Case X(a, X(b, c)) => X(a, b, c)
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
not(compound(Arg1)), Arg2=..[Name|_],
simplify(Arg2, C), C=..[_|ArgsC],
append([Arg1], ArgsC, ArgsB),
B =.. [Name|ArgsB], !.
% Case X(X(a, b), X(c, d)) => X(a, b, c, d)
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
Arg1=..[Name|_], Arg2=..[Name|_],
simplify(Arg1, C), simplify(Arg2, D),
C=..[_|ArgsC], D=..[_|ArgsD],
append(ArgsC, ArgsD, ArgsB),
B =.. [Name|ArgsB], !.
% Case X(X(a, b), Y(b, c)) => X(a, b, Y(b, c))
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
Arg1=..[Name|_], Arg2=..[DifferentName|_], Name \== DifferentName,
simplify(Arg1, C),
subset([DifferentName], [or, and]), simplify(Arg2, D),
C=..[_|ArgsC],
append(ArgsC, [D], ArgsB),
B =.. [Name|ArgsB], !.
% Case X(Y(a, b), X(c, d)) => X(Y(a, b), c, d)
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
Arg1=..[DifferentName|_], Arg2=..[Name|_],
simplify(Arg2, C),
subset([DifferentName], [or, and]), simplify(Arg1, D),
C=..[_|ArgsC],
append([D], ArgsC, ArgsB),
B =.. [Name|ArgsB], !.
% Case X(Y(a, b), Y(c, d)) => X(Y(a, b, c, d))
simplify(A, B) :- A=..[Name, Arg1, Arg2], subset([Name], [or, and]),
Arg1=..[DifferentName|_], Arg2=..[DifferentName|_],
simplify(Arg1, C), simplify(Arg2, D),
C=..[_|ArgsC], D=..[_|ArgsD],
append(ArgsC, ArgsD, ArgsB),
E =..[DifferentName|ArgsB],
B =.. [Name|[E]], !.
不應該簡化有兩個參數嗎?一個「返回」簡化版本? –
是的,你是對的。我需要解析函數而不是使用統一。我很困惑! – Dodicin
首先,您需要確定您想要處理的術語種類以及在這些情況下的結果。例如,'和(和(A,B)和(C,D))'很容易理解爲'和(A,B,C,D)'。但是......和(和(A,B)或(和(C,D),E))呢?你是否想要簡化表達式以及結合參數?一旦你決定,遞歸思考。簡化(和(A,B),表達式): - ...簡化(A),...,簡化(B),...等等。 – lurker