2017-02-17 6 views
1

バイナリ数式(この場合はAND/OR)を与えられた述語を、nが正の整数に変換する述語を書く必要があります。いずれかの引数に適用されます。したがって、例えばand(and(A, B), and(C, D))and(A, B, C, D)になります。Prolog - バイナリ関数をn進数に変換する

誰も私に何を書き込むのかを教えてもらうことなく、これをどのように進めるべきか、私に指示できますか?私はそれについて行く方法を理解したいですが、私は本当にそれを見つけるのは難しいです。私が今まで得たことがちょうど基本ケースである - それが正しいかどうかはわからないその:

私はANDと両方の引数を持っている場合ではない化合物であり、ある
simplify(A, B) :- 
    A=..[Name, Arg1, Arg2], 
    Name == and, 
    not(compound(Arg1)), 
    not(compound(Arg2)), 
    B = A. 

、それは単純化機能があることを意味し同じ。さらに進めるには?

ありがとうございます!

+0

2つのパラメータがありますか? 1つは、単純化されたバージョンを "返す"? –

+0

はい、そうです。私は統合を使用する代わりに内部の関数を解析する必要があります。私はかなり混乱しました! – Dodicin

+0

まず、処理したい用語の種類とその場合の結果を決定する必要があります。たとえば、 'and(and(A、B)、and(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)を持つすべてのノードを1つのノードにまとめると同時に、異なるキーを持つノードを保持します(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

関連する問題