diff --git a/.github/workflows/test-dafny-all.yml b/.github/workflows/test-dafny-all.yml index e7c7d86..06634bf 100644 --- a/.github/workflows/test-dafny-all.yml +++ b/.github/workflows/test-dafny-all.yml @@ -13,5 +13,7 @@ jobs: uses: cachix/install-nix-action@v20 - name: Test that all dafny files are named correctly run: nix run .#dafny-namecheck + - name: Test that all dafny files contain an impl + run: nix run .#check-contains-impl - name: Run Dafny on all files run: nix run .#dafny-check diff --git a/.github/workflows/test-dafny-new.yml b/.github/workflows/test-dafny-new.yml index d717c0a..ac0a2f7 100644 --- a/.github/workflows/test-dafny-new.yml +++ b/.github/workflows/test-dafny-new.yml @@ -16,6 +16,8 @@ jobs: uses: tj-actions/changed-files@v45 - name: Test that all dafny files are named correctly run: nix run .#dafny-namecheck + - name: Test that all dafny files contain an impl + run: nix run .#check-contains-impl - name: Run Dafny on new files env: diff --git a/023-strlen.dfy b/023-strlen.dfy index c380e30..478cd56 100644 --- a/023-strlen.dfy +++ b/023-strlen.dfy @@ -1,5 +1,9 @@ function strlen(s: string) : (len: int) + // post-conditions-start ensures len == |s| + // post-conditions-end { + // impl-start |s| + // impl-end } diff --git a/025-factorize.dfy b/025-factorize.dfy index ba4f214..6ea82bc 100644 --- a/025-factorize.dfy +++ b/025-factorize.dfy @@ -3,31 +3,40 @@ function prod(s: seq) : int { } method factorize(n: nat) returns (factors: seq) + // pre-conditions-start requires n > 0 + // pre-conditions-end + // post-conditions-start ensures prod(factors) == n + // post-conditions-end { + // impl-start factors := []; ghost var taken := 1; var cur := n; var i := 2; while i * i <= cur + // invariants-start invariant prod(factors) == taken invariant taken * cur == n invariant cur >= 1 + // invariants-end { ghost var pre := cur; ghost var temp := 1; while cur % i == 0 + // invariants-start invariant cur >= 1 invariant temp * cur == pre invariant prod(factors) == taken * temp + // invariants-end decreases cur - 1 { factors := factors + [i]; cur := cur / i; temp := temp * i; - assert 2 <= i && 2 * cur <= i * cur; + assert 2 <= i && 2 * cur <= i * cur; // assert-line } taken := taken * temp; i := i + 1; @@ -36,5 +45,6 @@ method factorize(n: nat) returns (factors: seq) factors := factors + [cur]; taken := taken * cur; } - assert taken == n; + assert taken == n; // assert-line + // impl-end } \ No newline at end of file diff --git a/flake.nix b/flake.nix index 8572ea8..4608228 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,23 @@ done ''; + check-contains-impl = pkgs.writeShellScriptBin "check-contains-impl" '' + DIR=''${1:-.} + + for file in "$DIR"/*.dfy; do + if [[ -e $file ]]; then + filename=$(basename "$file") + + if ! ${pkgs.gnugrep}/bin/grep -q "// impl-start" "$file"; then + echo "File $file does not contain an impl, please recheck if it was marked" + exit 1 + fi + fi + done + + echo "All dafny files contain an impl." + ''; + dafny-check-new = pkgs.writeShellScriptBin "dafny-check" '' file_count=0