Mercurial > hg > Members > kono > Proof > automaton1
view regex.agda @ 18:e168140d15b0
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 22 Nov 2020 19:18:15 +0900 |
parents | d1f04098fc13 |
children |
line wrap: on
line source
{-# OPTIONS --allow-unsolved-metas #-} module regex where open import Level renaming ( suc to Suc ; zero to Zero ) open import Data.List hiding ( any ; [_] ; concat ) open import Relation.Binary.PropositionalEquality hiding ( [_] ) open import Relation.Nullary using (¬_; Dec; yes; no) open import Data.Empty open import Data.Unit open import Data.Maybe open import logic data Regex ( Σ : Set ) : Set where φ : Regex Σ ε : Regex Σ _* : Regex Σ → Regex Σ _&_ : Regex Σ → Regex Σ → Regex Σ _||_ : Regex Σ → Regex Σ → Regex Σ <_> : Σ → Regex Σ -- postulate a b c d : Set data char : Set where a : char b : char c : char d : char infixr 40 _&_ _||_ r1' = (< a > & < b >) & < c > r1 = < a > & < b > & < c > any = < a > || < b > || < c > || < d > r2 = ( any * ) & ( < a > & < b > & < c > ) r3 = ( any * ) & ( < a > & < b > & < c > & < a > & < b > & < c > ) r4 = ( < a > & < b > & < c > ) || ( < b > & < c > & < d > ) r5 = ( any * ) & ( < a > & < b > & < c > || < b > & < c > & < d > ) data regular-expr {Σ : Set} : Regex Σ → List Σ → Set where atom : (x : Σ ) → regular-expr < x > ( x ∷ [] ) empty : regular-expr φ [] none : ⊥ → regular-expr φ [] concat : {x y : Regex Σ} {t s : List Σ} → regular-expr x t → regular-expr y s → regular-expr (x & y) (t ++ s ) select : {x y : Regex Σ} {t : List Σ} → regular-expr x t ∨ regular-expr y t → regular-expr (x || y) t star-nil : {x : Regex Σ} → regular-expr (x *) [] star : {x : Regex Σ} → {lx next : List Σ} → regular-expr x lx → regular-expr (x *) next → regular-expr (x *) (lx ++ next) test-regex : Set test-regex = ¬ (regular-expr r1 ( a ∷ [] ) ) test-regex1 : regular-expr r1 ( a ∷ b ∷ c ∷ [] ) test-regex1 = concat (atom a) (concat (atom b) (atom c)) open import regular-language open import Data.Empty open import Relation.Nullary regex-language : {Σ : Set} → (r : Regex Σ) → ((i j : Σ) → Dec ( i ≡ j)) → (t : List Σ ) → Set regex-language φ dec _ = ⊥ regex-language ε dec [] = ⊤ regex-language ε dec (_ ∷ _) = ⊥ regex-language (x *) dec f = Star ( regex-language x dec ) f regex-language (x & y) dec f = split ( regex-language x dec ) ( regex-language y dec ) f regex-language (x || y) dec f = ( regex-language x dec f ) ∨ ( regex-language y dec f ) regex-language < h > dec [] = ⊥ regex-language < h > dec (h1 ∷ [] ) with dec h h1 ... | yes _ = ⊤ ... | no _ = ⊥ regex-language < h > f _ = ⊥ char-dec : (i j : char) → Dec (i ≡ j) char-dec a a = yes refl char-dec b b = yes refl char-dec c c = yes refl char-dec d d = yes refl char-dec a b = no (λ ()) char-dec a c = no (λ ()) char-dec a d = no (λ ()) char-dec b a = no (λ ()) char-dec b c = no (λ ()) char-dec b d = no (λ ()) char-dec c a = no (λ ()) char-dec c b = no (λ ()) char-dec c d = no (λ ()) char-dec d a = no (λ ()) char-dec d b = no (λ ()) char-dec d c = no (λ ()) char-list : List char char-list = a ∷ b ∷ c ∷ d ∷ [] test-regex2 : ¬ (regex-language r1 char-dec ( a ∷ [] ) ) test-regex2 (case1 ()) test-regex2 (case2 ()) test-regex3 : regex-language r1 char-dec ( a ∷ b ∷ c ∷ [] ) test-regex3 = case2 (case1 [ tt , case2 (case1 [ tt , tt ]) ] ) splitb : {Σ : Set} → (List Σ → Bool) → ( List Σ → Bool) → List Σ → Bool splitb x y [] = x [] /\ y [] splitb x y (h ∷ t) = (x [] /\ y (h ∷ t)) \/ splitb (λ t1 → x ( h ∷ t1 )) (λ t2 → y t2 ) t {-# TERMINATING #-} repeatb : {Σ : Set} → (List Σ → Bool) → List Σ → Bool repeatb x [] = true repeatb {Σ} x ( h ∷ t ) = splitb x (repeatb {Σ} x) ( h ∷ t ) regular-language : {Σ : Set} → Regex Σ → ((i j : Σ) → Dec ( i ≡ j)) → List Σ → Bool regular-language ε dec _ = false regular-language φ dec [] = true regular-language φ dec (_ ∷ _ ) = false regular-language (x *) dec = repeatb ( regular-language x dec ) regular-language (x & y) dec = splitb ( regular-language x dec ) ( regular-language y dec ) regular-language (x || y) dec = λ s → ( regular-language x dec s ) \/ ( regular-language y dec s) regular-language < h > dec [] = false regular-language < h > dec (h1 ∷ [] ) with dec h h1 ... | yes _ = true ... | no _ = false regular-language < h > dec _ = false test-regex4 : Bool test-regex4 = regular-language r1 char-dec ( a ∷ [] ) test-regex5 : Bool test-regex5 = regular-language r1 char-dec ( a ∷ b ∷ c ∷ [] ) -- open import Data.Nat.DivMod -- test-regex-even : Set -- test-regex-even = (s : List char ) → regular-expr ( ( any & any ) * ) s → (length s) mod 2 ≡ zero empty? : {Σ : Set} → Regex Σ → Bool empty? φ = false empty? ε = true empty? (r *) = true empty? (r & s) with empty? r ... | false = false ... | true = empty? s empty? (r || s) with empty? r | empty? s ... | false | false = false ... | true | _ = true ... | _ | true = true empty? < x > = false data RexResult {Σ : Set} : Set where fail : RexResult finish : RexResult continue : (Regex Σ) → RexResult derivative : {Σ : Set} → Regex Σ → Σ → ((i j : Σ ) → Dec ( i ≡ j )) → RexResult derivative φ x dec = fail derivative ε x dec = fail derivative (r *) x dec with derivative r x dec ... | continue r1 = continue (r1 & (r *)) ... | finish = continue (r *) ... | fail = fail derivative (r & s) x dec with derivative r x dec | derivative s x dec | empty? r ... | fail | _ | _ = fail ... | finish | continue s1 | true = continue (s1 || s) ... | finish | _ | _ = continue s ... | continue r1 | continue s1 | true = continue (s1 || (r1 & s)) ... | continue r1 | _ | _ = continue (r1 & s) derivative (r || s) x dec with derivative r x dec | derivative s x dec ... | continue r1 | continue s1 = continue ( r1 || s1 ) ... | fail | p = p ... | p | fail = p ... | finish | _ = finish ... | _ | finish = finish derivative < i > x dec with dec i x ... | yes y = finish ... | no _ = fail open import automaton regex→automaton : {Σ : Set} → Regex Σ → ((i j : Σ ) → Dec ( i ≡ j )) → Automaton RexResult Σ regex→automaton {Σ} r dec = record { δ = δ ; F = F } where δ : RexResult → Σ → RexResult δ fail i = fail δ finish i = fail δ (continue r) i = derivative r i dec F : RexResult → Set F (continue r) with empty? r ... | true = ⊤ ... | false = ⊥ F finish = ⊤ F _ = ⊥ open Automaton a2 : accept (regex→automaton r2 char-dec ) (continue r2) ( a ∷ a ∷ b ∷ c ∷ [] ) a2 = tt tr2 = trace (regex→automaton r2 char-dec ) (continue r2) ( a ∷ a ∷ b ∷ c ∷ [] ) a2 a1 : accept (regex→automaton < a > char-dec ) (continue < a > ) ( a ∷ [] ) a1 = tt tr1 = trace (regex→automaton < a > char-dec ) (continue < a > ) ( a ∷ [] ) a1 a3 : accept (regex→automaton < a > char-dec ) (continue (< a > & < b > )) ( a ∷ b ∷ [] ) a3 = tt tr3 = trace (regex→automaton < a > char-dec ) (continue (< a > & < b > )) ( a ∷ b ∷ [] ) regex→accept : {Σ : Set} → (r : Regex Σ ) → (x : List Σ) → (dec : (i j : Σ ) → Dec ( i ≡ j )) → accept (regex→automaton r dec) (continue r) x → regular-expr r x regex→accept r x dec ac = {!!} regex←accept : {Σ : Set} → (r : Regex Σ ) → (x : List Σ) → (dec : (i j : Σ ) → Dec ( i ≡ j )) → regular-expr r x → accept (regex→automaton r dec) (continue r) x regex←accept r x dec re = {!!} RE-dec : {Σ : Set} → ((s t : Σ) → Dec (s ≡ t)) → (x y : Regex Σ) → Dec (x ≡ y) RE-dec dec (x *) (y *) with RE-dec dec x y ... | yes refl = yes refl ... | no n = no (contra-position relem1 n ) where relem1 : (x *) ≡ (y *) → x ≡ y relem1 refl = refl RE-dec dec (x *) (_ & _) = no (λ ()) RE-dec dec (x *) (_ || _) = no (λ ()) RE-dec dec (x *) < _ > = no (λ ()) RE-dec dec (x & x1) (y & y1) with RE-dec dec x y | RE-dec dec x1 y1 ... | yes refl | yes refl = yes refl ... | no n | _ = no (contra-position relem2 n ) where relem2 : x & x1 ≡ y & y1 → x ≡ y relem2 refl = refl ... | _ | no n = no (contra-position relem3 n ) where relem3 : x & x1 ≡ y & y1 → x1 ≡ y1 relem3 refl = refl RE-dec dec (x & x1) (y *) = no (λ ()) RE-dec dec (x & x1) (_ || _) = no (λ ()) RE-dec dec (x & x1) < _ > = no (λ ()) RE-dec dec (x || x1) φ = no (λ ()) RE-dec dec (x || x1) ε = no (λ ()) RE-dec dec (x || x1) (y *) = no (λ ()) RE-dec dec (x || x1) (y & y₁) = no (λ ()) RE-dec dec (x || x1) (y || y1) with RE-dec dec x y | RE-dec dec x1 y1 ... | yes refl | yes refl = yes refl ... | no n | _ = no (contra-position relem4 n ) where relem4 : x || x1 ≡ y || y1 → x ≡ y relem4 refl = refl ... | _ | no n = no (contra-position relem5 n ) where relem5 : x || x1 ≡ y || y1 → x1 ≡ y1 relem5 refl = refl RE-dec dec (x || x1) < x₁ > = no (λ ()) RE-dec dec < x > φ = no (λ ()) RE-dec dec < x > ε = no (λ ()) RE-dec dec < x > (y *) = no (λ ()) RE-dec dec < x > (y & y₁) = no (λ ()) RE-dec dec < x > (y || y₁) = no (λ ()) RE-dec dec < x > < x₁ > with dec x x₁ ... | yes refl = yes refl ... | no n = no (contra-position relem6 n ) where relem6 : < x > ≡ < x₁ > → x ≡ x₁ relem6 refl = refl RE-dec dec φ φ = yes refl RE-dec dec φ ε = no (λ ()) RE-dec dec φ (y *) = no (λ ()) RE-dec dec φ (y & y₁) = no (λ ()) RE-dec dec φ (y || y₁) = no (λ ()) RE-dec dec φ < x > = no (λ ()) RE-dec dec ε φ = no (λ ()) RE-dec dec ε ε = yes refl RE-dec dec ε (y *) = no (λ ()) RE-dec dec ε (y & y₁) = no (λ ()) RE-dec dec ε (y || y₁) = no (λ ()) RE-dec dec ε < x > = no (λ ()) RE-dec dec (x *) φ = no (λ ()) RE-dec dec (x *) ε = no (λ ()) RE-dec dec (x & x1) φ = no (λ ()) RE-dec dec (x & x1) ε = no (λ ())