Metadata-Version: 2.4
Name: logicscore-core
Version: 0.1.0
Summary: Logic Scoring of Preference - interpretable multi-criteria aggregation
Project-URL: Homepage, https://github.com/benmklein/logicscore-core
Project-URL: Repository, https://github.com/benmklein/logicscore-core
Project-URL: Issues, https://github.com/benmklein/logicscore-core/issues
License: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mypy>=1.9; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# LogicScore Core

LogicScore Core is a focused Python library for Logic Scoring of Preference (LSP): it provides deterministic, interpretable tree-based aggregation math and companion utilities for suitability mapping, validation, sensitivity analysis, and traversal.

## Install

```bash
pip install logicscore-core
```

```bash
uv add logicscore-core
```

## Quickstart

```python
from logicscore.core import TreeNode, compute_tree, SuitabilityCurve, validate_tree

# Map raw signals to suitability in [0.0, 1.0].
temperature_curve = SuitabilityCurve.linear((0.0, 100.0), low_suitability=0.0, high_suitability=1.0)
volatility_curve = SuitabilityCurve.inverted_u(peak=20.0, width=20.0, peak_suitability=1.0, base_suitability=0.2)

temperature = TreeNode(
    id="temperature",
    name="Temperature",
    weight=0.6,
    score=temperature_curve(72.0),
)
volatility = TreeNode(
    id="volatility",
    name="Volatility",
    weight=0.4,
    score=volatility_curve(18.0),
)

root = TreeNode(
    id="market_quality",
    name="Market Quality",
    operator=0.5,  # canonical neutral UGCD operator
    children=[temperature, volatility],
)

validation = validate_tree(root)
if not validation.valid:
    raise ValueError(f"invalid tree: {validation.errors}")

score = compute_tree(root)
print(f"Final score: {score:.4f}")
```

## What this package is / is not

### In scope

- Core tree math and utilities (`TreeNode`, UGCD aggregation, validation, sensitivity, traversal)
- Deterministic score computation from already-prepared node inputs

### Out of scope

- Runtime decision labels or score-to-action mapping
- Clock/timestamp enforcement and staleness orchestration
- Policy orchestration and execution/runtime adapters

For boundary details, see [`runtime-boundary.md`](runtime-boundary.md).

## API surface

Canonical imports are from `logicscore.core`:

- `TreeNode`
- `compute_tree`
- `SuitabilityCurve`
- `validate_tree`, `ValidationResult`
- `compute_sensitivity`
- `get_all_leaves`, `get_all_nodes`

## Development

```bash
uv sync --extra dev
uv run ruff check logicscore/ tests/
uv run mypy logicscore/
uv run pytest
```

If your environment does not expose script entry points through `uv run`, use:

```bash
uv run --extra dev python -m mypy logicscore/
uv run --extra dev python -m pytest
```

## Release Validation

```bash
uv run ruff check logicscore/ tests/
uv run mypy logicscore/
uv run pytest
uv build
uv run twine check dist/*
```

## License

Licensed under the MIT License. See [`LICENSE`](LICENSE).
