let isCrossableAtInit tr func =
  let rec isCross = function
    | POr  (c1, c2) ->
        (isCross c1) || (isCross c2)
    | PAnd (c1, c2) ->
        (isCross c1) && (isCross c2)
    | PNot (c1) ->
        not (isCross c1)

    | PCall (s) ->
        (func=s)
    | PReturn (_) ->
        false
    | PCallOrReturn (s) ->
        func=s

    | PTrue ->
        true
    | PFalse ->
        false
(*      | PGt (_,_)
      | PGe (_,_)
      | PLt (_,_)
      | PLe (_,_)
      | PEq (_,_)
      | PNeq (_,_)
      | PBoolVar (_)     -> Undefined*)


    | PIndexedExp e ->
        (evalExpAtInit (Data_for_ltl.get_exp_from_tmpident e))<>0



  and error_msg msg =
    Ltl_to_acsl_option.fatal "Ltl_to_acsl plugin internal error. Status : %s. \n" msg;

  and evalExpAtInit:Cil_types.exp -> int = fun e ->
    match e.enode with
    | Cil_types.Const (c) ->
        begin
          match c with
            | Cil_types.CInt64(int64,_,_) -> Int64.to_int int64
            | Cil_types.CStr (_)
            | Cil_types.CWStr(_) -> error_msg "String values not supported into LTL expressions"
            | Cil_types.CChr(c) -> Char.code c
            | Cil_types.CReal (_,_,_) -> error_msg "Real values not supported into LTL expressions"
            | Cil_types.CEnum {eival = exp} -> evalExpAtInit exp
        end


    | Cil_types.Lval (Cil_types.Var(vi),Cil_types.NoOffset-> get_val_from_vi vi
    | Cil_types.Lval (_) -> raise LazyInit
(*        error_msg "Only simple LVAL supported at this time into LTL expressions"*)

    | Cil_types.UnOp (unop,exp,typ) ->
        if not (Cil.isIntegralType typ) then
          error_msg "Such operator not yet supported in LTL expressions"
        else
          begin
            match unop with
              | Cil_types.Neg -> (-(evalExpAtInit exp))
              | Cil_types.BNot -> error_msg "Bitwise complement not supported in LTL expressions"
              | Cil_types.LNot -> if (evalExpAtInit exp)=0 then 1 else 0
          end

    | Cil_types.BinOp (binop,exp1,exp2,typ) ->
        if not (Cil.isIntegralType typ) then
          error_msg "Such operator not yet supported in LTL expressions"
        else
          begin
            match binop with
              | Cil_types.PlusA -> (evalExpAtInit exp1) + (evalExpAtInit exp2)
              | Cil_types.MinusA -> (evalExpAtInit exp1) - (evalExpAtInit exp2)
              | Cil_types.Mult -> (evalExpAtInit exp1) * (evalExpAtInit exp2)
              | Cil_types.Div  -> (evalExpAtInit exp1) / (evalExpAtInit exp2)
              | Cil_types.Mod -> error_msg "Modulo not yet supported in LTL expressions"
              | Cil_types.PlusPI
              | Cil_types.IndexPI
              | Cil_types.MinusPI
              | Cil_types.MinusPP -> error_msg "Pointer and array not yet supported in LTL expressions"
              | Cil_types.Shiftlt
              | Cil_types.Shiftrt -> error_msg "Shifts not yet supported in LTL expressions"
              | Cil_types.Lt -> ( try
                                                            if (evalExpAtInit exp1) <  (evalExpAtInit exp2) then 1 else 0
                                                                                                        with
                                                                                                                | LazyInit -> 1
                                                                                                                | _ as e -> raise e )
              | Cil_types.Gt ->try
                             if (evalExpAtInit exp1) >  (evalExpAtInit exp2) then 1 else 0
                         with
                           | LazyInit -> 1
                           | _ as e -> raise e)
              | Cil_types.Le ->(try
                             if (evalExpAtInit exp1) <= (evalExpAtInit exp2) then 1 else 0
                         with
                           | LazyInit -> 1
                           | _ as e -> raise e)
              | Cil_types.Ge ->(try
                             if (evalExpAtInit exp1) >= (evalExpAtInit exp2) then 1 else 0
                         with
                           | LazyInit -> 1
                           | _ as e -> raise e)
              | Cil_types.Eq ->(try
                             if (evalExpAtInit exp1) =  (evalExpAtInit exp2) then 1 else 0
                         with
                           | LazyInit -> 1
                           | _ as e -> raise e)
              | Cil_types.Ne ->(try
                             if (evalExpAtInit exp1) <> (evalExpAtInit exp2) then 1 else 0
                         with
                           | LazyInit -> 1
                           | _ as e -> raise e)
              | Cil_types.BAnd
              | Cil_types.BXor
              | Cil_types.BOr  -> error_msg "Bitwise operations not supported in LTL expressions"
              | Cil_types.LAnd ->(try
                                                             if (evalExpAtInit exp1)<>0 && (evalExpAtInit exp2)<>0 then 1 else 0
                           with
                             | LazyInit -> 1
                             | _ as e -> raise e )
              | Cil_types.LOr  ->(try
                                                             if (evalExpAtInit exp1)<>0 or (evalExpAtInit exp2)<>0 then 1 else 0
                           with
                             | LazyInit -> 1
                             | _ as e -> raise e )
          end



    | Cil_types.Info (exp,_) ->
        evalExpAtInit exp

    | Cil_types.CastE (_,exp) ->
        Ltl_to_acsl_option.warning "Warning (Ltl_to_acsl plugin) CastE is not yet fully supported as a valid LTL expression. " ;
        evalExpAtInit exp



    | Cil_types.SizeOf (_)
    | Cil_types.SizeOfE (_)
    | Cil_types.SizeOfStr (_) ->
        error_msg "Sizeof is not supported as a valid LTL expression"

    | Cil_types.AlignOf (_)
    | Cil_types.AlignOfE (_) ->
        error_msg "AlignOf is not supported as a valid LTL expression"

    | Cil_types.AddrOf (_) ->
        error_msg "AddrOf is not yet supported as a valid LTL expression"
    | Cil_types.StartOf(_) ->
        error_msg "StartOf is not yet supported as a valid LTL expression"


  and  get_val_from_vi vi =
    try
      let ini=Globals.Vars.find vi in
      match ini.Cil_types.init with
        | None ->  error_msg ("'"^(vi.Cil_types.vname)^"'Seems to not be initialized" )
        | Some (Cil_types.SingleInit(exp)) -> evalExpAtInit exp
        | Some (Cil_types.CompoundInit(_,_)) -> error_msg "Compound values not yet supported into LTL expressions"
    with
      | _ ->
          error_msg ("initialisation of '"^(vi.Cil_types.vname)^"' not found")



  in
    isCross tr.cross