The following Clojure code utilizza core.logic
per risolvere lo stesso problema logico con gli stessi obiettivi in due ordini diversi. Questa scelta di ordini fa sì che uno finisca rapidamente e l'altro si blocchi.L'ordinamento degli obiettivi in `core.logic` di Clojure
(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]))))
Esiste una soluzione generale o una pratica comune per evitare questo problema?
Che cos'è esattamente la ricerca in '(membero q x)'? X sta effettivamente iterando tra tutte le possibili raccolte? Quali calcoli si verificano mentre si blocca? – MRocklin
@MRocklin, esattamente. Infatti, se si immagina il codice per 'membero', tenterà di unificare l'elemento con una lista con solo quell'elemento, e quindi di creare in modo ricorsivo gli elenchi che contengono l'elemento in qualsiasi posizione fino all'infinito. In teoria, l'ordinamento dei fatti non è necessario, ma è conveniente limitare l'albero di ricerca. –