2016-09-03 7 views
1

나는 모델링 문제에 당분간 당황 스러웠다. 나는 어떻게 내가 "적절하게"그것을 core.logic에서 해결할 수 있을지 전혀 모르겠다 고 고백해야한다.Clojure에서 트리 검색 core.logic

트리 (비순환 단 향성 그래프)와 정점이있는 경우, core.logic을 사용하면 lvar가 주어진 정점의 도달 가능한 정점이 될 수있는 목표를 어떻게 정의 할 수 있습니까?

나는 가능한 한 간단하게 뭔가 시작했습니다

(defrel vertex x) 
(defrel child) 
(def facts 
    (pldb/db 
    [vertex 'a] 
    [vertex 'b] [child 'a 'b] 
    [vertex 'c] [child 'b 'c] 
    [vertex 'd] [child 'c 'd])) 

이 구성을 감안할 때, 나는 lvar가 [ 'A'B 'C'D의 값을 가질 수 있도록하는 목표를 정의하는 목표 ]. 그것은 "1 홉"에 도달 정점을 얻을 간단합니다 ...

(defn reachableo 
    [a] 
    (fresh [q] 
    (child a q))) 

하고 2 홉에 대한 변수를 추가 등등 수 있지만, 그것은 일반화 될 수 있는가? 나는 내가 갈 수있는 올바른 방법 확실하지 않다 고백해야, 나중에

(let [vars (repeatedly lvar)] 
    (map #(child (nth vars %) (nth vars (inc %))) 
     (-> vars count dec range)) 
    (all 
    ...)) 

하지만 여러 번 시도처럼 뭔가 lvar의 목록을 정의 할 생각했습니다.

답변

0
(pldb/db-rel vertex x) 
(pldb/db-rel child parent child) 
(def facts 
    (pldb/db 
    [vertex 'a] 
    [vertex 'b] [child 'a 'b] 
    [vertex 'c] [child 'b 'c] 
    [vertex 'd] [child 'c 'd])) 

재귀 목표 :

(defn reachable° [from to] 
    (l/fresh [v] 
    (l/conde 
     [(child from to)] 
     [(child from v) (reachable° v to)]))) 

테스트

=> (pldb/with-db facts 
    (vec (l/run* [to] (reachable° 'a to)))) 
[b c d] 
도와
0

감사합니다!

사실 나는 내가 로직 프로그래밍 연습을하지 않은 오랜 시간 이었기 때문에 나는이 질문을

(defn order-relationo 
    "Abstract the general pattern of a order relation in a logic, relational way." 
    [relation x y] 
    (conde 
    [(relation x y)] 
    [(fresh [z] 
     (relation x z) 
     (order-relationo relation z y))])) 

(def kino 
    "A goal where the two inputs x and y share kinship: x is an ancestor of y and 
    y a descandant of x." 
    (partial order-relationo child)) 

가지고 있지만 지금은 감사에게, 다시 오는 어쨌든

를 ^^있어 많은에 대한 느낌 당신의 대답은 저에게 추가적인 관점을 제공합니다.