use crate::bounded::{Bounded, Capped};
use crate::diagnostic::{REPAIR_LIMIT, Repair};
use crate::identity::{
self, ClosureId, ExplanationId, Identity, OwnerFact, PlanId, Profile, Provenance,
};
use crate::kind::{Disposition, Kind, Question};
use crate::plan::{DEPENDENCY_LIMIT, InvalidationSet, MEMBERSHIP_LIMIT, PlannedOutput};
use core::marker::PhantomData;
#[path = "type_guard.rs"]
mod guard;
pub const UNIVERSAL_QUESTION_COUNT: usize = 9;
pub const ASSUMPTION_LIMIT: usize = 16;
pub const RELATED_KIND_LIMIT: usize = 16;
pub const DECLARED_QUESTION_LIMIT: usize = 32;
pub const EXPLANATION_ISSUE_LIMIT: usize = 48;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum UniversalQuestion {
WhatAreYou,
WhichOwnerRequired,
WhichDeclarationCaused,
WhichProfile,
WhichOutputAndDigest,
WhichAssumptions,
WhatInvalidates,
WhyRelatedNotGenerated,
WhatRepairsARefusal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RelatedDisposition {
pub kind: &'static str,
pub disposition: Disposition,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AnsweredOutput {
pub output: Box<PlannedOutput>,
pub digest: Identity<identity::OutputBytes>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum UniversalAnswer {
Kind {
name: &'static str,
},
Owner {
owner: OwnerFact,
},
CausingDeclarations {
commitment: Identity<identity::CapturedDeclaration>,
dependencies: Bounded<Identity<identity::CapturedDeclaration>, DEPENDENCY_LIMIT>,
},
Profile {
profile: Profile,
},
OutputAndDigest {
outputs: Bounded<AnsweredOutput, MEMBERSHIP_LIMIT>,
},
Assumptions {
assumptions: Bounded<OwnerFact, ASSUMPTION_LIMIT>,
},
Invalidators {
triggers: InvalidationSet,
},
RelatedDispositions {
related: Bounded<RelatedDisposition, RELATED_KIND_LIMIT>,
},
Repairs {
repairs: Bounded<Repair, REPAIR_LIMIT>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ExplanationIssue {
UniversalUnanswered {
question: UniversalQuestion,
},
UniversalAnsweredTwice {
question: UniversalQuestion,
},
DeclaredUnanswered {
question: &'static str,
slot: u16,
},
DeclaredAnsweredTwice {
question: &'static str,
slot: u16,
},
QuestionOutsideRoster {
question: &'static str,
},
SeatBoundExceeded {
bound: u64,
observed: u64,
},
OutputsBesideTheProof {
expected: u16,
observed: u16,
diverges: u16,
},
}
#[must_use = "a coverage refusal carries every uncovered, doubled, and inadmissible question"]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ExplanationError {
body: Capped<ExplanationIssue, EXPLANATION_ISSUE_LIMIT>,
}
#[must_use = "a complete view is the proof every question has exactly one answer, over the plan and closure it names"]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct View<K: Kind> {
plan: PlanId,
closure: ClosureId,
universal: Bounded<UniversalAnswer, UNIVERSAL_QUESTION_COUNT>,
declared: Bounded<<K::Question as Question>::Answer, DECLARED_QUESTION_LIMIT>,
identity: ExplanationId,
provenance: Provenance,
kind: PhantomData<K>,
}