Std.Proof.IntOrder
View source →Proof-carrying order on the inductive integers Int = FromNat(Nat) | NegativeSuccessor(Nat), via decidable-Boolean reflection.
Family shape — reflected form (chosen). The plan (Task 6 design note)
and spec §7 allow either a direct four-constructor inductive family or the
reflected form IsTrue(le_int(a, b)). We use the reflected form. The direct
family is currently not expressible: a constructor whose field lives in a
different inductive family (Nat-order evidence) combined with a
constructor-headed result index (FromNat(m)) trips a spurious
:index_mismatch in the elaborator's constructor-index-inversion path
(kernel.ex remap_index_error). The reflected form sidesteps that path:
indices stay plain variables and the sole constructor carries an IsTrue
witness of the total Boolean test. This mirrors Idris (So/Oh), Agda
(T), and Lean (Decidable).
Consequence for lemma shapes. Because the reflected proof carries no
structure of the compared integers (only that a Boolean test is True),
order lemmas that must inspect those integers take them as explicit
(relevant) parameters rather than the erased implicit {index} slots used
by the structural Nat-order family in Std.Proof.Math. The Boolean tests
le_int / lt_int are total functions routed through Nat, and each law
is discharged by an ordinary Boolean lemma plus case analysis.
── Public kit ─────────────────────────────────────────────────────────── The complete exported surface of this module, grouped by role. Boolean tests and arithmetic are total functions; the two families are the proof-carrying order relations; the rest are the lemmas over them.
Total Boolean tests & integer/nat arithmetic: le_nat(left: Nat, right: Nat) -> Bool lt_nat(left: Nat, right: Nat) -> Bool le_int(left: Int, right: Int) -> Bool lt_int(left: Int, right: Int) -> Bool succ_int(i: Int) -> Int pred_int(i: Int) -> Int add_nat_succ(count: Nat, x: Int) -> Int add_nat_pred(count: Nat, x: Int) -> Int add_int(addend: Int, x: Int) -> Int int_zero() -> Int int_one() -> Int int_negative_one() -> Int scale_nat_int(scalar: Nat, value: Int) -> Int multiply_int(coefficient: Int, value: Int) -> Int add_int_commutative(left: Int, right: Int) -> Equivalent(Int, left+right, right+left) add_int_associative(a: Int, b: Int, c: Int) -> Equivalent(Int, a+(b+c), (a+b)+c) scale_nat_int_distributes_over_add(scalar: Nat, left: Int, right: Int) -> Equivalent(...) multiply(left: Nat, right: Nat) -> Nat ## local Std.Proof.Math.multiply mirror
Proof-carrying order families (reflected form): type IsLessThanOrEqual indices (left: Int, right: Int) AtMost : IsTrue(le_int(left, right)) -> IsLessThanOrEqual(left, right) type IsLessThan indices (left: Int, right: Int) StrictlyBelow : IsTrue(lt_int(left, right)) -> IsLessThan(left, right)
Ex falso: absurd({a: Type}, void: Empty) -> a
Reflexivity: le_nat_is_reflexive(value: Nat) -> IsTrue(le_nat(value, value)) le_int_from_nat_is_reflexive(n: Nat) -> IsTrue(le_int(FromNat(n), FromNat(n))) le_int_neg_succ_is_reflexive(k: Nat) -> IsTrue(le_int(NegativeSuccessor(k), NegativeSuccessor(k))) is_less_than_or_equal_is_reflexive(value: Int) -> IsLessThanOrEqual(value, value)
Transitivity: le_nat_transitive(a: Nat, b: Nat, c: Nat, a_le_b, b_le_c) -> IsTrue(le_nat(a, c)) le_int_transitive(a: Int, b: Int, c: Int, a_le_b, b_le_c) -> IsTrue(le_int(a, c)) is_less_than_or_equal_is_transitive(left: Int, middle: Int, right: Int, left_to_middle, middle_to_right) -> IsLessThanOrEqual(left, right)
Integer monotonicity: succ_int_is_monotone(a: Int, b: Int, a_le_b) -> IsTrue(le_int(succ_int(a), succ_int(b))) pred_int_is_monotone(a: Int, b: Int, a_le_b) -> IsTrue(le_int(pred_int(a), pred_int(b))) add_nat_succ_is_monotone(count: Nat, a: Int, b: Int, a_le_b) -> IsTrue(le_int(add_nat_succ(count, a), add_nat_succ(count, b))) add_nat_pred_is_monotone(count: Nat, a: Int, b: Int, a_le_b) -> IsTrue(le_int(add_nat_pred(count, a), add_nat_pred(count, b))) add_int_is_monotone(addend: Int, a: Int, b: Int, a_le_b) -> IsTrue(le_int(add_int(addend, a), add_int(addend, b))) adding_the_same_number_preserves_less_than_or_equal(addend: Int, left: Int, right: Int, proof) -> IsLessThanOrEqual(add_int(addend, left), add_int(addend, right)) add_int_is_monotone_first(addend: Int, left: Int, right: Int, proof) -> IsTrue(...) add_int_is_monotone_both(a: Int, b: Int, c: Int, d: Int, ab, cd) -> IsTrue(...) adding_preserves_less_than_or_equal(a: Int, b: Int, c: Int, d: Int, ab, cd) -> IsLessThanOrEqual(add_int(a,c), add_int(b,d)) scale_nat_int_is_monotone(scalar: Nat, left: Int, right: Int, proof) -> IsLessThanOrEqual(scale_nat_int(scalar,left), scale_nat_int(scalar,right))
Refutation & decision: at_most_is_refuted_by_boolean_refuter({left}, {right}, refuter: (IsTrue(le_int(left, right))) -> Empty, proof) -> Empty strictly_below_is_refuted_by_boolean_refuter({left}, {right}, refuter: (IsTrue(lt_int(left, right))) -> Empty, proof) -> Empty decide_is_less_than_or_equal(left: Int, right: Int) -> Decision(IsLessThanOrEqual(left, right)) decide_is_less_than(left: Int, right: Int) -> Decision(IsLessThan(left, right))
Sign lemmas & nonnegative-scaling monotonicity: zero_le_int_from_nat_evidence(n: Nat) -> IsTrue(le_int(FromNat(Z()), FromNat(n))) nonneg_of_from_nat(n: Nat) -> IsLessThanOrEqual(FromNat(Z()), FromNat(n)) zero_is_not_at_most_negative_one(proof: IsLessThanOrEqual(FromNat(Z()), NegativeSuccessor(Z()))) -> Empty le_nat_weaken_right(smaller: Nat, larger: Nat, evidence) -> IsTrue(le_nat(smaller, S(larger))) le_nat_add_left_weakens(base: Nat, addend: Nat) -> IsTrue(le_nat(base, plus(addend, base))) le_nat_plus_is_monotone_left(a: Nat, b: Nat, y: Nat, ab) -> IsTrue(le_nat(plus(a, y), plus(b, y))) le_nat_plus_is_monotone_right(a: Nat, x: Nat, y: Nat, xy) -> IsTrue(le_nat(plus(a, x), plus(a, y))) le_nat_plus_is_monotone(a: Nat, b: Nat, x: Nat, y: Nat, ab, xy) -> IsTrue(le_nat(plus(a, x), plus(b, y))) le_nat_multiply_is_monotone(scalar: Nat, left: Nat, right: Nat, lr) -> IsTrue(le_nat(multiply(scalar, left), multiply(scalar, right))) from_nat_le_evidence(l: Nat, r: Nat, ev: IsTrue(le_nat(l, r))) -> IsTrue(le_int(FromNat(l), FromNat(r))) scaling_by_nonneg_preserves_less_than_or_equal(scalar: Nat, left: Nat, right: Nat, proof) -> IsLessThanOrEqual(FromNat(multiply(scalar, left)), FromNat(multiply(scalar, right)))
Functions
-
# fn absurd(a: Type, void: Empty) -> a
Ex falso: anything follows from a proof of the empty type.
-
# fn add_int(addend: Int, x: Int) -> Int
Total integer addition, defined by iterating the successor/predecessor on
xaccording to the sign and magnitude ofaddend.FromNat(m)steps upmtimes;NegativeSuccessor(k)steps downk + 1times. -
# fn add_int_associative(a: Int, b: Int, c: Int) -> Equivalent(Int, add_int(a, add_int(b, c)), add_int(add_int(a, b), c))
-
# fn add_int_commutative(left: Int, right: Int) -> Equivalent(Int, add_int(left, right), add_int(right, left))
-
# fn add_int_cong_left(a: Int, b: Int, c: Int, proof: Equivalent(Int, a, b)) -> Equivalent(Int, add_int(a, c), add_int(b, c))
-
# fn add_int_cong_right(a: Int, b: Int, c: Int, proof: Equivalent(Int, b, c)) -> Equivalent(Int, add_int(a, b), add_int(a, c))
-
# fn add_int_is_monotone(addend: Int, a: Int, b: Int, a_le_b: IsTrue(le_int(a, b))) -> IsTrue(le_int(add_int(addend, a), add_int(addend, b)))
Integer addition is monotone in its second argument (Boolean form):
a ≤ b → addend + a ≤ addend + b, by iterating succ/pred monotonicity. -
# fn add_int_is_monotone_both(a: Int, b: Int, c: Int, d: Int, ab: IsTrue(le_int(a, b)), cd: IsTrue(le_int(c, d))) -> IsTrue(le_int(add_int(a, c), add_int(b, d)))
-
# fn add_int_is_monotone_first(addend: Int, left: Int, right: Int, proof: IsTrue(le_int(left, right))) -> IsTrue(le_int(add_int(left, addend), add_int(right, addend)))
Addition is monotone in its first argument, derived from commutativity and the already-proved second-argument monotonicity.
-
# fn add_int_left_inverse(value: Int) -> Equivalent(Int, add_int(negate(value), value), int_zero())
-
# fn add_int_left_pred(left: Int, right: Int) -> Equivalent(Int, add_int(pred_int(left), right), pred_int(add_int(left, right)))
-
# fn add_int_left_succ(left: Int, right: Int) -> Equivalent(Int, add_int(succ_int(left), right), succ_int(add_int(left, right)))
-
# fn add_int_rearrange_four(a: Int, b: Int, c: Int, d: Int) -> Equivalent(Int, add_int(add_int(a, b), add_int(c, d)), add_int(add_int(a, c), add_int(b, d)))
Four-term interchange, derived solely from associativity and commutativity: (a+b)+(c+d) = (a+c)+(b+d).
-
# fn add_int_right_inverse(value: Int) -> Equivalent(Int, add_int(value, negate(value)), int_zero())
-
# fn add_int_right_inverse_is_unique(value: Int, candidate: Int, proof: Equivalent(Int, add_int(value, candidate), int_zero())) -> Equivalent(Int, candidate, negate(value))
-
# fn add_int_right_pred(addend: Int, value: Int) -> Equivalent(Int, add_int(addend, pred_int(value)), pred_int(add_int(addend, value)))
-
# fn add_int_right_succ(addend: Int, value: Int) -> Equivalent(Int, add_int(addend, succ_int(value)), succ_int(add_int(addend, value)))
-
# fn add_int_zero_left(value: Int) -> Equivalent(Int, add_int(int_zero(), value), value)
-
# fn add_int_zero_right(value: Int) -> Equivalent(Int, add_int(value, int_zero()), value)
-
# fn add_nat_pred(count: Nat, x: Int) -> Int
xretreatedcountinteger predecessors. -
# fn add_nat_pred_is_monotone(count: Nat, a: Int, b: Int, a_le_b: IsTrue(le_int(a, b))) -> IsTrue(le_int(add_nat_pred(count, a), add_nat_pred(count, b)))
Iterating a monotone integer predecessor preserves
≤. -
# fn add_nat_pred_right_pred(count: Nat, value: Int) -> Equivalent(Int, add_nat_pred(count, pred_int(value)), pred_int(add_nat_pred(count, value)))
-
# fn add_nat_pred_right_succ(count: Nat, value: Int) -> Equivalent(Int, add_nat_pred(count, succ_int(value)), succ_int(add_nat_pred(count, value)))
-
# fn add_nat_pred_zero_successor(count: Nat) -> Equivalent(Int, add_nat_pred(S(count), int_zero()), NegativeSuccessor(count))
-
# fn add_nat_succ(count: Nat, x: Int) -> Int
xadvancedcountinteger successors. -
# fn add_nat_succ_is_monotone(count: Nat, a: Int, b: Int, a_le_b: IsTrue(le_int(a, b))) -> IsTrue(le_int(add_nat_succ(count, a), add_nat_succ(count, b)))
Iterating a monotone integer successor preserves
≤. -
# fn add_nat_succ_right_pred(count: Nat, value: Int) -> Equivalent(Int, add_nat_succ(count, pred_int(value)), pred_int(add_nat_succ(count, value)))
-
# fn add_nat_succ_right_succ(count: Nat, value: Int) -> Equivalent(Int, add_nat_succ(count, succ_int(value)), succ_int(add_nat_succ(count, value)))
Iterated successor/predecessor commute with one step on their argument.
-
# fn add_nat_succ_zero(count: Nat) -> Equivalent(Int, add_nat_succ(count, int_zero()), FromNat(count))
-
# fn add_value_to_negated_successor_scale(count: Nat, value: Int) -> Equivalent(Int, add_int(value, negate(scale_nat_int(S(count), value))), negate(scale_nat_int(count, value)))
-
# fn adding_preserves_less_than_or_equal(a: Int, b: Int, c: Int, d: Int, ab: IsLessThanOrEqual(a, b), cd: IsLessThanOrEqual(c, d)) -> IsLessThanOrEqual(add_int(a, c), add_int(b, d))
-
# fn adding_the_same_number_preserves_less_than_or_equal(addend: Int, left: Int, right: Int, proof: IsLessThanOrEqual(left, right)) -> IsLessThanOrEqual(add_int(addend, left), add_int(addend, right))
Adding the same integer to both sides preserves less-than-or-equal. The sides are explicit (see the module header) since
add_int_is_monotoneinspects them. -
# fn at_most_is_refuted_by_boolean_refuter(left: Int, right: Int, refuter: Function(IsTrue(le_int(left, right)), Empty), proof: IsLessThanOrEqual(left, right)) -> Empty
Invert
AtMost: a refutation of the reflected Boolean evidence refutes the whole≤proof (its only constructor carries exactly that evidence). -
# fn decide_is_less_than(left: Int, right: Int) -> Decision(IsLessThan(left, right))
Decide strict
<on integers, carrying checked evidence either way. -
# fn decide_is_less_than_or_equal(left: Int, right: Int) -> Decision(IsLessThanOrEqual(left, right))
Decide
≤on integers, carrying checked evidence either way. Reuses the generic decidable-Boolean decision onle_int(left, right). -
# fn from_nat_le_evidence(l: Nat, r: Nat, ev: IsTrue(le_nat(l, r))) -> IsTrue(le_int(FromNat(l), FromNat(r)))
A nonnegative-into-Int order witness between
FromNatoperands is exactlyle_nat(return-type conversion reducesle_int(FromNat l, FromNat r)). -
# fn int_negative_one() -> Int
-
# fn int_one() -> Int
-
# fn int_zero() -> Int
Canonical integer constants used by the reflective LIA checker. Functions, rather than a second data representation, keep every caller on Std.Int.Int.
-
# fn is_less_than_or_equal_is_reflexive(value: Int) -> IsLessThanOrEqual(value, value)
Reflexivity: every integer is ≤ itself.
-
# fn is_less_than_or_equal_is_transitive(left: Int, middle: Int, right: Int, left_to_middle: IsLessThanOrEqual(left, middle), middle_to_right: IsLessThanOrEqual(middle, right)) -> IsLessThanOrEqual(left, right)
Less-than-or-equal evidence composes transitively. The compared integers are explicit (see the module header): the reflected proof does not carry them, and
le_int_transitivemust inspect them. -
# fn le_int(left: Int, right: Int) -> Bool
Boolean less-than-or-equal on the inductive integers. Nonneg/nonneg reduces to
le_nat; any negative is ≤ any nonneg; no nonneg is ≤ a negative; neg/neg reversesle_naton the successors, since -(k+1) ≤ -(j+1) ⇔ j ≤ k. -
# fn le_int_from_nat_is_reflexive(n: Nat) -> IsTrue(le_int(FromNat(n), FromNat(n)))
le_int(FromNat(n), FromNat(n))reduces tole_nat(n, n), which isTrue. Stated at the reduced result type so the conversion — not the constructor index path — performs thele_int→le_natreduction; the witness is then syntactically whatAtMostexpects on theFromNatreflexivity arm. -
# fn le_int_neg_succ_is_reflexive(k: Nat) -> IsTrue(le_int(NegativeSuccessor(k), NegativeSuccessor(k)))
Same, for
le_int(NegativeSuccessor(k), NegativeSuccessor(k))→le_nat(k, k). -
# fn le_int_transitive(a: Int, b: Int, c: Int, a_le_b: IsTrue(le_int(a, b)), b_le_c: IsTrue(le_int(b, c))) -> IsTrue(le_int(a, c))
le_intcomposes transitively (Boolean form). Case-splits on the outer integersa,c, then the middleb; real cases delegate tole_nat_transitive(the neg/neg case reversed), the rest are immediate or refuted from the evidence. -
# fn le_int_transport(left: Int, left2: Int, right: Int, right2: Int, left_equal: Equivalent(Int, left, left2), right_equal: Equivalent(Int, right, right2), proof: IsTrue(le_int(left, right))) -> IsTrue(le_int(left2, right2))
-
# fn le_nat(left: Nat, right: Nat) -> Bool
Boolean less-than-or-equal on naturals, structural on the left operand.
-
# fn le_nat_add_left_weakens(base: Nat, addend: Nat) -> IsTrue(le_nat(base, plus(addend, base)))
base ≤ addend + base: adding on the left only grows a natural number. -
# fn le_nat_is_reflexive(value: Nat) -> IsTrue(le_nat(value, value))
le_natis reflexive:le_nat(n, n)computes toTruefor everyn. -
# fn le_nat_multiply_is_monotone(scalar: Nat, left: Nat, right: Nat, lr: IsTrue(le_nat(left, right))) -> IsTrue(le_nat(multiply(scalar, left), multiply(scalar, right)))
left ≤ right ⇒ scalar·left ≤ scalar·righton the Boolean test. Induction on the scalar; the successor step ismultiply(S(sp), v) = plus(v, multiply(sp, v)), discharged by two-sided addition monotonicity. -
# fn le_nat_plus_is_monotone(a: Nat, b: Nat, x: Nat, y: Nat, ab: IsTrue(le_nat(a, b)), xy: IsTrue(le_nat(x, y))) -> IsTrue(le_nat(plus(a, x), plus(b, y)))
a ≤ bandx ≤ y ⇒ a + x ≤ b + y: two-sided addition monotonicity. -
# fn le_nat_plus_is_monotone_left(a: Nat, b: Nat, y: Nat, ab: IsTrue(le_nat(a, b))) -> IsTrue(le_nat(plus(a, y), plus(b, y)))
a ≤ b ⇒ a + y ≤ b + y: monotone in the left addend. -
# fn le_nat_plus_is_monotone_right(a: Nat, x: Nat, y: Nat, xy: IsTrue(le_nat(x, y))) -> IsTrue(le_nat(plus(a, x), plus(a, y)))
x ≤ y ⇒ a + x ≤ a + y: monotone in the right addend. -
# fn le_nat_transitive(a: Nat, b: Nat, c: Nat, a_le_b: IsTrue(le_nat(a, b)), b_le_c: IsTrue(le_nat(b, c))) -> IsTrue(le_nat(a, c))
le_natcomposes transitively (Boolean form). A zero left operand is immediate; the impossibleS(_) ≤ Zcases are refuted from the evidence. -
# fn le_nat_weaken_right(smaller: Nat, larger: Nat, evidence: IsTrue(le_nat(smaller, larger))) -> IsTrue(le_nat(smaller, S(larger)))
le_nat(smaller, larger) ⇒ le_nat(smaller, S(larger)): weaken the bound. -
# fn less_than_or_equal_transport(left: Int, left2: Int, right: Int, right2: Int, left_equal: Equivalent(Int, left, left2), right_equal: Equivalent(Int, right, right2), proof: IsLessThanOrEqual(left, right)) -> IsLessThanOrEqual(left2, right2)
-
# fn lt_int(left: Int, right: Int) -> Bool
Boolean strictly-less-than on the inductive integers. Nonneg/nonneg reduces to
lt_nat; any negative is < any nonneg; no nonneg is < a negative; neg/neg reverseslt_naton the successors, since -(k+1) < -(j+1) ⇔ j < k. -
# fn lt_nat(left: Nat, right: Nat) -> Bool
Boolean strictly-less-than on naturals, structural on the right operand.
-
# fn multiply(left: Nat, right: Nat) -> Nat
── Nonnegative-scaling monotonicity ─────────────────────────────────────
Scaling both sides of
b ≤ cby a nonnegative integer preserves the order. The reduction target is natural-number multiplication (Nat → Nat → Nat), so the scalar and the operands are the nonnegative cone:scalar : Natwitnesses0 ≤ FromNat(scalar), andleft/rightare theFromNatoperands. On that cone the Int order proof betweenFromNatvalues is exactly the Booleanle_nat, so the whole development stays in the Boolean test world — no equational transport.multiplybelow is a local mirror ofStd.Proof.Math.multiply(identical structural definition). We cannotuse Std.Proof.Math: it exports its ownIsLessThanOrEqual/IsLessThan/IsPositive, whose bare names collide with this module's integer order families and mis-resolve at codegen. Referencing it qualified is not an option either — a qualified cross-module reference still requires the module to be imported. The local mirror is the same total function; the lemma it proves is identical.Extending this to general integer operands would require first-argument monotonicity of the iterated integer
add_int, deferred as out of scope for the multiply-reduction specified here. Natural-number multiplication, structural on the left operand — a local mirror ofStd.Proof.Math.multiply(see the note above on why it is not imported). -
# fn multiply_int(coefficient: Int, value: Int) -> Int
Signed coefficient application for affine evaluation. A nonnegative coefficient delegates directly to natural scaling; -(n+1) negates the result of scaling by n+1. Both recursions are therefore over Nat.
-
# fn multiply_int_cong_coefficient(left: Int, right: Int, value: Int, proof: Equivalent(Int, left, right)) -> Equivalent(Int, multiply_int(left, value), multiply_int(right, value))
-
# fn multiply_int_distributes_over_coefficient_add(left: Int, right: Int, value: Int) -> Equivalent(Int, multiply_int(add_int(left, right), value), add_int(multiply_int(left, value), multiply_int(right, value)))
-
# fn multiply_int_distributes_over_from_nat_add(count: Nat, right: Int, value: Int) -> Equivalent(Int, multiply_int(add_int(FromNat(count), right), value), add_int(multiply_int(FromNat(count), value), multiply_int(right, value)))
-
# fn multiply_int_distributes_over_negative_add(count: Nat, right: Int, value: Int) -> Equivalent(Int, multiply_int(add_int(NegativeSuccessor(count), right), value), add_int(multiply_int(NegativeSuccessor(count), value), multiply_int(right, value)))
-
# fn multiply_int_from_nat(n: Nat, value: Int) -> Equivalent(Int, multiply_int(FromNat(n), value), scale_nat_int(n, value))
-
# fn multiply_int_negative_successor(n: Nat, value: Int) -> Equivalent(Int, multiply_int(NegativeSuccessor(n), value), negate(scale_nat_int(S(n), value)))
-
# fn multiply_int_predecessor_coefficient(coefficient: Int, value: Int) -> Equivalent(Int, multiply_int(pred_int(coefficient), value), add_int(negate(value), multiply_int(coefficient, value)))
-
# fn multiply_int_scale_nat_coefficient(scalar: Nat, coefficient: Int, value: Int) -> Equivalent(Int, multiply_int(scale_nat_int(scalar, coefficient), value), scale_nat_int(scalar, multiply_int(coefficient, value)))
-
# fn multiply_int_successor_coefficient(coefficient: Int, value: Int) -> Equivalent(Int, multiply_int(succ_int(coefficient), value), add_int(value, multiply_int(coefficient, value)))
-
# fn negate_distributes_over_add(left: Int, right: Int) -> Equivalent(Int, negate(add_int(left, right)), add_int(negate(left), negate(right)))
-
# fn nonneg_of_from_nat(n: Nat) -> IsLessThanOrEqual(FromNat(Z()), FromNat(n))
-
# fn pred_int(i: Int) -> Int
The integer predecessor
i - 1. Nonnegatives shrink (to -1 at zero) and negatives grow one more negative. -
# fn pred_int_is_monotone(a: Int, b: Int, a_le_b: IsTrue(le_int(a, b))) -> IsTrue(le_int(pred_int(a), pred_int(b)))
The integer predecessor is monotone (Boolean form):
a ≤ b → a-1 ≤ b-1. -
# fn pred_succ_int(value: Int) -> Equivalent(Int, pred_int(succ_int(value)), value)
-
# fn predecessors_cancel_matching_positive(count: Nat) -> Equivalent(Int, add_nat_pred(S(count), FromNat(S(count))), int_zero())
-
# fn scale_nat_int(scalar: Nat, value: Int) -> Int
Scale an arbitrary signed integer by a nonnegative natural. This is repeated proof-level integer addition, structural on the certificate coefficient. Task 2 proves its monotonicity and distributive laws from these equations.
-
# fn scale_nat_int_add_scalars(left: Nat, right: Nat, value: Int) -> Equivalent(Int, scale_nat_int(plus(left, right), value), add_int(scale_nat_int(left, value), scale_nat_int(right, value)))
Addition in the natural scalar (coefficient) is represented by Nat.plus.
-
# fn scale_nat_int_distributes_over_add(scalar: Nat, left: Int, right: Int) -> Equivalent(Int, scale_nat_int(scalar, add_int(left, right)), add_int(scale_nat_int(scalar, left), scale_nat_int(scalar, right)))
Scaling distributes over integer addition. This is the scalar algebra that later lifts pointwise to coefficient vectors and dot products.
-
# fn scale_nat_int_is_monotone(scalar: Nat, left: Int, right: Int, proof: IsLessThanOrEqual(left, right)) -> IsLessThanOrEqual(scale_nat_int(scalar, left), scale_nat_int(scalar, right))
Natural scaling preserves order for arbitrary signed operands. The successor case combines the original inequality with the induction result.
-
# fn scale_nat_int_successor(scalar: Nat, value: Int) -> Equivalent(Int, scale_nat_int(S(scalar), value), add_int(value, scale_nat_int(scalar, value)))
-
# fn scale_nat_int_value_zero(scalar: Nat) -> Equivalent(Int, scale_nat_int(scalar, int_zero()), int_zero())
-
# fn scale_nat_int_zero(value: Int) -> Equivalent(Int, scale_nat_int(Z(), value), int_zero())
-
# fn scaling_by_nonneg_preserves_less_than_or_equal(scalar: Nat, left: Nat, right: Nat, proof: IsLessThanOrEqual(FromNat(left), FromNat(right))) -> IsLessThanOrEqual(FromNat(multiply(scalar, left)), FromNat(multiply(scalar, right)))
Nonnegative scaling preserves
≤: givenleft ≤ right(asFromNatoperands) and anyscalar : Nat(i.e.0 ≤ FromNat(scalar)),scalar·left ≤ scalar·right. Reduces toStd.Proof.Math.multiplyvia the Boolean monotonicity above. -
# fn strictly_below_is_refuted_by_boolean_refuter(left: Int, right: Int, refuter: Function(IsTrue(lt_int(left, right)), Empty), proof: IsLessThan(left, right)) -> Empty
Invert
StrictlyBelowlikewise for strict<. -
# fn succ_int(i: Int) -> Int
The integer successor
i + 1. -(k+1)+1 folds the negative magnitude down (to zero when k = 0), and nonnegatives grow by one. -
# fn succ_int_is_monotone(a: Int, b: Int, a_le_b: IsTrue(le_int(a, b))) -> IsTrue(le_int(succ_int(a), succ_int(b)))
The integer successor is monotone (Boolean form):
a ≤ b → a+1 ≤ b+1. -
# fn succ_pred_int(value: Int) -> Equivalent(Int, succ_int(pred_int(value)), value)
Successor and predecessor are mutually inverse on canonical integers.
-
# fn successors_cancel_matching_negative(count: Nat) -> Equivalent(Int, add_nat_succ(count, NegativeSuccessor(count)), int_negative_one())
Canonical cancellation spines used to establish the additive inverse laws.
-
# fn zero_is_not_at_most_negative_one(proof: IsLessThanOrEqual(FromNat(Z()), NegativeSuccessor(Z()))) -> Empty
0 ≤ -1is impossible.le_int(FromNat(Z), NegativeSuccessor(Z))reduces toFalse, so the carried witness inhabitsIsTrue(False), refuted bytrue_is_not_false. (In the reflected form the refutation is not an empty match — every index pair is inhabited byAtMost— but destructuring the impossible evidence yieldsEmptyall the same. This is LIA's contradiction extractor.) -
# fn zero_le_int_from_nat_evidence(n: Nat) -> IsTrue(le_int(FromNat(Z()), FromNat(n)))
── Sign lemmas ──────────────────────────────────────────────────────────
0 ≤ nfor every naturaln:le_int(FromNat(Z), FromNat(n))reduces tole_nat(Z, n) = True, so the reflected witness isConfirmed(). Stated via a return-typed helper so the reduction lands in return-type conversion (the constructor-index path does not reducele_int— see the reflexivity helpers above).