def test_fit(self): print(">> LUST.fit(data, features, targets)") # No transitions p = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) p_ = LUST.fit([], p.get_features(), p.get_targets()) self.assertEqual(len(p_),1) p_ = p_[0] self.assertEqual(p_.get_features(),p.get_features()) self.assertEqual(p_.get_targets(),p.get_targets()) self.assertEqual(p_.get_rules(),[]) for i in range(self.__nb_unit_test): #eprint("test: ", i, "/", self.__nb_unit_test) nb_programs = random.randint(1,self.__max_programs) transitions = [] p_ = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) features = p_.get_features() targets = p.get_targets() for j in range(nb_programs): # Generate transitions min_body_size = 0 max_body_size = random.randint(min_body_size, len(features)) p = LogicProgram.random(features, targets, min_body_size, max_body_size) transitions += Synchronous.transitions(p) #eprint(p.logic_form()) #eprint(transitions) t = LUST.encode_transitions_set(transitions, p.get_features(), p.get_targets()) P = LUST.fit(t, features, targets) #rules = p_.get_rules() # Generate transitions predictions = [] for p in P: #eprint(p.logic_form()) predictions += Synchronous.transitions(p) # Remove incomplete states #predictions = [ [s1,s2] for s1,s2 in predictions if -1 not in s2 ] #eprint("Expected: ", transitions) #eprint("Predicted: ", predictions) # All original transitions are predicted for s1, s2 in transitions: self.assertTrue([s1,s2] in predictions) # All predictions are in original transitions for s1, s2 in predictions: #eprint(s1,s2) self.assertTrue([s1,s2] in transitions)
def random_program(self, nb_features, nb_targets, nb_values, body_size): features = [("x"+str(i), ["val_"+str(val) for val in range(0,random.randint(2,nb_values))]) for i in range(random.randint(1,nb_features))] targets = [("y"+str(i), ["val_"+str(val) for val in range(0,random.randint(2,nb_values))]) for i in range(random.randint(1,nb_targets))] rules = [] for j in range(random.randint(0,100)): r = self.random_rule(features, targets, body_size) rules.append(r) return LogicProgram(features, targets, rules)
def test_fit(self): print(">> LFkT.fit(variables, values, time_series)") # No transitions p = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) min_body_size = 0 max_body_size = random.randint(min_body_size, len(p.get_features())) delay_original = random.randint(2, self.__max_delay) features = [] targets = p.get_targets() for d in range(1, delay_original + 1): features += [(var + "_" + str(d), vals) for var, vals in p.get_features()] p = LogicProgram.random(features, targets, min_body_size, max_body_size) p_ = LFkT.fit([], p.get_features(), p.get_targets()) self.assertEqual(p_.get_features(), p.get_features()) self.assertEqual(p_.get_targets(), p.get_targets()) self.assertEqual(p_.get_rules(), []) for i in range(self.__nb_unit_test): #eprint("\rTest ", i+1, "/", self.__nb_unit_test, end='') # Generate transitions p = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) min_body_size = 0 max_body_size = random.randint(min_body_size, len(p.get_features())) delay_original = random.randint(2, self.__max_delay) features = [] targets = p.get_features() for d in range(0, delay_original): features += [(var + "_t-" + str(d + 1), vals) for var, vals in p.get_features()] p = LogicProgram.random(features, targets, min_body_size, max_body_size) cut = len(targets) time_series = [[ list(s[cut * (d - 1):cut * d]) for d in range(1, delay_original + 1) ] for s in p.feature_states()] #eprint(delay_original) #eprint(p) #eprint(p.states()) #eprint(time_series) #exit() time_serie_size = delay_original + 2 for serie in time_series: while len(serie) < time_serie_size: serie_end = serie[-delay_original:] #eprint(serie_end) serie_end = list(itertools.chain.from_iterable(serie_end)) serie.append(Synchronous.next(p, serie_end)[0]) #eprint(p.logic_form()) #for s in time_series: # eprint(s) p_ = LFkT.fit(time_series, targets, targets) rules = p_.get_rules() #eprint(p_.logic_form()) for variable in range(len(targets)): for value in range(len(targets[variable][1])): #eprint("var="+str(variable)+", val="+str(value)) pos, neg, delay = LFkT.interprete(time_series, targets, targets, variable, value) #eprint("pos: ", pos) # Each positive is explained for s in pos: cover = False for r in rules: if r.get_head_variable() == variable \ and r.get_head_value() == value \ and r.matches(s): cover = True #if not cover: # eprint(p_) # eprint(s) self.assertTrue(cover) # One rule cover the example #eprint("neg: ", neg) # No negative is covered for s in neg: cover = False for r in rules: if r.get_head_variable() == variable \ and r.get_head_value() == value \ and r.matches(s): cover = True self.assertFalse(cover) # no rule covers the example # All rules are minimals for r in rules: if r.get_head_variable( ) == variable and r.get_head_value() == value: for (var, val) in r.get_body(): r.remove_condition(var) # Try remove condition conflict = False for s in neg: if r.matches( s): # Cover a negative example conflict = True break # # DEBUG: if not conflict: eprint("not minimal " + r.to_string()) eprint(neg) self.assertTrue(conflict) r.add_condition(var, val) # Cancel removal
def test_interprete(self): print(">> LUST.interprete(variables, values, transitions)") for i in range(self.__nb_unit_test): #eprint("test: ", i, "/", self.__nb_unit_test) # No transitions p_ = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) features = p_.get_features() targets = p_.get_targets() min_body_size = 0 max_body_size = random.randint(min_body_size, len(features)) p = LogicProgram.random(features, targets, min_body_size, max_body_size) DC, DS = LUST.interprete([]) self.assertEqual(DC,[]) self.assertEqual(DS,[]) # Regular case nb_programs = random.randint(1,self.__max_programs) transitions = [] for j in range(nb_programs): # Generate transitions min_body_size = 0 max_body_size = random.randint(min_body_size, len(features)) p = LogicProgram.random(features, targets, min_body_size, max_body_size) transitions += Synchronous.transitions(p) #eprint(p.logic_form()) #eprint(transitions) DC, DS = LUST.interprete(transitions) D = [] ND = [] for s1, s2 in transitions: deterministic = True for s3, s4 in transitions: if s1 == s3 and s2 != s4: ND.append( [s1,s2] ) deterministic = False break if deterministic: D.append( [s1,s2] ) #eprint("DC: ",DC) #eprint("DS: ",DS) #eprint("D: ",D) #eprint("ND: ",ND) # All deterministic are only in DC for s1, s2 in D: self.assertTrue([s1,s2] in DC) for s in DS: self.assertTrue([s1,s2] not in s) # All DC are deterministic for s1, s2 in DC: self.assertTrue([s1,s2] in D) # All non deterministic sets are set for s in DS: for s1, s2 in s: occ = 0 for s3, s4 in s: if s1 == s3 and s2 == s4: occ += 1 self.assertEqual(occ,1) # All input origin state appears in each DS TODO for s1, s2 in ND: for s in DS: occurs = False for s3, s4 in s: if s1 == s3: occurs = True self.assertTrue(occurs) # All DS are deterministic for s in DS: for s1, s2 in s: for s3, s4 in s: if s1 == s3: self.assertTrue(s2 == s4)
def test_interprete(self): print(">> LFkT.interprete(transitions, variable, value)") for i in range(self.__nb_unit_test): #eprint("Start test ", i, "/", self.__nb_unit_test) # Generate transitions p = self.random_program(self.__nb_features, self.__nb_targets, self.__nb_values, self.__body_size) min_body_size = 0 max_body_size = random.randint(min_body_size, len(p.get_features())) delay_original = random.randint(1, self.__max_delay) features = [] targets = p.get_features() for d in range(0, delay_original): features += [(var + "_t-" + str(d + 1), vals) for var, vals in p.get_features()] p = LogicProgram.random(features, targets, min_body_size, max_body_size) #eprint("Generating series...") cut = len(targets) time_series = [[ list(s[cut * (d - 1):cut * d]) for d in range(1, delay_original + 1) ] for s in p.feature_states()] #eprint(delay_original) #eprint(p) #eprint(p.states()) #eprint(time_series) #exit() time_serie_size = delay_original + 2 for serie in time_series: while len(serie) < time_serie_size: serie_end = serie[-delay_original:] #eprint(serie_end) serie_end = list(itertools.chain.from_iterable(serie_end)) serie.append(Synchronous.next(p, serie_end)[0]) var = random.randint(0, len(targets) - 1) val = random.randint(0, len(targets[var]) - 1) #eprint("interpreting...") pos, neg, delay = LFkT.interprete(time_series, targets, targets, var, val) # DBG #eprint("variables: ", variables) #eprint("values", values) #eprint("delay: ", delay_original) #eprint(p.logic_form()) #eprint(time_series) #eprint("var: ", var) #eprint("val: ", val) #eprint("pos: ", pos) #eprint("neg: ",neg) #eprint("delay detected: ", delay) # All pos are valid for s in pos: for serie in time_series: for id in range(len(serie) - delay): s1 = serie[id:id + delay].copy() #s1.reverse() s1 = [y for x in s1 for y in x] #eprint(s1) #eprint(s) s2 = serie[id + delay] if s1 == s: self.assertEqual(s2[var], val) break # All neg are valid for s in neg: for serie in time_series: for id in range(len(serie) - delay): s1 = serie[id:id + delay].copy() #s1.reverse() s1 = [y for x in s1 for y in x] s2 = serie[id + delay] if s1 == s: self.assertTrue(s2[var] != val) break # All transitions are interpreted #eprint("var/val: ", var, "/", val) #eprint("delay: ", delay) #eprint("Time serie: ", time_series) for serie in time_series: #eprint("checking: ", serie) for id in range(delay, len(serie)): s1 = serie[id - delay:id].copy() #s1.reverse() s1 = [y for x in s1 for y in x] s2 = serie[id] #eprint("s1: ", s1, ", s2: ", s2) #eprint("pos: ", pos) #eprint("neg: ", neg) if s2[var] == val: self.assertTrue(s1 in pos) self.assertFalse(s1 in neg) else: self.assertFalse(s1 in pos) self.assertTrue(s1 in neg) # delay valid global_delay = 1 for serie_1 in time_series: for id_state_1 in range(len(serie_1) - 1): state_1 = serie_1[id_state_1] next_1 = serie_1[id_state_1 + 1] # search duplicate with different future for serie_2 in time_series: for id_state_2 in range(len(serie_2) - 1): state_2 = serie_2[id_state_2] next_2 = serie_2[id_state_2 + 1] # Non-determinism detected if state_1 == state_2 and next_1[var] != next_2[ var]: local_delay = 2 id_1 = id_state_1 id_2 = id_state_2 while id_1 > 0 and id_2 > 0: previous_1 = serie_1[id_1 - 1] previous_2 = serie_2[id_2 - 1] if previous_1 != previous_2: break local_delay += 1 id_1 -= 1 id_2 -= 1 global_delay = max(global_delay, local_delay) self.assertTrue(local_delay <= delay) self.assertEqual(delay, global_delay)