How to convince the integrity check in Idris that I am not using a variable?

I am having trouble convincing Idris to verify that my function is complete. Here is a simple sample problem that I am facing. Let's say we have a very simple type of expression of the following form:

data SimpleType = Prop | Fn SimpleType SimpleType

data Expr : SimpleType -> Type where
  Var : String -> Expr type
  Lam : String -> Expr rng -> Expr (Fn dom rng)
  App : Expr (Fn dom rng) -> Expr dom -> Expr rng

I would like to write a function

total sub : {a, b : SimpleType} -> String -> Expr a -> Expr b -> Expr b

for which you need an DecEqinstance for SimpleType, but nothing unusual. The problem is how to convince the type check that the function is complete. For example, consider implementing it subas follows:

total sub : {a, b : SimpleType} -> String -> Expr a -> Expr b -> Expr b
sub name repl (App l r) = App (substitute name repl l) (substitute name repl r)
sub _ _ expr = expr

(This is incorrect, but a great place to run.) This gives an error:

Main.sub is possibly not total due to: repl

At first glance, it seems that Idris may have problems verifying that l and r are structurally smaller than (App lr). Perhaps the following will work?

total sub : {a, b : SimpleType} -> String -> Expr a -> Expr b -> Expr b
sub name repl expr@(App l r) = App
  (sub name repl (assert_smaller expr l))
  (sub name repl (assert_smaller expr r))
sub _ _ expr = expr

Nope!

Main.sub is possibly not total due to: repl

, , , :

total sub : {a, b : SimpleType} -> String -> Expr a -> Expr b -> Expr b
sub _ _ expr = expr

!

total sub : {a, b : SimpleType} -> String -> Expr a -> Expr b -> Expr b
sub _ repl expr = expr

, , repl . - , ?

+4
1

​​ , , "repl", , , . , - - , .

git . , , "repl", ( , , ...)

+5

All Articles