1
- use std:: cell:: RefCell ;
2
- use std:: collections:: HashMap ;
3
1
use std:: rc:: Rc ;
2
+ use std:: time:: { Duration , Instant } ;
4
3
5
4
use imbl:: vector;
6
5
use serde:: { Deserialize , Serialize } ;
@@ -24,60 +23,84 @@ pub mod unify;
24
23
#[ derive( Serialize , Deserialize ) ]
25
24
pub struct Input {
26
25
schemas : Vec < Schema > ,
27
- queries : ( relation:: Relation , relation:: Relation ) ,
26
+ pub queries : ( relation:: Relation , relation:: Relation ) ,
28
27
#[ serde( default ) ]
29
28
help : ( String , String ) ,
30
29
}
31
30
32
- pub fn unify ( Input { schemas, queries : ( rel1, rel2) , help } : Input ) -> bool {
31
+ #[ derive( Clone , Debug , Default , Serialize , Deserialize ) ]
32
+ pub struct Stats {
33
+ pub provable : bool ,
34
+ pub panicked : bool ,
35
+ pub complete_fragment : bool ,
36
+ pub equiv_class_duration : Duration ,
37
+ pub equiv_class_timed_out : bool ,
38
+ pub smt_duration : Duration ,
39
+ pub smt_timed_out : bool ,
40
+ pub nontrivial_perms : bool ,
41
+ pub translate_duration : Duration ,
42
+ pub normal_duration : Duration ,
43
+ pub stable_duration : Duration ,
44
+ pub unify_duration : Duration ,
45
+ pub total_duration : Duration ,
46
+ }
47
+
48
+ pub fn unify ( Input { schemas, queries : ( rel1, rel2) , help } : Input ) -> ( bool , Stats ) {
49
+ let mut stats = Stats :: default ( ) ;
33
50
let subst = vector ! [ ] ;
34
51
let env = relation:: Env ( & schemas, & subst, 0 ) ;
35
52
log:: info!( "Schemas:\n {:?}" , schemas) ;
36
53
log:: info!( "Input:\n {}\n {}" , help. 0 , help. 1 ) ;
54
+ stats. complete_fragment = rel1. complete ( ) && rel2. complete ( ) ;
37
55
if rel1 == rel2 {
38
56
println ! ( "Trivially true!" ) ;
39
- return true ;
57
+ return ( true , stats ) ;
40
58
}
59
+ let syn_start = Instant :: now ( ) ;
41
60
let rel1 = env. eval ( rel1) ;
42
61
let rel2 = env. eval ( rel2) ;
43
- if rel1 == rel2 {
44
- return true ;
45
- }
62
+ stats. translate_duration = syn_start. elapsed ( ) ;
46
63
log:: info!( "Syntax left:\n {}" , rel1) ;
47
64
log:: info!( "Syntax right:\n {}" , rel2) ;
65
+ if rel1 == rel2 {
66
+ return ( true , stats) ;
67
+ }
48
68
let nom_env = & vector ! [ ] ;
49
69
let eval_nom = |rel : syntax:: Relation | -> normal:: Relation {
50
70
let rel = ( & partial:: Env :: default ( ) ) . eval ( rel) ;
51
71
nom_env. eval ( rel)
52
72
} ;
73
+ let norm_start = Instant :: now ( ) ;
53
74
let rel1 = eval_nom ( rel1) ;
54
75
let rel2 = eval_nom ( rel2) ;
76
+ stats. normal_duration = norm_start. elapsed ( ) ;
55
77
log:: info!( "Normal left:\n {}" , rel1) ;
56
78
log:: info!( "Normal right:\n {}" , rel2) ;
57
79
if rel1 == rel2 {
58
- return true ;
80
+ return ( true , stats ) ;
59
81
}
60
82
let config = Config :: new ( ) ;
61
83
let z3_ctx = & Context :: new ( & config) ;
62
- let ctx = Rc :: new ( Ctx :: new ( Solver :: new ( z3_ctx) ) ) ;
63
- let h_ops = Rc :: new ( RefCell :: new ( HashMap :: new ( ) ) ) ;
64
- let agg_ops = Rc :: new ( RefCell :: new ( HashMap :: new ( ) ) ) ;
65
- let rel_h_ops = Rc :: new ( RefCell :: new ( HashMap :: new ( ) ) ) ;
84
+ let ctx = Rc :: new ( Ctx :: new_with_stats ( Solver :: new ( z3_ctx) , stats) ) ;
85
+ let z3_env = Z3Env :: empty ( ctx. clone ( ) ) ;
66
86
let eval_stb = |nom : normal:: Relation | -> normal:: Relation {
67
- let env = & stable:: Env ( vector ! [ ] , {
68
- let subst = vector ! [ ] ;
69
- Z3Env ( ctx. clone ( ) , subst, h_ops. clone ( ) , agg_ops. clone ( ) , rel_h_ops. clone ( ) )
70
- } ) ;
87
+ let env = & stable:: Env ( vector ! [ ] , z3_env. clone ( ) ) ;
71
88
let stb = env. eval ( nom) ;
72
89
nom_env. eval ( stb)
73
90
} ;
91
+ let stb_start = Instant :: now ( ) ;
74
92
let rel1 = eval_stb ( rel1) ;
75
93
let rel2 = eval_stb ( rel2) ;
94
+ ctx. stats . borrow_mut ( ) . stable_duration = stb_start. elapsed ( ) ;
76
95
log:: info!( "Stable left:\n {}" , rel1) ;
77
96
log:: info!( "Stable right:\n {}" , rel2) ;
78
97
if rel1 == rel2 {
79
- return true ;
98
+ return ( true , ctx . stats . borrow ( ) . clone ( ) ) ;
80
99
}
81
- let env = UnifyEnv ( ctx, vector ! [ ] , vector ! [ ] ) ;
82
- env. unify ( & rel1, & rel2)
100
+ let env = UnifyEnv ( ctx. clone ( ) , vector ! [ ] , vector ! [ ] ) ;
101
+ let unify_start = Instant :: now ( ) ;
102
+ let res = env. unify ( & rel1, & rel2) ;
103
+ ctx. stats . borrow_mut ( ) . unify_duration = unify_start. elapsed ( ) ;
104
+ let stats = ctx. stats . borrow ( ) . clone ( ) ;
105
+ ( res, stats)
83
106
}
0 commit comments