lemma inventory

pull/43/head
Alexander Bentkamp 2 years ago
parent c628d0eec4
commit 6e8a47b1a7

@ -5,23 +5,30 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLock, faLockOpen, faBook, faHammer, faBan } from '@fortawesome/free-solid-svg-icons' import { faLock, faLockOpen, faBook, faHammer, faBan } from '@fortawesome/free-solid-svg-icons'
import Markdown from './Markdown'; import Markdown from './Markdown';
function LeftPanel({ tactics, lemmas } :
function LeftPanel({ tactics, inventory, showSidePanel, setShowSidePanel }) { {lemmas: {name: string, locked: boolean, disabled: boolean}[],
tactics: {name: string, locked: boolean, disabled: boolean}[]}) {
return ( return (
<> <>
<div className="tactic-inventory"> <div className="inventory">
{ tactics.map (({name, locked, disabled}) => { { tactics.map(tac => <InventoryItem name={tac.name} locked={tac.locked} disabled={tac.disabled} />) }
const icon = locked ? <FontAwesomeIcon icon={faLock} /> :
disabled ? <FontAwesomeIcon icon={faBan} /> : ""
const className = locked ? "locked" : disabled ? "disabled" : ""
return <div className={`tactic ${className}`}>{icon} {name}</div>
})}
{/* TODO: Click on Tactic: show info {/* TODO: Click on Tactic: show info
TODO: click on paste icon -> paste into command line */} TODO: click on paste icon -> paste into command line */}
</div> </div>
<div className="inventory">
{ lemmas.map(lem => <InventoryItem name={lem.name} locked={lem.locked} disabled={lem.disabled} />) }
</div>
</> </>
) )
} }
function InventoryItem({name, locked, disabled}) {
const icon = locked ? <FontAwesomeIcon icon={faLock} /> :
disabled ? <FontAwesomeIcon icon={faBan} /> : ""
const className = locked ? "locked" : disabled ? "disabled" : ""
return <div className={`item ${className}`}>{icon} {name}</div>
}
export default LeftPanel; export default LeftPanel;

@ -67,13 +67,8 @@ function Level() {
const [commandLineMode, setCommandLineMode] = useState(true) const [commandLineMode, setCommandLineMode] = useState(true)
const [commandLineInput, setCommandLineInput] = useState("") const [commandLineInput, setCommandLineInput] = useState("")
const [showSidePanel, setShowSidePanel] = useState(true)
const [canUndo, setCanUndo] = useState(initialCode.trim() !== "") const [canUndo, setCanUndo] = useState(initialCode.trim() !== "")
const toggleSidePanel = () => {
setShowSidePanel(!showSidePanel)
}
const theme = useTheme(); const theme = useTheme();
useEffect(() => { useEffect(() => {
@ -184,8 +179,7 @@ function Level() {
</EditorContext.Provider> </EditorContext.Provider>
</div> </div>
<div className="doc-panel"> <div className="doc-panel">
{!level.isLoading && <LeftPanel tactics={level?.data?.tactics} inventory={level?.data?.lemmas} {!level.isLoading && <LeftPanel tactics={level?.data?.tactics} lemmas={level?.data?.lemmas} />}
showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />}
</div> </div>
</Split> </Split>
</> </>

@ -1,16 +1,16 @@
.tactic-inventory { .inventory {
display: flex; display: flex;
gap: .5em; gap: .5em;
flex-wrap : wrap; flex-wrap : wrap;
padding: 1em padding: 1em
} }
.tactic-inventory .tactic { .inventory .item {
border: solid 1px #aaa; border: solid 1px #aaa;
padding: .1em .5em; padding: .1em .5em;
} }
.tactic-inventory .tactic.locked, .inventory .item.locked,
.tactic-inventory .tactic.disabled { .inventory .item.disabled {
color: #aaa; color: #aaa;
} }

@ -15,7 +15,7 @@ interface LevelInfo {
introduction: null|string, introduction: null|string,
index: number, index: number,
tactics: {name: string, disabled: boolean, locked: boolean}[], tactics: {name: string, disabled: boolean, locked: boolean}[],
lemmas: any[], lemmas: {name: string, disabled: boolean, locked: boolean}[],
descrText: null|string, descrText: null|string,
descrFormat: null|string, descrFormat: null|string,
} }

@ -264,32 +264,50 @@ elab "MakeGame" : command => do
if game.worlds.hasLoops then if game.worlds.hasLoops then
throwError "World graph has loops!" throwError "World graph has loops!"
-- Compute which tactics are available in which level: -- Compute which tactics/lemmas are available in which level:
let mut newTacticsInWorld : HashMap Name (HashSet Name) := {} let mut newTacticsInWorld : HashMap Name (HashSet Name) := {}
let mut allTactics : HashSet Name := {} let mut allTactics : HashSet Name := {}
let mut newLemmasInWorld : HashMap Name (HashSet Name) := {}
let mut allLemmas : HashSet Name := {}
for (worldId, world) in game.worlds.nodes.toArray do for (worldId, world) in game.worlds.nodes.toArray do
let mut newTactics : HashSet Name:= {} let mut newTactics : HashSet Name:= {}
let mut newLemmas : HashSet Name:= {}
for (_, level) in world.levels.toArray do for (_, level) in world.levels.toArray do
newTactics := newTactics.insertMany level.newTactics newTactics := newTactics.insertMany level.newTactics
allTactics := allTactics.insertMany level.newTactics allTactics := allTactics.insertMany level.newTactics
newLemmas := newLemmas.insertMany level.newLemmas
allLemmas := allLemmas.insertMany level.newLemmas
newTacticsInWorld := newTacticsInWorld.insert worldId newTactics newTacticsInWorld := newTacticsInWorld.insert worldId newTactics
newLemmasInWorld := newLemmasInWorld.insert worldId newLemmas
let tacticAvailability₀ : HashMap Name TacticAvailability := -- Basic tactic/lemma availability: all locked, none disabled.
let Availability₀ : HashMap Name Availability :=
HashMap.ofList $ HashMap.ofList $
allTactics.toList.map fun name => allTactics.toList.map fun name =>
(name, {name, locked := true, disabled := false}) (name, {name, locked := true, disabled := false})
let lemmaAvailability₀ : HashMap Name Availability :=
HashMap.ofList $
allLemmas.toList.map fun name =>
(name, {name, locked := true, disabled := false})
let mut tacticsInWorld : HashMap Name (HashMap Name TacticAvailability) := {} -- Availability after a given world
let mut tacticsInWorld : HashMap Name (HashMap Name Availability) := {}
let mut lemmasInWorld : HashMap Name (HashMap Name Availability) := {}
for (worldId, _) in game.worlds.nodes.toArray do for (worldId, _) in game.worlds.nodes.toArray do
let mut tactics : HashMap Name TacticAvailability := tacticAvailability₀ let mut tactics := Availability₀
let mut lemmas := lemmaAvailability₀
let predecessors := game.worlds.predecessors worldId let predecessors := game.worlds.predecessors worldId
for predWorldId in predecessors do for predWorldId in predecessors do
for tac in newTacticsInWorld.find! predWorldId do for tac in newTacticsInWorld.find! predWorldId do
tactics := tactics.insert tac {name := tac, locked := false, disabled := false} tactics := tactics.insert tac {name := tac, locked := false, disabled := false}
for lem in newLemmasInWorld.find! predWorldId do
lemmas := lemmas.insert lem {name := lem, locked := false, disabled := false}
tacticsInWorld := tacticsInWorld.insert worldId tactics tacticsInWorld := tacticsInWorld.insert worldId tactics
lemmasInWorld := lemmasInWorld.insert worldId lemmas
for (worldId, world) in game.worlds.nodes.toArray do for (worldId, world) in game.worlds.nodes.toArray do
let mut tactics := tacticsInWorld.find! worldId let mut tactics := tacticsInWorld.find! worldId
let mut lemmas := lemmasInWorld.find! worldId
let levels := world.levels.toArray.insertionSort fun a b => a.1 < b.1 let levels := world.levels.toArray.insertionSort fun a b => a.1 < b.1
@ -298,9 +316,20 @@ elab "MakeGame" : command => do
tactics := tactics.insert tac {name := tac, locked := false, disabled := false} tactics := tactics.insert tac {name := tac, locked := false, disabled := false}
for tac in level.disabledTactics do for tac in level.disabledTactics do
tactics := tactics.insert tac {name := tac, locked := false, disabled := true} tactics := tactics.insert tac {name := tac, locked := false, disabled := true}
for lem in level.newLemmas do
lemmas := lemmas.insert lem {name := lem, locked := false, disabled := false}
for lem in level.disabledLemmas do
lemmas := lemmas.insert lem {name := lem, locked := false, disabled := true}
let tacticArray := tactics.toArray let tacticArray := tactics.toArray
|>.insertionSort (fun a b => a.1.toString < b.1.toString) |>.insertionSort (fun a b => a.1.toString < b.1.toString)
|>.map (·.2) |>.map (·.2)
let lemmaArray := lemmas.toArray
|>.insertionSort (fun a b => a.1.toString < b.1.toString)
|>.map (·.2)
modifyLevel ⟨← getCurGameId, worldId, levelId⟩ fun level => do modifyLevel ⟨← getCurGameId, worldId, levelId⟩ fun level => do
return {level with tactics := tacticArray} return {level with
tactics := tacticArray
lemmas := lemmaArray}

@ -144,7 +144,7 @@ structure LevelId where
level : Nat level : Nat
deriving Inhabited deriving Inhabited
structure TacticAvailability where structure Availability where
name : Name name : Name
locked : Bool locked : Bool
disabled : Bool disabled : Bool
@ -176,7 +176,7 @@ structure GameLevel where
-- only these tactics are allowed in this level (ignore if empty): -- only these tactics are allowed in this level (ignore if empty):
onlyTactics: Array Name := default onlyTactics: Array Name := default
-- tactics in this level (computed by `MakeGame`): -- tactics in this level (computed by `MakeGame`):
tactics: Array TacticAvailability := default tactics: Array Availability := default
-- new lemmas introduces by this level: -- new lemmas introduces by this level:
newLemmas: Array Name := default newLemmas: Array Name := default
-- lemmas exceptionally forbidden in this level: -- lemmas exceptionally forbidden in this level:
@ -184,7 +184,7 @@ structure GameLevel where
-- only these lemmas are allowed in this level (ignore if empty): -- only these lemmas are allowed in this level (ignore if empty):
onlyLemmas: Array Name := default onlyLemmas: Array Name := default
-- lemmas in this level (computed by `MakeGame`): -- lemmas in this level (computed by `MakeGame`):
lemmas: Array LemmaDocEntry := default lemmas: Array Availability := default
hints: Array GoalHintEntry := default hints: Array GoalHintEntry := default
goal : TSyntax `Lean.Parser.Command.declSig := default goal : TSyntax `Lean.Parser.Command.declSig := default
descrText: String := default descrText: String := default

@ -41,8 +41,8 @@ Fields:
structure LevelInfo where structure LevelInfo where
index : Nat index : Nat
title : String title : String
tactics: Array TacticAvailability tactics: Array Availability
lemmas: Array LemmaDocEntry lemmas: Array Availability
introduction : String introduction : String
descrText : String := "" descrText : String := ""
descrFormat : String := "" descrFormat : String := ""

Loading…
Cancel
Save