import proveit
from proveit import P, Q, alpha
from proveit.core_expr_types import x_1_to_n, Q__x_1_to_n, P__x_1_to_n
from proveit.logic import Not, Equals, TRUE, NotEquals
from proveit.logic.booleans.quantification.existence import skolem_elim_lemma
from proveit import defaults
theory = proveit.Theory() # the theorem's theory
%proving skolem_elim
skolem_elim_lemma
skolem_elim_lemma_inst = skolem_elim_lemma.instantiate({alpha:Equals(alpha, TRUE), P:P, Q:Q},
assumptions=[skolem_elim.condition])
antecedent = skolem_elim.instance_expr.instance_expr.antecedent
defaults.assumptions = (skolem_elim_lemma.condition, antecedent)
P_impl_alpha = antecedent.derive_right().instantiate(assumptions=[Q__x_1_to_n])
P_impl_alpha.derive_consequent(assumptions=[P__x_1_to_n])
alpha_eq_true__under__assumptions = Equals(alpha, TRUE).prove(
assumptions=[*defaults.assumptions, Q__x_1_to_n, P__x_1_to_n])
P__impl__alpha_eq_T = alpha_eq_true__under__assumptions.as_implication(P__x_1_to_n)
P__impl__alpha_eq_T.generalize(x_1_to_n, conditions=[Q__x_1_to_n])
skolem_elim_lemma_inst.derive_consequent()
%qed