Esiste un modo estensibile ed efficiente per scrivere istruzioni esistenziali in Haskell senza implementare un linguaggio di programmazione logica incorporato? Spesso quando sono algoritmi di attuazione, voglio esprimere esistenzialmente quantificati dichiarazioni del primo ordine comericerca e query esistenziali senza problemi
∃x.∃y.x,y ∈ xs ∧ x ≠ y ∧ p x y
dove ∈
è sovraccarico sulle liste. Se sono di fretta, potrei scrivere codice perspicua che assomiglia
find p [] = False
find p (x:xs) = any (\y -> x /= y && (p x y || p y x)) xs || find p xs
o
find p xs = or [ x /= y && (p x y || p y x) | x <- xs, y <- xs]
Ma questo approccio non generalizzare bene alle domande restituzione di valori o predicati o funzioni di più arietà . Ad esempio, anche una semplice istruzione come
∃x.∃y.x,y,z ∈ xs ∧ x ≠ y ≠ z ∧ f x y z = g x y z
richiede la scrittura di un'altra procedura di ricerca. E questo significa una quantità considerevole di codice boilerplate. Naturalmente, linguaggi come Curry
o Prolog
che implementano restringimento o un motore risoluzione consentono al programmatore di scrivere dichiarazioni come:
find(p,xs,z) = x ∈ xs & y ∈ xs & x =/= y & f x y =:= g x y =:= z
di abusare la notazione considerevolmente, che svolge sia una ricerca e restituisce un valore. Questo problema si verifica spesso quando si implementano algoritmi specificati in modo formale, ed è spesso risolto da combinazioni di funzioni come fmap
, foldr
e mapAccum
, ma la ricorsione per lo più esplicita. Esiste un modo più generale ed efficiente, o solo generale ed espressivo, di scrivere codice come questo in Haskell?
Sospetto che http://hackage.haskell.org/package/logict sia quello che stai cercando. –