anchor.diff:  open corelang
   
   
  -let divide2Mult_exp = 
  -  <@ 
  -    (%a / %b) / %c
  -    <==> 
  -    %a / (%b * %c)
  -  @>
  -
  -let distrMult_exp = 
  -  <@
  -    %a * (%b + %c)
  -    <==>
  -    %a * %b + %a * %c
  -  @>
  -
  -let constFold0_exp = 
  -  <@ 
  -    %a + 0.
  -    <==>
  -    %a
  -  @>
  -
  -let constFold1_exp = 
  -  <@ 
  -    %a * 1.
  -    <==>
  -    %a
  -  @>
  -
  -let subSame_exp = 
  -  <@
  -    %a - %a
  -    <==>
  -    0.0
  -  @>
  -
  -let multDivide_exp = 
  -  <@
  -    %a * (%b / %a)
  -    <==>
  -    %b
  -  @>
  -
  -let assocAddSub_exp = 
  -  <@
  -    (%a + %b) - %c
  -    <==>
  -    %a + (%b - %c)
  -  @>
  -
  -let assocAddAdd_exp = 
  -  <@
  -    (%a + %b) + %c
  -    <==>
  -    %a + (%b + %c)
  -  @>
  -
  -let assocSubSub_exp = 
  -  <@
  -    (%a - %b) - %c
  -    <==>
  -    %a - (%b + %c)
  -  @>
  -
  -let indexToDoubleToInt_exp = 
  -  <@ 
  -    int (double %k)
  -    <==>
  -    %k
  -  @>
  -
  -let vectorBuildGet_exp = 
  -  <@
  -    (vectorBuild %k %F).[%i]
  -    <==>
  -    (%F) %i
  -  @>
  -
  -let vectorBuildLength_exp = 
  -  <@
  -    (vectorBuild %k %F).Length
  -    <==>
  -    %k
  -  @>
  -
  -let comAddIndex_exp = 
  -  <@
  -    %i + %j
  -    <==>
  -    %j + %i
  -  @>
  -
  -let assocAddSubIndex_exp = 
  -  <@
  -    (%i + %j) - %k
  -    <==>
  -    %i + (%j - %k)
  -  @>
  -
  -let assocSubAddIndex_exp = 
  -  <@
  -    (%i - %j) + %k
  -    <==>
  -    %i - (%j - %k)
  -  @>
  -
  -let assocSubSubIndex_exp = 
  -  <@
  -    (%i - %j) - %k
  -    <==>
  -    %i - (%j + %k)
  -  @>
  -
  -let subSameIndex_exp = 
  -  <@
  -    %i - %i
  -    <==>
  -    0
  -  @>
  -
  -let constFold0Index_exp = 
  -  <@ 
  -    %i + 0
  -    <==>
  -    %i
  -  @>
  -
  -let constFoldN0Index_exp = 
  -  <@ 
  -    %i - 0
  -    <==>
  -    %i
  -  @>
  +let divide2Mult_exp        = <@ (%a / %b) / %c             <==>   %a / (%b * %c)      @>
  +let distrMult_exp          = <@ %a * (%b + %c)             <==>   %a * %b + %a * %c   @>
  +let constFold0_exp         = <@ %a + 0.                    <==>   %a                  @>
  +let constFold1_exp         = <@ %a * 1.                    <==>   %a                  @>
  +let subSame_exp            = <@ %a - %a                    <==>   0.0                 @>
  +let multDivide_exp         = <@ %a * (%b / %a)             <==>   %b                  @>
  +let assocAddSub_exp        = <@ (%a + %b) - %c             <==>   %a + (%b - %c)      @>
  +let assocAddAdd_exp        = <@ (%a + %b) + %c             <==>   %a + (%b + %c)      @>
  +let assocSubSub_exp        = <@ (%a - %b) - %c             <==>   %a - (%b + %c)      @>
  +let indexToDoubleToInt_exp = <@ int (double %k)            <==>   %k                  @>
  +let vectorBuildGet_exp     = <@ (vectorBuild %k %F).[%i]   <==>   (%F) %i             @>
  +let vectorBuildLength_exp  = <@ (vectorBuild %k %F).Length <==>   %k                  @>
  +let comAddIndex_exp        = <@ %i + %j                    <==>   %j + %i             @>
  +let assocAddSubIndex_exp   = <@ (%i + %j) - %k             <==>   %i + (%j - %k)      @>
  +let assocSubAddIndex_exp   = <@ (%i - %j) + %k             <==>   %i - (%j - %k)      @>
  +let assocSubSubIndex_exp   = <@ (%i - %j) - %k             <==>   %i - (%j + %k)      @>
  +let subSameIndex_exp       = <@ %i - %i                    <==>   0                   @>
  +let constFold0Index_exp    = <@ %i + 0                     <==>   %i                  @>
  +let constFoldN0Index_exp   = <@ %i - 0                     <==>   %i                  @>
  +let dce_exp                = <@ ( let x = %E1 in %E2: T1 ) <==>   %E2                 @>
  +let vectorFoldBuildToFoldOnRange_exp = 
  +                             <@ vectorFoldNumber %F %a (vectorBuild %k %G)
  +                                                           <==>
  +                                linalg.iterateNumber (fun acc idx -> (%F) acc ((%G) idx)) %a 0 (%k - 1)
  +                                                                                      @>
  +let vectorBuildToStorage_exp = 
  +                             <@ vectorBuild (%k) (%F)      
  +                                                           <==>
  +                                (let s = vectorAlloc (%k) in vectorBuildGivenStorage s (%F))
  +                                                                                      @>
  +
  +let vectorAddToStorage_exp = <@ linalg.add_vec %U %V       
  +                                                           <==>
  +                                (let s2 = vectorAlloc ((%U).Length) in linalg.add_vecGivenStorage s2 %U %V)
  +                                                                                      @>
  +
  +let letVectorBuildLength_exp = 
  +                             <@ ( let x = (vectorBuild %k %F) in ((%B1) x.Length x): T1 )
  +                                                           <==>
  +                                ( let x = (vectorBuild %k %F) in (%B1) %k x )
  +                                                                                      @>
  +
  +let letInliner_exp         = <@ ((let x = %E1 in (%B1) x): T1)
  +                                                           <==> (%B1) %E1             @>
  +
  +let letMerging_exp         = <@ ( let x: T1 = %E1 in let y: T1 = %E1 in ((%B1) x y): T2 )
  +                                                           <==>
  +                                let x: T1 = %E1 in (%B1) x x
  +                                                                                      @>
  +
  +let letCommutingConversion_exp 
  +                           = <@ ( let x: T1 = (let y: T2 = %E1 in (%B1) y) in ((%B2) x): T3 )
  +                                                           <==>
  +                                let y: T2 = %E1 in let x: T1 = (%B1) y in (%B2) x
  +                                                                                      @>
  +
  +let letReorder_exp         = <@ ( let x: T1 = %E1 in let y: T2 = %E2 in ((%B1) x y): T3 )
  +                                                           <==>
  +                                let y: T2 = %E2 in let x: T1 = %E1 in ((%B1) x y): T3
  +                                                                                      @>
  +
  +let copyLet_exp            = <@ ( vectorCopy %stg1 (let x = %E1 in (%B1) x) )
  +                                                           <==>
  +                                ( let x = %E1 in vectorCopy %stg1 ((%B1) x) )
  +                                                                                      @>
   
   // FIXME doesn't work
  -let vectorSliceToBuild_exp = 
  -  <@
  +let vectorSliceToBuild_exp = <@
       (%V).[(%i)..(%j)]
       <==>
       vectorBuild (%j - %i + 1) (fun i -> (%V).[i])
  -  @>
  -
  -let vectorFoldBuildToFoldOnRange_exp = 
  -  <@
  -    vectorFoldNumber %F %a (vectorBuild %k %G)
  -    <==>
  -    linalg.iterateNumber (fun acc idx -> (%F) acc ((%G) idx)) %a 0 (%k - 1)
  -  @>
  -
  -let vectorBuildToStorage_exp = 
  -  <@
  -    vectorBuild (%k) (%F)
  -    <==>
  -    (let s = vectorAlloc (%k) in vectorBuildGivenStorage s (%F))
  -  @>
  -
  -let vectorAddToStorage_exp = 
  -  <@
  -    linalg.add_vec %U %V
  -    <==>
  -    (let s2 = vectorAlloc ((%U).Length) in linalg.add_vecGivenStorage s2 %U %V)
  -  @>
  -
  -let letVectorBuildLength_exp =
  -  <@
  -    (
  -      let x = (vectorBuild %k %F)
  -      ((%B1) x.Length x): T1
  -    )
  -    <==>
  -    (
  -      let x = (vectorBuild %k %F)
  -      (%B1) %k x
  -    )
  -  @>
  -
  -let letInliner_exp = 
  -  <@
  -    ((let x = %E1 in (%B1) x): T1)
  -    <==>
  -    (%B1) %E1
  -  @>
  -
  -let letMerging_exp = 
  -  <@
  -    (
  -      let x: T1 = %E1
  -      let y: T1 = %E1
  -      ((%B1) x y): T2
  -    )
  -    <==>
  -      let x: T1 = %E1
  -      (%B1) x x
  -  @>
  -
  -let letCommutingConversion_exp = 
  -  <@
  -    (
  -      let x: T1 = 
  -        let y: T2 = %E1
  -        (%B1) y
  -      ((%B2) x): T3
  -    )
  -    <==>
  -      let y: T2 = %E1
  -      let x: T1 = (%B1) y
  -      (%B2) x
  -  @>
  -
  -let letReorder_exp = 
  -  <@
  -    (
  -      let x: T1 = %E1
  -      let y: T2 = %E2
  -      ((%B1) x y): T3
  -    )
  -    <==>
  -      let y: T2 = %E2
  -      let x: T1 = %E1
  -      ((%B1) x y): T3
     @>
   
   
  
positive.code:   @>
  
  // FIXME does not work
  let letFloatOutwards_exp = 
    <@
      (
        //((%B1) (let x: T1 = %E1 in x)): T2
        (%B1) (%E1: T1): T2
  
negative.code:     )
    @>
  
  
  
  let letVectorBuildLength: Rule = compilePatternWithNameToRule letVectorBuildLength_exp "letVectorBuildLength"
  
  