@@ -231,38 +231,34 @@ let get_variable_equality_variables (lineq: linear_equality_t) =
231231 []
232232
233233
234- let linear_equality_get_expr e v =
234+ (* Note: the signature of this function should be changed into a result
235+ type; the function should not raise an exception.
236+ *)
237+ let linear_equality_get_expr (lineq : linear_equality_t ) (v : variable_t ): xpr_t option =
235238 let make_factor c f =
236239 if c#equal numerical_one then
237240 XVar f
238241 else
239242 XOp (XMult , [num_constant_expr c; XVar f]) in
240243 try
241- let (c, _f) = List. find (fun (_ , f ) -> f#equal v) e .leq_factors in
242- let xfactors = List. filter (fun (_ , f ) -> not (f#equal v)) e .leq_factors in
244+ let (c, _f) = List. find (fun (_ , f ) -> f#equal v) lineq .leq_factors in
245+ let xfactors = List. filter (fun (_ , f ) -> not (f#equal v)) lineq .leq_factors in
243246 let x =
244247 if c#equal numerical_one then
245248 List. fold_left (fun a (c ,f ) -> XOp (XPlus , [a; make_factor c#neg f]))
246- (num_constant_expr e .leq_constant) xfactors
249+ (num_constant_expr lineq .leq_constant) xfactors
247250 else if c#equal numerical_one#neg then
248251 List. fold_left (fun a (c ,f ) -> XOp (XPlus , [a; make_factor c f]))
249- (num_constant_expr e .leq_constant#neg) xfactors
252+ (num_constant_expr lineq .leq_constant#neg) xfactors
250253 else
251- raise
254+ raise
252255 (BCH_failure
253- (LBLOCK [
254- STR " Case with higher coefficients not yet handled: " ;
255- linear_equality_to_pretty e])) in
256- simplify_xpr x
256+ (LBLOCK [STR " Case with higher coefficients not yet handled: " ;
257+ linear_equality_to_pretty lineq])) in
258+ Some (simplify_xpr x)
257259 with
258- Not_found ->
259- raise
260- (BCH_failure
261- (LBLOCK [
262- STR " Variable " ;
263- v#toPretty;
264- STR " not found in linear equality " ;
265- linear_equality_to_pretty e]))
260+ | Not_found ->
261+ None
266262
267263
268264let linear_equality_compare e1 e2 =
@@ -416,6 +412,13 @@ object (self:'a)
416412 is_variable_equality lineq
417413 | _ -> false
418414
415+ method is_loopcounter_equality =
416+ match fact with
417+ | RelationalFact lineq ->
418+ List. exists (fun (_ , f ) -> List. mem " lc" f#getName#getAttributes)
419+ lineq.leq_factors
420+ | _ -> false
421+
419422 method get_variable_equality_variables =
420423 match fact with
421424 | RelationalFact lineq when is_variable_equality lineq ->
@@ -425,6 +428,14 @@ object (self:'a)
425428 (BCH_failure
426429 (LBLOCK [STR " Not a variable-equality: " ; self#toPretty]))
427430
431+ method get_var_loopcounter_expr (v: variable_t ): xpr_t option =
432+ if self#is_loopcounter_equality then
433+ match fact with
434+ | RelationalFact lineq -> linear_equality_get_expr lineq v
435+ | _ -> None
436+ else
437+ None
438+
428439 method is_smaller (other:'a ) =
429440 match (fact, other#get_fact) with
430441 | (NonRelationalFact (_ , i1 ), NonRelationalFact (_ , i2 )) -> is_smaller_nrv i1 i2
@@ -643,7 +654,13 @@ object (self)
643654 | NonRelationalFact (w , FSymbolicExpr x ) when w#equal v -> Some x
644655 | _ -> None ) None (self#get_var_facts v)
645656
646- method rewrite_expr (x :xpr_t ) =
657+ method private get_var_loopcounter_expr (v : variable_t ): xpr_t option =
658+ List. fold_left (fun acc inv ->
659+ match acc with
660+ | Some _ -> acc
661+ | _ -> inv#get_var_loopcounter_expr v) None self#get_facts
662+
663+ method rewrite_expr ?(loopcounter =false ) (x :xpr_t ) =
647664 let subst1 v =
648665 if self#is_constant v then
649666 XConst (IntConst (self#get_constant v))
@@ -662,7 +679,19 @@ object (self)
662679 match self#get_external_exprs v with
663680 | [] -> XVar v
664681 | x :: _tl -> x in
665- let x1 = simplify_xpr (substitute_expr subst1 x) in
682+ let subst_lc v =
683+ (* For now only user-designated loop counter variables are annotated
684+ with the lc attribute. Loop counter does not refer to the engine
685+ loop-counter variable. *)
686+ if loopcounter && (not (List. mem " lc" v#getName#getAttributes)) then
687+ let eq = self#get_var_loopcounter_expr v in
688+ match eq with
689+ | Some x -> x
690+ | _ -> XVar v
691+ else
692+ XVar v in
693+ let x0 = simplify_xpr (substitute_expr subst_lc x) in
694+ let x1 = simplify_xpr (substitute_expr subst1 x0) in
666695 let x2 = simplify_xpr (substitute_expr subst2 x1) in
667696 let x3 = simplify_xpr (substitute_expr subst3 x2) in
668697 let x4 = simplify_xpr (substitute_expr subst4 x3) in
@@ -920,6 +949,9 @@ object (self)
920949 | NonRelationalFact (w , FSymbolicExpr _ ) when v#equal w -> true
921950 | _ -> false ) false (self#get_var_facts v)
922951
952+ method has_loop_counter_equality : bool =
953+ List. exists (fun inv -> inv#is_loopcounter_equality) self#get_facts
954+
923955 method write_xml (node :xml_element_int ) =
924956 let invs = List. sort Stdlib. compare (H. fold (fun k _ a -> k::a) facts [] ) in
925957 if (List. length invs) > 0 then
@@ -1134,7 +1166,9 @@ object (self)
11341166 self#add iaddr (TestVarEquality (tvar,tval,taddr,jaddr))
11351167
11361168 method add_lineq (iaddr :string ) (nc :numerical_constraint_t ) =
1137- self#add iaddr (RelationalFact (numerical_constraint_to_linear_equality nc))
1169+ let lineq = numerical_constraint_to_linear_equality nc in
1170+ let fact = RelationalFact lineq in
1171+ self#add iaddr fact
11381172
11391173 method get_location_invariant (iaddr :string ) =
11401174 match invariants#get iaddr with
0 commit comments