2016-04-16 3 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-A к одной функции matches, как указано выше? В частности, мне было бы интересно сделать так, чтобы вы могли запускать запросы, такие как (matches "not A"), (matches "B and C") и (matches "C or D") (в псевдокоде) для получения таких результатов, как (A D), (A) и (A B) соответственно. Это возможно?

ПРИМЕЧАНИЕ: Я использую clojurescript вместо clojure. Я не уверен, повлияет ли это на ответ.

ответ

2

Вы можете использовать conde решить эту задачу:

(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")) 

Выход:

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

Есть ли способ, чтобы вставить логические аргументы в эту функцию (например, «А и В» или «не C " и так далее)? – George

+0

@George Я не уверен, как вы хотите использовать «не C». Можете ли вы добавить пример для описания таблицы? – edbond

+0

Хорошая точка - это имеет двусмысленное значение. By - то есть - «не C» я имею в виду «(B C D)». То есть я имею в виду дополнение к тому, что соответствует C (в отличие от совокупности того, что соответствует дополнению C). – George

 Смежные вопросы

  • Нет связанных вопросов^_^