conda, condi, conde, condu
Estoy leyendoel Intrigante Razonado .
Tengo cierta intuición sobre cómo funciona conde
.
Sin Embargo, no puedo encontrar una definición formal de lo que conde
/conda
/condu
/condi
hacer.
Soy consciente de https://www.cs.indiana.edu/~webyrd / pero eso parece tener ejemplos en lugar de definiciones.
¿Existe una definición formal de conde
, conda
, condi
, condu
¿en alguna parte?
3 answers
En Prolog de los términos, condA
es "suave corte", *->
, y condU
es "comprometidos opción" – una combinación de once
y un suave corte, de modo que (once(A) *-> B ; false)
expresa la cortar en (A, !, B)
:
A *-> B ; C %% soft cut, condA
once(A) *-> B ; C %% committed choice, condU
En condA
, si el objetivo A
tiene éxito, todas las soluciones pasan a la primera cláusula B
y no hay alternativa cláusulas C
son juzgados. once/1
permite que su objetivo de argumento tenga éxito solo una vez (mantiene solo uno solución, en su caso).
condE
es un simple disyunción, y condI
es una disyunción que se alterna entre las soluciones de sus mandantes.
Aquí hay un intento de traducir fielmente el código del libro, sin variables lógicas y unificación, en 18 líneas de Haskell (donde la yuxtaposición es aplicación de función curry, y :
significa cons). Ver si esto aclara las cosas:
- Combinación de flujo secuencial ("
mplus
" del libro):
(1) [] ++: ys = ys
(2) (x:xs) ++: ys = x:(xs ++: ys)
- Combinación de corriente alterna("
mplusI
"):
(3) [] ++/ ys = ys
(4) (x:xs) ++/ ys = x:(ys ++/ xs)
- Alimentación secuencial("
bind
"):
(5) [] >>: g = []
(6) (x:xs) >>: g = g x ++: (xs >>: g)
- Alimentación alterna ("
bindI
"):
(7) [] >>/ g = []
(8) (x:xs) >>/ g = g x ++/ (xs >>/ g)
- "
OR
" meta combinación ("condE
"):
(9) (f ||: g) x = f x ++: g x
- "Alternando
OR
" combinación de goles ("condI
"):
(10) (f ||/ g) x = f x ++/ g x
- "
AND
" combinación de goles("all
"):
(11) (f &&: g) x = f x >>: g
- "Alternando
AND
," objetivo " combinación ("allI
" del libro):
(12) (f &&/ g) x = f x >>/ g
- Objetivos especiales
(13) true x = [x] -- a sigleton list with the same solution repackaged
(14) false x = [] -- an empty list, meaning the solution is rejected
Los objetivos producen flujos (posiblemente vacíos) de soluciones (posiblemente actualizadas), dada una solución (posiblemente parcial) a un problema.
Reescribir reglas para all
son:
(all) = true
(all g1) = g1
(all g1 g2 g3 ...) = (\x -> g1 x >>: (all g2 g3 ...))
=== g1 &&: (g2 &&: (g3 &&: ... ))
(allI g1 g2 g3 ...) = (\x -> g1 x >>/ (allI g2 g3 ...))
=== g1 &&/ (g2 &&/ (g3 &&/ ... ))
Reescribir reglas para condX
son:
(condX) = false
(condX (else g1 g2 ...)) = (all g1 g2 ...) === g1 &&: (g2 &&: (...))
(condX (g1 g2 ...)) = (all g1 g2 ...) === g1 &&: (g2 &&: (...))
(condX (g1 g2 ...) (h1 h2 ...) ...) =
(ifX g1 (all g2 ...) (ifX h1 (all h2 ...) (...) ))
Para llegar a la final condE
y condI
's traducción, no hay necesidad de implementar el libro de ifE
y ifI
, dado que se reducen aún más a combinaciones de operadores simples, con todos los operadores considerados como asociativos por derecho :
(condE (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ... ) ||: (h1 &&: h2 &&: ...) ||: ...
(condI (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ... ) ||/ (h1 &&: h2 &&: ...) ||/ ...
Así que no hay necesidad de ninguna "sintaxis" especial en Haskell, los operadores simples son suficientes. Cualquier se puede usar la combinación, con &&/
en lugar de &&:
si es necesario. Pero OTOH condI
también se podría implementar como una función para aceptar una colección(lista, árbol, etc.) de los objetivos a cumplir, que utilizaría alguna estrategia inteligente para elegir de ellos uno más probable o más necesario, etc, y no solo la simple alternancia binaria como en ||/
operador( o ifI
del libro).
A continuación, el librocondA
puede ser modelado por dos nuevos operadores, ~~>
y ||~
, trabajando junto. Podemos usarlos de una manera natural como en, por ejemplo,
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ... ||~ gelse
Que se puede leer intuitivamente como " IF g1 THEN g2 AND ... OR-ELSE IF h1 THEN ... OR-ELSE gelse
".
- "
IF-THEN
" la combinación de objetivos es producir un objetivo " try " que debe ser llamado con un objetivo de fracaso-continuación:
(15) (g ~~> h) f x = case g x of [] -> f x ; ys -> ys >>: h
- "
OR-ELSE
" la combinación de un objetivo " try " y un objetivo simple simplemente llama a su objetivo "try" con un segundo objetivo en caso de fallo, por lo que no es más que una sintaxis conveniente para la agrupación automática de operandos:
(16) (g ||~ f) x = g f x
Si el ||~
"OR-ELSE
" al operador se le da menos poder vinculante que el ~~>
"IF-THEN
" operador y hecho derecho-asociativo también, y ~~>
operador tiene todavía menos poder vinculante que &&:
y el similar, agrupación sensible del ejemplo anterior se produce automáticamente como
(g1 ~~> (g2 &&: ...)) ||~ ( (h1 ~~> (h2 &&: ...)) ||~ (... ||~ gelse)...)
El último gol en una cadena ||~
debe ser, por lo tanto, un objetivo simple. Eso no es ninguna limitación realmente, desde la última cláusula de condA
forma es equivalente de todos modos a simple "AND
" - combinación de sus objetivos (o simple false
se puede usar igual de bien).
Eso es todo. Incluso podemos tener más tipos de try-goals, representados por diferentes tipos de operadores " IF
", si queremos:
- use alimentación alterna en una cláusula exitosa (para modelar lo que podría haberse llamado
condAI
, si hubiera uno en el libro):
(17) (g ~~>/ h) f x = case g x of [] -> f x ; ys -> ys >>/ h
- use el flujo de solución exitosa solo una vez para producir el corte efecto, para modelar
condU
:
(18) (g ~~>! h) f x = case g x of [] -> f x ; (y:_) -> h y
Para que, finalmente, las reglas de reescritura para condA
y condU
del libro son simplemente:
(condA (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ...
(condU (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~>! g2 &&: ... ||~ h1 ~~>! h2 &&: ... ||~ ...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-10 06:33:36
El Conspirador Razonado cubre conda (corte suave) y condu (elección comprometida). También encontrarás explicaciones de su comportamiento en la excelente disertación de William Byrd sobre miniKanren . Has etiquetado este post como acerca de core.lógica. Para ser claro núcleo.la lógica se basa en una versión más reciente de miniKanren que la presentada en el Razonada de Mediapunta. miniKanren es siempre interleaves objetivos disyuntivos - condi y las variantes de interleaving ya no existir. conde es condi ahora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 12:34:35
Por Ejemplo, usando core.lógica:
Conde ejecutará cada grupo, tendrá éxito si al menos un grupo tiene éxito, y devolverá todos los resultados de todos los grupos exitosos.
user> (run* [w q]
(conde [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([_0 :second] [1 :first] [2 :first])
Conda y condu: ambos se detendrán después del primer grupo exitoso(de arriba a abajo)
Conda devuelve todos los resultados del primer grupo exitoso.
user> (run* [w q]
(conda [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first] [2 :first])
Condu devuelve solo un resultado del primer grupo exitoso.
user> (run* [w q]
(condu [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first])
No tengo idea de lo que condi lo hace sin embargo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-31 18:08:05