Skip to content

Commit

Permalink
Merge pull request conjure-cp#233 from Kieranoski702/metadata
Browse files Browse the repository at this point in the history
Add metadata to all enum variants
  • Loading branch information
ozgurakgun authored Feb 21, 2024
2 parents 0390d85 + d50b1e4 commit 054481e
Show file tree
Hide file tree
Showing 14 changed files with 1,059 additions and 565 deletions.
60 changes: 40 additions & 20 deletions conjure_oxide/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,40 +135,57 @@ fn parse_int_domain(v: &JsonValue) -> Result<Domain> {
}

// this needs an explicit type signature to force the closures to have the same type
type BinOp = Box<dyn Fn(Box<Expression>, Box<Expression>) -> Expression>;
type UnaryOp = Box<dyn Fn(Box<Expression>) -> Expression>;
type VecOp = Box<dyn Fn(Vec<Expression>) -> Expression>;
type BinOp = Box<dyn Fn(Metadata, Box<Expression>, Box<Expression>) -> Expression>;
type UnaryOp = Box<dyn Fn(Metadata, Box<Expression>) -> Expression>;
type VecOp = Box<dyn Fn(Metadata, Vec<Expression>) -> Expression>;

fn parse_expression(obj: &JsonValue) -> Option<Expression> {
let binary_operators: HashMap<&str, BinOp> = [
("MkOpEq", Box::new(Expression::Eq) as Box<dyn Fn(_, _) -> _>),
(
"MkOpEq",
Box::new(Expression::Eq) as Box<dyn Fn(_, _, _) -> _>,
),
(
"MkOpNeq",
Box::new(Expression::Neq) as Box<dyn Fn(_, _) -> _>,
Box::new(Expression::Neq) as Box<dyn Fn(_, _, _) -> _>,
),
(
"MkOpGeq",
Box::new(Expression::Geq) as Box<dyn Fn(_, _) -> _>,
Box::new(Expression::Geq) as Box<dyn Fn(_, _, _) -> _>,
),
(
"MkOpLeq",
Box::new(Expression::Leq) as Box<dyn Fn(_, _) -> _>,
Box::new(Expression::Leq) as Box<dyn Fn(_, _, _) -> _>,
),
(
"MkOpGt",
Box::new(Expression::Gt) as Box<dyn Fn(_, _, _) -> _>,
),
(
"MkOpLt",
Box::new(Expression::Lt) as Box<dyn Fn(_, _, _) -> _>,
),
("MkOpGt", Box::new(Expression::Gt) as Box<dyn Fn(_, _) -> _>),
("MkOpLt", Box::new(Expression::Lt) as Box<dyn Fn(_, _) -> _>),
]
.into_iter()
.collect();

let unary_operators: HashMap<&str, UnaryOp> =
[("MkOpNot", Box::new(Expression::Not) as Box<dyn Fn(_) -> _>)]
.into_iter()
.collect();
let unary_operators: HashMap<&str, UnaryOp> = [(
"MkOpNot",
Box::new(Expression::Not) as Box<dyn Fn(_, _) -> _>,
)]
.into_iter()
.collect();

let vec_operators: HashMap<&str, VecOp> = [
("MkOpSum", Box::new(Expression::Sum) as Box<dyn Fn(_) -> _>),
("MkOpAnd", Box::new(Expression::And) as Box<dyn Fn(_) -> _>),
("MkOpOr", Box::new(Expression::Or) as Box<dyn Fn(_) -> _>),
(
"MkOpSum",
Box::new(Expression::Sum) as Box<dyn Fn(_, _) -> _>,
),
(
"MkOpAnd",
Box::new(Expression::And) as Box<dyn Fn(_, _) -> _>,
),
("MkOpOr", Box::new(Expression::Or) as Box<dyn Fn(_, _) -> _>),
]
.into_iter()
.collect();
Expand All @@ -192,7 +209,10 @@ fn parse_expression(obj: &JsonValue) -> Option<Expression> {
},
Value::Object(refe) if refe.contains_key("Reference") => {
let name = refe["Reference"].as_array()?[0].as_object()?["Name"].as_str()?;
Some(Expression::Reference(Name::UserName(name.to_string())))
Some(Expression::Reference(
Metadata::new(),
Name::UserName(name.to_string()),
))
}
Value::Object(constant) if constant.contains_key("Constant") => parse_constant(constant),
otherwise => panic!("Unhandled Expression {:#?}", otherwise),
Expand All @@ -213,7 +233,7 @@ fn parse_bin_op(
Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
let arg1 = parse_expression(&bin_op_args[0])?;
let arg2 = parse_expression(&bin_op_args[1])?;
Some(constructor(Box::new(arg1), Box::new(arg2)))
Some(constructor(Metadata::new(), Box::new(arg1), Box::new(arg2)))
}
otherwise => panic!("Unhandled parse_bin_op {:#?}", otherwise),
}
Expand All @@ -227,7 +247,7 @@ fn parse_unary_op(
let constructor = unary_operators.get(key.as_str())?;

let arg = parse_expression(value)?;
Some(constructor(Box::new(arg)))
Some(constructor(Metadata::new(), Box::new(arg)))
}

fn parse_vec_op(
Expand All @@ -242,7 +262,7 @@ fn parse_vec_op(
.iter()
.map(|x| parse_expression(x).unwrap())
.collect();
Some(constructor(args_parsed))
Some(constructor(Metadata::new(), args_parsed))
}

fn parse_constant(constant: &serde_json::Map<String, Value>) -> Option<Expression> {
Expand Down
46 changes: 23 additions & 23 deletions conjure_oxide/src/rules/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ fn remove_nothings(expr: &Expr) -> Result<Expr, RuleApplicationError> {
}

match expr {
Expr::And(_) | Expr::Or(_) | Expr::Sum(_) => match expr.sub_expressions() {
Expr::And(_, _) | Expr::Or(_, _) | Expr::Sum(_, _) => match expr.sub_expressions() {
None => Err(RuleApplicationError::RuleNotApplicable),
Some(sub) => {
let new_sub = remove_nothings(sub)?;
let new_expr = expr.with_sub_expressions(new_sub);
Ok(new_expr)
}
},
Expr::SumEq(_, _) | Expr::SumLeq(_, _) | Expr::SumGeq(_, _) => {
Expr::SumEq(_, _, _) | Expr::SumLeq(_, _, _) | Expr::SumGeq(_, _, _) => {
match expr.sub_expressions() {
None => Err(RuleApplicationError::RuleNotApplicable),
Some(sub) => {
Expand Down Expand Up @@ -98,7 +98,7 @@ fn empty_to_nothing(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn sum_constants(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Sum(exprs) => {
Expr::Sum(metadata, exprs) => {
let mut sum = 0;
let mut new_exprs = Vec::new();
let mut changed = false;
Expand All @@ -116,7 +116,7 @@ fn sum_constants(expr: &Expr) -> Result<Expr, RuleApplicationError> {
}
// TODO (kf77): Get existing metadata instead of creating a new one
new_exprs.push(Expr::Constant(Metadata::new(), Const::Int(sum)));
Ok(Expr::Sum(new_exprs)) // Let other rules handle only one Expr being contained in the sum
Ok(Expr::Sum(Metadata::new(), new_exprs)) // Let other rules handle only one Expr being contained in the sum
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -131,7 +131,7 @@ fn sum_constants(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn unwrap_sum(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Sum(exprs) if (exprs.len() == 1) => Ok(exprs[0].clone()),
Expr::Sum(metadata, exprs) if (exprs.len() == 1) => Ok(exprs[0].clone()),
_ => Err(RuleApplicationError::RuleNotApplicable),
}
}
Expand All @@ -145,12 +145,12 @@ fn unwrap_sum(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
pub fn flatten_nested_sum(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Sum(exprs) => {
Expr::Sum(metadata, exprs) => {
let mut new_exprs = Vec::new();
let mut changed = false;
for e in exprs {
match e {
Expr::Sum(sub_exprs) => {
Expr::Sum(metadata, sub_exprs) => {
changed = true;
for e in sub_exprs {
new_exprs.push(e.clone());
Expand All @@ -162,7 +162,7 @@ pub fn flatten_nested_sum(expr: &Expr) -> Result<Expr, RuleApplicationError> {
if !changed {
return Err(RuleApplicationError::RuleNotApplicable);
}
Ok(Expr::Sum(new_exprs))
Ok(Expr::Sum(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -178,12 +178,12 @@ pub fn flatten_nested_sum(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn unwrap_nested_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Or(exprs) => {
Expr::Or(metadata, exprs) => {
let mut new_exprs = Vec::new();
let mut changed = false;
for e in exprs {
match e {
Expr::Or(exprs) => {
Expr::Or(metadata, exprs) => {
changed = true;
for e in exprs {
new_exprs.push(e.clone());
Expand All @@ -195,7 +195,7 @@ fn unwrap_nested_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
if !changed {
return Err(RuleApplicationError::RuleNotApplicable);
}
Ok(Expr::Or(new_exprs))
Ok(Expr::Or(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -211,12 +211,12 @@ fn unwrap_nested_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn unwrap_nested_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::And(exprs) => {
Expr::And(metadata, exprs) => {
let mut new_exprs = Vec::new();
let mut changed = false;
for e in exprs {
match e {
Expr::And(exprs) => {
Expr::And(metadata, exprs) => {
changed = true;
for e in exprs {
new_exprs.push(e.clone());
Expand All @@ -228,7 +228,7 @@ fn unwrap_nested_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
if !changed {
return Err(RuleApplicationError::RuleNotApplicable);
}
Ok(Expr::And(new_exprs))
Ok(Expr::And(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -244,8 +244,8 @@ fn unwrap_nested_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn remove_double_negation(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Not(contents) => match contents.as_ref() {
Expr::Not(expr_box) => Ok(*expr_box.clone()),
Expr::Not(metadata, contents) => match contents.as_ref() {
Expr::Not(metadata, expr_box) => Ok(*expr_box.clone()),
_ => Err(RuleApplicationError::RuleNotApplicable),
},
_ => Err(RuleApplicationError::RuleNotApplicable),
Expand All @@ -261,7 +261,7 @@ fn remove_double_negation(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn remove_trivial_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::And(exprs) => {
Expr::And(metadata, exprs) => {
if exprs.len() == 1 {
return Ok(exprs[0].clone());
}
Expand All @@ -280,7 +280,7 @@ fn remove_trivial_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn remove_trivial_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Or(exprs) => {
Expr::Or(metadata, exprs) => {
if exprs.len() == 1 {
return Ok(exprs[0].clone());
}
Expand All @@ -300,7 +300,7 @@ fn remove_trivial_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn remove_constants_from_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Or(exprs) => {
Expr::Or(metadata, exprs) => {
let mut new_exprs = Vec::new();
let mut changed = false;
for e in exprs {
Expand All @@ -320,7 +320,7 @@ fn remove_constants_from_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
if !changed {
return Err(RuleApplicationError::RuleNotApplicable);
}
Ok(Expr::Or(new_exprs))
Ok(Expr::Or(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -336,7 +336,7 @@ fn remove_constants_from_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn remove_constants_from_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::And(exprs) => {
Expr::And(metadata, exprs) => {
let mut new_exprs = Vec::new();
let mut changed = false;
for e in exprs {
Expand All @@ -356,7 +356,7 @@ fn remove_constants_from_and(expr: &Expr) -> Result<Expr, RuleApplicationError>
if !changed {
return Err(RuleApplicationError::RuleNotApplicable);
}
Ok(Expr::And(new_exprs))
Ok(Expr::And(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand All @@ -372,7 +372,7 @@ fn remove_constants_from_and(expr: &Expr) -> Result<Expr, RuleApplicationError>
#[register_rule]
fn evaluate_constant_not(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Not(contents) => match contents.as_ref() {
Expr::Not(metdata, contents) => match contents.as_ref() {
Expr::Constant(metadata, Const::Bool(val)) => {
Ok(Expr::Constant(metadata.clone(), Const::Bool(!val)))
}
Expand Down
26 changes: 13 additions & 13 deletions conjure_oxide/src/rules/cnf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ use conjure_rules::register_rule;
#[register_rule]
fn distribute_not_over_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Not(contents) => match contents.as_ref() {
Expr::And(exprs) => {
Expr::Not(metadata, contents) => match contents.as_ref() {
Expr::And(metadata, exprs) => {
let mut new_exprs = Vec::new();
for e in exprs {
new_exprs.push(Expr::Not(Box::new(e.clone())));
new_exprs.push(Expr::Not(metadata.clone(), Box::new(e.clone())));
}
Ok(Expr::Or(new_exprs))
Ok(Expr::Or(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
},
Expand All @@ -39,13 +39,13 @@ fn distribute_not_over_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
#[register_rule]
fn distribute_not_over_or(expr: &Expr) -> Result<Expr, RuleApplicationError> {
match expr {
Expr::Not(contents) => match contents.as_ref() {
Expr::Or(exprs) => {
Expr::Not(metadata, contents) => match contents.as_ref() {
Expr::Or(metadata, exprs) => {
let mut new_exprs = Vec::new();
for e in exprs {
new_exprs.push(Expr::Not(Box::new(e.clone())));
new_exprs.push(Expr::Not(metadata.clone(), Box::new(e.clone())));
}
Ok(Expr::And(new_exprs))
Ok(Expr::And(metadata.clone(), new_exprs))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
},
Expand All @@ -66,31 +66,31 @@ fn distribute_or_over_and(expr: &Expr) -> Result<Expr, RuleApplicationError> {
// ToDo: may be better to move this to some kind of utils module?
for (i, e) in exprs.iter().enumerate() {
match e {
Expr::And(_) => return Some(i),
Expr::And(_, _) => return Some(i),
_ => (),
}
}
None
}

match expr {
Expr::Or(exprs) => match find_and(exprs) {
Expr::Or(metadata, exprs) => match find_and(exprs) {
Some(idx) => {
let mut rest = exprs.clone();
let and_expr = rest.remove(idx);

match and_expr {
Expr::And(and_exprs) => {
Expr::And(metadata, and_exprs) => {
let mut new_and_contents = Vec::new();

for e in and_exprs {
// ToDo: Cloning everything may be a bit inefficient - discuss
let mut new_or_contents = rest.clone();
new_or_contents.push(e.clone());
new_and_contents.push(Expr::Or(new_or_contents))
new_and_contents.push(Expr::Or(metadata.clone(), new_or_contents))
}

Ok(Expr::And(new_and_contents))
Ok(Expr::And(metadata.clone(), new_and_contents))
}
_ => Err(RuleApplicationError::RuleNotApplicable),
}
Expand Down
Loading

0 comments on commit 054481e

Please sign in to comment.