スキル一覧に戻る
benbrastmckie

skill-model-checker

by benbrastmckie

A hyperintensional theorem prover for rapidly prototyping modular semantic theories

11🍴 3📅 2026年1月11日
GitHubで見るManusで実行

SKILL.md


name: skill-model-checker description: Research and develop semantic theories using ModelChecker with Z3 SMT solver. Define operators, adjust frame constraints, create examples, run tests, and report findings. Invoke with /mc or when working with model-checker, semantic theories, or Z3 constraints. allowed-tools: Read, Write, Edit, Glob, Grep, Bash(PYTHONPATH=* pytest ), Bash(PYTHONPATH= python *), Bash(cd Code && ./dev_cli.py *), Bash(model-checker *) context: fork

ModelChecker Research Skill

Comprehensive skill for developing and testing modular semantic theories using the ModelChecker framework with Z3 SMT solver.

Trigger Conditions

This skill activates when:

  • User invokes /mc command
  • Working with semantic theories (logos, exclusion, imposition, bimodal)
  • Defining or modifying operators
  • Creating or adjusting frame constraints
  • Writing model-checker examples
  • Running theory tests
  • Analyzing countermodels or theorem results

Context Loading

Load these context files as needed during skill execution:

Core ModelChecker Context (Always Load)

  • @.claude/context/project/modelchecker/architecture.md - System architecture and package structure
  • @.claude/context/project/modelchecker/theories.md - Theory library overview (logos, exclusion, imposition, bimodal)
  • @.claude/context/project/modelchecker/z3-patterns.md - Z3 solver patterns and best practices

Domain Context (Load When Relevant)

  • @.claude/context/project/logic/domain/kripke-semantics-overview.md - Modal semantics background

Installation Context (Load for Troubleshooting)

  • @.claude/context/project/modelchecker/installation.md - Installation and CLI usage

Sub-Commands

CommandPurpose
/mc operator <name>Create or modify an operator
/mc frameAdjust frame constraints
/mc exampleCreate test examples
/mc test [theory]Run tests
/mc reportAnalyze and report results

Quick Start

Running the Model Checker

# Development CLI (recommended)
cd Code && ./dev_cli.py examples/my_example.py

# Installed package
model-checker examples.py              # Basic run
model-checker examples.py --maximize   # Compare theories
model-checker examples.py --save       # Export results

Running Tests

# All tests
PYTHONPATH=Code/src pytest Code/tests/ -v

# Specific theory
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/logos/tests/ -v

# With coverage
PYTHONPATH=Code/src pytest --cov=model_checker --cov-report=term-missing

Operator Definition Workflow

When to Use

Use /mc operator when:

  • Adding a new logical operator
  • Modifying existing operator semantics
  • Implementing operator for a new subtheory

Theory Structure

Each theory follows this pattern:

theory_lib/{theory}/
├── __init__.py          # Public API
├── semantic.py          # Core semantic framework
├── operators.py         # Operator registry
├── examples.py          # Test cases
└── tests/
    ├── unit/           # Unit tests
    └── integration/    # Integration tests

Operator Class Template

from model_checker.syntactic import Operator

class MyOperator(Operator):
    """
    Operator implementing {description}.

    Syntax: A \\myop B
    """
    name = "\\myop"      # LaTeX-style name
    arity = 2            # Number of arguments

    def true_at(self, left, right, eval_point):
        """
        Truth conditions: when is 'A \\myop B' true at eval_point?

        Args:
            left: Left argument sentence
            right: Right argument sentence
            eval_point: Dict with 'world' key containing Z3 BitVec

        Returns:
            Z3 constraint for truth condition
        """
        world = eval_point["world"]
        # Example: conjunction semantics
        return z3.And(
            self.semantics.true_at(left, eval_point),
            self.semantics.true_at(right, eval_point)
        )

    def false_at(self, left, right, eval_point):
        """
        Falsity conditions: when is 'A \\myop B' false at eval_point?
        """
        world = eval_point["world"]
        # Example: conjunction falsity (either false)
        return z3.Or(
            self.semantics.false_at(left, eval_point),
            self.semantics.false_at(right, eval_point)
        )

    def extended_verify(self, state, left, right, eval_point):
        """
        Hyperintensional verification: state verifies 'A \\myop B'.

        Args:
            state: Z3 BitVec representing a state
            left, right: Argument sentences
            eval_point: Evaluation point
        """
        # Example: fusion of verifiers
        x, y = z3.BitVecs("ver_x ver_y", self.semantics.N)
        return z3.Exists([x, y], z3.And(
            self.semantics.extended_verify(x, left, eval_point),
            self.semantics.extended_verify(y, right, eval_point),
            state == self.semantics.fusion(x, y)
        ))

    def extended_falsify(self, state, left, right, eval_point):
        """
        Hyperintensional falsification: state falsifies 'A \\myop B'.
        """
        # Example: either falsifier suffices
        return z3.Or(
            self.semantics.extended_falsify(state, left, eval_point),
            self.semantics.extended_falsify(state, right, eval_point)
        )

    def find_verifiers_and_falsifiers(self, left, right, eval_point):
        """
        Compute proposition as (verifier_set, falsifier_set).
        Used for output display.
        """
        left_prop = self.semantics.find_proposition(left, eval_point)
        right_prop = self.semantics.find_proposition(right, eval_point)

        # Combine based on operator semantics
        verifiers = set()
        for lv in left_prop[0]:
            for rv in right_prop[0]:
                verifiers.add(self.semantics.fusion(lv, rv))

        falsifiers = left_prop[1] | right_prop[1]
        return (verifiers, falsifiers)

Operator Registration

Add to operators.py:

from .my_operator import MyOperator

def load_operators(semantics):
    """Load all operators for this theory."""
    return [
        # ... existing operators ...
        MyOperator(semantics),
    ]

TDD Workflow for Operators

1. Write failing test first:

# tests/unit/test_my_operator.py
import pytest
from model_checker.builder import BuildExample

class TestMyOperator:

    def test_basic_truth(self):
        """Test basic truth conditions for \\myop."""
        example = BuildExample(
            premises=['A', 'B'],
            conclusions=['A \\myop B'],
            settings={'N': 3, 'expectation': False}  # Should be theorem
        )
        result = example.run()
        assert result.is_theorem(), "A, B should entail A \\myop B"

    def test_countermodel(self):
        """Test that invalid inference has countermodel."""
        example = BuildExample(
            premises=['A \\myop B'],
            conclusions=['A'],
            settings={'N': 3, 'expectation': True}  # Should find countermodel
        )
        result = example.run()
        assert result.has_countermodel()

2. Run test - verify it fails (RED)

PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/{theory}/tests/unit/test_my_operator.py -v

3. Implement operator (GREEN)

4. Refactor while tests pass


Frame Constraints Workflow

When to Use

Use /mc frame when:

  • Adding new semantic constraints
  • Modifying world/state relationships
  • Adjusting possibility conditions

SemanticDefaults Extension Pattern

from model_checker.semantic import SemanticDefaults
from model_checker.utils import ForAll, Exists
import z3

class MySemantics(SemanticDefaults):

    def __init__(self, combined_settings=None, **kwargs):
        super().__init__(combined_settings)

        # Z3 primitives
        self.verify = z3.Function(
            "verify",
            z3.BitVecSort(self.N),
            syntactic.AtomSort,
            z3.BoolSort()
        )
        self.falsify = z3.Function(
            "falsify",
            z3.BitVecSort(self.N),
            syntactic.AtomSort,
            z3.BoolSort()
        )
        self.possible = z3.Function(
            "possible",
            z3.BitVecSort(self.N),
            z3.BoolSort()
        )

        # Main evaluation point
        self.main_world = z3.BitVec("w", self.N)
        self.main_point = {"world": self.main_world}

        # Build frame constraints
        self._build_frame_constraints()

    def _build_frame_constraints(self):
        """Define the frame constraints for this semantic theory."""
        x, y = z3.BitVecs("frame_x frame_y", self.N)

        # Possibility is downward closed under parthood
        possibility_downward = ForAll([x, y], z3.Implies(
            z3.And(self.possible(y), self.is_part_of(x, y)),
            self.possible(x)
        ))

        # Main world is a world
        main_is_world = self.is_world(self.main_world)

        # Verifiers must be possible
        atom = z3.Const("frame_atom", syntactic.AtomSort)
        verifier_possible = ForAll([x, atom], z3.Implies(
            self.verify(x, atom),
            self.possible(x)
        ))

        self.frame_constraints = [
            possibility_downward,
            main_is_world,
            verifier_possible,
        ]

        # Validity conditions
        self.premise_behavior = lambda p: self.true_at(p, self.main_point)
        self.conclusion_behavior = lambda c: self.false_at(c, self.main_point)

Common Constraint Patterns

ConstraintZ3 Pattern
UniversalForAll([x], condition(x))
ExistentialExists([x], condition(x))
Parthoodself.is_part_of(x, y) (x <= y in bitvec)
Fusionself.fusion(x, y) (x | y in bitvec)
Possibilityself.possible(x)
Worldself.is_world(x) (maximal possible state)

Example Creation Workflow

When to Use

Use /mc example when:

  • Creating test cases for operators
  • Validating logical relationships
  • Building countermodel demonstrations

Example Naming Convention

{SUBTHEORY}_{TYPE}_{NUMBER}

SUBTHEORY: EXT, MOD, CONST, CF, REL (or theory-specific)
TYPE: CM (countermodel expected), TH (theorem expected)
NUMBER: Sequential number

Example Template

# examples.py

# Countermodel example (expect to find model)
EXT_CM_1_premises = ['A']
EXT_CM_1_conclusions = ['B']
EXT_CM_1_settings = {
    'N': 3,                    # State space size (2^N states)
    'contingent': False,       # Force contingent propositions
    'non_null': True,          # Exclude null state verifiers
    'non_empty': True,         # Require non-empty verifier sets
    'disjoint': False,         # Allow verifier/falsifier overlap
    'max_time': 1,             # Solver timeout (seconds)
    'iterate': 1,              # Number of models to find
    'expectation': True,       # True = expect countermodel
}
EXT_CM_1_example = [
    EXT_CM_1_premises,
    EXT_CM_1_conclusions,
    EXT_CM_1_settings,
]

# Theorem example (expect no countermodel)
EXT_TH_1_premises = ['A', '(A \\rightarrow B)']
EXT_TH_1_conclusions = ['B']
EXT_TH_1_settings = {
    'N': 3,
    'max_time': 1,
    'expectation': False,      # False = expect theorem (no countermodel)
}
EXT_TH_1_example = [
    EXT_TH_1_premises,
    EXT_TH_1_conclusions,
    EXT_TH_1_settings,
]

# Organize into collections
countermodel_examples = {
    "EXT_CM_1": EXT_CM_1_example,
}

theorem_examples = {
    "EXT_TH_1": EXT_TH_1_example,
}

# Active examples for testing
example_range = {
    **countermodel_examples,
    **theorem_examples,
}

Settings Reference

SettingTypeDefaultDescription
Nint16State space size (2^N possible states)
contingentboolTrueForce propositions to be contingent
non_emptyboolTrueVerifier/falsifier sets must be non-empty
non_nullboolTrueExclude null state from verifiers
disjointboolTrueVerifiers and falsifiers must be disjoint
max_timeint10Solver timeout in seconds
iterateint/boolFalseNumber of models to find (False = 1)
expectationbool/NoneNoneTrue=countermodel, False=theorem, None=unknown

Testing Workflow

When to Use

Use /mc test when:

  • Running theory tests
  • Validating examples
  • Checking test coverage

Test Commands

# All tests
PYTHONPATH=Code/src pytest Code/tests/ -v

# Specific theory
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/logos/tests/ -v
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/exclusion/tests/ -v
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/imposition/tests/ -v
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/bimodal/tests/ -v

# Specific test file
PYTHONPATH=Code/src pytest Code/src/model_checker/theory_lib/logos/tests/unit/test_semantic.py -v

# With coverage
PYTHONPATH=Code/src pytest --cov=model_checker --cov-report=term-missing

# Run single test
PYTHONPATH=Code/src pytest -k "test_name" -v

Test Fixture Pattern

import pytest
from model_checker.theory_lib.logos import get_theory, get_examples

@pytest.fixture
def theory():
    """Get logos theory instance."""
    return get_theory()

@pytest.fixture
def examples():
    """Get example collection."""
    return get_examples()

class TestOperator:

    def test_truth_conditions(self, theory):
        """Test operator truth conditions."""
        # ... test code ...

    def test_with_examples(self, examples):
        """Test against standard examples."""
        for name, example in examples.items():
            result = example.run()
            # Validate based on expectation

Common Test Failures

ErrorCauseFix
ImportErrorPYTHONPATH not setAdd PYTHONPATH=Code/src
z3.Z3ExceptionConstraint type mismatchCheck BitVec sizes match
TimeoutState space too largeReduce N or add constraints
Wrong resultSemantic errorCheck operator methods

Reporting Workflow

When to Use

Use /mc report when:

  • Analyzing countermodel structure
  • Documenting logical results
  • Comparing theories

Model Output Interpretation

When a countermodel is found:

=== COUNTERMODEL FOUND ===

World (w): 0b1101 (state 13)

Atoms:
  A: verifiers={0b0001, 0b0101}, falsifiers={0b0010}
  B: verifiers={0b0100}, falsifiers={0b0001, 0b0011}

Premises satisfied:
  A is TRUE at w (verified by 0b0101 which is part of w)

Conclusion falsified:
  B is FALSE at w (falsified by 0b0001 which is part of w)

Key interpretation:

  • World: The evaluation world as a bitvector (maximal possible state)
  • Verifiers: States that make the proposition true
  • Falsifiers: States that make the proposition false
  • Parthood: x is part of y if (x & y) == x (bitvector AND)

Report Template

# Model-Checker Analysis: {Topic}

**Date**: {date}
**Theory**: {logos/exclusion/imposition/bimodal}

## Formula Under Test

Premises:
- {premise 1}
- {premise 2}

Conclusion:
- {conclusion}

## Result

{THEOREM / COUNTERMODEL FOUND}

## Analysis

{Explanation of the logical significance}

## Model Details (if countermodel)

{Countermodel structure and interpretation}

## Implications

{What this tells us about the logical system}

Theory Comparison

Run same formula across theories:

# Compare all theories
model-checker examples.py --maximize

# This runs the example against all available theories
# and reports which theory finds the smallest countermodel
# (or which validates as theorem)

Quick Reference

Formula Syntax

OperatorSyntaxArityDescription
Negation\\neg A1Classical negation
Conjunction(A \\wedge B)2And
Disjunction(A \\vee B)2Or
Conditional(A \\rightarrow B)2If-then
Biconditional(A \\leftrightarrow B)2Iff
Necessity\\Box A1Necessary
Possibility\\Diamond A1Possible
Ground(A \\leq B)2A grounds B
Essence(A \\sqsubseteq B)2A is essential to B

Subtheory Dependencies (Logos)

modal → extensional, counterfactual
counterfactual → extensional
constitutive → (none)
relevance → constitutive
extensional → (none)

Key Codebase Locations

ComponentPath
Theory libraryCode/src/model_checker/theory_lib/
Logos theoryCode/src/model_checker/theory_lib/logos/
Semantic baseCode/src/model_checker/semantic/
BuilderCode/src/model_checker/builder/
TestsCode/tests/
ExamplesCode/src/model_checker/theory_lib/*/examples.py

Z3 Quick Patterns

import z3
from model_checker.utils import ForAll, Exists

# BitVector state (N bits)
x = z3.BitVec("x", N)
state = z3.BitVecVal(5, N)  # Concrete state 0b101

# Parthood: x is part of y
is_part = (x & y) == x

# Fusion: combine states
fusion = x | y

# Quantified constraints
ForAll([x], z3.Implies(condition, result))
Exists([x], z3.And(condition1, condition2))

# Function declarations
verify = z3.Function("verify", z3.BitVecSort(N), AtomSort, z3.BoolSort())

# Solver usage
solver = z3.Solver()
solver.add(constraints)
if solver.check() == z3.sat:
    model = solver.model()
    value = model.evaluate(expression)

Error Recovery

Import Errors

# Verify PYTHONPATH
echo $PYTHONPATH
# Should include Code/src

# Test import
PYTHONPATH=Code/src python -c "from model_checker import BuildExample"

Solver Timeout

Reduce state space:

settings = {
    'N': 3,      # Smaller state space
    'max_time': 5,
}

Z3 Type Errors

Check BitVec sizes match:

# All states must use same N
x = z3.BitVec("x", self.N)  # Use self.N consistently

Additional Resources

  • Architecture: Code/docs/core/ARCHITECTURE.md
  • Testing Guide: Code/docs/core/TESTING_GUIDE.md
  • API Docs: Code/src/model_checker/README.md
  • Theory Docs: Code/src/model_checker/theory_lib/logos/README.md

スコア

総合スコア

55/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新

+5
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

レビュー

💬

レビュー機能は近日公開予定です