def parse_facts(string): facts = parse_theory_string(string)['facts'] facts = map(desugar_expr, facts) for fact in facts: for var in fact.vars: assert len(var.name) > 2, 'unbound variable: {}'.format(var) return facts
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 test_parse_theory_string(filename): with open(filename) as f: string = f.read() parser.parse_theory_string(string)
def _test_parse_theory_string(filename): with open(filename) as f: parser.parse_theory_string(f.read())