¿Existe una forma extensible y eficiente de escribir enunciados existenciales en Haskell sin implementar un lenguaje de programación lógica integrado? A menudo, cuando estoy poniendo en práctica algoritmos, quiero expresar declaraciones de primer orden existencialmente cuantificados comobúsqueda existencial y consulta sin el alboroto
∃x.∃y.x,y ∈ xs ∧ x ≠ y ∧ p x y
donde ∈
está sobrecargado en las listas. Si estoy en un apuro, podría escribir código perspicaz que se parece a
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]
Pero este enfoque no generaliza así a las preguntas valores o predicados o funciones de múltiples arities regresar . Por ejemplo, incluso una declaración simple como
∃x.∃y.x,y,z ∈ xs ∧ x ≠ y ≠ z ∧ f x y z = g x y z
requiere escribir otro procedimiento de búsqueda. Y esto significa una cantidad considerable de código repetitivo. Por supuesto, lenguajes como Curry
o Prolog
que implementan estrechamiento o un motor de resolución permiten al programador escribir frases como:
find(p,xs,z) = x ∈ xs & y ∈ xs & x =/= y & f x y =:= g x y =:= z
abusar de la notación considerablemente, lo que lleva a cabo tanto una búsqueda y devuelve un valor. Este problema surge a menudo cuando se implementan algoritmos formalmente especificados, y a menudo se resuelve mediante combinaciones de funciones como fmap
, foldr
y mapAccum
, pero en su mayoría recursividad explícita. ¿Hay alguna manera más general y eficiente, o simplemente general y expresiva, de escribir código como este en Haskell?
Sospecho que http://hackage.haskell.org/package/logict es lo que estás buscando. –