comparison src/MoreDep.v @ 86:fd505bcb5632

Start of certified regexp matcher
author Adam Chlipala <adamc@hcoop.net>
date Mon, 06 Oct 2008 14:33:11 -0400
parents 3746a2ded8da
children a0b8b550e265
comparison
equal deleted inserted replaced
85:3746a2ded8da 86:fd505bcb5632
8 *) 8 *)
9 9
10 (* begin hide *) 10 (* begin hide *)
11 Require Import Arith Bool List. 11 Require Import Arith Bool List.
12 12
13 Require Import Tactics. 13 Require Import Tactics MoreSpecif.
14 14
15 Set Implicit Arguments. 15 Set Implicit Arguments.
16 (* end hide *) 16 (* end hide *)
17 17
18 18
340 repeat (match goal with 340 repeat (match goal with
341 | [ |- context[cfold ?E] ] => dep_destruct (cfold E) 341 | [ |- context[cfold ?E] ] => dep_destruct (cfold E)
342 | [ |- (if ?E then _ else _) = _ ] => destruct E 342 | [ |- (if ?E then _ else _) = _ ] => destruct E
343 end; crush). 343 end; crush).
344 Qed. 344 Qed.
345
346
347 (** * A Certified Regular Expression Matcher *)
348
349 Require Import Ascii String.
350 Open Scope string_scope.
351
352 Inductive regexp : (string -> Prop) -> Set :=
353 | Char : forall ch : ascii,
354 regexp (fun s => s = String ch "")
355 | Concat : forall P1 P2 (r1 : regexp P1) (r2 : regexp P2),
356 regexp (fun s => exists s1, exists s2, s = s1 ++ s2 /\ P1 s1 /\ P2 s2).
357
358 Open Scope specif_scope.
359
360 Lemma length_emp : length "" <= 0.
361 crush.
362 Qed.
363
364 Lemma append_emp : forall s, s = "" ++ s.
365 crush.
366 Qed.
367
368 Ltac substring :=
369 crush;
370 repeat match goal with
371 | [ |- context[match ?N with O => _ | S _ => _ end] ] => destruct N; crush
372 end.
373
374 Lemma substring_le : forall s n m,
375 length (substring n m s) <= m.
376 induction s; substring.
377 Qed.
378
379 Lemma substring_all : forall s,
380 substring 0 (length s) s = s.
381 induction s; substring.
382 Qed.
383
384 Lemma substring_none : forall s n,
385 substring n 0 s = EmptyString.
386 induction s; substring.
387 Qed.
388
389 Hint Rewrite substring_all substring_none : cpdt.
390
391 Lemma substring_split : forall s m,
392 substring 0 m s ++ substring m (length s - m) s = s.
393 induction s; substring.
394 Qed.
395
396 Lemma length_app1 : forall s1 s2,
397 length s1 <= length (s1 ++ s2).
398 induction s1; crush.
399 Qed.
400
401 Hint Resolve length_emp append_emp substring_le substring_split length_app1.
402
403 Lemma substring_app_fst : forall s2 s1 n,
404 length s1 = n
405 -> substring 0 n (s1 ++ s2) = s1.
406 induction s1; crush.
407 Qed.
408
409 Lemma substring_app_snd : forall s2 s1 n,
410 length s1 = n
411 -> substring n (length (s1 ++ s2) - n) (s1 ++ s2) = s2.
412 Hint Rewrite <- minus_n_O : cpdt.
413
414 induction s1; crush.
415 Qed.
416
417 Hint Rewrite substring_app_fst substring_app_snd using assumption : cpdt.
418
419 Section split.
420 Variables P1 P2 : string -> Prop.
421 Variable P1_dec : forall s, {P1 s} + {~P1 s}.
422 Variable P2_dec : forall s, {P2 s} + {~P2 s}.
423
424 Variable s : string.
425
426 Definition split' (n : nat) : n <= length s
427 -> {exists s1, exists s2, length s1 <= n /\ s1 ++ s2 = s /\ P1 s1 /\ P2 s2}
428 + {forall s1 s2, length s1 <= n -> s1 ++ s2 = s -> ~P1 s1 \/ ~P2 s2}.
429 refine (fix F (n : nat) : n <= length s
430 -> {exists s1, exists s2, length s1 <= n /\ s1 ++ s2 = s /\ P1 s1 /\ P2 s2}
431 + {forall s1 s2, length s1 <= n -> s1 ++ s2 = s -> ~P1 s1 \/ ~P2 s2} :=
432 match n return n <= length s
433 -> {exists s1, exists s2, length s1 <= n /\ s1 ++ s2 = s /\ P1 s1 /\ P2 s2}
434 + {forall s1 s2, length s1 <= n -> s1 ++ s2 = s -> ~P1 s1 \/ ~P2 s2} with
435 | O => fun _ => Reduce (P1_dec "" && P2_dec s)
436 | S n' => fun _ => (P1_dec (substring 0 (S n') s) && P2_dec (substring (S n') (length s - S n') s))
437 || F n' _
438 end); clear F; crush; eauto 7;
439 match goal with
440 | [ _ : length ?S <= 0 |- _ ] => destruct S
441 | [ _ : length ?S' <= S ?N |- _ ] =>
442 generalize (eq_nat_dec (length S') (S N)); destruct 1
443 end; crush.
444 Defined.
445
446 Definition split : {exists s1, exists s2, s = s1 ++ s2 /\ P1 s1 /\ P2 s2}
447 + {forall s1 s2, s = s1 ++ s2 -> ~P1 s1 \/ ~P2 s2}.
448 refine (Reduce (split' (n := length s) _)); crush; eauto.
449 Defined.
450 End split.
451
452 Implicit Arguments split [P1 P2].
453
454 Lemma app_cong : forall x1 y1 x2 y2,
455 x1 = x2
456 -> y1 = y2
457 -> x1 ++ y1 = x2 ++ y2.
458 congruence.
459 Qed.
460
461 Hint Resolve app_cong.
462
463 Definition matches P (r : regexp P) s : {P s} + { ~P s}.
464 refine (fix F P (r : regexp P) s : {P s} + { ~P s} :=
465 match r with
466 | Char ch => string_dec s (String ch "")
467 | Concat _ _ r1 r2 => Reduce (split (F _ r1) (F _ r2) s)
468 end); crush;
469 match goal with
470 | [ H : _ |- _ ] => generalize (H _ _ (refl_equal _))
471 end;
472 tauto.
473 Defined.
474
475 Example hi := Concat (Char "h"%char) (Char "i"%char).
476 Eval simpl in matches hi "hi".
477 Eval simpl in matches hi "bye".