2017-02-17 85 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