3

次のような論理句が提示される楽しい小さな問題があります。

Rule 1. A, B and C are unique, and are numbers from 1 to 3 (so every number is used).
Rule 2. B < 2
Rule 3. C > 2

今(私が思いついたこの簡単な例が実際に検証されると仮定すると:P)、それは簡単に見ることができます

A = 2
B = 1
C = 3

しかし、これは非常に不自然な例です。

20 個 (または 1 万個) のルールがあり、それらが重複しているとしたらどうでしょう。有効な単一の回答があり、何らかの方法でルールにアクセスできると仮定します (述語のリストなど)。

素晴らしく、一般的で、直感的な解決策はありますか? Prolog が特定のライブラリで解決できることは知っていますが、私の試みは無駄でした。範囲内のすべての数値を力ずくで並べ替えてから、ルールに準拠していることを手動で確認できることはわかっています。しかし、それはかなり不自由なようです。

4

3 に答える 3

4

ブルートフォースソリューション

最初に、たまたますべての順列であるルール 1 に基づいて、可能なすべての入力を作成します。

val all = (1 to 3).permutations

次に、残りのルールを定義します。

val rule2 = (a: Int, b: Int, c: Int) => b < 2
val rule3 = (a: Int, b: Int, c: Int) => c > 2

そして、すべてのルールに一致しないソリューションを除外するだけです。

val solutions = all.
  filter(i => rule2(i(0), i(1), i(2))).
  filter(i => rule3(i(0), i(1), i(2))).
  toList

solutions.toList唯一の有効なソリューションを出力します。

List(Vector(2, 1, 3))

順列は遅延して生成されるため、この実装はそれほど効果的ではないことに注意してください (たとえばrule3、 に合格したソリューションにのみ適用されますrule2)。

foldLeft()任意の数の述語を適用するために使用できます。

val rules = List(rule2, rule3)

rules.
  foldLeft(all)((solutionsSoFar, rule) => 
    solutionsSoFar.filter(s => 
      rule(s(0), s(1), s(2))
    )
  )

よだれ

Droolsビジネス・ルール・エンジンを見てください。考えられるすべてのソリューションをナレッジ ベースとして配置し、Nice DSL を使用してルールを定義するだけです。

于 2012-05-14T06:56:43.333 に答える
3

これは制約の仕事です。Javaにはいくつかの制約ソルバーがあります。私のお気に入りはJaCoPです。それには素晴らしいscalaDSLがあるので、Prologの制約のように見えます。典型的なSENDMOREMONEYの例を次に示します。http://www.hakank.org/jacop/SendMoreMoney.scala

于 2012-05-14T07:14:27.483 に答える
2

著者が 3 部構成の記事で Scala でロジック プログラミングを行う方法を示しているこのブログに興味があるかもしれません。

http://ambassadortothecomputers.blogspot.com/feeds/posts/default?alt=rss

于 2012-05-14T19:26:34.910 に答える