The following Clojure code verwendet core.logic
, um das gleiche logische Problem mit den gleichen Zielen in zwei verschiedenen Ordnungen zu lösen. Diese Wahl der Reihenfolge bewirkt, dass man schnell fertig wird und der andere hängt.Goal-Bestellung in Clojure `core.logic`
(use `clojure.core.logic)
;; Runs quickly. Prints (1 2 3).
(clojure.pprint/pprint (run* [q] (fresh [x] (== x [1,2,3])
(membero q x))))
;; Hangs
(clojure.pprint/pprint (run* [q] (fresh [x] (membero q x)
(== x [1,2,3]))))
Gibt es eine allgemeine Lösung oder gängige Praxis, um dieses Problem zu vermeiden?
Was genau sucht es in '(membero q x)'? Existiert tatsächlich x unter allen möglichen Kollektionen? Welche Berechnungen treten auf, während es hängt? – MRocklin
@MRocklin, genau. In der Tat, wenn Sie sich den Code für 'membero' vorstellen, wird es versuchen, das Element mit einer Liste nur mit diesem Element zu vereinheitlichen und dann rekursiv Listen zu erstellen, die das Element an jeder Position bis unendlich enthalten. In der Theorie ist die Reihenfolge der Fakten nicht erforderlich, aber es ist praktisch, den Suchbaum zu begrenzen. –