///|
fn validate_digest(r : Record) -> Unit raise ModelError {
if text(r, "algorithm") != "sha256" {
fail("conceptual.invalid_record", r.path + "/algorithm")
}
let value = text(r, "value")
if value.length() != 64 ||
!value.iter().all(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {
fail("conceptual.invalid_record", r.path + "/value")
}
}
///|
fn resolved_reference(r : Record) -> ResolvedRef raise ModelError {
match reference(r) {
Resolved(value) => value
Unresolved(_, _, _) => {
fail("conceptual.invalid_variant", r.path)
abort("unreachable")
}
}
}
///|
fn forbid(r : Record, names : Array[String]) -> Unit raise ModelError {
for name in names {
if r.fields.contains(name) {
fail("conceptual.invalid_variant", r.path + "/" + name)
}
}
}
///|
fn trait_interpretation(r : Record) -> TraitInterpretation raise ModelError {
match text(r, "kind") {
"descriptive" => {
forbid(r, ["profiles"])
Descriptive
}
"semantic" => {
let profiles = strings(r, "profiles")
let seen : Map[String, Bool] = Map([])
if profiles.is_empty() {
fail("conceptual.invalid_record", r.path + "/profiles")
}
for p in profiles {
if seen.contains(p) {
fail("conceptual.invalid_record", r.path + "/profiles")
}
seen[p] = true
}
Semantic(
profiles.map(p => {
@intent.Id::parse(p) catch {
_ => abort("validated identifier")
}
}),
)
}
_ => {
fail("conceptual.unsupported_variant", r.path + "/kind")
abort("unreachable")
}
}
}
///|
fn trait_target(r : Record) -> TraitTarget raise ModelError {
match text(r, "kind") {
"model" => {
forbid(r, ["ref", "artifact", "node", "profile"])
ModelTarget(snapshot(child(r, "model")))
}
"module" => {
forbid(r, ["ref", "model", "profile"])
ModuleTarget(
snapshot(child(r, "artifact")),
text(r, "node", nonempty=true),
)
}
"concept" | "type" | "member" | "function" as name => {
forbid(r, ["model", "artifact", "node", "profile"])
let kind = match name {
"concept" => ConceptTarget
"type" => TypeTarget
"member" => MemberTarget
_ => FunctionTarget
}
EntityTarget(kind, reference(child(r, "ref")))
}
"operation" | "serviceBinding" as name => {
forbid(r, ["model", "artifact", "node"])
ProfileTarget(
if name == "operation" {
OperationTarget
} else {
ServiceBindingTarget
},
id(r, "profile"),
reference(child(r, "ref")),
)
}
_ => UnknownTarget(r)
}
}
///|
fn validate_concern(c : Record, name : String) -> Unit raise ModelError {
let state = text(c, "state")
match name {
"implementation" =>
match state {
"unbound" => forbid(c, ["binding"])
"bound" =>
if reference(child(c, "binding")) is Unresolved(_, _, _) {
fail("conceptual.invalid_variant", c.path + "/binding")
}
_ => fail("conceptual.unsupported_variant", c.path + "/state")
}
"elaboration" =>
match state {
"open" => {
forbid(c, ["rationale"])
if items(c, "aspects").is_empty() {
fail("conceptual.invalid_record", c.path + "/aspects")
}
}
"settled" => {
forbid(c, ["aspects"])
ignore(text(c, "rationale"))
}
_ => fail("conceptual.unsupported_variant", c.path + "/state")
}
"definition" =>
match state {
"completeSpecification" | "completeDefinition" =>
forbid(c, ["reason", "sourceRefs"])
"authoredPartial" => {
ignore(text(c, "reason"))
ignore(items(c, "sourceRefs"))
}
_ => fail("conceptual.unsupported_variant", c.path + "/state")
}
"recovery" =>
match state {
"clean" => forbid(c, ["sourceRef", "diagnostics"])
"recovering" => {
ignore(child(c, "sourceRef"))
if items(c, "diagnostics").is_empty() {
fail("conceptual.invalid_record", c.path + "/diagnostics")
}
}
_ => fail("conceptual.unsupported_variant", c.path + "/state")
}
"review" => {
ignore(revision(c, "entityRevision"))
ignore(revision(c, "modelRevision"))
match state {
"unreviewed" | "pending" => forbid(c, ["reviewer", "rationale"])
"accepted" | "rejected" => {
ignore(id(c, "reviewer"))
ignore(text(c, "rationale"))
}
_ => fail("conceptual.unsupported_variant", c.path + "/state")
}
}
_ => ()
}
}
///|
fn tracked_snapshot(
r : Record,
records : Array[Record],
) -> Snapshot raise ModelError {
let result = snapshot(r)
records.push(r)
result
}
///|
fn context_records(
r : Record,
records : Array[Record],
) -> Unit raise ModelError {
records.push(r)
ignore(tracked_snapshot(child(r, "model"), records))
for name in ["entities", "sources", "implementations"] {
let seen : Map[String, Bool] = Map([])
for item in record_list(r, name) {
let identity = tracked_snapshot(item, records)
if seen.contains(identity.id.value()) {
fail("conceptual.duplicate_identity", item.path + "/id")
}
seen[identity.id.value()] = true
}
}
}
///|
fn exact_nat(
r : Record,
name : String,
positive~ : Bool = false,
) -> Unit raise ModelError {
let v = required(r, name)
match v.kind() {
Int(n) if !v.has_annotations() &&
!n.to_string().has_prefix("-") &&
(!positive || n.to_string() != "0") => ()
_ => fail("conceptual.invalid_record", r.path + "/" + name)
}
}
///|
fn producer(r : Record, records : Array[Record]) -> Unit raise ModelError {
ignore(id(r, "id"))
ignore(text(r, "version", nonempty=true))
ignore(id(r, "profile"))
records.push(r)
}
///|
fn content_records(
kind : EntityKind,
c : Record,
records : Array[Record],
) -> Unit raise ModelError {
match kind {
Claim | Evidence => context_records(child(c, "context"), records)
_ => ()
}
match kind {
Declaration => {
let role = text(c, "role")
if !["function", "type", "field", "parameter", "result"].contains(role) {
fail("conceptual.unsupported_variant", c.path + "/role")
}
if role == "function" || role == "type" {
ignore(strings(c, "typeParameters"))
}
if c.fields.contains("representation") {
let r = child(c, "representation")
records.push(r)
match text(r, "state") {
"known" => {
forbid(r, ["reason"])
ignore(required(r, "type"))
if !["public", "defining-module"].contains(text(r, "access")) {
fail("conceptual.unsupported_variant", r.path + "/access")
}
}
"undecided" => {
forbid(r, ["type", "access"])
ignore(text(r, "reason"))
}
_ => fail("conceptual.unsupported_variant", r.path + "/state")
}
}
}
Contract => {
if !["refinement", "invariant", "precondition", "postcondition"].contains(
text(c, "clauseKind"),
) {
fail("conceptual.unsupported_variant", c.path + "/clauseKind")
}
let expression = child(c, "expression")
match text(expression, "state") {
"resolved" => {
forbid(expression, ["reason"])
ignore(id(expression, "profile"))
ignore(required(expression, "ast"))
}
"unresolved" => {
forbid(expression, ["profile", "ast"])
ignore(text(expression, "reason"))
}
_ => fail("conceptual.unsupported_variant", expression.path + "/state")
}
if c.fields.contains("compiledArtifact") {
let artifact = child(c, "compiledArtifact")
records.push(artifact)
ignore(tracked_snapshot(child(artifact, "artifact"), records))
producer(child(artifact, "compiler"), records)
ignore(revision(artifact, "contractRevision"))
for binding in record_list(artifact, "argumentMap") {
records.push(binding)
ignore(id(binding, "binderId"))
exact_nat(binding, "position")
}
}
}
Scenario => {
let origin = child(c, "origin")
match text(origin, "kind") {
"authored" => {
forbid(origin, ["generator", "configuration", "seed"])
ignore(id(origin, "author"))
}
"generated" => {
forbid(origin, ["author"])
let generator = child(origin, "generator")
ignore(id(generator, "id"))
ignore(text(generator, "version", nonempty=true))
records.push(generator)
ignore(required(origin, "configuration"))
}
_ => fail("conceptual.unsupported_variant", origin.path + "/kind")
}
}
Implementation => {
ignore(tracked_snapshot(child(c, "artifact"), records))
if !["declared", "supplied"].contains(text(c, "availability")) {
fail("conceptual.unsupported_variant", c.path + "/availability")
}
}
Evidence =>
match text(c, "evidenceKind") {
"run" => {
ignore(id(c, "valueProfile"))
ignore(required(c, "input"))
let output = child(c, "output")
records.push(output)
match text(output, "state") {
"observed" => {
forbid(output, ["reason"])
ignore(required(output, "value"))
}
"absent" => {
forbid(output, ["value"])
if !["notInvoked", "executionError", "missingResult"].contains(
text(output, "reason"),
) {
fail("conceptual.unsupported_variant", output.path + "/reason")
}
}
_ => fail("conceptual.unsupported_variant", output.path + "/state")
}
for clause in record_list(c, "clauses") {
records.push(clause)
ignore(id(clause, "entityId"))
ignore(revision(clause, "entityRevision"))
ignore(text(clause, "observation"))
}
producer(child(c, "evaluator"), records)
let environment = child(c, "environment")
records.push(environment)
ignore(text(environment, "target"))
ignore(required(environment, "configuration"))
let limits = child(c, "limits")
records.push(limits)
exact_nat(limits, "steps", positive=true)
exact_nat(limits, "depth", positive=true)
}
"analysis" => {
producer(child(c, "analyzer"), records)
ignore(required(c, "scope"))
ignore(required(c, "result"))
}
"review" => {
ignore(id(c, "reviewer"))
ignore(text(c, "decision"))
ignore(text(c, "rationale"))
}
_ => fail("conceptual.unsupported_variant", c.path + "/evidenceKind")
}
_ => ()
}
}