def simplify_defs(facts, vars_to_keep=set()): """Substitute all facts of form 'EQUAL var closed_term' into remaining facts. In case of multiple equivalent definitions, all combinations of substitutions will be added. This generally reduces the number of free variables. """ facts = set(desugar_expr(f) for f in facts) defs = {} extract_defs_from_facts(facts, defs) changed = True while changed: changed = False for var, bodies in defs.items(): if any(v in defs for b in bodies for v in b.vars): continue # avoid substitution cycles if not any(var in b.vars for bs in defs.itervalues() for b in bs): if not any(var in f.vars for f in facts): continue if var not in vars_to_keep: del defs[var] substitute_bodies(facts, var, bodies) for var2, bodies2 in defs.iteritems(): substitute_bodies(bodies2, var, bodies) extract_defs_from_facts(facts, defs) changed = True for var, bodies in defs.iteritems(): facts.update(EQUAL(var, b) for b in bodies) return facts
def desugar(*exprs): """Convert lambda terms to combinators. Examples: desugar FUN x APP x y desugar FUN x FUN y FUN z APP APP x z APP y z """ for expr in map(parser.parse_string_to_expr, exprs): print expr print ' =', desugar_expr(expr)
def compile_solver(expr, theory): ''' Produces a set of programs that finds values of term satisfying a theory. Inputs: expr - string, an expression with free variables theory - string representing a theory (in .theory format) Outputs: a program to be consumed by the virtual machine Example: expr = 's' theory = """ # 6 constraints = 4 facts + 2 rules LESS APP V s s NLESS x BOT NLESS x I LESS APP s BOT BOT -------------- ---------------- EQUAL APP s I I LESS I APP s x LESS TOP APP s x LESS TOP APP s TOP """ ''' assert isinstance(expr, basestring), expr assert isinstance(theory, basestring), theory expr = desugar_expr(parse_string_to_expr(expr)) assert expr.vars, expr theory = parse_theory_string(theory) facts = map(desugar_expr, theory['facts']) rules = map(desugar_sequent, theory['rules']) sequents = [] can_infer_necessary = not rules and all(f.vars <= expr.vars for f in facts) can_infer_possible = expr.is_var() # TODO generalize to injective exprs if can_infer_necessary: sequents.append(Sequent(facts, [NONEGATE(RETURN(expr))])) if can_infer_possible: fail = NONEGATE(NRETURN(expr)) sequents += [Sequent([], [f, fail]) for f in facts] sequents += [ Sequent(r.antecedents, set_with(r.succedents, fail)) for r in rules ] assert sequents, 'Cannot infer anything' programs = [] write_full_programs(programs, sequents, can_parallelize=False) program = '\n'.join(programs) assert not re.search('FOR_BLOCK', program), 'cannot parallelize' return program
def parse_expr(string): return desugar_expr(parse_string_to_expr(string))
def test_desugar(args): (expr, expected) = args actual = desugar_expr(expr) actual == expected
def desugar(string): expr = parse_string_to_expr(string) expr = desugar_expr(expr) expr = guard_vars(expr) return str(expr)