Logic Boolean / True Tables and Outputs
I am currently trying to replicate the way to convert truth tables to boolean expressions in C #. I was able to create a truth table 3 (a, b, c) and display it in a multi-line text box. I created eight more user text fields for each output: either true(1)
or false(0)
. But after generating the table, how can I display all outputs with a true
value?
namespace truth_table
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string newLine = Environment.NewLine;
bool a;
bool b;
bool c;
bool d;
private void Form1_Load(object sender, EventArgs e)
{
textBox1.AppendText(newLine + "A" + "\t" + "B" + "\t" + "C" + newLine);
textBox1.AppendText("______________________________" + newLine);
a = true; b = true; c = true;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c +newLine);
textBox1.AppendText("______________________________" + newLine);
a = true; b = true; c = false;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = true; b = false; c = true;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = true; b = false; c = false;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = false; b = true; c = true;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = false; b = true; c = false;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = false; b = false; c = true;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
a = false; b = false; c = false;
textBox1.AppendText(newLine + a + "\t" + b + "\t" + c + newLine);
textBox1.AppendText("______________________________" + newLine);
}
private void button1_Click(object sender, EventArgs e)
{
//Grab true value outputs and display in string
}
}
}
The above table is an example. I would like to somehow display the true output values:
Results Below:
FALSE TRUE TRUE
TRUE FALSE TRUE
TRUE TRUE FALSE
TRUE TRUE False
source to share
Try to encapsulate your TruthItem (along with the logic to calculate TruthValue). Then it would be easy to work with the truth table (generation, iteration, computation, etc.).
Here's a sample console application. It doesn't have your text boxes, but you would get the idea.
public abstract class ThreeItemTruthRow
{
protected ThreeItemTruthRow(bool a, bool b, bool c)
{
A = a; B = b; C = c;
}
public bool A { get; protected set; }
public bool B { get; protected set; }
public bool C { get; protected set; }
public abstract bool GetTruthValue();
}
public class MyCustomThreeItemTruthRow : ThreeItemTruthRow
{
public MyCustomThreeItemTruthRow(bool a, bool b, bool c)
: base(a, b, c)
{
}
public override bool GetTruthValue()
{
// My custom logic
return (!A && B && C) || (A && !B && C) || (A && B && !C) || (A && B && C);
}
}
class Program
{
static void Main(string[] args)
{
var myTruthTable = GenerateTruthTable().ToList();
//Print only true values
foreach (var item in myTruthTable)
{
if (item.GetTruthValue())
Console.WriteLine("{0}, {1}, {2}", item.A, item.B, item.C);
}
////Print all values
//foreach (var itemTruthRow in myTruthTable)
//{
// Console.WriteLine("{0}, {1}, {2}", itemTruthRow.A, itemTruthRow.B, itemTruthRow.C);
//}
////Print only false values
//foreach (var item in myTruthTable)
//{
// if (!item.GetTruthValue())
// Console.WriteLine("{0}, {1}, {2}", item.A, item.B, item.C);
//}
Console.ReadLine();
}
public static IEnumerable<MyCustomThreeItemTruthRow> GenerateTruthTable()
{
for (var a = 0; a < 2; a++)
for (var b = 0; b < 2; b++)
for (var c = 0; c < 2; c++)
yield return new MyCustomThreeItemTruthRow(
Convert.ToBoolean(a),
Convert.ToBoolean(b),
Convert.ToBoolean(c));
}
}
EDIT (included sample code for WinForm):
Use and pass the classes above (ThreeItemTruthRow and MyCustomThreeItemTruthRow).
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void GenerateButton_Click(object sender, EventArgs e)
{
OutputTextBox.Clear();
OutputTextBox.Text += "A\tB\tC\r\n";
OutputTextBox.Text += GetHorizontalLineText();
var myTruthTable = GenerateTruthTable().ToList();
foreach(var item in myTruthTable)
{
OutputTextBox.Text += GetFormattedItemText(item);
OutputTextBox.Text += GetHorizontalLineText();
}
}
private void ShowTrueValuesButton_Click(object sender, EventArgs e)
{
OutputTextBox.Clear();
OutputTextBox.Text += "True Values\r\n";
OutputTextBox.Text += "A\tB\tC\r\n";
OutputTextBox.Text += GetHorizontalLineText();
var myTruthTable = GenerateTruthTable().ToList();
foreach(var item in myTruthTable)
{
if(item.GetTruthValue())
OutputTextBox.Text += GetFormattedItemText(item);
}
}
private static string GetHorizontalLineText()
{
return "-----------------------------------------------\r\n";
}
private static string GetFormattedItemText(MyCustomThreeItemTruthRow item)
{
return string.Format("{0}\t{1}\t{2}\r\n", item.A, item.B, item.C);
}
private static IEnumerable<MyCustomThreeItemTruthRow> GenerateTruthTable()
{
for (var a = 0; a < 2; a++)
for (var b = 0; b < 2; b++)
for (var c = 0; c < 2; c++)
yield return new MyCustomThreeItemTruthRow(
Convert.ToBoolean(a),
Convert.ToBoolean(b),
Convert.ToBoolean(c));
}
}
source to share
Create a class that will hold the sensor inputs and output the result:
public class SensorInput
{
public SensorInput(bool a, bool b, bool c)
{
A = a;
B = b;
C = c;
}
public bool A { get; private set; }
public bool B { get; private set; }
public bool C { get; private set; }
public bool Output
{
// output logic goes here
get { return A || B || C; }
}
}
Then bind the list of inputs to the DataGridView control:
var inputs = new List<SensorInput>()
{
new SensorInput(true, true, true),
new SensorInput(true, true, false),
new SensorInput(true, false, true),
new SensorInput(true, false, false),
new SensorInput(false, true, true),
new SensorInput(false, true, false),
new SensorInput(false, false, true),
new SensorInput(false, false, false)
};
dataGridView1.DataSource = inputs;
By default, booleans are bound to CheckBoxColumns. If you want True / False as text, add four columns manually. Select their types as (read-only) TextBoxColumns and provide the property names to bind. The result will look like this:
You can use Linq to filter a table with a result equal to true. Like this:
dataGridView1.DataSource = inputs.Where(i => i.Output);
source to share
create a couple of classes to store your data.
public class TruthTable {
public TruthTable(int sensorCount) {
if (sensorCount<1 || sensorCount >26) {
throw new ArgumentOutOfRangeException("sensorCount");
}
this.Table=new Sensor[(int)Math.Pow(2,sensorCount)];
for (var i=0; i < Math.Pow(2,sensorCount);i++) {
this.Table[i]=new Sensor(sensorCount);
for (var j = 0; j < sensorCount; j++) {
this.Table[i].Inputs[sensorCount - (j + 1)] = ( i / (int)Math.Pow(2, j)) % 2 == 1;
}
}
}
public Sensor[] Table {get; private set;}
public string LiveOutputs {
get {
return string.Join("\n", Table.Where(x => x.Output).Select(x => x.InputsAsString));
}
}
public string LiveOutPuts2 {
get {
return string.Join(" + ", Table.Where(x => x.Output).Select (x => x.InputsAsString2));
}
}
}
// Define other methods and classes here
public class Sensor {
public Sensor(int sensorCount) {
if (sensorCount<1 || sensorCount >26) {
throw new ArgumentOutOfRangeException("sensorCount");
}
this.SensorCount = sensorCount;
this.Inputs=new bool[sensorCount];
}
private int SensorCount {get;set;}
public bool[] Inputs { get; private set;}
public bool Output {get;set;}
public string InputsAsString {
get {
return string.Join(" ",Inputs.Select(x => x.ToString().ToUpper()));
}
}
public string InputsAsString2 {
get {
var output=new StringBuilder();
for (var i=0; i < this.SensorCount; i++) {
var letter = (char)(i+65);
output.AppendFormat("{0}{1}",Inputs[i] ? "" : "!", letter);
}
return output.ToString();
}
}
}
Then you can instantiate the truth table;
var table = new TruthTable(3);
Then set the corresponding outputs to true
table.Table[3].Output=true;
table.Table[5].Output=true;
table.Table[6].Output=true;
table.Table[7].Output=true;
Then table.LiveOutputs
will give you
FALSE TRUE TRUE
TRUE FALSE TRUE
TRUE TRUE FALSE
TRUE TRUE TRUE
and table.LiveOutputs2
will give you the line
!ABC + A!BC + AB!C + ABC
I used! to indicate false input instead of overline
EDIT --- After a comment about winforms
It's been a long time since I wirtten winforms code, I usually work with WPF.
Some of the code depends on how your form is created if you add the controls at the code level ...
private CheckBox[] checkBoxes;
private TruthTable table;
private int sensors;
//Call this function from the constructor....
void InitForm() {
this.sensors = 3;
this.table= new TruthTable(this.sensors);
this.checkBoxes = new CheckBox[this.sensors];
for (Var i = 0; i < this.sensors; i++) {
this.checkBox[i] = new CheckBox();
// set the positioning of the checkbox - eg this.checkBox[i].Top = 100 + (i * 30);
this.Controls.Add(this.checkBox[i]);
// You can perform similar logic to create a text label control with the sensors in it.
}
}
private void button1_Click(object sender, EventArgs e) {
for (var i=0; i<this.sensors;i++) {
this.table.Table[i].Output = this.checkBoxes[i].IsChecked;
}
this.outputTextBox.Text = this.table.LiveOutputs2;
}
source to share