1use logicaffeine_system::fs::{Vfs, VfsResult};
7
8pub async fn seed_examples<V: Vfs>(vfs: &V) -> VfsResult<()> {
10 vfs.create_dir_all("/examples/logic").await?;
12 vfs.create_dir_all("/examples/code").await?;
13 vfs.create_dir_all("/examples/math").await?;
14 vfs.create_dir_all("/examples/hardware").await?;
15 vfs.create_dir_all("/workspace").await?;
16 for sub in [
17 "basics", "types", "collections", "functions", "distributed", "security", "memory",
18 "concurrency", "networking", "advanced", "native", "temporal",
19 ] {
20 vfs.create_dir_all(&format!("/examples/code/{sub}")).await?;
21 }
22
23 for obsolete in ["toggle.v", "mutex.v", "counter.v"] {
25 let _ = vfs.remove(&format!("/examples/hardware/{obsolete}")).await;
26 }
27
28 for spec in ALL_LOGIC_EXAMPLES
32 .iter()
33 .chain(ALL_CODE_EXAMPLES)
34 .chain(ALL_MATH_EXAMPLES)
35 .chain(ALL_HARDWARE_SPECS)
36 {
37 vfs.write(spec.vfs_path, spec.source.as_bytes()).await?;
38 }
39
40 Ok(())
41}
42
43pub const HARDWARE_EXAMPLES: &[(&str, &str)] = &[
51 ("handshake.hw", "Always, if request is high, then acknowledge is high."),
52 ("enable-ready.hw", "Always, if enable is high, then ready is high."),
53 ("start-done.hw", "Always, if start is high, then done is high."),
54 ("write-full.hw", "Always, if write is high, then full is high."),
55 (
58 "intersection-design.hw",
59 "Movements: ns-through, ew-through, ns-left, ew-left, pedestrian.\n\
60 ns-through conflicts with ew-through and ew-left.\n\
61 ew-through conflicts with ns-left.\n\
62 ns-left conflicts with ew-left.\n\
63 pedestrian conflicts with ns-through, ew-through, ns-left and ew-left.",
64 ),
65];
66
67pub const RTL_EXAMPLES: &[(&str, &str)] = &[
73 (
74 "arbiter.v",
75 "// 2-master round-robin arbiter. Grants are issued in mutually-exclusive branches.\n// PROVEN by k-induction (for every request/turn sequence): the two masters are\n// NEVER granted the bus at the same time.\nmodule arbiter(input clk, input r0, input r1);\n reg g0;\n reg g1;\n reg turn;\n initial begin g0 = 0; g1 = 0; turn = 0; end\n always @(posedge clk) begin\n if (r0 && (!r1 || turn == 0)) begin\n g0 <= 1;\n g1 <= 0;\n end else if (r1) begin\n g0 <= 0;\n g1 <= 1;\n end else begin\n g0 <= 0;\n g1 <= 0;\n end\n turn <= ~turn;\n end\n assert property (~(g0 & g1));\nendmodule\n",
76 ),
77 (
78 "bad-arbiter.v",
79 "// The classic arbiter BUG: each request is granted independently. If both masters\n// request in the same cycle, BOTH are granted. BMC finds the violation at step 1 and\n// the waveform shows r0=r1=1 -> g0=g1=1 (a real mutual-exclusion failure).\nmodule bad_arbiter(input clk, input r0, input r1);\n reg g0;\n reg g1;\n initial begin g0 = 0; g1 = 0; end\n always @(posedge clk) begin\n if (r0) g0 <= 1; else g0 <= 0;\n if (r1) g1 <= 1; else g1 <= 0;\n end\n assert property (~(g0 & g1));\nendmodule\n",
80 ),
81 (
82 "fifo.v",
83 "// FIFO occupancy counter, depth 8, over FREE push/pop inputs. Increment only when not\n// full, decrement only when not empty. PROVEN: the occupancy never overflows past 8 for\n// ANY push/pop sequence — even though `count` is a 4-bit register that could reach 15.\nmodule fifo(input clk, input push, input pop);\n reg [3:0] count;\n initial count = 0;\n always @(posedge clk)\n if (push && (count < 4'd8) && !(pop && (count > 4'd0)))\n count <= count + 1;\n else if (pop && (count > 4'd0) && !(push && (count < 4'd8)))\n count <= count - 1;\n else\n count <= count;\n assert property (count <= 4'd8);\nendmodule\n",
84 ),
85 (
86 "onehot.v",
87 "// 3-state one-hot ring FSM. The rotation a<=c, b<=a, c<=b permutes the state bits.\n// PROVEN invariant: EXACTLY one of a/b/c is ever high (at-least-one AND at-most-one).\nmodule onehot(input clk);\n reg a;\n reg b;\n reg c;\n initial begin a = 1; b = 0; c = 0; end\n always @(posedge clk) begin\n a <= c;\n b <= a;\n c <= b;\n end\n assert property ((a | b | c) & ~(a & b) & ~(a & c) & ~(b & c));\nendmodule\n",
88 ),
89 (
90 "reset-mirror.v",
91 "// Two registers with identical reset+toggle logic over a FREE reset input.\n// PROVEN by k-induction for EVERY reset sequence: a and b always stay equal.\nmodule mirror(input clk, input rst);\n reg a;\n reg b;\n initial begin a = 0; b = 0; end\n always @(posedge clk) begin\n if (rst) a <= 0; else a <= ~a;\n if (rst) b <= 0; else b <= ~b;\n end\n assert property (a == b);\nendmodule\n",
92 ),
93 (
94 "traffic-safe.v",
95 "// 🚦 A COMPLEX signalized intersection — the kind you verify for a formal-methods\n// final. NS/EW through movements, PROTECTED left turns (nsl/ewl), and a PEDESTRIAN phase,\n// sequenced by a 9-state controller with a per-phase timer. Lights: 0=red 1=green 2=yellow.\n// PROVEN by k-induction: no two conflicting movements are ever active together, and\n// pedestrians get WALK only when EVERY vehicle movement is red.\nmodule traffic(input clk);\n reg [1:0] ns;\n reg [1:0] ew;\n reg [1:0] nsl;\n reg [1:0] ewl;\n reg ped;\n reg [3:0] phase;\n reg [2:0] timer;\n initial begin ns=2'd0; ew=2'd0; nsl=2'd1; ewl=2'd0; ped=1'd0; phase=4'd0; timer=3'd1; end\n always @(posedge clk)\n if (timer == 3'd0) begin\n timer <= 3'd1;\n if (phase == 4'd0) begin phase<=4'd1; nsl<=2'd2; ns<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd1) begin phase<=4'd2; nsl<=2'd0; ns<=2'd1; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd2) begin phase<=4'd3; ns<=2'd2; nsl<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd3) begin phase<=4'd4; ewl<=2'd1; ns<=2'd0; ew<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd4) begin phase<=4'd5; ewl<=2'd2; ns<=2'd0; ew<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd5) begin phase<=4'd6; ewl<=2'd0; ew<=2'd1; ns<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd6) begin phase<=4'd7; ew<=2'd2; ns<=2'd0; nsl<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd7) begin phase<=4'd8; ped<=1'd1; ns<=2'd0; ew<=2'd0; nsl<=2'd0; ewl<=2'd0; end\n else begin phase<=4'd0; nsl<=2'd1; ns<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n end else\n timer <= timer - 1;\n assert property (~((ns != 2'd0) & (ew != 2'd0)) & ~((ped == 1'd1) & ((ns != 2'd0) | (ew != 2'd0) | (nsl != 2'd0) | (ewl != 2'd0))));\nendmodule\n",
96 ),
97 (
98 "traffic-crash.v",
99 "// 🚦💥 The SAME intersection with ONE dangerous bug: the pedestrian phase raises WALK\n// but forgets to clear NS, so it sends pedestrians into live cross traffic. BMC finds the\n// exact cycle — watch the lights step through the REAL trace, then flash CONFLICT.\nmodule traffic(input clk);\n reg [1:0] ns;\n reg [1:0] ew;\n reg [1:0] nsl;\n reg [1:0] ewl;\n reg ped;\n reg [3:0] phase;\n reg [2:0] timer;\n initial begin ns=2'd0; ew=2'd0; nsl=2'd1; ewl=2'd0; ped=1'd0; phase=4'd0; timer=3'd1; end\n always @(posedge clk)\n if (timer == 3'd0) begin\n timer <= 3'd1;\n if (phase == 4'd0) begin phase<=4'd1; nsl<=2'd2; ns<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd1) begin phase<=4'd2; nsl<=2'd0; ns<=2'd1; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd2) begin phase<=4'd3; ns<=2'd2; nsl<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd3) begin phase<=4'd4; ewl<=2'd1; ns<=2'd0; ew<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd4) begin phase<=4'd5; ewl<=2'd2; ns<=2'd0; ew<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd5) begin phase<=4'd6; ewl<=2'd0; ew<=2'd1; ns<=2'd0; nsl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd6) begin phase<=4'd7; ew<=2'd2; ns<=2'd0; nsl<=2'd0; ewl<=2'd0; ped<=1'd0; end\n else if (phase == 4'd7) begin phase<=4'd8; ped<=1'd1; ns<=2'd1; ew<=2'd0; nsl<=2'd0; ewl<=2'd0; end\n else begin phase<=4'd0; nsl<=2'd1; ns<=2'd0; ew<=2'd0; ewl<=2'd0; ped<=1'd0; end\n end else\n timer <= timer - 1;\n assert property (~((ns != 2'd0) & (ew != 2'd0)) & ~((ped == 1'd1) & ((ns != 2'd0) | (ew != 2'd0) | (nsl != 2'd0) | (ewl != 2'd0))));\nendmodule\n",
100 ),
101 (
102 "queue-jam.v",
103 "// \u{1F697}\u{1F6A6} TRAFFIC FLOW: an approach's queue is a counter. Served only every other cycle\n// while a car arrives each cycle (demand > capacity), so the queue climbs until it JAMS. BMC\n// finds the exact cycle it overflows \u{2014} watch q ramp up in the waveform.\nmodule flow(input clk);\n reg [2:0] q;\n reg phase;\n initial begin q = 3'd0; phase = 1'd0; end\n always @(posedge clk) begin\n phase <= ~phase;\n if (phase == 1'd1) q <= q + 3'd1;\n end\n assert property (q < 3'd7);\nendmodule\n",
104 ),
105 (
106 "queue-stable.v",
107 "// \u{1F697}\u{2705} TRAFFIC FLOW: the same queue, but service keeps up with demand, so a starting\n// backlog only ever DRAINS. PROVEN by k-induction to never jam \u{2014} for all time, not just a\n// bounded window.\nmodule flow(input clk);\n reg [2:0] q;\n initial begin q = 3'd5; end\n always @(posedge clk)\n if (q != 3'd0) q <= q - 3'd1;\n assert property (q < 3'd7);\nendmodule\n",
108 ),
109];
110
111pub const REGALLOC_EXAMPLES: &[(&str, &str)] = &[
115 (
116 "register-alloc-fits.hw",
117 "# Register allocation — a basic block whose live ranges fit in 3 registers.\n\
118 # Each line is `variable: firstInstr-lastInstr`; `registers:` is the physical budget.\n\
119 registers: 3\n\
120 a: 0-4\n\
121 b: 1-3\n\
122 c: 2-6\n\
123 d: 5-9\n\
124 e: 7-10\n",
125 ),
126 (
127 "register-alloc-spill.hw",
128 "# Register allocation — OVER PRESSURE: four variables are live at once but only 3\n\
129 # registers exist, so the allocator certifies (via the mutually-interfering clique)\n\
130 # that at least one must spill.\n\
131 registers: 3\n\
132 a: 0-6\n\
133 b: 1-7\n\
134 c: 2-8\n\
135 d: 3-9\n",
136 ),
137];
138
139pub const PIGEONHOLE_EXAMPLES: &[(&str, &str)] = &[
144 (
145 "pigeonhole.hw",
146 "# Pigeonhole — N pigeons into N-1 holes is impossible. Watch the last pigeon find no home.\n\
147 # Our prover certifies UNSAT in polynomial time (maximum matching + symmetry breaking);\n\
148 # every resolution solver (Kissat, CaDiCaL, Z3) needs exponentially many steps here.\n\
149 pigeons: 6\n",
150 ),
151 (
152 "pigeonhole-12.hw",
153 "# PHP(12): far past where Z3 times out, our certified PR proof stays polynomial.\n\
154 pigeons: 12\n",
155 ),
156];
157
158pub const LOGIC_SIMPLE: &str = r#"# Simple Sentences
163
164Every cat sleeps.
165Some dogs bark loudly.
166John loves Mary.
167The quick brown fox jumps.
168No student failed.
169"#;
170
171pub const LOGIC_QUANTIFIERS: &str = r#"# Quantifier Scope
172
173Every student read a book.
174A professor supervises every student.
175No student failed every exam.
176Some teacher praised every student.
177Every dog chased some cat.
178"#;
179
180const LOGIC_TENSE: &str = r#"# Tense and Aspect
181
182John was running.
183Mary has eaten.
184The train will arrive.
185She had been sleeping.
186They have been working.
187"#;
188
189const LOGIC_PROVER: &str = r#"## Theorem: Socrates_Mortality
194Given: All men are mortal.
195Given: Socrates is a man.
196Prove: Socrates is mortal.
197Proof: Auto.
198"#;
199
200const LOGIC_SIMON: &str = r#"## Theorem: Simon
207Given: Alpha, Beta, Gamma, and Delta are four different trips.
208Given: 2001, 2002, 2003, and 2004 are four different years.
209Given: Connecticut, Florida, Kentucky, and Maine are four different states.
210Given: Bill, Lillie, Neal, and Yvonne are four different friends.
211Given: Cycling, hunting, kayaking, and skydiving are four different activities.
212Given: Every trip is in 2001 or in 2002 or in 2003 or in 2004.
213Given: Exactly one trip is in 2001.
214Given: Exactly one trip is in 2002.
215Given: Exactly one trip is in 2003.
216Given: Exactly one trip is in 2004.
217Given: Every trip is in Connecticut or in Florida or in Kentucky or in Maine.
218Given: Exactly one trip is in Connecticut.
219Given: Exactly one trip is in Florida.
220Given: Exactly one trip is in Kentucky.
221Given: Exactly one trip is in Maine.
222Given: Every trip is with Bill or with Lillie or with Neal or with Yvonne.
223Given: Exactly one trip is with Bill.
224Given: Exactly one trip is with Lillie.
225Given: Exactly one trip is with Neal.
226Given: Exactly one trip is with Yvonne.
227Given: Every trip is cycling or hunting or kayaking or skydiving.
228Given: Exactly one trip is cycling.
229Given: Exactly one trip is hunting.
230Given: Exactly one trip is kayaking.
231Given: Exactly one trip is skydiving.
232Given: Alpha is in 2001.
233Given: Beta is in 2002.
234Given: Gamma is in 2003.
235Given: Delta is in 2004.
236Given: Of the hunting trip and the 2004 trip, one was with Neal and the other was in Connecticut.
237Given: The Florida trip was the hunting trip.
238Given: Neither the trip with Bill nor the Florida trip is the 2001 trip.
239Given: The trip with Yvonne is not in Kentucky.
240Given: Of the skydiving trip and the Maine trip, one was in 2003 and the other was with Bill.
241Given: The 2003 trip is not the cycling trip.
242Prove: Beta is in Florida.
243Proof: Auto.
244"#;
245
246const LOGIC_SYLLOGISM: &str = r#"## Theorem: Chain_Reasoning
247Given: All men are mortal.
248Given: All mortals are doomed.
249Given: Plato is a man.
250Prove: Plato is doomed.
251Proof: Auto.
252"#;
253
254const LOGIC_TRIVIAL: &str = r#"## Theorem: Direct_Match
255Given: Socrates is mortal.
256Prove: Socrates is mortal.
257Proof: Auto.
258"#;
259
260const LOGIC_DISJUNCTIVE: &str = r#"## Theorem: Disjunctive_Syllogism
261Given: Either Alice or Bob is guilty.
262Given: Alice is not guilty.
263Prove: Bob is guilty.
264Proof: Auto.
265"#;
266
267const LOGIC_MODUS_TOLLENS: &str = r#"## Theorem: Modus_Tollens_Chain
268Given: If the butler did it, he was seen.
269Given: If he was seen, he was caught.
270Given: He was not caught.
271Prove: The butler did not do it.
272Proof: Auto.
273"#;
274
275pub const LOGIC_LEIBNIZ: &str = r#"## Theorem: Leibniz_Identity
276Given: Clark is Superman.
277Given: Clark is mortal.
278Prove: Superman is mortal.
279Proof: Auto.
280"#;
281
282pub const LOGIC_BARBER: &str = r#"## Theorem: Barber_Paradox
283Given: The barber is a man.
284Given: The barber shaves all men who do not shave themselves.
285Given: The barber does not shave any man who shaves himself.
286Prove: The barber does not exist.
287Proof: Auto.
288"#;
289
290pub const CODE_HELLO: &str = r#"## Main
295
296Let greeting be "Hello, LOGOS!".
297Show greeting.
298
299Let x be 10.
300Let y be 20.
301Let sum be x + y.
302
303Show "The sum is:".
304Show sum.
305"#;
306
307const CODE_HELLO2: &str = r#"## Main
309
310greeting = "Hello, World!".
311Show greeting.
312
313counter = 0.
314Set counter to counter + 1.
315Show counter.
316"#;
317
318pub const CODE_FIBONACCI: &str = r#"## Main
319
320Let n be 10.
321Let a be 0.
322Let b be 1.
323
324Show "Fibonacci sequence:".
325Show a.
326
327Repeat for i from 1 to n:
328 Show b.
329 Let temp be a + b.
330 Set a to b.
331 Set b to temp.
332"#;
333
334const CODE_FIZZBUZZ: &str = r#"## Main
335
336Repeat for i from 1 to 20:
337 If i / 15 * 15 equals i:
338 Show "FizzBuzz".
339 Otherwise:
340 If i / 3 * 3 equals i:
341 Show "Fizz".
342 Otherwise:
343 If i / 5 * 5 equals i:
344 Show "Buzz".
345 Otherwise:
346 Show i.
347"#;
348
349const CODE_FIZZBUZZ2: &str = r#"## Main
351
352for i from 1 to 20:
353 If i / 15 * 15 equals i:
354 Show "FizzBuzz".
355 Otherwise If i / 3 * 3 equals i:
356 Show "Fizz".
357 Else If i / 5 * 5 equals i:
358 Show "Buzz".
359 Otherwise:
360 Show i.
361"#;
362
363const CODE_FIZZBUZZ3: &str = r#"## Main
365
366for i from 1 to 20:
367 If i / 15 * 15 equals i:
368 Show "FizzBuzz".
369 elif i / 3 * 3 equals i:
370 Show "Fizz".
371 elif i / 5 * 5 equals i:
372 Show "Buzz".
373 Else:
374 Show i.
375"#;
376
377const CODE_COLLECTIONS: &str = r#"## Main
378
379Let numbers be [1, 2, 3, 4, 5].
380Show "Numbers:".
381Show numbers.
382
383Push 6 to numbers.
384Show "After push:".
385Show numbers.
386
387Show "Length:".
388Show length of numbers.
389
390Show "First item:".
391Show item 1 of numbers.
392
393Show "Last item:".
394Show item 6 of numbers.
395"#;
396
397const CODE_FACTORIAL: &str = r#"## To factorial (n: Int):
398 If n <= 1:
399 Return 1.
400 Return n * factorial(n - 1).
401
402## Main
403
404Show "Factorial of 5:".
405Let result be factorial(5).
406Show result.
407
408Show "Factorial of 10:".
409Let big be factorial(10).
410Show big.
411"#;
412
413const CODE_PRIME: &str = r#"## To is_prime (n: Int) -> Bool:
414 If n <= 1:
415 Return false.
416 Let i be 2.
417 While i * i <= n:
418 If n / i * i equals n:
419 Return false.
420 Set i to i + 1.
421 Return true.
422
423## Main
424
425Show "Prime numbers from 2 to 30:".
426Repeat for num from 2 to 30:
427 If is_prime(num):
428 Show num.
429"#;
430
431const CODE_SUM_LIST: &str = r#"## Main
432
433Let numbers be [10, 20, 30, 40, 50].
434Let total be 0.
435
436Repeat for n in numbers:
437 Set total to total + n.
438
439Show "Sum of [10, 20, 30, 40, 50]:".
440Show total.
441"#;
442
443const CODE_BUBBLE_SORT: &str = r#"## Main
444
445Let numbers be [64, 34, 25, 12, 22, 11, 90].
446Let n be length of numbers.
447
448Show "Before sorting:".
449Show numbers.
450
451Repeat for i from 1 to n:
452 Repeat for j from 1 to (n - i):
453 Let a be item j of numbers.
454 Let b be item (j + 1) of numbers.
455 If a > b:
456 Set item j of numbers to b.
457 Set item (j + 1) of numbers to a.
458
459Show "After sorting:".
460Show numbers.
461"#;
462
463const CODE_STRUCT: &str = r#"## Definition
464
465A Person has:
466 a public name, which is Text.
467 a public age, which is Int.
468
469## Main
470
471Let alice be a new Person.
472Set alice's name to "Alice".
473Set alice's age to 30.
474
475Let bob be a new Person.
476Set bob's name to "Bob".
477Set bob's age to 25.
478
479Show "Person 1:".
480Show alice's name.
481Show alice's age.
482
483Show "Person 2:".
484Show bob's name.
485Show bob's age.
486"#;
487
488const CODE_ENUMS: &str = r#"# Enums & Pattern Matching
495
496## A Color is one of:
497 A Red.
498 A Green.
499 A Blue.
500
501## Main
502
503Let c be a new Red.
504Inspect c:
505 When Red: Show "It's red!".
506 When Green: Show "It's green!".
507 When Blue: Show "It's blue!".
508
509Let c2 be a new Blue.
510Inspect c2:
511 When Red: Show "red".
512 Otherwise: Show "not red".
513"#;
514
515const CODE_GENERICS: &str = r#"## Main
516
517Let mut scores be a new Map of Text to Int.
518Set scores["Alice"] to 100.
519Set scores["Bob"] to 85.
520Set scores["Charlie"] to 92.
521
522Let alice_score be scores["Alice"].
523Show "Alice's score:".
524Show alice_score.
525
526Set scores["Bob"] to 90.
527Show "Bob's new score:".
528Show scores["Bob"].
529
530Let total be scores["Alice"] + scores["Bob"] + scores["Charlie"].
531Show "Total:".
532Show total.
533"#;
534
535const CODE_SETS: &str = r#"## Main
538
539Let names be a new Set of Text.
540Add "Alice" to names.
541Add "Bob" to names.
542Add "Charlie" to names.
543Add "Alice" to names.
544
545Show "Set size (duplicates ignored):".
546Show length of names.
547
548If names contains "Bob":
549 Show "Bob is in the set!".
550
551Remove "Bob" from names.
552Show "After removing Bob:".
553Show length of names.
554
555Let sum be 0.
556Let numbers be a new Set of Int.
557Add 10 to numbers.
558Add 20 to numbers.
559Add 30 to numbers.
560Repeat for n in numbers:
561 Set sum to sum + n.
562Show "Sum of numbers:".
563Show sum.
564"#;
565
566const CODE_MAPS: &str = r#"## Main
567
568Let mut inventory be a new Map of Text to Int.
569Set item "iron" of inventory to 50.
570Set inventory["copper"] to 30.
571Set inventory["gold"] to 10.
572
573Show "Iron count:".
574Show item "iron" of inventory.
575
576Show "Copper count:".
577Show inventory["copper"].
578
579Set inventory["iron"] to 100.
580Show "Updated iron:".
581Show inventory["iron"].
582
583Let total be item "iron" of inventory + inventory["copper"] + inventory["gold"].
584Show "Total resources:".
585Show total.
586"#;
587
588const CODE_HIGHER_ORDER: &str = r#"## To double (x: Int):
591 Return x * 2.
592
593## To add (a: Int) and (b: Int):
594 Return a + b.
595
596## To isEven (n: Int) -> Bool:
597 Return n / 2 * 2 equals n.
598
599## Main
600
601Show "Double of 21:".
602Show double(21).
603
604Show "Sum of 15 and 27:".
605Show add(15, 27).
606
607Show "Is 42 even?".
608Show isEven(42).
609
610Show "Is 17 even?".
611Show isEven(17).
612"#;
613
614pub const CODE_CRDT_COUNTERS: &str = r#"## Definition
617A Counter is Shared and has:
618 points: ConvergentCount.
619
620## Main
621Let mutable c be a new Counter.
622Increase c's points by 10.
623Increase c's points by 5.
624Increase c's points by 3.
625Show "Total points:".
626Show c's points.
627"#;
628
629const CODE_POLICIES: &str = r#"# Security Policies
632
633## Definition
634A User has:
635 a role, which is Text.
636
637## Policy
638A User is admin if the user's role equals "admin".
639
640## Main
641
642Let u be a new User with role "admin".
643Check that the u is admin.
644Show "Admin check passed!".
645
646Let guest be a new User with role "guest".
647Show "Guest created (would fail admin check)".
648"#;
649
650const CODE_ZONES: &str = r#"# Memory Zones
653
654## Main
655
656Show "Working with memory zones...".
657
658Inside a zone called "Work":
659 Let x be 42.
660 Let y be 58.
661 Let sum be x + y.
662 Show "Sum in zone:".
663 Show sum.
664
665Inside a zone called "Buffer" of size 1 MB:
666 Let value be 100.
667 Show "Value in sized zone:".
668 Show value.
669
670Show "Zones cleaned up!".
671"#;
672
673const CODE_TASKS: &str = r#"## To worker:
676 Show "worker done".
677
678## To greet (name: Text):
679 Show name.
680
681## Main
682
683Launch a task to worker.
684Show "main continues".
685
686Launch a task to greet with "Hello from task".
687Show "task launched".
688"#;
689
690const CODE_CHANNELS: &str = r#"## Main
691
692Let ch be a Pipe of Int.
693Show "pipe created".
694
695Send 42 into ch.
696Show "sent 42".
697
698Receive x from ch.
699Show "received:".
700Show x.
701"#;
702
703pub const MATH_NAT: &str = r#"-- Natural Numbers
708-- The foundation of arithmetic in type theory
709
710-- Define the natural number type
711Inductive Nat := Zero : Nat | Succ : Nat -> Nat.
712
713-- Define some numbers
714Definition one : Nat := Succ Zero.
715Definition two : Nat := Succ one.
716Definition three : Nat := Succ two.
717
718-- Check the types
719Check Zero.
720Check Succ.
721Check one.
722Check two.
723
724-- Evaluate expressions
725Eval three.
726"#;
727
728pub const MATH_BOOL: &str = r#"Inductive MyBool := Yes : MyBool | No : MyBool.
729
730Check Yes.
731Check No.
732Eval Yes.
733Eval No.
734
735Definition id_bool : MyBool -> MyBool := fun b : MyBool => b.
736
737Check id_bool.
738Eval id_bool Yes.
739Eval id_bool No.
740"#;
741
742const MATH_GODEL: &str = r#"-- Godel Sentence Construction
743-- Building the self-referential sentence G
744
745-- The Provable predicate: "there exists a derivation concluding s"
746Definition Provable : Syntax -> Prop :=
747 fun s : Syntax => Ex Derivation (fun d : Derivation => Eq Syntax (concludes d) s).
748
749-- The Godel template T = "Not(Provable(x))"
750-- When we apply the diagonal lemma, x becomes the code of T itself
751Definition T : Syntax := SApp (SName "Not") (SApp (SName "Provable") (SVar 0)).
752
753-- The Godel sentence G = T[code(T)/x]
754-- G says "I am not provable"
755Definition G : Syntax := syn_diag T.
756
757-- Check our constructions
758Check Provable.
759Check T.
760Check G.
761
762-- G has type Syntax (it's a syntactic object)
763-- But Provable G has type Prop (it's a proposition)
764Check (Provable G).
765"#;
766
767const MATH_INCOMPLETENESS: &str = r#"-- Godel's First Incompleteness Theorem
768-- If LOGOS is consistent, G is not provable
769
770-- Setup: Provable predicate
771Definition Provable : Syntax -> Prop :=
772 fun s : Syntax => Ex Derivation (fun d : Derivation => Eq Syntax (concludes d) s).
773
774-- Consistency: the system cannot prove False
775Definition Consistent : Prop := Not (Provable (SName "False")).
776
777-- The Godel template and sentence
778Definition T : Syntax := SApp (SName "Not") (SApp (SName "Provable") (SVar 0)).
779Definition G : Syntax := syn_diag T.
780
781-- THE THEOREM STATEMENT
782-- "If LOGOS is consistent, then G is not provable"
783Definition Godel_I : Prop := Consistent -> Not (Provable G).
784
785-- Check that our theorem statement is well-typed
786Check Godel_I.
787Check Consistent.
788Check (Provable G).
789Check (Not (Provable G)).
790
791-- This is a proposition (a type in Prop)
792-- A proof would be a term of this type
793"#;
794
795pub const MATH_PROP_LOGIC: &str = r#"-- Propositional Logic Types
796-- Encoding logical connectives as types
797
798Inductive MyProp :=
799 PTrue : MyProp
800 | PFalse : MyProp
801 | PAnd : MyProp -> MyProp -> MyProp
802 | POr : MyProp -> MyProp -> MyProp
803 | PNot : MyProp -> MyProp.
804
805-- Some example propositions
806Definition p1 : MyProp := PTrue.
807Definition p2 : MyProp := PFalse.
808Definition p3 : MyProp := PAnd PTrue PTrue.
809Definition p4 : MyProp := POr PTrue PFalse.
810Definition p5 : MyProp := PNot PFalse.
811
812-- Check and evaluate
813Check p3.
814Check p4.
815Check p5.
816Eval p3.
817Eval p4.
818Eval p5.
819"#;
820
821const MATH_FUNCTIONS: &str = r#"-- Simple Functions
822-- Lambda calculus basics
823
824-- Identity function
825Definition id : Nat -> Nat := fun x : Nat => x.
826
827-- Constant function
828Definition const_zero : Nat -> Nat := fun x : Nat => Zero.
829
830-- Apply successor twice
831Definition double_succ : Nat -> Nat := fun x : Nat => Succ (Succ x).
832
833-- Check types
834Check id.
835Check const_zero.
836Check double_succ.
837
838-- Evaluate some applications
839Definition one : Nat := Succ Zero.
840Definition two : Nat := Succ one.
841
842Eval id one.
843Eval const_zero two.
844Eval double_succ one.
845"#;
846
847const MATH_LIST_OPS: &str = r#"-- List Operations
848-- Polymorphic lists in type theory
849
850-- Define a list type (built-in, but showing the structure)
851Inductive MyList (A : Type) :=
852 MyNil : MyList A
853 | MyCons : A -> MyList A -> MyList A.
854
855-- Example: a list of natural numbers
856Definition nat_list : MyList Nat := MyCons Nat Zero (MyCons Nat (Succ Zero) (MyNil Nat)).
857
858-- Check the types
859Check MyNil.
860Check MyCons.
861Check nat_list.
862
863-- Evaluate
864Eval nat_list.
865"#;
866
867const MATH_PAIRS: &str = r#"-- Pairs and Products
868-- Cartesian product types
869
870-- A small boolean type to pair with numbers.
871Inductive MyBool := Yes : MyBool | No : MyBool.
872
873Inductive MyPair (A : Type) (B : Type) :=
874 MkPair : A -> B -> MyPair A B.
875
876-- Example pairs
877Definition nat_bool_pair : MyPair Nat MyBool := MkPair Nat MyBool Zero Yes.
878Definition nat_nat_pair : MyPair Nat Nat := MkPair Nat Nat Zero (Succ Zero).
879
880-- Check types
881Check MkPair.
882Check nat_bool_pair.
883Check nat_nat_pair.
884
885-- Evaluate
886Eval nat_bool_pair.
887Eval nat_nat_pair.
888"#;
889
890const MATH_CIRCUIT: &str = r#"-- Logic Gates as a Circuit
891-- Encode the gates formally, then hit the crab Compile button to extract
892-- runnable Rust. The same code could run in WASM or drive a hardware circuit —
893-- this is "encode it, extract it, run it".
894
895Inductive MyBit := Lo : MyBit | Hi : MyBit.
896
897Definition not1 : MyBit -> MyBit := fun a : MyBit =>
898 match a return (fun _ : MyBit => MyBit) with | Lo => Hi | Hi => Lo.
899
900Definition and2 : MyBit -> MyBit -> MyBit := fun a : MyBit => fun b : MyBit =>
901 match a return (fun _ : MyBit => MyBit) with | Lo => Lo | Hi => b.
902
903Definition or2 : MyBit -> MyBit -> MyBit := fun a : MyBit => fun b : MyBit =>
904 match a return (fun _ : MyBit => MyBit) with | Lo => b | Hi => Hi.
905
906-- XOR built from the primitive gates
907Definition xor2 : MyBit -> MyBit -> MyBit := fun a : MyBit => fun b : MyBit =>
908 or2 (and2 a (not1 b)) (and2 (not1 a) b).
909
910-- Try it: XOR truth table
911Eval xor2 Lo Hi.
912Eval xor2 Hi Hi.
913"#;
914
915const MATH_PROPERTY: &str = r#"-- Proven theorems become RUNNABLE Rust property checks.
916-- Define a function, prove a theorem about it, then hit Compile: the proof turns
917-- into a `check_*` function over the extracted code that the demo main runs.
918
919Inductive Num := Z : Num | S : Num -> Num.
920
921Definition add : Num -> Num -> Num := fix rec => fun n : Num => fun m : Num =>
922 match n return (fun _ : Num => Num) with | Z => m | S k => S (rec k m).
923
924Definition one : Num := S Z.
925
926-- A proven theorem: adding Z on the left is the identity (true by computation,
927-- so `refl` proves it). Compile → `fn check_add_zero_l(n) -> bool { add(Z, n) == n }`.
928Definition add_zero_l : (forall n : Num, Eq Num (add Z n) n) := fun n : Num => refl Num n.
929
930Eval add one one.
931"#;
932
933const MATH_COLLATZ: &str = r###"-- ============================================
934-- THE COLLATZ CONJECTURE (Literate Mode)
935-- ============================================
936-- The Collatz sequence: if n is even, n/2; if odd, 3n+1
937-- Conjecture: All positive integers eventually reach 1
938-- This is one of mathematics' most famous unsolved problems!
939--
940-- This example demonstrates the Literate Specification syntax:
941-- - "A X is either" for sum types (instead of Inductive)
942-- - "## To" for functions (instead of Definition)
943-- - "Consider/When/Yield" for pattern matching (instead of match)
944-- - Implicit recursion (no explicit "fix")
945
946-- ============================================
947-- TYPE DEFINITIONS
948-- ============================================
949
950-- A Decision represents a binary choice (Yes/No)
951-- Replaces: Inductive MyBool := Yes : MyBool | No : MyBool.
952A Decision is either Yes or No.
953
954-- ============================================
955-- BOOLEAN OPERATIONS
956-- ============================================
957
958-- Negate a decision: Yes becomes No, No becomes Yes
959## To negate (d: Decision) -> Decision:
960 Consider d:
961 When Yes: Yield No.
962 When No: Yield Yes.
963
964-- ============================================
965-- NATURAL NUMBERS (using kernel's Nat)
966-- ============================================
967
968-- Addition: add two natural numbers
969-- Note: Recursion is implicit - we just call "add" in the body
970## To add (n: Nat) and (m: Nat) -> Nat:
971 Consider n:
972 When Zero: Yield m.
973 When Succ k: Yield Succ (add(k, m)).
974
975-- ============================================
976-- PARITY CHECKS
977-- ============================================
978
979-- Check if a number is even (Yes) or odd (No)
980-- isEven(0) = Yes, isEven(n+1) = negate(isEven(n))
981## To check_parity (n: Nat) -> Decision:
982 Consider n:
983 When Zero: Yield Yes.
984 When Succ k: Yield negate(check_parity(k)).
985
986-- Check if a number is odd
987## To is_odd (n: Nat) -> Decision:
988 Yield negate(check_parity(n)).
989
990-- ============================================
991-- ARITHMETIC HELPERS
992-- ============================================
993
994-- Half: floor division by 2
995-- half(0) = 0
996-- half(n+1) = if odd(n) then 1+half(n) else half(n)
997## To halve (n: Nat) -> Nat:
998 Consider n:
999 When Zero: Yield Zero.
1000 When Succ k:
1001 Consider is_odd(k):
1002 When Yes: Yield Succ (halve(k)).
1003 When No: Yield halve(k).
1004
1005-- Double: 2n = n + n
1006## To double (n: Nat) -> Nat:
1007 Yield add(n, n).
1008
1009-- Triple: 3n = n + 2n
1010## To triple (n: Nat) -> Nat:
1011 Yield add(n, double(n)).
1012
1013-- Multiplication: n * m
1014-- Used for defining 6k + 4
1015## To mul (n: Nat) and (m: Nat) -> Nat:
1016 Consider n:
1017 When Zero: Yield Zero.
1018 When Succ k: Yield add(m, mul(k, m)).
1019
1020-- Useful constants
1021Definition four : Nat := Succ (Succ (Succ (Succ Zero))).
1022Definition five : Nat := Succ (four).
1023Definition six : Nat := Succ (five).
1024Definition sixteen : Nat := double (double four).
1025
1026-- ============================================
1027-- THE COLLATZ STEP
1028-- ============================================
1029
1030-- The Collatz step function:
1031-- if even: n/2
1032-- if odd: 3n+1
1033## To take_collatz_step (n: Nat) -> Nat:
1034 Consider check_parity(n):
1035 When Yes: Yield halve(n).
1036 When No: Yield Succ (triple(n)).
1037
1038-- ============================================
1039-- VERIFICATION
1040-- ============================================
1041
1042Check negate.
1043Check check_parity.
1044Check is_odd.
1045Check halve.
1046Check take_collatz_step.
1047
1048-- Test check_parity: 0=even, 1=odd, 2=even, 3=odd
1049Eval (check_parity Zero).
1050Eval (check_parity (Succ Zero)).
1051Eval (check_parity (Succ (Succ Zero))).
1052Eval (check_parity (Succ (Succ (Succ Zero)))).
1053
1054-- Test halve: halve(4) = 2
1055Eval (halve (Succ (Succ (Succ (Succ Zero))))).
1056
1057-- Test take_collatz_step
1058-- 2 -> 1 (even, so divide by 2)
1059Eval (take_collatz_step (Succ (Succ Zero))).
1060
1061-- 4 -> 2 (even, so divide by 2)
1062Eval (take_collatz_step (Succ (Succ (Succ (Succ Zero))))).
1063
1064-- ============================================
1065-- PART 2: THE LOGICAL ENGINE
1066-- ============================================
1067-- The step function above is the "computational engine" - it runs.
1068-- But to REASON about the Collatz conjecture, we need a "logical engine".
1069--
1070-- Why can't we just write a function that counts steps to 1?
1071-- Because the termination checker cannot verify it always halts!
1072-- The compiler would reject it - that's the "termination wall".
1073--
1074-- Instead, we define a PREDICATE: "n eventually reaches 1"
1075-- This describes the PROPERTY without requiring computation to terminate.
1076
1077-- ============================================
1078-- REACHABILITY PREDICATE
1079-- ============================================
1080-- A proof that 'n' reaches 1 is a tree:
1081-- - Done: n IS 1 (with equality proof)
1082-- - Step: if take_collatz_step(n) reaches 1, so does n
1083
1084Inductive ReachesOne (n : Nat) :=
1085 | Done : Eq Nat n (Succ Zero) -> ReachesOne n
1086 | Step : ReachesOne (take_collatz_step n) -> ReachesOne n.
1087
1088-- ============================================
1089-- CONCRETE PROOFS
1090-- ============================================
1091-- Let's prove specific numbers reach 1 by constructing proof trees.
1092-- This is "running" the conjecture in the type system!
1093
1094-- Proof that 1 reaches 1 (trivial base case)
1095-- Note: Constructors for parameterized inductives take the parameter first
1096Definition one_reaches : ReachesOne (Succ Zero) :=
1097 Done (Succ Zero) (refl Nat (Succ Zero)).
1098
1099-- Proof that 2 reaches 1
1100-- Chain: 2 -> 1 (since 2 is even, take_collatz_step(2) = halve(2) = 1)
1101Definition two_reaches : ReachesOne (Succ (Succ Zero)) :=
1102 Step (Succ (Succ Zero)) (Done (Succ Zero) (refl Nat (Succ Zero))).
1103
1104-- Proof that 4 reaches 1
1105-- Chain: 4 -> 2 -> 1
1106Definition four_reaches : ReachesOne (Succ (Succ (Succ (Succ Zero)))) :=
1107 Step (Succ (Succ (Succ (Succ Zero))))
1108 (Step (Succ (Succ Zero))
1109 (Done (Succ Zero) (refl Nat (Succ Zero)))).
1110
1111-- Proof that 8 reaches 1
1112-- Chain: 8 -> 4 -> 2 -> 1
1113Definition eight_reaches : ReachesOne (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))) :=
1114 Step (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero))))))))
1115 (Step (Succ (Succ (Succ (Succ Zero))))
1116 (Step (Succ (Succ Zero))
1117 (Done (Succ Zero) (refl Nat (Succ Zero))))).
1118
1119-- Verify the proofs type-check
1120Check one_reaches.
1121Check two_reaches.
1122Check four_reaches.
1123Check eight_reaches.
1124
1125-- ============================================
1126-- THE INVERSE COLLATZ TREE
1127-- ============================================
1128-- A different perspective: instead of proving numbers GO to 1,
1129-- prove numbers COME FROM 1 by reversing the rules.
1130--
1131-- From any n in the tree:
1132-- - 2n is always in the tree (reverse the "even" rule)
1133-- - (n-1)/3 is in the tree if it's a positive odd integer
1134--
1135-- This tree is well-founded, so we CAN do structural induction!
1136
1137Inductive InverseCollatz (n : Nat) :=
1138 | Root : Eq Nat n (Succ Zero) -> InverseCollatz n
1139 | FromDouble : InverseCollatz n -> InverseCollatz (double n)
1140 | FromTripleSucc : InverseCollatz (Succ (triple n)) -> InverseCollatz n.
1141
1142-- ============================================
1143-- STRUCTURAL THEOREMS
1144-- ============================================
1145-- We can prove general facts about the inverse tree.
1146
1147-- Theorem: 1 is in the inverse tree
1148Definition one_in_tree : InverseCollatz (Succ Zero) :=
1149 Root (Succ Zero) (refl Nat (Succ Zero)).
1150
1151-- Theorem: 2 is in the tree (since 2 = double 1)
1152Definition two_in_tree : InverseCollatz (Succ (Succ Zero)) :=
1153 FromDouble (Succ Zero) one_in_tree.
1154
1155-- Theorem: 4 is in the tree (since 4 = double 2)
1156Definition four_in_tree : InverseCollatz (Succ (Succ (Succ (Succ Zero)))) :=
1157 FromDouble (Succ (Succ Zero)) two_in_tree.
1158
1159-- Verify the tree membership proofs
1160Check one_in_tree.
1161Check two_in_tree.
1162Check four_in_tree.
1163
1164-- ============================================
1165-- THEOREM 1: All Powers of Two
1166-- ============================================
1167-- power_of_two computes 2^n: 2^0 = 1, 2^(n+1) = double(2^n)
1168
1169Definition power_of_two : Nat -> Nat :=
1170 fix rec => fun n : Nat =>
1171 match n return Nat with
1172 | Zero => Succ Zero
1173 | Succ k => double (rec k)
1174 end.
1175
1176-- Theorem: All 2^n are in the inverse tree (proof by induction on n)
1177-- Base: 2^0 = 1 is the Root
1178-- Step: If 2^k is in tree, then 2^(k+1) = double(2^k) is in tree via FromDouble
1179Definition all_powers_of_two : forall n : Nat, InverseCollatz (power_of_two n) :=
1180 fix proof => fun n : Nat =>
1181 match n return (fun k : Nat => InverseCollatz (power_of_two k)) with
1182 | Zero => Root (Succ Zero) (refl Nat (Succ Zero))
1183 | Succ k => FromDouble (power_of_two k) (proof k)
1184 end.
1185
1186Check power_of_two.
1187Check all_powers_of_two.
1188
1189-- Verify: power_of_two 3 = 8
1190Eval (power_of_two (Succ (Succ (Succ Zero)))).
1191
1192-- ============================================
1193-- THEOREM 2: Grandchild Growth
1194-- ============================================
1195-- If n is in the tree, then 4n = double(double(n)) is also in the tree
1196-- This shows the tree has "depth" - we can always extend further
1197
1198Definition grandchild_growth : forall n : Nat, InverseCollatz n -> InverseCollatz (double (double n)) :=
1199 fun n : Nat => fun pf : InverseCollatz n =>
1200 FromDouble (double n) (FromDouble n pf).
1201
1202Check grandchild_growth.
1203
1204-- ============================================
1205-- THEOREM 3: Odd Numbers via FromTripleSucc
1206-- ============================================
1207-- 5 is in the tree because 3*5+1 = 16 = 2^4 is in the tree
1208-- This demonstrates the "reverse odd step" rule
1209
1210-- 5 is in tree: FromTripleSucc requires InverseCollatz (Succ (triple 5))
1211-- triple 5 = 15, so Succ (triple 5) = 16 = 2^4
1212Definition five_in_tree : InverseCollatz five :=
1213 FromTripleSucc five (all_powers_of_two four).
1214
1215Check five_in_tree.
1216
1217-- ============================================
1218-- WHAT WE PROVED AND DIDN'T PROVE
1219-- ============================================
1220-- PROVED:
1221-- - Specific numbers (1, 2, 4, 8) reach 1 via ReachesOne
1222-- - All powers of 2 are in the inverse tree (all_powers_of_two)
1223-- - If n is in tree, so is 4n (grandchild_growth)
1224-- - 5 is in the tree via the FromTripleSucc rule (five_in_tree)
1225-- - The inverse tree contains infinitely many numbers
1226--
1227-- DID NOT PROVE:
1228-- - That ALL positive integers reach 1 (the full conjecture)
1229-- - That the inverse tree covers ALL positive integers
1230--
1231-- The full conjecture remains open in mathematics!
1232-- But this demonstrates how proof assistants let us
1233-- verify partial results with absolute certainty.
1234
1235-- ============================================
1236-- PART 3: TOPOLOGY OF THE INVERSE GRAPH
1237-- ============================================
1238-- The inverse Collatz graph has special "skeleton" structure.
1239-- "Skeleton nodes" (junctions) are nodes of the form 6k + 4.
1240-- These are the ONLY nodes that can spawn odd children!
1241--
1242-- Key insight: For (n-1)/3 to be a positive odd integer,
1243-- we need n = 6k + 4 for some k.
1244
1245-- ============================================
1246-- SKELETON PREDICATE
1247-- ============================================
1248-- n is a skeleton node if n = 6k + 4 for some k
1249
1250Inductive IsSkeleton (n : Nat) :=
1251 | Witness : forall k : Nat, Eq Nat n (add (mul six k) four) -> IsSkeleton n.
1252
1253-- ============================================
1254-- ODDNESS PREDICATE
1255-- ============================================
1256-- n is odd if n = 2k + 1 for some k
1257
1258Inductive IsOdd (n : Nat) :=
1259 | OddWitness : forall k : Nat, Eq Nat n (Succ (double k)) -> IsOdd n.
1260
1261Check IsSkeleton.
1262Check IsOdd.
1263
1264-- ============================================
1265-- CONCRETE SKELETON EXAMPLES
1266-- ============================================
1267-- Demonstrate specific skeleton nodes: 4, 10, 16, 22...
1268-- These are the nodes of the form 6k + 4.
1269
1270-- 4 is skeleton: 4 = 6*0 + 4
1271Definition four_is_skeleton : IsSkeleton four :=
1272 Witness four Zero (refl Nat four).
1273
1274Check four_is_skeleton.
1275
1276-- 10 is skeleton: 10 = 6*1 + 4
1277-- First define 10
1278Definition ten : Nat := add six four.
1279
1280Definition ten_is_skeleton : IsSkeleton ten :=
1281 Witness ten (Succ Zero) (refl Nat ten).
1282
1283Check ten_is_skeleton.
1284
1285-- ============================================
1286-- CONCRETE ODD EXAMPLES
1287-- ============================================
1288-- Demonstrate specific odd numbers and their skeleton mappings.
1289
1290-- 1 is odd: 1 = 2*0 + 1
1291Definition one_is_odd : IsOdd (Succ Zero) :=
1292 OddWitness (Succ Zero) Zero (refl Nat (Succ Zero)).
1293
1294Check one_is_odd.
1295
1296-- 3 is odd: 3 = 2*1 + 1
1297Definition three : Nat := Succ (Succ (Succ Zero)).
1298Definition three_is_odd : IsOdd three :=
1299 OddWitness three (Succ Zero) (refl Nat three).
1300
1301Check three_is_odd.
1302
1303-- ============================================
1304-- SKELETON REDUCTION EXAMPLES
1305-- ============================================
1306-- Verify that 3m+1 lands on skeleton nodes for specific odd m.
1307--
1308-- For m=1: 3*1+1 = 4 = 6*0 + 4 (skeleton!)
1309-- For m=3: 3*3+1 = 10 = 6*1 + 4 (skeleton!)
1310
1311-- Verify: take_collatz_step(1) = 4 (since 1 is odd)
1312Eval (take_collatz_step (Succ Zero)).
1313
1314-- Verify: take_collatz_step(3) = 10 (since 3 is odd)
1315Eval (take_collatz_step three).
1316
1317-- ============================================
1318-- THEOREM 5: GREEN HIGHWAY
1319-- ============================================
1320-- Powers of 4 provide an infinite highway of skeleton nodes.
1321--
1322-- Power of four function: 4^n
1323
1324Definition power_of_four : Nat -> Nat :=
1325 fix rec => fun n : Nat =>
1326 match n return Nat with
1327 | Zero => Succ Zero
1328 | Succ k => double (double (rec k))
1329 end.
1330
1331Check power_of_four.
1332
1333-- Verify computations
1334Eval (power_of_four Zero).
1335Eval (power_of_four (Succ Zero)).
1336Eval (power_of_four (Succ (Succ Zero))).
1337Eval (power_of_four (Succ (Succ (Succ Zero)))).
1338
1339-- Base case: 4^1 = 4 is skeleton (6*0 + 4)
1340Definition pow4_1_skeleton : IsSkeleton (power_of_four (Succ Zero)) :=
1341 Witness (power_of_four (Succ Zero)) Zero (refl Nat four).
1342
1343Check pow4_1_skeleton.
1344
1345-- 4^2 = 16 is skeleton: 16 = 6*2 + 4
1346Definition two : Nat := Succ (Succ Zero).
1347Definition pow4_2_skeleton : IsSkeleton (power_of_four (Succ (Succ Zero))) :=
1348 Witness (power_of_four (Succ (Succ Zero))) two (refl Nat sixteen).
1349
1350Check pow4_2_skeleton.
1351
1352-- ============================================
1353-- PART 3 SUMMARY
1354-- ============================================
1355-- We have demonstrated the "Skeleton Network" topology:
1356-- 1. Skeleton nodes are defined by n = 6k + 4 for some k.
1357-- 2. Examples: 4, 10, 16, 22... are all skeleton nodes.
1358-- 3. Odd numbers map to skeleton nodes via 3m+1 (verified for m=1, m=3).
1359-- 4. The Green Highway (4^n) provides skeleton nodes: 4, 16, 64...
1360-- 5. To solve Collatz, we only need to check if the Skeleton is connected.
1361"###;
1362
1363pub const MATH_GODEL_LITERATE: &str = r###"-- ============================================
1368-- GÖDEL SENTENCE CONSTRUCTION (Literate Mode)
1369-- ============================================
1370-- Building the self-referential sentence G that says "I am not provable"
1371--
1372-- This example demonstrates the fully Literate meta-logic syntax:
1373-- - "## To be Predicate" for predicate definitions
1374-- - "Let X be Y" for constant definitions
1375-- - "the Name X" for syntax names (maps to SName)
1376-- - "Variable N" for syntax variables (maps to SVar)
1377-- - "Apply(f, x)" for syntax application (maps to SApp)
1378-- - "the diagonalization of T" for diagonal lemma
1379-- - "there exists a d: T such that P" for existential quantification
1380-- - "X equals Y" for equality propositions
1381
1382-- ============================================
1383-- 1. THE PROVABILITY PREDICATE
1384-- ============================================
1385-- "s is provable if there exists a derivation d that concludes s"
1386
1387## To be Provable (s: Syntax) -> Prop:
1388 Yield there exists a d: Derivation such that (concludes(d) equals s).
1389
1390-- ============================================
1391-- 2. THE TEMPLATE T
1392-- ============================================
1393-- T encodes "Not(Provable(x))" as syntax
1394
1395Let Not_Name be the Name "Not".
1396Let Provable_Name be the Name "Provable".
1397Let T be Apply(Not_Name, Apply(Provable_Name, Variable 0)).
1398
1399-- ============================================
1400-- 3. THE GÖDEL SENTENCE G
1401-- ============================================
1402-- G = T[code(T)/x] via the diagonal lemma
1403-- G says "I am not provable"
1404
1405Let G be the diagonalization of T.
1406
1407-- ============================================
1408-- VERIFICATION
1409-- ============================================
1410
1411Check Provable.
1412Check T.
1413Check G.
1414Check Provable(G).
1415"###;
1416
1417pub const MATH_INCOMPLETENESS_LITERATE: &str = r###"-- ============================================
1418-- GÖDEL'S FIRST INCOMPLETENESS THEOREM (Literate Mode)
1419-- ============================================
1420-- "If LOGOS is consistent, then G is not provable"
1421--
1422-- This example demonstrates fully Literate syntax:
1423-- - "## To be Predicate" for predicate definitions
1424-- - "## To be Consistent -> Prop:" for nullary predicates
1425-- - "## Theorem:" blocks with "Statement:"
1426-- - "X implies Y" for logical implication
1427-- - "X equals Y" for equality propositions
1428
1429-- ============================================
1430-- 1. THE PROVABILITY PREDICATE
1431-- ============================================
1432
1433## To be Provable (s: Syntax) -> Prop:
1434 Yield there exists a d: Derivation such that (concludes(d) equals s).
1435
1436-- ============================================
1437-- 2. CONSISTENCY DEFINITION
1438-- ============================================
1439-- A system is consistent if it cannot prove False
1440
1441Let False_Name be the Name "False".
1442
1443## To be Consistent -> Prop:
1444 Yield Not(Provable(False_Name)).
1445
1446-- ============================================
1447-- 3. THE GÖDEL SENTENCES
1448-- ============================================
1449
1450Let T be Apply(the Name "Not", Apply(the Name "Provable", Variable 0)).
1451Let G be the diagonalization of T.
1452
1453-- ============================================
1454-- 4. THE THEOREM STATEMENT
1455-- ============================================
1456
1457## Theorem: Godel_First_Incompleteness
1458 Statement: Consistent implies Not(Provable(G)).
1459
1460-- ============================================
1461-- VERIFICATION
1462-- ============================================
1463
1464Check Godel_First_Incompleteness.
1465Check Consistent.
1466Check Provable(G).
1467Check Not(Provable(G)).
1468"###;
1469
1470const MATH_RING: &str = r###"-- ============================================
1471-- RING TACTIC: Polynomial Equality by Normalization
1472-- ============================================
1473-- The ring tactic proves polynomial equalities automatically!
1474-- It works by normalizing both sides to canonical polynomial form
1475-- and checking if they're structurally equal.
1476--
1477-- Supported operations: add, sub, mul (no division)
1478-- This is a decision procedure - it either proves the equality or fails.
1479
1480-- ============================================
1481-- BASIC SETUP
1482-- ============================================
1483
1484-- Type annotation (for the Eq constructor)
1485Definition T : Syntax := SName "Int".
1486
1487-- Variables using de Bruijn indices
1488Definition x : Syntax := SVar 0.
1489Definition y : Syntax := SVar 1.
1490Definition z : Syntax := SVar 2.
1491
1492-- ============================================
1493-- EXAMPLE 1: REFLEXIVITY (x = x)
1494-- ============================================
1495
1496Definition refl_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) x) x.
1497Definition refl_proof : Derivation := try_ring refl_goal.
1498Definition refl_result : Syntax := concludes refl_proof.
1499
1500Check refl_proof.
1501Eval refl_result.
1502
1503-- ============================================
1504-- EXAMPLE 2: COMMUTATIVITY OF ADDITION (x + y = y + x)
1505-- ============================================
1506
1507Definition add_xy : Syntax := SApp (SApp (SName "add") x) y.
1508Definition add_yx : Syntax := SApp (SApp (SName "add") y) x.
1509Definition comm_add_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) add_xy) add_yx.
1510
1511-- The ring tactic proves this automatically!
1512Definition comm_add_proof : Derivation := try_ring comm_add_goal.
1513Definition comm_add_result : Syntax := concludes comm_add_proof.
1514
1515Check comm_add_proof.
1516Eval comm_add_result.
1517
1518-- ============================================
1519-- EXAMPLE 3: COMMUTATIVITY OF MULTIPLICATION (x * y = y * x)
1520-- ============================================
1521
1522Definition mul_xy : Syntax := SApp (SApp (SName "mul") x) y.
1523Definition mul_yx : Syntax := SApp (SApp (SName "mul") y) x.
1524Definition comm_mul_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) mul_xy) mul_yx.
1525
1526Definition comm_mul_proof : Derivation := try_ring comm_mul_goal.
1527Definition comm_mul_result : Syntax := concludes comm_mul_proof.
1528
1529Check comm_mul_proof.
1530Eval comm_mul_result.
1531
1532-- ============================================
1533-- EXAMPLE 4: DISTRIBUTIVITY (x * (y + z) = x*y + x*z)
1534-- ============================================
1535
1536-- LHS: x * (y + z)
1537Definition y_plus_z : Syntax := SApp (SApp (SName "add") y) z.
1538Definition dist_lhs : Syntax := SApp (SApp (SName "mul") x) y_plus_z.
1539
1540-- RHS: x*y + x*z
1541Definition x_times_y : Syntax := SApp (SApp (SName "mul") x) y.
1542Definition x_times_z : Syntax := SApp (SApp (SName "mul") x) z.
1543Definition dist_rhs : Syntax := SApp (SApp (SName "add") x_times_y) x_times_z.
1544
1545Definition dist_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) dist_lhs) dist_rhs.
1546
1547Definition dist_proof : Derivation := try_ring dist_goal.
1548Definition dist_result : Syntax := concludes dist_proof.
1549
1550Check dist_proof.
1551Eval dist_result.
1552
1553-- ============================================
1554-- EXAMPLE 5: THE COLLATZ ALGEBRA STEP
1555-- ============================================
1556-- The key algebraic identity in Collatz analysis:
1557-- 3(2k+1) + 1 = 6k + 4
1558--
1559-- This proves that applying the Collatz odd step (3n+1)
1560-- to an odd number of the form 2k+1 yields 6k+4.
1561
1562Definition k : Syntax := SVar 0.
1563
1564-- Build LHS: 3 * (2*k + 1) + 1
1565Definition two_k : Syntax := SApp (SApp (SName "mul") (SLit 2)) k.
1566Definition two_k_plus_1 : Syntax := SApp (SApp (SName "add") two_k) (SLit 1).
1567Definition three_times : Syntax := SApp (SApp (SName "mul") (SLit 3)) two_k_plus_1.
1568Definition collatz_lhs : Syntax := SApp (SApp (SName "add") three_times) (SLit 1).
1569
1570-- Build RHS: 6*k + 4
1571Definition six_k : Syntax := SApp (SApp (SName "mul") (SLit 6)) k.
1572Definition collatz_rhs : Syntax := SApp (SApp (SName "add") six_k) (SLit 4).
1573
1574-- The equality goal
1575Definition collatz_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) collatz_lhs) collatz_rhs.
1576
1577-- Ring proves it!
1578Definition collatz_proof : Derivation := try_ring collatz_goal.
1579Definition collatz_result : Syntax := concludes collatz_proof.
1580
1581Check collatz_proof.
1582Eval collatz_result.
1583
1584-- ============================================
1585-- EXAMPLE 6: ASSOCIATIVITY ((x + y) + z = x + (y + z))
1586-- ============================================
1587
1588Definition xy_plus_z : Syntax := SApp (SApp (SName "add") (SApp (SApp (SName "add") x) y)) z.
1589Definition x_plus_yz : Syntax := SApp (SApp (SName "add") x) (SApp (SApp (SName "add") y) z).
1590Definition assoc_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) xy_plus_z) x_plus_yz.
1591
1592Definition assoc_proof : Derivation := try_ring assoc_goal.
1593Definition assoc_result : Syntax := concludes assoc_proof.
1594
1595Check assoc_proof.
1596Eval assoc_result.
1597
1598-- ============================================
1599-- EXAMPLE 7: SUBTRACTION CANCELLATION (x - x = 0)
1600-- ============================================
1601
1602Definition x_minus_x : Syntax := SApp (SApp (SName "sub") x) x.
1603Definition zero_lit : Syntax := SLit 0.
1604Definition cancel_goal : Syntax := SApp (SApp (SApp (SName "Eq") T) x_minus_x) zero_lit.
1605
1606Definition cancel_proof : Derivation := try_ring cancel_goal.
1607Definition cancel_result : Syntax := concludes cancel_proof.
1608
1609Check cancel_proof.
1610Eval cancel_result.
1611
1612-- ============================================
1613-- SUMMARY
1614-- ============================================
1615-- The ring tactic is a decision procedure for polynomial ring equalities.
1616-- It handles: constants, variables, addition, subtraction, multiplication.
1617-- It does NOT handle: division, modulo, or non-polynomial operations.
1618--
1619-- Key insight: Both sides are normalized to a canonical polynomial form
1620-- (sum of monomials with sorted variable indices), and compared structurally.
1621-- If they match, the equality is provable. If not, it fails.
1622"###;
1623
1624const MATH_LIA: &str = r###"-- ============================================
1625-- LIA TACTIC: Linear Integer Arithmetic
1626-- ============================================
1627-- The lia tactic proves linear inequalities automatically!
1628-- It uses Fourier-Motzkin elimination to decide validity.
1629--
1630-- Supported: Lt (<), Le (<=), Gt (>), Ge (>=)
1631-- Expressions must be LINEAR: constants, variables, c*x (no x*y)
1632
1633-- ============================================
1634-- BASIC SETUP
1635-- ============================================
1636
1637-- Variables using de Bruijn indices
1638Definition x : Syntax := SVar 0.
1639Definition y : Syntax := SVar 1.
1640Definition z : Syntax := SVar 2.
1641
1642-- ============================================
1643-- EXAMPLE 1: REFLEXIVITY (x <= x)
1644-- ============================================
1645
1646Definition le_refl_goal : Syntax := SApp (SApp (SName "Le") x) x.
1647Definition le_refl_proof : Derivation := try_lia le_refl_goal.
1648Definition le_refl_result : Syntax := concludes le_refl_proof.
1649
1650Check le_refl_proof.
1651Eval le_refl_result.
1652
1653-- ============================================
1654-- EXAMPLE 2: CONSTANT INEQUALITY (2 < 5)
1655-- ============================================
1656
1657Definition const_lt_goal : Syntax := SApp (SApp (SName "Lt") (SLit 2)) (SLit 5).
1658Definition const_lt_proof : Derivation := try_lia const_lt_goal.
1659Definition const_lt_result : Syntax := concludes const_lt_proof.
1660
1661Check const_lt_proof.
1662Eval const_lt_result.
1663
1664-- ============================================
1665-- EXAMPLE 3: SUCCESSOR (x < x + 1)
1666-- ============================================
1667
1668Definition x_plus_1 : Syntax := SApp (SApp (SName "add") x) (SLit 1).
1669Definition succ_goal : Syntax := SApp (SApp (SName "Lt") x) x_plus_1.
1670Definition succ_proof : Derivation := try_lia succ_goal.
1671Definition succ_result : Syntax := concludes succ_proof.
1672
1673Check succ_proof.
1674Eval succ_result.
1675
1676-- ============================================
1677-- EXAMPLE 4: LINEAR COEFFICIENT (2*x <= 2*x)
1678-- ============================================
1679
1680Definition two_x : Syntax := SApp (SApp (SName "mul") (SLit 2)) x.
1681Definition linear_goal : Syntax := SApp (SApp (SName "Le") two_x) two_x.
1682Definition linear_proof : Derivation := try_lia linear_goal.
1683Definition linear_result : Syntax := concludes linear_proof.
1684
1685Check linear_proof.
1686Eval linear_result.
1687
1688-- ============================================
1689-- EXAMPLE 5: PREDECESSOR (x - 1 < x)
1690-- ============================================
1691
1692Definition x_minus_1 : Syntax := SApp (SApp (SName "sub") x) (SLit 1).
1693Definition pred_goal : Syntax := SApp (SApp (SName "Lt") x_minus_1) x.
1694Definition pred_proof : Derivation := try_lia pred_goal.
1695Definition pred_result : Syntax := concludes pred_proof.
1696
1697Check pred_proof.
1698Eval pred_result.
1699
1700-- ============================================
1701-- EXAMPLE 6: EQUALITY BOUND (5 <= 5)
1702-- ============================================
1703
1704Definition eq_bound_goal : Syntax := SApp (SApp (SName "Le") (SLit 5)) (SLit 5).
1705Definition eq_bound_proof : Derivation := try_lia eq_bound_goal.
1706Definition eq_bound_result : Syntax := concludes eq_bound_proof.
1707
1708Check eq_bound_proof.
1709Eval eq_bound_result.
1710
1711-- ============================================
1712-- SUMMARY
1713-- ============================================
1714-- The lia tactic is a decision procedure for linear integer arithmetic.
1715-- It handles: constants, variables, addition, subtraction, c*x multiplication.
1716-- It does NOT handle: variable * variable (nonlinear), division, modulo.
1717--
1718-- Key insight: Fourier-Motzkin elimination projects out variables one by one,
1719-- combining lower and upper bounds until only constant constraints remain.
1720-- If these are contradictory, the negation is unsatisfiable, proving the goal.
1721"###;
1722
1723const CODE_BASICS_VARIABLES: &str = r#"# Variables and Types
1728-- Guide Section 3: All primitive types
1729
1730## Main
1731
1732Let name be "Alice".
1733Let age be 25.
1734Let is_active be true.
1735Let price be 19.99.
1736
1737Show "Name: " + name.
1738Show "Age: " + age.
1739Show "Active: " + is_active.
1740Show "Price: " + price.
1741
1742Let count be 100.
1743Let doubled be count * 2.
1744Show "Doubled: " + doubled.
1745"#;
1746
1747const CODE_BASICS_OPERATORS: &str = r#"# Operators and Expressions
1748-- Guide Section 4: Arithmetic, comparisons, logical
1749
1750## Main
1751
1752Let a be 10.
1753Let b be 3.
1754
1755Show "Arithmetic:".
1756Show "a + b = " + (a + b).
1757Show "a - b = " + (a - b).
1758Show "a * b = " + (a * b).
1759Show "a / b = " + (a / b).
1760Show "a % b = " + (a % b).
1761
1762Show "Comparisons:".
1763Show "a > b?".
1764Show a is greater than b.
1765Show "a equals 10?".
1766Show a equals 10.
1767Show "a >= 5?".
1768Show a is at least 5.
1769
1770Show "Logical:".
1771Let x be true.
1772Let y be false.
1773Show "x and y:".
1774Show x and y.
1775Show "x or y:".
1776Show x or y.
1777Show "not x:".
1778Show not x.
1779"#;
1780
1781const CODE_BASICS_CONTROL_FLOW: &str = r#"# Control Flow
1782-- Guide Section 5: If/Otherwise, While, For-each
1783
1784## Main
1785
1786Let score be 85.
1787
1788Show "Grading:".
1789If score is at least 90:
1790 Show "Grade: A".
1791If score is at least 80 and score is less than 90:
1792 Show "Grade: B".
1793If score is less than 80:
1794 Show "Grade: C or below".
1795
1796Show "While loop:".
1797Let count be 1.
1798While count is at most 3:
1799 Show count.
1800 Set count to count + 1.
1801
1802Show "For-each loop:".
1803Let items be [10, 20, 30].
1804Repeat for n in items:
1805 Show n.
1806"#;
1807
1808const CODE_ENUMS_PATTERNS: &str = r#"# Enums and Pattern Matching
1813-- Guide Section 8: Full pattern matching demonstration
1814
1815## A Status is one of:
1816 A Pending.
1817 A Active.
1818 A Completed.
1819 A Failed.
1820
1821## Main
1822
1823Let s be a new Active.
1824Show "Current status:".
1825Inspect s:
1826 When Pending: Show "Waiting to start".
1827 When Active: Show "In progress".
1828 When Completed: Show "Done!".
1829 When Failed: Show "Error occurred".
1830
1831Let s2 be a new Completed.
1832Inspect s2:
1833 When Active: Show "still working".
1834 Otherwise: Show "not active".
1835"#;
1836
1837const CODE_OWNERSHIP: &str = r#"# Memory and Ownership
1842-- Guide Section 10: Give, Show, copy of
1843
1844## To display (data: Text):
1845 Show "Viewing: " + data.
1846
1847## To consume (data: Text):
1848 Show "Consumed: " + data.
1849
1850## Main
1851
1852Let profile be "User Profile Data".
1853
1854Show profile to display.
1855Show "Still have profile: " + profile.
1856
1857Let duplicate be copy of profile.
1858Give duplicate to consume.
1859
1860Show "Original intact: " + profile.
1861"#;
1862
1863const CODE_CONCURRENCY_PARALLEL: &str = r#"# Concurrency
1868-- Guide Section 12: Simultaneously and Attempt all
1869-- These work in the browser!
1870
1871## Main
1872
1873Show "Parallel computation:".
1874Simultaneously:
1875 Let a be 100.
1876 Let b be 200.
1877
1878Show "a = " + a.
1879Show "b = " + b.
1880Show "Product: " + (a * b).
1881
1882Show "Async concurrent:".
1883Attempt all of the following:
1884 Let x be 10.
1885 Let y be 20.
1886
1887Show "Sum: " + (x + y).
1888"#;
1889
1890pub const CODE_CRDT_TALLY: &str = r#"# Tally (Bidirectional Counter)
1895-- Guide Section 13: PN-Counter that can increase and decrease
1896
1897## Definition
1898A Score is Shared and has:
1899 points: Tally.
1900
1901## Main
1902Let mutable s be a new Score.
1903Increase s's points by 100.
1904Show "After +100: " + s's points.
1905
1906Decrease s's points by 30.
1907Show "After -30: " + s's points.
1908
1909Increase s's points by 10.
1910Show "Final: " + s's points.
1911"#;
1912
1913const CODE_CRDT_MERGE: &str = r#"# CRDT Merge
1914-- Guide Section 13: Merging replicas
1915
1916## Definition
1917A Stats is Shared and has:
1918 views: ConvergentCount.
1919
1920## Main
1921Let local be a new Stats.
1922Increase local's views by 100.
1923Show "Local views: " + local's views.
1924
1925Let remote be a new Stats.
1926Increase remote's views by 50.
1927Show "Remote views: " + remote's views.
1928
1929Merge remote into local.
1930Show "After merge: " + local's views.
1931"#;
1932
1933const CODE_NETWORK_SERVER: &str = r#"# P2P Server
1938-- Guide Section 15: Listen and mDNS discovery
1939-- NOTE: Compiled programs only (not browser)
1940
1941## Definition
1942A Message is Portable and has:
1943 content: Text.
1944
1945## Main
1946
1947Listen on "/ip4/0.0.0.0/tcp/8000".
1948Show "Server listening on port 8000".
1949Show "mDNS will auto-discover local peers".
1950"#;
1951
1952const CODE_NETWORK_CLIENT: &str = r#"# P2P Client
1953-- Guide Section 15: Connect, PeerAgent, Send
1954-- NOTE: Compiled programs only (not browser)
1955
1956## Definition
1957A Greeting is Portable and has:
1958 message: Text.
1959
1960## Main
1961
1962Let server be "/ip4/127.0.0.1/tcp/8000".
1963Connect to server.
1964Show "Connected!".
1965
1966Let remote be a PeerAgent at server.
1967Let msg be a new Greeting with message "Hello, peer!".
1968Send msg to remote.
1969Show "Message sent".
1970"#;
1971
1972const CODE_ERROR_HANDLING: &str = r#"# Error Handling
1977-- Guide Section 16: Defensive programming patterns
1978
1979## To safe_divide (a: Int) and (b: Int) -> Int:
1980 If b equals 0:
1981 Show "Error: Cannot divide by zero".
1982 Return 0.
1983 Return a / b.
1984
1985## To validate_age (age: Int) -> Bool:
1986 If age is less than 0:
1987 Show "Error: Age cannot be negative".
1988 Return false.
1989 If age is greater than 150:
1990 Show "Error: Age seems unrealistic".
1991 Return false.
1992 Return true.
1993
1994## Main
1995
1996Show "Safe division:".
1997Show "10 / 2 = " + safe_divide(10, 2).
1998Show "5 / 0 = " + safe_divide(5, 0).
1999
2000Show "Age validation:".
2001Show "Age 25 valid: " + validate_age(25).
2002Show "Age -5 valid: " + validate_age(-5).
2003Show "Age 200 valid: " + validate_age(200).
2004"#;
2005
2006const CODE_ADVANCED_REFINEMENT: &str = r#"# Refinement Types
2011-- Guide Section 17: Types with constraints
2012
2013## Main
2014
2015Let positive: Int where it > 0 be 5.
2016Let percentage: Int where it >= 0 and it <= 100 be 85.
2017
2018Show "Positive value: " + positive.
2019Show "Percentage: " + percentage.
2020
2021Let bounded: Int where it >= 1 and it <= 10 be 7.
2022Show "Bounded (1-10): " + bounded.
2023"#;
2024
2025const CODE_ADVANCED_ASSERTIONS: &str = r#"# Assertions and Trust
2026-- Guide Sections 17, 22: Assert and Trust statements
2027
2028## To withdraw (amount: Int) from (balance: Int) -> Int:
2029 Assert that amount is greater than 0.
2030 Assert that amount is at most balance.
2031 Return balance - amount.
2032
2033## To process (n: Int) -> Int:
2034 Trust that n is greater than 0 because "caller guarantees positive input".
2035 Return n * 2.
2036
2037## Main
2038
2039Show "Withdrawal:".
2040Let result be withdraw(50, 100).
2041Show "Withdrew 50 from 100: " + result.
2042
2043Show "Process with trust:".
2044Let doubled be process(5).
2045Show "5 doubled: " + doubled.
2046"#;
2047
2048const CODE_TEMPORAL: &str = r#"## Main
2053
2054Show "=== Duration Literals (SI Units) ===".
2055Let nano be 50ns.
2056Show nano.
2057
2058Let micro be 100us.
2059Show micro.
2060
2061Let milli be 500ms.
2062Show milli.
2063
2064Let sec be 1s.
2065Show sec.
2066
2067Show "".
2068Show "=== Sleep with Duration Variables ===".
2069
2070Let short_pause be 200ms.
2071Let medium_pause be 500ms.
2072
2073Show "Starting...".
2074Sleep short_pause.
2075Show "After 200ms pause".
2076Sleep medium_pause.
2077Show "After 500ms pause".
2078Sleep short_pause.
2079Show "Done with variable sleeps!".
2080
2081Show "".
2082Show "=== Duration Math ===".
2083Let a be 500ms.
2084Let b be 500ms.
2085Let total be a + b.
2086Show "500ms + 500ms =".
2087Show total.
2088
2089Let fast be 100ms.
2090Let doubled be fast + fast.
2091Show "100ms doubled =".
2092Show doubled.
2093
2094Show "".
2095Show "=== Duration Comparisons ===".
2096Let quick be 100ms.
2097Let slow be 1s.
2098
2099If quick < slow:
2100 Show "100ms is less than 1s".
2101
2102If slow > quick:
2103 Show "1s is greater than 100ms".
2104
2105Show "".
2106Show "=== Date Literals ===".
2107Let graduation be 2026-05-20.
2108Show graduation.
2109
2110Let epoch be 1970-01-01.
2111Show epoch.
2112
2113Let new_year be 2026-01-01.
2114Show new_year.
2115
2116Show "".
2117Show "=== Date Comparisons ===".
2118If graduation > epoch:
2119 Show "Graduation is after the Unix epoch".
2120
2121If new_year < graduation:
2122 Show "New Year comes before graduation".
2123
2124Show "".
2125Show "=== Calendar Spans ===".
2126Let vacation be 2 weeks.
2127Show vacation.
2128
2129Let project be 3 months.
2130Show project.
2131
2132Let sprint be 2 weeks and 3 days.
2133Show sprint.
2134
2135Let long_project be 1 year and 2 months and 5 days.
2136Show long_project.
2137
2138Show "".
2139Show "=== Today Builtin ===".
2140Let current_date be today.
2141Show "Today's date:".
2142Show current_date.
2143
2144Show "".
2145Show "=== Date + Span Arithmetic ===".
2146Let start be 2026-01-15.
2147Let deadline be start + 2 months.
2148Show "Start + 2 months =".
2149Show deadline.
2150
2151Let exam be 2026-05-20.
2152Let reminder be exam - 3 days.
2153Show "Exam - 3 days =".
2154Show reminder.
2155
2156Let project_start be 2026-01-10.
2157Let project_end be project_start + 1 month and 5 days.
2158Show "Project end:".
2159Show project_end.
2160
2161Show "".
2162Show "=== Time-of-Day Literals ===".
2163Let morning be 9am.
2164Show morning.
2165
2166Let afternoon be 4pm.
2167Show afternoon.
2168
2169Let lunch be noon.
2170Show lunch.
2171
2172Let late_night be midnight.
2173Show late_night.
2174
2175Let meeting_time be 9:30am.
2176Show meeting_time.
2177
2178Show "".
2179Show "=== Date + Time (Moments) ===".
2180Let meeting be 2026-05-20 at 4pm.
2181Show "Meeting moment:".
2182Show meeting.
2183
2184Let conference be 2026-03-15 at 9:30am.
2185Show "Conference:".
2186Show conference.
2187
2188Show "".
2189Show "=== Time Comparisons ===".
2190Let early be 9am.
2191Let late be 5pm.
2192
2193If early < late:
2194 Show "9am is before 5pm".
2195
2196If late > noon:
2197 Show "5pm is after noon".
2198
2199Show "".
2200Show "All temporal tests complete!".
2201"#;
2202
2203const MATH_CC: &str = r###"-- ============================================
2208-- CC TACTIC: Congruence Closure
2209-- ============================================
2210-- The cc tactic proves equalities over uninterpreted functions!
2211-- It uses the congruence rule: if a = b then f(a) = f(b)
2212--
2213-- Key insight: cc connects arithmetic proofs to function applications.
2214-- While ring proves "1 + 1 = 2", cc proves "f(1 + 1) = f(2)".
2215
2216-- ============================================
2217-- EXAMPLE 1: REFLEXIVITY (f(x) = f(x))
2218-- ============================================
2219-- Any term equals itself
2220
2221## Theorem: FxRefl
2222 Statement: (Eq (f x) (f x)).
2223 Proof: cc.
2224
2225Check FxRefl.
2226
2227-- ============================================
2228-- EXAMPLE 2: NESTED REFLEXIVITY (f(g(x)) = f(g(x)))
2229-- ============================================
2230
2231## Theorem: FgxRefl
2232 Statement: (Eq (f (g x)) (f (g x))).
2233 Proof: cc.
2234
2235Check FgxRefl.
2236
2237-- ============================================
2238-- EXAMPLE 3: CONGRUENCE (x = y → f(x) = f(y))
2239-- ============================================
2240-- The core congruence rule: equal arguments give equal results
2241
2242## Theorem: Congruence
2243 Statement: (implies (Eq x y) (Eq (f x) (f y))).
2244 Proof: cc.
2245
2246Check Congruence.
2247
2248-- ============================================
2249-- EXAMPLE 4: BINARY CONGRUENCE (a = b → add(a,c) = add(b,c))
2250-- ============================================
2251-- Congruence works for multi-argument functions too
2252
2253## Theorem: BinaryCongruence
2254 Statement: (implies (Eq a b) (Eq (add a c) (add b c))).
2255 Proof: cc.
2256
2257Check BinaryCongruence.
2258
2259-- ============================================
2260-- EXAMPLE 5: TRANSITIVITY CHAIN (a = b → b = c → f(a) = f(c))
2261-- ============================================
2262-- Multiple hypotheses combine via transitivity
2263
2264## Theorem: Transitivity
2265 Statement: (implies (Eq a b) (implies (Eq b c) (Eq (f a) (f c)))).
2266 Proof: cc.
2267
2268Check Transitivity.
2269
2270-- ============================================
2271-- SUMMARY
2272-- ============================================
2273-- The cc tactic proves equalities by:
2274-- 1. Building an E-graph from all subterms
2275-- 2. Merging equivalence classes from hypothesis equalities
2276-- 3. Propagating congruences: if a=b then f(a)=f(b)
2277-- 4. Checking if goal's LHS and RHS are equivalent
2278--
2279-- This completes the trinity of automated tactics:
2280-- - ring: polynomial equalities (normalization)
2281-- - lia: linear inequalities (Fourier-Motzkin)
2282-- - cc: function equalities (congruence closure)
2283"###;
2284
2285const MATH_SIMP: &str = r###"-- ============================================
2286-- SIMP TACTIC: Term Rewriting
2287-- ============================================
2288-- The simp tactic normalizes goals by applying rewrite rules!
2289-- It unfolds definitions and simplifies arithmetic.
2290--
2291-- Key insight: simp turns complex terms into canonical forms,
2292-- making equalities trivially checkable by reflexivity.
2293
2294-- ============================================
2295-- EXAMPLE 1: ARITHMETIC SIMPLIFICATION
2296-- ============================================
2297-- Constant expressions are evaluated
2298
2299## Theorem: TwoPlusThree
2300 Statement: (Eq (add 2 3) 5).
2301 Proof: simp.
2302
2303Check TwoPlusThree.
2304
2305## Theorem: Nested
2306 Statement: (Eq (mul (add 1 1) 3) 6).
2307 Proof: simp.
2308
2309Check Nested.
2310
2311## Theorem: TenMinusFour
2312 Statement: (Eq (sub 10 4) 6).
2313 Proof: simp.
2314
2315Check TenMinusFour.
2316
2317-- ============================================
2318-- EXAMPLE 2: DEFINITION UNFOLDING
2319-- ============================================
2320
2321## To double (n: Int) -> Int:
2322 Yield (add n n).
2323
2324## Theorem: DoubleTwo
2325 Statement: (Eq (double 2) 4).
2326 Proof: simp.
2327
2328Check DoubleTwo.
2329
2330## To quadruple (n: Int) -> Int:
2331 Yield (double (double n)).
2332
2333## Theorem: QuadTwo
2334 Statement: (Eq (quadruple 2) 8).
2335 Proof: simp.
2336
2337Check QuadTwo.
2338
2339## To zero_fn (n: Int) -> Int:
2340 Yield 0.
2341
2342## Theorem: ZeroFnTest
2343 Statement: (Eq (zero_fn 42) 0).
2344 Proof: simp.
2345
2346Check ZeroFnTest.
2347
2348-- ============================================
2349-- EXAMPLE 3: WITH HYPOTHESES
2350-- ============================================
2351-- simp uses equalities from hypotheses as rewrite rules
2352
2353## Theorem: SubstSimp
2354 Statement: (implies (Eq x 0) (Eq (add x 1) 1)).
2355 Proof: simp.
2356
2357Check SubstSimp.
2358
2359## Theorem: TwoHyps
2360 Statement: (implies (Eq x 1) (implies (Eq y 2) (Eq (add x y) 3))).
2361 Proof: simp.
2362
2363Check TwoHyps.
2364
2365-- ============================================
2366-- EXAMPLE 4: REFLEXIVE EQUALITIES
2367-- ============================================
2368-- simp handles reflexivity for free
2369
2370## Theorem: XEqX
2371 Statement: (Eq x x).
2372 Proof: simp.
2373
2374Check XEqX.
2375
2376## Theorem: FxRefl
2377 Statement: (Eq (f x) (f x)).
2378 Proof: simp.
2379
2380Check FxRefl.
2381
2382-- ============================================
2383-- SUMMARY
2384-- ============================================
2385-- The simp tactic:
2386-- 1. Collects rewrite rules from definitions and hypotheses
2387-- 2. Applies rules bottom-up to both sides of equality
2388-- 3. Evaluates arithmetic on constants
2389-- 4. Checks if simplified terms are equal
2390--
2391-- Combined with ring, lia, and cc, this completes the core
2392-- automated reasoning toolkit!
2393--
2394-- - ring: polynomial equalities (normalization)
2395-- - lia: linear inequalities (Fourier-Motzkin)
2396-- - cc: function equalities (congruence closure)
2397-- - simp: term rewriting (bottom-up simplification)
2398"###;
2399
2400const MATH_OMEGA: &str = r###"-- ============================================
2401-- OMEGA TACTIC: True Integer Arithmetic
2402-- ============================================
2403-- The omega tactic handles LINEAR INTEGER constraints!
2404-- Unlike lia (which uses rationals), omega knows that:
2405-- x > 1 means x >= 2 for integers
2406-- 2x = 3 has NO solution (3 is odd!)
2407--
2408-- This is essential for array bounds, loop indices,
2409-- and anything involving discrete counts.
2410
2411-- ============================================
2412-- BASIC INEQUALITIES (same as lia)
2413-- ============================================
2414
2415## Theorem: TwoLessThanFive
2416 Statement: (Lt 2 5).
2417 Proof: omega.
2418
2419Check TwoLessThanFive.
2420
2421## Theorem: XLessThanXPlusOne
2422 Statement: (Lt x (add x 1)).
2423 Proof: omega.
2424
2425Check XLessThanXPlusOne.
2426
2427## Theorem: XLeX
2428 Statement: (Le x x).
2429 Proof: omega.
2430
2431Check XLeX.
2432
2433-- ============================================
2434-- INTEGER-SPECIFIC REASONING
2435-- ============================================
2436-- These are IMPOSSIBLE with rational-based lia!
2437
2438## Theorem: StrictToNonStrict
2439 Statement: (implies (Gt x 0) (Ge x 1)).
2440 Proof: omega.
2441
2442Check StrictToNonStrict.
2443
2444-- x > 0 in rationals allows x = 0.001
2445-- x > 0 in integers means x >= 1
2446
2447## Theorem: LtConvertsToLe
2448 Statement: (implies (Lt x 5) (Le x 4)).
2449 Proof: omega.
2450
2451Check LtConvertsToLe.
2452
2453-- x < 5 in rationals allows x = 4.999
2454-- x < 5 in integers means x <= 4
2455
2456## Theorem: CoeffBound
2457 Statement: (implies (Le (mul 3 x) 10) (Le x 3)).
2458 Proof: omega.
2459
2460Check CoeffBound.
2461
2462-- 3x <= 10 means x <= floor(10/3) = 3
2463
2464## Theorem: TwoCoefficientBound
2465 Statement: (implies (Le (mul 2 x) 5) (Le x 2)).
2466 Proof: omega.
2467
2468Check TwoCoefficientBound.
2469
2470-- 2x <= 5 means x <= floor(5/2) = 2
2471
2472-- ============================================
2473-- TRANSITIVITY AND CHAINS
2474-- ============================================
2475
2476## Theorem: LtTrans
2477 Statement: (implies (Lt x y) (implies (Lt y z) (Lt x z))).
2478 Proof: omega.
2479
2480Check LtTrans.
2481
2482## Theorem: LeTrans
2483 Statement: (implies (Le x y) (implies (Le y z) (Le x z))).
2484 Proof: omega.
2485
2486Check LeTrans.
2487
2488-- ============================================
2489-- SUMMARY
2490-- ============================================
2491-- omega handles integer arithmetic properly:
2492-- 1. Strict-to-nonstrict conversion (x > n -> x >= n+1)
2493-- 2. Floor/ceil rounding in bounds
2494-- 3. Coefficient bounds with floor division
2495-- 4. Variable elimination via the Omega Test
2496--
2497-- Combined with ring, lia, cc, and simp, this completes
2498-- the core automated reasoning toolkit:
2499-- - ring: polynomial equalities (normalization)
2500-- - lia: linear rational inequalities (Fourier-Motzkin)
2501-- - cc: function equalities (congruence closure)
2502-- - simp: term rewriting (bottom-up simplification)
2503-- - omega: true integer arithmetic (Omega Test)
2504"###;
2505
2506pub const MATH_AUTO: &str = r###"-- ============================================
2507-- AUTO TACTIC: The Infinity Gauntlet
2508-- ============================================
2509-- The auto tactic combines ALL decision procedures!
2510-- It tries each one in sequence until one succeeds:
2511-- 1. True/False (trivial propositions)
2512-- 2. simp (simplification)
2513-- 3. ring (polynomial algebra)
2514-- 4. cc (congruence closure)
2515-- 5. omega (integer arithmetic)
2516-- 6. lia (linear arithmetic)
2517
2518-- ============================================
2519-- SIMPLIFICATION (auto -> simp)
2520-- ============================================
2521
2522## Theorem: TrueIsTrue
2523 Statement: True.
2524 Proof: auto.
2525
2526Check TrueIsTrue.
2527
2528-- ============================================
2529-- RING ALGEBRA (auto -> ring)
2530-- ============================================
2531
2532## Theorem: AddCommutative
2533 Statement: (Eq (add a b) (add b a)).
2534 Proof: auto.
2535
2536Check AddCommutative.
2537
2538## Theorem: AddAssociative
2539 Statement: (Eq (add (add a b) c) (add a (add b c))).
2540 Proof: auto.
2541
2542Check AddAssociative.
2543
2544## Theorem: MulDistributes
2545 Statement: (Eq (mul a (add b c)) (add (mul a b) (mul a c))).
2546 Proof: auto.
2547
2548Check MulDistributes.
2549
2550-- ============================================
2551-- CONGRUENCE CLOSURE (auto -> cc)
2552-- ============================================
2553
2554## Theorem: FunctionReflexive
2555 Statement: (Eq (f x) (f x)).
2556 Proof: auto.
2557
2558Check FunctionReflexive.
2559
2560-- ============================================
2561-- INTEGER ARITHMETIC (auto -> omega)
2562-- ============================================
2563
2564## Theorem: TwoLessThanFive
2565 Statement: (Lt 2 5).
2566 Proof: auto.
2567
2568Check TwoLessThanFive.
2569
2570## Theorem: StrictToNonStrict
2571 Statement: (implies (Gt x 0) (Ge x 1)).
2572 Proof: auto.
2573
2574Check StrictToNonStrict.
2575
2576## Theorem: XLessThanSucc
2577 Statement: (Lt x (add x 1)).
2578 Proof: auto.
2579
2580Check XLessThanSucc.
2581
2582-- ============================================
2583-- LINEAR ARITHMETIC (auto -> lia/omega)
2584-- ============================================
2585
2586## Theorem: LeReflexive
2587 Statement: (Le x x).
2588 Proof: auto.
2589
2590Check LeReflexive.
2591
2592## Theorem: LeTransitive
2593 Statement: (implies (Le x y) (implies (Le y z) (Le x z))).
2594 Proof: auto.
2595
2596Check LeTransitive.
2597
2598-- ============================================
2599-- THE POWER OF AUTO
2600-- ============================================
2601-- With auto, you don't need to think about
2602-- which tactic to use. Just say:
2603--
2604-- Proof: auto.
2605--
2606-- And the system figures it out!
2607--
2608-- auto combines ALL five stones:
2609-- - ring: polynomial equalities
2610-- - lia: linear rational arithmetic
2611-- - cc: congruence closure
2612-- - simp: simplification
2613-- - omega: true integer arithmetic
2614--
2615-- This is the Infinity Gauntlet of tactics!
2616"###;
2617
2618const MATH_INDUCTION: &str = r###"-- ============================================
2619-- INDUCTION TACTIC: The Time Machine
2620-- ============================================
2621-- Structural reasoning for inductive types.
2622-- Works for Nat, Bool, and any user-defined inductive.
2623--
2624-- The induction tactic automatically:
2625-- 1. Looks up constructors for the inductive type
2626-- 2. Generates one subgoal per constructor
2627-- 3. Provides induction hypotheses for recursive cases
2628
2629-- ============================================
2630-- KERNEL INFRASTRUCTURE
2631-- ============================================
2632-- These are the building blocks for induction.
2633
2634-- Check that induction helpers exist
2635Check try_induction.
2636Check induction_base_goal.
2637Check induction_step_goal.
2638Check induction_num_cases.
2639
2640-- ============================================
2641-- NAT INDUCTION EXAMPLES
2642-- ============================================
2643-- Nat has 2 constructors: Zero, Succ
2644
2645-- How many constructors does Nat have?
2646Definition nat_cases : Nat := induction_num_cases (SName "Nat").
2647Eval nat_cases.
2648
2649-- The motive: what we're proving (λn:Nat. Le n n)
2650Definition le_motive : Syntax := SLam (SName "Nat") (SApp (SApp (SName "Le") (SVar 0)) (SVar 0)).
2651
2652-- Base case goal: Le Zero Zero
2653Definition base_goal : Syntax := induction_base_goal (SName "Nat") le_motive.
2654Eval base_goal.
2655
2656-- Step case goal: ∀k. P(k) → P(Succ k)
2657Definition step_goal : Syntax := induction_step_goal (SName "Nat") le_motive (Succ Zero).
2658Eval step_goal.
2659
2660-- ============================================
2661-- BOOL INDUCTION
2662-- ============================================
2663-- Bool has 2 constructors: true, false
2664
2665-- How many constructors does Bool have?
2666Definition bool_cases : Nat := induction_num_cases (SName "Bool").
2667Eval bool_cases.
2668
2669-- Check the Bool type
2670Check Bool.
2671Check true.
2672Check false.
2673
2674-- ============================================
2675-- BUILDING A COMPLETE PROOF
2676-- ============================================
2677-- Let's build an induction proof manually using the kernel.
2678
2679-- Base case: Le Zero Zero (auto can solve this)
2680Definition base_proof : Derivation := try_auto (SApp (SApp (SName "Le") (SName "Zero")) (SName "Zero")).
2681Definition base_result : Syntax := concludes base_proof.
2682Eval base_result.
2683
2684-- Step case: use axiom for now (step needs IH)
2685Definition step_proof : Derivation := DAxiom step_goal.
2686
2687-- Combine into full induction proof
2688Definition full_proof : Derivation := try_induction (SName "Nat") le_motive (DCase base_proof (DCase step_proof DCaseEnd)).
2689Definition full_result : Syntax := concludes full_proof.
2690Eval full_result.
2691
2692-- ============================================
2693-- ERROR HANDLING
2694-- ============================================
2695-- Wrong number of cases should error
2696
2697Definition motive2 : Syntax := SLam (SName "Nat") (SName "True").
2698Definition single_case : Derivation := DAxiom (SName "True").
2699
2700-- Only 1 case for 2-constructor Nat = error
2701Definition bad_proof : Derivation := try_induction (SName "Nat") motive2 (DCase single_case DCaseEnd).
2702Definition bad_result : Syntax := concludes bad_proof.
2703Eval bad_result.
2704
2705-- ============================================
2706-- NON-INDUCTIVE TYPES
2707-- ============================================
2708-- Int is not an inductive type
2709
2710Definition int_cases : Nat := induction_num_cases (SName "Int").
2711Eval int_cases.
2712
2713-- ============================================
2714-- SUMMARY
2715-- ============================================
2716-- The induction infrastructure provides:
2717--
2718-- 1. induction_num_cases: Count constructors for a type
2719-- 2. induction_base_goal: Generate base case goal
2720-- 3. induction_step_goal: Generate step case goal
2721-- 4. try_induction: Build DElim from cases
2722--
2723-- This enables generic structural induction on:
2724-- - Nat (Zero, Succ)
2725-- - Bool (true, false)
2726-- - User-defined inductives
2727--
2728-- Bullet-point syntax in literate mode:
2729-- Proof:
2730-- induction n.
2731-- - auto. # Base case
2732-- - auto. # Step case
2733"###;
2734
2735const MATH_HINTS: &str = r###"-- ============================================
2736-- HINT DATABASE: Teaching Auto New Tricks
2737-- ============================================
2738-- Register theorems as hints so auto can use them!
2739--
2740-- The hint system allows you to:
2741-- 1. Prove a theorem once
2742-- 2. Register it with "Attribute: hint."
2743-- 3. Auto will try to use it when other tactics fail
2744
2745-- ============================================
2746-- BASIC HINT EXAMPLE
2747-- ============================================
2748
2749-- First, let's define a simple property
2750Definition trivial_true : Syntax := SName "True".
2751
2752-- Prove it (trivially)
2753Definition trivial_proof : Derivation := try_auto trivial_true.
2754
2755-- Verify the proof
2756Eval concludes trivial_proof.
2757
2758-- ============================================
2759-- HOW HINTS WORK
2760-- ============================================
2761-- When you write:
2762--
2763-- ## Theorem: my_lemma
2764-- Statement: <some_statement>
2765-- Proof: auto.
2766-- Attribute: hint.
2767--
2768-- The system:
2769-- 1. Proves the theorem
2770-- 2. Registers it in the hint database
2771-- 3. When auto runs later, it checks if any hint matches the goal
2772
2773-- ============================================
2774-- HINT-AWARE AUTO
2775-- ============================================
2776-- Auto tries tactics in this order:
2777-- 1. Trivial (True/False)
2778-- 2. simp (simplification)
2779-- 3. ring (polynomial arithmetic)
2780-- 4. cc (congruence closure)
2781-- 5. omega (integer arithmetic)
2782-- 6. lia (linear arithmetic)
2783-- 7. HINTS (registered theorems) <-- NEW!
2784
2785-- ============================================
2786-- LITERATE SYNTAX FOR HINTS
2787-- ============================================
2788-- In literate mode, you can write:
2789--
2790-- ## Theorem: plus_zero_right
2791-- Statement: For all (n: Nat), n + 0 = n.
2792-- Proof:
2793-- induction n.
2794-- - auto.
2795-- - auto.
2796-- Attribute: hint.
2797--
2798-- This registers plus_zero_right as a hint!
2799-- Now any proof with goal "n + 0 = n" can use auto.
2800
2801-- ============================================
2802-- CHECKING HINTS
2803-- ============================================
2804-- You can inspect the hint database via the context.
2805-- Hints are stored as theorem names.
2806
2807Check try_auto.
2808
2809-- ============================================
2810-- SUMMARY
2811-- ============================================
2812-- The hint system extends auto with learned knowledge:
2813--
2814-- 1. Prove theorems normally
2815-- 2. Add "Attribute: hint." to register them
2816-- 3. Auto will try hints when built-in tactics fail
2817--
2818-- This creates a virtuous cycle:
2819-- Prove lemmas → Register as hints → Prove harder theorems
2820"###;
2821
2822const MATH_INVERSION: &str = r###"-- ============================================
2823-- INVERSION: The Scalpel
2824-- ============================================
2825-- Derives contradictions by running constructors backwards.
2826--
2827-- If you claim something impossible (like Eq Nat 3 0),
2828-- inversion proves False by showing no constructor can build it.
2829
2830-- ============================================
2831-- KERNEL INFRASTRUCTURE
2832-- ============================================
2833-- These are the building blocks for inversion.
2834
2835-- Check that inversion helpers exist
2836Check try_inversion.
2837Check DInversion.
2838
2839-- ============================================
2840-- DISCRIMINATE: DIFFERENT CONSTRUCTORS
2841-- ============================================
2842-- The Eq type has only one constructor: refl
2843-- refl : Π(A:Type). Π(x:A). Eq A x x
2844--
2845-- refl requires BOTH arguments to be the same!
2846
2847-- Build hypothesis: Eq Nat 3 0 (impossible!)
2848Definition three : Syntax :=
2849 SApp (SName "Succ") (SApp (SName "Succ") (SApp (SName "Succ") (SName "Zero"))).
2850
2851Definition eq_three_zero : Syntax :=
2852 SApp (SApp (SApp (SName "Eq") (SName "Nat")) three) (SName "Zero").
2853
2854-- Try inversion: can refl build Eq Nat 3 0?
2855-- No! refl needs same args, but 3 ≠ 0
2856Definition discriminate_proof : Derivation := try_inversion eq_three_zero.
2857Definition discriminate_result : Syntax := concludes discriminate_proof.
2858Eval discriminate_result.
2859
2860-- ============================================
2861-- REFLEXIVE: CONSTRUCTOR CAN MATCH
2862-- ============================================
2863-- Eq Nat Zero Zero CAN be built by refl Zero
2864-- So inversion should NOT derive False (returns error)
2865
2866Definition eq_zero_zero : Syntax :=
2867 SApp (SApp (SApp (SName "Eq") (SName "Nat")) (SName "Zero")) (SName "Zero").
2868
2869Definition reflexive_proof : Derivation := try_inversion eq_zero_zero.
2870Definition reflexive_result : Syntax := concludes reflexive_proof.
2871Eval reflexive_result.
2872
2873-- ============================================
2874-- EMPTY INDUCTIVE: FALSE
2875-- ============================================
2876-- False has NO constructors at all.
2877-- Anything of type False is automatically contradictory.
2878
2879Definition false_hyp : Syntax := SName "False".
2880Definition false_proof : Derivation := try_inversion false_hyp.
2881Definition false_result : Syntax := concludes false_proof.
2882Eval false_result.
2883
2884-- ============================================
2885-- BOOL DISCRIMINATE: true ≠ false
2886-- ============================================
2887-- Eq Bool true false requires refl to make true = false
2888-- But true and false are different constructors!
2889
2890Definition eq_true_false : Syntax :=
2891 SApp (SApp (SApp (SName "Eq") (SName "Bool")) (SName "true")) (SName "false").
2892
2893Definition bool_proof : Derivation := try_inversion eq_true_false.
2894Definition bool_result : Syntax := concludes bool_proof.
2895Eval bool_result.
2896
2897-- ============================================
2898-- NON-INDUCTIVE: ERROR
2899-- ============================================
2900-- Inversion only works on inductive types.
2901-- Variables or unknown types produce errors.
2902
2903Definition var_hyp : Syntax := SVar 0.
2904Definition var_proof : Derivation := try_inversion var_hyp.
2905Definition var_result : Syntax := concludes var_proof.
2906Eval var_result.
2907
2908-- ============================================
2909-- SUMMARY
2910-- ============================================
2911-- The inversion tactic:
2912--
2913-- 1. Extracts the inductive type from the hypothesis
2914-- 2. Checks if ANY constructor could produce the given args
2915-- 3. If no constructor matches → proves False
2916-- 4. If some constructor matches → returns error
2917--
2918-- Key insight: Inversion is the INVERSE of introduction.
2919-- Introduction builds terms; inversion checks if building is possible.
2920--
2921-- Common uses:
2922-- - Discriminate different constructors (Eq 3 0 → False)
2923-- - Empty inductives (False → False)
2924-- - Proof by contradiction
2925"###;
2926
2927const MATH_OPERATOR: &str = r###"-- ============================================
2928-- THE OPERATOR: Manual Control Tactics
2929-- ============================================
2930-- When auto fails, you need precision tools.
2931--
2932-- rewrite - The Sniper: targeted substitution
2933-- destruct - The Fork: case analysis without IH
2934-- apply - The Arrow: backward chaining
2935
2936-- ============================================
2937-- KERNEL INFRASTRUCTURE
2938-- ============================================
2939
2940Check try_rewrite.
2941Check try_rewrite_rev.
2942Check try_destruct.
2943Check try_apply.
2944Check DRewrite.
2945Check DDestruct.
2946Check DApply.
2947
2948-- ============================================
2949-- REWRITE: The Sniper
2950-- ============================================
2951-- Given a proof of Eq A x y and a goal containing x,
2952-- rewrite replaces x with y (or vice versa with rewrite_rev).
2953--
2954-- Use case: When you have an equality lemma and need to
2955-- substitute one term for another.
2956
2957-- Example: Given Eq Nat x y, transform goal P(x) to P(y)
2958
2959-- Build equality hypothesis: Eq Nat (SVar 0) (SVar 1)
2960-- This represents "x = y" where x is var 0, y is var 1
2961Definition eq_type : Syntax :=
2962 SApp (SApp (SApp (SName "Eq") (SName "Nat")) (SVar 0)) (SVar 1).
2963
2964-- Create a proof of this equality (as axiom for demo)
2965Definition eq_proof : Derivation := DAxiom eq_type.
2966
2967-- Goal: P(x) = P(SVar 0)
2968Definition goal_px : Syntax := SApp (SName "P") (SVar 0).
2969
2970-- Rewrite: Replace x with y to get P(y)
2971Definition rewritten : Derivation := try_rewrite eq_proof goal_px.
2972Eval (concludes rewritten).
2973
2974-- Reverse rewrite: Given same equality, replace y with x
2975Definition goal_py : Syntax := SApp (SName "P") (SVar 1).
2976Definition rev_rewritten : Derivation := try_rewrite_rev eq_proof goal_py.
2977Eval (concludes rev_rewritten).
2978
2979-- ============================================
2980-- DESTRUCT: The Fork
2981-- ============================================
2982-- Case analysis WITHOUT induction hypotheses.
2983--
2984-- For Bool: generates true and false cases
2985-- For Nat: generates Zero case and "forall k. P(Succ k)"
2986-- NOT "forall k. P(k) -> P(Succ k)" (that's induction)
2987--
2988-- Use case: When you need to split on cases but don't need
2989-- the induction hypothesis (enums, finite types).
2990
2991-- Motive: λb:Bool. P(b)
2992Definition bool_motive : Syntax :=
2993 SLam (SName "Bool") (SApp (SName "P") (SVar 0)).
2994
2995-- Case proofs: P(true) and P(false) as axioms
2996Definition case_true : Derivation := DAxiom (SApp (SName "P") (SName "true")).
2997Definition case_false : Derivation := DAxiom (SApp (SName "P") (SName "false")).
2998
2999-- Build case list
3000Definition bool_cases : Derivation := DCase case_true (DCase case_false DCaseEnd).
3001
3002-- Destruct Bool
3003Definition bool_destruct : Derivation :=
3004 try_destruct (SName "Bool") bool_motive bool_cases.
3005Eval (concludes bool_destruct).
3006
3007-- ============================================
3008-- APPLY: The Arrow
3009-- ============================================
3010-- Manual backward chaining.
3011--
3012-- Given hypothesis H : P → Q and goal Q,
3013-- apply H transforms the goal to P.
3014--
3015-- Given hypothesis H : ∀x. P(x) and goal P(3),
3016-- apply H instantiates the forall.
3017--
3018-- Use case: When auto can't figure out which lemma to use.
3019
3020-- Implication example: H : P → Q, goal: Q
3021Definition impl_type : Syntax := SPi (SName "P") (SName "Q").
3022Definition impl_proof : Derivation := DAxiom impl_type.
3023Definition goal_q : Syntax := SName "Q".
3024
3025-- Apply H to goal Q → new goal P
3026Definition applied_impl : Derivation :=
3027 try_apply (SName "H") impl_proof goal_q.
3028Eval (concludes applied_impl).
3029
3030-- Forall example: H : ∀x:Nat. P(x), goal: P(3)
3031Definition forall_type : Syntax :=
3032 SApp (SName "Forall")
3033 (SLam (SName "Nat") (SApp (SName "P") (SVar 0))).
3034
3035Definition forall_proof : Derivation := DAxiom forall_type.
3036
3037Definition three : Syntax :=
3038 SApp (SName "Succ") (SApp (SName "Succ") (SApp (SName "Succ") (SName "Zero"))).
3039
3040Definition goal_p3 : Syntax := SApp (SName "P") three.
3041
3042-- Apply forall to goal P(3)
3043Definition applied_forall : Derivation :=
3044 try_apply (SName "lemma") forall_proof goal_p3.
3045Eval (concludes applied_forall).
3046
3047-- ============================================
3048-- SUMMARY
3049-- ============================================
3050-- The Operator tactics give you manual control:
3051--
3052-- rewrite eq_proof goal
3053-- - Given Eq A x y, replaces x with y in goal
3054-- - Surgical precision when you have the right equality
3055--
3056-- rewrite_rev eq_proof goal
3057-- - Same but replaces y with x (reverse direction)
3058--
3059-- destruct type motive cases
3060-- - Case analysis without induction hypothesis
3061-- - Simpler than induction for non-recursive proofs
3062--
3063-- apply hyp_name hyp_proof goal
3064-- - Backward chaining: uses hypothesis to transform goal
3065-- - Works with implications (P → Q) and foralls (∀x. P(x))
3066--
3067-- When to use:
3068-- - auto fails on complex goals
3069-- - Need specific control over proof steps
3070-- - Working with explicit equality proofs
3071"###;
3072
3073const MATH_TACTICALS: &str = r###"-- ============================================
3074-- THE STRATEGIST: PROGRAMMABLE PROOFS
3075-- ============================================
3076--
3077-- Phase 10: Higher-Order Tactic Combinators
3078--
3079-- Tacticals turn proofs into programs. Instead of:
3080-- induction n.
3081-- auto.
3082-- auto.
3083-- auto.
3084--
3085-- Write:
3086-- induction n; repeat auto.
3087--
3088-- One line. Infinite power.
3089
3090-- ============================================
3091-- TACT_TRY: THE SAFETY NET
3092-- ============================================
3093-- tact_try : (Syntax -> Derivation) -> Syntax -> Derivation
3094--
3095-- Attempts a tactic but never fails. If the tactic fails,
3096-- returns the goal unchanged (identity).
3097--
3098-- Use case: "Try to simplify, but don't crash if you can't"
3099
3100-- Reflexive goal - try_refl succeeds
3101Definition goal_refl : Syntax :=
3102 SApp (SApp (SApp (SName "Eq") (SName "Nat"))
3103 (SName "Zero")) (SName "Zero").
3104
3105-- Non-reflexive goal - try_refl would fail
3106Definition goal_hard : Syntax :=
3107 SApp (SApp (SApp (SName "Eq") (SName "Nat"))
3108 (SName "Zero")) (SApp (SName "Succ") (SName "Zero")).
3109
3110-- tact_try always succeeds
3111Definition d_try_easy : Derivation := tact_try try_refl goal_refl.
3112Definition d_try_hard : Derivation := tact_try try_refl goal_hard.
3113
3114-- Easy goal: proves it
3115Eval (concludes d_try_easy).
3116
3117-- Hard goal: returns unchanged (identity) - NOT Error
3118Eval (concludes d_try_hard).
3119
3120-- ============================================
3121-- TACT_REPEAT: THE LOOP
3122-- ============================================
3123-- tact_repeat : (Syntax -> Derivation) -> Syntax -> Derivation
3124--
3125-- Applies a tactic repeatedly until it fails.
3126-- Returns after the last successful application.
3127--
3128-- Use case: "Keep simplifying until you can't simplify anymore"
3129
3130-- Identity tactic (always succeeds, does nothing)
3131Definition tact_id : Syntax -> Derivation := fun g : Syntax => DAxiom g.
3132
3133-- tact_repeat stops when no progress is made
3134Definition d_repeat : Derivation := tact_repeat tact_id goal_refl.
3135Eval (concludes d_repeat).
3136
3137-- ============================================
3138-- TACT_THEN: THE SEQUENCER (;)
3139-- ============================================
3140-- tact_then : (Syntax -> Derivation) -> (Syntax -> Derivation) -> Syntax -> Derivation
3141--
3142-- Sequence two tactics: apply first, then apply second to result.
3143-- If either fails, the whole thing fails.
3144--
3145-- Use case: "First simplify, then prove by reflexivity"
3146
3147-- Sequence: try (always succeeds) ; refl
3148Definition tact_combo : Syntax -> Derivation :=
3149 tact_then (tact_try tact_fail) try_refl.
3150
3151Definition d_combo : Derivation := tact_combo goal_refl.
3152Eval (concludes d_combo).
3153
3154-- ============================================
3155-- TACT_FIRST: THE MENU
3156-- ============================================
3157-- tact_first : TTactics -> Syntax -> Derivation
3158--
3159-- Try tactics from a list until one succeeds.
3160-- Returns Error if all fail.
3161--
3162-- TTactics = TList of (Syntax -> Derivation)
3163-- TacCons and TacNil are convenience wrappers
3164
3165-- Build a tactic list: [tact_fail, tact_fail, try_refl]
3166Definition my_tactics : TTactics :=
3167 TacCons tact_fail
3168 (TacCons tact_fail
3169 (TacCons try_refl TacNil)).
3170
3171-- First will skip the failures and use try_refl
3172Definition d_first : Derivation := tact_first my_tactics goal_refl.
3173Eval (concludes d_first).
3174
3175-- All fail case
3176Definition fail_tactics : TTactics := TacCons tact_fail TacNil.
3177Definition d_all_fail : Derivation := tact_first fail_tactics goal_refl.
3178Eval (concludes d_all_fail).
3179
3180-- ============================================
3181-- TACT_SOLVE: THE ENFORCER
3182-- ============================================
3183-- tact_solve : (Syntax -> Derivation) -> Syntax -> Derivation
3184--
3185-- Tactic MUST completely solve the goal.
3186-- If the tactic returns Error, fails.
3187-- If the tactic succeeds, returns its proof.
3188--
3189-- Use case: "Only use this tactic if it finishes the job"
3190
3191-- try_refl completely solves reflexive goals
3192Definition d_solve : Derivation := tact_solve try_refl goal_refl.
3193Eval (concludes d_solve).
3194
3195-- ============================================
3196-- THE NUCLEAR CODE
3197-- ============================================
3198-- Combine all tacticals into the ultimate tactic:
3199-- "Try everything we know how to do"
3200
3201Definition nuclear : Syntax -> Derivation :=
3202 tact_first (TacCons try_refl
3203 (TacCons (tact_try try_simp)
3204 (TacCons try_lia
3205 (TacCons try_auto TacNil)))).
3206
3207-- Test it on our reflexive goal
3208Definition d_nuclear : Derivation := nuclear goal_refl.
3209Eval (concludes d_nuclear).
3210
3211-- ============================================
3212-- COMBINING TACTICALS
3213-- ============================================
3214-- Real power: nest them!
3215
3216-- repeat (first [refl, simp]) - keep trying until nothing works
3217Definition solve_trivial : Syntax -> Derivation :=
3218 tact_repeat (tact_first (TacCons try_refl
3219 (TacCons (tact_try try_simp) TacNil))).
3220
3221Definition d_trivial : Derivation := solve_trivial goal_refl.
3222Eval (concludes d_trivial).
3223
3224-- ============================================
3225-- SUMMARY
3226-- ============================================
3227-- tact_try t - Try t, never fail (identity on failure)
3228-- tact_repeat t - Apply t until failure
3229-- tact_then t1 t2 - Sequence: t1 then t2
3230-- tact_first ts - Try list of tactics until one works
3231-- tact_solve t - t must completely prove the goal
3232--
3233-- With tact_orelse from Phase 98:
3234-- tact_orelse t1 t2 - Try t1, if fails try t2
3235-- tact_fail - Always fail
3236--
3237-- These form a complete tactical language for
3238-- programming proofs. God Mode achieved.
3239"###;
3240
3241#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3251pub enum Mode {
3252 Logic,
3253 Code,
3254 Math,
3255 Hardware,
3256}
3257
3258#[derive(Debug, Clone)]
3261pub enum Expected {
3262 Proves,
3264 DerivationNotCertified,
3269 CompilesToFol(&'static [&'static str]),
3274 OutputContains(&'static [&'static str]),
3276 NativeOnlyCompiles,
3279 KernelAllStatementsOk,
3281 KernelAdmitsAt(&'static str),
3284 SvaSynthesizes,
3286 SignalPlanSynthesizes,
3288 RtlProven,
3290 RefutesWithCounterexample,
3292 RegisterAllocFits,
3294 SpillsRequired,
3296 UnsatCertified,
3298}
3299
3300pub struct ExampleSpec {
3303 pub vfs_path: &'static str,
3304 pub mode: Mode,
3305 pub source: &'static str,
3306 pub expected: Expected,
3307}
3308
3309pub const ALL_LOGIC_EXAMPLES: &[ExampleSpec] = &[
3311 ExampleSpec { vfs_path: "/examples/logic/simple-sentences.logic", mode: Mode::Logic, source: LOGIC_SIMPLE, expected: Expected::CompilesToFol(&["Sleep", "Bark", "Loudly", "Love", "Fail"]) },
3312 ExampleSpec { vfs_path: "/examples/logic/quantifiers.logic", mode: Mode::Logic, source: LOGIC_QUANTIFIERS, expected: Expected::CompilesToFol(&["Student", "Book", "Professor", "Exam", "Cat"]) },
3313 ExampleSpec { vfs_path: "/examples/logic/tense-aspect.logic", mode: Mode::Logic, source: LOGIC_TENSE, expected: Expected::CompilesToFol(&["Run", "Eat", "Arrive", "Sleep", "Work"]) },
3314 ExampleSpec { vfs_path: "/examples/logic/prover-demo.logic", mode: Mode::Logic, source: LOGIC_PROVER, expected: Expected::Proves },
3315 ExampleSpec { vfs_path: "/examples/logic/simon.logic", mode: Mode::Logic, source: LOGIC_SIMON, expected: Expected::Proves },
3316 ExampleSpec { vfs_path: "/examples/logic/syllogism.logic", mode: Mode::Logic, source: LOGIC_SYLLOGISM, expected: Expected::Proves },
3317 ExampleSpec { vfs_path: "/examples/logic/trivial-proof.logic", mode: Mode::Logic, source: LOGIC_TRIVIAL, expected: Expected::Proves },
3318 ExampleSpec { vfs_path: "/examples/logic/disjunctive-syllogism.logic", mode: Mode::Logic, source: LOGIC_DISJUNCTIVE, expected: Expected::Proves },
3319 ExampleSpec { vfs_path: "/examples/logic/modus-tollens.logic", mode: Mode::Logic, source: LOGIC_MODUS_TOLLENS, expected: Expected::Proves },
3320 ExampleSpec { vfs_path: "/examples/logic/leibniz-identity.logic", mode: Mode::Logic, source: LOGIC_LEIBNIZ, expected: Expected::Proves },
3321 ExampleSpec { vfs_path: "/examples/logic/barber-paradox.logic", mode: Mode::Logic, source: LOGIC_BARBER, expected: Expected::DerivationNotCertified },
3322];
3323
3324pub const ALL_CODE_EXAMPLES: &[ExampleSpec] = &[
3327 ExampleSpec { vfs_path: "/examples/code/hello-world.logos", mode: Mode::Code, source: CODE_HELLO, expected: Expected::OutputContains(&["Hello, LOGOS!", "30"]) },
3328 ExampleSpec { vfs_path: "/examples/code/hello-world2.logos", mode: Mode::Code, source: CODE_HELLO2, expected: Expected::OutputContains(&["Hello, World!"]) },
3329 ExampleSpec { vfs_path: "/examples/code/fibonacci.logos", mode: Mode::Code, source: CODE_FIBONACCI, expected: Expected::OutputContains(&["55"]) },
3330 ExampleSpec { vfs_path: "/examples/code/fizzbuzz.logos", mode: Mode::Code, source: CODE_FIZZBUZZ, expected: Expected::OutputContains(&["FizzBuzz", "Buzz"]) },
3331 ExampleSpec { vfs_path: "/examples/code/fizzbuzz2.logos", mode: Mode::Code, source: CODE_FIZZBUZZ2, expected: Expected::OutputContains(&["FizzBuzz", "Buzz"]) },
3332 ExampleSpec { vfs_path: "/examples/code/fizzbuzz3.logos", mode: Mode::Code, source: CODE_FIZZBUZZ3, expected: Expected::OutputContains(&["FizzBuzz", "Buzz"]) },
3333 ExampleSpec { vfs_path: "/examples/code/collections.logos", mode: Mode::Code, source: CODE_COLLECTIONS, expected: Expected::OutputContains(&["6"]) },
3334 ExampleSpec { vfs_path: "/examples/code/factorial.logos", mode: Mode::Code, source: CODE_FACTORIAL, expected: Expected::OutputContains(&["120"]) },
3335 ExampleSpec { vfs_path: "/examples/code/prime-check.logos", mode: Mode::Code, source: CODE_PRIME, expected: Expected::OutputContains(&["29"]) },
3336 ExampleSpec { vfs_path: "/examples/code/sum-list.logos", mode: Mode::Code, source: CODE_SUM_LIST, expected: Expected::OutputContains(&["150"]) },
3337 ExampleSpec { vfs_path: "/examples/code/bubble-sort.logos", mode: Mode::Code, source: CODE_BUBBLE_SORT, expected: Expected::OutputContains(&["90"]) },
3338 ExampleSpec { vfs_path: "/examples/code/struct-demo.logos", mode: Mode::Code, source: CODE_STRUCT, expected: Expected::OutputContains(&["Alice"]) },
3339 ExampleSpec { vfs_path: "/examples/code/types/enums.logos", mode: Mode::Code, source: CODE_ENUMS, expected: Expected::OutputContains(&["red"]) },
3340 ExampleSpec { vfs_path: "/examples/code/types/generics.logos", mode: Mode::Code, source: CODE_GENERICS, expected: Expected::OutputContains(&["100"]) },
3341 ExampleSpec { vfs_path: "/examples/code/collections/sets.logos", mode: Mode::Code, source: CODE_SETS, expected: Expected::OutputContains(&["3"]) },
3342 ExampleSpec { vfs_path: "/examples/code/collections/maps.logos", mode: Mode::Code, source: CODE_MAPS, expected: Expected::OutputContains(&["50"]) },
3343 ExampleSpec { vfs_path: "/examples/code/functions/higher-order.logos", mode: Mode::Code, source: CODE_HIGHER_ORDER, expected: Expected::OutputContains(&["42"]) },
3344 ExampleSpec { vfs_path: "/examples/code/distributed/counters.logos", mode: Mode::Code, source: CODE_CRDT_COUNTERS, expected: Expected::OutputContains(&["18"]) },
3345 ExampleSpec { vfs_path: "/examples/code/security/policies.logos", mode: Mode::Code, source: CODE_POLICIES, expected: Expected::OutputContains(&["Admin"]) },
3346 ExampleSpec { vfs_path: "/examples/code/memory/zones.logos", mode: Mode::Code, source: CODE_ZONES, expected: Expected::OutputContains(&["100"]) },
3347 ExampleSpec { vfs_path: "/examples/code/native/tasks.logos", mode: Mode::Code, source: CODE_TASKS, expected: Expected::OutputContains(&["worker"]) },
3348 ExampleSpec { vfs_path: "/examples/code/native/channels.logos", mode: Mode::Code, source: CODE_CHANNELS, expected: Expected::OutputContains(&["42"]) },
3349 ExampleSpec { vfs_path: "/examples/code/basics/variables.logos", mode: Mode::Code, source: CODE_BASICS_VARIABLES, expected: Expected::OutputContains(&["Alice"]) },
3350 ExampleSpec { vfs_path: "/examples/code/basics/operators.logos", mode: Mode::Code, source: CODE_BASICS_OPERATORS, expected: Expected::OutputContains(&["13"]) },
3351 ExampleSpec { vfs_path: "/examples/code/basics/control-flow.logos", mode: Mode::Code, source: CODE_BASICS_CONTROL_FLOW, expected: Expected::OutputContains(&["Grade"]) },
3352 ExampleSpec { vfs_path: "/examples/code/types/enums-patterns.logos", mode: Mode::Code, source: CODE_ENUMS_PATTERNS, expected: Expected::OutputContains(&["status"]) },
3353 ExampleSpec { vfs_path: "/examples/code/memory/ownership.logos", mode: Mode::Code, source: CODE_OWNERSHIP, expected: Expected::OutputContains(&["profile"]) },
3354 ExampleSpec { vfs_path: "/examples/code/concurrency/parallel.logos", mode: Mode::Code, source: CODE_CONCURRENCY_PARALLEL, expected: Expected::OutputContains(&["30"]) },
3355 ExampleSpec { vfs_path: "/examples/code/distributed/tally.logos", mode: Mode::Code, source: CODE_CRDT_TALLY, expected: Expected::OutputContains(&["80"]) },
3356 ExampleSpec { vfs_path: "/examples/code/distributed/merge.logos", mode: Mode::Code, source: CODE_CRDT_MERGE, expected: Expected::OutputContains(&["150"]) },
3357 ExampleSpec { vfs_path: "/examples/code/networking/server.logos", mode: Mode::Code, source: CODE_NETWORK_SERVER, expected: Expected::NativeOnlyCompiles },
3358 ExampleSpec { vfs_path: "/examples/code/networking/client.logos", mode: Mode::Code, source: CODE_NETWORK_CLIENT, expected: Expected::NativeOnlyCompiles },
3359 ExampleSpec { vfs_path: "/examples/code/error-handling.logos", mode: Mode::Code, source: CODE_ERROR_HANDLING, expected: Expected::OutputContains(&["5"]) },
3360 ExampleSpec { vfs_path: "/examples/code/advanced/refinement.logos", mode: Mode::Code, source: CODE_ADVANCED_REFINEMENT, expected: Expected::OutputContains(&["5"]) },
3361 ExampleSpec { vfs_path: "/examples/code/advanced/assertions.logos", mode: Mode::Code, source: CODE_ADVANCED_ASSERTIONS, expected: Expected::OutputContains(&["50"]) },
3362 ExampleSpec { vfs_path: "/examples/code/temporal/durations.logos", mode: Mode::Code, source: CODE_TEMPORAL, expected: Expected::OutputContains(&["ns"]) },
3363];
3364
3365pub const ALL_MATH_EXAMPLES: &[ExampleSpec] = &[
3367 ExampleSpec { vfs_path: "/examples/math/natural-numbers.logos", mode: Mode::Math, source: MATH_NAT, expected: Expected::KernelAllStatementsOk },
3368 ExampleSpec { vfs_path: "/examples/math/boolean-logic.logos", mode: Mode::Math, source: MATH_BOOL, expected: Expected::KernelAllStatementsOk },
3369 ExampleSpec { vfs_path: "/examples/math/godel-sentence.logos", mode: Mode::Math, source: MATH_GODEL, expected: Expected::KernelAllStatementsOk },
3370 ExampleSpec { vfs_path: "/examples/math/incompleteness.logos", mode: Mode::Math, source: MATH_INCOMPLETENESS, expected: Expected::KernelAllStatementsOk },
3371 ExampleSpec { vfs_path: "/examples/math/prop-logic.logos", mode: Mode::Math, source: MATH_PROP_LOGIC, expected: Expected::KernelAllStatementsOk },
3372 ExampleSpec { vfs_path: "/examples/math/functions.logos", mode: Mode::Math, source: MATH_FUNCTIONS, expected: Expected::KernelAllStatementsOk },
3373 ExampleSpec { vfs_path: "/examples/math/list-ops.logos", mode: Mode::Math, source: MATH_LIST_OPS, expected: Expected::KernelAllStatementsOk },
3374 ExampleSpec { vfs_path: "/examples/math/pairs.logos", mode: Mode::Math, source: MATH_PAIRS, expected: Expected::KernelAllStatementsOk },
3375 ExampleSpec { vfs_path: "/examples/math/logic-gates.logos", mode: Mode::Math, source: MATH_CIRCUIT, expected: Expected::KernelAllStatementsOk },
3376 ExampleSpec { vfs_path: "/examples/math/proven-property.logos", mode: Mode::Math, source: MATH_PROPERTY, expected: Expected::KernelAllStatementsOk },
3377 ExampleSpec { vfs_path: "/examples/math/collatz.logos", mode: Mode::Math, source: MATH_COLLATZ, expected: Expected::KernelAllStatementsOk },
3378 ExampleSpec { vfs_path: "/examples/math/godel-literate.logos", mode: Mode::Math, source: MATH_GODEL_LITERATE, expected: Expected::KernelAllStatementsOk },
3379 ExampleSpec { vfs_path: "/examples/math/incompleteness-literate.logos", mode: Mode::Math, source: MATH_INCOMPLETENESS_LITERATE, expected: Expected::KernelAllStatementsOk },
3380 ExampleSpec { vfs_path: "/examples/math/ring-tactic.logos", mode: Mode::Math, source: MATH_RING, expected: Expected::KernelAllStatementsOk },
3381 ExampleSpec { vfs_path: "/examples/math/lia-tactic.logos", mode: Mode::Math, source: MATH_LIA, expected: Expected::KernelAllStatementsOk },
3382 ExampleSpec { vfs_path: "/examples/math/cc-tactic.logos", mode: Mode::Math, source: MATH_CC, expected: Expected::KernelAllStatementsOk },
3383 ExampleSpec { vfs_path: "/examples/math/simp-tactic.logos", mode: Mode::Math, source: MATH_SIMP, expected: Expected::KernelAllStatementsOk },
3384 ExampleSpec { vfs_path: "/examples/math/omega-tactic.logos", mode: Mode::Math, source: MATH_OMEGA, expected: Expected::KernelAllStatementsOk },
3385 ExampleSpec { vfs_path: "/examples/math/auto-tactic.logos", mode: Mode::Math, source: MATH_AUTO, expected: Expected::KernelAllStatementsOk },
3386 ExampleSpec { vfs_path: "/examples/math/induction-tactic.logos", mode: Mode::Math, source: MATH_INDUCTION, expected: Expected::KernelAllStatementsOk },
3387 ExampleSpec { vfs_path: "/examples/math/hints.logos", mode: Mode::Math, source: MATH_HINTS, expected: Expected::KernelAllStatementsOk },
3388 ExampleSpec { vfs_path: "/examples/math/inversion-tactic.logos", mode: Mode::Math, source: MATH_INVERSION, expected: Expected::KernelAllStatementsOk },
3389 ExampleSpec { vfs_path: "/examples/math/operator-tactics.logos", mode: Mode::Math, source: MATH_OPERATOR, expected: Expected::KernelAllStatementsOk },
3390 ExampleSpec { vfs_path: "/examples/math/tacticals.logos", mode: Mode::Math, source: MATH_TACTICALS, expected: Expected::KernelAllStatementsOk },
3391];
3392
3393pub const ALL_HARDWARE_SPECS: &[ExampleSpec] = &[
3397 ExampleSpec { vfs_path: "/examples/hardware/handshake.hw", mode: Mode::Hardware, source: HARDWARE_EXAMPLES[0].1, expected: Expected::SvaSynthesizes },
3398 ExampleSpec { vfs_path: "/examples/hardware/enable-ready.hw", mode: Mode::Hardware, source: HARDWARE_EXAMPLES[1].1, expected: Expected::SvaSynthesizes },
3399 ExampleSpec { vfs_path: "/examples/hardware/start-done.hw", mode: Mode::Hardware, source: HARDWARE_EXAMPLES[2].1, expected: Expected::SvaSynthesizes },
3400 ExampleSpec { vfs_path: "/examples/hardware/write-full.hw", mode: Mode::Hardware, source: HARDWARE_EXAMPLES[3].1, expected: Expected::SvaSynthesizes },
3401 ExampleSpec { vfs_path: "/examples/hardware/intersection-design.hw", mode: Mode::Hardware, source: HARDWARE_EXAMPLES[4].1, expected: Expected::SignalPlanSynthesizes },
3402 ExampleSpec { vfs_path: "/examples/hardware/arbiter.v", mode: Mode::Hardware, source: RTL_EXAMPLES[0].1, expected: Expected::RtlProven },
3403 ExampleSpec { vfs_path: "/examples/hardware/bad-arbiter.v", mode: Mode::Hardware, source: RTL_EXAMPLES[1].1, expected: Expected::RefutesWithCounterexample },
3404 ExampleSpec { vfs_path: "/examples/hardware/fifo.v", mode: Mode::Hardware, source: RTL_EXAMPLES[2].1, expected: Expected::RtlProven },
3405 ExampleSpec { vfs_path: "/examples/hardware/onehot.v", mode: Mode::Hardware, source: RTL_EXAMPLES[3].1, expected: Expected::RtlProven },
3406 ExampleSpec { vfs_path: "/examples/hardware/reset-mirror.v", mode: Mode::Hardware, source: RTL_EXAMPLES[4].1, expected: Expected::RtlProven },
3407 ExampleSpec { vfs_path: "/examples/hardware/traffic-safe.v", mode: Mode::Hardware, source: RTL_EXAMPLES[5].1, expected: Expected::RtlProven },
3408 ExampleSpec { vfs_path: "/examples/hardware/traffic-crash.v", mode: Mode::Hardware, source: RTL_EXAMPLES[6].1, expected: Expected::RefutesWithCounterexample },
3409 ExampleSpec { vfs_path: "/examples/hardware/queue-jam.v", mode: Mode::Hardware, source: RTL_EXAMPLES[7].1, expected: Expected::RefutesWithCounterexample },
3410 ExampleSpec { vfs_path: "/examples/hardware/queue-stable.v", mode: Mode::Hardware, source: RTL_EXAMPLES[8].1, expected: Expected::RtlProven },
3411 ExampleSpec { vfs_path: "/examples/hardware/register-alloc-fits.hw", mode: Mode::Hardware, source: REGALLOC_EXAMPLES[0].1, expected: Expected::RegisterAllocFits },
3412 ExampleSpec { vfs_path: "/examples/hardware/register-alloc-spill.hw", mode: Mode::Hardware, source: REGALLOC_EXAMPLES[1].1, expected: Expected::SpillsRequired },
3413 ExampleSpec { vfs_path: "/examples/hardware/pigeonhole.hw", mode: Mode::Hardware, source: PIGEONHOLE_EXAMPLES[0].1, expected: Expected::UnsatCertified },
3414 ExampleSpec { vfs_path: "/examples/hardware/pigeonhole-12.hw", mode: Mode::Hardware, source: PIGEONHOLE_EXAMPLES[1].1, expected: Expected::UnsatCertified },
3415];
3416
3417#[cfg(test)]
3418mod example_health {
3419 use super::*;
3425 use logicaffeine_compile::codegen_sva::fol_to_sva::synthesize_sva_from_spec;
3426 use logicaffeine_compile::codegen_sva::hw_pipeline::prove_spec_sva_equivalence;
3427 use logicaffeine_compile::codegen_sva::rtl::parse_transition_system;
3428 use logicaffeine_compile::codegen_sva::signal_design::design_from_spec;
3429 use logicaffeine_compile::{
3430 compile_for_ui, compile_theorem_for_ui, generate_rust_code,
3431 interpret_for_ui_baseline_with_args,
3432 };
3433 use logicaffeine_kernel::interface::Repl;
3434 use logicaffeine_proof::bmc::{BmcOutcome, InductionOutcome};
3435 use logicaffeine_proof::register_alloc::{
3436 allocate, is_spill_certificate, is_valid_allocation, Allocation,
3437 };
3438
3439 fn check(spec: &ExampleSpec) -> Result<(), String> {
3442 match &spec.expected {
3443 Expected::CompilesToFol(needles) => {
3444 let r = compile_for_ui(spec.source);
3445 if let Some(e) = r.error {
3446 return Err(format!("compile error: {e}"));
3447 }
3448 let logic = r.logic.unwrap_or_default();
3449 if logic.trim().is_empty() {
3450 return Err("no FOL produced".to_string());
3451 }
3452 let simple = r.simple_logic.unwrap_or_default();
3453 for needle in *needles {
3454 if !logic.contains(needle) {
3455 return Err(format!("primary FOL missing {needle:?}:\n{logic}"));
3456 }
3457 if !simple.contains(needle) {
3458 return Err(format!("Simple FOL missing {needle:?}:\n{simple}"));
3459 }
3460 }
3461 Ok(())
3462 }
3463 Expected::Proves => {
3464 let r = compile_theorem_for_ui(spec.source);
3465 if r.verified {
3466 Ok(())
3467 } else {
3468 Err(format!(
3469 "theorem '{}' not kernel-verified{}",
3470 r.name,
3471 r.verification_error
3472 .map(|e| format!(": {e}"))
3473 .unwrap_or_default()
3474 ))
3475 }
3476 }
3477 Expected::DerivationNotCertified => {
3478 let r = compile_theorem_for_ui(spec.source);
3479 match (r.derivation.is_some(), r.verified) {
3480 (true, false) => Ok(()),
3481 (true, true) => Err(
3482 "expected an uncertified derivation (honesty demo) but it certified"
3483 .to_string(),
3484 ),
3485 (false, _) => Err("expected a derivation to be found, none was".to_string()),
3486 }
3487 }
3488 Expected::OutputContains(needles) => {
3489 match generate_rust_code(spec.source) {
3492 Ok(rust) if !rust.trim().is_empty() => {}
3493 Ok(_) => return Err("generated empty Rust".to_string()),
3494 Err(e) => return Err(format!("codegen error: {e:?}")),
3495 }
3496 let result = run_code(spec.source);
3497 if let Some(e) = result.error {
3498 return Err(format!("interpreter error: {e}"));
3499 }
3500 let out = result.lines.join("\n");
3501 for needle in *needles {
3502 if !out.contains(needle) {
3503 return Err(format!(
3504 "output missing {needle:?}; actual output:\n{out}"
3505 ));
3506 }
3507 }
3508 Ok(())
3509 }
3510 Expected::NativeOnlyCompiles => match generate_rust_code(spec.source) {
3511 Ok(rust) if !rust.trim().is_empty() => Ok(()),
3512 Ok(_) => Err("generated empty Rust".to_string()),
3513 Err(e) => Err(format!("codegen error: {e:?}")),
3514 },
3515 Expected::KernelAllStatementsOk => run_kernel(spec.source, None),
3516 Expected::KernelAdmitsAt(marker) => run_kernel(spec.source, Some(marker)),
3517 Expected::SvaSynthesizes => {
3518 let synth = synthesize_sva_from_spec(spec.source, "clk")
3519 .map_err(|e| format!("SVA synthesis failed: {e}"))?;
3520 let equiv = prove_spec_sva_equivalence(spec.source, &synth.body, 8)
3521 .map_err(|e| format!("equivalence check failed: {e:?}"))?;
3522 if equiv.equivalent {
3523 Ok(())
3524 } else {
3525 Err("synthesized SVA not certified equivalent to spec".to_string())
3526 }
3527 }
3528 Expected::SignalPlanSynthesizes => {
3529 let (_intersection, plan) = design_from_spec(spec.source)
3530 .map_err(|e| format!("signal-design failed: {e}"))?;
3531 if plan.num_phases >= 1 {
3532 Ok(())
3533 } else {
3534 Err("signal-design produced no phases".to_string())
3535 }
3536 }
3537 Expected::RtlProven => {
3538 let ts = parse_transition_system(spec.source)
3539 .map_err(|e| format!("RTL parse failed: {e:?}"))?;
3540 match ts.prove_invariant(4) {
3541 InductionOutcome::Proven => Ok(()),
3542 InductionOutcome::NotInductive => match ts.bmc(28) {
3543 BmcOutcome::NoneWithin(_) => Ok(()),
3544 other => Err(format!("expected safe, BMC found {other:?}")),
3545 },
3546 other => Err(format!("expected Proven, got {other:?}")),
3547 }
3548 }
3549 Expected::RefutesWithCounterexample => {
3550 let ts = parse_transition_system(spec.source)
3551 .map_err(|e| format!("RTL parse failed: {e:?}"))?;
3552 let inv = ts.prove_invariant(4);
3553 if matches!(inv, InductionOutcome::CounterexampleAt { .. }) {
3554 return Ok(());
3555 }
3556 if matches!(inv, InductionOutcome::NotInductive) {
3557 if matches!(ts.bmc(28), BmcOutcome::CounterexampleAt { .. }) {
3558 return Ok(());
3559 }
3560 }
3561 Err(format!(
3562 "expected a counterexample, prove_invariant gave {inv:?}"
3563 ))
3564 }
3565 Expected::RegisterAllocFits => {
3566 let regspec = crate::ui::pages::register_alloc_viz::parse_register_spec(spec.source)
3567 .ok_or("could not parse register spec")?;
3568 match allocate(®spec.ranges, regspec.registers) {
3569 Allocation::Allocated(reg_of) => {
3570 if is_valid_allocation(®spec.ranges, regspec.registers, ®_of) {
3571 Ok(())
3572 } else {
3573 Err("allocation is not valid".to_string())
3574 }
3575 }
3576 Allocation::Spill { .. } => {
3577 Err("expected a fitting allocation, got a spill".to_string())
3578 }
3579 }
3580 }
3581 Expected::SpillsRequired => {
3582 let regspec = crate::ui::pages::register_alloc_viz::parse_register_spec(spec.source)
3583 .ok_or("could not parse register spec")?;
3584 match allocate(®spec.ranges, regspec.registers) {
3585 Allocation::Spill { must_spill, .. } => {
3586 if is_spill_certificate(®spec.ranges, regspec.registers, &must_spill) {
3587 Ok(())
3588 } else {
3589 Err("spill certificate does not re-verify".to_string())
3590 }
3591 }
3592 Allocation::Allocated(_) => {
3593 Err("expected a required spill, got a fitting allocation".to_string())
3594 }
3595 }
3596 }
3597 Expected::UnsatCertified => {
3598 let pspec = crate::ui::pages::pigeonhole_viz::parse_pigeonhole_spec(spec.source)
3599 .ok_or("could not parse pigeonhole spec")?;
3600 let verdict = crate::ui::pages::pigeonhole_viz::solve(&pspec);
3601 if verdict.certified && !verdict.hall.slots.is_empty() {
3602 Ok(())
3603 } else {
3604 Err("pigeonhole UNSAT was not certified".to_string())
3605 }
3606 }
3607 }
3608 }
3609
3610 fn run_code(src: &str) -> logicaffeine_compile::interpreter::InterpreterResult {
3615 let rt = logicaffeine_system::tokio::runtime::Builder::new_current_thread()
3616 .enable_all()
3617 .build()
3618 .expect("failed to build Tokio runtime for code example");
3619 rt.block_on(interpret_for_ui_baseline_with_args(src, &[]))
3620 }
3621
3622 fn run_kernel(source: &str, admit_marker: Option<&str>) -> Result<(), String> {
3627 let mut repl = Repl::new();
3628 let mut admitted = false;
3629 for stmt in crate::ui::pages::studio::parse_math_statements(source) {
3630 if let Some(marker) = admit_marker {
3631 if stmt.contains(marker) {
3632 admitted = true;
3633 }
3634 }
3635 if let Err(e) = repl.execute(&stmt) {
3636 if admitted {
3637 return Ok(());
3638 }
3639 return Err(format!("statement failed: {stmt}\n -> {e}"));
3640 }
3641 }
3642 if admit_marker.is_some() && !admitted {
3643 return Err("admit marker never matched any statement".to_string());
3644 }
3645 Ok(())
3646 }
3647
3648 fn lock(registry: &[ExampleSpec], mode: &str) {
3651 let mut failures = Vec::new();
3652 for spec in registry {
3653 if let Err(reason) = check(spec) {
3654 failures.push(format!(" {}: {reason}", spec.vfs_path));
3655 }
3656 }
3657 assert!(
3658 failures.is_empty(),
3659 "{} {mode} example(s) failed their lock:\n{}",
3660 failures.len(),
3661 failures.join("\n")
3662 );
3663 }
3664
3665 #[test]
3666 fn lock_logic_examples() {
3667 lock(ALL_LOGIC_EXAMPLES, "logic");
3668 }
3669
3670 #[test]
3671 fn lock_code_examples() {
3672 lock(ALL_CODE_EXAMPLES, "code");
3673 }
3674
3675 #[test]
3676 fn lock_math_examples() {
3677 lock(ALL_MATH_EXAMPLES, "math");
3678 }
3679
3680 #[test]
3681 fn lock_hardware_examples() {
3682 lock(ALL_HARDWARE_SPECS, "hardware");
3683 }
3684
3685 fn all_specs() -> impl Iterator<Item = &'static ExampleSpec> {
3688 ALL_LOGIC_EXAMPLES
3689 .iter()
3690 .chain(ALL_CODE_EXAMPLES)
3691 .chain(ALL_MATH_EXAMPLES)
3692 .chain(ALL_HARDWARE_SPECS)
3693 }
3694
3695 #[test]
3698 fn registry_counts_are_locked() {
3699 assert_eq!(ALL_LOGIC_EXAMPLES.len(), 11, "logic example count changed");
3700 assert_eq!(ALL_CODE_EXAMPLES.len(), 36, "code example count changed");
3701 assert_eq!(ALL_MATH_EXAMPLES.len(), 24, "math example count changed");
3702 assert_eq!(ALL_HARDWARE_SPECS.len(), 18, "hardware example count changed");
3703 }
3704
3705 #[test]
3709 fn every_vfs_path_is_well_formed_and_unique() {
3710 use std::collections::HashSet;
3711 let mut seen = HashSet::new();
3712 for spec in all_specs() {
3713 assert!(seen.insert(spec.vfs_path), "duplicate vfs_path: {}", spec.vfs_path);
3714 let (dir, exts): (&str, &[&str]) = match spec.mode {
3715 Mode::Logic => ("/examples/logic/", &[".logic"]),
3716 Mode::Code => ("/examples/code/", &[".logos"]),
3717 Mode::Math => ("/examples/math/", &[".logos"]),
3718 Mode::Hardware => ("/examples/hardware/", &[".hw", ".v"]),
3719 };
3720 assert!(spec.vfs_path.starts_with(dir), "{} is not under {dir}", spec.vfs_path);
3721 assert!(
3722 exts.iter().any(|e| spec.vfs_path.ends_with(e)),
3723 "{} has the wrong extension for {:?}",
3724 spec.vfs_path,
3725 spec.mode
3726 );
3727 assert!(!spec.source.trim().is_empty(), "{} has empty source", spec.vfs_path);
3728 }
3729 }
3730
3731 #[cfg(not(target_arch = "wasm32"))]
3736 #[test]
3737 fn seeding_writes_exactly_the_registry() {
3738 use std::collections::HashSet;
3739 use std::path::Path;
3740
3741 let root = std::env::temp_dir().join(format!("logos_seed_ratchet_{}", std::process::id()));
3742 let _ = std::fs::remove_dir_all(&root);
3743 let vfs = logicaffeine_system::fs::NativeVfs::new(root.clone());
3744 let rt = logicaffeine_system::tokio::runtime::Builder::new_current_thread()
3745 .enable_all()
3746 .build()
3747 .expect("failed to build Tokio runtime");
3748 rt.block_on(super::seed_examples(&vfs)).expect("seed_examples failed");
3749
3750 fn collect(dir: &Path, base: &Path, out: &mut HashSet<String>) {
3751 if let Ok(entries) = std::fs::read_dir(dir) {
3752 for e in entries.flatten() {
3753 let p = e.path();
3754 if p.is_dir() {
3755 collect(&p, base, out);
3756 } else if let Ok(rel) = p.strip_prefix(base) {
3757 out.insert(format!("/{}", rel.to_string_lossy().replace('\\', "/")));
3758 }
3759 }
3760 }
3761 }
3762 let mut seeded = HashSet::new();
3763 collect(&root.join("examples"), &root, &mut seeded);
3764 let _ = std::fs::remove_dir_all(&root);
3765
3766 let registry: HashSet<String> = all_specs().map(|s| s.vfs_path.to_string()).collect();
3767 let missing: Vec<&String> = registry.difference(&seeded).collect();
3768 let extra: Vec<&String> = seeded.difference(®istry).collect();
3769 assert!(
3770 missing.is_empty() && extra.is_empty(),
3771 "seed_examples drifted from the registry.\n MISSING (in registry, not seeded): {missing:?}\n EXTRA (seeded, not in registry): {extra:?}"
3772 );
3773 }
3774
3775 #[cfg(not(target_arch = "wasm32"))]
3779 #[test]
3780 fn audit_logic_math_rust_compiles() {
3781 use logicaffeine_compile::{extract_logic_rust, extract_math_rust_from_source};
3782 use std::process::Command;
3783
3784 fn first_error(stderr: &[u8]) -> String {
3785 String::from_utf8_lossy(stderr)
3786 .lines()
3787 .find(|l| l.contains("error"))
3788 .unwrap_or("(unknown)")
3789 .to_string()
3790 }
3791
3792 fn rustc_check(name: &str, code: &str) -> Result<(), String> {
3793 let safe = name.replace(['/', '.', '-'], "_");
3795 let src = std::env::temp_dir().join(format!("logos_audit_{safe}.rs"));
3796 std::fs::write(&src, code).map_err(|e| e.to_string())?;
3797
3798 if code.contains("fn main") {
3805 let bin = std::env::temp_dir().join(format!("logos_audit_{safe}_bin"));
3806 let o = Command::new("rustc")
3807 .args(["--edition", "2021", "-A", "warnings", "-o"])
3808 .arg(&bin)
3809 .arg(&src)
3810 .output()
3811 .map_err(|e| e.to_string())?;
3812 if !o.status.success() {
3813 return Err(first_error(&o.stderr));
3814 }
3815 let mut child = Command::new(&bin).spawn().map_err(|e| e.to_string())?;
3816 let mut waited = 0u32;
3817 let status = loop {
3818 match child.try_wait().map_err(|e| e.to_string())? {
3819 Some(s) => break Some(s),
3820 None if waited >= 100 => {
3821 let _ = child.kill();
3822 break None;
3823 }
3824 None => {
3825 std::thread::sleep(std::time::Duration::from_millis(100));
3826 waited += 1;
3827 }
3828 }
3829 };
3830 let _ = std::fs::remove_file(&bin);
3831 match status {
3832 Some(s) if s.success() => Ok(()),
3833 Some(_) => Err("compiled but its self-checking main FAILED at runtime".to_string()),
3834 None => Err("compiled but did not finish within 10s".to_string()),
3835 }
3836 } else {
3837 let out = std::env::temp_dir().join(format!("logos_audit_{safe}.rmeta"));
3838 let o = Command::new("rustc")
3839 .args(["--edition", "2021", "--crate-type", "lib", "--emit=metadata", "-A", "warnings", "-o"])
3840 .arg(&out)
3841 .arg(&src)
3842 .output()
3843 .map_err(|e| e.to_string())?;
3844 if o.status.success() {
3845 Ok(())
3846 } else {
3847 Err(first_error(&o.stderr))
3848 }
3849 }
3850 }
3851
3852 fn report(kind: &str, items: &[(&str, String)], failures: &mut Vec<String>) {
3853 println!("\n=== {kind} examples → Rust ===");
3854 for (name, code) in items {
3855 let is_program = code.contains("fn ") || code.contains("enum ");
3857 if !is_program {
3858 println!(" {name:30} NOTE (not a program — by design)");
3859 continue;
3860 }
3861 match rustc_check(name, code) {
3862 Ok(()) => println!(" {name:30} compiles ✓"),
3863 Err(e) => {
3864 println!(" {name:30} DOES NOT COMPILE ✗ — {e}");
3865 failures.push(format!("{kind}/{name}: {e}"));
3866 }
3867 }
3868 }
3869 }
3870
3871 let logic: Vec<(&str, String)> = ALL_LOGIC_EXAMPLES
3872 .iter()
3873 .map(|s| (s.vfs_path, extract_logic_rust(s.source).unwrap_or_else(|e| format!("// err: {e}"))))
3874 .collect();
3875 let math: Vec<(&str, String)> = ALL_MATH_EXAMPLES
3876 .iter()
3877 .map(|s| (s.vfs_path, extract_math_rust_from_source(s.source)))
3878 .collect();
3879 let mut failures = Vec::new();
3880 report("LOGIC", &logic, &mut failures);
3881 report("MATH", &math, &mut failures);
3882 assert!(
3885 failures.is_empty(),
3886 "{} example(s) emit Rust that does not compile:\n{}",
3887 failures.len(),
3888 failures.join("\n")
3889 );
3890 }
3891}