Пример #1
0
 /// <summary>Make proposiiton with operator, atom and two sub-proposition</summary>
 /// <param name="op">Operator of proposition</param>
 /// <param name="atom">Atom of proposition</param>
 /// <param name="expr1">First sub-proposition of proposition</param>
 /// <param name="expr2">Second sub-proposition of proposition</param>
 public Proposition(Operator op, Atom atom, Proposition expr1, Proposition expr2)
 {
     this.left  = expr1;
     this.right = expr2;
     this.atom  = atom;
     this.op    = op;
 }
Пример #2
0
        /// <summary>Evaluate at given proposition</summary>
        /// <param name="expr">Proposition to evaluate</param>
        /// <returns>Result of evaluation</returns>
        private bool Evaluate(Proposition expr)
        {
            switch (expr.op)
            {
            case Operator.Atom:
                string s = expr.atom.Symbol;
                if (s == ParseEngine.SYMBOL_T)
                {
                    return(true);
                }
                else if (s == ParseEngine.SYMBOL_F)
                {
                    return(false);
                }
                return(evalData[s]);

            case Operator.Or:
                return(Evaluate(expr.left) || Evaluate(expr.right));

            case Operator.And:
                return(Evaluate(expr.left) && Evaluate(expr.right));

            case Operator.Not:
                return(!Evaluate(expr.left));

            case Operator.Imply:
                return(!Evaluate(expr.left) || Evaluate(expr.right));

            case Operator.IfOnlyIf:
                return(!(Evaluate(expr.left) ^ Evaluate(expr.right)));

            default:
                return(false);
            }
        }
Пример #3
0
        /// <summary>Parse from current position with given priority</summary>
        /// <param name="prec">Priority</param>
        /// <returns>Parsed proposition</returns>
        private Proposition ParseWithPrec(int prec)
        {
            Proposition expr1, expr2;

            expr1 = GetNextExpression();

            backIndex = index;

            while (index != input.Length)
            {
                string s = GetNextToken();

                if (s == SYMBOL_RP)
                {
                    index = backIndex;
                    return(expr1);
                }

                Operator op = GetOperator(s);
                int      pr = GetPrecedence(op);

                if (pr > prec)
                {
                    index = backIndex;
                    return(expr1);
                }
                else
                {
                    expr2 = ParseWithPrec(pr);
                    expr1 = new Proposition(op, expr1, expr2);
                }
            }
            return(expr1);
        }
Пример #4
0
 /// <summary>Check whether give proposition is contradiction</summary>
 /// <param name="expr">Proposition to check</param>
 /// <exception cref="InvaildPropositionException"></exception>
 /// <returns>True if contradiction</returns>
 public bool IsContradiction(Proposition expr)
 {
     if (expr == null || !expr.IsVaild())
     {
         throw new InvalidPropositionException("INVAILD");
     }
     return(GetTrueAssignmentList(expr).Count == 0);
 }
Пример #5
0
        /// <summary>Find assignment list which each assignment table make give proposition true</summary>
        /// <param name="expr">Proposition to get true assignment list</param>
        /// <exception cref="InvaildPropositionException"></exception>
        /// <returns>Assignment list</returns>
        public List <Dictionary <string, bool> > GetTrueAssignmentList(Proposition expr)
        {
            if (expr == null || !expr.IsVaild())
            {
                throw new InvalidPropositionException("INVAILD");
            }

            trueList = new List <Dictionary <string, bool> >();
            GetTrueAssignmentListCore(expr, new Dictionary <string, bool>());
            return(trueList);
        }
Пример #6
0
 /// <summary>Check whether give proposition is tautology</summary>
 /// <param name="expr">Proposition to check</param>
 /// <exception cref="InvaildPropositionException"></exception>
 /// <returns>True if tautology</returns>
 public bool IsTautology(Proposition expr)
 {
     if (expr == null || !expr.IsVaild())
     {
         throw new InvalidPropositionException("INVAILD");
     }
     if (!expr.IsCNF())
     {
         expr = ConvertToCNF(ConvertToNNF(expr));
     }
     return(IsTautologyCore(expr));
 }
Пример #7
0
        /// <summary>Convert given NNF proposition to CNF proposition</summary>
        /// <param name="expr">NNF proposition to convert</param>
        /// <exception cref="PropositionNotSupportException"></exception>
        /// <returns>CNF proposition</returns>
        public Proposition ConvertToCNF(Proposition expr)
        {
            if (expr == null || !expr.IsNNF())
            {
                throw new PropositionNotSupportedException("NOT_NNF");
            }

            if (expr.op == Operator.Atom)
            {
                return(expr);
            }
            else if (expr.op == Operator.And) // S(P&Q) => S(P)&S(Q)
            {
                return(new Proposition(Operator.And,
                                       ConvertToCNF(expr.left),
                                       ConvertToCNF(expr.right)));
            }
            else if (expr.op == Operator.Or) // S(P|Q) =>
            {
                Proposition c1 = ConvertToCNF(expr.left);
                Proposition c2 = ConvertToCNF(expr.right);

                if (c1.op != Operator.And && c2.op != Operator.And) // S(P|Q) => S(P)|S(Q)
                {
                    return(new Proposition(Operator.Or, c1, c2));
                }

                if (c1.op != Operator.And)
                {
                    Proposition tmp = c1; c1 = c2; c2 = tmp; // S((A&B)|C) => S(A|C)&S(B|C)
                }
                return(new Proposition(Operator.And,
                                       ConvertToCNF(new Proposition(Operator.Or, c1.left, c2)),
                                       ConvertToCNF(new Proposition(Operator.Or, c1.right, c2))));
            }
            else if (expr.op == Operator.Not)      // S(P) => S(P)
            {
                if (expr.left.op == Operator.Atom) // Must Be Unit According to Def. of NNF
                {
                    return(expr);
                }
            }
            return(null);
        }
Пример #8
0
        /// <summary>Evaluate proposition with given data</summary>
        /// <param name="value">Result of evaluation</param>
        /// <param name="error">Error Message</param>
        /// <param name="expr">Proposition to evaluate</param>
        /// <param name="data">Assignment table</param>
        /// <returns>True if successed evaluate</returns>
        public bool TryEvaluate(out bool value, out string error, Proposition expr, Dictionary <string, bool> data)
        {
            value = false; error = "";
            if (expr == null || !expr.IsVaild())
            {
                error = InvalidPropositionException.REASON_INVAILD;
                return(false);
            }

            List <string> atomList = expr.GetAtomList();
            List <string> keyList  = data.Keys.ToList();

            if (atomList.Intersect(keyList).Count() != atomList.Count)
            {
                error = "모든 atom에 대해 적절한 대입값이 없습니다.";
                return(false);
            }

            evalData = data;
            value    = Evaluate(expr);
            return(true);
        }
Пример #9
0
        /// <summary>Build all possible assignment and calculate</summary>
        /// <param name="expr">Proposition to calculate</param>
        /// <param name="dict">Assignment list</param>
        private void GetTrueAssignmentListCore(Proposition expr, Dictionary <string, bool> dict)
        {
            if (expr.GetAtomList().Count == dict.Count)
            {
                bool value; string result;
                calcEng.TryEvaluate(out value, out result, expr, dict);
                if (value)
                {
                    trueList.Add(dict.DeepCopy());
                }
            }
            else
            {
                string target = expr.GetAtomList().Except(dict.Keys.ToList()).First();
                Dictionary <string, bool> dict1 = dict.DeepCopy(), dict2 = dict.DeepCopy();
                dict1.Add(target, false);
                dict2.Add(target, true);

                GetTrueAssignmentListCore(expr, dict1);
                GetTrueAssignmentListCore(expr, dict2);
            }
        }
Пример #10
0
        /// <summary>Parse string to proposition object</summary>
        /// <param name="expr">Parsed proposition object</param>
        /// <param name="result">Result of parsing</param>
        /// <param name="str">String to parse</param>
        /// <returns>True if success parsing</returns>
        public bool TryParse(out Proposition expr, out string result, string str)
        {
            expr      = null; result = "";
            backIndex = 0;
            index     = 0;

            try
            {
                input = Normalize(str).ToCharArray();
                expr  = ParseWithPrec(PREC_MAX);
            }
            catch (ParseException e)
            {
                result = e.Message;
                return(false);
            }

            if (index != input.Length)
            {
                result = ParseException.REASON_NOT_READ_ALL; return(false);
            }
            return(true);
        }
Пример #11
0
        /// <summary>Find next proposition from current position</summary>
        /// <returns>Proposition</returns>
        private Proposition GetNextExpression()
        {
            string s = GetNextToken();

            if (s == SYMBOL_LP)
            {
                Proposition expr = ParseWithPrec(PREC_MAX);
                if (!MoveNext(SYMBOL_RP))
                {
                    throw new ParseException("NOT_MATCH_PARN", index.ToString());
                }
                return(expr);
            }
            else if (s == SYMBOL_NOT)
            {
                Proposition expr = ParseWithPrec(PREC_NOT);
                return(new Proposition(Operator.Not, expr));
            }
            else
            {
                return(new Proposition(Operator.Atom, new Atom(s)));
            }
        }
Пример #12
0
 /// <summary>Tautology core engine</summary>
 /// <param name="expr">Proposition to check</param>
 /// <returns>True if tautology</returns>
 private bool IsTautologyCore(Proposition expr)
 {
     if (expr.op == Operator.Atom)
     {
         if (expr.atom.Symbol == "T")
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     else if (expr.op == Operator.Not)
     {
         if (expr.atom.Symbol == "F")
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     else if (expr.op == Operator.And)
     {
         return(IsTautologyCore(expr.left) && IsTautologyCore(expr.right));
     }
     else if (expr.op == Operator.Or)
     {
         return(expr.IsTautologyClause());
     }
     else
     {
         return(false);
     }
 }
Пример #13
0
 /// <summary>Make proposiiton with operator and two sub-proposition</summary>
 /// <param name="op">Operator of proposition</param>
 /// <param name="expr1">First sub-proposition of proposition</param>
 /// <param name="expr2">Second sub-proposition of proposition</param>
 public Proposition(Operator op, Proposition expr1, Proposition expr2) : this(op, null, expr1, expr2)
 {
 }
Пример #14
0
        /// <summary>Convert given proposition to negative normal form</summary>
        /// <param name="expr">Proposition to convert</param>
        /// <exception cref="InvaildPropositionException"></exception>
        /// <returns>NNF proposition</returns>
        public Proposition ConvertToNNF(Proposition expr)
        {
            if (expr == null || !expr.IsVaild())
            {
                throw new InvalidPropositionException("INVAILD");
            }

            if (expr.op == Operator.Atom)
            {
                return(expr);
            }
            else if (expr.op == Operator.Or) // S(P|Q) => S(P)|S(Q)
            {
                return(new Proposition(Operator.Or,
                                       ConvertToNNF(expr.left),
                                       ConvertToNNF(expr.right)));
            }
            else if (expr.op == Operator.And) // S(P&Q) => S(P)&S(Q)
            {
                return(new Proposition(Operator.And,
                                       ConvertToNNF(expr.left),
                                       ConvertToNNF(expr.right)));
            }
            else if (expr.op == Operator.Imply) // S(P->Q) => S(~P)|S(Q)
            {
                return(new Proposition(Operator.Or,
                                       ConvertToNNF(new Proposition(Operator.Not, expr.left)),
                                       ConvertToNNF(expr.right)));
            }
            else if (expr.op == Operator.IfOnlyIf) // S(P<->Q) => S(P->Q)&S(Q->P)
            {
                return(new Proposition(Operator.And,
                                       ConvertToNNF(new Proposition(Operator.Imply, expr.left, expr.right)),
                                       ConvertToNNF(new Proposition(Operator.Imply, expr.right, expr.left))));
            }
            else if (expr.op == Operator.Not) // S(~P) =>
            {
                Proposition nexpr = expr.left;
                if (nexpr.op == Operator.Atom) // S(T) => F, S(F) => T, S(~P) => ~P
                {
                    if (nexpr.atom.Symbol == "T")
                    {
                        return(new Proposition(Operator.Atom, new Atom("F")));
                    }
                    else if (nexpr.atom.Symbol == "F")
                    {
                        return(new Proposition(Operator.Atom, new Atom("T")));
                    }
                    else
                    {
                        return(expr);
                    }
                }

                if (nexpr.op == Operator.Imply) // S(P->Q) => S(~P)|S(Q)
                {
                    nexpr = new Proposition(Operator.Or,
                                            ConvertToNNF(new Proposition(Operator.Not, nexpr.left)),
                                            ConvertToNNF(nexpr.right));
                }
                else if (nexpr.op == Operator.IfOnlyIf) // S(P<->Q) => S(P->Q)&S(Q->P)
                {
                    nexpr = new Proposition(Operator.And,
                                            ConvertToNNF(new Proposition(Operator.Imply, nexpr.left, nexpr.right)),
                                            ConvertToNNF(new Proposition(Operator.Imply, nexpr.right, nexpr.left)));
                }

                if (nexpr.op == Operator.Or) // S(~(P|Q)) => ~S(P)&~S(Q)
                {
                    return(new Proposition(Operator.And,
                                           ConvertToNNF(new Proposition(Operator.Not, nexpr.left)),
                                           ConvertToNNF(new Proposition(Operator.Not, nexpr.right))));
                }
                else if (nexpr.op == Operator.And) // S(~(P&Q)) => ~S(P)|~S(Q)
                {
                    return(new Proposition(Operator.Or,
                                           ConvertToNNF(new Proposition(Operator.Not, nexpr.left)),
                                           ConvertToNNF(new Proposition(Operator.Not, nexpr.right))));
                }
                else if (nexpr.op == Operator.Not) // S(~(~P))) => S(P)
                {
                    return(ConvertToNNF(nexpr.left));
                }
            }
            return(null);
        }