package lutin

  1. Overview
  2. Docs
Lutin: modeling stochastic reactive systems

Install

Dune Dependency

Authors

Maintainers

Sources

lutin.v2.71.15.tgz
md5=a7da42464f4ad0619bc4e759f2defca3
sha512=2142fe82b22c10f1baaf8591d177f2497c00b93e4f9d92b50e4ff24b34ecbc9d5dc8537efa21c94c09623501a1ef26292cfad36fa12fdde5cbe0add716b9c7cb

doc/src/lutin/ckTypeEff.ml.html

Source file ckTypeEff.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
(*----------------------------------------------------------
                 TYPE/BINDING CHECK 
------------------------------------------------------------

Type "sémantique" des idents et des exps
n.b. pour l'instant, on n'a que des types de base,
mais ga pourrait changer ...

Pour les profils, on gère le polymorphisme
avec des pseudos-types "any"

Pour les types any, on peut compléter par une
   condition qui restreint le match typiquement 
   - aux types data (autres que trace) 
   - aux types numériques seulement
----------------------------------------------------------*)
open LutErrors
open Format
open Syntaxe

let dbg = Verbose.get_flag "CkType"

type basic = Syntaxe.predef_type

(** le type "weight" est purement interne *)
type t =
   TEFF_weight
|  TEFF_except
|  TEFF_trace
|  TEFF_data of basic
|  TEFF_list of basic
|  TEFF_tuple of basic list
|	TEFF_any of string * any_cond
|	TEFF_ref of basic
and  any_cond = (t -> t option) 

let lift_ref = function
	TEFF_ref a -> TEFF_data a
|	_ -> (
	raise (Failure "not a ref")
)

let is_data = function
	TEFF_data _ -> true
|	_ ->  false

let get_data_tuple tl = (
	let undata = function
		TEFF_data d -> d
	| _ -> raise (Failure "not a data")
	in
	TEFF_tuple (List.map undata tl)
)

let tuple_to_data_list t = (
	let redata = function
		d -> TEFF_data d
	in
	match t with
	TEFF_tuple bl -> (List.map redata bl)
	| _ -> raise (Failure "not a tuple")
)

let is_ref = function
	TEFF_ref _ -> true
|	_ ->  false

let basic_to_string = (
function
 	Bool -> "bool"
|	Int -> "int"
|	Real -> "real"
)
(* pretty-print des types *)
let rec to_string = ( function
 	 | TEFF_data d -> (basic_to_string d)
    |	TEFF_list d -> (basic_to_string d)^ " list"
    |	TEFF_tuple l -> String.concat "*" (List.map basic_to_string l)
    |	TEFF_ref x -> (basic_to_string x)^" ref"
    |	TEFF_trace -> "trace"
    |	TEFF_weight -> "weight"
    |	TEFF_except -> "exception"
    |	TEFF_any (s, _) -> s
  ) and prof_to_string = ( function
	   (tl, t) -> (
		  sprintf "%s->%s"
			 (list_to_string tl)
			 (list_to_string t)
	   )
  ) and list_to_string = ( function
	   [] -> ""
    |	t::[] -> to_string t
    |	t::l -> sprintf "%s*%s" (to_string t) (list_to_string l)
  )

let ref_of = function
	TEFF_data x -> TEFF_ref x 
	| z -> (
		raise (Internal_error ("CkTypeEff:ref_of",
			"unexpected ref flag on type "^(to_string z)
		))
	)

(* any data :
   accepte tout type data ou data ref,
   lifte les ref
*)
let any_data_cond = (
function 
	  TEFF_data x -> Some (TEFF_data x)
	| TEFF_ref x  -> Some (TEFF_data x)
	| _ -> None
)

let any_num_cond = (
function 
	  TEFF_data Int  -> Some (TEFF_data Int)
	| TEFF_data Real -> Some (TEFF_data Real)
	| TEFF_ref Int  -> Some (TEFF_data Int)
	| TEFF_ref Real -> Some (TEFF_data Real)
	| _ -> None
)

(* type "fonctionnel", pour les macros et les opérateurs *)
type profile =
	t list * t list

(* acceptable profile for external func *)
let is_data_profile (i,o) = (
	List.fold_left (fun a x -> a && (is_data x)) true (i @ o)
)

let res_of_prof : profile -> t list = snd 
let params_of_prof : profile -> t list = fst
let split_prof = fun x -> x 
let get_prof tinl tout = (tinl, tout)


(* TYPE USUELS *)
let boolean  = TEFF_data Bool
let booleans = TEFF_list Bool
let boolref  = TEFF_ref Bool
let intref  = TEFF_ref Int
let integer   = TEFF_data Int
let real  = TEFF_data Real
let trace = TEFF_trace

let weight = TEFF_weight

let except = TEFF_except

(* QQ TYPES ANY ... *)
let any_data1  = TEFF_any  ("'a", any_data_cond)
let _any_data2  = TEFF_any  ("'b", any_data_cond)
let any_num1 = TEFF_any  ("'n", any_num_cond)

(* PROFILS USUELS *)
   (* simples ... *)
let prof_t_t = ([trace], [trace])
let prof_tt_t = ([trace;trace], [trace])
let prof_tw_t = ([trace;weight], [trace])
let prof_it_t = ([integer;trace], [trace])
let prof_ti_t = ([trace;integer], [trace])
let prof_bt_t = ([boolean;trace], [trace])
let prof_iit_t = ([integer;integer;trace], [trace])
let prof_b_b = ([boolean], [boolean])
let prof_bb_b = ([boolean;boolean], [boolean])
let prof_bl_b = ([booleans], [boolean])
                
let prof_ii_i = ([integer;integer], [integer])
let prof_iii_i = ([integer;integer;integer], [integer])
let prof_et_t = ([except;trace], [trace])
let prof_ett_t = ([except;trace;trace], [trace])
   (* polymorphes data ... *)
let prof_bxx_x = ([boolean;any_data1;any_data1], [any_data1])
let prof_xx_b = ([any_data1;any_data1], [boolean])
   (* surchargés numériques ... *)
let prof_nn_b = ([any_num1;any_num1], [boolean])
let prof_nn_n = ([any_num1;any_num1], [any_num1])
let prof_n_n = ([any_num1], [any_num1])

let rec of_texp = ( function 
	TEXP_predef Bool -> boolean
|	TEXP_predef Int -> integer
|	TEXP_predef Real -> real
|	TEXP_trace -> trace
|	TEXP_ref x -> ref_of (of_texp (TEXP_predef x))
)


(* compatibilité des types :
	bool -> trace
	int -> weight
	int ref -> weight
	x ref -> x
*)
let lifts_to t1 t2 = (
  let res =
	 (t1 = t2)
    || ((t1 = boolref) && (t2 = boolean))
    || ((t1 = boolean) && (t2 = trace))
	 || ((t1 = boolref) && (t2 = trace))
	 || ((t1 = integer) && (t2 = weight))
	 || ((t1 = intref) && (t2 = weight))
	 || (
		match (t1,t2) with
		  (TEFF_ref x, TEFF_data y) -> (x = y)
		| _ -> false
	 )
  in
  res
)
(* compatibilité d'un profil avec une liste de types de params
   Renvoie le type eff du résultat ou lève une exception :
	Failure OU Invalid_argument (on fait dans le détail ?)
*)
let rec match_prof tel prof = (
  (* table locale pour les types any *)
  let anytab = Hashtbl.create 2 in
  match prof with
  | ([TEFF_list Bool], [TEFF_data Bool]) -> (* a special case for xor/nor/# *)
	 let doit tc =
      try match_in_type anytab tc (TEFF_ref Bool)
      with _ -> match_in_type anytab tc boolean
    in
	 let _tins = List.map doit tel in
	 let _tout = List.map (match_out_type anytab) [TEFF_data Bool] in
    _tout
  | (txl, tres) ->
	 let doit tc tx = match_in_type anytab tc tx in
	 let _tins = List.map2 doit tel txl in
	 let _tout = List.map (match_out_type anytab) tres in
	 (* ICI : on a le profil effectif, 
		 est-ce que ca peut etre utile ??? *)
	 Verbose.exe ~flag:dbg (fun _ ->
		  Printf.fprintf stderr "CkTypeEff.match [%s] with (%s) gives %s\n"
			 (list_to_string tel)
			 (prof_to_string prof)
			 (list_to_string _tout)
	   );
	 _tout
)
(*
Vérifie la compatibilité :
- d'un type obtenu (tobtd)
- d'un type attendu (texptd)
- dans un table d'assoc. des any (anytab)
*)
and match_in_type anytab tobtd texptd =
  match (tobtd, texptd) with
  | (_ , TEFF_any (k, cond)) -> (
		try (
		  let tprev = Util.hfind anytab k in
		  match_in_type anytab tobtd tprev
      )
      with Not_found -> (
			 match (cond tobtd) with
		    | Some t -> (Hashtbl.add anytab k t ; t)
          | None -> failwith "uncompatible types"
		  )
	 )
  | _ -> (
		if (lifts_to tobtd texptd) then texptd
		else failwith "uncompatible types"
	 )
and match_out_type anytab tres = (
  match tres with
	 TEFF_any (k, _) -> (
		try (
		  Util.hfind anytab k
		) with Not_found -> (
			 failwith "uncompatible types"					
		  )
	 ) | _ -> tres
)
OCaml

Innovation. Community. Security.