[sledge] Export Term.map_rec_pre and add Term.fold_map_rec_pre

Summary:
These are map and folding map that perform a cycle-preserving
pre-order transformation.

Reviewed By: jvillard

Differential Revision: D20877974

fbshipit-source-id: 251288228
master
Josh Berdine 5 years ago committed by Facebook GitHub Bot
parent 548928a839
commit 2fc8bc1f84

@ -77,6 +77,15 @@ module Array = struct
include Core.Array
let pp sep pp_elt fs a = List.pp sep pp_elt fs (to_list a)
let fold_map_inplace a ~init ~f =
let s = ref init in
let f x =
let s', x' = f !s x in
s := s' ;
x'
in
map_inplace a ~f ; !s
end
module IArray = IArray

@ -76,6 +76,9 @@ module Array : sig
include module type of Array
val pp : (unit, unit) fmt -> 'a pp -> 'a array pp
val fold_map_inplace :
'a array -> init:'s -> f:('s -> 'a -> 's * 'a) -> 's
end
module IArray = IArray

@ -1132,13 +1132,7 @@ let fold_map e ~init ~f =
let e' = map e ~f in
(!s, e')
(** Pre-order transformation that preserves cycles. Each subterm [x] from
root to leaves is presented to [f]. If [f x = Some x'] then the subterms
of [x] are not traversed and [x] is transformed to [x']. Otherwise
traversal proceeds to the subterms of [x], followed by rebuilding the
term structure on the transformed subterms. Cycles (through terms
involving [RecN]) are preserved. *)
let map_rec_pre ~f e =
let map_rec_pre e ~f =
let rec map_rec_pre_f memo e =
match f e with
| Some e' -> e'
@ -1161,6 +1155,31 @@ let map_rec_pre ~f e =
in
map_rec_pre_f [] e
let fold_map_rec_pre e ~init ~f =
let rec fold_map_rec_pre_f memo s e =
match f s e with
| Some (s, e') -> (s, e')
| None -> (
match e with
| RecN (op, xs) -> (
match List.Assoc.find ~equal:( == ) memo e with
| None ->
let xs' = IArray.to_array xs in
let e' = RecN (op, IArray.of_array xs') in
let memo = List.Assoc.add ~equal:( == ) memo e e' in
let changed = ref false in
let s =
Array.fold_map_inplace ~init:s xs' ~f:(fun s x ->
let s, x' = fold_map_rec_pre_f memo s x in
if x' != x then changed := true ;
(s, x') )
in
if !changed then (s, e') else (s, e)
| Some e' -> (s, e') )
| _ -> fold_map ~f:(fold_map_rec_pre_f memo) ~init:s e )
in
fold_map_rec_pre_f [] init e
let rename sub e =
map_rec_pre e ~f:(function
| Var _ as v -> Some (Var.Subst.apply sub v)

@ -235,7 +235,20 @@ val size_of : Typ.t -> t
(** Transform *)
val map : t -> f:(t -> t) -> t
val map_rec_pre : t -> f:(t -> t option) -> t
(** Pre-order transformation that preserves cycles. Each subterm [x] from
root to leaves is presented to [f]. If [f x = Some x'] then the subterms
of [x] are not traversed and [x] is transformed to [x']. Otherwise
traversal proceeds to the subterms of [x], followed by rebuilding the
term structure on the transformed subterms. Cycles (through terms
involving [RecN]) are preserved. *)
val fold_map : t -> init:'a -> f:('a -> t -> 'a * t) -> 'a * t
val fold_map_rec_pre :
t -> init:'a -> f:('a -> t -> ('a * t) option) -> 'a * t
val rename : Var.Subst.t -> t -> t
(** Traverse *)

Loading…
Cancel
Save