From 61b03b2f696f86d82452010dbb871340f53f809d Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 25 Jun 2024 23:48:34 -0700 Subject: [PATCH 01/16] work in progress; does not compile yet. Need to think through constraints, error reporting, and the action virtual machine --- src/actions.rs | 10 +- src/ast/desugar.rs | 96 ++++++++++------ src/ast/expr.rs | 22 ++-- src/ast/mod.rs | 236 +++++++++++++++++++++----------------- src/ast/parse.lalrpop | 2 +- src/ast/remove_globals.rs | 5 +- src/constraint.rs | 53 ++++----- src/core.rs | 62 +++++----- src/extract.rs | 1 + src/lib.rs | 46 ++++---- src/main.rs | 16 +-- src/sort/bool.rs | 4 +- src/sort/f64.rs | 4 +- src/sort/fn.rs | 16 +-- src/sort/i64.rs | 4 +- src/sort/map.rs | 10 +- src/sort/mod.rs | 6 +- src/sort/rational.rs | 9 +- src/sort/set.rs | 10 +- src/sort/string.rs | 4 +- src/sort/unit.rs | 4 +- src/sort/vec.rs | 22 ++-- src/termdag.rs | 22 ++-- src/typechecking.rs | 43 ++++--- 24 files changed, 384 insertions(+), 323 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index 2a028802..324a3153 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -301,17 +301,15 @@ impl EGraph { value } _ => { - return Err(Error::NotFoundError(NotFoundError(Expr::Var( - (), + return Err(Error::NotFoundError(NotFoundError( format!("No value found for {f} {:?}", values).into(), - )))) + ))) } } } else { - return Err(Error::NotFoundError(NotFoundError(Expr::Var( - (), + return Err(Error::NotFoundError(NotFoundError( format!("No value found for {f} {:?}", values).into(), - )))); + ))); }; debug_assert_eq!(output_tag, value.tag); diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index a9a654d8..d704b886 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -45,13 +45,18 @@ fn desugar_rewrite( rewrite: &Rewrite, subsume: bool, ) -> Vec { + let span = rewrite.ann; let var = Symbol::from("rewrite_var__"); - let mut head = Actions::singleton(Action::Union((), Expr::Var((), var), rewrite.rhs.clone())); + let mut head = Actions::singleton(Action::Union( + span, + Expr::Var(span, var), + rewrite.rhs.clone(), + )); if subsume { match &rewrite.lhs { Expr::Call(_, f, args) => { head.0 - .push(Action::Change((), Change::Subsume, *f, args.to_vec())); + .push(Action::Change(span, Change::Subsume, *f, args.to_vec())); } _ => { panic!("Subsumed rewrite must have a function call on the lhs"); @@ -65,7 +70,8 @@ fn desugar_rewrite( ruleset, name, rule: Rule { - body: [Fact::Eq(vec![Expr::Var((), var), rewrite.lhs.clone()])] + ann: span, + body: [Fact::Eq(vec![Expr::Var(span, var), rewrite.lhs.clone()])] .into_iter() .chain(rewrite.conditions.clone()) .collect(), @@ -75,7 +81,9 @@ fn desugar_rewrite( } fn desugar_birewrite(ruleset: Symbol, name: Symbol, rewrite: &Rewrite) -> Vec { + let span = rewrite.ann; let rw2 = Rewrite { + ann: span, lhs: rewrite.rhs.clone(), rhs: rewrite.lhs.clone(), conditions: rewrite.conditions.clone(), @@ -91,6 +99,7 @@ fn desugar_birewrite(ruleset: Symbol, name: Symbol, rewrite: &Rewrite) -> Vec Option { let mut new_rule = rule; // Whenever an Let(_, expr@Call(...)) or Set(_, expr@Call(...)) is present in action, @@ -102,23 +111,23 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { let mut var_set = HashSet::default(); for head_slice in new_rule.head.0.iter_mut().rev() { match head_slice { - Action::Set(_ann, _, _, expr) => { + Action::Set(ann, _, _, expr) => { var_set.extend(expr.vars()); - if let Expr::Call((), _, _) = expr { + if let Expr::Call(..) = expr { add_new_rule = true; let fresh_symbol = desugar.get_fresh(); - let fresh_var = Expr::Var((), fresh_symbol); + let fresh_var = Expr::Var(*ann, fresh_symbol); let expr = std::mem::replace(expr, fresh_var.clone()); new_head_atoms.push(Fact::Eq(vec![fresh_var, expr])); }; } - Action::Let(_ann, symbol, expr) if var_set.contains(symbol) => { + Action::Let(ann, symbol, expr) if var_set.contains(symbol) => { var_set.extend(expr.vars()); - if let Expr::Call((), _, _) = expr { + if let Expr::Call(..) = expr { add_new_rule = true; - let var = Expr::Var((), *symbol); + let var = Expr::Var(*ann, *symbol); new_head_atoms.push(Fact::Eq(vec![var, expr.clone()])); } } @@ -140,15 +149,16 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { } fn desugar_simplify(desugar: &mut Desugar, expr: &Expr, schedule: &Schedule) -> Vec { + let ann = expr.ann(); let mut res = vec![NCommand::Push(1)]; let lhs = desugar.get_fresh(); - res.push(NCommand::CoreAction(Action::Let((), lhs, expr.clone()))); + res.push(NCommand::CoreAction(Action::Let(ann, lhs, expr.clone()))); res.push(NCommand::RunSchedule(schedule.clone())); res.extend( desugar_command( Command::QueryExtract { variants: 0, - expr: Expr::Var((), lhs), + expr: Expr::Var(ann, lhs), }, desugar, false, @@ -163,6 +173,7 @@ fn desugar_simplify(desugar: &mut Desugar, expr: &Expr, schedule: &Schedule) -> pub(crate) fn desugar_calc( desugar: &mut Desugar, + span: Span, idents: Vec, exprs: Vec, seminaive_transform: bool, @@ -171,7 +182,11 @@ pub(crate) fn desugar_calc( // first, push all the idents for IdentSort { ident, sort } in idents { - res.push(Command::Declare { name: ident, sort }); + res.push(Command::Declare { + ann: span, + name: ident, + sort, + }); } // now, for every pair of exprs we need to prove them equal @@ -182,23 +197,27 @@ pub(crate) fn desugar_calc( // add the two exprs only when they are calls (consts and vars don't need to be populated). if let Expr::Call(..) = expr1 { - res.push(Command::Action(Action::Expr((), expr1.clone()))); + res.push(Command::Action(Action::Expr(expr1.ann(), expr1.clone()))); } if let Expr::Call(..) = expr2 { - res.push(Command::Action(Action::Expr((), expr2.clone()))); + res.push(Command::Action(Action::Expr(expr2.ann(), expr2.clone()))); } - res.push(Command::RunSchedule(Schedule::Saturate(Box::new( - Schedule::Run(RunConfig { - ruleset: "".into(), - until: Some(vec![Fact::Eq(vec![expr1.clone(), expr2.clone()])]), - }), - )))); + res.push(Command::RunSchedule(Schedule::Saturate( + span, + Box::new(Schedule::Run( + span, + RunConfig { + ruleset: "".into(), + until: Some(vec![Fact::Eq(vec![expr1.clone(), expr2.clone()])]), + }, + )), + ))); - res.push(Command::Check(vec![Fact::Eq(vec![ - expr1.clone(), - expr2.clone(), - ])])); + res.push(Command::Check( + span, + vec![Fact::Eq(vec![expr1.clone(), expr2.clone()])], + )); res.push(Command::Pop(1)); } @@ -228,7 +247,7 @@ pub(crate) fn desugar_command( constructor, inputs, } => desugar.desugar_function(&FunctionDecl::relation(constructor, inputs)), - Command::Declare { name, sort } => desugar.declare(name, sort), + Command::Declare { ann, name, sort } => desugar.declare(ann, name, sort), Command::Datatype { name, variants } => desugar_datatype(name, variants), Command::Rewrite(ruleset, rewrite, subsume) => { desugar_rewrite(ruleset, rewrite_name(&rewrite).into(), &rewrite, subsume) @@ -240,7 +259,7 @@ pub(crate) fn desugar_command( let s = std::fs::read_to_string(&file) .unwrap_or_else(|_| panic!("Failed to read file {file}")); return desugar_commands( - desugar.parse_program(&s)?, + desugar.parse_program(Some(file.into()), &s)?, desugar, get_all_proofs, seminaive_transform, @@ -280,7 +299,9 @@ pub(crate) fn desugar_command( } Command::Action(action) => vec![NCommand::CoreAction(action)], Command::Simplify { expr, schedule } => desugar_simplify(desugar, &expr, &schedule), - Command::Calc(idents, exprs) => desugar_calc(desugar, idents, exprs, seminaive_transform)?, + Command::Calc(span, idents, exprs) => { + desugar_calc(desugar, span, idents, exprs, seminaive_transform)? + } Command::RunSchedule(sched) => { vec![NCommand::RunSchedule(sched.clone())] } @@ -290,7 +311,7 @@ pub(crate) fn desugar_command( Command::QueryExtract { variants, expr } => { let fresh = desugar.get_fresh(); let fresh_ruleset = desugar.get_fresh(); - let desugaring = if let Expr::Var((), v) = expr { + let desugaring = if let Expr::Var(_, v) = expr { format!("(extract {v} {variants})") } else { format!( @@ -304,13 +325,13 @@ pub(crate) fn desugar_command( }; desugar.desugar_program( - desugar.parse_program(&desugaring).unwrap(), + desugar.parse_program(todo!("our filename should be richer to better support locating desugared rule. Alternatively, we can just use the same source location"), &desugaring).unwrap(), get_all_proofs, seminaive_transform, )? } - Command::Check(facts) => { - let res = vec![NCommand::Check(facts)]; + Command::Check(span, facts) => { + let res = vec![NCommand::Check(span, facts)]; if get_all_proofs { // TODO check proofs @@ -383,15 +404,20 @@ impl Desugar { Ok(res) } - pub fn parse_program(&self, input: &str) -> Result, Error> { + pub fn parse_program( + &self, + filename: Option, + input: &str, + ) -> Result, Error> { + let filename = filename.unwrap_or_else(|| Symbol::from(DEFAULT_FILENAME)); Ok(self .parser - .parse(input) + .parse(filename, input) .map_err(|e| e.map_token(|tok| tok.to_string()))?) } // TODO declare by creating a new global function. See issue #334 - pub fn declare(&mut self, name: Symbol, sort: Symbol) -> Vec { + pub fn declare(&mut self, span: Span, name: Symbol, sort: Symbol) -> Vec { let fresh = self.get_fresh(); vec![ NCommand::Function(FunctionDecl { @@ -407,7 +433,7 @@ impl Desugar { unextractable: false, ignore_viz: false, }), - NCommand::CoreAction(Action::Let((), name, Expr::Call((), fresh, vec![]))), + NCommand::CoreAction(Action::Let(span, name, Expr::Call(span, fresh, vec![]))), ] } diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 718032ee..df722f4d 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -105,8 +105,11 @@ impl ToSexp for ResolvedVar { } } -pub type Expr = GenericExpr; -pub(crate) type ResolvedExpr = GenericExpr; +pub type Expr = GenericExpr; +/// A generated expression is an expression that is generated by the system +/// and does not have annotations. +pub type GeneratedExpr = GenericExpr; +pub(crate) type ResolvedExpr = GenericExpr; /// A [`MappedExpr`] arises naturally when you want a mapping between an expression /// and its flattened form. It records this mapping by annotating each `Head` /// with a `Leaf`, which it maps to in the flattened form. @@ -137,7 +140,7 @@ impl ResolvedExpr { } } -impl Expr { +impl GeneratedExpr { pub fn call(op: impl Into, children: impl IntoIterator) -> Self { Self::Call((), op.into(), children.into_iter().collect()) } @@ -208,18 +211,15 @@ impl } } - // TODO: Currently, subst_leaf takes a leaf but not an annotation over the leaf, - // so it has to "make up" annotations for the returned GenericExpr. A better - // approach is for subst_leaf to also take the annotation, which we should - // implement after we use real non-() annotations + /// `subst` replaces occurrences of variables and head symbols in the expression. pub fn subst( &self, - subst_leaf: &mut impl FnMut(&Leaf) -> GenericExpr, + subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, subst_head: &mut impl FnMut(&Head) -> Head2, ) -> GenericExpr { match self { GenericExpr::Lit(ann, lit) => GenericExpr::Lit(ann.clone(), lit.clone()), - GenericExpr::Var(_ann, v) => subst_leaf(v), + GenericExpr::Var(ann, v) => subst_leaf(ann, v), GenericExpr::Call(ann, op, children) => { let children = children .iter() @@ -232,7 +232,7 @@ impl pub fn subst_leaf( &self, - subst_leaf: &mut impl FnMut(&Leaf) -> GenericExpr, + subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, ) -> GenericExpr { self.subst(subst_leaf, &mut |x| x.clone()) } @@ -281,7 +281,7 @@ where pub(crate) fn parse_expr(s: &str) -> Result> { let parser = ast::parse::ExprParser::new(); parser - .parse(s) + .parse(DEFAULT_FILENAME.into(), s) .map_err(|e| e.map_token(|tok| tok.to_string())) } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index d1ff066b..f852be02 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -51,11 +51,24 @@ pub(crate) enum Ruleset { Combined(Symbol, Vec), } -pub type NCommand = GenericNCommand; +pub(crate) const DEFAULT_FILENAME: &str = ""; +pub(crate) const DUMMY_FILENAME: &str = ""; + +/// A [`Span`] contains the file name and a pair of offsets representing the start and the end. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Span(pub Symbol, pub usize, pub usize); + +impl Span { + pub(crate) const DUMMY: Span = Span(Symbol::from(DUMMY_FILENAME), 0, 0); +} + +impl Copy for Span {} + +pub type NCommand = GenericNCommand; /// [`ResolvedNCommand`] is another specialization of [`GenericNCommand`], which /// adds the type information to heads and leaves of commands. /// [`TypeInfo::typecheck_command`] turns an [`NCommand`] into a [`ResolvedNCommand`]. -pub(crate) type ResolvedNCommand = GenericNCommand; +pub(crate) type ResolvedNCommand = GenericNCommand; /// A [`NCommand`] is a desugared [`Command`], where syntactic sugars /// like [`Command::Datatype`], [`Command::Declare`], and [`Command::Rewrite`] @@ -71,7 +84,7 @@ pub(crate) type ResolvedNCommand = GenericNCommand where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -94,7 +107,7 @@ where CoreAction(GenericAction), RunSchedule(GenericSchedule), PrintOverallStatistics, - Check(Vec>), + Check(Ann, Vec>), CheckProof, PrintTable(Symbol, usize), PrintSize(Option), @@ -111,12 +124,13 @@ where }, } -impl GenericNCommand +impl GenericNCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, + Ann: Clone, { - pub fn to_command(&self) -> GenericCommand { + pub fn to_command(&self) -> GenericCommand { match self { GenericNCommand::SetOption { name, value } => GenericCommand::SetOption { name: *name, @@ -140,7 +154,7 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(facts) => GenericCommand::Check(facts.clone()), + GenericNCommand::Check(ann, facts) => GenericCommand::Check(*ann, facts.clone()), GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -160,7 +174,7 @@ where pub fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { match self { GenericNCommand::SetOption { name, value } => GenericNCommand::SetOption { @@ -189,9 +203,10 @@ where GenericNCommand::CoreAction(action) => { GenericNCommand::CoreAction(action.visit_exprs(f)) } - GenericNCommand::Check(facts) => { - GenericNCommand::Check(facts.into_iter().map(|fact| fact.visit_exprs(f)).collect()) - } + GenericNCommand::Check(ann, facts) => GenericNCommand::Check( + ann, + facts.into_iter().map(|fact| fact.visit_exprs(f)).collect(), + ), GenericNCommand::CheckProof => GenericNCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericNCommand::PrintTable(name, n), GenericNCommand::PrintSize(name) => GenericNCommand::PrintSize(name), @@ -207,21 +222,15 @@ where } } -pub type Schedule = GenericSchedule; -pub(crate) type ResolvedSchedule = GenericSchedule; +pub type Schedule = GenericSchedule; +pub(crate) type ResolvedSchedule = GenericSchedule; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum GenericSchedule { - Saturate(Box>), - Repeat(usize, Box>), - Run(GenericRunConfig), - Sequence(Vec>), -} - -impl GenericSchedule { - pub fn saturate(self) -> Self { - GenericSchedule::Saturate(Box::new(self)) - } + Saturate(Ann, Box>), + Repeat(Ann, usize, Box>), + Run(Ann, GenericRunConfig), + Sequence(Ann, Vec>), } pub trait ToSexp { @@ -266,7 +275,7 @@ macro_rules! list { impl GenericSchedule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -275,16 +284,17 @@ where f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericSchedule::Saturate(sched) => { - GenericSchedule::Saturate(Box::new(sched.visit_exprs(f))) - } - GenericSchedule::Repeat(size, sched) => { - GenericSchedule::Repeat(size, Box::new(sched.visit_exprs(f))) + GenericSchedule::Saturate(ann, sched) => { + GenericSchedule::Saturate(ann, Box::new(sched.visit_exprs(f))) } - GenericSchedule::Run(config) => GenericSchedule::Run(config.visit_exprs(f)), - GenericSchedule::Sequence(scheds) => { - GenericSchedule::Sequence(scheds.into_iter().map(|s| s.visit_exprs(f)).collect()) + GenericSchedule::Repeat(ann, size, sched) => { + GenericSchedule::Repeat(ann, size, Box::new(sched.visit_exprs(f))) } + GenericSchedule::Run(ann, config) => GenericSchedule::Run(ann, config.visit_exprs(f)), + GenericSchedule::Sequence(ann, scheds) => GenericSchedule::Sequence( + ann, + scheds.into_iter().map(|s| s.visit_exprs(f)).collect(), + ), } } } @@ -292,10 +302,10 @@ where impl ToSexp for GenericSchedule { fn to_sexp(&self) -> Sexp { match self { - GenericSchedule::Saturate(sched) => list!("saturate", sched), - GenericSchedule::Repeat(size, sched) => list!("repeat", size, sched), - GenericSchedule::Run(config) => config.to_sexp(), - GenericSchedule::Sequence(scheds) => list!("seq", ++ scheds), + GenericSchedule::Saturate(_ann, sched) => list!("saturate", sched), + GenericSchedule::Repeat(_ann, size, sched) => list!("repeat", size, sched), + GenericSchedule::Run(_ann, config) => config.to_sexp(), + GenericSchedule::Sequence(_ann, scheds) => list!("seq", ++ scheds), } } } @@ -306,7 +316,7 @@ impl Display for GenericSchedule; +pub type Command = GenericCommand; pub type Subsume = bool; @@ -314,10 +324,11 @@ pub type Subsume = bool; /// It includes defining rules, declaring functions, /// adding to tables, and running rules (via a [`Schedule`]). #[derive(Debug, Clone)] -pub enum GenericCommand +pub enum GenericCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, + Ann: Clone, { /// Egglog supports several *experimental* options /// that can be set using the `set-option` command. @@ -330,7 +341,7 @@ where /// tool to know when each command has finished running. SetOption { name: Symbol, - value: GenericExpr, + value: GenericExpr, }, /// Declare a user-defined datatype. /// Datatypes can be unioned with [`Action::Union`] either @@ -378,6 +389,7 @@ where /// Note that declare inserts the constant into the database, /// so rules can use the constant directly as a variable. Declare { + ann: Ann, name: Symbol, sort: Symbol, }, @@ -396,7 +408,10 @@ where /// ``` /// /// Now `MathVec` can be used as an input or output sort. - Sort(Symbol, Option<(Symbol, Vec)>), + Sort( + Symbol, + Option<(Symbol, Vec>)>, + ), /// Declare an egglog function, which is a database table with a /// a functional dependency (also called a primary key) on its inputs to one output. /// @@ -442,7 +457,7 @@ where /// /// Functions that are not a datatype can be `set` /// with [`Action::Set`]. - Function(GenericFunctionDecl), + Function(GenericFunctionDecl), /// The `relation` is syntactic sugar for a named function which returns the `Unit` type. /// Example: /// ```text @@ -516,7 +531,7 @@ where Rule { name: Symbol, ruleset: Symbol, - rule: GenericRule, + rule: GenericRule, }, /// `rewrite` is syntactic sugar for a specific form of `rule` /// which simply unions the left and right hand sides. @@ -557,7 +572,7 @@ where /// ((union lhs (bitshift-left a 1)) /// (subsume (Mul a 2)))) /// ``` - Rewrite(Symbol, GenericRewrite, Subsume), + Rewrite(Symbol, GenericRewrite, Subsume), /// Similar to [`Command::Rewrite`], but /// generates two rules, one for each direction. /// @@ -574,14 +589,14 @@ where /// (rule ((= lhs (Var x))) /// ((union lhs (Mul (Var x) (Num 0))))) /// ``` - BiRewrite(Symbol, GenericRewrite), + BiRewrite(Symbol, GenericRewrite), /// Perform an [`Action`] on the global database /// (see documentation for [`Action`] for more details). /// Example: /// ```text /// (let xplusone (Add (Var "x") (Num 1))) /// ``` - Action(GenericAction), + Action(GenericAction), /// Runs a [`Schedule`], which specifies /// rulesets and the number of times to run them. /// @@ -596,17 +611,17 @@ where /// then runs `my-ruleset-2` four times. /// /// See [`Schedule`] for more details. - RunSchedule(GenericSchedule), + RunSchedule(GenericSchedule), /// Print runtime statistics about rules /// and rulesets so far. PrintOverallStatistics, // TODO provide simplify docs Simplify { - expr: GenericExpr, - schedule: GenericSchedule, + expr: GenericExpr, + schedule: GenericSchedule, }, // TODO provide calc docs - Calc(Vec, Vec>), + Calc(Ann, Vec, Vec>), /// The `query-extract` command runs a query, /// extracting the result for each match that it finds. /// For a simpler extraction command, use [`Action::Extract`] instead. @@ -634,7 +649,7 @@ where /// function. QueryExtract { variants: usize, - expr: GenericExpr, + expr: GenericExpr, }, /// The `check` command checks that the given facts /// match at least once in the current database. @@ -656,7 +671,7 @@ where /// [ERROR] Check failed /// [INFO ] Command failed as expected. /// ``` - Check(Vec>), + Check(Ann, Vec>), /// Currently unused, this command will check proofs when they are implemented. CheckProof, /// Print out rows a given function, extracting each of the elements of the function. @@ -677,7 +692,7 @@ where /// Extract and output a set of expressions to a file. Output { file: String, - exprs: Vec>, + exprs: Vec>, }, /// `push` the current egraph `n` times so that it is saved. /// Later, the current database and rules can be restored using `pop`. @@ -686,15 +701,16 @@ where /// The argument specifies how many egraphs to pop. Pop(usize), /// Assert that a command fails with an error. - Fail(Box>), + Fail(Box>), /// Include another egglog file directly as text and run it. Include(String), } -impl ToSexp for GenericCommand +impl ToSexp for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, + Ann: Clone, { fn to_sexp(&self) -> Sexp { match self { @@ -704,7 +720,7 @@ where } GenericCommand::BiRewrite(name, rewrite) => rewrite.to_sexp(*name, true, false), GenericCommand::Datatype { name, variants } => list!("datatype", name, ++ variants), - GenericCommand::Declare { name, sort } => list!("declare", name, sort), + GenericCommand::Declare { ann, name, sort } => list!("declare", name, sort), GenericCommand::Action(a) => a.to_sexp(), GenericCommand::Sort(name, None) => list!("sort", name), GenericCommand::Sort(name, Some((name2, args))) => { @@ -726,11 +742,11 @@ where } => rule.to_sexp(*ruleset, *name), GenericCommand::RunSchedule(sched) => list!("run-schedule", sched), GenericCommand::PrintOverallStatistics => list!("print-stats"), - GenericCommand::Calc(args, exprs) => list!("calc", list!(++ args), ++ exprs), + GenericCommand::Calc(ann, args, exprs) => list!("calc", list!(++ args), ++ exprs), GenericCommand::QueryExtract { variants, expr } => { list!("query-extract", ":variants", variants, expr) } - GenericCommand::Check(facts) => list!("check", ++ facts), + GenericCommand::Check(ann, facts) => list!("check", ++ facts), GenericCommand::CheckProof => list!("check-proof"), GenericCommand::Push(n) => list!("push", n), GenericCommand::Pop(n) => list!("pop", n), @@ -747,20 +763,22 @@ where } } -impl Display for GenericNCommand +impl Display for GenericNCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, + Ann: Clone, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_command()) } } -impl Display for GenericCommand +impl Display for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, + Ann: Clone, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { @@ -769,7 +787,7 @@ where name, rule, } => rule.fmt_with_ruleset(f, *ruleset, *name), - GenericCommand::Check(facts) => { + GenericCommand::Check(ann, facts) => { write!(f, "(check {})", ListDisplay(facts, "\n")) } _ => write!(f, "{}", self.to_sexp()), @@ -795,8 +813,8 @@ impl Display for IdentSort { } } -pub type RunConfig = GenericRunConfig; -pub(crate) type ResolvedRunConfig = GenericRunConfig; +pub type RunConfig = GenericRunConfig; +pub(crate) type ResolvedRunConfig = GenericRunConfig; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GenericRunConfig { @@ -806,7 +824,7 @@ pub struct GenericRunConfig { impl GenericRunConfig where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -842,15 +860,15 @@ where } } -pub type FunctionDecl = GenericFunctionDecl; -pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl; +pub type FunctionDecl = GenericFunctionDecl; +pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl; /// Represents the declaration of a function /// directly parsed from source syntax. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GenericFunctionDecl where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -915,7 +933,7 @@ impl FunctionDecl { }, merge: None, merge_action: Actions::default(), - default: Some(Expr::Lit((), Literal::Unit)), + default: Some(Expr::Lit(Span::DUMMY, Literal::Unit)), cost: None, unextractable: false, ignore_viz: false, @@ -925,7 +943,7 @@ impl FunctionDecl { impl GenericFunctionDecl where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -948,7 +966,7 @@ where impl ToSexp for GenericFunctionDecl where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -996,8 +1014,8 @@ where } } -pub type Fact = GenericFact; -pub(crate) type ResolvedFact = GenericFact; +pub type Fact = GenericFact; +pub(crate) type ResolvedFact = GenericFact; pub(crate) type MappedFact = GenericFact, Leaf, Ann>; /// Facts are the left-hand side of a [`Command::Rule`]. @@ -1021,7 +1039,7 @@ pub struct Facts(pub Vec>); impl Facts where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1089,7 +1107,7 @@ where impl GenericFact where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1117,26 +1135,28 @@ where pub(crate) fn subst( &self, - subst_leaf: &mut impl FnMut(&Leaf) -> GenericExpr, + subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, subst_head: &mut impl FnMut(&Head) -> Head2, ) -> GenericFact { self.map_exprs(&mut |e| e.subst(subst_leaf, subst_head)) } } -impl GenericFact +impl GenericFact where Leaf: Clone + PartialEq + Eq + Display + Hash, Head: Clone + Display, + Ann: Clone, { - pub(crate) fn make_unresolved(self) -> Fact + pub(crate) fn make_unresolved(self) -> GenericFact where Leaf: SymbolLike, Head: SymbolLike, { - self.subst(&mut |v| Expr::Var((), v.to_symbol()), &mut |h| { - h.to_symbol() - }) + self.subst( + &mut |ann, v| GenericExpr::Var(ann.clone(), v.to_symbol()), + &mut |h| h.to_symbol(), + ) } } @@ -1191,14 +1211,14 @@ pub enum Change { Subsume, } -pub type Action = GenericAction; -pub(crate) type MappedAction = GenericAction, Symbol, ()>; -pub(crate) type ResolvedAction = GenericAction; +pub type Action = GenericAction; +pub(crate) type MappedAction = GenericAction, Symbol, Span>; +pub(crate) type ResolvedAction = GenericAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum GenericAction where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1257,16 +1277,16 @@ where pub struct GenericActions< Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Clone + Default, + Ann: Clone, >(pub Vec>); -pub type Actions = GenericActions; -pub(crate) type ResolvedActions = GenericActions; +pub type Actions = GenericActions; +pub(crate) type ResolvedActions = GenericActions; pub(crate) type MappedActions = GenericActions, Leaf, Ann>; impl Default for GenericActions where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1277,7 +1297,7 @@ where impl GenericActions where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1303,7 +1323,7 @@ where impl ToSexp for GenericAction where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1332,7 +1352,7 @@ impl GenericAction where Head: Clone + Display, Leaf: Clone + Eq + Display + Hash, - Ann: Clone + Default, + Ann: Clone, { // Applys `f` to all expressions in the action. pub fn map_exprs( @@ -1401,14 +1421,17 @@ where } } - pub fn subst(&self, subst: &mut impl FnMut(&Leaf) -> GenericExpr) -> Self { + pub fn subst( + &self, + subst: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, + ) -> Self { self.map_exprs(&mut |e| e.subst_leaf(subst)) } pub fn map_def_use(self, fvar: &mut impl FnMut(Leaf, bool) -> Leaf) -> Self { macro_rules! fvar_expr { () => { - |s: _| GenericExpr::Var(Ann::default(), fvar(s.clone(), false)) + |ann, s: _| GenericExpr::Var(ann.clone(), fvar(s.clone(), false)) }; } match self { @@ -1452,7 +1475,7 @@ where impl Display for GenericAction where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1467,23 +1490,24 @@ pub(crate) struct CompiledRule { pub(crate) program: Program, } -pub type Rule = GenericRule; -pub(crate) type ResolvedRule = GenericRule; +pub type Rule = GenericRule; +pub(crate) type ResolvedRule = GenericRule; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GenericRule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { + pub ann: Ann, pub head: GenericActions, pub body: Vec>, } impl GenericRule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1492,6 +1516,7 @@ where f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { Self { + ann: self.ann, head: self.head.visit_exprs(f), body: self .body @@ -1504,7 +1529,7 @@ where impl GenericRule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1554,7 +1579,7 @@ where impl GenericRule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1579,7 +1604,7 @@ where impl Display for GenericRule where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1588,10 +1613,11 @@ where } } -type Rewrite = GenericRewrite; +type Rewrite = GenericRewrite; #[derive(Clone, Debug)] pub struct GenericRewrite { + pub ann: Ann, pub lhs: GenericExpr, pub rhs: GenericExpr, pub conditions: Vec>, @@ -1636,7 +1662,7 @@ impl Display for GenericRewrite MappedExpr where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1661,16 +1687,16 @@ where } } -impl GenericActions +impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { - pub fn new(actions: Vec>) -> Self { + pub fn new(actions: Vec>) -> Self { Self(actions) } - pub fn singleton(action: GenericAction) -> Self { + pub fn singleton(action: GenericAction) -> Self { Self(vec![action]) } } diff --git a/src/ast/parse.lalrpop b/src/ast/parse.lalrpop index 31457aa8..8cf89e00 100644 --- a/src/ast/parse.lalrpop +++ b/src/ast/parse.lalrpop @@ -4,7 +4,7 @@ use crate::Symbol; use crate::Schedule; use ordered_float::OrderedFloat; -grammar; +grammar(filename: Symbol); extern { type Error = String; diff --git a/src/ast/remove_globals.rs b/src/ast/remove_globals.rs index 00814dea..3407d350 100644 --- a/src/ast/remove_globals.rs +++ b/src/ast/remove_globals.rs @@ -156,7 +156,7 @@ impl<'a> GlobalRemover<'a> { globals.insert( resolved_var.clone(), GenericExpr::Var( - (), + expr.ann(), ResolvedVar { name: new_name, sort: resolved_var.sort.clone(), @@ -171,13 +171,14 @@ impl<'a> GlobalRemover<'a> { .iter() .map(|(old, new)| { GenericFact::Eq(vec![ - GenericExpr::Call((), resolved_var_to_call(old), vec![]), + GenericExpr::Call(new.ann(), resolved_var_to_call(old), vec![]), new.clone(), ]) }) .collect(); let new_rule = GenericRule { + ann: rule.ann, // instrument the old facts and add the new facts to the end body: rule .body diff --git a/src/constraint.rs b/src/constraint.rs index d919a4ea..956a9ddb 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -2,14 +2,9 @@ use crate::{ ast::{ GenericAction, GenericActions, GenericExpr, GenericFact, MappedAction, ResolvedAction, ResolvedActions, ResolvedExpr, ResolvedFact, ResolvedVar, - }, - core::{ + }, core::{ Atom, AtomTerm, CoreAction, CoreRule, GenericCoreActions, Query, ResolvedCall, SymbolOrEq, - }, - sort::I64Sort, - typechecking::TypeError, - util::{FreshGen, HashMap, HashSet, SymbolGen}, - ArcSort, CorrespondingVar, Symbol, TypeInfo, + }, sort::I64Sort, typechecking::TypeError, util::{FreshGen, HashMap, HashSet, SymbolGen}, ArcSort, CorrespondingVar, Span, Symbol, TypeInfo }; use core::hash::Hash; use std::{fmt::Debug, iter::once, mem::swap}; @@ -217,19 +212,19 @@ where impl Assignment { pub(crate) fn annotate_expr( &self, - expr: &GenericExpr, Symbol, ()>, + expr: &GenericExpr, Symbol, Span>, typeinfo: &TypeInfo, ) -> ResolvedExpr { match &expr { - GenericExpr::Lit((), literal) => ResolvedExpr::Lit((), literal.clone()), - GenericExpr::Var((), var) => { + GenericExpr::Lit(span, literal) => ResolvedExpr::Lit(*span, literal.clone()), + GenericExpr::Var(span, var) => { let global_ty = typeinfo.lookup_global(var); let ty = global_ty .clone() .or_else(|| self.get(&AtomTerm::Var(*var)).cloned()) .expect("All variables should be assigned before annotation"); ResolvedExpr::Var( - (), + *span, ResolvedVar { name: *var, sort: ty.clone(), @@ -238,7 +233,7 @@ impl Assignment { ) } GenericExpr::Call( - (), + span, CorrespondingVar { head, to: corresponding_var, @@ -260,14 +255,14 @@ impl Assignment { )) .collect(); let resolved_call = ResolvedCall::from_resolution(head, &types, typeinfo); - GenericExpr::Call((), resolved_call, args) + GenericExpr::Call(*span, resolved_call, args) } } } pub(crate) fn annotate_fact( &self, - facts: &GenericFact, Symbol, ()>, + facts: &GenericFact, Symbol, Span>, typeinfo: &TypeInfo, ) -> ResolvedFact { match facts { @@ -283,7 +278,7 @@ impl Assignment { pub(crate) fn annotate_facts( &self, - mapped_facts: &[GenericFact, Symbol, ()>], + mapped_facts: &[GenericFact, Symbol, Span>], typeinfo: &TypeInfo, ) -> Vec { mapped_facts @@ -298,12 +293,12 @@ impl Assignment { typeinfo: &TypeInfo, ) -> Result { match action { - GenericAction::Let((), var, expr) => { + GenericAction::Let(span, var, expr) => { let ty = self .get(&AtomTerm::Var(*var)) .expect("All variables should be assigned before annotation"); Ok(ResolvedAction::Let( - (), + *span, ResolvedVar { name: *var, sort: ty.clone(), @@ -314,7 +309,7 @@ impl Assignment { } // Note mapped_var for set is a dummy variable that does not mean anything GenericAction::Set( - (), + span, CorrespondingVar { head, to: _mapped_var, @@ -336,11 +331,11 @@ impl Assignment { if !matches!(resolved_call, ResolvedCall::Func(_)) { return Err(TypeError::UnboundFunction(*head)); } - Ok(ResolvedAction::Set((), resolved_call, children, rhs)) + Ok(ResolvedAction::Set(*span, resolved_call, children, rhs)) } // Note mapped_var for delete is a dummy variable that does not mean anything GenericAction::Change( - (), + span, change, CorrespondingVar { head, @@ -360,32 +355,32 @@ impl Assignment { ResolvedCall::from_resolution_func_types(head, &types, typeinfo) .ok_or_else(|| TypeError::UnboundFunction(*head))?; Ok(ResolvedAction::Change( - (), + *span, *change, resolved_call, children.clone(), )) } - GenericAction::Union((), lhs, rhs) => Ok(ResolvedAction::Union( - (), + GenericAction::Union(span, lhs, rhs) => Ok(ResolvedAction::Union( + *span, self.annotate_expr(lhs, typeinfo), self.annotate_expr(rhs, typeinfo), )), - GenericAction::Extract((), lhs, rhs) => Ok(ResolvedAction::Extract( - (), + GenericAction::Extract(span, lhs, rhs) => Ok(ResolvedAction::Extract( + *span, self.annotate_expr(lhs, typeinfo), self.annotate_expr(rhs, typeinfo), )), - GenericAction::Panic((), msg) => Ok(ResolvedAction::Panic((), msg.clone())), - GenericAction::Expr((), expr) => { - Ok(ResolvedAction::Expr((), self.annotate_expr(expr, typeinfo))) + GenericAction::Panic(span, msg) => Ok(ResolvedAction::Panic(*span, msg.clone())), + GenericAction::Expr(span, expr) => { + Ok(ResolvedAction::Expr(*span, self.annotate_expr(expr, typeinfo))) } } } pub(crate) fn annotate_actions( &self, - mapped_actions: &GenericActions, Symbol, ()>, + mapped_actions: &GenericActions, Symbol, Span>, typeinfo: &TypeInfo, ) -> Result { let actions = mapped_actions diff --git a/src/core.rs b/src/core.rs index 15e97de0..2b05d18f 100644 --- a/src/core.rs +++ b/src/core.rs @@ -141,9 +141,9 @@ pub type ResolvedAtomTerm = GenericAtomTerm; impl AtomTerm { pub fn to_expr(&self) -> Expr { match self { - AtomTerm::Var(v) => Expr::Var((), *v), - AtomTerm::Literal(l) => Expr::Lit((), l.clone()), - AtomTerm::Global(v) => Expr::Var((), *v), + AtomTerm::Var(v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), + AtomTerm::Literal(l) => Expr::Lit(todo!("investigate usages of to_expr()"), l.clone()), + AtomTerm::Global(v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), } } } @@ -368,10 +368,11 @@ where } #[allow(clippy::type_complexity)] -impl GenericActions +impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, + Ann: Clone, { pub(crate) fn to_core_actions>( &self, @@ -381,7 +382,7 @@ where ) -> Result< ( GenericCoreActions, - MappedActions, + MappedActions, ), TypeError, > @@ -389,14 +390,14 @@ where Leaf: SymbolLike, { let mut norm_actions = vec![]; - let mut mapped_actions: MappedActions = GenericActions(vec![]); + let mut mapped_actions: MappedActions = GenericActions(vec![]); // During the lowering, there are two important guaratees: // Every used variable should be bound. // Every introduced variable should be unbound before. for action in self.0.iter() { match action { - GenericAction::Let(_ann, var, expr) => { + GenericAction::Let(ann, var, expr) => { if binding.contains(var) { return Err(TypeError::AlreadyDefined(var.to_symbol())); } @@ -409,10 +410,10 @@ where )); mapped_actions .0 - .push(GenericAction::Let((), var.clone(), mapped_expr)); + .push(GenericAction::Let(ann.clone(), var.clone(), mapped_expr)); binding.insert(var.clone()); } - GenericAction::Set(_ann, head, args, expr) => { + GenericAction::Set(ann, head, args, expr) => { let mut mapped_args = vec![]; for arg in args { let (actions, mapped_arg) = @@ -433,13 +434,13 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Set( - (), + ann.clone(), CorrespondingVar::new(head.clone(), v), mapped_args, mapped_expr, )); } - GenericAction::Change(_ann, change, head, args) => { + GenericAction::Change(ann, change, head, args) => { let mut mapped_args = vec![]; for arg in args { let (actions, mapped_arg) = @@ -457,13 +458,13 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Change( - (), + ann.clone(), *change, CorrespondingVar::new(head.clone(), v), mapped_args, )); } - GenericAction::Union(_ann, e1, e2) => { + GenericAction::Union(ann, e1, e2) => { let (actions1, mapped_e1) = e1.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions1.0); let (actions2, mapped_e2) = e2.to_core_actions(typeinfo, binding, fresh_gen)?; @@ -474,9 +475,9 @@ where )); mapped_actions .0 - .push(GenericAction::Union((), mapped_e1, mapped_e2)); + .push(GenericAction::Union(ann.clone(), mapped_e1, mapped_e2)); } - GenericAction::Extract(_ann, e, n) => { + GenericAction::Extract(ann, e, n) => { let (actions, mapped_e) = e.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); let (actions, mapped_n) = n.to_core_actions(typeinfo, binding, fresh_gen)?; @@ -487,19 +488,19 @@ where )); mapped_actions .0 - .push(GenericAction::Extract((), mapped_e, mapped_n)); + .push(GenericAction::Extract(ann.clone(), mapped_e, mapped_n)); } - GenericAction::Panic(_ann, string) => { + GenericAction::Panic(ann, string) => { norm_actions.push(GenericCoreAction::Panic(string.clone())); mapped_actions .0 - .push(GenericAction::Panic((), string.clone())); + .push(GenericAction::Panic(ann.clone(), string.clone())); } - GenericAction::Expr(_ann, expr) => { + GenericAction::Expr(ann, expr) => { let (actions, mapped_expr) = expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); - mapped_actions.0.push(GenericAction::Expr((), mapped_expr)); + mapped_actions.0.push(GenericAction::Expr(ann.clone(), mapped_expr)); } } } @@ -509,7 +510,7 @@ where impl GenericExpr where - Ann: Clone + Default, + Ann: Clone, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -564,27 +565,27 @@ where typeinfo: &TypeInfo, binding: &mut IndexSet, fresh_gen: &mut FG, - ) -> Result<(GenericCoreActions, MappedExpr), TypeError> + ) -> Result<(GenericCoreActions, MappedExpr), TypeError> where Leaf: Hash + Eq + SymbolLike, { match self { - GenericExpr::Lit(_ann, lit) => Ok(( + GenericExpr::Lit(ann, lit) => Ok(( GenericCoreActions::default(), - GenericExpr::Lit((), lit.clone()), + GenericExpr::Lit(ann.clone(), lit.clone()), )), - GenericExpr::Var(_ann, v) => { + GenericExpr::Var(ann, v) => { let sym = v.to_symbol(); if binding.contains(v) || typeinfo.is_global(sym) { Ok(( GenericCoreActions::default(), - GenericExpr::Var((), v.clone()), + GenericExpr::Var(ann.clone(), v.clone()), )) } else { Err(TypeError::Unbound(sym)) } } - GenericExpr::Call(_ann, f, args) => { + GenericExpr::Call(ann, f, args) => { let mut norm_actions = vec![]; let mut norm_args = vec![]; let mut mapped_args = vec![]; @@ -602,7 +603,7 @@ where norm_actions.push(GenericCoreAction::Let(var.clone(), f.clone(), norm_args)); Ok(( GenericCoreActions::new(norm_actions), - GenericExpr::Call((), CorrespondingVar::new(f.clone(), var), mapped_args), + GenericExpr::Call(ann.clone(), CorrespondingVar::new(f.clone(), var), mapped_args), )) } } @@ -719,10 +720,11 @@ where } } -impl GenericRule +impl GenericRule where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash + Debug, + Ann: Clone, { pub(crate) fn to_core_rule( &self, @@ -732,7 +734,7 @@ where where Leaf: SymbolLike, { - let GenericRule { head, body } = self; + let GenericRule { ann, head, body } = self; let (body, _correspondence) = Facts(body.clone()).to_query(typeinfo, &mut fresh_gen); let mut binding = body.get_vars(); diff --git a/src/extract.rs b/src/extract.rs index c89a28b0..9fabd80d 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -28,6 +28,7 @@ impl EGraph { /// let mut egraph = EGraph::default(); /// egraph /// .parse_and_run_program( + /// None, /// "(datatype Op (Add i64 i64)) /// (let expr (Add 1 1))", /// ) diff --git a/src/lib.rs b/src/lib.rs index 2a4b06a9..16a59550 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -482,7 +482,7 @@ impl Default for EGraph { #[derive(Debug, Error)] #[error("Not found: {0}")] -pub struct NotFoundError(Expr); +pub struct NotFoundError(String); /// For each rule, we produce a `SearchResult` /// storing data about that rule's matches. @@ -843,8 +843,8 @@ impl EGraph { // returns whether the egraph was updated fn run_schedule(&mut self, sched: &ResolvedSchedule) -> RunReport { match sched { - ResolvedSchedule::Run(config) => self.run_rules(config), - ResolvedSchedule::Repeat(limit, sched) => { + ResolvedSchedule::Run(span, config) => self.run_rules(span, config), + ResolvedSchedule::Repeat(span, limit, sched) => { let mut report = RunReport::default(); for _i in 0..*limit { let rec = self.run_schedule(sched); @@ -855,7 +855,7 @@ impl EGraph { } report } - ResolvedSchedule::Saturate(sched) => { + ResolvedSchedule::Saturate(span, sched) => { let mut report = RunReport::default(); loop { let rec = self.run_schedule(sched); @@ -866,7 +866,7 @@ impl EGraph { } report } - ResolvedSchedule::Sequence(scheds) => { + ResolvedSchedule::Sequence(span, scheds) => { let mut report = RunReport::default(); for sched in scheds { report = report.union(&self.run_schedule(sched)); @@ -893,7 +893,7 @@ impl EGraph { termdag.to_string(&term) } - fn run_rules(&mut self, config: &ResolvedRunConfig) -> RunReport { + fn run_rules(&mut self, span: &Span, config: &ResolvedRunConfig) -> RunReport { let mut report: RunReport = Default::default(); // first rebuild @@ -908,7 +908,7 @@ impl EGraph { let GenericRunConfig { ruleset, until } = config; if let Some(facts) = until { - if self.check_facts(facts).is_ok() { + if self.check_facts(span, facts).is_ok() { log::info!( "Breaking early because of facts:\n {}!", ListDisplay(facts, "\n") @@ -1135,7 +1135,7 @@ impl EGraph { pub fn eval_expr(&mut self, expr: &Expr) -> Result<(ArcSort, Value), Error> { let fresh_name = self.desugar.get_fresh(); - let command = Command::Action(Action::Let((), fresh_name, expr.clone())); + let command = Command::Action(Action::Let(Span::DUMMY, fresh_name, expr.clone())); self.run_program(vec![command])?; // find the table with the same name as the fresh name let func = self.functions.get(&fresh_name).unwrap(); @@ -1209,8 +1209,9 @@ impl EGraph { } } - fn check_facts(&mut self, facts: &[ResolvedFact]) -> Result<(), Error> { + fn check_facts(&mut self, span: &Span, facts: &[ResolvedFact]) -> Result<(), Error> { let rule = ast::ResolvedRule { + ann: span.clone(), head: ResolvedActions::default(), body: facts.to_vec(), }; @@ -1288,13 +1289,13 @@ impl EGraph { log::info!("Overall statistics:\n{}", self.overall_run_report); self.print_msg(format!("Overall statistics:\n{}", self.overall_run_report)); } - ResolvedNCommand::Check(facts) => { - self.check_facts(&facts)?; + ResolvedNCommand::Check(ann, facts) => { + self.check_facts(&ann, &facts)?; log::info!("Checked fact {:?}.", facts); } ResolvedNCommand::CheckProof => log::error!("TODO implement proofs"), ResolvedNCommand::CoreAction(action) => match &action { - ResolvedAction::Let((), name, contents) => { + ResolvedAction::Let(_, name, contents) => { panic!("Globals should have been desugared away: {name} = {contents}") } _ => { @@ -1385,6 +1386,7 @@ impl EGraph { let mut contents = String::new(); f.read_to_string(&mut contents).unwrap(); + let span = Span::DUMMY; let mut actions: Vec = vec![]; let mut str_buf: Vec<&str> = vec![]; for line in contents.lines() { @@ -1396,10 +1398,10 @@ impl EGraph { let parse = |s: &str| -> Expr { match s.parse::() { - Ok(i) => Expr::Lit((), Literal::Int(i)), + Ok(i) => Expr::Lit(span, Literal::Int(i)), Err(_) => match s.parse::() { - Ok(f) => Expr::Lit((), Literal::F64(f.into())), - Err(_) => Expr::Lit((), Literal::String(s.into())), + Ok(f) => Expr::Lit(span, Literal::F64(f.into())), + Err(_) => Expr::Lit(span, Literal::String(s.into())), }, } }; @@ -1408,10 +1410,10 @@ impl EGraph { actions.push( if function_type.is_datatype || function_type.output.name() == UNIT_SYM.into() { - Action::Expr((), Expr::Call((), func_name, exprs)) + Action::Expr(span, Expr::Call(span, func_name, exprs)) } else { let out = exprs.pop().unwrap(); - Action::Set((), func_name, exprs, out) + Action::Set(span, func_name, exprs, out) }, ); } @@ -1482,12 +1484,12 @@ impl EGraph { Ok(self.flush_msgs()) } - pub fn parse_program(&self, input: &str) -> Result, Error> { - self.desugar.parse_program(input) + pub fn parse_program(&self, filename: Option, input: &str) -> Result, Error> { + self.desugar.parse_program(filename, input) } - pub fn parse_and_run_program(&mut self, input: &str) -> Result, Error> { - let parsed = self.desugar.parse_program(input)?; + pub fn parse_and_run_program(&mut self, filename: Option, input: &str) -> Result, Error> { + let parsed = self.desugar.parse_program(filename, input)?; self.run_program(parsed) } @@ -1655,6 +1657,7 @@ mod tests { let mut egraph = EGraph::default(); egraph .parse_and_run_program( + None, " (sort IntVec (Vec i64)) ", @@ -1670,6 +1673,7 @@ mod tests { }); egraph .parse_and_run_program( + None, " (let a (vec-of 1 2 3 4 5 6)) (let b (vec-of 6 5 4 3 2 1)) diff --git a/src/main.rs b/src/main.rs index 2b597814..02f7a870 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,10 @@ struct Args { desugar: bool, #[clap(long)] resugar: bool, + /// Currently unused. #[clap(long)] proofs: bool, + /// Currently unused. /// Use the rust backend implimentation of eqsat, /// including a rust implementation of the union-find /// data structure and the rust implementation of @@ -60,12 +62,13 @@ fn main() { egraph.fact_directory = args.fact_directory.clone(); egraph.seminaive = !args.naive; egraph.run_mode = args.show; + // NB: both terms_encoding and proofs are currently unused if args.terms_encoding { egraph.enable_terms_encoding(); } if args.proofs { egraph - .parse_and_run_program("(set-option enable_proofs 1)") + .parse_and_run_program(None, "(set-option enable_proofs 1)") .unwrap(); } egraph @@ -78,7 +81,7 @@ fn main() { for line in BufReader::new(stdin).lines() { match line { - Ok(line_str) => match egraph.parse_and_run_program(&line_str) { + Ok(line_str) => match egraph.parse_and_run_program(None, &line_str) { Ok(msgs) => { for msg in msgs { println!("{msg}"); @@ -108,15 +111,8 @@ fn main() { panic!("Failed to read file {arg}") }); let mut egraph = mk_egraph(); - let already_enables = program_read.starts_with("(set-option enable_proofs 1)"); - let (program, program_offset) = if args.proofs && !already_enables { - let expr = "(set-option enable_proofs 1)\n"; - (format!("{}{}", expr, program_read), expr.len()) - } else { - (program_read, 0) - }; - match egraph.parse_and_run_program(&program) { + match egraph.parse_and_run_program(Some(input.into()),&program) { Ok(msgs) => { for msg in msgs { println!("{msg}"); diff --git a/src/sort/bool.rs b/src/sort/bool.rs index ae5a5902..0b4bbe5d 100644 --- a/src/sort/bool.rs +++ b/src/sort/bool.rs @@ -31,9 +31,9 @@ impl Sort for BoolSort { add_primitives!(eg, "=>" = |a: bool, b: bool| -> bool { !a || b }); } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert!(value.tag == self.name()); - (1, Expr::Lit((), Literal::Bool(value.bits > 0))) + (1, GeneratedExpr::Lit((), Literal::Bool(value.bits > 0))) } } diff --git a/src/sort/f64.rs b/src/sort/f64.rs index 297d64d7..4322b74a 100755 --- a/src/sort/f64.rs +++ b/src/sort/f64.rs @@ -53,11 +53,11 @@ impl Sort for F64Sort { } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert!(value.tag == self.name()); ( 1, - Expr::Lit((), Literal::F64(OrderedFloat(f64::from_bits(value.bits)))), + GeneratedExpr::Lit((), Literal::F64(OrderedFloat(f64::from_bits(value.bits)))), ) } } diff --git a/src/sort/fn.rs b/src/sort/fn.rs index 6ab2e3f9..194d1a8c 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -62,13 +62,13 @@ impl FunctionSort { name: Symbol, args: &[Expr], ) -> Result { - if let [Expr::Call((), first, rest_args), Expr::Var((), output)] = args { + if let [Expr::Call(_, first, rest_args), Expr::Var(_, output)] = args { let output_sort = typeinfo .sorts .get(output) .ok_or(TypeError::UndefinedSort(*output))?; let all_args = once(first).chain(rest_args.iter().map(|arg| { - if let Expr::Var((), arg) = arg { + if let Expr::Var(_, arg) = arg { arg } else { panic!("function sort must be called with list of input sorts"); @@ -151,7 +151,7 @@ impl Sort for FunctionSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -164,10 +164,10 @@ impl Sort for FunctionSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, Expr)> { + ) -> Option<(Cost, GeneratedExpr)> { let ValueFunction(name, inputs) = ValueFunction::load(self, &value); let (cost, args) = inputs.into_iter().try_fold( - (1usize, vec![Expr::Lit((), Literal::String(name))]), + (1usize, vec![GeneratedExpr::Lit((), Literal::String(name))]), |(cost, mut args), (sort, value)| { let (new_cost, term) = extractor.find_best(value, termdag, &sort)?; args.push(termdag.term_to_expr(&term)); @@ -175,7 +175,7 @@ impl Sort for FunctionSort { }, )?; - Some((cost, Expr::call("unstable-fn", args))) + Some((cost, GeneratedExpr::call("unstable-fn", args))) } } @@ -324,9 +324,9 @@ fn call_fn(egraph: &mut EGraph, name: &Symbol, types: Vec, args: Vec (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert!(value.tag == self.name()); - (1, Expr::Lit((), Literal::Int(value.bits as _))) + (1, GeneratedExpr::Lit((), Literal::Int(value.bits as _))) } } diff --git a/src/sort/map.rs b/src/sort/map.rs index 4edfb20e..eea2915d 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -29,7 +29,7 @@ impl MapSort { name: Symbol, args: &[Expr], ) -> Result { - if let [Expr::Var((), k), Expr::Var((), v)] = args { + if let [Expr::Var(_, k), Expr::Var(_, v)] = args { let k = typeinfo.sorts.get(k).ok_or(TypeError::UndefinedSort(*k))?; let v = typeinfo.sorts.get(v).ok_or(TypeError::UndefinedSort(*v))?; @@ -150,7 +150,7 @@ impl Sort for MapSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -163,15 +163,15 @@ impl Sort for MapSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, Expr)> { + ) -> Option<(Cost, GeneratedExpr)> { let map = ValueMap::load(self, &value); - let mut expr = Expr::call("map-empty", []); + let mut expr = GeneratedExpr::call("map-empty", []); let mut cost = 0usize; for (k, v) in map.iter().rev() { let k = extractor.find_best(*k, termdag, &self.key)?; let v = extractor.find_best(*v, termdag, &self.value)?; cost = cost.saturating_add(k.0).saturating_add(v.0); - expr = Expr::call( + expr = GeneratedExpr::call( "map-insert", [expr, termdag.term_to_expr(&k.1), termdag.term_to_expr(&v.1)], ) diff --git a/src/sort/mod.rs b/src/sort/mod.rs index f9eb396a..b5695450 100644 --- a/src/sort/mod.rs +++ b/src/sort/mod.rs @@ -84,7 +84,7 @@ pub trait Sort: Any + Send + Sync + Debug { } /// Extracting an expression (with smallest cost) out of a primitive value - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr); + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr); /// For values like EqSort containers, to make/extract an expression from it /// requires an extractor. Moreover, the extraction may be unsuccessful if @@ -97,7 +97,7 @@ pub trait Sort: Any + Send + Sync + Debug { value: Value, _extractor: &Extractor, _termdag: &mut TermDag, - ) -> Option<(Cost, Expr)> { + ) -> Option<(Cost, GeneratedExpr)> { Some(self.make_expr(egraph, value)) } } @@ -131,7 +131,7 @@ impl Sort for EqSort { } } - fn make_expr(&self, _egraph: &EGraph, _value: Value) -> (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, _value: Value) -> (Cost, GeneratedExpr) { unimplemented!("No make_expr for EqSort {}", self.name) } } diff --git a/src/sort/rational.rs b/src/sort/rational.rs index e7880059..7b757f60 100644 --- a/src/sort/rational.rs +++ b/src/sort/rational.rs @@ -109,18 +109,19 @@ impl Sort for RationalSort { add_primitives!(eg, "<=" = |a: R, b: R| -> Opt { if a <= b {Some(())} else {None} }); add_primitives!(eg, ">=" = |a: R, b: R| -> Opt { if a >= b {Some(())} else {None} }); } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { + + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert!(value.tag == self.name()); let rat = R::load(self, &value); let numer = *rat.numer(); let denom = *rat.denom(); ( 1, - Expr::call( + GeneratedExpr::call( "rational", vec![ - Expr::Lit((), Literal::Int(numer)), - Expr::Lit((), Literal::Int(denom)), + GeneratedExpr::Lit((), Literal::Int(numer)), + GeneratedExpr::Lit((), Literal::Int(denom)), ], ), ) diff --git a/src/sort/set.rs b/src/sort/set.rs index d38a77b5..c61169df 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -28,7 +28,7 @@ impl SetSort { name: Symbol, args: &[Expr], ) -> Result { - if let [Expr::Var((), e)] = args { + if let [Expr::Var(_, e)] = args { let e = typeinfo.sorts.get(e).ok_or(TypeError::UndefinedSort(*e))?; if e.is_eq_container_sort() { @@ -166,7 +166,7 @@ impl Sort for SetSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -179,14 +179,14 @@ impl Sort for SetSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, Expr)> { + ) -> Option<(Cost, GeneratedExpr)> { let set = ValueSet::load(self, &value); - let mut expr = Expr::call("set-empty", []); + let mut expr = GeneratedExpr::call("set-empty", []); let mut cost = 0usize; for e in set.iter().rev() { let e = extractor.find_best(*e, termdag, &self.element)?; cost = cost.saturating_add(e.0); - expr = Expr::call("set-insert", [expr, termdag.term_to_expr(&e.1)]) + expr = GeneratedExpr::call("set-insert", [expr, termdag.term_to_expr(&e.1)]) } Some((cost, expr)) } diff --git a/src/sort/string.rs b/src/sort/string.rs index 259a46f1..745d14e0 100644 --- a/src/sort/string.rs +++ b/src/sort/string.rs @@ -24,10 +24,10 @@ impl Sort for StringSort { self } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert!(value.tag == self.name); let sym = Symbol::from(NonZeroU32::new(value.bits as _).unwrap()); - (1, Expr::Lit((), Literal::String(sym))) + (1, GeneratedExpr::Lit((), Literal::String(sym))) } fn register_primitives(self: Arc, typeinfo: &mut TypeInfo) { diff --git a/src/sort/unit.rs b/src/sort/unit.rs index 58b8f2f0..a73a5983 100644 --- a/src/sort/unit.rs +++ b/src/sort/unit.rs @@ -25,9 +25,9 @@ impl Sort for UnitSort { type_info.add_primitive(NotEqualPrimitive { unit: self }) } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { assert_eq!(value.tag, self.name); - (1, Expr::Lit((), Literal::Unit)) + (1, GeneratedExpr::Lit((), Literal::Unit)) } } diff --git a/src/sort/vec.rs b/src/sort/vec.rs index 9933799a..99530247 100644 --- a/src/sort/vec.rs +++ b/src/sort/vec.rs @@ -43,7 +43,7 @@ impl VecSort { name: Symbol, args: &[Expr], ) -> Result { - if let [Expr::Var((), e)] = args { + if let [Expr::Var(_, e)] = args { let e = typeinfo.sorts.get(e).ok_or(TypeError::UndefinedSort(*e))?; if e.is_eq_container_sort() { @@ -165,7 +165,7 @@ impl Sort for VecSort { }) } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -178,12 +178,12 @@ impl Sort for VecSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, Expr)> { + ) -> Option<(Cost, GeneratedExpr)> { let vec = ValueVec::load(self, &value); let mut cost = 0usize; if vec.is_empty() { - Some((cost, Expr::call("vec-empty", []))) + Some((cost, GeneratedExpr::call("vec-empty", []))) } else { let elems = vec .into_iter() @@ -194,7 +194,7 @@ impl Sort for VecSort { }) .collect::>>()?; - Some((cost, Expr::call("vec-of", elems))) + Some((cost, GeneratedExpr::call("vec-of", elems))) } } } @@ -525,6 +525,7 @@ mod tests { let mut egraph = EGraph::default(); let outputs = egraph .parse_and_run_program( + None, r#" (sort IVec (Vec i64)) (let v0 (vec-empty)) @@ -537,13 +538,16 @@ mod tests { // Check extracted expr is parsed as an original expr egraph - .parse_and_run_program(&format!( - r#" + .parse_and_run_program( + None, + &format!( + r#" (check (= v0 {})) (check (= v1 {})) "#, - outputs[0], outputs[1], - )) + outputs[0], outputs[1], + ), + ) .unwrap(); } } diff --git a/src/termdag.rs b/src/termdag.rs index 67f260c1..b3906426 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,7 +1,5 @@ use crate::{ - ast::{Expr, Literal}, - util::{HashMap, HashSet}, - Symbol, + ast::{Expr, Literal}, util::{HashMap, HashSet}, GeneratedExpr, GenericExpr, Symbol }; pub type TermId = usize; @@ -109,11 +107,11 @@ impl TermDag { /// This involves inserting every subexpression into this DAG. Because /// TermDags are hashconsed, the resulting term is guaranteed to maximally /// share subterms. - pub fn expr_to_term(&mut self, expr: &Expr) -> Term { + pub fn expr_to_term(&mut self, expr: &GenericExpr) -> Term { let res = match expr { - Expr::Lit((), lit) => Term::Lit(lit.clone()), - Expr::Var((), v) => Term::Var(*v), - Expr::Call((), op, args) => { + GenericExpr::Lit(_, lit) => Term::Lit(lit.clone()), + GenericExpr::Var(_, v) => Term::Var(*v), + GenericExpr::Call(_, op, args) => { let args = args .iter() .map(|a| { @@ -131,10 +129,10 @@ impl TermDag { /// Recursively converts the given term to an expression. /// /// Panics if the term contains subterms that are not in the DAG. - pub fn term_to_expr(&self, term: &Term) -> Expr { + pub fn term_to_expr(&self, term: &Term) -> GeneratedExpr { match term { - Term::Lit(lit) => Expr::Lit((), lit.clone()), - Term::Var(v) => Expr::Var((), *v), + Term::Lit(lit) => GeneratedExpr::Lit((), lit.clone()), + Term::Var(v) => GeneratedExpr::Var((), *v), Term::App(op, args) => { let args = args .iter() @@ -143,7 +141,7 @@ impl TermDag { self.term_to_expr(&term) }) .collect(); - Expr::Call((), *op, args) + GeneratedExpr::Call((), *op, args) } } } @@ -233,7 +231,7 @@ mod tests { let (td, t) = parse_term(s); match_term_app!(t; { ("f", [_, x, _, _]) => - assert_eq!(td.term_to_expr(&td.get(*x)), ast::Expr::Var((), Symbol::new("x"))), + assert_eq!(td.term_to_expr(&td.get(*x)), ast::GeneratedExpr::Var((), Symbol::new("x"))), (head, _) => panic!("unexpected head {}, in {}:{}:{}", head, file!(), line!(), column!()) }) } diff --git a/src/typechecking.rs b/src/typechecking.rs index b40e77fd..f5303b49 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -180,7 +180,7 @@ impl TypeInfo { self.declare_sort(*sort, presort_and_args)?; ResolvedNCommand::Sort(*sort, presort_and_args.clone()) } - NCommand::CoreAction(Action::Let(_, var, expr)) => { + NCommand::CoreAction(Action::Let(ann, var, expr)) => { let expr = self.typecheck_expr(expr, &Default::default())?; let output_type = expr.output_type(self); self.global_types.insert(*var, output_type.clone()); @@ -190,12 +190,14 @@ impl TypeInfo { // not a global reference, but a global binding is_global_ref: false, }; - ResolvedNCommand::CoreAction(ResolvedAction::Let((), var, expr)) + ResolvedNCommand::CoreAction(ResolvedAction::Let(ann.clone(), var, expr)) } NCommand::CoreAction(action) => { ResolvedNCommand::CoreAction(self.typecheck_action(action, &Default::default())?) } - NCommand::Check(facts) => ResolvedNCommand::Check(self.typecheck_facts(facts)?), + NCommand::Check(span, facts) => { + ResolvedNCommand::Check(*span, self.typecheck_facts(facts)?) + } NCommand::Fail(cmd) => ResolvedNCommand::Fail(Box::new(self.typecheck_command(cmd)?)), NCommand::RunSchedule(schedule) => { ResolvedNCommand::RunSchedule(self.typecheck_schedule(schedule)?) @@ -275,28 +277,33 @@ impl TypeInfo { fn typecheck_schedule(&self, schedule: &Schedule) -> Result { let schedule = match schedule { - Schedule::Repeat(times, schedule) => { - ResolvedSchedule::Repeat(*times, Box::new(self.typecheck_schedule(schedule)?)) - } - Schedule::Sequence(schedules) => { + Schedule::Repeat(span, times, schedule) => ResolvedSchedule::Repeat( + *span, + *times, + Box::new(self.typecheck_schedule(schedule)?), + ), + Schedule::Sequence(span, schedules) => { let schedules = schedules .iter() .map(|schedule| self.typecheck_schedule(schedule)) .collect::, _>>()?; - ResolvedSchedule::Sequence(schedules) + ResolvedSchedule::Sequence(*span, schedules) } - Schedule::Saturate(schedule) => { - ResolvedSchedule::Saturate(Box::new(self.typecheck_schedule(schedule)?)) + Schedule::Saturate(span, schedule) => { + ResolvedSchedule::Saturate(*span, Box::new(self.typecheck_schedule(schedule)?)) } - Schedule::Run(RunConfig { ruleset, until }) => { + Schedule::Run(span, RunConfig { ruleset, until }) => { let until = until .as_ref() .map(|facts| self.typecheck_facts(facts)) .transpose()?; - ResolvedSchedule::Run(ResolvedRunConfig { - ruleset: *ruleset, - until, - }) + ResolvedSchedule::Run( + *span, + ResolvedRunConfig { + ruleset: *ruleset, + until, + }, + ) } }; @@ -327,7 +334,7 @@ impl TypeInfo { } fn typecheck_rule(&self, rule: &Rule) -> Result { - let Rule { head, body } = rule; + let Rule { ann, head, body } = rule; let mut constraints = vec![]; let mut fresh_gen = SymbolGen::new("$".to_string()); @@ -354,6 +361,7 @@ impl TypeInfo { let actions: ResolvedActions = assignment.annotate_actions(&mapped_action, self)?; Ok(ResolvedRule { + ann: *ann, body, head: actions, }) @@ -403,7 +411,7 @@ impl TypeInfo { expr: &Expr, binding: &IndexMap, ) -> Result { - let action = Action::Expr((), expr.clone()); + let action = Action::Expr(Span::DUMMY, expr.clone()); let typechecked_action = self.typecheck_action(&action, binding)?; match typechecked_action { ResolvedAction::Expr(_, expr) => Ok(expr), @@ -503,6 +511,7 @@ mod test { let mut egraph = EGraph::default(); let res = egraph.parse_and_run_program( + None, " (relation f (i64 i64)) (rule ((f a b c)) ()) From b6e047c736fa2955238250f90f59e0ac845b1cd1 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Wed, 26 Jun 2024 13:17:11 -0700 Subject: [PATCH 02/16] add spans to the parser --- src/ast/mod.rs | 9 +++-- src/ast/parse.lalrpop | 90 +++++++++++++++++++++++++------------------ src/core.rs | 2 +- src/lib.rs | 4 +- src/main.rs | 6 +-- src/termdag.rs | 3 +- src/typechecking.rs | 2 +- 7 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f852be02..b2b1229d 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,3 +1,4 @@ +use lazy_static::lazy_static; use std::fmt::Display; pub use symbol_table::GlobalSymbol as Symbol; @@ -58,8 +59,8 @@ pub(crate) const DUMMY_FILENAME: &str = ""; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Span(pub Symbol, pub usize, pub usize); -impl Span { - pub(crate) const DUMMY: Span = Span(Symbol::from(DUMMY_FILENAME), 0, 0); +lazy_static! { + pub(crate) static ref DUMMY_SPAN: Span = Span(Symbol::from(DUMMY_FILENAME), 0, 0); } impl Copy for Span {} @@ -154,7 +155,7 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(ann, facts) => GenericCommand::Check(*ann, facts.clone()), + GenericNCommand::Check(ann, facts) => GenericCommand::Check(ann.clone(), facts.clone()), GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -933,7 +934,7 @@ impl FunctionDecl { }, merge: None, merge_action: Actions::default(), - default: Some(Expr::Lit(Span::DUMMY, Literal::Unit)), + default: Some(Expr::Lit(*DUMMY_SPAN, Literal::Unit)), cost: None, unextractable: false, ignore_viz: false, diff --git a/src/ast/parse.lalrpop b/src/ast/parse.lalrpop index 8cf89e00..a603b502 100644 --- a/src/ast/parse.lalrpop +++ b/src/ast/parse.lalrpop @@ -1,4 +1,3 @@ -// TODO: span tracking use crate::ast::*; use crate::Symbol; use crate::Schedule; @@ -22,13 +21,13 @@ pub Program: Vec = { (Command)* => <> } -LParen: () = { - "(" => (), - "[" => (), +LParen: usize = { + <@L> "(" => <>, + <@L> "[" => <>, }; -RParen: () = { - ")" => (), - "]" => (), +RParen: usize = { + ")" <@R> => <>, + "]" <@R> => <>, }; List: Vec = { @@ -56,31 +55,39 @@ Command: Command = { )?> )?> RParen => { Command::Function(FunctionDecl { name, schema, merge, merge_action: Actions::new(merge_action.unwrap_or_default()), default, cost, unextractable: unextractable.is_some(), ignore_viz: false }) }, - LParen "declare" RParen => Command::Declare{name, sort}, + "declare" => Command::Declare{ann: Span(filename, lo, hi), name, sort}, LParen "relation" > RParen => Command::Relation{constructor, inputs}, LParen "ruleset" RParen => Command::AddRuleset(name), LParen "unstable-combined-ruleset" RParen => Command::UnstableCombinedRuleset(name, subrulesets), - LParen "rule" > > )?> )?> RParen => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { head: Actions::new(head), body }}, - LParen "rewrite" + "rule" > > + )?> + )?> + => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { ann: Span(filename, lo, hi), head: Actions::new(head), body }}, + "rewrite" >)?> )?> - RParen => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), - LParen "birewrite" + => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { ann: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), + "birewrite" >)?> )?> - RParen => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { lhs, rhs, conditions: conditions.unwrap_or_default() }), - LParen "let" RParen => Command::Action(Action::Let((), name, expr)), + => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { ann: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }), + "let" => Command::Action(Action::Let(Span(filename, lo, hi), name, expr)), => Command::Action(<>), - LParen "run" )?> RParen => Command::RunSchedule(Schedule::Repeat(limit, Box::new(Schedule::Run(RunConfig { ruleset : "".into(), until })))), - LParen "run" )?> RParen => Command::RunSchedule(Schedule::Repeat(limit, Box::new(Schedule::Run(RunConfig { ruleset, until })))), + "run" )?> => + Command::RunSchedule(Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( + Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset : "".into(), until })))), + "run" )?> => + Command::RunSchedule(Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( + Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset, until })))), LParen "simplify" RParen => Command::Simplify { expr, schedule }, - LParen "calc" LParen RParen RParen => Command::Calc(idents, exprs), + "calc" LParen RParen => Command::Calc(Span(filename, lo, hi), idents, exprs), LParen "query-extract" )?> RParen => Command::QueryExtract { expr, variants: variants.unwrap_or(0) }, - LParen "check" <(Fact)*> RParen => Command::Check(<>), + "check" => Command::Check(Span(filename, lo, hi), facts), LParen "check-proof" RParen => Command::CheckProof, - LParen "run-schedule" RParen => Command::RunSchedule(Schedule::Sequence(<>)), + "run-schedule" => + Command::RunSchedule(Schedule::Sequence(Span(filename, lo, hi), scheds)), LParen "print-stats" RParen => Command::PrintOverallStatistics, LParen "push" RParen => Command::Push(<>.unwrap_or(1)), LParen "pop" RParen => Command::Pop(<>.unwrap_or(1)), @@ -93,13 +100,20 @@ Command: Command = { } Schedule: Schedule = { - LParen "saturate" RParen => Schedule::Saturate(Box::new(Schedule::Sequence(<>))), - LParen "seq" RParen => Schedule::Sequence(<>), - LParen "repeat" RParen => Schedule::Repeat(limit, Box::new(Schedule::Sequence(scheds))), - LParen "run" )?> RParen => - Schedule::Run(RunConfig { ruleset: "".into(), until }), - LParen "run" )?> RParen => Schedule::Run(RunConfig { ruleset, until }), - => Schedule::Run(RunConfig { ruleset: ident, until: None }), + "saturate" => + Schedule::Saturate(Span(filename, lo, hi), Box::new( + Schedule::Sequence(Span(filename, lo, hi), scheds))), + "seq" => + Schedule::Sequence(Span(filename, lo, hi), scheds), + "repeat" => + Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( + Schedule::Sequence(Span(filename, lo, hi), scheds))), + "run" )?> => + Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset: "".into(), until }), + "run" )?> => + Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset, until }), + => + Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset: ident, until: None }), } Cost: Option = { @@ -108,18 +122,18 @@ Cost: Option = { } NonLetAction: Action = { - LParen "set" LParen RParen RParen => Action::Set ( (), f, args, v ), - LParen "delete" LParen RParen RParen => Action::Change ( (), Change::Delete, f, args), - LParen "subsume" LParen RParen RParen => Action::Change ( (), Change::Subsume, f, args), - LParen "union" RParen => Action::Union((), <>), - LParen "panic" RParen => Action::Panic((), msg), - LParen "extract" RParen => Action::Extract((), expr, Expr::Lit((), Literal::Int(0))), - LParen "extract" RParen => Action::Extract((), expr, variants), - => Action::Expr((), e), + "set" LParen RParen => Action::Set ( Span(filename, lo, hi), f, args, v ), + "delete" LParen RParen => Action::Change ( Span(filename, lo, hi), Change::Delete, f, args), + "subsume" LParen RParen => Action::Change ( Span(filename, lo, hi), Change::Subsume, f, args), + "union" => Action::Union(Span(filename, lo, hi), e1, e2), + "panic" => Action::Panic(Span(filename, lo, hi), msg), + "extract" => Action::Extract(Span(filename, lo, hi), expr, Expr::Lit(Span(filename, lo, hi), Literal::Int(0))), + "extract" => Action::Extract(Span(filename, lo, hi), expr, variants), + => Action::Expr(Span(filename, lo, hi), e), } pub Action: Action = { - LParen "let" RParen => Action::Let((), name, expr), + "let" => Action::Let(Span(filename, lo, hi), name, expr), => <>, } @@ -138,8 +152,8 @@ Schema: Schema = { } pub Expr: Expr = { - => Expr::Lit((), <>), - => Expr::Var((), <>), + => Expr::Lit(Span(filename, lo, hi), lit), + => Expr::Var(Span(filename, lo, hi), id), => <>, }; @@ -157,7 +171,7 @@ Bool: bool = { } CallExpr: Expr = { - LParen RParen => Expr::Call((), head, tail), + => Expr::Call(Span(filename, lo, hi), head, tail), } ExprList: Vec = { LParen RParen => sexps } diff --git a/src/core.rs b/src/core.rs index 2b05d18f..f8674c7a 100644 --- a/src/core.rs +++ b/src/core.rs @@ -213,7 +213,7 @@ impl Atom { pub(crate) fn to_expr(&self) -> Expr { let n = self.args.len(); Expr::Call( - (), + todo!("need to investigate to_expr"), self.head, self.args[0..n - 1] .iter() diff --git a/src/lib.rs b/src/lib.rs index 16a59550..d9b7a41a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1135,7 +1135,7 @@ impl EGraph { pub fn eval_expr(&mut self, expr: &Expr) -> Result<(ArcSort, Value), Error> { let fresh_name = self.desugar.get_fresh(); - let command = Command::Action(Action::Let(Span::DUMMY, fresh_name, expr.clone())); + let command = Command::Action(Action::Let(*DUMMY_SPAN, fresh_name, expr.clone())); self.run_program(vec![command])?; // find the table with the same name as the fresh name let func = self.functions.get(&fresh_name).unwrap(); @@ -1386,7 +1386,7 @@ impl EGraph { let mut contents = String::new(); f.read_to_string(&mut contents).unwrap(); - let span = Span::DUMMY; + let span: Span = *DUMMY_SPAN; let mut actions: Vec = vec![]; let mut str_buf: Vec<&str> = vec![]; for line in contents.lines() { diff --git a/src/main.rs b/src/main.rs index 02f7a870..573b7fcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -106,13 +106,13 @@ fn main() { } for (idx, input) in args.inputs.iter().enumerate() { - let program_read = std::fs::read_to_string(input).unwrap_or_else(|_| { + let program = std::fs::read_to_string(input).unwrap_or_else(|_| { let arg = input.to_string_lossy(); panic!("Failed to read file {arg}") }); let mut egraph = mk_egraph(); - - match egraph.parse_and_run_program(Some(input.into()),&program) { + let program_offset = 0; + match egraph.parse_and_run_program(Some(input.to_str().unwrap().into()),&program) { Ok(msgs) => { for msg in msgs { println!("{msg}"); diff --git a/src/termdag.rs b/src/termdag.rs index b3906426..2186dec4 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -222,7 +222,8 @@ mod tests { ] ); let e2 = td.term_to_expr(&t); - assert_eq!(e, e2); // roundtrip + todo!("the following assertion fails type check") + // assert_eq!(e, e2); // roundtrip } #[test] diff --git a/src/typechecking.rs b/src/typechecking.rs index f5303b49..c8215b65 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -411,7 +411,7 @@ impl TypeInfo { expr: &Expr, binding: &IndexMap, ) -> Result { - let action = Action::Expr(Span::DUMMY, expr.clone()); + let action = Action::Expr(*DUMMY_SPAN, expr.clone()); let typechecked_action = self.typecheck_action(&action, binding)?; match typechecked_action { ResolvedAction::Expr(_, expr) => Ok(expr), From b8da1e753050288684191d6cd516f3f80e12a516 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Wed, 26 Jun 2024 13:25:44 -0700 Subject: [PATCH 03/16] minor warnings --- src/ast/mod.rs | 8 ++++---- src/core.rs | 2 +- src/lib.rs | 6 +++--- src/termdag.rs | 4 +++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index b2b1229d..209b3359 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -721,7 +721,7 @@ where } GenericCommand::BiRewrite(name, rewrite) => rewrite.to_sexp(*name, true, false), GenericCommand::Datatype { name, variants } => list!("datatype", name, ++ variants), - GenericCommand::Declare { ann, name, sort } => list!("declare", name, sort), + GenericCommand::Declare { ann: _, name, sort } => list!("declare", name, sort), GenericCommand::Action(a) => a.to_sexp(), GenericCommand::Sort(name, None) => list!("sort", name), GenericCommand::Sort(name, Some((name2, args))) => { @@ -743,11 +743,11 @@ where } => rule.to_sexp(*ruleset, *name), GenericCommand::RunSchedule(sched) => list!("run-schedule", sched), GenericCommand::PrintOverallStatistics => list!("print-stats"), - GenericCommand::Calc(ann, args, exprs) => list!("calc", list!(++ args), ++ exprs), + GenericCommand::Calc(_ann, args, exprs) => list!("calc", list!(++ args), ++ exprs), GenericCommand::QueryExtract { variants, expr } => { list!("query-extract", ":variants", variants, expr) } - GenericCommand::Check(ann, facts) => list!("check", ++ facts), + GenericCommand::Check(_ann, facts) => list!("check", ++ facts), GenericCommand::CheckProof => list!("check-proof"), GenericCommand::Push(n) => list!("push", n), GenericCommand::Pop(n) => list!("pop", n), @@ -788,7 +788,7 @@ where name, rule, } => rule.fmt_with_ruleset(f, *ruleset, *name), - GenericCommand::Check(ann, facts) => { + GenericCommand::Check(_ann, facts) => { write!(f, "(check {})", ListDisplay(facts, "\n")) } _ => write!(f, "{}", self.to_sexp()), diff --git a/src/core.rs b/src/core.rs index f8674c7a..0bad962a 100644 --- a/src/core.rs +++ b/src/core.rs @@ -734,7 +734,7 @@ where where Leaf: SymbolLike, { - let GenericRule { ann, head, body } = self; + let GenericRule { ann: _, head, body } = self; let (body, _correspondence) = Facts(body.clone()).to_query(typeinfo, &mut fresh_gen); let mut binding = body.get_vars(); diff --git a/src/lib.rs b/src/lib.rs index d9b7a41a..cc864574 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -844,7 +844,7 @@ impl EGraph { fn run_schedule(&mut self, sched: &ResolvedSchedule) -> RunReport { match sched { ResolvedSchedule::Run(span, config) => self.run_rules(span, config), - ResolvedSchedule::Repeat(span, limit, sched) => { + ResolvedSchedule::Repeat(_span, limit, sched) => { let mut report = RunReport::default(); for _i in 0..*limit { let rec = self.run_schedule(sched); @@ -855,7 +855,7 @@ impl EGraph { } report } - ResolvedSchedule::Saturate(span, sched) => { + ResolvedSchedule::Saturate(_span, sched) => { let mut report = RunReport::default(); loop { let rec = self.run_schedule(sched); @@ -866,7 +866,7 @@ impl EGraph { } report } - ResolvedSchedule::Sequence(span, scheds) => { + ResolvedSchedule::Sequence(_span, scheds) => { let mut report = RunReport::default(); for sched in scheds { report = report.union(&self.run_schedule(sched)); diff --git a/src/termdag.rs b/src/termdag.rs index 2186dec4..85d01485 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,5 +1,7 @@ use crate::{ - ast::{Expr, Literal}, util::{HashMap, HashSet}, GeneratedExpr, GenericExpr, Symbol + ast::Literal, + util::{HashMap, HashSet}, + GeneratedExpr, GenericExpr, Symbol, }; pub type TermId = usize; From 227f2b44fa0677b86e1a0a1d922348cb5edc7d73 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Wed, 26 Jun 2024 22:37:57 -0700 Subject: [PATCH 04/16] Add span annotations to Fact::Eq and CoreIR; Changed the primitive's get_constraints and TypeConstraint to contain span information --- src/actions.rs | 20 +-- src/ast/desugar.rs | 10 +- src/ast/expr.rs | 2 +- src/ast/mod.rs | 107 +++++++++------- src/ast/parse.lalrpop | 4 +- src/ast/remove_globals.rs | 11 +- src/constraint.rs | 94 ++++++++------ src/core.rs | 256 ++++++++++++++++++++++++++------------ src/gj.rs | 61 +++++---- src/lib.rs | 19 +-- src/sort/fn.rs | 13 +- src/sort/i64.rs | 4 +- src/sort/macros.rs | 3 +- src/sort/map.rs | 35 +++--- src/sort/mod.rs | 4 +- src/sort/set.rs | 40 +++--- src/sort/string.rs | 8 +- src/sort/unit.rs | 4 +- src/sort/vec.rs | 45 ++++--- src/typechecking.rs | 15 +-- 20 files changed, 466 insertions(+), 289 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index 324a3153..09e88b22 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -16,20 +16,20 @@ struct ActionCompiler<'a> { impl<'a> ActionCompiler<'a> { fn compile_action(&mut self, action: &GenericCoreAction) { match action { - GenericCoreAction::Let(v, f, args) => { + GenericCoreAction::Let(_ann, v, f, args) => { self.do_call(f, args); self.locals.insert(v.clone()); } - GenericCoreAction::LetAtomTerm(v, at) => { + GenericCoreAction::LetAtomTerm(_ann, v, at) => { self.do_atom_term(at); self.locals.insert(v.clone()); } - GenericCoreAction::Extract(e, b) => { + GenericCoreAction::Extract(_ann, e, b) => { self.do_atom_term(e); self.do_atom_term(b); self.instructions.push(Instruction::Extract(2)); } - GenericCoreAction::Set(f, args, e) => { + GenericCoreAction::Set(_ann, f, args, e) => { let ResolvedCall::Func(func) = f else { panic!("Cannot set primitive- should have been caught by typechecking!!!") }; @@ -39,7 +39,7 @@ impl<'a> ActionCompiler<'a> { self.do_atom_term(e); self.instructions.push(Instruction::Set(func.name)); } - GenericCoreAction::Change(change, f, args) => { + GenericCoreAction::Change(_ann, change, f, args) => { let ResolvedCall::Func(func) = f else { panic!("Cannot change primitive- should have been caught by typechecking!!!") }; @@ -49,12 +49,12 @@ impl<'a> ActionCompiler<'a> { self.instructions .push(Instruction::Change(*change, func.name)); } - GenericCoreAction::Union(arg1, arg2) => { + GenericCoreAction::Union(_ann, arg1, arg2) => { self.do_atom_term(arg1); self.do_atom_term(arg2); self.instructions.push(Instruction::Union(2)); } - GenericCoreAction::Panic(msg) => { + GenericCoreAction::Panic(_ann, msg) => { self.instructions.push(Instruction::Panic(msg.clone())); } } @@ -72,7 +72,7 @@ impl<'a> ActionCompiler<'a> { fn do_atom_term(&mut self, at: &ResolvedAtomTerm) { match at { - ResolvedAtomTerm::Var(var) => { + ResolvedAtomTerm::Var(_ann, var) => { if let Some((i, _ty)) = self.locals.get_full(var) { self.instructions.push(Instruction::Load(Load::Stack(i))); } else { @@ -80,10 +80,10 @@ impl<'a> ActionCompiler<'a> { self.instructions.push(Instruction::Load(Load::Subst(i))); } } - ResolvedAtomTerm::Literal(lit) => { + ResolvedAtomTerm::Literal(_ann, lit) => { self.instructions.push(Instruction::Literal(lit.clone())); } - ResolvedAtomTerm::Global(_var) => { + ResolvedAtomTerm::Global(_ann, _var) => { panic!("Global variables should have been desugared"); } } diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index d704b886..f1808890 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -71,7 +71,7 @@ fn desugar_rewrite( name, rule: Rule { ann: span, - body: [Fact::Eq(vec![Expr::Var(span, var), rewrite.lhs.clone()])] + body: [Fact::Eq(span, vec![Expr::Var(span, var), rewrite.lhs.clone()])] .into_iter() .chain(rewrite.conditions.clone()) .collect(), @@ -119,7 +119,7 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { let fresh_symbol = desugar.get_fresh(); let fresh_var = Expr::Var(*ann, fresh_symbol); let expr = std::mem::replace(expr, fresh_var.clone()); - new_head_atoms.push(Fact::Eq(vec![fresh_var, expr])); + new_head_atoms.push(Fact::Eq(*ann, vec![fresh_var, expr])); }; } Action::Let(ann, symbol, expr) if var_set.contains(symbol) => { @@ -128,7 +128,7 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { add_new_rule = true; let var = Expr::Var(*ann, *symbol); - new_head_atoms.push(Fact::Eq(vec![var, expr.clone()])); + new_head_atoms.push(Fact::Eq(*ann, vec![var, expr.clone()])); } } _ => (), @@ -209,14 +209,14 @@ pub(crate) fn desugar_calc( span, RunConfig { ruleset: "".into(), - until: Some(vec![Fact::Eq(vec![expr1.clone(), expr2.clone()])]), + until: Some(vec![Fact::Eq(span, vec![expr1.clone(), expr2.clone()])]), }, )), ))); res.push(Command::Check( span, - vec![Fact::Eq(vec![expr1.clone(), expr2.clone()])], + vec![Fact::Eq(span, vec![expr1.clone(), expr2.clone()])], )); res.push(Command::Pop(1)); diff --git a/src/ast/expr.rs b/src/ast/expr.rs index df722f4d..0657bf8b 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -150,7 +150,7 @@ impl GeneratedExpr { } } -impl +impl GenericExpr { pub fn ann(&self) -> Ann { diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 209b3359..19e5a0f1 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -65,6 +65,22 @@ lazy_static! { impl Copy for Span {} +pub(crate) trait Annotation: Clone + PartialEq + Eq + Hash + Debug { + fn dummy() -> Self; +} + +impl Annotation for Span { + fn dummy() -> Self { + *DUMMY_SPAN + } +} + +impl Annotation for () { + fn dummy() -> Self { + () + } +} + pub type NCommand = GenericNCommand; /// [`ResolvedNCommand`] is another specialization of [`GenericNCommand`], which /// adds the type information to heads and leaves of commands. @@ -85,7 +101,7 @@ pub(crate) type ResolvedNCommand = GenericNCommand where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -129,7 +145,7 @@ impl GenericNCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Clone, + Ann: Annotation, { pub fn to_command(&self) -> GenericCommand { match self { @@ -276,7 +292,7 @@ macro_rules! list { impl GenericSchedule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -329,7 +345,7 @@ pub enum GenericCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Clone, + Ann: Annotation, { /// Egglog supports several *experimental* options /// that can be set using the `set-option` command. @@ -711,7 +727,7 @@ impl ToSexp for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Clone, + Ann: Annotation, { fn to_sexp(&self) -> Sexp { match self { @@ -768,7 +784,7 @@ impl Display for GenericNCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Clone, + Ann: Annotation, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_command()) @@ -779,7 +795,7 @@ impl Display for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Clone, + Ann: Annotation, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { @@ -825,7 +841,7 @@ pub struct GenericRunConfig { impl GenericRunConfig where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -869,7 +885,7 @@ pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -944,7 +960,7 @@ impl FunctionDecl { impl GenericFunctionDecl where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -967,7 +983,7 @@ where impl ToSexp for GenericFunctionDecl where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1032,7 +1048,7 @@ pub(crate) type MappedFact = GenericFact { /// Must be at least two things in an eq fact - Eq(Vec>), + Eq(Ann, Vec>), Fact(GenericExpr), } @@ -1040,7 +1056,7 @@ pub struct Facts(pub Vec>); impl Facts where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1056,7 +1072,7 @@ where typeinfo: &TypeInfo, fresh_gen: &mut impl FreshGen, ) -> ( - Query, Leaf>, + Query, Leaf, Ann>, Vec>, ) where @@ -1067,7 +1083,7 @@ where for fact in self.0.iter() { match fact { - GenericFact::Eq(exprs) => { + GenericFact::Eq(ann, exprs) => { let mut new_exprs = vec![]; let mut to_equate = vec![]; for expr in exprs { @@ -1077,10 +1093,11 @@ where new_exprs.push(expr); } atoms.push(GenericAtom { + ann: ann.clone(), head: HeadOrEq::Eq, args: to_equate, }); - new_body.push(GenericFact::Eq(new_exprs)); + new_body.push(GenericFact::Eq(ann.clone(), new_exprs)); } GenericFact::Fact(expr) => { let (child_atoms, expr) = expr.to_query(typeinfo, fresh_gen); @@ -1100,7 +1117,7 @@ where { fn to_sexp(&self) -> Sexp { match self { - GenericFact::Eq(exprs) => list!("=", ++ exprs), + GenericFact::Eq(_, exprs) => list!("=", ++ exprs), GenericFact::Fact(expr) => expr.to_sexp(), } } @@ -1108,7 +1125,7 @@ where impl GenericFact where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1117,9 +1134,10 @@ where f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> GenericFact { match self { - GenericFact::Eq(exprs) => { - GenericFact::Eq(exprs.into_iter().map(|expr| expr.visit_exprs(f)).collect()) - } + GenericFact::Eq(ann, exprs) => GenericFact::Eq( + ann.clone(), + exprs.into_iter().map(|expr| expr.visit_exprs(f)).collect(), + ), GenericFact::Fact(expr) => GenericFact::Fact(expr.visit_exprs(f)), } } @@ -1129,7 +1147,9 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> GenericFact { match self { - GenericFact::Eq(exprs) => GenericFact::Eq(exprs.iter().map(f).collect()), + GenericFact::Eq(ann, exprs) => { + GenericFact::Eq(ann.clone(), exprs.iter().map(f).collect()) + } GenericFact::Fact(expr) => GenericFact::Fact(f(expr)), } } @@ -1147,7 +1167,7 @@ impl GenericFact where Leaf: Clone + PartialEq + Eq + Display + Hash, Head: Clone + Display, - Ann: Clone, + Ann: Annotation, { pub(crate) fn make_unresolved(self) -> GenericFact where @@ -1219,7 +1239,7 @@ pub(crate) type ResolvedAction = GenericAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum GenericAction where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1278,7 +1298,7 @@ where pub struct GenericActions< Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Clone, + Ann: Annotation, >(pub Vec>); pub type Actions = GenericActions; pub(crate) type ResolvedActions = GenericActions; @@ -1287,7 +1307,7 @@ pub(crate) type MappedActions = impl Default for GenericActions where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1298,7 +1318,7 @@ where impl GenericActions where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1324,7 +1344,7 @@ where impl ToSexp for GenericAction where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1353,7 +1373,7 @@ impl GenericAction where Head: Clone + Display, Leaf: Clone + Eq + Display + Hash, - Ann: Clone, + Ann: Annotation, { // Applys `f` to all expressions in the action. pub fn map_exprs( @@ -1476,7 +1496,7 @@ where impl Display for GenericAction where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1497,7 +1517,7 @@ pub(crate) type ResolvedRule = GenericRule; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GenericRule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1508,7 +1528,7 @@ where impl GenericRule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1530,7 +1550,7 @@ where impl GenericRule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1580,7 +1600,7 @@ where impl GenericRule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1605,7 +1625,7 @@ where impl Display for GenericRule where - Ann: Clone, + Ann: Annotation, Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1663,11 +1683,14 @@ impl Display for GenericRewrite MappedExpr where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { - pub(crate) fn get_corresponding_var_or_lit(&self, typeinfo: &TypeInfo) -> GenericAtomTerm + pub(crate) fn get_corresponding_var_or_lit( + &self, + typeinfo: &TypeInfo, + ) -> GenericAtomTerm where Leaf: SymbolLike, { @@ -1675,15 +1698,15 @@ where // This is error-prone and the complexities can be avoided by treating globals // as nullary functions. match self { - GenericExpr::Var(_ann, v) => { + GenericExpr::Var(ann, v) => { if typeinfo.is_global(v.to_symbol()) { - GenericAtomTerm::Global(v.clone()) + GenericAtomTerm::Global(ann.clone(), v.clone()) } else { - GenericAtomTerm::Var(v.clone()) + GenericAtomTerm::Var(ann.clone(), v.clone()) } } - GenericExpr::Lit(_ann, lit) => GenericAtomTerm::Literal(lit.clone()), - GenericExpr::Call(_ann, head, _) => GenericAtomTerm::Var(head.to.clone()), + GenericExpr::Lit(ann, lit) => GenericAtomTerm::Literal(ann.clone(), lit.clone()), + GenericExpr::Call(ann, head, _) => GenericAtomTerm::Var(ann.clone(), head.to.clone()), } } } diff --git a/src/ast/parse.lalrpop b/src/ast/parse.lalrpop index a603b502..a1d1a475 100644 --- a/src/ast/parse.lalrpop +++ b/src/ast/parse.lalrpop @@ -140,9 +140,9 @@ pub Action: Action = { Name: Symbol = { "[" "]" => <> } pub Fact: Fact = { - LParen "=" RParen => { + "=" => { es.push(e); - Fact::Eq(es) + Fact::Eq(Span(filename, lo, hi), es) }, => Fact::Fact(<>), } diff --git a/src/ast/remove_globals.rs b/src/ast/remove_globals.rs index 3407d350..b2ae49da 100644 --- a/src/ast/remove_globals.rs +++ b/src/ast/remove_globals.rs @@ -170,10 +170,13 @@ impl<'a> GlobalRemover<'a> { let new_facts: Vec = globals .iter() .map(|(old, new)| { - GenericFact::Eq(vec![ - GenericExpr::Call(new.ann(), resolved_var_to_call(old), vec![]), - new.clone(), - ]) + GenericFact::Eq( + new.ann(), + vec![ + GenericExpr::Call(new.ann(), resolved_var_to_call(old), vec![]), + new.clone(), + ], + ) }) .collect(); diff --git a/src/constraint.rs b/src/constraint.rs index 956a9ddb..af6085d0 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -2,9 +2,14 @@ use crate::{ ast::{ GenericAction, GenericActions, GenericExpr, GenericFact, MappedAction, ResolvedAction, ResolvedActions, ResolvedExpr, ResolvedFact, ResolvedVar, - }, core::{ + }, + core::{ Atom, AtomTerm, CoreAction, CoreRule, GenericCoreActions, Query, ResolvedCall, SymbolOrEq, - }, sort::I64Sort, typechecking::TypeError, util::{FreshGen, HashMap, HashSet, SymbolGen}, ArcSort, CorrespondingVar, Span, Symbol, TypeInfo + }, + sort::I64Sort, + typechecking::TypeError, + util::{FreshGen, HashMap, HashSet, SymbolGen}, + ArcSort, CorrespondingVar, Span, Symbol, TypeInfo, DUMMY_SPAN, }; use core::hash::Hash; use std::{fmt::Debug, iter::once, mem::swap}; @@ -221,7 +226,8 @@ impl Assignment { let global_ty = typeinfo.lookup_global(var); let ty = global_ty .clone() - .or_else(|| self.get(&AtomTerm::Var(*var)).cloned()) + // Span is ignored when looking up atom_terms + .or_else(|| self.get(&AtomTerm::Var(*DUMMY_SPAN, *var)).cloned()) .expect("All variables should be assigned before annotation"); ResolvedExpr::Var( *span, @@ -249,7 +255,7 @@ impl Assignment { .iter() .map(|arg| arg.output_type(typeinfo)) .chain(once( - self.get(&AtomTerm::Var(*corresponding_var)) + self.get(&AtomTerm::Var(*DUMMY_SPAN, *corresponding_var)) .unwrap() .clone(), )) @@ -266,7 +272,8 @@ impl Assignment { typeinfo: &TypeInfo, ) -> ResolvedFact { match facts { - GenericFact::Eq(facts) => ResolvedFact::Eq( + GenericFact::Eq(ann, facts) => ResolvedFact::Eq( + *ann, facts .iter() .map(|expr| self.annotate_expr(expr, typeinfo)) @@ -295,7 +302,7 @@ impl Assignment { match action { GenericAction::Let(span, var, expr) => { let ty = self - .get(&AtomTerm::Var(*var)) + .get(&AtomTerm::Var(*span, *var)) .expect("All variables should be assigned before annotation"); Ok(ResolvedAction::Let( *span, @@ -372,9 +379,10 @@ impl Assignment { self.annotate_expr(rhs, typeinfo), )), GenericAction::Panic(span, msg) => Ok(ResolvedAction::Panic(*span, msg.clone())), - GenericAction::Expr(span, expr) => { - Ok(ResolvedAction::Expr(*span, self.annotate_expr(expr, typeinfo))) - } + GenericAction::Expr(span, expr) => Ok(ResolvedAction::Expr( + *span, + self.annotate_expr(expr, typeinfo), + )), } } @@ -446,11 +454,11 @@ impl Problem { // bound vars are added to range match action { - CoreAction::Let(var, _, _) => { - self.range.insert(AtomTerm::Var(*var)); + CoreAction::Let(ann, var, _, _) => { + self.range.insert(AtomTerm::Var(ann.clone(), *var)); } - CoreAction::LetAtomTerm(v, _) => { - self.range.insert(AtomTerm::Var(*v)); + CoreAction::LetAtomTerm(ann, v, _) => { + self.range.insert(AtomTerm::Var(ann.clone(), *v)); } _ => (), } @@ -463,7 +471,7 @@ impl Problem { rule: &CoreRule, typeinfo: &TypeInfo, ) -> Result<(), TypeError> { - let CoreRule { head, body } = rule; + let CoreRule { ann: _, head, body } = rule; self.add_query(body, typeinfo)?; self.add_actions(head, typeinfo)?; Ok(()) @@ -472,10 +480,11 @@ impl Problem { pub(crate) fn assign_local_var_type( &mut self, var: Symbol, + span: Span, sort: ArcSort, ) -> Result<(), TypeError> { - self.add_binding(AtomTerm::Var(var), sort); - self.range.insert(AtomTerm::Var(var)); + self.add_binding(AtomTerm::Var(span, var), sort); + self.range.insert(AtomTerm::Var(span, var)); Ok(()) } } @@ -487,39 +496,43 @@ impl CoreAction { symbol_gen: &mut SymbolGen, ) -> Result>, TypeError> { match self { - CoreAction::Let(symbol, f, args) => { + CoreAction::Let(ann, symbol, f, args) => { let mut args = args.clone(); - args.push(AtomTerm::Var(*symbol)); + args.push(AtomTerm::Var(ann.clone(), *symbol)); Ok(get_literal_and_global_constraints(&args, typeinfo) - .chain(get_atom_application_constraints(f, &args, typeinfo)?) + .chain(get_atom_application_constraints(f, &args, ann, typeinfo)?) .collect()) } - CoreAction::Set(head, args, rhs) => { + CoreAction::Set(ann, head, args, rhs) => { let mut args = args.clone(); args.push(rhs.clone()); Ok(get_literal_and_global_constraints(&args, typeinfo) - .chain(get_atom_application_constraints(head, &args, typeinfo)?) + .chain(get_atom_application_constraints( + head, &args, ann, typeinfo, + )?) .collect()) } - CoreAction::Change(_change, head, args) => { + CoreAction::Change(ann, _change, head, args) => { let mut args = args.clone(); // Add a dummy last output argument let var = symbol_gen.fresh(head); - args.push(AtomTerm::Var(var)); + args.push(AtomTerm::Var(*ann, var)); Ok(get_literal_and_global_constraints(&args, typeinfo) - .chain(get_atom_application_constraints(head, &args, typeinfo)?) + .chain(get_atom_application_constraints( + head, &args, ann, typeinfo, + )?) .collect()) } - CoreAction::Union(lhs, rhs) => Ok(get_literal_and_global_constraints( + CoreAction::Union(ann, lhs, rhs) => Ok(get_literal_and_global_constraints( &[lhs.clone(), rhs.clone()], typeinfo, ) .chain(once(Constraint::Eq(lhs.clone(), rhs.clone()))) .collect()), - CoreAction::Extract(e, n) => { + CoreAction::Extract(ann, e, n) => { // e can be anything Ok( get_literal_and_global_constraints(&[e.clone(), n.clone()], typeinfo) @@ -530,10 +543,10 @@ impl CoreAction { .collect(), ) } - CoreAction::Panic(_) => Ok(vec![]), - CoreAction::LetAtomTerm(v, at) => { + CoreAction::Panic(ann, _) => Ok(vec![]), + CoreAction::LetAtomTerm(ann, v, at) => { Ok(get_literal_and_global_constraints(&[at.clone()], typeinfo) - .chain(once(Constraint::Eq(AtomTerm::Var(*v), at.clone()))) + .chain(once(Constraint::Eq(AtomTerm::Var(*ann, *v), at.clone()))) .collect()) } } @@ -559,7 +572,7 @@ impl Atom { } SymbolOrEq::Symbol(head) => Ok(literal_constraints .chain(get_atom_application_constraints( - head, &self.args, type_info, + head, &self.args, &self.ann, type_info, )?) .collect()), } @@ -569,6 +582,7 @@ impl Atom { fn get_atom_application_constraints( head: &Symbol, args: &[AtomTerm], + span: &Span, type_info: &TypeInfo, ) -> Result>, TypeError> { // An atom can have potentially different semantics due to polymorphism @@ -587,6 +601,7 @@ fn get_atom_application_constraints( constraints.push(Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { + ann: *span, head: *head, args: args.to_vec(), }, @@ -611,7 +626,7 @@ fn get_atom_application_constraints( // primitive atom constraints if let Some(primitives) = type_info.primitives.get(head) { for p in primitives { - let constraints = p.get_type_constraints().get(args); + let constraints = p.get_type_constraints(span).get(args); xor_constraints.push(constraints); } } @@ -633,13 +648,13 @@ fn get_literal_and_global_constraints<'a>( ) -> impl Iterator> + 'a { args.iter().filter_map(|arg| { match arg { - AtomTerm::Var(_) => None, + AtomTerm::Var(_, _) => None, // Literal to type constraint - AtomTerm::Literal(lit) => { + AtomTerm::Literal(_, lit) => { let typ = type_info.infer_literal(lit); Some(Constraint::Assign(arg.clone(), typ.clone())) } - AtomTerm::Global(v) => { + AtomTerm::Global(_, v) => { if let Some(typ) = type_info.lookup_global(v) { Some(Constraint::Assign(arg.clone(), typ.clone())) } else { @@ -658,11 +673,12 @@ pub trait TypeConstraint { pub struct SimpleTypeConstraint { name: Symbol, sorts: Vec, + span: Span, } impl SimpleTypeConstraint { - pub fn new(name: Symbol, sorts: Vec) -> SimpleTypeConstraint { - SimpleTypeConstraint { name, sorts } + pub fn new(name: Symbol, sorts: Vec, span: Span) -> SimpleTypeConstraint { + SimpleTypeConstraint { name, sorts, span } } pub fn into_box(self) -> Box { @@ -676,6 +692,7 @@ impl TypeConstraint for SimpleTypeConstraint { vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { + ann: self.span, head: self.name, args: arguments.to_vec(), }, @@ -700,15 +717,17 @@ pub struct AllEqualTypeConstraint { sort: Option, exact_length: Option, output: Option, + span: Span, } impl AllEqualTypeConstraint { - pub fn new(name: Symbol) -> AllEqualTypeConstraint { + pub fn new(name: Symbol, span: Span) -> AllEqualTypeConstraint { AllEqualTypeConstraint { name, sort: None, exact_length: None, output: None, + span, } } @@ -749,6 +768,7 @@ impl TypeConstraint for AllEqualTypeConstraint { return vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { + ann: self.span, head: self.name, args: arguments.to_vec(), }, diff --git a/src/core.rs b/src/core.rs index 0bad962a..7ff3ab21 100644 --- a/src/core.rs +++ b/src/core.rs @@ -10,6 +10,7 @@ //! GJ compiler further compiler core queries to gj's CompiledQueries //! //! Most compiler-time optimizations are expected to be done over CoreRule format. +use std::hash::Hasher; use std::ops::AddAssign; use crate::HashMap; @@ -128,22 +129,64 @@ impl ToSexp for ResolvedCall { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum GenericAtomTerm { - Var(Leaf), - Literal(Literal), - Global(Leaf), +#[derive(Debug, Clone)] +pub enum GenericAtomTerm { + Var(Ann, Leaf), + Literal(Ann, Literal), + Global(Ann, Leaf), +} + +// Ignores annotations for equality and hasing +impl PartialEq for GenericAtomTerm +where + Leaf: PartialEq, +{ + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (GenericAtomTerm::Var(_, v1), GenericAtomTerm::Var(_, v2)) => v1 == v2, + (GenericAtomTerm::Literal(_, l1), GenericAtomTerm::Literal(_, l2)) => l1 == l2, + (GenericAtomTerm::Global(_, g1), GenericAtomTerm::Global(_, g2)) => g1 == g2, + _ => false, + } + } } -pub type AtomTerm = GenericAtomTerm; -pub type ResolvedAtomTerm = GenericAtomTerm; +impl Eq for GenericAtomTerm where Leaf: Eq {} + +impl Hash for GenericAtomTerm +where + Leaf: Hash, +{ + fn hash(&self, state: &mut H) { + match self { + GenericAtomTerm::Var(_, v) => v.hash(state), + GenericAtomTerm::Literal(_, l) => l.hash(state), + GenericAtomTerm::Global(_, g) => g.hash(state), + } + } +} + +pub type AtomTerm = GenericAtomTerm; +pub type ResolvedAtomTerm = GenericAtomTerm; + +impl GenericAtomTerm { + pub fn ann(&self) -> &Ann { + match self { + GenericAtomTerm::Var(ann, _) => ann, + GenericAtomTerm::Literal(ann, _) => ann, + GenericAtomTerm::Global(ann, _) => ann, + } + } +} impl AtomTerm { pub fn to_expr(&self) -> Expr { match self { - AtomTerm::Var(v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), - AtomTerm::Literal(l) => Expr::Lit(todo!("investigate usages of to_expr()"), l.clone()), - AtomTerm::Global(v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), + AtomTerm::Var(_, v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), + AtomTerm::Literal(_, l) => { + Expr::Lit(todo!("investigate usages of to_expr()"), l.clone()) + } + AtomTerm::Global(_, v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), } } } @@ -151,9 +194,9 @@ impl AtomTerm { impl ResolvedAtomTerm { pub fn output(&self, typeinfo: &TypeInfo) -> ArcSort { match self { - ResolvedAtomTerm::Var(v) => v.sort.clone(), - ResolvedAtomTerm::Literal(l) => typeinfo.infer_literal(l), - ResolvedAtomTerm::Global(v) => v.sort.clone(), + ResolvedAtomTerm::Var(_, v) => v.sort.clone(), + ResolvedAtomTerm::Literal(_, l) => typeinfo.infer_literal(l), + ResolvedAtomTerm::Global(_, v) => v.sort.clone(), } } } @@ -161,20 +204,21 @@ impl ResolvedAtomTerm { impl std::fmt::Display for AtomTerm { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AtomTerm::Var(v) => write!(f, "{v}"), - AtomTerm::Literal(lit) => write!(f, "{lit}"), - AtomTerm::Global(g) => write!(f, "{g}"), + AtomTerm::Var(_, v) => write!(f, "{v}"), + AtomTerm::Literal(_, lit) => write!(f, "{lit}"), + AtomTerm::Global(_, g) => write!(f, "{g}"), } } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericAtom { +pub struct GenericAtom { + pub ann: Ann, pub head: Head, - pub args: Vec>, + pub args: Vec>, } -pub type Atom = GenericAtom; +pub type Atom = GenericAtom; impl std::fmt::Display for Atom { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -182,29 +226,29 @@ impl std::fmt::Display for Atom { } } -impl GenericAtom +impl GenericAtom where Leaf: Clone + Eq + Hash, Head: Clone, { pub fn vars(&self) -> impl Iterator + '_ { self.args.iter().filter_map(|t| match t { - GenericAtomTerm::Var(v) => Some(v.clone()), - GenericAtomTerm::Literal(_) => None, - GenericAtomTerm::Global(_) => None, + GenericAtomTerm::Var(_, v) => Some(v.clone()), + GenericAtomTerm::Literal(..) => None, + GenericAtomTerm::Global(..) => None, }) } - fn subst(&mut self, subst: &HashMap>) { + fn subst(&mut self, subst: &HashMap>) { for arg in self.args.iter_mut() { match arg { - GenericAtomTerm::Var(v) => { + GenericAtomTerm::Var(_, v) => { if let Some(at) = subst.get(v) { *arg = at.clone(); } } - GenericAtomTerm::Literal(_) => (), - GenericAtomTerm::Global(_) => (), + GenericAtomTerm::Literal(..) => (), + GenericAtomTerm::Global(..) => (), } } } @@ -224,8 +268,8 @@ impl Atom { } #[derive(Debug, Clone)] -pub struct Query { - pub atoms: Vec>, +pub struct Query { + pub atoms: Vec>, } impl Default for Query { @@ -256,10 +300,11 @@ impl Query { } } -impl Query +impl Query where Leaf: Eq + Clone + Hash, Head: Clone, + Ann: Annotation, { pub(crate) fn get_vars(&self) -> IndexSet { self.atoms @@ -269,7 +314,7 @@ where } } -impl AddAssign for Query { +impl AddAssign for Query { fn add_assign(&mut self, rhs: Self) { self.atoms.extend(rhs.atoms); } @@ -305,20 +350,22 @@ impl std::fmt::Display for Query { } } -impl Query { - pub fn filters(&self) -> impl Iterator> + '_ { +impl Query { + pub fn filters(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(_) => None, ResolvedCall::Primitive(head) => Some(GenericAtom { + ann: atom.ann.clone(), head: head.primitive.clone(), args: atom.args.clone(), }), }) } - pub fn funcs(&self) -> impl Iterator> + '_ { + pub fn funcs(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(head) => Some(GenericAtom { + ann: atom.ann.clone(), head: head.name, args: atom.args.clone(), }), @@ -328,41 +375,55 @@ impl Query { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum GenericCoreAction { - Let(Leaf, Head, Vec>), - LetAtomTerm(Leaf, GenericAtomTerm), - Extract(GenericAtomTerm, GenericAtomTerm), - Set(Head, Vec>, GenericAtomTerm), - Change(Change, Head, Vec>), - Union(GenericAtomTerm, GenericAtomTerm), - Panic(String), +pub enum GenericCoreAction { + Let(Ann, Leaf, Head, Vec>), + LetAtomTerm(Ann, Leaf, GenericAtomTerm), + Extract(Ann, GenericAtomTerm, GenericAtomTerm), + Set( + Ann, + Head, + Vec>, + GenericAtomTerm, + ), + Change(Ann, Change, Head, Vec>), + Union(Ann, GenericAtomTerm, GenericAtomTerm), + Panic(Ann, String), } pub type CoreAction = GenericCoreAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericCoreActions(pub(crate) Vec>); +pub struct GenericCoreActions( + pub(crate) Vec>, +); pub(crate) type ResolvedCoreActions = GenericCoreActions; -impl Default for GenericCoreActions { +impl Default for GenericCoreActions { fn default() -> Self { Self(vec![]) } } -impl GenericCoreActions +impl GenericCoreActions where Leaf: Clone, + Ann: Annotation, { - pub(crate) fn subst(&mut self, subst: &HashMap>) { + pub(crate) fn subst(&mut self, subst: &HashMap>) { let actions = subst.iter().map(|(symbol, atom_term)| { - GenericCoreAction::LetAtomTerm(symbol.clone(), atom_term.clone()) + GenericCoreAction::LetAtomTerm( + atom_term.ann().clone(), + symbol.clone(), + atom_term.clone(), + ) }); let existing_actions = std::mem::take(&mut self.0); self.0 = actions.chain(existing_actions).collect(); } - fn new(actions: Vec>) -> GenericCoreActions { + fn new( + actions: Vec>, + ) -> GenericCoreActions { Self(actions) } } @@ -372,7 +433,7 @@ impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Clone, + Ann: Annotation, { pub(crate) fn to_core_actions>( &self, @@ -381,7 +442,7 @@ where fresh_gen: &mut FG, ) -> Result< ( - GenericCoreActions, + GenericCoreActions, MappedActions, ), TypeError, @@ -405,12 +466,15 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::LetAtomTerm( + ann.clone(), var.clone(), mapped_expr.get_corresponding_var_or_lit(typeinfo), )); - mapped_actions - .0 - .push(GenericAction::Let(ann.clone(), var.clone(), mapped_expr)); + mapped_actions.0.push(GenericAction::Let( + ann.clone(), + var.clone(), + mapped_expr, + )); binding.insert(var.clone()); } GenericAction::Set(ann, head, args, expr) => { @@ -425,6 +489,7 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Set( + ann.clone(), head.clone(), mapped_args .iter() @@ -449,6 +514,7 @@ where mapped_args.push(mapped_arg); } norm_actions.push(GenericCoreAction::Change( + ann.clone(), *change, head.clone(), mapped_args @@ -470,6 +536,7 @@ where let (actions2, mapped_e2) = e2.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions2.0); norm_actions.push(GenericCoreAction::Union( + ann.clone(), mapped_e1.get_corresponding_var_or_lit(typeinfo), mapped_e2.get_corresponding_var_or_lit(typeinfo), )); @@ -483,6 +550,7 @@ where let (actions, mapped_n) = n.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Extract( + ann.clone(), mapped_e.get_corresponding_var_or_lit(typeinfo), mapped_n.get_corresponding_var_or_lit(typeinfo), )); @@ -491,7 +559,7 @@ where .push(GenericAction::Extract(ann.clone(), mapped_e, mapped_n)); } GenericAction::Panic(ann, string) => { - norm_actions.push(GenericCoreAction::Panic(string.clone())); + norm_actions.push(GenericCoreAction::Panic(ann.clone(), string.clone())); mapped_actions .0 .push(GenericAction::Panic(ann.clone(), string.clone())); @@ -500,7 +568,9 @@ where let (actions, mapped_expr) = expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); - mapped_actions.0.push(GenericAction::Expr(ann.clone(), mapped_expr)); + mapped_actions + .0 + .push(GenericAction::Expr(ann.clone(), mapped_expr)); } } } @@ -510,7 +580,7 @@ where impl GenericExpr where - Ann: Clone, + Ann: Annotation, Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -519,7 +589,7 @@ where typeinfo: &TypeInfo, fresh_gen: &mut impl FreshGen, ) -> ( - Vec, Leaf>>, + Vec, Leaf, Ann>>, MappedExpr, ) where @@ -541,10 +611,11 @@ where child_exprs.push(child_expr); } let args = { - new_children.push(GenericAtomTerm::Var(fresh.clone())); + new_children.push(GenericAtomTerm::Var(ann.clone(), fresh.clone())); new_children }; atoms.push(GenericAtom { + ann: ann.clone(), head: HeadOrEq::Symbol(f.clone()), args, }); @@ -565,7 +636,13 @@ where typeinfo: &TypeInfo, binding: &mut IndexSet, fresh_gen: &mut FG, - ) -> Result<(GenericCoreActions, MappedExpr), TypeError> + ) -> Result< + ( + GenericCoreActions, + MappedExpr, + ), + TypeError, + > where Leaf: Hash + Eq + SymbolLike, { @@ -600,10 +677,19 @@ where let var = fresh_gen.fresh(f); binding.insert(var.clone()); - norm_actions.push(GenericCoreAction::Let(var.clone(), f.clone(), norm_args)); + norm_actions.push(GenericCoreAction::Let( + ann.clone(), + var.clone(), + f.clone(), + norm_args, + )); Ok(( GenericCoreActions::new(norm_actions), - GenericExpr::Call(ann.clone(), CorrespondingVar::new(f.clone(), var), mapped_args), + GenericExpr::Call( + ann.clone(), + CorrespondingVar::new(f.clone(), var), + mapped_args, + ), )) } } @@ -618,21 +704,23 @@ where /// for `body` needs to be a `HeadOrEq`, while `head` does not have equality /// constraints. #[derive(Debug, Clone)] -pub struct GenericCoreRule { - pub body: Query, - pub head: GenericCoreActions, +pub struct GenericCoreRule { + pub ann: Ann, + pub body: Query, + pub head: GenericCoreActions, } -pub(crate) type CoreRule = GenericCoreRule; -pub(crate) type ResolvedCoreRule = GenericCoreRule; +pub(crate) type CoreRule = GenericCoreRule; +pub(crate) type ResolvedCoreRule = GenericCoreRule; -impl GenericCoreRule +impl GenericCoreRule where Head1: Clone, Head2: Clone, Leaf: Clone + Eq + Hash, + Ann: Annotation, { - pub fn subst(&mut self, subst: &HashMap>) { + pub fn subst(&mut self, subst: &HashMap>) { for atom in &mut self.body.atoms { atom.subst(subst); } @@ -640,10 +728,11 @@ where } } -impl GenericCoreRule, Head, Leaf> +impl GenericCoreRule, Head, Leaf, Ann> where Leaf: Eq + Clone + Hash + Debug, Head: Clone, + Ann: Annotation, { /// Transformed a UnresolvedCoreRule into a CanonicalizedCoreRule. /// In particular, it removes equality checks between variables and @@ -652,15 +741,15 @@ where pub(crate) fn canonicalize( self, // Users need to pass in a substitute for equality constraints. - value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, - ) -> GenericCoreRule { + value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, + ) -> GenericCoreRule { let mut result_rule = self; loop { let mut to_subst = None; for atom in result_rule.body.atoms.iter() { if atom.head.is_eq() && atom.args[0] != atom.args[1] { match &atom.args[..] { - [GenericAtomTerm::Var(x), y] | [y, GenericAtomTerm::Var(x)] => { + [GenericAtomTerm::Var(_, x), y] | [y, GenericAtomTerm::Var(_, x)] => { to_subst = Some((x, y)); break; } @@ -684,11 +773,11 @@ where HeadOrEq::Eq => { assert_eq!(atom.args.len(), 2); match (&atom.args[0], &atom.args[1]) { - (GenericAtomTerm::Var(v1), GenericAtomTerm::Var(v2)) => { + (GenericAtomTerm::Var(_, v1), GenericAtomTerm::Var(_, v2)) => { assert_eq!(v1, v2); None } - (GenericAtomTerm::Var(_), _) | (_, GenericAtomTerm::Var(_)) => { + (GenericAtomTerm::Var(..), _) | (_, GenericAtomTerm::Var(..)) => { panic!("equalities between variable and non-variable arguments should have been canonicalized") } (at1, at2) => { @@ -696,11 +785,12 @@ where None } else { Some(GenericAtom { + ann: atom.ann.clone(), head: value_eq(&atom.args[0], &atom.args[1]), args: vec![ atom.args[0].clone(), atom.args[1].clone(), - GenericAtomTerm::Literal(Literal::Unit), + GenericAtomTerm::Literal(atom.ann, Literal::Unit), ], }) } @@ -708,12 +798,14 @@ where } } HeadOrEq::Symbol(symbol) => Some(GenericAtom { + ann: atom.ann, head: symbol, args: atom.args, }), }) .collect(); GenericCoreRule { + ann: result_rule.ann, body: Query { atoms }, head: result_rule.head, } @@ -724,13 +816,13 @@ impl GenericRule where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash + Debug, - Ann: Clone, + Ann: Annotation, { pub(crate) fn to_core_rule( &self, typeinfo: &TypeInfo, mut fresh_gen: impl FreshGen, - ) -> Result, Head, Leaf>, TypeError> + ) -> Result, Head, Leaf, Ann>, TypeError> where Leaf: SymbolLike, { @@ -740,15 +832,19 @@ where let mut binding = body.get_vars(); let (head, _correspondence) = head.to_core_actions(typeinfo, &mut binding, &mut fresh_gen)?; - Ok(GenericCoreRule { body, head }) + Ok(GenericCoreRule { + ann: self.ann.clone(), + body, + head, + }) } fn to_canonicalized_core_rule_impl( &self, typeinfo: &TypeInfo, fresh_gen: impl FreshGen, - value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, - ) -> Result, TypeError> + value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, + ) -> Result, TypeError> where Leaf: SymbolLike, { diff --git a/src/gj.rs b/src/gj.rs index 61661dd8..9627a46e 100644 --- a/src/gj.rs +++ b/src/gj.rs @@ -246,18 +246,18 @@ impl<'b> Context<'b> { let mut values: Vec = vec![]; for arg in args { values.push(match arg { - AtomTerm::Var(v) => { + AtomTerm::Var(_ann, v) => { let i = self.query.vars.get_index_of(v).unwrap(); self.tuple[i] } - AtomTerm::Literal(lit) => self.egraph.eval_lit(lit), - AtomTerm::Global(_g) => panic!("Globals should have been desugared"), + AtomTerm::Literal(_ann, lit) => self.egraph.eval_lit(lit), + AtomTerm::Global(_ann, _g) => panic!("Globals should have been desugared"), }) } if let Some(res) = prim.apply(&values, None) { match out { - AtomTerm::Var(v) => { + AtomTerm::Var(_ann, v) => { let i = self.query.vars.get_index_of(v).unwrap(); if *check { @@ -269,14 +269,14 @@ impl<'b> Context<'b> { self.tuple[i] = res; } - AtomTerm::Literal(lit) => { + AtomTerm::Literal(_ann, lit) => { assert!(check); let val = &self.egraph.eval_lit(lit); if val != &res { return Ok(()); } } - AtomTerm::Global(_g) => { + AtomTerm::Global(_ann, _g) => { panic!("Globals should have been desugared") } } @@ -362,11 +362,12 @@ impl EGraph { .into_iter() .map(|atom| { let args = atom.args.into_iter().map(|arg| match arg { - ResolvedAtomTerm::Var(v) => AtomTerm::Var(v.name), - ResolvedAtomTerm::Literal(lit) => AtomTerm::Literal(lit), - ResolvedAtomTerm::Global(g) => AtomTerm::Global(g.name), + ResolvedAtomTerm::Var(ann, v) => AtomTerm::Var(ann, v.name), + ResolvedAtomTerm::Literal(ann, lit) => AtomTerm::Literal(ann, lit), + ResolvedAtomTerm::Global(ann, g) => AtomTerm::Global(ann, g.name), }); Atom { + ann: atom.ann, head: atom.head, args: args.collect(), } @@ -389,14 +390,14 @@ impl EGraph { let mut constraints = vec![]; for (i, t) in atom.args.iter().enumerate() { match t { - AtomTerm::Literal(lit) => { + AtomTerm::Literal(_ann, lit) => { let val = self.eval_lit(lit); constraints.push(Constraint::Const(i, val)) } - AtomTerm::Global(_g) => { + AtomTerm::Global(_ann, _g) => { panic!("Globals should have been desugared") } - AtomTerm::Var(_v) => { + AtomTerm::Var(_ann, _v) => { if let Some(j) = atom.args[..i].iter().position(|t2| t == t2) { constraints.push(Constraint::Eq(j, i)); } @@ -423,7 +424,13 @@ impl EGraph { let column = atom .args .iter() - .position(|arg| arg == &AtomTerm::Var(var)) + .position(|arg| { + if let AtomTerm::Var(_, var2) = arg { + &var == var2 + } else { + false + } + }) .unwrap(); self.make_trie_access_for_column(atom, column, timestamp_range, include_subsumed) } @@ -448,12 +455,12 @@ impl EGraph { for (i, atom) in atoms.iter().enumerate() { for (col, arg) in atom.args.iter().enumerate() { match arg { - AtomTerm::Var(var) => vars.entry(*var).or_default().occurences.push(i), - AtomTerm::Literal(lit) => { + AtomTerm::Var(_ann, var) => vars.entry(*var).or_default().occurences.push(i), + AtomTerm::Literal(_ann, lit) => { let val = self.eval_lit(lit); constants.entry(i).or_default().push((col, val)); } - AtomTerm::Global(_g) => { + AtomTerm::Global(_ann, _g) => { panic!("Globals should have been desugared") } } @@ -568,24 +575,24 @@ impl EGraph { let next = extra.iter().position(|p| { assert!(!p.args.is_empty()); p.args[..p.args.len() - 1].iter().all(|a| match a { - AtomTerm::Var(v) => vars.contains_key(v), - AtomTerm::Literal(_) => true, - AtomTerm::Global(_) => true, + AtomTerm::Var(_ann, v) => vars.contains_key(v), + AtomTerm::Literal(_ann, _) => true, + AtomTerm::Global(_ann, _) => true, }) }); if let Some(i) = next { let p = extra.remove(i); let check = match p.args.last().unwrap() { - AtomTerm::Var(v) => match vars.entry(*v) { + AtomTerm::Var(_ann, v) => match vars.entry(*v) { Entry::Occupied(_) => true, Entry::Vacant(e) => { e.insert(Default::default()); false } }, - AtomTerm::Literal(_) => true, - AtomTerm::Global(_) => true, + AtomTerm::Literal(_ann, _) => true, + AtomTerm::Global(_ann, _) => true, }; program.push(Instr::Call { prim: p.head.clone(), @@ -623,24 +630,24 @@ impl EGraph { }; for a in args { - if let AtomTerm::Var(v) = a { + if let AtomTerm::Var(_ann, v) = a { let i = query.vars.get_index_of(v).unwrap(); assert!(tuple_valid[i]); } } match last { - AtomTerm::Var(v) => { + AtomTerm::Var(_ann, v) => { let i = query.vars.get_index_of(v).unwrap(); assert_eq!(*check, tuple_valid[i], "{instr}"); if !*check { tuple_valid[i] = true; } } - AtomTerm::Literal(_) => { + AtomTerm::Literal(_ann, _) => { assert!(*check); } - AtomTerm::Global(_) => { + AtomTerm::Global(_ann, _) => { assert!(*check); } } @@ -736,7 +743,7 @@ impl EGraph { if has_atoms { for atom in cq.query.funcs() { for arg in &atom.args { - if let AtomTerm::Global(_g) = arg { + if let AtomTerm::Global(_ann, _g) = arg { panic!("Globals should have been desugared") } } diff --git a/src/lib.rs b/src/lib.rs index cc864574..2a91e242 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,9 @@ pub type Subst = IndexMap; pub trait PrimitiveLike { fn name(&self) -> Symbol; - fn get_type_constraints(&self) -> Box; + /// Constructs a type constraint for the primitive that uses the span information + /// for error localization. + fn get_type_constraints(&self, span: &Span) -> Box; fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option; } @@ -299,12 +301,12 @@ impl Primitive { fn accept(&self, tys: &[Arc]) -> bool { let mut constraints = vec![]; let lits: Vec<_> = (0..tys.len()) - .map(|i| AtomTerm::Literal(Literal::Int(i as i64))) + .map(|i| AtomTerm::Literal(*DUMMY_SPAN, Literal::Int(i as i64))) .collect(); for (lit, ty) in lits.iter().zip(tys.iter()) { constraints.push(Constraint::Assign(lit.clone(), ty.clone())) } - constraints.extend(self.get_type_constraints().get(&lits)); + constraints.extend(self.get_type_constraints(&DUMMY_SPAN).get(&lits)); let problem = Problem { constraints, range: HashSet::default(), @@ -362,14 +364,14 @@ impl PrimitiveLike for SimplePrimitive { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { let sorts: Vec<_> = self .input .iter() .chain(once(&self.output as &ArcSort)) .cloned() .collect(); - SimpleTypeConstraint::new(self.name(), sorts).into_box() + SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { (self.f)(values) @@ -1611,9 +1613,7 @@ mod tests { use std::sync::Arc; use crate::{ - constraint::SimpleTypeConstraint, - sort::{FromSort, I64Sort, IntoSort, Sort, VecSort}, - EGraph, PrimitiveLike, Value, + constraint::SimpleTypeConstraint, sort::{FromSort, I64Sort, IntoSort, Sort, VecSort}, EGraph, PrimitiveLike, Span, Value }; struct InnerProduct { @@ -1626,10 +1626,11 @@ mod tests { "inner-product".into() } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.clone(), self.ele.clone()], + *span, ) .into_box() } diff --git a/src/sort/fn.rs b/src/sort/fn.rs index 194d1a8c..530b1b3b 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -203,6 +203,7 @@ struct FunctionCTorTypeConstraint { name: Symbol, function: Arc, string: Arc, + span: Span, } impl TypeConstraint for FunctionCTorTypeConstraint { @@ -212,6 +213,7 @@ impl TypeConstraint for FunctionCTorTypeConstraint { vec![Constraint::Impossible( constraint::ImpossibleConstraint::ArityMismatch { atom: core::Atom { + ann: self.span, head: self.name, args: arguments.to_vec(), }, @@ -243,11 +245,12 @@ impl PrimitiveLike for Ctor { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { Box::new(FunctionCTorTypeConstraint { name: self.name, function: self.function.clone(), string: self.string.clone(), + span: *span, }) } @@ -276,11 +279,11 @@ impl PrimitiveLike for Apply { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { let mut sorts: Vec = vec![self.function.clone()]; sorts.extend(self.function.inputs.clone()); sorts.push(self.function.output.clone()); - SimpleTypeConstraint::new(self.name(), sorts).into_box() + SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -324,9 +327,9 @@ fn call_fn(egraph: &mut EGraph, name: &Symbol, types: Vec, args: Vec Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.string.clone()) .with_exact_length(3) .with_output_sort(self.int.clone()) diff --git a/src/sort/macros.rs b/src/sort/macros.rs index 66ea6371..723ec28a 100644 --- a/src/sort/macros.rs +++ b/src/sort/macros.rs @@ -42,9 +42,10 @@ macro_rules! add_primitives { fn get_type_constraints( &self, + span: &Span ) -> Box { let sorts = vec![$(self.$param.clone(),)* self.__out.clone() as ArcSort]; - SimpleTypeConstraint::new(self.name(), sorts).into_box() + SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/map.rs b/src/sort/map.rs index eea2915d..938e04f9 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -210,8 +210,8 @@ impl PrimitiveLike for MapRebuild { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], *span).into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -243,8 +243,8 @@ impl PrimitiveLike for TermOrderingMin { "ordering-min".into() } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_exact_length(3) .into_box() } @@ -266,8 +266,8 @@ impl PrimitiveLike for TermOrderingMax { "ordering-max".into() } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_exact_length(3) .into_box() } @@ -287,8 +287,8 @@ impl PrimitiveLike for Ctor { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.map.clone()], *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -307,7 +307,7 @@ impl PrimitiveLike for Insert { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![ @@ -316,6 +316,7 @@ impl PrimitiveLike for Insert { self.map.value(), self.map.clone(), ], + *span, ) .into_box() } @@ -337,10 +338,11 @@ impl PrimitiveLike for Get { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.map.value()], + *span, ) .into_box() } @@ -362,10 +364,11 @@ impl PrimitiveLike for NotContains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.unit.clone()], + *span, ) .into_box() } @@ -391,10 +394,11 @@ impl PrimitiveLike for Contains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.unit.clone()], + *span, ) .into_box() } @@ -419,10 +423,11 @@ impl PrimitiveLike for Remove { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.map.clone()], + *span, ) .into_box() } @@ -445,8 +450,8 @@ impl PrimitiveLike for Length { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/mod.rs b/src/sort/mod.rs index b5695450..324b1bb5 100644 --- a/src/sort/mod.rs +++ b/src/sort/mod.rs @@ -170,8 +170,8 @@ impl PrimitiveLike for ValueEq { *VALUE_EQ } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_exact_length(3) .with_output_sort(self.unit.clone()) .into_box() diff --git a/src/sort/set.rs b/src/sort/set.rs index c61169df..ddab8bfb 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -222,8 +222,8 @@ impl PrimitiveLike for SetOf { self.name } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.set.element()) .with_output_sort(self.set.clone()) .into_box() @@ -245,8 +245,8 @@ impl PrimitiveLike for Ctor { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.set.clone()],*span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -265,8 +265,8 @@ impl PrimitiveLike for SetRebuild { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], *span).into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -289,10 +289,11 @@ impl PrimitiveLike for Insert { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.set.clone()], + *span, ) .into_box() } @@ -315,10 +316,11 @@ impl PrimitiveLike for NotContains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.unit.clone()], + *span, ) .into_box() } @@ -344,10 +346,11 @@ impl PrimitiveLike for Contains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.unit.clone()], + *span, ) .into_box() } @@ -372,10 +375,11 @@ impl PrimitiveLike for Union { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], + *span, ) .into_box() } @@ -398,10 +402,11 @@ impl PrimitiveLike for Intersect { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], + *span, ) .into_box() } @@ -426,8 +431,8 @@ impl PrimitiveLike for Length { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()],*span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -446,10 +451,11 @@ impl PrimitiveLike for Get { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.i64.clone(), self.set.element()], + *span, ) .into_box() } @@ -471,10 +477,11 @@ impl PrimitiveLike for Remove { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.set.clone()], + *span, ) .into_box() } @@ -496,10 +503,11 @@ impl PrimitiveLike for Diff { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], + *span, ) .into_box() } diff --git a/src/sort/string.rs b/src/sort/string.rs index 745d14e0..c3034d9d 100644 --- a/src/sort/string.rs +++ b/src/sort/string.rs @@ -71,8 +71,8 @@ impl PrimitiveLike for Add { self.name } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.string.clone()) .into_box() } @@ -98,8 +98,8 @@ impl PrimitiveLike for Replace { self.name } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.string.clone()) .with_exact_length(4) .into_box() diff --git a/src/sort/unit.rs b/src/sort/unit.rs index a73a5983..a2efdf4f 100644 --- a/src/sort/unit.rs +++ b/src/sort/unit.rs @@ -48,8 +48,8 @@ impl PrimitiveLike for NotEqualPrimitive { "!=".into() } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_exact_length(3) .with_output_sort(self.unit.clone()) .into_box() diff --git a/src/sort/vec.rs b/src/sort/vec.rs index 99530247..b933f96d 100644 --- a/src/sort/vec.rs +++ b/src/sort/vec.rs @@ -229,8 +229,9 @@ impl PrimitiveLike for VecRebuild { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -251,8 +252,8 @@ impl PrimitiveLike for VecOf { self.name } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.vec.element()) .with_output_sort(self.vec.clone()) .into_box() @@ -274,8 +275,8 @@ impl PrimitiveLike for Append { self.name } - fn get_type_constraints(&self) -> Box { - AllEqualTypeConstraint::new(self.name()) + fn get_type_constraints(&self, span: &Span) -> Box { + AllEqualTypeConstraint::new(self.name(), *span) .with_all_arguments_sort(self.vec.clone()) .into_box() } @@ -296,8 +297,8 @@ impl PrimitiveLike for Ctor { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone()], *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -316,10 +317,11 @@ impl PrimitiveLike for Push { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.vec.clone()], + *span, ) .into_box() } @@ -341,8 +343,9 @@ impl PrimitiveLike for Pop { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -363,10 +366,11 @@ impl PrimitiveLike for NotContains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.unit.clone()], + *span, ) .into_box() } @@ -392,10 +396,11 @@ impl PrimitiveLike for Contains { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.unit.clone()], + *span, ) .into_box() } @@ -421,8 +426,9 @@ impl PrimitiveLike for Length { self.name } - fn get_type_constraints(&self) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.i64.clone()]).into_box() + fn get_type_constraints(&self, span: &Span) -> Box { + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.i64.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -442,10 +448,11 @@ impl PrimitiveLike for Get { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.i64.clone(), self.vec.element()], + *span, ) .into_box() } @@ -468,7 +475,7 @@ impl PrimitiveLike for Set { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![ @@ -477,6 +484,7 @@ impl PrimitiveLike for Set { self.vec.element.clone(), self.vec.clone(), ], + *span, ) .into_box() } @@ -500,10 +508,11 @@ impl PrimitiveLike for Remove { self.name } - fn get_type_constraints(&self) -> Box { + fn get_type_constraints(&self, span: &Span) -> Box { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.i64.clone(), self.vec.clone()], + *span, ) .into_box() } diff --git a/src/typechecking.rs b/src/typechecking.rs index c8215b65..4eca6077 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -253,8 +253,8 @@ impl TypeInfo { } let mut bound_vars = IndexMap::default(); let output_type = self.sorts.get(&fdecl.schema.output).unwrap(); - bound_vars.insert("old".into(), output_type.clone()); - bound_vars.insert("new".into(), output_type.clone()); + bound_vars.insert("old".into(), (*DUMMY_SPAN, output_type.clone())); + bound_vars.insert("new".into(), (*DUMMY_SPAN, output_type.clone())); Ok(ResolvedFunctionDecl { name: fdecl.name, @@ -347,6 +347,7 @@ impl TypeInfo { let mut problem = Problem::default(); problem.add_rule( &CoreRule { + ann: *ann, body: query, head: actions, }, @@ -382,7 +383,7 @@ impl TypeInfo { fn typecheck_actions( &self, actions: &Actions, - binding: &IndexMap, + binding: &IndexMap, ) -> Result { let mut binding_set = binding.keys().cloned().collect::>(); let mut fresh_gen = SymbolGen::new("$".to_string()); @@ -394,8 +395,8 @@ impl TypeInfo { problem.add_actions(&actions, self)?; // add bindings from the context - for (var, sort) in binding { - problem.assign_local_var_type(*var, sort.clone())?; + for (var, (span, sort)) in binding { + problem.assign_local_var_type(*var, *span, sort.clone())?; } let assignment = problem @@ -409,7 +410,7 @@ impl TypeInfo { fn typecheck_expr( &self, expr: &Expr, - binding: &IndexMap, + binding: &IndexMap, ) -> Result { let action = Action::Expr(*DUMMY_SPAN, expr.clone()); let typechecked_action = self.typecheck_action(&action, binding)?; @@ -422,7 +423,7 @@ impl TypeInfo { fn typecheck_action( &self, action: &Action, - binding: &IndexMap, + binding: &IndexMap, ) -> Result { self.typecheck_actions(&Actions::singleton(action.clone()), binding) .map(|mut v| { From ab826f4b526ed12929d30b4f77169f862441e090 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 2 Jul 2024 17:00:02 -0700 Subject: [PATCH 05/16] almost passing tests --- src/ast/desugar.rs | 2 +- src/ast/mod.rs | 2 +- src/core.rs | 14 +++++++------- src/termdag.rs | 3 +-- tests/files.rs | 17 +++++++++++++---- tests/integration_test.rs | 23 ++++++++++++++++++++--- 6 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index f1808890..b9efb912 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -325,7 +325,7 @@ pub(crate) fn desugar_command( }; desugar.desugar_program( - desugar.parse_program(todo!("our filename should be richer to better support locating desugared rule. Alternatively, we can just use the same source location"), &desugaring).unwrap(), + desugar.parse_program(None, &desugaring).unwrap(), get_all_proofs, seminaive_transform, )? diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 19e5a0f1..1b5d5dfa 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -65,7 +65,7 @@ lazy_static! { impl Copy for Span {} -pub(crate) trait Annotation: Clone + PartialEq + Eq + Hash + Debug { +pub trait Annotation: Clone + PartialEq + Eq + Hash + Debug { fn dummy() -> Self; } diff --git a/src/core.rs b/src/core.rs index 7ff3ab21..a92fb725 100644 --- a/src/core.rs +++ b/src/core.rs @@ -179,14 +179,14 @@ impl GenericAtomTerm { } } -impl AtomTerm { - pub fn to_expr(&self) -> Expr { +impl GenericAtomTerm { + pub fn to_expr(&self) -> GenericExpr { match self { - AtomTerm::Var(_, v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), - AtomTerm::Literal(_, l) => { - Expr::Lit(todo!("investigate usages of to_expr()"), l.clone()) + GenericAtomTerm::Var(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), + GenericAtomTerm::Literal(ann, l) => { + GenericExpr::Lit(ann.clone(), l.clone()) } - AtomTerm::Global(_, v) => Expr::Var(todo!("investigate usages of to_expr()"), *v), + GenericAtomTerm::Global(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), } } } @@ -257,7 +257,7 @@ impl Atom { pub(crate) fn to_expr(&self) -> Expr { let n = self.args.len(); Expr::Call( - todo!("need to investigate to_expr"), + self.ann.clone(), self.head, self.args[0..n - 1] .iter() diff --git a/src/termdag.rs b/src/termdag.rs index 85d01485..0d5111e2 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -224,8 +224,7 @@ mod tests { ] ); let e2 = td.term_to_expr(&t); - todo!("the following assertion fails type check") - // assert_eq!(e, e2); // roundtrip + assert_eq!(e.to_sexp(), e2.to_sexp()); // roundtrip } #[test] diff --git a/tests/files.rs b/tests/files.rs index 3ee1f63b..5eb69300 100644 --- a/tests/files.rs +++ b/tests/files.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use egglog::*; use libtest_mimic::Trial; +use symbol_table::GlobalSymbol as Symbol; #[derive(Clone)] struct Run { @@ -16,24 +17,32 @@ impl Run { .unwrap_or_else(|err| panic!("Couldn't read {:?}: {:?}", self.path, err)); if !self.resugar { - self.test_program(&program, "Top level error"); + self.test_program( + self.path.to_str().map(Symbol::from), + &program, + "Top level error", + ); } else { let mut egraph = EGraph::default(); egraph.run_mode = RunMode::ShowDesugaredEgglog; egraph.set_reserved_symbol("__".into()); - let desugared_str = egraph.parse_and_run_program(&program).unwrap().join("\n"); + let desugared_str = egraph + .parse_and_run_program(self.path.to_str().map(Symbol::from), &program) + .unwrap() + .join("\n"); self.test_program( + None, &desugared_str, "ERROR after parse, to_string, and parse again.", ); } } - fn test_program(&self, program: &str, message: &str) { + fn test_program(&self, filename: Option, program: &str, message: &str) { let mut egraph = EGraph::default(); egraph.set_reserved_symbol("___".into()); - match egraph.parse_and_run_program(program) { + match egraph.parse_and_run_program(filename, program) { Ok(msgs) => { if self.should_fail() { panic!( diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 88861131..83aa1441 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,4 +1,4 @@ -use egglog::{ast::Expr, EGraph, ExtractReport, Function, Term, Value}; +use egglog::{ast::{Expr, GenericExpr}, EGraph, ExtractReport, Function, Term, Value}; use symbol_table::GlobalSymbol; #[test] @@ -8,6 +8,7 @@ fn test_subsumed_unextractable_action_extract() { egraph .parse_and_run_program( + None, r#" (datatype Math) (function exp () Math :cost 100) @@ -28,6 +29,7 @@ fn test_subsumed_unextractable_action_extract() { // Then if we make one as subsumed, it should give back the variable term egraph .parse_and_run_program( + None, r#" (subsume (cheap)) (query-extract (exp)) @@ -61,6 +63,7 @@ fn test_subsumed_unextractable_rebuild_arg() { egraph .parse_and_run_program( + None, r#" (datatype Math) (function container (Math) Math) @@ -83,6 +86,7 @@ fn test_subsumed_unextractable_rebuild_arg() { // Then we can union them egraph .parse_and_run_program( + None, r#" (union (cheap-1) (cheap)) "#, @@ -97,6 +101,7 @@ fn test_subsumed_unextractable_rebuild_arg() { // Now verify that if we extract, it still respects the unextractable, even though it's a different values now egraph .parse_and_run_program( + None, r#" (query-extract res) "#, @@ -107,7 +112,7 @@ fn test_subsumed_unextractable_rebuild_arg() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!(expr, Expr::Call((), GlobalSymbol::from("exp"), vec![])); + assert_eq!(expr, GenericExpr::Call((), GlobalSymbol::from("exp"), vec![])); } #[test] @@ -117,6 +122,7 @@ fn test_subsumed_unextractable_rebuild_self() { egraph .parse_and_run_program( + None, r#" (datatype Math) (function container (Math) Math) @@ -132,6 +138,7 @@ fn test_subsumed_unextractable_rebuild_self() { // Then we can union them egraph .parse_and_run_program( + None, r#" (union (exp) x) "#, @@ -145,6 +152,7 @@ fn test_subsumed_unextractable_rebuild_self() { // Now verify that if we extract, it still respects the subsumption, even though it's a different values now egraph .parse_and_run_program( + None, r#" (query-extract x) "#, @@ -155,7 +163,7 @@ fn test_subsumed_unextractable_rebuild_self() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!(expr, Expr::Call((), GlobalSymbol::from("exp"), vec![])); + assert_eq!(expr, GenericExpr::Call((), GlobalSymbol::from("exp"), vec![])); } #[test] @@ -165,6 +173,7 @@ fn test_subsume_unextractable_insert_and_merge() { egraph .parse_and_run_program( + None, r#" (datatype Expr (f Expr) @@ -198,6 +207,7 @@ fn test_subsume_unextractable_action_extract_multiple() { egraph .parse_and_run_program( + None, " (datatype Math (Num i64)) (Num 1) @@ -215,6 +225,7 @@ fn test_subsume_unextractable_action_extract_multiple() { // Then if we make one unextractable, it should only give back one term egraph .parse_and_run_program( + None, " (subsume (Num 2)) (query-extract :variants 2 (Num 1)) @@ -236,6 +247,7 @@ fn test_rewrite_subsumed_unextractable() { egraph .parse_and_run_program( + None, r#" (datatype Math) (function exp () Math :cost 100) @@ -265,6 +277,7 @@ fn test_rewrite_subsumed() { // If we rerite most-exp to another term, that rewrite shouldnt trigger since its been subsumed. egraph .parse_and_run_program( + None, r#" (datatype Math) (function exp () Math :cost 100) @@ -296,6 +309,7 @@ fn test_subsume() { let mut egraph = EGraph::default(); egraph .parse_and_run_program( + None, r#" (datatype Math (Add Math Math) @@ -317,6 +331,7 @@ fn test_subsume() { egraph .parse_and_run_program( + None, r#" ;; add something equal to x that can be extracted: (declare other Math) @@ -337,6 +352,7 @@ fn test_subsume_primitive() { let mut egraph = EGraph::default(); let res = egraph.parse_and_run_program( + None, r#" (function one () i64) (set (one) 1) @@ -352,6 +368,7 @@ fn test_cant_subsume_merge() { let mut egraph = EGraph::default(); let res = egraph.parse_and_run_program( + None, r#" (function one () i64 :merge old) (set (one) 1) From b5f03882bb84117c01ca99bb9706cfa3e83275d3 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 2 Jul 2024 17:06:51 -0700 Subject: [PATCH 06/16] fix test --- src/extract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extract.rs b/src/extract.rs index 9fabd80d..587afc4f 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -24,7 +24,7 @@ impl EGraph { /// trivial, as there is only a single variant of the expression in the /// egraph. /// ``` - /// use egglog::{EGraph, TermDag}; + /// use egglog::{EGraph, TermDag, ast::Annotation}; /// let mut egraph = EGraph::default(); /// egraph /// .parse_and_run_program( @@ -35,7 +35,7 @@ impl EGraph { /// .unwrap(); /// let mut termdag = TermDag::default(); /// let (sort, value) = egraph - /// .eval_expr(&egglog::ast::Expr::Var((), "expr".into())) + /// .eval_expr(&egglog::ast::Expr::Var(Annotation::dummy(), "expr".into())) /// .unwrap(); /// let (_, extracted) = egraph.extract(value, &mut termdag, &sort); /// assert_eq!(termdag.to_string(&extracted), "(Add 1 1)"); From 1f0a1fddfe59bd88504e2a2311d19186bc3bca5c Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 2 Jul 2024 17:28:21 -0700 Subject: [PATCH 07/16] fix web demo --- src/termdag.rs | 5 ++++- web-demo/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/termdag.rs b/src/termdag.rs index 0d5111e2..450bf595 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,5 +1,5 @@ use crate::{ - ast::Literal, + ast::{Literal, Expr}, util::{HashMap, HashSet}, GeneratedExpr, GenericExpr, Symbol, }; @@ -224,6 +224,9 @@ mod tests { ] ); let e2 = td.term_to_expr(&t); + // This is tested using Sexp's equality because e1 and e2 have different + // annotations. A better way to test this would be to implement a map_ann + // function for GenericExpr. assert_eq!(e.to_sexp(), e2.to_sexp()); // roundtrip } diff --git a/web-demo/src/lib.rs b/web-demo/src/lib.rs index 312b301c..548ae2bf 100644 --- a/web-demo/src/lib.rs +++ b/web-demo/src/lib.rs @@ -15,7 +15,7 @@ pub struct Result { #[wasm_bindgen] pub fn run_program(input: &str) -> Result { let mut egraph = egglog::EGraph::default(); - match egraph.parse_and_run_program(input) { + match egraph.parse_and_run_program(Some("web-demo.egg".into()), input) { Ok(outputs) => { let serialized = egraph.serialize_for_graphviz(false, 40, 40); Result { From 85a0fcb3d16829f1a50791918411471e14c4cc19 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 2 Jul 2024 17:32:05 -0700 Subject: [PATCH 08/16] nits --- src/actions.rs | 14 ++++++++------ src/ast/desugar.rs | 11 +++++++---- src/ast/mod.rs | 4 +--- src/constraint.rs | 12 ++++++------ src/core.rs | 6 ++---- src/lib.rs | 18 ++++++++++++++---- src/main.rs | 2 +- src/sort/map.rs | 6 ++++-- src/sort/set.rs | 8 +++++--- src/termdag.rs | 6 +++--- src/typechecking.rs | 2 +- tests/integration_test.rs | 12 +++++++++--- 12 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index 09e88b22..a14f7448 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -301,15 +301,17 @@ impl EGraph { value } _ => { - return Err(Error::NotFoundError(NotFoundError( - format!("No value found for {f} {:?}", values).into(), - ))) + return Err(Error::NotFoundError(NotFoundError(format!( + "No value found for {f} {:?}", + values + )))) } } } else { - return Err(Error::NotFoundError(NotFoundError( - format!("No value found for {f} {:?}", values).into(), - ))); + return Err(Error::NotFoundError(NotFoundError(format!( + "No value found for {f} {:?}", + values + )))); }; debug_assert_eq!(output_tag, value.tag); diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index b9efb912..01541971 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -71,10 +71,13 @@ fn desugar_rewrite( name, rule: Rule { ann: span, - body: [Fact::Eq(span, vec![Expr::Var(span, var), rewrite.lhs.clone()])] - .into_iter() - .chain(rewrite.conditions.clone()) - .collect(), + body: [Fact::Eq( + span, + vec![Expr::Var(span, var), rewrite.lhs.clone()], + )] + .into_iter() + .chain(rewrite.conditions.clone()) + .collect(), head, }, }] diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 1b5d5dfa..e9692eb4 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -76,9 +76,7 @@ impl Annotation for Span { } impl Annotation for () { - fn dummy() -> Self { - () - } + fn dummy() -> Self {} } pub type NCommand = GenericNCommand; diff --git a/src/constraint.rs b/src/constraint.rs index af6085d0..cbece6bd 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -455,10 +455,10 @@ impl Problem { // bound vars are added to range match action { CoreAction::Let(ann, var, _, _) => { - self.range.insert(AtomTerm::Var(ann.clone(), *var)); + self.range.insert(AtomTerm::Var(*ann, *var)); } CoreAction::LetAtomTerm(ann, v, _) => { - self.range.insert(AtomTerm::Var(ann.clone(), *v)); + self.range.insert(AtomTerm::Var(*ann, *v)); } _ => (), } @@ -498,7 +498,7 @@ impl CoreAction { match self { CoreAction::Let(ann, symbol, f, args) => { let mut args = args.clone(); - args.push(AtomTerm::Var(ann.clone(), *symbol)); + args.push(AtomTerm::Var(*ann, *symbol)); Ok(get_literal_and_global_constraints(&args, typeinfo) .chain(get_atom_application_constraints(f, &args, ann, typeinfo)?) @@ -526,13 +526,13 @@ impl CoreAction { )?) .collect()) } - CoreAction::Union(ann, lhs, rhs) => Ok(get_literal_and_global_constraints( + CoreAction::Union(_ann, lhs, rhs) => Ok(get_literal_and_global_constraints( &[lhs.clone(), rhs.clone()], typeinfo, ) .chain(once(Constraint::Eq(lhs.clone(), rhs.clone()))) .collect()), - CoreAction::Extract(ann, e, n) => { + CoreAction::Extract(_ann, e, n) => { // e can be anything Ok( get_literal_and_global_constraints(&[e.clone(), n.clone()], typeinfo) @@ -543,7 +543,7 @@ impl CoreAction { .collect(), ) } - CoreAction::Panic(ann, _) => Ok(vec![]), + CoreAction::Panic(_ann, _) => Ok(vec![]), CoreAction::LetAtomTerm(ann, v, at) => { Ok(get_literal_and_global_constraints(&[at.clone()], typeinfo) .chain(once(Constraint::Eq(AtomTerm::Var(*ann, *v), at.clone()))) diff --git a/src/core.rs b/src/core.rs index a92fb725..5f3eeed5 100644 --- a/src/core.rs +++ b/src/core.rs @@ -183,9 +183,7 @@ impl GenericAtomTerm { pub fn to_expr(&self) -> GenericExpr { match self { GenericAtomTerm::Var(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), - GenericAtomTerm::Literal(ann, l) => { - GenericExpr::Lit(ann.clone(), l.clone()) - } + GenericAtomTerm::Literal(ann, l) => GenericExpr::Lit(ann.clone(), l.clone()), GenericAtomTerm::Global(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), } } @@ -257,7 +255,7 @@ impl Atom { pub(crate) fn to_expr(&self) -> Expr { let n = self.args.len(); Expr::Call( - self.ann.clone(), + self.ann, self.head, self.args[0..n - 1] .iter() diff --git a/src/lib.rs b/src/lib.rs index 2a91e242..3da38e01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1213,7 +1213,7 @@ impl EGraph { fn check_facts(&mut self, span: &Span, facts: &[ResolvedFact]) -> Result<(), Error> { let rule = ast::ResolvedRule { - ann: span.clone(), + ann: *span, head: ResolvedActions::default(), body: facts.to_vec(), }; @@ -1486,11 +1486,19 @@ impl EGraph { Ok(self.flush_msgs()) } - pub fn parse_program(&self, filename: Option, input: &str) -> Result, Error> { + pub fn parse_program( + &self, + filename: Option, + input: &str, + ) -> Result, Error> { self.desugar.parse_program(filename, input) } - pub fn parse_and_run_program(&mut self, filename: Option, input: &str) -> Result, Error> { + pub fn parse_and_run_program( + &mut self, + filename: Option, + input: &str, + ) -> Result, Error> { let parsed = self.desugar.parse_program(filename, input)?; self.run_program(parsed) } @@ -1613,7 +1621,9 @@ mod tests { use std::sync::Arc; use crate::{ - constraint::SimpleTypeConstraint, sort::{FromSort, I64Sort, IntoSort, Sort, VecSort}, EGraph, PrimitiveLike, Span, Value + constraint::SimpleTypeConstraint, + sort::{FromSort, I64Sort, IntoSort, Sort, VecSort}, + EGraph, PrimitiveLike, Span, Value, }; struct InnerProduct { diff --git a/src/main.rs b/src/main.rs index 573b7fcc..d4dbf532 100644 --- a/src/main.rs +++ b/src/main.rs @@ -112,7 +112,7 @@ fn main() { }); let mut egraph = mk_egraph(); let program_offset = 0; - match egraph.parse_and_run_program(Some(input.to_str().unwrap().into()),&program) { + match egraph.parse_and_run_program(Some(input.to_str().unwrap().into()), &program) { Ok(msgs) => { for msg in msgs { println!("{msg}"); diff --git a/src/sort/map.rs b/src/sort/map.rs index 938e04f9..5769243f 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -211,7 +211,8 @@ impl PrimitiveLike for MapRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -451,7 +452,8 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/set.rs b/src/sort/set.rs index ddab8bfb..beb48e9a 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -246,7 +246,7 @@ impl PrimitiveLike for Ctor { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone()],*span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.set.clone()], *span).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -266,7 +266,8 @@ impl PrimitiveLike for SetRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -432,7 +433,8 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()],*span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()], *span) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/termdag.rs b/src/termdag.rs index 450bf595..5bb853a6 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{Literal, Expr}, + ast::Literal, util::{HashMap, HashSet}, GeneratedExpr, GenericExpr, Symbol, }; @@ -224,8 +224,8 @@ mod tests { ] ); let e2 = td.term_to_expr(&t); - // This is tested using Sexp's equality because e1 and e2 have different - // annotations. A better way to test this would be to implement a map_ann + // This is tested using Sexp's equality because e1 and e2 have different + // annotations. A better way to test this would be to implement a map_ann // function for GenericExpr. assert_eq!(e.to_sexp(), e2.to_sexp()); // roundtrip } diff --git a/src/typechecking.rs b/src/typechecking.rs index 4eca6077..d7053c64 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -190,7 +190,7 @@ impl TypeInfo { // not a global reference, but a global binding is_global_ref: false, }; - ResolvedNCommand::CoreAction(ResolvedAction::Let(ann.clone(), var, expr)) + ResolvedNCommand::CoreAction(ResolvedAction::Let(*ann, var, expr)) } NCommand::CoreAction(action) => { ResolvedNCommand::CoreAction(self.typecheck_action(action, &Default::default())?) diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 83aa1441..fa13e8da 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,4 +1,4 @@ -use egglog::{ast::{Expr, GenericExpr}, EGraph, ExtractReport, Function, Term, Value}; +use egglog::{ast::GenericExpr, EGraph, ExtractReport, Function, Term, Value}; use symbol_table::GlobalSymbol; #[test] @@ -112,7 +112,10 @@ fn test_subsumed_unextractable_rebuild_arg() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!(expr, GenericExpr::Call((), GlobalSymbol::from("exp"), vec![])); + assert_eq!( + expr, + GenericExpr::Call((), GlobalSymbol::from("exp"), vec![]) + ); } #[test] @@ -163,7 +166,10 @@ fn test_subsumed_unextractable_rebuild_self() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!(expr, GenericExpr::Call((), GlobalSymbol::from("exp"), vec![])); + assert_eq!( + expr, + GenericExpr::Call((), GlobalSymbol::from("exp"), vec![]) + ); } #[test] From 82b9457917edda42952da9422977438435f858d1 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Wed, 3 Jul 2024 14:09:48 -0700 Subject: [PATCH 09/16] add a test --- src/typechecking.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/typechecking.rs b/src/typechecking.rs index d7053c64..9d358b12 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -511,16 +511,20 @@ mod test { fn test_arity_mismatch() { let mut egraph = EGraph::default(); - let res = egraph.parse_and_run_program( - None, - " + let prog = " (relation f (i64 i64)) (rule ((f a b c)) ()) - ", + "; + let res = egraph.parse_and_run_program( + None, + prog, ); - assert!(matches!( - res, - Err(Error::TypeError(TypeError::Arity { expected: 2, .. })) - )); + match res { + Err(Error::TypeError(TypeError::Arity { expected: 2, expr: e })) => { + let span = e.ann(); + assert_eq!(&prog[span.1..span.2], "(f a b c)"); + }, + _ => panic!("Expected arity mismatch, got: {:?}", res), + } } } From 141aa1d81367568faf213fd6c29f3aa76b615bad Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Wed, 3 Jul 2024 14:11:14 -0700 Subject: [PATCH 10/16] nits --- src/typechecking.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/typechecking.rs b/src/typechecking.rs index 9d358b12..199166ae 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -515,15 +515,15 @@ mod test { (relation f (i64 i64)) (rule ((f a b c)) ()) "; - let res = egraph.parse_and_run_program( - None, - prog, - ); + let res = egraph.parse_and_run_program(None, prog); match res { - Err(Error::TypeError(TypeError::Arity { expected: 2, expr: e })) => { + Err(Error::TypeError(TypeError::Arity { + expected: 2, + expr: e, + })) => { let span = e.ann(); assert_eq!(&prog[span.1..span.2], "(f a b c)"); - }, + } _ => panic!("Expected arity mismatch, got: {:?}", res), } } From 9bf71a58bb21ed9cb2f9afd435576de42fe494e2 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Mon, 15 Jul 2024 20:25:18 -0700 Subject: [PATCH 11/16] remove generated_expr --- src/ast/expr.rs | 15 +++++++++------ src/sort/bool.rs | 4 ++-- src/sort/f64.rs | 4 ++-- src/sort/fn.rs | 8 ++++---- src/sort/i64.rs | 4 ++-- src/sort/map.rs | 8 ++++---- src/sort/mod.rs | 6 +++--- src/sort/rational.rs | 8 ++++---- src/sort/set.rs | 8 ++++---- src/sort/string.rs | 4 ++-- src/sort/unit.rs | 4 ++-- src/sort/vec.rs | 8 ++++---- src/termdag.rs | 16 +++++++--------- 13 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 0657bf8b..c34c657e 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -108,7 +108,6 @@ impl ToSexp for ResolvedVar { pub type Expr = GenericExpr; /// A generated expression is an expression that is generated by the system /// and does not have annotations. -pub type GeneratedExpr = GenericExpr; pub(crate) type ResolvedExpr = GenericExpr; /// A [`MappedExpr`] arises naturally when you want a mapping between an expression /// and its flattened form. It records this mapping by annotating each `Head` @@ -140,13 +139,17 @@ impl ResolvedExpr { } } -impl GeneratedExpr { - pub fn call(op: impl Into, children: impl IntoIterator) -> Self { - Self::Call((), op.into(), children.into_iter().collect()) +impl Expr { + pub fn call_no_span(op: impl Into, children: impl IntoIterator) -> Self { + Self::Call(*DUMMY_SPAN, op.into(), children.into_iter().collect()) } - pub fn lit(lit: impl Into) -> Self { - Self::Lit((), lit.into()) + pub fn lit_no_span(lit: impl Into) -> Self { + Self::Lit(*DUMMY_SPAN, lit.into()) + } + + pub fn var_no_span(v: impl Into) -> Self { + Self::Var(*DUMMY_SPAN, v.into()) } } diff --git a/src/sort/bool.rs b/src/sort/bool.rs index 0b4bbe5d..fbf63816 100644 --- a/src/sort/bool.rs +++ b/src/sort/bool.rs @@ -31,9 +31,9 @@ impl Sort for BoolSort { add_primitives!(eg, "=>" = |a: bool, b: bool| -> bool { !a || b }); } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); - (1, GeneratedExpr::Lit((), Literal::Bool(value.bits > 0))) + (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Bool(value.bits > 0))) } } diff --git a/src/sort/f64.rs b/src/sort/f64.rs index 4322b74a..f1d17508 100755 --- a/src/sort/f64.rs +++ b/src/sort/f64.rs @@ -53,11 +53,11 @@ impl Sort for F64Sort { } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); ( 1, - GeneratedExpr::Lit((), Literal::F64(OrderedFloat(f64::from_bits(value.bits)))), + GenericExpr::Lit(*DUMMY_SPAN, Literal::F64(OrderedFloat(f64::from_bits(value.bits)))), ) } } diff --git a/src/sort/fn.rs b/src/sort/fn.rs index 530b1b3b..b9711e21 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -151,7 +151,7 @@ impl Sort for FunctionSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -164,10 +164,10 @@ impl Sort for FunctionSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, GeneratedExpr)> { + ) -> Option<(Cost, Expr)> { let ValueFunction(name, inputs) = ValueFunction::load(self, &value); let (cost, args) = inputs.into_iter().try_fold( - (1usize, vec![GeneratedExpr::Lit((), Literal::String(name))]), + (1usize, vec![GenericExpr::Lit(*DUMMY_SPAN, Literal::String(name))]), |(cost, mut args), (sort, value)| { let (new_cost, term) = extractor.find_best(value, termdag, &sort)?; args.push(termdag.term_to_expr(&term)); @@ -175,7 +175,7 @@ impl Sort for FunctionSort { }, )?; - Some((cost, GeneratedExpr::call("unstable-fn", args))) + Some((cost, Expr::call_no_span("unstable-fn", args))) } } diff --git a/src/sort/i64.rs b/src/sort/i64.rs index 608aa791..12b265c7 100644 --- a/src/sort/i64.rs +++ b/src/sort/i64.rs @@ -74,9 +74,9 @@ impl Sort for I64Sort { } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); - (1, GeneratedExpr::Lit((), Literal::Int(value.bits as _))) + (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(value.bits as _))) } } diff --git a/src/sort/map.rs b/src/sort/map.rs index 5769243f..1267e9bc 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -150,7 +150,7 @@ impl Sort for MapSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -163,15 +163,15 @@ impl Sort for MapSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, GeneratedExpr)> { + ) -> Option<(Cost, Expr)> { let map = ValueMap::load(self, &value); - let mut expr = GeneratedExpr::call("map-empty", []); + let mut expr = Expr::call_no_span("map-empty", []); let mut cost = 0usize; for (k, v) in map.iter().rev() { let k = extractor.find_best(*k, termdag, &self.key)?; let v = extractor.find_best(*v, termdag, &self.value)?; cost = cost.saturating_add(k.0).saturating_add(v.0); - expr = GeneratedExpr::call( + expr = Expr::call_no_span( "map-insert", [expr, termdag.term_to_expr(&k.1), termdag.term_to_expr(&v.1)], ) diff --git a/src/sort/mod.rs b/src/sort/mod.rs index 324b1bb5..1890243c 100644 --- a/src/sort/mod.rs +++ b/src/sort/mod.rs @@ -84,7 +84,7 @@ pub trait Sort: Any + Send + Sync + Debug { } /// Extracting an expression (with smallest cost) out of a primitive value - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr); + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr); /// For values like EqSort containers, to make/extract an expression from it /// requires an extractor. Moreover, the extraction may be unsuccessful if @@ -97,7 +97,7 @@ pub trait Sort: Any + Send + Sync + Debug { value: Value, _extractor: &Extractor, _termdag: &mut TermDag, - ) -> Option<(Cost, GeneratedExpr)> { + ) -> Option<(Cost, Expr)> { Some(self.make_expr(egraph, value)) } } @@ -131,7 +131,7 @@ impl Sort for EqSort { } } - fn make_expr(&self, _egraph: &EGraph, _value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, _value: Value) -> (Cost, Expr) { unimplemented!("No make_expr for EqSort {}", self.name) } } diff --git a/src/sort/rational.rs b/src/sort/rational.rs index 7b757f60..b63ecc9b 100644 --- a/src/sort/rational.rs +++ b/src/sort/rational.rs @@ -110,18 +110,18 @@ impl Sort for RationalSort { add_primitives!(eg, ">=" = |a: R, b: R| -> Opt { if a >= b {Some(())} else {None} }); } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); let rat = R::load(self, &value); let numer = *rat.numer(); let denom = *rat.denom(); ( 1, - GeneratedExpr::call( + Expr::call_no_span( "rational", vec![ - GeneratedExpr::Lit((), Literal::Int(numer)), - GeneratedExpr::Lit((), Literal::Int(denom)), + GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(numer)), + GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(denom)), ], ), ) diff --git a/src/sort/set.rs b/src/sort/set.rs index beb48e9a..7fc58280 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -166,7 +166,7 @@ impl Sort for SetSort { }); } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -179,14 +179,14 @@ impl Sort for SetSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, GeneratedExpr)> { + ) -> Option<(Cost, Expr)> { let set = ValueSet::load(self, &value); - let mut expr = GeneratedExpr::call("set-empty", []); + let mut expr = Expr::call_no_span("set-empty", []); let mut cost = 0usize; for e in set.iter().rev() { let e = extractor.find_best(*e, termdag, &self.element)?; cost = cost.saturating_add(e.0); - expr = GeneratedExpr::call("set-insert", [expr, termdag.term_to_expr(&e.1)]) + expr = Expr::call_no_span("set-insert", [expr, termdag.term_to_expr(&e.1)]) } Some((cost, expr)) } diff --git a/src/sort/string.rs b/src/sort/string.rs index c3034d9d..23afea9d 100644 --- a/src/sort/string.rs +++ b/src/sort/string.rs @@ -24,10 +24,10 @@ impl Sort for StringSort { self } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name); let sym = Symbol::from(NonZeroU32::new(value.bits as _).unwrap()); - (1, GeneratedExpr::Lit((), Literal::String(sym))) + (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::String(sym))) } fn register_primitives(self: Arc, typeinfo: &mut TypeInfo) { diff --git a/src/sort/unit.rs b/src/sort/unit.rs index a2efdf4f..730b8e5a 100644 --- a/src/sort/unit.rs +++ b/src/sort/unit.rs @@ -25,9 +25,9 @@ impl Sort for UnitSort { type_info.add_primitive(NotEqualPrimitive { unit: self }) } - fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert_eq!(value.tag, self.name); - (1, GeneratedExpr::Lit((), Literal::Unit)) + (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Unit)) } } diff --git a/src/sort/vec.rs b/src/sort/vec.rs index b933f96d..b1cb5c60 100644 --- a/src/sort/vec.rs +++ b/src/sort/vec.rs @@ -165,7 +165,7 @@ impl Sort for VecSort { }) } - fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, GeneratedExpr) { + fn make_expr(&self, egraph: &EGraph, value: Value) -> (Cost, Expr) { let mut termdag = TermDag::default(); let extractor = Extractor::new(egraph, &mut termdag); self.extract_expr(egraph, value, &extractor, &mut termdag) @@ -178,12 +178,12 @@ impl Sort for VecSort { value: Value, extractor: &Extractor, termdag: &mut TermDag, - ) -> Option<(Cost, GeneratedExpr)> { + ) -> Option<(Cost, Expr)> { let vec = ValueVec::load(self, &value); let mut cost = 0usize; if vec.is_empty() { - Some((cost, GeneratedExpr::call("vec-empty", []))) + Some((cost, Expr::call_no_span("vec-empty", []))) } else { let elems = vec .into_iter() @@ -194,7 +194,7 @@ impl Sort for VecSort { }) .collect::>>()?; - Some((cost, GeneratedExpr::call("vec-of", elems))) + Some((cost, Expr::call_no_span("vec-of", elems))) } } } diff --git a/src/termdag.rs b/src/termdag.rs index 5bb853a6..9b3e6e9e 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,7 +1,5 @@ use crate::{ - ast::Literal, - util::{HashMap, HashSet}, - GeneratedExpr, GenericExpr, Symbol, + ast::Literal, util::{HashMap, HashSet}, Expr, GenericExpr, Symbol, DUMMY_SPAN }; pub type TermId = usize; @@ -131,19 +129,19 @@ impl TermDag { /// Recursively converts the given term to an expression. /// /// Panics if the term contains subterms that are not in the DAG. - pub fn term_to_expr(&self, term: &Term) -> GeneratedExpr { + pub fn term_to_expr(&self, term: &Term) -> Expr { match term { - Term::Lit(lit) => GeneratedExpr::Lit((), lit.clone()), - Term::Var(v) => GeneratedExpr::Var((), *v), + Term::Lit(lit) => Expr::lit_no_span(lit.clone()), + Term::Var(v) => Expr::var_no_span(*v), Term::App(op, args) => { - let args = args + let args: Vec<_> = args .iter() .map(|a| { let term = self.get(*a); self.term_to_expr(&term) }) .collect(); - GeneratedExpr::Call((), *op, args) + Expr::call_no_span(*op, args) } } } @@ -236,7 +234,7 @@ mod tests { let (td, t) = parse_term(s); match_term_app!(t; { ("f", [_, x, _, _]) => - assert_eq!(td.term_to_expr(&td.get(*x)), ast::GeneratedExpr::Var((), Symbol::new("x"))), + assert_eq!(td.term_to_expr(&td.get(*x)), ast::GenericExpr::Var(*DUMMY_SPAN, Symbol::new("x"))), (head, _) => panic!("unexpected head {}, in {}:{}:{}", head, file!(), line!(), column!()) }) } From 216d8d6137f241f5c841c803b148505352e5f091 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Mon, 15 Jul 2024 20:34:49 -0700 Subject: [PATCH 12/16] rename ann to span, get rid of ann --- src/ast/desugar.rs | 34 +-- src/ast/expr.rs | 52 ++--- src/ast/mod.rs | 478 ++++++++++++++++++-------------------- src/ast/parse.lalrpop | 8 +- src/ast/remove_globals.rs | 18 +- src/constraint.rs | 50 ++-- src/core.rs | 246 ++++++++++---------- src/extract.rs | 4 +- src/gj.rs | 8 +- src/lib.rs | 6 +- src/sort/fn.rs | 2 +- src/termdag.rs | 6 +- src/typechecking.rs | 12 +- tests/integration_test.rs | 6 +- 14 files changed, 458 insertions(+), 472 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index 01541971..d3bdab72 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -45,7 +45,7 @@ fn desugar_rewrite( rewrite: &Rewrite, subsume: bool, ) -> Vec { - let span = rewrite.ann; + let span = rewrite.span; let var = Symbol::from("rewrite_var__"); let mut head = Actions::singleton(Action::Union( span, @@ -70,7 +70,7 @@ fn desugar_rewrite( ruleset, name, rule: Rule { - ann: span, + span: span, body: [Fact::Eq( span, vec![Expr::Var(span, var), rewrite.lhs.clone()], @@ -84,9 +84,9 @@ fn desugar_rewrite( } fn desugar_birewrite(ruleset: Symbol, name: Symbol, rewrite: &Rewrite) -> Vec { - let span = rewrite.ann; + let span = rewrite.span; let rw2 = Rewrite { - ann: span, + span: span, lhs: rewrite.rhs.clone(), rhs: rewrite.lhs.clone(), conditions: rewrite.conditions.clone(), @@ -114,24 +114,24 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { let mut var_set = HashSet::default(); for head_slice in new_rule.head.0.iter_mut().rev() { match head_slice { - Action::Set(ann, _, _, expr) => { + Action::Set(span, _, _, expr) => { var_set.extend(expr.vars()); if let Expr::Call(..) = expr { add_new_rule = true; let fresh_symbol = desugar.get_fresh(); - let fresh_var = Expr::Var(*ann, fresh_symbol); + let fresh_var = Expr::Var(*span, fresh_symbol); let expr = std::mem::replace(expr, fresh_var.clone()); - new_head_atoms.push(Fact::Eq(*ann, vec![fresh_var, expr])); + new_head_atoms.push(Fact::Eq(*span, vec![fresh_var, expr])); }; } - Action::Let(ann, symbol, expr) if var_set.contains(symbol) => { + Action::Let(span, symbol, expr) if var_set.contains(symbol) => { var_set.extend(expr.vars()); if let Expr::Call(..) = expr { add_new_rule = true; - let var = Expr::Var(*ann, *symbol); - new_head_atoms.push(Fact::Eq(*ann, vec![var, expr.clone()])); + let var = Expr::Var(*span, *symbol); + new_head_atoms.push(Fact::Eq(*span, vec![var, expr.clone()])); } } _ => (), @@ -152,16 +152,16 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { } fn desugar_simplify(desugar: &mut Desugar, expr: &Expr, schedule: &Schedule) -> Vec { - let ann = expr.ann(); + let span = expr.span(); let mut res = vec![NCommand::Push(1)]; let lhs = desugar.get_fresh(); - res.push(NCommand::CoreAction(Action::Let(ann, lhs, expr.clone()))); + res.push(NCommand::CoreAction(Action::Let(span, lhs, expr.clone()))); res.push(NCommand::RunSchedule(schedule.clone())); res.extend( desugar_command( Command::QueryExtract { variants: 0, - expr: Expr::Var(ann, lhs), + expr: Expr::Var(span, lhs), }, desugar, false, @@ -186,7 +186,7 @@ pub(crate) fn desugar_calc( // first, push all the idents for IdentSort { ident, sort } in idents { res.push(Command::Declare { - ann: span, + span: span, name: ident, sort, }); @@ -200,10 +200,10 @@ pub(crate) fn desugar_calc( // add the two exprs only when they are calls (consts and vars don't need to be populated). if let Expr::Call(..) = expr1 { - res.push(Command::Action(Action::Expr(expr1.ann(), expr1.clone()))); + res.push(Command::Action(Action::Expr(expr1.span(), expr1.clone()))); } if let Expr::Call(..) = expr2 { - res.push(Command::Action(Action::Expr(expr2.ann(), expr2.clone()))); + res.push(Command::Action(Action::Expr(expr2.span(), expr2.clone()))); } res.push(Command::RunSchedule(Schedule::Saturate( @@ -250,7 +250,7 @@ pub(crate) fn desugar_command( constructor, inputs, } => desugar.desugar_function(&FunctionDecl::relation(constructor, inputs)), - Command::Declare { ann, name, sort } => desugar.declare(ann, name, sort), + Command::Declare { span, name, sort } => desugar.declare(span, name, sort), Command::Datatype { name, variants } => desugar_datatype(name, variants), Command::Rewrite(ruleset, rewrite, subsume) => { desugar_rewrite(ruleset, rewrite_name(&rewrite).into(), &rewrite, subsume) diff --git a/src/ast/expr.rs b/src/ast/expr.rs index c34c657e..a07b9886 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -105,21 +105,21 @@ impl ToSexp for ResolvedVar { } } -pub type Expr = GenericExpr; +pub type Expr = GenericExpr; /// A generated expression is an expression that is generated by the system /// and does not have annotations. -pub(crate) type ResolvedExpr = GenericExpr; +pub(crate) type ResolvedExpr = GenericExpr; /// A [`MappedExpr`] arises naturally when you want a mapping between an expression /// and its flattened form. It records this mapping by annotating each `Head` /// with a `Leaf`, which it maps to in the flattened form. /// A useful operation on `MappedExpr`s is [`MappedExpr::get_corresponding_var_or_lit``]. -pub(crate) type MappedExpr = GenericExpr, Leaf, Ann>; +pub(crate) type MappedExpr = GenericExpr, Leaf>; -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] -pub enum GenericExpr { - Lit(Ann, Literal), - Var(Ann, Leaf), - Call(Ann, Head, Vec), +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub enum GenericExpr { + Lit(Span, Literal), + Var(Span, Leaf), + Call(Span, Head, Vec), } impl ResolvedExpr { @@ -153,14 +153,14 @@ impl Expr { } } -impl - GenericExpr +impl + GenericExpr { - pub fn ann(&self) -> Ann { + pub fn span(&self) -> Span { match self { - GenericExpr::Lit(ann, _) => ann.clone(), - GenericExpr::Var(ann, _) => ann.clone(), - GenericExpr::Call(ann, _, _) => ann.clone(), + GenericExpr::Lit(span, _) => span.clone(), + GenericExpr::Var(span, _) => span.clone(), + GenericExpr::Call(span, _, _) => span.clone(), } } @@ -207,9 +207,9 @@ impl match self { GenericExpr::Lit(..) => f(self), GenericExpr::Var(..) => f(self), - GenericExpr::Call(ann, op, children) => { + GenericExpr::Call(span, op, children) => { let children = children.into_iter().map(|c| c.visit_exprs(f)).collect(); - f(GenericExpr::Call(ann.clone(), op.clone(), children)) + f(GenericExpr::Call(span.clone(), op.clone(), children)) } } } @@ -217,26 +217,26 @@ impl /// `subst` replaces occurrences of variables and head symbols in the expression. pub fn subst( &self, - subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, + subst_leaf: &mut impl FnMut(&Span, &Leaf) -> GenericExpr, subst_head: &mut impl FnMut(&Head) -> Head2, - ) -> GenericExpr { + ) -> GenericExpr { match self { - GenericExpr::Lit(ann, lit) => GenericExpr::Lit(ann.clone(), lit.clone()), - GenericExpr::Var(ann, v) => subst_leaf(ann, v), - GenericExpr::Call(ann, op, children) => { + GenericExpr::Lit(span, lit) => GenericExpr::Lit(span.clone(), lit.clone()), + GenericExpr::Var(span, v) => subst_leaf(span, v), + GenericExpr::Call(span, op, children) => { let children = children .iter() .map(|c| c.subst(subst_leaf, subst_head)) .collect(); - GenericExpr::Call(ann.clone(), subst_head(op), children) + GenericExpr::Call(span.clone(), subst_head(op), children) } } } pub fn subst_leaf( &self, - subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, - ) -> GenericExpr { + subst_leaf: &mut impl FnMut(&Span, &Leaf) -> GenericExpr, + ) -> GenericExpr { self.subst(subst_leaf, &mut |x| x.clone()) } @@ -250,7 +250,7 @@ impl } } -impl GenericExpr { +impl GenericExpr { /// Converts this expression into a /// s-expression (symbolic expression). /// Example: `(Add (Add 2 3) 4)` @@ -269,7 +269,7 @@ impl GenericExpr { } } -impl Display for GenericExpr +impl Display for GenericExpr where Head: Display, Leaf: Display, diff --git a/src/ast/mod.rs b/src/ast/mod.rs index e9692eb4..c8cc7a24 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -65,25 +65,11 @@ lazy_static! { impl Copy for Span {} -pub trait Annotation: Clone + PartialEq + Eq + Hash + Debug { - fn dummy() -> Self; -} - -impl Annotation for Span { - fn dummy() -> Self { - *DUMMY_SPAN - } -} - -impl Annotation for () { - fn dummy() -> Self {} -} - -pub type NCommand = GenericNCommand; +pub type NCommand = GenericNCommand; /// [`ResolvedNCommand`] is another specialization of [`GenericNCommand`], which /// adds the type information to heads and leaves of commands. /// [`TypeInfo::typecheck_command`] turns an [`NCommand`] into a [`ResolvedNCommand`]. -pub(crate) type ResolvedNCommand = GenericNCommand; +pub(crate) type ResolvedNCommand = GenericNCommand; /// A [`NCommand`] is a desugared [`Command`], where syntactic sugars /// like [`Command::Datatype`], [`Command::Declare`], and [`Command::Rewrite`] @@ -97,55 +83,55 @@ pub(crate) type ResolvedNCommand = GenericNCommand +pub enum GenericNCommand where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { SetOption { name: Symbol, - value: GenericExpr, + value: GenericExpr, }, Sort( Symbol, - Option<(Symbol, Vec>)>, + Option<(Symbol, Vec>)>, ), - Function(GenericFunctionDecl), + Function(GenericFunctionDecl), AddRuleset(Symbol), UnstableCombinedRuleset(Symbol, Vec), NormRule { name: Symbol, ruleset: Symbol, - rule: GenericRule, + rule: GenericRule, }, - CoreAction(GenericAction), - RunSchedule(GenericSchedule), + CoreAction(GenericAction), + RunSchedule(GenericSchedule), PrintOverallStatistics, - Check(Ann, Vec>), + Check(Span, Vec>), CheckProof, PrintTable(Symbol, usize), PrintSize(Option), Output { file: String, - exprs: Vec>, + exprs: Vec>, }, Push(usize), Pop(usize), - Fail(Box>), + Fail(Box>), Input { name: Symbol, file: String, }, } -impl GenericNCommand +impl GenericNCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Annotation, + { - pub fn to_command(&self) -> GenericCommand { + pub fn to_command(&self) -> GenericCommand { match self { GenericNCommand::SetOption { name, value } => GenericCommand::SetOption { name: *name, @@ -169,7 +155,7 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(ann, facts) => GenericCommand::Check(ann.clone(), facts.clone()), + GenericNCommand::Check(span, facts) => GenericCommand::Check(span.clone(), facts.clone()), GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -189,7 +175,7 @@ where pub fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { match self { GenericNCommand::SetOption { name, value } => GenericNCommand::SetOption { @@ -218,8 +204,8 @@ where GenericNCommand::CoreAction(action) => { GenericNCommand::CoreAction(action.visit_exprs(f)) } - GenericNCommand::Check(ann, facts) => GenericNCommand::Check( - ann, + GenericNCommand::Check(span, facts) => GenericNCommand::Check( + span, facts.into_iter().map(|fact| fact.visit_exprs(f)).collect(), ), GenericNCommand::CheckProof => GenericNCommand::CheckProof, @@ -237,15 +223,15 @@ where } } -pub type Schedule = GenericSchedule; -pub(crate) type ResolvedSchedule = GenericSchedule; +pub type Schedule = GenericSchedule; +pub(crate) type ResolvedSchedule = GenericSchedule; #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum GenericSchedule { - Saturate(Ann, Box>), - Repeat(Ann, usize, Box>), - Run(Ann, GenericRunConfig), - Sequence(Ann, Vec>), +pub enum GenericSchedule { + Saturate(Span, Box>), + Repeat(Span, usize, Box>), + Run(Span, GenericRunConfig), + Sequence(Span, Vec>), } pub trait ToSexp { @@ -288,33 +274,33 @@ macro_rules! list { }}; } -impl GenericSchedule +impl GenericSchedule where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericSchedule::Saturate(ann, sched) => { - GenericSchedule::Saturate(ann, Box::new(sched.visit_exprs(f))) + GenericSchedule::Saturate(span, sched) => { + GenericSchedule::Saturate(span, Box::new(sched.visit_exprs(f))) } - GenericSchedule::Repeat(ann, size, sched) => { - GenericSchedule::Repeat(ann, size, Box::new(sched.visit_exprs(f))) + GenericSchedule::Repeat(span, size, sched) => { + GenericSchedule::Repeat(span, size, Box::new(sched.visit_exprs(f))) } - GenericSchedule::Run(ann, config) => GenericSchedule::Run(ann, config.visit_exprs(f)), - GenericSchedule::Sequence(ann, scheds) => GenericSchedule::Sequence( - ann, + GenericSchedule::Run(span, config) => GenericSchedule::Run(span, config.visit_exprs(f)), + GenericSchedule::Sequence(span, scheds) => GenericSchedule::Sequence( + span, scheds.into_iter().map(|s| s.visit_exprs(f)).collect(), ), } } } -impl ToSexp for GenericSchedule { +impl ToSexp for GenericSchedule { fn to_sexp(&self) -> Sexp { match self { GenericSchedule::Saturate(_ann, sched) => list!("saturate", sched), @@ -325,13 +311,13 @@ impl ToSexp for GenericSchedule Display for GenericSchedule { +impl Display for GenericSchedule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_sexp()) } } -pub type Command = GenericCommand; +pub type Command = GenericCommand; pub type Subsume = bool; @@ -339,11 +325,11 @@ pub type Subsume = bool; /// It includes defining rules, declaring functions, /// adding to tables, and running rules (via a [`Schedule`]). #[derive(Debug, Clone)] -pub enum GenericCommand +pub enum GenericCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Annotation, + { /// Egglog supports several *experimental* options /// that can be set using the `set-option` command. @@ -356,7 +342,7 @@ where /// tool to know when each command has finished running. SetOption { name: Symbol, - value: GenericExpr, + value: GenericExpr, }, /// Declare a user-defined datatype. /// Datatypes can be unioned with [`Action::Union`] either @@ -404,7 +390,7 @@ where /// Note that declare inserts the constant into the database, /// so rules can use the constant directly as a variable. Declare { - ann: Ann, + span: Span, name: Symbol, sort: Symbol, }, @@ -425,7 +411,7 @@ where /// Now `MathVec` can be used as an input or output sort. Sort( Symbol, - Option<(Symbol, Vec>)>, + Option<(Symbol, Vec>)>, ), /// Declare an egglog function, which is a database table with a /// a functional dependency (also called a primary key) on its inputs to one output. @@ -472,7 +458,7 @@ where /// /// Functions that are not a datatype can be `set` /// with [`Action::Set`]. - Function(GenericFunctionDecl), + Function(GenericFunctionDecl), /// The `relation` is syntactic sugar for a named function which returns the `Unit` type. /// Example: /// ```text @@ -546,7 +532,7 @@ where Rule { name: Symbol, ruleset: Symbol, - rule: GenericRule, + rule: GenericRule, }, /// `rewrite` is syntactic sugar for a specific form of `rule` /// which simply unions the left and right hand sides. @@ -587,7 +573,7 @@ where /// ((union lhs (bitshift-left a 1)) /// (subsume (Mul a 2)))) /// ``` - Rewrite(Symbol, GenericRewrite, Subsume), + Rewrite(Symbol, GenericRewrite, Subsume), /// Similar to [`Command::Rewrite`], but /// generates two rules, one for each direction. /// @@ -604,14 +590,14 @@ where /// (rule ((= lhs (Var x))) /// ((union lhs (Mul (Var x) (Num 0))))) /// ``` - BiRewrite(Symbol, GenericRewrite), + BiRewrite(Symbol, GenericRewrite), /// Perform an [`Action`] on the global database /// (see documentation for [`Action`] for more details). /// Example: /// ```text /// (let xplusone (Add (Var "x") (Num 1))) /// ``` - Action(GenericAction), + Action(GenericAction), /// Runs a [`Schedule`], which specifies /// rulesets and the number of times to run them. /// @@ -626,17 +612,17 @@ where /// then runs `my-ruleset-2` four times. /// /// See [`Schedule`] for more details. - RunSchedule(GenericSchedule), + RunSchedule(GenericSchedule), /// Print runtime statistics about rules /// and rulesets so far. PrintOverallStatistics, // TODO provide simplify docs Simplify { - expr: GenericExpr, - schedule: GenericSchedule, + expr: GenericExpr, + schedule: GenericSchedule, }, // TODO provide calc docs - Calc(Ann, Vec, Vec>), + Calc(Span, Vec, Vec>), /// The `query-extract` command runs a query, /// extracting the result for each match that it finds. /// For a simpler extraction command, use [`Action::Extract`] instead. @@ -664,7 +650,7 @@ where /// function. QueryExtract { variants: usize, - expr: GenericExpr, + expr: GenericExpr, }, /// The `check` command checks that the given facts /// match at least once in the current database. @@ -686,7 +672,7 @@ where /// [ERROR] Check failed /// [INFO ] Command failed as expected. /// ``` - Check(Ann, Vec>), + Check(Span, Vec>), /// Currently unused, this command will check proofs when they are implemented. CheckProof, /// Print out rows a given function, extracting each of the elements of the function. @@ -707,7 +693,7 @@ where /// Extract and output a set of expressions to a file. Output { file: String, - exprs: Vec>, + exprs: Vec>, }, /// `push` the current egraph `n` times so that it is saved. /// Later, the current database and rules can be restored using `pop`. @@ -716,16 +702,16 @@ where /// The argument specifies how many egraphs to pop. Pop(usize), /// Assert that a command fails with an error. - Fail(Box>), + Fail(Box>), /// Include another egglog file directly as text and run it. Include(String), } -impl ToSexp for GenericCommand +impl ToSexp for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Annotation, + { fn to_sexp(&self) -> Sexp { match self { @@ -735,7 +721,7 @@ where } GenericCommand::BiRewrite(name, rewrite) => rewrite.to_sexp(*name, true, false), GenericCommand::Datatype { name, variants } => list!("datatype", name, ++ variants), - GenericCommand::Declare { ann: _, name, sort } => list!("declare", name, sort), + GenericCommand::Declare { span: _, name, sort } => list!("declare", name, sort), GenericCommand::Action(a) => a.to_sexp(), GenericCommand::Sort(name, None) => list!("sort", name), GenericCommand::Sort(name, Some((name2, args))) => { @@ -778,22 +764,22 @@ where } } -impl Display for GenericNCommand +impl Display for GenericNCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Annotation, + { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_command()) } } -impl Display for GenericCommand +impl Display for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - Ann: Annotation, + { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { @@ -828,24 +814,24 @@ impl Display for IdentSort { } } -pub type RunConfig = GenericRunConfig; -pub(crate) type ResolvedRunConfig = GenericRunConfig; +pub type RunConfig = GenericRunConfig; +pub(crate) type ResolvedRunConfig = GenericRunConfig; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericRunConfig { +pub struct GenericRunConfig { pub ruleset: Symbol, - pub until: Option>>, + pub until: Option>>, } -impl GenericRunConfig +impl GenericRunConfig where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { Self { ruleset: self.ruleset, @@ -856,7 +842,7 @@ where } } -impl ToSexp for GenericRunConfig +impl ToSexp for GenericRunConfig where Head: Display, Leaf: Display, @@ -875,23 +861,23 @@ where } } -pub type FunctionDecl = GenericFunctionDecl; -pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl; +pub type FunctionDecl = GenericFunctionDecl; +pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl; /// Represents the declaration of a function /// directly parsed from source syntax. #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericFunctionDecl +pub struct GenericFunctionDecl where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub name: Symbol, pub schema: Schema, - pub default: Option>, - pub merge: Option>, - pub merge_action: GenericActions, + pub default: Option>, + pub merge: Option>, + pub merge_action: GenericActions, pub cost: Option, pub unextractable: bool, /// Globals are desugared to functions, with this flag set to true. @@ -956,16 +942,16 @@ impl FunctionDecl { } } -impl GenericFunctionDecl +impl GenericFunctionDecl where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, - ) -> GenericFunctionDecl { + f: &mut impl FnMut(GenericExpr) -> GenericExpr, + ) -> GenericFunctionDecl { GenericFunctionDecl { name: self.name, schema: self.schema, @@ -979,9 +965,9 @@ where } } -impl ToSexp for GenericFunctionDecl +impl ToSexp for GenericFunctionDecl where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1029,9 +1015,9 @@ where } } -pub type Fact = GenericFact; -pub(crate) type ResolvedFact = GenericFact; -pub(crate) type MappedFact = GenericFact, Leaf, Ann>; +pub type Fact = GenericFact; +pub(crate) type ResolvedFact = GenericFact; +pub(crate) type MappedFact = GenericFact, Leaf>; /// Facts are the left-hand side of a [`Command::Rule`]. /// They represent a part of a database query. @@ -1044,17 +1030,17 @@ pub(crate) type MappedFact = GenericFact { +pub enum GenericFact { /// Must be at least two things in an eq fact - Eq(Ann, Vec>), - Fact(GenericExpr), + Eq(Span, Vec>), + Fact(GenericExpr), } -pub struct Facts(pub Vec>); +pub struct Facts(pub Vec>); -impl Facts +impl Facts where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1070,8 +1056,8 @@ where typeinfo: &TypeInfo, fresh_gen: &mut impl FreshGen, ) -> ( - Query, Leaf, Ann>, - Vec>, + Query, Leaf>, + Vec>, ) where Leaf: SymbolLike, @@ -1081,7 +1067,7 @@ where for fact in self.0.iter() { match fact { - GenericFact::Eq(ann, exprs) => { + GenericFact::Eq(span, exprs) => { let mut new_exprs = vec![]; let mut to_equate = vec![]; for expr in exprs { @@ -1091,11 +1077,11 @@ where new_exprs.push(expr); } atoms.push(GenericAtom { - ann: ann.clone(), + span: span.clone(), head: HeadOrEq::Eq, args: to_equate, }); - new_body.push(GenericFact::Eq(ann.clone(), new_exprs)); + new_body.push(GenericFact::Eq(span.clone(), new_exprs)); } GenericFact::Fact(expr) => { let (child_atoms, expr) = expr.to_query(typeinfo, fresh_gen); @@ -1108,7 +1094,7 @@ where } } -impl ToSexp for GenericFact +impl ToSexp for GenericFact where Head: Display, Leaf: Display, @@ -1121,19 +1107,19 @@ where } } -impl GenericFact +impl GenericFact where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub(crate) fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, - ) -> GenericFact { + f: &mut impl FnMut(GenericExpr) -> GenericExpr, + ) -> GenericFact { match self { - GenericFact::Eq(ann, exprs) => GenericFact::Eq( - ann.clone(), + GenericFact::Eq(span, exprs) => GenericFact::Eq( + span.clone(), exprs.into_iter().map(|expr| expr.visit_exprs(f)).collect(), ), GenericFact::Fact(expr) => GenericFact::Fact(expr.visit_exprs(f)), @@ -1142,11 +1128,11 @@ where pub(crate) fn map_exprs( &self, - f: &mut impl FnMut(&GenericExpr) -> GenericExpr, - ) -> GenericFact { + f: &mut impl FnMut(&GenericExpr) -> GenericExpr, + ) -> GenericFact { match self { - GenericFact::Eq(ann, exprs) => { - GenericFact::Eq(ann.clone(), exprs.iter().map(f).collect()) + GenericFact::Eq(span, exprs) => { + GenericFact::Eq(span.clone(), exprs.iter().map(f).collect()) } GenericFact::Fact(expr) => GenericFact::Fact(f(expr)), } @@ -1154,32 +1140,32 @@ where pub(crate) fn subst( &self, - subst_leaf: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, + subst_leaf: &mut impl FnMut(&Span, &Leaf) -> GenericExpr, subst_head: &mut impl FnMut(&Head) -> Head2, - ) -> GenericFact { + ) -> GenericFact { self.map_exprs(&mut |e| e.subst(subst_leaf, subst_head)) } } -impl GenericFact +impl GenericFact where Leaf: Clone + PartialEq + Eq + Display + Hash, Head: Clone + Display, - Ann: Annotation, + { - pub(crate) fn make_unresolved(self) -> GenericFact + pub(crate) fn make_unresolved(self) -> GenericFact where Leaf: SymbolLike, Head: SymbolLike, { self.subst( - &mut |ann, v| GenericExpr::Var(ann.clone(), v.to_symbol()), + &mut |span, v| GenericExpr::Var(span.clone(), v.to_symbol()), &mut |h| h.to_symbol(), ) } } -impl Display for GenericFact +impl Display for GenericFact where Head: Display, Leaf: Display, @@ -1230,32 +1216,32 @@ pub enum Change { Subsume, } -pub type Action = GenericAction; -pub(crate) type MappedAction = GenericAction, Symbol, Span>; -pub(crate) type ResolvedAction = GenericAction; +pub type Action = GenericAction; +pub(crate) type MappedAction = GenericAction, Symbol>; +pub(crate) type ResolvedAction = GenericAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum GenericAction +pub enum GenericAction where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { /// Bind a variable to a particular datatype or primitive. /// At the top level (in a [`Command::Action`]), this defines a global variable. /// In a [`Command::Rule`], this defines a local variable in the actions. - Let(Ann, Leaf, GenericExpr), + Let(Span, Leaf, GenericExpr), /// `set` a function to a particular result. /// `set` should not be used on datatypes- /// instead, use `union`. Set( - Ann, + Span, Head, - Vec>, - GenericExpr, + Vec>, + GenericExpr, ), /// Delete or subsume (mark as hidden from future rewrites and unextractable) an entry from a function. - Change(Ann, Change, Head, Vec>), + Change(Span, Change, Head, Vec>), /// `union` two datatypes, making them equal /// in the implicit, global equality relation /// of egglog. @@ -1269,9 +1255,9 @@ where /// (extract (Num 2)); Extracts Num 1 /// ``` Union( - Ann, - GenericExpr, - GenericExpr, + Span, + GenericExpr, + GenericExpr, ), /// `extract` a datatype from the egraph, choosing /// the smallest representative. @@ -1282,12 +1268,12 @@ where /// extract, picking different terms in the /// same equivalence class. Extract( - Ann, - GenericExpr, - GenericExpr, + Span, + GenericExpr, + GenericExpr, ), - Panic(Ann, String), - Expr(Ann, GenericExpr), + Panic(Span, String), + Expr(Span, GenericExpr), // If(Expr, Action, Action), } @@ -1296,16 +1282,16 @@ where pub struct GenericActions< Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Annotation, ->(pub Vec>); -pub type Actions = GenericActions; -pub(crate) type ResolvedActions = GenericActions; -pub(crate) type MappedActions = - GenericActions, Leaf, Ann>; - -impl Default for GenericActions + +>(pub Vec>); +pub type Actions = GenericActions; +pub(crate) type ResolvedActions = GenericActions; +pub(crate) type MappedActions = + GenericActions, Leaf>; + +impl Default for GenericActions where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1314,9 +1300,9 @@ where } } -impl GenericActions +impl GenericActions where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1324,7 +1310,7 @@ where self.0.len() } - pub(crate) fn iter(&self) -> impl Iterator> { + pub(crate) fn iter(&self) -> impl Iterator> { self.0.iter() } @@ -1334,15 +1320,15 @@ where pub(crate) fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { Self(self.0.into_iter().map(|a| a.visit_exprs(f)).collect()) } } -impl ToSexp for GenericAction +impl ToSexp for GenericAction where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1367,44 +1353,44 @@ where } } -impl GenericAction +impl GenericAction where Head: Clone + Display, Leaf: Clone + Eq + Display + Hash, - Ann: Annotation, + { // Applys `f` to all expressions in the action. pub fn map_exprs( &self, - f: &mut impl FnMut(&GenericExpr) -> GenericExpr, + f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericAction::Let(ann, lhs, rhs) => { - GenericAction::Let(ann.clone(), lhs.clone(), f(rhs)) + GenericAction::Let(span, lhs, rhs) => { + GenericAction::Let(span.clone(), lhs.clone(), f(rhs)) } - GenericAction::Set(ann, lhs, args, rhs) => { + GenericAction::Set(span, lhs, args, rhs) => { let right = f(rhs); GenericAction::Set( - ann.clone(), + span.clone(), lhs.clone(), args.iter().map(f).collect(), right, ) } - GenericAction::Change(ann, change, lhs, args) => GenericAction::Change( - ann.clone(), + GenericAction::Change(span, change, lhs, args) => GenericAction::Change( + span.clone(), *change, lhs.clone(), args.iter().map(f).collect(), ), - GenericAction::Union(ann, lhs, rhs) => { - GenericAction::Union(ann.clone(), f(lhs), f(rhs)) + GenericAction::Union(span, lhs, rhs) => { + GenericAction::Union(span.clone(), f(lhs), f(rhs)) } - GenericAction::Extract(ann, expr, variants) => { - GenericAction::Extract(ann.clone(), f(expr), f(variants)) + GenericAction::Extract(span, expr, variants) => { + GenericAction::Extract(span.clone(), f(expr), f(variants)) } - GenericAction::Panic(ann, msg) => GenericAction::Panic(ann.clone(), msg.clone()), - GenericAction::Expr(ann, e) => GenericAction::Expr(ann.clone(), f(e)), + GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), + GenericAction::Expr(span, e) => GenericAction::Expr(span.clone(), f(e)), } } @@ -1412,37 +1398,37 @@ where /// bottom-up, collecting the results. pub fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericAction::Let(ann, lhs, rhs) => { - GenericAction::Let(ann.clone(), lhs.clone(), rhs.visit_exprs(f)) + GenericAction::Let(span, lhs, rhs) => { + GenericAction::Let(span.clone(), lhs.clone(), rhs.visit_exprs(f)) } // TODO should we refactor `Set` so that we can map over Expr::Call(lhs, args)? // This seems more natural to oflatt // Currently, visit_exprs does not apply f to the first argument of Set. - GenericAction::Set(ann, lhs, args, rhs) => { + GenericAction::Set(span, lhs, args, rhs) => { let args = args.into_iter().map(|e| e.visit_exprs(f)).collect(); - GenericAction::Set(ann.clone(), lhs.clone(), args, rhs.visit_exprs(f)) + GenericAction::Set(span.clone(), lhs.clone(), args, rhs.visit_exprs(f)) } - GenericAction::Change(ann, change, lhs, args) => { + GenericAction::Change(span, change, lhs, args) => { let args = args.into_iter().map(|e| e.visit_exprs(f)).collect(); - GenericAction::Change(ann.clone(), change, lhs.clone(), args) + GenericAction::Change(span.clone(), change, lhs.clone(), args) } - GenericAction::Union(ann, lhs, rhs) => { - GenericAction::Union(ann.clone(), lhs.visit_exprs(f), rhs.visit_exprs(f)) + GenericAction::Union(span, lhs, rhs) => { + GenericAction::Union(span.clone(), lhs.visit_exprs(f), rhs.visit_exprs(f)) } - GenericAction::Extract(ann, expr, variants) => { - GenericAction::Extract(ann.clone(), expr.visit_exprs(f), variants.visit_exprs(f)) + GenericAction::Extract(span, expr, variants) => { + GenericAction::Extract(span.clone(), expr.visit_exprs(f), variants.visit_exprs(f)) } - GenericAction::Panic(ann, msg) => GenericAction::Panic(ann.clone(), msg.clone()), - GenericAction::Expr(ann, e) => GenericAction::Expr(ann.clone(), e.visit_exprs(f)), + GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), + GenericAction::Expr(span, e) => GenericAction::Expr(span.clone(), e.visit_exprs(f)), } } pub fn subst( &self, - subst: &mut impl FnMut(&Ann, &Leaf) -> GenericExpr, + subst: &mut impl FnMut(&Span, &Leaf) -> GenericExpr, ) -> Self { self.map_exprs(&mut |e| e.subst_leaf(subst)) } @@ -1450,51 +1436,51 @@ where pub fn map_def_use(self, fvar: &mut impl FnMut(Leaf, bool) -> Leaf) -> Self { macro_rules! fvar_expr { () => { - |ann, s: _| GenericExpr::Var(ann.clone(), fvar(s.clone(), false)) + |span, s: _| GenericExpr::Var(span.clone(), fvar(s.clone(), false)) }; } match self { - GenericAction::Let(ann, lhs, rhs) => { + GenericAction::Let(span, lhs, rhs) => { let lhs = fvar(lhs, true); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Let(ann.clone(), lhs, rhs) + GenericAction::Let(span.clone(), lhs, rhs) } - GenericAction::Set(ann, lhs, args, rhs) => { + GenericAction::Set(span, lhs, args, rhs) => { let args = args .into_iter() .map(|e| e.subst_leaf(&mut fvar_expr!())) .collect(); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Set(ann.clone(), lhs.clone(), args, rhs) + GenericAction::Set(span.clone(), lhs.clone(), args, rhs) } - GenericAction::Change(ann, change, lhs, args) => { + GenericAction::Change(span, change, lhs, args) => { let args = args .into_iter() .map(|e| e.subst_leaf(&mut fvar_expr!())) .collect(); - GenericAction::Change(ann.clone(), change, lhs.clone(), args) + GenericAction::Change(span.clone(), change, lhs.clone(), args) } - GenericAction::Union(ann, lhs, rhs) => { + GenericAction::Union(span, lhs, rhs) => { let lhs = lhs.subst_leaf(&mut fvar_expr!()); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Union(ann.clone(), lhs, rhs) + GenericAction::Union(span.clone(), lhs, rhs) } - GenericAction::Extract(ann, expr, variants) => { + GenericAction::Extract(span, expr, variants) => { let expr = expr.subst_leaf(&mut fvar_expr!()); let variants = variants.subst_leaf(&mut fvar_expr!()); - GenericAction::Extract(ann.clone(), expr, variants) + GenericAction::Extract(span.clone(), expr, variants) } - GenericAction::Panic(ann, msg) => GenericAction::Panic(ann.clone(), msg.clone()), - GenericAction::Expr(ann, e) => { - GenericAction::Expr(ann.clone(), e.subst_leaf(&mut fvar_expr!())) + GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), + GenericAction::Expr(span, e) => { + GenericAction::Expr(span.clone(), e.subst_leaf(&mut fvar_expr!())) } } } } -impl Display for GenericAction +impl Display for GenericAction where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1509,33 +1495,33 @@ pub(crate) struct CompiledRule { pub(crate) program: Program, } -pub type Rule = GenericRule; -pub(crate) type ResolvedRule = GenericRule; +pub type Rule = GenericRule; +pub(crate) type ResolvedRule = GenericRule; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericRule +pub struct GenericRule where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { - pub ann: Ann, - pub head: GenericActions, - pub body: Vec>, + pub span: Span, + pub head: GenericActions, + pub body: Vec>, } -impl GenericRule +impl GenericRule where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub(crate) fn visit_exprs( self, - f: &mut impl FnMut(GenericExpr) -> GenericExpr, + f: &mut impl FnMut(GenericExpr) -> GenericExpr, ) -> Self { Self { - ann: self.ann, + span: self.span, head: self.head.visit_exprs(f), body: self .body @@ -1546,9 +1532,9 @@ where } } -impl GenericRule +impl GenericRule where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1596,9 +1582,9 @@ where } } -impl GenericRule +impl GenericRule where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1621,9 +1607,9 @@ where } } -impl Display for GenericRule +impl Display for GenericRule where - Ann: Annotation, + Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1632,17 +1618,17 @@ where } } -type Rewrite = GenericRewrite; +type Rewrite = GenericRewrite; #[derive(Clone, Debug)] -pub struct GenericRewrite { - pub ann: Ann, - pub lhs: GenericExpr, - pub rhs: GenericExpr, - pub conditions: Vec>, +pub struct GenericRewrite { + pub span: Span, + pub lhs: GenericExpr, + pub rhs: GenericExpr, + pub conditions: Vec>, } -impl GenericRewrite { +impl GenericRewrite { /// Converts the rewrite into an s-expression. pub fn to_sexp(&self, ruleset: Symbol, is_bidirectional: bool, subsume: bool) -> Sexp { let mut res = vec![ @@ -1673,22 +1659,22 @@ impl GenericRewrite { } } -impl Display for GenericRewrite { +impl Display for GenericRewrite { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_sexp("".into(), false, false)) } } -impl MappedExpr +impl MappedExpr where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { pub(crate) fn get_corresponding_var_or_lit( &self, typeinfo: &TypeInfo, - ) -> GenericAtomTerm + ) -> GenericAtomTerm where Leaf: SymbolLike, { @@ -1696,29 +1682,29 @@ where // This is error-prone and the complexities can be avoided by treating globals // as nullary functions. match self { - GenericExpr::Var(ann, v) => { + GenericExpr::Var(span, v) => { if typeinfo.is_global(v.to_symbol()) { - GenericAtomTerm::Global(ann.clone(), v.clone()) + GenericAtomTerm::Global(span.clone(), v.clone()) } else { - GenericAtomTerm::Var(ann.clone(), v.clone()) + GenericAtomTerm::Var(span.clone(), v.clone()) } } - GenericExpr::Lit(ann, lit) => GenericAtomTerm::Literal(ann.clone(), lit.clone()), - GenericExpr::Call(ann, head, _) => GenericAtomTerm::Var(ann.clone(), head.to.clone()), + GenericExpr::Lit(span, lit) => GenericAtomTerm::Literal(span.clone(), lit.clone()), + GenericExpr::Call(span, head, _) => GenericAtomTerm::Var(span.clone(), head.to.clone()), } } } -impl GenericActions +impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { - pub fn new(actions: Vec>) -> Self { + pub fn new(actions: Vec>) -> Self { Self(actions) } - pub fn singleton(action: GenericAction) -> Self { + pub fn singleton(action: GenericAction) -> Self { Self(vec![action]) } } diff --git a/src/ast/parse.lalrpop b/src/ast/parse.lalrpop index a1d1a475..097c1f99 100644 --- a/src/ast/parse.lalrpop +++ b/src/ast/parse.lalrpop @@ -55,23 +55,23 @@ Command: Command = { )?> )?> RParen => { Command::Function(FunctionDecl { name, schema, merge, merge_action: Actions::new(merge_action.unwrap_or_default()), default, cost, unextractable: unextractable.is_some(), ignore_viz: false }) }, - "declare" => Command::Declare{ann: Span(filename, lo, hi), name, sort}, + "declare" => Command::Declare{span: Span(filename, lo, hi), name, sort}, LParen "relation" > RParen => Command::Relation{constructor, inputs}, LParen "ruleset" RParen => Command::AddRuleset(name), LParen "unstable-combined-ruleset" RParen => Command::UnstableCombinedRuleset(name, subrulesets), "rule" > > )?> )?> - => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { ann: Span(filename, lo, hi), head: Actions::new(head), body }}, + => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { span: Span(filename, lo, hi), head: Actions::new(head), body }}, "rewrite" >)?> )?> - => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { ann: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), + => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), "birewrite" >)?> )?> - => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { ann: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }), + => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }), "let" => Command::Action(Action::Let(Span(filename, lo, hi), name, expr)), => Command::Action(<>), "run" )?> => diff --git a/src/ast/remove_globals.rs b/src/ast/remove_globals.rs index b2ae49da..a9aade12 100644 --- a/src/ast/remove_globals.rs +++ b/src/ast/remove_globals.rs @@ -76,7 +76,7 @@ fn resolved_var_to_call(var: &ResolvedVar) -> ResolvedCall { fn replace_global_vars(expr: ResolvedExpr) -> ResolvedExpr { match expr.get_global_var() { Some(resolved_var) => { - GenericExpr::Call(expr.ann(), resolved_var_to_call(&resolved_var), vec![]) + GenericExpr::Call(expr.span(), resolved_var_to_call(&resolved_var), vec![]) } None => expr, } @@ -98,7 +98,7 @@ impl<'a> GlobalRemover<'a> { ) -> Vec { match cmd { GenericNCommand::CoreAction(action) => match action { - GenericAction::Let(ann, name, expr) => { + GenericAction::Let(span, name, expr) => { let ty = expr.output_type(type_info); let func_decl = ResolvedFunctionDecl { @@ -126,13 +126,13 @@ impl<'a> GlobalRemover<'a> { // output is eq-able, so generate a union if ty.is_eq_sort() { GenericNCommand::CoreAction(GenericAction::Union( - ann, - GenericExpr::Call(ann, resolved_call, vec![]), + span, + GenericExpr::Call(span, resolved_call, vec![]), remove_globals_expr(expr), )) } else { GenericNCommand::CoreAction(GenericAction::Set( - ann, + span, resolved_call, vec![], remove_globals_expr(expr), @@ -156,7 +156,7 @@ impl<'a> GlobalRemover<'a> { globals.insert( resolved_var.clone(), GenericExpr::Var( - expr.ann(), + expr.span(), ResolvedVar { name: new_name, sort: resolved_var.sort.clone(), @@ -171,9 +171,9 @@ impl<'a> GlobalRemover<'a> { .iter() .map(|(old, new)| { GenericFact::Eq( - new.ann(), + new.span(), vec![ - GenericExpr::Call(new.ann(), resolved_var_to_call(old), vec![]), + GenericExpr::Call(new.span(), resolved_var_to_call(old), vec![]), new.clone(), ], ) @@ -181,7 +181,7 @@ impl<'a> GlobalRemover<'a> { .collect(); let new_rule = GenericRule { - ann: rule.ann, + span: rule.span, // instrument the old facts and add the new facts to the end body: rule .body diff --git a/src/constraint.rs b/src/constraint.rs index cbece6bd..cf38ab5a 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -217,7 +217,7 @@ where impl Assignment { pub(crate) fn annotate_expr( &self, - expr: &GenericExpr, Symbol, Span>, + expr: &GenericExpr, Symbol>, typeinfo: &TypeInfo, ) -> ResolvedExpr { match &expr { @@ -268,12 +268,12 @@ impl Assignment { pub(crate) fn annotate_fact( &self, - facts: &GenericFact, Symbol, Span>, + facts: &GenericFact, Symbol>, typeinfo: &TypeInfo, ) -> ResolvedFact { match facts { - GenericFact::Eq(ann, facts) => ResolvedFact::Eq( - *ann, + GenericFact::Eq(span, facts) => ResolvedFact::Eq( + *span, facts .iter() .map(|expr| self.annotate_expr(expr, typeinfo)) @@ -285,7 +285,7 @@ impl Assignment { pub(crate) fn annotate_facts( &self, - mapped_facts: &[GenericFact, Symbol, Span>], + mapped_facts: &[GenericFact, Symbol>], typeinfo: &TypeInfo, ) -> Vec { mapped_facts @@ -388,7 +388,7 @@ impl Assignment { pub(crate) fn annotate_actions( &self, - mapped_actions: &GenericActions, Symbol, Span>, + mapped_actions: &GenericActions, Symbol>, typeinfo: &TypeInfo, ) -> Result { let actions = mapped_actions @@ -454,11 +454,11 @@ impl Problem { // bound vars are added to range match action { - CoreAction::Let(ann, var, _, _) => { - self.range.insert(AtomTerm::Var(*ann, *var)); + CoreAction::Let(span, var, _, _) => { + self.range.insert(AtomTerm::Var(*span, *var)); } - CoreAction::LetAtomTerm(ann, v, _) => { - self.range.insert(AtomTerm::Var(*ann, *v)); + CoreAction::LetAtomTerm(span, v, _) => { + self.range.insert(AtomTerm::Var(*span, *v)); } _ => (), } @@ -471,7 +471,7 @@ impl Problem { rule: &CoreRule, typeinfo: &TypeInfo, ) -> Result<(), TypeError> { - let CoreRule { ann: _, head, body } = rule; + let CoreRule { span: _, head, body } = rule; self.add_query(body, typeinfo)?; self.add_actions(head, typeinfo)?; Ok(()) @@ -496,33 +496,33 @@ impl CoreAction { symbol_gen: &mut SymbolGen, ) -> Result>, TypeError> { match self { - CoreAction::Let(ann, symbol, f, args) => { + CoreAction::Let(span, symbol, f, args) => { let mut args = args.clone(); - args.push(AtomTerm::Var(*ann, *symbol)); + args.push(AtomTerm::Var(*span, *symbol)); Ok(get_literal_and_global_constraints(&args, typeinfo) - .chain(get_atom_application_constraints(f, &args, ann, typeinfo)?) + .chain(get_atom_application_constraints(f, &args, span, typeinfo)?) .collect()) } - CoreAction::Set(ann, head, args, rhs) => { + CoreAction::Set(span, head, args, rhs) => { let mut args = args.clone(); args.push(rhs.clone()); Ok(get_literal_and_global_constraints(&args, typeinfo) .chain(get_atom_application_constraints( - head, &args, ann, typeinfo, + head, &args, span, typeinfo, )?) .collect()) } - CoreAction::Change(ann, _change, head, args) => { + CoreAction::Change(span, _change, head, args) => { let mut args = args.clone(); // Add a dummy last output argument let var = symbol_gen.fresh(head); - args.push(AtomTerm::Var(*ann, var)); + args.push(AtomTerm::Var(*span, var)); Ok(get_literal_and_global_constraints(&args, typeinfo) .chain(get_atom_application_constraints( - head, &args, ann, typeinfo, + head, &args, span, typeinfo, )?) .collect()) } @@ -544,9 +544,9 @@ impl CoreAction { ) } CoreAction::Panic(_ann, _) => Ok(vec![]), - CoreAction::LetAtomTerm(ann, v, at) => { + CoreAction::LetAtomTerm(span, v, at) => { Ok(get_literal_and_global_constraints(&[at.clone()], typeinfo) - .chain(once(Constraint::Eq(AtomTerm::Var(*ann, *v), at.clone()))) + .chain(once(Constraint::Eq(AtomTerm::Var(*span, *v), at.clone()))) .collect()) } } @@ -572,7 +572,7 @@ impl Atom { } SymbolOrEq::Symbol(head) => Ok(literal_constraints .chain(get_atom_application_constraints( - head, &self.args, &self.ann, type_info, + head, &self.args, &self.span, type_info, )?) .collect()), } @@ -601,7 +601,7 @@ fn get_atom_application_constraints( constraints.push(Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - ann: *span, + span: *span, head: *head, args: args.to_vec(), }, @@ -692,7 +692,7 @@ impl TypeConstraint for SimpleTypeConstraint { vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - ann: self.span, + span: self.span, head: self.name, args: arguments.to_vec(), }, @@ -768,7 +768,7 @@ impl TypeConstraint for AllEqualTypeConstraint { return vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - ann: self.span, + span: self.span, head: self.name, args: arguments.to_vec(), }, diff --git a/src/core.rs b/src/core.rs index 5f3eeed5..f9ffd3f3 100644 --- a/src/core.rs +++ b/src/core.rs @@ -130,14 +130,14 @@ impl ToSexp for ResolvedCall { } #[derive(Debug, Clone)] -pub enum GenericAtomTerm { - Var(Ann, Leaf), - Literal(Ann, Literal), - Global(Ann, Leaf), +pub enum GenericAtomTerm { + Var(Span, Leaf), + Literal(Span, Literal), + Global(Span, Leaf), } // Ignores annotations for equality and hasing -impl PartialEq for GenericAtomTerm +impl PartialEq for GenericAtomTerm where Leaf: PartialEq, { @@ -151,9 +151,9 @@ where } } -impl Eq for GenericAtomTerm where Leaf: Eq {} +impl Eq for GenericAtomTerm where Leaf: Eq {} -impl Hash for GenericAtomTerm +impl Hash for GenericAtomTerm where Leaf: Hash, { @@ -166,25 +166,25 @@ where } } -pub type AtomTerm = GenericAtomTerm; -pub type ResolvedAtomTerm = GenericAtomTerm; +pub type AtomTerm = GenericAtomTerm; +pub type ResolvedAtomTerm = GenericAtomTerm; -impl GenericAtomTerm { - pub fn ann(&self) -> &Ann { +impl GenericAtomTerm { + pub fn span(&self) -> &Span { match self { - GenericAtomTerm::Var(ann, _) => ann, - GenericAtomTerm::Literal(ann, _) => ann, - GenericAtomTerm::Global(ann, _) => ann, + GenericAtomTerm::Var(span, _) => span, + GenericAtomTerm::Literal(span, _) => span, + GenericAtomTerm::Global(span, _) => span, } } } -impl GenericAtomTerm { - pub fn to_expr(&self) -> GenericExpr { +impl GenericAtomTerm { + pub fn to_expr(&self) -> GenericExpr { match self { - GenericAtomTerm::Var(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), - GenericAtomTerm::Literal(ann, l) => GenericExpr::Lit(ann.clone(), l.clone()), - GenericAtomTerm::Global(ann, v) => GenericExpr::Var(ann.clone(), v.clone()), + GenericAtomTerm::Var(span, v) => GenericExpr::Var(span.clone(), v.clone()), + GenericAtomTerm::Literal(span, l) => GenericExpr::Lit(span.clone(), l.clone()), + GenericAtomTerm::Global(span, v) => GenericExpr::Var(span.clone(), v.clone()), } } } @@ -210,13 +210,13 @@ impl std::fmt::Display for AtomTerm { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericAtom { - pub ann: Ann, +pub struct GenericAtom { + pub span: Span, pub head: Head, - pub args: Vec>, + pub args: Vec>, } -pub type Atom = GenericAtom; +pub type Atom = GenericAtom; impl std::fmt::Display for Atom { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -224,7 +224,7 @@ impl std::fmt::Display for Atom { } } -impl GenericAtom +impl GenericAtom where Leaf: Clone + Eq + Hash, Head: Clone, @@ -237,7 +237,7 @@ where }) } - fn subst(&mut self, subst: &HashMap>) { + fn subst(&mut self, subst: &HashMap>) { for arg in self.args.iter_mut() { match arg { GenericAtomTerm::Var(_, v) => { @@ -255,7 +255,7 @@ impl Atom { pub(crate) fn to_expr(&self) -> Expr { let n = self.args.len(); Expr::Call( - self.ann, + self.span, self.head, self.args[0..n - 1] .iter() @@ -266,8 +266,8 @@ impl Atom { } #[derive(Debug, Clone)] -pub struct Query { - pub atoms: Vec>, +pub struct Query { + pub atoms: Vec>, } impl Default for Query { @@ -298,11 +298,11 @@ impl Query { } } -impl Query +impl Query where Leaf: Eq + Clone + Hash, Head: Clone, - Ann: Annotation, + { pub(crate) fn get_vars(&self) -> IndexSet { self.atoms @@ -312,7 +312,7 @@ where } } -impl AddAssign for Query { +impl AddAssign for Query { fn add_assign(&mut self, rhs: Self) { self.atoms.extend(rhs.atoms); } @@ -348,22 +348,22 @@ impl std::fmt::Display for Query { } } -impl Query { - pub fn filters(&self) -> impl Iterator> + '_ { +impl Query { + pub fn filters(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(_) => None, ResolvedCall::Primitive(head) => Some(GenericAtom { - ann: atom.ann.clone(), + span: atom.span.clone(), head: head.primitive.clone(), args: atom.args.clone(), }), }) } - pub fn funcs(&self) -> impl Iterator> + '_ { + pub fn funcs(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(head) => Some(GenericAtom { - ann: atom.ann.clone(), + span: atom.span.clone(), head: head.name, args: atom.args.clone(), }), @@ -373,44 +373,44 @@ impl Query { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum GenericCoreAction { - Let(Ann, Leaf, Head, Vec>), - LetAtomTerm(Ann, Leaf, GenericAtomTerm), - Extract(Ann, GenericAtomTerm, GenericAtomTerm), +pub enum GenericCoreAction { + Let(Span, Leaf, Head, Vec>), + LetAtomTerm(Span, Leaf, GenericAtomTerm), + Extract(Span, GenericAtomTerm, GenericAtomTerm), Set( - Ann, + Span, Head, - Vec>, - GenericAtomTerm, + Vec>, + GenericAtomTerm, ), - Change(Ann, Change, Head, Vec>), - Union(Ann, GenericAtomTerm, GenericAtomTerm), - Panic(Ann, String), + Change(Span, Change, Head, Vec>), + Union(Span, GenericAtomTerm, GenericAtomTerm), + Panic(Span, String), } pub type CoreAction = GenericCoreAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericCoreActions( - pub(crate) Vec>, +pub struct GenericCoreActions( + pub(crate) Vec>, ); pub(crate) type ResolvedCoreActions = GenericCoreActions; -impl Default for GenericCoreActions { +impl Default for GenericCoreActions { fn default() -> Self { Self(vec![]) } } -impl GenericCoreActions +impl GenericCoreActions where Leaf: Clone, - Ann: Annotation, + { - pub(crate) fn subst(&mut self, subst: &HashMap>) { + pub(crate) fn subst(&mut self, subst: &HashMap>) { let actions = subst.iter().map(|(symbol, atom_term)| { GenericCoreAction::LetAtomTerm( - atom_term.ann().clone(), + atom_term.span().clone(), symbol.clone(), atom_term.clone(), ) @@ -420,18 +420,18 @@ where } fn new( - actions: Vec>, - ) -> GenericCoreActions { + actions: Vec>, + ) -> GenericCoreActions { Self(actions) } } #[allow(clippy::type_complexity)] -impl GenericActions +impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - Ann: Annotation, + { pub(crate) fn to_core_actions>( &self, @@ -440,8 +440,8 @@ where fresh_gen: &mut FG, ) -> Result< ( - GenericCoreActions, - MappedActions, + GenericCoreActions, + MappedActions, ), TypeError, > @@ -449,14 +449,14 @@ where Leaf: SymbolLike, { let mut norm_actions = vec![]; - let mut mapped_actions: MappedActions = GenericActions(vec![]); + let mut mapped_actions: MappedActions = GenericActions(vec![]); // During the lowering, there are two important guaratees: // Every used variable should be bound. // Every introduced variable should be unbound before. for action in self.0.iter() { match action { - GenericAction::Let(ann, var, expr) => { + GenericAction::Let(span, var, expr) => { if binding.contains(var) { return Err(TypeError::AlreadyDefined(var.to_symbol())); } @@ -464,18 +464,18 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::LetAtomTerm( - ann.clone(), + span.clone(), var.clone(), mapped_expr.get_corresponding_var_or_lit(typeinfo), )); mapped_actions.0.push(GenericAction::Let( - ann.clone(), + span.clone(), var.clone(), mapped_expr, )); binding.insert(var.clone()); } - GenericAction::Set(ann, head, args, expr) => { + GenericAction::Set(span, head, args, expr) => { let mut mapped_args = vec![]; for arg in args { let (actions, mapped_arg) = @@ -487,7 +487,7 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Set( - ann.clone(), + span.clone(), head.clone(), mapped_args .iter() @@ -497,13 +497,13 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Set( - ann.clone(), + span.clone(), CorrespondingVar::new(head.clone(), v), mapped_args, mapped_expr, )); } - GenericAction::Change(ann, change, head, args) => { + GenericAction::Change(span, change, head, args) => { let mut mapped_args = vec![]; for arg in args { let (actions, mapped_arg) = @@ -512,7 +512,7 @@ where mapped_args.push(mapped_arg); } norm_actions.push(GenericCoreAction::Change( - ann.clone(), + span.clone(), *change, head.clone(), mapped_args @@ -522,53 +522,53 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Change( - ann.clone(), + span.clone(), *change, CorrespondingVar::new(head.clone(), v), mapped_args, )); } - GenericAction::Union(ann, e1, e2) => { + GenericAction::Union(span, e1, e2) => { let (actions1, mapped_e1) = e1.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions1.0); let (actions2, mapped_e2) = e2.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions2.0); norm_actions.push(GenericCoreAction::Union( - ann.clone(), + span.clone(), mapped_e1.get_corresponding_var_or_lit(typeinfo), mapped_e2.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Union(ann.clone(), mapped_e1, mapped_e2)); + .push(GenericAction::Union(span.clone(), mapped_e1, mapped_e2)); } - GenericAction::Extract(ann, e, n) => { + GenericAction::Extract(span, e, n) => { let (actions, mapped_e) = e.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); let (actions, mapped_n) = n.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Extract( - ann.clone(), + span.clone(), mapped_e.get_corresponding_var_or_lit(typeinfo), mapped_n.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Extract(ann.clone(), mapped_e, mapped_n)); + .push(GenericAction::Extract(span.clone(), mapped_e, mapped_n)); } - GenericAction::Panic(ann, string) => { - norm_actions.push(GenericCoreAction::Panic(ann.clone(), string.clone())); + GenericAction::Panic(span, string) => { + norm_actions.push(GenericCoreAction::Panic(span.clone(), string.clone())); mapped_actions .0 - .push(GenericAction::Panic(ann.clone(), string.clone())); + .push(GenericAction::Panic(span.clone(), string.clone())); } - GenericAction::Expr(ann, expr) => { + GenericAction::Expr(span, expr) => { let (actions, mapped_expr) = expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); mapped_actions .0 - .push(GenericAction::Expr(ann.clone(), mapped_expr)); + .push(GenericAction::Expr(span.clone(), mapped_expr)); } } } @@ -576,9 +576,9 @@ where } } -impl GenericExpr +impl GenericExpr where - Ann: Annotation, + Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -587,16 +587,16 @@ where typeinfo: &TypeInfo, fresh_gen: &mut impl FreshGen, ) -> ( - Vec, Leaf, Ann>>, - MappedExpr, + Vec, Leaf>>, + MappedExpr, ) where Leaf: SymbolLike, { match self { - GenericExpr::Lit(ann, lit) => (vec![], GenericExpr::Lit(ann.clone(), lit.clone())), - GenericExpr::Var(ann, v) => (vec![], GenericExpr::Var(ann.clone(), v.clone())), - GenericExpr::Call(ann, f, children) => { + GenericExpr::Lit(span, lit) => (vec![], GenericExpr::Lit(span.clone(), lit.clone())), + GenericExpr::Var(span, v) => (vec![], GenericExpr::Var(span.clone(), v.clone())), + GenericExpr::Call(span, f, children) => { let fresh = fresh_gen.fresh(f); let mut new_children = vec![]; let mut atoms = vec![]; @@ -609,18 +609,18 @@ where child_exprs.push(child_expr); } let args = { - new_children.push(GenericAtomTerm::Var(ann.clone(), fresh.clone())); + new_children.push(GenericAtomTerm::Var(span.clone(), fresh.clone())); new_children }; atoms.push(GenericAtom { - ann: ann.clone(), + span: span.clone(), head: HeadOrEq::Symbol(f.clone()), args, }); ( atoms, GenericExpr::Call( - ann.clone(), + span.clone(), CorrespondingVar::new(f.clone(), fresh), child_exprs, ), @@ -636,8 +636,8 @@ where fresh_gen: &mut FG, ) -> Result< ( - GenericCoreActions, - MappedExpr, + GenericCoreActions, + MappedExpr, ), TypeError, > @@ -645,22 +645,22 @@ where Leaf: Hash + Eq + SymbolLike, { match self { - GenericExpr::Lit(ann, lit) => Ok(( + GenericExpr::Lit(span, lit) => Ok(( GenericCoreActions::default(), - GenericExpr::Lit(ann.clone(), lit.clone()), + GenericExpr::Lit(span.clone(), lit.clone()), )), - GenericExpr::Var(ann, v) => { + GenericExpr::Var(span, v) => { let sym = v.to_symbol(); if binding.contains(v) || typeinfo.is_global(sym) { Ok(( GenericCoreActions::default(), - GenericExpr::Var(ann.clone(), v.clone()), + GenericExpr::Var(span.clone(), v.clone()), )) } else { Err(TypeError::Unbound(sym)) } } - GenericExpr::Call(ann, f, args) => { + GenericExpr::Call(span, f, args) => { let mut norm_actions = vec![]; let mut norm_args = vec![]; let mut mapped_args = vec![]; @@ -676,7 +676,7 @@ where binding.insert(var.clone()); norm_actions.push(GenericCoreAction::Let( - ann.clone(), + span.clone(), var.clone(), f.clone(), norm_args, @@ -684,7 +684,7 @@ where Ok(( GenericCoreActions::new(norm_actions), GenericExpr::Call( - ann.clone(), + span.clone(), CorrespondingVar::new(f.clone(), var), mapped_args, ), @@ -702,23 +702,23 @@ where /// for `body` needs to be a `HeadOrEq`, while `head` does not have equality /// constraints. #[derive(Debug, Clone)] -pub struct GenericCoreRule { - pub ann: Ann, - pub body: Query, - pub head: GenericCoreActions, +pub struct GenericCoreRule { + pub span: Span, + pub body: Query, + pub head: GenericCoreActions, } -pub(crate) type CoreRule = GenericCoreRule; -pub(crate) type ResolvedCoreRule = GenericCoreRule; +pub(crate) type CoreRule = GenericCoreRule; +pub(crate) type ResolvedCoreRule = GenericCoreRule; -impl GenericCoreRule +impl GenericCoreRule where Head1: Clone, Head2: Clone, Leaf: Clone + Eq + Hash, - Ann: Annotation, + { - pub fn subst(&mut self, subst: &HashMap>) { + pub fn subst(&mut self, subst: &HashMap>) { for atom in &mut self.body.atoms { atom.subst(subst); } @@ -726,11 +726,11 @@ where } } -impl GenericCoreRule, Head, Leaf, Ann> +impl GenericCoreRule, Head, Leaf> where Leaf: Eq + Clone + Hash + Debug, Head: Clone, - Ann: Annotation, + { /// Transformed a UnresolvedCoreRule into a CanonicalizedCoreRule. /// In particular, it removes equality checks between variables and @@ -739,8 +739,8 @@ where pub(crate) fn canonicalize( self, // Users need to pass in a substitute for equality constraints. - value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, - ) -> GenericCoreRule { + value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, + ) -> GenericCoreRule { let mut result_rule = self; loop { let mut to_subst = None; @@ -783,12 +783,12 @@ where None } else { Some(GenericAtom { - ann: atom.ann.clone(), + span: atom.span.clone(), head: value_eq(&atom.args[0], &atom.args[1]), args: vec![ atom.args[0].clone(), atom.args[1].clone(), - GenericAtomTerm::Literal(atom.ann, Literal::Unit), + GenericAtomTerm::Literal(atom.span, Literal::Unit), ], }) } @@ -796,42 +796,42 @@ where } } HeadOrEq::Symbol(symbol) => Some(GenericAtom { - ann: atom.ann, + span: atom.span, head: symbol, args: atom.args, }), }) .collect(); GenericCoreRule { - ann: result_rule.ann, + span: result_rule.span, body: Query { atoms }, head: result_rule.head, } } } -impl GenericRule +impl GenericRule where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash + Debug, - Ann: Annotation, + { pub(crate) fn to_core_rule( &self, typeinfo: &TypeInfo, mut fresh_gen: impl FreshGen, - ) -> Result, Head, Leaf, Ann>, TypeError> + ) -> Result, Head, Leaf>, TypeError> where Leaf: SymbolLike, { - let GenericRule { ann: _, head, body } = self; + let GenericRule { span: _, head, body } = self; let (body, _correspondence) = Facts(body.clone()).to_query(typeinfo, &mut fresh_gen); let mut binding = body.get_vars(); let (head, _correspondence) = head.to_core_actions(typeinfo, &mut binding, &mut fresh_gen)?; Ok(GenericCoreRule { - ann: self.ann.clone(), + span: self.span.clone(), body, head, }) @@ -841,8 +841,8 @@ where &self, typeinfo: &TypeInfo, fresh_gen: impl FreshGen, - value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, - ) -> Result, TypeError> + value_eq: impl Fn(&GenericAtomTerm, &GenericAtomTerm) -> Head, + ) -> Result, TypeError> where Leaf: SymbolLike, { diff --git a/src/extract.rs b/src/extract.rs index 587afc4f..e895082b 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -24,7 +24,7 @@ impl EGraph { /// trivial, as there is only a single variant of the expression in the /// egraph. /// ``` - /// use egglog::{EGraph, TermDag, ast::Annotation}; + /// use egglog::{EGraph, TermDag}; /// let mut egraph = EGraph::default(); /// egraph /// .parse_and_run_program( @@ -35,7 +35,7 @@ impl EGraph { /// .unwrap(); /// let mut termdag = TermDag::default(); /// let (sort, value) = egraph - /// .eval_expr(&egglog::ast::Expr::Var(Annotation::dummy(), "expr".into())) + /// .eval_expr(&egglog::ast::Expr::var_no_span("expr")) /// .unwrap(); /// let (_, extracted) = egraph.extract(value, &mut termdag, &sort); /// assert_eq!(termdag.to_string(&extracted), "(Add 1 1)"); diff --git a/src/gj.rs b/src/gj.rs index 9627a46e..230d8b08 100644 --- a/src/gj.rs +++ b/src/gj.rs @@ -362,12 +362,12 @@ impl EGraph { .into_iter() .map(|atom| { let args = atom.args.into_iter().map(|arg| match arg { - ResolvedAtomTerm::Var(ann, v) => AtomTerm::Var(ann, v.name), - ResolvedAtomTerm::Literal(ann, lit) => AtomTerm::Literal(ann, lit), - ResolvedAtomTerm::Global(ann, g) => AtomTerm::Global(ann, g.name), + ResolvedAtomTerm::Var(span, v) => AtomTerm::Var(span, v.name), + ResolvedAtomTerm::Literal(span, lit) => AtomTerm::Literal(span, lit), + ResolvedAtomTerm::Global(span, g) => AtomTerm::Global(span, g.name), }); Atom { - ann: atom.ann, + span: atom.span, head: atom.head, args: args.collect(), } diff --git a/src/lib.rs b/src/lib.rs index 3da38e01..2c3ab0c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1213,7 +1213,7 @@ impl EGraph { fn check_facts(&mut self, span: &Span, facts: &[ResolvedFact]) -> Result<(), Error> { let rule = ast::ResolvedRule { - ann: *span, + span: *span, head: ResolvedActions::default(), body: facts.to_vec(), }; @@ -1291,8 +1291,8 @@ impl EGraph { log::info!("Overall statistics:\n{}", self.overall_run_report); self.print_msg(format!("Overall statistics:\n{}", self.overall_run_report)); } - ResolvedNCommand::Check(ann, facts) => { - self.check_facts(&ann, &facts)?; + ResolvedNCommand::Check(span, facts) => { + self.check_facts(&span, &facts)?; log::info!("Checked fact {:?}.", facts); } ResolvedNCommand::CheckProof => log::error!("TODO implement proofs"), diff --git a/src/sort/fn.rs b/src/sort/fn.rs index b9711e21..4c5fe6f9 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -213,7 +213,7 @@ impl TypeConstraint for FunctionCTorTypeConstraint { vec![Constraint::Impossible( constraint::ImpossibleConstraint::ArityMismatch { atom: core::Atom { - ann: self.span, + span: self.span, head: self.name, args: arguments.to_vec(), }, diff --git a/src/termdag.rs b/src/termdag.rs index 9b3e6e9e..b1f05177 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,5 +1,5 @@ use crate::{ - ast::Literal, util::{HashMap, HashSet}, Expr, GenericExpr, Symbol, DUMMY_SPAN + ast::Literal, util::{HashMap, HashSet}, Expr, GenericExpr, Symbol }; pub type TermId = usize; @@ -107,7 +107,7 @@ impl TermDag { /// This involves inserting every subexpression into this DAG. Because /// TermDags are hashconsed, the resulting term is guaranteed to maximally /// share subterms. - pub fn expr_to_term(&mut self, expr: &GenericExpr) -> Term { + pub fn expr_to_term(&mut self, expr: &GenericExpr) -> Term { let res = match expr { GenericExpr::Lit(_, lit) => Term::Lit(lit.clone()), GenericExpr::Var(_, v) => Term::Var(*v), @@ -189,7 +189,7 @@ impl TermDag { #[cfg(test)] mod tests { - use crate::ast; + use crate::{ast, DUMMY_SPAN}; use super::*; diff --git a/src/typechecking.rs b/src/typechecking.rs index 199166ae..4adb366a 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -180,7 +180,7 @@ impl TypeInfo { self.declare_sort(*sort, presort_and_args)?; ResolvedNCommand::Sort(*sort, presort_and_args.clone()) } - NCommand::CoreAction(Action::Let(ann, var, expr)) => { + NCommand::CoreAction(Action::Let(span, var, expr)) => { let expr = self.typecheck_expr(expr, &Default::default())?; let output_type = expr.output_type(self); self.global_types.insert(*var, output_type.clone()); @@ -190,7 +190,7 @@ impl TypeInfo { // not a global reference, but a global binding is_global_ref: false, }; - ResolvedNCommand::CoreAction(ResolvedAction::Let(*ann, var, expr)) + ResolvedNCommand::CoreAction(ResolvedAction::Let(*span, var, expr)) } NCommand::CoreAction(action) => { ResolvedNCommand::CoreAction(self.typecheck_action(action, &Default::default())?) @@ -334,7 +334,7 @@ impl TypeInfo { } fn typecheck_rule(&self, rule: &Rule) -> Result { - let Rule { ann, head, body } = rule; + let Rule { span, head, body } = rule; let mut constraints = vec![]; let mut fresh_gen = SymbolGen::new("$".to_string()); @@ -347,7 +347,7 @@ impl TypeInfo { let mut problem = Problem::default(); problem.add_rule( &CoreRule { - ann: *ann, + span: *span, body: query, head: actions, }, @@ -362,7 +362,7 @@ impl TypeInfo { let actions: ResolvedActions = assignment.annotate_actions(&mapped_action, self)?; Ok(ResolvedRule { - ann: *ann, + span: *span, body, head: actions, }) @@ -521,7 +521,7 @@ mod test { expected: 2, expr: e, })) => { - let span = e.ann(); + let span = e.span(); assert_eq!(&prog[span.1..span.2], "(f a b c)"); } _ => panic!("Expected arity mismatch, got: {:?}", res), diff --git a/tests/integration_test.rs b/tests/integration_test.rs index fa13e8da..e57f6ade 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,4 +1,4 @@ -use egglog::{ast::GenericExpr, EGraph, ExtractReport, Function, Term, Value}; +use egglog::{ast::{Expr, GenericExpr}, EGraph, ExtractReport, Function, Term, Value}; use symbol_table::GlobalSymbol; #[test] @@ -114,7 +114,7 @@ fn test_subsumed_unextractable_rebuild_arg() { let expr = termdag.term_to_expr(&term); assert_eq!( expr, - GenericExpr::Call((), GlobalSymbol::from("exp"), vec![]) + Expr::call_no_span(GlobalSymbol::from("exp"), vec![]) ); } @@ -168,7 +168,7 @@ fn test_subsumed_unextractable_rebuild_self() { let expr = termdag.term_to_expr(&term); assert_eq!( expr, - GenericExpr::Call((), GlobalSymbol::from("exp"), vec![]) + Expr::call_no_span(GlobalSymbol::from("exp"), vec![]) ); } From 39e6d43c6691c359f31d16163d4bbd9420a35f0f Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Mon, 15 Jul 2024 20:39:08 -0700 Subject: [PATCH 13/16] nits --- src/ast/desugar.rs | 6 +- src/ast/expr.rs | 16 ++-- src/ast/mod.rs | 158 ++++++++++++-------------------------- src/constraint.rs | 6 +- src/core.rs | 115 ++++++++++----------------- src/sort/bool.rs | 5 +- src/sort/f64.rs | 5 +- src/sort/fn.rs | 5 +- src/sort/i64.rs | 5 +- src/termdag.rs | 4 +- tests/integration_test.rs | 12 +-- 11 files changed, 126 insertions(+), 211 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index d3bdab72..f7b599ac 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -70,7 +70,7 @@ fn desugar_rewrite( ruleset, name, rule: Rule { - span: span, + span, body: [Fact::Eq( span, vec![Expr::Var(span, var), rewrite.lhs.clone()], @@ -86,7 +86,7 @@ fn desugar_rewrite( fn desugar_birewrite(ruleset: Symbol, name: Symbol, rewrite: &Rewrite) -> Vec { let span = rewrite.span; let rw2 = Rewrite { - span: span, + span, lhs: rewrite.rhs.clone(), rhs: rewrite.lhs.clone(), conditions: rewrite.conditions.clone(), @@ -186,7 +186,7 @@ pub(crate) fn desugar_calc( // first, push all the idents for IdentSort { ident, sort } in idents { res.push(Command::Declare { - span: span, + span, name: ident, sort, }); diff --git a/src/ast/expr.rs b/src/ast/expr.rs index a07b9886..9c4f121c 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -153,14 +153,12 @@ impl Expr { } } -impl - GenericExpr -{ +impl GenericExpr { pub fn span(&self) -> Span { match self { - GenericExpr::Lit(span, _) => span.clone(), - GenericExpr::Var(span, _) => span.clone(), - GenericExpr::Call(span, _, _) => span.clone(), + GenericExpr::Lit(span, _) => *span, + GenericExpr::Var(span, _) => *span, + GenericExpr::Call(span, _, _) => *span, } } @@ -209,7 +207,7 @@ impl GenericExpr::Var(..) => f(self), GenericExpr::Call(span, op, children) => { let children = children.into_iter().map(|c| c.visit_exprs(f)).collect(); - f(GenericExpr::Call(span.clone(), op.clone(), children)) + f(GenericExpr::Call(span, op.clone(), children)) } } } @@ -221,14 +219,14 @@ impl subst_head: &mut impl FnMut(&Head) -> Head2, ) -> GenericExpr { match self { - GenericExpr::Lit(span, lit) => GenericExpr::Lit(span.clone(), lit.clone()), + GenericExpr::Lit(span, lit) => GenericExpr::Lit(*span, lit.clone()), GenericExpr::Var(span, v) => subst_leaf(span, v), GenericExpr::Call(span, op, children) => { let children = children .iter() .map(|c| c.subst(subst_leaf, subst_head)) .collect(); - GenericExpr::Call(span.clone(), subst_head(op), children) + GenericExpr::Call(*span, subst_head(op), children) } } } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index c8cc7a24..4e03f639 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -85,7 +85,6 @@ pub(crate) type ResolvedNCommand = GenericNCommand; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum GenericNCommand where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -93,10 +92,7 @@ where name: Symbol, value: GenericExpr, }, - Sort( - Symbol, - Option<(Symbol, Vec>)>, - ), + Sort(Symbol, Option<(Symbol, Vec>)>), Function(GenericFunctionDecl), AddRuleset(Symbol), UnstableCombinedRuleset(Symbol, Vec), @@ -129,7 +125,6 @@ impl GenericNCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - { pub fn to_command(&self) -> GenericCommand { match self { @@ -155,7 +150,7 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(span, facts) => GenericCommand::Check(span.clone(), facts.clone()), + GenericNCommand::Check(span, facts) => GenericCommand::Check(*span, facts.clone()), GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -276,7 +271,6 @@ macro_rules! list { impl GenericSchedule where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -329,7 +323,6 @@ pub enum GenericCommand where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - { /// Egglog supports several *experimental* options /// that can be set using the `set-option` command. @@ -409,10 +402,7 @@ where /// ``` /// /// Now `MathVec` can be used as an input or output sort. - Sort( - Symbol, - Option<(Symbol, Vec>)>, - ), + Sort(Symbol, Option<(Symbol, Vec>)>), /// Declare an egglog function, which is a database table with a /// a functional dependency (also called a primary key) on its inputs to one output. /// @@ -711,7 +701,6 @@ impl ToSexp for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - { fn to_sexp(&self) -> Sexp { match self { @@ -721,7 +710,11 @@ where } GenericCommand::BiRewrite(name, rewrite) => rewrite.to_sexp(*name, true, false), GenericCommand::Datatype { name, variants } => list!("datatype", name, ++ variants), - GenericCommand::Declare { span: _, name, sort } => list!("declare", name, sort), + GenericCommand::Declare { + span: _, + name, + sort, + } => list!("declare", name, sort), GenericCommand::Action(a) => a.to_sexp(), GenericCommand::Sort(name, None) => list!("sort", name), GenericCommand::Sort(name, Some((name2, args))) => { @@ -768,7 +761,6 @@ impl Display for GenericNCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_command()) @@ -779,7 +771,6 @@ impl Display for GenericCommand where Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, - { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { @@ -825,7 +816,6 @@ pub struct GenericRunConfig { impl GenericRunConfig where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -869,7 +859,6 @@ pub(crate) type ResolvedFunctionDecl = GenericFunctionDecl where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -944,7 +933,6 @@ impl FunctionDecl { impl GenericFunctionDecl where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -967,7 +955,6 @@ where impl ToSexp for GenericFunctionDecl where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1040,7 +1027,6 @@ pub struct Facts(pub Vec>); impl Facts where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1055,10 +1041,7 @@ where &self, typeinfo: &TypeInfo, fresh_gen: &mut impl FreshGen, - ) -> ( - Query, Leaf>, - Vec>, - ) + ) -> (Query, Leaf>, Vec>) where Leaf: SymbolLike, { @@ -1077,11 +1060,11 @@ where new_exprs.push(expr); } atoms.push(GenericAtom { - span: span.clone(), + span: *span, head: HeadOrEq::Eq, args: to_equate, }); - new_body.push(GenericFact::Eq(span.clone(), new_exprs)); + new_body.push(GenericFact::Eq(*span, new_exprs)); } GenericFact::Fact(expr) => { let (child_atoms, expr) = expr.to_query(typeinfo, fresh_gen); @@ -1109,7 +1092,6 @@ where impl GenericFact where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1119,7 +1101,7 @@ where ) -> GenericFact { match self { GenericFact::Eq(span, exprs) => GenericFact::Eq( - span.clone(), + span, exprs.into_iter().map(|expr| expr.visit_exprs(f)).collect(), ), GenericFact::Fact(expr) => GenericFact::Fact(expr.visit_exprs(f)), @@ -1131,9 +1113,7 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> GenericFact { match self { - GenericFact::Eq(span, exprs) => { - GenericFact::Eq(span.clone(), exprs.iter().map(f).collect()) - } + GenericFact::Eq(span, exprs) => GenericFact::Eq(*span, exprs.iter().map(f).collect()), GenericFact::Fact(expr) => GenericFact::Fact(f(expr)), } } @@ -1151,7 +1131,6 @@ impl GenericFact where Leaf: Clone + PartialEq + Eq + Display + Hash, Head: Clone + Display, - { pub(crate) fn make_unresolved(self) -> GenericFact where @@ -1159,7 +1138,7 @@ where Head: SymbolLike, { self.subst( - &mut |span, v| GenericExpr::Var(span.clone(), v.to_symbol()), + &mut |span, v| GenericExpr::Var(*span, v.to_symbol()), &mut |h| h.to_symbol(), ) } @@ -1223,7 +1202,6 @@ pub(crate) type ResolvedAction = GenericAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum GenericAction where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1254,11 +1232,7 @@ where /// (extract (Num 1)); Extracts Num 1 /// (extract (Num 2)); Extracts Num 1 /// ``` - Union( - Span, - GenericExpr, - GenericExpr, - ), + Union(Span, GenericExpr, GenericExpr), /// `extract` a datatype from the egraph, choosing /// the smallest representative. /// By default, each constructor costs 1 to extract @@ -1267,11 +1241,7 @@ where /// The second argument is the number of variants to /// extract, picking different terms in the /// same equivalence class. - Extract( - Span, - GenericExpr, - GenericExpr, - ), + Extract(Span, GenericExpr, GenericExpr), Panic(Span, String), Expr(Span, GenericExpr), // If(Expr, Action, Action), @@ -1279,19 +1249,15 @@ where #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericActions< - Head: Clone + Display, - Leaf: Clone + PartialEq + Eq + Display + Hash, - ->(pub Vec>); +pub struct GenericActions( + pub Vec>, +); pub type Actions = GenericActions; pub(crate) type ResolvedActions = GenericActions; -pub(crate) type MappedActions = - GenericActions, Leaf>; +pub(crate) type MappedActions = GenericActions, Leaf>; impl Default for GenericActions where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1302,7 +1268,6 @@ where impl GenericActions where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1328,7 +1293,6 @@ where impl ToSexp for GenericAction where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1357,7 +1321,6 @@ impl GenericAction where Head: Clone + Display, Leaf: Clone + Eq + Display + Hash, - { // Applys `f` to all expressions in the action. pub fn map_exprs( @@ -1365,32 +1328,20 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericAction::Let(span, lhs, rhs) => { - GenericAction::Let(span.clone(), lhs.clone(), f(rhs)) - } + GenericAction::Let(span, lhs, rhs) => GenericAction::Let(*span, lhs.clone(), f(rhs)), GenericAction::Set(span, lhs, args, rhs) => { let right = f(rhs); - GenericAction::Set( - span.clone(), - lhs.clone(), - args.iter().map(f).collect(), - right, - ) + GenericAction::Set(*span, lhs.clone(), args.iter().map(f).collect(), right) } - GenericAction::Change(span, change, lhs, args) => GenericAction::Change( - span.clone(), - *change, - lhs.clone(), - args.iter().map(f).collect(), - ), - GenericAction::Union(span, lhs, rhs) => { - GenericAction::Union(span.clone(), f(lhs), f(rhs)) + GenericAction::Change(span, change, lhs, args) => { + GenericAction::Change(*span, *change, lhs.clone(), args.iter().map(f).collect()) } + GenericAction::Union(span, lhs, rhs) => GenericAction::Union(*span, f(lhs), f(rhs)), GenericAction::Extract(span, expr, variants) => { - GenericAction::Extract(span.clone(), f(expr), f(variants)) + GenericAction::Extract(*span, f(expr), f(variants)) } - GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), - GenericAction::Expr(span, e) => GenericAction::Expr(span.clone(), f(e)), + GenericAction::Panic(span, msg) => GenericAction::Panic(*span, msg.clone()), + GenericAction::Expr(span, e) => GenericAction::Expr(*span, f(e)), } } @@ -1402,34 +1353,31 @@ where ) -> Self { match self { GenericAction::Let(span, lhs, rhs) => { - GenericAction::Let(span.clone(), lhs.clone(), rhs.visit_exprs(f)) + GenericAction::Let(span, lhs.clone(), rhs.visit_exprs(f)) } // TODO should we refactor `Set` so that we can map over Expr::Call(lhs, args)? // This seems more natural to oflatt // Currently, visit_exprs does not apply f to the first argument of Set. GenericAction::Set(span, lhs, args, rhs) => { let args = args.into_iter().map(|e| e.visit_exprs(f)).collect(); - GenericAction::Set(span.clone(), lhs.clone(), args, rhs.visit_exprs(f)) + GenericAction::Set(span, lhs.clone(), args, rhs.visit_exprs(f)) } GenericAction::Change(span, change, lhs, args) => { let args = args.into_iter().map(|e| e.visit_exprs(f)).collect(); - GenericAction::Change(span.clone(), change, lhs.clone(), args) + GenericAction::Change(span, change, lhs.clone(), args) } GenericAction::Union(span, lhs, rhs) => { - GenericAction::Union(span.clone(), lhs.visit_exprs(f), rhs.visit_exprs(f)) + GenericAction::Union(span, lhs.visit_exprs(f), rhs.visit_exprs(f)) } GenericAction::Extract(span, expr, variants) => { - GenericAction::Extract(span.clone(), expr.visit_exprs(f), variants.visit_exprs(f)) + GenericAction::Extract(span, expr.visit_exprs(f), variants.visit_exprs(f)) } - GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), - GenericAction::Expr(span, e) => GenericAction::Expr(span.clone(), e.visit_exprs(f)), + GenericAction::Panic(span, msg) => GenericAction::Panic(span, msg.clone()), + GenericAction::Expr(span, e) => GenericAction::Expr(span, e.visit_exprs(f)), } } - pub fn subst( - &self, - subst: &mut impl FnMut(&Span, &Leaf) -> GenericExpr, - ) -> Self { + pub fn subst(&self, subst: &mut impl FnMut(&Span, &Leaf) -> GenericExpr) -> Self { self.map_exprs(&mut |e| e.subst_leaf(subst)) } @@ -1443,7 +1391,7 @@ where GenericAction::Let(span, lhs, rhs) => { let lhs = fvar(lhs, true); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Let(span.clone(), lhs, rhs) + GenericAction::Let(span, lhs, rhs) } GenericAction::Set(span, lhs, args, rhs) => { let args = args @@ -1451,28 +1399,28 @@ where .map(|e| e.subst_leaf(&mut fvar_expr!())) .collect(); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Set(span.clone(), lhs.clone(), args, rhs) + GenericAction::Set(span, lhs.clone(), args, rhs) } GenericAction::Change(span, change, lhs, args) => { let args = args .into_iter() .map(|e| e.subst_leaf(&mut fvar_expr!())) .collect(); - GenericAction::Change(span.clone(), change, lhs.clone(), args) + GenericAction::Change(span, change, lhs.clone(), args) } GenericAction::Union(span, lhs, rhs) => { let lhs = lhs.subst_leaf(&mut fvar_expr!()); let rhs = rhs.subst_leaf(&mut fvar_expr!()); - GenericAction::Union(span.clone(), lhs, rhs) + GenericAction::Union(span, lhs, rhs) } GenericAction::Extract(span, expr, variants) => { let expr = expr.subst_leaf(&mut fvar_expr!()); let variants = variants.subst_leaf(&mut fvar_expr!()); - GenericAction::Extract(span.clone(), expr, variants) + GenericAction::Extract(span, expr, variants) } - GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), + GenericAction::Panic(span, msg) => GenericAction::Panic(span, msg.clone()), GenericAction::Expr(span, e) => { - GenericAction::Expr(span.clone(), e.subst_leaf(&mut fvar_expr!())) + GenericAction::Expr(span, e.subst_leaf(&mut fvar_expr!())) } } } @@ -1480,7 +1428,6 @@ where impl Display for GenericAction where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1501,7 +1448,6 @@ pub(crate) type ResolvedRule = GenericRule; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GenericRule where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1512,7 +1458,6 @@ where impl GenericRule where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -1534,7 +1479,6 @@ where impl GenericRule where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1584,7 +1528,6 @@ where impl GenericRule where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1609,7 +1552,6 @@ where impl Display for GenericRule where - Head: Clone + Display + ToSexp, Leaf: Clone + PartialEq + Eq + Display + Hash + ToSexp, { @@ -1667,14 +1609,10 @@ impl Display for GenericRewrite { impl MappedExpr where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { - pub(crate) fn get_corresponding_var_or_lit( - &self, - typeinfo: &TypeInfo, - ) -> GenericAtomTerm + pub(crate) fn get_corresponding_var_or_lit(&self, typeinfo: &TypeInfo) -> GenericAtomTerm where Leaf: SymbolLike, { @@ -1684,13 +1622,13 @@ where match self { GenericExpr::Var(span, v) => { if typeinfo.is_global(v.to_symbol()) { - GenericAtomTerm::Global(span.clone(), v.clone()) + GenericAtomTerm::Global(*span, v.clone()) } else { - GenericAtomTerm::Var(span.clone(), v.clone()) + GenericAtomTerm::Var(*span, v.clone()) } } - GenericExpr::Lit(span, lit) => GenericAtomTerm::Literal(span.clone(), lit.clone()), - GenericExpr::Call(span, head, _) => GenericAtomTerm::Var(span.clone(), head.to.clone()), + GenericExpr::Lit(span, lit) => GenericAtomTerm::Literal(*span, lit.clone()), + GenericExpr::Call(span, head, _) => GenericAtomTerm::Var(*span, head.to.clone()), } } } diff --git a/src/constraint.rs b/src/constraint.rs index cf38ab5a..d5e8414d 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -471,7 +471,11 @@ impl Problem { rule: &CoreRule, typeinfo: &TypeInfo, ) -> Result<(), TypeError> { - let CoreRule { span: _, head, body } = rule; + let CoreRule { + span: _, + head, + body, + } = rule; self.add_query(body, typeinfo)?; self.add_actions(head, typeinfo)?; Ok(()) diff --git a/src/core.rs b/src/core.rs index f9ffd3f3..58b70dec 100644 --- a/src/core.rs +++ b/src/core.rs @@ -182,9 +182,9 @@ impl GenericAtomTerm { impl GenericAtomTerm { pub fn to_expr(&self) -> GenericExpr { match self { - GenericAtomTerm::Var(span, v) => GenericExpr::Var(span.clone(), v.clone()), - GenericAtomTerm::Literal(span, l) => GenericExpr::Lit(span.clone(), l.clone()), - GenericAtomTerm::Global(span, v) => GenericExpr::Var(span.clone(), v.clone()), + GenericAtomTerm::Var(span, v) => GenericExpr::Var(*span, v.clone()), + GenericAtomTerm::Literal(span, l) => GenericExpr::Lit(*span, l.clone()), + GenericAtomTerm::Global(span, v) => GenericExpr::Var(*span, v.clone()), } } } @@ -302,7 +302,6 @@ impl Query where Leaf: Eq + Clone + Hash, Head: Clone, - { pub(crate) fn get_vars(&self) -> IndexSet { self.atoms @@ -353,7 +352,7 @@ impl Query { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(_) => None, ResolvedCall::Primitive(head) => Some(GenericAtom { - span: atom.span.clone(), + span: atom.span, head: head.primitive.clone(), args: atom.args.clone(), }), @@ -363,7 +362,7 @@ impl Query { pub fn funcs(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(head) => Some(GenericAtom { - span: atom.span.clone(), + span: atom.span, head: head.name, args: atom.args.clone(), }), @@ -391,9 +390,7 @@ pub enum GenericCoreAction { pub type CoreAction = GenericCoreAction; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct GenericCoreActions( - pub(crate) Vec>, -); +pub struct GenericCoreActions(pub(crate) Vec>); pub(crate) type ResolvedCoreActions = GenericCoreActions; impl Default for GenericCoreActions { @@ -405,23 +402,16 @@ impl Default for GenericCoreActions { impl GenericCoreActions where Leaf: Clone, - { pub(crate) fn subst(&mut self, subst: &HashMap>) { let actions = subst.iter().map(|(symbol, atom_term)| { - GenericCoreAction::LetAtomTerm( - atom_term.span().clone(), - symbol.clone(), - atom_term.clone(), - ) + GenericCoreAction::LetAtomTerm(*atom_term.span(), symbol.clone(), atom_term.clone()) }); let existing_actions = std::mem::take(&mut self.0); self.0 = actions.chain(existing_actions).collect(); } - fn new( - actions: Vec>, - ) -> GenericCoreActions { + fn new(actions: Vec>) -> GenericCoreActions { Self(actions) } } @@ -431,20 +421,13 @@ impl GenericActions where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, - { pub(crate) fn to_core_actions>( &self, typeinfo: &TypeInfo, binding: &mut IndexSet, fresh_gen: &mut FG, - ) -> Result< - ( - GenericCoreActions, - MappedActions, - ), - TypeError, - > + ) -> Result<(GenericCoreActions, MappedActions), TypeError> where Leaf: SymbolLike, { @@ -464,15 +447,13 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::LetAtomTerm( - span.clone(), + *span, var.clone(), mapped_expr.get_corresponding_var_or_lit(typeinfo), )); - mapped_actions.0.push(GenericAction::Let( - span.clone(), - var.clone(), - mapped_expr, - )); + mapped_actions + .0 + .push(GenericAction::Let(*span, var.clone(), mapped_expr)); binding.insert(var.clone()); } GenericAction::Set(span, head, args, expr) => { @@ -487,7 +468,7 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Set( - span.clone(), + *span, head.clone(), mapped_args .iter() @@ -497,7 +478,7 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Set( - span.clone(), + *span, CorrespondingVar::new(head.clone(), v), mapped_args, mapped_expr, @@ -512,7 +493,7 @@ where mapped_args.push(mapped_arg); } norm_actions.push(GenericCoreAction::Change( - span.clone(), + *span, *change, head.clone(), mapped_args @@ -522,7 +503,7 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Change( - span.clone(), + *span, *change, CorrespondingVar::new(head.clone(), v), mapped_args, @@ -534,13 +515,13 @@ where let (actions2, mapped_e2) = e2.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions2.0); norm_actions.push(GenericCoreAction::Union( - span.clone(), + *span, mapped_e1.get_corresponding_var_or_lit(typeinfo), mapped_e2.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Union(span.clone(), mapped_e1, mapped_e2)); + .push(GenericAction::Union(*span, mapped_e1, mapped_e2)); } GenericAction::Extract(span, e, n) => { let (actions, mapped_e) = e.to_core_actions(typeinfo, binding, fresh_gen)?; @@ -548,19 +529,19 @@ where let (actions, mapped_n) = n.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Extract( - span.clone(), + *span, mapped_e.get_corresponding_var_or_lit(typeinfo), mapped_n.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Extract(span.clone(), mapped_e, mapped_n)); + .push(GenericAction::Extract(*span, mapped_e, mapped_n)); } GenericAction::Panic(span, string) => { - norm_actions.push(GenericCoreAction::Panic(span.clone(), string.clone())); + norm_actions.push(GenericCoreAction::Panic(*span, string.clone())); mapped_actions .0 - .push(GenericAction::Panic(span.clone(), string.clone())); + .push(GenericAction::Panic(*span, string.clone())); } GenericAction::Expr(span, expr) => { let (actions, mapped_expr) = @@ -568,7 +549,7 @@ where norm_actions.extend(actions.0); mapped_actions .0 - .push(GenericAction::Expr(span.clone(), mapped_expr)); + .push(GenericAction::Expr(*span, mapped_expr)); } } } @@ -578,7 +559,6 @@ where impl GenericExpr where - Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash, { @@ -594,8 +574,8 @@ where Leaf: SymbolLike, { match self { - GenericExpr::Lit(span, lit) => (vec![], GenericExpr::Lit(span.clone(), lit.clone())), - GenericExpr::Var(span, v) => (vec![], GenericExpr::Var(span.clone(), v.clone())), + GenericExpr::Lit(span, lit) => (vec![], GenericExpr::Lit(*span, lit.clone())), + GenericExpr::Var(span, v) => (vec![], GenericExpr::Var(*span, v.clone())), GenericExpr::Call(span, f, children) => { let fresh = fresh_gen.fresh(f); let mut new_children = vec![]; @@ -609,21 +589,17 @@ where child_exprs.push(child_expr); } let args = { - new_children.push(GenericAtomTerm::Var(span.clone(), fresh.clone())); + new_children.push(GenericAtomTerm::Var(*span, fresh.clone())); new_children }; atoms.push(GenericAtom { - span: span.clone(), + span: *span, head: HeadOrEq::Symbol(f.clone()), args, }); ( atoms, - GenericExpr::Call( - span.clone(), - CorrespondingVar::new(f.clone(), fresh), - child_exprs, - ), + GenericExpr::Call(*span, CorrespondingVar::new(f.clone(), fresh), child_exprs), ) } } @@ -634,27 +610,21 @@ where typeinfo: &TypeInfo, binding: &mut IndexSet, fresh_gen: &mut FG, - ) -> Result< - ( - GenericCoreActions, - MappedExpr, - ), - TypeError, - > + ) -> Result<(GenericCoreActions, MappedExpr), TypeError> where Leaf: Hash + Eq + SymbolLike, { match self { GenericExpr::Lit(span, lit) => Ok(( GenericCoreActions::default(), - GenericExpr::Lit(span.clone(), lit.clone()), + GenericExpr::Lit(*span, lit.clone()), )), GenericExpr::Var(span, v) => { let sym = v.to_symbol(); if binding.contains(v) || typeinfo.is_global(sym) { Ok(( GenericCoreActions::default(), - GenericExpr::Var(span.clone(), v.clone()), + GenericExpr::Var(*span, v.clone()), )) } else { Err(TypeError::Unbound(sym)) @@ -676,18 +646,14 @@ where binding.insert(var.clone()); norm_actions.push(GenericCoreAction::Let( - span.clone(), + *span, var.clone(), f.clone(), norm_args, )); Ok(( GenericCoreActions::new(norm_actions), - GenericExpr::Call( - span.clone(), - CorrespondingVar::new(f.clone(), var), - mapped_args, - ), + GenericExpr::Call(*span, CorrespondingVar::new(f.clone(), var), mapped_args), )) } } @@ -716,7 +682,6 @@ where Head1: Clone, Head2: Clone, Leaf: Clone + Eq + Hash, - { pub fn subst(&mut self, subst: &HashMap>) { for atom in &mut self.body.atoms { @@ -730,7 +695,6 @@ impl GenericCoreRule, Head, Leaf> where Leaf: Eq + Clone + Hash + Debug, Head: Clone, - { /// Transformed a UnresolvedCoreRule into a CanonicalizedCoreRule. /// In particular, it removes equality checks between variables and @@ -783,7 +747,7 @@ where None } else { Some(GenericAtom { - span: atom.span.clone(), + span: atom.span, head: value_eq(&atom.args[0], &atom.args[1]), args: vec![ atom.args[0].clone(), @@ -814,7 +778,6 @@ impl GenericRule where Head: Clone + Display, Leaf: Clone + PartialEq + Eq + Display + Hash + Debug, - { pub(crate) fn to_core_rule( &self, @@ -824,14 +787,18 @@ where where Leaf: SymbolLike, { - let GenericRule { span: _, head, body } = self; + let GenericRule { + span: _, + head, + body, + } = self; let (body, _correspondence) = Facts(body.clone()).to_query(typeinfo, &mut fresh_gen); let mut binding = body.get_vars(); let (head, _correspondence) = head.to_core_actions(typeinfo, &mut binding, &mut fresh_gen)?; Ok(GenericCoreRule { - span: self.span.clone(), + span: self.span, body, head, }) diff --git a/src/sort/bool.rs b/src/sort/bool.rs index fbf63816..2e4160ec 100644 --- a/src/sort/bool.rs +++ b/src/sort/bool.rs @@ -33,7 +33,10 @@ impl Sort for BoolSort { fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); - (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Bool(value.bits > 0))) + ( + 1, + GenericExpr::Lit(*DUMMY_SPAN, Literal::Bool(value.bits > 0)), + ) } } diff --git a/src/sort/f64.rs b/src/sort/f64.rs index f1d17508..3d81be5e 100755 --- a/src/sort/f64.rs +++ b/src/sort/f64.rs @@ -57,7 +57,10 @@ impl Sort for F64Sort { assert!(value.tag == self.name()); ( 1, - GenericExpr::Lit(*DUMMY_SPAN, Literal::F64(OrderedFloat(f64::from_bits(value.bits)))), + GenericExpr::Lit( + *DUMMY_SPAN, + Literal::F64(OrderedFloat(f64::from_bits(value.bits))), + ), ) } } diff --git a/src/sort/fn.rs b/src/sort/fn.rs index 756f411d..f423a087 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -176,7 +176,10 @@ impl Sort for FunctionSort { ) -> Option<(Cost, Expr)> { let ValueFunction(name, inputs) = ValueFunction::load(self, &value); let (cost, args) = inputs.into_iter().try_fold( - (1usize, vec![GenericExpr::Lit(*DUMMY_SPAN, Literal::String(name))]), + ( + 1usize, + vec![GenericExpr::Lit(*DUMMY_SPAN, Literal::String(name))], + ), |(cost, mut args), (sort, value)| { let (new_cost, term) = extractor.find_best(value, termdag, &sort)?; args.push(termdag.term_to_expr(&term)); diff --git a/src/sort/i64.rs b/src/sort/i64.rs index 12b265c7..a4fb31da 100644 --- a/src/sort/i64.rs +++ b/src/sort/i64.rs @@ -76,7 +76,10 @@ impl Sort for I64Sort { fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name()); - (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(value.bits as _))) + ( + 1, + GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(value.bits as _)), + ) } } diff --git a/src/termdag.rs b/src/termdag.rs index b1f05177..07f06843 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -1,5 +1,7 @@ use crate::{ - ast::Literal, util::{HashMap, HashSet}, Expr, GenericExpr, Symbol + ast::Literal, + util::{HashMap, HashSet}, + Expr, GenericExpr, Symbol, }; pub type TermId = usize; diff --git a/tests/integration_test.rs b/tests/integration_test.rs index e57f6ade..50026050 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,4 +1,4 @@ -use egglog::{ast::{Expr, GenericExpr}, EGraph, ExtractReport, Function, Term, Value}; +use egglog::{ast::Expr, EGraph, ExtractReport, Function, Term, Value}; use symbol_table::GlobalSymbol; #[test] @@ -112,10 +112,7 @@ fn test_subsumed_unextractable_rebuild_arg() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!( - expr, - Expr::call_no_span(GlobalSymbol::from("exp"), vec![]) - ); + assert_eq!(expr, Expr::call_no_span(GlobalSymbol::from("exp"), vec![])); } #[test] @@ -166,10 +163,7 @@ fn test_subsumed_unextractable_rebuild_self() { panic!(); }; let expr = termdag.term_to_expr(&term); - assert_eq!( - expr, - Expr::call_no_span(GlobalSymbol::from("exp"), vec![]) - ); + assert_eq!(expr, Expr::call_no_span(GlobalSymbol::from("exp"), vec![])); } #[test] From 366378f55d0c3ca35746f480f418a9ef1cd29379 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 23 Jul 2024 23:16:56 -0700 Subject: [PATCH 14/16] make Span non-copyable --- src/ast/desugar.rs | 48 ++++++++++++++------------- src/ast/expr.rs | 18 +++++------ src/ast/mod.rs | 54 +++++++++++++++++++------------ src/ast/parse.lalrpop | 68 +++++++++++++++++++-------------------- src/ast/remove_globals.rs | 2 +- src/constraint.rs | 46 +++++++++++++------------- src/core.rs | 66 ++++++++++++++++++------------------- src/lib.rs | 26 +++++++-------- src/sort/bool.rs | 2 +- src/sort/f64.rs | 2 +- src/sort/fn.rs | 12 +++---- src/sort/i64.rs | 4 +-- src/sort/macros.rs | 2 +- src/sort/map.rs | 20 ++++++------ src/sort/mod.rs | 2 +- src/sort/rational.rs | 4 +-- src/sort/set.rs | 24 +++++++------- src/sort/string.rs | 6 ++-- src/sort/unit.rs | 4 +-- src/sort/vec.rs | 24 +++++++------- src/termdag.rs | 2 +- src/typechecking.rs | 24 +++++++------- 22 files changed, 238 insertions(+), 222 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index f7b599ac..e1dccfff 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -45,18 +45,18 @@ fn desugar_rewrite( rewrite: &Rewrite, subsume: bool, ) -> Vec { - let span = rewrite.span; + let span = rewrite.span.clone(); let var = Symbol::from("rewrite_var__"); let mut head = Actions::singleton(Action::Union( - span, - Expr::Var(span, var), + span.clone(), + Expr::Var(span.clone(), var), rewrite.rhs.clone(), )); if subsume { match &rewrite.lhs { Expr::Call(_, f, args) => { head.0 - .push(Action::Change(span, Change::Subsume, *f, args.to_vec())); + .push(Action::Change(span.clone(), Change::Subsume, *f, args.to_vec())); } _ => { panic!("Subsumed rewrite must have a function call on the lhs"); @@ -70,9 +70,9 @@ fn desugar_rewrite( ruleset, name, rule: Rule { - span, + span: span.clone(), body: [Fact::Eq( - span, + span.clone(), vec![Expr::Var(span, var), rewrite.lhs.clone()], )] .into_iter() @@ -84,7 +84,7 @@ fn desugar_rewrite( } fn desugar_birewrite(ruleset: Symbol, name: Symbol, rewrite: &Rewrite) -> Vec { - let span = rewrite.span; + let span = rewrite.span.clone(); let rw2 = Rewrite { span, lhs: rewrite.rhs.clone(), @@ -120,9 +120,9 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { add_new_rule = true; let fresh_symbol = desugar.get_fresh(); - let fresh_var = Expr::Var(*span, fresh_symbol); + let fresh_var = Expr::Var(span.clone(), fresh_symbol); let expr = std::mem::replace(expr, fresh_var.clone()); - new_head_atoms.push(Fact::Eq(*span, vec![fresh_var, expr])); + new_head_atoms.push(Fact::Eq(span.clone(), vec![fresh_var, expr])); }; } Action::Let(span, symbol, expr) if var_set.contains(symbol) => { @@ -130,8 +130,8 @@ fn add_semi_naive_rule(desugar: &mut Desugar, rule: Rule) -> Option { if let Expr::Call(..) = expr { add_new_rule = true; - let var = Expr::Var(*span, *symbol); - new_head_atoms.push(Fact::Eq(*span, vec![var, expr.clone()])); + let var = Expr::Var(span.clone(), *symbol); + new_head_atoms.push(Fact::Eq(span.clone(), vec![var, expr.clone()])); } } _ => (), @@ -155,7 +155,7 @@ fn desugar_simplify(desugar: &mut Desugar, expr: &Expr, schedule: &Schedule) -> let span = expr.span(); let mut res = vec![NCommand::Push(1)]; let lhs = desugar.get_fresh(); - res.push(NCommand::CoreAction(Action::Let(span, lhs, expr.clone()))); + res.push(NCommand::CoreAction(Action::Let(span.clone(), lhs, expr.clone()))); res.push(NCommand::RunSchedule(schedule.clone())); res.extend( desugar_command( @@ -186,7 +186,7 @@ pub(crate) fn desugar_calc( // first, push all the idents for IdentSort { ident, sort } in idents { res.push(Command::Declare { - span, + span: span.clone(), name: ident, sort, }); @@ -207,19 +207,19 @@ pub(crate) fn desugar_calc( } res.push(Command::RunSchedule(Schedule::Saturate( - span, + span.clone(), Box::new(Schedule::Run( - span, + span.clone(), RunConfig { ruleset: "".into(), - until: Some(vec![Fact::Eq(span, vec![expr1.clone(), expr2.clone()])]), + until: Some(vec![Fact::Eq(span.clone(), vec![expr1.clone(), expr2.clone()])]), }, )), ))); res.push(Command::Check( - span, - vec![Fact::Eq(span, vec![expr1.clone(), expr2.clone()])], + span.clone(), + vec![Fact::Eq(span.clone(), vec![expr1.clone(), expr2.clone()])], )); res.push(Command::Pop(1)); @@ -409,13 +409,17 @@ impl Desugar { pub fn parse_program( &self, - filename: Option, + filename: Option, input: &str, ) -> Result, Error> { - let filename = filename.unwrap_or_else(|| Symbol::from(DEFAULT_FILENAME)); + let filename = filename.unwrap_or_else(|| DEFAULT_FILENAME.to_string()); + let srcfile = Arc::new(SrcFile { + name: filename, + contents: Some(input.to_string()), + }); Ok(self .parser - .parse(filename, input) + .parse(&srcfile, input) .map_err(|e| e.map_token(|tok| tok.to_string()))?) } @@ -436,7 +440,7 @@ impl Desugar { unextractable: false, ignore_viz: false, }), - NCommand::CoreAction(Action::Let(span, name, Expr::Call(span, fresh, vec![]))), + NCommand::CoreAction(Action::Let(span.clone(), name, Expr::Call(span.clone(), fresh, vec![]))), ] } diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 9c4f121c..a73477bf 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -141,24 +141,24 @@ impl ResolvedExpr { impl Expr { pub fn call_no_span(op: impl Into, children: impl IntoIterator) -> Self { - Self::Call(*DUMMY_SPAN, op.into(), children.into_iter().collect()) + Self::Call(DUMMY_SPAN.clone(), op.into(), children.into_iter().collect()) } pub fn lit_no_span(lit: impl Into) -> Self { - Self::Lit(*DUMMY_SPAN, lit.into()) + Self::Lit(DUMMY_SPAN.clone(), lit.into()) } pub fn var_no_span(v: impl Into) -> Self { - Self::Var(*DUMMY_SPAN, v.into()) + Self::Var(DUMMY_SPAN.clone(), v.into()) } } impl GenericExpr { pub fn span(&self) -> Span { match self { - GenericExpr::Lit(span, _) => *span, - GenericExpr::Var(span, _) => *span, - GenericExpr::Call(span, _, _) => *span, + GenericExpr::Lit(span, _) => span.clone(), + GenericExpr::Var(span, _) => span.clone(), + GenericExpr::Call(span, _, _) => span.clone(), } } @@ -219,14 +219,14 @@ impl GenericExpr Head2, ) -> GenericExpr { match self { - GenericExpr::Lit(span, lit) => GenericExpr::Lit(*span, lit.clone()), + GenericExpr::Lit(span, lit) => GenericExpr::Lit(span.clone(), lit.clone()), GenericExpr::Var(span, v) => subst_leaf(span, v), GenericExpr::Call(span, op, children) => { let children = children .iter() .map(|c| c.subst(subst_leaf, subst_head)) .collect(); - GenericExpr::Call(*span, subst_head(op), children) + GenericExpr::Call(span.clone(), subst_head(op), children) } } } @@ -282,7 +282,7 @@ where pub(crate) fn parse_expr(s: &str) -> Result> { let parser = ast::parse::ExprParser::new(); parser - .parse(DEFAULT_FILENAME.into(), s) + .parse(&SrcFile::dummy(), s) .map_err(|e| e.map_token(|tok| tok.to_string())) } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4e03f639..9d715d1d 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -55,16 +55,28 @@ pub(crate) enum Ruleset { pub(crate) const DEFAULT_FILENAME: &str = ""; pub(crate) const DUMMY_FILENAME: &str = ""; +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct SrcFile { + pub name: String, + pub contents: Option, +} + /// A [`Span`] contains the file name and a pair of offsets representing the start and the end. #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Span(pub Symbol, pub usize, pub usize); +pub struct Span(pub Arc, pub usize, pub usize); lazy_static! { - pub(crate) static ref DUMMY_SPAN: Span = Span(Symbol::from(DUMMY_FILENAME), 0, 0); + pub(crate) static ref DUMMY_FILE: Arc = Arc::new(SrcFile { + name: DUMMY_FILENAME.to_string(), + contents: None + }); + pub(crate) static ref DUMMY_SPAN: Span = Span( + DUMMY_FILE.clone(), + 0, + 0 + ); } -impl Copy for Span {} - pub type NCommand = GenericNCommand; /// [`ResolvedNCommand`] is another specialization of [`GenericNCommand`], which /// adds the type information to heads and leaves of commands. @@ -150,7 +162,7 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(span, facts) => GenericCommand::Check(*span, facts.clone()), + GenericNCommand::Check(span, facts) => GenericCommand::Check(span.clone(), facts.clone()), GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -923,7 +935,7 @@ impl FunctionDecl { }, merge: None, merge_action: Actions::default(), - default: Some(Expr::Lit(*DUMMY_SPAN, Literal::Unit)), + default: Some(Expr::Lit(DUMMY_SPAN.clone(), Literal::Unit)), cost: None, unextractable: false, ignore_viz: false, @@ -1060,11 +1072,11 @@ where new_exprs.push(expr); } atoms.push(GenericAtom { - span: *span, + span: span.clone(), head: HeadOrEq::Eq, args: to_equate, }); - new_body.push(GenericFact::Eq(*span, new_exprs)); + new_body.push(GenericFact::Eq(span.clone(), new_exprs)); } GenericFact::Fact(expr) => { let (child_atoms, expr) = expr.to_query(typeinfo, fresh_gen); @@ -1113,7 +1125,7 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> GenericFact { match self { - GenericFact::Eq(span, exprs) => GenericFact::Eq(*span, exprs.iter().map(f).collect()), + GenericFact::Eq(span, exprs) => GenericFact::Eq(span.clone(), exprs.iter().map(f).collect()), GenericFact::Fact(expr) => GenericFact::Fact(f(expr)), } } @@ -1138,7 +1150,7 @@ where Head: SymbolLike, { self.subst( - &mut |span, v| GenericExpr::Var(*span, v.to_symbol()), + &mut |span, v| GenericExpr::Var(span.clone(), v.to_symbol()), &mut |h| h.to_symbol(), ) } @@ -1328,20 +1340,20 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericAction::Let(span, lhs, rhs) => GenericAction::Let(*span, lhs.clone(), f(rhs)), + GenericAction::Let(span, lhs, rhs) => GenericAction::Let(span.clone(), lhs.clone(), f(rhs)), GenericAction::Set(span, lhs, args, rhs) => { let right = f(rhs); - GenericAction::Set(*span, lhs.clone(), args.iter().map(f).collect(), right) + GenericAction::Set(span.clone(), lhs.clone(), args.iter().map(f).collect(), right) } GenericAction::Change(span, change, lhs, args) => { - GenericAction::Change(*span, *change, lhs.clone(), args.iter().map(f).collect()) + GenericAction::Change(span.clone(), *change, lhs.clone(), args.iter().map(f).collect()) } - GenericAction::Union(span, lhs, rhs) => GenericAction::Union(*span, f(lhs), f(rhs)), + GenericAction::Union(span, lhs, rhs) => GenericAction::Union(span.clone(), f(lhs), f(rhs)), GenericAction::Extract(span, expr, variants) => { - GenericAction::Extract(*span, f(expr), f(variants)) + GenericAction::Extract(span.clone(), f(expr), f(variants)) } - GenericAction::Panic(span, msg) => GenericAction::Panic(*span, msg.clone()), - GenericAction::Expr(span, e) => GenericAction::Expr(*span, f(e)), + GenericAction::Panic(span, msg) => GenericAction::Panic(span.clone(), msg.clone()), + GenericAction::Expr(span, e) => GenericAction::Expr(span.clone(), f(e)), } } @@ -1622,13 +1634,13 @@ where match self { GenericExpr::Var(span, v) => { if typeinfo.is_global(v.to_symbol()) { - GenericAtomTerm::Global(*span, v.clone()) + GenericAtomTerm::Global(span.clone(), v.clone()) } else { - GenericAtomTerm::Var(*span, v.clone()) + GenericAtomTerm::Var(span.clone(), v.clone()) } } - GenericExpr::Lit(span, lit) => GenericAtomTerm::Literal(*span, lit.clone()), - GenericExpr::Call(span, head, _) => GenericAtomTerm::Var(*span, head.to.clone()), + GenericExpr::Lit(span, lit) => GenericAtomTerm::Literal(span.clone(), lit.clone()), + GenericExpr::Call(span, head, _) => GenericAtomTerm::Var(span.clone(), head.to.clone()), } } } diff --git a/src/ast/parse.lalrpop b/src/ast/parse.lalrpop index 097c1f99..4d55408a 100644 --- a/src/ast/parse.lalrpop +++ b/src/ast/parse.lalrpop @@ -3,7 +3,7 @@ use crate::Symbol; use crate::Schedule; use ordered_float::OrderedFloat; -grammar(filename: Symbol); +grammar(srcfile: &Arc); extern { type Error = String; @@ -55,39 +55,39 @@ Command: Command = { )?> )?> RParen => { Command::Function(FunctionDecl { name, schema, merge, merge_action: Actions::new(merge_action.unwrap_or_default()), default, cost, unextractable: unextractable.is_some(), ignore_viz: false }) }, - "declare" => Command::Declare{span: Span(filename, lo, hi), name, sort}, + "declare" => Command::Declare{span: Span(srcfile.clone(), lo, hi), name, sort}, LParen "relation" > RParen => Command::Relation{constructor, inputs}, LParen "ruleset" RParen => Command::AddRuleset(name), LParen "unstable-combined-ruleset" RParen => Command::UnstableCombinedRuleset(name, subrulesets), "rule" > > )?> )?> - => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { span: Span(filename, lo, hi), head: Actions::new(head), body }}, + => Command::Rule{ruleset: ruleset.unwrap_or("".into()), name: name.unwrap_or("".to_string()).into(), rule: Rule { span: Span(srcfile.clone(), lo, hi), head: Actions::new(head), body }}, "rewrite" >)?> )?> - => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), + => Command::Rewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(srcfile.clone(), lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }, subsume.is_some()), "birewrite" >)?> )?> - => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(filename, lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }), - "let" => Command::Action(Action::Let(Span(filename, lo, hi), name, expr)), + => Command::BiRewrite(ruleset.unwrap_or("".into()), Rewrite { span: Span(srcfile.clone(), lo, hi), lhs, rhs, conditions: conditions.unwrap_or_default() }), + "let" => Command::Action(Action::Let(Span(srcfile.clone(), lo, hi), name, expr)), => Command::Action(<>), "run" )?> => - Command::RunSchedule(Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( - Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset : "".into(), until })))), + Command::RunSchedule(Schedule::Repeat(Span(srcfile.clone(), lo, hi), limit, Box::new( + Schedule::Run(Span(srcfile.clone(), lo, hi), RunConfig { ruleset : "".into(), until })))), "run" )?> => - Command::RunSchedule(Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( - Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset, until })))), + Command::RunSchedule(Schedule::Repeat(Span(srcfile.clone(), lo, hi), limit, Box::new( + Schedule::Run(Span(srcfile.clone(), lo, hi), RunConfig { ruleset, until })))), LParen "simplify" RParen => Command::Simplify { expr, schedule }, - "calc" LParen RParen => Command::Calc(Span(filename, lo, hi), idents, exprs), + "calc" LParen RParen => Command::Calc(Span(srcfile.clone(), lo, hi), idents, exprs), LParen "query-extract" )?> RParen => Command::QueryExtract { expr, variants: variants.unwrap_or(0) }, - "check" => Command::Check(Span(filename, lo, hi), facts), + "check" => Command::Check(Span(srcfile.clone(), lo, hi), facts), LParen "check-proof" RParen => Command::CheckProof, "run-schedule" => - Command::RunSchedule(Schedule::Sequence(Span(filename, lo, hi), scheds)), + Command::RunSchedule(Schedule::Sequence(Span(srcfile.clone(), lo, hi), scheds)), LParen "print-stats" RParen => Command::PrintOverallStatistics, LParen "push" RParen => Command::Push(<>.unwrap_or(1)), LParen "pop" RParen => Command::Pop(<>.unwrap_or(1)), @@ -101,19 +101,19 @@ Command: Command = { Schedule: Schedule = { "saturate" => - Schedule::Saturate(Span(filename, lo, hi), Box::new( - Schedule::Sequence(Span(filename, lo, hi), scheds))), + Schedule::Saturate(Span(srcfile.clone(), lo, hi), Box::new( + Schedule::Sequence(Span(srcfile.clone(), lo, hi), scheds))), "seq" => - Schedule::Sequence(Span(filename, lo, hi), scheds), + Schedule::Sequence(Span(srcfile.clone(), lo, hi), scheds), "repeat" => - Schedule::Repeat(Span(filename, lo, hi), limit, Box::new( - Schedule::Sequence(Span(filename, lo, hi), scheds))), + Schedule::Repeat(Span(srcfile.clone(), lo, hi), limit, Box::new( + Schedule::Sequence(Span(srcfile.clone(), lo, hi), scheds))), "run" )?> => - Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset: "".into(), until }), + Schedule::Run(Span(srcfile.clone(), lo, hi), RunConfig { ruleset: "".into(), until }), "run" )?> => - Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset, until }), + Schedule::Run(Span(srcfile.clone(), lo, hi), RunConfig { ruleset, until }), => - Schedule::Run(Span(filename, lo, hi), RunConfig { ruleset: ident, until: None }), + Schedule::Run(Span(srcfile.clone(), lo, hi), RunConfig { ruleset: ident, until: None }), } Cost: Option = { @@ -122,18 +122,18 @@ Cost: Option = { } NonLetAction: Action = { - "set" LParen RParen => Action::Set ( Span(filename, lo, hi), f, args, v ), - "delete" LParen RParen => Action::Change ( Span(filename, lo, hi), Change::Delete, f, args), - "subsume" LParen RParen => Action::Change ( Span(filename, lo, hi), Change::Subsume, f, args), - "union" => Action::Union(Span(filename, lo, hi), e1, e2), - "panic" => Action::Panic(Span(filename, lo, hi), msg), - "extract" => Action::Extract(Span(filename, lo, hi), expr, Expr::Lit(Span(filename, lo, hi), Literal::Int(0))), - "extract" => Action::Extract(Span(filename, lo, hi), expr, variants), - => Action::Expr(Span(filename, lo, hi), e), + "set" LParen RParen => Action::Set ( Span(srcfile.clone(), lo, hi), f, args, v ), + "delete" LParen RParen => Action::Change ( Span(srcfile.clone(), lo, hi), Change::Delete, f, args), + "subsume" LParen RParen => Action::Change ( Span(srcfile.clone(), lo, hi), Change::Subsume, f, args), + "union" => Action::Union(Span(srcfile.clone(), lo, hi), e1, e2), + "panic" => Action::Panic(Span(srcfile.clone(), lo, hi), msg), + "extract" => Action::Extract(Span(srcfile.clone(), lo, hi), expr, Expr::Lit(Span(srcfile.clone(), lo, hi), Literal::Int(0))), + "extract" => Action::Extract(Span(srcfile.clone(), lo, hi), expr, variants), + => Action::Expr(Span(srcfile.clone(), lo, hi), e), } pub Action: Action = { - "let" => Action::Let(Span(filename, lo, hi), name, expr), + "let" => Action::Let(Span(srcfile.clone(), lo, hi), name, expr), => <>, } @@ -142,7 +142,7 @@ Name: Symbol = { "[" "]" => <> } pub Fact: Fact = { "=" => { es.push(e); - Fact::Eq(Span(filename, lo, hi), es) + Fact::Eq(Span(srcfile.clone(), lo, hi), es) }, => Fact::Fact(<>), } @@ -152,8 +152,8 @@ Schema: Schema = { } pub Expr: Expr = { - => Expr::Lit(Span(filename, lo, hi), lit), - => Expr::Var(Span(filename, lo, hi), id), + => Expr::Lit(Span(srcfile.clone(), lo, hi), lit), + => Expr::Var(Span(srcfile.clone(), lo, hi), id), => <>, }; @@ -171,7 +171,7 @@ Bool: bool = { } CallExpr: Expr = { - => Expr::Call(Span(filename, lo, hi), head, tail), + => Expr::Call(Span(srcfile.clone(), lo, hi), head, tail), } ExprList: Vec = { LParen RParen => sexps } diff --git a/src/ast/remove_globals.rs b/src/ast/remove_globals.rs index a9aade12..eca727df 100644 --- a/src/ast/remove_globals.rs +++ b/src/ast/remove_globals.rs @@ -126,7 +126,7 @@ impl<'a> GlobalRemover<'a> { // output is eq-able, so generate a union if ty.is_eq_sort() { GenericNCommand::CoreAction(GenericAction::Union( - span, + span.clone(), GenericExpr::Call(span, resolved_call, vec![]), remove_globals_expr(expr), )) diff --git a/src/constraint.rs b/src/constraint.rs index d5e8414d..a641d236 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -221,16 +221,16 @@ impl Assignment { typeinfo: &TypeInfo, ) -> ResolvedExpr { match &expr { - GenericExpr::Lit(span, literal) => ResolvedExpr::Lit(*span, literal.clone()), + GenericExpr::Lit(span, literal) => ResolvedExpr::Lit(span.clone(), literal.clone()), GenericExpr::Var(span, var) => { let global_ty = typeinfo.lookup_global(var); let ty = global_ty .clone() // Span is ignored when looking up atom_terms - .or_else(|| self.get(&AtomTerm::Var(*DUMMY_SPAN, *var)).cloned()) + .or_else(|| self.get(&AtomTerm::Var(DUMMY_SPAN.clone(), *var)).cloned()) .expect("All variables should be assigned before annotation"); ResolvedExpr::Var( - *span, + span.clone(), ResolvedVar { name: *var, sort: ty.clone(), @@ -255,13 +255,13 @@ impl Assignment { .iter() .map(|arg| arg.output_type(typeinfo)) .chain(once( - self.get(&AtomTerm::Var(*DUMMY_SPAN, *corresponding_var)) + self.get(&AtomTerm::Var(DUMMY_SPAN.clone(), *corresponding_var)) .unwrap() .clone(), )) .collect(); let resolved_call = ResolvedCall::from_resolution(head, &types, typeinfo); - GenericExpr::Call(*span, resolved_call, args) + GenericExpr::Call(span.clone(), resolved_call, args) } } } @@ -273,7 +273,7 @@ impl Assignment { ) -> ResolvedFact { match facts { GenericFact::Eq(span, facts) => ResolvedFact::Eq( - *span, + span.clone(), facts .iter() .map(|expr| self.annotate_expr(expr, typeinfo)) @@ -302,10 +302,10 @@ impl Assignment { match action { GenericAction::Let(span, var, expr) => { let ty = self - .get(&AtomTerm::Var(*span, *var)) + .get(&AtomTerm::Var(span.clone(), *var)) .expect("All variables should be assigned before annotation"); Ok(ResolvedAction::Let( - *span, + span.clone(), ResolvedVar { name: *var, sort: ty.clone(), @@ -338,7 +338,7 @@ impl Assignment { if !matches!(resolved_call, ResolvedCall::Func(_)) { return Err(TypeError::UnboundFunction(*head)); } - Ok(ResolvedAction::Set(*span, resolved_call, children, rhs)) + Ok(ResolvedAction::Set(span.clone(), resolved_call, children, rhs)) } // Note mapped_var for delete is a dummy variable that does not mean anything GenericAction::Change( @@ -362,25 +362,25 @@ impl Assignment { ResolvedCall::from_resolution_func_types(head, &types, typeinfo) .ok_or_else(|| TypeError::UnboundFunction(*head))?; Ok(ResolvedAction::Change( - *span, + span.clone(), *change, resolved_call, children.clone(), )) } GenericAction::Union(span, lhs, rhs) => Ok(ResolvedAction::Union( - *span, + span.clone(), self.annotate_expr(lhs, typeinfo), self.annotate_expr(rhs, typeinfo), )), GenericAction::Extract(span, lhs, rhs) => Ok(ResolvedAction::Extract( - *span, + span.clone(), self.annotate_expr(lhs, typeinfo), self.annotate_expr(rhs, typeinfo), )), - GenericAction::Panic(span, msg) => Ok(ResolvedAction::Panic(*span, msg.clone())), + GenericAction::Panic(span, msg) => Ok(ResolvedAction::Panic(span.clone(), msg.clone())), GenericAction::Expr(span, expr) => Ok(ResolvedAction::Expr( - *span, + span.clone(), self.annotate_expr(expr, typeinfo), )), } @@ -455,10 +455,10 @@ impl Problem { // bound vars are added to range match action { CoreAction::Let(span, var, _, _) => { - self.range.insert(AtomTerm::Var(*span, *var)); + self.range.insert(AtomTerm::Var(span.clone(), *var)); } CoreAction::LetAtomTerm(span, v, _) => { - self.range.insert(AtomTerm::Var(*span, *v)); + self.range.insert(AtomTerm::Var(span.clone(), *v)); } _ => (), } @@ -487,7 +487,7 @@ impl Problem { span: Span, sort: ArcSort, ) -> Result<(), TypeError> { - self.add_binding(AtomTerm::Var(span, var), sort); + self.add_binding(AtomTerm::Var(span.clone(), var), sort); self.range.insert(AtomTerm::Var(span, var)); Ok(()) } @@ -502,7 +502,7 @@ impl CoreAction { match self { CoreAction::Let(span, symbol, f, args) => { let mut args = args.clone(); - args.push(AtomTerm::Var(*span, *symbol)); + args.push(AtomTerm::Var(span.clone(), *symbol)); Ok(get_literal_and_global_constraints(&args, typeinfo) .chain(get_atom_application_constraints(f, &args, span, typeinfo)?) @@ -522,7 +522,7 @@ impl CoreAction { let mut args = args.clone(); // Add a dummy last output argument let var = symbol_gen.fresh(head); - args.push(AtomTerm::Var(*span, var)); + args.push(AtomTerm::Var(span.clone(), var)); Ok(get_literal_and_global_constraints(&args, typeinfo) .chain(get_atom_application_constraints( @@ -550,7 +550,7 @@ impl CoreAction { CoreAction::Panic(_ann, _) => Ok(vec![]), CoreAction::LetAtomTerm(span, v, at) => { Ok(get_literal_and_global_constraints(&[at.clone()], typeinfo) - .chain(once(Constraint::Eq(AtomTerm::Var(*span, *v), at.clone()))) + .chain(once(Constraint::Eq(AtomTerm::Var(span.clone(), *v), at.clone()))) .collect()) } } @@ -605,7 +605,7 @@ fn get_atom_application_constraints( constraints.push(Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - span: *span, + span: span.clone(), head: *head, args: args.to_vec(), }, @@ -696,7 +696,7 @@ impl TypeConstraint for SimpleTypeConstraint { vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - span: self.span, + span: self.span.clone(), head: self.name, args: arguments.to_vec(), }, @@ -772,7 +772,7 @@ impl TypeConstraint for AllEqualTypeConstraint { return vec![Constraint::Impossible( ImpossibleConstraint::ArityMismatch { atom: Atom { - span: self.span, + span: self.span.clone(), head: self.name, args: arguments.to_vec(), }, diff --git a/src/core.rs b/src/core.rs index 58b70dec..4e5da7f0 100644 --- a/src/core.rs +++ b/src/core.rs @@ -182,9 +182,9 @@ impl GenericAtomTerm { impl GenericAtomTerm { pub fn to_expr(&self) -> GenericExpr { match self { - GenericAtomTerm::Var(span, v) => GenericExpr::Var(*span, v.clone()), - GenericAtomTerm::Literal(span, l) => GenericExpr::Lit(*span, l.clone()), - GenericAtomTerm::Global(span, v) => GenericExpr::Var(*span, v.clone()), + GenericAtomTerm::Var(span, v) => GenericExpr::Var(span.clone(), v.clone()), + GenericAtomTerm::Literal(span, l) => GenericExpr::Lit(span.clone(), l.clone()), + GenericAtomTerm::Global(span, v) => GenericExpr::Var(span.clone(), v.clone()), } } } @@ -255,7 +255,7 @@ impl Atom { pub(crate) fn to_expr(&self) -> Expr { let n = self.args.len(); Expr::Call( - self.span, + self.span.clone(), self.head, self.args[0..n - 1] .iter() @@ -352,7 +352,7 @@ impl Query { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(_) => None, ResolvedCall::Primitive(head) => Some(GenericAtom { - span: atom.span, + span: atom.span.clone(), head: head.primitive.clone(), args: atom.args.clone(), }), @@ -362,7 +362,7 @@ impl Query { pub fn funcs(&self) -> impl Iterator> + '_ { self.atoms.iter().filter_map(|atom| match &atom.head { ResolvedCall::Func(head) => Some(GenericAtom { - span: atom.span, + span: atom.span.clone(), head: head.name, args: atom.args.clone(), }), @@ -405,7 +405,7 @@ where { pub(crate) fn subst(&mut self, subst: &HashMap>) { let actions = subst.iter().map(|(symbol, atom_term)| { - GenericCoreAction::LetAtomTerm(*atom_term.span(), symbol.clone(), atom_term.clone()) + GenericCoreAction::LetAtomTerm(atom_term.span().clone(), symbol.clone(), atom_term.clone()) }); let existing_actions = std::mem::take(&mut self.0); self.0 = actions.chain(existing_actions).collect(); @@ -447,13 +447,13 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::LetAtomTerm( - *span, + span.clone(), var.clone(), mapped_expr.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Let(*span, var.clone(), mapped_expr)); + .push(GenericAction::Let(span.clone(), var.clone(), mapped_expr)); binding.insert(var.clone()); } GenericAction::Set(span, head, args, expr) => { @@ -468,7 +468,7 @@ where expr.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Set( - *span, + span.clone(), head.clone(), mapped_args .iter() @@ -478,7 +478,7 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Set( - *span, + span.clone(), CorrespondingVar::new(head.clone(), v), mapped_args, mapped_expr, @@ -493,7 +493,7 @@ where mapped_args.push(mapped_arg); } norm_actions.push(GenericCoreAction::Change( - *span, + span.clone(), *change, head.clone(), mapped_args @@ -503,7 +503,7 @@ where )); let v = fresh_gen.fresh(head); mapped_actions.0.push(GenericAction::Change( - *span, + span.clone(), *change, CorrespondingVar::new(head.clone(), v), mapped_args, @@ -515,13 +515,13 @@ where let (actions2, mapped_e2) = e2.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions2.0); norm_actions.push(GenericCoreAction::Union( - *span, + span.clone(), mapped_e1.get_corresponding_var_or_lit(typeinfo), mapped_e2.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Union(*span, mapped_e1, mapped_e2)); + .push(GenericAction::Union(span.clone(), mapped_e1, mapped_e2)); } GenericAction::Extract(span, e, n) => { let (actions, mapped_e) = e.to_core_actions(typeinfo, binding, fresh_gen)?; @@ -529,19 +529,19 @@ where let (actions, mapped_n) = n.to_core_actions(typeinfo, binding, fresh_gen)?; norm_actions.extend(actions.0); norm_actions.push(GenericCoreAction::Extract( - *span, + span.clone(), mapped_e.get_corresponding_var_or_lit(typeinfo), mapped_n.get_corresponding_var_or_lit(typeinfo), )); mapped_actions .0 - .push(GenericAction::Extract(*span, mapped_e, mapped_n)); + .push(GenericAction::Extract(span.clone(), mapped_e, mapped_n)); } GenericAction::Panic(span, string) => { - norm_actions.push(GenericCoreAction::Panic(*span, string.clone())); + norm_actions.push(GenericCoreAction::Panic(span.clone(), string.clone())); mapped_actions .0 - .push(GenericAction::Panic(*span, string.clone())); + .push(GenericAction::Panic(span.clone(), string.clone())); } GenericAction::Expr(span, expr) => { let (actions, mapped_expr) = @@ -549,7 +549,7 @@ where norm_actions.extend(actions.0); mapped_actions .0 - .push(GenericAction::Expr(*span, mapped_expr)); + .push(GenericAction::Expr(span.clone(), mapped_expr)); } } } @@ -574,8 +574,8 @@ where Leaf: SymbolLike, { match self { - GenericExpr::Lit(span, lit) => (vec![], GenericExpr::Lit(*span, lit.clone())), - GenericExpr::Var(span, v) => (vec![], GenericExpr::Var(*span, v.clone())), + GenericExpr::Lit(span, lit) => (vec![], GenericExpr::Lit(span.clone(), lit.clone())), + GenericExpr::Var(span, v) => (vec![], GenericExpr::Var(span.clone(), v.clone())), GenericExpr::Call(span, f, children) => { let fresh = fresh_gen.fresh(f); let mut new_children = vec![]; @@ -589,17 +589,17 @@ where child_exprs.push(child_expr); } let args = { - new_children.push(GenericAtomTerm::Var(*span, fresh.clone())); + new_children.push(GenericAtomTerm::Var(span.clone(), fresh.clone())); new_children }; atoms.push(GenericAtom { - span: *span, + span: span.clone(), head: HeadOrEq::Symbol(f.clone()), args, }); ( atoms, - GenericExpr::Call(*span, CorrespondingVar::new(f.clone(), fresh), child_exprs), + GenericExpr::Call(span.clone(), CorrespondingVar::new(f.clone(), fresh), child_exprs), ) } } @@ -617,14 +617,14 @@ where match self { GenericExpr::Lit(span, lit) => Ok(( GenericCoreActions::default(), - GenericExpr::Lit(*span, lit.clone()), + GenericExpr::Lit(span.clone(), lit.clone()), )), GenericExpr::Var(span, v) => { let sym = v.to_symbol(); if binding.contains(v) || typeinfo.is_global(sym) { Ok(( GenericCoreActions::default(), - GenericExpr::Var(*span, v.clone()), + GenericExpr::Var(span.clone(), v.clone()), )) } else { Err(TypeError::Unbound(sym)) @@ -646,14 +646,14 @@ where binding.insert(var.clone()); norm_actions.push(GenericCoreAction::Let( - *span, + span.clone(), var.clone(), f.clone(), norm_args, )); Ok(( GenericCoreActions::new(norm_actions), - GenericExpr::Call(*span, CorrespondingVar::new(f.clone(), var), mapped_args), + GenericExpr::Call(span.clone(), CorrespondingVar::new(f.clone(), var), mapped_args), )) } } @@ -747,12 +747,12 @@ where None } else { Some(GenericAtom { - span: atom.span, + span: atom.span.clone(), head: value_eq(&atom.args[0], &atom.args[1]), args: vec![ atom.args[0].clone(), atom.args[1].clone(), - GenericAtomTerm::Literal(atom.span, Literal::Unit), + GenericAtomTerm::Literal(atom.span.clone(), Literal::Unit), ], }) } @@ -760,7 +760,7 @@ where } } HeadOrEq::Symbol(symbol) => Some(GenericAtom { - span: atom.span, + span: atom.span.clone(), head: symbol, args: atom.args, }), @@ -798,7 +798,7 @@ where let (head, _correspondence) = head.to_core_actions(typeinfo, &mut binding, &mut fresh_gen)?; Ok(GenericCoreRule { - span: self.span, + span: self.span.clone(), body, head, }) diff --git a/src/lib.rs b/src/lib.rs index 2c3ab0c2..4ffebec5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -301,7 +301,7 @@ impl Primitive { fn accept(&self, tys: &[Arc]) -> bool { let mut constraints = vec![]; let lits: Vec<_> = (0..tys.len()) - .map(|i| AtomTerm::Literal(*DUMMY_SPAN, Literal::Int(i as i64))) + .map(|i| AtomTerm::Literal(DUMMY_SPAN.clone(), Literal::Int(i as i64))) .collect(); for (lit, ty) in lits.iter().zip(tys.iter()) { constraints.push(Constraint::Assign(lit.clone(), ty.clone())) @@ -371,7 +371,7 @@ impl PrimitiveLike for SimplePrimitive { .chain(once(&self.output as &ArcSort)) .cloned() .collect(); - SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() + SimpleTypeConstraint::new(self.name(), sorts, span.clone()).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { (self.f)(values) @@ -1137,7 +1137,7 @@ impl EGraph { pub fn eval_expr(&mut self, expr: &Expr) -> Result<(ArcSort, Value), Error> { let fresh_name = self.desugar.get_fresh(); - let command = Command::Action(Action::Let(*DUMMY_SPAN, fresh_name, expr.clone())); + let command = Command::Action(Action::Let(DUMMY_SPAN.clone(), fresh_name, expr.clone())); self.run_program(vec![command])?; // find the table with the same name as the fresh name let func = self.functions.get(&fresh_name).unwrap(); @@ -1213,7 +1213,7 @@ impl EGraph { fn check_facts(&mut self, span: &Span, facts: &[ResolvedFact]) -> Result<(), Error> { let rule = ast::ResolvedRule { - span: *span, + span: span.clone(), head: ResolvedActions::default(), body: facts.to_vec(), }; @@ -1388,7 +1388,7 @@ impl EGraph { let mut contents = String::new(); f.read_to_string(&mut contents).unwrap(); - let span: Span = *DUMMY_SPAN; + let span: Span = DUMMY_SPAN.clone(); let mut actions: Vec = vec![]; let mut str_buf: Vec<&str> = vec![]; for line in contents.lines() { @@ -1400,10 +1400,10 @@ impl EGraph { let parse = |s: &str| -> Expr { match s.parse::() { - Ok(i) => Expr::Lit(span, Literal::Int(i)), + Ok(i) => Expr::Lit(span.clone(), Literal::Int(i)), Err(_) => match s.parse::() { - Ok(f) => Expr::Lit(span, Literal::F64(f.into())), - Err(_) => Expr::Lit(span, Literal::String(s.into())), + Ok(f) => Expr::Lit(span.clone(), Literal::F64(f.into())), + Err(_) => Expr::Lit(span.clone(), Literal::String(s.into())), }, } }; @@ -1412,10 +1412,10 @@ impl EGraph { actions.push( if function_type.is_datatype || function_type.output.name() == UNIT_SYM.into() { - Action::Expr(span, Expr::Call(span, func_name, exprs)) + Action::Expr(span.clone(), Expr::Call(span.clone(), func_name, exprs)) } else { let out = exprs.pop().unwrap(); - Action::Set(span, func_name, exprs, out) + Action::Set(span.clone(), func_name, exprs, out) }, ); } @@ -1488,7 +1488,7 @@ impl EGraph { pub fn parse_program( &self, - filename: Option, + filename: Option, input: &str, ) -> Result, Error> { self.desugar.parse_program(filename, input) @@ -1496,7 +1496,7 @@ impl EGraph { pub fn parse_and_run_program( &mut self, - filename: Option, + filename: Option, input: &str, ) -> Result, Error> { let parsed = self.desugar.parse_program(filename, input)?; @@ -1640,7 +1640,7 @@ mod tests { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.clone(), self.ele.clone()], - *span, + span.clone(), ) .into_box() } diff --git a/src/sort/bool.rs b/src/sort/bool.rs index 2e4160ec..aa1e8bb5 100644 --- a/src/sort/bool.rs +++ b/src/sort/bool.rs @@ -35,7 +35,7 @@ impl Sort for BoolSort { assert!(value.tag == self.name()); ( 1, - GenericExpr::Lit(*DUMMY_SPAN, Literal::Bool(value.bits > 0)), + GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::Bool(value.bits > 0)), ) } } diff --git a/src/sort/f64.rs b/src/sort/f64.rs index 3d81be5e..7b960615 100755 --- a/src/sort/f64.rs +++ b/src/sort/f64.rs @@ -58,7 +58,7 @@ impl Sort for F64Sort { ( 1, GenericExpr::Lit( - *DUMMY_SPAN, + DUMMY_SPAN.clone(), Literal::F64(OrderedFloat(f64::from_bits(value.bits))), ), ) diff --git a/src/sort/fn.rs b/src/sort/fn.rs index f423a087..fdd4efff 100644 --- a/src/sort/fn.rs +++ b/src/sort/fn.rs @@ -178,7 +178,7 @@ impl Sort for FunctionSort { let (cost, args) = inputs.into_iter().try_fold( ( 1usize, - vec![GenericExpr::Lit(*DUMMY_SPAN, Literal::String(name))], + vec![GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::String(name))], ), |(cost, mut args), (sort, value)| { let (new_cost, term) = extractor.find_best(value, termdag, &sort)?; @@ -225,7 +225,7 @@ impl TypeConstraint for FunctionCTorTypeConstraint { vec![Constraint::Impossible( constraint::ImpossibleConstraint::ArityMismatch { atom: core::Atom { - span: self.span, + span: self.span.clone(), head: self.name, args: arguments.to_vec(), }, @@ -262,7 +262,7 @@ impl PrimitiveLike for Ctor { name: self.name, function: self.function.clone(), string: self.string.clone(), - span: *span, + span: span.clone(), }) } @@ -295,7 +295,7 @@ impl PrimitiveLike for Apply { let mut sorts: Vec = vec![self.function.clone()]; sorts.extend(self.function.inputs.clone()); sorts.push(self.function.output.clone()); - SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() + SimpleTypeConstraint::new(self.name(), sorts, span.clone()).into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -339,9 +339,9 @@ fn call_fn(egraph: &mut EGraph, name: &Symbol, types: Vec, args: Vec Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.string.clone()) .with_exact_length(3) .with_output_sort(self.int.clone()) diff --git a/src/sort/macros.rs b/src/sort/macros.rs index 723ec28a..086c2045 100644 --- a/src/sort/macros.rs +++ b/src/sort/macros.rs @@ -45,7 +45,7 @@ macro_rules! add_primitives { span: &Span ) -> Box { let sorts = vec![$(self.$param.clone(),)* self.__out.clone() as ArcSort]; - SimpleTypeConstraint::new(self.name(), sorts, *span).into_box() + SimpleTypeConstraint::new(self.name(), sorts, span.clone()).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/map.rs b/src/sort/map.rs index 1267e9bc..61a637a4 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -211,7 +211,7 @@ impl PrimitiveLike for MapRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], span.clone()) .into_box() } @@ -245,7 +245,7 @@ impl PrimitiveLike for TermOrderingMin { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_exact_length(3) .into_box() } @@ -268,7 +268,7 @@ impl PrimitiveLike for TermOrderingMax { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_exact_length(3) .into_box() } @@ -289,7 +289,7 @@ impl PrimitiveLike for Ctor { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.map.clone()], span.clone()).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -317,7 +317,7 @@ impl PrimitiveLike for Insert { self.map.value(), self.map.clone(), ], - *span, + span.clone(), ) .into_box() } @@ -343,7 +343,7 @@ impl PrimitiveLike for Get { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.map.value()], - *span, + span.clone(), ) .into_box() } @@ -369,7 +369,7 @@ impl PrimitiveLike for NotContains { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -399,7 +399,7 @@ impl PrimitiveLike for Contains { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -428,7 +428,7 @@ impl PrimitiveLike for Remove { SimpleTypeConstraint::new( self.name(), vec![self.map.clone(), self.map.key(), self.map.clone()], - *span, + span.clone(), ) .into_box() } @@ -452,7 +452,7 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], span.clone()) .into_box() } diff --git a/src/sort/mod.rs b/src/sort/mod.rs index 1890243c..e758a52c 100644 --- a/src/sort/mod.rs +++ b/src/sort/mod.rs @@ -171,7 +171,7 @@ impl PrimitiveLike for ValueEq { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_exact_length(3) .with_output_sort(self.unit.clone()) .into_box() diff --git a/src/sort/rational.rs b/src/sort/rational.rs index b63ecc9b..739faf07 100644 --- a/src/sort/rational.rs +++ b/src/sort/rational.rs @@ -120,8 +120,8 @@ impl Sort for RationalSort { Expr::call_no_span( "rational", vec![ - GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(numer)), - GenericExpr::Lit(*DUMMY_SPAN, Literal::Int(denom)), + GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::Int(numer)), + GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::Int(denom)), ], ), ) diff --git a/src/sort/set.rs b/src/sort/set.rs index 7fc58280..4bd471b0 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -223,7 +223,7 @@ impl PrimitiveLike for SetOf { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.set.element()) .with_output_sort(self.set.clone()) .into_box() @@ -246,7 +246,7 @@ impl PrimitiveLike for Ctor { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.set.clone()], span.clone()).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -266,7 +266,7 @@ impl PrimitiveLike for SetRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], span.clone()) .into_box() } @@ -294,7 +294,7 @@ impl PrimitiveLike for Insert { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.set.clone()], - *span, + span.clone(), ) .into_box() } @@ -321,7 +321,7 @@ impl PrimitiveLike for NotContains { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -351,7 +351,7 @@ impl PrimitiveLike for Contains { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -380,7 +380,7 @@ impl PrimitiveLike for Union { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], - *span, + span.clone(), ) .into_box() } @@ -407,7 +407,7 @@ impl PrimitiveLike for Intersect { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], - *span, + span.clone(), ) .into_box() } @@ -433,7 +433,7 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()], span.clone()) .into_box() } @@ -457,7 +457,7 @@ impl PrimitiveLike for Get { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.i64.clone(), self.set.element()], - *span, + span.clone(), ) .into_box() } @@ -483,7 +483,7 @@ impl PrimitiveLike for Remove { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.element(), self.set.clone()], - *span, + span.clone(), ) .into_box() } @@ -509,7 +509,7 @@ impl PrimitiveLike for Diff { SimpleTypeConstraint::new( self.name(), vec![self.set.clone(), self.set.clone(), self.set.clone()], - *span, + span.clone(), ) .into_box() } diff --git a/src/sort/string.rs b/src/sort/string.rs index 23afea9d..4556bc4c 100644 --- a/src/sort/string.rs +++ b/src/sort/string.rs @@ -27,7 +27,7 @@ impl Sort for StringSort { fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name); let sym = Symbol::from(NonZeroU32::new(value.bits as _).unwrap()); - (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::String(sym))) + (1, GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::String(sym))) } fn register_primitives(self: Arc, typeinfo: &mut TypeInfo) { @@ -72,7 +72,7 @@ impl PrimitiveLike for Add { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.string.clone()) .into_box() } @@ -99,7 +99,7 @@ impl PrimitiveLike for Replace { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.string.clone()) .with_exact_length(4) .into_box() diff --git a/src/sort/unit.rs b/src/sort/unit.rs index 730b8e5a..31caf14a 100644 --- a/src/sort/unit.rs +++ b/src/sort/unit.rs @@ -27,7 +27,7 @@ impl Sort for UnitSort { fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert_eq!(value.tag, self.name); - (1, GenericExpr::Lit(*DUMMY_SPAN, Literal::Unit)) + (1, GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::Unit)) } } @@ -49,7 +49,7 @@ impl PrimitiveLike for NotEqualPrimitive { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_exact_length(3) .with_output_sort(self.unit.clone()) .into_box() diff --git a/src/sort/vec.rs b/src/sort/vec.rs index b1cb5c60..c113a952 100644 --- a/src/sort/vec.rs +++ b/src/sort/vec.rs @@ -230,7 +230,7 @@ impl PrimitiveLike for VecRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], span.clone()) .into_box() } @@ -253,7 +253,7 @@ impl PrimitiveLike for VecOf { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.vec.element()) .with_output_sort(self.vec.clone()) .into_box() @@ -276,7 +276,7 @@ impl PrimitiveLike for Append { } fn get_type_constraints(&self, span: &Span) -> Box { - AllEqualTypeConstraint::new(self.name(), *span) + AllEqualTypeConstraint::new(self.name(), span.clone()) .with_all_arguments_sort(self.vec.clone()) .into_box() } @@ -298,7 +298,7 @@ impl PrimitiveLike for Ctor { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone()], *span).into_box() + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone()], span.clone()).into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -321,7 +321,7 @@ impl PrimitiveLike for Push { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.vec.clone()], - *span, + span.clone(), ) .into_box() } @@ -344,7 +344,7 @@ impl PrimitiveLike for Pop { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], span.clone()) .into_box() } @@ -370,7 +370,7 @@ impl PrimitiveLike for NotContains { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -400,7 +400,7 @@ impl PrimitiveLike for Contains { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.vec.element(), self.unit.clone()], - *span, + span.clone(), ) .into_box() } @@ -427,7 +427,7 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.i64.clone()], *span) + SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.i64.clone()], span.clone()) .into_box() } @@ -452,7 +452,7 @@ impl PrimitiveLike for Get { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.i64.clone(), self.vec.element()], - *span, + span.clone(), ) .into_box() } @@ -484,7 +484,7 @@ impl PrimitiveLike for Set { self.vec.element.clone(), self.vec.clone(), ], - *span, + span.clone(), ) .into_box() } @@ -512,7 +512,7 @@ impl PrimitiveLike for Remove { SimpleTypeConstraint::new( self.name(), vec![self.vec.clone(), self.i64.clone(), self.vec.clone()], - *span, + span.clone(), ) .into_box() } diff --git a/src/termdag.rs b/src/termdag.rs index 07f06843..5f0d47c8 100644 --- a/src/termdag.rs +++ b/src/termdag.rs @@ -236,7 +236,7 @@ mod tests { let (td, t) = parse_term(s); match_term_app!(t; { ("f", [_, x, _, _]) => - assert_eq!(td.term_to_expr(&td.get(*x)), ast::GenericExpr::Var(*DUMMY_SPAN, Symbol::new("x"))), + assert_eq!(td.term_to_expr(&td.get(*x)), ast::GenericExpr::Var(DUMMY_SPAN.clone(), Symbol::new("x"))), (head, _) => panic!("unexpected head {}, in {}:{}:{}", head, file!(), line!(), column!()) }) } diff --git a/src/typechecking.rs b/src/typechecking.rs index 4adb366a..0a6a04fc 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -190,13 +190,13 @@ impl TypeInfo { // not a global reference, but a global binding is_global_ref: false, }; - ResolvedNCommand::CoreAction(ResolvedAction::Let(*span, var, expr)) + ResolvedNCommand::CoreAction(ResolvedAction::Let(span.clone(), var, expr)) } NCommand::CoreAction(action) => { ResolvedNCommand::CoreAction(self.typecheck_action(action, &Default::default())?) } NCommand::Check(span, facts) => { - ResolvedNCommand::Check(*span, self.typecheck_facts(facts)?) + ResolvedNCommand::Check(span.clone(), self.typecheck_facts(facts)?) } NCommand::Fail(cmd) => ResolvedNCommand::Fail(Box::new(self.typecheck_command(cmd)?)), NCommand::RunSchedule(schedule) => { @@ -253,8 +253,8 @@ impl TypeInfo { } let mut bound_vars = IndexMap::default(); let output_type = self.sorts.get(&fdecl.schema.output).unwrap(); - bound_vars.insert("old".into(), (*DUMMY_SPAN, output_type.clone())); - bound_vars.insert("new".into(), (*DUMMY_SPAN, output_type.clone())); + bound_vars.insert("old".into(), (DUMMY_SPAN.clone(), output_type.clone())); + bound_vars.insert("new".into(), (DUMMY_SPAN.clone(), output_type.clone())); Ok(ResolvedFunctionDecl { name: fdecl.name, @@ -278,7 +278,7 @@ impl TypeInfo { fn typecheck_schedule(&self, schedule: &Schedule) -> Result { let schedule = match schedule { Schedule::Repeat(span, times, schedule) => ResolvedSchedule::Repeat( - *span, + span.clone(), *times, Box::new(self.typecheck_schedule(schedule)?), ), @@ -287,10 +287,10 @@ impl TypeInfo { .iter() .map(|schedule| self.typecheck_schedule(schedule)) .collect::, _>>()?; - ResolvedSchedule::Sequence(*span, schedules) + ResolvedSchedule::Sequence(span.clone(), schedules) } Schedule::Saturate(span, schedule) => { - ResolvedSchedule::Saturate(*span, Box::new(self.typecheck_schedule(schedule)?)) + ResolvedSchedule::Saturate(span.clone(), Box::new(self.typecheck_schedule(schedule)?)) } Schedule::Run(span, RunConfig { ruleset, until }) => { let until = until @@ -298,7 +298,7 @@ impl TypeInfo { .map(|facts| self.typecheck_facts(facts)) .transpose()?; ResolvedSchedule::Run( - *span, + span.clone(), ResolvedRunConfig { ruleset: *ruleset, until, @@ -347,7 +347,7 @@ impl TypeInfo { let mut problem = Problem::default(); problem.add_rule( &CoreRule { - span: *span, + span: span.clone(), body: query, head: actions, }, @@ -362,7 +362,7 @@ impl TypeInfo { let actions: ResolvedActions = assignment.annotate_actions(&mapped_action, self)?; Ok(ResolvedRule { - span: *span, + span: span.clone(), body, head: actions, }) @@ -396,7 +396,7 @@ impl TypeInfo { // add bindings from the context for (var, (span, sort)) in binding { - problem.assign_local_var_type(*var, *span, sort.clone())?; + problem.assign_local_var_type(*var, span.clone(), sort.clone())?; } let assignment = problem @@ -412,7 +412,7 @@ impl TypeInfo { expr: &Expr, binding: &IndexMap, ) -> Result { - let action = Action::Expr(*DUMMY_SPAN, expr.clone()); + let action = Action::Expr(DUMMY_SPAN.clone(), expr.clone()); let typechecked_action = self.typecheck_action(&action, binding)?; match typechecked_action { ResolvedAction::Expr(_, expr) => Ok(expr), From bc38366157419c9609dcbaee8bb7ea4d47a8ee76 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 23 Jul 2024 23:25:23 -0700 Subject: [PATCH 15/16] fix test --- src/ast/desugar.rs | 2 +- src/ast/expr.rs | 2 +- tests/files.rs | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index e1dccfff..f26302f9 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -262,7 +262,7 @@ pub(crate) fn desugar_command( let s = std::fs::read_to_string(&file) .unwrap_or_else(|_| panic!("Failed to read file {file}")); return desugar_commands( - desugar.parse_program(Some(file.into()), &s)?, + desugar.parse_program(Some(file), &s)?, desugar, get_all_proofs, seminaive_transform, diff --git a/src/ast/expr.rs b/src/ast/expr.rs index a73477bf..53201fdb 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -282,7 +282,7 @@ where pub(crate) fn parse_expr(s: &str) -> Result> { let parser = ast::parse::ExprParser::new(); parser - .parse(&SrcFile::dummy(), s) + .parse(&DUMMY_FILE, s) .map_err(|e| e.map_token(|tok| tok.to_string())) } diff --git a/tests/files.rs b/tests/files.rs index 5eb69300..6539b2f9 100644 --- a/tests/files.rs +++ b/tests/files.rs @@ -2,7 +2,6 @@ use std::path::PathBuf; use egglog::*; use libtest_mimic::Trial; -use symbol_table::GlobalSymbol as Symbol; #[derive(Clone)] struct Run { @@ -18,7 +17,7 @@ impl Run { if !self.resugar { self.test_program( - self.path.to_str().map(Symbol::from), + self.path.to_str().map(String::from), &program, "Top level error", ); @@ -27,7 +26,7 @@ impl Run { egraph.run_mode = RunMode::ShowDesugaredEgglog; egraph.set_reserved_symbol("__".into()); let desugared_str = egraph - .parse_and_run_program(self.path.to_str().map(Symbol::from), &program) + .parse_and_run_program(self.path.to_str().map(String::from), &program) .unwrap() .join("\n"); @@ -39,7 +38,7 @@ impl Run { } } - fn test_program(&self, filename: Option, program: &str, message: &str) { + fn test_program(&self, filename: Option, program: &str, message: &str) { let mut egraph = EGraph::default(); egraph.set_reserved_symbol("___".into()); match egraph.parse_and_run_program(filename, program) { From bb24033b1081a0194056509bf318291469e90f81 Mon Sep 17 00:00:00 2001 From: Yihong Zhang Date: Tue, 23 Jul 2024 23:26:10 -0700 Subject: [PATCH 16/16] fmt --- src/ast/desugar.rs | 25 ++++++++++++++++++++----- src/ast/expr.rs | 6 +++++- src/ast/mod.rs | 36 ++++++++++++++++++++++++------------ src/constraint.rs | 12 ++++++++++-- src/core.rs | 26 ++++++++++++++++++++------ src/sort/map.rs | 16 ++++++++++++---- src/sort/set.rs | 16 ++++++++++++---- src/sort/string.rs | 5 ++++- src/sort/vec.rs | 24 ++++++++++++++++++------ src/typechecking.rs | 7 ++++--- 10 files changed, 129 insertions(+), 44 deletions(-) diff --git a/src/ast/desugar.rs b/src/ast/desugar.rs index f26302f9..4fe3fc1e 100644 --- a/src/ast/desugar.rs +++ b/src/ast/desugar.rs @@ -55,8 +55,12 @@ fn desugar_rewrite( if subsume { match &rewrite.lhs { Expr::Call(_, f, args) => { - head.0 - .push(Action::Change(span.clone(), Change::Subsume, *f, args.to_vec())); + head.0.push(Action::Change( + span.clone(), + Change::Subsume, + *f, + args.to_vec(), + )); } _ => { panic!("Subsumed rewrite must have a function call on the lhs"); @@ -155,7 +159,11 @@ fn desugar_simplify(desugar: &mut Desugar, expr: &Expr, schedule: &Schedule) -> let span = expr.span(); let mut res = vec![NCommand::Push(1)]; let lhs = desugar.get_fresh(); - res.push(NCommand::CoreAction(Action::Let(span.clone(), lhs, expr.clone()))); + res.push(NCommand::CoreAction(Action::Let( + span.clone(), + lhs, + expr.clone(), + ))); res.push(NCommand::RunSchedule(schedule.clone())); res.extend( desugar_command( @@ -212,7 +220,10 @@ pub(crate) fn desugar_calc( span.clone(), RunConfig { ruleset: "".into(), - until: Some(vec![Fact::Eq(span.clone(), vec![expr1.clone(), expr2.clone()])]), + until: Some(vec![Fact::Eq( + span.clone(), + vec![expr1.clone(), expr2.clone()], + )]), }, )), ))); @@ -440,7 +451,11 @@ impl Desugar { unextractable: false, ignore_viz: false, }), - NCommand::CoreAction(Action::Let(span.clone(), name, Expr::Call(span.clone(), fresh, vec![]))), + NCommand::CoreAction(Action::Let( + span.clone(), + name, + Expr::Call(span.clone(), fresh, vec![]), + )), ] } diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 53201fdb..83f96566 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -141,7 +141,11 @@ impl ResolvedExpr { impl Expr { pub fn call_no_span(op: impl Into, children: impl IntoIterator) -> Self { - Self::Call(DUMMY_SPAN.clone(), op.into(), children.into_iter().collect()) + Self::Call( + DUMMY_SPAN.clone(), + op.into(), + children.into_iter().collect(), + ) } pub fn lit_no_span(lit: impl Into) -> Self { diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 9d715d1d..30e49bc6 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -70,11 +70,7 @@ lazy_static! { name: DUMMY_FILENAME.to_string(), contents: None }); - pub(crate) static ref DUMMY_SPAN: Span = Span( - DUMMY_FILE.clone(), - 0, - 0 - ); + pub(crate) static ref DUMMY_SPAN: Span = Span(DUMMY_FILE.clone(), 0, 0); } pub type NCommand = GenericNCommand; @@ -162,7 +158,9 @@ where GenericNCommand::RunSchedule(schedule) => GenericCommand::RunSchedule(schedule.clone()), GenericNCommand::PrintOverallStatistics => GenericCommand::PrintOverallStatistics, GenericNCommand::CoreAction(action) => GenericCommand::Action(action.clone()), - GenericNCommand::Check(span, facts) => GenericCommand::Check(span.clone(), facts.clone()), + GenericNCommand::Check(span, facts) => { + GenericCommand::Check(span.clone(), facts.clone()) + } GenericNCommand::CheckProof => GenericCommand::CheckProof, GenericNCommand::PrintTable(name, n) => GenericCommand::PrintFunction(*name, *n), GenericNCommand::PrintSize(name) => GenericCommand::PrintSize(*name), @@ -1125,7 +1123,9 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> GenericFact { match self { - GenericFact::Eq(span, exprs) => GenericFact::Eq(span.clone(), exprs.iter().map(f).collect()), + GenericFact::Eq(span, exprs) => { + GenericFact::Eq(span.clone(), exprs.iter().map(f).collect()) + } GenericFact::Fact(expr) => GenericFact::Fact(f(expr)), } } @@ -1340,15 +1340,27 @@ where f: &mut impl FnMut(&GenericExpr) -> GenericExpr, ) -> Self { match self { - GenericAction::Let(span, lhs, rhs) => GenericAction::Let(span.clone(), lhs.clone(), f(rhs)), + GenericAction::Let(span, lhs, rhs) => { + GenericAction::Let(span.clone(), lhs.clone(), f(rhs)) + } GenericAction::Set(span, lhs, args, rhs) => { let right = f(rhs); - GenericAction::Set(span.clone(), lhs.clone(), args.iter().map(f).collect(), right) + GenericAction::Set( + span.clone(), + lhs.clone(), + args.iter().map(f).collect(), + right, + ) } - GenericAction::Change(span, change, lhs, args) => { - GenericAction::Change(span.clone(), *change, lhs.clone(), args.iter().map(f).collect()) + GenericAction::Change(span, change, lhs, args) => GenericAction::Change( + span.clone(), + *change, + lhs.clone(), + args.iter().map(f).collect(), + ), + GenericAction::Union(span, lhs, rhs) => { + GenericAction::Union(span.clone(), f(lhs), f(rhs)) } - GenericAction::Union(span, lhs, rhs) => GenericAction::Union(span.clone(), f(lhs), f(rhs)), GenericAction::Extract(span, expr, variants) => { GenericAction::Extract(span.clone(), f(expr), f(variants)) } diff --git a/src/constraint.rs b/src/constraint.rs index a641d236..8c94f888 100644 --- a/src/constraint.rs +++ b/src/constraint.rs @@ -338,7 +338,12 @@ impl Assignment { if !matches!(resolved_call, ResolvedCall::Func(_)) { return Err(TypeError::UnboundFunction(*head)); } - Ok(ResolvedAction::Set(span.clone(), resolved_call, children, rhs)) + Ok(ResolvedAction::Set( + span.clone(), + resolved_call, + children, + rhs, + )) } // Note mapped_var for delete is a dummy variable that does not mean anything GenericAction::Change( @@ -550,7 +555,10 @@ impl CoreAction { CoreAction::Panic(_ann, _) => Ok(vec![]), CoreAction::LetAtomTerm(span, v, at) => { Ok(get_literal_and_global_constraints(&[at.clone()], typeinfo) - .chain(once(Constraint::Eq(AtomTerm::Var(span.clone(), *v), at.clone()))) + .chain(once(Constraint::Eq( + AtomTerm::Var(span.clone(), *v), + at.clone(), + ))) .collect()) } } diff --git a/src/core.rs b/src/core.rs index 4e5da7f0..c64dc2b3 100644 --- a/src/core.rs +++ b/src/core.rs @@ -405,7 +405,11 @@ where { pub(crate) fn subst(&mut self, subst: &HashMap>) { let actions = subst.iter().map(|(symbol, atom_term)| { - GenericCoreAction::LetAtomTerm(atom_term.span().clone(), symbol.clone(), atom_term.clone()) + GenericCoreAction::LetAtomTerm( + atom_term.span().clone(), + symbol.clone(), + atom_term.clone(), + ) }); let existing_actions = std::mem::take(&mut self.0); self.0 = actions.chain(existing_actions).collect(); @@ -451,9 +455,11 @@ where var.clone(), mapped_expr.get_corresponding_var_or_lit(typeinfo), )); - mapped_actions - .0 - .push(GenericAction::Let(span.clone(), var.clone(), mapped_expr)); + mapped_actions.0.push(GenericAction::Let( + span.clone(), + var.clone(), + mapped_expr, + )); binding.insert(var.clone()); } GenericAction::Set(span, head, args, expr) => { @@ -599,7 +605,11 @@ where }); ( atoms, - GenericExpr::Call(span.clone(), CorrespondingVar::new(f.clone(), fresh), child_exprs), + GenericExpr::Call( + span.clone(), + CorrespondingVar::new(f.clone(), fresh), + child_exprs, + ), ) } } @@ -653,7 +663,11 @@ where )); Ok(( GenericCoreActions::new(norm_actions), - GenericExpr::Call(span.clone(), CorrespondingVar::new(f.clone(), var), mapped_args), + GenericExpr::Call( + span.clone(), + CorrespondingVar::new(f.clone(), var), + mapped_args, + ), )) } } diff --git a/src/sort/map.rs b/src/sort/map.rs index 61a637a4..a0f9b416 100644 --- a/src/sort/map.rs +++ b/src/sort/map.rs @@ -211,8 +211,12 @@ impl PrimitiveLike for MapRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.map.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.map.clone(), self.map.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -452,8 +456,12 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.map.clone(), self.i64.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.map.clone(), self.i64.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/set.rs b/src/sort/set.rs index 4bd471b0..99e238a5 100644 --- a/src/sort/set.rs +++ b/src/sort/set.rs @@ -266,8 +266,12 @@ impl PrimitiveLike for SetRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.set.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.set.clone(), self.set.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -433,8 +437,12 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.set.clone(), self.i64.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.set.clone(), self.i64.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/sort/string.rs b/src/sort/string.rs index 4556bc4c..ce115d6f 100644 --- a/src/sort/string.rs +++ b/src/sort/string.rs @@ -27,7 +27,10 @@ impl Sort for StringSort { fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) { assert!(value.tag == self.name); let sym = Symbol::from(NonZeroU32::new(value.bits as _).unwrap()); - (1, GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::String(sym))) + ( + 1, + GenericExpr::Lit(DUMMY_SPAN.clone(), Literal::String(sym)), + ) } fn register_primitives(self: Arc, typeinfo: &mut TypeInfo) { diff --git a/src/sort/vec.rs b/src/sort/vec.rs index c113a952..b616889d 100644 --- a/src/sort/vec.rs +++ b/src/sort/vec.rs @@ -230,8 +230,12 @@ impl PrimitiveLike for VecRebuild { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.vec.clone(), self.vec.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], egraph: Option<&mut EGraph>) -> Option { @@ -344,8 +348,12 @@ impl PrimitiveLike for Pop { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.vec.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.vec.clone(), self.vec.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { @@ -427,8 +435,12 @@ impl PrimitiveLike for Length { } fn get_type_constraints(&self, span: &Span) -> Box { - SimpleTypeConstraint::new(self.name(), vec![self.vec.clone(), self.i64.clone()], span.clone()) - .into_box() + SimpleTypeConstraint::new( + self.name(), + vec![self.vec.clone(), self.i64.clone()], + span.clone(), + ) + .into_box() } fn apply(&self, values: &[Value], _egraph: Option<&mut EGraph>) -> Option { diff --git a/src/typechecking.rs b/src/typechecking.rs index 0a6a04fc..56c2c0ad 100644 --- a/src/typechecking.rs +++ b/src/typechecking.rs @@ -289,9 +289,10 @@ impl TypeInfo { .collect::, _>>()?; ResolvedSchedule::Sequence(span.clone(), schedules) } - Schedule::Saturate(span, schedule) => { - ResolvedSchedule::Saturate(span.clone(), Box::new(self.typecheck_schedule(schedule)?)) - } + Schedule::Saturate(span, schedule) => ResolvedSchedule::Saturate( + span.clone(), + Box::new(self.typecheck_schedule(schedule)?), + ), Schedule::Run(span, RunConfig { ruleset, until }) => { let until = until .as_ref()