2013-03-03 1 views
0

Я начал изучать core.logic, и я полностью потерян. Я пытаюсь написать отношение core.logic, которое реорганизует выражение, переименование символов. Я хочу, чтобы это отношение, которое возвращает для данного выражения, список символов и список символов, чтобы переименовать эти символы:Рефакторинг с core.logic

(defn rename [exp from to]... 

выражение со всеми символами в стать соответствующий один в к:

e.g. (rename '(defn multiply [x y] (* x y)) [x y] [a b]) 

возвращает (defn multiply [a b] (* a b))

, но она должна быть в курсе сферы,

так (rename '(defn q [x] ((fn [x] (* x 5)) x)) [x] [a])

вернется (defn q [a] ((fn [x] (* x 5)) a))

Я не знаю, с чего начать решение этого - любые намеки бы весьма признателен!

+0

Вам больше не интересна помощь при решении этой проблемы, или с помощью системы core.logic? Я мог бы указать на другое решение. – Ambrose

+0

Я мог бы сделать это функционально, но я хочу посмотреть, как сделать это реляционно, из любопытства - если это не глупый способ сделать это! Любые предложения приветствуются. Правда, попробовав несколько простых упражнений в core.logic, я до сих пор не знаю, как подойти к этой проблеме (которая является реальной проблемой, которую мне нужно решить для того, что я пишу), реляционным способом. Я думал, что это похоже на кандидата на core.logic. – Hendekagon

+1

Вот какой код для гигиенических преобразований. https://github.com/frenchy64/analyze/blob/master/src/analyze/hygienic.clj Нетрудно будет его обновить, чтобы переименовать locals. Это работает на полностью макроэкспонированных формах. Было бы почти невозможно получить правильную работу без полного макрорасширения. – Ambrose

ответ

2

Эта проблема более подходит для FP, поскольку это просто обход дерева и замена операции, где, поскольку LP больше описывает задание ограничений и задает все возможные решения вокруг этих ограничений для конкретного ввода. Но если вы действительно хотите сделать это логично, я попробовал что-то, что пытается сделать это LP, но оно не обрабатывает много случаев и является лишь отправной точкой.

(defrel replace-with a b) 
(fact replace-with 'x 'a) 
(fact replace-with 'y 'b) 

(defn replace [a b] 
    (conde 
    [(replace-with a b)] 
    [(== a b)])) 


(defn replace-list [from to] 
    (conde 
    [(== from []) (== to [])] 
    [(fresh [f t f-rest t-rest] 
      (resto from f-rest) 
      (resto to t-rest) 
      (firsto from f) (firsto to t) 
      (conda [(replace-list f t)] 
        [(replace f t)]) 
      (replace-list f-rest t-rest))])) 


(first (run 1 [q] 
     (fresh [from] 
     (== from '(defn multiply [x y] (* x y))) 
     (replace-list from q)))) 

==> (defn multiply (a b) (* a b))