2011-12-01 13 views
5

La coincidencia de patrones (tal como se encuentra en, por ejemplo, Prolog, los lenguajes de la familia ML y varios shells de sistemas expertos) normalmente funciona haciendo coincidir una consulta contra elemento de datos por elemento en orden estricto.Coincidencia de patrones con operadores asociativos y conmutativos

En dominios como la demostración automática de teoremas, sin embargo, es necesario tener en cuenta que algunos operadores son asociativos y conmutativos. Supongamos que tenemos datos

A or B or C 

y consulta

C or $X 

El ir por la sintaxis superficie esto no coincide, pero lógicamente debe coincidir con $X obligado a A or B porque or es asociativa y conmutativa.

¿Existe algún sistema existente, en cualquier idioma, que haga este tipo de cosas?

+0

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

+0

No digo que sean lo mismo, solo que tienen en común la comparación de elementos en orden estricto. – rwallace

+0

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. –

Respuesta

6

La coincidencia de patrón conmutativo asociativo ha existido desde 1981 and earlier, y sigue siendo un tema candente today.

Existen muchos sistemas que implementan esta idea y la hacen útil; significa que puede evitar escribir coincidencias de patrones complicados cuando la asociatividad o la conmutatividad podrían usarse para hacer que el patrón coincida. Sí, puede ser costoso; es mejor que el patrón matcher haga esto automáticamente, que lo haces mal a mano.

Puede ver un ejemplo en un rewrite system for algebra and simple calculus implementado mediante nuestro sistema de transformación de programas. En este ejemplo, el lenguaje simbólico que se procesará está definido por las reglas de la gramática, y las reglas que tienen propiedades A-C están marcadas. Las reescrituras en árboles producidos al analizar el lenguaje simbólico se extienden automáticamente para coincidir.

1

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.

+0

Acepto, mi pensamiento hasta ahora sobre cómo implementar esto es convertir la representación basada en tuplas en una representación de conjunto por adelantado para poder realizar este tipo de consultas de manera razonablemente eficiente. Pensé que valía la pena comprobar para ver si alguien ya había inventado esta rueda en particular primero. – rwallace

+0

Implementé algo similar en un corrector de modelos para bigraphs. La composición paralela para bigraphs es conmutativa, así que tuve que implementar exactamente esta funcionalidad. En su mayoría fue horrible de implementar, debo decir.El código está disponible, pero sospecho que no será útil porque está muy ligado con otro código de coincidencia Bigraph, y es improbable que sea útil reutilizable. Sin embargo, voy a editar mi respuesta para esbozar la forma en que lo implementé. – Gian

+1

¡Gracias! Upvoted; No sé de quién vino el voto vencido. – rwallace

5

El reescritor del término maude implementa la coincidencia de patrones asociativos y conmutativos.

http://maude.cs.uiuc.edu/

+0

¿podría dar un enlace más específico? quizás con un ejemplo de código? –

Cuestiones relacionadas