From e0f5e14bdb83c232272d4d685d2c06734611145e Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 17:09:54 +0100 Subject: [PATCH 01/11] More examples, with a loop invariant --- rocq-brick-libstdcpp/test/dune.inc | 18 +++++++++ .../test/geeks_for_geeks_examples/N3_sum.cpp | 11 ++++++ .../test/geeks_for_geeks_examples/N3_sum.v | 20 ++++++++++ .../geeks_for_geeks_examples/N3_sum_a.cpp | 18 +++++++++ .../test/geeks_for_geeks_examples/N3_sum_a.v | 37 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index a5b255d..e1d3ecf 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -35,6 +35,24 @@ (run cpp2v -v %{input} -o N2_input_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps N2_input.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N3_sum_cpp.v) + (alias test_ast) + (deps (:input N3_sum.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N3_sum_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N3_sum.cpp)) +) +(subdir geeks_for_geeks_examples + (rule + (targets N3_sum_a_cpp.v) + (alias test_ast) + (deps (:input N3_sum_a.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N3_sum_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N3_sum_a.cpp)) +) (subdir geeks_for_geeks_examples (rule (targets iostream_cpp.v) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp new file mode 100644 index 0000000..f0bf9b0 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp @@ -0,0 +1,11 @@ +#include +using namespace std; + +int main() { + int a = 11, b = 9; + + // Adding the two numbers and printing + // their sum + cout << a + b; + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v new file mode 100644 index 0000000..e62a246 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v @@ -0,0 +1,20 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N3_sum_cpp. + +Import linearity. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + cpp.spec "main()" from source as main_spec with ( + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + _global "std::cout" |-> ostream_contentR 1$m (str ++ Z_to_string 20) + ). + + Lemma main_ok : verify?[source] main_spec. + Proof. verify_spec; go. Qed. +End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp new file mode 100644 index 0000000..9323d4c --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp @@ -0,0 +1,18 @@ +#include +using namespace std; + +int main() { + int a = 11, b = 9; + + // If b is positive, increment a to b times + for (int i = 0; i < b; i++) + a++; + + // If b is negative, decrement a to |b| times + for (int i = 0; i > b; i--) + a--; + + cout << a; + + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v new file mode 100644 index 0000000..d6047de --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v @@ -0,0 +1,37 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N3_sum_a_cpp. + +Import linearity. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + cpp.spec "main()" from source as main_spec with ( + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + _global "std::cout" |-> ostream_contentR 1$m (str ++ Z_to_string 20) + ). + + #[global] Declare Instance Z_to_string_inj : Inj eq eq Z_to_string. + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_spec; go. + + wp_for (fun ρ => + \pre{i1} _local ρ "i" |-> intR 1$m i1 + \pre _local ρ "a" |-> intR 1$m (11 + i1) + \require 0 <= i1 <= 9 + \post* _local ρ "i" |-> anyR "int" 1$m + \post* _local ρ "a" |-> intR 1$m 20 + \post emp + ). + + go. + wp_if; go. + wp_for (fun ρ => emp); go. + Qed. +End with_cpp. From 9fc58884be567e99722139cd9e9053f356de6211 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 19:14:14 +0100 Subject: [PATCH 02/11] Example 5 --- rocq-brick-libstdcpp/test/dune.inc | 9 ++ .../test/geeks_for_geeks_examples/N5_swap.cpp | 17 ++ .../test/geeks_for_geeks_examples/N5_swap.v | 146 ++++++++++++++++++ .../test/geeks_for_geeks_examples/spec.v | 5 + 4 files changed, 177 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index e1d3ecf..ffc3af3 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -53,6 +53,15 @@ (run cpp2v -v %{input} -o N3_sum_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps N3_sum_a.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N5_swap_cpp.v) + (alias test_ast) + (deps (:input N5_swap.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N5_swap_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N5_swap.cpp)) +) (subdir geeks_for_geeks_examples (rule (targets iostream_cpp.v) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp new file mode 100644 index 0000000..e1e67d6 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp @@ -0,0 +1,17 @@ +// https://www.geeksforgeeks.org/cpp/cpp-program-to-swap-two-numbers/ +#include +using namespace std; + +int main(){ + int a = 2, b = 3; + + cout << "Before swapping a = " << a << " , b = " << b << endl; + + int temp; + + temp = a; + a = b; + b = temp; + cout << "After swapping a = " << a << " , b = " << b << endl; + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v new file mode 100644 index 0000000..80c653f --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -0,0 +1,146 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N5_swap_cpp. + +Import linearity. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + cpp.spec "main()" from source as main_spec with ( + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + _global "std::cout" |-> ostream_contentR 1$m + (str ++ + "Before swapping a = " ++ + Z_to_string 2 ++ " , b = " ++ Z_to_string 3 ++ "\n" ++ + "After swapping a = " ++ Z_to_string 3 ++ " , b = " ++ Z_to_string 2 ++ "\n" + ) + ). + + Definition iostream_manip_spec f : WpSpec_cpp_val := ( + \arg{osP : ptr} "" (Vptr osP) + \prepost{osM} osP |-> ostreamR 1$m osM + \pre{str} osP |-> ostream_contentR 1$m str + \post[Vptr osP] osP |-> ostream_contentR 1$m (f str)). + + Definition ostream_cpp_type : type := + "std::basic_ostream>&". + Definition iostream_manip_kind : okind := + tFunction ostream_cpp_type [ostream_cpp_type]. + + cpp.spec "std::endl>(std::basic_ostream>&)" from source as endl_spec with ( + \exact Reduce iostream_manip_spec (fun str => str ++ "\n")%bs + ). + + (* This is the overload taking the endl manipulator. *) + cpp.spec "std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))" from source as ostream_insert_string_spec with ( + \this this + \arg{os_f} "" (Vptr os_f) + \pre{stream_f} + os_f |-> unmaterialized_specR + iostream_manip_kind + (iostream_manip_spec stream_f) + \prepost{osM} this |-> ostreamR 1$m osM + \pre{str} this |-> ostream_contentR 1$m str + \post[Vptr this] + this |-> ostream_contentR 1$m (stream_f str) + ). + + #[program] + Definition hint_stream_F := + \cancelx@{mpredI} + \bound_existential (stream_f : cstring.t → cstring.t) + \instantiate stream_f := fun str => (str ++ "\n")%bs + \end. + Next Obligation. work. Qed. + + (* #[program] + Definition hint_stream_F := + \cancelx@{mpredI} + \bound_existential (stream_f : cstring.t → cstring.t) + (* \goal_trigger{os_f : ptr} + os_f |-> unmaterialized_specR + iostream_manip_kind + (iostream_manip_spec stream_f) *) + \goal_trigger{os_f : ptr} + os_f |-> cptrR + iostream_manip_kind + (iostream_manip_spec stream_f) + \instantiate stream_f := (fun str => str ++ "\n")%bs + + \end. + Next Obligation. work. Qed. *) + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_shift; go. + +(** +_ : denoteModule source +_ : ostream_insert_string_spec +_ : endl_spec +_ : ostream_print_int_spec +_ : ostream_insert_spec +_ : type_ptr "int" a_addr +_ : type_ptr "int" b_addr +_ : type_ptr "char" _x_1 +_ : ∀ q : Qp, _x_1 |-> cstring.R q$c "Before swapping a = " ={⊤}=∗ emp +_ : type_ptr "char" _x_4 +_ : ∀ q : Qp, _x_4 |-> cstring.R q$c " , b = " ={⊤}=∗ emp +--------------------------------------□ +_ : PostCond +_ : _x_1 |-> cstring.R _x_2$c "Before swapping a = " +_ : a_addr |-> intR 1$m 2 +_ : _x_4 |-> cstring.R _x_5$c " , b = " +_ : b_addr |-> intR 1$m 3 +--------------------------------------∗ +∃ stream_f : cstring.t → cstring.t, +_global "std::endl>(std::basic_ostream>&)" +|-> cptrR +(unmaterialized_fspec (tFunction ostream_cpp_type [ostream_cpp_type]) +(add_with +(λ osP : ptr, +add_arg (Vptr osP) +(add_with +(λ osM0 : ostreamT, +add_pre ([...]) +([...])) "osM" DummyValue)) "osP" DummyValue)) ∗ +(_global "std::cout" |-> ostreamR 1$m osM ∗ +_global "std::cout" +|-> ostream_contentR 1$m +(stream_f ((((str ++ "Before swapping a = ") ++ Z_to_string 2) ++ " , b = ") ++ Z_to_string 3)%bs) -∗ +interp source 1 +(interp source ((1 >*> 1) >*> ((1 >*> 1) >*> ((1 >*> 1) >*> (([...]) >*> ([...]))))) +(wp_block source [region: "b" @ b_addr; "a" @ a_addr; return {?: "int"}] +[Sdecl [Dvar "temp" "int" None]; Sexpr (Eassign (Evar "temp" "int") (Ecast Cl2r ([...])) "int"); +Sexpr (Eassign (Evar "a" "int") (Ecast Cl2r ([...])) "int"); +Sexpr (Eassign (Evar "b" "int") (Ecast Cl2r ([...])) "int"); +Sexpr +(Eoperator_call OOLessLess +(operator_impl.MFunc +"std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))"%cpp_name +Direct +"std::basic_ostream>&(std::basic_ostream>&(*)(std::basic_ostream>&))"%cpp_type) +[Eoperator_call OOLessLess +([...]) +[[...]; +[...]]; +Ecast Cfun2ptr +([...])]); +Sreturn (Some (Eint 0 "int"))] +(Kfree source ((1 >*> FreeTemps.delete "int" b_addr) >*> FreeTemps.delete "int" a_addr) +(Kcleanup source [] (Kreturn ([...]))))))) +*) + + iExists (_ : cstring.t → cstring.t); work with br_erefl; go. + (* iExists (fun str => str ++ "\n")%bs; go. *) + iExists (_ : cstring.t → cstring.t); work with br_erefl; go. + banish_string_literals. + iModIntro. + rewrite -!(assoc_L BS.append). + go. + Qed. +End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v index bcc48b1..1d874c9 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -16,6 +16,11 @@ Proof. elim: x => [|x xs /= IH] [|y1 ys1] [|y2 ys2] //= [/(inj (BS.append _))] //. Qed. +#[global] Instance BS_append_assoc : Assoc eq BS.append. +Proof. + elim => [|x xs IH] [|y ys] [|z zs] //=. all: by rewrite -IH. +Qed. + #[global] Instance refine_bs_app' (str a b : BS.t) : Refine1 true true (str ++ a = str ++ b)%bs [a = b]. Proof. tac_refine. move: H. apply: inj. Qed. From 4e662c25039db5228d140ea729900e6107af86c5 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 19:53:41 +0100 Subject: [PATCH 03/11] iostream spec: Let stream manipulators modify stream state --- .../test/geeks_for_geeks_examples/N5_swap.v | 29 +++++++++++-------- .../test/geeks_for_geeks_examples/spec.v | 2 ++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v index 80c653f..f0c3e58 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -20,11 +20,13 @@ Section with_cpp. ) ). - Definition iostream_manip_spec f : WpSpec_cpp_val := ( + Definition iostream_manip_spec state_f contents_f : WpSpec_cpp_val := ( \arg{osP : ptr} "" (Vptr osP) - \prepost{osM} osP |-> ostreamR 1$m osM + (* XXX: manipulators can modify [osM]! *) + \pre{osM} osP |-> ostreamR 1$m osM + \post* osP |-> ostreamR 1$m (state_f osM) \pre{str} osP |-> ostream_contentR 1$m str - \post[Vptr osP] osP |-> ostream_contentR 1$m (f str)). + \post[Vptr osP] osP |-> ostream_contentR 1$m (contents_f str)). Definition ostream_cpp_type : type := "std::basic_ostream>&". @@ -32,18 +34,19 @@ Section with_cpp. tFunction ostream_cpp_type [ostream_cpp_type]. cpp.spec "std::endl>(std::basic_ostream>&)" from source as endl_spec with ( - \exact Reduce iostream_manip_spec (fun str => str ++ "\n")%bs + \exact Reduce iostream_manip_spec (fun osM => osM) (fun str => str ++ "\n")%bs ). (* This is the overload taking the endl manipulator. *) cpp.spec "std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))" from source as ostream_insert_string_spec with ( \this this \arg{os_f} "" (Vptr os_f) - \pre{stream_f} + \pre{state_f stream_f} os_f |-> unmaterialized_specR iostream_manip_kind - (iostream_manip_spec stream_f) - \prepost{osM} this |-> ostreamR 1$m osM + (iostream_manip_spec state_f stream_f) + \pre{osM} this |-> ostreamR 1$m osM + \post* this |-> ostreamR 1$m (state_f osM) \pre{str} this |-> ostream_contentR 1$m str \post[Vptr this] this |-> ostream_contentR 1$m (stream_f str) @@ -53,7 +56,9 @@ Section with_cpp. Definition hint_stream_F := \cancelx@{mpredI} \bound_existential (stream_f : cstring.t → cstring.t) + \bound_existential (state_f : ostreamT → ostreamT) \instantiate stream_f := fun str => (str ++ "\n")%bs + \instantiate state_f := fun osM => osM \end. Next Obligation. work. Qed. @@ -68,7 +73,7 @@ Section with_cpp. \goal_trigger{os_f : ptr} os_f |-> cptrR iostream_manip_kind - (iostream_manip_spec stream_f) + (iostream_manip_spec state_f stream_f) \instantiate stream_f := (fun str => str ++ "\n")%bs \end. @@ -135,12 +140,12 @@ Sreturn (Some (Eint 0 "int"))] (Kcleanup source [] (Kreturn ([...]))))))) *) - iExists (_ : cstring.t → cstring.t); work with br_erefl; go. - (* iExists (fun str => str ++ "\n")%bs; go. *) - iExists (_ : cstring.t → cstring.t); work with br_erefl; go. + (* iExists id, (fun str => str ++ "\n")%bs; go. *) + iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. + iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. banish_string_literals. iModIntro. rewrite -!(assoc_L BS.append). - go. + work. Qed. End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v index 1d874c9..1dafe13 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -25,6 +25,8 @@ Qed. Refine1 true true (str ++ a = str ++ b)%bs [a = b]. Proof. tac_refine. move: H. apply: inj. Qed. +#[global] Arguments BS.append : simpl never. + Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. From 34a7b72c5f07d1cd5176dbb5f8b8ff1e69bf82fb Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 21:44:10 +0100 Subject: [PATCH 04/11] Upstream specs --- .../test/geeks_for_geeks_examples/N5_swap.v | 32 --------------- .../test/geeks_for_geeks_examples/spec.v | 41 +++++++++++++++++++ 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v index f0c3e58..64b852a 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -20,38 +20,6 @@ Section with_cpp. ) ). - Definition iostream_manip_spec state_f contents_f : WpSpec_cpp_val := ( - \arg{osP : ptr} "" (Vptr osP) - (* XXX: manipulators can modify [osM]! *) - \pre{osM} osP |-> ostreamR 1$m osM - \post* osP |-> ostreamR 1$m (state_f osM) - \pre{str} osP |-> ostream_contentR 1$m str - \post[Vptr osP] osP |-> ostream_contentR 1$m (contents_f str)). - - Definition ostream_cpp_type : type := - "std::basic_ostream>&". - Definition iostream_manip_kind : okind := - tFunction ostream_cpp_type [ostream_cpp_type]. - - cpp.spec "std::endl>(std::basic_ostream>&)" from source as endl_spec with ( - \exact Reduce iostream_manip_spec (fun osM => osM) (fun str => str ++ "\n")%bs - ). - - (* This is the overload taking the endl manipulator. *) - cpp.spec "std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))" from source as ostream_insert_string_spec with ( - \this this - \arg{os_f} "" (Vptr os_f) - \pre{state_f stream_f} - os_f |-> unmaterialized_specR - iostream_manip_kind - (iostream_manip_spec state_f stream_f) - \pre{osM} this |-> ostreamR 1$m osM - \post* this |-> ostreamR 1$m (state_f osM) - \pre{str} this |-> ostream_contentR 1$m str - \post[Vptr this] - this |-> ostream_contentR 1$m (stream_f str) - ). - #[program] Definition hint_stream_F := \cancelx@{mpredI} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v index 1dafe13..87c0ddc 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -63,4 +63,45 @@ Section with_cpp. this |-> ostream_contentR 1$m (str ++ Z_to_string n) ). + cpp.spec "std::basic_ostream>::operator<<(unsigned long)" from source as ostream_print_ulong_spec with ( + \this this + \prepost{osM} this |-> ostreamR 1$m osM + \pre{str} this |-> ostream_contentR 1$m str + \arg{n} "" (Vint n) + \post[Vptr this] + this |-> ostream_contentR 1$m (str ++ Z_to_string n) + ). + + Definition iostream_manip_spec state_f contents_f : WpSpec_cpp_val := ( + \arg{osP : ptr} "" (Vptr osP) + (* XXX: manipulators can modify [osM]! *) + \pre{osM} osP |-> ostreamR 1$m osM + \post* osP |-> ostreamR 1$m (state_f osM) + \pre{str} osP |-> ostream_contentR 1$m str + \post[Vptr osP] osP |-> ostream_contentR 1$m (contents_f str)). + + Definition ostream_cpp_type : type := + "std::basic_ostream>&". + Definition iostream_manip_kind : okind := + tFunction ostream_cpp_type [ostream_cpp_type]. + + cpp.spec "std::endl>(std::basic_ostream>&)" from source as endl_spec with ( + \exact Reduce iostream_manip_spec (fun osM => osM) (fun str => str ++ "\n")%bs + ). + + (* This is the overload taking the endl manipulator. *) + cpp.spec "std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))" from source as ostream_insert_string_spec with ( + \this this + \arg{os_f} "" (Vptr os_f) + \pre{state_f stream_f} + os_f |-> unmaterialized_specR + iostream_manip_kind + (iostream_manip_spec state_f stream_f) + \pre{osM} this |-> ostreamR 1$m osM + \post* this |-> ostreamR 1$m (state_f osM) + \pre{str} this |-> ostream_contentR 1$m str + \post[Vptr this] + this |-> ostream_contentR 1$m (stream_f str) + ). + End with_cpp. From 8fa75b4a481a1de677c0014d76fae687e6758b0c Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 21:44:48 +0100 Subject: [PATCH 05/11] More examples --- rocq-brick-libstdcpp/test/dune.inc | 18 +++++++++ .../geeks_for_geeks_examples/N12_area.cpp | 30 +++++++++++++++ .../test/geeks_for_geeks_examples/N12_area.v | 37 +++++++++++++++++++ .../N6_print_sizeof.cpp | 31 ++++++++++++++++ .../N6_print_sizeof.v | 29 +++++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index ffc3af3..f708dd5 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -26,6 +26,15 @@ (run cpp2v -v %{input} -o N0_hello_world_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps N0_hello_world.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N12_area_cpp.v) + (alias test_ast) + (deps (:input N12_area.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N12_area_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N12_area.cpp)) +) (subdir geeks_for_geeks_examples (rule (targets N2_input_cpp.v) @@ -62,6 +71,15 @@ (run cpp2v -v %{input} -o N5_swap_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps N5_swap.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N6_print_sizeof_cpp.v) + (alias test_ast) + (deps (:input N6_print_sizeof.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N6_print_sizeof_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N6_print_sizeof.cpp)) +) (subdir geeks_for_geeks_examples (rule (targets iostream_cpp.v) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.cpp new file mode 100644 index 0000000..ccbab26 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.cpp @@ -0,0 +1,30 @@ +// C++ program to find area +// and perimeter of rectangle +#include +using namespace std; + +// Utility function +int areaRectangle(int a, int b) +{ + int area = a * b; + return area; +} + +int perimeterRectangle(int a, int b) +{ + int perimeter = 2*(a + b); + return perimeter; +} + +// Driver code +int main() +{ + int a = 5; + int b = 6; + cout << "Area = " << + areaRectangle(a, b) << + endl; + cout << "Perimeter = " << + perimeterRectangle(a, b); + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v new file mode 100644 index 0000000..baf4ec4 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v @@ -0,0 +1,37 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N12_area_cpp. + +Import linearity. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + Definition area_of_rectangle (side1 side2 : Z) := side1 * side2. + Definition perimeter_of_rectangle (side1 side2 : Z) := 2 * (side1 + side2). + Definition side1 := 5. + Definition side2 := 6. + + cpp.spec "main()" from source as main_spec with ( + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + _global "std::cout" |-> ostream_contentR 1$m + (str ++ "Area = " ++ Z_to_string (area_of_rectangle side1 side2) ++ "\n" ++ "Perimeter = " ++ Z_to_string (perimeter_of_rectangle side1 side2)) + ). + + cpp.spec "areaRectangle(int, int)" from source inline. + cpp.spec "perimeterRectangle(int, int)" from source inline. + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_shift; go. + iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. + + banish_string_literals. + iModIntro. + rewrite -!(assoc_L BS.append). + work. + Qed. +End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.cpp new file mode 100644 index 0000000..8e82db0 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.cpp @@ -0,0 +1,31 @@ +#include +using namespace std; + +int main() +{ + int integerType; + char charType; + float floatType; + double doubleType; + + // Calculate and Print + // the size of integer type + cout << "Size of int is: " << sizeof(integerType) + << "\n"; + + // Calculate and Print + // the size of doubleType + cout << "Size of char is: " << sizeof(charType) << "\n"; + + // Calculate and Print + // the size of charType + cout << "Size of float is: " << sizeof(floatType) + << "\n"; + + // Calculate and Print + // the size of floatType + cout << "Size of double is: " << sizeof(doubleType) + << "\n"; + + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v new file mode 100644 index 0000000..a11e0ec --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v @@ -0,0 +1,29 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N6_print_sizeof_cpp. + +Import linearity. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + cpp.spec "main()" from source as main_spec with ( + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + Exists str', + _global "std::cout" |-> ostream_contentR 1$m + (str ++ str') + ). + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_shift; go. + + banish_string_literals. + iModIntro. + rewrite -!(assoc_L BS.append). + work. + Qed. +End with_cpp. From 0db2ef354686f3737020ddacbf997d5fa1b0dfe5 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 22:06:47 +0100 Subject: [PATCH 06/11] Rephrase proofs for aggressive hint --- .../test/geeks_for_geeks_examples/N12_area.v | 2 +- .../test/geeks_for_geeks_examples/N5_swap.v | 2 +- .../test/geeks_for_geeks_examples/spec.v | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v index baf4ec4..0570fac 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N12_area.v @@ -31,7 +31,7 @@ Section with_cpp. banish_string_literals. iModIntro. - rewrite -!(assoc_L BS.append). work. + by rewrite -!(assoc_L BS.append). Qed. End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v index 64b852a..3f06e28 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -113,7 +113,7 @@ Sreturn (Some (Eint 0 "int"))] iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. banish_string_literals. iModIntro. - rewrite -!(assoc_L BS.append). work. + by rewrite -!(assoc_L BS.append). Qed. End with_cpp. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v index 87c0ddc..c7e640e 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -104,4 +104,13 @@ Section with_cpp. this |-> ostream_contentR 1$m (stream_f str) ). + Lemma ostream_contentR_aggressive (os_p : ptr) q str str': + os_p |-> ostream_contentR q str ⊢ + [| str = str' |] -∗ + os_p |-> ostream_contentR q str'. + Proof. work. Qed. + Definition ostream_contentR_aggressiveC := [CANCEL] ostream_contentR_aggressive. + End with_cpp. + +#[export] Hint Resolve ostream_contentR_aggressiveC : br_hints. From 8a49d09ad6b08147b723debaedb8e95b6c7ace44 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 22:09:24 +0100 Subject: [PATCH 07/11] Improve spec --- .../test/geeks_for_geeks_examples/N6_print_sizeof.v | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v index a11e0ec..e476f45 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v @@ -8,13 +8,19 @@ Import linearity. Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. + Definition newline := " +"%bs. + cpp.spec "main()" from source as main_spec with ( \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM \pre{str} _global "std::cout" |-> ostream_contentR 1$m str \post[Vint 0] - Exists str', _global "std::cout" |-> ostream_contentR 1$m - (str ++ str') + (str ++ + "Size of int is: " ++ Z_to_string 4 ++ newline ++ + "Size of char is: " ++ Z_to_string 1 ++ newline ++ + "Size of float is: " ++ Z_to_string 4 ++ newline ++ + "Size of double is: " ++ Z_to_string 8 ++ newline) ). Lemma main_ok : verify?[source] main_spec. @@ -23,7 +29,7 @@ Section with_cpp. banish_string_literals. iModIntro. - rewrite -!(assoc_L BS.append). work. + by rewrite -!(assoc_L BS.append). Qed. End with_cpp. From ebefe20434905af06a3b2a37c578ac07536f6aaa Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 12 Feb 2026 17:13:08 +0100 Subject: [PATCH 08/11] Fix numbers --- rocq-brick-libstdcpp/test/dune.inc | 58 ++++++++++++------- ...{N0_hello_world.cpp => N1_hello_world.cpp} | 0 .../{N0_hello_world.v => N1_hello_world.v} | 2 +- .../{N2_input.cpp => N3_input.cpp} | 0 .../{N2_input.v => N3_input.v} | 2 +- .../{N3_sum.cpp => N4_sum.cpp} | 0 .../{N3_sum.v => N4_sum.v} | 2 +- .../{N3_sum_a.cpp => N4_sum_a.cpp} | 0 .../{N3_sum_a.v => N4_sum_a.v} | 2 +- 9 files changed, 42 insertions(+), 24 deletions(-) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N0_hello_world.cpp => N1_hello_world.cpp} (100%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N0_hello_world.v => N1_hello_world.v} (96%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N2_input.cpp => N3_input.cpp} (100%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N2_input.v => N3_input.v} (99%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N3_sum.cpp => N4_sum.cpp} (100%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N3_sum.v => N4_sum.v} (97%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N3_sum_a.cpp => N4_sum_a.cpp} (100%) rename rocq-brick-libstdcpp/test/geeks_for_geeks_examples/{N3_sum_a.v => N4_sum_a.v} (98%) diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index f708dd5..b4ecf39 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -19,48 +19,48 @@ ) (subdir geeks_for_geeks_examples (rule - (targets N0_hello_world_cpp.v) + (targets N12_area_cpp.v) (alias test_ast) - (deps (:input N0_hello_world.cpp) (glob_files_rec ../*.hpp) (universe)) + (deps (:input N12_area.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N0_hello_world_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) - (alias (name srcs) (deps N0_hello_world.cpp)) + (run cpp2v -v %{input} -o N12_area_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N12_area.cpp)) ) (subdir geeks_for_geeks_examples (rule - (targets N12_area_cpp.v) + (targets N1_hello_world_cpp.v) (alias test_ast) - (deps (:input N12_area.cpp) (glob_files_rec ../*.hpp) (universe)) + (deps (:input N1_hello_world.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N12_area_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) - (alias (name srcs) (deps N12_area.cpp)) + (run cpp2v -v %{input} -o N1_hello_world_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N1_hello_world.cpp)) ) (subdir geeks_for_geeks_examples (rule - (targets N2_input_cpp.v) + (targets N3_input_cpp.v) (alias test_ast) - (deps (:input N2_input.cpp) (glob_files_rec ../*.hpp) (universe)) + (deps (:input N3_input.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N2_input_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) - (alias (name srcs) (deps N2_input.cpp)) + (run cpp2v -v %{input} -o N3_input_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N3_input.cpp)) ) (subdir geeks_for_geeks_examples (rule - (targets N3_sum_cpp.v) + (targets N4_sum_cpp.v) (alias test_ast) - (deps (:input N3_sum.cpp) (glob_files_rec ../*.hpp) (universe)) + (deps (:input N4_sum.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N3_sum_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) - (alias (name srcs) (deps N3_sum.cpp)) + (run cpp2v -v %{input} -o N4_sum_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N4_sum.cpp)) ) (subdir geeks_for_geeks_examples (rule - (targets N3_sum_a_cpp.v) + (targets N4_sum_a_cpp.v) (alias test_ast) - (deps (:input N3_sum_a.cpp) (glob_files_rec ../*.hpp) (universe)) + (deps (:input N4_sum_a.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N3_sum_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) - (alias (name srcs) (deps N3_sum_a.cpp)) + (run cpp2v -v %{input} -o N4_sum_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N4_sum_a.cpp)) ) (subdir geeks_for_geeks_examples (rule @@ -80,6 +80,24 @@ (run cpp2v -v %{input} -o N6_print_sizeof_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps N6_print_sizeof.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N8_ascii_value_cast_cpp.v) + (alias test_ast) + (deps (:input N8_ascii_value_cast.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N8_ascii_value_cast_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N8_ascii_value_cast.cpp)) +) +(subdir geeks_for_geeks_examples + (rule + (targets N8_ascii_value_printf_cpp.v) + (alias test_ast) + (deps (:input N8_ascii_value_printf.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o N8_ascii_value_printf_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps N8_ascii_value_printf.cpp)) +) (subdir geeks_for_geeks_examples (rule (targets iostream_cpp.v) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.cpp similarity index 100% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.cpp diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v similarity index 96% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v index 21fd44d..2dabb26 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v @@ -1,7 +1,7 @@ Require Import skylabs.auto.cpp.prelude.proof. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. -Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N0_hello_world_cpp. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N1_hello_world_cpp. Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.cpp similarity index 100% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.cpp diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v similarity index 99% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v index a22b7cb..d911790 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v @@ -1,7 +1,7 @@ Require Import skylabs.auto.cpp.prelude.proof. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. -Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N2_input_cpp. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N3_input_cpp. Import linearity. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp similarity index 100% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.cpp rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.v similarity index 97% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.v index e62a246..fd17459 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.v @@ -1,7 +1,7 @@ Require Import skylabs.auto.cpp.prelude.proof. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. -Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N3_sum_cpp. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N4_sum_cpp. Import linearity. diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp similarity index 100% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.cpp rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.v similarity index 98% rename from rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v rename to rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.v index d6047de..f5bad0c 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_sum_a.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.v @@ -1,7 +1,7 @@ Require Import skylabs.auto.cpp.prelude.proof. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. -Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N3_sum_a_cpp. +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N4_sum_a_cpp. Import linearity. From bfbd44949e8f604b2da8c0a2a3e7e87b5aca8086 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 12 Feb 2026 17:15:33 +0100 Subject: [PATCH 09/11] Missing URLs --- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp | 2 ++ rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp | 2 ++ rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp | 1 + 3 files changed, 5 insertions(+) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp index f0bf9b0..b4c759e 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum.cpp @@ -1,3 +1,5 @@ +// https://www.geeksforgeeks.org/cpp/cpp-add-numbers/ + #include using namespace std; diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp index 9323d4c..bbadd7f 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N4_sum_a.cpp @@ -1,3 +1,5 @@ +// https://www.geeksforgeeks.org/cpp/cpp-add-numbers/, 2nd version + #include using namespace std; diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp index e1e67d6..b3b635d 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.cpp @@ -1,4 +1,5 @@ // https://www.geeksforgeeks.org/cpp/cpp-program-to-swap-two-numbers/ + #include using namespace std; From 35944828ff0ceadb5d241596537fd187fc0a576e Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 12 Feb 2026 17:18:55 +0100 Subject: [PATCH 10/11] fixup! Example 5 --- .../test/geeks_for_geeks_examples/N5_swap.v | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v index 3f06e28..3e02a3a 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -30,84 +30,9 @@ Section with_cpp. \end. Next Obligation. work. Qed. - (* #[program] - Definition hint_stream_F := - \cancelx@{mpredI} - \bound_existential (stream_f : cstring.t → cstring.t) - (* \goal_trigger{os_f : ptr} - os_f |-> unmaterialized_specR - iostream_manip_kind - (iostream_manip_spec stream_f) *) - \goal_trigger{os_f : ptr} - os_f |-> cptrR - iostream_manip_kind - (iostream_manip_spec state_f stream_f) - \instantiate stream_f := (fun str => str ++ "\n")%bs - - \end. - Next Obligation. work. Qed. *) - Lemma main_ok : verify?[source] main_spec. Proof. verify_shift; go. - -(** -_ : denoteModule source -_ : ostream_insert_string_spec -_ : endl_spec -_ : ostream_print_int_spec -_ : ostream_insert_spec -_ : type_ptr "int" a_addr -_ : type_ptr "int" b_addr -_ : type_ptr "char" _x_1 -_ : ∀ q : Qp, _x_1 |-> cstring.R q$c "Before swapping a = " ={⊤}=∗ emp -_ : type_ptr "char" _x_4 -_ : ∀ q : Qp, _x_4 |-> cstring.R q$c " , b = " ={⊤}=∗ emp ---------------------------------------□ -_ : PostCond -_ : _x_1 |-> cstring.R _x_2$c "Before swapping a = " -_ : a_addr |-> intR 1$m 2 -_ : _x_4 |-> cstring.R _x_5$c " , b = " -_ : b_addr |-> intR 1$m 3 ---------------------------------------∗ -∃ stream_f : cstring.t → cstring.t, -_global "std::endl>(std::basic_ostream>&)" -|-> cptrR -(unmaterialized_fspec (tFunction ostream_cpp_type [ostream_cpp_type]) -(add_with -(λ osP : ptr, -add_arg (Vptr osP) -(add_with -(λ osM0 : ostreamT, -add_pre ([...]) -([...])) "osM" DummyValue)) "osP" DummyValue)) ∗ -(_global "std::cout" |-> ostreamR 1$m osM ∗ -_global "std::cout" -|-> ostream_contentR 1$m -(stream_f ((((str ++ "Before swapping a = ") ++ Z_to_string 2) ++ " , b = ") ++ Z_to_string 3)%bs) -∗ -interp source 1 -(interp source ((1 >*> 1) >*> ((1 >*> 1) >*> ((1 >*> 1) >*> (([...]) >*> ([...]))))) -(wp_block source [region: "b" @ b_addr; "a" @ a_addr; return {?: "int"}] -[Sdecl [Dvar "temp" "int" None]; Sexpr (Eassign (Evar "temp" "int") (Ecast Cl2r ([...])) "int"); -Sexpr (Eassign (Evar "a" "int") (Ecast Cl2r ([...])) "int"); -Sexpr (Eassign (Evar "b" "int") (Ecast Cl2r ([...])) "int"); -Sexpr -(Eoperator_call OOLessLess -(operator_impl.MFunc -"std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))"%cpp_name -Direct -"std::basic_ostream>&(std::basic_ostream>&(*)(std::basic_ostream>&))"%cpp_type) -[Eoperator_call OOLessLess -([...]) -[[...]; -[...]]; -Ecast Cfun2ptr -([...])]); -Sreturn (Some (Eint 0 "int"))] -(Kfree source ((1 >*> FreeTemps.delete "int" b_addr) >*> FreeTemps.delete "int" a_addr) -(Kcleanup source [] (Kreturn ([...]))))))) -*) - (* iExists id, (fun str => str ++ "\n")%bs; go. *) iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. iExists (_ : ostreamT → ostreamT), (_ : cstring.t → cstring.t); work with br_erefl; go. From 944dabf8b113528549095524bf0e560f3757da88 Mon Sep 17 00:00:00 2001 From: Gregory Malecha Date: Thu, 12 Feb 2026 23:56:36 -0500 Subject: [PATCH 11/11] A sketch of a refinement-based setup. --- .../test/geeks_for_geeks_examples/spec.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v index c7e640e..32ac5d1 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -30,12 +30,13 @@ Proof. tac_refine. move: H. apply: inj. Qed. Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. - Parameter ostreamT : Type. - Parameter ostreamR : cQp.t -> ostreamT -> Rep. - Parameter ostream_contentR : cQp.t -> cstring.t -> Rep. + Parameter ostreamR : cQp.t -> gname -> Rep. + + (** This is effectively an <> that yields the characters and then continues *) + Parameter ostream_yield : gname -> string -> mpred -> mpred. #[global] Instance: LearnEqF1 ostreamR := ltac:(solve_learnable). - #[global] Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). + (* #[global] Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). *) Parameter istreamT : Type. Parameter istreamR : cQp.t -> istreamT -> Rep. @@ -43,12 +44,11 @@ Section with_cpp. cpp.spec "std::operator<<>(std::basic_ostream>&, const char*)" from source as ostream_insert_spec with ( \arg{osP} "" (Vptr osP) - \prepost{osM} osP |-> ostreamR 1$m osM - \pre{str} osP |-> ostream_contentR 1$m str + \prepost{γ} osP |-> ostreamR 1$m γ \arg{strP} "" (Vptr strP) \prepost{q__s strM} strP |-> cstring.R q__s strM - \post[Vptr osP] - osP |-> ostream_contentR 1$m (str ++ strM)). + \pre{Q} ostream_yield γ _ Q + \post[Vptr osP] Q) Parameter Z_to_string : Z -> cstring.t. #[global] Declare Instance Z_to_string_inj : Inj eq eq Z_to_string.