noprompt / meander

Tools for transparent data transformation
MIT License
921 stars 54 forks source link

rewrite fails when it should succeed #33

Closed timothypratley closed 5 years ago

timothypratley commented 5 years ago

Example:

(def Ω (m/until = (m/bottom-up (m/attempt (m/rewrite
                                            [?a ?b]
                                            [?a]
                                            (?a ?b)
                                            (?a))))))
=> #'justice.translation/Ω
(Ω [1 2])
=> [1]
(Ω '(1 2))
=> (1 2)

However, note that sometimes the 2nd clause does work:

(def Ω (m/until = (m/bottom-up (m/attempt (m/rewrite
                                            [?a ?b]
                                            [?a]
                                            [(?a ?b)]
                                            (?a))))))
=> #'justice.translation/Ω
(Ω ['(1 2)])
=> (1)
noprompt commented 5 years ago

@timothypratley This a bug in the compilation of the find macro which rewrite uses.

(r.match/find '(1 2)
  [?a ?b]
  (r.substitute/substitute [?a])
  (?a ?b)
  (r.substitute/substitute (?a))
  _
  r/*fail*)
;; =>
#meander.delta/fail[]

(r.match/match '(1 2)
  [?a ?b]
  (r.substitute/substitute [?a])
  (?a ?b)
  (r.substitute/substitute (?a))
  _
  r/*fail*)
;; =>
(1)
noprompt commented 5 years ago

Here's the compiled find code which demonstrates the problem.

(let [target__66772 t__66626__auto__]
  (letfn
    [;; [?a ?b]
     (state__66785 []
       (if (vector? target__66772)
         (if (= (count target__66772) 2)
           (let [nth_0__66777 (nth target__66772 0)
                 nth_1__66778 (nth target__66772 1)
                 ?a nth_0__66777
                 ?b nth_1__66778]
             (r.substitute/substitute [?a]))
           (state__66786)) ;; <= Should be 66787.
         (state__66786)))
     (state__66786 [] r/*fail*) ;; <=  Should not be here.
     ;; (?a ?b)
     (state__66787 [] ;; <= Should be called in 66785 .
       (if (seq? target__66772)
         (if (= (bounded-count (inc 2) target__66772) 2)
           (let [nth_0__66783 (nth target__66772 0)
                 nth_1__66784 (nth target__66772 1)
                 ?a nth_0__66783
                 ?b nth_1__66784]
             (r.substitute/substitute (?a)))
           (state__66788))
         (state__66788)))
     (state__66788 [] r/*fail*)]
    (state__66785)))