From 10cb2f0f5033723f7b7fc965b19395e0322e57f1 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 15:25:01 +0100 Subject: [PATCH 01/21] Remove duplication --- rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh | 139 +------------------ 1 file changed, 1 insertion(+), 138 deletions(-) mode change 100755 => 120000 rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh diff --git a/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh b/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh deleted file mode 100755 index a228dca..0000000 --- a/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2020-2025 BlueRock Security, Inc. -# -# This software is distributed under the terms of the BedRock Open-Source License. -# See the LICENSE-BedRock file in the repository root for details. -# - -usage() { - cat >&2 <<-EOF - usage: $(basename "$0") [ -t ] . -- [ ] - - This will output (to stdout) dune rules for building ., - passing to cpp2v. Redirect output to dune.inc and - load via dune's include. - - The output is filesystem-independent and . need not exist. - Placing the output in /dune.inc will transform - /. into /_.v and - /__names.v and (with \`-t\`) - /__templates.v. - EOF - exit 1 -} - -outRule() { - local indent fullName name ext - indent="$1" - fullName="$2" - shift 2 - - # The extension starts at the last dot: - name="${fullName%.*}" - if [ "$name" = "$fullName" ]; then - echo -e "Error: filename '$fullName' has no extension\n" >&2 - usage - fi - ext="${fullName##*.}" - - local module="${name}_${ext}.v" - local targ="${module}" - local clang_options="" - local universe="" - if [ "$system" = 1 ]; then - universe=" (universe)" - fi - local cpp2v="cpp2v -v %{input} -o ${module}" - - if [ "$gen_names" = 1 ]; then - local names="${name}_${ext}_names.v" - targ="${targ} ${names}" - cpp2v="${cpp2v} -names ${names}" - fi - - if [ "$templates" = 1 ]; then - local templates="${name}_${ext}_templates.v" - cpp2v="${cpp2v} --templates=${templates}" - targ="$targ ${templates}" - fi - - action="(run ${cpp2v} ${1+ $@} ${clang_options})" - - sed "s/^/${indent}/" <<-EOF - (rule - (targets ${module}.stderr ${targ}) - (alias test_ast) - (deps (:input ${name}.${ext}) (glob_files_rec ${prefix}*.hpp)${universe}) - (action - (with-stderr-to ${module}.stderr ${action}))) - (alias (name srcs) (deps ${name}.${ext})) - EOF - # TODO: maybe drop @srcs alias, seems leftover from !2613 -} - -traverse() { - local indent path firstDir rest - indent="$1" - path="$2" - shift 2 - firstDir="${path%%/*}" - rest="${path#*/}" - if [ "$firstDir" = "$path" ]; then - outRule "$indent" "$path" "$@" - elif [ "$firstDir" = "." ]; then - traverse "$indent" "$rest" "$@" - else - #echo DIR $firstDir - #echo REST $rest - echo "${indent}(subdir ${firstDir}" - (cd "${firstDir}"; traverse " $indent" "$rest" "$@") - echo "${indent})" - fi -} - -gen_names=0 -templates=0 -system=0 -prefix="../" -while : -do - case "$1" in - -n) - gen_names=1 - shift - ;; - -t) - templates=1 - shift - ;; - -s) - system=1 - shift - ;; - -p) - shift - prefix="$1" - shift - ;; - --) - shift - break - ;; - -*) - usage - ;; - *) - break - ;; - esac -done -[ $# -ge 1 ] || usage - -path="$1" -shift - -traverse "" "$path" "$@" - -# vim:set noet sw=8: diff --git a/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh b/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh new file mode 120000 index 0000000..de18be0 --- /dev/null +++ b/rocq-brick-libstdcpp/proof/cpp2v-dune-gen.sh @@ -0,0 +1 @@ +../test/cpp2v-dune-gen.sh \ No newline at end of file From 6cec5c28e916846b7bc1bd9af14dea779aadfe74 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 15:25:54 +0100 Subject: [PATCH 02/21] Add --no-elaborate --- rocq-brick-libstdcpp/test/cpp2v-dune-gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocq-brick-libstdcpp/test/cpp2v-dune-gen.sh b/rocq-brick-libstdcpp/test/cpp2v-dune-gen.sh index a228dca..d6ef98b 100755 --- a/rocq-brick-libstdcpp/test/cpp2v-dune-gen.sh +++ b/rocq-brick-libstdcpp/test/cpp2v-dune-gen.sh @@ -44,7 +44,7 @@ outRule() { if [ "$system" = 1 ]; then universe=" (universe)" fi - local cpp2v="cpp2v -v %{input} -o ${module}" + local cpp2v="cpp2v -v %{input} -o ${module} --no-elaborate" if [ "$gen_names" = 1 ]; then local names="${name}_${ext}_names.v" From cfb0af5696a2e527df5572daf9560bd8d8e52c41 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 15:25:22 +0100 Subject: [PATCH 03/21] TMP Update generated dune.inc --- rocq-brick-libstdcpp/proof/dune.inc | 36 ++++++++++++++--------------- rocq-brick-libstdcpp/test/dune.inc | 21 ++++++++++++----- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/rocq-brick-libstdcpp/proof/dune.inc b/rocq-brick-libstdcpp/proof/dune.inc index dd49356..4482e93 100644 --- a/rocq-brick-libstdcpp/proof/dune.inc +++ b/rocq-brick-libstdcpp/proof/dune.inc @@ -1,82 +1,82 @@ ; DO NOT EDIT: Generated by "./dune-gen.sh" (subdir cassert (rule - (targets inc_cassert_cpp.v.stderr inc_cassert_cpp.v) + (targets inc_cassert_cpp.v) (alias test_ast) (deps (:input inc_cassert.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_cassert_cpp.v.stderr (run cpp2v -v %{input} -o inc_cassert_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_cassert_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc_cassert.cpp)) ) (subdir cctype (rule - (targets inc_cctype_cpp.v.stderr inc_cctype_cpp.v) + (targets inc_cctype_cpp.v) (alias test_ast) (deps (:input inc_cctype.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_cctype_cpp.v.stderr (run cpp2v -v %{input} -o inc_cctype_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_cctype_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc_cctype.cpp)) ) (subdir cstdlib (rule - (targets inc_cstdlib_cpp.v.stderr inc_cstdlib_cpp.v) + (targets inc_cstdlib_cpp.v) (alias test_ast) (deps (:input inc_cstdlib.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_cstdlib_cpp.v.stderr (run cpp2v -v %{input} -o inc_cstdlib_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_cstdlib_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc_cstdlib.cpp)) ) (subdir mutex (rule - (targets demo_cpp.v.stderr demo_cpp.v) + (targets demo_cpp.v) (alias test_ast) (deps (:input demo.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to demo_cpp.v.stderr (run cpp2v -v %{input} -o demo_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps demo.cpp)) ) (subdir mutex (rule - (targets inc_hpp.v.stderr inc_hpp.v) + (targets inc_hpp.v) (alias test_ast) (deps (:input inc.hpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_hpp.v.stderr (run cpp2v -v %{input} -o inc_hpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc.hpp)) ) (subdir mutex (rule - (targets test_cpp.v.stderr test_cpp.v) + (targets test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps test.cpp)) ) (subdir new (rule - (targets inc_new_cpp.v.stderr inc_new_cpp.v) + (targets inc_new_cpp.v) (alias test_ast) (deps (:input inc_new.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_new_cpp.v.stderr (run cpp2v -v %{input} -o inc_new_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_new_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc_new.cpp)) ) (subdir semaphore (rule - (targets inc_hpp.v.stderr inc_hpp.v) + (targets inc_hpp.v) (alias test_ast) (deps (:input inc.hpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to inc_hpp.v.stderr (run cpp2v -v %{input} -o inc_hpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps inc.hpp)) ) (subdir semaphore (rule - (targets test_cpp.v.stderr test_cpp.v) + (targets test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps test.cpp)) ) diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index 37569d2..a781725 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -1,28 +1,37 @@ ; DO NOT EDIT: Generated by "./dune-gen.sh" (subdir cctype (rule - (targets test_cpp.v.stderr test_cpp.v) + (targets test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps test.cpp)) ) (subdir cstdlib (rule - (targets test_cpp.v.stderr test_cpp.v) + (targets test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps test.cpp)) ) +(subdir geeks_for_geeks_examples + (rule + (targets N0_hello_world_cpp.v) + (alias test_ast) + (deps (:input N0_hello_world.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)) +) (subdir new (rule - (targets demo_cpp.v.stderr demo_cpp.v) + (targets demo_cpp.v) (alias test_ast) (deps (:input demo.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (with-stderr-to demo_cpp.v.stderr (run cpp2v -v %{input} -o demo_cpp.v -- -std=c++20 -stdlib=libstdc++ )))) + (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) (alias (name srcs) (deps demo.cpp)) ) From b6ef46fe39828829e72d374cb1e5eaea1c531740 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 15:35:36 +0100 Subject: [PATCH 04/21] Examples WIP --- .../N0_hello_world.cpp | 22 +++++ .../geeks_for_geeks_examples/N0_hello_world.v | 85 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.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/N0_hello_world.cpp new file mode 100644 index 0000000..e570d51 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp @@ -0,0 +1,22 @@ +#include +// #include + +using namespace std; + +int main() { + // Printing the name using cout object + cout << "Anmol"; + return 0; +} + +// #include +// #include + +// using namespace std; + +// int main() { +// // Printing the name +// puts("Anmol"); +// cout << "Anmol"; +// return 0; +// } diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v new file mode 100644 index 0000000..a830cd8 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v @@ -0,0 +1,85 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Import skylabs.cpp.string. +Require Import skylabs.lang.cpp.parser.plugin.cpp2v. + +(** TODO upstream *) +#[only(cfracsplittable)] derive cstring.R. + +(** TODO upstream *) +Bind Scope bs_scope with cstring.t. +(* We only have `Bind Scope bs_scope with t.` inside `Module cstring.` *) + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N0_hello_world_cpp. + +(* cpp.prog source prog cpp:{{ + +// #include +#include + +int main() { + // Printing the name + puts("Anmol"); + // cout << "Anmol"; + return 0; +} +}}. *) + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + Parameter ostreamT : Type. + Parameter ostreamR : cQp.t -> ostreamT -> Rep. + Parameter ostream_contentR : cQp.t -> cstring.t -> Rep. + Instance: LearnEqF1 ostreamR := ltac:(solve_learnable). + Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). + + 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 + \arg{strP} "" (Vptr strP) + \prepost{q__s strM} strP |-> cstring.R q__s strM + \post[Vptr osP] + osP |-> ostream_contentR 1$m (str ++ strM)). + + 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 ++ "Anmol")). + + (* cpp.spec "puts" from source as puts_spec with ( + \arg{p} "" (Vptr p) + \prepost{q s} p |-> cstring.R q s + \post{n}[Vint n] emp). *) + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_spec; go. + Qed. + +End with_cpp. + +(* #include *) + +(* cpp.prog source prog cpp:{{ + +#include + +using namespace std; + +int main() { + // Printing the name using cout object + cout << "Anmol"; + return 0; +} +}}. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + cpp.spec "main()" as main_spec with + (\post emp). + + +End with_cpp. *) From 24cb3217b0f8109631cb30544af4c8118d593fae Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 16:34:41 +0100 Subject: [PATCH 05/21] Cleanup first example a bit --- rocq-brick-libstdcpp/test/dune.inc | 9 +++ .../N0_hello_world.cpp | 16 +---- .../geeks_for_geeks_examples/N0_hello_world.v | 66 +------------------ .../geeks_for_geeks_examples/iostream.cpp | 1 + .../test/geeks_for_geeks_examples/spec.v | 32 +++++++++ 5 files changed, 48 insertions(+), 76 deletions(-) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/iostream.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index a781725..ac9c705 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 iostream_cpp.v) + (alias test_ast) + (deps (:input iostream.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (run cpp2v -v %{input} -o iostream_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (alias (name srcs) (deps iostream.cpp)) +) (subdir new (rule (targets demo_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/N0_hello_world.cpp index e570d51..eef6f4f 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.cpp @@ -1,3 +1,4 @@ +// https://www.geeksforgeeks.org/cpp/writing-first-c-program-hello-world-example/ #include // #include @@ -5,18 +6,7 @@ using namespace std; int main() { // Printing the name using cout object - cout << "Anmol"; + cout << "Hello World"; + return 0; } - -// #include -// #include - -// using namespace std; - -// int main() { -// // Printing the name -// puts("Anmol"); -// cout << "Anmol"; -// return 0; -// } diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v index a830cd8..21fd44d 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N0_hello_world.v @@ -1,52 +1,16 @@ Require Import skylabs.auto.cpp.prelude.proof. -Require Import skylabs.cpp.string. -Require Import skylabs.lang.cpp.parser.plugin.cpp2v. - -(** TODO upstream *) -#[only(cfracsplittable)] derive cstring.R. - -(** TODO upstream *) -Bind Scope bs_scope with cstring.t. -(* We only have `Bind Scope bs_scope with t.` inside `Module cstring.` *) +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. -(* cpp.prog source prog cpp:{{ - -// #include -#include - -int main() { - // Printing the name - puts("Anmol"); - // cout << "Anmol"; - return 0; -} -}}. *) - Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. - Parameter ostreamT : Type. - Parameter ostreamR : cQp.t -> ostreamT -> Rep. - Parameter ostream_contentR : cQp.t -> cstring.t -> Rep. - Instance: LearnEqF1 ostreamR := ltac:(solve_learnable). - Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). - - 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 - \arg{strP} "" (Vptr strP) - \prepost{q__s strM} strP |-> cstring.R q__s strM - \post[Vptr osP] - osP |-> ostream_contentR 1$m (str ++ strM)). - - cpp.spec "main()" from source as main_spec with ( + cpp.spec "main()" from N0_hello_world_cpp.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 ++ "Anmol")). + _global "std::cout" |-> ostream_contentR 1$m (str ++ "Hello World")). (* cpp.spec "puts" from source as puts_spec with ( \arg{p} "" (Vptr p) @@ -59,27 +23,3 @@ Section with_cpp. Qed. End with_cpp. - -(* #include *) - -(* cpp.prog source prog cpp:{{ - -#include - -using namespace std; - -int main() { - // Printing the name using cout object - cout << "Anmol"; - return 0; -} -}}. - -Section with_cpp. - Context `{Σ : cpp_logic, σ : genv}. - - cpp.spec "main()" as main_spec with - (\post emp). - - -End with_cpp. *) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/iostream.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/iostream.cpp new file mode 100644 index 0000000..604782e --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/iostream.cpp @@ -0,0 +1 @@ +#include diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v new file mode 100644 index 0000000..9321767 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -0,0 +1,32 @@ +Require Import skylabs.auto.cpp.prelude.proof. +Require Export skylabs.cpp.string. + +(** TODO upstream *) +#[only(cfracsplittable)] derive cstring.R. + +(** TODO upstream *) +#[global] Bind Scope bs_scope with cstring.t. +(* We only have `Bind Scope bs_scope with t.` inside `Module cstring.` *) + +Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.iostream_cpp. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + Parameter ostreamT : Type. + Parameter ostreamR : cQp.t -> ostreamT -> Rep. + Parameter ostream_contentR : cQp.t -> cstring.t -> Rep. + + #[global] Instance: LearnEqF1 ostreamR := ltac:(solve_learnable). + #[global] Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). + + 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 + \arg{strP} "" (Vptr strP) + \prepost{q__s strM} strP |-> cstring.R q__s strM + \post[Vptr osP] + osP |-> ostream_contentR 1$m (str ++ strM)). + +End with_cpp. From 7e4d58985bc4fd05ba000cd9b662a7af44abd02c Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 16:34:59 +0100 Subject: [PATCH 06/21] New example, stuck on bug? Changing next --- rocq-brick-libstdcpp/test/dune.inc | 9 +++ .../geeks_for_geeks_examples/N2_input.cpp | 24 +++++++ .../test/geeks_for_geeks_examples/N2_input.v | 65 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index ac9c705..a5b255d 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 N2_input_cpp.v) + (alias test_ast) + (deps (:input N2_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)) +) (subdir geeks_for_geeks_examples (rule (targets iostream_cpp.v) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp new file mode 100644 index 0000000..1da1f13 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp @@ -0,0 +1,24 @@ +// https://www.geeksforgeeks.org/cpp/input-in-cpp/ + +#include +using namespace std; + +// int main(){ +// int i; +// // Take input using cin +// cin >> i; +// // Print output +// cout << i; +// return 0; +// } + +int main() { + string name; + int age; + // Take multiple input using cin + cin >> name >> age; + // Print output + cout << "Name : " << name << endl; + cout << "Age : " << age << endl; + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v new file mode 100644 index 0000000..b3de793 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v @@ -0,0 +1,65 @@ +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. + +Section with_cpp. + Context `{Σ : cpp_logic, σ : genv}. + + Parameter istreamT : Type. + Parameter istreamR : cQp.t -> istreamT -> Rep. + (* Parameter istream_contentR : cQp.t -> cstring.t -> Rep. *) + + cpp.spec "main()" from N2_input_cpp.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 ++ "Hello World")). + + (* cpp.spec "puts" from source as puts_spec with ( + \arg{p} "" (Vptr p) + \prepost{q s} p |-> cstring.R q s + \post{n}[Vint n] emp). *) + + Parameter cppStringR : cQp.t -> cstring.t -> Rep. + cpp.spec "std::__cxx11::basic_string, std::allocator>::basic_string()" from source as string_ctor_spec with ( + \this this + \post this |-> cppStringR 1$m ""). + + #[global] Declare Instance cppStringR_typed : Typed2 "std::__cxx11::basic_string, std::allocator>" cppStringR. + + #[ignore_missing] + cpp.spec + "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" + from source as istream_take_char_spec with ( + (* cpp.spec "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" from source with ( *) + \arg{isP} "" (Vptr isP) + \pre{isM} isP |-> istreamR 1$m isM + \arg{strP} "" (Vptr strP) + \pre{strM} strP |-> cppStringR 1$m strM + \post[Vptr isP] + Exists isM' strM', + isP |-> istreamR 1$m isM' ** + strP |-> cppStringR 1$m strM' (* TODO: this is not precise enough *) + ). + (* Print istream_take_spec . + Print _inststd_dot__opgreatergreater_with_and_cons_ref_named_inststd_dot_basic__istream_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_nil_cons_ref_named_inststd_dot_____cxx11_dot_basic__string_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_nil_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_spec. *) +(* The following dependencies are missing specifications: +"std::endl>(std::basic_ostream>&)"%cpp_name +"std::cin"%cpp_name +"std::cout"%cpp_name + +"std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name +"std::operator<<, std::allocator>(std::basic_ostream>&, const std::__cxx11::basic_string, std::allocator>&)"%cpp_name +"std::__cxx11::basic_string, std::allocator>::~basic_string()"%cpp_name +"std::basic_ostream>::operator<<(std::basic_ostream>&(*)(std::basic_ostream>&))"%cpp_name +"std::basic_istream>::operator>>(int&)"%cpp_name +"std::basic_ostream>::operator<<(int)"%cpp_name *) + + Lemma main_ok : istream_take_spec |-- verify?[source] main_spec. + Proof. + verify_spec; go. + Qed. + +End with_cpp. + From c66d8e7f4900ce5cf0f32ec814157ec982a10e2e Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 16:47:47 +0100 Subject: [PATCH 07/21] Completed simpler example --- .../geeks_for_geeks_examples/N2_input.cpp | 32 ++++----- .../test/geeks_for_geeks_examples/N2_input.v | 72 +++++++++++++++---- 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp index 1da1f13..222f99c 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp @@ -3,22 +3,22 @@ #include using namespace std; -// int main(){ -// int i; -// // Take input using cin -// cin >> i; -// // Print output -// cout << i; -// return 0; -// } - -int main() { - string name; - int age; - // Take multiple input using cin - cin >> name >> age; +int main(){ + int i; + // Take input using cin + cin >> i; // Print output - cout << "Name : " << name << endl; - cout << "Age : " << age << endl; + cout << i; return 0; } + +// int main() { +// string name; +// int age; +// // Take multiple input using cin +// cin >> name >> age; +// // Print output +// cout << "Name : " << name << endl; +// cout << "Age : " << age << endl; +// return 0; +// } diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v index b3de793..b9572ad 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v @@ -3,31 +3,29 @@ Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.spec. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N2_input_cpp. +Import linearity. + Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. Parameter istreamT : Type. Parameter istreamR : cQp.t -> istreamT -> Rep. - (* Parameter istream_contentR : cQp.t -> cstring.t -> Rep. *) + #[global] Instance: LearnEqF1 istreamR := ltac:(solve_learnable). - cpp.spec "main()" from N2_input_cpp.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 ++ "Hello World")). + (* Parameter istream_contentR : cQp.t -> cstring.t -> Rep. *) (* cpp.spec "puts" from source as puts_spec with ( \arg{p} "" (Vptr p) \prepost{q s} p |-> cstring.R q s \post{n}[Vint n] emp). *) - +(* Parameter cppStringR : cQp.t -> cstring.t -> Rep. cpp.spec "std::__cxx11::basic_string, std::allocator>::basic_string()" from source as string_ctor_spec with ( \this this \post this |-> cppStringR 1$m ""). - #[global] Declare Instance cppStringR_typed : Typed2 "std::__cxx11::basic_string, std::allocator>" cppStringR. - + #[global] Declare Instance cppStringR_typed : Typed2 "std::__cxx11::basic_string, std::allocator>" cppStringR. *) +(* #[ignore_missing] cpp.spec "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" @@ -42,8 +40,56 @@ Section with_cpp. isP |-> istreamR 1$m isM' ** strP |-> cppStringR 1$m strM' (* TODO: this is not precise enough *) ). - (* Print istream_take_spec . - Print _inststd_dot__opgreatergreater_with_and_cons_ref_named_inststd_dot_basic__istream_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_nil_cons_ref_named_inststd_dot_____cxx11_dot_basic__string_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_nil_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_spec. *) + Print istream_take_char_spec . *) + + cpp.spec "std::basic_istream>::operator>>(int&)" from source as istream_take_int_spec with ( + \this this + \pre{isM} this |-> istreamR 1$m isM + \arg{nP} "" (Vptr nP) + \pre nP |-> anyR "int" 1$m + \post[Vptr this] + Exists isM' n, + this |-> istreamR 1$m isM' ** + nP |-> intR 1$m n (* TODO: this is not precise enough *) + ). + + Parameter Z_to_string : Z -> cstring.t. + (** TODO: find an implementation!*) + + cpp.spec "std::basic_ostream>::operator<<(int)" from source as ostream_print_int_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) + ). + + cpp.spec "main()" from N2_input_cpp.source as main_spec with ( + \pre{isM} _global "std::cin" |-> istreamR 1$m isM + \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM + \pre{str} _global "std::cout" |-> ostream_contentR 1$m str + \post[Vint 0] + (* TODO: this is not precise enough *) + Exists n isM', + _global "std::cin" |-> istreamR 1$m isM' ** + _global "std::cout" |-> ostream_contentR 1$m (str ++ Z_to_string n) + ). + + Lemma main_ok : verify?[source] main_spec. + Proof. + + verify_spec; go. + ework with br_erefl. + Qed. + +(* The following dependencies are missing specifications: +"std::cin"%cpp_name +"std::cout"%cpp_name +"std::basic_istream>::operator>>(int&)"%cpp_name +"std::basic_ostream>::operator<<(int)"%cpp_name *) + + (* Print _inststd_dot__opgreatergreater_with_and_cons_ref_named_inststd_dot_basic__istream_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_nil_cons_ref_named_inststd_dot_____cxx11_dot_basic__string_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_nil_with_cons_char_cons_named_inststd_dot_char__traits_with_cons_char_nil_cons_named_inststd_dot_allocator_with_cons_char_nil_nil_spec. *) (* The following dependencies are missing specifications: "std::endl>(std::basic_ostream>&)"%cpp_name "std::cin"%cpp_name @@ -56,10 +102,6 @@ Section with_cpp. "std::basic_istream>::operator>>(int&)"%cpp_name "std::basic_ostream>::operator<<(int)"%cpp_name *) - Lemma main_ok : istream_take_spec |-- verify?[source] main_spec. - Proof. - verify_spec; go. - Qed. End with_cpp. From 5e573b132c53a07c34f87ff2d7ef70e559505ecb Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 17:01:05 +0100 Subject: [PATCH 08/21] WIP towards full example --- .../geeks_for_geeks_examples/N2_input.cpp | 24 +++++++++++++++---- .../test/geeks_for_geeks_examples/N2_input.v | 14 +++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp index 222f99c..344291d 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp @@ -3,15 +3,29 @@ #include using namespace std; -int main(){ - int i; - // Take input using cin - cin >> i; +// int main(){ +// int i; +// // Take input using cin +// cin >> i; +// // Print output +// cout << i; +// return 0; +// } + +int main() { + int age; + cin >> age; + string name; + // Take multiple input using cin + cin >> name; + // cin >> name >> age; // Print output - cout << i; + cout << "Name : " << name << endl; + cout << "Age : " << age << endl; return 0; } + // int main() { // string name; // int age; diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v index b9572ad..9df5e31 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v @@ -18,13 +18,6 @@ Section with_cpp. \arg{p} "" (Vptr p) \prepost{q s} p |-> cstring.R q s \post{n}[Vint n] emp). *) -(* - Parameter cppStringR : cQp.t -> cstring.t -> Rep. - cpp.spec "std::__cxx11::basic_string, std::allocator>::basic_string()" from source as string_ctor_spec with ( - \this this - \post this |-> cppStringR 1$m ""). - - #[global] Declare Instance cppStringR_typed : Typed2 "std::__cxx11::basic_string, std::allocator>" cppStringR. *) (* #[ignore_missing] cpp.spec @@ -76,6 +69,13 @@ Section with_cpp. _global "std::cout" |-> ostream_contentR 1$m (str ++ Z_to_string n) ). + Parameter cppStringR : cQp.t -> cstring.t -> Rep. + cpp.spec "std::__cxx11::basic_string, std::allocator>::basic_string()" from source as string_ctor_spec with ( + \this this + \post this |-> cppStringR 1$m ""). + + #[global] Declare Instance cppStringR_typed : Typed2 "std::__cxx11::basic_string, std::allocator>" cppStringR. + Lemma main_ok : verify?[source] main_spec. Proof. From 9231a51a1e591aa681ac7365a0656a4108a2226f Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 10 Feb 2026 17:53:28 +0100 Subject: [PATCH 09/21] more examples --- .../geeks_for_geeks_examples/N2_input.cpp | 2 +- .../test/geeks_for_geeks_examples/N2_input.v | 47 ++++++++++++------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp index 344291d..6e03f51 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.cpp @@ -3,7 +3,7 @@ #include using namespace std; -// int main(){ +// int main() { // int i; // // Take input using cin // cin >> i; diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v index 9df5e31..e4bf587 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v @@ -18,22 +18,8 @@ Section with_cpp. \arg{p} "" (Vptr p) \prepost{q s} p |-> cstring.R q s \post{n}[Vint n] emp). *) -(* - #[ignore_missing] - cpp.spec - "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" - from source as istream_take_char_spec with ( - (* cpp.spec "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" from source with ( *) - \arg{isP} "" (Vptr isP) - \pre{isM} isP |-> istreamR 1$m isM - \arg{strP} "" (Vptr strP) - \pre{strM} strP |-> cppStringR 1$m strM - \post[Vptr isP] - Exists isM' strM', - isP |-> istreamR 1$m isM' ** - strP |-> cppStringR 1$m strM' (* TODO: this is not precise enough *) - ). - Print istream_take_char_spec . *) + + Parameter cppStringR : cQp.t -> cstring.t -> Rep. cpp.spec "std::basic_istream>::operator>>(int&)" from source as istream_take_int_spec with ( \this this @@ -69,7 +55,6 @@ Section with_cpp. _global "std::cout" |-> ostream_contentR 1$m (str ++ Z_to_string n) ). - Parameter cppStringR : cQp.t -> cstring.t -> Rep. cpp.spec "std::__cxx11::basic_string, std::allocator>::basic_string()" from source as string_ctor_spec with ( \this this \post this |-> cppStringR 1$m ""). @@ -80,8 +65,34 @@ Section with_cpp. Proof. verify_spec; go. - ework with br_erefl. + (* progress ework with br_erefl. *) + set name := "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name. + exfalso. + clear. +Set Printing All. +Check "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name. +Eval cbv in ("std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name). +(* Print "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name. *) + Qed. +(* Print "std::operator() , std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)"%cpp_name. *) + + (* #[ignore_missing] *) + cpp.spec + "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" + from N2_input_cpp.source as istream_take_char_spec with ( + (* cpp.spec "std::operator>>, std::allocator>(std::basic_istream>&, std::__cxx11::basic_string, std::allocator>&)" from source with ( *) + \arg{isP} "" (Vptr isP) + \pre{isM} isP |-> istreamR 1$m isM + \arg{strP} "" (Vptr strP) + \pre{strM} strP |-> cppStringR 1$m strM + \post[Vptr isP] + Exists isM' strM', + isP |-> istreamR 1$m isM' ** + strP |-> cppStringR 1$m strM' (* TODO: this is not precise enough *) + ). + Print istream_take_char_spec . + (* The following dependencies are missing specifications: "std::cin"%cpp_name From 970a14fb8d93da4d360b81a2f0932639caf87931 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 17:09:26 +0100 Subject: [PATCH 10/21] Upstreaming some specs a bit --- .../test/geeks_for_geeks_examples/N2_input.v | 17 +----------- .../test/geeks_for_geeks_examples/spec.v | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v index e4bf587..a22b7cb 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N2_input.v @@ -8,10 +8,6 @@ Import linearity. Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. - Parameter istreamT : Type. - Parameter istreamR : cQp.t -> istreamT -> Rep. - #[global] Instance: LearnEqF1 istreamR := ltac:(solve_learnable). - (* Parameter istream_contentR : cQp.t -> cstring.t -> Rep. *) (* cpp.spec "puts" from source as puts_spec with ( @@ -19,6 +15,7 @@ Section with_cpp. \prepost{q s} p |-> cstring.R q s \post{n}[Vint n] emp). *) + (** TODO: the model is bigger than cstring.t: just a list of "characters". *) Parameter cppStringR : cQp.t -> cstring.t -> Rep. cpp.spec "std::basic_istream>::operator>>(int&)" from source as istream_take_int_spec with ( @@ -32,18 +29,6 @@ Section with_cpp. nP |-> intR 1$m n (* TODO: this is not precise enough *) ). - Parameter Z_to_string : Z -> cstring.t. - (** TODO: find an implementation!*) - - cpp.spec "std::basic_ostream>::operator<<(int)" from source as ostream_print_int_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) - ). - cpp.spec "main()" from N2_input_cpp.source as main_spec with ( \pre{isM} _global "std::cin" |-> istreamR 1$m isM \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM 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 9321767..bcc48b1 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -10,6 +10,16 @@ Require Export skylabs.cpp.string. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.iostream_cpp. +(** TODO upstream to bytestring *) +#[global] Instance BS_append_inj_r x : Inj eq eq (BS.append x). +Proof. + elim: x => [|x xs /= IH] [|y1 ys1] [|y2 ys2] //= [/(inj (BS.append _))] //. +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. + Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. @@ -20,6 +30,10 @@ Section with_cpp. #[global] Instance: LearnEqF1 ostreamR := ltac:(solve_learnable). #[global] Instance: LearnEqF1 ostream_contentR := ltac:(solve_learnable). + Parameter istreamT : Type. + Parameter istreamR : cQp.t -> istreamT -> Rep. + #[global] Instance: LearnEqF1 istreamR := ltac:(solve_learnable). + 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 @@ -29,4 +43,17 @@ Section with_cpp. \post[Vptr osP] osP |-> ostream_contentR 1$m (str ++ strM)). + Parameter Z_to_string : Z -> cstring.t. + #[global] Declare Instance Z_to_string_inj : Inj eq eq Z_to_string. + (** TODO: find an implementation!*) + + cpp.spec "std::basic_ostream>::operator<<(int)" from source as ostream_print_int_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) + ). + End with_cpp. From 3472ceb00a9a6e7725320b88c7ce89e9f66d389f Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 11 Feb 2026 17:09:54 +0100 Subject: [PATCH 11/21] More examples, with a loop invariant Example 5 iostream spec: Let stream manipulators modify stream state Upstream specs More examples Rephrase proofs for aggressive hint Improve spec --- rocq-brick-libstdcpp/test/dune.inc | 45 +++++++++++++++ .../geeks_for_geeks_examples/N12_area.cpp | 30 ++++++++++ .../test/geeks_for_geeks_examples/N12_area.v | 37 ++++++++++++ .../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 ++++++++++++ .../test/geeks_for_geeks_examples/N5_swap.cpp | 17 ++++++ .../test/geeks_for_geeks_examples/N5_swap.v | 44 ++++++++++++++ .../N6_print_sizeof.cpp | 31 ++++++++++ .../N6_print_sizeof.v | 35 ++++++++++++ .../test/geeks_for_geeks_examples/spec.v | 57 +++++++++++++++++++ 12 files changed, 382 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/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 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 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 a5b255d..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) @@ -35,6 +44,42 @@ (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 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 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..0570fac --- /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. + work. + by rewrite -!(assoc_L BS.append). + Qed. +End with_cpp. 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. 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..3e02a3a --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap.v @@ -0,0 +1,44 @@ +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" + ) + ). + + #[program] + 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. + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_shift; 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. + work. + by rewrite -!(assoc_L BS.append). + 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..e476f45 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N6_print_sizeof.v @@ -0,0 +1,35 @@ +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}. + + 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] + _global "std::cout" |-> ostream_contentR 1$m + (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. + Proof. + verify_shift; go. + + banish_string_literals. + iModIntro. + 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 bcc48b1..c7e640e 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -16,10 +16,17 @@ 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. +#[global] Arguments BS.append : simpl never. + Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. @@ -56,4 +63,54 @@ 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) + ). + + 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 5d26e23a8ccea67a8f776c4a5f06b28cf9015a21 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 12 Feb 2026 17:13:08 +0100 Subject: [PATCH 12/21] 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 4fe5cd716758aba601a8de0573705ad7614a838e Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 12 Feb 2026 17:15:33 +0100 Subject: [PATCH 13/21] 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 70cd703538c57612d1cc3f82d54dc7ad4fe17233 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 13 Feb 2026 14:04:52 +0100 Subject: [PATCH 14/21] WIP readd stderr files --- rocq-brick-libstdcpp/proof/dune.inc | 36 ++++++++--------- rocq-brick-libstdcpp/test/dune.inc | 61 +++++++++++++++++------------ 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/rocq-brick-libstdcpp/proof/dune.inc b/rocq-brick-libstdcpp/proof/dune.inc index 4482e93..6d6db53 100644 --- a/rocq-brick-libstdcpp/proof/dune.inc +++ b/rocq-brick-libstdcpp/proof/dune.inc @@ -1,82 +1,82 @@ ; DO NOT EDIT: Generated by "./dune-gen.sh" (subdir cassert (rule - (targets inc_cassert_cpp.v) + (targets inc_cassert_cpp.v.stderr inc_cassert_cpp.v) (alias test_ast) (deps (:input inc_cassert.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_cassert_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_cassert_cpp.v.stderr (run cpp2v -v %{input} -o inc_cassert_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc_cassert.cpp)) ) (subdir cctype (rule - (targets inc_cctype_cpp.v) + (targets inc_cctype_cpp.v.stderr inc_cctype_cpp.v) (alias test_ast) (deps (:input inc_cctype.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_cctype_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_cctype_cpp.v.stderr (run cpp2v -v %{input} -o inc_cctype_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc_cctype.cpp)) ) (subdir cstdlib (rule - (targets inc_cstdlib_cpp.v) + (targets inc_cstdlib_cpp.v.stderr inc_cstdlib_cpp.v) (alias test_ast) (deps (:input inc_cstdlib.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_cstdlib_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_cstdlib_cpp.v.stderr (run cpp2v -v %{input} -o inc_cstdlib_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc_cstdlib.cpp)) ) (subdir mutex (rule - (targets demo_cpp.v) + (targets demo_cpp.v.stderr demo_cpp.v) (alias test_ast) (deps (:input demo.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to demo_cpp.v.stderr (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps demo.cpp)) ) (subdir mutex (rule - (targets inc_hpp.v) + (targets inc_hpp.v.stderr inc_hpp.v) (alias test_ast) (deps (:input inc.hpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_hpp.v.stderr (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc.hpp)) ) (subdir mutex (rule - (targets test_cpp.v) + (targets test_cpp.v.stderr test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps test.cpp)) ) (subdir new (rule - (targets inc_new_cpp.v) + (targets inc_new_cpp.v.stderr inc_new_cpp.v) (alias test_ast) (deps (:input inc_new.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_new_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_new_cpp.v.stderr (run cpp2v -v %{input} -o inc_new_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc_new.cpp)) ) (subdir semaphore (rule - (targets inc_hpp.v) + (targets inc_hpp.v.stderr inc_hpp.v) (alias test_ast) (deps (:input inc.hpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to inc_hpp.v.stderr (run cpp2v -v %{input} -o inc_hpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps inc.hpp)) ) (subdir semaphore (rule - (targets test_cpp.v) + (targets test_cpp.v.stderr test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps test.cpp)) ) diff --git a/rocq-brick-libstdcpp/test/dune.inc b/rocq-brick-libstdcpp/test/dune.inc index b4ecf39..88dc99a 100644 --- a/rocq-brick-libstdcpp/test/dune.inc +++ b/rocq-brick-libstdcpp/test/dune.inc @@ -1,118 +1,127 @@ ; DO NOT EDIT: Generated by "./dune-gen.sh" (subdir cctype (rule - (targets test_cpp.v) + (targets test_cpp.v.stderr test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps test.cpp)) ) (subdir cstdlib (rule - (targets test_cpp.v) + (targets test_cpp.v.stderr test_cpp.v) (alias test_ast) (deps (:input test.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to test_cpp.v.stderr (run cpp2v -v %{input} -o test_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps test.cpp)) ) (subdir geeks_for_geeks_examples (rule - (targets N12_area_cpp.v) + (targets N12_area_cpp.v.stderr 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++ ))) + (with-stderr-to N12_area_cpp.v.stderr (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 N1_hello_world_cpp.v) + (targets N1_hello_world_cpp.v.stderr N1_hello_world_cpp.v) (alias test_ast) (deps (:input N1_hello_world.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N1_hello_world_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to N1_hello_world_cpp.v.stderr (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 N3_input_cpp.v) + (targets N3_input_cpp.v.stderr N3_input_cpp.v) (alias test_ast) (deps (:input N3_input.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N3_input_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to N3_input_cpp.v.stderr (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 N4_sum_cpp.v) + (targets N4_sum_cpp.v.stderr N4_sum_cpp.v) (alias test_ast) (deps (:input N4_sum.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N4_sum_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to N4_sum_cpp.v.stderr (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 N4_sum_a_cpp.v) + (targets N4_sum_a_cpp.v.stderr N4_sum_a_cpp.v) (alias test_ast) (deps (:input N4_sum_a.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o N4_sum_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to N4_sum_a_cpp.v.stderr (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 - (targets N5_swap_cpp.v) + (targets N5_swap_cpp.v.stderr 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++ ))) + (with-stderr-to N5_swap_cpp.v.stderr (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) + (targets N5_swap_a_cpp.v.stderr N5_swap_a_cpp.v) + (alias test_ast) + (deps (:input N5_swap_a.cpp) (glob_files_rec ../*.hpp) (universe)) + (action + (with-stderr-to N5_swap_a_cpp.v.stderr (run cpp2v -v %{input} -o N5_swap_a_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) + (alias (name srcs) (deps N5_swap_a.cpp)) +) +(subdir geeks_for_geeks_examples + (rule + (targets N6_print_sizeof_cpp.v.stderr 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++ ))) + (with-stderr-to N6_print_sizeof_cpp.v.stderr (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) + (targets N8_ascii_value_cast_cpp.v.stderr 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++ ))) + (with-stderr-to N8_ascii_value_cast_cpp.v.stderr (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) + (targets N8_ascii_value_printf_cpp.v.stderr 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++ ))) + (with-stderr-to N8_ascii_value_printf_cpp.v.stderr (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) + (targets iostream_cpp.v.stderr iostream_cpp.v) (alias test_ast) (deps (:input iostream.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o iostream_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to iostream_cpp.v.stderr (run cpp2v -v %{input} -o iostream_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps iostream.cpp)) ) (subdir new (rule - (targets demo_cpp.v) + (targets demo_cpp.v.stderr demo_cpp.v) (alias test_ast) (deps (:input demo.cpp) (glob_files_rec ../*.hpp) (universe)) (action - (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ ))) + (with-stderr-to demo_cpp.v.stderr (run cpp2v -v %{input} -o demo_cpp.v --no-elaborate -- -std=c++20 -stdlib=libstdc++ )))) (alias (name srcs) (deps demo.cpp)) ) From aec0888ffbbf91324fb4b37c5bed6215eabe9084 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 13 Feb 2026 14:05:40 +0100 Subject: [PATCH 15/21] More name fixes --- .../test/geeks_for_geeks_examples/N1_hello_world.v | 2 +- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v index 2dabb26..9e773f6 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N1_hello_world.v @@ -6,7 +6,7 @@ Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.N1_hello_wo Section with_cpp. Context `{Σ : cpp_logic, σ : genv}. - cpp.spec "main()" from N0_hello_world_cpp.source as main_spec with ( + 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] diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v index d911790..79a4dce 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N3_input.v @@ -29,7 +29,7 @@ Section with_cpp. nP |-> intR 1$m n (* TODO: this is not precise enough *) ). - cpp.spec "main()" from N2_input_cpp.source as main_spec with ( + cpp.spec "main()" from source as main_spec with ( \pre{isM} _global "std::cin" |-> istreamR 1$m isM \prepost{osM} _global "std::cout" |-> ostreamR 1$m osM \pre{str} _global "std::cout" |-> ostream_contentR 1$m str From 663d1bae89ff1c046bbe886789ab29d8769eb96b Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 13 Feb 2026 14:07:44 +0100 Subject: [PATCH 16/21] Add variant of example --- .../geeks_for_geeks_examples/N5_swap_a.cpp | 15 ++++++++ .../test/geeks_for_geeks_examples/N5_swap_a.v | 35 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.cpp create mode 100644 rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.v diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.cpp b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.cpp new file mode 100644 index 0000000..0866ce7 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.cpp @@ -0,0 +1,15 @@ +#include +using namespace std; + +int main(){ + int a = 2, b = 3; + + cout << "Before swapping a = " << a << " , b = " << b << endl; + + b = a + b; + a = b - a; + b = b - a; + + cout << "After swapping a = " << a << " , b = " << b << endl; + return 0; +} diff --git a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.v b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.v new file mode 100644 index 0000000..e7098f3 --- /dev/null +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/N5_swap_a.v @@ -0,0 +1,35 @@ +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_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 ++ + "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" + ) + ). + + Lemma main_ok : verify?[source] main_spec. + Proof. + verify_shift; 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. + work. + by rewrite -!(assoc_L BS.append). + Qed. +End with_cpp. + From 9ebdaf5d7dcc71cfbc3b9d94a81c299a2004fc76 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 13 Feb 2026 14:09:21 +0100 Subject: [PATCH 17/21] Drop non-working hint --- .../test/geeks_for_geeks_examples/N5_swap.v | 10 ---------- 1 file changed, 10 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 3e02a3a..2cc46fa 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,16 +20,6 @@ Section with_cpp. ) ). - #[program] - 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. - Lemma main_ok : verify?[source] main_spec. Proof. verify_shift; go. From 6d3ec5e2f2a13e795c5ad66d4d2a5eed102718dd Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 17 Feb 2026 15:48:01 +0100 Subject: [PATCH 18/21] Annotate spec stability --- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v | 7 +++++++ 1 file changed, 7 insertions(+) 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..021a40d 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -1,3 +1,10 @@ +(** +Tentative iostreams specs. + +These are trace-based specifications, and there is a _wish_ to move to a +different style of specifications. + +*) Require Import skylabs.auto.cpp.prelude.proof. Require Export skylabs.cpp.string. From 5e54c3883a3e10d95539d1677f8741ed07ecdc53 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 17 Feb 2026 15:48:51 +0100 Subject: [PATCH 19/21] TODO fix buggy spec --- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v | 1 + 1 file changed, 1 insertion(+) 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 021a40d..c935096 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -97,6 +97,7 @@ Section with_cpp. ). (* This is the overload taking the endl manipulator. *) + (* https://eel.is/c++draft/output.streams#ostream.inserters *) 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) From 0ad249415656de6809ad76f8b985f781860864ed Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 17 Feb 2026 15:49:26 +0100 Subject: [PATCH 20/21] Tweak upstreamed code --- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v | 5 +++-- 1 file changed, 3 insertions(+), 2 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 c935096..b919038 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -18,14 +18,15 @@ Require Export skylabs.cpp.string. Require Import skylabs.brick.libstdcpp.test.geeks_for_geeks_examples.iostream_cpp. (** TODO upstream to bytestring *) +#[global] Arguments BS.append !_ !_ /. #[global] Instance BS_append_inj_r x : Inj eq eq (BS.append x). Proof. - elim: x => [|x xs /= IH] [|y1 ys1] [|y2 ys2] //= [/(inj (BS.append _))] //. + 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. + elim => [|x xs IH] [|y ys] [|z zs] //=; by rewrite -IH. Qed. #[global] Instance refine_bs_app' (str a b : BS.t) : From a6e495d5d733112d906ec48bc3b015f7fb63f876 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 17 Feb 2026 15:49:33 +0100 Subject: [PATCH 21/21] Tweak code to upstream --- rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v | 5 ++--- 1 file changed, 2 insertions(+), 3 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 b919038..453ed76 100644 --- a/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v +++ b/rocq-brick-libstdcpp/test/geeks_for_geeks_examples/spec.v @@ -29,11 +29,10 @@ Proof. elim => [|x xs IH] [|y ys] [|z zs] //=; by rewrite -IH. Qed. +(** TODO upstream to auto *) #[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. - -#[global] Arguments BS.append : simpl never. +Proof. tac_refine. exact: inj (BS.append str). Qed. Section with_cpp. Context `{Σ : cpp_logic, σ : genv}.