Exemple #1
0
        protected IEnumerable <Proposition> ConvertFromAST(AST ast, Language.Symbol oper)
        {
            if (ast == null)
            {
                return(null);
            }

            List <Proposition> result = new List <Proposition>();
            string             type   = ast.GetType().Name;

            if (type == "ASTOpBinary")
            {
                ASTOpBinary opBin = ast as ASTOpBinary;
                if (opBin.value == oper)
                {
                    result.AddRange(ConvertFromAST(opBin.left, oper));
                    result.AddRange(ConvertFromAST(opBin.right, oper));
                    return(result);
                }
            }

            // else
            result.Add(Proposition.FromAST(ast));
            return(result);
        }
Exemple #2
0
 // transitional constructor.
 public MultipleOperation(AST ast, Language.Symbol oper = Language.Symbol.INVALIDO)
 {
     if (oper == Language.Symbol.INVALIDO && ast.GetType().Name == "ASTOpBinary")
     {
         oper = (ast as ASTOpBinary).value;
     }
     m_props = new List <Proposition>(ConvertFromAST(ast, oper));
 }
Exemple #3
0
        }  // Extractor class

        #endregion Inner classes

        #region Public functions

        /// <summary>
        /// Convert the formula to conjuntive normal form.
        /// </summary>
        /// <param name="ast">original abstract syntatic tree representinf the formula.</param>
        /// <returns>formula in CNF.</returns>
        public static AST Convert(AST ast)
        {
            if (ast == null)
            {
                return(ast);
            }

            switch (ast.GetType().Name)
            {
            case "ASTProp":
                return(ast);

            case "ASTOpBinary":
                ASTOpBinary opBin = ast as ASTOpBinary;
                switch (opBin.value)
                {
                case Language.Symbol.E:                 // Form (P&Q).
                    AST left  = Convert(opBin.left);
                    AST right = Convert(opBin.right);
                    return(new ASTOpBinary(left, right, Language.Symbol.E));

                case Language.Symbol.OU:                // Form (P|Q).
                    left  = Convert(opBin.left);
                    right = Convert(opBin.right);
                    return(Distribute(left, right));

                case Language.Symbol.IMPLICA:           // Form (P->Q). Equivalent to (~P|Q)
                    return(Convert(
                               new ASTOpBinary(
                                   new ASTOpUnary(opBin.left, Language.Symbol.NAO),
                                   opBin.right, Language.Symbol.OU)
                               ));

                case Language.Symbol.EQUIVALE:         // Form (P<->Q). Equivalent to (P&Q)|(~P&~Q).
                    left  = new ASTOpBinary(opBin.left, opBin.right, Language.Symbol.E);
                    right = new ASTOpBinary(
                        new ASTOpUnary(opBin.left, Language.Symbol.NAO),
                        new ASTOpUnary(opBin.right, Language.Symbol.NAO),
                        Language.Symbol.E
                        );
                    return(Convert(new ASTOpBinary(left, right, Language.Symbol.OU)));
                }
                break;

            case "ASTOpUnary":
                AST p = (ast as ASTOpUnary).ast;
                switch (p.GetType().Name)
                {
                case "ASTProp":                 // Form ~P ... return ~P
                    return(ast);

                case "ASTOpUnary":              // Form ~(~P) - double negation ... return Convert(P)
                    return(Convert((p as ASTOpUnary).ast));

                case "ASTOpBinary":
                    opBin = (ASTOpBinary)p;
                    Language.Symbol op = opBin.value;
                    if (op != Language.Symbol.E && op != Language.Symbol.OU)
                    {         // Not yet in CNF.
                        AST pInNcf = Convert(p);
                        return(Convert(new ASTOpUnary(pInNcf, Language.Symbol.NAO)));
                    }
                    AST             left       = new ASTOpUnary(opBin.left, Language.Symbol.NAO);
                    AST             right      = new ASTOpUnary(opBin.right, Language.Symbol.NAO);
                    Language.Symbol deMorganOp = Language.Symbol.INVALIDO;
                    if (opBin.value == Language.Symbol.E)
                    {
                        // Form ~(P&Q): from DeMorgan's Law, return Convert(~P|~Q)
                        deMorganOp = Language.Symbol.OU;
                    }
                    else if (opBin.value == Language.Symbol.OU)
                    {
                        // Form ~(P|Q): from DeMorgan's Law, return Convert(~P&~Q)
                        deMorganOp = Language.Symbol.E;
                    }
                    return(Convert(new ASTOpBinary(left, right, deMorganOp)));
                }
                break;
            }

            return(null);
        }
Exemple #4
0
        /// <summary>
        /// Tokenization function
        /// </summary>
        /// <param name="expr">Logic expression to tokenize</param>
        /// <returns>If tokenization succedded. If not, see the erros in Errors attribute.</returns>
        public bool Tokenize(string expr = "")
        {
            if (expr != "") Expr = expr;

            int opened = 0;
            Error = new List<string>();

            // Go through all the expression.
            for (int i = 0; i < expr.Length; i++)
            {
                // Get the symbol of the character in current position.
                char token = expr[i];
                Language.Symbol symbol = Language.Lang.SymbolOf(token);

                if (symbol == Language.Symbol.INVALIDO)
                { // Symbol unknown.
                    CreateError(ERR_UNKNOWNSYMBOL, token, i);
                    continue;
                }

                bool isValid;   // is the token valid to its position? 
                string valid;   // valid tokens for the token's position.
                if (Tokens.Count == 0)
                { // starting of the expression.
                    // Token is a valid initial? 
                    isValid = Language.Lang.IsValidInitial(token);
                    // Get the valid initial tokens set.
                    valid = string.Join<Language.Symbol>(",", Language.Lang.Initial);
                }
                else
                { // middle of the expression.
                    // Token as valid as a follower of the previous symbol? 
                    Language.Symbol previous = Tokens.Last().type;
                    isValid = Language.Lang.Follows(symbol, previous);
                    // Get the valid symbols for the previous one.
                    valid = string.Join<Language.Symbol>(",", Language.Lang.Expected[previous]);
                }

                if (isValid)
                { // token detected as valid.
                    if (symbol != Language.Symbol.VAZIO)        // empty symbols/tokens are ignored.
                        Tokens.Add(new Token(symbol, token));   // add the token to the extracted tokens list.
                }
                else
                { // Token is not valid to its position. 
                    CreateError(ERR_SYMBOL, new object[] { token, i, valid });
                    continue;
                }

                // Add or subtract the opening counting.
                if (symbol == Language.Symbol.ABERTURA) opened++;
                if (symbol == Language.Symbol.FECHAMENTO) opened--;
            }

            if (opened != 0)
            { // Opening and closing counts doesn't match.
                // Gets the exceding symbol/token and create error accordingly.
                char paren = opened < 1 ? ')' : '(';
                CreateError(ERR_PARENS, new object[] { Math.Abs(opened), paren });
            }

            return Error.Count == 0;
        }
Exemple #5
0
 // Constructor.
 public ASTOpUnary(AST ast, Language.Symbol value)
 {
     this.value = value;
     this.ast   = ast;
 }
Exemple #6
0
 // Constructor.
 public ASTOpBinary(AST left, AST right, Language.Symbol value)
 {
     this.left  = left;
     this.right = right;
     this.value = value;
 }
Exemple #7
0
 // Construtor.
 public Token(Language.Symbol symbol, char value)
 {
     this.type  = symbol;
     this.value = value;
 }