class Simulated_annealing_learner: def __init__(self, seed, initial_t, data, annealer): self.randomizer = Randomizer(seed) self.annealer = annealer self.T = initial_t self.data = data # self.hyp = self.annealer.find_initial_hypthesis(data) self.hyp = self.annealer.initial_hypothesis() self.creation_time = datetime.datetime.now() def simulated_annealing(self, create_plots, positive_examples, output_directory, threshold, alpha): assert (0 < alpha < 1) and (0 < threshold) and (self.T > 0) iter_counter = 0 p = None if create_plots: # Initial hypothesis self.hyp.plot_transitions( 'hyp_%d ; E_%s' % (iter_counter, self.annealer.metric_calc(self.hyp, positive_examples)), output_directory) while self.T > threshold: iter_counter += 1 info("# ITERATION COUNTER =", iter_counter) info("Current temperature:", self.T) H_tag = self.annealer.get_random_neighbor(self.hyp, self.data) delta = self.annealer.energy_difference_a_minus_b( H_tag, self.hyp, positive_examples) info("Delta =", delta) if delta < 0: p = 1 else: p = math.exp(-delta / self.T) if p >= self.randomizer.get_prng().random(): info("Changing hypothesis\n") self.hyp = H_tag else: info("Didn't change hypothesis\n") energy = self.annealer.metric_calc(self.hyp, positive_examples) if create_plots: self.hyp.plot_transitions( 'hyp_%d ; E_%s' % (iter_counter, energy), output_directory) self.T *= alpha info("CHOSEN HYPOTHESIS:\n", self.hyp) return self.hyp, positive_examples def logger(self, create_plots, positive_examples, output_directory, threshold, alpha): info("# APPLYING LEARNER ON THE FOLLOWING POSITIVE EXAMPLES: %s" % ','.join(positive_examples)) info("\nInitial temperature:", self.T, ", Threshold:", threshold, ", Alpha:", alpha) info("\n# INITIAL HYPOTHESIS:\n", self.hyp) info("\n") return self.simulated_annealing(create_plots, positive_examples, output_directory, threshold, alpha)
class DFA_Annealer: def __init__(self, seed): self.randomizer = Randomizer(seed) def __flip_acceptance_of_random_state(self, dfa): randomly_chosen_state = self.randomizer.get_prng().choice( list(dfa.states - {'qF'})) new_transitions = deepcopy(dfa.transitions) if '#' in new_transitions[randomly_chosen_state]: new_transitions[randomly_chosen_state].pop('#') else: new_transitions[randomly_chosen_state]['#'] = 'qF' new_dfa = DFA(deepcopy(dfa.states), new_transitions, 'q0', deepcopy(dfa.accepting)) info(new_dfa) return new_dfa def initial_hypothesis(self): """ Returns a DFA that accepts all strings """ states = {'q0', 'qF'} transitions = {'q0': {'0': 'q0', '1': 'q0', '#': 'qF'}} initial_state = 'q0' accepting_states = {'qF'} return DFA(states, transitions, initial_state, accepting_states) @staticmethod def energy_difference_a_minus_b(dfa_a, dfa_b, positive_examples): metric_eval_a = DFA_Annealer.metric_calc(dfa_a, positive_examples) # info("Evaluation of suggested hypothesis =", metric_eval_a) metric_eval_b = DFA_Annealer.metric_calc(dfa_b, positive_examples) # info("Evaluation of current hypothesis =", metric_eval_b) return metric_eval_a - metric_eval_b def get_random_neighbor(self, dfa, positive_examples): """ Chooses randomly a potential random neighbor and calls function try_option in order to check the validity of the chosen neighbor. If the random neighbor is not valid for some reason (as will be described in the try_option documantion), the function will re-choose a potential neighbor. Number of retries is limited to 20. Once a valid neighbor is found, it will be returned by the function. If by the end of 20 tries it doesn't find a valid neighbor, the current DFA is returned. """ options = [ self.__flip_acceptance_of_random_state, self.__remove_final_state, self.__switching_transitions, self.__add_final_state, self.__increase_accepting_from_left, self.__increase_accepting_from_right, self.__decrease_accepting_from_left, self.__decrease_accepting_from_right, self.__remove_transition_from_qn, self.__remove_self_transitions ] for i in range(20): #Limited to 20 tries if i >= 1: info("Raffles another hypothesis.") chosen_option = self.randomizer.get_prng().choice(options) result_dfa = self.__try_option(dfa, positive_examples, chosen_option) if result_dfa is not None: result_dfa.positive_examples = dfa.positive_examples return result_dfa return dfa @staticmethod def metric_calc(dfa, positive_examples): len_g = len(dfa.encode()) len_d_g = sum( dfa.encode_positive_example(string) for string in positive_examples) return len_g + len_d_g ''' Functions for getting random neighbor ''' def __add_final_state(self, dfa): """ Returns a DFA with one more state than the given DFA, which will be the new final state. The acceptance of the new final state will be identical to the acceptance of the previous final state @param DFA: DFA with n states @return new_DFA: DFA with n+1 states """ # finding final state of given DFA prev_final_state = "q" + str(len(dfa.states) - 2) # finding final state of new DFA new_final_state = "q" + str(len(dfa.states) - 1) # Building new DFA new_states = dfa.states | {new_final_state} # Adding new final state new_transitions = deepcopy(dfa.transitions) if new_transitions['q0'].get('0') == 'q0': new_transitions[prev_final_state]['1'] = new_final_state else: new_transitions[prev_final_state]['0'] = new_final_state new_transitions[new_final_state] = {} new_transitions[new_final_state]['0'] = new_final_state new_transitions[new_final_state]['1'] = new_final_state # new final state will agree with acceptance of prev final state if dfa.reaches_qf(prev_final_state): new_transitions[new_final_state]['#'] = 'qF' new_accepting = deepcopy(dfa.accepting) new_dfa = DFA(new_states, new_transitions, 'q0', new_accepting) info(new_dfa) return new_dfa def __remove_final_state(self, dfa): """ Returns a DFA with one less state than the given DFA @param DFA: DFA with n states @return new_DFA: DFA with n-1 states """ # Getting q_n of given DFA prev_final_state = "q" + str(len(dfa.states) - 2) # Removing q_n from states new_states = dfa.states - {prev_final_state} # Getting q_n of new DFA new_final_state = "q" + str(len(new_states) - 2) # Deleting transitions associated with q_n from transitions new_transitions = deepcopy(dfa.transitions) new_transitions[new_final_state]['0'] = new_final_state new_transitions[new_final_state]['1'] = new_final_state del new_transitions[prev_final_state] # Removing prev_final_state from accepting states of new dfa, if necessary new_accepting = dfa.accepting - {prev_final_state} new_dfa = DFA(new_states, new_transitions, 'q0', new_accepting) info(new_dfa) return new_dfa def __switching_transitions(delf, dfa): new_initial = 'q0' new_states = deepcopy(dfa.states) new_accepting = deepcopy(dfa.accepting) # Changing transitions def switch(edge_label): return '0' if edge_label == '1' else ( '1' if edge_label == '0' else edge_label) new_transitions = { state: { switch(edge_label): dfa.transitions[state][edge_label] for edge_label in dfa.transitions[state] } for state in new_states - {'qF'} } new_dfa = DFA(new_states, new_transitions, new_initial, new_accepting) info(new_dfa) return new_dfa def __change_accepting_states(self, dfa, refer_state, size_change): """ @param DFA: DFA with n states and x accpeting states @param refer_state: 'first_acc' for left-most accepting state or 'last_acc' for right-most accepting state. @param size_change: 'increase' or 'decrease'. @return new_DFA: DFA with change in accepting states per the other parameters. """ accepting_ints = [ int(state[1:]) for state in dfa.states if dfa.reaches_qf(state) ] new_transitions = deepcopy(dfa.transitions) if refer_state == 'first_acc': min_acc_index = min(accepting_ints) if size_change == 'decrease' or min_acc_index == 0: new_transitions['q' + str(min_acc_index)].pop('#') else: new_transitions['q' + str(min_acc_index - 1)]['#'] = 'qF' else: max_acc_index = max(accepting_ints) if size_change == 'decrease' or max_acc_index == len( dfa.states) - 2: new_transitions['q' + str(max_acc_index)].pop('#') else: new_transitions['q' + str(max_acc_index + 1)]['#'] = 'qF' new_dfa = DFA(deepcopy(dfa.states), new_transitions, 'q0', deepcopy(dfa.accepting)) info(new_dfa) return new_dfa def __decrease_accepting_from_right(self, dfa): """ @param DFA: DFA with n states and x accpeting states @return new_DFA: DFA with n and x+1 or x-1 accepting states, depanding on random choice """ return self.__change_accepting_states(dfa, 'last_acc', 'decrease') def __decrease_accepting_from_left(self, dfa): """ @param DFA: DFA with n states and x accpeting states @return new_DFA: DFA with n and x+1 or x-1 accepting states, depanding on random choice """ return self.__change_accepting_states(dfa, 'first_acc', 'decrease') def __increase_accepting_from_right(self, dfa): """ @param DFA: DFA with n states and x accpeting states @return new_DFA: DFA with n and x+1 or x-1 accepting states, depanding on random choice """ return self.__change_accepting_states(dfa, 'last_acc', 'increase') def __increase_accepting_from_left(self, dfa): """ @param DFA: DFA with n states and x accpeting states @return new_DFA: DFA with n and x+1 or x-1 accepting states, depanding on random choice """ return self.__change_accepting_states(dfa, 'first_acc', 'increase') def __get_index_of_qn(self, dfa): return max(i for i in range(len(dfa.states)) if ('q%s' % i) in dfa.states) def __remove_self_transitions(self, dfa): new_transitions = { state: { edge_label: dfa.transitions[state][edge_label] for edge_label in dfa.transitions[state] if dfa.transitions[state][edge_label] != state } for state in dfa.transitions } new_dfa = DFA(deepcopy(dfa.states), new_transitions, 'q0', deepcopy(dfa.accepting)) info(new_dfa) return new_dfa def __remove_transition_from_qn(self, dfa): new_transitions = deepcopy(dfa.transitions) last_state_index = self.__get_index_of_qn(dfa) if last_state_index is not None: last_state = 'q%s' % last_state_index if all(symbol not in dfa.transitions[last_state] for symbol in ['0', '1']): return deepcopy(dfa) if last_state_index == 0 or any( symbol not in dfa.transitions[last_state] for symbol in ['0', '1']): transition_to_remove = self.randomizer.get_prng().choice([ symbol for symbol in dfa.transitions[last_state] if symbol != '#' ]) else: prev_state = 'q%s' % (last_state_index - 1) transition_to_remove = '0' if new_transitions[prev_state].get( '0') == last_state else '1' new_transitions[last_state].pop(transition_to_remove) new_dfa = DFA(deepcopy(dfa.states), new_transitions, 'q0', deepcopy(dfa.accepting)) info(new_dfa) return new_dfa def __try_option(self, dfa, positive_examples, chosen_option): """ Checks whether a chosen neighbor is valid, i.e: 1) Accepts all pairs in data 2) Doesn't reduce a state from an only-state machine If one of the above doesn't hold, None is returned. Otherwise, the chosen neighbor is returned. """ info("Random neighbor to be checked:", chosen_option.__name__) if len(dfa.states) <= 2 and chosen_option == self.__remove_final_state: info("Neigbor will cause dfa to have 0 states.") return None neighbor = chosen_option(dfa) # Check whether the neighbor dfa recognizes all couples in data # If not, return old dfa (i.e don't use neighbor). Otherwise, return neighbor for sample in positive_examples: if not neighbor.recognize(sample): info("Neighbor didn't recognize one of the pairs in data: %s" % sample) return None info("Neighbor is valid.") return neighbor
class SingleSimulationRunner(object): def __init__(self, create_plots, seed): self.create_plots = create_plots self.randomizer = Randomizer(seed) def make_list_of_set_pairs_for_determiner_EXACTLY( self, ns, min_sample_for_each_n, max_sample_for_each_n, min_zeros_per_positive_example, max_zeros_per_positive_example): pairs = [] for n in ns: pairs.extend([(set( range(n + self.randomizer.get_prng().randint( min_zeros_per_positive_example, max_zeros_per_positive_example))), set(range(n))) for _ in range(self.randomizer.get_prng().randint( min_sample_for_each_n, max_sample_for_each_n))]) return pairs def simulate_EXACTLY(self, initial_temperature, threshold, alpha, ns, min_sample_for_each_n, max_sample_for_each_n, min_zeros_per_positive_example, max_zeros_per_positive_example): data = self.make_list_of_set_pairs_for_determiner_EXACTLY( ns, min_sample_for_each_n, max_sample_for_each_n, min_zeros_per_positive_example, max_zeros_per_positive_example) return self.__simulate_with_data( 'EXACTLY', dict( ns=ns, min_sample_for_each_n=min_sample_for_each_n, max_sample_for_each_n=max_sample_for_each_n, min_zeros_per_positive_example=min_zeros_per_positive_example, max_zeros_per_positive_example=max_zeros_per_positive_example), data, initial_temperature, threshold, alpha) def make_list_of_set_pairs_quantifier_ALL_OF_THE_EXACTLY( self, ns, min_sample_for_each_n, max_sample_for_each_n): pairs = [] for n in ns: pairs.extend([(set(range(n)), set(range(n))) for _ in range(self.randomizer.get_prng().randint( min_sample_for_each_n, max_sample_for_each_n))]) return pairs def simulate_ALL_OF_THE_EXACTLY(self, initial_temperature, threshold, alpha, ns, min_sample_for_each_n, max_sample_for_each_n): data = self.make_list_of_set_pairs_quantifier_ALL_OF_THE_EXACTLY( ns, min_sample_for_each_n, max_sample_for_each_n) return self.__simulate_with_data( 'ALL_OF_THE_EXACTLY', dict(ns=ns, min_sample_for_each_n=min_sample_for_each_n, max_sample_for_each_n=max_sample_for_each_n), data, initial_temperature, threshold, alpha) def make_list_of_set_pairs_for_quantifier_all(self, min_set_size, max_set_size, number_of_pairs): lists = [] for i in range(number_of_pairs): list_size = self.randomizer.get_prng().choice( range(min_set_size, max_set_size)) lists.append((set(range(list_size)), set(range(list_size)))) return lists def make_list_of_set_pairs_for_quantifier_none(self, min_set_size, max_set_size, number_of_pairs): lists = [] for i in range(number_of_pairs): list_size = self.randomizer.get_prng().choice( range(min_set_size, max_set_size)) lists.append((set(range(list_size)), set())) return lists def make_list_of_set_pairs_for_quantifier_between( self, at_least_ones, at_most_ones, min_size_of_universe, max_size_of_universe, number_of_positive_examples, add_examples_which_are_all_ones_of_these_lengths=[]): """ Returns pairs, each of which will later be transformed into a binary string, which represents set membership. In each pair: 1) First element is the universe: a set {0,...,M}, where M is a random number in [min_list_size, ..., max_list_size]. 2) Second element is a random subset {0,...,K}, where K is in [at_least, ..., at_most]. More precisely, K is in [at_least,..., M] if M < at_most. Thus generally speaking, the result is multiple instances of the generalized quantifier, each taken at random from a random size universe. Numeric example: at_least=3 at_most=6 min_list_size=20 max_list_size=40 number_of_lists=18 We'll get 18 pairs. Example of one pair: (L1, L2) where L1 = {0, 1, 2, ..., 32} L2 = set(range(self.randomizer.get_prng().choice(range(3, min(7, 33))))) = set(range(self.randomizer.get_prng().choice(range(3, 7))) = set(range(22)) :param at_least_ones: :param at_most_ones: :param min_size_of_universe: :param max_size_of_universe: :param number_of_positive_examples: :return: """ if not all(at_least_ones <= length <= at_most_ones for length in add_examples_which_are_all_ones_of_these_lengths): raise ValueError('Length to add is out of allowed range') positive_examples_as_pairs_of_sets = [] for i in range(number_of_positive_examples): universe_size = self.randomizer.get_prng().choice( range(min_size_of_universe, max_size_of_universe)) univese_set = set(range(universe_size)) subset_of_universe = set( range(self.randomizer.get_prng().choice( range(at_least_ones, min(at_most_ones + 1, universe_size))))) positive_examples_as_pairs_of_sets.append( (univese_set, subset_of_universe)) positive_examples_as_pairs_of_sets.extend( (set(range(length)), set(range(length))) for length in add_examples_which_are_all_ones_of_these_lengths) return positive_examples_as_pairs_of_sets def simulate_whatever(self): DOGS = {'Rex', 'Spot', 'Bolt', 'Belka', 'Laika', 'Azit'} BROWN_ANIMALS = {'Belka', 'Spot', 'Azit', 'Mitzi'} SATELLITES = { 'Yaogan', 'Ofeq_7', 'Ofeq_9', 'WorldView', 'Eros_B', 'Amos_5', 'Glonass' } LOW_EARTH_ORBIT = { 'Yaogan', 'Ofeq_7', 'Ofeq_9', 'WorldView', 'Eros_B', 'Hubble' } data = [(DOGS, BROWN_ANIMALS), (SATELLITES, LOW_EARTH_ORBIT)] DOGS = {'Rex', 'Spot', 'Bolt', 'Belka', 'Laika', 'Azit'} BROWN_ANIMALS = { 'Rex', 'Spot', 'Bolt', 'Belka', 'Laika', 'Azit', 'IKEA table', 'Humus' } SATELLITES = {'Yaogan', 'Ofeq_7', 'Ofeq_9', 'WorldView', 'Eros_B'} LOW_EARTH_ORBIT = { 'Yaogan', 'Ofeq_7', 'Ofeq_9', 'WorldView', 'Eros_B', 'Hubble' } BOYS = {'Tom', 'John', 'Max', 'Mark', 'Barak', 'Guy', 'Ted', 'Joey'} HAPPY = { 'Linda', 'Mary', 'Tom', 'John', 'Max', 'Mark', 'Barak', 'Guy', 'Ted', 'Joey' } data5 = [(DOGS, BROWN_ANIMALS), (SATELLITES, LOW_EARTH_ORBIT), (BOYS, HAPPY)] # ALL GROUP_A = {'hello'} GROUP_B = {'hello'} GROUP_C = {'0', '2', '6', '17'} GROUP_D = {'0', '2', '6', '17'} data_1 = [(GROUP_A, GROUP_B), (GROUP_C, GROUP_D)] # Minimal Quantifier: NONE CATS = {'Mitzi', 'Tuli', 'KitKat', 'Chat', 'Ears'} TWEET = {'Tweety', 'Zebra Finch', 'Cockatoo'} HAVE_ONE_SOUL = {'Rex', 'John'} data7 = [(CATS, TWEET), (CATS, HAVE_ONE_SOUL), (CATS, DOGS)] def simulate_data_3(self): def make_list_of_set_pairs_2(at_least_not, at_most_not, list_size): Q = frozenset(range(1, at_most_not * 2)) return [(frozenset(self.randomizer.get_prng().sample( Q, len(Q) - self.randomizer.get_prng().randint( at_least_not, at_most_not))), Q) for i in range(list_size)] data3 = make_list_of_set_pairs_2(at_least_not=3, at_most_not=7, list_size=50) assert all(len(Q) - 10 <= len(P) <= len(Q) - 0 for P, Q in data3) def create_output_directory(self, quantifier_type, additional_parameters_to_persist, positive_examples, initial_temperature, threshold, alpha): output_directory = os.path.join( run_dir(quantifier_type, initial_temperature, alpha, threshold), ('runid[%s]' % uuid.uuid4().hex)) os.makedirs(output_directory) with open(os.path.join(output_directory, 'parameters.csv'), 'w') as params_f: params_f.write('initial_temperature,%s\n' % initial_temperature) params_f.write('threshold,%s\n' % threshold) params_f.write('alpha,%s\n' % alpha) for param_name, param_value in additional_parameters_to_persist.items( ): params_f.write('%s,%s\n' % (param_name, param_value)) with open(os.path.join(output_directory, 'positive_examples.txt'), 'w') as pos_f: pos_f.write('\n'.join(positive_examples)) return output_directory def __simulate_with_data(self, quantifier_type, additional_parameters_to_persist, data, initial_temperature, threshold, alpha): positive_examples = [ get_binary_representation(Randomizer(self.randomizer.seed), set_a, set_b) for set_a, set_b in data ] output_directory = self.create_output_directory( quantifier_type, additional_parameters_to_persist, positive_examples, initial_temperature, threshold, alpha) annealer = DFA_Annealer(self.randomizer.seed) learner = Simulated_annealing_learner(self.randomizer.seed, initial_temperature, data, annealer) final_hyp = learner.logger(self.create_plots, positive_examples, output_directory, threshold, alpha)[0] return output_directory, final_hyp, positive_examples def simulate_BETWEEN_with_dynamic_universe_size( self, initial_temperature, threshold, alpha, add_examples_which_are_all_ones_of_these_lengths, at_least_ones, at_most_ones, min_size_of_universe, max_size_of_universe, number_of_positive_examples): data = self.make_list_of_set_pairs_for_quantifier_between( at_least_ones, at_most_ones, min_size_of_universe, max_size_of_universe, number_of_positive_examples, add_examples_which_are_all_ones_of_these_lengths) return self.__simulate_with_data( 'BETWEEN_WITH_DYNAMIC_UNIVERSE_SIZE', dict(add_examples_which_are_all_ones_of_these_lengths= add_examples_which_are_all_ones_of_these_lengths, at_least_ones=at_least_ones, at_most_ones=at_most_ones, min_size_of_universe=min_size_of_universe, max_size_of_universe=max_size_of_universe, number_of_positive_examples=number_of_positive_examples), data, initial_temperature, threshold, alpha) def simulate_BETWEEN_with_fixed_universe_size(self, initial_temperature, threshold, alpha, all_ones, at_least_ones, at_most_plus_1_ones, fixed_universe_size, number_of_positive_examples): data = self.make_list_of_set_pairs_for_quantifier_between( at_least_ones, at_most_plus_1_ones, min_size_of_universe=fixed_universe_size, max_size_of_universe=fixed_universe_size + 1, number_of_positive_examples=number_of_positive_examples, add_examples_which_are_all_ones_of_these_lengths=all_ones) return self.__simulate_with_data( 'BETWEEN_WITH_FIXED_UNIVERSE_SIZE', dict(all_ones=all_ones, at_least_ones=at_least_ones, at_most_plus_1_ones=at_most_plus_1_ones, fixed_universe_size=fixed_universe_size, number_of_positive_examples=number_of_positive_examples), data, initial_temperature, threshold, alpha) def simulate_ALL(self, initial_temperature, threshold, alpha, min_set_size, max_set_size, number_of_pairs): data = self.make_list_of_set_pairs_for_quantifier_all( min_set_size, max_set_size, number_of_pairs) return self.__simulate_with_data( 'ALL', dict(min_set_size=min_set_size, max_set_size=max_set_size, number_of_pairs=number_of_pairs), data, initial_temperature, threshold, alpha) def simulate_NONE(self, initial_temperature, threshold, alpha, min_set_size, max_set_size, number_of_pairs): data = self.make_list_of_set_pairs_for_quantifier_none( min_set_size, max_set_size, number_of_pairs) return self.__simulate_with_data( 'NONE', dict(min_set_size=min_set_size, max_set_size=max_set_size, number_of_pairs=number_of_pairs), data, initial_temperature, threshold, alpha) def run_single_simulation(self, quantifier_type, initial_temperature, threshold, alpha, *args, **kwargs): info('############ Starting simulation for quantifier %s' % quantifier_type) quantifier_names_to_functions = { 'BETWEEN_WITH_DYNAMIC_UNIVERSE_SIZE': self.simulate_BETWEEN_with_dynamic_universe_size, 'NONE': self.simulate_NONE, 'EXACTLY': self.simulate_EXACTLY, 'ALL': self.simulate_ALL, 'ALL_OF_THE_EXACTLY': self.simulate_ALL_OF_THE_EXACTLY, 'BETWEEN_WITH_FIXED_UNIVERSE_SIZE': self.simulate_BETWEEN_with_fixed_universe_size } qunatifier_names_to_target_dfa = { 'NONE': target_automaton.expected_final_hyp_none(), 'ALL': target_automaton.expected_final_hyp_all(), 'BETWEEN_WITH_FIXED_UNIVERSE_SIZE': target_automaton.expected_final_hyp_between_with_any_universe_size( lower=kwargs.get('at_least_ones'), upper=kwargs.get('at_most_plus_1_ones')), 'BETWEEN_WITH_DYNAMIC_UNIVERSE_SIZE': target_automaton.expected_final_hyp_between_with_any_universe_size( lower=kwargs.get('at_least_ones'), upper=kwargs.get('at_most_ones')), 'EXACTLY': target_automaton.expected_final_hyp_exactly(kwargs.get('ns')), 'ALL_OF_THE_EXACTLY': target_automaton.expected_final_hyp_all_of_the_exactly( kwargs.get('ns')) } if quantifier_type in quantifier_names_to_functions: output_directory, final_hyp, positive_examples = quantifier_names_to_functions[quantifier_type] \ (initial_temperature, threshold, alpha, *args, **kwargs) final_hyp.plot_transitions('final_hyp', output_directory) is_success = ( final_hyp == qunatifier_names_to_target_dfa[quantifier_type]) with open(os.path.join(output_directory, 'is_success.txt'), 'w') as f_success: f_success.write(str(is_success)) # with open(os.path.join(output_directory, 'energy_final_hyp_minus_target.csv'), 'w') as final_diff_f: # final_diff_f.write(str(DFA_Annealer.energy_difference_a_minus_b( # final_hyp, # qunatifier_names_to_target_dfa[quantifier_type], # positive_examples)) if quantifier_type in qunatifier_names_to_target_dfa \ # else 'No target automaton defined') info( '############ Finished simulation for quantifier %s, output in %s' % (quantifier_type, output_directory)) return is_success else: raise ValueError('Unknown quantifier type %s' % quantifier_type)