Mercurial > cpdt > repo
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)). |