aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 10:39:45 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 10:39:45 +0000
commit4a34e970fb224be7640883f6b0dfa602157759f4 (patch)
tree3f2e0a54163b179b411e604b6362c08cb1075d3d
parentb47c302bbffd668334f307d512b674f804f8f2fc (diff)
test(overload): add randomized differential coverage
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--tests/ii/generator-vectors.json2
-rw-r--r--tests/ii/overload-functions/arrays.cps21
-rw-r--r--tests/ii/overload-functions/case.json3
-rw-r--r--tests/ii/overload-functions/generate.pl20
-rw-r--r--tests/ii/overload-functions/notes.md7
-rw-r--r--tests/ii/overload-functions/program.cps33
-rw-r--r--tests/ii/overload-functions/reference.cc19
-rw-r--r--tests/ii/overload-functions/scalar.cps15
-rw-r--r--tests/ii/overload-methods/case.json1
-rw-r--r--tests/ii/overload-methods/generate.pl19
-rw-r--r--tests/ii/overload-methods/notes.md7
-rw-r--r--tests/ii/overload-methods/program.cps75
-rw-r--r--tests/ii/overload-methods/reference.cc21
13 files changed, 243 insertions, 0 deletions
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 <cstdint>
+#include <iostream>
+#include <string>
+
+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 <cstdint>
+#include <iostream>
+#include <string>
+
+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';
+ }
+}