mirror of
https://github.com/AdaCore/why3.git
synced 2026-02-12 12:34:55 -08:00
149 lines
4.3 KiB
Plaintext
149 lines
4.3 KiB
Plaintext
use int.Int
|
|
use seq.Seq
|
|
use seq.FreeMonoid
|
|
|
|
(** {Logical definition of Regular Expressions} *)
|
|
|
|
type char
|
|
|
|
type regexp =
|
|
| Empty
|
|
| Epsilon
|
|
| Char char
|
|
| Alt regexp regexp
|
|
| Concat regexp regexp
|
|
| Star regexp
|
|
|
|
|
|
predicate re_g (r r1: regexp)
|
|
|
|
axiom re_g_alt :
|
|
forall r r1 r2: regexp.
|
|
r = Alt r1 r2 -> re_g r r1 /\ re_g r r2
|
|
|
|
axiom re_g_concat :
|
|
forall r r1 r2: regexp.
|
|
r = Concat r1 r2 -> re_g r r1 /\ re_g r r2
|
|
|
|
axiom re_g_star :
|
|
forall r r1: regexp.
|
|
r = Star r1 -> re_g r r1
|
|
|
|
-- lemma re_g_trans :
|
|
-- forall r1 r2 r3: regexp. re_g r1 r2 -> re_g r2 r3 -> re_g r1 r3
|
|
|
|
type word = seq char
|
|
|
|
inductive mem (w: word) (r: regexp) =
|
|
| mem_eps:
|
|
mem empty Epsilon
|
|
| mem_char:
|
|
forall c: char. mem (singleton c) (Char c)
|
|
| mem_altl:
|
|
forall w: word, r1 r2: regexp. mem w r1 -> mem w (Alt r1 r2)
|
|
| mem_altr:
|
|
forall w: word, r1 r2: regexp. mem w r2 -> mem w (Alt r1 r2)
|
|
| mem_concat:
|
|
forall w1 w2: word, r1 r2: regexp.
|
|
mem w1 r1 -> mem w2 r2 -> mem (w1 ++ w2) (Concat r1 r2)
|
|
| mems1:
|
|
forall r: regexp. mem empty (Star r)
|
|
| mems2:
|
|
forall w1 w2: word, r: regexp.
|
|
mem w1 r -> mem w2 (Star r) -> mem (w1 ++ w2) (Star r)
|
|
|
|
lemma mem_star_nonempty: forall w: word. forall r: regexp.
|
|
mem w (Star r) ->
|
|
w <> empty ->
|
|
exists k: int.
|
|
0 < k <= length w /\
|
|
mem w[..k] r /\
|
|
mem w[k..] (Star r)
|
|
|
|
lemma split_concat: forall w: word. forall r1 r2: regexp.
|
|
mem w (Concat r1 r2) ->
|
|
exists k: int.
|
|
0 <= k <= length w /\
|
|
mem w[..k] r1 /\ mem w[k..] r2
|
|
|
|
lemma concat_split: forall w: word. forall r1 r2: regexp. forall i j k: int.
|
|
0 <= i <= k <= j <= length w ->
|
|
mem w[i..k] r1 ->
|
|
mem w[k..j] r2 ->
|
|
mem w[i..j] (Concat r1 r2)
|
|
|
|
lemma extseq: forall w: word. w[0..length w] = w
|
|
|
|
(** {Coma Part} *)
|
|
use coma.Std
|
|
|
|
let unRe (r: regexp)
|
|
(empty {r = Empty})
|
|
(eps {r = Epsilon})
|
|
(char (c: char) {r = Char c})
|
|
(alt (r1 r2: regexp) {r = Alt r1 r2})
|
|
(cat (r1 r2: regexp) {r = Concat r1 r2})
|
|
(star (r1: regexp) {r = Star r1})
|
|
= any
|
|
|
|
predicate cons (w: word) (r: regexp) (ck: int -> bool) (i: int) =
|
|
[@inline:trivial]
|
|
exists j. i <= j <= length w /\ mem w[i..j] r /\ ck j
|
|
|
|
let accept_nonterm (r: regexp) (w: word) {} (ret (b: bool) {b <-> mem w r})
|
|
= a {r} {0} {fun j -> j = n}
|
|
(fun (i: int) (h) -> if {i = n} (ret {true}) h)
|
|
(ret {false})
|
|
[ a (r: regexp) (i: int) (ck: int -> bool) {0 <= i <= n}
|
|
(k (j: int) {mem w[i..j] r} {i <= j <= n} (h {not ck j}))
|
|
(o {not cons w r ck i})
|
|
= unRe {r} empty eps char alt cat star
|
|
[ empty -> o
|
|
| eps -> k {i} o
|
|
| char (c: char) ->
|
|
if {i < n && w[i] = c} (k {i+1} o) o
|
|
| alt (r1 r2: regexp) ->
|
|
a {r1} {i} {ck} k (-> a {r2} {i} {ck} k o)
|
|
| cat (r1 r2: regexp) ->
|
|
a {r1} {i} {cons w r2 ck}
|
|
(fun (j: int) (h) -> a {r2} {j} {ck} k h) o
|
|
| star (r1: regexp) ->
|
|
k {i} (-> a {r1} {i} {fun j -> i < j && cons w r ck j}
|
|
(fun (j: int) (h) -> if {i < j} (-> a {r} {j} {ck} k h) h)
|
|
o)
|
|
]
|
|
]
|
|
[ n: int = length w ]
|
|
|
|
predicate v (n old_i i: int) (old_r r: regexp) =
|
|
(n-i) < (n-old_i) || (old_i=i /\ re_g old_r r)
|
|
|
|
-- variant lexico : n-i, r
|
|
let accept_terminates (r: regexp) (w: word) {} (ret (b: bool) {b <-> mem w r})
|
|
= a {r} {0} {fun j -> j = n}
|
|
(fun (i: int) (h) -> if {i = n} (ret {true}) h)
|
|
({not mem w[0..n] r} ret {false})
|
|
[ a (r: regexp) (i: int) (ck: int -> bool) {0 <= i <= n}
|
|
(k (j: int) {mem w[i..j] r} {i <= j <= n} (h {not ck j}))
|
|
(o {not cons w r ck i})
|
|
= (fun (r__: regexp) (i__: int) ->
|
|
unRe {r} empty eps char alt cat star
|
|
[ empty -> o
|
|
| eps -> k {i} o
|
|
| char (c: char) ->
|
|
if {i < n && w[i] = c} (k {i+1} o) o
|
|
| alt (r1 r2: regexp) ->
|
|
arec {r1} {i} {ck} k (-> arec {r2} {i} {ck} k o)
|
|
| cat (r1 r2: regexp) ->
|
|
arec {r1} {i} {cons w r2 ck}
|
|
(fun (j: int) (h) -> arec {r2} {j} {ck} k h) o
|
|
| star (r1: regexp) ->
|
|
k {i} (-> arec {r1} {i} {fun j -> i < j && cons w r ck j}
|
|
(fun (j: int) (h) -> if {i < j} (-> arec {r} {j} {ck} k h) h)
|
|
o)
|
|
]
|
|
[ arec (r_: regexp) (i_: int) (ck_: int -> bool) (k_ (j: int) (h)) (o_)
|
|
-> { v n i__ i_ r__ r_ } a {r_} {i_} {ck_} k_ o_ ]) {r} {i}
|
|
]
|
|
[ n: int = length w ]
|