1use std::fmt::Display;
4
5use egglog::{EGraph, Error, ast::*, span};
6use ref_cast::RefCast;
7
8#[derive(Clone, Debug, RefCast)]
14#[repr(transparent)]
15pub struct Program(pub Vec<Command>);
16
17impl Display for Program {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 for command in self.0.iter() {
21 writeln!(f, "{}", command)?;
22 }
23 Ok(())
24 }
25}
26
27impl Program {
28 pub fn check_equal(&mut self, lhs: Expr, rhs: Expr, schedule: Option<Schedule>) {
30 let prog = &mut self.0;
31 if let Some(schedule) = schedule {
32 prog.push(Command::Action(Action::Expr(span!(), lhs.clone())));
34 prog.push(Command::Action(Action::Expr(span!(), rhs.clone())));
35 prog.push(Command::RunSchedule(schedule));
36 }
37 prog.push(Command::Check(span!(), vec![Fact::Eq(span!(), lhs, rhs)]));
38 }
39
40 pub fn union(&mut self, lhs: Expr, rhs: Expr) {
42 self.0.push(Command::Action(Action::Union(span!(), lhs, rhs)));
43 }
44
45 pub fn run_in(self, egraph: &mut EGraph) -> Result<Vec<String>, Error> {
47 egraph.run_program(self.0)
48 }
49
50 pub fn check_in(self, egraph: &mut EGraph) -> Result<bool, Error> {
55 match self.run_in(egraph) {
56 Ok(_) => Ok(true),
57 Err(Error::CheckError(_, _)) => Ok(false),
58 Err(error) => Err(error),
59 }
60 }
61}
62
63pub struct CommandRewrite {
65 pub ruleset: Symbol,
67 pub lhs: Expr,
69 pub rhs: Expr,
71}
72
73impl From<CommandRewrite> for Command {
74 fn from(rule: CommandRewrite) -> Self {
75 Command::Rewrite(
76 rule.ruleset,
77 Rewrite {
78 span: span!(),
79 lhs: rule.lhs,
80 rhs: rule.rhs,
81 conditions: vec![],
82 },
83 false,
84 )
85 }
86}
87
88pub struct CommandRule {
90 pub ruleset: Symbol,
92 pub head: Vec<Action>,
94 pub body: Vec<Fact>,
96}
97
98impl From<CommandRule> for Command {
99 fn from(rule: CommandRule) -> Self {
100 Command::Rule {
101 name: "".into(),
102 ruleset: rule.ruleset,
103 rule: Rule {
104 span: span!(),
105 head: Actions::new(rule.head),
106 body: rule.body,
107 },
108 }
109 }
110}