import proveit
theory = proveit.Theory() # the theorem's theory
from proveit import x, y, defaults
from proveit.logic import Not
from proveit.numbers import greater_eq
from proveit.numbers.ordering import (
less_eq_def, less_or_greater_eq, min_def_bin)
%proving min_bin_args_commute
defaults.assumptions = min_bin_args_commute.conditions
min_def_bin
min_x_y_def = min_def_bin.instantiate({x: x, y: y})
min_y_x_def = min_def_bin.instantiate({x: y, y: x})
less_or_greater_eq
relation_choices = less_or_greater_eq.instantiate({x: x, y: y})
case_1_assumptions = defaults.assumptions+(relation_choices.operands[0],)
min_x_y_def.inner_expr().rhs.simplify(assumptions=case_1_assumptions)
min_y_x_def.inner_expr().rhs.simplify(assumptions=case_1_assumptions)
case_2_assumptions = defaults.assumptions+(relation_choices.operands[1],)
For Case 2, we can quickly get the desired output for Min(y, x):
case_2_non_implication = min_y_x_def.inner_expr().rhs.simplify(assumptions=case_2_assumptions)
Then for later we seem to need this in implication form:
from proveit.logic import Implies
Implies(greater_eq(x, y), case_2_non_implication).prove()
For Min(x, y), Case 2 needs to be broken up into two pieces.
less_eq_def
y_le_x_as_disjunction = less_eq_def.instantiate({x: y, y: x})
y_le_x_as_disjunction.derive_right_via_equality(assumptions=case_2_assumptions)
case_2_a_assumptions = defaults.assumptions + (y_le_x_as_disjunction.rhs.operands[0],)
min_x_y_def.inner_expr().rhs.simplify(assumptions=case_2_a_assumptions)
case_2_b_assumptions = defaults.assumptions + (y_le_x_as_disjunction.rhs.operands[1],)
# Need this piece explicitly ---
# y >= x is not derived as an automatic side-effect from y = x
greater_eq(y, x).prove(assumptions=case_2_b_assumptions)
min_x_y_when_y_eq_x = min_x_y_def.inner_expr().rhs.simplify(assumptions=case_2_b_assumptions)
case_2_b_non_implication = min_x_y_when_y_eq_x.inner_expr().rhs.substitute(y,
assumptions=case_2_b_assumptions, auto_simplify=False)
Recall the full Case (2) conditions, and combine the two sub-cases of Case (2) into a single conclusion:
y_le_x_as_disjunction
y_le_x_as_disjunction.rhs.derive_via_singular_dilemma(
min_bin_args_commute.instance_expr,
assumptions=defaults.assumptions+(y_le_x_as_disjunction.lhs,))
Now we're ready for combining Cases (1) and (2) using derive_via_singular_dilemma() and the default assumptions:
relation_choices.expr.derive_via_singular_dilemma(
min_bin_args_commute.instance_expr)
%qed