Compare commits

..

1 Commits

Author SHA1 Message Date
radrow 1a14602f36 Upgrade sorting function 2021-02-09 14:18:42 +01:00
3 changed files with 79 additions and 36 deletions
+9 -1
View File
@@ -975,12 +975,20 @@ List.unzip(l : list('a * 'b)) : list('a) * list('b)
Opposite to the `zip` operation. Takes a list of pairs and returns pair of lists with respective elements on same indices. Opposite to the `zip` operation. Takes a list of pairs and returns pair of lists with respective elements on same indices.
### merge
```
List.merge(lesser_cmp : ('a, 'a) => bool, l1 : list('a), l2 : list('a)) : list('a)
```
Merges two sorted lists into a single sorted list. O(length(l1) + length(l2))
### sort ### sort
``` ```
List.sort(lesser_cmp : ('a, 'a) => bool, l : list('a)) : list('a) List.sort(lesser_cmp : ('a, 'a) => bool, l : list('a)) : list('a)
``` ```
Sorts a list using given comparator. `lesser_cmp(x, y)` should return `true` iff `x < y`. If `lesser_cmp` is not transitive or there exists an element `x` such that `lesser_cmp(x, x)` or there exists a pair of elements `x` and `y` such that `lesser_cmp(x, y) && lesser_cmp(y, x)` then the result is undefined. Currently O(n^2). Sorts a list using given comparator. `lesser_cmp(x, y)` should return `true` iff `x < y`. If `lesser_cmp` is not transitive or there exists an element `x` such that `lesser_cmp(x, x)` or there exists a pair of elements `x` and `y` such that `lesser_cmp(x, y) && lesser_cmp(y, x)` then the result is undefined. O(length(l) * log_2(length(l))).
### intersperse ### intersperse
+61 -5
View File
@@ -227,11 +227,67 @@ namespace List =
(left, right)::t => unzip_(t, left::acc_l, right::acc_r) (left, right)::t => unzip_(t, left::acc_l, right::acc_r)
// TODO: Improve? /** Merges two sorted lists using `lt` comparator
function sort(lesser_cmp : ('a, 'a) => bool, l : list('a)) : list('a) = switch(l) */
[] => [] function
h::t => switch (partition((x) => lesser_cmp(x, h), t)) merge : (('a, 'a) => bool, list('a), list('a)) => list('a)
(lesser, bigger) => sort(lesser_cmp, lesser) ++ h::sort(lesser_cmp, bigger) merge(lt, x::xs, y::ys) =
if(lt(x, y)) x::merge(lt, xs, y::ys)
else y::merge(lt, x::xs, ys)
merge(_, [], ys) = ys
merge(_, xs, []) = xs
/** Mergesort inspired by
* https://hackage.haskell.org/package/base-4.14.1.0/docs/src/Data.OldList.html#sort
*/
function
sort : (('a, 'a) => bool, list('a)) => list('a)
sort(_, []) = []
sort(lt, l) =
merge_all(lt, monotonic_subs(lt, l))
/** Splits list into compound increasing sublists
*/
private function
monotonic_subs : (('a, 'a) => bool, list('a)) => list(list('a))
monotonic_subs(lt, x::y::rest) =
if(lt(y, x)) desc(lt, y, [x], rest)
else asc(lt, y, [x], rest)
monotonic_subs(_, l) = [l]
/** Extracts the longest descending prefix and proceeds with monotonic split
*/
private function
desc : (('a, 'a) => bool, 'a, list('a), list('a)) => list(list('a))
desc(lt, x, acc, h::t) =
if(lt(x, h)) (x::acc) :: monotonic_subs(lt, h::t)
else desc(lt, h, x::acc, t)
desc(_, x, acc, []) = [x::acc]
/** Extracts the longest ascending prefix and proceeds with monotonic split
*/
private function
asc : (('a, 'a) => bool, 'a, list('a), list('a)) => list(list('a))
asc(lt, x, acc, h::t) =
if(lt(h, x)) List.reverse(x::acc) :: monotonic_subs(lt, h::t)
else asc(lt, h, x::acc, t)
asc(_, x, acc, []) = [List.reverse(x::acc)]
/** Merges list of sorted lists
*/
private function
merge_all : (('a, 'a) => bool, list(list('a))) => list('a)
merge_all(_, [part]) = part
merge_all(lt, parts) = merge_all(lt, merge_pairs(lt, parts))
/** Single round of `merge_all` pairs of lists in a list of list
*/
private function
merge_pairs : (('a, 'a) => bool, list(list('a))) => list(list('a))
merge_pairs(lt, x::y::rest) = merge(lt, x, y) :: merge_pairs(lt, rest)
merge_pairs(_, l) = l
/** Puts `delim` between every two members of the list /** Puts `delim` between every two members of the list
*/ */
+9 -30
View File
@@ -1557,15 +1557,6 @@ free_vars(L) when is_list(L) ->
[V || Elem <- L, [V || Elem <- L,
V <- free_vars(Elem)]. V <- free_vars(Elem)].
next_count() ->
V = case get(counter) of
undefined ->
0;
X -> X
end,
put(counter, V + 1),
V.
%% Clean up all the ets tables (in case of an exception) %% Clean up all the ets tables (in case of an exception)
ets_tables() -> ets_tables() ->
@@ -1611,18 +1602,6 @@ ets_tab2list(Name) ->
TabId = ets_tabid(Name), TabId = ets_tabid(Name),
ets:tab2list(TabId). ets:tab2list(TabId).
ets_insert_ordered(_, []) -> true;
ets_insert_ordered(Name, [H|T]) ->
ets_insert_ordered(Name, H),
ets_insert_ordered(Name, T);
ets_insert_ordered(Name, Object) ->
Count = next_count(),
TabId = ets_tabid(Name),
ets:insert(TabId, {Count, Object}).
ets_tab2list_ordered(Name) ->
[E || {_, E} <- ets_tab2list(Name)].
%% Options %% Options
create_options(Options) -> create_options(Options) ->
@@ -1658,17 +1637,17 @@ destroy_and_report_unsolved_constraints(Env) ->
%% -- Named argument constraints -- %% -- Named argument constraints --
create_named_argument_constraints() -> create_named_argument_constraints() ->
ets_new(named_argument_constraints, [ordered_set]). ets_new(named_argument_constraints, [bag]).
destroy_named_argument_constraints() -> destroy_named_argument_constraints() ->
ets_delete(named_argument_constraints). ets_delete(named_argument_constraints).
get_named_argument_constraints() -> get_named_argument_constraints() ->
ets_tab2list_ordered(named_argument_constraints). ets_tab2list(named_argument_constraints).
-spec add_named_argument_constraint(named_argument_constraint()) -> ok. -spec add_named_argument_constraint(named_argument_constraint()) -> ok.
add_named_argument_constraint(Constraint) -> add_named_argument_constraint(Constraint) ->
ets_insert_ordered(named_argument_constraints, Constraint), ets_insert(named_argument_constraints, Constraint),
ok. ok.
solve_named_argument_constraints(Env) -> solve_named_argument_constraints(Env) ->
@@ -1707,14 +1686,14 @@ destroy_and_report_unsolved_named_argument_constraints(Env) ->
| {add_bytes, aeso_syntax:ann(), concat | split, utype(), utype(), utype()}. | {add_bytes, aeso_syntax:ann(), concat | split, utype(), utype(), utype()}.
create_bytes_constraints() -> create_bytes_constraints() ->
ets_new(bytes_constraints, [ordered_set]). ets_new(bytes_constraints, [bag]).
get_bytes_constraints() -> get_bytes_constraints() ->
ets_tab2list_ordered(bytes_constraints). ets_tab2list(bytes_constraints).
-spec add_bytes_constraint(byte_constraint()) -> true. -spec add_bytes_constraint(byte_constraint()) -> true.
add_bytes_constraint(Constraint) -> add_bytes_constraint(Constraint) ->
ets_insert_ordered(bytes_constraints, Constraint). ets_insert(bytes_constraints, Constraint).
solve_bytes_constraints(Env) -> solve_bytes_constraints(Env) ->
[ solve_bytes_constraint(Env, C) || C <- get_bytes_constraints() ], [ solve_bytes_constraint(Env, C) || C <- get_bytes_constraints() ],
@@ -1768,18 +1747,18 @@ check_bytes_constraint(Env, {add_bytes, Ann, Fun, A0, B0, C0}) ->
create_field_constraints() -> create_field_constraints() ->
%% A relation from uvars to constraints %% A relation from uvars to constraints
ets_new(field_constraints, [ordered_set]). ets_new(field_constraints, [bag]).
destroy_field_constraints() -> destroy_field_constraints() ->
ets_delete(field_constraints). ets_delete(field_constraints).
-spec constrain([field_constraint()]) -> true. -spec constrain([field_constraint()]) -> true.
constrain(FieldConstraints) -> constrain(FieldConstraints) ->
ets_insert_ordered(field_constraints, FieldConstraints). ets_insert(field_constraints, FieldConstraints).
-spec get_field_constraints() -> [field_constraint()]. -spec get_field_constraints() -> [field_constraint()].
get_field_constraints() -> get_field_constraints() ->
ets_tab2list_ordered(field_constraints). ets_tab2list(field_constraints).
solve_field_constraints(Env) -> solve_field_constraints(Env) ->
FieldCs = FieldCs =