def apply(self, axiom, *args, split=True, **kwargs): if self.is_And: if axiom.__name__.split(sep='.', maxsplit=3)[2] == 'et': split = False if split: _args = [] funcs = [] depth = kwargs.pop('depth', None) if not depth: _args = [*self.args] else: def instantiate(eq): function = eq for _ in range(depth): function = function.function return function for eq in self.args: if eq.is_ConditionalBoolean: _funcs, function = eq.funcs() _funcs = _funcs[-depth:] if funcs: assert _funcs == funcs else: funcs = _funcs function = instantiate(eq) _args.append(function) else: _args.append(eq) function = axiom.apply(*_args, *args, **kwargs) if isinstance(function, tuple): for f in function: clue = f.clue break function = And(*function, **{clue: self}) else: clue = function.clue for func, limits in funcs: function = func(function, *limits) if function.is_BooleanAtom: return function.copy(**{clue: self}) function.set_clause(clue, self, force=True) if kwargs.get('simplify', True): function = function.simplify() return function eqs = axiom.apply(self, *args, **kwargs) if isinstance(eqs, (list, tuple)): eqs = And(*eqs, equivalent=eqs) elif eqs.is_Equivalent: if eqs.clue is None: if self.cond is eqs.lhs: return eqs.rhs return eqs