From a24f2d1367b2848779014c7bb3ecfe6bfbcff7d7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 24 Jan 2020 18:38:30 +0000 Subject: Fix some variable shifting failures --- dhall/src/semantics/core/context.rs | 17 +++++++++++++++-- dhall/src/semantics/core/value.rs | 18 +++++++++++------- dhall/src/semantics/nze/nzexpr.rs | 8 ++++++++ dhall/src/semantics/phase/normalize.rs | 24 +++++++++++++++++++----- 4 files changed, 53 insertions(+), 14 deletions(-) (limited to 'dhall/src/semantics') diff --git a/dhall/src/semantics/core/context.rs b/dhall/src/semantics/core/context.rs index 7972a20..0e62fef 100644 --- a/dhall/src/semantics/core/context.rs +++ b/dhall/src/semantics/core/context.rs @@ -2,7 +2,8 @@ use crate::error::TypeError; use crate::semantics::core::value::Value; use crate::semantics::core::value::ValueKind; use crate::semantics::core::var::{AlphaVar, Binder}; -use crate::semantics::nze::NzVar; +use crate::semantics::nze::{NzVar, QuoteEnv}; +use crate::semantics::phase::normalize::{NzEnv, NzEnvItem}; use crate::syntax::{Label, V}; #[derive(Debug, Clone)] @@ -69,7 +70,19 @@ impl TyCtx { ValueKind::Var(AlphaVar::default(), NzVar::new(var_idx)), t.clone(), ), - CtxItem::Replaced(v) => v.clone(), + CtxItem::Replaced(v) => v.clone() + // .to_tyexpr(QuoteEnv::construct(var_idx)) + // .normalize_whnf(&NzEnv::construct( + // self.ctx + // .iter() + // .filter_map(|(_, i)| match i { + // CtxItem::Kept(t) => { + // Some(NzEnvItem::Kept(t.clone())) + // } + // CtxItem::Replaced(_) => None, + // }) + // .collect(), + // )), }; // Can't fail because delta is positive let v = v.shift(shift_delta, &AlphaVar::default()).unwrap(); diff --git a/dhall/src/semantics/core/value.rs b/dhall/src/semantics/core/value.rs index 96bb99a..11d8bd8 100644 --- a/dhall/src/semantics/core/value.rs +++ b/dhall/src/semantics/core/value.rs @@ -185,7 +185,7 @@ impl Value { self.normalize_nf(); } - self.to_tyexpr(QuoteEnv::new()).to_expr(opts) + self.to_tyexpr_noenv().to_expr(opts) } pub(crate) fn to_whnf_ignore_type(&self) -> ValueKind { self.as_whnf().clone() @@ -292,11 +292,9 @@ impl Value { pub fn to_tyexpr(&self, qenv: QuoteEnv) -> TyExpr { let tye = match &*self.as_kind() { - ValueKind::Var(v, _w) => { - TyExprKind::Var(*v) - // TODO: Only works when we don't normalize under lambdas - // TyExprKind::Var(qenv.lookup(w)) - } + // ValueKind::Var(v, _w) => TyExprKind::Var(*v), + // TODO: Only works when we don't normalize under lambdas + ValueKind::Var(_v, w) => TyExprKind::Var(qenv.lookup(w)), ValueKind::LamClosure { binder, annot, @@ -611,7 +609,13 @@ impl ValueKind { fn shift(&self, delta: isize, var: &AlphaVar) -> Option { Some(match self { - ValueKind::Var(v, w) => ValueKind::Var(v.shift(delta, var)?, *w), + ValueKind::Var(v, w) if var.idx() <= v.idx() => { + ValueKind::Var(v.shift(delta, var)?, *w) + } + ValueKind::Var(v, w) => { + ValueKind::Var(v.shift(delta, var)?, w.shift(delta)) + } + // ValueKind::Var(v, w) => ValueKind::Var(v.shift(delta, var)?, *w), _ => self.traverse_ref_with_special_handling_of_binders( |x| Ok(x.shift(delta, var)?), |_, _, x| Ok(x.shift(delta, &var.under_binder())?), diff --git a/dhall/src/semantics/nze/nzexpr.rs b/dhall/src/semantics/nze/nzexpr.rs index 723c895..49aa704 100644 --- a/dhall/src/semantics/nze/nzexpr.rs +++ b/dhall/src/semantics/nze/nzexpr.rs @@ -217,6 +217,9 @@ impl QuoteEnv { pub fn new() -> Self { QuoteEnv { size: 0 } } + pub fn construct(size: usize) -> Self { + QuoteEnv { size } + } pub fn insert(&self) -> Self { QuoteEnv { size: self.size + 1, @@ -231,6 +234,11 @@ impl NzVar { pub fn new(idx: usize) -> Self { NzVar { idx } } + pub fn shift(&self, delta: isize) -> Self { + NzVar { + idx: (self.idx as isize + delta) as usize, + } + } } impl TyExpr { diff --git a/dhall/src/semantics/phase/normalize.rs b/dhall/src/semantics/phase/normalize.rs index ac60ce0..3ddfb84 100644 --- a/dhall/src/semantics/phase/normalize.rs +++ b/dhall/src/semantics/phase/normalize.rs @@ -12,8 +12,8 @@ use crate::semantics::{ use crate::syntax; use crate::syntax::Const::Type; use crate::syntax::{ - BinOp, Builtin, ExprKind, InterpolatedText, InterpolatedTextContents, - Label, NaiveDouble, + BinOp, Builtin, Const, ExprKind, InterpolatedText, + InterpolatedTextContents, Label, NaiveDouble, }; // Ad-hoc macro to help construct closures @@ -822,7 +822,7 @@ pub(crate) fn normalize_whnf( } #[derive(Debug, Clone)] -enum NzEnvItem { +pub(crate) enum NzEnvItem { // Variable is bound with given type Kept(Value), // Variable has been replaced by corresponding value @@ -838,6 +838,9 @@ impl NzEnv { pub fn new() -> Self { NzEnv { items: Vec::new() } } + pub fn construct(items: Vec) -> Self { + NzEnv { items } + } pub fn insert_type(&self, t: Value) -> Self { let mut env = self.clone(); @@ -851,9 +854,16 @@ impl NzEnv { } pub fn lookup_val(&self, var: &AlphaVar) -> Value { let idx = self.items.len() - 1 - var.idx(); + let var_idx = self.items[..idx] + .iter() + .filter(|i| match i { + NzEnvItem::Kept(_) => true, + NzEnvItem::Replaced(_) => false, + }) + .count(); match &self.items[idx] { NzEnvItem::Kept(ty) => Value::from_kind_and_type_whnf( - ValueKind::Var(var.clone(), NzVar::new(idx)), + ValueKind::Var(var.clone(), NzVar::new(var_idx)), ty.clone(), ), NzEnvItem::Replaced(x) => x.clone(), @@ -863,7 +873,11 @@ impl NzEnv { /// Normalize a TyExpr into WHNF pub(crate) fn normalize_tyexpr_whnf(tye: &TyExpr, env: &NzEnv) -> Value { - let ty = tye.get_type().unwrap(); + let ty = match tye.get_type() { + Ok(ty) => ty, + Err(_) => return Value::from_const(Const::Sort), + }; + let kind = match tye.kind() { TyExprKind::Var(var) => return env.lookup_val(var), TyExprKind::Expr(ExprKind::Lam(binder, annot, body)) => { -- cgit v1.2.3