package mugen

  1. Overview
  2. Docs

Source file Semantics.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
module Endo =
struct
  include SemanticsSigs.Endo

  module Make (P : Param) : S with type shift := P.Shift.t and type level := P.level =
  struct
    include P
    open Syntax.Endo

    let top = level Top

    let shifted l s =
      match unlevel l with
      | Some Top -> invalid_arg "cannot shift the top level"
      | Some (Shifted (l, s')) ->
        let s = Shift.compose s' s in
        level @@ Shifted (l, s)
      | None ->
        level @@ Shifted (l, s)
  end
end

module Free =
struct
  include SemanticsSigs.Free

  module Make (P : Param) : S with type shift := P.Shift.t and type var := P.var =
  struct
    open Syntax.Free

    let var = var
    module P = struct
      include P
      type level = (Shift.t, var) Syntax.free
      let level t = Level t
      let unlevel t = match t with Level l -> Some l | _ -> None
    end

    include P
    include Endo.Make(P)

    let normalize l =
      let rec go l acc =
        match l with
        | Level Top ->
          if acc = []
          then level Top
          else invalid_arg "cannot shift the top level"
        | Level (Shifted (l, s)) -> go l (s :: acc)
        | Var v -> Level (Shifted (Var v, List.fold_left Shift.compose Shift.id acc))
      in
      go l []

    let equal x y =
      match normalize x, normalize y with
      | Level Top, Level Top -> true
      | Level (Shifted (Var vx, sx)), Level (Shifted (Var vy, sy)) ->
        equal_var vx vy && Shift.equal sx sy
      | _ -> false

    let lt x y =
      match normalize x, normalize y with
      | Level (Shifted (Var _, _)), Level Top -> true
      | Level (Shifted (Var vx, sx)), Level (Shifted (Var vy, sy)) ->
        equal_var vx vy && Shift.lt sx sy
      | _ -> false

    let leq x y =
      match normalize x, normalize y with
      | _, Level Top -> true
      | Level (Shifted (Var vx, sx)), Level (Shifted (Var vy, sy)) ->
        equal_var vx vy && Shift.leq sx sy
      | _ -> false

    let gt x y = lt y x
    let geq x y = leq y x

    module Infix =
    struct
      let (=) = equal
      let (<) = lt
      let (<=) = leq
      let (>) = gt
      let (>=) = geq
    end
  end
end