Skip to content

Commit

Permalink
Add are-inequal! constraint
Browse files Browse the repository at this point in the history
relates #135
  • Loading branch information
tuturto committed Nov 8, 2015
1 parent ff61576 commit e275352
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 30 deletions.
19 changes: 10 additions & 9 deletions src/pyherc/solver.hy
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@
false
(if (= new-values variable.values)
true
(do (.append (:variable-stack context) variable)
(.append (:value-stack context) variable.values)
(setv variable.last-save-frame-pointer (:frame-pointer context))
(do (save context variable)
(setv variable.values new-values)
(all (genexpr (constraint context variable)
[constraint variable.constraints])))))))
Expand All @@ -78,14 +76,21 @@
(let [[var (.pop (:variable-stack context))]
[vals (.pop (:value-stack context))]]
(setv var.values vals)))
(setv (:frame-pointer context) frame-pointer))
(assoc context :frame-pointer frame-pointer))

(fact are-equal!
"equality constraint"
(if (= updated-variable var1)
(narrow context var2 updated-variable.values)
(narrow context var1 updated-variable.values)))

(fact are-inequal!
"inequality constraint"
(when (value? var1)
(narrow context var2 (^ var1.values var2.values)))
(when (value? var2)
(narrow context var1 (^ var1.values var2.values))))

(defn solve [&rest variables]
"solve all variables"
(let [[context {:frame-pointer nil
Expand All @@ -110,11 +115,7 @@
(assert false))))
false))
(when (not (:solved context))
(while (!= (len (:variable-stack context)) frame)
(let [[var (.pop (:variable-stack context))]
[val (.pop (:value-stack context))]]
(setv var.values val)))
(assoc context :frame-pointer frame))))
(restore-values context variable frame))))
(when (:solved context)
variables))))

Expand Down
38 changes: 17 additions & 21 deletions src/pyherc/test/unit/test_solver.hy
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
;; You should have received a copy of the GNU General Public License
;; along with pyherc. If not, see <http://www.gnu.org/licenses/>.

(import [pyherc.solver [Variable are-equal! solve solve-one value]]
[hamcrest [assert-that is- equal-to]])
(import [pyherc.solver [Variable are-equal! are-inequal! solve solve-one value]]
[hamcrest [assert-that is- equal-to is-not :as is-not-]])

(defn context []
"create an empty context for testing"
Expand All @@ -35,28 +35,24 @@
(solve var₁ var₂)
(assert-that (value var₁) (is- (equal-to (value var₂))))))

(defn test-are-equal []
"applying equality will narrow down correctly"
(let [[var₁ (Variable 1)]
(defn test-simple-inequality []
"inequal variables have different values"
(let [[var₁ (Variable 1 2 3)]
[var₂ (Variable 1 2 3)]]
(are-equal! var₁ var₂)
((first var₁.constraints) (context) var₁)
(assert-that (value var₁) (is- (equal-to (value var₂))))))

(defn test-not-equal-results-false []
"narrow non-equals with equality will return false"
(let [[var₁ (Variable 1)]
[var₂ (Variable 2 3)]]
(are-equal! var₁ var₂)
(assert-that ((first var₁.constraints) (context) var₁) (is- (equal-to false)))))
(are-inequal! var₁ var₂)
(solve var₁ var₂)
(assert-that (value var₁) (is-not- (equal-to (value var₂))))))

(defn test-easy-narrow []
"two variables with same domains and equality constraint are narrowed down"
(let [[var₁ (Variable 1 2)]
[var₂ (Variable 1 2)]]
(defn test-multiple-constraints []
"variables with multiple constraints can be solved"
(let [[var₁ (Variable 1 2 3 4 5)]
[var₂ (Variable 1 2 3 4 5)]
[var₃ (Variable 1 2 3 4 5)]]
(are-equal! var₁ var₂)
(solve var₁ var₂)
(assert-that (value var₁) (is- (equal-to (value var₂))))))
(are-inequal! var₁ var₃)
(solve var₁ var₂ var₃)
(assert-that (value var₁) (is- (equal-to (value var₂))))
(assert-that (value var₁) (is-not- (equal-to (value var₃))))))

(defn test-single-value-left []
"when variables have single value left, they are reported"
Expand Down

0 comments on commit e275352

Please sign in to comment.