(!******************************************************
Mosel User Guide Example Problems
=================================
file lcdiv2.mos
```````````````
Recursive function calls.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, 2001, rev. Jun. 2022
*******************************************************!)
model Lcdiv2
function lcdiv(a,b:integer):integer
if a=b then
returned:=a
elif a>b then
returned:=lcdiv(b,a-b)
else
returned:=lcdiv(a,b-a)
end-if
end-function
declarations
A,B: integer
end-declarations
write("Enter two integer numbers:\n A: ")
readln(A)
write(" B: ")
readln(B)
writeln("Largest common divisor: ", lcdiv(A,B))
end-model
|
(!******************************************************
Mosel User Guide Example Problems
=================================
file qsort1.mos
```````````````
'forward' definition of subroutines.
(c) 2008 Fair Isaac Corporation
author: Y. Colombani, 2001, rev. Sep. 2022
*******************************************************!)
model "Quick sort 1"
parameters
LIM=50
end-parameters
forward procedure startqsort(L:array(range) of integer)
(! Equivalent form of declaration:
declarations
procedure startqsort(L:array(range) of integer)
end-declarations
!)
declarations
T:array(1..LIM) of integer
end-declarations
forall(i in 1..LIM) T(i):=round(.5+random*LIM)
writeln(T)
startqsort(T)
writeln(T)
! Swap the positions of two numbers in an array
procedure swap(L:array(range) of integer,i,j:integer)
k:=L(i)
L(i):=L(j)
L(j):=k
end-procedure
! Main sorting routine
procedure qsort(L:array(range) of integer,s,e:integer)
v:=L((s+e) div 2) ! Determine a partitioning value
i:=s; j:=e
repeat ! Partition the array into two subarrays
while(L(i)<v) i+=1
while(L(j)>v) j-=1
if i<j then
swap(L,i,j)
i+=1; j-=1
end-if
until i>=j
! Recursively sort the two subarrays
if j<e and s<j: qsort(L,s,j)
if i>s and i<e: qsort(L,i,e)
end-procedure
! Start of the sorting process
procedure startqsort(L:array(r:range) of integer)
qsort(L,getfirst(r),getlast(r))
end-procedure
end-model
|
(!******************************************************
Mosel User Guide Example Problems
=================================
file qsort2.mos
```````````````
Overloading of subroutines.
(c) 2008 Fair Isaac Corporation
author: Y. Colombani, 2001
*******************************************************!)
model "Quick sort 2"
parameters
LIM=50
end-parameters
forward procedure qsort(L:array(range) of integer)
(! Equivalent form of declaration:
declarations
procedure qsort(L:array(range) of integer)
end-declarations
!)
declarations
T:array(1..LIM) of integer
end-declarations
forall(i in 1..LIM) T(i):=round(.5+random*LIM)
writeln(T)
qsort(T)
writeln(T)
! Swap the positions of two numbers in an array
procedure swap(L:array(range) of integer,i,j:integer)
k:=L(i)
L(i):=L(j)
L(j):=k
end-procedure
! Main sorting routine
procedure qsort(L:array(range) of integer,s,e:integer)
v:=L((s+e) div 2) ! Determine a partitioning value
i:=s; j:=e
repeat ! Partition the array into two subarrays
while(L(i)<v) i+=1
while(L(j)>v) j-=1
if i<j then
swap(L,i,j)
i+=1; j-=1
end-if
until i>=j
! Recursively sort the two subarrays
if j<e and s<j then qsort(L,s,j); end-if
if i>s and i<e then qsort(L,i,e); end-if
end-procedure
! Start of the sorting process
procedure qsort(L:array(r:range) of integer)
qsort(L,getfirst(r),getlast(r))
end-procedure
end-model
|
(!******************************************************
Mosel User Guide Example Problems
=================================
file shsortfct.mos
``````````````````
Combining the 'repeat-until', 'while-do', and
'forall-do' loops. Function returning an array.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Nov. 2005, rev. Sep. 2022
*******************************************************!)
model "Shell sort (fct)"
declarations
N: integer ! Size of array ANum
R: range ! Index range of the arrays
ANum: array(R) of real ! Unsorted array of numbers
ASorted: array(R) of real ! Sorted array of numbers
end-declarations
forward function shsort(ANum: array(R) of real): array(R) of real
N:=50
forall(i in 1..N)
ANum(i):=round(random*100)
writeln("Given list of numbers (size: ", N, "): ")
forall(i in 1..N) write(ANum(i), " ")
writeln
ASorted:= shsort(ANum)
writeln("Ordered array: ")
forall(i in 1..N) write(ASorted(i), " ")
writeln
!***************************************************************
function shsort(ANum: array(R) of real): array(R) of real
returned:=ANum ! Copy the array to be sorted
! (Return the sorted array)
inc:=1 ! Determine the starting increment
repeat
inc:=3*inc+1
until (inc>N)
repeat ! Loop over the partial sorts
inc:=inc div 3
forall(i in inc+1..N) do ! Outer loop of straight insertion
v:=returned(i)
j:=i
while (returned(j-inc)>v) do ! Inner loop of straight insertion
returned(j):=returned(j-inc)
j -= inc
if j<=inc: break
end-do
returned(j):= v
end-do
until (inc<=1)
end-function
end-model
|
(!*******************************************************
Mosel User Guide Examples
=========================
file subrout.mos
````````````````
Simple subroutines.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, 2001, rev. Jun. 2022
*******************************************************!)
model "Simple subroutines"
declarations
a:integer
end-declarations
function three:integer
returned := 3
end-function
function timestwo(b:integer):integer
returned := 2*b
end-function
procedure printstart
writeln("The program starts here.")
end-procedure
procedure hide_a_1
declarations
a: integer
end-declarations
a:=7
writeln("Procedure hide_a_1: a = ", a)
end-procedure
procedure hide_a_2(a:integer)
a:=2
writeln("Procedure hide_a_2: a = ", a)
end-procedure
(! This version generates an error because 'a' is declared twice
procedure hide_a_3(a:integer)
declarations
a: integer
end-declarations
a := 15
writeln("Procedure hide_a_3: a = ", a)
end-procedure
!)
! Corrected version of hide_a_3
procedure hide_a_3(aa:integer)
declarations
a: integer
end-declarations
a := 15
writeln("Procedure hide_a_3: a = ", a, ", aa = ", aa)
end-procedure
printstart
a:=three
writeln("a = ", a)
a:=timestwo(a)
writeln("a = ", a)
hide_a_1
writeln("a = ", a)
hide_a_2(-10)
writeln("a = ", a)
hide_a_3(a)
writeln("a = ", a)
! Subroutines with variable number of arguments
function sumall(Values:...): integer
returned:= sum(i in Values) i.integer
end-function
procedure showint(Optargs:...)
forall(i as counter, v in Optargs)
if v is integer then writeln("arg ", i, ": ", v.integer); end-if
end-procedure
writeln("sum = ", sumall(a, 1, 2, 3, 4, 5))
showint(1.5,0,"abc",true,5)
end-model
|
(!******************************************************
Mosel User Guide Example Problems
=================================
file reftosubr.mos
``````````````````
Subroutine references:
* declaration, type definition
* assignment ('reference to' operator) and invocation
* subroutine returning a subroutine
* error handling
* using mmreflect functionality for retrieving and calling subroutines
(c) 2022 Fair Isaac Corporation
author: S. Heipcke, Mar. 2022
*******************************************************!)
model "subroutine references"
uses "mmsystem", "mmreflect"
declarations
myfct: function(real):real ! Subroutine reference
u: any
realfct=function(real):real ! Subroutine type definition
end-declarations
function div2(r:real):real
returned:=r/2
end-function
myfct:=->div2
writeln("div2(10)=", myfct(10))
u:=->div2
writeln(u) ! Display the internal name of the subroutine
! In order to call 'u' as a subroutine we need to know its type
! (or alternatively, use 'callproc' or 'callfunc' of mmreflect)
writeln("div2(10)=", u.realfct(10))
!**** Typed(=declared) list of subroutines
declarations
L: list of function(real):real
! or equivalently:
! L: list of realfct
end-declarations
L:=[->cos,->sin,->arctan,->abs,->exp,->div2]
forall(i in [-1.0,0.5]) do
write(formattext("i=%3g:", i))
forall(f in L) write(formattext(" %10g", f(i)))
writeln
end-do
!**** Untyped list of functions
L2:=[->cos,->sin,->arctan,realfct(->abs),->exp,->div2]
forall(i in [-1.0,0.5]) do
write(formattext("i=%3g:", i))
forall(f in L2) write(formattext(" %10g", f.realfct(i)))
writeln
end-do
!**** Subroutine as return type in subroutine definition
function choose(name:string):function(real):real
case name of
"cos": returned:= ->cos
"abs": returned:= ->abs
"div": returned:= ->div2
else writeln("Unknown selection '", name, "'")
end-case
end-function
fsel:=choose("cos")
if isdefined(->fsel) then
writeln("cos(1)=", fsel(1))
end-if
! Reset cancels the association
reset(->fsel)
if not isdefined(->fsel) then
writeln("no function selected")
end-if
fsel:=choose("error")
if not isdefined(->fsel) then
writeln("no function selected")
end-if
!****Syntax for calling an element of an array of subroutines with arguments
declarations
arfct:array(string) of function(real):real
! or equivalently:
! arfct:array(string) of realfct
end-declarations
arfct("cos"):= ->cos
arfct("sin"):= ->sin
writeln("cos(1)=", arfct("cos")(1))
!*********************Using mmreflect functionality*********************
!**** Retrieving and calling a function with arguments
declarations
res:any
end-declarations
if findident("div2", u, realfct.id)<>0 then
callfunc(u,res,real(-10))
! Same behaviour as:
! res:= u.realfct(-10)
writeln("Result:", res) ! or: res.real
end-if
!**** Calling a subroutine with a list of arguments
declarations
procrs=procedure(real,real,real)
end-declarations
public procedure mysum(a,b,c:real)
writeln(a+b+c)
end-procedure
asproc(findident("mysum", u, procrs.id))
! Simpler form that results in the same:
! u:= procrs(->mysum)
write("mysum+lsa:" ); callproclsa(u, [1.2,3.4,5.6])
! Same as:
write("mysum:" ); callproc(u, 1.2, 3.4, 5.6)
!**** Retrieving and calling a procedure with arguments
declarations
procstr=procedure(string)
end-declarations
public procedure hello(msg:string)
writeln("hello ", msg)
end-procedure
if findident("hello", u, procstr.id)<>0 then
u.procstr("world") ! Output: 'hello world'
! Same behaviour as:
! callproc(u,"world")
end-if
stat:=findident("hello", u)
if stat.struct=STRUCT_ROUTINE and stat.eltype=0 then
callproc(u, "world") ! Output: 'hello world'
end-if
!**** Retrieving all procedures that match a given name
! Overloaded version with a different signature
public procedure hello
writeln("hello")
end-procedure
declarations
flist: list of any
end-declarations
asproc(findident("hello", flist))
forall(ff in flist,ct as counter)
writeln("Entry ", ct, " is a procedure: ", ff is procedure,
" returns nothing: ", ff.rettype=0, " signature: '", ff.signature, "'")
end-model
|