def test_validate_rule_csq_in_ant(self): antecedents = ['p1', 'p2', 'p3'] consequent = 'p3' msg = "You can't have a consequent, '{}', in the antecedents.".format( consequent) with self.assertRaises(InvalidRuleError, msg=msg): RulesUtils.validate_rule(antecedents, consequent)
def test_validate_rule_for_duplicates(self): antecedent = ['p1', 'p2', 'p3'] csq = 'p4' RulesUtils.create_rule(antecedent, csq) msg_error = "This rule already exists!" with self.assertRaises(InvalidDuplicateRuleError, msg=msg_error): RulesUtils.validate_rule(antecedent, csq)
def test_10_forward_duplicate_csq_but_satisfiable(self): RulesUtils.get_rules_from_file('../rules_base_06') # Same as before, but notice in rules_base_06 a rule with goal as csq again, and satisfiable. new_facts = [ 'v', 'u', 'y', 'x', 'z', 'w', 'goal' ] # Therefore, we test for no duplicate of goal in new_facts. self.assertEqual(ChainingStrategy.forward(), new_facts)
def test_08_forward_left_one(self): RulesUtils.get_rules_from_file('../rules_base_03') new_facts = ['z', 'w', 'x'] self.assertEqual(ChainingStrategy.forward(), new_facts) # ...
def test_07_forward(self): RulesUtils.get_rules_from_file('../rules_base_02') new_facts = ['c', 'd'] self.assertEqual(ChainingStrategy.forward(), new_facts) # TODO: use RuleUtils.get_new_facts()
def test_05_backward_medium_maybe(self): RulesUtils.get_rules_from_file('../rules_base_05') goal = 'goal' goal_false = 'nao_tem' # In some rule's antecedent only self.assertTrue(ChainingStrategy.backward(goal)) self.assertFalse(ChainingStrategy.backward(goal_false))
def test_04_backward_almost_not_easy(self): RulesUtils.get_rules_from_file('../rules_base_04') goal = 'goal' goal_false = 'm' # Need p and q, which can't be proved. self.assertTrue(ChainingStrategy.backward(goal)) self.assertFalse(ChainingStrategy.backward(goal_false))
def test_03_backward_less_easy(self): RulesUtils.get_rules_from_file('../rules_base_03') goal = 'x' goal_false = 'y' # In rules_base_03 as csq, but need f, which can be proved True. self.assertTrue(ChainingStrategy.backward(goal)) self.assertFalse(ChainingStrategy.backward(goal_false))
def test_check_for_rules(self): ant = ['p1', 'p2'] csq = 'p3' RulesUtils.create_rule(ant, csq) self.assertTrue(RulesUtils.check_for_rules())
def tearDown(self): RulesUtils.clear_running_database()
def test_check_variable_false(self): fact_w_sp = UtilsTest._random_string( 2, 4) + ' ' + UtilsTest._random_string(2, 4) self.assertFalse(RulesUtils.add_fact(fact_w_sp))
def test_validate_rule_for_blank_rule(self): ant = '' csq = '' msg_error = 'You can"t have a blank rule!' with self.assertRaises(InvalidRuleError, msg=msg_error): RulesUtils.validate_rule(ant, csq)
def test_validate_rule_ant_repeating(self): antecedents = ['p1', 'p1', 'p2'] consequent = 'p3' msg_error = "You can't have a premise more than once in antecedents." with self.assertRaises(InvalidRuleError, msg=msg_error): RulesUtils.validate_rule(antecedents, consequent)
def test_check_for_facts_false(self): self.assertFalse(RulesUtils.check_for_facts())
def test_check_for_facts(self): fact = 'f1' RulesUtils.add_fact(fact) self.assertTrue(RulesUtils.check_for_facts())
def test_09_forward_duplicate_csq(self): RulesUtils.get_rules_from_file('../rules_base_05') new_facts = ['v', 'u', 'y', 'x', 'z', 'w', 'goal'] self.assertEqual(ChainingStrategy.forward(), new_facts)
def main(): print( "Type 'yes' below if you want to tell your own rules (or 'no' for file as input)." ) where_to_get = input('> ') InputUtils.check_input_ok(where_to_get) if where_to_get == 'yes': print(""" Type the rules as in the example below (one at a time): IF premise_1 premise_2 ... premise_n THEN consequent Example: IF will_not_rain have_cash THEN go_out_tomorrow """) while True: RulesUtils.show_rules() antecedents, consequent = RulesUtils.get_rules_from_user() RulesUtils.validate_rule(antecedents, consequent) print('\nYour rule: ', RulesUtils.show_rule(antecedents, consequent)) print( 'Confirm (yes/no)? Also, type "stop" to confirm and terminate here.' ) confirm = input('> ') InputUtils.check_input_ok(confirm, possible_stop=True) if confirm == 'stop': RulesUtils.create_rule(antecedents, consequent) break elif confirm == 'yes': RulesUtils.create_rule(antecedents, consequent) else: if not RulesUtils.check_for_rules( ): # TODO: test check_for_rules print(">! You must add at least one rule.") else: print('Do you want to continue? (yes/no)') confirm = input('> ') InputUtils.check_input_ok(confirm) if confirm == 'no': break print( 'Rules database now complete. However, you must add your facts to the database.' ) print(""" Below, type the variables that you know are TRUE (blank line for stop). Example (notice the blank line): > will_rain > go_out_tomorrow > """) while True: fact = input('> ') if not fact: if not RulesUtils.check_for_facts( ): # TODO: check_for_facts NOT TESTED print(">! No facts have been added till now. " "You really wishes to continue (yes/no)? " "You will not be able to prove anything.") confirm = input('> ') InputUtils.check_input_ok(confirm) if confirm == 'yes': break break elif RulesUtils.add_fact(fact): continue print('Facts added to the database.') RulesUtils.save_rules_to_file() else: # TODO: this else is not tested print( 'Type the file name below, please. Verify that it is in the same folder as this script.' ) while True: path_file = input('> ') if InputUtils.check_path_file_ok(path_file): RulesUtils.get_rules_from_file(path_file) print('Rules and facts loaded!') break RulesUtils.show_rules() RulesUtils.show_facts() print('\n') print(""" Type now which strategy do you want (type 1 or 2): 1. Forward chaining 2. Backward chaining 3. Other (not implemented) """) type_strategy = int(input('> ')) InputUtils.check_strategy_ok(type_strategy) # Rules and facts database will now be class attributes of RulesUtils if type_strategy == 1: print('Running now forward chaining...') new_facts = ChainingStrategy.forward() print('Done.') if new_facts: print('Showing new facts...') RulesUtils.show_new_facts(new_facts) print( "Type 'yes' if you want to save the new facts discovered ('no' otherwise)." ) save_facts = input('> ') InputUtils.check_input_ok(save_facts) if save_facts == 'yes': RulesUtils.merge_new_facts(new_facts) RulesUtils.save_rules_to_file() else: print('No new facts have been discovered.') print('Bye!') elif type_strategy == 2: print(""" Type now what you want to prove (with the given database). Ex.: 'will_rain' or 'temperature_less_than_20' Anything like that, named as variable. """) while True: goal = input('>') if RulesUtils.check_variable(goal): break print('Running now backward chaining on "{}"...'.format(goal)) result_msg = 'Based on the existing database, we have {} = {}.' if ChainingStrategy.backward(goal): print(result_msg.format(goal, True)) print( "Type 'yes' if you want to see the explanation ('no' otherwise)." ) confirm = input('> ') InputUtils.check_input_ok(confirm) if confirm == 'yes': ChainingStrategy.show_explanation_tree(goal) else: print(result_msg.format(goal, False)) print('Done.') else: print("Not implemented yet.")
def test_02_backward_easy(self): RulesUtils.get_rules_from_file('../rules_base_02') goal = 'd' goal_false = 'e' # Not in rules_base_02 self.assertTrue(ChainingStrategy.backward(goal)) self.assertFalse(ChainingStrategy.backward(goal_false))
def test_01_backward(self): RulesUtils.get_rules_from_file('../rules_base') goal = 'green' goal_false = 'canary' self.assertTrue(ChainingStrategy.backward(goal)) self.assertFalse(ChainingStrategy.backward(goal_false))
def test_check_variable_false_with_punc(self): fact_wo_sp_but_with_punc = UtilsTest._random_string(8, 12) self.assertFalse(RulesUtils.add_fact(fact_wo_sp_but_with_punc))