comparison src/Subset.v @ 72:839d159cac5d

Code for type-checking example
author Adam Chlipala <adamc@hcoop.net>
date Fri, 03 Oct 2008 12:44:56 -0400
parents db967eff40d7
children 535e1cd17d9a
comparison
equal deleted inserted replaced
71:db967eff40d7 72:839d159cac5d
365 | S n0 -> false) 365 | S n0 -> false)
366 | S n0 -> (match m0 with 366 | S n0 -> (match m0 with
367 | O -> false 367 | O -> false
368 | S n1 -> eq_nat_dec' n0 n1) 368 | S n1 -> eq_nat_dec' n0 n1)
369 </pre># *) 369 </pre># *)
370
371 (** %\smallskip%
372
373 We can build "smart" versions of the usual boolean operators and put them to good use in certified programming. For instance, here is a [sumbool] version of boolean "or." *)
374
375 Notation "x || y" := (if x then Yes else Reduce y) (at level 50).
376
377 (** Let us use it for building a function that decides list membership. We need to assume the existence of an equality decision procedure for the type of list elements. *)
378
379 Section In_dec.
380 Variable A : Set.
381 Variable A_eq_dec : forall x y : A, {x = y} + {x <> y}.
382
383 (** The final function is easy to write using the techniques we have developed so far. *)
384
385 Definition In_dec : forall (x : A) (ls : list A), {In x ls} + { ~In x ls}.
386 refine (fix f (x : A) (ls : list A) {struct ls}
387 : {In x ls} + { ~In x ls} :=
388 match ls return {In x ls} + { ~In x ls} with
389 | nil => No
390 | x' :: ls' => A_eq_dec x x' || f x ls'
391 end); crush.
392 Qed.
393 End In_dec.
394
395 (** [In_dec] has a reasonable extraction to OCaml. *)
396
397 Extraction In_dec.
398
399 (** %\begin{verbatim}
400 (** val in_dec : ('a1 -> 'a1 -> bool) -> 'a1 -> 'a1 list -> bool **)
401
402 let rec in_dec a_eq_dec x = function
403 | Nil -> false
404 | Cons (x', ls') ->
405 (match a_eq_dec x x' with
406 | true -> true
407 | false -> in_dec a_eq_dec x ls')
408 \end{verbatim}%
409
410 #<pre>
411 (** val in_dec : ('a1 -> 'a1 -> bool) -> 'a1 -> 'a1 list -> bool **)
412
413 let rec in_dec a_eq_dec x = function
414 | Nil -> false
415 | Cons (x', ls') ->
416 (match a_eq_dec x x' with
417 | true -> true
418 | false -> in_dec a_eq_dec x ls')
419 </pre># *)
420
421
422 (** * Partial Subset Types *)
423
424 Inductive maybe (A : Type) (P : A -> Prop) : Set :=
425 | Unknown : maybe P
426 | Found : forall x : A, P x -> maybe P.
427
428 Notation "{{ x | P }}" := (maybe (fun x => P)).
429 Notation "??" := (Unknown _).
430 Notation "[[ x ]]" := (Found _ x _).
431
432 Notation "x <- e1 ; e2" := (match e1 with
433 | Unknown => ??
434 | Found x _ => e2
435 end)
436 (right associativity, at level 60).
437
438 Notation "e1 ;; e2" := (if e1 then e2 else ??)
439 (right associativity, at level 60).
440
441
442 (** * A Type-Checking Example *)
443
444 Inductive exp : Set :=
445 | Nat : nat -> exp
446 | Plus : exp -> exp -> exp
447 | Bool : bool -> exp
448 | And : exp -> exp -> exp.
449
450 Inductive type : Set := TNat | TBool.
451
452 Inductive hasType : exp -> type -> Prop :=
453 | HtNat : forall n,
454 hasType (Nat n) TNat
455 | HtPlus : forall e1 e2,
456 hasType e1 TNat
457 -> hasType e2 TNat
458 -> hasType (Plus e1 e2) TNat
459 | HtBool : forall b,
460 hasType (Bool b) TBool
461 | HtAnd : forall e1 e2,
462 hasType e1 TBool
463 -> hasType e2 TBool
464 -> hasType (And e1 e2) TBool.
465
466 Definition eq_type_dec : forall (t1 t2 : type), {t1 = t2} + {t1 <> t2}.
467 decide equality.
468 Defined.
469
470 Definition typeCheck (e : exp) : {{t | hasType e t}}.
471 Hint Constructors hasType.
472
473 refine (fix F (e : exp) : {{t | hasType e t}} :=
474 match e return {{t | hasType e t}} with
475 | Nat _ => [[TNat]]
476 | Plus e1 e2 =>
477 t1 <- F e1;
478 t2 <- F e2;
479 eq_type_dec t1 TNat;;
480 eq_type_dec t2 TNat;;
481 [[TNat]]
482 | Bool _ => [[TBool]]
483 | And e1 e2 =>
484 t1 <- F e1;
485 t2 <- F e2;
486 eq_type_dec t1 TBool;;
487 eq_type_dec t2 TBool;;
488 [[TBool]]
489 end); crush.
490 Defined.
491
492 Eval simpl in typeCheck (Nat 0).
493 Eval simpl in typeCheck (Plus (Nat 1) (Nat 2)).
494 Eval simpl in typeCheck (Plus (Nat 1) (Bool false)).