Skip to content

Commit f71d0d7

Browse files
committed
Remove the non_tuple flag for the variables
The non_tuple flag for the variables is needed when we add both the collapse of the tuple (t * unit = t) and the collapse of the arrow (unit -> t = t). For now, we don't add the collapse of the arrow, and therefore, it is not needed.
1 parent 5162b30 commit f71d0d7

File tree

7 files changed

+35
-86
lines changed

7 files changed

+35
-86
lines changed

lib/common/Scheme.ml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,12 @@ type t = {
33
ty : Type.t ;
44
}
55

6-
type flags = NonArrow | NonTuple
7-
86
type var_type = Frozen | Flags of Variable.Flags.t
97

108
let parse_var_type =
119
let open CCParse in
1210
(string "^" >|= fun _ -> Frozen) <|>
13-
(many1 ((string ">" >|= fun _ -> NonArrow)
14-
<|> (string "*" >|= fun _ -> NonTuple))
15-
>|= fun l -> Flags (List.fold_left (fun flags m ->
16-
match m with
17-
| NonArrow -> Variable.Flags.(set non_arrow flags)
18-
| NonTuple -> Variable.Flags.(set non_tuple flags))
19-
Variable.Flags.empty l))
11+
(string ">" >|= fun _ -> Flags Variable.Flags.(set non_arrow empty))
2012

2113
let parse_var =
2214
let open CCParse in

lib/common/Type.ml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,6 @@ let is_non_arrow_var = function
401401
| Var v -> Variable.is_non_arrow v
402402
| _ -> false
403403

404-
let is_non_tuple_var = function
405-
| Var v -> Variable.is_non_tuple v
406-
| _ -> false
407-
408404
(** import functions *)
409405

410406
let of_outcometree of_outcometree env var (out_ty : Outcometree.out_type) =
@@ -495,7 +491,7 @@ let generate_var bdgs (env : Env.t) = function
495491
let v = Variable.(Gen.gen Flags.empty env.var_gen) in
496492
String.HMap.add bdgs name v;
497493
var env v)
498-
494+
499495
let of_outcometree', of_parsetree' =
500496
let wrap fn (env : Env.t) x =
501497
let env = Env.restart env in
@@ -567,7 +563,6 @@ let rec iter_consts t f =
567563
let variable_clash v = function
568564
| Var v' -> Variable.rel v v' <> Variable.Smaller
569565
| Arrow _ -> Variable.is_non_arrow v
570-
| Tuple _ -> Variable.is_non_tuple v
571566
| _ -> false
572567

573568

lib/common/Type.mli

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ val refresh_variables : Env.t -> t -> t
108108
val is_arrow : t -> bool
109109
val is_tuple : t -> bool
110110
val is_non_arrow_var : t -> bool
111-
val is_non_tuple_var : t -> bool
112111

113112
(* import functions *)
114113

lib/common/Variable.ml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module Flags : sig
1111
val empty : t
1212

1313
val non_arrow : field
14-
val non_tuple : field
1514

1615
val set : field -> t -> t
1716
val get : field -> t -> bool
@@ -30,14 +29,12 @@ end = struct
3029

3130
let equal = Int.equal
3231

33-
(* Writen reversed so that variable with the non_tuple flags are the smallest. *)
3432
let compare b1 b2 = Int.compare b2 b1
3533

3634
let empty = 0
3735

3836
(* This must be in this order, because of the compare function. *)
3937
let non_arrow = mk_field ()
40-
let non_tuple = mk_field ()
4138

4239
let set f b = (1 lsl f) lor b
4340
let get f b = (1 lsl f) land b <> 0
@@ -58,8 +55,6 @@ type var = t
5855

5956
let as_int v = v.id
6057

61-
(* The order must guarantee that the variable with the flags non_tuple are smaller than
62-
variable without this flags. *)
6358
let compare v1 v2 =
6459
CCPair.compare Flags.compare CCInt.compare (v1.flags, v1.id) (v2.flags, v2.id)
6560
let equal v1 v2 =
@@ -75,7 +70,6 @@ let rel v1 v2 =
7570

7671
let is_pure v = Flags.(equal empty v.flags)
7772
let is_non_arrow v = Flags.(get non_arrow v.flags)
78-
let is_non_tuple v = Flags.(get non_tuple v.flags)
7973

8074
let get_flags {flags; _} = flags
8175

@@ -160,8 +154,6 @@ let to_string =
160154
var.id
161155
|> base_26 'a'
162156
|> (fun l -> if is_non_arrow var then '>' :: l else l)
163-
|> (fun l -> if is_non_tuple var then '*' :: l else
164-
l)
165157
|> String.of_list
166158
in
167159
str

lib/common/Variable.mli

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ module Flags : sig
44

55
val empty : t
66
val non_arrow : field
7-
val non_tuple : field
87

98
val equal : t -> t -> bool
109

@@ -17,7 +16,7 @@ type t
1716
type var = t
1817
type rel = Smaller | Bigger | Equal | Incomparable
1918

20-
val as_int : t -> int
19+
val as_int : t -> int
2120
val equal : t CCEqual.t
2221
val compare : t CCOrd.t
2322

@@ -28,7 +27,6 @@ val rel : t -> t -> rel
2827

2928
val is_pure : t -> bool
3029
val is_non_arrow : t -> bool
31-
val is_non_tuple : t -> bool
3230

3331
val get_flags : t -> Flags.t
3432

lib/unification/AC.ml

Lines changed: 31 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ module System : sig
1212
nb_atom : int ; (* Number of atoms in each equation *)
1313
assoc_type : Type.t array ; (* Map from indices to the associated terms *)
1414
nb_non_var : int ; (* Non variables are at the beginning of the array, Variables at the end. *)
15-
nb_non_tuple : int ; (* Among the variable, first we have the non tuple variables *)
1615
system : int array array ;
1716
}
1817

@@ -40,13 +39,12 @@ end = struct
4039
nb_atom : int ; (* Number of atoms in each equation *)
4140
assoc_type : Type.t array ; (* Map from indices to the associated types *)
4241
nb_non_var : int ; (* Constants are at the beginning of the array, Variables at the end. *)
43-
nb_non_tuple : int ; (* Among the variable, first we have the non tuple variables *)
4442
system : int array array ;
4543
}
4644

47-
let pp ppf {system; assoc_type; nb_atom; nb_non_var; nb_non_tuple} =
48-
Format.fprintf ppf "@[<v>{nb_atom: %i@ nb_non_var: %i@ nb_non_tuple: %i@ assoc: %a@ system: %a}@]"
49-
nb_atom nb_non_var nb_non_tuple
45+
let pp ppf {system; assoc_type; nb_atom; nb_non_var} =
46+
Format.fprintf ppf "@[<v>{nb_atom: %i@ nb_non_var: %i@ assoc: %a@ system: %a}@]"
47+
nb_atom nb_non_var
5048
Fmt.(vbox (array ~sep:(any ",") Type.pp)) assoc_type
5149
Fmt.(vbox (array ~sep:cut @@ array ~sep:(any ", ") int)) system
5250

@@ -91,12 +89,6 @@ end = struct
9189
let m = Type.Set.fold (f part count) all_types Type.Map.empty in
9290
(!count, m)
9391
in
94-
let nb_non_tuple_var = Type.Set.fold (function
95-
| Type.Var v ->
96-
if Variable.is_non_tuple v then (+) 1 else Fun.id
97-
| _ -> Fun.id) all_types 0
98-
in
99-
nb_non_tuple_var,
10092
{
10193
S.variable = aux shape_partition.variable;
10294
shapes = List.map aux shape_partition.shapes;
@@ -114,7 +106,7 @@ end = struct
114106
TODO: is it true that equal type up to iso in the current substitution will be equal here?
115107
*)
116108
let make problems : t * t List.t =
117-
let nb_non_tuple, mapping = make_mapping problems in
109+
let mapping = make_mapping problems in
118110
let nb_vars, vars = mapping.variable in
119111
let shape_partition = mapping.shapes in
120112
let get_index map t =
@@ -130,16 +122,13 @@ end = struct
130122
let var_system =
131123
let nb_atom = nb_vars in
132124
let assoc_type = Array.make nb_atom Type.dummy in
133-
Type.Map.iter (fun k i ->
134-
assert (if i < nb_non_tuple then Type.is_non_tuple_var k
135-
else not (Type.is_non_tuple_var k));
136-
assoc_type.(i) <- k) vars ;
125+
Type.Map.iter (fun k i -> assoc_type.(i) <- k) vars ;
137126
let nb_non_var = 0 in
138127
let system =
139128
List.map (add_problem (get_index vars) nb_atom) problems
140129
|> Array.of_list
141130
in
142-
{ nb_atom ; assoc_type ; nb_non_var; nb_non_tuple ; system }
131+
{ nb_atom ; assoc_type ; nb_non_var ; system }
143132
in
144133

145134
let gen_shape_system nb_frees types_map =
@@ -154,7 +143,7 @@ end = struct
154143
(get_index_shape vars types_map nb_frees) nb_atom) problems
155144
|> Array.of_list
156145
in
157-
{ nb_atom ; assoc_type ; nb_non_var; nb_non_tuple ; system }
146+
{ nb_atom ; assoc_type ; nb_non_var ; system }
158147
in
159148
let shape_systems = List.map
160149
(fun (n, tm) -> gen_shape_system n tm)
@@ -231,45 +220,32 @@ end = struct
231220
in
232221
aux env Bitv.empty (Array.length solutions - 1)
233222

234-
let iterate_var_subsets_acu system solutions bitvars_cover =
223+
let iterate_var_subsets_acu _system solutions _bitvars_cover =
235224
(* TODO: this could be faster because we only deal with partial, therefore, we don't need to
236225
merge anything in the quasi solved. *)
237-
let mask = Bitv.all_until (system.System.nb_non_tuple - 1) in
238-
let non_tuples_sols, pure_sols =
239-
List.combine (Array.to_list bitvars_cover) (Array.to_list solutions)
240-
|> List.partition (fun (b, _) -> not Bitv.(is_empty (b && mask)))
241-
in
242226
let pure_var_env =
243-
match pure_sols with
244-
| [] -> None
245-
| [ _, env ] -> Some env
246-
| (_, hd) :: tl -> Some (List.fold_left (fun acc (_, env) -> merge_env acc env) hd tl)
227+
match Array.length solutions with
228+
| 0 -> None
229+
| _ ->
230+
let env = ref solutions.(0) in
231+
for i = 1 to Array.length solutions - 1 do
232+
env := merge_env !env solutions.(i)
233+
done;
234+
Some !env
247235
in
248-
fun env shape_coverage k ->
249-
let rec aux env coverage = function
250-
| [] -> (
251-
let merged_env = match pure_var_env with None -> env | Some pure_var_env -> merge_env env pure_var_env in
252-
let final_env, stack = Env.commit merged_env in
253-
match
254-
let* _ =
255-
if List.is_empty stack then Done
256-
else Syntactic.process_stack final_env (Stack.of_list stack)
257-
in
258-
Syntactic.occur_check final_env
259-
with
260-
| Syntactic.FailUnif _ | FailedOccurCheck _ -> ()
261-
| Done ->
262-
k final_env )
263-
| (cover, var_env):: t ->
264-
aux env coverage t;
265-
if Bitv.(is_empty (coverage && cover && mask)) then
266-
match merge_env env var_env with
267-
| env ->
268-
let coverage = Bitv.(coverage || cover) in
269-
aux env coverage t
270-
| exception Bail -> ()
271-
in
272-
aux env shape_coverage non_tuples_sols
236+
fun env _shape_coverage k ->
237+
let merged_env = match pure_var_env with None -> env | Some pure_var_env -> merge_env env pure_var_env in
238+
let final_env, stack = Env.commit merged_env in
239+
match
240+
let* _ =
241+
if List.is_empty stack then Done
242+
else Syntactic.process_stack final_env (Stack.of_list stack)
243+
in
244+
Syntactic.occur_check final_env
245+
with
246+
| Syntactic.FailUnif _ | FailedOccurCheck _ -> ()
247+
| Done ->
248+
k final_env
273249

274250
let iterate_var_subsets_ac system solutions bitvars_cover env shape_coverage k =
275251
let mask = Bitv.all_until (system.System.nb_atom - 1) in
@@ -443,7 +419,7 @@ let solve_systems env (var_system, shape_systems) =
443419
in
444420

445421
let var_sols =
446-
System.solve (cut var_system.nb_non_tuple) var_system
422+
System.solve (fun _ -> false) var_system
447423
|> Iter.filter (fun sol ->
448424
exists (fun x -> x > 0) sol 0 var_system.nb_atom)
449425
(* TODO: Maybe a bug in the solver.
@@ -463,7 +439,7 @@ let solve_systems env (var_system, shape_systems) =
463439
let shapes_sols = List.map (fun (system: System.t) ->
464440
assert (system.nb_non_var > 0);
465441
( system,
466-
System.solve (cut (system.nb_non_var + system.nb_non_tuple)) system
442+
System.solve (cut (system.nb_non_var)) system
467443
|> Iter.filter (fun sol ->
468444
exists (fun x -> x > 0) sol 0 system.nb_non_var)
469445
)
@@ -478,4 +454,3 @@ let solve env problems =
478454
Logs.debug (fun m -> m "Solving AC system: @,@[%a@]" (CCList.pp ACTerm.pp_problem) problems);
479455
make_systems env problems
480456
|> solve_systems env
481-

test/unit_tests/test_unification.ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,13 @@ let slow_tests = [
110110

111111
let marked_var_pos_tests = [
112112
">a. 'a * int", "int * float * float";
113-
"*a. 'a * int", " (int -> string) * int";
114113
">a. 'a * int", " (int -> string) * int * float";
115114
]
116115

117116
let marked_var_neg_tests = [
118-
"*a. 'a * int", "int * float * float";
119117
">a. 'a * int", " (int -> string) * int";
120118
]
121-
119+
122120

123121
let tests =
124122
let make_test speed res (str1, str2) =

0 commit comments

Comments
 (0)