From 799b72d0a554146c5d1c30ec7b59f28ea2caacd0 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 11:35:42 -0600 Subject: [PATCH 01/25] setup perennial for nix development --- .envrc | 1 + .gitignore | 3 +++ flake.nix | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 .envrc create mode 100644 flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..3550a30f2 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index a7afdeb4e..ba2e539b7 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ __pycache__ # Compiled code supplement /peony-code.zip + +# direnv +.direnv diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..ad2e6ae45 --- /dev/null +++ b/flake.nix @@ -0,0 +1,41 @@ +{ + description = "A Flake for Applying Grackle to gokv"; + + inputs = { + nixpkgs.url = "nixpkgs"; + }; + + outputs = {nixpkgs, ...}: let + system = "x86_64-linux"; + in { + devShells."${system}".default = let + pkgs = import nixpkgs { + inherit system; + }; + grackle = pkgs.buildGoModule { + name = "grackle"; + src = pkgs.fetchFromGitHub { + owner = "mjschwenne"; + repo = "grackle"; + rev = "18dbbd313c299d74895f566aae028eeba62a699a"; + hash = "sha256-GDo3c3VbRl0FR7sJ2Cvmdau+rBRcxwb/sGAEwV5seFQ="; + }; + vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; + checkPhase = false; + }; + in + pkgs.mkShell { + # create an environment with the required coq libraries + packages = with pkgs; [ + # coq deps + coqc + + # grackle + grackle + ]; + + shellHook = '' + ''; + }; + }; +} From d0f74e16bb3bf47b428113df8379c450f96e8ad9 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 11:37:04 -0600 Subject: [PATCH 02/25] fix nix setup --- flake.lock | 24 ++++++++++++++++++++++++ flake.nix | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 flake.lock diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..7973da7c0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,24 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", + "path": "/nix/store/zq2axpgzd5kykk1v446rkffj3bxa2m2h-source", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index ad2e6ae45..0d5431900 100644 --- a/flake.nix +++ b/flake.nix @@ -28,7 +28,7 @@ # create an environment with the required coq libraries packages = with pkgs; [ # coq deps - coqc + coq # grackle grackle From 278c1ed88078f02dc798ae1a42da62a4128e56d4 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 11:57:00 -0600 Subject: [PATCH 03/25] Start working on update-grackle.sh --- etc/update-grackle.sh | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 etc/update-grackle.sh diff --git a/etc/update-grackle.sh b/etc/update-grackle.sh new file mode 100755 index 000000000..181421511 --- /dev/null +++ b/etc/update-grackle.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +compile_grackle() { + CWD=$(pwd) + cd "$1" || return + go install ./cmd/grackle + cd "$CWD" || exit +} + +# Computes the coq logical name by +# +# - Replacing "." with "-" +# - Replacing "-" with "_" +# - Replacing "/" with "." +# +# This mirrors grackle/internal/util/util.go :: CleanCoqName function +coq_logical_name() { + echo "$1" | sed -E -e "s/\./-/g" -e "s/-/_/g" -e "s/\//\./g" +} + +# Run grackle on the input go package. +# +# We will assume that: +# 1. The proto file is in the directory $1/$2 +# 2. We only want to output coq code +# 3. The coq code should be output into $2 +# 4. The desired coq package matches the directory structure +# 5. Grackle is on your $PATH +# +# Parameters +# - $1 : path to go repo with proto files +# - $2 : go package in that repo we're grackling +# - $3 : path to output in perennial +run_grackle() { + echo grackle --coq-logical-path "Perennial.program_proof.$(coq_logical_name $3)" --coq-physical-path "src/program_proof/$3" "$1/$2" +} + +ARGS=$(getopt -o "c:g:h" --long "compile-grackle:,gokv:,help" -- "$@") + +eval set -- "$ARGS" +while [ $# -ge 1 ]; do + case "$1" in + -c | --compile-grackle) + compile_grackle "$2" + shift + ;; + -g | --gokv) + grackle_gokv "$2" + shift + ;; + -h | --help) + cat < | -c ] [--help | -h] + +Calls grackle on all gokv go modules known to have proto files for grackle usage, generating coq proofs. + +--compile-grackle [-g] : Takes the path to the grackle repository, recompiles and installs grackle +EOF + shift + exit 0 + ;; + --) + shift + break + ;; + esac + shift +done + +# Generate Coq files from gokv repo. +# +# Parameters +# - $1 : Path to the gokv repo. +grackle_gokv() { + gokv_packages=( + "tutorial/kvservice" + "tutorial/lockservice" + "tutorial/objectstore/chunk" + "tutorial/objectstore/dir" + ) + + for gopkg in "${gokv_packages[@]}"; do + run_grackle "$1" "$gopkg" "program_proof/$gokv" + done +} From ed01ac1e6e502d87a4b18007bee079431600176c Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 13:53:26 -0600 Subject: [PATCH 04/25] Finished (but untested) update-grackle.sh --- etc/update-grackle.sh | 53 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/etc/update-grackle.sh b/etc/update-grackle.sh index 181421511..360a8641d 100755 --- a/etc/update-grackle.sh +++ b/etc/update-grackle.sh @@ -21,18 +21,35 @@ coq_logical_name() { # Run grackle on the input go package. # # We will assume that: -# 1. The proto file is in the directory $1/$2 +# 1. The proto file is in the directory $2/$1 # 2. We only want to output coq code -# 3. The coq code should be output into $2 +# 3. The coq code should be output into "src/program_proof/$1" # 4. The desired coq package matches the directory structure # 5. Grackle is on your $PATH # # Parameters -# - $1 : path to go repo with proto files -# - $2 : go package in that repo we're grackling -# - $3 : path to output in perennial +# - $1 : Name of the go package inside its repo +# - $2 : Path to the root of the go repo. Go package to translate should be at "$2/$1" +# - $3 : Prefix to compute the go package name, "$3/$1" run_grackle() { - echo grackle --coq-logical-path "Perennial.program_proof.$(coq_logical_name $3)" --coq-physical-path "src/program_proof/$3" "$1/$2" + grackle --coq-logical-path "Perennial.program_proof.$(coq_logical_name $1)" --coq-physical-path "src/program_proof/$1" --go-package "$3/$1" $(realpath "$2/$1") +} + +# Generate Coq files from gokv repo. +# +# Parameters +# - $1 : Path to the gokv repo. +grackle_gokv() { + gokv_packages=( + "tutorial/kvservice" + "tutorial/lockservice" + "tutorial/objectstore/chunk" + "tutorial/objectstore/dir" + ) + + for gopkg in "${gokv_packages[@]}"; do + run_grackle "$gopkg" "$1" "github.com/mit-pdos/gokv" + done } ARGS=$(getopt -o "c:g:h" --long "compile-grackle:,gokv:,help" -- "$@") @@ -50,11 +67,14 @@ while [ $# -ge 1 ]; do ;; -h | --help) cat < | -c ] [--help | -h] +usage: update-grackle.sh [--compile-grackle | -c ] + [--gokv | -g] [--help | -h] Calls grackle on all gokv go modules known to have proto files for grackle usage, generating coq proofs. ---compile-grackle [-g] : Takes the path to the grackle repository, recompiles and installs grackle +--compile-grackle [-c] : Takes the path to the grackle repository, recompiles and installs grackle + +--gokv [-g] : Regenerate Coq proofs for the gokv project EOF shift exit 0 @@ -66,20 +86,3 @@ EOF esac shift done - -# Generate Coq files from gokv repo. -# -# Parameters -# - $1 : Path to the gokv repo. -grackle_gokv() { - gokv_packages=( - "tutorial/kvservice" - "tutorial/lockservice" - "tutorial/objectstore/chunk" - "tutorial/objectstore/dir" - ) - - for gopkg in "${gokv_packages[@]}"; do - run_grackle "$1" "$gopkg" "program_proof/$gokv" - done -} From 3dc6da746e8acdf8ce2e8a968adc9af864e8aa7d Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 13:53:47 -0600 Subject: [PATCH 05/25] Update flake to include protoc --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 0d5431900..0c945f315 100644 --- a/flake.nix +++ b/flake.nix @@ -32,6 +32,7 @@ # grackle grackle + protobuf ]; shellHook = '' From fbebaab02fabb0af2867a583d0fdb039c907dc85 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 19:23:59 -0600 Subject: [PATCH 06/25] Begin grackle integration --- etc/update-goose.py | 10 +- .../mit_pdos/gokv/tutorial/kvservice.v | 176 +++++++++--------- .../tutorial/kvservice/conditionalput_gk.v | 70 +++++++ .../mit_pdos/gokv/tutorial/kvservice/get_gk.v | 44 +++++ .../mit_pdos/gokv/tutorial/kvservice/put_gk.v | 57 ++++++ .../mit_pdos/gokv/tutorial/lockservice.v | 9 +- .../tutorial/lockservice/lockrequest_gk.v | 31 +++ .../gokv/tutorial/objectstore/chunk.v | 18 +- .../objectstore/chunk/writechunk_gk.v | 48 +++++ .../gokv/tutorial/objectstore/client.v | 6 +- .../mit_pdos/gokv/tutorial/objectstore/dir.v | 24 +-- .../tutorial/objectstore/dir/chunkhandle_gk.v | 44 +++++ .../tutorial/objectstore/dir/finishwrite_gk.v | 44 +++++ .../tutorial/objectstore/dir/recordchunk_gk.v | 54 ++++++ flake.nix | 30 ++- .../tutorial/kvservice/conditionalput_proof.v | 157 ++++++++++++++++ .../tutorial/kvservice/get_proof.v | 106 +++++++++++ src/program_proof/tutorial/kvservice/proof.v | 7 + .../tutorial/kvservice/put_proof.v | 131 +++++++++++++ .../tutorial/lockservice/lockrequest_proof.v | 79 ++++++++ .../objectstore/chunk/writechunk_proof.v | 115 ++++++++++++ .../objectstore/dir/chunkhandle_proof.v | 105 +++++++++++ .../objectstore/dir/finishwrite_proof.v | 105 +++++++++++ .../objectstore/dir/recordchunk_proof.v | 121 ++++++++++++ 24 files changed, 1469 insertions(+), 122 deletions(-) create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v create mode 100644 external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v create mode 100644 src/program_proof/tutorial/kvservice/conditionalput_proof.v create mode 100644 src/program_proof/tutorial/kvservice/get_proof.v create mode 100644 src/program_proof/tutorial/kvservice/put_proof.v create mode 100644 src/program_proof/tutorial/lockservice/lockrequest_proof.v create mode 100644 src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v create mode 100644 src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v create mode 100644 src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v create mode 100644 src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v diff --git a/etc/update-goose.py b/etc/update-goose.py index 9b596c0eb..a11e01ce8 100755 --- a/etc/update-goose.py +++ b/etc/update-goose.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import os -from os import path import subprocess +from os import path def run_command(args, dry_run=False, verbose=False): @@ -281,10 +281,18 @@ def run_goose(src_path, *pkgs): "./vrsm/apps/closed", "./tutorial", # atomic commit "./tutorial/objectstore/dir", + "./tutorial/objectstore/dir/chunkhandle_gk", + "./tutorial/objectstore/dir/finishwrite_gk", + "./tutorial/objectstore/dir/recordchunk_gk", "./tutorial/objectstore/chunk", + "./tutorial/objectstore/chunk/writechunk_gk", "./tutorial/objectstore/client", "./tutorial/lockservice", + "./tutorial/lockservice/lockrequest_gk", "./tutorial/kvservice", + "./tutorial/kvservice/conditionalput_gk", + "./tutorial/kvservice/get_gk", + "./tutorial/kvservice/put_gk", "./tutorial/basics", "./tutorial/queue", "./map_marshal", diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v index 6a87b6172..94d83df6d 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v @@ -1,6 +1,9 @@ (* autogenerated from github.com/mit-pdos/gokv/tutorial/kvservice *) From Perennial.goose_lang Require Import prelude. From Goose Require github_com.goose_lang.std. +From Goose Require github_com.mit_pdos.gokv.tutorial.kvservice.conditionalput_gk. +From Goose Require github_com.mit_pdos.gokv.tutorial.kvservice.get_gk. +From Goose Require github_com.mit_pdos.gokv.tutorial.kvservice.put_gk. From Goose Require github_com.mit_pdos.gokv.urpc. From Goose Require github_com.tchajed.marshal. @@ -62,31 +65,10 @@ Definition Client__getFreshNumRpc: val := then (DecodeUint64 (![slice.T byteT] "reply"), "err") else (#0, "err")). -(* putArgs from kvservice.gb.go *) - -(* Put *) -Definition putArgs := struct.decl [ - "opId" :: uint64T; - "key" :: stringT; - "val" :: stringT -]. - -Definition encodePutArgs: val := - rec: "encodePutArgs" "a" := - let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF putArgs "opId" "a"));; - let: "keyBytes" := StringToBytes (struct.loadF putArgs "key" "a") in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "keyBytes"));; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "keyBytes");; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF putArgs "val" "a")));; - ![slice.T byteT] "e". - -(* Client__putRpc from kvservice_rpc.gb.go *) - Definition Client__putRpc: val := rec: "Client__putRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdPut (encodePutArgs "args") "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdPut (put_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in (if: "err" = urpc.ErrNone then "err" else "err"). @@ -105,45 +87,20 @@ Definition Clerk__Put: val := else Continue));; Skip;; (for: (λ: <>, #true); (λ: <>, Skip) := λ: <>, - let: "args" := struct.new putArgs [ - "opId" ::= ![uint64T] "opId"; - "key" ::= "key"; - "val" ::= "val" + let: "args" := struct.new put_gk.S [ + "OpId" ::= ![uint64T] "opId"; + "Key" ::= "key"; + "Val" ::= "val" ] in (if: (Client__putRpc (struct.loadF Clerk "rpcCl" "ck") "args") = urpc.ErrNone then Break else Continue));; #(). -(* conditionalPutArgs from kvservice.gb.go *) - -(* ConditionalPut *) -Definition conditionalPutArgs := struct.decl [ - "opId" :: uint64T; - "key" :: stringT; - "expectedVal" :: stringT; - "newVal" :: stringT -]. - -Definition encodeConditionalPutArgs: val := - rec: "encodeConditionalPutArgs" "a" := - let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF conditionalPutArgs "opId" "a"));; - let: "keyBytes" := StringToBytes (struct.loadF conditionalPutArgs "key" "a") in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "keyBytes"));; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "keyBytes");; - let: "expectedValBytes" := StringToBytes (struct.loadF conditionalPutArgs "expectedVal" "a") in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "expectedValBytes"));; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "expectedValBytes");; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF conditionalPutArgs "newVal" "a")));; - ![slice.T byteT] "e". - -(* Client__conditionalPutRpc from kvservice_rpc.gb.go *) - Definition Client__conditionalPutRpc: val := rec: "Client__conditionalPutRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdConditionalPut (encodeConditionalPutArgs "args") "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdConditionalPut (conditionalput_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in (if: "err" = urpc.ErrNone then (StringFromBytes (![slice.T byteT] "reply"), "err") else (#(str""), "err")). @@ -165,11 +122,11 @@ Definition Clerk__ConditionalPut: val := let: "ret" := ref (zero_val boolT) in Skip;; (for: (λ: <>, #true); (λ: <>, Skip) := λ: <>, - let: "args" := struct.new conditionalPutArgs [ - "opId" ::= ![uint64T] "opId"; - "key" ::= "key"; - "expectedVal" ::= "expectedVal"; - "newVal" ::= "newVal" + let: "args" := struct.new conditionalput_gk.S [ + "OpId" ::= ![uint64T] "opId"; + "Key" ::= "key"; + "ExpectedVal" ::= "expectedVal"; + "NewVal" ::= "newVal" ] in let: ("reply", "err") := Client__conditionalPutRpc (struct.loadF Clerk "rpcCl" "ck") "args" in (if: "err" = urpc.ErrNone @@ -179,27 +136,10 @@ Definition Clerk__ConditionalPut: val := else Continue));; ![boolT] "ret". -(* getArgs from kvservice.gb.go *) - -(* Get *) -Definition getArgs := struct.decl [ - "opId" :: uint64T; - "key" :: stringT -]. - -Definition encodeGetArgs: val := - rec: "encodeGetArgs" "a" := - let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in - "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF getArgs "opId" "a"));; - "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF getArgs "key" "a")));; - ![slice.T byteT] "e". - -(* Client__getRpc from kvservice_rpc.gb.go *) - Definition Client__getRpc: val := rec: "Client__getRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdGet (encodeGetArgs "args") "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdGet (get_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in (if: "err" = urpc.ErrNone then (StringFromBytes (![slice.T byteT] "reply"), "err") else (#(str""), "err")). @@ -221,9 +161,9 @@ Definition Clerk__Get: val := let: "ret" := ref (zero_val stringT) in Skip;; (for: (λ: <>, #true); (λ: <>, Skip) := λ: <>, - let: "args" := struct.new getArgs [ - "opId" ::= ![uint64T] "opId"; - "key" ::= "key" + let: "args" := struct.new get_gk.S [ + "OpId" ::= ![uint64T] "opId"; + "Key" ::= "key" ] in let: ("reply", "err") := Client__getRpc (struct.loadF Clerk "rpcCl" "ck") "args" in (if: "err" = urpc.ErrNone @@ -250,6 +190,23 @@ Definition EncodeUint64: val := rec: "EncodeUint64" "a" := marshal.WriteInt (NewSlice byteT #0) "a". +(* Put *) +Definition putArgs := struct.decl [ + "opId" :: uint64T; + "key" :: stringT; + "val" :: stringT +]. + +Definition encodePutArgs: val := + rec: "encodePutArgs" "a" := + let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF putArgs "opId" "a"));; + let: "keyBytes" := StringToBytes (struct.loadF putArgs "key" "a") in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "keyBytes"));; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "keyBytes");; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF putArgs "val" "a")));; + ![slice.T byteT] "e". + Definition decodePutArgs: val := rec: "decodePutArgs" "x" := let: "e" := ref_to (slice.T byteT) "x" in @@ -263,6 +220,27 @@ Definition decodePutArgs: val := struct.storeF putArgs "val" "a" (StringFromBytes "valBytes");; "a". +(* ConditionalPut *) +Definition conditionalPutArgs := struct.decl [ + "opId" :: uint64T; + "key" :: stringT; + "expectedVal" :: stringT; + "newVal" :: stringT +]. + +Definition encodeConditionalPutArgs: val := + rec: "encodeConditionalPutArgs" "a" := + let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF conditionalPutArgs "opId" "a"));; + let: "keyBytes" := StringToBytes (struct.loadF conditionalPutArgs "key" "a") in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "keyBytes"));; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "keyBytes");; + let: "expectedValBytes" := StringToBytes (struct.loadF conditionalPutArgs "expectedVal" "a") in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (slice.len "expectedValBytes"));; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") "expectedValBytes");; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF conditionalPutArgs "newVal" "a")));; + ![slice.T byteT] "e". + Definition decodeConditionalPutArgs: val := rec: "decodeConditionalPutArgs" "x" := let: "e" := ref_to (slice.T byteT) "x" in @@ -279,6 +257,19 @@ Definition decodeConditionalPutArgs: val := struct.storeF conditionalPutArgs "newVal" "a" (StringFromBytes "newValBytes");; "a". +(* Get *) +Definition getArgs := struct.decl [ + "opId" :: uint64T; + "key" :: stringT +]. + +Definition encodeGetArgs: val := + rec: "encodeGetArgs" "a" := + let: "e" := ref_to (slice.T byteT) (NewSlice byteT #0) in + "e" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "e") (struct.loadF getArgs "opId" "a"));; + "e" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "e") (StringToBytes (struct.loadF getArgs "key" "a")));; + ![slice.T byteT] "e". + Definition decodeGetArgs: val := rec: "decodeGetArgs" "x" := let: "e" := ref_to (slice.T byteT) "x" in @@ -314,47 +305,47 @@ Definition Server__getFreshNum: val := Definition Server__put: val := rec: "Server__put" "s" "args" := Mutex__Lock (struct.loadF Server "mu" "s");; - let: (<>, "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF putArgs "opId" "args") in + let: (<>, "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF put_gk.S "OpId" "args") in (if: "ok" then Mutex__Unlock (struct.loadF Server "mu" "s");; #() else - MapInsert (struct.loadF Server "kvs" "s") (struct.loadF putArgs "key" "args") (struct.loadF putArgs "val" "args");; - MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF putArgs "opId" "args") #(str"");; + MapInsert (struct.loadF Server "kvs" "s") (struct.loadF put_gk.S "Key" "args") (struct.loadF put_gk.S "Val" "args");; + MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF put_gk.S "OpId" "args") #(str"");; Mutex__Unlock (struct.loadF Server "mu" "s");; #()). Definition Server__conditionalPut: val := rec: "Server__conditionalPut" "s" "args" := Mutex__Lock (struct.loadF Server "mu" "s");; - let: ("ret", "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF conditionalPutArgs "opId" "args") in + let: ("ret", "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF conditionalput_gk.S "OpId" "args") in (if: "ok" then Mutex__Unlock (struct.loadF Server "mu" "s");; "ret" else let: "ret2" := ref_to stringT #(str"") in - (if: (Fst (MapGet (struct.loadF Server "kvs" "s") (struct.loadF conditionalPutArgs "key" "args"))) = (struct.loadF conditionalPutArgs "expectedVal" "args") + (if: (Fst (MapGet (struct.loadF Server "kvs" "s") (struct.loadF conditionalput_gk.S "Key" "args"))) = (struct.loadF conditionalput_gk.S "ExpectedVal" "args") then - MapInsert (struct.loadF Server "kvs" "s") (struct.loadF conditionalPutArgs "key" "args") (struct.loadF conditionalPutArgs "newVal" "args");; + MapInsert (struct.loadF Server "kvs" "s") (struct.loadF conditionalput_gk.S "Key" "args") (struct.loadF conditionalput_gk.S "NewVal" "args");; "ret2" <-[stringT] #(str"ok") else #());; - MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF conditionalPutArgs "opId" "args") (![stringT] "ret2");; + MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF conditionalput_gk.S "OpId" "args") (![stringT] "ret2");; Mutex__Unlock (struct.loadF Server "mu" "s");; ![stringT] "ret2"). Definition Server__get: val := rec: "Server__get" "s" "args" := Mutex__Lock (struct.loadF Server "mu" "s");; - let: ("ret", "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF getArgs "opId" "args") in + let: ("ret", "ok") := MapGet (struct.loadF Server "lastReplies" "s") (struct.loadF get_gk.S "OpId" "args") in (if: "ok" then Mutex__Unlock (struct.loadF Server "mu" "s");; "ret" else - let: "ret2" := Fst (MapGet (struct.loadF Server "kvs" "s") (struct.loadF getArgs "key" "args")) in - MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF getArgs "opId" "args") "ret2";; + let: "ret2" := Fst (MapGet (struct.loadF Server "kvs" "s") (struct.loadF get_gk.S "Key" "args")) in + MapInsert (struct.loadF Server "lastReplies" "s") (struct.loadF get_gk.S "OpId" "args") "ret2";; Mutex__Unlock (struct.loadF Server "mu" "s");; "ret2"). @@ -366,15 +357,18 @@ Definition Server__Start: val := #() );; MapInsert "handlers" rpcIdPut (λ: "enc_args" "enc_reply", - Server__put "s" (decodePutArgs "enc_args");; + let: ("args", <>) := put_gk.Unmarshal "enc_args" in + Server__put "s" "args";; #() );; MapInsert "handlers" rpcIdConditionalPut (λ: "enc_args" "enc_reply", - "enc_reply" <-[slice.T byteT] (StringToBytes (Server__conditionalPut "s" (decodeConditionalPutArgs "enc_args")));; + let: ("args", <>) := conditionalput_gk.Unmarshal "enc_args" in + "enc_reply" <-[slice.T byteT] (StringToBytes (Server__conditionalPut "s" "args"));; #() );; MapInsert "handlers" rpcIdGet (λ: "enc_args" "enc_reply", - "enc_reply" <-[slice.T byteT] (StringToBytes (Server__get "s" (decodeGetArgs "enc_args")));; + let: ("args", <>) := get_gk.Unmarshal "enc_args" in + "enc_reply" <-[slice.T byteT] (StringToBytes (Server__get "s" "args"));; #() );; urpc.Server__Serve (urpc.MakeServer "handlers") "me";; diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v new file mode 100644 index 000000000..351022b37 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v @@ -0,0 +1,70 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/kvservice/conditionalput_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "OpId" :: uint64T; + "Key" :: stringT; + "ExpectedVal" :: stringT; + "NewVal" :: stringT +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "c" := + #0. + +Definition Marshal: val := + rec: "Marshal" "c" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "OpId" "c"));; + let: "keyBytes" := StringToBytes (struct.loadF S "Key" "c") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "keyBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "keyBytes");; + let: "expectedvalBytes" := StringToBytes (struct.loadF S "ExpectedVal" "c") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "expectedvalBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "expectedvalBytes");; + let: "newvalBytes" := StringToBytes (struct.loadF S "NewVal" "c") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "newvalBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "newvalBytes");; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "c" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "OpId" "c" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "keyLen" := ref (zero_val uint64T) in + let: "keyBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "keyLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "keyLen") in + "keyBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Key" "c" (StringFromBytes (![slice.T byteT] "keyBytes"));; + let: "expectedValLen" := ref (zero_val uint64T) in + let: "expectedValBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "expectedValLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "expectedValLen") in + "expectedValBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "ExpectedVal" "c" (StringFromBytes (![slice.T byteT] "expectedValBytes"));; + let: "newValLen" := ref (zero_val uint64T) in + let: "newValBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "newValLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "newValLen") in + "newValBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "NewVal" "c" (StringFromBytes (![slice.T byteT] "newValBytes"));; + ("c", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v new file mode 100644 index 000000000..b457fe732 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v @@ -0,0 +1,44 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/kvservice/get_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "OpId" :: uint64T; + "Key" :: stringT +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "g" := + #0. + +Definition Marshal: val := + rec: "Marshal" "g" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "OpId" "g"));; + let: "keyBytes" := StringToBytes (struct.loadF S "Key" "g") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "keyBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "keyBytes");; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "g" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "OpId" "g" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "keyLen" := ref (zero_val uint64T) in + let: "keyBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "keyLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "keyLen") in + "keyBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Key" "g" (StringFromBytes (![slice.T byteT] "keyBytes"));; + ("g", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v new file mode 100644 index 000000000..d8760220e --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v @@ -0,0 +1,57 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/kvservice/put_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "OpId" :: uint64T; + "Key" :: stringT; + "Val" :: stringT +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "p" := + #0. + +Definition Marshal: val := + rec: "Marshal" "p" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "OpId" "p"));; + let: "keyBytes" := StringToBytes (struct.loadF S "Key" "p") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "keyBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "keyBytes");; + let: "valBytes" := StringToBytes (struct.loadF S "Val" "p") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "valBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "valBytes");; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "p" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "OpId" "p" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "keyLen" := ref (zero_val uint64T) in + let: "keyBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "keyLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "keyLen") in + "keyBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Key" "p" (StringFromBytes (![slice.T byteT] "keyBytes"));; + let: "valLen" := ref (zero_val uint64T) in + let: "valBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "valLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "valLen") in + "valBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Val" "p" (StringFromBytes (![slice.T byteT] "valBytes"));; + ("p", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v index 8b29c3544..29dc6cbfb 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v @@ -1,6 +1,7 @@ (* autogenerated from github.com/mit-pdos/gokv/tutorial/lockservice *) From Perennial.goose_lang Require Import prelude. From Goose Require github_com.goose_lang.std. +From Goose Require github_com.mit_pdos.gokv.tutorial.lockservice.lockrequest_gk. From Goose Require github_com.mit_pdos.gokv.urpc. From Goose Require github_com.tchajed.marshal. @@ -53,7 +54,9 @@ Definition Client__getFreshNum: val := Definition Client__tryAcquire: val := rec: "Client__tryAcquire" "cl" "id" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "args" := EncodeUint64 "id" in + let: "args" := lockrequest_gk.Marshal (struct.new lockrequest_gk.S [ + "Id" ::= "id" + ]) (NewSlice byteT #0) in let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") RPC_TRY_ACQUIRE "args" "reply" #100 in (if: "err" = urpc.ErrNone then (DecodeUint64 (![slice.T byteT] "reply"), "err") @@ -62,7 +65,9 @@ Definition Client__tryAcquire: val := Definition Client__release: val := rec: "Client__release" "cl" "id" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "args" := EncodeUint64 "id" in + let: "args" := lockrequest_gk.Marshal (struct.new lockrequest_gk.S [ + "Id" ::= "id" + ]) (NewSlice byteT #0) in urpc.Client__Call (struct.loadF Client "cl" "cl") RPC_RELEASE "args" "reply" #100. Definition makeClient: val := diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v new file mode 100644 index 000000000..82af21c96 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v @@ -0,0 +1,31 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/lockservice/lockrequest_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "Id" :: uint64T +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "l" := + #0. + +Definition Marshal: val := + rec: "Marshal" "l" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "Id" "l"));; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "l" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "Id" "l" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + ("l", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v index 7b7aaa6b1..3cbcf1a4f 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v @@ -1,7 +1,9 @@ (* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/chunk *) From Perennial.goose_lang Require Import prelude. From Goose Require github_com.mit_pdos.gokv.connman. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.chunk.writechunk_gk. From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir.recordchunk_gk. From Goose Require github_com.mit_pdos.gokv.urpc. From Perennial.goose_lang.trusted Require Import github_com.mit_pdos.gokv.trusted_hash. @@ -41,7 +43,7 @@ Definition ClerkPool := struct.decl [ Definition ClerkPool__WriteChunk: val := rec: "ClerkPool__WriteChunk" "ck" "addr" "args" := - let: "req" := MarshalWriteChunkArgs "args" in + let: "req" := writechunk_gk.Marshal "args" (NewSlice byteT #0) in let: "reply" := ref (zero_val (slice.T byteT)) in connman.ConnMan__CallAtLeastOnce (struct.loadF ClerkPool "cm" "ck") "addr" WriteChunkId "req" "reply" #100;; #(). @@ -64,15 +66,15 @@ Definition Server := struct.decl [ Definition Server__WriteChunk: val := rec: "Server__WriteChunk" "s" "args" := - let: "content_hash" := trusted_hash.Hash (struct.get WriteChunkArgs "Chunk" "args") in + let: "content_hash" := trusted_hash.Hash (struct.get writechunk_gk.S "Chunk" "args") in Mutex__Lock (struct.loadF Server "m" "s");; - MapInsert (struct.loadF Server "chunks" "s") "content_hash" (struct.get WriteChunkArgs "Chunk" "args");; + MapInsert (struct.loadF Server "chunks" "s") "content_hash" (struct.get writechunk_gk.S "Chunk" "args");; Mutex__Unlock (struct.loadF Server "m" "s");; - dir.Clerk__RecordChunk (struct.loadF Server "dir" "s") (struct.mk dir.RecordChunkArgs [ - "WriteId" ::= struct.get WriteChunkArgs "WriteId" "args"; + dir.Clerk__RecordChunk (struct.loadF Server "dir" "s") (struct.mk recordchunk_gk.S [ + "WriteId" ::= struct.get writechunk_gk.S "WriteId" "args"; "Server" ::= struct.loadF Server "me" "s"; "ContentHash" ::= "content_hash"; - "Index" ::= struct.get WriteChunkArgs "Index" "args" + "Index" ::= struct.get writechunk_gk.S "Index" "args" ]);; #(). @@ -94,8 +96,8 @@ Definition StartServer: val := ] in let: "handlers" := NewMap uint64T ((slice.T byteT) -> ptrT -> unitT)%ht #() in MapInsert "handlers" WriteChunkId (λ: "req" "reply", - let: "args" := ParseWriteChunkArgs "req" in - Server__WriteChunk "s" "args";; + let: ("args", <>) := writechunk_gk.Unmarshal "req" in + Server__WriteChunk "s" (struct.load writechunk_gk.S "args");; "reply" <-[slice.T byteT] (NewSlice byteT #0);; #() );; diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v new file mode 100644 index 000000000..6d96e7a67 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v @@ -0,0 +1,48 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/chunk/writechunk_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "WriteId" :: uint64T; + "Chunk" :: slice.T byteT; + "Index" :: uint64T +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "w" := + #0. + +Definition Marshal: val := + rec: "Marshal" "w" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "WriteId" "w"));; + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len (struct.loadF S "Chunk" "w")));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") (struct.loadF S "Chunk" "w"));; + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "Index" "w"));; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "w" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "WriteId" "w" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "chunkLen" := ref (zero_val uint64T) in + let: "chunkBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "chunkLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "chunkLen") in + "chunkBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Chunk" "w" (![slice.T byteT] "chunkBytes");; + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "Index" "w" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + ("w", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/client.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/client.v index 03e3c0da4..86a3b2e4c 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/client.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/client.v @@ -1,7 +1,9 @@ (* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/client *) From Perennial.goose_lang Require Import prelude. From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.chunk. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.chunk.writechunk_gk. From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir.finishwrite_gk. From Perennial.goose_lang Require Import ffi.grove_prelude. @@ -35,7 +37,7 @@ Definition Writer__AppendChunk: val := let: "index" := struct.loadF Writer "index" "w" in struct.storeF Writer "index" "w" ((struct.loadF Writer "index" "w") + #1);; Fork (let: "addr" := SliceGet uint64T (struct.loadF Writer "chunkAddrs" "w") ("index" `rem` (slice.len (struct.loadF Writer "chunkAddrs" "w"))) in - let: "args" := struct.mk chunk.WriteChunkArgs [ + let: "args" := struct.mk writechunk_gk.S [ "WriteId" ::= struct.loadF Writer "writeId" "w"; "Chunk" ::= "data"; "Index" ::= "index" @@ -47,7 +49,7 @@ Definition Writer__AppendChunk: val := Definition Writer__Done: val := rec: "Writer__Done" "w" := waitgroup.Wait (struct.loadF Writer "wg" "w");; - dir.Clerk__FinishWrite (struct.loadF Clerk "dCk" (struct.loadF Writer "ck" "w")) (struct.mk dir.FinishWriteArgs [ + dir.Clerk__FinishWrite (struct.loadF Clerk "dCk" (struct.loadF Writer "ck" "w")) (struct.mk finishwrite_gk.S [ "WriteId" ::= struct.loadF Writer "writeId" "w"; "Keyname" ::= struct.loadF Writer "keyname" "w" ]);; diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v index 362b1aeb9..2025085f0 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v @@ -1,6 +1,8 @@ (* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/dir *) From Perennial.goose_lang Require Import prelude. From Goose Require github_com.mit_pdos.gokv.reconnectclient. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir.finishwrite_gk. +From Goose Require github_com.mit_pdos.gokv.tutorial.objectstore.dir.recordchunk_gk. From Goose Require github_com.mit_pdos.gokv.urpc. From Perennial.goose_lang Require Import ffi.grove_prelude. @@ -108,7 +110,7 @@ Definition Clerk__PrepareWrite: val := (* From chunk *) Definition Clerk__RecordChunk: val := rec: "Clerk__RecordChunk" "ck" "args" := - let: "req" := MarshalRecordChunkArgs "args" in + let: "req" := recordchunk_gk.Marshal "args" (NewSlice byteT #0) in let: "reply" := ref (zero_val (slice.T byteT)) in reconnectclient.ReconnectingClient__Call (struct.loadF Clerk "client" "ck") RecordChunkId "req" "reply" #100;; #(). @@ -116,7 +118,7 @@ Definition Clerk__RecordChunk: val := (* From chunk *) Definition Clerk__FinishWrite: val := rec: "Clerk__FinishWrite" "ck" "args" := - let: "req" := MarshalFinishWriteArgs "args" in + let: "req" := finishwrite_gk.Marshal "args" (NewSlice byteT #0) in let: "reply" := ref (zero_val (slice.T byteT)) in reconnectclient.ReconnectingClient__Call (struct.loadF Clerk "client" "ck") FinishWriteId "req" "reply" #100;; #(). @@ -164,9 +166,9 @@ Definition Server__PrepareWrite: val := Definition Server__RecordChunk: val := rec: "Server__RecordChunk" "s" "args" := Mutex__Lock (struct.loadF Server "m" "s");; - MapInsert (struct.get PartialValue "servers" (Fst (MapGet (struct.loadF Server "ongoing" "s") (struct.get RecordChunkArgs "WriteId" "args")))) (struct.get RecordChunkArgs "Index" "args") (struct.mk ChunkHandle [ - "Addr" ::= struct.get RecordChunkArgs "Server" "args"; - "ContentHash" ::= struct.get RecordChunkArgs "ContentHash" "args" + MapInsert (struct.get PartialValue "servers" (Fst (MapGet (struct.loadF Server "ongoing" "s") (struct.get recordchunk_gk.S "WriteId" "args")))) (struct.get recordchunk_gk.S "Index" "args") (struct.mk ChunkHandle [ + "Addr" ::= struct.get recordchunk_gk.S "Server" "args"; + "ContentHash" ::= struct.get recordchunk_gk.S "ContentHash" "args" ]);; Mutex__Unlock (struct.loadF Server "m" "s");; #(). @@ -175,14 +177,14 @@ Definition Server__RecordChunk: val := Definition Server__FinishWrite: val := rec: "Server__FinishWrite" "s" "args" := Mutex__Lock (struct.loadF Server "m" "s");; - let: "v" := struct.get PartialValue "servers" (Fst (MapGet (struct.loadF Server "ongoing" "s") (struct.get FinishWriteArgs "WriteId" "args"))) in + let: "v" := struct.get PartialValue "servers" (Fst (MapGet (struct.loadF Server "ongoing" "s") (struct.get finishwrite_gk.S "WriteId" "args"))) in let: "numChunks" := MapLen "v" in let: "servers" := ref_to (slice.T (struct.t ChunkHandle)) (NewSlice (struct.t ChunkHandle) #0) in let: "i" := ref_to uint64T #0 in (for: (λ: <>, (![uint64T] "i") < "numChunks"); (λ: <>, "i" <-[uint64T] ((![uint64T] "i") + #1)) := λ: <>, "servers" <-[slice.T (struct.t ChunkHandle)] (SliceAppend (struct.t ChunkHandle) (![slice.T (struct.t ChunkHandle)] "servers") (Fst (MapGet "v" (![uint64T] "i"))));; Continue);; - MapInsert (struct.loadF Server "data" "s") (struct.get FinishWriteArgs "Keyname" "args") (struct.mk Value [ + MapInsert (struct.loadF Server "data" "s") (struct.get finishwrite_gk.S "Keyname" "args") (struct.mk Value [ "servers" ::= ![slice.T (struct.t ChunkHandle)] "servers" ]);; Mutex__Unlock (struct.loadF Server "m" "s");; @@ -212,14 +214,14 @@ Definition StartServer: val := #() );; MapInsert "handlers" RecordChunkId (λ: "req" "reply", - let: "args" := ParseRecordChunkArgs "req" in - Server__RecordChunk "s" "args";; + let: ("args", <>) := recordchunk_gk.Unmarshal "req" in + Server__RecordChunk "s" (struct.load recordchunk_gk.S "args");; "reply" <-[slice.T byteT] (NewSlice byteT #0);; #() );; MapInsert "handlers" FinishWriteId (λ: "req" "reply", - let: "args" := ParseFinishWriteArgs "req" in - Server__FinishWrite "s" "args";; + let: ("args", <>) := finishwrite_gk.Unmarshal "req" in + Server__FinishWrite "s" (struct.load finishwrite_gk.S "args");; "reply" <-[slice.T byteT] (NewSlice byteT #0);; #() );; diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v new file mode 100644 index 000000000..a0835a597 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v @@ -0,0 +1,44 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "Addr" :: uint64T; + "ContentHash" :: stringT +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "c" := + #0. + +Definition Marshal: val := + rec: "Marshal" "c" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "Addr" "c"));; + let: "contenthashBytes" := StringToBytes (struct.loadF S "ContentHash" "c") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "contenthashBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "contenthashBytes");; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "c" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "Addr" "c" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "contentHashLen" := ref (zero_val uint64T) in + let: "contentHashBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "contentHashLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "contentHashLen") in + "contentHashBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "ContentHash" "c" (StringFromBytes (![slice.T byteT] "contentHashBytes"));; + ("c", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v new file mode 100644 index 000000000..28550d2d9 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v @@ -0,0 +1,44 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/dir/finishwrite_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "WriteId" :: uint64T; + "Keyname" :: stringT +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "f" := + #0. + +Definition Marshal: val := + rec: "Marshal" "f" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "WriteId" "f"));; + let: "keynameBytes" := StringToBytes (struct.loadF S "Keyname" "f") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "keynameBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "keynameBytes");; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "f" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "WriteId" "f" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "keynameLen" := ref (zero_val uint64T) in + let: "keynameBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "keynameLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "keynameLen") in + "keynameBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "Keyname" "f" (StringFromBytes (![slice.T byteT] "keynameBytes"));; + ("f", ![slice.T byteT] "enc"). + +End code. diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v new file mode 100644 index 000000000..1b103f780 --- /dev/null +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v @@ -0,0 +1,54 @@ +(* autogenerated from github.com/mit-pdos/gokv/tutorial/objectstore/dir/recordchunk_gk *) +From Perennial.goose_lang Require Import prelude. +From Goose Require github_com.tchajed.marshal. + +Section code. +Context `{ext_ty: ext_types}. + +Definition S := struct.decl [ + "WriteId" :: uint64T; + "Server" :: uint64T; + "ContentHash" :: stringT; + "Index" :: uint64T +]. + +Definition S__approxSize: val := + rec: "S__approxSize" "r" := + #0. + +Definition Marshal: val := + rec: "Marshal" "r" "prefix" := + let: "enc" := ref_to (slice.T byteT) "prefix" in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "WriteId" "r"));; + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "Server" "r"));; + let: "contenthashBytes" := StringToBytes (struct.loadF S "ContentHash" "r") in + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len "contenthashBytes"));; + "enc" <-[slice.T byteT] (marshal.WriteBytes (![slice.T byteT] "enc") "contenthashBytes");; + "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.loadF S "Index" "r"));; + ![slice.T byteT] "enc". + +Definition Unmarshal: val := + rec: "Unmarshal" "s" := + let: "r" := struct.alloc S (zero_val (struct.t S)) in + let: "enc" := ref_to (slice.T byteT) "s" in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "WriteId" "r" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "Server" "r" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: "contentHashLen" := ref (zero_val uint64T) in + let: "contentHashBytes" := ref (zero_val (slice.T byteT)) in + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + "contentHashLen" <-[uint64T] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + let: ("0_ret", "1_ret") := marshal.ReadBytes (![slice.T byteT] "enc") (![uint64T] "contentHashLen") in + "contentHashBytes" <-[slice.T byteT] "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + struct.storeF S "ContentHash" "r" (StringFromBytes (![slice.T byteT] "contentHashBytes"));; + let: ("0_ret", "1_ret") := marshal.ReadInt (![slice.T byteT] "enc") in + struct.storeF S "Index" "r" "0_ret";; + "enc" <-[slice.T byteT] "1_ret";; + ("r", ![slice.T byteT] "enc"). + +End code. diff --git a/flake.nix b/flake.nix index 0c945f315..866449179 100644 --- a/flake.nix +++ b/flake.nix @@ -17,22 +17,38 @@ src = pkgs.fetchFromGitHub { owner = "mjschwenne"; repo = "grackle"; - rev = "18dbbd313c299d74895f566aae028eeba62a699a"; - hash = "sha256-GDo3c3VbRl0FR7sJ2Cvmdau+rBRcxwb/sGAEwV5seFQ="; + rev = "967767505d688aa2c578d75653e3cbd96af7a5bd"; + hash = "sha256-z9hl6fjFZH8t3DtvGVedMJDg1fL6+8XyANBsH3DE4r8="; }; vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; checkPhase = false; }; + goose = pkgs.buildGoModule { + name = "goose"; + src = pkgs.fetchFromGitHub { + owner = "goose-lang"; + repo = "goose"; + rev = "585abc3cfef50dd466e112d7c535dbdfccd3c0ca"; + hash = "sha256-M4zaZ1DdecYXeDugrL+TV7HWPMLuj1P25G6mf+fgljg="; + }; + vendorHash = "sha256-HCJ8v3TSv4UrkOsRuENWVz5Z7zQ1UsOygx0Mo7MELzY="; + }; in pkgs.mkShell { - # create an environment with the required coq libraries - packages = with pkgs; [ + packages = [ # coq deps - coq + pkgs.coq - # grackle + pkgs.go grackle - protobuf + goose + pkgs.protobuf + + # nix helper + # Should be able to update goose and grackle with `update-nix-fetchgit flake.nix` + pkgs.update-nix-fetchgit + pkgs.nix-prefetch-git + pkgs.nix-prefetch ]; shellHook = '' diff --git a/src/program_proof/tutorial/kvservice/conditionalput_proof.v b/src/program_proof/tutorial/kvservice/conditionalput_proof.v new file mode 100644 index 000000000..b0e952bae --- /dev/null +++ b/src/program_proof/tutorial/kvservice/conditionalput_proof.v @@ -0,0 +1,157 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.conditionalput_gk. + +Module conditionalPut. +Section conditionalPut. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + opId : u64; + key : string; + expectedVal : string; + newVal : string; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(opId)) ++ + (u64_le $ length $ string_to_bytes args.(key)) ++ string_to_bytes args.(key) ++ + (u64_le $ length $ string_to_bytes args.(expectedVal)) ++ string_to_bytes args.(expectedVal) ++ + (u64_le $ length $ string_to_bytes args.(newVal)) ++ string_to_bytes args.(newVal). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[conditionalput_gk.S :: "OpId"]{q} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[conditionalput_gk.S :: "Key"]{q} #(str args.(key)) ∗ + "Hargs_expectedVal" ∷ args_ptr ↦[conditionalput_gk.S :: "ExpectedVal"]{q} #(str args.(expectedVal)) ∗ + "Hargs_newVal" ∷ args_ptr ↦[conditionalput_gk.S :: "NewVal"]{q} #(str args.(newVal)). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + conditionalput_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". + iApply own_slice_to_small in "Hargs_key_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_expectedVal_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_expectedVal_enc") as "%Hargs_expectedVal_sz". + iApply own_slice_to_small in "Hargs_expectedVal_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_expectedVal_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_newVal_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_newVal_enc") as "%Hargs_newVal_sz". + iApply own_slice_to_small in "Hargs_newVal_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_newVal_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + conditionalput_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in Hkey_sz. word. } + iIntros (??) "[Hkey' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". + wp_storeField. + + wp_apply wp_ref_of_zero; first done. iIntros (expectedValLen) "HexpectedValLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (expectedValBytes) "HexpectedValBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %HexpectedVal_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in HexpectedVal_sz. word. } + iIntros (??) "[HexpectedVal' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$HexpectedVal']"). iIntros "_". + wp_storeField. + + wp_apply wp_ref_of_zero; first done. iIntros (newValLen) "HnewValLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (newValBytes) "HnewValBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %HnewVal_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in HnewVal_sz. word. } + iIntros (??) "[HnewVal' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$HnewVal']"). iIntros "_". + wp_storeField. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End conditionalPut. +End conditionalPut. + diff --git a/src/program_proof/tutorial/kvservice/get_proof.v b/src/program_proof/tutorial/kvservice/get_proof.v new file mode 100644 index 000000000..ca1945a8a --- /dev/null +++ b/src/program_proof/tutorial/kvservice/get_proof.v @@ -0,0 +1,106 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.get_gk. + +Module get. +Section get. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + opId : u64; + key : string; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(opId)) ++ + (u64_le $ length $ string_to_bytes args.(key)) ++ string_to_bytes args.(key). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[get_gk.S :: "OpId"]{q} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[get_gk.S :: "Key"]{q} #(str args.(key)). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + get_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". + iApply own_slice_to_small in "Hargs_key_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + unfold has_encoding. rewrite ?string_bytes_length. rewrite Hargs_key_sz. + rewrite w64_to_nat_id. exact. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + get_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in Hkey_sz. word. } + iIntros (??) "[Hkey' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". + wp_storeField. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End get. +End get. + diff --git a/src/program_proof/tutorial/kvservice/proof.v b/src/program_proof/tutorial/kvservice/proof.v index 0bee80249..1b4d511ba 100644 --- a/src/program_proof/tutorial/kvservice/proof.v +++ b/src/program_proof/tutorial/kvservice/proof.v @@ -6,6 +6,10 @@ From Perennial.program_proof Require Import std_proof. From Perennial.goose_lang.automation Require Import extra_tactics. From Perennial.goose_lang Require Import proofmode. +From Perennial.program_proof.tutorial.kvservice Require Import get_proof. +From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof. +From Perennial.program_proof.tutorial.kvservice Require Import put_proof. + Unset Printing Projections. (********************************************************************************) @@ -623,6 +627,9 @@ Proof. wp_apply (wp_Mutex__Lock with "[$]") as "[Hlocked Hown]"; iNamed "Hown". iNamed "Hargs". wp_auto. + + wp_loadField. + wp_apply (wp_MapGet with "HlastRepliesM") as (??) "[%HlastReply HlastRepliesM]". wp_if_destruct; wp_auto. { (* case: this is a duplicate request *) diff --git a/src/program_proof/tutorial/kvservice/put_proof.v b/src/program_proof/tutorial/kvservice/put_proof.v new file mode 100644 index 000000000..eee039486 --- /dev/null +++ b/src/program_proof/tutorial/kvservice/put_proof.v @@ -0,0 +1,131 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.put_gk. + +Module put. +Section put. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + opId : u64; + key : string; + val : string; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(opId)) ++ + (u64_le $ length $ string_to_bytes args.(key)) ++ string_to_bytes args.(key) ++ + (u64_le $ length $ string_to_bytes args.(val)) ++ string_to_bytes args.(val). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[put_gk.S :: "OpId"]{q} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[put_gk.S :: "Key"]{q} #(str args.(key)) ∗ + "Hargs_val" ∷ args_ptr ↦[put_gk.S :: "Val"]{q} #(str args.(val)). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + put_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". + iApply own_slice_to_small in "Hargs_key_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_val_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_val_enc") as "%Hargs_val_sz". + iApply own_slice_to_small in "Hargs_val_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_val_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + put_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in Hkey_sz. word. } + iIntros (??) "[Hkey' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". + wp_storeField. + + wp_apply wp_ref_of_zero; first done. iIntros (valLen) "HvalLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (valBytes) "HvalBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hval_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in Hval_sz. word. } + iIntros (??) "[Hval' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$Hval']"). iIntros "_". + wp_storeField. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End put. +End put. + diff --git a/src/program_proof/tutorial/lockservice/lockrequest_proof.v b/src/program_proof/tutorial/lockservice/lockrequest_proof.v new file mode 100644 index 000000000..8c071bf3a --- /dev/null +++ b/src/program_proof/tutorial/lockservice/lockrequest_proof.v @@ -0,0 +1,79 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.lockservice.lockrequest_gk. + +Module LockRequest. +Section LockRequest. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + id : u64; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(id)). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_id" ∷ args_ptr ↦[lockrequest_gk.S :: "Id"]{q} #args.(id). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + lockrequest_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + lockrequest_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End LockRequest. +End LockRequest. + diff --git a/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v b/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v new file mode 100644 index 000000000..857fa7d7d --- /dev/null +++ b/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v @@ -0,0 +1,115 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.chunk.writechunk_gk. + +Module writeChunk. +Section writeChunk. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + writeId : u64; + chunk : list u8; + index : u64; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(writeId)) ++ + (u64_le $ length $ args.(chunk)) ++ args.(chunk) ++ + (u64_le args.(index)). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ :=(chunk_sl : Slice.t) + "Hargs_writeId" ∷ args_ptr ↦[writechunk_gk.S :: "WriteId"]{q} #args.(writeId) ∗ + "Hargs_chunk" ∷ args_ptr ↦[writechunk_gk.S :: "Chunk"]{q} (slice_val chunk_sl) ∗ + "Hargs_chunk_sl" ∷ own_slice_small chunk_sl byteT q args.(chunk) + ∗ + "Hargs_index" ∷ args_ptr ↦[writechunk_gk.S :: "Index"]{q} #args.(index). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + writechunk_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + + iDestruct (own_slice_small_sz with "Hargs_chunk_enc") as "%Hargs_chunk_sz". + wp_loadField. wp_load. wp_apply wp_slice_len. wp_load. + wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + + wp_loadField. wp_load. wp_load. + wp_apply (wp_WriteBytes with "[$Hsl $Hargs_chunk_enc]"). + iIntros (?) "[Hsl _]". wp_store. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + writechunk_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_allocN; first done; first by val_ty. + iIntros (?) "HchunkLen". iApply array_singleton in "HchunkLen". wp_pures. + wp_apply wp_allocN; first done; first by val_ty. + iIntros (?) "Hchunk". iApply array_singleton in "Hchunk". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hchunk_sz. + wp_apply (wp_ReadBytesCopy with "[$]"). + { rewrite length_app in Hchunk_sz. word. } + iIntros (??) "[Hchunk' Hsl]". iApply own_slice_to_small in "Hchunk'". + + wp_pures. wp_store. wp_store. wp_storeField. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End writeChunk. +End writeChunk. + diff --git a/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v b/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v new file mode 100644 index 000000000..110f03755 --- /dev/null +++ b/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v @@ -0,0 +1,105 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.chunkhandle_gk. + +Module chunkHandle. +Section chunkHandle. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + addr : u64; + contentHash : string; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(addr)) ++ + (u64_le $ length $ string_to_bytes args.(contentHash)) ++ string_to_bytes args.(contentHash). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_addr" ∷ args_ptr ↦[chunkhandle_gk.S :: "Addr"]{q} #args.(addr) ∗ + "Hargs_contentHash" ∷ args_ptr ↦[chunkhandle_gk.S :: "ContentHash"]{q} #(str args.(contentHash)). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + chunkhandle_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_contentHash_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_contentHash_enc") as "%Hargs_contentHash_sz". + iApply own_slice_to_small in "Hargs_contentHash_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_contentHash_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + chunkhandle_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (contentHashLen) "HcontentHashLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (contentHashBytes) "HcontentHashBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %HcontentHash_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in HcontentHash_sz. word. } + iIntros (??) "[HcontentHash' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$HcontentHash']"). iIntros "_". + wp_storeField. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End chunkHandle. +End chunkHandle. + diff --git a/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v b/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v new file mode 100644 index 000000000..ec37e9af3 --- /dev/null +++ b/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v @@ -0,0 +1,105 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.finishwrite_gk. + +Module finishWrite. +Section finishWrite. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + writeId : u64; + keyname : string; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(writeId)) ++ + (u64_le $ length $ string_to_bytes args.(keyname)) ++ string_to_bytes args.(keyname). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_writeId" ∷ args_ptr ↦[finishwrite_gk.S :: "WriteId"]{q} #args.(writeId) ∗ + "Hargs_keyname" ∷ args_ptr ↦[finishwrite_gk.S :: "Keyname"]{q} #(str args.(keyname)). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + finishwrite_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_keyname_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_keyname_enc") as "%Hargs_keyname_sz". + iApply own_slice_to_small in "Hargs_keyname_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_keyname_enc]"). + iIntros (?) "[Hsl _]". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + finishwrite_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (keynameLen) "HkeynameLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (keynameBytes) "HkeynameBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %Hkeyname_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in Hkeyname_sz. word. } + iIntros (??) "[Hkeyname' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$Hkeyname']"). iIntros "_". + wp_storeField. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End finishWrite. +End finishWrite. + diff --git a/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v b/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v new file mode 100644 index 000000000..404dd62e5 --- /dev/null +++ b/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v @@ -0,0 +1,121 @@ +From Perennial.program_proof Require Import grove_prelude. +From Perennial.program_proof Require Import marshal_stateless_proof. +From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.recordchunk_gk. + +Module recordChunk. +Section recordChunk. + +Typeclasses Opaque app. + +Context `{!heapGS Σ}. + +Record C := + mkC { + writeId : u64; + server : u64; + contentHash : string; + index : u64; + }. + +Definition has_encoding (encoded:list u8) (args:C) : Prop := + encoded = (u64_le args.(writeId)) ++ + (u64_le args.(server)) ++ + (u64_le $ length $ string_to_bytes args.(contentHash)) ++ string_to_bytes args.(contentHash) ++ + (u64_le args.(index)). + +Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := + "Hargs_writeId" ∷ args_ptr ↦[recordchunk_gk.S :: "WriteId"]{q} #args.(writeId) ∗ + "Hargs_server" ∷ args_ptr ↦[recordchunk_gk.S :: "Server"]{q} #args.(server) ∗ + "Hargs_contentHash" ∷ args_ptr ↦[recordchunk_gk.S :: "ContentHash"]{q} #(str args.(contentHash)) ∗ + "Hargs_index" ∷ args_ptr ↦[recordchunk_gk.S :: "Index"]{q} #args.(index). + +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : + {{{ + own args_ptr args (DfracDiscarded) ∗ + own_slice pre_sl byteT (DfracOwn 1) prefix + }}} + recordchunk_gk.Marshal #args_ptr (slice_val pre_sl) + {{{ + enc enc_sl, RET (slice_val enc_sl); + ⌜has_encoding enc args⌝ ∗ + own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) + }}}. + +Proof. + iIntros (?) "H HΦ". iDestruct "H" as "[Hown Hsl]". iNamed "Hown". + wp_rec. wp_pures. + wp_apply (wp_ref_to); first by val_ty. + iIntros (?) "Hptr". wp_pures. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_loadField. + wp_apply wp_StringToBytes. iIntros (?) "Hargs_contentHash_enc". wp_pures. + wp_apply (wp_slice_len). + iDestruct (own_slice_sz with "Hargs_contentHash_enc") as "%Hargs_contentHash_sz". + iApply own_slice_to_small in "Hargs_contentHash_enc". + wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_contentHash_enc]"). + iIntros (?) "[Hsl _]". wp_store. + wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_store. + + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. + iFrame. iPureIntro. + + done. +Qed. + +Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): + {{{ + ⌜has_encoding enc args⌝ ∗ + own_slice_small enc_sl byteT q (enc ++ suffix) + }}} + recordchunk_gk.Unmarshal (slice_val enc_sl) + {{{ + args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ + own_slice_small suff_sl byteT q suffix + }}}. + +Proof. + iIntros (?) "[%Henc Hsl] HΦ". wp_rec. + wp_apply wp_allocStruct; first by val_ty. + iIntros (?) "Hstruct". wp_pures. + wp_apply wp_ref_to; first done. + iIntros (?) "Hptr". wp_pures. + iDestruct (struct_fields_split with "Hstruct") as "HH". + iNamed "HH". + + rewrite Henc. rewrite -?app_assoc. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_apply wp_ref_of_zero; first done. iIntros (contentHashLen) "HcontentHashLen". wp_pures. + wp_apply wp_ref_of_zero; first done. iIntros (contentHashBytes) "HcontentHashBytes". wp_pures. + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). + iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. + + iDestruct (own_slice_small_sz with "Hsl") as %HcontentHash_sz. + wp_apply (wp_ReadBytes with "[$]"). + { rewrite length_app in HcontentHash_sz. word. } + iIntros (??) "[HcontentHash' Hsl]". + + wp_pures. wp_store. wp_store. wp_load. + wp_apply (wp_StringFromBytes with "[$HcontentHash']"). iIntros "_". + wp_storeField. + + wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". + wp_pures. wp_storeField. wp_store. + + wp_load. wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. +Qed. + +End recordChunk. +End recordChunk. + From 5cdcc20d3e752301b2579ea486baeb31d84a31be Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 22:13:49 -0600 Subject: [PATCH 07/25] begin integration of kvservice --- flake.nix | 6 +- .../tutorial/kvservice/conditionalput_proof.v | 8 +- .../tutorial/kvservice/get_proof.v | 7 +- src/program_proof/tutorial/kvservice/proof.v | 924 +++++++++--------- .../tutorial/kvservice/put_proof.v | 7 +- 5 files changed, 483 insertions(+), 469 deletions(-) diff --git a/flake.nix b/flake.nix index 866449179..20ec4a617 100644 --- a/flake.nix +++ b/flake.nix @@ -17,8 +17,8 @@ src = pkgs.fetchFromGitHub { owner = "mjschwenne"; repo = "grackle"; - rev = "967767505d688aa2c578d75653e3cbd96af7a5bd"; - hash = "sha256-z9hl6fjFZH8t3DtvGVedMJDg1fL6+8XyANBsH3DE4r8="; + rev = "ee753e57e3ad574d7d3f76f7de97af8817ac184c"; + sha256 = "0j532jnk52sfk36spkl7knd6ryqwg19ih5sg6pb9f2qy9lsyaw9g"; }; vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; checkPhase = false; @@ -29,7 +29,7 @@ owner = "goose-lang"; repo = "goose"; rev = "585abc3cfef50dd466e112d7c535dbdfccd3c0ca"; - hash = "sha256-M4zaZ1DdecYXeDugrL+TV7HWPMLuj1P25G6mf+fgljg="; + sha256 = "sha256-M4zaZ1DdecYXeDugrL+TV7HWPMLuj1P25G6mf+fgljg="; }; vendorHash = "sha256-HCJ8v3TSv4UrkOsRuENWVz5Z7zQ1UsOygx0Mo7MELzY="; }; diff --git a/src/program_proof/tutorial/kvservice/conditionalput_proof.v b/src/program_proof/tutorial/kvservice/conditionalput_proof.v index b0e952bae..039abaa07 100644 --- a/src/program_proof/tutorial/kvservice/conditionalput_proof.v +++ b/src/program_proof/tutorial/kvservice/conditionalput_proof.v @@ -76,10 +76,16 @@ Proof. wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_newVal_enc]"). iIntros (?) "[Hsl _]". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_key_sz. + rewrite Hargs_expectedVal_sz. + rewrite Hargs_newVal_sz. + rewrite ?w64_to_nat_id. exact. Qed. Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): diff --git a/src/program_proof/tutorial/kvservice/get_proof.v b/src/program_proof/tutorial/kvservice/get_proof.v index ca1945a8a..63fc7a810 100644 --- a/src/program_proof/tutorial/kvservice/get_proof.v +++ b/src/program_proof/tutorial/kvservice/get_proof.v @@ -52,11 +52,14 @@ Proof. wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). iIntros (?) "[Hsl _]". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - unfold has_encoding. rewrite ?string_bytes_length. rewrite Hargs_key_sz. - rewrite w64_to_nat_id. exact. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_key_sz. + rewrite ?w64_to_nat_id. exact. Qed. Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): diff --git a/src/program_proof/tutorial/kvservice/proof.v b/src/program_proof/tutorial/kvservice/proof.v index 1b4d511ba..ffad44ba9 100644 --- a/src/program_proof/tutorial/kvservice/proof.v +++ b/src/program_proof/tutorial/kvservice/proof.v @@ -14,433 +14,433 @@ Unset Printing Projections. (********************************************************************************) -Module putArgs. -Record t := - mk { - opId: u64 ; - key: string ; - val: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ - string_to_bytes a.(key) ++ string_to_bytes a.(val) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ - "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodePutArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (sl) "Hsl". - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - - wp_pures. - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "[$]"). - iIntros (?) "Hsl". - rewrite replicate_0 /=. - wp_store. - - wp_loadField. - wp_apply wp_StringToBytes. - iIntros (key_sl) "Hkey_sl". - wp_pures. - - wp_apply wp_slice_len. - iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl Hkey_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hval_sl". - iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". - wp_load. - wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). - iIntros (?) "[Hsl Hval_sl]". - wp_store. - - wp_load. - iApply "HΦ". - iFrame. - iPureIntro. - unfold encodes. - repeat rewrite -assoc. - rewrite Hsz. - repeat f_equal. - word. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodePutArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - - wp_pures. - wp_load. - rewrite Henc; clear dependent enc_args. - wp_apply (wp_ReadInt with "[$]"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - wp_load. - wp_apply (wp_ReadInt with "[$]"). - iIntros (?) "Hsl". - wp_pures. - iDestruct (own_slice_small_sz with "Hsl") as %Hsz. - wp_apply (wp_ReadBytes with "[$]"). - { rewrite length_app in Hsz. word. } - iIntros (??) "[Hkey Hval]". - wp_pures. - wp_apply (wp_StringFromBytes with "[$Hkey]"). - iIntros "Hkey". - wp_storeField. - wp_apply (wp_StringFromBytes with "[$Hval]"). - iIntros "Hval". - wp_storeField. - iModIntro. - iApply "HΦ". - do 2 rewrite string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. -End putArgs. - -Module conditionalPutArgs. -Record t := - mk { - opId: u64 ; - key: string ; - expectedVal: string ; - newVal: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ - (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ - "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ - "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodeConditionalPutArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (sl) "Hsl". - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - wp_pures. - - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "[$]"). - iIntros (?) "Hsl". - rewrite replicate_0 /=. - wp_store. - - wp_loadField. - wp_apply wp_StringToBytes. - iIntros (key_sl) "Hkey_sl". - wp_pures. - wp_apply wp_slice_len. - iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl Hkey_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hexpect_sl". - iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". - wp_pures. - - wp_apply wp_slice_len. - iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). - iIntros (?) "[Hsl Hexpect_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hval_sl". - wp_load. - iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). - iIntros (?) "[Hsl Hval_sl]". - wp_store. - - wp_load. - iApply "HΦ". - iFrame. - iPureIntro. - unfold encodes. - repeat rewrite -assoc. - rewrite Hsz. - repeat f_equal; word. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodeConditionalPutArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply wp_ref_to. - { done. } - iIntros (?) "He". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - wp_pures. - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - wp_load. - rewrite Henc. - - wp_apply (wp_ReadInt with "Hsl"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - - wp_load. - wp_apply (wp_ReadInt with "Hsl"). - iIntros (?) "Hsl". - wp_pures. - - iDestruct (own_slice_small_sz with "Hsl") as %Hsz. - wp_apply (wp_ReadBytes with "[$Hsl]"). - { rewrite length_app in Hsz. word. } - iIntros (??) "[Hkey Hsl]". - wp_pures. - wp_apply (wp_StringFromBytes with "[$Hkey]"). - iIntros "_". - wp_storeField. - - wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_pures. - - wp_apply (wp_ReadBytes with "[$Hsl]"). - { repeat rewrite length_app in Hsz. word. } - iIntros (??) "[Hexpect Hval]". - wp_pures. - - wp_apply (wp_StringFromBytes with "[$Hexpect]"). - iIntros "_". - wp_storeField. - wp_apply (wp_StringFromBytes with "[$Hval]"). - iIntros "_". - wp_storeField. - iModIntro. iApply "HΦ". - repeat rewrite string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. -End conditionalPutArgs. - -Module getArgs. -Record t := - mk { - opId: u64 ; - key: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ string_to_bytes a.(key) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodeGetArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (?) "Hsl". - wp_apply (wp_ref_to). - { done. } - iIntros (?) "He". - wp_pures. - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "Hsl"). - iIntros (?) "Hsl". - wp_store. - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hkey_sl". - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl _]". - wp_store. - wp_load. - iModIntro. iApply "HΦ". - iFrame. - iPureIntro. done. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodeGetArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply (wp_ref_to). - { done. } - iIntros (?) "He". - wp_pures. - wp_apply (wp_ref_of_zero). - { done. } - iIntros (?) "HkeyBytes". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - wp_pures. - wp_load. - rewrite Henc. - wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - - wp_load. - wp_apply (wp_StringFromBytes with "[$Hsl]"). - iIntros "_". - wp_storeField. - iModIntro. - iApply "HΦ". - repeat rewrite string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. - -End getArgs. +(* Module putArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* val: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ *) +(* string_to_bytes a.(key) ++ string_to_bytes a.(val) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ *) +(* "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodePutArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (sl) "Hsl". *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) + +(* wp_pures. *) +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* rewrite replicate_0 /=. *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply wp_StringToBytes. *) +(* iIntros (key_sl) "Hkey_sl". *) +(* wp_pures. *) + +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl Hkey_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hval_sl". *) +(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) +(* wp_load. *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) +(* iIntros (?) "[Hsl Hval_sl]". *) +(* wp_store. *) + +(* wp_load. *) +(* iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. *) +(* unfold encodes. *) +(* repeat rewrite -assoc. *) +(* rewrite Hsz. *) +(* repeat f_equal. *) +(* word. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodePutArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) + +(* wp_pures. *) +(* wp_load. *) +(* rewrite Henc; clear dependent enc_args. *) +(* wp_apply (wp_ReadInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) +(* wp_load. *) +(* wp_apply (wp_ReadInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) +(* wp_apply (wp_ReadBytes with "[$]"). *) +(* { rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hkey Hval]". *) +(* wp_pures. *) +(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) +(* iIntros "Hkey". *) +(* wp_storeField. *) +(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) +(* iIntros "Hval". *) +(* wp_storeField. *) +(* iModIntro. *) +(* iApply "HΦ". *) +(* do 2 rewrite string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) +(* End putArgs. *) + +(* Module conditionalPutArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* expectedVal: string ; *) +(* newVal: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ *) +(* (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ *) +(* "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ *) +(* "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodeConditionalPutArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (sl) "Hsl". *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) +(* wp_pures. *) + +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* rewrite replicate_0 /=. *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply wp_StringToBytes. *) +(* iIntros (key_sl) "Hkey_sl". *) +(* wp_pures. *) +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl Hkey_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hexpect_sl". *) +(* iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". *) +(* wp_pures. *) + +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). *) +(* iIntros (?) "[Hsl Hexpect_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hval_sl". *) +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) +(* iIntros (?) "[Hsl Hval_sl]". *) +(* wp_store. *) + +(* wp_load. *) +(* iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. *) +(* unfold encodes. *) +(* repeat rewrite -assoc. *) +(* rewrite Hsz. *) +(* repeat f_equal; word. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodeConditionalPutArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* wp_pures. *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) +(* wp_load. *) +(* rewrite Henc. *) + +(* wp_apply (wp_ReadInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_ReadInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) + +(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) +(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) +(* { rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hkey Hsl]". *) +(* wp_pures. *) +(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) +(* iIntros "_". *) +(* wp_storeField. *) + +(* wp_apply (wp_ReadInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) + +(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) +(* { repeat rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hexpect Hval]". *) +(* wp_pures. *) + +(* wp_apply (wp_StringFromBytes with "[$Hexpect]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* iModIntro. iApply "HΦ". *) +(* repeat rewrite string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) +(* End conditionalPutArgs. *) + +(* Module getArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ string_to_bytes a.(key) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodeGetArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (?) "Hsl". *) +(* wp_apply (wp_ref_to). *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hkey_sl". *) +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl _]". *) +(* wp_store. *) +(* wp_load. *) +(* iModIntro. iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. done. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodeGetArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply (wp_ref_to). *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_apply (wp_ref_of_zero). *) +(* { done. } *) +(* iIntros (?) "HkeyBytes". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) +(* wp_pures. *) +(* wp_load. *) +(* rewrite Henc. *) +(* wp_apply (wp_ReadInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_StringFromBytes with "[$Hsl]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* iModIntro. *) +(* iApply "HΦ". *) +(* repeat rewrite string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) + +(* End getArgs. *) (********************************************************************************) @@ -541,21 +541,21 @@ Definition getFreshNum_core_spec (Φ:u64 → iPropO Σ): iPropO Σ := Global Instance getFreshNum_core_MonotonicPred : MonotonicPred (getFreshNum_core_spec). Proof. apply _. Qed. -Definition put_core_spec (args:putArgs.t) (Φ:unit → iPropO Σ): iPropO Σ := +Definition put_core_spec (args:put.C) (Φ:unit → iPropO Σ): iPropO Σ := (* TUTORIAL: write a more useful spec *) Φ (). Global Instance put_core_MonotonicPred args : MonotonicPred (put_core_spec args). Proof. apply _. Qed. -Definition conditionalPut_core_spec (args:conditionalPutArgs.t) (Φ:string → iPropO Σ): iPropO Σ := +Definition conditionalPut_core_spec (args:conditionalPut.C) (Φ:string → iPropO Σ): iPropO Σ := (* TUTORIAL: write a more useful spec *) (∀ status, Φ status)%I. Global Instance conditionalPut_core_MonotonicPred args : MonotonicPred (conditionalPut_core_spec args). Proof. apply _. Qed. -Definition get_core_spec (args:getArgs.t) (Φ:string → iPropO Σ): iPropO Σ := +Definition get_core_spec (args:get.C) (Φ:string → iPropO Σ): iPropO Σ := (* TUTORIAL: write a more useful spec *) (∀ ret, Φ ret)%I. @@ -609,11 +609,11 @@ Proof. iApply "Hspec". Qed. -Lemma wp_Server__put (s:loc) args_ptr (args:putArgs.t) Ψ : +Lemma wp_Server__put (s:loc) args_ptr (args:put.C) Ψ : {{{ "#Hsrv" ∷ is_Server s ∗ "Hspec" ∷ put_core_spec args Ψ ∗ - "Hargs" ∷ putArgs.own args_ptr args + "Hargs" ∷ put.own args_ptr args (DfracOwn 1) }}} Server__put #s #args_ptr {{{ @@ -627,9 +627,6 @@ Proof. wp_apply (wp_Mutex__Lock with "[$]") as "[Hlocked Hown]"; iNamed "Hown". iNamed "Hargs". wp_auto. - - wp_loadField. - wp_apply (wp_MapGet with "HlastRepliesM") as (??) "[%HlastReply HlastRepliesM]". wp_if_destruct; wp_auto. { (* case: this is a duplicate request *) @@ -654,11 +651,11 @@ Proof. iApply ("HΦ" with "Hspec"). Qed. -Lemma wp_Server__conditionalPut (s:loc) args_ptr (args:conditionalPutArgs.t) Ψ : +Lemma wp_Server__conditionalPut (s:loc) args_ptr (args:conditionalPut.C) Ψ : {{{ "#Hsrv" ∷ is_Server s ∗ "Hspec" ∷ conditionalPut_core_spec args Ψ ∗ - "Hargs" ∷ conditionalPutArgs.own args_ptr args + "Hargs" ∷ conditionalPut.own args_ptr args (DfracOwn 1) }}} Server__conditionalPut #s #args_ptr {{{ r, RET #(str r); Ψ r }}} @@ -714,11 +711,11 @@ Proof. iApply ("HΦ" with "Hspec"). Qed. -Lemma wp_Server__get (s:loc) args_ptr (args:getArgs.t) Ψ : +Lemma wp_Server__get (s:loc) args_ptr (args:get.C) Ψ : {{{ "#Hsrv" ∷ is_Server s ∗ "Hspec" ∷ get_core_spec args Ψ ∗ - "Hargs" ∷ getArgs.own args_ptr args + "Hargs" ∷ get.own args_ptr args (DfracOwn 1) }}} Server__get #s #args_ptr {{{ @@ -813,7 +810,7 @@ Defined. Program Definition put_spec := λ (enc_args:list u8), λne (Φ : list u8 -d> iPropO Σ) , (∃ args, - "%Henc" ∷ ⌜putArgs.encodes enc_args args⌝ ∗ + "%Henc" ∷ ⌜put.has_encoding enc_args args⌝ ∗ put_core_spec args (λ _, ∀ enc_reply, Φ enc_reply) )%I . @@ -824,7 +821,7 @@ Defined. Program Definition conditionalPut_spec := λ (enc_args:list u8), λne (Φ : list u8 -d> iPropO Σ) , (∃ args, - "%Henc" ∷ ⌜conditionalPutArgs.encodes enc_args args⌝ ∗ + "%Henc" ∷ ⌜conditionalPut.has_encoding enc_args args⌝ ∗ conditionalPut_core_spec args (λ rep, Φ (string_to_bytes rep)) )%I . @@ -835,7 +832,7 @@ Defined. Program Definition get_spec := λ (enc_args:list u8), λne (Φ : list u8 -d> iPropO Σ) , (∃ args, - "%Henc" ∷ ⌜getArgs.encodes enc_args args⌝ ∗ + "%Henc" ∷ ⌜get.has_encoding enc_args args⌝ ∗ get_core_spec args (λ rep, Φ (string_to_bytes rep)) )%I . @@ -924,9 +921,9 @@ Proof. iIntros (?????) "!# (Hreq_sl & Hrep & Hspec) HΦ". wp_pures. iDestruct "Hspec" as (?) "[%Henc Hspec]". - wp_apply (getArgs.wp_decode with "[$Hreq_sl]"). - { by iPureIntro. } - iIntros (?) "[Hargs Hreq_sl]". + wp_apply (get.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. by iPureIntro. } + iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__get with "[$]"). iIntros (?) "HΨ". wp_pures. wp_apply wp_StringToBytes. @@ -943,9 +940,9 @@ Proof. iIntros (?????) "!# (Hreq_sl & Hrep & Hspec) HΦ". wp_pures. iDestruct "Hspec" as (?) "[%Henc Hspec]". - wp_apply (conditionalPutArgs.wp_decode with "[$Hreq_sl]"). - { done. } - iIntros (?) "[Hargs Hreq_sl]". + wp_apply (conditionalPut.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. done. } + iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__conditionalPut with "[$]"). iIntros (?) "HΨ". wp_apply wp_StringToBytes. @@ -962,9 +959,9 @@ Proof. iIntros (?????) "!# (Hreq_sl & Hrep & Hspec) HΦ". wp_pures. iDestruct "Hspec" as (?) "[%Henc Hspec]". - wp_apply (putArgs.wp_decode with "[$Hreq_sl]"). - { done. } - iIntros (?) "Hargs". + wp_apply (put.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. done. } + iIntros (??) "Hargs". iDestruct "Hargs" as "[Hargs _]". wp_apply (wp_Server__put with "[$Hsrv $Hargs Hspec //]"). iIntros "HΨ". wp_pures. iApply "HΦ"; iFrame. @@ -1091,7 +1088,7 @@ Qed. Lemma wp_Client__putRpc Post cl args args_ptr : {{{ - "Hargs" ∷ putArgs.own args_ptr args ∗ + "Hargs" ∷ put.own args_ptr args DfracDiscarded ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ put_core_spec args Post }}} @@ -1109,8 +1106,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (putArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply wp_NewSlice. iIntros (s) "Hs". + wp_apply (put.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1149,7 +1147,7 @@ Qed. Lemma wp_Client__conditionalPutRpc Post cl args args_ptr : {{{ - "Hargs" ∷ conditionalPutArgs.own args_ptr args ∗ + "Hargs" ∷ conditionalPut.own args_ptr args DfracDiscarded ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ conditionalPut_core_spec args Post }}} @@ -1167,8 +1165,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (conditionalPutArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply wp_NewSlice. iIntros (s) "Hs". + wp_apply (conditionalPut.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1212,7 +1211,7 @@ Qed. Lemma wp_Client__getRpc Post cl args args_ptr : {{{ - "Hargs" ∷ getArgs.own args_ptr args ∗ + "Hargs" ∷ get.own args_ptr args DfracDiscarded ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ get_core_spec args Post }}} @@ -1230,8 +1229,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (getArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply wp_NewSlice. iIntros (s) "Hs". + wp_apply (get.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1343,8 +1343,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__putRpc (λ _, True)%I with "[Hcl opId key val]"). - { instantiate (2:=putArgs.mk _ _ _). iFrame "∗#". done. } + wp_apply (wp_Client__putRpc (λ _, True)%I with "[Hcl OpId Key Val]"). + { instantiate (2:=put.mkC _ _ _). iFrame "∗#". done. } iClear "Hpost". iIntros (err) "Hpost". wp_pures. diff --git a/src/program_proof/tutorial/kvservice/put_proof.v b/src/program_proof/tutorial/kvservice/put_proof.v index eee039486..f3fd8fbe5 100644 --- a/src/program_proof/tutorial/kvservice/put_proof.v +++ b/src/program_proof/tutorial/kvservice/put_proof.v @@ -64,10 +64,15 @@ Proof. wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_val_enc]"). iIntros (?) "[Hsl _]". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_key_sz. + rewrite Hargs_val_sz. + rewrite ?w64_to_nat_id. exact. Qed. Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): From 137f830dd04087014d501be8db8ca9f31927c3ff Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 12 Nov 2024 22:20:41 -0600 Subject: [PATCH 08/25] Add Matt Schwennesen to email list --- .github/commit-emails.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/commit-emails.toml b/.github/commit-emails.toml index 8b9c53755..5410d6976 100644 --- a/.github/commit-emails.toml +++ b/.github/commit-emails.toml @@ -1,2 +1,2 @@ # commit-emails.xyz config -to = "chajed@wisc.edu,kaashoek@mit.edu,nickolai@csail.mit.edu,jt4767@nyu.edu,sanjit.bhat@gmail.com,upamanyu@mit.edu" +to = "chajed@wisc.edu,kaashoek@mit.edu,nickolai@csail.mit.edu,jt4767@nyu.edu,sanjit.bhat@gmail.com,upamanyu@mit.edu,schwennesen@cs.wisc.edu" From f6d68b1c193c101a9324aee9f5abcbbd73c53fb9 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Wed, 13 Nov 2024 17:12:07 -0600 Subject: [PATCH 09/25] finish integrating kvservice/proof.v --- flake.nix | 8 +++--- .../tutorial/kvservice/conditionalput_proof.v | 22 ++++++++------- .../tutorial/kvservice/get_proof.v | 18 ++++++------ src/program_proof/tutorial/kvservice/proof.v | 22 +++++++-------- .../tutorial/kvservice/put_proof.v | 20 +++++++------ .../tutorial/lockservice/lockrequest_proof.v | 18 ++++++------ .../objectstore/chunk/writechunk_proof.v | 28 +++++++++++-------- .../objectstore/dir/chunkhandle_proof.v | 24 ++++++++++------ .../objectstore/dir/finishwrite_proof.v | 24 ++++++++++------ .../objectstore/dir/recordchunk_proof.v | 28 +++++++++++-------- 10 files changed, 122 insertions(+), 90 deletions(-) diff --git a/flake.nix b/flake.nix index 20ec4a617..d0d093739 100644 --- a/flake.nix +++ b/flake.nix @@ -17,8 +17,8 @@ src = pkgs.fetchFromGitHub { owner = "mjschwenne"; repo = "grackle"; - rev = "ee753e57e3ad574d7d3f76f7de97af8817ac184c"; - sha256 = "0j532jnk52sfk36spkl7knd6ryqwg19ih5sg6pb9f2qy9lsyaw9g"; + rev = "50fb62a4d9363e09c25e997b452eac4af844b5cd"; + sha256 = "16vgpxdkg2686r0m2dqlxm5czxgf07j0myxixsqc84k1z90kivy6"; }; vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; checkPhase = false; @@ -28,8 +28,8 @@ src = pkgs.fetchFromGitHub { owner = "goose-lang"; repo = "goose"; - rev = "585abc3cfef50dd466e112d7c535dbdfccd3c0ca"; - sha256 = "sha256-M4zaZ1DdecYXeDugrL+TV7HWPMLuj1P25G6mf+fgljg="; + rev = "8352f2a82040a814b60e0dd9ac75f09cec3dd619"; + sha256 = "0as9cw8v6bxwv2100db63nk8h2mk3330c8kmdlk3kjzlkvy1bdwf"; }; vendorHash = "sha256-HCJ8v3TSv4UrkOsRuENWVz5Z7zQ1UsOygx0Mo7MELzY="; }; diff --git a/src/program_proof/tutorial/kvservice/conditionalput_proof.v b/src/program_proof/tutorial/kvservice/conditionalput_proof.v index 039abaa07..f89991ce2 100644 --- a/src/program_proof/tutorial/kvservice/conditionalput_proof.v +++ b/src/program_proof/tutorial/kvservice/conditionalput_proof.v @@ -23,21 +23,22 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := (u64_le $ length $ string_to_bytes args.(expectedVal)) ++ string_to_bytes args.(expectedVal) ++ (u64_le $ length $ string_to_bytes args.(newVal)) ++ string_to_bytes args.(newVal). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_opId" ∷ args_ptr ↦[conditionalput_gk.S :: "OpId"]{q} #args.(opId) ∗ - "Hargs_key" ∷ args_ptr ↦[conditionalput_gk.S :: "Key"]{q} #(str args.(key)) ∗ - "Hargs_expectedVal" ∷ args_ptr ↦[conditionalput_gk.S :: "ExpectedVal"]{q} #(str args.(expectedVal)) ∗ - "Hargs_newVal" ∷ args_ptr ↦[conditionalput_gk.S :: "NewVal"]{q} #(str args.(newVal)). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[conditionalput_gk.S :: "OpId"]{dq} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[conditionalput_gk.S :: "Key"]{dq} #(str args.(key)) ∗ + "Hargs_expectedVal" ∷ args_ptr ↦[conditionalput_gk.S :: "ExpectedVal"]{dq} #(str args.(expectedVal)) ∗ + "Hargs_newVal" ∷ args_ptr ↦[conditionalput_gk.S :: "NewVal"]{dq} #(str args.(newVal)). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} conditionalput_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -86,17 +87,18 @@ Proof. rewrite Hargs_expectedVal_sz. rewrite Hargs_newVal_sz. rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} conditionalput_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/kvservice/get_proof.v b/src/program_proof/tutorial/kvservice/get_proof.v index 63fc7a810..e91bd7cf0 100644 --- a/src/program_proof/tutorial/kvservice/get_proof.v +++ b/src/program_proof/tutorial/kvservice/get_proof.v @@ -19,19 +19,20 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := encoded = (u64_le args.(opId)) ++ (u64_le $ length $ string_to_bytes args.(key)) ++ string_to_bytes args.(key). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_opId" ∷ args_ptr ↦[get_gk.S :: "OpId"]{q} #args.(opId) ∗ - "Hargs_key" ∷ args_ptr ↦[get_gk.S :: "Key"]{q} #(str args.(key)). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[get_gk.S :: "OpId"]{dq} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[get_gk.S :: "Key"]{dq} #(str args.(key)). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} get_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -60,17 +61,18 @@ Proof. rewrite ?string_bytes_length. rewrite Hargs_key_sz. rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} get_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/kvservice/proof.v b/src/program_proof/tutorial/kvservice/proof.v index ffad44ba9..f1523ceaa 100644 --- a/src/program_proof/tutorial/kvservice/proof.v +++ b/src/program_proof/tutorial/kvservice/proof.v @@ -1086,9 +1086,9 @@ Proof. } Qed. -Lemma wp_Client__putRpc Post cl args args_ptr : +Lemma wp_Client__putRpc Post cl args args_ptr: {{{ - "Hargs" ∷ put.own args_ptr args DfracDiscarded ∗ + "Hargs" ∷ put.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ put_core_spec args Post }}} @@ -1108,7 +1108,7 @@ Proof. wp_pures. wp_apply wp_NewSlice. iIntros (s) "Hs". wp_apply (put.wp_Encode with "[$]"). - iIntros (??) "(%Henc & Hreq_sl)". + iIntros (??) "(%Henc & Hargs_own & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1147,7 +1147,7 @@ Qed. Lemma wp_Client__conditionalPutRpc Post cl args args_ptr : {{{ - "Hargs" ∷ conditionalPut.own args_ptr args DfracDiscarded ∗ + "Hargs" ∷ conditionalPut.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ conditionalPut_core_spec args Post }}} @@ -1167,7 +1167,7 @@ Proof. wp_pures. wp_apply wp_NewSlice. iIntros (s) "Hs". wp_apply (conditionalPut.wp_Encode with "[$]"). - iIntros (??) "(%Henc & Hreq_sl)". + iIntros (??) "(%Henc & Hargs_own & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1211,7 +1211,7 @@ Qed. Lemma wp_Client__getRpc Post cl args args_ptr : {{{ - "Hargs" ∷ get.own args_ptr args DfracDiscarded ∗ + "Hargs" ∷ get.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl ∗ "#Hspec" ∷ □ get_core_spec args Post }}} @@ -1231,7 +1231,7 @@ Proof. wp_pures. wp_apply wp_NewSlice. iIntros (s) "Hs". wp_apply (get.wp_Encode with "[$]"). - iIntros (??) "(%Henc & Hreq_sl)". + iIntros (??) "(%Henc & Hargs_own & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1423,8 +1423,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__conditionalPutRpc (λ _, True)%I with "[Hcl opId key expectedVal newVal]"). - { instantiate (2:=conditionalPutArgs.mk _ _ _ _). iFrame "∗#". done. } + wp_apply (wp_Client__conditionalPutRpc (λ _, True)%I with "[Hcl OpId Key ExpectedVal NewVal]"). + { instantiate (2:=conditionalPut.mkC _ _ _ _). iFrame "∗#". done. } iClear "Hpost". iIntros (ret err) "Hpost". wp_pures. @@ -1506,8 +1506,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__getRpc (λ _, True)%I with "[Hcl opId key]"). - { instantiate (2:=getArgs.mk _ _). iFrame "∗#". done. } + wp_apply (wp_Client__getRpc (λ _, True)%I with "[Hcl OpId Key]"). + { instantiate (2:=get.mkC _ _). iFrame "∗#". done. } iClear "Hpost". iIntros (ret err) "Hpost". wp_pures. diff --git a/src/program_proof/tutorial/kvservice/put_proof.v b/src/program_proof/tutorial/kvservice/put_proof.v index f3fd8fbe5..802812561 100644 --- a/src/program_proof/tutorial/kvservice/put_proof.v +++ b/src/program_proof/tutorial/kvservice/put_proof.v @@ -21,20 +21,21 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := (u64_le $ length $ string_to_bytes args.(key)) ++ string_to_bytes args.(key) ++ (u64_le $ length $ string_to_bytes args.(val)) ++ string_to_bytes args.(val). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_opId" ∷ args_ptr ↦[put_gk.S :: "OpId"]{q} #args.(opId) ∗ - "Hargs_key" ∷ args_ptr ↦[put_gk.S :: "Key"]{q} #(str args.(key)) ∗ - "Hargs_val" ∷ args_ptr ↦[put_gk.S :: "Val"]{q} #(str args.(val)). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_opId" ∷ args_ptr ↦[put_gk.S :: "OpId"]{dq} #args.(opId) ∗ + "Hargs_key" ∷ args_ptr ↦[put_gk.S :: "Key"]{dq} #(str args.(key)) ∗ + "Hargs_val" ∷ args_ptr ↦[put_gk.S :: "Val"]{dq} #(str args.(val)). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} put_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -73,17 +74,18 @@ Proof. rewrite Hargs_key_sz. rewrite Hargs_val_sz. rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} put_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/lockservice/lockrequest_proof.v b/src/program_proof/tutorial/lockservice/lockrequest_proof.v index 8c071bf3a..69c712b0a 100644 --- a/src/program_proof/tutorial/lockservice/lockrequest_proof.v +++ b/src/program_proof/tutorial/lockservice/lockrequest_proof.v @@ -17,18 +17,19 @@ Record C := Definition has_encoding (encoded:list u8) (args:C) : Prop := encoded = (u64_le args.(id)). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_id" ∷ args_ptr ↦[lockrequest_gk.S :: "Id"]{q} #args.(id). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_id" ∷ args_ptr ↦[lockrequest_gk.S :: "Id"]{dq} #args.(id). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} lockrequest_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -40,21 +41,22 @@ Proof. wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + done. Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} lockrequest_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v b/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v index 857fa7d7d..d9c18c540 100644 --- a/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v +++ b/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v @@ -21,22 +21,23 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := (u64_le $ length $ args.(chunk)) ++ args.(chunk) ++ (u64_le args.(index)). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ :=(chunk_sl : Slice.t) - "Hargs_writeId" ∷ args_ptr ↦[writechunk_gk.S :: "WriteId"]{q} #args.(writeId) ∗ - "Hargs_chunk" ∷ args_ptr ↦[writechunk_gk.S :: "Chunk"]{q} (slice_val chunk_sl) ∗ - "Hargs_chunk_sl" ∷ own_slice_small chunk_sl byteT q args.(chunk) +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ :=(chunk_sl : Slice.t) + "Hargs_writeId" ∷ args_ptr ↦[writechunk_gk.S :: "WriteId"]{dq} #args.(writeId) ∗ + "Hargs_chunk" ∷ args_ptr ↦[writechunk_gk.S :: "Chunk"]{dq} (slice_val chunk_sl) ∗ + "Hargs_chunk_sl" ∷ own_slice_small chunk_sl byteT dq args.(chunk) ∗ - "Hargs_index" ∷ args_ptr ↦[writechunk_gk.S :: "Index"]{q} #args.(index). + "Hargs_index" ∷ args_ptr ↦[writechunk_gk.S :: "Index"]{dq} #args.(index). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} writechunk_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -59,21 +60,26 @@ Proof. wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_chunk_sz. + rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} writechunk_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v b/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v index 110f03755..da190a65e 100644 --- a/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v +++ b/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v @@ -19,19 +19,20 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := encoded = (u64_le args.(addr)) ++ (u64_le $ length $ string_to_bytes args.(contentHash)) ++ string_to_bytes args.(contentHash). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_addr" ∷ args_ptr ↦[chunkhandle_gk.S :: "Addr"]{q} #args.(addr) ∗ - "Hargs_contentHash" ∷ args_ptr ↦[chunkhandle_gk.S :: "ContentHash"]{q} #(str args.(contentHash)). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_addr" ∷ args_ptr ↦[chunkhandle_gk.S :: "Addr"]{dq} #args.(addr) ∗ + "Hargs_contentHash" ∷ args_ptr ↦[chunkhandle_gk.S :: "ContentHash"]{dq} #(str args.(contentHash)). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} chunkhandle_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -52,21 +53,26 @@ Proof. wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_contentHash_enc]"). iIntros (?) "[Hsl _]". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_contentHash_sz. + rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} chunkhandle_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v b/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v index ec37e9af3..5cb88a872 100644 --- a/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v +++ b/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v @@ -19,19 +19,20 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := encoded = (u64_le args.(writeId)) ++ (u64_le $ length $ string_to_bytes args.(keyname)) ++ string_to_bytes args.(keyname). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_writeId" ∷ args_ptr ↦[finishwrite_gk.S :: "WriteId"]{q} #args.(writeId) ∗ - "Hargs_keyname" ∷ args_ptr ↦[finishwrite_gk.S :: "Keyname"]{q} #(str args.(keyname)). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_writeId" ∷ args_ptr ↦[finishwrite_gk.S :: "WriteId"]{dq} #args.(writeId) ∗ + "Hargs_keyname" ∷ args_ptr ↦[finishwrite_gk.S :: "Keyname"]{dq} #(str args.(keyname)). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} finishwrite_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -52,21 +53,26 @@ Proof. wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_keyname_enc]"). iIntros (?) "[Hsl _]". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_keyname_sz. + rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} finishwrite_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. diff --git a/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v b/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v index 404dd62e5..d67f2bee3 100644 --- a/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v +++ b/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v @@ -23,21 +23,22 @@ Definition has_encoding (encoded:list u8) (args:C) : Prop := (u64_le $ length $ string_to_bytes args.(contentHash)) ++ string_to_bytes args.(contentHash) ++ (u64_le args.(index)). -Definition own (args_ptr:loc) (args:C) (q:dfrac) : iProp Σ := - "Hargs_writeId" ∷ args_ptr ↦[recordchunk_gk.S :: "WriteId"]{q} #args.(writeId) ∗ - "Hargs_server" ∷ args_ptr ↦[recordchunk_gk.S :: "Server"]{q} #args.(server) ∗ - "Hargs_contentHash" ∷ args_ptr ↦[recordchunk_gk.S :: "ContentHash"]{q} #(str args.(contentHash)) ∗ - "Hargs_index" ∷ args_ptr ↦[recordchunk_gk.S :: "Index"]{q} #args.(index). +Definition own (args_ptr: loc) (args: C) (dq: dfrac) : iProp Σ := + "Hargs_writeId" ∷ args_ptr ↦[recordchunk_gk.S :: "WriteId"]{dq} #args.(writeId) ∗ + "Hargs_server" ∷ args_ptr ↦[recordchunk_gk.S :: "Server"]{dq} #args.(server) ∗ + "Hargs_contentHash" ∷ args_ptr ↦[recordchunk_gk.S :: "ContentHash"]{dq} #(str args.(contentHash)) ∗ + "Hargs_index" ∷ args_ptr ↦[recordchunk_gk.S :: "Index"]{dq} #args.(index). -Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) : +Lemma wp_Encode (args_ptr:loc) (args:C) (pre_sl:Slice.t) (prefix:list u8) (dq: dfrac): {{{ - own args_ptr args (DfracDiscarded) ∗ + own args_ptr args dq ∗ own_slice pre_sl byteT (DfracOwn 1) prefix }}} recordchunk_gk.Marshal #args_ptr (slice_val pre_sl) {{{ enc enc_sl, RET (slice_val enc_sl); ⌜has_encoding enc args⌝ ∗ + own args_ptr args dq ∗ own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) }}}. @@ -62,21 +63,26 @@ Proof. wp_loadField. wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. + wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. iFrame. iPureIntro. - done. + unfold has_encoding. + rewrite ?string_bytes_length. + rewrite Hargs_contentHash_sz. + rewrite ?w64_to_nat_id. exact. + Qed. -Lemma wp_Decode enc enc_sl (args:C) (suffix:list u8) (q:dfrac): +Lemma wp_Decode enc enc_sl (args: C) (suffix: list u8) (dq: dfrac): {{{ ⌜has_encoding enc args⌝ ∗ - own_slice_small enc_sl byteT q (enc ++ suffix) + own_slice_small enc_sl byteT dq (enc ++ suffix) }}} recordchunk_gk.Unmarshal (slice_val enc_sl) {{{ args_ptr suff_sl, RET (#args_ptr, suff_sl); own args_ptr args (DfracOwn 1) ∗ - own_slice_small suff_sl byteT q suffix + own_slice_small suff_sl byteT dq suffix }}}. Proof. From c63b3a955cd6d3f638422788c7259063f0c05928 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Mon, 25 Nov 2024 14:48:03 -0600 Subject: [PATCH 10/25] begin grackle integration of tutorial/kvservice/full_proof.v --- .../tutorial/kvservice/full_proof.v | 1151 +++++++++-------- 1 file changed, 579 insertions(+), 572 deletions(-) diff --git a/src/program_proof/tutorial/kvservice/full_proof.v b/src/program_proof/tutorial/kvservice/full_proof.v index d476d9e52..e07f28b23 100644 --- a/src/program_proof/tutorial/kvservice/full_proof.v +++ b/src/program_proof/tutorial/kvservice/full_proof.v @@ -8,525 +8,529 @@ From Perennial.program_logic Require Import atomic_fupd. From RecordUpdate Require Import RecordSet. Import RecordSetNotations. -(********************************************************************************) - -Module putArgs. -Record t := - mk { - opId: u64 ; - key: string ; - val: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ - string_to_bytes a.(key) ++ string_to_bytes a.(val) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ - "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodePutArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (sl) "Hsl". - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - - wp_pures. - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "[$]"). - iIntros (?) "Hsl". - rewrite replicate_0 /=. - wp_store. - - wp_loadField. - wp_apply wp_StringToBytes. - iIntros (key_sl) "Hkey_sl". - wp_pures. - - wp_apply wp_slice_len. - iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl Hkey_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hval_sl". - iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". - wp_load. - wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). - iIntros (?) "[Hsl Hval_sl]". - wp_store. - - wp_load. - iApply "HΦ". - iFrame. - iPureIntro. - unfold encodes. - repeat rewrite -assoc. - rewrite Hsz. - repeat f_equal. - word. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodePutArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - - wp_pures. - wp_load. - rewrite Henc; clear dependent enc_args. - wp_apply (wp_ReadInt with "[$]"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - wp_load. - wp_apply (wp_ReadInt with "[$]"). - iIntros (?) "Hsl". - wp_pures. - iDestruct (own_slice_small_sz with "Hsl") as %Hsz. - wp_apply (wp_ReadBytes with "[$]"). - { rewrite length_app in Hsz. word. } - iIntros (??) "[Hkey Hval]". - wp_pures. - wp_apply (wp_StringFromBytes with "[$Hkey]"). - iIntros "Hkey". - wp_storeField. - wp_apply (wp_StringFromBytes with "[$Hval]"). - iIntros "Hval". - wp_storeField. - iModIntro. - iApply "HΦ". - repeat rewrite string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. -End putArgs. - -Module conditionalPutArgs. -Record t := - mk { - opId: u64 ; - key: string ; - expectedVal: string ; - newVal: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ - (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ - "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ - "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodeConditionalPutArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (sl) "Hsl". - wp_apply wp_ref_to. - { done. } - iIntros (e) "He". - wp_pures. - - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "[$]"). - iIntros (?) "Hsl". - rewrite replicate_0 /=. - wp_store. - - wp_loadField. - wp_apply wp_StringToBytes. - iIntros (key_sl) "Hkey_sl". - wp_pures. - wp_apply wp_slice_len. - iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl Hkey_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hexpect_sl". - iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". - wp_pures. - - wp_apply wp_slice_len. - iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. - wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_store. - - wp_load. - wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). - iIntros (?) "[Hsl Hexpect_sl]". - wp_store. - - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hval_sl". - wp_load. - iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). - iIntros (?) "[Hsl Hval_sl]". - wp_store. - - wp_load. - iApply "HΦ". - iFrame. - iPureIntro. - unfold encodes. - repeat rewrite -assoc. - rewrite Hsz. - repeat f_equal; word. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodeConditionalPutArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply wp_ref_to. - { done. } - iIntros (?) "He". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - wp_pures. - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - wp_load. - rewrite Henc. - - wp_apply (wp_ReadInt with "Hsl"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - - wp_load. - wp_apply (wp_ReadInt with "Hsl"). - iIntros (?) "Hsl". - wp_pures. - - iDestruct (own_slice_small_sz with "Hsl") as %Hsz. - wp_apply (wp_ReadBytes with "[$Hsl]"). - { rewrite length_app in Hsz. word. } - iIntros (??) "[Hkey Hsl]". - wp_pures. - wp_apply (wp_StringFromBytes with "[$Hkey]"). - iIntros "_". - wp_storeField. - - wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_pures. - - wp_apply (wp_ReadBytes with "[$Hsl]"). - { repeat rewrite length_app in Hsz. word. } - iIntros (??) "[Hexpect Hval]". - wp_pures. - - wp_apply (wp_StringFromBytes with "[$Hexpect]"). - iIntros "_". - wp_storeField. - wp_apply (wp_StringFromBytes with "[$Hval]"). - iIntros "_". - wp_storeField. - iModIntro. iApply "HΦ". - iFrame. - rewrite ?string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. -End conditionalPutArgs. - -Module getArgs. -Record t := - mk { - opId: u64 ; - key: string ; - }. - -Definition encodes (x:list u8) (a:t) : Prop := - x = u64_le a.(opId) ++ string_to_bytes a.(key) -. - -Section local_defs. -Context `{!heapGS Σ}. -Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := - "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ - "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) -. - -Lemma wp_encode args_ptr args : - {{{ - own args_ptr args - }}} - encodeGetArgs #args_ptr - {{{ - (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ - ⌜encodes enc_args args⌝ ∗ - own_slice sl byteT (DfracOwn 1) enc_args - }}} -. -Proof. - iIntros (Φ) "Hargs HΦ". - iNamed "Hargs". - wp_rec. - wp_apply wp_NewSlice. - iIntros (?) "Hsl". - wp_apply (wp_ref_to). - { done. } - iIntros (?) "He". - wp_pures. - wp_loadField. - wp_load. - wp_apply (wp_WriteInt with "Hsl"). - iIntros (?) "Hsl". - wp_store. - wp_loadField. - wp_apply (wp_StringToBytes). - iIntros (?) "Hkey_sl". - wp_load. - iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". - wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). - iIntros (?) "[Hsl _]". - wp_store. - wp_load. - iModIntro. iApply "HΦ". - iFrame. - iPureIntro. done. -Qed. - -Lemma wp_decode sl enc_args args q : - {{{ - "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ - "Hsl" ∷ own_slice_small sl byteT q enc_args - }}} - decodeGetArgs (slice_val sl) - {{{ - (args_ptr:loc), RET #args_ptr; own args_ptr args - }}} -. -Proof. - iIntros (Φ) "Hpre HΦ". - iNamed "Hpre". - wp_rec. - wp_apply (wp_ref_to). - { done. } - iIntros (?) "He". - wp_pures. - wp_apply (wp_ref_of_zero). - { done. } - iIntros (?) "HkeyBytes". - wp_pures. - wp_apply wp_allocStruct. - { repeat econstructor. } - iIntros (args_ptr) "Hargs". - iDestruct (struct_fields_split with "Hargs") as "HH". - iNamed "HH". - wp_pures. - wp_load. - rewrite Henc. - wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". - wp_pures. - wp_storeField. - wp_store. - - wp_load. - wp_apply (wp_StringFromBytes with "[$Hsl]"). - iIntros "_". - wp_storeField. - iModIntro. - iApply "HΦ". - iFrame. - rewrite string_to_bytes_to_string. - iFrame. -Qed. - -End local_defs. - -End getArgs. +From Perennial.program_proof.tutorial.kvservice Require Import get_proof. +From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof. +From Perennial.program_proof.tutorial.kvservice Require Import put_proof. (********************************************************************************) -Section marshal_proof. -Context `{!heapGS Σ}. - -(* TODO: copied this naming convention from "u64_le". What does le actually - mean? *) -Definition bool_le (b:bool) : list u8 := if b then [W8 1] else [W8 0]. - -Lemma wp_EncodeBool (b:bool) : - {{{ True }}} - EncodeBool #b - {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (bool_le b) }}} -. -Proof. - iIntros (Φ) "_ HΦ". - wp_rec. wp_if_destruct. - { - wp_apply wp_NewSlice. iIntros (?) "?". - wp_apply (wp_SliceAppend with "[$]"). - iIntros (?) "?". - by iApply "HΦ". - } - { - wp_apply wp_NewSlice. iIntros (?) "?". - wp_apply (wp_SliceAppend with "[$]"). - iIntros (?) "?". - by iApply "HΦ". - } -Qed. - -Lemma wp_DecodeBool sl b q : - {{{ own_slice_small sl byteT q (bool_le b) }}} - DecodeBool (slice_val sl) - {{{ RET #b; True }}} -. -Proof. - iIntros (?) "Hsl HΦ". - wp_rec. - unfold bool_le. - destruct b. - { - wp_apply (wp_SliceGet with "[$Hsl]"). - { done. } - iIntros "_". - wp_pures. - iModIntro. by iApply "HΦ". - } - { - wp_apply (wp_SliceGet with "[$Hsl]"). - { done. } - iIntros "_". - wp_pures. - iModIntro. by iApply "HΦ". - } -Qed. - -Lemma wp_EncodeUint64 x: - {{{ True }}} - EncodeUint64 #x - {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (u64_le x) }}} -. -Proof. - iIntros (Φ) "_ HΦ". - wp_rec. - wp_apply wp_NewSlice. - iIntros (?) "Hsl". - wp_apply (wp_WriteInt with "Hsl"). - iIntros (?) "Hsl". - by iApply "HΦ". -Qed. +(* Module putArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* val: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ *) +(* string_to_bytes a.(key) ++ string_to_bytes a.(val) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ *) +(* "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodePutArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (sl) "Hsl". *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) + +(* wp_pures. *) +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* rewrite replicate_0 /=. *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply wp_StringToBytes. *) +(* iIntros (key_sl) "Hkey_sl". *) +(* wp_pures. *) + +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl Hkey_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hval_sl". *) +(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) +(* wp_load. *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) +(* iIntros (?) "[Hsl Hval_sl]". *) +(* wp_store. *) + +(* wp_load. *) +(* iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. *) +(* unfold encodes. *) +(* repeat rewrite -assoc. *) +(* rewrite Hsz. *) +(* repeat f_equal. *) +(* word. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodePutArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) + +(* wp_pures. *) +(* wp_load. *) +(* rewrite Henc; clear dependent enc_args. *) +(* wp_apply (wp_ReadInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) +(* wp_load. *) +(* wp_apply (wp_ReadInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) +(* wp_apply (wp_ReadBytes with "[$]"). *) +(* { rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hkey Hval]". *) +(* wp_pures. *) +(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) +(* iIntros "Hkey". *) +(* wp_storeField. *) +(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) +(* iIntros "Hval". *) +(* wp_storeField. *) +(* iModIntro. *) +(* iApply "HΦ". *) +(* repeat rewrite string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) +(* End putArgs. *) + +(* Module conditionalPutArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* expectedVal: string ; *) +(* newVal: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ *) +(* (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ *) +(* "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ *) +(* "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodeConditionalPutArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (sl) "Hsl". *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (e) "He". *) +(* wp_pures. *) + +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$]"). *) +(* iIntros (?) "Hsl". *) +(* rewrite replicate_0 /=. *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply wp_StringToBytes. *) +(* iIntros (key_sl) "Hkey_sl". *) +(* wp_pures. *) +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl Hkey_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hexpect_sl". *) +(* iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". *) +(* wp_pures. *) + +(* wp_apply wp_slice_len. *) +(* iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). *) +(* iIntros (?) "[Hsl Hexpect_sl]". *) +(* wp_store. *) + +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hval_sl". *) +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) +(* iIntros (?) "[Hsl Hval_sl]". *) +(* wp_store. *) + +(* wp_load. *) +(* iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. *) +(* unfold encodes. *) +(* repeat rewrite -assoc. *) +(* rewrite Hsz. *) +(* repeat f_equal; word. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodeConditionalPutArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply wp_ref_to. *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* wp_pures. *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) +(* wp_load. *) +(* rewrite Henc. *) + +(* wp_apply (wp_ReadInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_ReadInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) + +(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) +(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) +(* { rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hkey Hsl]". *) +(* wp_pures. *) +(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) +(* iIntros "_". *) +(* wp_storeField. *) + +(* wp_apply (wp_ReadInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) + +(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) +(* { repeat rewrite length_app in Hsz. word. } *) +(* iIntros (??) "[Hexpect Hval]". *) +(* wp_pures. *) + +(* wp_apply (wp_StringFromBytes with "[$Hexpect]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* iModIntro. iApply "HΦ". *) +(* iFrame. *) +(* rewrite ?string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) +(* End conditionalPutArgs. *) + +(* Module getArgs. *) +(* Record t := *) +(* mk { *) +(* opId: u64 ; *) +(* key: string ; *) +(* }. *) + +(* Definition encodes (x:list u8) (a:t) : Prop := *) +(* x = u64_le a.(opId) ++ string_to_bytes a.(key) *) +(* . *) + +(* Section local_defs. *) +(* Context `{!heapGS Σ}. *) +(* Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := *) +(* "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ *) +(* "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) *) +(* . *) + +(* Lemma wp_encode args_ptr args : *) +(* {{{ *) +(* own args_ptr args *) +(* }}} *) +(* encodeGetArgs #args_ptr *) +(* {{{ *) +(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) +(* ⌜encodes enc_args args⌝ ∗ *) +(* own_slice sl byteT (DfracOwn 1) enc_args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hargs HΦ". *) +(* iNamed "Hargs". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (?) "Hsl". *) +(* wp_apply (wp_ref_to). *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_loadField. *) +(* wp_load. *) +(* wp_apply (wp_WriteInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_store. *) +(* wp_loadField. *) +(* wp_apply (wp_StringToBytes). *) +(* iIntros (?) "Hkey_sl". *) +(* wp_load. *) +(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) +(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) +(* iIntros (?) "[Hsl _]". *) +(* wp_store. *) +(* wp_load. *) +(* iModIntro. iApply "HΦ". *) +(* iFrame. *) +(* iPureIntro. done. *) +(* Qed. *) + +(* Lemma wp_decode sl enc_args args q : *) +(* {{{ *) +(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) +(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) +(* }}} *) +(* decodeGetArgs (slice_val sl) *) +(* {{{ *) +(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) +(* }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hpre HΦ". *) +(* iNamed "Hpre". *) +(* wp_rec. *) +(* wp_apply (wp_ref_to). *) +(* { done. } *) +(* iIntros (?) "He". *) +(* wp_pures. *) +(* wp_apply (wp_ref_of_zero). *) +(* { done. } *) +(* iIntros (?) "HkeyBytes". *) +(* wp_pures. *) +(* wp_apply wp_allocStruct. *) +(* { repeat econstructor. } *) +(* iIntros (args_ptr) "Hargs". *) +(* iDestruct (struct_fields_split with "Hargs") as "HH". *) +(* iNamed "HH". *) +(* wp_pures. *) +(* wp_load. *) +(* rewrite Henc. *) +(* wp_apply (wp_ReadInt with "[$Hsl]"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* wp_storeField. *) +(* wp_store. *) + +(* wp_load. *) +(* wp_apply (wp_StringFromBytes with "[$Hsl]"). *) +(* iIntros "_". *) +(* wp_storeField. *) +(* iModIntro. *) +(* iApply "HΦ". *) +(* iFrame. *) +(* rewrite string_to_bytes_to_string. *) +(* iFrame. *) +(* Qed. *) + +(* End local_defs. *) + +(* End getArgs. *) -Lemma wp_DecodeUint64 sl x q : - {{{ own_slice_small sl byteT q (u64_le x) }}} - DecodeUint64 (slice_val sl) - {{{ RET #x; True }}} -. -Proof. - iIntros (Φ) "Hsl HΦ". - wp_rec. - wp_apply (wp_ReadInt with "Hsl"). - iIntros (?) "Hsl". - wp_pures. - by iApply "HΦ". -Qed. +(********************************************************************************) -End marshal_proof. +(* Section marshal_proof. *) +(* Context `{!heapGS Σ}. *) + +(* (* TODO: copied this naming convention from "u64_le". What does le actually *) +(* mean? *) *) +(* Definition bool_le (b:bool) : list u8 := if b then [W8 1] else [W8 0]. *) + +(* Lemma wp_EncodeBool (b:bool) : *) +(* {{{ True }}} *) +(* EncodeBool #b *) +(* {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (bool_le b) }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "_ HΦ". *) +(* wp_rec. wp_if_destruct. *) +(* { *) +(* wp_apply wp_NewSlice. iIntros (?) "?". *) +(* wp_apply (wp_SliceAppend with "[$]"). *) +(* iIntros (?) "?". *) +(* by iApply "HΦ". *) +(* } *) +(* { *) +(* wp_apply wp_NewSlice. iIntros (?) "?". *) +(* wp_apply (wp_SliceAppend with "[$]"). *) +(* iIntros (?) "?". *) +(* by iApply "HΦ". *) +(* } *) +(* Qed. *) + +(* Lemma wp_DecodeBool sl b q : *) +(* {{{ own_slice_small sl byteT q (bool_le b) }}} *) +(* DecodeBool (slice_val sl) *) +(* {{{ RET #b; True }}} *) +(* . *) +(* Proof. *) +(* iIntros (?) "Hsl HΦ". *) +(* wp_rec. *) +(* unfold bool_le. *) +(* destruct b. *) +(* { *) +(* wp_apply (wp_SliceGet with "[$Hsl]"). *) +(* { done. } *) +(* iIntros "_". *) +(* wp_pures. *) +(* iModIntro. by iApply "HΦ". *) +(* } *) +(* { *) +(* wp_apply (wp_SliceGet with "[$Hsl]"). *) +(* { done. } *) +(* iIntros "_". *) +(* wp_pures. *) +(* iModIntro. by iApply "HΦ". *) +(* } *) +(* Qed. *) + +(* Lemma wp_EncodeUint64 x: *) +(* {{{ True }}} *) +(* EncodeUint64 #x *) +(* {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (u64_le x) }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "_ HΦ". *) +(* wp_rec. *) +(* wp_apply wp_NewSlice. *) +(* iIntros (?) "Hsl". *) +(* wp_apply (wp_WriteInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* by iApply "HΦ". *) +(* Qed. *) + +(* Lemma wp_DecodeUint64 sl x q : *) +(* {{{ own_slice_small sl byteT q (u64_le x) }}} *) +(* DecodeUint64 (slice_val sl) *) +(* {{{ RET #x; True }}} *) +(* . *) +(* Proof. *) +(* iIntros (Φ) "Hsl HΦ". *) +(* wp_rec. *) +(* wp_apply (wp_ReadInt with "Hsl"). *) +(* iIntros (?) "Hsl". *) +(* wp_pures. *) +(* by iApply "HΦ". *) +(* Qed. *) + +(* End marshal_proof. *) Section escrow_library. @@ -762,42 +766,42 @@ Definition getFreshNum_core_pre : iProp Σ := Definition getFreshNum_core_post : u64 → iProp Σ := λ opId, own_unexecuted_token γ.(erpc_gn) opId. -Definition put_core_pre (args : putArgs.t) : iProp Σ := - ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(putArgs.opId) - (|={⊤∖↑reqN,∅}=> ∃ oldv, args.(putArgs.key) ↪[γ.(kv_gn)] oldv ∗ - (args.(putArgs.key) ↪[γ.(kv_gn)] args.(putArgs.val) ={∅,⊤∖↑reqN}=∗ +Definition put_core_pre (args : put.C) : iProp Σ := + ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(put.opId) + (|={⊤∖↑reqN,∅}=> ∃ oldv, args.(put.key) ↪[γ.(kv_gn)] oldv ∗ + (args.(put.key) ↪[γ.(kv_gn)] args.(put.val) ={∅,⊤∖↑reqN}=∗ Q))%I (λ _, Q). -Definition put_core_post (args : putArgs.t) : iProp Σ := - ∃ r, is_executed_witness γ.(erpc_gn) args.(putArgs.opId) ∗ - is_request_receipt γ.(erpc_gn) args.(putArgs.opId) r. +Definition put_core_post (args : put.C) : iProp Σ := + ∃ r, is_executed_witness γ.(erpc_gn) args.(put.opId) ∗ + is_request_receipt γ.(erpc_gn) args.(put.opId) r. -Definition conditionalPut_core_pre (args:conditionalPutArgs.t) : iProp Σ := - ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(conditionalPutArgs.opId) - (|={⊤∖↑reqN,∅}=> ∃ oldv, args.(conditionalPutArgs.key) ↪[γ.(kv_gn)] oldv ∗ - (args.(conditionalPutArgs.key) ↪[γ.(kv_gn)] - (if bool_decide (oldv = args.(conditionalPutArgs.expectedVal)) then - args.(conditionalPutArgs.newVal) +Definition conditionalPut_core_pre (args:conditionalPut.C) : iProp Σ := + ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(conditionalPut.opId) + (|={⊤∖↑reqN,∅}=> ∃ oldv, args.(conditionalPut.key) ↪[γ.(kv_gn)] oldv ∗ + (args.(conditionalPut.key) ↪[γ.(kv_gn)] + (if bool_decide (oldv = args.(conditionalPut.expectedVal)) then + args.(conditionalPut.newVal) else oldv) ={∅,⊤∖↑reqN}=∗ - (Q (bool_decide (oldv = args.(conditionalPutArgs.expectedVal)))))) + (Q (bool_decide (oldv = args.(conditionalPut.expectedVal)))))) (λ r, if decide (r = "ok") then Q true else Q false) . -Definition conditionalPut_core_post (args:conditionalPutArgs.t) r : iProp Σ := - is_executed_witness γ.(erpc_gn) args.(conditionalPutArgs.opId) ∗ - is_request_receipt γ.(erpc_gn) args.(conditionalPutArgs.opId) r. +Definition conditionalPut_core_post (args:conditionalPut.C) r : iProp Σ := + is_executed_witness γ.(erpc_gn) args.(conditionalPut.opId) ∗ + is_request_receipt γ.(erpc_gn) args.(conditionalPut.opId) r. -Definition get_core_pre (args:getArgs.t) : iProp Σ := - ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(getArgs.opId) - (|={⊤∖↑reqN,∅}=> ∃ v, args.(getArgs.key) ↪[γ.(kv_gn)] v ∗ - (args.(getArgs.key) ↪[γ.(kv_gn)] v ={∅,⊤∖↑reqN}=∗ +Definition get_core_pre (args:get.C) : iProp Σ := + ∃ γcl Q, is_request_inv γ.(erpc_gn) γcl args.(get.opId) + (|={⊤∖↑reqN,∅}=> ∃ v, args.(get.key) ↪[γ.(kv_gn)] v ∗ + (args.(get.key) ↪[γ.(kv_gn)] v ={∅,⊤∖↑reqN}=∗ (Q v))) Q. -Definition get_core_post (args:getArgs.t) r : iProp Σ := - is_executed_witness γ.(erpc_gn) args.(getArgs.opId) ∗ - is_request_receipt γ.(erpc_gn) args.(getArgs.opId) r. +Definition get_core_post (args:get.C) r : iProp Σ := + is_executed_witness γ.(erpc_gn) args.(get.opId) ∗ + is_request_receipt γ.(erpc_gn) args.(get.opId) r. End rpc_definitions. @@ -930,7 +934,7 @@ Proof. Qed. Lemma ghost_put_dup γ st r args : - st.(server.lastReplies) !! args.(putArgs.opId) = Some r → + st.(server.lastReplies) !! args.(put.opId) = Some r → put_core_pre γ args -∗ server.own_ghost γ st -∗ server.own_ghost γ st ∗ @@ -944,13 +948,13 @@ Proof. Qed. Lemma ghost_put γ st args : - st.(server.lastReplies) !! args.(putArgs.opId) = None → + st.(server.lastReplies) !! args.(put.opId) = None → £ 1 -∗ put_core_pre γ args -∗ server.own_ghost γ st ={⊤}=∗ server.own_ghost γ - (st <|server.lastReplies := <[args.(putArgs.opId) := ""]> st.(server.lastReplies)|> - <|server.kvs := <[args.(putArgs.key) := args.(putArgs.val)]> st.(server.kvs)|>) ∗ + (st <|server.lastReplies := <[args.(put.opId) := ""]> st.(server.lastReplies)|> + <|server.kvs := <[args.(put.key) := args.(put.val)]> st.(server.kvs)|>) ∗ put_core_post γ args. Proof. intros. @@ -967,11 +971,11 @@ Proof. iPureIntro. simpl. by f_equiv. Qed. -Lemma wp_Server__put (s:loc) γ args_ptr (args:putArgs.t) : +Lemma wp_Server__put (s:loc) γ args_ptr (args:put.C) : {{{ "#Hsrv" ∷ is_Server s γ ∗ "Hspec" ∷ put_core_pre γ args ∗ - "Hargs" ∷ putArgs.own args_ptr args + "Hargs" ∷ put.own args_ptr args (DfracOwn 1) }}} Server__put #s #args_ptr {{{ @@ -1040,7 +1044,7 @@ Proof. Qed. Lemma ghost_conditionalPut_dup γ st r args : - st.(server.lastReplies) !! args.(conditionalPutArgs.opId) = Some r → + st.(server.lastReplies) !! args.(conditionalPut.opId) = Some r → conditionalPut_core_pre γ args -∗ server.own_ghost γ st -∗ server.own_ghost γ st ∗ @@ -1056,19 +1060,19 @@ Qed. Local Definition cond_put_ok st args := (st <|server.lastReplies := - <[args.(conditionalPutArgs.opId) := "ok"]> st.(server.lastReplies)|> + <[args.(conditionalPut.opId) := "ok"]> st.(server.lastReplies)|> <|server.kvs := - <[args.(conditionalPutArgs.key) := args.(conditionalPutArgs.newVal)]> st.(server.kvs)|>) + <[args.(conditionalPut.key) := args.(conditionalPut.newVal)]> st.(server.kvs)|>) . Local Definition cond_put_not_ok st args := - (st <|server.lastReplies := <[args.(conditionalPutArgs.opId) := ""]> + (st <|server.lastReplies := <[args.(conditionalPut.opId) := ""]> st.(server.lastReplies)|>) . Lemma ghost_conditionalPut_ok γ st args : - st.(server.lastReplies) !! args.(conditionalPutArgs.opId) = None → - default "" (st.(server.kvs) !! args.(conditionalPutArgs.key)) = args.(conditionalPutArgs.expectedVal) → + st.(server.lastReplies) !! args.(conditionalPut.opId) = None → + default "" (st.(server.kvs) !! args.(conditionalPut.key)) = args.(conditionalPut.expectedVal) → £ 1 -∗ conditionalPut_core_pre γ args -∗ server.own_ghost γ st ={⊤}=∗ @@ -1097,8 +1101,8 @@ Proof. Qed. Lemma ghost_conditionalPut_not_ok γ st args : - st.(server.lastReplies) !! args.(conditionalPutArgs.opId) = None → - default "" (st.(server.kvs) !! args.(conditionalPutArgs.key)) ≠ args.(conditionalPutArgs.expectedVal) → + st.(server.lastReplies) !! args.(conditionalPut.opId) = None → + default "" (st.(server.kvs) !! args.(conditionalPut.key)) ≠ args.(conditionalPut.expectedVal) → £ 1 -∗ conditionalPut_core_pre γ args -∗ server.own_ghost γ st ={⊤}=∗ @@ -1124,11 +1128,11 @@ Proof. iFrame "∗#%" . Qed. -Lemma wp_Server__conditionalPut γ (s:loc) args_ptr (args:conditionalPutArgs.t) : +Lemma wp_Server__conditionalPut γ (s:loc) args_ptr (args:conditionalPut.C) : {{{ "#Hsrv" ∷ is_Server s γ ∗ "Hspec" ∷ conditionalPut_core_pre γ args ∗ - "Hargs" ∷ conditionalPutArgs.own args_ptr args + "Hargs" ∷ conditionalPut.own args_ptr args (DfracOwn 1) }}} Server__conditionalPut #s #args_ptr {{{ r, RET #(str r); conditionalPut_core_post γ args r }}} @@ -1255,7 +1259,7 @@ Proof. Qed. Lemma ghost_get_dup γ st r args : - st.(server.lastReplies) !! args.(getArgs.opId) = Some r → + st.(server.lastReplies) !! args.(get.opId) = Some r → get_core_pre γ args -∗ server.own_ghost γ st -∗ server.own_ghost γ st ∗ @@ -1269,15 +1273,15 @@ Proof. Qed. Lemma ghost_get γ st args : - st.(server.lastReplies) !! args.(getArgs.opId) = None → + st.(server.lastReplies) !! args.(get.opId) = None → £ 1 -∗ get_core_pre γ args -∗ server.own_ghost γ st ={⊤}=∗ server.own_ghost γ (st <|server.lastReplies := - <[args.(getArgs.opId) := (default "" (st.(server.kvs) !! args.(getArgs.key)))]> + <[args.(get.opId) := (default "" (st.(server.kvs) !! args.(get.key)))]> st.(server.lastReplies)|>) ∗ - get_core_post γ args (default "" (st.(server.kvs) !! args.(getArgs.key))). + get_core_post γ args (default "" (st.(server.kvs) !! args.(get.key))). Proof. intros. iIntros "Hlc Hspec". iNamed 1. @@ -1294,11 +1298,11 @@ Proof. iFrame "∗#%". Qed. -Lemma wp_Server__get (s:loc) γ args_ptr (args:getArgs.t) : +Lemma wp_Server__get (s:loc) γ args_ptr (args:get.C) : {{{ "#Hsrv" ∷ is_Server s γ ∗ "Hspec" ∷ get_core_pre γ args ∗ - "Hargs" ∷ getArgs.own args_ptr args + "Hargs" ∷ get.own args_ptr args (DfracOwn 1) }}} Server__get #s #args_ptr {{{ @@ -1441,15 +1445,15 @@ Definition getFreshNum_spec γ := Program Definition put_spec γ := {| - spec_ty := putArgs.t ; - spec_Pre := (λ args enc_args, ⌜ putArgs.encodes enc_args args ⌝ ∗ put_core_pre γ args)%I; + spec_ty := put.C ; + spec_Pre := (λ args enc_args, ⌜ put.has_encoding enc_args args ⌝ ∗ put_core_pre γ args)%I; spec_Post := (λ args enc_args _, put_core_post γ args)%I; |}. Program Definition conditionalPut_spec γ := {| - spec_ty := conditionalPutArgs.t ; - spec_Pre := (λ args enc_args, ⌜ conditionalPutArgs.encodes enc_args args ⌝ ∗ + spec_ty := conditionalPut.C ; + spec_Pre := (λ args enc_args, ⌜ conditionalPut.has_encoding enc_args args ⌝ ∗ conditionalPut_core_pre γ args)%I; spec_Post := (λ args enc_args enc_reply, ∃ reply, ⌜ enc_reply = string_to_bytes reply ⌝ ∗ @@ -1458,8 +1462,8 @@ Program Definition conditionalPut_spec γ := Program Definition get_spec γ := {| - spec_ty := getArgs.t ; - spec_Pre := (λ args enc_args, ⌜ getArgs.encodes enc_args args ⌝ ∗ + spec_ty := get.C ; + spec_Pre := (λ args enc_args, ⌜ get.has_encoding enc_args args ⌝ ∗ get_core_pre γ args)%I; spec_Post := (λ args enc_args enc_reply, ∃ reply, ⌜ enc_reply = string_to_bytes reply ⌝ ∗ @@ -1547,8 +1551,9 @@ Proof. iIntros "%*%* !# (Hreq_sl & Hrep_sl & Hpre) HΦ". iDestruct "Hpre" as (?) "[% Hpre]". wp_pures. - wp_apply (getArgs.wp_decode with "[$Hreq_sl //]"). - iIntros (?) "[Hargs Hreq_sl]". + wp_apply (get.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. done.} + iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__get with "[$]"). iIntros (?) "HΨ". wp_pures. wp_apply wp_StringToBytes. @@ -1565,8 +1570,9 @@ Proof. iIntros "%*%* !# (Hreq_sl & Hrep_sl & Hpre) HΦ". iDestruct "Hpre" as (?) "[% Hpre]". wp_pures. - wp_apply (conditionalPutArgs.wp_decode with "[$Hreq_sl //]"). - iIntros (?) "[Hargs Hreq_sl]". + wp_apply (conditionalPut.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. done. } + iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__conditionalPut with "[$]"). iIntros (?) "HΨ". wp_pures. wp_apply wp_StringToBytes. @@ -1583,8 +1589,9 @@ Proof. iIntros "%*%* !# (Hreq_sl & Hrep_sl & Hpre) HΦ". iDestruct "Hpre" as (?) "[% Hpre]". wp_pures. - wp_apply (putArgs.wp_decode with "[$Hreq_sl //]"). - iIntros (?) "[Hargs Hreq_sl]". + wp_apply (put.wp_Decode _ _ _ [] with "[Hreq_sl]"). + { rewrite app_nil_r. iFrame. done. } + iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__put with "[$]"). iIntros "HΨ". wp_pures. From 93a1f6d2455ddd81e6aef6ad5dd92c93a065037f Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Wed, 27 Nov 2024 09:10:14 -0600 Subject: [PATCH 11/25] fix typo in tutorial/kvservice/full_proof.v --- .../tutorial/kvservice/full_proof.v | 194 +++++++++--------- 1 file changed, 99 insertions(+), 95 deletions(-) diff --git a/src/program_proof/tutorial/kvservice/full_proof.v b/src/program_proof/tutorial/kvservice/full_proof.v index e07f28b23..ceeb1a395 100644 --- a/src/program_proof/tutorial/kvservice/full_proof.v +++ b/src/program_proof/tutorial/kvservice/full_proof.v @@ -446,91 +446,91 @@ From Perennial.program_proof.tutorial.kvservice Require Import put_proof. (********************************************************************************) -(* Section marshal_proof. *) -(* Context `{!heapGS Σ}. *) +Section marshal_proof. +Context `{!heapGS Σ}. -(* (* TODO: copied this naming convention from "u64_le". What does le actually *) -(* mean? *) *) -(* Definition bool_le (b:bool) : list u8 := if b then [W8 1] else [W8 0]. *) +(* TODO: copied this naming convention from "u64_le". What does le actually *) +(* mean? *) +Definition bool_le (b:bool) : list u8 := if b then [W8 1] else [W8 0]. -(* Lemma wp_EncodeBool (b:bool) : *) -(* {{{ True }}} *) -(* EncodeBool #b *) -(* {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (bool_le b) }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "_ HΦ". *) -(* wp_rec. wp_if_destruct. *) -(* { *) -(* wp_apply wp_NewSlice. iIntros (?) "?". *) -(* wp_apply (wp_SliceAppend with "[$]"). *) -(* iIntros (?) "?". *) -(* by iApply "HΦ". *) -(* } *) -(* { *) -(* wp_apply wp_NewSlice. iIntros (?) "?". *) -(* wp_apply (wp_SliceAppend with "[$]"). *) -(* iIntros (?) "?". *) -(* by iApply "HΦ". *) -(* } *) -(* Qed. *) +Lemma wp_EncodeBool (b:bool) : + {{{ True }}} + EncodeBool #b + {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (bool_le b) }}} +. +Proof. + iIntros (Φ) "_ HΦ". + wp_rec. wp_if_destruct. + { + wp_apply wp_NewSlice. iIntros (?) "?". + wp_apply (wp_SliceAppend with "[$]"). + iIntros (?) "?". + by iApply "HΦ". + } + { + wp_apply wp_NewSlice. iIntros (?) "?". + wp_apply (wp_SliceAppend with "[$]"). + iIntros (?) "?". + by iApply "HΦ". + } +Qed. -(* Lemma wp_DecodeBool sl b q : *) -(* {{{ own_slice_small sl byteT q (bool_le b) }}} *) -(* DecodeBool (slice_val sl) *) -(* {{{ RET #b; True }}} *) -(* . *) -(* Proof. *) -(* iIntros (?) "Hsl HΦ". *) -(* wp_rec. *) -(* unfold bool_le. *) -(* destruct b. *) -(* { *) -(* wp_apply (wp_SliceGet with "[$Hsl]"). *) -(* { done. } *) -(* iIntros "_". *) -(* wp_pures. *) -(* iModIntro. by iApply "HΦ". *) -(* } *) -(* { *) -(* wp_apply (wp_SliceGet with "[$Hsl]"). *) -(* { done. } *) -(* iIntros "_". *) -(* wp_pures. *) -(* iModIntro. by iApply "HΦ". *) -(* } *) -(* Qed. *) +Lemma wp_DecodeBool sl b q : + {{{ own_slice_small sl byteT q (bool_le b) }}} + DecodeBool (slice_val sl) + {{{ RET #b; True }}} +. +Proof. + iIntros (?) "Hsl HΦ". + wp_rec. + unfold bool_le. + destruct b. + { + wp_apply (wp_SliceGet with "[$Hsl]"). + { done. } + iIntros "_". + wp_pures. + iModIntro. by iApply "HΦ". + } + { + wp_apply (wp_SliceGet with "[$Hsl]"). + { done. } + iIntros "_". + wp_pures. + iModIntro. by iApply "HΦ". + } +Qed. -(* Lemma wp_EncodeUint64 x: *) -(* {{{ True }}} *) -(* EncodeUint64 #x *) -(* {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (u64_le x) }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "_ HΦ". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (?) "Hsl". *) -(* wp_apply (wp_WriteInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* by iApply "HΦ". *) -(* Qed. *) +Lemma wp_EncodeUint64 x: + {{{ True }}} + EncodeUint64 #x + {{{ sl, RET (slice_val sl); own_slice sl byteT (DfracOwn 1) (u64_le x) }}} +. +Proof. + iIntros (Φ) "_ HΦ". + wp_rec. + wp_apply wp_NewSlice. + iIntros (?) "Hsl". + wp_apply (wp_WriteInt with "Hsl"). + iIntros (?) "Hsl". + by iApply "HΦ". +Qed. -(* Lemma wp_DecodeUint64 sl x q : *) -(* {{{ own_slice_small sl byteT q (u64_le x) }}} *) -(* DecodeUint64 (slice_val sl) *) -(* {{{ RET #x; True }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hsl HΦ". *) -(* wp_rec. *) -(* wp_apply (wp_ReadInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* by iApply "HΦ". *) -(* Qed. *) +Lemma wp_DecodeUint64 sl x q : + {{{ own_slice_small sl byteT q (u64_le x) }}} + DecodeUint64 (slice_val sl) + {{{ RET #x; True }}} +. +Proof. + iIntros (Φ) "Hsl HΦ". + wp_rec. + wp_apply (wp_ReadInt with "Hsl"). + iIntros (?) "Hsl". + wp_pures. + by iApply "HΦ". +Qed. -(* End marshal_proof. *) +End marshal_proof. Section escrow_library. @@ -1552,7 +1552,7 @@ Proof. iDestruct "Hpre" as (?) "[% Hpre]". wp_pures. wp_apply (get.wp_Decode _ _ _ [] with "[Hreq_sl]"). - { rewrite app_nil_r. iFrame. done.} + { rewrite app_nil_r. iFrame. done. } iIntros (??) "[Hargs Hreq_sl]". wp_apply (wp_Server__get with "[$]"). iIntros (?) "HΨ". @@ -1595,6 +1595,7 @@ Proof. wp_apply (wp_Server__put with "[$]"). iIntros "HΨ". wp_pures. + iClear "Hreq_sl". (* Clear extra information about suff_sl to avoid confusing coq *) iModIntro. iApply "HΦ". iFrame. by iApply (own_slice_small_nil _ (DfracOwn 1)). @@ -1707,7 +1708,7 @@ Qed. Lemma wp_Client__putRpc cl args args_ptr γ : {{{ - "Hargs" ∷ putArgs.own args_ptr args ∗ + "Hargs" ∷ put.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl γ ∗ "#Hspec" ∷ □ put_core_pre γ args }}} @@ -1724,8 +1725,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (putArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply (wp_NewSlice). iIntros (?) "Hnew_sl". + wp_apply (put.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hargs_own & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1749,7 +1751,7 @@ Qed. Lemma wp_Client__conditionalPutRpc γ cl args args_ptr : {{{ - "Hargs" ∷ conditionalPutArgs.own args_ptr args ∗ + "Hargs" ∷ conditionalPut.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl γ ∗ "#Hspec" ∷ □ conditionalPut_core_pre γ args }}} @@ -1768,8 +1770,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (conditionalPutArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply (wp_NewSlice). iIntros (?) "Hs". + wp_apply (conditionalPut.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hargs & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1796,7 +1799,7 @@ Qed. Lemma wp_Client__getRpc γ cl args args_ptr : {{{ - "Hargs" ∷ getArgs.own args_ptr args ∗ + "Hargs" ∷ get.own args_ptr args (DfracOwn 1) ∗ "#Hcl" ∷ is_Client cl γ ∗ "#Hspec" ∷ □ get_core_pre γ args }}} @@ -1813,8 +1816,9 @@ Proof. { done. } iIntros (rep_ptr) "Hrep". wp_pures. - wp_apply (getArgs.wp_encode with "[$]"). - iIntros (??) "(Hargs & %Henc & Hreq_sl)". + wp_apply (wp_NewSlice). iIntros (?) "Hs". + wp_apply (get.wp_Encode with "[$]"). + iIntros (??) "(%Henc & Hargs & Hreq_sl)". wp_pures. iNamed "Hcl". wp_loadField. @@ -1913,8 +1917,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__putRpc with "[Hcl opId key val]"). - { instantiate (1:=putArgs.mk _ _ _). iFrame "∗#". } + wp_apply (wp_Client__putRpc with "[Hcl OpId Key Val]"). + { instantiate (1:=put.mkC _ _ _). iFrame "∗#". } Unshelve. 2:{ iFrame. } iIntros (err) "Hpost". @@ -2002,8 +2006,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__conditionalPutRpc with "[Hcl opId key expectedVal newVal]"). - { instantiate (1:=conditionalPutArgs.mk _ _ _ _). iFrame "∗#". } + wp_apply (wp_Client__conditionalPutRpc with "[Hcl OpId Key ExpectedVal NewVal]"). + { instantiate (1:=conditionalPut.mkC _ _ _ _). iFrame "∗#". } Unshelve. 2:{ instantiate (1:=(λ x, True -∗ Φ #x)%I). @@ -2100,8 +2104,8 @@ Proof. wp_loadField. (* TUTORIAL: *) - wp_apply (wp_Client__getRpc with "[Hcl opId key]"). - { instantiate (1:=getArgs.mk _ _). iFrame "∗#". } + wp_apply (wp_Client__getRpc with "[Hcl OpId Key]"). + { instantiate (1:=get.mkC _ _). iFrame "∗#". } Unshelve. 3:{ iFrame. } iIntros (ret err) "Hpost". From bf2fb41dc8155df9008a8ba1f688a977e734a835 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 3 Dec 2024 09:20:53 -0600 Subject: [PATCH 12/25] update grackle and goose --- flake.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index d0d093739..7e0ff4429 100644 --- a/flake.nix +++ b/flake.nix @@ -17,8 +17,8 @@ src = pkgs.fetchFromGitHub { owner = "mjschwenne"; repo = "grackle"; - rev = "50fb62a4d9363e09c25e997b452eac4af844b5cd"; - sha256 = "16vgpxdkg2686r0m2dqlxm5czxgf07j0myxixsqc84k1z90kivy6"; + rev = "275fce5626d662527ff987ad61aad61044019fa6"; + sha256 = "16iw5hqg2hd12mc62wqv5hxqb8jwymbnhyy16zsza0limhmr0aya"; }; vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; checkPhase = false; @@ -28,8 +28,8 @@ src = pkgs.fetchFromGitHub { owner = "goose-lang"; repo = "goose"; - rev = "8352f2a82040a814b60e0dd9ac75f09cec3dd619"; - sha256 = "0as9cw8v6bxwv2100db63nk8h2mk3330c8kmdlk3kjzlkvy1bdwf"; + rev = "8d13c771b9a80957089f7c5b0ee2ccf58e5eb06f"; + sha256 = "1fbqs75ya4as3my2knkaq4m0crdh3n004grw5g5iczvb5h5k06lz"; }; vendorHash = "sha256-HCJ8v3TSv4UrkOsRuENWVz5Z7zQ1UsOygx0Mo7MELzY="; }; From 5bc8428038ea472bb940a54bbcc2e8906c7f138c Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 3 Dec 2024 11:53:05 -0600 Subject: [PATCH 13/25] update update-grackle with flake integration --- etc/update-grackle.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/etc/update-grackle.sh b/etc/update-grackle.sh index 360a8641d..ee0764450 100755 --- a/etc/update-grackle.sh +++ b/etc/update-grackle.sh @@ -1,5 +1,13 @@ #!/usr/bin/env bash +if [[ -z "$IN_NIX_SHELL" ]]; then + # Not in nix shell, use the default go installs + GRACKLE="go run github.com/mjschwenne/grackle/cmd/grackle@latest" +else + # In a nix shell, expect grackle to be on the PATH and use that + GRACKLE="grackle" +fi + compile_grackle() { CWD=$(pwd) cd "$1" || return @@ -25,14 +33,13 @@ coq_logical_name() { # 2. We only want to output coq code # 3. The coq code should be output into "src/program_proof/$1" # 4. The desired coq package matches the directory structure -# 5. Grackle is on your $PATH # # Parameters # - $1 : Name of the go package inside its repo # - $2 : Path to the root of the go repo. Go package to translate should be at "$2/$1" # - $3 : Prefix to compute the go package name, "$3/$1" run_grackle() { - grackle --coq-logical-path "Perennial.program_proof.$(coq_logical_name $1)" --coq-physical-path "src/program_proof/$1" --go-package "$3/$1" $(realpath "$2/$1") + $GRACKLE --coq-logical-path "Perennial.program_proof.$(coq_logical_name $1)" --coq-physical-path "src/program_proof/$1" --go-package "$3/$1" "$(realpath "$2/$1")" } # Generate Coq files from gokv repo. From 19fa0ef1841fcc18f06359abf42a57e56d8fba8e Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 3 Dec 2024 14:52:45 -0600 Subject: [PATCH 14/25] setup grackle checking for perennial --- .github/workflows/ci.yml | 26 +++++++++++++++++++ etc/ci-grackle-check.py | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100755 etc/ci-grackle-check.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e54050328..7f15aa3f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,32 @@ jobs: - name: check that Goosed files are clean run: etc/ci-goose-check.py + check-grackle: + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + - name: Install protoc + run: sudo apt-get install protobuf-compiler -y + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" + cache: false + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: "pip" + - name: Check Grackle + run: | + ./etc/ci-grackle-check.py + git diff --exit-code + python: runs-on: ubuntu-latest steps: diff --git a/etc/ci-grackle-check.py b/etc/ci-grackle-check.py new file mode 100755 index 000000000..d956489b3 --- /dev/null +++ b/etc/ci-grackle-check.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import shutil +import subprocess as sp +from dataclasses import dataclass + + +@dataclass +class Proj: + name: str + repo: str + commit: str + + def path(self) -> str: + return f"/tmp/{self.name}" + + +projs = { + "gokv": Proj("gokv", "https://github.com/mit-pdos/gokv", "main"), +} + + +def checkout(proj: Proj): + print(f"Checking out {proj.name}") + path = proj.path() + shared_args = {"check": True, "cwd": path} + + try: + p = sp.run( + ["git", "remote", "get-url", "origin"], + text=True, + capture_output=True, + **shared_args, + ) + assert p.stdout.strip() == proj.repo + sp.run(["git", "reset", "--hard"], **shared_args) + sp.run(["git", "pull"], **shared_args) + except (FileNotFoundError, sp.CalledProcessError, AssertionError): + shutil.rmtree(path, ignore_errors=True) + sp.run(["git", "clone", proj.repo, path], check=True) + + sp.run(["git", "checkout", proj.commit], **shared_args) + + +for proj in projs.values(): + checkout(proj) + +print("\nRunning Grackle") +sp.run( + [ + "etc/update-grackle.sh", + "--gokv", + projs["gokv"].path(), + ], + check=True, +) From de4422e6eded4a127a1974003aa784637222a76e Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 3 Dec 2024 19:42:37 -0600 Subject: [PATCH 15/25] draft spec for wp_ReadSlice --- src/program_proof/marshal_stateless_proof.v | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index 2f7a171ed..02009cb91 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -124,6 +124,34 @@ Proof. iApply "Hs". Qed. +Theorem wp_ReadSlice {A:Type} + (enc : list u8) (enc_sl : Slice.t) (count : u64) (args: list A) (goT: ty) + (has_encoding : list u8 -> A -> Prop) (own : loc -> A -> dfrac -> iProp Σ) (readOne : val) + (suffix : list u8) (dq : dfrac) : + {{{ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ + ∀ enc' enc_sl' suffix' x, + {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ + ⌜has_encoding enc' x⌝ + }}} + readOne (slice_val enc_sl') + {{{ x (v : A) suff_sl, RET (#x, slice_val suff_sl); own x v (DfracOwn 1) ∗ + own_slice_small suff_sl byteT dq suffix' ∗ + (* While this is true, I don't know if it is strong enough *) + ⌜v ∈ args⌝ + }}} + }}} + ReadSlice goT (slice_val enc_sl) #count readOne + {{{ xs b2, RET (slice_val xs, slice_val b2); + own_slice_small b2 byteT dq suffix (* ∗ *) + (* FIXME We need to show that the type A can be converted into a val in order + to represent it in go/goose. + + Error: Could not find an instance for "IntoVal A" *) + (* own_slice_small xs goT dq args *) + }}}. +Proof. + Admitted. + Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : {{{ True }}} compute_new_cap #old_cap #min_cap From b79121e1dd48cabaaf6cf1dea01c4006618e8120 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Wed, 4 Dec 2024 17:12:27 -0600 Subject: [PATCH 16/25] add encode fixpoint --- src/program_proof/marshal_stateless_proof.v | 41 +++++++++++++++------ 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index 02009cb91..5a8903353 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -124,12 +124,19 @@ Proof. iApply "Hs". Qed. -Theorem wp_ReadSlice {A:Type} - (enc : list u8) (enc_sl : Slice.t) (count : u64) (args: list A) (goT: ty) +Fixpoint encodes {A:Type} (enc : list u8) (xs : list A) (has_encoding : list u8 -> A -> Prop): Prop := + match xs with + | [] => enc = [] + | x :: xs' => exists bs bs', xs = x :: xs' /\ enc = bs ++ bs' /\ has_encoding bs x /\ encodes bs' xs' has_encoding + end. + +Theorem wp_ReadSlice {A:Type} {V: IntoVal A} {goT: ty} + (enc : list u8) (enc_sl : Slice.t) (count : u64) (args: list A) (ValRel: IntoValForType A goT) (has_encoding : list u8 -> A -> Prop) (own : loc -> A -> dfrac -> iProp Σ) (readOne : val) (suffix : list u8) (dq : dfrac) : - {{{ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ - ∀ enc' enc_sl' suffix' x, + {{{ "Hsl" ∷ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ + "%Henc" ∷ ⌜encodes enc args has_encoding⌝ ∗ + "HreadOne" ∷ ∀ enc' enc_sl' suffix' x, {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ ⌜has_encoding enc' x⌝ }}} @@ -142,15 +149,27 @@ Theorem wp_ReadSlice {A:Type} }}} ReadSlice goT (slice_val enc_sl) #count readOne {{{ xs b2, RET (slice_val xs, slice_val b2); - own_slice_small b2 byteT dq suffix (* ∗ *) - (* FIXME We need to show that the type A can be converted into a val in order - to represent it in go/goose. - - Error: Could not find an instance for "IntoVal A" *) - (* own_slice_small xs goT dq args *) + own_slice_small b2 byteT dq suffix ∗ + own_slice_small xs goT dq args }}}. Proof. - Admitted. + iIntros (ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. + wp_apply (wp_ref_to); first val_ty. iIntros (l) "Henc_sl". + wp_pures. + + wp_apply (wp_NewSlice). iIntros (s) "Hs". + wp_apply (wp_ref_to); first val_ty. iIntros (?) "Hret". + wp_pures. + + wp_apply (wp_ref_to); first val_ty. iIntros (i) "Hi". wp_pures. + + wp_apply (wp_forUpto' + (λ i, ∃ (next: u64), + "%Hi_ge" ∷ ⌜0 ≤ uint.Z i⌝ + )%I + with "[$Hi]" + ). +Admitted. Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : {{{ True }}} From f3cecb129d3f13846627082a1692f79e890060f2 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Wed, 4 Dec 2024 22:05:42 -0600 Subject: [PATCH 17/25] begin working on ReadSlice loop proof --- src/program_proof/marshal_stateless_proof.v | 39 ++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index 5a8903353..fb45504fc 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -136,7 +136,8 @@ Theorem wp_ReadSlice {A:Type} {V: IntoVal A} {goT: ty} (suffix : list u8) (dq : dfrac) : {{{ "Hsl" ∷ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ "%Henc" ∷ ⌜encodes enc args has_encoding⌝ ∗ - "HreadOne" ∷ ∀ enc' enc_sl' suffix' x, + "%Hcount" ∷ ⌜ uint.nat count <= length args ⌝ ∗ + "#HreadOne" ∷ ∀ enc' enc_sl' suffix' x, {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ ⌜has_encoding enc' x⌝ }}} @@ -154,21 +155,43 @@ Theorem wp_ReadSlice {A:Type} {V: IntoVal A} {goT: ty} }}}. Proof. iIntros (ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. - wp_apply (wp_ref_to); first val_ty. iIntros (l) "Henc_sl". + wp_apply (wp_ref_to); first val_ty. iIntros (l__b2) "Henc_sl". wp_pures. - wp_apply (wp_NewSlice). iIntros (s) "Hs". - wp_apply (wp_ref_to); first val_ty. iIntros (?) "Hret". + wp_apply (wp_NewSlice). iIntros (xs) "Hxs". + wp_apply (wp_ref_to); first val_ty. iIntros (l__xs) "Hxs_sl". wp_pures. - wp_apply (wp_ref_to); first val_ty. iIntros (i) "Hi". wp_pures. + wp_apply (wp_ref_to); first val_ty. iIntros (l__i) "Hi". + wp_pures. wp_apply (wp_forUpto' - (λ i, ∃ (next: u64), - "%Hi_ge" ∷ ⌜0 ≤ uint.Z i⌝ + (λ i, ∃ (enc' : list u8) (enc_sl' : Slice.t), + (* Loop Bounds *) + "%Hi_ge" ∷ ⌜0 ≤ uint.nat i⌝ ∗ + "%Hi_le" ∷ ⌜uint.nat i <= uint.Z count⌝ ∗ + (* Encoding *) + "%H_b2_enc" ∷ ⌜encodes enc' (drop (uint.nat i) args) has_encoding⌝ ∗ + "H_b2_sl" ∷ own_slice_small enc_sl' byteT dq (enc' ++ suffix) ∗ + (* Outside variables *) + "Henc_sl" ∷ l__b2 ↦[slice.T byteT] enc_sl ∗ + "Hxs" ∷ own_slice xs goT (DfracOwn 1) (take (uint.nat i) args) ∗ + "Hxs_sl" ∷ l__xs ↦[slice.T goT] xs )%I - with "[$Hi]" + with "[$Hi $Hsl $Henc_sl $Hxs $Hxs_sl]" ). + - iSplit. { word. } + iPureIntro. + split; first word. split; first word. done. + - clear ϕ. iIntros "!>" (i Φ) "[IH (i & %Hle)] HΦ". iNamed "IH". + wp_pures. wp_load. + assert (uint.nat i < length args) as Hi_length. { word. } + unfold encodes in H_b2_enc. + (* TODO Show that args can't be empty at this point to help reduce encodes *) + pose proof (drop_lt args $ uint.nat i) as Hargs_ne. + (* apply Hargs_ne in Hi_length. *) + (* wp_apply ("HreadOne" with "[H_b2_sl]"). *) + (* { iFrame. } *) Admitted. Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : From 0c7b6d794cdc7dd16a7e54300c19851e6ed76284 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Thu, 5 Dec 2024 10:54:01 -0600 Subject: [PATCH 18/25] More work on ReadSlice --- src/program_proof/marshal_stateless_proof.v | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index fb45504fc..4fa51af3e 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -166,13 +166,13 @@ Proof. wp_pures. wp_apply (wp_forUpto' - (λ i, ∃ (enc' : list u8) (enc_sl' : Slice.t), + (λ i, ∃ (enc' suffix' : list u8), (* Loop Bounds *) "%Hi_ge" ∷ ⌜0 ≤ uint.nat i⌝ ∗ "%Hi_le" ∷ ⌜uint.nat i <= uint.Z count⌝ ∗ (* Encoding *) "%H_b2_enc" ∷ ⌜encodes enc' (drop (uint.nat i) args) has_encoding⌝ ∗ - "H_b2_sl" ∷ own_slice_small enc_sl' byteT dq (enc' ++ suffix) ∗ + "H_b2_sl" ∷ own_slice_small enc_sl byteT dq (enc' ++ suffix') ∗ (* Outside variables *) "Henc_sl" ∷ l__b2 ↦[slice.T byteT] enc_sl ∗ "Hxs" ∷ own_slice xs goT (DfracOwn 1) (take (uint.nat i) args) ∗ @@ -185,13 +185,16 @@ Proof. split; first word. split; first word. done. - clear ϕ. iIntros "!>" (i Φ) "[IH (i & %Hle)] HΦ". iNamed "IH". wp_pures. wp_load. - assert (uint.nat i < length args) as Hi_length. { word. } + assert ((uint.nat i < length args)%nat) as Hi_length. { word. } + apply drop_lt in Hi_length. unfold encodes in H_b2_enc. - (* TODO Show that args can't be empty at this point to help reduce encodes *) - pose proof (drop_lt args $ uint.nat i) as Hargs_ne. - (* apply Hargs_ne in Hi_length. *) - (* wp_apply ("HreadOne" with "[H_b2_sl]"). *) - (* { iFrame. } *) + destruct (drop (uint.nat i) args). { contradiction. } + destruct H_b2_enc as (H_b2_bs & H_b2_bs' & H_b2_enc & H_b2_enc' & H_b2_encoding & H_b2_enc_next). + subst. rewrite <- app_assoc. + wp_apply ("HreadOne" with "[$H_b2_sl //]"). + iIntros (???) "(Hown_x & Hsuff_sl & %Helem)". + wp_pures. wp_load. + wp_apply (wp_SliceAppend'). { apply to_val_has_zero. } Admitted. Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : From 210b349f5182aafe02a0a4b2916811fde46e1669 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Thu, 5 Dec 2024 17:00:03 -0600 Subject: [PATCH 19/25] More work on finishing ReadSlice proof --- src/program_proof/marshal_stateless_proof.v | 60 ++++++++++++--------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index 4fa51af3e..d8dd715b1 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -130,35 +130,36 @@ Fixpoint encodes {A:Type} (enc : list u8) (xs : list A) (has_encoding : list u8 | x :: xs' => exists bs bs', xs = x :: xs' /\ enc = bs ++ bs' /\ has_encoding bs x /\ encodes bs' xs' has_encoding end. -Theorem wp_ReadSlice {A:Type} {V: IntoVal A} {goT: ty} - (enc : list u8) (enc_sl : Slice.t) (count : u64) (args: list A) (ValRel: IntoValForType A goT) - (has_encoding : list u8 -> A -> Prop) (own : loc -> A -> dfrac -> iProp Σ) (readOne : val) +Theorem wp_ReadSlice {X : Type} {V : IntoVal X} {goT: ty} + (enc : list u8) (enc_sl : Slice.t) (count : u64) (xs : list X) (ValRel: IntoValForType X goT) + (has_encoding : list u8 -> X -> Prop) (own : val -> X -> dfrac -> iProp Σ) (readOne : val) (suffix : list u8) (dq : dfrac) : + (forall (v : val) (x : X) (dq : dfrac), own v x dq -∗ ⌜v = to_val x⌝) -> {{{ "Hsl" ∷ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ - "%Henc" ∷ ⌜encodes enc args has_encoding⌝ ∗ - "%Hcount" ∷ ⌜ uint.nat count <= length args ⌝ ∗ + "%Henc" ∷ ⌜encodes enc xs has_encoding⌝ ∗ + "%Hcount" ∷ ⌜uint.nat count <= length xs⌝ ∗ "#HreadOne" ∷ ∀ enc' enc_sl' suffix' x, {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ ⌜has_encoding enc' x⌝ }}} readOne (slice_val enc_sl') - {{{ x (v : A) suff_sl, RET (#x, slice_val suff_sl); own x v (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix' ∗ + {{{ (v : val) (x : X) (suff_sl : Slice.t), RET (v, slice_val suff_sl); own v x (DfracOwn 1) ∗ + own_slice_small suff_sl byteT dq suffix' (* While this is true, I don't know if it is strong enough *) - ⌜v ∈ args⌝ + (* ⌜x ∈ xs⌝ *) }}} }}} ReadSlice goT (slice_val enc_sl) #count readOne - {{{ xs b2, RET (slice_val xs, slice_val b2); + {{{ vals b2, RET (slice_val vals, slice_val b2); own_slice_small b2 byteT dq suffix ∗ - own_slice_small xs goT dq args + own_slice_small vals goT dq xs }}}. Proof. - iIntros (ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. + iIntros (Hown_val ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. wp_apply (wp_ref_to); first val_ty. iIntros (l__b2) "Henc_sl". wp_pures. - wp_apply (wp_NewSlice). iIntros (xs) "Hxs". + wp_apply (wp_NewSlice). iIntros (gxs) "Hgxs". wp_apply (wp_ref_to); first val_ty. iIntros (l__xs) "Hxs_sl". wp_pures. @@ -166,35 +167,44 @@ Proof. wp_pures. wp_apply (wp_forUpto' - (λ i, ∃ (enc' suffix' : list u8), + (λ i, ∃ (enc' suffix' : list u8) (enc_sl' gxs' : Slice.t), (* Loop Bounds *) "%Hi_ge" ∷ ⌜0 ≤ uint.nat i⌝ ∗ "%Hi_le" ∷ ⌜uint.nat i <= uint.Z count⌝ ∗ (* Encoding *) - "%H_b2_enc" ∷ ⌜encodes enc' (drop (uint.nat i) args) has_encoding⌝ ∗ - "H_b2_sl" ∷ own_slice_small enc_sl byteT dq (enc' ++ suffix') ∗ + "%H_b2_enc" ∷ ⌜encodes enc' (drop (uint.nat i) xs) has_encoding⌝ ∗ + "H_b2_sl" ∷ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ (* Outside variables *) - "Henc_sl" ∷ l__b2 ↦[slice.T byteT] enc_sl ∗ - "Hxs" ∷ own_slice xs goT (DfracOwn 1) (take (uint.nat i) args) ∗ - "Hxs_sl" ∷ l__xs ↦[slice.T goT] xs + "Henc_sl" ∷ l__b2 ↦[slice.T byteT] enc_sl' ∗ + "Hxs_sl" ∷ l__xs ↦[slice.T goT] gxs' ∗ + "Hxs" ∷ own_slice gxs' goT (DfracOwn 1) (take (uint.nat i) xs) )%I - with "[$Hi $Hsl $Henc_sl $Hxs $Hxs_sl]" + with "[$Hi $Hsl $Henc_sl $Hgxs $Hxs_sl]" ). - iSplit. { word. } iPureIntro. split; first word. split; first word. done. - clear ϕ. iIntros "!>" (i Φ) "[IH (i & %Hle)] HΦ". iNamed "IH". wp_pures. wp_load. - assert ((uint.nat i < length args)%nat) as Hi_length. { word. } - apply drop_lt in Hi_length. + assert ((uint.nat i < length xs)%nat) as Hi_length. { word. } + assert ((uint.nat i < length xs)%nat) as Hi_l_ne. { word. } + apply drop_lt in Hi_l_ne. unfold encodes in H_b2_enc. - destruct (drop (uint.nat i) args). { contradiction. } + destruct (drop (uint.nat i) xs). { contradiction. } destruct H_b2_enc as (H_b2_bs & H_b2_bs' & H_b2_enc & H_b2_enc' & H_b2_encoding & H_b2_enc_next). subst. rewrite <- app_assoc. - wp_apply ("HreadOne" with "[$H_b2_sl //]"). - iIntros (???) "(Hown_x & Hsuff_sl & %Helem)". + wp_apply ("HreadOne" with "[$H_b2_sl //]"). + iIntros (???) "(Hown_x & Hsuff_sl)". wp_pures. wp_load. - wp_apply (wp_SliceAppend'). { apply to_val_has_zero. } + pose proof (Hown_val v x0 (DfracOwn 1)) as Hto_val. + iApply Hto_val in "Hown_x". iDestruct "Hown_x" as "%Hown_x". + rewrite Hown_x. + wp_apply (wp_SliceAppend with "[$Hxs]"). iIntros (s') "Hs'". + wp_store. wp_store. + + iModIntro. iApply "HΦ". iFrame. + (* So I should be able to get rid of the x₀, but take i and take i+1 are fundamentally differenct. + The loop invariant needs to be changed somehow, probably to make it less specific. *) Admitted. Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : From e83d9c107f0ea020ca141380a07cd5c3ca1df9f4 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Fri, 6 Dec 2024 15:13:01 -0600 Subject: [PATCH 20/25] Finish ReadSlice proof --- src/program_proof/marshal_stateless_proof.v | 68 +++++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index d8dd715b1..921aeaacb 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -124,6 +124,15 @@ Proof. iApply "Hs". Qed. +Lemma drop_succ : + forall {A : Type} (l : list A) (x : A) (l' : list A) (n : nat), + l !! n = Some x -> drop n l = x :: l' -> drop (S n) l = l'. +Proof. + intros A l x l' n Helem Hd. + pose proof drop_S l x n. apply H in Helem. rewrite Helem in Hd. + inversion Hd. reflexivity. +Qed. + Fixpoint encodes {A:Type} (enc : list u8) (xs : list A) (has_encoding : list u8 -> A -> Prop): Prop := match xs with | [] => enc = [] @@ -131,31 +140,29 @@ Fixpoint encodes {A:Type} (enc : list u8) (xs : list A) (has_encoding : list u8 end. Theorem wp_ReadSlice {X : Type} {V : IntoVal X} {goT: ty} - (enc : list u8) (enc_sl : Slice.t) (count : u64) (xs : list X) (ValRel: IntoValForType X goT) + (enc : list u8) (enc_sl : Slice.t) (xs : list X) (ValRel: IntoValForType X goT) (has_encoding : list u8 -> X -> Prop) (own : val -> X -> dfrac -> iProp Σ) (readOne : val) (suffix : list u8) (dq : dfrac) : + (length xs < 2^64) -> (forall (v : val) (x : X) (dq : dfrac), own v x dq -∗ ⌜v = to_val x⌝) -> {{{ "Hsl" ∷ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ "%Henc" ∷ ⌜encodes enc xs has_encoding⌝ ∗ - "%Hcount" ∷ ⌜uint.nat count <= length xs⌝ ∗ "#HreadOne" ∷ ∀ enc' enc_sl' suffix' x, {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ ⌜has_encoding enc' x⌝ }}} readOne (slice_val enc_sl') - {{{ (v : val) (x : X) (suff_sl : Slice.t), RET (v, slice_val suff_sl); own v x (DfracOwn 1) ∗ + {{{ (v : val) (suff_sl : Slice.t), RET (v, slice_val suff_sl); own v x (DfracOwn 1) ∗ own_slice_small suff_sl byteT dq suffix' - (* While this is true, I don't know if it is strong enough *) - (* ⌜x ∈ xs⌝ *) }}} }}} - ReadSlice goT (slice_val enc_sl) #count readOne + ReadSlice goT (slice_val enc_sl) #(length xs) readOne {{{ vals b2, RET (slice_val vals, slice_val b2); - own_slice_small b2 byteT dq suffix ∗ - own_slice_small vals goT dq xs + own_slice vals goT (DfracOwn 1) xs ∗ + own_slice_small b2 byteT dq suffix }}}. Proof. - iIntros (Hown_val ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. + iIntros (Hxs_len Hown_val ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. wp_apply (wp_ref_to); first val_ty. iIntros (l__b2) "Henc_sl". wp_pures. @@ -167,13 +174,13 @@ Proof. wp_pures. wp_apply (wp_forUpto' - (λ i, ∃ (enc' suffix' : list u8) (enc_sl' gxs' : Slice.t), + (λ i, ∃ (enc' : list u8) (enc_sl' gxs' : Slice.t), (* Loop Bounds *) "%Hi_ge" ∷ ⌜0 ≤ uint.nat i⌝ ∗ - "%Hi_le" ∷ ⌜uint.nat i <= uint.Z count⌝ ∗ + "%Hi_le" ∷ ⌜uint.nat i <= length xs⌝ ∗ (* Encoding *) "%H_b2_enc" ∷ ⌜encodes enc' (drop (uint.nat i) xs) has_encoding⌝ ∗ - "H_b2_sl" ∷ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ + "H_b2_sl" ∷ own_slice_small enc_sl' byteT dq (enc' ++ suffix) ∗ (* Outside variables *) "Henc_sl" ∷ l__b2 ↦[slice.T byteT] enc_sl' ∗ "Hxs_sl" ∷ l__xs ↦[slice.T goT] gxs' ∗ @@ -186,26 +193,47 @@ Proof. split; first word. split; first word. done. - clear ϕ. iIntros "!>" (i Φ) "[IH (i & %Hle)] HΦ". iNamed "IH". wp_pures. wp_load. - assert ((uint.nat i < length xs)%nat) as Hi_length. { word. } + assert ((uint.nat i <= length xs)%nat) as Hi_length. { word. } assert ((uint.nat i < length xs)%nat) as Hi_l_ne. { word. } apply drop_lt in Hi_l_ne. unfold encodes in H_b2_enc. - destruct (drop (uint.nat i) xs). { contradiction. } + destruct (drop (uint.nat i) xs) eqn:Hdrop. { contradiction. } destruct H_b2_enc as (H_b2_bs & H_b2_bs' & H_b2_enc & H_b2_enc' & H_b2_encoding & H_b2_enc_next). - subst. rewrite <- app_assoc. + rewrite H_b2_enc'. rewrite <- app_assoc. wp_apply ("HreadOne" with "[$H_b2_sl //]"). - iIntros (???) "(Hown_x & Hsuff_sl)". + iIntros (??) "(Hown_x & Hsuff_sl)". wp_pures. wp_load. - pose proof (Hown_val v x0 (DfracOwn 1)) as Hto_val. + pose proof (Hown_val v x (DfracOwn 1)) as Hto_val. iApply Hto_val in "Hown_x". iDestruct "Hown_x" as "%Hown_x". rewrite Hown_x. wp_apply (wp_SliceAppend with "[$Hxs]"). iIntros (s') "Hs'". wp_store. wp_store. iModIntro. iApply "HΦ". iFrame. - (* So I should be able to get rid of the x₀, but take i and take i+1 are fundamentally differenct. - The loop invariant needs to be changed somehow, probably to make it less specific. *) -Admitted. + pose proof (take_drop (uint.nat i) xs) as H_td. + rewrite Hdrop in H_td. + pose proof (length_take_le xs $ uint.nat i) as H_tl. + apply H_tl in Hi_length. symmetry in Hi_length. + pose proof (list_lookup_middle (take (uint.nat i) xs) l x $ uint.nat i) as Hmiddle. + apply Hmiddle in Hi_length as Hlookup. + apply take_S_r in Hlookup as Htake. + rewrite H_td in Htake. + rewrite <- Htake. + replace (uint.nat (w64_word_instance.(word.add) i (W64 1))) with (S (uint.nat i)) by word. + iFrame. iPureIntro. + split; first word. split; first word. + apply drop_succ in Hdrop. + + rewrite Hdrop. done. + + rewrite <- H_td. done. + - iIntros "[Hloop Hi]". iNamed "Hloop". + wp_pures. wp_load. wp_load. wp_pures. + iModIntro. iApply "HΦ". + replace (uint.nat (W64 (length xs))) with (length xs) by word. + replace (uint.nat (W64 (length xs))) with (length xs) in H_b2_enc by word. + rewrite firstn_all. rewrite skipn_all in H_b2_enc. + unfold encodes in H_b2_enc. rewrite H_b2_enc. rewrite app_nil_l. + iFrame. +Qed. Local Theorem wp_compute_new_cap (old_cap min_cap : u64) : {{{ True }}} From 5f4940f2f7b880673e73516ac54e3a2614b8bbc2 Mon Sep 17 00:00:00 2001 From: Tej Chajed Date: Wed, 11 Dec 2024 13:11:44 -0600 Subject: [PATCH 21/25] Remove length xs < 2^64 precondition --- src/program_proof/marshal_stateless_proof.v | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/program_proof/marshal_stateless_proof.v b/src/program_proof/marshal_stateless_proof.v index 921aeaacb..148e3d909 100644 --- a/src/program_proof/marshal_stateless_proof.v +++ b/src/program_proof/marshal_stateless_proof.v @@ -140,13 +140,13 @@ Fixpoint encodes {A:Type} (enc : list u8) (xs : list A) (has_encoding : list u8 end. Theorem wp_ReadSlice {X : Type} {V : IntoVal X} {goT: ty} - (enc : list u8) (enc_sl : Slice.t) (xs : list X) (ValRel: IntoValForType X goT) + (enc : list u8) (enc_sl : Slice.t) (xs : list X) (count : w64) (ValRel: IntoValForType X goT) (has_encoding : list u8 -> X -> Prop) (own : val -> X -> dfrac -> iProp Σ) (readOne : val) (suffix : list u8) (dq : dfrac) : - (length xs < 2^64) -> (forall (v : val) (x : X) (dq : dfrac), own v x dq -∗ ⌜v = to_val x⌝) -> {{{ "Hsl" ∷ own_slice_small enc_sl byteT dq (enc ++ suffix) ∗ "%Henc" ∷ ⌜encodes enc xs has_encoding⌝ ∗ + "%Hcount" ∷ ⌜uint.nat count = length xs⌝ ∗ "#HreadOne" ∷ ∀ enc' enc_sl' suffix' x, {{{ own_slice_small enc_sl' byteT dq (enc' ++ suffix') ∗ ⌜has_encoding enc' x⌝ @@ -156,13 +156,13 @@ Theorem wp_ReadSlice {X : Type} {V : IntoVal X} {goT: ty} own_slice_small suff_sl byteT dq suffix' }}} }}} - ReadSlice goT (slice_val enc_sl) #(length xs) readOne + ReadSlice goT (slice_val enc_sl) #count readOne {{{ vals b2, RET (slice_val vals, slice_val b2); own_slice vals goT (DfracOwn 1) xs ∗ own_slice_small b2 byteT dq suffix }}}. Proof. - iIntros (Hxs_len Hown_val ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. + iIntros (Hown_val ϕ) "Hpre HΦ". iNamed "Hpre". wp_rec. wp_pures. wp_apply (wp_ref_to); first val_ty. iIntros (l__b2) "Henc_sl". wp_pures. @@ -230,7 +230,8 @@ Proof. iModIntro. iApply "HΦ". replace (uint.nat (W64 (length xs))) with (length xs) by word. replace (uint.nat (W64 (length xs))) with (length xs) in H_b2_enc by word. - rewrite firstn_all. rewrite skipn_all in H_b2_enc. + rewrite take_ge; [ | word ]. + rewrite drop_ge in H_b2_enc; [ | word ]. unfold encodes in H_b2_enc. rewrite H_b2_enc. rewrite app_nil_l. iFrame. Qed. From ab7d68f01da29039ffbcae7613ea584e062e0f8d Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Mon, 13 Jan 2025 09:44:42 -0600 Subject: [PATCH 22/25] remove commented marshaling code --- .../tutorial/kvservice/full_proof.v | 434 ------------------ src/program_proof/tutorial/kvservice/proof.v | 432 ----------------- 2 files changed, 866 deletions(-) diff --git a/src/program_proof/tutorial/kvservice/full_proof.v b/src/program_proof/tutorial/kvservice/full_proof.v index 836592ea0..7eadf63b0 100644 --- a/src/program_proof/tutorial/kvservice/full_proof.v +++ b/src/program_proof/tutorial/kvservice/full_proof.v @@ -12,440 +12,6 @@ From Perennial.program_proof.tutorial.kvservice Require Import get_proof. From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof. From Perennial.program_proof.tutorial.kvservice Require Import put_proof. -(********************************************************************************) - -(* Module putArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* val: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ *) -(* string_to_bytes a.(key) ++ string_to_bytes a.(val) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ *) -(* "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodePutArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (sl) "Hsl". *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) - -(* wp_pures. *) -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* rewrite replicate_0 /=. *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply wp_StringToBytes. *) -(* iIntros (key_sl) "Hkey_sl". *) -(* wp_pures. *) - -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl Hkey_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hval_sl". *) -(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) -(* wp_load. *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) -(* iIntros (?) "[Hsl Hval_sl]". *) -(* wp_store. *) - -(* wp_load. *) -(* iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. *) -(* unfold encodes. *) -(* repeat rewrite -assoc. *) -(* rewrite Hsz. *) -(* repeat f_equal. *) -(* word. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodePutArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) - -(* wp_pures. *) -(* wp_load. *) -(* rewrite Henc; clear dependent enc_args. *) -(* wp_apply (wp_ReadInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) -(* wp_load. *) -(* wp_apply (wp_ReadInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) -(* wp_apply (wp_ReadBytes with "[$]"). *) -(* { rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hkey Hval]". *) -(* wp_pures. *) -(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) -(* iIntros "Hkey". *) -(* wp_storeField. *) -(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) -(* iIntros "Hval". *) -(* wp_storeField. *) -(* iModIntro. *) -(* iApply "HΦ". *) -(* repeat rewrite string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) -(* End putArgs. *) - -(* Module conditionalPutArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* expectedVal: string ; *) -(* newVal: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ *) -(* (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ *) -(* "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ *) -(* "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodeConditionalPutArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (sl) "Hsl". *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) -(* wp_pures. *) - -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* rewrite replicate_0 /=. *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply wp_StringToBytes. *) -(* iIntros (key_sl) "Hkey_sl". *) -(* wp_pures. *) -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl Hkey_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hexpect_sl". *) -(* iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". *) -(* wp_pures. *) - -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). *) -(* iIntros (?) "[Hsl Hexpect_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hval_sl". *) -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) -(* iIntros (?) "[Hsl Hval_sl]". *) -(* wp_store. *) - -(* wp_load. *) -(* iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. *) -(* unfold encodes. *) -(* repeat rewrite -assoc. *) -(* rewrite Hsz. *) -(* repeat f_equal; word. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodeConditionalPutArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* wp_pures. *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) -(* wp_load. *) -(* rewrite Henc. *) - -(* wp_apply (wp_ReadInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_ReadInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) - -(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) -(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) -(* { rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hkey Hsl]". *) -(* wp_pures. *) -(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) -(* iIntros "_". *) -(* wp_storeField. *) - -(* wp_apply (wp_ReadInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) - -(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) -(* { repeat rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hexpect Hval]". *) -(* wp_pures. *) - -(* wp_apply (wp_StringFromBytes with "[$Hexpect]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* iModIntro. iApply "HΦ". *) -(* iFrame. *) -(* rewrite ?string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) -(* End conditionalPutArgs. *) - -(* Module getArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ string_to_bytes a.(key) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodeGetArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (?) "Hsl". *) -(* wp_apply (wp_ref_to). *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hkey_sl". *) -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl _]". *) -(* wp_store. *) -(* wp_load. *) -(* iModIntro. iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. done. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodeGetArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply (wp_ref_to). *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_apply (wp_ref_of_zero). *) -(* { done. } *) -(* iIntros (?) "HkeyBytes". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) -(* wp_pures. *) -(* wp_load. *) -(* rewrite Henc. *) -(* wp_apply (wp_ReadInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_StringFromBytes with "[$Hsl]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* iModIntro. *) -(* iApply "HΦ". *) -(* iFrame. *) -(* rewrite string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) - -(* End getArgs. *) - -(********************************************************************************) - Section marshal_proof. Context `{!heapGS Σ}. diff --git a/src/program_proof/tutorial/kvservice/proof.v b/src/program_proof/tutorial/kvservice/proof.v index 3a912c94f..8e96381db 100644 --- a/src/program_proof/tutorial/kvservice/proof.v +++ b/src/program_proof/tutorial/kvservice/proof.v @@ -12,438 +12,6 @@ From Perennial.program_proof.tutorial.kvservice Require Import put_proof. Unset Printing Projections. -(********************************************************************************) - -(* Module putArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* val: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ *) -(* string_to_bytes a.(key) ++ string_to_bytes a.(val) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[putArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[putArgs :: "key"] #(str args.(key)) ∗ *) -(* "Hval" ∷ a ↦[putArgs :: "val"] #(str args.(val)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodePutArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (sl) "Hsl". *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) - -(* wp_pures. *) -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* rewrite replicate_0 /=. *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply wp_StringToBytes. *) -(* iIntros (key_sl) "Hkey_sl". *) -(* wp_pures. *) - -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl Hkey_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hval_sl". *) -(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) -(* wp_load. *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) -(* iIntros (?) "[Hsl Hval_sl]". *) -(* wp_store. *) - -(* wp_load. *) -(* iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. *) -(* unfold encodes. *) -(* repeat rewrite -assoc. *) -(* rewrite Hsz. *) -(* repeat f_equal. *) -(* word. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodePutArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) - -(* wp_pures. *) -(* wp_load. *) -(* rewrite Henc; clear dependent enc_args. *) -(* wp_apply (wp_ReadInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) -(* wp_load. *) -(* wp_apply (wp_ReadInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) -(* wp_apply (wp_ReadBytes with "[$]"). *) -(* { rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hkey Hval]". *) -(* wp_pures. *) -(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) -(* iIntros "Hkey". *) -(* wp_storeField. *) -(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) -(* iIntros "Hval". *) -(* wp_storeField. *) -(* iModIntro. *) -(* iApply "HΦ". *) -(* do 2 rewrite string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) -(* End putArgs. *) - -(* Module conditionalPutArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* expectedVal: string ; *) -(* newVal: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ (u64_le $ length $ string_to_bytes a.(key)) ++ string_to_bytes a.(key) ++ *) -(* (u64_le $ length $ string_to_bytes a.(expectedVal)) ++ string_to_bytes a.(expectedVal) ++ string_to_bytes a.(newVal) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[conditionalPutArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[conditionalPutArgs :: "key"] #(str args.(key)) ∗ *) -(* "HexpectedVal" ∷ a ↦[conditionalPutArgs :: "expectedVal"] #(str args.(expectedVal)) ∗ *) -(* "Hval" ∷ a ↦[conditionalPutArgs :: "newVal"] #(str args.(newVal)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodeConditionalPutArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (sl) "Hsl". *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (e) "He". *) -(* wp_pures. *) - -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$]"). *) -(* iIntros (?) "Hsl". *) -(* rewrite replicate_0 /=. *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply wp_StringToBytes. *) -(* iIntros (key_sl) "Hkey_sl". *) -(* wp_pures. *) -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_sz with "Hkey_sl") as "%Hsz". *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl Hkey_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hexpect_sl". *) -(* iDestruct (own_slice_to_small with "Hexpect_sl") as "Hexpect_sl". *) -(* wp_pures. *) - -(* wp_apply wp_slice_len. *) -(* iDestruct (own_slice_small_sz with "Hexpect_sl") as %?. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hexpect_sl]"). *) -(* iIntros (?) "[Hsl Hexpect_sl]". *) -(* wp_store. *) - -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hval_sl". *) -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hval_sl") as "Hval_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hval_sl]"). *) -(* iIntros (?) "[Hsl Hval_sl]". *) -(* wp_store. *) - -(* wp_load. *) -(* iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. *) -(* unfold encodes. *) -(* repeat rewrite -assoc. *) -(* rewrite Hsz. *) -(* repeat f_equal; word. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodeConditionalPutArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply wp_ref_to. *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* wp_pures. *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) -(* wp_load. *) -(* rewrite Henc. *) - -(* wp_apply (wp_ReadInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_ReadInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) - -(* iDestruct (own_slice_small_sz with "Hsl") as %Hsz. *) -(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) -(* { rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hkey Hsl]". *) -(* wp_pures. *) -(* wp_apply (wp_StringFromBytes with "[$Hkey]"). *) -(* iIntros "_". *) -(* wp_storeField. *) - -(* wp_apply (wp_ReadInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) - -(* wp_apply (wp_ReadBytes with "[$Hsl]"). *) -(* { repeat rewrite length_app in Hsz. word. } *) -(* iIntros (??) "[Hexpect Hval]". *) -(* wp_pures. *) - -(* wp_apply (wp_StringFromBytes with "[$Hexpect]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* wp_apply (wp_StringFromBytes with "[$Hval]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* iModIntro. iApply "HΦ". *) -(* repeat rewrite string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) -(* End conditionalPutArgs. *) - -(* Module getArgs. *) -(* Record t := *) -(* mk { *) -(* opId: u64 ; *) -(* key: string ; *) -(* }. *) - -(* Definition encodes (x:list u8) (a:t) : Prop := *) -(* x = u64_le a.(opId) ++ string_to_bytes a.(key) *) -(* . *) - -(* Section local_defs. *) -(* Context `{!heapGS Σ}. *) -(* Definition own `{!heapGS Σ} (a:loc) (args:t) : iProp Σ := *) -(* "HopId" ∷ a ↦[getArgs :: "opId"] #args.(opId) ∗ *) -(* "Hkey" ∷ a ↦[getArgs :: "key"] #(str args.(key)) *) -(* . *) - -(* Lemma wp_encode args_ptr args : *) -(* {{{ *) -(* own args_ptr args *) -(* }}} *) -(* encodeGetArgs #args_ptr *) -(* {{{ *) -(* (sl:Slice.t) enc_args, RET (slice_val sl); own args_ptr args ∗ *) -(* ⌜encodes enc_args args⌝ ∗ *) -(* own_slice sl byteT (DfracOwn 1) enc_args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hargs HΦ". *) -(* iNamed "Hargs". *) -(* wp_rec. *) -(* wp_apply wp_NewSlice. *) -(* iIntros (?) "Hsl". *) -(* wp_apply (wp_ref_to). *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_loadField. *) -(* wp_load. *) -(* wp_apply (wp_WriteInt with "Hsl"). *) -(* iIntros (?) "Hsl". *) -(* wp_store. *) -(* wp_loadField. *) -(* wp_apply (wp_StringToBytes). *) -(* iIntros (?) "Hkey_sl". *) -(* wp_load. *) -(* iDestruct (own_slice_to_small with "Hkey_sl") as "Hkey_sl". *) -(* wp_apply (wp_WriteBytes with "[$Hsl $Hkey_sl]"). *) -(* iIntros (?) "[Hsl _]". *) -(* wp_store. *) -(* wp_load. *) -(* iModIntro. iApply "HΦ". *) -(* iFrame. *) -(* iPureIntro. done. *) -(* Qed. *) - -(* Lemma wp_decode sl enc_args args q : *) -(* {{{ *) -(* "%Henc" ∷ ⌜encodes enc_args args⌝ ∗ *) -(* "Hsl" ∷ own_slice_small sl byteT q enc_args *) -(* }}} *) -(* decodeGetArgs (slice_val sl) *) -(* {{{ *) -(* (args_ptr:loc), RET #args_ptr; own args_ptr args *) -(* }}} *) -(* . *) -(* Proof. *) -(* iIntros (Φ) "Hpre HΦ". *) -(* iNamed "Hpre". *) -(* wp_rec. *) -(* wp_apply (wp_ref_to). *) -(* { done. } *) -(* iIntros (?) "He". *) -(* wp_pures. *) -(* wp_apply (wp_ref_of_zero). *) -(* { done. } *) -(* iIntros (?) "HkeyBytes". *) -(* wp_pures. *) -(* wp_apply wp_allocStruct. *) -(* { repeat econstructor. } *) -(* iIntros (args_ptr) "Hargs". *) -(* iDestruct (struct_fields_split with "Hargs") as "HH". *) -(* iNamed "HH". *) -(* wp_pures. *) -(* wp_load. *) -(* rewrite Henc. *) -(* wp_apply (wp_ReadInt with "[$Hsl]"). *) -(* iIntros (?) "Hsl". *) -(* wp_pures. *) -(* wp_storeField. *) -(* wp_store. *) - -(* wp_load. *) -(* wp_apply (wp_StringFromBytes with "[$Hsl]"). *) -(* iIntros "_". *) -(* wp_storeField. *) -(* iModIntro. *) -(* iApply "HΦ". *) -(* repeat rewrite string_to_bytes_to_string. *) -(* iFrame. *) -(* Qed. *) - -(* End local_defs. *) - -(* End getArgs. *) - -(********************************************************************************) - Section marshal_proof. Context `{!heapGS Σ}. From 92ed2ba9a30526c27c00546f4af7762a04e896cd Mon Sep 17 00:00:00 2001 From: Tej Chajed Date: Tue, 14 Jan 2025 14:45:26 -0600 Subject: [PATCH 23/25] Mark auto-generated files for GitHub PR review --- .gitattributes | 1 + src/program_proof/tutorial/.gitattributes | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 .gitattributes create mode 100644 src/program_proof/tutorial/.gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..c02830986 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +external/Goose/** linguist-generated diff --git a/src/program_proof/tutorial/.gitattributes b/src/program_proof/tutorial/.gitattributes new file mode 100644 index 000000000..f3da06eac --- /dev/null +++ b/src/program_proof/tutorial/.gitattributes @@ -0,0 +1,4 @@ +kvservice/get_proof.v linguist-generated +kvservice/put_proof.v linguist-generated +kvservice/conditionalput_proof.v linguist-generated +objectstore/**/**_proof.v linguist-generated From 0b25fed9399ce9607eb37ff7737baaa023084140 Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 28 Jan 2025 15:31:53 -0600 Subject: [PATCH 24/25] update kvservice proofs to use new file names --- external/Goose/github_com/tchajed/marshal.v | 2 +- flake.nix | 10 +- .../tutorial/kvservice/conditionalput_proof.v | 222 ------------------ .../tutorial/kvservice/full_proof.v | 6 +- .../tutorial/kvservice/get_proof.v | 164 ------------- src/program_proof/tutorial/kvservice/proof.v | 6 +- .../tutorial/kvservice/put_proof.v | 193 --------------- .../tutorial/lockservice/lockrequest_proof.v | 129 ---------- .../objectstore/chunk/writechunk_proof.v | 137 ----------- .../objectstore/dir/chunkhandle_proof.v | 164 ------------- .../objectstore/dir/finishwrite_proof.v | 164 ------------- .../objectstore/dir/recordchunk_proof.v | 186 --------------- 12 files changed, 12 insertions(+), 1371 deletions(-) delete mode 100644 src/program_proof/tutorial/kvservice/conditionalput_proof.v delete mode 100644 src/program_proof/tutorial/kvservice/get_proof.v delete mode 100644 src/program_proof/tutorial/kvservice/put_proof.v delete mode 100644 src/program_proof/tutorial/lockservice/lockrequest_proof.v delete mode 100644 src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v delete mode 100644 src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v delete mode 100644 src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v delete mode 100644 src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v diff --git a/external/Goose/github_com/tchajed/marshal.v b/external/Goose/github_com/tchajed/marshal.v index bc75d6e0f..264770990 100644 --- a/external/Goose/github_com/tchajed/marshal.v +++ b/external/Goose/github_com/tchajed/marshal.v @@ -233,7 +233,7 @@ Definition WriteSlice (T:ty): val := rec: "WriteSlice" "b" "xs" "writeOne" := let: "b2" := ref_to (slice.T byteT) "b" in ForSlice T <> "x" "xs" - ("b2" <-[slice.T byteT] ("writeOne" "x" (![slice.T byteT] "b2")));; + ("b2" <-[slice.T byteT] (("writeOne" ([]byte__to__T (![slice.T byteT] "b2"))) "x"));; ![slice.T byteT] "b2". Definition WriteSliceLenPrefix (T:ty): val := diff --git a/flake.nix b/flake.nix index e3f4ecc15..948070d3e 100644 --- a/flake.nix +++ b/flake.nix @@ -17,10 +17,10 @@ src = pkgs.fetchFromGitHub { owner = "mjschwenne"; repo = "grackle"; - rev = "101412356cdfbcad78f8aaa724101312928c4978"; - sha256 = "06zf2bvrbbjhgrd6994h3wcaml7m83m6f9r61pj7y09xq9nw10br"; + rev = "3a83c3b22f163da77d75bfdb3923f007af2ad515"; + sha256 = "1bl8lx50qhl6yczjnwfwywx29nvinr20v2zjdc2zjqi8kcls7kqr"; }; - vendorHash = "sha256-Wk2v0HSAkrzxHJvCfbw6xOn0OQ1xukvYjDxk3c2LmH8="; + vendorHash = "sha256-c9+npmcdynfqSnxEZSdubVeN8Y3eYAwjya52vTJayY0="; checkPhase = false; }; goose = pkgs.buildGoModule { @@ -28,8 +28,8 @@ src = pkgs.fetchFromGitHub { owner = "goose-lang"; repo = "goose"; - rev = "a4f2f84193d34f56dd84fc623adc43a6441da1eb"; - sha256 = "1b1dfa1qsv2h7hy5x20zhic2npr5gz1zp76m1lab4v490adxj2rx"; + rev = "67cf95ebfc80e80ddc40b0518e6d761cde44977c"; + sha256 = "16040c4frxn9dk3xmajzg4jb7fi7q39hasfp94rpnphmpr4hvr51"; }; vendorHash = "sha256-HCJ8v3TSv4UrkOsRuENWVz5Z7zQ1UsOygx0Mo7MELzY="; }; diff --git a/src/program_proof/tutorial/kvservice/conditionalput_proof.v b/src/program_proof/tutorial/kvservice/conditionalput_proof.v deleted file mode 100644 index 6b97f4b0e..000000000 --- a/src/program_proof/tutorial/kvservice/conditionalput_proof.v +++ /dev/null @@ -1,222 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.conditionalput_gk. - -Module conditionalPut. -Section conditionalPut. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - opId : u64; - key : byte_string; - expectedVal : byte_string; - newVal : byte_string; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(opId)) ++ - (u64_le $ length $ args.(key)) ++ args.(key) ++ - (u64_le $ length $ args.(expectedVal)) ++ args.(expectedVal) ++ - (u64_le $ length $ args.(newVal)) ++ args.(newVal). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(opId), (#(str args__c.(key)), (#(str args__c.(expectedVal)), (#(str args__c.(newVal)), #()))))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(opId), (#(str c.(key)), (#(str c.(expectedVal)), (#(str c.(newVal)), #())))). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt opId), (#(LitString key), (#(LitString expectedVal), (#(LitString newVal), #()))))%V => - Some (mkC opId key expectedVal newVal) - | _ => None - end. - -#[global] -Instance conditionalPut_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) "" "" "") - |}. - intros v. - destruct v as [opId key expectedVal newVal]; done. -Defined. - -#[global] -Instance conditionalPut_into_val_for_type : IntoValForType C (struct.t conditionalput_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - conditionalput_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". - iApply own_slice_to_small in "Hargs_key_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_expectedVal_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_expectedVal_enc") as "%Hargs_expectedVal_sz". - iApply own_slice_to_small in "Hargs_expectedVal_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_expectedVal_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_newVal_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_newVal_enc") as "%Hargs_newVal_sz". - iApply own_slice_to_small in "Hargs_newVal_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_newVal_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_key_sz. - rewrite Hargs_expectedVal_sz. - rewrite Hargs_newVal_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - conditionalput_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__opId) "HopId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__key) "Hkey". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__expectedVal) "HexpectedVal". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__newVal) "HnewVal". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hkey_sz. word. } - iIntros (??) "[Hkey' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "Hkey'". - wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". - wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (expectedValLen) "HexpectedValLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (expectedValBytes) "HexpectedValBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %HexpectedVal_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in HexpectedVal_sz. word. } - iIntros (??) "[HexpectedVal' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "HexpectedVal'". - wp_apply (wp_StringFromBytes with "[$HexpectedVal']"). iIntros "_". - wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (newValLen) "HnewValLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (newValBytes) "HnewValBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %HnewVal_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in HnewVal_sz. word. } - iIntros (??) "[HnewVal' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "HnewVal'". - wp_apply (wp_StringFromBytes with "[$HnewVal']"). iIntros "_". - wp_store. - - wp_load. wp_load. wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End conditionalPut. -End conditionalPut. - diff --git a/src/program_proof/tutorial/kvservice/full_proof.v b/src/program_proof/tutorial/kvservice/full_proof.v index 7eadf63b0..eb68f7c5b 100644 --- a/src/program_proof/tutorial/kvservice/full_proof.v +++ b/src/program_proof/tutorial/kvservice/full_proof.v @@ -8,9 +8,9 @@ From Perennial.program_logic Require Import atomic_fupd. From RecordUpdate Require Import RecordSet. Import RecordSetNotations. -From Perennial.program_proof.tutorial.kvservice Require Import get_proof. -From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof. -From Perennial.program_proof.tutorial.kvservice Require Import put_proof. +From Perennial.program_proof.tutorial.kvservice Require Import get_proof_gk. +From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof_gk. +From Perennial.program_proof.tutorial.kvservice Require Import put_proof_gk. Section marshal_proof. Context `{!heapGS Σ}. diff --git a/src/program_proof/tutorial/kvservice/get_proof.v b/src/program_proof/tutorial/kvservice/get_proof.v deleted file mode 100644 index 600ea38b8..000000000 --- a/src/program_proof/tutorial/kvservice/get_proof.v +++ /dev/null @@ -1,164 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.get_gk. - -Module get. -Section get. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - opId : u64; - key : byte_string; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(opId)) ++ - (u64_le $ length $ args.(key)) ++ args.(key). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(opId), (#(str args__c.(key)), #()))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(opId), (#(str c.(key)), #())). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt opId), (#(LitString key), #()))%V => - Some (mkC opId key) - | _ => None - end. - -#[global] -Instance get_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) "") - |}. - intros v. - destruct v as [opId key]; done. -Defined. - -#[global] -Instance get_into_val_for_type : IntoValForType C (struct.t get_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - get_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". - iApply own_slice_to_small in "Hargs_key_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_key_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - get_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__opId) "HopId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__key) "Hkey". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hkey_sz. word. } - iIntros (??) "[Hkey' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "Hkey'". - wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". - wp_store. - - wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End get. -End get. - diff --git a/src/program_proof/tutorial/kvservice/proof.v b/src/program_proof/tutorial/kvservice/proof.v index 8e96381db..4cfbb47a1 100644 --- a/src/program_proof/tutorial/kvservice/proof.v +++ b/src/program_proof/tutorial/kvservice/proof.v @@ -6,9 +6,9 @@ From Perennial.program_proof Require Import std_proof. From Perennial.goose_lang.automation Require Import extra_tactics. From Perennial.goose_lang Require Import proofmode. -From Perennial.program_proof.tutorial.kvservice Require Import get_proof. -From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof. -From Perennial.program_proof.tutorial.kvservice Require Import put_proof. +From Perennial.program_proof.tutorial.kvservice Require Import get_proof_gk. +From Perennial.program_proof.tutorial.kvservice Require Import conditionalput_proof_gk. +From Perennial.program_proof.tutorial.kvservice Require Import put_proof_gk. Unset Printing Projections. diff --git a/src/program_proof/tutorial/kvservice/put_proof.v b/src/program_proof/tutorial/kvservice/put_proof.v deleted file mode 100644 index 1edfb6822..000000000 --- a/src/program_proof/tutorial/kvservice/put_proof.v +++ /dev/null @@ -1,193 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.kvservice.put_gk. - -Module put. -Section put. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - opId : u64; - key : byte_string; - value : byte_string; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(opId)) ++ - (u64_le $ length $ args.(key)) ++ args.(key) ++ - (u64_le $ length $ args.(value)) ++ args.(value). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(opId), (#(str args__c.(key)), (#(str args__c.(value)), #())))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(opId), (#(str c.(key)), (#(str c.(value)), #()))). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt opId), (#(LitString key), (#(LitString value), #())))%V => - Some (mkC opId key value) - | _ => None - end. - -#[global] -Instance put_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) "" "") - |}. - intros v. - destruct v as [opId key value]; done. -Defined. - -#[global] -Instance put_into_val_for_type : IntoValForType C (struct.t put_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - put_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_key_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_key_enc") as "%Hargs_key_sz". - iApply own_slice_to_small in "Hargs_key_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_key_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_value_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_value_enc") as "%Hargs_value_sz". - iApply own_slice_to_small in "Hargs_value_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_value_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_key_sz. - rewrite Hargs_value_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - put_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__opId) "HopId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__key) "Hkey". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__value) "Hvalue". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (keyLen) "HkeyLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (keyBytes) "HkeyBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hkey_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hkey_sz. word. } - iIntros (??) "[Hkey' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "Hkey'". - wp_apply (wp_StringFromBytes with "[$Hkey']"). iIntros "_". - wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (valueLen) "HvalueLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (valueBytes) "HvalueBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hvalue_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hvalue_sz. word. } - iIntros (??) "[Hvalue' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "Hvalue'". - wp_apply (wp_StringFromBytes with "[$Hvalue']"). iIntros "_". - wp_store. - - wp_load. wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End put. -End put. - diff --git a/src/program_proof/tutorial/lockservice/lockrequest_proof.v b/src/program_proof/tutorial/lockservice/lockrequest_proof.v deleted file mode 100644 index 02b850c3b..000000000 --- a/src/program_proof/tutorial/lockservice/lockrequest_proof.v +++ /dev/null @@ -1,129 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.lockservice.lockrequest_gk. - -Module LockRequest. -Section LockRequest. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - id : u64; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(id)). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(id), #())%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(id), #()). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt id), #())%V => - Some (mkC id) - | _ => None - end. - -#[global] -Instance LockRequest_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0)) - |}. - intros v. - destruct v as [id]; done. -Defined. - -#[global] -Instance LockRequest_into_val_for_type : IntoValForType C (struct.t lockrequest_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - lockrequest_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - lockrequest_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__id) "Hid". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End LockRequest. -End LockRequest. - diff --git a/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v b/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v deleted file mode 100644 index 2e2bb008e..000000000 --- a/src/program_proof/tutorial/objectstore/chunk/writechunk_proof.v +++ /dev/null @@ -1,137 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.chunk.writechunk_gk. - -Module writeChunk. -Section writeChunk. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - writeId : u64; - chunk : list u8; - index : u64; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(writeId)) ++ - (u64_le $ length $ args.(chunk)) ++ args.(chunk) ++ - (u64_le args.(index)). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - ∃(chunk_sl : Slice.t), - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(writeId), (slice_val chunk_sl, (#args__c.(index), #())))%V ⌝ ∗ - "Hown_chunk" ∷ own_slice_small chunk_sl byteT dq args__c.(chunk). - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - writechunk_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - iDestruct (own_slice_small_sz with "Hown_chunk") as "%Hargs_chunk_sz". - wp_pures. wp_apply (wp_slice_len). wp_load. - wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_pures. wp_load. - wp_apply (wp_WriteBytes with "[$Hsl $Hown_chunk]"). - iIntros (?) "[Hsl Hargs_chunk_sl]". wp_store. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_chunk_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - writechunk_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__writeId) "HwriteId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__chunk) "Hchunk". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__index) "Hindex". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_allocN; first done; first by val_ty. - iIntros (?) "HchunkLen". iApply array_singleton in "HchunkLen". wp_pures. - wp_apply wp_allocN; first done; first by val_ty. - iIntros (?) "HchunkBytes". iApply array_singleton in "HchunkBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hchunk_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hchunk_sz. word. } - iIntros (??) "[Hchunk' Hsl]". iApply own_slice_to_small in "Hchunk'". - - wp_pures. wp_store. wp_store. wp_load. wp_store. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_load. wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End writeChunk. -End writeChunk. - diff --git a/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v b/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v deleted file mode 100644 index 21ea25bff..000000000 --- a/src/program_proof/tutorial/objectstore/dir/chunkhandle_proof.v +++ /dev/null @@ -1,164 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.chunkhandle_gk. - -Module chunkHandle. -Section chunkHandle. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - addr : u64; - contentHash : byte_string; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(addr)) ++ - (u64_le $ length $ args.(contentHash)) ++ args.(contentHash). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(addr), (#(str args__c.(contentHash)), #()))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(addr), (#(str c.(contentHash)), #())). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt addr), (#(LitString contentHash), #()))%V => - Some (mkC addr contentHash) - | _ => None - end. - -#[global] -Instance chunkHandle_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) "") - |}. - intros v. - destruct v as [addr contentHash]; done. -Defined. - -#[global] -Instance chunkHandle_into_val_for_type : IntoValForType C (struct.t chunkhandle_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - chunkhandle_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_contentHash_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_contentHash_enc") as "%Hargs_contentHash_sz". - iApply own_slice_to_small in "Hargs_contentHash_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_contentHash_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_contentHash_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - chunkhandle_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__addr) "Haddr". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__contentHash) "HcontentHash". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (contentHashLen) "HcontentHashLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (contentHashBytes) "HcontentHashBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %HcontentHash_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in HcontentHash_sz. word. } - iIntros (??) "[HcontentHash' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "HcontentHash'". - wp_apply (wp_StringFromBytes with "[$HcontentHash']"). iIntros "_". - wp_store. - - wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End chunkHandle. -End chunkHandle. - diff --git a/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v b/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v deleted file mode 100644 index 0380f0724..000000000 --- a/src/program_proof/tutorial/objectstore/dir/finishwrite_proof.v +++ /dev/null @@ -1,164 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.finishwrite_gk. - -Module finishWrite. -Section finishWrite. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - writeId : u64; - keyname : byte_string; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(writeId)) ++ - (u64_le $ length $ args.(keyname)) ++ args.(keyname). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(writeId), (#(str args__c.(keyname)), #()))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(writeId), (#(str c.(keyname)), #())). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt writeId), (#(LitString keyname), #()))%V => - Some (mkC writeId keyname) - | _ => None - end. - -#[global] -Instance finishWrite_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) "") - |}. - intros v. - destruct v as [writeId keyname]; done. -Defined. - -#[global] -Instance finishWrite_into_val_for_type : IntoValForType C (struct.t finishwrite_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - finishwrite_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_keyname_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_keyname_enc") as "%Hargs_keyname_sz". - iApply own_slice_to_small in "Hargs_keyname_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_keyname_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_keyname_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - finishwrite_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__writeId) "HwriteId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__keyname) "Hkeyname". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (keynameLen) "HkeynameLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (keynameBytes) "HkeynameBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %Hkeyname_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in Hkeyname_sz. word. } - iIntros (??) "[Hkeyname' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "Hkeyname'". - wp_apply (wp_StringFromBytes with "[$Hkeyname']"). iIntros "_". - wp_store. - - wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End finishWrite. -End finishWrite. - diff --git a/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v b/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v deleted file mode 100644 index 583309026..000000000 --- a/src/program_proof/tutorial/objectstore/dir/recordchunk_proof.v +++ /dev/null @@ -1,186 +0,0 @@ -(*****************************************) -(* This file is autogenerated by grackle *) -(* DO NOT MANUALLY EDIT THIS FILE *) -(*****************************************) - -From Perennial.program_proof Require Import grove_prelude. -From Perennial.program_proof Require Import marshal_stateless_proof. -From Goose Require Import github_com.mit_pdos.gokv.tutorial.objectstore.dir.recordchunk_gk. - -Module recordChunk. -Section recordChunk. - -Typeclasses Opaque app. - -Context `{!heapGS Σ}. - -Record C := - mkC { - writeId : u64; - server : u64; - contentHash : byte_string; - index : u64; - }. - -Definition has_encoding (encoded:list u8) (args:C) : Prop := - encoded = (u64_le args.(writeId)) ++ - (u64_le args.(server)) ++ - (u64_le $ length $ args.(contentHash)) ++ args.(contentHash) ++ - (u64_le args.(index)). - -Definition own (args__v: val) (args__c: C) (dq: dfrac) : iProp Σ := - "%Hown_struct" ∷ ⌜ args__v = (#args__c.(writeId), (#args__c.(server), (#(str args__c.(contentHash)), (#args__c.(index), #()))))%V ⌝. - - -Definition to_val' (c : C) : val := - (#c.(writeId), (#c.(server), (#(str c.(contentHash)), (#c.(index), #())))). - -Definition from_val' (v : val) : option C := - match v with - | (#(LitInt writeId), (#(LitInt server), (#(LitString contentHash), (#(LitInt index), #()))))%V => - Some (mkC writeId server contentHash index) - | _ => None - end. - -#[global] -Instance recordChunk_into_val : IntoVal C. -Proof. - refine {| - to_val := to_val'; - from_val := from_val'; - IntoVal_def := (mkC (W64 0) (W64 0) "" (W64 0)) - |}. - intros v. - destruct v as [writeId server contentHash index]; done. -Defined. - -#[global] -Instance recordChunk_into_val_for_type : IntoValForType C (struct.t recordchunk_gk.S). -Proof. constructor; auto 10. Defined. - -Lemma own_to_val (v : val) (c : C) (dq : dfrac) : - own v c dq -∗ own v c dq ∗ ⌜ v = to_val c ⌝. -Proof. - iIntros "%Hown_struct". - - iUnfold own. - iSplitL. - + iPureIntro. done. - + done. -Qed. - - -Lemma wp_Encode (args__v : val) (args__c : C) (pre_sl : Slice.t) (prefix : list u8) (dq : dfrac): - {{{ - own args__v args__c dq ∗ - own_slice pre_sl byteT (DfracOwn 1) prefix - }}} - recordchunk_gk.Marshal args__v (slice_val pre_sl) - {{{ - enc enc_sl, RET (slice_val enc_sl); - ⌜ has_encoding enc args__c ⌝ ∗ - own args__v args__c dq ∗ - own_slice enc_sl byteT (DfracOwn 1) (prefix ++ enc) - }}}. - -Proof. - iIntros (?) "[Hown Hsl] HΦ". - wp_rec. wp_pures. - iUnfold own in "Hown". iNamed "Hown". rewrite Hown_struct. - wp_apply (wp_ref_to); first by val_ty. - iIntros (?) "Hptr". wp_pures. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - wp_apply wp_StringToBytes. iIntros (?) "Hargs_contentHash_enc". wp_pures. - wp_apply (wp_slice_len). - iDestruct (own_slice_sz with "Hargs_contentHash_enc") as "%Hargs_contentHash_sz". - iApply own_slice_to_small in "Hargs_contentHash_enc". - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). iIntros (?) "Hsl". wp_store. - wp_load. wp_apply (wp_WriteBytes with "[$Hsl $Hargs_contentHash_enc]"). - iIntros (?) "[Hsl _]". wp_store. - - wp_load. wp_apply (wp_WriteInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_store. - - - wp_load. iApply "HΦ". iModIntro. rewrite -?app_assoc. - iFrame. iPureIntro. - - unfold has_encoding. split. - { - - rewrite ?string_bytes_length. - rewrite Hargs_contentHash_sz. - rewrite ?w64_to_nat_id. exact. - - } done. -Qed. - -Lemma wp_Decode (enc : list u8) (enc_sl : Slice.t) (args__c : C) (suffix : list u8) (dq : dfrac): - {{{ - ⌜ has_encoding enc args__c ⌝ ∗ - own_slice_small enc_sl byteT dq (enc ++ suffix) - }}} - recordchunk_gk.Unmarshal (slice_val enc_sl) - {{{ - args__v suff_sl, RET (args__v, suff_sl); - own args__v args__c (DfracOwn 1) ∗ - own_slice_small suff_sl byteT dq suffix - }}}. - -Proof. - iIntros (?) "[%Henc Hsl] HΦ". wp_rec. - wp_apply wp_ref_to; first done. - iIntros (l__s) "Hs". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__writeId) "HwriteId". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__server) "Hserver". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__contentHash) "HcontentHash". wp_pures. - - wp_apply wp_ref_of_zero; first done. - iIntros (l__index) "Hindex". wp_pures. - - rewrite Henc. rewrite -?app_assoc. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_apply wp_ref_of_zero; first done. iIntros (contentHashLen) "HcontentHashLen". wp_pures. - wp_apply wp_ref_of_zero; first done. iIntros (contentHashBytes) "HcontentHashBytes". wp_pures. - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). - iIntros (?) "Hsl". wp_pures. wp_store. wp_store. wp_load. wp_load. - - iDestruct (own_slice_small_sz with "Hsl") as %HcontentHash_sz. - wp_apply (wp_ReadBytesCopy with "[$]"). - { rewrite length_app in HcontentHash_sz. word. } - iIntros (??) "[HcontentHash' Hsl]". - - wp_pures. wp_store. wp_store. wp_load. - iApply own_slice_to_small in "HcontentHash'". - wp_apply (wp_StringFromBytes with "[$HcontentHash']"). iIntros "_". - wp_store. - - wp_load. wp_apply (wp_ReadInt with "[$Hsl]"). iIntros (?) "Hsl". - wp_pures. wp_store. wp_store. - - wp_load. wp_load. wp_load. wp_load. wp_load. - wp_pures. iApply "HΦ". iModIntro. rewrite ?string_to_bytes_to_string. iFrame. - iPureIntro. reflexivity. -Qed. - -End recordChunk. -End recordChunk. - From 15923a9875e630dc14073c32b64af0bde179afdd Mon Sep 17 00:00:00 2001 From: Matt Schwennesen Date: Tue, 28 Jan 2025 19:28:25 -0600 Subject: [PATCH 25/25] update tutorial --- .../Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v | 6 +++--- .../mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v | 2 +- .../github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v | 2 +- .../github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v | 2 +- .../Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v | 8 ++++---- .../mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v | 2 +- .../github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v | 2 +- .../gokv/tutorial/objectstore/chunk/writechunk_gk.v | 2 +- .../github_com/mit_pdos/gokv/tutorial/objectstore/dir.v | 4 ++-- .../gokv/tutorial/objectstore/dir/chunkhandle_gk.v | 2 +- .../gokv/tutorial/objectstore/dir/finishwrite_gk.v | 2 +- .../gokv/tutorial/objectstore/dir/recordchunk_gk.v | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v index c2e46983f..cad99ef64 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice.v @@ -68,7 +68,7 @@ Definition Client__getFreshNumRpc: val := Definition Client__putRpc: val := rec: "Client__putRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdPut (put_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdPut (put_gk.Marshal (NewSlice byteT #0) "args") "reply" #100 in (if: "err" = urpc.ErrNone then "err" else "err"). @@ -100,7 +100,7 @@ Definition Clerk__Put: val := Definition Client__conditionalPutRpc: val := rec: "Client__conditionalPutRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdConditionalPut (conditionalput_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdConditionalPut (conditionalput_gk.Marshal (NewSlice byteT #0) "args") "reply" #100 in (if: "err" = urpc.ErrNone then (StringFromBytes (![slice.T byteT] "reply"), "err") else (#(str""), "err")). @@ -139,7 +139,7 @@ Definition Clerk__ConditionalPut: val := Definition Client__getRpc: val := rec: "Client__getRpc" "cl" "args" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdGet (get_gk.Marshal "args" (NewSlice byteT #0)) "reply" #100 in + let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") rpcIdGet (get_gk.Marshal (NewSlice byteT #0) "args") "reply" #100 in (if: "err" = urpc.ErrNone then (StringFromBytes (![slice.T byteT] "reply"), "err") else (#(str""), "err")). diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v index 88de553db..daab05798 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/conditionalput_gk.v @@ -13,7 +13,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "c" "prefix" := + rec: "Marshal" "prefix" "c" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "OpId" "c"));; let: "keyBytes" := StringToBytes (struct.get S "Key" "c") in diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v index 442e52d68..290aae88b 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/get_gk.v @@ -11,7 +11,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "g" "prefix" := + rec: "Marshal" "prefix" "g" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "OpId" "g"));; let: "keyBytes" := StringToBytes (struct.get S "Key" "g") in diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v index 424197f84..f1b193f92 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/kvservice/put_gk.v @@ -12,7 +12,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "p" "prefix" := + rec: "Marshal" "prefix" "p" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "OpId" "p"));; let: "keyBytes" := StringToBytes (struct.get S "Key" "p") in diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v index 804adfc3f..fed4bec29 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice.v @@ -54,9 +54,9 @@ Definition Client__getFreshNum: val := Definition Client__tryAcquire: val := rec: "Client__tryAcquire" "cl" "id" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "args" := lockrequest_gk.Marshal (struct.mk lockrequest_gk.S [ + let: "args" := lockrequest_gk.Marshal (NewSlice byteT #0) (struct.mk lockrequest_gk.S [ "Id" ::= "id" - ]) (NewSlice byteT #0) in + ]) in let: "err" := urpc.Client__Call (struct.loadF Client "cl" "cl") RPC_TRY_ACQUIRE "args" "reply" #100 in (if: "err" = urpc.ErrNone then (DecodeUint64 (![slice.T byteT] "reply"), "err") @@ -65,9 +65,9 @@ Definition Client__tryAcquire: val := Definition Client__release: val := rec: "Client__release" "cl" "id" := let: "reply" := ref (zero_val (slice.T byteT)) in - let: "args" := lockrequest_gk.Marshal (struct.mk lockrequest_gk.S [ + let: "args" := lockrequest_gk.Marshal (NewSlice byteT #0) (struct.mk lockrequest_gk.S [ "Id" ::= "id" - ]) (NewSlice byteT #0) in + ]) in urpc.Client__Call (struct.loadF Client "cl" "cl") RPC_RELEASE "args" "reply" #100. Definition makeClient: val := diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v index dc1fec0d0..f5b1c8b9e 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/lockservice/lockrequest_gk.v @@ -10,7 +10,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "l" "prefix" := + rec: "Marshal" "prefix" "l" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "Id" "l"));; ![slice.T byteT] "enc". diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v index b0bf70aca..910b60555 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk.v @@ -43,7 +43,7 @@ Definition ClerkPool := struct.decl [ Definition ClerkPool__WriteChunk: val := rec: "ClerkPool__WriteChunk" "ck" "addr" "args" := - let: "req" := writechunk_gk.Marshal "args" (NewSlice byteT #0) in + let: "req" := writechunk_gk.Marshal (NewSlice byteT #0) "args" in let: "reply" := ref (zero_val (slice.T byteT)) in connman.ConnMan__CallAtLeastOnce (struct.loadF ClerkPool "cm" "ck") "addr" WriteChunkId "req" "reply" #100;; #(). diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v index 3ac7b22a1..7a1023811 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/chunk/writechunk_gk.v @@ -12,7 +12,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "w" "prefix" := + rec: "Marshal" "prefix" "w" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "WriteId" "w"));; "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (slice.len (struct.get S "Chunk" "w")));; diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v index 7a979657b..fc8f0803f 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir.v @@ -110,7 +110,7 @@ Definition Clerk__PrepareWrite: val := (* From chunk *) Definition Clerk__RecordChunk: val := rec: "Clerk__RecordChunk" "ck" "args" := - let: "req" := recordchunk_gk.Marshal "args" (NewSlice byteT #0) in + let: "req" := recordchunk_gk.Marshal (NewSlice byteT #0) "args" in let: "reply" := ref (zero_val (slice.T byteT)) in reconnectclient.ReconnectingClient__Call (struct.loadF Clerk "client" "ck") RecordChunkId "req" "reply" #100;; #(). @@ -118,7 +118,7 @@ Definition Clerk__RecordChunk: val := (* From chunk *) Definition Clerk__FinishWrite: val := rec: "Clerk__FinishWrite" "ck" "args" := - let: "req" := finishwrite_gk.Marshal "args" (NewSlice byteT #0) in + let: "req" := finishwrite_gk.Marshal (NewSlice byteT #0) "args" in let: "reply" := ref (zero_val (slice.T byteT)) in reconnectclient.ReconnectingClient__Call (struct.loadF Clerk "client" "ck") FinishWriteId "req" "reply" #100;; #(). diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v index 960fd4625..a0e2568d5 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/chunkhandle_gk.v @@ -11,7 +11,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "c" "prefix" := + rec: "Marshal" "prefix" "c" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "Addr" "c"));; let: "contenthashBytes" := StringToBytes (struct.get S "ContentHash" "c") in diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v index afcc6bda9..169d63427 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/finishwrite_gk.v @@ -11,7 +11,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "f" "prefix" := + rec: "Marshal" "prefix" "f" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "WriteId" "f"));; let: "keynameBytes" := StringToBytes (struct.get S "Keyname" "f") in diff --git a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v index 6b965846e..63edd4ed9 100644 --- a/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v +++ b/external/Goose/github_com/mit_pdos/gokv/tutorial/objectstore/dir/recordchunk_gk.v @@ -13,7 +13,7 @@ Definition S := struct.decl [ ]. Definition Marshal: val := - rec: "Marshal" "r" "prefix" := + rec: "Marshal" "prefix" "r" := let: "enc" := ref_to (slice.T byteT) "prefix" in "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "WriteId" "r"));; "enc" <-[slice.T byteT] (marshal.WriteInt (![slice.T byteT] "enc") (struct.get S "Server" "r"));;