File: weightmap.mlg.cppo

package info (click to toggle)
coq-quickchick 2.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,428 kB
  • sloc: ml: 4,367; ansic: 789; makefile: 384; sh: 27; python: 4; perl: 2; lisp: 2
file content (112 lines) | stat: -rw-r--r-- 3,497 bytes parent folder | download | duplicates (4)
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
112
DECLARE PLUGIN "coq-quickchick.plugin"

{
(*

THIS FILE IS PREPROCESSED USING cppo
MAKE SURE TO EDIT THE .cppo SOURCE OF THIS FILE RATHER THAN THE GENERATED RESULT

*)


open GenericLib
open Stdarg
open Error
open Pp
open Constrexpr
open Libnames

module CtrMap = Map.Make(Ord_ctr)

type weight_ast = 
  | WNum of int
  | WSize 

let weight_ast_to_string = function
  | WNum n -> string_of_int n
  | WSize  -> "size"
  
let weight_env : weight_ast CtrMap.t ref =
  Summary.ref ~name:"QC_weight_environ" CtrMap.empty

let weight_env_to_string () =
  let all = CtrMap.fold (fun ctr w acc -> (Printf.sprintf "%s : %s\n" 
                                                          (constructor_to_string ctr) 
                                                          (weight_ast_to_string w))::acc) 
                        !weight_env [] in
  String.concat "" all

let register_weights (l : (constructor * weight_ast) list) =
  List.iter (fun (c,w) -> weight_env := CtrMap.add c w !weight_env) l

let convert_constr_to_weight c = 
  match c.CAst.v with
  | CPrim (Number (NumTok.SPlus, i)) ->
      (match NumTok.Unsigned.to_nat i with
      | Some n -> WNum (int_of_string n)
      | None -> failwith "QC: Numeric weights should be positive integers."
      )
  | CRef (r, _) ->
     if string_of_qualid r = "size" then WSize
     else failwith "QC: Expected number or 'size'."
  | _ -> failwith "QC: match failure."

let convert_constr_to_cw_pair c : (constructor * weight_ast) = 
  match c.CAst.v with
  | CNotation (_, _, ([a],[[b]],_,_)) ->
      let ctr = 
        match a with 
        | { CAst.v = CRef (r, _); _ } -> injectCtr (string_of_qualid r)
        | _ -> failwith "First argument should be a constructor name"
      in 
      let w = convert_constr_to_weight b in
      (ctr,w)
  | _ -> failwith "Not a pair?"

#if COQ_VERSION >= (8, 16, 0)
let register_weights_object =
  Libobject.declare_object
    (Libobject.superglobal_object_nodischarge "QC_register_weights"
      ~cache:(fun ws -> register_weights ws)
      ~subst:None (* XXX should this be substitutive? why are we using qualid instead of Names.constructor? *))

let add_weights w = Lib.add_leaf (register_weights_object w)
#else
let register_weights_object = 
  Libobject.declare_object
    {(Libobject.default_object ("QC_register_weights")) with
      Libobject.cache_function = (fun (_,ws) -> register_weights ws);
      Libobject.load_function = (fun _ (_,ws) -> register_weights ws)}

let add_weights w = Lib.add_anonymous_leaf (register_weights_object w)
#endif
let lookup_weight b ctr size_var = 
  try match CtrMap.find ctr !weight_env with
      | WNum n -> gInt n
      | WSize  -> gSucc (gVar (size_var))
  with Not_found -> if b then gInt 1 else gSucc (gVar (size_var))

}

VERNAC COMMAND EXTEND QuickChickWeights CLASSIFIED AS SIDEFF
  | ["QuickChickWeights" constr(c)] -> 
     {
       let weight_assocs = 
         match c.CAst.v with
         | CNotation (_, _, ([a],[b],_,_)) ->
             let c = convert_constr_to_cw_pair a in
             let cs = List.map convert_constr_to_cw_pair b in
             c :: cs
         | _ -> failwith "QC: Expected list of constructor -> weights"
       in 
       msg_debug (str "Current weights: " ++ fnl ());
       msg_debug (str (weight_env_to_string ()) ++ fnl ());
       add_weights weight_assocs
     }
END

(*
let s1' = Names.string_of_id s1 in
       let s2' = Names.string_of_id s2 in 
       Lib.add_anonymous_leaf (set_debug_flag s1' (s1',s2')) ]
 *)