예제 #1
0
 public void Visit(Existential visitable) => throw new System.NotImplementedException();
예제 #2
0
        private Decomposition DecomposeWFF(Negation f)
        {
            if (f.inner is AtomicWFF)
            {
                return(null);
            }
            else if (f.inner is Biconditional)
            {
                Biconditional inner = (Biconditional)f.inner;
                List <WFF>    left  = new List <WFF>();
                List <WFF>    right = new List <WFF>();
                left.Add(inner.left.GetNegation());
                left.Add(inner.right);
                right.Add(inner.left);
                right.Add(inner.right.GetNegation());
                return(new Decomposition(f, left, right));
            }
            else if (f.inner is Conditional)
            {
                Conditional inner = (Conditional)f.inner;
                List <WFF>  left  = new List <WFF>();
                left.Add(inner.antecedent);
                left.Add(inner.consequent.GetNegation());
                return(new Decomposition(f, left));
            }
            else if (f.inner is Conjunction)
            {
                Conjunction  inner     = (Conjunction)f.inner;
                List <WFF>[] conjuncts = new List <WFF> [inner.arity];
                for (int a = 0; a < inner.arity; a++)
                {
                    conjuncts[a] = new List <WFF>();
                    conjuncts[a].Add(inner.conjuncts[a].GetNegation());
                }

                return(new Decomposition(f, conjuncts.ToArray()));
            }
            else if (f.inner is Disjunction)
            {
                Disjunction inner     = (Disjunction)f.inner;
                List <WFF>  disjuncts = new List <WFF>();
                foreach (WFF d in inner.disjuncts)
                {
                    disjuncts.Add(d.GetNegation());
                }
                return(new Decomposition(f, disjuncts));
            }
            else if (f.inner is Existential)
            {
                Existential inner = (Existential)f.inner;
                List <WFF>  dec   = new List <WFF>();
                dec.Add(new Universal(inner.variable, inner.scope.GetNegation()));
                return(new Decomposition(f, dec));
            }
            else if (f.inner is Negation)
            {
                Negation   inner = (Negation)f.inner;
                List <WFF> dec   = new List <WFF>();
                dec.Add(inner.inner);
                return(new Decomposition(f, dec));
            }
            else if (f.inner is Universal)
            {
                Universal  inner = (Universal)f.inner;
                List <WFF> dec   = new List <WFF>();
                dec.Add(new Existential(inner.variable, inner.scope.GetNegation()));
                return(new Decomposition(f, dec));
            }

            throw new NotImplementedException(f.inner.GetType().ToString());
        }
        /// <summary>
        /// Build the Abstract Syntax Tree using prefix expression input
        /// </summary>
        public void Build()
        {
            // Remove white space and separator (assume that operand has only 1 character)
            Expression = Regex.Replace(Expression, @"\s+", "");

            if (Expression.Contains(",,"))
            {
                throw new ArgumentException();
            }

            Expression = Regex.Replace(Expression, ",", "");

            // Mark the appeared variables
            int[]  variableAppeared = new int[130];
            bool[] currentlyBounded = new bool[130];

            // The stack used for building AST
            List <Symbol> utilityStack = new List <Symbol>();

            for (int i = 0; i < Expression.Length; i++)
            {
                /////// Close parenthesis, the signal to trigger an operation
                if (Expression[i] == ')')
                {
                    HandleCloseBracket(utilityStack, currentlyBounded, variableAppeared);
                }
                /////// End Close parenthesis
                else if (availablePlaceholder.Contains(Expression[i]))
                {
                    utilityStack.Add(new Placeholder(Expression[i]));
                }
                // Predicate P(x,y,z,t)
                else if (availablePredicate.Contains(Expression[i]))
                {
                    //NumPredicateVariables[Expression[i]] =
                    Predicate P = new Predicate(Expression[i]);
                    utilityStack.Add(P);

                    // P takes 0 object variables
                    if (i == Expression.Length - 1 || Expression[i + 1] != '(')
                    {
                        if (NumPredicateVariables[P.Name] > 0)
                        {
                            throw new InvalidDataException("Wrong number of object variables for predicate " + P.Name);
                        }

                        NumPredicateVariables[P.Name] = 0;
                        P.nChild = 0;
                    }

                    variableAppeared[P.Name]++;
                }
                // Variable
                else if (availableVariable.Contains(Expression[i]))
                {
                    variableAppeared[Expression[i]]++;

                    Variable v = new Variable(Expression[i]);
                    if (currentlyBounded[Expression[i]])
                    {
                        v.Bounded = true;
                    }
                    utilityStack.Add(v);
                }
                // Constant (True/False)
                else if (availableConstant.Contains(Expression[i]))
                {
                    Constant cons = new Constant(Expression[i]);
                    utilityStack.Add(cons);
                }
                // Operator
                else if (availableOperator.Contains(Expression[i]))
                {
                    Symbol currentOperator;

                    switch (Expression[i])
                    {
                    case '&':
                        currentOperator = new And();
                        break;

                    case '|':
                        currentOperator = new Or();
                        break;

                    case '%':
                        currentOperator = new Nand();
                        break;

                    case '=':
                        currentOperator = new BiImplication();
                        break;

                    case '>':
                        currentOperator = new Implication();
                        break;

                    case '~':
                        currentOperator = new Not();
                        break;

                    default:
                        currentOperator = new And();
                        break;
                    }

                    // add to stack
                    utilityStack.Add(currentOperator);
                }
                else if (availableQuantifier.Contains(Expression[i]))
                {
                    HasQuantifier = true;
                    char   quantName   = Expression[i];
                    string tmpBoundVar = "";

                    for (int j = i + 1; j < Expression.Length; j++)
                    {
                        if (availableVariable.Contains(Expression[j]))
                        {
                            tmpBoundVar += Expression[j];
                            currentlyBounded[Expression[j]] = true;
                        }
                        else if (Expression[j] != '.' || j == i + 1)
                        {
                            throw new ArgumentException("Wrong input format at " + j);
                        }
                        else
                        {
                            i = j;
                            break;
                        }
                    }

                    Symbol currentQuantifier;

                    switch (quantName)
                    {
                    case '@':
                        currentQuantifier = new Universal(tmpBoundVar);
                        break;

                    default:
                        currentQuantifier = new Existential(tmpBoundVar);
                        break;
                    }

                    utilityStack.Add(currentQuantifier);
                }
                // Invalid symbol
                else
                {
                    throw new ArgumentException("Invalid symbol.");
                }
            }

            if (utilityStack.Count != 1)
            {
                throw new ArgumentException("Wrong format.");
            }

            Root = utilityStack[0];

            for (char c = 'A'; c <= 'Z'; c++)
            {
                if (variableAppeared[c] > 0)
                {
                    ListVariable.Add(c);
                }
            }

            for (char c = 'a'; c <= 'z'; c++)
            {
                if (variableAppeared[c] > 0)
                {
                    ListVariable.Add(c);
                }
            }
        }
예제 #4
0
 public void Visit(Existential visitable) => visitable.InFixFormula = $"!{visitable.Variables()}[{visitable.LeftNode.InFixFormula}]";