egglog_ast/
generic_ast.rs

1use std::fmt::Display;
2use std::hash::Hash;
3
4use ordered_float::OrderedFloat;
5
6use crate::span::Span;
7
8#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
9pub enum Literal {
10    Int(i64),
11    Float(OrderedFloat<f64>),
12    String(String),
13    Bool(bool),
14    Unit,
15}
16
17#[derive(Clone, Debug, PartialEq, Eq, Hash)]
18pub enum GenericExpr<Head, Leaf> {
19    Var(Span, Leaf),
20    Call(Span, Head, Vec<GenericExpr<Head, Leaf>>),
21    Lit(Span, Literal),
22}
23
24/// Facts are the left-hand side of a [`Command::Rule`].
25/// They represent a part of a database query.
26/// Facts can be expressions or equality constraints between expressions.
27///
28/// Note that primitives such as  `!=` are partial.
29/// When two things are equal, it returns nothing and the query does not match.
30/// For example, the following egglog code runs:
31/// ```text
32/// (fail (check (!= 1 1)))
33/// ```
34#[derive(Clone, Debug, PartialEq, Eq, Hash)]
35pub enum GenericFact<Head, Leaf> {
36    Eq(Span, GenericExpr<Head, Leaf>, GenericExpr<Head, Leaf>),
37    Fact(GenericExpr<Head, Leaf>),
38}
39
40#[derive(Clone, Debug, PartialEq, Eq, Hash)]
41pub struct GenericActions<Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash>(
42    pub Vec<GenericAction<Head, Leaf>>,
43);
44
45#[derive(Clone, Debug, PartialEq, Eq, Hash)]
46pub enum GenericAction<Head, Leaf>
47where
48    Head: Clone + Display,
49    Leaf: Clone + PartialEq + Eq + Display + Hash,
50{
51    /// Bind a variable to a particular datatype or primitive.
52    /// At the top level (in a [`Command::Action`]), this defines a global variable.
53    /// In a [`Command::Rule`], this defines a local variable in the actions.
54    Let(Span, Leaf, GenericExpr<Head, Leaf>),
55    /// `set` a function to a particular result.
56    /// `set` should not be used on datatypes-
57    /// instead, use `union`.
58    Set(
59        Span,
60        Head,
61        Vec<GenericExpr<Head, Leaf>>,
62        GenericExpr<Head, Leaf>,
63    ),
64    /// Delete or subsume (mark as hidden from future rewrites and unextractable) an entry from a function.
65    Change(Span, Change, Head, Vec<GenericExpr<Head, Leaf>>),
66    /// `union` two datatypes, making them equal
67    /// in the implicit, global equality relation
68    /// of egglog.
69    /// All rules match modulo this equality relation.
70    ///
71    /// Example:
72    /// ```text
73    /// (datatype Math (Num i64))
74    /// (union (Num 1) (Num 2)); Define that Num 1 and Num 2 are equivalent
75    /// (extract (Num 1)); Extracts Num 1
76    /// (extract (Num 2)); Extracts Num 1
77    /// ```
78    Union(Span, GenericExpr<Head, Leaf>, GenericExpr<Head, Leaf>),
79    Panic(Span, String),
80    Expr(Span, GenericExpr<Head, Leaf>),
81}
82
83#[derive(Clone, Debug, PartialEq, Eq, Hash)]
84pub struct GenericRule<Head, Leaf>
85where
86    Head: Clone + Display,
87    Leaf: Clone + PartialEq + Eq + Display + Hash,
88{
89    pub span: Span,
90    pub head: GenericActions<Head, Leaf>,
91    pub body: Vec<GenericFact<Head, Leaf>>,
92    /// A globally unique name for this rule in the EGraph.
93    pub name: String,
94    /// The ruleset this rule belongs to. Defaults to `""`.
95    pub ruleset: String,
96}
97
98/// Change a function entry.
99#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)]
100pub enum Change {
101    /// `delete` this entry from a function.
102    /// Be wary! Only delete entries that are guaranteed to be not useful.
103    Delete,
104    /// `subsume` this entry so that it cannot be queried or extracted, but still can be checked.
105    /// Note that this is currently forbidden for functions with custom merges.
106    Subsume,
107}