这是我的临时解决方案。它仍然不理想,它会在第一个深度级别上“平滑”函数,因此如果公式中有更深入的其他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