2016-04-16 7 views
1

我々は以下の表を介して関係matchesを定義するとします。これにより単純なマッチング機能を行うためにcore.logic使用

|-----+-----+-----+-----+-----| 
|  | *A* | *B* | *C* | *D* | 
|-----+-----+-----+-----+-----| 
| *A* |  | X | X |  | 
|-----+-----+-----+-----+-----| 
| *B* | X |  |  | X | 
|-----+-----+-----+-----+-----| 
| *C* | X |  |  |  | 
|-----+-----+-----+-----+-----| 
| *D* |  | X |  |  | 
|-----+-----+-----+-----+-----| 

、それはその(pseduoコードで)

(matches A) ;=> (B C) 
(matches B) ;=> (A D) 
(matches C) ;=> (C) 
(matches D) ;=> (B) 
意味しますcore.logicで

は、私がmatchesの挙動を近似することができ、個別の機能を作成する方法を知っているだろうと思う:

(defn matches-A 
    (run* [q] 
    (membero q [B C]))) ;=> (B C) 

... matches-Bおよびmatches-Cについては、

質問:私は一般化可能性がどのように、すなわち、単一の関数として上記matchesからmatches-A?特に、(matches "not A"),(matches "B and C")(matches "C or D")(擬似コード)のようなクエリを実行して、(A D),(A)、および(A B)のようなクエリを実行できるようにすることに興味があります。これは可能ですか?

注:私はclojureの代わりにclojurescriptを使用しています。それが答えに全く影響しないかどうかは分かりません。

(ns qradv.welcome 
    (:require [cljs.core.logic :as l])) 

;; |-----+-----+-----+-----+-----| 
;; |  | *A* | *B* | *C* | *D* | 
;; |-----+-----+-----+-----+-----| 
;; | *A* |  | X | X |  | 
;; |-----+-----+-----+-----+-----| 
;; | *B* | X |  |  | X | 
;; |-----+-----+-----+-----+-----| 
;; | *C* | X |  |  |  | 
;; |-----+-----+-----+-----+-----| 
;; | *D* |  | X |  |  | 
;; |-----+-----+-----+-----+-----| 
(defn matches [x] 
    (l/run* [y] 
    (l/conde 
     [(l/== x "A") (l/membero y ["B" "C"])] 
     [(l/== x "B") (l/membero y ["A" "D"])] 
     [(l/== x "C") (l/membero y ["C"])] 
     [(l/== x "D") (l/membero y ["B"])]))) 

(prn (matches "A")) 
(prn (matches "B")) 
(prn (matches "C")) 
(prn (matches "D")) 

出力:

答えて

2

このタスク解決するためにcondeを使用することができます

("B" "C") 
("A" "D") 
("C") 
("B") 
+0

をこの関数に論理的な引数を埋め込む方法はあります( "AとB" または「ないCのような"など)? – George

+0

@George「not C」をどのように使いたいかわかりません。テーブルを記述する例を追加できますか? – edbond

+0

良い点 - あいまいな意味を持っています。すなわち、「not C」は、「(B C D)」を意味する。つまり、私はCの補数と一致するものの集合ではなく、Cと一致するものの補数を意味します。 – George

関連する問題