181 lines
5.6 KiB
Markdown
181 lines
5.6 KiB
Markdown
|
|
# AGENTS.md
|
||
|
|
|
||
|
|
This file provides guidance to coding agents collaborating on this repository.
|
||
|
|
|
||
|
|
## Mission
|
||
|
|
|
||
|
|
Chase-rs is an efficient implementation of the chase algorithm in Rust for advanced reasoning engines.
|
||
|
|
Priorities, in order:
|
||
|
|
|
||
|
|
1. Correctness of reasoning (sound and complete chase).
|
||
|
|
2. Termination guarantees (restricted chase for existential rules).
|
||
|
|
3. Performance and scalability.
|
||
|
|
4. Clear, maintainable, idiomatic Rust code.
|
||
|
|
|
||
|
|
## Core Rules
|
||
|
|
|
||
|
|
- Use English for code, comments, docs, and tests.
|
||
|
|
- Keep all chase state inside well-defined structs; avoid global mutable state.
|
||
|
|
- Prefer small, focused changes over large refactoring.
|
||
|
|
- Add comments only when they clarify non-obvious behavior.
|
||
|
|
- Follow Rust idioms: use `Result` for errors, iterators over manual loops, etc.
|
||
|
|
|
||
|
|
Quick examples:
|
||
|
|
|
||
|
|
- Good: add a new chase variant by implementing a trait or strategy pattern.
|
||
|
|
- Bad: add global configuration that affects all chase instances.
|
||
|
|
|
||
|
|
## Repository Layout
|
||
|
|
|
||
|
|
- `src/`: core implementation.
|
||
|
|
- `src/chase/`: chase algorithm modules.
|
||
|
|
- `term.rs`: terms (constants, nulls, variables).
|
||
|
|
- `atom.rs`: atoms (predicate applied to terms).
|
||
|
|
- `instance.rs`: database instance (set of facts).
|
||
|
|
- `rule.rs`: TGDs (tuple-generating dependencies).
|
||
|
|
- `substitution.rs`: variable bindings and unification.
|
||
|
|
- `engine.rs`: core chase algorithm.
|
||
|
|
- `tests/`: integration, regression, and property-based tests.
|
||
|
|
|
||
|
|
## Architecture Constraints
|
||
|
|
|
||
|
|
- `Instance` holds the database state (set of ground atoms).
|
||
|
|
- `Rule` represents tuple-generating dependencies (TGDs).
|
||
|
|
- The chase engine is stateless; state is passed explicitly.
|
||
|
|
- New chase variants should be composable with existing infrastructure.
|
||
|
|
- Existential variables generate labeled nulls (`Term::Null`).
|
||
|
|
|
||
|
|
## Rust Conventions
|
||
|
|
|
||
|
|
- Target stable Rust (edition 2024, rust-version 1.92).
|
||
|
|
- Use `#[derive(...)]` for common traits where appropriate.
|
||
|
|
- Prefer `&str` over `String` in function parameters when ownership isn't needed.
|
||
|
|
- Use `impl Trait` for return types when the concrete type is an implementation detail.
|
||
|
|
- Run `cargo clippy` and address warnings before committing.
|
||
|
|
|
||
|
|
## Required Validation
|
||
|
|
|
||
|
|
Run these checks for any non-trivial change:
|
||
|
|
|
||
|
|
1. `cargo test` (all unit and integration tests)
|
||
|
|
2. `cargo clippy` (lint checks)
|
||
|
|
3. `cargo fmt --check` (formatting)
|
||
|
|
|
||
|
|
For performance-sensitive changes:
|
||
|
|
|
||
|
|
1. Add benchmarks if they don't exist
|
||
|
|
2. Compare before/after performance
|
||
|
|
|
||
|
|
## First Contribution Flow
|
||
|
|
|
||
|
|
Use this sequence for your first change:
|
||
|
|
|
||
|
|
1. Read `src/chase/mod.rs` and the relevant module files.
|
||
|
|
2. Implement the smallest possible code change.
|
||
|
|
3. Add or update tests that fail before and pass after.
|
||
|
|
4. Run `cargo test`.
|
||
|
|
5. Run `cargo clippy` and fix any warnings.
|
||
|
|
6. Update docs if public API behavior changed.
|
||
|
|
|
||
|
|
Example scopes that are good first tasks:
|
||
|
|
|
||
|
|
- Add tests for an edge case in unification.
|
||
|
|
- Implement a new utility method on `Instance` or `Atom`.
|
||
|
|
- Add support for equality-generating dependencies (EGDs).
|
||
|
|
- Improve error handling with proper `Result` types.
|
||
|
|
|
||
|
|
## Testing Expectations
|
||
|
|
|
||
|
|
- No chase logic change is complete without tests.
|
||
|
|
- Unit tests go in `#[cfg(test)] mod tests` within each module.
|
||
|
|
- Integration tests go in `tests/integration_tests.rs`.
|
||
|
|
- Regression tests for bug fixes go in `tests/regression_tests.rs`.
|
||
|
|
- Property-based tests go in `tests/property_tests.rs`.
|
||
|
|
- Do not merge code that breaks existing tests.
|
||
|
|
|
||
|
|
Minimal unit-test checklist:
|
||
|
|
|
||
|
|
1. Create an `Instance` with relevant facts.
|
||
|
|
2. Define rules using `RuleBuilder`.
|
||
|
|
3. Run `chase(instance, &rules)`.
|
||
|
|
4. Assert on `result.terminated`, `result.instance`, and derived facts.
|
||
|
|
|
||
|
|
Example test skeleton:
|
||
|
|
|
||
|
|
```rust
|
||
|
|
#[test]
|
||
|
|
fn test_example() {
|
||
|
|
let instance: Instance = vec![
|
||
|
|
Atom::new("Pred", vec![Term::constant("a")]),
|
||
|
|
].into_iter().collect();
|
||
|
|
|
||
|
|
let rule = RuleBuilder::new()
|
||
|
|
.when("Pred", vec![Term::var("X")])
|
||
|
|
.then("Derived", vec![Term::var("X")])
|
||
|
|
.build();
|
||
|
|
|
||
|
|
let result = chase(instance, &[rule]);
|
||
|
|
|
||
|
|
assert!(result.terminated);
|
||
|
|
assert_eq!(result.instance.facts_for_predicate("Derived").len(), 1);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Change Design Checklist
|
||
|
|
|
||
|
|
Before coding:
|
||
|
|
|
||
|
|
1. Confirm whether the change affects chase semantics or termination.
|
||
|
|
2. Identify affected tests.
|
||
|
|
3. Consider impact on API stability.
|
||
|
|
|
||
|
|
Before submitting:
|
||
|
|
|
||
|
|
1. Verify `cargo test` passes.
|
||
|
|
2. Verify `cargo clippy` has no warnings.
|
||
|
|
3. Ensure tests were added/updated where relevant.
|
||
|
|
|
||
|
|
## Review Guidelines (P0/P1 Focus)
|
||
|
|
|
||
|
|
Review output should be concise and only include critical issues.
|
||
|
|
|
||
|
|
- `P0`: must-fix defects (incorrect reasoning, non-termination, soundness bugs).
|
||
|
|
- `P1`: high-priority defects (likely functional bug, performance regression, API breakage).
|
||
|
|
|
||
|
|
Do not include:
|
||
|
|
|
||
|
|
- style-only nitpicks,
|
||
|
|
- praise/summary of what is already good,
|
||
|
|
- exhaustive restatement of the patch.
|
||
|
|
|
||
|
|
Use this review format:
|
||
|
|
|
||
|
|
1. `Severity` (`P0`/`P1`)
|
||
|
|
2. `File:line`
|
||
|
|
3. `Issue`
|
||
|
|
4. `Why it matters`
|
||
|
|
5. `Minimal fix direction`
|
||
|
|
|
||
|
|
## Practical Notes for Agents
|
||
|
|
|
||
|
|
- Prefer targeted edits over broad mechanical rewrites.
|
||
|
|
- If you detect contradictory repository conventions, follow existing code and update docs accordingly.
|
||
|
|
- When uncertain about correctness, add/extend tests first, then optimize.
|
||
|
|
- The chase algorithm has well-defined semantics; consult database theory literature if needed.
|
||
|
|
|
||
|
|
## Commit and PR Hygiene
|
||
|
|
|
||
|
|
- Keep commits scoped to one logical change.
|
||
|
|
- PR descriptions should include:
|
||
|
|
1. behavioral change summary,
|
||
|
|
2. tests added/updated,
|
||
|
|
3. performance impact (if applicable),
|
||
|
|
4. API changes (if any).
|
||
|
|
|
||
|
|
Suggested PR checklist:
|
||
|
|
|
||
|
|
- [ ] Tests added/updated for behavior changes
|
||
|
|
- [ ] `cargo test` passes
|
||
|
|
- [ ] `cargo clippy` has no warnings
|
||
|
|
- [ ] `cargo fmt` applied
|