liquid-fixpoint-0.1.0.0: external/fixpoint/fixConfig.ml
(*
* Copyright © 2009 The Regents of the University of California. All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
* FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION
* TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*)
module Sy = Ast.Symbol
module SM = Sy.SMap
module Q = Qualifier
module C = FixConstraint
module So = Ast.Sort
module Co = Constants
module Misc = FixMisc open Misc.Ops
exception UnmappedKvar of Ast.Symbol.t
let mydebug = false
type qbind = Q.t list
type solbind = Ast.Symbol.t * ((Ast.Symbol.t * (Ast.expr list)) list)
type deft = Srt of Ast.Sort.t
| Axm of Ast.pred
| Cst of FixConstraint.t
| Wfc of FixConstraint.wf
| Con of Ast.Symbol.t * Ast.Sort.t
| Sol of solbind
(* | Sol of Ast.Symbol.t * (Ast.pred * (Ast.Symbol.t * Ast.Subst.t)) list *)
| Qul of Q.t
| Dep of FixConstraint.dep
| Kut of Ast.Symbol.t
| IBind of int * Ast.Symbol.t * FixConstraint.reft
type 'bind cfg = {
a : int (* Tag arity *)
; ts : Ast.Sort.t list (* New sorts, now = [] *)
; ps : Ast.pred list (* New axioms, now = [] *)
; cs : FixConstraint.t list (* Implication Constraints *)
; ws : FixConstraint.wf list (* Well-formedness Constraints *)
; ds : FixConstraint.dep list (* Constraint Dependencies *)
; qs : Q.t list (* Qualifiers *)
; kuts : Ast.Symbol.t list (* "Cut"-Kvars, which break cycles *)
; bm : 'bind SM.t (* Initial Sol Bindings *)
; uops : Ast.Sort.t Ast.Symbol.SMap.t (* Globals: measures + distinct consts) *)
; cons : Ast.Symbol.t list (* Distinct Constants, defined in uops *)
; assm : FixConstraint.soln (* Seed Solution -- must be a fixpoint over constraints *)
}
let get_arity = function
| [] -> Constants.bprintflush mydebug "WARNING: NO CONSTRAINTS!"; 0
| c::_ -> c |> FixConstraint.tag_of_t |> fst |> List.length
let sift_quals qs =
qs >> (fun _ -> Co.bprintflush mydebug "BEGIN: Q.normalize\n")
|> Q.normalize
(* >> (Format.printf "Normalized Quals: \n%a" (Misc.pprint_many true "\n" Q.print)) *)
>> (fun _ -> Co.bprintflush mydebug "DONE: Q.normalize\n")
|> Misc.map (Misc.pad_fst Q.name_of_t)
|> SM.of_list
let extend f cfg = function
| Srt t -> {cfg with ts = t :: cfg.ts }
| Axm p -> {cfg with ps = p :: cfg.ps }
| Cst c -> {cfg with cs = c :: cfg.cs }
| Wfc w -> {cfg with ws = w :: cfg.ws }
| Dep d -> {cfg with ds = d :: cfg.ds }
| Kut k -> {cfg with kuts = k :: cfg.kuts }
| Qul q -> {cfg with qs = q :: cfg.qs }
| Sol (k, fess) -> {cfg with bm = SM.add k (List.map f fess) cfg.bm }
| Con (s,t) -> {cfg with cons = if So.is_func t then cfg.cons else s :: cfg.cons
; uops = SM.add s t cfg.uops}
| IBind _ -> cfg
let empty =
{ a = 0
; ts = []
; ps = []
; cs = []
; ws = []
; ds = []
; qs = []
; kuts = []
; bm = SM.empty
; cons = []
; uops = SM.empty
; assm = FixConstraint.empty_solution
}
let fes2q qm (f, es) =
let q = SM.safeFind f qm "name2qual" in
q |> Q.all_params_of_t
|> List.map fst
|> Misc.flip (Misc.combine "FixConfig.fes2q") es
|> Q.inst q
let normalize_defts ds =
let qs, ds' = Misc.either_partition begin function
| Qul q -> Left q
| d -> Right d
end ds in
let qm = sift_quals qs in
let ds'' = qm |> SM.range
|>: (fun q -> Qul q)
|> (++) ds' in
(qm, ds'')
(* API *)
let create ds =
let qm, ds' = normalize_defts ds in
ds' |> List.fold_left (extend (fes2q qm)) empty
|> (fun cfg -> {cfg with a = get_arity cfg.cs})
|> (fun cfg -> {cfg with ws = C.add_wf_ids cfg.ws})
(* API *)
let create_raw ts env ps a ds cs ws qs kuts assm =
{ empty with
a = a
; ts = ts
; uops = env
; ps = ps
; ds = ds
; cs = cs
; ws = C.add_wf_ids ws
; kuts = kuts
; qs = Q.normalize qs
; assm = assm
}
module type SIMPLIFIER = sig
val simplify_ts: FixConstraint.t list -> FixConstraint.t list
end
(* type t = Ast.Qualifier.def list list cfg *)
let print ppf me =
(* Print cs *)
Format.fprintf ppf "@[%a@] \n" (Misc.pprint_many true "\n" (C.print_t None)) me.cs;
(* Print ws *)
Format.fprintf ppf "@[%a@] \n" (Misc.pprint_many true "\n" (C.print_wf None)) me.ws;
(* Print qs *)
Format.fprintf ppf "@[%a@] \n" (Misc.pprint_many true "\n" Q.print) (Q.normalize me.qs)