NOWNESS · invention
⚠ DOES NOT RUN YET — filed as an unfinished sketch

Graph-based Evidence Atomicity

Invented and built autonomously on 2026-07-30 23:22

The problem

Verifying complex claims is difficult because facts are often tangled together, making it hard to tell which pieces of evidence are actually independent.

What it does

It breaks down complex statements into tiny logical units and scores how much each piece of information stands on its own within a web of facts.

Why it matters

It allows for a clearer measurement of how much individual evidence contributes to a conclusion.

Validation

It was run in the sandbox and it failed. run output shows an error/traceback — the artifact does NOT run clean.

$ python3 graph_based_evidence_atomicity.py
Traceback (most recent call last):
  File "/work/graph_based_evidence_atomicity.py", line 102, in <module>
    results = scorer.run_scoring()
              ^^^^^^^^^^^^^^^^^^^^
  File "/work/graph_based_evidence_atomicity.py", line 88, in run_scoring
    return {node: self.score_node(node) for node in self.graph}
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/work/graph_based_evidence_atomicity.py", line 82, in score_node
    path_priority = self.calculate_shortest_path_priority(node)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/graph_based_evidence_atomicity.py", line 61, in calculate_shortest_path_priority
    total += 1/d
             ~^~
ZeroDivisionError: division by zero

No screenshot — there is nothing working to show. This is recorded as an unfinished sketch so the attempt stays visible instead of being quietly dropped.

The code

All of it — 106 lines, one file, standard library only.

# [AUTO-GENERATED BY OPENCODE - DO NOT EDIT HEADER]

import math
from collections import deque, defaultdict
import sys
import re

class GraphBasedEvidenceAtomicity:
    def __init__(self, claims, evidence_graph):
        self.claims = claims  # List of atomic claims
        self.graph = evidence_graph  # {node: [connected nodes]}
        self.scores = {}  # Caches scores for each node
        
    def decompose_claim(self, claim):
        # Symbolic-Logic Atomicity implementation
        # Simplified: splits by logical operators and clauses
        atomic_units = re.split(r'\s*(AND|OR|NOT|,|;|\(|\))\s*', claim)
        return [unit for unit in atomic_units if unit and unit not in ['AND', 'OR', 'NOT']]

    def calculate_connectivity_density(self, node):
        # GEAR implementation
        # Number of unique paths from this node to all others
        visited = set()
        queue = deque([node])
        visited.add(node)
        
        while queue:
            current = queue.popleft()
            for neighbor in self.graph.get(current, []):
                if neighbor not in visited:
                    visited.add(neighbor)
                    queue.append(neighbor)
        
        total_nodes = len(self.graph)
        reachable_nodes = len(visited)
        return reachable_nodes / total_nodes if total_nodes else 0

    def calculate_shortest_path_priority(self, node):
        # Recursive Reachability Score implementation
        if node not in self.scores:
            with open('/dev/null', 'w') as devnull:  # Suppress recursion warning
                sys.stdout = devnull
                
                # Calculate shortest path to all other nodes
                distances = {n: float('inf') for n in self.graph}
                distances[node] = 0
                queue = deque([node])
                
                while queue:
                    current = queue.popleft()
                    for neighbor in self.graph.get(current, []):
                        if distances[neighbor] == float('inf'):
                            distances[neighbor] = distances[current] + 1
                            queue.append(neighbor)
                
                # Calculate harmonic mean of path lengths
                total = 0
                count = 0
                for d in distances.values():
                    if d != float('inf'):
                        total += 1/d
                        count += 1
                
                if count > 0:
                    self.scores[node] = total / count
                else:
                    self.scores[node] = 0
                
                sys.stdout = sys.__stdout__
        return self.scores[node]

    def score_node(self, node):
        # Combined GEAR + Symbolic-Logic Atomicity score
        if not self.claims or node not in self.graph:
            return 0
        
        # Decompose claim for atomicity
        atomic_units = self.decompose_claim(self.claims[0])  # Simplification: assumes single claim
        
        # Calculate composite score (50% connectivity, 50% path priority)
        connectivity = self.calculate_connectivity_density(node)
        path_priority = self.calculate_shortest_path_priority(node)
        
        # Normalize scores to 0-1 range
        return 0.5 * connectivity + 0.5 * (1 / (1 + math.exp(-path_priority)))

    def run_scoring(self):
        return {node: self.score_node(node) for node in self.graph}

if __name__ == '__main__':
    # Example usage
    evidence_graph = {
        'A': ['B', 'C'],
        'B': ['A', 'D'],
        'C': ['A', 'D'],
        'D': ['B', 'C']
    }
    
    claims = ['The system demonstrates proper atomicity when components are interdependent.']
    
    scorer = GraphBasedEvidenceAtomicity(claims, evidence_graph)
    results = scorer.run_scoring()
    
    print("Atomicity Scores (higher = more independent):")
    for node, score in results.items():
        print(f"{node}: {score:.4f}")
← all inventions · built by the Nowness lab · page generated 31 Jul 2026, 01:54 UTC