def test_parse_nested_expression(self): root = AssociativeSet('*') parse_text = "foo bar (baz berz)" parse(parse_text, root) # Expected: foo, bar, (baz berz), baz, berz, outer expression, inner expression (parenthetical) # Plus outer ordinals: 0, 1, 2 (which should be shared w/ inner ordinals) and 5 relations to # support them, and the 'position' category. # self.assertEqual( len(root.contents), 15) self.assertTrue("foo" in root.contents) self.assertTrue("bar" in root.contents) relations = root.comprehend("baz", "berz") self.assertTrue( len(relations) > 0, "Should get a relation back for the inner expression") inner_expression = relations[0] self.assertNotEqual(inner_expression.name, '*', "Shouldn't get root back as our match") self.assertTrue("baz" in inner_expression, "Can't see first item in nested expression.") self.assertTrue("berz" in inner_expression, "Can't see second item in nested expression.")
def test_generate_simple_dump(self): filename = "/nml/nextwheel/tests/test.dot" root = AssociativeSet('*') # parse_text = "foo bar (baz berz)" parse_text = "foo bar" parse(parse_text, root) # Expected: foo, bar, (baz berz), baz, berz, outer expression, inner expression (parenthetical) CategoryInspector(root).dump_to_file(filename) dumpfile = open(filename, "r") self.assertNotEqual(dumpfile, None, "Can't find the file?") content = dumpfile.readlines() self.assertTrue(len(content) > 0, "No lines read from dot file?") # We don't want duplicate relations. Let's only allow them once. # In this case our context is named '*' and our test category is 'bar'. lines_with_bar_and_star = [ line for line in content if "bar" in line and "*" in line ] self.assertTrue( len(lines_with_bar_and_star) == 1, "'bar' and '*' should appear only ONCE")
def test_parse_nested_expression(self): root = AssociativeSet('*') parse_text = "foo bar (baz berz)" parse(parse_text, root) # Expected: foo, bar, (baz berz), baz, berz, outer expression, inner expression (parenthetical) # Plus outer ordinals: 0, 1, 2 (which should be shared w/ inner ordinals) and 5 relations to # support them, and the 'position' category. # self.assertEqual( len(root.contents), 15) self.assertTrue( "foo" in root.contents ) self.assertTrue( "bar" in root.contents ) relations = root.comprehend("baz", "berz") self.assertTrue(len(relations) > 0, "Should get a relation back for the inner expression") inner_expression = relations[0] self.assertNotEqual( inner_expression.name, '*', "Shouldn't get root back as our match") self.assertTrue("baz" in inner_expression, "Can't see first item in nested expression.") self.assertTrue("berz" in inner_expression, "Can't see second item in nested expression.")
def test_identify_string(self): expression = '"foo bar baz"' root = Category("*") parse(expression, root) match = root.comprehend(expression, "string", "metadata") self.assertTrue(len(match) > 0, "Not seeing string metadata for this expression.")
def test_identify_string(self): expression = '"foo bar baz"' root = Category("*") parse(expression, root) match = root.comprehend(expression, "string", "metadata") self.assertTrue( len(match) > 0, "Not seeing string metadata for this expression.")
def test_evaluate_different_atoms(self): rootA = Category('*') rootB = Category('*') expressionA = "foo" expressionB = "(foo)" evaluate(parse(expressionA, rootA), rootA) evaluate(parse(expressionB, rootB), rootB) category_delta = len(rootB.contents) - len(rootA.contents) self.assertTrue(category_delta > 0, "Second expression should generate different numbers of categories")
def test_evaluate_simple_expression_multiple_times(self): root = Category('*') expression = "foo bar baz" evaluate(parse(expression, root), root) # Don't forget that at this point there are a bunch of meta-categories. evaluate(parse(expression, root), root) # Don't forget that at this point there are a bunch of meta-categories. evaluate(parse(expression, root), root) # Don't forget that at this point there are a bunch of meta-categories. connections = root.comprehend("baz", "foo", "bar") self.assertEqual(len(connections), 3) # Should have a relation for each evaluation.
def test_simple_subtraction(self): expression = '8 - 5' # self.fail("Subtraction doesn't work yet") result = parse(expression, ROOT).evaluate() self.assertTrue( result.has('3'), "Expected 3 in the result but I see: %s" % result.contents)
def test_parse_atom(self): root = AssociativeSet('.') expression = "foo" parsed = parse(expression, root) self.assertTrue( isinstance(parsed, AssociativeSet) ) self.assertTrue( expression in parsed.contents, "Not seeing 'foo' in the contents.")
def test_has_metadata(self): expression = '"foo bar baz"' root = Category("*") result = parse(expression, root) metadata = root.contents["metadata"] self.assertTrue(result.related( set([metadata]) ), "All expressions should have metadata associated with them. This does not.")
def test_simple_addition(self): expression = '1 + 2' result = parse(expression, ROOT).evaluate() self.assertTrue( result.has('3'), "Expected 3 in the result but I see: %s" % result.contents)
def test_parse_atom(self): root = AssociativeSet('.') expression = "foo" parsed = parse(expression, root) self.assertTrue(isinstance(parsed, AssociativeSet)) self.assertTrue(expression in parsed.contents, "Not seeing 'foo' in the contents.")
def test_detailed_regex(self): expression = r"/ABC\d+def[^c]/" root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "regex", "metadata") self.assertTrue(len(match) > 0, "Not seeing 'regex' metadata for this expression.")
def test_identify_simple_regex(self): expression = '/ABC/' root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "regex", "metadata") self.assertTrue(len(match) > 0, "Not seeing 'regex' metadata for this expression.")
def test_identify_numeric(self): expression = '123' root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "number", "metadata") self.assertTrue(len(match) > 0, "Not seeing 'number' metadata for this expression.")
def test_timestamp(self): expression = '123' root = Category("*") result = parse(expression, root) time_match = root.comprehend(result.name, "time", "metadata") self.assertTrue( len(time_match) > 0, "Not seeing 'time' metadata for this expression.") timestamp = time_match[0] # YEAR #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "year") self.assertTrue(len(match) > 0, "Not seeing 'year' info.") year = extract_time_component(match, "year") self.assertTrue(re.match(year_pattern, year), "Not seeing year value.") # MONTH #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "month") self.assertTrue(len(match) > 0, "Not seeing 'month' info.") month = extract_time_component(match, "month") self.assertTrue(re.match(month_pattern, month), "Not seeing month value.") # DATE #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "date") self.assertTrue(len(match) > 0, "Not seeing 'date' info.") date = extract_time_component(match, "date") self.assertTrue(re.match(date_pattern, date), "Not seeing date value.") # HOUR - Go with 24 hour clock for now. #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "hour") self.assertTrue(len(match) > 0, "Not seeing 'hour' info.") hour = extract_time_component(match, "hour") self.assertTrue(re.match(hour_pattern, hour), "Not seeing hour value.") # MINUTE #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "minute") self.assertTrue(len(match) > 0, "Not seeing 'minute' info.") minute = extract_time_component(match, "minute") self.assertTrue(re.match(minute_pattern, minute), "Not seeing minute value.") # SECOND #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "second") self.assertTrue(len(match) > 0, "Not seeing 'second' info.") second = extract_time_component(match, "second") self.assertTrue(re.match(second_pattern, second), "Not seeing second value.")
def test_identify_simple_regex(self): expression = '/ABC/' root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "regex", "metadata") self.assertTrue( len(match) > 0, "Not seeing 'regex' metadata for this expression.")
def test_detailed_regex(self): expression = r"/ABC\d+def[^c]/" root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "regex", "metadata") self.assertTrue( len(match) > 0, "Not seeing 'regex' metadata for this expression.")
def load_prelude(): for line in open( os.path.dirname(os.path.abspath(__file__)) + "/prelude.w", "r"): line = line.strip() # Comment stripper. Fragile! line = line[:line.find('#')] if '#' in line else line # Ignore blank lines if line: evaluate( parse(line, ROOT), ROOT )
def test_has_metadata(self): expression = '"foo bar baz"' root = Category("*") result = parse(expression, root) metadata = root.contents["metadata"] self.assertTrue( result.related(set([metadata])), "All expressions should have metadata associated with them. This does not." )
def test_identify_numeric(self): expression = '123' root = Category("*") result = parse(expression, root) match = root.comprehend(expression, "number", "metadata") self.assertTrue( len(match) > 0, "Not seeing 'number' metadata for this expression.")
def load_file(filename): try: for line in open( os.path.dirname(os.path.abspath(__file__)) + "/%s.w" % filename, "r"): line = line.strip() # Comment stripper. Fragile! line = line[:line.find('#')] if '#' in line else line # Ignore blank lines if line: evaluate( parse( expand_arrows(line), ROOT), ROOT ) except: print "Can't load that file for some damned reason or another."
def test_simultaneous_transitions(self): root = Category('*') setup_expressions = [ "foo A", "bar B", "transition (pattern (A)) (action B)", "transition (pattern (Y)) (action Z)", ] # Setup the world for expression in setup_expressions: evaluate(parse(expression, root), root) expression = "foo bar" # After evaluation the following relationships should exist: # foo B # bar Z # foo bar expected_relationships = ["foo B", "bar Z", "foo bar"] relationships = list( chain.from_iterable( [root.comprehend(*r.split()) for r in expected_relationships])) # Verify those relationships do not yet exist. self.assertFalse(any(relationships), "None of those relationships should exist yet.") evaluate(parse(expression, root), root) # Now, ALL of those relationships should exist. relationships = list( chain.from_iterable( [root.comprehend(*r.split()) for r in expected_relationships])) self.assertTrue(all(relationships), "All of those relationships should exist.")
def test_parse_ordering_of_expression(self): root = AssociativeSet('*') expression_result = parse("foo bar", root) self.assertEqual(len(root.comprehend("foo", "0")), 1) # Should get ONE hit. position_relation = root.comprehend("foo", "0")[0] self.assertTrue("position" in position_relation.contents) position_tags = [x for x in position_relation.contents.values() if "position" in x.contents] self.assertTrue(position_tags, "Should be able to see the position relation marked as such.")
def test_timestamp(self): expression = '123' root = Category("*") result = parse(expression, root) time_match = root.comprehend(result.name, "time", "metadata") self.assertTrue(len(time_match) > 0, "Not seeing 'time' metadata for this expression.") timestamp = time_match[0] # YEAR #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "year") self.assertTrue(len(match) > 0, "Not seeing 'year' info.") year = extract_time_component(match, "year") self.assertTrue(re.match(year_pattern, year), "Not seeing year value.") # MONTH #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "month") self.assertTrue(len(match) > 0, "Not seeing 'month' info.") month = extract_time_component(match, "month") self.assertTrue(re.match(month_pattern, month), "Not seeing month value.") # DATE #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "date") self.assertTrue(len(match) > 0, "Not seeing 'date' info.") date = extract_time_component(match, "date") self.assertTrue(re.match(date_pattern, date), "Not seeing date value.") # HOUR - Go with 24 hour clock for now. #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "hour") self.assertTrue(len(match) > 0, "Not seeing 'hour' info.") hour = extract_time_component(match, "hour") self.assertTrue(re.match(hour_pattern, hour), "Not seeing hour value.") # MINUTE #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "minute") self.assertTrue(len(match) > 0, "Not seeing 'minute' info.") minute = extract_time_component(match, "minute") self.assertTrue(re.match(minute_pattern, minute), "Not seeing minute value.") # SECOND #----------------------------------------------------------------------- match = root.comprehend(timestamp.name, "second") self.assertTrue(len(match) > 0, "Not seeing 'second' info.") second = extract_time_component(match, "second") self.assertTrue(re.match(second_pattern, second), "Not seeing second value.")
def test_simultaneous_transitions(self): root = Category('*') setup_expressions = [ "foo A", "bar B", "transition (pattern (A)) (action B)", "transition (pattern (Y)) (action Z)", ] # Setup the world for expression in setup_expressions: evaluate(parse(expression, root), root) expression = "foo bar" # After evaluation the following relationships should exist: # foo B # bar Z # foo bar expected_relationships = [ "foo B", "bar Z", "foo bar" ] relationships = list(chain.from_iterable([ root.comprehend(*r.split()) for r in expected_relationships ])) # Verify those relationships do not yet exist. self.assertFalse(any(relationships), "None of those relationships should exist yet.") evaluate(parse(expression, root), root) # Now, ALL of those relationships should exist. relationships = list(chain.from_iterable([ root.comprehend(*r.split()) for r in expected_relationships ])) self.assertTrue(all(relationships), "All of those relationships should exist.")
def test_simple_interaction(self): root = Category('*') expression = "foo bar" evaluate(parse(expression, root), root) self.assertTrue(root.has("foo")) self.assertTrue(isinstance(root.contents["foo"], Category)) foo = root.contents["foo"] bar = root.contents["bar"] self.assertTrue(bar.related(set([foo])), "no double relation?")
def test_simple_interaction(self): root = Category('*') expression = "foo bar" evaluate(parse(expression, root), root) self.assertTrue( root.has("foo") ) self.assertTrue( isinstance( root.contents["foo"], Category) ) foo = root.contents["foo"] bar = root.contents["bar"] self.assertTrue(bar.related(set([foo])), "no double relation?")
def test_categories_receive_precedence(self): plus = ROOT.contents["+"] precedence = ROOT.contents["precedence"] three = ROOT.contents["3"] self.assertTrue("+" in ROOT.contents, "'+' isn't defined?") self.assertTrue(three in plus.intersection(precedence), "Addition hasn't the right precedence.") expression = '1 + 2' expression_category = parse(expression, ROOT) self.assertTrue("precedence" in expression_category.contents["+"].contents, "No precedence found for '+'!") self.assertTrue("+" in expression_category.contents["+"].contents["precedence"].contents, "Precedence category doesn't know about '+'?")
def test_getting_a_thingy_between_two_other_thingies(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] related = root.comprehend("apple", "red") self.assertTrue(len(related) > 0, "We should have received some results back.") self.assertTrue( root.comprehend("apple", "red")[0].related( set([tasty]) ), "Can't find a relationship?")
def test_getting_a_thingy_between_two_other_thingies2(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] relation = root.comprehend("apple", "red") self.assertTrue(len(relation) > 0, "We should have received some results back.") # TODO: Make this test less crude and more direct. self.assertTrue( tasty in relation[0].contents.values(), "Can't find a relationship?")
def test_parse_simple_expression(self): root = AssociativeSet('.') expression = "foo bar" # Note that this is the result of the expression being # *parsed*, not *parsed AND evaluated*. If it was being # evaluated there would be another category that represented # the result of the interaction. expression_result = parse(expression, root) # Expected in root: foo, bar, the relation between them, and the literal <<relation>> category. # Also the ordinal values (positions) for each element of the expression, and a relation for each. # And the 'position' category. # self.assertEqual( len(root.contents), 9) self.assertTrue( "foo" in root.contents ) self.assertTrue( "bar" in root.contents ) self.assertTrue( "__relation__0" in root.contents )
def test_parse_ordering_of_expression(self): root = AssociativeSet('*') expression_result = parse("foo bar", root) self.assertEqual(len(root.comprehend("foo", "0")), 1) # Should get ONE hit. position_relation = root.comprehend("foo", "0")[0] self.assertTrue("position" in position_relation.contents) position_tags = [ x for x in position_relation.contents.values() if "position" in x.contents ] self.assertTrue( position_tags, "Should be able to see the position relation marked as such.")
def test_parse_simple_expression(self): root = AssociativeSet('.') expression = "foo bar" # Note that this is the result of the expression being # *parsed*, not *parsed AND evaluated*. If it was being # evaluated there would be another category that represented # the result of the interaction. expression_result = parse(expression, root) # Expected in root: foo, bar, the relation between them, and the literal <<relation>> category. # Also the ordinal values (positions) for each element of the expression, and a relation for each. # And the 'position' category. # self.assertEqual( len(root.contents), 9) self.assertTrue("foo" in root.contents) self.assertTrue("bar" in root.contents) self.assertTrue("__relation__0" in root.contents)
def test_getting_a_thingy_between_two_other_thingies2(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] relation = root.comprehend("apple", "red") self.assertTrue( len(relation) > 0, "We should have received some results back.") # TODO: Make this test less crude and more direct. self.assertTrue(tasty in relation[0].contents.values(), "Can't find a relationship?")
def test_getting_a_thingy_between_two_other_thingies(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] related = root.comprehend("apple", "red") self.assertTrue( len(related) > 0, "We should have received some results back.") self.assertTrue( root.comprehend("apple", "red")[0].related(set([tasty])), "Can't find a relationship?")
def test_arithmetic_precedence(self): expression = '1 + 2 / 5 * 3 - 2' expression_category = parse(expression, ROOT) metadata = expression_category.contents["metadata"] plus = expression_category.contents["+"] minus = expression_category.contents["-"] mult = expression_category.contents["*"] div = expression_category.contents["/"] operators = (plus, minus, mult, div) precedence = ROOT.contents["precedence"] self.assertTrue("0" in [category.name for category in precedence.intersection(div)], "Division should have precedence zero") self.assertTrue("1" in [category.name for category in precedence.intersection(mult)], "Multiplication should have precedence one") self.assertTrue("2" in [category.name for category in precedence.intersection(minus)], "Subtraction should have precedence two") self.assertTrue("3" in [category.name for category in precedence.intersection(plus)], "Addition should have precedence three")
def test_another_interaction(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] # TODO: Make #related not suck. self.assertTrue(apple.related( set([tasty]) ), "no relation?") self.assertTrue(apple.related( set([red]) ), "no relation?") self.assertTrue(tasty.related( set([red]) ), "no relation?") self.assertTrue(tasty.related( set([apple]) ), "no relation?") self.assertTrue(red.related( set([tasty]) ) , "no relation?") self.assertTrue(red.related( set([apple]) ), "no relation?")
def test_another_interaction(self): root = Category('*') expression = "apple tasty red" evaluate(parse(expression, root), root) apple = root.contents["apple"] tasty = root.contents["tasty"] red = root.contents["red"] # TODO: Make #related not suck. self.assertTrue(apple.related(set([tasty])), "no relation?") self.assertTrue(apple.related(set([red])), "no relation?") self.assertTrue(tasty.related(set([red])), "no relation?") self.assertTrue(tasty.related(set([apple])), "no relation?") self.assertTrue(red.related(set([tasty])), "no relation?") self.assertTrue(red.related(set([apple])), "no relation?")
def test_evaluate_atom(self): root = Category('*') root.create("relation") # Housekeeping expression = "foo" parsed = parse(expression, root) evaluate(parsed, root) # After an evaluation we should be able to see a relation which represents the result # of this particular evaluation. It will relate to a timestamp and the given expression. # In this way you should be able to see a history of evaluations. self.assertTrue( "foo" in root.contents.keys() ) self.assertTrue( root.has("foo") ) self.assertTrue( isinstance( root.contents["foo"], Category) ) foo = root.contents["foo"] self.assertFalse(foo.has("relation")) # Should not connect directly to <<relation>>
def test_simple_subtraction(self): expression = '8 - 5' # self.fail("Subtraction doesn't work yet") result = parse(expression, ROOT).evaluate() self.assertTrue(result.has('3'), "Expected 3 in the result but I see: %s" % result.contents )
from interpreter.tools import parse, evaluate, expand_arrows from common import * import os def load_prelude(): for line in open(os.path.dirname(os.path.abspath(__file__)) + "/prelude.w", "r"): line = line.strip() # Comment stripper. Fragile! line = line[:line.find('#')] if '#' in line else line # Ignore blank lines if line: evaluate( parse( expand_arrows(line), ROOT), ROOT ) load_prelude() tokenized_lines = [] line_number = 1 for line in fileinput.input(): line = line.strip() # Comment stripper. Fragile! line = line[:line.find('#')] if '#' in line else line # Ignore blank lines if line: evaluate( parse(line, ROOT), ROOT )
if command in ('reset',): ROOT = Category("*") ROOT.add(ROOT) load_prelude() print "* was reset" continue if command.split() and command.split()[0] == "load": args = command.split() if len(args) != 2: print "This didn't make sense for loading: ", args else: load_file(args[1]) continue # Ignore blank lines if line: evaluate( parse( expand_arrows(line), ROOT), ROOT )
def test_simple_addition(self): expression = '1 + 2' result = parse(expression, ROOT).evaluate() self.assertTrue(result.has('3'), "Expected 3 in the result but I see: %s" % result.contents )