From 2cadde8892f3f798479c2bbca6ce215e2383c639 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 11 Dec 2023 22:11:24 -0800 Subject: [PATCH] feat: Tighten specifications on Strings standard library (#4868) ### Description As follow-up from the initial review, this adds a bodiless `CharsConsistent` lemma to the abstract `Std.Strings.ParametricConversion` module that ensures `chars` and `charsToDigits` are consistent, which is necessary but not sufficient to prove that `forall n :: ToInt(OfInt(n)) == n`. Also makes some documentation and naming improvements, adding an `IsDigitChar` predicate for better readability than `c in charsToDigit` (which is slightly different from `c in chars`) and merges the two confusingly-named `ToNumberStr` and `OfNumberStr` predicate into one `IsNumberStr` (with the definition of the former, weaker predicate). ### How has this been tested? Existing tests + verification. --- .../binaries/DafnyStandardLibraries-cs.doo | Bin 1337 -> 1337 bytes .../binaries/DafnyStandardLibraries-go.doo | Bin 1363 -> 1363 bytes .../binaries/DafnyStandardLibraries-java.doo | Bin 1334 -> 1334 bytes .../binaries/DafnyStandardLibraries-js.doo | Bin 1858 -> 1858 bytes .../DafnyStandardLibraries-notarget.doo | Bin 1310 -> 1310 bytes .../binaries/DafnyStandardLibraries-py.doo | Bin 1305 -> 1305 bytes .../binaries/DafnyStandardLibraries.doo | Bin 56833 -> 56937 bytes .../src/Std/JSON/ByteStrConversion.dfy | 4 ++ .../src/Std/JSON/Deserializer.dfy | 4 ++ .../src/Std/JSON/Spec.dfy | 2 +- .../src/Std/Strings.dfy | 50 +++++++++++------- 11 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo index 9d33f712f292205b6159187acd450f835ea4bd39..815f253050bbc2c9db9107e5f8286524b048ef20 100644 GIT binary patch delta 41 tcmdnVwUdh{z?+#xgn@y9gQ2l)BF{yp#TLAd$4YdFO delta 41 tcmdnVwUdh{z?+#xgn@y9gCR0)BF{yp$h3|3A20){$p=|1LDU}>TL9-H43z)? diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo index 58789cb25e64bab62c2c2369f1889c48624d2338..245f678b5738aba8d635bb1700e880b74d6e0e78 100644 GIT binary patch delta 41 tcmcc2b(xDNz?+#xgn@y9gQ2BuBF{ypmbQ)ee=!58$+uZ7L6jJ)EdT-04MYF{ delta 41 tcmcc2b(xDNz?+#xgn@y9gCQnuBF{ypn6!=ee=!58$+uZ7L6jJ)EdcNO3?u*m diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-java.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-java.doo index a58887ff468a80298403562e6f0305b6b4835aeb..6059092c78f7777a44fad8890310c6bf771a1210 100644 GIT binary patch delta 41 tcmdnSwT+7>z?+#xgn@y9gQ2NyBF{yprnZgu?=l0a$@^F=LDWwcTLAav4XOYD delta 41 tcmdnSwT+7>z?+#xgn@y9gCQzyBF{ypsI-mu?=l0a$@^F=LDWwcTL9)A42l2% diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo index 01ceb428541af0a7284911c3b9175b9ea58d1811..48df0950419441245e38f909519e48d29e577290 100644 GIT binary patch delta 41 tcmX@acZiQCz?+#xgn@y9gQ2-?BF{yp=C+OZU$O$J$*0&XK@=;yEdcwl4EX>6 delta 41 tcmX@acZiQCz?+#xgn@y9gCRO?BF{yp=(LUZU$O$J$*0&XK@=;yEdc503)uhw diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-notarget.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-notarget.doo index e8d767a1a4d6f3504ee8ac0477bd460a561b5f8c..f320bf2c8ec31c63c8c70b85258239f96c30bd9a 100644 GIT binary patch delta 41 tcmbQoHIIuYz?+#xgn@y9gQ1~qBF{yphPI9Ok1_+P$;((QLDWMQTLA4V4JrTt delta 41 tcmbQoHIIuYz?+#xgn@y9gCQbqBF{yph_sFOk1_+P$;((QLDWMQTL9Z*3<>}M diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-py.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-py.doo index 54b0913b674b936c2fd5eff9588139e6aae12148..a6de78d0e2b92c98493e4eed037b4877a99547be 100644 GIT binary patch delta 41 tcmbQqHIs`cz?+#xgn@y9gQ2x;BF{yp*0zoJ4=@9%$qQL5LDU@(GGlui&xS)$&KsW001X?vFj~(f3@vR z9Ls{=`4tmB97{oHE!z-cgY!6Ga(phqTx?G6uH%QRmoW%r$!KI_g4y4`T~+;3)h{z6 zS%ze9cJB#RPj_`yb#--hb#?W5SW>)=6g}-0LCwioq;waB8#vP+DO*{5e7Li%1&rML znE3<VRfBy5f0aW|2 zEbb9_f}@`W>YF@2EaIa|R-G=;KzSjM3I$3rXFKfH0FK3`9E&Z^3%ftxfk1SdVMb~8 zoB}D}j*A_28*7e`I5!h z%t38MSW9XO0=)9+MLy6B9^@z8^U(|+xr=eRjFa^^xBzb!8UsU^P&0R(c<^;zO{~Xk z;+g7(y%dXY0d9->ce%vz0DWF*+X2-zoeR_J{0WV~b6476HG&LOf6A^A9XVQE4=>fC zJeu?yd~jP?8mc!3X_aeK$$~A%5#F{s(aOkw(|SD5bfa~`=Uq~i?5l=xEe-X|?`pAw z)NFe7F;APhVKa&w|Gn!jIeRlvf{0B+V_KAHrBB$%*Yctv|G8GJFbDkuS>47^h>p2yX{6 zb;R=E)tCiw^%p1~x0m>D5GeHzt^V+%-Vk!xW}QX{8lZ;PuG9cL!M@cWT;~%){<0%W zodL-DKF%7iv;Xyd_WEKq`~H7rm?hZpwJEr2z&@UweS!#{e?|_ zFmV&sGe3pOvImBv?jS15*0S&A*ha<5i0Gnb%o3!;AOEy&EMZ(z%1(R%FKr*2dv@fN zR6G&;LM3KuV?K*dJp5$#WDijapSXQqy!OMu;BomxOZSNWh(s8#cYfH>v7U@icv-AI ze$kg#f%&3Pe{$QL=AjjB5@YGz1ySczqi2^JOsFJwf-Idd)^CF#!)w_(yeJXplnU2K z1TD$XB%;Bz>9n%TH5Sx)(zv9j6xAPV^4j$!rhC3zyOoGOeLOimJ)d5qHAvqq;YqO?*sS86e1zVW^MtaUAz^r5V@P^eK?l zjlE(XG8FJQ9U4nO%#q^D!V}p2>cQ!0cO{{(WC2KY6*%II@F>$QHWI!P3Rd7Kxh1{d z1f3N);#nbw#EMPV8RLnX33GbFcc;_Il>62{e{T+kMYlJ~pHIf4;W+P3cc#PHTO}I9 z{uejrepb9Ym_a%hcq{}s4EemrYE%#K4UD4wqC4%XR?}ghRRaE@hcoNH?M}&?xU#we zizkdmD_iOCA8Y)_I{&f3f866g?(-i%@E;HOk00%iV}aA*Lfq-G@f-Y+i)Kmq1$=f6<0N)$9dOOp%~u7L72*>j1s#=hNXq{4V z38Zk4fxa2LEvab}#0lDbLua5we*nThqloiEXT=P>=+&9IzJoMs5@+VNq@~c*t4QT) z+bW@91VJHPC_On0DgSxe?Y~!ZWAN}vD?2bl>q@m?sEw8S+%hu+_@Zq3^HU{g=O-t_ zOVeI3%1B#^M-OrAkVy#4W0WtXe{Ld-d=jyg_ND|1D#Thwrq6%mpK!_4q`x!2W77qW z>k-cTR0sXZXfnoWYhku8!cLzm2Ad8~)ZZm);Y_X5lY!I(^f1O>C7qlO$LB=|7861%y+I{FdJCE1eNY6nfS{0 ze{x!#YYru`ktQ^`SQ9qe%yjgc5Vu(q&3^o-xEE=H9AhnrgJfGwr%vadc4z&!q@0ac z2jg*`pN~e3u?WV&IW%taT0c)Fqed^R)f2T0PZT?NO;#*>Ms}bEe_^#*F|X|eQPgI| zytb7iQQ4JZkrycTYJ4&o4Nw>~4i`o?)+CA0!j>e$v^RoRmk2ph;wLAfQ;P^1vLp>8{YesZYdI6D zDG<`be{uZRV)(n4e=TVvznN(_Qp!q4e}tt??D>^_oV}V2N3_xuYRf~>R He^EQ@ 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 DM>rsI delta 25987 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 CGfMja diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/ByteStrConversion.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/ByteStrConversion.dfy index 05ed37a44dd..a9dc9bc2676 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/ByteStrConversion.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/ByteStrConversion.dfy @@ -22,4 +22,8 @@ module {:disableNonlinearArithmetic} Std.JSON.ByteStrConversion refines Strings. '4' as byte := 4, '5' as byte := 5, '6' as byte := 6, '7' as byte := 7, '8' as byte := 8, '9' as byte := 9 ] + + lemma CharsConsistent() + ensures forall c <- chars :: c in charToDigit && chars[charToDigit[c]] == c + {} } \ No newline at end of file diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy index ced3e61bd0c..dd3641eb7f9 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy @@ -50,6 +50,10 @@ module Std.JSON.Deserializer { 'a' as uint16 := 0xA, 'b' as uint16 := 0xB, 'c' as uint16 := 0xC, 'd' as uint16 := 0xD, 'e' as uint16 := 0xE, 'f' as uint16 := 0xF, 'A' as uint16 := 0xA, 'B' as uint16 := 0xB, 'C' as uint16 := 0xC, 'D' as uint16 := 0xD, 'E' as uint16 := 0xE, 'F' as uint16 := 0xF ] + + // The size of the map makes this impractical to verify easily. + lemma {:axiom} CharsConsistent() + ensures forall c <- chars :: c in charToDigit && chars[charToDigit[c]] == c } const HEX_TABLE_16 := Uint16StrConversion.charToDigit diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/Spec.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/Spec.dfy index 9b1be70bba7..7183a4bb2e6 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/Spec.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/Spec.dfy @@ -74,7 +74,7 @@ module Std.JSON.Spec { if i == 0 { } else { var isHexDigit := c => c in Strings.HexConversion.HEX_DIGITS; - assert Strings.HexConversion.OfNumberStr(s, '-'); + assert Strings.HexConversion.IsNumberStr(s, '-'); assert isHexDigit(s[i]); } } diff --git a/Source/DafnyStandardLibraries/src/Std/Strings.dfy b/Source/DafnyStandardLibraries/src/Std/Strings.dfy index f479eb2d430..a9acc6b46f0 100644 --- a/Source/DafnyStandardLibraries/src/Std/Strings.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Strings.dfy @@ -11,7 +11,7 @@ module {:disableNonlinearArithmetic} Std.Strings { Refine this module to use it. The refinee must define: - the type of character used, Char - - a conversion from nat to Char and vice versa + - a conversion from nat to Char (the chars sequences) and vice versa (charToDigit) */ abstract module {:disableNonlinearArithmetic} ParametricConversion refines Arithmetic.LittleEndianNat { import opened Wrappers @@ -20,16 +20,25 @@ module {:disableNonlinearArithmetic} Std.Strings { type String = seq type CharSeq = chars: seq | |chars| > 1 witness * + // Canoncial digit characters: converting to strings will uses these characters. const chars: CharSeq const base := |chars| + // All recognized digit characters: converting from strings will use this map, + // which may associate multiple characters with the same digit. const charToDigit: map + lemma CharsConsistent() + ensures forall c <- chars :: c in charToDigit && chars[charToDigit[c]] == c + function BASE(): nat { base } + predicate IsDigitChar(c: Char) { + c in charToDigit + } + function OfDigits(digits: seq) : (str: String) - requires forall d | d in digits :: 0 <= d < base ensures forall c <- str :: c in chars ensures |str| == |digits| { @@ -51,16 +60,10 @@ module {:disableNonlinearArithmetic} Std.Strings { else LemmaFromNatLen2(n); OfDigits(FromNat(n)) } - predicate OfNumberStr(str: String, minus: Char) { - str != [] ==> - && (str[0] == minus || str[0] in chars) - && forall c <- str[1..] :: c in chars - } - - predicate ToNumberStr(str: String, minus: Char) { + predicate IsNumberStr(str: String, minus: Char) { str != [] ==> && (str[0] == minus || str[0] in charToDigit) - && forall c <- str[1..] :: c in charToDigit + && forall c <- str[1..] :: IsDigitChar(c) } /* @@ -68,8 +71,9 @@ module {:disableNonlinearArithmetic} Std.Strings { given a particular minus character. */ function OfInt(n: int, minus: Char) : (str: String) - ensures OfNumberStr(str, minus) + ensures IsNumberStr(str, minus) { + CharsConsistent(); if n >= 0 then OfNat(n) else [minus] + OfNat(-n) } @@ -78,18 +82,19 @@ module {:disableNonlinearArithmetic} Std.Strings { Convert a String that represents a natural number, back into that number. */ function {:vcs_split_on_every_assert} ToNat(str: String) : (n: nat) - requires forall c <- str :: c in charToDigit + requires forall c <- str :: IsDigitChar(c) { if str == [] then 0 else LemmaMulNonnegativeAuto(); - ToNat(str[..|str| - 1]) * base + charToDigit[str[|str| - 1]] + var c := str[|str| - 1]; + assert IsDigitChar(c); + ToNat(str[..|str| - 1]) * base + charToDigit[c] } lemma {:induction false} ToNatBound(str: String) requires base > 0 - requires forall c <- str :: c in charToDigit - requires forall c <- str :: charToDigit[c] < base + requires forall c <- str :: IsDigitChar(c) ensures ToNat(str) < Pow(base, |str|) { if str == [] { @@ -97,6 +102,7 @@ module {:disableNonlinearArithmetic} Std.Strings { } else { calc <= { ToNat(str); + { assert IsDigitChar(str[|str| - 1]); } ToNat(str[..|str| - 1]) * base + charToDigit[str[|str| - 1]]; ToNat(str[..|str| - 1]) * base + (base - 1); { ToNatBound(str[..|str| - 1]); @@ -115,7 +121,7 @@ module {:disableNonlinearArithmetic} Std.Strings { */ function ToInt(str: String, minus: Char): (s: int) requires str != [minus] - requires ToNumberStr(str, minus) + requires IsNumberStr(str, minus) { if [minus] <= str then -(ToNat(str[1..]) as int) else @@ -172,6 +178,9 @@ module {:disableNonlinearArithmetic} Std.Strings { 'a' := 0xA, 'b' := 0xB, 'c' := 0xC, 'd' := 0xD, 'e' := 0xE, 'f' := 0xF, 'A' := 0xA, 'B' := 0xB, 'C' := 0xC, 'D' := 0xD, 'E' := 0xE, 'F' := 0xF ] + // The size of the map makes this impractical to verify easily. + lemma {:axiom} CharsConsistent() + ensures forall c <- chars :: c in charToDigit && chars[charToDigit[c]] == c } module {:disableNonlinearArithmetic} DecimalConversion refines ParametricConversion { @@ -182,6 +191,9 @@ module {:disableNonlinearArithmetic} Std.Strings { map[ '0' := 0, '1' := 1, '2' := 2, '3' := 3, '4' := 4, '5' := 5, '6' := 6, '7' := 7, '8' := 8, '9' := 9 ] + lemma CharsConsistent() + ensures forall c <- chars :: c in charToDigit && chars[charToDigit[c]] == c + {} } module CharStrEscaping refines ParametricEscaping { @@ -202,7 +214,7 @@ module {:disableNonlinearArithmetic} Std.Strings { Convert an integer into its String representation for a decimal number system */ function OfInt(n: int) : (str: string) - ensures DecimalConversion.OfNumberStr(str, '-') + ensures DecimalConversion.IsNumberStr(str, '-') { DecimalConversion.OfInt(n, '-') } @@ -211,7 +223,7 @@ module {:disableNonlinearArithmetic} Std.Strings { Given a natural number represented as a decimal number in a String, back into an integer */ function ToNat(str: string) : (n: nat) - requires forall c <- str :: c in DecimalConversion.charToDigit && DecimalConversion.charToDigit[c] as int < DecimalConversion.base + requires forall c <- str :: DecimalConversion.IsDigitChar(c) ensures n < Pow(DecimalConversion.base, |str|) { DecimalConversion.ToNatBound(str); @@ -223,7 +235,7 @@ module {:disableNonlinearArithmetic} Std.Strings { */ function ToInt(str: string) : (n: int) requires str != "-" - requires DecimalConversion.ToNumberStr(str, '-') + requires DecimalConversion.IsNumberStr(str, '-') { DecimalConversion.ToInt(str, '-') }