(value: Rc<SymbolicValue>)
| 427 | impl TryFrom<Rc<SymbolicValue>> for LinearConstraintSystem { |
| 428 | type Error = &'static str; |
| 429 | fn try_from(value: Rc<SymbolicValue>) -> Result<Self, &'static str> { |
| 430 | debug!( |
| 431 | "Converting symbolic value into LinearConstraintSystem: {:?}", |
| 432 | value |
| 433 | ); |
| 434 | |
| 435 | let res = |
| 436 | match &value.expression { |
| 437 | Expression::And { left, right } => { |
| 438 | let lcsts = LinearConstraintSystem::try_from(left.clone()); |
| 439 | let rcsts = LinearConstraintSystem::try_from(right.clone()); |
| 440 | if let (Ok(lcsts), Ok(rcsts)) = (lcsts, rcsts) { |
| 441 | lcsts.join(rcsts) |
| 442 | } else { |
| 443 | return Err("Error when converting And expression"); |
| 444 | } |
| 445 | } |
| 446 | // Constant, so it must be either true or false |
| 447 | Expression::CompileTimeConstant(const_value) => { |
| 448 | match const_value.as_bool_if_known() { |
| 449 | Some(true) => LinearConstraint::new_true().into(), |
| 450 | Some(false) => LinearConstraint::new_false().into(), |
| 451 | None => unreachable!("Converting a constant symbolic value into linear constraint but the value is neither true nor false"), |
| 452 | } |
| 453 | } |
| 454 | // A single variable, equivalent to `var == true` |
| 455 | Expression::Variable { path, .. } => { |
| 456 | let mut expr = LinearExpression::default(); |
| 457 | expr = expr + path.clone() - Integer::from(1); |
| 458 | LinearConstraint::Equality(expr).into() |
| 459 | } |
| 460 | // A single numerical variable, equivalent to `var == true` |
| 461 | Expression::Numerical(path) => { |
| 462 | let mut expr = LinearExpression::default(); |
| 463 | expr = expr + path.clone() - Integer::from(1); |
| 464 | LinearConstraint::Equality(expr).into() |
| 465 | } |
| 466 | Expression::Widen { operand, .. } => { |
| 467 | Self::try_from(operand.clone()).unwrap().into() |
| 468 | } |
| 469 | // An expression `lhs <= rhs`, equivalent to `lhs - rhs <= 0` |
| 470 | Expression::LessOrEqual { left, right } => { |
| 471 | let left_expr = symbolic_to_expression(left.clone()); |
| 472 | let right_expr = symbolic_to_expression(right.clone()); |
| 473 | if let (Ok(left_expr), Ok(right_expr)) = (left_expr, right_expr) { |
| 474 | LinearConstraint::LessEq(left_expr - right_expr).into() |
| 475 | } else { |
| 476 | return Err("Error when converting LessOrEqual expression"); |
| 477 | } |
| 478 | } |
| 479 | // An expression `lhs < rhs`, equivalent to `lhs - rhs < 0` |
| 480 | Expression::LessThan { left, right } => { |
| 481 | let left_expr = symbolic_to_expression(left.clone()); |
| 482 | let right_expr = symbolic_to_expression(right.clone()); |
| 483 | if let (Ok(left_expr), Ok(right_expr)) = (left_expr, right_expr) { |
| 484 | LinearConstraint::LessThan(left_expr - right_expr).into() |
| 485 | } else { |
| 486 | return Err("Error when converting LessThan expression"); |
nothing calls this directly
no test coverage detected