The following Clojure code używa core.logic
do rozwiązania tego samego problemu logicznego z tymi samymi celami w dwóch różnych zamówieniach. Ten wybór uporządkowania powoduje szybkie zakończenie, a drugi zawieszenie.Zamawianie celu w 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]))))
Czy istnieje ogólne rozwiązanie lub powszechna praktyka, aby uniknąć tego problemu?
Co dokładnie szuka w '(membero q x)'? Czy X rzeczywiście jest iteracją wśród wszystkich możliwych kolekcji? Jakie obliczenia występują, gdy się zawiesi? – MRocklin
@MRocklin, dokładnie. W rzeczywistości, jeśli wyobrazisz sobie kod dla 'membero', spróbuje zunifikować element z listą z tym elementem, a następnie rekurencyjnie zbudować listy, które zawierają element w dowolnej pozycji do nieskończoności. Teoretycznie uporządkowanie faktów nie jest potrzebne, ale wygodnie jest ograniczyć drzewo wyszukiwania. –