11use super :: CombDataflow ;
22use crate :: ir_visitor:: { Action , Construct , Visitor , VisitorData } ;
3- use core:: time;
43use easy_smt:: { self as smt, SExpr , SExprData } ;
5- use fil_ir:: { self as ir, AddCtx , Ctx , DisplayCtx , MutCtx , PortOwner } ;
4+ use fil_ir:: { self as ir, AddCtx , Ctx , DisplayCtx , MutCtx , PortOwner , Subst } ;
65use fil_utils:: { AttrCtx , CompNum } ;
76use itertools:: Itertools ;
87use std:: { collections:: HashMap , fs} ;
@@ -102,6 +101,128 @@ impl Solve {
102101 self . sol . assert ( self . sol . not ( equalities) ) . unwrap ( ) ;
103102 }
104103 }
104+
105+ pub fn timesub_to_sexp (
106+ & self ,
107+ ctx : & ir:: Component ,
108+ event_bind : & ir:: SparseInfoMap < ir:: Event , SExpr > ,
109+ time_sub : & ir:: TimeSub ,
110+ ) -> SExpr {
111+ match time_sub {
112+ fil_ir:: TimeSub :: Unit ( idx) => {
113+ self . expr_to_sexp ( ctx, event_bind, * idx)
114+ }
115+ fil_ir:: TimeSub :: Sym { l, r } => {
116+ let l = self . time_to_sexp ( ctx, event_bind, * l) ;
117+ let r = self . time_to_sexp ( ctx, event_bind, * r) ;
118+ self . sol . sub ( l, r)
119+ }
120+ }
121+ }
122+
123+ pub fn time_to_sexp (
124+ & self ,
125+ ctx : & ir:: Component ,
126+ event_bind : & ir:: SparseInfoMap < ir:: Event , SExpr > ,
127+ time : ir:: TimeIdx ,
128+ ) -> SExpr {
129+ let ir:: Time { event, offset } = ctx. get ( time) ;
130+
131+ let offset = self . expr_to_sexp ( ctx, event_bind, * offset) ;
132+ let event = * event_bind. get ( * event) ;
133+
134+ self . sol . plus ( event, offset)
135+ }
136+
137+ /// Fold an expression to an SExpr
138+ pub fn expr_to_sexp (
139+ & self ,
140+ ctx : & ir:: Component ,
141+ event_bind : & ir:: SparseInfoMap < ir:: Event , SExpr > ,
142+ expr : ir:: ExprIdx ,
143+ ) -> SExpr {
144+ match ctx. get ( expr) {
145+ fil_ir:: Expr :: Concrete ( n) => self . sol . numeral ( * n) ,
146+ fil_ir:: Expr :: Bin { op, lhs, rhs } => {
147+ let lhs = self . expr_to_sexp ( ctx, event_bind, * lhs) ;
148+ let rhs = self . expr_to_sexp ( ctx, event_bind, * rhs) ;
149+ match op {
150+ fil_ast:: Op :: Add => self . sol . plus ( lhs, rhs) ,
151+ fil_ast:: Op :: Sub => self . sol . sub ( lhs, rhs) ,
152+ fil_ast:: Op :: Mul => self . sol . times ( lhs, rhs) ,
153+ fil_ast:: Op :: Div => self . sol . div ( lhs, rhs) ,
154+ fil_ast:: Op :: Mod => self . sol . modulo ( lhs, rhs) ,
155+ }
156+ }
157+ fil_ir:: Expr :: If { cond, then, alt } => {
158+ let cond = self . prop_to_sexp ( ctx, event_bind, * cond) ;
159+ let then = self . expr_to_sexp ( ctx, event_bind, * then) ;
160+ let alt = self . expr_to_sexp ( ctx, event_bind, * alt) ;
161+ self . sol . ite ( cond, then, alt)
162+ }
163+ fil_ir:: Expr :: Fn { .. } => unreachable ! (
164+ "Constraints on scheduled components do not support custom function calls."
165+ ) ,
166+ fil_ir:: Expr :: Param ( _) => {
167+ unreachable ! ( "Parameters should have been monomorphized" )
168+ }
169+ }
170+ }
171+
172+ /// Fold a proposition on events to an SExpr
173+ pub fn prop_to_sexp (
174+ & self ,
175+ ctx : & ir:: Component ,
176+ event_bind : & ir:: SparseInfoMap < ir:: Event , SExpr > ,
177+ prop : ir:: PropIdx ,
178+ ) -> SExpr {
179+ match ctx. get ( prop) {
180+ fil_ir:: Prop :: True => self . sol . atom ( "true" ) ,
181+ fil_ir:: Prop :: False => self . sol . atom ( "false" ) ,
182+ fil_ir:: Prop :: Cmp ( ir:: CmpOp { op, lhs, rhs } ) => {
183+ let lhs = self . expr_to_sexp ( ctx, event_bind, * lhs) ;
184+ let rhs = self . expr_to_sexp ( ctx, event_bind, * rhs) ;
185+ match op {
186+ fil_ir:: Cmp :: Gt => self . sol . gt ( lhs, rhs) ,
187+ fil_ir:: Cmp :: Gte => self . sol . gte ( lhs, rhs) ,
188+ fil_ir:: Cmp :: Eq => self . sol . eq ( lhs, rhs) ,
189+ }
190+ }
191+ fil_ir:: Prop :: TimeCmp ( ir:: CmpOp { op, lhs, rhs } ) => {
192+ let lhs = self . time_to_sexp ( ctx, event_bind, * lhs) ;
193+ let rhs = self . time_to_sexp ( ctx, event_bind, * rhs) ;
194+ match op {
195+ fil_ir:: Cmp :: Gt => self . sol . gt ( lhs, rhs) ,
196+ fil_ir:: Cmp :: Gte => self . sol . gte ( lhs, rhs) ,
197+ fil_ir:: Cmp :: Eq => self . sol . eq ( lhs, rhs) ,
198+ }
199+ }
200+ fil_ir:: Prop :: TimeSubCmp ( ir:: CmpOp { op, lhs, rhs } ) => {
201+ let lhs = self . timesub_to_sexp ( ctx, event_bind, lhs) ;
202+ let rhs = self . timesub_to_sexp ( ctx, event_bind, rhs) ;
203+ match op {
204+ fil_ir:: Cmp :: Gt => self . sol . gt ( lhs, rhs) ,
205+ fil_ir:: Cmp :: Gte => self . sol . gte ( lhs, rhs) ,
206+ fil_ir:: Cmp :: Eq => self . sol . eq ( lhs, rhs) ,
207+ }
208+ }
209+ fil_ir:: Prop :: Not ( idx) => {
210+ self . sol . not ( self . prop_to_sexp ( ctx, event_bind, * idx) )
211+ }
212+ fil_ir:: Prop :: And ( idx, idx1) => self . sol . and (
213+ self . prop_to_sexp ( ctx, event_bind, * idx) ,
214+ self . prop_to_sexp ( ctx, event_bind, * idx1) ,
215+ ) ,
216+ fil_ir:: Prop :: Or ( idx, idx1) => self . sol . or (
217+ self . prop_to_sexp ( ctx, event_bind, * idx) ,
218+ self . prop_to_sexp ( ctx, event_bind, * idx1) ,
219+ ) ,
220+ fil_ir:: Prop :: Implies ( idx, idx1) => self . sol . imp (
221+ self . prop_to_sexp ( ctx, event_bind, * idx) ,
222+ self . prop_to_sexp ( ctx, event_bind, * idx1) ,
223+ ) ,
224+ }
225+ }
105226}
106227
107228impl Construct for Solve {
@@ -270,7 +391,9 @@ impl Visitor for Solve {
270391 // Intern all the constraints for the events
271392 let foreign_comp = data. ctx ( ) . get ( inv. inst . comp ( comp) ) ;
272393 for & constraint in foreign_comp. get_event_asserts ( ) {
273- let prop = foreign_comp. get ( constraint) ;
394+ self . sol
395+ . assert ( self . prop_to_sexp ( foreign_comp, & events, constraint) )
396+ . unwrap ( ) ;
274397 }
275398
276399 for pidx in inv. ports . iter ( ) {
@@ -280,32 +403,26 @@ impl Visitor for Solve {
280403 ir:: PortOwner :: Inv {
281404 base : foreign_pidx, ..
282405 } ,
283- live :
284- ir:: Liveness {
285- range : ir:: Range { start, end } ,
286- ..
287- } ,
288406 ..
289407 } = port
290408 else {
291409 unreachable ! ( "Port {} is not owned by an invocation" , pidx)
292410 } ;
293411
294- // Find the events associated with the start and end of the port
295- let start_expr = * events. get ( comp. get ( * start) . event ) ;
296- let end_expr = * events. get ( comp. get ( * end) . event ) ;
297-
298- let ( start, end) = foreign_pidx. apply (
412+ let ( start_expr, end_expr, start, end) = foreign_pidx. apply (
299413 |p, foreign_comp| {
300414 let ir:: Range { start, end } =
301415 foreign_comp. get ( p) . live . range ;
302416
417+ let start_expr = * events. get ( foreign_comp. get ( start) . event ) ;
418+ let end_expr = * events. get ( foreign_comp. get ( end) . event ) ;
419+
303420 let start =
304421 foreign_comp. get ( start) . offset . concrete ( foreign_comp) ;
305422 let end =
306423 foreign_comp. get ( end) . offset . concrete ( foreign_comp) ;
307424
308- ( start, end)
425+ ( start_expr , end_expr , start, end)
309426 } ,
310427 data. ctx ( ) ,
311428 ) ;
0 commit comments