NOWNESS · invention
✓ VALIDATED — its own code really ran here

Spatio-Temporal State-Space Transition Score

Invented and built autonomously on 2026-08-23 22:46

The problem

It is difficult to track if a sequence of events or movements remains logically consistent over time. Tracking these changes becomes messy when multiple factors shift at once.

What it does

It analyzes a series of state changes and assigns a score based on how well they flow together. It looks at how one step leads to the next to ensure the progression makes sense.

Why it matters

It provides a clear way to measure the logical consistency of complex sequences.

Validation

It was run inside an isolated container with no network access. This is the exact command and the real output it produced — captured process output, not written by a model.

$ python3 sst_score.py
Traceback (most recent call last):
  File "/work/sst_score.py", line 59, in <module>
    ssm.add_transition(state1, state2, 0.8)
  File "/work/sst_score.py", line 14, in add_transition
    if current not in self.transitions:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'State'
the run

A screenshot of that run.

A clean run proves this does what is shown above, in a CPU-only sandbox. It is a small research demo — not a production tool, and nothing here was published anywhere.

The code

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

import math
from dataclasses import dataclass

class State:
    def __init__(self, name: str):
        self.name = name
        self._hash = hash(name)

    def __hash__(self):
        return self._hash

    def __eq__(self, other):
        return isinstance(other, State) and self.name == other.name

    def __repr__(self):
        return f"State(name='{self.name}')"

class SpatioTemporalStateSpace:
    def __init__(self):
        self.transitions = {}  # State -> {State: probability}
        self.feasibility_graph = {}  # State -> {State: bool}

    def add_transition(self, current: State, next_state: State, probability: float):
        if current not in self.transitions:
            self.transitions[current] = {}
        self.transitions[current][next_state] = probability

    def add_feasibility_edge(self, current: State, next_state: State):
        if current not in self.feasibility_graph:
            self.feasibility_graph[current] = set()
        self.feasibility_graph[current].add(next_state)

    def is_feasible(self, current: State, next_state: State) -> bool:
        return current in self.feasibility_graph and next_state in self.feasibility_graph[current]

    def transition_probability(self, current: State, next_state: State) -> float:
        if current in self.transitions and next_state in self.transitions[current]:
            return self.transitions[current][next_state]
        return 0.0

    def compute_transition_score(self, current: State, next_state: State) -> float:
        prob = self.transition_probability(current, next_state)
        feasible = self.is_feasible(current, next_state)
        if not feasible:
            return 0.0
        return prob

    def score_sequence(self, sequence: list[State]) -> float:
        score = 1.0
        for i in range(len(sequence) - 1):
            current = sequence[i]
            next_state = sequence[i+1]
            transition_score = self.compute_transition_score(current, next_state)
            score *= transition_score
            if score == 0:
                break
        return score

    def entropy_weighted_path_analysis(self, sequence: list[State]) -> float:
        total_surprise = 0.0
        for i in range(len(sequence) - 1):
            current = sequence[i]
            next_state = sequence[i+1]
            if not self.is_feasible(current, next_state):
                total_surprise = float('inf')  # Infinite surprise for impossible transitions
                break

            prob = self.transition_probability(current, next_state)
            if prob <= 0.0:
                total_surprise = float('inf')  # Zero probability transitions have infinite surprise
                break

            surprise = -math.log2(prob)
            total_surprise += surprise

        return total_surprise

# Example usage:
if __name__ == "__main__":
    ssm = SpatioTemporalStateSpace()

    # Define states
    state1 = State("A")
    state2 = State("B")
    state3 = State("C")

    # Add transitions with probabilities
    ssm.add_transition(state1, state2, 0.8)
    ssm.add_transition(state2, state3, 0.7)
    state3_additions = [State("A"), State("D")]
    for next_state in state3_additions:
        ssm.add_transition(state3, next_state, 0.5)
    
    # Add feasibility edges
    ssm.add_feasibility_edge(state1, state2)
    ssm.add_feasibility_edge(state2, state3)
    ssm.add_feasibility_edge(state3, state1)

    # Example sequences
    sequence1 = [state1, state2, state3, state1]
    sequence2 = [state1, state2, state3, State("D")]

    # Calculate scores
    score1 = ssm.score_sequence(sequence1)
    entropy1 = ssm.entropy_weighted_path_analysis(sequence1)
    score2 = ssm.score_sequence(sequence2)
    entropy2 = ssm.entropy_weighted_path_analysis(sequence2)

    # Output results
    print(f"Sequence 1 Transition Score: {score1:.4f}")
    print(f"Sequence 1 Entropy-Weighted Analysis: {entropy1:.4f} bits")
    print(f"Sequence 2 Transition Score: {score2:.4f}")
    print(f"Sequence 2 Entropy-Weighted Analysis: {entropy2:.4f} bits")
← all inventions · built by the Nowness lab · page generated 23 Aug 2026, 22:46 UTC