summaryrefslogtreecommitdiff
path: root/experiments/bci_td_protocol_smoke.py
blob: ed42db5a8ca64fe108ea4fd13207fc13009b83d5 (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python3
"""Endpoint-free falsification checks for the frozen oral-B R1/R2 gates."""
import copy
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from experiments.analyze_bci_td_confirmation import r2_checks, summarize
from experiments.analyze_bci_td_development import seed_checks


def check_r1_boundaries():
    row = {
        "conditions": {
            "intact": {
                "learning_gain": 0.20, "final_success": 0.80,
                "role_cosine_after_training": 0.90,
            },
            "fixed_vectorizer": {"final_success": 0.50},
            "plasticity_lesion": {"learning_gain": 0.05},
            "oracle_role": {"final_success": 0.85},
        },
        "signatures": {
            "causal_role_sign_inversion_index": 0.10,
            "velocity_minus_error_abs_cv_corr": 0.10,
            "mean_abs_residual_soma_corr": 0.05,
            "raw_minus_residual_abs_soma_corr": 0.30,
        },
    }
    assert all(seed_checks(row).values())
    no_learning = copy.deepcopy(row)
    no_learning["conditions"]["intact"]["learning_gain"] = 0.0
    no_learning["conditions"]["plasticity_lesion"]["learning_gain"] = 0.0
    assert not seed_checks(no_learning)["learning_gain_at_least_0p10"]
    wrong_sign = copy.deepcopy(row)
    wrong_sign["signatures"]["causal_role_sign_inversion_index"] = -0.01
    assert not seed_checks(wrong_sign)["sign_inversion_at_least_0p01"]
    no_vectorizer_gap = copy.deepcopy(row)
    no_vectorizer_gap["conditions"]["fixed_vectorizer"]["final_success"] = 0.75
    assert not seed_checks(no_vectorizer_gap)[
        "fixed_vectorizer_gap_at_least_0p20"]
    print("oral-B R1 learning, sign, and vectorizer gates: falsifiable")


def passing_r2_inputs():
    values = {
        "intact_final": 0.80,
        "intact_gain": 0.20,
        "fixed_final_gap": 0.30,
        "oracle_final_deficit": 0.05,
        "plasticity_half_margin": 0.05,
        "role_cosine": 0.90,
        "residual_soma_corr": 0.05,
        "raw_residual_corr_gap": 0.30,
        "surrounding_event_accuracy": 0.60,
        "decoder_distance_corr": 0.20,
        "residual_outcome_accuracy": 0.65,
        "residual_soma_outcome_gap": 0.10,
        "sign_inversion": 0.10,
        "velocity_advantage": 0.10,
        "longitudinal_prediction": 0.40,
    }
    clustered = {name: [value] * 6 for name, value in values.items()}
    metrics = {name: summarize(rows) for name, rows in clustered.items()}
    return metrics, clustered, [0.90] * 30, [0.10] * 30


def flatten(checks):
    return [value for values in checks.values()
            for value in ([values] if isinstance(values, bool)
                          else values.values())]


def check_r2_boundaries():
    metrics, clustered, roles, signs = passing_r2_inputs()
    checks = r2_checks(metrics, clustered, roles, signs)
    assert all(flatten(checks))

    no_learning_metrics = copy.deepcopy(metrics)
    no_learning_clusters = copy.deepcopy(clustered)
    no_learning_clusters["intact_gain"] = [0.0] * 6
    no_learning_metrics["intact_gain"] = summarize(
        no_learning_clusters["intact_gain"])
    no_learning = r2_checks(
        no_learning_metrics, no_learning_clusters, roles, signs)
    assert not no_learning["learning_and_plasticity"][
        "mean_learning_gain_at_least_0p10"]

    only_24_positive = [0.10] * 24 + [-0.10] * 6
    sign_failure = r2_checks(metrics, clustered, roles, only_24_positive)
    assert not sign_failure["outcome_and_causal_role_vectorization"][
        "positive_sign_inversion_in_at_least_25_of_30"]

    heterogeneous_metrics = copy.deepcopy(metrics)
    heterogeneous_clusters = copy.deepcopy(clustered)
    heterogeneous_clusters["fixed_final_gap"] = [0.30] * 5 + [-0.20]
    heterogeneous_metrics["fixed_final_gap"] = summarize(
        heterogeneous_clusters["fixed_final_gap"])
    heterogeneous = r2_checks(
        heterogeneous_metrics, heterogeneous_clusters, roles, signs)
    assert heterogeneous["learning_and_plasticity"][
        "mean_fixed_gap_at_least_0p20"]
    assert not heterogeneous["learning_and_plasticity"][
        "fixed_gap_lower_bound_at_least_0p10"]

    no_longitudinal_metrics = copy.deepcopy(metrics)
    no_longitudinal_clusters = copy.deepcopy(clustered)
    no_longitudinal_clusters["longitudinal_prediction"] = [0.0] * 6
    no_longitudinal_metrics["longitudinal_prediction"] = summarize(
        no_longitudinal_clusters["longitudinal_prediction"])
    no_longitudinal = r2_checks(
        no_longitudinal_metrics, no_longitudinal_clusters, roles, signs)
    assert not no_longitudinal["outcome_and_causal_role_vectorization"][
        "mean_longitudinal_prediction_at_least_0p30"]
    print("oral-B R2 learning, clustered robustness, sign, and prediction gates: falsifiable")


if __name__ == "__main__":
    check_r1_boundaries()
    check_r2_boundaries()
    print("ALL ORAL-B PROTOCOL BOUNDARY CHECKS PASSED")