def negation_introduction( expr_set: Set[BooleanFunction]) -> InferenceRuleDict: implies_expr = list(filter(lambda x: x.func is Implies, expr_set)) new_facts = dict() for ex in implies_expr: lhs = ex.args[0] rhs = ex.args[1] not_rhs = convert_to_not(rhs) valid_implies_expr = list( filter(lambda x: x.args[0] == lhs and x.args[1] == not_rhs, implies_expr)) if valid_implies_expr.__len__() > 0: new_expr = convert_to_not(lhs) new_facts[new_expr] = [ex, valid_implies_expr[0]] return new_facts
def modus_tollens_rule( expr_set: Set[BooleanFunction]) -> InferenceRuleDict: implies_expr, non_implies_expr = sift(expr_set, lambda x: x.func is Implies, binary=True) non_implies_expr = set(non_implies_expr) new_facts = dict() for ex in implies_expr: rhs = ex.args[1] not_rhs = convert_to_not(rhs) if non_implies_expr.__contains__(not_rhs): lhs = ex.args[0] not_lhs = convert_to_not(lhs) new_facts[not_lhs] = [ex, not_rhs] return new_facts
def disjunctive_syllogism( expr_set: Set[BooleanFunction]) -> InferenceRuleDict: or_expr = set(filter(lambda x: x.func is Or, expr_set)) new_facts = dict() def check_expr(_expr: BooleanFunction, loop_expr: BooleanFunction, non_args: List[BooleanFunction]): nonlocal new_facts if expr_set.__contains__(_expr): _, new_args = sift(args, lambda x: non_args.__contains__(x), binary=True) if new_args.__len__() == 0: return elif new_args.__len__() == 1: new_expr = new_args[0] else: new_expr = Or(*new_args) new_facts[new_expr] = [loop_expr, _expr] for ex in or_expr: args = list(ex.args) for ag in args: not_ag = convert_to_not(ag) check_expr(not_ag, ex, [ag]) for l in range(2, args.__len__(), 1): combs = list(itertools.combinations(args, l)) for comb in combs: comb_list = list(comb) not_exprs = list( map(lambda x: convert_to_not(x), comb_list)) new_or_expr = Or(*not_exprs) check_expr(new_or_expr, ex, comb_list) return new_facts
def de_morgan_expand_law( expr_set: Set[BooleanFunction]) -> InferenceRuleDict: def valid_expr(_expr: BooleanFunction): return _expr.func is Not and (_expr.args[0].func is And or _expr.args[0].func is Or) new_facts = dict() expr_to_convert = filter(lambda x: valid_expr(x), expr_set) for ex in expr_to_convert: func = And if ex.args[0].func is Or else Or args = ex.args[0].args new_arg = list( map(lambda sub_arg: convert_to_not(sub_arg), list(args))) new_expr = func(*new_arg) new_facts[new_expr] = [ex] return new_facts
def absorption_and_distribution(_expr: BooleanFunction) -> list: """Luật phân phối và hấp thụ""" parent_expr = _expr.atoms(And, Or) results = list() for _ex in parent_expr: op_func = Or if _ex.func is And else And inner_ex, other_args = sift(_ex.args, lambda _x: _x.func is op_func, binary=True) if inner_ex.__len__() < 1: continue not_other_expr_set = set(map(lambda _x: convert_to_not(_x), other_args)) for in_ex in inner_ex: in_args = list(map(lambda _x: remove_double_not(_x), in_ex.args)) in_args_set = set(in_args) dup_not_args = in_args_set.intersection(not_other_expr_set) _, other_inner_expr = sift(inner_ex, lambda _x: _x == in_ex, binary=True) if dup_not_args.__len__() > 0: # p | (~p & q) _, new_inner_args = sift(in_args, lambda _x: _x in dup_not_args, binary=True) if new_inner_args.__len__() == 0: new_inner_expr = true if _ex.func is Or else false _, new_other_args = sift( other_args, lambda _x: convert_to_not(_x) in dup_not_args, binary=True) new_args = [ new_inner_expr, *new_other_args, *other_inner_expr ] new_ex = _ex.func(*new_args) results.append(("Luật về phần tử bù", _ex, new_ex)) continue new_inner_expr = op_func(*new_inner_args) new_args = [new_inner_expr, *other_args, *other_inner_expr] new_ex = _ex.func(*new_args) results.append(("Luật phân phối và hấp thụ", _ex, new_ex)) else: # ~(p & q) | (p & q & r) for not_expr in not_other_expr_set: if (not_expr.func is Not and not_expr.args[0].func is Symbol) or (not_expr.func is Symbol): continue not_expr_args = set(not_expr.args) dup_not_args = not_expr_args.intersection(in_args_set) if dup_not_args.__len__() == not_expr_args.__len__(): _, new_inner_args = sift(in_ex.args, lambda _x: _x in dup_not_args, binary=True) if new_inner_args.__len__() == 0: continue new_inner_expr = op_func(*new_inner_args) new_args = [ new_inner_expr, *other_args, *other_inner_expr ] new_ex = _ex.func(*new_args) results.append( ("Luật phân phối và hấp thụ", _ex, new_ex)) if inner_ex.__len__() > 1: for _ex1, _ex2 in itertools.combinations(inner_ex, 2): if _ex1.args.__len__() == _ex2.args.__len__(): continue if _ex1.args.__len__() > _ex2.args.__len__(): _ex1, _ex2 = _ex2, _ex1 ex1_not = convert_to_not(_ex1) if ex1_not in _ex2.args: new_inner_args = list(_ex2.args) new_inner_args.remove(ex1_not) if new_inner_args.__len__() == 0: continue new_inner_expr = op_func(*new_inner_args) _, other_inner = sift(inner_ex, lambda _x: _x == _ex1 or _x == _ex2, binary=True) new_args = [ new_inner_expr, _ex1, *other_args, *other_inner ] new_ex = _ex.func(*new_args) results.append(("Luật phân phối và hấp thụ", _ex, new_ex)) return results