diff --git a/telamon-gen/src/ast/constraint.rs b/telamon-gen/src/ast/constraint.rs deleted file mode 100644 index 0aae4b752..000000000 --- a/telamon-gen/src/ast/constraint.rs +++ /dev/null @@ -1,38 +0,0 @@ -use super::VarDef; -use super::Condition; -use super::ir; - -/// A constraint that must be enforced by the IR. -#[derive(Debug, Clone)] -pub struct Constraint { - /// Variables for which the conditions must be respected. - pub forall_vars: Vec, - /// Conjunction of disjuction of condition that must be respected. - pub disjunctions: Vec>, - /// Indicates if the constraint should restrict fragile values. - pub restrict_fragile: bool, -} - -impl Constraint { - /// Creates a new constraint. - pub fn new(forall_vars: Vec, disjunctions: Vec>) -> Self { - Constraint { forall_vars, disjunctions, restrict_fragile: true } - } - - /// Type check the constraint. - fn type_check(self, ir_desc: &ir::IrDesc) -> Vec { - let mut var_map = VarMap::default(); - let sets = self.forall_vars.into_iter() - .map(|v| var_map.decl_forall(ir_desc, v)).collect_vec(); - let restrict_fragile = self.restrict_fragile; - self.disjunctions.into_iter().map(|disjuction| { - let mut inputs = Vec::new(); - let conditions = disjuction.into_iter() - .map(|x| x.type_check(ir_desc, &var_map, &mut inputs)).collect(); - TypedConstraint { - vars: sets.clone(), - restrict_fragile, inputs, conditions, - } - }).collect_vec() - } -} diff --git a/telamon-gen/src/ast/context.rs b/telamon-gen/src/ast/context.rs index 648a3b717..84d9a3b9c 100644 --- a/telamon-gen/src/ast/context.rs +++ b/telamon-gen/src/ast/context.rs @@ -79,7 +79,7 @@ impl TypingContext { quotient: Option) { trace!("defining set {}", name); let mut var_map = VarMap::default(); - let arg_name = arg_def.as_ref().map(|var| "$".to_string() + &var.name); + let arg_name = arg_def.as_ref().map(|var| "$".to_string() + &var.name.data); let arg = arg_def.clone().map(|arg| var_map.decl_argument(&self.ir_desc, arg)); let superset = superset.map(|set| set.type_check(&self.ir_desc, &var_map)); for disjoint in &disjoints { self.ir_desc.get_set_def(disjoint); } @@ -99,7 +99,7 @@ impl TypingContext { // Handle the optional forall. if key == ir::SetDefKey::Reverse { let var_def = var.as_ref().unwrap(); - let var_name = "$".to_string() + &var_def.name; + let var_name = "$".to_string() + &var_def.name.data; value = value.replace(&var_name, "$var"); env.push("var"); } else { assert!(var.is_none()); } @@ -146,17 +146,29 @@ impl TypingContext { let forall_vars = arg.clone().into_iter() .chain(std::iter::once(quotient.item)).collect_vec(); let counter_name = self.create_repr_counter( - set.name().clone(), &repr_name, arg.clone(), item_name.clone(), + set.name().clone(), &repr_name, arg.clone(), item_name.data.clone(), forall_vars.clone(), RcStr::new(quotient.equiv_relation.0), quotient.equiv_relation.1); // Generate the code that set an item as representant. let trigger_code = print::add_to_quotient( - set, &repr_name, &counter_name, &item_name, &arg_name); + set, &repr_name, &counter_name, &item_name.data, + &arg_name.clone().map(|n| n.data) + ); // Constraint the representative value. let forall_names = forall_vars.iter().map(|x| x.name.clone()).collect_vec(); - let repr_instance = ChoiceInstance { name: repr_name, vars: forall_names.clone() }; - let counter_instance = ChoiceInstance { name: counter_name, vars: forall_names }; + let repr_instance = ChoiceInstance { + name: repr_name, + vars: forall_names.iter() + .map(|n| n.data.clone()) + .collect::>() + }; + let counter_instance = ChoiceInstance { + name: counter_name, + vars: forall_names.iter() + .map(|n| n.data.clone()) + .collect::>() + }; let not_repr = Condition::new_is_bool(repr_instance.clone(), false); let counter_leq_zero = Condition::CmpCode { lhs: counter_instance, rhs: "0".into(), op: ir::CmpOp::Leq @@ -185,7 +197,7 @@ impl TypingContext { // Add the constraint `item in set => repr is TRUE`. let quotient_item_def = VarDef { name: item_name, - set: SetRef { name: set.name().clone(), var: arg_name } + set: SetRef { name: set.name().clone(), var: arg_name.map(|n| n.data) } }; let item_in_set_foralls = arg.into_iter() .chain(std::iter::once(quotient_item_def)).collect(); @@ -202,7 +214,7 @@ impl TypingContext { fn create_repr_choice(&mut self, name: RcStr, set: &ir::SetDef, arg: Option, - item_name: RcStr) { + item_name: Spanned) { let bool_str: RcStr = "Bool".into(); let def = ir::ChoiceDef::Enum(bool_str.clone()); let mut vars = Vec::new(); @@ -210,7 +222,10 @@ impl TypingContext { vars.push((arg.name.clone(), set.arg().unwrap().clone())); } vars.push((item_name, set.superset().unwrap().clone())); - let args = ir::ChoiceArguments::new(vars, false, false); + let args = ir::ChoiceArguments::new(vars.into_iter() + .map(|(n, s)| (n.data, s)) + .collect(), + false, false); let mut repr = ir::Choice::new(name, None, args, def); let false_value_set = std::iter::once("FALSE".into()).collect(); repr.add_fragile_values(ir::ValueSet::enum_values(bool_str, false_value_set)); @@ -233,7 +248,7 @@ impl TypingContext { let rhs_name = RcStr::new(format!("{}_repr", item_name)); let rhs_set = SetRef { name: set_name, - var: arg.as_ref().map(|d| d.name.clone()) + var: arg.as_ref().map(|d| d.name.data.clone()) }; let equiv_choice = ChoiceInstance { name: equiv_choice_name, @@ -246,7 +261,11 @@ impl TypingContext { let body = CounterBody { base: "0".to_string(), conditions: vec![condition], - iter_vars: vec![VarDef { name: rhs_name, set: rhs_set }], + iter_vars: vec![VarDef { name: Spanned { + data: rhs_name, + beg: Default::default(), + end: Default::default() + }, set: rhs_set }], kind: ir::CounterKind::Add, value: CounterVal::Code("1".to_string()), }; @@ -280,8 +299,12 @@ impl TypingContext { let vars = vars.into_iter().map(|v| { let name = v.name.clone(); (name, var_map.decl_argument(&self.ir_desc, v)) - }).collect(); - let arguments = ir::ChoiceArguments::new(vars, symmetric, inverse); + }).collect::>(); + let arguments = ir::ChoiceArguments::new(vars.into_iter() + .map(|(n, s)| (n.data, s)) + .collect::>(), + symmetric, + inverse); let inverse = if let Some(Symmetry::AntiSymmetric(mapping)) = stmts.symmetry { { let mut mapped = HashSet::default(); @@ -330,8 +353,11 @@ impl TypingContext { let vars = def.variables.into_iter().map(|v| { let name = v.name.clone(); (name, var_map.decl_argument(&self.ir_desc, v)) - }).collect(); - let arguments = ir::ChoiceArguments::new(vars, false, false); + }).collect::>(); + let arguments = ir::ChoiceArguments::new(vars.into_iter() + .map(|(n, s)| (n.data, s)) + .collect::>(), + false, false); let universe = type_check_code(def.code.into(), &var_map); let choice_def = ir::ChoiceDef::Number { universe }; self.ir_desc.add_choice(ir::Choice::new(choice_name, doc, arguments, choice_def)); @@ -340,8 +366,14 @@ impl TypingContext { /// Register a constraint on an enum value. fn register_value_constraint(&mut self, choice: RcStr, args: Vec, value: RcStr, mut constraint: Constraint) { - let choice_args = args.iter().map(|def| def.name.clone()).collect(); - let self_instance = ChoiceInstance { name: choice, vars: choice_args }; + let choice_args = + args.iter().map(|def| def.name.clone()) + .collect::>(); + let self_instance = ChoiceInstance { + name: choice, vars: choice_args.into_iter() + .map(|n| n.data) + .collect::>() + }; let condition = Condition::Is { lhs: self_instance, rhs: vec![value], is: false }; constraint.forall_vars.extend(args); for disjunction in &mut constraint.disjunctions { @@ -372,7 +404,18 @@ impl TypingContext { }).collect_vec(); let doc = doc.map(RcStr::new); let (incr, incr_condition) = self.gen_increment( - &counter_name, &vars, &iter_vars, all_var_defs, body.conditions, &var_map); + &counter_name, + vars.iter() + .cloned() + .map(|(n, s)| (n.data, s)) + .collect::>() + .as_slice(), + iter_vars.iter() + .cloned() + .map(|(n, s)| (n.data, s)) + .collect::>() + .as_slice(), + all_var_defs, body.conditions, &var_map); // Type check the value. let value = match body.value { CounterVal::Code(code) => @@ -394,7 +437,9 @@ impl TypingContext { let counter_def = ir::ChoiceDef::Counter { incr_iter, kind, value, incr, incr_condition, visibility, base }; - let counter_args = ir::ChoiceArguments::new(vars, false, false); + let counter_args = ir::ChoiceArguments::new(vars.into_iter() + .map(|(n, s)| (n.data, s)) + .collect(), false, false); let mut counter_choice = ir::Choice::new( counter_name, doc, counter_args, counter_def); // Filter the counter itself after an update, because the filter actually acts on diff --git a/telamon-gen/src/ast/mod.rs b/telamon-gen/src/ast/mod.rs index 43873e251..5639cede5 100644 --- a/telamon-gen/src/ast/mod.rs +++ b/telamon-gen/src/ast/mod.rs @@ -302,7 +302,7 @@ impl SetRef { /// Defines a variable. #[derive(Debug, Clone)] pub struct VarDef { - pub name: RcStr, + pub name: Spanned, pub set: SetRef, } @@ -339,9 +339,9 @@ impl VarMap { fn decl_var(&mut self, ir_desc: &ir::IrDesc, var_def: VarDef, var: ir::Variable) -> ir::Set { let set = var_def.set.type_check(ir_desc, self); - match self.map.entry(var_def.name.clone()) { + match self.map.entry(var_def.name.data.clone()) { hash_map::Entry::Occupied(..) => - panic!("variable {} defined twice", var_def.name), + panic!("variable {} defined twice", var_def.name.data), hash_map::Entry::Vacant(entry) => { entry.insert((var, set.clone())); }, }; set diff --git a/telamon-gen/src/parser.lalrpop b/telamon-gen/src/parser.lalrpop index 41affee70..1f198e5ad 100644 --- a/telamon-gen/src/parser.lalrpop +++ b/telamon-gen/src/parser.lalrpop @@ -52,9 +52,13 @@ set_disjoint: Vec = { choice_vars = { list }; +rc_var: RcStr = { + => RcStr::new(name), +}; + var_def: ast::VarDef = { - in_ => { - ast::VarDef { name: RcStr::new(name), set } + > in_ => { + ast::VarDef { name: spanned_name, set } }, };