Skip to content

Support static-body derived predicates#2

Merged
sunsided merged 2 commits into
mainfrom
feature/hanoi
Apr 25, 2026
Merged

Support static-body derived predicates#2
sunsided merged 2 commits into
mainfrom
feature/hanoi

Conversation

@sunsided
Copy link
Copy Markdown
Owner

Summary

Support PDDL :derived-predicates with static bodies — derived facts are computed once at ground time and materialised as regular facts in the initial state. No runtime, search, or heuristic code changes needed.

Before

StructureDef::Derived was silently ignored by the grounder. Domains using :derived-predicates loaded but derived rules had no effect.

After

  • New ground/derived.rs module with DerivedRule, DerivedRuleSet, collect, eval_gd, and expand_into_init
  • build_fact_universe emits derived head groundings alongside base predicates so action preconditions resolve fact IDs
  • expand_into_init evaluates each rule body against the init fact set and sets matching derived facts true
  • eval_gd is a dedicated boolean evaluator that understands and, or, not, imply, exists, forall, equality, and rejects fluent comparisons
  • Validation rejects: recursive rules, multi-layer (derived referencing derived), and rules referencing fluent predicates
  • New examples/pddl/hanoi-derived.pddl with optimal plan length 7, using is-peg and smaller as static rule bodies
  • 4 unit tests + 1 integration test

Outcome

All 90 tests pass (43 unit + 21 integration + 33 doctests). Existing hanoi.pddl behaviour is untouched.

Findings

  • Derived predicates not listed in :predicates still get their full Cartesian product of groundings via the build_fact_universe extension, so action preconditions referencing them resolve correctly.
  • add_derived_fact must handle facts that were already emitted by build_fact_universe (just set the init bit) as well as entirely new facts.
  • Derived rule bodies that reference fluents like on are rejected. The Hanoi-derived example works because can-place depends only on is-peg and smaller, both static.

Review Instructions

  1. Review ground/derived.rscollect validation logic, eval_gd quantifier handling, and expand_into_init flow
  2. Review ground/action.rs changes — build_fact_universe extension and insertion of expand_into_init call between init build and action grounding
  3. Verify examples/pddl/hanoi-derived.pddl solves to plan length 7 with the integration test
  4. Confirm existing tests are unaffected (especially original hanoi.pddl tests)

What:
- New ground/derived.rs module with DerivedRule, eval_gd, and expand_into_init
- build_fact_universe emits derived head groundings alongside base predicates
- expand_into_init evaluates rule bodies against init facts and materialises truths
- eval_gd handles and, or, not, imply, exists, forall, equality, and fluent comparison rejection
- 4 unit tests (happy-path, exists+equality, fluent-body rejection, recursion rejection)
- Integration test asserting plan length 7 on hanoi-derived.pddl
- New hanoi-derived.pddl example using is-peg and smaller as static rule bodies

Why:
- Support :derived-predicates PDDL requirement without runtime cost
- Static bodies are computed once at ground time; search and heuristics stay untouched

Findings:
- derived heads not listed in :predicates still get groundings via build_fact_universe extension
- add_derived_fact must set init bits for facts already emitted by build_fact_universe
Copilot AI review requested due to automatic review settings April 25, 2026 23:27
@sunsided sunsided self-assigned this Apr 25, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for PDDL :derived-predicates whose bodies are static, by evaluating them once during grounding and materializing the resulting derived facts into the initial state.

Changes:

  • Introduces ground/derived.rs to collect/validate derived rules and evaluate derived bodies (eval_gd) against the init fact set.
  • Extends fact-universe construction to include groundings for derived predicate heads, and expands derived facts into Task.init during grounding.
  • Adds a Hanoi derived-predicate example plus unit/integration tests to validate optimal plan length and validation behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
crates/miniplan/src/ground/derived.rs New derived-rule collection/validation, boolean GD evaluator, and init expansion logic
crates/miniplan/src/ground/action.rs Calls derived init expansion and adds derived head groundings to the fact universe
crates/miniplan/src/ground/formula.rs Exposes term_to_string for derived evaluation and documents quantifier limitations of DNF walking
crates/miniplan/src/ground.rs Registers the new derived module
examples/pddl/hanoi-derived.pddl New example domain/problem using a derived can-place predicate
crates/miniplan/tests/hanoi_derived.rs New integration test asserting optimal plan length (7)
README.md Updates feature matrix to mention derived predicates (static bodies)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/miniplan/tests/hanoi_derived.rs
Comment thread crates/miniplan/src/ground/derived.rs Outdated
Comment thread crates/miniplan/src/ground/derived.rs
Comment thread crates/miniplan/src/ground/derived.rs Outdated
Comment thread crates/miniplan/src/ground/derived.rs
Comment thread crates/miniplan/src/ground/derived.rs
Comment thread crates/miniplan/src/ground/action.rs
Comment thread examples/pddl/hanoi-derived.pddl
Before:
- Derived predicate head name collision with :predicates rejected valid domains
- Multi-layer validation only checked rules collected so far
- Fluent extraction collected from effect conditions, not just primitive effects
- Forall handling ignored nested When/Forall in conditional effects
- Quantifier bindings appended to outer bindings, causing shadowing bugs
- Derived rules collected twice: in build_fact_universe and expand_into_init
- hanoi-derived.pddl had type mismatch in smaller predicate

After:
- Remove collision check; derived heads may appear in :predicates (standard PDDL)
- First pass collects all derived head names before validating
- extract_fluent_names only inspects primitive effects
- Recursive collect_pred_names_in_conditional_effect handles all variants
- ext_bindings prepended before bindings so inner bindings override
- Derived rules collected once in ground() and passed to both consumers
- smaller predicate accepts (disc, location) to match derived rule body

Why:
- Address all 8 PR review comments on PR #2
@sunsided sunsided merged commit a2af964 into main Apr 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants