Initializing help system before first use

Switching to mmreflect

Switching from 'xreflect' to 'mmreflect'

The module mmreflect now provides functional equivalence to xreflect (the latter is now deprecated), however, the usage of individual features is different given that the implementation of mmreflect relies on the recently introduced concept of unions and the possibility to work with subroutine references. The following listing compares the implementation of specific programming tasks with these two modules, using the examples from the xreflect manual. It should be noted that the functionality provided by mmreflect is more generic than the cases discussed here which focus on the portion of its functionality that matches what is accessible through xreflect. In particular, by working with unions there are no restrictions on the types or data structures that can be handled through mmreflect.

All functionality of the module xreflect is defined within the namespace xreflect to avoid clashes with functionality of the same name in mmreflect, the following code examples assume that namespace search has been specified for xreflect:

xreflect mmreflect
uses "xreflect"
nssearch xreflect
   
uses "mmreflect"
   

The type 'basicvalue'

The module xreflect defines the type basicvalue for scalar values of Mosel types boolean, integer, real, string, text. The implementation of mmreflect relies on standard Mosel union types that work with all Mosel types and arbitrary data structures. This generic implementation obviously makes it possible for users to define their own union type basicvalue (limited to the five scalar types of xreflect) with access routines matching closely the restricted functionality available through xreflect:

uses "mmreflect"

! Defining a union type 'basicvalue' to hold scalars of basic Mosel types or 'text'
public declarations
  basicvalue = string or integer or real or boolean or text
  bvtrue, bvpi, bvhello: basicvalue
end-declarations

! Defining xreflect-style access routines
function getboolvalue(u: basicvalue):boolean
  returned:=u.boolean
end-function

public function gettype(u: basicvalue):string
  case u.typeid of
    boolean.id: returned:="boolean"
    integer.id: returned:="integer"
    real.id: returned:="real"
    string.id: returned:="string"
    text.id: returned:="string"
    else returned:="unsupported type"
  end-case
end-function

bvtrue := true                 ! Same as:  bvtrue := basicvalue(true)
bvpi := 3.14                   ! Same as:  bvpi := basicvalue(3.14)
bvhello := 'hello'             ! Same as:  bvhello := basicvalue('hello')

writeln("***Compatibility routines:")
writeln('bv value=', bvtrue.boolvalue)     ! Output:  bv value=true
writeln('bv type=', bvtrue.type)           ! Output:  bv type=boolean

However, unless such restrictive typing is indeed required we strongly recommend to switch to working with the generic union type any as shown in the following examples, using standard Mosel functionality and the new set of access routines provided through mmreflect.

The following Mosel code example shows correspondence of standard union type handling for

  • type xreflect∼basicvalue
  • subroutines xreflect∼get[bool|int|real|string|text]value and xreflect∼gettype

xreflect mmreflect
!*** Working with type basicvalue
public declarations
   bvtrue, bvseven, bvpi, bvhello, bvname: basicvalue
end-declarations
bvtrue := basicvalue(true)
bvseven := basicvalue(7)
bvpi := basicvalue(3.14)
bvhello := basicvalue('hello')
bvname := basicvalue(text('my name'))

writeln('boolvalue=', bvtrue.boolvalue)
        ! Output:  boolvalue=true
writeln('is boolean:', bvtrue.type=XREFLECT_TYP_BOOL)
        ! Output:  is boolean:true
writeln('intvalue=', bvseven.intvalue)
        ! Output:  intvalue=7
writeln('is integer:', bvseven.type=XREFLECT_TYP_INT)
        ! Output:  is integer:true
writeln('realvalue=', bvpi.realvalue)
        ! Output:  realvalue=3.14
writeln('is real:', bvpi.type=XREFLECT_TYP_REAL)
        ! Output:  is real:true
writeln('stringvalue=' ,bvhello.stringvalue)
        ! Output:  stringvalue=hello
writeln('is string:', bvhello.type=XREFLECT_TYP_STRING)
        ! Output:  is string:true
writeln('textvalue=', bvname.textvalue)
        ! Output:  textvalue=my name
writeln('is string:', bvname.type=XREFLECT_TYP_STRING)
        ! Output:  is string:true
!*** Working with union types
public declarations
   bvtrue, bvseven, bvpi, bvhello, bvname: any
end-declarations
bvtrue := true
bvseven := 7
bvpi := 3.14
bvhello := 'hello'
bvname := text('my name')

writeln('boolvalue=', bvtrue.boolean)
        ! Output:  boolvalue=true
writeln('is boolean:', bvtrue.typeid=boolean.id)
        ! Output:  is boolean:true
writeln('intvalue=', bvseven.integer)
        ! Output:  intvalue=7
writeln('is integer:', bvseven is integer)
        ! Output:  is integer:true
writeln('realvalue=', bvpi.real)
        ! Output:  realvalue=3.14
writeln('is real:', bvpi is real)
        ! Output:  is real:true
writeln('stringvalue=', bvhello.string)
        ! Output:  stringvalue=hello
writeln('is string:', bvhello is string)
        ! Output:  is string:true
writeln('textvalue=', bvname.text)
        ! Output:  textvalue=my name
writeln('is text:', bvname is text)     ! is text:true
writeln('is string:', bvname is string) ! is string:false

Accessing scalars, retrieving type and structural information

The subroutines of xreflect search for model entities by their name. With mmreflect the entities are first retrieved into a union via a call to findident and all subsequent operations are carried out directly on this union.

The following Mosel code example shows mmreflect correspondence for

  • subroutines xreflect∼getscalarvalue, xreflect∼setscalarvalue, xreflect∼getvaluetype, xreflect∼getstructtype, and xreflect∼getindexsettypes

xreflect mmreflect
public declarations
  mystr: string
  myarr: array(range) of real
  myset: set of integer
  mylst: list of integer
  mydate: date
  mybool=true
  myrng=1..5
end-declarations


!*** Retrieving and setting scalar values
mystr := 'hello'
writeln('mystr=',getscalarvalue('mystr'))
                           ! Output:  myvar=hello
setscalarvalue('mystr',basicvalue('world'))
writeln('mystr=',mystr)    ! Output:  myvar=world

!*** Accessing structural information

writeln('myvar=', getvaluetype('mystr'))
        ! Output:  mystr=string
writeln('mystr struct is variable:',
  getstructtype('mystr')=XREFLECT_STR_REF)
        ! Output:  mystr struct is variable:true

writeln('myarr=', getvaluetype('myarr'))
        ! Output:  myarr=real
writeln('myarr struct is array:',
  getstructtype('myvar')=XREFLECT_STR_REF)
        ! Output:  mystr struct is variable:true

writeln('myset=', getvaluetype('myset'))
        ! Output:  myset=integer
writeln('myset struct is set:',
  getstructtype('myset')=XREFLECT_STR_SET)
        ! Output:  mystr struct is variable:true

writeln('myrng=', getvaluetype('myrng'))
        ! Output:  myrng=integer
writeln('myrng struct is set:',
  getstructtype('myrng')=XREFLECT_STR_SET)
        ! Output:  mystr struct is variable:true

writeln('mydate=', getvaluetype('mydate'))
        ! Output:  mydate=unsupported
writeln('mydate struct is variable:',
  getstructtype('mydate')=XREFLECT_STR_REF)
        ! Output:  mydate struct is variable:true

writeln('mybool=',getvaluetype('mybool'))
        ! Output:  mybool=boolean
writeln('mybool struct is const:',
  getstructtype('mybool')=XREFLECT_STR_CONST)
        ! Output:  mystr struct is variable:true

writeln('mylst=', getvaluetype('mylst'))
        ! Output:  mylst=integer
writeln('mylst struct is unsupported:',
  getstructtype('mylst')=XREFLECT_STR_UNSUPPORTED)


!*** Index set type information
public declarations
  myarr2: array(set of integer,set of string) of real
end-declarations
writeln('index set types=',
  getindexsettypes('myarr2'))
      ! Output:  index set types=[`integer',`string']
   
public declarations
  mystr: string
  myarr: array(range) of real
  myset: set of integer
  mylst: list of integer
  mydate: date
  mybool=true
  myrng=1..5
  a: any
end-declarations

!*** Retrieving and assigning scalar values
mystr := 'hello'
asproc(findident('mystr', a))
writeln('mystr=',a)        ! Output:  mystr=hello
a := 'world'
writeln('mystr=',mystr)    ! Output:  mystr=world

!*** Accessing structural information
res:=findident('mystr', a)
writeln(testtype(res,STRUCT_REF+string.id))  ! Output:  true
writeln('mystr=string: ', a is string)
        ! Output:  mystr=string: true
writeln('mystr struct is variable:', a.struct=STRUCT_REF)
        ! Output:  mystr struct is variable:true

asproc(findident('myarr', a))
writeln('myarr=real: ', a.eltype=real.id)
        ! Output:  myarr=real: true
writeln('myarr struct is array:', a.struct=STRUCT_ARRAY)
        ! Output:  myarr struct is array:true

asproc(findident('myset', a))
writeln('myset=integer: ', a.eltype=integer.id)
        ! Output:  myset=integer: true
writeln('myset struct is set:', a.struct=STRUCT_SET)
        ! Output:  myset struct is set:true

asproc(findident('myrng', a))
writeln('myrng=integer: ', a.eltype=integer.id)
        ! Output:  myrng=integer: true
writeln('myrng struct is set:', a.struct=STRUCT_SET)
        ! Output:  myrng struct is set:true

asproc(findident('mydate', a))
writeln('mydate=date: ', a.typeid=date.id)
        ! Output:  mydate=date: true
writeln('mydate struct is variable:', a.struct=STRUCT_REF)
        ! Output:  mydate struct is variable:true

asproc(findident('mybool', a))
writeln('mybool=boolean: ', a.eltype=boolean.id)
        ! Output:  mybool=boolean: true
writeln('mybool struct is const:', a.struct=STRUCT_CONST)
        ! Output:  mybool struct is const:true

asproc(findident('mylst', a))
writeln('mylst=integer: ', a.eltype=integer.id)
        ! Output:  mylst=integer: true
writeln('mylst struct is list:', a.struct=STRUCT_LIST)
        ! Output:  mylst struct is list:true

!*** Index set type information
public declarations
  myarr2: array(set of integer,set of string) of real
  lst: list of integer
end-declarations
asproc(findident('myarr2', a))
forall(i in 1..a.array.nbdim) lst+=[a.array.index(i).eltype]
writeln('index set types=',lst)
        ! Output:  index set types=[1,3]

Accessing sets

Since the set access routines in mmreflect work on unions, the type of the set must be specified when accessing the corresponding set.

The following Mosel code example shows mmreflect correspondence for

  • subroutines xreflect∼addsetelement, xreflect∼finaliseset, xreflect∼checksetcontains, xreflect∼getsetelements, and xreflect∼copysetelements

xreflect mmreflect
public declarations
  dlst: list of basicvalue
end-declarations

myset := {1,3}






addsetelement('myset', basicvalue(4))
writeln('myset=', myset)    ! Output:  myset={1,3,4}

finaliseset('myset')        ! No further changes
!addsetelement('myset',basicvalue(6))  ! Error
writeln('contains 6=', checksetcontains('myset',
  basicvalue(6)))           ! Output:  contains 6=false

writeln('myset=', getsetelements('myset'))
                            ! Output:  myset=[1,3,4]
dlst:=[]
copysetelements('myset', dlst)
writeln(dlst)               ! Output:  [1,3,4] 
   
public declarations
  dlst: list of any
  mysettype=set of integer
end-declarations
myset := {1,3}
asproc(findident('myset', a))
if a is not mysettype then
! Alternatively:
!if findident('myset', a, mysettype.id)=0 then
  writeln("Unexpected type"); exit(1)
end-if
a.mysettype+={4}
writeln('myset=', myset)    ! Output:  myset={1,3,4}

finalise(a.set)             ! No further changes
!a+={6}                     ! Results in an error
writeln('contains 6=', 6 in a.mysettype)
                            ! Output:  contains 6=false

writeln('myset=', a)
                            ! Output:  myset={1,3,4}
dlst:=[]
dlst:=list(a.set)
writeln(dlst)               ! Output:  [1,3,4] 
   

Accessing arrays

When accessing arrays via mmreflect functionality the type of array elements needs to be stated, with the exception of the routines delcell, exists, and create for which it is sufficient to state the generic type any.

The following Mosel code example shows mmreflect correspondence for

  • Subroutines xreflect∼arrayentryexists, xreflect∼getarrayentry, xreflect∼setarrayentry, xreflect∼getindexsetelements, xreflect∼copyindexsetelements, xreflect∼delarray, and xreflect∼delarrayentry

xreflect mmreflect
public declarations
  myarr4: dynamic array(range,set of integer) of real
  dlst: list of basicvalue
end-declarations

myarr4(1,100) := 5.0
myarr4(1,101) := 5.1
myarr4(2,101) := 5.2


writeln('exists(2,100)=', arrayentryexists('myarr4',
  [basicvalue(2),basicvalue(100)]))
        ! Output:  exists(2,100)=false

!*** Accessing array elements
writeln('myarr4(2,101)=', getarrayentry('myarr4',
  [basicvalue(2),basicvalue(101)]))
        ! Output:  myarr4(2,101)=5.2
setarrayentry( 'myarr4', [basicvalue(1),
  basicvalue(101)], basicvalue(17.5) )
writeln('myarr4(1,101)=', myarr4(1,101))
        ! Output:  myarr4(1,101)=17.5





setarrayentry( 'myarr4', [basicvalue(3),
  basicvalue(100)], basicvalue(2.0) )
writeln('myarr4_i1=', getindexsetelements('myarr4',1))
        ! Output:  myarr4_i1=[1,2,3]

copyindexsetelements('myarr4',1,dlst)
writeln(dlst)          ! Output:  [1,2,3]

delarrayentry('myarr4',
  [basicvalue(1),basicvalue(101)])
writeln('exists(1,101)=', arrayentryexists('myarr4',
  [basicvalue(1),basicvalue(101)]))
        ! Output:  exists(1,101)=false

delarray('myarr4')
writeln('size=', myarr4.size)
        ! Output:  size=0
   
public declarations
  myarr4: dynamic array(range,set of integer) of real
  dlst: list of any
end-declarations

myarr4(1,100) := 5.0
myarr4(1,101) := 5.1
myarr4(2,101) := 5.2

stat:= findident('myarr4', a)
if not testtype(stat, STRUCT_ARRAY) then exit(1); end-if
writeln('exists(2,100)=', exists(a.array(2,100).any))
        ! Output:  exists(2,100)=false

!*** Array element access using standard union handling
writeln('myarr4(2,101)=', a.array(2,101).real)
        ! Output:  myarr4(2,101)=5.2
a.array(1,101).real := 17.5
writeln('myarr4(1,101)=', myarr4(1,101))
        ! Output:  myarr4(1,101)=17.5
!*** Alternative forms using array element access routines
setarrval(a, 7.5, 1,101)
getarrval(myarr4, u, 1,101)
writeln('myarr4(1,101)=', u) ! Output:  myarr4(1,101)=7.5
setarrval(myarr4, 2.5, [1,101])
getarrval(a, u, [1,101])
writeln('myarr4(1,101)=', u) ! Output:  myarr4(1,101)=2.5

a.array(3,100).real := 2.0
writeln('myarr4_i1=', a.array.index(1))
        ! Output:  myarr4_i1=1..3

dlst:= list(a.array.index(1))
writeln(dlst)           ! Output:  [1,2,3]


delcell(a.array(1,101).any)
writeln('exists(1,101)=', exists(a.array(1,101).real))
        ! Output:  exists(1,101)=false


reset(a.array)     ! Same as:  delcell(a.array)
writeln('size=', myarr4.size)
        ! Output:  size=0  

Array iterators

The module mmreflect defines the type iterator that can be used in a similar way as the type arrayiterator of xreflect for enumerating the entries defined for a Mosel array.

The following Mosel code example shows mmreflect correspondence for

  • type xreflect∼arrayiterator
  • subroutines xreflect∼gethasvalue, xreflect∼getindices, xreflect∼getvalue, xreflect∼iteratorinit, and xreflect∼nextvalue

xreflect mmreflect
public declarations
  myarray:dynamic array(range,set of string) of real
end-declarations
! Populate our example data-set
myarray(100,'fred') := 100.1
myarray(100,'jim') := 101.5
myarray(101,'fred') := 215.7

! Iterate through array entries using the arrayiterator
declarations
  it:arrayiterator
end-declarations

iteratorinit(it, 'myarray')

writeln(it.hasvalue)    ! Output:  false (before start)
while (nextvalue(it)) do
  write('myarray(', it.indices)
        ! Index tuple: list of basicvalue
  writeln(') = ', it.value)


end-do
  ! Output:
  !  myarray([100,fred]) = 100.1
  !  myarray([100,jim]) = 101.5
  !  myarray([101,fred]) = 215.7
writeln(it.hasvalue)   ! Output:  false (after end)

   
public declarations
  myarray:dynamic array(range,set of string) of real
end-declarations
! Populate our example data-set
myarray(100,'fred') := 100.1
myarray(100,'jim') := 101.5
myarray(101,'fred') := 215.7

! Iterate through array entries using the iterator
declarations
  it:iterator
  u:any
end-declarations
inititer(it, myarray)
writeln(it.status)               ! Output:  0 (before start)
writeln(exists(myarray(it)))     ! Output:  false
while (nextcell(it)) do
  write('myarray(', it.indices)  ! Index tuple: list of any
  writeln(') = ', myarray(it))
!*** Alternative form: using getarrval with iterator
!  getarrval(myarray,u,it.indices)
!  write(') = ',u)
end-do
  ! Output:
  !  myarray([100,fred]) = 100.1
  !  myarray([100,jim]) = 101.5
  !  myarray([101,fred]) = 215.7
writeln(it.status)               ! Output:  2 (after end)
writeln(exists(myarray(it)))     ! Output:  false  

Accessing subroutines

The module mmreflect generalizes the handling of subroutines to include subroutine arguments and it also adds functionality for handling functions.

The following Mosel code example shows mmreflect correspondence for

  • subroutines xreflect∼findproc and xreflect∼callproc

xreflect mmreflect
!*** Calling a procedure
public procedure myproc
  writeln('hello world');
end-procedure
callproc('myproc')      ! Output:  hello world

public procedure myproc1
  writeln('hello');
end-procedure
public procedure myproc2(xyz:string)
  writeln('world: ', xyz);
end-procedure
! Subroutines with arguments are not supported


!*** Checking for a subroutine




writeln('findproc(myproc1)=', findproc('myproc1'))
        ! Output:   findproc(myproc1)=true
! Calling the subroutine
callproc('myproc')      ! Output:  hello world

writeln('findproc(myproc2)=', findproc('myproc2'))
! myproc2 will not be found as it takes an argument
        ! Output:   findproc(myproc2)=false




!*** Functions are not supported
public function myfunc: text
  returned:=text('-')*10
end-function
writeln('findproc(myfunc)=', findproc('myfunc'))
        ! Output:   findproc(myfunc)=false   
!*** Calling a procedure
public procedure myproc
  writeln('hello world');
end-procedure
callproc('myproc')       ! Output:  hello world

public procedure myproc1
  writeln('hello');
end-procedure
public procedure myproc2(xyz:string)
  writeln('world: ', xyz);
end-procedure
! Calling a subroutine with an argument
callproc('myproc2', 'my text')  ! Output:  world: my text

!*** Checking for a subroutine
declarations
  srtype=procedure   ! Type definition for 'findident'
  srtype2=procedure(string)
end-declarations
writeln('findproc(myproc1)=',
  getstruct(findident('myproc1',a,srtype.id))=STRUCT_ROUTINE)
        ! Output:   findproc(myproc1)=true
! Calling the subroutine that has been retrieved
callproc(a)              ! Output:  hello world
writeln('findproc(myproc2)=',
  getstruct(findident('myproc2',a,srtype.id))=STRUCT_ROUTINE)
        ! Output:   findproc(myproc2)=false
writeln('findproc(myproc2)=',
  getstruct(findident('myproc2',a,srtype2.id))=STRUCT_ROUTINE)
        ! Output:   findproc(myproc2)=true

!*** Support for functions
public function myfunc: text
  returned:='-'*10
end-function
writeln('findproc(myfunc)=',
  testtype(findident('myfunc',a), STRUCT_ROUTINE+text.id))
        ! Output:   findproc(myfunc)=true
declarations
  res: any
end-declarations
callfunc(a,res)
writeln("Result=", res)	 ! Output:  Result=---------- 


© 2001-2024 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.