¿Cuál es la mejor fue evaluar una expresión como la siguiente:

(A Y B) O (A Y C) O (No B Y C)

(Un && B) || (A && C) || (!B && C)

En tiempo de ejecución, yo estaba pensando en la conversión de las expresiones anteriores, los siguientes:
(Verdadero Y Falso) O (Verdadero Y Falso) O (No Falso Y Verdadero)

(True && False) || (True && False) || (! False && Verdadero)

Condiciones:
1) La expresión lógica es que no se conoce hasta el tiempo de ejecución.
2) El número de variables y sus valores no son conocidos hasta el tiempo de ejecución.
3) los valores de la Variable son nunca null.

Sé que podría crear un sencillo de montar con una clase y un método que puedo generar en tiempo de ejecución basado en las entradas, pero hay una manera mejor.
He hecho esto antes. El uso de un generador de cadenas de escribir el código, a continuación, llamar al compilador. Después de eso, la carga de la asamblea y de la llamada al método.

Sugerencias?

Gracias.

¿Qué estás tratando de lograr? Puedes compartir cómo están llegando a las comparaciones? Esto se ve como algo que podría ser mejor abordado de manera diferente.
Parece una lista de cosas para comparar. Usted puede recorrer la lista, y descanso cuando usted encuentra que cualquiera de las dos son verdaderas.
Se podría escribir un simple Lógica Proposicional analizador… recuerdo que tenía que hacer para solucionar el Wumpus problema del Mundo.

OriginalEl autor Bobby Ortiz | 2008-12-08

8 Comentarios

  1. 7

    Si usted está utilizando .NET3.5 a continuación, puede analizar el texto y crear un resumen sytax árbol mediante la Expresión de las clases. A continuación, cree un adecuado LambdaExpression instancia y se compila en un delegado, que puede ejecutar.

    La construcción de un analizador de sintaxis y árbol generador para este tipo de bastante simple gramática es un ejercicio interesante, y se ejecutará un poco más rápido que el de invocar el compilador (y es más prolijo en mi punto de vista).

    Si no los estás usando .NET3.5, entonces también no complicadas de llevar a cabo una interpretado árbol de sintaxis abstracta uno mismo.

    ¿Podría dar un ejemplo.
    Un enlace o un ejemplo podría ser útil.

    OriginalEl autor Chris

  2. 4

    Ser advertido: las dos últimas condiciones de las que estamos hablando no son necesariamente equivalentes. El && operadores en C# uso a corto-circuito evalution, mientras que la lógica And operador en VB no. Si usted quiere estar seguro de que las declaraciones son equivalentes, traducir un usuario And a AndAlso y un usuario Or a OrElse.

    Por simple expresssions probablemente no notará la diferencia. Pero si las condiciones pueden tener efectos secundarios o si la diferencia de rendimiento entre los dos es una preocupación, esto puede ser importante.

    Independientemente de que sean o no de corto circuito, el resultado de la expresión es la misma. La única diferencia es que cuando a,B,C son funciones y los cortocircuitos efectos si son o no la llamada, que no afecta el resultado final de la expresión.
    pero podría afectar el resultado final de la sistema si los efectos secundarios son los involucrados.

    OriginalEl autor Joel Coehoorn

  3. 3

    Usted puede hacer esto fácilmente con:

    1. un parser generator (como ANTLR, mencionado arriba) que se lleva a expresiones booleanas como entrada y produce un infijo lista y
    2. código para evaluar una Notación polaca Inversa de la pila.

    La gramática se ve algo como esto:

    program: exprList ;
    
    exprList: expr { Append($1); }
        | expr OR exprList { Append(OR); }
        | expr AND exprList { Append(AND); }
        | NOT exprList { Append(NOT); }
        | ( exprList ) { /* Do nothing */ }
        ;
    
    expr: var { Append($1); }
        | TRUE { Append(True); }
        | FALSE { Append(False); }
        ;

    Para evaluar, hacer esto:

    for each item in list
        if item is symbol or truth value, push onto RPN stack
        else if item is AND, push (pop() AND pop())
        else if item is OR, push (pop() OR pop())
        else if item is NOT, push (NOT pop())
    
    result = pop()

    De los símbolos, usted tiene que sustituir el valor de verdad en tiempo de ejecución.

    OriginalEl autor hughdbrown

  4. 3

    Puede utilizar https://github.com/mrazekv/logicalparser

    Simplemente biblioteca para escribir la expresión lógica (evaulated con precenednce tabla, permite O NO, y el operador Y >, >=, <=, < sobre variables de tipo integer y = en las variables de cadena)

    OriginalEl autor Vojta

  5. 0

    Puede escribir un simple intérprete/parser. Usar algo como ANTLR y reutilizar las existentes gramáticas.

    OriginalEl autor Eugene Yokota

  6. 0

    Si usted está utilizando .NET 3.5, puede crear una Expresión Lambda. A continuación, puede crear un delegado de ella y la llame como estándar delegado/método.
    En el internet es una gran cantidad de muestras sobre las Expresiones Lambda.

    OriginalEl autor TcKs

  7. 0

    Esto no va a ser la mejor respuesta, pero yo mismo tuve este problema hace algún tiempo.

    Aquí está mi código antiguo:
    VB.Net – no hay garantía en todos!

    https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB

    Dim BoolTermParseObjekt As New BoolTermParse
    MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)

    Este código se come una Cadena con múltiples ‘(‘, ‘)’, ‘y’, ‘o’ plus ‘otras cosas’ y rompe la lógica booleana mediante la sustitución de las cosas con valores booleanos.
    por lo tanto:

    Lo ‘otras cosas’ yo quería evaluar tuve que poner en Función de resolveTerm()
    en el comentario “‘funktionen ausführen und zurückgeben, einzelwert!”
    en la página 2.
    Allí la única evaluación rightnow es “Si el número es > 1”

    Saludos

    OriginalEl autor Nibbels

  8. -1

    Una solución sería montar la expresión como una cadena y, a continuación, enviar de SQL Server, o cualquiera que sea tu base de datos para la evaluación. Reemplazar las variables reales con 1=1 or 0=1 para Verdadero y Falso respectivamente, y que terminaría con una consulta como esta:

    SELECCIONE 1 DONDE (1=1 Y 0=1) O (1=1 Y 1=1) O (No 0=1 Y 1=1)

    Luego al ejecutar la consulta, se obtiene un 1 cuando el resultado es true. Puede no ser la solución más elegante, pero funciona. Un montón de gente que probablemente le aconsejará en contra de esto, pero me voy a tirar por ahí como una posible solución, de todos modos.

    -1: no animo a la gente a escribir hacks como este, en particular en el código de liberación.
    Es una idea interesante. Usted puede hacer pivotar más fácil mediante el uso de la versión incorporada de sql server, en lugar de confiar en una instalación completa. A veces hacks como este puede salvar tu culo. +1

    OriginalEl autor Kibbee

Dejar respuesta

Please enter your comment!
Please enter your name here