def create_negative_model(self, rule, red_cm, blue_cm, args, time): o1, o2 = args[:2] model = self.add_new_model() red_o1 = self.add_cm(red_cm, o1, model) blue_o2 = self.add_cm(blue_cm, o2, model) self.add_prior(rule, model) self.known_rules.add(rule) rule_violation_CPD = rule.generate_CPD() correction_table = variable_or_CPD(1) Vrule = f'V_{time}({rule})' corr = f'corr_{time}' rule_violated = TabularCPD(Vrule, 2, rule_violation_CPD, evidence=[red_o1, blue_o2, rule], evidence_card=[2, 2, 2]) rule_violated_factor = rule_violated.to_factor() self.add_factor([Vrule, rule, rule_violated_factor], rule_violated_factor, model) correction = TabularCPD(corr, 2, correction_table, evidence=[Vrule], evidence_card=[2]) correction_factor = correction.to_factor() self.add_factor([corr, correction_factor], correction_factor, model) return [Vrule]
def create_table_neg_model(self, rule, red_cm, blue_cm, args, time): model = self.add_new_model() o1, o2, o3 = args[:3] blue_o1 = self.add_cm(blue_cm, o1, model) red_o3 = self.add_cm(red_cm, o3, model) self.add_prior(rule, model) self.known_rules.add(rule) rule_cpd = generate_neg_table_cpd() correction_table = variable_or_CPD(1) Vrule = f'V_{time}({rule})' corr = f'corr_{time}' rule_evidence = [rule, blue_o1, red_o3] rule_violated = TabularCPD(Vrule, 2, rule_cpd, evidence=rule_evidence, evidence_card=[2, 2, 2, 2, 2]) self.add_factor(rule_evidence + [Vrule], rule_violated.to_factor(), model) correction = TabularCPD(corr, 2, correction_table, evidence=[Vrule], evidence_card=[2]) self.add_factor([Vrule, corr], correction.to_factor(), model) return [Vrule]
def add_joint_violations(self, colour_count: ColourCountRule, red_on_blue_options: list, time: int, colours_in_tower: list, model: FactorGraph): p = self.get_p(CorrectionType.TABLE) cpds = [ colour_count.generateCPD(num_blocks_in_tower=len(colours_in_tower), correction_type=CorrectionType.TABLE, p=p) for rule in red_on_blue_options ] violated_rule_factor_name1 = f"V_{time}({colour_count} && {red_on_blue_options[0]})" violated_rule_factor_name2 = f"V_{time}({colour_count} && {red_on_blue_options[1]})" evidence1 = colours_in_tower + [red_on_blue_options[0], colour_count] evidence2 = colours_in_tower + [red_on_blue_options[1], colour_count] cpd1, cpd2 = cpds rule_violated_factor1 = TabularCPD(violated_rule_factor_name1, 2, cpd1, evidence=evidence1, evidence_card=[2] * len(evidence1)) rule_violated_factor1 = rule_violated_factor1.to_factor() rule_violated_factor2 = TabularCPD(violated_rule_factor_name2, 2, cpd1, evidence=evidence2, evidence_card=[2] * len(evidence2)) rule_violated_factor2 = rule_violated_factor2.to_factor() self.add_factor([ violated_rule_factor_name1, rule_violated_factor1, red_on_blue_options[0], colour_count ], rule_violated_factor1, model) self.add_factor([ violated_rule_factor_name2, rule_violated_factor2, red_on_blue_options[1], colour_count ], rule_violated_factor2, model) return [violated_rule_factor_name1, violated_rule_factor_name2]
def add_violation_factor(self, rule, time, colours, correction_type=CorrectionType.TABLE, table_empty=False, model=None): """ Adds a factor representing when the rule is violated :param colours: :param correction_type: :param table_empty: :param rule: Rule object representing the rule being violated :param time: the time step at which the violation happened :param red_o1: factor name of form colour(o1) as returned by add_cm() :param blue_o2: factor name of form colour(o2) as returned by add_cm() :return: the factor name in the form V_time(rule) """ violated_rule_factor_name = f"V_{time}({rule})" evidence = colours + [str(rule)] p = 1.0 # self.get_p(correction_type) violated_rule_cpd = rule.generateCPD(correction_type=correction_type, len_evidence=len(evidence), table_empty=table_empty, p=p) try: rule_violated_factor = TabularCPD(violated_rule_factor_name, 2, violated_rule_cpd, evidence=evidence, evidence_card=[2] * len(evidence)) except ValueError as e: print("rule", rule) print("time", time) print("correction_type", correction_type) print("table empty", table_empty) print("evidence", evidence) print("len evidence", str(len(evidence))) print("cpd_shape", np.array(violated_rule_cpd).shape) raise e rule_violated_factor = rule_violated_factor.to_factor() self.add_factor( [violated_rule_factor_name, rule, rule_violated_factor] + evidence, rule_violated_factor, model=model) return violated_rule_factor_name
def add_correction_factor(self, violations, time, model=None, p=1.0): """ :param p: :param model: :param violations: :param time: :return: """ corr = f'corr_{time}' correction_table = variable_or_CPD(len(violations), p) correction = TabularCPD(corr, 2, correction_table, evidence=violations, evidence_card=[2] * len(violations)) correction_factor = correction.to_factor() self.add_factor([corr, correction_factor] + violations, correction_factor, model=model) return corr