Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clips-bindings

Safe, idiomatic Rust bindings for the CLIPS 6.4.2 embedding API.

The FFI layer is written by hand rather than emitted by a code generator: there is no bindgen output, and the only C compiled into the crate is the unmodified CLIPS source tree plus one layout-verification file. The unsafe layer is private; the public API uses RAII, typed values, explicit errors, and lifetimes that prevent CLIPS-owned values from outliving their environment.

Coverage

Environment lifecycle and execution, typed evaluation, value creation, multifields, direct function calls, facts, COOL instances and message dispatch, typed builders and modifiers, and typed lookup and iteration for every construct family. Agenda and focus control, rule match summaries, module lists, and construct metadata including class slot descriptors, method restrictions, and template constraints. Panic-contained Rust user-defined functions and I/O routers, lifecycle hooks covering reset, clear, periodic, cleanup, binary load, module change, rule firing, fact changes, and saving, plus parser diagnostics. Text and binary persistence for constructs, facts, and instances, watch and dribble control, and memory statistics.

docs/coverage.md maps Advanced Programming Guide sections 3–12 to the Rust API, including what is intentionally not bound and why.

Building

The crate does not vendor CLIPS. Point CLIPS_SOURCE_DIR at a CLIPS 6.4.2 source root or its core directory:

CLIPS_SOURCE_DIR=/path/to/clips_core_source_642 cargo build

The variable is required: the build never guesses where CLIPS lives, because building against the wrong tree would compile cleanly and then misbehave at run time. To avoid repeating it, set it once in .cargo/config.toml:

[env]
CLIPS_SOURCE_DIR = "/path/to/clips_core_source_642"

The build reads VERSION_STRING from the source tree and refuses anything other than 6.4.2, because the declarations are audited against that release only.

The one exception is documentation: when DOCS_RS is set, build.rs skips the C build entirely, because rustdoc never links and the docs.rs sandbox has no CLIPS tree. This affects cargo doc on docs.rs only; every real build still requires the variable.

Only 64-bit macOS and Linux are configured; other targets fail the build rather than guessing platform defines.

Usage

use clips_bindings::{Environment, Result};

fn main() -> Result<()> {
    let mut environment = Environment::new()?;
    environment.build("(deftemplate person (slot name) (slot age))")?;

    let fact = environment
        .fact_builder("person")?
        .symbol("name", "Ada")?
        .integer("age", 36)?
        .assert()?;

    assert_eq!(fact.slot("age")?.as_i64(), Some(36));
    Ok(())
}

Runnable examples:

cargo run --example rule_base
cargo run --example objects_and_messages
cargo run --example rust_extensions
cargo run --example persistence_and_hooks

Verification

cargo fmt --all -- --check
cargo test --offline
cargo clippy --all-targets --offline -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --offline --no-deps

The crate sets #![deny(missing_docs)], so an undocumented public item fails the build rather than reaching a release; building the documentation with -D warnings also catches broken intra-doc links.

The declarations in src/ffi.rs redeclare a handful of CLIPS structures by hand, and getting one wrong misreads memory the C code owns. cargo test therefore checks them against C rather than against constants: shim/abi_layout.c is compiled with the same target, dialect, and flags as the CLIPS sources and exports one sizeof/offsetof per field, which src/abi.rs compares to Rust's own size_of, align_of, and offset_of!. Neither side is transcribed from a header, so they cannot drift together in the same wrong direction.

This is the crate's only C file and the one exception to its Rust-only rule. It runs no code and CLIPS never calls it; it exists because Rust cannot compute a C struct's layout, and a hand-copied constant would verify the crate against its author's reading of a header rather than against the compiler.

Provenance

These bindings were produced by GPT 5.6 Sol and Claude Opus 5, working from analysis of the CLIPS 6.4.2 C sources and headers together with a synthesis of the Advanced Programming Guide. Nothing here was emitted by a binding generator: each declaration was written against the corresponding header prototype, and each safe wrapper against the documented behaviour of the routine beneath it.

Because that is a fallible process, the crate leans on verification rather than on the provenance of the code:

  • All 394 custom-written FFI declarations were audited against the parsed 6.4.2 header prototypes for return type and arity. That audit found a real defect — LoadFromString returns a bool, not an error code, which had inverted success and failure in load_str.
  • Struct layouts are checked against the C compiler that built CLIPS, not against transcribed constants, so the Rust and C sides cannot drift together.
  • Behavioural claims in the documentation are backed by tests against real CLIPS environments. Several claims were corrected when the tests contradicted them: the class defaults mode controls accessor creation rather than slot defaults, and neither halt flag survives a Run.
  • Places where CLIPS's own behaviour blocks a safe binding are recorded as explicit exclusions in docs/coverage.md, with the reason, rather than being bound unsafely or quietly omitted. A test fails if anything documented as excluded is nevertheless declared in src/ffi.rs.

Read the coverage matrix and the test suite before relying on this in anything that matters.

License

MIT — see LICENSE.

This covers the binding code in this repository only. CLIPS itself is neither vendored nor distributed here; obtain it from its maintainers and observe its own terms.

About

Rust bindings for CLIPS 6.4.2

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages