From e7cfdf7eeda42f0faddda55a1873cda0266193de Mon Sep 17 00:00:00 2001 From: Marceline Cramer Date: Fri, 1 May 2026 14:38:33 -0600 Subject: [PATCH] Trivial IR to-do --- crates/ir/src/lib.rs | 87 ++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/crates/ir/src/lib.rs b/crates/ir/src/lib.rs index a55c283..b225bcd 100644 --- a/crates/ir/src/lib.rs +++ b/crates/ir/src/lib.rs @@ -136,34 +136,73 @@ pub struct RuleBody { pub body: Expr, } +/// A Kerolox expression tree. +/// +/// This type expresses the general "shape" of some calculation in Kerolox, but +/// the means under which the values can actually be calculated depends on the +/// backend. With a top-down approach, the expression nodes are used to constrain some +/// query, but with a bottom-up approach, the expression nodes are used directly to +/// produce new sets of results from their children. #[derive_where(Clone, Debug, PartialEq, Eq)] #[derive_where(PartialOrd, Ord; T: OrdProgramInfo)] #[derive_where(Hash; T: HashProgramInfo)] #[cfg_attr(feature = "serde", derive_where(Deserialize, Serialize; T: SerdeProgramInfo))] pub struct Expr { + /// Parameterizable metadata. pub meta: T::ExprMeta, + + /// The variant of expression. pub kind: ExprKind, } +/// An expression node variant. See [Expr]. #[derive_where(Clone, Debug, PartialEq, Eq)] #[derive_where(PartialOrd, Ord; T: OrdProgramInfo)] #[derive_where(Hash; T: HashProgramInfo)] #[cfg_attr(feature = "serde", derive_where(Deserialize, Serialize; T: SerdeProgramInfo))] pub enum ExprKind { + /// A non-standard expression kind. Extra(T::ExprExtra), - Variable(u32), + + /// A variable's index in the parent [RuleBody]. + Variable(usize), + + /// A constant [Value]. Value(Value), + + /// Loads tuples from a relation. Load { - relation: u32, + /// The source relation's index in the parent [RuleBody]. + relation: usize, + + /// The list of [QueryTerm] parameters to the query. query: Vec, }, + + /// A unary arithmetic operation. UnaryOp { + /// The kind of operator. + /// + /// This is extended by [ProgramInfo::UnaryOp] but + /// must always be convertible to/from [UnaryOpKind]. op: T::UnaryOp, + + /// The value to perform the operation on. term: Arc>, }, + + /// A binary arithmetic operation. BinaryOp { + /// The kind of operator. + /// + /// This is extended by [ProgramInfo::BinaryOp] but + /// must always be convertible to/from [BinaryOpKind]. op: T::BinaryOp, + + /// The left-hand side of the arithmetic expression. lhs: Arc>, + + /// The right-hand side of the arithmetic expression. rhs: Arc>, }, } @@ -187,10 +226,12 @@ pub enum RelationIO { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum AssumptionWeight { Hard, - Soft(u32), + Soft(usize), } /// Redundant operations (Sub, Neq, Gt, Ge) are not included. +/// +/// This type is not directly used in [Expr] because [ProgramInfo::BinaryOp] can extend it. // TODO: more docs #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, EnumIter)] #[cfg_attr(feature = "fuzz", derive(Arbitrary))] @@ -226,32 +267,18 @@ impl EnumRepr for BinaryOpKind { } } -// TODO: is this type necessary? -pub enum BinaryOpCategory { - Arithmetic, - String, - Logical, - Comparison, -} - -impl From for BinaryOpCategory { - fn from(op: BinaryOpKind) -> BinaryOpCategory { - use BinaryOpCategory::*; - use BinaryOpKind::*; - match op { - Add | Mul | Div | Range => Arithmetic, - Concat => String, - And | Or => Logical, - Eq | Lt | Le => Comparison, - } - } -} - +/// Each kind of unary operator. See [ExprKind::UnaryOp]. +/// +/// This type is not directly used in [Expr] because [ProgramInfo::BinaryOp] can extend it. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, EnumIter)] #[cfg_attr(feature = "fuzz", derive(Arbitrary))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum UnaryOpKind { - Not, // TODO: settle the difference between well-founded negation and NAF + /// Boolean "not". + // TODO: settle the difference between well-founded negation and NAF + Not, + + /// Negates an integer or real number. Negate, } @@ -289,11 +316,15 @@ pub trait EnumRepr { fn repr(&self) -> &'static str; } +/// A single term in a query (see [Rule] and [ExprKind::Load]). #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "fuzz", derive(Arbitrary))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum QueryTerm { - Variable(u32), + /// A reference to the variable to load/store. + Variable(usize), + + /// A constant [Value] to constrain/store in this query. Value(Value), } @@ -302,6 +333,7 @@ pub enum QueryTerm { #[cfg_attr(feature = "fuzz", derive(Arbitrary))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum Type { + /// A Boolean literal value. Boolean, /// An integer, in practice backed by [i64]. @@ -338,7 +370,7 @@ pub enum Value { /// An atomic, unforgeable symbol. /// /// Symbols are labelled in a global [Program] table. - Symbol(u32), + Symbol(usize), } impl fmt::Display for Value { @@ -357,6 +389,7 @@ impl fmt::Display for Value { } impl Value { + /// Retrieves the [Type] of this value. pub fn ty(&self) -> Type { use Value::*; match self {