use crate::enforcement::{
BindingEntry, BindingsTable, CompileTime, CompileUnit, CompileUnitBuilder,
CompletenessCertificate, ConstrainedTypeInput, GenericImpossibilityWitness, Grounded,
GroundingCertificate, InhabitanceCertificate, InhabitanceImpossibilityWitness,
LeaseDeclaration, LeaseDeclarationBuilder, LiftChainCertificate, MultiplicationCertificate,
ParallelDeclarationBuilder, PipelineFailure, ShapeViolation, StreamDeclarationBuilder, Term,
Validated,
};
use crate::ViolationKind;
use crate::WittLevel;
pub const PREFLIGHT_CHECK_IRIS: &[&str] = &[
"https://uor.foundation/reduction/BudgetSolvencyCheck",
"https://uor.foundation/reduction/FeasibilityCheck",
"https://uor.foundation/reduction/DispatchCoverageCheck",
"https://uor.foundation/reduction/PackageCoherenceCheck",
"https://uor.foundation/reduction/PreflightTiming",
"https://uor.foundation/reduction/RuntimeTiming",
];
pub const REDUCTION_STAGE_IRIS: &[&str] = &[
"https://uor.foundation/reduction/stage_initialization",
"https://uor.foundation/reduction/stage_declare",
"https://uor.foundation/reduction/stage_factorize",
"https://uor.foundation/reduction/stage_resolve",
"https://uor.foundation/reduction/stage_attest",
"https://uor.foundation/reduction/stage_extract",
"https://uor.foundation/reduction/stage_convergence",
];
pub const AFFINE_MAX_COEFFS: usize = 8;
pub const CONJUNCTION_MAX_TERMS: usize = 8;
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
pub enum ConstraintRef {
Residue { modulus: u64, residue: u64 },
Hamming { bound: u32 },
Depth { min: u32, max: u32 },
Carry { site: u32 },
Site { position: u32 },
Affine {
coefficients: [i64; AFFINE_MAX_COEFFS],
coefficient_count: u32,
bias: i64,
},
SatClauses {
clauses: &'static [&'static [(u32, bool)]],
num_vars: u32,
},
Bound {
observable_iri: &'static str,
bound_shape_iri: &'static str,
args_repr: &'static str,
},
Conjunction {
conjuncts: [LeafConstraintRef; CONJUNCTION_MAX_TERMS],
conjunct_count: u32,
},
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum LeafConstraintRef {
Residue { modulus: u64, residue: u64 },
Hamming { bound: u32 },
Depth { min: u32, max: u32 },
Carry { site: u32 },
Site { position: u32 },
Affine {
coefficients: [i64; AFFINE_MAX_COEFFS],
coefficient_count: u32,
bias: i64,
},
SatClauses {
clauses: &'static [&'static [(u32, bool)]],
num_vars: u32,
},
Bound {
observable_iri: &'static str,
bound_shape_iri: &'static str,
args_repr: &'static str,
},
}
impl ConstraintRef {
#[inline]
#[must_use]
pub const fn as_leaf(self) -> LeafConstraintRef {
match self {
ConstraintRef::Residue { modulus, residue } => {
LeafConstraintRef::Residue { modulus, residue }
}
ConstraintRef::Hamming { bound } => LeafConstraintRef::Hamming { bound },
ConstraintRef::Depth { min, max } => LeafConstraintRef::Depth { min, max },
ConstraintRef::Carry { site } => LeafConstraintRef::Carry { site },
ConstraintRef::Site { position } => LeafConstraintRef::Site { position },
ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => LeafConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
},
ConstraintRef::SatClauses { clauses, num_vars } => {
LeafConstraintRef::SatClauses { clauses, num_vars }
}
ConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
} => LeafConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
},
ConstraintRef::Conjunction { .. } => LeafConstraintRef::Site { position: 0 },
}
}
}
impl LeafConstraintRef {
#[inline]
#[must_use]
pub const fn into_constraint(self) -> ConstraintRef {
match self {
LeafConstraintRef::Residue { modulus, residue } => {
ConstraintRef::Residue { modulus, residue }
}
LeafConstraintRef::Hamming { bound } => ConstraintRef::Hamming { bound },
LeafConstraintRef::Depth { min, max } => ConstraintRef::Depth { min, max },
LeafConstraintRef::Carry { site } => ConstraintRef::Carry { site },
LeafConstraintRef::Site { position } => ConstraintRef::Site { position },
LeafConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
},
LeafConstraintRef::SatClauses { clauses, num_vars } => {
ConstraintRef::SatClauses { clauses, num_vars }
}
LeafConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
} => ConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
},
}
}
}
#[inline]
#[must_use]
#[allow(dead_code)]
pub(crate) const fn encode_constraint_to_clauses(
constraint: &ConstraintRef,
) -> Option<&'static [&'static [(u32, bool)]]> {
const EMPTY: &[&[(u32, bool)]] = &[];
const UNSAT_SENTINEL: &[&[(u32, bool)]] = &[&[(0u32, false)], &[(0u32, true)]];
match constraint {
ConstraintRef::SatClauses { clauses, .. } => Some(clauses),
ConstraintRef::Residue { .. }
| ConstraintRef::Carry { .. }
| ConstraintRef::Depth { .. }
| ConstraintRef::Hamming { .. }
| ConstraintRef::Site { .. } => Some(EMPTY),
ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => {
if is_affine_consistent(coefficients, *coefficient_count, *bias) {
Some(EMPTY)
} else {
Some(UNSAT_SENTINEL)
}
}
ConstraintRef::Bound { .. } => Some(EMPTY),
ConstraintRef::Conjunction {
conjuncts,
conjunct_count,
} => {
if conjunction_all_sat(conjuncts, *conjunct_count) {
Some(EMPTY)
} else {
Some(UNSAT_SENTINEL)
}
}
}
}
#[inline]
#[must_use]
const fn is_affine_consistent(
coefficients: &[i64; AFFINE_MAX_COEFFS],
coefficient_count: u32,
bias: i64,
) -> bool {
let mut sum: i128 = 0;
let count = coefficient_count as usize;
let mut i = 0;
while i < count && i < AFFINE_MAX_COEFFS {
sum += coefficients[i] as i128;
i += 1;
}
if sum == 0 {
bias == 0
} else {
true
}
}
#[inline]
#[must_use]
const fn conjunction_all_sat(
conjuncts: &[LeafConstraintRef; CONJUNCTION_MAX_TERMS],
conjunct_count: u32,
) -> bool {
let count = conjunct_count as usize;
let mut i = 0;
while i < count && i < CONJUNCTION_MAX_TERMS {
let lifted = conjuncts[i].into_constraint();
match encode_constraint_to_clauses(&lifted) {
Some([]) => {}
_ => return false,
}
i += 1;
}
true
}
pub trait ConstrainedTypeShape {
const IRI: &'static str;
const SITE_COUNT: usize;
const SITE_BUDGET: usize = Self::SITE_COUNT;
const CONSTRAINTS: &'static [ConstraintRef];
}
impl ConstrainedTypeShape for ConstrainedTypeInput {
const IRI: &'static str = "https://uor.foundation/type/ConstrainedType";
const SITE_COUNT: usize = 0;
const CONSTRAINTS: &'static [ConstraintRef] = &[];
}
#[doc(hidden)]
pub mod __sdk_seal {
pub trait Sealed {}
}
pub trait FoundationClosed: __sdk_seal::Sealed {
fn arena_slice() -> &'static [crate::enforcement::Term];
}
pub trait IntoBindingValue: ConstrainedTypeShape + __sdk_seal::Sealed {
const MAX_BYTES: usize;
#[allow(clippy::wrong_self_convention)]
fn into_binding_bytes(
&self,
out: &mut [u8],
) -> core::result::Result<usize, crate::enforcement::ShapeViolation>;
}
pub const ROUTE_INPUT_BUFFER_BYTES: usize = 4096;
pub const ROUTE_OUTPUT_BUFFER_BYTES: usize = 4096;
pub const FOLD_UNROLL_THRESHOLD: usize = 8;
pub trait PrismModel<H, B, A>: __sdk_seal::Sealed
where
H: crate::HostTypes,
B: crate::HostBounds,
A: crate::enforcement::Hasher,
{
type Input: ConstrainedTypeShape + IntoBindingValue;
type Output: ConstrainedTypeShape + crate::enforcement::GroundedShape + IntoBindingValue;
type Route: FoundationClosed;
fn forward(
input: Self::Input,
) -> Result<crate::enforcement::Grounded<Self::Output>, PipelineFailure>;
}
pub fn run_route<H, B, A, M>(
input: M::Input,
) -> Result<crate::enforcement::Grounded<M::Output>, PipelineFailure>
where
H: crate::HostTypes,
B: crate::HostBounds,
A: crate::enforcement::Hasher,
M: PrismModel<H, B, A>,
{
let arena_slice = <M::Route as FoundationClosed>::arena_slice();
let max_bytes = <M::Input as IntoBindingValue>::MAX_BYTES;
if max_bytes > ROUTE_INPUT_BUFFER_BYTES {
return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/RouteInputBufferShape",
constraint_iri: "https://uor.foundation/pipeline/RouteInputBufferShape/maxBytes",
property_iri: "https://uor.foundation/pipeline/inputMaxBytes",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 0,
max_count: ROUTE_INPUT_BUFFER_BYTES as u32,
kind: crate::ViolationKind::ValueCheck,
},
});
}
let mut buf = [0u8; ROUTE_INPUT_BUFFER_BYTES];
let written = input
.into_binding_bytes(&mut buf[..max_bytes])
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
let mut hasher = <A as crate::enforcement::Hasher>::initial();
hasher = hasher.fold_bytes(&buf[..written]);
let digest = hasher.finalize();
let content_address: u64 = u64::from_be_bytes([
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
]);
let transient_input = [crate::enforcement::Binding {
name_index: 0,
type_index: 0,
value_index: 0,
surface: <M::Input as ConstrainedTypeShape>::IRI,
content_address,
}];
static TARGET_DOMAINS: &[crate::VerificationDomain] = &[crate::VerificationDomain::Enumerative];
let level = match B::WITT_LEVEL_MAX_BITS {
bits if bits >= 32 => crate::WittLevel::W32,
bits if bits >= 24 => crate::WittLevel::W24,
bits if bits >= 16 => crate::WittLevel::W16,
_ => crate::WittLevel::W8,
};
let unit = CompileUnitBuilder::new()
.root_term(arena_slice)
.bindings(&transient_input)
.witt_level_ceiling(level)
.thermodynamic_budget(1024)
.target_domains(TARGET_DOMAINS)
.result_type::<M::Output>()
.validate()
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
let out_max = <M::Output as IntoBindingValue>::MAX_BYTES;
if out_max > ROUTE_OUTPUT_BUFFER_BYTES {
return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/RouteOutputBufferShape",
constraint_iri: "https://uor.foundation/pipeline/RouteOutputBufferShape/maxBytes",
property_iri: "https://uor.foundation/pipeline/outputMaxBytes",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 0,
max_count: ROUTE_OUTPUT_BUFFER_BYTES as u32,
kind: crate::ViolationKind::ValueCheck,
},
});
}
let evaluation = evaluate_term_tree::<A>(arena_slice, &buf[..written])?;
let grounded = run::<M::Output, _, A>(unit)?;
Ok(grounded.with_output_bytes(evaluation.bytes()))
}
pub const TERM_VALUE_MAX_BYTES: usize = 4096;
pub const RECURSE_PLACEHOLDER_NAME_INDEX: u32 = u32::MAX - 1;
pub const UNFOLD_PLACEHOLDER_NAME_INDEX: u32 = u32::MAX - 2;
pub const UNFOLD_MAX_ITERATIONS: usize = 256;
#[derive(Debug, Clone, Copy)]
pub struct TermValue {
bytes: [u8; TERM_VALUE_MAX_BYTES],
len: u16,
}
impl TermValue {
#[must_use]
pub const fn empty() -> Self {
Self {
bytes: [0u8; TERM_VALUE_MAX_BYTES],
len: 0,
}
}
#[must_use]
pub fn from_slice(bytes: &[u8]) -> Self {
let mut buf = [0u8; TERM_VALUE_MAX_BYTES];
let copy_len = if bytes.len() > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else {
bytes.len()
};
let mut i = 0;
while i < copy_len {
buf[i] = bytes[i];
i += 1;
}
Self {
bytes: buf,
len: copy_len as u16,
}
}
#[inline]
#[must_use]
pub fn bytes(&self) -> &[u8] {
&self.bytes[..self.len as usize]
}
}
pub fn evaluate_term_tree<A>(
arena: &[crate::enforcement::Term],
input_bytes: &[u8],
) -> Result<TermValue, PipelineFailure>
where
A: crate::enforcement::Hasher,
{
if arena.is_empty() {
return Ok(TermValue::from_slice(input_bytes));
}
let root_idx = arena.len() - 1;
evaluate_term_at::<A>(arena, root_idx, input_bytes, None, None)
}
fn evaluate_term_at<A>(
arena: &[crate::enforcement::Term],
idx: usize,
input_bytes: &[u8],
recurse_value: Option<&[u8]>,
unfold_value: Option<&[u8]>,
) -> Result<TermValue, PipelineFailure>
where
A: crate::enforcement::Hasher,
{
if idx >= arena.len() {
return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/TermArenaShape",
constraint_iri: "https://uor.foundation/pipeline/TermArenaShape/inBounds",
property_iri: "https://uor.foundation/pipeline/termIndex",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 0,
max_count: arena.len() as u32,
kind: crate::ViolationKind::ValueCheck,
},
});
}
match arena[idx] {
crate::enforcement::Term::Literal { value, level } => {
let width = (level.witt_length() / 8) as usize;
let width = if width == 0 {
1
} else if width > 8 {
8
} else {
width
};
let be = value.to_be_bytes();
Ok(TermValue::from_slice(&be[8 - width..]))
}
crate::enforcement::Term::Variable { name_index } => {
if name_index == RECURSE_PLACEHOLDER_NAME_INDEX {
return Ok(TermValue::from_slice(recurse_value.unwrap_or(&[])));
}
if name_index == UNFOLD_PLACEHOLDER_NAME_INDEX {
return Ok(TermValue::from_slice(unfold_value.unwrap_or(&[])));
}
Ok(TermValue::from_slice(input_bytes))
}
crate::enforcement::Term::Application { operator, args } => {
let start = args.start as usize;
let len = args.len as usize;
apply_primitive_op::<A>(
arena,
operator,
start,
len,
input_bytes,
recurse_value,
unfold_value,
)
}
crate::enforcement::Term::Lift {
operand_index,
target,
} => {
let v = evaluate_term_at::<A>(
arena,
operand_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let target_width = (target.witt_length() / 8) as usize;
let target_width = if target_width > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else if target_width == 0 {
1
} else {
target_width
};
let mut buf = [0u8; TERM_VALUE_MAX_BYTES];
let src = v.bytes();
let pad = target_width.saturating_sub(src.len());
let mut i = 0;
while i < src.len() && pad + i < target_width {
buf[pad + i] = src[i];
i += 1;
}
Ok(TermValue {
bytes: buf,
len: target_width as u16,
})
}
crate::enforcement::Term::Project {
operand_index,
target,
} => {
let v = evaluate_term_at::<A>(
arena,
operand_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let target_width = (target.witt_length() / 8) as usize;
let target_width = if target_width > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else if target_width == 0 {
1
} else {
target_width
};
let src = v.bytes();
let take_from = src.len().saturating_sub(target_width);
Ok(TermValue::from_slice(&src[take_from..]))
}
crate::enforcement::Term::Match {
scrutinee_index,
arms,
} => {
let scrutinee = evaluate_term_at::<A>(
arena,
scrutinee_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let start = arms.start as usize;
let count = arms.len as usize;
let mut i = 0usize;
while i + 1 < count {
let pattern_idx = start + i;
let body_idx = start + i + 1;
let is_wildcard = matches!(
arena[pattern_idx],
crate::enforcement::Term::Variable { name_index } if name_index == u32::MAX
);
if is_wildcard {
return evaluate_term_at::<A>(
arena,
body_idx,
input_bytes,
recurse_value,
unfold_value,
);
}
let pattern_val = evaluate_term_at::<A>(
arena,
pattern_idx,
input_bytes,
recurse_value,
unfold_value,
)?;
if pattern_val.bytes() == scrutinee.bytes() {
return evaluate_term_at::<A>(
arena,
body_idx,
input_bytes,
recurse_value,
unfold_value,
);
}
i += 2;
}
Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/MatchExhaustivenessShape",
constraint_iri:
"https://uor.foundation/pipeline/MatchExhaustivenessShape/wildcard",
property_iri: "https://uor.foundation/pipeline/matchArms",
expected_range: "http://www.w3.org/2001/XMLSchema#string",
min_count: 1,
max_count: 0,
kind: crate::ViolationKind::Missing,
},
})
}
crate::enforcement::Term::Recurse {
measure_index,
base_index,
step_index,
} => {
let measure = evaluate_term_at::<A>(
arena,
measure_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let n = bytes_to_u64_be(measure.bytes());
let base_val = evaluate_term_at::<A>(
arena,
base_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
if n == 0 {
return Ok(base_val);
}
let mut current_buf = [0u8; TERM_VALUE_MAX_BYTES];
let mut current_len = base_val.bytes().len();
let mut k = 0;
while k < current_len {
current_buf[k] = base_val.bytes()[k];
k += 1;
}
let mut iter = 0u64;
while iter < n {
let next = evaluate_term_at::<A>(
arena,
step_index as usize,
input_bytes,
Some(¤t_buf[..current_len]),
unfold_value,
)?;
let nb = next.bytes();
let copy_len = if nb.len() > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else {
nb.len()
};
let mut j = 0;
while j < copy_len {
current_buf[j] = nb[j];
j += 1;
}
current_len = copy_len;
iter += 1;
}
Ok(TermValue::from_slice(¤t_buf[..current_len]))
}
crate::enforcement::Term::Unfold {
seed_index,
step_index,
} => {
let seed_val = evaluate_term_at::<A>(
arena,
seed_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let mut state_buf = [0u8; TERM_VALUE_MAX_BYTES];
let mut state_len = seed_val.bytes().len();
let mut k = 0;
while k < state_len {
state_buf[k] = seed_val.bytes()[k];
k += 1;
}
let mut iter = 0usize;
while iter < UNFOLD_MAX_ITERATIONS {
let next = evaluate_term_at::<A>(
arena,
step_index as usize,
input_bytes,
recurse_value,
Some(&state_buf[..state_len]),
)?;
let nb = next.bytes();
if nb.len() == state_len && nb == &state_buf[..state_len] {
return Ok(TermValue::from_slice(&state_buf[..state_len]));
}
let copy_len = if nb.len() > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else {
nb.len()
};
let mut j = 0;
while j < copy_len {
state_buf[j] = nb[j];
j += 1;
}
state_len = copy_len;
iter += 1;
}
Ok(TermValue::from_slice(&state_buf[..state_len]))
}
crate::enforcement::Term::Try {
body_index,
handler_index,
} => {
match evaluate_term_at::<A>(
arena,
body_index as usize,
input_bytes,
recurse_value,
unfold_value,
) {
Ok(v) => Ok(v),
Err(e) => {
if handler_index == u32::MAX {
Err(e)
} else {
evaluate_term_at::<A>(
arena,
handler_index as usize,
input_bytes,
recurse_value,
unfold_value,
)
}
}
}
}
crate::enforcement::Term::HasherProjection { input_index } => {
let v = evaluate_term_at::<A>(
arena,
input_index as usize,
input_bytes,
recurse_value,
unfold_value,
)?;
let mut hasher = <A as crate::enforcement::Hasher>::initial();
hasher = hasher.fold_bytes(v.bytes());
let digest = hasher.finalize();
let width = if A::OUTPUT_BYTES > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else {
A::OUTPUT_BYTES
};
Ok(TermValue::from_slice(&digest[..width]))
}
}
}
fn apply_primitive_op<A>(
arena: &[crate::enforcement::Term],
operator: crate::PrimitiveOp,
args_start: usize,
args_len: usize,
input_bytes: &[u8],
recurse_value: Option<&[u8]>,
unfold_value: Option<&[u8]>,
) -> Result<TermValue, PipelineFailure>
where
A: crate::enforcement::Hasher,
{
let arity = match operator {
crate::PrimitiveOp::Neg
| crate::PrimitiveOp::Bnot
| crate::PrimitiveOp::Succ
| crate::PrimitiveOp::Pred => 1usize,
crate::PrimitiveOp::Add
| crate::PrimitiveOp::Sub
| crate::PrimitiveOp::Mul
| crate::PrimitiveOp::Xor
| crate::PrimitiveOp::And
| crate::PrimitiveOp::Or
| crate::PrimitiveOp::Le
| crate::PrimitiveOp::Lt
| crate::PrimitiveOp::Ge
| crate::PrimitiveOp::Gt
| crate::PrimitiveOp::Concat => 2usize,
};
if args_len != arity {
return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/PrimitiveOpArityShape",
constraint_iri: "https://uor.foundation/pipeline/PrimitiveOpArityShape/arity",
property_iri: "https://uor.foundation/pipeline/operatorArity",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: arity as u32,
max_count: arity as u32,
kind: crate::ViolationKind::CardinalityViolation,
},
});
}
if arity == 1 {
let v = evaluate_term_at::<A>(arena, args_start, input_bytes, recurse_value, unfold_value)?;
let x = bytes_to_u64_be(v.bytes());
let r =
match operator {
crate::PrimitiveOp::Neg => x.wrapping_neg(),
crate::PrimitiveOp::Bnot => !x,
crate::PrimitiveOp::Succ => x.wrapping_add(1),
crate::PrimitiveOp::Pred => x.wrapping_sub(1),
_ => return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/PrimitiveOpArityShape",
constraint_iri:
"https://uor.foundation/pipeline/PrimitiveOpArityShape/binary-as-unary",
property_iri: "https://uor.foundation/pipeline/operatorArity",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 2,
max_count: 2,
kind: crate::ViolationKind::CardinalityViolation,
},
}),
};
let width = v.bytes().len().clamp(1, 8);
let arr = r.to_be_bytes();
Ok(TermValue::from_slice(&arr[8 - width..]))
} else {
let lhs =
evaluate_term_at::<A>(arena, args_start, input_bytes, recurse_value, unfold_value)?;
let rhs = evaluate_term_at::<A>(
arena,
args_start + 1,
input_bytes,
recurse_value,
unfold_value,
)?;
match operator {
crate::PrimitiveOp::Concat => {
let lb = lhs.bytes();
let rb = rhs.bytes();
let total = lb.len() + rb.len();
let cap = if total > TERM_VALUE_MAX_BYTES {
TERM_VALUE_MAX_BYTES
} else {
total
};
let mut buf = [0u8; TERM_VALUE_MAX_BYTES];
let mut i = 0;
while i < lb.len() && i < cap {
buf[i] = lb[i];
i += 1;
}
let mut j = 0;
while j < rb.len() && i < cap {
buf[i] = rb[j];
i += 1;
j += 1;
}
return Ok(TermValue::from_slice(&buf[..cap]));
}
crate::PrimitiveOp::Le
| crate::PrimitiveOp::Lt
| crate::PrimitiveOp::Ge
| crate::PrimitiveOp::Gt => {
let cmp = byte_compare_be(lhs.bytes(), rhs.bytes());
let result_byte: u8 = match operator {
crate::PrimitiveOp::Le => u8::from(cmp != core::cmp::Ordering::Greater),
crate::PrimitiveOp::Lt => u8::from(cmp == core::cmp::Ordering::Less),
crate::PrimitiveOp::Ge => u8::from(cmp != core::cmp::Ordering::Less),
crate::PrimitiveOp::Gt => u8::from(cmp == core::cmp::Ordering::Greater),
_ => 0,
};
return Ok(TermValue::from_slice(&[result_byte]));
}
_ => {}
}
let a = bytes_to_u64_be(lhs.bytes());
let b = bytes_to_u64_be(rhs.bytes());
let width = lhs.bytes().len().max(rhs.bytes().len()).max(1);
let r =
match operator {
crate::PrimitiveOp::Add => a.wrapping_add(b),
crate::PrimitiveOp::Sub => a.wrapping_sub(b),
crate::PrimitiveOp::Mul => a.wrapping_mul(b),
crate::PrimitiveOp::Xor => a ^ b,
crate::PrimitiveOp::And => a & b,
crate::PrimitiveOp::Or => a | b,
_ => return Err(PipelineFailure::ShapeViolation {
report: crate::enforcement::ShapeViolation {
shape_iri: "https://uor.foundation/pipeline/PrimitiveOpArityShape",
constraint_iri:
"https://uor.foundation/pipeline/PrimitiveOpArityShape/unary-as-binary",
property_iri: "https://uor.foundation/pipeline/operatorArity",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 1,
max_count: 1,
kind: crate::ViolationKind::CardinalityViolation,
},
}),
};
let width = if width > 8 { 8 } else { width };
let arr = r.to_be_bytes();
Ok(TermValue::from_slice(&arr[8 - width..]))
}
}
fn byte_compare_be(a: &[u8], b: &[u8]) -> core::cmp::Ordering {
let max_len = if a.len() > b.len() { a.len() } else { b.len() };
let mut i = 0;
while i < max_len {
let ai = if i + a.len() >= max_len {
a[i + a.len() - max_len]
} else {
0u8
};
let bi = if i + b.len() >= max_len {
b[i + b.len() - max_len]
} else {
0u8
};
if ai < bi {
return core::cmp::Ordering::Less;
}
if ai > bi {
return core::cmp::Ordering::Greater;
}
i += 1;
}
core::cmp::Ordering::Equal
}
fn bytes_to_u64_be(bytes: &[u8]) -> u64 {
let take = if bytes.len() > 8 { 8 } else { bytes.len() };
let start = bytes.len() - take;
let mut acc = 0u64;
let mut i = 0;
while i < take {
acc = (acc << 8) | bytes[start + i] as u64;
i += 1;
}
acc
}
impl __sdk_seal::Sealed for ConstrainedTypeInput {}
impl FoundationClosed for ConstrainedTypeInput {
fn arena_slice() -> &'static [crate::enforcement::Term] {
&[]
}
}
impl IntoBindingValue for ConstrainedTypeInput {
const MAX_BYTES: usize = 0;
fn into_binding_bytes(
&self,
_out: &mut [u8],
) -> core::result::Result<usize, crate::enforcement::ShapeViolation> {
Ok(0)
}
}
pub trait CartesianProductShape: ConstrainedTypeShape {
type Left: ConstrainedTypeShape;
type Right: ConstrainedTypeShape;
}
pub const fn kunneth_compose(
a: &[u32; crate::enforcement::MAX_BETTI_DIMENSION],
b: &[u32; crate::enforcement::MAX_BETTI_DIMENSION],
) -> [u32; crate::enforcement::MAX_BETTI_DIMENSION] {
let mut out = [0u32; crate::enforcement::MAX_BETTI_DIMENSION];
let mut i: usize = 0;
while i < crate::enforcement::MAX_BETTI_DIMENSION {
let mut j: usize = 0;
while j < crate::enforcement::MAX_BETTI_DIMENSION - i {
let term = a[i].saturating_mul(b[j]);
out[i + j] = out[i + j].saturating_add(term);
j += 1;
}
i += 1;
}
out
}
pub fn primitive_cartesian_nerve_betti<S: CartesianProductShape>() -> Result<
[u32; crate::enforcement::MAX_BETTI_DIMENSION],
crate::enforcement::GenericImpossibilityWitness,
> {
let left = crate::enforcement::primitive_simplicial_nerve_betti::<S::Left>()?;
let right = crate::enforcement::primitive_simplicial_nerve_betti::<S::Right>()?;
Ok(kunneth_compose(&left, &right))
}
pub const fn shift_constraint(c: ConstraintRef, offset: u32) -> ConstraintRef {
match c {
ConstraintRef::Site { position } => ConstraintRef::Site {
position: position.saturating_add(offset),
},
ConstraintRef::Carry { site } => ConstraintRef::Carry {
site: site.saturating_add(offset),
},
ConstraintRef::Residue { modulus, residue } => ConstraintRef::Residue { modulus, residue },
ConstraintRef::Hamming { bound } => ConstraintRef::Hamming { bound },
ConstraintRef::Depth { min, max } => ConstraintRef::Depth { min, max },
ConstraintRef::SatClauses { clauses, num_vars } => {
ConstraintRef::SatClauses { clauses, num_vars }
}
ConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
} => ConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
},
ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => {
let (out, new_count) =
shift_affine_coefficients(&coefficients, coefficient_count, offset);
ConstraintRef::Affine {
coefficients: out,
coefficient_count: new_count,
bias,
}
}
ConstraintRef::Conjunction {
conjuncts,
conjunct_count,
} => {
let mut out = [LeafConstraintRef::Site { position: 0 }; CONJUNCTION_MAX_TERMS];
let count = conjunct_count as usize;
let mut i = 0;
while i < count && i < CONJUNCTION_MAX_TERMS {
out[i] = shift_leaf_constraint(conjuncts[i], offset);
i += 1;
}
ConstraintRef::Conjunction {
conjuncts: out,
conjunct_count,
}
}
}
}
#[inline]
#[must_use]
const fn shift_affine_coefficients(
coefficients: &[i64; AFFINE_MAX_COEFFS],
coefficient_count: u32,
offset: u32,
) -> ([i64; AFFINE_MAX_COEFFS], u32) {
let mut out = [0i64; AFFINE_MAX_COEFFS];
let count = coefficient_count as usize;
let off = offset as usize;
if off >= AFFINE_MAX_COEFFS {
return (out, 0);
}
let mut i = 0;
while i < count && i + off < AFFINE_MAX_COEFFS {
out[i + off] = coefficients[i];
i += 1;
}
let new_count = (i + off) as u32;
(out, new_count)
}
#[inline]
#[must_use]
pub const fn shift_leaf_constraint(c: LeafConstraintRef, offset: u32) -> LeafConstraintRef {
match c {
LeafConstraintRef::Site { position } => LeafConstraintRef::Site {
position: position.saturating_add(offset),
},
LeafConstraintRef::Carry { site } => LeafConstraintRef::Carry {
site: site.saturating_add(offset),
},
LeafConstraintRef::Residue { modulus, residue } => {
LeafConstraintRef::Residue { modulus, residue }
}
LeafConstraintRef::Hamming { bound } => LeafConstraintRef::Hamming { bound },
LeafConstraintRef::Depth { min, max } => LeafConstraintRef::Depth { min, max },
LeafConstraintRef::SatClauses { clauses, num_vars } => {
LeafConstraintRef::SatClauses { clauses, num_vars }
}
LeafConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
} => LeafConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
},
LeafConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => {
let (out, new_count) =
shift_affine_coefficients(&coefficients, coefficient_count, offset);
LeafConstraintRef::Affine {
coefficients: out,
coefficient_count: new_count,
bias,
}
}
}
}
pub const fn sdk_concat_product_constraints<A, B>(
) -> [ConstraintRef; 2 * crate::enforcement::NERVE_CONSTRAINTS_CAP]
where
A: ConstrainedTypeShape,
B: ConstrainedTypeShape,
{
let mut out =
[ConstraintRef::Site { position: u32::MAX }; 2 * crate::enforcement::NERVE_CONSTRAINTS_CAP];
let left = A::CONSTRAINTS;
let right = B::CONSTRAINTS;
let offset = A::SITE_COUNT as u32;
let mut i: usize = 0;
while i < left.len() {
out[i] = left[i];
i += 1;
}
let mut j: usize = 0;
while j < right.len() {
out[i + j] = shift_constraint(right[j], offset);
j += 1;
}
out
}
pub const fn sdk_product_constraints_len<A, B>() -> usize
where
A: ConstrainedTypeShape,
B: ConstrainedTypeShape,
{
A::CONSTRAINTS.len() + B::CONSTRAINTS.len()
}
pub fn validate_constrained_type<T: ConstrainedTypeShape>(
shape: T,
) -> Result<Validated<T, crate::enforcement::Runtime>, ShapeViolation> {
preflight_feasibility(T::CONSTRAINTS)?;
preflight_package_coherence(T::CONSTRAINTS)?;
Ok(Validated::new(shape))
}
pub const fn validate_constrained_type_const<T: ConstrainedTypeShape + Copy>(
shape: T,
) -> Result<Validated<T, crate::enforcement::CompileTime>, ShapeViolation> {
let constraints = T::CONSTRAINTS;
let mut i = 0;
while i < constraints.len() {
let ok = match &constraints[i] {
ConstraintRef::SatClauses { clauses, num_vars } => *num_vars != 0 || clauses.is_empty(),
ConstraintRef::Residue { modulus, residue } => *modulus != 0 && *residue < *modulus,
ConstraintRef::Carry { .. } => true,
ConstraintRef::Depth { min, max } => *min <= *max,
ConstraintRef::Hamming { bound } => *bound <= 32_768,
ConstraintRef::Site { .. } => true,
ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => {
let count = *coefficient_count as usize;
if count == 0 {
false
} else {
let mut ok_coeff = true;
let mut idx = 0;
while idx < count && idx < AFFINE_MAX_COEFFS {
if coefficients[idx] == i64::MIN {
ok_coeff = false;
break;
}
idx += 1;
}
ok_coeff && is_affine_consistent(coefficients, *coefficient_count, *bias)
}
}
ConstraintRef::Bound { observable_iri, .. } => {
!crate::enforcement::str_eq(
observable_iri,
"https://uor.foundation/observable/LandauerCost",
)
}
ConstraintRef::Conjunction {
conjuncts,
conjunct_count,
} => conjunction_all_sat(conjuncts, *conjunct_count),
};
if !ok {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/type/ConstrainedType",
constraint_iri: "https://uor.foundation/type/ConstrainedType_const_constraint",
property_iri: "https://uor.foundation/type/constraints",
expected_range: "https://uor.foundation/type/Constraint",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
});
}
i += 1;
}
Ok(Validated::new(shape))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FragmentKind {
TwoSat,
Horn,
Residual,
}
#[must_use]
pub const fn fragment_classify(constraints: &[ConstraintRef]) -> FragmentKind {
let mut i = 0;
while i < constraints.len() {
if let ConstraintRef::SatClauses { clauses, .. } = constraints[i] {
let mut max_width: usize = 0;
let mut horn: bool = true;
let mut j = 0;
while j < clauses.len() {
let clause = clauses[j];
if clause.len() > max_width {
max_width = clause.len();
}
let mut positives: usize = 0;
let mut k = 0;
while k < clause.len() {
let (_, negated) = clause[k];
if !negated {
positives += 1;
}
k += 1;
}
if positives > 1 {
horn = false;
}
j += 1;
}
if max_width <= 2 {
return FragmentKind::TwoSat;
} else if horn {
return FragmentKind::Horn;
} else {
return FragmentKind::Residual;
}
}
i += 1;
}
FragmentKind::Residual
}
const TWO_SAT_MAX_VARS: usize = 256;
const TWO_SAT_MAX_NODES: usize = TWO_SAT_MAX_VARS * 2;
const TWO_SAT_MAX_EDGES: usize = 2048;
#[must_use]
pub fn decide_two_sat(clauses: &[&[(u32, bool)]], num_vars: u32) -> bool {
if (num_vars as usize) > TWO_SAT_MAX_VARS {
return false;
}
let n = (num_vars as usize) * 2;
let mut adj_starts = [0usize; TWO_SAT_MAX_NODES + 1];
let mut adj_targets = [0usize; TWO_SAT_MAX_EDGES];
for clause in clauses {
if clause.len() > 2 || clause.is_empty() {
return false;
}
if clause.len() == 1 {
let (v, neg) = clause[0];
let lit = lit_index(v, neg);
let neg_lit = lit_index(v, !neg);
if neg_lit < n + 1 {
adj_starts[neg_lit + 1] += 1;
}
let _ = lit;
} else {
let (a, an) = clause[0];
let (b, bn) = clause[1];
let na = lit_index(a, !an);
let nb = lit_index(b, !bn);
if na + 1 < n + 1 {
adj_starts[na + 1] += 1;
}
if nb + 1 < n + 1 {
adj_starts[nb + 1] += 1;
}
}
}
let mut i = 1;
while i <= n {
adj_starts[i] += adj_starts[i - 1];
i += 1;
}
let edge_count = adj_starts[n];
if edge_count > TWO_SAT_MAX_EDGES {
return false;
}
let mut fill = [0usize; TWO_SAT_MAX_NODES];
for clause in clauses {
if clause.len() == 1 {
let (v, neg) = clause[0];
let pos_lit = lit_index(v, neg);
let neg_lit = lit_index(v, !neg);
let slot = adj_starts[neg_lit] + fill[neg_lit];
adj_targets[slot] = pos_lit;
fill[neg_lit] += 1;
} else {
let (a, an) = clause[0];
let (b, bn) = clause[1];
let pa = lit_index(a, an);
let na = lit_index(a, !an);
let pb = lit_index(b, bn);
let nb = lit_index(b, !bn);
let s1 = adj_starts[na] + fill[na];
adj_targets[s1] = pb;
fill[na] += 1;
let s2 = adj_starts[nb] + fill[nb];
adj_targets[s2] = pa;
fill[nb] += 1;
}
}
let mut index_counter: usize = 0;
let mut indices = [usize::MAX; TWO_SAT_MAX_NODES];
let mut lowlinks = [0usize; TWO_SAT_MAX_NODES];
let mut on_stack = [false; TWO_SAT_MAX_NODES];
let mut stack = [0usize; TWO_SAT_MAX_NODES];
let mut stack_top: usize = 0;
let mut scc_id = [usize::MAX; TWO_SAT_MAX_NODES];
let mut scc_count: usize = 0;
let mut call_stack = [(0usize, 0usize); TWO_SAT_MAX_NODES];
let mut call_top: usize = 0;
let mut v = 0;
while v < n {
if indices[v] == usize::MAX {
call_stack[call_top] = (v, adj_starts[v]);
call_top += 1;
indices[v] = index_counter;
lowlinks[v] = index_counter;
index_counter += 1;
stack[stack_top] = v;
stack_top += 1;
on_stack[v] = true;
while call_top > 0 {
let (u, mut next_edge) = call_stack[call_top - 1];
let end_edge = adj_starts[u + 1];
let mut advanced = false;
while next_edge < end_edge {
let w = adj_targets[next_edge];
next_edge += 1;
if indices[w] == usize::MAX {
call_stack[call_top - 1] = (u, next_edge);
indices[w] = index_counter;
lowlinks[w] = index_counter;
index_counter += 1;
stack[stack_top] = w;
stack_top += 1;
on_stack[w] = true;
call_stack[call_top] = (w, adj_starts[w]);
call_top += 1;
advanced = true;
break;
} else if on_stack[w] && indices[w] < lowlinks[u] {
lowlinks[u] = indices[w];
}
}
if !advanced {
call_stack[call_top - 1] = (u, next_edge);
if lowlinks[u] == indices[u] {
loop {
stack_top -= 1;
let w = stack[stack_top];
on_stack[w] = false;
scc_id[w] = scc_count;
if w == u {
break;
}
}
scc_count += 1;
}
call_top -= 1;
if call_top > 0 {
let (parent, _) = call_stack[call_top - 1];
if lowlinks[u] < lowlinks[parent] {
lowlinks[parent] = lowlinks[u];
}
}
}
}
}
v += 1;
}
let mut var = 0u32;
while var < num_vars {
let pos = lit_index(var, false);
let neg = lit_index(var, true);
if scc_id[pos] == scc_id[neg] {
return false;
}
var += 1;
}
true
}
#[inline]
const fn lit_index(var: u32, negated: bool) -> usize {
let base = (var as usize) * 2;
if negated {
base + 1
} else {
base
}
}
const HORN_MAX_VARS: usize = 256;
#[must_use]
pub fn decide_horn_sat(clauses: &[&[(u32, bool)]], num_vars: u32) -> bool {
if (num_vars as usize) > HORN_MAX_VARS {
return false;
}
let mut assignment = [false; HORN_MAX_VARS];
let n = num_vars as usize;
loop {
let mut changed = false;
for clause in clauses {
let mut positive: Option<u32> = None;
let mut positive_count = 0;
for (_, negated) in clause.iter() {
if !*negated {
positive_count += 1;
}
}
if positive_count > 1 {
return false;
}
for (var, negated) in clause.iter() {
if !*negated {
positive = Some(*var);
}
}
let mut all_neg_satisfied = true;
for (var, negated) in clause.iter() {
if *negated {
let idx = *var as usize;
if idx >= n {
return false;
}
if !assignment[idx] {
all_neg_satisfied = false;
break;
}
}
}
if all_neg_satisfied {
match positive {
None => return false,
Some(v) => {
let idx = v as usize;
if idx >= n {
return false;
}
if !assignment[idx] {
assignment[idx] = true;
changed = true;
}
}
}
}
}
if !changed {
break;
}
}
for clause in clauses {
let mut satisfied = false;
for (var, negated) in clause.iter() {
let idx = *var as usize;
if idx >= n {
return false;
}
let val = assignment[idx];
if (*negated && !val) || (!*negated && val) {
satisfied = true;
break;
}
}
if !satisfied {
return false;
}
}
true
}
pub fn preflight_budget_solvency(budget_units: u64, witt_bits: u32) -> Result<(), ShapeViolation> {
let minimum = witt_bits as u64;
if budget_units >= minimum {
Ok(())
} else {
Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
})
}
}
pub const WITT_MAX_BITS: u16 = 16_384;
#[must_use]
pub fn parse_u32(s: &str) -> u32 {
let bytes = s.as_bytes();
let mut out: u32 = 0;
let mut i = 0;
while i < bytes.len() {
let b = bytes[i];
if !b.is_ascii_digit() {
return 0;
}
out = out.saturating_mul(10).saturating_add((b - b'0') as u32);
i += 1;
}
out
}
#[must_use]
pub fn parse_u64(s: &str) -> u64 {
let bytes = s.as_bytes();
let mut out: u64 = 0;
let mut i = 0;
while i < bytes.len() {
let b = bytes[i];
if !b.is_ascii_digit() {
return 0;
}
out = out.saturating_mul(10).saturating_add((b - b'0') as u64);
i += 1;
}
out
}
#[must_use]
pub fn parse_u64_pair(s: &str) -> (u64, u64) {
let bytes = s.as_bytes();
let mut split = bytes.len();
let mut i = 0;
while i < bytes.len() {
if bytes[i] == b'|' {
split = i;
break;
}
i += 1;
}
if split >= bytes.len() {
return (0, 0);
}
let (left, right_with_pipe) = s.split_at(split);
let (_, right) = right_with_pipe.split_at(1);
(parse_u64(left), parse_u64(right))
}
#[must_use]
pub fn parse_u64_bits_str(s: &str) -> u64 {
parse_u64(s)
}
fn check_bound_feasibility(
observable_iri: &'static str,
bound_shape_iri: &'static str,
args_repr: &'static str,
) -> Result<(), ShapeViolation> {
const VALUE_MOD_IRI: &str = "https://uor.foundation/observable/ValueModObservable";
const CARRY_DEPTH_IRI: &str = "https://uor.foundation/observable/CarryDepthObservable";
const LANDAUER_IRI: &str = "https://uor.foundation/observable/LandauerCost";
let ok = if crate::enforcement::str_eq(observable_iri, VALUE_MOD_IRI) {
let (modulus, residue) = parse_u64_pair(args_repr);
modulus != 0 && residue < modulus
} else if crate::enforcement::str_eq(observable_iri, CARRY_DEPTH_IRI) {
let depth = parse_u32(args_repr);
depth <= WITT_MAX_BITS as u32
} else if crate::enforcement::str_eq(observable_iri, LANDAUER_IRI) {
let bits = parse_u64_bits_str(args_repr);
let nats = <f64 as crate::DecimalTranscendental>::from_bits(bits);
nats.is_finite() && nats > 0.0
} else {
false
};
if ok {
Ok(())
} else {
Err(ShapeViolation {
shape_iri: bound_shape_iri,
constraint_iri: "https://uor.foundation/type/BoundConstraint",
property_iri: observable_iri,
expected_range: "https://uor.foundation/observable/BaseMetric",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
})
}
}
pub fn preflight_feasibility(constraints: &[ConstraintRef]) -> Result<(), ShapeViolation> {
for c in constraints {
if let ConstraintRef::Bound {
observable_iri,
bound_shape_iri,
args_repr,
} = c
{
check_bound_feasibility(observable_iri, bound_shape_iri, args_repr)?;
continue;
}
let ok = match c {
ConstraintRef::SatClauses { clauses, num_vars } => *num_vars != 0 || clauses.is_empty(),
ConstraintRef::Residue { modulus, residue } => *modulus != 0 && *residue < *modulus,
ConstraintRef::Carry { .. } => true,
ConstraintRef::Depth { min, max } => min <= max,
ConstraintRef::Hamming { bound } => *bound <= 32_768,
ConstraintRef::Site { .. } => true,
ConstraintRef::Affine {
coefficients,
coefficient_count,
bias,
} => {
let count = *coefficient_count as usize;
if count == 0 {
false
} else {
let mut ok_coeff = true;
let mut idx = 0;
while idx < count && idx < AFFINE_MAX_COEFFS {
if coefficients[idx] == i64::MIN {
ok_coeff = false;
break;
}
idx += 1;
}
ok_coeff && is_affine_consistent(coefficients, *coefficient_count, *bias)
}
}
ConstraintRef::Bound { .. } => true,
ConstraintRef::Conjunction {
conjuncts,
conjunct_count,
} => conjunction_all_sat(conjuncts, *conjunct_count),
};
if !ok {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
property_iri: "https://uor.foundation/reduction/rootTerm",
expected_range: "https://uor.foundation/schema/Term",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
});
}
}
Ok(())
}
pub fn preflight_dispatch_coverage() -> Result<(), ShapeViolation> {
Ok(())
}
pub fn preflight_package_coherence(constraints: &[ConstraintRef]) -> Result<(), ShapeViolation> {
let mut i = 0;
while i < constraints.len() {
if let ConstraintRef::Residue {
modulus: m1,
residue: r1,
} = constraints[i]
{
let mut j = i + 1;
while j < constraints.len() {
if let ConstraintRef::Residue {
modulus: m2,
residue: r2,
} = constraints[j]
{
if m1 == m2 && r1 != r2 {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
property_iri: "https://uor.foundation/reduction/rootTerm",
expected_range: "https://uor.foundation/schema/Term",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
});
}
}
j += 1;
}
}
i += 1;
}
Ok(())
}
#[must_use]
pub fn estimate_preflight_uor_time<T: ConstrainedTypeShape + ?Sized>(
witt_bits: u16,
) -> crate::enforcement::UorTime {
let steps = (witt_bits as u64).saturating_mul((T::CONSTRAINTS.len() as u64).max(1));
let nats = (steps as f64) * core::f64::consts::LN_2;
crate::enforcement::UorTime::new(crate::enforcement::LandauerBudget::new(nats), steps)
}
#[allow(dead_code)]
pub(crate) const CANONICAL_PREFLIGHT_BUDGET_NS: u64 = 10000000;
pub fn preflight_timing<P: crate::enforcement::TimingPolicy>(
expected: crate::enforcement::UorTime,
) -> Result<(), ShapeViolation> {
let nanos = expected.min_wall_clock(P::CALIBRATION).as_u64();
if nanos <= P::PREFLIGHT_BUDGET_NS {
Ok(())
} else {
Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri: "https://uor.foundation/reduction/PreflightTimingBound",
property_iri: "https://uor.foundation/reduction/preflightBudgetNs",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
})
}
}
#[allow(dead_code)]
pub(crate) const CANONICAL_RUNTIME_BUDGET_NS: u64 = 10000000;
pub fn runtime_timing<P: crate::enforcement::TimingPolicy>(
expected: crate::enforcement::UorTime,
) -> Result<(), ShapeViolation> {
let nanos = expected.min_wall_clock(P::CALIBRATION).as_u64();
if nanos <= P::RUNTIME_BUDGET_NS {
Ok(())
} else {
Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri: "https://uor.foundation/reduction/RuntimeTimingBound",
property_iri: "https://uor.foundation/reduction/runtimeBudgetNs",
expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
min_count: 1,
max_count: 1,
kind: ViolationKind::ValueCheck,
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct StageOutcome {
pub witt_bits: u16,
pub fragment: FragmentKind,
pub satisfiable: bool,
}
pub fn run_reduction_stages<T: ConstrainedTypeShape + ?Sized>(
witt_bits: u16,
) -> Result<StageOutcome, PipelineFailure> {
let fragment = fragment_classify(T::CONSTRAINTS);
let satisfiable = match fragment {
FragmentKind::TwoSat => {
let mut sat = true;
for c in T::CONSTRAINTS {
if let ConstraintRef::SatClauses { clauses, num_vars } = c {
sat = decide_two_sat(clauses, *num_vars);
break;
}
}
sat
}
FragmentKind::Horn => {
let mut sat = true;
for c in T::CONSTRAINTS {
if let ConstraintRef::SatClauses { clauses, num_vars } = c {
sat = decide_horn_sat(clauses, *num_vars);
break;
}
}
sat
}
FragmentKind::Residual => {
let mut has_sat_clauses = false;
for c in T::CONSTRAINTS {
if matches!(c, ConstraintRef::SatClauses { .. }) {
has_sat_clauses = true;
break;
}
}
!has_sat_clauses
}
};
if matches!(fragment, FragmentKind::Residual) && !satisfiable {
return Err(PipelineFailure::ConvergenceStall {
stage_iri: "https://uor.foundation/reduction/stage_convergence",
angle_milliradians: 0,
});
}
Ok(StageOutcome {
witt_bits,
fragment,
satisfiable,
})
}
pub fn run_tower_completeness<T: ConstrainedTypeShape + ?Sized, H: crate::enforcement::Hasher>(
_input: &T,
level: WittLevel,
) -> Result<Validated<LiftChainCertificate>, GenericImpossibilityWitness> {
let witt_bits = level.witt_length() as u16;
preflight_budget_solvency(witt_bits as u64, witt_bits as u32)
.map_err(|_| GenericImpossibilityWitness::default())?;
preflight_feasibility(T::CONSTRAINTS).map_err(|_| GenericImpossibilityWitness::default())?;
preflight_package_coherence(T::CONSTRAINTS)
.map_err(|_| GenericImpossibilityWitness::default())?;
preflight_dispatch_coverage().map_err(|_| GenericImpossibilityWitness::default())?;
let expected = estimate_preflight_uor_time::<T>(witt_bits);
preflight_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| GenericImpossibilityWitness::default())?;
runtime_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| GenericImpossibilityWitness::default())?;
let outcome =
run_reduction_stages::<T>(witt_bits).map_err(|_| GenericImpossibilityWitness::default())?;
if outcome.satisfiable {
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
outcome.witt_bits,
0,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::TowerCompleteness,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let cert = LiftChainCertificate::with_level_and_fingerprint_const(outcome.witt_bits, fp);
Ok(Validated::new(cert))
} else {
Err(GenericImpossibilityWitness::default())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SpectralSequencePage {
page_index: u32,
source_bits: u16,
target_bits: u16,
differential_vanished: bool,
obstruction_class_iri: &'static str,
_sealed: (),
}
impl SpectralSequencePage {
#[inline]
#[must_use]
pub(crate) const fn from_parts(
page_index: u32,
source_bits: u16,
target_bits: u16,
differential_vanished: bool,
obstruction_class_iri: &'static str,
) -> Self {
Self {
page_index,
source_bits,
target_bits,
differential_vanished,
obstruction_class_iri,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn page_index(&self) -> u32 {
self.page_index
}
#[inline]
#[must_use]
pub const fn source_bits(&self) -> u16 {
self.source_bits
}
#[inline]
#[must_use]
pub const fn target_bits(&self) -> u16 {
self.target_bits
}
#[inline]
#[must_use]
pub const fn differential_vanished(&self) -> bool {
self.differential_vanished
}
#[inline]
#[must_use]
pub const fn obstruction_class_iri(&self) -> &'static str {
self.obstruction_class_iri
}
}
pub fn run_incremental_completeness<
T: ConstrainedTypeShape + ?Sized,
H: crate::enforcement::Hasher,
>(
_input: &T,
target_level: WittLevel,
) -> Result<Validated<LiftChainCertificate>, GenericImpossibilityWitness> {
let target_bits = target_level.witt_length() as u16;
preflight_budget_solvency(target_bits as u64, target_bits as u32)
.map_err(|_| GenericImpossibilityWitness::default())?;
preflight_feasibility(T::CONSTRAINTS).map_err(|_| GenericImpossibilityWitness::default())?;
preflight_package_coherence(T::CONSTRAINTS)
.map_err(|_| GenericImpossibilityWitness::default())?;
preflight_dispatch_coverage().map_err(|_| GenericImpossibilityWitness::default())?;
let expected = estimate_preflight_uor_time::<T>(target_bits);
preflight_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| GenericImpossibilityWitness::default())?;
runtime_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| GenericImpossibilityWitness::default())?;
let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()?;
let mut page_index: u32 = 0;
let mut from_bits: u16 = 8;
let mut pages_hasher = H::initial();
while from_bits < target_bits {
let to_bits = if from_bits + 8 > target_bits {
target_bits
} else {
from_bits + 8
};
let outcome_source = run_reduction_stages::<T>(from_bits)
.map_err(|_| GenericImpossibilityWitness::default())?;
let outcome_target = run_reduction_stages::<T>(to_bits)
.map_err(|_| GenericImpossibilityWitness::default())?;
let q: usize = ((page_index as usize) + 1).min(crate::enforcement::MAX_BETTI_DIMENSION - 1);
let betti_q = betti[q];
let differential_vanishes = outcome_source.satisfiable && outcome_target.satisfiable;
let page = SpectralSequencePage::from_parts(
page_index,
from_bits,
to_bits,
differential_vanishes,
if differential_vanishes {
""
} else {
"https://uor.foundation/type/LiftObstruction"
},
);
if !page.differential_vanished() {
return Err(GenericImpossibilityWitness::default());
}
pages_hasher = pages_hasher.fold_bytes(&page_index.to_be_bytes());
pages_hasher = pages_hasher.fold_bytes(&from_bits.to_be_bytes());
pages_hasher = pages_hasher.fold_bytes(&to_bits.to_be_bytes());
pages_hasher = pages_hasher.fold_bytes(&betti_q.to_be_bytes());
page_index += 1;
from_bits = to_bits;
}
let _ = pages_hasher;
let outcome = run_reduction_stages::<T>(target_bits)
.map_err(|_| GenericImpossibilityWitness::default())?;
if !outcome.satisfiable {
return Err(GenericImpossibilityWitness::default());
}
let mut hasher = H::initial();
hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
hasher = crate::enforcement::fold_unit_digest(
hasher,
outcome.witt_bits,
page_index as u64,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::IncrementalCompleteness,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let cert = LiftChainCertificate::with_level_and_fingerprint_const(outcome.witt_bits, fp);
Ok(Validated::new(cert))
}
pub fn run_grounding_aware<H: crate::enforcement::Hasher>(
unit: &CompileUnit,
level: WittLevel,
) -> Result<Validated<GroundingCertificate>, GenericImpossibilityWitness> {
let witt_bits = level.witt_length() as u16;
let root_term = unit.root_term();
let bindings = unit.bindings();
let mut ti = 0;
while ti < root_term.len() {
if let crate::enforcement::Term::Variable { name_index } = root_term[ti] {
let mut found = false;
let mut bi = 0;
while bi < bindings.len() {
if bindings[bi].name_index == name_index {
found = true;
break;
}
bi += 1;
}
if !found {
return Err(GenericImpossibilityWitness::default());
}
}
ti += 1;
}
let mut hasher = H::initial();
hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
hasher = hasher.fold_bytes(&unit.thermodynamic_budget().to_be_bytes());
hasher = hasher.fold_bytes(unit.result_type_iri().as_bytes());
hasher = hasher.fold_byte(0);
let (binding_count, fold_addr) =
crate::enforcement::primitive_session_binding_signature(bindings);
hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
hasher = hasher.fold_byte(crate::enforcement::certificate_kind_discriminant(
crate::enforcement::CertificateKind::Grounding,
));
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let cert = GroundingCertificate::with_level_and_fingerprint_const(witt_bits, fp);
Ok(Validated::new(cert))
}
pub fn run_inhabitance<T: ConstrainedTypeShape + ?Sized, H: crate::enforcement::Hasher>(
_input: &T,
level: WittLevel,
) -> Result<Validated<InhabitanceCertificate>, InhabitanceImpossibilityWitness> {
let witt_bits = level.witt_length() as u16;
preflight_budget_solvency(witt_bits as u64, witt_bits as u32)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
preflight_feasibility(T::CONSTRAINTS)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
preflight_package_coherence(T::CONSTRAINTS)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
preflight_dispatch_coverage().map_err(|_| InhabitanceImpossibilityWitness::default())?;
let expected = estimate_preflight_uor_time::<T>(witt_bits);
preflight_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
runtime_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
let outcome = run_reduction_stages::<T>(witt_bits)
.map_err(|_| InhabitanceImpossibilityWitness::default())?;
if outcome.satisfiable {
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
outcome.witt_bits,
0,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Inhabitance,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let cert = InhabitanceCertificate::with_level_and_fingerprint_const(outcome.witt_bits, fp);
Ok(Validated::new(cert))
} else {
Err(InhabitanceImpossibilityWitness::default())
}
}
pub fn run<T, P, H>(unit: Validated<CompileUnit, P>) -> Result<Grounded<T>, PipelineFailure>
where
T: ConstrainedTypeShape + crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
{
let witt_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let unit_iri = unit.inner().result_type_iri();
if !crate::enforcement::str_eq(unit_iri, T::IRI) {
return Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: unit_iri,
});
}
preflight_budget_solvency(witt_bits as u64, witt_bits as u32)
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
preflight_feasibility(T::CONSTRAINTS)
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
preflight_package_coherence(T::CONSTRAINTS)
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
preflight_dispatch_coverage().map_err(|report| PipelineFailure::ShapeViolation { report })?;
let expected = estimate_preflight_uor_time::<T>(witt_bits);
preflight_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
runtime_timing::<crate::enforcement::CanonicalTimingPolicy>(expected)
.map_err(|report| PipelineFailure::ShapeViolation { report })?;
let outcome = run_reduction_stages::<T>(witt_bits)?;
if !outcome.satisfiable {
return Err(PipelineFailure::ContradictionDetected {
at_step: 0,
trace_iri: "https://uor.foundation/trace/InhabitanceSearchTrace",
});
}
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
witt_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
witt_bits,
content_fingerprint,
));
let bindings = empty_bindings_table();
Ok(Grounded::<T>::new_internal(
grounding,
bindings,
outcome.witt_bits,
unit_address,
content_fingerprint,
))
}
#[must_use]
pub const fn empty_bindings_table() -> BindingsTable {
BindingsTable { entries: &[] }
}
#[allow(dead_code)]
const _BINDING_ENTRY_REF: Option<BindingEntry> = None;
#[allow(dead_code)]
const _COMPLETENESS_CERT_REF: Option<CompletenessCertificate> = None;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ParallelDeclaration<'a> {
payload: u64,
result_type_iri: &'static str,
site_partition: &'a [u32],
disjointness_witness: &'a str,
_sealed: (),
}
impl<'a> ParallelDeclaration<'a> {
#[inline]
#[must_use]
pub const fn new_with_partition<T: ConstrainedTypeShape>(
site_partition: &'a [u32],
disjointness_witness: &'a str,
) -> Self {
Self {
payload: site_partition.len() as u64,
result_type_iri: T::IRI,
site_partition,
disjointness_witness,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn site_count(&self) -> u64 {
self.payload
}
#[inline]
#[must_use]
pub const fn result_type_iri(&self) -> &'static str {
self.result_type_iri
}
#[inline]
#[must_use]
pub const fn site_partition(&self) -> &'a [u32] {
self.site_partition
}
#[inline]
#[must_use]
pub const fn disjointness_witness(&self) -> &'a str {
self.disjointness_witness
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StreamDeclaration<'a> {
payload: u64,
result_type_iri: &'static str,
seed: &'a [Term],
step: &'a [Term],
productivity_witness: &'a str,
_sealed: (),
}
impl<'a> StreamDeclaration<'a> {
#[inline]
#[must_use]
pub const fn new<T: ConstrainedTypeShape>(
productivity_bound: u64,
) -> StreamDeclaration<'static> {
StreamDeclaration {
payload: productivity_bound,
result_type_iri: T::IRI,
seed: &[],
step: &[],
productivity_witness: "",
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn new_full<T: ConstrainedTypeShape>(
productivity_bound: u64,
seed: &'a [Term],
step: &'a [Term],
productivity_witness: &'a str,
) -> Self {
Self {
payload: productivity_bound,
result_type_iri: T::IRI,
seed,
step,
productivity_witness,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn productivity_bound(&self) -> u64 {
self.payload
}
#[inline]
#[must_use]
pub const fn result_type_iri(&self) -> &'static str {
self.result_type_iri
}
#[inline]
#[must_use]
pub const fn seed(&self) -> &'a [Term] {
self.seed
}
#[inline]
#[must_use]
pub const fn step(&self) -> &'a [Term] {
self.step
}
#[inline]
#[must_use]
pub const fn productivity_witness(&self) -> &'a str {
self.productivity_witness
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InteractionDeclaration<'a> {
payload: u64,
result_type_iri: &'static str,
_sealed: (),
_lifetime: core::marker::PhantomData<&'a ()>,
}
impl<'a> InteractionDeclaration<'a> {
#[inline]
#[must_use]
pub const fn new<T: ConstrainedTypeShape>(
convergence_seed: u64,
) -> InteractionDeclaration<'static> {
InteractionDeclaration {
payload: convergence_seed,
result_type_iri: T::IRI,
_sealed: (),
_lifetime: core::marker::PhantomData,
}
}
#[inline]
#[must_use]
pub const fn convergence_seed(&self) -> u64 {
self.payload
}
#[inline]
#[must_use]
pub const fn result_type_iri(&self) -> &'static str {
self.result_type_iri
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PeerPayload {
words: [u64; 32],
bit_width: u16,
_sealed: (),
}
impl PeerPayload {
#[inline]
#[must_use]
pub const fn zero(bit_width: u16) -> Self {
Self {
words: [0u64; 32],
bit_width,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn words(&self) -> &[u64; 32] {
&self.words
}
#[inline]
#[must_use]
pub const fn bit_width(&self) -> u16 {
self.bit_width
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PeerInput {
peer_id: u128,
payload: PeerPayload,
_sealed: (),
}
impl PeerInput {
#[inline]
#[must_use]
pub const fn new(peer_id: u128, payload: PeerPayload) -> Self {
Self {
peer_id,
payload,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn peer_id(&self) -> u128 {
self.peer_id
}
#[inline]
#[must_use]
pub const fn payload(&self) -> &PeerPayload {
&self.payload
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum StepResult<T: crate::enforcement::GroundedShape> {
Continue,
Output(Grounded<T>),
Converged(Grounded<T>),
Diverged,
Failure(PipelineFailure),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CommutatorState<L> {
accumulator: [u64; 4],
_level: core::marker::PhantomData<L>,
_sealed: (),
}
impl<L> CommutatorState<L> {
#[inline]
#[must_use]
pub const fn zero() -> Self {
Self {
accumulator: [0u64; 4],
_level: core::marker::PhantomData,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn accumulator(&self) -> &[u64; 4] {
&self.accumulator
}
}
#[derive(Debug, Clone)]
pub struct StreamDriver<
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
> {
rewrite_steps: u64,
landauer_nats: u64,
productivity_countdown: u64,
seed: u64,
result_type_iri: &'static str,
terminated: bool,
_shape: core::marker::PhantomData<T>,
_phase: core::marker::PhantomData<P>,
_hasher: core::marker::PhantomData<H>,
_sealed: (),
}
impl<
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
> StreamDriver<T, P, H>
{
#[inline]
#[must_use]
#[allow(dead_code)]
pub(crate) const fn new_internal(
productivity_bound: u64,
seed: u64,
result_type_iri: &'static str,
) -> Self {
Self {
rewrite_steps: 0,
landauer_nats: 0,
productivity_countdown: productivity_bound,
seed,
result_type_iri,
terminated: false,
_shape: core::marker::PhantomData,
_phase: core::marker::PhantomData,
_hasher: core::marker::PhantomData,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn rewrite_steps(&self) -> u64 {
self.rewrite_steps
}
#[inline]
#[must_use]
pub const fn landauer_nats(&self) -> u64 {
self.landauer_nats
}
#[inline]
#[must_use]
pub const fn is_terminated(&self) -> bool {
self.terminated
}
}
impl<
T: crate::enforcement::GroundedShape + ConstrainedTypeShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
> Iterator for StreamDriver<T, P, H>
{
type Item = Result<Grounded<T>, PipelineFailure>;
fn next(&mut self) -> Option<Self::Item> {
if self.terminated || self.productivity_countdown == 0 {
self.terminated = true;
return None;
}
if self.rewrite_steps == 0 && !crate::enforcement::str_eq(self.result_type_iri, T::IRI) {
self.terminated = true;
return Some(Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: self.result_type_iri,
}));
}
self.productivity_countdown -= 1;
self.rewrite_steps += 1;
self.landauer_nats += 1;
let mut hasher = H::initial();
hasher = crate::enforcement::fold_stream_step_digest(
hasher,
self.productivity_countdown,
self.rewrite_steps,
self.seed,
self.result_type_iri,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
32,
content_fingerprint,
));
let bindings = empty_bindings_table();
Some(Ok(Grounded::<T>::new_internal(
grounding,
bindings,
32, unit_address,
content_fingerprint,
)))
}
}
#[derive(Debug, Clone)]
pub struct InteractionDriver<
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
> {
commutator_acc: [u64; 4],
peer_step_count: u64,
converged: bool,
seed: u64,
prev_commutator_norm: u64,
consecutive_non_decreasing: u32,
result_type_iri: &'static str,
_shape: core::marker::PhantomData<T>,
_phase: core::marker::PhantomData<P>,
_hasher: core::marker::PhantomData<H>,
_sealed: (),
}
pub const INTERACTION_DIVERGENCE_BUDGET: u32 = 16;
impl<
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
> InteractionDriver<T, P, H>
{
#[inline]
#[must_use]
#[allow(dead_code)]
pub(crate) const fn new_internal(seed: u64, result_type_iri: &'static str) -> Self {
Self {
commutator_acc: [seed, 0, 0, 0],
peer_step_count: 0,
converged: false,
seed,
prev_commutator_norm: seed.saturating_mul(seed),
consecutive_non_decreasing: 0,
result_type_iri,
_shape: core::marker::PhantomData,
_phase: core::marker::PhantomData,
_hasher: core::marker::PhantomData,
_sealed: (),
}
}
#[inline]
#[must_use]
pub const fn convergence_threshold(&self) -> u64 {
self.seed.rotate_right(32) ^ 0xDEAD_BEEF_CAFE_BABE
}
#[must_use]
pub fn step(&mut self, input: PeerInput) -> StepResult<T>
where
T: ConstrainedTypeShape,
{
self.peer_step_count += 1;
let words = input.payload().words();
let mut i = 0usize;
while i < 4 {
self.commutator_acc[i] ^= words[i];
i += 1;
}
let mut norm: u64 = 0;
let mut j = 0usize;
while j < 4 {
let limb = self.commutator_acc[j];
norm = norm.saturating_add(limb.saturating_mul(limb));
j += 1;
}
let threshold = self.convergence_threshold();
let norm_converged = norm < threshold;
let handshake_close = input.peer_id() == 0;
if norm_converged || handshake_close {
self.converged = true;
let mut hasher = H::initial();
hasher = crate::enforcement::fold_interaction_step_digest(
hasher,
&self.commutator_acc,
self.peer_step_count,
self.seed,
self.result_type_iri,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
32,
content_fingerprint,
));
let bindings = empty_bindings_table();
return StepResult::Converged(Grounded::<T>::new_internal(
grounding,
bindings,
32,
unit_address,
content_fingerprint,
));
}
if norm >= self.prev_commutator_norm {
self.consecutive_non_decreasing = self.consecutive_non_decreasing.saturating_add(1);
} else {
self.consecutive_non_decreasing = 0;
}
self.prev_commutator_norm = norm;
if self.consecutive_non_decreasing >= INTERACTION_DIVERGENCE_BUDGET {
return StepResult::Diverged;
}
StepResult::Continue
}
#[inline]
#[must_use]
pub const fn is_converged(&self) -> bool {
self.converged
}
#[inline]
#[must_use]
pub const fn peer_step_count(&self) -> u64 {
self.peer_step_count
}
#[inline]
#[must_use]
pub const fn seed(&self) -> u64 {
self.seed
}
pub fn finalize(self) -> Result<Grounded<T>, PipelineFailure>
where
T: ConstrainedTypeShape,
{
if !crate::enforcement::str_eq(self.result_type_iri, T::IRI) {
return Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: self.result_type_iri,
});
}
if !self.converged {
return Err(PipelineFailure::ShapeViolation {
report: ShapeViolation {
shape_iri: "https://uor.foundation/conformance/InteractionShape",
constraint_iri:
"https://uor.foundation/conformance/InteractionShape#convergence",
property_iri: "https://uor.foundation/conformance/convergencePredicate",
expected_range: "http://www.w3.org/2002/07/owl#Thing",
min_count: 1,
max_count: 1,
kind: ViolationKind::Missing,
},
});
}
let mut hasher = H::initial();
hasher = crate::enforcement::fold_interaction_step_digest(
hasher,
&self.commutator_acc,
self.peer_step_count,
self.seed,
self.result_type_iri,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
32,
content_fingerprint,
));
let bindings = empty_bindings_table();
Ok(Grounded::<T>::new_internal(
grounding,
bindings,
32,
unit_address,
content_fingerprint,
))
}
}
pub fn run_parallel<T, P, H>(
unit: Validated<ParallelDeclaration, P>,
) -> Result<Grounded<T>, PipelineFailure>
where
T: ConstrainedTypeShape + crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
{
let decl = unit.inner();
let site_count = decl.site_count();
let partition = decl.site_partition();
let witness_iri = decl.disjointness_witness();
if !crate::enforcement::str_eq(decl.result_type_iri(), T::IRI) {
return Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: decl.result_type_iri(),
});
}
if site_count == 0 || partition.is_empty() {
return Err(PipelineFailure::ContradictionDetected {
at_step: 0,
trace_iri: "https://uor.foundation/parallel/ParallelProduct",
});
}
if partition.len() as u64 != site_count {
return Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: decl.result_type_iri(),
});
}
let mut hasher = H::initial();
let mut component_ids = [0u32; WITT_MAX_BITS as usize];
let mut component_counts = [0u32; WITT_MAX_BITS as usize];
let mut n_components: usize = 0;
let mut si = 0;
while si < partition.len() {
let cid = partition[si];
let mut ci = 0;
let mut found = false;
while ci < n_components {
if component_ids[ci] == cid {
component_counts[ci] = component_counts[ci].saturating_add(1);
found = true;
break;
}
ci += 1;
}
if !found && n_components < (WITT_MAX_BITS as usize) {
component_ids[n_components] = cid;
component_counts[n_components] = 1;
n_components += 1;
}
si += 1;
}
let mut ci = 0;
while ci < n_components {
hasher = hasher.fold_bytes(&component_ids[ci].to_be_bytes());
hasher = hasher.fold_bytes(&component_counts[ci].to_be_bytes());
ci += 1;
}
hasher = hasher.fold_bytes(witness_iri.as_bytes());
hasher = hasher.fold_byte(0);
hasher = crate::enforcement::fold_parallel_digest(
hasher,
site_count,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
32,
content_fingerprint,
));
let bindings = empty_bindings_table();
Ok(Grounded::<T>::new_internal(
grounding,
bindings,
32,
unit_address,
content_fingerprint,
))
}
#[must_use]
pub fn run_stream<T, P, H>(unit: Validated<StreamDeclaration, P>) -> StreamDriver<T, P, H>
where
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
{
let bound = unit.inner().productivity_bound();
let result_type_iri = unit.inner().result_type_iri();
StreamDriver::new_internal(bound, bound, result_type_iri)
}
#[must_use]
pub fn run_interactive<T, P, H>(
unit: Validated<InteractionDeclaration, P>,
) -> InteractionDriver<T, P, H>
where
T: crate::enforcement::GroundedShape,
P: crate::enforcement::ValidationPhase,
H: crate::enforcement::Hasher,
{
InteractionDriver::new_internal(
unit.inner().convergence_seed(),
unit.inner().result_type_iri(),
)
}
pub const fn validate_lease_const<'a>(
builder: &LeaseDeclarationBuilder<'a>,
) -> Result<Validated<LeaseDeclaration, CompileTime>, ShapeViolation> {
builder.validate_const()
}
pub const fn validate_compile_unit_const<'a>(
builder: &CompileUnitBuilder<'a>,
) -> Result<Validated<CompileUnit<'a>, CompileTime>, ShapeViolation> {
if !builder.has_root_term_const() {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri: "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
property_iri: "https://uor.foundation/reduction/rootTerm",
expected_range: "https://uor.foundation/schema/Term",
min_count: 1,
max_count: 1,
kind: ViolationKind::Missing,
});
}
let level = match builder.witt_level_option() {
Some(l) => l,
None => {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_unitWittLevel_constraint",
property_iri: "https://uor.foundation/reduction/unitWittLevel",
expected_range: "https://uor.foundation/schema/WittLevel",
min_count: 1,
max_count: 1,
kind: ViolationKind::Missing,
})
}
};
let budget =
match builder.budget_option() {
Some(b) => b,
None => return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
min_count: 1,
max_count: 1,
kind: ViolationKind::Missing,
}),
};
if !builder.has_target_domains_const() {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_targetDomains_constraint",
property_iri: "https://uor.foundation/reduction/targetDomains",
expected_range: "https://uor.foundation/op/VerificationDomain",
min_count: 1,
max_count: 0,
kind: ViolationKind::Missing,
});
}
let result_type_iri = match builder.result_type_iri_const() {
Some(iri) => iri,
None => {
return Err(ShapeViolation {
shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
constraint_iri:
"https://uor.foundation/conformance/compileUnit_resultType_constraint",
property_iri: "https://uor.foundation/reduction/resultType",
expected_range: "https://uor.foundation/type/ConstrainedType",
min_count: 1,
max_count: 1,
kind: ViolationKind::Missing,
})
}
};
Ok(Validated::new(CompileUnit::from_parts_const(
level,
budget,
result_type_iri,
builder.root_term_slice_const(),
builder.bindings_slice_const(),
builder.target_domains_slice_const(),
)))
}
#[must_use]
pub const fn validate_parallel_const<'a, T: ConstrainedTypeShape>(
builder: &ParallelDeclarationBuilder<'a>,
) -> Validated<ParallelDeclaration<'a>, CompileTime> {
Validated::new(ParallelDeclaration::new_with_partition::<T>(
builder.site_partition_slice_const(),
builder.disjointness_witness_const(),
))
}
#[must_use]
pub const fn validate_stream_const<'a, T: ConstrainedTypeShape>(
builder: &StreamDeclarationBuilder<'a>,
) -> Validated<StreamDeclaration<'a>, CompileTime> {
let bound = builder.productivity_bound_const();
Validated::new(StreamDeclaration::new_full::<T>(
bound,
builder.seed_slice_const(),
builder.step_slice_const(),
builder.productivity_witness_const(),
))
}
#[must_use]
pub fn certify_tower_completeness_const<T, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Validated<GroundingCertificate, CompileTime>
where
T: ConstrainedTypeShape,
H: crate::enforcement::Hasher,
{
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::TowerCompleteness,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
level_bits, fp,
))
}
#[must_use]
pub fn certify_incremental_completeness_const<T, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Validated<GroundingCertificate, CompileTime>
where
T: ConstrainedTypeShape,
H: crate::enforcement::Hasher,
{
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::IncrementalCompleteness,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
level_bits, fp,
))
}
#[must_use]
pub fn certify_inhabitance_const<T, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Validated<GroundingCertificate, CompileTime>
where
T: ConstrainedTypeShape,
H: crate::enforcement::Hasher,
{
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Inhabitance,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
level_bits, fp,
))
}
#[must_use]
pub fn certify_multiplication_const<T, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Validated<MultiplicationCertificate, CompileTime>
where
T: ConstrainedTypeShape,
H: crate::enforcement::Hasher,
{
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Multiplication,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
Validated::new(MultiplicationCertificate::with_level_and_fingerprint_const(
level_bits, fp,
))
}
#[must_use]
pub fn certify_grounding_aware_const<T, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Validated<GroundingCertificate, CompileTime>
where
T: ConstrainedTypeShape,
H: crate::enforcement::Hasher,
{
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let fp = crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
level_bits, fp,
))
}
pub fn run_const<T, M, H>(
unit: &Validated<CompileUnit, CompileTime>,
) -> Result<Grounded<T>, PipelineFailure>
where
T: ConstrainedTypeShape + crate::enforcement::GroundedShape,
M: crate::enforcement::GroundingMapKind
+ crate::enforcement::Total
+ crate::enforcement::Invertible,
H: crate::enforcement::Hasher,
{
let _phantom_map: core::marker::PhantomData<M> = core::marker::PhantomData;
let level_bits = unit.inner().witt_level().witt_length() as u16;
let budget = unit.inner().thermodynamic_budget();
let unit_iri = unit.inner().result_type_iri();
if !crate::enforcement::str_eq(unit_iri, T::IRI) {
return Err(PipelineFailure::ShapeMismatch {
expected: T::IRI,
got: unit_iri,
});
}
let mut hasher = H::initial();
hasher = crate::enforcement::fold_unit_digest(
hasher,
level_bits,
budget,
T::IRI,
T::SITE_COUNT,
T::CONSTRAINTS,
crate::enforcement::CertificateKind::Grounding,
);
let buffer = hasher.finalize();
let content_fingerprint =
crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
let unit_address = crate::enforcement::unit_address_from_buffer(&buffer);
let grounding = Validated::new(GroundingCertificate::with_level_and_fingerprint_const(
level_bits,
content_fingerprint,
));
let bindings = empty_bindings_table();
Ok(Grounded::<T>::new_internal(
grounding,
bindings,
level_bits,
unit_address,
content_fingerprint,
))
}