clinlat 0.1.0

A symbolic substrate for clinical decision-making based on refinable hypothesis lattices and sound deduction operators
Documentation
  • Coverage
  • 79.55%
    35 out of 44 items documented1 out of 22 items with examples
  • Size
  • Source code size: 36.58 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 843.07 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 8s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • SHA888/SFClinAI
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • SHA888

clinlat — Clinical Lattice Types

A Rust substrate for symbolic clinical decision-making based on refinable hypothesis lattices and sound deduction operators.

Version: 0.1.0 Status: Early implementation (kernel milestone)

Overview

The clinlat crate provides:

  • Hyp: A poset (partially ordered set) of clinical hypotheses, ordered by refinement (specificity).
  • Outcome<H, A>: A result type for operator outputs (refined hypothesis or abstention).
  • Deduction operators: Sound functions that refine hypotheses using clinical evidence (e.g., SOFA-3 respiratory scoring).

This implements the patient-state substrate from Substrate-First Clinical AI, a position arguing that clinical AI safety must be enforced by symbolic reasoning, not learned components alone.

Quick Start

Creating a Hypothesis

use clinlat::Hyp;

// The top element (most general hypothesis).
let unknown = Hyp::unknown();

// A specific hypothesis (in v0.1.0, atoms are static strings).
let diagnosis = Hyp::new(vec!["sepsis_3", "respiratory_dysfunction"]);

Refinement Ordering

use clinlat::Hyp;
use std::cmp::Ordering;

let unknown = Hyp::unknown();
let specific = Hyp::new(vec!["sofa_score_3"]);

// `specific` refines (is more specific than) `unknown`.
assert_eq!(specific.partial_cmp(&unknown), Some(Ordering::Less));

Compatibility and Meet

use clinlat::Hyp;

let h1 = Hyp::new(vec!["diagnosis_a"]);
let h2 = Hyp::new(vec!["diagnosis_b"]);
let unknown = Hyp::unknown();

// h1 and h2 are incompatible (orthogonal diagnoses).
assert!(!h1.compat(&h2));

// Any hypothesis is compatible with unknown.
assert!(h1.compat(&unknown));

// Meet of h1 and unknown is h1 itself.
assert_eq!(h1.meet(&unknown), Some(h1.clone()));

// Meet of incomparable hypotheses is None.
assert_eq!(h1.meet(&h2), None);

SOFA-3 Respiratory Scoring

use clinlat::sofa::{SofaRespEvidence, score_from_ratio};

// Evidence: PaO₂ = 350 mmHg, FiO₂ = 1.0, not on ventilator.
let evidence = SofaRespEvidence::new(350.0, 1.0, false);
let ratio = evidence.pao2_fio2_ratio().unwrap();  // 350.0

// Map to SOFA score (300–399 → score 1).
let score = score_from_ratio(ratio, false);
assert_eq!(score, Some(1));

// If score ≥3, mechanical ventilation is required.
let severe = score_from_ratio(80.0, false);  // <100 → score 4
assert_eq!(severe, None);  // Precondition unmet (not ventilated).

let severe_ventilated = score_from_ratio(80.0, true);
assert_eq!(severe_ventilated, Some(4));

Architecture

Hypothesis Lattice

Hypotheses are ordered by refinement:

        Unknown (top)
           / | \
      Score0 Score1 ... Score4 (bottom elements, incomparable to each other)

In this lattice:

  • Unknown is the greatest element (least specific; no information).
  • Score{N} elements are minimal (each is a specific diagnostic score).
  • The partial meet of two elements is their greatest lower bound (if it exists).

Operators

An Operator is a function from a hypothesis and evidence to an outcome:

apply: (Hyp, Evidence) → Outcome<Hyp, AbstainReason>

The operator either:

  • Refines the hypothesis to a more specific one based on evidence.
  • Abstains with a reason (e.g., insufficient evidence, precondition unmet).

SOFA-3 Respiratory Component

The SOFA-3 operator scores respiratory dysfunction severity via the PaO₂/FiO₂ ratio:

Ratio (mmHg) Score Meaning
≥ 400 0 No dysfunction
300–399 1 Mild
200–299 2 Moderate
100–199 3 Severe (requires ventilation)
< 100 4 Very severe (requires ventilation)

Per Sepsis-3, scores 3 and 4 are only valid for intubated patients; the operator abstains if this precondition is unmet.

Soundness

Each operator carries a soundness argument establishing three properties:

  1. Refinement monotonicity: If h₁ ⊑ h₂, operator output on h₁ refines that on h₂.
  2. No spurious refinement: Output never exceeds what the evidence justifies.
  3. Abstention purity: Abstention is structural, not error handling.

See clinlat/docs/operators/sofa_resp_soundness.md for the SOFA-3 argument.

v0.1.0 Simplifications

  • AtomId: Static string reference (&'static str). Real ontology binding (SNOMED CT, RxNorm, LOINC, ICD-11) deferred to v0.2.
  • Evidence: Unit type in the trait interface. Structured evidence (lab values, timestamps, provenance) deferred to v0.2.
  • Operator trait: Generic interface; actual operators (like SOFA-3) use concrete evidence types.
  • Provenance: Unit stub (); real lineage and timestamping deferred to v0.2.

References

  • Position note: Substrate-First Clinical AI (NOTE.md) § 4A–4D (eighteen load-bearing principles).
  • Formalization: SPEC.md § 2 (patient-state substrate definitions and proof obligations).
  • Clinical references:
    • Vincent JL, et al. The SOFA (Sepsis-related Organ Failure Assessment) score to describe organ dysfunction/failure. Intensive Care Medicine. 1996;22(7):707–710.
    • Singer M, et al. The Third International Consensus Definitions for Sepsis and Septic Shock (Sepsis-3). JAMA. 2016;315(8):801–810.

Testing

All public types and functions have unit tests:

cargo test

Documentation tests are included in rustdoc:

cargo test --doc

Building Documentation

Generate full API documentation with cross-references:

cargo doc --no-deps --open

License

Code: MIT OR Apache-2.0 (see LICENSE-MIT and LICENSE-APACHE at repo root).

Contributing

Contributions follow the repository contribution order (see CONTRIBUTING.md):

  1. Show the synthesis is already published (and was missed in prior art).
  2. Demonstrate one of the eighteen principles is wrong or unnecessary.
  3. Show the substrate framing fails on a clinical decision not covered by the worked examples.

For questions or issues, see the main repository: https://github.com/SHA888/SFClinAI