示例#1
0
        /// <summary>
        /// From ~(a||b) to ~a&~b and ~(a&b) to ~a||~b (vice-versa)
        /// </summary>
        /// <param name="blockWithNestedContent"></param>
        /// <returns>The block passed to this method</returns>
        public override Block Translate()
        {
            if (FirstBlock == null && (FirstBlock = SecondBlock) == null)
            {
                ThrowErrorOnFirstCheck();
            }

            Block blockWithNestedContent = FirstBlock;

            if (blockWithNestedContent.ContentType == ContentType.Nested)
            {
                blockWithNestedContent.SetNegation(!blockWithNestedContent.IsNegated);
                BlockIterator.ForEach(blockWithNestedContent.GetContent() as Block, (currentBlock) =>
                {
                    switch (currentBlock.ContentType)
                    {
                    case ContentType.Logic:
                        (currentBlock.GetContent() as PropositionalLogic).Invert();
                        break;

                    default:
                        currentBlock.SetNegation(!currentBlock.IsNegated);
                        break;
                    }
                });
            }
            return(blockWithNestedContent);
        }
示例#2
0
        private void IterateThroughBlockLists(Block block)
        {
            BlockIterator.ForEach(block, (currentBlock) =>
            {
                // recursion for removal of deep nesting
                object content = currentBlock.GetContent();
                if (content is Block)
                {
                    IterateThroughBlockLists(content as Block);
                    return;
                }

                // we do not want any logic in here
                if (content is PropositionalLogic)
                {
                    return;
                }

                // definitely a string, containing a symbol
                string value = content as string;
                if (!UniqueValues.Contains(value))
                {
                    UniqueValues.Add(value);
                }
            });
        }
示例#3
0
        /// <summary>
        /// Check clause (a&b) against one model (row) in truth table
        /// </summary>
        /// <param name="rootBlock"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        private bool CheckClauseAgainstModel(Block rootBlock, Model model)
        {
            bool   result     = false;
            string logic      = "";
            bool   firstValue = true;

            BlockIterator.ForEach(rootBlock, (block) =>
            {
                switch (block.ContentType)
                {
                case ContentType.Normal:
                    bool blockValue = model.GetTruthBlock(block.GetContent(true).ToString());

                    if (block.IsNegated)
                    {
                        blockValue = !blockValue;
                    }

                    // if else
                    if (firstValue)
                    {
                        result     = blockValue;
                        firstValue = false;
                        return;
                    }
                    result = Verify(result, logic, blockValue);

                    break;

                case ContentType.Logic:
                    logic = block.GetContent(true).ToString();
                    break;

                case ContentType.Nested:
                    bool nestedBlockValue = CheckClauseAgainstModel(block.GetContent() as Block, model);

                    if (block.IsNegated)
                    {
                        nestedBlockValue = !nestedBlockValue;
                    }

                    // if else
                    if (firstValue)
                    {
                        result     = nestedBlockValue;
                        firstValue = false;
                        return;
                    }
                    result = Verify(result, logic, nestedBlockValue);

                    break;
                }
            });

            return(result);
        }
示例#4
0
 /// <summary>
 /// Traverse through the list, regardless of parentheses
 /// </summary>
 protected int Traverse(Action <Block, int> action, Block rootBlock = null, int index = 0)
 {
     BlockIterator.ForEach(rootBlock ?? RootBlock, (currentBlock) =>
     {
         if (currentBlock.ContentType == ContentType.Nested)
         {
             index = Traverse(action, currentBlock.GetContent() as Block, index);
             return;
         }
         action.Invoke(currentBlock, index++);
     });
     return(index);
 }
示例#5
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());
        }
示例#6
0
        /// <summary>
        /// Distribute content to nested block using given logic (under assumption that nested block
        /// contains no more nested contents)
        /// <para>E.g: a&(b||c) <=> (a&b)||(a&c)</para>
        /// </summary>
        /// <param name="content"></param>
        /// <param name="logic"></param>
        /// <param name="nested"></param>
        /// <returns></returns>
        private Block Distribute(bool isNegated, string content, Block nested)
        {
            // with a||(b&c)
            // isNegated = false, content = a, logic = ||, nested = b&c
            BlockIterator.ForEach(nested, (currentBlock) =>
            {
                if (currentBlock.ContentType != ContentType.Logic)
                {
                    var block = new Block(content, isNegated);                              // a (or ~a)
                    block.InsertBack(new Block(Logic))                                      // connective
                    .InsertBack(new Block(currentBlock.GetContent(true).ToString()));       // b or c in (b||c)

                    currentBlock.SetContent(block);
                }
            });
            return(nested);
        }
示例#7
0
        /// <summary>
        /// Represent the whole linked list as a string again
        /// </summary>
        /// <returns>A string in form of ~a& to represent a certain part of the list</returns>
        public override string ToString()
        {
            string result = "";

            if (NextBlock == null && PreviousBlock == null)
            {
                return((IsNegated ? PropositionalLogic.NEGATION : "") + GetContent(true));
            }

            // forward iterate through the list from this block onwards
            BlockIterator.ForEach(this, (currentBlock) =>
            {
                // one block of content is pushed into the result (no whitespaces in between)
                result +=
                    (currentBlock.IsNegated ? PropositionalLogic.NEGATION : "") +
                    currentBlock.GetContent(true);
            });

            return(result);
        }
        public void TestGuaranteeCNF()
        {
            Assert.DoesNotThrow(() =>
            {
                foreach (var clause in StartingClauses)
                {
                    var block = new ClauseRephraser().RephraseIntoBlock(clause);
                    BlockIterator.ForEach(block, (currentBlock) =>
                    {
                        // all normal clauses contain only disjunction
                        // conjunction only appears when concatenating two or more clauses
                        if (currentBlock.ContentType == ContentType.Logic)
                            Assert.AreEqual(
                                (currentBlock.GetContent() as PropositionalLogic).IsDisjunction,
                                true
                            );
                    });
                }
            });

        }