Reuse canonical item occurrence evidence

This commit is contained in:
2026-08-09 02:36:53 +00:00
parent b3ebfcef37
commit d28d1062e0
6 changed files with 97 additions and 39 deletions

View File

@@ -62,9 +62,11 @@ func Validate(doc *source.SourceDocument, value dnd.ItemOccurrenceList) error {
func issuesFor(order shared.SourceRefOrder, value dnd.ItemOccurrenceList) []string {
issues := make([]string, 0)
seenIdentity := make(map[string]int)
canonicalEvidence := make([]bool, len(value.Occurrences))
seenIdentity := make(map[string][]int)
for occurrenceIndex, occurrence := range value.Occurrences {
prefix := fmt.Sprintf("occurrences[%d]", occurrenceIndex)
canonicalEvidence[occurrenceIndex] = true
if occurrence.Name != itemoccurrencemodel.DisplayValue(occurrence.Name) {
issues = append(issues, prefix+".name is not display-normalized")
}
@@ -79,19 +81,29 @@ func issuesFor(order shared.SourceRefOrder, value dnd.ItemOccurrenceList) []stri
current := occurrence.SourceRefs[refIndex]
if order.Less(current, previous) {
issues = append(issues, fmt.Sprintf("%s.source_refs are not in canonical order at index %d", prefix, refIndex))
canonicalEvidence[occurrenceIndex] = false
} else if current == previous {
issues = append(issues, fmt.Sprintf("%s.source_refs[%d] duplicates the previous reference", prefix, refIndex))
canonicalEvidence[occurrenceIndex] = false
}
}
key := itemoccurrencemodel.ExactIdentity(order, occurrence)
if previous, exists := seenIdentity[key]; exists {
issues = append(issues, fmt.Sprintf("%s duplicates item occurrence %d under normalized identity", prefix, previous))
} else {
seenIdentity[key] = occurrenceIndex
if canonicalEvidence[occurrenceIndex] {
key := itemoccurrencemodel.CanonicalExactIdentity(occurrence)
for _, previous := range seenIdentity[key] {
if itemoccurrencemodel.CanonicalExactEqual(value.Occurrences[previous], occurrence) {
issues = append(issues, fmt.Sprintf("%s duplicates item occurrence %d under normalized identity", prefix, previous))
break
}
}
seenIdentity[key] = append(seenIdentity[key], occurrenceIndex)
}
}
for occurrenceIndex := 1; occurrenceIndex < len(value.Occurrences); occurrenceIndex++ {
if itemoccurrencemodel.Less(order, value.Occurrences[occurrenceIndex], value.Occurrences[occurrenceIndex-1]) {
less := itemoccurrencemodel.Less
if canonicalEvidence[occurrenceIndex] && canonicalEvidence[occurrenceIndex-1] {
less = itemoccurrencemodel.CanonicalLess
}
if less(order, value.Occurrences[occurrenceIndex], value.Occurrences[occurrenceIndex-1]) {
issues = append(issues, fmt.Sprintf("occurrences[%d] is out of canonical order", occurrenceIndex))
}
}