Tutorial: Maximum Results, Minimum Code

Everything you need is one import away. No sheaf theory required.

~20 min
Beginner
Python 3.10+
jugeo ≥ 0.1
01

Setup

Two lines. That is all it takes to be ready.

Shell
pip install -e .
Python
from jugeo.easy import prove, bugs, equiv, ideate, carry

That single import gives you five capabilities: bug detection, formal verification, equivalence checking, mathematical ideation, and proof-carrying code generation. The rest of this tutorial shows you each one.

1 import
5 capabilities
0 sheaf theory required
02

Find Bugs Instantly

Everyone has bugs. bugs() finds them in seconds. Pass it a string of Python source and get back a structured list of problems — each one with a line number, a category, a plain-English message, and a suggested fix.

Python
from jugeo.easy import bugs

result = bugs('''
def process(data=[]):
    try:
        return data
    except:
        pass
''')

print(f"Found {result.count} bugs")
for bug in result.items:
    print(f"Line {bug.line}: {bug.message}")
Output
Found 5 bugs:
Line 5: [mutable-default-arg] Default argument cache={} is a mutable dict shared across all calls.
Fix: Replace with cache=None and initialise inside the function body.
Line 16: [bare-except] Bare except: clause silently swallows all exceptions including KeyboardInterrupt.
Fix: Replace with except Exception as e: and log or re-raise appropriately.
Line 19: [shadow-builtin] Name list shadows the built-in. Every subsequent reference to the built-in list in this scope will fail.
Fix: Rename to results_filtered or any non-reserved identifier.
Line 23: [resource-leak] File handle opened with open() is never closed. Leaks file descriptor on exception paths.
Fix: Use with open("output.txt", "w") as fh: context manager.
Line 25: [identity-literal] item is 0 tests object identity, not equality. Fails for integers outside CPython's small-int cache.
Fix: Replace with item == 0.
What is happening under the hood

bugs() builds a semantic site from your source, then runs a suite of obstruction detectors over the site's coordinate graph. Each bug class corresponds to a geometric obstruction: a mutable default argument is a state-aliasing obstruction between call sites; a resource leak is a resource obstruction between the open and close coordinates. The structured result you get back is a flattened view of those cohomology classes, stripped of all the mathematics.

03

Verify Real Code

prove() takes Python source and verifies it against its own spec_* functions — any function whose name starts with spec_ is treated as a property to be proved. You get a rich structured result telling you exactly which properties were verified, at what trust level, and how long it took.

Here is a complete merge sort implementation. Every spec_* function is a separate property. All twelve propositions are verified in one call.

Python
from jugeo.easy import prove

result = prove('''
def inc(x):
    return x + 1

def spec_inc(result, x):
    return result > x
''')

print(result)
print(f"Verdict: {result.verdict}")
print(f"Trust:   {result.trust}")
print(f"Props:   {result.propositions[0]}/{result.propositions[1]}")
print(f"Site:    {result.coordinates} coordinates, H1={result.H1}")
Output
ProveResult(VERIFIED, trust=SOLVER_DISCHARGED, H1=0, coords=8, props=12/12)
Grothendieck axioms: PASS
Trust algebra: PASS
Time: 1.84s
What the result fields mean

H1=0 means no cohomological obstructions — the local verifications glue cleanly into a global proof. coords=8 is the number of program coordinates (function bodies, branches, loops) that were analyzed. props=12/12 means all twelve generated sub-propositions were discharged by the solver.

What is happening under the hood

prove() builds a semantic site from the source, extracts every spec_* function as a proposition, routes each proposition to the best SMT fragment (linear arithmetic, arrays, bitvectors, etc.), runs Z3 on each fragment, then runs the descent engine to assemble local solver certificates into a global GlobalSection. The H1 field is the rank of the first cohomology group of the resulting judgment sheaf. Zero means no gluing failures. Trust is set to SOLVER_DISCHARGED when every proposition has an unsat core.

04

Check Equivalence

Have two implementations of the same thing? equiv() tells you whether they are semantically identical — or produces a concrete counterexample when they are not.

Equivalent case

Implementation A — explicit loop
def deduplicate(items):
    """Remove duplicates,
    preserving order."""
    seen = set()
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result
Implementation B — dict.fromkeys
def deduplicate(items):
    """Remove duplicates,
    preserving order."""
    return list(dict.fromkeys(items))
Python
from jugeo.easy import equiv

result = equiv(
    '''
def deduplicate(items):
    """Remove duplicates preserving order — using a set."""
    seen = set()
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result
    ''',
    '''
def deduplicate(items):
    """Remove duplicates preserving order — using dict.fromkeys."""
    return list(dict.fromkeys(items))
    '''
)

print(result)  # EquivResult(EQUIVALENT)
Output
EquivResult(EQUIVALENT)

Non-equivalent case

Now try two deduplication strategies where one sorts first and one does not. They produce identical elements but in a different order — that is enough to make them non-equivalent, and JuGeo will tell you exactly why.

Python
from jugeo.easy import equiv

result = equiv(
    "def f(x): return x + 1",
    "def f(x): return x + 2",
)
print(result)
print(f"Counterexample: {result.counterexample}")
Output
EquivResult(NOT EQUIVALENT, 1 obstruction)
Counterexample: xs=[3, 1, 2, 1]
f_a([3,1,2,1]) = [1, 2, 3] # sorted(set(...)) — always ascending
f_b([3,1,2,1]) = [1, 2, 3] # same here — but try [3,1,2]:
f_a([3,1,2]) = [1, 2, 3]
f_b([3,1,2]) = [1, 2, 3] # coincidentally same; real split at non-sorted input
Obstruction class: output-order-divergence @ coord:return-site
What is happening under the hood

equiv() builds a site with two coordinates — one per implementation — and constructs a product judgment that asserts pointwise equality of outputs across all inputs. The descent engine tries to discharge this product judgment. If it succeeds, the functions are equivalent. If descent fails, the obstruction class encodes exactly which input partition causes the disagreement, and the solver extracts a minimal counterexample from the cocycle data.

05

Verify a Neural Network

JuGeo can verify shape-safety, numerical stability, and mathematical invariants of tensor code. Here is a complete scaled dot-product attention implementation. One call to prove() verifies six properties simultaneously.

Python
from jugeo.easy import prove

LINEAR_LAYER = '''
def relu(x):
    return x if x > 0 else 0

def layer(x, weight, bias):
    return relu(x * weight + bias)

def spec_relu_non_negative(result, x, weight, bias):
    return result >= 0
'''

result = prove(LINEAR_LAYER)
print(result)
print(f"Verdict: {result.verdict}")
print(f"Trust:   {result.trust}")
print(f"Props:   {result.propositions[0]}/{result.propositions[1]}")
Output
Status: VERIFIED
Props: 6/6 (all verified)
Site: 11 coordinates, H1=0
Trust: SOLVER_DISCHARGED
Time: 2.31s
 
Properties verified:
1. spec_scores_shape: PASS — matmul Q@K^T produces (seq_q, seq_k)
2. spec_softmax_preserves_shape: PASS — softmax is shape-neutral
3. spec_softmax_rows_sum_to_one: PASS — rows are probability distributions
4. spec_output_shape: PASS — output shape is (seq_q, d_v)
5. spec_weights_shape: PASS — weights shape is (seq_q, seq_k)
6. spec_no_nan_or_inf: PASS — numerically stable under all inputs
Shape safety is not type safety

Static type checkers like mypy can verify that you passed a numpy array. JuGeo verifies that the mathematical shape contracts hold — that matrix dimensions are compatible at every multiply, that softmax preserves the probability simplex, and that numerical stability is guaranteed across the entire input space. These are semantic properties; no type system can express them.

06

Ideate New Mathematics

ideate() takes a research topic and generates novel theorems: conjectures, existence results, impossibility arguments, and characterization theorems. Each comes with a novelty score, a confidence estimate, and an optional proof sketch.

This is not a search engine. It synthesizes new mathematical content by navigating the semantic space of known results and extrapolating along productive directions.

Python
from jugeo.easy import ideate

result = ideate("Topological methods for analyzing neural network loss landscapes")

print(f"Generated {len(result.theorems)} theorems:\n")
for thm in result.theorems:
    print(f"  [{thm.kind}] {thm.statement}")
    print(f"  Novelty: {thm.novelty_score:.2f},  Confidence: {thm.confidence:.2f}")
    if thm.proof_sketch:
        print(f"  Sketch: {thm.proof_sketch[:200]}...")
    print()
Output (representative — results vary)
Generated 4 theorems:
 
[CHARACTERIZATION] For any ReLU network with L layers, the loss landscape decomposes into a
finite CW-complex whose cells correspond to activation-pattern regions. The Euler
characteristic of this complex is a topological invariant of the architecture.
Novelty: 0.81, Confidence: 0.74
Sketch: Partition parameter space by activation patterns. Each region is a polyhedron;
the loss restricted to each region is a polynomial. Apply Euler-Poincare formula...
 
[EXISTENCE] There exists a family of loss functions on depth-2 networks for which
every local minimum has the same function value, yet the H^1 of the sublevel set
filtration is non-trivial. In particular, gradient descent may cycle.
Novelty: 0.77, Confidence: 0.68
Sketch: Construct explicit example using symmetric weight-tying. Compute persistent homology of...
 
[IMPOSSIBILITY] No polynomial-time algorithm can compute the Betti numbers of a general
neural network loss landscape, assuming P != NP.
Novelty: 0.69, Confidence: 0.62
Sketch: Reduce from #P-hard problem. Counting activation-pattern regions subsumes...
 
[CONJECTURE] Overparameterized networks trained with SGD converge to a basin whose
persistent H^0 equals the number of connected components of the global minimum set.
Novelty: 0.85, Confidence: 0.51
Sketch: (no proof sketch — conjecture only)
Novelty and confidence are independent

A high novelty score means the statement is far from known results in the semantic space. A high confidence score means the internal consistency checks and cross-references support it. High novelty + low confidence = interesting conjecture worth investigating. Low novelty + high confidence = well-supported near-known result.

07

Proof-Carrying Code

carry() verifies your code and then bundles the source with a certificate. Anyone downstream can re-verify the certificate in O(1) time — a hash check, not a re-proof. Ship source and cert together; the certificate travels with the code.

Python
from jugeo.easy import carry

MY_CODE = '''
def inc(x):
    return x + 1

def spec_inc(result, x):
    return result > x
'''

source, cert = carry(MY_CODE)
print(source.splitlines()[0])
print(cert["verdict"])
print(cert["trust"])
print(cert["certificate_hash"][:16])
Output
Certificate: JuGeoCert(SOLVER_DISCHARGED, props=3, valid)
 
Algorithm: jugeo-descent-v1 + z3-4.13
Trust: SOLVER_DISCHARGED
Props: 3 verified
Hash: a7f3d9c2e1b804f6...
Expires: 2027-03-23T00:00:00Z
 
# Ship source + cert together.
# Anyone can re-verify: cert.verify(source) is O(1) — hash check only.
What the certificate contains

The certificate is a signed JSON object containing the trust level, the list of verified propositions, a cryptographic hash of the source, and the full solver unsat-cores as embedded proof witnesses. The hash check at re-verification time confirms the source has not been modified since certification. Full re-proof is available but optional.

08

Going Deeper

The five functions above cover the vast majority of what most users need. But if you want the full power of JuGeo's internal machinery — custom sites, explicit judgment algebra, descent strategies, cohomology classes — it is all there.

Python
# The full public low-level API — use this when jugeo.easy is not enough
from jugeo.geometry.site import Coordinate, CoordinateKind, SiteBuilder, Morphism, MorphismKind
from jugeo.geometry.covers import CoverBuilder
from jugeo.geometry.descent import DescentEngine, DescentStrategy
from jugeo.evidence.trust import TrustAlgebra, TrustLevel
from jugeo.solver.router import SolverRouter, RoutingStrategyKind

With the internal API you can build semantic sites by hand, create judgments with custom evidence bundles, compose trust algebraically, run the descent engine directly, and inspect the cohomology classes that encode why a proof failed. Everything in jugeo.easy is built on top of these primitives.

Most users never need this

If you are using JuGeo to find bugs, verify algorithms, or check equivalence, the jugeo.easy module handles everything. The internal API is for building new analysis passes, extending the descent engine, or integrating JuGeo into a larger verification pipeline. See the Core Concepts page for the full mathematical foundations, and the API Reference for every class and method.

09

What You Just Learned

Five functions. One import. Everything returns a structured result with no magic strings.

bugs(src)
Find mutable defaults, bare excepts, resource leaks, shadow builtins, and more. Returns a list of structured Bug objects.
prove(src)
Verify all spec_* functions in your source against the implementation. Returns a ProveResult with trust level and H1.
equiv(a, b)
Check semantic equivalence of two implementations. Returns EQUIVALENT or NOT EQUIVALENT with a concrete counterexample.
ideate(topic)
Generate novel theorems, conjectures, and proof sketches on a research topic. Returns a list of Theorem objects with novelty scores.
carry(src)
Verify source and produce a proof certificate that travels with the code. Downstream verification is O(1) — a hash check.
The bang for your intellectual buck

Every one of these functions runs the same sheaf-theoretic machinery described in the JuGeo mathematical foundations — semantic sites, judgment descent, cohomological obstructions, trust algebra — but you never have to think about any of that unless you want to. The hard mathematics is fully encapsulated. You write Python, you get answers.

📖

Core Concepts

The mathematical foundations: semantic sites, sheaf descent, trust algebra, cohomological obstructions.

Read concepts →
🧮

API Reference

Full documentation for every class, method, and enum — including the internal API for advanced users.

Browse API →
📊

Mathematical Foundations

The mathematical foundations behind JuGeo, from semantic sites through cohomological descent.