neural/inf/rs/ast/src/lib.rs

//! inf AST and IR.
//!
//! The AST is what the parser produces from the pure-register surface
//! (specs/grammar.md). The IR is the stratified, ordered plan the planner
//! produces and the evaluator and the nox lowering both consume (specs/ir.md).

// โ”€โ”€โ”€ AST โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

/// A term: a value-producing expression in a rule body or head argument.
#[derive(Clone, Debug, PartialEq)]
pub enum Term {
    Var(String),
    Int(i64),
    Bool(bool),
    Str(String),
    /// A field-element literal (written `f<digits>` or produced by the planner).
    Field(u64),
    /// A cybermark address used as a first-class value.
    Addr(Addr),
    List(Vec<Term>),
    Call(Box<Call>),
}

/// A cybermark sigil address: `#particle`, `@neuron`, `~name`.
#[derive(Clone, Debug, PartialEq)]
pub enum Addr {
    Particle(String),
    Neuron(String),
    Name(String),
}

/// A function application: a builtin (`gt(..)`) or a sibling call (`Tri.add(..)`).
#[derive(Clone, Debug, PartialEq)]
pub struct Call {
    pub sibling: Option<String>, // Some("Tri") | None for builtins
    pub func: String,
    pub args: Vec<Term>,
}

/// Column/positional bindings for a relation read or a mutation.
#[derive(Clone, Debug, PartialEq)]
pub enum Binds {
    /// `{ col: term, col2, .. }` โ€” shorthand `{col}` normalizes to `(col, Var(col))`.
    Named(Vec<(String, Term)>),
    /// `[ term, term, .. ]` โ€” positional by column order.
    Pos(Vec<Term>),
}

/// A body atom: a conjunct of a rule body.
#[derive(Clone, Debug, PartialEq)]
pub enum Atom {
    /// Read a relation, binding its columns to terms.
    Read { rel: String, binds: Binds },
    /// Apply another rule (a derived relation) positionally.
    Apply { rule: String, args: Vec<Term> },
    /// A condition โ€” a boolean call into a builtin or sibling.
    Cond(Call),
    /// A binding `var = term`.
    Bind { var: String, term: Term },
    /// Stratified negation: the inner atom must not hold.
    Not(Box<Atom>),
}

/// A head argument: a grouping variable or an aggregation over one.
#[derive(Clone, Debug, PartialEq)]
pub enum HeadArg {
    Var(String),
    Aggr { op: String, var: String },
}

/// A rule head. `name = None` marks the entry rule `?`.
#[derive(Clone, Debug, PartialEq)]
pub struct Head {
    pub name: Option<String>,
    pub args: Vec<HeadArg>,
}

impl Head {
    /// Whether any head argument aggregates.
    pub fn has_aggr(&self) -> bool {
        self.args.iter().any(|a| matches!(a, HeadArg::Aggr { .. }))
    }
}

/// A fixed-rule (`<~`) invocation: a built-in graph algorithm over an edges
/// relation, with named parameters and positional arguments (specs/algorithms.md).
#[derive(Clone, Debug, PartialEq)]
pub struct Fixed {
    pub algo: String,
    pub edges: String,
    pub params: Vec<(String, Term)>,
    pub pos: Vec<Term>,
}

/// A rule. Either an inline rule (`head := body`) with an optional recursion
/// bound, or a fixed rule (`head <~ Algo(..)`).
#[derive(Clone, Debug, PartialEq)]
pub struct Rule {
    pub head: Head,
    pub body: Vec<Atom>,
    pub bound: Option<u64>,
    pub fixed: Option<Fixed>,
}

/// A canonical or temp-relation mutation.
#[derive(Clone, Debug, PartialEq)]
pub enum Mutation {
    Link(Binds),
    Unlink(Binds),
    Put { rel: String, binds: Binds },
    Rm { rel: String, binds: Binds },
}

/// An I/O declaration direction.
#[derive(Clone, Debug, PartialEq)]
pub enum Dir {
    In,
    Out,
}

/// A declared type in a `pub input/output` declaration.
#[derive(Clone, Debug, PartialEq)]
pub enum Type {
    Named(String),
    Array(Box<Type>, u64),
    Record(Vec<(String, Type)>),
}

/// A program I/O declaration: `pub input graph_root : Particle`.
#[derive(Clone, Debug, PartialEq)]
pub struct Decl {
    pub dir: Dir,
    pub name: String,
    pub ty: Type,
}

/// A program-level option applied to the entry relation.
#[derive(Clone, Debug, PartialEq)]
pub enum Opt {
    Limit(u64),
    Offset(u64),
    Sort { col: String, desc: bool },
    AssertNone,
    AssertSome,
}

/// A parsed program.
#[derive(Clone, Debug, PartialEq, Default)]
pub struct Program {
    pub decls: Vec<Decl>,
    pub rules: Vec<Rule>,
    pub mutation: Option<Mutation>,
    pub opts: Vec<Opt>,
    /// Reactive register: re-evaluate when this relation changes (`:subscribe`).
    pub subscribe: Option<(String, Binds)>,
}

/// The internal name for the entry rule's relation.
pub const ENTRY: &str = "?";

impl Program {
    /// The entry rule (`?`), if present.
    pub fn entry(&self) -> Option<&Rule> {
        self.rules.iter().find(|r| r.head.name.is_none())
    }
}

// โ”€โ”€โ”€ IR โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

/// A stratum: a group of rules evaluated together. Recursive strata iterate to a
/// bounded fixed point (specs/language.md, bounded recursion).
#[derive(Clone, Debug)]
pub struct Stratum {
    pub rules: Vec<Rule>,
    pub recursive: bool,
    /// The explicit `:bounded N`, if any; otherwise the evaluator uses the
    /// committed graph bound (see specs/cost.md).
    pub bound: Option<u64>,
}

/// The compiled program: strata bottom-up, plus the entry relation and the
/// program-level mutation and options.
#[derive(Clone, Debug)]
pub struct IrProgram {
    pub strata: Vec<Stratum>,
    pub entry: String,
    pub mutation: Option<Mutation>,
    pub opts: Vec<Opt>,
    pub subscribe: Option<(String, Binds)>,
}

impl Atom {
    /// The relation/rule name an atom reads, if it reads one.
    pub fn rel_name(&self) -> Option<&str> {
        match self {
            Atom::Read { rel, .. } => Some(rel),
            Atom::Apply { rule, .. } => Some(rule),
            Atom::Not(inner) => inner.rel_name(),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn entry_lookup() {
        let p = Program {
            rules: vec![
                Rule {
                    head: Head { name: Some("r".into()), args: vec![HeadArg::Var("x".into())] },
                    body: vec![],
                    bound: None,
                    fixed: None,
                },
                Rule {
                    head: Head { name: None, args: vec![HeadArg::Var("x".into())] },
                    body: vec![Atom::Apply { rule: "r".into(), args: vec![Term::Var("x".into())] }],
                    bound: None,
                    fixed: None,
                },
            ],
            decls: vec![],
            mutation: None,
            opts: vec![Opt::Limit(20)],
            subscribe: None,
        };
        assert!(p.entry().is_some());
        assert!(!p.entry().unwrap().head.has_aggr());
    }

    #[test]
    fn aggr_head_detected() {
        let h = Head {
            name: None,
            args: vec![HeadArg::Var("n".into()), HeadArg::Aggr { op: "count".into(), var: "p".into() }],
        };
        assert!(h.has_aggr());
    }
}

Homonyms

cyb/optica/src/lib.rs
soft3/strata/src/lib.rs
cyb/honeycrisp/src/lib.rs
warriors/trisha/honeycrisp/lib.rs
warriors/trisha/wgpu/lib.rs
soft3/glia/import/lib.rs
soft3/foculus/src/lib.rs
soft3/nox/rs/lib.rs
soft3/cybergraph/src/lib.rs
soft3/tru/rs/lib.rs
soft3/mudra/src/lib.rs
soft3/glia/run/lib.rs
cyb/prysm/rs/lib.rs
warriors/trisha/rs/lib.rs
cyb/src-tauri/src/lib.rs
soft3/mir/src/lib.rs
soft3/lens/src/lib.rs
neural/trident/src/lib.rs
neural/rune/rs/subject/lib.rs
cyb/cyb/cyb-services/src/lib.rs
soft3/strata/nebu/rs/lib.rs
soft3/lens/core/src/lib.rs
neural/rs/mir-format/src/lib.rs
soft3/zheng/rs/src/lib.rs
neural/rune/rs/interp/lib.rs
soft3/radio/iroh-willow/src/lib.rs
neural/rune/rs/parse/lib.rs
neural/eidos/rs/src/lib.rs
neural/rs/darwin-sys/src/lib.rs
soft3/radio/iroh-gossip/src/lib.rs
soft3/radio/iroh-ffi/src/lib.rs
soft3/radio/iroh-car/src/lib.rs
soft3/radio/iroh-relay/src/lib.rs
soft3/bbg/rs/src/lib.rs
soft3/radio/iroh-docs/src/lib.rs
soft3/lens/ikat/src/lib.rs
neural/rune/rs/lex/lib.rs
cyb/honeycrisp/aruminium/src/lib.rs
soft3/hemera/rs/src/lib.rs
neural/rune/rs/ast/lib.rs
soft3/radio/iroh-blobs/src/lib.rs
cyb/honeycrisp/acpu/src/lib.rs
soft3/lens/porphyry/src/lib.rs
cyb/honeycrisp/rane/src/lib.rs
neural/rune/rs/compile/lib.rs
neural/rune/rs/parse-pure/lib.rs
neural/rs/codegen/src/lib.rs
soft3/lens/binius/src/lib.rs
neural/rune/rs/prysm/lib.rs
neural/rs/link/src/lib.rs
neural/rune/rs/mold/lib.rs
soft3/strata/proof/src/lib.rs
soft3/lens/brakedown/src/lib.rs
soft3/strata/kuro/rs/lib.rs
soft3/lens/assayer/src/lib.rs
neural/rs/core/src/lib.rs
neural/rs/macros/src/lib.rs
soft3/radio/cyber-bao/src/lib.rs
soft3/strata/compute/src/lib.rs
soft3/radio/iroh-base/src/lib.rs
soft3/radio/iroh-dns-server/src/lib.rs
neural/rune/rs/lower/lib.rs
soft3/strata/ext/src/lib.rs
soft3/strata/core/src/lib.rs
soft3/hemera/wgsl/src/lib.rs
soft3/radio/iroh/src/lib.rs
cyb/honeycrisp/unimem/src/lib.rs
cyb/evy/crates/evy_engine_tasks/src/lib.rs
cyb/evy/crates/evy_dialect/src/lib.rs
cyb/wysm/crates/wasi/src/lib.rs
cyb/wysm/crates/fuzz/src/lib.rs
soft3/strata/genies/rs/src/lib.rs
cyb/evy/crates/evy_platform_caps/src/lib.rs
neural/inf/rs/oracle/src/lib.rs
soft3/strata/jali/wgsl/src/lib.rs
cyb/evy/forks/bevy_transform/src/lib.rs
soft3/tape/impl/rust/src/lib.rs
cyb/wysm/crates/wasmi/src/lib.rs
cyb/evy/forks/bevy_render/src/lib.rs
cyb/evy/crates/evy_ecs_storage/src/lib.rs
cyb/evy/forks/naga/src/lib.rs
soft3/strata/trop/wgsl/src/lib.rs
cyb/wysm/crates/c_api/artifact/lib.rs
cyb/evy/forks/bevy_ecs/src/lib.rs
cyb/wysm/crates/ir/src/lib.rs
cyb/evy/forks/bevy_animation/src/lib.rs
cyb/evy/forks/bevy_sprite_render/src/lib.rs
cyb/wysm/crates/c_api/src/lib.rs
neural/inf/rs/parse/src/lib.rs
soft3/strata/trop/rs/src/lib.rs
soft3/strata/kuro/wgsl/src/lib.rs
neural/trident/editor/zed/src/lib.rs
cyb/evy/forks/bevy_mesh/src/lib.rs
cyb/evy/crates/evy_radio/src/lib.rs
cyb/evy/forks/bevy_anti_alias/src/lib.rs
soft3/strata/jali/rs/src/lib.rs
cyb/wysm/crates/wast/src/lib.rs
neural/inf/rs/plan/src/lib.rs
neural/rs/tests/macro-integration/src/lib.rs
soft3/radio/iroh-ffi/iroh-js/src/lib.rs
cyb/evy/forks/bevy_image/src/lib.rs
cyb/evy/forks/bevy_post_process/src/lib.rs
neural/inf/rs/source/src/lib.rs
cyb/wysm/crates/core/src/lib.rs
cyb/evy/crates/evy_diagnostic/src/lib.rs
cyb/evy/crates/evy_engine_dispatch/src/lib.rs
cyb/evy/forks/bevy_pbr/src/lib.rs
cyb/evy/forks/bevy_gizmos/src/lib.rs
cyb/evy/forks/bevy_gizmos_render/src/lib.rs
soft3/radio/iroh/bench/src/lib.rs
neural/inf/rs/lex/src/lib.rs
soft3/strata/genies/wgsl/src/lib.rs
soft3/strata/nebu/wgsl/src/lib.rs
cyb/wysm/crates/collections/src/lib.rs
neural/inf/rs/lower/src/lib.rs
cyb/evy/forks/bevy_sprite/src/lib.rs
cyb/evy/forks/bevy_diagnostic/src/lib.rs
neural/inf/rs/eval/src/lib.rs
cyb/wysm/crates/c_api/macro/lib.rs
cyb/evy/forks/bevy_tasks/src/lib.rs
cyb/evy/forks/bevy_core_pipeline/src/lib.rs
cyb/evy/crates/evy_prysm_core/src/lib.rs
neural/inf/rs/value/src/lib.rs
cyb/evy/crates/evy_engine_core/src/lib.rs
soft3/radio/tests/integration/src/lib.rs
bootloader/go-cyber/cw/packages/cyber-std-test/src/lib.rs
bootloader/go-cyber/cw/contracts/std-test/src/lib.rs
bootloader/go-cyber/cw/contracts/graph-filter/src/lib.rs
bootloader/go-cyber/cw/packages/cyber-std/src/lib.rs

Graph