-
Notifications
You must be signed in to change notification settings - Fork 125
Time reasoning #1275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Time reasoning #1275
Changes from all commits
cf62085
19027ad
72ecf6a
76fdd0e
b674e34
5f54d60
09ef945
72ab443
d341f99
9366b68
4f9b4da
dbbd4f0
4881b52
659b98f
e958a4a
c36040b
5ba2c1f
b029e94
b9f2128
4267cde
b85cab5
3693f84
3356338
4b46a5d
0bb8266
31c8871
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,8 +20,9 @@ impl Simplifier for ast::Function { | |
| /// <https://github.com/viperproject/silicon/issues/387> | ||
| fn simplify(mut self) -> Self { | ||
| trace!("[enter] simplify = {}", self); | ||
| let new_body = self.body.map(|b| b.simplify()); | ||
| self.body = new_body; | ||
| self.body = self.body.map(|b| b.simplify()); | ||
| self.posts = self.posts.into_iter().map(|p| p.simplify()).collect(); | ||
| self.pres = self.pres.into_iter().map(|p| p.simplify()).collect(); | ||
| trace!("[exit] simplify = {}", self); | ||
| self | ||
| } | ||
|
|
@@ -30,8 +31,11 @@ impl Simplifier for ast::Function { | |
| impl Simplifier for ast::Expr { | ||
| #[must_use] | ||
| fn simplify(self) -> Self { | ||
| trace!("[enter] simplify = {:?}", self); | ||
| let mut folder = ExprSimplifier {}; | ||
| folder.fold(self) | ||
| let res = folder.fold(self); | ||
| trace!("[exit] simplify = {:?}", res); | ||
| res | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -46,134 +50,115 @@ impl ExprSimplifier { | |
| argument: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| position: pos, | ||
| }) => ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(!b), | ||
| position: pos, | ||
| }), | ||
| }) | ||
| .set_default_pos(inner_pos), | ||
| ast::Expr::UnaryOp(ast::UnaryOp { | ||
| op_kind: ast::UnaryOpKind::Not, | ||
| argument: | ||
| box ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::EqCmp, | ||
| box left, | ||
| box right, | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| position: pos, | ||
| }) => ast::Expr::BinOp(ast::BinOp { | ||
| }) if !matches!(left.get_type(), ast::Type::Float(_)) => ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::NeCmp, | ||
| left: box left, | ||
| right: box right, | ||
| position: pos, | ||
| }), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::And, | ||
| left: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b1), | ||
| .. | ||
| }), | ||
| right: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b2), | ||
| .. | ||
| }), | ||
| position: pos, | ||
| }) => ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b1 && b2), | ||
| position: pos, | ||
| }), | ||
| }) | ||
| .set_default_pos(inner_pos), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::And, | ||
| left: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| right: box conjunct, | ||
| .. | ||
| position: pos, | ||
| }) | ||
| | ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::And, | ||
| left: box conjunct, | ||
| right: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| .. | ||
| }) => { | ||
| if b { | ||
| conjunct | ||
| } else { | ||
| false.into() | ||
| } | ||
| position: pos, | ||
| }) => if b { | ||
| conjunct | ||
|
Comment on lines
+97
to
+98
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vakaras If we inline a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this can be a problem. For this and other reasons, it is better to use domain functions as triggers (with an axiom that says its value is always |
||
| } else { | ||
| Into::<ast::Expr>::into(false).set_pos(inner_pos) | ||
| } | ||
| .set_default_pos(pos), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::Or, | ||
| left: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| right: box disjunct, | ||
| .. | ||
| position: pos, | ||
| }) | ||
| | ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::Or, | ||
| left: box disjunct, | ||
| right: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| .. | ||
| }) => { | ||
| if b { | ||
| true.into() | ||
| } else { | ||
| disjunct | ||
| } | ||
| position: pos, | ||
| }) => if b { | ||
| Into::<ast::Expr>::into(true).set_pos(inner_pos) | ||
| } else { | ||
| disjunct | ||
| } | ||
| .set_default_pos(pos), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::Implies, | ||
| left: guard, | ||
| right: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| position: pos, | ||
| }) => { | ||
| if b { | ||
| true.into() | ||
| } else { | ||
| ast::Expr::UnaryOp(ast::UnaryOp { | ||
| op_kind: ast::UnaryOpKind::Not, | ||
| argument: guard, | ||
| position: pos, | ||
| }) | ||
| } | ||
| }) => if b { | ||
| Into::<ast::Expr>::into(true).set_pos(pos) | ||
| } else { | ||
| ast::Expr::UnaryOp(ast::UnaryOp { | ||
| op_kind: ast::UnaryOpKind::Not, | ||
| argument: guard, | ||
| position: pos, | ||
| }) | ||
| } | ||
| .set_default_pos(inner_pos), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::Implies, | ||
| left: | ||
| box ast::Expr::Const(ast::ConstExpr { | ||
| value: ast::Const::Bool(b), | ||
| .. | ||
| position: inner_pos, | ||
| }), | ||
| right: box body, | ||
| .. | ||
| }) => { | ||
| if b { | ||
| body | ||
| } else { | ||
| true.into() | ||
| } | ||
| position: pos, | ||
| }) => if b { | ||
| body | ||
| } else { | ||
| Into::<ast::Expr>::into(true).set_pos(inner_pos) | ||
| } | ||
| .set_default_pos(pos), | ||
| ast::Expr::BinOp(ast::BinOp { | ||
| op_kind: ast::BinaryOpKind::And, | ||
| left: box op1, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // © 2022, ETH Zurich | ||
| // | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
|
||
| use log::debug; | ||
| use std::mem; | ||
| use vir::polymorphic::*; | ||
|
|
||
| use crate::vir::optimizations::functions::Simplifier; | ||
|
|
||
| /// This optimization simplifies all expressions in a method. | ||
| /// It is required when resource access predicates appear on the RHS of | ||
| /// implications as implications are transformed into ors which need to be | ||
| /// transformed back into implications otherwise, we would have an impure | ||
| /// expression in ors which is disallowed in Viper. | ||
|
|
||
| pub fn simplify_exprs(mut cfg: CfgMethod) -> CfgMethod { | ||
| debug!("Simplifying exprs in {}", cfg.name()); | ||
| let mut sentinel_stmt = Stmt::comment("moved out stmt"); | ||
| for block in &mut cfg.basic_blocks { | ||
| for stmt in &mut block.stmts { | ||
| mem::swap(&mut sentinel_stmt, stmt); | ||
| sentinel_stmt = sentinel_stmt.simplify(); | ||
| mem::swap(&mut sentinel_stmt, stmt); | ||
| } | ||
| } | ||
| cfg | ||
| } | ||
|
|
||
| struct StmtSimplifier; | ||
|
|
||
| impl Simplifier for Stmt { | ||
| fn simplify(self) -> Self { | ||
| let mut folder = StmtSimplifier; | ||
| folder.fold(self) | ||
| } | ||
| } | ||
|
|
||
| impl StmtFolder for StmtSimplifier { | ||
| fn fold_expr(&mut self, expr: Expr) -> Expr { | ||
| expr.simplify() | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.