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 4 -- What was actually installed? (About 20 minutes.) Read after L03_Accessibility.v. This closes the Phase 2 walkthrough. Source paths below are relative to the Rocq checkout; README.md has the source map with line references and the recorded commit.*)From Corelib Require Import Init.Nat Program.Wf.From TerminationStudy Require Import L02_Obligations L03_Accessibility.Set Guard Checking.SetUniverseChecking.(** The public wrapper only packs arguments for the generated function. This is a checked equality for arbitrary inputs, by conversion. *)
euclid_trace =
funab : nat => euclid_trace_func (existT (fun_ : nat => nat) a b)
: nat -> nat -> nat
Arguments euclid_trace (a b)%_nat_scope
a, b: nat
euclid_trace a b = euclid_trace_func (pack a b)
a, b: nat
euclid_trace a b = euclid_trace_func (pack a b)
reflexivity.Qed.(** Inspect the artifact and its evidence. In [euclid_trace_func], find the application of [Fix_sub], the reference to obligation 4, and the two calls carrying obligations 1 and 2. Obligation 3 belongs to the elaborated match. The full output stays in this lesson's log. *)
euclid_trace_func =
Fix_sub {_ : nat & nat}
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
L02_Obligations.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) =>
L02_Obligations.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) =>
L02_Obligations.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) =>
L02_Obligations.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
(* Generated obligations require qualification after importing a module. *)
L02_Obligations.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
L02_Obligations.euclid_trace_func_obligation_2
: 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
L02_Obligations.euclid_trace_func_obligation_3
: foralln : nat,
letwildcard' := S n inforallwildcard'0 : nat, ~ (0 = wildcard' /\ wildcard'0 = 0)
L02_Obligations.euclid_trace_func_obligation_4
: well_founded
(MR lt
(funrecarg : {_ : nat & nat} =>
leta := projT1 recarg inletb := projT2 recarg in a + b))
Fetching opaque proofs from disk for Corelib.Init.Peano
Closed under the globalcontext
Closed under the globalcontext
Closed under the globalcontext
Closed under the globalcontext
Closed under the globalcontext
Closed under the globalcontext
(** Follow one call, end to end: source: euclid_trace (S a') (S b' - S a') -> a recursive-function argument with an extra decrease proof -> [exist] carrying [existT ...] and obligation 1's proof -> [Fix_sub] invokes [Fix_F_sub] with obligation 4's [Acc] proof -> [Acc_inv] uses that call's proof to select a child [Acc] proof -> [Fix_F_sub] recurses structurally on this child proof. The generated Euclid body is an ordinary term applying an existing recursor. [Fix_F_sub]'s recursive body was checked when Corelib was built; declaring Euclid does not reinstall that library definition. Implementation trail at commit 67ab16a375d31812dc1dd788f92d446d7d6dcd45: - vernac/comFixpoint.ml: [encapsulate_Fix_sub], [build_wellfounded] build the relation, proof holes, recursor application, and wrapper. - vernac/declare.ml: [prepare_obligations], [declare_obligation], [obligation_substitution], [update_obls], [declare_definition] connect solved evidence to the proposed term and complete it. - vernac/declare.ml: [declare_constant] calls [Global.add_constant]. - kernel/safe_typing.ml: [add_constant] checks a definition before adding its constant body to the environment. - kernel/typeops.ml: the [Fix] case calls [Inductive.check_fix]; kernel/inductive.ml implements the guard check. Thus the proof-producing elaborator and tactics may change while their output remains subject to the existing kernel's checks. This observation does not justify changing the kernel or its rules. In the study's vocabulary: substrate = the existing core theory and environment; proposer = source author plus elaboration/proof-producing tools; evidence = the typed decrease and well-foundedness proof terms; gate = kernel checking of the resulting declarations, with guards and universe checking enabled; admission policy = add definitions accepted under those core rules; reflective depth = construct terms in the existing theory. We have not added native reduction rules. We have not proved a general guarantee about all future admission histories. Changing conversion or the gate itself requires a different argument.*)(** Stop for discussion here, as requested in study_plan.md. Explain the trace using [right_call] and [Fix_F_sub], then ask: what evidence must remain transparent for this function to compute? That is an open experimental question for Phase 3. Later checkpoints are planned in README.md: controlled changes, the scope of the admission discipline, then native rewrite rules. This import shows how we use the saved lesson; it is not a claim that normal [Require Import] independently rechecks every proof.*)