Пример #1
0
        private Block RelatedTheorems()
        {
            string firstContent  = FirstBlock.GetContent(true).ToString(),
                   secondContent = SecondBlock.GetContent(true).ToString();
            bool isConjunctive   = Logic.IsConjunction;

            if (firstContent == secondContent)
            {
                return(FirstBlock.IsNegated != SecondBlock.IsNegated ?
                       new Block(isConjunctive ? "false" : "true") : // complement
                       FirstBlock);                                  // idempotent
            }
            switch (firstContent)
            {
            case "true": return(isConjunctive ? SecondBlock : new Block("true"));       // identity

            case "false": return(isConjunctive ? new Block("false") : SecondBlock);     // annulment
            }

            return(secondContent switch
            {
                "true" => isConjunctive ? FirstBlock : new Block("true"),               // identity
                "false" => isConjunctive ? new Block("false") : SecondBlock,            // annulment
                _ => ConcatStoredBlocks(),
            });
        /// <summary>
        /// a<=>b into (a=>b)&(b=>a) into ((~a||b)&(a||~b)) (Prioritize CNF over DNF)
        /// Warning: This method is one directional, do not use this to convert a logic block into <=>
        /// </summary>
        /// <param name="logicBlock"></param>
        /// <returns>The block passed to this method</returns>
        public override Block Translate()
        {
            if (FirstBlock == null || SecondBlock == null)
            {
                ThrowErrorOnFirstCheck();
            }
            if (!Logic.IsBiconditional)
            {
                return(ConcatStoredBlocks());
            }

            Block cloneFirstBlock  = new Block(FirstBlock.GetContent(true).ToString(), FirstBlock.IsNegated),
                  cloneSecondBlock = new Block(SecondBlock.GetContent(true).ToString(), SecondBlock.IsNegated);

            // (~a||b)
            FirstBlock.SetNegation(!FirstBlock.IsNegated)
            .InsertBack(new Block(PropositionalLogic.Disjunction))
            .InsertBack(SecondBlock);

            // (a||~b)
            cloneFirstBlock
            .InsertBack(new Block(PropositionalLogic.Disjunction))
            .InsertBack(cloneSecondBlock.SetNegation(!cloneFirstBlock.IsNegated));

            // ((~a||b)&(a||~b))
            var nested = new Block(FirstBlock);

            nested.InsertBack(new Block(PropositionalLogic.Conjunction))
            .InsertBack(new Block(cloneFirstBlock));

            return(nested);
        }
Пример #3
0
        /// <summary>
        /// Only a||(b&c) <=> (a||b)&(a||c) is available to prioritize CNF over DNF
        /// </summary>
        /// <param name="logicBlock"></param>
        /// <returns>A block containing nested contents, which are distributed from original one</returns>
        public override Block Translate()
        {
            if (FirstBlock == null || Logic == null || SecondBlock == null)
            {
                ThrowErrorOnFirstCheck();
            }

            bool isFirstNormal  = FirstBlock.ContentType == ContentType.Normal,
                 isSecondNormal = SecondBlock.ContentType == ContentType.Normal;

            // from left to right instead of expanding from the least to the most symbols
            // no point in taking a&b or similars into consideration
            if (!isFirstNormal || !isSecondNormal)
            {
                var logic = Logic.ToString();

                // swap places: (a&b)||c into c||(a&b) locally
                if (isSecondNormal)
                {
                    (FirstBlock, SecondBlock) = (SecondBlock, FirstBlock);
                }

                // a&(b||c) like
                if (FirstBlock.ContentType == ContentType.Normal)
                {
                    return(Distribute(
                               FirstBlock.IsNegated,
                               FirstBlock.GetContent(true).ToString(),
                               SecondBlock.GetContent() as Block));
                }

                // (a||b)&(c||d) like
                if (FirstBlock.ContentType == ContentType.Nested)
                {
                    BlockIterator.ForEach(FirstBlock.GetContent() as Block, (currentBlock) =>
                    {
                        if (currentBlock.ContentType == ContentType.Normal)
                        {
                            Distribute(
                                currentBlock.IsNegated,
                                currentBlock.GetContent(true).ToString(),
                                SecondBlock.GetContent() as Block
                                );
                        }
                    });
                    return(FirstBlock.GetContent() as Block);
                }
            }

            return(ConcatStoredBlocks());
        }