whitepaper: 366/178 — wave5 defect tables + PDF rebuild
This commit is contained in:
parent
835ae73b0f
commit
a4b0cf4edd
79 changed files with 3829 additions and 17 deletions
124
defects/swift/unit/SwiftRequirementMachineAlgorithm.java
Normal file
124
defects/swift/unit/SwiftRequirementMachineAlgorithm.java
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: Swift RequirementMachine isInMinimizationDomain
|
||||
*
|
||||
* Models the Swift compiler's RewriteSystem where:
|
||||
* - Protos = list of protocol declarations in the minimization domain
|
||||
* - Rules = rewrite rules over those protocols
|
||||
*
|
||||
* The defect: isInMinimizationDomain() does a linear scan over Protos
|
||||
* on every call, and is called once per rule in loops over all rules.
|
||||
* Total cost: O(R × P) where R = rule count, P = protocol count.
|
||||
*
|
||||
* The fix: replace the linear scan with a HashSet lookup — O(1) per call.
|
||||
*
|
||||
* Test measures ops count (comparisons) at N=800 (protos and rules both N).
|
||||
*/
|
||||
public class SwiftRequirementMachineAlgorithm {
|
||||
|
||||
// ---- Defective version: std::find equivalent (linear scan) ----------------
|
||||
|
||||
static long defectiveIsInDomain(List<Integer> protos, int proto) {
|
||||
// models: std::find(Protos.begin(), Protos.end(), proto)
|
||||
// returns ops performed
|
||||
long ops = 0;
|
||||
for (Integer p : protos) {
|
||||
ops++;
|
||||
if (p.equals(proto)) return ops;
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the rule-loop pattern from HomotopyReduction.cpp:611
|
||||
* for (const auto &rule : getLocalRules()) {
|
||||
* if (!isInMinimizationDomain(rule.getLHS().getRootProtocol())) continue;
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
static long defectiveMinimize(List<Integer> protos, List<Integer> rules) {
|
||||
long totalOps = 0;
|
||||
for (int rule : rules) {
|
||||
// Each rule references a protocol; check membership linearly
|
||||
totalOps += defectiveIsInDomain(protos, rule % protos.size());
|
||||
}
|
||||
return totalOps;
|
||||
}
|
||||
|
||||
// ---- Fixed version: HashSet O(1) lookup -----------------------------------
|
||||
|
||||
static long fixedMinimize(Set<Integer> protoSet, List<Integer> rules) {
|
||||
long totalOps = 0;
|
||||
for (int rule : rules) {
|
||||
// O(1) hash set lookup
|
||||
totalOps++;
|
||||
protoSet.contains(rule % protoSet.size());
|
||||
}
|
||||
return totalOps;
|
||||
}
|
||||
|
||||
// ---- Test harness ----------------------------------------------------------
|
||||
|
||||
static final int N = 800;
|
||||
|
||||
public static void main(String[] args) {
|
||||
int passed = 0;
|
||||
int total = 0;
|
||||
|
||||
// Build protos list (P = N protocols) and rules list (R = N rules)
|
||||
List<Integer> protos = new ArrayList<>(N);
|
||||
for (int i = 0; i < N; i++) protos.add(i);
|
||||
|
||||
List<Integer> rules = new ArrayList<>(N);
|
||||
for (int i = 0; i < N; i++) rules.add(i);
|
||||
|
||||
Set<Integer> protoSet = new HashSet<>(protos);
|
||||
|
||||
// Test 1: defective version is O(R*P) — ops >= N*N/2 on average
|
||||
total++;
|
||||
long slowOps = defectiveMinimize(protos, rules);
|
||||
// Each rule on average scans half the protos list
|
||||
long expectedMinSlow = (long) N * N / 4; // conservative lower bound
|
||||
assert slowOps >= expectedMinSlow
|
||||
: "Slow ops " + slowOps + " unexpectedly low, expected >= " + expectedMinSlow;
|
||||
System.out.println("PASS test1: defective ops=" + slowOps + " (O(N^2) confirmed, N=" + N + ")");
|
||||
passed++;
|
||||
|
||||
// Test 2: fixed version is O(R) — ops == N exactly
|
||||
total++;
|
||||
long fastOps = fixedMinimize(protoSet, rules);
|
||||
assert fastOps == N
|
||||
: "Fast ops should be exactly N=" + N + ", got " + fastOps;
|
||||
System.out.println("PASS test2: fixed ops=" + fastOps + " (O(N) confirmed, N=" + N + ")");
|
||||
passed++;
|
||||
|
||||
// Test 3: speedup is at least 10x
|
||||
total++;
|
||||
double speedup = (double) slowOps / fastOps;
|
||||
assert speedup >= 10.0
|
||||
: "Expected speedup >= 10x, got " + speedup;
|
||||
System.out.printf("PASS test3: speedup=%.1fx%n", speedup);
|
||||
passed++;
|
||||
|
||||
// Test 4: correctness — both find the same items in domain
|
||||
total++;
|
||||
List<Integer> smallProtos = Arrays.asList(10, 20, 30, 40, 50);
|
||||
Set<Integer> smallSet = new HashSet<>(smallProtos);
|
||||
|
||||
// Probe 5 different values
|
||||
int[] probeVals = {10, 25, 30, 99, 50};
|
||||
for (int v : probeVals) {
|
||||
boolean defectResult = defectiveIsInDomain(smallProtos, v) > 0 && smallProtos.contains(v);
|
||||
boolean fixedResult = smallSet.contains(v);
|
||||
assert defectResult == fixedResult
|
||||
: "Mismatch for value " + v + ": defect=" + defectResult + " fixed=" + fixedResult;
|
||||
}
|
||||
System.out.println("PASS test4: correctness — defective and fixed agree on all probes");
|
||||
passed++;
|
||||
|
||||
System.out.println(passed + "/" + total + " PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue