From 222d88511a3e7e7869d90a63e4c89512228776db Mon Sep 17 00:00:00 2001 From: yabwon Date: Mon, 30 Nov 2020 14:30:12 +0100 Subject: [PATCH] DFA, version 0.3 DFA, version 0.3 -documentation modified, dfa.md file added --- README.md | 5 +- packages/README.md | 6 +- packages/SHA256_for_packages.txt | 3 + packages/dfa.md | 1150 ++++++++++++++++++++++++++++++ packages/dfa.zip | Bin 30177 -> 37349 bytes 5 files changed, 1160 insertions(+), 4 deletions(-) create mode 100644 packages/dfa.md diff --git a/README.md b/README.md index 49f0c84..bdfd9ef 100644 --- a/README.md +++ b/README.md @@ -110,10 +110,11 @@ SHA256 digest for MacroCore: A23C29529F3CE7D0C8BEE9545C5D22D5B5594907547374A5135 [Documentation for MacroCore](https://core.sasjs.io "Documentation for MacroCore") -- **DFA** (Dynamic Function Arrays)\[0.2\], contains set of macros and FCMP functions which implement: a dynamically allocated array, a stack, a fifo queue, an ordered stack, and a priority queue, run `%helpPackage(DFA,createDFArray)` to find examples. +- **DFA** (Dynamic Function Arrays)\[0.3\], contains set of macros and FCMP functions which implement: a dynamically allocated array, a stack, a fifo queue, an ordered stack, and a priority queue, run `%helpPackage(DFA,createDFArray)` to find examples. -SHA256 digest for DFA: C795736F55B3C6EFBEF2E82362694EB017D37C54E6AEC3EB0F6F813F69F54B5F +SHA256 digest for DFA: 1FC8D030D576C33F1B5DEB27E17534946209BC148D57A1357CA025ED1E69AEB8 +[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA") - **macroArray**\[0.7\], implementation of an array concept in a macrolanguage, e.g. ``` diff --git a/packages/README.md b/packages/README.md index 4c3860f..99d0a2b 100644 --- a/packages/README.md +++ b/packages/README.md @@ -32,7 +32,7 @@ SHA256 digest for MacroCore: A23C29529F3CE7D0C8BEE9545C5D22D5B5594907547374A5135 --- -- **DFA** (Dynamic Function Arrays)\[0.2\], contains set of macros and FCMP functions which implement: a dynamically allocated array, a stack, a fifo queue, an ordered stack, and a priority queue, run `%helpPackage(DFA,createDFArray)` to find examples. +- **DFA** (Dynamic Function Arrays)\[0.3\], contains set of macros and FCMP functions which implement: a dynamically allocated array, a stack, a fifo queue, an ordered stack, and a priority queue, run `%helpPackage(DFA,createDFArray)` to find examples. ``` %createDFArray(ArrDynamic, resizefactor=17); @@ -59,7 +59,9 @@ data _null_; end; run; ``` -SHA256 digest for DFA: C795736F55B3C6EFBEF2E82362694EB017D37C54E6AEC3EB0F6F813F69F54B5F +SHA256 digest for DFA: 1FC8D030D576C33F1B5DEB27E17534946209BC148D57A1357CA025ED1E69AEB8 + +[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA") --- diff --git a/packages/SHA256_for_packages.txt b/packages/SHA256_for_packages.txt index a77bb0e..eac0768 100644 --- a/packages/SHA256_for_packages.txt +++ b/packages/SHA256_for_packages.txt @@ -1,3 +1,6 @@ +/* 20201130 */ +DFA: 1FC8D030D576C33F1B5DEB27E17534946209BC148D57A1357CA025ED1E69AEB8 + /* 20201115 */ BasePlus: B25A3992B6FCD13528BEE462B3ADD0F5A6D15E607A6DABAA984CA66B0AD69415 DFA: C795736F55B3C6EFBEF2E82362694EB017D37C54E6AEC3EB0F6F813F69F54B5F diff --git a/packages/dfa.md b/packages/dfa.md new file mode 100644 index 0000000..b01f9dd --- /dev/null +++ b/packages/dfa.md @@ -0,0 +1,1150 @@ +- [The DFA package](#dfa-package) +- [Content description](#content-description) + * [`%createDFArray()` macro](#createdfarray-macro) + * [`%createDHArray()` macro](#createdharray-macro) + * [`%createDHFifo()` macro](#createdhfifo-macro) + * [`%createDHOrdStack()` macro](#createdhordstack-macro) + * [`%createDHPrtQueue()` macro](#createdhprtqueue-macro) + * [`%createDHStack()` macro](#createdhstack-macro) + * [`generateArrays` exec](#createdhprtqueue-exec) + * [`generateArrays` clean](#createdhprtqueue-clean) + + * [License](#license) + +--- + +# The DFA package [ver. 0.3] ############################################### + +The **DFA** (a.k.a. *Dynamic Function Array*) package implements: + - dynamic numeric and character arrays, + - dynamic stacks (filo), + - dynamic queues (fifo), + - dynamic ordered stacks, + - priority queues. + +The package provides a set of *macros*, +which allows to *generate* `call routines` +simulating data structures mentioned above. + +Few exemplary functions are also generated. +See particular macro help for further details. + +--- + +Package contains: + 1. macro createdfarray + 2. macro createdharray + 3. macro createdhfifo + 4. macro createdhordstack + 5. macro createdhprtqueue + 6. macro createdhstack + 7. exec generatearrays + 8. clean generatearrays + +*SAS package generated by generatePackage, version 20201115* + +The SHA256 hash digest for package BasePlus: +`1FC8D030D576C33F1B5DEB27E17534946209BC148D57A1357CA025ED1E69AEB8` + +--- +# Content description ############################################################################################ + +## >>> `%createDFArray()` macro: <<< ####################### + +The `%createDFArray()` macro allows to generate +a `dynamic function array` which is a FCMP based +approach to create *dynamically* allocated **numeric** +array with possible values searching and `WHICHN()` +function emulation. + +*Note:* Arrays provided by the macro are *one dimensional* arrays. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDFArray( + arrayName + <,debug=0> + <,simple=0> + <,resizeFactor=0> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrayName` - *Required*, creates a FCMP call subroutine which is also + an array name. In the data step it is used in form of + a call subroutine, e.g. `call arrayName("Allocate", -3, 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `simple=` - *Optional*, the default value is `0`. A *simple* dynamic + function array is one which is not searchable and does not + allows to use `which()` functionality. + If set to `1` then it disables `SEARCH` and `WHICH` functionality. + See examples below for details. + +* `resizeFactor=` - *Optional*, the default value is `0`. If set to `0` then + the dynamic array size is not changeable(mutable) after initial + size allocation. + If set not to `0` then arrays dimensions are mutable after allocation, + i.e. even if an array is allocated for ten elements (like `A[1:10]`) + you can do `A[17] = 42` and it will resize itself dynamically. + *Hint!* Set to, e.g. 4999, for faster allocation process. + See examples below for details. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &arrayName.(IO, position, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `R`, `Return` - to get the data from an array, + - `I`, `Input` - to insert the data into an array, + - `+`, `Add` - to increment given position by a value, + - `C`, `Clear` - to reduce an array to a single empty cell, + - `A`, `Allocate` - to reserve space for array width and set starting values, + - `D`, `Dimension` - to return minimal and maximal index of an array, + - `F`, `Find`, `Exist` - to find out if a given value exist in an array, + - `W`, `Which` - to search the first position of data in array, `WHICHN()` function emulator, + - `Sum` - to return the sum of non-missing elements of an array, + - `Nonmiss` - to return the number of non-missing elements of an array, + - `Avg`, `Mean`, `Average` - to return the average of non-missing elements of an array, + - `Min`, `Minimum` - to return the minimum of non-missing elements of an array, + - `Max`, `Maximum` - to return the maximum of non-missing elements of an array. + +2. `position` - is a *numeric* argument and depends on the `IO` value. + Behaves in the following way: + - for `O`, `Output`, `R`, `Return`/ `I`, `Input`/ `+`, `Add` it takes + an arrays index from (into) which data is get (put), + - for `C`, `Clear` is ignored, + - for `A`, `Allocate` sets the value of the minposition, i.e. the minimal position of the array index, + - for `D`, `Dimension` it returns value of the minposition, + - for `Sum`, `Nonmiss`, `Avg`, `Mean`, `Average`, `Min`, `Minimum`, `Max`, and `Maximum` is ignored, + - for `F`, `Find`, `Exist` it returns number of occurrences of a given value in an array, + - for `W`, `Which` it returns position the first occurrence of a given value in an array. + +.3 `value` - is a *numeric* argument and depends on the `IO` value. + Behaves in the following way: + - for `O`, `Output`, `R`, `Return` it holds value retrieved from an array on a given position, + - for `I`, `Input` it holds the value inserted into an array on a given position, + - for `+`, `Add` it holds the value that is used to increment an array value at a given position, + - for `C`, `Clear` is ignored, + - for `A`, `Allocate` it sets the value of the maxposition, i.e. maximal position of the array index, + - for `D`, `Dimension` it returns value of the maxposition + - for `Sum`, `Nonmiss`, `Avg`, `Mean`, `Average`, `Min`, `Minimum`, `Max`, and `Maximum` it returns + the calculated summary value, + - for `F`, `Find`, `Exist`, `W`, `Which` is the value to be searched in an array. + +The `position` and the `value` arguments are **outargs**, i.e. can be changed by the function. + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Searchable, and Immutable array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDFArray(ArrDSI); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example1; + call ArrDSI("Allocate", 1, 10); + L = 0; H = 0; + call ArrDSI("Dim", L, H); + put L= H=; + + * populate array with data ; + do i = L to H; + call ArrDSI("Input", i, i**2); + end; + + * searchability allows to find number of occurrences of value in the array ; + F = .; + call ArrDSI("Find", F, 16); + put "Value 16 occurs " F "times"; + call ArrDSI("Find", F, 17); + put "Value 17 occurs " F "times"; + + * increase value of cell 4 by 1, and verify at WHICH position is 17 (by searchability); + call ArrDSI("+", 4, 1); + call ArrDSI("Which", F, 17); + put "Value 17 occurred for the first time at position " F; + + * get values from the array ; + Value = .; + do i = L to H; + call ArrDSI("Output", i, Value); + put i= Value=; + end; + + * some basic statistics ; + call ArrDSI("Sum", ., STAT); put "sum = " STAT; + call ArrDSI("Avg", ., STAT); put "avg = " STAT; + call ArrDSI("Min", ., STAT); put "min = " STAT; + call ArrDSI("Max", ., STAT); put "max = " STAT; + call ArrDSI("Cnt", ., STAT); put "cnt = " STAT; + + * immutability does _not_ allow to increase dimensions automatically; + * this line returns an error ; + call ArrDSI("Input", 42, -1); + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Searchable, and Mutable array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDFArray(ArrDSM, resizefactor=17); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + call ArrDSM("Allocate", -2, 2); + + do i = -2 to 2; + call ArrDSM("Input", i, 2**i); + end; + + L = .; H = .; + call ArrDSM("Dim", L, H); + put L= H=; + + * mutability allows to increase dimensions automatically + * create index 3 and -3; + call ArrDSM("+", 3, 8); + call ArrDSM("+",-3, 0.125); + call ArrDSM("Dim", L, H); + put L= H=; + + Value = .; + do i = L to H; + call ArrDSM("O", i, Value); + put i= Value=; + end; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Dynamic, non-searchable (a.k.a. SiMPle), and Immutable array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDFArray(ArrDSMPLI, simple=1); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example3; + call ArrDSMPLI("Allocate", -2, 2); + + do i = -2 to 2; + call ArrDSMPLI("Input", i, 2**i); + end; + + * non-searchable array (a.k.a. simple) does not allow ; + * to find number of occurrences of value in the array ; + * and verify what is the first position of a value ; + * this lines return a warning ; + call ArrDSMPLI("Exist", i, 1); + call ArrDSMPLI("Which", i, 1); + run; + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Dynamic, non-searchable (a.k.a. SiMPle), and Mutable array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDFArray(ArrDSMPLM, simple=1, resizefactor=42); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example4; + call ArrDSMPLM("Allocate", 1, 1); + + * mutability allows to increase dimensions automatically ; + do i = -12 to 12; + call ArrDSMPLM("Input", i, i*2); + end; + + * non-searchable array (a.k.a. simple) does not allow ; + * to find number of occurrences of value in the array ; + * and verify what is the first position of a value ; + * this lines return a warning ; + i = .; + call ArrDSMPLM("Exist", i, -24); + put "Exist " i=; + call ArrDSMPLM("Which", i, 24); + put "Which " i=; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `%createDHArray()` macro: <<< ####################### + +The `%createDHArray()` macro allows to generate +a `dynamic hash array` which is a FCMP based approach +to create *dynamically* allocated **numeric** +or **character** array + +*Note:* Arrays provided by the macro are *one dimensional* arrays. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDHArray( + arrayName + <,debug=0> + <,type=8> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrayName` - *Required*, creates a FCMP call subroutine which is also + an array name. In the data step it is used in form of + a call subroutine, e.g. `call arrayName("Allocate", -3, 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `type=` - *Optional*, the default value is `8`. + Indicates what *type* (numeric/character) and *length* + are data portion of generated array. Should be in line + with the LENGTH statement, e.g. `8`, `$ 30`, etc. + Determines if the `value` argument is numeric or character. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &arrayName.(IO, position, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `R`, `Return` - to get the data from an array, + - `I`, `Input` - to insert the data into an array, + - `C`, `Clear` - to reduce an array to a single empty cell, + - `L`, `Low`, `Lower`, `Lbound` - to return minimal position of index, + - `H`, `High`, `Higher`, `Hbound` - to return maximal position of index. + +2. `position` - is a *numeric* argument and depends on the `IO` value. + Behaves in the following way: + - for `O`, `Output`, `R`, `Return`/ `I`, and `Input` it is an array + index from (into) which data is get (put), + - for `C` it is ignored, + - for `L`, `Low`, `Lower`, and `Lbound` it returns the first position of an index, + - for `H`, `High`, `Higher`, and `Hbound` it returns the last position of an index, + - otherwise is not modified. + +3. `value` - is a *numeric* or *character* argument (determined by the `type=`) + and depends on the `IO` value. Behaves in the following way: + - for `O`, `Output`, `R`, and `Return` it holds value retrieved from an array from a given position, + - for `I`, `Input` it holds the value inserted into an array into a given position, + - for `C` is ignored, + - for `L`, `Low`, `Lower`, and `Lbound` returns first value of index, + - for `H`, `High`, `Higher`, and `Hbound` returns last value of index, + - otherwise is not modified. + +The `position` and the `value` arguments are **outargs**, i.e. can be changed by the function. + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Hash-based, and Character array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHArray(ArrDHC, type = $ 12); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + %let zeros = 6; *[to test bigger sizes]; + data Example1; + + t = time(); + do _I_ = -1e&zeros. to 1e&zeros.; + _X_ = put(_I_*10, z12.); + call ArrDHC("Input", _I_, _X_); + end; + t = time() - t; + put t= / _X_= /; + + * get the size info ; + LB = 0; HB = 0; + drop LB HB; + call ArrDHC('Lbound', LB, _X_); + call ArrDHC('Hbound', HB, _X_); + put LB= HB= /; + + t = time(); + do _I_ = HB + 1 to LB - 1 by -1; + call ArrDHC('Output', _I_, _X_); + output; + end; + t = time() - t; + put t= / _X_= /; + + * clear for further reuse ; + call ArrDHC('C', ., ''); + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Hash-based, and Numeric array: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHArray(ArrDHN); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + + do i = -2 to 2; + call ArrDHN("Input", i, 2**i); + end; + + do i = -2 to 2; + call ArrDHN("+", i, -10); + end; + + v = .; + do i = -2 to 2; + call ArrDHN("Output", i, v); + put i= v=; + end; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `%createDHFifo()` macro: <<< ####################### + +The `%createDHFifo()` macro allows to generate +a `dynamic hash fifo` which is a FCMP based approach +to create dynamically allocated numeric or character +"first in first out" [queue](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) + +Interesting reading about implementing a fifo via hash table +can be found in *chapter 10.4* of the: +*"Data Management Solutions Using SAS Hash Table Operations: + A Business Intelligence Case Study"* book +by Paul Dorfman and Don Henderson. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDHFifo( + fifoName + <,debug=0> + <,type=8> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `fifoName` - *Required*, creates a FCMP call subroutine which is also + a fifo name. In the data step it is used in form of + a call subroutine, e.g. `call fifoName("Enqueue", 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `type=` - *Optional*, the default value is `8`. + Indicates what *type* (numeric/character) and *length* + are data portion of generated array. Should be in line + with the LENGTH statement, e.g. `8`, `$ 30`, etc. + Determines if the `value` argument is numeric or character. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &fifoName.(IO, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `D`, `Dequeue`, `R`, `Return` - to get the data from a fifo (and remove it from the fifo) + - `I`, `Input`, `E`, `Enqueue`, and `Insert` - to insert the data into a fifo + - `C`, `Clear` - to reduce a fifo to an empty one + - `P`, `Peek`, `T`, and `Tail` - to peek the data from a fifo (and NOT remove it from the fifo) + - `H`, `Head` - to peek the data from a fifo head (and NOT remove it from the fifo) + - `Sum` - returns sum of nonmissing numeric elements of a stack + - `Avg`, `Mean`, `Average` - returns average of nonmissing numeric elements of a stack + - `Nonmiss`, `Cnt` - returns number of nonmissing elements of a stack + - `Height` - returns height a stack + +2. `value` - is a *numeric* or *character* argument (determined by the `type=`) + and depends on the `IO` value. Behaves in the following way: + - for `O`, `Output`, `D`, `Dequeue`, `R`, `Return` it holds the value popped from the fifo, + - for `I`, `Input`, `E`, `Enqueue`, `Insert` it holds the value to be pushed into the fifo, + - for `C`, `Clear` it is ignored, + - for `P`, `Peek` holds the value peeked from the fifo, + - for `Sum`, `Nonmiss`, `Cnt`, `Avg`, `Mean`, `Average`, and `Height` it returns calculated summary value. + +The `value` argument is **outarg**, i.e. can be changed by the function. + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Hash-based, and Character fifo: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHFifo(FifoDHC, type = $ 12); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + + %let zeros = 6; *[to test bigger sizes]; + data Example1; + + t = time(); drop t; + do _I_ = 1 to 1e&zeros.; + _X_ = put(_I_*10, z12.); + call FifoDHC("Enqueue", _X_); + end; + t = time() - t; + + call FifoDHC("Height", _X_); + put t= / _X_=; + + t = time(); + do _I_ = 1 to 1e&zeros. + 3; + call FifoDHC('Dequeue', _X_); + output; + end; + t = time() - t; + + call FifoDHC("Height", _X_); + put t= / _X_=; + + %* clear for further reuse *; + call FifoDHC('Clear', ''); + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Hash-based, and Numeric fifo: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHFifo(FifoDHN); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + + do _I_ = 1,.,2,.,3,.,4,.,5,.,6; + call FifoDHN("E", _I_); + end; + + call FifoDHN("Sum", _I_); + put "Sum " _I_=; + + call FifoDHN("Avg", _I_); + put "Avg " _I_=; + + call FifoDHN("Cnt", _I_); + put "Cnt " _I_=; + + call FifoDHN("Height", _I_); + put "Height " _I_=; + + call FifoDHN("Tail", _I_); + put "Tail of fifo is " _I_=; + + call FifoDHN("Height", _I_); + put "Height after Tail " _I_=; + + call FifoDHN("Head", _I_); + put "Head of fifo is " _I_=; + + call FifoDHN("Height", _I_); + put "Height after Head" _I_=; + + _X_ = 0; + do _I_ = 1 to _I_; + call FifoDHN('D', _X_); + output; + end; + + call FifoDHN("Height", _I_); + put "Height " _I_=; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `%createDHOrdStack()` macro: <<< ####################### + +The `%createDHOrdStack()` macro allows to generate +a `dynamic ORDERED hash stack` which is a FCMP based approach +to create dynamically allocated numeric or character +*ordered* [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) + +Interesting reading about implementing a stack via hash table +can be found in *chapter 10.4* of the: +*"Data Management Solutions Using SAS Hash Table Operations: + A Business Intelligence Case Study"* book +by Paul Dorfman and Don Henderson. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDHOrdStack( + fifoName + <,debug=0> + <,type=8> + <,order=A> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `stackName` - *Required*, creates a FCMP call subroutine which is also + a stack name. In the data step it is used in form of + a call subroutine, e.g. `call stackName("Push", 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `type=` - *Optional*, the default value is `8`. + Indicates what *type* (numeric/character) and *length* + are data portion of generated array. Should be in line + with the LENGTH statement, e.g. `8`, `$ 30`, etc. + Determines if the `value` argument is numeric or character. + +* `order=` - *Optional*, the default value is `A`. + Indicates a method of ordering of the stack, + allowed values are: `A` for ascending and `D` for descending. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &stackName.(IO, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `Pop`, `G`, `Get`, `R`, `Return` - to get the data from a stack (and remove it from the top), + - `I`, `Input`, `Push`, `Put`, `Insert` - to insert the data into a stack, + - `C`, `Clear` - to reduce a stack to an empty one, + - `P`, `Peek` - to peek the data from a stack (and NOT remove it from the top), + - `Sum` - returns sum of non-missing numeric elements of a stack, + - `Avg`, `Mean`, `Average` - returns average of non-missing numeric elements of a stack, + - `Nonmiss`, `Cnt`, `Nnm` - returns number of non-missing elements of a stack, + - `Height` - returns height a stack, + - `Min`, `Minimum` - returns minimum of non-missing elements of a stack, + - `Max`, `Maximum` - returns maximum of non-missing elements of a stack. + +2. `value` - is a *numeric* or *character* argument (determined by the `type=`) + and depends on the `IO` value. Behaves in the following way: + - for `O`, `Output`, `Pop`, `G`, `Get`, `R`, `Return` it holds a value popped from a stack, + - for `I`, `Input`, `Push`, `Put`, `Insert` it holds a value to be pushed into a stack, + - for `C`, `Clear` it is ignored, + - for `P`, `Peek` it holds a value peeked from a stack, + - for `Sum`, `Nonmiss`, `Cnt`, `Avg`, `Mean`, `Average`, `Height`, `Min`, `Minimum`, `Max`, and `Maximum` + it returns calculated summary value, + +The `value` argument is **outarg**, i.e. can be changed by the function. + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Hash-based, and Character Descending Ordered stack: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHOrdStack(DescStackC, type = $ 12, order=D); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example1; + + do _X_ = "A","B"," ","C","A"," ","B","C"; + call DescStackC("Push", _X_); + end; + + length S $ 12; + call DescStackC('Height', S); + put 'Height ' S; + + do until(strip(S) = "0"); + call DescStackC('Get', _X_); + call DescStackC('Height', S); + put S= _X_=; + output; + end; + + %* clear for further reuse *; + call DescStackC('Clear',''); + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Hash-based, and Numeric Ascending Ordered stack: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHOrdStack(DescStackN, order=A); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + + call missing(Sum, Avg, Min, Max, Cnt, Hgt, Peek); + do _X_ = 1,6,2,.,5,3,4; + call DescStackN("Put", _X_); + call DescStackN('Sum', Sum); + call DescStackN('Avg', Avg); + call DescStackN('Min', Min); + call DescStackN('Max', Max); + call DescStackN('Cnt', Cnt); + call DescStackN('Height', Hgt); + put (_ALL_) (=); + end; + + call DescStackN('Peek', Peek); + put Peek=; + + do _I_ = 1 to Hgt; + call DescStackN('Output', _X_); + keep _X_; + if _X_ > .z then output; + end; + + call DescStackN('Peek', Peek); + put Peek=; + + %* clear for further reuse *; + call DescStackN('Clear',.); + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `%createDHPrtQueue()` macro: <<< ####################### + + +The `%createDHPrtQueue()` macro allows to generate +a `dynamic PRIORITY hash queue` which is a FCMP based approach +to create dynamically allocated numeric or character +[priority queue](https://en.wikipedia.org/wiki/Priority_queue) + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDHPrtQueue( + fifoName + <,debug=0> + <,type=8> + <,newOnTop=+> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `queueName` - *Required*, creates a FCMP call subroutine which is also + a queue name. In the data step it is used in form of + a call subroutine, e.g. `call queueName("Bottom", 1, 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `type=` - *Optional*, the default value is `8`. + Indicates what *type* (numeric/character) and *length* + are data portion of generated array. Should be in line + with the LENGTH statement, e.g. `8`, `$ 30`, etc. + Determines if the `value` argument is numeric or character. + +* `newOnTop=` - *Optional*, the default value is `+`. + Indicates how to keep order in the same priority group, + allowed values are `+` or `-`. Plus(`+`) sets new elements + at the top of the group, minus(`-`) at the bottom. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &queueName.(IO, position, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `D`, `Dequeue`, `R`, `Return` - it pops/gets/outputs the data from the queue head (high priority), + - `B`, `Bottom` - it pops/gets/outputs the data from the queue tail (low priority), + - `I`, `Input`, `E`, `Enqueue`, `Insert` - it push/puts/inserts the data into the queue, + - `C`, `Clear` - it reduces a queue to an empty one, + - `H`, `Head` - it peeks the data from the queue head and NOT removes it, + - `T`, `Tail` - it peeks the data from the queue tail and NOT removes it, + - `Sum` - it returns sum of non-missing *numeric* elements of the queue, + - `Avg`, `Mean`, `Average` - it returns average of non-missing *numeric* elements of the queue, + - `Nonmiss`, `Cnt` - it returns number of non-missing elements of the queue, + - `Height` - it returns height of the queue. + +2. `position` - is a *numeric* argument and depends on the `IO` value. + Behaves in the following way: + - for `O`, `Output`, `D`, `Dequeue`, `R`, `Return` and `B`, `Bottom`, or `H`, `Head`, `T`, `Tail` + it holds a priority level of value popped from the queue, + - for `I`, `Input`, `E`, `Enqueue`, `Insert` it holds a priority level of value to be pushed into the queue, + - for `C` ignored, + - for *numeric* queue and `Sum`, `Nonmiss`, `Cnt`, `Avg`, `Mean`, `Average`, `Height` returns calculated summary value. + +3. `value` - is a *numeric* or *character* argument (determined by the `type=`) + and depends on the `IO` value. Behaves in the following way: + - for `O`, `Output`, `D`, `Dequeue`, `R`, `Return` and `B`, `Bottom` or `H`, `Head`, `T`, `Tail` + it holds a value popped from the queue, + - for `I`, `Input`, `E`, `Enqueue`, `Insert` it holds a value to be pushed into the queue, + - for `C` ignored, + - for *numeric* queue and `Sum`, `Nonmiss`, `Cnt`, `Avg`, `Mean`, `Average`, `Height` returns calculated summary value, + - otherwise does not modify value. + +The `position` and the `value` arguments are **outargs**, i.e. can be changed by the function. + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Hash-based, and Character Priority queue: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHPrtQueue(PriorityQueuePC, type = $ 12, newOnTop=+); + %createDHPrtQueue(PriorityQueueNC, type = $ 12, newOnTop=-); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example1; + + _I_ = .; + length _X_ _Y_ $ 3; + do _X_ = "AAA","BBB","CCC","AA","BB","CC","A","B","C"; + _I_ + 1; + call PriorityQueuePC("I", mod(_I_, 3), _X_); + call PriorityQueueNC("I", mod(_I_, 3), _X_); + end; + + Height = .; + call PriorityQueuePC('Height', Height, ''); + put Height=; + + do until(Height = 0); + call PriorityQueuePC('Dequeue', _I_, _X_); + call PriorityQueueNC("Dequeue", _I_, _Y_); + call PriorityQueueNC('Height', Height, ''); + put (_ALL_) (=); + output; + end; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Hash-based, and Numeric Priority queue: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHPrtQueue(PriorityQueueN); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + + do _X_ = -5 to 5; + call PriorityQueueN("Enqueue", abs(_X_), _X_); + end; + + call missing(Sum, Avg, Cnt, Hgt); + call PriorityQueueN('Sum', ., Sum); + call PriorityQueueN('Avg', ., Avg); + call PriorityQueueN('Cnt', ., Cnt); + call PriorityQueueN('Height', ., Hgt); + put (_ALL_) (=); + + do _N_ = 1 to Hgt; + call PriorityQueueN("Dequeue", _X_, _Y_); + put _X_= _Y_=; + end; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `%createDHStack()` macro: <<< ####################### + +The `%createDHStack()` macro allows to generate +a `dynamic hash stack` which is a FCMP based approach +to create dynamically allocated numeric or character +[stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) + +Interesting reading about implementing a stack via hash table +can be found in *chapter 10.4* of the: +*"Data Management Solutions Using SAS Hash Table Operations: + A Business Intelligence Case Study"* book +by Paul Dorfman and Don Henderson. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%createDHStack( + fifoName + <,debug=0> + <,type=8> + <,outlib=work.DFAfcmp.package> + <,hashexp=13> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `stackName` - *Required*, creates a FCMP call subroutine which is also + a stack name. In the data step it is used in form of + a call subroutine, e.g. `call stackName("Push", 3)`. + Has to satisfy FCMP function naming requirements, but with + maximum of 24 characters. + +* `debug=` - *Optional*, the default value is `0`. + If set to `1` then it turns on a debugging mode. + +* `type=` - *Optional*, the default value is `8`. + Indicates what *type* (numeric/character) and *length* + are data portion of generated array. Should be in line + with the LENGTH statement, e.g. `8`, `$ 30`, etc. + Determines if the `value` argument is numeric or character. + +* `outlib=` - *Optional*, the default value is `work.DFAfcmp.package`. + It points the default location for new generated dynamic + function arrays compiled by FCMP. + *Hint!* Keep it as it is. + +* `hashexp=` - *Optional*, the default value is `13`. It is the default `hashexp=` + value for internal hash table used by the function. + + +**Created function arguments description**: + +A function generated by the macro is: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +call &stackName.(IO, value) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and accepts the following list of arguments and values: + +1. `IO` - is a *character* steering argument, possible + values and behaviour they call are the following: + - `O`, `Output`, `Pop`, `G`, `Get`, `R`, `Return` - to get the data from a stack (and remove it from the top), + - `I`, `Input`, `Push`, `Put`, `Insert` - to insert the data into a stack, + - `C`, `Clear` - to reduce a stack to an empty one, + - `P`, `Peek` - to peek the data from a stack (and NOT remove it from the top), + - `Sum` - returns sum of non-missing numeric elements of a stack, + - `Avg`, `Mean`, `Average` - returns average of non-missing numeric elements of a stack, + - `Nonmiss`, `Cnt`, `Nnm` - returns number of non-missing elements of a stack, + - `Height` - returns height a stack, + +2. `value` - is a *numeric* or *character* argument (determined by the `type=`) + and depends on the `IO` value. Behaves in the following way: + - for `O`, `Output`, `Pop`, `G`, `Get`, `R`, `Return` it holds a value popped from a stack, + - for `I`, `Input`, `Push`, `Put`, `Insert` it holds a value to be pushed into a stack, + - for `C`, `Clear` it is ignored, + - for `P`, `Peek` it holds a value peeked from a stack, + - for `Sum`, `Nonmiss`, `Cnt`, `Avg`, `Mean`, `Average`, `Height` it returns calculated summary value, + +The `value` argument is **outarg**, i.e. can be changed by the function. + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Dynamic, Hash-based, and Character stack: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHStack(StackDHC, type = $ 12); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + + %let zeros = 6; *[to test bigger sizes]; + data Example1; + + t = time(); drop t; + do _I_ = 1 to 1e&zeros.; + _X_ = put(_I_*10, z12.); + call StackDHC("Put", _X_); + end; + t = time() - t; + + call StackDHC("Height", _X_); + put t= / _X_=; + + t = time(); + do _I_ = 1 to 1e&zeros. + 3; + call StackDHC('Pop', _X_); + output; + end; + t = time() - t; + + call StackDHC("Height", _X_); + put t= / _X_=; + + %* clear for further reuse *; + call StackDHC('Clear', ''); + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Dynamic, Hash-based, and Numeric stack: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %createDHStack(StackDHN); + options APPEND=(cmplib = WORK.DFAfcmp) ; + + data Example2; + + do _I_ = 1,.,2,.,3,.,4,.,5,.,6; + call StackDHN("Put", _I_); + end; + + call StackDHN("Sum", _I_); + put "Sum " _I_=; + + call StackDHN("Avg", _I_); + put "Avg " _I_=; + + call StackDHN("Cnt", _I_); + put "Cnt " _I_=; + + call StackDHN("Height", _I_); + put "Height " _I_=; + + _X_ = 0; + do _I_ = 1 to _I_; + call StackDHN('Pop', _X_); + output; + end; + + call StackDHN("Height", _I_); + put "Height " _I_=; + + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- +## >>> `generateArrays` exec: <<< ####################### + +The generateArrays exec file provides a **list of automatically generated examples** of functions +emulating data structures. + +The list of provided examples is the following: +- `SmpArray` - Simple Immutable Dynamic Function Array +- `SmpMtbArray` - Simple Mutable Dynamic Function Array +- `SrchArray` - Searchable Immutable Dynamic Function Array +- `SrchMtbArray` - Searchable Mutable Dynamic Function Array +- `DynArrayC` - Dynamic Hash-based Character Function Array (length 256 bytes) +- `StackC` - Dynamic Hash-based Character Stack (length 256 bytes) +- `StackN` - Dynamic Hash-based Numeric Stack +- `FifoC` - Dynamic Hash-based Character Fifo (length 256 bytes) +- `FifoN` - Dynamic Hash-based Character Fifo +- `DescStackC` - Dynamic Hash-based Character Descending Ordered Stack (length 256 bytes) +- `AscStackC` - Dynamic Hash-based Character Ascending Ordered Stack (length 256 bytes) +- `DescStackN` - Dynamic Hash-based Numeric Descending Ordered Stack +- `AscStackN` - Dynamic Hash-based Numeric Ascending Ordered Stack +- `PrtQueueNTC` - Dynamic Hash-based Character Priority Queue with *New on Top* (length 256 bytes) +- `PrtQueueNBC` - Dynamic Hash-based Character Priority Queue with *New on Bottom* (length 256 bytes) +- `PrtQueueNTN` - Dynamic Hash-based Numeric Priority Queue with *New on Top* +- `PrtQueueNBN` - Dynamic Hash-based Numeric Priority Queue with *New on Bottom* + +The `outlib=` option is set to `work.DFAfcmp.package`. The `cmplib=` option is updated automatically. + +--- +## >>> `generateArrays` clean: <<< ####################### + +The generateArrays clean file clears the list of automatically generated examples of functions +emulating data structures provided in the `generatearrays.sas` exec file. + +The `cmplib=` option is updated automatically. + +--- + +## License #################################################################### + +Copyright (c) 2019 Bartosz Jablonski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- diff --git a/packages/dfa.zip b/packages/dfa.zip index 5de6acf0d8a7322600f0eca6ed0a4b63485d715d..82ec6609e0033aeee2f20649b7db7ac2d8af474d 100644 GIT binary patch delta 35115 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 delta 27917 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