From b6fe4db5d48089fb7ba3899d99a326f4469e68ec Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 9 Mar 2026 18:19:35 +0100 Subject: [PATCH] feat(skill): add umbrella gecode skill --- README.md | 42 +++++++---- evals/gecode-trigger-evals.json | 62 ++++++++++++++++ skills/gecode/SKILL.md | 70 +++++++++++++++++++ skills/gecode/agents/openai.yaml | 4 ++ .../references/brancher-implementation.md | 33 +++++++++ .../gecode/references/debugging-workflow.md | 41 +++++++++++ skills/gecode/references/general-knowledge.md | 11 +++ skills/gecode/references/memory-handling.md | 32 +++++++++ skills/gecode/references/modeling-cookbook.md | 36 ++++++++++ skills/gecode/references/modeling.md | 45 ++++++++++++ .../references/propagator-implementation.md | 35 ++++++++++ .../gecode/references/scheduling-patterns.md | 22 ++++++ .../search-engine-implementation.md | 33 +++++++++ skills/gecode/references/search-engines.md | 38 ++++++++++ .../references/set-and-float-modeling.md | 23 ++++++ 15 files changed, 513 insertions(+), 14 deletions(-) create mode 100644 evals/gecode-trigger-evals.json create mode 100644 skills/gecode/SKILL.md create mode 100644 skills/gecode/agents/openai.yaml create mode 100644 skills/gecode/references/brancher-implementation.md create mode 100644 skills/gecode/references/debugging-workflow.md create mode 100644 skills/gecode/references/general-knowledge.md create mode 100644 skills/gecode/references/memory-handling.md create mode 100644 skills/gecode/references/modeling-cookbook.md create mode 100644 skills/gecode/references/modeling.md create mode 100644 skills/gecode/references/propagator-implementation.md create mode 100644 skills/gecode/references/scheduling-patterns.md create mode 100644 skills/gecode/references/search-engine-implementation.md create mode 100644 skills/gecode/references/search-engines.md create mode 100644 skills/gecode/references/set-and-float-modeling.md diff --git a/README.md b/README.md index c2d30ef..140f294 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,43 @@ # Gecode Skills -Repository infrastructure for publishing Gecode-focused AI agent skills. +Canonical skill repository for the umbrella Gecode AI agent skill. -This branch sets up validation, CI, and release automation. It does not introduce a published skill yet. +Install with: -## Infrastructure +```bash +npx skills add Gecode/gecode-skills +``` + +List available skills: + +```bash +npx skills add Gecode/gecode-skills --list +``` -Included here: +Install a single skill: -- GitHub Actions for validation and release publishing -- semver/version helper scripts -- release policy gating through `.release-policy.yml` -- generic skill validation that works before any skill is added +```bash +npx skills add Gecode/gecode-skills --skill gecode +``` -## Future Skill Layout +## Available Skill -Skills will live under: +- `gecode` -- `skills//SKILL.md` +The skill routes internally to focused reference documents for: +- Gecode architecture and runtime semantics +- modeling and search setup +- custom propagators +- custom branchers +- memory management +- built-in search engines +- custom search engine implementation ## Contributing ### Skill structure -Each skill must be under: +The skill must be under: - `skills//SKILL.md` @@ -33,7 +47,7 @@ Optional metadata for UIs can be added at: ### Required frontmatter -Each `SKILL.md` must include YAML frontmatter with: +`SKILL.md` must include YAML frontmatter with: - `name` - `description` @@ -48,7 +62,7 @@ Auto-release determines semver bump from PR labels: - `release:minor` -> minor bump - no label -> patch bump -## Release Policy +## Release policy Releases are controlled by `.release-policy.yml`. diff --git a/evals/gecode-trigger-evals.json b/evals/gecode-trigger-evals.json new file mode 100644 index 0000000..f2931dd --- /dev/null +++ b/evals/gecode-trigger-evals.json @@ -0,0 +1,62 @@ +[ + { + "query": "I'm implementing a cumulative-style constraint in Gecode and the decomposition is too weak. I think I need a custom propagator with better domain filtering. Can you sketch the post/propagate structure and what propagation conditions I should subscribe to?", + "should_trigger": true + }, + { + "query": "I need a custom Gecode brancher for a packing model where the second alternative should encode a symmetry-breaking exclusion. How should I structure the choice payload and commit logic so recomputation stays safe?", + "should_trigger": true + }, + { + "query": "My Gecode model solves, but BAB is crawling. Help me decide whether to stay on BAB, switch to restart-based search, or diversify with PBS. I also want to understand the completeness tradeoffs.", + "should_trigger": true + }, + { + "query": "Can you help debug a Gecode issue where a stored choice seems invalid after recomputation? The model uses custom branchers and I suspect I'm breaking clone or commit invariants.", + "should_trigger": true + }, + { + "query": "Please model this scheduling problem in Gecode with strong global constraints, sensible symmetry breaking, and a branching strategy that focuses on the cost-driving variables first.", + "should_trigger": true + }, + { + "query": "My Gecode search tree exploded after I added a few side constraints. I need a debugging workflow for deciding whether the problem is weak propagation, bad branching, or missing symmetry breaking.", + "should_trigger": true + }, + { + "query": "I want a cookbook-style answer for modeling a Gecode optimization problem with channeling, a couple of implied constraints, and a clean brancher order. Think recipe, not theory.", + "should_trigger": true + }, + { + "query": "How should I model this warehouse assignment problem in Gecode if each customer can be assigned to a set of depots and I care about subset and cardinality structure? I think set vars might fit better than raw ints.", + "should_trigger": true + }, + { + "query": "I'm using Gecode with a mix of discrete choices and continuous tolerances. What should I watch out for when float vars are part of the model, especially compared with ordinary integer branching intuition?", + "should_trigger": true + }, + { + "query": "How would you model a nurse rostering problem in constraint programming? I'm open to any solver or even OR-Tools, I mainly want high-level CP advice.", + "should_trigger": false + }, + { + "query": "I'm debugging a C++ memory leak around std::shared_ptr and custom allocators. This is ordinary application code, not a solver, and I'm not using Gecode.", + "should_trigger": false + }, + { + "query": "Can you explain branch and bound versus depth-first search in general terms? I don't need implementation details for any particular library.", + "should_trigger": false + }, + { + "query": "What are good heuristics for graph coloring in CP, and how do I think about symmetry? Solver-agnostic advice is fine.", + "should_trigger": false + }, + { + "query": "My game engine is slow and I want advice on profiling frame spikes with Tracy and Instruments. This has nothing to do with constraint programming.", + "should_trigger": false + }, + { + "query": "I need help modeling a production schedule, but I'm doing it in CP-SAT and mostly want generic scheduling ideas, not Gecode-specific guidance.", + "should_trigger": false + } +] diff --git a/skills/gecode/SKILL.md b/skills/gecode/SKILL.md new file mode 100644 index 0000000..464f6bc --- /dev/null +++ b/skills/gecode/SKILL.md @@ -0,0 +1,70 @@ +--- +name: gecode +description: "Gecode architecture, modeling, cookbook-style modeling patterns, set/float/scheduling guidance, propagators, branchers, memory management, search engine usage and implementation, recomputation/cloning behavior, and debugging/performance diagnosis. Use for any materially Gecode-specific task: building or refining Gecode models, implementing custom constraints or branchers, tuning DFS/BAB/RBS/PBS/LDS search, diagnosing weak propagation or search pathologies, or reasoning about set/float/resource-style models." +--- + +# Gecode + +Use this skill as the entry point for any Gecode-specific task. Carry the universal Gecode runtime model in mind for every response, then load only the additional reference files needed for the task. + +## Always-On Mental Model +- Space is the home for variables, propagators, branchers, and optimization order. +- Propagation is explicit: call `status()`. +- Search primitives are `status()`, `choice()`, `clone()`, `commit()`, and `constrain()`. +- Space status values are `SS_FAILED`, `SS_SOLVED`, and `SS_BRANCH`. +- Choice is a space-independent descriptor; alternatives are indexed `0..n-1`. +- Choice compatibility is clone-based: a choice is valid for its source space and clones. +- `choice()` invalidates previous choices for later `commit()` on that space. +- Clone only stable, non-failed spaces. +- Branchers run in posting order. +- Recomputation can be nondeterministic with weakly monotonic propagation while remaining sound and complete. +- Model as `class M : public Space`, implement copy constructor and virtual `copy()`, and update variable arrays with `x.update(home, s.x)` during cloning. +- After `status()==SS_BRANCH`, compute `choice()` immediately. +- Treat returned solutions as owned `Space` objects and delete seed models, choices, and solution spaces explicitly. +- Do not assume posting performs full propagation. +- Do not call the `Space` copy constructor directly instead of `clone()`. +- Do not reuse stale choices after another `choice()` call. + +## Default Gecode Heuristics +- Tighten variable domains as early as possible. +- Prefer global constraints over weak manual decompositions. +- Keep branching explicit and problem-specific rather than relying on generic defaults. +- Treat symmetry handling as first-class design work. +- Use `DFS` as the baseline complete search engine. +- Use `BAB` for optimization unless there is a concrete reason to move to restart or portfolio search. +- Treat restart, portfolio, and parallel search behavior as intentionally nondeterministic. +- Remember that clone footprint matters when designing actor state and cached data. +- Use explicit disposal discipline for external or heap-backed resources. + +## Routing +- Read `references/modeling.md` for model structure, variables, constraints, branching setup, and built-in search configuration. +- Read `references/modeling-cookbook.md` when the user needs concrete recipe-style guidance for channeling, symmetry, branching, optimization setup, or choosing globals versus decompositions. +- Read `references/debugging-workflow.md` for weak propagation, exploding search trees, stale choices, recomputation bugs, memory growth, or tracing/profiling workflow. +- Read `references/set-and-float-modeling.md` for set-variable modeling, float-specific caveats, or mixed-domain modeling. +- Read `references/scheduling-patterns.md` for cumulative/resource-style models, sequencing/order constraints, and scheduling-oriented branching or symmetry choices. +- Read `references/propagator-implementation.md` for custom propagator design, posting, propagation lifecycle, advisors, and rewriting. +- Read `references/brancher-implementation.md` for custom branchers, choices, commits, archiving, and NGL support. +- Read `references/memory-handling.md` for space/region/heap allocation, handles, clone footprint, and disposal obligations. +- Read `references/search-engines.md` for using and tuning built-in engines such as `DFS`, `BAB`, `LDS`, restart, and portfolio search. +- Read `references/search-engine-implementation.md` for custom engine orchestration, recomputation strategy, LAO, and completeness invariants. +- Read `references/general-knowledge.md` only for broad conceptual explanations, tracing/observability guidance, or staged model-improvement workflow discussion that goes beyond the always-on mental model. + +## Operating Rules +- Read only the reference file or files needed for the current task. +- Combine references only when the task genuinely crosses boundaries, such as a custom propagator with nontrivial memory strategy or a search-engine bug tied to choice compatibility. +- Prefer the narrowest useful reference set first, then expand if the user asks for adjacent concerns. +- Keep answers Gecode-specific. If the request is generic CMake, generic C++ memory, or generic CP theory without a real Gecode angle, do not over-apply this skill. +- Use this `SKILL.md` alone for broad explanations, initial modeling guidance, and many runtime/debugging answers before reaching for extra references. + +## Reference Index +- `references/general-knowledge.md`: advanced observability, staged improvement workflow, and broad conceptual framing beyond the always-on core. +- `references/modeling.md`: variable selection, globals, reification, symmetry, branching, and search setup in ordinary models. +- `references/modeling-cookbook.md`: concrete modeling recipes for globals, channeling, symmetry, branching, optimization, and “propagation versus search” decisions. +- `references/debugging-workflow.md`: symptom-driven diagnosis for weak models, stale choices, recomputation issues, performance pathologies, and observability tooling. +- `references/set-and-float-modeling.md`: set-variable patterns, float-specific caveats, and mixed-domain modeling reminders. +- `references/scheduling-patterns.md`: scheduling/resource modeling patterns, sequencing constraints, and search guidance for schedule-like problems. +- `references/propagator-implementation.md`: actor lifecycle, `ExecStatus`, propagation conditions, iterators, advisors, and rewrite patterns. +- `references/brancher-implementation.md`: `status`, `choice`, `commit`, archive compatibility, NGLs, and heuristic encoding. +- `references/memory-handling.md`: memory areas, lazy vs eager allocation, shared/local handles, and `AP_DISPOSE` discipline. +- `references/search-engines.md`: engine selection, restart/portfolio tradeoffs, no-goods, parallel semantics, and completeness caveats. +- `references/search-engine-implementation.md`: custom engine state, replay/recomputation, ownership, branch-and-bound integration, and invariants. diff --git a/skills/gecode/agents/openai.yaml b/skills/gecode/agents/openai.yaml new file mode 100644 index 0000000..c1973fe --- /dev/null +++ b/skills/gecode/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Gecode" + short_description: "Route any Gecode task to the right internal reference" + default_prompt: "Handle this Gecode-specific task by reading only the relevant internal reference files, then provide concise, technically accurate guidance." diff --git a/skills/gecode/references/brancher-implementation.md b/skills/gecode/references/brancher-implementation.md new file mode 100644 index 0000000..cf38a25 --- /dev/null +++ b/skills/gecode/references/brancher-implementation.md @@ -0,0 +1,33 @@ +# Gecode Brancher Implementation + +## Core +- Brancher is the actor that implements branching behavior. +- Implement `status`, `choice(Space&)`, `choice(const Space&, Archive&)`, `commit`, `print`, `copy`, and `dispose`. +- Choice stores only space-independent commit data. +- `commit` must work with recomputed or cloned spaces using only the choice payload. +- Choices must be archive-compatible and deterministic. +- Branchers execute in queue order of posting. +- Optional `ngl()` adds no-good support. +- `status()==false` does not imply immediate disposal; commits for earlier choices must remain valid. + +## Key Patterns +- Track the first candidate index such as `start` to avoid rescanning. +- Keep the choice payload minimal, for example `pos`, `val`, and alternative count, and archive it deterministically. +- Use binary alternatives such as `eq` versus `nq` unless an assignment brancher genuinely needs a single alternative. +- Implement an NGL class with `status`, `prune`, `subscribe`, `cancel`, and `reschedule`. +- For complementary last alternatives, `ngl()` can return `NULL` when that is semantically valid. +- Reuse branchers through views, notably minus views for max-style variants. +- Encode the problem heuristic explicitly, such as Warnsdorff or best-fit slack. +- Mix assignment-style one-alternative choices with pruning alternatives only when the heuristic justifies it. +- Design second alternatives to embed symmetry breaking when safe. +- Pair the brancher with branch print callbacks for explainability and debugging. + +## Pitfalls +- Storing views or pointers to space state inside choice objects. +- Disposing the brancher too early when `status()` becomes false. +- Depending on mutable brancher state not encoded in the choice for `commit()`. +- Using choices after invalidation by a later `choice()` call on the same space. +- Not skipping assigned views, causing repeated same choice or an infinite tree. +- Violating recomputation invariants and commit-order assumptions. +- Using generic variable-value branching when a structure-aware heuristic is required. +- Forgetting that brancher disposal is not automatic when external resources exist. diff --git a/skills/gecode/references/debugging-workflow.md b/skills/gecode/references/debugging-workflow.md new file mode 100644 index 0000000..b3b3055 --- /dev/null +++ b/skills/gecode/references/debugging-workflow.md @@ -0,0 +1,41 @@ +# Gecode Debugging Workflow + +## Symptom: Search Tree Explodes +- First ask whether the model is weak or the branching is weak; the fix is often different. +- Check initial domains, missing implied constraints, and whether a stronger global can replace a weak decomposition. +- Compare nodes and failures before and after modeling changes; do not trust runtime alone. +- If propagation looks adequate but the tree is still huge, inspect branching order, value choice, and symmetry breaking. +- Use `DFS` as a baseline before judging restart or portfolio search. + +## Symptom: Branching or Recomputation Looks Wrong +- Suspect stale choices if behavior changes after another `choice()` call on the same space. +- Recheck choice compatibility: choices must be valid only for the originating space and its clones. +- Confirm `commit()` uses only archived, space-independent choice payload. +- If a bug appears only after deeper search, compare direct-clone behavior versus replayed recomputation behavior. +- When a custom brancher is involved, inspect queue order, assigned-view skipping, and brancher disposal timing. + +## Symptom: Propagation Is Wrong or Too Weak +- Separate correctness bugs from strength issues. Wrong answers or unexplained failure usually mean correctness; huge trees with valid answers usually mean weak propagation. +- Re-check subscriptions, propagation conditions, and whether the propagator actually reaches fixpoint when it should. +- Replace weak decompositions with stronger globals or a dedicated propagator when two ordinary constraints do not reason jointly enough. +- Use advisor-based localization only when the extra complexity is justified by change locality. +- If reification is involved, verify the exact semantics of the chosen decomposition rather than assuming the control literal forces a benign fallback. + +## Symptom: Memory or Clone Footprint Is Too Large +- Inspect what state is copied into every clone and move resize-heavy data away from space memory when appropriate. +- Prefer lazy construction for heavy internal state when many branches will never need it. +- Check external-resource ownership and `AP_DISPOSE` discipline before assuming the issue is search alone. +- Watch for per-choice heap allocations in hot paths, especially inside custom branchers. +- If recomputation is cheaper than cloning the current state, revisit search options and state layout together. + +## Observability Tools +- Use groups and tracing to narrow which parts of the model or search are active at the wrong time. +- Use Gist or CPProfiler when you need to see search-tree shape, branching behavior, and failure concentration rather than just counters. +- Measure nodes, failures, restarts, and memory-related symptoms alongside runtime. +- Improve in loops: baseline, strengthen propagation, improve branching, then tune search and memory strategy. + +## Escalation Paths +- For custom propagation mechanics, continue into `propagator-implementation.md`. +- For stale-choice, commit, or NGL issues, continue into `brancher-implementation.md`. +- For memory ownership and clone-footprint problems, continue into `memory-handling.md`. +- For restart, no-good, and completeness behavior, continue into `search-engines.md` or `search-engine-implementation.md` depending on whether you are using or implementing engines. diff --git a/skills/gecode/references/general-knowledge.md b/skills/gecode/references/general-knowledge.md new file mode 100644 index 0000000..f414afc --- /dev/null +++ b/skills/gecode/references/general-knowledge.md @@ -0,0 +1,11 @@ +# Gecode General Knowledge + +## Advanced Framing +- Use groups and tracing for observability and selective control. +- Improve models in loops: baseline, stronger propagation, better branching, then tuned search. +- Measure with nodes, time, and restarts, not runtime alone. +- Treat symmetry handling as a first-class design concern, not post-processing. + +## Conceptual Pitfalls +- Assuming parallel search preserves sequential solution order or runtime profile. +- Assuming one modeling pass is enough; most nontrivial case studies need staged refinement. diff --git a/skills/gecode/references/memory-handling.md b/skills/gecode/references/memory-handling.md new file mode 100644 index 0000000..fd8b91a --- /dev/null +++ b/skills/gecode/references/memory-handling.md @@ -0,0 +1,32 @@ +# Gecode Memory Handling + +## Core +- Memory areas are space, region, heap, and space freelists. +- `alloc`, `realloc`, and `free` follow C++ object lifecycle semantics. +- Space memory is reclaimed automatically on space deletion and fits stable-size actor data. +- Region is a temporary arena with implicit free on region destruction. +- Heap is for frequently resized or dynamic structures. +- Search memory profile favors pristine clones, so allocation timing matters. +- Shared handles point to cross-space or cross-thread shared heap objects with reference counting. +- Local handles point to per-space shared objects copied on cloning. + +## Key Patterns +- Allocate fixed actor members in home space. +- Allocate resize-heavy buffers on the heap and free them in `dispose()`. +- Build heavy internal state lazily on first propagation when possible. +- Choose eager, lazy, or hybrid allocation based on clone footprint and expected hit rate. +- Use regions for short-lived iterators and temporary buffers. +- Call `Region::free()` at clear control-flow boundaries to maximize reuse. +- Use `SharedHandle` for immutable or global lookup data. +- Use `LocalHandle` for shared per-space mutable state. +- Use `IntSharedArray` or related shared arrays for read-only large data reused across clones. +- For brancher choices using heap buffers, pair allocation and free, and register `AP_DISPOSE`. +- Use `Region` for per-choice scratch arrays to avoid heap churn. + +## Pitfalls +- Frequent resize in space memory causing fragmentation. +- Forgetting `home.notice(..., AP_DISPOSE)` for external or heap resources. +- Forgetting the matching `home.ignore(..., AP_DISPOSE)` in the dispose path. +- Assuming identical alignment guarantees across space, heap, and region memory. +- Leaking ownership assumptions across cloning boundaries. +- Allocating per-choice temporary arrays on the heap in hot paths. diff --git a/skills/gecode/references/modeling-cookbook.md b/skills/gecode/references/modeling-cookbook.md new file mode 100644 index 0000000..e56f69c --- /dev/null +++ b/skills/gecode/references/modeling-cookbook.md @@ -0,0 +1,36 @@ +# Gecode Modeling Cookbook + +## Strong Initial Domains +- Start with the tightest semantically correct domains you can justify; domain width is often the first-order search cost. +- Introduce helper variables only when they buy propagation, symmetry handling, or cleaner branching. +- Reuse shared arrays and tuple sets when structure repeats across many constraints. + +## Globals Versus Decompositions +- Prefer globals such as `distinct`, `count`, `binpacking`, `circuit`, or `extensional` when they capture the intended structure directly. +- Decompose only when there is no suitable global or when the decomposition is easier to maintain and the propagation loss is acceptable. +- When a decomposition is kept for simplicity, add implied constraints that recover some lost strength. + +## Channeling and Reification +- Use channeling when two views of the same decision space support different strong constraints or different branchers. +- Keep reification semantics explicit: full reification, half reification, and decomposed reification behave differently under failure. +- If Boolean control logic starts dominating the model, verify that the introduced structure is paying for its propagation cost. + +## Symmetry Templates +- Break symmetry structurally before trying heuristic tricks. +- Use anchors, ordering constraints, `precede`, or canonical placement rules to collapse equivalent solutions early. +- Re-check symmetry assumptions when mixing LDSB with static symmetry breaking or custom branchers. + +## Branching Playbooks +- Put branchers in intentional order; creation order matters. +- For optimization models, branch first on variables that drive the objective or major feasibility bottlenecks. +- When a generic brancher underperforms, ask whether the issue is value choice, variable choice, or missing model structure before jumping to a custom brancher. + +## Optimization Setup +- Use `BAB` as the default exact optimization engine. +- If best-solution search stalls, improve bounds and cost-driving propagation before assuming a different engine will rescue the model. +- Tune restart or portfolio search only after you understand the baseline `DFS` or `BAB` behavior. + +## Propagation Versus Search +- If failures come late and trees are wide, strengthen propagation first. +- If failures are early but node count is still high, the model may be fine and the branching may be poor. +- When a model already has strong globals and tight domains, branching quality often dominates the next gain. diff --git a/skills/gecode/references/modeling.md b/skills/gecode/references/modeling.md new file mode 100644 index 0000000..146a6cd --- /dev/null +++ b/skills/gecode/references/modeling.md @@ -0,0 +1,45 @@ +# Gecode Modeling + +## Related References +- Read `modeling-cookbook.md` for recipe-style modeling patterns and concrete construction templates. +- Read `set-and-float-modeling.md` when the task depends on set vars, float vars, or mixed-domain behavior. +- Read `scheduling-patterns.md` for cumulative/resource-style models and sequencing-heavy schedules. + +## Core +- Define the model as a `Space` subclass. +- Create typed variable arrays with tight domains early. +- Post constraints via post functions such as `rel`, `linear`, `distinct`, and the set/float variants. +- Post branching via `branch(...)`; variable and value strategy together define the tree shape. +- Use search engines such as `DFS`, `BAB`, or restart/portfolio variants according to the objective. +- MiniModel adds expression syntax via `expr(...)`, `rel(...)`, and matrix/channel helpers. +- Reified modeling supports full and half reification; decomposition semantics matter. + +## Key Patterns +- Prefer global constraints over manual decompositions when available. +- Keep branchings explicit and problem-specific for scale. +- Use multiple branchers intentionally; creation order matters. +- Tune search options such as recomputation distance, restarts, no-goods, and stop objects. +- Use tracing, Gist, or CPProfiler for diagnostics. +- Add implied constraints when semantics stay unchanged but propagation improves. +- Break symmetry structurally with order constraints, fixed anchors, `precede`, or monotone bins. +- Use LDSB only with supported branching and value configurations, and validate symmetry assumptions. +- Match propagation level to complexity; use `IPL_DOM` only where the payoff exceeds the cost. +- Replace weak decompositions with stronger globals such as `count`, `binpacking`, `circuit`, or `extensional`. +- Cache reusable heavy artifacts such as tuple sets or shared arrays keyed by shape and parameters. +- For arrays requiring non-shared variables, call `unshare(...)` once and reuse the result. +- Use branch filters and print functions for targeted branching and observability. +- When executing code between branchers, remember propagation is still explicit on recomputation paths. +- For optimization models, branch on cost-driving variables first and tie-break with objective structure. + +## Pitfalls +- Weak domains at model start causing huge trees. +- Forgetting to update every variable member in the cloning constructor. +- Assuming MiniModel nonlinear expressions stay monolithic; many decompose. +- Assuming reified non-functional decompositions imply `b=false`; they can fail instead. +- Treating Boolean variables as a subclass of integer variables. +- Ignoring exceptions from invalid arguments or overflow. +- Using domain propagation for `linear` indiscriminately when it can be exponential. +- Recomputing identical tuple sets or shared maps per post. +- Repeated implicit unsharing patterns that create unnecessary variables and propagators. +- Combining LDSB with unrelated static symmetry breaking without safety analysis. +- Leaving major value or variable symmetries unbroken. diff --git a/skills/gecode/references/propagator-implementation.md b/skills/gecode/references/propagator-implementation.md new file mode 100644 index 0000000..c6afa08 --- /dev/null +++ b/skills/gecode/references/propagator-implementation.md @@ -0,0 +1,35 @@ +# Gecode Propagator Implementation + +## Core +- Propagators compute on views, not model variables. +- Implement a post function and the actor lifecycle: `copy`, `dispose`, `cost`, `reschedule`, and `propagate`. +- Use `Home` for posting context and use fail/check macros. +- Return honest `ExecStatus`: `ES_FAILED`, `ES_SUBSUMED`, `ES_FIX`, or `ES_NOFIX`. +- Respect obligations around correctness, checking, contracting, monotonicity or waived monotonicity, subscription completeness, and update completeness. +- Respect implementation obligations: subsumption complete, cloning conservative, and subscription correct. +- Use standard patterns such as `Unary`, `Binary`, `Ternary`, `Nary`, or mixed variants to reduce boilerplate. + +## Key Patterns +- Do cheap pruning in `post()` and skip posting when already subsumed or failed. +- Select the weakest sound propagation condition: `*_VAL`, `*_BND`, or `*_DOM`. +- Prefer iterator-based domain operations such as `inter_r`, `narrow_r`, or `minus_r` for domain propagation. +- Use fixpoint reasoning deliberately; return `ES_FIX` only when justified. +- Use `ModEventDelta` and staging to combine cheap and expensive propagation phases. +- Use advisors for incremental change localization. +- Maintain council lifecycle correctly when advisors are present, including rescheduling and subscription completeness. +- Rewrite propagators with `GECODE_REWRITE` when state simplifies enough to switch representation. +- Use reified and rewriting patterns to remove reification overhead once control literals decide the mode. +- Template propagators on view types for reuse. +- If decomposition is propagation-weak, prefer a dedicated propagator or an extensional surrogate. +- Treat expensive support data as a cacheable object rather than recomputing it per post. + +## Pitfalls +- Modifying a view while iterating its domain iterator. +- Returning `ES_FIX` when the propagator is not actually at fixpoint. +- Returning `ES_NOFIX` when the propagator is idempotent and could finish inside the same `propagate()` call. +- Missing view updates or subscription cancellation during cloning or disposal. +- Using external resources without `AP_DISPOSE` notice/ignore discipline. +- Continuing execution after subsuming or disposing the actor. +- Failing to check modification-event failure after view updates. +- Breaking subscription completeness when using advisors or dynamic subscriptions. +- Expecting two weak propagators such as `distinct` plus `linear` to match the joint reasoning of one stronger constraint. diff --git a/skills/gecode/references/scheduling-patterns.md b/skills/gecode/references/scheduling-patterns.md new file mode 100644 index 0000000..fa1c797 --- /dev/null +++ b/skills/gecode/references/scheduling-patterns.md @@ -0,0 +1,22 @@ +# Gecode Scheduling Patterns + +## Resource-Style Models +- Start with the tightest time windows, durations, and resource bounds you can justify. +- Prefer cumulative or other structure-aware scheduling constraints over hand-built overlap decompositions when the resource semantics are standard. +- Add obvious implied constraints such as precedence, release/deadline tightening, or resource-balance bounds when they strengthen propagation without changing semantics. + +## Sequencing and Ordering +- Use explicit sequencing or order constraints when the model’s main difficulty is relative position rather than raw resource usage. +- Anchor interchangeable tasks or machines when symmetry would otherwise multiply equivalent schedules. +- When setup or transition structure matters, make it explicit in the model rather than burying it inside a weak objective. + +## Branching Guidance +- Branch first on bottleneck tasks, scarce resources, or tasks that most affect the objective. +- Prefer branchers that expose schedule structure over generic variable-value selection when the schedule has obvious critical-path or packing bottlenecks. +- If a schedule model has wide windows and weak propagation, strengthen the model before inventing a custom search strategy. + +## Common Failure Modes +- Weak overlap decompositions that fail to propagate resource pressure. +- Symmetric machines or interchangeable tasks creating huge equivalent subtrees. +- Objective-driven search without enough feasibility structure, causing the engine to explore many nearly identical schedules. +- Diagnosing schedule problems only by runtime rather than failures, nodes, and where the tree actually branches. diff --git a/skills/gecode/references/search-engine-implementation.md b/skills/gecode/references/search-engine-implementation.md new file mode 100644 index 0000000..235dc06 --- /dev/null +++ b/skills/gecode/references/search-engine-implementation.md @@ -0,0 +1,33 @@ +# Gecode Search Engine Implementation + +## Core +- Implement engines against the `Space` interface: `status`, `choice`, `clone`, and `commit`. +- Maintain explicit ownership for all `Space*` and `Choice*` objects. +- Respect compatibility invariants: choices are valid only for clone-related spaces. +- Treat `choice()` as invalidating earlier choices on that space. +- Handle all `SpaceStatus` cases: `SS_FAILED`, `SS_SOLVED`, and `SS_BRANCH`. + +## Key Patterns +- Keep a clear split between exploration mode and recomputation mode. +- Use edge or path state to store choices, alternatives, and optional clones. +- For recomputation, replay commits from the nearest stored clone or the root clone. +- Apply LAO, the last-alternative optimization, to avoid unnecessary stored choices and commits. +- Use hybrid recomputation with a commit distance to cap replay cost. +- Use adaptive recomputation to add clones where repeated failures show that recomputation is too expensive. +- Integrate branch-and-bound by constraining future spaces against the current best solution. +- Keep restart and meta-engine hooks explicit, such as `master` and `slave`, when required. +- Wire statistics and stop-object checks consistently. + +## Pitfalls +- Reusing stale choices after another `choice()` call. +- Mixing incompatible choices and spaces and triggering `SpaceNoBrancher`. +- Forgetting to delete choices and returned solution spaces. +- Assuming deterministic node order under parallel execution. +- Overusing no-good depth without accounting for memory and LAO tradeoffs. +- Reporting completeness when stop, cutoff, or meta-engine policy makes the run incomplete. + +## Invariants +- Recomputed spaces must follow the same decision path as the stored edge choices. +- Commit order must match original choice generation order. +- If recomputation fails due to nondeterminism or weak monotonicity effects, recover path state safely and continue search. +- Cloning and copying must never mutate model state outside the allowed operations. diff --git a/skills/gecode/references/search-engines.md b/skills/gecode/references/search-engines.md new file mode 100644 index 0000000..65bf86b --- /dev/null +++ b/skills/gecode/references/search-engines.md @@ -0,0 +1,38 @@ +# Gecode Search Engines + +## Core +- This reference is for using built-in engines, not implementing custom engines. +- Base engines are `DFS`, `BAB`, and `LDS`. +- Meta engines are `RBS` for restart-based search and `PBS` for portfolio-based search. +- Key options live in `Search::Options`, including `threads`, `c_d`, `a_d`, `clone`, `stop`, `cutoff`, `nogoods_limit`, `assets`, `slice`, and `tracer`. +- For optimization, use `BAB`-style search with a valid model-side objective and constrain setup. + +## Key Patterns +- Use `DFS` for baseline complete search and enumeration. +- Use `BAB` for best-solution search. +- Use `LDS` when the branching heuristic is strong and discrepancy-ordered exploration is desirable. +- Use `RBS` to improve robustness through cutoffs, restart policies, and optional no-goods. +- Use `PBS` to improve robustness through asset diversification across heuristics, models, engines, or options. +- In restart search, let `master()` decide restart behavior and optional no-good posting. +- In restart search, let `slave()` signal completeness intentionally: `true` for complete slave search, `false` for deliberate incompleteness such as LNS neighborhoods. +- In portfolio search, remember `slave()` return value has no meaning. +- For restart-based best-solution assets in portfolios, use `RBS`. +- Diversify assets intentionally; identical assets rarely justify portfolio overhead. + +## Pitfalls +- Expecting deterministic behavior from restart, portfolio, or parallel runs. +- Treating restart or portfolio search as complete when stop conditions, cutoffs, or `slave()==false` make the run incomplete. +- Forgetting to diversify assets and then expecting portfolio gains. +- Assuming no-goods are always available or effective regardless of brancher mix and parallelism. +- Forgetting that `master()` and `slave()` policy choices directly change search completeness and restart behavior. + +## No-Good and Parallel Nuances +- Restart no-goods are available from `DFS` and `BAB`, not `LDS`. +- Enable no-goods with `nogoods_limit > 0`; depth is a memory-versus-benefit tradeoff. +- Larger no-good depth limits reduce LAO effectiveness near the root and can raise memory use significantly. +- Not all branchers support no-goods; float branchers and execution branchers do not. +- Parallel search usually yields fewer extractable no-goods. +- Parallel search is intentionally nondeterministic in solution order, node counts, and runtime. +- In portfolios, `assets` and `threads` are allocated conservatively. +- Sequential portfolios use failure slices via `slice` for round-robin asset scheduling. +- With `threads > assets`, extra threads can be used inside asset engines. diff --git a/skills/gecode/references/set-and-float-modeling.md b/skills/gecode/references/set-and-float-modeling.md new file mode 100644 index 0000000..99ba1a6 --- /dev/null +++ b/skills/gecode/references/set-and-float-modeling.md @@ -0,0 +1,23 @@ +# Gecode Set and Float Modeling + +## Set Variables +- Model set variables when membership, subset, cardinality, or partition structure is the natural shape of the problem. +- Keep lower and upper bounds on sets tight; loose envelope sets behave like wide integer domains and weaken propagation. +- Use cardinality constraints aggressively when the set size matters; they often provide the missing structure for branching and propagation. +- Channel set decisions to integer or Boolean views only when another constraint family becomes substantially stronger through that representation. + +## Float Variables +- Treat float models differently from integer models: propagation is approximate, and branching intuition from integer domains often does not transfer directly. +- Use float variables when the problem is genuinely continuous or mixed continuous/discrete, not just because integer scaling feels inconvenient. +- Be careful with no-good assumptions and search behavior: not all branchers or search features available for integer models carry over the same way for float-heavy models. +- Inspect tolerances, bounds, and objective semantics before concluding that a float model is “wrong.” + +## Mixed-Domain Reminders +- Keep the reason for each domain type explicit; mixed-domain models become hard to debug when variables exist only as translation artifacts. +- Channel across domains only when it enables stronger pruning, clearer objectives, or better branching. +- Re-check clone footprint and cache layout when mixed-domain support data becomes large. + +## When Integer Intuition Fails +- Do not assume set or float domains shrink in the same way that integer intervals do. +- Do not assume the strongest-looking branching is best; mixed-domain models often need problem-structure-aware branching more than aggressive generic branching. +- When propagation quality is hard to judge, compare behavior on a tiny instance with tracing or profiling before scaling up.