How to resolve the algorithm Truth table step by step in the Go programming language

Published on 12 May 2024 09:40 PM
#Go

How to resolve the algorithm Truth table step by step in the Go programming language

Table of Contents

Problem Statement

A truth table is a display of the inputs to, and the output of a Boolean function organized as a table where each row gives one combination of input values and the corresponding value of the function.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Truth table step by step in the Go programming language

The program above implements a truth table generator for boolean expressions. It does so by parsing a user input expression using the go/parser library, and then evaluating the truth table by recursively assigning boolean values to the variables in the expression and evaluating the result.

The main function initialises a buffered scanner to read user input, and a loop to continuously prompt the user for an expression. For each input expression, the tt function is called to generate the truth table.

The tt function first parses the expression using the parser.ParseExpr function, and then creates an evaluator object to encapsulate the parsed expression, the set of variable names, and a map of variable names to boolean values. The evaluator object implements the ast.Visitor interface, which allows it to be used as a visitor function for the ast.Walk function. The ast.Walk function traverses the parsed expression tree, calling the evaluator's Visit method for each node. The Visit method adds the variable name to the evaluator's set of variable names if it is not already present.

After the ast.Walk function has completed, the evaluator's evalVar method is called to generate the truth table. The evalVar method recursively assigns boolean values to the variables in the expression, and evaluates the expression for each combination of values. The result of each evaluation is printed to the console, along with the corresponding combination of variable values.

The evalNode function recursively evaluates the ast expression tree, based on the values assigned to the variables by the evalVar method. It supports binary expressions (AND, OR, XOR), unary expressions (NOT), and parentheses. If an unsupported expression is encountered, an error is returned.

Source code in the go programming language

package main

import (
    "bufio"
    "errors"
    "fmt"
    "go/ast"
    "go/parser"
    "go/token"
    "os"
    "reflect"
)

func main() {
    in := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("Expr:  ")
        in.Scan()
        if err := in.Err(); err != nil {
            fmt.Println(err)
            return
        }
        if !tt(in.Text()) {
            return
        }
    }
}

func tt(expr string) bool {
    // call library parser
    tree, err := parser.ParseExpr(expr)
    if err != nil {
        fmt.Println(err)
        return false
    }
    // create handy object to pass around
    e := &evaluator{nil, map[string]bool{}, tree}
    // library tree traversal function calls e.Visit for each node.
    // use this to collect variables of the expression.
    ast.Walk(e, tree)
    // print headings for truth table
    for _, n := range e.names {
        fmt.Printf("%-6s", n)
    }
    fmt.Println(" ", expr)
    // start recursive table generation function on first variable
    e.evalVar(0)
    return true
}

type evaluator struct {
    names []string        // variables, in order of appearance
    val   map[string]bool // map variables to boolean values
    tree  ast.Expr        // parsed expression as ast
}

// visitor function called by library Walk function.
// builds a list of unique variable names.
func (e *evaluator) Visit(n ast.Node) ast.Visitor {
    if id, ok := n.(*ast.Ident); ok {
        if !e.val[id.Name] {
            e.names = append(e.names, id.Name)
            e.val[id.Name] = true
        }
    }
    return e
}

// method recurses for each variable of the truth table, assigning it to
// false, then true.  At bottom of recursion, when all variables are
// assigned, it evaluates the expression and outputs one line of the
// truth table
func (e *evaluator) evalVar(nx int) bool {
    if nx == len(e.names) {
        // base case
        v, err := evalNode(e.tree, e.val)
        if err != nil {
            fmt.Println(" ", err)
            return false
        }
        // print variable values
        for _, n := range e.names {
            fmt.Printf("%-6t", e.val[n])
        }
        // print expression value
        fmt.Println(" ", v)
        return true
    }
    // recursive case
    for _, v := range []bool{false, true} {
        e.val[e.names[nx]] = v
        if !e.evalVar(nx + 1) {
            return false
        }
    }
    return true
}

// recursively evaluate ast
func evalNode(nd ast.Node, val map[string]bool) (bool, error) {
    switch n := nd.(type) {
    case *ast.Ident:
        return val[n.Name], nil
    case *ast.BinaryExpr:
        x, err := evalNode(n.X, val)
        if err != nil {
            return false, err
        }
        y, err := evalNode(n.Y, val)
        if err != nil {
            return false, err
        }
        switch n.Op {
        case token.AND:
            return x && y, nil
        case token.OR:
            return x || y, nil
        case token.XOR:
            return x != y, nil
        default:
            return unsup(n.Op)
        }
    case *ast.UnaryExpr:
        x, err := evalNode(n.X, val)
        if err != nil {
            return false, err
        }
        switch n.Op {
        case token.XOR:
            return !x, nil
        default:
            return unsup(n.Op)
        }
    case *ast.ParenExpr:
        return evalNode(n.X, val)
    }
    return unsup(reflect.TypeOf(nd))
}

func unsup(i interface{}) (bool, error) {
    return false, errors.New(fmt.Sprintf("%v unsupported", i))
}


  

You may also check:How to resolve the algorithm Concurrent computing step by step in the Mathematica / Wolfram Language programming language
You may also check:How to resolve the algorithm Unbias a random generator step by step in the C# programming language
You may also check:How to resolve the algorithm Host introspection step by step in the Julia programming language
You may also check:How to resolve the algorithm Ackermann function step by step in the PostScript programming language
You may also check:How to resolve the algorithm Tokenize a string step by step in the LDPL programming language