aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2026-05-07 15:33:30 +0100
committertslil <tslil@posteo.de>2026-05-07 16:19:27 +0100
commit77d637846be1eb0d140612731c80ca7a6cf1bb29 (patch)
treeb5adb44f73a59644e54e7a21d7fbe9160f70b0bb /src
parent8d9c0e5868b2a7fa22080f814357dcda69a10057 (diff)
fix failure to add hypotheticals for instances of compound signatures
Diffstat (limited to 'src')
-rw-r--r--src/checker_signature.rs52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/checker_signature.rs b/src/checker_signature.rs
index 6acd271..55682a9 100644
--- a/src/checker_signature.rs
+++ b/src/checker_signature.rs
@@ -90,11 +90,11 @@ impl CheckerState {
let mut new_fields = Vec::new();
for Field { carries, name } in fields {
let signature = ctx.check_signature(carries)?;
- ctx.add_instance(name.clone(), InstanceValue::Hypothetical, signature.clone())?;
- // And lo, the special case, our chosen canonical form
- if signature == Signature::Set {
- ctx.add_set(name.clone(), Set::ClaimedSet(Instance::Var(name.clone())))?;
- }
+ ctx._recursively_add_hypothetical_instance(
+ name.clone(),
+ signature.clone(),
+ None,
+ )?;
new_fields.push(Field {
name: name.clone(),
carries: signature,
@@ -112,6 +112,48 @@ impl CheckerState {
}
}
+ // the goal here is to spread the love: if we are adding a hypothetical of
+ // some signature _ : theory { ... } then we must recurse into all of those
+ // fields and add hypotheticals for them---but, we need to build the tree as
+ // we go, giving them the concrete value of their path from the root (our
+ // canonical form).
+ fn _recursively_add_hypothetical_instance(
+ &mut self,
+ name: String,
+ signature: Signature,
+ head: Option<&Instance>,
+ ) -> Result<(), CheckerError> {
+ let value = match head {
+ Some(h) => InstanceValue::Concrete(Instance::Project {
+ instance: Box::new(h.clone()),
+ field: name.clone(),
+ }),
+ None => InstanceValue::Hypothetical,
+ };
+ let self_instance = match head {
+ Some(h) => Instance::Project {
+ instance: Box::new(h.clone()),
+ field: name.clone(),
+ },
+ None => Instance::Var(name.clone()),
+ };
+ // handle the special case canonical form for _ :: Set
+ if signature == Signature::Set {
+ self.add_set(name.clone(), Set::ClaimedSet(self_instance.clone()))?;
+ }
+ self.add_instance(name.clone(), value, signature.clone())?;
+ if let Signature::Theory(fields) = signature {
+ for f in fields {
+ self._recursively_add_hypothetical_instance(
+ f.name,
+ f.carries,
+ Some(&self_instance),
+ )?;
+ }
+ }
+ Ok(())
+ }
+
#[instrument(skip(self), level = "debug", fields(%instance, signature=%signature.map(|s| s.to_string()).unwrap_or_default()) )]
pub fn check_instance(
&self,