Trivial IR to-do

This commit is contained in:
2026-05-01 14:38:33 -06:00
parent 4f5f4e2943
commit e7cfdf7eed

View File

@@ -136,34 +136,73 @@ pub struct RuleBody<T: ProgramInfo> {
pub body: Expr<T>,
}
/// 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<T: ProgramInfo> {
/// Parameterizable metadata.
pub meta: T::ExprMeta,
/// The variant of expression.
pub kind: ExprKind<T>,
}
/// 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<T: ProgramInfo> {
/// 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<QueryTerm>,
},
/// 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<Expr<T>>,
},
/// 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<Expr<T>>,
/// The right-hand side of the arithmetic expression.
rhs: Arc<Expr<T>>,
},
}
@@ -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<BinaryOpKind> 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 {