Built with Alectryon, running vsrocq-language-server v9.4+alpha 5.4.1 / 2.5.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(** Lesson 2 -- Watch a definition become available. (About 30 minutes.) Read after L01_Baseline.v. This is the same Euclid algorithm and measure, with a fresh name and inspection commands inserted. Arithmetic evidence is defined in Euclid.v. This begins Phase 2.*)From Corelib Require Import Init.Nat Program.Wf.From TerminationStudy Require Import Euclid.Set Guard Checking.SetUniverseChecking.(** Pause automatic proof search so every obligation stays visible. *)#[local] Obligation Tactic := idtac.
euclid_trace_func has type-checked, generating 4 obligations
Solving obligations automatically...
4 obligations remaining
Obligation 1 of euclid_trace_func:
(forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' + (S b' - S a') < a + b).
Obligation 2 of euclid_trace_func:
(forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' - S b' + S b' < a + b).
Obligation 3 of euclid_trace_func:
(forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
(euclid_trace_func_obligation_1 a b euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
(euclid_trace_func_obligation_2 a b euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)).
Obligation 4 of euclid_trace_func:
(well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))).
(** Before solving anything, inspect the four pending propositions and the proposed term. The name with [_func] is Program's internal function on a packed pair of arguments. Search the Preterm output for [Fix_sub], [existT], [exist], and [_obligation_1]. These commands inspect Program's pending state; they do not install an incomplete function in the global environment. *)
4 obligation(s) remaining:
Obligation 1 of euclid_trace_func:
(forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' + (S b' - S a') < a + b).
Obligation 2 of euclid_trace_func:
(forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' - S b' + S b' < a + b).
Obligation 3 of euclid_trace_func:
(forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
(euclid_trace_func_obligation_1 a b euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
(euclid_trace_func_obligation_2 a b euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)).
Obligation 4 of euclid_trace_func:
(well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))).
euclid_trace_func :
(forallrecarg : {_ : nat & nat},
leta := projT1 recarg inletb := projT2 recarg in nat)
:=
(Fix_sub {_ : nat & nat}
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
euclid_trace_func_obligation_4
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in nat)
(fun (recarg : {_ : nat & nat})
(euclid_trace' : forallrecarg' : {recarg' : {_ : nat & nat}
| (leta := projT1 recarg' inletb := projT2 recarg' in a + b) <
(leta := projT1 recarg inletb := projT2 recarg in a + b)},
leta := projT1 (proj1_sig recarg') inletb := projT2 (proj1_sig recarg') in nat) =>
leta := projT1 recarg inletb := projT2 recarg inleteuclid_trace :=
fun (a0b0 : nat) (recproof : a0 + b0 < a + b) =>
euclid_trace'
(exist
(funrecarg' : {_ : nat & nat} =>
(leta1 := projT1 recarg' inletb1 := projT2 recarg' in a1 + b1) <
(leta1 := projT1 recarg inletb1 := projT2 recarg in a1 + b1))
(existT (fun_ : nat => nat) a0 b0) recproof)
inletprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
(euclid_trace_func_obligation_1 a b euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
(euclid_trace_func_obligation_2 a b euclid_trace a' b' Heq_a Heq_b)
inmatch a as a' return a' = a -> b = b -> nat with
| 0 => program_branch_0 b
| S a' =>
match b as b' return S a' = a -> b' = b -> nat with
| 0 =>
program_branch_1 (S a')
(euclid_trace_func_obligation_3 a b euclid_trace a')
| S b' => program_branch_2 a' b'
endend eq_refl eq_refl))
The command has indeed failed with message:
The reference euclid_trace was not found in the current environment.
The command has indeed failed with message:
The reference euclid_trace_func was not found in the current environment.
Did you mean euclid_sub_func?
(** Follow the [then] call. Its local recursive function now takes an extra proof that the new sum is smaller than the CURRENT sum. Match equalities identify the current [a,b] with [S a',S b']. Execute [Show] before and after [subst] and read the change. *)
forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' + (S b' - S a') < a + b
a, b: nat recurse: foralla0b0 : nat, a0 + b0 < a + b -> nat a', b': nat Ha: S a' = a Hb: S b' = b
S a' + (S b' - S a') < a + b
1 goal
a, b : nat
recurse : foralla0b0 : nat, a0 + b0 < a + b -> nat
a', b' : nat
Ha : S a' = a
Hb : S b' = b
============================
S a' + (S b' - S a') < a + b
a, b: nat recurse: foralla0b0 : nat, a0 + b0 < a + b -> nat a', b': nat Ha: S a' = a Hb: S b' = b
S a' + (S b' - S a') < a + b
a', b': nat recurse: forallab : nat, a + b < S a' + S b' -> nat
S a' + (S b' - S a') < S a' + S b'
1 goal
a', b' : nat
recurse : forallab : nat, a + b < S a' + S b' -> nat
============================
S a' + (S b' - S a') < S a' + S b'
a', b': nat recurse: forallab : nat, a + b < S a' + S b' -> nat
S a' + (S b' - S a') < S a' + S b'
apply TerminationFacts.subtract_right_decreases.
3 obligations remaining
Solving obligations automatically...
3 obligations remaining
(** One evidence constant is now installed, but the function is not. *)
euclid_trace_func_obligation_1
: forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat,
S a' = a -> S b' = b -> S a' + (S b' - S a') < a + b
euclid_trace_func_obligation_1 =
fun (ab : nat) (recurse : foralla0b0 : nat, a0 + b0 < a + b -> nat)
(a'b' : nat) (Ha : S a' = a) (Hb : S b' = b) =>
eq_ind (S a')
(funa0 : nat =>
(foralla1b0 : nat, a1 + b0 < a0 + b -> nat) ->
S a' + (S b' - S a') < a0 + b)
(funrecurse0 : foralla0b0 : nat, a0 + b0 < S a' + b -> nat =>
eq_ind (S b')
(funb0 : nat =>
(foralla0b1 : nat, a0 + b1 < S a' + b0 -> nat) ->
S a' + (S b' - S a') < S a' + b0)
(fun_ : foralla0b0 : nat, a0 + b0 < S a' + S b' -> nat =>
TerminationFacts.subtract_right_decreases a' b')
b Hb recurse0)
a Ha recurse
: forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat,
S a' = a -> S b' = b -> S a' + (S b' - S a') < a + b
Arguments euclid_trace_func_obligation_1 (a b)%_nat_scope
recurse%_function_scope (a' b')%_nat_scope Ha Hb
The command has indeed failed with message:
The reference euclid_trace was not found in the current environment.
3 obligation(s) remaining:
Obligation 2 of euclid_trace_func:
(forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' - S b' + S b' < a + b).
Obligation 3 of euclid_trace_func:
(forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_1 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
(euclid_trace_func_obligation_2 a b euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)).
Obligation 4 of euclid_trace_func:
(well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))).
forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' - S b' + S b' < a + b
a, b: nat recurse: foralla0b0 : nat, a0 + b0 < a + b -> nat a', b': nat Ha: S a' = a Hb: S b' = b
S a' - S b' + S b' < a + b
a', b': nat recurse: forallab : nat, a + b < S a' + S b' -> nat
S a' - S b' + S b' < S a' + S b'
apply TerminationFacts.subtract_left_decreases.
2 obligations remaining
Solving obligations automatically...
2 obligations remaining
(** This third goal is match bookkeeping, not another recursive call. *)
forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_1 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_2 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)
1 goal
============================
forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_1 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_2 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)
forall (ab : nat)
(euclid_trace : foralla0b0 : nat, a0 + b0 < a + b -> nat),
letprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_1 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_2 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
inforalln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)
intros; intuitiondiscriminate.
1 obligation remaining
(** Both decreases are proved, but the relation still needs a proof of well-foundedness. The public function remains unavailable. *)
The command has indeed failed with message:
The reference euclid_trace was not found in the current environment.
The command has indeed failed with message:
The reference euclid_trace_func was not found in the current environment.
Did you mean euclid_sub_func?
1 obligation(s) remaining:
Obligation 4 of euclid_trace_func:
(well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))).
euclid_trace_func :
(forallrecarg : {_ : nat & nat},
leta := projT1 recarg inletb := projT2 recarg in nat)
:=
(Fix_sub {_ : nat & nat}
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
euclid_trace_func_obligation_4
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in nat)
(fun (recarg : {_ : nat & nat})
(euclid_trace' : forallrecarg' : {recarg' : {_ : nat & nat}
| (leta := projT1 recarg' inletb := projT2 recarg' in a + b) <
(leta := projT1 recarg inletb := projT2 recarg in a + b)},
leta := projT1 (proj1_sig recarg') inletb := projT2 (proj1_sig recarg') in nat) =>
leta := projT1 recarg inletb := projT2 recarg inleteuclid_trace :=
fun (a0b0 : nat) (recproof : a0 + b0 < a + b) =>
euclid_trace'
(exist
(funrecarg' : {_ : nat & nat} =>
(leta1 := projT1 recarg' inletb1 := projT2 recarg' in a1 + b1) <
(leta1 := projT1 recarg inletb1 := projT2 recarg in a1 + b1))
(existT (fun_ : nat => nat) a0 b0) recproof)
inletprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
(euclid_trace_func_obligation_1 a b euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
(euclid_trace_func_obligation_2 a b euclid_trace a' b' Heq_a Heq_b)
inmatch a as a' return a' = a -> b = b -> nat with
| 0 => program_branch_0 b
| S a' =>
match b as b' return S a' = a -> b' = b -> nat with
| 0 =>
program_branch_1 (S a')
(euclid_trace_func_obligation_3 a b euclid_trace a')
| S b' => program_branch_2 a' b'
endend eq_refl eq_refl))
well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
1 goal
============================
well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
well_founded lt
exact TerminationFacts.nat_lt_wf.
No more obligations remaining
(** Crossing this last [Defined] completes the definition and its two-argument wrapper. No extra admission command is needed. *)
euclid_trace_func
: forallrecarg : {_ : nat & nat},
leta := projT1 recarg inletb := projT2 recarg in nat
euclid_trace
: nat -> nat -> nat
euclid_trace =
funab : nat => euclid_trace_func (existT (fun_ : nat => nat) a b)
: nat -> nat -> nat
Arguments euclid_trace (a b)%_nat_scope
euclid_trace_func =
Fix_sub {_ : nat & nat}
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
euclid_trace_func_obligation_4
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in nat)
(fun (recarg : {_ : nat & nat})
(euclid_trace' : forallrecarg' : {recarg' : {_ : nat & nat}
| (leta := projT1 recarg' inletb := projT2 recarg' in a + b) <
(leta := projT1 recarg inletb := projT2 recarg in a + b)},
leta := projT1 (proj1_sig recarg') inletb := projT2 (proj1_sig recarg') in nat) =>
leta := projT1 recarg inletb := projT2 recarg inleteuclid_trace :=
fun (a0b0 : nat) (recproof : a0 + b0 < a + b) =>
euclid_trace'
(exist
(funrecarg' : {_ : nat & nat} =>
(leta1 := projT1 recarg' inletb1 := projT2 recarg' in a1 + b1) <
(leta1 := projT1 recarg inletb1 := projT2 recarg in a1 + b1))
(existT (fun_ : nat => nat) a0 b0) recproof)
inletprogram_branch_0 :=
fun (wildcard' : nat) (_ : 0 = a) (_ : wildcard' = b) => b inletprogram_branch_1 :=
fun (wildcard' : nat)
(_ : forallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0))
(_ : wildcard' = a) (_ : 0 = b) =>
a inletprogram_branch_2 :=
fun (a'b' : nat) (Heq_a : S a' = a) (Heq_b : S b' = b) =>
if S a' <=? S b'
then
euclid_trace (S a') (S b' - S a')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_1 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
else
euclid_trace (S a' - S b') (S b')
((fun (a0b0 : nat)
(recurse : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(a'0b'0 : nat) (Ha : S a'0 = a0) (Hb : S b'0 = b0) =>
euclid_trace_func_obligation_2 a0 b0 recurse a'0 b'0 Ha Hb) a b
euclid_trace a' b' Heq_a Heq_b)
inmatch a as a' return a' = a -> b = b -> nat with
| 0 => program_branch_0 b
| S a' =>
match b as b' return S a' = a -> b' = b -> nat with
| 0 =>
program_branch_1 (S a')
((fun (a0b0 : nat)
(_ : foralla1b1 : nat, a1 + b1 < a0 + b0 -> nat)
(nwildcard' : nat) =>
euclid_trace_func_obligation_3 n wildcard') a b euclid_trace
a')
| S b' => program_branch_2 a' b'
endend eq_refl eq_refl)
: forallrecarg : {_ : nat & nat},
leta := projT1 recarg inletb := projT2 recarg in nat
Arguments euclid_trace_func recarg
euclid_trace_func_obligation_2 =
fun (ab : nat) (recurse : foralla0b0 : nat, a0 + b0 < a + b -> nat)
(a'b' : nat) (Ha : S a' = a) (Hb : S b' = b) =>
eq_ind (S a')
(funa0 : nat =>
(foralla1b0 : nat, a1 + b0 < a0 + b -> nat) ->
S a' - S b' + S b' < a0 + b)
(funrecurse0 : foralla0b0 : nat, a0 + b0 < S a' + b -> nat =>
eq_ind (S b')
(funb0 : nat =>
(foralla0b1 : nat, a0 + b1 < S a' + b0 -> nat) ->
S a' - S b' + S b' < S a' + b0)
(fun_ : foralla0b0 : nat, a0 + b0 < S a' + S b' -> nat =>
TerminationFacts.subtract_left_decreases a' b')
b Hb recurse0)
a Ha recurse
: forallab : nat,
(foralla0b0 : nat, a0 + b0 < a + b -> nat) ->
foralla'b' : nat, S a' = a -> S b' = b -> S a' - S b' + S b' < a + b
Arguments euclid_trace_func_obligation_2 (a b)%_nat_scope
recurse%_function_scope (a' b')%_nat_scope Ha Hb
euclid_trace_func_obligation_3 =
funn : nat =>
letwildcard' := S n infun (wildcard'0 : nat) (H : 0 = wildcard' /\ wildcard'0 = 0) =>
and_ind
(fun (H0 : 0 = wildcard') (_ : wildcard'0 = 0) =>
letH1 : False :=
eq_ind 0 (fune : nat => match e with
| 0 => True
| S _ => Falseend)
I wildcard' H0
in
False_ind False H1)
H
: foralln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)
Arguments euclid_trace_func_obligation_3 (n wildcard')%_nat_scope _
euclid_trace_func_obligation_4 =
measure_wf TerminationFacts.nat_lt_wf
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b)
: well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
Arguments euclid_trace_func_obligation_4 a
= 6
: nat
euclid_trace 1848 = 6
euclid_trace 1848 = 6
reflexivity.Qed.
Fetching opaque proofs from disk for Corelib.Init.Peano
Closed under the globalcontext
(** Checkpoint: - Point to the proof argument attached to the [then] call in Preterm. - Classify the four obligations: two decreases, one match condition, one well-foundedness proof. - At which command does [Check euclid_trace] first succeed? The four propositions constrain THIS proposed term. The proofs are referenced or substituted into its holes, not filed beside unrelated source text. We inspect the final connection again in Lesson 4. Next: L03_Accessibility.v -- what core recursion does Fix_sub use?*)