A   set   is a collection (container) of certain values,
without any particular order, and no repeated values.

It corresponds with a finite set in mathematics.

A set can be implemented as an associative array (partial mapping)
in which the value of each key-value pair is ignored.

Given a set S, the power set (or powerset) of S, written P(S), or 2S, is the set of all subsets of S.



Task

By using a library or built-in set type, or by defining a set type with necessary operations, write a function with a set S as input that yields the power set 2S of S.



For example, the power set of     {1,2,3,4}     is

 {{}, {1}, {2}, {1,2}, {3}, {1,3}, {2,3}, {1,2,3}, {4}, {1,4}, {2,4}, {1,2,4}, {3,4}, {1,3,4}, {2,3,4}, {1,2,3,4}}.
For a set which contains n elements, the corresponding power set has 2n elements, including the edge cases of empty set.


The power set of the empty set is the set which contains itself (20 = 1):


 





P




{\displaystyle {\mathcal {P}}}

(



∅


{\displaystyle \varnothing }

) = { 



∅


{\displaystyle \varnothing }

 }

And the power set of the set which contains only the empty set, has two subsets, the empty set and the set which contains the empty set (21 = 2):


 





P




{\displaystyle {\mathcal {P}}}

({



∅


{\displaystyle \varnothing }

}) = { 



∅


{\displaystyle \varnothing }

, { 



∅


{\displaystyle \varnothing }

 } }


Extra credit:  Demonstrate that your language supports these last two powersets.




/*REXX program  displays a  power set;  items may be  anything  (but can't have blanks).*/
parse arg S                                      /*allow the user specify optional set. */
if S=''  then S= 'one two three four'            /*Not specified?  Then use the default.*/
@= '{}'                                          /*start process with a null power set. */
N= words(S);     do chunk=1  for N               /*traipse through the items in the set.*/
                 @=@  combN(N, chunk)            /*take  N  items, a  CHUNK  at a time. */
                 end    /*chunk*/
w= length(2**N)                                  /*the number of items in the power set.*/
                 do k=1  for words(@)            /* [↓]  show combinations,  1 per line.*/
                 say right(k, w)     word(@, k)  /*display a single combination to term.*/
                 end    /*k*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
combN:  procedure expose S;  parse arg x,y;      base= x + 1;             bbase= base - y
        !.= 0
                         do p=1  for y;          !.p= p
                         end      /*p*/
        $=                                                         /* [↓] build powerset*/
                         do j=1;                 L=
                            do d=1  for y;       L= L','word(S, !.d)
                            end   /*d*/
                         $= $  '{'strip(L, "L", ',')"}";                  !.y= !.y + 1
                         if !.y==base  then  if .combU(y - 1)  then leave
                         end      /*j*/
        return strip($)                          /*return with a partial power set chunk*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.combU: procedure expose !. y bbase;        parse arg d;           if d==0  then return 1
        p= !.d
                  do u=d  to y;   !.u= p + 1;     if !.u==bbase+u  then return .combU(u-1)
                  p= !.u                                           /*             ↑     */
                  end   /*u*/                                      /*recurse──►───┘     */
        return 0