def pl_true(exp, model={}):
op, args = exp.op, exp.args<EOL>if exp == TRUE:<EOL><INDENT>return True<EOL><DEDENT>elif exp == FALSE:<EOL><INDENT>return False<EOL><DEDENT>elif is_prop_symbol(op):<EOL><INDENT>return model.get(exp)<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>p = pl_true(args[<NUM_LIT:0>], model)<EOL>if p is None: return None<EOL>else: return not p<EOL><DEDENT>elif op == '<STR_LIT:|>':<EOL><INDENT>result = False<EOL>for arg in args:<EOL><INDENT>p = pl_true(arg, model)<EOL>if p is True: return True<EOL>if p is None: result = None<EOL><DEDENT>return result<EOL><DEDENT>elif op == '<STR_LIT:&>':<EOL><INDENT>result = True<EOL>for arg in args:<EOL><INDENT>p = pl_true(arg, model)<EOL>if p is False: return False<EOL>if p is None: result = None<EOL><DEDENT>return result<EOL><DEDENT>p, q = args<EOL>if op == '<STR_LIT>':<EOL><INDENT>return pl_true(~p | q, model)<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>return pl_true(p | ~q, model)<EOL><DEDENT>pt = pl_true(p, model)<EOL>if pt is None: return None<EOL>qt = pl_true(q, model)<EOL>if qt is None: return None<EOL>if op == '<STR_LIT>':<EOL><INDENT>return pt == qt<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>return pt != qt<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>" + str(exp))<EOL><DEDENT>
Return True if the propositional logic expression is true in the model,
    and False if it is false. If the model does not specify the value for
    every proposition, this may return None to indicate 'not obvious';
    this may happen even when the expression is tautological.