code wiki / (root) / nx_semruler_lib.nx

nx_semruler_lib.nx source

↩ module page · 116 lines · 6472 B

1// nx_semruler_lib.nx -- THE SEMANTIC RULER'S DECISION CORE (/compare/mediaingest; nx_imgsearch's own 2// declared next step). license_tier: ORIGINAL 3// 4// WHY THIS EXISTS, IN THE SUBJECT ORGAN'S OWN WORDS. nx_imgsearch status publishes, honestly: 5// {"class":"semantic-lookalike","permille":-1,"status":"UNMEASURED", 6// "note":"-1 means NEVER MEASURED, not zero. No semantic class exists in the 17-transform ruler, so 7// the previous literal 0 was a CLAIM, not a result. Order: (1) build a semantic ruler from 8// labelled same-concept pairs, (2) measure the EXISTING descriptors as the honest baseline, 9// (3) only then a quantised learned image-embedding tier (NX_IT_KIND_SEMANTIC reserved)." 10// This lib is step (1)'s decision core, and it is deliberately TINY because steps of it already existed: 11// 12// NOT WRITTEN HERE, COMPOSED INSTEAD -- each one would have been a duplicate ruler: 13// nx_recall_eval the estate's IR scorecard (nDCG/MRR/Recall/P/AP). No rate math beyond the 14// one abstaining ratio below, which exists only to refuse the empty set. 15// it_copy_distance the copy tier's own bit-Hamming over the 64-bit dHash. The admissibility 16// floor is expressed in THAT metric so the bar and the tier it guards against 17// cannot drift apart. (nx_hamming is BYTE-wise and would have mis-scaled the 18// floor by 8x while still returning a plausible number.) 19// NX_IT_CLASS_IDENTITY / NX_IT_CLASS_SIMILAR 20// the tier partition is already a first-class concept in the base class; this 21// lib only NAMES the reading so a caller cannot mistake one for the other. 22// 23// THE ONE THING THAT DID NOT EXIST, AND THE WHOLE POINT OF THE FILE: 24// A "SAME-CONCEPT" PAIR THAT IS ACTUALLY A NEAR-DUPLICATE MEASURES THE COPY TIER, NOT SEMANTICS. 25// Tiers 0-2 are copy detectors and they are excellent -- 992 permil overall across rescale, crop, 26// watermark and recompress. Feed this ruler re-crops and re-encodes of one photograph and it will 27// report near 1000 permil and "prove" the engine is already semantic. The number would be real and 28// the SUBJECT would be wrong: that is the vacuous-test defect wearing a benchmark's clothes, and it 29// is the single most likely way this measurement gets faked without anyone lying. 30// sr_pair_admissible REFUSES such a pair. Its caller MUST publish the refusal count -- a ruler that 31// silently drops inadmissible pairs has chosen its own population, which is the same defect one 32// layer up. 33// 34// AND THE MIRROR CASE, WHICH THE OBVIOUS ONE-LINE VERSION GETS WRONG: a mirrored or quarter-turned 35// re-upload has a LARGE copy distance and a TINY orient distance, because tier 1 is dihedral-invariant 36// by construction. A predicate that tested only the copy distance would admit every mirrored duplicate 37// and quietly re-measure tier 1 while claiming to measure semantics. The floor is applied to the MINIMUM 38// of the two, i.e. "is this the same photograph under ANY dihedral transform". 39 40import "nx_syscalls.nx" 41import "nx_imgsearch_tier.nx" 42 43// A rate over zero admitted pairs is UNOBSERVABLE. It is NEVER 0 and NEVER 1000: an abstention that 44// acquits is the failure this whole organ exists to prevent, and a rate printed as 0 over no 45// observations is a lie in the direction nobody audits. 46const SR_UNOBSERVABLE: i64 = 0 - 1 47const SR_PERMIL: i64 = 1000 48 49// An unknown tier class is its OWN bucket. It must never fall into a known one -- the bucket it lands 50// in becomes the number somebody plans against. 51const SR_CLASS_UNKNOWN: i64 = 0 52 53func sr_min(a: i64, b: i64) -> i64 { 54 if a < b { return a } 55 return b 56} 57 58// 1 = this pair can carry semantic evidence . 0 = it is a duplicate under some dihedral transform and 59// would measure the copy/orient tiers instead. FAIL-CLOSED on an unknown distance: a pair whose 60// distance could not be computed is inadmissible, because admitting it would let an undecodable or 61// mis-strided record silently inflate the very number this ruler exists to keep honest. 62func sr_pair_admissible(copy_dist: i64, orient_dist: i64) -> i64 { 63 if copy_dist < 0 { return 0 } 64 if orient_dist < 0 { return 0 } 65 let d: i64 = sr_min(copy_dist, orient_dist) 66 if d <= NX_IT_COPY_THRESH { return 0 } 67 return 1 68} 69 70// Recall/precision-style rate over admitted pairs, in permil. ABSTAINS rather than clamps: an 71// impossible input (more hits than subjects) is a defect in the caller's counting and must surface as 72// UNOBSERVABLE, not be silently squashed to 1000 -- a clamp here would convert a counting bug into a 73// perfect score. 74func sr_rate_permil(hits: i64, admitted: i64) -> i64 { 75 if admitted <= 0 { return SR_UNOBSERVABLE } 76 if hits < 0 { return SR_UNOBSERVABLE } 77 if hits > admitted { return SR_UNOBSERVABLE } 78 return (hits * SR_PERMIL) / admitted 79} 80 81// Which class produced a hit. Named so a caller cannot read an identity-tier hit as semantic retrieval. 82func sr_hit_is_semantic(klass: i64) -> i64 { 83 if klass == NX_IT_CLASS_SIMILAR { return 1 } 84 return 0 85} 86 87func sr_hit_is_identity(klass: i64) -> i64 { 88 if klass == NX_IT_CLASS_IDENTITY { return 1 } 89 return 0 90} 91 92// An unrecognised class is neither, and says so. 93func sr_klass_known(klass: i64) -> i64 { 94 if klass == NX_IT_CLASS_IDENTITY { return 1 } 95 if klass == NX_IT_CLASS_SIMILAR { return 1 } 96 return 0 97} 98 99// A partition is a claim: check the parts SUM, and make the check callable so no consumer has to 100// remember to do it. Returns 1 iff the three buckets reconcile to the total. 101func sr_partition_sums(identity: i64, semantic: i64, unknown: i64, total: i64) -> i64 { 102 if identity < 0 { return 0 } 103 if semantic < 0 { return 0 } 104 if unknown < 0 { return 0 } 105 if total < 0 { return 0 } 106 if identity + semantic + unknown != total { return 0 } 107 return 1 108} 109 110// The headline this ruler exists to publish, kept in ONE place so the -1 sentinel cannot be respelled 111// by a consumer. Returns the semantic-lookalike figure in permil, or SR_UNOBSERVABLE when the admitted 112// population is empty -- which is the answer whenever a pair set is all near-duplicates, and is the 113// correct, loud outcome rather than a flattering one. 114func sr_semantic_permil(semantic_hits: i64, admitted: i64) -> i64 { 115 return sr_rate_permil(semantic_hits, admitted) 116}