2

Suppose I want an inductive definiton of a substring (with string being just a synonym for list).

Inductive substring {A : Set} (w : string A) :
                    (string A) -> Prop :=
  | SS_substr : forall x y z : string A,
                  x ++ y ++ z = w ->
                  substring w y.

Here I can for example prove the following:

Theorem test : substring [3;4;1] [4].
Proof.
  eapply SS_substr.
  cbn.
  instantiate (1:=[1]).
  instantiate (1:=[3]).
  reflexivity.
Qed.

However, the proof is "existential" rather than "universal", in spite of the fact that the inductive definition states forall x y z and only then constrains their shapes. This seems somewhat unintuitive to me. What gives?

Also, is it possible to make an inductive definition using exists x : string A, exists y : string A, exists z : string, x ++ y ++ z = w -> substring w y?

AntlerM
  • 181
  • 6

1 Answers1

2

One important thing to note is that exists is not a built-in functionality of Coq (contrary to forall). Actually, exists itself is a notation, but behind there is an inductive type named ex. The notation and the inductive type are defined in the Coq standard library. Here is the definition of ex:

Inductive ex (A:Type) (P:A -> Prop) : Prop :=
    ex_intro : forall x:A, P x -> ex (A:=A) P.

It is defined using one constructor and a universal quantification, like your substring type, so it is not surprising that your susbtring type seems to be "existential" at some point.

Of course, you can define your type using exists, and you do not even need Inductive.

Definition substring' {A : Set} (w y : string A) : Prop :=
    exists x z, x ++ y ++ z = w.
eponier
  • 3,062
  • 9
  • 20
  • Neat, thanks! (Jibadiba podajiba brm brm brm - needed more characters) – AntlerM Nov 08 '16 at 09:28
  • @AntlerM Even if I answered your initial question, you should wait before selecting my post as the solution, as it could discourage other users to post something interesting about the subject. – eponier Nov 08 '16 at 09:35
  • Well, for my purposes, it makes sense that existential certainly follows from universal (surely if forall x in A, P x then exists x' : A, P x' assuming A is not empty) which explains just about everything I was wondering about; that said, as others may stumble upon this at some point, leaving room for more "interestings" on the subject sounds reasonable. Sadly I can't upboat you with 13 rep :). – AntlerM Nov 08 '16 at 10:18
  • @AntlerM I might be wrong, but I think you're misreading the definition of `ex_intro`. `ex_intro` is a *dependently*-typed function (constructor), that takes 4 arguments: a type `A`, a predicate `P : A -> Prop`, an `x` of type `A` **and** a proof of `P x` (in this last part dependent types play crucial role!), then it sort of wraps them together in one bundle which is `exists`. There is nothing that requires you to prove `forall x, P x`! And eponier has just showed that with dependent types one doesn't need `exists` as a separate (independent) entity -- it can be encoded within the system. – Anton Trunov Nov 08 '16 at 11:07
  • @AntonTrunov Thanks for making things clear as usual. I realized in your comment that the fact that `exists` is not built-in is not obvious. I edited my post to make things clearer. – eponier Nov 08 '16 at 12:17
  • @eponier I like your edit! Especially one thing is pretty convenient -- the precise link to `ex`. How did you do it? I understand that I can append `#ex` to `Coq.Init.Logic.html`. But is there a way to link to, say, `Notation "x = y" := (x = y :>_) : type_scope.` (in that same html doc)? – Anton Trunov Nov 08 '16 at 12:21
  • 1
    @AntonTrunov I must admit I looked into the html source code. But there is a simpler way to do it: find a use of the object you want to refer to, since the documentation usually links to the definition of the object. For instance, `=` is used in `eq_sym` just after the definition. If you click on the `=`, you are sent to the definition. Just copy the url then. For this example, the link is https://coq.inria.fr/library/Coq.Init.Logic.html#1c39bf18749e5cc609e83c0a0ba5a372. – eponier Nov 08 '16 at 13:22
  • Nice and simple! Thank you. – Anton Trunov Nov 08 '16 at 13:27
  • @AntonTrunov right - so the `forall x` is in this scenario simply states that "given any arbitrary element `x`"... (and a proof that `P` holds for that element `x`), I give you a bundle (an ordered pair, in some sense), with the first element being that element `x` and the second its proof that `P x`. Forall = for arbitrary, that is, right? – AntlerM Nov 09 '16 at 11:50
  • @AntlerM Yes, it's kind of arbitrary in the sense that *any* `x` for which `P x` is provable would do, so it doesn't matter exactly which `x` and which proof of `P x` you provide. An important thing here is you've got to provide *both*. You can't get a value of type `ex` for a completely arbitrary `x` unless `forall x, P x`. – Anton Trunov Nov 09 '16 at 12:03
  • @AntonTrunov Ooo that's a good observation. So, in some sense, you can't get a curried version of it! :) This is quite interesting - how existential quantification is really somewhat less fundamental than the universal one. (It makes sense un-intuitively, considering you can build everything off of implication / forall in coq, but intuitively it's (at least to me) not as clear.) – AntlerM Nov 09 '16 at 12:16
  • @AntlerM You can partially apply `ex_intro`. E.g. the type of `ex_intro (fun n => n = 0) 0` is `0 = 0 -> exists n : nat, n = 0`. It's a partially applied constructor, which "waits" for a proof of `0 = 0`. You might also want to look at this [question](http://stackoverflow.com/questions/38777736/how-do-i-read-the-definition-of-ex-intro). – Anton Trunov Nov 09 '16 at 12:28