1use egglog_ast::generic_ast::GenericExpr;
2use std::fmt::{Display, Formatter};
3use std::hash::Hash;
4use std::hash::Hasher;
5
6use crate::ast::CorrespondingVar;
7use crate::core::ResolvedCall;
8use crate::{ArcSort, sort};
9
10#[derive(Debug, Clone)]
11pub struct ResolvedVar {
12 pub name: String,
13 pub sort: ArcSort,
14 pub is_global_ref: bool,
22}
23
24impl PartialEq for ResolvedVar {
25 fn eq(&self, other: &Self) -> bool {
26 self.name == other.name && self.sort.name() == other.sort.name()
27 }
28}
29
30impl Eq for ResolvedVar {}
31
32impl Hash for ResolvedVar {
33 fn hash<H: Hasher>(&self, state: &mut H) {
34 self.name.hash(state);
35 self.sort.name().hash(state);
36 }
37}
38
39impl Display for ResolvedVar {
40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41 write!(f, "{}", self.name)
42 }
43}
44
45pub type Expr = GenericExpr<String, String>;
46pub type ResolvedExpr = GenericExpr<ResolvedCall, ResolvedVar>;
49pub(crate) type MappedExpr<Head, Leaf> = GenericExpr<CorrespondingVar<Head, Leaf>, Leaf>;
54
55pub(crate) trait ResolvedExprExt {
56 fn output_type(&self) -> ArcSort;
57 fn get_global_var(&self) -> Option<ResolvedVar>;
58}
59
60impl ResolvedExprExt for ResolvedExpr {
61 fn output_type(&self) -> ArcSort {
62 match self {
63 ResolvedExpr::Lit(_, lit) => sort::literal_sort(lit),
64 ResolvedExpr::Var(_, resolved_var) => resolved_var.sort.clone(),
65 ResolvedExpr::Call(_, resolved_call, _) => resolved_call.output().clone(),
66 }
67 }
68
69 fn get_global_var(&self) -> Option<ResolvedVar> {
70 match self {
71 ResolvedExpr::Var(_, v) if v.is_global_ref => Some(v.clone()),
72 _ => None,
73 }
74 }
75}
76
77#[macro_export]
78macro_rules! call {
79 ($func:expr, $args:expr) => {
80 $crate::ast::GenericExpr::Call($crate::span!(), $func.into(), $args.into_iter().collect())
81 };
82}
83
84#[macro_export]
85macro_rules! lit {
86 ($lit:expr) => {
87 $crate::ast::GenericExpr::Lit($crate::span!(), $lit.into())
88 };
89}
90
91#[macro_export]
92macro_rules! var {
93 ($var:expr) => {
94 $crate::ast::GenericExpr::Var($crate::span!(), $var.into())
95 };
96}
97
98pub use {call, lit, var};