def test_transformation_of_result(self): mod = Module([Parser.rule("a() --> b where b => 2")]) term = Parser.term("a()") result = Interpreter(mod).interpret(term) self.assertEqual(result, IntTerm(2))
def test_invalid_premise(self): mod = Module([Parser.rule("a() --> b() where 1 == 2")]) term = Parser.term("a()") with self.assertRaises(DynsemError): Interpreter(mod).interpret( term) # does not know where to go when 1 != 2
def test_block(self): mod = Module([Parser.rule("block([x | xs]) --> block(xs)")]) term = Parser.term("block([1, 2, 3, 4])") result = Interpreter(mod).interpret(term) self.assertEqual(result, ApplTerm("block"))
def test_one_transformation(self): mod = Module([Parser.rule("a(x) --> b where x == 1")]) term = Parser.term("a(1)") result = Interpreter(mod).interpret(term) self.assertEqual(result, VarTerm("b"))
def test_header(self): text = """ module trans/runtime/environment """ sut = Parser(text) self.assertEqual(sut.all().name, "trans/runtime/environment")
def test_native(self): add = NativeFunction(Parser.native_function("add(x, y)"), lambda x, y: x + y) mod = Module([Parser.rule("a(x) --> add(x, 1)")], [add]) term = Parser.term("a(1)") result = Interpreter(mod).interpret(term) self.assertEqual(result, IntTerm(2))
def bind(self, term1, term2): self.term1 = Parser.term(term1) # need to do this here because slot assignments are made at the rule level number_of_bound_terms = SlotAssigner().assign_term(self.term1) self.sut = Context(number_of_bound_terms) self.term2 = Parser.term(term2) self.sut.bind(self.term1, self.term2)
def test_environment_retrieval(self): mod = Module([Parser.rule("E |- read(y) --> E[y]")]) term = Parser.term("read(y)") sut = Interpreter(mod) sut.environment.locate_and_put("y", 42) result = sut.interpret(term) self.assertEqual(result, 42)
def test_comments(self): text = """ imports trans/runtime/a trans/runtime/b """ sut = Parser(text) self.assertEqual(len(sut.all().imports), 2)
def test_reduction_premise(self): mod = Module([ Parser.rule("b() --> c()"), Parser.rule("a(x) --> y where x --> y") ]) term = Parser.term("a(b())") result = Interpreter(mod).interpret(term) self.assertEqual(result, ApplTerm("c"))
def test_environment_assignment(self): mod = Module([Parser.rule("E |- bindVar(k, v) --> {k |--> v, E}")]) term = Parser.term("bindVar(a, 1)") sut = Interpreter(mod) a = sut.environment.locate_and_put( "a", IntTerm(42)) # this should be overwritten result = sut.interpret(term) self.assertIsInstance(result, MapWriteTerm) self.assertEqual(IntTerm(1), sut.environment.get(a))
def test_multiple_transformations(self): mod = Module([ Parser.rule("a() --> b()"), Parser.rule("b() --> c()"), Parser.rule("c() --> d()") ]) term = Parser.term("a()") result = Interpreter(mod).interpret(term) self.assertEqual(result, Parser.term("d()"))
def test_recursive_contexts(self): ifz_rule = Parser.rule( "ifz(cond, then, else) --> ifzc(value, then, else) where cond --> value" ) ifz0_rule = Parser.rule("ifzc(0, then, else) --> then") ifz1_rule = Parser.rule("ifzc(nonzero, then, else) --> else") # TODO need inequality check, e.g. where non_zero != 0 module = Module([ifz_rule, ifz0_rule, ifz1_rule]) interpreter = Interpreter(module) result = interpreter.interpret(Parser.term("ifz(ifz(1, 2, 3), 4, 5)")) self.assertEqual(IntTerm(5), result)
def test_interpreter_caching(self): if_rule = Parser.rule("if(a) --> then(a)") then1_rule = Parser.rule("then(0) --> b") then2_rule = Parser.rule("then(x) --> c") module = Module([if_rule, then1_rule, then2_rule]) interpreter = Interpreter(module) result1 = interpreter.interpret(Parser.term("if(0)")) self.assertEqual(VarTerm("b"), result1) result2 = interpreter.interpret(Parser.term("if(1)")) self.assertEqual(VarTerm("c"), result2)
def test_hashing(self): self.assertEquals(Parser.term("a"), Parser.term("a")) self.assertNotEquals(Parser.term("a"), Parser.term("b")) self.assertEquals(Parser.term("[1, a(b), {c |--> d}]"), Parser.term("[1, a(b), {c |--> d}]")) self.assertNotEquals(Parser.term("hello(world)"), Parser.term("hello[world]"))
def main(argv): """Parse and run any E2 program""" # parse input program try: file = argv[1] except IndexError: print( "Expected one file name argument to be passed, e.g. ./e2 program.e2" ) raise RuntimeError program_contents = read_file(argv[1]) program = Parser.term(program_contents) # set debug level debug_level = 0 try: debug_level = int(os.environ['DEBUG']) except KeyError: # there may be a better way to do this but RPython apparently does not allow "'DEBUG' in os.environ" pass # run the program Interpreter(e2, debug_level).interpret(program) return 0
def test_slots_on_block(self): sut = SlotAssigner() rule = Parser.rule("block([x | xs]) --> block(xs) where x --> y.") assigned = sut.assign_rule(rule.before, rule.after, rule.premises) self.assertEqual(3, assigned)
def test_block_environment(self): term = Parser.term("block([assign(a, 1), write(retrieve(a))])") result = Interpreter(e2).interpret(term) self.assertEqual(result, ApplTerm("block")) self.assertEqual(len(result.args), 0)
def test_case(self): premise = Parser.premise( "case i of {1 => x --> y otherwise => y --> z}") self.assertIsInstance(premise, CasePremise) self.assertEqual("i", premise.left.name) self.assertEqual(2, len(premise.values)) self.assertEqual(2, len(premise.premises))
def test_slots_on_terms(self): sut = SlotAssigner() term = Parser.term("a(b, c)") assigned = sut.assign_term(term) self.assertEqual(2, assigned) self.assertEqual(0, term.args[0].slot) self.assertEqual(1, term.args[1].slot)
def test_parentheses(self): text = """ rules Lit(s) --> NumV(parseI(s)) Plus(NumV(a), NumV(b)) --> NumV(addI(a, b)) """ sut = Parser(text) mod = sut.all() self.assertEqual(2, len(mod.rules)) self.assertEqual(ApplTerm("Lit", [VarTerm("s", 0)]), mod.rules[0].before) self.assertEqual( ApplTerm( "NumV", [ApplTerm( "addI", [VarTerm("a", 0), VarTerm("b", 1)])]), mod.rules[1].after)
def assertResolves(self, name, value): if isinstance(value, int): value = IntTerm(value) elif isinstance(value, str): value = Parser.term(value) slotted_var = TestContext.__find_slot(self.term1, name) resolved = self.sut.resolve(slotted_var) self.assertEqual(resolved, value)
def test_rules(self): text = """a(x, y) --> b where 1 == 1""" parsed = Parser.rule(text) expected = Rule(ApplTerm( "a", [VarTerm("x", 0), VarTerm("y", 1)]), VarTerm("b"), None, None, 2) expected.premises.append(EqualityCheckPremise(IntTerm(1), IntTerm(1))) self.assertEqual(expected, parsed)
def test_multi_resolution(self): program = """ block([ assign(a, 1), assign(a, add(retrieve(a), 1)) ]) """ term = Parser.term(program) interpreter = Interpreter(e2) interpreter.interpret(term) self.assertEqual(interpreter.environment.locate_and_get("a"), IntTerm(2))
def test_slots_on_rules(self): sut = SlotAssigner() rule = Parser.rule("a(x) --> [z] where x == 1; b(y) => x; y --> z.") assigned = sut.assign_rule(rule.before, rule.after, rule.premises) self.assertEqual(3, assigned) self.assertEqual(0, rule.before.args[0].slot) # a(x) self.assertEqual(0, rule.premises[0].left.slot) # x == 1 self.assertEqual(1, rule.premises[1].left.args[0].slot) # b(y) => x self.assertEqual(0, rule.premises[1].right.slot) # b(y) => x self.assertEqual(1, rule.premises[2].left.slot) # y --> z self.assertEqual(2, rule.premises[2].right.slot) # y --> z self.assertEqual(2, rule.after.items[0].slot) # [z]
def main(argv): """Run an E2 while-loop as an example""" program = Parser.term(""" block([ assign(a, 0), while(leq(retrieve(a), 10000), block([ assign(a, add(retrieve(a), 1)), write(retrieve(a)) ]) ) ]) """) Interpreter(e2).interpret(program) return 0
def test_while(self): interpreter = Interpreter(e2) program = """ block([ assign(a, 0), assign(max, 10), while(leq(retrieve(a), retrieve(max)), block([assign(a, add(retrieve(a), 1)), write(retrieve(a))]) ) ]) """ term = Parser.term(program) result = interpreter.interpret(term) self.assertEqual(interpreter.environment.locate_and_get("a"), IntTerm(11)) self.assertEqual(result, ApplTerm("block")) self.assertEqual(len(result.args), 0)
def test_sumprimes(self): program = """ /* sum up all primes in [2..max], using inefficient algorithm from lecture 1. */ block([ assign(max, 50), assign(s, 0), assign(n, 2), while(leq(retrieve(n), retrieve(max)), block([ assign(p, 1), /* flag indicating primeness: initialize to true */ assign(d, 2), while(leq(retrieve(d), sub(retrieve(n), 1)), block([ /* we have no mod operator... */ assign(m, mul(retrieve(d), div(retrieve(n), retrieve(d)))), ifz(leq(retrieve(n), retrieve(m)), /* always have m <= n */ assign(p, 0), /* i.e., n = m, so d divides n, so set p false */ block() /* (block) is a no-op */ ), assign(d, add(retrieve(d), 1)) ]) ), ifz(retrieve(p), assign(s, add(retrieve(s), retrieve(n))), block() ), assign(n, add(retrieve(n), 1)) ]) ), write(retrieve(s)) ]) """ term = Parser.term(program) interpreter = Interpreter(e2) # TODO fix that E somehow gets saved on the environment interpreter.interpret(term) # 328 seems about right: http://www.wolframalpha.com/input/?i=sum+primes+up+to+50&x=0&y=0 self.assertEqual(interpreter.environment.locate_and_get("s"), IntTerm(328))
def test_if(self): term = Parser.term("ifz(leq(2, 1), a(), b())") result = Interpreter(e2).interpret(term) self.assertEqual(result, ApplTerm("b"))
def test_term_equality(self): a1 = Parser.term("a(x, y)") a2 = Parser.term("a(x, y)") self.assertTrue(a1 == a2) self.assertEqual(a1, a2)