Initializing help system before first use

Working with unions


Type: Programming
Rating: 3 (intermediate)
Description:
  • uniondef.mos: Defining unions, assignment of values, retrieving type information, compatible union types in subroutine arguments
  • unioninit.mos: Initializing unions from a text file (requires uniondata.dat), displaying type names
  • unionops.mos: 'reference to' operator, accessing unions of array type (exists, create, delcell, reset)
File(s): uniondef.mos, unioninit.mos, unionops.mos
Data file(s): uniondata.dat

uniondef.mos
(!******************************************************
   Mosel User Guide Example Problems
   ================================= 

   file uniondef.mos 
   `````````````````
   Defining unions.
 
   (c) 2021 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2021, rev. Mar. 2022
*******************************************************!)
model "Defining unions"
  uses "mmsystem", "mmxprs"

  declarations
    u: string or real              ! Scalar accepting 'string' or 'real'
    a: any                         ! Entity accepting any type
    L: list of any                 ! List of type 'any'
  end-declarations

 ! Assigning a value determines the type of the union
  u:="a"
  writeln(u, " is string: ", u.typeid = string.id)
  u:=7.5
  writeln(u, " is real: ", u.typeid = real.id)
 ! The preceding line is equivalent to:
  writeln(u, " is real: ", u is real) 

 ! Assignment of basic types results in constants, all others are references
  a:=10
  writeln(a, ":", a.struct=STRUCT_CONST, a is integer)
  a:=date(2020,12,24)
  writeln(a, ":", a.struct=STRUCT_REF, a is date)

 ! Can specify type in assignment to force a particular type
  a.real:=10
  writeln(a, ":", a is real, a is integer)
  a.text:="a text"
  writeln(a, ":", a is text, a is string)

 ! Employ 'create' for types that do not support assignment such as 'mpvar': 
  create(a.mpvar)
  writeln(getsol(a.mpvar), ":", a is mpvar)
 ! ... or to change the type without performing any assignment:
  create(a.linctr)
  writeln(getact(a.linctr), ":", a is linctr)

 !**** Working with structured types
  declarations
    artype = dynamic array(range,string) of real   ! Array type definition
    rectype = public record                        ! Record type definition
      val: real
    end-record
  end-declarations

 !** List and set structures
  L:=[2.5, "abc", {true,false}, [1,2,3]]
  writeln("L=", L)
  writeln(L(1), " is real:", L(1) is real)  
  writeln(L(3), ": is set:", L(3) is set,
    " is set of boolean:", L(3) is set of boolean, 
    " elem. type is boolean:", L(3).eltype = boolean.id) 
  writeln(L(4), ": is list:", L(4).struct=STRUCT_LIST, 
    " elem. type is integer:", L(4).eltype = integer.id)

 !** Defining and accessing arrays
 ! Optional: explicit type specification (req. if type not used in assignment)
 ! create(a.artype); a.array(1,"a").real:= 1.5   
  a.artype(1,"b"):= 1.5; a.artype(3,"b"):= -0.5
  a.array(1,"cde").real:= 7.25;       ! Type has been set by prev. assignments
  writeln(a, " is array:", a is array, 
    " is array of real:", a is array of real)
  writeln(" is of artype:", a is artype, 
    " elem. type is real:", a.eltype = real.id)
  writeln("  dimensions:", a.array.nbdim, " size:", a.array.size)
                                                 
  forall(i in 1..a.array.nbdim)
    writeln("  index", i, "=", a.array.index(i))
 
  with A(I,J)=a.artype do
    forall(i in I,j in J | exists(A(i,j))) writeln("A(",i,",",j,")=",A(i,j))
  end-do

 !** Record structure
  a.rectype.val:=1.25
  writeln(a, " is record:", a is record, " is rectype:", a is rectype)

 !**** Defining a type name for a union of the 4 basic Mosel types
  declarations
    basictype = string or integer or real or boolean
    B: array(range) of basictype     ! Array of union type 'basictype'
  end-declarations

  B(1):="abc"; B(3):=5; B(4):=5.0
  forall(i in 1..3) writeln(B(i), ":", B(i) is string)
  writeln(B(2).struct=STRUCT_NIL)    ! Undefined entry has no structure
  writeln(B(2).typeid=STRUCT_NIL)    ! Undefined entry has no type
  writeln(B(3)=B(4), B(3).integer=B(4).real) 

 !**** Wrapping mechanism for subroutines: compatible union types are accepted 
  procedure dosomething(aunion: any)
    writeln("In procedure: ", aunion)
  end-procedure

  a:=date(2020,12,24)   ! u:=7.5; B(1):="abc"
  dosomething(a)
  dosomething(u)
  dosomething(B(1))
  writeln("B(10) is defined:", isdefined(B(10)))
  dosomething(B(10))    ! Undefined entry 
  dosomething(L)


  procedure dosomething2(aunion: basictype)
    writeln("In procedure 2: ", aunion)
  end-procedure

!  dosomething2(a)      ! This would result in an error since 'date' is not a compatible type
  a:=1.5                ! u:=7.5; B(1):="abc"
  dosomething2(a)
  dosomething2(u)
  dosomething2(B(1))

end-model  

unioninit.mos
(!******************************************************
   Mosel User Guide Example Problems
   ================================= 

   file unioninit.mos 
   ``````````````````
   Initializing unions from a text file.
 
   (c) 2021 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2021
*******************************************************!)
model "Initializing unions"
  uses "mmsystem"

  declarations
    L: list of any                  ! List of type 'any'
    S: set of any                   ! Set of type 'any'
    mytype = text or integer or real or boolean
    B: array(R:range) of mytype     ! Array of union type 'mytype'
    TNAME: array(integer) of text   ! Type names for display
  end-declarations

 ! Reading from text format file
  initializations from "uniondata.dat"
    L  S  B
  end-initializations

  TNAME(integer.id):="integer"; TNAME(real.id):="real"
  TNAME(string.id):="string"; TNAME(text.id):="text"
  TNAME(boolean.id):="boolean"

  writeln("L=", L)
  forall(i in L) writeln("  ", i, ":", i.typeid, " ", TNAME(i.typeid))
  writeln("S=", S)
  forall(i in S) writeln("  ", i, ":", i.typeid, " ", TNAME(i.typeid))
  writeln("B=", B)
  forall(i in R)
    writeln("  B", i, "=", B(i),":", B(i).typeid, " ", TNAME(B(i).typeid)) 

 ! Writing to text format file
  declarations
    x: mpvar                        ! This type does not support 'tostring'
  end-declarations
  L+= [any(x)]
  writeln(L)

  initializations to "unionout.dat"
    L  S  B
  end-initializations

end-model  

unionops.mos
(!******************************************************
   Mosel User Guide Example Problems
   ================================= 

   file unionops.mos 
   `````````````````
   Using the 'reference to' operator and working with 
   unions of array type (exists, create, delcell, reset).
 
   (c) 2022 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2022
*******************************************************!)
model "union operations"
 uses 'mmsystem'

!**** Using 'reference to' with various data structures and types 
 declarations
   anInt: integer
   aList: list of integer
   Dates: array(1..10) of date
   u: any
 end-declarations
 u:= ->anInt              ! u.integer and anInt are the same entity
 u.integer:=10
 writeln("anInt=", anInt) 

 u:= ->aList
 writeln("u=", u)   
 aList:=[1,2,3]
 writeln("u=", u) 

 u:= ->Dates(2)
 u.date:=date("2011-11-11")
 writeln("Dates(2)=", Dates(2)) 

!**** Difference between assignment and reference
 declarations
   A: array(range) of integer
 end-declarations
 A::(2..5)[2,4,6,8]

 writeln("Assignment:")
 u:=A                            ! u holds a copy of A
 writeln("A=", A, "  u=", u) 
 writeln("u is array:", u is array)
 u.array(2).integer:=10          ! Modify 'u'      
 writeln("A=", A, "  u=", u)     ! ('A' unchanged)
 A(5):=10                        ! Modify 'A'
 writeln("A=", A, "  u=", u)     ! ('u' unchanged)

 writeln("Reference to:")
 u:=->A                          ! u is a reference to A
 writeln("A=", A, "  u=", u) 
 writeln("u is array:", u is array) 
 u.array(2).integer:=-1          ! Modify 'u'
 writeln("A=", A, "  u=", u)
 A(5):=25                        ! Modify 'A'
 writeln("A=", A, "  u=", u) 


!**** Working with exists, create, delcell, reset
!**** (typed and untyped versions are equivalent)
 declarations
   B: dynamic array(string,range) of real
 end-declarations
 B("a",2):=2.5; B("a",4):=4.5; B("c",4):=6.5

 writeln("B: nbdim:", B.nbdim, " size:", B.size)
 writeln("   first index:", B.index(1))
 u:=->B
 writeln("u: first index:", u.array.index(1))
 create(u.array("b",4).any)
 create(u.array("b",5).real)
 writeln("B: new size:", B.size, " first index:", B.index(1))
 writeln("test of existence (typed): ", exists(u.array("a",2).real))
 writeln("test of existence (untyped): ", exists(u.array("a",2).any))
 writeln(u.array("a",2).real)

! Removing an entry from a sparse array:
 delcell(u.array("a",2).any)
 delcell(u.array("a",4).real)
 writeln("B: new size:", B.size)
! Resetting (=deleting contents of) the array for sparse or dense arrays:
 reset(u.array)
 writeln("Arrays are empty:", B.size=0 and u.array.size=0)  
 writeln("u is defined:", isdefined(u), " is array:", u is array of real)
! Reset the reference (original array B remains unchanged)
 reset(u)
 writeln("u is defined:", isdefined(u), " is array:", u is array)    

end-model

© 2001-2025 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.