Building truth tables

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • andrea

    Building truth tables

    Well I would like to make a little program that given a certain
    logical expression gives the complete truth table.

    It's not too difficult in fact, I just have some doubts on how to
    design it.

    I thought something like that:

    class Term:

    class Table:

    def and(...
    def or(...


    But I'm not convinced...
    I would like something like that more or less:
    a,b,c = Term()

    table([a,b,c], impl(and(or(a,b )),c))

    Any idea??
    Thanks
  • Tim Rowe

    #2
    Re: Building truth tables

    2008/9/26 andrea <kerny404@gmail .com>:
    Well I would like to make a little program that given a certain
    logical expression gives the complete truth table.
    >
    It's not too difficult in fact, I just have some doubts on how to
    design it.
    >
    I thought something like that:
    >
    class Term:
    >
    class Table:
    >
    def and(...
    def or(...
    As a quick and dirty solution, I'd write a function that takes a
    function as a parameter.

    Starting with a helper function to separate the bits of an integer
    into a list of bools:

    def int_to_bool(i, bits):
    # Extract the bits of i to a boolean array.
    # 'bits' is the number of signifcant bits.
    result = []
    for j in range(0, bits):
    result.append(i & 1)
    i >>= 1
    result.reverse( )
    return result

    Now I'd define a function such as:
    def table(f, n):
    # Calculate a truth table for function f taking n boolean parameters
    result = []
    for i in range(0, math.pow(2, n)):
    for j in range(0, n):
    params = int_to_bool(i, n)
    result.append(p arams + [(f(*params))])
    return result

    Now you could define the function you want as a separate function, or
    just use a lambda:

    table(lambda a, b, c:(a or b) and c, 3)
    [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 1, 1, 1], [1, 0, 0, 0],
    [1, 0, 1, 1], [1, 1, 0, 0], [1, 1, 1, 1]]

    Each element in the result is the state of the parameters followed by
    the result of the function.

    I stress that this is quick and dirty -- I'm sure somebody will be
    along with something better soon!


    --
    Tim Rowe

    Comment

    • Aaron \Castironpi\ Brady

      #3
      Re: Building truth tables

      On Sep 26, 11:40 am, "Tim Rowe" <digi...@gmail. comwrote:
      2008/9/26 andrea <kerny...@gmail .com>:
      >
      Well I would like to make a little program that given a certain
      logical expression gives the complete truth table.
      >
      It's not too difficult in fact, I just have some doubts on how to
      design it.
      >
      I thought something like that:
      >
      class Term:
      >
      class Table:
      >
        def and(...
        def or(...
      >
      As a quick and dirty solution, I'd write a function that takes a
      function as a parameter.
      >
      Starting with a helper function to separate the bits of an integer
      into a list of bools:
      >
      def int_to_bool(i, bits):
              # Extract the bits of i to a boolean array.
              # 'bits' is the number of signifcant bits.
              result = []
              for j in range(0, bits):
                      result.append(i & 1)
                      i >>= 1
              result.reverse( )
              return result
      >
      Now I'd define a function such as:
      def table(f, n):
              # Calculate a truth table for function f taking n booleanparamete rs
              result = []
              for i in range(0, math.pow(2, n)):
                      for j in range(0, n):
                              params = int_to_bool(i,n )
                      result.append(p arams + [(f(*params))])
              return result
      >
      Now you could define the function you want as a separate function, or
      just use a lambda:
      >
      table(lambda a, b, c:(a or b) and c, 3)
      [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 1, 1, 1], [1, 0, 0, 0],
      [1, 0, 1, 1], [1, 1, 0, 0], [1, 1, 1, 1]]
      >
      Each element in the result is the state of the parameters followed by
      the result of the function.
      >
      I stress that this is quick and dirty -- I'm sure somebody will be
      along with something better soon!
      >
      --
      Tim Rowe
      Good idea. If you want prefixed operators: 'and( a, b )' instead of
      'a and b', you'll have to write your own. ('operator.and_ ' is bitwise
      only.) It may be confusing to mix prefix with infix: 'impl( a and b,
      c )', so you may want to keep everything prefix, but you can still use
      table( f, n ) like Tim said.

      Comment

      • andrea

        #4
        Re: Building truth tables

        On 26 Set, 20:01, "Aaron \"Castironpi \" Brady" <castiro...@gma il.com>
        wrote:
        >
        Good idea.  If you want prefixed operators: 'and( a, b )' instead of
        'a and b', you'll have to write your own.  ('operator.and_ ' is bitwise
        only.)  It may be confusing to mix prefix with infix: 'impl( a and b,
        c )', so you may want to keep everything prefix, but you can still use
        table( f, n ) like Tim said.
        After a while I'm back, thanks a lot, the truth table creator works,
        now I just want to parse some strings to make it easier to use.

        Like

        (P \/ Q) -S == S

        Must return a truth table 2^3 lines...

        I'm using pyparsing and this should be really simple, but it doesn't
        allow me to recurse and that makes mu stuck.
        The grammar BNF is:

        Var :: = [A..Z]
        Exp ::= Var | !Exp | Exp \/ Exp | Exp -Exp | Exp /\ Exp | Exp ==
        Exp

        I tried different ways but I don't find a smart way to get from the
        recursive bnf grammar to the implementation in pyparsing...
        Any hint?

        Comment

        • Paul McGuire

          #5
          Re: Building truth tables

          On Oct 24, 5:53 am, andrea <kerny...@gmail .comwrote:
          On 26 Set, 20:01, "Aaron \"Castironpi \" Brady" <castiro...@gma il.com>
          wrote:
          >
          >
          >
          Good idea.  If you want prefixed operators: 'and( a, b )' instead of
          'a and b', you'll have to write your own.  ('operator.and_ ' is bitwise
          only.)  It may be confusing to mix prefix with infix: 'impl( a and b,
          c )', so you may want to keep everything prefix, but you can still use
          table( f, n ) like Tim said.
          >
          After a while I'm back, thanks a lot, the truth table creator works,
          now I just want to parse some strings to make it easier to use.
          >
          Like
          >
          (P \/ Q) -S == S
          >
          Must return a truth table 2^3 lines...
          >
          I'm using pyparsing and this should be really simple, but it doesn't
          allow me to recurse and that makes mu stuck.
          The grammar BNF is:
          >
          Var :: = [A..Z]
          Exp ::= Var | !Exp  | Exp \/ Exp | Exp -Exp | Exp /\ Exp | Exp ==
          Exp
          >
          I tried different ways but I don't find a smart way to get from the
          recursive bnf grammar to the implementation in pyparsing...
          Any hint?
          Use Forward to create a recursive grammar. Look at the examples page
          on the pyparsing wiki, and there should be several samples of
          recursive grammars.

          Here is a very simple recursive grammar, with no precedence to your
          operators:

          from pyparsing import oneOf, alphas, Forward, ZeroOrMore, Group,
          Optional
          var = oneOf(list(alph as))
          op = oneOf(r"\/ /\ -==")
          expr = Forward()
          expr << Optional('!') + ( var | Group('(' + expr + ')') ) +
          ZeroOrMore(op + expr)

          test = "(P \/ Q) -S == S"

          print expr.parseStrin g(test).asList( )

          prints:

          [['(', 'P', '\\/', 'Q', ')'], '->', 'S', '==', 'S']


          Since these kinds of expressions are common, pyparsing includes a
          helper method for defining precedence of operations infix notation:

          from pyparsing import operatorPrecede nce, opAssoc

          expr = operatorPrecede nce(var,
          [
          (r'!', 1, opAssoc.RIGHT),
          (r'\/', 2, opAssoc.LEFT),
          (r'/\\', 2, opAssoc.LEFT),
          (r'->', 2, opAssoc.LEFT),
          (r'==', 2, opAssoc.LEFT),
          ])

          print expr.parseStrin g(test).asList( )

          prints:

          [[[['P', '\\/', 'Q'], '->', 'S'], '==', 'S']]

          HTH,
          -- Paul

          Comment

          • Aaron Brady

            #6
            Re: Building truth tables

            On Oct 24, 5:53 am, andrea <kerny...@gmail .comwrote:
            On 26 Set, 20:01, "Aaron \"Castironpi \" Brady" <castiro...@gma il.com>
            wrote:
            >
            >
            >
            Good idea.  If you want prefixed operators: 'and( a, b )' instead of
            'a and b', you'll have to write your own.  ('operator.and_ ' is bitwise
            only.)  It may be confusing to mix prefix with infix: 'impl( a and b,
            c )', so you may want to keep everything prefix, but you can still use
            table( f, n ) like Tim said.
            >
            After a while I'm back, thanks a lot, the truth table creator works,
            now I just want to parse some strings to make it easier to use.
            >
            Like
            >
            (P \/ Q) -S == S
            >
            Must return a truth table 2^3 lines...
            >
            I'm using pyparsing and this should be really simple, but it doesn't
            allow me to recurse and that makes mu stuck.
            The grammar BNF is:
            >
            Var :: = [A..Z]
            Exp ::= Var | !Exp  | Exp \/ Exp | Exp -Exp | Exp /\ Exp | Exp ==
            Exp
            >
            I tried different ways but I don't find a smart way to get from the
            recursive bnf grammar to the implementation in pyparsing...
            Any hint?
            Tell you what. At the risk of "carrot-and-stick, jump-how-high"
            tyranny, I'll show you some output of a walk-through. It should give
            you an idea of the process. You can always ask for more hints.

            ( ( ( !( R ) /\ ( !( P \/ Q ) ) ) -S ) == S )
            (((!(R)/\(!(P\/Q)))->S)==S)
            (((!R/\(!(P\/Q)))->S)==S)
            n1 := !R
            (((n1/\(!(P\/Q)))->S)==S)
            n2 := P\/Q
            (((n1/\(!(n2)))->S)==S)
            (((n1/\(!n2))->S)==S)
            n3 := !n2
            (((n1/\(n3))->S)==S)
            (((n1/\n3)->S)==S)
            n4 := n1/\n3
            (((n4)->S)==S)
            ((n4->S)==S)
            n5 := n4->S
            ((n5)==S)
            (n5==S)
            n6 := n5==S
            (n6)
            n6
            {'n1': (<function not_ at 0x00A04070>, '!R', ('R',)),
            'n2': (<function or_ at 0x00A040F0>, 'P\\/Q', ('P', 'Q')),
            'n3': (<function not_ at 0x00A04070>, '!n2', ('n2',)),
            'n4': (<function and_ at 0x00A040B0>, 'n1/\\n3', ('n1', 'n3')),
            'n5': (<function imp_ at 0x00A04130>, 'n4->S', ('n4', 'S')),
            'n6': (<function eq_ at 0x00A04170>, 'n5==S', ('n5', 'S'))}
            {'Q': True, 'P': True, 'S': True, 'R': True} True
            {'Q': True, 'P': True, 'S': False, 'R': True} False
            {'Q': True, 'P': True, 'S': True, 'R': False} True
            {'Q': True, 'P': True, 'S': False, 'R': False} False
            {'Q': False, 'P': True, 'S': True, 'R': True} True
            {'Q': False, 'P': True, 'S': False, 'R': True} False
            {'Q': False, 'P': True, 'S': True, 'R': False} True
            {'Q': False, 'P': True, 'S': False, 'R': False} False
            {'Q': True, 'P': False, 'S': True, 'R': True} True
            {'Q': True, 'P': False, 'S': False, 'R': True} False
            {'Q': True, 'P': False, 'S': True, 'R': False} True
            {'Q': True, 'P': False, 'S': False, 'R': False} False
            {'Q': False, 'P': False, 'S': True, 'R': True} True
            {'Q': False, 'P': False, 'S': False, 'R': True} False
            {'Q': False, 'P': False, 'S': True, 'R': False} True
            {'Q': False, 'P': False, 'S': False, 'R': False} True

            Before you trust me too much, you might want to check at least some of
            these, to see if the starting (complicated) expression is evaluated
            correctly. I didn't.

            Comment

            Working...