regexp.syn

Require Import regexp.prelude.
Require Import regexp.expr.
Require regexp.lang.
Require Import regexp.concrete.universe.
Require Import regexp.concrete.function.
Require Import regexp.concrete.rule.

PHOAS based syntax for building regexps

Inductive t {B v : Type} : nat Type :=
| Ret : expr.t v t 0
| Bind : B {n}, (expr.t v t n) t (S n).

Arguments t : clear implicits.
Arguments Bind {B v} _ {n}.

The existentially quantified closed syntax tree
Definition T B n := v, t B v n.

Most syntactic operations on closed syntax trees begin with defining the corresponding operation with a suitably chosen variable type v. The internal module contains these functions and are meant to be used by the function of the same name defined at the top level.

Definition unret {B v}(bt : t B v 0) : expr.t v :=
  match bt with
  | Ret ee
  end.

Definition unbind {B v m}(bt : t B v (S m)) : B × (v t B v m) :=
  match bt with
  | Bind b _ bfn(b , fun vbfn (single v))
  end.

Fixpoint sortOf (n : nat) : sort :=
  match n with
  | 0 ⇒ 𝟙
  | S m ⇒ (𝟙 sortOf m)
  end%con.

Definition vars v n := if n is m.+1 then (sortOf m ~> v)%con else option v.

Definition split {v n} : vars v (S n) v × vars v n :=
  if n is m.+1 then fun vs : vars v (m.+2) ⇒ let (H,T) := unsum vs in (unconst H, T)
  else fun vs : vars v 1 ⇒ (unconst vs, None).

Definition attach {v n} : (v × vars v n) vars v (S n) :=
  if n is m.+1 then fun vslet (x,rest) := vs in (constant x ++ rest)%con
  else fun vsconstant vs.1.

Definition filled B v n := (vars B n × expr.t v)%type.

Fixpoint fill {B}{v : finType} {n} : vars v n t B v n filled B v n :=
  if n is m.+1 then fun vs btlet (h,t) := split vs in
                              let (b,bfn) := unbind bt in
                              let (bs,e) := fill t (bfn h) in
                              (attach (b, bs) , e)
  else fun _ bt(None, unret bt).

Definition alphabet := universe.typeOf \o sortOf.
Compiled expression that can be converted to hardware

Module internal.

  Fixpoint denote {B n}(re : t B B n) : expr.t B :=
    match re with
    | Ret rr
    | Bind b _ bfndenote (bfn (single b))
    end.

  Definition alloc m : vars (alphabet m) (m.+1) := function.from (fun x : sortOf mx).

  Definition compile {B n}(re : t B (alphabet n) n.+1) : (sortOf n ~> B)%con × expr.t (alphabet n) :=
    fill (alloc n) re.

End internal.

Definition denote {B n}(re : T B n) : expr.t B := internal.denote (re B).

Definition compile {B n}(re : T B (n.+1)) : (sortOf n ~> B)%con × expr.t (alphabet n) := internal.compile (re (alphabet n)).

Custom syntax for regular expr

Declare Custom Entry rules.

Notation "'let' x ':=' b 'in' E"
  := (Bind b (fun xE)) (in custom rules at level 70, right associativity, x ident, b constr,
          format "'let' x ':=' b 'in' '//' E"
        ).

Notation "'match' e"
  := (Ret e) (in custom rules at level 70, right associativity, e constr).

Definition makeRule {I n}(re : T (I bool) (n.+1)) : Rule I :=
  let (bt, e) := compile re in
  {|
    letter := sortOf n;
    atomTable := bt;
    regexp := e
  |}.

Notation "[rule| e |]" := (makeRule (fun _e)) (e custom rules).

Example foo : Rule nat := [rule| let dgt := fun xx < 10 in
                               let oct := fun xx < 7 in
                               match many (dgt || oct)%re
                               |].