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 1 -- What changes when an equation computes? (~25 minutes.) Run [python3 check.py] from this folder, then visit the L*.v files in order. README.md explains editor setup. All examples use Corelib. We start with ordinary addition, then declare a fresh symbol whose rules compute on either argument. Before each [Fail] or [Eval], predict what Rocq will do. No theorem about the whole rewrite system is being claimed by these individual examples.*)From Corelib Require Import Init.Nat.Set Guard Checking.SetUniverseChecking.
Guard Checking is on
UniverseCheckingis on
(** Ordinary addition inspects its FIRST argument. A variable blocks that match, even when the second argument is zero. *)
add =
fix add (n m : nat) {struct n} : nat :=
match n with
| 0 => m
| S p => S (add p m)
end
: nat -> nat -> nat
Arguments add (n m)%_nat_scope
= funn : nat => n
: nat -> nat
= funn : nat => n + 0
: nat -> nat
Definitionordinary_left_zero : foralln, 0 + n = n :=
funn => eq_refl.
The command has indeed failed with message:
In environment
n : nat
The term "eq_refl" has type "n + 0 = n + 0" while it is expected to have type
"n + 0 = n"
(cannot unify"n + 0"and"n").
(** The missing computational equation is still PROVABLE. Hide this proof and try it yourself: what is the induction hypothesis? *)
foralln : nat, n + 0 = n
foralln : nat, n + 0 = n
0 + 0 = 0
n: nat IH: n + 0 = n
S n + 0 = S n
0 + 0 = 0
reflexivity.
n: nat IH: n + 0 = n
S n + 0 = S n
n: nat IH: n + 0 = n
S (n + 0) = S n
n: nat IH: n + 0 = n
S n = S n
reflexivity.Qed.(** [rewrite] uses an equality proof to transform a goal. It does not install a native rule for [Nat.add]. *)
n: nat
S (n + 0) = S n
n: nat
S (n + 0) = S n
n: nat
S n = S n
reflexivity.Qed.
The command has indeed failed with message:
In environment
n : nat
The term "eq_refl" has type "n + 0 = n + 0" while it is expected to have type
"n + 0 = n"
(cannot unify"n + 0"and"n").
(** A Symbol has a declared type and no defining body. This declaration is an assumption about a new operation; it is not a Fixpoint. *)Symbol pplus : nat -> nat -> nat.
The command has indeed failed with message:
In environment
n : nat
The term "eq_refl" has type "pplus n 0 = pplus n 0"
while it is expected to have type "pplus n 0 = n" (cannot unify"pplus n 0"and"n").
(** Parallel addition, following the native rewrite-rule manual. [?n] binds a pattern variable. The same name on the right refers to the matched term. Rules here overlap: overlap is not itself failure of confluence. That distinction will matter in Lesson 5. *)Rewrite Rule pplus_rules :=
| pplus ?n0 => ?n
| pplus ?n (S ?m) => S (pplus ?n?m)
| pplus 0?n => ?n
| pplus (S ?n) ?m => S (pplus ?n?m).Definitionnative_right_zero : foralln, pplus n 0 = n :=
funn => eq_refl.Definitionnative_left_zero : foralln, pplus 0 n = n :=
funn => eq_refl.Definitionnative_successors :
forallnm, pplus (S n) (S m) = S (S (pplus n m)) :=
funnm => eq_refl.
= funn : nat => n
: nat -> nat
= funnm : nat => S (S (pplus n m))
: nat -> nat -> nat
pplus 510 = 15
pplus 510 = 15
reflexivity.Qed.(** Conversion also aligns TYPES. [P] is an arbitrary family indexed by natural numbers. Inspect the body: there is no equality transport in it. The expected and actual types become equal by computation. *)Definitionnative_reindex (P : nat -> Type) (n : nat)
(x : P (pplus n 0)) : P n := x.
The command has indeed failed with message:
In environment
P : nat -> Type
n : nat
x : P (n + 0)
The term "x" has type "P (n + 0)" while it is expected to have type "P n".
native_right_zero =
funn : nat => eq_refl
: foralln : nat, pplus n 0 = n
Arguments native_right_zero n%_nat_scope
native_reindex =
fun (P : nat -> Type) (n : nat) (x : P (pplus n 0)) => x
: forall (P : nat -> Type) (n : nat), P (pplus n 0) -> P n
Arguments native_reindex P%_function_scope n%_nat_scope x
Theory:
Rewrite rules are allowed (subject reduction might be broken)
Axioms:
pplus : nat -> nat -> nat
Theory:
Rewrite rules are allowed (subject reduction might be broken)
(** Checkpoint 1. Why can [eq_refl] prove [native_right_zero]? 2. Did proving [ordinary_right_zero] change computation of [Nat.add]? 3. Which assumption and theory flag appear for the native example? 4. Does one successful equality prove confluence or termination? Cues: conversion uses the registered rule; an equality theorem does not change native reduction; the symbol [pplus] and rewrite opt-in are reported; testing equalities establishes those examples only. Next: L02_Patterns.v -- which declarations are actually rejected?*)