added some more matrix functions and tidied up the calculus ones

;matrix fns

(def init-matrix(dims initval)
  (zap flat dims)
  (if cdr.dims
    (n-of car.dims (init-matrix cdr.dims initval))
    (n-of car.dims initval)))

(def matrix-rank (mat)
  (if atom.mat 0
      (let rec (afn (M r)
		 (if (atom car.M) r
		     (self car.M (+ r 1))))
	(rec mat 1))))

(def zeros dims
  (init-matrix dims 0))

(def ones dims
  (init-matrix dims 1))

(mac elt (mat pos)
  "access the element of the matix given by co-ords listed in pos"
  (if (cdr pos)
      `(elt (,mat ,(car pos)) ,(cdr pos))
      `(,mat ,(car pos))))

(def matrix-multiply (a b)
  "multiplies the matrix a by the matrix b  (N.B. Rank one row vectors need to be in the form ((a b c d ...)) /NOT/ (a b c d), i.e. initiated with dims=(1 n) not (n))"
  (with (col (fn (mat i) (map [_ i] mat))
	 result-matrix (list))
    (for rw 0 (- len.a 1)
          (push (let result-row (list)
		  (for cl 0 (- (len b.0) 1)
		       (push (apply + (map * a.rw (col b cl))) result-row))
		  rev.result-row)
		result-matrix))
    rev.result-matrix));could be generalised as a recursive macro to work on arbitrary rank tensors?

(def gauss-elim (mat rhs)
  "solve the linear equations:

mat_00*x_0 + mat_01*x_1 ... mat_0n*x_n = rhs_0
mat_10*x_0 + mat_11*x_1 ... mat_1n*x_n = rhs_1
...
mat_n0*x_0 + mat_n1*x_1 ... mat_nn*x_n = rhs_n

using gaussian elimination and returns a list of x's (N.B. not efficient for large sparce matrices)"
  (zap flat rhs)
  (withs (N (if (no (is len.mat (len car.mat))) (err "mat must be a square matrix, use co-effs of 0 for equations which dont have a certain variable in them")
	     len.mat)
	  tmp (list)
	  MAX 0
	  i 0 j 0 k 0
	  X (zeros N))
    (for i 0 (- N 1) (push (join mat.i (cons rhs.i ())) tmp))
    (let M rev.tmp
      ;elimination step
      (loop (= i 0) (<= i (- N 1)) (++ i)
       (= MAX i)
       (loop (= j (+ i 1)) (<= j (- N 1)) (++ j)
        (if (> (abs:elt M (j i)) (abs:elt M (MAX i))) (= MAX j)))
       (if (isnt MAX i) (swap M.i M.MAX))
       (loop (= j (+ i 1)) (<= j (- N 1)) (++ j)
	  (loop (= k N) (>= k i) (-- k)
	   (-- (elt M (j k)) (/ (* (elt M (i k)) (elt M (j i))) (elt M (i i))))))) ;;end of elimination step
      ;;substitution
      (loop (= j (- N 1)) (>= j 0) (-- j)
	    (= tmp 0.0)
	    (loop (= k (+ j 1)) (<= k(- N 1)) (++ k) (++ tmp (* (elt M (j k)) X.k)))
	    (= X.j (/ (- (elt M (j N)) tmp) (elt M (j j))))))
    X))

;calculus fns

(def deriv (f)
  "provides differential of a function of a single vairable"
  (fn (x)
    (let dx (if (is x 0) 1d-9 (abs:* x 1d-9))
       (/ (- (f (+ x dx))
	     (f x))
          dx))))

(mac partial-diff (f n arity)
  "returns deriv function of f (w/ num args ARITY) wrt Nth variable(from 0) "
  (withs (arglis (n-of arity (uniq))
	  a-lis (firstn n arglis)
	  x arglis.n
	  b-lis (nthcdr (+ n 1) arglis))
    `(fn ,arglis
      (let dx (if (is ,x 0) 1d-9 (abs:* ,x 1d-9))
	(/ (- (,f ,@a-lis (+ ,x dx) ,@b-lis)
	      (,f ,@a-lis    ,x     ,@b-lis))
	   dx)))))

(mac partial-diff-vec (f n arity)
  "returns vector with each element differentiated with respect to Nth argument"
  (withs (arglis (n-of arity (uniq))
	  a-lis (firstn n arglis)
	  x arglis.n
	  b-lis (nthcdr (+ n 1) arglis))
    `(fn ,arglis
	(let dx (if (is ,x 0) 1d-9 (abs:* ,x 1d-9))
	   (vec-scale (vec- (,f ,@a-lis	(+ ,x dx) ,@b-lis)
			    (,f ,@a-lis    ,x     ,@b-lis))
		      (/ 1 dx))))))

(def grad (f)
  "gradient of 3D scalar field given by F"
  (fn (x y z)
    (list ((partial-diff f 0 3) x y z)
	  ((partial-diff f 1 3) x y z)
	  ((partial-diff f 2 3) x y z))))

(def div (f)
  "divergence of 3D vector field given by F"
  (fn (x y z)
      (+ (((partial-diff-vec f 0 3) x y z) 0)
	 (((partial-diff-vec f 1 3) x y z) 1)
	 (((partial-diff-vec f 2 3) x y z) 2))))

(def curl (f)
  "curl of 3D vector field given by F"
  (with (d/dx (partial-diff-vec f 0 3)
	 d/dy (partial-diff-vec f 1 3)
	 d/dz (partial-diff-vec f 2 3))
  (fn (x y z)
    (list (- ((d/dy x y z) 2)
	     ((d/dz x y z) 1))
	  (- ((d/dz x y z) 0)
	     ((d/dx x y z) 2))
	  (- ((d/dx x y z) 1)
	     ((d/dy x y z) 0))))))

(def integral (f)
  "returns the integral of a single argument function using Simpson's method"
  (fn (lower upper (o its 100))
    (withs (dx      (/ (- upper lower) its)
	    x       lower
	    current (f x)
	    next    (f (+ x dx))
	    accum   0)
      (while (<= x (- upper dx))
	     (++ accum (/ (+ (* (+ current next) 1/2 dx)
			     (* 2 dx (f (+ x (/ dx 2)))))
			  3))
	     (++ x dx)
	     (= current next)
	     (= next (f x)))
      accum)))

; vector fns

(def vec-dot (v1 v2)
  (apply + (map (fn (x y) (* x y)) v1 v2)))

(def vec-cross (v1 v2 . args)
  (if (car args)(vec-cross (vec-cross v1 v2) (car args) (cdr args))
                (list (- (* v1.1 v2.2) (* v2.1 v1.2))
		      (- (* v1.2 v2.0) (* v2.2 v1.0))
		      (- (* v1.0 v2.1) (* v2.0 v1.1)))))

(with (v+ (fn (v1 v2)
	     (map (fn (x y) (+ x y)) v1 v2))
       v- (fn (v1 v2)
	     (map (fn (x y) (- x y)) v1 v2)))

  (def vec+ (v1 . args)
    (if no.args v1
	(reduce v+ (cons v1 args))))

  (def vec- (v1 . args)
    (if no.args (map [- _] v1)
	(v- v1 (apply vec+ args))))
)

(def vec-scale (vec . scalars)
  (let c (apply * scalars)
    (map [* _ c] vec)))

(def quad-add args
  ((afn (tot xs)
     (if no.xs (sqrt tot)
	 (self (+ tot (expt (car xs) 2)) (cdr xs))))
   0 args))

(def vec-norm (vec)
  (vec-scale vec (/ (apply quad-add vec))))

;others

(def square (x) (* x x))
(def cube (x) (* x x x))
(def floor (n) (trunc n))
(def ceiling (n) (int ($.ceiling n)))
(def highbyte (n) (floor (/ n 256)))
(def lowbyte (n) (mod n 256))

(def fact (num)
  "factorial of num (num must be a fixnum)"
  (if (or (< num 0)(no:isa num 'int)) (err "num must be a positive integer")
      ((afn (n x)
	 (if (<= n 1)
	     x
	     (self (- n 1) (* n x))))
       num 1)))

(def n-bessel (n (o terms 100))
  "gives a fn for the nth bessel function of the first kind evaluated at x"
  (fn (x)
    (with (i 0
	   tot 0)
      (while (< i terms)
	     (++ tot (/ (* (expt -1 i) (expt (/ x 2) (+ n i i)))
			(* (fact i) (fact (+ n i)))))
	     (++ i 1))
      tot)))

(def mean lis
  ((afn (tot i x . xs)
     (if no.xs (/ (+ tot x) (+ i 1))
	 (self (+ tot x) (+ i 1) car.xs cdr.xs)))
   0 0 car.lis cdr.lis))

(def std-dev lis
  (let m mean.lis
    (sqrt:/ (apply + (map [expt (- _ m) 2] lis))
	    len.lis)))

(def choose (n x)
  "number of ways of picking n elements from x (ie no. of ways of mixing 2 different sets of identical objects of size n and (- x n))"
  (if (> n x)
      (do (prn "")(pr n)(pr " is greater than ")(prn x))
      (/ (fact x) (* (fact n) (fact (- x n))))))

(def gauss-random (sigma (o middle 0))
  "aproximation to a gausian distributed random with width sigma around middle, max possible deviation +/- 1000sigma"
  (let tot 0
    (for i 0 999
      (++ tot  (- (* (rand) 2.0) 1)))
    (+ (* tot (/ sigma 25)) middle)))

(def quad-roots (a b c)
  "returns roots of the equation ax^2+bx+c=0"
  (let sqroot (sqrt (- (* b b) (* 4 a c)))
    (if (is sqroot 0) (list (/ (- b) 2 a))
	(list (/ (- sqroot b) 2 a)
	      (/ (- 0 sqroot b) 2 a)))))

(def init-matrix(dims initval)
  (zap flat dims)
  (if cdr.dims
    (n-of car.dims (init-matrix cdr.dims initval))
    (n-of car.dims initval)))

(def zeros dims
  (init-matrix dims 0))

(def ones dims
  (init-matrix dims 1))

(def square (x)
  (* x x))

(def floor (n) (trunc n))
(def ceiling (n) (int ($.ceiling n)))
(def highbyte (n) (floor (/ n 256)))
(def lowbyte (n) (mod n 256))

;calculus fns

(def deriv (f)
  "provides differential of a function of a single vairable"
  (fn (x)
    (let dx (min 1d-9 (abs:* x 1d-9))
       (/ (- (f (+ x dx))
	     (f x))
          dx))))

(mac partial-diff (f n arity)
  "returns deriv function of f (w/ num args ARITY) wrt Nth variable(from 0) "
  (withs (arglis (n-of arity (uniq))
	  a-lis (firstn n arglis)
	  x arglis.n
	  b-lis (nthcdr (+ n 1) arglis))
    `(fn ,arglis
      (let dx (min 1d-9 (abs:* ,x 1d-9))
	(/ (- (,f ,@a-lis (+ ,x dx) ,@b-lis)
	      (,f ,@a-lis    ,x     ,@b-lis))
	   dx)))))

(mac partial-diff-vec (f n arity)
  "returns vector with each element differentiated with respect to Nth argument"
  (withs (arglis (n-of arity (uniq))
	  a-lis (firstn n arglis)
	  x arglis.n
	  b-lis (nthcdr (+ n 1) arglis))
    `(fn ,arglis
	(let dx (max 1d-9 (abs:* ,x 1d-9))
	   (vec-scale (vec- (,f ,@a-lis	(+ ,x dx) ,@b-lis)
			    (,f ,@a-lis    ,x     ,@b-lis))
		      (/ 1 dx))))))

(def grad (f)
  "gradient of 3D scalar field given by F"
  (fn (x y z)
    (list ((partial-diff f 0 3) x y z)
	  ((partial-diff f 1 3) x y z)
	  ((partial-diff f 2 3) x y z))))

(def div (f)
  "divergence of 3D vector field given by F"
  (fn (x y z)
      (+ (((partial-diff-vec f 0 3) x y z) 0)
	 (((partial-diff-vec f 1 3) x y z) 1)
	 (((partial-diff-vec f 2 3) x y z) 2))))

(def curl (f)
  "curl of 3D vector field given by F"
  (with (d/dx (partial-diff-vec f 0 3)
	 d/dy (partial-diff-vec f 1 3)
	 d/dz (partial-diff-vec f 2 3))
  (fn (x y z)
    (list (- ((d/dy x y z) 2)
	     ((d/dz x y z) 1))
	  (- ((d/dz x y z) 0)
	     ((d/dx x y z) 2))
	  (- ((d/dx x y z) 1)
	     ((d/dy x y z) 0))))))

(def integral (f)
  "returns the integral of a single argument function"
  (fn (lower upper (o its 10000))
    (withs (dx      (/ (- upper lower) its)
	    x       lower
	    current (f x)
	    next    (f (+ x dx))
	    accum   0)
      (while (<= x (- upper dx))
	     (++ accum (* (/ (+ current next) 2) dx))
	     (++ x dx)
	     (= current next)
	     (= next (f:+ x dx)))
      accum)))

; vector fns

(def vec-dot (v1 v2)
  (apply + (map (fn (x y) (* x y)) v1 v2)))

(def vec-cross (v1 v2 . args)
  (if (car args)
      (vec-cross (vec-cross v1 v2) (car args) (cdr args))
      (list (- (* v1.1 v2.2) (* v2.1 v1.2))
	    (- (* v1.2 v2.0) (* v2.2 v1.0))
	    (- (* v1.0 v2.1) (* v2.0 v1.1)))))

(with (v+ (fn (v1 v2)
	     (map (fn (x y) (+ x y)) v1 v2))
       v- (fn (v1 v2)
	     (map (fn (x y) (- x y)) v1 v2)))

  (def vec+ (v1 . args)
    (if no.args v1
	(reduce v+ (cons v1 args))))

  (def vec- (v1 . args)
    (if no.args (map [- _] v1)
	(v- v1 (apply vec+ args))))

)

(def vec-scale (vec . scalars)
  (let c (apply * scalars)
    (map [* _ c] vec)))

(def quad-add args
  ((afn (tot xs)
     (if no.xs (sqrt tot)
	 (self (+ tot (expt (car xs) 2)) (cdr xs))))
   0 args))

(def vec-norm (vec)
  (vec-scale vec (/ (apply quad-add vec))))

;others

(def fact (num)
  "factorial of num (num must be a fixnum)"
  (if (or (< num 0)(no:isa num 'int)) (err "num must be a positive integer")
      ((afn (n x)
	 (if (<= n 1)
	     x
	     (self (- n 1) (* n x))))
       num 1)))

(def n-bessel (n (o terms 100))
  "gives a fn for the nth bessel function of the first kind evaluated at x"
  (fn (x)
    (with (i 0
	   tot 0)
      (while (< i terms)
	     (++ tot (/ (* (expt -1 i) (expt (/ x 2) (+ n i i)))
			(* (fact i) (fact (+ n i)))))
	     (++ i 1))
      tot)))

(def mean lis
  ((afn (tot i x . xs)
     (if no.xs (/ (+ tot x) (+ i 1))
	 (self (+ tot x) (+ i 1) car.xs cdr.xs)))
   0 0 car.lis cdr.lis))

(def std-dev lis
  (let m mean.lis
    (sqrt:/ (apply + (map [expt (- _ m) 2] lis))
	    len.lis)))

(def choose (n x)
  "number of ways of picking n elements from x (ie no. of ways of mixing 2 different sets of identical objects of size n and (- x n))"
  (if (> n x)
      (do (prn "")(pr n)(pr " is greater than ")(prn x))
      (/ (fact x) (* (fact n) (fact (- x n))))))

(def gauss-random (sigma (o middle 0))
  "aproximation to a gausian distributed random with width sigma around middle, max possible deviation +/- 1000sigma"
  (let tot 0
    (for i 0 999
      (++ tot  (- (* (rand) 2.0) 1)))
    (+ (* tot (/ sigma 25)) middle)))

(def quad-roots (a b c)
  "returns roots of the equation ax²+bx+c=0"
  (let sqroot (sqrt (- (* b b) (* 4 a c)))
    (if (is sqroot 0) (list (/ (- b) 2 a))
	(list (/ (- sqroot b) 2 a)
	      (/ (- 0 sqroot b) 2 a)))))


More transient renaming. #4

More transient renaming. #4

.//============================================================================
.// $RCSfile: q.class.pei.arc,v $
.//
.// Description:
.// This archetype file contains the functions for generating
.// preexisting instances initialization code.
.//
.// Notice:
.// (C) Copyright 1998-2013 Mentor Graphics Corporation
.//     All rights reserved.
.//
.// This document contains confidential and proprietary information and
.// property of Mentor Graphics Corp.  No part of this document may be
.// reproduced without the express written permission of Mentor Graphics Corp.
.//============================================================================
.//
.//
.//============================================================================
.// Initialize the instance subsystem.
.// Update the instance and link records with array index values
.// and container counts.
.// The mapping of the instances to a particular array index is
.// arbitrary.
.//============================================================================
.function PEIInstanceSubsystemInit
  .param inst_ref_set o_objs
  .//
  .for each o_obj in o_objs
    .select many i_inss related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
    .// Check for preexisting instance population requirement.
    .// The class must have instances and also be colored.
    .assign i = cardinality i_inss
    .select one te_class related by o_obj->TE_CLASS[R2019]
    .if ( ( i > 0 ) and ( te_class.PEIsDefinedInData ) )
      .assign te_class.PEIsDefinedInData = TRUE
    .else
      .assign te_class.PEIsDefinedInData = FALSE
    .end if
    .//
    .assign i = 0
    .for each i_ins in i_inss
      .assign i_ins.Name = "${i}"
      .assign i = i + 1
    .end for
  .end for
.end function
.//
.//
.//============================================================================
.// Count the preexisting instances of the given type.
.// Return the number of preexisting instances for obj.
.//============================================================================
.function PEINumberOfPreexistingInstances
  .param inst_ref o_obj
  .select many i_inss related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
  .assign attr_result = cardinality i_inss
  .// .assign msg =       "PEINumberOfPreexistingInstances is ${attr_result} "
  .// .assign msg = msg + "for ${o_obj.Name} (${o_obj.Key_Lett})"
  .// .print "${msg}"
.end function
.//
.//
.//=============================================================================
.// Generate initializers for preexisting instances.
.// We generate the initializers in array index order.  C initializers
.// will assume sequential ordering.
.//=============================================================================
.function PEIRenderInitializers
  .param inst_ref o_obj
  .assign attr_assset = ""
  .select any te_set from instances of TE_SET
  .select one te_class related by o_obj->TE_CLASS[R2019]
  .if ( te_class.PEIsDefinedInData )
    .assign inst_count = 0
    .select many i_inss related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
    .assign i_inss_cardinality = cardinality i_inss
    .while ( inst_count < i_inss_cardinality )
      .for each i_ins in i_inss
        .if ( i_ins.Name == "${inst_count}" )
          .invoke initializercode = PEIRenderInitializerBody( i_ins, o_obj )
          .assign attr_assset = attr_assset + initializercode.assset
  { ${initializercode.result} }\
          .if ( last i_inss )

          .else
,
          .end if
          .break for
        .end if
      .end for
      .assign inst_count = inst_count + 1
    .end while .// inst_count
    .// If there is a need for relationship set containers, build them up.
    .if ( attr_assset != "" )
      .invoke rel_set_name = PEIGetRelationshipSetContainerName( te_class )
      .assign attr_assset = "static ${te_set.element_type} ${rel_set_name.result}[] = {\n" + attr_assset
      .assign attr_assset = "/* PEI relationship set containers.  */\n" + attr_assset
      .assign attr_assset = attr_assset + "\n};\n"
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate body of one preexisting instance initializer.
.// First, the initial state initializer is output.
.// The class instance attribute data variable values are generated
.// in the same order in which they appear in the application analysis OIM.
.// The relationship optimization initializers are then generated.
.//=============================================================================
.function PEIRenderInitializerBody
  .param inst_ref i_ins
  .param inst_ref o_obj
  .assign attr_result = ""
  .assign attr_assset = ""
  .//
  .// Generate state machine state (if needed).
  .//
  .invoke cs_init = PEIRenderInitializerBodyCurrentState( i_ins, o_obj )
  .assign attr_result = attr_result + cs_init.result
  .if ( "" != attr_result )
    .assign attr_result = attr_result + ", "
  .end if
  .//
  .// Generate the attribute value initializers.
  .//
  .select any te_attr related by o_obj->TE_CLASS[R2019]-TE_ATTR[R2061] where ( selected.prevID == 0 )
  .if ( not_empty te_attr )
    .select one o_attr related by te_attr->O_ATTR[R2033]
    .while ( not_empty te_attr )
      .if ( te_attr.translate )
        .select any i_avl related by i_ins->I_AVL[R2909] where ( selected.Attr_ID == o_attr.Attr_ID )
        .invoke avlcode = PEIRenderInitializerBodyAttribute( o_attr, i_avl )
        .assign attr_result = attr_result + avlcode.result
      .end if
      .//
      .// Advance to the next object attribute, if any.
      .select one te_attr related by te_attr->TE_ATTR[R2087.'succeeds']
      .//
      .// Generate comma separator.
      .if ( not_empty te_attr )
        .if ( te_attr.translate )
          .assign attr_result = attr_result + ", "
        .end if
      .end if
    .end while
  .end if
  .//
  .// Generate the association linkage (if needed).
  .//
  .invoke ass_init = PEIRenderInitializerBodyAssociation( i_ins, o_obj )
  .assign attr_result = attr_result + ass_init.result
  .assign attr_assset = attr_assset + ass_init.assset
  .//
.end function
.//
.//
.//=============================================================================
.// Generate initialization for a single attribute value.
.// Return the value as a string quoted correctly (if needed).
.//=============================================================================
.function PEIRenderInitializerBodyAttribute
  .param inst_ref o_attr
  .param inst_ref i_avl
  .assign attr_result = "0"
  .// Get the attribute data type.  Strings need to be quoted.
  .invoke member_type = GetAttributeCodeGenType( o_attr )
  .assign cdt = member_type.cdt
  .if ( 4 == cdt.Core_Typ )
    .// string
    .if ( empty i_avl )
      .// In absence of a populated attribute, use the attribute default value.
      .if ( "" != o_attr.DefaultValue )
        .assign attr_result = o_attr.DefaultValue
      .else
        .assign attr_result = """"""
      .end if
    .else
      .assign attr_result = """${i_avl.Value}"""
    .end if
  .else
    .if ( empty i_avl )
      .assign attr_result = "0"
    .else
      .assign attr_result = i_avl.Value
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized association linkage for this instance.
.// Select the relationship set for this object.  Loop through each one
.// generating linkage anywhere storage is provided (for pointer refs).
.// Get the multiplicity so we know whether we need sets or simple
.// pointers.
.// Do the right thing for each flavor of association, simple, reflexive,
.// associative and sub/super.
.// Return the static initializer body material.
.//=============================================================================
.function PEIRenderInitializerBodyAssociation
  .param inst_ref i_ins
  .param inst_ref o_obj
  .//
  .assign multiplicity = 0
  .assign attr_assset = ""
  .assign attr_result = ""
  .select many te_rels related by o_obj->R_OIR[R201]->R_REL[R201]->TE_REL[R2034]
  .if ( not_empty te_rels )
    .// Pre-order the relationships ascending by their relationship number.
    .// Note:  This decouples code generation from SQL table
    .//        insertion ordering internals.
    .invoke SortSetAscendingByAttr_Numb( te_rels )
    .assign rel_count = 0
    .assign rel_cardinality = cardinality te_rels
    .//
    .while ( rel_count < rel_cardinality )
      .for each te_rel in te_rels
        .if ( te_rel.Order == rel_count )
          .select one rel related by te_rel->R_REL[R2034]
          .if ( not te_rel.storage_needed )
            .break for
          .end if
          .// Simple relationship?
          .select one simple_rel related by rel->R_SIMP[R206]
          .if ( not_empty simple_rel )
            .select one participant related by simple_rel->R_PART[R207]
            .select one formalizer related by simple_rel->R_FORM[R208]
            .if ( empty formalizer )
              .print "\n\tRelationship R${rel.Numb} is not formalized!\n"
              .exit 101
            .end if
            .// Deal with reflexives.
            .if ( participant.Obj_ID == formalizer.Obj_ID )
              .invoke s = PEIRelInitSimpleReflexive( i_ins, o_obj, rel, participant, formalizer )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
            .else
              .// Get multiplicity to pass to the code generator.
              .if ( o_obj.Obj_ID == participant.Obj_ID )
                .assign multiplicity = formalizer.Mult
              .else
                .assign multiplicity = participant.Mult
              .end if
              .invoke s = PEIRelInitSimple( i_ins, o_obj, rel, multiplicity )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
            .end if .// reflexive
          .else
            .// elif Subtype-Supertype relationship?
            .select one r_subsup related by rel->R_SUBSUP[R206]
            .if ( not_empty r_subsup )
              .invoke s = PEIRelInitSubSuper( i_ins, o_obj, rel, r_subsup )
              .assign attr_result = attr_result + s.result
          .else
            .// elif Associative relationship?
            .select one assrel related by rel->R_ASSOC[R206]
            .if ( not_empty assrel )
              .invoke s = PEIRelInitAssociative( i_ins, o_obj, rel, assrel )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
          .else
            .// elif Composed relationship?
            .select one composed_rel related by rel->R_COMP[R206]
            .if ( not_empty composed_rel )
              .print "\nWARNING:  R${rel.Numb} is COMPOSITION - No code generated.\n"
              .invoke s = PEIRelInitComposed( o_obj, rel )
              .assign attr_result = attr_result + s.result
          .else
            .// elif Error: New subtype of R_REL or a corrupted model SQL...
            .print "ERROR:  Unknown association type:R${rel.Numb} for class '${o_obj.Name}' (${o_obj.Key_Lett})"
            .exit 101
          .end if  .// not_empty composed_rel
          .end if  .// not_empty associative_rel
          .end if  .// not_empty subtype_supertype_rel
          .end if  .// not_empty simp_rel
          .break for
        .end if
      .end for
      .assign rel_count = rel_count + 1
    .end while .// rel_count < rel_cardinality
  .end if .// not_empty rel_set
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a simple association.
.// of multiplicity ONE.
.//=============================================================================
.function PEIRelInitSimple
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param integer multiplicity
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select any related_i_ins from instances of I_INS
  .//
  .// Find related instance index.
  .// Traverse the instance to link to instance chain
  .// to get the instance ArrayIndex.
  .if ( multiplicity == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .if ( empty related_i_ins )
      .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .end if
    .if ( not_empty related_i_ins )
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .assign attr_result = ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// not participating
      .assign attr_result = ", 0"
    .end if  .// not empty
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts1 related by links->I_LIP[R2901]->I_INS[R2958]
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts2 related by links->I_LIP[R2902]->I_INS[R2958]
    .assign related_insts = related_insts1 | related_insts2
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a simple reflexive
.// association.
.// In the reflexive case, the part and form are aligned with R2901 and R2902.
.//=============================================================================
.function PEIRelInitSimpleReflexive
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_part
  .param inst_ref r_form
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .invoke related_extent_info = GetFixedSizeClassExtentInfo( o_obj )
  .select any related_i_ins from instances of I_INS
  .//
  .// Link the formalizer to the participant.
  .//
  .if ( r_part.Mult == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .if ( not_empty related_i_ins )
      .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// Not participating.
      .assign attr_result = attr_result + ", 0"
    .end if
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts related by links->I_LIP[R2901]->I_INS[R2958]
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
  .// Now link the participant to the formalizer(s).
  .//
  .if ( r_form.Mult == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .if ( not_empty related_i_ins )
      .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// Not participating.
      .assign attr_result = attr_result + ", 0"
    .end if
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts related by links->I_LIP[R2902]->I_INS[R2958]
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for an associative
.// relationship.
.// In the reflexive case, R2901 and R2902 will jive with AONE and AOTH.
.// In the non-reflexive, we compare the instance Obj_ID with the
.// AONE/AOTH Obj_ID.
.//=============================================================================
.function PEIRelInitAssociative
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_assoc
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select one aone related by r_assoc->R_AONE[R209]
  .select one aoth related by r_assoc->R_AOTH[R210]
  .select one assr related by r_assoc->R_ASSR[R211]
  .//
  .// The other associated instance.
  .//
  .if ( o_obj.Obj_ID == aoth.Obj_ID )
    .// Optimize relationship to associator.
    .if ( ( aone.Mult == 0 ) and ( assr.Mult == 0 ) )
      .// ONE
      .select any link from instances of I_LNK where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .if ( empty link )
          .select one related_obj related by i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
          .if ( related_obj.Obj_ID == aoth.Obj_ID )
            .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
          .end if
        .end if  .// not empty
      .end if .// reflexive
      .if ( not_empty link )
        .select one related_i_ins related by link->I_LIP[R2903]->I_INS[R2958]
        .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
        .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .// not participating
        .assign attr_result = attr_result + ", 0"
      .end if  .// not empty
    .else
      .// MANY
      .// Build linked list of containers pointing to related instances.
      .select many links from instances of I_LNK where ( false )
      .select many related_insts from instances of I_INS where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select many links1 related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .select many links2 related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .assign links = links1 | links2
      .end if
      .select many related_insts related by links->I_LIP[R2903]->I_INS[R2958]
      .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
      .assign attr_result = attr_result + s.result
      .assign attr_assset = attr_assset + s.assset
    .end if
  .end if
  .//
  .// The one associated instance.
  .//
  .if ( o_obj.Obj_ID == aone.Obj_ID )
    .// Optimize relationship to associator.
    .if ( ( aoth.Mult == 0 ) and ( assr.Mult == 0 ) )
      .// ONE
      .select any link from instances of I_LNK where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .if ( empty link )
          .select one related_obj related by i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
          .if ( related_obj.Obj_ID == aone.Obj_ID )
            .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
          .end if
        .end if
      .end if .// reflexive
      .if ( not_empty link )
        .select one related_i_ins related by link->I_LIP[R2903]->I_INS[R2958]
        .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
        .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .// not participating
        .assign attr_result = attr_result + ", 0"
      .end if  .// not empty
    .else
      .// MANY
      .// Build linked list of containers pointing to related instances.
      .select many links from instances of I_LNK where ( false )
      .select many related_insts from instances of I_INS where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select many links1 related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .select many links2 related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .assign links = links1 | links2
      .end if
      .select many related_insts related by links->I_LIP[R2903]->I_INS[R2958]
      .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
      .assign attr_result = attr_result + s.result
      .assign attr_assset = attr_assset + s.assset
    .end if
  .end if
  .//
  .// The associative instance.
  .//
  .if ( o_obj.Obj_ID == assr.Obj_ID )
    .// Optimize relationship to both associates.
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2903] where ( selected.Rel_ID == r_rel.Rel_ID )
    .if ( not_empty link )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .select one related_inst2 related by link->I_LIP[R2902]->I_INS[R2958]
      .select one related_obj2 related by related_inst2->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info2 = GetFixedSizeClassExtentInfo( related_obj2 )
      .if ( ( aone.Obj_ID == aoth.Obj_ID ) or ( related_obj2.Obj_ID == aone.Obj_ID ) )
        .assign attr_result = attr_result + ", &${related_extent_info2.obj_pool_var_name}[${related_inst2.Name}]"
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
        .assign attr_result = attr_result + ", &${related_extent_info2.obj_pool_var_name}[${related_inst2.Name}]"
      .end if
    .else
      .// not participating
      .assign attr_result = attr_result + ", 0, 0"
    .end if  .// not empty
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a Subtype/Supertype
.// association.
.//=============================================================================
.function PEIRelInitSubSuper
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_subsup
  .assign attr_result = ""
  .//
  .// Find related instance index.
  .// Traverse the instance to link to instance chain
  .// to get the instance ArrayIndex.
  .select one super related by r_subsup->R_SUPER[R212]
  .if ( o_obj.Obj_ID == super.Obj_ID )
    .// Supertype
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .if ( empty link )
      .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .end if
    .if ( not_empty link )
      .select one related_object related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .select one te_class related by related_object->TE_CLASS[R2019]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_object )
      .assign attr_result = ", (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], ${te_class.system_class_number}"
    .else
      .// not participating
      .assign attr_result = ", 0, 0"
    .end if
  .else
    .// Subtype
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .if ( not_empty link )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
      .select one related_object related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_object )
      .assign attr_result = ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// not participating
      .assign attr_result = ", 0"
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a composed association.
.//=============================================================================
.function PEIRelInitComposed
  .param inst_ref o_obj
  .param inst_ref r_rel
  .assign attr_result = ""
.end function
.//
.//
.//=============================================================================
.// Generate an initializer for the current state attribute if needed.
.//=============================================================================
.function PEIRenderInitializerBodyCurrentState
  .param inst_ref i_ins
  .param inst_ref o_obj
  .assign attr_result = ""
  .select one te_state related by i_ins->SM_STATE[R2915]->TE_STATE[R2037]
  .if ( not_empty te_state )
    .assign attr_result = te_state.enumerator
  .end if
.end function
.//
.//
.//=============================================================================
.// Render relationship MANY optimization.
.// This helper is used to render the code used to optimize a relationship
.// set.  The set variable is generated for inside the instance structure.
.// The linked list body pointing to related instances is also generated.
.//=============================================================================
.function PEIRenderRelationshipManyOptimization
  .param inst_ref_set i_inss
  .param inst_ref o_obj
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select any te_sys from instances of TE_SYS
  .// i_inss, o_obj
  .assign instance_count = cardinality i_inss
  .if ( instance_count > 0 )
    .select one te_class related by o_obj->TE_CLASS[R2019]
    .assign ContainerIndex = te_class.ContainerIndex
    .// A container index starting greater than zero means we are not the
    .// first (instance) to be adding linked lists.  Precede with comma.
    .if ( ContainerIndex > 0 )
      .assign attr_assset = ",\n"
    .end if
    .invoke rel_set_name = PEIGetRelationshipSetContainerName( te_class )
    .assign attr_result = ", { &${rel_set_name.result}[${ContainerIndex}] }"
    .for each related_i_ins in i_inss
      .assign ContainerIndex = ContainerIndex + 1
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .if ( last i_inss )
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign icount = cardinality i_inss
          .if ( icount > 1 )
            .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], &${rel_set_name.result}[${ContainerIndex} - 2] }"
          .else
            .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], 0 }"
          .end if .// cardinality i_inss > 1
        .else
          .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] }"
        .end if
      .elif ( first i_inss )
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], 0 },\n"
        .else
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] },\n"
        .end if
      .else
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], &${rel_set_name.result}[${ContainerIndex} - 2] },\n"
        .else
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] },\n"
        .end if
      .end if
    .end for
    .assign te_class.ContainerIndex = ContainerIndex
  .else
    .// Empty relationship set.
    .assign attr_result = ", { 0 }"
  .end if
.end function
.//

.//============================================================================
.// $RCSfile: q.class.pei.arc,v $
.//
.// Description:
.// This archetype file contains the functions for generating
.// preexisting instances initialization code.
.//
.// Notice:
.// (C) Copyright 1998-2013 Mentor Graphics Corporation
.//     All rights reserved.
.//
.// This document contains confidential and proprietary information and
.// property of Mentor Graphics Corp.  No part of this document may be
.// reproduced without the express written permission of Mentor Graphics Corp.
.//============================================================================
.//
.//
.//============================================================================
.// Initialize the instance subsystem.
.// Update the instance and link records with array index values
.// and container counts.
.// The mapping of the instances to a particular array index is
.// arbitrary.
.//============================================================================
.function PEIInstanceSubsystemInit
  .param inst_ref_set o_objs
  .//
  .for each o_obj in o_objs
    .select many i_inss related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
    .// Check for preexisting instance population requirement.
    .// The class must have instances and also be colored.
    .assign i = cardinality i_inss
    .select one te_class related by o_obj->TE_CLASS[R2019]
    .if ( ( i > 0 ) and ( te_class.PEIsDefinedInData ) )
      .assign te_class.PEIsDefinedInData = TRUE
    .else
      .assign te_class.PEIsDefinedInData = FALSE
    .end if
    .//
    .assign i = 0
    .for each i_ins in i_inss
      .assign i_ins.Name = "${i}"
      .assign i = i + 1
    .end for
  .end for
.end function
.//
.//
.//============================================================================
.// Count the preexisting instances of the given type.
.// Return the number of preexisting instances for obj.
.//============================================================================
.function PEINumberOfPreexistingInstances
  .param inst_ref o_obj
  .select many inst_set related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
  .assign attr_result = cardinality inst_set
  .// .assign msg =       "PEINumberOfPreexistingInstances is ${attr_result} "
  .// .assign msg = msg + "for ${o_obj.Name} (${o_obj.Key_Lett})"
  .// .print "${msg}"
.end function
.//
.//
.//=============================================================================
.// Generate initializers for preexisting instances.
.// We generate the initializers in array index order.  C initializers
.// will assume sequential ordering.
.//=============================================================================
.function PEIRenderInitializers
  .param inst_ref o_obj
  .assign attr_assset = ""
  .select any te_set from instances of TE_SET
  .select one te_class related by o_obj->TE_CLASS[R2019]
  .if ( te_class.PEIsDefinedInData )
    .assign inst_count = 0
    .select many i_inss related by o_obj->CSME_CIE[R2961]->I_INS[R2962]
    .assign i_inss_cardinality = cardinality i_inss
    .while ( inst_count < i_inss_cardinality )
      .for each i_ins in i_inss
        .if ( i_ins.Name == "${inst_count}" )
          .invoke initializercode = PEIRenderInitializerBody( i_ins, o_obj )
          .assign attr_assset = attr_assset + initializercode.assset
  { ${initializercode.result} }\
          .if ( last i_inss )

          .else
,
          .end if
          .break for
        .end if
      .end for
      .assign inst_count = inst_count + 1
    .end while .// inst_count
    .// If there is a need for relationship set containers, build them up.
    .if ( attr_assset != "" )
      .invoke rel_set_name = PEIGetRelationshipSetContainerName( te_class )
      .assign attr_assset = "static ${te_set.element_type} ${rel_set_name.result}[] = {\n" + attr_assset
      .assign attr_assset = "/* PEI relationship set containers.  */\n" + attr_assset
      .assign attr_assset = attr_assset + "\n};\n"
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate body of one preexisting instance initializer.
.// First, the initial state initializer is output.
.// The class instance attribute data variable values are generated
.// in the same order in which they appear in the application analysis OIM.
.// The relationship optimization initializers are then generated.
.//=============================================================================
.function PEIRenderInitializerBody
  .param inst_ref i_ins
  .param inst_ref o_obj
  .assign attr_result = ""
  .assign attr_assset = ""
  .//
  .// Generate state machine state (if needed).
  .//
  .invoke cs_init = PEIRenderInitializerBodyCurrentState( i_ins, o_obj )
  .assign attr_result = attr_result + cs_init.result
  .if ( "" != attr_result )
    .assign attr_result = attr_result + ", "
  .end if
  .//
  .// Generate the attribute value initializers.
  .//
  .select any te_attr related by o_obj->TE_CLASS[R2019]-TE_ATTR[R2061] where ( selected.prevID == 0 )
  .if ( not_empty te_attr )
    .select one o_attr related by te_attr->O_ATTR[R2033]
    .while ( not_empty te_attr )
      .if ( te_attr.translate )
        .select any i_avl related by i_ins->I_AVL[R2909] where ( selected.Attr_ID == o_attr.Attr_ID )
        .invoke avlcode = PEIRenderInitializerBodyAttribute( o_attr, i_avl )
        .assign attr_result = attr_result + avlcode.result
      .end if
      .//
      .// Advance to the next object attribute, if any.
      .select one te_attr related by te_attr->TE_ATTR[R2087.'succeeds']
      .//
      .// Generate comma separator.
      .if ( not_empty te_attr )
        .if ( te_attr.translate )
          .assign attr_result = attr_result + ", "
        .end if
      .end if
    .end while
  .end if
  .//
  .// Generate the association linkage (if needed).
  .//
  .invoke ass_init = PEIRenderInitializerBodyAssociation( i_ins, o_obj )
  .assign attr_result = attr_result + ass_init.result
  .assign attr_assset = attr_assset + ass_init.assset
  .//
.end function
.//
.//
.//=============================================================================
.// Generate initialization for a single attribute value.
.// Return the value as a string quoted correctly (if needed).
.//=============================================================================
.function PEIRenderInitializerBodyAttribute
  .param inst_ref o_attr
  .param inst_ref i_avl
  .assign attr_result = "0"
  .// Get the attribute data type.  Strings need to be quoted.
  .invoke member_type = GetAttributeCodeGenType( o_attr )
  .assign cdt = member_type.cdt
  .if ( 4 == cdt.Core_Typ )
    .// string
    .if ( empty i_avl )
      .// In absence of a populated attribute, use the attribute default value.
      .if ( "" != o_attr.DefaultValue )
        .assign attr_result = o_attr.DefaultValue
      .else
        .assign attr_result = """"""
      .end if
    .else
      .assign attr_result = """${i_avl.Value}"""
    .end if
  .else
    .if ( empty i_avl )
      .assign attr_result = "0"
    .else
      .assign attr_result = i_avl.Value
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized association linkage for this instance.
.// Select the relationship set for this object.  Loop through each one
.// generating linkage anywhere storage is provided (for pointer refs).
.// Get the multiplicity so we know whether we need sets or simple
.// pointers.
.// Do the right thing for each flavor of association, simple, reflexive,
.// associative and sub/super.
.// Return the static initializer body material.
.//=============================================================================
.function PEIRenderInitializerBodyAssociation
  .param inst_ref i_ins
  .param inst_ref o_obj
  .//
  .assign multiplicity = 0
  .assign attr_assset = ""
  .assign attr_result = ""
  .select many te_rels related by o_obj->R_OIR[R201]->R_REL[R201]->TE_REL[R2034]
  .if ( not_empty te_rels )
    .// Pre-order the relationships ascending by their relationship number.
    .// Note:  This decouples code generation from SQL table
    .//        insertion ordering internals.
    .invoke SortSetAscendingByAttr_Numb( te_rels )
    .assign rel_count = 0
    .assign rel_cardinality = cardinality te_rels
    .//
    .while ( rel_count < rel_cardinality )
      .for each te_rel in te_rels
        .if ( te_rel.Order == rel_count )
          .select one rel related by te_rel->R_REL[R2034]
          .if ( not te_rel.storage_needed )
            .break for
          .end if
          .// Simple relationship?
          .select one simple_rel related by rel->R_SIMP[R206]
          .if ( not_empty simple_rel )
            .select one participant related by simple_rel->R_PART[R207]
            .select one formalizer related by simple_rel->R_FORM[R208]
            .if ( empty formalizer )
              .print "\n\tRelationship R${rel.Numb} is not formalized!\n"
              .exit 101
            .end if
            .// Deal with reflexives.
            .if ( participant.Obj_ID == formalizer.Obj_ID )
              .invoke s = PEIRelInitSimpleReflexive( i_ins, o_obj, rel, participant, formalizer )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
            .else
              .// Get multiplicity to pass to the code generator.
              .if ( o_obj.Obj_ID == participant.Obj_ID )
                .assign multiplicity = formalizer.Mult
              .else
                .assign multiplicity = participant.Mult
              .end if
              .invoke s = PEIRelInitSimple( i_ins, o_obj, rel, multiplicity )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
            .end if .// reflexive
          .else
            .// elif Subtype-Supertype relationship?
            .select one r_subsup related by rel->R_SUBSUP[R206]
            .if ( not_empty r_subsup )
              .invoke s = PEIRelInitSubSuper( i_ins, o_obj, rel, r_subsup )
              .assign attr_result = attr_result + s.result
          .else
            .// elif Associative relationship?
            .select one assrel related by rel->R_ASSOC[R206]
            .if ( not_empty assrel )
              .invoke s = PEIRelInitAssociative( i_ins, o_obj, rel, assrel )
              .assign attr_result = attr_result + s.result
              .assign attr_assset = attr_assset + s.assset
          .else
            .// elif Composed relationship?
            .select one composed_rel related by rel->R_COMP[R206]
            .if ( not_empty composed_rel )
              .print "\nWARNING:  R${rel.Numb} is COMPOSITION - No code generated.\n"
              .invoke s = PEIRelInitComposed( o_obj, rel )
              .assign attr_result = attr_result + s.result
          .else
            .// elif Error: New subtype of R_REL or a corrupted model SQL...
            .print "ERROR:  Unknown association type:R${rel.Numb} for class '${o_obj.Name}' (${o_obj.Key_Lett})"
            .exit 101
          .end if  .// not_empty composed_rel
          .end if  .// not_empty associative_rel
          .end if  .// not_empty subtype_supertype_rel
          .end if  .// not_empty simp_rel
          .break for
        .end if
      .end for
      .assign rel_count = rel_count + 1
    .end while .// rel_count < rel_cardinality
  .end if .// not_empty rel_set
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a simple association.
.// of multiplicity ONE.
.//=============================================================================
.function PEIRelInitSimple
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param integer multiplicity
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select any related_i_ins from instances of I_INS
  .//
  .// Find related instance index.
  .// Traverse the instance to link to instance chain
  .// to get the instance ArrayIndex.
  .if ( multiplicity == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .if ( empty related_i_ins )
      .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .end if
    .if ( not_empty related_i_ins )
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .assign attr_result = ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// not participating
      .assign attr_result = ", 0"
    .end if  .// not empty
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts1 related by links->I_LIP[R2901]->I_INS[R2958]
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts2 related by links->I_LIP[R2902]->I_INS[R2958]
    .assign related_insts = related_insts1 | related_insts2
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a simple reflexive
.// association.
.// In the reflexive case, the part and form are aligned with R2901 and R2902.
.//=============================================================================
.function PEIRelInitSimpleReflexive
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_part
  .param inst_ref r_form
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .invoke related_extent_info = GetFixedSizeClassExtentInfo( o_obj )
  .select any related_i_ins from instances of I_INS
  .//
  .// Link the formalizer to the participant.
  .//
  .if ( r_part.Mult == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .if ( not_empty related_i_ins )
      .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// Not participating.
      .assign attr_result = attr_result + ", 0"
    .end if
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts related by links->I_LIP[R2901]->I_INS[R2958]
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
  .// Now link the participant to the formalizer(s).
  .//
  .if ( r_form.Mult == 0 )
    .// ONE
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .if ( not_empty related_i_ins )
      .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// Not participating.
      .assign attr_result = attr_result + ", 0"
    .end if
  .else
    .// MANY
    .// Build linked list of containers pointing to related instances.
    .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select many related_insts related by links->I_LIP[R2902]->I_INS[R2958]
    .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
    .assign attr_result = attr_result + s.result
    .assign attr_assset = attr_assset + s.assset
  .end if
  .//
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for an associative
.// relationship.
.// In the reflexive case, R2901 and R2902 will jive with AONE and AOTH.
.// In the non-reflexive, we compare the instance Obj_ID with the
.// AONE/AOTH Obj_ID.
.//=============================================================================
.function PEIRelInitAssociative
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_assoc
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select one aone related by r_assoc->R_AONE[R209]
  .select one aoth related by r_assoc->R_AOTH[R210]
  .select one assr related by r_assoc->R_ASSR[R211]
  .//
  .// The other associated instance.
  .//
  .if ( o_obj.Obj_ID == aoth.Obj_ID )
    .// Optimize relationship to associator.
    .if ( ( aone.Mult == 0 ) and ( assr.Mult == 0 ) )
      .// ONE
      .select any link from instances of I_LNK where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .if ( empty link )
          .select one related_obj related by i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
          .if ( related_obj.Obj_ID == aoth.Obj_ID )
            .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
          .end if
        .end if  .// not empty
      .end if .// reflexive
      .if ( not_empty link )
        .select one related_i_ins related by link->I_LIP[R2903]->I_INS[R2958]
        .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
        .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .// not participating
        .assign attr_result = attr_result + ", 0"
      .end if  .// not empty
    .else
      .// MANY
      .// Build linked list of containers pointing to related instances.
      .select many links from instances of I_LNK where ( false )
      .select many related_insts from instances of I_INS where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select many links1 related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .select many links2 related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .assign links = links1 | links2
      .end if
      .select many related_insts related by links->I_LIP[R2903]->I_INS[R2958]
      .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
      .assign attr_result = attr_result + s.result
      .assign attr_assset = attr_assset + s.assset
    .end if
  .end if
  .//
  .// The one associated instance.
  .//
  .if ( o_obj.Obj_ID == aone.Obj_ID )
    .// Optimize relationship to associator.
    .if ( ( aoth.Mult == 0 ) and ( assr.Mult == 0 ) )
      .// ONE
      .select any link from instances of I_LNK where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .// reflexive
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .if ( empty link )
          .select one related_obj related by i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
          .if ( related_obj.Obj_ID == aone.Obj_ID )
            .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
          .end if
        .end if
      .end if .// reflexive
      .if ( not_empty link )
        .select one related_i_ins related by link->I_LIP[R2903]->I_INS[R2958]
        .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
        .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .// not participating
        .assign attr_result = attr_result + ", 0"
      .end if  .// not empty
    .else
      .// MANY
      .// Build linked list of containers pointing to related instances.
      .select many links from instances of I_LNK where ( false )
      .select many related_insts from instances of I_INS where ( false )
      .if ( aone.Obj_ID == aoth.Obj_ID )
        .select many links related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .else
        .select many links1 related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
        .select many links2 related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
        .assign links = links1 | links2
      .end if
      .select many related_insts related by links->I_LIP[R2903]->I_INS[R2958]
      .invoke s = PEIRenderRelationshipManyOptimization( related_insts, o_obj )
      .assign attr_result = attr_result + s.result
      .assign attr_assset = attr_assset + s.assset
    .end if
  .end if
  .//
  .// The associative instance.
  .//
  .if ( o_obj.Obj_ID == assr.Obj_ID )
    .// Optimize relationship to both associates.
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2903] where ( selected.Rel_ID == r_rel.Rel_ID )
    .if ( not_empty link )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .select one related_inst2 related by link->I_LIP[R2902]->I_INS[R2958]
      .select one related_obj2 related by related_inst2->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info2 = GetFixedSizeClassExtentInfo( related_obj2 )
      .if ( ( aone.Obj_ID == aoth.Obj_ID ) or ( related_obj2.Obj_ID == aone.Obj_ID ) )
        .assign attr_result = attr_result + ", &${related_extent_info2.obj_pool_var_name}[${related_inst2.Name}]"
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
      .else
        .assign attr_result = attr_result + ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
        .assign attr_result = attr_result + ", &${related_extent_info2.obj_pool_var_name}[${related_inst2.Name}]"
      .end if
    .else
      .// not participating
      .assign attr_result = attr_result + ", 0, 0"
    .end if  .// not empty
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a Subtype/Supertype
.// association.
.//=============================================================================
.function PEIRelInitSubSuper
  .param inst_ref i_ins
  .param inst_ref o_obj
  .param inst_ref r_rel
  .param inst_ref r_subsup
  .assign attr_result = ""
  .//
  .// Find related instance index.
  .// Traverse the instance to link to instance chain
  .// to get the instance ArrayIndex.
  .select one super related by r_subsup->R_SUPER[R212]
  .if ( o_obj.Obj_ID == super.Obj_ID )
    .// Supertype
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2901] where ( selected.Rel_ID == r_rel.Rel_ID )
    .select one related_i_ins related by link->I_LIP[R2902]->I_INS[R2958]
    .if ( empty link )
      .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
    .end if
    .if ( not_empty link )
      .select one related_object related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .select one te_class related by related_object->TE_CLASS[R2019]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_object )
      .assign attr_result = ", (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], ${te_class.system_class_number}"
    .else
      .// not participating
      .assign attr_result = ", 0, 0"
    .end if
  .else
    .// Subtype
    .select any link related by i_ins->I_LIP[R2958]->I_LNK[R2902] where ( selected.Rel_ID == r_rel.Rel_ID )
    .if ( not_empty link )
      .select one related_i_ins related by link->I_LIP[R2901]->I_INS[R2958]
      .select one related_object related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_object )
      .assign attr_result = ", &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}]"
    .else
      .// not participating
      .assign attr_result = ", 0"
    .end if
  .end if
.end function
.//
.//
.//=============================================================================
.// Generate the optimized relationship linkage for a composed association.
.//=============================================================================
.function PEIRelInitComposed
  .param inst_ref o_obj
  .param inst_ref r_rel
  .assign attr_result = ""
.end function
.//
.//
.//=============================================================================
.// Generate an initializer for the current state attribute if needed.
.//=============================================================================
.function PEIRenderInitializerBodyCurrentState
  .param inst_ref i_ins
  .param inst_ref o_obj
  .assign attr_result = ""
  .select one te_state related by i_ins->SM_STATE[R2915]->TE_STATE[R2037]
  .if ( not_empty te_state )
    .assign attr_result = te_state.enumerator
  .end if
.end function
.//
.//
.//=============================================================================
.// Render relationship MANY optimization.
.// This helper is used to render the code used to optimize a relationship
.// set.  The set variable is generated for inside the instance structure.
.// The linked list body pointing to related instances is also generated.
.//=============================================================================
.function PEIRenderRelationshipManyOptimization
  .param inst_ref_set i_inss
  .param inst_ref o_obj
  .//
  .assign attr_result = ""
  .assign attr_assset = ""
  .select any te_sys from instances of TE_SYS
  .// i_inss, o_obj
  .assign instance_count = cardinality i_inss
  .if ( instance_count > 0 )
    .select one te_class related by o_obj->TE_CLASS[R2019]
    .assign ContainerIndex = te_class.ContainerIndex
    .// A container index starting greater than zero means we are not the
    .// first (instance) to be adding linked lists.  Precede with comma.
    .if ( ContainerIndex > 0 )
      .assign attr_assset = ",\n"
    .end if
    .invoke rel_set_name = PEIGetRelationshipSetContainerName( te_class )
    .assign attr_result = ", { &${rel_set_name.result}[${ContainerIndex}] }"
    .for each related_i_ins in i_inss
      .assign ContainerIndex = ContainerIndex + 1
      .select one related_obj related by related_i_ins->CSME_CIE[R2962]->O_OBJ[R2961]
      .invoke related_extent_info = GetFixedSizeClassExtentInfo( related_obj )
      .if ( last i_inss )
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign icount = cardinality i_inss
          .if ( icount > 1 )
            .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], &${rel_set_name.result}[${ContainerIndex} - 2] }"
          .else
            .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], 0 }"
          .end if .// cardinality i_inss > 1
        .else
          .assign attr_assset = attr_assset + "  { 0, (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] }"
        .end if
      .elif ( first i_inss )
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], 0 },\n"
        .else
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] },\n"
        .end if
      .else
        .if ( te_sys.CollectionsFlavor == 20 )
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}], &${rel_set_name.result}[${ContainerIndex} - 2] },\n"
        .else
          .assign attr_assset = attr_assset + "  { &${rel_set_name.result}[${ContainerIndex}], (void *) &${related_extent_info.obj_pool_var_name}[${related_i_ins.Name}] },\n"
        .end if
      .end if
    .end for
    .assign te_class.ContainerIndex = ContainerIndex
  .else
    .// Empty relationship set.
    .assign attr_result = ", { 0 }"
  .end if
.end function
.//