@@ -232,6 +232,36 @@ impl Specialist for Algebraist {
232232 script: "by (simp add: field_simps)" . to_string( ) ,
233233 description: "Field/ring arithmetic simplification." . to_string( ) ,
234234 } ,
235+ TacticTemplate {
236+ name: "ac-simps" . to_string( ) ,
237+ script: "by (simp add: ac_simps)" . to_string( ) ,
238+ description: "Associativity + commutativity rewriting — replaces looping metis chains on +/* monoids." . to_string( ) ,
239+ } ,
240+ TacticTemplate {
241+ name: "semiring-distrib" . to_string( ) ,
242+ script: "by (simp add: distrib_left distrib_right)" . to_string( ) ,
243+ description: "Both-sided distributivity for semiring goals." . to_string( ) ,
244+ } ,
245+ TacticTemplate {
246+ name: "metis-empty" . to_string( ) ,
247+ script: "by metis" . to_string( ) ,
248+ description: "Equational reasoning without hints — succeeds where simp loses orientation." . to_string( ) ,
249+ } ,
250+ TacticTemplate {
251+ name: "linarith-after-simp" . to_string( ) ,
252+ script: "by (simp; linarith)" . to_string( ) ,
253+ description: "Simplifier reduction followed by linear arithmetic — Isabelle 2025-1 omega→linarith drift fallback." . to_string( ) ,
254+ } ,
255+ TacticTemplate {
256+ name: "comm-monoid-add" . to_string( ) ,
257+ script: "by (simp add: ac_simps add.commute)" . to_string( ) ,
258+ description: "Commutative-monoid rewriting (add.commute is the post-rebrand name)." . to_string( ) ,
259+ } ,
260+ TacticTemplate {
261+ name: "transfer-then-simp" . to_string( ) ,
262+ script: "by (transfer, simp add: algebra_simps)" . to_string( ) ,
263+ description: "Transfer to representation type then simplify — useful for tropical/quotient goals." . to_string( ) ,
264+ } ,
235265 ] ,
236266 }
237267 }
@@ -265,7 +295,7 @@ impl Specialist for OrderTheorist {
265295 TacticTemplate {
266296 name: "order-trans" . to_string( ) ,
267297 script: "by (rule order_trans)" . to_string( ) ,
268- description: "Transitivity of ≤." . to_string( ) ,
298+ description: "Transitivity of ≤ (Isabelle 2025-1 canonical name; le_trans was deprecated) ." . to_string( ) ,
269299 } ,
270300 TacticTemplate {
271301 name: "order-auto" . to_string( ) ,
@@ -277,6 +307,46 @@ impl Specialist for OrderTheorist {
277307 script: "by (auto simp: subset_iff)" . to_string( ) ,
278308 description: "Element-wise subset reasoning." . to_string( ) ,
279309 } ,
310+ TacticTemplate {
311+ name: "linarith" . to_string( ) ,
312+ script: "by linarith" . to_string( ) ,
313+ description: "Linear arithmetic decision procedure — replaces omega in Isabelle 2025-1." . to_string( ) ,
314+ } ,
315+ TacticTemplate {
316+ name: "sum-mono" . to_string( ) ,
317+ script: "by (rule sum_mono) auto" . to_string( ) ,
318+ description: "Pointwise monotonicity of sums (Kleene 237 pattern)." . to_string( ) ,
319+ } ,
320+ TacticTemplate {
321+ name: "monoI-then-auto" . to_string( ) ,
322+ script: "by (intro monoI) auto" . to_string( ) ,
323+ description: "Introduce monotonicity then resolve elementwise." . to_string( ) ,
324+ } ,
325+ TacticTemplate {
326+ name: "force" . to_string( ) ,
327+ script: "by force" . to_string( ) ,
328+ description: "Stronger than blast for goals needing list/sequence decomposition (Kleene 403 pattern: [v] vs v#[])." . to_string( ) ,
329+ } ,
330+ TacticTemplate {
331+ name: "meson-order" . to_string( ) ,
332+ script: "by (meson order_trans)" . to_string( ) ,
333+ description: "Meson with transitive chain — succeeds on multi-hop ≤ goals where blast loops." . to_string( ) ,
334+ } ,
335+ TacticTemplate {
336+ name: "le-supI" . to_string( ) ,
337+ script: "by (auto intro: le_supI1 le_supI2)" . to_string( ) ,
338+ description: "Sup introduction on either side — for goals against a join." . to_string( ) ,
339+ } ,
340+ TacticTemplate {
341+ name: "subset-trans" . to_string( ) ,
342+ script: "by (meson subset_trans)" . to_string( ) ,
343+ description: "Subset transitivity chain — replaces blast loops on nested ⊆ obligations." . to_string( ) ,
344+ } ,
345+ TacticTemplate {
346+ name: "order-trans-OF" . to_string( ) ,
347+ script: "by (rule order_trans[OF assms]) simp" . to_string( ) ,
348+ description: "Apply transitivity with the assumption pre-substituted — often the missing instantiation." . to_string( ) ,
349+ } ,
280350 ] ,
281351 }
282352 }
@@ -321,6 +391,51 @@ impl Specialist for Combinatorialist {
321391 script: "by (induction xs) auto" . to_string( ) ,
322392 description: "Structural induction on a list named xs." . to_string( ) ,
323393 } ,
394+ TacticTemplate {
395+ name: "induction-arbitrary" . to_string( ) ,
396+ script: "by (induction k arbitrary: j) auto" . to_string( ) ,
397+ description: "Generalised induction (Matrices_Full helper pattern: arbitrary: j keeps the IH usable across positions)." . to_string( ) ,
398+ } ,
399+ TacticTemplate {
400+ name: "cases-list" . to_string( ) ,
401+ script: "by (cases w; auto)" . to_string( ) ,
402+ description: "Case-split on list constructors then auto — the list-non-empty pattern." . to_string( ) ,
403+ } ,
404+ TacticTemplate {
405+ name: "sum-insert" . to_string( ) ,
406+ script: "by (subst sum.insert) auto" . to_string( ) ,
407+ description: "Step a sum at an insert (replaces sum.atLeastAtMost_Suc, deprecated in 2025-1)." . to_string( ) ,
408+ } ,
409+ TacticTemplate {
410+ name: "sum-distrib" . to_string( ) ,
411+ script: "by (simp add: sum.distrib)" . to_string( ) ,
412+ description: "Sum distributivity (replaces sum_add_distrib, renamed in 2025-1)." . to_string( ) ,
413+ } ,
414+ TacticTemplate {
415+ name: "unfolding-walks-def" . to_string( ) ,
416+ script: "unfolding walks_def by simp" . to_string( ) ,
417+ description: "Unfold walks_def then simp — beats `proof (intro conjI)` because walks_def yields a Collect set." . to_string( ) ,
418+ } ,
419+ TacticTemplate {
420+ name: "metis-append" . to_string( ) ,
421+ script: "by (metis append_Cons append_Nil)" . to_string( ) ,
422+ description: "List concatenation lemmas — closes obtain-decompositions of [v]@ys vs v#ys (Kleene 403 pattern)." . to_string( ) ,
423+ } ,
424+ TacticTemplate {
425+ name: "force" . to_string( ) ,
426+ script: "by force" . to_string( ) ,
427+ description: "Stronger than blast for list-decomposition obtain goals." . to_string( ) ,
428+ } ,
429+ TacticTemplate {
430+ name: "permutes-in-image" . to_string( ) ,
431+ script: "by (rule permutes_in_image[OF assms])" . to_string( ) ,
432+ description: "Permutations as image-preserving — closes Det 153/207 type-class regression goals." . to_string( ) ,
433+ } ,
434+ TacticTemplate {
435+ name: "transposition-2x2" . to_string( ) ,
436+ script: "by (cases a; cases b) (auto simp: Transposition.transpose)" . to_string( ) ,
437+ description: "2x2 case split using Transposition.transpose (Fun.swap is input-only in 2025-1)." . to_string( ) ,
438+ } ,
324439 ] ,
325440 }
326441 }
@@ -543,6 +658,55 @@ mod tests {
543658 assert ! ( s. relevance( & g) > 0.0 , "should engage on walks + finite" ) ;
544659 }
545660
661+ #[ test]
662+ fn playbooks_expanded_2026_04_26 ( ) {
663+ // After the swarm-dogfood session against Tropical_Semirings, each
664+ // playbook was expanded with proof-repair patterns observed in real
665+ // failure sites (cycle-excise, Det 153/207, Kleene 403, etc.) plus
666+ // Isabelle 2025-1 drift fixes (omega→linarith, sum.atLeastAtMost_Suc
667+ // deprecation, Fun.swap input-only). Lock in the new minimums so
668+ // future shrink-regressions are caught.
669+ assert ! ( Algebraist . playbook( ) . tactics. len( ) >= 10 ,
670+ "Algebraist playbook should have ≥10 tactics post-2026-04-26 expansion" ) ;
671+ assert ! ( OrderTheorist . playbook( ) . tactics. len( ) >= 12 ,
672+ "OrderTheorist playbook should have ≥12 tactics post-2026-04-26 expansion" ) ;
673+ assert ! ( Combinatorialist . playbook( ) . tactics. len( ) >= 12 ,
674+ "Combinatorialist playbook should have ≥12 tactics post-2026-04-26 expansion" ) ;
675+ }
676+
677+ #[ test]
678+ fn combinatorialist_carries_session_repair_patterns ( ) {
679+ // The Tropical_Semirings session-close added these specific tactics
680+ // because real failures pointed at them. They must stay named-and-
681+ // findable so a future ledger entry can cite them by name.
682+ let names: Vec < String > = Combinatorialist . playbook ( ) . tactics
683+ . iter ( ) . map ( |t| t. name . clone ( ) ) . collect ( ) ;
684+ assert ! ( names. iter( ) . any( |n| n == "permutes-in-image" ) ,
685+ "Combinatorialist must carry the Det 153/207 fix" ) ;
686+ assert ! ( names. iter( ) . any( |n| n == "metis-append" ) ,
687+ "Combinatorialist must carry the Kleene 403 list-decomp fix" ) ;
688+ assert ! ( names. iter( ) . any( |n| n == "induction-arbitrary" ) ,
689+ "Combinatorialist must carry the Matrices_Full generalised-induction pattern" ) ;
690+ }
691+
692+ #[ test]
693+ fn order_theorist_carries_2025_drift_fixes ( ) {
694+ let names: Vec < String > = OrderTheorist . playbook ( ) . tactics
695+ . iter ( ) . map ( |t| t. name . clone ( ) ) . collect ( ) ;
696+ assert ! ( names. iter( ) . any( |n| n == "linarith" ) ,
697+ "OrderTheorist must carry linarith (omega→linarith drift in 2025-1)" ) ;
698+ assert ! ( names. iter( ) . any( |n| n == "force" ) ,
699+ "OrderTheorist must carry force (Kleene 403 list-decomp fallback)" ) ;
700+ }
701+
702+ #[ test]
703+ fn algebraist_carries_ac_simps_replacement ( ) {
704+ let names: Vec < String > = Algebraist . playbook ( ) . tactics
705+ . iter ( ) . map ( |t| t. name . clone ( ) ) . collect ( ) ;
706+ assert ! ( names. iter( ) . any( |n| n == "ac-simps" ) ,
707+ "Algebraist must carry ac-simps (replaces looping metis chains)" ) ;
708+ }
709+
546710 #[ test]
547711 fn swarm_routes_to_relevant_specialists_first ( ) {
548712 let g = parse_goal ( "lemma foo: \" finite T \\ <Longrightarrow> trop_walks_sum A S \\ <le> trop_walks_sum A T\" " ) ;
0 commit comments