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

SCM Repository

[diderot] View of /branches/charisee/src/compiler/high-il/EpsHelpers.sml
ViewVC logotype

View of /branches/charisee/src/compiler/high-il/EpsHelpers.sml

Parent Directory Parent Directory | Revision Log Revision Log

Revision 2605 - (download) (annotate)
Wed Apr 30 01:46:09 2014 UTC (7 years, 2 months ago) by cchiw
File size: 4932 byte(s)
code cleanup
structure EpsHelpers = struct


    structure E = Ein
    structure P=Printer
    structure F=Filter

fun err str=raise Fail (String.concat["Ill-formed EIN Operator",str])


(*remove eps Index*)

fun rmEpsIndex(i,[],[],[])= []
    | rmEpsIndex(i,[],x,[])= [x]
    | rmEpsIndex(i,[],x,e::es)= rmEpsIndex(i,e,[],es)@[x]
    | rmEpsIndex(i,  ( c ,lb, ub)::b,x, es)=
        if (i=c) then let
                val z=[(x@b)]
                in (case z of [] => es |_=>z@es) end
        else rmEpsIndex(i,b,x@[(c ,lb, ub)],es)
fun doubleEps(count,E.Epsilon (a,b,c),E.Epsilon(d,e,f))=let
    (*Function is called when eps are being changed to deltas*)
    fun createDeltas(i,s,t,u,v)= let
        val c'= rmEpsIndex(E.V i,[],[],count)
        val d1=[E.Delta(E.V s,E.V u), E.Delta(E.V t,E.V v)]
        val d2= [E.Delta(E.V s,E.V v), E.Delta(E.V t,E.V u)]
        in (1,c',d1,d2)
    in if(a=d) then createDeltas(a,b,c,e,f)
        else if(a=e) then createDeltas(a,b,c,f,d)
        else if(a=f) then createDeltas(a,b,c,d,e)
        else if(b=d) then createDeltas(b,c,a,e,f)
        else if(b=e) then createDeltas(b,c,a,f,d)
        else if(b=f) then createDeltas(b,c,a,d,e)
        else if(c=d) then createDeltas(c,a,b,e,f)
        else if(c=e) then createDeltas(c,a,b,f,d)
        else if(c=f) then createDeltas(c,a,b,d,e)
        else (0,[],[],[])
fun distEps([],eps,_,_)=(0,[],[],[],[])
    | distEps([e],eps,_,_)=(0,[],[],[],[])
    | distEps(e1::e2::[],eps,c1::count,sx)=let
        val(change,c',d1,d2)= doubleEps([c1@sx]@count,e1,e2)
        in (case change
        of 1=>(1, c', eps, d1,d2)
        |_=> (0,[],[],[],[])
        (*end case*))
    | distEps(e1::e2::current,eps,count,sx)=let
        val(change,c',d1,d2)= doubleEps(count,e1,e2)
        in (case change
            of 1=>(1, c', eps@current, d1,d2)
            |_=> distEps(e2::current, eps@[e1],count,sx)
            (*end case*))

(* Transform eps to deltas*)
fun epsToDels(count,E.Prod e)= let
    val (epsA,es,sx)=F.findeps([],e,[])
    val (change, s', eps,d1,d2)= distEps(epsA,[],count,sx)
    val deltas=E.Sub(E.Prod d1,E.Prod d2)
    in (case (change,eps,es)
        of (0,_,_)=>(0,[],epsA,es)
        |(_,[],[]) =>(1,s',[deltas],[])
        | _ =>(1,s',[E.Sub( E.Prod(eps@d1@es), E.Prod(eps@d2@es))],[])
        (*end case *))

(*Another strategy. Go through entire expression inside summation and jsut examine index to apply deltas*)
(* Apply deltas to tensors/fields*)
fun reduceDelta(c, eps, dels, es)=let
    fun distribute(change,d,dels,[],done)=(change,dels@d,done)
        | distribute(change,[],[],e,done)=(change,[],done@e)
        | distribute(change,[],dels,e::es,done)=distribute(change,dels,[],es,done@[e])
        | distribute(change,E.Delta(i,j)::ds,dels,e::es,done)=(case e
                of  E.Tensor(id,[tx])=>
                    if(j=tx) then distribute(change@[j],dels@ds,[] ,es ,done@[E.Tensor(id,[i])])
                    else distribute(change,ds,dels@[E.Delta(i,j)],E.Tensor(id,[tx])::es,done)
            |  E.Field(id,[tx])=>
                    if(j=tx) then distribute(change@[j],dels@ds,[] ,es ,done@[E.Field(id,[i])])
                    else distribute(change,ds,dels@[E.Delta(i,j)],E.Field(id,[tx])::es,done)
            | E.Apply(E.Partial d,e)=>let
                fun distPart([],rest) =(0 ,rest)
                    | distPart(p::pd,rest)=
                        if(p=j) then (1,rest@[i]@pd)
                        else (distPart(pd,rest@[p]))
                        val (change'',p')=distPart(d,[])
                in (case change''
                    of 0=>distribute(change, ds,dels@[E.Delta(i,j)], [E.Apply(E.Partial d, e)]@es,done)
                    |_=> distribute(change@[j], dels@ds,[], es,done@[E.Apply(E.Partial p', e)])
                    (*end case*))
            | _=>distribute(change,dels@[E.Delta(i,j)]@ds,[],es,done@[e])
            (*end case*))

    val (change,dels',done)=distribute([],dels,[],es,[])
     fun m([],c')=c'
        | m(e::es,c')= let val s=rmEpsIndex(e,[],[],c')
          in m(es, s) end
    val index= m(change, c)
       (length change, index,E.Prod (eps@dels'@done))

fun matchEps(2,_,_,_)= 1 (*matched 2*)
    | matchEps(num,_,_,[])=0
    | matchEps(0,_,_,[eps])=0
    | matchEps(num,[],rest,eps::epsx)=
    | matchEps(num,E.V p::px,rest,eps::epsx)=
        if(p=eps) then (matchEps(num+1,rest@px,[],epsx))
        else matchEps(num,px,rest@[E.V p], eps::epsx)
    | matchEps(num,p::px,rest,eps)= matchEps(num,px,rest,eps)


end (* local *)

ViewVC Help
Powered by ViewVC 1.0.0