(****************************************************************************)
(*     Sail                                                                 *)
(*                                                                          *)
(*  Sail and the Sail architecture models here, comprising all files and    *)
(*  directories except the ASL-derived Sail code in the aarch64 directory,  *)
(*  are subject to the BSD two-clause licence below.                        *)
(*                                                                          *)
(*  The ASL derived parts of the ARMv8.3 specification in                   *)
(*  aarch64/no_vector and aarch64/full are copyright ARM Ltd.               *)
(*                                                                          *)
(*  Copyright (c) 2013-2021                                                 *)
(*    Kathyrn Gray                                                          *)
(*    Shaked Flur                                                           *)
(*    Stephen Kell                                                          *)
(*    Gabriel Kerneis                                                       *)
(*    Robert Norton-Wright                                                  *)
(*    Christopher Pulte                                                     *)
(*    Peter Sewell                                                          *)
(*    Alasdair Armstrong                                                    *)
(*    Brian Campbell                                                        *)
(*    Thomas Bauereiss                                                      *)
(*    Anthony Fox                                                           *)
(*    Jon French                                                            *)
(*    Dominic Mulligan                                                      *)
(*    Stephen Kell                                                          *)
(*    Mark Wassell                                                          *)
(*    Alastair Reid (Arm Ltd)                                               *)
(*                                                                          *)
(*  All rights reserved.                                                    *)
(*                                                                          *)
(*  This work was partially supported by EPSRC grant EP/K008528/1 <a        *)
(*  href="http://www.cl.cam.ac.uk/users/pes20/rems">REMS: Rigorous          *)
(*  Engineering for Mainstream Systems</a>, an ARM iCASE award, EPSRC IAA   *)
(*  KTF funding, and donations from Arm.  This project has received         *)
(*  funding from the European Research Council (ERC) under the European     *)
(*  Union’s Horizon 2020 research and innovation programme (grant           *)
(*  agreement No 789108, ELVER).                                            *)
(*                                                                          *)
(*  This software was developed by SRI International and the University of  *)
(*  Cambridge Computer Laboratory (Department of Computer Science and       *)
(*  Technology) under DARPA/AFRL contracts FA8650-18-C-7809 ("CIFV")        *)
(*  and FA8750-10-C-0237 ("CTSRD").                                         *)
(*                                                                          *)
(*  SPDX-License-Identifier: BSD-2-Clause                                   *)
(****************************************************************************)

open Ast
open Ast_defs
open Type_check

(* Monomorphisation options *)
val opt_mono_rewrites : bool ref
val opt_mono_complex_nexps : bool ref
val opt_mono_split : ((string * int) * string) list ref
val opt_dmono_analysis : int ref
val opt_auto_mono : bool ref
val opt_dall_split_errors : bool ref
val opt_dmono_continue : bool ref

(** Unroll loops with constant bounds if less than 'max_iter' iterations *)
val opt_unroll_loops : bool ref

val opt_unroll_loops_max_iter : int ref

(** Warn about matches where we add a default case for Coq because they're not exhaustive *)
val opt_coq_warn_nonexhaustive : bool ref

(** Output each rewrite step (as produced by the rewrite function) to a file for debugging *)
val opt_ddump_rewrite_ast : (string * int) option ref

(** Generate a fresh id with the given prefix *)
val fresh_id : string -> l -> id

(** Re-write undefined to functions created by -undefined_gen flag *)
val rewrite_undefined : bool -> Env.t -> typed_ast -> typed_ast

type rewriter =
  | Full_rewriter of
      (Initial_check.ctx ->
      Effects.side_effect_info ->
      Env.t ->
      typed_ast ->
      Initial_check.ctx * typed_ast * Effects.side_effect_info * Env.t
      )
  | Bool_rewriter of (bool -> rewriter)
  | String_rewriter of (string -> rewriter)
  | Literal_rewriter of ((lit -> bool) -> rewriter)

val describe_rewriter : rewriter -> string list

val all_rewriters : (string * rewriter) list

type rewrite_sequence =
  ( string
  * (Initial_check.ctx ->
    Effects.side_effect_info ->
    Env.t ->
    typed_ast ->
    Initial_check.ctx * typed_ast * Effects.side_effect_info * Env.t
    )
  )
  list

val rewrite_lit_ocaml : lit -> bool
val rewrite_lit_lem : lit -> bool

type rewriter_arg =
  | If_mono_arg
  | If_mwords_arg
  | If_flag of bool ref
  | Bool_arg of bool
  | Flag_arg of bool ref
  | String_arg of string
  | Literal_arg of string

(** Get the list of instantiated rewrites for a list of rewrites *)
val instantiate_rewrites : (string * rewriter_arg list) list -> rewrite_sequence

(** Apply a sequence of rewrites to an AST *)
val rewrite :
  Initial_check.ctx ->
  Effects.side_effect_info ->
  Env.t ->
  rewrite_sequence ->
  typed_ast ->
  Initial_check.ctx * typed_ast * Effects.side_effect_info * Env.t

val rewrites_interpreter : (string * rewriter_arg list) list

val simple_typ : typ -> typ
