de Rigo, D. (2012). Applying semantic constraints to array programming: the module "check_is" of the Mastrave modelling library. In: Semantic Array Programming with Mastrave - Introduction to Semantic Computational Modelling. http://mastrave.org/doc/mtv_m/check_is

Applying semantic constraints to array programming: the module "check_is" of the Mastrave modelling library

 

Daniele de Rigo

 

Abstract: Array programming originated to reduce the gap between mathematical notation and algorithm implementations by promoting arrays (vectors, matrices, tensors, up to more complex structures) as atomic quantities with extremely concise manipulating operators. Coherent array-based mathematical description of models can simplify complex algorithm design and prototyping while moving mathematical reasoning directly into the source code - because of its substantial size reduction - where the mathematical description is actually expressed in a completely formalized and reproducible way.

Operations with arrays are often performed by delegating low-level details (e.g. loops among scalar elements of the arrays) to state-of-the-art numerical/scientific libraries while offering clean abstract operators (e.g. GNU Octave, MATLAB, GNU R, Numpy and Scipy in Python, ...). Array operators and functions concisely apply to multi-dimensional variables as if they were atomic, almost completely removing the need for explicit loops. They may offer a very terse and high-performance replacement for verbose object-oriented approaches, especially when dealing with complex data-processing of large/heterogeneous data.

However, this compact approach has a drawback. As arrays are considered to be a basic type, array variables can legitimately (and silently...) be assigned with other arrays of heterogeneous size or with values which semantically might be wrong for a given algorithm. Although this abstraction offers a powerful and extremely concise notation, complex array-based algorithms and models still may consist of hundreds or thousands of code lines, for which good practices such as assertions and ad-hoc consistency checks may tend to proliferate. Here, a collection of array-based concise and consistent semantic constraints is presented along with a specialised module to properly manage array-based semantics in array programming. Although the module is implemented in GNU Octave/MATLAB language (it is able to run in both computing environments), the set of array-based semantic constraints is language neutral and it may be easily accessed in other languages via multi-language array programming bridges. Aside from the actual implementation of algorithms, the semantic constraints may prove helpful as standard support in the design phase to annotate array-based semantic properties of input, output and intermediate data-layers of complex chains of data-transformations.

The set of array-based semantic constraints here listed implements the standard semantic support for the Semantic Array Programming paradigm.
Array programming originated to reduce the gap between mathematical notation and algorithm implementations. This is done by promoting arrays (vectors, matrices, tensors, up to more complex structures) as atomic quantities with extremely concise manipulating operators.

Coherent array-based mathematical description of models can simplify complex algorithm design and prototyping while moving mathematical reasoning directly into the source code - because of its substantial size reduction - where the mathematical description is actually expressed in a completely formalized and reproducible way. This powerful approach mostly relies on programming languages which are dynamically and weakly typed (e.g. GNU Octave, MATLAB, GNU R, Numpy and Scipy in Python, ...) where the concepts of vector, matrix and multidimensional array can all be represented by the native type double, which in some languages can also seamlessly represent complex-valued numbers.

Operations with arrays are often performed by delegating low-level details (e.g. loops among scalar elements of the arrays) to state-of-the-art numerical/scientific libraries - on which array programming languages transparently rely while offering clean abstract operators. Array operators and functions concisely apply to multi-dimensional variables as if they were atomic, almost completely removing the need for explicit loops. They may offer a very terse and high-performance replacement for verbose object-oriented approaches, especially when dealing with complex data-processing of large/heterogeneous data.

However, this compact approach has a drawback. As arrays are considered to be a basic type, array variables can legitimately (and silently...) be assigned with other arrays of heterogeneous size or with values which semantically might be wrong for a given algorithm (e.g. negative values for algorithms expecting positive ones). Although this abstraction offers a powerful and extremely concise notation, complex array-based algorithms and models still may consist of hundreds or thousands of code lines, for which good practices such as assertions and ad-hoc consistency checks may tend to proliferate. This however raises relevant issues on the sustainability and effectiveness of such intensely needed "DIY" ad-hoc solutions. Semantic constraints: a pictoral representation

Here, a collection of array-based concise and consistent semantic constraints is presented along with a specialised module to properly manage array-based semantics in array programming. Although the module is implemented in GNU Octave/MATLAB language (it is able to run in both computing environments), the set of array-based semantic constraints is language neutral. Aside from the actual implementation of algorithms, the semantic constraints may prove helpful as standard support in the design phase to annotate array-based semantic properties of input, output and intermediate data-layers of complex chains of data-transformations. The module may be easily accessed in other languages via multi-language array programming bridges (e.g. [1][2]). The sole assumption regarding the data-types to check is that an array programming language may offer as basic array-types at least one of the following categories:
  • multi-dimensional arrays of numbers (booleans, integers, reals or complex-valued) or characters;
  • sets of uneven arrays, indexed either with positive integers (e.g. cell-arrays in GNU Octave/MATLAB [3]) or with strings (e.g. structures in GNU Octave/MATLAB [4]).
  • Functional programming types are supported by extending basic data to include anonymous functions and function handles ([5]).
  • Numbers are extended with the infinite and the concept of "not a number" denoting undefined (e.g. 1/0) or missing data. This follows the standard IEEE 754 for floating-point arithmetic.


Examples of array-based semantic constraints

Examples of array-based semantic constraints. Left: an array of raster layers (e.g. covariates/predictors to serve as input for a multivariate statistical analysis). The elements composing the array may be accessed and denoted with different levels of granularity, from the single element of a given spatial cell (pixel value) up to sparse collection of them, entire matrix layers and list of matrices. Right: Another semantic dimension associated with the aforementioned arrays is defined by the numerical values of each array element. Permissible values may vary depending on specific requirements of the particular algorithm which is expected to operate on the arrays.

The set of array-based semantic constraints here listed implements the standard semantic support for the Semantic Array Programming paradigm. This support is meant to allow concise pieces of array-programming code to be immersed within a robust semantic network of array-concepts, without renouncing to extremely compact representations.


Copyright and license notice of the function check_is

 

 

Copyright © 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 Daniele de Rigo

The file check_is.m is part of Mastrave.

Mastrave is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Mastrave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Mastrave. If not, see http://www.gnu.org/licenses/.

Function declaration

 

 

[answer, msg, must] = check_is( obj           ,
                                obj_type      ,
                                msg      = '' ,
                                ...           )

Description

 

 

Module for checking whether the variable obj belongs to the category obj_type . obj_type categories implement the concept of semantic array-based constraints on which the paradigm of Semantic Array Programming is based.

The behaviour of the function depends on the number of output arguments.

If nargout==0 , then if the check ends successfully, the module returns to the caller. Otherwise, an error is thrown displaying a message whose format is msg .

If nargout==1 , then the module returns a boolean value answer which is true if the check ends successfully, false otherwise.

If nargout==2 , then the module returns the boolean answer as in the previous case, along with an error message whose format is msg (the message is an empty string if the check ends successfully).

If nargout==3 , the module returns answer and msg as in the previous case, along with the struct must whose fields contain the constraints to be satisfied.

If other arguments are passed after msg , they are managed like the optional arguments in the function @sprintf (see the help of @sprintf for more details about the format of msg and the optional arguments).

The semantic constraints associated to each input argument and documented within the help of all Mastrave functions are implemented by invoking this function.


Representation of semantic constraints

In order for a function to be compliant with the Mastrave coding standards, it must explicitly express (and document) a set of semantic constraints for each of its input arguments and optionally for its output arguments. Semantic constraints take the form of a sequence of categories between :: . The special token :: is used as "quotation" delimiter of the semantic constraints which are expected to be delimited by :: both as prefix and suffix. The general documentation syntax is:


argument_name ::semantic constraints::
Documentation describing the argument
argument_name and the reason why its
semantic constraints ought to hold.

where ::semantic constraint:: is a generic placeholder which actually stays for one or more of the categories described in the following section "Input arguments". Within the Semantic Array Programming paradigm, the use of these array-based semantic checks is indeed straightforward and in many cases do not require the user to pay attention to the mathematical details underpinning the implementation of the concept of array-based semantic check. For reference, these details are briefly summarised in the following.

The role of the category obj_type for the variable obj could be formalized within the deontic logic. In case to obj a single category is applied, the category can be interpreted as a necessity. If obj_type value is ::p::, then for obj it must hold the deontic logic proposition (basic unary modal operators ☐ and ◇ are here used):

☐ p % it ought to be that p

(Beware that the label ::p::, and in the following the label ::q::, are used as generic place-holders, so that neither ::p:: nor ::q:: are valid constraints.) A consequence of ::p:: is that:


not ( ◇ not(p) )
% it is not permissible that not-p

meaning that if the semantic constraint ::p:: - which we suppose to be required e.g. for a given input argument of a certain module - is not satisfied, then it is not permissible that module's execution to be continued.

If obj_type value is ::p,q::, then for obj it must hold the deontic logic proposition:

( ☐ p ) and ( ☐ q ) % it ought to be both that p and q

a consequence of it is that:


not ( ◇ not(p) ) or not ( ◇ not(q) )
% it is not permissible that either not-p or not-q

If obj_type value is ::p|q::, then for obj it must hold the deontic logic proposition:

( ☐ p ) or ( ☐ q ) % it ought to be either p or q
whose consequence is that:


( ◇ not(p) ) and ( ◇ not(q) ) and not ( ◇ ( not(p) and not(q) ) )
% not-p and not-q are both permissible,
% however it is not permissible that neither p nor q

An accurate (despite possibly inefficient) implementation of the previous deontic logic propositions on obj may be obtained by replacing each atomic proposition:

☐ p

with the call to @check_is:


T = check_is( obj , ::p:: )

so that e.g. the semantic constraint ::p|q:: on obj can be implemented as:


T1 = check_is( obj , ::p:: )
T2 = check_is( obj , ::q:: )
T = check_is( T1 | T2 , ::true:: )

The validity of the aggregated check result T must hold.

Input arguments

 

 


 obj                      ::generic::
                          Object on which to check the  obj_type 
                          constraint.

 obj_type                 ::generic|row_string::
                          Constraint to be checked. Follows here a list of
                          the implemented categories for  obj_type :

    obj_type  value            constraint to verify
  ──────────────────────────────────────────────────────────────────────────
    model                    class(  obj  ) must be the same as
                             class(  model  ) and if  model  is a 
                             ::cell::-array or a struct, each element of 
                              model  must recursively have the same class 
                             of the corresponding element of  obj .
                              model  cannot be a string: if you need to
                             check if  obj  is a string, use instead
                             something like:
                                    check_is(   obj   ,  'string'  , ...
                                               'must be a string!'       )
                            
                             Only the classes of the (element composing
                             the) object are compared.  As a consequence, 
                             the numeric or string values and also the size 
                             of a given array element of  obj  may not 
                             imply a matching failure, provided that the 
                             class of the corresponding element of  model 
                             is the same.  However, in case the class of
                             that element is a container of heterogeneous
                             items (e.g. a cell-array of a struct), then
                             the size of the element is considered.  
                             This is because the i-th item of the  obj 
                             element has to be checked for ensuring its
                             class is the same of the one of the i-th
                             item of the corresponding element of  model .
                             As a general rule, heterogeneous containers
                             are checked item by item, while homogeneous
                             containers (e.g. ordinary arrays) are not.
 
                             \((\newcommand{\obj}[1]{\text{obj}}\newcommand{\semapi}[2]{:\,\!:\!\!{\large \mid}\, {#2} \,{\large \mid}\!\!:\,\!:{}^{\hspace{-3mm}{}^{{}^{\LARGE \mathtt{\text{#1}\;\;}^{\mbox{}}}}}}\newcommand{\semap}[1]{\semapi{#1}{\obj{}}}\newcommand{\atpos}[1]{{[\,#1\,]}}\))

 ──────────────────────────────────────────────────────────────────────────
   'generic',                Synonym of:  logical(     1   )
   'anything'               
                             Rationale: to support an always-passing test.
  ──────────────────────────────────────────────────────────────────────────
   'nothing',                Synonym of:  logical(     0   )
   'fail'                   
                             Rationale: to support an always-failing test.
  ──────────────────────────────────────────────────────────────────────────
   'true'                    Synonym of:  logical(    obj  )
                            
                             Rationale: to offer a generic logical test in
                             case no one of the supported specific tests
                             applies.
  ──────────────────────────────────────────────────────────────────────────
   'false'                   Synonym of:  ~logical(   obj  )
                            
                             Rationale: to offer a generic logical test in
                             case no one of the supported specific tests
                             applies.
  ──────────────────────────────────────────────────────────────────────────
   'any'                     Synonym of:  isnumeric(  obj     ) && ...
                                          any(        obj (:) )
 
                             \((\semap{numeric} \;\;\land\;\; \exists i, \;\text{obj}\atpos{i} \equiv true\))

 ──────────────────────────────────────────────────────────────────────────
   'all'                     Synonym of:  isnumeric(  obj     ) && ...
                                          all(        obj (:) )
 
                             \((\semap{numeric} \;\;\land\;\; \forall i, \;\text{obj}\atpos{i} \equiv true\))

 ──────────────────────────────────────────────────────────────────────────
   'logical'                 Synonym of:  islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'binary'                  Synonym of:  islogical(  obj  ) ||  ( ...
                                          isnumeric(  obj  ) &&    ...
                                          all(        obj (:) ==   ...
                                            logical(  obj (:)) ) )
  ──────────────────────────────────────────────────────────────────────────
   'numeric'                 Synonym of:  isnumeric(  obj  ) || ...
                                          islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'real'                    Synonym of:  isnumeric(  obj  ) || ...
                                          islogical(  obj  ) && ...
                                          ~any(imag(  obj (:)) )
  ──────────────────────────────────────────────────────────────────────────
   'finite'                   obj  must be ::numeric:: and its elements
                             must have finite values so that no infinite
                             nor NaN elements are allowed.
 
                             \((\semap{numeric} \;\;\land\;\; \forall i, \; -\infty \lt \text{obj}\atpos{i} \lt \infty\))

 ──────────────────────────────────────────────────────────────────────────
   'nanless'                  obj  must be ::numeric:: and its elements'
                             value cannot be NaN.
                            
                             Example of usage: to support algorithms 
                             relaying on operators whose use may be 
                             problematic when dealing with NaN values 
                             (e.g. statistics such as @var, scan operators
                             such as @cumsum, ... ) with a default check 
                             for ensuring input data to have been properly
                             pre-processed. Typically, this kind of 
                             constraint may require a pre-processing step 
                             for the NaN values to be replaced with neutral
                             values (e.g. in a sum operator, 0 is the
                             neutral value, while in a product operator 
                             the neutral value would be 1, etc..). Then, a
                             post-processing step might be further required
                             for the NaN values to be reintroduced (e.g. 
                             the operator average may be split in the sum 
                             the elements  with zeros replacing NaN values
                              divided by the counting of non-NaN elements:  
                             when all elements are NaN, the division by 0
                             would reintroduce NaN as the average value for
                             that particular case).
  ──────────────────────────────────────────────────────────────────────────
   'nonzero'                  obj  must be ::numeric:: and its elements'
                             value cannot be zero.
 
                             \((\semap{numeric} \;\;\land\;\; \forall i, \;\text{obj}\atpos{i} \neq 0\))

 ──────────────────────────────────────────────────────────────────────────
   'numstring'               Synonym of:  ischar(     obj  ) || ...
                                          isnumeric(  obj  ) ||...
                                          islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'realstring'              Synonym of:  ischar(     obj  ) ||  (...
                                          isnumeric(  obj  ) ||   ...
                                          islogical(  obj  ) &&   ...
                                          ~any(imag(  obj (:)) ) )
  ──────────────────────────────────────────────────────────────────────────
   'char' ,                  Synonym of:  ischar(     obj  )
   'string'                  
  ──────────────────────────────────────────────────────────────────────────
   'row_string'               obj  must be a one-row string.
  ──────────────────────────────────────────────────────────────────────────
   'varname'                 Synonym of:  ischar(     obj  ) && ...
                                          isvarname(  obj  ) && ...
                                           obj (1) ~= '_'
                             Rationale: to ensure  obj  is a portable
                             variable name.
  ──────────────────────────────────────────────────────────────────────────
   'format_string'            obj  must be a valid format string for the
                             *printf family of functions.
  ──────────────────────────────────────────────────────────────────────────
   'regexp'                   obj  must be a valid regular expression for
                             the regex* family of functions.
  ──────────────────────────────────────────────────────────────────────────
   'cell'                    Synonym of:  iscell(     obj  )
   'list'                    Almost all array-programming languages support
                             a native array container for uneven objects.
                             In MATLAB/GNU Octave, this special array type
                             is called "cell-array" and allows each of its
                             elements to be a numeric type, a string, a
                             function-handle, a struct or another nested
                             cell-array, irrespective of the type of the
                             other elements. 
                            
                             Other array-programming languages may use the
                             concept of "list" for expressing a pretty
                             similar type of array container.
                             Please, be aware that a "cell-array" is not
                             supposed to be a one-dimensional array: it
                             may be a generic n-dimensional array of uneven
                             elements. In some array-programming languages,
                             "list" arrays are only one-dimensional. Here,
                             ::list:: is used as a synonym for ::cell::,
                             thus implying the array not to be constrained
                             to necessarily be a one-dimensional one. 
                             If this instead were the intended semantics, 
                             please mimic it e.g. by also requiring the 
                             array to be a ::vector::.
  ──────────────────────────────────────────────────────────────────────────
   'struct'                  Synonym of:  isstruct(   obj  )
  ──────────────────────────────────────────────────────────────────────────
   'sparse'                  Synonym of:  issparse(   obj  )
  ──────────────────────────────────────────────────────────────────────────
   'full'                    Synonym of:  ~issparse(   obj  )
   'nonsparse'              
  ──────────────────────────────────────────────────────────────────────────
   'function_handle'         Synonym of:  isa(  obj  , 'function_handle' )
   'funhandle'              
   'func'                   
  ──────────────────────────────────────────────────────────────────────────
   'strfunhandle'            Synonym of:  ischar(     obj  ) || ...
   'strfunc'                              isa(  obj  , 'function_handle' )
  ──────────────────────────────────────────────────────────────────────────
   'numfunhandle'            Synonym of:  isnumeric(  obj  ) || ...
   'numfunc'                              islogical(  obj  ) || ...
                                          isa(  obj  , 'function_handle' )
  ──────────────────────────────────────────────────────────────────────────
   'numstrfunhandle'         Synonym of:  isnumeric(  obj  ) || ...
   'numstrfunc'                           islogical(  obj  ) || ...
                                          ischar(     obj  ) || ...
                                          isa(  obj  , 'function_handle' )
  ──────────────────────────────────────────────────────────────────────────
   'int8'                    Synonym of:  isa(  obj  , 'int8'   )
  ──────────────────────────────────────────────────────────────────────────
   'uint8'                   Synonym of:  isa(  obj  , 'uint8'  )
  ──────────────────────────────────────────────────────────────────────────
   'int16'                   Synonym of:  isa(  obj  , 'int16'  )
  ──────────────────────────────────────────────────────────────────────────
   'uint16'                  Synonym of:  isa(  obj  , 'uint16' )
  ──────────────────────────────────────────────────────────────────────────
   'int32'                   Synonym of:  isa(  obj  , 'int32'  )
  ──────────────────────────────────────────────────────────────────────────
   'uint32'                  Synonym of:  isa(  obj  , 'uint32' )
  ──────────────────────────────────────────────────────────────────────────
   'tileable'                 obj  must be ::numeric:: or a ::char:: or a 
                             ::cell::-array or a struct.
                            
                             Rationale: to ensure  obj  can be tiled, e.g.
                             using repmat(  obj  , .. ).
  ──────────────────────────────────────────────────────────────────────────
   'numcellstring'            obj  must be ::numeric:: or a ::char:: or a 
   'sortable'                ::cell::-array whose elements  obj_type  must
                             be ::char:: .
                            
                             Rationale: to ensure  obj  can be sorted, e.g.
                             using sort(  obj  , .. ).
  ──────────────────────────────────────────────────────────────────────────
   'realcellstring'           obj  must be ::real:: or a ::char:: or a 
   'tsortable'               ::cell::-array whose elements  obj_type  must 
                             be ::char:: .
                            
                             Rationale: to ensure  obj  can be sorted, e.g.
                             using sort(  obj  , .. ), with the guarantee
                             of total-order.  This excludes complex numbers
                             with nonzero imaginary part.
  ──────────────────────────────────────────────────────────────────────────
   'sorted'                   obj  must be sorted in either ascending or
                             descending order.
  ──────────────────────────────────────────────────────────────────────────
   'sorted-ascend'            obj  must be sorted in ascending order.
  ──────────────────────────────────────────────────────────────────────────
   'sorted-descend'           obj  must be sorted in descending order.
  ──────────────────────────────────────────────────────────────────────────
   'row_elems'                obj  must be a row-vector or a 
                             ::cell::-array whose elements must be
                             row-vectors.
  ──────────────────────────────────────────────────────────────────────────
   'cellstring'               obj  must be a ::char:: or a ::cell::-array
   'liststring'              whose elements  obj_type  must be ::char:: .
 
                             \((\semap{string} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{string}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellstring-r'             obj  must be a ::char:: or a cell-array 
   'liststring-r'            whose elements  obj_type  must be 
                             ::cellstring-r:: .
 
                             \((\semap{string} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellstring-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellstring-1'             obj  must be a ::cell::-array of ::char:: .
   'liststring-1'            
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{string}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellstring-2'             obj  must be a ::cell::-array of cell-arrays 
   'liststring-2'            of ::char:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{string}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumeric'              obj  must be ::numeric:: or a ::cell::-array
   'listnumeric'             whose elements  obj_type  must be 
                             ::numeric:: .
 
                             \((\semap{numeric} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{numeric}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumeric-r'            obj  must be ::numeric:: or a ::cell::-array 
   'listnumeric-r'           whose elements  obj_type  must be 
                             ::cellnumeric-r:: .
 
                             \((\semap{numeric} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellnumeric-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumeric-1'            obj  must be a ::cell::-array of 
   'listnumeric-1'           ::numeric:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numeric}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellnumeric-2'            obj  must be a ::cell::-array of cell-arrays 
   'listnumeric-2'           of ::numeric:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{numeric}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfinite'               obj  must be ::finite:: or a ::cell::-array 
   'listfinite'              whose elements  obj_type  must be ::finite:: .
 
                             \((\semap{finite} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{finite}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfinite-r'             obj  must be ::finite:: or a ::cell::-array 
   'listfinite-r'            whose elements  obj_type  must be 
                             ::cellfinite-r:: .
 
                             \((\semap{finite} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellfinite-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfinite-1'             obj  must be a ::cell::-array of ::finite:: .
   'listfinite-1'            
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{finite}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellfinite-2'             obj  must be a ::cell::-array of cell-arrays 
   'listfinite-2'            of ::finite:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{finite}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnanless'              obj  must be ::nanless:: or a ::cell::-array 
   'listnanless'             whose elements  obj_type  must be  
                             ::nanless:: .
 
                             \((\semap{nanless} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{nanless}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnanless-r'            obj  must be ::nanless:: or a ::cell::-array 
   'listnanless-r'           whose elements  obj_type  must be 
                             ::cellnanless-r:: .
 
                             \((\semap{nanless} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellnanless-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnanless-1'            obj  must be a ::cell::-array of 
   'listnanless-1'           ::nanless:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{nanless}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellnanless-2'            obj  must be a ::cell::-array of cell-arrays 
   'listnanless-2'           of ::nanless:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{nanless}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnonzero'              obj  must be ::nonzero:: or a ::cell::-array 
   'listnonzero'             whose elements  obj_type  must be 
                             ::nonzero:: .
 
                             \((\semap{nonzero} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{nonzero}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnonzero-r'            obj  must be ::nonzero:: or a ::cell::-array 
   'listnonzero-r'           whose elements  obj_type  must be 
                             ::cellnonzero-r:: .
 
                             \((\semap{nonzero} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellnonzero-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnonzero-1'            obj  must be a ::cell::-array of 
   'listnonzero-1'           ::nonzero:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{nonzero}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellnonzero-2'            obj  must be a ::cell::-array of cell-arrays 
   'listnonzero-2'           of ::nonzero:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{nonzero}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellint'                  obj  must be integer or a ::cell::-array 
   'listint'                 whose elements  obj_type  must be integers.
 
                             \((\semap{int} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{int}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellint-r'                obj  must be integers or a ::cell::-array 
   'listint-r'               whose elements  obj_type  must be  
                             ::cellint-r:: .
 
                             \((\semap{int} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellint-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellint-1'                obj  must be a ::cell::-array of integers.
   'listint-1'               
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{int}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellint-2'                obj  must be a ::cell::-array of cell-arrays 
   'listint-2'               of integers.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{int}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellscalar'               obj  must be a scalar or a ::cell::-array 
   'listscalar'              whose elements  obj_type  must be scalars.
 
                             \((\semap{scalar} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{scalar}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellscalar-r'             obj  must be a scalar or a ::cell::-array 
   'listscalar-r'            whose elements  obj_type  must be  
                             ::cellscalar-r:: .
 
                             \((\semap{scalar} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellscalar-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellscalar-1'             obj  must be a ::cell::-array of scalars.
   'listscalar-1'            
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{scalar}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellscalar-2'             obj  must be a ::cell::-array of cell-arrays 
   'listscalar-2'            of scalars.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{scalar}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellvector'               obj  must be a vector or a ::cell::-array 
   'listvector'              whose elements  obj_type  must be vectors.
 
                             \((\semap{vector} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{vector}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellvector-r'             obj  must be a vector or a ::cell::-array 
   'listvector-r'            whose elements  obj_type  must be 
                             ::cellvector-r::.
 
                             \((\semap{vector} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellvector-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellvector-1'             obj  must be a ::cell::-array of vectors.
   'listvector-1'            
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{vector}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellvector-2'             obj  must be a ::cell::-array of cell-arrays 
   'listvector-2'            of vectors.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{vector}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellmatrix'               obj  must be a matrix or a ::cell::-array 
   'listmatrix'              whose elements  obj_type  must be matrices.
 
                             \((\semap{matrix} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{matrix}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellmatrix-r'             obj  must be a matrix or a ::cell::-array 
   'listmatrix-r'            whose elements  obj_type  must be 
                             ::cellmatrix-r:: .
 
                             \((\semap{matrix} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellmatrix-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellmatrix-1'             obj  must be a ::cell::-array of matrices.
   'listmatrix-1'            
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{matrix}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellmatrix-2'             obj  must be a ::cell::-array of cell-arrays 
   'listmatrix-2'            of matrices.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{matrix}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell3-array'              obj  must be a ::3-array:: or a 
   'list3-array'             ::cell::-array whose elements  obj_type  must 
                             be 3-arrays.
 
                             \((\semap{3-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{3-array}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell3-array-r'            obj  must be a ::3-array:: or a  
   'list3-array-r'           ::cell::-array whose elements  obj_type  must
                             be ::cell3-array-r:: .
 
                             \((\semap{3-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cell3-array-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell3-array-1'            obj  must be a ::cell::-array of 
   'list3-array-1'           ::3-arrays:: . 
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{3-array}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cell3-array-2'            obj  must be a ::cell::-array of cell-arrays 
   'list3-array-2'           of ::3-array:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{3-array}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell4-array'              obj  must be a ::4-array:: or a 
   'list4-array'             ::cell::-array whose elements  obj_type  must
                             be 4-arrays.
 
                             \((\semap{4-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{4-array}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell4-array-r'            obj  must be a ::4-array:: or a  
   'list4-array-r'           ::cell::-array whose elements  obj_type  must
                             be ::cell4-array-r:: .
 
                             \((\semap{4-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cell4-array-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell4-array-1'            obj  must be a ::cell::-array of 
   'list4-array-1'           ::4-arrays:: . 
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{4-array}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cell4-array-2'            obj  must be a ::cell::-array of cell-arrays 
   'list4-array-2'           of ::4-array:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{4-array}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell5-array'              obj  must be a ::5-array:: or a
   'list5-array'             ::cell::-array whose elements  obj_type  must
                             be 5-arrays.
 
                             \((\semap{5-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{5-array}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell5-array-r'            obj  must be a ::5-array:: or a 
   'list5-array-r'           ::cell::-array whose elements  obj_type  must 
                             be ::cell5-array-r:: .
 
                             \((\semap{5-array} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cell5-array-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cell5-array-1'            obj  must be a ::cell::-array of
                             ::5-arrays:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{5-array}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cell5-array-2'            obj  must be a ::cell::-array of cell-arrays 
   'list5-array-2'           of ::5-array:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{5-array}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellreal'                 obj  must be ::real:: or a ::cell::-array 
   'listreal'                whose elements  obj_type  must be ::real:: .
 
                             \((\semap{real} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{real}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellreal-r'               obj  must be ::real:: or a ::cell::-array 
   'listreal-r'              whose elements  obj_type  must be 
                             ::cellreal-r:: .
 
                             \((\semap{real} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellreal-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellreal-1'               obj  must be a ::cell::-array of ::real:: .
   'listreal-1'              
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{real}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellreal-2'               obj  must be a ::cell::-array of cell-arrays 
   'listreal-2'              of ::real:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{real}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumstring'            obj  must be ::numstring:: or a 
   'listnumstring'           ::cell::-array whose elements  obj_type  must
                             be ::numstring:: .
 
                             \((\semap{numstring} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{numstring}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumstring-r'          obj  must be ::numstring:: or a 
   'listnumstring-r'         ::cell::-array whose elements  obj_type  must 
                             be ::cellnumstring-r:: .
 
                             \((\semap{numstring} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellnumstring-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumstring-1'          obj  must be a ::cell::-array of 
   'listnumstring-1'         ::numstring::. 
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numstring}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellnumstring-2'          obj  must be a ::cell::-array of cell-arrays 
   'listnumstring-2'         of ::numstring::.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{numstring}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellrealstring'           obj  must be ::realstring:: or a 
   'listrealstring'          ::cell::-array whose elements  obj_type  must 
                             be ::realstring:: .
 
                             \((\semap{realstring} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{realstring}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellrealstring-r'         obj  must be ::realstring:: or a 
   'listrealstring-r'        ::cell::-array whose elements  obj_type  must 
                             be ::cellrealstring-r:: .
 
                             \((\semap{realstring} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellrealstring-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellrealstring-1'         obj  must be a ::cell::-array of 
   'listrealstring-1'        ::realstring:: . 
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{realstring}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellrealstring-2'         obj  must be a ::cell::-array of cell-arrays 
   'listrealstring-2'        of ::realstring:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{realstring}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfunhandle'            obj  must be a function handle or a ::cell::
   'listfunhandle'           array whose elements  obj_type  must be 
                             function handles.
 
                             \((\semap{funhandle} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{funhandle}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfunhandle-r'          obj  must be a function handle or a ::cell::
   'listfunhandle-r'         array whose elements  obj_type  must be 
                             ::cellfunhandle-r:: .
 
                             \((\semap{funhandle} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellfunhandle-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellfunhandle-1'          obj  must be a ::cell::-array of function
   'listfunhandle-1'         handles.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{funhandle}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellfunhandle-2'          obj  must be a ::cell::-array of cell-arrays 
   'listfunhandle-2'         of function handles.
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{funhandle}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellindex'                obj  must be ::index:: or a ::cell::-array 
   'listindex'               whose elements  obj_type  must be ::index:: .
 
                             \((\semap{index} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{index}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellindex-r'              obj  must be ::index:: or a ::cell::-array 
   'listindex-r'             whose elements  obj_type  must be 
                             ::cellindex-r::.
 
                             \((\semap{index} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellindex-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellindex-1'              obj  must be a ::cell::-array of ::index:: .
   'listindex-1'             
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{index}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellindex-2'              obj  must be a ::cell::-array of cell-arrays 
   'listindex-2'             of ::index:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{index}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumel'                obj  must be ::numel:: or a ::cell::-array 
   'listnumel'               whose elements  obj_type  must be ::numel:: .
 
                             \((\semap{numel} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{numel}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumel-r'              obj  must be ::numel:: or a ::cell::-array 
   'listnumel-r'             whose elements  obj_type  must be 
                             ::cellnumel-r:: .
 
                             \((\semap{numel} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellnumel-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellnumel-1'              obj  must be a ::cell::-array of ::numel:: .
   'listnumel-1'             
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numel}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellnumel-2'              obj  must be a ::cell::-array of cell-arrays 
   'listnumel-2'             of ::numel:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{numel}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellprob'                 obj  must be of ::probability:: or a ::cell::
   'listprob'                array whose elements  obj_type  must be 
                             ::probability:: .
 
                             \((\semap{prob} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{prob}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellprob-r'               obj  must be of ::probability:: or a ::cell::
   'listprob-r'              array whose elements  obj_type  must be 
                             ::cellprob-r:: .
 
                             \((\semap{prob} \;\;\lor\;\; \))
                             \((\left ( \semap{cell} \;\;\land\;\;  \forall i, \;\semapi{cellprob-r}{\text{obj}\atpos{i}} \right )\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellprob-1'               obj  must be a ::cell::-array of 
   'listprob-1'              ::probability:: . 
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{prob}{\text{obj}\atpos{i}}\))

 ──────────────────────────────────────────────────────────────────────────
   'cellprob-2'               obj  must be a ::cell::-array of cell-arrays 
   'listprob-2'              of ::probability:: .
 
                             \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\))
                             \((\forall i \,\forall j, \;\semapi{prob}{\text{obj}\atpos{i}\atpos{j}}\)) 

 ──────────────────────────────────────────────────────────────────────────
   'cellempty'                obj  must be empty or a ::cell::-array whose
   'listempty'               elements must be empty.
  ──────────────────────────────────────────────────────────────────────────
   'cellempty-c'              obj  must be empty or a ::cell::-array whose
   'listempty-c'             elements must be empty.
                             If  obj  is a cell-array, it is not checked
                             if it is empty but only if its elements are
                             empty. Status: experimental.
  ──────────────────────────────────────────────────────────────────────────
   'cellempty-r'              obj  must be empty or a ::cell::-array whose
   'listempty-r'             elements  obj_type  must be ::cellempty-r:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellempty-1'              obj  must be a ::cell::-array of empty 
   'listempty-1'             elements. 
  ──────────────────────────────────────────────────────────────────────────
   'cellempty-2'              obj  must be a ::cell::-array of cell-arrays 
   'listempty-2'             of empty elements.
  ──────────────────────────────────────────────────────────────────────────
   'cellnonempty'             obj  must be empty or a ::cell::-array whose
   'listnonempty'            elements cannot be empty.
  ──────────────────────────────────────────────────────────────────────────
   'cellnonempty-c'           obj  must be empty or a ::cell::-array whose
   'listnonempty-c'          elements cannot be empty.
                             If  obj  is a cell-array, it is not checked
                             if it is non-empty but only if its elements
                             are non-empty. Status: experimental.
  ──────────────────────────────────────────────────────────────────────────
   'cellnonempty-r'           obj  must be ::nonempty:: or a ::cell::-array 
   'listnonempty-r'          whose elements  obj_type  must be 
                             ::cellnonempty-r:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellnonempty-1'           obj  must be a ::cell::-array of ::nonempty::
   'listnonempty-1'          elements.
  ──────────────────────────────────────────────────────────────────────────
   'cellnonempty-2'           obj  must be a ::cell::-array of cell-arrays 
   'listnonempty-2'          of ::nonempty:: elements.
  ──────────────────────────────────────────────────────────────────────────
   'cellscalempty'            obj  must be ::scalempty:: or a
   'listscalempty'           ::cell::-array whose elements  obj_type  must  
                             be ::scalempty:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellscalempty-c'          obj  must be ::scalempty:: or a ::cell::-array
   'listscalempty-c'         whose elements  obj_type  must be 
                             ::scalempty:: .
                             If  obj  is a cell-array, it is not checked
                             if it is ::scalempty:: but only if its
                             elements are scalempty. Status: experimental.
  ──────────────────────────────────────────────────────────────────────────
   'cellscalempty-r'          obj  must be ::scalempty:: or a
   'listscalempty-r'         ::cell::-array whose elements  obj_type  must 
                             be ::cellscalempty-r:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellscalempty-1'          obj  must be a ::cell::-array of ::scalempty::
   'listscalempty-1'         elements.
  ──────────────────────────────────────────────────────────────────────────
   'cellscalempty-2'          obj  must be a ::cell::-array of cell-arrays 
   'listscalempty-2'         of ::scalempty:: elements.
  ──────────────────────────────────────────────────────────────────────────
   'cellxorempty'             obj  must be a non-cell-array or a 
   'listxorempty'            ::cell::-array whose elements  obj_type  must 
                             be all empty or all ::nonempty:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellxorempty-c'           obj  must be a non-cell-array or a 
   'listxorempty-c'          ::cell::-array whose elements  obj_type  must 
                             be ::xorempty:: which means all empty or all 
                             ::nonempty:: . If  obj  is a cell-array, it  
                             is not checked if it is ::xorempty:: but only 
                             if its elements are ::xorempty:: .
                             Status: experimental.
  ──────────────────────────────────────────────────────────────────────────
   'cellxorempty-r'           obj  must be a non-cell-array or a 
   'listxorempty-r'          ::cell::-array whose elements  obj_type  must 
                             be all empty or all ::cellnonempty-r:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellxorempty-1'           obj  must be a ::cell::-array whose elements 
   'listxorempty-1'          must be all empty or all ::nonempty:: .
  ──────────────────────────────────────────────────────────────────────────
   'cellxorempty-2'           obj  must be a ::cell::-array of cell-arrays
   'listxorempty-2'          whose elements must be all empty or all
                             ::nonempty:: .
  ──────────────────────────────────────────────────────────────────────────
   'celltileable'             obj  must be ::tileable:: or a ::cell::-array 
   'listtileable'            whose elements  obj_type  must be 
                             ::tileable:: .
  ──────────────────────────────────────────────────────────────────────────
   'celltileable-c'           obj  must be ::tileable:: or a ::cell::-array 
   'listtileable-c'          whose elements  obj_type  must be 
                             ::tileable:: .
                             If  obj  is a cell-array, it is not checked
                             if it is ::tileable:: but only if its
                             elements are ::tileable:: .
  ──────────────────────────────────────────────────────────────────────────
   'celltileable-r'           obj  must be ::tileable:: or a ::cell::-array 
   'listtileable-r'          whose elements  obj_type  must be 
                             ::celltileable-r:: .
  ──────────────────────────────────────────────────────────────────────────
   'celltileable-1'           obj  must be a ::cell::-array of
   'listtileable-1'          ::tileable:: .
  ──────────────────────────────────────────────────────────────────────────
   'celltileable-2'           obj  must be a ::cell::-array of cell-arrays 
   'listtileable-2'          of ::tileable:: .
  ──────────────────────────────────────────────────────────────────────────
   'same_rows'                obj  must be a ::cell::-array of objects,
                             each of them having the same number of rows. 
  ──────────────────────────────────────────────────────────────────────────
   'same_columns'             obj  must be a ::cell::-array of objects, 
                             each of them having the same number of 
                             columns.
  ──────────────────────────────────────────────────────────────────────────
   'same_length'              obj  must be a ::cell::-array of objects, 
                             each of them having the same length.
  ──────────────────────────────────────────────────────────────────────────
   'same_size'                obj  must be a ::cell::-array of objects, 
                             each of them having the same size.
  ──────────────────────────────────────────────────────────────────────────
   'same_ndims'               obj  must be a ::cell::-array of objects,  
                             each of them having the same number of 
                             dimensions.
  ──────────────────────────────────────────────────────────────────────────
   'same_numel'               obj  must be a ::cell::-array of objects,  
                             each of them having the same number of
                             elements.
  ──────────────────────────────────────────────────────────────────────────
   'same_vals'                obj  must be a ::cell::-array of objects,  
                             each of them equal to all other ones.  
                             Not-a-number values (nan) are never equal to
                             each other.
  ──────────────────────────────────────────────────────────────────────────
   'same_valnans'             obj  must be a ::cell::-array of objects,  
                             each of them equal to all other ones.  
                             Not-a-number values (nan) are always equal to
                             each other.
  ──────────────────────────────────────────────────────────────────────────
   'same_diff'                obj  must be ::subtractable:: and the @diff 
                             between elements of  obj  must be constant.
  ──────────────────────────────────────────────────────────────────────────
   'comparable'               obj  must be a ::cell::-array of objects,  
                             each of them must be comparable with the
                             other using the operator == .
  ──────────────────────────────────────────────────────────────────────────
   'multipliable'             obj  must be a ::cell::-array of objects,  
                             each of them must be multipliable with the
                             next one using the usual matrix product.
  ──────────────────────────────────────────────────────────────────────────
   'subtractable'             obj  must be capable of being subtracted. In
                             addition, its elements must be capable of 
                             being subtracted by means of the @diff 
                             operator.
  ──────────────────────────────────────────────────────────────────────────
   'positive'                 obj  must be numeric and each of its elements
                             must be greater than zero.
  ──────────────────────────────────────────────────────────────────────────
   'nonpositive'              obj  must be numeric and each of its elements
                             must be less or equal to zero.
  ──────────────────────────────────────────────────────────────────────────
   'negative'                 obj  must be numeric and each of its elements
                             must be less than zero.
  ──────────────────────────────────────────────────────────────────────────
   'nonnegative'              obj  must be numeric and each of its elements
                             must be greater or equal to zero.
  ──────────────────────────────────────────────────────────────────────────
   'probability'              obj  must be of real values each of them
   'possibility'             being greater or equal to zero and less or
   'proportion'              equal to one.
                            
                             Rationale: to ensure all  obj  elements lie
                             in the interval [0 1] and therefore are
                             suitable to be interpreted as probabilities,
                             fuzzy possibilities or proportions.
                             
                             Although all are required to lie in [0 1],
                             the semantics of probabilities, fuzzy
                             possibilities and proportions differs.
                             
                             A probability expresses the mathematical
                             concept defined by the classical 
                             "probability axioms".
                             
                             A fuzzy possibility does not necessarily 
                             respect the "probability axioms". It 
                             expresses the concept of set membership in
                             the fuzzy logic.
                             
                             A proportion expresses the dimensionless ratio
                             between a subset/part of a given quantity and 
                             the whole quantity.
  ──────────────────────────────────────────────────────────────────────────
   'angle'                    obj  must be of real values each of them
   'radian'                  being greater or equal to zero and less or
                             equal to 2*pi. 
                            
                             Rationale: to express normalised circular
                             variables, so as for the values approaching
                             the upper bound (2*pi) from the left and those 
                             approaching the lower bound (0) from the right
                             to be semantically contiguous.
                             
                             Example of usage: a circular variable  t  with 
                             period  T  satisfies the semantic constraint:
                                check_is( 
                                   mod(  t ,  T  ) / T  * 2*pi ,
                                   ::angle::             
                                )
  ──────────────────────────────────────────────────────────────────────────
   'versor_coord-L1'          obj  must be a matrix of real values each
   '1-partition'             such that:
                                sum( abs( obj ) , 2 ) == 1.
                            
                             Rationale: to ensure  obj  is suitable to be
                             interpreted as a versor in L-1 space (L-1
                             norm is also known as Manhattan distance). 
                             This is also equivalent to requiring the 
                             columns of  obj  to be partitions of 1 (i.e.
                             each column sums to 1).
  ──────────────────────────────────────────────────────────────────────────
   'versor_coord-L2'          obj  must be a matrix of real values each
                             such that:
                                sum(  obj .^2 , 2 ) == 1.
                            
                             Rationale: to ensure  obj  is suitable to be
                             interpreted as a versor in L-2 space (L-2
                             norm is also known as Euclidean distance).
  ──────────────────────────────────────────────────────────────────────────
   'versor_coord-Linf'        obj  must be a matrix of real values each
                             such that:
                                max(  obj  , [] , 2 ) == 1.
                            
                             Rationale: to ensure  obj  is suitable to be
                             interpreted as a versor in L-infinite space
                             (L-infinite norm is also known as Maximum
                             distance).
  ──────────────────────────────────────────────────────────────────────────
   'integer'                  obj  must be numeric and each of its elements
                             must be convertible to an integer without loss
                             of information.
  ──────────────────────────────────────────────────────────────────────────
   'natural'                  obj  must be numeric and each of its elements
   'numel'                   must be convertible to a non-negative integer
                             without loss of information.
                            
                             Rationale: to ensure  obj  can represent the
                             result of a (set of) count(s).
  ──────────────────────────────────────────────────────────────────────────
   'natural_nonzero'          obj  must be numeric and each of its elements
   'index'                   must be convertible to a positive integer
                             without loss of information.
                            
                             Rationale: to ensure  obj  can represent a
                             valid (set of) index(indices).
  ──────────────────────────────────────────────────────────────────────────
   'empty'                   Synonim of:  numel(  obj  )==0
  ──────────────────────────────────────────────────────────────────────────
   'nonempty'                Synonim of:  numel(  obj  )~=0
  ──────────────────────────────────────────────────────────────────────────
   'scalempty'               Synonym of:  numel(  obj  )<=1
  ──────────────────────────────────────────────────────────────────────────
   'scalar'                  Synonym of:  numel(  obj  )==1
   '1-vector'               
  ──────────────────────────────────────────────────────────────────────────
   '2-vector'                Synonym of:  numel(  obj  )==2
  ──────────────────────────────────────────────────────────────────────────
   '3-vector'                Synonym of:  numel(  obj  )==3
  ──────────────────────────────────────────────────────────────────────────
   'n-vectors'                obj  must be a ::cell::-array whose first  
   '[n]-vectors'             element
                                n =  obj {1}
                             is a scalar or an array with the same number
                             of elements of  numel(  obj  )-1 .
                             The number of elements of each object passed
                             as ::cell::-element of   obj (2:end)  must be
                             exactly equal to the (corresponding) value(s)
                             of  n . 
                             Synonym of:
                                cellfun( @numel,  obj (2:end) )  ==  n
  ──────────────────────────────────────────────────────────────────────────
   'n]-vectors'               obj  must be a ::cell::-array whose first  
                             element
                                n =  obj {1}
                             is a scalar or an array with the same number
                             of elements of  numel(  obj  )-1 .
                             The number of elements of each object passed
                             as ::cell::-element of   obj (2:end)  must be
                             less or equal to the (corresponding) value(s)
                             of  n . 
                             Synonym of: 
                                cellfun( @numel,  obj (2:end) )  <=  n
  ──────────────────────────────────────────────────────────────────────────
   '[n-vectors'               obj  must be a ::cell::-array whose first 
                             element 
                                n =  obj {1}
                             is a scalar or an array with the same number
                             of elements of  numel(  obj  )-1 .
                             The number of elements of each object passed
                             as ::cell::-element of   obj (2:end)  must be
                             greater or equal to the (corresponding) 
                             value(s) of  n . 
                             Synonym of:
                                cellfun( @numel,  obj (2:end) )  >=  n
  ──────────────────────────────────────────────────────────────────────────
   'n[-vectors'               obj  must be a ::cell::-array whose first 
                             element
                                n =  obj {1}
                             is a scalar or an array with the same number
                             of elements of  numel(  obj  )-1 .
                             The number of elements of each object passed
                             as ::cell::-element of   obj (2:end)  must be
                             strictly less than the (corresponding)
                             value(s) of  n . 
                             Synonym of:
                                cellfun( @numel,  obj (2:end) )  <  n
  ──────────────────────────────────────────────────────────────────────────
   ']n-vectors'               obj  must be a ::cell::-array whose first 
                             element
                                n =  obj {1}
                             is a scalar or an array with the same number
                             of elements of  numel(  obj  )-1 .
                             The number of elements of each object passed
                             as ::cell::-element of   obj (2:end)  must be
                             strictly greater than the (corresponding)
                             value(s) of  n . 
                             Synonym of:
                                cellfun( @numel,  obj (2:end) )  >  n
  ──────────────────────────────────────────────────────────────────────────
   '{}-numeric'               obj  must be a ::cell::-array whose first 
   'categorical-numeric'     element
                                valid =  obj {1}
                             is an array of admissible numbers and the 
                             following elements   obj (2:end)  are numeric 
                             arrays composed only by admissible numbers.
                             Here, the order in which the categories are 
                             listed in  obj {1} does not have any special 
                             meaning (i.e.  obj {1} is an unordered set).
                            
                             Rationale: to implement the concept of 
                             categorical variable for the special case in 
                             which the admissible categories lie in a given
                             set of numbers.
  ──────────────────────────────────────────────────────────────────────────
   '{}-interval'              obj  must be a ::cell::-array whose first 
   'categorical-interval'    element
                                valid =  obj {1}
                             is an array of admissible ::interval::s and 
                             the following elements   obj (2:end)  are 
                             arrays composed only by admissible 
                             ::interval::s.
                             
                             Here, the order in which the categories are 
                             listed in  obj {1} does not have any special 
                             meaning (i.e.  obj {1} is an unordered set).
                            
                             Rationale: to implement the concept of 
                             categorical variable for the special case in 
                             which the admissible categories lie in a given
                             set of intervals.
                             (Under testing: not yet fully operational)
  ──────────────────────────────────────────────────────────────────────────
   '{}-numstring'             obj  must be a ::cell::-array whose first 
   'categorical'             element
                                valid =  obj {1}
                             is an array of admissible numbers or a 
                             ::cell::-array of ::numstring:: (numeric 
                             arrays or strings) and the following elements 
                                 obj (2:end)
                             are ::numstring:: composed only by admissible
                             numbers or strings. 
                             
                             Here, the order in which the categories are 
                             listed in  obj {1} does not have any special 
                             meaning (i.e.  obj {1} is an unordered set).
                            
                             Rationale: to implement the concept of 
                             categorical variable for the typical case in 
                             which the admissible categories lie in a given
                             set of numbers (e.g. indices) or strings (e.g.
                             textual descriptions).
                             (Under testing: not yet fully operational)
  ──────────────────────────────────────────────────────────────────────────
   '{}-sortable-numstring'    obj  must be a ::cell::-array whose first 
   'sortable-categorical'    element
                                valid =  obj {1}
                             is an array of admissible numbers or a 
                             ::cell::-array of ::numstring:: (numeric  
                             arrays or strings) and the following elements 
                                 obj (2:end)
                             are ::numstring:: composed only by admissible
                             numbers or strings.
                             
                             ::sortable-categorical:: elements differ from
                             ::categorical:: elements because here the
                             order in which the categories are listed in
                              obj {1} is considered. It defines the ranking
                             between categories: they are expected to be
                             provided in  obj {1} sorted in ascending 
                             order.
                            
                             Rationale: to implement the concept of
                             sortable categorical variable for the typical
                             case in which the admissible categories lie in
                             a given set of numbers (e.g. indices) or
                             strings (e.g. textual descriptions).
                             (Under testing: not yet fully operational)
  ──────────────────────────────────────────────────────────────────────────
   '{}-function_handle'      Forthcoming
   '{}-funhandle'           
   '{}-func'                
  ──────────────────────────────────────────────────────────────────────────
   '{}-strfunhandle'         Forthcoming
   '{}-strfunc'             
  ──────────────────────────────────────────────────────────────────────────
   '{}-numfunhandle'         Forthcoming
   '{}-numfunc'             
  ──────────────────────────────────────────────────────────────────────────
   '{}-numstrfunhandle'      Forthcoming
   '{}-numstrfunc'          
  ──────────────────────────────────────────────────────────────────────────
   'scalar_logical'          Synonym of:  numel(  obj  )==1  && ...
                                          islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_binary'           Synonym of:  numel(  obj  )==1  &&  ( ...
                                             islogical(  obj  ) ||  ( ...
                                             isnumeric(  obj  ) &&    ...
                                             all(        obj (:) ==   ...
                                               logical(  obj (:)) ) ) )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_numeric'          Synonym of:  numel(  obj  )==1  && ...
                                          isnumeric(  obj  ) || ...
                                          islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_real'             Synonym of:  numel(  obj  )==1  && ...
                                          isnumeric(  obj  ) || ...
                                          islogical(  obj  ) && ...
                                          ~any(imag(  obj (:)) )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_string'           Synonym of:  numel(  obj  )==1  && ...
                                          ischar(     obj  ) 
  ──────────────────────────────────────────────────────────────────────────
   'scalar_numstring'        Synonym of:  numel(  obj  )==1  && ...
                                          ischar(     obj  ) || ...
                                          isnumeric(  obj  ) || ...
                                          islogical(  obj  )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_realstring'       Synonym of:  numel(  obj  )==1  && ...
                                          ischar(     obj  ) ||   (...
                                          isnumeric(  obj  ) ||    ...
                                          islogical(  obj  ) &&    ...
                                          ~any(imag(  obj (:)) ) )
  ──────────────────────────────────────────────────────────────────────────
   'scalar_positive'          obj  must be scalar, numeric, greater than
                             zero.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_nonpositive'       obj  must be scalar, numeric, less or equal
                             to zero.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_negative'          obj  must be scalar, numeric, less than zero.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_nonnegative'       obj  must be scalar, numeric, greater or
                             equal to zero.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_integer'           obj  must be scalar, numeric and convertible
                             to an integer without loss of information.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_natural'           obj  must be scalar, numeric and convertible
   'scalar_numel'            to a non-negative integer without loss of
                             information.
  ──────────────────────────────────────────────────────────────────────────
   'scalar_natural_nonzero'   obj  must be scalar, numeric and convertible
   'scalar_index'            to a positive integer without loss of
                             information.
  ──────────────────────────────────────────────────────────────────────────
   'vector'                   obj  must be a row or column vector.
  ──────────────────────────────────────────────────────────────────────────
   'row_vector'               obj  must be a row vector.
  ──────────────────────────────────────────────────────────────────────────
   'col_vector'               obj  must be a column vector.
  ──────────────────────────────────────────────────────────────────────────
   'matrix'                  Synonym of:  ndims( obj ) <= 2
  ──────────────────────────────────────────────────────────────────────────
   '3-array'                 Synonym of:  ndims( obj ) == 3
  ──────────────────────────────────────────────────────────────────────────
   '4-array'                 Synonym of:  ndims( obj ) == 4
  ──────────────────────────────────────────────────────────────────────────
   '5-array'                 Synonym of:  ndims( obj ) == 5
  ──────────────────────────────────────────────────────────────────────────
   'interval'                Synonym of:  ::real::                   && ...
                                          size(  obj  , 2 ) == 2     && ...
                                          all( diff( obj ') >= 0 )
                            
                             Rationale: to ensure  obj  represents an
                             interval or a set of intervals.  An interval
                             is represented by its lower and upper
                             endpoints whose values are expressed as a
                             couple of real numbers (a row vector).
                             Intervals cannot have negative length.
  ──────────────────────────────────────────────────────────────────────────
   'sortable_interval'       Synonym of:  ::interval::               && ...
                                          all(diff(reshape(             ...
                                             sortrows( obj ).',[],1     ...
                                          ))>=0)
                            
                             Rationale: to ensure a set of intervals can
                             be sorted.  A total-order criterion is adopted
                             to ensure a sufficient condition in many cases
                             of interest.  The total-order criterion asks
                             all intervals to be disjoint, i.e. to have
                             zero-length intersections. 
  ──────────────────────────────────────────────────────────────────────────
   'o-sortable_interval'     Synonym of:  ::interval::               && ...
                                          all(reshape(diff(             ...
                                             sortrows( obj ),[],1       ...
                                          ))>=0)
                            
                             Rationale: to ensure a set of intervals can
                             be partially sorted by checking they either
                             are disjoint or overlap, without any of them 
                             being strictly included by others (overlap 
                             partial sortability).  A partial ordering 
                             criterion is adopted: two intervals are in
                             ascending order if their lower endpoints are
                             in ascending order (i.e. their values are
                             non-decreasing) and their upper endpoints
                             are in ascending order.  Strict sub-intervals
                             (intervals whose endpoints lie strictly inside
                             a previous interval) do not pass the test.
                             Non-strict sub-intervals could pass the test:
                             e.g intervals having equal upper endpoints 
                             and non-decreasing lower endpoints pass the
                             test. 
  ──────────────────────────────────────────────────────────────────────────
   'sorted_interval'         Synonym of:  ::interval::               && ...
                                          all(diff(reshape(             ...
                                              obj .'                    ...
                                          ),[],1)>=0)
                            
                             Rationale: to ensure a set of intervals to be
                             ascending ordered.  A total-order criterion 
                             is adopted to ensure a sufficient condition
                             in many cases of interest. 
                             The total-order criterion asks all intervals
                             to be disjoint, i.e. to have zero-length 
                             intersections.  
  ──────────────────────────────────────────────────────────────────────────
   'o-sorted_interval'       Synonym of:  ::interval::               && ...
                                          all(reshape(diff( obj ),[],1)>=0)
                            
                             Rationale: to ensure a set of intervals to be
                             ascending partially-ordered.  They can either
                             be disjoint or overlap, without any of them 
                             being strictly included by others (overlap 
                             partial sortability).  A partial ordering 
                             criterion is adopted: two intervals are in
                             ascending order if their lower endpoints are
                             in ascending order (i.e. their values are
                             non-decreasing) and their upper endpoints
                             are in ascending order.  Strict sub-intervals
                             (intervals whose endpoints lie strictly inside
                             a previous interval) do not pass the test.
                             Non-strict sub-intervals could pass the test:
                             e.g intervals having equal upper endpoints and
                             non-decreasing lower endpoints pass the test. 
  ──────────────────────────────────────────────────────────────────────────
   'disjoint_interval'       Synonym of:  ::sorted_interval::        && ...
                                          all(                          ...
                                             diff(reshape( obj ',[],1)) ...
                                          >=0 )
                            
                             Rationale: to ensure a set of sorted intervals
                             to have zero-length intersections.
  ──────────────────────────────────────────────────────────────────────────
   'contiguous_interval'     Synonym of:  ::disjoint_interval::      && ...
                                          all(  obj (2:end,1) ==        ...
                                                obj (1:end-1) )
                            
                             Rationale: to ensure a set of disjoint
                             intervals to be contiguous (i.e. each interval
                             upper endpoint must coincide with the lower
                             endpoint of the subsequent interval of  obj ).

 msg                      ::string::
                          String that contains the message to emit in case of
                          check-failure. It can optionally contain C-language
                          format tags that are replaced by the values
                          specified in subsequent additional arguments.
                          See @fprintf help for more details.


Example of usage

 

 


   s={ 'cell'         , 'string'        , 'cellstring'    , ...
       'cellstring-r' , 'cellstring-1'  , 'cellstring-2'  };
   obj1   = {},         obj2 =   { 'a'  'bc'  },         obj3 =     'a'    ,
   obj4   = { 'a' {} }, obj5 = { { 'a'  'bc'  }  {}  },  obj6 = {{{ 'a' }}},
   objlist = { obj1 , obj2 , obj3 , obj4 , obj5 , obj6 };
   for i=1:numel(s)
      for j=1:numel(objlist)
         obj = objlist{j};
         [answer, msg] = check_is( obj , s{i}, 'oops..');
         fprintf('is obj%d a %s ?: %d (%s)\n', j, s{i}, answer, msg );
      end
   end


   s={ 'same_rows'   , 'same_columns' , 'same_numel' , ...
       'same_length' , 'same_size'    , 'same_ndims' , 'comparable' };
   obj1   = rand(4,4), obj2 = rand(4,4), obj3 = rand(4,2,2),
   obj4   = rand(3,4), obj5 = rand(5,4),
   for i=1:numel(s)
      [answer, msg] = check_is( { obj1, obj2, obj3, obj4, obj5 }, ...
                                s{i},  'oops..'   );
      fprintf('%s : %d (%s)\n', s{i}, answer, msg );
   end


   % ::multipliable::
   % [OK]:
   check_is( { ones(3,2) ones(2,5) ones(5,4) } , 'multipliable' , 'err' )
   % [FAIL]: incompatible size
   check_is( { ones(3,2) ones(7,5) ones(5,4) } , 'multipliable' , 'err' )
   % [FAIL]: multi-array not supported by matrix product
   check_is( { ones(3,2) ones(2,5,3) ones(5,4) } , 'multipliable' , 'err' )


   % ::same_vals::  ,  ::same_valnans::
   obj1  = randn( 4 , 3 );
   obj2  = obj1;
   obj2([3 5]) = [nan -inf];
   % [OK]:
   check_is( { obj1 obj1 obj1 }  , 'same_vals'    , 'err' )
   check_is( { obj1 obj1 obj1 }  , 'same_valnans' , 'err' )
   check_is( { obj2 obj2 obj2 }  , 'same_valnans' , 'err' )
   % [FAIL]: different objects
   check_is( { obj2 obj2 'foo' } , 'same_valnans' , 'err' )
   % [FAIL]: assert( nan ~= nan )
   check_is( { obj2 obj2 obj2 }  , 'same_vals'   , 'err' )


   % ::sorted*:: objects
   a3   = rand( 3 , 2 , 4 )
   cc   = cell( 3 , 2 , 4 );
   c    = 'abcdefghijklmnopqrstuvwxyz';
   for i=1:numel(cc) cc{i}=c(ceil(rand(1,ceil(rand*10))*numel(c))); end
   
   sa3  = sort( a3 , 1 )
   scc  = sort( cc , 1 )
   sa3_ = sort( a3 , 1 , 'descend' )
   scc_ = sort( cc , 1 , 'descend' )
   % [FAIL]: unsorted objects
   check_is(  a3  , 'sorted' , 'err' )
   check_is(  cc  , 'sorted' , 'err' )
   check_is(  a3  , 'sorted-ascend' , 'err' )
   check_is(  cc  , 'sorted-ascend' , 'err' )
   check_is(  a3  , 'sorted-descend' , 'err' )
   check_is(  cc  , 'sorted-descend' , 'err' )
   % [OK]:
   check_is( sa3  , 'sorted' , 'err' )
   check_is( scc  , 'sorted' , 'err' )
   check_is( sa3  , 'sorted-ascend' , 'err' )
   check_is( scc  , 'sorted-ascend' , 'err' )
   check_is( sa3_ , 'sorted-descend' , 'err' )
   check_is( scc_ , 'sorted-descend' , 'err' )
   % [FAIL]: objects sorted in ascending order
   check_is( sa3  , 'sorted-descend' , 'err' )
   check_is( scc  , 'sorted-descend' , 'err' )
   % [FAIL]: objects sorted in descending order
   check_is( sa3_ , 'sorted-ascend' , 'err' )
   check_is( scc_ , 'sorted-ascend' , 'err' )


   % ::finite:: objects
   % [FAIL]: non numeric object
   check_is( { 'a' { 1:3 } } , 'finite' , 'err' )
   % [FAIL]: non numeric object
   check_is( 'finite string' , 'finite' , 'err' )
   % [FAIL]: object containing Inf values
   check_is( [-1 0 1 Inf 3]  , 'finite' , 'err' )
   % [FAIL]: object containing NaN values
   check_is( [-1 0 1 NaN 3]  , 'finite' , 'err' )
   % [OK]: numeric object containing only finite values
   check_is( [-1 0 1 2 3]    , 'finite' , 'err' )
   % [OK]: numeric object containing only finite values
   check_is( []              , 'finite' , 'err' )


   % Versors in L-1 norm: ::versor_coord-L1:: 
   % [FAIL]:non numeric object
   check_is(  { 'a' { 1:3 } }, 'versor_coord-L1' , 'err' )
   % [FAIL]:it is not an L-1 versor
   check_is( [1 3]           , 'versor_coord-L1' , 'err' )
   % [OK]
   check_is( [ pi/4 1-pi/4 ] , 'versor_coord-L1' , 'err' )
   check_is( [1]             , 'versor_coord-L1' , 'err' )
   check_is( [ ]             , 'versor_coord-L1' , 'err' )

   % Versors in L-2 norm: ::versor_coord-L2:: 
   % [FAIL]:non numeric object
   check_is(  { 'a' { 1:3 } }, 'versor_coord-L2' , 'err' )
   % [FAIL]:it is not an L-2 versor
   check_is( [1 3]           , 'versor_coord-L2' , 'err' )
   % [OK]
   check_is( [2 2].^-0.5     , 'versor_coord-L2' , 'err' )
   check_is( [1]             , 'versor_coord-L2' , 'err' )
   check_is( [ ]             , 'versor_coord-L2' , 'err' )

   % Versors in L-infinite norm: ::versor_coord-Linf:: 
   % [FAIL]:non numeric object
   check_is(  { 'a' { 1:3 } }, 'versor_coord-Linf' , 'err' )
   % [FAIL]:it is not an L-2 versor
   check_is( [1 3]           , 'versor_coord-Linf' , 'err' )
   % [OK]
   check_is( [1 0 .1;0 .2 1] , 'versor_coord-Linf' , 'err' )
   check_is( [1]             , 'versor_coord-Linf' , 'err' )
   check_is( [ ]             , 'versor_coord-Linf' , 'err' )


   % ::format_string::
   format = '%g, %d.\n'
   % [OK]
   check_is( format, 'format_string' , 'err' )
   fprintf( 1 , format, pi, -1 )
   format = '%&$'
   % [FAIL]:invalid format string
   check_is( format, 'format_string' , 'err' )
   format = 123
   % [FAIL]:it is not a string
   check_is( format, 'format_string' , 'err' )


   % ::regexp::, regular expressions
   regexp  = '.*'
   % [OK]
   check_is( pattern, 'regexp' , 'err' )
   pattern = '.*['
   % [FAIL]:invalid regular expression string
   check_is( pattern, 'regexp' , 'err' )
   pattern = 123
   % [FAIL]:it is not a string
   check_is( pattern, 'regexp' , 'err' )


   % ::*funhandle::
   % ::cellfunhandle::
   f = @max
   % [OK]    
   check_is( f     , 'funhandle'     , 'err' )
   check_is( 'max' , 'strfunhandle'  , 'err' )
   check_is( f     , 'cellfunhandle' , 'err' )
   f = @(x)quantile( x, 0.2 )
   % [OK]    
   check_is( f     , 'funhandle'     , 'err' )
   check_is( 0.2   , 'numfunhandle'  , 'err' )
   check_is( f     , 'cellfunhandle' , 'err' )
   f = { @max , @median , @min }
   % [FAIL]: expected a single funtion handle     
   check_is( f     , 'funhandle'     , 'err' )
   % [OK]    
   check_is( f     , 'cellfunhandle' , 'err' )
   f = { @max , { @median , @min } }
   % [FAIL]: invalid cell-array of cell-arrays    
   check_is( f     , 'cellfunhandle' , 'err' )
   f = 'max'
   % [FAIL]: it is not a function handle    
   check_is( f     , 'cellfunhandle' , 'err' )


   % ::*-vector::, ::*n-vectors::
   % [OK]    
   check_is( pi              , 'scalar'  ,  'err' )
   check_is( pi              , '1-vector',  'err' )
   % [OK]    
   check_is( { 'foo', 'bar' }, '2-vector',  'err' )
   % [OK]    
   check_is( [2 3 5]         , '3-vector',  'err' )
   % [FAIL]
   check_is( [2 3 5]         , '2-vector',  'err' )

   % [OK]    
   check_is( { 3, [2 3 5] }        , 'n-vectors', 'err' )
   % [OK]    
   check_is( { [1 3], pi, [2 3 5] }, 'n-vectors', 'err' )
   % [FAIL]: [2 3 5] has not 2 elements
   check_is( { [1 2], pi, [2 3 5] }, 'n-vectors', 'err' )
   % [FAIL]: the first element of the cell-array
   %         must be an array
   check_is( { 'foo', pi, [2 3 5] }, 'n-vectors', 'err' )
   % [FAIL]: the first element of the cell-array
   %         must be scalar of have exactly 
   %            numel( obj )-1 
   %         elements
   check_is( {  1:3 , pi, [2 3 5] }, 'n-vectors', 'err' )
   
   % [OK]: numel( [2 3 5] ) <= 3
   check_is( { 3, [2 3 5] }        , '[n-vectors', 'err' )
   % [OK]    
   check_is( { [1 3], pi, [2 3 5] }, '[n-vectors', 'err' )
   % [OK]
   check_is( { [1 2], pi, [2 3 5] }, '[n-vectors', 'err' )
   % [FAIL]: [2 3 5] has less than 4 elements
   check_is( { [1 4], pi, [2 3 5] }, '[n-vectors', 'err' )
   % [OK]
   check_is( { [1 4], pi, [2 3 5] }, 'n]-vectors', 'err' )
   % [FAIL]: pi  has not more than 1 element
   check_is( { [1 4], pi, [2 3 5] }, ']n-vectors', 'err' )
   % [FAIL]: pi  has not less than 1 element
   check_is( { [1 4], pi, [2 3 5] }, 'n[-vectors', 'err' )
   % [OK]
   check_is( { [2 4], pi, [2 3 5] }, 'n[-vectors', 'err' )


See also:
   gettext



Keywords:
   constraints, pre-conditions, post-conditions, checks



Version: 0.13.27

Support

 

 

The Mastrave modelling library is committed to provide reusable and general - but also robust and scalable - modules for research modellers dealing with computational science.  You can help the Mastrave project by providing feedbacks on unexpected behaviours of this module.  Despite all efforts, all of us - either developers or users - (should) know that errors are unavoidable.  However, the free software paradigm successfully highlights that scientific knowledge freedom also implies an impressive opportunity for collectively evolve the tools and ideas upon which our daily work is based.  Reporting a problem that you found using Mastrave may help the developer team to find a possible bug.  Please, be aware that Mastrave is entirely based on voluntary efforts: in order for your help to be as effective as possible, please read carefully the section on reporting problems.  Thank you for your collaboration.

Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Daniele de Rigo

This page is licensed under a Creative Commons Attribution-NoDerivs 3.0 Italy License.

This document is also part of the book:
de Rigo, D. (2012). Semantic Array Programming with Mastrave - Introduction to Semantic Computational Modelling. http://mastrave.org/doc/MTV-1.012-1


Valid XHTML 1.0 Transitional