(** * IndProp: Inductively Defined Propositions *)
Set Warnings "-notation-overridden,-parsing".
Require Export Logic.
Require Coq.omega.Omega.
(* ################################################################# *)
(** * Inductively Defined Propositions *)
(** In the [Logic] chapter, we looked at several ways of writing propositions, including conjunction, disjunction, and quantifiers. In this chapter, we bring a new tool into the mix: _inductive definitions_.  Recall that we have seen two ways of stating that a number [n] is even: We can say (1) [evenb n = true], or (2) [exists k, n = double k].  Yet another possibility is to say that [n] is even if we can establish its evenness from the following rules:  - Rule [ev_0]:  The number [0] is even. - Rule [ev_SS]: If [n] is even, then [S (S n)] is even. *)
(** To illustrate how this definition of evenness works, let's imagine using it to show that [4] is even. By rule [ev_SS], it suffices to show that [2] is even. This, in turn, is again guaranteed by rule [ev_SS], as long as we can show that [0] is even. But this last fact follows directly from the [ev_0] rule. *)
(** We will see many definitions like this one during the rest of the course.  For purposes of informal discussions, it is helpful to have a lightweight notation that makes them easy to read and write.  _Inference rules_ are one such notation: *)
(**  ------------                        (ev_0) ev 0  ev n --------------                      (ev_SS) ev (S (S n)) *)
(** Each of the textual rules above is reformatted here as an inference rule; the intended reading is that, if the _premises_ above the line all hold, then the _conclusion_ below the line follows.  For example, the rule [ev_SS] says that, if [n] satisfies [ev], then [S (S n)] also does.  If a rule has no premises above the line, then its conclusion holds unconditionally.  We can represent a proof using these rules by combining rule applications into a _proof tree_. Here's how we might transcribe the above proof that [4] is even: *)
(**  ------  (ev_0) ev 0 ------ (ev_SS) ev 2 ------ (ev_SS) ev 4 *)
(** Why call this a "tree" (rather than a "stack", for example)? Because, in general, inference rules can have multiple premises. We will see examples of this below. *)
(** Putting all of this together, we can translate the definition of evenness into a formal Coq definition using an [Inductive] declaration, where each constructor corresponds to an inference rule: *)
Inductive ev : nat -> Prop :=
| ev_0 : ev 0
| ev_SS : forall n : nat, ev n -> ev (S (S n)).
(** This definition is different in one crucial respect from previous uses of [Inductive]: its result is not a [Type], but rather a function from [nat] to [Prop] -- that is, a property of numbers.  Note that we've already seen other inductive definitions that result in functions, such as [list], whose type is [Type -> Type].  What is new here is that, because the [nat] argument of [ev] appears _unnamed_, to the _right_ of the colon, it is allowed to take different values in the types of different constructors: [0] in the type of [ev_0] and [S (S n)] in the type of [ev_SS].  In contrast, the definition of [list] names the [X] parameter _globally_, to the _left_ of the colon, forcing the result of [nil] and [cons] to be the same ([list X]).  Had we tried to bring [nat] to the left in defining [ev], we would have seen an error: *)
Fail Inductive wrong_ev (n : nat) : Prop :=
| wrong_ev_0 : wrong_ev 0
| wrong_ev_SS : forall n, wrong_ev n -> wrong_ev (S (S n)).
(* ===> Error: A parameter of an inductive type n is not allowed to be used as a bound variable in the type of its constructor. *)
(** ("Parameter" here is Coq jargon for an argument on the left of the colon in an [Inductive] definition; "index" is used to refer to arguments on the right of the colon.) *)
(** We can think of the definition of [ev] as defining a Coq property [ev : nat -> Prop], together with theorems [ev_0 : ev 0] and [ev_SS : forall n, ev n -> ev (S (S n))].  Such "constructor theorems" have the same status as proven theorems.  In particular, we can use Coq's [apply] tactic with the rule names to prove [ev] for particular numbers... *)
(** More generally, we can show that any number multiplied by 2 is even: *)

(** **** Exercise: 1 star (ev_double)  *)
Theorem ev_double : forall n,
ev (double n).