SDSU CS 662: Theory of Parallel Algorithms
SR - Sequential Aspects

[To Course Home Page]
San Diego State University -- This page last updated February 1, 1996
----------

Contents of SR - Sequential Aspects Lecture

  1. Sequential Part of SR
    1. Types, Variables and Assignments
      1. Some Basics
      2. Basic Types
      3. Compound Types
        1. Arrays
      4. Bounds of Arrays
        1. Enumerations
        2. Records
        3. Pointers
        4. Pointers Continued
      5. Expressions
      6. Basic Input/Output
      7. Type Equivalence
      8. Blocks
    2. Sequential Control
      1. If
      2. Do
      3. For-All
      4. Nested Loops
    3. Procedures
      1. Declarations
      2. Parameter Passing
      3. Op and Proc
      4. Operation Types
      5. Operation Capabilities
    4. Resources and Globals
      1. Extending Resources
      2. Globals

Sequential Part of SR

Hello World Example

resource hello()
	write("Hello World")
end

Place code in file.sr and compile with command:

sr file.sr


Example of IO & Procedure Call

resource Example()
	procedure Test(v: int) returns r: int
		r := 2*v
	end

	var n: int
	writes("enter a positive integer: ")
	read(n)
	write("two times:", n, "is", Test(n))
end


Types, Variables and Assignments

Some Basics

Identifiers are sequences of letters, digits, and underscores.

First character must be a letter

Case sensitive

Newline or semicolons can be used to terminate declarations, statements, or expressions

resource EndLines()

	var Nice:	int
	var Try:	int;
	var Dad:	int;
	
	Nice := 5 +
					3	#Nice is 8
	
	Try  := 5
				+ 3   #Try is 5
	
	Dad  := 5 \
					+ 3; #Dad is 8
	
	/* This is also a comment
	*/
	
end



Basic Types

resource BasicTypes()

	var FirstInt:	int	
	var SecondReal:	real	:=	4.3
	var ThirdChar:	char	:= 'a'
	var FourthString:	string[20]	:= "Hi Mom"
	var IsThisRight:	bool	:= true
	var AreWeDone:	bool	:= false

	var Guess := 3	#type deduced from value

	const Fixed: int := 3	#needs an initial value
	const Tight: float := 2* SecondReal


	IsThisRight := true and 
						(false or not AreWeDone)

	AreWeDone := IsThisRight xor AreWeDone
	#operators are short-circuited

	SecondReal:= FirstInt + 2  #convert int to real

	FirstInt := 3.2;  			#compile error

end

Compound Types

Arrays

resource ArrayTypes()

	var FirstArray[10]:  int  #first index = 1

	FirstArray[12] := 3		
		#runtime error: illegal subscript [12] of array with bounds [1:10]

	var SecondArray[5,3]: real #2 dimensional

	var ThirdArray[-2: 5]: bool #first index is -2

	var Me[3]: int := (3, 2, 1)	
		#initialize array with constructor

	var You[10]: int := ([6] 0, [4] 1)

	var Trouble[10]: int := ([6] 0, [3] 1)
		#runtime error: size mismatch

	

	type Age = int

	var Old: Age := 95;

	type AnArrayOfInt = [0:100] int

	var WhatIsThis: AnArrayOfInt



end
	


Array Slices

resource SlicedToast()

	var BigArray[1:10, 1:10]: int := ([100] 0)

	var SmallArray[1:10]: int := ([10] 1)

	SmallArray[2:5] := BigArray[4,5:8]

	BigArray[5,*] := SmallArray[*]

end

Forms of a Slice

Array[K:J] results in Array[K], Array[K+1], ..., Array[J]

Array[K:*] results in Array[K], ..., to end of array

Array[*:J] results in start of the array to Array[J]

Array[*] results in entire array


Restrictions Apply

A slice can not appear as operand of the swap operator

Slices can not be passed as reference parameters

Strings can not be assigned to a slice of strings if their maximum lengths differ

Assignments can be made to a single slice if an array, unless it is either sliced again or subscripted after being sliced


Bounds of Arrays

lb is built-in function which returns lower bound of the first dimension of an array

ub returns upper bound of the first dimension of an array

var A[10]: int

var Q['a':'z', -2:4]


lb(A)                   1                       lb(Q,1)                 'a'                     
ub(A)                   10                      lb(Q,2)                 -2                      
lb(Q)                   'a'                     ub(Q,2)                 4                       
ub(Q)                   'z'                     ub(A,1)                 10                      





Enumerations

resource Count()

	type color = enum(red, blue, yellow)

	type StopLight = enum(red, yellow, green)
		#Error, can not repeat enum literal

	type Why = enum(do, this)
		#Error, can not use reserved words (do)


	var flower: color := blue

	var CollegeAve: StopLight = red


	write(pred(flower))		#prints 	0

	write(high(StopLight))	#prints	2

	write(min(blue,yellow))	#prints	1

end

Enumerations Functions

max maximum of N enumeration literals

min minimum of N enumeration literals

succ successor of an enumeration literal

pred predecessor of an enumeration literal

low smallest element of an enumeration type

high largest element of an enumeration type


Records

resource recordThis()

	var Me: rec(name: string[10]; age: int)

	Me.name := "Roger"

	Me.age := 15



	type dims = rec( height, weight: real)

	type person = rec( 	name: string[10];
				measurements: dims;
				grade: char)


	var Test: dims := dims(132.2,  52.1)

	var You: person := 
			 person("Sam", dims(21.3, 2.9), 'A')

	You.measurements.height := 34.2

	write(You.name)

end


Pointers


resource GetToThePoint()

	var intPtr: ptr int

	var Target: int := 5

	intPtr := @Target  #@ - address of operator

	intPtr^ := intPtr^ + 1  #^ dereference operator

	Target := intPtr^


	type Simple = rec(A, B: int)

	var RecordPointer: ptr Simple

	RecordPointer := new(Simple)

	RecordPointer^.A := 10

	free(RecordPointer)


	var DoublePointer: ptr ptr real

	DoublePointer := new(ptr real)

	DoublePointer^ := new(real)

	DoublePointer^^ := 5.5

	write(DoublePointer^^)

end

Pointers Continued


Pointers can be assigned to, copied, and dereferenced

null is used to indicate a pointer value that points to no valid object

Any

resource WhatIsThis()

	type Simple = rec(A, B: int)

	var GenericPtr: ptr any


	GenericPtr := new(int)

	GenericPtr := new(real)

	GenericPtr := new(Simple)

	GenericPtr^.A := 5  #Compile error


	var SimplePtr: ptr Simple

	SimplePtr := GenericPtr

	SimplePtr^.A := 5

end
	

Pointers of type any can only be assigned to and copied


Expressions

resource A_Bit_Like_C()

	var J, K, L: int

	J := 1;  K := 2;  L := 3;

	J := ++K			#preincrement K = 3, J = 3

	J := L++			#postincrement L = 4, J = 3

	J += 1				#same as J := J + 1

	K :=: L			#interchange K and L


	J := K :=: L		#what does this do?

end
	



Basic Input/Output

read(variable, variable,...)

Reads standard input

Values be separated by white space

Read returns number of values successfully read

Read returns EOF if the end-of-file is reached before any values are found




write(variable, variable, ...)

Writes variables to standard output, separated by space

Places return after last variable

writes(variable, variable, ...)

Same as write, but no return at end

Type Equivalence

NAME EQUIVALENCE

Two variables are same type if they have the same user defined or built in type name or appear on the same declaration

STRUCTURAL EQUIVALENCE

Two variables are the seam type if they have the same structure

One has to determine underlying structure

Time consuming if have types of types of types....

type t = [1:20] int;

var a[1:20], b[1:20]: int;

var c[1:20]: int;

var d: t;

var e, f: rec( a: int; b: t );

Name Equivalent
	a and b,    
	e and f,   
	d and e.b and f.b  

Structural Equivalent   
	a, b, c, d, e.b , f.b   



Blocks

resource Nested()

	var Who: int := 5;
	
	begin
	
		var Where: int;
		
		Where := Who;			#Where = 5
		
		var Who: int := 10;
		
		Where := Who;			#Where = 10
		
		begin
		
			var Who: real := 4.4;
			
			Where := Who;  		#illegal
			
		end;

	Where := Who + 1;		#OK

	end

#Where does not exist here

end


Sequential Control


If

if a < b 	-> write("Bad Value")
fi


if a < b 	-> write("Bad Value")
[] else 	-> write("Good Value")
fi

if A < 10 -> B := 1
[] A > 32 -> B := 2
[] A = 60 -> B := 3
[] A > 50 -> B := 4
[] else   -> B := 5
if

The order in which the guards are evaluated is nondeterministic

Do

do X < Y -> Y := Y - X
[] Y < X -> X := X - Y
od

Repeat do until all guards evaluate to false

The order in which the guards are evaluated is nondeterministic


For-All

fa x := 1 to 50  -> 
	write(x) 
af


fa x := 50 downto 1 -> 
	write(x) 
af


fa x := 1 to 50 by 2 -> 
	write(x) 
af


fa x := 1 to 50 st A[x] < 10 -> 
	write(x) 
af


Nested Loops


fa x := 1 to 10, y := 1 to x -> 
	write(x, y)
af

is the same as:

fa x := 1 to 10 ->
	fa y := 1 to x ->
		write(x, y)
	af
af

skip

Do nothing, go on to next statement

stopstop(expr)

Stop program and return value of expr to operating system

Return 0 if expr is not given

exit

Terminates the smallest enclosing loop

next

Go to next iteration of enclosing loop


Procedures


Declarations

procedure factorial(x: int)returns result: int
	if x <= 1 -> result := x
	[] x >  1 -> result := x * factorial(x-1)
	fi
end

procedure LongList(a, b, c : int; d : int)
	# Your code here
end



Parameter Passing

val	copy in	default 

res copy out

var copy in and out

ref pass by address

return values are passed by copy

resource testParameter()
	
	procedure test(ParamType x: int)
		writes(x, ",')
		x := 5
	end

	var n := 10
	test(n)
	write(n)
end


ParamType	Output 
val 		10, 10
res 		-808464433, 5
var 		10, 5
ref		10, 5



More Procedures

resource main()

	procedure sort(ref a[*,*]: int)
		fa k := lb(a) to ub(a) -1,
			j := k + 1 to ub(a) st 
			a[j-1] > a[j] -> a[j-1] :=: a[j]
		af
	
		return				#ends function call
	
		write("never reach here")

	end sort

	var x[1:20] : int
	var y[40 : 100] : int
	var z['a' : 'k'] : int

	# code to initialize x, y, z

	sort(x)

	sort(y)

	call sort(z)			#call is optional

end main


Op and Proc

Forward Declaration of Functions

op is the signiture of the procedure

proc is body of the procedure

procedure Test(v: int) returns r: int
		r := 2*v
end

Short for:

op Test(int) returns r: int

proc Test(v) returns r
		r := 2*v
end

resource main()
	op factorial(x: int) returns result : int
	op sum(int) return int
	
	write(factorial(3))
	write(fact(5))
	
	proc factorial(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x*factorial(x-1)
		fi
		end factorial
	
	proc sum(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x + sum(x-1)
		fi
	end sum
end

Operation Types

resource main()

	optype f(int) returns int
	op factorial: f
	op sum: f
	
	write(factorial(3))
	write(sum(5))
	
	proc factorial(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x*factorial(x-1)
		fi
	end factorial
	
	proc sum(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x+sum(x-1)
		fi
	end sum
	
end main

Operation Capabilities

Pointers to Functions
resource main()
	optype f(int) returns int
	op factorial: f
	op sum: f
	
	procedure Tricky(var X: cap f)
		var test: int
		read(test)
	
		if test < 10 -> X := factorial
		[] test > 10 -> X := sum
		fi
	end
	
	var What: cap f		#Pointer to a function
	
	
	Tricky(What)
	
	write(What(4))
	
	proc factorial(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x*factorial(x-1)
		fi
	end
	
	proc sum(x) returns result
		if x <= 1 -> result := x
		[] x > 1 -> result := x+sum(x-1)
		fi
	end
	
end

Resources and Globals


resource Stack
	type result = enum(OK, OVERFLOW, UNDERFLOW)
	op push(item: int) returns r: result
	op pop(res item: int) returns r: result

body Stack(size: int)
	var store[1:size]: int
	var top: int := 0
	
	proc push(item) returns r
	if top < size -> 
		store[++top] := item
		r := OK
	[] top = size -> 
		r := OVERFLOW
	fi
	end
	
	proc pop(item) returns r
	if top > 0 ->
		item := store(top--)
		r := OK
	[] top = 0 -> 
		r := UNDERFLOW
	end
	
	begin				#Optional initialization code
		write("Start up Stack")
	end
	
	final  				#Optional final code
		write("End Stack")
	end
end

Using a Resource


resource StackUser()
	import Stack			#Stack from previous page
	
	var x: Stack.result
	var s1, s2: cap Stack
	
	s1 := create Stack(10)
	s2 := create Stack(20)
	
	s1.push(4) 
	s1.push(12)
	s2.push(3)
	
	if (x := s1.pop(y)) = OK -> write(y)
	[] else -> write("Bad return call")
	fi
	
	final
		destroy s1
		write("Done with user")
	end
end

Output

Start up Stack

Start up Stack

12

End Stack

Done with user


More Resources
Full foo
resource foo
body foo(x, y: int)
	write("Input is:", x, y)
end foo

Short foo
resource foo(x, y: int)
	write("input is:", x, y)
end foo

Using foo

resource DoIt()
	import foo
	var X: cap foo

	X := create foo(2,5)
end

Bank Example
resource BankAccount
	op transaction(amount: real)
	op getBalance() returns x: real
	#No variables in spec

body BankAccount(initialDeposit: real)

	var balance: real

	proc getBalance() returns x 
		x := balance
	end getBalance
		#Can't use balance for name of proc and resource variable

	proc transaction(amount)
		balance := balance + amount
	end transaction

	begin
		balance := initialDeposit
	end

end BankAccount



resource test()

	import BankAccount
	var Mine: cap BankAccount

	Mine := create BankAccount(10)
	write(Mine.getBalance())
end     


Extending Resources

Declaration Inheritance

resource BankAccount
	#Same as previous page
end BankAccount

resource CheckingAccount
	extend BankAccount
	op check(amount: real)

body CheckingAccount(initialDeposit: real)

	var balance: real

	proc getBalance() returns x 
		x := balance
	end getBalance

	proc transaction(amount)
		balance := balance + amount
	end transaction

	proc check(amount)
		transaction(- amount)
	end check

	begin
		balance := initialDeposit
	end
end

resource test()
	import CheckingAccount
	var Mine: cap CheckingAccount
	Mine := create CheckingAccount(10)
	write(Mine.getBalance())
end   

Multiple Inheritance
resource left
	op GetSam(X: int)
body left()
	proc GetSam(X)
		write("Left")
	end
end

resource right
	op GetSam(X: int)
body right()
	proc GetSam(X)
		write("Right")
	end
end

resource bottom
	extend left, right
body bottom()
	proc GetSam(X)
		X := 5
	end
end

resource test
	import bottom
	write("Done")
end

Compile Error

line 10 (extended by bottom): fatal: duplicate identifier: GetSam

line 10 (extended by test): fatal: duplicate identifier: GetSam


Globals


global Characters
	const TAB := '\t'
	const CR	:= 'r'
end

global Node
	type node = 
		rec(value: char; link: ptr node)
	type head = ptr node
	type tail = ptr node
end

global Matrix
	const N := 20
	var m[N,N]: int := ([N] ([N] 0))
end

resource foo()
	import Characters, Node, Matrix
	var x: Node.node
	var y: node 		#if name "node" is unique

	if x.value = Characters.TAB -> null fi

	Matrix.m[3,4] = 23
end

Only One Copy of a Global
global One
	var X: int := 0
end

resource A
	import One
	op increase()
body A()
	proc increase()
		X++
	end
end

resource B
	import One
	op writeX()
body B()
	proc writeX()
		write(X)
	end
end

resource foo()
	import A, B
	var You, Me: cap A
	var Sam: cap B
	You := create A()
	Me := create A()
	Sam := create B()
	You.increase()
	Me.increase()
	Sam.writeX()
end

General Form of Global

global global_name

imports
declarations

body global_name

imports
declarations, statments, procs
final
clean up code
end
end
SR Performance

Experiment					SGI 340	Sun IPX       
Local Procedure Call				1.7	2.7           
Dynamic Process - create empty process		50.0	171.9         
Asynchronous message with context switch 	35.0 	122.5         
Rendezvous 					54.0	202.9         

Time in microseconds