Nunca me he encontrado con tal cosa, y acabo de tener un aspecto más detallado.
Existe una razón de cálculo de sonido para no implementar esto de forma predeterminada - uno tiene que generar esencialmente todas las combinaciones de la entrada antes de la coincidencia de patrones, o tiene que generar las cláusulas de match of match.
Sospecho que la forma habitual de implementar esto sería simplemente escribir ambos patrones (en el caso binario), es decir, tener patrones para C or $X
y $X or C
.
Dependiendo de la organización subyacente de los datos (generalmente son tuplas), esta coincidencia de patrones implicaría reordenar el orden de los elementos de tupla, lo que sería extraño (¡especialmente en un entorno fuertemente tipado!). Si se trata de listas, entonces estás en un terreno aún más inestable.
Por cierto, sospecho que la operación que quiere es fundamentalmente patrones de unión de la desunión en conjuntos, por ejemplo:
foo (Or ({C} disjointUnion {X})) = ...
El único entorno de programación que he visto que se ocupa de conjuntos en detalle sería Isabelle/HOL , y todavía no estoy seguro de que puedas construir coincidencias de patrones sobre ellos.
EDIT: Parece que la funcionalidad de Isabelle function
(en lugar de fun
) le permitirá definir patrones no constructor complejos, excepto entonces usted tiene que demostrar que se utilizan constantemente, y no se puede utilizar el generador de código más.
EDIT 2: La forma en que he implementado una funcionalidad similar sobre n
operadores conmutativa, asociativa y transitivos era la siguiente:
Mis términos eran de la forma A | B | C | D
, mientras que las consultas eran de la forma B | C | $X
, donde $X
fue permitida para que coincida cero o más cosas. Pre-ordené estos usando el orden lexicográfico, de modo que las variables siempre ocurrieron en la última posición.
En primer lugar, construyes todas las coincidencias por pares, ignorando las variables por ahora, y registrando las que coinciden de acuerdo con tus reglas.
{ (B,B), (C,C) }
Si se trata esto como un grafo bipartito, entonces usted está haciendo esencialmente un problema perfect marriage. Existen algoritmos rápidos para encontrarlos.
Suponiendo que encuentre uno, a continuación, se reúnen todo lo que no aparece en el lado izquierdo de su relación (en este ejemplo, A
y D
), y los mete en la variable $X
, y su partido se completar. Obviamente, puede fallar en cualquier etapa aquí, pero esto ocurrirá mayormente si no hay una variable libre en el RHS, o si existe un constructor en el LHS que no coincida con nada (evitando que encuentre una combinación perfecta).
Lo siento si esto es un poco confuso. Ha pasado un tiempo desde que escribí este código, pero espero que esto te ayude, ¡incluso un poco!
Para el registro, este podría no ser un buen enfoque en todos los casos. Tenía nociones muy complejas de 'coincidencia' en los subtítulos (es decir, no simple igualdad), por lo que construir conjuntos o cualquier cosa no habría funcionado. Tal vez eso funcione en su caso y usted puede calcular uniones disjuntas directamente.
no estoy seguro estoy de acuerdo con su fusión de Prolog coincidencia de patrones vs ML coincidencia de patrones. La coincidencia de patrones ML es puramente sintáctica, y en Prolog no creo que este sea el caso. – Gian
No digo que sean lo mismo, solo que tienen en común la comparación de elementos en orden estricto. – rwallace
Supongo que el software de prueba de teoremas dedicado como Otter ya lo hace colocando fórmulas lógicas en una forma normal y tratando las cláusulas como estructuras de datos establecidas, lo que cuesta O (n log n) tiempo para la creación y la verificación. De hecho, supongo que tienen optimizaciones preprogramadas para las operaciones de propiedades como la asociatividad y la conmutatividad. –