/// <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);
        }
Пример #2
0
        /// <summary>
        /// a->b <=> (~a||b)
        /// </summary>
        /// <param name="logicBlock"></param>
        /// <returns>The block passed to this method</returns>
        public override Block Translate()
        {
            if (FirstBlock == null || SecondBlock == null)
            {
                ThrowErrorOnFirstCheck();
            }

            // elimination
            if (Logic.IsImplication)
            {
                FirstBlock.SetNegation(!FirstBlock.IsNegated)
                .InsertBack(new Block(PropositionalLogic.Disjunction))
                .InsertBack(SecondBlock);

                return(FirstBlock);
            }

            // reverse elimination
            // ~a||b into a=>b and a||~b into b=>a
            // accepting either one of them is negated, not both true or both false => XOR is the best choice
            if (Logic.IsDisjunction && (FirstBlock.IsNegated ^ SecondBlock.IsNegated))
            {
                FirstBlock  = FirstBlock.IsNegated ? FirstBlock : SecondBlock;
                SecondBlock = FirstBlock.IsNegated ? SecondBlock : FirstBlock;

                FirstBlock.SetNegation(!FirstBlock.IsNegated)
                .InsertBack(new Block(PropositionalLogic.Implication))
                .InsertBack(SecondBlock);

                return(FirstBlock);
            }

            return(ConcatStoredBlocks());
        }
Пример #3
0
        protected override void Layout()
        {
            Renderman     renderer = Element.Document.Renderer;
            ComputedStyle computed = Element.Style.Computed;
            // Get the top left inner corner (inside margin and border):
            int width  = computed.PaddedWidth;
            int height = computed.PaddedHeight;
            int top    = computed.OffsetTop + computed.BorderTop;
            int left   = computed.OffsetLeft + computed.BorderLeft;

            // Is it clipped?
            if (renderer.IsInvisible(left, top, width, height))
            {
                // Totally not visible.
                return;
            }

            // Ensure we have a batch (doesn't change graphics or font thus both nulls):
            SetupBatch(null, null);

            Add();

            // Using firstblock as our block here.
            // Set the UV to that of the solid block colour pixel:
            FirstBlock.SetSolidColourUV();
            // Set the (overlay) colour:
            FirstBlock.SetColour(BackingColour);

            // And finally sort out the verts:
            FirstBlock.SetClipped(renderer.ClippingBoundary, new BoxRegion(left, top, width, height), renderer, computed.ZIndex - 0.006f);
        }
Пример #4
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(),
            });
Пример #5
0
        public override void Paint()
        {
            if (FirstBlock == null)
            {
                // This can happen if an animation is requesting that a now offscreen element gets painted only.
                return;
            }

            FirstBlock.SetColour(BackingColour);
            FirstBlock.Paint();
        }
Пример #6
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());
        }