You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
9.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
let%test_module _ =
( module struct
let () =
Trace.init ~margin:68
~config:(Result.ok_exn (Trace.parse "+Solver.infer_frame"))
()
(* let () =
* Trace.init ~margin:160
* ~config:
* (Result.ok_exn (Trace.parse "+Solver.infer_frame+Solver.excise"))
* () *)
let infer_frame p xs q =
Solver.infer_frame p (Var.Set.of_list xs) q
|> (ignore : Sh.t option -> _)
let check_frame p xs q =
Solver.infer_frame p (Var.Set.of_list xs) q
|> fun r -> assert (Option.is_some r)
let ( ! ) i = Term.integer (Z.of_int i)
let ( + ) = Term.add
let ( - ) = Term.sub
let ( * ) = Term.mul
let wrt = Var.Set.empty
let a_, wrt = Var.fresh "a" ~wrt
let a2_, wrt = Var.fresh "a" ~wrt
let a3_, wrt = Var.fresh "a" ~wrt
let b_, wrt = Var.fresh "b" ~wrt
let k_, wrt = Var.fresh "k" ~wrt
let l_, wrt = Var.fresh "l" ~wrt
let l2_, wrt = Var.fresh "l" ~wrt
let m_, wrt = Var.fresh "m" ~wrt
let n_, _ = Var.fresh "n" ~wrt
let a = Term.var a_
let a2 = Term.var a2_
let a3 = Term.var a3_
let b = Term.var b_
let k = Term.var k_
let l = Term.var l_
let l2 = Term.var l2_
let m = Term.var m_
let n = Term.var n_
let%expect_test _ =
check_frame Sh.emp [] Sh.emp ;
[%expect
{|
( infer_frame: emp \- emp
) infer_frame: emp |}]
let%expect_test _ =
check_frame (Sh.false_ Var.Set.empty) [] Sh.emp ;
[%expect
{|
( infer_frame: false \- emp
) infer_frame: false |}]
let%expect_test _ =
check_frame Sh.emp [n_; m_] (Sh.and_ (Term.eq m n) Sh.emp) ;
[%expect
{|
( infer_frame: emp \- %m_8, %n_9 . %m_8 = %n_9 emp
) infer_frame: %m_8 = %n_9 emp |}]
let%expect_test _ =
check_frame
(Sh.seg {loc= l; bas= b; len= m; siz= n; arr= a})
[] Sh.emp ;
[%expect
{|
( infer_frame: %l_6 -[ %b_4, %m_8 )-> %n_9,%a_1 \- emp
) infer_frame: %l_6 -[ %b_4, %m_8 )-> %n_9,%a_1 |}]
let%expect_test _ =
check_frame
(Sh.seg {loc= l; bas= b; len= m; siz= n; arr= a})
[]
(Sh.seg {loc= l; bas= b; len= m; siz= n; arr= a}) ;
[%expect
{|
( infer_frame:
%l_6 -[ %b_4, %m_8 )-> %n_9,%a_1
\- %l_6 -[ %b_4, %m_8 )-> %n_9,%a_1
) infer_frame: emp |}]
let%expect_test _ =
let common = Sh.seg {loc= l2; bas= b; len= !10; siz= !10; arr= a2} in
let seg1 = Sh.seg {loc= l; bas= b; len= !10; siz= !10; arr= a} in
let minued = Sh.star common seg1 in
let subtrahend =
Sh.and_ (Term.eq m n)
(Sh.exists
(Var.Set.of_list [m_])
(Sh.extend_us (Var.Set.of_list [m_]) common))
in
infer_frame minued [n_; m_] subtrahend ;
[%expect
{|
( infer_frame:
%l_6 -[ %b_4, 10 )-> 10,%a_1 * %l_7 -[ %b_4, 10 )-> 10,%a_2
\- %m_8, %n_9 .
%m_10 . %m_8 = %n_9 %l_7 -[ %b_4, 10 )-> 10,%a_2
) infer_frame:
%m_10 . %m_8 = %n_9 %l_6 -[ %b_4, 10 )-> 10,%a_1 |}]
let%expect_test _ =
check_frame
(Sh.star
(Sh.seg {loc= l; bas= b; len= m; siz= n; arr= a})
(Sh.seg {loc= l2; bas= b; len= m; siz= n; arr= a2}))
[]
(Sh.seg {loc= l; bas= b; len= m; siz= n; arr= a}) ;
[%expect
{|
( infer_frame:
%l_6 -[ %b_4, %m_8 )-> %n_9,%a_1
* %l_7 -[ %b_4, %m_8 )-> %n_9,%a_2
\- %l_6 -[ %b_4, %m_8 )-> %n_9,%a_1
) infer_frame: %l_7 -[ %b_4, %m_8 )-> %n_9,%a_2 |}]
let%expect_test _ =
check_frame
(Sh.star
(Sh.seg {loc= l; bas= l; len= !16; siz= !8; arr= a})
(Sh.seg {loc= l + !8; bas= l; len= !16; siz= !8; arr= a2}))
[a3_]
(Sh.seg {loc= l; bas= l; len= !16; siz= !16; arr= a3}) ;
[%expect
{|
( infer_frame:
%l_6 -[)-> 8,%a_1^8,%a_2 \- %a_3 . %l_6 -[)-> 16,%a_3
) infer_frame: %a_2 = _ (8,%a_1^8,%a_2) = %a_3 emp |}]
let%expect_test _ =
check_frame
(Sh.star
(Sh.seg {loc= l; bas= l; len= !16; siz= !8; arr= a})
(Sh.seg {loc= l + !8; bas= l; len= !16; siz= !8; arr= a2}))
[a3_; m_]
(Sh.seg {loc= l; bas= l; len= m; siz= !16; arr= a3}) ;
[%expect
{|
( infer_frame:
%l_6 -[)-> 8,%a_1^8,%a_2
\- %a_3, %m_8 .
%l_6 -[ %l_6, %m_8 )-> 16,%a_3
) infer_frame:
%a_2 = _ (8,%a_1^8,%a_2) = %a_3 16 = %m_8 emp |}]
let%expect_test _ =
check_frame
(Sh.star
(Sh.seg {loc= l; bas= l; len= !16; siz= !8; arr= a})
(Sh.seg {loc= l + !8; bas= l; len= !16; siz= !8; arr= a2}))
[a3_; m_]
(Sh.seg {loc= l; bas= l; len= m; siz= m; arr= a3}) ;
[%expect
{|
( infer_frame:
%l_6 -[)-> 8,%a_1^8,%a_2
\- %a_3, %m_8 .
%l_6 -[ %l_6, %m_8 )-> %m_8,%a_3
) infer_frame:
%a_2 = _ (8,%a_1^8,%a_2) = %a_3 16 = %m_8 emp |}]
let%expect_test _ =
check_frame
(Sh.star
(Sh.seg {loc= k; bas= k; len= !16; siz= !32; arr= a})
(Sh.seg {loc= l; bas= l; len= !8; siz= !8; arr= !16}))
[a2_; m_; n_]
(Sh.star
(Sh.seg {loc= l; bas= l; len= !8; siz= !8; arr= n})
(Sh.seg {loc= k; bas= k; len= m; siz= n; arr= a2})) ;
[%expect
{|
( infer_frame:
%k_5 -[ %k_5, 16 )-> 32,%a_1 * %l_6 -[)-> 8,16
\- %a_2, %m_8, %n_9 .
%k_5 -[ %k_5, %m_8 )-> %n_9,%a_2 * %l_6 -[)-> 8,%n_9
) infer_frame:
%a0_10, %a1_11 .
%a_2 = %a0_10
(16,%a_2^16,%a1_11) = %a_1
16 = %m_8 = %n_9
(%k_5 + 16) -[ %k_5, 16 )-> 16,%a1_11 |}]
let%expect_test _ =
infer_frame
(Sh.star
(Sh.seg {loc= k; bas= k; len= !16; siz= !32; arr= a})
(Sh.seg {loc= l; bas= l; len= !8; siz= !8; arr= !16}))
[a2_; m_; n_]
(Sh.star
(Sh.seg {loc= k; bas= k; len= m; siz= n; arr= a2})
(Sh.seg {loc= l; bas= l; len= !8; siz= !8; arr= n})) ;
[%expect
{|
( infer_frame:
%k_5 -[ %k_5, 16 )-> 32,%a_1 * %l_6 -[)-> 8,16
\- %a_2, %m_8, %n_9 .
%k_5 -[ %k_5, %m_8 )-> %n_9,%a_2 * %l_6 -[)-> 8,%n_9
) infer_frame:
%a0_10, %a1_11 .
%a_2 = %a0_10
(16,%a_2^16,%a1_11) = %a_1
16 = %m_8 = %n_9
(%k_5 + 16) -[ %k_5, 16 )-> 16,%a1_11 |}]
let seg_split_symbolically =
Sh.star
(Sh.seg {loc= l; bas= l; len= !16; siz= !8 * n; arr= a2})
(Sh.seg
{ loc= l + (!8 * n)
; bas= l
; len= !16
; siz= !16 - (!8 * n)
; arr= a3 })
let%expect_test _ =
check_frame
(Sh.and_
Term.(or_ (or_ (eq n !0) (eq n !1)) (eq n !2))
seg_split_symbolically)
[m_; a_]
(Sh.seg {loc= l; bas= l; len= m; siz= m; arr= a}) ;
[%expect
{|
( infer_frame:
(%l_6 + 8 × %n_9) -[ %l_6, 16 )-> (-8 × %n_9 + 16),%a_3
* %l_6 -[ %l_6, 16 )-> (8 × %n_9),%a_2
* ( ( 2 = %n_9 emp)
( 0 = %n_9 emp)
( 1 = %n_9 emp)
)
\- %a_1, %m_8 .
%l_6 -[ %l_6, %m_8 )-> %m_8,%a_1
) infer_frame:
( ( %a_1 = %a_2
2 = %n_9
16 = %m_8
(%l_6 + 16) -[ %l_6, 16 )-> 0,%a_3)
( %a_3 = _
(8,%a_2^8,%a_3) = %a_1
1 = %n_9
16 = %m_8
emp)
( %a_3 = _
(0,%a_2^16,%a_3) = %a_1
0 = %n_9
16 = %m_8
emp)
) |}]
(* Incompleteness: equivalent to above but using ≤ instead of *)
let%expect_test _ =
infer_frame
(Sh.and_ (Term.le n !2) seg_split_symbolically)
[m_; a_]
(Sh.seg {loc= l; bas= l; len= m; siz= m; arr= a}) ;
[%expect
{|
( infer_frame:
(%n_9 2)
(%l_6 + 8 × %n_9) -[ %l_6, 16 )-> (-8 × %n_9 + 16),%a_3
* %l_6 -[ %l_6, 16 )-> (8 × %n_9),%a_2
\- %a_1, %m_8 .
%l_6 -[ %l_6, %m_8 )-> %m_8,%a_1
) infer_frame: |}]
(* Incompleteness: cannot witness existentials to satisfy non-equality
pure constraints *)
let%expect_test _ =
let subtrahend = Sh.and_ (Term.eq m a) (Sh.pure (Term.dq m !0)) in
let minuend = Sh.extend_us (Var.Set.of_ a_) Sh.emp in
infer_frame minuend [m_] subtrahend ;
[%expect
{|
( infer_frame: emp \- %m_8 . %a_1 = %m_8 (%a_1 0) emp
) infer_frame: |}]
end )