Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Diff of /branches/charisee/src/compiler/high-to-mid/ProbeEin.sml
ViewVC logotype

Diff of /branches/charisee/src/compiler/high-to-mid/ProbeEin.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2829, Wed Nov 12 23:24:38 2014 UTC revision 2838, Tue Nov 25 03:40:24 2014 UTC
# Line 32  Line 32 
32      structure DstV = DstIL.Var      structure DstV = DstIL.Var
33      structure SrcV = SrcIL.Var      structure SrcV = SrcIL.Var
34      structure P=Printer      structure P=Printer
     structure shift=ShiftEin  
     structure split=SplitEin  
35      structure F=Filter      structure F=Filter
36      structure T=TransformEin      structure T=TransformEin
37        structure split=Split
38    
39      val testing=0      val testing=0
40    
41    
42      in      in
43    
44    val cnt = ref 0
45    fun genName prefix = let
46    val n = !cnt
47    in
48    cnt := n+1;
49    String.concat[prefix, "_", Int.toString n]
50    end
51    
52    
53  fun assign (x, rator, args) = (x, DstIL.OP(rator, args))  fun assign (x, rator, args) = (x, DstIL.OP(rator, args))
54  fun assignEin (x, rator, args) = ((x, DstIL.EINAPP(rator, args)))  fun assignEin (x, rator, args) = ((x, DstIL.EINAPP(rator, args)))
# Line 50  Line 57 
57      | _ =>(print(String.concat n);1)      | _ =>(print(String.concat n);1)
58      (*end case*))      (*end case*))
59    
60  (*Create fractional, and integer position vectors*)  (*transform image-space position x to world space position*)
61  fun transformToImgSpace  (dim,v,posx,imgArgDst)=let  
62    fun getTys 1= (DstTy.intTy,[],[])
63     | getTys dim = (DstTy.iVecTy dim,[dim],[dim,dim])
64    
65    
66    fun WorldToImagespace(dim,v,posx,imgArgDst)=let
67      val translate=DstOp.Translate v      val translate=DstOp.Translate v
68      val transform=DstOp.Transform v      val transform=DstOp.Transform v
69      val M  = DstV.new ("M", DstTy.tensorTy [dim,dim])   (*transform dim by dim?*)          val (_ ,fty,pty)=getTys dim
70      val T  = DstV.new ("T", DstTy.tensorTy [dim])   (*translate*)          val mty=DstTy.TensorTy  pty
71      val x  = DstV.new ("x", DstTy.vecTy dim)            (*Image-Space position*)          val rty=DstTy.TensorTy fty
72      val x0  = DstV.new ("x0", DstTy.vecTy dim)  
73      val x1  = DstV.new ("x1", DstTy.vecTy dim)          val M  = DstV.new (genName "M", mty)   (*transform dim by dim?*)
74      val f  = DstV.new ("f", DstTy.vecTy dim)            (*fractional*)          val T  = DstV.new (genName "T", rty)
75      val nd = DstV.new ("nd", DstTy.vecTy dim)           (*real position*)          val x  = DstV.new (genName "x", rty)            (*Image-Space position*)
76      val n  = DstV.new ("n", DstTy.iVecTy dim)           (*integer position*)          val x0  = DstV.new (genName "x0", rty)
77      val PosToImgSpace=mk.transform(dim,dim)          val (PosToImgSpaceA,PosToImgSpaceB)=(case dim
78      val PosToImgSpaceA=mk.transformA(dim,dim)              of 1=>(mk.prodScalar,mk.addScalar)
79      val PosToImgSpaceB=mk.transformB dim              | _ => (mk.transformA(dim,dim) ,mk.transformB(dim))
80      val P  = DstV.new ("P", DstTy.tensorTy [dim,dim])   (*transform dim by dim?*)              (*end case*))
81      val code=[      val code=[
82          assign(M, transform, [imgArgDst]),          assign(M, transform, [imgArgDst]),
83          assign(T, translate, [imgArgDst]),          assign(T, translate, [imgArgDst]),
84          (*assignEin(x, PosToImgSpace,[M,posx,T]) ,  (* MX+T*)*)              assignEin(x0, PosToImgSpaceA,[M,posx]) , (*xo=MX*)
85          assignEin(x0, PosToImgSpaceA,[M,posx]) ,              assignEin(x, PosToImgSpaceB,[x0,T])  (*x=x0+T*)
86          assignEin(x, PosToImgSpaceB,[x0,T]) ,          ]
87        in (M,x,code)
88            end
89    
90    
91    (*Create fractional, and integer position vectors*)
92    fun transformToImgSpace  (dim,v,posx,imgArgDst)=let
93        val (ity,fty,pty)=getTys dim
94        val mty=DstTy.TensorTy  pty
95        val rty=DstTy.TensorTy fty
96    
97        val f  = DstV.new ("f", rty)            (*fractional*)
98        val nd = DstV.new ("nd",  rty)           (*real position*)
99        val n  = DstV.new ("n", ity)           (*integer position*)
100        val P  = DstV.new ("P",mty)   (*transform dim by dim?*)
101    
102        val (M,x,code1)=WorldToImagespace(dim,v,posx,imgArgDst)
103        val (P,PCode)=(case dim
104            of 1=>(M,[])
105            | _ =>(P,[assignEin(P, mk.transpose(pty), [M])])
106            (*end case*))
107        val code=[
108          assign(nd, DstOp.Floor dim, [x]),   (*nd *)          assign(nd, DstOp.Floor dim, [x]),   (*nd *)
109          assignEin(f, mk.subTen([dim]),[x,nd]),           (*fractional*)          assignEin(f, mk.subTen(fty),[x,nd]),           (*fractional*)
110          assign(n, DstOp.RealToInt dim, [nd]), (*real to Int*)          assign(n, DstOp.RealToInt dim, [nd]) (*real to Int*)
         assignEin(P, mk.transpose([dim,dim]), [M])  
111          ]          ]
112      in ([n,f],P,code)      in ([n,f],P,code1@PCode@code)
113      end      end
114    
 fun getRHS x  = (case SrcIL.Var.binding x  
     of SrcIL.VB_RHS(SrcIL.OP(rator, args)) => (rator, args)  
     | SrcIL.VB_RHS(SrcIL.VAR x') => getRHS x'  
     | vb => raise Fail(concat[ "expected rhs operator for ", SrcIL.Var.toString x, "but found ", SrcIL.vbToString vb])  
     (* end case *))  
115    
116  (*Get Img, and Kern Args*)   fun getRHSDst x  = (case DstIL.Var.binding x
117  fun getArgs(hid,hArg,V,imgArg,args,lift,varI)=(case (getRHS hArg,getRHS imgArg)      of DstIL.VB_RHS(DstIL.OP(rator, args)) => (rator, args)
118      of ((SrcOp.Kernel(h, i), _ ),(SrcOp.LoadImage img, _ ))=> let      | DstIL.VB_RHS(DstIL.VAR x') => getRHSDst x'
119          val hvar=DstV.new ("KNL", DstTy.KernelTy)      | vb => raise Fail(concat[ "expected rhs operator for ", DstIL.Var.toString x, "but found ", DstIL.vbToString vb])
         val imgvar=DstV.new ("IMG", DstTy.ImageTy img)  
         val argsVK= (case lift  
             of 0=> let  
                 val _=print "non lift"  
                 val l1=List.take(args, hid)  
                 val l2=List.drop(args,hid+1)  
                 in  
                     l1@[hvar]@l2  
                 end  
             | _ => [varI, hvar]  
120          (* end case *))          (* end case *))
121    
122          val assigments=[assign (hvar, DstOp.Kernel(h, i), [])]  
123     (*Get Img, and Kern Args*)
124     fun getArgsDst(hid,hArg,imgArg,args)=(case (getRHSDst hArg,getRHSDst imgArg)
125        of ((DstOp.Kernel(h, i), _ ),(DstOp.LoadImage img, _ ))=> let
126          in          in
127              ((Kernel.support h) ,img, assigments,argsVK)          ((Kernel.support h) ,img)
128          end          end
129      |  _ => raise Fail "Expected Image and kernel argument"      |  _ => raise Fail "Expected Image and kernel argument"
130      (*end case*))      (*end case*))
131    
132    
133  fun handleArgs(V,h,t,(params,args),origargs,lift,dstargs)=let  
134      val E.IMG(dim)=List.nth(params,V)  fun handleArgs(V,hid,t,args)=let
135      val kArg=List.nth(origargs,h)      val hArg=List.nth(args,hid)
136      val imgArg=List.nth(origargs,V)      val imgArg=List.nth(args,V)
137      val newposArg=List.nth(args, t)      val newposArg=List.nth(args, t)
138      val imgArgDst=List.nth(dstargs,V)      val (s,img) =getArgsDst(hid,hArg,imgArg,args)
139      val (s,img,argcode,argsVH) =getArgs(h,kArg,V,imgArg,args,lift,imgArgDst)      val dim=ImageInfo.dim img
140      val (argsT,P,code')=transformToImgSpace(dim,img,newposArg,imgArgDst)      val (argsT,P,code)=transformToImgSpace(dim,img,newposArg,imgArg)
141      in (dim,argsVH@argsT,argcode@code', s,P)      in (dim,args@argsT,code, s,P)
142      end      end
143    
144    
 (*createDels=> creates the kronecker deltas for each Kernel*)  
 fun createDels([],_)= []  
     | createDels(d::ds,dim)= [( E.C dim,d)]@createDels(ds,dim)  
   
145  (*Created new body for probe*)  (*Created new body for probe*)
146  fun createBody(dim, s,sx,shape,deltas,V, h, nid, fid)=let  fun createBody(dim, s,sx,shape,deltas,V, h, nid, fid)=let
147    
148      (*sumIndex creating summaiton Index for body*)      (*sumIndex creating summaiton Index for body*)
149      fun sumIndex(0)=[]      fun sumIndex 0=[]
150      |sumIndex(dim)= sumIndex(dim-1)@[(E.V (dim+sx-1),1-s,s)]      |sumIndex(dim)= sumIndex(dim-1)@[(E.V (dim+sx-1),1-s,s)]
151    
152    
153        fun createKRND1 ()=let
154            val sum=sx
155            val dels=List.map (fn e=>(E.C 0,e)) deltas
156            val pos=[E.Add[E.Tensor(fid,[]),E.Value(sum)]]
157            val rest= E.Krn(h,dels,E.Sub(E.Tensor(nid,[]),E.Value(sum)))
158            in
159                E.Prod [E.Img(V,shape,pos),rest]
160    
161            end
162    
163      (*createKRN Image field and kernels *)      (*createKRN Image field and kernels *)
164      fun createKRN(0,imgpos,rest)=E.Prod ([E.Img(V,shape,imgpos)] @rest)      fun createKRN(0,imgpos,rest)=E.Prod ([E.Img(V,shape,imgpos)] @rest)
165      | createKRN(dim,imgpos,rest)=let      | createKRN(dim,imgpos,rest)=let
166          val dim'=dim-1          val dim'=dim-1
167          val sum=sx+dim'          val sum=sx+dim'
168          val dels=createDels(deltas,dim')          val dels=List.map (fn e=>(E.C dim',e)) deltas
169          val pos=[E.Add[E.Tensor(fid,[E.C dim']),E.Value(sum)]]          val pos=[E.Add[E.Tensor(fid,[E.C dim']),E.Value(sum)]]
170          val rest'= E.Krn(h,dels,E.Sub(E.Tensor(nid,[E.C dim']),E.Value(sum)))          val rest'= E.Krn(h,dels,E.Sub(E.Tensor(nid,[E.C dim']),E.Value(sum)))
171          in          in
172              createKRN(dim',pos@imgpos,[rest']@rest)              createKRN(dim',pos@imgpos,[rest']@rest)
173          end          end
174    
175      val exp=createKRN(dim, [],[])      val exp=(case dim
176            of 1 => createKRND1()
177            | _=> createKRN(dim, [],[])
178            (*end case*))
179    
180      val esum=sumIndex (dim)      val esum=sumIndex (dim)
181      in E.Sum(esum, exp)      in E.Sum(esum, exp)
182      end      end
# Line 164  Line 194 
194      | mapIndex(E.C c::es,index) = mapIndex(es,index)      | mapIndex(E.C c::es,index) = mapIndex(es,index)
195    
196    
 (*  
 (*Lift probe and Multiply by P*)  
 fun liftProbe(E.Probe(E.Conv(V,alpha,H,dx),E.Tensor(t,_)),(params,args),index, sumIndex,origargs)=let  
     val _ =print "Lift Probe"  
   
     val n=length(index)  
     val ns=length sumIndex  
     val nshift=length(dx)  
     val np=length(params)  
     val nsumshift =(case ns  
         of 0=>   n  
         |_=>let  val (E.V v,_,_)=List.nth(sumIndex, ns-1)  
             in  
                 v+1  
             end  
         (* end case *))  
   
   
     (*Outer Index-id Of Probe*)  
     val VShape=ShapeConv(alpha, n)  
     val HShape=ShapeConv(dx, n)  
     val shape=VShape@HShape  
   
     (* Bindings for Shape*)  
     val shapebind= mapIndex(shape,index)  
     val Vshapebind= mapIndex(VShape,index)  
   
     (*Look at Args and get dim, mid-il ops, support, and Arg for transformation matrix P*)  
     val (dim,args',code,support,PArg) = handleArgs(V,H,t,(params,args), origargs,1)  
     val _ =print("\nSupport is "^Int.toString support)  
   
     (*New transformations:params, sx, rest, will be empty if no transformation is made*)  
     val (oldArg,newArg,dx, paramsT,sxT,restT,ixT,dataT) = T.Transform(dx,shapebind,Vshapebind,dim,PArg,nsumshift,ns,4)  
   
     (*rewriteBody*)  
     val bodyExpanded = createBody(dim, support,nsumshift+nshift,alpha,dx,0, 1, 3, 2)  
   
     val sx=sumIndex@sxT  
     val body'=(case sx  
         of [] =>E.Prod(restT@[bodyExpanded])  
         | _ => E.Sum(sx, E.Prod(restT@[bodyExpanded]))  
         (*end case*))  
   
     (*create new EIN OPerator*)  
     val _ =print("Found this many args ")  
     val _ =print(Int.toString(length(args')))  
   
     val params'=[E.IMG(dim),E.KRN,E.TEN(3,[dim]),E.TEN(1,[dim])]@paramsT  
     val (p',i',b',a')=shift.clean(params', index@ixT, body', args'@[PArg])  
     val newbie'=Ein.EIN{params=p', index=i', body=b'}  
     val data=assignEin (oldArg, newbie', a')  
   
     val _ = (case testing  
         of 0 => 1  
         | _ => (print(String.concat["\n Lift Probe\n", split.printA(newArg, newbie', a'),"\n"]);1)  
         (*end case *))  
     in  
         (E.Tensor(np,shape), (params@[E.TEN(1,shapebind)],args@[newArg]),code@[data]@dataT)  
     end  
  |liftProbe _ =raise Fail"Incorrect body for Probe"  
   
 *)  
   
197    
198   (* Expand probe in place *)   (* Expand probe in place eplaceProbe(b,params,args, index, sx,args)*)
199   fun replaceProbe(b,(params,args),index, sumIndex,origargs,dstargs)=let   fun replaceProbe(b,params,args,index, sumIndex)=let
200    
201      val E.Probe(E.Conv(V,alpha,h,dx),E.Tensor(t,_))=b      val E.Probe(E.Conv(V,alpha,h,dx),E.Tensor(t,_))=b
202      val fid=length(params)      val fid=length(params)
203      val nid=fid+1      val nid=fid+1
204      val n=length(index)      val n=length(index)
205      val ns=length sumIndex  
206      val nshift=length(dx)      val nshift=length(dx)
207      val nsumshift =(case ns      val nsumshift =(case sumIndex
208          of 0=> n          of []=> n
209          | _=>let          | _=>let
210              val (E.V v,_,_)=List.nth(sumIndex, ns-1)              val (E.V v,_,_)=List.hd(List.rev sumIndex)
211              in v+1              in v+1
212              end              end
213      (* end case *))      (* end case *))
214    
215        val aa=List.map (fn (E.V v,_,_)=>Int.toString v) sumIndex
216        val _ =testp["\n", "SumIndex" ,(String.concatWith"," aa),"\nThink nshift is ", Int.toString nsumshift]
217    
218      (*Outer Index-id Of Probe*)      (*Outer Index-id Of Probe*)
219      val VShape=ShapeConv(alpha, n)      val VShape=ShapeConv(alpha, n)
220      val HShape=ShapeConv(dx, n)      val HShape=ShapeConv(dx, n)
# Line 254  Line 224 
224      val Vshapebind= mapIndex(VShape,index)      val Vshapebind= mapIndex(VShape,index)
225    
226    
227      val (dim,argsA,code,s,PArg) = handleArgs(V,h,t,(params,args), origargs,0,dstargs)      val (dim,argsA,code,s,PArg) = handleArgs(V,h,t,args)
     val _ =testp["\nSupport is ",Int.toString s]  
228      val (_,_,dx, _,sxT,restT,_,_) = T.Transform(dx,shapebind,Vshapebind,dim,PArg,nsumshift,1,nid+1)      val (_,_,dx, _,sxT,restT,_,_) = T.Transform(dx,shapebind,Vshapebind,dim,PArg,nsumshift,1,nid+1)
229    
230      val params'=params@[E.TEN(3,[dim]),E.TEN(1,[dim]),E.TEN(1,[dim,dim])]      val params'=params@[E.TEN(3,[dim]),E.TEN(1,[dim]),E.TEN(1,[dim,dim])]
# Line 265  Line 234 
234          | _ => E.Sum(sxT, E.Prod(restT@[body'']))          | _ => E.Sum(sxT, E.Prod(restT@[body'']))
235          (*end case*))          (*end case*))
236      val args'=argsA@[PArg]      val args'=argsA@[PArg]
     val subexp=Ein.EIN{params=params', index=index, body=body'}  
     val _ = testp["\n Don't replace probe  \n $$$ new sub-expression $$$ \n",P.printerE(subexp),"\n"]  
   
     in (body',(params',args') ,code)  
     end  
   
 (*  
 (*Checks if (1) Summation variable occurs just once (2) it matches n.  
 Then we lift otherwise expand in place *)  
 fun checkSum(sx,b,info,index,origargs)=(case sx  
     of [(E.V i,lb,ub)]=>  let  
         val E.Probe(E.Conv(V,alpha,h,dx), E.Tensor(id,beta))=b  
         val n=length(index)  
         val _=(case testing  
             of 1=> (print(String.concat["in check Sum\n " ,P.printbody(E.Sum([(E.V i,lb,ub)],b))]);1)  
             |_ => 1)  
237          in          in
238              if (i=n) then (case F.countSx(sx,b)          (body',params',args' ,code)
                 of (1,ixx) => liftProbe(b,info,index@[ub], [],origargs)  
                 | _ => replaceProbe(b, info,index,sx,origargs)  
                 (*end case*))  
             else replaceProbe(b, info,index, sx,origargs)  
239          end          end
     | _ =>replaceProbe(b, info,index, sx,origargs)  
     (*end case*))  
 *)  
   
 fun flatten []=[]  
     | flatten(e1::es)=e1@(flatten es)  
240    
241    
242   (* sx-[] then move out, otherwise keep in *)   (* sx-[] then move out, otherwise keep in *)
243  fun expandEinOp ( Ein.EIN{params, index, body}, origargs,args) = let  fun expandEinOp( e as (y, DstIL.EINAPP(Ein.EIN{params, index, body}, args))) = let
244    
     val dummy=E.Const 0  
     val sumIndex=ref []  
245    
246      (*b-current body, info-original ein op, data-new assigments*)      (*b-current body, info-original ein op, data-new assigments*)
247      fun rewriteBody(b,info)= let      fun rewriteBody b= let
   
         fun callfn(c1,body)=let  
             val ref x=sumIndex  
             val c'=[c1]@x  
             val (bodyK,infoK,dataK)= (sumIndex:=c';rewriteBody(body ,info))  
             val ref s=sumIndex  
             val z=hd(s)  
             val e'=( case bodyK  
                 of E.Const _ =>bodyK  
                 | _ => E.Sum(z,bodyK)  
                 (*end case*))  
             in  
                 (sumIndex:=tl(s);(e',infoK,dataK))  
             end  
   
   
         (*Nothing liftProbe and checkSum are commented out.  
             Some mistake underestimating size of dimension*)  
   
         fun filter es=let  
             fun filterApply([], doneB, infoB, dataB)= (doneB, infoB,dataB)  
             | filterApply(B::es, doneA, infoA,dataA)= let  
                 val (bodyB, infoB,dataB)= rewriteBody(B,infoA)  
                 in  
                     filterApply(es, doneA@[bodyB], infoB,dataA@dataB)  
                 end  
             in filterApply(es, [],info,[])  
             end  
248          in (case b          in (case b
249              of  E.Sum(c,  E.Probe(E.Conv v, E.Tensor t)) =>let              of E.Probe(E.Conv _, E.Tensor _) =>let
250                  val ref sx=sumIndex              val (body',params',args',newbies)=replaceProbe(b, params,args,index, [])
251                  in (case sx              val einapp=(y,DstIL.EINAPP(Ein.EIN{params=params', index=index, body=body'},args'))
252                      of  (* [] => liftProbe(E.Probe(E.Conv v, E.Tensor t ), info,index, c,origargs)              val code=newbies@[einapp]
253                        | [i]=> checkSum(i,b, info,index,origargs)              in
254                        |*) _ => let                  (1,code)
255                          val (b,m,code)=replaceProbe(E.Probe(E.Conv v, E.Tensor t ), info,index, (flatten sx)@c,origargs,args)              end
256                          in (E.Sum(c,b),m,code)          | E.Sum(sx,E.Probe e) =>let
257                          end              val (body',params',args',newbies)=replaceProbe(E.Probe e,params,args, index, sx)
258                  (* end case*))              val  body'=E.Sum(sx,body')
259              end              val einapp=(y,DstIL.EINAPP(Ein.EIN{params=params', index=index, body=body'},args'))
260          | E.Probe(E.Conv _, E.Tensor _) =>let              val code=newbies@[einapp]
             val ref sx=sumIndex  
             in (case sx  
                 of (* []=> liftProbe(b, info,index, [],origargs)  
                 | [i]=> checkSum(i,b, info,index,origargs)  
                 |*) _ => replaceProbe(b, info,index, flatten sx,origargs,args)  
              (* end case*))  
             end  
         | E.Probe _=> (dummy,info,[])  
         | E.Conv _=>  (dummy,info,[])  
         | E.Lift _=> (dummy,info,[])  
         | E.Field _ => (dummy,info,[])  
         | E.Apply _ => (dummy,info,[])  
         | E.Neg e=> let  
             val (body',info',data')=rewriteBody(e,info)  
261              in              in
262                  (E.Neg(body'),info',data')                  (1,code)
263              end              end
264          | E.Sum (c,e)=> callfn(c,e)          | _=> (0,[e])
         | E.Sub(a,b)=>let  
             val (bodyA,infoA,dataA)= rewriteBody(a,info)  
             val (bodyB, infoB, dataB)= rewriteBody(b,infoA)  
             in   (E.Sub(bodyA, bodyB),infoB,dataA@dataB)  
             end  
         | E.Div(a,b)=>let  
             val (bodyA,infoA,dataA)= rewriteBody(a,info)  
             val (bodyB, infoB,dataB)= rewriteBody(b,infoA)  
             in  (E.Div(bodyA, bodyB),infoB,dataA@dataB) end  
         | E.Add es=> let  
             val (done, info',data')= filter es  
             val (_, e)=F.mkAdd done  
             in (e, info',data')  
             end  
         | E.Prod es=> let  
             val (done, info',data')= filter es  
             val (_, e)=F.mkProd done  
             in (e, info',data')  
             end  
         | _=>  (b,info,[])  
265          (* end case *))          (* end case *))
266          end          end
267    
268       val empty =fn key =>NONE       val empty =fn key =>NONE
      val _ =(case testing  
         of 0 => 1  
         | _ => (print "\n ************************** \n Starting Expand";1)  
         (*end case*))  
269    
270      val (body',(params',args'),newbies)=rewriteBody(body,(params,args))      val (c,code)=rewriteBody body
271      val e'=Ein.EIN{params=params', index=index, body=body'}      val b=String.concatWith",\t"(List.map split.printEINAPP code)
272      (*val _ =(case testing      val _ =(case c
273          of 0 => 1          of 1 =>print(String.concat["\nbody",split.printEINAPP e, "\n=>\n",b ])
274          | _ => (String.concat[P.printerE(e'),"\n DONE expand ************************** \n "];1)          | _ =>print(String.concat[""])
275          (*end case*))*)          (*end case*))
276      in      in
277          ((e',args'),newbies)          code
278      end      end
279    
280    end; (* local *)    end; (* local *)

Legend:
Removed from v.2829  
changed lines
  Added in v.2838

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0