Hendekagon
Hendekagon

Reputation: 4643

Refactoring with core.logic

I've started learning core.logic and I'm totally lost. I am trying to write a core.logic relation which refactors an expression, renaming symbols. I want a relation that returns for a given expression, list of symbols and a list of symbols to rename those symbols:

(defn rename [exp from to]...

the expression with all the symbols in from becoming the corresponding one in to:

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

returns (defn multiply [a b] (* a b))

but it needs to be aware of scope,

so (rename '(defn q [x] ((fn [x] (* x 5)) x)) [x] [a])

would return (defn q [a] ((fn [x] (* x 5)) a))

I don't know where to start solving this - any hints would be greatly appreciated!

Upvotes: 0

Views: 186

Answers (1)

Ankur
Ankur

Reputation: 33637

This problem is more suitable for FP as it is just a tree traversal and replace operation, where as LP is more about specifying constrains and asking all possible solution around those constrains for a specific input. But if you really want to do this logical way, I tried something that does try to do it LP way but it doesn't handle a lot of cases and is just a starting point.

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

Upvotes: 2

Related Questions