From 4a34e970fb224be7640883f6b0dfa602157759f4 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 10:39:45 +0000 Subject: test(overload): add randomized differential coverage Co-Authored-By: Claude Opus 5.5 --- tests/ii/generator-vectors.json | 2 + tests/ii/overload-functions/arrays.cps | 21 +++++++++ tests/ii/overload-functions/case.json | 3 ++ tests/ii/overload-functions/generate.pl | 20 +++++++++ tests/ii/overload-functions/notes.md | 7 +++ tests/ii/overload-functions/program.cps | 33 ++++++++++++++ tests/ii/overload-functions/reference.cc | 19 ++++++++ tests/ii/overload-functions/scalar.cps | 15 +++++++ tests/ii/overload-methods/case.json | 1 + tests/ii/overload-methods/generate.pl | 19 ++++++++ tests/ii/overload-methods/notes.md | 7 +++ tests/ii/overload-methods/program.cps | 75 ++++++++++++++++++++++++++++++++ tests/ii/overload-methods/reference.cc | 21 +++++++++ 13 files changed, 243 insertions(+) create mode 100644 tests/ii/overload-functions/arrays.cps create mode 100644 tests/ii/overload-functions/case.json create mode 100644 tests/ii/overload-functions/generate.pl create mode 100644 tests/ii/overload-functions/notes.md create mode 100644 tests/ii/overload-functions/program.cps create mode 100644 tests/ii/overload-functions/reference.cc create mode 100644 tests/ii/overload-functions/scalar.cps create mode 100644 tests/ii/overload-methods/case.json create mode 100644 tests/ii/overload-methods/generate.pl create mode 100644 tests/ii/overload-methods/notes.md create mode 100644 tests/ii/overload-methods/program.cps create mode 100644 tests/ii/overload-methods/reference.cc (limited to 'tests') diff --git a/tests/ii/generator-vectors.json b/tests/ii/generator-vectors.json index 8d08da7..d6a95a6 100644 --- a/tests/ii/generator-vectors.json +++ b/tests/ii/generator-vectors.json @@ -4,6 +4,8 @@ "calls": "1933d62e59a50ab51eca103b012ba69064651de0af06b62ff48a6235c47405ee", "files": "0addc4652097fed574bdc5c0e9d59f237d49dcb7b92638dde146adde04bc6042", "native-types": "649e978c2ccc0d4de66e2a69b8f98131015fb77c371ce4749d6278ffd84287f2", + "overload-functions": "1c2c3aedfed36812d8f7cd1648046b134eebac1fd73260558ed4d486e3d72c6e", + "overload-methods": "f02d8d7e31c3c03ccf647d7e2bda18cdedd706db38308cdd35f8a3b5f87b2905", "real": "8ffb0244589eff8a1d873ca6f1e1d66cc84944ab68d8bfafa118e941891ac518", "strings": "c8b1aa74413d7e2a673baa27e495745b5fdf799ba423e0180620b8427cd1c42a" } diff --git a/tests/ii/overload-functions/arrays.cps b/tests/ii/overload-functions/arrays.cps new file mode 100644 index 0000000..47ff46c --- /dev/null +++ b/tests/ii/overload-functions/arrays.cps @@ -0,0 +1,21 @@ +OVERLOAD FUNCTION Score(Values : ARRAY OF INTEGER, First : INTEGER, Size : INTEGER) RETURNS INTEGER + DECLARE I : INTEGER + DECLARE Total : INTEGER + Total <- 0 + FOR I <- First TO First + Size - 1 + Total <- Total + Values[I] + NEXT I + RETURN Total +ENDFUNCTION +OVERLOAD FUNCTION Score(Values : ARRAY OF REAL, First : INTEGER, Size : INTEGER) RETURNS BOOLEAN + DECLARE I : INTEGER + DECLARE Total : REAL + Total <- 0.0 + FOR I <- First TO First + Size - 1 + Total <- Total + Values[I] + NEXT I + RETURN Total > 0.0 +ENDFUNCTION +OVERLOAD FUNCTION Score(Values : ARRAY[1:2,1:2] OF INTEGER, First : INTEGER, Size : INTEGER) RETURNS INTEGER + RETURN Values[1,1] + 2 * Values[1,2] + 3 * Values[2,1] + 4 * Values[2,2] +ENDFUNCTION diff --git a/tests/ii/overload-functions/case.json b/tests/ii/overload-functions/case.json new file mode 100644 index 0000000..073cfee --- /dev/null +++ b/tests/ii/overload-functions/case.json @@ -0,0 +1,3 @@ +{ + "sources": ["program.cps", "scalar.cps", "arrays.cps"] +} diff --git a/tests/ii/overload-functions/generate.pl b/tests/ii/overload-functions/generate.pl new file mode 100644 index 0000000..33ca9f3 --- /dev/null +++ b/tests/ii/overload-functions/generate.pl @@ -0,0 +1,20 @@ +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/.."; +use Random; +my ($seed, $count) = @ARGV; +my $rng = Random->new($seed, "overload-functions"); +my @edges = ( + '0 0 1 0 x', + '-1000 1000 8 -8 boundary', + '1000 -1000 8 8 z', + '-7 2 8 -3 cancellation', + '1 -2 2 0 pair', + '-1 2 2 -1 positive', +); +$rng->emit($count, \@edges, sub { + return join ' ', $rng->integer(-1000,1000), $rng->integer(-1000,1000), + $rng->integer(1,8), $rng->integer(-8,8), + 'x' x $rng->integer(1,24); +}); diff --git a/tests/ii/overload-functions/notes.md b/tests/ii/overload-functions/notes.md new file mode 100644 index 0000000..54b3f5d --- /dev/null +++ b/tests/ii/overload-functions/notes.md @@ -0,0 +1,7 @@ +# overload-functions + +OVERLOAD is a project extension. The scalar and array overloads of Score are defined in separate imported files. Each input record exercises INTEGER, REAL and STRING argument types; different argument counts; FUNCTION and PROCEDURE sharing a name; BYREF scalar mutation; array element types and ranks; case-insensitive calls; and nested calls whose static result type selects the outer overload. + +Inputs are A, B, Size, Lower and a nonempty ASCII string. Integer array elements form the progression A + k*B for k from 0 to Size-1. REAL elements are those exact integers divided by eight. The independent C++ oracle uses the closed-form progression sum Size*A + B*Size*(Size-1)/2, its sign, and the simplified weighted matrix sum 8*A+B. The nested scalar result is 9*A+4, and the BYREF procedure changes only its destination to A+B*Size. + +Each record emits one colon-separated line. A and B stay within [-1000,1000], Size within [1,8], and Lower within [-8,8]; all arithmetic is safely bounded. Binary fractions are exactly representable, and REAL results are observed through BOOLEAN output. Fixed records cover zero, range endpoints, changing array bounds, positive/negative totals and exact cancellation. The SHA-256 generator adds the requested random count. diff --git a/tests/ii/overload-functions/program.cps b/tests/ii/overload-functions/program.cps new file mode 100644 index 0000000..ea94a93 --- /dev/null +++ b/tests/ii/overload-functions/program.cps @@ -0,0 +1,33 @@ +INCLUDE "scalar.cps" +INCLUDE "arrays.cps" +DECLARE Count : INTEGER +DECLARE Row : INTEGER +DECLARE A : INTEGER +DECLARE B : INTEGER +DECLARE Size : INTEGER +DECLARE Lower : INTEGER +DECLARE Text : STRING +DECLARE I : INTEGER +DECLARE Changed : INTEGER +INPUT Count +FOR Row <- 1 TO Count + INPUT A + INPUT B + INPUT Size + INPUT Lower + INPUT Text + DECLARE Integers : ARRAY[Lower:Lower+Size-1] OF INTEGER + DECLARE Reals : ARRAY[Lower:Lower+Size-1] OF REAL + DECLARE Matrix : ARRAY[1:2,1:2] OF INTEGER + FOR I <- Lower TO Lower + Size - 1 + Integers[I] <- A + (I - Lower) * B + Reals[I] <- (A + (I - Lower) * B) / 8 + NEXT I + Matrix[1,1] <- A + Matrix[1,2] <- B + Matrix[2,1] <- A + B + Matrix[2,2] <- A - B + Changed <- A + CALL sCoRe(Changed, B, Size) + OUTPUT Score(A), ":", Score(A / 8), ":", Score(Text), ":", Score(A, B), ":", Score(Integers, Lower, Size), ":", Score(Reals, Lower, Size), ":", Score(Matrix, Lower, Size), ":", Score(Score(A)), ":", Changed, ":", A +NEXT Row diff --git a/tests/ii/overload-functions/reference.cc b/tests/ii/overload-functions/reference.cc new file mode 100644 index 0000000..2b4b03f --- /dev/null +++ b/tests/ii/overload-functions/reference.cc @@ -0,0 +1,19 @@ +#include +#include +#include + +int main() { + int count; + if (!(std::cin >> count)) return 1; + for (int row = 0; row < count; ++row) { + std::int64_t a, b, size, lower; + std::string text; + if (!(std::cin >> a >> b >> size >> lower >> text)) return 1; + // Closed forms are independent of the pseudocode's loops and dispatch. + const auto sum = size * a + b * size * (size - 1) / 2; + std::cout << 3 * a + 1 << ':' << (a < 0 ? "TRUE" : "FALSE") << ':' + << text.size() + 100 << ':' << 17 * a + b << ':' << sum << ':' + << (sum > 0 ? "TRUE" : "FALSE") << ':' << 8 * a + b << ':' + << 9 * a + 4 << ':' << a + b * size << ':' << a << '\n'; + } +} diff --git a/tests/ii/overload-functions/scalar.cps b/tests/ii/overload-functions/scalar.cps new file mode 100644 index 0000000..6953662 --- /dev/null +++ b/tests/ii/overload-functions/scalar.cps @@ -0,0 +1,15 @@ +OVERLOAD FUNCTION Score(X : INTEGER) RETURNS INTEGER + RETURN 3 * X + 1 +ENDFUNCTION +OVERLOAD FUNCTION Score(X : REAL) RETURNS BOOLEAN + RETURN X < 0.0 +ENDFUNCTION +OVERLOAD FUNCTION Score(Text : STRING) RETURNS INTEGER + RETURN LENGTH(Text) + 100 +ENDFUNCTION +OVERLOAD FUNCTION Score(X : INTEGER, Y : INTEGER) RETURNS INTEGER + RETURN 17 * X + Y +ENDFUNCTION +OVERLOAD PROCEDURE Score(BYREF Value : INTEGER, BYVAL Delta : INTEGER, Repetitions : INTEGER) + Value <- Value + Delta * Repetitions +ENDPROCEDURE diff --git a/tests/ii/overload-methods/case.json b/tests/ii/overload-methods/case.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/ii/overload-methods/case.json @@ -0,0 +1 @@ +{} diff --git a/tests/ii/overload-methods/generate.pl b/tests/ii/overload-methods/generate.pl new file mode 100644 index 0000000..6ea50f2 --- /dev/null +++ b/tests/ii/overload-methods/generate.pl @@ -0,0 +1,19 @@ +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/.."; +use Random; +my ($seed, $count) = @ARGV; +my $rng = Random->new($seed, "overload-methods"); +my @edges = ( + '0 0 1 x', + '-1000 1000 8 boundary', + '1000 -1000 8 z', + '0 24 2 equal', + '0 23 2 below', + '0 25 2 above', +); +$rng->emit($count, \@edges, sub { + return join ' ', $rng->integer(-1000,1000), $rng->integer(-1000,1000), + $rng->integer(1,8), 'x' x $rng->integer(1,24); +}); diff --git a/tests/ii/overload-methods/notes.md b/tests/ii/overload-methods/notes.md new file mode 100644 index 0000000..627e2f7 --- /dev/null +++ b/tests/ii/overload-methods/notes.md @@ -0,0 +1,7 @@ +# overload-methods + +OVERLOAD is a project extension. Each record exercises NEW with zero arguments, INTEGER, STRING and two INTEGER arguments; overloaded getters with different result types; overloaded setters; nested this.Get/this.Set calls; explicit constructor calls; keyword NEW and DELETE; and parameterless construction of record fields and array elements. + +Inputs are A, B, Size and a nonempty ASCII string. The independent C++ oracle models resulting values directly: default construction yields 5, INTEGER construction yields 2*A+3, STRING construction yields length+20, and two-argument construction yields A-B. Default array values sum to 5*Size. Get(INTEGER) adds 3*B; Get(REAL) compares the stored value with B/8; Get(STRING) appends an exclamation mark. Set(STRING) stores length. Set(A) followed by Apply(B) yields A+3*B. Explicit NEW(STRING) rebuilds the receiver's value as length+20. + +Each record emits one colon-separated line. A and B stay within [-1000,1000], Size within [1,8], and string length within [1,24] for random records. All arithmetic is safely bounded; REAL comparisons use exactly representable binary fractions. Fixed records include equal, immediately smaller and immediately larger comparison thresholds, zero and range endpoints. The SHA-256 generator adds the requested random count. diff --git a/tests/ii/overload-methods/program.cps b/tests/ii/overload-methods/program.cps new file mode 100644 index 0000000..5594cf0 --- /dev/null +++ b/tests/ii/overload-methods/program.cps @@ -0,0 +1,75 @@ +CLASS Meter + PRIVATE Value : INTEGER + PUBLIC OVERLOAD PROCEDURE NEW() + Value <- 5 + ENDPROCEDURE + PUBLIC OVERLOAD PROCEDURE NEW(X : INTEGER) + Value <- 2 * X + 3 + ENDPROCEDURE + PUBLIC OVERLOAD PROCEDURE NEW(Text : STRING) + Value <- LENGTH(Text) + 20 + ENDPROCEDURE + PUBLIC OVERLOAD PROCEDURE NEW(X : INTEGER, Y : INTEGER) + Value <- X - Y + ENDPROCEDURE + PUBLIC OVERLOAD FUNCTION Get() RETURNS INTEGER + RETURN Value + ENDFUNCTION + PUBLIC OVERLOAD FUNCTION Get(X : INTEGER) RETURNS INTEGER + RETURN Value + 3 * X + ENDFUNCTION + PUBLIC OVERLOAD FUNCTION Get(X : REAL) RETURNS BOOLEAN + RETURN Value > X + ENDFUNCTION + PUBLIC OVERLOAD FUNCTION Get(Text : STRING) RETURNS STRING + RETURN Text & "!" + ENDFUNCTION + PUBLIC OVERLOAD PROCEDURE Set(X : INTEGER) + Value <- X + ENDPROCEDURE + PUBLIC OVERLOAD PROCEDURE Set(Text : STRING) + Value <- LENGTH(Text) + ENDPROCEDURE + PUBLIC PROCEDURE Apply(X : INTEGER) + CALL this.Set(this.Get(X)) + ENDPROCEDURE +ENDCLASS +TYPE Holder + DECLARE Item : Meter +ENDTYPE +DECLARE Count : INTEGER +DECLARE Row : INTEGER +DECLARE A : INTEGER +DECLARE B : INTEGER +DECLARE Size : INTEGER +DECLARE Text : STRING +DECLARE I : INTEGER +DECLARE Total : INTEGER +INPUT Count +FOR Row <- 1 TO Count + INPUT A + INPUT B + INPUT Size + INPUT Text + DECLARE DefaultItem : Meter + DECLARE NumberItem : Meter(A) + DECLARE TextItem : Meter(Text) + DECLARE PairItem : Meter(A, B) + DECLARE Wrapped : Holder + DECLARE Items : ARRAY[1:Size] OF Meter + DECLARE ChangedNumber : Meter(A) + DECLARE ChangedText : Meter(Text) + DECLARE Rebuilt : Meter(A, B) + DECLARE HeapItem : Meter + Total <- 0 + FOR I <- 1 TO Size + Total <- Total + Items[I].Get() + NEXT I + HeapItem <- NEW Meter(A, B) + CALL ChangedNumber.Set(Text) + CALL ChangedText.Set(A) + CALL ChangedText.Apply(B) + CALL Rebuilt.NEW(Text) + OUTPUT DefaultItem.Get(), ":", NumberItem.Get(), ":", TextItem.Get(), ":", PairItem.Get(), ":", Wrapped.Item.Get(), ":", Total, ":", NumberItem.Get(B), ":", NumberItem.Get(B / 8), ":", NumberItem.Get(Text), ":", HeapItem.Get(), ":", ChangedNumber.Get(), ":", ChangedText.Get(), ":", Rebuilt.Get() + DELETE HeapItem +NEXT Row diff --git a/tests/ii/overload-methods/reference.cc b/tests/ii/overload-methods/reference.cc new file mode 100644 index 0000000..1ef1829 --- /dev/null +++ b/tests/ii/overload-methods/reference.cc @@ -0,0 +1,21 @@ +#include +#include +#include + +int main() { + int count; + if (!(std::cin >> count)) return 1; + for (int row = 0; row < count; ++row) { + std::int64_t a, b, size; + std::string text; + if (!(std::cin >> a >> b >> size >> text)) return 1; + // Model the resulting values directly, without reproducing class dispatch. + const auto number = 2 * a + 3; + const auto length = text.size(); + std::cout << 5 << ':' << number << ':' << length + 20 << ':' << a - b + << ':' << 5 << ':' << 5 * size << ':' << number + 3 * b << ':' + << (number > b / 8.0 ? "TRUE" : "FALSE") << ':' << text << "!:" + << a - b << ':'; + std::cout << length << ':' << a + 3 * b << ':' << length + 20 << '\n'; + } +} -- cgit v1.3.1-4-g156e