-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #333 from egraphs-good/oflatt-assume-propogate2
Add rules that propogate assume nodes to create unique contexts
- Loading branch information
Showing
10 changed files
with
257 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
(run-schedule | ||
(repeat 6 | ||
(repeat 100 assume) | ||
(saturate always-run) | ||
(saturate error-checking) | ||
(run constant_fold) | ||
)) | ||
(saturate constant_fold))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
; This file propogates assume nodes top-down from functions. | ||
; It gives each program path a unique equality relation. | ||
; This can be quite expensive, so be careful running these rules. | ||
|
||
(ruleset assume) | ||
|
||
(sort AssumeList) | ||
|
||
; In order to saturate and not create unecessary contexts, we need to collapse | ||
; duplicate assumptions. | ||
; For example, the rewrite over `Function` could create many | ||
; `(Assume (InFunc name) (Assume (InFunc name) ...))` nestings | ||
(rewrite (Assume assumption (Assume assumption rest)) | ||
(Assume assumption rest) | ||
:ruleset assume) | ||
|
||
; ################### start top-down assumptions | ||
|
||
(rewrite | ||
(Function name in_ty out_ty out) | ||
(Function name in_ty out_ty | ||
(Assume (InFunc name) | ||
out)) | ||
:ruleset assume) | ||
|
||
|
||
; ################### operations | ||
(rewrite (Assume asum (Bop op c1 c2)) | ||
(Bop op (Assume asum c1) (Assume asum c2)) | ||
:ruleset assume) | ||
(rewrite (Assume assum (Uop op c1)) | ||
(Uop op (Assume assum c1)) | ||
:ruleset assume) | ||
(rewrite (Assume assum (Get expr index)) | ||
(Get (Assume assum expr) index) | ||
:ruleset assume) | ||
(rewrite (Assume assum (Alloc expr ty)) | ||
(Alloc (Assume assum expr) ty) | ||
:ruleset assume) | ||
(rewrite (Assume assum (Call name expr)) | ||
(Call name (Assume assum expr)) | ||
:ruleset assume) | ||
|
||
; ################### tuple operations | ||
(rewrite (Assume assum (Single expr)) | ||
(Single (Assume assum expr)) | ||
:ruleset assume) | ||
(rewrite (Assume assum (Concat order e1 e2)) | ||
(Concat order (Assume assum e1) (Assume assum e2)) | ||
:ruleset assume) | ||
|
||
; #################### control flow | ||
|
||
; assumptions, predicate, cases, current case | ||
(function SwitchAssume (AssumeList Expr ListExpr i64) ListExpr :unextractable) | ||
|
||
(rewrite (Assume assum (If pred then else)) | ||
(If (Assume assum pred) | ||
(Assume | ||
(InIf true (Assume assum pred)) then) | ||
(Assume | ||
(InIf false (Assume assum pred)) else)) | ||
:ruleset assume) | ||
|
||
(rewrite (Assume assum (Let inputs body)) | ||
(Let | ||
(Assume assum inputs) | ||
(Assume | ||
(InLet (Assume assum inputs)) | ||
body)) | ||
:ruleset assume) | ||
|
||
|
||
(rule ((= lhs (Assume assum (DoWhile inputs pred_outputs)))) | ||
((union lhs | ||
(DoWhile | ||
(Assume assum inputs) | ||
(Assume | ||
(InLoop (Assume assum inputs) pred_outputs) | ||
pred_outputs)))) | ||
:ruleset assume) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#[cfg(test)] | ||
use crate::{egglog_test, interpreter::Value, schema::Constant}; | ||
|
||
#[test] | ||
fn test_assume_in_func() -> crate::Result { | ||
use crate::ast::*; | ||
let expr = function("main", intt(), intt(), int(2)); | ||
let expected = function("main", intt(), intt(), assume(infunc("main"), int(2))); | ||
egglog_test( | ||
&format!("{expr}"), | ||
&format!("(check (= {expr} {expected}))"), | ||
vec![ | ||
expr.to_program(emptyt(), intt()), | ||
expected.to_program(emptyt(), intt()), | ||
], | ||
Value::Tuple(vec![]), | ||
Value::Const(Constant::Int(2)), | ||
) | ||
} | ||
|
||
#[test] | ||
fn test_assume_two_lets() -> crate::Result { | ||
use crate::ast::*; | ||
let expr = function( | ||
"main", | ||
intt(), | ||
intt(), | ||
tlet(int(1), tlet(add(arg(), arg()), mul(arg(), int(2)))), | ||
); | ||
let int1 = assume(infunc("main"), int(1)); | ||
let arg1 = assume(inlet(int1.clone()), arg()); | ||
let addarg1 = add(arg1.clone(), arg1.clone()); | ||
let int2 = assume(inlet(addarg1.clone()), int(2)); | ||
let arg2 = assume(inlet(addarg1.clone()), arg()); | ||
let expr2 = function( | ||
"main", | ||
intt(), | ||
intt(), | ||
tlet( | ||
int1, | ||
tlet( | ||
add(arg1.clone(), arg1.clone()), | ||
mul(arg2.clone(), int2.clone()), | ||
), | ||
), | ||
); | ||
|
||
egglog_test( | ||
&format!("{expr}"), | ||
&format!("(check (= {expr} {expr2}))"), | ||
vec![ | ||
expr.to_program(emptyt(), intt()), | ||
expr2.to_program(emptyt(), intt()), | ||
], | ||
Value::Tuple(vec![]), | ||
Value::Const(Constant::Int(4)), | ||
) | ||
} | ||
|
||
#[test] | ||
fn test_switch_contexts() -> crate::Result { | ||
use crate::ast::*; | ||
let expr = function("main", intt(), intt(), tif(ttrue(), int(1), int(2))); | ||
let pred = assume(infunc("main"), ttrue()); | ||
let expr2 = function( | ||
"main", | ||
intt(), | ||
intt(), | ||
tif( | ||
pred.clone(), | ||
assume(inif(true, pred.clone()), int(1)), | ||
assume(inif(false, pred.clone()), int(2)), | ||
), | ||
); | ||
egglog_test( | ||
&format!("{expr}"), | ||
&format!("(check (= {expr} {expr2}))"), | ||
vec![ | ||
expr.to_program(emptyt(), intt()), | ||
expr2.to_program(emptyt(), intt()), | ||
], | ||
Value::Tuple(vec![]), | ||
Value::Const(Constant::Int(1)), | ||
) | ||
} | ||
|
||
#[test] | ||
fn test_dowhile_cycle_assume() -> crate::Result { | ||
use crate::ast::*; | ||
// loop runs one iteration and returns 3 | ||
let myloop = dowhile(single(int(2)), parallel!(tfalse(), int(3))); | ||
let expr = function("main", intt(), intt(), myloop); | ||
|
||
let int2 = single(assume(infunc("main"), int(2))); | ||
let inner_assume = inloop(int2.clone(), parallel!(tfalse(), int(3))); | ||
let expr2 = function( | ||
"main", | ||
intt(), | ||
intt(), | ||
dowhile( | ||
int2.clone(), | ||
parallel!( | ||
assume(inner_assume.clone(), tfalse()), | ||
assume(inner_assume.clone(), int(3)), | ||
), | ||
), | ||
); | ||
|
||
egglog_test( | ||
&format!( | ||
"{expr} | ||
(union {} {expr})", | ||
single(int(3)) | ||
), | ||
&format!("(check (= {expr} {expr2}))"), | ||
vec![ | ||
expr.to_program(emptyt(), intt()), | ||
expr2.to_program(emptyt(), intt()), | ||
], | ||
Value::Tuple(vec![]), | ||
Value::Tuple(vec![Value::Const(Constant::Int(3))]), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub(crate) mod assume; |