user1261800
user1261800

Reputation:

Boolean logic/truth tables and outputs

I am currently trying to replicate a way of converting truth tables into Boolean expressions in C#. I have been able to generate a 3 variable (a,b,c) truth table and display it on a multiline textbox. I have created an additional eight textboxes for user to decide for each input’s output: either true(1) or false(0) . But After generating the table how can I then display the all the outputs that have a true value?

public partial class Form1 : Form
{
    public Form1() => InitializeComponent();

    string newLine = Environment.NewLine;
    bool a, b, c, 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
    }
}

enter image description here

enter image description here

Table above is an example. I would like to display true output values somehow like this:

Results Below: FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE False

Upvotes: 2

Views: 12155

Answers (3)

Bob Vale
Bob Vale

Reputation: 18474

create a couple of classes to hold 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();
    }
  }
}

You can then create an instance of truth table;

var table = new TruthTable(3);

Then set the appropriate 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 string

!ABC + A!BC + AB!C + ABC

I've used ! to indicate false input instead of overline

EDIT --- After comment about winforms

It's been a long while since I've wirtten winforms code, I'm usually working with WPF.

Some of the code depends on how your form is generated, if you add your controls at 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;
}

Upvotes: 1

publicgk
publicgk

Reputation: 3191

Try encapsulating your TruthItem (along with the logic to calculate the TruthValue). It would be easy to work with the truth table then (generation, iteration, calculation, etc.)

Here's sample console app. It doesn't have your textboxes, 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 refer 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));
    }
}

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236248

Create class which will hold sensor inputs and produce output:

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 list of inputs to 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 boolean values will be bound to CheckBoxColumns. If you want to have True/False as text, then add four columns manually. Choose their types as (readonly) TextBoxColumns, and provide property names for binding. Result will look like:

DataGridView

For filtering table by output equal to true you can use Linq. Like this:

dataGridView1.DataSource = inputs.Where(i => i.Output);

Upvotes: 0

Related Questions