named Statements are automatically added to inventory

pull/68/head
Jon Eugster 2 years ago
parent 26239d6687
commit 0560c0100b

@ -230,7 +230,7 @@ elab "Statement" statementName:ident ? descr:str ? sig:declSig val:declVal : com
-- Check that the statement name is a lemma in the doc
match statementName with
| some name => checkInventoryDoc .Lemma name.getId
| none => pure Unit.unit
| none => pure ()
let lvlIdx ← getCurLevelIdx
let defaultDeclName : Name := (← getCurGame).name ++ (← getCurWorld).name ++
@ -283,6 +283,9 @@ elab "Statement" statementName:ident ? descr:str ? sig:declSig val:declVal : com
descrText := match descr with
| none => ""
| some s => s.getString
statementName := match statementName with
| none => default
| some name => name.getId
descrFormat := match statementName with
| none => "example " ++ (toString <| reprint sig.raw) ++ " := by"
| some name => (Format.join ["lemma ", reprint name.raw, " ", reprint sig.raw, " := by"]).pretty 10 -- "lemma " ++ (toString <| reprint name.raw) ++ " " ++ (Format.pretty (reprint sig.raw) 40) ++ " := by"
@ -404,14 +407,42 @@ elab "MakeGame" : command => do
throwError "World graph must not contain loops! Check your `Path` declarations."
-- Compute which inventory items are available in which level:
for inventoryType in open InventoryType in #[Tactic, Definition, Lemma] do
for inventoryType in #[.Tactic, .Definition, .Lemma] do
let mut newItemsInWorld : HashMap Name (HashSet Name) := {}
let mut lemmaStatements : HashMap (Name × Nat) Name := {}
let mut allItems : HashSet Name := {}
for (worldId, world) in game.worlds.nodes.toArray do
let mut newItems : HashSet Name := {}
for (_, level) in world.levels.toArray do
newItems := newItems.insertMany (level.getInventory inventoryType).new
allItems := allItems.insertMany (level.getInventory inventoryType).new
for (levelId, level) in world.levels.toArray do
let newLemmas := (level.getInventory inventoryType).new
newItems := newItems.insertMany newLemmas
allItems := allItems.insertMany newLemmas
if inventoryType == .Lemma then
-- For levels `2, 3, …` we check if the previous level was named
-- in which case we add it as available lemma.
match levelId with
| 0 => pure ()
| 1 => pure () -- level ids start with 1, so we need to skip 1, too.
| i₀ + 1 =>
-- add named statement from previous level to the available lemmas.
match (world.levels.find! (i₀)).statementName with
| .anonymous => pure ()
| .num _ _ => panic "Did not expect to get a numerical statement name!"
| .str pre s =>
let name := Name.str pre s
newItems := newItems.insert name
allItems := allItems.insert name
lemmaStatements := lemmaStatements.insert (worldId, levelId) name
if inventoryType == .Lemma then
-- if named, add the lemma from the last level of the world to the inventory
let i₀ := world.levels.size
match (world.levels.find! (i₀)).statementName with
| .anonymous => pure ()
| .num _ _ => panic "Did not expect to get a numerical statement name!"
| .str pre s =>
let name := Name.str pre s
newItems := newItems.insert name
allItems := allItems.insert name
newItemsInWorld := newItemsInWorld.insert worldId newItems
-- Basic inventory item availability: all locked.
@ -457,6 +488,18 @@ elab "MakeGame" : command => do
category := data.category
locked := false }
-- add the statement from the previous level permanently as unlocked
if inventoryType == .Lemma then
match lemmaStatements.find? (worldId, levelId) with
| none => pure ()
| some name =>
let data := (← getInventoryDoc? name inventoryType).get!
items := items.insert name {
name := name
displayName := data.displayName
category := data.category
locked := false }
let itemsArray := items.toArray
|>.insertionSort (fun a b => a.1.toString < b.1.toString)
|>.map (·.2)

@ -173,6 +173,9 @@ structure GameLevel where
/-- Introduction text shown all the time. (markdown) -/
introduction: String := default
conclusion: String := default
/-- The name of the exercise proven. If provided this lemma will be available in
future levels. -/
statementName: Name := default
hints: Array GoalHintEntry := default
/-- The statement in Lean. -/
goal : TSyntax `Lean.Parser.Command.declSig := default
@ -189,6 +192,7 @@ structure GameLevel where
lemmas: InventoryInfo := default
deriving Inhabited, Repr
/-! ## World -/
/-- A world is a collection of levels, like a chapter. -/

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Addition
import NNG.Levels.Addition.Level_1
Game "NNG"
World "Addition"
@ -8,9 +8,7 @@ Title "add_assoc (associativity of addition)"
open MyNat
namespace AdditionWorld
theorem zero_add (n : ) : 0 + n = n := by
theorem MyNat.zero_add (n : ) : 0 + n = n := by
induction n with n hn
· rw [add_zero]
rfl
@ -31,6 +29,7 @@ See if you can prove associativity of addition.
"
Statement MyNat.add_assoc
"On the set of natural numbers, addition is associative.
In other words, for all natural numbers $a, b$ and $c$, we have
$ (a + b) + c = a + (b + c). $"

@ -1,5 +1,4 @@
import NNG.Metadata
import NNG.MyNat.Addition
import NNG.Levels.Addition.Level_2
Game "NNG"
@ -9,9 +8,7 @@ Title "succ_add"
open MyNat
namespace AdditionWorld
theorem add_assoc (a b c : ) : (a + b) + c = a + (b + c) := by
theorem MyNat.add_assoc (a b c : ) : (a + b) + c = a + (b + c) := by
induction c with c hc
· rw [add_zero]
rw [add_zero]
@ -60,8 +57,6 @@ $ \\operatorname{succ}(a) + b = \\operatorname{succ}(a + b)$."
rw [add_succ]
rfl
NewLemma MyNat.add_assoc
Conclusion
"

@ -1,5 +1,4 @@
import NNG.Metadata
import NNG.MyNat.Addition
import NNG.Levels.Addition.Level_3
Game "NNG"
@ -9,9 +8,7 @@ Title "`add_comm` (boss level)"
open MyNat
namespace AdditionWorld
theorem succ_add (a b : ) : succ a + b = succ (a + b) := by
theorem MyNat.succ_add (a b : ) : succ a + b = succ (a + b) := by
induction b with d hd
· rw [add_zero]
rw [add_zero]
@ -52,8 +49,6 @@ $a + b = b + a$."
rw [succ_add]
rfl
NewLemma MyNat.succ_add
Conclusion
"
If you got this far -- nice! You're nearly ready to make a choice:

@ -9,9 +9,7 @@ Title "succ_eq_add_one"
open MyNat
namespace AdditionWorld
theorem add_comm (a b : ) : a + b = b + a := by
theorem MyNat.add_comm (a b : ) : a + b = b + a := by
induction b with d hd
· rw [zero_add]
rw [add_zero]
@ -23,7 +21,7 @@ theorem add_comm (a b : ) : a + b = b + a := by
theorem one_eq_succ_zero : (1 : ) = succ 0 := by simp only
NewLemma MyNat.add_comm MyNat.one_eq_succ_zero
NewLemma MyNat.one_eq_succ_zero
Introduction
"

@ -9,8 +9,6 @@ Title "add_right_comm"
open MyNat
namespace AdditionWorld
Introduction
"
Lean sometimes writes `a + b + c`. What does it mean? The convention is

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
import NNG.MyNat.Multiplication
Game "NNG"

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
import NNG.MyNat.Multiplication
Game "NNG"

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
import NNG.MyNat.Multiplication
Game "NNG"

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
import NNG.MyNat.Multiplication
Game "NNG"

@ -1,5 +1,5 @@
import NNG.Metadata
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
import NNG.MyNat.Multiplication
Game "NNG"

@ -1,4 +1,4 @@
import NNG.MyNat.Theorems.Addition
import NNG.Levels.Addition.Level_6
namespace MyNat
open MyNat

@ -1,46 +0,0 @@
import NNG.Metadata
import NNG.MyNat.Addition
open MyNat
theorem MyNat.zero_add (n : ) : 0 + n = n := by
induction n with n hn
· rw [add_zero]
rfl
· rw [add_succ]
rw [hn]
rfl
theorem MyNat.add_assoc (a b c : ) : (a + b) + c = a + (b + c) := by
induction c with c hc
· rw [add_zero]
rw [add_zero]
rfl
· rw [add_succ]
rw [add_succ]
rw [add_succ]
rw [hc]
rfl
theorem MyNat.succ_add (a b : ) : succ a + b = succ (a + b) := by
induction b with d hd
· rw [add_zero]
rw [add_zero]
rfl
· rw [add_succ]
rw [hd]
rw [add_succ]
rfl
theorem MyNat.add_comm (a b : ) : a + b = b + a := by
induction b with d hd
· rw [zero_add]
rw [add_zero]
rfl
· rw [add_succ]
rw [hd]
rw [succ_add]
rfl
theorem MyNat.one_eq_succ_zero : (1 : ) = succ 0 := by
simp only
Loading…
Cancel
Save