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_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_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 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_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_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_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_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 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_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_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 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 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_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_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_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 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_term_equality(self): a1 = Parser.term("a(x, y)") a2 = Parser.term("a(x, y)") self.assertTrue(a1 == a2) self.assertEqual(a1, a2)
def test_list(self): list = Parser.term("[a, b, 1, 2]") self.assertIsInstance(list, ListTerm) self.assertEqual(4, len(list.items))
def test_list_constructor(self): list = Parser.term("[a, b, 1, 2]") pattern = Parser.term("[x | xs]") self.assertTrue(pattern.matches(list))
def test_constructor_matching(self): a1 = Parser.term("a(1)") ax = Parser.term("a(x)") self.assertTrue(ax.matches(a1))
def test_term_matching(self): a1 = Parser.term("a(x, y)") b = Parser.term("b") self.assertTrue(b.matches(a1)) self.assertFalse(a1.matches(b))
def test_terms(self): text = """a(x, y)""" term = Parser.term(text) self.assertEqual(ApplTerm("a", [VarTerm("x"), VarTerm("y")]), term)
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_if(self): term = Parser.term("if(leq(1, 2), a(), b())") self.assertIsInstance(term, ApplTerm) self.assertEqual(3, len(term.args)) self.assertEqual("leq", term.args[0].name)