hive-0003

This commit is contained in:
russell@unturf.com 2026-03-29 22:19:47 -04:00
parent 7e7cd2945a
commit 0fb709cb72
11 changed files with 1163 additions and 6 deletions

View file

@ -0,0 +1,145 @@
package unit;
import java.util.*;
/**
* ElixirTypespaceUsedTypePairsAlgorithm — CWE-407 test for elixir-0002
*
* Models Kernel.Typespec used_type_pairs state accumulation:
* slow: :lists.member({name,arity}, used_type_pairs) — O(T) per check, O(T²) total
* fast: MapSet.member?(used_type_pairs, {name,arity}) — O(log T) per check
*
* Test: for T distinct type references, slow path does ~T*(T+1)/2 list scans;
* fast path does T * log(T) set lookups. Ratio must be >= 10x at T=200.
*/
public class ElixirTypespaceUsedTypePairsAlgorithm {
// Simulate a type pair: {name, arity}
static final class TypePair {
final String name;
final int arity;
TypePair(String name, int arity) { this.name = name; this.arity = arity; }
@Override
public boolean equals(Object o) {
if (!(o instanceof TypePair)) return false;
TypePair tp = (TypePair) o;
return name.equals(tp.name) && arity == tp.arity;
}
@Override
public int hashCode() { return 31 * name.hashCode() + arity; }
}
// --- SLOW: O(T²) total ---
// used_type_pairs: list (cons-cell), :lists.member scans entire list
static class SlowTypePairTracker {
long comparisons = 0;
List<TypePair> usedTypePairs = new ArrayList<>();
// :lists.member({name, arity}, state.used_type_pairs)
boolean isMember(TypePair tp) {
for (TypePair existing : usedTypePairs) {
comparisons++;
if (existing.equals(tp)) return true;
}
return false;
}
// %{state | used_type_pairs: [{name,arity} | state.used_type_pairs]}
void addIfAbsent(TypePair tp) {
if (!isMember(tp)) {
usedTypePairs.add(0, tp); // prepend (cons)
}
}
}
// --- FAST: O(T log T) total ---
// used_type_pairs: MapSet — O(log T) membership and insertion
static class FastTypePairTracker {
long lookups = 0;
Set<TypePair> usedTypePairs = new HashSet<>();
// MapSet.member?(state.used_type_pairs, {name, arity})
boolean isMember(TypePair tp) {
lookups++;
return usedTypePairs.contains(tp);
}
// MapSet.put(state.used_type_pairs, {name, arity})
void addIfAbsent(TypePair tp) {
if (!isMember(tp)) {
usedTypePairs.add(tp);
}
}
}
// Simulate type-spec translation: R type references over T distinct types
// Each reference calls addIfAbsent then at the end filter_used_types checks isMember once more
static long simulateSlow(int distinctTypes, int refsPerType) {
SlowTypePairTracker tracker = new SlowTypePairTracker();
List<TypePair> types = new ArrayList<>();
for (int i = 0; i < distinctTypes; i++) {
types.add(new TypePair("type_" + i, 0));
}
// Simulate translation: each type is referenced refsPerType times
for (int r = 0; r < refsPerType; r++) {
for (TypePair tp : types) {
tracker.addIfAbsent(tp);
}
}
// filter_used_types: :lists.member for each distinct type
for (TypePair tp : types) {
tracker.isMember(tp);
}
return tracker.comparisons;
}
static long simulateFast(int distinctTypes, int refsPerType) {
FastTypePairTracker tracker = new FastTypePairTracker();
List<TypePair> types = new ArrayList<>();
for (int i = 0; i < distinctTypes; i++) {
types.add(new TypePair("type_" + i, 0));
}
for (int r = 0; r < refsPerType; r++) {
for (TypePair tp : types) {
tracker.addIfAbsent(tp);
}
}
for (TypePair tp : types) {
tracker.isMember(tp);
}
return tracker.lookups;
}
public static void main(String[] args) {
int[] sizes = {20, 50, 100, 200};
int refsPerType = 3;
System.out.println("ElixirTypespaceUsedTypePairsAlgorithm — elixir-0002");
System.out.println(" Pattern: :lists.member on used_type_pairs list — O(T²) vs MapSet — O(T log T)");
System.out.println(" Simulation: " + refsPerType + " refs per type, filter_used_types at end");
System.out.println();
int passed = 0;
int total = 0;
for (int t : sizes) {
long slowOps = simulateSlow(t, refsPerType);
long fastOps = simulateFast(t, refsPerType);
double ratio = (double) slowOps / fastOps;
boolean correct = ratio >= 3.0; // at T=20 ratio ~3x, at T=200 ~30x
if (t >= 100) correct = ratio >= 10.0;
total++;
if (correct) passed++;
System.out.printf(" T=%-4d slow=%7d fast=%5d ratio=%.1fx %s%n",
t, slowOps, fastOps, ratio, correct ? "PASS" : "FAIL");
}
System.out.println();
System.out.printf("Result: %d/%d PASS%n", passed, total);
if (passed < total) System.exit(1);
}
}