Reputation:
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
}
}
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
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
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
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:
For filtering table by output equal to true you can use Linq. Like this:
dataGridView1.DataSource = inputs.Where(i => i.Output);
Upvotes: 0