def calculate_outputs(self): """ calculate the output of the net using the current input values (e.g. generated using generate_random_inputs above) and output values. Note that for generating the SatProblem, all variables are prefixed (using 'x'), because valid identifiers must start with a letter (and some ISCAS files use names like 11gat). The abnormal predicate of every gate is named AB<gate>, e.g. ABx11gat. """ vars = [] for input, value in self.inputs.iteritems(): vars.append(Variable(prefix(input), Variable.BOOLEAN, value)) for output, value in self.outputs.iteritems(): vars.append(Variable(prefix(output), Variable.BOOLEAN, value)) for gate in set(self.gates.keys()) - set(self.outputs.keys()): vars.append(Variable(prefix(gate), Variable.BOOLEAN, None)) sentences = [] for output, gate in self.gates.iteritems(): sentences.append(GateSentence(prefix_gate(gate))) p = Problem(self.sat_engine_name) result = p.solve(Description(vars, sentences)) outputs = result.get_values() p.finished() for output, value in outputs.iteritems(): if output[ 1:] in self.outputs: # just set outputs, no internal lines! self.outputs[output[1:]] = value return result.sat()
def test_generate_model_parameter1(self): config = observer_configuration(type="hz", resource=['/topic']) topics_published_from_nodes = {'/topic': ['/node1', '/node2']} topics_subscribed_from_nodes = {} nodes_publish_topics = {'/node1': ['/topic'], '/node2': ['/topic']} nodes_subscribe_topics = {} vars, rules, nodes, real_nodes = HzObserver.generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics) vars_req = {'hz_obs_/topic_all': Variable('hz_obs_/topic_all', 1, None), 'hz_obs_/topic_/node1': Variable('hz_obs_/topic_/node1', 1, None), 'hz_obs_/topic_/node2': Variable('hz_obs_/topic_/node2', 1, None)} self.assertEqual(len(vars), len(vars_req), "Hz added wrong number of variables!") for i, obj in vars.items(): self.assertTrue(i in vars_req, "Key '" + str(i) + "' not in variables-required list!") self.assertEqual(str(vars_req[i]), str(obj), "Variable '" + str(i) + "' not generated with right parameters!") subscribed_topics = [] rules_req = [HzObserver(ab_pred('/node1'), 'hz_obs_/topic_/node1', subscribed_topics), HzObserver(ab_pred('/node2'), 'hz_obs_/topic_/node2', subscribed_topics), CalleridsObserver('hz_obs_/topic_all', ['hz_obs_/topic_/node1', 'hz_obs_/topic_/node2'])] rules_req_str = [str(x) for x in rules_req] self.assertTrue(not any([x for x in rules if str(x) not in rules_req_str]), "Rules does not match!") self.assertEqual(len(rules), len(rules_req), "Hz added wrong number of rules!") self.assertEqual(len(nodes), 0, "Hz should not add nodes!") self.assertEqual(len(real_nodes), 0, "Hz should not add real nodes!")
def construct_problem_for_reuse(self): vars = [] sentences = [] # primary input variables are constrained to their value for input, value in self.inputs.iteritems(): vars.append(Variable(prefix(input), Variable.BOOLEAN, value)) # primary output variables are constrained to their value for output, value in self.outputs.iteritems(): vars.append(Variable(prefix(output), Variable.BOOLEAN, value)) # all other output variables (internal lines) are unconstrained for gate in set(self.gates.keys()) - set(self.outputs.keys()): vars.append(Variable(prefix(gate), Variable.BOOLEAN, None)) # create a variable for the AB predicate of each gate: for gate in set(self.gates.keys()): vars.append(Variable(ab_pred(prefix(gate)), Variable.BOOLEAN, None)) # all gates are equipped with (not ABx => (= x ...)) for gate in set(self.gates.keys()): sentences.append( GateWithAbPredicate(ab_pred(prefix(gate)), prefix_gate(self.gates[gate]))) return vars, sentences
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): topics = config.resource checkInputData.list_data_valid(topics) checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=False, allow_empty=False) checkInputData.dict_data_valid(topics_subscribed_from_nodes, check_entries=False, allow_empty=True) checkInputData.dict_data_valid(nodes_publish_topics, check_entries=False, allow_empty=False) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=False, allow_empty=True) vars = {} rules = [] nodes = [] for topic in topics: checkInputData.list_data_valid(topics_published_from_nodes[topic]) vars[topic] = Variable(topic, Variable.BOOLEAN, None) vars[ab_pred(topic)] = Variable(ab_pred(topic), Variable.BOOLEAN, None) nodes.append(topic) nodes_publish = topics_published_from_nodes[topic] data = {} for node in nodes_publish: subscribed_topics = nodes_subscribe_topics.get(node, []) published_topics = nodes_publish_topics.get(node, []) data[ab_pred(str(node))] = (all_ab_pred(subscribed_topics), all_ab_pred(published_topics)) rules.append(GeneralObserver(ab_pred(topic), data)) return vars, rules, nodes, []
def test_generate_model_parameter1(self): # config = {'topics': [['/topicA', '/topicB']], 'type': 'velocity'} config = observer_configuration(type="velocity", resource=['/topicA', '/topicB']) topics_published_from_nodes = { '/topicA': ['/node1'], '/topicB': ['/node2'] } topics_subscribed_from_nodes = {} nodes_publish_topics = {'/node1': ['/topicA'], '/node2': ['/topicB']} nodes_subscribe_topics = {} vars, rules, nodes, real_nodes = VelocityObserver.generate_model_parameter( config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics) vars_req = { 'velocity': Variable("velocity", Variable.BOOLEAN, None), ab_pred("velocity"): Variable(ab_pred("velocity"), Variable.BOOLEAN, None), 'velocity_obs_/topicA_/topicB': Variable('velocity_obs_/topicA_/topicB', 1, None), } self.assertEqual(len(vars), len(vars_req), "Velocity added wrong number of variables!") for i, obj in vars.items(): self.assertTrue( vars_req.has_key(i), "Key '" + str(i) + "' not in variables-required list!") self.assertEqual( str(vars_req[i]), str(obj), "Variable '" + str(i) + "' not generated with right parameters!") subscribed_topics = [] rules_req = [(VelocityObserver(all_ab_pred(['/node1']), all_ab_pred(['/node2']), ab_pred("velocity"), 'velocity_obs_/topicA_/topicB', all_ab_pred([])))] rules_req_str = [str(x) for x in rules_req] self.assertTrue( not any([x for x in rules if str(x) not in rules_req_str]), "Rules does not match!") self.assertEqual(len(rules), len(rules_req), "velocity added wrong number of rules!") self.assertEqual(len(nodes), 0, "Velocity should not add nodes!") self.assertEqual(len(real_nodes), 1, "Velocity should add one real node!") self.assertEqual(str(real_nodes[0]), 'velocity', "'Velocity' not added to real nodes!")
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): config_type = str('timestamp') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') # checkInputData.dict_data_valid(config, False) # topics = config['topics'] topics = config.resource checkInputData.list_data_valid(topics, num_entries=1) # checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=False, allow_empty=False) # checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=False, allow_empty=True) checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=True, entry_type=list, allow_empty=False) checkInputData.list_data_valid(topics_published_from_nodes.keys(), check_entries=True) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=True, entry_type=list, allow_empty=True) vars = {} rules = [] nodes = [] topic = topics[0] callerids = topics_published_from_nodes.get(topic, []) checkInputData.list_data_valid(callerids, allow_empty=False) for callerid in callerids: observation = config_type + "_obs_" + topic + "_" + callerid vars[observation] = Variable(observation, Variable.BOOLEAN, None) subscribed_topics = nodes_subscribe_topics.get(callerid, []) rules.append( TimestampObserver(ab_pred(str(callerid)), observation, all_ab_pred(subscribed_topics))) if not set(subscribed_topics).issubset( topics_published_from_nodes.keys()): raise ValueError( 'subscribed topics are not not in topics published list!') new_vars, new_rules, new_nodes = CalleridsObserver.generate_model_parameter( config_type, topic, topics_published_from_nodes[topic]) vars.update(new_vars) rules += new_rules nodes += new_nodes return vars, rules, nodes, []
def test_generate_model_parameter2(self): # config = {'nodes': ['node1', 'node2', 'node3'], 'type': 'resources'} config = observer_configuration(type="resources", resource=['node1']) topics_published_from_nodes = {'/topic3': ['node3'], '/topic2': ['node2'], '/topic1': ['node1']} topics_subscribed_from_nodes = {'node3': ['/topic2'], 'node2': ['/topic1']} nodes_publish_topics = {'node1': ['/topic1'], 'node3': ['/topic3'], 'node2': ['/topic2']} nodes_subscribe_topics = {'node3': ['/topic2'], 'node2': ['/topic1']} vars, rules, nodes, real_nodes = ResourcesObserver.generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics) vars_req = {'resources_obs_node1': Variable('resources_obs_node1', 1, None), # 'resources_obs_node2': Variable('resources_obs_node2', 1, None), # 'resources_obs_node3': Variable('resources_obs_node3', 1, None) } self.assertEqual(len(vars), len(vars_req), "resources added wrong number of variables!") for i, obj in vars.items(): self.assertTrue(vars_req.has_key(i), "Key '" + str(i) + "' not in variables-required list!") self.assertEqual(str(vars_req[i]), str(obj), "Variable '" + str(i) + "' not generated with right parameters!") rules_req = [ResourcesObserver(ab_pred('node1'), 'resources_obs_node1', all_ab_pred([])), # ResourcesObserver(ab_pred('node2'), 'resources_obs_node2', all_ab_pred(['/topic1'])), # ResourcesObserver(ab_pred('node3'), 'resources_obs_node3', all_ab_pred(['/topic2'])) ] rules_req_str = [str(x) for x in rules_req] self.assertTrue(not any([x for x in rules if str(x) not in rules_req_str]), "Rules does not match!") self.assertEqual(len(rules), len(rules_req), "resources added wrong number of rules!") self.assertEqual(len(nodes), 0, "resources should not add nodes!") self.assertEqual(len(real_nodes), 0, "resources should not add real nodes!")
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): config_type = str('resources') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') nodes = config.resource checkInputData.list_data_valid(nodes, num_entries=1) # checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=False, allow_empty=True) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=True, entry_type=list, allow_empty=True) vars = {} rules = [] node = nodes[0] observation = config_type + "_obs_" + node vars[observation] = Variable(observation, Variable.BOOLEAN, None) subscribed_topics = nodes_subscribe_topics.get(node, []) rules.append(ResourcesObserver(ab_pred(node), observation, all_ab_pred(subscribed_topics))) if not set(subscribed_topics).issubset(topics_published_from_nodes.keys()): raise ValueError('subscribed topics are not not in topics published list!') return vars, rules, [], []
def test_generate_model_parameter(self): vars, rules, nodes = CalleridsObserver.generate_model_parameter("hz", "/topic1", ["/node1", "node2"]) vars_req = {'hz_obs_/topic1_all': Variable('hz_obs_/topic1_all', 1, None)} self.assertEqual(len(vars), len(vars_req), "Hz added wrong number of variables!") for i, obj in vars.items(): self.assertTrue(vars_req.has_key(i), "Key '" + str(i) + "' not in variables-required list!") self.assertEqual(str(vars_req[i]), str(obj), "Variable '" + str(i) + "' not generated with right parameters!") rules_req = [CalleridsObserver('hz_obs_/topic1_all', ['hz_obs_/topic1_/node1', 'hz_obs_/topic1_node2'])] self.assertEqual(str(rules[0]), str(rules_req[0]), "Rules does not match!") self.assertEqual(len(rules), len(rules_req), "Added wrong number of rules!") self.assertEqual(len(rules), 1, "Callerids observer should add only one rule!") self.assertEqual(len(nodes), 0, "Callerids observer should not add nodes!") with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("", "topic1", ["node1", "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("/", "topic1", ["node1", "node2"]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter(1, "topic1", ["node1", "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "", ["node1", "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "/", ["node1", "node2"]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", 1, ["node1", "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", ["", "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", ["/", "node2"]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", "topic1", [1, "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", [ab_pred("/"), "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", [ab_pred(""), "node2"]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", "topic1", [ab_pred(1), "node2"]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", ["node1", ""]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", ["node1", "/"]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", "topic1", ["node1", 1]) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", []) with self.assertRaises(ValueError): CalleridsObserver.generate_model_parameter("hz", "topic1", [""]) with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", "topic1", "") with self.assertRaises(TypeError): CalleridsObserver.generate_model_parameter("hz", "topic1", 1)
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): ''' Read config for the observer module and generate model. Model is returned via vars, rules, nodes and real_nodes. :param config: configuration for this observer module :param topics_published_from_nodes: dict with topic as key and list of nodes that publishs it :param topics_subscribed_from_nodes: dict with topic as key and list of nodes that subscribes it :param nodes_publish_topics: dict with node as key and list of topics that are published by them :param nodes_subscribe_topics: dict with node as key and list of topics that are subscribed by them :return: vars: dict of new added variables rules: list of new added rules nodes: list of new added nodes real_nodes: list of new added real nodes ''' config_type = str('hz') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') topics = config.resource checkInputData.list_data_valid(topics, num_entries=1) checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=True, entry_type=list, allow_empty=False) checkInputData.list_data_valid(topics_published_from_nodes.keys(), check_entries=True) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=True, entry_type=list, allow_empty=True) vars = {} rules = [] nodes = [] topic = topics[0] callerids = topics_published_from_nodes.get(topic, []) # checkInputData.list_data_valid(callerids, allow_empty=True) checkInputData.list_data_valid(callerids, allow_empty=False) # if not len(callerids): # return {}, [], [], [] for callerid in callerids: observation = config_type + "_obs_" + topic + "_" + callerid vars[observation] = Variable(observation, Variable.BOOLEAN, None) subscribed_topics = nodes_subscribe_topics.get(callerid, []) rules.append(HzObserver(ab_pred(str(callerid)), observation, all_ab_pred(subscribed_topics))) if not set(subscribed_topics).issubset(topics_published_from_nodes.keys()): raise ValueError('subscribed topics are not not in topics published list!') new_vars, new_rules, new_nodes = CalleridsObserver.generate_model_parameter(config_type, topic, topics_published_from_nodes[topic]) vars.update(new_vars) rules += new_rules nodes += new_nodes return vars, rules, nodes, []
def generate_model_parameter(obs_type, topic, callerids): vars = {} rules = [] checkInputData.str_data_valid(obs_type) checkInputData.str_data_valid(topic) checkInputData.list_data_valid(callerids) observation_all = obs_type + "_obs_" + topic + "_all" observations_w_prefix = [obs_type + "_obs_" + topic + "_" + obs for obs in callerids] vars[observation_all] = Variable(observation_all, Variable.BOOLEAN, None) rules.append(CalleridsObserver(observation_all, observations_w_prefix)) return vars, rules, []
def generate_model_parameter_2(obs_type, topic_a, callerids_a, topic_b, callerids_b): vars = {} rules = [] checkInputData.str_data_valid(obs_type) checkInputData.str_data_valid(topic_a) checkInputData.str_data_valid(topic_b) checkInputData.list_data_valid(callerids_a) checkInputData.list_data_valid(callerids_b) observation_all_all = obs_type + "_obs_" + topic_a + "_all_" + topic_b + "_all" vars[observation_all_all] = Variable(observation_all_all, Variable.BOOLEAN, None) observations_all_items = [obs_type + "_obs_" + topic_a + "_all_" + topic_b + "_" + obs_item for obs_item in callerids_b] rules.append(CalleridsObserver(observation_all_all, observations_all_items)) observations_items_all = [obs_type + "_obs_" + topic_a + "_" + obs_item + "_" + topic_b + "_all" for obs_item in callerids_a] rules.append(CalleridsObserver(observation_all_all, observations_items_all)) for node_a in callerids_a: observations_item_all = obs_type + "_obs_" + topic_a + "_" + node_a + "_" + topic_b + "_all" vars[observations_item_all] = Variable(observations_item_all, Variable.BOOLEAN, None) observations_item_items = [obs_type + "_obs_" + topic_a + "_" + node_a + "_" + topic_b + "_" + obs for obs in callerids_b] rules.append(CalleridsObserver(observations_item_all, observations_item_items)) for node_b in callerids_b: observations_all_item = obs_type + "_obs_" + topic_a + "_all_" + topic_b + "_" + node_b vars[observations_all_item] = Variable(observations_all_item, Variable.BOOLEAN, None) observations_items_item = [obs_type + "_obs_" + topic_a + "_" + obs + "_" + topic_b + "_" + node_b for obs in callerids_a] rules.append(CalleridsObserver(observations_all_item, observations_items_item)) return vars, rules, []
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): config_type = str('activated') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') nodes = config.resource checkInputData.list_data_valid(nodes, num_entries=1) vars = {} rules = [] node = nodes[0] observation = config_type + "_obs_" + node vars[observation] = Variable(observation, Variable.BOOLEAN, None) rules.append(ActivatedObserver(ab_pred(str(node)), observation)) return vars, rules, [], []
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): config_type = str('velocity') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') topics = config.resource checkInputData.list_data_valid(topics, num_entries=2) checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=True, entry_type=list, allow_empty=False) checkInputData.list_data_valid(topics_published_from_nodes.keys(), check_entries=True) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=True, entry_type=list, allow_empty=True) vars = {} rules = [] real_nodes = [] real_nodes.append(config_type) vars[config_type] = Variable(config_type, Variable.BOOLEAN, None) vars[ab_pred(config_type)] = Variable(ab_pred(config_type), Variable.BOOLEAN, None) topic_pair = topics checkInputData.list_data_valid(topic_pair, check_entries=True, allow_empty=False) topic_a = topic_pair[0] topic_b = topic_pair[1] if not set(topic_pair).issubset(topics_published_from_nodes.keys()): raise ValueError('topics are not not in topics published list!') observation = config_type + "_obs_" + topic_a + "_" + topic_b vars[observation] = Variable(observation, Variable.BOOLEAN, None) nodes_a = topics_published_from_nodes.get(topic_a, []) nodes_b = topics_published_from_nodes.get(topic_b, []) checkInputData.list_data_valid(nodes_a, check_entries=True, allow_empty=False) checkInputData.list_data_valid(nodes_b, check_entries=True, allow_empty=False) subscribed_topics = [] [ subscribed_topics.extend(nodes_subscribe_topics.get(node, [])) for node in nodes_a + nodes_b ] rules.append( VelocityObserver(all_ab_pred(nodes_a), all_ab_pred(nodes_b), ab_pred(config_type), observation, all_ab_pred(subscribed_topics))) if not set(subscribed_topics).issubset( topics_published_from_nodes.keys()): raise ValueError( 'subscribed topics are not not in topics published list!') return vars, rules, [], real_nodes
def check_consistency(self, h): """ Calculate a conflict set by constraining the AB predicates depending on a gates inclusion in h. These new sentences are added to the problem and the SAT solver is started again. If it returns SAT, the hitting set h is consistent, otherwise it returns UNSAT. """ if self.options['separate_tp'] == True: self.check_queries += 1 if self.check_queries > 100 or self.options['relaunch_sat_solver']: self.check_queries = 0 self.check_problem.finished() self.check_problem = Problem(self.sat_engine_name) self.first_check_call = True else: self.queries += 1 if self.queries > 100 or self.options['relaunch_sat_solver']: self.queries = 0 self.check_problem.finished() self.check_problem = Problem(self.sat_engine_name) self.comp_problem = self.check_problem self.first_check_call = True self.first_comp_call = True if self.options['reuse_sat']: if self.first_check_call: self.first_check_call = False if self.options[ 'separate_tp'] == True and self.check_problem == self.comp_problem: self.check_problem = Problem(self.sat_engine_name) vars, sentences = self.construct_problem_for_reuse() sentences.append(PushSentence()) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()) - h: sentences.append( AbConstraint(prefix(gate), False, extended=False)) for gate in h: sentences.append( AbConstraint(prefix(gate), True, extended=False)) # is this problem satisfiable? r = self.check_problem.solve(Description(vars, sentences), calculate_unsat_core=False) return r.sat() else: # (not self.first_check_consistency) sentences = [] sentences.append(PopSentence()) sentences.append(PushSentence()) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()) - h: sentences.append( AbConstraint(prefix(gate), False, extended=False)) for gate in h: sentences.append( AbConstraint(prefix(gate), True, extended=False)) # is this problem satisfiable? r = self.check_problem.solve_again(sentences, calculate_unsat_core=False) return r.sat() else: # (not self.reuse_sat) if self.options[ 'separate_tp'] == True and self.check_problem == self.comp_problem: self.check_problem = Problem(self.sat_engine_name) vars = [] sentences = [] # primary input variables are constrained to their value for input, value in self.inputs.iteritems(): vars.append(Variable(prefix(input), Variable.BOOLEAN, value)) # primary output variables are constrained to their value for output, value in self.outputs.iteritems(): vars.append(Variable(prefix(output), Variable.BOOLEAN, value)) # all other output variables (internal lines) are unconstrained for gate in set(self.gates.keys()) - set(self.outputs.keys()): vars.append(Variable(prefix(gate), Variable.BOOLEAN, None)) # all gate outputs except those in `h' behave according to their gate function for gate in set(self.gates.keys()) - h: sentences.append(GateSentence(prefix_gate(self.gates[gate]))) # is this problem satisfiable? r = self.check_problem.solve(Description(vars, sentences), calculate_unsat_core=False) return r.sat()
def calculate_conflicts(self, h): """ Calculate a conflict set by constraining the AB predicates depending on a gates inclusion in h. These new sentences are added to the problem and the SAT solver is started again. This should return a new UNSAT core, which is returned as new conflict set. """ if self.options['separate_tp'] == True: self.comp_queries += 1 if self.comp_queries > 100 or self.options['relaunch_sat_solver']: self.comp_queries = 0 self.comp_problem.finished() self.comp_problem = Problem(self.sat_engine_name) self.first_comp_call = True else: self.queries += 1 if self.queries > 100 or self.options['relaunch_sat_solver']: self.queries = 0 self.check_problem.finished() self.check_problem = Problem(self.sat_engine_name) self.comp_problem = self.check_problem self.first_check_call = True self.first_comp_call = True if self.options['reuse_sat']: if self.first_comp_call: self.first_comp_call = False vars, sentences = self.construct_problem_for_reuse() sentences.append(PushSentence()) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()) - h: sentences.append(AbConstraint(prefix(gate), False)) for gate in h: sentences.append(AbConstraint(prefix(gate), True)) # get me an unsatisfiable core of AB predicates r = self.comp_problem.solve(Description(vars, sentences), calculate_unsat_core=True) if (r.sat()): return None else: conflict = map(lambda x: x[1:], r.get_unsat_core()) return frozenset(conflict) else: # not self.first_calculate_conflicts: sentences = [] sentences.append(PopSentence()) sentences.append(PushSentence()) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()) - h: sentences.append(AbConstraint(prefix(gate), False)) for gate in h: sentences.append(AbConstraint(prefix(gate), True)) r = self.comp_problem.solve_again(sentences, calculate_unsat_core=True) if (r.sat()): return None else: conflict = map(lambda x: x[1:], r.get_unsat_core()) return frozenset(conflict) else: # (not self.reuse_sat) vars = [] sentences = [] # primary input variables are constrained to their value for input, value in self.inputs.iteritems(): vars.append(Variable(prefix(input), Variable.BOOLEAN, value)) # primary output variables are constrained to their value for output, value in self.outputs.iteritems(): vars.append(Variable(prefix(output), Variable.BOOLEAN, value)) # all other output variables (internal lines) are unconstrained for gate in set(self.gates.keys()) - set(self.outputs.keys()): vars.append(Variable(prefix(gate), Variable.BOOLEAN, None)) # create a variable for the AB predicate of each gate except those in `h': for gate in set(self.gates.keys()) - h: vars.append( Variable(ab_pred(prefix(gate)), Variable.BOOLEAN, None)) # all gates except those in `h' are equipped with (not ABx => (= x ...)) for gate in set(self.gates.keys()) - h: sentences.append( GateWithAbPredicate(ab_pred(prefix(gate)), prefix_gate(self.gates[gate]))) sentences.append(PushSentence()) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()) - h: sentences.append(AbConstraint(prefix(gate), False)) # get me an unsatisfiable core of AB predicates r = self.comp_problem.solve(Description(vars, sentences), calculate_unsat_core=True) if (r.sat()): return None else: conflict = map(lambda x: x[1:], r.get_unsat_core()) return frozenset(conflict)
def calculate_next_diagnosis(self, blocked_diagnoses, max_card=None, find_all_sols=False): """ """ if self.queries > 100 or self.options['relaunch_sat_solver'] or ( self.sat_engine_name == "yices-cn-cnf" and self.last_max_card != max_card): self.queries = 0 self.check_problem.finished() self.check_problem = Problem(self.sat_engine_name) self.comp_problem = self.check_problem self.first_check_call = True self.first_comp_call = True blocked_diagnoses = set( blocked_diagnoses) | self.previous_diagnoses self.last_max_card = max_card if self.options['reuse_sat']: self.ab_vars = [] if self.first_comp_call: self.first_comp_call = False vars, sentences = self.construct_problem_for_reuse() # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()): sentences.append( AbConstraint(prefix(gate), False, weight=1)) self.ab_vars.append("AB" + prefix(gate)) for diag in blocked_diagnoses: sentences.append(BlockingSentence(diag)) # get me an unsatisfiable core of AB predicates r = self.comp_problem.solve(Description(vars, sentences), calculate_unsat_core=True, max_card=max_card, find_all_sols=find_all_sols, ab_vars=self.ab_vars) if r: self.previous_diagnoses |= frozenset(r) return r else: # not self.first_calculate_conflicts: sentences = [] for diag in blocked_diagnoses: sentences.append(BlockingSentence(diag)) r = self.comp_problem.solve_again(sentences, calculate_unsat_core=True, max_card=max_card, find_all_sols=find_all_sols, ab_vars=self.ab_vars) if r: self.previous_diagnoses |= frozenset(r) return r else: # (not self.reuse_sat) vars = [] sentences = [] ab_vars = [] # primary input variables are constrained to their value for input, value in self.inputs.iteritems(): vars.append(Variable(prefix(input), Variable.BOOLEAN, value)) # primary output variables are constrained to their value for output, value in self.outputs.iteritems(): vars.append(Variable(prefix(output), Variable.BOOLEAN, value)) # all other output variables (internal lines) are unconstrained for gate in set(self.gates.keys()) - set(self.outputs.keys()): vars.append(Variable(prefix(gate), Variable.BOOLEAN, None)) # create a variable for the AB predicate of each gate except those in `h': for gate in set(self.gates.keys()): vars.append( Variable(ab_pred(prefix(gate)), Variable.BOOLEAN, None)) # all gates except those in `h' are equipped with (not ABx => (= x ...)) for gate in set(self.gates.keys()): sentences.append( GateWithAbPredicate(ab_pred(prefix(gate)), prefix_gate(self.gates[gate]))) # for all gates not in h set the AB predicate to false. for gate in set(self.gates.keys()): sentences.append(AbConstraint(prefix(gate), False, weight=1)) ab_vars.append("AB" + prefix(gate)) for diag in blocked_diagnoses: sentences.append(BlockingSentence(diag)) # get me an unsatisfiable core of AB predicates r = self.comp_problem.solve(Description(vars, sentences), calculate_unsat_core=True, ab_vars=ab_vars, max_card=max_card, find_all_sols=find_all_sols) if r: self.previous_diagnoses |= frozenset(r) return r
def test_generate_model_parameter3(self): # +----------+ /topicA +---------+ /topicB # | starter1 |----------+ +-->| timing1 |----------+ # +----------+ | | +---------+ | # *--* +---> # +----------+ /topicA | | +---------+ /topicB | # | starter2 |----------> +-->| timing2 |----------+ # +----------+ +---------+ # config = {'topics': [['/topicA', '/topicB']], 'type': 'timing'} config = observer_configuration(type="timing", resource=['/topicA', '/topicB']) topics_published_from_nodes = { '/topicA': ['node1', 'node3'], '/topicB': ['node2', 'node4'] } topics_subscribed_from_nodes = {'/topicA': ['node2', 'node4']} nodes_publish_topics = { 'node1': ['/topicA'], 'node2': ['/topicB'], 'node3': ['/topicA'], 'node4': ['/topicB'] } nodes_subscribe_topics = {'node2': ['/topicA'], 'node4': ['/topicA']} vars, rules, nodes, real_nodes = TimingObserver.generate_model_parameter( config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics) vars_req = {} vars_req = { 'timing_obs_/topicA_node1_/topicB_all': Variable('timing_obs_/topicA_node1_/topicB_all', 1, None), 'timing_obs_/topicA_node3_/topicB_node4': Variable('timing_obs_/topicA_node3_/topicB_node4', 1, None), 'timing_obs_/topicA_node3_/topicB_all': Variable('timing_obs_/topicA_node3_/topicB_all', 1, None), 'timing_obs_/topicA_node3_/topicB_node2': Variable('timing_obs_/topicA_node3_/topicB_node2', 1, None), 'timing_obs_/topicA_all_/topicB_all': Variable('timing_obs_/topicA_all_/topicB_all', 1, None), 'timing_obs_/topicA_all_/topicB_node4': Variable('timing_obs_/topicA_all_/topicB_node4', 1, None), 'timing_obs_/topicA_all_/topicB_node2': Variable('timing_obs_/topicA_all_/topicB_node2', 1, None), 'timing_obs_/topicA_node1_/topicB_node2': Variable('timing_obs_/topicA_node1_/topicB_node2', 1, None), 'timing_obs_/topicA_node1_/topicB_node4': Variable('timing_obs_/topicA_node1_/topicB_node4', 1, None), } self.assertEqual(len(vars), len(vars_req), "Timing added wrong number of variables!") for i, obj in vars.items(): self.assertTrue( vars_req.has_key(i), "Key '" + str(i) + "' not in variables-required list!") self.assertEqual( str(vars_req[i]), str(obj), "Variable '" + str(i) + "' not generated with right parameters!") rules_req = [ TimingObserver( all_ab_pred(['node2', 'node4']), 'timing_obs_/topicA_node1_/topicB_node2', all_ab_pred(nodes_subscribe_topics.get('node2', []))), TimingObserver( all_ab_pred(['node2', 'node4']), 'timing_obs_/topicA_node1_/topicB_node4', all_ab_pred(nodes_subscribe_topics.get('node4', []))), TimingObserver( all_ab_pred(['node2', 'node4']), 'timing_obs_/topicA_node3_/topicB_node2', all_ab_pred(nodes_subscribe_topics.get('node2', []))), TimingObserver( all_ab_pred(['node2', 'node4']), 'timing_obs_/topicA_node3_/topicB_node4', all_ab_pred(nodes_subscribe_topics.get('node4', []))), CalleridsObserver('timing_obs_/topicA_all_/topicB_all', [ 'timing_obs_/topicA_all_/topicB_node2', 'timing_obs_/topicA_all_/topicB_node4' ]), CalleridsObserver('timing_obs_/topicA_all_/topicB_all', [ 'timing_obs_/topicA_node1_/topicB_all', 'timing_obs_/topicA_node3_/topicB_all' ]), CalleridsObserver('timing_obs_/topicA_node1_/topicB_all', [ 'timing_obs_/topicA_node1_/topicB_node2', 'timing_obs_/topicA_node1_/topicB_node4' ]), CalleridsObserver('timing_obs_/topicA_node3_/topicB_all', [ 'timing_obs_/topicA_node3_/topicB_node2', 'timing_obs_/topicA_node3_/topicB_node4' ]), CalleridsObserver('timing_obs_/topicA_all_/topicB_node2', [ 'timing_obs_/topicA_node1_/topicB_node2', 'timing_obs_/topicA_node3_/topicB_node2' ]), CalleridsObserver('timing_obs_/topicA_all_/topicB_node4', [ 'timing_obs_/topicA_node1_/topicB_node4', 'timing_obs_/topicA_node3_/topicB_node4' ]), ] rules_req_str = [str(x) for x in rules_req] self.assertTrue( not any([x for x in rules if str(x) not in rules_req_str]), "Rules does not match!") self.assertEqual(len(rules), len(rules_req), "Timing added wrong number of rules!") self.assertEqual(len(nodes), 0, "Timing should not add nodes!") self.assertEqual(len(real_nodes), 0, "Timing should not add real nodes!")
def generate_model_parameter(config, topics_published_from_nodes, topics_subscribed_from_nodes, nodes_publish_topics, nodes_subscribe_topics): config_type = str('timing') if not isinstance(config, observer_configuration): raise TypeError if not config.type == config_type: raise KeyError('given type in config is wrong!') topics = config.resource checkInputData.list_data_valid(topics, num_entries=2) checkInputData.dict_data_valid(topics_published_from_nodes, check_entries=True, entry_type=list, allow_empty=False) checkInputData.list_data_valid(topics_published_from_nodes.keys(), check_entries=True) checkInputData.dict_data_valid(topics_subscribed_from_nodes, check_entries=True, entry_type=list, allow_empty=True) checkInputData.list_data_valid(topics_subscribed_from_nodes.keys(), check_entries=True, allow_empty=True) checkInputData.dict_data_valid(nodes_subscribe_topics, check_entries=True, entry_type=list, allow_empty=True) vars = {} rules = [] nodes = [] topic_pair = topics[:] checkInputData.list_data_valid(topic_pair, check_entries=True, allow_empty=False) topicA = topic_pair[0] topicB = topic_pair[1] if not set(topic_pair).issubset(topics_published_from_nodes.keys()): raise ValueError('topics are not not in topics published list!') nodes_list = [] nodes_a = topics_published_from_nodes.get(topicA, []) nodes_b = topics_published_from_nodes.get(topicB, []) checkInputData.list_data_valid(nodes_a, check_entries=True, allow_empty=False) checkInputData.list_data_valid(nodes_b, check_entries=True, allow_empty=False) topics_to_node_a = topics_subscribed_from_nodes.get(topicA, []) topics_to_node_b = topics_subscribed_from_nodes.get(topicB, []) checkInputData.list_data_valid(topics_to_node_a, check_entries=True, allow_empty=True) checkInputData.list_data_valid(topics_to_node_b, check_entries=True, allow_empty=True) for node in nodes_b: if node in topics_to_node_a: nodes_list += nodes_b break for node in nodes_a: if node in topics_to_node_b: nodes_list += nodes_a if not nodes_list: nodes_list = nodes_a + nodes_b for calleridA in nodes_a: for calleridB in nodes_b: observation = config_type + "_obs_" + topicA + "_" + calleridA + "_" + topicB + "_" + calleridB vars[observation] = Variable(observation, Variable.BOOLEAN, None) subscribed_topics = nodes_subscribe_topics.get(calleridB, []) checkInputData.list_data_valid(subscribed_topics, allow_empty=True) rules.append( TimingObserver(all_ab_pred(nodes_list), observation, all_ab_pred(subscribed_topics))) if not set(subscribed_topics).issubset( topics_published_from_nodes.keys()): raise ValueError( 'subscribed topics are not not in topics published list!' ) new_vars, new_rules, new_nodes = CalleridsObserver.generate_model_parameter_2( config_type, topicA, topics_published_from_nodes[topicA], topicB, topics_published_from_nodes[topicB]) vars.update(new_vars) rules += new_rules nodes += new_nodes return vars, rules, nodes, []