5

I tried to model a less naive monadic encoding of non-determinism (less naive than MonadPlus and common lists) in Coq that is often used in Haskell; for example the encoding for lists looks like

data List m a = Nil | Cons (m a) (m (List m a))

whereas the corresponding definition in Coq would like as follows.

Inductive List (M: Type -> Type) (A: Type) :=
   Nil: List M A
 | Cons : M A -> M (List M A) -> List M A.

However, this kind of definition is not allowed in Coq because of the "strictly positive"-condition for inductive data types.

I'm not sure if I am aiming for a Coq-specific answer or an alternative implementation in Haskell that I can formalise in Coq, but I am happy to read any suggestions on how to overcome this problem.

ichistmeinname
  • 1,480
  • 10
  • 19
  • 2
    You're probably looking for [`Freer`](http://okmij.org/ftp/Haskell/extensible/more.pdf) monads and the `NDet` effect there. Everything is strictly positive and this representation even gives you non-determinism with [committed choice](http://okmij.org/ftp/papers/LogicT.pdf). I [implemented](https://github.com/effectfully/Eff/blob/master/Simple/Effect/NonDet.agda) that in Agda, but the code is horrible due to the Agda's way of handling universe polymorphism. – effectfully Apr 05 '16 at 15:46
  • 1
    Committed choice (or call-time choice as the FLP community likes to call it) is exactly what I want to formalise with Coq! My current source is [another paper](http://homes.soic.indiana.edu/ccshan/rational/lazy-nondet.pdf) that is explicitly modelling a FLP-like semantics of non-determinism with monads. Since I'm still trying to figure out which model would be best suited to be used in Coq, I'm definitely going to look at the representation with Oleg's `Freer` monads -- as far as I remember, I have already read the paper (for a different context). So thanks for the reminder! – ichistmeinname Apr 06 '16 at 06:50

1 Answers1

3

See Chlipala's "Certified Programming with Dependent Types". If you had Definition Id T := T -> T, then List Id could produce a non-terminating term. I think you might also be able to derive a contradiction by Definition Not T := T -> False, especially if you drop the Nil constructor and accept the law of excluded middle.

It would be nice if there were some way to annotate M as only using its argument in positive locations. I think Andreas Abel may have done some work in this direction.

Anyway, if you're willing to restrict your datatypes just a little bit, you could use:

Fixpoint SizedList M A (n : nat) : Type :=
  match n with
    | 0 => unit
    | S m => option (M A * M (SizedList M A m))
  end.

Definition List M A := { n : nat & SizedList M A n }.
jbapple
  • 3,297
  • 1
  • 24
  • 38
  • 1
    Abel's work in that direction is implemented in [MiniAgda](http://www2.tcs.ifi.lmu.de/~abel/miniagda/). – gallais Apr 05 '16 at 10:55
  • Thanks for the quick answer; unfortunately, I forgot to write that I'm still a beginner in Coq. Could you maybe elaborate a bit on the idea behind this encoding? And is it the right way to define values of type `List M A` with `existT`? This kind of construction is new for me and somehow googling didn't help. – ichistmeinname Apr 05 '16 at 14:18