def rename_and_pull(f, quant, old_var1, old_var2, arg1, arg2): """ Helper function that renames given variable in a formula. """ # when both variables are to be renamed, re-use the variable name # eg. (forall x: P(x) & forall y: Q(y)) <-> (forall x: P(x) & Q(x)) new_var = None if old_var1: # rename left? new_var = variant(old_var1, fvars(f)) a1 = subst({old_var1: new_var}, arg1) else: a1 = arg1 if old_var2: # rename right? if not new_var: new_var = variant(old_var2, fvars(f)) a2 = subst({old_var2: new_var}, arg2) else: a2 = arg2 return Quantifier(quant, new_var, pullquants(Expr(f.op, a1 , a2)))
def helper(f, used, substs): if is_variable(f): if f in substs: return substs[f] else: return f if is_quantified(f): # does this quantifier use a variable that is already used? clashing = (used & set(f.vars)) # set intersection if len(clashing) > 0: for var in clashing: existing = used.union(*list(map(vars, substs.values()))) # rename any clashing variable var2 = variant(var, existing) substs[var] = var2 used.update(f.vars) arg = helper(f.args[0], used, substs) return Quantifier(f.op, [subst(substs, x) for x in f.vars], *[subst(substs, x) for x in f.args]) else: used.update(f.vars) arg = helper(f.args[0], used, substs) return Quantifier(f.op, f.vars, arg) else: return Expr(f.op, *[helper(x, used, substs) for x in f.args])