From 2bb69a506407323fe02c6dfa6e8368fa2539a7f1 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 2 Aug 2021 14:14:39 +0300 Subject: [PATCH 1/6] Implement Set stdlib --- CHANGELOG.md | 1 + priv/stdlib/Set.aes | 51 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 priv/stdlib/Set.aes diff --git a/CHANGELOG.md b/CHANGELOG.md index ea32d45..1532fb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- `Set` stdlib ### Changed ### Removed diff --git a/priv/stdlib/Set.aes b/priv/stdlib/Set.aes new file mode 100644 index 0000000..a1c3984 --- /dev/null +++ b/priv/stdlib/Set.aes @@ -0,0 +1,51 @@ +include "List.aes" +include "Option.aes" +include "Pair.aes" + +namespace Set = + record set('a) = { to_map : map('a, unit) } + + function new() : set('a) = + { to_map = {} } + + function member(e : 'a, s : set('a)) : bool = + Map.member(e, s.to_map) + + function insert(e : 'a, s : set('a)) : set('a) = + { to_map = s.to_map{[e] = ()} } + + function delete(e : 'a, s : set('a)) : set('a) = + { to_map = Map.delete(e, s.to_map) } + + function size(s : set('a)) : int = + Map.size(s.to_map) + + function to_list(s : set('a)) : list('a) = + List.map(Pair.fst, Map.to_list(s.to_map)) + + function from_list(l : list('a)) : set('a) = + { to_map = Map.from_list(List.map((x) => (x, ()), l)) } + + function filter(p : 'a => bool, s : set('a)) : set('a) = + from_list(List.filter(p, to_list(s))) + + function fold(f : ('a, 'b) => 'b, acc : 'b, l : set('a)) : 'b = + List.foldr(f, acc, to_list(l)) + + function subtract(s1 : set('a), s2 : set('a)) : set('a) = + filter((x) => !member(x, s2), s1) + + function intersection(s1 : set('a), s2 : set('a)) : set('a) = + filter((x) => member(x, s2), s1) + + function intersection_list(sets : list(set('a))) : set('a) = + List.foldr( + intersection, + Option.default(new(), List.first(sets)), + Option.default([], List.tail(sets))) + + function union(s1 : set('a), s2 : set('a)) : set('a) = + from_list(to_list(s1) ++ to_list(s2)) + + function union_list(sets : list(set('a))) : set('a) = + List.foldr(union, new(), sets) -- 2.30.2 From a94abab8ebf0b3c4233c1d3b74fb67c5fc0e2396 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 2 Aug 2021 16:03:17 +0300 Subject: [PATCH 2/6] Rename an argument of the function Set.fold --- priv/stdlib/Set.aes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/stdlib/Set.aes b/priv/stdlib/Set.aes index a1c3984..794f93a 100644 --- a/priv/stdlib/Set.aes +++ b/priv/stdlib/Set.aes @@ -29,7 +29,7 @@ namespace Set = function filter(p : 'a => bool, s : set('a)) : set('a) = from_list(List.filter(p, to_list(s))) - function fold(f : ('a, 'b) => 'b, acc : 'b, l : set('a)) : 'b = + function fold(f : ('a, 'b) => 'b, acc : 'b, s : set('a)) : 'b = List.foldr(f, acc, to_list(l)) function subtract(s1 : set('a), s2 : set('a)) : set('a) = -- 2.30.2 From 416999e19a541d421e2bc26c20ee6f44cc55eee6 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 2 Aug 2021 16:03:37 +0300 Subject: [PATCH 3/6] Add docs for Set stdlib --- docs/sophia_stdlib.md | 123 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/docs/sophia_stdlib.md b/docs/sophia_stdlib.md index a0106fe..2c19b42 100644 --- a/docs/sophia_stdlib.md +++ b/docs/sophia_stdlib.md @@ -39,6 +39,7 @@ include "List.aes" - [Triple](#Triple) - [BLS12_381](#BLS12_381) - [Frac](#Frac) +- [Set](#Set) # Builtin namespaces @@ -2264,3 +2265,125 @@ accept arbitrary `frac`s from the surface you should report it as a If you expect getting calls with malformed `frac`s in your contract, you should use this function to verify the input. + +## Set + +### Types + +``` +record set('a) = { to_map : map('a, unit) } +``` + +### Functions + +#### new + +``` +Set.new() : set('a) +``` + +Returns an empty set + +#### member + +``` +member(e : 'a, s : set('a)) : bool +``` + +Checks if the element is present in the Set + +#### insert + +``` +insert(e : 'a, s : set('a)) : set('a) +``` + +Inserts the element in the set + +#### delete + +``` +Set.delete(e : 'a, s : set('a)) : set('a) +``` + +Removes the element from the set + +#### size + +``` +size(s : set('a)) : int +``` + +Returns the number of elements in the set + +#### to_list + +``` +Set.to_list(s : set('a)) : list('a) +``` + +Returns a list containing the elements of the set + +#### from_list + +``` +Set.from_list(l : list('a)) : set('a) +``` + +Turns a list into a set + +#### filter + +``` +Set.filter(p : 'a => bool, s : set('a)) : set('a) +``` + +Filters out elements of `s` that fulfill predicate `p` + +#### fold + +``` +Set.fold(f : ('a, 'b) => 'b, acc : 'b, s : set('a)) : 'b +``` + +Folds the function `f` over every element in the set `s` and returns the final value of the accumulator. + +#### subtract + +``` +Set.subtract(s1 : set('a), s2 : set('a)) : set('a) +``` + +Returns the elements of `s1` that are not members of `s2` + +#### intersection + +``` +Set.intersection(s1 : set('a), s2 : set('a)) : set('a) +``` + +Returns the intersection of the two sets `s1` and `s2` + +#### intersection_list + +``` +Set.intersection_list(sets : list(set('a))) : set('a) +``` + +Returns the intersection of all the sets in the given list + +#### union + +``` +Set.union(s1 : set('a), s2 : set('a)) : set('a) +``` + +Returns the union of the two sets `s1` and `s2` + +#### union_list + +``` +Set.union_list(sets : list(set('a))) : set('a) +``` + +Returns the union of all the sets in the given list -- 2.30.2 From 588684ba16cb8e6bc33b30f7fcd54f184ff02285 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 2 Aug 2021 16:25:45 +0300 Subject: [PATCH 4/6] Correct the usage of articles in the docs --- docs/sophia_stdlib.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/sophia_stdlib.md b/docs/sophia_stdlib.md index 2c19b42..17157dc 100644 --- a/docs/sophia_stdlib.md +++ b/docs/sophia_stdlib.md @@ -2290,7 +2290,7 @@ Returns an empty set member(e : 'a, s : set('a)) : bool ``` -Checks if the element is present in the Set +Checks if the element `e` is present in the set `s` #### insert @@ -2298,7 +2298,7 @@ Checks if the element is present in the Set insert(e : 'a, s : set('a)) : set('a) ``` -Inserts the element in the set +Inserts the element `e` in the set `s` #### delete @@ -2306,7 +2306,7 @@ Inserts the element in the set Set.delete(e : 'a, s : set('a)) : set('a) ``` -Removes the element from the set +Removes the element `e` from the set `s` #### size @@ -2314,7 +2314,7 @@ Removes the element from the set size(s : set('a)) : int ``` -Returns the number of elements in the set +Returns the number of elements in the set `s` #### to_list @@ -2322,7 +2322,7 @@ Returns the number of elements in the set Set.to_list(s : set('a)) : list('a) ``` -Returns a list containing the elements of the set +Returns a list containing the elements of the set `s` #### from_list @@ -2330,7 +2330,7 @@ Returns a list containing the elements of the set Set.from_list(l : list('a)) : set('a) ``` -Turns a list into a set +Turns the list `l` into a set #### filter @@ -2346,7 +2346,7 @@ Filters out elements of `s` that fulfill predicate `p` Set.fold(f : ('a, 'b) => 'b, acc : 'b, s : set('a)) : 'b ``` -Folds the function `f` over every element in the set `s` and returns the final value of the accumulator. +Folds the function `f` over every element in the set `s` and returns the final value of the accumulator `acc`. #### subtract -- 2.30.2 From ed1c74cdcffb4dbe0bf532a286648043289a728f Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 2 Aug 2021 17:01:30 +0300 Subject: [PATCH 5/6] Fix bug --- priv/stdlib/Set.aes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/priv/stdlib/Set.aes b/priv/stdlib/Set.aes index 794f93a..daec288 100644 --- a/priv/stdlib/Set.aes +++ b/priv/stdlib/Set.aes @@ -25,12 +25,12 @@ namespace Set = function from_list(l : list('a)) : set('a) = { to_map = Map.from_list(List.map((x) => (x, ()), l)) } - + function filter(p : 'a => bool, s : set('a)) : set('a) = from_list(List.filter(p, to_list(s))) function fold(f : ('a, 'b) => 'b, acc : 'b, s : set('a)) : 'b = - List.foldr(f, acc, to_list(l)) + List.foldr(f, acc, to_list(s)) function subtract(s1 : set('a), s2 : set('a)) : set('a) = filter((x) => !member(x, s2), s1) -- 2.30.2 From 028b12ddc6c6a478207744057b6817b4abdfe0b2 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Wed, 4 Aug 2021 13:56:51 +0300 Subject: [PATCH 6/6] Fix the link to Set stdlib section --- docs/sophia_stdlib.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sophia_stdlib.md b/docs/sophia_stdlib.md index 17157dc..4503d95 100644 --- a/docs/sophia_stdlib.md +++ b/docs/sophia_stdlib.md @@ -39,7 +39,7 @@ include "List.aes" - [Triple](#Triple) - [BLS12_381](#BLS12_381) - [Frac](#Frac) -- [Set](#Set) +- [Set](#set-stdlib) # Builtin namespaces @@ -2266,7 +2266,7 @@ accept arbitrary `frac`s from the surface you should report it as a If you expect getting calls with malformed `frac`s in your contract, you should use this function to verify the input. -## Set +## Set ### Types -- 2.30.2