2017-02-17 106 views
1

如果函数是相同的,我必须编写一个谓词给定一个二进制公式(在这种情况下为ANDs/ORs),将其转换为n元序列适用于任一论点。因此,例如,and(and(A, B), and(C, D))变为and(A, B, C, D)Prolog - 将二进制函数转换为n进制函数

任何人都可以告诉我如何继续这个没有告诉我究竟写什么?我想了解如何去做,但我真的觉得很难。什么我到现在为止仅仅是一个基本情况 - 我不知道这是否是正确的:

simplify(A, B) :- 
    A=..[Name, Arg1, Arg2], 
    Name == and, 
    not(compound(Arg1)), 
    not(compound(Arg2)), 
    B = A. 

也就是说,如果我有一个AND和两个参数都没有的化合物,那么就意味着简化的功能一样。我如何继续进行下去?

谢谢!

+0

不应该简化有两个参数吗?一个“返回”简化版本? –

+0

是的,你是对的。我需要解析函数而不是使用统一。我很困惑! – Dodicin

+0

首先,您需要确定您想要处理的术语种类以及在这些情况下的结果。例如,'和(和(A,B)和(C,D))'很容易理解为'和(A,B,C,D)'。但是......和(和(A,B)或(和(C,D),E))呢?你是否想要简化表达式以及结合参数?一旦你决定,递归思考。简化(和(A,B),表达式): - ...简化(A),...,简化(B),...等等。 – lurker

回答

0

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

这只是看起来不正确。我不明白如何在没有递归的情况下处理一般情况,除非您在问题中没有明确说明您的假设。 – lurker

+0

我编辑的代码更清晰。它有效,但有很多情况下,我不知道你是否可以推广更多。也许通过跟踪父亲仿函数或类似的东西? – Dodicin

+0

这就是我要说的。有很多情况,似乎递归是处理它们的方式。如果您限制了将项嵌入括号内的深度,则可以在不递归的情况下执行此操作,但正如我所说,您的问题没有提供任何限制问题范围的指导。一般问题需要递归。看到我对你原来的问题的评论。 – lurker