+1 (315) 557-6473 

Read A Text File Describing A Digital Logic Circuit And Output The Truth Table For Circuit Assignment Solution.


Instructions

Objective
Write a program to read a text file that describes a digital logic circuit and output the truth table for the circuit.

Requirements and Specifications

Your program should take a single command line argument specifying the path to an input file. The input file is a digital circuit description that lists how many input and output variables are in the circuit, the names of the input and output variables, and digital logic gates that describe how the output variables relate to the input variables.
  • The first line of the file will look like this: "INPUTVAR 2 input0 input1". The number N indicates the number of Boolean input variables to the digital logic circuit. In this case N=2. The rest of the line lists the names of the input variables, separated by spaces.
  • The second line of the file will look like this: "OUTPUTVAR 1 output0". The number M indicates the number of Boolean output variables from the digital logic circuit. In this case M=1. The rest of line lists the names of the output variables, separated by spaces.
  • The remainder of the file will have lines describing digital logic gates. The gates have either a single input or two inputs:
  • Single input gates include the "NOT" gate. A line describing such a gate will look like this: "NOT input0 temp0". This means the Boolean value of temp0 = ! input0. The intermediate Boolean variable temp0 is a variable in the circuit that is neither part of the inputs nor outputs of the digital circuit, but you need to keep track of temp0's value to calculate the circuit's truth table.
  • Double input gates include the "AND", "NAND", "OR", "NOR", "XOR", and "XNOR" gates. A line describing such a gate will like this: "XNOR input1 temp0 output0". This means the Boolean value of output0 = input1 XNOR temp0.
For 2 inputs
The input format for the previous part, basicGates, carries over, with these important differences:
  • Instead of double input gates, the input files now have multi-input gates that include the "AND", "NAND", "OR", and "NOR" gates. A line describing such a gate will like this: "AND 3 input1 input0 input1 temp0". The second entry on the line indicates that this AND gate takes three inputs, which are immediately listed before listing the single output variable. This means the Boolean value of temp0 = input1 AND input0 AND input1.
  • The input files will no longer have "XOR" and "XNOR" gates as these gates do not have a strict definition for multiple inputs.
Screenshots of output
program to read logic gates and print truth table in python


program to read logic gates and print truth table in python 1


program to read logic gates and print truth table in python 2


program to read logic gates and print truth table in python 3


program to read logic gates and print truth table in python 4


program to read logic gates and print truth table in python 5

Source Code

Basic Gates

#!/usr/bin/python3

import os 

import datetime

import random

import subprocess

def generate_test ( filenum, inCount=1, gateCount=0, outCount=1, path="./" ):

    inVars = [ "input"+str(i) for i in range(inCount) ]

    gates = ("NOT", "AND", "NAND", "OR", "NOR", "XOR", "XNOR")

    tempCount = 0

    tempVars = inVars.copy()

    circuit = []

    outVars = []

    for i in range(gateCount):

        in0 = random.choice(tempVars)

        in1 = random.choice(tempVars)

        gate = random.choice(gates)

        out = "temp"+str(tempCount)

        tempCount += 1

        circuit.append({ "in0":in0, "in1":in1, "gate":gate, "out":out })

        tempVars.append(out)

        for i in range(outCount):

        in0 = random.choice(tempVars)

        in1 = random.choice(tempVars)

        gate = random.choice(gates)

        out = "output"+str(i)

        circuit.append({ "in0":in0, "in1":in1, "gate":gate, "out":out })

        outVars.append(out)

        with open("{}tests/test{}.txt".format(path,filenum), "w") as infile:

         infile.write("INPUTVAR {}".format(inCount))

        for inVar in inVars:

            infile.write(" "+inVar)

        infile.write("\n")

        infile.write("OUTPUTVAR {}".format(outCount))

        for outVar in outVars:

            infile.write(" "+outVar)

        infile.write("\n")

        for gate in circuit:

            if gate["gate"] is "NOT":

                infile.write( "NOT {} {}\n".format( gate["in0"], gate["out"] ) )

            else:

                infile.write( "{} {} {} {}\n".format( gate["gate"], gate["in0"], gate["in1"], gate["out"] ) )

                with open("{}answers/answer{}.txt".format(path,filenum), "w") as outfile:

                for i in range(2**inCount):

            state = {}

            for bit, inVar in enumerate(inVars):

                state[inVar] = bool(1&i>>bit)

               for gate in circuit:

                inState0 = state[gate["in0"]]

                inState1 = state[gate["in1"]]

                if gate["gate"] is "NOT":

                    outState = not inState0

                elif gate["gate"] is "AND":

                    outState = inState0 and inState1

                elif gate["gate"] is "NAND":

                    outState = not(inState0 and inState1)

                elif gate["gate"] is "OR":

                    outState = inState0 or inState1

                elif gate["gate"] is "NOR":

                    outState = not(inState0 or inState1)

                elif gate["gate"] is "XOR":

                    outState = inState0!=inState1

                elif gate["gate"] is "XNOR":

                    outState = inState0==inState1

                else:

                    error()

                state[gate["out"]] = outState

            for inVar in inVars:

                outfile.write("{} ".format(int(state[inVar])))

            for outVar in outVars:

                outfile.write("{} ".format(int(state[outVar])))

            outfile.write("\n")

def generate_test_suite():

    os.makedirs("tests", exist_ok=True)

    os.makedirs("answers", exist_ok=True)

    generate_test ( 0, inCount=1, gateCount=0, outCount=1, path="./" )

    generate_test ( 1, inCount=2, gateCount=1, outCount=1, path="./" )

    generate_test ( 2, inCount=2, gateCount=2, outCount=2, path="./" )

    generate_test ( 3, inCount=2, gateCount=4, outCount=2, path="./" )

    generate_test ( 4, inCount=4, gateCount=8, outCount=4, path="./" )

    generate_test ( 5, inCount=4, gateCount=16, outCount=4, path="./" )

def test_basicGates ( filenum, path="./", verbose=False ):

    try:

        with open("{}answers/answer{}.txt".format(path,filenum), "r") as outfile:

            answerSet = set()

            for line in outfile.read().split("\n"):

                row = []

                for string in line.split(" "):

                    if string is not "":

                        row.append(int(string))

                if line is not "":

                    answerSet.add(tuple(row))

    except EnvironmentError: # parent of IOError, OSError

        print ("answers/answer{}.txt missing".format(filenum))

    try:

        result = subprocess.run(

            ["./basicGates", "tests/test{}.txt".format(filenum)],

            cwd=path,

            check=True,

            stdout=subprocess.PIPE,

            stderr=subprocess.STDOUT,

            encoding="ASCII",

            timeout=datetime.timedelta(seconds=4).total_seconds(),

        )

        resultSet = set()

        for line in result.stdout.split("\n"):

            row = []

            for string in line.split(" "):

                if string is not "":

                    row.append(int(string))

            if line is not "":

                resultSet.add(tuple(row))

        if verbose:

            print (' '.join(result.args))

            # print ("answer")

            # print (answerSet)

            # print ("result")

            # print (result.stdout)

        assert resultSet == answerSet, "The circuit simulation result doesn't match answers/answer{}.txt.".format(filenum)

        return True

    except subprocess.CalledProcessError as e:

        print (e.output)

        print ("Calling ./basicGates returned non-zero exit status.")

    except ValueError as e:

        print (result.stdout)

        print ("Please check your output formatting.")

    except AssertionError as e:

        print (result.stdout)

        print (e.args[0])

    return False

def grade_basicGates( path="./", verbose=False ):

    score = 0

    try:

        subprocess.run( ["make", "-B"], cwd=path, check=True, )

    except subprocess.CalledProcessError as e:

        print ("Couldn't compile basicGates.")

        return score

    if test_basicGates(0,path,verbose):

        score += 5

        if test_basicGates(1,path,verbose):

            score += 5

            if test_basicGates(2,path,verbose):

                score += 5

                if test_basicGates(3,path,verbose):

                    score+= 5

                    if test_basicGates(4,path,verbose):

                        score += 5

                        if test_basicGates(5,path,verbose):

                            score += 5

                            for filenum in range(6,16):

                                generate_test ( filenum, inCount=8, gateCount=16, outCount=8, path=path )

                                if test_basicGates(filenum,path,verbose):

                                    score += 1

                                else:

                                    break

    print ("Score on basicGates: {} out of 40.".format(score))

    return score

if __name__ == '__main__':

    # generate_test_suite()

    grade_basicGates(verbose=True)

    exit()

Multi Input

#!/usr/bin/python3

import os

import datetime

import random

import subprocess

def generate_test ( filenum, circuitInCount=1, gateInMax=4, gateCount=0, circuitOutCount=1, path="./" ):

    inVars = [ "input"+str(i) for i in range(circuitInCount) ]

    gates = ("NOT", "AND", "NAND", "OR", "NOR")

    tempCount = 0

    tempVars = inVars.copy()

    circuit = []

    outVars = []

    for i in range(gateCount):

        gate = random.choice(gates)

        if gate is "NOT":

            gateInCount = 1

        elif gate in ("AND", "NAND", "OR", "NOR"):

            gateInCount = random.randint(2,gateInMax)

        gateIn = random.choices(tempVars,k=gateInCount)

        gateOut = "temp"+str(tempCount)

        tempCount += 1

        circuit.append({ "inCount":gateInCount, "gateIn":gateIn, "gate":gate, "gateOut":gateOut })

        tempVars.append(gateOut)

    for i in range(circuitOutCount):

        gate = random.choice(gates)

        if gate is "NOT":

            gateInCount = 1

        elif gate in ("AND", "NAND", "OR", "NOR"):

            gateInCount = random.randint(2,gateInMax)

        gateIn = random.choices(tempVars,k=gateInCount)

        gateOut = "output"+str(i)

        circuit.append({ "inCount":gateInCount, "gateIn":gateIn, "gate":gate, "gateOut":gateOut })

        outVars.append(gateOut)

    with open("{}tests/test{}.txt".format(path,filenum), "w") as infile:

        infile.write("INPUTVAR {}".format(circuitInCount))

        for inVar in inVars:

            infile.write(" "+inVar)

        infile.write("\n")

        infile.write("OUTPUTVAR {}".format(circuitOutCount))

        for outVar in outVars:

            infile.write(" "+outVar)

        infile.write("\n")

        for gate in circuit:

            if gate["gate"] is "NOT":

                infile.write( "NOT {} {}\n".format( ' '.join(map(str, gate["gateIn"])), gate["gateOut"] ) )

            else:

                infile.write( "{} {} {} {}\n".format( gate["gate"], gate["inCount"], ' '.join(map(str, gate["gateIn"])), gate["gateOut"] ) )

    with open("{}answers/answer{}.txt".format(path,filenum), "w") as outfile:

        for i in range(2**circuitInCount):

            state = {}

            for bit, inVar in enumerate(inVars):

                state[inVar] = bool(1&i>>bit)

            for gate in circuit:

                inStates = [ state[gateIn] for gateIn in gate["gateIn"] ]

                if gate["gate"] is "NOT":

                    outState = not inStates[0]

                elif gate["gate"] is "AND":

                    outState = True

                    for inState in inStates:

                        outState = outState and inState

                elif gate["gate"] is "NAND":

                    outState = True

                    for inState in inStates:

                        outState = outState and inState

                    outState = not outState

                elif gate["gate"] is "OR":

                    outState = False

                    for inState in inStates:

                        outState = outState or inState

                elif gate["gate"] is "NOR":

                    outState = False

                    for inState in inStates:

                        outState = outState or inState

                    outState = not outState

                else:

                    sys.exit("Invalid gate.")

                state[gate["gateOut"]] = outState

            for inVar in inVars:

                outfile.write("{} ".format(int(state[inVar])))

            for outVar in outVars:

                outfile.write("{} ".format(int(state[outVar])))

            outfile.write("\n")

def generate_test_suite():

    os.makedirs("tests", exist_ok=True)

    os.makedirs("answers", exist_ok=True)

    generate_test ( 0, circuitInCount=1, gateInMax=2, gateCount=0, circuitOutCount=1, path="./" )

    generate_test ( 1, circuitInCount=2, gateInMax=2, gateCount=1, circuitOutCount=1, path="./" )

    generate_test ( 2, circuitInCount=2, gateInMax=3, gateCount=2, circuitOutCount=2, path="./" )

    generate_test ( 3, circuitInCount=2, gateInMax=4, gateCount=4, circuitOutCount=2, path="./" )

    generate_test ( 4, circuitInCount=4, gateInMax=5, gateCount=8, circuitOutCount=4, path="./" )

    generate_test ( 5, circuitInCount=4, gateInMax=6, gateCount=16, circuitOutCount=4, path="./" )

def test_multiInput ( filenum, path="./", verbose=False ):

    try:

        with open("{}answers/answer{}.txt".format(path,filenum), "r") as outfile:

            answerSet = set()

            for line in outfile.read().split("\n"):

                row = []

                for string in line.split(" "):

                    if string is not "":

                        row.append(int(string))

                if line is not "":

                    answerSet.add(tuple(row))

    except EnvironmentError: # parent of IOError, OSError

        print ("answers/answer{}.txt missing".format(filenum))

    try:

        result = subprocess.run(

            ["./multiInput", "tests/test{}.txt".format(filenum)],

            cwd=path,

            check=True,

            stdout=subprocess.PIPE,

            stderr=subprocess.STDOUT,

            encoding="ASCII",

            timeout=datetime.timedelta(seconds=4).total_seconds(),

        )

        resultSet = set()

        for line in result.stdout.split("\n"):

            row = []

            for string in line.split(" "):

                if string is not "":

                    row.append(int(string))

            if line is not "":

                resultSet.add(tuple(row))

        if verbose:

            print (' '.join(result.args))

            # print ("answer")

            # print (answerSet)

            # print ("result")

            # print (result.stdout)

        assert resultSet == answerSet, "The circuit simulation result doesn't match answers/answer{}.txt.".format(filenum)

        return True

    except subprocess.CalledProcessError as e:

        print (e.output)

        print ("Calling ./multiInput returned non-zero exit status.")

    except ValueError as e:

        print (result.stdout)

        print ("Please check your output formatting.")

    except AssertionError as e:

        print (result.stdout)

        print (e.args[0])

    return False

def grade_multiInput( path="./", verbose=False ):

    score = 0

    try:

        subprocess.run( ["make", "-B"], cwd=path, check=True, )

    except subprocess.CalledProcessError as e:

        print ("Couldn't compile multiInput.")

        return score

    if test_multiInput(0,path,verbose):

        score += 5

        if test_multiInput(1,path,verbose):

            score += 5

            if test_multiInput(2,path,verbose):

                score += 5

                if test_multiInput(3,path,verbose):

                    score+= 5

                    if test_multiInput(4,path,verbose):

                        score += 5

                        if test_multiInput(5,path,verbose):

                            score += 5

                            for filenum in range(6,16):

                                generate_test ( filenum, circuitInCount=8, gateInMax=8, gateCount=16, circuitOutCount=8, path=path )

                                if test_multiInput(filenum,path,verbose):

                                    score += 1

                                else:

                                    break

    print ("Score on multiInput: {} out of 0. (extra credit)".format(score))

    return score

if __name__ == '__main__':

    # generate_test_suite()

    grade_multiInput(verbose=True)

    exit()