def test_precision(self): print(">> ContinuumLogicProgram.precision(expected, predicted)") self.assertEqual(ContinuumLogicProgram.precision([],[]), 1.0) # Equal programs for i in range(self.__nb_unit_test): variables, domains = self.random_system() nb_states = random.randint(1,100) expected = [] predicted = [] for j in range(nb_states): s1 = [ random.uniform(d.get_min_value(),d.get_max_value()) for d in domains ] s2 = [ random.uniform(d.get_min_value(),d.get_max_value()) for d in domains ] s2_ = [ Continuum.random(d.get_min_value(), d.get_max_value()) for d in domains ] expected.append( (s1,s2) ) predicted.append( (s1,s2_) ) precision = ContinuumLogicProgram.precision(expected, predicted) error = 0 for j in range(len(expected)): s1, s2 = expected[j] s1_, s2_ = predicted[j] for k in range(len(s2)): if not s2_[k].includes(s2[k]): error += 1 total = nb_states * len(variables) self.assertEqual( precision, 1.0 - (error / total) ) #eprint("precision: ", precision) # error of size state_id = random.randint(0, len(expected)-1) modif = random.randint(1,len(expected[state_id])) expected[state_id] = ( expected[state_id][0][:-modif], expected[state_id][1] ) self.assertRaises(ValueError, ContinuumLogicProgram.precision, expected, predicted)
def random_program(self, variables=None, domains=None): if variables is None: variables, domains = self.random_system() rules = [] for j in range(random.randint(0, self.__nb_rules)): r = self.random_rule(variables, domains) rules.append(r) return ContinuumLogicProgram(variables, domains, rules)
def test___init__(self): print(">> ContinuumLogicProgram.__init__(self, variables, domains, rules)") for i in range(self.__nb_unit_test): variables, domains = self.random_system() rules = [] for j in range(random.randint(0,self.__nb_rules)): r = self.random_rule(variables, domains) rules.append(r) p = ContinuumLogicProgram(variables, domains, rules) self.assertEqual(p.get_variables(), variables) self.assertEqual(p.get_domains(), domains) self.assertEqual(p.get_rules(), rules) modif = random.randint(1,len(variables)) self.assertRaises(ValueError, ContinuumLogicProgram, variables, domains[:-modif], rules) for var in range(0, modif): domains.append(Continuum.random(self.__min_value, self.__max_value, self.__min_domain_size)) self.assertRaises(ValueError, ContinuumLogicProgram, variables, domains, rules)
def test_fit(self): eprint(">> ACEDIA.fit(variables, values, transitions)") for i in range(self.__nb_unit_test): eprint("\rTest ", i + 1, "/", self.__nb_unit_test, end='') # Generate transitions epsilon = random.choice([0.1, 0.25, 0.3, 0.5]) variables, domains = self.random_system() p = ContinuumLogicProgram.random(variables, domains, 1, len(variables), epsilon) #eprint("Progam: ", p) # Valid and realistic epsilon #epsilon = round(random.uniform(0.1,1.0), 2) #while epsilon == 1.0: # epsilon = round(random.uniform(0.1,1.0), 2) t = p.generate_all_transitions(epsilon) #sys.exit() #eprint("Transitions: ") #for s1, s2 in t: # eprint(s1, s2) #eprint("Transitions: ", t) p_ = ACEDIA.fit(p.get_variables(), p.get_domains(), t) rules = p_.get_rules() #eprint("learned: ", p_) # All transitions are realized #------------------------------ for head_var in range(len(p.get_variables())): for s1, s2 in t: for idx, val in enumerate(s2): realized = 0 for r in rules: if r.get_head_variable( ) == idx and r.get_head_value().includes( val) and r.matches(s1): realized += 1 break if realized <= 0: eprint("head_var: ", head_var) eprint("s1: ", s1) eprint("s2: ", s2) eprint("learned: ", p_) self.assertTrue( realized >= 1) # One rule realize the example # All rules are minimals #------------------------ for r in rules: #eprint("r: ", r) # Try reducing head min #----------------------- r_ = r.copy() h = r_.get_head_value() if h.get_min_value() + epsilon <= h.get_max_value(): r_.set_head_value( Continuum(h.get_min_value() + epsilon, h.get_max_value(), h.min_included(), h.max_included())) #eprint("spec: ", r_) conflict = False for s1, s2 in t: if not r_.get_head_value().includes( s2[r_.get_head_variable()]) and r_.matches( s1): # Cover a negative example conflict = True #eprint("conflict") break if not conflict: eprint("Non minimal rule: ", r) eprint("head can be specialized into: ", r_.get_head_variable(), "=", r_.get_head_value()) self.assertTrue(conflict) # Try reducing head max #----------------------- r_ = r.copy() h = r_.get_head_value() if h.get_max_value() - epsilon >= h.get_min_value(): r_.set_head_value( Continuum(h.get_min_value(), h.get_max_value() - epsilon, h.min_included(), h.max_included())) #eprint("spec: ", r_) conflict = False for s1, s2 in t: if not r_.get_head_value().includes( s2[r_.get_head_variable()]) and r_.matches( s1): # Cover a negative example conflict = True #eprint("conflict") break if not conflict: eprint("Non minimal rule: ", r) eprint("head can be generalized to: ", r_.get_head_variable(), "=", r_.get_head_value()) self.assertTrue(conflict) # Try extending condition #------------------------- for (var, val) in r.get_body(): # Try extend min r_ = r.copy() if val.get_min_value( ) - epsilon >= domains[var].get_min_value(): val_ = val.copy() if not val_.min_included(): val_.set_lower_bound(val_.get_min_value(), True) else: val_.set_lower_bound( val_.get_min_value() - epsilon, False) r_.set_condition(var, val_) #eprint("gen: ", r_) conflict = False for s1, s2 in t: if not r_.get_head_value().includes( s2[r_.get_head_variable()]) and r_.matches( s1): # Cover a negative example conflict = True #eprint("conflict") break if not conflict: eprint("Non minimal rule: ", r) eprint("condition can be generalized: ", var, "=", val_) self.assertTrue(conflict) # Try extend max r_ = r.copy() if val.get_max_value( ) + epsilon <= domains[var].get_max_value(): val_ = val.copy() if not val_.max_included(): val_.set_upper_bound(val_.get_max_value(), True) else: val_.set_upper_bound( val_.get_max_value() + epsilon, False) r_.set_condition(var, val_) #eprint("gen: ", r_) conflict = False for s1, s2 in t: if not r_.get_head_value().includes( s2[r_.get_head_variable()]) and r_.matches( s1): # Cover a negative example conflict = True #eprint("conflict") break if not conflict: eprint("Non minimal rule: ", r) eprint("condition can be generalized: ", var, "=", val_) self.assertTrue(conflict) eprint()
def test_random(self): print(">> ContinuumLogicProgram.random(variables, values, rule_min_size, rule_max_size, epsilon, delay=1)") # No delay for i in range(self.__nb_unit_test): variables, domains = self.random_system() min_body_size = 0 max_body_size = random.randint(min_body_size, len(variables)) # Valid and realistic epsilon epsilon = round(random.uniform(0.1,1.0), 2) while epsilon == 1.0: epsilon = round(random.uniform(0.1,1.0), 2) p = ContinuumLogicProgram.random(variables, domains, min_body_size, max_body_size, epsilon) #eprint(p.to_string()) self.assertEqual(p.get_variables(), variables) self.assertEqual(p.get_domains(), domains) for r in p.get_rules(): self.assertTrue(len(r.get_body()) >= min_body_size) self.assertTrue(len(r.get_body()) <= max_body_size) states = ContinuumLogicProgram.states(domains, epsilon) for s in states: for var in range(len(s)): matched = False conclusion = -1 for r in p.get_rules(): if r.get_head_variable() == var and r.matches(s): matched = True #if conclusion == -1: # stored first conclusion # conclusion = r.get_head_value() #else: # check conflict # self.assertEqual(conclusion, r.get_head_value()) self.assertTrue(matched) # Delay for i in range(self.__nb_unit_test): variables, domains = self.random_system() min_body_size = 0 max_body_size = random.randint(min_body_size, len(variables)) delay = random.randint(1, self.__max_delay) # Valid and realistic epsilon epsilon = round(random.uniform(0.1,1.0), 2) while epsilon == 1.0: epsilon = round(random.uniform(0.1,1.0), 2) p = ContinuumLogicProgram.random(variables, domains, min_body_size, max_body_size, epsilon, delay) #eprint(p.logic_form()) extended_variables = variables.copy() extended_domains = domains.copy() for d in range(1,delay): extended_variables += [var+"_"+str(d) for var in variables] extended_domains += domains self.assertEqual(p.get_variables(), variables) self.assertEqual(p.get_domains(), domains) for r in p.get_rules(): self.assertTrue(len(r.get_body()) >= min_body_size) self.assertTrue(len(r.get_body()) <= max_body_size) states = ContinuumLogicProgram.states(extended_domains, epsilon) for s in states: for var in range(len(variables)): matched = False conclusion = -1 for r in p.get_rules(): if r.get_head_variable() == var and r.matches(s): matched = True break #if conclusion == -1: # stored first conclusion # conclusion = r.get_head_value() #else: # check conflict # self.assertEqual(conclusion, r.get_head_value()) #if not matched: #eprint(s) #eprint(p) self.assertTrue(matched)
def test_generate_all_transitions(self): print(">> ContinuumLogicProgram.generate_all_transitions(epsilon)") for i in range(self.__nb_unit_test): variables, domains = self.random_system() p = self.random_program(variables, domains) # bad epsilon epsilon = random.uniform(-100, 0) self.assertRaises(ValueError, p.generate_all_transitions, epsilon) epsilon = random.uniform(0, 0.1) while epsilon == 0.0 or epsilon == 0.1: epsilon = random.uniform(0, 0.1) self.assertRaises(ValueError, p.generate_all_transitions, epsilon) epsilon = random.uniform(1.0, 100) while epsilon == 1.0: epsilon = random.uniform(1.0, 100) self.assertRaises(ValueError, p.generate_all_transitions, epsilon) # Valid and realistic epsilon epsilon = round(random.uniform(self.__min_epsilon,1.0), 2) while epsilon == 1.0: epsilon = round(random.uniform(self.__min_epsilon,1.0), 2) #eprint("epsilon: ", epsilon) transitions = p.generate_all_transitions(epsilon) #eprint(p.to_string()) #eprint("transitions: ", transitions) #eprint("Nb transitions: ", len(transitions)) #eprint(transitions) # All initial state appears S = ContinuumLogicProgram.states(p.get_domains(), epsilon) init = [s1 for s1, s2 in transitions] #eprint("init: ", init) #eprint("S: ", S) #eprint() for s in S: s2 = p.next(s) if None in s2: # uncomplete states ignored continue appears = False for s1 in init: different = False for idx in range(len(s1)): if abs(s1[idx]-s[idx]) > 0.0001: different = True break if not different: appears = True break self.assertTrue(appears) # All transitions appears and are valid for s1, s2 in transitions: # all transitions from s1 S = p.next(s1) S = ContinuumLogicProgram.states(S, epsilon) # s2 is a transion of s1 self.assertTrue(s2 in S) # All transitions from s1 appears for s3 in S: self.assertTrue( [s1,s3] in transitions)