File size: 3,194 Bytes
fc3e70a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

"""Tests: Phase 2 — Semantic IR."""

import pytest
from semantic_engine.ir import (
    Geometry, TemporalState, TemporalLock, TemporalTransition,
    Operand, Constraint, SemanticOperation, SemanticNode,
    SemanticIR, Artifact,
)
from semantic_engine.types import (
    ArtifactType, FSMState, IntentClass, Provenance,
    SemanticNodeType, TemporalViolation, VerificationState,
)


def make_provenance():
    return Provenance("input-1", "test")


def make_temporal():
    return TemporalState(tau=0)


def test_geometry_matmul_compatible():
    a = Geometry(row=3, col=4)
    b = Geometry(row=4, col=5)
    assert a.compatible_with(b)
    out = a.output_geometry(b)
    assert out.row == 3
    assert out.col == 5


def test_geometry_matmul_incompatible():
    a = Geometry(row=3, col=4)
    b = Geometry(row=5, col=5)
    assert not a.compatible_with(b)


def test_temporal_advance():
    t = TemporalState(tau=0)
    t1 = t.advance("step1")
    assert t1.tau == 1
    assert t.tau == 0  # original unchanged


def test_temporal_lock_prevents_advance():
    t = TemporalState(tau=0, locked=True)
    with pytest.raises(TemporalViolation):
        t.advance("should fail")


def test_temporal_lock_records_transitions():
    lock = TemporalLock()
    t = TemporalTransition(from_tau=0, to_tau=1, reason="step", stage="test")
    lock.record(t)
    assert len(lock.audit()) == 1


def test_temporal_lock_rejects_invalid_jump():
    lock = TemporalLock()
    bad = TemporalTransition(from_tau=0, to_tau=5, reason="jump", stage="test")
    with pytest.raises(TemporalViolation):
        lock.record(bad)


def test_semantic_node_stable_id():
    p = make_provenance()
    t = make_temporal()
    op = SemanticOperation("build", 1)
    n1 = SemanticNode.make(SemanticNodeType.OPERATION, op, [], [], None, t, p)
    n2 = SemanticNode.make(SemanticNodeType.OPERATION, op, [], [], None, t, p)
    assert n1.id == n2.id


def test_semantic_ir_create():
    p = make_provenance()
    t = make_temporal()
    op = SemanticOperation("build", 0)
    node = SemanticNode.make(SemanticNodeType.INTENT, op, [], [], None, t, p)
    ir = SemanticIR.create(IntentClass.BUILD, node, [node], TemporalLock(), p)
    assert ir.ir_id
    assert ir.intent == IntentClass.BUILD
    assert ir.verification_state == VerificationState.UNVERIFIED


def test_semantic_ir_find_node():
    p = make_provenance()
    t = make_temporal()
    op = SemanticOperation("build", 0)
    node = SemanticNode.make(SemanticNodeType.INTENT, op, [], [], None, t, p)
    ir = SemanticIR.create(IntentClass.BUILD, node, [node], TemporalLock(), p)
    found = ir.find_node(node.id)
    assert found is node
    assert ir.find_node("nonexistent") is None


def test_artifact_create():
    p = make_provenance()
    t = make_temporal()
    a = Artifact.create(ArtifactType.DOCUMENT, "root-id", "tmpl", "content", p, t)
    assert a.type == ArtifactType.DOCUMENT
    assert a.content == "content"
    assert a.semantic_root == "root-id"