ExKanren icon indicating copy to clipboard operation
ExKanren copied to clipboard

Evaluate functions completely in conda/condu

Open dewyze opened this issue 7 years ago • 0 comments

The current behavior in ExKanren is that if a function is passed to the first clause of a conda/condu block, it would seem that as long as the first sub-clause of that function is successful, the conda/condu will consider that line "successful" and follow that path.

It is unclear in the "Thin Ice" chapter of The Reasoned Schemer if that is the desired behavior. However, when looking at clojure's core.logic library, it would seem the function should be evaluated completely.

(ns ex-kanren
  #_=>   (:refer-clojure :exclude [==])
  #_=>   (:require [clojure.core.logic :refer :all]))

(defn latefail []
  #_=> (== 1 1)
  #_=> (conda
         #_=> [(== 1 2)]
         #_=> [(== 1 3)]
         #_=> ))

(run* [x]
      #_=> (conda
             #_=> [(latefail) (== x 0)]
             #_=> [(== 1 1) (== x 1)]
             #_=> )
      #_=> )

=> (1)

Current ExKanren behavior:

use MiniKanren
alias MiniKanren, as: MK

latefail = fn() ->
  eq(1, 1)
  conda do
    [eq(1,2)]
  end
end

MK.run_all([x]) do
  conda do
    [latefail.(), eq(x, 0)]
    [eq(1,1), eq(x, 1)]
  end
end

=> []

In the above, since the first statement of latefil eq(1,1) succeeds, it continues on but will fail and ultimately not bind x to 0.

Suggested ExKanren behavior:

use MiniKanren
alias MiniKanren, as: MK

latefail = fn() ->
  eq(1, 1)
  conda do
    [eq(1,2)]
  end
end

MK.run_all([x]) do
  conda do
    [latefail.(), eq(x, 0)]
    [eq(1,1), eq(x, 1)]
  end
end

=> [1]

The failure of the latefail method should ultimately moved the conda into the second sequence with eq(1,1) succeeding and assigning x to 1.

Admittedly, I am not sure if there are side effects in the way I implemented the change, but I have not seen any yet.

dewyze avatar Oct 13 '17 19:10 dewyze