def test_call_binding_no_reexecution(self): self.assertTrue(self.engine.solve('Z = !, call((Z=!, a(X), Z)).')) self.assertEquals({ 'X': Atomic(1), 'Z': Atomic('!') }, self.engine.currsubst()) self.assertFalse(self.engine.solve_next())
def test_simple_flatten(self): s = Substitution() s['A'] = Variable('B') s['B'] = Atomic(1) self.assertEquals(Variable('B'), s.get('A')) s.flatten() self.assertEquals(Atomic(1), s.get('A')) self.assertEquals(Atomic(1), s['B'])
def test_deep_compound(self): px = Compound('p', Variable('X')) p1 = Compound('p', Atomic(1)) foo = Compound('foo', px, p1) args = (Variable('A'),) * 2 foo_variable = Compound('foo', *args) mgu = unify(foo, foo_variable) self.assertIsNotNone(mgu) self.assertEquals(Atomic(1), mgu['X'])
def test_end_of_stream(self): s = open('tests/resources/editor') stream = prologio.Stream(s) stream.stream_term = Compound('$stream', Atomic(999)) prologio.stream_terms[str(stream.stream_term)] = stream # FIXME Single quotes are not preserved in atoms self.assertTrue(self.engine.solve("peek_code('$stream'(999), Code).")) self.assertEquals(Atomic(-1), self.engine.currsubst()['Code']) del prologio.stream_terms[str(stream.stream_term)]
def test_simple_reduce(self): s = Substitution() # variables ending with '#N' are considered as renamed s['A#0'] = Variable('I') s['I'] = Atomic('p') s['X'] = Variable('C#0') result = Substitution() result['I'] = Atomic('p') s.reduce() self.assertEquals(result, s)
def test_stream_code(self): s = open('tests/resources/qwerty') stream = prologio.Stream(s) stream.stream_term = Compound('$stream', Atomic(999)) prologio.stream_terms[str(stream.stream_term)] = stream # FIXME Single quotes are not preserved in atoms self.assertTrue(self.engine.solve("get_code('$stream'(999), Code).")) self.assertEquals(Atomic(113), self.engine.currsubst()['Code']) self.assertEquals('werty', s.read()) del prologio.stream_terms[str(stream.stream_term)]
def test_stream_quote(self): s = open('tests/resources/quoted_qwerty') stream = prologio.Stream(s) stream.stream_term = Compound('$stream', Atomic(999)) prologio.stream_terms[str(stream.stream_term)] = stream # FIXME Single quotes are not preserved in atoms self.assertTrue(self.engine.solve("peek_char('$stream'(999), Char).")) self.assertEquals(Atomic("'"), self.engine.currsubst()['Char']) self.assertEquals("'qwerty'", s.read()) del prologio.stream_terms[str(stream.stream_term)]
def test_file_name_property(self): goal = 'stream_property(S, file_name(F)).' self.assertTrue(self.engine.solve(goal)) s = Compound('$stream', Atomic(1)) self.assertEquals(s, self.engine.currsubst()['S']) self.assertEquals(Atomic('<stdout>'), self.engine.currsubst()['F']) self.assertTrue(self.engine.solve_next()) s = Compound('$stream', Atomic(0)) self.assertEquals(s, self.engine.currsubst()['S']) self.assertEquals(Atomic('<stdin>'), self.engine.currsubst()['F']) self.assertFalse(self.engine.solve_next())
def test_end_of_stream(self): s = open('tests/resources/editor') stream = prologio.Stream(s) stream.stream_term = Compound('$stream', Atomic(999)) prologio.stream_terms[str(stream.stream_term)] = stream # FIXME Single quotes are not preserved in atoms self.assertTrue(self.engine.solve("get_char('$stream'(999), Char).")) self.assertEquals(Atomic('end_of_file'), self.engine.currsubst()['Char']) # The stream-position past-end-of-stream is not supported del prologio.stream_terms[str(stream.stream_term)]
def test_reduce_with_compound(self): s = Substitution() # variables ending with '#N' are considered as renamed s['A#0'] = Variable('I') s['B'] = Compound('p', Variable('A#0')) s['I'] = Atomic('q') result = Substitution() result['I'] = Atomic('q') result['B'] = Compound('p', Variable('A#0')) s.reduce() self.assertEquals(result, s)
def test_update(self): s1 = Substitution() s1['A'] = Variable('B') s1['B'] = Atomic(1) s2 = Substitution() s2['A'] = Variable('C') s2['D'] = Atomic(2) s1.update(s2) b = s1.get('A') # A is still bound to a variable... self.assertTrue(isinstance(b, Variable)) # ...but the variable has been updated to point to 1 self.assertEquals(Atomic(1), b.value) # C is updated to reflect its proper status self.assertEquals(Atomic(1), s1['C']) # D is left as it is self.assertEquals(Atomic(2), s1['D'])
def test_current_input_stream_code(self): s = open('tests/resources/qwerty') stream = prologio.Stream(s) old_current_input_stream = prologio.current_input_stream prologio.current_input_stream = stream self.assertTrue(self.engine.solve('peek_code(Code).')) self.assertEquals(Atomic(113), self.engine.currsubst()['Code']) self.assertEquals('qwerty', s.read()) prologio.current_input_stream = old_current_input_stream
def test_stream_wrong_code(self): s = open('tests/resources/qwerty') stream = prologio.Stream(s) stream.stream_term = Compound('$stream', Atomic(999)) prologio.stream_terms[str(stream.stream_term)] = stream # FIXME Single quotes are not preserved in atoms self.assertFalse(self.engine.solve("peek_code('$stream'(999), 0'p).")) self.assertEquals('qwerty', s.read()) del prologio.stream_terms[str(stream.stream_term)]
def test_current_input_stream_char(self): s = open('tests/resources/qwerty') stream = prologio.Stream(s) old_current_input_stream = prologio.current_input_stream prologio.current_input_stream = stream self.assertTrue(self.engine.solve('get_char(Char).')) self.assertEquals(Atomic('q'), self.engine.currsubst()['Char']) self.assertEquals('werty', s.read()) prologio.current_input_stream = old_current_input_stream
def test_catch_with_unification_and_output_without_reexecution(self): output = StringIO() from prologlib.builtin import io as prologio prologio.current_output_stream = output self.assertTrue(self.engine.solve('catch(g, C, write(h1)).')) self.assertEquals({'C': Atomic('c')}, self.engine.currsubst()) self.assertFalse(self.engine.solve_next()) self.assertEquals('h1', output.getvalue()) prologio.current_output_stream = prologio.STANDARD_OUTPUT_STREAM
def test_term_from_current_input_stream(self): s = StringIO('term1. term2.') s.name = 'terms' s.fileno = lambda: 999 stream = prologio.Stream(s) old_current_input_stream = prologio.current_input_stream prologio.current_input_stream = stream self.assertTrue(self.engine.solve('read(T).')) self.assertEquals(Atomic('term1'), self.engine.currsubst()['T']) self.assertEquals('term2.', s.read()) prologio.current_input_stream = old_current_input_stream
def test_get_binding(self): s = Substitution() s['A'] = Variable('B') s['B'] = Atomic(1) self.assertEquals(Atomic(1), s['A']) self.assertEquals(Atomic(1), s['B'])
def test_code_as_variable(self): goal = 'put_code(my_file, C).' caught = self.assertRaises(PrologError, self.engine.solve, goal) error = Atomic('instantiation_error') self.assertEquals(error, caught.error_term())
def test_code_as_string(self): goal = "put_code(my_file, 'ty')." caught = self.assertRaises(PrologError, self.engine.solve, goal) error = Compound('type_error', Atomic('integer'), Atomic('ty')) self.assertEquals(error, caught.error_term())
def test_stream_as_variable(self): goal = 'nl(Str).' caught = self.assertRaises(PrologError, self.engine.solve, goal) error = Atomic('instantiation_error') self.assertEquals(error, caught.error_term())
def test_input_stream(self): goal = 'nl(user_input).' caught = self.assertRaises(PrologError, self.engine.solve, goal) args = (Atomic('output'), Atomic('stream'), Atomic('user_input')) error = Compound('permission_error', *args) self.assertEquals(error, caught.error_term())
def test_convert_compound(self): term = Compound('f', Variable('X'), Atomic('g')) self.assertEquals(term, convert_to_goal(term))
def test_catch_propagate_unification_from_catcher_to_recovery(self): '''A non-ISO regression test to avoid a bug in propagating the substitution''' goal = "catch(X is float_fractional_part(5), error(type_error(_, N), _), A is N)." self.assertTrue(self.engine.solve(goal)) self.assertEquals(Atomic(5), self.engine.currsubst()['N']) self.assertEquals(Atomic(5), self.engine.currsubst()['A'])
def test_compound(self): args = (Variable('A'),) * 3 foo_variable = Compound('foo', *args) foo_ground = Compound('foo', Atomic(1), Atomic(2), Atomic(3)) self.assertIsNone(unify(foo_variable, foo_ground))
def test_list(self): aList = List.from_list([Variable('A')] * 3) anotherList = List.from_list([Atomic(1), Atomic(2), Atomic(3)]) self.assertIsNone(unify(aList, anotherList))
def test_set_existing_binding(self): s = Substitution() s['A'] = Atomic(1) s['A'] = Atomic(2) self.assertEquals(Atomic(1), s['A'])
def test_convert_number(self): term = Atomic(3) self.assertTrue(convert_to_goal(term) is None)
def test_catch_with_error_unification(self): self.assertTrue(self.engine.solve('catch(coo(X), Y, true).')) error = self.engine.currsubst()['Y'] self.assertEquals(Compound, type(error)) self.assertEquals(Atomic('instantiation_error'), error.value[1])
def test_output_property(self): goal = 'stream_property(S, output).' self.assertTrue(self.engine.solve(goal)) s = Compound('$stream', Atomic(1)) self.assertEquals(s, self.engine.currsubst()['S']) self.assertFalse(self.engine.solve_next())
def test_convert_disjunction(self): term = Compound(';', Variable('X'), Atomic('p')) goal = convert_to_goal(term) self.assertEquals(';/2', goal.predicate_indicator()) self.assertEquals(Compound('call', Variable('X')), goal.value[1]) self.assertEquals(Atomic('p'), goal.value[2])