Error reflection for Fin

Add reflection-based error message improvements for Fin literals. Now,
instead of a collection of internal implementation details, a friendly
and descriptive message is returned.

See test/error005 for a demo.
This commit is contained in:
David Raymond Christiansen 2014-12-22 09:52:34 -08:00
parent 91cd4d5489
commit 348ddce3ac
13 changed files with 90 additions and 14 deletions

View File

@ -18,6 +18,6 @@ class Decidable (ts : Vect k Type) (p : Rel ts) where
--decision : Decidable ts p => (ts : Vect k Type) -> (p : Rel ts) -> liftRel ts p Dec --decision : Decidable ts p => (ts : Vect k Type) -> (p : Rel ts) -> liftRel ts p Dec
--decision ts p = decide {ts} {p} --decision ts p = decide {ts} {p}
using (P : Type, p : P) using (a : Type, x : a)
data Given : Dec P -> Type where data Given : Dec a -> Type where
always : Given (Yes p) Always : Given (Yes x)

View File

@ -3,17 +3,17 @@ module Language.Reflection.Utils
import Language.Reflection import Language.Reflection
import Language.Reflection.Errors import Language.Reflection.Errors
%default total
-------------------------------------------------------- --------------------------------------------------------
-- Tactic construction conveniences -- Tactic construction conveniences
-------------------------------------------------------- --------------------------------------------------------
total
seq : List Tactic -> Tactic seq : List Tactic -> Tactic
seq [] = GoalType "This is an impossible case" Trivial seq [] = GoalType "This is an impossible case" Trivial
seq [t] = t seq [t] = t
seq (t::ts) = t `Seq` seq ts seq (t::ts) = t `Seq` seq ts
total
try : List Tactic -> Tactic try : List Tactic -> Tactic
try [] = GoalType "This is an impossible case" Trivial try [] = GoalType "This is an impossible case" Trivial
try [t] = t try [t] = t
@ -23,6 +23,7 @@ try (t::ts) = t `Try` seq ts
-------------------------------------------------------- --------------------------------------------------------
-- For use in tactic scripts -- For use in tactic scripts
-------------------------------------------------------- --------------------------------------------------------
total
mkPair : a -> b -> (a, b) mkPair : a -> b -> (a, b)
mkPair a b = (a, b) mkPair a b = (a, b)
@ -30,22 +31,25 @@ mkPair a b = (a, b)
-------------------------------------------------------- --------------------------------------------------------
-- Tools for constructing proof terms directly -- Tools for constructing proof terms directly
-------------------------------------------------------- --------------------------------------------------------
total
getUName : TTName -> Maybe String getUName : TTName -> Maybe String
getUName (UN n) = Just n getUName (UN n) = Just n
getUName (NS n ns) = getUName n getUName (NS n ns) = getUName n
getUName _ = Nothing getUName _ = Nothing
total
unApply : TT -> (TT, List TT) unApply : TT -> (TT, List TT)
unApply t = unA t [] unApply t = unA t []
where unA : TT -> List TT -> (TT, List TT) where unA : TT -> List TT -> (TT, List TT)
unA (App fn arg) args = unA fn (arg::args) unA (App fn arg) args = unA fn (arg::args)
unA tm args = (tm, args) unA tm args = (tm, args)
total
mkApp : TT -> List TT -> TT mkApp : TT -> List TT -> TT
mkApp tm [] = tm mkApp tm [] = tm
mkApp tm (a::as) = mkApp (App tm a) as mkApp tm (a::as) = mkApp (App tm a) as
total
binderTy : (Eq t) => Binder t -> t binderTy : (Eq t) => Binder t -> t
binderTy (Lam t) = t binderTy (Lam t) = t
binderTy (Pi t _) = t binderTy (Pi t _) = t

View File

@ -56,13 +56,13 @@ instance Show SocketType where
show NotASocket = "Not a socket" show NotASocket = "Not a socket"
show Stream = "Stream" show Stream = "Stream"
show Datagram = "Datagram" show Datagram = "Datagram"
show Raw = "Raw" show RawSocket = "Raw"
instance ToCode SocketType where instance ToCode SocketType where
toCode NotASocket = 0 toCode NotASocket = 0
toCode Stream = 1 toCode Stream = 1
toCode Datagram = 2 toCode Datagram = 2
toCode Raw = 3 toCode RawSocket = 3
data RecvStructPtr = RSPtr Ptr data RecvStructPtr = RSPtr Ptr

View File

@ -13,7 +13,7 @@ modules = System,
Providers, Providers,
Language.Reflection, Language.Reflection.Utils, Language.Reflection.Errors, Language.Reflection.Utils,
Syntax.PreorderReasoning, Syntax.PreorderReasoning,

View File

@ -1,5 +1,14 @@
module Language.Reflection module Language.Reflection
import Builtins
import Prelude.Applicative
import Prelude.Basics
import Prelude.Foldable
import Prelude.Functor
import Prelude.List
import Prelude.Nat
import Prelude.Traversable
%access public %access public
data TTName = data TTName =

View File

@ -1,7 +1,12 @@
module Language.Reflection.Errors module Language.Reflection.Errors
import Builtins
import Language.Reflection import Language.Reflection
import Prelude.Bool
import Prelude.List
import Prelude.Maybe
data Err = Msg String data Err = Msg String
| InternalMsg String | InternalMsg String

View File

@ -27,6 +27,8 @@ import public Prelude.Uninhabited
import public Prelude.Pairs import public Prelude.Pairs
import public Decidable.Equality import public Decidable.Equality
import public Language.Reflection
import public Language.Reflection.Errors
%access public %access public
%default total %default total

View File

@ -6,11 +6,15 @@ import Prelude.Basics
import Prelude.Bool import Prelude.Bool
import Prelude.Cast import Prelude.Cast
import Prelude.Classes import Prelude.Classes
import Prelude.List
import Prelude.Maybe import Prelude.Maybe
import Prelude.Nat import Prelude.Nat
import Prelude.Either import Prelude.Either
import Prelude.Uninhabited import Prelude.Uninhabited
import Language.Reflection
import Language.Reflection.Errors
%default total %default total
||| Numbers strictly less than some bound. The name comes from "finite sets". ||| Numbers strictly less than some bound. The name comes from "finite sets".
@ -157,3 +161,20 @@ fromInteger : (x : Integer) ->
fromInteger {n} x {prf} with (integerToFin x n) fromInteger {n} x {prf} with (integerToFin x n)
fromInteger {n} x {prf = ItIsJust} | Just y = y fromInteger {n} x {prf = ItIsJust} | Just y = y
%language ErrorReflection
total
finFromIntegerErrors : Err -> Maybe (List ErrorReportPart)
finFromIntegerErrors (CantUnify x tm `(IsJust (integerToFin ~n ~m)) err xs y)
= Just [ TextPart "When using", TermPart n
, TextPart "as a literal for a"
, TermPart `(Fin ~m)
, SubReport [ TextPart "Could not show that"
, TermPart n
, TextPart "is less than"
, TermPart m
]
]
finFromIntegerErrors _ = Nothing
%error_handlers Prelude.Fin.fromInteger prf finFromIntegerErrors

View File

@ -3,6 +3,8 @@ package prelude
opts = "--nobuiltins --total" opts = "--nobuiltins --total"
modules = Builtins, Prelude, IO, modules = Builtins, Prelude, IO,
Language.Reflection, Language.Reflection.Errors,
Prelude.Algebra, Prelude.Basics, Prelude.Bool, Prelude.Cast, Prelude.Algebra, Prelude.Basics, Prelude.Bool, Prelude.Cast,
Prelude.Classes, Prelude.Nat, Prelude.Fin, Prelude.List, Prelude.Classes, Prelude.Nat, Prelude.Fin, Prelude.List,
Prelude.Maybe, Prelude.Monad, Prelude.Applicative, Prelude.Either, Prelude.Maybe, Prelude.Monad, Prelude.Applicative, Prelude.Either,

View File

@ -0,0 +1,18 @@
module error005
-- Test the Prelude's error rewrites for Fin
one : Fin 2
one = 1
two : Fin 2
two = 2
hahaha : (n : Nat) -> Fin n
hahaha n = 0
ok : (n : Nat) -> Fin (plus 2 n)
ok n = 1
notOk : (n : Nat) -> Fin (plus 2 n)
notOk n = 2

12
test/error005/expected Normal file
View File

@ -0,0 +1,12 @@
error005.idr:11:1:When elaborating right hand side of two:
When elaborating argument prf to function Prelude.Fin.fromInteger:
When using 2 as a literal for a Fin 2
Could not show that 2 is less than 2
error005.idr:14:1:When elaborating right hand side of hahaha:
When elaborating argument prf to function Prelude.Fin.fromInteger:
When using 0 as a literal for a Fin n
Could not show that 0 is less than n
error005.idr:19:1:When elaborating right hand side of notOk:
When elaborating argument prf to function Prelude.Fin.fromInteger:
When using 2 as a literal for a Fin (S (S n))
Could not show that 2 is less than S (S n)

3
test/error005/run Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
idris $@ --check --nocolour error005.idr
rm -f *.ibc

View File

@ -24,13 +24,13 @@ FullBoard (MkBoard b) = All (All Filled) b
indexStep : {i : Fin n} -> {xs : Vect n a} -> {x : a} -> index i xs = index (FS i) (x::xs) indexStep : {i : Fin n} -> {xs : Vect n a} -> {x : a} -> index i xs = index (FS i) (x::xs)
indexStep = Refl indexStep = Refl
find : {P : a -> Type} -> ((x : a) -> Dec (P x)) -> (xs : Vect n a) find : {p : a -> Type} -> ((x : a) -> Dec (p x)) -> (xs : Vect n a)
-> Either (All (\x => Not (P x)) xs) (y : a ** (P y, (i : Fin n ** y = index i xs))) -> Either (All (\x => Not (p x)) xs) (y : a ** (p y, (i : Fin n ** y = index i xs)))
find _ Nil = Left Nil find _ Nil = Left Nil
find {P} d (x::xs) with (d x) find {p} d (x::xs) with (d x)
| Yes prf = Right (x ** (prf, (FZ ** Refl))) | Yes prf = Right (x ** (prf, (FZ ** Refl)))
| No prf = | No prf =
case find {P} d xs of case find {p} d xs of
Right (y ** (prf', (i ** prf''))) => Right (y ** (prf', (i ** prf''))) =>
Right (y ** (prf', (FS i ** replace {P=(\x => y = x)} (indexStep {x=x}) prf''))) Right (y ** (prf', (FS i ** replace {P=(\x => y = x)} (indexStep {x=x}) prf'')))
Left prf' => Left (prf::prf') Left prf' => Left (prf::prf')
@ -41,7 +41,7 @@ empty (Just _) = No nothingNotJust
findEmptyInRow : (xs : Vect n (Cell n)) -> Either (All Filled xs) (i : Fin n ** Empty (index i xs)) findEmptyInRow : (xs : Vect n (Cell n)) -> Either (All Filled xs) (i : Fin n ** Empty (index i xs))
findEmptyInRow xs = findEmptyInRow xs =
case find {P=Empty} empty xs of case find {p=Empty} empty xs of
Right (_ ** (pempty, (i ** pidx))) => Right (i ** trans pempty pidx) Right (_ ** (pempty, (i ** pidx))) => Right (i ** trans pempty pidx)
Left p => Left p Left p => Left p