let cached_substitute call_site_froms extra_loc subst =
    let f k intervs =
      match k with
      | Base.Var((*{vtype = typ} as*) vi,_)
      | Base.Initialized_Var ((*{ vtype = typ } as*) vi,_)->
          ( try
              ( match VarinfoHashtbl.find subst vi
                with
                  Froms f -> f
                | Lvalue offs ->
                    (Lmap_bitwise.From_Model.LOffset.find_intervs
                       (Zone.default k)
                       intervs
                       offs))
            with
              Not_found ->
                Lmap_bitwise.From_Model.find call_site_froms (Zone.inject k intervs) )
      | Base.Null | Base.String _ | Base.Cell_class _ ->
          Zone.inject k intervs


    in
    let joiner = Zone.join in
    let projection base =
      match Base.validity base with
      | Base.Known (min_valid,max_valid) | Base.Unknown (min_valid,max_valid)->
          Int_Intervals.inject_bounds min_valid max_valid
      | Base.All -> assert false(*TODO*)
    in
    let zone_substitution =
        Zone.cached_fold ~cache:("from substitution", 331)
          ~f ~joiner ~empty:Zone.bottom ~projection
    in
    let zone_substitution x =
      try
        zone_substitution x
      with Zone.Error_Top -> Zone.top
    in
    fun z -> Zone.join extra_loc (zone_substitution z)