1
+ extern crate datalog;
2
+ use datalog:: Iteration ;
3
+
4
+ type Region = u32 ;
5
+ type Borrow = u32 ;
6
+ type Point = u32 ;
7
+
8
+ fn main ( ) {
9
+
10
+ let subset = {
11
+
12
+ // Create a new iteration context, ...
13
+ let mut iteration1 = Iteration :: new ( ) ;
14
+
15
+ // .. some variables, ..
16
+ let subset = iteration1. variable :: < ( Region , Region , Point ) > ( "subset" ) ;
17
+
18
+ // different indices for `subset`.
19
+ let subset_r1p = iteration1. variable :: < ( ( Region , Point ) , Region ) > ( "subset_r1p" ) ;
20
+ let subset_r2p = iteration1. variable :: < ( ( Region , Point ) , Region ) > ( "subset_r2p" ) ;
21
+ let subset_p = iteration1. variable :: < ( Point , ( Region , Region ) ) > ( "subset_p" ) ;
22
+
23
+ let subset_1 = iteration1. variable :: < ( ( Region , Point ) , Region ) > ( "subset_1" ) ;
24
+ let subset_2 = iteration1. variable :: < ( ( Region , Point ) , Region ) > ( "subset_2" ) ;
25
+
26
+ let region_live_at = iteration1. variable :: < ( ( Region , Point ) , ( ) ) > ( "region_live_at" ) ;
27
+ let cfg_edge_p = iteration1. variable :: < ( Point , Point ) > ( "cfg_edge_p" ) ;
28
+
29
+ // load initial facts.
30
+ subset. insert ( Vec :: new ( ) . into ( ) ) ;
31
+ region_live_at. insert ( Vec :: new ( ) . into ( ) ) ;
32
+ cfg_edge_p. insert ( Vec :: new ( ) . into ( ) ) ;
33
+
34
+ // .. and then start iterating rules!
35
+ while iteration1. changed ( ) {
36
+
37
+ // remap fields to re-index by keys.
38
+ subset_r1p. from_map ( & subset, |& ( r1, r2, p) | ( ( r1, p) , r2) ) ;
39
+ subset_r2p. from_map ( & subset, |& ( r1, r2, p) | ( ( r2, p) , r1) ) ;
40
+ subset_p. from_map ( & subset, |& ( r1, r2, p) | ( p, ( r1, r2) ) ) ;
41
+
42
+ // R0: subset(R1, R2, P) :- outlives(R1, R2, P).
43
+ // Already loaded; outlives is static.
44
+
45
+ // R1: subset(R1, R3, P) :-
46
+ // subset(R1, R2, P),
47
+ // subset(R2, R3, P).
48
+ subset. from_join ( & subset_r2p, & subset_r1p, |& ( _r2, p) , & r1, & r3| ( r1, r3, p) ) ;
49
+
50
+ // R2: subset(R1, R2, Q) :-
51
+ // subset(R1, R2, P),
52
+ // cfg_edge(P, Q),
53
+ // region_live_at(R1, Q),
54
+ // region_live_at(R2, Q).
55
+
56
+ subset_1. from_join ( & subset_p, & cfg_edge_p, |& _p, & ( r1, r2) , & q| ( ( r1, q) , r2) ) ;
57
+ subset_2. from_join ( & subset_1, & region_live_at, |& ( r1, q) , & r2, & ( ) | ( ( r2, q) , r1) ) ;
58
+ subset. from_join ( & subset_2, & region_live_at, |& ( r2, q) , & r1, & ( ) | ( r1, r2, q) ) ;
59
+
60
+ }
61
+
62
+ subset_r1p. complete ( )
63
+ } ;
64
+
65
+ let requires = {
66
+
67
+ // Create a new iteration context, ...
68
+ let mut iteration2 = Iteration :: new ( ) ;
69
+
70
+ // .. some variables, ..
71
+ let requires = iteration2. variable :: < ( Region , Borrow , Point ) > ( "requires" ) ;
72
+ requires. insert ( Vec :: new ( ) . into ( ) ) ;
73
+
74
+ let requires_rp = iteration2. variable :: < ( ( Region , Point ) , Borrow ) > ( "requires_rp" ) ;
75
+ let requires_bp = iteration2. variable :: < ( ( Borrow , Point ) , Region ) > ( "requires_bp" ) ;
76
+
77
+ let requires_1 = iteration2. variable :: < ( Point , ( Borrow , Region ) ) > ( "requires_1" ) ;
78
+ let requires_2 = iteration2. variable :: < ( ( Region , Point ) , Borrow ) > ( "requires_2" ) ;
79
+
80
+ let subset_r1p = iteration2. variable :: < ( ( Region , Point ) , Region ) > ( "subset_r1p" ) ;
81
+ subset_r1p. insert ( subset) ;
82
+
83
+ let killed = Vec :: new ( ) . into ( ) ;
84
+ let region_live_at = iteration2. variable :: < ( ( Region , Point ) , ( ) ) > ( "region_live_at" ) ;
85
+ let cfg_edge_p = iteration2. variable :: < ( Point , Point ) > ( "cfg_edge_p" ) ;
86
+
87
+ // .. and then start iterating rules!
88
+ while iteration2. changed ( ) {
89
+
90
+ requires_rp. from_map ( & requires, |& ( r, b, p) | ( ( r, p) , b) ) ;
91
+ requires_bp. from_map ( & requires, |& ( r, b, p) | ( ( b, p) , r) ) ;
92
+
93
+ // requires(R, B, P) :- borrow_region(R, B, P).
94
+ // Already loaded; borrow_region is static.
95
+
96
+ // requires(R2, B, P) :-
97
+ // requires(R1, B, P),
98
+ // subset(R1, R2, P).
99
+ requires. from_join ( & requires_rp, & subset_r1p, |& ( _r1, p) , & b, & r2| ( r2, b, p) ) ;
100
+
101
+ // requires(R, B, Q) :-
102
+ // requires(R, B, P),
103
+ // !killed(B, P),
104
+ // cfg_edge(P, Q),
105
+ // (region_live_at(R, Q); universal_region(R)).
106
+
107
+ requires_1. from_antijoin ( & requires_bp, & killed, |& ( b, p) , & r| ( p, ( b, r) ) ) ;
108
+ requires_2. from_join ( & requires_1, & cfg_edge_p, |& _p, & ( b, r) , & q| ( ( r, q) , b) ) ;
109
+ requires. from_join ( & requires_2, & region_live_at, |& ( r, q) , & b, & ( ) | ( r, b, q) ) ;
110
+ }
111
+
112
+ requires. complete ( )
113
+ } ;
114
+
115
+ // borrow_live_at(B, P) :- requires(R, B, P), region_live_at(R, P)
116
+
117
+ // borrow_live_at(B, P) :- requires(R, B, P), universal_region(R).
118
+
119
+ }
0 commit comments