Пример #1
0
 public static void DeleteRowValues(this TruthTableValues values, int row)
 {
     foreach (var key in values.Keys)
     {
         values[key].RemoveAt(row);
     }
 }
Пример #2
0
 public void Should_Return_List_Of_Values_For_Specified_Row_In_Specified_TruthTable_Values_Without_Result_Column_Values(
     TruthTableValues tableValues,
     int row,
     List <string> expectedResult)
 {
     tableValues.GetRowValuesWithouthResultColumn(row).Should().BeEquivalentTo(expectedResult);
 }
Пример #3
0
        public static TruthTableValues FillTruthTableVariablesValues(List <INode> leafs, int rows)
        {
            TruthTableValues tableValues = new TruthTableValues();

            foreach (INode leaf in leafs)
            {
                int numberOfZeros = (int)Math.Pow(2, (leafs.Count() - tableValues.Count()) - 1);

                string valueToAdd = "0";

                int curr = 0;

                for (int i = 0; i < rows; i++)
                {
                    if (tableValues.ContainsKey($@"{leaf.Value}"))
                    {
                        tableValues[$@"{leaf.Value}"].Add(valueToAdd);
                    }
                    else
                    {
                        tableValues.Add($@"{leaf.Value}", new List <string>()
                        {
                            valueToAdd
                        });
                    }

                    if (++curr == numberOfZeros)
                    {
                        valueToAdd = valueToAdd == "0" ? "1" : "0";
                        curr       = 0;
                    }
                }
            }
            return(tableValues);
        }
Пример #4
0
        public void Should_Duplicate_TruthTableValues_Without_Reference()
        {
            TruthTableValues values1 = new TruthTableValues();
            TruthTableValues values2 = (TruthTableValues)values1.Clone();

            values1.Add("dummy_key", new List <string>());
            values1.Should().NotBeSameAs(values2);
        }
Пример #5
0
        public static List <string> GetRowValuesWithouthResultColumn(this TruthTableValues values, int row)
        {
            var list = new List <string>();

            foreach (var key in values.Keys)
            {
                if (key != values.Keys.Last())
                {
                    list.Add(values[key][row]);
                }
            }
            return(list);
        }
Пример #6
0
        public static TruthTable GenerateTruthTable(List <int> minterms)
        {
            TruthTableValues values = GenerateVariableValues(minterms);
            int rows = (int)Math.Pow(2, values.Count);

            List <string> resultValues = new List <string>();

            for (int i = 0; i < rows; i++)
            {
                resultValues.Add(minterms.Contains(i) ? "1" : "0");
            }

            values.Add("RESULT", resultValues);

            return(new TruthTable(values));
        }
Пример #7
0
        private static TruthTable EvaluateTruthTable(
            this TruthTableValues tableValues,
            IBinaryExpressionTree tree,
            string resultColumnName,
            int rows)
        {
            tableValues.Add(resultColumnName, new List <string>());
            Stack <bool> stack           = new Stack <bool>();
            var          postOrderedTree = tree.TraversePostOrder();

            for (int i = 0; i < rows; i++)
            {
                foreach (var node in postOrderedTree)
                {
                    if (node.Value.IsOperator())
                    {
                        if (((char)Operators.Negation).Equals(node.Value))
                        {
                            bool      value        = stack.Pop();
                            Operators operatoValue = (Operators)node.Value;

                            bool operationResult = HelperExtensions.GetOperationResult(value, operatoValue);
                            stack.Push(operationResult);
                        }
                        else
                        {
                            bool      value2       = stack.Pop();
                            bool      value1       = stack.Pop();
                            Operators operatoValue = (Operators)node.Value;

                            bool operationResult = HelperExtensions.GetOperationResult(value1, operatoValue, value2);
                            stack.Push(operationResult);
                        }
                    }
                    else
                    {
                        stack.Push(Convert.ToInt32(tableValues[$@"{node.Value}"][i]).ToBool());
                    }
                }
                tableValues[resultColumnName].Add(stack.Pop() ? "1" : "0");
            }

            return(new TruthTable(tableValues));
        }
Пример #8
0
        /// <summary>
        /// Function that forms groups of number of 1s from the truth table values that need to be simplified.
        /// Ex: Group for values with only 1 positive variables, group for values with 2 positive variables and so on...
        /// </summary>
        /// <param name="reference">The values of the truth table that has to be simplified.</param>
        /// <returns>Formed gruops with keys the number of 1's in the data plus the minterms that are necessary for getting the prime implicants.</returns>
        private static Tuple <QMCGroups, HashSet <int> > FormGroupsWithMintermsForComparison(TruthTableValues reference)
        {
            // Groups with number of ones //
            var groups     = new QMCGroups();
            var minterms   = new HashSet <int>();
            var resultData = reference[reference.Keys.Last()];

            for (int i = 0; i < resultData.Count; i++)
            {
                if (resultData[i] == "1")
                {
                    minterms.Add(i);
                    var rowValues   = reference.GetRowValuesWithouthResultColumn(i);
                    int GroupNumber = rowValues.FindAll(n => n == "1").Count;
                    if (!groups.ContainsKey(GroupNumber))
                    {
                        groups.Add(GroupNumber, new List <QMCGroupData>()
                        {
                            new QMCGroupData(i, String.Join("", rowValues))
                        });
                    }
                    else
                    {
                        groups[GroupNumber].Add(new QMCGroupData(i, String.Join("", rowValues)));
                    }
                }
            }
            return(new Tuple <QMCGroups, HashSet <int> >(groups, minterms));
        }
Пример #9
0
        /// <summary>
        /// Function which simplifies the passed <see cref="TruthTableValues"/> for a <see cref="TruthTable"/>
        /// </summary>
        /// <param name="reference">The values of the table which has to be simplified</param>
        /// <returns>List of the essential prime implicants.</returns>
        public static IEnumerable <QMCGroupData> SimplifyTable(TruthTableValues reference)
        {
            // Form the groups and the minterms
            var result = FormGroupsWithMintermsForComparison(reference);

            //Assign the groups and the minterms
            var groups   = result.Item1;
            var minterms = result.Item2;

            //Initialize a queue needed to iterate over the groups until no groups can be compared no more, and fill it with the initial groups
            Queue <KeyValuePair <int, List <QMCGroupData> > > queue = new Queue <KeyValuePair <int, List <QMCGroupData> > >();

            foreach (var group in groups)
            {
                queue.Enqueue(group);
            }

            //Set for keeping track of the values which were already simplified
            HashSet <QMCGroupData> marked = new HashSet <QMCGroupData>();

            //Set for keeping track of the prime latest simplified values
            HashSet <QMCGroupData> simplifiedValues = new HashSet <QMCGroupData>();

            //In order not to compare the last group with the first group from the completely newly formed groups which are different and not comparable to the previous
            //We keep track of the index of the last group of the currently evaluated groups
            int indexShouldNotCompare = groups.Keys.Last();

            //The key that has to be assigned to the eventually newly created group
            int nextKey = indexShouldNotCompare + 1;

            //Iterate through the groups until there are at least 2 groups available, we can't compare less than 2 groups
            while (queue.Count >= 2)
            {
                //Get the current group and the one that is following
                //NOTE: Groups are always sorted by the number of positive variables in the group
                var group1 = queue.Dequeue();
                var group2 = queue.Peek();

                if (group1.Key != indexShouldNotCompare)
                {
                    //The data for the newly created group
                    List <QMCGroupData> newGroupData = new List <QMCGroupData>();

                    for (int i = 0; i < group1.Value.Count; i++)
                    {
                        //Get the first values from the first group
                        QMCGroupData data1 = group1.Value[i];

                        //Find the comparable values from the second group with the first data values of the first group
                        var comparables = GetComparableRows(group2.Value, data1);

                        if (comparables.Count > 0)
                        {
                            //Iterate through the list of comparables
                            for (int j = 0; j < comparables.Count; j++)
                            {
                                QMCGroupData data2 = comparables[j];

                                //Get the don't care index and mark it in the data of the first group's data values
                                var chars           = data1.RowData.ToCharArray();
                                int indexToSimplify = chars.Length - 1 - (int)Math.Log2(GetDontCareIndex(data1, data2));
                                chars[indexToSimplify] = DONT_CARE;
                                string simplifiedData = new string(chars);

                                //Create a new data object and put it in the latest simplified values and in the new group data values, if it is not there yet
                                QMCGroupData data = new QMCGroupData(GetNewRows(data1, data2), simplifiedData);
                                if (!simplifiedValues.Contains(data))
                                {
                                    newGroupData.Add(data);
                                    simplifiedValues.Add(data);
                                }

                                //Mark the data values that were simplified
                                marked.Add(data1);
                                marked.Add(data2);

                                //If the latest simplified values contains the data values that were simplified again,
                                //remove them from the set because we keep only the latest
                                if (simplifiedValues.Contains(data1))
                                {
                                    simplifiedValues.Remove(data1);
                                }

                                if (simplifiedValues.Contains(data2))
                                {
                                    simplifiedValues.Remove(data2);
                                }
                            }
                        }
                        else if (!simplifiedValues.Contains(data1) && !marked.Contains(data1))
                        {
                            //If the data values cannot be simplified, it still is count later as a prime implicant and it should be added in the simplified values.
                            //If later in the process it is simplified, it will be removed.
                            simplifiedValues.Add(data1);
                        }
                    }

                    //Add the new group to the queue if it has any data values
                    if (newGroupData.Count > 0)
                    {
                        queue.Enqueue(new KeyValuePair <int, List <QMCGroupData> >(nextKey++, newGroupData));
                    }
                    else
                    {
                        nextKey++;
                    }
                }
                else
                {
                    //If the group should not be compared because it is the last one

                    //Set the next group key
                    indexShouldNotCompare = nextKey - 1;

                    //If the group has only one row, this means a group from the initial ones is not simplified, it should be added in the simplified values
                    //because it is still evaluated at the end as a prime implicant and it will not be compared anymore in the process of simplifying.

                    //We add only the initial groups because if a group is already simplified it has more than 1 rows and it is already added in the simplified values.
                    if (group1.Value.First().Rows.Length == 1)
                    {
                        foreach (var data in group1.Value)
                        {
                            if (!simplifiedValues.Contains(data) && !marked.Contains(data))
                            {
                                simplifiedValues.Add(data);
                            }
                        }
                    }
                }
            }
            //Return the essential prime implicants
            return(GetPrimeImplicants(simplifiedValues, minterms));
        }
Пример #10
0
        public void Should_Calculate_And_Return_Expected_Hex_Value_From_TruthTable_Result_Column(TruthTableValues values, string expectedResult)
        {
            TruthTable table = new TruthTable(values);

            table.HexResult.Should().BeEquivalentTo(expectedResult);
        }