package prbnmcn-basic-structures

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file free_module.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module Make
    (Basis : Basic_intf.Std)
    (R : Basic_intf.Ring_std)
    (M : Map.S with type key = Basis.t) :
  Basic_intf.Free_module_std
    with module R = R
     and module Basis = Basis
     and type basis = Basis.t
     and type t = R.t M.t = struct
  module R = R
  module Basis = Basis

  type basis = Basis.t

  type t = R.t M.t

  let zero = M.empty

  let binop op (vec1 : t) (vec2 : t) : t =
    M.union
      (fun _elt i1 i2 ->
        let res = op i1 i2 in
        if R.compare res R.zero = 0 then None else Some res)
      vec1
      vec2
    [@@inline]

  let add vec1 vec2 = binop R.add vec1 vec2

  let smul coeff vec =
    if R.compare coeff R.zero = 0 then zero
    else M.map (fun x -> R.mul coeff x) vec

  let neg vec = M.map R.neg vec

  let fold = M.fold

  let bind x f =
    fold (fun basis coeff acc -> add acc (smul coeff (f basis))) x zero

  let eval vec i = try M.find i vec with Not_found -> R.zero

  let of_list : (basis * R.t) list -> t =
   fun l ->
    let exception Not_all_distinct in
    try
      List.fold_left
        (fun vec (i, elt) ->
          if M.mem i vec then raise Not_all_distinct
          else if R.equal elt R.zero then vec
          else add vec (M.singleton i elt))
        zero
        l
    with Not_all_distinct -> invalid_arg "of_list"

  let delta x = of_list [(x, R.one)]

  let compare = M.compare R.compare

  let equal x y = compare x y = 0

  let hash (x : t) =
    M.fold (fun basis v hash -> Hashtbl.hash (basis, R.hash v, hash)) x 0

  let pp : Format.formatter -> t -> unit =
   fun fmtr vec ->
    if M.is_empty vec then Format.fprintf fmtr "∅"
    else
      let bindings = M.bindings vec in
      Format.pp_print_list
        ~pp_sep:(fun fmtr () -> Format.fprintf fmtr ";@,")
        (fun fmtr (k, v) -> Format.fprintf fmtr "%a ↦ %a" Basis.pp k R.pp v)
        fmtr
        bindings
end

module type Free_module_with_map = sig
  type r

  module Map : Map.S

  include
    Basic_intf.Free_module_std
      with type R.t = r
       and type Basis.t = Map.key
       and type t = r Map.t
end

module Make_with_map (X : Basic_intf.Std) (R : Basic_intf.Ring_std) :
  Free_module_with_map with type r = R.t and type Map.key = X.t = struct
  type r = R.t

  module Map = Map.Make (X)
  include Make (X) (R) (Map)
end

module Rational_valued = struct
  module Int = Make (Std.Int) (Std.Q) (Int_map)
  module String = Make (Std.String) (Std.Q) (String_map)
  module Float = Make (Std.Float) (Std.Q) (Float_map)
  module Bool = Make (Std.Bool) (Std.Q) (Bool_map)
  module Make_with_map (X : Basic_intf.Std) = Make_with_map (X) (Std.Q)
end

module Float_valued = struct
  module Int = Make (Std.Int) (Std.Float) (Int_map)
  module String = Make (Std.String) (Std.Float) (String_map)
  module Float = Make (Std.Float) (Std.Float) (Float_map)
  module Bool = Make (Std.Bool) (Std.Float) (Bool_map)
  module Make_with_map (X : Basic_intf.Std) = Make_with_map (X) (Std.Float)
end
OCaml

Innovation. Community. Security.