public static void DeleteRowValues(this TruthTableValues values, int row) { foreach (var key in values.Keys) { values[key].RemoveAt(row); } }
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); }
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); }
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); }
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); }
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)); }
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)); }
/// <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)); }
/// <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)); }
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); }