コード例 #1
0
ファイル: LogicEngine.cs プロジェクト: samjo-nyang/zerogic
 /// <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);
 }
コード例 #2
0
ファイル: LogicEngine.cs プロジェクト: samjo-nyang/zerogic
        /// <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);
        }
コード例 #3
0
ファイル: LogicEngine.cs プロジェクト: samjo-nyang/zerogic
 /// <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));
 }
コード例 #4
0
 /// <summary>Check this proposition is vaild</summary>
 /// <returns>True if vaild</returns>
 public bool IsVaild()
 {
     if (op == Operator.Null)
     {
         return(false);
     }
     else if (op == Operator.Atom)
     {
         return(atom != null);
     }
     else if (op == Operator.Not)
     {
         return(left != null && left.IsVaild());
     }
     else if (op == Operator.Or || op == Operator.And || op == Operator.Imply || op == Operator.IfOnlyIf)
     {
         return(left != null && right != null && left.IsVaild() && right.IsVaild());
     }
     else
     {
         return(false);
     }
 }
コード例 #5
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);
        }
コード例 #6
0
ファイル: LogicEngine.cs プロジェクト: samjo-nyang/zerogic
        /// <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);
        }