packages feed

liquid-fixpoint (empty) → 0.1.0.0

raw patch · 170 files changed

+51601/−0 lines, 170 filesdep +ansi-terminaldep +arraydep +basebuild-type:Customsetup-changed

Dependencies added: ansi-terminal, array, base, bifunctors, bytestring, cmdargs, containers, deepseq, directory, filemanip, filepath, ghc, ghc-prim, hashable, liquid-fixpoint, mtl, parsec, pretty, process, syb, text, unordered-containers

Files

+ Fixpoint.hs view
@@ -0,0 +1,37 @@++import Language.Fixpoint.Interface     (solveFile)+import System.Environment              (getArgs)+-- import System.Console.GetOpt+import Language.Fixpoint.Config hiding (config)+import Data.Maybe                      (fromMaybe, listToMaybe)+import System.Console.CmdArgs                  +import System.Console.CmdArgs.Verbosity (whenLoud)++++main = do cfg <- getOpts +          whenLoud $ putStrLn $ "Options: " ++ show cfg+          solveFile cfg++config = Config { +    inFile   = def   &= typ "TARGET"       &= args    &= typFile +  , outFile  = "out" &= help "Output file"  +  , solver   = def   &= help "Name of SMT Solver" +  , genSorts = def   &= help "Generalize qualifier sorts"+}  &= verbosity+   &= program "fixpoint" +   &= help    "Predicate Abstraction Based Horn-Clause Solver" +   &= summary "fixpoint © Copyright 2009-13 Regents of the University of California." +   &= details [ "Predicate Abstraction Based Horn-Clause Solver"+              , ""+              , "To check a file foo.fq type:"+              , "  fixpoint foo.fq"+              ]++getOpts :: IO Config +getOpts = do md <- cmdArgs config +             putStrLn $ banner md+             return md++banner args =  "Liquid-Fixpoint © Copyright 2009-13 Regents of the University of California.\n" +            ++ "All Rights Reserved.\n"
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Ranjit Jhala++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Ranjit Jhala nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,34 @@+import Control.Monad+import Data.Maybe+import Distribution.PackageDescription+import Distribution.Simple+import Distribution.Simple.LocalBuildInfo+import Distribution.Simple.Setup+import System.Posix.Env+import System.Process+import System.Exit++main         = defaultMainWithHooks fixHooks +  where +    fixHooks = simpleUserHooks { postInst = buildAndCopyFixpoint } +   +buildAndCopyFixpoint _ _ pkg lbi +  = do putStrLn $ "Post Install: " ++ show binDir+       setEnv "Z3MEM" (show z3mem) True+       executeShellCommand "./configure"+       executeShellCommand "./build.sh"+       executeShellCommand "chmod a+x external/fixpoint/fixpoint.native "+       executeShellCommand $ "cp external/fixpoint/fixpoint.native " ++ binDir+       when z3mem $+         executeShellCommand $ "cp external/z3/lib/libz3.* "         ++ binDir+  where +    allDirs     = absoluteInstallDirs pkg lbi NoCopyDest+    binDir      = bindir allDirs ++ "/"+    flags       = configConfigurationsFlags $ configFlags lbi+    z3mem       = fromJust $ lookup (FlagName "z3mem") flags++executeShellCommand cmd   = putStrLn ("EXEC: " ++ cmd) >> system cmd >>= check+  where +    check (ExitSuccess)   = return ()+    check (ExitFailure n) = error $ "cmd: " ++ cmd ++ " failure code " ++ show n +
+ configure view
@@ -0,0 +1,45 @@+#!/bin/bash++ROOTHOME=`pwd`+GHCBIN=`which ghc`+GHCHOME=`dirname $GHCBIN`+OCAMLLIB=`ocamlc -v | tail -1 | cut -d : -f 2 | tr -d " "`++if [[ $Z3MEM = 'True' ]]+then+  Z3HOME=$ROOTHOME/external/z3+else+  Z3HOME=+fi++cat - > external/fixpoint/config.make <<EOF+OCAMLGRAPHHOME=$ROOTHOME/external/ocamlgraph+OCAMLLIB=$OCAMLLIB+Z3HOME=$Z3HOME+EOF++cat - > build.sh <<EOF+#!`which bash`++set -e++if [[ '$Z3MEM' = 'True' ]]+then+  if [[ \`uname -m\` = 'x86_64' ]]+  then+    echo Found 64-bit kernel. Moving z3 into place.+    cp external/z3/lib/libz3-so-64b external/z3/lib/libz3.so+    cp external/z3/lib/libz3-a-64b external/z3/lib/libz3.a+  else+    echo Assuming 32-bit kernel. Moving z3 into place.+    cp external/z3/lib/libz3-so-32b external/z3/lib/libz3.so+    cp external/z3/lib/libz3-a-32b external/z3/lib/libz3.a+  fi+  cd external/z3/ocaml; ./build-lib.sh; cd ../../../+fi++cd external/ocamlgraph/; ./configure; make; cd ../../+cd external/fixpoint; make; cd ../../+EOF++chmod a+x build.sh
+ external/fixpoint/Makefile view
@@ -0,0 +1,64 @@+include config.make++DIRS=-I misc+OFLAGS=$(DIRS) $(IFLAGS) $(LFLAGS) $(CFLAGS)++LIBS_=-libs unix,str,graph+IFLAGS_=-lflags -I,$(OCAMLGRAPHHOME)+LFLAGS_=-lflags -cclib,-L$(OCAMLLIB) \++CFLAGS_=-cflags -dtypes,-annot \+		-cflags -I,$(OCAMLGRAPHHOME) \+		-cflags -thread++SMTZ3=smtZ3.ml++ifdef Z3HOME+  LIBS=$(LIBS_),z3+  IFLAGS=$(IFLAGS_) \+		 -lflags -I,$(Z3HOME)/lib \+		 -lflags -I,$(Z3HOME)/ocaml+  LFLAGS=$(LFLAGS_) \+		 -lflags -cc,g++ \+		 -lflags -cclib,-lstdc++ \+		 -lflags -cclib,-lcamlidl \+		 -lflags -cclib,-L$(Z3HOME)/lib \+		 -lflags -cclib,-lz3 \+		 -lflags -cclib,-lz3stubs \+		 -lflags -cclib,-fopenmp\+		 -lflags -cclib,-lrt+  CFLAGS=$(CFLAGS_) \+		 -cflags -I,$(Z3HOME)/ocaml+  SMTZ3SRC=smtZ3.mem.ml+else+  LIBS=$(LIBS_)+  IFLAGS=$(IFLAGS_)+  LFLAGS=$(LFLAGS_)+  CFLAGS=$(CFLAGS_)+  SMTZ3SRC=smtZ3.nomem.ml+endif++all: smtz3+	ln -sf ../misc+	ocamlbuild -r $(LIBS) $(OFLAGS) -tags thread fixpoint.native+	ocamlbuild -r $(OFLAGS) fix.cmxa+	rm -f fixpoint.native+	cp _build/fixpoint.native .++smtz3: $(SMTZ3SRC)+	cp $(SMTZ3SRC) $(SMTZ3)++clean:+	rm -rf *.byte *.native _build _log++fixtop:+	ocamlbuild -r $(LIBS) $(OFLAGS) fixtop.native++horn:+	ocamlbuild -r $(LIBS) $(OFLAGS) hornToInterproc.native++MLITARGET=toSmtLib.ml+mli:+	ocamlc -I _build/ -I _build/misc/ -I $(Z3HOME)/lib -I $(Z3HOME)/ocaml -i $(MLITARGET)++
+ external/fixpoint/Simplification.ml view
@@ -0,0 +1,197 @@+module C = FixConstraint+module P = Ast.Predicate+module E = Ast.Expression+module Sy = Ast.Symbol+module Su = Ast.Subst++module Misc = FixMisc open Misc.Ops++let rec defs_of_pred (edefs, pdefs) ((p, _) as pred) = +  match p with+    | Ast.Atom ((Ast.Var v, _), Ast.Eq, e) when not(P.is_tauto pred) -> Sy.SMap.add v e edefs, pdefs+    | Ast.And [Ast.Imp ((Ast.Bexp (Ast.Var v1, _), _), p1), _; +	       Ast.Imp (p2, (Ast.Bexp (Ast.Var v2, _), _)), _] when v1 = v2 && p1 = p2 && not(P.is_tauto pred) -> +	edefs, Sy.SMap.add v1 p1 pdefs+    | Ast.And preds -> List.fold_left defs_of_pred (edefs, pdefs) preds+    | _ -> edefs, pdefs++let some_def_applied = ref false+let rec expr_apply_defs edefs pdefs ((e, _) as expr) = +  let current_some_def_applied = !some_def_applied in+    some_def_applied := false;+    let expr'' =+      match e with+	| Ast.Con _ -> expr+	| Ast.Var v -> +	    begin+	      try+		let expr' = Sy.SMap.find v edefs in+		  some_def_applied := true;+		  expr'+	      with Not_found -> expr+	    end+	| Ast.App (v, es) -> +	    let edefs' = Sy.SMap.remove v edefs in+	      Ast.eApp (v, List.map (expr_apply_defs edefs' pdefs) es)+	| Ast.Bin (e1, op, e2) -> +	    Ast.eBin (expr_apply_defs edefs pdefs e1, op, expr_apply_defs edefs pdefs e2)+	| Ast.Ite (p, e1, e2) -> +	    Ast.eIte (pred_apply_defs edefs pdefs p, +		      expr_apply_defs edefs pdefs e1,+		      expr_apply_defs edefs pdefs e2)+	| Ast.Fld (v, e) -> +	    let v' = +	      try+		match Sy.SMap.find v edefs with+		  | (Ast.Var v'', _) -> +		      some_def_applied := true;+		      v''+		  | _ -> v+	      with Not_found -> v+	    in+	      Ast.eFld (v', expr_apply_defs edefs pdefs e)+        | _ -> assertf "Simplification.expr_apply_defs TODO" +    in+      if !some_def_applied then+	let expr''' = expr_apply_defs edefs pdefs expr'' in+	  some_def_applied := current_some_def_applied;+	  expr'''+      else+	begin+	  some_def_applied := current_some_def_applied;+	  expr''+	end++and pred_apply_defs edefs pdefs ((p, _) as pred) =+  let current_some_def_applied = !some_def_applied in+    some_def_applied := false;+    let pred'' =+      match p with+	| Ast.And ps -> List.map (pred_apply_defs edefs pdefs) ps |> Ast.pAnd+	| Ast.Or ps -> List.map (pred_apply_defs edefs pdefs) ps |> Ast.pOr+	| Ast.Not p -> pred_apply_defs edefs pdefs p |> Ast.pNot+	| Ast.Imp (p, q) -> Ast.pImp (pred_apply_defs edefs pdefs p, pred_apply_defs edefs pdefs q)+	| Ast.Bexp (Ast.Var v, _) ->+	    begin+	      try+		let expr' = Sy.SMap.find v edefs in+		  some_def_applied := true;+		  Ast.pBexp expr'+	      with Not_found ->+		try+		  let pred' = Sy.SMap.find v pdefs in+		    some_def_applied := true;+		    pred'+		with Not_found ->+		  pred+	    end+	| Ast.Atom (e1, brel, e2) ->+	    Ast.pAtom (expr_apply_defs edefs pdefs e1, brel, expr_apply_defs edefs pdefs e2)+	| Ast.Forall (qs, p) ->+	    let vs = List.map fst qs in+	    let edefs' = List.fold_left (fun defs v -> Sy.SMap.remove v defs) edefs vs in+	    let pdefs' = List.fold_left (fun defs v -> Sy.SMap.remove v defs) pdefs vs in+	      Ast.pForall (qs, pred_apply_defs edefs' pdefs' p)+	| _ -> pred+    in+      if !some_def_applied then+	let pred''' = pred_apply_defs edefs pdefs pred'' in+	  some_def_applied := current_some_def_applied;+	  pred'''+      else +	begin+	  some_def_applied := current_some_def_applied;+	  pred''+	end++let subs_apply_defs edefs pdefs subs =+  List.map (fun (s, e) -> s, expr_apply_defs edefs pdefs e) subs++let kvar_apply_defs edefs pdefs (subs, sym) = +  subs_apply_defs edefs pdefs subs, sym++let simplify_subs subs =+  List.filter (fun (s, e) -> not(P.is_tauto (Ast.pAtom (Ast.eVar s, Ast.Eq, e)))) subs++let simplify_kvar (subs, sym) =+  simplify_subs subs, sym++let simplify_t t = +  let env_ps, pfree_env = (* separate concrete predicates from refinement templates *)+    Sy.SMap.fold +      (fun bv reft (ps, env) -> +	 let vv = C.vv_of_reft reft in+	 let bv_expr = Ast.eVar bv in+	 let sort = C.sort_of_reft reft in+	 let reft_ps, reft_ks = C.preds_kvars_of_reft reft in+	   (List.rev_append (List.map (fun p -> P.subst p vv bv_expr) reft_ps) ps,+	    if reft_ks = [] then env else Sy.SMap.add bv (vv, sort, reft_ks) env)+      ) (C.env_of_t t) ([], Sy.SMap.empty) in+  let lhs = C.lhs_of_t t in+  let lhs_vv = C.vv_of_reft lhs in+  let lhs_ps, lhs_ks = C.preds_kvars_of_reft lhs in+  let body_pred = Ast.pAnd (C.grd_of_t t :: List.rev_append lhs_ps env_ps) in+  let edefs, pdefs = defs_of_pred (Sy.SMap.empty, Sy.SMap.empty) body_pred in+    (*+    Printf.printf "\nbody_pred edefs map for %d\n" (C.id_of_t t);+    Sy.SMap.iter (fun v exp ->+		    Printf.printf "%s -> %s\n" (Sy.to_string v) (E.to_string exp)+		 ) edefs;+    Printf.printf "edef for lhs_vv %s = %s (simplified %s)\n" (Sy.to_string lhs_vv) +      (try Sy.SMap.find lhs_vv edefs |> E.to_string with Not_found -> "none")+      (try +	 Sy.SMap.find lhs_vv edefs +         |> expr_apply_defs edefs pdefs +	 |> E.to_string with Not_found -> "none");+    *)+  let kvar_to_simple_Kvar (subs, sym) = C.Kvar (subs |> Su.to_list |> subs_apply_defs edefs pdefs |> simplify_subs |> Su.of_list, sym) in+  let senv = +    Sy.SMap.mapi (fun bv (vv, sort, ks) -> +		    List.map kvar_to_simple_Kvar ks |>	C.make_reft vv sort) pfree_env in+(*     Printf.printf "body_pred: %s\n" (P.to_string body_pred); *)+  let sgrd' = pred_apply_defs edefs pdefs body_pred |> Ast.simplify_pred in+  let sgrd = +    try+      Ast.pAnd [sgrd'; Ast.pAtom (Ast.eVar lhs_vv, Ast.Eq, Sy.SMap.find lhs_vv edefs |> expr_apply_defs edefs pdefs)]+    with Not_found -> sgrd' in+(*    Printf.printf "simplified body_pred: %s\n" (P.to_string sgrd); *)+  let slhs = List.map kvar_to_simple_Kvar lhs_ks |> C.make_reft (C.vv_of_reft lhs) (C.sort_of_reft lhs) in+  let rhs = C.rhs_of_t t in+  let rhs_ps, rhs_ks = C.preds_kvars_of_reft rhs in+  let srhs_pred = pred_apply_defs edefs pdefs (Ast.pAnd rhs_ps) |> Ast.simplify_pred in+  let srhs_ks = List.map kvar_to_simple_Kvar rhs_ks in+  let srhs =  (if P.is_tauto srhs_pred then srhs_ks else (C.Conc srhs_pred) :: srhs_ks) |> +      C.make_reft (C.vv_of_reft rhs) (C.sort_of_reft rhs) in+    C.make_t senv sgrd slhs srhs (Some (C.id_of_t t)) (C.tag_of_t t)++let simplify_ts ts =+  (* drop t if its rhs is a k variable that is not read *)+  let ts_sofar = ref ts in+  let pruned = ref true in+    while !pruned && !ts_sofar <> [] do+      let pruned_ts, rest_ts = +	List.partition+	  (fun t ->+	     match C.rhs_of_t t |> C.preds_kvars_of_reft with+	       | [], [(_, sy)] ->+		   List.for_all +		     (fun t' -> +			List.for_all (fun (_, sy') -> sy <> sy') +			  (Sy.SMap.fold +			     (fun _ reft sofar -> List.rev_append (C.kvars_of_reft reft) sofar) +			     (C.env_of_t t') (C.lhs_of_t t' |> C.kvars_of_reft))+		     ) !ts_sofar+	       | _ -> false+	  ) !ts_sofar in+	ts_sofar := rest_ts;+	pruned := pruned_ts <> []+    done;+    !ts_sofar++let is_tauto_t t =+  match C.rhs_of_t t |> C.ras_of_reft with+    | [] -> true+    | [C.Conc p] -> P.is_tauto p +    | _ -> false++  
+ external/fixpoint/Simplification.mli view
@@ -0,0 +1,5 @@++val simplify_t  : FixConstraint.t -> FixConstraint.t+val simplify_ts : FixConstraint.t list -> FixConstraint.t list+val is_tauto_t  : FixConstraint.t -> bool+
+ external/fixpoint/ast.ml view
@@ -0,0 +1,1652 @@+(*+ * 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.+ *+ *)++(**+ * This module implements a DAG representation for expressions and + * predicates: each sub-predicate or sub-expression is paired with+ * a unique int ID, which enables constant time hashing. + * However, one must take care when using DAGS:+ * (1) they can only be constructed using the appropriate functions+ * (2) when destructed via pattern-matching, one must discard the ID+ *)++(* random touch *)++module F  = Format+module Misc = FixMisc+open Misc.Ops+module SM = Misc.StringMap++let mydebug = false++module Cone = struct+  type 'a t = Empty | Cone of ('a * 'a t) list++  let rec map f = function +    | Empty    -> Empty+    | Cone xcs -> Cone (List.map (f <**> map f) xcs)+end ++module Sort =+  struct+    type loc = +      | Loc  of string +      | Lvar of int+      | LFun ++    type tycon = string++    type t =+      | Int+      | Bool+      | Obj+      | Var of int              (* type-var *)+      | Ptr of loc              (* c-pointer *)+      | Func of int * t list    (* type-var-arity, in-types @ [out-type]      *)+      | Num                     (* kind, for numeric tyvars -- ptr(loc(s)) -- *)+      | App of tycon * t list   (* type constructors *)++    type sub = { locs: (int * string) list; +                 vars: (int * t) list; }++   +    let tycon_string x = x+    (*+    let is_loc_string s = +      let re = Str.regexp "[a-zA-Z]+[0-9]+" in +      Str.string_match re s 0+    +    let loc_of_string = fun s -> let _ = asserts (is_loc_string s) in Loc s+    let loc_of_index  = fun i -> Lvar i+    *)++    let t_num       = Num +    let t_obj       = Obj+    let t_bool      = Bool+    let t_int       = Int+    let t_generic   = fun i -> let _ = asserts (0 <= i) "t_generic: %d" i in Var i+    let t_ptr       = fun l -> Ptr l+    let t_func      = fun i ts -> Func (i, ts)+    let tycon s     = s +    +    (* let tycon_re    = Str.regexp "[A-Z][0-9 a-z A-Z '.']"+     * function | s when Str.string_match tycon_re s 0 -> s  +                | s -> assertf "Error: Invalid tycon: %s" s +     *)++    let t_app c ts  = App (c, ts)++    let loc_to_string = function+      | Loc s  -> s+      | Lvar i -> string_of_int i+      | LFun   -> "<fun>"++    let rec to_string = function+      | Var i        -> Printf.sprintf "@(%d)" i+      | Int          -> "int"+      | Bool         -> "bool"+      | Obj          -> "obj"+      | Num          -> "num"+      | Ptr l        -> loc_to_string l +                        (* Printf.sprintf "ptr(%s)" (loc_to_string l) *)+      | Func (n, ts) -> ts |> List.map to_string +                           |> String.concat " ; " +                           |> Printf.sprintf "func(%d, [%s])" n +      | App (c, ts)  -> ts |> List.map to_string_arg +                           |> String.concat " " +                           |> Printf.sprintf "%s %s" c +    +    and to_string_arg t = match t with +      | App (_, _) -> Printf.sprintf "(%s)" (to_string t)+      | _          -> to_string t++    let to_string_short = function+      | Func _ -> "func"+   (* | Ptr _  -> "ptr" *)+      | t      -> to_string t      ++    let print fmt t = +      t |> to_string +        |> Format.fprintf fmt "%s"++    let sub_to_string {locs = ls; vars = vs} =+      let lts = fun (i, s) -> Printf.sprintf "(%d := %s)" i s in+      let vts = fun (i, t) -> Printf.sprintf "(%d := %s)" i (to_string t) in+      Printf.sprintf "locs := %s, vars := %s \n" +        (String.concat "" (List.map lts ls)) +        (String.concat "" (List.map vts vs)) ++    let rec map f = function +      | Func (n, ts) -> Func (n, List.map (map f) ts)+      | App  (c, ts) -> App  (c, List.map (map f) ts)+      | t            -> f t++    let rec fold f b = function+      | Func (n, ts) as t -> List.fold_left (fold f) (f b t) ts+      | t                 -> f b t++    let subs_tvar ts = +      map begin function +          | Var i -> Misc.do_catchf "ERROR: subs_tvar" (List.nth ts) i+          | t     -> t+      end++    let is_bool = function+      | Bool -> true+      | _    -> false++    let is_int = function+      | Int -> true+      | _   -> false++    let is_func = function+      | Func _ -> true+      | _   -> false++    let app_of_t = function+      | App (c, ts) -> Some (c, ts) +      | _           -> None+++    let func_of_t = function+      | Func (i, ts) -> let (xts, t) = ts |> Misc.list_snoc |> Misc.swap in +                        Some (i, xts, t)+      | _            -> None++    let ptr_of_t = function+      | Ptr l -> Some l+      | _     -> None++    (* Sleazy Hack for C pointers. Make this go away... *)++    let compat t1 t2 = match t1, t2 with+      | Int, (Ptr _) -> true+      | (Ptr _), Int -> true+      | _            -> t1 = t2++    (* {{{ +    let concretize ts = function +      | Func (n, ats) when n = List.length ts -> +          Func (n, List.map (subs_tvar ts) ats)+      | _ -> +          assertf "ERROR: bad application" ++    let is_monotype t = +      fold (fun b t -> b && (match t with Var _ -> false | _ -> true)) true t+    }}} *)+++    let lookup_var = fun s i -> try Some (List.assoc i s.vars) with Not_found -> None+    let lookup_loc = fun s j -> try Some (List.assoc j s.locs) with Not_found -> None+    +    let rec unifyt s = function +      | Num,_ | _, Num -> None+      | ct, (Var i) +      | (Var i), ct +        (* when ct != Bool *) -> +          begin match lookup_var s i with +          | Some ct' when ct = ct' -> Some s+          | Some _                 -> None+          | None                   -> Some {s with vars = (i,ct) :: s.vars}+          end++      | Ptr LFun, Ptr _ +      | Ptr _, Ptr LFun -> Some s+      | Ptr (Loc cl), Ptr (Lvar j)+      | Ptr (Lvar j), Ptr (Loc cl) ->+          begin match lookup_loc s j with +          | Some cl' when cl' = cl -> Some s+          | Some _                 -> None+          | None                   -> Some {s with locs = (j,cl) :: s.locs}+          end+      +      | App (c1, t1s), App (c2, t2s) +        when c1 = c2 && List.length t1s = List.length t2s ->+          Misc.maybe_fold unifyt s (List.combine t1s t2s)+      +      | (t1, t2) when t1 = t2 -> +          Some s+      | _        -> None+   +    let empty_sub = {vars = []; locs = []}+   +    let unifyWith s ats cts =+      let _ = asserts (List.length ats = List.length cts) "ERROR: unify sorts" in+      List.combine ats cts +      |> Misc.maybe_fold unifyt s +      (* >> (fun so -> Printf.printf "unify: [%s] ~ [%s] = %s \n" +                      (String.concat "; " (List.map to_string ats))+                      (String.concat "; " (List.map to_string cts))+                      (match so with None -> "NONE" | Some s -> sub_to_string s))+       *)++    let unify = unifyWith empty_sub++    let apply s = +      map begin fun t -> match t with+          | Var i        -> (match lookup_var s i with Some t' -> t' | _ -> t)+          | Ptr (Lvar j) -> (match lookup_loc s j with Some l -> Ptr (Loc l) | _ -> t)+          | _            -> t+      end++    let rec fold f acc t = match t with+      | Var _ | Int  | Bool | Obj | Num | Ptr _ +        -> f acc t +      | Func (_, ts) | App (_, ts) +        -> List.fold_left (fold f) (f acc t) ts +      +    let vars_of_t = fold begin fun acc -> function +      | Var i -> i :: acc +      | _     -> acc+    end []+    +    let locs_of_t = fold begin fun acc -> function +      | Ptr (Loc l) -> l :: acc +      | _           -> acc+    end []+    +    let subst_locs_vars lim = map begin function+      | Ptr (Loc l) when SM.mem l lim -> Var (SM.find l lim)+      | t                             -> t+    end++    (* API *)+    let generalize ts = +      let locs = ts |> Misc.flap locs_of_t |> Misc.sort_and_compact       in+      let idx  = ts |> Misc.flap vars_of_t |> Misc.list_max (-1) |> (+) 1 in +      let lim  = Misc.index_from idx locs |>: Misc.swap |> SM.of_list     in+      List.map (subst_locs_vars lim) ts++    (* API *)+    let sub_args s = List.sort compare s.vars++    (* API *)+    let check_arity n s = s.vars |>: fst |> Misc.sort_and_compact |> List.length |> (=) n+      (* if ... then s else assertf "Type Inst. With Wrong Arity!" *)++  end++module Symbol = +  struct +    type t = string+    +    let mk_wild =+      let t,_ = Misc.mk_int_factory () in+      t <+> string_of_int <+> (^) "~A"+    +    let is_wild_fresh s = s = "_"+    let is_wild_any   s = s.[0] = '~'+    let is_wild_pre   s = s.[0] = '@'+    let is_wild s       = is_wild_fresh s || is_wild_any s || is_wild_pre s++    let is_safe s = +      let re = Str.regexp "[A-Za-z '~' '_' '\'' '@' ][0-9 a-z A-Z '_' '@' '\'' '.' '#']*$" in+      Str.string_match re s 0+    +    let of_string, to_string = +      let of_t = Hashtbl.create 117 in+      let to_t = Hashtbl.create 117 in+      let bind = fun s sy -> Hashtbl.replace of_t s sy; Hashtbl.replace to_t sy s in+      let f,_  = Misc.mk_string_factory "FIXPOINTSYMBOL_" in+      ((fun s -> +        if is_wild_fresh s then mk_wild () else+        if is_safe s then s else+           try Hashtbl.find of_t s with Not_found ->+             let sy = f () in+             let _  = bind s sy in sy),+       (fun sy -> try Hashtbl.find to_t sy with Not_found -> sy))+                   +    let to_string = fun s -> s (* if is_safe s then s else "'" ^ s ^ "'" *)++    let suffix = fun s suff -> of_string ((to_string s) ^ suff)++    let print fmt s =+      to_string s |> Format.fprintf fmt "%s" ++    let vvprefix = "VV_"+    let vvsuffix = function+      | Sort.Ptr l -> Sort.loc_to_string l+      | t          -> Sort.to_string_short t++++    let is_value_variable = Misc.is_prefix vvprefix+    let value_variable t = vvprefix ^ (vvsuffix t)++    (* DEBUG *)+    let vvprefix = "VV"+    let is_value_variable = (=) vvprefix+    let value_variable _  = vvprefix++    module SMap = Misc.EMap (struct type t = string +                                    let compare i1 i2 = compare i1 i2 +                                    let print         = print         end)++    module SSet = Misc.ESet (struct type t = string+                                    let compare i1 i2 = compare i1 i2 end)++   (* let sm_length m = +      SMap.fold (fun _ _ i -> i+1) m 0++    let sm_filter f sm = +      SMap.fold begin fun x y sm -> +        if f x y then SMap.add x y sm else sm +    end sm SMap.empty ++    let sm_to_list sm =+      SMap.fold (fun x y acc -> (x,y)::acc) sm []+    +    let sm_of_list xs = +      List.fold_left (fun sm (k,v) -> SMap.add k v sm) SMap.empty xs +   *)++  end++module Constant =+  struct+    type t = Int of int++    let to_string = function+      | Int i -> string_of_int i++    let print fmt s =+      to_string s |> Format.fprintf fmt "%s"+  end+ ++type tag = int++type brel = Eq | Ne | Gt | Ge | Lt | Le ++type bop  = Plus | Minus | Times | Div | Mod  (* NOTE: For "Mod" 2nd expr should be a constant or a var *)++type expr = expr_int * tag +    +and expr_int =+  | Con  of Constant.t+  | Var  of Symbol.t+  | App  of Symbol.t * expr list+  | Bin  of expr * bop * expr  +  | Ite  of pred * expr * expr+  | Fld  of Symbol.t * expr             (* NOTE: Fld (s, e) == App ("field"^s,[e]) *) +  | Cst  of expr * Sort.t +  | Bot+  | MExp of expr list+  | MBin of expr * bop list * expr ++and pred = pred_int * tag++and pred_int =+  | True+  | False+  | And   of pred list+  | Or    of pred list+  | Not   of pred+  | Imp   of pred * pred+  | Iff   of pred * pred+  | Bexp  of expr+  | Atom  of expr * brel * expr +  | MAtom of expr * brel list * expr+  | Forall of ((Symbol.t * Sort.t) list) * pred++let list_hash b xs = +  List.fold_left (fun v (_,id) -> 2*v + id) b xs++module Hashcons (X : sig type t +                         val sub_equal : t -> t -> bool +                         val hash : t -> int end) = struct++  module HashStruct = struct+    type t = X.t * int+    let equal (x,_) (y,_) = X.sub_equal x y+    let hash (x,_) = X.hash x+  end++  module Hash = Weak.Make(HashStruct)+  +  let wrap = +    let tab = Hash.create 251 in+    let ctr = ref 0 in+    fun e -> +      let res = Hash.merge tab (e, !ctr) in+      let _   = if snd res = !ctr then incr ctr in+      res++  let unwrap (e,_) = e++end++module ExprHashconsStruct = struct+  type t = expr_int+  let sub_equal e1 e2 =+    match e1, e2 with+      | Con c1, Con c2 -> +          c1 = c2+      | MExp es1, MExp es2 -> +          es1 = es2+      | Var x1, Var x2 -> +          x1 = x2+      | App (s1, e1s), App (s2, e2s) ->+	  (s1 = s2) && +          (try List.for_all2 (==) e1s e2s with _ -> false)+      | Bin (e1, op1, e1'), Bin (e2, op2, e2') ->+          op1 = op2 && e1 == e2 && e1' == e2'+      | MBin (e1, ops1, e1'), MBin (e2, ops2, e2') ->+          ops1 = ops2 && e1 == e2 && e1' == e2'+      | Ite (ip1,te1,ee1), Ite (ip2,te2,ee2) ->+	      ip1 == ip2 && te1 == te2 && ee1 == ee2+      | Fld (s1, e1), Fld (s2, e2) ->+          s1 = s2 && e1 == e2+      | Cst (e1, s1), Cst (e2, s2) ->+          s1 = s2 && e1 == e2+      | _ -> +          false+  +  let hash = function+    | Con (Constant.Int x) -> +        x+    | MExp es ->+        list_hash 6 es +    | Var x -> +        Hashtbl.hash x+    | App (s, es) -> +        list_hash ((Hashtbl.hash s) + 1) es +    | Bin ((_,id1), op, (_,id2)) -> +        (Hashtbl.hash op) + 1 + (2 * id1) + id2 +    | MBin ((_,id1), op::_ , (_,id2)) -> +        (Hashtbl.hash op) + 1 + (2 * id1) + id2 +    | Ite ((_,id1), (_,id2), (_,id3)) -> +        32 + (4 * id1) + (2 * id2) + id3+    | Fld (s, (_,id)) ->+        (Hashtbl.hash s) + 12 + id+    | Cst ((_, id), t) ->+        id + Hashtbl.hash (Sort.to_string t)+    | Bot ->+        0+    | _ -> assertf "pattern error in A.pred hash"++end+  +module ExprHashcons = Hashcons(ExprHashconsStruct)++module PredHashconsStruct = struct+  +  type t = pred_int+  +  let sub_equal p1 p2 =+    match p1, p2 with+      | True, True | False, False -> +          true+      | And p1s, And p2s  | Or  p1s, Or p2s -> +          (try List.for_all2 (==) p1s p2s with _ -> false)+      | Not p1, Not p2 -> +          p1 == p2+      | Imp (p1, p1'), Imp (p2, p2') -> +          p1 == p2 && p1' == p2'+      | Iff (p1,p1'), Iff (p2,p2') ->+          p1 == p2 && p1' == p2'+      | Bexp e1, Bexp e2 -> +          e1 == e2+      | Atom (e1, r1, e1'), Atom (e2, r2, e2') ->+          r1 = r2 && e1 == e2 && e1' == e2'+      | MAtom (e1, r1, e1'), MAtom (e2, r2, e2') ->+          r1 = r2 && e1 == e2 && e1' == e2'+      | Forall(q1s,p1), Forall(q2s,p2) -> +          q1s = q2s && p1 == p2+      | _ -> +          false+ + let hash = function+   | True -> +       0+   | False -> +       1+   | And ps -> +       list_hash 2 ps+   | Or ps -> +       list_hash 3 ps+   | Not (_,id) -> +       8 + id +   | Imp ((_,id1), (_,id2)) ->+       20 + (2 * id1) + id2+   | Iff ((_,id1), (_,id2)) ->+       28 + (2 * id1) + id2+   | Bexp (_, id) ->+       32 + id+   | Atom ((_,id1), r, (_,id2)) ->+       36 + (Hashtbl.hash r) + (2 * id1) + id2+   | MAtom ((_,id1), r, (_,id2)) ->+       42 + (Hashtbl.hash r) + (2 * id1) + id2+   | Forall(qs,(_,id)) -> +       50 + (2 * (Hashtbl.hash qs)) + id+end+  +module PredHashcons = Hashcons(PredHashconsStruct)++let ewr = ExprHashcons.wrap+let euw = ExprHashcons.unwrap+let pwr = PredHashcons.wrap +let puw = PredHashcons.unwrap++(* Constructors: Expressions *)+let eCon  = fun c  -> ewr  (Con c)+let eMExp = fun es -> ewr  (MExp es)+let eInt  = fun i  -> eCon (Constant.Int i)+let zero  = eInt 0+let one   = eInt 1+let bot  = ewr Bot+let eMod = fun (e, m) -> ewr (Bin (e, Mod, eInt m))+let eModExp = fun (e, m) -> ewr (Bin (e, Mod, m))+let eVar = fun s -> ewr (Var s)+let eApp = fun (s, es) -> ewr (App (s, es))+let eBin = fun (e1, op, e2) -> ewr (Bin (e1, op, e2)) ++let eMBin = fun (e1, ops, e2) -> ewr (MBin (e1, ops, e2)) +let eIte = fun (ip,te,ee) -> ewr (Ite(ip,te,ee))+let eFld = fun (s,e) -> ewr (Fld (s,e))+let eCst = fun (e,t) -> ewr (Cst (e, t))++let eTim = function +  | (Con (Constant.Int n1), _), (Con (Constant.Int n2), _) -> +      ewr (Con (Constant.Int (n1 * n2)))+  | (Con (Constant.Int 1), _), e2 -> +      e2 +  | (Con (Constant.Int (-1)), _), e2 -> +      eBin (zero, Minus, e2) +  | (e1, e2) -> eBin (e1, Times, e2)+++let rec conjuncts = function+  | And ps, _ -> Misc.flap conjuncts ps+  | True, _   -> []+  | p         -> [p]+++(* Constructors: Predicates *)+let pTrue  = pwr True+let pFalse = pwr False+let pAtom  = fun (e1, r, e2) -> pwr (Atom (e1, r, e2))+let pMAtom = fun (e1, r, e2) -> pwr (MAtom (e1, r, e2))+let pOr    = fun ps -> pwr (Or ps)+let pNot   = fun p  -> pwr (Not p)+let pBexp  = fun e  -> pwr (Bexp e)+let pImp   = fun (p1,p2) -> pwr (Imp (p1,p2))+let pIff   = fun (p1,p2) -> pwr (Iff (p1,p2))+let pForall= fun (qs, p) -> pwr (Forall (qs, p))+let pEqual = fun (e1,e2) -> pAtom (e1, Eq, e2)+++let pAnd   = fun ps -> match Misc.flap conjuncts ps with +                       | []  -> pTrue +                       | [p] -> p+                       | ps  -> pwr (And (Misc.flap conjuncts ps))++++module ExprHash = Hashtbl.Make(struct+  type t = expr+  let equal (_,x) (_,y) = (x = y)+  let hash (_,x) = x+end)++module PredHash = Hashtbl.Make(struct+  type t = pred+  let equal (_,x) (_,y) = (x = y)+  let hash (_,x) = x+end)++let bop_to_string = function +  | Plus  -> "+"+  | Minus -> "-"+  | Times -> "*"+  | Div   -> "/"+  | Mod   -> "mod" ++let brel_to_string = function +  | Eq -> "="+  | Ne -> "!="+  | Gt -> ">"+  | Ge -> ">="+  | Lt -> "<"+  | Le -> "<="++let print_brel ppf r = +  F.fprintf ppf "%s" (brel_to_string r)++let print_binding ppf (s,t) = +  F.fprintf ppf "%a:%a" Symbol.print s Sort.print t++let bind_to_string  (s,t) = +  Printf.sprintf "%s:%s" (Symbol.to_string s) (Sort.to_string t)++let rec print_expr ppf e = match euw e with+  | Con c -> +      F.fprintf ppf "%a" Constant.print c +  | MExp es -> +      F.fprintf ppf "[%a]" (Misc.pprint_many false " ; " print_expr) es+  | Var s -> +      F.fprintf ppf "%a" Symbol.print s+  | App (s, es) -> +      F.fprintf ppf "%a([%a])" +        Symbol.print s+        (Misc.pprint_many false "; " print_expr) es+  | Bin (e1, op, e2) ->+      F.fprintf ppf "(%a %s %a)" +        print_expr e1 +        (bop_to_string op) +        print_expr e2+  | MBin (e1, ops, e2) ->+      F.fprintf ppf "(%a [%s] %a)" +        print_expr e1 +        (ops |>: bop_to_string |> String.concat " ; ")+        print_expr e2+ +  | Ite(ip,te,ee) -> +      F.fprintf ppf "(%a ? %a : %a)" +        print_pred ip +        print_expr te+        print_expr ee+  | Fld(s, e) -> +      F.fprintf ppf "%a.%s" print_expr e s +  | Cst(e,t) ->+      F.fprintf ppf "(%a : %a)" +        print_expr e +        Sort.print t+  | Bot ->+      F.fprintf ppf "_|_" ++and print_pred ppf p = match puw p with+  | True -> +      F.fprintf ppf "true"+  | False -> +      F.fprintf ppf "false"+  | Bexp (App (s, es), _) ->+      F.fprintf ppf "%a(%a)" Symbol.print s (Misc.pprint_many false ", " print_expr) es+  | Bexp e ->+      F.fprintf ppf "(Bexp %a)" print_expr e+  | Not p -> +      F.fprintf ppf "(~ (%a))" print_pred p+  | Imp (p1, p2) -> +      F.fprintf ppf "(%a => %a)" print_pred p1 print_pred p2 +  | Iff (p1, p2) ->+      F.fprintf ppf "(%a <=> %a)" print_pred p1 print_pred p2 +  | And ps -> begin match ps with [] -> F.fprintf ppf "true" | _ ->+      F.fprintf ppf "&& %a" (Misc.pprint_many_brackets true print_pred) ps+    end+  | Or ps -> begin match ps with [] -> F.fprintf ppf "false" | _ -> +      F.fprintf ppf "|| %a" (Misc.pprint_many_brackets true print_pred) ps+    end++  | Atom (e1, r, e2) ->+      (* F.fprintf ppf "@[(%a %s %a)@]" *)+      F.fprintf ppf "(%a %s %a)"+        print_expr e1 +        (brel_to_string r) +        print_expr e2+  | MAtom (e1, rs, e2) ->+      F.fprintf ppf "(%a [%a] %a)" +      (* F.fprintf ppf "@[(%a [%a] %a)@]"  *)+        print_expr e1 +        (Misc.pprint_many false " ; " print_brel) rs+        print_expr e2+  | Forall (qs, p) -> +      F.fprintf ppf "forall [%a] . %a" +        (Misc.pprint_many false "; " print_binding) qs+        print_pred p+  +let rec expr_to_string e = +  match euw e with+  | Con c -> +      Constant.to_string c+  | MExp es -> +      Printf.sprintf "[%s]" (es |>: expr_to_string |> String.concat " ; ")+  | Var s -> +      Symbol.to_string s+  | App (s, es) ->+      Printf.sprintf "%s([%s])" +        (Symbol.to_string s)+        (es |> List.map expr_to_string |> String.concat "; ")+  | Bin (e1, op, e2) ->+      Printf.sprintf "(%s %s %s)" +        (expr_to_string e1) (bop_to_string op) (expr_to_string e2)+  | MBin (e1, ops, e2) ->+      Printf.sprintf "(%s [%s] %s)" +        (expr_to_string e1) +        (ops |> List.map bop_to_string |> String.concat "; ")+        (expr_to_string e2)+  | Ite(ip,te,ee) -> +      Printf.sprintf "(%s ? %s : %s)" +        (pred_to_string ip) (expr_to_string te) (expr_to_string ee)+  | Fld(s,e) -> +      Printf.sprintf "%s.%s" (expr_to_string e) s +  | Cst(e,t) ->+      Printf.sprintf "(%s : %s)" (expr_to_string e) (Sort.to_string t)+  | Bot ->+      Printf.sprintf "_|_" +++and pred_to_string p = +  match puw p with+    | True -> +        "true"+    | False -> +        "false"+    | Bexp e ->+        Printf.sprintf "(Bexp %s)" (expr_to_string e)+    | Not p -> +        Printf.sprintf "(~ (%s))" (pred_to_string p) +    | Imp (p1, p2) -> +        Printf.sprintf "(%s => %s)" (pred_to_string p1) (pred_to_string p2)+    | Iff (p1, p2) ->+        Printf.sprintf "(%s <=> %s)" (pred_to_string p1) (pred_to_string p2)+    | And ps -> +        Printf.sprintf "&& [%s]" (List.map pred_to_string ps |> String.concat " ; ")+    | Or ps -> +        Printf.sprintf "|| [%s]" (List.map pred_to_string ps |> String.concat ";")+    | Atom (e1, r, e2) ->+        Printf.sprintf "(%s %s %s)" +        (expr_to_string e1) (brel_to_string r) (expr_to_string e2)+    | MAtom (e1, rs, e2) ->+        Printf.sprintf "(%s [%s] %s)" +        (expr_to_string e1)+        (List.map brel_to_string rs |> String.concat " ; ") +        (expr_to_string e2)+    | Forall (qs,p) -> +        Printf.sprintf "forall [%s] . %s" +        (List.map bind_to_string qs |> String.concat "; ") (pred_to_string p)++let rec pred_map hp he fp fe p =+  let rec pm p =+    try PredHash.find hp p with Not_found -> begin+      let p' = +        match puw p with+        | True | False as p1 -> +            p1+        | And ps -> +            And (List.map pm ps)  +        | Or ps -> +            Or (List.map pm ps)  +        | Not p -> +            Not (pm p) +        | Imp (p1, p2) -> +            Imp (pm p1, pm p2)+        | Iff (p1, p2) ->+            Iff (pm p1, pm p2)+        | Bexp e ->+            Bexp (expr_map hp he fp fe e) +        | Atom (e1, r, e2) ->+            Atom (expr_map hp he fp fe e1, r, expr_map hp he fp fe e2)+        | MAtom (e1, rs, e2) ->+            MAtom (expr_map hp he fp fe e1, rs, expr_map hp he fp fe e2)+        | Forall (qs, p) ->+            Forall (qs, pm p) in+      let rv = fp (pwr p') in+      let _  = PredHash.add hp p rv in +      rv+    end in pm p ++and expr_map hp he fp fe e =+  let rec em e =+    try ExprHash.find he e with Not_found -> begin+      let e' = +        match euw e with+        | Con _ | Var _ | Bot as e1 -> +            e1+        | MExp es ->+            MExp (List.map em es) +        | App (f, es) ->+            App (f, List.map em es)+        | Bin (e1, op, e2) ->+            Bin (em e1, op, em e2)+        | MBin (e1, ops, e2) ->+            MBin (em e1, ops, em e2)+        | Ite (ip, te, ee) ->+            Ite (pred_map hp he fp fe ip, em te, em ee) +        | Fld (s, e1) -> +            Fld (s, em e1) +        | Cst (e1, t) -> +            Cst (em e1, t) +      in+      let rv = fe (ewr e') in+      let _  = ExprHash.add he e rv in+      rv+    end in em e++let rec pred_iter fp fe pw =+  begin match puw pw with+    | True | False -> ()+    | Bexp e -> expr_iter fp fe e+    | Not p -> pred_iter fp fe p+    | Imp (p1, p2) -> pred_iter fp fe p1; pred_iter fp fe p2+    | Iff (p1, p2) -> pred_iter fp fe p1; pred_iter fp fe p2+    | And ps | Or ps -> List.iter (pred_iter fp fe) ps+    | Atom (e1, _, e2) -> expr_iter fp fe e1; expr_iter fp fe e2+    | MAtom (e1, _, e2) -> expr_iter fp fe e1; expr_iter fp fe e2+    | Forall (_, p) -> pred_iter fp fe p (* pmr: looks wrong, but so does pred_map *)+  end;+  fp pw++and expr_iter fp fe ew =+  begin match puw ew with+    | Con _ | Var _ | Bot -> +        ()+    | MExp es ->+        List.iter (expr_iter fp fe) es+    | App (_, es)  -> +        List.iter (expr_iter fp fe) es+    | Bin (e1, _, e2)  -> +        expr_iter fp fe e1; expr_iter fp fe e2+    | MBin (e1, _, e2)  -> +        expr_iter fp fe e1; expr_iter fp fe e2+    | Ite (ip, te, ee) -> +        pred_iter fp fe ip; expr_iter fp fe te; expr_iter fp fe ee+    | Fld (_, e1) | Cst (e1, _) -> +        expr_iter fp fe e1+  end;+  fe ew++let esub x e = function+  | (Var y), _ when x = y -> e+  | _ as e1 -> e1 ++let expr_subst hp he e x e' =+  expr_map hp he id (esub x e') e ++let pred_subst hp he p x e' =+  pred_map hp he id (esub x e') p ++module Expression = +  struct+      +    module Hash   = ExprHash +      +    let to_string = expr_to_string++    (* let print     = fun fmt e -> Format.pp_print_string fmt (to_string e)+     *)+    let print = print_expr+    +    let show      = print Format.std_formatter++    let map fp fe e =+      let hp = PredHash.create 251 in+      let he = ExprHash.create 251 in +      expr_map hp he fp fe e ++    let iter fp fe e =+      expr_iter fp fe e++    let subst e x e' =+      map id (esub x e') e++    let substs e xes =+      map id (fun e -> List.fold_left (esub |> Misc.uncurry |> Misc.flip) e xes) e++    let support e =+      let xs = ref Symbol.SSet.empty in+      iter un begin function +        | (Var x), _ +        | (App (x,_)),_ -> xs := Symbol.SSet.add x !xs+        | _               -> ()+      end e;+      Symbol.SSet.elements !xs |> List.sort compare++    let unwrap = euw++    let has_bot p =+      let r = ref false in+      iter un begin function +        | Bot, _ -> r := true+        | _      -> ()+      end p; +      !r++  end+    +module Predicate = struct+  module Hash = PredHash +	+  let to_string = pred_to_string+  let print     = print_pred+  let show      = print Format.std_formatter+			+  let map fp fe p =+	let hp = PredHash.create 251 in+	let he = ExprHash.create 251 in +    pred_map hp he fp fe p+	+  let iter fp fe p =+    pred_iter fp fe p++  let subst p x e' =+    map id (esub x e') p++  let substs p xes =+    map id (fun e -> List.fold_left (esub |> Misc.uncurry |> Misc.flip) e xes) p++  let support p =+    let xs = ref Symbol.SSet.empty in+    iter un begin function +      | (Var x), _ +      | (App (x,_)),_ -> xs := Symbol.SSet.add x !xs;+      | _               -> ()+    end p; +    Symbol.SSet.elements !xs |> List.sort compare++  (*+  let size p =+	let c = ref 0           in+    let f = fun _ -> incr c in+    let _ = iter f f p      in +    !c++  let size p =+	let c = ref 0                    in+    let _ = iter (fun _ -> incr c) p in +    !c+  *)+  +  let unwrap = puw++  let is_contra = +    let t = PredHash.create 17 in+    let _ = [pFalse; pNot pTrue; pAtom (zero, Eq, one); pAtom (one, Eq, zero)]+            |> List.iter (fun p-> PredHash.replace t p ()) in +    fun p -> PredHash.mem t p +   ++  let rec is_tauto  = function+    | Atom(e1, Eq, e2), _ -> snd e1 == snd e2+    | Imp (p1, p2), _     -> snd p1 == snd p2+    | And ps, _           -> List.for_all is_tauto ps+    | Or  ps, _           -> List.exists is_tauto ps+    | True, _             -> true+    | _                   -> false++  let has_bot p =+    let r = ref false in+    iter un begin function +      | Bot, _ -> r := true+      | _      -> ()+    end p; +    !r++  end++let print_stats _ = +  Printf.printf "Ast Stats. [none] \n"+++(********************************************************************************)+(************************** Rationalizing Division ******************************)+(********************************************************************************)++let expr_isdiv = function+  | Bin (_, Div, _), _ -> true+  | _                  -> false++let pull_divisor = function +  | Bin (_, Div, (Con (Constant.Int i),_)), _ -> i +  | _ -> 1++let calc_cm e1 e2 =+    pull_divisor e1 * pull_divisor e2 ++let rec apply_mult m = function +  | Bin (e, Div,  (Con (Constant.Int d),_)), _ ->+      let _   = assert ((m/d) * d = m) in+      eTim ((eCon (Constant.Int (m/d))), e)  +  | Bin (e1, op, e2), _ ->+      eBin (apply_mult m e1, op, apply_mult m e2)+  | Con (Constant.Int i), _ -> +      eCon (Constant.Int (i*m))+  | e -> +      eTim (eCon (Constant.Int m), e)++let rec pred_isdiv = function +  | True,_ | False,_ -> +      false+  | And ps,_ | Or ps,_ -> +      List.exists pred_isdiv ps+  | Not p, _ | Forall (_, p), _ -> +      pred_isdiv p+  | Imp (p1, p2), _ ->+      pred_isdiv p1 || pred_isdiv p2+  | Iff (p1, p2), _ ->+      pred_isdiv p1 || pred_isdiv p2+  | Bexp e, _ ->+      expr_isdiv e+  | Atom (e1, _, e2), _ -> +      expr_isdiv e1 || expr_isdiv e2+  | _ -> failwith "Unexpected: pred_isdiv"++let bound m e e1 e2 =+  pAnd [pAtom (apply_mult m e, Gt, apply_mult m e2);+        pAtom(apply_mult m e, Le, apply_mult m e1)] ++let rec fixdiv = function+  | p when not (pred_isdiv p) -> +      p+  | Atom ((Var _,_) as e, Eq, e1), _ | Atom ((Con _, _) as e, Eq, e1), _ ->+      bound (calc_cm e e1) e e1 (eBin (e1, Minus, one))+  | And ps, _ ->+      pAnd (List.map fixdiv ps) +  | Or ps, _ ->+      pOr (List.map fixdiv ps)+  | Imp (p1, p2), _ ->+      pImp (fixdiv p1, fixdiv p2)+  | Iff (p1, p2), _ ->+      pIff (fixdiv p1, fixdiv p2)+  | Not p, _ -> +      pNot (fixdiv p) +  | p -> p++(***************************************************************************)+(************* Type Checking Expressions and Predicates ********************)+(***************************************************************************)++let sortcheck_sym f s = f s+  (* try Some (f s)  with _ -> None *)++let sortcheck_loc f = function+  | Sort.Loc s  -> sortcheck_sym f (Symbol.of_string s)+  | Sort.Lvar _ -> None+  | Sort.LFun   -> None++let rec sortcheck_expr g f e = +  match euw e with+  | Bot   -> +      None+  | Con _ -> +      Some Sort.Int +  | Var s ->+      sortcheck_sym f s+  | Bin (e1, op, e2) -> +      sortcheck_op g f (e1, op, e2)+  | Ite (p, e1, e2) -> +      if sortcheck_pred g f p then +        match Misc.map_pair (sortcheck_expr g f) (e1, e2) with+        | (Some t1, Some t2) when t1 = t2 -> Some t1 +        | _ -> None+      else None+  +  | Cst (e1, t) ->+      begin match euw e1 with+        | App (uf, es) -> sortcheck_app g f (Some t) uf es+        | _            ->+            match sortcheck_expr g f e1 with+              | Some t1 when Sort.compat t t1 -> Some t+              | _                             -> None +      end++  | App (uf, es) ->+      sortcheck_app g f None uf es+    +  | _ -> assertf "Ast.sortcheck_expr: unhandled expr = %s" (Expression.to_string e)++(* TODO: OMG! 5 levels of matching!!!!! *)+and sortcheck_app_sub g f so_expected uf es =+  let yikes uf = F.printf "sortcheck_app_sub: unknown sym = %s \n" (Symbol.to_string uf) in+  sortcheck_sym f uf+  |> function None -> (yikes uf; None) | Some t -> +       Sort.func_of_t t +       |> function None -> None | Some (tyArity, i_ts, o_t) -> +              let _  = asserts (List.length es = List.length i_ts) +                         "ERROR: uf arg-arity error: uf=%s" uf in+              let e_ts = es |> List.map (sortcheck_expr g f) |> Misc.map_partial id in+                if List.length e_ts <> List.length i_ts then +                  None +                else+                  match Sort.unify e_ts i_ts with+                    | None   -> None+                    | Some s ->+                        let t = Sort.apply s o_t in+                          match so_expected with+                            | None    -> Some (s, t)+                            | Some t' ->+                                match Sort.unifyWith s [t] [t'] with+                                  | None    -> None+                                  | Some s' -> Some (s', Sort.apply s' t)++and sortcheck_app g f so_expected uf es = +  sortcheck_app_sub g f so_expected uf es +  |> Misc.maybe_map snd +  (* >> begin function +       | Some t -> Format.printf "sortcheck_app: e = %s , t = %s \n"+                     (expr_to_string (eApp (uf, es))) (Sort.to_string t)+       | None   -> Format.printf "sortcheck_app: e = %s FAILS\n"+                     (expr_to_string (eApp (uf, es)))+     end+  *)++++and sortcheck_op g f (e1, op, e2) = +  match Misc.map_pair (sortcheck_expr g f) (e1, e2) with+  | (Some Sort.Int, Some Sort.Int) +  -> Some Sort.Int+  +  (* only allow when language is Haskell *)+  | (Some (Sort.Ptr l), Some (Sort.Ptr l')) +  when (l = l' && sortcheck_loc f l = Some Sort.Num)+ -> Some (Sort.Ptr l)+ +  (* only allow when language is C *)+  | (Some (Sort.Ptr s), Some Sort.Int) +  | (Some Sort.Int, Some (Sort.Ptr s)) +  -> Some (Sort.Ptr s)++  (* only allow when language is C *)+  | (Some (Sort.Ptr s), Some (Sort.Ptr s')) +  when op = Minus && s = s'+  -> Some Sort.Int++  | _ -> None+++and sortcheck_rel g f (e1, r, e2) =+  let t1o, t2o = (e1,e2) |> Misc.map_pair (sortcheck_expr g f) in+  match r, t1o, t2o with+  | _, Some (Sort.Ptr _) , Some (Sort.Ptr Sort.LFun)+  | _, Some (Sort.Ptr Sort.LFun), Some (Sort.Ptr _)+    -> true+  | _ , Some Sort.Int,     Some (Sort.Ptr l)+  | _ , Some (Sort.Ptr l), Some Sort.Int+    -> (sortcheck_loc f l = Some Sort.Num)+  | _ , Some (Sort.Ptr l1), Some (Sort.Ptr l2) when (sortcheck_loc f l1 = Some Sort.Num) && (sortcheck_loc f l2 = Some Sort.Num)+    -> true+  | Eq, Some t1, Some t2+  | Ne, Some t1, Some t2+    -> t1 = t2+  | _ , Some (Sort.App (tc,_)), _+    when (g tc) (* tc is an interpreted tycon *)+    -> false+  | _ , Some t1, Some t2+    -> t1 = t2 && t1 != Sort.Bool+  | _ -> false++and sortcheck_pred g f p =+  match puw p with+    | True  +    | False -> +        true +    | Bexp e ->+        sortcheck_expr g f e = Some Sort.Bool +    | Not p -> +        sortcheck_pred g f p+    | Imp (p1, p2) | Iff (p1, p2) -> +        List.for_all (sortcheck_pred g f) [p1; p2]+    | And ps  +    | Or ps ->+        List.for_all (sortcheck_pred g f) ps+    +    | Atom ((Con (Constant.Int(0)),_), _, e) +    | Atom (e, _, (Con (Constant.Int(0)),_)) +      when not (!Constants.strictsortcheck)+      -> not (None = sortcheck_expr g f e)+    +    | Atom ((Var x, _) , Eq, (App (uf, es), _))+    | Atom ((App (uf, es), _), Eq, (Var x, _))+      -> begin match sortcheck_sym f x with +         | None    -> false +         | Some tx -> not (None = sortcheck_app g f (Some tx) uf es)+         end++    | Atom (e1, r, e2) ->+        sortcheck_rel g f (e1, r, e2)+    | Forall (qs,p) ->+        (* let f' = fun x -> try List.assoc x qs with _ -> f x in *)+        let f' = fun x -> match Misc.list_assoc_maybe x qs with None -> f x | y -> y+        in sortcheck_pred g f' p+    | _ -> failwith "Unexpected: sortcheck_pred"++(* and sortcheck_pred f p =+  sortcheck_pred' f p+  >> (fun b -> if not b then F.eprintf "WARNING: Malformed Lhs Pred (%a)\n" Predicate.print p) + *)++let uf_arity f uf =  +  match sortcheck_sym f uf with None -> None | Some t -> +    match Sort.func_of_t t with None -> None | Some (i,_,_) -> +      Some i+ +(* API *)+let sortcheck_app g f t uf es = +  match uf_arity f uf, sortcheck_app_sub g f t uf es with +    | (Some n , Some (s, t)) -> +        if Sort.check_arity n s then Some (s, t) else+           assertf "Ast.sortcheck_app: type args not fully instantiated %s" +             (expr_to_string (eApp (uf, es)))+    | _ -> None++(*+let sortcheck_pred f p = +  sortcheck_pred f p+  >> (fun b -> ignore <| F.printf "sortcheck_pred: p = %a, res = %b\n"+  Predicate.print p b)+*)++(***************************************************************************)+(************* Simplifying Expressions and Predicates **********************)+(***************************************************************************)++let pred_of_bool = function true -> pTrue | false -> pFalse++let rec remove_bot pol ((p, _) as pred) =+  match p with+  | Not p  -> +      pNot (remove_bot (not pol) p)+  | Imp (p, q) ->+      pImp (remove_bot (not pol) p, remove_bot pol q)+  | Forall (qs, p) ->+      pForall (qs, remove_bot pol p)+  | And ps ->+      ps |> List.map (remove_bot pol) |> pAnd+  | Or ps -> +      ps |> List.map (remove_bot pol) |> pOr+  | Bexp e when Expression.has_bot e ->+      pred_of_bool pol+  | Atom (e1, _, e2) when Expression.has_bot e1 || Expression.has_bot e2 -> +      pred_of_bool pol+  | _ -> +      pred++let remove_bot p = +  if Predicate.has_bot p +  then remove_bot true p +  else p++let symm_brel = function+  | Eq -> Eq +  | Ne -> Ne +  | Gt -> Lt+  | Ge -> Le+  | Lt -> Gt+  | Le -> Ge+++let neg_brel = function +  | Eq -> Ne+  | Ne -> Eq+  | Gt -> Le+  | Ge -> Lt+  | Lt -> Ge+  | Le -> Gt++let rec push_neg ?(neg=false) ((p, _) as pred) =+  match p with+    | True   -> +        if neg then pFalse else pred+    | False  -> +        if neg then pTrue else pred+    | Bexp _ -> +        if neg then pNot pred else pred+    | Not p  -> +        push_neg ~neg:(not neg) p+    | Imp (p, q) -> +	if neg then pAnd [push_neg p; push_neg ~neg:true q]+	else pImp (push_neg p, push_neg q)+    | Iff (p, q) ->+        if neg then pIff (p, push_neg ~neg:true q)+        else pIff (push_neg p, push_neg q)+    | Forall (qs, p) -> +	let pred' = pForall (qs, push_neg ~neg:false p) in+	if neg then pNot pred' else pred'+    | And ps -> +        List.map (push_neg ~neg:neg) ps +        |> if neg then pOr else pAnd+    | Or ps -> +        List.map (push_neg ~neg:neg) ps +        |> if neg then pAnd else pOr+    | Atom (e1, brel, e2) -> +        if neg then pAtom (e1, neg_brel brel, e2) else pred+    | _ -> failwith "Unexpected: push_neg"++(* Andrey: TODO flatten nested conjunctions/disjunctions *)+let rec simplify_pred ((p, _) as pred) =+  match p with+    | Not p -> pNot (simplify_pred p)+    | Imp (p, q) -> pImp (simplify_pred p, simplify_pred q) +    | Forall (qs, p) -> pForall (qs, simplify_pred p)+    | And ps -> ps |> List.map simplify_pred +                   |> List.filter (not <.> Predicate.is_tauto) +                   |> (function | []  -> pTrue+                                | [p] -> p+                                | _ when List.exists Predicate.is_contra ps -> pFalse+                                | _   -> pAnd ps)+    | Or ps -> ps |> List.map simplify_pred +                  |> List.filter (not <.> Predicate.is_contra)+                  |> (function []  -> pFalse+                             | [p] -> p+                             | ps when List.exists Predicate.is_tauto ps -> pTrue+                             | ps  -> pOr ps)+    | _ -> pred++(**************************************************************************)+(*************************** Substitutions ********************************)+(**************************************************************************)++module Subst = struct++  type t = expr Symbol.SMap.t+ +  let valid xes = +    xes |> List.split +        |> Misc.app_snd (Misc.flap Expression.support)+        |> Misc.uncurry Misc.disjoint+            +    +  let extend s (x, e) =+    let s = Symbol.SMap.map (esub x e) s in+      if Symbol.SMap.mem x s then+        s+      else+        match e with+        | Var x', _ when x = x' -> s+        | _                     -> Symbol.SMap.add x e s++  let empty     = Symbol.SMap.empty+  let is_empty  = Symbol.SMap.is_empty+  let to_list   = Symbol.SMap.to_list   +  let apply     = Misc.flip Symbol.SMap.maybe_find+  let of_list   = fun xes -> List.fold_left extend empty xes+  let simultaneous_of_list = Symbol.SMap.of_list+  let compose s t = +    let s' = Symbol.SMap.fold (fun x e s -> Symbol.SMap.map (esub x e) s) t s+    in Symbol.SMap.fold (fun x e s -> if Symbol.SMap.mem x s+                                         then s else Symbol.SMap.add x e s)+                        t s'+  let print_sub = fun ppf (x,e) -> F.fprintf ppf "[%a:=%a]" Symbol.print x Expression.print e+  let print     = fun ppf -> to_list <+> F.fprintf ppf "%a" (Misc.pprint_many false "" print_sub)+      +(* fun s1 s2 -> Symbol.SMap.fold (fun x e s -> extend s (x, e)) s2 s1 *)+(*   let apply     = Misc.flip Symbol.SMap.maybe_find *)++end+++(**************************************************************************)+(******************* Horn Clauses: Parsing ARMC files *********************)+(**************************************************************************)++module Horn = struct+  +  type pr = string * string list+  type gd = C of pred | K of pr+  type t  = pr * gd list ++  let print_pr ppf (x, xs) = +    Format.fprintf ppf "%s(%s)" x (String.concat "," xs) +    +  let print_gd ppf = function +    | C p -> Predicate.print ppf p+    | K x -> print_pr ppf x ++  let print ppf (hd, gds) = +    Format.fprintf ppf "%a :- %a." +      print_pr hd +      (Misc.pprint_many false "," print_gd) gds++  let support_pr = snd +  let support_gd = function K pr -> support_pr pr | C p  -> p |> Predicate.support |> List.map Symbol.to_string +  let support    = fun (hd, gds) -> (support_pr hd) ++ (Misc.flap support_gd gds)+end++(* API *)+let simplify_pred = remove_bot <+> simplify_pred+++let esub_su su e = match e with +  | ((Var y), _) -> Misc.maybe_default (Subst.apply su y) e+  | _            -> e++(* ORIG +   let substs_pred   = fun p su -> su |> Subst.to_list |> Predicate.substs p |> simplify_pred+*)++let substs_pred p su = Predicate.map  id (esub_su su) p+let substs_expr e su = Expression.map id (esub_su su) e++(****************************************************************************)+(******************** Unification of Predicates *****************************)+(****************************************************************************)+++exception DoesNotUnify ++let rec pUnify (p1, p2) = +  let res = +    match p1, p2 with+  | (Atom (e1, r1, e1'), _), (Atom (e2, r2, e2'), _) when r1 = r2 ->+      let s1       = eUnify (e1, e2) in+      let e1', e2' = Misc.map_pair ((Misc.flip Expression.substs) s1) (e1', e2') in+      let s2       = eUnify (e1', e2') in+      s1 ++ s2+  | (Bexp e1, _), (Bexp e2, _) ->+      eUnify (e1, e2)+  | (Not p1, _), (Not p2, _) ->+      pUnify (p1, p2)+  | (Imp (p1, p1'), _), (Imp (p2, p2'), _) ->+      psUnify ([p1; p1'], [p2; p2'])+  +  | (And p1s, _), (And p2s, _) +  | (Or p1s, _), (Or p2s, _) +    when List.length p1s = List.length p2s ->+      psUnify (p1s, p2s)+  | _, _ -> raise DoesNotUnify+  in+  let _ = if mydebug then +          (Format.printf "pUnify: p1 is %a, p2 is %a, subst = %a \n" +          Predicate.print p1 Predicate.print p2 Subst.print (Subst.of_list res)) in+  res++and psUnify (p1s, p2s) =+  let _ = asserts (List.length p1s = List.length p2s) "psUnify" in+  List.fold_left2 begin fun s p1 p2 ->+    (p1, p2) +    |> Misc.map_pair (fun p -> Predicate.substs p s)+    |> pUnify+    |> (fun s' -> s' ++ s)+  end [] p1s p2s++and eUnify = function+  | (Con c1, _), (Con c2, _) when c1 = c2 ->+      []+  | (Var x1, _), (Var x2, _) when x1 = x2 ->+      []+  | (Bin (e1, op1, e1'),_), (Bin (e2, op2, e2'), _) when op1 = op2 ->+      esUnify ([e1; e1'], [e2; e2'])+  | (Ite (p1, e1, e1'),_), (Ite (p2, e2, e2'), _) ->+      let s = pUnify (p1, p2) in+      let [e1; e1'; e2; e2'] = List.map ((Misc.flip Expression.substs) s) [e1; e1'; e2; e2'] in+      esUnify ([e1; e1'], [e2; e2'])+  | (Cst (e1, t1),_), (Cst (e2, t2),_) when t1 = t2 ->+      eUnify (e1, e2)+  | (App (uf1, e1s), _), (App (uf2, e2s),_) when uf1 = uf2 ->+      esUnify (e1s, e2s)+  | e, (Var x, _) | (Var x, _), e when Symbol.is_wild x ->+      [(x, e)]+  | _, _ -> raise DoesNotUnify ++and esUnify (e1s, e2s) =+  let _ = asserts (List.length e1s = List.length e2s) "esUnify" in+  List.fold_left2 begin fun s e1 e2 ->+    (e1, e2) +    |> Misc.map_pair (fun e -> Expression.substs e s)+    |> eUnify+    |> (fun s' -> s' ++ s)+  end [] e1s e2s++(* API *)+let unify_pred p1 p2 = try pUnify (p1, p2) |> Subst.of_list |> some with DoesNotUnify -> None +let into_of_expr = function Con (Constant.Int i), _  -> Some i | _ -> None++let symm_pred = function +  | Atom (e1, r, e2), _ -> pAtom (e2, symm_brel r, e1)+  | p                   -> p++(* {{{+let rec expr_subst hp he e x e' =+  let rec esub e =+    try ExprHash.find he e with Not_found -> begin+      let rv = +        match euw e with+        | Var y when x = y ->+            e' +        | Con _ | Var _ -> +            e+        | App (s, es) ->+            App (s, List.map esub es) |> ewr+        | Bin (e1, op, e2) ->+            Bin (esub e1, op, esub e2) |> ewr+        | Ite (ip, te, ee) ->+            Ite (pred_subst hp he ip x e', esub te, esub ee) |> ewr+        | Fld (s, e1) ->+            Fld (s, esub e1) |> ewr in+      let _  = ExprHash.add he e rv in+      rv +    end in esub e++and pred_subst hp he e x e' =+  let rec s e =+    try PredHash.find h e with+	Not_found -> (let foo = s1 e in PredHash.add h e foo; foo)+  and s1 e =+    match puw e with+	True -> e+      | False -> e+      | And plist -> pwr (And(List.map s plist))+      | Or plist -> pwr (Or(List.map s plist))+      | Not p -> pwr (Not(s p))+      | Implies (p1, p2) -> pwr (Implies (s p1, s p2))+      | Equality (x,y) -> pwr (Equality(expr_subst h he x v vv,expr_subst h he y v vv))+      | Atom (_) -> e+      | Leq(x,y) -> pwr (Leq(expr_subst h he x v vv, expr_subst h he y v vv))+  in s e+}}} *)  +(** {{{+      let rec support pred =+        let h = Hash.create 251 in+        let eh = Expression.Hash.create 251 in+        let sh = Hashtbl.create 251 in+        let res = ref [] in+        let add s = if not(Hashtbl.mem sh s) then Hashtbl.add sh s (); res := s :: !res in++        let se exp =+          let rec s exp =+            try Expression.Hash.find eh exp with+                Not_found -> Expression.Hash.add eh exp (); s1 exp+          and s1 exp =+            match euw exp with+                Constant(_) -> ()+              | Application (func, args) -> +                  add func; List.iter s args+              | Variable(sym) -> add sym+              | Sum(args) -> List.iter s args+              | Coeff(c,t) -> s t+              | Ite _ -> failwith "ite not supported"+          in s exp in+          +        let rec s exp =+          try Hash.find h exp with+              Not_found -> Hash.add h exp (); s1 exp+        and s1 pred =+          match puw pred with+              True -> ()+            | False -> ()+            | And plist -> List.iter s plist+            | Or plist -> List.iter s plist+            | Not p -> s p+            | Implies (p1, p2) -> s p1; s p2+            | Equality (x,y) -> se x; se y+            | Leq (x,y) -> se x; se y+            | Atom (s) -> ()+        in s pred; List.rev !res+        +      let h = PredHash.create 251 in+        let rec ip p =+          let _ = f p in+          if not (PredHash.mem h p) then begin+            let _ = PredHash.add h p () in+            match puw p with+            | And ps | Or ps -> +                List.iter ip plist+            | Not p  | Forall (_,p) -> +                ip p +            | Imp (p1, p2) -> +                ip p1; ip p2+            | _ -> ()+          end in+        ip p +   }}} *)+(* {{{+  +      (* Translate predicate to a satisfiability-equivalent predicate without Ite *)+      +      let temp_ctr = ref 0+      let new_temp () =+	let n = "$$$" ^ (string_of_int !temp_ctr) in+	  (temp_ctr := !temp_ctr + 1; n)+	  +      let elim_ite sp =+	let cnsts = ref [] in+	let he = Expression.Hash.create 251 in+	let hp = Hash.create 251 in+	let rec te e =+	  try Expression.Hash.find he e+	  with Not_found -> (let foo = te1 e in Expression.Hash.add he e foo; foo)+	and te1 e =+	  match euw e with+	      Constant(c) -> e+	    | Application (func, args) -> +		ewr (Application (func, List.map te args))+	    | Variable(v) -> ewr (Variable(v))+	    | Sum(args) -> ewr (Sum(List.map te args))+	    | Coeff(c,t) -> ewr (Coeff(c,te t))+	    | Ite(si,st,se) ->+		let temp = ewr (Variable(new_temp())) in+		let i = tp si in+		let tv = te st and ev = te se in+		  begin+		    cnsts := pwr (Or [pwr (Not i); pwr (Equality(temp,(tv)))]) :: (!cnsts);+		    cnsts := pwr (Or [i; pwr (Equality(temp,(ev)))]) :: (!cnsts);+		    temp+		  end+	and tp p = +	  try Hash.find hp p+	  with Not_found -> (let foo = tp1 p in Hash.add hp p foo; foo)+	and tp1 p =+	  match puw p with+	      True -> p+	    | False -> p+	    | And plist -> pwr (And (List.map tp plist))+	    | Or plist -> pwr (Or (List.map tp plist))+	    | Not p -> pwr (Not (tp p))+	    | Implies (p1, p2) -> pwr (Implies((tp p1),(tp p2)))+	    | Equality (x,y) -> pwr(Equality((te x),(te y)))+	    | Leq (x,y) -> pwr(Leq((te x),(te y)))+	    | Atom (s) -> p+	in+	let foo = tp sp in+	  pwr (And(foo :: !cnsts))+    }}} *)
+ external/fixpoint/ast.mli view
@@ -0,0 +1,250 @@+(*+ * 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.+ *+ *)++(**+ * This module implements a DAG representation for expressions and + * predicates: each sub-predicate or sub-expression is paired with+ * a unique int ID, which enables constant time hashing. + * However, one must take care when using DAGS:+ * (1) they can only be constructed using the appropriate functions+ * (2) when destructed via pattern-matching, one must discard the ID+ *)++(*******************************************************)+(********************** Base Logic  ********************)+(*******************************************************)++module Cone : sig +  type 'a t = Empty | Cone of ('a * 'a t) list+  val map : ('a -> 'b) -> 'a t -> 'b t+end++module Sort :+  sig+    type loc = +      | Loc  of string +      | Lvar of int+      | LFun++    type tycon+    type t    +    type sub+   +    val tycon       : string -> tycon+    val tycon_string: tycon -> string++    val to_string   : t -> string+    val print       : Format.formatter -> t -> unit+   +    val t_num       : t+    val t_obj       : t+    val t_bool      : t+    val t_int       : t+    val t_generic   : int -> t+    val t_ptr       : loc -> t+    val t_func      : int -> t list -> t+    val t_app       : tycon -> t list -> t+    (* val t_fptr      : t *)+   +    val is_bool     : t -> bool+    val is_int      : t -> bool+    val is_func     : t -> bool+    val app_of_t    : t -> (tycon * t list) option +    val func_of_t   : t -> (int * t list * t) option+    val ptr_of_t    : t -> loc option+ +    val compat      : t -> t -> bool+    val empty_sub   : sub+    val unifyWith   : sub -> t list -> t list -> sub option +    val unify       : t list -> t list -> sub option+    val apply       : sub -> t -> t+    val generalize  : t list -> t list+    val sub_args    : sub -> (int * t) list+    (* val check_arity : int -> sub -> bool *)+  end++module Symbol : +  sig +    type t +    module SMap         : FixMisc.EMapType with type key = t+    module SSet         : FixMisc.ESetType with type elt = t+    val mk_wild         : unit -> t  +    val of_string       : string -> t+    val to_string       : t -> string +    val is_wild_any     : t -> bool+    val is_wild_fresh   : t -> bool+    val is_wild         : t -> bool+    val print           : Format.formatter -> t -> unit+    val value_variable  : Sort.t -> t+    val is_value_variable : t -> bool+    val suffix          : t -> string -> t+  end++module Constant :+  sig+    type t = Int of int+    val to_string : t -> string+    val print : Format.formatter -> t -> unit+  end++type tag  (* externally opaque *)++type brel = Eq | Ne | Gt | Ge | Lt | Le ++type bop  = Plus | Minus | Times | Div | Mod    (* NOTE: For "Mod" 2nd expr should be a constant or a var *)++type expr = expr_int * tag ++and expr_int =+  | Con  of Constant.t+  | Var  of Symbol.t+  | App  of Symbol.t * expr list+  | Bin  of expr * bop * expr  +  | Ite  of pred * expr * expr+  | Fld  of Symbol.t * expr             (* NOTE: Fld (s, e) == App ("field"^s,[e]) *) +  | Cst  of expr * Sort.t +  | Bot+  | MExp of expr list+  | MBin of expr * bop list * expr +  +and pred = pred_int * tag++and pred_int =+  | True+  | False+  | And  of pred list+  | Or   of pred list+  | Not  of pred+  | Imp  of pred * pred+  | Iff  of pred * pred+  | Bexp of expr+  | Atom of expr * brel * expr +  | MAtom of expr * brel list * expr+  | Forall of ((Symbol.t * Sort.t) list) * pred++(* Constructors : expressions *)+val eTim : expr * expr -> expr+val eInt : int -> expr+val eCon : Constant.t -> expr+val eMExp : expr list -> expr+val eMod : expr * int -> expr+val eModExp : expr * expr -> expr+val eVar : Symbol.t -> expr+val eApp : Symbol.t * expr list -> expr+val eBin : expr * bop * expr -> expr +val eMBin : expr * bop list * expr -> expr +val eIte : pred * expr * expr -> expr+val eFld : Symbol.t * expr -> expr+val eCst : expr * Sort.t -> expr+(* Constructors : predicates *)+val pTrue  : pred+val pFalse : pred+val pAtom  : expr * brel * expr -> pred+val pMAtom : expr * brel list * expr -> pred+val pAnd   : pred list -> pred+val pOr    : pred list -> pred+val pNot   : pred -> pred+val pImp   : (pred * pred) -> pred+val pIff   : (pred * pred) -> pred+val pBexp  : expr -> pred+val pForall: ((Symbol.t * Sort. t) list) * pred -> pred+val pEqual : expr * expr -> pred++val neg_brel : brel -> brel++module Expression : +sig+  module Hash : Hashtbl.S with type key = expr +  +  val print     : Format.formatter -> expr -> unit+  val show      : expr -> unit+  val to_string : expr -> string+  +  val unwrap    : expr -> expr_int+  val support   : expr -> Symbol.t list+  val subst     : expr -> Symbol.t -> expr -> expr +  val map       : (pred -> pred) -> (expr -> expr) -> expr -> expr +  val iter      : (pred -> unit) -> (expr -> unit) -> expr -> unit +end+ ++module Predicate :+sig+  module Hash : Hashtbl.S with type key = pred + +  val print     : Format.formatter -> pred -> unit+  val show      : pred -> unit+  val to_string : pred -> string++  val unwrap    : pred -> pred_int+  val support   : pred -> Symbol.t list+  val subst     : pred -> Symbol.t -> expr -> pred+  val map       : (pred -> pred) -> (expr -> expr) -> pred -> pred +  val iter      : (pred -> unit) -> (expr -> unit) -> pred -> unit +  val is_contra : pred -> bool+  val is_tauto  : pred -> bool+end++module Subst : +  sig+    type t+    val empty                : t+    val is_empty             : t -> bool+    val extend               : t -> (Symbol.t * expr) -> t+    val compose               : t -> t -> t+    val of_list              : (Symbol.t * expr) list -> t+    val simultaneous_of_list : (Symbol.t * expr) list -> t+    val to_list              : t -> (Symbol.t * expr) list+    val print                : Format.formatter -> t -> unit+    val apply                : t -> Symbol.t -> expr option+  end+++module Horn :+  sig+    type pr = string * string list+    type gd = C of pred | K of pr+    type t  = pr * gd list +    val print: Format.formatter -> t -> unit+    val support: t -> string list+  end++val print_stats    : unit -> unit+val fixdiv         : pred -> pred+val zero           : expr+val one            : expr+val bot            : expr++val symm_pred      : pred -> pred+val unify_pred     : pred -> pred -> Subst.t option+val substs_expr    : expr -> Subst.t -> expr+val substs_pred    : pred -> Subst.t -> pred +val simplify_pred  : pred -> pred+val conjuncts      : pred -> pred list++val sortcheck_expr : (Sort.tycon -> bool) -> (Symbol.t -> Sort.t option) -> expr -> Sort.t option+val sortcheck_pred : (Sort.tycon -> bool)  -> (Symbol.t -> Sort.t option) -> pred -> bool+val sortcheck_app  : (Sort.tycon -> bool)  -> (Symbol.t -> Sort.t option) -> Sort.t option -> Symbol.t -> expr list -> (Sort.sub * Sort.t) option++val into_of_expr   : expr -> int option+
+ external/fixpoint/cindex.ml view
@@ -0,0 +1,411 @@+(*+ * 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.+ *+ *)++(***************************************************************)+(**** This module implements constraint indexing ***************)+(***************************************************************)+module H  = Hashtbl+module F  = Format+module BS = BNstats+module Co = Constants+module C  = FixConstraint+module Misc = FixMisc +module IM = Misc.IntMap+module IS = Misc.IntSet+module SM = Ast.Symbol.SMap +module SS = Ast.Symbol.SSet+module P  = Ast.Predicate++open Misc.Ops++let mydebug = false ++(* TODO: Describe the SCC ordering scheme! *)++(***********************************************************************)+(***************** Index Data Structures and Accessors *****************)+(***********************************************************************)++type rank = {+    id    : C.id+  ; scc   : int    (* SCC number with ALL dependencies    *)+  ; iscc  : int    (* SCC number without CUT dependencies *)+  ; simpl : bool   (* Is the RHS simple ?                 *)+  ; cut   : bool   (* Is the RHS a CUT-VAR                *)+  ; tag   : C.tag;+}++let string_of_tag t = +  Printf.sprintf "[%s]" (Misc.map_to_string string_of_int t)++let pprint_rank ppf r = +  Format.fprintf ppf "id=%d, scc=%d, iscc=%d, cut=%b, tag=%a" +    r.id r.scc r.iscc r.cut C.print_tag r.tag++module WH = +  Heaps.Functional (struct +    type t = int * rank +    let compare (ts,r) (ts',r') = +      if r.scc <> r'.scc then compare r.scc r'.scc else+        if ts <> ts' then - (compare ts ts') else +          if r.iscc <> r'.iscc then compare r.iscc r'.iscc else+            if !Constants.ptag && r.tag <> r'.tag then compare r.tag r'.tag else+              compare r.simpl r'.simpl+  end)++type wkl = WH.t++type t = +  { cnst  : FixConstraint.t IM.t     (* id   -> refinement_constraint *) +  ; rnkm  : rank IM.t                (* id   -> dependency rank *)+  ; depm  : C.id list IM.t           (* id   -> successor ids *)+  ; pend  : (C.id, unit) H.t         (* id   -> is in wkl ? *)+  ; rts   : IS.t                     (* {rank} members are "root" sccs *)+  ; ds    : C.dep list               (* add/del dep list *)+  ; rdeps : (int * int) list         (* real dependencies *)  +  ; kuts  : Ast.Symbol.t list        (* CUT KVars *)+  }++let get_ref_rank me c =+  Misc.do_catch "ERROR: Cindex.get_ref_rank" (IM.find (C.id_of_t c)) me.rnkm++let get_ref_constraint me i = +  Misc.do_catch "ERROR: Cindex.get_ref_constraint" (IM.find i) me.cnst++(***********************************************************************)+(******************** Building Real Dependencies ***********************)+(***********************************************************************)++let refa_ko = function C.Kvar (_,k) -> Some k | _ -> None++let reft_ks = function (_,_,ras) -> Misc.map_partial refa_ko ras++let lhs_ks c = +  c |> C.lhs_of_t+    |> reft_ks +    |> SM.fold (fun _ (r:C.reft) l -> (reft_ks r) ++ l) (C.env_of_t c)++let rhs_ks c =+  c |> C.rhs_of_t |> reft_ks ++let make_kread_map cm = +  cm |> IM.to_list +     |> Misc.flap (fun (id, c) -> lhs_ks c |>: (fun k -> (k, id)))+     |> SM.of_alist +(*     >> SM.iter (fun k ids -> Co.bprintf mydebug "ReadIn %a := %a\n" Ast.Symbol.print k Misc.pprint_pretty_ints ids) + *)++let make_deps cm = +  let km = make_kread_map cm in+  cm |> IM.to_list+     |> Misc.flap (fun (id, c) -> rhs_ks c |> Misc.flap (fun k -> SM.finds k km |>: (fun id' -> (id, id'))))+     |> Misc.pad_fst IM.of_alist +(*      >> (fst <+> IM.iter (fun i js -> Co.bprintf mydebug "DepsOf (id = %d) = @[%a@]\n" i Misc.pprint_pretty_ints js)) +*)++(* IM.fold begin fun id c acc ->+    List.fold_left begin fun (dm, deps) k -> +      let rd_ids = SM.finds k km in+      let deps'  = List.map (fun rd_id -> (id, rd_id)) rd_ids in+      (IM.adds id rd_ids dm, (deps' ++ deps)) +    end acc (rhs_ks c) +   end cm (IM.empty, [])+ *)++(***********************************************************************)+(************* Adjusting Dependencies with Provided Tag-Deps ***********)+(***********************************************************************)++let delete_deps cm dds = +  let delf = C.matches_deps dds in+  let tagf = fun x -> IM.find x cm |> C.tag_of_t in+  List.filter (not <.> delf <.> Misc.map_pair tagf)+  +let add_deps cm ads ijs = +  let tt = H.create 37 in+  let _  = IM.iter (fun id c -> H.add tt (C.tag_of_t c) id) cm in+  ads |> Misc.map C.tags_of_dep+      |> Misc.map (Misc.map_pair (H.find_all tt))+      |> Misc.flap (Misc.uncurry Misc.cross_product)+      |> (++) ijs++let adjust_deps cm ds = +  let ads, dds = List.partition C.pol_of_dep ds in+  !Constants.adjdeps <?> (add_deps cm ads <.> delete_deps cm dds)++(***********************************************************************)+(**************************** Dependency SCCs **************************)+(***********************************************************************)++let string_of_ints is = is |> List.map string_of_int |> String.concat ", "++let print_rank_groups f rs = +  rs |>  Misc.kgroupby f +     |>  List.sort compare +     |>  List.iter begin fun (g, rs) ->+            Format.printf "Group=%s size=%d ids=%s\n" +              g (List.length rs) (string_of_ints (List.map (fun r -> r.id) rs)) +          end++let string_of_cid cm id = +  try +    IM.find id cm +    |> C.tag_of_t+    |> Misc.fsprintf C.print_tag+    |> Printf.sprintf "%d: %s" id +  with _ -> assertf "string_of_cid: impossible" ++let make_rankm cm ranks iranks = +  let rm  = IM.of_list ranks  in+  let irm = IM.of_list iranks in+  IM.domain cm +    |>: begin fun id ->+          let c         = IM.find id cm  in+          let r         = IM.find id rm  in+          let (ir, cut) = IM.find id irm in+          id, { id    = id; scc   = r; iscc  = ir; cut   = cut; tag   = C.tag_of_t c +              ; simpl = (not !Co.psimple) || (C.is_simple c)                         }+        end+    |> IM.of_list+    (* >> (IM.range <+> print_rank_groups (fun r -> Printf.sprintf "(%d/%d)" r.scc r.iscc ))   *)++(* returns a predicate which is true of ids whose RHS kvar is a kut-var *)+let is_cut_cst cm kuts = +  let id_cstr     = fun i -> IM.find i cm    in+  let is_cut_kvar = let ks = SS.of_list kuts in +                    fun k -> SS.mem k ks  +  in List.exists is_cut_kvar <.> List.map snd <.> C.kvars_of_reft <.> C.rhs_of_t <.> id_cstr ++let inner_ranks cm deps irs = function +  | [] ->   (* if no kuts specified, use dummys *)+      irs  |>: (fun (i, r) -> (i, (r, false)))  +  | kuts -> (* else, redo the SCC computation without cut-dependencies *)+      let is_eq_rank = let rm = IM.of_list irs in  fun i j -> (IM.find i rm = IM.find j rm)  in+      let is_cut_id  = is_cut_cst cm kuts                                                    in+      let is_cut_dep = fun (i, j) -> is_cut_id i && is_eq_rank i j                           in+      deps |> List.filter (not <.> is_cut_dep)+           |> Fcommon.scc_rank "inner" (string_of_cid cm) (IM.domain cm)  +           |>: (fun (i, ir) -> (i, (ir, is_cut_id i)))++let make_ranks cm deps kuts =+  let ranks  = Fcommon.scc_rank "constraint" (string_of_cid cm) (IM.domain cm) deps in+  let iranks = inner_ranks cm deps ranks kuts                                       in+  make_rankm cm ranks iranks++let make_roots rankm ijs =+  let sccs = rankm |> IM.to_list |> Misc.map (fun (_,r) -> r.scc) in +  let sccm = List.fold_left (fun is scc -> IS.add scc is) IS.empty sccs in+  List.fold_left begin fun sccm (i,j) ->+    let ir = (IM.find i rankm).scc in+    let jr = (IM.find j rankm).scc in+    if ir <> jr then IS.remove jr sccm else sccm+  end sccm ijs+++(* A constraint c is non-live if its rhs is a k variable that is not+ * (transitively) read. + * roots := { c | (rhs_of_t c) has a concrete predicate }+ * lives := Pre*(roots) where Pre* is refl-trans-clos of the depends-on relation *)++let make_lives cm real_deps =+  let dm = real_deps |>: Misc.swap |> IM.of_alist in+  let js = cm |> IM.filter (fun _ -> C.is_conc_rhs) |> IM.domain |> IS.of_list  in+  (js, IS.empty)+  |> Misc.fixpoint begin fun (js, vm) ->+       let vm = IS.fold (fun j vm -> IS.add j vm) js vm in+       let js = IS.fold begin fun j js ->+                  IM.finds j dm +                  |> List.filter (fun j -> not (IS.mem j vm)) +                  |> IS.of_list+                  |> IS.union js+                end js IS.empty+       in ((js, vm), not (IS.is_empty js))+     end+  |> (fst <+> snd) +  >> (IS.cardinal <+> Co.bprintf mydebug "#Live Constraints: %d \n") ++let create_raw kuts ds cm dm real_deps =+  let deps = adjust_deps cm ds real_deps in+  let rnkm = make_ranks cm deps kuts     in+  { cnst = cm; ds  = ds; kuts = kuts; rdeps = real_deps; rnkm  = rnkm+  ; depm = dm; rts = make_roots rnkm deps ;  pend = H.create 17}+++(***********************************************************************)+(**************************** API **************************************)+(***********************************************************************)++(* API *) +let print ppf me =+  List.iter (Format.fprintf ppf "@[%a@] \n" C.print_dep) me.ds; +  IM.iter (fun _ c -> Format.fprintf ppf "@[%a@] \n" (C.print_t None) c) me.cnst+ +let save fname me = +  Misc.with_out_file fname begin fun oc -> +    let ppf = F.formatter_of_out_channel oc in +    F.fprintf ppf "//Sliced Constraints@.";+    F.fprintf ppf "@[%a@] \n" print me+  end++(* The "adjusted" dependencies are used to create the SCC ranks ONLY.+ * For soundness, the "real" dependencies must be used to push + * "successors" into the worklist. *)++(* API *)+let create kuts ds cs =+  let cm            = cs |>: (Misc.pad_fst C.id_of_t) |> IM.of_list in +  let dm, real_deps = make_deps cm in+  create_raw kuts ds cm dm real_deps ++(* API *)+let slice me = +  let lives = make_lives me.cnst me.rdeps in+  let cm    = me.cnst  +              |> IM.filter (fun i _ -> IS.mem i lives) in+  let dm    = me.depm  +              |> IM.filter (fun i _ -> IS.mem i lives) +              |> IM.map (List.filter (fun j -> IS.mem j lives)) in+  let rdeps = me.rdeps +              |> Misc.filter (fun (i,j) -> IS.mem i lives && IS.mem j lives) in  +  create_raw me.kuts me.ds cm dm rdeps+  >> save !Co.save_file++(* API *) +let slice_wf me ws = +  let ks = me.cnst +           |> IM.range +           |> Misc.flap C.kvars_of_t +           |> Misc.map snd +           |> SS.of_list +  in Misc.filter (C.reft_of_wf <+> C.kvars_of_reft <+> List.exists (fun (_,k) -> SS.mem k ks)) ws+  +  +let pp_cstr_id ppf c   = F.fprintf ppf "%d" (C.id_of_t c)+let pp_cstr_ids ppf cs = F.fprintf ppf "@[%a@.@]" (Misc.pprint_many false "," pp_cstr_id) cs++(* API *) +let deps me c =+  (try IM.find (C.id_of_t c) me.depm with Not_found -> [])+  |> List.map (get_ref_constraint me)+  (* >> (List.map C.id_of_t <+> Co.logPrintf "Deps %d = [%a]\n" (C.id_of_t c) Misc.pprint_pretty_ints) *)++(* API *)+let to_list me = IM.range me.cnst++(* +(* API *)+let to_live_list me =+  me.cnst |> IM.to_list +          |> Misc.map_partial (fun (i,c) -> if IS.mem i me.livs then Some c else None)++*)++let sort_iter_ref_constraints me f = +  me.rnkm |> IM.to_list+          |> List.sort (fun (_,r) (_,r') -> compare r.tag r'.tag) +          |> List.iter (fun (id,_) -> f (IM.find id me.cnst)) ++(* API *)+let wpush =+  let timestamp = ref 0 in+  fun me w cs ->+    incr timestamp;+    List.fold_left begin fun w c -> +      let id = C.id_of_t c in+      if Hashtbl.mem me.pend id then w else begin +        Co.cprintf Co.ol_solve "Pushing %d at %d \n" id !timestamp; +        Hashtbl.replace me.pend id (); +        WH.add (!timestamp, get_ref_rank me c) w+      end+    end w cs++let wstring w = +  WH.fold (fun (_,r) acc -> r.id :: acc) w [] +  |> List.sort compare+  |> Misc.map_to_string string_of_int++(* API *)+let wpop me w =+  try +    let _, r = WH.maximum w in+    let _    = Hashtbl.remove me.pend r.id in+    let c    = get_ref_constraint me r.id in+    let _    = Co.cprintf Co.ol_solve "popping (%a) " pprint_rank r in+    let _    = Co.cprintf Co.ol_solve "from wkl = %s \n" (wstring w) in +    (Some c, WH.remove w)+  with Heaps.EmptyHeap -> (None, w) ++let roots me =+  IM.fold begin fun id r sccm ->+   (*  if not (IM.mem r.scc me.rts) then sccm else *)+      let rs = try IM.find r.scc sccm with Not_found -> [] in+      IM.add r.scc (r::rs) sccm+  end me.rnkm IM.empty+  |> IM.map (List.hd <.> List.sort compare)+  |> IM.to_list+  |> Misc.map (fun (_,r) -> get_ref_constraint me r.id) ++(* API *)+let winit me = +  roots me |> wpush me WH.empty  ++++(***************************************************************)+(*********** A Operations for Constraint Cones *****************)+(***************************************************************)++let rec cone_height = function+  | Ast.Cone.Empty    -> +      0+  | Ast.Cone.Cone xcs -> +      xcs |> List.map (snd <+> cone_height <+> (+) 1) |> Misc.list_max 0++let rec cone_size = function+  | Ast.Cone.Empty    ->+      0+  | Ast.Cone.Cone xcs -> +      let ns = List.map (snd <+> cone_size) xcs in+      List.fold_left (+) (List.length ns) ns++let cone (cm, dm) =+  let rec go seen cid = +    if IS.mem cid seen then Ast.Cone.Empty else+      let seen' = IS.add cid seen in+      match IM.finds cid dm with+      | []    -> Ast.Cone.Empty+      | cids' -> Ast.Cone.Cone (List.map (Misc.pad_snd (go seen')) cids')+  in begin fun id -> +           (Ast.Cone.Cone [(id, go IS.empty id)])+        |> (Ast.Cone.map (fun i -> C.tag_of_t <| IM.safeFind i cm "Cindex.cone")) +        >> (fun c -> Format.printf "CONE: %d size=%d height=%d" id (cone_size c) (cone_height c))+     end++let data_sliced_deps cs = +  let cs = FixSimplify.WeakFixpoint.simplify_ts cs          in+  let cm = cs |>: Misc.pad_fst C.id_of_t |>  IM.of_list     in+  let dm = make_deps cm |> snd |>: Misc.swap |> IM.of_alist in+  (cm, dm)+  +(* API *)+let data_cones cs = cs |> data_sliced_deps |> cone
+ external/fixpoint/cindex.mli view
@@ -0,0 +1,54 @@+(*+ * 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.+ *+ *)++(***************************************************************)+(**** This module implements constraint indexing ***************)+(***************************************************************)++type t+type wkl++(** indexing and dependencies *)+val to_list      : t -> FixConstraint.t list ++(* val to_live_list : t -> FixConstraint.t list *)+val create       : Ast.Symbol.t list -> FixConstraint.dep list -> FixConstraint.t list -> t +val deps         : t -> FixConstraint.t -> FixConstraint.t list+val slice        : t -> t +val slice_wf     : t -> FixConstraint.wf list -> FixConstraint.wf list++(** worklist manipulation *)+val wpush        : t -> wkl -> FixConstraint.t list -> wkl +val wpop         : t -> wkl -> FixConstraint.t option * wkl+val winit        : t -> wkl++(** printing *)+val print        : Format.formatter -> t -> unit +++(***************************************************************)+(*********** Some Operations for Constraint Cones **************)+(***************************************************************)++val data_cones: FixConstraint.t list -> FixConstraint.id -> FixConstraint.tag Ast.Cone.t+
+ external/fixpoint/counterexample.ml view
@@ -0,0 +1,323 @@+(*+ * Copyright © 2009-12 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.+ *+ *)++(***************************************************************)+(* Counterexample Generation (cf. Lahiri-Vanegue, VMCAI 2011) **) +(***************************************************************)++module F  = Format+module BS = BNstats+module C  = FixConstraint++module Misc = FixMisc +module IM = Misc.IntMap+module IS = Misc.IntSet++module A  = Ast+module Sy = A.Symbol+module SM = Sy.SMap +module SS = Sy.SSet+module P  = A.Predicate+module Su = A.Subst+module Q  = Qualifier++open Misc.Ops++let mydebug   = false++(***************************************************************************)+(************** Type Aliases ***********************************************)+(***************************************************************************)++type step  = int+type kvar  = Sy.t+type fact  = Abs of kvar * Qualifier.t | Conc of C.id+type cause = step * C.id * ((Sy.t * fact) list)++(* [k |-> [(i0, [q_i0_1...]),...]] + * where q_i0_1... are killed at timestep i0 for kvar k sorted by step *)+type lifespan = (step * Q.t list) list SM.t ++(* [id |-> i0,...] + * where the constraint id is selected at steps i0... by solver *)+type ctrace  = step list IM.t ++(* [((x1,k1,q1), c1);...;((xn,kn,qn),cn)] + * where each k_i+1, q_i+1, c_i+1 is the "cause" for why k_i, q_i is killed *)+(* type cex     = (Sy.t * fact * C.id) list *)+type cex     = Cause of Sy.t * fact * C.id * cex list++(****************************************************************************)+(******************** Printing Counterexamples ******************************)+(****************************************************************************)++let print_fact ppf = function+  | Abs (k, q) -> F.fprintf ppf "(%a/%a)" Sy.print k Q.print_args q+  | Conc i     -> F.fprintf ppf "(id %d)" i++let print_step ppf (x, f, cid) =+  F.fprintf ppf "%a: %a @@ %d" Sy.print x print_fact f cid++(*+let print_cex = Misc.pprint_many_box true "" "---> " "" print_step+*)++let rec print_cex spaces ppf (Cause (x, f, cid, cs)) =+  F.fprintf ppf "%s `-> %a\n%a" +    (String.concat "" (Misc.clone " " spaces))+    print_step (x, f, cid) +    (Misc.pprint_many false "\n\n" (print_cex (spaces + 4))) cs++let print_cex = print_cex 0++let print_fact_causes n ppf (f, xfs) =+  F.fprintf ppf "fact %a killed at %d by: %a \n"+    print_fact f+    n+    (Misc.pprint_many_brackets false  (Misc.pprint_tuple Sy.print print_fact)) xfs++(****************************************************************************)+(******************** Instance Type *****************************************)+(****************************************************************************)++let compare_fact f1 f2 =+  compare (Misc.fsprintf print_fact f1) (Misc.fsprintf print_fact f2)++module FactMap = Misc.EMap (struct +  type t = fact+  let compare = compare_fact+  let print   = print_fact+end)++type t = { tpc      : ProverArch.prover +         ; n        : int                   (* number of solver iters *)+         ; s        : FixConstraint.soln+         ; cm       : FixConstraint.t IM.t+         ; ctrace   : ctrace +         ; lifespan : lifespan              (* builds soln at n                *)+         ; fsm      : step FactMap.t        (* fact |-> step at which killed   *)+         ; scm      : int IM.t              (* step |-> constr at step         *)+         }++let scm_of_ctrace ctrace = +  ctrace +  |> IM.to_list +  |> Misc.flap (fun (cid, is) -> List.map (fun i -> (i, cid)) is)+  |> Misc.fsort fst+  |> IM.of_list++let fsm_of_lifespan lifetime =+  SM.fold begin fun k sqs fsm ->+    List.fold_left begin fun fsm (step, qs) -> +      List.fold_left begin fun fsm q -> +        FactMap.add (Abs (k, q)) step fsm+      end fsm qs+    end fsm sqs+  end lifetime FactMap.empty ++(************************************************************************)+(*********** Helpers to Reconstitute Solutions and Candidates ***********)+(************************************************************************)++let constrOfId me cid = +   IM.safeFind cid me.cm "Cex.constrOfId"++let solutionAt me n k =+  SM.safeFind k me.lifespan "solutionAt: bad kvar"+  |> List.filter (fun (m,_) -> n <= m) +  |> Misc.flap snd+  |> Misc.map Q.pred_of_t+  |> (++) (me.s k)++let isUnsatAt me c n = +  let s     = solutionAt me n                                 in+  let rhsp  = A.pAnd <| C.preds_of_reft s (C.rhs_of_t c)      in+  let query = A.pAnd <| (A.pNot rhsp) :: (C.preds_of_lhs s c) in+  not <| me.tpc#is_contra (C.senv_of_t c) query++let prevStep_conc me c : int =+  let _  = asserts (C.is_conc_rhs c) in+  let no = Misc.find_first_true (isUnsatAt me c) 0 me.n in+  Misc.maybe_apply (+) no (-1)++let prevStep_abs me cid n : int = +  let rec go n = function+    | m1 :: _ when m1 = n     -> (-1)+    | m1 :: (m2 :: _ as rest) -> if n = m2 then m1 else go n rest+    | _                       -> assertf "prevStep with bad ctrace"+  in go n (IM.safeFind cid me.ctrace "prevStep: bad cid") ++let prevStep me c n = +  if C.is_conc_rhs c then +    prevStep_conc me c+  else+    prevStep_abs me (C.id_of_t c) n++let killstep_of_fact me f = +  FactMap.safeFind f me.fsm "Cex.killstep_of_fact"++let delta me c n k : fact list = +  let _n = prevStep me c n in+  SM.safeFind k me.lifespan "delta: bad kvar" +  |> List.filter (fun (m,_) -> _n <= m && m < n) +  |> Misc.flap snd+  |> Misc.map (fun q -> Abs (k, q))++(************************************************************************)+(************************************************************************)+(************************************************************************)++let killerCands me c n : (int * (((Sy.t * fact) * A.pred)) list) list =+  foreach (C.kbindings_of_lhs c) begin fun (x, (vv, t, ras)) ->+    foreach ras begin function C.Kvar (su, k) ->+      foreach (delta me c n k) begin function (Abs (_, q) as f) ->+        let su' = Su.extend su (vv, A.eVar x)       in+        let p'  = A.substs_pred (Q.pred_of_t q) su' in +        (x, f), p'+      end+    end |> Misc.flatten+  end |> Misc.flatten+  |> Misc.kgroupby (fst <+> snd <+> killstep_of_fact me)++(************************************************************************)+(******************** Lazy Explanations *********************************)+(************************************************************************)++let killedPred me c f =  +  match f, C.rhs_of_t c with+  | Abs (k, q), (_,_, [C.Kvar (su, k')])+    when k = k'+    -> A.substs_pred (Q.pred_of_t q) su+  | Conc cid, (_,_,[C.Conc p])+    when C.id_of_t c = cid+    -> p +  | _ -> failwith "Counterexample.killed"++let getKillStep me c bgp iks =+  let iks = Misc.fsort fst iks in+  let ps  = iks |>: (snd <+> List.map snd <+> A.pAnd) in+  match me.tpc#unsat_suffix (C.senv_of_t c) bgp ps with+  | Some j when 0 <= j && j < List.length iks +       -> List.nth iks j +  | io -> let _ = F.printf +                  "getKillStep failure: (cid = %d) (|iks| = %d) (io = %a)\n bgp = %a\nps  = %a\n"+                    (C.id_of_t c) +                    (List.length iks) +                    (Misc.pprint_maybe Misc.pprint_int) io+                    P.print bgp+                    (Misc.pprint_many_brackets true P.print) ps +          in assertf "getKillStep"++let killinfo me = function+  | Conc cid -> me.n, cid+  | f        -> let n = killstep_of_fact me f in+                (n, IM.safeFind n me.scm "Cex.killinfo")++(* {{{ ORIGINAL: simply use unsat core.++let is_bot_killer = function+  | (f, p) when P.is_contra p -> Some f+  | _                         -> None+++let getKillers_cands me c bgp cands =+  match cands, Misc.exists_maybe is_bot_killer cands with +  | [], _ ->+      None+  | _, Some g -> +      Some g +  | _, _  -> +      TP.unsat_core me.tpc (C.senv_of_t c) bgp cands +      |> Misc.do_catch "ERROR: empty unsat core" List.hd+      |> some++let getKillers_fact (me: t) (f: fact) = +  let n, cid     = killinfo me f                            in+  let c          = IM.safeFind cid me.cm "Cex.getKillers 3" in+  match killerCands me c n with []  -> (cid, None) | iks -> +    let bgps       = C.preds_of_lhs (solutionAt me n) c+                     |> (++) [A.pNot (killedPred me c f)]   in+    let (j, cands) = getKillStep me c (A.pAnd bgps) iks     in+    let bgps'      = iks +                   |> List.filter (fun (i,_) -> j < i)+                   |> Misc.flap   (snd <+> List.map snd)    in +    (cid, getKillers_cands me c (A.pAnd (bgps ++ bgps')) cands)++let maxCubeSize = 1++let underApproxCubes me  (p:pred) (q:pred) (rs: ('a * pred) list) : 'a option =+  Misc.exists_maybe begin fun (f, fp) ->+    if SAT (p /\ fp) && UNSAT (p /\ fp /\ q) +    then Some f+    else None+  end rs++}}} *)++let getKillers_cands me c p q rs =+  let env    = C.senv_of_t c in+  let contra = fun p -> me.tpc#is_contra env p in+  Misc.map_partial begin fun (f, fp) ->+    if contra (A.pAnd [p; fp; q]) && not (contra (A.pAnd [p; fp]))+    then Some f+    else None+  end rs++let getKillers_fact (me: t) (f: fact) = +  let n, cid     = killinfo me f                            in+  let c          = IM.safeFind cid me.cm "Cex.getKillers 3" in+  match killerCands me c n with []  -> (cid, []) | iks -> +    let bgps       = C.preds_of_lhs (solutionAt me n) c     in+    let killedp    = A.pNot (killedPred me c f)             in +    let (j, cands) = getKillStep me c (A.pAnd bgps) iks     in+    let bgps'      = iks +                   |> List.filter (fun (i,_) -> j < i)+                   |> Misc.flap   (snd <+> List.map snd)    in +    (cid, getKillers_cands me c (A.pAnd (bgps ++ bgps')) killedp cands)++let rec explain me f =+  let cid, xfs = getKillers_fact me f in+  List.map (fun (x',f') -> Cause (x', f', cid, explain me f')) xfs++(********************************************************************)+(*********************** API ****************************************)+(********************************************************************)++(* API *)+let create tpc s cs ctrace lifespan =+  let scm    = scm_of_ctrace ctrace in+  { tpc      = tpc +  ; s        = s +  ; cm       = cs |>: Misc.pad_fst C.id_of_t |> IM.of_list +  ; n        = 1 + Misc.list_max 0 (IM.domain scm)+  ; ctrace   = IM.map Misc.sort_and_compact ctrace +  ; lifespan = lifespan+  ; fsm      = fsm_of_lifespan lifespan+  ; scm      = scm+  }  ++(* API *)+let explain me c = +  let cid0 = C.id_of_t c in+  let f0   = Conc cid0   in+  Cause (Sy.of_string "ERROR", f0, cid0, explain me f0)
+ external/fixpoint/counterexample.mli view
@@ -0,0 +1,51 @@+(*+ * Copyright © 2009-12 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.+ *+ *)++(***************************************************************)+(* Counterexample Generation (cf. Lahiri-Vanegue, VMCAI 2011) **) +(***************************************************************)++type t ++type kvar     = Ast.Symbol.t+type fact     = Abs of kvar * Qualifier.t | Conc of FixConstraint.id+type step     = int ++(* [k |-> [(i0, [q_i0_1...]),...]] + * where q_i0_1... are killed at timestep i0 for kvar k sorted by step *)+type lifespan = (step * Qualifier.t list) list Ast.Symbol.SMap.t ++(* [cid |-> i0,...] cid is selected at steps i0... by solver *)+type ctrace  = step list FixMisc.IntMap.t ++type cex     ++val create  :  ProverArch.prover        (* tp context        *)+            -> FixConstraint.soln       (* assumes           *) +            -> FixConstraint.t list     (* all constraints   *)+            -> ctrace                   +            -> lifespan +            -> t++val explain : t -> FixConstraint.t -> cex+val print_cex : Format.formatter -> cex -> unit
+ external/fixpoint/fix.ml view
@@ -0,0 +1,36 @@+(*+ * 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 Ast        = Ast+module Symbol     = Ast.Symbol+module Constant   = Ast.Constant++module Sort       = Ast.Sort+module Predicate  = Ast.Sort+module Expression = Ast.Expression++module FixConstraint = FixConstraint+module Solve      = Solve+++
+ external/fixpoint/fixConfig.ml view
@@ -0,0 +1,162 @@+(*+ * 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)+
+ external/fixpoint/fixConfig.mli view
@@ -0,0 +1,53 @@+(* This module deals with top-level parsing of fq files and such *)++(*+exception UnmappedKvar of Ast.Symbol.t+*)+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+          | Qul of Qualifier.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    : Qualifier.t list                  (* Qualifiers                           *)+ ; kuts  : Ast.Symbol.t list                 (* "Cut"-Kvars, which break cycles      *)+ ; bm    : 'bind Ast.Symbol.SMap.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 *)+}+++++module type SIMPLIFIER = sig+  val simplify_ts: FixConstraint.t list -> FixConstraint.t list+end++val empty     : 'a cfg +val create    : deft list -> (Qualifier.t list) cfg+val print     : Format.formatter -> 'a cfg -> unit+val create_raw:  Ast.Sort.t list +              -> Ast.Sort.t Ast.Symbol.SMap.t +              -> Ast.pred list +              -> int +              -> FixConstraint.dep list +              -> FixConstraint.t list +              -> FixConstraint.wf list +              -> Qualifier.t list+              -> Ast.Symbol.t list+              -> FixConstraint.soln +              -> 'a cfg
+ external/fixpoint/fixConstraint.ml view
@@ -0,0 +1,541 @@+(*+ * 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 MODIFICATIONSy.+ *+ *)++(* This module implements basic datatypes and operations on constraints *)+module F  = Format+module H  = Hashtbl+module A  = Ast+module E  = A.Expression+module P  = A.Predicate+module Sy = A.Symbol+module So = A.Sort+module SM = Sy.SMap+module BS = BNstats+module Su = Ast.Subst+module Co  = Constants+module Misc = FixMisc +module MSM  = Misc.StringMap++open Misc.Ops++type tag  = int list * string+type id   = int+type dep  = Adp of tag * tag | Ddp of tag * tag | Ddp_s of tag | Ddp_t of tag++type refa = Conc of A.pred | Kvar of Su.t * Sy.t+type reft = Sy.t * A.Sort.t * refa list                (* { VV: t | [ra] } *)+type envt = reft SM.t+type wf   = envt * reft * (id option) * (Qualifier.t -> bool)+type t    = { full    : envt; +              nontriv : envt;+              guard   : A.pred;+              iguard  : A.pred;+              lhs     : reft;+              rhs     : reft;+              ido     : id option;+              tag     : tag; }++type soln = Ast.Symbol.t -> Ast.pred list++exception BadConstraint of (id * tag * string)+++(*+type soln    = Ast.pred list Ast.Symbol.SMap.t+type soln = { read  : Ast.Symbol.t -> Ast.pred list+            ; kvars : Ast.Symbol.SSet.t }+*)++let mydebug = false ++(*************************************************************)+(************************** Misc.  ***************************)+(*************************************************************)++let is_simple_refatom = function +  | Kvar (s, _) -> Ast.Subst.is_empty s +  | _           -> false++let is_tauto_refatom  = function +  | Conc p -> P.is_tauto p +  |  _ -> false+  ++(* API *)+let fresh_kvar = +  let tick, _  = Misc.mk_int_factory () in+  tick <+> string_of_int <+> (^) "k_" <+> Sy.of_string++(* API *)+let kvars_of_reft (_, _, rs) =+  Misc.map_partial begin function +    | Kvar (subs, k) -> Some (subs,k) +    | _              -> None +  end rs++let meet x (v1, t1, ra1s) (v2, t2, ra2s) = +  asserts (v1=v2 && t1=t2) "ERROR: FixConstraint.meet x=%s (v1=%s, t1=%s) (v2=%s, t2=%s)" +  (Sy.to_string x) (Sy.to_string v1) (A.Sort.to_string t1) (Sy.to_string v2) (A.Sort.to_string t2) ;+  (v1, t1, Misc.sort_and_compact (ra1s ++ ra2s))++let env_of_bindings_ meetb xrs =+  List.fold_left begin fun env (x, r) -> +    let r = if meetb && SM.mem x env then meet x r (SM.find x env) else r in+    SM.add x r env+  end SM.empty xrs++(* API *)+let env_of_bindings         = env_of_bindings_ true+let env_of_ordered_bindings = env_of_bindings_ false ++(* +let env_of_bindings xrs =+  List.fold_left begin fun env (x, r) -> +    let r = if SM.mem x env then meet x r (SM.find x env) else r in+    SM.add x r env+  end SM.empty xrs+*)++let bindings_of_env = SM.to_list++(* let bindings_of_env env = +  SM.fold (fun x y bs -> (x,y)::bs) env []+*)++let split_ras ras = +  let cras, kras = List.partition (function (Conc _) -> true | _ -> false) ras in+  cras |> Misc.map_partial (function Conc p -> Some p | _ -> None) +       |> (function [] -> (None, kras) | ps -> (Some (A.pAnd ps), kras))+++let kbindings_of_lhs {nontriv = ne; lhs = (v, t, ras)} =  +  let xkss     = SM.to_list ne in+  let _, kras  = split_ras ras in+  (v, (v,t,kras)) :: xkss++let map_env    = SM.mapi+let lookup_env = Misc.flip SM.maybe_find +(* let lookup_env env x = try Some (SM.find x env) with Not_found -> None *)++++(* API *)+let is_simple {lhs = (_,_,ra1s); rhs = (_,_,ra2s)} = +  List.for_all is_simple_refatom ra1s +  && List.for_all is_simple_refatom ra2s +  && !Co.simple++let is_conc_refa = function Conc p -> not (P.is_tauto p) | _ -> false++(* API *)+let is_conc_rhs {rhs = (_,_,ras)} =+  List.exists is_conc_refa ras+  >> (fun rv -> if rv then (asserts (List.for_all is_conc_refa ras) "is_conc_rhs"))+++(* API *)+let kvars_of_t {nontriv = env; lhs = lhs; rhs = rhs} =+  [lhs; rhs] +  |> SM.fold (fun _ r acc -> r :: acc) env+  |> Misc.flap kvars_of_reft +++++(*************************************************************)+(*********************** Logic Embedding *********************)+(*************************************************************)++let canon_ras ras = +  match split_ras ras with+  | None, kras   -> kras+  | Some p, kras -> Conc p :: kras++(* +let non_trivial env = +  SM.fold begin fun x r sm -> match thd3 r with +        | [] -> sm +        | _::_ -> SM.add x r sm+  end env SM.empty+*)++let non_trivial env = +  SM.fold begin fun x (v,t,ras) ((ne, ps) as acc) -> match ras with+    | [] -> acc +    | _  -> let po, kras = split_ras ras in +            let ne' = match kras with [] -> ne | _      -> SM.add x (v,t,kras) ne in+            let ps' = match po with None -> ps | Some p -> (P.subst p v (A.eVar x)) :: ps  in+            ne', ps'+  end env (SM.empty, []) ++(* API *)+let is_conc_refa = function+  | Conc _ -> true+  | _      -> false++let soln_read s k = s k (* SM.find k s *)++(* API *)+let preds_of_refa s = function+  | Conc p      -> [p]+  | Kvar (su,k) -> soln_read s k |> List.map (Misc.flip A.substs_pred su)++(* API *)+let preds_of_reft f (_,_,ras) = +  Misc.flap (preds_of_refa f) ras++(* API *)+let meet_solution s1 s2 = fun k -> s1 k ++ s2 k (* SM.extendWith (fun _ -> (++)) *)+let empty_solution      = fun _ -> []++let apply_solution_refa f ra = +  Conc (A.pAnd (preds_of_refa f ra))++(* API *)+let apply_solution f (v, t, ras) = +  (v, t, List.map (apply_solution_refa f) ras)++let preds_of_envt f env =+  SM.fold+    (fun x ((vv, t, ras) as r) ps -> +      let vps = preds_of_reft f r in+      let xps = List.map (fun p -> P.subst p vv (A.eVar x)) vps in+      xps ++ ps)+    env [] ++(* API *)+let wellformed_pred env = +  A.sortcheck_pred Theories.is_interp (Misc.maybe_map snd3 <.> Misc.flip SM.maybe_find env)++(* API *)+let preds_of_lhs_nofilter f c = +  let envps = preds_of_envt f c.nontriv in+  let r1ps  = preds_of_reft f c.lhs in+  (c.iguard :: envps) ++ r1ps+++(* let preds_of_lhs f c =+  let env   = SM.add (fst3 c.lhs) c.lhs c.full in+  let wfp p = wellformed_pred env p +              >> (fun b -> if not b then F.eprintf "WARNING: Malformed Lhs Pred (%a)\n" P.print p) in+  let ps    = preds_of_lhs_nofilter f c        in+  let ps'   = List.filter wfp ps               in+  if !Co.strictsortcheck && List.length ps != List.length ps' +  then raise (BadConstraint (Misc.maybe c.ido, c.tag, "Malformed Lhs Pred"))+  else ps+*)++let report_wellformed env c p wf = +  if not wf then+    let msg = F.sprintf "WARNING: Malformed Lhs Pred (%s)\n" (P.to_string p)                  in +    let _   = F.eprintf "%s" msg                                                              in +    let _   = SM.iter (fun s (_,t,_) -> F.eprintf "@[%a :: %a@]@." Sy.print s So.print t) env in+    let _   = F.eprintf "@[%a@]@.@." P.print p                                                in+    if !Co.strictsortcheck then raise (BadConstraint (Misc.maybe c.ido, c.tag, msg))++(* API *)+let preds_of_lhs f c = +  let env = SM.add (fst3 c.lhs) c.lhs c.full in+  preds_of_lhs_nofilter f c +  |> List.filter (fun p -> wellformed_pred env p >> report_wellformed env c p)++(* API *)+let vars_of_t f ({rhs = r2} as c) =+  (preds_of_reft f r2) ++ (preds_of_lhs f c)+  |> Misc.flap P.support++(**************************************************************)+(********************** Pretty Printing ***********************)+(**************************************************************)++let print_refineatom ppf = function+  | Conc p       -> F.fprintf ppf "%a" P.print p+  | Kvar (su, k) -> F.fprintf ppf "%a%a" Sy.print k Su.print su++(*+(* API *)+let print_ras so ppf = function +  | []  -> F.fprintf ppf "true"+  | ras -> begin match so with +            | None   ->+               F.fprintf ppf "%a" (Misc.pprint_many_box false "" "; " "" print_refineatom) ras +             | Some s -> let ps = Misc.flap (preds_of_refa s) ras in+                         (match ps with +                         | [] -> F.fprintf ppf "[]" +                         | _  -> F.fprintf ppf "%a" P.print (A.pAnd ps))+           end+*)++(* API *)+let print_ras so ppf ras = match so with+  | None  -> +      Misc.pprint_many_box false "[" "; " "]" print_refineatom ppf ras+  | Some s -> +      begin match Misc.flap (preds_of_refa s) ras with +            | [] -> F.fprintf ppf "[]"+            | ps -> F.fprintf ppf "[%a]" P.print (A.pAnd ps)+      end+++(* API *)+let print_reft_pred so ppf (v,t,ras) =+  F.fprintf ppf "@[{%a:%a | %a}@]"+    Sy.print v +    Ast.Sort.print t+    (print_ras so) ras++(*+let print_reft_pred so ppf = function+  | (v,_,[])  -> F.fprintf ppf "@[{%a | true }@]" Sy.print v+  | (v,_,ras) -> F.fprintf ppf "@[{%a | @[%a@]}@]" Sy.print v (print_ras so) ras+*)++(* API *)+let print_reft so ppf (v, t, ras) =+  F.fprintf ppf "@[{%a : %a | %a}@]" +    Sy.print v +    Ast.Sort.print t+    (print_ras so) ras++(* API *)+let print_binding so ppf (x, r) = +  F.fprintf ppf "@[%a:%a@]" Sy.print x (print_reft so) r ++(* API *)+let print_env so ppf env = +  bindings_of_env env +  |> F.fprintf ppf "@[%a@]" (Misc.pprint_many_brackets true (print_binding so))+++let pprint_id ppf = function+  | Some id     -> F.fprintf ppf "id %d" id+  | None        -> F.fprintf ppf ""+++let string_of_intlist = (String.concat ";") <.> (List.map string_of_int)++(* API *)+let print_tag ppf = function+  | [],_ -> F.fprintf ppf ""+  | is,s -> F.fprintf ppf "tag [%s] //%s" (string_of_intlist is) s ++(* API *)+let print_dep ppf = function+  | Adp ((t,_), (t',_)) +    -> F.fprintf ppf "add_dep: [%s] => [%s]" (string_of_intlist t) (string_of_intlist t')+  | Ddp ((t,_), (t',_)) +    -> F.fprintf ppf "del_dep: [%s] => [%s]" (string_of_intlist t) (string_of_intlist t')+  | Ddp_s (t,_)    +    -> F.fprintf ppf "del_dep: [%s] => *" (string_of_intlist t) +  | Ddp_t (t',_)    +    -> F.fprintf ppf "del_dep: * => [%s]" (string_of_intlist t')++(* API *)+let print_wf so ppf (env, r, io, _) =+  F.fprintf ppf "wf: env @[%a@] @\n reft %a @\n %a @\n"+    (print_env so) env+    (print_reft so) r+    pprint_id io++let print_t so ppf c =+  let env, g = if !Co.print_nontriv then c.nontriv, c.iguard else c.full, c.guard in +  F.fprintf ppf +  "constraint:@. env  @[%a@] @\n grd @[%a@] @\n lhs @[%a@] @\n rhs @[%a@] @\n %a %a @\n"+    (print_env so) env +    P.print g+    (print_reft so) c.lhs +    (print_reft so) c.rhs+    pprint_id c.ido+    print_tag c.tag ++(* API *)+let to_string         = Misc.fsprintf (print_t None)+let refa_to_string    = Misc.fsprintf print_refineatom +let reft_to_string    = Misc.fsprintf (print_reft None)+let binding_to_string = Misc.fsprintf (print_binding None) +++ +(***************************************************************)+(*********************** Getter/Setter *************************)+(***************************************************************)++let theta_ra (su': Su.t) = function+  | Conc p       -> Conc (A.substs_pred p su')+  | Kvar (su, k) -> Kvar (Su.compose su su', k) +++(* API *)+let make_reft     = fun v so ras -> (v, so, List.map (theta_ra Su.empty) (canon_ras ras))++let vv_of_reft    = fst3+let sort_of_reft  = snd3+let ras_of_reft   = thd3+let shape_of_reft = fun (v, so, _) -> (v, so, [])+let theta         = fun subs (v, so, ras) -> (v, so, Misc.map (theta_ra subs) ras)+++(* API *)+let env_of_t    = fun t -> t.full +let grd_of_t    = fun t -> t.guard +let lhs_of_t    = fun t -> t.lhs +let rhs_of_t    = fun t -> t.rhs+let tag_of_t    = fun t -> t.tag+let ido_of_t    = fun t -> t.ido+let id_of_t     = fun t -> match t.ido with Some i -> i | _ -> assertf "C.id_of_t"+let is_tauto    = rhs_of_t <+> ras_of_reft <+> List.for_all is_tauto_refatom+let make_t      = fun env p r1 r2 io is ->+                    let p        = A.simplify_pred p in+                    let ne, ps   = non_trivial env   in+                    { full    = env +                    ; nontriv = ne+                    ; guard   = p+                    ; iguard  = A.pAnd (p::ps) +                    ; lhs     = r1 +                    ; rhs     = r2+                    ; ido     = io+                    ; tag     = is }++let vv_of_t     = fun t -> fst3 t.lhs+let sort_of_t   = fun t -> snd3 t.lhs+let senv_of_t   = fun t -> SM.map snd3 t.full+                        |> SM.add (vv_of_t t) (sort_of_t t) ++(*+let make_t      = fun env p ((v,t,ras1) as r1) r2 io is ->+                    let p        = A.simplify_pred p in+                    let po, kras = split_ras ras1    in+                    let ne, ps   = non_trivial env   in+                    let gps      = match po with Some p' -> p' :: p :: ps | _ -> p :: ps in+                    { full    = env +                    ; nontriv = ne+                    ; guard   = p+                    ; iguard  = A.pAnd gps +                    ; lhs     = (v, t, kras) +                    ; rhs     = r2+                    ; ido     = io+                    ; tag     = is }+*)++let reft_of_sort so = make_reft (Sy.value_variable so) so []++let add_consts_env consts env =+  consts+  |> List.map (Misc.app_snd reft_of_sort)+  |> List.fold_left (fun env (x,r) -> SM.add x r env) env++(* API *)+let add_consts_wf consts (env,x,y,z) = (add_consts_env consts env, x, y, z)++(* API *)+let add_consts_t consts t = {t with full = add_consts_env consts t.full}++(* API *)+let make_wf          = fun env r io -> (env, r, io, fun _ -> true)+let make_filtered_wf = fun env r io fltr -> (env, r, io, fltr)+let env_of_wf        = fst4+let reft_of_wf       = snd4+let id_of_wf         = function (_,_,Some i,_) -> i | _ -> assertf "C.id_of_wf"+let filter_of_wf     = fth4+  +let intersect_maps m1 m2 = SM.filter begin fun k elt ->+  SM.mem k m2 && SM.find k m2 = elt+end m1+  +let intersect_wfs (e1, r1, id1, qf1) (e2, r2, id2, qf2) =+  let _ = assert (r1 = r2) in+  let env = intersect_maps e1 e2 in+  (env, r1, id1, fun x -> (qf1 x && qf2 x))+    +let reduce_wfs wfs = +  wfs +  |> Misc.groupby reft_of_wf +  |>: (fun wfs -> List.fold_left intersect_wfs (List.hd wfs) (List.tl wfs))+++(* API *)+let matches_deps ds = +  let tt   = H.create 37 in+  let s_tt = H.create 37 in+  let t_tt = H.create 37 in+  List.iter begin function  +    | Adp (t, t') +    | Ddp (t, t') -> H.add tt (t,t') ()+    | Ddp_s t     -> H.add s_tt t  ()+    | Ddp_t t'    -> H.add t_tt t' ()+  end ds;+  (fun (t, t') -> H.mem tt (t, t') || H.mem s_tt t || H.mem t_tt t')++(* API *)+let pol_of_dep = function Adp (_,_) -> true | _ -> false++(* API *)+let tags_of_dep = function +  | Adp (t, t') | Ddp (t, t') -> t,t' +  | _ -> assertf "tags_of_dep"++(* API *)+let make_dep b xo yo =+  match (b, xo, yo) with+  | true , Some t, Some t' -> Adp (t, t')+  | false, Some t, Some t' -> Ddp (t, t')+  | false, Some t, None    -> Ddp_s t+  | false, None  , Some t' -> Ddp_t t'+  | _                      -> assertf "FixConstraint.make_dep: match failure"++(* API *)+let preds_kvars_of_reft reft =+  List.fold_left begin fun (ps, ks) -> function +    | Conc p -> p :: ps, ks+    | Kvar (xes, kvar) -> ps, (xes, kvar) :: ks +  end ([], []) (ras_of_reft reft)+++(***************************************************************)+(************* Add Distinct Ids to Constraints *****************)+(***************************************************************)++let max_id n cs =+  cs |> Misc.map_partial ido_of_t +     >> (fun ids -> asserts (Misc.distinct ids) "Duplicate Ids")+     |> List.fold_left max n++let max_wf_id n ws =+  ws |> Misc.map_partial (fun (_,_,ido,_) -> ido) +     >> (fun ids -> asserts (Misc.distinct ids) "Duplicate WF Ids")+     |> List.fold_left max n++(* API *)+let add_wf_ids ws = +  Misc.mapfold begin fun j wf -> match wf with+    | (x,y,None,z) -> j+1, (x, y, Some j, z) +    | _            -> j, wf+  end ((max_wf_id 0 ws) + 1) ws+  |> snd+    +(* API *)+let add_ids n cs =+  Misc.mapfold begin fun j c -> match c with+    | {ido = None} -> j+1, {c with ido = Some j}+    | c            -> j, c+  end ((max_id n cs) + 1) cs
+ external/fixpoint/fixConstraint.mli view
@@ -0,0 +1,140 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++(* This module implements basic datatypes and operations on constraints *)+++type t                  (* NEVER EVER expose! *) +type wf                 (* NEVER EVER expose! *)+type dep                (* NEVER EVER expose! dependencies between constraints *)++type tag  = int list * string (* for ordering: must have same dim, lexico-ordered *)+type id   = int         (* for identifying: must be unique *) ++exception BadConstraint of (id * tag * string)++type soln = Ast.Symbol.t -> Ast.pred list+type refa = Conc of Ast.pred | Kvar of Ast.Subst.t * Ast.Symbol.t+type reft = Ast.Symbol.t * Ast.Sort.t * refa list   (* { VV: t | [ra] } *)+type envt = reft Ast.Symbol.SMap.t++val fresh_kvar       : unit -> Ast.Symbol.t+val kvars_of_reft    : reft -> (Ast.Subst.t * Ast.Symbol.t) list+val kvars_of_t       : t -> (Ast.Subst.t * Ast.Symbol.t) list++val is_conc_refa     : refa -> bool+val is_conc_rhs      : t -> bool++val empty_solution   : soln+val meet_solution    : soln -> soln -> soln+val apply_solution   : soln -> reft -> reft++val wellformed_pred  : envt -> Ast.pred -> bool+val preds_of_refa    : soln -> refa -> Ast.pred list+val preds_of_reft    : soln -> reft -> Ast.pred list+val preds_of_lhs     : soln -> t -> Ast.pred list+val preds_of_lhs_nofilter : soln -> t -> Ast.pred list++val vars_of_t        : soln -> t -> Ast.Symbol.t list+val is_tauto         : t -> bool++val preds_kvars_of_reft     : reft -> (Ast.pred list * (Ast.Subst.t * Ast.Symbol.t) list)+val env_of_bindings         : (Ast.Symbol.t * reft) list -> envt+val env_of_ordered_bindings : (Ast.Symbol.t * reft) list -> envt++(* TODO: Deprecate *)+val bindings_of_env  : envt -> (Ast.Symbol.t * reft) list++val kbindings_of_lhs : t -> (Ast.Symbol.t * reft) list++val is_simple        : t -> bool+val map_env          : (Ast.Symbol.t -> reft -> reft) -> envt -> envt +val lookup_env       : envt -> Ast.Symbol.t -> reft option++(* to print a constraint "c" do:+   Format.printf "%a" (print_t None) c++   to print an env "env" do:+   Format.printf "%a" (print_env None) c++   to print a wf constraint wf do:+   Format.printf "%a" (print_wf None) wf++   to convert a constraint c to a string do:+   to_string c++   to print a list of constraints cs do: +   Format.printf "%a" (FixMisc.pprint_many true "\n" (C.print_t None)) cs+   *)++val print_env        : soln option -> Format.formatter -> envt -> unit+val print_wf         : soln option -> Format.formatter -> wf -> unit+val print_t          : soln option -> Format.formatter -> t -> unit+val print_ras        : soln option -> Format.formatter -> refa list -> unit+val print_reft       : soln option -> Format.formatter -> reft -> unit+val print_reft_pred  : soln option -> Format.formatter -> reft -> unit+val print_binding    : soln option -> Format.formatter -> (Ast.Symbol.t * reft) -> unit+val print_tag        : Format.formatter -> tag -> unit+val print_dep        : Format.formatter -> dep -> unit++val to_string        : t -> string +val refa_to_string   : refa -> string+val reft_to_string   : reft -> string+val binding_to_string: (Ast.Symbol.t * reft) -> string++val make_reft        : Ast.Symbol.t -> Ast.Sort.t -> refa list -> reft+val vv_of_reft       : reft -> Ast.Symbol.t+val sort_of_reft     : reft -> Ast.Sort.t+val ras_of_reft      : reft -> refa list+val shape_of_reft    : reft -> reft+val theta            : Ast.Subst.t -> reft -> reft++val add_consts_wf    : (Ast.Symbol.t * Ast.Sort.t) list -> wf -> wf+val add_consts_t     : (Ast.Symbol.t * Ast.Sort.t) list -> t -> t+val make_t           : envt -> Ast.pred -> reft -> reft -> id option -> tag -> t++val sort_of_t        : t -> Ast.Sort.t+val vv_of_t          : t -> Ast.Symbol.t+val senv_of_t        : t -> Ast.Sort.t Ast.Symbol.SMap.t+val env_of_t         : t -> envt+val grd_of_t         : t -> Ast.pred+val lhs_of_t         : t -> reft+val rhs_of_t         : t -> reft+val id_of_t          : t -> id+val ido_of_t         : t -> id option+val tag_of_t         : t -> tag+val add_ids          : id -> t list -> id * t list+val add_wf_ids       : wf list -> wf list+val make_wf          : envt -> reft -> id option -> wf+val make_filtered_wf : envt -> reft -> id option -> (Qualifier.t -> bool) -> wf+val env_of_wf        : wf -> envt+val reft_of_wf       : wf -> reft+val id_of_wf         : wf -> id +val filter_of_wf     : wf -> (Qualifier.t -> bool)+  +val reduce_wfs       : wf list -> wf list++val make_dep         : bool -> tag option -> tag option -> dep+val matches_deps     : dep list -> tag * tag -> bool+val tags_of_dep      : dep -> tag * tag+val pol_of_dep       : dep -> bool 
+ external/fixpoint/fixLex.mll view
@@ -0,0 +1,151 @@+(*+ * Copyright © 1990-2002 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 + * d + * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.+ *+ *)++{+  module Misc = FixMisc+  +  open Misc.Ops+  module E = Errorline+  open E+  open FixParse ++  let lexerror msg lexbuf = +    E.error (Lexing.lexeme_start lexbuf) msg+ +  (* +  let int_of_lexbuf lb = +    let str = Lexing.lexeme lb in+    let len = String.length str in+    let zero = Char.code '0' in+    let rec accum a d =+      let acc c = a + (d * ((Char.code c) - zero)) in+      function 0 -> let c = str.[0] in+			  	    if c='-' then - a else (acc c)+		     | i -> accum (acc str.[i]) (d * 10) (i - 1)+    in accum 0 1 (len-1) +   *)++  let safe_int_of_string s = +    try int_of_string s with ex -> +      let _ = Printf.printf "safe_int_of_string crashes on: %s (error = %s)" s (Printexc.to_string ex) in+      raise ex+}++let digit    = ['0'-'9' '-']+let letdig   = ['0'-'9' 'a'-'z' 'A'-'Z' '_' '@' ''' '.' '#']+let alphlet  = ['A'-'Z' 'a'-'z' '~' '_' ''' '@' ]+let capital  = ['A'-'Z']+let small    = ['a'-'z' '$' '_']+let ws       = [' ' '\009' '\012']+let pathname = ['a'-'z' 'A'-'Z' '0'-'9' '.' '/' '\\' '-']++rule token = parse+    ['\r''\t'' ']       { token lexbuf}+  | '\n'		        { begin+			                E.startNewline (Lexing.lexeme_end lexbuf);+			                token lexbuf +			              end }+  | "//"[^'\n']*'\n'+                        { begin+                          E.startNewline (Lexing.lexeme_end lexbuf);+			              token lexbuf+                          end +                        }+  | '['                 { LB }+  | ']'                 { RB }+  | '('			        { LPAREN }+  | ')'			        { RPAREN }+  | '{'			        { LC }+  | '}'			        { RC }+  | '~'                 { NOT }+  | ';'                 { SEMI }+  | ','                 { COMMA }+  | ':'                 { COLON }+  | '|'                 { MID }+  | '+'                 { PLUS }+  | '-'                 { MINUS }+  | '*'                 { TIMES }+  | '/'                 { DIV }+  | '?'                 { QM }+  | '.'                 { DOT }+  | "not"               { NOTWORD }+  | "tag"               { TAG }+  | "id"                { ID }+  | "Bexp"              { BEXP }+  | "false"             { FALSE }+  | "true"              { TRUE }+  | ":="                { ASGN }+  | "&&"                { AND }+  | "||"                { OR  }+  | "<=>"               { IFF }+  | "iff"               { IFFWORD }+  | "=>"                { IMPL }+  | "!="		        { NE }+  | "="		            { EQ }+  | "<="		        { LE }+  | "<"		            { LT }+  | ">="		        { GE }+  | ">"		            { GT }+  | "mod"               { MOD }+  | "obj"               { OBJ }+  | "num"               { NUM }+  | "int"               { INT }+  | "ptr"               { PTR }+  | "<fun>"             { LFUN }+  (* | "fptr"           { FPTR } *)+  | "bool"              { BOOL }+  | "uit"               { UNINT }+  | "func"              { FUNC }+  | "sort"              { SRT }+  | "axiom"             { AXM }+  | "constant"          { CON }+  | "constraint"        { CST }+  | "wf"                { WF }+  | "solution"          { SOL }+  | "qualif"            { QUL }+  | "cut"               { KUT }+  | "bind"              { BIND }+  | "add_dep"           { ADP }+  | "del_dep"           { DDP }+  | "env"               { ENV }+  | "grd"               { GRD }+  | "lhs"               { LHS }+  | "rhs"               { RHS }+  | "reft"              { REF }+  | "@"                 { TVAR } +  | (digit)+	        { Num (safe_int_of_string (Lexing.lexeme lexbuf)) }+  | (alphlet)letdig*	{ Id    (Lexing.lexeme lexbuf) }+  | '''[^''']*'''       { let str = Lexing.lexeme lexbuf in+			              let len = String.length str in+			              Id (String.sub str 1 (len-2)) +                        }+  +  | eof			{ EOF }+  | _			{ +                          begin+                            lexerror ("Illegal Character '" ^ +                                      (Lexing.lexeme lexbuf) ^ "'") lexbuf;+			    token lexbuf+			  end }+
+ external/fixpoint/fixParse.mly view
@@ -0,0 +1,420 @@++%{+module A  = Ast+module So = A.Sort+module Sy = A.Symbol+module E  = A.Expression+module P  = A.Predicate+module H  = A.Horn+module Su = A.Subst+module C  = FixConstraint+module Co = Constants+open FixMisc.Ops++(* + *+  %token <string> Tycon+  | (capital)letdig*    { Tycon (Lexing.lexeme lexbuf) }          +  | Tycon                               { So.t_app (So.tycon $1) [] }+  | Tycon tyconargsne                   { So.t_app (So.tycon $1) $2 }+   *)+  (*  | Id                                  { So.t_ptr (So.Loc $1) }++(*+pExprs:+    LPAREN RPAREN                       { []   }+  | LPAREN expr RPAREN                  { [$2] }+  | LPAREN exprsCommaNe RPAREN          { $2   }+  ;++exprsCommaNe:+    expr                                { [$1] }+  | expr COMMA exprsCommaNe             { $1 :: $3 }+  ; +  *)++*)+let parse_error msg =+  Errorline.error (symbol_start ()) msg++let create_qual name vv = Qualifier.create (Sy.of_string name) (Sy.of_string vv) ++let set_ibind, get_ibind =+  let bindt = Hashtbl.create 37 in+  ( (fun (i, x, t) -> Hashtbl.replace bindt i (x, t))+  , (fun i         -> try Hashtbl.find bindt i with Not_found -> assertf "Unknown binding: %d\n" i) +  )++let env_of_ibindings is = +  is |> FixMisc.sort_and_compact +     |> FixMisc.map get_ibind+     |> C.env_of_ordered_bindings++%}++%token <string> Id+%token <int> Num+%token TVAR +%token TAG ID +%token BEXP+%token TRUE FALSE+%token LPAREN  RPAREN LB RB LC RC+%token EQ NE GT GE LT LE+%token AND OR NOT NOTWORD IMPL IFF IFFWORD FORALL SEMI COMMA COLON MID+%token EOF+%token MOD +%token PLUS+%token MINUS+%token TIMES +%token DIV +%token QM DOT ASGN+%token OBJ INT NUM PTR LFUN BOOL UNINT FUNC+%token SRT AXM CON CST WF SOL QUL KUT BIND ADP DDP+%token ENV GRD LHS RHS REF++%right IFF IFFWORD+%right IMPL+%left PLUS+%left MINUS+%left DIV+%left TIMES+%left DOT+%right NOT++%start defs +%start sols+%start reft ++%type <FixConfig.deft list>     defs+%type <FixConfig.deft>          def+%type <FixConfig.solbind list>  sols+%type <So.t list>               sorts, sortsne +%type <So.t>                    sort+%type <(Sy.t * So.t) list>      binds, bindsne +%type <A.pred list>             preds, predsne+%type <A.pred>                  pred+%type <A.expr list>             exprs, exprsne+%type <A.expr>                  expr+%type <C.t>                     cstr+%type <C.envt>                  env+%type <FixConstraint.reft>      reft+%type <C.refa list>             refas, refasne+%type <C.refa>                  refa+%type <Su.t>                    subs++%%+defs:+                                        { [] } +  | def defs                            { $1 :: $2 }+  ;++++qual:+    Id LPAREN Id COLON sort RPAREN COLON pred            { create_qual $1 $3 $5 [] $8 }+  | Id LPAREN Id RPAREN COLON pred                       { create_qual $1 $3 So.t_int [] $6 }+  | Id LPAREN Id COLON sort qbindsne RPAREN COLON pred   { create_qual $1 $3 $5 $6 $9 }+  ;++qbindsne:+    COMMA bind                          { [$2] }+  | COMMA bind qbindsne                 { $2 :: $3 }+  ;++def:+    SRT COLON sort                      { FixConfig.Srt $3 }+  | AXM COLON pred                      { FixConfig.Axm $3 }+  | CST COLON cstr                      { FixConfig.Cst $3 }+  | CON Id COLON sort                   { FixConfig.Con (Sy.of_string $2, $4) }+  | WF  COLON wf                        { FixConfig.Wfc $3 }+  | sol                                 { FixConfig.Sol $1 } +  | QUL qual                            { FixConfig.Qul $2 }+  | KUT Id                              { FixConfig.Kut (Sy.of_string $2) }+  | dep                                 { FixConfig.Dep $1 }+  | BIND Num Id COLON reft              { let (i, x, r) = ($2, Sy.of_string $3, $5) +                                                          >> set_ibind +                                          in FixConfig.IBind (i,x,r)              } +  ;+++sorts:+    LB RB                               { [] }+  | LB sortsne RB                       { $2 }+  ;++sortsne:+    sort                                { [$1] }+  | sort SEMI sortsne                   { $1 :: $3 }+  ;++tyconargsne: +  | bsort                               { [$1] }+  | bsort tyconargsne                   { $1 :: $2 }+  ;++sort:+  | bsort                               { $1 }+  | Id tyconargsne                      { So.t_app (So.tycon $1) $2 }+  | LB sort RB                          { So.t_app (So.tycon "List") [$2] }+ +  ;++bsort:+  | INT                                 { So.t_int }+  | BOOL                                { So.t_bool }+  | PTR                                 { So.t_ptr (So.Lvar 0) }+  | PTR LPAREN LFUN RPAREN              { So.t_ptr (So.LFun) }+  | PTR LPAREN Num RPAREN               { So.t_ptr (So.Lvar $3) }+  | PTR LPAREN Id RPAREN                { So.t_ptr (So.Loc $3) }+  | OBJ                                 { So.t_obj } +  | NUM                                 { So.t_num } +  | TVAR LPAREN Num RPAREN              { So.t_generic $3 }+  | FUNC LPAREN sorts RPAREN            { So.t_func 0 $3  }+  | FUNC LPAREN Num COMMA sorts RPAREN  { So.t_func $3 $5 }+  | Id                                  { let s = $1 in +                                          if !Co.gen_qual_sorts || FixMisc.stringIsLower s then +                                            So.t_ptr (So.Loc s)       (* tyvar *) +                                          else +                                            So.t_app (So.tycon s) []  (* tycon *) +                                        }+  | LPAREN sort RPAREN                  { $2 }+  ; +++binds:+    LB RB                               { [] }+  | LB bindsne RB                       { $2 }+  ;++bindsne:+    bind                                { [$1] }+  | bind SEMI bindsne                   { $1::$3 }+  ;+++bind:+  Id COLON sort                         { ((Sy.of_string $1), $3) }+  ;++rels:+    LB RB                               { [] }+  | LB relsne RB                        { $2 }+  ;++relsne: +    rel                                 { [$1]}+  | rel SEMI relsne                     { $1 :: $3}+  ;++rel:+   EQ                                   { A.Eq }+ | NE                                   { A.Ne }    + | GT                                   { A.Gt }+ | GE                                   { A.Ge }+ | LT                                   { A.Lt }+ | LE                                   { A.Le }+ ;+++preds:+    LB RB                               { [] }+  | LB predsne RB                       { $2 }+  ;++predsne:+    pred                                { [$1] }+  | pred SEMI predsne                   { $1 :: $3 }+;++pred:+    TRUE				                { A.pTrue }+  | FALSE				                { A.pFalse }+  | BEXP expr                           { A.pBexp $2 }+  | QM expr                             { A.pBexp $2 }+  | Id LPAREN argsne RPAREN             { A.pBexp (A.eApp ((Sy.of_string $1), $3)) }+  | AND preds   			            { A.pAnd ($2) }+  | OR  preds 	        		        { A.pOr  ($2) }+  | NOT pred				            { A.pNot ($2) }+  | NOTWORD pred				        { A.pNot ($2) }+  | LPAREN pred AND pred RPAREN         { A.pAnd [$2; $4] }+  | LPAREN pred OR  pred RPAREN         { A.pOr  [$2; $4] }+  | expr rel expr                       { A.pAtom  ($1, $2, $3) }+  | expr rels expr                      { A.pMAtom ($1, $2, $3) }+  | FORALL binds DOT pred               { A.pForall ($2, $4) }+  | pred IMPL pred                      { A.pImp ($1, $3) }+  | pred IFF pred                       { A.pIff ($1, $3) }+  | pred IFFWORD pred                   { A.pIff ($1, $3) }+  | LPAREN pred RPAREN			        { $2 }+  ;++argsne:+    expr                                { [$1] } +  | expr COMMA argsne                   { $1::$3 }+  ;++++exprs:+    LB RB                               { [] }+  | LB exprsne RB                       { $2 }+  ;++exprsne:+    expr                                { [$1] }+  | expr SEMI exprsne                   { $1 :: $3 }+  ;++expr:+    Id                                    { A.eVar (Sy.of_string $1) }+  | con                                   { A.eCon $1  }+  | exprs                                 { A.eMExp $1 } +  | LPAREN expr MOD Num RPAREN            { A.eMod ($2, $4) }+  | expr PLUS expr                        { A.eBin ($1, A.Plus, $3) }+  | expr MINUS expr                       { A.eBin ($1, A.Minus, $3) }+  | expr TIMES expr                       { A.eBin ($1, A.Times, $3) }+  | expr DIV expr                         { A.eBin ($1, A.Div, $3) }+  | expr ops expr                         { A.eMBin ($1, $2, $3) }+  | Id LPAREN exprs RPAREN                { A.eApp ((Sy.of_string $1), $3) }+  | Id Id                                 { A.eApp ((Sy.of_string $1), [A.eVar (Sy.of_string $2)]) }+  | LPAREN pred QM expr COLON expr RPAREN { A.eIte ($2,$4,$6) }+  | expr DOT Id                           { A.eFld ((Sy.of_string $3), $1) }+  | LPAREN expr COLON sort RPAREN         { A.eCst ($2, $4) }+  | LPAREN expr RPAREN                    { $2 }+  ;++op:+  | PLUS                                  { A.Plus  }+  | MINUS                                 { A.Minus }+  | TIMES                                 { A.Times }+  | DIV                                   { A.Div   }+  ; ++ops:+    LB RB                                 { [] }+  | LB opsne RB                           { $2 }+  ; ++opsne:+    op                                    { [$1] }+  | op SEMI opsne                         { $1 :: $3 }+  ;++++con:+  | Num                                   { (A.Constant.Int $1) }+  | MINUS Num                             { (A.Constant.Int (-1 * $2)) }+  ;++cons:+    LB RB                                 { [] }+  | LB consne RB                          { $2 }+  ;++consne:+    con                                   { [$1] }+  | con SEMI consne                       { $1 :: $3 }+  ;++wf:+    ENV env REF reft                              { C.make_wf $2 $4 None }+  | ENV env REF reft ID Num                       { C.make_wf $2 $4 (Some $6) }+  ;++tagsne:+  Num                                             { [$1] }+  | Num SEMI tagsne                               { $1 :: $3 }+  ;++tag: +  | LB tagsne RB                                  { ($2, "") }+  ;++dep:+  | ADP COLON tag IMPL tag                     {C.make_dep true (Some $3) (Some $5) }+  | DDP COLON tag IMPL tag                     {C.make_dep false (Some $3) (Some $5) }+  | DDP COLON TIMES IMPL tag                   {C.make_dep false None (Some $5) }+  | DDP COLON tag IMPL TIMES                   {C.make_dep false (Some $3) None }+  ;++info:+  ID Num                                        { ((Some $2), ([],"")) }+  | TAG tag                                     { (None     , $2)} +  | ID Num TAG tag                              { ((Some $2), $4) }+  ;++cstr:+  | ENV env GRD pred LHS reft RHS reft          { C.make_t $2 $4 $6 $8 None ([],"") }+  | ENV env GRD pred LHS reft RHS reft info     { C.make_t $2 $4 $6 $8 (fst $9) (snd $9)}+  ;++env:+    LB RB                               { C.env_of_bindings [] }+  | LB envne RB                         { C.env_of_bindings $2 }+  | LB ienvne RB                        { env_of_ibindings $2  }+  ;++ienvne:+    Num                                 { [$1] }+  | Num SEMI ienvne                     { $1 :: $3 }+  ;++envne:+    rbind                               { [$1] }+  | rbind SEMI envne                    { $1 :: $3 }+  ;+++rbind: +  Id COLON reft                         { (Sy.of_string $1, $3) }+  ;++ibind:+  Num Id COLON reft                     { ($1, Sy.of_string $2, $4) }    +  ;++reft: +  LC Id COLON sort MID refas RC         { ((Sy.of_string $2), $4, $6) }+  ;++refas:+    LB RB                               { [] }+  | LB refasne RB                       { $2 }+  ;++refasne:+    refa                                { [$1] }+  | refa SEMI refasne                   { $1 :: $3 }+  ;+  +refa:+    Id subs                             { C.Kvar ($2, (Sy.of_string $1)) }+  | pred                                { C.Conc $1 }+  ;++subs:+                                        { Su.empty }+  | LB Id ASGN expr RB subs             { Su.extend $6 ((Sy.of_string $2), $4) } +  ;++npred: +  LPAREN pred COMMA Id LPAREN argsne RPAREN RPAREN      { ((* $2, *) (Sy.of_string $4, $6)) }+  ;++npreds:+    LB RB                                { [] }+  | LB npredsne RB                       { $2 }+  ;++npredsne:+    npred                                { [$1] }+  | npred SEMI npredsne                  { $1 :: $3 }+;++sol:+    SOL COLON Id ASGN npreds            { ((Sy.of_string $3), $5) }++sols:+             { [] }+  | sol sols { $1 :: $2 }+
+ external/fixpoint/fixSimplify.ml view
@@ -0,0 +1,455 @@+(*+ * 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 BS = BNstats+module Co = Constants+module C  = FixConstraint+module P  = Ast.Predicate+module E  = Ast.Expression+module Sy = Ast.Symbol+module Kg = Kvgraph+module Su = Ast.Subst+module SM = Ast.Symbol.SMap+module SS = Ast.Symbol.SSet++module Misc = FixMisc +module IM = Misc.IntMap+open Misc.Ops+open Ast++let mydebug = false+++(****************************************************************************)+(*********************************** Misc. **********************************)+(****************************************************************************)++let add_cm     = List.fold_left (fun cm c -> IM.add (C.id_of_t c) c cm) +let find_cm    = fun cm id -> IM.find id cm+let refas_of_k = fun k -> [C.Kvar (Su.empty, k)] ++(****************************************************************************)+(************** Generic Simplification/Transformation API *******************)+(****************************************************************************)++module type SIMPLIFIER = sig+  val simplify_ts: FixConstraint.t list -> FixConstraint.t list+end++(****************************************************************************)+(******************* Syntactic Simplification *******************************)+(****************************************************************************)++module Syntactic : SIMPLIFIER = struct++let defs_of_pred = +  let rec dofp (em, pm) p = match p with+    | Atom ((Var v, _), Eq, e), _ +      when not (P.is_tauto p) -> +        Sy.SMap.add v e em, pm+    | And [Imp ((Bexp (Var v1, _), _), p1), _; +           Imp (p2, (Bexp (Var v2, _), _)), _], _ +      when v1 = v2 && p1 = p2 && not(P.is_tauto p) -> +        em, Sy.SMap.add v1 p1 pm+    | And ps, _ -> +        List.fold_left dofp (em, pm) ps+    | _ -> em, pm+  in dofp (Sy.SMap.empty, Sy.SMap.empty)++let rec expr_apply_defs em pm expr = +  let ef = expr_apply_defs em pm in+  let pf = pred_apply_defs em pm in+  match expr with +  | Var v, _ when Sy.SMap.mem v em ->+      Sy.SMap.find v em, true+  | Var _, _ | Con _, _ | Bot, _ ->+      expr, false+  | App (v, es), _ -> +      let _  = asserts (not (Sy.SMap.mem v em)) "binding for UF" in+      es |> List.map ef +         |> List.split +         |> (fun (es', bs') -> (eApp (v, es'), List.fold_left (||) false bs'))+  | Bin (e1, op, e2), _ -> +      let e1', b1' = ef e1 in+      let e2', b2' = ef e2 in+      eBin (e1', op, e2'), (b1' || b2')+  | Ite (p, e1, e2), _ -> +      let p', b'   = pf p in+      let e1', b1' = ef e1 in+      let e2', b2' = ef e2 in+      eIte (p', e1', e2'), (b' || b1' || b2')+  | Fld (v, e), _ -> +      let e', b'   = ef e in+      eFld (v, e'), b'+  | Cst (e, t), _ ->+      let e', b'   = ef e in+      eCst (e', t), b'+  | _ -> failwith "Pattern: expr_apply_defs"++and pred_apply_defs em pm pred =+  let ef = expr_apply_defs em pm in+  let pf = pred_apply_defs em pm in+  match pred with +  | And ps, _ -> +      ps |> List.map pf+         |> List.split+         |> (fun (ps', bs') -> pAnd ps', List.exists id bs') +  | Or ps, _ -> +      ps |> List.map pf+         |> List.split+         |> (fun (ps', bs') -> pOr ps', List.exists id bs') +  | Not p, _ ->+       p |> pf +         |> Misc.app_fst pNot+  | Imp (p1, p2), _ -> +      let p1', b1' = pf p1 in+      let p2', b2' = pf p2 in+      pImp (p1', p2'), b1' || b2'+  | Bexp (Var v, _), _ when Sy.SMap.mem v pm ->+      Sy.SMap.find v pm, true+  | Bexp e, _ ->+      e |> ef |> Misc.app_fst pBexp+  | Atom (e1, brel, e2), _ ->+      let e1', b1' = ef e1 in+      let e2', b2' = ef e2 in+      pAtom (e1', brel, e2'), b1' || b2'+  | Forall (qs, p), _ -> +      assertf "Forall in Simplify!"+  | _ ->+      pred, false++(* Why does this fixpointing terminate?+ * close em, pm under substitution so that+   for all x in dom(em), support(em(x)) \cap dom(em) = empty *)++(* Assume: em is well-formed, + * i.e. exists an ordering on vars of dom(em)+ * x1 < x2 < ... < xn s.t. if xj \in em(xi) then xj < xi *)++let expr_apply_defs em fm e = +  e |> Misc.fixpoint (expr_apply_defs em fm) +    |> fst++let pred_apply_defs em fm p = +  p |> Misc.fixpoint (pred_apply_defs em fm) +    |> fst+    |> simplify_pred++let subs_apply_defs em pm xes = List.map (Misc.app_snd (expr_apply_defs em pm)) xes+++let print_em_pm t (em, pm) =+  let id   = t |> C.id_of_t in+  let vv   = t |> C.lhs_of_t |> C.vv_of_reft in+  let vve  = try Sy.SMap.find vv em with Not_found -> bot in+  let vve' = expr_apply_defs em pm vve in+  Co.bprintf mydebug "\nbodyp em map for %d\n" id ;+  Sy.SMap.iter (fun x e -> Co.bprintf mydebug "%a -> %a\n" Sy.print x  E.print e) em;+  Co.bprintf mydebug "\nbodyp pm map for %d\n" id ;+  Sy.SMap.iter (fun x p -> Co.bprintf mydebug "%a -> %a\n" Sy.print x  P.print p) pm;+  Co.bprintf mydebug "edef for vv %a = %a (simplified %a)\n" Sy.print vv E.print vve E.print vve'++let preds_kvars_of_env env =+  Sy.SMap.fold begin fun x r (ps, env) -> +    let vv       = C.vv_of_reft r in+    let xe       = Ast.eVar x in+    let t        = C.sort_of_reft r in+    let rps, rks = C.preds_kvars_of_reft r in+    let ps'      = List.map (fun p -> P.subst p vv xe) rps ++ ps in+    let env'     = (* match rks with [] -> env | _ -> *) Sy.SMap.add x (vv, t, rks) env in+    ps', env'+  end env ([], Sy.SMap.empty)++let simplify_kvar em pm (su, sym) =+  su |> Su.to_list +     |> subs_apply_defs em pm+     |> Su.of_list+     |> (fun su -> C.Kvar (su, sym))++let simplify_env em pm ks_env = +  Sy.SMap.map begin fun (vv, t, ks) -> +    ks |> List.map (simplify_kvar em pm) |> C.make_reft vv t+  end ks_env++let simplify_grd em pm vv t p =+  let _  = Co.bprintf mydebug "simplify_grd [1]: %a \n" P.print p in+  let p  = pred_apply_defs em pm p in+  let _  = Co.bprintf mydebug "simplify_grd [2]: %a \n" P.print p in+  begin try +    Sy.SMap.find vv em +    |> expr_apply_defs em pm+    |> (fun vve -> pAnd [p; pAtom (eVar vv, Eq, vve)])+  with Not_found -> p end+  >> Co.bprintf mydebug "simplify_grd [3]: %a \n" P.print++let simplify_refa em pm = function +  | C.Conc p          -> C.Conc (pred_apply_defs em pm p) +  | C.Kvar (xes, sym) -> simplify_kvar em pm (xes, sym)++(* API *)+let simplify_t c = +  let id             = c |> C.id_of_t in+  let _              = Co.bprintf mydebug "============== Simplifying %d ============== \n"id in+  let env_ps, ks_env = c |> C.env_of_t |> preds_kvars_of_env in+  let l_ps, l_ks     = c |> C.lhs_of_t |> C.preds_kvars_of_reft in+  let vv, t          = c |> C.lhs_of_t |> Misc.tmap2 (C.vv_of_reft, C.sort_of_reft) in+  let bodyp          = Ast.pAnd ([C.grd_of_t c] ++ l_ps ++ env_ps) +                       >> Co.bprintf mydebug "body_pred: %a \n" P.print in+  let em, pm         = defs_of_pred bodyp                          +                       >> print_em_pm c in++  let senv           = simplify_env em pm ks_env in+  let sgrd           = simplify_grd em pm vv t bodyp in+  let slhs           = l_ks |> List.map (simplify_kvar em pm) |> C.make_reft vv t in+  let srhs           = c |> C.rhs_of_t |> C.ras_of_reft |> List.map (simplify_refa em pm) |> C.make_reft vv t in+  +  C.make_t senv sgrd slhs srhs (C.ido_of_t c) (C.tag_of_t c)++(* API *)+let simplify_ts cs = +  cs |> List.map simplify_t+    (* |> List.filter (not <.> C.is_tauto) *) +end++(****************************************************************************)+(*** Cone-of-Influence: Remove Constraints that don't reach constant-pred ***)+(****************************************************************************)++module Cone : SIMPLIFIER = struct+  let simplify_ts cs =+    let cm = add_cm IM.empty cs in +    cs |> Kg.add Kg.empty +       >> Kg.print_stats+       |> Kg.cone_ids +       |> List.map (find_cm cm)+end++(**************************************************************************)+(*** Direct-Dependencies: Remove non-data-dependent binders****************)+(*************************************************************************)++module WeakFixpoint : SIMPLIFIER = struct+ +  let weaken_env c e = +    C.make_t e +      (C.grd_of_t c) (C.lhs_of_t c) (C.rhs_of_t c) +      (C.ido_of_t c) (C.tag_of_t c)++  let support_of_refa = function +    | C.Conc p -> P.support p+    | _        -> []++  let support_of_reft = +    Misc.flap support_of_refa <.> thd3++  let rec data_cone env m n xs = match xs with +    | _::_ -> let m' = List.fold_left (fun m' x -> Sy.SMap.add x n m') m xs in+              xs |> Misc.map_partial (C.lookup_env env) +                 |> Misc.flap support_of_reft+                 |> Misc.filter (fun x -> not (Sy.SMap.mem x m))+                 |> data_cone env m' (n+1)+    | []   -> m+  +  let data_cone c = +    (P.support (C.grd_of_t c)) +    |> (++) (support_of_reft (C.lhs_of_t c))+    |> data_cone (C.env_of_t c) Sy.SMap.empty 0++  let project_cone m x ((v,t,ras) as r) =+    if Sy.SMap.mem x m then r else (v, t, List.filter C.is_conc_refa ras)++  let simplify_t c =+    c |> data_cone |> project_cone |> C.map_env +      |> (fun f -> f (C.env_of_t c))+      |> weaken_env c+      +  let simplify_ts = Misc.map simplify_t+end++(****************************************************************************)+(***** Merge Write and Read of Kvar: A |- k and B, k |- C  iff A,B |- C  ****)+(****************************************************************************)++module EliminateK : SIMPLIFIER = struct+  +  type t = { g  : Kg.t;+             cm : FixConstraint.t IM.t;+             id : int; }++  let print_k ppf k = +    Format.fprintf ppf "%s" (C.refa_to_string k)++  let empty  = +    { g  = Kg.empty; +      cm = IM.empty; +      id = 0; }+ +  let add me cs = +    let n, cs = C.add_ids me.id cs in +    { g  = Kg.add me.g cs; +      cm = add_cm me.cm cs; +      id = n+1 }+ +  let remove me (k, cs) =+    { g  = Kg.remove me.g [k]; +      cm = List.map C.id_of_t cs |> List.fold_left (Misc.flip IM.remove) me.cm;+      id = me.id; }+ +  let of_ts     = add empty +  let to_ts     = fun me -> me.cm |> IM.to_list |> List.map snd+  let cs_of_k   = fun f me k ->  f me.g [k] |> List.map (find_cm me.cm)++  (* Assume that k is written in (1) and read once in (2)+     +     (1) env1, g1, k_v:l1                       |- k[xi := ai]+     (2) env2, g2, y:k[xi := bi]                |- r2+     +     Now, (1) equiv (1') and (2) equiv (2')+     +     (1') env1, g1, #i:{v=ai}, k_v:l1                           |- k[xi := #i]+     (2') env2, g2, #i:{v=bi}, y:k2[xi := #i]                   |- r2+     +     Next, we can merge (1') and (2')+     +     (1'+2') env1 ++ env2, g1 && g2, #i:{v=ai}, #i:{v=bi}, y:l1 |- r2+     +     Which simplifies to:+     +     (1'+2') env1 ++ env2, g1 && g2 && {ai = bi}, y:l1          |- r2+  *)++  let meet_env env1 env2 xrs =+    [env1; env2]+    |> Misc.flap C.bindings_of_env +    |> (++) xrs +    |> C.env_of_bindings++  let meet_sub su1 su2 =+    [su1; su2]+    |> Misc.flap Su.to_list+    |> Misc.groupby fst +    |> List.map (function [(x,e)] -> pEqual (eVar x, e)| [(_,e1);(_,e2)] -> pEqual (e1,e2))+    |> pAnd++  let merge_one me k (wc, rc) =+    let env1, env2       = Misc.map_pair C.env_of_t (wc, rc) in +    let g1, g2           = Misc.map_pair C.grd_of_t (wc, rc) in+    let l1               = C.lhs_of_t wc in+    let [C.Kvar(su1, k)] = C.rhs_of_t wc |> thd3 in+    let su2, yr', l'     = match Kg.k_reads me.g (C.id_of_t rc) (C.Kvar (Su.empty, k)) with +                           | [Kg.Bnd (y, su2)] -> su2, [(y,l1)], (C.lhs_of_t rc)+                           | [Kg.Lhs su2]      -> su2, [], l1 +                           | _ -> assertf "EliminateK.merge_one (k=%s, id=%d)" (Sy.to_string k) (C.id_of_t rc) in+    let env'             = meet_env env1 env2 yr'          in+    let g'               = pAnd [g1; g2; meet_sub su1 su2] in+    let r'               = C.rhs_of_t rc                   in+    C.make_t env' g' l' r' None (C.tag_of_t rc)+    +  let eliminate me (k, wcs, rcs)  =+    me >> (fun _ -> Format.printf "EliminateK.eliminate %s \n" (C.refa_to_string k))  +       |> Misc.flip add    (Misc.cross_product wcs rcs |> List.map (merge_one me k)) +       |> Misc.flip remove (k, wcs ++ rcs)++  let select_ks me = +    me.g +    |> Kg.filter_kvars (Kg.is_single_wr me.g) +    |> List.filter (Kg.is_single_rd me.g)+    |> List.map (fun k -> (k, cs_of_k Kg.writes me k, cs_of_k Kg.reads me k))+    |> List.filter (fun (_,wcs, rcs) -> Misc.disjoint wcs rcs)+    >> (List.map fst3 <+> Format.printf "EliminateK.select_ks [OUT]: %a \n" +                          (Misc.pprint_many false "," print_k))++  let simplify_ts cs =+    let me = of_ts cs in+    me |> select_ks+       |> List.fold_left eliminate me +       |> to_ts +end+++(****************************************************************************)+(***** Copy Propagation *****************************************************)+(****************************************************************************)++module CopyProp : SIMPLIFIER = struct++  let subst_theta = +    List.map <.> Misc.app_snd <.> (fun (x, e) e' -> E.subst e' x e) +  +  let subst_bind su x y ((v, t, ras) as r) =  +    if x = y then (v, t, []) else C.theta su r++  let subst_cstr (x, e) c =+    let su    = Su.of_list [(x, e)]                         in+    let env'  = C.env_of_t c |> C.map_env (subst_bind su x) in+    let grd'  = C.grd_of_t c |> (fun p -> P.subst p x e)    in+    let lhs'  = C.lhs_of_t c |> C.theta su                  in+    let rhs'  = C.rhs_of_t c |> C.theta su                  in+    C.make_t env' grd' lhs' rhs' (C.ido_of_t c) (C.tag_of_t c)+  +  let rec eliminate c = function +      | (x, e) :: theta' when List.mem x (E.support e)+        -> eliminate c theta'+      | xe :: theta' (* x not in e *)+        -> eliminate (subst_cstr xe c) (subst_theta xe theta') +      | []  -> c+ +  let rigid_vars c =+    c |> C.kvars_of_t +      |> List.map fst +      |> Misc.flap Su.to_list +      |> List.map fst +      |> SS.of_list ++  let equalities_of_binding = function +    | (x, (v, _, [C.Conc ( Atom ((Var v', _), Eq, e), _  )])) +      when v = v' -> Some (x, e)+    | (x, (v, _, [C.Conc (  Atom (e, Eq, (Var v', _)), _ )])) +      when v = v' -> Some (x, e)+    | _ -> None++  let equalities_of_t c =+    c |> C.env_of_t +      |> (fun _ -> failwith "CopyProp.equalities_of_t") (* C.bindings_of_env  *)+      |> Misc.map_partial equalities_of_binding++  let simplify_t c = +    let ys = rigid_vars c in+    c |> equalities_of_t +      |> List.filter (fun (x,_) -> not (SS.mem x ys))+      |> eliminate c++  let simplify_ts = Misc.map simplify_t+end++(* API *)+let simplify_ts cs =+  cs +  |> Misc.filter (not <.> C.is_tauto)+  |> ((not !Co.lfp)  <?> BS.time "simplify 0" WeakFixpoint.simplify_ts)+  |> BS.time "add ids  1" (C.add_ids 0) +  |> snd+  (* |> (!Co.copyprop   <?> BS.time "simplify CP" CopyProp.simplify_ts)  *)+  |> (!Co.simplify_t <?> BS.time "simplify 1" Syntactic.simplify_ts) (* termination bug, tickled by C benchmarks *)+  |> (!Co.simplify_t <?> BS.time "simplify 2" Cone.simplify_ts)+  |> (!Co.simplify_t <?> BS.time "simplify 3" EliminateK.simplify_ts)
+ external/fixpoint/fixSimplify.mli view
@@ -0,0 +1,28 @@+(*+ * 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 WeakFixpoint : FixConfig.SIMPLIFIER +include FixConfig.SIMPLIFIER++(* val simplify_ts : FixConstraint.t list -> FixConstraint.t list *)
+ external/fixpoint/fixpoint.ml view
@@ -0,0 +1,148 @@+(*+ * 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.+ *+ *)+++(** read a set of constraints, solve, and dump out the solution *)++module CX  = Counterexample+module BS  = BNstats+module SM  = Ast.Symbol.SMap+module Co  = Constants +module C   = FixConstraint+module F   = Format+module T   = Toplevel+module PA  = PredAbs+module SPA = Solve.Make (PA)+module Cg  = FixConfig++module Misc = FixMisc open Misc.Ops++let mydebug = false++(*****************************************************************)+(********************* Hooking into Solver ***********************)+(*****************************************************************)++let print_raw_cs ppf = function+  | [] -> F.fprintf ppf "SAT \n \n \n"+  | cs -> F.fprintf ppf "UNSAT [%s] \n \n \n" (Misc.map_to_string (C.id_of_t <+> string_of_int) cs)++let save_raw fname cs s = +  Misc.with_out_formatter fname begin fun ppf ->+    F.fprintf ppf "%a \n" print_raw_cs cs; +    F.fprintf ppf "%a \n" PA.print s;+    F.fprintf ppf "@.";+    F.print_flush ()+  end++let save_crash fname (id, tag, msg) =+  Misc.with_out_formatter fname begin fun ppf ->+    F.fprintf ppf "CRASH %d (%s)\n" id msg;+    F.fprintf ppf "//%a\n" C.print_tag tag;+    F.fprintf ppf "@.";+    F.print_flush ()+  end++let solve ac  = +  let _         = Co.bprintflush mydebug "Fixpoint: Creating  CI\n" in+  let ctx, s    = BS.time "create" SPA.create ac None in+  let _         = Co.bprintflush mydebug "Fixpoint: Solving \n" in+  let s, cs',_  = BS.time "solve" (SPA.solve ctx) s in+  +  let _         = Co.bprintflush mydebug "Fixpoint: Saving Result \n" in+  let _         = BS.time "save" (save_raw !Co.out_file cs') s in+  let _         = Co.bprintflush mydebug "Fixpoint: Saving Result DONE \n" in+  cs'++let dump_solve ac = +  try +    let cs' = solve { ac with Cg.bm = SM.map PA.mkbind ac.Cg.bm } in+    let _   = if Co.ck_olev 1 then BNstats.print stdout "Fixpoint Solver Time \n" in+    match cs' with +    | [] -> (F.printf "\nSAT\n" ; exit 0)+    | _  -> (F.printf "\nUNSAT\n" ; exit 1)+  with (C.BadConstraint (id, tag, msg)) -> begin+    Format.printf "Fixpoint: Bad Constraint! id = %d (%s) tag = %a \n" +    id msg C.print_tag tag;+    save_crash !Co.out_file (id, tag, msg); +  end++(*****************************************************************)+(********************* Generate Imp Program **********************)+(*****************************************************************)++let dump_imp a = +  (List.map (fun c -> Cg.Cst c) a.Cg.cs ++ List.map (fun c -> Cg.Wfc c) a.Cg.ws)+  |> ToImp.render F.std_formatter+  |> fun _ -> exit 1 ++(*****************************************************************)+(***************** Generate Simplified Constraints ***************)+(*****************************************************************)++let hook_simplify_ts = function+  | "andrey" -> List.map Simplification.simplify_t+                <+> List.filter (not <.> Simplification.is_tauto_t)+                <+> Simplification.simplify_ts+  | "jhala"  -> FixSimplify.simplify_ts+  (* put other transforms here *)+  | _        -> id++let simplify_ts cs = hook_simplify_ts !Co.dump_simp cs++let dump_simp ac = +  let ac = {ac with Cg.cs = simplify_ts ac.Cg.cs; Cg.bm = SM.empty} in+  Misc.with_out_formatter !Co.save_file (fun ppf -> Cg.print ppf ac)++(*+let dump_simp ac = +  (* let ac    = {ac with Cg.cs = simplify_ts ac.Cg.cs; Cg.bm = SM.empty; Cg.qs = []} in *)+  let ac    = {ac with Cg.cs = simplify_ts ac.Cg.cs; Cg.bm = SM.empty} in+  Misc.with_out_formatter !Co.save_file (fun ppf -> Cg.print ppf ac)++  let ctx,_ = BS.time "create" SPA.create ac None in+  let s0    = PA.empty (* PA.create ac None *) in +  let _     = BS.time "save" (SPA.save !Co.save_file ctx) s0 in+  exit 1+*)++(*****************************************************************)+(*********************** Main ************************************)+(*****************************************************************)++let usage = "Usage: fixpoint.native <options> [source-files]\noptions are:"++let main () =+  let cfg  = usage |> Toplevel.read_inputs |> snd in +  if !Co.dump_imp then +    dump_imp cfg +  else if !Co.dump_smtlib then+    ToSmtLib.dump_smtlib cfg+  else if !Co.dump_simp <> "" then +    dump_simp cfg+  else+    dump_solve cfg ++++let _ = main ()
+ external/fixpoint/fixtop.ml view
@@ -0,0 +1,123 @@+(*+ * 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.+ *+ *)+++(** read a set of constraints, solve, and dump out the solution *)++module SM = Ast.Symbol.SMap+module Co = Constants +module C  = FixConstraint+module F  = Format+(*module Si = Simplification *)+module Misc = FixMisc +open Misc.Ops++let _ = FixLex.token (Lexing.from_string "int");;++let parse_string f = f FixLex.token <.> Lexing.from_string +++let dump cs ws =+  Format.printf "Printing Out Parsed Constraints \n \n \n" ;+  Format.printf "%a" (Misc.pprint_many true "\n" (FixConstraint.print_t None)) cs; +  Format.printf "\n \n";+  Format.printf "%a" (Misc.pprint_many true "\n" (FixConstraint.print_wf None)) ws;+  Format.printf "\n \n"++let usage = "Usage: fixtop <options> [source-files]\noptions are:"++let main () = print_string "Hello World \n"++(*+let main () =+  let fs, config = Toplevel.read_inputs usage in+  let cs = config.C.cs in+  let ws = config.C.ws in+  let cs = +    if !Co.simplify_t then+      Misc.map_partial begin fun t -> +        let st = Si.simplify_t t in+	if Si.is_tauto_t st then None else Some st+      end cs |> Si.simplify_ts+    else cs in+    begin+      match !Co.latex_file with+	| Some f ->+	    let out = open_out f in+	      ToLatex.to_latex out cs ws;+	      close_out out+	| None -> ()+    end;+  (*+    begin+      match !Co.armc_file with+	| Some f -> +	    let out = open_out f in+	      Printf.fprintf out "%% %s\n" (String.concat ", " fs);+	      ToHC.to_dataflow_armc out cs ws sol;+	      close_out out+	| None -> ()+    end;+  *)+    (*+    begin+      match !Co.horn_file with+	| Some f -> +	    let out = open_out f in+	      Printf.fprintf out "%% %s\n" (String.concat ", " fs);+	      ToHC.to_horn out cs ws sol;+	      close_out out+	| None -> ()+    end;+    *)+    begin+      match !Co.q_armc_file with+	| Some f -> +	    let out = open_out f in+	      Printf.fprintf out "%% %s\n" (String.concat ", " fs);+	      ToQARMC.to_qarmc out cs ws;+	      close_out out+	| None -> ()+    end;+(*+    begin+      match !Co.raw_horn_file with+	| Some f -> +	    let out = open_out f in+	      Printf.fprintf out "%% %s\n" (String.concat ", " fs);+	      ToRawHorn.to_raw_horn out cs ws sol;+	      close_out out+	| None -> ()+    end;+*)+    begin+      match !Co.dot_file with+	| Some f -> +	    let oc = open_out f in+	      ToDot.to_dot oc cs;+	      close_out oc+	| None -> ()+    end+*)++let _ = main ()
+ external/fixpoint/hornLex.mll view
@@ -0,0 +1,99 @@+(*+ * Copyright © 1990-2002 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 + * d + * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.+ *+ *)++{+  module E = Errorline+  open E+  open HornParse +	       +  let lexerror msg lexbuf = +    E.error (Lexing.lexeme_start lexbuf) msg+      +}++let letdig   = ['0'-'9' 'a'-'z' 'A'-'Z' '_' '@' ''' '.' '#']+let small    = ['a'-'z']+let digit    = ['0'-'9']++rule token = parse+    ['\r''\t'' ']       { token lexbuf}+  | '\n'		{ begin+			    E.startNewline (Lexing.lexeme_end lexbuf);+			    token lexbuf +			  end }+  | "//"[^'\n']*'\n'+                        { begin+                            E.startNewline (Lexing.lexeme_end lexbuf);+			    token lexbuf+                          end }+  | '['                 { LB }+  | ']'                 { RB }+  | '('			{ LPAREN }+  | ')'			{ RPAREN }+  | '{'			{ LC }+  | '}'			{ RC }+  | '~'                 { NOT }+  | ';'                 { SEMI }+  | ','                 { COMMA }+  | ':'                 { COLON }+  | '+'                 { PLUS }+  | '-'                 { MINUS }+  | '*'                 { TIMES }+  | '/'                 { DIV }+  | '.'                 { DOT }+  | "hc"                { HC }+  | "Bexp"              { BEXP }+  | "false"             { FALSE }+  | "true"              { TRUE }+  | "&&"                { AND }+  | "||"                { OR  }+  | "!="		{ NE }+  | "="		        { EQ }+  | "=<"		{ LE }+  | "<"		        { LT }+  | ">="		{ GE }+  | ">"		        { GT }+  | "->"                { IMPL }+  | (digit)+	        { let str = Lexing.lexeme lexbuf in+			  let len = String.length str in+			  let zero = Char.code '0' in+			  let rec accum a d =+			    let acc c = a + (d * ((Char.code c) - zero)) in+			    function+			      0 -> let c = str.[0] in+				   if c='-' then - a else (acc c)+			    | i -> accum (acc str.[i]) (d * 10) (i - 1)+			  in+			  Num (accum 0 1 (len-1)) }+  +  | '_'(digit)+ 	{ Id (Lexing.lexeme lexbuf) }+  | (small)letdig+      { Var (Lexing.lexeme lexbuf) } +  | eof			{ EOF }+  | _			{ +                          begin+                            lexerror ("Illegal Character '" ^ +                                      (Lexing.lexeme lexbuf) ^ "'") lexbuf;+			    token lexbuf+			  end }+
+ external/fixpoint/hornParse.mly view
@@ -0,0 +1,147 @@++%{+module A  = Ast+module So = A.Sort+module Sy = A.Symbol+module E  = A.Expression+module P  = A.Predicate+module H  = A.Horn+module Su = A.Subst+module C  = FixConstraint++let parse_error msg =+  Errorline.error (symbol_start ()) msg++%}++%token <string> Var+%token <string> Id+%token <int> Num+%token BEXP+%token TRUE FALSE+%token LPAREN  RPAREN LB RB LC RC+%token EQ NE GT GE LT LE+%token AND OR NOT IMPL FORALL SEMI COMMA COLON DOT+%token EOF+%token PLUS+%token MINUS+%token TIMES +%token DIV+%token HC ++%right PLUS +%right MINUS+%right TIMES +%right DIV +++%start horns ++%type <A.pred list>                          preds, predsne+%type <A.pred>                               pred+%type <A.expr list>                          exprs, exprsne+%type <A.expr>                               expr+%type <A.brel>                               brel +%type <A.bop>                                bop ++%type <H.pr>                                 pr+%type <H.gd>                                 guard+%type <H.gd list>                            guards, guardsne+%type <Ast.Horn.t>                           hc+%type <Ast.Horn.t list>                      horns ++%%+preds:+    LB RB                               { [] }+  | LB predsne RB                       { $2 }+  ;++predsne:+    pred                                { [$1] }+  | pred SEMI predsne                   { $1 :: $3 }+;++pred:+    TRUE				{ A.pTrue }+  | FALSE				{ A.pFalse }+  | BEXP expr                           { A.pBexp $2 }+  | AND preds   			{ A.pAnd ($2) }+  | OR  preds 	        		{ A.pOr  ($2) }+  | NOT pred				{ A.pNot ($2) }+  | pred IMPL pred			{ A.pImp ($1, $3) }+  | expr brel expr                      { A.pAtom ($1, $2, $3) }+  | LPAREN pred RPAREN			{ $2 }+  ;++exprs:+    LB RB                               { [] }+  | LB exprsne RB                       { $2 }+  ;++exprsne:+    expr                                { [$1] }+  | expr SEMI exprsne                   { $1 :: $3 }+  ;++expr:+    Id				        { A.eVar (Sy.of_string $1) }+  | Num 				{ A.eCon (A.Constant.Int $1) }+  | MINUS Num 				{ A.eCon (A.Constant.Int (-1 * $2)) }+  | MINUS LPAREN expr RPAREN 	        { A.eBin (A.zero, A.Minus, $3) }+  | expr bop expr                       { A.eBin ($1, $2, $3) }+  | Id LPAREN  exprs RPAREN             { A.eApp ((Sy.of_string $1), $3) }+  | LPAREN expr RPAREN                  { $2 }+  ;++brel:+    EQ                                  { A.Eq }+  | NE                                  { A.Ne }+  | GT                                  { A.Gt }+  | GE                                  { A.Ge }+  | LT                                  { A.Lt }+  | LE                                  { A.Le }+  ;++bop:+    PLUS                                { A.Plus }+  | MINUS                               { A.Minus }+  | TIMES                               { A.Times }+  | DIV                                 { A.Div }+  ;+++idsne:+    Id                                  { [$1] }+  | Id COMMA idsne                      { $1 :: $3 }+  ;++pr: +    Var LPAREN RPAREN                    { ($1, []) }+  | Var LPAREN idsne RPAREN              { ($1, $3) }+  | Var                                  { ($1, []) }+  ;++guard:+    pr                                  { H.K ($1) }+  | pred                                { H.C ($1) }+  ;++guards:+    LB RB                               { [] }+  | LB guardsne RB                      { $2 }+  ;++guardsne:+    guard                               { [$1] }+  | guard COMMA guardsne                { $1 :: $3 }+  ;++hc: +  HC LPAREN pr COMMA guards RPAREN DOT {($3, $5)}+  ;+++horns:+                                        { [] }+  | hc horns                            { $1 :: $2 } +
+ external/fixpoint/hornToInterproc.ml view
@@ -0,0 +1,154 @@++module F  = Format+module BS = BNstats+module Co = Constants +module SM = Misc.StringMap +module H  = Ast.Horn+module Misc = FixMisc open Misc.Ops+++let tmpname1 = "tmp"++(***************************************************************************)+(************************* Parse Horn Clauses ******************************)+(***************************************************************************)++let clean f =+  Misc.map_lines_of_file f tmpname1 begin fun s ->+    if String.length s > 3 && String.sub s 0 3 = "hc(" then+        let ss = Misc.chop s ", " in+        match ss with+        | [s1; s2; _] -> Printf.sprintf "%s, %s).\n\n" s1 s2+        | ss          -> assertf "bad string: %s" (String.concat "####" ss)+    else ""+  end;+  tmpname1++let parse f : H.t list = +  let ic = f |> clean >> Errorline.startFile |> open_in in+  let rv = Lexing.from_channel ic |> HornParse.horns HornLex.token in+  let _  = close_in ic in+  rv++(****************************************************************************)+(******************* Preprocess HC to get global information ****************)+(****************************************************************************)++type t = {+  aritym : int SM.t;            (* k -> arity *)+  bindm  : string list SM.t;    (* k -> local bindings *)+  argn   : int;                 (* max-fun-args across all ks *)+  cm     : H.t list SM.t;       (* k -> cs *)+}++let create (cs: H.t list) : t =+  let cm = cs |> Misc.kgroupby (fun ((k,_),_) -> k) +              |> List.fold_left (fun cm (k,cs) -> SM.add k cs cm) SM.empty in+  let aritym = SM.map (function ((k, xs),_)::_ -> +                         let n = List.length xs in+                         (* let _ = Printf.printf "Arity(%s) using %s is %d \n" k+                         (String.concat "," xs) n in *)+                      n) cm in+  let bindm  = SM.map ((Misc.flap H.support) <+> Misc.sort_and_compact) cm in+  let argn   = SM.fold (fun _ a n -> max a n) aritym 0 in+  { aritym = aritym; bindm = bindm; argn = argn; cm = cm }++(****************************************************************************)+(**************************** Generic Sequencers ****************************)+(****************************************************************************)++let gen f sep xs =+  xs |> Misc.map f |> String.concat sep++let geni f sep xs = +  xs |> Misc.mapi f |> String.concat sep++let defn x n =+  geni (fun i _ -> Printf.sprintf "%s%d : int" x i) ", " (Misc.range 0 n)++(****************************************************************************)+(********************************* Translation ******************************)+(****************************************************************************)++let tx_gd = function+  | H.C p       -> Printf.sprintf "    assume %s;" (Misc.fsprintf Ast.Predicate.print p)+  | H.K (k, xs) -> Printf.sprintf "%s\n    () = %s(%s);" +                     (geni (Printf.sprintf "    a%d = %s;") "\n" xs)+                     k+                     (geni (fun i _ -> Printf.sprintf "a%d" i) "," xs)++let tx_hd = function +  | "error", _ -> "    fail;"+  | _, xs      -> Printf.sprintf "    assume %s;" +                     (geni (fun i x -> Printf.sprintf " z%d == %s " i x) " and " xs)++let tx_t k (head, guards) : string =+  Printf.sprintf "  if brandom then\n%s\n%s\n  else" (gen tx_gd "\n" guards) (tx_hd head)++let tx_def me = function+  | "error" -> +      ""+  | k -> +      let n = try SM.find k me.aritym with Not_found -> assertf "ERROR:no arity for %s" k in+      let _ = Printf.printf "Arity(%s) := %d \n" k n in +      Printf.sprintf "proc %s(%s) returns ()" k (defn "z" n) ++let tx_k me (k, cs) =  +  Printf.sprintf +"+%s+var %s, %s;+begin+%s+    halt;+  %s  +end+" +(tx_def me k) +(defn "a" me.argn) +(gen (Printf.sprintf "%s : int") ", " (SM.find k me.bindm)) +(gen (tx_t me) "\n" cs)+(gen (fun _ -> "endif;") " " cs)++let rewrite_eq s = +  if Misc.is_substring s "assume" then +    Misc.replace_substring " = " " == " s +  else s++let tx cs = +  let me = create cs in+  me.cm +  |> Misc.sm_to_list+  |> List.map (tx_k me)+  |> String.concat "\n\n"+  |> Misc.flip Misc.chop "\n" +  |> List.map rewrite_eq+  |> String.concat "\n"++(***************************************************************************)+(***************************** Output Clauses ******************************)+(***************************************************************************)++let dump f cs =+  cs >> Format.printf "*************Horn Clauses************\n\n%a\n\n\n" (Misc.pprint_many true "\n" H.print)+     |> tx +     >> Format.printf "***********Interproc Program*********\n\n%s\n\n\n" +     |> Misc.write_to_file (f^".ipc")++let usage = "hornToInterproc.native [filename.pl]"++let main usage = +  print_now "\n \n \n \n \n";+  print_now "========================================================\n";+  print_now "© Copyright 2009 Regents of the University of California.\n";+  print_now "All Rights Reserved.\n";+  print_now "========================================================\n";+  print_now (Sys.argv |> Array.to_list |> String.concat " ");+  print_now "\n========================================================\n";+  let fs = ref [] in+  let _  = Arg.parse Co.arg_spec (fun s -> fs := s::!fs) usage in+  match !fs with +  | [f] -> parse f |> dump f +  | _   -> assertf "I choke on too many/few files!" ++let _ = main usage
+ external/fixpoint/kvgraph.ml view
@@ -0,0 +1,211 @@+(*+ * 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 P  = Ast.Predicate +module Su = Ast.Subst+module C  = FixConstraint+module Misc = FixMisc open Misc.Ops++type rd = Bnd of Sy.t * Su.t | Lhs of Su.t | Grd | Junk++let print_rd ppf = function+  | Bnd (x, su) -> Format.fprintf ppf "Bnd (%a, %a)" Sy.print x Su.print su+  | Lhs su      -> Format.fprintf ppf "Lhs (%a)" Su.print su+  | Grd         -> Format.fprintf ppf "Grd"+  | Junk        -> Format.fprintf ppf "Junk"++(************************************************************************)+(********************* Build Graph of Kvar Dependencies *****************)+(************************************************************************)++module V : Graph.Sig.COMPARABLE with type t = C.refa = struct+  type t = C.refa+  let hash    = C.refa_to_string <+> Hashtbl.hash+  let compare = fun x y -> compare (C.refa_to_string x) (C.refa_to_string y)+  let equal   = fun x y -> C.refa_to_string x = C.refa_to_string y+end++module Id : Graph.Sig.ORDERED_TYPE_DFT with type t = int * rd = struct+  type t = int * rd+  let default = 0, Junk +  let compare = compare+end++module G   = Graph.Persistent.Digraph.ConcreteLabeled(V)(Id)+module VS  = Set.Make(V)++type t = G.t++(************************************************************************)+(*************************** Dumping to Dot *****************************) +(************************************************************************)++module DotGraph = struct+  type t = G.t+  module V = G.V+  module E = G.E+  let iter_vertex               = G.iter_vertex+  let iter_edges_e              = G.iter_edges_e+  let graph_attributes          = fun _ -> [`Size (11.0, 8.5); `Ratio (`Float 1.29)]+  let default_vertex_attributes = fun _ -> [`Shape `Box]+  let vertex_name               = function C.Kvar (_,k) -> Sy.to_string k | ra -> "C"^(string_of_int (V.hash ra))+  let vertex_attributes         = fun ra -> [`Label (C.refa_to_string ra)] +  let default_edge_attributes   = fun _ -> []+  let edge_attributes           = fun (_,(i,r),_) -> [`Label (Printf.sprintf "%d:%s" i (Misc.fsprintf print_rd r))]+  let get_subgraph              = fun _ -> None+end++module Dot = Graph.Graphviz.Dot(DotGraph) ++let dump_graph s g = +  s |> open_out +    >> (fun oc -> Dot.output_graph oc g)+    |> close_out ++(************************************************************************)+(********************* Constraints-to-Graph *****************************) +(************************************************************************)++let xkvars_of_env env = +  Sy.SMap.fold begin fun x r acc -> +    r |> C.kvars_of_reft +      |> List.map (fun z -> x,z) +      |> (fun xks -> xks ++ acc)+  end env []++let dsts_of_t c = +  c |> C.rhs_of_t +    |> C.ras_of_reft +    |> List.map (function C.Kvar (_,k) -> C.Kvar (Su.empty, k) | ra -> ra) ++let edges_of_t c =+  let eks = c |> C.env_of_t +              |> xkvars_of_env +              |> List.map (fun (x, (su, k)) -> (C.Kvar (Su.empty, k)), Bnd (x, su)) in+  let gps = c |> C.grd_of_t +              |> (fun p -> if P.is_tauto p then [] else [(C.Conc p, Grd)]) in+  let lks = c |> C.lhs_of_t +              |> C.ras_of_reft +              |> List.map (function C.Kvar (su, k) -> (C.Kvar (Su.empty, k), Lhs su) | ra -> (ra, Grd)) in +  c |> dsts_of_t+    |> Misc.cross_product (lks ++ gps ++ eks)  +    |> List.map (fun ((ra, l), ra') -> (ra, (C.id_of_t c, l), ra'))++(************************************************************************)+(*************************** Misc. Accessors ****************************) +(************************************************************************)++let vertices_of_graph = fun g -> G.fold_vertex (fun v acc -> v::acc) g []++(* API *)+let filter_kvars f g =+  g  |> vertices_of_graph+     |> List.filter (not <.> C.is_conc_refa)+     |> List.filter f +     |> Misc.sort_and_compact++let get_edges f g vs =+  vs |> Misc.flap (f g)+     |> List.map (fun (_,(i,_),_) -> i) +     |> Misc.sort_and_compact++(* APU *)+let writes  = get_edges G.pred_e +let reads   = get_edges G.succ_e++(* API *)+let k_reads g i k =+  k >> (C.refa_to_string <+> Format.printf "Kvgraph.k_reads [IN] id=%d, k=%s\n" i)+    |> G.succ_e g +    |> Misc.map_partial (function (_,(j,x),_) when i=j -> Some x | _ -> None)+    >> (Format.printf "Kvgraph.k_reads [OUT] %a \n" (Misc.pprint_many false "," print_rd))++(************************************************************************)+(********************* (Backwards) Reachability *************************) +(************************************************************************)++let vset_of_list vs = List.fold_left (fun s v -> VS.add v s) VS.empty vs+let pre_star g vs =+  (vs, VS.empty)+  |> Misc.fixpoint begin function +     | [], r -> ([], r), false+     | ws, r -> ws |> List.filter (fun v -> not (VS.mem v r)) +                   |> Misc.tmap2 (Misc.flap (G.pred g), vset_of_list <+> VS.union r)+                   |> (fun x -> x, true) +     end +  |> fst |> snd +  |> VS.elements++(************************************************************************)+(****************************** Predicates ******************************) +(************************************************************************)++let is_num_write g f v = +  [v] |> writes g +      |> List.length +      |> f++let undef_ks     = fun g -> filter_kvars (is_num_write g ((=) 0)) g+let multi_wr_ks  = fun g -> filter_kvars (is_num_write g ((<) 1)) g+let single_wr_ks = fun g -> filter_kvars (is_num_write g ((=) 1)) g++let cone_nodes g =  +  g |> vertices_of_graph+    |> List.filter C.is_conc_refa+    |> pre_star g++(*************************************************************************)+(******************************* API *************************************)+(*************************************************************************)++let print_ks s ks =+  ks |> Misc.map_partial (function C.Kvar (_,k) -> Some k | _ -> None)+     |> Format.printf "[KVG] %s %a \n" s (Misc.pprint_many false "," Sy.print) ++(* API *)+let is_single_wr = fun g -> is_num_write g ((=) 1)+let is_single_rd = fun g -> G.succ_e g <+> Misc.groupby (snd3 <+> fst) <+> List.for_all (function [_] -> true | _ -> false)++(* API *)+let empty  = G.empty+let add    = List.fold_left (fun g -> List.fold_left G.add_edge_e g <.> edges_of_t)+let remove = List.fold_left G.remove_vertex ++(* API *)+let cone_ks g = +  g |> cone_nodes+    |> List.filter (not <.> C.is_conc_refa)++(* API *)+let cone_ids g = +  g |> cone_nodes +    |> writes g++(* API *)+let print_stats g = +  g >> dump_graph (!Constants.save_file^".dot")+    >> (single_wr_ks <+> print_ks "single write kvs:")+    >> (multi_wr_ks  <+> print_ks "multi write kvs:")+    >> (undef_ks     <+> print_ks "undefined kvs:")+    >> (cone_ks      <+> print_ks "cone kvs:")+    |> ignore
+ external/fixpoint/kvgraph.mli view
@@ -0,0 +1,37 @@+(*+ * 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.+ *)++type t++type rd = Bnd of Ast.Symbol.t * Ast.Subst.t | Lhs of Ast.Subst.t | Grd | Junk++val empty        : t+val remove       : t -> FixConstraint.refa list -> t+val add          : t -> FixConstraint.t list -> t +val print_stats  : t -> unit+val cone_ids     : t -> FixConstraint.id list+val writes       : t -> FixConstraint.refa list -> FixConstraint.id list+val reads        : t -> FixConstraint.refa list -> FixConstraint.id list+val k_reads      : t -> FixConstraint.id -> FixConstraint.refa -> rd list+val filter_kvars : (FixConstraint.refa -> bool) -> t -> FixConstraint.refa list+val is_single_wr : t -> FixConstraint.refa -> bool+val is_single_rd : t -> FixConstraint.refa -> bool
+ external/fixpoint/predAbs.ml view
@@ -0,0 +1,839 @@+(*+ * 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.+ *)++ +(*************************************************************)+(******************** Solution Management ********************)+(*************************************************************)++module F   = Format+module A   = Ast+module E   = A.Expression+module P   = A.Predicate++module Q   = Qualifier+module QS  = Q.QSet+module Sy  = A.Symbol+module Su  = A.Subst+module SM  = Sy.SMap+module SS  = Sy.SSet+module C   = FixConstraint++module BS  = BNstats+module Co  = Constants+module Cg  = FixConfig+module H   = Hashtbl+module PH  = A.Predicate.Hash++module CX  = Counterexample+module Misc = FixMisc +module IM  = Misc.IntMap+open Misc.Ops++let mydebug = false ++module Q2S = Misc.ESet (struct+  type t = Sy.t * Sy.t+  let compare x y = compare x y +end)++module V : Graph.Sig.COMPARABLE with type t = Sy.t = struct+  type t = Sy.t+  let hash    = Sy.to_string <+> H.hash+  let compare = compare+  let equal   = (=) +end++++(*+let tag_of_qual2 = Misc.map_pair tag_of_qual++module Q2S = Misc.ESet (struct+  type t = Q.t * Q.t+  let compare x y = compare (tag_of_qual2 x) (tag_of_qual2 y)+end)++module V : Graph.Sig.COMPARABLE with type t = Q.t = struct+  type t = Q.t+  let hash    = tag_of_qual <+> H.hash+  let compare = fun q1 q2 -> compare (tag_of_qual q1) (tag_of_qual q2)+  let equal   = fun q1 q2 -> tag_of_qual q1 = tag_of_qual q2+end++*)++module Id : Graph.Sig.ORDERED_TYPE_DFT with type t = unit = struct+  type t = unit +  let default = ()+  let compare = compare +end++module G   = Graph.Persistent.Digraph.ConcreteLabeled(V)(Id)+module SCC = Graph.Components.Make(G)++type bind = Q.t list++type t   = +  { tpc  : ProverArch.prover+  ; m    : bind SM.t+  ; assm : FixConstraint.soln  (* invariant assumption for K, +                                 must be a fixpoint wrt constraints *)+  ; qm   : Q.t SM.t            (* map from names to qualifiers *)+  ; qleqs: Q2S.t               (* (q1,q2) \in qleqs implies q1 => q2 *)+  +  (* counterexamples *)+  ; step     : CX.step         (* which iteration *)+  ; ctrace   : CX.ctrace +  ; lifespan : CX.lifespan +  +  (* stats *)+  ; stat_simple_refines : int ref +  ; stat_tp_refines     : int ref +  ; stat_imp_queries    : int ref +  ; stat_valid_queries  : int ref +  ; stat_matches        : int ref +  ; stat_umatches       : int ref +  ; stat_unsatLHS       : int ref +  ; stat_emptyRHS       : int ref +}++let pprint_ps =+  Misc.pprint_many false ";" P.print ++ +let pprint_dep ppf q = +  F.fprintf ppf "(%a, %a)" P.print (Q.pred_of_t q) Q.print_args q++let pprint_ds = +  Misc.pprint_many false ";" pprint_dep++let pprint_qs ppf = +  F.fprintf ppf "[%a]" (Misc.pprint_many false ";" Q.print)++let pprint_qs' ppf = +  List.map (fst <+> snd <+> snd <+> fst) <+> pprint_qs ppf ++(*************************************************************)+(************* Breadcrumbs for Cex Generation ****************)+(*************************************************************)++let cx_iter c me = +  { me with step = me.step + 1 }          ++let cx_ctrace b c me = +  let _ = if mydebug then F.printf "\nPredAbs.refine iter = %d cid = %d b = %b\n" +                          me.step (C.id_of_t c) b in+  if b then { me with ctrace = IM.adds (C.id_of_t c) [me.step] me.ctrace } else me++let cx_update ks kqsm' me : t = +  List.fold_left begin fun me k -> +    let qs    = QS.of_list  (SM.finds k me.m)  in+    let qs'   = QS.of_list  (SM.finds k kqsm') in+    let kills = QS.elements (QS.diff qs qs')   in+    if Misc.nonnull kills +    then {me with lifespan = SM.adds k [(me.step, kills)] me.lifespan}+    else me+  end me ks++(*************************************************************)+(************* Constructing Initial Solution *****************)+(*************************************************************)++(*++let def_of_pred_qual (p, q) =+  let qp = Q.pred_of_t q in+  match A.unify_pred qp p with+  | Some su -> (p, q, su)+  | None    -> assertf "ERROR: unify q=%s p=%s" (P.to_string qp) (P.to_string p)++let map_of_bindings bs =+  List.fold_left begin fun s (k, ds) -> +    ds |> List.map Misc.single +       |> Misc.flip (SM.add k) s+  end SM.empty bs +*)++let quals_of_bindings bm =+  bm |> SM.range +     |> Misc.flatten+     (* |> Misc.map (snd <+> fst)  *)+     |> Misc.sort_and_compact+     >> (fun qs -> Co.bprintf mydebug "Quals of Bindings: \n%a" (Misc.pprint_many true "\n" Q.print) qs; flush stdout)++(************************************************************************)+(*************************** Dumping to Dot *****************************) +(************************************************************************)+++module DotGraph = struct+  type t = G.t+  module V = G.V+  module E = G.E+  let iter_vertex               = G.iter_vertex+  let iter_edges_e              = G.iter_edges_e+  let graph_attributes          = fun _ -> [`Size (11.0, 8.5); `Ratio (`Fill (* Float 1.29*))]+  let default_vertex_attributes = fun _ -> [`Shape `Box]+  let vertex_name               = Sy.to_string +  let vertex_attributes         = fun q -> [`Label (Sy.to_string q)] +  let default_edge_attributes   = fun _ -> []+  let edge_attributes           = fun (_,(),_) -> [] +  let get_subgraph              = fun _ -> None+end++module Dot = Graph.Graphviz.Dot(DotGraph) ++let dump_graph s g = +  s |> open_out +    >> (fun oc -> Dot.output_graph oc g)+    |> close_out ++let p_read s k =+  let _ = asserts (SM.mem k s.m) "ERROR: p_read : unknown kvar %s\n" (Sy.to_string k) in+  SM.find k s.m  |>: (fun q -> ((k, q), Q.pred_of_t q))++(* INV: qs' \subseteq qs *)+let update m k ds' =+  let ds = SM.finds k m in+  let n  = List.length ds  in+  let n' = List.length ds' in +  let _  = asserts (n = 0 || n' <= n) "PredAbs.update: Non-monotone k = %s |ds| = %d |ds'| = %d \n" (Sy.to_string k) n n' in +  ((n != n'), SM.add k ds' m)+  (* >> begin fun _ -> +        if n' > n && n > 0 then +          Co.bprintflush mydebug  <| Printf.sprintf "OMFG: update k = %s |ds| = %d |ds'| = %d \n" +                          (Sy.to_string k) n n'+     end+   *)++(* We must ensure there are NO duplicate k-q pairs in the update list.+ * If there are duplicate KVars in the ks then the kqs must be grouped:+ * a "k-q" binding is ONLY preserved  IF #bindings = #copies-of-k+ * If there are NO duplicate KVars there SHOULD BE no duplicate k-q pairs. *)++let group_ks_kqs ks kqs = +  if (Misc.cardinality ks = List.length ks) then +    kqs (* no duplicate kvars *) +  else +    let km = SM.frequency ks in+    kqs |> Misc.frequency +        |> Misc.filter (fun ((k, _), n) -> n = SM.find_default 0 k km)+        |> Misc.map fst ++let p_update me ks kqs = +  (* let _    = Co.bprintflush mydebug (Printf.sprintf "p_update A: |kqs| = %d \n" (List.length kqs)) in *)+  let kqs  = group_ks_kqs ks kqs in+  (* let _    = Co.bprintflush mydebug (Printf.sprintf "p_update B: |kqs| = %d \n" (List.length kqs)) in *)+  let kqsm = SM.of_alist kqs in+  let me   = me |> (!Co.cex <?> BS.time "cx_update" (cx_update ks) kqsm) in +  List.fold_left begin fun (b, m) k ->+    SM.finds k kqsm +    |> update m k +    |> Misc.app_fst ((||) b)+  end (false, me.m) ks+  |> Misc.app_snd (fun m -> { me with m = m })  +++(* API *)+let top s ks = +  ks (* |> List.partition (fun k -> SM.mem k s.m)+     >> (fun (_, badks) -> Co.bprintf mydebug "WARNING: Trueing Unbound KVars = %s \n" (Misc.fsprintf (Misc.pprint_many false "," Sy.print) badks))+     |> fst *)+     |> Misc.flip (p_update s) []+     |> snd++(***************************************************************)+(************************** Refinement *************************)+(***************************************************************)++let rhs_cands s = function+  | C.Kvar (su, k) -> k (* >> (fun k -> Co.bprintflush mydebug ("rhs_cands: k = "^(Sy.to_string k)^"\n")) *)+                        |> p_read s +                        (* >> (fun xs -> Co.bprintflush mydebug ("rhs_cands: size="^(string_of_int (List.length xs))^" BEGIN \n")) *)+                        |>: (Misc.app_snd (Misc.flip A.substs_pred su))+                        (* >> (fun xs -> Co.bprintflush mydebug ("rhs_cands: size="^(string_of_int (List.length xs))^" DONE\n")) *)+  | _ -> []++let check_tp me env vv t lps =  function [] -> [] | rcs ->+  (* let rv  = TP.set_filter me.tpc env vv lps rcs               in+  let _   = ignore(me.stat_tp_refines    += 1)+          ; ignore(me.stat_imp_queries   += (List.length rcs))+          ; ignore(me.stat_valid_queries += (List.length rv)) +  in rv *)+  me.tpc#set_filter env vv lps rcs+  >> (fun _  -> me.stat_tp_refines    += 1)+  >> (fun _  -> me.stat_imp_queries   += List.length rcs)+  >> (fun rv -> me.stat_valid_queries += List.length rv) +++++(* API *)+let read me k = (me.assm k) ++ (if SM.mem k me.m then p_read me k |>: snd else [])++(* API *)+let read_bind s k = failwith "PredAbs.read_bind"++let refine me c =+  let (_,_,ra2s) as r2 = C.rhs_of_t c in+  let k2s = r2 |> C.kvars_of_reft |> List.map snd in+  let rcs = BS.time "rhs_cands" (Misc.flap (rhs_cands me)) ra2s in+  if rcs = [] then+    let _ = me.stat_emptyRHS += 1 in+    (false, me)+  else +    let lps = BS.time "preds_of_lhs" (C.preds_of_lhs (read me)) c in+    if BS.time "lhs_contra" (List.exists P.is_contra) lps then +    let _ = me.stat_unsatLHS += 1 in+    let _ = me.stat_umatches += List.length rcs in+    (false, me)+  else +    let rcs     = List.filter (fun (_,p) -> not (P.is_contra p)) rcs in+    let lt      = PH.create 17 in+    let _       = List.iter (fun p -> PH.add lt p ()) lps in+    let (x1,x2) = List.partition (fun (_,p) -> PH.mem lt p) rcs in+    let _       = me.stat_matches += (List.length x1) in+    let kqs1    = List.map fst x1 in+    (if C.is_simple c +     then (ignore(me.stat_simple_refines += 1); kqs1) +     else let senv = C.senv_of_t c in+          let vv   = C.vv_of_t c   in+          let t    = C.sort_of_t c in+          kqs1 ++ (BS.time "check tp" (check_tp me senv vv t lps) x2))+    |> p_update me k2s++let refine me c = +  let me      = me |> (!Co.cex <?> cx_iter c)     in+  let (b, me) = refine me c                       in+  let me      = me |> (!Co.cex <?> cx_ctrace b c) in+  (b, me)+++(***************************************************************)+(****************** Sort Check Based Refinement ****************)+(***************************************************************)++let refts_of_c c =+  [ C.lhs_of_t c ; C.rhs_of_t c] ++ (C.env_of_t c |> C.bindings_of_env |>: snd)++let refine_sort_reft env me ((vv, so, ras) as r) = +  let env' = SM.add vv r env in +  let ks   = r |> C.kvars_of_reft |>: snd in+  (* let _    = let s =  String.concat ", " (List.map Sy.to_string ks) in Co.bprintflush mydebug ("\n refine_sort_reft ks = "^s^"\n")  in  *)+  ras +  |> Misc.flap (rhs_cands me) (* OMFG blowup due to FLAP if kv appears multiple times...*)+  |> Misc.filter (fun (_, p) -> C.wellformed_pred env' p)+  |> List.rev_map fst+(* |> (fun xs -> Co.bprintflush mydebug (Printf.sprintf "refine_sort_reft map: size = %d\n" (List.length xs)); +                List.rev_map fst xs)+  >> (fun _ -> Co.bprintflush mydebug "\n refine_sort_reft TICK 4 \n")+  *)+  |> p_update me ks+  |> snd++let refine_sort me c =+  let env = C.env_of_t c in+  c (* >> (fun _ -> Co.bprintflush mydebug ("\n refine_sort TICK 0 id = "^(string_of_int (C.id_of_t c))^"\n")) *)+    |> refts_of_c+    |> List.fold_left (refine_sort_reft env) me  +    (* >> (fun _ -> Co.bprintflush mydebug "\n refine_sort TICK 2 \n") *)++(***************************************************************)+(************************* Satisfaction ************************)+(***************************************************************)++let unsat me c = +  let s        = read me      in+  let (vv,t,_) = C.lhs_of_t c in+  let lps      = C.preds_of_lhs s c  in+  let rhsp     = c |> C.rhs_of_t |> C.preds_of_reft s |> A.pAnd in+  let k        = Sy.of_string "k" in+  let kq       = (k, Q.create k k Ast.Sort.t_int [] A.pTrue) in+  not ((check_tp me (C.senv_of_t c) vv t lps [(kq, rhsp)]) = [kq])++(****************************************************************)+(************* Minimization: For Prettier Output ****************)+(****************************************************************)++(*+let canonize_subs = +  Su.to_list <+> List.sort (fun (x,_) (y,_) -> compare x y)++let subst_leq =+  Misc.map_pair canonize_subs <+> Misc.isPrefix+*)++let args_leq q1 q2 =+  let xe1s, xe2s = (Q.args_of_t q1, Q.args_of_t q2) in+  let xe1e2s     = Misc.join fst xe1s xe2s          in+  List.for_all (fun ((_,e1),(_,e2)) -> e1 = e2) xe1e2s ++(* P(v,x,y,z) => Q(v,x) if P => Q held and _intersection_ of args match. *)+let def_leq s q1 q2 = +     Q2S.mem (Q.name_of_t q1, Q.name_of_t q2) s.qleqs && args_leq q1 q2++let pred_of_bind_name q = +  let name = q |> Q.name_of_t                 in+  let args = q |> Q.args_of_t |> List.map snd in+  A.pBexp (A.eApp (name, args)) ++let pred_of_bind_raw = Q.pred_of_t ++let pred_of_bind q = +  if !Co.shortannots +  then pred_of_bind_name q +  else pred_of_bind_raw q ++let min_binds_bot ds = +  match Misc.list_find_maybe (P.is_contra <.> pred_of_bind_raw) ds with+    | None   -> ds+    | Some d -> [d] ++(* API *)+let min_binds s ds = ds |> min_binds_bot |> Misc.rootsBy (def_leq s)+let min_read s k   = SM.finds k s.m |> min_binds s |>: pred_of_bind+let min_read s k   = if !Co.minquals then min_read s k else read s k+let min_read s k   = BS.time "min_read" (min_read s) k++let close_env qs sm =+  qs |> Misc.flap   (Q.pred_of_t <+> P.support) +     |> Misc.filter (not <.> Misc.flip SM.mem sm)+     |> Misc.map    (fun x -> (x, Ast.Sort.t_int))+     |> SM.of_list+     |> SM.extend sm++let rename_vv q q' =+  List.combine (Q.all_params_of_t q |>: fst) (Q.all_params_of_t q' |>: fst)+  |> List.filter (fun (x, y) -> not (x = y))+  |> List.map (fun (x, y) -> (y, A.eVar x))+  |> Su.of_list+  |> A.substs_pred (Q.pred_of_t q')+  |> (fun p' -> (q', p'))++let sm_of_qual sm q = +  q |> Q.all_params_of_t +    |> SM.of_list +    |> SM.extend sm++(*  check_leq tp sm q qs = [q' | q' <- qs, Z3 |- q => q'] *)+let check_leq (tp : ProverArch.prover) sm (q : Q.t) (qs : Q.t list) : Q.t list = +  let vv  = Q.vv_of_t q in+  let lps = [Q.pred_of_t q] in+  let sm  = q |> sm_of_qual sm |> close_env qs in+  qs |> List.map (rename_vv q) (* (fun q -> (q, Q.pred_of_t q)) *)+     (* >> (List.map fst <+> F.printf "CHECK_TP: %a IN %a \n" Q.print q pprint_qs) *)+     |> tp#set_filter sm vv lps+     (* >> F.printf "CHECK_TP: %a OUT %a \n" Q.print q pprint_qs *)++let qimps_of_partition tp sm qs =+  foreach qs begin fun q ->+    let qs' = check_leq tp sm q qs in+    foreach qs' begin fun q' ->+      (q, q')+    end+  end++let wellformed_qual sm q =+  let sm = sm_of_qual sm q in+  A.sortcheck_pred Theories.is_interp (fun x -> SM.maybe_find x sm) (Q.pred_of_t q)++let qleqs_of_qs ts sm cs ps qs  =+  let tp = TpNull.create ts sm cs ps in+  qs |> Misc.filter (wellformed_qual sm)+     |> Misc.groupby (List.map snd <.> Q.all_params_of_t) (* Q.sort_of_t *)+     |> Misc.flap (qimps_of_partition tp sm)+     |> Misc.flatten+     |> Misc.map (Misc.map_pair Q.name_of_t) +     |> Q2S.of_list++(***************************************************************)+(******************** Qualifier Instantiation ******************)+(***************************************************************)++type qual_binding = (Sy.t * Sy.t) list++(* DEBUG ONLY *)+let print_param ppf (x, t) =+  F.fprintf ppf "%a:%a" Sy.print x Ast.Sort.print t +let print_params ppf args =+  F.fprintf ppf "%a" (Misc.pprint_many false ", " print_param) args+let print_valid_binding ppf (x,y) =+  F.fprintf ppf "[%a := %a]" Sy.print x Sy.print y+let print_valid_bindings ppf xys =+  F.printf "[%a]" (Misc.pprint_many false "" print_valid_binding) xys++(* +let dupfree_binding xys : bool = +  let ys  = List.map snd xys in+  let ys' = Misc.sort_and_compact ys in+  List.length ys = List.length ys'+*)++let varmatch_ctr = ref 0++let varmatch (x, y) = +  let _ = varmatch_ctr += 1 in+  let (x,y) = Misc.map_pair Sy.to_string (x,y) in+  if x.[0] = '@' then+    let x' = Misc.suffix_of_string x 1 in+    Misc.is_prefix x' y+  else true++let sort_compat t1 t2 = A.Sort.unify [t1] [t2] <> None++(* {{{ DONT DELETE FOR NOW let valid_bindings_sort env (x, t) =+  let _ = failwith "valid_bindings_sort: slow AND incorrect. suppressed!" in+  env |> SM.to_list+      |> Misc.filter (snd <+> C.sort_of_reft <+> (sort_compat t))+      |> Misc.map (fun (y,_) -> (x, y))+      |> Misc.filter varmatch++let valid_bindings env ys (x, t) =+  if !Co.sorted_quals+  then valid_bindings_sort env (x, t)+  else valid_bindings ys x+}}} *)++let wellformed_qual wf f q = +  q |> Q.pred_of_t +    |> A.sortcheck_pred Theories.is_interp f+    (* >> (F.printf "\nwellformed: id = %d q = @[%a@] result %b\n" (C.id_of_wf wf) Q.print q) *)+    (* NEVER uncomment out the above. *)++(********************************************************************************)+(****** Brute Force (Post-Selection based) Qualifier Instantiation **************)+(********************************************************************************)++let is_valid_binding (xys : qual_binding) : bool = +  List.for_all varmatch xys++let valid_bindings ys (x,_) =+  ys |> List.map (fun y -> (x, y))+     |> List.filter varmatch++let inst_qual env ys evv (q : Q.t) : Q.t list =+  let vve = (Q.vv_of_t q, evv) in+  match Q.params_of_t q with+  | [] ->+      [(Q.inst q [vve])]+  | xts ->+      xts+      (* >> F.printf "\n\ninst_qual: params q = %a: %a" Q.print q print_params          *)+      |> List.map (valid_bindings ys)                       (* candidate bindings    *)+      |> Misc.product                                       (* generate combinations *) +      (* >> (List.iter (F.printf "\ninst_qual: pre-binds = %a\n" print_valid_bindings)) *)+      |> List.filter is_valid_binding                       (* remove bogus bindings *)+      (* >> (List.iter (F.printf "\ninst_qual: post-binds = %a\n" print_valid_bindings)) *)+      |> List.rev_map (List.map (Misc.app_snd A.eVar))      (* instantiations        *)+      |> List.rev_map (fun xes -> Q.inst q (vve::xes))      (* quals *)+      (* >> (F.printf "\n\ninst_qual: result q = %a:\n%a DONE\n" Q.print q (Misc.pprint_many true "" Q.print)) *)++let inst_vars env = +  env |> Sy.SMap.to_list +      |> List.filter (fun (_, (_,so,_)) -> not (A.Sort.is_func so))+      |> List.map fst ++let inst_ext qs wf = +  let _    = Misc.display_tick () in+  let r    = C.reft_of_wf wf in +  let ks   = C.kvars_of_reft r |> List.map snd in+  let env  = C.env_of_wf wf in+  let vv   = fst3 r in+  let t    = snd3 r in+  let ys   = inst_vars env   in+  let env' = Misc.maybe_map C.sort_of_reft <.> C.lookup_env (SM.add vv r env) in+  qs |> List.filter (Q.sort_of_t <+> sort_compat t)+     |> Misc.flap   (inst_qual env ys (A.eVar vv))+     |> Misc.filter (wellformed_qual wf env' <&&> C.filter_of_wf wf)+     |> Misc.cross_product ks+     +(********************************************************************************)+(****** Sort Based Qualifier Instantiation **************************************)+(********************************************************************************)++let inst_binds env = +  env |> SM.to_list +      |> Misc.map (Misc.app_snd snd3) +      |> Misc.filter (not <.> A.Sort.is_func <.> snd)++(* [ (su', (x,y) : xys) | (su, xys) <- wkl+                        , (y, ty)   <- yts+                        , varmatch (x, y)+                        , Some su'  <- unifyWith su [tx] [ty] ]  *)++let ext_bindings yts wkl (x, tx) =+  let yts = List.filter (fun (y,_) -> varmatch (x, y)) yts in+  Misc.tr_rev_flap (fun (su, xys) ->+    Misc.map_partial (fun (y, ty) -> +      match A.Sort.unifyWith su [tx] [ty] with+        | None     -> None+        | Some su' -> Some (su', (x,y) :: xys)+    ) yts+  ) wkl ++let inst_qual_sorted yts vv t q = +  let (qvv0, t0) :: xts = Q.all_params_of_t q     in+  match A.Sort.unify [t0] [t] with +    | Some su0 -> +        xts |> List.fold_left (ext_bindings yts) [(su0, [(qvv0, vv)])]  (* generate subs-bindings *)+            |> List.rev_map (List.rev <.> snd)                          (* extract sorted bindings *)+            |> List.rev_map (List.map (Misc.app_snd A.eVar))            (* instantiations        *)+            |> List.rev_map (Q.inst q)                                  (* quals *)+    | None    -> [] ++let inst_ext_sorted qs wf = +  let _    = Misc.display_tick ()               in+  let r    = C.reft_of_wf wf                    in +  let ks   = List.map snd <| C.kvars_of_reft r  in+  let env  = C.env_of_wf wf                     in+  let vv   = fst3 r                             in+  let t    = snd3 r                             in+  let yts  = inst_binds env                     in+  qs |> Misc.flap (inst_qual_sorted yts vv t)+     |> Misc.cross_product ks++(*************************************************************************************)++let inst_ext qs wf =+  if !Co.sorted_quals +  then inst_ext_sorted qs wf +  else inst_ext        qs wf+ +let inst_ext qs wf =+  if mydebug then +    let msg = Printf.sprintf "inst_ext wf id = %d" (C.id_of_wf wf) in+    Misc.trace msg (inst_ext qs) wf+    >> (List.length <+> F.printf "\n\ninst_ext wfid = %d: size = %d\n"  (C.id_of_wf wf))+  else inst_ext qs wf++(* API *)+let inst ws qs =+  Misc.flap (inst_ext qs) ws +  |> Misc.kgroupby fst +  |> Misc.map (Misc.app_snd (List.map snd)) ++++(*************************************************************************)+(*************************** Creation ************************************)+(*************************************************************************)++let create_qleqs ts sm ps consts qs =+  if !Co.minquals +  then BS.time "Annots: make qleqs" (qleqs_of_qs ts sm consts ps) qs +  else Q2S.empty++let create ts sm ps consts assm qs bm =+ {  m     = bm+  ; assm  = assm+  ; qm    = qs |>: Misc.pad_fst Q.name_of_t |> SM.of_list+  ; qleqs = Misc.with_ref_at Constants.strictsortcheck false +              (fun () -> create_qleqs ts sm consts ps qs) +  ; tpc   = TpNull.create ts sm ps consts+  +  (* Counterexamples *) +  ; step     = 0+  ; ctrace   = IM.empty+  ; lifespan = SM.empty++  (* Stats *)+  ; stat_simple_refines = ref 0+  ; stat_tp_refines     = ref 0; stat_imp_queries    = ref 0+  ; stat_valid_queries  = ref 0; stat_matches        = ref 0+  ; stat_umatches       = ref 0; stat_unsatLHS       = ref 0+  ; stat_emptyRHS       = ref 0+  } ++(* RJ: DO NOT DELETE! *)+let ppBinding (k, zs) = +  F.printf "ppBind %a := %a \n" +    Sy.print k +    (Misc.pprint_many false "," Q.print) zs++(* Take in a solution of things that are known to be true, kf. Using+   this, we can prune qualifiers whose negations are implied by+   information in kf *)+let update_pruned ks me fqm =+  List.fold_left begin fun m k ->+    if not (SM.mem k fqm) then m else+      let false_qs = SM.safeFind k fqm "update_pruned 1" in+      let qs = SM.safeFind k m "update_pruned 2" +               |> List.filter (fun q -> (not (List.mem (k,q) false_qs))) +      in SM.add k qs m+  end me.m ks++let apply_facts_c kf me c =+  let env = C.senv_of_t c in+  let (vv, t, lras) = C.lhs_of_t c in+  let (_,_,ras) as rhs = C.rhs_of_t c in+  let ks = rhs |> C.kvars_of_reft |> List.map snd in+  let lps = C.preds_of_lhs kf c in (* Use the known facts here *)+  let rcs = (Misc.flap (rhs_cands me)) ras in+    if rcs = [] then               (* Nothing on the right hand side *)+      me+    else if check_tp me env vv t lps [(0, A.pFalse)] = [0] then+      me+    else+      let rcs = List.filter (fun (_,p) -> not (P.is_contra p)) rcs+                |> List.map (fun (x,p) -> (x, A.pNot p)) in+	(* can we prove anything on lhs implies something on rhs is false? *)+      let fqs = BS.time "apply_facts tp" (check_tp me env vv t lps) rcs in+      let fqm = fqs |> Misc.kgroupby fst |> SM.of_list in+	  {me with m = BS.time "update pruned" (update_pruned ks me) fqm}++let apply_facts cs kf me =+  let numqs = me.m |> Ast.Symbol.SMap.to_list+              |> List.map snd |> List.concat |> List.length in+  let sol   = List.fold_left (apply_facts_c kf) me cs in+  let numqs' = sol.m |> Ast.Symbol.SMap.to_list+               |> List.map snd |> List.concat |> List.length in+  let _ = Printf.printf "Started with %d, proved %d false\n" numqs (numqs-numqs') in+    sol++let binds_of_quals ws qs =+  qs+  (* |> Q.normalize *)+  >> (fun qs -> Co.bprintf mydebug "Using Quals: \n%a" (Misc.pprint_many true "\n" Q.print) qs)+  >> (fun _  -> Co.bprintflush mydebug "\nBEGIN: Qualifier Instantiation\n")+  |> BS.time "Qual Inst" (inst ws) +  >> (fun _  -> Co.bprintflush mydebug "\nDONE: Qualifier Instantiation\n")+  (* >> List.iter ppBinding *)+  |> SM.of_list +  >> (fun _ -> Co.bprintflush mydebug "\nDONE: Qualifier Instantiation: Built Map \n")+++let binds_of_quals ws qs = +  match !Constants.dump_simp with+  | "" -> binds_of_quals ws qs  (* regular solving mode *)+  | _  -> SM.empty              (* constraint simplification mode *)+++(* API *)+let create c facts = +  binds_of_quals c.Cg.ws c.Cg.qs+  |> SM.extendWith (fun _ -> (++)) c.Cg.bm+  |> create c.Cg.ts c.Cg.uops c.Cg.ps c.Cg.cons c.Cg.assm c.Cg.qs+  >> (fun _ -> Co.bprintflush mydebug "\nBEGIN: refine_sort\n")+  |> ((!Constants.refine_sort) <?> Misc.flip (List.fold_left refine_sort) c.Cg.cs)+  >> (fun _ -> Co.bprintflush mydebug "\nEND: refine_sort\n")+  |> Misc.maybe_apply (apply_facts c.Cg.cs) facts+++++(* API *)+let empty = create Cg.empty None++(* API *)+let meet me you = {me with m = SM.extendWith (fun _ -> (++)) me.m you.m} ++(****************************************************************)+(************* Simplify Solution Using min_read *****************)+(****************************************************************)++(* let minb s bs = min_binds s bs +              >> Printf.printf "minBinds: [%a] \n\n"  pprint_ds+ *)++let simplify s = {s with m = SM.map (min_binds s) s.m} ++(************************************************************************)+(****************** Counterexample Generation ***************************)+(************************************************************************)++ +let ctr_examples me cs ucs = +  let cx = CX.create me.tpc (read me) cs me.ctrace me.lifespan in +  List.map (CX.explain cx) ucs+++(*******************************************************************************)+(******************************** Profile/Stats ********************************)+(*******************************************************************************)++let print_m ppf s = +  SM.iter begin fun k ds ->+    ds |> (<?>) (!Co.minquals) (min_binds s)+       |> F.fprintf ppf "solution: %a := [%a] \n\n"  Sy.print k pprint_ds +  end s.m + +let print_qs ppf s = +  SM.range s.qm+  >> (fun _ -> F.fprintf ppf "//QUALIFIERS \n\n")+  |> F.fprintf ppf "%a" (Misc.pprint_many true "\n" Q.print)+(*  |> List.iter (F.fprintf ppf "%a" Q.print) + *) |> ignore++(* API *)+let print ppf s = s >> print_m ppf >> print_qs ppf |> ignore++     +let botInt qs = if List.exists (Q.pred_of_t <+> P.is_contra) qs then 1 else 0++(* API *)+let print_stats ppf me =+  let (sum, max, min, bot) =   +    (SM.fold (fun _ qs x -> (+) x (List.length qs)) me.m 0,+     SM.fold (fun _ qs x -> max x (List.length qs)) me.m min_int,+     SM.fold (fun _ qs x -> min x (List.length qs)) me.m max_int,+     SM.fold (fun _ qs x -> x + botInt qs) me.m 0) in+  let n   = SM.length me.m in+  let avg = (float_of_int sum) /. (float_of_int n) in+  F.fprintf ppf "# Vars: (Total=%d, False=%d) Quals: (Total=%d, Avg=%f, Max=%d, Min=%d)\n" +    n bot sum avg max min;+  F.fprintf ppf "#Iteration Profile = (si=%d tp=%d unsatLHS=%d emptyRHS=%d) \n"+    !(me.stat_simple_refines) !(me.stat_tp_refines)+    !(me.stat_unsatLHS) !(me.stat_emptyRHS);+  F.fprintf ppf "#Queries: umatch=%d, match=%d, ask=%d, valid=%d\n" +    !(me.stat_umatches) !(me.stat_matches) !(me.stat_imp_queries)+    !(me.stat_valid_queries);+  me.tpc#print_stats ppf++(* API *)+let save fname s =+  let oc  = open_out fname in+  let ppf = F.formatter_of_out_channel oc in+  F.fprintf ppf "@[%a@] \n" print s;+  close_out oc++let key_of_quals qs = +  qs |> List.map P.to_string +     |> List.sort compare+     |> String.concat ","++(* API *)+let mkbind = id (* Misc.flatten <+> Misc.sort_and_compact *)++(* API *)+let dump s = +  s.m +  |> SM.to_list +  |> List.map (snd <+> List.map Q.pred_of_t)+  |> Misc.groupby key_of_quals+  |> List.map begin function +     | []             -> assertf "impossible" +     | (ps::_ as pss) -> Co.bprintf mydebug "SolnCluster: preds %d = size %d \n" (List.length ps) (List.length pss)+     end+  |> ignore++
+ external/fixpoint/predAbs.mli view
@@ -0,0 +1,16 @@+(* + * 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.+ *+ *)++include SolverArch.DOMAIN
+ external/fixpoint/prepass.ml view
@@ -0,0 +1,238 @@+(*+ * 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.+ *)+++(** This module implements various constraint validation and simplification + *  prepasses *)++module BS = BNstats+module F  = Format+module A  = Ast+module Co = Constants+module P  = A.Predicate+module E  = A.Expression+module So = A.Sort+module Q  = Qualifier+module PH = A.Predicate.Hash+module Sy = A.Symbol+module SM = Sy.SMap+module C  = FixConstraint++module Misc = FixMisc +module IM = Misc.IntMap ++open Misc.Ops+let mydebug = false ++(***************************************************************)+(*********** Input Constraint & Solution Validation ************)+(***************************************************************)+++(* 3a. check that lhs/rhs have same sort *)+let phase3a = +  List.iter begin fun c ->+    let (vv1,t1,_) = C.lhs_of_t c in+    let (vv2,t2,_) = C.rhs_of_t c in+    if not (vv1 = vv2 && t1 = t2) then +      let msg = "Invalid Constraints 3a (LHS/RHS sort mismatch)" in+      let _   = Format.printf "%s in \n %a " msg (C.print_t None) c in+      raise (C.BadConstraint (C.id_of_t c, C.tag_of_t c, msg))+  end++(* 3b. check that sorts are consistent across constraints. + * DEPRECATED, due to the following counterexample.+ * Suppose you have a function:++	concatMap :: forall a, t. (a -> [t]) -> [a] -> [t]+	concatMap f [] 	   = []+	concatMap f (y:ys) = (f y) ++ (concatMap f ys)++ * Now, "f" gets a template+	+	(y:a) -> [t]++ * And inside the body of concatMap, the recursive call + * creates a function subtyping on "f" ++	... |- (y:a) -> [t] <: (y:a) -> t++ * which after splitting gives a constraint++	...,(y:a) |- t <: t			(1)++ * Now, suppose you have a call to concatMap++	baz = concatMap (\x -> [x])++ * Here, concatMap is actually "instantiated" with a + * different type variable, so at this instance,++	concatMap :: ((y:b) -> [b]) -> [b] -> [b]++ * That is, a, t are instantiated with b, b. Now, the + * application creates another function subtyping, and + * this time you end up with ++	...,(y:b) |- b <: b			(2)++let phase3b cs =+  let memo = Hashtbl.create 17 in+  List.iter begin fun c ->+    let env = C.env_of_t c in+    let id  = C.id_of_t c in+    SM.iter begin fun x (_,t,_) ->+      if Hashtbl.mem memo x then +        let xt = Hashtbl.find memo x in+        asserts (t = xt) "Invalid Constraints 3b: %d (%s is %s and %s)" +          id (Sy.to_string x) (So.to_string t) (So.to_string xt)+      else +        Hashtbl.replace memo x t+    end env+  end cs+*) ++(* 4. check that each tag has the same arity [a] *)+let phase4 a = +  List.iter begin fun c ->+    if (a = List.length (fst (C.tag_of_t c))) then () else+      raise (C.BadConstraint (C.id_of_t c, C.tag_of_t c, "Tag Arity Error"))+  end++(* 5. check that all refinements are well-formed *)+let validate_vars env msg vs = +  List.iter begin fun v -> +    if not (SM.mem v env) then +      let _ = F.printf "ERROR: out_of_scope variable %a (%s)" Sy.print v (Lazy.force msg) in+      failwith ("Out_of_scope: "^(Sy.to_string v))+  end vs ++let validate_pred env msg p = +  P.support p +  |> BS.time "validate_vars" (validate_vars env msg)++let validate_reft s env msg ((vv,t,_) as r) =+  let env = SM.add vv t env in+  r |> BS.time "preds_of_reft" (C.preds_of_reft s)+    |> List.iter (validate_pred env msg)++let phase5 s cs =+  Misc.filter begin fun c ->+    try+      let msg  = C.to_string c in+      let env  = C.senv_of_t c in+      let rhs  = C.rhs_of_t c  in+      List.iter (validate_pred env (lazy (msg^" BAD LHS"))) (C.preds_of_lhs s c);+      BS.time "valid rhs" (validate_reft s env (lazy (msg^"\n BAD RHS"))) rhs;+      true+    with ex -> begin +      let id  = C.id_of_t c           in+      let tag = C.tag_of_t c          in+      let msg = Printexc.to_string ex in+      Format.printf "Phase5: exn = %s on constraint: %a \n" msg (C.print_t None) c;+      raise (C.BadConstraint (id, tag, msg))+    end+  end cs+++(* API *)+let validate a s cs =+  cs >> phase3a +  (* >> phase3b : RJ: this invariant need not hold! *) +     >> phase4 a +     |> phase5 s+     |> (fun cs' -> asserts (List.length cs = List.length cs') "Validation")++(******************************************************************************)+(******************* Validating Well-Formedness Constraints *******************)+(******************************************************************************)++let validate_wf wfvs = +  C.reft_of_wf +  <+> C.kvars_of_reft +  <+> List.fold_left (fun wfvars (_, k) -> Sy.SSet.add k wfvars) wfvs+         (* if Sy.SSet.mem k wfvars then+           let _ = F.printf "ERROR: variable %a is checked for WF twice\n" Sy.print k in+             assert false+         else *)++(* API *)+let validate_wfs ws =+  ws |> List.fold_left begin fun (ws, wfvars) wf -> +          (wf :: ws, validate_wf wfvars wf)+        end ([], Sy.SSet.empty) +     |> fst+++(***************************************************************)+(*********************** Constraint Profiling  *****************)+(***************************************************************)++let profile_cstr im c = +  SM.fold begin fun _ (_,_,rs) ((a, b, c, d) as pfl) -> +    match rs with [] -> (a+1, b, c, d+1)  | _::_ -> begin +      List.fold_left begin fun (sz, csz, ksz, esz) r -> match r with +        | C.Conc _  -> (sz+1, csz+1, ksz, esz) +        | _         -> (sz+1, csz, ksz+1, esz)+      end pfl rs+    end+  end (C.env_of_t c) (0,0,0,0)+  |> fun pfl -> IM.add (C.id_of_t c) pfl im++let dump_profile im =+  let (tsz, tcsz, tksz, tesz) = +    IM.fold begin fun i (sz, csz, ksz, esz) (tsz, tcsz, tksz, tesz) -> +      Co.bprintf mydebug+        "ctag %d: binds=%d, cbinds=%d, kbinds=%d, ebinds=%d \n" +         i sz csz ksz esz;+      (tsz + sz, tcsz + csz, tksz + ksz, tesz + esz)+    end im (0,0,0,0) in+  Co.bprintf mydebug +    "Total binds=%d, cbinds=%d, kbinds=%d, ebinds=%d \n" +    tsz tcsz tksz tesz++let profile1 sri = +  sri |> Cindex.to_list+      |> List.fold_left profile_cstr IM.empty+      |> dump_profile++let key_of_cstr c = +  c |> C.env_of_t +    |> C.bindings_of_env +    |> List.map fst +    |> List.map Sy.to_string +    |> List.sort compare +    |> String.concat "," ++let profile2 sri =+  sri |> Cindex.to_list+      |> Misc.groupby key_of_cstr +      |> List.length+      |> fun n -> Co.bprintf mydebug "Constraint Clusters = %d \n" n++(* API *) +let profile sri = +  sri +  >> profile1 +  >> profile2 +  |> ignore +
+ external/fixpoint/prepass.mli view
@@ -0,0 +1,31 @@+(*+ * 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.+ *)+++(** This module implements various constraint validation and simplification + *  prepasses *)++val validate           : int -> FixConstraint.soln -> FixConstraint.t list -> unit +val validate_wfs       : FixConstraint.wf list -> FixConstraint.wf list+(* val true_unconstrained : FixSolution.t -> Cindex.t -> FixSolution.t+*)+val profile            : Cindex.t -> unit
+ external/fixpoint/proverArch.ml view
@@ -0,0 +1,196 @@+(*+ * 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.+ *)++(* Theories API *)++module type THEORY = sig+  type context+  type sort+  type ast+  type appDef +  type sortDef ++  val sym_sort    : appDef  -> Ast.Sort.t+  val sym_name    : appDef  -> Ast.Symbol.t+  val sort_name   : sortDef -> Ast.Sort.tycon+  val mk_thy_sort : sortDef -> context -> sort list -> sort+  val mk_thy_app  : appDef  -> context -> sort list -> ast list -> ast+  val theories    : sortDef list * appDef list+end++module type SMTSOLVER = sig+ +  (* Types *)+  type context+  type symbol +  type ast+  type sort+  type fun_decl++  (* Expression *)+  val mkAll : context -> sort array -> symbol array -> ast -> ast+  val mkApp : context -> fun_decl -> ast list -> ast+  val mkMul : context -> ast -> ast -> ast+  val mkAdd : context -> ast -> ast -> ast+  val mkSub : context -> ast -> ast -> ast+  val mkMod : context -> ast -> ast -> ast+  +  (* Predicates *)+  val mkIte     : context -> ast -> ast -> ast -> ast+  val mkInt     : context -> int -> sort -> ast+  val mkTrue    : context -> ast+  val mkFalse   : context -> ast+  val mkNot     : context -> ast -> ast+  val mkAnd     : context -> ast list -> ast+  val mkOr      : context -> ast list -> ast+  val mkImp     : context -> ast -> ast -> ast+  val mkIff     : context -> ast -> ast -> ast+  val mkRel     : context -> Ast.brel   -> ast -> ast -> ast ++  (* Conversions *)+  val astString : context -> ast -> string++  (* Set Theory Operations *)+  val mkSetSort     : context -> sort   -> sort+  val mkEmptySet    : context -> sort -> ast+  val mkSetAdd      : context -> ast -> ast -> ast+  val mkSetMem      : context -> ast -> ast -> ast+  val mkSetCup      : context -> ast -> ast -> ast+  val mkSetCap      : context -> ast -> ast -> ast+  val mkSetDif      : context -> ast -> ast -> ast+  val mkSetSub      : context -> ast -> ast -> ast++  (* Constructors *)+  val mkContext      : (string * string) array -> context+  val mkIntSort      : context -> sort+  val mkBoolSort     : context -> sort+  val var            : context -> symbol -> sort -> ast+  val boundVar       : context -> int    -> sort -> ast+  val stringSymbol   : context -> string -> symbol+  val funcDecl       : context -> symbol -> sort array -> sort -> fun_decl+  val isBool         : context -> ast -> bool+  +  (* Queries *)+  val bracket        : context -> (unit -> 'a) -> 'a+  val assertAxiom    : context -> ast -> unit+  val assertPreds    : context -> ast list -> unit+  val assertDistinct : context -> ast list -> unit+  val unsat          : context -> bool+ +  (* Stats *)+  val print_stats    : Format.formatter -> unit -> unit+end++class type prover = +  object+       (* AST/TC Interface *)+       method interp_syms :  (Ast.Symbol.t * Ast.Sort.t) list++       (* Query Interface *)+       method set_filter  :  'a . Ast.Sort.t Ast.Symbol.SMap.t +                          -> Ast.Symbol.t +                          -> Ast.pred list +                          -> ('a * Ast.pred) list +                          -> 'a list+++       (* method set_filter  :  Ast.Sort.t Ast.Symbol.SMap.t +                          -> Ast.Symbol.t +                          -> Ast.pred list +                          -> ((Ast.Symbol.t * Qualifier.t) * Ast.pred) list +                          -> (Ast.Symbol.t * Qualifier.t) list+        *)++       method print_stats : Format.formatter -> unit+  +       (* Counterexample Interface *) +       method is_contra   :  Ast.Sort.t Ast.Symbol.SMap.t +                          -> Ast.pred +                          -> bool+  ++       method unsat_suffix :  Ast.Sort.t Ast.Symbol.SMap.t +                           -> Ast.pred                     (* background predicate   *)+                           -> Ast.pred list                (* [p0,...,pn] *)+                           -> int option                   (* max j st. p /\i=j..n pi unsat *)++       (* method unsat_core  :  Ast.Sort.t Ast.Symbol.SMap.t +                          -> Ast.pred                      (* background predicate   *)+                          -> ('a * Ast.pred) list          (* [(index, killer-fact)] *)+                          -> 'a list                       (* [unsat-core-index]    *)+       *)+end++module type PROVER = sig+  +  val mkProver :  Ast.Sort.t list                      (* sorts        *) +               -> Ast.Sort.t Ast.Symbol.SMap.t         (* environment  *)+               -> Ast.pred list                        (* axioms       *) +               -> Ast.Symbol.t list                    (* distinct constants, sorts in env *)+               -> prover++(* {{{+  type t +  +  (* theory interface *)+  val is_interp   : Ast.Sort.tycon -> bool+  val interp_syms : unit -> (Ast.Symbol.t * Ast.Sort.t) list++  (* constraint solving interface *)+  val create      : Ast.Sort.t list                         (* sorts        *) +                    -> Ast.Sort.t Ast.Symbol.SMap.t         (* environment  *)+                    -> Ast.pred list                        (* axioms       *) +                    -> Ast.Symbol.t list                    (* distinct constants, sorts in env *)+                    -> t+ +  val set_filter  : t +                    -> Ast.Sort.t Ast.Symbol.SMap.t +                    -> Ast.Symbol.t +                    -> Ast.pred list +                    -> ('a * Ast.pred) list +                    -> 'a list++  val print_stats : Format.formatter -> t -> unit+  +  (* Counterexample Interface *) +  +  val is_contra   : t  +                    -> Ast.Sort.t Ast.Symbol.SMap.t +                    -> Ast.pred+                    -> bool++  val unsat_core  : t                                       +                    -> Ast.Sort.t Ast.Symbol.SMap.t +                    -> Ast.pred                             (* background predicate   *)+                    -> ('a * Ast.pred) list                 (* [(index, killer-fact)] *)+                    -> 'a list                              (* [unsat-core-index]    *)++  val unsat_suffix : t+                   -> Ast.Sort.t Ast.Symbol.SMap.t +                   -> Ast.pred                              (* background predicate   *)+                   -> Ast.pred list                         (* [p0,...,pn] *)+                   -> int option                            (* max j st. p /\i=j..n pi unsat *)+}}} *)++end++
+ external/fixpoint/qualifier.ml view
@@ -0,0 +1,366 @@+(*+ * Copyright © 2009-11 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.+ *+ *)++(**+ * This module implements a module for representing and manipulating Qualifiers.+ * *)+module Co = Constants++module F = Format++module P  = Ast.Predicate+module E  = Ast.Expression+module Sy = Ast.Symbol+module So = Ast.Sort+module Su = Ast.Subst+module SM = Sy.SMap+module SS = Sy.SSet++module Misc = FixMisc open Misc.Ops+module IM = Misc.IntMap+open Ast++let mydebug = false++(**************************************************************************)+(***************************** Qualifiers *********************************)+(**************************************************************************)+ +type q = { name    : Sy.t +         ; vvar    : Sy.t+         ; vsort   : So.t+         ; params  : (Sy.t * So.t) list+         ; pred    : pred+         ; args    : expr list option +           (* when args = Some es, es = vv'::[e1;...;en]+              where vv' is the applied vv and e1...en are the args applied to ~A1,...,~An *)+         }+++type t = q      (* to appease the functor gods. *)++let rename          = fun n -> fun q -> {q with name = n} +let name_of_t       = fun q -> q.name+let vv_of_t         = fun q -> q.vvar+let sort_of_t       = fun q -> q.vsort+let pred_of_t       = fun q -> q.pred+let params_of_t     = fun q -> q.params+let all_params_of_t = fun q -> (q.vvar, q.vsort) :: q.params++let args_of_t q  =+  let xs = all_params_of_t q |> List.map fst in+  let es = match q.args with+           | Some es -> es+           | None    -> List.map eVar xs+  in Misc.combine "Qualifier.args_of_t" xs es++let print_param ppf (x, t) =+  F.fprintf ppf "%a:%a" Sy.print x So.print t ++let print_params ppf args =+  F.fprintf ppf "%a" (Misc.pprint_many false ", " print_param) args++let print_args ppf q =+  q |> args_of_t |> List.map snd +    |> F.fprintf ppf "%a(%a)" Sy.print q.name (Misc.pprint_many false ", " E.print) + +(* API *) +let print ppf q = +  F.fprintf ppf "qualif %a(%a):%a" +    Sy.print q.name+    print_params (all_params_of_t q) +    P.print q.pred++  +(**********************************************************************)+(****************** Canonizing Wildcards (e.g. _ ---> ~A) *************)+(**********************************************************************)++let is_free params x = Misc.list_assoc_maybe x params |> Misc.maybe_bool |> not++let canonizer params =+  let fresh = Misc.mk_string_factory "~AA" |> fst |> (fun f -> f <+> Sy.of_string <+> eVar) in+  let memo  = Hashtbl.create 7 in+  function+    | (Var x, _) when is_free params x && Hashtbl.mem memo x -> +        Hashtbl.find memo x+    | (Var x, _) when is_free params x && Sy.is_wild_fresh x ->+        fresh () +    | (Var x, _) when is_free params x && Sy.is_wild_any x -> +        fresh () >> Hashtbl.replace memo x +    | e -> e ++(**************************************************************************)+(*************** Expanding Away Sets of Ops and Rels **********************)+(**************************************************************************)+ +let expand_with_list f g =+  List.map f <+> Misc.cross_flatten <+> Misc.map g++let expand_with_pair f g =+  Misc.map_pair f <+> Misc.uncurry Misc.cross_product <+> Misc.map g++let crunchExpr f e1s xs e2s =+  List.map begin fun e1 -> +    List.map begin fun e2 ->+      List.map begin fun x ->+        f (e1, x, e2)+      end xs+    end e2s+  end e1s+  |> List.flatten |> List.flatten++let rec expand_p ((p,_) as pred) = match p with +   | And ps             -> expand_ps pAnd ps+   | Or ps              -> expand_ps pOr ps+   | Not p              -> expand_p p |> List.map pNot +   | Imp (p1,p2)        -> expand_pp pImp (p1, p2)+   | Iff (p1,p2)        -> expand_pp pIff (p1, p2)+   | Forall(qs, p)      -> expand_p p |> List.map (fun p -> pForall (qs, p))+   | Bexp e             -> expand_e e |> List.map pBexp+   | MAtom (e1, rs, e2) -> let (e1s, e2s) = Misc.map_pair expand_e (e1,e2) in+                           crunchExpr pAtom e1s rs e2s+   | Atom (e1, r, e2)   -> let (e1s, e2s) = Misc.map_pair expand_e (e1,e2) in+                           crunchExpr pAtom e1s [r] e2s+   | _                  -> [pred]++and expand_e ((e,_) as expr) = match e with+   | MExp es            -> Misc.flap expand_e es+   | App (f, es)        -> expand_es (fun es -> eApp (f, es)) es+   | Bin (e1, op, e2)   -> expand_ep (fun (e1,e2) -> eBin (e1, op, e2)) (e1, e2) +   | MBin (e1, ops, e2) -> let e1s, e2s = Misc.map_pair expand_e (e1, e2) in+                           crunchExpr eBin e1s ops e2s+   | Fld (s, e)         -> expand_e e |> List.map (fun e -> eFld (s,e))+   | Cst (e, t)         -> expand_e e |> List.map (fun e -> eCst (e,t))+   | Ite (p,e1,e2)      -> let e1s, e2s = Misc.map_pair expand_e (e1, e2) in+                           let ps       = expand_p p in +                           List.map begin fun e1 ->+                             List.map begin fun e2 ->+                               List.map begin fun p ->+                                 eIte (p, e1, e2)+                               end ps+                             end e2s+                           end e1s+                           |> List.flatten |> List.flatten+   | _ -> [expr]++and expand_ps x = expand_with_list expand_p x+and expand_pp x = expand_with_pair expand_p x+and expand_es x = expand_with_list expand_e x+and expand_ep x = expand_with_pair expand_e x++(* API *)+let expand_qual q = +  expand_p q.pred+  |> List.map (fun p -> {q with pred = p})++(**************************************************************************)+(*************** Expanding Away Sets of Ops and Rels **********************)+(**************************************************************************)++let make_def_deps qnames q = +  let res = ref [] in+  let p' : pred  = P.map begin function +                         | Bexp (App (f, args),_), _ +                           when SS.mem f qnames -> res := (f, args) :: !res; pTrue +                         | p -> p +                         end id q.pred  +  in (q.name, !res) +(*  >> (fun (n, xs) ->  F.printf "qdep %a = %a \n" Sy.print n (Misc.pprint_many false ", " Sy.print) (List.map fst xs) )+  *)++let check_def_deps qm = +  List.iter begin fun (n, fargs) ->+      List.iter begin fun (f, args) ->+        match SM.finds f qm with+        | [q] -> asserts (List.length args = 1 + List.length q.params) +                 "Malformed Qualifier: %s with incorrect application of %s"+                 (Sy.to_string n) (Sy.to_string f)+        | _::_::_ -> assertf "Malformed Qualifier: %s refers to multiply defined %s" +                 (Sy.to_string n) (Sy.to_string f)+        | _   -> ()     +(*      | []  -> assertf "Malformed Qualifier: %s refers to unknown %s" +                 (Sy.to_string n) (Sy.to_string f) *)+ +      end fargs+  end++let order_by_defs qm qs = +  let is   = Misc.range 0 (List.length qs)                                      in+  let qis  = List.combine qs is                                                 in+  let i2q  = qis  |>: Misc.swap |> IM.of_list  |> Misc.flip IM.find             in+  let i2s  = i2q <+> name_of_t <+> Sy.to_string                                 in  +  let n2i  = qis  |>: Misc.app_fst name_of_t |> SM.of_list +             |> (fun m n -> SM.safeFind n m "order_by_defs") in+   +  let qnams= qs |>: name_of_t |> SS.of_list in+  let deps = qs |>: make_def_deps qnams >> check_def_deps qm                       in+  let ijs  = deps |> Misc.flap (fun (n, fargs) -> fargs |>: (fun (f,_) -> (n, f)))   +                  |> List.map (Misc.map_pair n2i)                               in+  let irs  = Fcommon.scc_rank "qualifier-deps" i2s is ijs                       in +  Misc.fsort snd irs +  |>: (fst <+> i2q)+(*   >> (F.printf "ORDERED QUALS:\n%a\n" (Misc.pprint_many true "\n" print)) *)++let expand_def qm p = match p with +  | Bexp (App (f, args),_), _ -> begin+    match SM.finds f qm with+    | _::_::_ -> assertf "Ambiguous Qualifier: %s" (Sy.to_string f)+    | [q]     -> q |> all_params_of_t+                   |> List.map fst+                   |> Misc.flip (Misc.combine ("Q.expand_def "^ (P.to_string p))) args+                   |> Su.of_list+                   |> substs_pred q.pred+    | []      -> p (* assertf "Unknown Qualifier: %s"   (Sy.to_string f)  *)+    end+  | _ -> p+    +(* this MUST precede any renaming as renaming can screw up name resolution *)+let compile_definitions qs = +  let qm   = List.fold_left (fun qm q -> SM.adds q.name [q] qm) SM.empty qs in+  let qs'  = order_by_defs qm qs                                       in +  List.fold_left begin fun qm q -> +    let q' = {q with pred = P.map (expand_def qm) id q.pred } in+    SM.adds q.name [q'] qm+  end SM.empty qs'+  |> SM.range |> Misc.flatten++(**************************************************************************)+(************************* Normalize Qualifier Sets ***********************)+(**************************************************************************)++let remove_duplicates qs = +  qs |> Misc.kgroupby (all_params_of_t <*> pred_of_t)+     |> List.map (fun (_,x::_) -> x)++let rename_qual q i = +  {q with name = Sy.suffix q.name (string_of_int i)}++let uniquely_rename qs =+  Misc.mapfold begin fun m q ->+    if SM.mem q.name m then+      let i = SM.safeFind q.name m "uniquelyRename" in+      (SM.add q.name (i+1) m, rename_qual q i)+    else +      (SM.add q.name 0 m, q)+  end SM.empty qs +  |> snd+++let check_dup t q = +  try +    let q' = Hashtbl.find t q.name in+    if (pred_of_t q' = pred_of_t q) then () else+      Format.printf "WARNING: duplicate qualifiers after normalization! (q = %a) (q' = %a)"+        print q +        print q'+  with Not_found -> ()++let qualifMap_set, qualifMap_get = +  let t = Hashtbl.create 37 in+  ( (fun qs -> Hashtbl.clear t; List.iter (fun q -> check_dup t q; Hashtbl.replace t q.name q) qs)+  , (fun n -> try Some (Hashtbl.find t  n) +              with Not_found -> (Format.printf "qualifMap_get fails on %a" Sy.print n; assert false) +    )+  )++let ticker = ref 0++(* API *)+let normalize qs =+  qs |> Misc.flap expand_qual+     |> compile_definitions+     |> remove_duplicates+     |> uniquely_rename+     >> qualifMap_set+(*   >> (fun qs -> ticker += 1; Co.logPrintf "normalize (%d):\n%a" (!ticker) +        (Misc.pprint_many true "\n" print) qs; flush stdout) *)++(* API *)+let expandPred n es = +  n |> qualifMap_get+    |> Misc.maybe_map begin fun q ->+         let xs = List.map fst <| args_of_t q in+         Misc.combine "expandPred" xs es +         |> Ast.Subst.of_list +         |> Ast.substs_pred (pred_of_t q)+       end++(*********************************************************************)+(***************************** Create ********************************)+(*********************************************************************)++let generalize_sorts vts = +  let vs, ts = List.split vts   in+  let ts'    = So.generalize ts in+  List.combine vs ts'++(* let generalize_sorts z = if !Co.gen_qual_sorts then generalize_sorts z else z *)++let close_params vts p =+  p |> P.support+    |> List.filter (Sy.is_wild <&&> is_free vts) +    |> List.map (fun x -> (x, So.t_int (* t_generic 0 causes blowup? *)))+    |> (@) vts (* Sy.SMap.of_list *)++(* API *)+let create n v t vts p =+  let p          = P.map id (canonizer vts) p    in+  let vts        = close_params vts p            in+  let (v,t)::vts = generalize_sorts ((v,t)::vts) in+  let _          = asserts (Misc.distinct vts) "Error: Q.create duplicate params %s \n" (Sy.to_string n)+  in { name   = n +     ; vvar   = v+     ; vsort  = t+     ; pred   = p+     ; params = vts +     ; args   = None }++(* DEBUG ONLY *)+let printb ppf (x, e) =+  F.fprintf ppf "%a:%a" Sy.print x E.print e +let printbs ppf args =+  F.fprintf ppf "%a" (Misc.pprint_many false ", " printb) args++(* API *)+let inst q args =+  let _   = if mydebug then F.printf "\nQ.inst with <<%a>>\n" printbs args in +  let xes = try q |> all_params_of_t |> List.map (fun (x,_) -> (x, List.assoc x args)) +            with Not_found -> +              let _ = F.printf "Error: Q.inst with bad args %a <<%a>>" print q printbs args +              in assertf "Error: Q.inst with bad args \n" +  in+  let v   = match xes with (_, (Var v, _)) :: _ -> v | _ -> assertf "Error: Q.inst with non-vvar arg" in+  let p   = xes |> Su.of_list |> Ast.substs_pred q.pred in+  { q with vvar = v; pred = p; args = Some (List.map snd xes)}+++module QSet = Misc.ESet (struct+  type t = q+  let compare q1 q2 = +    if (q1.name = q2.name) +    then compare q1.args q2.args +    else compare q1.name q2.name +end)+
+ external/fixpoint/qualifier.mli view
@@ -0,0 +1,53 @@+(*+ * Copyright © 2009-11 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.+ *+ *)++(**+ * This module implements a module for representing and manipulating Qualifiers.+ * *)++type t +module QSet : FixMisc.ESetType with type elt = t++val create          :  Ast.Symbol.t +                    -> Ast.Symbol.t +                    -> Ast.Sort.t +                    -> (Ast.Symbol.t * Ast.Sort.t) list +                    -> Ast.pred +                    -> t ++val name_of_t       : t -> Ast.Symbol.t+val vv_of_t         : t -> Ast.Symbol.t+val pred_of_t       : t -> Ast.pred+val sort_of_t       : t -> Ast.Sort.t+val params_of_t     : t -> (Ast.Symbol.t * Ast.Sort.t) list (* Ast.Sort.t Ast.Symbol.SMap.t *)+val all_params_of_t : t -> (Ast.Symbol.t * Ast.Sort.t) list +val vv_of_t         : t -> Ast.Symbol.t+val args_of_t       : t -> (Ast.Symbol.t * Ast.expr) list+val normalize       : t list -> t list+val inst            : t -> (Ast.Symbol.t * Ast.expr) list -> t+val print           : Format.formatter -> t -> unit+val print_args      : Format.formatter -> t -> unit+val expandPred      : Ast.Symbol.t -> Ast.expr list -> Ast.pred option++
+ external/fixpoint/smtLIB2.ml view
@@ -0,0 +1,419 @@+(*+ * Copyright © 2008 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.+ *)++(********************************************************************************)+(*********** This module implements the binary interface with SMTLIB2   *********)+(*********** http://www.smt-lib.org/                                    *********)+(*********** http://www.grammatech.com/resource/smt/SMTLIBTutorial.pdf  *********)+(********************************************************************************)+++module H  = Hashtbl+module F  = Format+module Co = Constants+module BS = BNstats+module A  = Ast+module Sy = A.Symbol+module So = A.Sort+module SM = Sy.SMap+module P  = A.Predicate+module E  = A.Expression+module Misc = FixMisc open Misc.Ops+module SSM = Misc.StringMap+module Th = Theories++module SMTLib2 : ProverArch.SMTSOLVER = struct++let spr = Printf.sprintf++let mydebug = false ++let nb_unsat     = ref 0+let nb_pop       = ref 0+let nb_push      = ref 0++(***************************************************************)+(********************** Types **********************************)+(***************************************************************)++type symbol   = string  (* Sy.t *)+type sort     = string  (* So.t *)+type ast      = string  (* E of A.expr | P of A.pred *) +type fun_decl = symbol ++type cmd      = Push+              | Pop+              | CheckSat+              | Declare     of symbol * sort list * sort+              | AssertCnstr of ast+              | Distinct    of ast list (* {v: ast list | (len v) >= 2} *)++type resp     = Ok +              | Sat +              | Unsat +              | Unknown+              | Error of string++type solver   = Z3 | Mathsat | Cvc4 ++type context  = { cin  : in_channel+                ; cout : out_channel+                ; clog : out_channel }++let respString = function+  | Ok      -> "Ok"+  | Sat     -> "Sat"+  | Unsat   -> "Unsat"+  | Unknown -> "Unknown"+  | Error s -> "Error " ^ s++let solverString = function+  | Z3      -> "z3"+  | Mathsat -> "mathsat"+  | Cvc4    -> "cvc4"++(*******************************************************************)+(*********************** Set Theory ********************************)+(*******************************************************************)++let elt = "Elt"+let set = "Set"+let emp = "smt_set_emp"+let add = "smt_set_add"+let cup = "smt_set_cup"+let cap = "smt_set_cap"+let mem = "smt_set_mem"+let dif = "smt_set_dif"+let sub = "smt_set_sub"+let com = "smt_set_com"++(* +   (define-fun smt_set_emp () Set ((as const Set) false))+   (define-fun smt_set_mem ((x Elt) (s Set)) Bool (select s x))+   (define-fun smt_set_add ((s Set) (x Elt)) Set  (store s x true))+   (define-fun smt_set_cap ((s1 Set) (s2 Set)) Set ((_ map and) s1 s2))+   (define-fun smt_set_cup ((s1 Set) (s2 Set)) Set ((_ map or) s1 s2))+   (define-fun smt_set_com ((s Set)) Set ((_ map not) s))+   (define-fun smt_set_dif ((s1 Set) (s2 Set)) Set (smt_set_cap s1 (smt_set_com s2)))+   (define-fun smt_set_sub ((s1 Set) (s2 Set)) Bool (= smt_set_emp (smt_set_dif s1 s2)))+*)++(* z3 specific *)+let z3_preamble +  = [ spr "(define-sort %s () Int)"+        elt+    ; spr "(define-sort %s () (Array %s Bool))" +        set elt+    ; spr "(define-fun %s () %s ((as const %s) false))" +        emp set set +    ; spr "(define-fun %s ((x %s) (s %s)) Bool (select s x))"+        mem elt set+    ; spr "(define-fun %s ((s %s) (x %s)) %s (store s x true))"+        add set elt set+    ; spr "(define-fun %s ((s1 %s) (s2 %s)) %s ((_ map or) s1 s2))"+        cup set set set+    ; spr "(define-fun %s ((s1 %s) (s2 %s)) %s ((_ map and) s1 s2))"+        cap set set set+    ; spr "(define-fun %s ((s %s)) %s ((_ map not) s))"+        com set set+    ; spr "(define-fun %s ((s1 %s) (s2 %s)) %s (%s s1 (%s s2)))"+        dif set set set cap com+    ; spr "(define-fun %s ((s1 %s) (s2 %s)) Bool (= %s (%s s1 s2)))"+        sub set set emp dif +    ] + +let smtlib_preamble +  = [ spr "(set-logic QF_UFLIA)"+    ; spr "(define-sort %s () Int)"       elt+    ; spr "(define-sort %s () Int)"       set +    ; spr "(declare-fun %s () %s)"        emp set+    ; spr "(declare-fun %s (%s %s) %s)"   add set elt set+    ; spr "(declare-fun %s (%s %s) %s)"   cup set set set+    ; spr "(declare-fun %s (%s %s) %s)"   cap set set set+    ; spr "(declare-fun %s (%s %s) %s)"   dif set set set+    ; spr "(declare-fun %s (%s %s) Bool)" sub set set +    ; spr "(declare-fun %s (%s %s) Bool)" mem elt set +   +    (* HIDE? +    ; spr "(assert (forall ((x %s)) (not (%s x %s))))" +          elt mem emp+    ; spr "(assert (forall ((x %s) (s1 %s) (s2 %s)) +            (= (%s x (%s s1 s2)) (or (%s x s1) (%s x s2)))))"+            elt set set mem cup mem mem+    ; spr "(assert (forall ((x %s) (s1 %s) (s2 %s)) +            (= (%s x (%s s1 s2)) (and (%s x s1) (%s x s2)))))"+            elt set set mem cap mem mem+    ; spr "(assert (forall ((x %s) (s1 %s) (s2 %s)) +            (= (%s x (%s s1 s2)) (and (%s x s1) (not (%s x s2))))))"+            elt set set mem dif mem mem+    ; spr "(assert (forall ((x %s) (s %s) (y %s)) +            (= (%s x (%s s y)) (or (%s x s) (= x y)))))"+            elt set elt mem add mem +    *)+    ] +++let mkSetSort _ _  = set+let mkEmptySet _ _ = emp+let mkSetAdd _ s x = spr "(%s %s %s)" add s x+let mkSetMem _ x s = spr "(%s %s %s)" mem x s +let mkSetCup _ s t = spr "(%s %s %s)" cup s t+let mkSetCap _ s t = spr "(%s %s %s)" cap s t+let mkSetDif _ s t = spr "(%s %s %s)" dif s t+let mkSetSub _ s t = spr "(%s %s %s)" sub s t++(******************************************************************)+(**************** SMT IO ******************************************)+(** https://raw.github.com/ravichugh/djs/master/src/zzz.ml ********)+(******************************************************************)+        +(* "z3 -smt2 -in"                   *)+(* "z3 -smtc SOFT_TIMEOUT=1000 -in" *)+(* "z3 -smtc -in MBQI=false"        *)++let smt_cmd = function+  | Z3      -> "z3 -smt2 -in MODEL=false MODEL.PARTIAL=true smt.mbqi=false auto-config=false"+  | Mathsat -> "mathsat -input=smt2"+  | Cvc4    -> "cvc4 --incremental -L smtlib2"++let smt_preamble = function+  | Z3 -> z3_preamble+  | _  -> smtlib_preamble +++let smt_file = fun () -> !Co.out_file ^ ".smt2"++let smt_write_raw me s = +  output_now me.clog s; +  output_now me.cout s++let smt_read_raw me = +  input_line me.cin++let smt_write me ?nl:(nl=true) ?tab:(tab=false) s =+  let pre = if tab then "    " else "" in+  let suf = if nl  then "\n"   else "" in+  smt_write_raw me (pre^s^suf)++let rec smt_read me+  = match smt_read_raw me with+  | "sat"     -> Sat+  | "unsat"   -> Unsat+  | "success" -> smt_read me +  | "unknown" -> Unknown+  | s         -> Error s+++(* val interact : context -> cmd -> resp *)+let interact me = function +  | Declare (x, ts, t) -> +      let _ = smt_write me <| spr "(declare-fun %s (%s) %s)" x (String.concat " " ts) t in+      Ok +  | Push -> +      let _ = smt_write me <|     "(push 1)" in+      Ok+  | Pop -> +      let _ = smt_write me <|     "(pop 1)" in+      Ok+  | CheckSat -> +      let _ = smt_write me <|     "(check-sat)" in+      smt_read me +  | AssertCnstr a -> +      let _ = smt_write me <| spr "(assert %s)" a in+      Ok+  | Distinct az -> +      let _ = smt_write me <| spr "(assert (distinct %s))" (String.concat " " az) in+      Ok+++(* API *)+let smt_decl me x ts t +  = match interact me (Declare (x, ts, t)) with+  | Ok -> ()+  | _  -> assertf "crash: SMTLIB2 smt_decl"++(* API *)+let smt_push me +  = match interact me Push with+  | Ok -> incr nb_push; () +  | _  -> assertf "crash: SMTLIB2 smt_push"++(* API *)+let smt_pop me +  = match interact me Pop with+  | Ok -> incr nb_pop; () +  | _  -> assertf "crash: SMTLIB2 smt_pop"++(* API *)+let smt_check_unsat me +  = match interact me CheckSat with+  | Unsat   -> true+  | Sat     -> false+  | Unknown -> false +  | e       -> assertf "crash: SMTLIB2 smt_check_unsat %s" (respString e)++(* API *)+let smt_assert_cnstr me p +  = match interact me (AssertCnstr p) with+  | Ok -> ()+  | _  -> assertf "crash: SMTLIB2 smt_assert_cnstr"++(* API *)+let smt_assert_distinct me az+  = match interact me (Distinct az) with+  | Ok -> ()+  | _  -> assertf "crash: SMTLIB2 smt_assert_distinct"++let solver () =+  match !Co.smt_solver with+    | Some "z3"      -> Z3+    | Some "mathsat" -> Mathsat+    | Some "cvc4"    -> Cvc4+    | Some str       -> assertf "ERROR: fixpoint does not yet support SMTSOLVER: %s" str+    | None           -> assertf "ERROR: undefined solver for smtLIB2"++let mkContext _ =+  let s      = solver ()                          in+  let ci, co = Unix.open_process <| smt_cmd s     in+  let cl     = smt_file () |> open_out            in+  let pre    = smt_preamble s                     in+  let ctx    = { cin = ci; cout = co; clog = cl } in+  let _      = List.iter (smt_write ctx) pre      in+  ctx++(***********************************************************************)+(*********************** AST Constructors ******************************)+(***********************************************************************)++let stringSymbol _ s = s+let astString _ a    = a +let isBool c a       = failwith "TODO:SMTLib2.isBool"+let boundVar me i t  = failwith "TODO:SMTLib2.boundVar"++let var me x t =+  let _ = smt_decl me x [] t in  +  x ++let funcDecl me s ta t =+  let _ = smt_decl me s (Array.to_list ta) t in+  s++let mkIntSort _    = "Int"          +let mkBoolSort _   = "Bool"         ++let mkInt _ i _    = string_of_int i+let mkTrue _       = "true"+let mkFalse _      = "false" ++let mkAll _ _ _ _  = failwith "TODO:SMTLib2.mkAll"++let mkRel _ r a1 a2 +  = match r with +  | A.Eq -> spr "(= %s %s)"       a1 a2 +  | A.Ne -> spr "(not (= %s %s))" a1 a2 +  | A.Gt -> spr "(>  %s %s)"      a1 a2 +  | A.Ge -> spr "(>= %s %s)"      a1 a2 +  | A.Lt -> spr "(<  %s %s)"      a1 a2 +  | A.Le -> spr "(<= %s %s)"      a1 a2 ++++let mkApp _ f = function+  | [] -> f +  | az -> spr "(%s %s)" f (String.concat " " az)++let opStr = function+  | A.Plus  -> "+"+  | A.Minus -> "-"+  | A.Times -> "*"+  | A.Div   -> "/"+  | A.Mod   -> "mod"++let mkOp op a1 a2+  = spr "(%s %s %s)" (opStr op) a1 a2+  +let mkMul _ = mkOp A.Times  +let mkAdd _ = mkOp A.Plus+let mkSub _ = mkOp A.Minus+let mkMod _ = mkOp A.Mod++let mkIte _ a1 a2 a3 +  = spr "(ite %s %s %s)" a1 a2 a3++let mkNot _ a +  = spr "(not %s)" a ++let mkAnd _ az  +  = spr "(and %s)" (String.concat " " az) ++let mkOr _ az +  = spr "(or %s)" (String.concat " " az) ++let mkImp _ a1 a2 +  = spr "(=> %s %s)" a1 a2 ++let mkIff _ a1 a2 +  = spr "(= %s %s)" a1 a2 ++(*******************************************************************)+(*********************** Queries ***********************************)+(*******************************************************************)++let us_ref = ref 0++(* API *)+let unsat me =  +  let _  = if mydebug then begin +              Printf.printf "[%d] UNSAT 1 " (us_ref += 1);+              flush stdout+           end +  in+  let rv = BS.time "SMT.check_unsat" smt_check_unsat me               in+  let _  = if mydebug then (Printf.printf "UNSAT 2 \n"; flush stdout) in+  let _  = if rv then ignore (nb_unsat += 1) in +  rv++(* API *)+let assertAxiom me p+  = (* Co.bprintf mydebug "@[Pushing axiom %s@]@." (astString me p); *)+    BS.time "assertAxiom" (smt_assert_cnstr me) p;+    asserts (not (unsat me)) "ERROR: Axiom makes background theory inconsistent!"++(* API *)+let assertDistinct me = function +  | ((x1::x2::_) as az) -> smt_assert_distinct me az+  | _                   -> ()++(* API *)+let bracket me f +  = Misc.bracket (fun _ -> smt_push me) (fun _ -> smt_pop me) f++(* API *)+let assertPreds me ps +  = List.iter (fun p -> BS.time "assertPreds" (smt_assert_cnstr me) p) ps++(* API *)+let print_stats ppf () =+  F.fprintf ppf "SMT stats: pushes=%d, pops=%d, unsats=%d \n" +    !nb_push !nb_pop !nb_unsat++end
+ external/fixpoint/smtZ3.mem.ml view
@@ -0,0 +1,169 @@+(*+ * Copyright © 2008 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.+ *)++(* This file is part of the LiquidC Project *)++module H  = Hashtbl+module F  = Format+module Co = Constants+module BS = BNstats+module A  = Ast+module Sy = A.Symbol+module So = A.Sort+module SM = Sy.SMap+module P  = A.Predicate+module E  = A.Expression+module Misc = FixMisc open Misc.Ops+module SSM = Misc.StringMap+module Th = Theories++module SMTZ3 : ProverArch.SMTSOLVER = struct++let mydebug = false ++(********************************************************************************)+(************ SMT INTERFACE *****************************************************) +(********************************************************************************)++let nb_unsat     = ref 0+let nb_pop       = ref 0+let nb_push      = ref 0++type context     = Z3.context+type symbol      = Z3.symbol+type sort        = Z3.sort+type ast         = Z3.ast+type fun_decl    = Z3.func_decl ++let var          = Z3.mk_const +let boundVar     = Z3.mk_bound+let stringSymbol = Z3.mk_string_symbol +let funcDecl     = Z3.mk_func_decl++let isBool c a =+  a |> Z3.get_sort c   +    |> Z3.sort_to_string c+    |> (=) "bool"++let isInt me a =+  a |> Z3.get_sort me   +    |> Z3.sort_to_string me+    |> (=) "int"++let mkAll me = Z3.mk_forall me 0 [||]++let mkRel c r a1 a2 +  = match r with+  | A.Eq -> Z3.mk_eq c          a1  a2  +  | A.Ne -> Z3.mk_distinct c [| a1; a2 |]+  | A.Gt -> Z3.mk_gt c          a1  a2 +  | A.Ge -> Z3.mk_ge c          a1  a2+  | A.Lt -> Z3.mk_lt c          a1  a2+  | A.Le -> Z3.mk_le c          a1  a2++let mkApp c f az  = Z3.mk_app c f (Array.of_list az)+let mkMul c a1 a2 = Z3.mk_mul c [| a1; a2|]+let mkAdd c a1 a2 = Z3.mk_add c [| a1; a2|]+let mkSub c a1 a2 = Z3.mk_sub c [| a1; a2|]+let mkMod = Z3.mk_mod +let mkIte = Z3.mk_ite++let mkInt      = Z3.mk_int +let mkTrue     = Z3.mk_true+let mkFalse    = Z3.mk_false+let mkNot      = Z3.mk_not+let mkAnd c az = Z3.mk_and c (Array.of_list az) +let mkOr c az  = Z3.mk_or c  (Array.of_list az) +let mkImp      = Z3.mk_implies+let mkIff      = Z3.mk_iff+let astString  = Z3.ast_to_string +let mkIntSort  = Z3.mk_int_sort  +let mkBoolSort = Z3.mk_bool_sort +let mkSetSort  = Z3.mk_set_sort  +let mkEmptySet = Z3.mk_empty_set +let mkSetAdd   = Z3.mk_set_add+let mkSetMem   = Z3.mk_set_member +let mkSetCup   = fun me s1 s2 -> Z3.mk_set_union     me [| s1; s2 |]+let mkSetCap   = fun me s1 s2 -> Z3.mk_set_intersect me [| s1; s2 |]+let mkSetDif   = Z3.mk_set_difference+let mkSetSub   = Z3.mk_set_subset +let mkContext  = Z3.mk_context_x ++(*********************************************************)++let z3push me =+  let _ = nb_push += 1 in+  let _ = BS.time "Z3.push" Z3.push me in+  () ++let z3pop me =+  let _ = incr nb_pop in+  BS.time "Z3.pop" (Z3.pop me) 1 +++(* Z3 API *)+let unsat =  +  let us_ref = ref 0 in+  fun me ->+    let _  = if mydebug then (Printf.printf "[%d] UNSAT 1 " (us_ref += 1); flush stdout) in+    let rv = (BS.time "Z3.check" Z3.check me) = Z3.L_FALSE in+    let _  = if mydebug then (Printf.printf "UNSAT 2 \n"; flush stdout) in+    let _  = if rv then ignore (nb_unsat += 1) in +    rv++(* API *)+let assertAxiom me p =+  Co.bprintf mydebug "@[Pushing axiom %s@]@." (astString me p); +  BS.time "Z3 assert axiom" (Z3.assert_cnstr me) p;+  asserts (not (unsat me)) "ERROR: Axiom makes background theory inconsistent!"++(* API *)+let assertDistinct me xs =+  xs |> Array.of_list |> Z3.mk_distinct me |> assertAxiom me++(* Z3 API *)+let bracket me f = Misc.bracket (fun _ -> z3push me) (fun _ -> z3pop me) f++(* Z3 API *)+let assertPreds me ps = List.iter (fun p -> BS.time "Z3.ass_cst" (Z3.assert_cnstr me) p) ps++(* Z3 API *)+let valid me p = +  bracket me begin fun _ ->+    assertPreds me [Z3.mk_not me p];+    BS.time "unsat" unsat me +  end++(* Z3 API *)+let contra me p = +  bracket me begin fun _ ->+    assertPreds me [p];+    BS.time "unsat" unsat me +  end++(* API *)+let print_stats ppf () =+  F.fprintf ppf+    "SMT stats: pushes=%d, pops=%d, unsats=%d \n" +    !nb_push !nb_pop !nb_unsat ++end
+ external/fixpoint/smtZ3.ml view
@@ -0,0 +1,169 @@+(*+ * Copyright © 2008 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.+ *)++(* This file is part of the LiquidC Project *)++module H  = Hashtbl+module F  = Format+module Co = Constants+module BS = BNstats+module A  = Ast+module Sy = A.Symbol+module So = A.Sort+module SM = Sy.SMap+module P  = A.Predicate+module E  = A.Expression+module Misc = FixMisc open Misc.Ops+module SSM = Misc.StringMap+module Th = Theories++module SMTZ3 : ProverArch.SMTSOLVER = struct++let mydebug = false ++(********************************************************************************)+(************ SMT INTERFACE *****************************************************) +(********************************************************************************)++let nb_unsat     = ref 0+let nb_pop       = ref 0+let nb_push      = ref 0++type context     = Z3.context+type symbol      = Z3.symbol+type sort        = Z3.sort+type ast         = Z3.ast+type fun_decl    = Z3.func_decl ++let var          = Z3.mk_const +let boundVar     = Z3.mk_bound+let stringSymbol = Z3.mk_string_symbol +let funcDecl     = Z3.mk_func_decl++let isBool c a =+  a |> Z3.get_sort c   +    |> Z3.sort_to_string c+    |> (=) "bool"++let isInt me a =+  a |> Z3.get_sort me   +    |> Z3.sort_to_string me+    |> (=) "int"++let mkAll me = Z3.mk_forall me 0 [||]++let mkRel c r a1 a2 +  = match r with+  | A.Eq -> Z3.mk_eq c          a1  a2  +  | A.Ne -> Z3.mk_distinct c [| a1; a2 |]+  | A.Gt -> Z3.mk_gt c          a1  a2 +  | A.Ge -> Z3.mk_ge c          a1  a2+  | A.Lt -> Z3.mk_lt c          a1  a2+  | A.Le -> Z3.mk_le c          a1  a2++let mkApp c f az  = Z3.mk_app c f (Array.of_list az)+let mkMul c a1 a2 = Z3.mk_mul c [| a1; a2|]+let mkAdd c a1 a2 = Z3.mk_add c [| a1; a2|]+let mkSub c a1 a2 = Z3.mk_sub c [| a1; a2|]+let mkMod = Z3.mk_mod +let mkIte = Z3.mk_ite++let mkInt      = Z3.mk_int +let mkTrue     = Z3.mk_true+let mkFalse    = Z3.mk_false+let mkNot      = Z3.mk_not+let mkAnd c az = Z3.mk_and c (Array.of_list az) +let mkOr c az  = Z3.mk_or c  (Array.of_list az) +let mkImp      = Z3.mk_implies+let mkIff      = Z3.mk_iff+let astString  = Z3.ast_to_string +let mkIntSort  = Z3.mk_int_sort  +let mkBoolSort = Z3.mk_bool_sort +let mkSetSort  = Z3.mk_set_sort  +let mkEmptySet = Z3.mk_empty_set +let mkSetAdd   = Z3.mk_set_add+let mkSetMem   = Z3.mk_set_member +let mkSetCup   = fun me s1 s2 -> Z3.mk_set_union     me [| s1; s2 |]+let mkSetCap   = fun me s1 s2 -> Z3.mk_set_intersect me [| s1; s2 |]+let mkSetDif   = Z3.mk_set_difference+let mkSetSub   = Z3.mk_set_subset +let mkContext  = Z3.mk_context_x ++(*********************************************************)++let z3push me =+  let _ = nb_push += 1 in+  let _ = BS.time "Z3.push" Z3.push me in+  () ++let z3pop me =+  let _ = incr nb_pop in+  BS.time "Z3.pop" (Z3.pop me) 1 +++(* Z3 API *)+let unsat =  +  let us_ref = ref 0 in+  fun me ->+    let _  = if mydebug then (Printf.printf "[%d] UNSAT 1 " (us_ref += 1); flush stdout) in+    let rv = (BS.time "Z3.check" Z3.check me) = Z3.L_FALSE in+    let _  = if mydebug then (Printf.printf "UNSAT 2 \n"; flush stdout) in+    let _  = if rv then ignore (nb_unsat += 1) in +    rv++(* API *)+let assertAxiom me p =+  Co.bprintf mydebug "@[Pushing axiom %s@]@." (astString me p); +  BS.time "Z3 assert axiom" (Z3.assert_cnstr me) p;+  asserts (not (unsat me)) "ERROR: Axiom makes background theory inconsistent!"++(* API *)+let assertDistinct me xs =+  xs |> Array.of_list |> Z3.mk_distinct me |> assertAxiom me++(* Z3 API *)+let bracket me f = Misc.bracket (fun _ -> z3push me) (fun _ -> z3pop me) f++(* Z3 API *)+let assertPreds me ps = List.iter (fun p -> BS.time "Z3.ass_cst" (Z3.assert_cnstr me) p) ps++(* Z3 API *)+let valid me p = +  bracket me begin fun _ ->+    assertPreds me [Z3.mk_not me p];+    BS.time "unsat" unsat me +  end++(* Z3 API *)+let contra me p = +  bracket me begin fun _ ->+    assertPreds me [p];+    BS.time "unsat" unsat me +  end++(* API *)+let print_stats ppf () =+  F.fprintf ppf+    "SMT stats: pushes=%d, pops=%d, unsats=%d \n" +    !nb_push !nb_pop !nb_unsat ++end
+ external/fixpoint/smtZ3.nomem.ml view
@@ -0,0 +1,81 @@+(*+ * Copyright © 2008 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.+ *)++(********************************************************************************)+(** DUMMY SMT-Z3 Solver (for non Z3MEM builds) **********************************)+(********************************************************************************)++let assertf = FixMisc.Ops.assertf+let msg     = "This build is NOT linked against Z3. Please rebuild with Z3MEM=true. Only possible on linux"++module SMTZ3 : ProverArch.SMTSOLVER = struct++type context     = ()+type symbol      = ()   +type sort        = () +type ast         = () +type fun_decl    = ()  ++let var          _   = failwith msg +let boundVar     _   = failwith msg+let stringSymbol _   = failwith msg+let funcDecl     _   = failwith msg+let isBool _         = failwith msg+let isInt _          = failwith msg+let mkAll _          = failwith msg+let mkRel _          = failwith msg+let mkApp _          = failwith msg  +let mkMul _          = failwith msg+let mkAdd _          = failwith msg+let mkSub _          = failwith msg+let mkMod _          = failwith msg+let mkIte _          = failwith msg+let mkInt _          = failwith msg  +let mkTrue _         = failwith msg+let mkFalse _        = failwith msg+let mkNot _          = failwith msg+let mkAnd _          = failwith msg +let mkOr _           = failwith msg +let mkImp _          = failwith msg +let mkIff _          = failwith msg+let astString _      = failwith msg+let mkIntSort _      = failwith msg+let mkBoolSort _     = failwith msg+let mkSetSort _      = failwith msg+let mkEmptySet _     = failwith msg+let mkSetAdd _       = failwith msg+let mkSetMem _       = failwith msg+let mkSetCup _       = failwith msg+let mkSetCap _       = failwith msg+let mkSetDif _       = failwith msg+let mkSetSub _       = failwith msg+let mkContext _      = failwith msg+let unsat _          = failwith msg  +let assertAxiom _    = failwith msg+let assertDistinct _ = failwith msg+let bracket _        = failwith msg+let assertPreds _    = failwith msg+let valid _          = failwith msg +let contra _         = failwith msg+let print_stats _    = failwith msg++end
+ external/fixpoint/solve.ml view
@@ -0,0 +1,271 @@+(*+ * 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.+ *)+++(** This module implements a fixpoint solver *)+module BS = BNstats+module F  = Format+module A  = Ast+module Co = Constants+module P  = A.Predicate+module E  = A.Expression+module So = A.Sort+module Su = A.Subst+module Q  = Qualifier+module Sy = A.Symbol+module SM = Sy.SMap+module C  = FixConstraint+module Ci = Cindex+module PP = Prepass+module Cg = FixConfig+(* module TP   = TpNull.Prover *)+module Misc = FixMisc open Misc.Ops+++let mydebug = false ++type t = {+   sri : Ci.t+ ; ws  : C.wf list+ ; tt  : Timer.t+   + (* Stats *)+ ; stat_refines        : int ref+ ; stat_cfreqt         : (int * bool, int) Hashtbl.t +}++module type SOLVER = sig+  type soln+  type bind+  val create    : bind Cg.cfg -> FixConstraint.soln option -> (t * soln)+  val solve     : t -> soln -> (soln * (FixConstraint.t list) * Counterexample.cex list) +  val save      : string -> t -> soln -> unit +  val read      : soln -> FixConstraint.soln+  val min_read  : soln -> FixConstraint.soln+  val read_bind : soln -> Ast.Symbol.t -> bind+  val cone      : t -> FixConstraint.id -> FixConstraint.tag Ast.Cone.t+  (* val meet   : soln -> soln -> soln  *)+end++module Make (Dom : SolverArch.DOMAIN) = struct+  type soln     = Dom.t+  type bind     = Dom.bind+  let min_read  = Dom.min_read+  let read      = Dom.read+  let read_bind = Dom.read_bind  +(* let meet = Dom.meet *)+++(*************************************************************)+(********************* Stats *********************************)+(*************************************************************)++let hashtbl_incr_frequency t k = +  let n = try Hashtbl.find t k with Not_found -> 0 in+  Hashtbl.replace t k (n+1)++let hashtbl_print_frequency t = +  Misc.hashtbl_to_list t +  |> Misc.kgroupby (fun ((k,b),n) -> (n,b))+  |> List.map (fun ((n,b), xs) -> (n, b, List.map (fst <+> fst) xs))+  |> List.sort compare+  |> List.iter begin fun (n, b, xs) -> +       Co.bprintf mydebug "ITERFREQ: %d times (ch = %b) %d constraints %s \n"+         n b (List.length xs) (Misc.map_to_string string_of_int xs) +     end++(***************************************************************)+(************************ Debugging/Stats **********************)+(***************************************************************)++let print_constr_stats ppf cs = +  let cn   = List.length cs in+  let scn  = List.length (List.filter C.is_simple cs) in+  F.fprintf ppf "#Constraints: %d (simple = %d) \n" cn scn++let print_solver_stats ppf me = +  print_constr_stats ppf (Ci.to_list me.sri); +  F.fprintf ppf "#Iterations = %d\n" !(me.stat_refines);+  F.fprintf ppf "Iteration Frequency: \n"; +    hashtbl_print_frequency me.stat_cfreqt;+  F.fprintf ppf "Iteration Periods: @[%a@] \n" Timer.print me.tt++let dump me s = +  Co.bprintf mydebug "%a \n" print_solver_stats me;+  Co.bprintf mydebug "%a \n" Dom.print_stats s;+  Dom.dump s++let log_iter_stats me s =+  (if Co.ck_olev Co.ol_insane then Co.bprintf mydebug "log_iter_stats\n%a" Dom.print s);+  (if !(me.stat_refines) mod 100 = 0 then +     let msg = Printf.sprintf "\n num refines=%d" !(me.stat_refines) in +     let _   = Timer.log_event me.tt (Some msg)                      in+     let _   = Co.bprintf mydebug "%s\n %a\n" msg Dom.print_stats s  in+     let _   = Format.print_flush ()                                 in+     ());+  ()++(***************************************************************)+(******************** Iterative Refinement *********************)+(***************************************************************)++let is_solved s c = +  let sol = read s in+  c |> C.rhs_of_t +    |> C.kvars_of_reft+    |> List.map (sol <.> snd)+    |> List.for_all ((=) [])++let refine_constraint s c =+  try BS.time "refine" (Dom.refine s) c with ex ->+    let _ = F.printf "constraint refinement fails with: %s\n" (Printexc.to_string ex) in+    let _ = F.printf "Failed on constraint:\n%a\n" (C.print_t None) c in+    assert false++let update_worklist me s' c w' = +  c |> Ci.deps me.sri +    |> Misc.filter (not <.> is_solved s')+    |> Ci.wpush me.sri w'++let rec acsolve me w s =+  let _ = log_iter_stats me s in+  let _ = Misc.display_tick () in+  match Ci.wpop me.sri w with +  | (None,_) -> +      let _ = Timer.log_event me.tt (Some "Finished") in +      s +  | (Some c, w') ->+      let _        = me.stat_refines += 1             in +      let (ch, s') = BS.time "refine" (refine_constraint s) c in+      let _        = hashtbl_incr_frequency me.stat_cfreqt (C.id_of_t c, ch) in  +      let _        = Co.bprintf mydebug "iter=%d id=%d ch=%b %a \n" +                      !(me.stat_refines) (C.id_of_t c) ch C.print_tag (C.tag_of_t c) in+      let w''      = if ch then update_worklist me s' c w' else w' in +      acsolve me w'' s' ++let unsat_constraints me s =+  me.sri |> Ci.to_list |> List.filter (Dom.unsat s)++let simplify_solution me s = Dom.simplify s+++(***************************************************************)+(****************** Pruning Unconstrained Vars *****************)+(***************************************************************)++let rhs_ks cs =+  cs  |> Misc.flap (Misc.compose C.kvars_of_reft C.rhs_of_t)+      |> List.fold_left (fun rhss (_, kv) -> Sy.SSet.add kv rhss) Sy.SSet.empty++let unconstrained_kvars cs =+  let rhss = rhs_ks cs in+  cs  |> Misc.flap C.kvars_of_t+      |> List.map snd+      |> List.filter (fun kv -> not (Sy.SSet.mem kv rhss))++let true_unconstrained sri s =+  sri |> Ci.to_list +      |> unconstrained_kvars+      |> Dom.top s++(* +let true_unconstrained sri s = +  if !Co.true_unconstrained then +    let _ = Co.logPrintf "Fixpoint: Pruning unconstrained kvars \n" +    in true_unconstrained sri s+  else +    let _ = Co.logPrintf "Fixpoint: NOT Pruning unconstrained kvars \n" +    in s+*)++(* API *)+let solve me s = +  let _  = Co.bprintflush mydebug "Fixpoint: Validating Initial Solution \n" in+  (* let _ = F.printf "create: SOLUTION \n %a \n" Dom.print s in *)+  let _  = BS.time "Prepass.profile" PP.profile me.sri in+  let _  = Co.bprintflush mydebug "\nBEGIN: Fixpoint: Trueing Unconstrained Variables \n" in+  let s  = s |> (!Co.true_unconstrained <?> BS.time "Prepass.true_unconstr" (true_unconstrained me.sri)) in+  let _  = Co.bprintflush mydebug "\nDONE: Fixpoint: Trueing Unconstrained Variables \n" in+  (* let _ = F.printf "create: SOLUTION1 \n %a \n" Dom.print s in *)+  let _  = Co.bprintflush mydebug "\nBEGIN: Fixpoint: Initialize Worklist \n" in+  let w  = BS.time "Cindex.winit" Ci.winit me.sri in +  let _  = Co.bprintflush mydebug "\nDONE: Fixpoint: Initialize Worklist \n" in+  let _  = Co.bprintflush mydebug "\nBEGIN: Fixpoint Refinement Loop \n" in+  let s  = BS.time "Solve.acsolve"  (acsolve me w) s in+  let _  = Co.bprintflush mydebug "\nDONE: Fixpoint Refinement Loop \n" in+  (* let _ = F.printf "create: SOLUTION2 \n %a \n" Dom.print s in *)+  let s  = if !Co.minquals then simplify_solution me s else s in+  let _  = Co.bprintflush mydebug "\nDONE: Simplify Solution \n" in+  let _  = BS.time "Solve.dump" (dump me) s in+  let _  = Co.bprintflush mydebug "Fixpoint: Testing Solution \n" in+  let u  = BS.time "Solve.unsatcs" (unsat_constraints me) s in+  let _  = if u != [] then F.printf "Unsatisfied Constraints:\n %a" (Misc.pprint_many true "\n" (C.print_t None)) u in+  let cx = if !Co.cex && Misc.nonnull u then Dom.ctr_examples s (Ci.to_list me.sri) u else [] in+  (s, u, cx)++let global_symbols cfg = +     (SM.to_list cfg.Cg.uops)   (* specified globals *) +  ++ (Theories.interp_syms)     (* theory globals    *)++(* API *)+let create cfg kf =+  let gts = global_symbols cfg in+  let sri = cfg.Cg.cs+            >> Co.bprintf mydebug "Pre-Simplify Stats\n%a" print_constr_stats+            |> BS.time  "Constant Env" (List.map (C.add_consts_t gts))+            |> BS.time  "Simplify" FixSimplify.simplify_ts+            >> Co.bprintf mydebug "Post-Simplify Stats\n%a" print_constr_stats+            |> BS.time  "Ref Index" Ci.create cfg.Cg.kuts cfg.Cg.ds+            |> (!Co.slice <?> BS.time "Slice" Ci.slice) in+  let ws  = cfg.Cg.ws+            |> (!Co.slice <?> BS.time "slice_wf" (Ci.slice_wf sri))+            |> BS.time  "Constant EnvWF" (List.map (C.add_consts_wf gts))+            |> PP.validate_wfs in+  let cfg = { cfg with Cg.cs = Ci.to_list sri; Cg.ws = ws } in+  let s   = if !Constants.dump_simp <> "" then Dom.empty else BS.time "Dom.create" (Dom.create cfg) kf in+  let _   = Co.bprintflush mydebug "\nDONE: Dom.create\n" in+  let _   = Co.bprintflush mydebug "\nBEGIN: PP.validate\n" in+  let _   = Ci.to_list sri+            |> BS.time "Validate" (PP.validate cfg.Cg.a (Dom.read s)) in+  let _   = Co.bprintflush mydebug "\nEND: PP.validate\n" in+  ({ sri          = sri+   ; ws           = ws+   (* stat *)+   ; tt           = Timer.create "fixpoint iters"+   ; stat_refines = ref 0+   ; stat_cfreqt  = Hashtbl.create 37+   }, s)+   >> (fun _ -> Co.bprintflush mydebug "DONE: Solve.create\n")++(* API *)+let save fname me s =+  let oc  = open_out fname in+  let ppf = F.formatter_of_out_channel oc in+  F.fprintf ppf "@[%a@] \n" Ci.print me.sri;+  F.fprintf ppf "@[%a@] \n" (Misc.pprint_many true "\n" (C.print_wf None)) me.ws;+  F.fprintf ppf "@[%a@] \n" Dom.print s;+  close_out oc++(* API *)+let cone me = Cindex.data_cones (Ci.to_list me.sri)++end
+ external/fixpoint/solve.mli view
@@ -0,0 +1,34 @@+(* + * 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.+ *+ *)++type t++module type SOLVER = sig+  type soln+  type bind+  val create    : bind FixConfig.cfg -> FixConstraint.soln option -> (t * soln) +  val solve     : t -> soln -> (soln * (FixConstraint.t list) * Counterexample.cex list) +  val save      : string -> t -> soln -> unit +  val read      : soln -> FixConstraint.soln+  val min_read  : soln -> FixConstraint.soln+  val read_bind : soln -> Ast.Symbol.t -> bind+  val cone      : t -> FixConstraint.id -> FixConstraint.tag Ast.Cone.t+  (* val meet   : soln -> soln -> soln *)++end++module Make (Dom : SolverArch.DOMAIN) : SOLVER +  with type bind = Dom.bind +  with type soln = Dom.t
+ external/fixpoint/solverArch.ml view
@@ -0,0 +1,44 @@+(*+ * 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.+ *+ *)++type qbind   = Qualifier.t list++module type DOMAIN = sig+  type t+  type bind+  val empty        : t +  (* val meet         : t -> t -> t *)+  val min_read     : t -> FixConstraint.soln+  val read         : t -> FixConstraint.soln+  val read_bind    : t -> Ast.Symbol.t -> bind+  val top          : t -> Ast.Symbol.t list -> t+  val refine       : t -> FixConstraint.t -> (bool * t)+  val unsat        : t -> FixConstraint.t -> bool+  val create       : bind FixConfig.cfg -> FixConstraint.soln option -> t+  val print        : Format.formatter -> t -> unit+  val print_stats  : Format.formatter -> t -> unit+  val dump         : t -> unit+  val simplify     : t -> t+  val ctr_examples : t -> FixConstraint.t list -> FixConstraint.t list -> Counterexample.cex list +  val mkbind       : qbind -> bind+end
+ external/fixpoint/theories.ml view
@@ -0,0 +1,198 @@+(*+ * 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 So = Ast.Sort+module Sy = Ast.Symbol+(* module SMT  = SmtZ3.SMTZ3 *)++open ProverArch+open FixMisc.Ops++let set_tycon  = So.tycon "Set_Set"+let t_set a    = So.t_app set_tycon [a]++(* API *)+let is_interp t = t = set_tycon++(* API *)+let emp = ( Sy.of_string "Set_emp"+          , So.t_func 1 [t_set (So.t_generic 0); So.t_bool] )++let sng = ( Sy.of_string "Set_sng"+          , So.t_func 1 [So.t_generic 0; t_set (So.t_generic 0)] )++let mem = ( Sy.of_string "Set_mem"+          , So.t_func 1 [So.t_generic 0; t_set (So.t_generic 0); So.t_bool] )+++let cup = ( Sy.of_string "Set_cup"+          , So.t_func 1 [t_set (So.t_generic 0); t_set (So.t_generic 0); t_set (So.t_generic 0)])++let cap = ( Sy.of_string "Set_cap"+          , So.t_func 1 [t_set (So.t_generic 0); t_set (So.t_generic 0); t_set (So.t_generic 0)])++let dif = ( Sy.of_string "Set_dif"+          , So.t_func 1 [t_set (So.t_generic 0); t_set (So.t_generic 0); t_set (So.t_generic 0)])++let sub = ( Sy.of_string "Set_sub" +          , So.t_func 1 [t_set (So.t_generic 0); t_set (So.t_generic 0); So.t_bool] )++let interp_syms = [emp; sng; mem; cup; cap; dif; sub]++module MakeTheory(SMT : SMTSOLVER): +  (THEORY with type context = SMT.context +          and  type sort    = SMT.sort+          and  type ast     = SMT.ast) +  = struct ++type context = SMT.context+type sort    = SMT.sort+type ast     = SMT.ast+++type appDef  = { sy_name  : Sy.t+               ; sy_sort  : So.t+               ; sy_emb   : SMT.context -> SMT.sort list -> SMT.ast list -> SMT.ast+               }++type sortDef = { so_name  : Ast.Sort.tycon+               ; so_arity : int+               ; so_emb   : SMT.context -> SMT.sort list -> SMT.sort +               }++(* API *)+let sort_name d = d.so_name+let sym_name d  = d.sy_name+let sym_sort d  = d.sy_sort++(***************************************************************************)+(******************** Theory of Sets ***************************************)+(***************************************************************************)++let set_set : sortDef = +  { so_name  = set_tycon +  ; so_arity = 1 +  ; so_emb   = fun c -> function +                 [t] -> SMT.mkSetSort c t+                 | _ -> assertf "Set_set: type mismatch"+  }  ++let set_emp : appDef  = +  { sy_name  = fst emp +  ; sy_sort  = snd emp +  ; sy_emb   = fun c ts es -> match ts, es with+                 | [t], [e] -> SMT.mkRel c Ast.Eq e (SMT.mkEmptySet c t)+                 | _        -> assertf "Set_emp: type mismatch"+  }++let set_sng : appDef  = +  { sy_name = fst sng +  ; sy_sort = snd sng  +  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e] -> SMT.mkSetAdd c (SMT.mkEmptySet c t) e+                 | _        -> assertf "Set_sng: type mismatch"+  }+++let set_mem : appDef  = +  { sy_name = fst mem +  ; sy_sort = snd mem+  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e;es] -> SMT.mkSetMem c e es +                 | _           -> assertf "Set_mem: type mismatch"+  }++let set_cup : appDef  = +  { sy_name = fst cup +  ; sy_sort = snd cup+  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e1;e2] -> SMT.mkSetCup c e1 e2+                 | _            -> assertf "Set_cup: type mismatch"+  }++let set_cap : appDef  = +  { sy_name = fst cap +  ; sy_sort = snd cap +  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e1;e2] -> SMT.mkSetCap  c e1 e2+                 | _            -> assertf "Set_cap: type mismatch"+  }++let set_dif : appDef  = +  { sy_name = fst dif +  ; sy_sort = snd dif+  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e1;e2] -> SMT.mkSetDif c e1 e2 +                 | _            -> assertf "Set_dif: type mismatch"+  }++let set_sub : appDef =+  { sy_name = fst sub +  ; sy_sort = snd sub+  ; sy_emb  = fun c ts es -> match ts, es with+                 | [t], [e1;e2] -> SMT.mkSetSub c e1 e2 +                 | _            -> assertf "Set_dif: type mismatch"+  }++(***************************************************************************)+(********* Wrappers Around Z3 Constructors For Last-Minute Checking ********)+(***************************************************************************)++let app_sort_arity def = match So.func_of_t def.sy_sort with+  | Some (n,_,_) -> n+  | None         -> assertf "Theories: app with non-function symbol %s" +                    (Sy.to_string def.sy_name)++let check_app_arities def tArgs eArgs = match So.func_of_t def.sy_sort with+  | Some (n, ts,_) +     -> asserts (n = List.length tArgs)  +          "Theories: app with mismatched sorts %s" (Sy.to_string def.sy_name);+        asserts (List.length ts = List.length eArgs) +          "Theories: app with mismatched args %s" (Sy.to_string def.sy_name) +  | None         +     -> assertf "Theories: app with non-function symbol %s" +          (Sy.to_string def.sy_name)+++(* API *)+let mk_thy_app def c ts es = +  check_app_arities def ts es;+  def.sy_emb c ts es++(* API *)+let mk_thy_sort def c ts = +  asserts (List.length ts = def.so_arity) +    "Theories: app with mismatched sorts %s" (So.tycon_string def.so_name);+  def.so_emb c ts ++(* API *)+let theories = +  ([set_set], [set_emp; +               set_sng; +               set_mem; +               set_cup; +               set_cap; +               set_dif; +               set_sub])++  +end
+ external/fixpoint/theories.mli view
@@ -0,0 +1,27 @@+(*+ * 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.+ *)++val is_interp   : Ast.Sort.tycon -> bool+val interp_syms : (Ast.Symbol.t * Ast.Sort.t) list++module MakeTheory(SMT : ProverArch.SMTSOLVER): (ProverArch.THEORY with type context = SMT.context and  type sort = SMT.sort and type ast = SMT.ast) + 
+ external/fixpoint/timeout.ml view
@@ -0,0 +1,30 @@+++module M = Mutex+module T = Thread++let get_time () = int_of_float (Unix.time ())++let mk_task =+  fun f x lk (ret, rd) -> let rv = f x in+    M.lock lk; ret := Some rv; rd := true; M.unlock lk++let not_done lk (ret, rd) = +  M.lock lk; let trd = !rd in (M.unlock lk; not(trd))++let fail thread (ret, rd) =+  T.kill thread; ret := None; rd := true ++let do_timeout i f x =+  let task = mk_task f x in+  let (ret, rd) as rr = (ref None, ref false) in+  let stime = get_time () in+  let lk = M.create () in +  let t  = T.create (task lk) rr in+  while not_done lk rr do+    if (get_time () - stime < i) then+      T.yield ()+    else+      fail t rr+  done; !ret+
+ external/fixpoint/timeout.mli view
@@ -0,0 +1,4 @@+(* simple timeout mechanism executes a function for a number of seconds+ * specified by the first argument *)++val do_timeout: int -> ('a -> 'b) -> 'a  -> 'b option
+ external/fixpoint/toARMC.ml view
@@ -0,0 +1,333 @@+(* translation to ARMC *)++module C  = FixConstraint+module StrMap = Map.Make (struct type t = string let compare = compare end)+module StrSet = Set.Make (struct type t = string let compare = compare end)+module Misc = FixMisc open Misc.Ops+++(* Andrey: TODO get rid of grd in t? grd p is a binding v:{v:b|p} *)+(* Andrey: TODO move to fixConstraint.ml? *)+++(* Andrey: TODO move to ast.ml? *)+let pred_is_atomic (p, _) =+  match p with+    | Ast.True | Ast.False | Ast.Bexp _ | Ast.Atom _ -> true+    | Ast.And _ | Ast.Or _ | Ast.Not _ | Ast.Imp _ | Ast.Forall _ -> false++(* +let negate_brel = function+  | Ast.Eq -> Ast.Ne+  | Ast.Ne -> Ast.Eq+  | Ast.Gt -> Ast.Le+  | Ast.Ge -> Ast.Lt+  | Ast.Lt -> Ast.Ge+  | Ast.Le -> Ast.Gt++let deep_negate_pred (p, t) =+  match p with+    | Ast.True -> Ast.pFalse+    | Ast.False -> Ast.pTrue+    | Ast.Atom (e1, r, e2) -> Ast.pAtom (e1, negate_brel r, e2)+    | _ -> Ast.pNot (p, t)+*)++let start_pc = "start"+let loop_pc = "loop"+let error_pc = "error"+let val_vname = "VVVV"+let card_vname = "CARD"+let exists_kv = "EX"+let primed_suffix = "p"+let str__cil_tmp = "__cil_tmp"++type kv_scope = {+  kvs : string list;+  kv_scope : string list StrMap.t+}++let sanitize_symbol s = +  Str.global_replace (Str.regexp "@") "_at_"  s |> Str.global_replace (Str.regexp "#") "_hash_" ++let symbol_to_armc s = Ast.Symbol.to_string s |> sanitize_symbol++let mk_data_var ?(suffix = "") kv v = +  Printf.sprintf "_%s_%s%s%s" +    (sanitize_symbol kv) (sanitize_symbol v) (if suffix = "" then "" else "_") suffix++let constant_to_armc = Ast.Constant.to_string+let bop_to_armc = function +  | Ast.Plus  -> "+"+  | Ast.Minus -> "-"+  | Ast.Times -> "*"+  | Ast.Div   -> "/"+let brel_to_armc = function +  | Ast.Eq -> "="+  | Ast.Ne -> "=\\="+  | Ast.Gt -> ">" (*  ">= 1+" *)+  | Ast.Ge -> ">="+  | Ast.Lt -> "<" (*  "+1 =<" *)+  | Ast.Le -> "=<"+let bind_to_armc (s, t) = (* Andrey: TODO support binders *)+  Printf.sprintf "%s:%s" (symbol_to_armc s) (Ast.Sort.to_string t |> sanitize_symbol)+let rec expr_to_armc (e, _) = +  match e with+    | Ast.Con c -> constant_to_armc c+    | Ast.Var s -> mk_data_var exists_kv (symbol_to_armc s)+    | Ast.App (s, es) ->+	let str = symbol_to_armc s in+	  if es = [] then str else+	    Printf.sprintf "f_%s(%s)" str (List.map expr_to_armc es |> String.concat ", ")+    | Ast.Bin (e1, op, e2) ->+	Printf.sprintf "(%s %s %s)" +	  (expr_to_armc e1) (bop_to_armc op) (expr_to_armc e2)+    | Ast.Ite (ip, te, ee) -> +	Printf.sprintf "ite(%s, %s, %s)" +	  (pred_to_armc ip) (expr_to_armc te) (expr_to_armc ee)+    | Ast.Fld (s, e) -> +	Printf.sprintf "fld(%s, %s)" (expr_to_armc e) (symbol_to_armc s)+and pred_to_armc (p, _) = +  match p with+    | Ast.True -> "1=1"+    | Ast.False -> "0=1"+    | Ast.Bexp e -> expr_to_armc e+    | Ast.Not p -> Printf.sprintf "neg(%s)" (pred_to_armc p) +    | Ast.Imp (p1, p2) -> Printf.sprintf "(neg(%s); %s)" (pred_to_armc p1) (pred_to_armc p2)+    | Ast.And [] -> "1=1"+    | Ast.And [p] -> pred_to_armc p+    | Ast.And (_::_ as ps) -> Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat ", ")+    | Ast.Or [] -> "0=1"+    | Ast.Or [p] -> pred_to_armc p+    | Ast.Or (_::_ as ps) -> Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat "; ")+    | Ast.Atom (e1, r, e2) ->+	Printf.sprintf "%s %s %s" +          (expr_to_armc e1) (brel_to_armc r) (expr_to_armc e2)+    | Ast.Forall (qs,p) -> (* Andrey: TODO support forall *) +	Printf.sprintf "forall([%s], %s)" +          (List.map bind_to_armc qs |> String.concat ", ") +	  (pred_to_armc p)+++let mk_kv_scope out ts wfs =+  output_string out "% kv -> scope:\n";+  let kvs = List.map C.kvars_of_t ts |> List.flatten |> List.map snd+    |> List.map symbol_to_armc |> Misc.sort_and_compact in+  let kv_scope =+    List.fold_left+      (fun m wf ->+	   match C.reft_of_wf wf |> C.ras_of_reft with+	     | [C.Kvar([], kvar)] ->+		 let v = symbol_to_armc kvar in+		 let scope = +		   card_vname :: val_vname ::+		     (C.env_of_wf wf |> C.bindings_of_env |> List.map fst |> List.map symbol_to_armc+		     |> List.filter (fun s -> not (Misc.is_prefix str__cil_tmp s)) |> List.sort compare) in+		   Printf.fprintf out "%% %s -> %s\n"+		     v (String.concat ", " scope);+		   StrMap.add v scope m+	     | _ ->  (* Andrey: TODO print ill-formed wf *)+		 failure "ERROR: kname_scope_map: ill-formed wf"+      ) StrMap.empty wfs in+    {kvs = kvs; kv_scope = kv_scope}++let mk_data ?(suffix = "") ?(skip_kvs = []) s = +  Printf.sprintf "[%s]"+    (List.map +       (fun kv ->+	  try +	    StrMap.find kv s.kv_scope |> +		List.map (mk_data_var ~suffix:(if List.mem kv skip_kvs then "" else suffix) kv)+	  with Not_found -> failure "ERROR: rel_state_vs: scope not found for %s" kv+       ) s.kvs |> List.flatten |> String.concat ", ")++let mk_var2names state = +  List.map+    (fun kv ->+       List.map +	 (fun v -> +	    Printf.sprintf "(%s, \'%s_%s\')"+	      (mk_data_var kv v)  kv v+	 ) (StrMap.find kv state.kv_scope) |> String.concat ", "+    ) state.kvs |> String.concat ", "++let mk_skip_update state kvs = +  if kvs = [] then "1=1" else+    List.map+      (fun kv ->+	 List.map +	   (fun v -> +	      Printf.sprintf "%s = %s"+		(mk_data_var ~suffix:primed_suffix kv v) (mk_data_var kv v)+	   ) (StrMap.find kv state.kv_scope) |> String.concat ", "+      ) kvs |> String.concat ", "++let mk_update_str from_vs to_vs updates = +  List.map2+    (fun v vp ->+       Printf.sprintf "%s = %s" vp (try StrMap.find v updates with Not_found -> v)+    ) from_vs to_vs |> String.concat ", "++let split_scope scope = +  match scope with+    | card :: value :: data -> card, value, data+    | _ -> failure "ERROR: split_scope: empty scope %s" (String.concat ", " scope)++let reft_to_armc ?(suffix = "") state reft = +  let vv = C.vv_of_reft reft |> symbol_to_armc in+  let rs = C.ras_of_reft reft in+    if rs = [] then "1=1" else+      List.map+	(function+	   | C.Conc pred -> pred_to_armc pred+	   | C.Kvar (subs, sym) -> +	       let subs_map = List.fold_left+		 (fun m (s, e) -> StrMap.add (symbol_to_armc s) e m) StrMap.empty subs in+	       let find_subst v default = +		 try StrMap.find v subs_map |> expr_to_armc with Not_found -> default in+	       let kv = symbol_to_armc sym in+	       let card, value, data = StrMap.find kv state.kv_scope |> split_scope in+		 Printf.sprintf "%s = 1" (mk_data_var ~suffix:suffix  kv card) +		 :: Printf.sprintf "%s = %s" +		   (mk_data_var ~suffix:suffix kv value) +		   (find_subst vv (mk_data_var exists_kv vv)) +		 :: List.map+		   (fun v -> +		      Printf.sprintf "%s = %s"+			(mk_data_var ~suffix:suffix kv v)+			(find_subst v (mk_data_var exists_kv v))+		   ) data |> String.concat ", "+	) rs |> String.concat ", "++let mk_rule from_pc from_data to_pc to_data annot_guards annot_updates id = +(*+  let unless_error l = if to_pc = error_pc then to_pc else l in+  let from_pc, to_pc = +    if id = "t_init" then+      from_pc, unless_error "l0"+    else if List.mem id ["11"; "12"; "13"; "14"; "15"; "16"; "17"; "18"; "19"] then+      "l0", unless_error "l1"+    else if List.mem id ["1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"; "28"] then+      "l1", unless_error "l1"+    else if List.mem id ["29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"] then+      "l1", unless_error "l2"+    else+      "l2", unless_error "l2"+  in+*)+  let rec annot_conj_to_armc = function+    | (g, a) :: rest -> +	if rest = [] then Printf.sprintf "\n   %s \t%% %s\n  ]," g a+	else Printf.sprintf "\n   %s, \t%% %s%s" g a (annot_conj_to_armc rest)+    | [] -> "],"+  in+    Printf.sprintf+      "+r(p(pc(%s), data(%s)), +  p(pc(%s), data(%s)),+  [%s+  [%s+  %s).+" +      from_pc from_data to_pc to_data+      (annot_conj_to_armc annot_guards)+      (annot_conj_to_armc annot_updates)+      id++let t_to_armc from_data to_data state t = +  let grd = C.grd_of_t t in+  let lhs = C.lhs_of_t t in+  let rhs = C.rhs_of_t t in+  let rhs_s = C.reft_to_string rhs in+  let tag = try string_of_int (C.id_of_t t) with _ -> +    failure "ERROR: t_to_armc: anonymous constraint %s" (C.to_string t) in+  let annot_guards = +    List.map+      (fun (bv, reft) ->+	 reft_to_armc state (C.theta [(C.vv_of_reft reft, Ast.eVar bv)] reft),+	 C.binding_to_string (bv, reft)+      ) (C.env_of_t t |> C.bindings_of_env) +    ++ [(pred_to_armc grd, Ast.Predicate.to_string grd); +	(reft_to_armc state lhs, "|- " ^ (C.reft_to_string lhs))] in+  let ps, kvs =  +    List.fold_left (fun (ps', kvs') refa ->+		      match refa with+			| C.Conc p -> p::ps', kvs'+			| C.Kvar (subs, sym) -> ps', (subs, sym)::kvs'+		   ) ([], []) (C.ras_of_reft rhs) in+    (if ps <> [] then+       [mk_rule loop_pc from_data error_pc to_data annot_guards +	  [(Ast.pAnd ps |> Ast.pNot |> pred_to_armc, "<: " ^ rhs_s)]+	  tag]+     else +       [])+    +++      (List.map +	 (fun (_, sym) ->+	    let kv = symbol_to_armc sym in+	    let skip_kvs = List.filter (fun kv' -> kv <> kv') state.kvs in+	      mk_rule loop_pc from_data loop_pc +		(mk_data ~suffix:primed_suffix ~skip_kvs:skip_kvs state)+		annot_guards +		[(reft_to_armc ~suffix:primed_suffix state rhs, "<: " ^ rhs_s)]+		tag+	 ) kvs)++let to_armc out ts wfs =+  print_endline "Translating to ARMC.";+  let state = mk_kv_scope out ts wfs in+  let from_data =  mk_data state in+  let to_data = mk_data ~suffix:primed_suffix state in+    Printf.fprintf out+      ":- multifile r/5,implicit_updates/0,var2names/2,preds/2,trans_preds/3,cube_size/1,start/1,error/1,refinement/1,cutpoint/1,invgen_template/2,invgen_template/1,cfg_exit_relation/1,stmtsrc/2,strengthening/2.++refinement(inter).+cube_size(1).++start(pc(%s)).+error(pc(%s)).+cutpoint(pc(%s)).++preds(p(_, data(%s)), [%s]).++trans_preds(p(_, data(%s)), p(_, data(%s)), []).++var2names(p(_, data(%s)), [%s]).+"+      start_pc error_pc loop_pc +      from_data (List.map (fun kv ->+			     let card, _, _ = StrMap.find kv state.kv_scope |> split_scope in+			     let kv_card = mk_data_var kv card in+			       Printf.sprintf "%s = 0, %s = 1" kv_card kv_card+			  ) state.kvs |> String.concat ", ") (* preds *)+      from_data to_data (* trans_preds *)+      from_data (mk_var2names state); (* var2names *)+    output_string out +      (mk_rule start_pc from_data loop_pc to_data [] +	 [(List.map +	     (fun kv -> +		let card, _, _ = StrMap.find kv state.kv_scope |> split_scope in+		  Printf.sprintf "%s = 0" (mk_data_var ~suffix:primed_suffix kv card)+	     ) state.kvs |> String.concat ", ", +	   "")]+         "t_init");+    List.iter (fun t -> t_to_armc from_data to_data state t |> List.iter (output_string out)) ts+++(*+  make -f Makefile.fixtop && ./f -latex /tmp/main.tex -armc /tmp/a.pl tests/pldi08-max.fq && cat /tmp/a.pl++tests:++for file in `ls pldi08-*-atom.fq`; do ../f -latex /tmp/main.tex -armc /tmp/a.pl $file; head -n 1 /tmp/a.pl; armc a.pl | grep correct; done++pldi08-arraymax-atom.fq  pass+pldi08-max-atom.fq       pass+pldi08-foldn-atom.fq     pass+pldi08-sum-atom.fq       pass+mask-atom.fq             pass+samples-atom.fq          pass ++test00.c                 pass++*)
+ external/fixpoint/toDot.ml view
@@ -0,0 +1,173 @@+module C = FixConstraint+module StrSet = Set.Make (struct type t = string let compare = compare end)+module StrStrSet = Set.Make (struct type t = StrSet.t let compare = StrSet.compare end)++module S2 = StrSet+module S3 = StrStrSet+module Misc = FixMisc open Misc.Ops+++module V = struct+  type t = string+  let compare = Pervasives.compare+  let hash = Hashtbl.hash+  let equal = (=)+end+module E = struct+  type t = string+  let compare = Pervasives.compare+  let default = ""+end+++module G = Graph.Persistent.Digraph.ConcreteLabeled(V)(E)++module Display = struct+  include G+  let vertex_name v = "\"" ^ String.escaped v ^ "\""+  let graph_attributes _ = []+  let default_vertex_attributes _ = []+  let vertex_attributes _ = []+  let default_edge_attributes _ = []+  let edge_attributes e = [`Label (G.E.label e)]+  let get_subgraph _ = None+end++module DotOutput = Graph.Graphviz.Dot(Display)++module SCC = Graph.Components.Make(G) ++let vertices_of_graph g = G.fold_vertex (fun v vs -> v::vs) g []+let edges_e_of_graph g = G.fold_edges_e (fun e es -> e::es) g []++let set_of_strings = List.fold_left (fun s x -> StrSet.add x s) StrSet.empty++let set_to_string default s = +  if StrSet.is_empty s then default else StrSet.elements s |> List.map String.escaped |> String.concat ", "++let edges_e_to_graph es = List.fold_left (fun g e -> G.add_edge_e g e) G.empty es++(* k_1, ..., k_n <: k_0 depends on l_1, ..., l_m <: l_0 iff l_0 = k_i for some 1 \leq i \leq n *)+++let t_to_dep t = +  let env = C.env_of_t t in+  let lhs = C.lhs_of_t t in+  let rhs = C.rhs_of_t t in+  let tag = try string_of_int (C.id_of_t t) with _ -> +    failure "ERROR: t_to_edge: anonymous constraint %s" (C.to_string t) in+  let src =+    C.kvars_of_reft lhs :: List.map (fun b -> snd b |> C.kvars_of_reft) (C.bindings_of_env env) |> +	List.flatten |> List.map snd |> List.map Ast.Symbol.to_string |> set_of_strings in+  let dst = C.kvars_of_reft rhs |> List.map snd |> List.map Ast.Symbol.to_string |> set_of_strings in+    src, tag, dst++let sccs_to_dot g prefix =+  let n, scc_of = SCC.scc g in+  let vs = vertices_of_graph g in+    Printf.printf "%s #scc = %d\n" prefix n;+    for i = 0 to n-1 do+      let scc, rest = List.partition (fun v -> scc_of v = i) vs in+      let g' = List.fold_left (fun g'' v -> G.remove_vertex g'' v) g rest in +      let out = open_out (Printf.sprintf "/tmp/%s-scc-%d.dot" prefix i) in+	Printf.printf "%s scc %d %s\n" prefix i (String.concat ", " scc);+	DotOutput.output_graph out g';+	close_out out+    done+++let mk_dep_graph ts =+  let ds' = List.map t_to_dep ts in+  let ds = List.map (fun (src, tag, dst) ->+		       (if StrSet.is_empty src then StrSet.singleton "start" else src),+		       tag,+		       (if StrSet.is_empty dst then StrSet.singleton "error" else dst)+		    ) ds' in+  let g = +    List.map+      (fun (src, tag, dst) ->+	 Misc.map_partial+	   (fun (src', tag', dst') ->+	      let inter = StrSet.inter dst src' in+		if StrSet.is_empty inter then +		  None+		else +		  begin+		    Printf.printf "self loop %s\n" tag;+		    Some(G.E.create tag (set_to_string "" inter) tag') (* tag depends on tag' via inter   *)+		  end+	   ) ds+      ) ds |> List.flatten |> edges_e_to_graph in+  let srcs = List.fold_left (fun xs (src, tag, dst) -> src::xs) [] ds' in++(*+  let veanu = +    List.fold_left (fun xs src ->+		      S3.fold (fun x ys -> +				 ys |> S3.add (S2.diff x src) |> S3.add (S2.diff src x) |> S3.add (S2.inter x src) +			      ) xs S3.empty +		   ) (List.hd srcs |> S3.singleton) (List.tl srcs) in+*)+  let oc = open_out "/tmp/dep.dot" in+    DotOutput.output_graph oc g;+    close_out oc;+    sccs_to_dot g "dep";+    print_endline "start deps";+    List.iter (fun (src, tag, dst) -> +		 Printf.printf "%s <: %s  (%s)\n" (set_to_string "" src) (set_to_string "" dst) tag) ds;+    print_endline "end deps";+    print_endline "start dep graph";+    List.iter (fun e -> +		 Printf.printf "%s - %s -> %s\n" (G.E.src e) (G.E.label e) (G.E.dst e)) (edges_e_of_graph g);+    print_endline "end dep graph"+(*+    Printf.printf "Veanu %d sets\n%s\n" +      (S3.cardinal veanu)+      (S3.fold (fun x s -> +		  (Printf.sprintf "{%s}" (set_to_string "empty" x))::s+	       ) veanu [] |> String.concat ",\n")+*)+++let other_graph ts =+  let deps = List.map t_to_dep ts in+  let srcs, dsts = List.map (fun (s, _, d) -> s, d) deps |> List.split in+  let es = List.map (fun (src, tag, dst) ->+		       G.E.create (set_to_string "start" src) tag (set_to_string "error" dst) +		    ) deps in+  let es' = List.fold_left (fun es'' dst ->+			      Misc.map_partial (fun src -> +						  if StrSet.diff dst src |> StrSet.is_empty then+						    Some (G.E.create (set_to_string "error" dst) "" (set_to_string "start" src))+						  else+						    None+					       ) srcs ++ es''+			   ) es dsts in+  let g = List.fold_left (fun g e -> G.add_edge_e g e) G.empty es' in+    g++let t_to_edge t = +  let srcs', tag, dsts' = t_to_dep t in+  let srcs = if StrSet.is_empty srcs' then ["start"] else StrSet.elements srcs' in+  let dsts = if StrSet.is_empty dsts' then ["error"] else StrSet.elements dsts' in+    List.fold_left (fun es src -> List.map (G.E.create src tag) dsts ++ es) [] srcs+++    ++let to_dot oc ts =+  let _ =  List.fold_left (fun g e -> G.add_edge_e g e ) G.empty (List.map t_to_edge ts |> List.flatten) in+  let g = other_graph ts in+  let vs = G.fold_vertex (fun v vs' -> v::vs') g [] in+  let n, scc_of = SCC.scc g in+    DotOutput.output_graph oc g;+    Printf.printf "#scc = %d\n" n;+    for i = 0 to n-1 do+      let scc, rest = List.partition (fun v -> scc_of v = i) vs in+      let g' = List.fold_left (fun g'' v -> G.remove_vertex g'' v) g rest in +      let out = open_out (Printf.sprintf "/tmp/scc-%d.dot" i) in+	Printf.printf "scc %d %s\n" i (String.concat ", " scc);+	DotOutput.output_graph out g';+	close_out out+    done;+    mk_dep_graph ts
+ external/fixpoint/toHC.ml view
@@ -0,0 +1,613 @@+(* translation to HC'ARMC *)+++module C  = FixConstraint+module Co = Constants +module Sy = Ast.Symbol+module Su = Ast.Subst+module P = Ast.Predicate+module E = Ast.Expression+module StrMap = Map.Make (struct type t = string let compare = compare end)+module StrSet = Set.Make (struct type t = string let compare = compare end)+module Misc = FixMisc open Misc.Ops++let strlist_to_strset = List.fold_left (fun s x -> StrSet.add x s) StrSet.empty+++let armc_true = "1=1"+let armc_false = "0=1"+(*+let armc_true = "true"+let armc_false = "false"+*)+let loop_pc = "loop"+let start_pc = "start"+let error_pc = "error"+let val_vname = "AA_0"+let card_vname = "CARD"+let exists_kv = "EX"+let primed_suffix = "p"+let str__cil_tmp = "__cil_tmp"++type kv_scope = {+  kvs : string list;+  kv_scope : string list StrMap.t;+  sol : Ast.pred list Sy.SMap.t;+}++type horn_clause = {+  body_pred : Ast.pred;+  body_kvars : (Su.t * Sy.t) list;+  head_pred : Ast.pred;+  head_kvar_opt : (Su.t * Sy.t) option;+  tag : string;+}++let sanitize_symbol s = +  Str.global_replace (Str.regexp "@") "_at_"  s |> Str.global_replace (Str.regexp "#") "_hash_" |>+      Str.global_replace (Str.regexp "\\.") "_dot_" |> Str.global_replace (Str.regexp "'") "_q_" ++let symbol_to_armc s = Sy.to_string s |> sanitize_symbol++let mk_data_var ?(suffix = "") kv v = +  Printf.sprintf "_%s_%s%s%s" +    (sanitize_symbol v) (sanitize_symbol kv) (if suffix = "" then "" else "_") suffix++let mk_data ?(suffix = "") ?(skip_kvs = []) s = +  Printf.sprintf "[%s]"+    (List.map +       (fun kv ->+	  try +	    StrMap.find kv s.kv_scope |> +		List.map (mk_data_var ~suffix:(if List.mem kv skip_kvs then "" else suffix) kv)+	  with Not_found -> failure "ERROR: rel_state_vs: scope not found for %s" kv+       ) s.kvs |> List.flatten |> String.concat ", ")++let constant_to_armc = Ast.Constant.to_string+let bop_to_armc = function +  | Ast.Plus  -> "+"+  | Ast.Minus -> "-"+  | Ast.Times -> "*"+  | Ast.Div   -> "/"+let brel_to_armc = function +  | Ast.Eq -> "="+  | Ast.Ne -> "=\\="+  | Ast.Gt -> ">"+  | Ast.Ge -> ">="+  | Ast.Lt -> "<"+  | Ast.Le -> "=<"+let bind_to_armc (s, t) = (* Andrey: TODO support binders *)+  Printf.sprintf "%s:%s" (symbol_to_armc s) (Ast.Sort.to_string t |> sanitize_symbol)+let rec expr_to_armc expr = +  let e = E.unwrap expr in+    match e with+      | Ast.Con c -> constant_to_armc c+      | Ast.Var s -> mk_data_var exists_kv (symbol_to_armc s)+      | Ast.App (s, es) -> +	  if !Co.purify_function_application then "_" else+	    let str = symbol_to_armc s in+	      if es = [] then str else+		Printf.sprintf "f_%s(%s)" str (List.map expr_to_armc es |> String.concat ", ")+      | Ast.Bin (e1, op, e2) ->+	  Printf.sprintf "(%s %s %s)" +	    (expr_to_armc e1) (bop_to_armc op) (expr_to_armc e2)+      | Ast.Ite (ip, te, ee) -> +	  Printf.sprintf "ite(%s, %s, %s)" +	    (pred_to_armc ip) (expr_to_armc te) (expr_to_armc ee)+      | Ast.Fld (s, e) -> +	  Printf.sprintf "fld(%s, %s)" (expr_to_armc e) (symbol_to_armc s) +      | _ -> failwith (Printf.sprintf "expr_to_armc: %s" (E.to_string expr))+and pred_to_armc pred = +  let p = P.unwrap pred in +    match p with+      | Ast.True -> armc_true+      | Ast.False -> armc_false+      | Ast.Bexp e -> Printf.sprintf "%s = 1" (expr_to_armc e)+      | Ast.Not (Ast.True, _) -> armc_false+      | Ast.Not (Ast.False, _) -> armc_true+      | Ast.Not p -> Printf.sprintf "neg(%s)" (pred_to_armc p) +      | Ast.Imp (p1, p2) -> Printf.sprintf "imp(%s, %s)" (pred_to_armc p1) (pred_to_armc p2)+      | Ast.And [] -> armc_true+      | Ast.And [p] -> pred_to_armc p+      | Ast.And (_::_ as ps) -> +	  Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat ", ")+      | Ast.Or [] -> armc_false+      | Ast.Or [p] -> pred_to_armc p+      | Ast.Or (_::_ as ps) -> Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat "; ")+      | Ast.Atom (e1, Ast.Eq, (Ast.Ite(ip, te, ee), _)) ->+	  let ip_str = pred_to_armc ip in+	  let e1_str = expr_to_armc e1 in+	    Printf.sprintf "((%s, %s = %s); (neg(%s), %s = %s))"+	      ip_str e1_str (expr_to_armc te) +	      ip_str e1_str (expr_to_armc ee) +      | Ast.Atom (e1, r, e2) ->+	  Printf.sprintf "%s %s %s" +            (expr_to_armc e1) (brel_to_armc r) (expr_to_armc e2)+      | Ast.Forall (qs,p) -> (* Andrey: TODO support forall *) +	  Printf.sprintf "forall([%s], %s)" +            (List.map bind_to_armc qs |> String.concat ", ") +	    (pred_to_armc p)++let preds_kvars_of_reft reft =+  List.fold_left +    (fun (ps, ks) r ->+       match r with+	 | C.Conc p -> p :: ps, ks+	 | C.Kvar (subs, kvar) -> ps, (subs, kvar) :: ks+    ) ([], []) (C.ras_of_reft reft)++let preds_to_pred ps =+  match ps with +    | [] -> Ast.pTrue+    | [p] -> p+    | _ :: _ -> Ast.pAnd ps	 ++let rec flatten_pAnd pred =+  match P.unwrap pred with+    | Ast.And [] -> []+    | Ast.And [p] -> flatten_pAnd p+    | Ast.And ps -> List.map flatten_pAnd ps |> List.flatten+    | _ -> [pred]++let t_to_horn_clause t =+  let lhs_ps, lhs_ks = C.lhs_of_t t |> preds_kvars_of_reft in+  let body_ps, body_ks = +    Sy.SMap.fold +      (fun bv reft (ps, ks) -> +	 let ps', ks' = preds_kvars_of_reft (C.theta (Su.of_list [(C.vv_of_reft reft, Ast.eVar bv)]) reft) in+	   List.rev_append ps' ps, List.rev_append ks' ks+      ) (C.env_of_t t) (C.grd_of_t t :: lhs_ps, lhs_ks) in+  let head_ps, head_ks = C.rhs_of_t t |> preds_kvars_of_reft in+  let head_kvar_opt =+    match head_ks with +      | [] -> None+      | [head_kvar] -> Some head_kvar+      | _ ->+	  failwith (Printf.sprintf "t_to_horn_clause: multiple k's in rhs of %d" (C.id_of_t t));+  in+    {+      body_pred = Ast.pAnd body_ps |> flatten_pAnd |> preds_to_pred; +      body_kvars = body_ks; +      head_pred = Ast.pAnd head_ps |> flatten_pAnd |> preds_to_pred;+      head_kvar_opt = head_kvar_opt;+      tag = C.id_of_t t |> string_of_int;+    }++let horn_clause_to_string hc = +  Printf.sprintf "%s: %s, %s :- %s, %s."+    hc.tag +    (P.to_string hc.head_pred)+    (match hc.head_kvar_opt with+       | Some (subs, kvar) -> C.refa_to_string (C.Kvar (subs, kvar))+       | None -> "none"+    )+    (P.to_string hc.body_pred)+    (List.map (fun (subs, kvar) -> C.refa_to_string (C.Kvar (subs, kvar))) hc.body_kvars |> String.concat ", ")+++module CFGNodeSet = Set.Make (struct type t = StrSet.t let compare = StrSet.compare end)+++module DepV = struct+  type t = string+  let compare = Pervasives.compare+  let hash = Hashtbl.hash+  let equal = (=)+end+module DepE = struct+  type t = string+  let compare = Pervasives.compare+  let default = ""+end+module DepG = Graph.Persistent.Digraph.ConcreteLabeled(DepV)(DepE)++module Display = struct+  include DepG+  let vertex_name v = DepG.V.label v+  let graph_attributes _ = []+  let default_vertex_attributes _ = []+  let vertex_attributes _ = []+  let default_edge_attributes _ = []+  let edge_attributes _ = []+  let get_subgraph _ = None+end+module DepGToDot = Graph.Graphviz.Dot(Display)+module DepGOper = Graph.Oper.P(DepG)++module DepGSCC = Graph.Components.Make(DepG)++module G = Graph.Pack.Digraph++let hc_to_dep hc =+  (match hc.head_kvar_opt with+     | Some (_, sym) -> Some (symbol_to_armc sym) +     | None -> None+  ),+  List.map (fun (_, sym) -> symbol_to_armc sym) hc.body_kvars |> List.sort compare++(*+let mk_cfg state hcs =+  let nodes = ref (CFGNodeSet.singleton StrSet.empty) in+  let nodes_size = ref 0 in+  let nodes_size' = ref 1 in+    while !nodes_size < !nodes_size' do+      nodes_size := CFGNodeSet.cardinal !nodes;+      List.iter (fun hc ->+		   let heads, body = hc_to_dep hc in+		   let body_set = List.fold_left (fun sofar b -> StrSet.add b sofar) StrSet.empty body in+		     List.iter (fun node ->+				  List.iter (fun head ->+					       if StrSet.subset body_set node then+						 nodes := CFGNodeSet.add (StrSet.add head node) !nodes+					    ) heads+			       ) (CFGNodeSet.elements !nodes)+		) hcs;+      nodes_size' := CFGNodeSet.cardinal !nodes+    done;+    Printf.printf "nodes: %s\n" (List.sort compare state.kvs |> String.concat ", ");+    CFGNodeSet.iter (fun node -> +		       Printf.printf "node: %s\n" (StrSet.elements node |> List.sort compare |> String.concat ", ")+		    ) !nodes;+    let g = G.create () in+      List.iter (fun hc -> +		   let heads, body = hc_to_dep hc in+		     List.iter (fun b -> +				  List.iter (fun head -> +					       G.add_edge g (G.V.create 1) (G.V.create 2)+					    ) heads+			       ) body+		) hcs;+    let depg = +      List.fold_left+	(fun g hc -> +	   let heads, body = hc_to_dep hc in+	     List.fold_left +	       (fun g' b -> +		  List.fold_left +		    (fun g'' head -> +		       DepG.add_edge_e g'' (DepG.E.create b (* hc.tag *) "" head)+		    ) g' heads+	       ) g body+	) DepG.empty hcs in+    let dep_cs = +      List.fold_left+	(fun g hc -> +	   let heads, _ = hc_to_dep hc in+	     List.fold_left +	       (fun g' hc' -> +		  (* check if heads intersect body' *)+		  let _, body' = hc_to_dep hc' in+		    if hc.tag <> hc'.tag && List.exists (fun head -> List.mem head body') heads then +		      DepG.add_edge g' hc.tag hc'.tag+		    else +		      g'+	       ) g hcs+	) DepG.empty hcs in+    let out = open_out "/var/tmp/awesome/g.dot" in+      DepGToDot.output_graph out depg;+      close_out out;+    let out = open_out "/var/tmp/awesome/t.dot" in+      DepGToDot.output_graph out (DepGOper.transitive_closure depg);+      close_out out;+    let out = open_out "/var/tmp/awesome/cs.dot" in+      DepGToDot.output_graph out dep_cs;+      close_out out+*)+    ++let kvar_to_hc_armcs ?(suffix = "") state (subs, sym) = +  let subs_map = List.fold_left (fun m (s, e) -> StrMap.add (symbol_to_armc s) e m) StrMap.empty (Su.to_list subs) in+  let find_subst v default = try StrMap.find v subs_map |> expr_to_armc with Not_found -> default in+  let kv = symbol_to_armc sym in+    try+      let scope = StrMap.find kv state.kv_scope in +	Printf.sprintf "%s(%s)" +	  kv (List.map (mk_data_var ~suffix:suffix kv) scope |> String.concat ", ")+	:: List.map (fun v -> +		       Printf.sprintf "%s = %s" +			 (mk_data_var ~suffix:suffix kv v) (find_subst v (mk_data_var exists_kv v))+		    ) scope +    with Not_found -> [armc_true] (* input variable *)++let kvar_to_armcs ?(suffix = "") ?(with_card=true) state (subs, sym) = +  let subs_map = +    List.fold_left (fun m (s, e) -> StrMap.add (symbol_to_armc s) (expr_to_armc e) m) StrMap.empty (Su.to_list subs) in+  let find_subst v default = try StrMap.find v subs_map with Not_found -> default in+  let kv = symbol_to_armc sym in+  try+    let scope = StrMap.find kv state.kv_scope in+    let card_armc, data = +      if with_card then+	[Printf.sprintf "%s = 1" (mk_data_var ~suffix:suffix kv card_vname)], List.tl scope+      else +	[], scope+    in+      card_armc+      @ List.map (fun v -> +		     Printf.sprintf "%s = %s" +		       (mk_data_var ~suffix:suffix kv v) (find_subst v (mk_data_var exists_kv v))+		  ) data |> String.concat ", "+  with Not_found -> armc_true (* input variable *)++let hc_to_rule state hc =+  let mk_rule head body tag = Printf.sprintf "rule(%s, %s, [%s])." tag head body in+  let body = +    pred_to_armc hc.body_pred :: (List.map (kvar_to_hc_armcs state) hc.body_kvars |> List.flatten) |>  +	String.concat ", " in+  let prules = +    if P.is_tauto hc.head_pred then []+    else [mk_rule error_pc  (Printf.sprintf "%s, %s" body (Ast.pNot hc.head_pred |> pred_to_armc)) hc.tag] in+  let krules =+    match hc.head_kvar_opt with+      | Some kvar ->+	 let head_armcs = kvar_to_hc_armcs ~suffix:primed_suffix state kvar in+	   [mk_rule +	     (List.hd head_armcs) (* kv *)+	     (body :: (List.tl head_armcs (* subs *)) |> String.concat ", ")+	     hc.tag]+      | None -> []+  in+    krules @ prules++let mk_rule from_pc from_data to_pc to_data guard update tag = +  Printf.sprintf "r(p(pc(%s), data(%s)),\np(pc(%s), data(%s)),\n[%s],\n[%s], %s).%s"+    from_pc from_data to_pc to_data guard update tag+    (if guard = "" && update = "" then Printf.sprintf "\nid_trans(%s)." tag else "")++let hc_to_armc ?(cfg=false) ?(with_card=true) ?(with_dataflow=false) state hc = +  let from_data = mk_data state in+  let to_data = mk_data ~suffix:primed_suffix state in+  let body = pred_to_armc hc.body_pred :: List.map (kvar_to_armcs ~with_card:with_card state) hc.body_kvars in+  let body_kv_strs = hc_to_dep hc |> snd |> List.filter (fun kv -> StrMap.mem kv state.kv_scope) in+  let prules =+    if P.is_tauto hc.head_pred then []+    else +      mk_rule +	(if cfg then Printf.sprintf "src_%s" hc.tag else loop_pc)+	from_data error_pc to_data +	((Ast.pNot hc.head_pred |> pred_to_armc) :: body |> String.concat ",\n") "" hc.tag+      :: +	if with_dataflow then+	  [Printf.sprintf "dataflow_transition(%s, [%s], [])." hc.tag (String.concat ", " body_kv_strs)]+	else [] in+  let krules =+    match hc.head_kvar_opt with+      | Some ((subs, sym) as kvar) ->+	  let kv = symbol_to_armc sym in+	  let skip_kvs = List.filter (fun kv' -> kv <> kv') state.kvs in+	    mk_rule +	      (if cfg then Printf.sprintf "src_%s" hc.tag else loop_pc)+	      from_data +	      (if cfg then Printf.sprintf "dst_%s" hc.tag else loop_pc)+	      (mk_data ~suffix:primed_suffix ~skip_kvs:skip_kvs state) +	      (body |> String.concat ",\n") +	      (kvar_to_armcs ~with_card:with_card ~suffix:primed_suffix state kvar) +	      hc.tag+	    ::+	      if with_dataflow then+		[Printf.sprintf "dataflow_transition(%s, [%s], [%s])." hc.tag (String.concat ", " body_kv_strs) kv]+	      else []+      | None -> []+  in+    krules @ prules++let mk_hc_var2names state = +  List.map+    (fun kv ->+       Printf.sprintf "var2names(p(pc(%s), data(%s)), [%s])."+	 kv+	 (List.map (mk_data_var kv) (StrMap.find kv state.kv_scope) |> String.concat ", ")+	 (List.map +	    (fun v -> +	       Printf.sprintf "(%s, \'%s_%s\')" (mk_data_var kv v)  v kv+	    ) (StrMap.find kv state.kv_scope) |> String.concat ", ")+    ) state.kvs |> String.concat "\n"++let mk_var2names state = +  Printf.sprintf "var2names(p(pc(_), data(%s)), [%s])."+    (mk_data state)+    (List.map+       (fun kv ->+	  List.map +	    (fun v -> +	       Printf.sprintf "(%s, \'%s_%s\')" (mk_data_var kv v)  v kv+	    ) (StrMap.find kv state.kv_scope) |> String.concat ", "+       ) state.kvs |> String.concat ", ")++let mk_hc_preds state = +  List.map+    (fun kv ->+       Printf.sprintf "preds(p(pc(%s), data(%s)), [])."+	 kv+	 (List.map (mk_data_var kv) (StrMap.find kv state.kv_scope) |> String.concat ", ")+    ) state.kvs |> String.concat "\n"++let mk_preds ?(with_card = true) state = +  let preds = +    if with_card then+      List.map (fun kv ->+		  let card = StrMap.find kv state.kv_scope |> List.hd in+		  let kv_card = mk_data_var kv card in+		    Printf.sprintf "%s = 0, %s = 1" kv_card kv_card+	       ) state.kvs |> String.concat ", "+    else +      ""+  in+    Printf.sprintf "preds(p(pc(_), data(%s)), [%s])." (mk_data state) preds++let mk_start_rule state = +  mk_rule start_pc (mk_data state) loop_pc (mk_data ~suffix:primed_suffix state) "" +    (List.map (fun kv ->+		 let card = StrMap.find kv state.kv_scope |> List.hd in+		   Printf.sprintf "%s = 0" (mk_data_var ~suffix:primed_suffix kv card)+	      ) state.kvs |> String.concat ", ")+    "start_t"++let find_kv_wf_scope wfs kv = +  let wf =+    try List.find (fun wf -> +		     match C.reft_of_wf wf |> C.kvars_of_reft with+		       | [(subs, kvar)] -> Su.is_empty subs && kv = symbol_to_armc kvar+		       | _ -> false+		  ) wfs +    with Not_found -> failwith (Printf.sprintf "find_wf_scope: %s" kv)+  in+    Sy.SMap.fold (fun kvar _ sofar -> StrSet.add (symbol_to_armc kvar) sofar) (C.env_of_wf wf) StrSet.empty++(* map each k variable to variables in its scope *)+(* k variables no appearing in any rhs don't have any scope *)+let mk_kv_scope ?(with_card=true) ?(hcs=[]) out ts wfs sol =+  (*+  List.iter (fun wf -> +	       let env = C.env_of_wf wf in+	       let bvs = Sy.SMap.fold (fun bv _ sofar -> symbol_to_armc bv :: sofar) env [] in+		 Printf.printf "wf: %s : %s\n" (C.reft_of_wf wf |> C.reft_to_string) (String.concat ", " bvs)+	    ) wfs;+  *)+  let hcs = if hcs = [] then List.map t_to_horn_clause ts else hcs in+  let hc_deps = List.map hc_to_dep hcs in+  let kv_scope_aux =+    ref (List.fold_left (fun kv_scope' t ->+			   (* collect bound vars of t *)+			   let scope =+			     Sy.SMap.fold (fun bv _ scope' ->+					     StrSet.add (symbol_to_armc bv) scope'+					  ) (C.env_of_t t) StrSet.empty in+			   let _, rhs_kvs = C.rhs_of_t t |> C.preds_kvars_of_reft in+			     (* add these bound vars to the scope of each k var in rhs of t *)+			     List.fold_left (fun kv_scope'' kv ->+					       StrMap.add kv (StrSet.union +								(try StrMap.find kv kv_scope'' with Not_found -> StrSet.empty) +								scope) kv_scope''+					    ) kv_scope' (List.map snd rhs_kvs |> List.map symbol_to_armc)+			) StrMap.empty ts) in+  let done_flag = ref false in+    (* if k' depends on k then scope(k') contains scope(k) *)+    while not(!done_flag) do+      done_flag := true;+      List.iter (fun (head_opt, body) ->+		   match head_opt with+		     | Some kv' -> +			 let scope_kv' = StrMap.find kv' !kv_scope_aux in +			 let size_scope_kv' = StrSet.cardinal scope_kv' in+			 let upd_scope_kv' = +			   List.fold_left (fun sofar kv ->+					     StrSet.union (try StrMap.find kv !kv_scope_aux with Not_found -> StrSet.empty) sofar+					  ) scope_kv' body +			 in+			   if size_scope_kv' < StrSet.cardinal upd_scope_kv' then+			     begin+			       kv_scope_aux := StrMap.add kv' upd_scope_kv' !kv_scope_aux;+			       done_flag := false+			     end+		     | None -> ()+		) hc_deps+    done;+    let kv_scope = +      (* sort scope, add value variable and, if needed, cardinality variable *)+      StrMap.mapi (fun kv scope -> +		     let scope' = val_vname :: (StrSet.inter scope (find_kv_wf_scope wfs kv) |> StrSet.elements |> List.sort compare) in+		       if with_card then card_vname :: scope' else scope'+		  ) !kv_scope_aux in+    let kvs = StrMap.fold (fun kv _ kvs -> kv :: kvs) kv_scope [] in+      StrMap.iter (fun kv scope ->+    		     Printf.fprintf out "%% %s -> %s\n" kv (String.concat ", " scope)) kv_scope;+      {kvs = kvs; kv_scope = kv_scope; sol = sol}+++let to_horn out ts wfs sol =+  print_endline "Translating to Horn clauses.";+(*  let cex = [1;2;4;5;9;23;24] in   *)+  let cex = [] in+  let ts = if cex = [] then ts else List.filter (fun t -> List.mem (C.id_of_t t) cex) ts in+  let state = mk_kv_scope out ~with_card:false ts wfs sol in+    Printf.fprintf out+      ":- multifile rule/3, var2names/2, preds/2, error/1.++error(%s).+%s+%s+"+      error_pc+      (mk_hc_var2names state)+      (mk_hc_preds state);+    List.iter (fun t -> +		 Printf.fprintf out "/*\n%s\n%s\n*/\n" (C.to_string t) (t_to_horn_clause t |> horn_clause_to_string);+		 List.iter (fun r -> +			      output_string out r;+			      output_string out "\n\n"+			   ) (t_to_horn_clause t |> hc_to_rule state)+	      ) ts++let to_armc out ts wfs sol =+  print_endline "Translating to ARMC. ToHC.to_armc";+(*  let cex = [1;5;13;14;68;69;54] in *)+  let cex = [] in+  let state = mk_kv_scope out ts wfs sol in+    Printf.fprintf out+      ":- multifile r/5,implicit_updates/0,var2names/2,preds/2,trans_preds/3,cube_size/1,start/1,error/1,refinement/1,cutpoint/1,invgen_template/2,invgen_template/1,cfg_exit_relation/1,stmtsrc/2,strengthening/2.+refinement(inter). +cube_size(1). ++start(pc(%s)).+error(pc(%s)).+cutpoint(pc(%s)).+\n%s\n\n%s\n+"+      start_pc error_pc loop_pc +      (mk_var2names state)+      (mk_preds state);+    Printf.fprintf out "%s\n\n" (mk_start_rule state);+    List.iter (fun t -> +		 if List.mem (C.id_of_t t) cex || List.length cex = 0 then+		   let hc = t_to_horn_clause t in+		     Printf.fprintf out "/*\n%s%s\n*/\n" (C.to_string t) (horn_clause_to_string hc);+		     List.iter (fun r -> +				  output_string out r;+				  output_string out "\n\n"+			       ) (hc_to_armc state hc)+		 else+		   ()+	      ) ts;+    List.iter (fun id ->  +		 List.iter (fun t -> +			      if List.mem (C.id_of_t t) cex then+				Printf.printf "%s\n" (C.to_string t)+			   ) ts+	      ) cex+++let to_dataflow_armc out ts wfs sol =+  print_endline "Translating to ARMC. ToHC.to_dataflow_armc ";+  let with_card_flag = false in+(*  let cex = [1;2;4;5;9;23;24] in   *)+  let cex = [] in+  let ts = (if cex = [] then ts else List.filter (fun t -> List.mem (C.id_of_t t) cex) ts) in+  let hcs = List.map t_to_horn_clause ts in+  let state = mk_kv_scope ~with_card:with_card_flag ~hcs:hcs out ts wfs sol in+    Printf.fprintf out+      ":- multifile r/5,implicit_updates/0,var2names/2,preds/2,trans_preds/3,cube_size/1,start/1,error/1,refinement/1,cutpoint/1,invgen_template/2,invgen_template/1,cfg_exit_relation/1,stmtsrc/2,strengthening/2,id_trans/1,dataflow_transition/3.+refinement(inter). +cube_size(1). ++start(pc(%s)).+error(pc(%s)).++\n%s\n\n%s\n+"+      start_pc error_pc +      (mk_var2names state)+      (mk_preds ~with_card:with_card_flag state);+    (* connect the start with the loop *)+    Printf.fprintf out "%s\n\n" (mk_rule start_pc (mk_data state) loop_pc (mk_data state) "" "" "start");+    Printf.fprintf out "dataflow_transition(%s, [], []).\n\n" "start";+    List.iter+      (fun hc -> +	 Printf.fprintf out "/*\n%s\n*/\n" (horn_clause_to_string hc);+	 (* the actual transition relation, each disjunct *) +	 List.iter (Printf.fprintf out "%s\n\n") (hc_to_armc ~cfg:false ~with_card:with_card_flag ~with_dataflow:true state hc)+      ) hcs;+    output_string out "/*\n";+    List.iter (fun t -> Printf.fprintf out "%s\n" (C.to_string t)) ts;+    List.iter (fun hc -> Printf.fprintf out "%s\n\n" (horn_clause_to_string hc)) hcs;+    output_string out "*/\n"
+ external/fixpoint/toImp.ml view
@@ -0,0 +1,378 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++(* This module implements the IMP language and translation from fixpoint constraints *)+++module F  = Format+module H  = Hashtbl+module A  = Ast+module E  = A.Expression+module P  = A.Predicate+module Sy = A.Symbol+module SM = Sy.SMap+module C  = FixConstraint+module Cg = FixConfig+(*module BS = BNstats*)++module Misc = FixMisc open Misc.Ops++(**********************************************************************)+(************* Datatypes for IMP Representation ***********************)+(**********************************************************************)++(* vars are always in lex order *)+(* We can have at most one set of temporaries in scope at a time+ * so we share names and mark temporaries *)++type var   = PVar of Sy.t+           | TVar of Sy.t++type kvar  = Ast.Subst.t * Sy.t++type decl  = RDecl of Sy.t * Sy.t list+           | PDecl of Sy.t++(* IMP commands *)++type tupl  = var list++type instr = Assm of A.pred list+           | Asst of A.pred list+           | Asgn of var * var+           | Rget of Sy.t * tupl+           | Rset of tupl * Sy.t+           | Havc of var++type block = instr list++type program = decl list * block list++(**********************************************************************)+(************* Datatypes for IMP Representation ***********************)+(**********************************************************************)++(* Convenience *)++let mk_temp = function+  | TVar v -> TVar v+  | PVar v -> TVar v++let rv_append v1 = function+  | TVar v2 | PVar v2 ->+      PVar (Sy.of_string (Sy.to_string v1 ^ "_" ^ Sy.to_string v2))+  +let collect_apps_from_pred p = +  let apps = ref [] in+  let f_exp e =+    match E.unwrap e with+    | A.App (s, es) -> apps := (s, List.length es) :: !apps+    | t -> () in+  P.iter (fun _ -> ()) f_exp p; !apps++let collect_apps_from_instr = function+  | Assm ps+  | Asst ps ->+      Misc.flap collect_apps_from_pred ps+  | _ -> []++let collect_apps_from_block block =+  Misc.flap collect_apps_from_instr block++let collect_apps_from_program (_, blocks) =+  Misc.flap collect_apps_from_block blocks++(*************************************************************************)+(************* Rendering IMP to String ***********************************)+(*************************************************************************)++let print_var ppf = function +  | PVar v -> F.fprintf ppf "%a" Sy.print v+  | TVar v -> F.fprintf ppf "'%a" Sy.print v++let print_tuple ppf =+  F.fprintf ppf "(%a)" (Misc.pprint_many false ", " print_var)++let print_instr ppf = function+  | Assm ps ->+      F.fprintf ppf "@[assume %a;@]" P.print (A.pAnd ps)+  | Asst ps ->+      F.fprintf ppf "@[assert %a;@]" P.print (A.pAnd ps)+  | Asgn (lhs, rhs) ->+      F.fprintf ppf "@[%a@ :=@ %a;@]" print_var lhs print_var rhs+  | Rget (rv, tupl) ->+      F.fprintf ppf "@[%a@ <|@ %a;@]" print_tuple tupl Sy.print rv+  | Rset (tupl, rv) ->+      F.fprintf ppf "@[%a@ |>@ %a;@]" print_tuple tupl Sy.print rv+  | Havc v ->+      F.fprintf ppf "@[havoc@ %a;@]" print_var v ++let print_decl ppf = function+  | RDecl (r, vs) ->+      F.fprintf ppf "@[rel@ (%a)@ (%a);@]" Sy.print r+        (Misc.pprint_many false ", " Sy.print) vs +  | PDecl v ->+      F.fprintf ppf "@[var@ %a;@]" Sy.print v++let print_block ppf block =+  F.fprintf ppf "@[%a@]"+    (Misc.pprint_many false "\n" print_instr) block++let print_program ppf (decls, blocks) =+  F.fprintf ppf "@[%a@.%a@]"+    (Misc.pprint_many false "\n" print_decl) decls+    (Misc.pprint_many false "\n" print_block) blocks ++(* Printing as C syntax *)++let print_brel_as_c ppf = function+  | A.Eq -> F.fprintf ppf "=="+  | A.Ne -> F.fprintf ppf "!="+  | A.Gt -> F.fprintf ppf ">"+  | A.Ge -> F.fprintf ppf ">="+  | A.Lt -> F.fprintf ppf "<"+  | A.Le -> F.fprintf ppf "<="++let print_bop_as_c ppf = function+  | A.Plus  -> F.fprintf ppf "+"+  | A.Minus -> F.fprintf ppf "-"+  | A.Times -> F.fprintf ppf "*"+  | A.Div   ->  F.fprintf ppf "/"+  +let rec print_predicate_as_c ppf pred =+  match P.unwrap pred with+  | A.True ->+      F.fprintf ppf "True"+  | A.False ->+      F.fprintf ppf "False"+  | A.Atom (e1, r, e2) ->+      F.fprintf ppf "(%a %a %a)" print_expr_as_c e1 print_brel_as_c r print_expr_as_c e2+  | A.And ps ->+      Misc.pprint_many false " && " P.print ppf ps+  | A.Or ps ->+      Misc.pprint_many false " || " P.print ppf ps+  | A.Not p ->+      F.fprintf ppf "!(%a)" print_predicate_as_c p+  | A.Imp (p1, p2) ->+      print_predicate_as_c ppf (A.pOr [A.pNot p1; p2])+  | A.Iff (p1, p2) ->+      print_predicate_as_c ppf (A.pAnd [A.pImp (p1, p2); A.pImp (p2, p1)])+  | A.Bexp e ->+      print_expr_as_c ppf e+  | A.Forall (ds, p) ->+      assert false+      +and print_expr_as_c ppf expr =+  match E.unwrap expr with+  | A.Con c ->+      F.fprintf ppf "%a" A.Constant.print c+  | A.Var v ->+      F.fprintf ppf "%a" Sy.print v+  | A.App (f, es) ->+      F.fprintf ppf "%a(%a)" Sy.print f+        (Misc.pprint_many false ", " print_expr_as_c) es+  | A.Bin (e1, op, e2) ->+      F.fprintf ppf "(%a %a %a)"+        print_expr_as_c e1+        print_bop_as_c op+        print_expr_as_c e2+  | A.Ite (p, e1, e2) ->+      F.fprintf ppf "(%a ? %a : %a)"+        print_predicate_as_c p+        print_expr_as_c e1+        print_expr_as_c e2+  | A.Fld (s, e) ->+      print_expr_as_c ppf (A.eApp (Sy.of_string ("field" ^ Sy.to_string s), [e]))+(*  | A.Mod (e1, i) ->+      F.fprintf ppf "(%a mod %d)" print_expr_as_c e1 i +*)++let print_var_as_c ppf = function+  | PVar v -> F.fprintf ppf "%a" Sy.print v+  | TVar v -> F.fprintf ppf "_%a" Sy.print v++let sy_append v1 v2 =+  Sy.of_string ((Sy.to_string v1) ^ "_" ^ (Sy.to_string v2))++let print_decl_as_c ppf = function+  | RDecl (rv, tupl) ->+      let pv v1 = (fun v2 -> F.fprintf ppf "@[int %a;@]@\n" Sy.print (sy_append v1 v2)) in+      List.iter (pv rv) tupl+  | PDecl v ->+      F.fprintf ppf "@[int %a;@]@\n" Sy.print v++let rec print_instr_as_c ppf = function+  | Havc v ->+      F.fprintf ppf "@[%a = nondet();@]" print_var_as_c v+  | Asgn (v1, v2) ->+      F.fprintf ppf "@[%a = %a@]" print_var_as_c v1 print_var_as_c v2+  | Assm ps ->+      F.fprintf ppf "@[if (!(%a)) { diverge(); }@]" print_predicate_as_c (A.pAnd ps)+  | Asst ps ->+      F.fprintf ppf "@[if (!(%a)) { error(); }@]" print_predicate_as_c (A.pAnd ps)+  | Rget (rv, tupl) ->+      List.map (fun v -> Asgn (mk_temp v, rv_append rv v)) tupl |>+      print_block_as_c ppf+  | Rset (tupl, rv) ->+      List.map (fun v -> Asgn (rv_append rv v, mk_temp v)) tupl |>+      print_block_as_c ppf++and print_block_as_c ppf block =+  F.fprintf ppf "@[%a@]"+    (Misc.pprint_many false "\n" print_instr_as_c) block++let print_list ppf = List.iter (F.fprintf ppf "%s")++let generate_uf (name, numargs) =+  let rec mkargs n s =+    if numargs > 0 then+      mkargs (n-1) ("int, " ^ s)+    else+      s in+  "int " ^ (Sy.to_string name) ^ "(" ^ (mkargs (numargs-1) "int") ^ ") {}"++let prologue =+  [ "void error() { ERROR: goto ERROR; }"+  ; "void diverge() { DIV: goto DIV; }"+  ; "int nondet() { int x; return x; }"+  ; "int main() {"+  ]++let epilogue =+  ["return 0; }"]++let print_program_as_c ppf ((decls, blocks) as program) =+  F.fprintf ppf "@[%a@.%a@.%a@.%a@.%a@.@]"+    print_list (collect_apps_from_program program |> List.map generate_uf)+    print_list prologue+    (Misc.pprint_many false "\n" print_decl_as_c) decls+    (Misc.pprint_many false "\n" print_block_as_c) blocks+    print_list epilogue++let check_imp (decls, instrs) = true+(* Translation from fixpoint to IMP *)++(*************************************************************************)+(************* Converting FixConfig.deft to SMTLIB ***********************)+(*************************************************************************)++(* Declarations *)++let filter_wfs cs =+  (* Misc.maybe_list (List.map (function Cg.Wfc x -> Some x | _ -> None) cs) *)+  Misc.map_partial (function Cg.Wfc x -> Some x | _ -> None) cs++let filter_subt cs =+  Misc.map_partial (function Cg.Cst x -> Some x | _ -> None) cs+  (* Misc.maybe_list (List.map (function Cg.Cst x -> Some x | _ -> None) cs)+   *)++let wf_to_decls wf =+  let vars  = wf |> C.env_of_wf+                 |> C.bindings_of_env+                 |> List.map fst+                 |> Misc.sort_and_compact+  in+  let kvars = C.kvars_of_reft (C.reft_of_wf wf) in+  ( List.map (fun k -> RDecl (snd k, vars)) kvars+  , List.map (fun v -> PDecl v) vars)++let constraints_to_decls cs =+  let decls = List.map wf_to_decls (filter_wfs cs) in+  let (rdecls, pdecls) = (Misc.flap fst decls, Misc.flap snd decls) in+  rdecls @ pdecls ++(* Constraint translation *)++let rec get_kdecl kvar decls =+  match decls with  +  | RDecl (k, vars) :: decls ->+      if k = kvar then+        vars+      else+        get_kdecl kvar decls+  | _ :: decls -> get_kdecl kvar decls+  | [] -> raise Not_found++let sub_to_assume (var, expr) =+  Assm [A.pAtom (A.eVar var, A.Eq, expr)]++(* [[{t | p}]]_get *)++let get_instrs vv decls (subs, kvar) =+  let vars = get_kdecl kvar decls |> List.map (fun v -> TVar v) in+  let assumes = subs |> Ast.Subst.to_list |> List.map sub_to_assume in+  Rget (kvar, vars) :: assumes @+  [Asgn (PVar vv, List.hd vars)]++let set_instr decls (subs, kvar) =+  Rset (List.map (fun v -> TVar v) (get_kdecl kvar decls), kvar)++let emptySol = PredAbs.read PredAbs.empty++let reft_to_get_instrs decls reft =+  let vv = C.vv_of_reft reft in+  let kvars = C.kvars_of_reft reft in+  let preds = C.preds_of_reft emptySol reft in+  match (kvars, preds) with+  | ([], preds) -> Havc (PVar vv) :: Assm preds :: []+  | (kvars, []) -> Misc.flap (get_instrs vv decls) kvars+  | (kvars, preds) -> Misc.flap (get_instrs vv decls) kvars @ ([Assm preds])++(* [[{t | p}]]_set *)++let reft_to_set_instrs decls reft =+  let kvars = C.kvars_of_reft reft in+  let preds = C.preds_of_reft emptySol reft in+  match (kvars, preds) with+  | ([], preds) -> Asst preds :: []+  | (kvars, []) -> List.map (set_instr decls) kvars+  | (kvars, preds) -> List.map (set_instr decls) kvars @ [(Asst preds)]++(* [[x:T; G]] *)++let binding_to_instrs decls (var, reft) =+  reft_to_get_instrs decls reft @ [Asgn (PVar var, PVar (C.vv_of_reft reft))]++let envt_to_instrs decls envt =+  Misc.flap (binding_to_instrs decls) (C.bindings_of_env envt)++let constraint_to_block decls c =+  let (env, grd, lhs, rhs) =+    (C.env_of_t c, C.grd_of_t c, C.lhs_of_t c, C.rhs_of_t c) in+  Assm [grd] ::+  envt_to_instrs decls env @+  reft_to_get_instrs decls lhs @+  reft_to_set_instrs decls rhs++let constraints_to_blocks decls cs =+  List.map (constraint_to_block decls) (filter_subt cs)++let mk_program cs =+  let decls = constraints_to_decls cs in+  (decls, constraints_to_blocks decls cs)++(* API *)+let render ppf cs = +  cs |> mk_program +     |> F.fprintf ppf "%a" print_program_as_c 
+ external/fixpoint/toImp.mli view
@@ -0,0 +1,26 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++val render : Format.formatter -> FixConfig.deft list -> unit++
+ external/fixpoint/toLatex.ml view
@@ -0,0 +1,149 @@+(* translation of constraints to latex *)++module C = FixConstraint+module Su = Ast.Subst+module Misc = FixMisc open Misc.Ops++(* print linebreak after each connective in constraint *)+let c_linebreak = ref true++let q_mathit = Printf.sprintf "\\mathit{%s}"++let sort_to_latex s = Ast.Sort.to_string s |> q_mathit+let symbol_to_latex s = +  Ast.Symbol.to_string s+  |> Str.global_replace (Str.regexp "_") "\\_" +  |> Str.global_replace (Str.regexp "#") "\\#" |> q_mathit+let constant_to_latex = Ast.Constant.to_string++let bop_to_latex = function +  | Ast.Plus  -> "+"+  | Ast.Minus -> "-"+  | Ast.Times -> ""+  | Ast.Div   -> "/"+let brel_to_latex = function +  | Ast.Eq -> "="+  | Ast.Ne -> "!="+  | Ast.Gt -> ">"+  | Ast.Ge -> "\\geq"+  | Ast.Lt -> "<"+  | Ast.Le -> "\\leq"+let bind_to_latex (s, t) = +  Printf.sprintf "%s:%s" (symbol_to_latex s) (sort_to_latex t)+let rec expr_to_latex (e, _) = +  match e with+    | Ast.Con c -> constant_to_latex c+    | Ast.Var s -> symbol_to_latex s+    | Ast.App (s, es) ->+	Printf.sprintf "%s([%s])" +	  (symbol_to_latex s) (List.map expr_to_latex es |> String.concat " ")+    | Ast.Bin (e1, op, e2) ->+	Printf.sprintf "(%s %s %s)" +	  (expr_to_latex e1) (bop_to_latex op) (expr_to_latex e2)+    | Ast.Ite (ip, te, ee) -> +	Printf.sprintf "%s ? %s : %s" +	  (pred_to_latex ip) (expr_to_latex te) (expr_to_latex ee)+    | Ast.Fld (s, e) -> +	Printf.sprintf "%s.%s" (expr_to_latex e) (symbol_to_latex s)+and pred_to_latex (p, _) = +  match p with+    | Ast.True -> "\\ltrue"+    | Ast.False -> "\\lfalse"+    | Ast.Bexp e -> expr_to_latex e+    | Ast.Not p -> Printf.sprintf "\\neg (%s)" (pred_to_latex p) +    | Ast.Imp (p1, p2) -> +	Printf.sprintf "(%s \\limp %s)" (pred_to_latex p1) (pred_to_latex p2)+    | Ast.And ps -> +	if ps = [] then "\\ltrue" else+	  List.map pred_to_latex ps |> String.concat " \\land "+    | Ast.Or ps -> +	if ps = [] then "\\lfalse" else+	  List.map pred_to_latex ps |> String.concat " \\lor "+    | Ast.Atom (e1, r, e2) ->+	Printf.sprintf "(%s %s %s)" +          (expr_to_latex e1) (brel_to_latex r) (expr_to_latex e2)+    | Ast.Forall (qs,p) -> +	Printf.sprintf "\\forall %s: %s" +          (List.map bind_to_latex qs |> String.concat ", ") (pred_to_latex p)+let subst_to_latex (s, e) = +  Printf.sprintf "[%s/%s]" (expr_to_latex e) (symbol_to_latex s)+let refa_to_latex refa =+  match refa with +    | C.Conc pred -> pred_to_latex pred+    | C.Kvar (subs, sym) -> +	Printf.sprintf "%s%s" +	  (symbol_to_latex sym)+	  (List.map subst_to_latex (Su.to_list subs) |> String.concat "")+let reft_to_latex (v, b, r) = +  Printf.sprintf "\\{ %s:%s \\mid %s \\}"+    (symbol_to_latex v) (sort_to_latex b) +    (if r = [] then "\\ltrue" else+       (List.map refa_to_latex r |> String.concat " \\land "))+let envt_to_latex envt = +  if Ast.Symbol.SMap.is_empty envt then+    "\\ltrue;\\ "+  else+    Ast.Symbol.SMap.fold +      (fun sym reft sofar -> +	 Printf.sprintf "%s:%s;%s%s" +	   (symbol_to_latex sym) (reft_to_latex reft) +	   (if !c_linebreak then "\\\\\n" else "\\ ")+	   sofar) envt ""++let c_to_latex out c = +  Printf.fprintf out +    "\\begin{footnotesize}+  \\begin{verbatim}+%s+  \\end{verbatim}+\\end{footnotesize}+" (C.to_string c);+  Printf.fprintf out+    "\\begin{displaymath}+  \\begin{array}[t]{l}+  %s %s\\ \\deriv\\\\ %s\\ <:\\\\ %s\\qquad %s+  \\end{array}+\\end{displaymath}+\\hrule+" +    (C.env_of_t c |> envt_to_latex)  +    (C.grd_of_t c |> pred_to_latex)+    (C.lhs_of_t c |> reft_to_latex) +    (C.rhs_of_t c |> reft_to_latex)+    (try string_of_int (C.id_of_t c) with _ -> "")++let wf_to_latex out wf = +  Printf.fprintf out+    "\\begin{displaymath}+  \\begin{array}[t]{l}+  %s\\ \\deriv\\ %s\\qquad %s+  \\end{array}+\\end{displaymath}+\\hrule+" +    (C.env_of_wf wf |> envt_to_latex)  +    (C.reft_of_wf wf |> reft_to_latex)+    (try string_of_int (C.id_of_wf wf) with _ -> "")+++let to_latex out cs ws = +  print_endline "Translating to LaTeX.";+  Printf.fprintf out +"\\documentclass[10pt]{llncs}+\\pagestyle{plain}+\\usepackage{amsmath}+\\newcommand{\\ltrue}{\\mathit{true}}+\\newcommand{\\lfalse}{\\mathit{false}}+\\newcommand{\\limp}{\\rightarrow}+\\newcommand{\\deriv}{\\vdash}+\\begin{document}+";+  List.iter (c_to_latex out) cs;+  List.iter (wf_to_latex out) ws;+  Printf.fprintf out +"\\end{document}+%%%%%% Local Variables: +%%%%%% mode: latex+%%%%%% TeX-master: t+%%%%%% End: +"
+ external/fixpoint/toQARMC.ml view
@@ -0,0 +1,721 @@+(* translation to Q'ARMC *)+++module C  = FixConstraint+module Co = Constants +module Sy = Ast.Symbol+module Su = Ast.Subst+module P = Ast.Predicate+module E = Ast.Expression+module StrMap = Map.Make (struct type t = string let compare = compare end)+module StrSet = Set.Make (struct type t = string let compare = compare end)+module Misc = FixMisc open Misc.Ops++let strlist_to_strset = List.fold_left (fun s x -> StrSet.add x s) StrSet.empty++(* Andrey: TODO move to ast.ml? *)+let pred_is_atomic (p, _) =+  match p with+    | Ast.True | Ast.False | Ast.Bexp _ | Ast.Atom _ -> true+    | Ast.And _ | Ast.Or _ | Ast.Not _ | Ast.Imp _ | Ast.Forall _ -> false++let pred_is_true (p, _) = +  match p with +    | Ast.True -> true+    | Ast.Atom (e1, Ast.Eq, e2) -> E.to_string e1 = E.to_string e2 +    | _ -> false++let neg_brel = function +  | Ast.Eq -> Ast.Ne+  | Ast.Ne -> Ast.Eq+  | Ast.Gt -> Ast.Le+  | Ast.Ge -> Ast.Lt+  | Ast.Lt -> Ast.Ge+  | Ast.Le -> Ast.Gt++let rec push_neg ?(neg=false) ((p, _) as pred) =+  match p with+    | Ast.True -> if neg then Ast.pFalse else pred+    | Ast.False -> if neg then Ast.pTrue else pred+    | Ast.Bexp _ -> if neg then Ast.pNot pred else pred+    | Ast.Not p -> push_neg ~neg:(not neg) p+    | Ast.Imp (p, q) -> +	if neg then Ast.pAnd [push_neg p; push_neg ~neg:true q]+	else Ast.pImp (push_neg p, push_neg q)+    | Ast.Forall (qs, p) -> +	let pred' = Ast.pForall (qs, push_neg ~neg:false p) in+	  if neg then Ast.pNot pred' else pred'+    | Ast.And ps -> List.map (push_neg ~neg:neg) ps |> if neg then Ast.pOr else Ast.pAnd+    | Ast.Or ps -> List.map (push_neg ~neg:neg) ps |> if neg then Ast.pAnd else Ast.pOr+    | Ast.Atom (e1, brel, e2) -> if neg then Ast.pAtom (e1, neg_brel brel, e2) else pred++(* Andrey: TODO flatten nested conjunctions/disjunctions *)+let rec simplify_tauto ((p, _) as pred) =+  match p with+    | Ast.Not p -> Ast.pNot (simplify_tauto p)+    | Ast.Imp (p, q) -> Ast.pImp (simplify_tauto p, simplify_tauto q) +    | Ast.Forall (qs, p) -> Ast.pForall (qs, simplify_tauto p)+    | Ast.And ps -> +	let ps' = List.map simplify_tauto ps |> List.filter (fun p -> not(P.is_tauto p)) in+	  if List.mem Ast.pFalse ps' then Ast.pFalse else+	    begin+	      match ps' with+		| [] -> Ast.pTrue+		| [p'] -> p'+		| _ :: _ -> Ast.pAnd ps'+	    end+    | Ast.Or ps -> +	let ps' = List.map simplify_tauto ps in+	  if List.exists P.is_tauto ps' then Ast.pTrue else +	    begin+	      match ps' with+		| [] -> Ast.pFalse+		| [p'] -> p'+		| _ :: _ -> Ast.pOr ps'+	    end+    | _ -> pred++let rec partition_pred_defs edefs pdefs ((p, _) as pred) = +  match p with+    | Ast.Atom ((Ast.Var v, _), Ast.Eq, e) -> Ast.pTrue, Sy.SMap.add v e edefs, pdefs+    | Ast.And [Ast.Imp ((Ast.Bexp (Ast.Var v1, _), _), p1), _; +	       Ast.Imp (p2, (Ast.Bexp (Ast.Var v2, _), _)), _] when v1 = v2 && p1 = p2 -> +	Ast.pTrue, edefs, Sy.SMap.add v1 p1 pdefs+    | Ast.And preds -> +	let preds', edefs', pdefs' = List.fold_left +	  (fun (preds_sofar, edefs_sofar, pdefs_sofar) p ->+	     let p'', edefs'', pdefs'' = partition_pred_defs edefs_sofar pdefs_sofar p in+	       p'' :: preds_sofar, edefs'', pdefs''+	  ) ([], edefs, pdefs) preds in+	  (Ast.pAnd preds'), edefs', pdefs'+    | _ -> pred, edefs, pdefs++let rec defs_of_pred edefs pdefs (p, _) = +  match p with+    | Ast.Atom ((Ast.Var v, _), Ast.Eq, e) -> Sy.SMap.add v e edefs, pdefs+    | Ast.And [Ast.Imp ((Ast.Bexp (Ast.Var v1, _), _), p1), _; +	       Ast.Imp (p2, (Ast.Bexp (Ast.Var v2, _), _)), _] when v1 = v2 && p1 = p2 -> +	edefs, Sy.SMap.add v1 p1 pdefs+    | Ast.And preds -> +	let edefs', pdefs' = List.fold_left +	  (fun (edefs_sofar, pdefs_sofar) p ->+	     let edefs'', pdefs'' = defs_of_pred edefs_sofar pdefs_sofar p in+	       edefs'', pdefs''+	  ) (edefs, pdefs) preds in+	  edefs', pdefs'+    | _ -> edefs, pdefs+++let some_def_applied = ref false+let rec expr_apply_defs edefs pdefs ((e, _) as expr) = +  let current_some_def_applied = !some_def_applied in+    some_def_applied := false;+    let expr'' =+      match e with+	| Ast.Con _ -> expr+	| Ast.Var v -> +	    begin+	      try+		let expr' = Sy.SMap.find v edefs in+		  some_def_applied := true;+		  expr'+	      with Not_found -> expr+	    end+	| Ast.App (v, es) -> +	    let edefs' = Sy.SMap.remove v edefs in+	      Ast.eApp (v, List.map (expr_apply_defs edefs' pdefs) es)+	| Ast.Bin (e1, op, e2) -> +	    Ast.eBin (expr_apply_defs edefs pdefs e1, op, expr_apply_defs edefs pdefs e2)+	| Ast.Ite (p, e1, e2) -> +	    Ast.eIte (pred_apply_defs edefs pdefs p, +		      expr_apply_defs edefs pdefs e1,+		      expr_apply_defs edefs pdefs e2)+	| Ast.Fld (v, e) -> +	    let v' = +	      try+		match Sy.SMap.find v edefs with+		  | (Ast.Var v'', _) -> +		      some_def_applied := true;+		      v''+		  | _ -> v+	      with Not_found -> v+	    in+	      Ast.eFld (v', expr_apply_defs edefs pdefs e)+    in+      if !some_def_applied then+	let expr''' = expr_apply_defs edefs pdefs expr'' in+	  some_def_applied := current_some_def_applied;+	  expr'''+      else+	begin+	  some_def_applied := current_some_def_applied;+	  expr''+	end+and pred_apply_defs edefs pdefs ((p, _) as pred) =+  let current_some_def_applied = !some_def_applied in+    some_def_applied := false;+    let pred'' =+      match p with+	| Ast.And ps -> List.map (pred_apply_defs edefs pdefs) ps |> Ast.pAnd+	| Ast.Or ps -> List.map (pred_apply_defs edefs pdefs) ps |> Ast.pOr+	| Ast.Not p -> pred_apply_defs edefs pdefs p |> Ast.pNot+	| Ast.Imp (p, q) -> Ast.pImp (pred_apply_defs edefs pdefs p, pred_apply_defs edefs pdefs q)+	| Ast.Bexp (Ast.Var v, _) ->+	    begin+	      Printf.printf "Applying on Bexp: %s\n" (P.to_string pred);+	      (* Andrey: TODO also consider edefs *)+	      try+		let expr' = Sy.SMap.find v edefs in+		  some_def_applied := true;+		  Ast.pBexp expr'+	      with Not_found ->+		try+		  let pred' = Sy.SMap.find v pdefs in+		    some_def_applied := true;+		    pred'+		with Not_found ->+		  pred+	    end+	| Ast.Atom (e1, brel, e2) ->+	    Ast.pAtom (expr_apply_defs edefs pdefs e1, brel, expr_apply_defs edefs pdefs e2)+	| Ast.Forall (qs, p) ->+	    let vs = List.map fst qs in+	    let edefs' = List.fold_left (fun defs v -> Sy.SMap.remove v defs) edefs vs in+	    let pdefs' = List.fold_left (fun defs v -> Sy.SMap.remove v defs) pdefs vs in+	      Ast.pForall (qs, pred_apply_defs edefs' pdefs' p)+	| _ -> pred+    in+      if !some_def_applied then+	let pred''' = pred_apply_defs edefs pdefs pred'' in+	  some_def_applied := current_some_def_applied;+	  pred'''+      else +	begin+	  some_def_applied := current_some_def_applied;+	  pred''+	end+      ++let support_of_env sol env =+  Sy.SMap.fold+    (fun ksym reft sup -> +       let vv = C.vv_of_reft reft in+       let kv = Ast.eVar ksym in+       let syms = C.preds_of_reft sol reft |>+	   List.map (fun p -> P.subst p vv kv) |> List.filter (fun p -> not(pred_is_true p)) |>+	       List.map P.support |> List.flatten+       in+	 List.fold_left (fun sup' sym -> Sy.SSet.add sym sup') sup syms+    ) env Sy.SSet.empty++++let armc_true = "true"+let armc_false = "false"+let loop_pc = "loop"+let start_pc = "start"+let error_pc = "error"+let val_vname = "VVVV"+let exists_kv = "EX"+let primed_suffix = "p"+let str__cil_tmp = "__cil_tmp"++type kv_scope = {+  kvs : string list;+  kv_scope : string list StrMap.t+}++type horn_clause = {+  body_pred : Ast.pred;+  body_kvars : (Su.t * Sy.t) list;+  head_pred : Ast.pred;+  head_kvars : (Su.t * Sy.t) list;+  tag : string;+}++let sanitize_symbol s = +  Str.global_replace (Str.regexp "@") "_at_"  s |> Str.global_replace (Str.regexp "#") "_hash_" |>+      Str.global_replace (Str.regexp "\\.") "_dot_" |> Str.global_replace (Str.regexp "'") "_q_" ++let symbol_to_armc s = Sy.to_string s |> sanitize_symbol++let var_to_armc s = Sy.to_string s |> sanitize_symbol |> String.capitalize++let subs_to_map subs = +  List.fold_left +    (fun m (s, e) -> +      StrMap.add (symbol_to_armc s) e m+    ) StrMap.empty (Su.to_list subs)++let mk_data_var ?(suffix = "") kv v = +  Printf.sprintf "_%s_%s%s%s" +    (sanitize_symbol v) (sanitize_symbol kv) (if suffix = "" then "" else "_") suffix++	+(*+let defs_of_env state env = +  Sy.SMap.fold +    (fun ksym reft defs ->+       let vv = C.vv_of_reft reft in+       let kv = Ast.eVar ksym in+       let defs' = C.preds_of_reft state.sol reft |>+	   List.map (fun p -> P.subst p vv kv) |> List.filter (fun p -> not(pred_is_true p)) |>+	       List.map (defs_of_pred state) |> List.flatten+       in+	 defs' ++ defs+    ) env []+*)++let constant_to_armc = Ast.Constant.to_string+let bop_to_armc = function +  | Ast.Plus  -> "+"+  | Ast.Minus -> "-"+  | Ast.Times -> "*"+  | Ast.Div   -> "/"+let brel_to_armc = function +  | Ast.Eq -> "="+  | Ast.Ne -> "=\\="+  | Ast.Gt -> ">"+  | Ast.Ge -> ">="+  | Ast.Lt -> "<"+  | Ast.Le -> "=<"+let bind_to_armc (s, t) = (* Andrey: TODO support binders *)+  Printf.sprintf "%s:%s" (symbol_to_armc s) (Ast.Sort.to_string t |> sanitize_symbol)+let rec expr_to_armc (e, _) = +  match e with+    | Ast.Con c -> constant_to_armc c+    | Ast.Var s -> var_to_armc s+    | Ast.App (s, es) -> +	if !Co.purify_function_application then "_" else+	  let str = symbol_to_armc s in+	    if es = [] then str else+	      Printf.sprintf "f_%s(%s)" str (List.map expr_to_armc es |> String.concat ", ")+    | Ast.Bin (e1, op, e2) ->+	Printf.sprintf "(%s %s %s)" +	  (expr_to_armc e1) (bop_to_armc op) (expr_to_armc e2)+    | Ast.Ite (ip, te, ee) -> +	Printf.sprintf "ite(%s, %s, %s)" +	  (pred_to_armc ip) (expr_to_armc te) (expr_to_armc ee)+    | Ast.Fld (s, e) -> +	Printf.sprintf "fld(%s, %s)" (expr_to_armc e) (symbol_to_armc s)+and pred_to_armc ((p, _) as pred) = +  if pred_is_true pred then +    armc_true+  else+    match p with+      | Ast.True -> armc_true+      | Ast.False -> armc_false+      | Ast.Bexp e -> Printf.sprintf "bexp(%s)" (expr_to_armc e)+      | Ast.Not (Ast.True, _) -> armc_false+      | Ast.Not (Ast.False, _) -> armc_true+      | Ast.Not p -> Printf.sprintf "neg(%s)" (pred_to_armc p) +      | Ast.Imp (p1, p2) -> Printf.sprintf "imp(%s, %s)" (pred_to_armc p1) (pred_to_armc p2)+      | Ast.And [] -> armc_true+      | Ast.And [p] -> pred_to_armc p+      | Ast.And [Ast.Imp ((Ast.Bexp e1, _) as p, p1), _; +		 Ast.Imp (p2, (Ast.Bexp e2, _)), _] when e1 = e2 && p1 = p2 -> +	  Printf.sprintf "bexp_def(%s, %s)" (pred_to_armc p) (pred_to_armc p1)+      | Ast.And (_::_ as ps) -> +	  Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat ", ")+      | Ast.Or [] -> armc_false+      | Ast.Or [p] -> pred_to_armc p+      | Ast.Or (_::_ as ps) -> Printf.sprintf "(%s)" (List.map pred_to_armc ps |> String.concat "; ")+      | Ast.Atom (e1, Ast.Eq, (Ast.Ite(ip, te, ee), _)) ->+	  let ip_str = pred_to_armc ip in+	  let e1_str = expr_to_armc e1 in+	    Printf.sprintf "((%s, %s = %s); (neg(%s), %s = %s))"+	      ip_str e1_str (expr_to_armc te) +	      ip_str e1_str (expr_to_armc ee) +      | Ast.Atom (e1, r, e2) ->+	  Printf.sprintf "%s %s %s" +            (expr_to_armc e1) (brel_to_armc r) (expr_to_armc e2)+      | Ast.Forall (qs,p) -> (* Andrey: TODO support forall *) +	  Printf.sprintf "forall([%s], %s)" +            (List.map bind_to_armc qs |> String.concat ", ") +	    (pred_to_armc p)+++let mk_kv_scope out ts wfs =+  (*  let kvs = List.map C.kvars_of_t ts |> List.flatten |> List.map snd |> +      List.map symbol_to_armc |> (* (fun s -> Printf.sprintf "k%s" (symbol_to_armc s)) |> *)+      Misc.sort_and_compact in+  *)+  let kv_scope_wf =+    List.fold_left+      (fun m wf ->+	match C.reft_of_wf wf |> C.ras_of_reft with+	  | [C.Kvar (subs, kvar)] when Su.is_empty subs ->+	    let v = symbol_to_armc kvar in+	    let scope = +(*	      val_vname :: *)+		(C.env_of_wf wf +		    |> C.bindings_of_env +		    |> List.filter +			(fun (_, (_, typ, _)) ->+			  Ast.Sort.t_int = typ+			)+		    |> List.map fst +		    |> List.map symbol_to_armc +		    |> List.filter +			(fun s -> +			  not(Misc.is_prefix str__cil_tmp s +			      || Misc.is_prefix "FP_" s+			      || Misc.is_prefix "Open_" s+			      || Misc.is_prefix "None_0" s+			      || Misc.is_prefix "Some_0" s+			      || Misc.is_prefix "true_0" s+			      || Misc.is_prefix "false_0" s+			      || Misc.is_prefix "Pervasives_" s+			      || Misc.is_prefix "FIXPOINTSYMBOL_" s)) +		    |> List.sort compare) +	    in+	    StrMap.add v scope m+	  | _ -> m+      (* Andrey: TODO handle ill-formed wf *)+      (*		 Format.printf "%a" (C.print_wf None) wf;+			 +			 failure "ERROR: kname_scope_map: ill-formed wf"+      *)+      ) StrMap.empty wfs in+  let kv_scope_t =+    List.fold_left +      (fun m (subs, kvar) ->+	let v = symbol_to_armc kvar in+	let scope = +	  List.filter (fun (v, (e, _)) -> +	    match e with+	      | Ast.Var v' -> v <> v'+	      | _ -> true+	  ) (Su.to_list subs) |> +	      List.map fst |> List.map symbol_to_armc |> strlist_to_strset in+	let scope' = try StrMap.find v m with Not_found -> StrSet.empty in+	StrMap.add v (StrSet.union scope scope') m+      ) StrMap.empty (List.map C.kvars_of_t ts |> List.flatten) in+  let kv_scope = kv_scope_wf in+  let kv_scope_old = +    StrMap.map (fun scope -> val_vname :: (StrSet.elements scope |> List.sort compare)) kv_scope_t in+  let kvs = StrMap.fold (fun kv _ kvs -> kv :: kvs) kv_scope [] in+  (* +  StrMap.iter (fun kv scope ->+    Printf.fprintf out "%% %s -> %s\n" kv (String.concat ", " scope)) kv_scope;+  *)+  {kvs = kvs; kv_scope = kv_scope}++let mk_data ?(suffix = "") ?(skip_kvs = []) s = +  Printf.sprintf "[%s]"+    (List.map +       (fun kv ->+	  try +	    StrMap.find kv s.kv_scope |> +		List.map (mk_data_var ~suffix:(if List.mem kv skip_kvs then "" else suffix) kv)+	  with Not_found -> failure "ERROR: mk_data: scope not found for %s" kv+       ) s.kvs |> List.flatten |> String.concat ", ")++let mk_query ?(suffix = "") s kv = +  Printf.sprintf "k%s(%s)" +    kv (List.map (mk_data_var ~suffix:suffix kv) (StrMap.find kv s.kv_scope) |> String.concat ", ")++let mk_var2names state = +  List.map+    (fun kv ->+       Printf.sprintf "var2names(p(pc(k%s), data(%s)), [%s])."+	 kv+	 (List.map (mk_data_var kv) (StrMap.find kv state.kv_scope) |> String.concat ", ")+	 (List.map +	    (fun v -> +	       Printf.sprintf "(%s, \'%s_%s\')" (mk_data_var kv v)  v kv+	    ) (StrMap.find kv state.kv_scope) |> String.concat ", ")+    ) state.kvs |> String.concat "\n"++let mk_skip_update state kvs = +  if kvs = [] then armc_true else+    List.map+      (fun kv ->+	 List.map +	   (fun v -> +	      Printf.sprintf "%s = %s"+		(mk_data_var ~suffix:primed_suffix kv v) (mk_data_var kv v)+	   ) (StrMap.find kv state.kv_scope) |> String.concat ", "+      ) kvs |> String.concat ", "++let mk_update_str from_vs to_vs updates = +  List.map2+    (fun v vp ->+       Printf.sprintf "%s = %s" vp (try StrMap.find v updates with Not_found -> v)+    ) from_vs to_vs |> String.concat ", "++let split_scope scope = +  match scope with+    | value :: data -> value, data+    | _ -> failure "ERROR: split_scope: empty scope %s" (String.concat ", " scope)++let reft_to_armc ?(noquery = false) ?(suffix = "") state reft = +  let vv = C.vv_of_reft reft |> symbol_to_armc in+  let rs = C.ras_of_reft reft in+    if rs = [] then armc_true else+      List.map+	(function+	   | C.Conc pred -> pred_to_armc pred+	   | C.Kvar (subs, sym) -> +	     failwith "AR: toQARMC.ml reft_to_armc";+	     if true (* Sy.SMap.mem sym state.sol && Sy.SMap.find sym state.sol = [] *)then +		 armc_true  (* skip true *)+	       else+		 let subs_map = subs_to_map subs in+		 let find_subst v default = +		   try StrMap.find v subs_map |> expr_to_armc with Not_found -> default in+		 let kv = symbol_to_armc sym in+		 let value, data = StrMap.find kv state.kv_scope |> split_scope in+		   Printf.sprintf "%s%s = %s" +		     (if noquery then "" else (mk_query ~suffix:suffix state kv) ^ ", ")+		     (mk_data_var ~suffix:suffix kv value) +		     (find_subst vv (mk_data_var exists_kv vv)) +		   :: List.map+		     (fun v -> +			Printf.sprintf "%s = %s"+			  (mk_data_var ~suffix:suffix kv v)+			  (find_subst v (mk_data_var exists_kv v))+		     ) data |> String.concat ", "+	) rs |> String.concat ", "++let mk_rule head annot_guards annot_updates id = +  let rec annot_conj_to_armc = function+    | (g, a) :: rest -> +	if rest = [] then Printf.sprintf "\n   %s \t%% %s\n  ]," g a+	else Printf.sprintf "\n   %s, \t%% %s%s" g a (annot_conj_to_armc rest)+    | [] -> "],"+  in+    Printf.sprintf+      "+hc(%s, [%s  %s).+" +      head (annot_guards @ annot_updates |> List.filter (fun (g, _) -> g <> armc_true) |> annot_conj_to_armc) id++let preds_kvars_of_reft reft =+  List.fold_left +    (fun (ps, ks) r ->+       match r with+	 | C.Conc p -> p :: ps, ks+	 | C.Kvar (subs, kvar) -> ps, (subs, kvar) :: ks+    ) ([], []) (C.ras_of_reft reft)++let t_to_horn_clause t =+  let lhs_ps, lhs_ks = C.lhs_of_t t |> preds_kvars_of_reft in+  let body_ps, body_ks = +    Sy.SMap.fold +      (fun bv reft (ps, ks) -> +	 let ps', ks' = preds_kvars_of_reft (C.theta (Su.of_list [(C.vv_of_reft reft, Ast.eVar bv)]) reft) in+	   List.rev_append ps' ps, List.rev_append ks' ks+      ) (C.env_of_t t) (C.grd_of_t t :: lhs_ps, lhs_ks) in+  let head_ps, head_ks = C.rhs_of_t t |> preds_kvars_of_reft in+    {+      body_pred = Ast.pAnd body_ps |> simplify_tauto; +      body_kvars = body_ks; +      head_pred = Ast.pAnd head_ps |> simplify_tauto;+      head_kvars = head_ks;+      tag = try string_of_int (C.id_of_t t) with _ -> failure "ERROR: t_to_horn_clause: anonymous constraint %s" (C.to_string t)+    }++let simplify_horn_clause hc = +  let body_edefs, body_pdefs = defs_of_pred Sy.SMap.empty Sy.SMap.empty hc.body_pred in+  let edefs, pdefs = defs_of_pred body_edefs body_pdefs hc.head_pred in+    {+      body_pred = pred_apply_defs edefs pdefs hc.body_pred |> simplify_tauto; +      body_kvars = hc.body_kvars; +      head_pred = pred_apply_defs edefs pdefs hc.head_pred |> simplify_tauto;+      head_kvars = hc.head_kvars; +      tag = hc.tag+    }++let print_horn_clause hc = +  Printf.printf "%s: %s, %s :- %s, #%d %s\n"+    hc.tag +    (P.to_string hc.head_pred)+    (List.map (fun (subs, kvar) -> C.refa_to_string (C.Kvar (subs, kvar))) hc.head_kvars |> String.concat ", ")+    (P.to_string hc.body_pred)+    (List.length hc.body_kvars)+    (List.map (fun (subs, kvar) -> C.refa_to_string (C.Kvar (subs, kvar))) hc.body_kvars |> String.concat ", ")++    +let t_to_armc state t = +  t_to_horn_clause t |> simplify_horn_clause |> print_horn_clause;+  let env = C.env_of_t t in+  let grd = C.grd_of_t t in+  let lhs = C.lhs_of_t t in+  let rhs = C.rhs_of_t t in+  let rhs_s = C.reft_to_string rhs in+  let tag = try string_of_int (C.id_of_t t) with _ -> +    failure "ERROR: t_to_armc: anonymous constraint %s" (C.to_string t) in+(*   let defs = defs_of_env state env in *)+  let annot_guards = +    Misc.map_partial+      (fun (bv, reft) ->+	 if C.ras_of_reft reft <> [] then+	   Some (reft_to_armc state (C.theta (Su.of_list [(C.vv_of_reft reft, Ast.eVar bv)]) reft),+		 C.binding_to_string (bv, reft))+	 else+	   None+      ) (env |> C.bindings_of_env)+    ++ [(pred_to_armc grd, P.to_string grd); +	(reft_to_armc state lhs, "|- " ^ (C.reft_to_string lhs))] in+  let ps, kvs =  +    List.fold_left (fun (ps', kvs') refa ->+		      match refa with+			| C.Conc p -> p::ps', kvs'+			| C.Kvar (subs, sym) -> ps', (subs, sym)::kvs'+		   ) ([], []) (C.ras_of_reft rhs) in+(* Andrey: obsolete code+  let env_sup = support_of_env state.sol env |> Sy.SSet.elements in+    Printf.printf "Rule %s\n" tag;+    Printf.printf "Env support #%d: %s\n" +      (List.length env_sup) (env_sup |> List.map Sy.to_string |> String.concat ", ");+    Printf.printf "Guard support %s: %s\n" +      (P.to_string grd) +      (P.support grd |> List.map Sy.to_string |> String.concat ", ");+*)    +    (if ps <> [] then+       [mk_rule error_pc annot_guards [(Ast.pAnd ps |> Ast.pNot |> pred_to_armc, "<: " ^ rhs_s)] tag]+     else +       [])+    +++      (List.map +	 (fun (_, sym) ->+	    mk_rule (mk_query ~suffix:primed_suffix state (symbol_to_armc sym))+	      annot_guards +	      [(reft_to_armc ~noquery:true ~suffix:primed_suffix state rhs, "<: " ^ rhs_s)]+	      tag+	 ) kvs)+++(*+  make -f Makefile.fixtop && ./f -latex /tmp/main.tex -armc /tmp/a.pl tests/pldi08-max.fq && cat /tmp/a.pl++tests:++for file in `ls pldi08-*-atom.fq`; do ../f -latex /tmp/main.tex -armc /tmp/a.pl $file; head -n 1 /tmp/a.pl; armc a.pl | grep correct; done++pldi08-arraymax-atom.fq  pass+pldi08-max-atom.fq       pass+pldi08-foldn-atom.fq     pass+pldi08-sum-atom.fq       pass+mask-atom.fq             pass+samples-atom.fq          pass ++test00.c                 pass++*)++let subs_kvar_to_strs state ?(suffix = "") subs kvar =+  let kv = symbol_to_armc kvar in +  let scope = StrMap.find kv state.kv_scope in+  let scope_set = strlist_to_strset scope in+  let subs_map = subs_to_map subs in+  let kvar_str = +    Printf.sprintf "%s(%s)" kv+      (List.map +	 (fun v ->+	   let v_cap = String.capitalize v in+	   let v_cap_suffix = v_cap ^ suffix in+	   try +	     match StrMap.find v subs_map with+	       | (Ast.Var s, _) -> +		 let v_exp = var_to_armc s in+		 if StrSet.mem v_exp scope_set then v_cap_suffix+		 else v_exp+	       | _ -> v_cap_suffix+	   with Not_found -> v_cap+	 ) scope |> String.concat ", ") +  in+  let subs_strs = +    StrMap.fold (fun v e acc ->+      let subs_str = +	Printf.sprintf "%s%s = %s" +	  (String.capitalize v) suffix (StrMap.find v subs_map |> expr_to_armc)+      in+      match e with +	| (Ast.Var s, _) -> +	  let v_exp = var_to_armc s in+	  if StrSet.mem v_exp scope_set then subs_str :: acc+	  else acc+	| _ -> subs_str :: acc+    ) subs_map [] +  in+  kvar_str, subs_strs++let mk_query_naming state = +  List.map+    (fun kv ->+      Printf.sprintf "query_naming(%s(%s))." kv+	(StrMap.find kv state.kv_scope +	    |> List.map +		(fun v -> +		  if 'a' <= v.[0] && v.[0] <= 'z' then v+		  else Printf.sprintf "'%s'" v+		) +	    |> String.concat ", ")+    ) state.kvs |> String.concat "\n"++exception ValidClause+let horn_clause_to_tc state hc = +  let head_str, head_grd_strs = +(*+    match hc.head_kvars with+      | [(subs, kvar)] -> +	let head_kvar_str, head_subs_strs = +	  subs_kvar_to_strs state ~suffix:"_0" subs kvar +	in+	head_kvar_str, head_subs_strs+      | [] -> +	let head_pred = push_neg ~neg:true hc.head_pred |> simplify_tauto in+	"false", if P.is_tauto head_pred then [] else [pred_to_armc head_pred]+      | _ :: _ -> +	print_horn_clause hc;+	failwith ("horn_clause_to_tc: unexpected clause " ^ hc.tag)+*)+    match P.is_tauto hc.head_pred, hc.head_kvars with+    | true, [(subs, kvar)] -> +    let head_kvar_str, head_subs_strs = +    subs_kvar_to_strs state ~suffix:"_0" subs kvar +    in+    head_kvar_str, head_subs_strs+    | true, [] -> raise ValidClause+    | false, [] -> +    let head_pred = push_neg ~neg:true hc.head_pred |> simplify_tauto in+    "false", if P.is_tauto head_pred then [] else [pred_to_armc head_pred]+    | _, _ -> +    print_horn_clause hc;+    failwith ("horn_clause_to_tc: unexpected clause " ^ hc.tag)+  in +  let tag_str = Printf.sprintf "id(%s)" hc.tag in+  let simple_body_pred = hc.body_pred |> push_neg ~neg:false |> simplify_tauto in+  let grd_tag_strs = +    if P.is_tauto simple_body_pred then tag_str :: head_grd_strs+    else pred_to_armc simple_body_pred :: tag_str :: head_grd_strs+  in+  let body_strs, _ = +    List.fold_left (fun (s, n) (subs, kvar) -> +      let kvar_str, subs_strs = subs_kvar_to_strs state ~suffix:("_" ^ string_of_int n) subs kvar in+      kvar_str :: (subs_strs ++ s),+      n+1+    ) (grd_tag_strs, 1) hc.body_kvars+  in+  Printf.sprintf "%s :- %s.\n" head_str (body_strs |> List.rev |> String.concat ", ")++let to_qarmc out ts wfs =+  print_endline "Translating to QARMC.";+  +  print_endline "=========================";+  List.iter (Format.printf "%a" (C.print_t None)) ts;+  print_endline "=========================";++  let state = mk_kv_scope out ts wfs in+(*  let hcs = List.map (fun t -> t_to_horn_clause t |> simplify_horn_clause) ts in *)+  let hcs = List.map t_to_horn_clause ts in+  output_string out (mk_query_naming state);+  output_string out "\n\n";+  List.iter (fun hc -> +    try horn_clause_to_tc state hc |> output_string out+    with ValidClause -> ()+  ) hcs;+  print_endline "heheheheh";+  List.iter (fun hc -> print_horn_clause hc; output_string out "\n") hcs
+ external/fixpoint/toRawHorn.ml view
@@ -0,0 +1,200 @@+(* Dumping constraints as Horn clauses without any simplifications *)++module C  = FixConstraint+module Co = Constants +module Sy = Ast.Symbol+module Su = Ast.Subst+module P = Ast.Predicate+module E = Ast.Expression+module StrMap = Map.Make (struct type t = string let compare = compare end)+module StrSet = Set.Make (struct type t = string let compare = compare end)+module Misc = FixMisc open Misc.Ops++let raw_true = "1=1"+let raw_false = "0=1"+++let sanitize_symbol s = +  Str.global_replace (Str.regexp "@") "_at_"  s |> Str.global_replace (Str.regexp "#") "_hash_" |>+      Str.global_replace (Str.regexp "\\.") "_dot_" |> Str.global_replace (Str.regexp "'") "_q_" ++let symbol_to_raw s = Sy.to_string s |> sanitize_symbol+let constant_to_raw = Ast.Constant.to_string+let bop_to_raw = function +  | Ast.Plus  -> "+"+  | Ast.Minus -> "-"+  | Ast.Times -> "*"+  | Ast.Div   -> "/"+let brel_to_raw = function +  | Ast.Eq -> "="+  | Ast.Ne -> "=\\="+  | Ast.Gt -> ">"+  | Ast.Ge -> ">="+  | Ast.Lt -> "<"+  | Ast.Le -> "=<"+let bind_to_raw (s, t) = (* Andrey: TODO support binders *)+  Printf.sprintf "%s:%s" (symbol_to_raw s) (Ast.Sort.to_string t |> sanitize_symbol)+let rec expr_to_raw expr = +  let e = E.unwrap expr in+    match e with+      | Ast.Con c -> constant_to_raw c+      | Ast.Var s -> symbol_to_raw s+      | Ast.App (s, es) -> +	  if !Co.purify_function_application then "_" else+	    let str = symbol_to_raw s in+	      if es = [] then str else+		Printf.sprintf "f_%s(%s)" str (List.map expr_to_raw es |> String.concat ", ")+      | Ast.Bin (e1, op, e2) ->+	  Printf.sprintf "(%s %s %s)" +	    (expr_to_raw e1) (bop_to_raw op) (expr_to_raw e2)+      | Ast.Ite (ip, te, ee) -> +	  Printf.sprintf "ite(%s, %s, %s)" +	    (pred_to_raw ip) (expr_to_raw te) (expr_to_raw ee)+      | Ast.Fld (s, e) -> +	  Printf.sprintf "fld(%s, %s)" (expr_to_raw e) (symbol_to_raw s) +      | _ -> failwith (Printf.sprintf "expr_to_raw: %s" (E.to_string expr))+and pred_to_raw pred = +  if P.is_tauto pred then +    raw_true+  else +    let p = P.unwrap pred in +      match p with+	| Ast.True -> raw_true+	| Ast.False -> raw_false+	| Ast.Bexp e -> Printf.sprintf "%s = 1" (expr_to_raw e)+	| Ast.Not (Ast.True, _) -> raw_false+	| Ast.Not (Ast.False, _) -> raw_true+	| Ast.Not p -> Printf.sprintf "neg(%s)" (pred_to_raw p) +	| Ast.Imp (p1, p2) -> Printf.sprintf "imp(%s, %s)" (pred_to_raw p1) (pred_to_raw p2)+	| Ast.And [] -> raw_true+	| Ast.And [p] -> pred_to_raw p+	| Ast.And (_::_ as ps) -> +	    Printf.sprintf "(%s)" (List.map pred_to_raw ps |> String.concat ", ")+	| Ast.Or [] -> raw_false+	| Ast.Or [p] -> pred_to_raw p+	| Ast.Or (_::_ as ps) -> Printf.sprintf "(%s)" (List.map pred_to_raw ps |> String.concat "; ")+	| Ast.Atom (e1, Ast.Eq, (Ast.Ite(ip, te, ee), _)) ->+	    let ip_str = pred_to_raw ip in+	    let e1_str = expr_to_raw e1 in+	      Printf.sprintf "((%s, %s = %s); (neg(%s), %s = %s))"+		ip_str e1_str (expr_to_raw te) +		ip_str e1_str (expr_to_raw ee) +	| Ast.Atom (e1, r, e2) ->+	    Printf.sprintf "%s %s %s" +              (expr_to_raw e1) (brel_to_raw r) (expr_to_raw e2)+	| Ast.Forall (qs,p) -> (* Andrey: TODO support forall *) +	    Printf.sprintf "forall([%s], %s)" +              (List.map bind_to_raw qs |> String.concat ", ") +	      (pred_to_raw p)++let subst_to_raw subst =+  Misc.map_to_string+    (fun (sym, expr) ->+       Printf.sprintf "%s = %s" (symbol_to_raw sym) (expr_to_raw expr)+    ) (Ast.Subst.to_list subst)++let kvar_to_scope_tbl = Hashtbl.create 100++let wfs_option = ref None++let is_upper c = c = Char.uppercase c++let find_scope wfs sym =+  match Misc.map_partial +    (fun wf -> +       let reft = C.reft_of_wf wf in +       let vv = C.vv_of_reft reft in+	 match C.ras_of_reft reft with+	   | [C.Kvar (subst, sym')] when (Ast.Subst.is_empty subst) && sym = sym' ->+	       let vv_raw = symbol_to_raw vv in+		 Some (vv_raw, +		       StrSet.remove vv_raw+			 (Sy.SMap.fold (fun bv reft sofar ->+					  if not(C.sort_of_reft reft |> Ast.Sort.is_int)+(*					      is_upper (Sy.to_string bv).[0] *)+					  then +					    sofar+					  else +					    StrSet.add (symbol_to_raw bv) sofar+				       ) (C.env_of_wf wf) StrSet.empty))+	   | _ -> None+    ) wfs with+      | (vv, scope) :: _ -> vv, scope+      | [] -> failwith (Printf.sprintf "Not found wf constraint for %s" (Sy.to_string sym))++let scope_of_ksym ksym =  +  try+    Hashtbl.find kvar_to_scope_tbl ksym+  with Not_found ->+    begin+      match !wfs_option with+	| Some wfs -> +	    let scope = find_scope wfs ksym in+	      Hashtbl.add kvar_to_scope_tbl ksym scope;+	      scope+	| None -> failwith "Uninitialized wfs_option reference"+    end++let refa_to_raw = function +  | C.Conc pred -> pred_to_raw pred+  | C.Kvar (subst, sym) ->+      let vv, scope = scope_of_ksym sym in +      let subs = Ast.Subst.to_list subst in+      let params =+	List.map (fun param ->+		    try+		      let _, exp =+			List.find (fun (v, _) -> +				     symbol_to_raw v = param+				  ) subs in +			match exp with +			  | Ast.Var param', _ -> symbol_to_raw param'+			  | _ -> failwith (Printf.sprintf "substition by a non-variable %s" (E.to_string exp))+		    with Not_found -> param +		 ) (vv :: (StrSet.elements scope |> List.sort compare))+      in+	Printf.sprintf "%s(%s)" (symbol_to_raw sym) (String.concat ", " params)++let reft_to_raw reft = +  if C.sort_of_reft reft |> Ast.Sort.is_func then +    raw_true+  else +    let ras = C.ras_of_reft reft in+      match ras with+	| [] -> raw_true+	| _ :: _ ->+	    Misc.map_to_string refa_to_raw ras++let subst_refa refa sym exp = +  match refa with +    | C.Conc pred -> C.Conc (P.subst pred sym exp)+    | C.Kvar (subst, sym') -> C.Kvar (Ast.Subst.extend subst (sym, exp), sym')++let subst_reft reft sym exp =+  C.make_reft +    (C.vv_of_reft reft) (C.sort_of_reft reft) +    (List.map (fun refa -> subst_refa refa sym exp) (C.ras_of_reft reft))++let env_to_raw env =+  Sy.SMap.fold +      (fun bv reft sofar -> +	 [subst_reft reft (C.vv_of_reft reft) (Ast.eVar bv) |> reft_to_raw] ++ sofar+      ) env [] |> List.filter ((<>) "1=1") |> String.concat ", "+++let c_to_raw c =+  Printf.sprintf "rule(%d, %s, [\n%s,\n%s,\n%s\n]).\n\n"+    (C.id_of_t c)+    (C.rhs_of_t c |> reft_to_raw)+    (C.lhs_of_t c |> reft_to_raw)+    (C.grd_of_t c |> pred_to_raw)+    (C.env_of_t c |> env_to_raw)++let to_raw_horn out cs wfs sol = +  let cs = FixSimplify.simplify_ts cs in+    wfs_option := Some wfs;+    print_endline "Translating to raw Horn clauses.";+    List.iter (fun c -> +		 Printf.fprintf out "/*\n%s*/\n" (C.to_string c);+		 output_string out (c_to_raw c)+	      ) cs
+ external/fixpoint/toSmtLib.ml view
@@ -0,0 +1,503 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++(* This module implements the IMP language and translation from fixpoint constraints *)+++module F  = Format+module H  = Hashtbl+module A  = Ast+module E  = A.Expression+module P  = A.Predicate+module Sy = A.Symbol+module So = A.Sort+module SM = Sy.SMap+module SS = Sy.SSet+module C  = FixConstraint+module Cg = FixConfig+module Co = Constants+(*module BS = BNstats*)++module Misc = FixMisc open Misc.Ops++let mydebug = false++(*************************************************************************)+(************* Datatypes for SMTLIB Representation ***********************)+(*************************************************************************)+(*+type sort = Int | Bool | Func of (sort list * sort)+*)+type rpred  +  = A.pred                      (* Bexp (App (k, es)) *) ++type vdef+  = Sy.t * So.t                 (* variable, sort *)++type kdef+  = Sy.t * (vdef list)++type cstr+  = { lhs : A.pred +    ; rhs : rpred option+    ; id  : int +    }++type smtlib +  = { vars   : vdef list+    ; kvars  : kdef list+    ; cstrs  : cstr list +    ; consts : vdef list+  }++type kmap +  = kdef SM.t++let is_kvar x = Misc.is_prefix "k_" (Sy.to_string x) ++(*************************************************************************)+(************* Rendering SMTLIB to String ********************************)+(*************************************************************************)++(* Printing as C syntax *)++let print_brel ppf = function+  | A.Eq -> F.fprintf ppf "="+  | A.Ne -> F.fprintf ppf "!="+  | A.Gt -> F.fprintf ppf ">"+  | A.Ge -> F.fprintf ppf ">="+  | A.Lt -> F.fprintf ppf "<"+  | A.Le -> F.fprintf ppf "<="++let print_bop ppf = function+  | A.Plus  -> F.fprintf ppf "+"+  | A.Minus -> F.fprintf ppf "-"+  | A.Times -> F.fprintf ppf "*"+  | A.Div   -> F.fprintf ppf "/"+  | A.Mod   -> F.fprintf ppf "mod"++let rec print_pred ppf pred =+  match P.unwrap pred with+  | A.True ->+      F.fprintf ppf "true"+  | A.False ->+      F.fprintf ppf "false"+  | A.Atom (e1, A.Ne, e2) ->+      F.fprintf ppf "(not (= %a %a))" +        print_expr e1 +        print_expr e2+  | A.Atom (e1, r, e2) ->+      F.fprintf ppf "(%a %a %a)" +        print_brel r +        print_expr e1 +        print_expr e2+  | A.And ps ->+      Misc.pprint_many_prefix "and" A.pTrue print_pred ppf ps+  | A.Or ps ->+      Misc.pprint_many_prefix "or" A.pFalse print_pred ppf ps+  | A.Not p ->+      F.fprintf ppf "(not %a)" print_pred p+  | A.Imp (p1, p2) ->+      F.fprintf ppf "(=> %a %a)" +        print_pred p1 +        print_pred p2+  | A.Iff (p1, p2) ->+      F.fprintf ppf "(= %a %a)" +        print_pred p1 +        print_pred p2+  | A.Bexp e ->+      print_expr ppf e+  | _ -> assertf "ERROR: ToSmtLib.print_pred %s" (P.to_string pred)+     +and print_expr_app f ppf = function +  | [e] -> +      F.fprintf ppf "(select %a %a)" +        Sy.print f +        print_expr e+  | e::es ->+      F.fprintf ppf "(select %a %a)"+        (print_expr_app f) es+        print_expr e++and print_expr ppf expr =+  match E.unwrap expr with+  | A.Con c ->+      F.fprintf ppf "%a" A.Constant.print c+  | A.App (v, []) +  | A.Var v ->+      F.fprintf ppf "%a" Sy.print v+  | A.App (f, es) when is_kvar f ->+      F.fprintf ppf "(%a %a)" +        Sy.print f+        (Misc.pprint_many false " " print_expr) es ++  | A.App (f, es) ->+      print_expr_app f ppf (List.rev es)++      (*+      print_expr_app f ppf (List.rev es)+      F.fprintf ppf "(%a %a)" +        Sy.print f+        (Misc.pprint_many false " " print_expr) es *)+  | A.Bin (e1, op, e2) ->+      F.fprintf ppf "(%a %a %a)"+        print_bop  op+        print_expr e1+        print_expr e2+  | A.Ite (p, e1, e2) ->+      F.fprintf ppf "(ite %a %a %a)"+        print_pred p+        print_expr e1+        print_expr e2+  | A.Cst (e, _) ->+      F.fprintf ppf "%a" print_expr e+  | _ -> assertf "ERROR: ToSmtLib.print_expr %s" (E.to_string expr)++let print_sort_base ppf t = +  if So.is_bool t then +    Format.fprintf ppf "Bool"+  else+    Format.fprintf ppf "Int"++let rec print_sort ppf t = match So.func_of_t t with+  | Some (_, [], t) ->+      print_sort_base ppf t++  | Some (_, ts, t) -> +      Format.fprintf ppf "%a %a"+        (Misc.pprint_many false " " print_sort) ts+        print_sort t+  | None -> +      print_sort_base ppf t++      +(*+let print_vdef ppf (x, t) = match So.func_of_t t with+  | Some (_, ts, t') when So.is_bool t' -> +      Format.fprintf ppf ":extrapreds ((%a %a))" +        Sy.print x +        (Misc.pprint_many false " " print_sort) ts+  | _ ->+      Format.fprintf ppf ":extrafuns ((%a %a))" +        Sy.print x +        print_sort t+*)++let rec print_fun_sorts ppf = function+  | [t]   -> print_sort ppf t+  | t::ts -> Format.fprintf ppf "(Array %a %a)" +               print_sort t+               print_fun_sorts ts++let print_vdef ppf (x, t) = match So.func_of_t t with+  | Some (_, ts, t') -> +     Format.fprintf ppf "(%a %a)"+       Sy.print x+       print_fun_sorts (ts @ [t'])+  | _ ->+      Format.fprintf ppf "(%a %a)" +        Sy.print x +        print_sort t++let print_const ppf c = +  Format.fprintf ppf "; constant \n%a\n" print_vdef c++let groupConsts cs = +  cs |> Misc.kgroupby snd +     |> Misc.map (Misc.app_snd (List.map fst))+     |> List.filter (snd <+> List.length <+> (>) 0)++let print_distinct ppf (t, cs) =+  Format.fprintf ppf +    "; distinct constants of sort: %a\n(distinct %a)\n"   +     print_sort t+     (Misc.pprint_many false " " Sy.print) cs++(*+let print_kdef ppf (kf, xts) = +  Format.fprintf ppf ":extrapreds ((%a %a))"+    Sy.print kf+    (Misc.pprint_many false " " print_sort) (List.map snd xts)+*)+let print_kdef ppf (kf, xts) =+  Format.fprintf ppf "(declare-fun %a (%a) Bool)"+    Sy.print kf+    (Misc.pprint_many false " " print_sort) (List.map snd xts)+++let print_rhs ppf = function+  | None   -> Format.fprintf ppf "false"+  | Some p -> Format.fprintf ppf "%a" print_pred p++(*+let print_cstr ppf c = +  Format.fprintf ppf "\n; cid = %d\n:assumption\n(implies (%a) %a)\n"+    c.id print_pred c.lhs print_rhs c.rhs+*)++let binds_of_cstr env c =+  let lsyms = P.support c.lhs                                     in+  let rsyms = match c.rhs with None -> [] | Some p -> P.support p in+  Misc.sort_and_compact (lsyms ++ rsyms)    +  |> List.filter (fun x -> SM.mem x env)+  |> List.map (fun x -> (x, SM.safeFind x env "binds_of_cstr"))++let print_cstr env ppf c = +  Format.fprintf ppf "\n; cid = %d\n(assert (forall (%a) \n (=> %a %a))\n)"+    c.id +    (Misc.pprint_many true " " print_vdef) (binds_of_cstr env c)+    print_pred c.lhs +    print_rhs c.rhs+++(*+let print ppf smt = +  Format.fprintf ppf +    "(benchmark unknown\n:status unsat\n:logic AUFLIA\n%a\n%a\n%a\n%a\n%a\n)"+    (Misc.pprint_many true "\n" print_vdef)     smt.vars+    (Misc.pprint_many true "\n" print_const)    smt.consts+    (Misc.pprint_many true "\n" print_kdef)     smt.kvars+    (Misc.pprint_many true "\n" print_distinct) (groupConsts smt.consts)+    (Misc.pprint_many true "\n" print_cstr)     smt.cstrs+*)++let print ppf smt =+  let env = SM.of_list (smt.vars ++ smt.consts) in+  Format.fprintf ppf +    "(set-logic HORN)\n; KVARS\n\n%a\n\n; CONSTRAINTS\n%a\n"+    (Misc.pprint_many true "\n" print_kdef)     smt.kvars+    (Misc.pprint_many true "\n" (print_cstr env)) smt.cstrs++++(*************************************************************************)+(************* Helpers for extracting var-sort bindings ******************) +(*************************************************************************)++let sort_compat x t t' =+  Ast.Sort.compat t t'+  >> (fun b -> if not b then +               Printf.printf "WARNING: k-sort incompatible for %s" +               (Sy.to_string x))++(* HACKY sort_compat because in the end everything is an Int *)+let sort_compat x t1 t2 = +  not (So.is_bool t1) +  && not (So.is_bool t2) +  && (not (So.is_func t1) || (t1 = t2))+  && (not (So.is_func t2) || (t1 = t2))++let vdefs_of_env env r = +  env |> C.bindings_of_env+      |> (++) [(C.vv_of_reft r, r)]+      |> List.map (Misc.app_snd C.sort_of_reft)+      (* |> List.filter (not <.> So.is_func <.> snd)  *)+      |> Misc.fsort fst++(*************************************************************************)+(************* Build VMap : gather all vars/sorts for regular vars *******) +(*************************************************************************)++let update_vmap vm (x, t) =+  Misc.maybe_iter begin fun t' ->+    asserts (sort_compat x t t') "ERROR: v-sort incompatible %s" (Sy.to_string x)+  end (SM.maybe_find x vm);+  SM.add x t vm++let update_vmap_int vm (x, t) =+  SM.add x So.t_int vm++let add_c_var_to_vmap vm c =+  let vvl = C.vv_of_reft (C.lhs_of_t c) in+  let vvr = C.vv_of_reft (C.rhs_of_t c) in+  let _   = asserts (vvl = vvr) "Different VVs in Constr: %d" (C.id_of_t c) in+  vdefs_of_env (C.env_of_t c) (C.lhs_of_t c)+  |> List.fold_left update_vmap_int vm + +let add_wf_var_to_vmap vm w =+  vdefs_of_env (C.env_of_wf w) (C.reft_of_wf w)+  |> List.fold_left update_vmap_int vm +  +(*************************************************************************)+(************ Build KMap: gather scopes for each kvar from wfs** *********)+(*************************************************************************)++let check_no_subs wid suks = +  asserts +    (List.for_all (fst <+> A.Subst.is_empty) suks) +    "NonTriv Subst wid=%d" wid++let join vds vds' = +  let xm  = SM.of_list vds  in+  List.filter begin fun (x, t) ->+    match SM.maybe_find x xm with+    | None    -> false+    | Some t' -> sort_compat x t t'  +  end vds'       ++let update_kmap vdefs km k : kmap =+  match SM.maybe_find k km with+  | None            -> SM.add k (k, vdefs) km+  | Some (_,vdefs') -> SM.add k (k, join vdefs vdefs') km++let add_wf_to_kmap km wf =+  let vdefs = vdefs_of_env (C.env_of_wf wf) (C.reft_of_wf wf) +              |> List.filter (snd <+> So.is_func <+> not)+  in+  C.reft_of_wf wf+  |> C.kvars_of_reft  +  >> check_no_subs (C.id_of_wf wf) +  |> List.map snd+  |> List.fold_left (update_kmap vdefs) km++let make_kmap defs : kmap = +  defs +  |> Misc.map_partial (function Cg.Wfc x -> Some x | _ -> None)+  |> List.fold_left add_wf_to_kmap SM.empty++let mkFreshI, _   = Misc.mk_int_factory ()+let mkFresh cid x = +  Sy.of_string (Format.sprintf "%s_smt_%d_%d" (Sy.to_string x) cid (mkFreshI ())) +(*  >> (fun x' -> Format.printf "fresh_var: %a \n" Sy.print x')+ *)++let fresh_vars env cid es = +  let t   = Hashtbl.create 17 in+  let msg = "fresh_vars: cid = "^(string_of_int cid) in   +  let es' = List.map begin fun e -> match e with+            | (A.Var x, _) ->+                if Hashtbl.mem t x then+                  x |> mkFresh cid >> Hashtbl.add t x |> A.eVar+                else let _ = Hashtbl.add t x x in e +            | _ -> failwith ("ERROR: " ^ msg)+            end es in+  let l' = Misc.hashtbl_keys t +           |> Misc.flap begin fun x -> +                let so = SM.safeFind x env msg in+                foreach (Hashtbl.find_all t x) begin fun x' ->+                  (x', so), A.pEqual ((A.eVar x), (A.eVar x'))+                end+              end+           |> List.split+           |> Misc.app_snd A.pAnd in+  l', es'++(*************************************************************************)+(************* Translating using the KMap ********************************)+(*************************************************************************)++let pred_of_kdef (kf, xts) =+  A.pBexp <| A.eApp (kf, List.map (fst <+> A.eVar) xts)  ++let soln_of_kmap km k =+  [pred_of_kdef <| SM.safeFind k km "soln_of_kmap"]+  (* >> (Format.printf "soln_of_kmap: k = %a ps = %a \n" Sy.print k (Misc.pprint_many false " " P.print))+   *)++let tx_constraint s c =+  let cid     = C.id_of_t c                 in+  let lps     = C.preds_of_lhs_nofilter s c in+  let v,t,ras = C.rhs_of_t c                in+  ras |>: begin function +            | C.Conc p -> { lhs = A.pAnd ((A.pNot p) :: lps)+                          ; rhs = None +                          ; id  = cid }+            | ra       -> { lhs = A.pAnd lps+                          ; rhs = (match C.preds_of_refa s ra with +                                  | [p] -> Some p +                                  | _   -> failwith "tx_constraint")+                          ; id  = cid}+          end+       +       |>: begin function+         (* Ken needed this tx but it messes up with typeclasses... maybe not+          * needed any more?  +            +         | { rhs = Some (A.Bexp (A.App (f, es),_), _) } as c' ->+                let (xts, eqp), es' = fresh_vars (C.senv_of_t c) cid es in+                let r'              = A.pBexp (A.eApp (f, es')) in +                (xts, {c' with lhs = A.pAnd [eqp; c'.lhs]; rhs = Some r' })+          *)+          |  c' -> ([], c')+          end++let tx_defs cfg =+  let defs = List.map (fun c -> Cg.Cst c) cfg.Cg.cs ++ +             List.map (fun c -> Cg.Wfc c) cfg.Cg.ws     in+  let km   = defs |> make_kmap                          in+  let s    = soln_of_kmap km                            in +  let cs   = cfg.Cg.cs                                  in+  let ws   = cfg.Cg.ws                                  in+  let xts,cs' = List.split <| Misc.flap (tx_constraint s) cs in+  { vars   =  Misc.flatten xts +           ++ (SM.to_list <| List.fold_left add_c_var_to_vmap SM.empty cs) +           ++ (SM.to_list <| List.fold_left add_wf_var_to_vmap SM.empty ws)+  ; kvars  = SM.range km+  ; cstrs  = cs'+  ; consts = SM.to_list cfg.Cg.uops +  }++(*************************************************************************)+(************* Slicing into Single Assertions ****************************)+(*************************************************************************)+++let split_by_assertion cfg =+  let ccs, kcs = Misc.tr_partition C.is_conc_rhs cfg.Cg.cs in+  Misc.map (fun c -> { cfg with Cg.cs = c :: kcs }) ccs++let slice_by_assertion cfg = +  let cs' =  cfg.Cg.cs +          |> Cindex.create cfg.Cg.kuts cfg.Cg.ds +          |> Cindex.slice +          |> Cindex.to_list+  in {cfg with Cg.cs = cs' }+++(*************************************************************************)+(************* API *******************************************************)+(*************************************************************************)++let dump_smtlib_indexed (no, cfg) =+  let su = Misc.maybe_apply (fun x _ -> "." ^ (string_of_int x)) no "" in+  let fn = !Constants.out_file ^ su ^ ".smt2"  in +  let _  = Co.bprintflush mydebug ("BEGIN: Dump SMTLIB \n") in+  let me = tx_defs cfg                         in+  let _  = Misc.with_out_formatter fn (fun ppf -> F.fprintf ppf "%a" print me) in+  let _  = Co.bprintflush mydebug ("DONE: Dump SMTLIB to " ^ !Constants.out_file ^"\n") in+  ()++let dump_smtlib_mono cfg = +  dump_smtlib_indexed (None, cfg);+  exit 1++let dump_smtlib_sliced cfg = +  cfg |>  split_by_assertion+      |>: slice_by_assertion+      |>  Misc.index_from 0+      |>: (Misc.app_fst some) +      |>  List.iter dump_smtlib_indexed+      |>  (fun _ -> exit 1)++let dump_smtlib = dump_smtlib_sliced+
+ external/fixpoint/toSmtLib.mli view
@@ -0,0 +1,86 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++(* HIDE: all the sigs for defined binders+ +type rpred = A.pred+type vdef = Sy.t * So.t+type kdef = Sy.t * vdef list+type cstr = { lhs : A.pred; rhs : rpred option; id : int; }+type smtlib = {+  vars : vdef list;+  kvars : kdef list;+  cstrs : cstr list;+  consts : vdef list;+}+type kmap = kdef SM.t+val is_kvar : Sy.t -> bool+val print_brel : F.formatter -> A.brel -> unit+val print_bop : F.formatter -> A.bop -> unit+val print_pred : F.formatter -> A.pred -> unit+val print_expr_app : Sy.t -> F.formatter -> A.expr list -> unit+val print_expr : F.formatter -> A.expr -> unit+val print_sort_base : Format.formatter -> So.t -> unit+val print_sort : Format.formatter -> So.t -> unit+val print_fun_sorts : Format.formatter -> So.t list -> unit+val print_vdef : Format.formatter -> Sy.t * So.t -> unit+val print_const : Format.formatter -> Sy.t * So.t -> unit+val groupConsts : ('a * 'b) list -> ('b * 'a list) list+val print_distinct : Format.formatter -> So.t * Sy.t list -> unit+val print_kdef : Format.formatter -> Sy.t * ('a * So.t) list -> unit+val print_rhs : Format.formatter -> A.pred option -> unit+val binds_of_cstr : 'a SM.t -> cstr -> (SM.key * 'a) list+val print_cstr : So.t SM.t -> Format.formatter -> cstr -> unit+val print : Format.formatter -> smtlib -> unit+val sort_compat : 'a -> So.t -> So.t -> bool+val vdefs_of_env : C.envt -> C.reft -> (Ast.Symbol.t * Ast.Sort.t) list+val update_vmap : So.t SM.t -> Sy.t * So.t -> So.t SM.t+val update_vmap_int : So.t SM.t -> SM.key * 'a -> So.t SM.t+val add_c_var_to_vmap : So.t SM.t -> C.t -> So.t SM.t+val add_wf_var_to_vmap : So.t SM.t -> C.wf -> So.t SM.t+val check_no_subs : int -> (A.Subst.t * 'a) list -> unit+val join : (SM.key * So.t) list -> (SM.key * So.t) list -> (SM.key * So.t) list+val update_kmap : vdef list -> kdef SM.t -> SM.key -> kmap+val add_wf_to_kmap : kdef SM.t -> C.wf -> kdef SM.t+val make_kmap : Cg.deft list -> kmap+val mkFreshI : unit -> int+val mkFresh : int -> Sy.t -> Sy.t+val fresh_vars : 'a SM.t -> int -> A.expr list -> ((Sy.t * 'a) list * A.pred) * A.expr list+val pred_of_kdef : A.Symbol.t * (A.Symbol.t * 'a) list -> A.pred+val soln_of_kmap : (A.Symbol.t * (A.Symbol.t * 'a) list) SM.t -> SM.key -> A.pred list+val tx_constraint : C.soln -> C.t -> ('a list * cstr) list+val tx_defs : 'a Cg.cfg -> smtlib+val split_by_assertion : 'a Cg.cfg -> 'a Cg.cfg list+val slice_by_assertion : 'a Cg.cfg -> 'a Cg.cfg+val dump_smtlib_indexed : int option * 'a Cg.cfg -> unit+val dump_smtlib_mono : 'a Cg.cfg -> 'b+val dump_smtlib_sliced : 'a Cg.cfg -> 'b+val dump_smtlib : 'a Cg.cfg -> 'b++*)++(* val render : Format.formatter -> FixConfig.deft list -> unit +val render : Format.formatter -> 'a FixConfig.cfg -> unit+*)+val dump_smtlib : 'a FixConfig.cfg -> unit+
+ external/fixpoint/toplevel.ml view
@@ -0,0 +1,48 @@+module BS = BNstats+module SM = Ast.Symbol.SMap+module Co = Constants +module C  = FixConstraint+module F  = Format+module Misc = FixMisc open Misc.Ops+++(*+let parse_string str =+  let lb = Lexing.from_string str in+    ArithParser.aexpr ArithLexer.token lb++let token_list_of_string s =+  let lb = Lexing.from_string s in+  let rec helper l = +    try +      let t = ArithLexer.token lb in+      if t = ArithParser.EOF then List.rev l else helper (t::l)+    with _ -> List.rev l+  in helper []++let eval_string env str = ArithInterpreter.eval env (parse_string str) +*)++(*****************************************************************)+(********************* Command line options **********************)+(*****************************************************************)++let parse f = +  let _  = Errorline.startFile f in+  let ic = open_in f in+  let rv = Lexing.from_channel ic |> FixParse.defs FixLex.token in+  let _  = close_in ic in+  rv++let read_inputs usage = +  Co.bprintflush true "\n\n";+  Co.bprintflush true "========================================================\n";+  Co.bprintflush true "© Copyright 2009 Regents of the University of California.\n";+  Co.bprintflush true "All Rights Reserved.\n";+  Co.bprintflush true "========================================================\n";+  Co.bprintflush false (Sys.argv |> Array.to_list |> String.concat " ");+  Co.bprintflush false "\n========================================================\n";+  let fs = ref [] in+  let _  = Arg.parse Co.arg_spec (fun s -> fs := s::!fs) usage in+  let fq = !fs |> BS.time "parse" (Misc.flap parse) |> FixConfig.create in +  (!fs, fq)
+ external/fixpoint/toplevel.mli view
@@ -0,0 +1,25 @@+(*+ * 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 MODIFICATIONAst.Symbol.+ *+ *)++val read_inputs      : string -> (string list * SolverArch.qbind FixConfig.cfg)+
+ external/fixpoint/tpGen.ml view
@@ -0,0 +1,499 @@+(*+ * Copyright © 2008 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.+ *)++(* This file is part of the LiquidC Project *)++module H  = Hashtbl+module F  = Format+module Co = Constants+module BS = BNstats+module A  = Ast+module Sy = A.Symbol+module So = A.Sort+module SM   = Sy.SMap+module P    = A.Predicate+module E    = A.Expression+module Misc = FixMisc +module SSM  = Misc.StringMap+module SMT  = SmtZ3.SMTZ3++open Misc.Ops+open ProverArch++let mydebug = false ++module MakeProver(SMT : SMTSOLVER) : PROVER = struct++  module Th   = Theories.MakeTheory(SMT) ++(*************************************************************************)+(*************************** Type Definitions ****************************)+(*************************************************************************)++type decl    = Vbl of (Sy.t * So.t) | Fun of Sy.t * int | Barrier++type var_ast = Const of SMT.ast | Bound of int * So.t++type t = { +  c             : SMT.context;+  tint          : SMT.sort;+  tbool         : SMT.sort;+  vart          : (decl, var_ast) H.t;+  funt          : (decl, SMT.fun_decl) H.t;+  tydt          : (So.t, SMT.sort) H.t;+  mutable vars  : decl list ;+  mutable bnd   : int;+  thy_sortm     : (So.tycon, Th.sortDef) H.t;+  thy_symm      : (Sy.t,     Th.appDef)  H.t;+}++(*************************************************************************)+(************************** Pretty Printing ******************************)+(*************************************************************************)++let pprint_decl ppf = function+  | Vbl (x, t) 	-> F.fprintf ppf "%a:%a" Sy.print x So.print t +  | Barrier 	-> F.fprintf ppf "----@." +  | Fun (s, i) 	-> F.fprintf ppf "%a[%i]" Sy.print s i++let dump_decls me =+  F.printf "Vars: %a" (Misc.pprint_many true "," pprint_decl) me.vars       ++(************************************************************************)+(***************************** Stats Counters  **************************)+(************************************************************************)++let nb_set  		= ref 0+let nb_query 		= ref 0++(************************************************************************)+(********************** Misc. Constants *********************************)+(************************************************************************)++let div_n  = Sy.of_string "_DIV"+let tag_n  = Sy.of_string "_TAG"+let mul_n  = Sy.of_string "_MUL"++let axioms = []++(* TBD these are related to ML and should be in DSOLVE, not here *)+let builtins = +  SM.empty +  |> SM.add tag_n  (So.t_func 0 [So.t_obj; So.t_int])+  |> SM.add div_n  (So.t_func 0 [So.t_int; So.t_int; So.t_int]) +  |> SM.add mul_n  (So.t_func 0 [So.t_int; So.t_int; So.t_int]) ++let select_t = So.t_func 0 [So.t_int; So.t_int]++let mk_select, is_select =+  let ss = "SELECT" in+  (fun f -> Sy.to_string f |> (^) (ss ^ "_") |> Sy.of_string),+  (fun s -> Sy.to_string s |> Misc.is_prefix ss)++let fresh = +  let x = ref 0 in+  fun v -> incr x; (v^(string_of_int !x))++(*************************************************************************)+(********************** Typing *******************************************)+(*************************************************************************)++let varSort env s =+  try SM.find s env with Not_found -> +    failure "ERROR: varSort cannot type %s in TPZ3 \n" (Sy.to_string s) ++let funSort env s =+  try SM.find s builtins with Not_found -> +    try SM.find s env with Not_found -> +      if is_select s then select_t else +        failure "ERROR: could not type function %s in TPZ3 \n" (Sy.to_string s) ++let rec z3Type me t =+  Misc.do_memo me.tydt begin fun t -> +    if So.is_bool t then me.tbool else+      if So.is_int t then me.tint else+        match z3TypeThy me t with +          | Some t' -> t'+          | None    -> me.tint+  end t t++and z3TypeThy me t = match So.app_of_t t with+ | Some (c, ts) when H.mem me.thy_sortm c -> +     let def = H.find me.thy_sortm c   in+     let zts = List.map (z3Type me) ts in+     Some (Th.mk_thy_sort def me.c zts)+ | _ -> None + +(***********************************************************************)+(********************** Identifiers ************************************)+(***********************************************************************)++let getVbl env x = Vbl (x, varSort env x)++let z3Var_memo me env x =+  let vx  = getVbl env x in+  Misc.do_memo me.vart+    (fun () -> +      let t   = x |> varSort env |> z3Type me in+      let sym = fresh "z3v" +             (* >> F.printf "z3Var_memo: %a :->  %s\n" Sy.print x *)+                |> SMT.stringSymbol me.c in +      let rv  = Const (SMT.var me.c sym t) in+      let _   = me.vars <- vx :: me.vars in +      rv) +    () vx++let z3Var me env x =+  match BS.time "z3Var memo" (z3Var_memo me env) x with+  | Const v      -> v+  | Bound (b, t) -> SMT.boundVar me.c (me.bnd - b) (z3Type me t)+++let z3Fun me env p t k = +  Misc.do_memo me.funt begin fun _ -> +    match So.func_of_t t with+    | None             -> assertf "MATCH ERROR: z3ArgTypes" +    | Some (_, ts, rt) ->+        let ts = List.map (z3Type me) ts in+        let rt = z3Type me rt in+        let cf = SMT.stringSymbol me.c (fresh "z3f") in+        let rv = SMT.funcDecl me.c cf (Array.of_list ts) rt in+        let _  = me.vars <- (Fun (p,k))::me.vars in+        rv+  end () (Fun (p, k))++(**********************************************************************)+(********************** Pred/Expr Transl ******************************)+(**********************************************************************)++ +exception Z3RelTypeError++let z3Bind me env x t =+  let vx = Vbl (x, varSort env x) in+  me.bnd <- me.bnd + 1; +  H.replace me.vart vx (Bound (me.bnd, t)); +  me.vars <- vx :: me.vars;+  SMT.stringSymbol me.c (fresh "z3b")++let rec z3Rel me env (e1, r, e2) =+  let p  = A.pAtom (e1, r, e2)                                   in+  let ok = A.sortcheck_pred Theories.is_interp (Misc.flip SM.maybe_find env) p   in +  (* let _  = F.printf "z3Rel: e = %a, res = %b \n" P.print p ok in+     let _  = F.print_flush ()                                   in *)+  if ok then +    SMT.mkRel me.c r (z3Exp me env e1) (z3Exp me env e2)+  else begin +    SM.iter (fun s t -> F.printf "@[%a :: %a@]@." Sy.print s So.print t) env;+    F.printf "@[%a@]@.@." P.print (A.pAtom (e1, r, e2));+    F.print_flush ();+    raise Z3RelTypeError+  end++and z3App me env p zes =+  let t  = funSort env p                      in+  let cf = z3Fun me env p t (List.length zes) in+  SMT.mkApp me.c cf zes++and z3AppThy me env def tyo f es = +  match A.sortcheck_app Theories.is_interp (Misc.flip SM.maybe_find env) tyo f es with +    | Some (s, t) ->+        let zts = So.sub_args s |> List.map (snd <+> z3Type me) in+        let zes = es            |> List.map (z3Exp me env)      in+        Th.mk_thy_app def me.c zts zes+    | None ->+        A.eApp (f, es)+        |> E.to_string+        |> assertf "z3AppThy: sort error %s"++and z3Mul me env = function+  | ((A.Con (A.Constant.Int i), _), e) +  | (e, (A.Con (A.Constant.Int i), _)) ->+      SMT.mkMul me.c (SMT.mkInt me.c i me.tint) (z3Exp me env e) +  | (e1, e2) when !Co.uif_multiply -> +      z3App me env mul_n (List.map (z3Exp me env) [e1; e2])+  | (e1, e2) -> +      SMT.mkMul me.c (z3Exp me env e1) (z3Exp me env e2)++and z3Exp me env = function+  | A.Con (A.Constant.Int i), _ -> +      SMT.mkInt me.c i me.tint +  | A.Var s, _ -> +      z3Var me env s+  | A.Cst ((A.App (f, es), _), t), _ when (H.mem me.thy_symm f) -> +      z3AppThy me env (H.find me.thy_symm f) (Some t) f es+  | A.App (f, es), _ when (H.mem me.thy_symm f) -> +      z3AppThy me env (H.find me.thy_symm f) None f es+  | A.App (f, es), _  -> +      z3App me env f (List.map (z3Exp me env) es)+  | A.Bin (e1, A.Plus, e2), _ ->+      SMT.mkAdd me.c (z3Exp me env e1) (z3Exp me env e2)+  | A.Bin (e1, A.Minus, e2), _ ->+      SMT.mkSub me.c (z3Exp me env e1) (z3Exp me env e2)+  | A.Bin((A.Con (A.Constant.Int n1), _), A.Times, (A.Con (A.Constant.Int n2), _)),_ ->+      SMT.mkInt me.c (n1 * n2) me.tint+  | A.Bin (e1, A.Times, e2), _ ->+      z3Mul me env (e1, e2)+  | A.Bin (e1, A.Div, e2), _ -> +      z3App me env div_n (List.map (z3Exp me env) [e1;e2])+  | A.Bin (e, A.Mod, (A.Con (A.Constant.Int i), _)), _ ->+      SMT.mkMod me.c (z3Exp me env e) (SMT.mkInt me.c i me.tint)+  | A.Bin (e1, A.Mod, e2), _ ->+      SMT.mkMod me.c (z3Exp me env e1) (z3Exp me env e2)+  | A.Ite (e1, e2, e3), _ -> +      SMT.mkIte me.c (z3Pred me env e1) (z3Exp me env e2) (z3Exp me env e3)++  | A.Fld (f, e), _ -> +      z3App me env (mk_select f) [z3Exp me env e] (** REQUIRES: disjoint field names *)+  | A.Cst (e, _), _ -> +      z3Exp me env e+  | e -> +      assertf "z3Exp: Cannot Convert %s!" (E.to_string e) ++and z3Pred me env = function+  | A.True, _ -> +      SMT.mkTrue  me.c+  | A.False, _ ->+      SMT.mkFalse me.c+  | A.Not p, _ -> +      SMT.mkNot  me.c (z3Pred me env p)+  | A.And ps, _ -> +      SMT.mkAnd me.c (List.map (z3Pred me env) ps)+  | A.Or ps, _  -> +      SMT.mkOr  me.c (List.map (z3Pred me env) ps)+  | A.Imp (p1, p2), _ -> +      SMT.mkImp me.c (z3Pred me env p1) (z3Pred me env p2)+  | A.Iff (p1, p2), _ ->+      SMT.mkIff me.c (z3Pred me env p1) (z3Pred me env p2)+  | A.Atom (e1, r, e2), _ ->+      z3Rel me env (e1, r, e2)+  | A.Bexp e, _ -> +      let a  = z3Exp me env e in+      let s2  = E.to_string e in+      let Some so = A.sortcheck_expr Theories.is_interp (Misc.flip SM.maybe_find env) e in+      let sos = So.to_string so in+      (* let s1  = SMT.astString me.c a in+      let _   = asserts (SMT.isBool me.c a) +                        "Bexp is not bool (e = %s)! z3=%s, fix=%s, sort=%s" +                        (E.to_string e) s1 s2 sos +      in *)      +      a++  | A.Forall (xts, p), _ -> +      let (xs, ts) = List.split xts                                  in+      let zargs    = Array.of_list (List.map2 (z3Bind me env) xs ts) in+      let zts      = Array.of_list (List.map  (z3Type me) ts)        in +      let rv       = SMT.mkAll me.c zts zargs (z3Pred me env p)      in+      let _        = me.bnd <- me.bnd - (List.length xs)             in+      rv+  | p -> +      assertf "z3Pred: Cannot Convert %s!" (P.to_string p) +++  +let z3Pred me env p = +  try +    let p = BS.time "fixdiv" A.fixdiv p in+    BS.time "z3Pred" (z3Pred me env) p+  with ex -> (F.printf "z3Pred: error converting %a\n" P.print p) ; raise ex ++(***************************************************************************)+(***************** Binder/Stack Management *********************************)+(***************************************************************************)++let rec vpop (cs,s) =+  match s with +  | []           -> (cs,s)+  | Barrier :: t -> (cs,t)+  | h :: t       -> vpop (h::cs,t) ++let clean_decls me =+  let cs, vars' = vpop ([],me.vars) in+  let _         = me.vars <- vars'  in +  List.iter begin function +    | Barrier    -> failure "ERROR: TPZ3-cleanDecls" +    | Vbl _ as d -> H.remove me.vart d +    | Fun _ as d -> H.remove me.funt d+  end cs++let handle_vv me env vv = +  H.remove me.vart (getVbl env vv) (* RJ: why are we removing this? *) +++(************************************************************************)+(********************************* API **********************************)+(************************************************************************)++let create_theories () =+  Th.theories +  |> (Misc.hashtbl_of_list_with Th.sort_name <**> Misc.hashtbl_of_list_with Th.sym_name)++let assert_distinct_constants me env = function [] -> () | cs -> +  cs |> Misc.kgroupby (varSort env) +     |> List.iter begin fun (_, xs) ->+         xs >> Co.bprintf mydebug "Distinct Constants: %a \n" (Misc.pprint_many false ", " Sy.print)+            |> List.map (z3Var me env) +            |> SMT.assertDistinct me.c+         end++let prep_preds me env ps =+  let ps = List.rev_map (z3Pred me env) ps in+  let _  = me.vars <- Barrier :: me.vars in+  ps++let valid me p = +  SMT.bracket me begin fun _ ->+    SMT.assertPreds me [SMT.mkNot me p];+    BS.time "unsat" SMT.unsat me +  end++(* API *)+let set_filter (me: t) (env: So.t SM.t) (vv: Sy.t) ps qs =+  let _   = ignore(nb_set   += 1); ignore (nb_query += List.length qs) in+  let _   = handle_vv me env vv  in+  let zps = prep_preds me env ps in (* DO NOT PUSH INSIDE SMT.bracket or z3 blocks postests/ll3.c *)+  SMT.bracket me.c begin fun _ ->+    let _        = SMT.assertPreds me.c zps                      in+    let tqs, fqs = List.partition (snd <+> P.is_tauto) qs        in+    let fqs      = fqs |> List.rev_map (Misc.app_snd (z3Pred me env))+                       |> Misc.filter  (snd <+> valid me.c)      in +    let _        = clean_decls me                                in+    (List.map fst tqs) ++ (List.map fst fqs)+  end++(* API *)+let print_stats ppf me =+  SMT.print_stats ppf ();+  F.fprintf ppf "TP stats: sets=%d, queries=%d, count=%d\n"  +    !nb_set !nb_query (List.length me.vars) ++(*************************************************************************)+(****************** Unsat Core for CEX generation ************************)+(*************************************************************************)++let mk_prop_var me pfx i : SMT.ast =+  i |> string_of_int+    |> (^) pfx+    |> SMT.stringSymbol me.c +    |> Misc.flip (SMT.var me.c) me.tbool ++let mk_prop_var_idx me ipa : (SMT.ast array * (SMT.ast -> 'a option)) =+  let va  = Array.mapi (fun i _ -> mk_prop_var me "uc_p_" i) ipa in+  let vm  = va +            |> Array.map   (SMT.astString me.c)+            |> Misc.array_to_index_list +            |> List .map Misc.swap +            |> SSM.of_list in +  let f z = SSM.maybe_find (SMT.astString me.c z) vm+            |> Misc.maybe_map (fst <.> Array.get ipa) in+  (va, f)++let mk_pa me p2z pfx ics =+  ics |> List.map (Misc.app_snd p2z) +      |> Array.of_list +      |> Array.mapi (fun i (x, p) -> (x, p, mk_prop_var me pfx i))++(* API *)+let unsat_core me env bgp ips =+  let _     = H.clear me.vart                                       in +  let p2z   = A.fixdiv <+> z3Pred me env                            in+  let ipa   = ips |> List.map (Misc.app_snd p2z) |> Array.of_list   in +  let va, f = mk_prop_var_idx me ipa                                in+  let zp    = ipa |> Array.mapi (fun i (_, p) -> SMT.mkIff me.c va.(i) p)+                  |> Array.to_list+                  |> (++) [p2z bgp]+                  |> SMT.mkAnd me.c in+  SMT.bracket me.c begin fun _ ->+    let _   = SMT.assertPreds me.c [zp] in+    let n   = Array.length va in+    let va' = Array.map id va in+    failwith "SMT-UNSAT-CORE-TODO"+    (************************************+    match SMT.check_assumptions me.c va n va' with+      | (Z3.L_FALSE, m,_, n, ucore) +          -> Array.map f ucore |> Array.to_list |> Misc.map_partial id +      | _ -> []+      ************************************)+  end++let contra me p = +  SMT.bracket me begin fun _ ->+    SMT.assertPreds me [p];+    BS.time "unsat" SMT.unsat me +  end++(* API *)+let is_contra me env =  z3Pred me env <+> contra me.c ++(* API *)+let unsat_suffix me env p ps =+  let _ = if SMT.unsat me.c then assertf "ERROR: unsat_suffix" in+  SMT.bracket me.c begin fun _ ->+    let rec loop j = function [] -> None | zp' :: zps' -> +      SMT.assertPreds me.c [zp']; +      if SMT.unsat me.c then Some j else loop (j-1) zps'+    in loop (List.length ps) (List.map (z3Pred me env) (p :: List.rev ps)) +  end++(***********************************************************************)+(******** Prover Object ************************************************)+(***********************************************************************)++(* API *)+let create ts env ps consts =+  let _        = asserts (ts = []) "ERROR: TPZ3-create non-empty sorts!" in+  let c        = SMT.mkContext [|("MODEL", "false"); ("MODEL_PARTIAL", "true")|] in+  let som, sym = create_theories () in +  let me       = { c     = c; +                   tint  = SMT.mkIntSort  c; +                   tbool = SMT.mkBoolSort c; +                   tydt  = H.create 37; +                   vart  = H.create 37; +                   funt  = H.create 37; +                   vars  = []; +                   bnd   = 0;+                   thy_sortm = som; +                   thy_symm  = sym +                 } +  in+  let _  = List.iter (z3Pred me env <+> SMT.assertAxiom me.c) (axioms ++ ps) in+  let _  = assert_distinct_constants me env consts                      in+  me++class tprover ts env ps consts : prover = +  object (self)+    val me = create ts env ps consts +    method interp_syms  = Theories.interp_syms +    method set_filter :  'a. Ast.Sort.t Ast.Symbol.SMap.t +                          -> Ast.Symbol.t +                          -> Ast.pred list +                          -> ('a * Ast.pred) list +                          -> 'a list+                        = set_filter me  +    method print_stats  = fun ppf -> print_stats ppf me +    method is_contra    = is_contra me +    method unsat_suffix = unsat_suffix me+  end++let mkProver ts env ps consts = new tprover ts env ps consts++end
+ external/fixpoint/tpNull.ml view
@@ -0,0 +1,38 @@+(*+ * Copyright © 2008 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.+ *)++open FixMisc.Ops++module Mem : ProverArch.PROVER = TpGen.MakeProver(SmtZ3.SMTZ3)+module Smt : ProverArch.PROVER = TpGen.MakeProver(SmtLIB2.SMTLib2)++let mydebug = false++let create ts env ps cs  +  = match !Constants.smt_solver with+      | None   -> +          Constants.bprintflush mydebug "\nUSING z3 bindings \n"; +          Mem.mkProver ts env ps cs+      | Some s -> +          Constants.bprintflush mydebug ("\nUSING SMTLIB bindings with " ^ s ^ "\n"); +          Smt.mkProver ts env ps cs+
+ external/misc/bNstats.ml view
@@ -0,0 +1,118 @@+(*+ *+ * Copyright (c) 2001 by+ *  George C. Necula	necula@cs.berkeley.edu+ *  Scott McPeak        smcpeak@cs.berkeley.edu+ *  Wes Weimer          weimer@cs.berkeley.edu+ *   + * All rights reserved.  Permission to use, copy, modify and distribute+ * this software for research purposes only is hereby granted, + * provided that the following conditions are met: + * 1. XSRedistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the authors may not be used to endorse or promote products + * derived from  this software without specific prior written permission. + *+ * DISCLAIMER:+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ *)++                                        (* A hierarchy of timings *)+type t = { name : string;+           mutable time : float;+           mutable sub  : t list}++                                        (* Create the top level *)+let top = { name = "TOTAL";+            time = 0.0;+            sub  = []; }++                                        (* The stack of current path through +                                         * the hierarchy. The first is the +                                         * leaf. *)+let current : t list ref = ref [top]++let reset () = top.sub <- []++let do_time = ref true ++let dont_time () = do_time := false++let print chn msg = +  (* Total up *)+  top.time <- List.fold_left (fun sum f -> sum +. f.time) 0.0 top.sub;+  let rec prTree ind node = +    Printf.fprintf chn "%s%-20s          %6.3f s\n" +      (String.make ind ' ') node.name node.time  ;+    List.iter (prTree (ind + 2)) node.sub+  in+  Printf.fprintf chn "%s" msg;+  List.iter (prTree 0) [ top ]+        +let time str f arg = +  (* Find the right stat *)+  let stat : t = +    let curr = match !current with h :: _ -> h | _ -> assert false in+    let rec loop = function+        h :: _ when h.name = str -> h+      | _ :: rest -> loop rest+      | [] -> +          let nw = {name = str; time = 0.0; sub = []} in+            curr.sub <- nw :: curr.sub;+            nw+    in+      loop curr.sub+  in+  let oldcurrent = !current in+    current := stat :: oldcurrent;+    let start = (Unix.times ()).Unix.tms_utime in+    let _ = if str == "interp" then Printf.printf "interp start = %6.3f\n" start in+    let res   = +      try (f arg) with+	  x -> (let finish   = Unix.times () in+		let diff = finish.Unix.tms_utime -. start in+		let _ = if str == "interp" then Printf.printf "interp elapsed = %6.3f\n" diff in+		  stat.time <- stat.time +. (diff);+		  current := oldcurrent;+                  raise x) (* Pop the current stat *)+    in+    let finish   = Unix.times () in+    let diff = finish.Unix.tms_utime -. start in+    let _ = if str == "interp" then Printf.printf "interp elapsed = %6.3f\n" diff in+      stat.time <- stat.time +. (diff);+      current := oldcurrent;+      res+	++let time str f arg = if !do_time then time str f arg else f arg  ++let print chn msg = if !do_time then print chn msg else ()++++++++++++++++
+ external/misc/bNstats.mli view
@@ -0,0 +1,48 @@+(*  + *+ * Copyright (c) 2001 by+ *  George C. Necula	necula@cs.berkeley.edu+ *  Scott McPeak        smcpeak@cs.berkeley.edu+ *  Wes Weimer          weimer@cs.berkeley.edu+ *   + * All rights reserved.  Permission to use, copy, modify and distribute+ * this software for research purposes only is hereby granted, + * provided that the following conditions are met: + * 1. XSRedistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the authors may not be used to endorse or promote products + * derived from  this software without specific prior written permission. + *+ * DISCLAIMER:+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ *)++(** Utilities for maintaining timing statistics *)++val dont_time : unit -> unit++(** Reset all the timings *)+val reset : unit -> unit ++(** Time a function and associate the time with the given string. If some+    timing information is already associated with that string, then accumulate+    the times. If this function is invoked within another timed function then+    you can have a hierarchy of timings *)+val time : string -> ('a -> 'b) -> 'a -> 'b ++(** Print the current stats preceeded by a message *)+val print : out_channel -> string -> unit+
+ external/misc/constants.ml view
@@ -0,0 +1,405 @@+(*+ * 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.+ *)++open FixMisc.Ops+module SS = FixMisc.StringSet++(******* This module contains globals representing "flags" **************)+let lib_path            = Sys.argv.(0) |> Filename.dirname |> ref+let annotsep_name       = "\n\n=+=\n\n"+let global_name         = "GLOBAL"+++let file: string option ref = ref None         (* last commandline param*)+let csolve_file_prefix  = ref "csolve"         (* where to find/place csolve-related files *)+let safe                = ref false            (* -safe *)+let manual              = ref false            (* -manual *)+let out_file            = ref "out"            (* -save *)+let save_file           = ref "out.fq"         (* -save *)+let dump_ref_constraints= ref false            (* -drconstr *)+let ctypes_only         = ref false            (* -ctypes *)+let verbose_level       = ref 0                (* -v *)+let inccheck            = ref SS.empty         (* -inccheck *)+let cex                 = ref false            (* -counterexamples *)+let shortannots         = ref true             (* -shortannots *)+let strictsortcheck     = ref false            (* -strictsortcheck *)+let latex_file: string option ref = ref None   (* translate to LaTeX *)+let armc_file: string option ref  = ref None   (* translate to ARMC *)+let horn_file: string option ref  = ref None   (* translate to Horn clauses *)+let raw_horn_file: string option ref  = ref None   (* translate to raw Horn clauses *)+let q_armc_file: string option ref = ref None   (* OBSOLETE translate to Q'ARMC file *)+let dot_file: string option ref = ref None   (* translate to dot file *)+let purify_function_application = ref true  (* replace fun-terms by existentially quantified variables *)+let z3_timeout           = ref 25++let fastscalar                  = ref false (* -fastscalar *)+let vannots                     = ref true  (* -noannots *)+let minquals                    = ref true  (* -allquals *)+let ptag                        = ref true  (* -ptag *)+let genspec                     = ref false (* -genspec *)+let simplify_t                  = ref false (* simplify and prune vacuous FixConstraint.t constraints *)+let copyprop                    = ref true  (* perform copyprop to eliminate tempvars *)+let root                        = ref ""    (* root function *)+let refine_sort                 = ref false (* -refinesort *)+let sorted_quals                = ref false (* -sortedquals *)+let true_unconstrained          = ref true  (* -true_unconstrained *)+let do_nothing                  = ref false (* -nop *)+let smt_solver                  = ref (Some "z3") (* -smtsolver [z3, yices, cvc4, ...] *)+let dump_imp                    = ref false (* -imp *)+let dump_smtlib                 = ref false (* -smtlib *)+let dump_simp                   = ref ""    (* -simp *)+let prune_live                  = ref false (* -prunelive *)+let print_nontriv               = ref false (* -print_nontriv *)+let heapify_nonarrays           = ref true  (* heapify all stack variables *)+let timeout                     = ref (-1)+let lfp                         = ref true  (* -nolfp *)+let slice                       = ref true  (* -slice  *)+let no_lib_hquals               = ref false (* -no-lib-hquals *)+let gen_qual_sorts              = ref true  (* -no-gen-qual-sorts  *)+let web_demo                    = ref false (* -web-demo *)+let simple                      = ref true  (* -simple  *) ++(* JHALA: what do these do ? *)+let psimple       = ref true            (* -psimple *)+let dump_graph    = ref false           (* -dgraph :: this probably caused the dsolve solver to dump the constraint graph *)+let dropcalls     = ref false           (* -dropcalls *)+let adjdeps       = ref true            (* -origdeps *)+let check_is      = ref false           (* -check-indices *)+let trace_scalar  = ref false           (* -trace-scalar *)+let prune_index   = ref false           (* -prune-index *)  +let uif_multiply  = ref true            (* -no-uif-multiply *) ++(****************************************************************)+(************* Output levels ************************************)+(****************************************************************)+ +(* verbosity levels by purpose *)+let ol_always = 0+let ol_solve_error = 1+let ol_warning = 1+let ol_solve_master = 2+let ol_solve_stats = 2+let ol_timing = 2+let ol_warn_mlqs = 3+let ol_normalized = 3+let ol_finals = 3+let ol_ctypes = 3+let ol_dquals = 4 +let ol_unique_names = 5 (* must be > ol_dquals *)+let ol_solve = 10 +let ol_refine = 11 +let ol_scc = 12 +let ol_dump_env = 10 +let ol_axioms = 5+let ol_dump_prover = 20+let ol_verb_constrs = 21+let ol_dump_wfs = 22+let ol_dump_meas = 30+let ol_dump_quals = 50+let ol_insane = 200++let verb_stack = ref []+let ck_olev l              = l <= !verbose_level+let null_formatter         = Format.make_formatter (fun a b c -> ()) ignore+let nprintf a              = Format.fprintf null_formatter a+let cprintf l              = if ck_olev l then Format.printf else nprintf+let ecprintf l             = if ck_olev l then Format.eprintf else nprintf+let fcprintf ppf l         = if ck_olev l then Format.fprintf ppf else nprintf+let icprintf printer l ppf = if ck_olev l then printer ppf else printer null_formatter+let cprintln l s           = if ck_olev l then Printf.ksprintf (Format.printf "@[%s@\n@]") s else nprintf+let elevate_olev l         = if ck_olev l then () else verb_stack := !verbose_level :: !verb_stack; verbose_level := l+let restore_olev           = match !verb_stack with +                               | x :: xs -> verbose_level := x; verb_stack := xs +                               | _       -> ()++let bprintf b       = if b || ck_olev 1 then Format.printf else nprintf+let bprintflush b s = bprintf b "%s" s; flush stdout++++(******************************************************************************)+(*********************************** Logging **********************************)+(******************************************************************************)++let logChannel   = ref stdout+let logFormatter = ref (Format.formatter_of_out_channel stdout)++let setLogChannel lc =+  logChannel   := lc;+  logFormatter := Format.formatter_of_out_channel lc++let logPrintf a  = Format.fprintf !logFormatter a+let blogPrintf b = if b then logPrintf else nprintf+let cLogPrintf l = if ck_olev l then logPrintf else nprintf++(*****************************************************************)+(*********** Command Line Options ********************************)+(*****************************************************************)++(* taken from dsolve/liquid/liquid.ml *)++let arg_spec = +  [("-out", +    Arg.String (fun s -> out_file := s), +    " Save solution to file [out]"); +   ("-save", +    Arg.String (fun s -> save_file := s), +    " Save constraints to file [out.fq]"); +   ("-inccheck", +    Arg.String (fun s -> true_unconstrained := false; +                         inccheck := SS.add s !inccheck), +    " Incrementally check the specified function"); +   ("-noslice",+   Arg.Clear slice,+   " Compute fixpoint for all kvars, not just those affecting property"); +   ("-nolfp",+   Arg.Clear lfp,+   " Weaken environment (do not produce least fixed-point solution)"); +   ("-origdeps",+     Arg.Clear adjdeps,+     " Don't adjust constraint dependencies [true]");+   ("-dropcalls",+     Arg.Set dropcalls,+     " Ignore function calls during consgen [false]");+   ("-drconstr", +    Arg.Set dump_ref_constraints, +    " Dump refinement constraints [false]");+   ("-noshortannots",+    Arg.Clear shortannots,+    " Annotations with full predicates (not names) [false]");+   ("-strictsortcheck",+    Arg.Set strictsortcheck,+    " Strict Sort Checking -- e.g. ptr/int comparisons -- for non-C constraints+    [false]");+   ("-ctypes",+    Arg.Set ctypes_only,+    " Infer ctypes only [false]");+   ("-safe", +    Arg.Set safe, +    " run in failsafe mode [false]");+   ("-manual",+    Arg.Set manual,+    " only verify manually-inserted checks");+   ("-fastscalar",+    Arg.Set fastscalar,+    " use new (experimental) fastscalar solver, eventually will be default"); +   ("-counterexamples",+    Arg.Set cex,+    " generate counterexamples [false] ");+   ("-noannots",+    Arg.Unit (fun () -> vannots := false; minquals := false),+    " generate vim readable annotation file [true] ");+   ("-allquals",+    Arg.Clear minquals,+    " don't minimize qualifiers by using pre-computed one-level implication [true] ");+   ("-timeout",+    Arg.Set_int timeout,+    " limit total time (in seconds, default no limit)");+   ("-ptag", +    Arg.Set ptag, +    " prioritize constraints using lexico-ordering on tags [true]");+   ("-genspec", +    Arg.Set genspec, +    " Generate spec file only [false]");+   ("-root",+    Arg.String (fun s -> root := s),+    " Use root function []");+   ( "-nosimple"+   , Arg.Clear simple+   , " Directly propagate qualifiers for simple constraints (K1 <: K2) [true]");+   ("-psimple", +    Arg.Set psimple, +    " prioritize simple constraints [true]");+   ("-dgraph", +    Arg.Set dump_graph, +    " dump constraints SCC to constraints.dot [false]");+   ("-sortedquals",+    Arg.Set sorted_quals,+    " use sorted parameters in the qualifiers, to speed up instantiation. Should+      become default after vetting.");+   ("-refinesort",+    Arg.Set refine_sort,+    " use sortchecking to refine constraints -- and toss out badly instantiated quals. +      Shouldn't need except for backward compatibility with dsolve constraints, DONT USE!");+   ("-notruekvars",+    Arg.Clear true_unconstrained,+    " don't true unconstrained kvars [true]");+   ("-v", Arg.Int (fun c -> verbose_level := c), +              " <level> Set degree of analyzer verbosity:\n\+               \032    0      No output\n\+               \032    1      +Verbose errors\n\+               \032    [2]    +Verbose stats, timing\n\+               \032    3      +Print normalized source\n\+               \032    11     +Verbose solver\n\+               \032    13     +Dump constraint graph\n\+               \032    64     +Drowning in output");+   ("-latex", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 || String.sub s (l-4) 4 <> ".tex" then+		      print_endline "-latex: invalid parameter"+		    else+		      latex_file := Some s),+    " translates constraints to LaTeX file"+   );+   ("-armc", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 then+		      print_endline "-armc: invalid parameter"+		    else+		      armc_file := Some s),+    " translate constraints to ARMC file"+   );+   ("-horn", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 then+		      print_endline "-rules: invalid parameter"+		    else+		      horn_file := Some s),+    " translate constraints to Horn clauses"+   );+   ("-raw-horn", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 then+		      print_endline "-rules: invalid parameter"+		    else+		      raw_horn_file := Some s),+    " translate constraints to raw Horn clauses"+   );+   ("-qarmc", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 then+		      print_endline "-qarmc: invalid parameter"+		    else+		      q_armc_file := Some s),+    " translate constraints to Q'ARMC file"+   );+   ("-dot", +    Arg.String (fun s -> +		  let l = String.length s in+		    if l = 0 || String.sub s (l-4) 4 <> ".dot" then+		      print_endline "-dot: invalid parameter"+		    else+		      dot_file := Some s),+    " translate constraints to dot file"+   );+   ("-keep-uif", +    Arg.Clear purify_function_application,+    " do not replace function terms by existentially quantified variables"+   );+   ("-no-simplify-t", +    Arg.Clear simplify_t,+    " do not simplify constraints"+   );+   ("-simplify-t", +    Arg.Set simplify_t,+    " simplify constraints"+   );+   ("-nocopyprop", +    Arg.Clear copyprop,+    " simplify constraints via local copy propagation [true]"+   );+   ("-libpath",+    Arg.String (fun s -> lib_path := s), +    (" library path for default spec, quals ["^(!lib_path)^"]")+   );+   ("-nop",+    Arg.Set do_nothing,+    " do nothing (useful for regression tests known to be broken)";+   );+   ("-imp",+    Arg.Set dump_imp,+    " print constraints as IMP program (experimental)"+   );+   ("-smtsolver",+    Arg.String (fun s -> smt_solver := if s = "z3mem" then None else Some s),+    (" SMT solver (default: Z3 SMTLIB2. z3mem for bindings)")+   );+   ("-smtlib",+    Arg.Set dump_smtlib,+    " print constraints as SMTLIB query (experimental)"+   );+   ("-prunelive",+    Arg.Set prune_live,+    " Restrict liquid types to live variables (experimental)"+   );+   ("-no-uif-multiply",+    Arg.Clear uif_multiply,+    " Don't encode non-linear multiplication with UIFs [true]"+   );+   ("-simp",+    Arg.String ((:=) dump_simp),+    " print simplified constraints to save-file (experimental) use [andrey] or [jhala] or [id]"+   );+   ("-print-nontriv",+    Arg.Set (print_nontriv),+    " print non-trivial bindings in each environment [false]"+   );+   ("-trace-scalar",+    Arg.Set(trace_scalar),+    " print constraints and index values in the Index solver");+   ("-check-indices",+    Arg.Set(check_is),+    " sanity check computed indices");+   ("-prune-index",+    Arg.Set(prune_index),+    " use the index domain to prune initial solution");+   ("-no-lib-hquals",+    Arg.Set(no_lib_hquals),+    " don't use qualifier library in type inference");+   ("-no-gen-qual-sorts",+    Arg.Clear(gen_qual_sorts),+    " don't generalize parameter sorts in qualifiers");+   ("-web-demo",+    Arg.Set(web_demo),+    " set HTML output to web demo mode");+  ]+++let is_prefix p s = +  let reg = Str.regexp p in+  Str.string_match reg s 0++(******************************************************************)+(*************** Paths for builtin specs, quals etc ***************)+(******************************************************************)++let get_lib_squals  = fun () -> Filename.concat !lib_path "lib.squals"+let get_lib_hquals  = fun () -> Filename.concat !lib_path "lib.hquals"+let get_lib_spec    = fun () -> Filename.concat !lib_path "lib.spec"+let get_lib_h       = fun () -> Filename.concat !lib_path "lib.h"+let get_csolve_h    = fun () -> Filename.concat !lib_path "../lib/csolve.h"+let get_c2html      = fun () -> Filename.concat !lib_path "../demo/jquery/cs2html.py"++(* TODO: FIX SHADY HACK *)+let set_csolve_file_prefix fn = csolve_file_prefix := fn+(*+  let fn' = try (Filename.chop_extension fn)^".c" with _ -> fn   in+  if Filename.check_suffix fn ".o" && Sys.file_exists fn' then +    csolve_file_prefix := fn'+  else +    csolve_file_prefix := fn+    *)
+ external/misc/errorline.ml view
@@ -0,0 +1,31 @@+type info =+    { mutable  linenum: int;   (* current line number *)+      mutable  linepos: int;   (* char position of beginning of current line *)	+      fileName        : string (* current file name *)+    }+      +let current : info ref = +  ref +    { linenum  = 1 ;+      linepos  = 0 ;+      fileName = ""+    }	++let startFile fname =+  current := { linenum  = 1 ;+               linepos  = 0 ;+               fileName = fname}++let startNewline n =+  let i = !current in+  begin+    i.linenum <- i.linenum + 1 ;+    i.linepos <- n+  end++    +let error n msg = +  let i = !current in+    Printf.eprintf "%s at %s: %d.%d\n" +      msg i.fileName i.linenum (n - i.linepos)+       
+ external/misc/fcommon.ml view
@@ -0,0 +1,128 @@+(*+ * Copyright © 2008 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 F = Format+module C = Constants++let mydebug = false ++(****************************************************************)+(************* SCC Ranking **************************************)+(****************************************************************)++module Int : Graph.Sig.COMPARABLE with type t = int * string =+struct+   type t = int * string +   let compare = compare+   let hash = Hashtbl.hash+   let equal = (=)+end++module G = Graph.Imperative.Digraph.Concrete(Int)++module SCC = Graph.Components.Make(G)    ++(* Use of Graphviz *)++let io_to_string = function +  | Some i -> string_of_int i +  | None -> "*"++module DotGraph =+struct+   type t = G.t+   module V = G.V+   module E = G.E+   let iter_vertex = G.iter_vertex+   let iter_edges_e = G.iter_edges_e+   let graph_attributes g = [`Size (11.0, 8.5); `Ratio (`Float 1.29)]+   let default_vertex_attributes g = [`Shape `Box]+   let vertex_name (i,_) = string_of_int i (* Printf.sprintf "V_%d" i *) +   let vertex_attributes (_,s) = [`Label s]+   let default_edge_attributes g = []+   let edge_attributes e = []+   let get_subgraph v = None+end++module Dot = Graph.Graphviz.Dot(DotGraph) ++let dump_graph s g = +  let oc = open_out (s^".dot") in+  Dot.output_graph oc g; +  close_out oc++let int_s_to_string ppf (i,s) = +  F.fprintf ppf "(%d,%s)" i s ++let scc_print g a = +  C.bprintf mydebug "dep graph: vertices= %d, sccs= %d \n" (G.nb_vertex g) (Array.length a);+  C.bprintf mydebug "scc sizes: \n";+  Array.iteri begin fun i xs -> +    C.bprintf mydebug "%d : [%a] \n" i (FixMisc.pprint_many false "," int_s_to_string) xs+  end a;+  C.bprintf mydebug "\n"++let make_graph s f is ijs = +  let g = G.create () in+  let _ = List.iter (fun i -> G.add_vertex g (i, (f i))) is in+  let _ = List.iter (fun (i,j) -> G.add_edge g (i,(f i)) (j,(f j))) ijs in+  let _ = if !Constants.dump_graph then dump_graph s g in+  g+ +(* Given list [(u,v)] returns a numbering [(ui,ri)] s.t. + * 1. if ui,uj in same SCC then ri = rj+ * 2. if ui -> uj then ui >= uj *)+let scc_rank s f is ijs = +  let g = BNstats.time "making_graph" (make_graph s f is) ijs in+  let a = SCC.scc_array g in+  let _ = scc_print g a in+  let sccs = FixMisc.array_to_index_list a in+  FixMisc.flap (fun (i,vs) -> List.map (fun (j,_) -> (j,i)) vs) sccs++(*+let g1 = [(1,2);(2,3);(3,1);(2,4);(3,4);(4,5)];;+let g2 = [(0,1);(1,2);(2,0);(1,3);(4,3);+          (5,6);(5,7);(6,9);(7,9);(7,8);(8,5)];;+let g3 = (6,2)::g2;;+let g4 = (2,6)::g2;;+  +let n1 = make_scc_num g1 ;;+let n2 = make_scc_num g2 ;;+let n3 = make_scc_num g3 ;;+let n4 = make_scc_num g4 ;; *)++(*+type fc_id = int option +type subref_id = int ++module WH = +  Heaps.Functional(struct +      type t = subref_id * int * (int * bool * fc_id)+      let compare (_,ts,(i,j,k)) (_,ts',(i',j',k')) =+        if i <> i' then compare i i' else+          if ts <> ts' then -(compare ts ts') else+            if j <> j' then compare j j' else +              compare k' k+    end)+*)+
+ external/misc/fcommon.mli view
@@ -0,0 +1,24 @@+(*+ * Copyright © 2008 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.+ *+ *)++val scc_rank : string -> (int -> string) -> int list -> (int * int) list -> (int * int) list 
+ external/misc/fixMisc.ml view
@@ -0,0 +1,1353 @@+(*+ * Copyright ? 1990-2007 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.+ *+ *)++(* $Id: misc.ml,v 1.14 2006/09/26 01:47:01 jhala Exp $+ *+ * This file is part of the SIMPLE Project.+ *)++(**+ * This module provides some miscellaneous useful helper functions.+ *)++module Ops = struct++  type ('a, 'b) either = Left of 'a | Right of 'b++  let (>|) _ x = x++  let (|>) x f = f x++  let (<|) f x = f x++  let (>>) x f = f x; x++  let (|>>) xo f = match xo with None -> None | Some x -> f x++  let (|>:) xs f = List.map f xs++  let (=+) x n = let v = !x in (x := v + n; v)++  let (+=) x n = x := !x + n; !x++  let (++) = List.rev_append++  let (+++)= fun (x1s, y1s) (x2s, y2s) -> (x1s ++ x2s, y1s ++ y2s)++  let id = fun x -> x++  let un = fun x -> ()++  let const x = fun _ -> x++  let (<.>) f g  = fun x -> x |> g |> f++  let (<+>) f g  = fun x -> x |> f |> g ++  let (<?>) b f  = fun x -> if b then f x else x++  let wwhen b f  = fun x -> if b then f x ++  let (<*>) f g  = fun x -> (f x, g x)+  +  let (<**>) f g = fun (x, y) -> (f x, g y)++  let (<&&>) f g = fun x -> f x && g x++  let failure fmt = Printf.ksprintf failwith fmt++  let foreach xs f = List.map f xs++  let asserts p fmt =+    Printf.ksprintf (fun x -> if not p then failwith x) fmt++let asserti = asserts+  (*+let asserti p fmt = +  Printf.ksprintf (fun x -> if not p then (print_string (x^"\n"); ignore(0/0)) else ()) fmt+*)++let assertf fmt =+  Printf.ksprintf failwith fmt++let halt _ =+  assert false++let fst3 (x,_,_) = x+let snd3 (_,x,_) = x+let thd3 (_,_,x) = x++let fst4 (x, _, _, _) = x+let snd4 (_, x, _, _) = x+let thd4 (_, _, x, _) = x+let fth4 (_, _, _, x) = x++let withfst3 (_,y,z) x = (x,y,z)+let withsnd3 (x,_,z) y = (x,y,z)+let withthd3 (x,y,_) z = (x,y,z)++let print_now s = +  print_string s;+  flush stdout++let print_now_error msg =+  prerr_string msg;+  flush stderr++let output_now c s = +  output_string c s; +  flush c++let some = fun x -> Some x++end++open Ops++let maybe_fold f b xs = +  let fo = fun bo x -> match bo with Some b -> f b x | _ -> None in+  List.fold_left fo (Some b) xs++let maybe_map f = function Some x -> Some (f x) | None -> None++let maybe_iter f = function Some x -> f x | None -> ()++let maybe = function Some x -> x | _ -> assertf "maybe called with None"++let maybe_apply f xo v = match xo with Some x -> f x v | None -> v++let maybe_default xo y = match xo with Some x -> x | None -> y++let maybe_string f = function Some x -> "Some " ^ (f x) | None -> "None"++let rec maybe_chain x d = function +  | f::fs -> (match f x with +              | Some y -> y +              | None -> maybe_chain x d fs)+  | []    -> d++++++let trace s f x =+  let _ = print_now <| Printf.sprintf "BEGIN: %s \n" s in+  let r = f x in+  let _ = print_now <| Printf.sprintf "END: %s \n" s   in+  r++(* ORIG+let rec pprint_many_box s f ppf = function+  | []     -> ()+  | x::[]  -> Format.fprintf ppf "%a" f x+  | x::xs' -> (Format.fprintf ppf "%a%s@\n" f x s; pprint_many_box s f ppf xs')+*)+let rec pprint_many_prefix sep base f ppf = function+  | x::xs -> Format.fprintf ppf "(%s %a %a)" +               sep f x (pprint_many_prefix sep base f) xs+  | []    -> Format.fprintf ppf "%a" f base+++let rec pprint_many_box brk s f ppf = function+  | []              -> ()+  | [x]             -> Format.fprintf ppf "%a" f x+  | x::xs' when brk -> Format.fprintf ppf "%a@\n%s" f x s; +                       pprint_many_box brk s f ppf xs'+  | x::xs'          -> Format.fprintf ppf "%a@,%s" f x s;+                       pprint_many_box brk s f ppf xs'++let pprint_many_box brk l s r f ppf = function+  | []     -> Format.fprintf ppf "[]"+  | xs     -> Format.fprintf ppf "@[%s%a%s@]" l (pprint_many_box brk s f) xs r++let pprint_many_brackets brk f ppf x = +  Format.fprintf ppf "%a" (pprint_many_box brk "[ " "; " "]" f) x++let rec pprint_many brk s f ppf = function+  | []              -> ()+  | [x]             -> Format.fprintf ppf "%a" f x+  | x::xs' when brk -> Format.fprintf ppf "%a%s@," f x s; pprint_many brk s f ppf xs'+  | x::xs'          -> Format.fprintf ppf "%a%s" f x s ; pprint_many brk s f ppf xs'++let pprint_maybe f ppf = function+  | Some x -> Format.fprintf ppf "Some %a" f x+  | None   -> Format.fprintf ppf "None"++let pprint_int ppf i =+  Format.fprintf ppf "%d" i++let pprint_int_o = pprint_maybe pprint_int+(*+let pprint_int_o ppf = function+  | None -> Format.fprintf ppf "None" +  | Some d -> Format.fprintf ppf "Some(%d)" d+*)++let pprint_str ppf s =+  Format.fprintf ppf "%s" s++let pprint_ints ppf is = +  pprint_many_brackets false (fun ppf i -> Format.fprintf ppf "%d" i) ppf is++let pprint_pretty_ints ppf is = +  is |> List.map string_of_int |> String.concat ";" |> Format.fprintf ppf "[%s]"++let pprint_tuple pp1 pp2 ppf (x1, x2) = +  Format.fprintf ppf "(%a, %a)" pp1 x1 pp2 x2++let rec subsets n = function+  | _ when n <= 0 +    -> [[]]+  | xs when n > List.length xs->+      []+  | x::xs +    -> (List.map (fun ys -> x :: ys) (subsets (n-1) xs))+    ++ (subsets n xs)+  | _ -> assertf "Misc.subsets"++let choose b f g = if b then f else g++let liftfst2 (f: 'a -> 'a -> 'b) (x: 'a * 'c) (y: 'a * 'c): 'b =+  f (fst x) (fst y)++let curry   = fun f x y   -> f (x,y)+let uncurry = fun f (x,y) -> f x y+let flip    = fun f x y   -> f y x++let maybe_bool = function+  | Some _ -> true+  | None   -> false++module type EMapType = sig+  include Map.S+  val extendWith   : (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t+  val extend       : 'a t -> 'a t -> 'a t+  val filter       : (key -> 'a -> bool) -> 'a t -> 'a t+  val of_list      : (key * 'a) list -> 'a t+  val to_list      : 'a t -> (key * 'a) list+  val length       : 'a t -> int+  val domain       : 'a t -> key list+  val range        : 'a t -> 'a list+  val join         : 'a t -> 'b t -> ('a * 'b) t+  val adds         : key -> 'a list -> 'a list t -> 'a list t+  val of_alist     : (key * 'a) list -> 'a list t+  val finds        : key -> 'a list t -> 'a list+  val safeFind     : key -> 'a t -> string -> 'a+  val safeAdd      : key -> 'a -> 'a t -> string -> 'a t+  val single       : key -> 'a -> 'a t+  val map_partial  : ('a -> 'b option) -> 'a t -> 'b t+  val maybe_find   : key -> 'a t -> 'a option+  val find_default : 'a -> key -> 'a t -> 'a+  val frequency    : key list -> int t+end++module type ESetType = sig+  include Set.S+  val of_list : elt list -> t+end++module ESet (K: Set.OrderedType) = +  struct+    include Set.Make(K)+    let of_list = List.fold_left (flip add) empty  +end++module type EOrderedType = sig+  include Map.OrderedType +  val print : Format.formatter -> t -> unit+end++(* module EMap (K: Map.OrderedType) = *) +module EMap (K: EOrderedType) = +  struct+    include Map.Make(K)++    let extendWith (f: key -> 'a -> 'a -> 'a) (m1: 'a t) (m2: 'a t) =+      fold begin fun k v m -> +        let v' = if mem k m then f k v (find k m) else v in+        add k v' m+      end m2 m1 +    +    let extend (m1: 'a t)  (m2: 'a t) : 'a t = fold add m2 m1++    (* in 3.12 *)+    let filter (f: key -> 'a -> bool) (m: 'a t) : 'a t =  +      fold (fun x y m -> if f x y then add x y m else m) m empty +    +    let of_list (kvs : (key * 'a) list) = +      List.fold_left (fun m (k, v) -> add k v m) empty kvs++        (* in 3.12 -- bindings *)+    let to_list (m : 'a t) : (key * 'a) list = +      fold (fun k v acc -> (k,v)::acc) m [] ++    (* in 3.12 -- cardinality *)+    let length (m : 'a t) : int = +      fold (fun _ _ i -> i+1) m 0++    (* in 3.12 -- singleton *)+    let single k v = add k v empty++    let domain m =+      fold (fun k _ acc -> k :: acc) m []++    let range (m : 'a t) : 'a list = +      fold (fun _ v acc -> v :: acc) m []+     +    let join (m1 : 'a t) (m2 : 'b t) : ('a * 'b) t =+      mapi begin fun k v1 ->+        let _  = asserts (mem k m2) "EMap.join" in+        (v1, find k m2) +      end m1++    let maybe_find k m = +      try Some (find k m) with Not_found -> None++    let find_default d k m = +      maybe_default (maybe_find k m) d ++    (* let finds k m = try find k m with Not_found -> [] *)+    let finds k m = find_default [] k m++    let adds (k: key) (vs: 'a list) (m : ('a list) t) : 'a list t = +      add k (vs ++ find_default [] k m) m++    let of_alist (kvs : (key * 'a) list) =+      List.fold_left (fun m (k, v) -> adds k [v] m) empty kvs+     +    let frequency (ks : key list) : int t =+      List.fold_left (fun m k -> +        add k (1 + (find_default 0 k m)) m+      ) empty ks ++    let safeFind k m msg =+      try find k m with Not_found -> +        let err = Format.fprintf Format.str_formatter +                    "ERROR: safeFind (%s): %a" msg K.print k; +                  Format.flush_str_formatter ()+        in failwith err++    let safeAdd k v m msg =+      if mem k m then +        let err = Format.fprintf Format.str_formatter +                    "ERROR: safeAdd (%s): %a" msg K.print k; +                  Format.flush_str_formatter ()+        in failwith err+      else add k v m++    let map_partial f m = +      fold (fun x yo m -> match yo with Some y -> add x y m | _ -> m) (map f m) empty +  end++module type KeyValType =+  sig+    type t+    val compare : t -> t -> int+    val print : Format.formatter -> t -> unit ++    type v+    val default : v+  end++module MapWithDefault (K: KeyValType) =+  struct+    include EMap(K)+    let find (i: K.t) (m: K.v t): K.v =+      try find i m with Not_found -> K.default+  end++module IntMap = +  EMap+  (struct+    type t = int+    let compare i1 i2 = compare i1 i2+    let print         = pprint_int+  end)++module IntSet =+  ESet+  (struct+    type t = int+    let compare i1 i2 =+      compare i1 i2+  end)++module IntIntMap = +  EMap +  (struct+    type t = int * int+    let compare i1 i2 = compare i1 i2+    let print ppf (i1, i2) = Format.fprintf ppf "(%d, %d)" i1 i2+   end)++module StringMap = +  EMap +  (struct+    type t = string +    let compare i1 i2 = compare i1 i2+    let print ppf s   = Format.fprintf ppf "%s" s+  end)++module StringSet =+  ESet+  (struct+    type t = string+    let compare i1 i2 = compare i1 i2+  end)++(* +let sm_join sm1 sm2 = +  StringMap.mapi (fun k v1 ->+    let v2 = asserts (StringMap.mem k sm2) "sm_join"; StringMap.find k sm2 in+    (v1, v2)+  ) sm1++let sm_extend sm1 sm2 =+  StringMap.fold StringMap.add sm2 sm1 ++let sm_filter f sm = +  StringMap.fold begin fun x y sm -> +    if f x y then StringMap.add x y sm else sm +  end sm StringMap.empty ++let sm_of_list kvs = +  List.fold_left (fun sm (k,v) -> StringMap.add k v sm) StringMap.empty kvs++let sm_to_list sm = +  StringMap.fold (fun k v acc -> (k,v)::acc) sm [] ++let sm_to_range sm = +  sm |> sm_to_list |> List.map snd+*)++let sm_print_keys name sm =+  sm |> StringMap.to_list +     |> List.map fst +     |> String.concat ", "+     |> Printf.printf "%s : %s \n" name++let foldn f n b = +  let rec foo acc i = +    if i >= n then acc else foo (f acc i) (i+1) +  in foo b 0 ++let rec range i j = +  if i >= j then [] else i::(range (i+1) j)++let dump s = +  print_string s; flush stdout++let mapn f n = +  foldn (fun acc i -> (f i) :: acc) n [] +  |> List.rev++let chop_last = function+  | [] -> failure "ERROR: Misc.chop_last"+  | xs -> xs |> List.rev |> List.tl |> List.rev++let list_snoc xs = +  match List.rev xs with +  | [] -> assertf "list_snoc with empty list!"+  | h::t  -> h, List.rev t++let negfilter f xs = +  List.fold_left (fun acc x -> if f x then acc else x::acc) [] xs +  |> List.rev++let get_option d = function  +  | Some x -> x +  | None   -> d++let list_somes xs =+  xs |> List.fold_left begin fun acc -> function +          | Some x -> x :: acc +          | None   -> acc +        end []+     |> List.rev++(* let map_partial f = list_somes <.> List.map f  *)++let map_partial f xs =+  List.rev +    (List.fold_left +      (fun acc x -> +        match f x with+        | None   -> acc+        | Some z -> (z::acc)) [] xs)+++let fold_left_partial f b xs =+  List.fold_left begin fun b xo ->+    match xo with+      | Some x -> f b x+      | None   -> b+  end b xs++let list_reduce msg f = function+  | []    -> assertf "ERROR: list_reduce with empty list: %s" msg +  | x::xs -> List.fold_left f x xs++let nonnull = function+  | [] -> false+  | _  -> true++(*+let list_is_empty = function+  | [] -> true+  | _::_ -> false+*)++let list_max x xs = +  List.fold_left max x xs++let list_min x xs = +  List.fold_left min x xs++let list_max_with msg f = function+  | []    -> assertf "ERROR: list_max_with with empty list: %s" msg +  | x::xs -> List.fold_left (fun acc x -> if f x > f acc then x else acc) x xs++let rec take_max n = function+  | x :: xs when n > 0 -> x :: take_max (n - 1) xs+  | _                  -> []+    +let rec drop n = function+  | x :: xs when n > 0 -> drop (n - 1) xs+  | []      when n > 0 -> assertf "ERROR: dropped too many"+  | xs -> xs++let getf a i fmt = +  try a.(i) with ex -> assertf fmt++let do_catchu f x g =+  try f x with ex -> (g ex; raise ex)++let do_catchf s f x =+  try f x with ex -> +    assertf "%s hits exn: %s \n" s (Printexc.to_string ex)++let do_catch s f x =+  try f x with ex -> +     (Printf.printf "%s hits exn: %s \n" s (Printexc.to_string ex); raise ex) ++let do_catch_ret s f x y = +  try f x with ex -> +     (Printf.printf "%s hits exn: %s \n" s (Printexc.to_string ex); y) ++let do_memo memo f args key = +  try Hashtbl.find memo key with Not_found ->+    let rv = f args in+    let _ = Hashtbl.replace memo key rv in+    rv++let do_bimemo fmemo rmemo f args key =+  try Hashtbl.find fmemo key with Not_found ->+    let rv = f args in+    let _ = Hashtbl.replace fmemo key rv in+    let _ = Hashtbl.replace rmemo rv key in+    rv++let rec exists_maybe f = function+  | []    -> None+  | x::xs -> (match f x with None -> exists_maybe f xs | z -> z)++let map_pair   = fun f (x1, x2)     -> (f x1, f x2)+let map_triple = fun f (x1, x2, x3) -> (f x1, f x2, f x3)+let app_fst    = fun f (a, b)       -> (f a, b)+let app_snd    = fun f (a, b)       -> (a, f b)+let app_fst3   = fun f (a, b, c)    -> (f a, b, c)++let app_snd3   = fun f (a, b, c)    -> (a, f b, c)++let app_thd3   = fun f (a, b, c)    -> (a, b, f c)+let pad_snd    = fun f x            -> (x, f x)+let pad_fst    = fun f y            -> (f y, y)+let tmap2      = fun (f, g) x       -> (f x, g x)+let tmap3      = fun (f, g, h) x    -> (f x, g x, h x)+let iter_fst   = fun f (a, b)       -> f a+let iter_snd   = fun f (a, b)       -> f b++let split3 lst =+  List.fold_right (fun (x, y, z) (xs, ys, zs) -> (x :: xs, y :: ys, z :: zs)) lst ([], [], [])++let split4 lst =+  List.fold_right (fun (w, x, y, z) (ws, xs, ys, zs) -> (w :: ws, x :: xs, y :: ys, z :: zs)) lst ([], [], [], [])++let twrap s f x =+  let _  = Printf.printf "calling %s \n" s in+  let rv = f x in+  let _  = Printf.printf "returned from %s \n" s in+  rv++let mapfold_rev f b xs = +  List.fold_left begin fun (acc, ys) x -> +    let (acc', y) = f acc x in +    (acc', y::ys)+  end (b, []) xs++let mapfold f b xs =+  mapfold_rev f b xs +  |> app_snd List.rev ++let rootsBy leq xs = +  let notDomBy x = not <.> (leq x) in+  let rec loop acc = function+    | [] -> +        acc+    | (x::xs) ->+        let acc', xs' = map_pair (List.filter (notDomBy x)) (acc, xs) in+        loop (x::acc') xs'+  in loop [] xs++let cov_filter cov f xs = +  let rec loop acc = function+    | [] -> +        acc+    | (x::xs) when f x ->+        let covs, uncovs = List.partition (cov x) xs in+        loop ((x, covs) :: acc) uncovs  +    | (_::xs) ->+      loop acc xs+  in loop [] xs++let filter f xs = +  List.fold_left (fun xs' x -> if f x then x::xs' else xs') [] xs+  |> List.rev++let iter f xs = +  List.fold_left (fun () x -> f x) () xs++let map2 f xs ys = +  let _ = asserti (List.length xs = List.length ys) "Misc.map2" in+  List.map2 f xs ys++let map f xs = +  List.rev_map f xs |> List.rev++let flatten xss =+  xss+  |> List.fold_left (fun acc xs -> xs ++ acc) []+  |> List.rev++let flatsingles xss =+  xss |> List.fold_left (fun acc -> function [x] -> x::acc | _ -> assertf "flatsingles") []+      |> List.rev++let splitflatten xsyss = +  let xss, yss = List.split xsyss in+  (flatten xss, flatten yss)++let splitflatten3 xsyszss =+  let xss, yss, zss = split3 xsyszss in+    (flatten xss, flatten yss, flatten zss)++let flap f xs =+  xs |> List.rev_map f |> flatten |> List.rev++let flap_pair f = splitflatten <.> map f++let tr_rev_flatten xs =+  List.fold_left (fun x xs -> x ++ xs) [] xs++let tr_rev_flap f xs =+  List.fold_left (fun xs x -> (f x) ++ xs) [] xs++let rec fast_unflat ys = function+  | x :: xs -> fast_unflat ([x] :: ys) xs+  | [] -> ys++let dup x = (x, x)+++let rec rev_perms s = function+  | [] -> s+  | e :: es -> rev_perms +    (tr_rev_flap (fun e -> List.rev_map (fun s -> e :: s) s) e) es ++let product = function+  | e :: es -> rev_perms (fast_unflat [] e) es+  | es -> es ++let pairs xs =+  let rec pairs_aux ps = function+    | [] -> ps+    | x :: xs -> pairs_aux (List.fold_left (fun ps y -> (x, y) :: ps) ps xs) xs+  in pairs_aux [] xs++let cross_product xs ys = +  map begin fun x ->+    map begin fun y ->+      (x,y)+    end ys+  end xs+  |> flatten++let rec cross_flatten = function+  | []      -> +      [[]]+  | xs::xss ->+      map begin fun x ->+        map begin fun ys ->+          (x::ys)+        end (cross_flatten xss)+      end xs+      |> flatten+++let append_pref p s =+  (p ^ "." ^ s)+++let fsort f xs =+  let cmp = fun (k1,_) (k2,_) -> compare k1 k2 in+  xs |> map (fun x -> ((f x), x)) +     |> List.sort cmp +     |> map snd++let sort_and_compact ls =+  let rec _sorted_compact l = +    match l with+	h1::h2::tl ->+	  let rest = _sorted_compact (h2::tl) in+	    if h1 = h2 then rest else h1::rest+      | tl -> tl+  in+    _sorted_compact (List.sort compare ls)   ++let sort_and_compact xs = +  List.sort compare xs +  |> List.fold_left +       (fun ys x -> match ys with+        | y::_ when x=y -> ys+        | _::_          -> x::ys+        | []            -> [x])+       [] +  |> List.rev++let hashtbl_to_list t = +  Hashtbl.fold (fun x y l -> (x,y)::l) t []++let hashtbl_keys t = +  Hashtbl.fold (fun x y l -> x::l) t []+  |> sort_and_compact++let hashtbl_invert t = +  let t' = Hashtbl.create 17 in+  hashtbl_to_list t +  |> List.iter (fun (x,y) -> Hashtbl.replace t' y x) +  |> fun _ -> t'+++let distinct xs = + List.length xs = List.length (sort_and_compact xs)++(** repeats f: unit - > unit i times *)+let rec repeat_fn f i = +  if i = 0 then ()+  else (f (); repeat_fn f (i-1))++(* chop s chopper returns ([x;y;z...]) if s = x.chopper.y.chopper ...*)+let chop s chopper = Str.split (Str.regexp chopper) s  ++(* like chop only the chop is by chop+ *)+let chop_star chopper s = +    Str.split (Str.regexp (Printf.sprintf "[%s+]" chopper)) s++let bounded_chop s chopper i = Str.bounded_split (Str.regexp chopper) s i ++let is_prefix p s = +  let (ls, lp) = (String.length s, String.length p) in+  if ls < lp+    then false+  else+    (String.sub s 0 lp) = p++let is_substring s subs = +  let reg = Str.regexp subs in+  try ignore(Str.search_forward reg s 0); true+  with Not_found -> false++let replace_substring src dst s =+  Str.global_replace (Str.regexp src) dst s++let is_suffix suffix s = +  let k = String.length suffix+  and n = String.length s in+  (n-k >= 0) && Str.string_match (Str.regexp suffix) s (n-k)++let iteri f xs =+  List.fold_left (fun i x -> f i x; i+1) 0 xs+  |> ignore++let numbered_list xs =+  xs |> List.fold_left (fun (i, acc) x -> (i+1, (i,x)::acc)) (0,[]) +     |> snd +     |> List.rev ++exception FalseException++let sm_protected_add fail k v sm = +  if not (StringMap.mem k sm) then StringMap.add k v sm else +    if not fail then sm else +      assertf "protected_add: duplicate binding for %s \n" k++let hashtbl_to_list_all t = +  hashtbl_keys t |> map (Hashtbl.find_all t) ++let clone x n =+  let rec f n xs = if n <= 0 then xs else f (n-1) (x::xs) in+  f n []++let single x = [x]++let distinct xs = +  List.length (sort_and_compact xs) = List.length xs++let trunc i j = +  let (ai,aj) = (abs i, abs j) in+  if aj <= ai then j else ai*j/aj ++let map_to_string f xs = +  String.concat "," (List.map f xs)++let suffix_of_string = fun s i -> String.sub s i (String.length s - 1)++(* [count_map xs] = fun x -> number of times x appears in xs if non-zero *)+let count_map rs =+  List.fold_left begin fun m r -> +      let c = try IntMap.find r m with Not_found -> 0 in+      IntMap.add r (c+1) m+  end IntMap.empty rs++let o2s f = function+  | Some x -> "Some "^ (f x)+  | None   -> "None"++let fixpoint f x =+  let rec acf b x =+    let x', b' = f x in+    if b' then acf true x' else (x', b) in+  acf false x+++let fsprintf f p = +  Format.fprintf Format.str_formatter "@[%a@]" f p;+  Format.flush_str_formatter ()++let rec same_length l1 l2 = match l1, l2 with+  | [], []           -> true+  | _ :: xs, _ :: ys -> same_length xs ys+  | _                -> false++let ex_one s = function+  | [x]    -> x+  | _ :: _ -> failwith s+  | _      -> failwith (s ^ ". empty")++let only_one s = function+    x :: [] -> Some x+  | _ :: _  -> failwith s+  | []      -> None++let maybe_one = function+  | [x] -> Some x+  | _   -> None+++let int_of_bool b = if b then 1 else 0++(*****************************************************************)+(******************** Mem Management *****************************)+(*****************************************************************)++open Gc+(* open Format *)++let pprint_gc s =+  (*printf "@[Gc@ Stats:@]@.";+  printf "@[minor@ words:@ %f@]@." s.minor_words;+  printf "@[promoted@ words:@ %f@]@." s.promoted_words;+  printf "@[major@ words:@ %f@]@." s.major_words;*)+  (*printf "@[total allocated:@ %fMB@]@." (floor ((s.major_words +. s.minor_words -. s.promoted_words) *. (4.0) /. (1024.0 *. 1024.0)));*)++  Format.printf "@[total allocated:@ %fMB@]@." (floor ((allocated_bytes ()) /. (1024.0 *. 1024.0)));+  Format.printf "@[minor@ collections:@ %i@]@." s.minor_collections;+  Format.printf "@[major@ collections:@ %i@]@." s.major_collections;+  Format.printf "@[heap@ size:@ %iMB@]@." (s.heap_words * 4 / (1024 * 1024));+  (*printf "@[heap@ chunks:@ %i@]@." s.heap_chunks;+  (*printf "@[live@ words:@ %i@]@." s.live_words;+  printf "@[live@ blocks:@ %i@]@." s.live_blocks;+  printf "@[free@ words:@ %i@]@." s.free_words;+  printf "@[free@ blocks:@ %i@]@." s.free_blocks;+  printf "@[largest@ free:@ %i@]@." s.largest_free;+  printf "@[fragments:@ %i@]@." s.fragments;*)*)+  Format.printf "@[compactions:@ %i@]@." s.compactions;+  (*printf "@[top@ heap@ words:@ %i@]@." s.top_heap_words*) ()++let dump_gc s =+  Format.printf "@[%s@]@." s;+  pprint_gc (Gc.quick_stat ())+++let append_to_file f s = +  let oc = Unix.openfile f [Unix.O_WRONLY; Unix.O_APPEND; Unix.O_CREAT] 420  in+  ignore (Unix.write oc s 0 ((String.length s)-1) ); +  Unix.close oc++(*+let with_out_file file f =+  let oc = open_out file in+    f oc;+    close_out oc+*)++let display_tick = fun () -> print_now "."++let display_tick = +  let icona = [| "|"; "/" ; "-"; "\\" |] in+  let n     = ref 0                      in+  let pos   = ref 0                      in+  fun () -> +    let k   = !pos                       in+    let _   = pos := (k + 1) mod 4       in+    let _   = incr n                     in+    let suf = if (!n mod 76) = 0 +              then "\n" +              else icona.(k)             in+    let _   = print_now ("\b."^suf)      in+    ()++++let with_out_file file f = file |> open_out >> f |> close_out++let write_to_file f s =+  with_out_file f (fun oc -> output_string oc s)++let with_out_formatter file f =+  with_out_file file (fun oc -> f (Format.formatter_of_out_channel oc))++let get_unique =+  let cnt = ref 0 in+  (fun () -> let rv = !cnt in incr cnt; rv)++let lines_of_file filename = +  let lines = ref [] in+  let chan = open_in filename in+  try +    while true; do+      lines := input_line chan :: !lines+    done; [] +  with End_of_file ->+    close_in chan;+    List.rev !lines++let map_lines_of_file infile outfile f =+  let ic = open_in infile in+  let oc = open_out outfile in+  try+    while true; do+      ic |> input_line |> f |> output_string oc+    done;+  with End_of_file -> +    (close_in ic; close_out oc)++let maybe_cons m xs = match m with+  | None -> xs+  | Some x -> x :: xs++let maybe_list xs = +  List.fold_right maybe_cons xs []++let rec list_first_maybe f = function+  | x::xs -> begin match f x with +              | Some y -> Some y +              | _      -> list_first_maybe f xs+             end+  | []    -> None++let list_find_maybe f xs =+  try some <| List.find f xs with Not_found -> None++let list_assoc_maybe k kvs =+  try Some (List.assoc k kvs) with Not_found -> None++let list_assoc_default d kvs k =+  try List.assoc k kvs with Not_found -> d++let list_assoc_flip xs = +  let r (x, y) = (y, x) in+    List.map r xs++let fold_lefti f b xs =+  List.fold_left (fun (i,b) x -> ((i+1), f i b x)) (0,b) xs++let mapi f xs = +  xs |> fold_lefti (fun i acc x -> (f i x) :: acc) [] +     |> snd |> List.rev++let index_from n xs = +  let is = range n (n + List.length xs) in+  List.combine is xs++let fold_left_flip f b xs =+  List.fold_left (flip f) b xs++let fold_left_swap f xs b =+  List.fold_left f b xs++let rec map3 f xs ys zs = match (xs, ys, zs) with+  | ([], [], []) -> []+  | (x :: xs, y :: ys, z :: zs) -> f x y z :: map3 f xs ys zs+  | _ -> assert false++let rec fold_right3 f xs ys zs acc = match xs, ys, zs with+  | x :: xs, y :: ys, z :: zs -> f x y z (fold_right3 f xs ys zs acc)+  | [], [], []                -> acc+  | _                         -> assert false++let rec fold_left3 f acc xs ys zs = match xs, ys, zs with+  | x :: xs, y :: ys, z :: zs -> fold_left3 f (f acc x y z) xs ys zs+  | [], [], []                -> acc+  | _                         -> assert false++let zip_partition xs bs =+  let (xbs, xbs') = List.partition snd (List.combine xs bs) in+  (List.map fst xbs, List.map fst xbs')++let rec map4 f ws xs ys zs = match ws, xs, ys, zs with+  | [], [], [], []                     -> []+  | w :: ws, x :: xs, y :: ys, z :: zs -> f w x y z :: map4 f ws xs ys zs+  | _                                  -> asserti false "map4"; assert false+++let rec perms es =+  match es with+    | s :: [] ->+        List.map (fun c -> [c]) s+    | s :: es ->+        flap (fun c -> List.map (fun d -> c :: d) (perms es)) s+    | [] ->+        []++let flap2 f xs ys = +  List.flatten (List.map2 f xs ys)++let flap3 f xs ys zs =+  List.flatten (map3 f xs ys zs)++let combine msg xs ys =+  let _ = asserts (List.length xs = List.length ys) "%s" msg in+  List.combine xs ys++let combine3 xs ys zs =+  map3 (fun x y z -> (x, y, z)) xs ys zs++let combine4 ws xs ys zs =+  map4 (fun w x y z -> (w, x, y, z)) ws xs ys zs++let tr_partition f xs =+  List.fold_left begin fun (xs,ys) z -> +    if f z +    then (z::xs, ys) +    else (xs, z::ys)+  end ([],[]) xs++let either_partition f xs =+  List.fold_left begin fun (xs, ys) z -> +    match f z with+    | Left x  -> (x::xs, ys)+    | Right y -> (xs, y::ys)+  end ([], []) xs++(* these do odd things with order for performance + * it is possible that fast is a misnomer *)+let fast_flatten xs =+  List.fold_left (++) [] xs++let fast_append v v' =+  let (v, v') = if List.length v > List.length v' then (v', v) else (v, v') in+  List.rev_append v v'++let fast_flap f xs =+  List.fold_left (fun xs x -> List.rev_append (f x) xs) [] xs++let rec fast_unflat ys = function+  | x :: xs -> fast_unflat ([x] :: ys) xs+  | [] -> ys++let rec rev_perms s = function+  | [] -> s+  | e :: es -> rev_perms +    (fast_flap (fun e -> List.rev_map (fun s -> e :: s) s) e) es ++let rev_perms = function+  | e :: es -> rev_perms (fast_unflat [] e) es+  | es -> es ++let tflap2 (e1, e2) f =+  List.fold_left (fun bs b -> List.fold_left (fun aas a -> f a b :: aas) bs e1) [] e2++let tflap3 (e1, e2, e3) f =+  List.fold_left begin fun cs c -> +    List.fold_left begin fun bs b -> +      List.fold_left begin fun aas a -> +        f a b c :: aas+      end bs e1+    end cs e2+  end[] e3++let rec expand f xs ys =+  match xs with+  | []    -> ys+  | x::xs -> let (xs', ys') = f x in+             expand f (xs' ++  xs) (ys' ++ ys)++let rec get_first f = function+  | x::xs when f x -> Some x +  | _::xs          -> get_first f xs+  | []             -> None++let join f xs ys = +  let rec fuse acc xs ys = +    match xs, ys with +    | [],_ | _, []                              -> List.rev acc+    | ((kx, _)::xs', (ky,_)::_  ) when kx < ky  -> fuse acc xs' ys+    | ((kx, _)::_  , (ky,_)::ys') when kx > ky  -> fuse acc xs  ys' +    | ((kx, x)::xs', (ky,y)::ys') (* kx = ky *) -> fuse ((x,y)::acc) xs' ys' in+  let xs' = List.map (fun x -> (f x, x)) xs |> List.sort compare in+  let ys' = List.map (fun y -> (f y, y)) ys |> List.sort compare in+  fuse [] xs' ys'++let hashtbl_find_default d t x =+  try Hashtbl.find t x with Not_found -> d++let frequency (xs : 'a list) : ('a * int) list = +  let t = Hashtbl.create 17 in+  List.iter begin fun x ->+    let n =  hashtbl_find_default 0 t x in+    Hashtbl.replace t x (n + 1)+  end xs;+  hashtbl_to_list t++let kgroupby (f: 'a -> 'b) (xs: 'a list): ('b * 'a list) list =+  let t        = Hashtbl.create 17 in+  let lookup x = try Hashtbl.find t x with Not_found -> [] in+  (* build table *)+  List.iter begin fun x -> +    Hashtbl.replace t (f x) (x :: lookup (f x))+  end xs;+  (* build cluster *)+  Hashtbl.fold (fun k xs xxs -> (k, xs) :: xxs) t []++++let groupby (f: 'a -> 'b) (xs: 'a list): 'a list list =+  kgroupby f xs |> List.map (snd <+> List.rev)++let full_join f xs ys =+     (xs, ys)+  |> map_pair (kgroupby f)+  |> uncurry (join fst)+  |> flap (map_pair snd <+> uncurry cross_product)++let exists_pair (f: 'a -> 'a -> bool) (xs: 'a list): bool =+  fst (List.fold_left (fun (b, ys) x -> (b || List.exists (f x) ys, x :: ys)) (false, []) xs)++let rec find_pair (f: 'a -> 'a -> bool): 'a list -> 'a * 'a = function+  | []    -> raise Not_found+  | x::xs -> try (x, List.find (f x) xs) with Not_found -> find_pair f xs++let rec is_unique = function+  | []      -> true+  | x :: xs -> if List.mem x xs then false else is_unique xs++let map_opt f = function+  | Some o -> Some (f o)+  | None -> None++let resl_opt f = function+  | Some o -> f o+  | None -> []++let resi_opt f = function+  | Some o -> f o+  | None -> ()++let opt_iter f l = +  List.iter (resi_opt f) l++let array_findi p arr =+  let rec look i =+    if i < 0 then raise Not_found else+      if p arr.(i) then i else look i - 1+  in look (Array.length arr - 1)++let array_to_index_list a =+  Array.fold_left (fun (i, rv) v -> (i+1,(i,v)::rv)) (0,[]) a+  |> snd+  |> List.rev+++let hashtbl_of_list xys = +  let t = Hashtbl.create 37 in+  let _ = List.iter (fun (x,y) -> Hashtbl.add t x y) xys in+  t++let hashtbl_of_list_with kf xs = +  xs |>: pad_fst kf |> hashtbl_of_list++let array_flapi f a =+  Array.fold_left (fun (i, acc) x -> (i+1, (f i x) :: acc)) (0,[]) a+  |> snd +  |> List.rev+  |> flatten++let array_fold_lefti f acc a =+  Array.fold_left (fun (i, acc) x -> (i + 1, f i acc x)) (0, acc) a |> snd++let array_map2 f xa ya = +  Array.mapi (fun i x -> f x (ya.(i))) xa++let array_rev_iteri f a =+  for i = Array.length a - 1 downto 0 do+    f i a.(i)+  done++exception NotForall++let array_forall f a =+  try+    Array.iter (fun e -> if f e then () else raise NotForall) a; true+  with NotForall ->+    false++let array_combine a1 a2 = +  asserts (Array.length a1 = Array.length a2) "array_combine";+  Array.init (Array.length a1) (fun i -> (a1.(i), a2.(i)))+++let compose f g a = f (g a)+++let rec gcd (a: int) (b: int): int =+  if b = 0 then a else gcd b (a mod b)++let lcm (a: int) (b: int): int =+  if a = 0 then a else (abs (a * b)) / (gcd a b)++let mk_int_factory () =+  let id = ref (-1) in+    ((fun () -> incr id; !id), (fun () -> id := -1))++let mk_char_factory () =+  let (fresh_int, reset_fresh_int) = mk_int_factory () in+    ((fun () -> Char.chr (fresh_int () + Char.code 'a')), reset_fresh_int)++let mk_string_factory s =+  let (fresh_int, reset_fresh_int) = mk_int_factory () in+    ((fun () -> s^(string_of_int (fresh_int ()))), reset_fresh_int)++let swap (x,y) = (y,x)++(* ('a * (int * 'b) list) list -> (int * ('a * 'b) list) list *)+let transpose x_iys_s = +  let t = Hashtbl.create 17 in+  List.iter begin fun (x, iys) ->+    List.iter begin fun (i, y) -> +      Hashtbl.add t i (x,y) +    end iys+  end x_iys_s; +  hashtbl_keys t |> List.map (fun i -> (i, Hashtbl.find_all t i))++let basename_no_extension fname =+  fname |> Filename.basename |> Filename.chop_extension++let absolute_name name =+  if not (Filename.is_relative name) then name else+    let b    = Filename.basename name in+    let d    = Filename.dirname name in+    let dir  = Sys.getcwd () in+    let _    = Sys.chdir (Filename.concat dir d) in+    let dir' = Sys.getcwd () in+    let rv   = Filename.concat dir' b in+    let _    = Sys.chdir dir in+    rv++let cardinality = fun xs -> xs |> sort_and_compact |> List.length+let disjoint    = fun xs ys -> cardinality xs + cardinality ys = cardinality (xs ++ ys)++let bracket (l : unit -> unit) (r : unit -> unit) (f : unit -> 'a) : 'a = +  try l () |> f >> (fun _ -> r ())+  with ex -> assertf "bracket hits exn: %s \n" (Printexc.to_string ex)++(*+let with_ref_at x v f =+  let oldv  = !x in +  bracket (fun _ -> x := v) (fun _ -> x := oldv) f +*)++let with_ref_at x v f = +  let oldv = !x        in +  let _    = x := v    in+  let res  = f ()      in+  let _    = x := oldv in+  res++++let rec isPrefix = function+  | ([], _)                   -> true+  | (x::xs, y::ys) when x = y -> isPrefix (xs, ys)+  | _                         -> false++let find_first_true f lo hi =+  let rec go lo hi = +    let mid = lo + ((hi - lo) / 2) in+    match () with+    | _ when lo >= hi    -> None+    | _ when lo = hi - 1 -> Some hi +    | _ when f mid       -> go lo mid +    | _                  -> go mid hi +  in   if f lo then Some lo +  else if not (f hi) then None +  else go lo hi++let safeHead msg = function+  | [x] -> x+  | _   -> failwith ("ERROR: safeHead" ^ msg) ++let safeApply pp f x = match f x with+  | Some y -> y+  | None   -> failwith ("ERROR: safeApply " ^ (pp x)) ++let stringIsUpper = function+  | "" -> false+  | s  -> let c = s.[0] in c = Char.uppercase c++let stringIsLower = function+  | "" -> false+  | s  -> let c = s.[0] in c = Char.lowercase c+++
+ external/misc/heaps.ml view
@@ -0,0 +1,223 @@+(**************************************************************************)+(*                                                                        *)+(*  Copyright (C) Jean-Christophe Filliatre                               *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*s Heaps *)++module type Ordered = sig+  type t+  val compare : t -> t -> int+end++exception EmptyHeap++(*s Imperative implementation *)++module Imperative(X : Ordered) = struct++  (* The heap is encoded in the array [data], where elements are stored+     from [0] to [size - 1]. From an element stored at [i], the left +     (resp. right) subtree, if any, is rooted at [2*i+1] (resp. [2*i+2]). *)++  type t = { mutable size : int; mutable data : X.t array }++  (* When [create n] is called, we cannot allocate the array, since there is+     no known value of type [X.t]; we'll wait for the first addition to +     do it, and we remember this situation with a negative size. *)++  let create n = +    if n <= 0 then invalid_arg "create";+    { size = -n; data = [||] }++  let is_empty h = h.size <= 0++  (* [resize] doubles the size of [data] *)++  let resize h =+    let n = h.size in+    assert (n > 0);+    let n' = 2 * n in+    let d = h.data in+    let d' = Array.create n' d.(0) in+    Array.blit d 0 d' 0 n;+    h.data <- d'++  let add h x =+    (* first addition: we allocate the array *)+    if h.size < 0 then begin+      h.data <- Array.create (- h.size) x; h.size <- 0+    end;+    let n = h.size in+    (* resizing if needed *)+    if n == Array.length h.data then resize h;+    let d = h.data in+    (* moving [x] up in the heap *)+    let rec moveup i =+      let fi = (i - 1) / 2 in+      if i > 0 && X.compare d.(fi) x < 0 then begin+	d.(i) <- d.(fi);+	moveup fi+      end else+	d.(i) <- x+    in+    moveup n;+    h.size <- n + 1++  let maximum h =+    if h.size <= 0 then raise EmptyHeap;+    h.data.(0)++  let remove h =+    if h.size <= 0 then raise EmptyHeap;+    let n = h.size - 1 in+    h.size <- n;+    let d = h.data in+    let x = d.(n) in+    (* moving [x] down in the heap *)+    let rec movedown i =+      let j = 2 * i + 1 in+      if j < n then+	let j = +	  let j' = j + 1 in +	  if j' < n && X.compare d.(j') d.(j) > 0 then j' else j +	in+	if X.compare d.(j) x > 0 then begin +	  d.(i) <- d.(j); +	  movedown j +	end else+	  d.(i) <- x+      else+	d.(i) <- x+    in+    movedown 0++  let pop_maximum h = let m = maximum h in remove h; m++  let iter f h = +    let d = h.data in+    for i = 0 to h.size - 1 do f d.(i) done++  let fold f h x0 =+    let n = h.size in+    let d = h.data in+    let rec foldrec x i =+      if i >= n then x else foldrec (f d.(i) x) (succ i)+    in+    foldrec x0 0++end+++(*s Functional implementation *)++module type FunctionalSig = sig+  type elt+  type t+  val empty : t+  val add : elt -> t -> t+  val maximum : t -> elt+  val remove : t -> t+  val iter : (elt -> unit) -> t -> unit+  val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a+end++module Functional(X : Ordered) = struct++  (* Heaps are encoded as complete binary trees, i.e., binary trees+     which are full expect, may be, on the bottom level. +     These trees also enjoy the heap property, namely the value of any node +     is greater or equal than those of its left and right subtrees.++     The representation invariant is the following: the number of nodes in+     the left subtree is equal to the number of nodes in the right+     subtree, or exceeds it by exactly once. In the first case, we use+     the constructor [Same] and in the second the constructor [Diff].+     Then it can be proved that [2^(h-1) <= n <= 2^h] when [n] is the+     number of elements and [h] the height of the tree. *)++  type elt = X.t++  type t = +    | Empty+    | Same of t * X.t * t (* same number of elements on both sides *)+    | Diff of t * X.t * t (* left has [n+1] nodes and right has [n] *)++  let empty = Empty+ +  let rec add x = function+    | Empty -> +	Same (Empty, x, Empty)+    (* insertion to the left *)+    | Same (l, y, r) ->+	if X.compare x y > 0 then Diff (add y l, x, r) else Diff (add x l, y,r)+    (* insertion to the right *)+    | Diff (l, y, r) ->+	if X.compare x y > 0 then Same (l, x, add y r) else Same (l,y, add x r)++  let maximum = function+    | Empty -> raise EmptyHeap+    | Same (_, x, _) | Diff (_, x, _) -> x++  (* extracts one element on the bottom level of the tree, while+     maintaining the representation invariant *)+  let rec extract_last = function+    | Empty -> raise EmptyHeap+    | Same (Empty, x, Empty) -> x, Empty+    | Same (l, x, r) -> let y,r' = extract_last r in y, Diff (l, x, r')+    | Diff (l, x, r) -> let y,l' = extract_last l in y, Same (l', x, r)++  (* removes the topmost element of the tree and inserts a new element [x] *)+  let rec descent x = function+    | Empty -> +	assert false+    | Same (Empty, _, Empty) -> +	Same (Empty, x, Empty)+    | Diff (Same (_, z, _) as l, _, Empty) -> +	if X.compare x z > 0 then Diff (l, x, Empty) +	else Diff (Same (Empty, x, Empty), z, Empty)+    | Same (l, _, r) ->+	let ml = maximum l in+	let mr = maximum r in+	if X.compare x ml > 0 && X.compare x mr > 0 then +	  Same (l, x, r)+	else +	  if X.compare ml mr > 0 then+	    Same (descent x l, ml, r)+	  else +	    Same (l, mr, descent x r)+    | Diff (l, _, r) ->+	let ml = maximum l in+	let mr = maximum r in+	if X.compare x ml > 0 && X.compare x mr > 0 then +	  Diff (l, x, r)+	else +	  if X.compare ml mr > 0 then+	    Diff (descent x l, ml, r)+	  else +	    Diff (l, mr, descent x r)++  let remove = function+    | Empty -> raise EmptyHeap+    | Same (Empty, x, Empty) -> Empty+    | h -> let y,h' = extract_last h in descent y h'++  let rec iter f = function+    | Empty -> ()+    | Same (l, x, r) | Diff (l, x, r) -> iter f l; f x; iter f r++  let rec fold f h x0 = match h with+    | Empty -> x0+    | Same (l, x, r) | Diff (l, x, r) -> fold f l (fold f r (f x x0))++end
+ external/misc/heaps.mli view
@@ -0,0 +1,98 @@+(**************************************************************************)+(*                                                                        *)+(*  Copyright (C) Jean-Christophe Filliatre                               *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* Heaps *)++module type Ordered = sig+  type t+  val compare : t -> t -> int+end++exception EmptyHeap++(*S Imperative implementation. *)++module Imperative(X: Ordered) : sig++  (* Type of imperative heaps.+     (In the following [n] refers to the number of elements in the heap) *)++  type t ++  (* [create c] creates a new heap, with initial capacity of [c] *)+  val create : int -> t++  (* [is_empty h] checks the emptiness of [h] *)+  val is_empty : t -> bool++  (* [add x h] adds a new element [x] in heap [h]; size of [h] is doubled+     when maximum capacity is reached; complexity $O(log(n))$ *)+  val add : t -> X.t -> unit++  (* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(1)$ *)+  val maximum : t -> X.t++  (* [remove h] removes the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(log(n))$ *)+  val remove : t -> unit++  (* [pop_maximum h] removes the maximum element of [h] and returns it;+     raises [EmptyHeap] when [h] is empty; complexity $O(log(n))$ *)+  val pop_maximum : t -> X.t++  (* usual iterators and combinators; elements are presented in+     arbitrary order *)+  val iter : (X.t -> unit) -> t -> unit++  val fold : (X.t -> 'a -> 'a) -> t -> 'a -> 'a++end++(*S Functional implementation. *)++module type FunctionalSig = sig++  (* heap elements *)+  type elt++  (* Type of functional heaps *)+  type t++  (* The empty heap *)+  val empty : t++  (* [add x h] returns a new heap containing the elements of [h], plus [x];+     complexity $O(log(n))$ *)+  val add : elt -> t -> t++  (* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(1)$ *)+  val maximum : t -> elt++  (* [remove h] returns a new heap containing the elements of [h], except+     the maximum of [h]; raises [EmptyHeap] when [h] is empty; +     complexity $O(log(n))$ *) +  val remove : t -> t++  (* usual iterators and combinators; elements are presented in+     arbitrary order *)+  val iter : (elt -> unit) -> t -> unit++  val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a++end++module Functional(X: Ordered) : FunctionalSig with type elt = X.t
+ external/misc/misc.ml view
@@ -0,0 +1,1346 @@+(*+ * Copyright ? 1990-2007 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.+ *+ *)++(* $Id: misc.ml,v 1.14 2006/09/26 01:47:01 jhala Exp $+ *+ * This file is part of the SIMPLE Project.+ *)++(**+ * This module provides some miscellaneous useful helper functions.+ *)++module Ops = struct++  type ('a, 'b) either = Left of 'a | Right of 'b++  let (>|) _ x = x++  let (|>) x f = f x++  let (<|) f x = f x++  let (>>) x f = f x; x++  let (|>>) xo f = match xo with None -> None | Some x -> f x++  let (|>:) xs f = List.map f xs++  let (=+) x n = let v = !x in (x := v + n; v)++  let (+=) x n = x := !x + n; !x++  let (++) = List.rev_append++  let (+++)= fun (x1s, y1s) (x2s, y2s) -> (x1s ++ x2s, y1s ++ y2s)++  let id = fun x -> x++  let un = fun x -> ()++  let const x = fun _ -> x++  let (<.>) f g  = fun x -> x |> g |> f++  let (<+>) f g  = fun x -> x |> f |> g ++  let (<?>) b f  = fun x -> if b then f x else x++  let wwhen b f  = fun x -> if b then f x ++  let (<*>) f g  = fun x -> (f x, g x)+  +  let (<**>) f g = fun (x, y) -> (f x, g y)++  let (<&&>) f g = fun x -> f x && g x++  let failure fmt = Printf.ksprintf failwith fmt++  let foreach xs f = List.map f xs++  let asserts p fmt =+    Printf.ksprintf (fun x -> if not p then failwith x) fmt++let asserti = asserts+  (*+let asserti p fmt = +  Printf.ksprintf (fun x -> if not p then (print_string (x^"\n"); ignore(0/0)) else ()) fmt+*)++let assertf fmt =+  Printf.ksprintf failwith fmt++let halt _ =+  assert false++let fst3 (x,_,_) = x+let snd3 (_,x,_) = x+let thd3 (_,_,x) = x++let fst4 (x, _, _, _) = x+let snd4 (_, x, _, _) = x+let thd4 (_, _, x, _) = x+let fth4 (_, _, _, x) = x++let withfst3 (_,y,z) x = (x,y,z)+let withsnd3 (x,_,z) y = (x,y,z)+let withthd3 (x,y,_) z = (x,y,z)++let print_now s = +  print_string s;+  flush stdout++let print_now_error msg =+  prerr_string msg;+  flush stderr++let output_now c s = +  output_string c s; +  flush c++let some = fun x -> Some x++end++open Ops++let maybe_fold f b xs = +  let fo = fun bo x -> match bo with Some b -> f b x | _ -> None in+  List.fold_left fo (Some b) xs++let maybe_map f = function Some x -> Some (f x) | None -> None++let maybe_iter f = function Some x -> f x | None -> ()++let maybe = function Some x -> x | _ -> assertf "maybe called with None"++let maybe_apply f xo v = match xo with Some x -> f x v | None -> v++let maybe_default xo y = match xo with Some x -> x | None -> y++let maybe_string f = function Some x -> "Some " ^ (f x) | None -> "None"++let rec maybe_chain x d = function +  | f::fs -> (match f x with +              | Some y -> y +              | None -> maybe_chain x d fs)+  | []    -> d++++++let trace s f x =+  let _ = print_now <| Printf.sprintf "BEGIN: %s \n" s in+  let r = f x in+  let _ = print_now <| Printf.sprintf "END: %s \n" s   in+  r++(* ORIG+let rec pprint_many_box s f ppf = function+  | []     -> ()+  | x::[]  -> Format.fprintf ppf "%a" f x+  | x::xs' -> (Format.fprintf ppf "%a%s@\n" f x s; pprint_many_box s f ppf xs')+*)+let rec pprint_many_prefix sep base f ppf = function+  | x::xs -> Format.fprintf ppf "(%s %a %a)" +               sep f x (pprint_many_prefix sep base f) xs+  | []    -> Format.fprintf ppf "%a" f base+++let rec pprint_many_box brk s f ppf = function+  | []              -> ()+  | [x]             -> Format.fprintf ppf "%a" f x+  | x::xs' when brk -> Format.fprintf ppf "%a@\n%s" f x s; +                       pprint_many_box brk s f ppf xs'+  | x::xs'          -> Format.fprintf ppf "%a@,%s" f x s;+                       pprint_many_box brk s f ppf xs'++let pprint_many_box brk l s r f ppf = function+  | []     -> Format.fprintf ppf "[]"+  | xs     -> Format.fprintf ppf "@[%s%a%s@]" l (pprint_many_box brk s f) xs r++let pprint_many_brackets brk f ppf x = +  Format.fprintf ppf "%a" (pprint_many_box brk "[ " "; " "]" f) x++let rec pprint_many brk s f ppf = function+  | []              -> ()+  | [x]             -> Format.fprintf ppf "%a" f x+  | x::xs' when brk -> Format.fprintf ppf "%a%s@," f x s; pprint_many brk s f ppf xs'+  | x::xs'          -> Format.fprintf ppf "%a%s" f x s ; pprint_many brk s f ppf xs'++let pprint_maybe f ppf = function+  | Some x -> Format.fprintf ppf "Some %a" f x+  | None   -> Format.fprintf ppf "None"++let pprint_int ppf i =+  Format.fprintf ppf "%d" i++let pprint_int_o = pprint_maybe pprint_int+(*+let pprint_int_o ppf = function+  | None -> Format.fprintf ppf "None" +  | Some d -> Format.fprintf ppf "Some(%d)" d+*)++let pprint_str ppf s =+  Format.fprintf ppf "%s" s++let pprint_ints ppf is = +  pprint_many_brackets false (fun ppf i -> Format.fprintf ppf "%d" i) ppf is++let pprint_pretty_ints ppf is = +  is |> List.map string_of_int |> String.concat ";" |> Format.fprintf ppf "[%s]"++let pprint_tuple pp1 pp2 ppf (x1, x2) = +  Format.fprintf ppf "(%a, %a)" pp1 x1 pp2 x2++let rec subsets n = function+  | _ when n <= 0 +    -> [[]]+  | xs when n > List.length xs->+      []+  | x::xs +    -> (List.map (fun ys -> x :: ys) (subsets (n-1) xs))+    ++ (subsets n xs)+  | _ -> assertf "Misc.subsets"++let choose b f g = if b then f else g++let liftfst2 (f: 'a -> 'a -> 'b) (x: 'a * 'c) (y: 'a * 'c): 'b =+  f (fst x) (fst y)++let curry   = fun f x y   -> f (x,y)+let uncurry = fun f (x,y) -> f x y+let flip    = fun f x y   -> f y x++let maybe_bool = function+  | Some _ -> true+  | None   -> false++module type EMapType = sig+  include Map.S+  val extendWith   : (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t+  val extend       : 'a t -> 'a t -> 'a t+  val filter       : (key -> 'a -> bool) -> 'a t -> 'a t+  val of_list      : (key * 'a) list -> 'a t+  val to_list      : 'a t -> (key * 'a) list+  val length       : 'a t -> int+  val domain       : 'a t -> key list+  val range        : 'a t -> 'a list+  val join         : 'a t -> 'b t -> ('a * 'b) t+  val adds         : key -> 'a list -> 'a list t -> 'a list t+  val of_alist     : (key * 'a) list -> 'a list t+  val finds        : key -> 'a list t -> 'a list+  val safeFind     : key -> 'a t -> string -> 'a+  val safeAdd      : key -> 'a -> 'a t -> string -> 'a t+  val single       : key -> 'a -> 'a t+  val map_partial  : ('a -> 'b option) -> 'a t -> 'b t+  val maybe_find   : key -> 'a t -> 'a option+  val find_default : 'a -> key -> 'a t -> 'a+  val frequency    : key list -> int t+end++module type ESetType = sig+  include Set.S+  val of_list : elt list -> t+end++module ESet (K: Set.OrderedType) = +  struct+    include Set.Make(K)+    let of_list = List.fold_left (flip add) empty  +end++module type EOrderedType = sig+  include Map.OrderedType +  val print : Format.formatter -> t -> unit+end++(* module EMap (K: Map.OrderedType) = *) +module EMap (K: EOrderedType) = +  struct+    include Map.Make(K)++    let extendWith (f: key -> 'a -> 'a -> 'a) (m1: 'a t) (m2: 'a t) =+      fold begin fun k v m -> +        let v' = if mem k m then f k v (find k m) else v in+        add k v' m+      end m2 m1 +    +    let extend (m1: 'a t)  (m2: 'a t) : 'a t = fold add m2 m1++    (* in 3.12 *)+    let filter (f: key -> 'a -> bool) (m: 'a t) : 'a t =  +      fold (fun x y m -> if f x y then add x y m else m) m empty +    +    let of_list (kvs : (key * 'a) list) = +      List.fold_left (fun m (k, v) -> add k v m) empty kvs++        (* in 3.12 -- bindings *)+    let to_list (m : 'a t) : (key * 'a) list = +      fold (fun k v acc -> (k,v)::acc) m [] ++    (* in 3.12 -- cardinality *)+    let length (m : 'a t) : int = +      fold (fun _ _ i -> i+1) m 0++    (* in 3.12 -- singleton *)+    let single k v = add k v empty++    let domain m =+      fold (fun k _ acc -> k :: acc) m []++    let range (m : 'a t) : 'a list = +      fold (fun _ v acc -> v :: acc) m []+     +    let join (m1 : 'a t) (m2 : 'b t) : ('a * 'b) t =+      mapi begin fun k v1 ->+        let _  = asserts (mem k m2) "EMap.join" in+        (v1, find k m2) +      end m1++    let maybe_find k m = +      try Some (find k m) with Not_found -> None++    let find_default d k m = +      maybe_default (maybe_find k m) d ++    (* let finds k m = try find k m with Not_found -> [] *)+    let finds k m = find_default [] k m++    let adds (k: key) (vs: 'a list) (m : ('a list) t) : 'a list t = +      add k (vs ++ find_default [] k m) m++    let of_alist (kvs : (key * 'a) list) =+      List.fold_left (fun m (k, v) -> adds k [v] m) empty kvs+     +    let frequency (ks : key list) : int t =+      List.fold_left (fun m k -> +        add k (1 + (find_default 0 k m)) m+      ) empty ks ++    let safeFind k m msg =+      try find k m with Not_found -> +        let err = Format.fprintf Format.str_formatter +                    "ERROR: safeFind (%s): %a" msg K.print k; +                  Format.flush_str_formatter ()+        in failwith err++    let safeAdd k v m msg =+      if mem k m then +        let err = Format.fprintf Format.str_formatter +                    "ERROR: safeAdd (%s): %a" msg K.print k; +                  Format.flush_str_formatter ()+        in failwith err+      else add k v m++    let map_partial f m = +      fold (fun x yo m -> match yo with Some y -> add x y m | _ -> m) (map f m) empty +  end++module type KeyValType =+  sig+    type t+    val compare : t -> t -> int+    val print : Format.formatter -> t -> unit ++    type v+    val default : v+  end++module MapWithDefault (K: KeyValType) =+  struct+    include EMap(K)+    let find (i: K.t) (m: K.v t): K.v =+      try find i m with Not_found -> K.default+  end++module IntMap = +  EMap+  (struct+    type t = int+    let compare i1 i2 = compare i1 i2+    let print         = pprint_int+  end)++module IntSet =+  ESet+  (struct+    type t = int+    let compare i1 i2 =+      compare i1 i2+  end)++module IntIntMap = +  EMap +  (struct+    type t = int * int+    let compare i1 i2 = compare i1 i2+    let print ppf (i1, i2) = Format.fprintf ppf "(%d, %d)" i1 i2+   end)++module StringMap = +  EMap +  (struct+    type t = string +    let compare i1 i2 = compare i1 i2+    let print ppf s   = Format.fprintf ppf "%s" s+  end)++module StringSet =+  ESet+  (struct+    type t = string+    let compare i1 i2 = compare i1 i2+  end)++(* +let sm_join sm1 sm2 = +  StringMap.mapi (fun k v1 ->+    let v2 = asserts (StringMap.mem k sm2) "sm_join"; StringMap.find k sm2 in+    (v1, v2)+  ) sm1++let sm_extend sm1 sm2 =+  StringMap.fold StringMap.add sm2 sm1 ++let sm_filter f sm = +  StringMap.fold begin fun x y sm -> +    if f x y then StringMap.add x y sm else sm +  end sm StringMap.empty ++let sm_of_list kvs = +  List.fold_left (fun sm (k,v) -> StringMap.add k v sm) StringMap.empty kvs++let sm_to_list sm = +  StringMap.fold (fun k v acc -> (k,v)::acc) sm [] ++let sm_to_range sm = +  sm |> sm_to_list |> List.map snd+*)++let sm_print_keys name sm =+  sm |> StringMap.to_list +     |> List.map fst +     |> String.concat ", "+     |> Printf.printf "%s : %s \n" name++let foldn f n b = +  let rec foo acc i = +    if i >= n then acc else foo (f acc i) (i+1) +  in foo b 0 ++let rec range i j = +  if i >= j then [] else i::(range (i+1) j)++let dump s = +  print_string s; flush stdout++let mapn f n = +  foldn (fun acc i -> (f i) :: acc) n [] +  |> List.rev++let chop_last = function+  | [] -> failure "ERROR: Misc.chop_last"+  | xs -> xs |> List.rev |> List.tl |> List.rev++let list_snoc xs = +  match List.rev xs with +  | [] -> assertf "list_snoc with empty list!"+  | h::t  -> h, List.rev t++let negfilter f xs = +  List.fold_left (fun acc x -> if f x then acc else x::acc) [] xs +  |> List.rev++let get_option d = function  +  | Some x -> x +  | None   -> d++let list_somes xs =+  xs |> List.fold_left begin fun acc -> function +          | Some x -> x :: acc +          | None   -> acc +        end []+     |> List.rev++(* let map_partial f = list_somes <.> List.map f  *)++let map_partial f xs =+  List.rev +    (List.fold_left +      (fun acc x -> +        match f x with+        | None   -> acc+        | Some z -> (z::acc)) [] xs)+++let fold_left_partial f b xs =+  List.fold_left begin fun b xo ->+    match xo with+      | Some x -> f b x+      | None   -> b+  end b xs++let list_reduce msg f = function+  | []    -> assertf "ERROR: list_reduce with empty list: %s" msg +  | x::xs -> List.fold_left f x xs++let nonnull = function+  | [] -> false+  | _  -> true++(*+let list_is_empty = function+  | [] -> true+  | _::_ -> false+*)++let list_max x xs = +  List.fold_left max x xs++let list_min x xs = +  List.fold_left min x xs++let list_max_with msg f = function+  | []    -> assertf "ERROR: list_max_with with empty list: %s" msg +  | x::xs -> List.fold_left (fun acc x -> if f x > f acc then x else acc) x xs++let rec take_max n = function+  | x :: xs when n > 0 -> x :: take_max (n - 1) xs+  | _                  -> []+    +let rec drop n = function+  | x :: xs when n > 0 -> drop (n - 1) xs+  | []      when n > 0 -> assertf "ERROR: dropped too many"+  | xs -> xs++let getf a i fmt = +  try a.(i) with ex -> assertf fmt++let do_catchu f x g =+  try f x with ex -> (g ex; raise ex)++let do_catchf s f x =+  try f x with ex -> +    assertf "%s hits exn: %s \n" s (Printexc.to_string ex)++let do_catch s f x =+  try f x with ex -> +     (Printf.printf "%s hits exn: %s \n" s (Printexc.to_string ex); raise ex) ++let do_catch_ret s f x y = +  try f x with ex -> +     (Printf.printf "%s hits exn: %s \n" s (Printexc.to_string ex); y) ++let do_memo memo f args key = +  try Hashtbl.find memo key with Not_found ->+    let rv = f args in+    let _ = Hashtbl.replace memo key rv in+    rv++let do_bimemo fmemo rmemo f args key =+  try Hashtbl.find fmemo key with Not_found ->+    let rv = f args in+    let _ = Hashtbl.replace fmemo key rv in+    let _ = Hashtbl.replace rmemo rv key in+    rv++let rec exists_maybe f = function+  | []    -> None+  | x::xs -> (match f x with None -> exists_maybe f xs | z -> z)++let map_pair   = fun f (x1, x2)     -> (f x1, f x2)+let map_triple = fun f (x1, x2, x3) -> (f x1, f x2, f x3)+let app_fst    = fun f (a, b)       -> (f a, b)+let app_snd    = fun f (a, b)       -> (a, f b)+let app_fst3   = fun f (a, b, c)    -> (f a, b, c)++let app_snd3   = fun f (a, b, c)    -> (a, f b, c)++let app_thd3   = fun f (a, b, c)    -> (a, b, f c)+let pad_snd    = fun f x            -> (x, f x)+let pad_fst    = fun f y            -> (f y, y)+let tmap2      = fun (f, g) x       -> (f x, g x)+let tmap3      = fun (f, g, h) x    -> (f x, g x, h x)+let iter_fst   = fun f (a, b)       -> f a+let iter_snd   = fun f (a, b)       -> f b++let split3 lst =+  List.fold_right (fun (x, y, z) (xs, ys, zs) -> (x :: xs, y :: ys, z :: zs)) lst ([], [], [])++let split4 lst =+  List.fold_right (fun (w, x, y, z) (ws, xs, ys, zs) -> (w :: ws, x :: xs, y :: ys, z :: zs)) lst ([], [], [], [])++let twrap s f x =+  let _  = Printf.printf "calling %s \n" s in+  let rv = f x in+  let _  = Printf.printf "returned from %s \n" s in+  rv++let mapfold_rev f b xs = +  List.fold_left begin fun (acc, ys) x -> +    let (acc', y) = f acc x in +    (acc', y::ys)+  end (b, []) xs++let mapfold f b xs =+  mapfold_rev f b xs +  |> app_snd List.rev ++let rootsBy leq xs = +  let notDomBy x = not <.> (leq x) in+  let rec loop acc = function+    | [] -> +        acc+    | (x::xs) ->+        let acc', xs' = map_pair (List.filter (notDomBy x)) (acc, xs) in+        loop (x::acc') xs'+  in loop [] xs++let cov_filter cov f xs = +  let rec loop acc = function+    | [] -> +        acc+    | (x::xs) when f x ->+        let covs, uncovs = List.partition (cov x) xs in+        loop ((x, covs) :: acc) uncovs  +    | (_::xs) ->+      loop acc xs+  in loop [] xs++let filter f xs = +  List.fold_left (fun xs' x -> if f x then x::xs' else xs') [] xs+  |> List.rev++let iter f xs = +  List.fold_left (fun () x -> f x) () xs++let map2 f xs ys = +  let _ = asserti (List.length xs = List.length ys) "Misc.map2" in+  List.map2 f xs ys++let map f xs = +  List.rev_map f xs |> List.rev++let flatten xss =+  xss+  |> List.fold_left (fun acc xs -> xs ++ acc) []+  |> List.rev++let flatsingles xss =+  xss |> List.fold_left (fun acc -> function [x] -> x::acc | _ -> assertf "flatsingles") []+      |> List.rev++let splitflatten xsyss = +  let xss, yss = List.split xsyss in+  (flatten xss, flatten yss)++let splitflatten3 xsyszss =+  let xss, yss, zss = split3 xsyszss in+    (flatten xss, flatten yss, flatten zss)++let flap f xs =+  xs |> List.rev_map f |> flatten |> List.rev++let flap_pair f = splitflatten <.> map f++let tr_rev_flatten xs =+  List.fold_left (fun x xs -> x ++ xs) [] xs++let tr_rev_flap f xs =+  List.fold_left (fun xs x -> (f x) ++ xs) [] xs++let rec fast_unflat ys = function+  | x :: xs -> fast_unflat ([x] :: ys) xs+  | [] -> ys++let dup x = (x, x)+++let rec rev_perms s = function+  | [] -> s+  | e :: es -> rev_perms +    (tr_rev_flap (fun e -> List.rev_map (fun s -> e :: s) s) e) es ++let product = function+  | e :: es -> rev_perms (fast_unflat [] e) es+  | es -> es ++let pairs xs =+  let rec pairs_aux ps = function+    | [] -> ps+    | x :: xs -> pairs_aux (List.fold_left (fun ps y -> (x, y) :: ps) ps xs) xs+  in pairs_aux [] xs++let cross_product xs ys = +  map begin fun x ->+    map begin fun y ->+      (x,y)+    end ys+  end xs+  |> flatten++let rec cross_flatten = function+  | []      -> +      [[]]+  | xs::xss ->+      map begin fun x ->+        map begin fun ys ->+          (x::ys)+        end (cross_flatten xss)+      end xs+      |> flatten+++let append_pref p s =+  (p ^ "." ^ s)+++let fsort f xs =+  let cmp = fun (k1,_) (k2,_) -> compare k1 k2 in+  xs |> map (fun x -> ((f x), x)) +     |> List.sort cmp +     |> map snd++let sort_and_compact ls =+  let rec _sorted_compact l = +    match l with+	h1::h2::tl ->+	  let rest = _sorted_compact (h2::tl) in+	    if h1 = h2 then rest else h1::rest+      | tl -> tl+  in+    _sorted_compact (List.sort compare ls)   ++let sort_and_compact xs = +  List.sort compare xs +  |> List.fold_left +       (fun ys x -> match ys with+        | y::_ when x=y -> ys+        | _::_          -> x::ys+        | []            -> [x])+       [] +  |> List.rev++let hashtbl_to_list t = +  Hashtbl.fold (fun x y l -> (x,y)::l) t []++let hashtbl_keys t = +  Hashtbl.fold (fun x y l -> x::l) t []+  |> sort_and_compact++let hashtbl_invert t = +  let t' = Hashtbl.create 17 in+  hashtbl_to_list t +  |> List.iter (fun (x,y) -> Hashtbl.replace t' y x) +  |> fun _ -> t'+++let distinct xs = + List.length xs = List.length (sort_and_compact xs)++(** repeats f: unit - > unit i times *)+let rec repeat_fn f i = +  if i = 0 then ()+  else (f (); repeat_fn f (i-1))++(* chop s chopper returns ([x;y;z...]) if s = x.chopper.y.chopper ...*)+let chop s chopper = Str.split (Str.regexp chopper) s  ++(* like chop only the chop is by chop+ *)+let chop_star chopper s = +    Str.split (Str.regexp (Printf.sprintf "[%s+]" chopper)) s++let bounded_chop s chopper i = Str.bounded_split (Str.regexp chopper) s i ++let is_prefix p s = +  let (ls, lp) = (String.length s, String.length p) in+  if ls < lp+    then false+  else+    (String.sub s 0 lp) = p++let is_substring s subs = +  let reg = Str.regexp subs in+  try ignore(Str.search_forward reg s 0); true+  with Not_found -> false++let replace_substring src dst s =+  Str.global_replace (Str.regexp src) dst s++let is_suffix suffix s = +  let k = String.length suffix+  and n = String.length s in+  (n-k >= 0) && Str.string_match (Str.regexp suffix) s (n-k)++let iteri f xs =+  List.fold_left (fun i x -> f i x; i+1) 0 xs+  |> ignore++let numbered_list xs =+  xs |> List.fold_left (fun (i, acc) x -> (i+1, (i,x)::acc)) (0,[]) +     |> snd +     |> List.rev ++exception FalseException++let sm_protected_add fail k v sm = +  if not (StringMap.mem k sm) then StringMap.add k v sm else +    if not fail then sm else +      assertf "protected_add: duplicate binding for %s \n" k++let hashtbl_to_list_all t = +  hashtbl_keys t |> map (Hashtbl.find_all t) ++let clone x n =+  let rec f n xs = if n <= 0 then xs else f (n-1) (x::xs) in+  f n []++let single x = [x]++let distinct xs = +  List.length (sort_and_compact xs) = List.length xs++let trunc i j = +  let (ai,aj) = (abs i, abs j) in+  if aj <= ai then j else ai*j/aj ++let map_to_string f xs = +  String.concat "," (List.map f xs)++let suffix_of_string = fun s i -> String.sub s i (String.length s - 1)++(* [count_map xs] = fun x -> number of times x appears in xs if non-zero *)+let count_map rs =+  List.fold_left begin fun m r -> +      let c = try IntMap.find r m with Not_found -> 0 in+      IntMap.add r (c+1) m+  end IntMap.empty rs++let o2s f = function+  | Some x -> "Some "^ (f x)+  | None   -> "None"++let fixpoint f x =+  let rec acf b x =+    let x', b' = f x in+    if b' then acf true x' else (x', b) in+  acf false x+++let fsprintf f p = +  Format.fprintf Format.str_formatter "@[%a@]" f p;+  Format.flush_str_formatter ()++let rec same_length l1 l2 = match l1, l2 with+  | [], []           -> true+  | _ :: xs, _ :: ys -> same_length xs ys+  | _                -> false++let ex_one s = function+  | [x]    -> x+  | _ :: _ -> failwith s+  | _      -> failwith (s ^ ". empty")++let only_one s = function+    x :: [] -> Some x+  | _ :: _  -> failwith s+  | []      -> None++let maybe_one = function+  | [x] -> Some x+  | _   -> None+++let int_of_bool b = if b then 1 else 0++(*****************************************************************)+(******************** Mem Management *****************************)+(*****************************************************************)++open Gc+(* open Format *)++let pprint_gc s =+  (*printf "@[Gc@ Stats:@]@.";+  printf "@[minor@ words:@ %f@]@." s.minor_words;+  printf "@[promoted@ words:@ %f@]@." s.promoted_words;+  printf "@[major@ words:@ %f@]@." s.major_words;*)+  (*printf "@[total allocated:@ %fMB@]@." (floor ((s.major_words +. s.minor_words -. s.promoted_words) *. (4.0) /. (1024.0 *. 1024.0)));*)++  Format.printf "@[total allocated:@ %fMB@]@." (floor ((allocated_bytes ()) /. (1024.0 *. 1024.0)));+  Format.printf "@[minor@ collections:@ %i@]@." s.minor_collections;+  Format.printf "@[major@ collections:@ %i@]@." s.major_collections;+  Format.printf "@[heap@ size:@ %iMB@]@." (s.heap_words * 4 / (1024 * 1024));+  (*printf "@[heap@ chunks:@ %i@]@." s.heap_chunks;+  (*printf "@[live@ words:@ %i@]@." s.live_words;+  printf "@[live@ blocks:@ %i@]@." s.live_blocks;+  printf "@[free@ words:@ %i@]@." s.free_words;+  printf "@[free@ blocks:@ %i@]@." s.free_blocks;+  printf "@[largest@ free:@ %i@]@." s.largest_free;+  printf "@[fragments:@ %i@]@." s.fragments;*)*)+  Format.printf "@[compactions:@ %i@]@." s.compactions;+  (*printf "@[top@ heap@ words:@ %i@]@." s.top_heap_words*) ()++let dump_gc s =+  Format.printf "@[%s@]@." s;+  pprint_gc (Gc.quick_stat ())+++let append_to_file f s = +  let oc = Unix.openfile f [Unix.O_WRONLY; Unix.O_APPEND; Unix.O_CREAT] 420  in+  ignore (Unix.write oc s 0 ((String.length s)-1) ); +  Unix.close oc++(*+let with_out_file file f =+  let oc = open_out file in+    f oc;+    close_out oc+*)++let display_tick = fun () -> print_now "."++let display_tick = +  let icona = [| "|"; "/" ; "-"; "\\" |] in+  let pos   = ref 0 in+  fun () -> +    let k = !pos in+    let _ = print_now ("\b."^icona.(k)) in+    let _ = pos := (k + 1) mod 4 in+    ()++let with_out_file file f = file |> open_out >> f |> close_out++let write_to_file f s =+  with_out_file f (fun oc -> output_string oc s)++let with_out_formatter file f =+  with_out_file file (fun oc -> f (Format.formatter_of_out_channel oc))++let get_unique =+  let cnt = ref 0 in+  (fun () -> let rv = !cnt in incr cnt; rv)++let lines_of_file filename = +  let lines = ref [] in+  let chan = open_in filename in+  try +    while true; do+      lines := input_line chan :: !lines+    done; [] +  with End_of_file ->+    close_in chan;+    List.rev !lines++let map_lines_of_file infile outfile f =+  let ic = open_in infile in+  let oc = open_out outfile in+  try+    while true; do+      ic |> input_line |> f |> output_string oc+    done;+  with End_of_file -> +    (close_in ic; close_out oc)++let maybe_cons m xs = match m with+  | None -> xs+  | Some x -> x :: xs++let maybe_list xs = +  List.fold_right maybe_cons xs []++let rec list_first_maybe f = function+  | x::xs -> begin match f x with +              | Some y -> Some y +              | _      -> list_first_maybe f xs+             end+  | []    -> None++let list_find_maybe f xs =+  try some <| List.find f xs with Not_found -> None++let list_assoc_maybe k kvs =+  try Some (List.assoc k kvs) with Not_found -> None++let list_assoc_default d kvs k =+  try List.assoc k kvs with Not_found -> d++let list_assoc_flip xs = +  let r (x, y) = (y, x) in+    List.map r xs++let fold_lefti f b xs =+  List.fold_left (fun (i,b) x -> ((i+1), f i b x)) (0,b) xs++let mapi f xs = +  xs |> fold_lefti (fun i acc x -> (f i x) :: acc) [] +     |> snd |> List.rev++let index_from n xs = +  let is = range n (n + List.length xs) in+  List.combine is xs++let fold_left_flip f b xs =+  List.fold_left (flip f) b xs++let fold_left_swap f xs b =+  List.fold_left f b xs++let rec map3 f xs ys zs = match (xs, ys, zs) with+  | ([], [], []) -> []+  | (x :: xs, y :: ys, z :: zs) -> f x y z :: map3 f xs ys zs+  | _ -> assert false++let rec fold_right3 f xs ys zs acc = match xs, ys, zs with+  | x :: xs, y :: ys, z :: zs -> f x y z (fold_right3 f xs ys zs acc)+  | [], [], []                -> acc+  | _                         -> assert false++let rec fold_left3 f acc xs ys zs = match xs, ys, zs with+  | x :: xs, y :: ys, z :: zs -> fold_left3 f (f acc x y z) xs ys zs+  | [], [], []                -> acc+  | _                         -> assert false++let zip_partition xs bs =+  let (xbs, xbs') = List.partition snd (List.combine xs bs) in+  (List.map fst xbs, List.map fst xbs')++let rec map4 f ws xs ys zs = match ws, xs, ys, zs with+  | [], [], [], []                     -> []+  | w :: ws, x :: xs, y :: ys, z :: zs -> f w x y z :: map4 f ws xs ys zs+  | _                                  -> asserti false "map4"; assert false+++let rec perms es =+  match es with+    | s :: [] ->+        List.map (fun c -> [c]) s+    | s :: es ->+        flap (fun c -> List.map (fun d -> c :: d) (perms es)) s+    | [] ->+        []++let flap2 f xs ys = +  List.flatten (List.map2 f xs ys)++let flap3 f xs ys zs =+  List.flatten (map3 f xs ys zs)++let combine msg xs ys =+  let _ = asserts (List.length xs = List.length ys) "%s" msg in+  List.combine xs ys++let combine3 xs ys zs =+  map3 (fun x y z -> (x, y, z)) xs ys zs++let combine4 ws xs ys zs =+  map4 (fun w x y z -> (w, x, y, z)) ws xs ys zs++let tr_partition f xs =+  List.fold_left begin fun (xs,ys) z -> +    if f z +    then (z::xs, ys) +    else (xs, z::ys)+  end ([],[]) xs++let either_partition f xs =+  List.fold_left begin fun (xs, ys) z -> +    match f z with+    | Left x  -> (x::xs, ys)+    | Right y -> (xs, y::ys)+  end ([], []) xs++(* these do odd things with order for performance + * it is possible that fast is a misnomer *)+let fast_flatten xs =+  List.fold_left (++) [] xs++let fast_append v v' =+  let (v, v') = if List.length v > List.length v' then (v', v) else (v, v') in+  List.rev_append v v'++let fast_flap f xs =+  List.fold_left (fun xs x -> List.rev_append (f x) xs) [] xs++let rec fast_unflat ys = function+  | x :: xs -> fast_unflat ([x] :: ys) xs+  | [] -> ys++let rec rev_perms s = function+  | [] -> s+  | e :: es -> rev_perms +    (fast_flap (fun e -> List.rev_map (fun s -> e :: s) s) e) es ++let rev_perms = function+  | e :: es -> rev_perms (fast_unflat [] e) es+  | es -> es ++let tflap2 (e1, e2) f =+  List.fold_left (fun bs b -> List.fold_left (fun aas a -> f a b :: aas) bs e1) [] e2++let tflap3 (e1, e2, e3) f =+  List.fold_left begin fun cs c -> +    List.fold_left begin fun bs b -> +      List.fold_left begin fun aas a -> +        f a b c :: aas+      end bs e1+    end cs e2+  end[] e3++let rec expand f xs ys =+  match xs with+  | []    -> ys+  | x::xs -> let (xs', ys') = f x in+             expand f (xs' ++  xs) (ys' ++ ys)++let rec get_first f = function+  | x::xs when f x -> Some x +  | _::xs          -> get_first f xs+  | []             -> None++let join f xs ys = +  let rec fuse acc xs ys = +    match xs, ys with +    | [],_ | _, []                              -> List.rev acc+    | ((kx, _)::xs', (ky,_)::_  ) when kx < ky  -> fuse acc xs' ys+    | ((kx, _)::_  , (ky,_)::ys') when kx > ky  -> fuse acc xs  ys' +    | ((kx, x)::xs', (ky,y)::ys') (* kx = ky *) -> fuse ((x,y)::acc) xs' ys' in+  let xs' = List.map (fun x -> (f x, x)) xs |> List.sort compare in+  let ys' = List.map (fun y -> (f y, y)) ys |> List.sort compare in+  fuse [] xs' ys'++let hashtbl_find_default d t x =+  try Hashtbl.find t x with Not_found -> d++let frequency (xs : 'a list) : ('a * int) list = +  let t = Hashtbl.create 17 in+  List.iter begin fun x ->+    let n =  hashtbl_find_default 0 t x in+    Hashtbl.replace t x (n + 1)+  end xs;+  hashtbl_to_list t++let kgroupby (f: 'a -> 'b) (xs: 'a list): ('b * 'a list) list =+  let t        = Hashtbl.create 17 in+  let lookup x = try Hashtbl.find t x with Not_found -> [] in+  (* build table *)+  List.iter begin fun x -> +    Hashtbl.replace t (f x) (x :: lookup (f x))+  end xs;+  (* build cluster *)+  Hashtbl.fold (fun k xs xxs -> (k, xs) :: xxs) t []++++let groupby (f: 'a -> 'b) (xs: 'a list): 'a list list =+  kgroupby f xs |> List.map (snd <+> List.rev)++let full_join f xs ys =+     (xs, ys)+  |> map_pair (kgroupby f)+  |> uncurry (join fst)+  |> flap (map_pair snd <+> uncurry cross_product)++let exists_pair (f: 'a -> 'a -> bool) (xs: 'a list): bool =+  fst (List.fold_left (fun (b, ys) x -> (b || List.exists (f x) ys, x :: ys)) (false, []) xs)++let rec find_pair (f: 'a -> 'a -> bool): 'a list -> 'a * 'a = function+  | []    -> raise Not_found+  | x::xs -> try (x, List.find (f x) xs) with Not_found -> find_pair f xs++let rec is_unique = function+  | []      -> true+  | x :: xs -> if List.mem x xs then false else is_unique xs++let map_opt f = function+  | Some o -> Some (f o)+  | None -> None++let resl_opt f = function+  | Some o -> f o+  | None -> []++let resi_opt f = function+  | Some o -> f o+  | None -> ()++let opt_iter f l = +  List.iter (resi_opt f) l++let array_findi p arr =+  let rec look i =+    if i < 0 then raise Not_found else+      if p arr.(i) then i else look i - 1+  in look (Array.length arr - 1)++let array_to_index_list a =+  Array.fold_left (fun (i, rv) v -> (i+1,(i,v)::rv)) (0,[]) a+  |> snd+  |> List.rev+++let hashtbl_of_list xys = +  let t = Hashtbl.create 37 in+  let _ = List.iter (fun (x,y) -> Hashtbl.add t x y) xys in+  t++let hashtbl_of_list_with kf xs = +  xs |>: pad_fst kf |> hashtbl_of_list++let array_flapi f a =+  Array.fold_left (fun (i, acc) x -> (i+1, (f i x) :: acc)) (0,[]) a+  |> snd +  |> List.rev+  |> flatten++let array_fold_lefti f acc a =+  Array.fold_left (fun (i, acc) x -> (i + 1, f i acc x)) (0, acc) a |> snd++let array_map2 f xa ya = +  Array.mapi (fun i x -> f x (ya.(i))) xa++let array_rev_iteri f a =+  for i = Array.length a - 1 downto 0 do+    f i a.(i)+  done++exception NotForall++let array_forall f a =+  try+    Array.iter (fun e -> if f e then () else raise NotForall) a; true+  with NotForall ->+    false++let array_combine a1 a2 = +  asserts (Array.length a1 = Array.length a2) "array_combine";+  Array.init (Array.length a1) (fun i -> (a1.(i), a2.(i)))+++let compose f g a = f (g a)+++let rec gcd (a: int) (b: int): int =+  if b = 0 then a else gcd b (a mod b)++let lcm (a: int) (b: int): int =+  if a = 0 then a else (abs (a * b)) / (gcd a b)++let mk_int_factory () =+  let id = ref (-1) in+    ((fun () -> incr id; !id), (fun () -> id := -1))++let mk_char_factory () =+  let (fresh_int, reset_fresh_int) = mk_int_factory () in+    ((fun () -> Char.chr (fresh_int () + Char.code 'a')), reset_fresh_int)++let mk_string_factory s =+  let (fresh_int, reset_fresh_int) = mk_int_factory () in+    ((fun () -> s^(string_of_int (fresh_int ()))), reset_fresh_int)++let swap (x,y) = (y,x)++(* ('a * (int * 'b) list) list -> (int * ('a * 'b) list) list *)+let transpose x_iys_s = +  let t = Hashtbl.create 17 in+  List.iter begin fun (x, iys) ->+    List.iter begin fun (i, y) -> +      Hashtbl.add t i (x,y) +    end iys+  end x_iys_s; +  hashtbl_keys t |> List.map (fun i -> (i, Hashtbl.find_all t i))++let basename_no_extension fname =+  fname |> Filename.basename |> Filename.chop_extension++let absolute_name name =+  if not (Filename.is_relative name) then name else+    let b    = Filename.basename name in+    let d    = Filename.dirname name in+    let dir  = Sys.getcwd () in+    let _    = Sys.chdir (Filename.concat dir d) in+    let dir' = Sys.getcwd () in+    let rv   = Filename.concat dir' b in+    let _    = Sys.chdir dir in+    rv++let cardinality = fun xs -> xs |> sort_and_compact |> List.length+let disjoint    = fun xs ys -> cardinality xs + cardinality ys = cardinality (xs ++ ys)++let bracket (l : unit -> unit) (r : unit -> unit) (f : unit -> 'a) : 'a = +  try l () |> f >> (fun _ -> r ())+  with ex -> assertf "bracket hits exn: %s \n" (Printexc.to_string ex)++(*+let with_ref_at x v f =+  let oldv  = !x in +  bracket (fun _ -> x := v) (fun _ -> x := oldv) f +*)++let with_ref_at x v f = +  let oldv = !x        in +  let _    = x := v    in+  let res  = f ()      in+  let _    = x := oldv in+  res++++let rec isPrefix = function+  | ([], _)                   -> true+  | (x::xs, y::ys) when x = y -> isPrefix (xs, ys)+  | _                         -> false++let find_first_true f lo hi =+  let rec go lo hi = +    let mid = lo + ((hi - lo) / 2) in+    match () with+    | _ when lo >= hi    -> None+    | _ when lo = hi - 1 -> Some hi +    | _ when f mid       -> go lo mid +    | _                  -> go mid hi +  in   if f lo then Some lo +  else if not (f hi) then None +  else go lo hi++let safeHead msg = function+  | [x] -> x+  | _   -> failwith ("ERROR: safeHead" ^ msg) ++let safeApply pp f x = match f x with+  | Some y -> y+  | None   -> failwith ("ERROR: safeApply " ^ (pp x)) ++let stringIsUpper = function+  | "" -> false+  | s  -> let c = s.[0] in c = Char.uppercase c++let stringIsLower = function+  | "" -> false+  | s  -> let c = s.[0] in c = Char.lowercase c+++
+ external/misc/tagtime.ml view
@@ -0,0 +1,125 @@+(*+ *+ * Copyright (c) 2001 by+ *  George C. Necula	necula@cs.berkeley.edu+ *  Scott McPeak        smcpeak@cs.berkeley.edu+ *  Wes Weimer          weimer@cs.berkeley.edu+ *   + * All rights reserved.  Permission to use, copy, modify and distribute+ * this software for research purposes only is hereby granted, + * provided that the following conditions are met: + * 1. XSRedistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the authors may not be used to endorse or promote products + * derived from  this software without specific prior written permission. + *+ * DISCLAIMER:+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ *)++open Misc.Ops++(******************************************************************)+(************************* Definitions ****************************)+(******************************************************************)++                                        (* A hierarchy of timings *)+type t = { name : string * (string list);+           mutable time : float;+           mutable sub  : t list}++                                        (* Create the top level *)+let top = { name = "TOTAL", [];+            time = 0.0;+            sub  = []; }++                                        (* The stack of current path through +                                         * the hierarchy. The head is the +                                         * leaf. *)+let current : t list ref = ref [top]++let subtime x = +  x.sub |> List.map (fun y -> y.time) +        |> List.fold_left (+.) 0.0 ++(******************************************************************)+(************************* Printing *******************************)+(******************************************************************)++let _print x chn msg = +  x.time <- subtime x; +  let rec prTree ind node = +    Printf.fprintf chn "%s%-20s          %6.3f s\n" +      (String.make ind ' ') (fst node.name) node.time  ;+    List.iter (prTree (ind + 2)) node.sub+  in Printf.fprintf chn "%s" msg; prTree 0 x+ +let collapse (x: t) : t = failwith "TBD: Tagtime.collapse"++(* API *)+let print chn msg = _print (collapse top) chn msg++(******************************************************************)+(************************* Timing *********************************)+(******************************************************************)++let restore_stat (oldcurrent, start, stat) = +  let stop = Unix.times () in+  let diff = stop.Unix.tms_utime -. start in+  stat.time <- stat.time +. diff; +  current := oldcurrent++let find_stat stags =+  let curr = (match !current with h :: _ -> h | _ -> assert false) in+  let rec loop = function+    | h :: _ when h.name = stags -> h+    | _ :: rest -> loop rest+    | [] -> let nw = {name = stags; time = 0.0; sub = []} in+            curr.sub <- nw :: curr.sub;+            nw+  in loop curr.sub++(* API *)+let time (str, tags) f arg = +  let stat = find_stat (str, List.sort compare tags) in +  let oldcurrent = !current in+  let _ = current := stat :: oldcurrent in+  let start = (Unix.times ()).Unix.tms_utime in+  try +    let res = f arg in+    restore_stat (oldcurrent, start, stat);+    res  +  with x -> begin+    restore_stat (oldcurrent, start, stat);+    raise x+  end ++(******************************************************************)+(************************* Logging ********************************)+(******************************************************************)++let dump_to_channel chn = +  top.time <- subtime top;+  let rec prTree tags node =+    let s, ts = node.name in+    let tags' = [s] ++ ts ++ tags in+    let time' = max 0.0 (node.time -. (subtime node)) in+    Printf.fprintf chn "%s,%6.3f\n" (String.concat "," tags') time';+    List.iter (prTree tags') node.sub+  in prTree [] top ++(* API *)+let dump = fun fn -> fn |> open_out >> dump_to_channel |> close_out
+ external/misc/tagtime.mli view
@@ -0,0 +1,37 @@+(*+ * Copyright ? 1990-2007 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.+ *+ *)++(* Based on "Stats" by George Necula, Westley Weimer and Scott McPeak *)++(** Time a function and associate the time with the given +    (key) string and the list of (tags) strings. If some+    timing information is already associated with the key +    string, then accumulate the times. If this function is +    invoked within another timed function then you can have +    a hierarchy of timings *)+val time : string * string list -> ('a -> 'b) -> 'a -> 'b ++(** [dump fname] saves the tagged profile to file *)+val dump : string -> unit++val print: out_channel -> string -> unit
+ external/misc/timer.ml view
@@ -0,0 +1,59 @@+(*+ * Copyright ? 1990-2010 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.+ *)++open FixMisc.Ops++type t = {+  name          : string; +  mutable last  : float;+  mutable events: (int * string option * float) list;+}++let get_time  = fun _ -> (Unix.times ()).Unix.tms_utime++let create n = +  let now = get_time () in+  { name   = n; +    events = [(0, None, 0.0)];+    last   = now;+  }++let log_event t so =+  match t.events with+  | []         -> assertf "impossible" +  | (i,_,_)::_ -> let now = get_time () in+                  t.events <- (i+1, so, now -. t.last)::t.events; +                  t.last   <- now ++let to_events = fun t -> List.rev t.events+let to_name   = fun t -> t.name++let print_event ppf = function+  | (i, Some s, f) -> Format.fprintf ppf "<%6d, %6.3f, %s>@\n" i f s+  | (i, None  , f) -> Format.fprintf ppf "<%6d, %6.3f, *>@\n"  i f++let print ppf t = +  Format.fprintf ppf "Timer %s :: @[%a@] \n" +    t.name +    (FixMisc.pprint_many false "" print_event) (to_events t) ++
+ external/misc/timer.mli view
@@ -0,0 +1,28 @@+(*+ * Copyright ? 1990-2010 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.+ *+ *)++type t+val create   : string -> t+val log_event: t -> string option -> unit+val print    : Format.formatter -> t -> unit +
+ external/misc/timetest.ml view
@@ -0,0 +1,29 @@+(**************************************************************)+(*************** Unit Test For Time Modules *******************)+(**************************************************************)++open Misc.Ops++let rec repeat f n = if n > 0 then (f (); repeat f (n-1)) ++let pause_1_sec () = repeat (fun () -> ()) 112516096+let pause_n_sec n  = repeat pause_1_sec n++let rec sim n c b t = +  if n > 0 then begin+    let id = "downtick "^(string_of_int n) in+    let _  = Printf.printf "%s \n" id in+    Timer.log_event t (Some id); +    Tagtime.time ("pause",[id]) pause_n_sec b; +    sim (n-1) c (c*b) t+  end++let sim n c b t = +  sim n c b t; +  Timer.log_event t None++let c = try Sys.argv.(1) |> int_of_string with _ -> 1+let _ = Timer.create "boo" +        >> (fun t -> Tagtime.time ("sim", []) (sim 4 c 1) t)+        |> Format.printf "%a" Timer.print+let _ = Tagtime.dump "timetest.stat"
+ external/ocamlgraph/.depend view
@@ -0,0 +1,128 @@+lib/bitv.cmo: lib/bitv.cmi+lib/bitv.cmx: lib/bitv.cmi+lib/heap.cmo: lib/heap.cmi+lib/heap.cmx: lib/heap.cmi+lib/unionfind.cmo: lib/unionfind.cmi+lib/unionfind.cmx: lib/unionfind.cmi+lib/bitv.cmi:+lib/heap.cmi:+lib/unionfind.cmi:+src/blocks.cmo: src/util.cmi src/sig.cmi+src/blocks.cmx: src/util.cmx src/sig.cmi+src/builder.cmo: src/sig.cmi src/builder.cmi+src/builder.cmx: src/sig.cmi src/builder.cmi+src/classic.cmo: src/sig.cmi src/builder.cmi src/classic.cmi+src/classic.cmx: src/sig.cmi src/builder.cmx src/classic.cmi+src/cliquetree.cmo: src/util.cmi src/sig.cmi src/persistent.cmi src/oper.cmi \+    src/gmap.cmi src/builder.cmi src/cliquetree.cmi+src/cliquetree.cmx: src/util.cmx src/sig.cmi src/persistent.cmx src/oper.cmx \+    src/gmap.cmx src/builder.cmx src/cliquetree.cmi+src/components.cmo: src/util.cmi src/sig.cmi src/components.cmi+src/components.cmx: src/util.cmx src/sig.cmi src/components.cmi+src/delaunay.cmo: src/delaunay.cmi+src/delaunay.cmx: src/delaunay.cmi+src/dot.cmo: src/dot_parser.cmi src/dot_lexer.cmo src/dot_ast.cmi \+    src/builder.cmi src/dot.cmi+src/dot.cmx: src/dot_parser.cmx src/dot_lexer.cmx src/dot_ast.cmi \+    src/builder.cmx src/dot.cmi+src/dot_lexer.cmo: src/dot_parser.cmi src/dot_ast.cmi+src/dot_lexer.cmx: src/dot_parser.cmx src/dot_ast.cmi+src/dot_parser.cmo: src/dot_ast.cmi src/dot_parser.cmi+src/dot_parser.cmx: src/dot_ast.cmi src/dot_parser.cmi+src/flow.cmo: src/util.cmi src/sig.cmi src/flow.cmi+src/flow.cmx: src/util.cmx src/sig.cmi src/flow.cmi+src/gcoloring.cmo: src/traverse.cmi src/sig.cmi src/gcoloring.cmi+src/gcoloring.cmx: src/traverse.cmx src/sig.cmi src/gcoloring.cmi+src/gmap.cmo: src/sig.cmi src/gmap.cmi+src/gmap.cmx: src/sig.cmi src/gmap.cmi+src/gml.cmo: src/builder.cmi src/gml.cmi+src/gml.cmx: src/builder.cmx src/gml.cmi+src/gpath.cmo: src/util.cmi src/sig.cmi lib/heap.cmi src/gpath.cmi+src/gpath.cmx: src/util.cmx src/sig.cmi lib/heap.cmx src/gpath.cmi+src/graphviz.cmo: src/graphviz.cmi+src/graphviz.cmx: src/graphviz.cmi+src/imperative.cmo: src/sig.cmi src/blocks.cmo lib/bitv.cmi \+    src/imperative.cmi+src/imperative.cmx: src/sig.cmi src/blocks.cmx lib/bitv.cmx \+    src/imperative.cmi+src/kruskal.cmo: src/util.cmi lib/unionfind.cmi src/sig.cmi src/kruskal.cmi+src/kruskal.cmx: src/util.cmx lib/unionfind.cmx src/sig.cmi src/kruskal.cmi+src/mcs_m.cmo: src/util.cmi src/sig.cmi src/persistent.cmi src/oper.cmi \+    src/imperative.cmi src/gmap.cmi src/builder.cmi src/mcs_m.cmi+src/mcs_m.cmx: src/util.cmx src/sig.cmi src/persistent.cmx src/oper.cmx \+    src/imperative.cmx src/gmap.cmx src/builder.cmx src/mcs_m.cmi+src/md.cmo: src/sig.cmi src/oper.cmi src/gmap.cmi src/cliquetree.cmi \+    src/builder.cmi src/md.cmi+src/md.cmx: src/sig.cmi src/oper.cmx src/gmap.cmx src/cliquetree.cmx \+    src/builder.cmx src/md.cmi+src/minsep.cmo: src/sig.cmi src/oper.cmi src/components.cmi src/minsep.cmi+src/minsep.cmx: src/sig.cmi src/oper.cmx src/components.cmx src/minsep.cmi+src/oper.cmo: src/sig.cmi src/builder.cmi src/oper.cmi+src/oper.cmx: src/sig.cmi src/builder.cmx src/oper.cmi+src/pack.cmo: src/traverse.cmi src/topological.cmi src/sig.cmi src/rand.cmi \+    src/oper.cmi src/kruskal.cmi src/imperative.cmi src/graphviz.cmi \+    src/gpath.cmi src/gml.cmi src/flow.cmi src/dot.cmi src/components.cmi \+    src/classic.cmi src/builder.cmi src/pack.cmi+src/pack.cmx: src/traverse.cmx src/topological.cmx src/sig.cmi src/rand.cmx \+    src/oper.cmx src/kruskal.cmx src/imperative.cmx src/graphviz.cmx \+    src/gpath.cmx src/gml.cmx src/flow.cmx src/dot.cmx src/components.cmx \+    src/classic.cmx src/builder.cmx src/pack.cmi+src/persistent.cmo: src/util.cmi src/sig.cmi src/blocks.cmo \+    src/persistent.cmi+src/persistent.cmx: src/util.cmx src/sig.cmi src/blocks.cmx \+    src/persistent.cmi+src/rand.cmo: src/sig.cmi src/delaunay.cmi src/builder.cmi src/rand.cmi+src/rand.cmx: src/sig.cmi src/delaunay.cmx src/builder.cmx src/rand.cmi+src/strat.cmo: src/sig.cmi src/strat.cmi+src/strat.cmx: src/sig.cmi src/strat.cmi+src/topological.cmo: src/sig.cmi src/topological.cmi+src/topological.cmx: src/sig.cmi src/topological.cmi+src/traverse.cmo: src/sig.cmi src/traverse.cmi+src/traverse.cmx: src/sig.cmi src/traverse.cmi+src/util.cmo: src/sig.cmi src/util.cmi+src/util.cmx: src/sig.cmi src/util.cmi+src/version.cmo:+src/version.cmx:+src/builder.cmi: src/sig.cmi+src/classic.cmi: src/sig.cmi+src/cliquetree.cmi: src/sig.cmi+src/components.cmi: src/util.cmi src/sig.cmi+src/delaunay.cmi:+src/dot.cmi: src/dot_ast.cmi src/builder.cmi+src/dot_ast.cmi:+src/dot_parser.cmi: src/dot_ast.cmi+src/flow.cmi: src/sig.cmi+src/gcoloring.cmi: src/sig.cmi+src/gmap.cmi: src/sig.cmi+src/gml.cmi: src/builder.cmi+src/gpath.cmi: src/sig.cmi+src/graphviz.cmi:+src/imperative.cmi: src/sig.cmi+src/kruskal.cmi: src/sig.cmi+src/mcs_m.cmi: src/sig.cmi+src/md.cmi: src/sig.cmi+src/minsep.cmi: src/sig.cmi+src/oper.cmi: src/sig.cmi src/builder.cmi+src/pack.cmi: src/sig_pack.cmi+src/persistent.cmi: src/sig.cmi+src/rand.cmi: src/sig.cmi src/builder.cmi+src/sig.cmi:+src/sig_pack.cmi:+src/strat.cmi: src/sig.cmi+src/topological.cmi: src/sig.cmi+src/traverse.cmi: src/sig.cmi+src/util.cmi: src/sig.cmi+editor/ed_display.cmo:+editor/ed_display.cmx:+editor/ed_draw.cmo: src/components.cmi+editor/ed_draw.cmx: src/components.cmx+editor/ed_graph.cmo: src/traverse.cmi src/imperative.cmi src/graphviz.cmi \+    src/gml.cmi src/dot_ast.cmi src/dot.cmi src/components.cmi \+    src/builder.cmi+editor/ed_graph.cmx: src/traverse.cmx src/imperative.cmx src/graphviz.cmx \+    src/gml.cmx src/dot_ast.cmi src/dot.cmx src/components.cmx \+    src/builder.cmx+editor/ed_hyper.cmo:+editor/ed_hyper.cmx:+editor/ed_main.cmo:+editor/ed_main.cmx:
+ external/ocamlgraph/META view
@@ -0,0 +1,5 @@+version = "0.99b"+description = "Generic Graph Library"+requires=""+archive(byte) = "graph.cma"+archive(native) = "graph.cmxa"
+ external/ocamlgraph/META.in view
@@ -0,0 +1,5 @@+version = "VERSION"+description = "Generic Graph Library"+requires=""+archive(byte) = "CMA"+archive(native) = "CMXA"
+ external/ocamlgraph/Makefile view
@@ -0,0 +1,386 @@+##########################################################################+#                                                                        #+#  Ocamlgraph: a generic graph library for OCaml                         #+#  Copyright (C) 2004-2007                                               #+#  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        #+#                                                                        #+#  This software is free software; you can redistribute it and/or        #+#  modify it under the terms of the GNU Library General Public           #+#  License version 2, with the special exception on linking              #+#  described in file LICENSE.                                            #+#                                                                        #+#  This software is distributed in the hope that it will be useful,      #+#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  #+#                                                                        #+##########################################################################++# Where to install the binaries+prefix=/usr/local+exec_prefix=${prefix}+BINDIR=${exec_prefix}/bin++# Where to install the man page+MANDIR=${prefix}/share/man++# Other variables set by ./configure+OCAMLC   = ocamlc+OCAMLOPT = ocamlopt+OCAMLDEP = ocamldep+OCAMLDOC = ocamldoc+OCAMLLEX = ocamllex+OCAMLYACC= ocamlyacc+OCAMLLIB = /usr/lib/ocaml+OCAMLBEST= opt+OCAMLVERSION = 3.12.1+OCAMLWEB = true+OCAMLWIN32 = no+OCAMLFIND = +EXE = +LIBEXT = .a+OBJEXT = .o++# Others global variables+SRCDIR	= src+LIBDIR	= lib++INCLUDES= -I $(SRCDIR) -I $(LIBDIR) +BFLAGS = $(INCLUDES)+OFLAGS = $(INCLUDES) -for-pack Graph++# main target+#############++NAME=ocamlgraph++all: byte $(OCAMLBEST)+#all: byte $(OCAMLBEST) editor-no++# bytecode and native-code compilation+######################################++LIB= unionfind heap bitv+LIB:=$(patsubst %, $(LIBDIR)/%.cmo, $(LIB))++CMO = util blocks persistent imperative \+	delaunay builder classic rand oper \+	gpath traverse gcoloring topological components kruskal flow \+        graphviz gml dot_parser dot_lexer dot pack \+	gmap minsep cliquetree mcs_m md strat+CMO := $(LIB) $(patsubst %, $(SRCDIR)/%.cmo, $(CMO))++CMX = $(CMO:.cmo=.cmx)+CMA = graph.cma+CMXA = graph.cmxa++CMI = sig dot_ast sig_pack+CMI := $(patsubst %, src/%.cmi, $(CMI))++GENERATED = META \+	src/gml.ml src/version.ml \+	src/dot_parser.ml src/dot_parser.mli src/dot_lexer.ml++byte: $(CMA)+opt: $(CMXA)++graph.cma: graph.cmo+	$(OCAMLC) $(INCLUDES) -a -o $@ $^++graph.cmxa: graph.cmx+	$(OCAMLOPT) $(INCLUDES) -a -o $@ $^++graph.cmo: $(CMI) $(CMO)+	$(OCAMLC) $(INCLUDES) -pack -o $@ $^++graph.cmx: $(CMI) $(CMX)+	$(OCAMLOPT) $(INCLUDES) -pack -o $@ $^++EXAMPLESBIN=bin/demo.$(OCAMLBEST) bin/demo_planar.$(OCAMLBEST) \+  bin/bench.$(OCAMLBEST) bin/color.$(OCAMLBEST) bin/sudoku.$(OCAMLBEST) \+  bin/test.$(OCAMLBEST) ++.PHONY: examples+examples: $(EXAMPLESBIN)++.PHONY: demo+demo: bin/demo.$(OCAMLBEST)++bin/demo.byte: $(CMA) examples/demo.cmo+	$(OCAMLC) -o $@ $^++bin/demo.opt: $(CMXA) examples/demo.cmx+	$(OCAMLOPT) -o $@ $^++bin/demo_planar.byte: $(CMA) examples/demo_planar.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/demo_planar.opt: $(CMXA) examples/demo_planar.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++bin/color.byte: $(CMA) examples/color.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/color.opt: $(CMXA) examples/color.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++bin/sudoku.byte: $(CMA) examples/sudoku.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/sudoku.opt: $(CMXA) examples/sudoku.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++test: $(CMA) tests/test.ml+	ocaml unix.cma graphics.cma $^++bin/test.byte: $(CMA) tests/test.cmo+	$(OCAMLC) -g -unsafe -o $@ unix.cma graphics.cma $^++bin/test.opt: $(CMXA) tests/test.cmx+	$(OCAMLOPT) -unsafe -inline 100 -o $@ unix.cmxa graphics.cmxa $^++bench: bin/bench.$(OCAMLBEST)+	bin/bench.opt++bin/bench.opt: $(CMXA) tests/bench.ml+	$(OCAMLOPT) -unsafe -inline 100 -o $@ unix.cmxa $^++check: $(CMA) tests/check.ml+	ocaml $^++# gtk2 graph editor++ED_DIR=editor++editor-no:+editor-yes: $(ED_DIR)/editor.$(OCAMLBEST)++editor: $(ED_DIR)/editor.byte editor-yes++ED_CMO = ed_hyper ed_graph ed_draw ed_display ed_main+ED_CMO:= $(patsubst %, $(ED_DIR)/%.cmo, $(ED_CMO))+ED_CMX = $(ED_CMO:.cmo=.cmx)++ED_INCLUDES =  -I +threads -I $(ED_DIR)++$(ED_CMO): BFLAGS+= $(ED_INCLUDES)+$(ED_CMX): OFLAGS+= $(ED_INCLUDES)++$(ED_DIR)/editor.byte: $(CMA) $(ED_CMO)+	$(OCAMLC) -g -o $@  \+		lablgtk.cma lablgnomecanvas.cma unix.cma $^++$(ED_DIR)/editor.opt: $(CMXA) $(ED_CMX)+	$(OCAMLOPT) -o $@  \+		lablgtk.cmxa lablgnomecanvas.cmxa unix.cmxa $^++VERSION=0.99b++src/version.ml: Makefile+	echo "let version = \""$(VERSION)"\"" > $@+	echo "let date = \""`date`"\"" >> $@++META: META.in Makefile+	sed -e s/VERSION/$(VERSION)/ -e s/CMA/$(CMA)/ -e s/CMXA/$(CMXA)/ \+		$@.in > $@++# Additional rules+##################++EXAMPLES = demo color demo_planar sudoku+EXAMPLES:= $(patsubst %, examples/%.ml, $(EXAMPLES))++TESTS = test check+TESTS := $(patsubst %, tests/%.ml, $(TESTS))++DPD_GRAPH_ML= $(TESTS) $(EXAMPLES)++$(DPD_GRAPH_ML:.ml=.cmo): $(CMA)+$(DPD_GRAPH_ML:.ml=.cmx): $(CMXA)++# installation+##############++install: install-$(OCAMLBEST) install-byte++install-byte: +	cp -f graph.cmo graph.cmi $(CMA) "$(OCAMLLIB)"++install-opt: install-byte+	cp -f graph$(LIBEXT) graph.cmx $(CMXA) "$(OCAMLLIB)"++install-findlib: META+ifdef OCAMLFIND+	$(OCAMLFIND) install ocamlgraph META *.mli \+		graph$(LIBEXT) graph.cmx graph.cmo graph.cmi $(CMA) $(CMXA)+endif++# documentation+###############++DOCFILES=$(NAME).ps $(NAME).html++NODOC	= util blocks dot_parser dot_lexer+NODOC	:= $(patsubst %, $(SRCDIR)/%.cmo, $(NODOC))+DOC_CMO	= $(filter-out $(NODOC) $(LIB), $(CMO))+DOC_SRC	= $(CMI:.cmi=.mli) $(DOC_CMO:.cmo=.mli) $(DOC_CMO:.cmo=.ml)++.PHONY: doc+doc: $(DOC_CMO)+	mkdir -p doc+	rm -f doc/*+	$(OCAMLDOC) -d doc -html $(INCLUDES) $(DOC_SRC)++# literate programming+$(NAME).tex: $(DOC_SRC)+	$(OCAMLWEB) -o $@ $^++wc:+	ocamlwc -p $(SRCDIRC)/*.mli $(SRCDIRC)/*.ml++# file headers+##############+headers:+	headache -c misc/headache_config.txt -h misc/header.txt \+		Makefile.in configure.in README \+		$(LIBDIR)*.ml $(LIBDIR)*.ml[ily] \+		$(SRCDIR)*.ml $(SRCDIR)*.ml[ily] \+		$(ED_DIR)/*.ml $(ED_DIR)/*.mli \++# export+########++EXPORTDIR=$(NAME)-$(VERSION)+TAR=$(EXPORTDIR).tar++FTP = $$HOME/ftp/$(NAME)+WWW = $$HOME/WWW/$(NAME)++FILES = src/*.ml* lib/*.ml* Makefile.in configure configure.in META.in  \+	.depend editor/ed_*.ml* editor/Makefile \+        editor/tests/*.dot editor/tests/*.gml \+	examples/*.ml tests/*.ml \+	.depend README FAQ CREDITS INSTALL COPYING LICENSE CHANGES++export: source export-doc export-web export-delaunay++source: +	mkdir -p export+	cd export; rm -rf $(EXPORTDIR)+	mkdir -p export/$(EXPORTDIR)/bin+	cp --parents $(FILES) export/$(EXPORTDIR)+	cd export ; tar cf $(TAR) $(EXPORTDIR) ; gzip -f --best $(TAR)+	cp export/$(TAR).gz $(FTP)+	cp README FAQ CREDITS COPYING LICENSE CHANGES $(EXAMPLES) $(FTP)++www/version.prehtml: Makefile.in+	echo "<#def version>$(VERSION)</#def>" > www/version.prehtml++export-web: www/version.prehtml+	make -C www install++export-doc: $(DOC_CMO)+	rm -f $(WWW)/doc/*+	-$(OCAMLDOC) -d $(WWW)/doc -html $(INCLUDES) $(DOC_SRC)++MISCFTP = $(HOME)/WWW/ftp/ocaml/misc+DELAUNAY=delaunay.ml delaunay.mli+export-delaunay:+	cd src; cp -f $(DELAUNAY) $(MISCFTP)+	cd src; caml2html -d $(MISCFTP) $(DELAUNAY)++# generic rules+###############++.SUFFIXES: .mli .ml .cmi .cmo .cmx .mll .mly .tex .dvi .ps .html++.mli.cmi:+	$(OCAMLC) -c $(BFLAGS) $<++.ml.cmo:+	$(OCAMLC) -c $(BFLAGS) $<++.ml.o:+	$(OCAMLOPT) -c $(OFLAGS) $<++.ml.cmx:+	$(OCAMLOPT) -c $(OFLAGS) $<++.mll.ml:+	$(OCAMLLEX) $<++.mly.ml:+	$(OCAMLYACC) -v $<++.mly.mli:+	$(OCAMLYACC) -v $<++.tex.dvi:+	latex $< && latex $<++.dvi.ps:+	dvips $< -o $@ ++.tex.html:+	hevea $<++# Emacs tags+############++otags:+	otags -r src editor++tags:+	find . -name "*.ml*" | sort -r | xargs \+	etags "--regex=/let[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/let[ \t]+rec[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/and[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/type[ \t]+\([^ \t]+\)/\1/" \+              "--regex=/exception[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/val[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/module[ \t]+\([^ \t]+\)/\1/"++# Makefile is rebuilt whenever Makefile.in or configure.in is modified+######################################################################++Makefile: Makefile.in config.status+	if test -e $@; then chmod a+w $@; fi		+	./config.status+	chmod a-w $@++config.status: configure+	./config.status --recheck++configure: configure.in+	autoconf ++# clean+#######++clean:+	rm -f *~+	for d in $(SRCDIR) $(LIBDIR) $(ED_DIR) tests examples; do \+	  rm -f $$d/*.cm[iox] $$d/*$(OBJEXT) $$d/*~; \+	done+	rm -f $(GENERATED) $(SRCDIR)/dot_parser.output+	rm -f graph.*a graph$(LIBEXT) bin/$(NAME).byte bin/$(NAME).opt+	rm -f *.haux *.aux *.log $(NAME).tex $(NAME).dvi $(DOCFILES)+	rm -f $(EXAMPLESBIN)++dist-clean distclean:: clean+	rm -f Makefile config.cache config.log config.status *.byte *.opt++svnclean svn-clean:: dist-clean+	rm -f config.* configure configure.lineno++# depend+########++.PHONY: depend+.depend depend: $(GENERATED)+	rm -f .depend+	$(OCAMLDEP) $(INCLUDES) \+		$(LIBDIR)/*.ml $(LIBDIR)/*.mli \+		$(SRCDIR)/*.ml $(SRCDIR)/*.mli \+		$(ED_DIR)/*.mli $(ED_DIR)/*.ml > .depend++include .depend
+ external/ocamlgraph/Makefile.in view
@@ -0,0 +1,386 @@+##########################################################################+#                                                                        #+#  Ocamlgraph: a generic graph library for OCaml                         #+#  Copyright (C) 2004-2007                                               #+#  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        #+#                                                                        #+#  This software is free software; you can redistribute it and/or        #+#  modify it under the terms of the GNU Library General Public           #+#  License version 2, with the special exception on linking              #+#  described in file LICENSE.                                            #+#                                                                        #+#  This software is distributed in the hope that it will be useful,      #+#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  #+#                                                                        #+##########################################################################++# Where to install the binaries+prefix=@prefix@+exec_prefix=@exec_prefix@+BINDIR=@bindir@++# Where to install the man page+MANDIR=@mandir@++# Other variables set by ./configure+OCAMLC   = @OCAMLC@+OCAMLOPT = @OCAMLOPT@+OCAMLDEP = @OCAMLDEP@+OCAMLDOC = @OCAMLDOC@+OCAMLLEX = @OCAMLLEX@+OCAMLYACC= @OCAMLYACC@+OCAMLLIB = @OCAMLLIB@+OCAMLBEST= @OCAMLBEST@+OCAMLVERSION = @OCAMLVERSION@+OCAMLWEB = @OCAMLWEB@+OCAMLWIN32 = @OCAMLWIN32@+OCAMLFIND = @OCAMLFIND@+EXE = @EXE@+LIBEXT = @LIBEXT@+OBJEXT = @OBJEXT@++# Others global variables+SRCDIR	= src+LIBDIR	= lib++INCLUDES= -I $(SRCDIR) -I $(LIBDIR) +BFLAGS = $(INCLUDES)+OFLAGS = $(INCLUDES) @FORPACK@++# main target+#############++NAME=ocamlgraph++all: byte $(OCAMLBEST)+#all: byte $(OCAMLBEST) editor-@LABLGTK2@++# bytecode and native-code compilation+######################################++LIB= unionfind heap bitv+LIB:=$(patsubst %, $(LIBDIR)/%.cmo, $(LIB))++CMO = util blocks persistent imperative \+	delaunay builder classic rand oper \+	gpath traverse gcoloring topological components kruskal flow \+        graphviz gml dot_parser dot_lexer dot pack \+	gmap minsep cliquetree mcs_m md strat+CMO := $(LIB) $(patsubst %, $(SRCDIR)/%.cmo, $(CMO))++CMX = $(CMO:.cmo=.cmx)+CMA = graph.cma+CMXA = graph.cmxa++CMI = sig dot_ast sig_pack+CMI := $(patsubst %, src/%.cmi, $(CMI))++GENERATED = META \+	src/gml.ml src/version.ml \+	src/dot_parser.ml src/dot_parser.mli src/dot_lexer.ml++byte: $(CMA)+opt: $(CMXA)++graph.cma: graph.cmo+	$(OCAMLC) $(INCLUDES) -a -o $@ $^++graph.cmxa: graph.cmx+	$(OCAMLOPT) $(INCLUDES) -a -o $@ $^++graph.cmo: $(CMI) $(CMO)+	$(OCAMLC) $(INCLUDES) -pack -o $@ $^++graph.cmx: $(CMI) $(CMX)+	$(OCAMLOPT) $(INCLUDES) -pack -o $@ $^++EXAMPLESBIN=bin/demo.$(OCAMLBEST) bin/demo_planar.$(OCAMLBEST) \+  bin/bench.$(OCAMLBEST) bin/color.$(OCAMLBEST) bin/sudoku.$(OCAMLBEST) \+  bin/test.$(OCAMLBEST) ++.PHONY: examples+examples: $(EXAMPLESBIN)++.PHONY: demo+demo: bin/demo.$(OCAMLBEST)++bin/demo.byte: $(CMA) examples/demo.cmo+	$(OCAMLC) -o $@ $^++bin/demo.opt: $(CMXA) examples/demo.cmx+	$(OCAMLOPT) -o $@ $^++bin/demo_planar.byte: $(CMA) examples/demo_planar.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/demo_planar.opt: $(CMXA) examples/demo_planar.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++bin/color.byte: $(CMA) examples/color.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/color.opt: $(CMXA) examples/color.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++bin/sudoku.byte: $(CMA) examples/sudoku.cmo+	$(OCAMLC) -o $@ graphics.cma unix.cma $^++bin/sudoku.opt: $(CMXA) examples/sudoku.cmx+	$(OCAMLOPT) -o $@ graphics.cmxa unix.cmxa $^++test: $(CMA) tests/test.ml+	ocaml unix.cma graphics.cma $^++bin/test.byte: $(CMA) tests/test.cmo+	$(OCAMLC) -g -unsafe -o $@ unix.cma graphics.cma $^++bin/test.opt: $(CMXA) tests/test.cmx+	$(OCAMLOPT) -unsafe -inline 100 -o $@ unix.cmxa graphics.cmxa $^++bench: bin/bench.$(OCAMLBEST)+	bin/bench.opt++bin/bench.opt: $(CMXA) tests/bench.ml+	$(OCAMLOPT) -unsafe -inline 100 -o $@ unix.cmxa $^++check: $(CMA) tests/check.ml+	ocaml $^++# gtk2 graph editor++ED_DIR=editor++editor-no:+editor-yes: $(ED_DIR)/editor.$(OCAMLBEST)++editor: $(ED_DIR)/editor.byte editor-yes++ED_CMO = ed_hyper ed_graph ed_draw ed_display ed_main+ED_CMO:= $(patsubst %, $(ED_DIR)/%.cmo, $(ED_CMO))+ED_CMX = $(ED_CMO:.cmo=.cmx)++ED_INCLUDES = @INCLUDEGTK2@ -I +threads -I $(ED_DIR)++$(ED_CMO): BFLAGS+= $(ED_INCLUDES)+$(ED_CMX): OFLAGS+= $(ED_INCLUDES)++$(ED_DIR)/editor.byte: $(CMA) $(ED_CMO)+	$(OCAMLC) -g -o $@ @INCLUDEGTK2@ \+		lablgtk.cma lablgnomecanvas.cma unix.cma $^++$(ED_DIR)/editor.opt: $(CMXA) $(ED_CMX)+	$(OCAMLOPT) -o $@ @INCLUDEGTK2@ \+		lablgtk.cmxa lablgnomecanvas.cmxa unix.cmxa $^++VERSION=0.99b++src/version.ml: Makefile+	echo "let version = \""$(VERSION)"\"" > $@+	echo "let date = \""`date`"\"" >> $@++META: META.in Makefile+	sed -e s/VERSION/$(VERSION)/ -e s/CMA/$(CMA)/ -e s/CMXA/$(CMXA)/ \+		$@.in > $@++# Additional rules+##################++EXAMPLES = demo color demo_planar sudoku+EXAMPLES:= $(patsubst %, examples/%.ml, $(EXAMPLES))++TESTS = test check+TESTS := $(patsubst %, tests/%.ml, $(TESTS))++DPD_GRAPH_ML= $(TESTS) $(EXAMPLES)++$(DPD_GRAPH_ML:.ml=.cmo): $(CMA)+$(DPD_GRAPH_ML:.ml=.cmx): $(CMXA)++# installation+##############++install: install-$(OCAMLBEST) install-byte++install-byte: +	cp -f graph.cmo graph.cmi $(CMA) "$(OCAMLLIB)"++install-opt: install-byte+	cp -f graph$(LIBEXT) graph.cmx $(CMXA) "$(OCAMLLIB)"++install-findlib: META+ifdef OCAMLFIND+	$(OCAMLFIND) install ocamlgraph META *.mli \+		graph$(LIBEXT) graph.cmx graph.cmo graph.cmi $(CMA) $(CMXA)+endif++# documentation+###############++DOCFILES=$(NAME).ps $(NAME).html++NODOC	= util blocks dot_parser dot_lexer+NODOC	:= $(patsubst %, $(SRCDIR)/%.cmo, $(NODOC))+DOC_CMO	= $(filter-out $(NODOC) $(LIB), $(CMO))+DOC_SRC	= $(CMI:.cmi=.mli) $(DOC_CMO:.cmo=.mli) $(DOC_CMO:.cmo=.ml)++.PHONY: doc+doc: $(DOC_CMO)+	mkdir -p doc+	rm -f doc/*+	$(OCAMLDOC) -d doc -html $(INCLUDES) $(DOC_SRC)++# literate programming+$(NAME).tex: $(DOC_SRC)+	$(OCAMLWEB) -o $@ $^++wc:+	ocamlwc -p $(SRCDIRC)/*.mli $(SRCDIRC)/*.ml++# file headers+##############+headers:+	headache -c misc/headache_config.txt -h misc/header.txt \+		Makefile.in configure.in README \+		$(LIBDIR)*.ml $(LIBDIR)*.ml[ily] \+		$(SRCDIR)*.ml $(SRCDIR)*.ml[ily] \+		$(ED_DIR)/*.ml $(ED_DIR)/*.mli \++# export+########++EXPORTDIR=$(NAME)-$(VERSION)+TAR=$(EXPORTDIR).tar++FTP = $$HOME/ftp/$(NAME)+WWW = $$HOME/WWW/$(NAME)++FILES = src/*.ml* lib/*.ml* Makefile.in configure configure.in META.in  \+	.depend editor/ed_*.ml* editor/Makefile \+        editor/tests/*.dot editor/tests/*.gml \+	examples/*.ml tests/*.ml \+	.depend README FAQ CREDITS INSTALL COPYING LICENSE CHANGES++export: source export-doc export-web export-delaunay++source: +	mkdir -p export+	cd export; rm -rf $(EXPORTDIR)+	mkdir -p export/$(EXPORTDIR)/bin+	cp --parents $(FILES) export/$(EXPORTDIR)+	cd export ; tar cf $(TAR) $(EXPORTDIR) ; gzip -f --best $(TAR)+	cp export/$(TAR).gz $(FTP)+	cp README FAQ CREDITS COPYING LICENSE CHANGES $(EXAMPLES) $(FTP)++www/version.prehtml: Makefile.in+	echo "<#def version>$(VERSION)</#def>" > www/version.prehtml++export-web: www/version.prehtml+	make -C www install++export-doc: $(DOC_CMO)+	rm -f $(WWW)/doc/*+	-$(OCAMLDOC) -d $(WWW)/doc -html $(INCLUDES) $(DOC_SRC)++MISCFTP = $(HOME)/WWW/ftp/ocaml/misc+DELAUNAY=delaunay.ml delaunay.mli+export-delaunay:+	cd src; cp -f $(DELAUNAY) $(MISCFTP)+	cd src; caml2html -d $(MISCFTP) $(DELAUNAY)++# generic rules+###############++.SUFFIXES: .mli .ml .cmi .cmo .cmx .mll .mly .tex .dvi .ps .html++.mli.cmi:+	$(OCAMLC) -c $(BFLAGS) $<++.ml.cmo:+	$(OCAMLC) -c $(BFLAGS) $<++.ml.o:+	$(OCAMLOPT) -c $(OFLAGS) $<++.ml.cmx:+	$(OCAMLOPT) -c $(OFLAGS) $<++.mll.ml:+	$(OCAMLLEX) $<++.mly.ml:+	$(OCAMLYACC) -v $<++.mly.mli:+	$(OCAMLYACC) -v $<++.tex.dvi:+	latex $< && latex $<++.dvi.ps:+	dvips $< -o $@ ++.tex.html:+	hevea $<++# Emacs tags+############++otags:+	otags -r src editor++tags:+	find . -name "*.ml*" | sort -r | xargs \+	etags "--regex=/let[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/let[ \t]+rec[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/and[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/type[ \t]+\([^ \t]+\)/\1/" \+              "--regex=/exception[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/val[ \t]+\([^ \t]+\)/\1/" \+	      "--regex=/module[ \t]+\([^ \t]+\)/\1/"++# Makefile is rebuilt whenever Makefile.in or configure.in is modified+######################################################################++Makefile: Makefile.in config.status+	if test -e $@; then chmod a+w $@; fi		+	./config.status+	chmod a-w $@++config.status: configure+	./config.status --recheck++configure: configure.in+	autoconf ++# clean+#######++clean:+	rm -f *~+	for d in $(SRCDIR) $(LIBDIR) $(ED_DIR) tests examples; do \+	  rm -f $$d/*.cm[iox] $$d/*$(OBJEXT) $$d/*~; \+	done+	rm -f $(GENERATED) $(SRCDIR)/dot_parser.output+	rm -f graph.*a graph$(LIBEXT) bin/$(NAME).byte bin/$(NAME).opt+	rm -f *.haux *.aux *.log $(NAME).tex $(NAME).dvi $(DOCFILES)+	rm -f $(EXAMPLESBIN)++dist-clean distclean:: clean+	rm -f Makefile config.cache config.log config.status *.byte *.opt++svnclean svn-clean:: dist-clean+	rm -f config.* configure configure.lineno++# depend+########++.PHONY: depend+.depend depend: $(GENERATED)+	rm -f .depend+	$(OCAMLDEP) $(INCLUDES) \+		$(LIBDIR)/*.ml $(LIBDIR)/*.mli \+		$(SRCDIR)/*.ml $(SRCDIR)/*.mli \+		$(ED_DIR)/*.mli $(ED_DIR)/*.ml > .depend++include .depend
+ external/ocamlgraph/configure view
@@ -0,0 +1,3485 @@+#! /bin/sh+# Guess values for system-dependent variables and create Makefiles.+# Generated by GNU Autoconf 2.68.+#+#+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software+# Foundation, Inc.+#+#+# This configure script is free software; the Free Software Foundation+# gives unlimited permission to copy, distribute and modify it.+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else+  case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+# Prefer a ksh shell builtin over an external printf program on Solaris,+# but without wasting forks for bash or zsh.+if test -z "$BASH_VERSION$ZSH_VERSION" \+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='print -r --'+  as_echo_n='print -rn --'+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='printf %s\n'+  as_echo_n='printf %s'+else+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+    as_echo_n='/usr/ucb/echo -n'+  else+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+    as_echo_n_body='eval+      arg=$1;+      case $arg in #(+      *"$as_nl"*)+	expr "X$arg" : "X\\(.*\\)$as_nl";+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+      esac;+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+    '+    export as_echo_n_body+    as_echo_n='sh -c $as_echo_n_body as_echo'+  fi+  export as_echo_body+  as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# IFS+# We need space, tab and new line, in precisely that order.  Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" ""	$as_nl"++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi++# Unset variables that we do not need and which cause bugs (e.g. in+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"+# suppresses any "Segmentation fault" message there.  '((' could+# trigger a bug in pdksh 5.2.14.+for as_var in BASH_ENV ENV MAIL MAILPATH+do eval test x\${$as_var+set} = xset \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# CDPATH.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH++if test "x$CONFIG_SHELL" = x; then+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '\${1+\"\$@\"}'='\"\$@\"'+  setopt NO_GLOB_SUBST+else+  case \`(set -o) 2>/dev/null\` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+"+  as_required="as_fn_return () { (exit \$1); }+as_fn_success () { as_fn_return 0; }+as_fn_failure () { as_fn_return 1; }+as_fn_ret_success () { return 0; }+as_fn_ret_failure () { return 1; }++exitcode=0+as_fn_success || { exitcode=1; echo as_fn_success failed.; }+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :++else+  exitcode=1; echo positional parameters were not saved.+fi+test x\$exitcode = x0 || exit 1"+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"+  if (eval "$as_required") 2>/dev/null; then :+  as_have_required=yes+else+  as_have_required=no+fi+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :++else+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_found=false+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+  as_found=:+  case $as_dir in #(+	 /*)+	   for as_base in sh bash ksh sh5; do+	     # Try only shells that exist, to save several forks.+	     as_shell=$as_dir/$as_base+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :+  CONFIG_SHELL=$as_shell as_have_required=yes+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :+  break 2+fi+fi+	   done;;+       esac+  as_found=false+done+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :+  CONFIG_SHELL=$SHELL as_have_required=yes+fi; }+IFS=$as_save_IFS+++      if test "x$CONFIG_SHELL" != x; then :+  # We cannot yet assume a decent shell, so we have to provide a+	# neutralization value for shells without unset; and this also+	# works around shells that cannot unset nonexistent variables.+	# Preserve -v and -x to the replacement shell.+	BASH_ENV=/dev/null+	ENV=/dev/null+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+	export CONFIG_SHELL+	case $- in # ((((+	  *v*x* | *x*v* ) as_opts=-vx ;;+	  *v* ) as_opts=-v ;;+	  *x* ) as_opts=-x ;;+	  * ) as_opts= ;;+	esac+	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}+fi++    if test x$as_have_required = xno; then :+  $as_echo "$0: This script requires a shell more modern than all"+  $as_echo "$0: the shells that I found on your system."+  if test x${ZSH_VERSION+set} = xset ; then+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."+  else+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,+$0: including any error possibly output before this+$0: message. Then install a modern shell, or manually run+$0: the script under such a shell if you do have one."+  fi+  exit 1+fi+fi+fi+SHELL=${CONFIG_SHELL-/bin/sh}+export SHELL+# Unset more variables known to interfere with behavior of common tools.+CLICOLOR_FORCE= GREP_OPTIONS=+unset CLICOLOR_FORCE GREP_OPTIONS++## --------------------- ##+## M4sh Shell Functions. ##+## --------------------- ##+# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p+# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else+  as_fn_append ()+  {+    eval $1=\$$1\$2+  }+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else+  as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  }+fi # as_fn_arith+++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  $as_echo "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits+++  as_lineno_1=$LINENO as_lineno_1a=$LINENO+  as_lineno_2=$LINENO as_lineno_2a=$LINENO+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)+  sed -n '+    p+    /[$]LINENO/=+  ' <$as_myself |+    sed '+      s/[$]LINENO.*/&-/+      t lineno+      b+      :lineno+      N+      :loop+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/+      t loop+      s/-\n.*//+    ' >$as_me.lineno &&+  chmod +x "$as_me.lineno" ||+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }++  # Don't try to exec as it changes $[0], causing all sort of problems+  # (the dirname of $[0] is not the place where we might find the+  # original and so on.  Autoconf is especially sensitive to this).+  . "./$as_me.lineno"+  # Exit status is that of the last command.+  exit+}++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+    # In both cases, we have to default to `cp -p'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -p'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -p'+  fi+else+  as_ln_s='cp -p'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null++if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi++if test -x / >/dev/null 2>&1; then+  as_test_x='test -x'+else+  if ls -dL / >/dev/null 2>&1; then+    as_ls_L_option=L+  else+    as_ls_L_option=+  fi+  as_test_x='+    eval sh -c '\''+      if test -d "$1"; then+	test -d "$1/.";+      else+	case $1 in #(+	-*)set "./$1";;+	esac;+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((+	???[sx]*):;;*)false;;esac;fi+    '\'' sh+  '+fi+as_executable_p=$as_test_x++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"+++test -n "$DJDIR" || exec 7<&0 </dev/null+exec 6>&1++# Name of the host.+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,+# so uname gets run too.+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`++#+# Initializations.+#+ac_default_prefix=/usr/local+ac_clean_files=+ac_config_libobj_dir=.+LIBOBJS=+cross_compiling=no+subdirs=+MFLAGS=+MAKEFLAGS=++# Identity of this package.+PACKAGE_NAME=+PACKAGE_TARNAME=+PACKAGE_VERSION=+PACKAGE_STRING=+PACKAGE_BUGREPORT=+PACKAGE_URL=++ac_unique_file="src/sig.mli"+ac_subst_vars='LTLIBOBJS+LIBOBJS+INCLUDEGTK2+FORPACK+OBJEXT+LIBEXT+EXE+OCAMLWIN32+OCAMLLIB+OCAMLVERSION+OCAMLBEST+LABLGTK2+OCAMLFIND+OCAMLWEB+OCAMLDOCOPT+OCAMLDOC+OCAMLYACC+OCAMLLEXDOTOPT+OCAMLLEX+OCAMLDEP+OCAMLOPTDOTOPT+OCAMLCDOTOPT+OCAMLOPT+OCAMLC+target_alias+host_alias+build_alias+LIBS+ECHO_T+ECHO_N+ECHO_C+DEFS+mandir+localedir+libdir+psdir+pdfdir+dvidir+htmldir+infodir+docdir+oldincludedir+includedir+localstatedir+sharedstatedir+sysconfdir+datadir+datarootdir+libexecdir+sbindir+bindir+program_transform_name+prefix+exec_prefix+PACKAGE_URL+PACKAGE_BUGREPORT+PACKAGE_STRING+PACKAGE_VERSION+PACKAGE_TARNAME+PACKAGE_NAME+PATH_SEPARATOR+SHELL'+ac_subst_files=''+ac_user_opts='+enable_option_checking+'+      ac_precious_vars='build_alias+host_alias+target_alias'+++# Initialize some variables set by options.+ac_init_help=+ac_init_version=false+ac_unrecognized_opts=+ac_unrecognized_sep=+# The variables have the same names as the options, with+# dashes changed to underlines.+cache_file=/dev/null+exec_prefix=NONE+no_create=+no_recursion=+prefix=NONE+program_prefix=NONE+program_suffix=NONE+program_transform_name=s,x,x,+silent=+site=+srcdir=+verbose=+x_includes=NONE+x_libraries=NONE++# Installation directory options.+# These are left unexpanded so users can "make install exec_prefix=/foo"+# and all the variables that are supposed to be based on exec_prefix+# by default will actually change.+# Use braces instead of parens because sh, perl, etc. also accept them.+# (The list follows the same order as the GNU Coding Standards.)+bindir='${exec_prefix}/bin'+sbindir='${exec_prefix}/sbin'+libexecdir='${exec_prefix}/libexec'+datarootdir='${prefix}/share'+datadir='${datarootdir}'+sysconfdir='${prefix}/etc'+sharedstatedir='${prefix}/com'+localstatedir='${prefix}/var'+includedir='${prefix}/include'+oldincludedir='/usr/include'+docdir='${datarootdir}/doc/${PACKAGE}'+infodir='${datarootdir}/info'+htmldir='${docdir}'+dvidir='${docdir}'+pdfdir='${docdir}'+psdir='${docdir}'+libdir='${exec_prefix}/lib'+localedir='${datarootdir}/locale'+mandir='${datarootdir}/man'++ac_prev=+ac_dashdash=+for ac_option+do+  # If the previous option needs an argument, assign it.+  if test -n "$ac_prev"; then+    eval $ac_prev=\$ac_option+    ac_prev=+    continue+  fi++  case $ac_option in+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;+  *=)   ac_optarg= ;;+  *)    ac_optarg=yes ;;+  esac++  # Accept the important Cygnus configure options, so we can diagnose typos.++  case $ac_dashdash$ac_option in+  --)+    ac_dashdash=yes ;;++  -bindir | --bindir | --bindi | --bind | --bin | --bi)+    ac_prev=bindir ;;+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)+    bindir=$ac_optarg ;;++  -build | --build | --buil | --bui | --bu)+    ac_prev=build_alias ;;+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)+    build_alias=$ac_optarg ;;++  -cache-file | --cache-file | --cache-fil | --cache-fi \+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)+    ac_prev=cache_file ;;+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)+    cache_file=$ac_optarg ;;++  --config-cache | -C)+    cache_file=config.cache ;;++  -datadir | --datadir | --datadi | --datad)+    ac_prev=datadir ;;+  -datadir=* | --datadir=* | --datadi=* | --datad=*)+    datadir=$ac_optarg ;;++  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \+  | --dataroo | --dataro | --datar)+    ac_prev=datarootdir ;;+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)+    datarootdir=$ac_optarg ;;++  -disable-* | --disable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=no ;;++  -docdir | --docdir | --docdi | --doc | --do)+    ac_prev=docdir ;;+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)+    docdir=$ac_optarg ;;++  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)+    ac_prev=dvidir ;;+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)+    dvidir=$ac_optarg ;;++  -enable-* | --enable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=\$ac_optarg ;;++  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \+  | --exec | --exe | --ex)+    ac_prev=exec_prefix ;;+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \+  | --exec=* | --exe=* | --ex=*)+    exec_prefix=$ac_optarg ;;++  -gas | --gas | --ga | --g)+    # Obsolete; use --with-gas.+    with_gas=yes ;;++  -help | --help | --hel | --he | -h)+    ac_init_help=long ;;+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)+    ac_init_help=recursive ;;+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)+    ac_init_help=short ;;++  -host | --host | --hos | --ho)+    ac_prev=host_alias ;;+  -host=* | --host=* | --hos=* | --ho=*)+    host_alias=$ac_optarg ;;++  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)+    ac_prev=htmldir ;;+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \+  | --ht=*)+    htmldir=$ac_optarg ;;++  -includedir | --includedir | --includedi | --included | --include \+  | --includ | --inclu | --incl | --inc)+    ac_prev=includedir ;;+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \+  | --includ=* | --inclu=* | --incl=* | --inc=*)+    includedir=$ac_optarg ;;++  -infodir | --infodir | --infodi | --infod | --info | --inf)+    ac_prev=infodir ;;+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)+    infodir=$ac_optarg ;;++  -libdir | --libdir | --libdi | --libd)+    ac_prev=libdir ;;+  -libdir=* | --libdir=* | --libdi=* | --libd=*)+    libdir=$ac_optarg ;;++  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \+  | --libexe | --libex | --libe)+    ac_prev=libexecdir ;;+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \+  | --libexe=* | --libex=* | --libe=*)+    libexecdir=$ac_optarg ;;++  -localedir | --localedir | --localedi | --localed | --locale)+    ac_prev=localedir ;;+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)+    localedir=$ac_optarg ;;++  -localstatedir | --localstatedir | --localstatedi | --localstated \+  | --localstate | --localstat | --localsta | --localst | --locals)+    ac_prev=localstatedir ;;+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)+    localstatedir=$ac_optarg ;;++  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)+    ac_prev=mandir ;;+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)+    mandir=$ac_optarg ;;++  -nfp | --nfp | --nf)+    # Obsolete; use --without-fp.+    with_fp=no ;;++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \+  | --no-cr | --no-c | -n)+    no_create=yes ;;++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)+    no_recursion=yes ;;++  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \+  | --oldin | --oldi | --old | --ol | --o)+    ac_prev=oldincludedir ;;+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)+    oldincludedir=$ac_optarg ;;++  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)+    ac_prev=prefix ;;+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)+    prefix=$ac_optarg ;;++  -program-prefix | --program-prefix | --program-prefi | --program-pref \+  | --program-pre | --program-pr | --program-p)+    ac_prev=program_prefix ;;+  -program-prefix=* | --program-prefix=* | --program-prefi=* \+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)+    program_prefix=$ac_optarg ;;++  -program-suffix | --program-suffix | --program-suffi | --program-suff \+  | --program-suf | --program-su | --program-s)+    ac_prev=program_suffix ;;+  -program-suffix=* | --program-suffix=* | --program-suffi=* \+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)+    program_suffix=$ac_optarg ;;++  -program-transform-name | --program-transform-name \+  | --program-transform-nam | --program-transform-na \+  | --program-transform-n | --program-transform- \+  | --program-transform | --program-transfor \+  | --program-transfo | --program-transf \+  | --program-trans | --program-tran \+  | --progr-tra | --program-tr | --program-t)+    ac_prev=program_transform_name ;;+  -program-transform-name=* | --program-transform-name=* \+  | --program-transform-nam=* | --program-transform-na=* \+  | --program-transform-n=* | --program-transform-=* \+  | --program-transform=* | --program-transfor=* \+  | --program-transfo=* | --program-transf=* \+  | --program-trans=* | --program-tran=* \+  | --progr-tra=* | --program-tr=* | --program-t=*)+    program_transform_name=$ac_optarg ;;++  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)+    ac_prev=pdfdir ;;+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)+    pdfdir=$ac_optarg ;;++  -psdir | --psdir | --psdi | --psd | --ps)+    ac_prev=psdir ;;+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)+    psdir=$ac_optarg ;;++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil)+    silent=yes ;;++  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)+    ac_prev=sbindir ;;+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \+  | --sbi=* | --sb=*)+    sbindir=$ac_optarg ;;++  -sharedstatedir | --sharedstatedir | --sharedstatedi \+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \+  | --sharedst | --shareds | --shared | --share | --shar \+  | --sha | --sh)+    ac_prev=sharedstatedir ;;+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \+  | --sha=* | --sh=*)+    sharedstatedir=$ac_optarg ;;++  -site | --site | --sit)+    ac_prev=site ;;+  -site=* | --site=* | --sit=*)+    site=$ac_optarg ;;++  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)+    ac_prev=srcdir ;;+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)+    srcdir=$ac_optarg ;;++  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \+  | --syscon | --sysco | --sysc | --sys | --sy)+    ac_prev=sysconfdir ;;+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)+    sysconfdir=$ac_optarg ;;++  -target | --target | --targe | --targ | --tar | --ta | --t)+    ac_prev=target_alias ;;+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)+    target_alias=$ac_optarg ;;++  -v | -verbose | --verbose | --verbos | --verbo | --verb)+    verbose=yes ;;++  -version | --version | --versio | --versi | --vers | -V)+    ac_init_version=: ;;++  -with-* | --with-*)+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=\$ac_optarg ;;++  -without-* | --without-*)+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=no ;;++  --x)+    # Obsolete; use --with-x.+    with_x=yes ;;++  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \+  | --x-incl | --x-inc | --x-in | --x-i)+    ac_prev=x_includes ;;+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)+    x_includes=$ac_optarg ;;++  -x-libraries | --x-libraries | --x-librarie | --x-librari \+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)+    ac_prev=x_libraries ;;+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)+    x_libraries=$ac_optarg ;;++  -*) as_fn_error $? "unrecognized option: \`$ac_option'+Try \`$0 --help' for more information"+    ;;++  *=*)+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`+    # Reject names that are not valid shell variable names.+    case $ac_envvar in #(+      '' | [0-9]* | *[!_$as_cr_alnum]* )+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;+    esac+    eval $ac_envvar=\$ac_optarg+    export $ac_envvar ;;++  *)+    # FIXME: should be removed in autoconf 3.0.+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"+    ;;++  esac+done++if test -n "$ac_prev"; then+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`+  as_fn_error $? "missing argument to $ac_option"+fi++if test -n "$ac_unrecognized_opts"; then+  case $enable_option_checking in+    no) ;;+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;+  esac+fi++# Check all directory arguments for consistency.+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \+		datadir sysconfdir sharedstatedir localstatedir includedir \+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \+		libdir localedir mandir+do+  eval ac_val=\$$ac_var+  # Remove trailing slashes.+  case $ac_val in+    */ )+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`+      eval $ac_var=\$ac_val;;+  esac+  # Be sure to have absolute directory names.+  case $ac_val in+    [\\/$]* | ?:[\\/]* )  continue;;+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;+  esac+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"+done++# There might be people who depend on the old broken behavior: `$host'+# used to hold the argument of --host etc.+# FIXME: To remove some day.+build=$build_alias+host=$host_alias+target=$target_alias++# FIXME: To remove some day.+if test "x$host_alias" != x; then+  if test "x$build_alias" = x; then+    cross_compiling=maybe+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.+    If a cross compiler is detected then cross compile mode will be used" >&2+  elif test "x$build_alias" != "x$host_alias"; then+    cross_compiling=yes+  fi+fi++ac_tool_prefix=+test -n "$host_alias" && ac_tool_prefix=$host_alias-++test "$silent" = yes && exec 6>/dev/null+++ac_pwd=`pwd` && test -n "$ac_pwd" &&+ac_ls_di=`ls -di .` &&+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||+  as_fn_error $? "working directory cannot be determined"+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||+  as_fn_error $? "pwd does not report name of working directory"+++# Find the source files, if location was not specified.+if test -z "$srcdir"; then+  ac_srcdir_defaulted=yes+  # Try the directory containing this script, then the parent directory.+  ac_confdir=`$as_dirname -- "$as_myself" ||+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_myself" : 'X\(//\)[^/]' \| \+	 X"$as_myself" : 'X\(//\)$' \| \+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_myself" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  srcdir=$ac_confdir+  if test ! -r "$srcdir/$ac_unique_file"; then+    srcdir=..+  fi+else+  ac_srcdir_defaulted=no+fi+if test ! -r "$srcdir/$ac_unique_file"; then+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"+fi+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"+ac_abs_confdir=`(+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"+	pwd)`+# When building in place, set srcdir=.+if test "$ac_abs_confdir" = "$ac_pwd"; then+  srcdir=.+fi+# Remove unnecessary trailing slashes from srcdir.+# Double slashes in file names in object file debugging info+# mess up M-x gdb in Emacs.+case $srcdir in+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;+esac+for ac_var in $ac_precious_vars; do+  eval ac_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_env_${ac_var}_value=\$${ac_var}+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_cv_env_${ac_var}_value=\$${ac_var}+done++#+# Report the --help message.+#+if test "$ac_init_help" = "long"; then+  # Omit some internal or obsolete options to make the list less imposing.+  # This message is too long to be a string in the A/UX 3.1 sh.+  cat <<_ACEOF+\`configure' configures this package to adapt to many kinds of systems.++Usage: $0 [OPTION]... [VAR=VALUE]...++To assign environment variables (e.g., CC, CFLAGS...), specify them as+VAR=VALUE.  See below for descriptions of some of the useful variables.++Defaults for the options are specified in brackets.++Configuration:+  -h, --help              display this help and exit+      --help=short        display options specific to this package+      --help=recursive    display the short help of all the included packages+  -V, --version           display version information and exit+  -q, --quiet, --silent   do not print \`checking ...' messages+      --cache-file=FILE   cache test results in FILE [disabled]+  -C, --config-cache      alias for \`--cache-file=config.cache'+  -n, --no-create         do not create output files+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']++Installation directories:+  --prefix=PREFIX         install architecture-independent files in PREFIX+                          [$ac_default_prefix]+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX+                          [PREFIX]++By default, \`make install' will install all the files in+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify+an installation prefix other than \`$ac_default_prefix' using \`--prefix',+for instance \`--prefix=\$HOME'.++For better control, use the options below.++Fine tuning of the installation directories:+  --bindir=DIR            user executables [EPREFIX/bin]+  --sbindir=DIR           system admin executables [EPREFIX/sbin]+  --libexecdir=DIR        program executables [EPREFIX/libexec]+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]+  --libdir=DIR            object code libraries [EPREFIX/lib]+  --includedir=DIR        C header files [PREFIX/include]+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]+  --infodir=DIR           info documentation [DATAROOTDIR/info]+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]+  --mandir=DIR            man documentation [DATAROOTDIR/man]+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]+  --htmldir=DIR           html documentation [DOCDIR]+  --dvidir=DIR            dvi documentation [DOCDIR]+  --pdfdir=DIR            pdf documentation [DOCDIR]+  --psdir=DIR             ps documentation [DOCDIR]+_ACEOF++  cat <<\_ACEOF+_ACEOF+fi++if test -n "$ac_init_help"; then++  cat <<\_ACEOF++Report bugs to the package provider.+_ACEOF+ac_status=$?+fi++if test "$ac_init_help" = "recursive"; then+  # If there are subdirs, report their specific --help.+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue+    test -d "$ac_dir" ||+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||+      continue+    ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix++    cd "$ac_dir" || { ac_status=$?; continue; }+    # Check for guested configure.+    if test -f "$ac_srcdir/configure.gnu"; then+      echo &&+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive+    elif test -f "$ac_srcdir/configure"; then+      echo &&+      $SHELL "$ac_srcdir/configure" --help=recursive+    else+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2+    fi || ac_status=$?+    cd "$ac_pwd" || { ac_status=$?; break; }+  done+fi++test -n "$ac_init_help" && exit $ac_status+if $ac_init_version; then+  cat <<\_ACEOF+configure+generated by GNU Autoconf 2.68++Copyright (C) 2010 Free Software Foundation, Inc.+This configure script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it.+_ACEOF+  exit+fi++## ------------------------ ##+## Autoconf initialization. ##+## ------------------------ ##+cat >config.log <<_ACEOF+This file contains any messages produced by compilers while+running configure, to aid debugging if configure makes a mistake.++It was created by $as_me, which was+generated by GNU Autoconf 2.68.  Invocation command line was++  $ $0 $@++_ACEOF+exec 5>>config.log+{+cat <<_ASUNAME+## --------- ##+## Platform. ##+## --------- ##++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`+uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`++/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`++_ASUNAME++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    $as_echo "PATH: $as_dir"+  done+IFS=$as_save_IFS++} >&5++cat >&5 <<_ACEOF+++## ----------- ##+## Core tests. ##+## ----------- ##++_ACEOF+++# Keep a trace of the command line.+# Strip out --no-create and --no-recursion so they do not pile up.+# Strip out --silent because we don't want to record it for future runs.+# Also quote any args containing shell meta-characters.+# Make two passes to allow for proper duplicate-argument suppression.+ac_configure_args=+ac_configure_args0=+ac_configure_args1=+ac_must_keep_next=false+for ac_pass in 1 2+do+  for ac_arg+  do+    case $ac_arg in+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \+    | -silent | --silent | --silen | --sile | --sil)+      continue ;;+    *\'*)+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;+    esac+    case $ac_pass in+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;+    2)+      as_fn_append ac_configure_args1 " '$ac_arg'"+      if test $ac_must_keep_next = true; then+	ac_must_keep_next=false # Got value, back to normal.+      else+	case $ac_arg in+	  *=* | --config-cache | -C | -disable-* | --disable-* \+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \+	  | -with-* | --with-* | -without-* | --without-* | --x)+	    case "$ac_configure_args0 " in+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;+	    esac+	    ;;+	  -* ) ac_must_keep_next=true ;;+	esac+      fi+      as_fn_append ac_configure_args " '$ac_arg'"+      ;;+    esac+  done+done+{ ac_configure_args0=; unset ac_configure_args0;}+{ ac_configure_args1=; unset ac_configure_args1;}++# When interrupted or exit'd, cleanup temporary files, and complete+# config.log.  We remove comments because anyway the quotes in there+# would cause problems or look ugly.+# WARNING: Use '\'' to represent an apostrophe within the trap.+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.+trap 'exit_status=$?+  # Save into config.log some information that might help in debugging.+  {+    echo++    $as_echo "## ---------------- ##+## Cache variables. ##+## ---------------- ##"+    echo+    # The following way of writing the cache mishandles newlines in values,+(+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done+  (set) 2>&1 |+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      sed -n \+	"s/'\''/'\''\\\\'\'''\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"+      ;; #(+    *)+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+)+    echo++    $as_echo "## ----------------- ##+## Output variables. ##+## ----------------- ##"+    echo+    for ac_var in $ac_subst_vars+    do+      eval ac_val=\$$ac_var+      case $ac_val in+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+      esac+      $as_echo "$ac_var='\''$ac_val'\''"+    done | sort+    echo++    if test -n "$ac_subst_files"; then+      $as_echo "## ------------------- ##+## File substitutions. ##+## ------------------- ##"+      echo+      for ac_var in $ac_subst_files+      do+	eval ac_val=\$$ac_var+	case $ac_val in+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+	esac+	$as_echo "$ac_var='\''$ac_val'\''"+      done | sort+      echo+    fi++    if test -s confdefs.h; then+      $as_echo "## ----------- ##+## confdefs.h. ##+## ----------- ##"+      echo+      cat confdefs.h+      echo+    fi+    test "$ac_signal" != 0 &&+      $as_echo "$as_me: caught signal $ac_signal"+    $as_echo "$as_me: exit $exit_status"+  } >&5+  rm -f core *.core core.conftest.* &&+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&+    exit $exit_status+' 0+for ac_signal in 1 2 13 15; do+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal+done+ac_signal=0++# confdefs.h avoids OS command line length limits that DEFS can exceed.+rm -f -r conftest* confdefs.h++$as_echo "/* confdefs.h */" > confdefs.h++# Predefined preprocessor variables.++cat >>confdefs.h <<_ACEOF+#define PACKAGE_NAME "$PACKAGE_NAME"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_VERSION "$PACKAGE_VERSION"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_STRING "$PACKAGE_STRING"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_URL "$PACKAGE_URL"+_ACEOF+++# Let the site file select an alternate cache file if it wants to.+# Prefer an explicitly selected file to automatically selected ones.+ac_site_file1=NONE+ac_site_file2=NONE+if test -n "$CONFIG_SITE"; then+  # We do not want a PATH search for config.site.+  case $CONFIG_SITE in #((+    -*)  ac_site_file1=./$CONFIG_SITE;;+    */*) ac_site_file1=$CONFIG_SITE;;+    *)   ac_site_file1=./$CONFIG_SITE;;+  esac+elif test "x$prefix" != xNONE; then+  ac_site_file1=$prefix/share/config.site+  ac_site_file2=$prefix/etc/config.site+else+  ac_site_file1=$ac_default_prefix/share/config.site+  ac_site_file2=$ac_default_prefix/etc/config.site+fi+for ac_site_file in "$ac_site_file1" "$ac_site_file2"+do+  test "x$ac_site_file" = xNONE && continue+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5+$as_echo "$as_me: loading site script $ac_site_file" >&6;}+    sed 's/^/| /' "$ac_site_file" >&5+    . "$ac_site_file" \+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "failed to load site script $ac_site_file+See \`config.log' for more details" "$LINENO" 5; }+  fi+done++if test -r "$cache_file"; then+  # Some versions of bash will fail to source /dev/null (special files+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5+$as_echo "$as_me: loading cache $cache_file" >&6;}+    case $cache_file in+      [\\/]* | ?:[\\/]* ) . "$cache_file";;+      *)                      . "./$cache_file";;+    esac+  fi+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5+$as_echo "$as_me: creating cache $cache_file" >&6;}+  >$cache_file+fi++# Check that the precious variables saved in the cache have kept the same+# value.+ac_cache_corrupted=false+for ac_var in $ac_precious_vars; do+  eval ac_old_set=\$ac_cv_env_${ac_var}_set+  eval ac_new_set=\$ac_env_${ac_var}_set+  eval ac_old_val=\$ac_cv_env_${ac_var}_value+  eval ac_new_val=\$ac_env_${ac_var}_value+  case $ac_old_set,$ac_new_set in+    set,)+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,set)+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,);;+    *)+      if test "x$ac_old_val" != "x$ac_new_val"; then+	# differences in whitespace do not lead to failure.+	ac_old_val_w=`echo x $ac_old_val`+	ac_new_val_w=`echo x $ac_new_val`+	if test "$ac_old_val_w" != "$ac_new_val_w"; then+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}+	  ac_cache_corrupted=:+	else+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}+	  eval $ac_var=\$ac_old_val+	fi+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}+      fi;;+  esac+  # Pass precious variables to config.status.+  if test "$ac_new_set" = set; then+    case $ac_new_val in+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;+    *) ac_arg=$ac_var=$ac_new_val ;;+    esac+    case " $ac_configure_args " in+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;+    esac+  fi+done+if $ac_cache_corrupted; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5+fi+## -------------------- ##+## Main body of script. ##+## -------------------- ##++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++# Check for Ocaml compilers++# we first look for ocamlc in the path; if not present, we fail+# Extract the first word of "ocamlc", so it can be a program name with args.+set dummy ocamlc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLC"; then+  ac_cv_prog_OCAMLC="$OCAMLC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLC="ocamlc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLC" && ac_cv_prog_OCAMLC="no"+fi+fi+OCAMLC=$ac_cv_prog_OCAMLC+if test -n "$OCAMLC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLC" >&5+$as_echo "$OCAMLC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLC" = no ; then+	as_fn_error $? "Cannot find ocamlc." "$LINENO" 5+fi++# we extract Ocaml version number and library path+OCAMLVERSION=`$OCAMLC -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+echo "ocaml version is $OCAMLVERSION"++case $OCAMLVERSION in+  0.*|1.*|2.*|3.00*|3.01*|3.02*|3.03*|3.04*|3.05*|3.06*|3.07*)+        as_fn_error $? "ocamlgraph needs ocaml version 3.08.0 or higher" "$LINENO" 5;;+  3.08*)+	FORPACK="";;+  *)+	FORPACK="-for-pack Graph";;+esac++# OCAMLLIB=`$OCAMLC -v | tail -n 1 | cut -f 4 -d " "`+# OCAMLLIB=`$OCAMLC -v | tail -n 1 | sed -e 's|[[^:]]*: \(.*\)|\1|' `+OCAMLLIB=`$OCAMLC -where`+echo "ocaml library path is $OCAMLLIB"++# then we look for ocamlopt; if not present, we issue a warning+# if the version is not the same, we also discard it+# we set OCAMLBEST to "opt" or "byte", whether ocamlopt is available or not+# Extract the first word of "ocamlopt", so it can be a program name with args.+set dummy ocamlopt; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLOPT+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLOPT"; then+  ac_cv_prog_OCAMLOPT="$OCAMLOPT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLOPT="ocamlopt"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLOPT" && ac_cv_prog_OCAMLOPT="no"+fi+fi+OCAMLOPT=$ac_cv_prog_OCAMLOPT+if test -n "$OCAMLOPT"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPT" >&5+$as_echo "$OCAMLOPT" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++OCAMLBEST=byte+if test "$OCAMLOPT" = no ; then+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamlopt; bytecode compilation only." >&5+$as_echo "$as_me: WARNING: Cannot find ocamlopt; bytecode compilation only." >&2;}+else+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlopt version" >&5+$as_echo_n "checking ocamlopt version... " >&6; }+	TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVERSION" != "$OCAMLVERSION" ; then+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt discarded." >&5+$as_echo "differs from ocamlc; ocamlopt discarded." >&6; }+	    OCAMLOPT=no+	else+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5+$as_echo "ok" >&6; }+	    OCAMLBEST=opt+	fi+fi++# checking for ocamlc.opt+# Extract the first word of "ocamlc.opt", so it can be a program name with args.+set dummy ocamlc.opt; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLCDOTOPT+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLCDOTOPT"; then+  ac_cv_prog_OCAMLCDOTOPT="$OCAMLCDOTOPT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLCDOTOPT="ocamlc.opt"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLCDOTOPT" && ac_cv_prog_OCAMLCDOTOPT="no"+fi+fi+OCAMLCDOTOPT=$ac_cv_prog_OCAMLCDOTOPT+if test -n "$OCAMLCDOTOPT"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLCDOTOPT" >&5+$as_echo "$OCAMLCDOTOPT" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLCDOTOPT" != no ; then+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5+$as_echo_n "checking ocamlc.opt version... " >&6; }+	TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVERSION" != "$OCAMLVERSION" ; then+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlc.opt discarded." >&5+$as_echo "differs from ocamlc; ocamlc.opt discarded." >&6; }+	else+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5+$as_echo "ok" >&6; }+	    OCAMLC=$OCAMLCDOTOPT+	fi+fi++# checking for ocamlopt.opt+if test "$OCAMLOPT" != no ; then+    # Extract the first word of "ocamlopt.opt", so it can be a program name with args.+set dummy ocamlopt.opt; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLOPTDOTOPT+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLOPTDOTOPT"; then+  ac_cv_prog_OCAMLOPTDOTOPT="$OCAMLOPTDOTOPT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLOPTDOTOPT="ocamlopt.opt"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLOPTDOTOPT" && ac_cv_prog_OCAMLOPTDOTOPT="no"+fi+fi+OCAMLOPTDOTOPT=$ac_cv_prog_OCAMLOPTDOTOPT+if test -n "$OCAMLOPTDOTOPT"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPTDOTOPT" >&5+$as_echo "$OCAMLOPTDOTOPT" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++    if test "$OCAMLOPTDOTOPT" != no ; then+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5+$as_echo_n "checking ocamlc.opt version... " >&6; }+	TMPVER=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVER" != "$OCAMLVERSION" ; then+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt.opt discarded." >&5+$as_echo "differs from ocamlc; ocamlopt.opt discarded." >&6; }+	else+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5+$as_echo "ok" >&6; }+	    OCAMLOPT=$OCAMLOPTDOTOPT+	fi+    fi+fi++# ocamldep, ocamllex and ocamlyacc should also be present in the path+# Extract the first word of "ocamldep", so it can be a program name with args.+set dummy ocamldep; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLDEP+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLDEP"; then+  ac_cv_prog_OCAMLDEP="$OCAMLDEP" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLDEP="ocamldep"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLDEP" && ac_cv_prog_OCAMLDEP="no"+fi+fi+OCAMLDEP=$ac_cv_prog_OCAMLDEP+if test -n "$OCAMLDEP"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDEP" >&5+$as_echo "$OCAMLDEP" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLDEP" = no ; then+	as_fn_error $? "Cannot find ocamldep." "$LINENO" 5+fi++# Extract the first word of "ocamllex", so it can be a program name with args.+set dummy ocamllex; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLLEX+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLLEX"; then+  ac_cv_prog_OCAMLLEX="$OCAMLLEX" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLLEX="ocamllex"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLLEX" && ac_cv_prog_OCAMLLEX="no"+fi+fi+OCAMLLEX=$ac_cv_prog_OCAMLLEX+if test -n "$OCAMLLEX"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLLEX" >&5+$as_echo "$OCAMLLEX" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLLEX" = no ; then+    as_fn_error $? "Cannot find ocamllex." "$LINENO" 5+else+    # Extract the first word of "ocamllex.opt", so it can be a program name with args.+set dummy ocamllex.opt; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLLEXDOTOPT+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLLEXDOTOPT"; then+  ac_cv_prog_OCAMLLEXDOTOPT="$OCAMLLEXDOTOPT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLLEXDOTOPT="ocamllex.opt"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLLEXDOTOPT" && ac_cv_prog_OCAMLLEXDOTOPT="no"+fi+fi+OCAMLLEXDOTOPT=$ac_cv_prog_OCAMLLEXDOTOPT+if test -n "$OCAMLLEXDOTOPT"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLLEXDOTOPT" >&5+$as_echo "$OCAMLLEXDOTOPT" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++    if test "$OCAMLLEXDOTOPT" != no ; then+	OCAMLLEX=$OCAMLLEXDOTOPT+    fi+fi++# Extract the first word of "ocamlyacc", so it can be a program name with args.+set dummy ocamlyacc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLYACC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLYACC"; then+  ac_cv_prog_OCAMLYACC="$OCAMLYACC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLYACC="ocamlyacc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLYACC" && ac_cv_prog_OCAMLYACC="no"+fi+fi+OCAMLYACC=$ac_cv_prog_OCAMLYACC+if test -n "$OCAMLYACC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLYACC" >&5+$as_echo "$OCAMLYACC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLYACC" = no ; then+	as_fn_error $? "Cannot find ocamlyacc." "$LINENO" 5+fi++# Extract the first word of "ocamldoc", so it can be a program name with args.+set dummy ocamldoc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLDOC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLDOC"; then+  ac_cv_prog_OCAMLDOC="$OCAMLDOC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLDOC="ocamldoc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLDOC" && ac_cv_prog_OCAMLDOC="true"+fi+fi+OCAMLDOC=$ac_cv_prog_OCAMLDOC+if test -n "$OCAMLDOC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDOC" >&5+$as_echo "$OCAMLDOC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$OCAMLDOC" = true ; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamldoc" >&5+$as_echo "$as_me: WARNING: Cannot find ocamldoc" >&2;}+else+    # Extract the first word of "ocamldoc.opt", so it can be a program name with args.+set dummy ocamldoc.opt; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLDOCOPT+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLDOCOPT"; then+  ac_cv_prog_OCAMLDOCOPT="$OCAMLDOCOPT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLDOCOPT="ocamldoc.opt"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLDOCOPT" && ac_cv_prog_OCAMLDOCOPT="no"+fi+fi+OCAMLDOCOPT=$ac_cv_prog_OCAMLDOCOPT+if test -n "$OCAMLDOCOPT"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDOCOPT" >&5+$as_echo "$OCAMLDOCOPT" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++    if test "$OCAMLDOCOPT" != no ; then+	OCAMLDOC=$OCAMLDOCOPT+    fi+fi++# Extract the first word of "ocamlweb", so it can be a program name with args.+set dummy ocamlweb; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLWEB+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLWEB"; then+  ac_cv_prog_OCAMLWEB="$OCAMLWEB" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLWEB="ocamlweb"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_OCAMLWEB" && ac_cv_prog_OCAMLWEB="true"+fi+fi+OCAMLWEB=$ac_cv_prog_OCAMLWEB+if test -n "$OCAMLWEB"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLWEB" >&5+$as_echo "$OCAMLWEB" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi++++# Extract the first word of "ocamlfind", so it can be a program name with args.+set dummy ocamlfind; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_OCAMLFIND+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$OCAMLFIND"; then+  ac_cv_prog_OCAMLFIND="$OCAMLFIND" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_OCAMLFIND="ocamlfind"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+OCAMLFIND=$ac_cv_prog_OCAMLFIND+if test -n "$OCAMLFIND"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLFIND" >&5+$as_echo "$OCAMLFIND" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi++++# checking for lablgtk2+# Extract the first word of "lablgtk2", so it can be a program name with args.+set dummy lablgtk2; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_LABLGTK2+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$LABLGTK2"; then+  ac_cv_prog_LABLGTK2="$LABLGTK2" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+    ac_cv_prog_LABLGTK2="yes"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_LABLGTK2" && ac_cv_prog_LABLGTK2="no"+fi+fi+LABLGTK2=$ac_cv_prog_LABLGTK2+if test -n "$LABLGTK2"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LABLGTK2" >&5+$as_echo "$LABLGTK2" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++if test "$LABLGTK2" = yes ; then+   if test -d "$OCAMLLIB/lablgtk2" ; then+      INCLUDEGTK2="-I +lablgtk2"+   else+      LABLGTK2=no+   fi+fi++# platform+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Win32 platform" >&5+$as_echo_n "checking Win32 platform... " >&6; }+if echo "let _ = Sys.os_type;;" | ocaml | grep -q Win32; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5+$as_echo "yes" >&6; }+    OCAMLWIN32=yes+    EXE=.exe+    LIBEXT=.lib+    OBJEXT=.obj+else+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+    OCAMLWIN32=no+    EXE=+    LIBEXT=.a+    OBJEXT=.o+fi++# substitutions to perform+++++++++++++++++++# Finally create the Makefile from Makefile.in+ac_config_files="$ac_config_files Makefile"++cat >confcache <<\_ACEOF+# This file is a shell script that caches the results of configure+# tests run on this system so they can be shared between configure+# scripts and configure runs, see configure's option --config-cache.+# It is not useful on other systems.  If it contains results you don't+# want to keep, you may remove or edit it.+#+# config.status only pays attention to the cache file if you give it+# the --recheck option to rerun configure.+#+# `ac_cv_env_foo' variables (set or unset) will be overridden when+# loading this file, other *unset* `ac_cv_foo' will be assigned the+# following values.++_ACEOF++# The following way of writing the cache mishandles newlines in values,+# but we know of no workaround that is simple, portable, and efficient.+# So, we kill variables containing newlines.+# Ultrix sh set writes to stderr and can't be redirected directly,+# and sets the high bit in the cache file unless we assign to the vars.+(+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done++  (set) 2>&1 |+    case $as_nl`(ac_space=' '; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      # `set' does not quote correctly, so add quotes: double-quote+      # substitution turns \\\\ into \\, and sed turns \\ into \.+      sed -n \+	"s/'/'\\\\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"+      ;; #(+    *)+      # `set' quotes correctly as required by POSIX, so do not add quotes.+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+) |+  sed '+     /^ac_cv_env_/b end+     t clear+     :clear+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/+     t end+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/+     :end' >>confcache+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else+  if test -w "$cache_file"; then+    if test "x$cache_file" != "x/dev/null"; then+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5+$as_echo "$as_me: updating cache $cache_file" >&6;}+      if test ! -f "$cache_file" || test -h "$cache_file"; then+	cat confcache >"$cache_file"+      else+        case $cache_file in #(+        */* | ?:*)+	  mv -f confcache "$cache_file"$$ &&+	  mv -f "$cache_file"$$ "$cache_file" ;; #(+        *)+	  mv -f confcache "$cache_file" ;;+	esac+      fi+    fi+  else+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}+  fi+fi+rm -f confcache++test "x$prefix" = xNONE && prefix=$ac_default_prefix+# Let make expand exec_prefix.+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'++# Transform confdefs.h into DEFS.+# Protect against shell expansion while executing Makefile rules.+# Protect against Makefile macro expansion.+#+# If the first sed substitution is executed (which looks for macros that+# take arguments), then branch to the quote section.  Otherwise,+# look for a macro that doesn't take arguments.+ac_script='+:mline+/\\$/{+ N+ s,\\\n,,+ b mline+}+t clear+:clear+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g+t quote+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g+t quote+b any+:quote+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g+s/\[/\\&/g+s/\]/\\&/g+s/\$/$$/g+H+:any+${+	g+	s/^\n//+	s/\n/ /g+	p+}+'+DEFS=`sed -n "$ac_script" confdefs.h`+++ac_libobjs=+ac_ltlibobjs=+U=+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue+  # 1. Remove the extension, and $U if already installed.+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR+  #    will be set to the directory where LIBOBJS objects are built.+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'+done+LIBOBJS=$ac_libobjs++LTLIBOBJS=$ac_ltlibobjs++++: "${CONFIG_STATUS=./config.status}"+ac_write_fail=0+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files $CONFIG_STATUS"+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}+as_write_fail=0+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1+#! $SHELL+# Generated by $as_me.+# Run this file to recreate the current configuration.+# Compiler output produced by configure, useful for debugging+# configure, is in config.log if it exists.++debug=false+ac_cs_recheck=false+ac_cs_silent=false++SHELL=\${CONFIG_SHELL-$SHELL}+export SHELL+_ASEOF+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else+  case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+# Prefer a ksh shell builtin over an external printf program on Solaris,+# but without wasting forks for bash or zsh.+if test -z "$BASH_VERSION$ZSH_VERSION" \+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='print -r --'+  as_echo_n='print -rn --'+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='printf %s\n'+  as_echo_n='printf %s'+else+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+    as_echo_n='/usr/ucb/echo -n'+  else+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+    as_echo_n_body='eval+      arg=$1;+      case $arg in #(+      *"$as_nl"*)+	expr "X$arg" : "X\\(.*\\)$as_nl";+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+      esac;+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+    '+    export as_echo_n_body+    as_echo_n='sh -c $as_echo_n_body as_echo'+  fi+  export as_echo_body+  as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# IFS+# We need space, tab and new line, in precisely that order.  Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" ""	$as_nl"++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi++# Unset variables that we do not need and which cause bugs (e.g. in+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"+# suppresses any "Segmentation fault" message there.  '((' could+# trigger a bug in pdksh 5.2.14.+for as_var in BASH_ENV ENV MAIL MAILPATH+do eval test x\${$as_var+set} = xset \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# CDPATH.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH+++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  $as_echo "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error+++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset+# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else+  as_fn_append ()+  {+    eval $1=\$$1\$2+  }+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else+  as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  }+fi # as_fn_arith+++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+    # In both cases, we have to default to `cp -p'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -p'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -p'+  fi+else+  as_ln_s='cp -p'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null+++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p+if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi++if test -x / >/dev/null 2>&1; then+  as_test_x='test -x'+else+  if ls -dL / >/dev/null 2>&1; then+    as_ls_L_option=L+  else+    as_ls_L_option=+  fi+  as_test_x='+    eval sh -c '\''+      if test -d "$1"; then+	test -d "$1/.";+      else+	case $1 in #(+	-*)set "./$1";;+	esac;+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((+	???[sx]*):;;*)false;;esac;fi+    '\'' sh+  '+fi+as_executable_p=$as_test_x++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"+++exec 6>&1+## ----------------------------------- ##+## Main body of $CONFIG_STATUS script. ##+## ----------------------------------- ##+_ASEOF+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# Save the log message, to keep $0 and so on meaningful, and to+# report actual input values of CONFIG_FILES etc. instead of their+# values after options handling.+ac_log="+This file was extended by $as_me, which was+generated by GNU Autoconf 2.68.  Invocation command line was++  CONFIG_FILES    = $CONFIG_FILES+  CONFIG_HEADERS  = $CONFIG_HEADERS+  CONFIG_LINKS    = $CONFIG_LINKS+  CONFIG_COMMANDS = $CONFIG_COMMANDS+  $ $0 $@++on `(hostname || uname -n) 2>/dev/null | sed 1q`+"++_ACEOF++case $ac_config_files in *"+"*) set x $ac_config_files; shift; ac_config_files=$*;;+esac++++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+# Files that config.status was made for.+config_files="$ac_config_files"++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+ac_cs_usage="\+\`$as_me' instantiates files and other configuration actions+from templates according to the current configuration.  Unless the files+and actions are specified as TAGs, all are instantiated by default.++Usage: $0 [OPTION]... [TAG]...++  -h, --help       print this help, then exit+  -V, --version    print version number and configuration settings, then exit+      --config     print configuration, then exit+  -q, --quiet, --silent+                   do not print progress messages+  -d, --debug      don't remove temporary files+      --recheck    update $as_me by reconfiguring in the same conditions+      --file=FILE[:TEMPLATE]+                   instantiate the configuration file FILE++Configuration files:+$config_files++Report bugs to the package provider."++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"+ac_cs_version="\\+config.status+configured by $0, generated by GNU Autoconf 2.68,+  with options \\"\$ac_cs_config\\"++Copyright (C) 2010 Free Software Foundation, Inc.+This config.status script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it."++ac_pwd='$ac_pwd'+srcdir='$srcdir'+test -n "\$AWK" || AWK=awk+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# The default lists apply if the user does not specify any file.+ac_need_defaults=:+while test $# != 0+do+  case $1 in+  --*=?*)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`+    ac_shift=:+    ;;+  --*=)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=+    ac_shift=:+    ;;+  *)+    ac_option=$1+    ac_optarg=$2+    ac_shift=shift+    ;;+  esac++  case $ac_option in+  # Handling of the options.+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)+    ac_cs_recheck=: ;;+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )+    $as_echo "$ac_cs_version"; exit ;;+  --config | --confi | --conf | --con | --co | --c )+    $as_echo "$ac_cs_config"; exit ;;+  --debug | --debu | --deb | --de | --d | -d )+    debug=: ;;+  --file | --fil | --fi | --f )+    $ac_shift+    case $ac_optarg in+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+    '') as_fn_error $? "missing file argument" ;;+    esac+    as_fn_append CONFIG_FILES " '$ac_optarg'"+    ac_need_defaults=false;;+  --he | --h |  --help | --hel | -h )+    $as_echo "$ac_cs_usage"; exit ;;+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil | --si | --s)+    ac_cs_silent=: ;;++  # This is an error.+  -*) as_fn_error $? "unrecognized option: \`$1'+Try \`$0 --help' for more information." ;;++  *) as_fn_append ac_config_targets " $1"+     ac_need_defaults=false ;;++  esac+  shift+done++ac_configure_extra_args=++if $ac_cs_silent; then+  exec 6>/dev/null+  ac_configure_extra_args="$ac_configure_extra_args --silent"+fi++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+if \$ac_cs_recheck; then+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion+  shift+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6+  CONFIG_SHELL='$SHELL'+  export CONFIG_SHELL+  exec "\$@"+fi++_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+exec 5>>config.log+{+  echo+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX+## Running $as_me. ##+_ASBOX+  $as_echo "$ac_log"+} >&5++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1++# Handling of arguments.+for ac_config_target in $ac_config_targets+do+  case $ac_config_target in+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;++  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;+  esac+done+++# If the user did not use the arguments to specify the items to instantiate,+# then the envvar interface is used.  Set only those that are not.+# We use the long form for the default assignment because of an extremely+# bizarre bug on SunOS 4.1.3.+if $ac_need_defaults; then+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files+fi++# Have a temporary directory for convenience.  Make it in the build tree+# simply because there is no reason against having it here, and in addition,+# creating and moving files from /tmp can sometimes cause problems.+# Hook for its removal unless debugging.+# Note that there is a small window in which the directory will not be cleaned:+# after its creation but before its name has been assigned to `$tmp'.+$debug ||+{+  tmp= ac_tmp=+  trap 'exit_status=$?+  : "${ac_tmp:=$tmp}"+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status+' 0+  trap 'as_fn_exit 1' 1 2 13 15+}+# Create a (secure) tmp directory for tmp files.++{+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&+  test -d "$tmp"+}  ||+{+  tmp=./conf$$-$RANDOM+  (umask 077 && mkdir "$tmp")+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5+ac_tmp=$tmp++# Set up the scripts for CONFIG_FILES section.+# No need to generate them if there are no CONFIG_FILES.+# This happens for instance with `./config.status config.h'.+if test -n "$CONFIG_FILES"; then+++ac_cr=`echo X | tr X '\015'`+# On cygwin, bash can eat \r inside `` if the user requested igncr.+# But we know of no other shell where ac_cr would be empty at this+# point, so we can use a bashism as a fallback.+if test "x$ac_cr" = x; then+  eval ac_cr=\$\'\\r\'+fi+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then+  ac_cs_awk_cr='\\r'+else+  ac_cs_awk_cr=$ac_cr+fi++echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&+_ACEOF+++{+  echo "cat >conf$$subs.awk <<_ACEOF" &&+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&+  echo "_ACEOF"+} >conf$$subs.sh ||+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`+ac_delim='%!_!# '+for ac_last_try in false false false false false :; do+  . ./conf$$subs.sh ||+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5++  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`+  if test $ac_delim_n = $ac_delim_num; then+    break+  elif $ac_last_try; then+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+  else+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+  fi+done+rm -f conf$$subs.sh++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&+_ACEOF+sed -n '+h+s/^/S["/; s/!.*/"]=/+p+g+s/^[^!]*!//+:repl+t repl+s/'"$ac_delim"'$//+t delim+:nl+h+s/\(.\{148\}\)..*/\1/+t more1+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/+p+n+b repl+:more1+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t nl+:delim+h+s/\(.\{148\}\)..*/\1/+t more2+s/["\\]/\\&/g; s/^/"/; s/$/"/+p+b+:more2+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t delim+' <conf$$subs.awk | sed '+/^[^""]/{+  N+  s/\n//+}+' >>$CONFIG_STATUS || ac_write_fail=1+rm -f conf$$subs.awk+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACAWK+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&+  for (key in S) S_is_set[key] = 1+  FS = ""++}+{+  line = $ 0+  nfields = split(line, field, "@")+  substed = 0+  len = length(field[1])+  for (i = 2; i < nfields; i++) {+    key = field[i]+    keylen = length(key)+    if (S_is_set[key]) {+      value = S[key]+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)+      len += length(value) + length(field[++i])+      substed = 1+    } else+      len += 1 + keylen+  }++  print line+}++_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"+else+  cat+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5+_ACEOF++# VPATH may cause trouble with some makes, so we remove sole $(srcdir),+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and+# trailing colons and then remove the whole line if VPATH becomes empty+# (actually we leave an empty line to preserve line numbers).+if test "x$srcdir" = x.; then+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{+h+s///+s/^/:/+s/[	 ]*$/:/+s/:\$(srcdir):/:/g+s/:\${srcdir}:/:/g+s/:@srcdir@:/:/g+s/^:*//+s/:*$//+x+s/\(=[	 ]*\).*/\1/+G+s/\n//+s/^[^=]*=[	 ]*$//+}'+fi++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+fi # test -n "$CONFIG_FILES"+++eval set X "  :F $CONFIG_FILES      "+shift+for ac_tag+do+  case $ac_tag in+  :[FHLC]) ac_mode=$ac_tag; continue;;+  esac+  case $ac_mode$ac_tag in+  :[FHL]*:*);;+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;+  :[FH]-) ac_tag=-:-;;+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;+  esac+  ac_save_IFS=$IFS+  IFS=:+  set x $ac_tag+  IFS=$ac_save_IFS+  shift+  ac_file=$1+  shift++  case $ac_mode in+  :L) ac_source=$1;;+  :[FH])+    ac_file_inputs=+    for ac_f+    do+      case $ac_f in+      -) ac_f="$ac_tmp/stdin";;+      *) # Look for the file first in the build tree, then in the source tree+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,+	 # because $ac_f cannot contain `:'.+	 test -f "$ac_f" ||+	   case $ac_f in+	   [\\/$]*) false;;+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;+	   esac ||+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;+      esac+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac+      as_fn_append ac_file_inputs " '$ac_f'"+    done++    # Let's still pretend it is `configure' which instantiates (i.e., don't+    # use $as_me), people would be surprised to read:+    #    /* config.h.  Generated by config.status.  */+    configure_input='Generated from '`+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'+	`' by configure.'+    if test x"$ac_file" != x-; then+      configure_input="$ac_file.  $configure_input"+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5+$as_echo "$as_me: creating $ac_file" >&6;}+    fi+    # Neutralize special characters interpreted by sed in replacement strings.+    case $configure_input in #(+    *\&* | *\|* | *\\* )+       ac_sed_conf_input=`$as_echo "$configure_input" |+       sed 's/[\\\\&|]/\\\\&/g'`;; #(+    *) ac_sed_conf_input=$configure_input;;+    esac++    case $ac_tag in+    *:-:* | *:-) cat >"$ac_tmp/stdin" \+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;+    esac+    ;;+  esac++  ac_dir=`$as_dirname -- "$ac_file" ||+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$ac_file" : 'X\(//\)[^/]' \| \+	 X"$ac_file" : 'X\(//\)$' \| \+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$ac_file" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  as_dir="$ac_dir"; as_fn_mkdir_p+  ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix+++  case $ac_mode in+  :F)+  #+  # CONFIG_FILE+  #++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# If the template does not know about datarootdir, expand it.+# FIXME: This hack should be removed a few years after 2.60.+ac_datarootdir_hack=; ac_datarootdir_seen=+ac_sed_dataroot='+/datarootdir/ {+  p+  q+}+/@datadir@/p+/@docdir@/p+/@infodir@/p+/@localedir@/p+/@mandir@/p'+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in+*datarootdir*) ac_datarootdir_seen=yes;;+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}+_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+  ac_datarootdir_hack='+  s&@datadir@&$datadir&g+  s&@docdir@&$docdir&g+  s&@infodir@&$infodir&g+  s&@localedir@&$localedir&g+  s&@mandir@&$mandir&g+  s&\\\${datarootdir}&$datarootdir&g' ;;+esac+_ACEOF++# Neutralize VPATH when `$srcdir' = `.'.+# Shell code in configure.ac might set extrasub.+# FIXME: do we really want to maintain this feature?+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_sed_extra="$ac_vpsub+$extrasub+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+:t+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b+s|@configure_input@|$ac_sed_conf_input|;t t+s&@top_builddir@&$ac_top_builddir_sub&;t t+s&@top_build_prefix@&$ac_top_build_prefix&;t t+s&@srcdir@&$ac_srcdir&;t t+s&@abs_srcdir@&$ac_abs_srcdir&;t t+s&@top_srcdir@&$ac_top_srcdir&;t t+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t+s&@builddir@&$ac_builddir&;t t+s&@abs_builddir@&$ac_abs_builddir&;t t+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t+$ac_datarootdir_hack+"+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \+      "$ac_tmp/out"`; test -z "$ac_out"; } &&+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined.  Please make sure it is defined" >&5+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined.  Please make sure it is defined" >&2;}++  rm -f "$ac_tmp/stdin"+  case $ac_file in+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;+  esac \+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5+ ;;++++  esac++done # for ac_tag+++as_fn_exit 0+_ACEOF+ac_clean_files=$ac_clean_files_save++test $ac_write_fail = 0 ||+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5+++# configure is writing to config.log, and then calls config.status.+# config.status does its own redirection, appending to config.log.+# Unfortunately, on DOS this fails, as config.log is still kept open+# by configure, so config.status won't be able to write to it; its+# output is simply discarded.  So we exec the FD to /dev/null,+# effectively closing config.log, so it can be properly (re)opened and+# appended to by config.status.  When coming back to configure, we+# need to make the FD available again.+if test "$no_create" != yes; then+  ac_cs_success=:+  ac_config_status_args=+  test "$silent" = yes &&+    ac_config_status_args="$ac_config_status_args --quiet"+  exec 5>/dev/null+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false+  exec 5>>config.log+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which+  # would make configure fail if this is the last instruction.+  $ac_cs_success || as_fn_exit 1+fi+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}+fi++chmod a-w Makefile
+ external/ocamlgraph/configure.in view
@@ -0,0 +1,193 @@+##########################################################################+#                                                                        #+#  Ocamlgraph: a generic graph library for OCaml                         #+#  Copyright (C) 2004-2007                                               #+#  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        #+#                                                                        #+#  This software is free software; you can redistribute it and/or        #+#  modify it under the terms of the GNU Library General Public           #+#  License version 2, with the special exception on linking              #+#  described in file LICENSE.                                            #+#                                                                        #+#  This software is distributed in the hope that it will be useful,      #+#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  #+#                                                                        #+##########################################################################++# the script generated by autoconf from this input will set the following+# variables:+#   OCAMLC        "ocamlc" if present in the path, or a failure+#                 or "ocamlc.opt" if present with same version number as ocamlc+#   OCAMLOPT      "ocamlopt" (or "ocamlopt.opt" if present), or "no"+#   OCAMLBEST     either "byte" if no native compiler was found, +#                 or "opt" otherwise+#   OCAMLDEP      "ocamldep"+#   OCAMLLEX      "ocamllex" (or "ocamllex.opt" if present)+#   OCAMLYACC     "ocamlyac"+#   OCAMLLIB      the path to the ocaml standard library+#   OCAMLVERSION  the ocaml version number+#   OCAMLWEB      "ocamlweb" (not mandatory)+#   OCAMLWIN32    "yes"/"no" depending on Sys.os_type = "Win32"+#   EXE           ".exe" if OCAMLWIN32=yes, "" otherwise++# check for one particular file of the sources +# ADAPT THE FOLLOWING LINE TO YOUR SOURCES!+AC_INIT(src/sig.mli)++# Check for Ocaml compilers++# we first look for ocamlc in the path; if not present, we fail+AC_CHECK_PROG(OCAMLC,ocamlc,ocamlc,no)+if test "$OCAMLC" = no ; then+	AC_MSG_ERROR(Cannot find ocamlc.)+fi++# we extract Ocaml version number and library path+OCAMLVERSION=`$OCAMLC -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+echo "ocaml version is $OCAMLVERSION"++case $OCAMLVERSION in+  0.*|1.*|2.*|3.00*|3.01*|3.02*|3.03*|3.04*|3.05*|3.06*|3.07*)+        AC_MSG_ERROR(ocamlgraph needs ocaml version 3.08.0 or higher);;+  3.08*)+	FORPACK="";;+  *)+	FORPACK="-for-pack Graph";;+esac++# OCAMLLIB=`$OCAMLC -v | tail -n 1 | cut -f 4 -d " "`+# OCAMLLIB=`$OCAMLC -v | tail -n 1 | sed -e 's|[[^:]]*: \(.*\)|\1|' `+OCAMLLIB=`$OCAMLC -where`+echo "ocaml library path is $OCAMLLIB"++# then we look for ocamlopt; if not present, we issue a warning+# if the version is not the same, we also discard it+# we set OCAMLBEST to "opt" or "byte", whether ocamlopt is available or not+AC_CHECK_PROG(OCAMLOPT,ocamlopt,ocamlopt,no)+OCAMLBEST=byte+if test "$OCAMLOPT" = no ; then+	AC_MSG_WARN(Cannot find ocamlopt; bytecode compilation only.)+else+	AC_MSG_CHECKING(ocamlopt version)+	TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVERSION" != "$OCAMLVERSION" ; then+	    AC_MSG_RESULT(differs from ocamlc; ocamlopt discarded.)+	    OCAMLOPT=no+	else+	    AC_MSG_RESULT(ok)+	    OCAMLBEST=opt+	fi+fi++# checking for ocamlc.opt+AC_CHECK_PROG(OCAMLCDOTOPT,ocamlc.opt,ocamlc.opt,no)+if test "$OCAMLCDOTOPT" != no ; then+	AC_MSG_CHECKING(ocamlc.opt version)+	TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVERSION" != "$OCAMLVERSION" ; then+	    AC_MSG_RESULT(differs from ocamlc; ocamlc.opt discarded.)+	else+	    AC_MSG_RESULT(ok)+	    OCAMLC=$OCAMLCDOTOPT+	fi+fi++# checking for ocamlopt.opt+if test "$OCAMLOPT" != no ; then+    AC_CHECK_PROG(OCAMLOPTDOTOPT,ocamlopt.opt,ocamlopt.opt,no)+    if test "$OCAMLOPTDOTOPT" != no ; then+	AC_MSG_CHECKING(ocamlc.opt version)+	TMPVER=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version *\(.*\)$|\1|p' `+	if test "$TMPVER" != "$OCAMLVERSION" ; then+	    AC_MSG_RESULT(differs from ocamlc; ocamlopt.opt discarded.)+	else+	    AC_MSG_RESULT(ok)+	    OCAMLOPT=$OCAMLOPTDOTOPT+	fi+    fi+fi++# ocamldep, ocamllex and ocamlyacc should also be present in the path+AC_CHECK_PROG(OCAMLDEP,ocamldep,ocamldep,no)+if test "$OCAMLDEP" = no ; then+	AC_MSG_ERROR(Cannot find ocamldep.)+fi++AC_CHECK_PROG(OCAMLLEX,ocamllex,ocamllex,no)+if test "$OCAMLLEX" = no ; then+    AC_MSG_ERROR(Cannot find ocamllex.)+else+    AC_CHECK_PROG(OCAMLLEXDOTOPT,ocamllex.opt,ocamllex.opt,no)+    if test "$OCAMLLEXDOTOPT" != no ; then+	OCAMLLEX=$OCAMLLEXDOTOPT+    fi+fi++AC_CHECK_PROG(OCAMLYACC,ocamlyacc,ocamlyacc,no)+if test "$OCAMLYACC" = no ; then+	AC_MSG_ERROR(Cannot find ocamlyacc.)+fi++AC_CHECK_PROG(OCAMLDOC,ocamldoc,ocamldoc,true)+if test "$OCAMLDOC" = true ; then+    AC_MSG_WARN(Cannot find ocamldoc)+else+    AC_CHECK_PROG(OCAMLDOCOPT,ocamldoc.opt,ocamldoc.opt,no)+    if test "$OCAMLDOCOPT" != no ; then+	OCAMLDOC=$OCAMLDOCOPT+    fi+fi++AC_CHECK_PROG(OCAMLWEB,ocamlweb,ocamlweb,true)++AC_CHECK_PROG(OCAMLFIND,ocamlfind,ocamlfind)++# checking for lablgtk2+AC_CHECK_PROG(LABLGTK2,lablgtk2,yes,no)+if test "$LABLGTK2" = yes ; then+   if test -d "$OCAMLLIB/lablgtk2" ; then+      INCLUDEGTK2="-I +lablgtk2"+   else+      LABLGTK2=no+   fi      +fi++# platform+AC_MSG_CHECKING(Win32 platform)+if echo "let _ = Sys.os_type;;" | ocaml | grep -q Win32; then+    AC_MSG_RESULT(yes)+    OCAMLWIN32=yes+    EXE=.exe+    LIBEXT=.lib+    OBJEXT=.obj+else+    AC_MSG_RESULT(no)+    OCAMLWIN32=no+    EXE=+    LIBEXT=.a+    OBJEXT=.o+fi++# substitutions to perform+AC_SUBST(OCAMLC)+AC_SUBST(OCAMLOPT)+AC_SUBST(OCAMLDEP)+AC_SUBST(OCAMLLEX)+AC_SUBST(OCAMLDOC)+AC_SUBST(OCAMLYACC)+AC_SUBST(OCAMLBEST)+AC_SUBST(OCAMLVERSION)+AC_SUBST(OCAMLLIB)+AC_SUBST(OCAMLWEB)+AC_SUBST(LABLGTK2)+AC_SUBST(OCAMLWIN32)+AC_SUBST(EXE)+AC_SUBST(LIBEXT)+AC_SUBST(OBJEXT)+AC_SUBST(FORPACK)+AC_SUBST(INCLUDEGTK2)++# Finally create the Makefile from Makefile.in+AC_OUTPUT(Makefile)+chmod a-w Makefile
+ external/ocamlgraph/lib/bitv.ml view
@@ -0,0 +1,610 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*i $Id: bitv.ml,v 1.3 2004-07-13 12:54:42 filliatr Exp $ i*)++(*s Bit vectors. The interface and part of the code are borrowed from the +    [Array] module of the ocaml standard library (but things are simplified+    here since we can always initialize a bit vector). This module also+    provides bitwise operations. *)++(*s We represent a bit vector by a vector of integers (field [bits]),+    and we keep the information of the size of the bit vector since it+    can not be found out with the size of the array (field [length]). *)++type t = {+  length : int;+  bits   : int array }++let length v = v.length++(*s Each element of the array is an integer containing [bpi] bits, where+    [bpi] is determined according to the machine word size. Since we do not+    use the sign bit, [bpi] is 30 on a 32-bits machine and 62 on a 64-bits+    machines. We maintain the following invariant:+    {\em The unused bits of the last integer are always +    zeros.} This is ensured by [create] and maintained in other functions+    using [normalize]. [bit_j], [bit_not_j], [low_mask] and [up_mask]+    are arrays used to extract and mask bits in a single integer. *)++let bpi = Sys.word_size - 2++let max_length = Sys.max_array_length * bpi++let bit_j = Array.init bpi (fun j -> 1 lsl j)+let bit_not_j = Array.init bpi (fun j -> max_int - bit_j.(j))++let low_mask = Array.create (succ bpi) 0+let _ = +  for i = 1 to bpi do low_mask.(i) <- low_mask.(i-1) lor bit_j.(pred i) done++let keep_lowest_bits a j = a land low_mask.(j)++let high_mask = Array.init (succ bpi) (fun j -> low_mask.(j) lsl (bpi-j))++let keep_highest_bits a j = a land high_mask.(j)++(*s Creating and normalizing a bit vector is easy: it is just a matter of+    taking care of the invariant. Copy is immediate. *)++let create n b =+  let initv = if b then max_int else 0 in+  let r = n mod bpi in+  if r = 0 then+    { length = n; bits = Array.create (n / bpi) initv }+  else begin+    let s = n / bpi in+    let b = Array.create (succ s) initv in+    b.(s) <- b.(s) land low_mask.(r);+    { length = n; bits = b }+  end+    +let normalize v =+  let r = v.length mod bpi in+  if r > 0 then+    let b = v.bits in+    let s = Array.length b in+    b.(s-1) <- b.(s-1) land low_mask.(r)++let copy v = { length = v.length; bits = Array.copy v.bits }++(*s Access and assignment. The [n]th bit of a bit vector is the [j]th+    bit of the [i]th integer, where [i = n / bpi] and [j = n mod+    bpi]. Both [i] and [j] and computed by the function [pos].+    Accessing a bit is testing whether the result of the corresponding+    mask operation is non-zero, and assigning it is done with a+    bitwiwe operation: an {\em or} with [bit_j] to set it, and an {\em+    and} with [bit_not_j] to unset it. *)++let pos n = +  let i = n / bpi and j = n mod bpi in+  if j < 0 then (i - 1, j + bpi) else (i,j)++let unsafe_get v n =+  let (i,j) = pos n in +  ((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_j j)) > 0++let unsafe_set v n b =+  let (i,j) = pos n in+  if b then+    Array.unsafe_set v.bits i +      ((Array.unsafe_get v.bits i) lor (Array.unsafe_get bit_j j))+  else +    Array.unsafe_set v.bits i +      ((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_not_j j))++(*s The corresponding safe operations test the validiy of the access. *)++let get v n =+  if n < 0 or n >= v.length then invalid_arg "Bitv.get";+  let (i,j) = pos n in +  ((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_j j)) > 0++let set v n b =+  if n < 0 or n >= v.length then invalid_arg "Bitv.set";+  let (i,j) = pos n in+  if b then+    Array.unsafe_set v.bits i+      ((Array.unsafe_get v.bits i) lor (Array.unsafe_get bit_j j))+  else+    Array.unsafe_set v.bits i+      ((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_not_j j))++(*s [init] is implemented naively using [unsafe_set]. *)++let init n f =+  let v = create n false in+  for i = 0 to pred n do+    unsafe_set v i (f i)+  done;+  v++(*s Handling bits by packets is the key for efficiency of functions+    [append], [concat], [sub] and [blit]. +    We start by a very general function [blit_bits a i m v n] which blits +    the bits [i] to [i+m-1] of a native integer [a] +    onto the bit vector [v] at index [n]. It assumes that [i..i+m-1] and+    [n..n+m-1] are respectively valid subparts of [a] and [v]. +    It is optimized when the bits fit the lowest boundary of an integer +    (case [j == 0]). *)++let blit_bits a i m v n =+  let (i',j) = pos n in+  if j == 0 then+    Array.unsafe_set v i'+      ((keep_lowest_bits (a lsr i) m) lor+       (keep_highest_bits (Array.unsafe_get v i') (bpi - m)))+  else +    let d = m + j - bpi in+    if d > 0 then begin+      Array.unsafe_set v i'+	(((keep_lowest_bits (a lsr i) (bpi - j)) lsl j) lor+	 (keep_lowest_bits (Array.unsafe_get v i') j));+      Array.unsafe_set v (succ i')+	((keep_lowest_bits (a lsr (i + bpi - j)) d) lor+	 (keep_highest_bits (Array.unsafe_get v (succ i')) (bpi - d)))+    end else +      Array.unsafe_set v i'+	(((keep_lowest_bits (a lsr i) m) lsl j) lor+	 ((Array.unsafe_get v i') land (low_mask.(j) lor high_mask.(-d))))++(*s [blit_int] implements [blit_bits] in the particular case when+    [i=0] and [m=bpi] i.e. when we blit all the bits of [a]. *)++let blit_int a v n =+  let (i,j) = pos n in+  if j == 0 then+    Array.unsafe_set v i a+  else begin+    Array.unsafe_set v i +      ( (keep_lowest_bits (Array.unsafe_get v i) j) lor+       ((keep_lowest_bits a (bpi - j)) lsl j));+    Array.unsafe_set v (succ i)+      ((keep_highest_bits (Array.unsafe_get v (succ i)) (bpi - j)) lor+       (a lsr (bpi - j)))+  end++(*s When blitting a subpart of a bit vector into another bit vector, there+    are two possible cases: (1) all the bits are contained in a single integer+    of the first bit vector, and a single call to [blit_bits] is the+    only thing to do, or (2) the source bits overlap on several integers of+    the source array, and then we do a loop of [blit_int], with two calls+    to [blit_bits] for the two bounds. *)++let unsafe_blit v1 ofs1 v2 ofs2 len =+  let (bi,bj) = pos ofs1 in+  let (ei,ej) = pos (ofs1 + len - 1) in+  if bi == ei then+    blit_bits (Array.unsafe_get v1 bi) bj len v2 ofs2+  else begin+    blit_bits (Array.unsafe_get v1 bi) bj (bpi - bj) v2 ofs2;+    let n = ref (ofs2 + bpi - bj) in+    for i = succ bi to pred ei do+      blit_int (Array.unsafe_get v1 i) v2 !n;+      n := !n + bpi+    done;+    blit_bits (Array.unsafe_get v1 ei) 0 (succ ej) v2 !n+  end++let blit v1 ofs1 v2 ofs2 len =+  if len < 0 or ofs1 < 0 or ofs1 + len > v1.length+             or ofs2 < 0 or ofs2 + len > v2.length+  then invalid_arg "Bitv.blit";+  unsafe_blit v1.bits ofs1 v2.bits ofs2 len++(*s Extracting the subvector [ofs..ofs+len-1] of [v] is just creating a+    new vector of length [len] and blitting the subvector of [v] inside. *)++let sub v ofs len =+  if ofs < 0 or len < 0 or ofs + len > v.length then invalid_arg "Bitv.sub";+  let r = create len false in+  unsafe_blit v.bits ofs r.bits 0 len;+  r++(*s The concatenation of two bit vectors [v1] and [v2] is obtained by +    creating a vector for the result and blitting inside the two vectors.+    [v1] is copied directly. *)++let append v1 v2 =+  let l1 = v1.length +  and l2 = v2.length in+  let r = create (l1 + l2) false in+  let b1 = v1.bits in+  let b2 = v2.bits in+  let b = r.bits in+  for i = 0 to Array.length b1 - 1 do +    Array.unsafe_set b i (Array.unsafe_get b1 i) +  done;  +  unsafe_blit b2 0 b l1 l2;+  r++(*s The concatenation of a list of bit vectors is obtained by iterating+    [unsafe_blit]. *)++let concat vl =+  let size = List.fold_left (fun sz v -> sz + v.length) 0 vl in+  let res = create size false in+  let b = res.bits in+  let pos = ref 0 in+  List.iter+    (fun v ->+       let n = v.length in+       unsafe_blit v.bits 0 b !pos n;+       pos := !pos + n)+    vl;+  res++(*s Filling is a particular case of blitting with a source made of all+    ones or all zeros. Thus we instanciate [unsafe_blit], with 0 and+    [max_int]. *)++let blit_zeros v ofs len =+  let (bi,bj) = pos ofs in+  let (ei,ej) = pos (ofs + len - 1) in+  if bi == ei then+    blit_bits 0 bj len v ofs+  else begin+    blit_bits 0 bj (bpi - bj) v ofs;+    let n = ref (ofs + bpi - bj) in+    for i = succ bi to pred ei do+      blit_int 0 v !n;+      n := !n + bpi+    done;+    blit_bits 0 0 (succ ej) v !n+  end++let blit_ones v ofs len =+  let (bi,bj) = pos ofs in+  let (ei,ej) = pos (ofs + len - 1) in+  if bi == ei then+    blit_bits max_int bj len v ofs+  else begin+    blit_bits max_int bj (bpi - bj) v ofs;+    let n = ref (ofs + bpi - bj) in+    for i = succ bi to pred ei do+      blit_int max_int v !n;+      n := !n + bpi+    done;+    blit_bits max_int 0 (succ ej) v !n+  end++let fill v ofs len b =+  if ofs < 0 or len < 0 or ofs + len > v.length then invalid_arg "Bitv.fill";+  if b then blit_ones v.bits ofs len else blit_zeros v.bits ofs len++(*s All the iterators are implemented as for traditional arrays, using+    [unsafe_get]. For [iter] and [map], we do not precompute [(f+    true)] and [(f false)] since [f] is likely to have+    side-effects. *)++let iter f v =+  for i = 0 to v.length - 1 do f (unsafe_get v i) done++let map f v =+  let l = v.length in+  let r = create l false in+  for i = 0 to l - 1 do+    unsafe_set r i (f (unsafe_get v i))+  done;+  r++let iteri f v =+  for i = 0 to v.length - 1 do f i (unsafe_get v i) done++let mapi f v =+  let l = v.length in+  let r = create l false in+  for i = 0 to l - 1 do+    unsafe_set r i (f i (unsafe_get v i))+  done;+  r++let fold_left f x v =+  let r = ref x in+  for i = 0 to v.length - 1 do+    r := f !r (unsafe_get v i)+  done;+  !r++let fold_right f v x =+  let r = ref x in+  for i = v.length - 1 downto 0 do+    r := f (unsafe_get v i) !r+  done;+  !r++let foldi_left f x v =+  let r = ref x in+  for i = 0 to v.length - 1 do+    r := f !r i (unsafe_get v i)+  done;+  !r++let foldi_right f v x =+  let r = ref x in+  for i = v.length - 1 downto 0 do+    r := f i (unsafe_get v i) !r+  done;+  !r++(*s Bitwise operations. It is straigthforward, since bitwise operations+    can be realized by the corresponding bitwise operations over integers.+    However, one has to take care of normalizing the result of [bwnot]+    which introduces ones in highest significant positions. *)++let bw_and v1 v2 = +  let l = v1.length in+  if l <> v2.length then invalid_arg "Bitv.bw_and";+  let b1 = v1.bits +  and b2 = v2.bits in+  let n = Array.length b1 in+  let a = Array.create n 0 in+  for i = 0 to n - 1 do+    a.(i) <- b1.(i) land b2.(i)+  done;+  { length = l; bits = a }+  +let bw_or v1 v2 = +  let l = v1.length in+  if l <> v2.length then invalid_arg "Bitv.bw_or";+  let b1 = v1.bits +  and b2 = v2.bits in+  let n = Array.length b1 in+  let a = Array.create n 0 in+  for i = 0 to n - 1 do+    a.(i) <- b1.(i) lor b2.(i)+  done;+  { length = l; bits = a }+  +let bw_xor v1 v2 = +  let l = v1.length in+  if l <> v2.length then invalid_arg "Bitv.bw_xor";+  let b1 = v1.bits +  and b2 = v2.bits in+  let n = Array.length b1 in+  let a = Array.create n 0 in+  for i = 0 to n - 1 do+    a.(i) <- b1.(i) lxor b2.(i)+  done;+  { length = l; bits = a }+  +let bw_not v = +  let b = v.bits in+  let n = Array.length b in+  let a = Array.create n 0 in+  for i = 0 to n - 1 do+    a.(i) <- max_int land (lnot b.(i))+  done;+  let r = { length = v.length; bits = a } in+  normalize r;+  r++(*s Shift operations. It is easy to reuse [unsafe_blit], although it is +    probably slightly less efficient than a ad-hoc piece of code. *)++let rec shiftl v d =+  if d == 0 then +    copy v+  else if d < 0 then+    shiftr v (-d)+  else begin+    let n = v.length in+    let r = create n false in+    if d < n then unsafe_blit v.bits 0 r.bits d (n - d);+    r+  end+  +and shiftr v d =+  if d == 0 then +    copy v+  else if d < 0 then+    shiftl v (-d)+  else begin+    let n = v.length in+    let r = create n false in+    if d < n then unsafe_blit v.bits d r.bits 0 (n - d);+    r+  end++(*s Testing for all zeros and all ones. *)++let all_zeros v = +  let b = v.bits in+  let n = Array.length b in+  let rec test i = +    (i == n) || ((Array.unsafe_get b i == 0) && test (succ i)) +  in+  test 0++let all_ones v = +  let b = v.bits in+  let n = Array.length b in+  let rec test i = +    if i == n - 1 then+      let m = v.length mod bpi in+      (Array.unsafe_get b i) == (if m == 0 then max_int else low_mask.(m))+    else+      ((Array.unsafe_get b i) == max_int) && test (succ i)+  in+  test 0++(*s Conversions to and from strings. *)++let to_string v = +  let n = v.length in+  let s = String.make n '0' in+  for i = 0 to n - 1 do+    if unsafe_get v i then s.[i] <- '1'+  done;+  s++let print fmt v = Format.pp_print_string fmt (to_string v)++let of_string s =+  let n = String.length s in+  let v = create n false in+  for i = 0 to n - 1 do+    let c = String.unsafe_get s i in+    if c = '1' then +      unsafe_set v i true+    else +      if c <> '0' then invalid_arg "Bitv.of_string"+  done;+  v++(*s Iteration on all bit vectors of length [n] using a Gray code. *)++let first_set v n = +  let rec lookup i = +    if i = n then raise Not_found ;+    if unsafe_get v i then i else lookup (i + 1)+  in +  lookup 0++let gray_iter f n = +  let bv = create n false in +  let rec iter () =+    f bv; +    unsafe_set bv 0 (not (unsafe_get bv 0));+    f bv; +    let pos = succ (first_set bv n) in+    if pos < n then begin+      unsafe_set bv pos (not (unsafe_get bv pos));+      iter ()+    end+  in+  if n > 0 then iter ()+++(*s Coercions to/from lists of integers *)++let of_list l =+  let n = List.fold_left max 0 l in+  let b = create (succ n) false in+  let add_element i = +    (* negative numbers are invalid *)+    if i < 0 then invalid_arg "Bitv.of_list";+    unsafe_set b i true +  in+  List.iter add_element l;+  b++let of_list_with_length l len =+  let b = create len false in+  let add_element i =+    if i < 0 || i >= len then invalid_arg "Bitv.of_list_with_length";+    unsafe_set b i true+  in+  List.iter add_element l;+  b++let to_list b =+  let n = length b in+  let rec make i acc = +    if i < 0 then acc +    else make (pred i) (if unsafe_get b i then i :: acc else acc)+  in+  make (pred n) []+++(*s To/from integers. *)++(* [int] *)+let of_int_us i = +  { length = bpi; bits = [| i land max_int |] }+let to_int_us v = +  if v.length < bpi then invalid_arg "Bitv.to_int_us"; +  v.bits.(0)++let of_int_s i = +  { length = succ bpi; bits = [| i land max_int; (i lsr bpi) land 1 |] }+let to_int_s v = +  if v.length < succ bpi then invalid_arg "Bitv.to_int_s"; +  v.bits.(0) lor (v.bits.(1) lsl bpi)++(* [Int32] *)+let of_int32_us i = match Sys.word_size with+  | 32 -> { length = 31; +	    bits = [| (Int32.to_int i) land max_int; +		      let hi = Int32.shift_right_logical i 30 in+		      (Int32.to_int hi) land 1 |] }+  | 64 -> { length = 31; bits = [| (Int32.to_int i) land 0x7fffffff |] }+  | _ -> assert false+let to_int32_us v =+  if v.length < 31 then invalid_arg "Bitv.to_int32_us"; +  match Sys.word_size with+    | 32 -> +	Int32.logor (Int32.of_int v.bits.(0))+	            (Int32.shift_left (Int32.of_int (v.bits.(1) land 1)) 30)+    | 64 ->+	Int32.of_int (v.bits.(0) land 0x7fffffff)+    | _ -> assert false++(* this is 0xffffffff (ocaml >= 3.08 checks for literal overflow) *)+let ffffffff = (0xffff lsl 16) lor 0xffff++let of_int32_s i = match Sys.word_size with+  | 32 -> { length = 32; +	    bits = [| (Int32.to_int i) land max_int; +		      let hi = Int32.shift_right_logical i 30 in+		      (Int32.to_int hi) land 3 |] }+  | 64 -> { length = 32; bits = [| (Int32.to_int i) land ffffffff |] }+  | _ -> assert false++let to_int32_s v =+  if v.length < 32 then invalid_arg "Bitv.to_int32_s"; +  match Sys.word_size with+    | 32 -> +	Int32.logor (Int32.of_int v.bits.(0))+	            (Int32.shift_left (Int32.of_int (v.bits.(1) land 3)) 30)+    | 64 ->+	Int32.of_int (v.bits.(0) land ffffffff)+    | _ -> assert false++(* [Int64] *)+let of_int64_us i = match Sys.word_size with+  | 32 -> { length = 63; +	    bits = [| (Int64.to_int i) land max_int; +		      (let mi = Int64.shift_right_logical i 30 in+		       (Int64.to_int mi) land max_int);+		      let hi = Int64.shift_right_logical i 60 in+		      (Int64.to_int hi) land 1 |] }+  | 64 -> { length = 63; +	    bits = [| (Int64.to_int i) land max_int;+		      let hi = Int64.shift_right_logical i 62 in +		      (Int64.to_int hi) land 1 |] }+  | _ -> assert false+let to_int64_us v = failwith "todo"++let of_int64_s i = failwith "todo"+let to_int64_s v = failwith "todo"++(* [Nativeint] *)+let select_of f32 f64 = match Sys.word_size with +  | 32 -> (fun i -> f32 (Nativeint.to_int32 i))+  | 64 -> (fun i -> f64 (Int64.of_nativeint i))+  | _ -> assert false+let of_nativeint_s = select_of of_int32_s of_int64_s+let of_nativeint_us = select_of of_int32_us of_int64_us+let select_to f32 f64 = match Sys.word_size with +  | 32 -> (fun i -> Nativeint.of_int32 (f32 i))+  | 64 -> (fun i -> Int64.to_nativeint (f64 i))+  | _ -> assert false+let to_nativeint_s = select_to to_int32_s to_int64_s+let to_nativeint_us = select_to to_int32_us to_int64_us++
+ external/ocamlgraph/lib/bitv.mli view
@@ -0,0 +1,195 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*s {\bf Module Bitv}.+    This module implements bit vectors, as an abstract datatype [t]. +    Since bit vectors are particular cases of arrays, this module provides+    the same operations as the module [Array] (Sections~\ref{barray} +    up to \ref{earray}). It also provides bitwise operations +    (Section~\ref{bitwise}). In the following, [false] stands for the bit 0 +    and [true] for the bit 1. *)++type t++(*s {\bf Creation, access and assignment.} \label{barray}+    [(Bitv.create n b)] creates a new bit vector of length [n],+    initialized with [b].+    [(Bitv.init n f)] returns a fresh vector of length [n],+    with bit number [i] initialized to the result of [(f i)]. +    [(Bitv.set v n b)] sets the [n]th bit of [v] to the value [b].+    [(Bitv.get v n)] returns the [n]th bit of [v]. +    [Bitv.length] returns the length (number of elements) of the given +    vector. *)++val create : int -> bool -> t++val init : int -> (int -> bool) -> t++val set : t -> int -> bool -> unit+    +val get : t -> int -> bool++val length : t -> int++(*s [max_length] is the maximum length of a bit vector (System dependent). *)++val max_length : int++(*s {\bf Copies and concatenations.}+   [(Bitv.copy v)] returns a copy of [v],+   that is, a fresh vector containing the same elements as+   [v]. [(Bitv.append v1 v2)] returns a fresh vector containing the+   concatenation of the vectors [v1] and [v2]. [Bitv.concat] is+   similar to [Bitv.append], but catenates a list of vectors. *)++val copy : t -> t++val append : t -> t -> t++val concat : t list -> t++(*s {\bf Sub-vectors and filling.} +    [(Bitv.sub v start len)] returns a fresh+    vector of length [len], containing the bits number [start] to+    [start + len - 1] of vector [v].  Raise [Invalid_argument+    "Bitv.sub"] if [start] and [len] do not designate a valid+    subvector of [v]; that is, if [start < 0], or [len < 0], or [start+    + len > Bitv.length a].++    [(Bitv.fill v ofs len b)] modifies the vector [v] in place,+    storing [b] in elements number [ofs] to [ofs + len - 1].  Raise+    [Invalid_argument "Bitv.fill"] if [ofs] and [len] do not designate+    a valid subvector of [v].++    [(Bitv.blit v1 o1 v2 o2 len)] copies [len] elements from vector+    [v1], starting at element number [o1], to vector [v2], starting at+    element number [o2]. It {\em does not work} correctly if [v1] and [v2] are+    the same vector with the source and destination chunks overlapping.+    Raise [Invalid_argument "Bitv.blit"] if [o1] and [len] do not+    designate a valid subvector of [v1], or if [o2] and [len] do not+    designate a valid subvector of [v2]. *)++val sub : t -> int -> int -> t++val fill : t -> int -> int -> bool -> unit++val blit : t -> int -> t -> int -> int -> unit++(*s {\bf Iterators.} \label{earray}+    [(Bitv.iter f v)] applies function [f] in turn to all+    the elements of [v]. Given a function [f], [(Bitv.map f v)] applies+    [f] to all+    the elements of [v], and builds a vector with the results returned+    by [f]. [Bitv.iteri] and [Bitv.mapi] are similar to [Bitv.iter]+    and [Bitv.map] respectively, but the function is applied to the+    index of the element as first argument, and the element itself as+    second argument.++    [(Bitv.fold_left f x v)] computes [f (... (f (f x (get v 0)) (get+    v 1)) ...) (get v (n-1))], where [n] is the length of the vector+    [v]. ++    [(Bitv.fold_right f a x)] computes [f (get v 0) (f (get v 1)+    ( ... (f (get v (n-1)) x) ...))], where [n] is the length of the+    vector [v]. *)++val iter : (bool -> unit) -> t -> unit+val map : (bool -> bool) -> t -> t++val iteri : (int -> bool -> unit) -> t -> unit+val mapi : (int -> bool -> bool) -> t -> t++val fold_left : ('a -> bool -> 'a) -> 'a -> t -> 'a+val fold_right : (bool -> 'a -> 'a) -> t -> 'a -> 'a+val foldi_left : ('a -> int -> bool -> 'a) -> 'a -> t -> 'a+val foldi_right : (int -> bool -> 'a -> 'a) -> t -> 'a -> 'a++(*s [gray_iter f n] iterates function [f] on all bit vectors+    of length [n], once each, using a Gray code. The order in which+    bit vectors are processed is unspecified. *)++val gray_iter : (t -> unit) -> int -> unit++(*s {\bf Bitwise operations.} \label{bitwise} [bwand], [bwor] and+    [bwxor] implement logical and, or and exclusive or.  They return+    fresh vectors and raise [Invalid_argument "Bitv.xxx"] if the two+    vectors do not have the same length (where \texttt{xxx} is the+    name of the function).  [bwnot] implements the logical negation. +    It returns a fresh vector.+    [shiftl] and [shiftr] implement shifts. They return fresh vectors.+    [shiftl] moves bits from least to most significant, and [shiftr]+    from most to least significant (think [lsl] and [lsr]).+    [all_zeros] and [all_ones] respectively test for a vector only+    containing zeros and only containing ones. *)++val bw_and : t -> t -> t+val bw_or  : t -> t -> t+val bw_xor : t -> t -> t+val bw_not : t -> t++val shiftl : t -> int -> t+val shiftr : t -> int -> t++val all_zeros : t -> bool+val all_ones  : t -> bool++(*s {\bf Conversions to and from strings.} +    Least significant bit comes first. *)++val to_string : t -> string+val of_string : string -> t+val print : Format.formatter -> t -> unit++(*s {\bf Conversions to and from lists of integers.} +    The list gives the indices of bits which are set (ie [true]). *)++val to_list : t -> int list+val of_list : int list -> t+val of_list_with_length : int list -> int -> t++(*s Interpretation of bit vectors as integers. Least significant bit +    comes first (ie is at index 0 in the bit vector). +    [to_xxx] functions truncate when the bit vector is too wide, +    and raise [Invalid_argument] when it is too short. +    Suffix [_s] indicates that sign bit is kept, +    and [_us] that it is discarded. *) ++(* type [int] (length 31/63 with sign, 30/62 without) *)+val of_int_s : int -> t+val to_int_s : t -> int+val of_int_us : int -> t+val to_int_us : t -> int+(* type [Int32.t] (length 32 with sign, 31 without) *)+val of_int32_s : Int32.t -> t+val to_int32_s : t -> Int32.t+val of_int32_us : Int32.t -> t+val to_int32_us : t -> Int32.t+(* type [Int64.t] (length 64 with sign, 63 without) *)+val of_int64_s : Int64.t -> t+val to_int64_s : t -> Int64.t+val of_int64_us : Int64.t -> t+val to_int64_us : t -> Int64.t+(* type [Nativeint.t] (length 32/64 with sign, 31/63 without) *)+val of_nativeint_s : Nativeint.t -> t+val to_nativeint_s : t -> Nativeint.t+val of_nativeint_us : Nativeint.t -> t+val to_nativeint_us : t -> Nativeint.t++(*s Only if you know what you are doing... *)++val unsafe_set : t -> int -> bool -> unit+val unsafe_get : t -> int -> bool
+ external/ocamlgraph/lib/heap.ml view
@@ -0,0 +1,236 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++module type Ordered = sig+  type t+  val compare : t -> t -> int+end++exception EmptyHeap++(*s Imperative implementation *)++module Imperative(X : Ordered) = struct++  (* The heap is encoded in the array [data], where elements are stored+     from [0] to [size - 1]. From an element stored at [i], the left +     (resp. right) subtree, if any, is rooted at [2*i+1] (resp. [2*i+2]). *)++  type t = { mutable size : int; mutable data : X.t array }++  (* When [create n] is called, we cannot allocate the array, since there is+     no known value of type [X.t]; we'll wait for the first addition to +     do it, and we remember this situation with a negative size. *)++  let create n = +    if n <= 0 then invalid_arg "create";+    { size = -n; data = [||] }++  let is_empty h = h.size <= 0++  (* [resize] doubles the size of [data] *)++  let resize h =+    let n = h.size in+    assert (n > 0);+    let n' = 2 * n in+    let d = h.data in+    let d' = Array.create n' d.(0) in+    Array.blit d 0 d' 0 n;+    h.data <- d'++  let add h x =+    (* first addition: we allocate the array *)+    if h.size < 0 then begin+      h.data <- Array.create (- h.size) x; h.size <- 0+    end;+    let n = h.size in+    (* resizing if needed *)+    if n == Array.length h.data then resize h;+    let d = h.data in+    (* moving [x] up in the heap *)+    let rec moveup i =+      let fi = (i - 1) / 2 in+      if i > 0 && X.compare d.(fi) x < 0 then begin+	d.(i) <- d.(fi);+	moveup fi+      end else+	d.(i) <- x+    in+    moveup n;+    h.size <- n + 1++  let maximum h =+    if h.size <= 0 then raise EmptyHeap;+    h.data.(0)++  let remove h =+    if h.size <= 0 then raise EmptyHeap;+    let n = h.size - 1 in+    h.size <- n;+    let d = h.data in+    let x = d.(n) in+    (* moving [x] down in the heap *)+    let rec movedown i =+      let j = 2 * i + 1 in+      if j < n then+	let j = +	  let j' = j + 1 in +	  if j' < n && X.compare d.(j') d.(j) > 0 then j' else j +	in+	if X.compare d.(j) x > 0 then begin +	  d.(i) <- d.(j); +	  movedown j +	end else+	  d.(i) <- x+      else+	d.(i) <- x+    in+    movedown 0++  let pop_maximum h = let m = maximum h in remove h; m++  let iter f h = +    let d = h.data in+    for i = 0 to h.size - 1 do f d.(i) done++  let fold f h x0 =+    let n = h.size in+    let d = h.data in+    let rec foldrec x i =+      if i >= n then x else foldrec (f d.(i) x) (succ i)+    in+    foldrec x0 0++end+++(*s Functional implementation *)++module type FunctionalSig = sig+  type elt+  type t+  val empty : t+  val add : elt -> t -> t+  val maximum : t -> elt+  val remove : t -> t+  val iter : (elt -> unit) -> t -> unit+  val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a+end++module Functional(X : Ordered) = struct++  (* Heaps are encoded as complete binary trees, i.e., binary trees+     which are full expect, may be, on the bottom level where it is filled +     from the left. +     These trees also enjoy the heap property, namely the value of any node +     is greater or equal than those of its left and right subtrees.++     There are 4 kinds of complete binary trees, denoted by 4 constructors:+     [FFF] for a full binary tree (and thus 2 full subtrees);+     [PPF] for a partial tree with a partial left subtree and a full+     right subtree;+     [PFF] for a partial tree with a full left subtree and a full right subtree+     (but of different heights);+     and [PFP] for a partial tree with a full left subtree and a partial+     right subtree. *)++  type elt = X.t++  type t = +    | Empty+    | FFF of t * X.t * t (* full    (full,    full) *)+    | PPF of t * X.t * t (* partial (partial, full) *)+    | PFF of t * X.t * t (* partial (full,    full) *)+    | PFP of t * X.t * t (* partial (full,    partial) *)++  let empty = Empty+ +  (* smart constructors for insertion *)+  let p_f l x r = match l with+    | Empty | FFF _ -> PFF (l, x, r)+    | _ -> PPF (l, x, r)++  let pf_ l x = function+    | Empty | FFF _ as r -> FFF (l, x, r)+    | r -> PFP (l, x, r)++  let rec add x = function+    | Empty -> +	FFF (Empty, x, Empty)+    (* insertion to the left *)+    | FFF (l, y, r) | PPF (l, y, r) ->+	if X.compare x y > 0 then p_f (add y l) x r else p_f (add x l) y r+    (* insertion to the right *)+    | PFF (l, y, r) | PFP (l, y, r) ->+	if X.compare x y > 0 then pf_ l x (add y r) else pf_ l y (add x r)++  let maximum = function+    | Empty -> raise EmptyHeap+    | FFF (_, x, _) | PPF (_, x, _) | PFF (_, x, _) | PFP (_, x, _) -> x++  (* smart constructors for removal; note that they are different+     from the ones for insertion! *)+  let p_f l x r = match l with+    | Empty | FFF _ -> FFF (l, x, r)+    | _ -> PPF (l, x, r)++  let pf_ l x = function+    | Empty | FFF _ as r -> PFF (l, x, r)+    | r -> PFP (l, x, r)++  let rec remove = function+    | Empty -> +	raise EmptyHeap+    | FFF (Empty, _, Empty) -> +	Empty+    | PFF (l, _, Empty) ->+	l+    (* remove on the left *)+    | PPF (l, x, r) | PFF (l, x, r) ->+        let xl = maximum l in+	let xr = maximum r in+	let l' = remove l in+	if X.compare xl xr >= 0 then +	  p_f l' xl r +	else +	  p_f l' xr (add xl (remove r))+    (* remove on the right *)+    | FFF (l, x, r) | PFP (l, x, r) ->+        let xl = maximum l in+	let xr = maximum r in+	let r' = remove r in+	if X.compare xl xr > 0 then +	  pf_ (add xr (remove l)) xl r'+	else +	  pf_ l xr r'++  let rec iter f = function+    | Empty -> +	()+    | FFF (l, x, r) | PPF (l, x, r) | PFF (l, x, r) | PFP (l, x, r) -> +	iter f l; f x; iter f r++  let rec fold f h x0 = match h with+    | Empty -> +	x0+    | FFF (l, x, r) | PPF (l, x, r) | PFF (l, x, r) | PFP (l, x, r) -> +	fold f l (fold f r (f x x0))++end
+ external/ocamlgraph/lib/heap.mli view
@@ -0,0 +1,99 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)+++module type Ordered = sig+  type t+  val compare : t -> t -> int+end++exception EmptyHeap++(*S Imperative implementation. *)++module Imperative(X: Ordered) : sig++  (* Type of imperative heaps.+     (In the following [n] refers to the number of elements in the heap) *)++  type t ++  (* [create c] creates a new heap, with initial capacity of [c] *)+  val create : int -> t++  (* [is_empty h] checks the emptiness of [h] *)+  val is_empty : t -> bool++  (* [add x h] adds a new element [x] in heap [h]; size of [h] is doubled+     when maximum capacity is reached; complexity $O(log(n))$ *)+  val add : t -> X.t -> unit++  (* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(1)$ *)+  val maximum : t -> X.t++  (* [remove h] removes the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(log(n))$ *)+  val remove : t -> unit++  (* [pop_maximum h] removes the maximum element of [h] and returns it;+     raises [EmptyHeap] when [h] is empty; complexity $O(log(n))$ *)+  val pop_maximum : t -> X.t++  (* usual iterators and combinators; elements are presented in+     arbitrary order *)+  val iter : (X.t -> unit) -> t -> unit++  val fold : (X.t -> 'a -> 'a) -> t -> 'a -> 'a++end++(*S Functional implementation. *)++module type FunctionalSig = sig++  (* heap elements *)+  type elt++  (* Type of functional heaps *)+  type t++  (* The empty heap *)+  val empty : t++  (* [add x h] returns a new heap containing the elements of [h], plus [x];+     complexity $O(log(n))$ *)+  val add : elt -> t -> t++  (* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]+     when [h] is empty; complexity $O(1)$ *)+  val maximum : t -> elt++  (* [remove h] returns a new heap containing the elements of [h], except+     the maximum of [h]; raises [EmptyHeap] when [h] is empty; +     complexity $O(log(n))$ *) +  val remove : t -> t++  (* usual iterators and combinators; elements are presented in+     arbitrary order *)+  val iter : (elt -> unit) -> t -> unit++  val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a++end++module Functional(X: Ordered) : FunctionalSig with type elt = X.t
+ external/ocamlgraph/lib/unionfind.ml view
@@ -0,0 +1,117 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++module type HashedOrderedType = sig+  type t+  val equal : t -> t -> bool+  val hash : t -> int +  val compare : t -> t -> int +end++module type S = sig+  type elt+  type t+    +  val init : elt list -> t+  val find : elt -> t -> elt+  val union : elt -> elt -> t -> unit+end++module Make(X:HashedOrderedType) = struct++  type elt = X.t++  module H = Hashtbl.Make(X)+  +  type cell = {+    mutable c : int;+    data : elt;+    mutable father : cell+  }+  +  type t = cell H.t (* a forest *)++  let init l = +    let h = H.create 997 in+    List.iter +      (fun x ->+         let rec cell = { c = 0; data = x; father = cell } in +	 H.add h x cell) +      l;+    h++  let rec find_aux cell = +    if cell.father == cell then +      cell+    else +      let r = find_aux cell.father in +      cell.father <- r; +      r++  let find x h = (find_aux (H.find h x)).data++  let union x y h = +    let rx = find_aux (H.find h x) in+    let ry = find_aux (H.find h y) in+    if rx != ry then begin+      if rx.c > ry.c then+        ry.father <- rx+      else if rx.c < ry.c then+        rx.father <- ry+      else begin+        rx.c <- rx.c + 1;+        ry.father <- rx+      end+    end+end++(*** test ***)+(***++module M = Make (struct +        type t = int let +        hash = Hashtbl.hash +        let compare = compare +        let equal = (=) +    end)++open Printf++let saisir s  = +        printf "%s = " s; flush stdout;+        let x = read_int () in+        x++let h = M.init [0;1;2;3;4;5;6;7;8;9] +let () = if not !Sys.interactive then +    while true do +        printf "1) find\n2) union\n";+        match read_int () with+            1 -> begin+                let x = saisir "x" in+                printf "%d\n" (M.find x h) +            end+          | 2 -> begin+                let x, y = saisir "x", saisir "y" in+                M.union x y h+            end+          | _ -> ()+    done++***)
+ external/ocamlgraph/lib/unionfind.mli view
@@ -0,0 +1,49 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++++(* Unionfind structure over hash-ordered types.++   This module implements a unionfind data structure, given a total ordering+   function and a hash function over the elements. ++*)+++module type HashedOrderedType = sig+  (* The type of the elements*)+  type t+  val equal : t -> t -> bool+  val hash : t -> int +  val compare : t -> t -> int +end++(* Input signature of the functor Unionfind.Make *)++module type S = sig+  type elt+  type t+    +  val init : elt list -> t+  val find : elt -> t -> elt+  val union : elt -> elt -> t -> unit+end++module Make (X : HashedOrderedType) : S with type elt = X.t++
+ external/ocamlgraph/src/blocks.ml view
@@ -0,0 +1,650 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: per_imp.ml,v 1.32 2006-02-03 09:27:29 filliatr Exp $ *)++(** Common implementation to persistent and imperative graphs. *)++open Sig+open Util++let cpt_vertex = ref min_int+  (* global counter for abstract vertex *)++(* ************************************************************************* *)+(** {2 Association table builder} *)+(* ************************************************************************* *)++(** Common signature to an imperative/persistent association table *)+module type HM = sig+  type 'a return+  type 'a t+  type key+  val create : int -> 'a t+  val create_from : 'a t -> 'a t+  val empty : 'a return+  val is_empty : 'a t -> bool+  val add : key -> 'a -> 'a t -> 'a t+  val remove : key -> 'a t -> 'a t+  val mem : key -> 'a t -> bool+  val find : key -> 'a t -> 'a+  val find_and_raise : key -> 'a t -> string -> 'a+    (** [find_and_raise k t s] is equivalent to [find k t] but+       raises [Invalid_argument s] when [find k t] raises [Not_found] *)++  val iter : (key -> 'a -> unit) -> 'a t -> unit+  val map : (key -> 'a -> key * 'a) -> 'a t -> 'a t+  val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b+  val copy : 'a t -> 'a t+end++module type TBL_BUILDER = functor(X: COMPARABLE) -> HM with type key = X.t++(** [HM] implementation using hashtbl. *)+module Make_Hashtbl(X: COMPARABLE) = struct++  include Hashtbl.Make(X)++  type 'a return = unit+  let empty = ()+    (* never call and not visible for the user thank's to signature +       constraints *)++  let create_from h = create (length h)++  let is_empty h = (length h = 0)++  let find_and_raise k h s = try find h k with Not_found -> invalid_arg s++  let map f h = +    let h' = create_from h  in+    iter (fun k v -> let k, v = f k v in add h' k v) h;+    h'++  let add k v h = replace h k v; h+  let remove k h = remove h k; h+  let mem k h = mem h k+  let find k h = find h k++end++(** [HM] implementation using map *)+module Make_Map(X: COMPARABLE) = struct+  include Map.Make(X)+  type 'a return = 'a t+  let is_empty m = (m = empty)+  let create _ = assert false+    (* never call and not visible for the user thank's to +       signature constraints *)+  let create_from _ = empty+  let copy m = m+  let map f m = fold (fun k v m -> let k, v = f k v in add k v m) m empty+  let find_and_raise k h s = try find k h with Not_found -> invalid_arg s+end++(* ************************************************************************* *)+(** {2 Blocks builder} *)+(* ************************************************************************* *)++(** Common implementation to all (directed) graph implementations. *)+module Minimal(S: Set.S)(HM: HM) = struct++  type vertex = HM.key++  let is_directed = true+  let empty = HM.empty+  let create = HM.create+  let is_empty = HM.is_empty++  let nb_vertex g = HM.fold (fun _ _ -> succ) g 0+  let nb_edges g = HM.fold (fun _ s n -> n + S.cardinal s) g 0+  let out_degree g v = +    S.cardinal (try HM.find v g with Not_found -> invalid_arg "out_degree")++  let mem_vertex g v = HM.mem v g++  let unsafe_add_vertex g v = HM.add v S.empty g+  let unsafe_add_edge g v1 v2 = HM.add v1 (S.add v2 (HM.find v1 g)) g++  let add_vertex g v = if HM.mem v g then g else unsafe_add_vertex g v++  let iter_vertex f = HM.iter (fun v _ -> f v)+  let fold_vertex f = HM.fold (fun v _ -> f v)+    +end++(** All the predecessor operations from the iterators on the edges *)+module Pred(S: sig+	      module PV: COMPARABLE+	      module PE: EDGE with type vertex = PV.t+	      type t+	      val mem_vertex : PV.t -> t -> bool+	      val iter_edges : (PV.t -> PV.t -> unit) -> t -> unit+	      val fold_edges : (PV.t -> PV.t -> 'a -> 'a) -> t -> 'a -> 'a+	      val iter_edges_e : (PE.t -> unit) -> t -> unit+	      val fold_edges_e : (PE.t -> 'a -> 'a) -> t -> 'a -> 'a+	    end) =+struct++  open S++  let iter_pred f g v = +    if not (mem_vertex v g) then invalid_arg "iter_pred";+    iter_edges (fun v1 v2 -> if PV.equal v v2 then f v1) g++  let fold_pred f g v = +    if not (mem_vertex v g) then invalid_arg "fold_pred";+    fold_edges (fun v1 v2 a -> if PV.equal v v2 then f v1 a else a) g++  let pred g v = fold_pred (fun v l -> v :: l) g v []++  let in_degree g v = +    if not (mem_vertex v g) then invalid_arg "in_degree";+    fold_pred (fun v n -> n + 1) g v 0++  let iter_pred_e f g v =+    if not (mem_vertex v g) then invalid_arg "iter_pred_e";+    iter_edges_e (fun e -> if PV.equal v (PE.dst e) then f e) g++  let fold_pred_e f g v =+    if not (mem_vertex v g) then invalid_arg "fold_pred_e";+    fold_edges_e (fun e a -> if PV.equal v (PE.dst e) then f e a else a) g+      +  let pred_e g v = fold_pred_e (fun v l -> v :: l) g v []++end++(** Common implementation to all the unlabeled (directed) graphs. *)+module Unlabeled(V: COMPARABLE)(HM: HM with type key = V.t) = struct+  +  module S = Set.Make(V)++  module E = struct+    type vertex = V.t+    include OTProduct(V)(V)+    let src = fst+    let dst = snd+    type label = unit+    let label _ = ()+    let create v1 () v2 = v1, v2+  end++  type edge = E.t++  let mem_edge g v1 v2 = +    try+      S.mem v2 (HM.find v1 g)+    with Not_found ->+      false++  let mem_edge_e g (v1, v2) = mem_edge g v1 v2++  let find_edge g v1 v2 = if mem_edge g v1 v2 then v1, v2 else raise Not_found++  let unsafe_remove_edge g v1 v2 = HM.add v1 (S.remove v2 (HM.find v1 g)) g+  let unsafe_remove_edge_e g (v1, v2) = unsafe_remove_edge g v1 v2++  let remove_edge g v1 v2 = +    if not (HM.mem v2 g) then invalid_arg "remove_edge";+    HM.add v1 (S.remove v2 (HM.find_and_raise v1 g "remove_edge")) g++  let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  let iter_succ f g v = S.iter f (HM.find_and_raise v g "iter_succ")+  let fold_succ f g v = S.fold f (HM.find_and_raise v g "fold_succ")++  let iter_succ_e f g v = iter_succ (fun v2 -> f (v, v2)) g v+  let fold_succ_e f g v = fold_succ (fun v2 -> f (v, v2)) g v++  let succ g v = S.elements (HM.find_and_raise v g "succ")+  let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []++  let map_vertex f = +    HM.map (fun v s -> f v, S.fold (fun v s -> S.add (f v) s) s S.empty)++  module I = struct+    type t = S.t HM.t+    module PV = V+    module PE = E+    let iter_edges f = HM.iter (fun v -> S.iter (f v))+    let fold_edges f = HM.fold (fun v -> S.fold (f v))+    let iter_edges_e f = iter_edges (fun v1 v2 -> f (v1, v2))+    let fold_edges_e f = fold_edges (fun v1 v2 a -> f (v1, v2) a)+  end+  include I++  include Pred(struct include I let mem_vertex = HM.mem end)++end++(** Common implementation to all the labeled (directed) graphs. *)+module Labeled(V: COMPARABLE)(E: ORDERED_TYPE)(HM: HM with type key = V.t) = +struct++  module VE = OTProduct(V)(E)++  module S = Set.Make(VE)++  module E = struct+    type vertex = V.t+    type label = E.t+    type t = vertex * label * vertex+    let src (v, _, _) = v+    let dst (_, _, v) = v+    let label (_, l, _) = l+    let create v1 l v2 = v1, l, v2+    module C = OTProduct(V)(VE)+    let compare (x1, x2, x3) (y1, y2, y3) = +      C.compare (x1, (x3, x2)) (y1, (y3, y2))+  end++  type edge = E.t++  let mem_edge g v1 v2 = +    try+      S.exists (fun (v2', _) -> V.equal v2 v2') (HM.find v1 g)+    with Not_found ->+      false++  let mem_edge_e g (v1, l, v2) =+    try+      let ve = v2, l in+      S.exists (fun ve' -> VE.compare ve ve' == 0) (HM.find v1 g)+    with Not_found ->+      false++  exception Found of edge+  let find_edge g v1 v2 =+    try+      S.iter +	(fun (v2', l) -> if V.equal v2 v2' then raise (Found (v1, l, v2')))+	(HM.find v1 g);+      raise Not_found+    with Found e ->+      e++  let unsafe_remove_edge g v1 v2 = +    HM.add v1 (S.filter +		 (fun (v2', _) -> not (V.equal v2 v2')) (HM.find v1 g)) g++  let unsafe_remove_edge_e g (v1, l, v2) = +    HM.add v1 (S.remove (v2, l) (HM.find v1 g)) g++  let remove_edge g v1 v2 =+    if not (HM.mem v2 g) then invalid_arg "remove_edge";+    HM.add v1 (S.filter +		 (fun (v2', _) -> not (V.equal v2 v2'))+		 (HM.find_and_raise v1 g "remove_edge")) g++  let remove_edge_e g (v1, l, v2) = +    if not (HM.mem v2 g) then invalid_arg "remove_edge_e";+    HM.add v1 (S.remove (v2, l) (HM.find_and_raise v1 g "remove_edge_e")) g++  let iter_succ f g v = +    S.iter (fun (w, _) -> f w) (HM.find_and_raise v g "iter_succ")+  let fold_succ f g v = +    S.fold (fun (w, _) -> f w) (HM.find_and_raise v g "fold_succ")++  let iter_succ_e f g v = +    S.iter (fun (w, l) -> f (v, l, w)) (HM.find_and_raise v g "iter_succ_e")+  let fold_succ_e f g v = +    S.fold (fun (w, l) -> f (v, l, w)) (HM.find_and_raise v g "fold_succ_e")++  let succ g v = fold_succ (fun w l -> w :: l) g v []+  let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []++  let map_vertex f = +    HM.map (fun v s -> +	      f v, S.fold (fun (v, l) s -> S.add (f v, l) s) s S.empty)++  module I = struct+    type t = S.t HM.t+    module PV = V+    module PE = E++    let iter_edges f = HM.iter (fun v -> S.iter (fun (w, _) -> f v w))+    let fold_edges f = HM.fold (fun v -> S.fold (fun (w, _) -> f v w))+    let iter_edges_e f = +      HM.iter (fun v -> S.iter (fun (w, l) -> f (v, l, w)))+    let fold_edges_e f = +      HM.fold (fun v -> S.fold (fun (w, l) -> f (v, l, w)))+  end+  include I++  include Pred(struct include I let mem_vertex = HM.mem end)++end++(** The vertex module and the vertex table for the concrete graphs. *)+module ConcreteVertex(F : TBL_BUILDER)(V: COMPARABLE) = struct++  module V = struct+    include V+    type label = t+    let label v = v+    let create v = v+  end++  module HM = F(V)++end++(* Support for explicitly maintaining edge set of+   predecessors.  Crucial for algorithms that do a lot of backwards+   traversal. *)++module BidirectionalMinimal(S:Set.S)(HM:HM with type key = S.elt) = +struct++  type vertex = HM.key++  let is_directed = true+  let empty = HM.empty+  let create = HM.create+  let is_empty = HM.is_empty++  let nb_vertex g = HM.fold (fun _ _ -> succ) g 0+  let nb_edges g = HM.fold (fun _ (_,s) n -> n + S.cardinal s) g 0+  let out_degree g v = +    S.cardinal (snd (try HM.find v g with Not_found -> invalid_arg "out_degree"))++  let mem_vertex g v = HM.mem v g++  let unsafe_add_vertex g v = HM.add v (S.empty,S.empty) g+  let unsafe_add_edge g v1 v2 = +    let (in_set,out_set) = HM.find v1 g+    in +      ignore ( HM.add v1 (in_set,S.add v2 out_set) g ) ;+      let (in_set,out_set) = HM.find v2 g+      in+	HM.add v2 (S.add v1 in_set,out_set) g++  let iter_vertex f = HM.iter (fun v _ -> f v)+  let fold_vertex f = HM.fold (fun v _ -> f v)+end++module BidirectionalUnlabeled(V:COMPARABLE)(HM:HM with type key = V.t) =+struct++  module S = Set.Make(V)++  (* Edge definition *)++  module E = struct+    type vertex = V.t+    include OTProduct(V)(V)+    let src = fst+    let dst = snd+    type label = unit+    let label _ = ()+    let create v1 () v2 = v1, v2+  end++  type edge = E.t++  let mem_edge g v1 v2 =+    try S.mem v2 (snd (HM.find v1 g))+    with Not_found -> false++  let mem_edge_e g (v1,v2) = mem_edge g v1 v2++  let find_edge g v1 v2 = if mem_edge g v1 v2 then v1, v2 else raise Not_found++  let unsafe_remove_edge g v1 v2 =+    let (in_set,out_set) = HM.find v1 g in +    ignore ( HM.add v1 (in_set,( S.remove v2 out_set )) g ) ;+    let (in_set,out_set) = HM.find v2 g in+    HM.add v2 (S.remove v1 in_set,out_set) g++  let unsafe_remove_edge_e g (v1,v2) = unsafe_remove_edge g v1 v2++  let remove_edge g v1 v2 = +    if not (HM.mem v2 g) then invalid_arg "remove_edge";+    unsafe_remove_edge g v1 v2+    (* HM.add v1 (S.remove v2 (HM.find_and_raise v1 g "remove_edge")) g *)++  let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  let iter_succ f g v = S.iter f (snd (HM.find_and_raise v g "iter_succ"))+  let fold_succ f g v = S.fold f (snd (HM.find_and_raise v g "fold_succ"))++  let iter_succ_e f g v = iter_succ (fun v2 -> f (v, v2)) g v+  let fold_succ_e f g v = fold_succ (fun v2 -> f (v, v2)) g v++  let succ g v = S.elements (snd (HM.find_and_raise v g "succ"))+  let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []+ +  let map_vertex f = +    HM.map (fun v (s1,s2) -> +	      f v, +	      ( S.fold (fun v s -> S.add (f v) s) s1 S.empty,+		S.fold (fun v s -> S.add (f v) s) s2 S.empty ) +	   )++  module I = struct+    (* we keep sets for both incoming and outgoing edges *)+    type t = (S.t * S.t) HM.t  +    module PV = V+    module PE = E+    let iter_edges f = HM.iter (fun v (_,outset) -> S.iter (f v) outset )+    let fold_edges f = HM.fold (fun v (_,outset) -> S.fold (f v) outset )+    let iter_edges_e f = iter_edges (fun v1 v2 -> f (v1, v2))+    let fold_edges_e f = fold_edges (fun v1 v2 a -> f (v1, v2) a)+  end+  include I++  let iter_pred f g v = S.iter f (fst (HM.find_and_raise v g "iter_pred"))+  let fold_pred f g v = S.fold f (fst (HM.find_and_raise v g "fold_pred"))++  let pred g v = S.elements (fst (HM.find_and_raise v g "pred"))++  let in_degree g v = +    S.cardinal +      (fst (try HM.find v g with Not_found -> invalid_arg "in_degree"))++  let iter_pred_e f g v = iter_pred (fun v2 -> f (v2,v)) g v+  let fold_pred_e f g v = fold_pred (fun v2 -> f (v2,v)) g v++  let pred_e g v = fold_pred_e (fun e l -> e :: l) g v []   +end++module Make_Abstract+  (G: sig+     module HM: HM+     module S: Set.S+     include G with type t = S.t HM.t and type V.t = HM.key+     val remove_edge: t -> vertex -> vertex -> t+     val remove_edge_e: t -> edge -> t+     val unsafe_add_vertex: t -> vertex -> t+     val unsafe_add_edge: t -> vertex -> S.elt -> t+     val unsafe_remove_edge: t -> vertex -> vertex -> t+     val unsafe_remove_edge_e: t -> edge -> t+     val empty: S.t HM.return+     val create: int -> t+   end) = +struct++  module I = struct+    type t = { edges : G.t; mutable size : int }+	(* BE CAREFUL: [size] is only mutable in the imperative version.+	   As there is no extensible records in current ocaml version,+	   and for genericity purpose, [size] is mutable in both the+	   imperative and persistent implementation.+	   Do not modify size in the persistent implementation! *)++    type vertex = G.vertex+    type edge = G.edge++    module PV = G.V+    module PE = G.E++    let iter_edges f g = G.iter_edges f g.edges+    let fold_edges f g = G.fold_edges f g.edges+    let iter_edges_e f g = G.iter_edges_e f g.edges+    let fold_edges_e f g = G.fold_edges_e f g.edges+    let mem_vertex v g = G.mem_vertex g.edges v+  end+  include I++  include Pred(I)++  (* optimisations *)++  let is_empty g = g.size = 0+  let nb_vertex g = g.size++  (* redefinitions *)+  module V = G.V+  module E = G.E+  module HM = G.HM+  module S = G.S++  let unsafe_add_edge = G.unsafe_add_edge+  let unsafe_remove_edge = G.unsafe_remove_edge+  let unsafe_remove_edge_e = G.unsafe_remove_edge_e+  let is_directed = G.is_directed++  let remove_edge g = G.remove_edge g.edges+  let remove_edge_e g = G.remove_edge_e g.edges++  let out_degree g = G.out_degree g.edges+  let in_degree g = G.in_degree g.edges++  let nb_edges g = G.nb_edges g.edges+  let succ g = G.succ g.edges+  let mem_vertex g = G.mem_vertex g.edges+  let mem_edge g = G.mem_edge g.edges+  let mem_edge_e g = G.mem_edge_e g.edges+  let find_edge g = G.find_edge g.edges++  let iter_vertex f g = G.iter_vertex f g.edges+  let fold_vertex f g = G.fold_vertex f g.edges+  let iter_succ f g = G.iter_succ f g.edges+  let fold_succ f g = G.fold_succ f g.edges+  let succ_e g = G.succ_e g.edges+  let iter_succ_e f g = G.iter_succ_e f g.edges+  let fold_succ_e f g = G.fold_succ_e f g.edges+  let map_vertex f g = { g with edges = G.map_vertex f g.edges }++end++(** Build persistent (resp. imperative) graphs from a persistent (resp. +    imperative) association table *)+module Make(F : TBL_BUILDER) = struct++  module Digraph = struct++    module Concrete(V: COMPARABLE) = struct+      include ConcreteVertex(F)(V)+      include Unlabeled(V)(HM)+      include Minimal(S)(HM)++      let add_edge g v1 v2 = +	let g = add_vertex g v1 in+	let g = add_vertex g v2 in+	unsafe_add_edge g v1 v2++      let add_edge_e g (v1, v2) = add_edge g v1 v2++      let remove_vertex g v =+	if HM.mem v g then+	  let g = HM.remove v g in+	  HM.fold +	    (fun k s g -> HM.add k (S.remove v s) g) +	    g +	    (HM.create_from g)+	else+	  g++    end++    module ConcreteBidirectional(V: COMPARABLE) = struct+      include ConcreteVertex(F)(V)+      include BidirectionalUnlabeled(V)(HM)+      include BidirectionalMinimal(S)(HM)+    end++    module ConcreteLabeled(V: COMPARABLE)(E: ORDERED_TYPE_DFT) = struct+      include ConcreteVertex(F)(V)+      include Labeled(V)(E)(HM)+      include Minimal(S)(HM)+    end++    module Abstract(V: VERTEX) = struct+      module G = struct+	module V = V+	module HM = F(V)+	include Unlabeled(V)(HM) +	include Minimal(S)(HM)+      end+      include Make_Abstract(G)+    end++    module AbstractLabeled(V: VERTEX)(E: ORDERED_TYPE_DFT) = struct+      module G = struct+	module V = V+	module HM = F(V)+	include Labeled(V)(E)(HM) +	include Minimal(S)(HM)+      end+      include Make_Abstract(G)+    end++  end++end++(** Implementation of undirected graphs from implementation of directed+    graphs. *)+module Graph(G: Sig.G) = struct++  include G++  let is_directed = false++  (* Redefine iterators and [nb_edges]. *)++  let iter_edges f =+    iter_edges (fun v1 v2 -> if V.compare v1 v2 >= 0 then f v1 v2)++  let fold_edges f =+    fold_edges +      (fun v1 v2 acc -> if V.compare v1 v2 >= 0 then f v1 v2 acc else acc)++  let iter_edges_e f =+    iter_edges_e+      (fun e -> if V.compare (E.src e) (E.dst e) >= 0 then f e)++  let fold_edges_e f =+    fold_edges_e+      (fun e acc -> +	 if V.compare (E.src e) (E.dst e) >= 0 then f e acc else acc)++  let nb_edges g = fold_edges_e (fun _ -> (+) 1) g 0++  (* Redefine operations on predecessors:+     predecessors are successors in an undirected graph. *)++  let pred = succ+  let in_degree = out_degree+  let iter_pred = iter_succ+  let fold_pred = fold_succ+  let pred_e = succ_e+  let iter_pred_e = iter_succ_e+  let fold_pred_e = fold_succ_e++end
+ external/ocamlgraph/src/builder.ml view
@@ -0,0 +1,49 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: builder.ml,v 1.12 2004-02-20 14:37:40 signoles Exp $ *)++open Sig++module type S = sig+  module G : Sig.G+  val empty : unit -> G.t+  val copy : G.t -> G.t+  val add_vertex : G.t -> G.V.t -> G.t+  val add_edge : G.t -> G.V.t -> G.V.t -> G.t+  val add_edge_e : G.t -> G.E.t -> G.t+end++module type INT = S with type G.V.label = int++module P(G : Sig.P) = struct+  module G = G+  let empty () = G.empty+  let copy g = g+  let add_vertex = G.add_vertex+  let add_edge = G.add_edge+  let add_edge_e = G.add_edge_e+end++module I(G : Sig.I) = struct+  module G = G+  let empty () = G.create ~size:997 ()+  let copy = G.copy+  let add_vertex g v = G.add_vertex g v; g+  let add_edge g v1 v2 = G.add_edge g v1 v2; g+  let add_edge_e g e = G.add_edge_e g e; g+end
+ external/ocamlgraph/src/builder.mli view
@@ -0,0 +1,47 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: builder.mli,v 1.13 2004-02-20 14:37:40 signoles Exp $ *)++(** Graph builders *)++open Sig++(** {1 Common interface for graph builders}.++   Note: the following functions always return graphs but this is meaningless+   for imperative implementations (the graph is modified in-place).  +   This is just to provide a common interface. *)++module type S = sig+  module G : Sig.G+  val empty : unit -> G.t+  val copy : G.t -> G.t+  val add_vertex : G.t -> G.V.t -> G.t+  val add_edge : G.t -> G.V.t -> G.V.t -> G.t+  val add_edge_e : G.t -> G.E.t -> G.t+end++module type INT = S with type G.V.label = int++(** {1 Builders for the various graph implementations} *)++module P(G : Sig.P) : S with module G = G+  (** Persistent Graphs Builders *)++module I(G : Sig.I) : S with module G = G+  (** Imperative Graphs Builders *)
+ external/ocamlgraph/src/classic.ml view
@@ -0,0 +1,85 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: classic.ml,v 1.9 2004-02-02 08:11:14 filliatr Exp $ *)++module type S = sig+  type graph +  val divisors : int -> graph+  val de_bruijn : int -> graph+  val vertex_only : int -> graph+  val full : ?self:bool -> int -> graph+end++module Generic(B : Builder.INT) = struct++  type graph = B.G.t++  let divisors n =+    if n < 2 then invalid_arg "divisors";+    let v = Array.init (n + 1) (fun i -> B.G.V.create i) in+    let rec loop g i =+      let sqrt_i = truncate (sqrt (float i)) in+      let rec loop_i g d =+	if d > sqrt_i then +	  g +	else if i mod d == 0 then+	  loop_i (B.add_edge (B.add_edge g v.(i / d) v.(i)) v.(d) v.(i)) (d+1)+	else+	  loop_i g (succ d)+      in+      if i > n then g else loop (loop_i (B.add_vertex g v.(i)) 2) (i+1)+    in+    loop (B.empty ()) 2+	+  let fold_for i0 i1 f =+    let rec loop i v = if i > i1 then v else loop (i + 1) (f v i) in+    loop i0++  let de_bruijn n =+    if n < 1 || n > Sys.word_size - 1 then invalid_arg "de_bruijn";+    let v = Array.init (1 lsl n) (fun i -> B.G.V.create i) in+    let all_1 = 1 lsl n - 1 in (* 11...1 *)+    let g = fold_for 0 all_1 (fun g i -> B.add_vertex g v.(i)) (B.empty ()) in+    let rec loop g i =+      if i > all_1 then+	g+      else +	let si = (i lsl 1) land all_1 in+	let g = B.add_edge g v.(i) v.(si) in+	let g = B.add_edge g v.(i) v.(si lor 1) in+	loop g (i + 1)+    in+    loop g 0++  let vertex_only n =+    fold_for 1 n (fun g i -> B.add_vertex g (B.G.V.create i)) (B.empty ())++  let full ?(self=true) n =+    let v = Array.init (n + 1) (fun i -> B.G.V.create i) in+    fold_for 1 n+      (fun g i ->+	 fold_for 1 n+	   (fun g j -> if self || i <> j then B.add_edge g v.(i) v.(j) else g)+	   g)+      (fold_for 1 n (fun g i -> B.add_vertex g v.(i)) (B.empty ()))++end++module P (G : Sig.P with type V.label = int) = Generic(Builder.P(G))++module I (G : Sig.I with type V.label = int) = Generic(Builder.I(G))
+ external/ocamlgraph/src/classic.mli view
@@ -0,0 +1,54 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: classic.mli,v 1.12 2005-02-25 13:54:33 signoles Exp $ *)++(** Some classic graphs *)++module type S = sig++  type graph ++  val divisors : int -> graph+    (** [divisors n] builds the graph of divisors. +      Vertices are integers from [2] to [n]. [i] is connected to [j] if+      and only if [i] divides [j]. +      @raise Invalid_argument is [n < 2]. *)++  val de_bruijn : int -> graph+    (** [de_bruijn n] builds the de Bruijn graph of order [n].+      Vertices are bit sequences of length [n] (encoded as their+      interpretation as binary integers). The sequence [xw] is connected+      to the sequence [wy] for any bits [x] and [y] and any bit sequence +      [w] of length [n-1]. +      @raise Invalid_argument is [n < 1] or [n > Sys.word_size-1]. *)++  val vertex_only : int -> graph+    (** [vertex_only n] builds a graph with [n] vertices and no edge. *)++  val full : ?self:bool -> int -> graph+    (** [full n] builds a graph with [n] vertices and all possible edges.+      The optional argument [self] indicates if loop edges should be added+      (default value is [true]). *)++end++module P (G : Sig.P with type V.label = int) : S with type graph = G.t+  (** Classic Persistent Graphs *)++module I (G : Sig.I with type V.label = int) : S with type graph = G.t+  (** Classic Imperative Graphs *)
+ external/ocamlgraph/src/cliquetree.ml view
@@ -0,0 +1,343 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(**+  Clique tree of a graph.+  +  @author Matthieu Sozeau+*)++(*i $Id: cliquetree.ml,v 1.6 2005-11-02 13:43:35 filliatr Exp $ i*)++module CliqueTree(Gr : Sig.G) = struct++  (* Original vertex set (of Gr) *)+  module OVSet = Set.Make(Gr.V) +    +  (* Vertex signature *)+  module rec CliqueV : +  sig +    type t+    val compare : t -> t -> int  +    val hash : t -> int+    val equal : t -> t -> bool+    val label : t -> t+    val create : Gr.V.t -> t+    val vertex : t -> Gr.V.t+    val number : t -> int+    val set_number : t -> int -> unit+    val clique : t -> int+    val set_clique : t -> int -> unit+    val mark : t -> int+    val incr_mark : t -> unit+    val m : t -> CVS.t+    val set_m : t -> CVS.t -> unit+    val last : t -> t+    val set_last : t -> t -> unit+  end =+  struct+    type t = {+      mutable mark: int;+      orig: Gr.V.t;+      mutable m: CVS.t;+      mutable last: t option;+      mutable number: int;+      mutable clique: int;+    }++    let compare x y = Gr.V.compare x.orig y.orig+    let hash x = Gr.V.hash x.orig+    let equal x y = Gr.V.equal x.orig y.orig++    type label = t+    let label x = x++    let create o = { +      mark = 0; +      orig = o; +      m = CVS.empty;+      last = None;+      number = 0;+      clique = -1;+    }++    let vertex x = x.orig++    let clique x = x.clique+    let set_clique x v = x.clique <- v++    let number x = x.number+    let set_number x v = x.number <- v++    let mark x = x.mark+    let incr_mark x = +      (*Printf.printf "Increasing mark of %s to %i\n%!"+	(Gr.v_to_string x.orig) (succ x.mark);*)+      x.mark <- succ x.mark++    let m x = x.m+    let set_m x v = x.m <- v+		      +    let last x = +      match x.last with+	  Some v -> v+	| None -> failwith "last not set"+	    +    let set_last x v = x.last <- Some v++  end+    (* Clique tree vertex set *)+  and CVS : Set.S with type elt = CliqueV.t = Set.Make(CliqueV)+		    +  (* The final clique tree vertex type:+     - set of original vertexes ordered by mark.+     - clique number.+  *)+  module CliqueTreeV = +    Util.DataV+      (struct type t = CliqueV.t list * CVS.t end)+      (struct+	 type t = int+	 type label = int+	 let compare x y = Pervasives.compare x y+	 let hash = Hashtbl.hash+	 let equal x y = x = y+	 let label x = x+	 let create lbl = lbl+       end)  +    +  module CliqueTreeE = struct+    type t = int * CVS.t+	+    let compare (x, _) (y, _) = Pervasives.compare x y++    let default = (0, CVS.empty)+		    +    let create n s = (n, s)+		       +    let vertices = snd++    let width g tri (_, x) = +      let vertices = List.map CliqueV.vertex (CVS.elements x) in+      let w =+	List.fold_left+	  (fun w v ->+	     List.fold_left+	     (fun w v' ->+		if v <> v' then+		  if not (Gr.mem_edge g v v') && Gr.mem_edge tri v v'+		  then succ w+		  else w+		else w)+	     w vertices)+	  0 vertices+      in +      assert(w mod 2 = 0);+      w / 2+  end+    +  (* The returned tree *)+  module CliqueTree =+    Persistent.Digraph.ConcreteLabeled(CliqueTreeV)(CliqueTreeE)+      +  (* Intermediate graph *)+  module G = Persistent.Graph.Concrete(CliqueV)+    +  (* Convenient types *)+  module EdgeSet = Set.Make(G.E)+  module H = Hashtbl.Make(CliqueV)++  (* Used to choose some vertex in the intermediate graph *)+  module Choose = Oper.Choose(G)++  (* Creates the intermediate graph from the original *)+  module Copy = Gmap.Vertex(Gr)(struct include G include Builder.P(G) end)++  open CliqueV++  let vertices_list x =+    let l = CVS.elements x in+    List.sort+      (fun x y -> +	 (*let markx = mark x and marky = mark y in*)+	 - Pervasives.compare (number x) (number y))+      l++  let mcs_clique g =+    (* initializations *)+    let n = Gr.nb_vertex g in+    let g' = Copy.map CliqueV.create g in+    let unnumbered = ref (G.fold_vertex CVS.add g' CVS.empty) in+    let pmark = ref (-1) in+    let order = ref [] in+    let cliques = Array.make n ([], CVS.empty) in+    let ties = ref [] in+    let j = ref 0 in+      (* loop, taking each unnumbered vertex in turn *)+      for i = n downto 1 do+	(* Find greatest unnumbered vertex+	   if CVS.is_empty !unnumbered then+	   Printf.printf "No more unnumbered vertices\n%!"+	   else+	   Printf.printf "%i unnumbered vertices remaining\n%!" +	   (CVS.cardinal !unnumbered);+	*)+ 	let x, mark = +	  let choosed = CVS.choose !unnumbered in+ 	    CVS.fold+ 	      (fun x ((maxx, maxv) as max) ->+ 		 let v = mark x in+ 		 if v > maxv then (x, v) else max)+ 	      !unnumbered (choosed, mark choosed)+  	in+	  (* peo construction *)+	  order := x :: !order;+	  (* now numbered *)+	  unnumbered := CVS.remove x !unnumbered;+	  if mark <= !pmark then begin+	    (* Create a new clique (lemma 8) *)+	    incr j;+	    (* m x is the neighborhoud of x in the previous clique *)+	    cliques.(!j) <- ([x], CVS.add x (m x));+	    (* Use reverse map of cliques to find what clique +	       we're connected to. m x is the width of the ties *)+	    let clast = clique (last x) in+	    ties := (clast, m x, !j) :: !ties;+	  end else begin+	    let l, c = cliques.(!j) in+	    cliques.(!j) <- (x::l, CVS.add x c);+	  end;+	  G.iter_succ+	    (fun y ->+	       if number y == 0 then begin+		 incr_mark y;+		 set_m y (CVS.add x (m y));+	       end;+	       set_last y x)+	    g' x;+	  pmark := mark;+	  set_number x i;+	  set_clique x !j;+      done;+      let cliques = +	Array.mapi+	  (fun i (l, c) -> CliqueTreeV.create (List.rev l, c) i)+	  (Array.sub cliques 0 (succ !j))+      in+      let tree = +	Array.fold_left CliqueTree.add_vertex CliqueTree.empty cliques+      in+      let tree, _ = +	List.fold_left+	  (fun (g, n) (i, verts, j) ->	     +	     let label = CliqueTreeE.create n verts in+	     let edge = CliqueTree.E.create cliques.(i) label cliques.(j) in+	     (CliqueTree.add_edge_e g edge, succ n))+	  (tree, 1) !ties+      in+      List.map CliqueV.vertex !order, tree, cliques.(0)++   let sons g x = CliqueTree.fold_succ (fun x y -> x :: y) g x []++   exception NotClique++   let rec drop_while p l =+     match l with+       | x :: tl -> +	   if p x then drop_while p tl+	   else l+       | [] -> []++   let test_simpliciality_first l sons =+     let takeOne l = match !l with+       | x :: xs -> l := xs; Some x+       | [] -> None+     in+     let vertices = ref l in+     let sons = ref sons in+     try+       while !vertices <> [] && not (List.for_all (fun c -> !c = []) !sons) do+	 (match takeOne vertices with+	      Some v -> +		let mark = CliqueV.mark v in+		List.iter+		  (fun s -> +		     match !s with+		       | y :: tl -> +			   let ymark = CliqueV.mark y in+			   if ymark > mark then+			     ()+			   else if ymark = mark then+			     s := drop_while +			       (fun y -> CliqueV.mark y = mark) tl+			   else raise NotClique+		       | [] -> ())+		  !sons+	      | None -> assert false);+       done;+       !vertices <> []+     with NotClique -> false++   let test_simpliciality_first' l sons =+     List.for_all+       (fun son ->+	  match !son with+	    | [] -> false+	    | xi :: tl ->+		let other = m xi in+		CVS.subset other l)+       sons++   let test_simpliciality_next vertices sons =+     match vertices with+       | x :: tl ->+	   begin+	     try+	       ignore(+		 List.fold_left+			(fun vm v' ->+			   let vm' = CliqueV.m v' in+			   if CVS.equal vm' vm then+			     CVS.add v' vm'+			   else raise NotClique)+			(CVS.add x (m x)) tl);+	       true+	     with NotClique -> false+	   end+       | _ -> true++   let is_chordal g = +     let order, tree, root = mcs_clique g in+     let rec aux c = +       let csons = sons tree c in+       let s = List.map CliqueTreeV.data csons in+       let l = CliqueTreeV.data c in+       let sons () = List.map (fun (x,y) -> ref x) s in+       let first = test_simpliciality_first' (snd l) (sons ()) in+       let next = test_simpliciality_next (fst l) (sons ()) in+       first && next && (List.for_all aux csons)+     in +     aux root+	  +   let maxwidth g tri tree = +     CliqueTree.fold_edges_e+       (fun e res -> +	  let w = CliqueTreeE.width g tri (CliqueTree.E.label e) in	   +	  max res w)+       tree 0      	 ++end
+ external/ocamlgraph/src/cliquetree.mli view
@@ -0,0 +1,90 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(**+  Construction of the clique tree of a graph and recognition+  of chordal graphs.+  +  Based on the article:+  Chordal graphs and their clique graph+  by P. Galinier, M. Habib and C. Paul.+  +  @author Matthieu Sozeau+*)++(*i $Id: cliquetree.mli,v 1.4 2004-10-19 15:22:47 signoles Exp $ i*)++module CliqueTree(G : Sig.G) : sig++  (** Original graph vertex *)+  module CliqueV :+  sig+    type t+    val compare : t -> t -> int+    val hash : t -> int+    val equal : t -> t -> bool+    val label : t -> t+    val create : G.V.t -> t+    val vertex : t -> G.V.t+  end++  (** Set of original vertices *)+  module CVS : Set.S with type elt = CliqueV.t+		       +  (** Clique tree vertex type *)+  module CliqueTreeV : sig+    (** Trace of the algorithm as a list of markers Clique vertices *)+    type data = CliqueV.t list * CVS.t+    type label+    type t++    val compare : t -> t -> int+    val hash : t -> int+    val equal : t -> t -> bool+	    +    val create : data -> label -> t+    val label : t -> label+    val data : t -> data+  end+	+  module CliqueTreeE : sig+    type t = int * CVS.t+    val compare : t -> t -> int+    val default : t+    val create : int -> CVS.t -> t+	    +    (** Vertices in the clique tree edge +      (intersection of the two clique extremities). *)+    val vertices : t -> CVS.t+  end+	+  (** The clique tree graph type *)+  module CliqueTree : Sig.G with type V.t = CliqueTreeV.t+			    and type E.label = CliqueTreeE.t+      +  (** [mcs_clique g] return an perfect elimination order of [g] +    (if it is chordal), the clique tree of [g] and its root.  *)+  val mcs_clique : G.t -> G.V.t list * CliqueTree.t * CliqueTree.V.t++  (** [is_chordal g] uses the clique tree construction to test if a graph is +    chordal or not. *)+  val is_chordal : G.t -> bool++  (** [maxwidth g tri tree] returns the maxwidth characteristic of the+    triangulation [tri] of graph [g] given the clique tree [tree] of [tri]. *)+  val maxwidth : G.t -> G.t -> CliqueTree.t -> int+end
+ external/ocamlgraph/src/components.ml view
@@ -0,0 +1,90 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: components.ml,v 1.9 2004-10-22 14:42:06 signoles Exp $ *)++open Util++module type G = sig+  type t+  module V : Sig.COMPARABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+end++module Make(G: G) = struct++  module H = Hashtbl.Make(G.V)+  module S = Set.Make(G.V)++  let scc g =+    let root = H.create 997 in+    let hashcomp = H.create 997 in+    let stack = ref [] in+    let numdfs = ref 0 in+    let numcomp = ref 0 in+    let rec pop x c = function+      | (y, w) :: l when y > x -> +	  H.add hashcomp w !numcomp; +	  pop x (S.add w c) l+      | l -> c,l+    in+    let rec visit v = +      if not (H.mem root v) then+	begin+	  let n = incr numdfs; !numdfs in+	  H.add root v n; +	  G.iter_succ +	    (fun w -> +	       visit w;+	       if not (H.mem hashcomp w) then +		 H.replace root v (min (H.find root v) (H.find root w)))+	    g v;+	  if H.find root v = n then +	    (H.add hashcomp v !numcomp;+	     let comp,s = pop n (S.add v S.empty) !stack in +	     stack:= s;+	     incr numcomp)+	  else stack := (n,v)::!stack;+	end+    in +    G.iter_vertex visit g;+    (!numcomp,(fun v -> H.find hashcomp v))++  let scc_array g =+    let n,f = scc g in+    let t = Array.make n [] in+    G.iter_vertex +      (fun v -> let i = f v in t.(i) <- v::t.(i)) g;+    t++  let scc_list g =+    let _,scc = scc g in+    let tbl = Hashtbl.create 97 in+    G.iter_vertex +      (fun v -> +	 let n = scc v in+	 try+	   let l = Hashtbl.find tbl n in+	   l := v :: !l+	 with Not_found ->+	   Hashtbl.add tbl n (ref [ v ]))+      g;+    Hashtbl.fold (fun _ v l -> !v :: l) tbl []+++end
+ external/ocamlgraph/src/components.mli view
@@ -0,0 +1,53 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: components.mli,v 1.12 2004-10-22 14:42:06 signoles Exp $ *)++(** Strongly connected components *)++open Util++(** Minimal graph signature for [scc] *)+module type G = sig+  type t+  module V : Sig.COMPARABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+end++module Make (G: G) : sig++  val scc : G.t -> int*(G.V.t -> int)+    (** [scc g] computes the strongly connected components of [g].+	The result is a pair [(n,f)] where [n] is the number of+	components. Components are numbered from [0] to [n-1], and+	[f] is a function mapping each vertex to its component+	number. In particular, [f u = f v] if and only if [u] and+	[v] are in the same component. Another property of the+	numbering is that components are numbered in a topological+	order: if there is an arc from [u] to [v], then [f u >= f u] *)++  val scc_array : G.t -> G.V.t list array+    (** [scc_array] computes the strongly connected components of [g].+	Components are stored in the resulting array, indexed with a+	numbering with the same properties as for [scc] above. *)++  val scc_list : G.t -> G.V.t list list+    (** [scc_list] computes the strongly connected components of [g].+	The result is a partition of the set of the vertices of [g]. *)++end
+ external/ocamlgraph/src/delaunay.ml view
@@ -0,0 +1,344 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: delaunay.ml,v 1.12 2005-11-02 13:43:35 filliatr Exp $ *)++(** Code follows Don Knuth's algorithm+    from ``Axioms and hulls'' (LNCS 606, Springer-Verlag, 1992), pp. 73-77 *)++open Printf++module type CCC = sig+  type point+  val ccw : point -> point -> point -> bool+  val in_circle : point -> point -> point -> point -> bool+end++module type Triangulation = sig+  module S : CCC+  type triangulation+  val triangulate : S.point array -> triangulation+  val iter : (S.point -> S.point -> unit) -> triangulation -> unit+  val fold : (S.point -> S.point -> 'a -> 'a) -> triangulation -> 'a -> 'a+end++module Make (S : CCC) = struct++  module S = S++  type point = Point of int | Infinity++  type arc = { mutable vert : point;+	       mutable next : arc;+	       mutable inst : node ref;+	       mate : int }+  and node = +    | Branch of int * int * node ref * node ref+    | Terminal of arc++  type triangulation = { +    points : S.point array; +    arcs : arc array;+    last_used_arc : int +  }++  let rec dummy_arc = +    { vert = Infinity; next = dummy_arc; +      inst = ref (Terminal dummy_arc); mate = -1 }++  let make_arc n i =+    { vert = Infinity; next = dummy_arc; +      inst = ref (Terminal dummy_arc); mate = 6 * n - 7 - i }++  let finite = function Point p -> p | Infinity -> assert false++  (* [flip] will be used in both steps T4 and T5 *)+  let flip c d e t'' p n n' =+    let e' = e.next in+    let c' = c.next in+    let c'' = c'.next in+    e.next <- c;+    c.next <- c'';+    c''.next <- e;+    c''.inst <- n; c.inst <- n; e.inst <- n;+    c.vert <- Point p;+    d.next <- e';+    e'.next <- c'; +    c'.next <- d;+    c'.inst <- n'; e'.inst <- n'; d.inst <- n';+    d.vert <- Point t''++  let triangulate points =+    let ccw p q r = S.ccw points.(p) points.(q) points.(r) in+    let in_circle p q r s = +      S.in_circle points.(p) points.(q) points.(r) points.(s)+    in+    let n = Array.length points in+    if n < 2 then invalid_arg "triangulate";+    let arcs = Array.init (6 * n - 6) (make_arc n) in+    let mate i = 6 * n - 7 - i in++  (*i DEBUG+  let rec dump d l = +    eprintf "%s" (String.make (2*d) ' ');+    match !l with+      | Terminal a ->+	  eprintf "T %d\n" (mate a.mate)+      | Branch (u, v, l, r) ->+	  eprintf "N %d %d\n" u v;+	  dump (d+1) l;+	  dump (d+1) r+  in+  i*)++    (* initialization: +       create a trivial triangulation for the first 2 vertices *)+    let u = 0 in+    let v = 1 in+    let a1 = arcs.(0) in+    let a2 = arcs.(1) in+    let a3 = arcs.(2) in+    let b1 = arcs.(mate 0) in+    let b2 = arcs.(mate 1) in+    let b3 = arcs.(mate 2) in+    let l1 = ref (Terminal a2) in+    let l2 = ref (Terminal b3) in+    a1.vert <- Point v;  a1.next <- a2; a1.inst <- l1;+    a2.vert <- Infinity; a2.next <- a3; a2.inst <- l1;+    a3.vert <- Point u;  a3.next <- a1; a3.inst <- l1;+    b1.vert <- Point u;  b1.next <- b3; b1.inst <- l2;+    b2.vert <- Point v;  b2.next <- b1; b2.inst <- l2;+    b3.vert <- Infinity; b3.next <- b2; b3.inst <- l2;+    let l0 = ref (Branch (u, v, l1, l2)) in+    let j = ref 2 in (* last used arc *)++    (* then for each new vertex [p] *)+    for p = 2 to n - 1 do+      (* Step T1 *)+      let rec step_T1 l p = match !l with+	| Terminal al -> +	    l, al+	| Branch (pl, ql, al, bl) -> +	    step_T1 (if ccw pl ql p then al else bl) p+      in+      let l, al = step_T1 l0 p in++      (* Step T2 *)+      let a = al in+      let b = a.next in+      let c = b.next in+      let q = a.vert in+      let r = b.vert in+      let s = c.vert in+      j := !j + 3;+      let aj = arcs.(!j) in+      let aj_1 = arcs.(!j - 1) in+      let aj_2 = arcs.(!j - 2) in+      let bj = arcs.(aj.mate) in+      let bj_1 = arcs.(aj_1.mate) in+      let bj_2 = arcs.(aj_2.mate) in+      let l' = ref (Terminal a) in+      let l'' = ref (Terminal aj) in+      let l''' = ref (Terminal c) in+      aj.vert   <- q;         aj.next <- b;      aj.inst <- l'';+      aj_1.vert <- r;       aj_1.next <- c;    aj_1.inst <- l''';+      aj_2.vert <- s;       aj_2.next <- a;    aj_2.inst <- l';+      bj.vert   <- Point p;   bj.next <- aj_2;   bj.inst <- l';+      bj_1.vert <- Point p; bj_1.next <- aj;   bj_1.inst <- l'';+      bj_2.vert <- Point p; bj_2.next <- aj_1; bj_2.inst <- l''';+      a.next <- bj;   a.inst <- l'; +      b.next <- bj_1; b.inst <- l'';+      c.next <- bj_2; c.inst <- l''';+      let r = finite r in+      let s = finite s in++      (* steps T3 or T4 depending on [q] *)+      let r = match q with+	| Point q -> (* Step T3 *)+	    let n = ref (Branch (q, p, l', l'')) in+	    let n' = ref (Branch (s, p, l''', l')) in+	    l := Branch (r, p, n, n');+	    r+	| Infinity -> (* Step T4 *)+	    let n = ref (Branch (s, p, l''', l')) in+	    l := Branch (r, p, l'', n);+	    let rec loop m a d s t =+	      if t <> r && ccw p s t then begin+		let n = ref (Terminal d) in+		match !m with+		  | Branch (mu, mv, ml, is_l') -> +		      assert (is_l' == l');+		      m := Branch (mu, mv, ml, d.inst);+		      d.inst := Branch (t, p, n, l');+		      let m = d.inst in+		      flip a arcs.(a.mate) d t p n l';+		      let a = arcs.(a.mate).next in+		      let d = arcs.(a.mate).next in+		      let s = t in+		      let t = finite d.vert in+		      l' := Terminal a;+		      loop m a d s t+		  | Terminal _ -> +		      assert false+	      end else begin+		(* at exit of while loop *)+		let n = ref (Terminal d.next) in+		d.inst := Branch (s, p, n, l');+		d.inst <- n; d.next.inst <- n; d.next.next.inst <- n;+		s+	      end+	    in+	    let d = arcs.(a.mate).next in+	    loop n a d s (finite d.vert)+      in++      (* Step T5 *)+      let rec loop c =+	let d = arcs.(c.mate) in+	let e = d.next in+	let t = finite d.vert in+	let t' = finite c.vert in+	let t'' = e.vert in+	if t'' <> Infinity && in_circle (finite t'') t' t p then begin+	  let t'' = finite t'' in+	  let n = ref (Terminal e) in+	  let n' = ref (Terminal d) in+	  c.inst := Branch (t'', p, n, n');+	  d.inst := Branch (t'', p, n, n');+	  flip c d e t'' p n n';+	  loop e+	end else if t' <> r then+	  loop arcs.(c.next.mate).next+	else+	  () (* break *)+      in+      loop c++    done;+    { points = points; arcs = arcs; last_used_arc = !j }++  let iter f t =+    let points = t.points in+    let n = Array.length t.arcs in+    for i = 0 to t.last_used_arc do+      match t.arcs.(i).vert, t.arcs.(n - 1 - i).vert with+	| Point u, Point v -> f points.(u) points.(v)+	| _ -> ()+    done++  let fold f t a =+    let points = t.points in+    let n = Array.length t.arcs in+    let rec loop i a =+      if i <= t.last_used_arc then+	match t.arcs.(i).vert, t.arcs.(n - 1 - i).vert with+	  | Point u, Point v -> loop (succ i) (f points.(u) points.(v) a)+	  | _ -> loop (succ i) a+      else+	a+    in+    loop 0 a++end++(** Points with floating point coordinates *)++module FloatPoints = struct++  type point = float * float++  let ( + ) = ( +. )+  let ( - ) = ( -. )+  let ( * ) = ( *. )++  let det = function+    | [| [| a00; a01 |];+	 [| a10; a11 |] |] -> +	a00 * a11 - a01 * a10+    | [| [| a00; a01; a02 |];+	 [| a10; a11; a12 |];+	 [| a20; a21; a22 |] |] -> +	a00*a11*a22 - a00*a12*a21 - a10*a01*a22 + +	a10*a02*a21 + a20*a01*a12 - a20*a02*a11+    | [| [| a00; a01; a02; a03 |];+	 [| a10; a11; a12; a13 |];+	 [| a20; a21; a22; a23 |];+	 [| a30; a31; a32; a33 |] |] -> +	a00*a11*a22*a33 - a00*a11*a23*a32 - a00*a21*a12*a33 + +	a00*a21*a13*a32 + a00*a31*a12*a23 - a00*a31*a13*a22 - +	a10*a01*a22*a33 + a10*a01*a23*a32 + a10*a21*a02*a33 - +	a10*a21*a03*a32 - a10*a31*a02*a23 + a10*a31*a03*a22 + +	a20*a01*a12*a33 - a20*a01*a13*a32 - a20*a11*a02*a33 + +	a20*a11*a03*a32 + a20*a31*a02*a13 - a20*a31*a03*a12 - +	a30*a01*a12*a23 + a30*a01*a13*a22 + a30*a11*a02*a23 - +	a30*a11*a03*a22 - a30*a21*a02*a13 + a30*a21*a03*a12+    | _ -> assert false++  let ccw (xu,yu) (xv,yv) (xw,yw) = +    det [| [| xu; yu; 1.0 |];+	   [| xv; yv; 1.0 |];+	   [| xw; yw; 1.0 |] |] > 0.0++  (*i DEBUG+  let ccw (xu,yu) (xv,yv) (xw,yw) = +    eprintf "ccw((%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f)) -> " +      xu yu xv yv xw yw;+    let r = ccw (xu,yu) (xv,yv) (xw,yw) in+    eprintf "%b\n" r; flush stderr;+    r+  i*)++  let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) = +    det [| [| xt; yt; (xt * xt + yt * yt); 1.0 |];+	   [| xu; yu; (xu * xu + yu * yu); 1.0 |];+	   [| xv; yv; (xv * xv + yv * yv); 1.0 |];+	   [| xw; yw; (xw * xw + yw * yw); 1.0 |]; |] > 0.0++  (*i DEBUG+  let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) = +    eprintf "in_circle((%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f)) -> " +      xt yt xu yu xv yv xw yw;+    let r = in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) in+    eprintf "%b\n" r; flush stderr;+    r+  i*)++end++module Float = Make(FloatPoints)++(** Points with integer coordinates.+    We approximate using module [FloatPoints] but this could be made exact+    following Knuth's code in Axioms and Hulls *)++module IntPoints = struct++  type point = int * int++  let ccw (xu,yu) (xv,yv) (xw,yw) = +    FloatPoints.ccw +      (float xu, float yu) (float xv, float yv) (float xw, float yw)++  let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) = +    FloatPoints.in_circle+      (float xt, float yt)+      (float xu, float yu) (float xv, float yv) (float xw, float yw)++end++module Int = Make(IntPoints)+
+ external/ocamlgraph/src/delaunay.mli view
@@ -0,0 +1,76 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: delaunay.mli,v 1.8 2004-02-20 14:37:40 signoles Exp $ *)++(** Delaunay triangulation *)++(** Delaunay triangulation is available for any CCC system in the sense+    of Knuth's ``Axioms and Hulls'' *)+module type CCC = sig++  type point++  val ccw : point -> point -> point -> bool+    (** The counterclockwise relation [ccw p q r] states that the +      circle through points [(p,q,r)] is traversed counterclockwise +      when we encounter the points in cyclic order [p,q,r,p,...] **)++  val in_circle : point -> point -> point -> point -> bool+    (** The relation [in_circle p q r s] states that [s] lies +      inside the circle [(p,q,r)] if [ccw p q r] is true, or outside that +      circle if [ccw p q r] is false. *)++end++(** The result of triangulation is an abstract value of type [triangulation].+  Then one can iterate over all edges of the triangulation. *)+module type Triangulation = sig++  module S : CCC++  type triangulation++  val triangulate : S.point array -> triangulation+    (** [triangulate a] computes the Delaunay triangulation of a set of +      points, given as an array [a]. If [N] is the number of points+      (that is [Array.length a]), then the running time is $O(N \log N)$+      on the average and $O(N^2)$ on the worst-case. The space used is +      always $O(N)$. *)++  val iter : (S.point -> S.point -> unit) -> triangulation -> unit+    (** [iter f t] iterates over all edges of the triangulation [t]. +      [f u v] is called once for each undirected edge [(u,v)]. *)++  val fold : (S.point -> S.point -> 'a -> 'a) -> triangulation -> 'a -> 'a++end++(** Generic Delaunay triangulation *)+module Make(S : CCC) : Triangulation with module S = S++(** Points with integer coordinates *)+module IntPoints : CCC with type point = int * int++(** Delaunay triangulation with integer coordinates *)+module Int : Triangulation with module S = IntPoints++(** Points with floating point coordinates *)+module FloatPoints : CCC with type point = float * float++(** Delaunay triangulation with floating point coordinates *)+module Float : Triangulation with module S = FloatPoints
+ external/ocamlgraph/src/dot.ml view
@@ -0,0 +1,78 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++(** Parser for DOT file format *)++open Dot_ast++module Parse +  (B : Builder.S)+  (L : sig +     val node : node_id -> attr list -> B.G.V.label+       (** how to build the node label out of the set of attributes *)+     val edge : attr list -> B.G.E.label +       (** how to build the edge label out of the set of attributes *)+   end) =+struct++  let create_graph dot =+    let nodes = Hashtbl.create 97 in+    let node g id l =+      try+	g, Hashtbl.find nodes id+      with Not_found ->+	let n = B.G.V.create (L.node id l) in+	Hashtbl.add nodes id n;+	B.add_vertex g n, n+    in+    List.fold_left+      (fun g s -> match s with+	| Node_stmt (id, al) ->+	    let g,_ = node g id al in g+	| Edge_stmt (NodeId id, nl, al) ->+	    let el = L.edge al in+	    let g,vn = node g id [] in+	    List.fold_left+	      (fun g m -> match m with+		| NodeId idm -> +		    let g,vm = node g idm [] in+		    let e = B.G.E.create vn el vm in+		    B.add_edge_e g e+		| NodeSub _ -> +		    g)+	      g nl+	| _ ->+	    g)+      (B.empty ()) +      dot.stmts++  let parse f =+    let c = open_in f in+    let lb = Lexing.from_channel c in+    let dot = +      try+	Dot_parser.file Dot_lexer.token lb +      with Parsing.Parse_error ->+	let n = Lexing.lexeme_start lb in+	failwith (Printf.sprintf "Dot.parse: parse error character %d" n)+    in+    close_in c;+    create_graph dot++end
+ external/ocamlgraph/src/dot.mli view
@@ -0,0 +1,34 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(** Parser for DOT file format *)++open Dot_ast++module Parse +  (B : Builder.S)+  (L : sig +     val node : node_id -> attr list -> B.G.V.label+       (** how to build the node label out of the set of attributes *)+     val edge : attr list -> B.G.E.label +       (** how to build the edge label out of the set of attributes *)+   end) :+sig+  +  val parse : string -> B.G.t++end
+ external/ocamlgraph/src/dot_ast.mli view
@@ -0,0 +1,57 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++type id = +  | Ident of string+  | Number of string+  | String of string+  | Html of string++type attr = (id * id option) list++type compass_pt = N | Ne | E | Se | S | Sw | W | Nw++type port = +  | PortId of id * compass_pt option+  | PortC of compass_pt++type node_id = id * port option++type subgraph = +  | SubgraphId of id+  | SubgraphDef of id option * stmt list++and node =+  | NodeId of node_id+  | NodeSub of subgraph++and stmt = +  | Node_stmt of node_id * attr list+  | Edge_stmt of node * node list * attr list+  | Attr_graph of attr list+  | Attr_node of attr list+  | Attr_edge of attr list+  | Equal of id * id+  | Subgraph of subgraph++type file =+  { strict : bool;+    digraph : bool;+    id : id option;+    stmts : stmt list }
+ external/ocamlgraph/src/dot_lexer.ml view
@@ -0,0 +1,386 @@+# 20 "src/dot_lexer.mll"+ +  open Lexing+  open Dot_ast+  open Dot_parser++  let string_buf = Buffer.create 1024++  let keyword =+    let h = Hashtbl.create 17 in+    List.iter +      (fun (s,k) -> Hashtbl.add h s k)+      [+	"strict", STRICT;+	"graph", GRAPH;+	"digraph", DIGRAPH;+	"subgraph", SUBGRAPH;+	"node", NODE;+	"edge", EDGE;+      ];+    fun s -> let s = String.lowercase s in Hashtbl.find h s+++# 25 "src/dot_lexer.ml"+let __ocaml_lex_tables = {+  Lexing.lex_base = +   "\000\000\238\255\239\255\240\255\241\255\078\000\088\000\098\000\+    \176\000\245\255\246\255\247\255\248\255\249\255\250\255\251\255\+    \252\255\114\000\001\000\005\000\254\255\002\000\253\255\191\000\+    \244\255\211\000\221\000\157\000\252\255\253\255\002\000\255\255\+    \254\255\032\000\252\255\253\255\254\255\255\255\054\000\253\255\+    \254\255\015\000\255\255";+  Lexing.lex_backtrk = +   "\255\255\255\255\255\255\255\255\255\255\013\000\017\000\012\000\+    \017\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\017\000\017\000\000\000\255\255\255\255\255\255\255\255\+    \255\255\013\000\013\000\255\255\255\255\255\255\002\000\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\001\000\255\255";+  Lexing.lex_default = +   "\001\000\000\000\000\000\000\000\000\000\255\255\255\255\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\255\255\021\000\255\255\000\000\021\000\000\000\255\255\+    \000\000\255\255\255\255\029\000\000\000\000\000\255\255\000\000\+    \000\000\035\000\000\000\000\000\000\000\000\000\040\000\000\000\+    \000\000\255\255\000\000";+  Lexing.lex_trans = +   "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\019\000\019\000\020\000\020\000\019\000\019\000\019\000\+    \000\000\000\000\019\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \019\000\000\000\004\000\018\000\032\000\019\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\015\000\008\000\006\000\017\000\+    \005\000\005\000\005\000\005\000\005\000\005\000\005\000\005\000\+    \005\000\005\000\016\000\014\000\003\000\013\000\042\000\000\000\+    \000\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\010\000\036\000\009\000\037\000\007\000\+    \041\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\012\000\026\000\011\000\005\000\005\000\+    \005\000\005\000\005\000\005\000\005\000\005\000\005\000\005\000\+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\+    \025\000\025\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\022\000\000\000\000\000\000\000\+    \000\000\021\000\000\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\000\000\000\000\031\000\+    \000\000\007\000\000\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\024\000\023\000\000\000\+    \005\000\005\000\005\000\005\000\005\000\005\000\005\000\005\000\+    \005\000\005\000\000\000\000\000\000\000\000\000\024\000\025\000\+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\+    \025\000\030\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \002\000\255\255\255\255\025\000\025\000\025\000\025\000\025\000\+    \025\000\025\000\025\000\025\000\025\000\026\000\026\000\026\000\+    \026\000\026\000\026\000\026\000\026\000\026\000\026\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \034\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\039\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\028\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000";+  Lexing.lex_check = +   "\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\000\000\000\000\018\000\021\000\000\000\019\000\019\000\+    \255\255\255\255\019\000\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \000\000\255\255\000\000\000\000\030\000\019\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\041\000\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\033\000\000\000\033\000\000\000\+    \038\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\005\000\000\000\005\000\005\000\+    \005\000\005\000\005\000\005\000\005\000\005\000\005\000\005\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\017\000\255\255\255\255\255\255\+    \255\255\017\000\255\255\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\255\255\255\255\027\000\+    \255\255\007\000\255\255\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\008\000\008\000\255\255\+    \008\000\008\000\008\000\008\000\008\000\008\000\008\000\008\000\+    \008\000\008\000\255\255\255\255\255\255\255\255\008\000\023\000\+    \023\000\023\000\023\000\023\000\023\000\023\000\023\000\023\000\+    \023\000\027\000\255\255\255\255\255\255\255\255\255\255\255\255\+    \000\000\018\000\021\000\025\000\025\000\025\000\025\000\025\000\+    \025\000\025\000\025\000\025\000\025\000\026\000\026\000\026\000\+    \026\000\026\000\026\000\026\000\026\000\026\000\026\000\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \033\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\038\000\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\027\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255";+  Lexing.lex_base_code = +   "";+  Lexing.lex_backtrk_code = +   "";+  Lexing.lex_default_code = +   "";+  Lexing.lex_trans_code = +   "";+  Lexing.lex_check_code = +   "";+  Lexing.lex_code = +   "";+}++let rec token lexbuf =+    __ocaml_lex_token_rec lexbuf 0+and __ocaml_lex_token_rec lexbuf __ocaml_lex_state =+  match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 52 "src/dot_lexer.mll"+      ( token lexbuf )+# 191 "src/dot_lexer.ml"++  | 1 ->+# 54 "src/dot_lexer.mll"+      ( token lexbuf )+# 196 "src/dot_lexer.ml"++  | 2 ->+# 56 "src/dot_lexer.mll"+      ( comment lexbuf; token lexbuf )+# 201 "src/dot_lexer.ml"++  | 3 ->+# 58 "src/dot_lexer.mll"+      ( COLON )+# 206 "src/dot_lexer.ml"++  | 4 ->+# 60 "src/dot_lexer.mll"+      ( COMMA )+# 211 "src/dot_lexer.ml"++  | 5 ->+# 62 "src/dot_lexer.mll"+      ( SEMICOLON )+# 216 "src/dot_lexer.ml"++  | 6 ->+# 64 "src/dot_lexer.mll"+      ( EQUAL )+# 221 "src/dot_lexer.ml"++  | 7 ->+# 66 "src/dot_lexer.mll"+      ( LBRA )+# 226 "src/dot_lexer.ml"++  | 8 ->+# 68 "src/dot_lexer.mll"+      ( RBRA )+# 231 "src/dot_lexer.ml"++  | 9 ->+# 70 "src/dot_lexer.mll"+      ( LSQ )+# 236 "src/dot_lexer.ml"++  | 10 ->+# 72 "src/dot_lexer.mll"+      ( RSQ )+# 241 "src/dot_lexer.ml"++  | 11 ->+# 74 "src/dot_lexer.mll"+      ( EDGEOP )+# 246 "src/dot_lexer.ml"++  | 12 ->+let+# 75 "src/dot_lexer.mll"+             s+# 252 "src/dot_lexer.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_pos in+# 76 "src/dot_lexer.mll"+      ( try keyword s with Not_found -> ID (Ident s) )+# 256 "src/dot_lexer.ml"++  | 13 ->+let+# 77 "src/dot_lexer.mll"+              s+# 262 "src/dot_lexer.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_pos in+# 78 "src/dot_lexer.mll"+      ( ID (Number s) )+# 266 "src/dot_lexer.ml"++  | 14 ->+# 80 "src/dot_lexer.mll"+      ( Buffer.clear string_buf; +	let s = string lexbuf in+	ID (String s) )+# 273 "src/dot_lexer.ml"++  | 15 ->+# 84 "src/dot_lexer.mll"+      ( Buffer.clear string_buf; +	html lexbuf; +	ID (Html (Buffer.contents string_buf)) )+# 280 "src/dot_lexer.ml"++  | 16 ->+# 88 "src/dot_lexer.mll"+      ( EOF )+# 285 "src/dot_lexer.ml"++  | 17 ->+let+# 89 "src/dot_lexer.mll"+         c+# 291 "src/dot_lexer.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 90 "src/dot_lexer.mll"+      ( failwith ("Dot_lexer: invalid character " ^ String.make 1 c) )+# 295 "src/dot_lexer.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_token_rec lexbuf __ocaml_lex_state++and string lexbuf =+    __ocaml_lex_string_rec lexbuf 27+and __ocaml_lex_string_rec lexbuf __ocaml_lex_state =+  match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 94 "src/dot_lexer.mll"+      ( Buffer.contents string_buf )+# 306 "src/dot_lexer.ml"++  | 1 ->+# 96 "src/dot_lexer.mll"+      ( Buffer.add_char string_buf '"';+	string lexbuf )+# 312 "src/dot_lexer.ml"++  | 2 ->+let+# 98 "src/dot_lexer.mll"+         c+# 318 "src/dot_lexer.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 99 "src/dot_lexer.mll"+      ( Buffer.add_char string_buf c;+	string lexbuf )+# 323 "src/dot_lexer.ml"++  | 3 ->+# 102 "src/dot_lexer.mll"+      ( failwith ("Dot_lexer: unterminated string literal") )+# 328 "src/dot_lexer.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_string_rec lexbuf __ocaml_lex_state++and html lexbuf =+    __ocaml_lex_html_rec lexbuf 33+and __ocaml_lex_html_rec lexbuf __ocaml_lex_state =+  match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 106 "src/dot_lexer.mll"+      ( () )+# 339 "src/dot_lexer.ml"++  | 1 ->+# 108 "src/dot_lexer.mll"+      ( Buffer.add_char string_buf '<'; html lexbuf;+	Buffer.add_char string_buf '>'; html lexbuf )+# 345 "src/dot_lexer.ml"++  | 2 ->+let+# 110 "src/dot_lexer.mll"+         c+# 351 "src/dot_lexer.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 111 "src/dot_lexer.mll"+      ( Buffer.add_char string_buf c;+	html lexbuf )+# 356 "src/dot_lexer.ml"++  | 3 ->+# 114 "src/dot_lexer.mll"+      ( failwith ("Dot_lexer: unterminated html literal") )+# 361 "src/dot_lexer.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_html_rec lexbuf __ocaml_lex_state++and comment lexbuf =+    __ocaml_lex_comment_rec lexbuf 38+and __ocaml_lex_comment_rec lexbuf __ocaml_lex_state =+  match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 118 "src/dot_lexer.mll"+      ( () )+# 372 "src/dot_lexer.ml"++  | 1 ->+# 120 "src/dot_lexer.mll"+      ( comment lexbuf )+# 377 "src/dot_lexer.ml"++  | 2 ->+# 122 "src/dot_lexer.mll"+      ( failwith "Dot_lexer: unterminated comment" )+# 382 "src/dot_lexer.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_comment_rec lexbuf __ocaml_lex_state++;;+
+ external/ocamlgraph/src/dot_lexer.mll view
@@ -0,0 +1,122 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++{+  open Lexing+  open Dot_ast+  open Dot_parser++  let string_buf = Buffer.create 1024++  let keyword =+    let h = Hashtbl.create 17 in+    List.iter +      (fun (s,k) -> Hashtbl.add h s k)+      [+	"strict", STRICT;+	"graph", GRAPH;+	"digraph", DIGRAPH;+	"subgraph", SUBGRAPH;+	"node", NODE;+	"edge", EDGE;+      ];+    fun s -> let s = String.lowercase s in Hashtbl.find h s++}++let alpha = ['a'-'z' 'A'-'Z' '_']+let digit = ['0'-'9']+let ident = alpha (alpha | digit)*+let number = '-'? ('.'['0'-'9']+ | ['0'-'9']+('.'['0'-'9']*)? )++let space = [' ' '\t' '\r' '\n']+++rule token = parse+  | space+      { token lexbuf }+  | ('#' | "//") [^ '\n']* '\n'+      { token lexbuf }+  | "/*"+      { comment lexbuf; token lexbuf }+  | ":" +      { COLON }+  | "," +      { COMMA }+  | ";" +      { SEMICOLON }+  | "=" +      { EQUAL }+  | "{" +      { LBRA }+  | "}" +      { RBRA }+  | "[" +      { LSQ }+  | "]" +      { RSQ }+  | "--" | "->"+      { EDGEOP }+  | ident as s+      { try keyword s with Not_found -> ID (Ident s) }+  | number as s+      { ID (Number s) }+  | "\""+      { Buffer.clear string_buf; +	let s = string lexbuf in+	ID (String s) }+  | "<"+      { Buffer.clear string_buf; +	html lexbuf; +	ID (Html (Buffer.contents string_buf)) }+  | eof+      { EOF }+  | _ as c+      { failwith ("Dot_lexer: invalid character " ^ String.make 1 c) }++and string = parse+  | "\"" +      { Buffer.contents string_buf }+  | "\\" "\""+      { Buffer.add_char string_buf '"';+	string lexbuf }+  | _ as c+      { Buffer.add_char string_buf c;+	string lexbuf }+  | eof+      { failwith ("Dot_lexer: unterminated string literal") }++and html = parse+  | ">"+      { () }+  | "<"+      { Buffer.add_char string_buf '<'; html lexbuf;+	Buffer.add_char string_buf '>'; html lexbuf }+  | _ as c+      { Buffer.add_char string_buf c;+	html lexbuf }+  | eof+      { failwith ("Dot_lexer: unterminated html literal") }++and comment = parse+  | "*/"+      { () }+  | _ +      { comment lexbuf }+  | eof+      { failwith "Dot_lexer: unterminated comment" }
+ external/ocamlgraph/src/dot_parser.ml view
@@ -0,0 +1,551 @@+type token =+  | ID of (Dot_ast.id)+  | COLON+  | COMMA+  | EQUAL+  | SEMICOLON+  | EDGEOP+  | STRICT+  | GRAPH+  | DIGRAPH+  | LBRA+  | RBRA+  | LSQ+  | RSQ+  | NODE+  | EDGE+  | SUBGRAPH+  | EOF++open Parsing;;+# 23 "src/dot_parser.mly"+  open Dot_ast+  open Parsing++  let compass_pt = function+    | Ident "n" -> N+    | Ident "ne" -> Ne+    | Ident "e" -> E+    | Ident "se" -> Se+    | Ident "s" -> S+    | Ident "sw" -> Sw+    | Ident "w" -> W+    | Ident "nw" -> Nw+    | _ -> invalid_arg "compass_pt"++# 37 "src/dot_parser.ml"+let yytransl_const = [|+  258 (* COLON *);+  259 (* COMMA *);+  260 (* EQUAL *);+  261 (* SEMICOLON *);+  262 (* EDGEOP *);+  263 (* STRICT *);+  264 (* GRAPH *);+  265 (* DIGRAPH *);+  266 (* LBRA *);+  267 (* RBRA *);+  268 (* LSQ *);+  269 (* RSQ *);+  270 (* NODE *);+  271 (* EDGE *);+  272 (* SUBGRAPH *);+    0 (* EOF *);+    0|]++let yytransl_block = [|+  257 (* ID *);+    0|]++let yylhs = "\255\255\+\001\000\002\000\002\000\003\000\003\000\005\000\005\000\006\000\+\006\000\008\000\008\000\007\000\007\000\007\000\007\000\007\000\+\009\000\010\000\011\000\011\000\011\000\016\000\018\000\018\000\+\015\000\015\000\013\000\019\000\019\000\020\000\020\000\014\000\+\014\000\017\000\017\000\004\000\004\000\021\000\021\000\022\000\+\022\000\023\000\023\000\012\000\012\000\012\000\012\000\000\000"++let yylen = "\002\000\+\007\000\000\000\001\000\001\000\001\000\000\000\001\000\002\000\+\003\000\000\000\001\000\001\000\001\000\001\000\003\000\001\000\+\002\000\003\000\002\000\002\000\002\000\003\000\000\000\003\000\+\001\000\001\000\002\000\000\000\001\000\002\000\004\000\000\000\+\001\000\003\000\004\000\000\000\001\000\002\000\003\000\001\000\+\003\000\000\000\001\000\002\000\005\000\004\000\003\000\002\000"++let yydefred = "\000\000\+\000\000\000\000\003\000\048\000\000\000\004\000\005\000\000\000\+\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+\000\000\000\000\007\000\000\000\012\000\013\000\014\000\000\000\+\000\000\000\000\000\000\000\000\027\000\029\000\000\000\019\000\+\000\000\020\000\021\000\000\000\000\000\000\000\011\000\000\000\+\017\000\033\000\000\000\000\000\000\000\015\000\000\000\000\000\+\000\000\047\000\000\000\000\000\001\000\009\000\000\000\026\000\+\025\000\000\000\018\000\000\000\000\000\000\000\043\000\000\000\+\000\000\046\000\000\000\022\000\031\000\041\000\035\000\039\000\+\045\000\000\000\024\000"++let yydgoto = "\002\000\+\004\000\005\000\008\000\010\000\018\000\019\000\020\000\040\000\+\021\000\022\000\023\000\024\000\025\000\041\000\026\000\044\000\+\042\000\068\000\029\000\030\000\048\000\049\000\064\000"++let yysindex = "\009\000\+\024\255\000\000\000\000\000\000\000\255\000\000\000\000\031\255\+\000\000\029\255\131\255\011\255\033\255\131\255\033\255\033\255\+\051\255\040\255\000\000\048\255\000\000\000\000\000\000\000\000\+\033\255\050\255\057\255\067\255\000\000\000\000\069\255\000\000\+\062\255\000\000\000\000\070\255\131\255\091\000\000\000\131\255\+\000\000\000\000\018\255\033\255\090\255\000\000\099\255\081\255\+\101\255\000\000\131\255\095\255\000\000\000\000\107\255\000\000\+\000\000\110\255\000\000\114\255\117\255\033\255\000\000\069\255\+\111\255\000\000\018\255\000\000\000\000\000\000\000\000\000\000\+\000\000\110\255\000\000"++let yyrindex = "\000\000\+\074\255\000\000\000\000\000\000\000\000\000\000\000\000\116\255\+\000\000\000\000\118\255\006\255\000\000\118\255\000\000\000\000\+\000\000\000\000\000\000\120\255\000\000\000\000\000\000\049\255\+\061\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+\000\000\000\000\000\000\073\255\118\255\000\000\000\000\122\255\+\000\000\000\000\000\000\097\255\032\255\000\000\023\255\000\000\+\022\255\000\000\118\255\000\000\000\000\000\000\006\255\000\000\+\000\000\085\255\000\000\000\000\000\000\109\255\000\000\124\255\+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+\000\000\085\255\000\000"++let yygindex = "\000\000\+\000\000\000\000\000\000\000\000\246\255\087\000\000\000\000\000\+\000\000\000\000\000\000\214\255\218\255\094\000\219\255\000\000\+\243\255\066\000\000\000\000\000\078\000\000\000\000\000"++let yytablesize = 147+let yytable = "\032\000\+\056\000\034\000\035\000\033\000\057\000\058\000\028\000\006\000\+\007\000\001\000\028\000\028\000\027\000\028\000\028\000\028\000\+\028\000\028\000\055\000\028\000\028\000\028\000\042\000\040\000\+\056\000\040\000\052\000\014\000\057\000\074\000\003\000\009\000\+\030\000\017\000\042\000\040\000\030\000\030\000\011\000\030\000\+\065\000\030\000\030\000\030\000\031\000\030\000\030\000\030\000\+\071\000\016\000\038\000\036\000\039\000\016\000\026\000\043\000\+\016\000\045\000\016\000\016\000\037\000\032\000\016\000\016\000\+\016\000\032\000\025\000\046\000\032\000\047\000\032\000\032\000\+\050\000\044\000\032\000\032\000\032\000\044\000\044\000\051\000\+\044\000\002\000\002\000\044\000\044\000\023\000\044\000\044\000\+\044\000\023\000\053\000\060\000\023\000\062\000\023\000\023\000\+\023\000\032\000\023\000\023\000\023\000\032\000\061\000\063\000\+\032\000\066\000\032\000\032\000\027\000\034\000\032\000\032\000\+\032\000\034\000\069\000\067\000\034\000\070\000\034\000\034\000\+\010\000\073\000\034\000\034\000\034\000\036\000\054\000\010\000\+\006\000\010\000\010\000\012\000\008\000\010\000\010\000\010\000\+\038\000\059\000\013\000\075\000\014\000\072\000\000\000\000\000\+\015\000\016\000\017\000"++let yycheck = "\013\000\+\043\000\015\000\016\000\014\000\043\000\043\000\001\001\008\001\+\009\001\001\000\005\001\006\001\002\001\008\001\004\001\010\001\+\011\001\012\001\001\001\014\001\015\001\016\001\001\001\001\001\+\067\000\003\001\037\000\010\001\067\000\067\000\007\001\001\001\+\001\001\016\001\013\001\013\001\005\001\006\001\010\001\008\001\+\051\000\010\001\011\001\012\001\012\001\014\001\015\001\016\001\+\062\000\001\001\011\001\001\001\005\001\005\001\006\001\006\001\+\008\001\001\001\010\001\011\001\010\001\001\001\014\001\015\001\+\016\001\005\001\006\001\001\001\008\001\001\001\010\001\011\001\+\011\001\001\001\014\001\015\001\016\001\005\001\006\001\010\001\+\008\001\008\001\009\001\011\001\012\001\001\001\014\001\015\001\+\016\001\005\001\000\000\002\001\008\001\013\001\010\001\011\001\+\012\001\001\001\014\001\015\001\016\001\005\001\004\001\003\001\+\008\001\011\001\010\001\011\001\002\001\001\001\014\001\015\001\+\016\001\005\001\001\001\006\001\008\001\001\001\010\001\011\001\+\001\001\011\001\014\001\015\001\016\001\010\001\040\000\008\001\+\011\001\010\001\011\001\001\001\011\001\014\001\015\001\016\001\+\013\001\044\000\008\001\074\000\010\001\064\000\255\255\255\255\+\014\001\015\001\016\001"++let yynames_const = "\+  COLON\000\+  COMMA\000\+  EQUAL\000\+  SEMICOLON\000\+  EDGEOP\000\+  STRICT\000\+  GRAPH\000\+  DIGRAPH\000\+  LBRA\000\+  RBRA\000\+  LSQ\000\+  RSQ\000\+  NODE\000\+  EDGE\000\+  SUBGRAPH\000\+  EOF\000\+  "++let yynames_block = "\+  ID\000\+  "++let yyact = [|+  (fun _ -> failwith "parser")+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 6 : 'strict_opt) in+    let _2 = (Parsing.peek_val __caml_parser_env 5 : 'graph_or_digraph) in+    let _3 = (Parsing.peek_val __caml_parser_env 4 : 'id_opt) in+    let _5 = (Parsing.peek_val __caml_parser_env 2 : 'stmt_list) in+    Obj.repr(+# 49 "src/dot_parser.mly"+    ( { strict = _1; digraph = _2; id = _3; stmts = _5 } )+# 199 "src/dot_parser.ml"+               : Dot_ast.file))+; (fun __caml_parser_env ->+    Obj.repr(+# 53 "src/dot_parser.mly"+                ( false )+# 205 "src/dot_parser.ml"+               : 'strict_opt))+; (fun __caml_parser_env ->+    Obj.repr(+# 54 "src/dot_parser.mly"+                ( true )+# 211 "src/dot_parser.ml"+               : 'strict_opt))+; (fun __caml_parser_env ->+    Obj.repr(+# 58 "src/dot_parser.mly"+          ( false )+# 217 "src/dot_parser.ml"+               : 'graph_or_digraph))+; (fun __caml_parser_env ->+    Obj.repr(+# 59 "src/dot_parser.mly"+          ( true )+# 223 "src/dot_parser.ml"+               : 'graph_or_digraph))+; (fun __caml_parser_env ->+    Obj.repr(+# 63 "src/dot_parser.mly"+                ( [] )+# 229 "src/dot_parser.ml"+               : 'stmt_list))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'list1_stmt) in+    Obj.repr(+# 64 "src/dot_parser.mly"+                ( _1 )+# 236 "src/dot_parser.ml"+               : 'stmt_list))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 1 : 'stmt) in+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'semicolon_opt) in+    Obj.repr(+# 68 "src/dot_parser.mly"+                     ( [_1] )+# 244 "src/dot_parser.ml"+               : 'list1_stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 2 : 'stmt) in+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'semicolon_opt) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : 'list1_stmt) in+    Obj.repr(+# 69 "src/dot_parser.mly"+                                ( _1 :: _3 )+# 253 "src/dot_parser.ml"+               : 'list1_stmt))+; (fun __caml_parser_env ->+    Obj.repr(+# 73 "src/dot_parser.mly"+                ( () )+# 259 "src/dot_parser.ml"+               : 'semicolon_opt))+; (fun __caml_parser_env ->+    Obj.repr(+# 74 "src/dot_parser.mly"+                ( () )+# 265 "src/dot_parser.ml"+               : 'semicolon_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'node_stmt) in+    Obj.repr(+# 78 "src/dot_parser.mly"+            ( _1 )+# 272 "src/dot_parser.ml"+               : 'stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'edge_stmt) in+    Obj.repr(+# 79 "src/dot_parser.mly"+            ( _1 )+# 279 "src/dot_parser.ml"+               : 'stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'attr_stmt) in+    Obj.repr(+# 80 "src/dot_parser.mly"+            ( _1 )+# 286 "src/dot_parser.ml"+               : 'stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 2 : Dot_ast.id) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 81 "src/dot_parser.mly"+              ( Equal (_1, _3) )+# 294 "src/dot_parser.ml"+               : 'stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'subgraph) in+    Obj.repr(+# 82 "src/dot_parser.mly"+            ( Subgraph _1 )+# 301 "src/dot_parser.ml"+               : 'stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 1 : 'node_id) in+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list_opt) in+    Obj.repr(+# 86 "src/dot_parser.mly"+                        ( Node_stmt (_1, _2) )+# 309 "src/dot_parser.ml"+               : 'node_stmt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 2 : 'node) in+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'edge_rhs) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list_opt) in+    Obj.repr(+# 90 "src/dot_parser.mly"+                              ( Edge_stmt (_1, _2, _3) )+# 318 "src/dot_parser.ml"+               : 'edge_stmt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list) in+    Obj.repr(+# 94 "src/dot_parser.mly"+                  ( Attr_graph _2 )+# 325 "src/dot_parser.ml"+               : 'attr_stmt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list) in+    Obj.repr(+# 95 "src/dot_parser.mly"+                  ( Attr_node _2 )+# 332 "src/dot_parser.ml"+               : 'attr_stmt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list) in+    Obj.repr(+# 96 "src/dot_parser.mly"+                  ( Attr_edge _2 )+# 339 "src/dot_parser.ml"+               : 'attr_stmt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'node) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : 'edge_rhs_opt) in+    Obj.repr(+# 100 "src/dot_parser.mly"+                           ( _2 :: _3 )+# 347 "src/dot_parser.ml"+               : 'edge_rhs))+; (fun __caml_parser_env ->+    Obj.repr(+# 104 "src/dot_parser.mly"+                ( [] )+# 353 "src/dot_parser.ml"+               : 'edge_rhs_opt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'node) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : 'edge_rhs_opt) in+    Obj.repr(+# 105 "src/dot_parser.mly"+                           ( _2 :: _3 )+# 361 "src/dot_parser.ml"+               : 'edge_rhs_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'node_id) in+    Obj.repr(+# 109 "src/dot_parser.mly"+           ( NodeId _1 )+# 368 "src/dot_parser.ml"+               : 'node))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'subgraph) in+    Obj.repr(+# 110 "src/dot_parser.mly"+           ( NodeSub _1 )+# 375 "src/dot_parser.ml"+               : 'node))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 1 : Dot_ast.id) in+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'port_opt) in+    Obj.repr(+# 114 "src/dot_parser.mly"+              ( _1, _2 )+# 383 "src/dot_parser.ml"+               : 'node_id))+; (fun __caml_parser_env ->+    Obj.repr(+# 118 "src/dot_parser.mly"+                ( None )+# 389 "src/dot_parser.ml"+               : 'port_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'port) in+    Obj.repr(+# 119 "src/dot_parser.mly"+                ( Some _1 )+# 396 "src/dot_parser.ml"+               : 'port_opt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 123 "src/dot_parser.mly"+           ( try PortC (compass_pt _2)+             with Invalid_argument _ -> PortId (_2, None) )+# 404 "src/dot_parser.ml"+               : 'port))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 2 : Dot_ast.id) in+    let _4 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 126 "src/dot_parser.mly"+      ( let cp = +  	  try compass_pt _4 with Invalid_argument _ -> raise Parse_error +	in+	PortId (_2, Some cp) )+# 415 "src/dot_parser.ml"+               : 'port))+; (fun __caml_parser_env ->+    Obj.repr(+# 133 "src/dot_parser.mly"+                ( [] )+# 421 "src/dot_parser.ml"+               : 'attr_list_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list) in+    Obj.repr(+# 134 "src/dot_parser.mly"+               ( _1 )+# 428 "src/dot_parser.ml"+               : 'attr_list_opt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'a_list) in+    Obj.repr(+# 138 "src/dot_parser.mly"+                 ( [_2] )+# 435 "src/dot_parser.ml"+               : 'attr_list))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 2 : 'a_list) in+    let _4 = (Parsing.peek_val __caml_parser_env 0 : 'attr_list) in+    Obj.repr(+# 139 "src/dot_parser.mly"+                           ( _2 :: _4 )+# 443 "src/dot_parser.ml"+               : 'attr_list))+; (fun __caml_parser_env ->+    Obj.repr(+# 143 "src/dot_parser.mly"+                ( None )+# 449 "src/dot_parser.ml"+               : 'id_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 144 "src/dot_parser.mly"+                ( Some _1 )+# 456 "src/dot_parser.ml"+               : 'id_opt))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 1 : 'equality) in+    let _2 = (Parsing.peek_val __caml_parser_env 0 : 'comma_opt) in+    Obj.repr(+# 148 "src/dot_parser.mly"+                     ( [_1] )+# 464 "src/dot_parser.ml"+               : 'a_list))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 2 : 'equality) in+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'comma_opt) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : 'a_list) in+    Obj.repr(+# 149 "src/dot_parser.mly"+                            ( _1 :: _3 )+# 473 "src/dot_parser.ml"+               : 'a_list))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 153 "src/dot_parser.mly"+     ( _1, None )+# 480 "src/dot_parser.ml"+               : 'equality))+; (fun __caml_parser_env ->+    let _1 = (Parsing.peek_val __caml_parser_env 2 : Dot_ast.id) in+    let _3 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 154 "src/dot_parser.mly"+              ( _1, Some _3 )+# 488 "src/dot_parser.ml"+               : 'equality))+; (fun __caml_parser_env ->+    Obj.repr(+# 158 "src/dot_parser.mly"+                ( () )+# 494 "src/dot_parser.ml"+               : 'comma_opt))+; (fun __caml_parser_env ->+    Obj.repr(+# 159 "src/dot_parser.mly"+                ( () )+# 500 "src/dot_parser.ml"+               : 'comma_opt))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 0 : Dot_ast.id) in+    Obj.repr(+# 164 "src/dot_parser.mly"+              ( SubgraphId _2 )+# 507 "src/dot_parser.ml"+               : 'subgraph))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 3 : Dot_ast.id) in+    let _4 = (Parsing.peek_val __caml_parser_env 1 : 'stmt_list) in+    Obj.repr(+# 165 "src/dot_parser.mly"+                                  ( SubgraphDef (Some _2, _4) )+# 515 "src/dot_parser.ml"+               : 'subgraph))+; (fun __caml_parser_env ->+    let _3 = (Parsing.peek_val __caml_parser_env 1 : 'stmt_list) in+    Obj.repr(+# 166 "src/dot_parser.mly"+                               ( SubgraphDef (None, _3) )+# 522 "src/dot_parser.ml"+               : 'subgraph))+; (fun __caml_parser_env ->+    let _2 = (Parsing.peek_val __caml_parser_env 1 : 'stmt_list) in+    Obj.repr(+# 167 "src/dot_parser.mly"+                      ( SubgraphDef (None, _2) )+# 529 "src/dot_parser.ml"+               : 'subgraph))+(* Entry file *)+; (fun __caml_parser_env -> raise (Parsing.YYexit (Parsing.peek_val __caml_parser_env 0)))+|]+let yytables =+  { Parsing.actions=yyact;+    Parsing.transl_const=yytransl_const;+    Parsing.transl_block=yytransl_block;+    Parsing.lhs=yylhs;+    Parsing.len=yylen;+    Parsing.defred=yydefred;+    Parsing.dgoto=yydgoto;+    Parsing.sindex=yysindex;+    Parsing.rindex=yyrindex;+    Parsing.gindex=yygindex;+    Parsing.tablesize=yytablesize;+    Parsing.table=yytable;+    Parsing.check=yycheck;+    Parsing.error_function=parse_error;+    Parsing.names_const=yynames_const;+    Parsing.names_block=yynames_block }+let file (lexfun : Lexing.lexbuf -> token) (lexbuf : Lexing.lexbuf) =+   (Parsing.yyparse yytables 1 lexfun lexbuf : Dot_ast.file)
+ external/ocamlgraph/src/dot_parser.mli view
@@ -0,0 +1,21 @@+type token =+  | ID of (Dot_ast.id)+  | COLON+  | COMMA+  | EQUAL+  | SEMICOLON+  | EDGEOP+  | STRICT+  | GRAPH+  | DIGRAPH+  | LBRA+  | RBRA+  | LSQ+  | RSQ+  | NODE+  | EDGE+  | SUBGRAPH+  | EOF++val file :+  (Lexing.lexbuf  -> token) -> Lexing.lexbuf -> Dot_ast.file
+ external/ocamlgraph/src/dot_parser.mly view
@@ -0,0 +1,168 @@+/**************************************************************************/+/*                                                                        */+/*  Ocamlgraph: a generic graph library for OCaml                         */+/*  Copyright (C) 2004-2007                                               */+/*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        */+/*                                                                        */+/*  This software is free software; you can redistribute it and/or        */+/*  modify it under the terms of the GNU Library General Public           */+/*  License version 2, with the special exception on linking              */+/*  described in file LICENSE.                                            */+/*                                                                        */+/*  This software is distributed in the hope that it will be useful,      */+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  */+/*                                                                        */+/**************************************************************************/++/* $Id:$ */++/* DOT parser, following http://www.graphviz.org/doc/info/lang.html */++%{+  open Dot_ast+  open Parsing++  let compass_pt = function+    | Ident "n" -> N+    | Ident "ne" -> Ne+    | Ident "e" -> E+    | Ident "se" -> Se+    | Ident "s" -> S+    | Ident "sw" -> Sw+    | Ident "w" -> W+    | Ident "nw" -> Nw+    | _ -> invalid_arg "compass_pt"++%} ++%token <Dot_ast.id> ID+%token COLON COMMA EQUAL SEMICOLON EDGEOP+%token STRICT GRAPH DIGRAPH LBRA RBRA LSQ RSQ NODE EDGE SUBGRAPH EOF++%type <Dot_ast.file> file+%start file+%%++file: +| strict_opt graph_or_digraph id_opt LBRA stmt_list RBRA EOF+    { { strict = $1; digraph = $2; id = $3; stmts = $5 } }+;++strict_opt:+| /* epsilon */ { false }+| STRICT        { true }+;++graph_or_digraph:+| GRAPH   { false }+| DIGRAPH { true }+;++stmt_list:+| /* epsilon */ { [] }+| list1_stmt    { $1 }+;++list1_stmt:+| stmt semicolon_opt { [$1] }+| stmt semicolon_opt list1_stmt { $1 :: $3 }+;++semicolon_opt:+| /* epsilon */ { () }+| SEMICOLON     { () }+;++stmt:+| node_stmt { $1 }+| edge_stmt { $1 }+| attr_stmt { $1 }+| ID EQUAL ID { Equal ($1, $3) }+| subgraph  { Subgraph $1 }+;++node_stmt:+| node_id attr_list_opt { Node_stmt ($1, $2) }+;++edge_stmt:+| node edge_rhs attr_list_opt { Edge_stmt ($1, $2, $3) }+;++attr_stmt:+| GRAPH attr_list { Attr_graph $2 }+| NODE  attr_list { Attr_node $2 }+| EDGE  attr_list { Attr_edge $2 }+;++edge_rhs:+| EDGEOP node edge_rhs_opt { $2 :: $3 }+;++edge_rhs_opt:+| /* epsilon */ { [] }+| EDGEOP node edge_rhs_opt { $2 :: $3 }+;++node:+| node_id  { NodeId $1 }+| subgraph { NodeSub $1 }+; ++node_id:+| ID port_opt { $1, $2 }+;++port_opt:+| /* epsilon */ { None }+| port          { Some $1 }+;++port:+| COLON ID { try PortC (compass_pt $2)+             with Invalid_argument _ -> PortId ($2, None) }+| COLON ID COLON ID +      { let cp = +  	  try compass_pt $4 with Invalid_argument _ -> raise Parse_error +	in+	PortId ($2, Some cp) }+;++attr_list_opt:+| /* epsilon */ { [] }+| attr_list    { $1 }+;++attr_list:+| LSQ a_list RSQ { [$2] }+| LSQ a_list RSQ attr_list { $2 :: $4 }+;++id_opt:+| /* epsilon */ { None }+| ID            { Some $1 }+;++a_list:+| equality comma_opt { [$1] }+| equality comma_opt a_list { $1 :: $3 }+;++equality:+| ID { $1, None }+| ID EQUAL ID { $1, Some $3 }+;++comma_opt:+| /* epsilon */ { () }+| COMMA         { () }+;++/* one shift/reduce conflict here, which is ok */+subgraph:+| SUBGRAPH ID { SubgraphId $2 }+| SUBGRAPH ID LBRA stmt_list RBRA { SubgraphDef (Some $2, $4) }+| SUBGRAPH LBRA stmt_list RBRA { SubgraphDef (None, $3) }+| LBRA stmt_list RBRA { SubgraphDef (None, $2) }+;
+ external/ocamlgraph/src/flow.ml view
@@ -0,0 +1,329 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++module type FLOW = sig+  type label+  type t+  val max_capacity : label -> t+  val min_capacity : label -> t+  val flow : label -> t+  val add : t -> t -> t+  val sub : t -> t -> t+  val zero : t+  val compare : t -> t -> int+end++module type G_GOLDBERG = sig+  type t+  module V : Sig.COMPARABLE+  module E : Sig.EDGE with type vertex = V.t+  val nb_vertex : t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_edges_e : (E.t -> unit) -> t -> unit+  val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++module Goldberg(G: G_GOLDBERG)(F: FLOW with type label = G.E.label) = +struct+  +  module V = Hashtbl.Make(G.V)+  module E = Hashtbl.Make(Util.HTProduct(G.V)(G.V)) +  module Se = Set.Make(G.E)+  module Sv = Set.Make(G.V)++  let excedents = V.create 997+  let hauteur = V.create 997+  let flot = E.create 997++  let fold_booleen f = List.fold_left (fun r x->(f x) or r) false++  let capacite_restante g e = +    F.sub (F.max_capacity (G.E.label e)) (E.find flot (G.E.src e, G.E.dst e))++  let reste_excedent x = F.compare (V.find excedents x) F.zero > 0 +      +  let flux_et_reflux g x = +    let s = +      G.fold_succ_e +	(fun e s->+	   if F.compare +	     (capacite_restante g e) (F.min_capacity (G.E.label e))+	     > 0 +	   then e::s else s) +	g x [] +    in +    G.fold_pred_e +      (fun e s -> +	 if F.compare +	   (E.find flot (G.E.src e, G.E.dst e)) (F.min_capacity (G.E.label e))+	   > 0 +	 then (G.E.create (G.E.dst e) (G.E.label e) (G.E.src e))::s else s)+      g x s++  let pousser g e l =+    let x, y = G.E.src e, G.E.dst e in+    let ex = V.find excedents x in+    let cxy = capacite_restante g e in+    if F.compare ex F.zero > 0 &&+      F.compare cxy (F.min_capacity (G.E.label e)) > 0 &&+      V.find hauteur x = (V.find hauteur y + 1)+    then+      let d = if F.compare ex cxy < 0 then ex else cxy in+      let fxy = E.find flot (x,y) in+      let ex = V.find excedents x in+      let ey = V.find excedents y in+      E.replace flot (x,y) (F.add fxy d);+      E.replace flot (y,x) (F.sub F.zero (F.add fxy d));+      V.replace excedents x (F.sub ex d);+      V.replace excedents y (F.add ey d);+      if reste_excedent x then l:=Sv.add x !l;+      if reste_excedent y then l:=Sv.add y !l;+      true+    else +      (if F.compare ex F.zero > 0 then l:=Sv.add x !l; +       false)++  let elever g p x = +    let u = flux_et_reflux g x in+    reste_excedent x+    && not (G.V.equal x p) +    && +    List.for_all +      (fun e -> (V.find hauteur (G.E.src e)) <= (V.find hauteur (G.E.dst e))) u+    && +    (let min = +       List.fold_left (fun m e -> min (V.find hauteur (G.E.dst e)) m) max_int u+     in+     V.replace hauteur x (1+min); +     true)++  let init_preflot g s p = +    G.iter_vertex (fun x -> V.add excedents x F.zero; V.add hauteur x 0) g;+    G.iter_edges_e +      (fun e -> +	 let x,y = G.E.src e, G.E.dst e in +	 E.add flot (x,y) (F.flow (G.E.label e)); +	 E.add flot (y,x) (F.sub F.zero (F.flow (G.E.label e))))+      g;+    V.add hauteur s (G.nb_vertex g);+    G.fold_succ_e +      (fun e l -> +	 let y = G.E.dst e in+	 let c = F.max_capacity (G.E.label e) in +	 E.add flot (s,y) c;+	 E.add flot (y,s) (F.sub F.zero c);+	 V.add excedents y c;+	 y::l)+      g s []+      +  let maxflow g s p = +    let push_and_pull l x = +      G.fold_succ_e (fun e r->pousser g e l or r) g x false+      or G.fold_pred_e (fun e r->pousser g e l or r) g x false+    in+    let todo = ref (init_preflot g s p) in+    while +      (fold_booleen (elever g p) !todo) or +      (let l = ref Sv.empty in +       let r = fold_booleen (push_and_pull l) !todo in+       todo:=Sv.elements !l; r)+    do () done;+    let flot_max = +      G.fold_pred_e (fun e f -> F.add (E.find flot (G.E.src e,p)) f) g p F.zero+    in+    let flot_init = +      G.fold_pred_e (fun e f -> F.add (F.flow (G.E.label e)) f) g p F.zero+    in+    let f e = +      let x,y = G.E.src e, G.E.dst e in +      try E.find flot (x,y) +      with Not_found -> F.flow (G.E.label e)+    in+    f, F.sub flot_max flot_init+end++(*****************************************************************************)++module type G_FORD_FULKERSON = sig+  type t+  module V : Sig.HASHABLE+  module E : sig+    type t+    type label+    val src : t -> V.t+    val dst : t -> V.t+    val label : t -> label+  end+  val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit+  val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit+end++module Ford_Fulkerson+  (G: G_FORD_FULKERSON)+  (F: FLOW with type label = G.E.label) =+struct++  (* redefinition of F *)+  module F = struct+    include F++    type u =+      | Flow of F.t+      | Infinity++    let min x y = match x, y with+      | Flow _, Infinity -> x+      | Flow fx, Flow fy when F.compare fx fy < 0 -> x+      | (Infinity, _) | (Flow _, Flow _) -> y+  end++  module Mark = struct+    module H = Hashtbl.Make(G.V)+    type mark = Plus | Minus++    let marked = H.create 997+    let unvisited = Queue.create ()++    let clear () = H.clear marked++    let mem = H.mem marked++    let set s e tag = +      assert (not (mem s));+      H.add marked s (e, tag);+      Queue.add s unvisited++    let get s : G.E.t * mark =+      let e, tag = H.find marked s in+      (match e with None -> assert false | Some e -> e), tag++    exception Empty = Queue.Empty+    let next () = Queue.pop unvisited+  end++  module Result = struct+    module H = +      Hashtbl.Make+	(struct+	   open G+	   type t = E.t+	   module U = Util.HTProduct(V)(V)+	   let equal e1 e2 = U.equal (E.src e1, E.dst e1) (E.src e2, E.dst e2)+	   let hash e = U.hash (E.src e, E.dst e)+	 end)++    let create () = H.create 997++    let find = H.find++    let flow r e = +      try+	find r e+      with Not_found ->+	let f = F.flow (G.E.label e) in+	H.add r e f;+	f++    let change op r e f =+      try+	H.replace r e (op (find r e) f);+      with Not_found ->+	assert false++    let grow = change F.add+    let reduce = change F.sub+  end++  let is_full r e =+    F.compare (F.max_capacity (G.E.label e)) (Result.flow r e) = 0++  let is_empty r e =+    F.compare (F.min_capacity (G.E.label e)) (Result.flow r e) = 0++  let set_flow r s t a =+    let rec loop t =+      if not (G.V.equal s t) then+	let e, tag = Mark.get t in+	match tag with +	  | Mark.Plus -> Result.grow r e a; loop (G.E.src e)+	  | Mark.Minus -> Result.reduce r e a; loop (G.E.dst e)+    in+    loop t++  let grow_flow r s t a =+    let rec loop u b =+      if G.V.equal s u then begin+	match b with+	  | F.Infinity -> (* source = destination *)+	      assert (G.V.equal s t); +	      a+	  | F.Flow f ->+	      set_flow r s t f;+	      F.add a f+      end else+	let e, tag = Mark.get u in+	let l = G.E.label e in+	match tag with+	  | Mark.Plus -> +	      loop +	        (G.E.src e) +	        (F.min b (F.Flow (F.sub (F.max_capacity l) (Result.flow r e))))+	  | Mark.Minus -> +	      loop +	        (G.E.dst e) +	        (F.min b (F.Flow (F.sub (Result.flow r e) (F.min_capacity l))))+    in+    loop t F.Infinity++  let maxflow g s t =+    let r = Result.create () in+    let succ s = +      G.iter_succ_e+	(fun e ->+	   assert (G.V.equal s (G.E.src e));+	   let t = G.E.dst e in+	   if not (Mark.mem t || is_full r e) then +	     Mark.set t (Some e) Mark.Plus)+	g s+    in+    let pred s = +      G.iter_pred_e+	(fun e ->+	   assert (G.V.equal s (G.E.dst e));+	   let t = G.E.src e in+	   if not (Mark.mem t || is_empty r e) then+	     Mark.set t (Some e) Mark.Minus)+	g s+    in+    let internal_loop a =+      try+	while true do let s = Mark.next () in succ s; pred s done;+	assert false+      with Mark.Empty ->+	if Mark.mem t then grow_flow r s t a else a+    in+    let rec external_loop a =+      Mark.clear ();+      Mark.set s None Mark.Plus;+      let a' = internal_loop a in+      if a = a' then a else external_loop a'+    in+    let a = external_loop F.zero in+    (fun e -> try Result.find r e with Not_found -> F.flow (G.E.label e)), a++end
+ external/ocamlgraph/src/flow.mli view
@@ -0,0 +1,107 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(** Algorithms on flows ++    The following flow algorithms only apply to networks, that are+    directed graphs together with a source (a 0 in-degree vertex) and a +    terminal (a 0 out-degree vertex). *)++(** {1 Maximum flow algorithms} *)++(** Signature for edges' flow *)+module type FLOW = sig+  type label+  type t++  (** maximum and minimum capacities for a label on an edge *)++  val max_capacity : label -> t+  val min_capacity : label -> t++  (** current flow for a label on an edge *)++  val flow : label -> t++  (** [+] and [-] on flows. *)++  val add : t -> t -> t+  val sub : t -> t -> t++  (** neutral element for [add] and [sub]. *)++  val zero : t++  (** a total ordering over flows *)++  val compare : t -> t -> int++end++(**  {2 Goldberg maximal flow algorithm} *)++(** Minimal digraph signature for Goldberg *)+module type G_GOLDBERG = sig+  type t+  module V : Sig.COMPARABLE+  module E : Sig.EDGE with type vertex = V.t+  val nb_vertex : t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_edges_e : (E.t -> unit) -> t -> unit+  val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++module Goldberg(G: G_GOLDBERG)(F: FLOW with type label = G.E.label) : +sig+      +  val maxflow : G.t -> G.V.t -> G.V.t -> (G.E.t -> F.t) * F.t+    (** [maxflow g v1 v2] searchs the maximal flow from source [v1] to+      terminal [v2] using the Goldberg algorithm. It returns the new+      flows on each edges and the growth of the flow. *)++end++(**  {2 Ford-Fulkerson maximal flow algorithm} *)++(** Minimal digraph signature for Ford-Fulkerson *)+module type G_FORD_FULKERSON = sig+  type t+  module V : Sig.HASHABLE+  module E : sig+    type t+    type label+    val src : t -> V.t+    val dst : t -> V.t+    val label : t -> label+  end+  val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit+  val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit+end++module Ford_Fulkerson+  (G: G_FORD_FULKERSON)+  (F: FLOW with type label = G.E.label) :+sig++  val maxflow : G.t -> G.V.t -> G.V.t -> (G.E.t -> F.t) * F.t+      (** [maxflow g v1 v2] searchs the maximal flow from source [v1]+	to terminal [v2] using the Ford-Fulkerson algorithm. It+	returns the new flows on each edges and the growth of the+	flow. *)++end
+ external/ocamlgraph/src/gcoloring.ml view
@@ -0,0 +1,123 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++exception NoColoring++module type GM = sig+  type t+  val nb_vertex : t -> int+  module V : Sig.COMPARABLE+  val out_degree : t -> V.t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  module Mark : sig+    val get : V.t -> int+    val set : V.t -> int -> unit+  end+end++(** Graph coloring with marking. +    Only applies to imperative graphs with marks. *)+module Mark(G : GM) = struct++  module Bfs = Traverse.Bfs(G)+  +  let coloring g k =+    (* first step: we eliminate vertices with less than [k] successors *)+    let stack = Stack.create () in+    let nb_to_color = ref (G.nb_vertex g) in+    let count = ref 1 in+    while !count > 0 do +      count := 0;+      let erase v = incr count; G.Mark.set v (k+1); Stack.push v stack in+      G.iter_vertex +	(fun v -> if G.Mark.get v = 0 && G.out_degree g v < k then erase v) +	g;+      (*Format.printf "eliminating %d nodes@." !count;*)+      nb_to_color := !nb_to_color - !count+    done;+    (* second step: we k-color the remaining of the graph *)+    (* [try_color v i] tries to assign color [i] to vertex [v] *)+    let try_color v i =+      G.Mark.set v i;+      G.iter_succ (fun w -> if G.Mark.get w = i then raise NoColoring) g v+    in+    let uncolor v = G.Mark.set v 0 in+    if !nb_to_color > 0 then begin+      let rec iterate iter =+	let v = Bfs.get iter in+	let m = G.Mark.get v in+	if m > 0 then+	  iterate (Bfs.step iter)+	else begin+	  for i = 1 to k do+	    try try_color v i; iterate (Bfs.step iter)+	    with NoColoring -> ()+	  done;+	  uncolor v;+	  raise NoColoring+	end+      in+      try iterate (Bfs.start g) with Exit -> ()+    end;+    (* third step: we color the eliminated vertices, in reverse order *)+    Stack.iter+      (fun v -> +	 try +	   for i = 1 to k do +	     try try_color v i; raise Exit with NoColoring -> ()+	   done;+	   raise NoColoring (* it may still fail on a self edge v->v *)+	 with Exit -> ())+      stack++end++(** Graph coloring for graphs without marks: we use an external hashtbl *)++module type G = sig+  type t+  val nb_vertex : t -> int+  module V : Sig.COMPARABLE+  val out_degree : t -> V.t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++module Make(G: G) = struct++  module H = Hashtbl.Make(G.V)++  let coloring g k =+    let h = H.create 97 in+    let module M = +      Mark(struct+	     include G+	     module Mark = struct+	       let get v = try H.find h v with Not_found -> 0+	       let set v n = H.replace h v n+	     end+	   end )+    in+    M.coloring g k;+    h++end
+ external/ocamlgraph/src/gcoloring.mli view
@@ -0,0 +1,79 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(** k-coloring of undirected graphs.++    A k-coloring of a graph g is a mapping c from nodes to \{1,...,k\} such+    that c(u)<>c(v) for any edge u-v in g. *)++exception NoColoring++(** Graph coloring for graph with integer marks. *)++module type GM = sig+  type t+  val nb_vertex : t -> int+  module V : Sig.COMPARABLE+  val out_degree : t -> V.t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  module Mark : sig+    val get : V.t -> int+    val set : V.t -> int -> unit+  end+end++module Mark(G : GM) : sig++  val coloring : G.t -> int -> unit+    (** [coloring g k] colors the nodes of graph [g] using k colors,+	assigning the marks integer values between 1 and k.+        raises [NoColoring] when there is no possible coloring.++        The graph marks may be partially set before starting; the meaning of+        initial values is as follows:+	- 0: a node to be colored+	- any value between 1 and k: a color already assigned+	- any value greater than k: a node to be ignored *)++end++(** Graph coloring for graphs without marks *)++module type G = sig+  type t+  val nb_vertex : t -> int+  module V : Sig.COMPARABLE+  val out_degree : t -> V.t -> int+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++module Make(G: G) : sig++  module H : Hashtbl.S with type key = G.V.t+    (** hash tables used to store the coloring *)++  val coloring : G.t -> int -> int H.t+    (** [coloring g k] colors the graph [g] with [k] colors and returns the+        coloring as a hash table mapping nodes to their colors. *)++end
+ external/ocamlgraph/src/gmap.ml view
@@ -0,0 +1,68 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: gmap.ml,v 1.1 2004-10-20 09:59:56 signoles Exp $ *)++module Vertex+  (G_Init : sig+     type t+     module V : Sig.HASHABLE+     val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a+   end)+  (G_Dest : sig+     type t+     type vertex+     val empty : unit -> t+     val add_vertex : t -> vertex -> t+   end) =+struct+  +  module H = Hashtbl.Make(G_Init.V)+    +  let vertices = H.create 97++  let convert_vertex f x =+    try +      H.find vertices x+    with Not_found ->+      let x' = f x in+      H.add vertices x x';+      x'++  let map f g =+    H.clear vertices;+    G_Init.fold_vertex+      (fun x g -> G_Dest.add_vertex g (convert_vertex f x)) +      g (G_Dest.empty ())++end++module Edge+  (G_Init : sig+     type t+     module E : Sig.HASHABLE+     val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a+   end)+  (G_Dest : sig+     type t+     type edge+     val empty : unit -> t+     val add_edge_e : t -> edge -> t+   end) =+  Vertex+    (struct include G_Init module V = E let fold_vertex = fold_edges_e end)+    (struct include G_Dest type vertex = edge let add_vertex = add_edge_e end)
+ external/ocamlgraph/src/gmap.mli view
@@ -0,0 +1,60 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: gmap.mli,v 1.1 2004-10-20 09:59:56 signoles Exp $ *)++(** Graph mapping *)++module Vertex+  (G_Init : sig+     type t+     module V : Sig.HASHABLE+     val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a+   end)+  (G_Dest : sig+     type t+     type vertex+     val empty : unit -> t+     val add_vertex : t -> vertex -> t+   end) :+sig++  val map : (G_Init.V.t -> G_Dest.vertex) -> G_Init.t -> G_Dest.t+    (** [map f g] applies [f] to each vertex of [g] and so builds a new graph+      based on [g] *)++end++module Edge+  (G_Init : sig+     type t+     module E : Sig.HASHABLE+     val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a+   end)+  (G_Dest : sig+     type t+     type edge+     val empty : unit -> t+     val add_edge_e : t -> edge -> t+   end) :+sig++  val map : (G_Init.E.t -> G_Dest.edge) -> G_Init.t -> G_Dest.t+    (** [map f g] applies [f] to each edge of [g] and so builds a new graph+      based on [g] *)++end
+ external/ocamlgraph/src/gml.ml view
@@ -0,0 +1,670 @@+# 20 "src/gml.mll"+  ++  open Lexing++  type value = +    | Int of int +    | Float of float+    | String of string+    | List of value_list++  and value_list = (string * value) list+++# 16 "src/gml.ml"+let __ocaml_lex_tables = {+  Lexing.lex_base = +   "\000\000\252\255\253\255\114\000\002\000\007\000\228\000\086\001\+    \252\255\253\255\200\001\009\000\014\000\058\002\002\000\251\255\+    \252\255\001\000\080\000\102\000\194\000\216\000\052\001\071\001\+    \253\255\006\000";+  Lexing.lex_backtrk = +   "\255\255\255\255\255\255\003\000\000\000\001\000\255\255\255\255\+    \255\255\255\255\003\000\000\000\001\000\255\255\255\255\255\255\+    \255\255\004\000\001\000\000\000\004\000\255\255\001\000\255\255\+    \255\255\255\255";+  Lexing.lex_default = +   "\001\000\000\000\000\000\255\255\255\255\255\255\255\255\008\000\+    \000\000\000\000\255\255\255\255\255\255\255\255\015\000\000\000\+    \000\000\025\000\255\255\255\255\255\255\255\255\255\255\255\255\+    \000\000\025\000";+  Lexing.lex_trans = +   "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\004\000\004\000\004\000\004\000\004\000\000\000\004\000\+    \005\000\005\000\011\000\011\000\005\000\000\000\011\000\012\000\+    \012\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\+    \004\000\000\000\004\000\024\000\017\000\000\000\000\000\005\000\+    \024\000\011\000\000\000\000\000\000\000\020\000\012\000\020\000\+    \018\000\000\000\019\000\019\000\019\000\019\000\019\000\019\000\+    \019\000\019\000\019\000\019\000\000\000\000\000\000\000\000\000\+    \000\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\000\000\000\000\016\000\000\000\000\000\+    \000\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\005\000\005\000\000\000\000\000\005\000\+    \018\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\+    \018\000\018\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\005\000\000\000\018\000\021\000\019\000\019\000\+    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\+    \000\000\000\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\005\000\005\000\000\000\+    \018\000\005\000\019\000\019\000\019\000\019\000\019\000\019\000\+    \019\000\019\000\019\000\019\000\000\000\000\000\000\000\000\000\+    \002\000\255\255\255\255\023\000\005\000\023\000\255\255\000\000\+    \022\000\022\000\022\000\022\000\022\000\022\000\022\000\022\000\+    \022\000\022\000\000\000\000\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\011\000\+    \011\000\000\000\000\000\011\000\022\000\022\000\022\000\022\000\+    \022\000\022\000\022\000\022\000\022\000\022\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\011\000\022\000\+    \022\000\022\000\022\000\022\000\022\000\022\000\022\000\022\000\+    \022\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\000\000\000\000\009\000\000\000\000\000\000\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\012\000\012\000\000\000\000\000\012\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\012\000\012\000\000\000\000\000\012\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\255\255\000\000\+    \000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000";+  Lexing.lex_check = +   "\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\000\000\000\000\004\000\004\000\000\000\255\255\004\000\+    \005\000\005\000\011\000\011\000\005\000\255\255\011\000\012\000\+    \012\000\255\255\255\255\012\000\255\255\255\255\255\255\255\255\+    \000\000\255\255\004\000\017\000\014\000\255\255\255\255\005\000\+    \025\000\011\000\255\255\255\255\255\255\014\000\012\000\014\000\+    \014\000\255\255\014\000\014\000\014\000\014\000\014\000\014\000\+    \014\000\014\000\014\000\014\000\255\255\255\255\255\255\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\255\255\255\255\014\000\255\255\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\003\000\003\000\255\255\255\255\003\000\+    \018\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\+    \018\000\018\000\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\003\000\255\255\019\000\018\000\019\000\019\000\+    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\+    \255\255\255\255\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\255\255\255\255\255\255\+    \255\255\255\255\255\255\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\006\000\006\000\255\255\+    \020\000\006\000\020\000\020\000\020\000\020\000\020\000\020\000\+    \020\000\020\000\020\000\020\000\255\255\255\255\255\255\255\255\+    \000\000\017\000\014\000\021\000\006\000\021\000\025\000\255\255\+    \021\000\021\000\021\000\021\000\021\000\021\000\021\000\021\000\+    \021\000\021\000\255\255\255\255\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\255\255\+    \255\255\255\255\255\255\255\255\255\255\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\007\000\+    \007\000\255\255\255\255\007\000\022\000\022\000\022\000\022\000\+    \022\000\022\000\022\000\022\000\022\000\022\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\007\000\023\000\+    \023\000\023\000\023\000\023\000\023\000\023\000\023\000\023\000\+    \023\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\255\255\255\255\007\000\255\255\255\255\255\255\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\010\000\010\000\255\255\255\255\010\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \010\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\255\255\255\255\255\255\255\255\255\255\+    \255\255\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\013\000\013\000\255\255\255\255\013\000\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\007\000\255\255\+    \255\255\255\255\013\000\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\255\255\255\255\255\255\+    \255\255\255\255\255\255\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255";+  Lexing.lex_base_code = +   "\000\000\000\000\000\000\075\000\000\000\000\000\150\000\208\000\+    \000\000\000\000\027\001\000\000\000\000\102\001\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000";+  Lexing.lex_backtrk_code = +   "\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000";+  Lexing.lex_default_code = +   "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000";+  Lexing.lex_trans_code = +   "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\+    \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000";+  Lexing.lex_check_code = +   "\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\255\255\255\255\255\255\255\255\255\255\+    \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\+    \000\000\000\000\000\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\003\000\003\000\+    \003\000\003\000\003\000\003\000\003\000\003\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\255\255\255\255\255\255\255\255\255\255\255\255\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\+    \006\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\255\255\255\255\255\255\255\255\255\255\+    \255\255\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\007\000\007\000\007\000\007\000\007\000\+    \007\000\007\000\007\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\255\255\255\255\+    \255\255\255\255\255\255\255\255\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\010\000\010\000\+    \010\000\010\000\010\000\010\000\010\000\010\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\255\255\255\255\255\255\255\255\255\255\255\255\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\013\000\013\000\013\000\013\000\013\000\013\000\013\000\+    \013\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\+    \255\255\255\255\255\255\255\255\255\255\255\255\255\255";+  Lexing.lex_code = +   "\255\001\255\255\000\001\255";+}++let rec file lexbuf =+  lexbuf.Lexing.lex_mem <- Array.create 2 (-1) ;   __ocaml_lex_file_rec lexbuf 0+and __ocaml_lex_file_rec lexbuf __ocaml_lex_state =+  match Lexing.new_engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 45 "src/gml.mll"+      ( file lexbuf )+# 425 "src/gml.ml"++  | 1 ->+let+# 46 "src/gml.mll"+              key+# 431 "src/gml.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_mem.(0) in+# 47 "src/gml.mll"+      ( let v = value lexbuf in+	(key, v) :: file lexbuf )+# 436 "src/gml.ml"++  | 2 ->+# 50 "src/gml.mll"+      ( [] )+# 441 "src/gml.ml"++  | 3 ->+let+# 51 "src/gml.mll"+         c+# 447 "src/gml.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 52 "src/gml.mll"+      ( failwith ("Gml: invalid character " ^ String.make 1 c) )+# 451 "src/gml.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_file_rec lexbuf __ocaml_lex_state++and value_list lexbuf =+  lexbuf.Lexing.lex_mem <- Array.create 2 (-1) ;   __ocaml_lex_value_list_rec lexbuf 7+and __ocaml_lex_value_list_rec lexbuf __ocaml_lex_state =+  match Lexing.new_engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+# 56 "src/gml.mll"+      ( value_list lexbuf )+# 462 "src/gml.ml"++  | 1 ->+let+# 57 "src/gml.mll"+              key+# 468 "src/gml.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_mem.(0) in+# 58 "src/gml.mll"+      ( let v = value lexbuf in+	(key, v) :: value_list lexbuf )+# 473 "src/gml.ml"++  | 2 ->+# 61 "src/gml.mll"+      ( [] )+# 478 "src/gml.ml"++  | 3 ->+let+# 62 "src/gml.mll"+         c+# 484 "src/gml.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 63 "src/gml.mll"+      ( failwith ("Gml: invalid character " ^ String.make 1 c) )+# 488 "src/gml.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_value_list_rec lexbuf __ocaml_lex_state++and value lexbuf =+    __ocaml_lex_value_rec lexbuf 14+and __ocaml_lex_value_rec lexbuf __ocaml_lex_state =+  match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with+      | 0 ->+let+# 66 "src/gml.mll"+               i+# 500 "src/gml.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_pos in+# 67 "src/gml.mll"+      ( Int (int_of_string i) )+# 504 "src/gml.ml"++  | 1 ->+let+# 68 "src/gml.mll"+            r+# 510 "src/gml.ml"+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_pos in+# 69 "src/gml.mll"+      ( Float (float_of_string r) )+# 514 "src/gml.ml"++  | 2 ->+let+# 70 "src/gml.mll"+                      s+# 520 "src/gml.ml"+= Lexing.sub_lexeme lexbuf (lexbuf.Lexing.lex_start_pos + 1) (lexbuf.Lexing.lex_curr_pos + -1) in+# 71 "src/gml.mll"+      ( String s )+# 524 "src/gml.ml"++  | 3 ->+# 73 "src/gml.mll"+      ( let l = value_list lexbuf in List l )+# 529 "src/gml.ml"++  | 4 ->+let+# 74 "src/gml.mll"+         c+# 535 "src/gml.ml"+= Lexing.sub_lexeme_char lexbuf lexbuf.Lexing.lex_start_pos in+# 75 "src/gml.mll"+      ( failwith ("Gml: invalid character " ^ String.make 1 c) )+# 539 "src/gml.ml"++  | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_value_rec lexbuf __ocaml_lex_state++;;++# 77 "src/gml.mll"+ ++  let parse f =+    let c = open_in f in+    let lb = from_channel c in+    let v = file lb in+    close_in c;+    v++  module Parse+    (B : Builder.S)+    (L : sig val node : value_list -> B.G.V.label+	     val edge : value_list -> B.G.E.label end) = +  struct++    let create_graph l =+      let nodes = Hashtbl.create 97 in+      let g = B.empty () in+      (* 1st pass: create the nodes *)+      let g =+	List.fold_left +	  (fun g v -> match v with+	     | "node", List l ->+		 let n = B.G.V.create (L.node l) in+		 begin +		   try +		     let id = List.assoc "id" l in Hashtbl.add nodes id n+		   with Not_found -> +		     ()+		 end;+		 B.add_vertex g n+	     | _ -> +		 g)+	  g l+      in+      (* 2nd pass: add the edges *)+      List.fold_left+	(fun g v -> match v with+	   | "edge", List l ->+	       begin try+		 let source = List.assoc "source" l in+		 let target = List.assoc "target" l in+		 let nsource = Hashtbl.find nodes source in+		 let ntarget = Hashtbl.find nodes target in+		 let e = B.G.E.create nsource (L.edge l) ntarget in+		 B.add_edge_e g e+	       with Not_found ->+		 g+	       end+	   | _ ->+	       g)+	g l+	+    let parse f =+      match parse f with+	| ["graph", List l] -> create_graph l+	| _ -> invalid_arg "Gml.Parse.parse: not a graph file"+      +  end++  module Print+    (G : sig+       module V : sig+	 type t+	 val hash : t -> int+	 val equal : t -> t -> bool+	 type label+	 val label : t -> label+       end+       module E : sig+	 type t+	 type label+	 val src : t -> V.t+	 val dst : t -> V.t+	 val label : t -> label+       end+       type t+       val iter_vertex : (V.t -> unit) -> t -> unit+       val iter_edges_e : (E.t -> unit) -> t -> unit+     end)+    (L : sig+       val node : G.V.label -> value_list+       val edge : G.E.label -> value_list+     end) =+  struct++    open Format++    module H = Hashtbl.Make(G.V)++    let print fmt g =+      let nodes = H.create 97 in+      let cpt = ref 0 in+      let id n = +	try H.find nodes n+	with Not_found -> incr cpt; let id = !cpt in H.add nodes n id; id+      in+      fprintf fmt "@[graph [@\n";+      let rec value fmt = function+	| Int n -> fprintf fmt "%d" n+	| Float f -> fprintf fmt "%f" f+	| String s -> fprintf fmt "\"%s\"" s+	| List l -> fprintf fmt "[@\n  @[%a@]@\n]" value_list l+      and value_list fmt = function+	| [] -> ()+	| [s,v] -> fprintf fmt "%s %a" s value v+	| (s,v) :: l -> fprintf fmt "%s %a@\n" s value v; value_list fmt l+      in+      G.iter_vertex+	(fun v -> +	   fprintf fmt "  @[node [@\n  id %d@\n  @[%a@]@\n]@]@\n" +	     (id v) value_list (L.node (G.V.label v)))+	g;+      G.iter_edges_e+	(fun e ->+	   fprintf fmt +	     "  @[edge [@\n  source %d@\n  target %d@\n  @[%a@]@\n]@]@\n"+	     (id (G.E.src e)) (id (G.E.dst e)) +	     value_list (L.edge (G.E.label e)))+	g;+      fprintf fmt "]@\n"++  end+++# 671 "src/gml.ml"
+ external/ocamlgraph/src/gml.mli view
@@ -0,0 +1,76 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: gml.mli,v 1.3 2005-07-06 13:20:31 conchon Exp $ *)++(** Parser for GML file format *)++type value = +  | Int of int +  | Float of float+  | String of string+  | List of value_list+      +and value_list = (string * value) list++module Parse +  (B : Builder.S)+  (L : sig +     val node : value_list -> B.G.V.label+       (** how to build the node label out of the set of GML attributes;+for example {v node [ id 12 label "foo" ] v} +will call this function with [["id", Int 12; "label", String "foo"]] *)+     val edge : value_list -> B.G.E.label +       (** how to build the edge label out of the set of GML attributes *)+   end) :+sig+  +  val parse : string -> B.G.t++end++module Print+  (G : sig+     module V : sig+       type t+       val hash : t -> int+       val equal : t -> t -> bool+       type label+       val label : t -> label+     end+     module E : sig+       type t+       type label+       val src : t -> V.t+       val dst : t -> V.t+       val label : t -> label+     end+     type t+     val iter_vertex : (V.t -> unit) -> t -> unit+     val iter_edges_e : (E.t -> unit) -> t -> unit+   end)+  (L : sig+     val node : G.V.label -> value_list+     val edge : G.E.label -> value_list+   end) :+sig++  val print : Format.formatter -> G.t -> unit++end++
+ external/ocamlgraph/src/gml.mll view
@@ -0,0 +1,202 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: gml.mll,v 1.3 2005-07-06 13:20:31 conchon Exp $ *)++{ ++  open Lexing++  type value = +    | Int of int +    | Float of float+    | String of string+    | List of value_list++  and value_list = (string * value) list++}++let space = [' ' '\t' '\r' '\n']++let ident = ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']*+let digit = ['0'-'9']+let sign = '-' | '+' +let integer = sign? digit++let mantissa = 'E' sign? digit++let real = sign? digit* '.' digit* mantissa?+let in_string = [^ '"']*++rule file = parse+  | space +      { file lexbuf }+  | (ident as key) space +      { let v = value lexbuf in+	(key, v) :: file lexbuf }+  | eof +      { [] }+  | _ as c+      { failwith ("Gml: invalid character " ^ String.make 1 c) }++and value_list = parse+  | space +      { value_list lexbuf }+  | (ident as key) space +      { let v = value lexbuf in+	(key, v) :: value_list lexbuf }+  | ']' +      { [] }+  | _ as c+      { failwith ("Gml: invalid character " ^ String.make 1 c) }++and value = parse+  | integer as i+      { Int (int_of_string i) }+  | real as r+      { Float (float_of_string r) }+  | '"' (in_string as s) '"'+      { String s }+  | '['+      { let l = value_list lexbuf in List l }+  | _ as c+      { failwith ("Gml: invalid character " ^ String.make 1 c) }++{++  let parse f =+    let c = open_in f in+    let lb = from_channel c in+    let v = file lb in+    close_in c;+    v++  module Parse+    (B : Builder.S)+    (L : sig val node : value_list -> B.G.V.label+	     val edge : value_list -> B.G.E.label end) = +  struct++    let create_graph l =+      let nodes = Hashtbl.create 97 in+      let g = B.empty () in+      (* 1st pass: create the nodes *)+      let g =+	List.fold_left +	  (fun g v -> match v with+	     | "node", List l ->+		 let n = B.G.V.create (L.node l) in+		 begin +		   try +		     let id = List.assoc "id" l in Hashtbl.add nodes id n+		   with Not_found -> +		     ()+		 end;+		 B.add_vertex g n+	     | _ -> +		 g)+	  g l+      in+      (* 2nd pass: add the edges *)+      List.fold_left+	(fun g v -> match v with+	   | "edge", List l ->+	       begin try+		 let source = List.assoc "source" l in+		 let target = List.assoc "target" l in+		 let nsource = Hashtbl.find nodes source in+		 let ntarget = Hashtbl.find nodes target in+		 let e = B.G.E.create nsource (L.edge l) ntarget in+		 B.add_edge_e g e+	       with Not_found ->+		 g+	       end+	   | _ ->+	       g)+	g l+	+    let parse f =+      match parse f with+	| ["graph", List l] -> create_graph l+	| _ -> invalid_arg "Gml.Parse.parse: not a graph file"+      +  end++  module Print+    (G : sig+       module V : sig+	 type t+	 val hash : t -> int+	 val equal : t -> t -> bool+	 type label+	 val label : t -> label+       end+       module E : sig+	 type t+	 type label+	 val src : t -> V.t+	 val dst : t -> V.t+	 val label : t -> label+       end+       type t+       val iter_vertex : (V.t -> unit) -> t -> unit+       val iter_edges_e : (E.t -> unit) -> t -> unit+     end)+    (L : sig+       val node : G.V.label -> value_list+       val edge : G.E.label -> value_list+     end) =+  struct++    open Format++    module H = Hashtbl.Make(G.V)++    let print fmt g =+      let nodes = H.create 97 in+      let cpt = ref 0 in+      let id n = +	try H.find nodes n+	with Not_found -> incr cpt; let id = !cpt in H.add nodes n id; id+      in+      fprintf fmt "@[graph [@\n";+      let rec value fmt = function+	| Int n -> fprintf fmt "%d" n+	| Float f -> fprintf fmt "%f" f+	| String s -> fprintf fmt "\"%s\"" s+	| List l -> fprintf fmt "[@\n  @[%a@]@\n]" value_list l+      and value_list fmt = function+	| [] -> ()+	| [s,v] -> fprintf fmt "%s %a" s value v+	| (s,v) :: l -> fprintf fmt "%s %a@\n" s value v; value_list fmt l+      in+      G.iter_vertex+	(fun v -> +	   fprintf fmt "  @[node [@\n  id %d@\n  @[%a@]@\n]@]@\n" +	     (id v) value_list (L.node (G.V.label v)))+	g;+      G.iter_edges_e+	(fun e ->+	   fprintf fmt +	     "  @[edge [@\n  source %d@\n  target %d@\n  @[%a@]@\n]@]@\n"+	     (id (G.E.src e)) (id (G.E.dst e)) +	     value_list (L.edge (G.E.label e)))+	g;+      fprintf fmt "]@\n"++  end++}+
+ external/ocamlgraph/src/gpath.ml view
@@ -0,0 +1,132 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: path.ml,v 1.6 2005-07-18 07:10:35 filliatr Exp $ *)++module type WEIGHT = sig+  type label+  type t+  val weight : label -> t+  val zero : t+  val add : t -> t -> t+  val compare : t -> t -> int+end++module type G = sig+  type t +  module V : Sig.COMPARABLE +  module E : sig +    type t +    type label +    val label : t -> label +    val dst : t -> V.t +  end +  val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit+end++module Dijkstra+  (G: G)+  (W: WEIGHT with type label = G.E.label) =+struct++  open G.E++  module H =  Hashtbl.Make(G.V)++  module Elt = struct+    type t = W.t * G.V.t * G.E.t list++    (* weights are compared first, and minimal weights come first in the+       queue *)	       +    let compare (w1,v1,_) (w2,v2,_) =+      let cw = W.compare w2 w1 in+      if cw != 0 then cw else G.V.compare v1 v2+  end++  module PQ = Heap.Imperative(Elt)++  let shortest_path g v1 v2 =+    let visited = H.create 97 in+    let q = PQ.create 17 in+    let rec loop () = +      if PQ.is_empty q then raise Not_found;+      let (w,v,p) = PQ.pop_maximum q in+      if G.V.compare v v2 = 0 then +	List.rev p, w+      else begin+	if not (H.mem visited v) then begin+	  H.add visited v ();+	  G.iter_succ_e+	    (fun e -> PQ.add q (W.add w (W.weight (label e)), dst e, e :: p))+	    g v+	end;+	loop ()+      end+    in+    PQ.add q (W.zero, v1, []);+    loop ()++end++++module Check +  (G : +    sig+      type t+      module V : Sig.COMPARABLE+      val iter_succ : (V.t -> unit) -> t -> V.t -> unit+    end) = +struct++  module HV = Hashtbl.Make(G.V)+  module HVV = Hashtbl.Make(Util.HTProduct(G.V)(G.V))++  (* the cache contains the path tests already computed *)+  type path_checker = { cache : bool HVV.t; graph : G.t }++  let create g = { cache = HVV.create 97; graph = g }++  let check_path pc v1 v2 =+    try +      HVV.find pc.cache (v1, v2)+    with Not_found -> +      (* the path is not in cache; we check it with Dijkstra *)+      let visited = HV.create 97 in+      let q = Queue.create () in+      let rec loop () =+	if Queue.is_empty q then begin+	  HVV.add pc.cache (v1, v2) false;+	  false+	end else begin+	  let v = Queue.pop q in+	  HVV.add pc.cache (v1, v) true;+	  if G.V.compare v v2 = 0 then +	    true+	  else begin+	    if not (HV.mem visited v) then begin+	      HV.add visited v ();+	      G.iter_succ (fun v' -> Queue.add v' q) pc.graph v+	    end;+	    loop ()+	  end+	end+      in+      Queue.add v1 q;+      loop ()++end
+ external/ocamlgraph/src/gpath.mli view
@@ -0,0 +1,96 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: path.mli,v 1.9 2005-07-18 07:10:35 filliatr Exp $ *)++(** Paths *)++(** Minimal graph signature for Dijkstra's algorithm *)+module type G = sig+  type t +  module V : Sig.COMPARABLE +  module E : sig +    type t +    type label +    val label : t -> label +    val dst : t -> V.t +  end +  val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit+end++(** Signature for edges' weights *)+module type WEIGHT = sig+  type label+  type t+  val weight : label -> t+  val zero : t+  val add : t -> t -> t+  val compare : t -> t -> int+end++module Dijkstra+  (G: G)+  (W: WEIGHT with type label = G.E.label) : +sig++  val shortest_path : G.t -> G.V.t -> G.V.t -> G.E.t list * W.t+    (** [shortest_path g v1 v2] computes the shortest path from vertex [v1]+      to vertex [v2] in graph [g]. The path is returned as the list of +      followed edges, together with the total length of the path. +      raise [Not_found] if the path from [v1] to [v2] does not exist. ++      Complexity: at most O((V+E)log(V)) *)++end+++(** Check for a path *)++module Check+  (G : +    sig+      type t+      module V : Sig.COMPARABLE+      val iter_succ : (V.t -> unit) -> t -> V.t -> unit+    end) : +sig++  type path_checker+    (** the abstract data type of a path checker; this is a mutable data +	structure *)++  val create : G.t -> path_checker+    (** [create g] builds a new path checker for the graph [g];+        if the graph is mutable, it must not be mutated while this path +        checker is in use (through the function [check_path] below). *)++  val check_path : path_checker -> G.V.t -> G.V.t -> bool+    (** [check_path pc v1 v2] checks whether there is a path from [v1] to+	[v2] in the graph associated to the path checker [pc].++        Complexity: The path checker contains a cache of all results computed+	so far. This cache is implemented with a hash table so access in this +	cache is usually O(1). When the result is not in the cache, Dijkstra's+	algorithm is run to check for the path, and all intermediate results+	are cached.++	Note: if checks are to be done for almost all pairs of vertices, it+	may be more efficient to compute the transitive closure of the graph+	(see module [Oper]).+	*)++end
+ external/ocamlgraph/src/graphviz.ml view
@@ -0,0 +1,779 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: graphviz.ml,v 1.4 2006-05-09 10:19:37 conchon Exp $ *)++(** Interface with {i GraphViz}++    This module provides a basic interface with dot and neato,+    two programs of the GraphViz toolbox.+    These tools are available at the following URLs:+      http://www.graphviz.org/+      http://www.research.att.com/sw/tools/graphviz/++ *)++open Format++(***************************************************************************)+(** {2 Common stuff} *)++(** Because the neato and dot engines present a lot of common points -+    in particular in the graph description language, large parts of+    the code is shared.  First, the [!CommonAttributes] module defines+    attributes of graphs, nodes and edges that are understood by the+    two engines.  Second, given a module (of type [!ENGINE])+    describing an engine the [!MakeEngine] functor provides suitable+    interface function for it. *)++(*-------------------------------------------------------------------------*)+(** {3 Common attributes} *)++type color = int++let fprint_color ppf color =+  fprintf ppf "\"#%06X\"" color++let fprint_string ppf s = fprintf ppf "\"%s\"" s+(*  let s' = String.escaped s in+  if s' = s && s <> ""+  then fprintf ppf "%s" s+  else fprintf ppf "\"%s\"" s'*)++let fprint_string_user ppf s =+(*  let s = String.escaped s in*)+    fprintf ppf "\"%s\"" s++type arrow_style =+  [ `None | `Normal | `Inv | `Dot | `Odot | `Invdot | `Invodot ] ++let fprint_arrow_style ppf = function+    `None -> fprintf ppf "none"+  | `Normal -> fprintf ppf "normal"+  | `Inv -> fprintf ppf "inv"+  | `Dot -> fprintf ppf "dot"+  | `Odot -> fprintf ppf "odot"+  | `Invdot -> fprintf ppf "invdot"+  | `Invodot -> fprintf ppf "invodot"++let fprint_dir ppf = function+    `TopToBottom -> fprintf ppf "TB"+  | `LeftToRight -> fprintf ppf "LR"++(** The [ATTRIBUTES] module type defines the interface for the engines. *)+module type ATTRIBUTES = sig++  type graph  (** Attributes of graphs. *)++  type vertex (** Attributes of vertices. *)++  type edge   (** Attributes of edges. *)++  (** Attributes of (optional) boxes around vertices. *) +  type subgraph = {+    sg_name : string;            (** Box name. *)+    sg_attributes : vertex list; (** Box attributes. *)+  }++end++(** The [CommonAttributes] module defines attributes for graphs, nodes and+    edges that are available in the two engines, dot and neato. *)+module CommonAttributes = struct++  (** Attributes of graphs. *)+  type graph =+    [ `Center of bool+        (** Centers the drawing on the page.  Default value is [false]. *)+    | `Fontcolor of color+        (** Sets the font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the font family name.  Default value is ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the type size (in points).  Default value is [14]. *)+    | `Label of string+        (** Caption for graph drawing. *)+    | `Orientation of [ `Portrait | `Landscape ]+        (** Sets the page orientation.  Default value is [`Portrait]. *)+    | `Page of float * float+        (** Sets the PostScript pagination unit, e.g [8.5, 11.0]. *)+    | `Pagedir of [ `TopToBottom | `LeftToRight ]+        (** Traversal order of pages.  Default value is [`TopToBottom]. *)+    | `Size of float * float+        (** Sets the bounding box of drawing (in inches). *)+    | `OrderingOut+        (** Constrains  order of out-edges in a subgraph according to+          their file sequence *)+    ] ++  (** Attributes of nodes. *)+  type vertex =+    [ `Color of color+        (** Sets the color of the border of the node. Default value is [black]+         *)+    | `Fontcolor of color+        (** Sets the label font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the label font family name.  Default value is+            ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the label type size (in points).  Default value is [14]. *)+    | `Height of float+        (** Sets the minimum height.  Default value is [0.5]. *)+    | `Label of string+        (** Sets the label printed in the node. The string may include escaped+            newlines [\n], [\l], or [\r] for center, left, and right justified+	    lines.+            Record labels may contain recursive box lists delimited by { | }. +	*)+    | `Orientation of float+        (** Node rotation angle, in degrees.  Default value is [0.0]. *)+    | `Peripheries of int+        (** Sets  the  number  of periphery lines drawn around the polygon. *)+    | `Regular of bool+        (** If [true], then the polygon is made regular, i.e. symmetric about+	    the x and y axis, otherwise  the polygon   takes   on   the  aspect+	    ratio of the label.  Default value is [false]. *)+    | `Shape of+        [`Ellipse | `Box | `Circle | `Doublecircle | `Diamond+        | `Plaintext | `Record | `Polygon of int * float]+        (** Sets the shape of the node.  Default value is [`Ellipse].+            [`Polygon (i, f)] draws a polygon with [n] sides and a skewing+            of [f]. *)+    | `Style of [ `Filled | `Solid | `Dashed | `Dotted | `Bold | `Invis ]+        (** Sets the layout style of the node.  Several styles may be combined+            simultaneously. *)+    | `Width of float+        (** Sets the minimum width.  Default value is [0.75]. *)+    ]     ++  (** Attributes of edges. *)+  type edge =+    [ `Color of color+        (** Sets the edge stroke color.  Default value is [black]. *)+    | `Decorate of bool+        (** If [true], draws a line connecting labels with their edges. *)+    | `Dir of [ `Forward | `Back | `Both | `None ] +        (** Sets arrow direction.  Default value is [`Forward]. *)+    | `Fontcolor of color+        (** Sets the label font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the label font family name.  Default value is+	    ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the label type size (in points).  Default value is [14]. *)+    | `Label of string+        (** Sets the label to be attached to the edge.  The string may include+	    escaped newlines [\n], [\l], or [\r] for centered, left, or right+	    justified lines. *)+    | `Labelfontcolor of color+        (** Sets the font color for head and tail labels.  Default value is+            [black]. *)+    | `Labelfontname of string+        (** Sets the font family name for head and tail labels.  Default+            value is ["Times-Roman"]. *)+    | `Labelfontsize of int+        (** Sets the font size for head and tail labels (in points). +            Default value is [14]. *)+    | `Style of [ `Solid | `Dashed | `Dotted | `Bold | `Invis ]+        (** Sets the layout style of the edge.  Several styles may be combined+            simultaneously. *)+    ]     ++  (** Pretty-print. *)++  let fprint_orientation ppf = function+      `Portrait -> fprintf ppf "portrait"+    | `Landscape -> fprintf ppf "landscape"++  let fprint_graph ppf = function+      `Center b -> fprintf ppf "center=%i" (if b then 1 else 0)+    | `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a+    | `Fontname s -> fprintf ppf "fontname=%a" fprint_string s+    | `Fontsize i -> fprintf ppf "fontsize=%i" i+    | `Label s -> fprintf ppf "label=%a" fprint_string_user s+    | `Orientation a -> fprintf ppf "orientation=%a" fprint_orientation a+    | `Page (x, y) -> fprintf ppf "page=\"%f,%f\"" x y+    | `Pagedir a -> fprintf ppf "pagedir=%a" fprint_dir a+    | `Size (x, y) -> fprintf ppf "size=\"%f,%f\"" x y+    | `OrderingOut -> fprintf ppf "ordering=out"++  let fprint_shape ppf = function+    | `Ellipse -> fprintf ppf "ellipse"+    | `Box -> fprintf ppf "box"+    | `Circle -> fprintf ppf "circle"+    | `Doublecircle -> fprintf ppf "doublecircle"+    | `Diamond -> fprintf ppf "diamond"+    | `Plaintext -> fprintf ppf "plaintext"+    | `Record -> fprintf ppf "record"+    | `Polygon (i, f) -> fprintf ppf "polygon, sides=%i, skew=%f" i f++  let fprint_node_style ppf = function+      `Filled -> fprintf ppf "filled"+    | `Solid -> fprintf ppf "solid"+    | `Dashed -> fprintf ppf "dashed"+    | `Dotted -> fprintf ppf "dotted"+    | `Bold -> fprintf ppf "bold"+    | `Invis -> fprintf ppf "invis"++  let fprint_vertex ppf = function+      `Color a -> fprintf ppf "color=%a" fprint_color a+    | `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a+    | `Fontname s -> fprintf ppf "fontname=%a"  fprint_string s+    | `Fontsize i -> fprintf ppf "fontsize=%i" i+    | `Height f -> fprintf ppf "height=%f" f+    | `Label s -> fprintf ppf "label=%a" fprint_string_user s+    | `Orientation f -> fprintf ppf "orientation=%f" f+    | `Peripheries i -> fprintf ppf "peripheries=%i" i+    | `Regular b -> fprintf ppf "regular=%b" b+    | `Shape a -> fprintf ppf "shape=%a" fprint_shape a+    | `Style a -> fprintf ppf "style=%a" fprint_node_style a+    | `Width f -> fprintf ppf "width=%f" f++  let fprint_edge_style = +    fprint_node_style++  let fprint_arrow_direction ppf = function+      `Forward -> fprintf ppf "forward"+    | `Back -> fprintf ppf "back"+    | `Both -> fprintf ppf "both"+    | `None -> fprintf ppf "none"++  let fprint_edge ppf = function+      `Color a -> fprintf ppf "color=%a" fprint_color a+    | `Decorate b -> fprintf ppf "decorate=%b" b+    | `Dir a -> fprintf ppf "dir=%a" fprint_arrow_direction a+    | `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a+    | `Fontname s -> fprintf ppf "fontname=%a" fprint_string s+    | `Fontsize i -> fprintf ppf "fontsize=%i" i+    | `Label s -> fprintf ppf "label=%a" fprint_string_user s+    | `Labelfontcolor a -> fprintf ppf "labelfontcolor=%a" fprint_color a+    | `Labelfontname s -> fprintf ppf "labelfontname=\"%s\"" s +	(* (String.escaped s) *)+    | `Labelfontsize i -> fprintf ppf "labelfontsize=%i" i+    | `Style a -> fprintf ppf "style=%a" fprint_edge_style a++end+++(*-------------------------------------------------------------------------*)+(** {3 The [MakeEngine] functor} *)++(** An engine is described by a module of the following signature. *)+module type ENGINE = sig++  module Attributes : sig+    include ATTRIBUTES +    val fprint_graph:formatter -> graph -> unit+    val fprint_vertex: formatter -> vertex -> unit+    val fprint_edge: formatter -> edge -> unit+  end++  (** The litteral name of the engine. *)      +  val name: string++  (** The keyword for graphs ("digraph" for dot, "graph" for neato) *)+  val opening: string++  (** The litteral for edge arrows ("->" for dot, "--" for neato) *)+  val edge_arrow: string++end++module type GRAPH = sig++end++module MakeEngine+  (EN: ENGINE)+  (X : sig+     type t+     module V : sig type t end+     module E : sig type t val src : t -> V.t val dst : t -> V.t end+       +     val iter_vertex : (V.t -> unit) -> t -> unit+     val iter_edges_e : (E.t -> unit) -> t -> unit++     val graph_attributes: t -> EN.Attributes.graph list++     val default_vertex_attributes: t -> EN.Attributes.vertex list+     val vertex_name : V.t -> string+     val vertex_attributes: V.t -> EN.Attributes.vertex list++     val default_edge_attributes: t -> EN.Attributes.edge list+     val edge_attributes: E.t -> EN.Attributes.edge list+     val get_subgraph : V.t -> EN.Attributes.subgraph option+   end) =+struct++  let command = ref EN.name+  let set_command cmd =+    command := cmd++  exception Error of string++  let handle_error f arg =+    try +      f arg+    with +	Error msg ->+	  Printf.eprintf "%s: %s failure\n   %s\n"+	  Sys.argv.(0) EN.name msg;+	  flush stderr;+	  exit 2++    (** [fprint_graph_attributes ppf list] pretty prints a list of +        graph attributes on the formatter [ppf].  Attributes are separated+        by a ";". *)+    let fprint_graph_attributes ppf list =+       List.iter (function att ->+	 fprintf ppf "%a;@ " EN.Attributes.fprint_graph att+       ) list++   (** [fprint_graph_attribute printer ppf list] pretty prints a list of +       attributes on the formatter [ppf], using the printer [printer] for+       each attribute.  The list appears between brackets and attributes+       are speparated by ",".  If the list is empty, nothing is printed. *)+    let fprint_attributes fprint_attribute ppf = function+	[] -> ()+      | hd :: tl ->+	  let rec fprint_attributes_rec ppf = function+	      [] -> ()+	    | hd' :: tl' ->+		fprintf ppf ",@ %a%a" +		  fprint_attribute hd'+		  fprint_attributes_rec tl'+	  in+	  fprintf ppf " [@[<hov>%a%a@]]"+	    fprint_attribute hd+	    fprint_attributes_rec tl++    (** [fprint_graph_attributes ppf list] pretty prints a list of +        node attributes using the format of [fprint_attributes]. *)+    let fprint_node_attributes ppf list = +      fprint_attributes EN.Attributes.fprint_vertex ppf list+	 +    (** [fprint_graph_attributes ppf list] pretty prints a list of +        edge attributes using the format of [fprint_attributes]. *)+    let fprint_edge_attributes ppf list =+      fprint_attributes EN.Attributes.fprint_edge ppf list++    (** [fprint_graph ppf graph] pretty prints the graph [graph] in+        the CGL language on the formatter [ppf]. *)+    let fprint_graph ppf graph =+      let subgraphs = Hashtbl.create 7 in ++      (* Printing nodes. *)++      let print_nodes ppf =++	let default_node_attributes = X.default_vertex_attributes graph in+	if default_node_attributes  <> [] then+	  fprintf ppf "node%a;@ " +	    fprint_node_attributes default_node_attributes;++	X.iter_vertex +          (function node ->+             begin match X.get_subgraph node with +             | None -> ()+             | Some sg -> +                 try +                   let (sg,nodes) = +		     Hashtbl.find subgraphs sg.EN.Attributes.sg_name +		   in+                   Hashtbl.replace subgraphs +		     sg.EN.Attributes.sg_name (sg,node::nodes)+                 with Not_found -> +                   Hashtbl.add subgraphs sg.EN.Attributes.sg_name (sg,[node]) +             end;+	     fprintf ppf "%s%a;@ " +	       (X.vertex_name node)+	       fprint_node_attributes (X.vertex_attributes node)) +          graph++      in++      (* Printing subgraphs *)++      let print_subgraphs ppf = ++        Hashtbl.iter+          (fun name (sg,nodes) -> +             fprintf ppf "@[<v 2>subgraph cluster_%s { %t%t };@]@\n"+               name+               +               (fun ppf -> +                  (List.iter +                     (fun n -> +			fprintf ppf "%a;@\n" EN.Attributes.fprint_vertex n)+                     sg.EN.Attributes.sg_attributes))++               (fun ppf -> +                  (List.iter +		     (fun n -> fprintf ppf "%s;" (X.vertex_name n))+                     nodes))+          )+          subgraphs +        +      in++      (* Printing edges *)++      let print_edges ppf =+	+	let default_edge_attributes = X.default_edge_attributes graph in+	if default_edge_attributes <> [] then+	  fprintf ppf "edge%a;@ " +	    fprint_edge_attributes default_edge_attributes;++	X.iter_edges_e (function edge ->+	                  fprintf ppf "%s %s %s%a;@ "+	                    (X.vertex_name (X.E.src edge))+	                    EN.edge_arrow+	                    (X.vertex_name (X.E.dst edge))+	                    fprint_edge_attributes (X.edge_attributes edge)+                       ) graph++      in++      fprintf ppf "@[<v>%s G {@ @[<v 2>  %a"+	EN.opening+	fprint_graph_attributes (X.graph_attributes graph);+      fprintf ppf "%t@ " print_nodes;+      fprintf ppf "%t@ " print_subgraphs;+      fprintf ppf "%t@ " print_edges;+      fprintf ppf "@]}@]"++    (** [output_graph oc graph] pretty prints the graph [graph] in the dot+	language on the channel [oc]. *)+    let output_graph oc graph =++      let ppf = formatter_of_out_channel oc in+      fprint_graph ppf graph;+      pp_print_flush ppf ()++  end++(***************************************************************************)+(** {2 Interface with the dot engine} *)++(** The [DotAttributes] module defines attributes for graphs, nodes and edges+    that are available in the dot engine. *)+module DotAttributes = struct++  (** Attributes of graphs.  They include all common graph attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: clusterank, color,+      compound, labeljust, labelloc, ordering, rank, remincross, rotate,+      searchsize and style.+   *)+  type graph =+    [ CommonAttributes.graph+    | `Bgcolor of color+        (** Sets the background color and the inital fill color. *)+    | `Comment of string+        (** Comment string. *)+    | `Concentrate of bool+        (** If [true], enables edge concentrators.  Default value is [false]. *)+    | `Fontpath of string+        (** List of directories for fonts. *)+    | `Layers of string list+        (** List of layers. *)+    | `Margin of float+        (** Sets the page margin (included in the page size).  Default value is+            [0.5]. *)+    | `Mclimit of float+        (** Scale factor for mincross iterations.  Default value is [1.0]. *)+    | `Nodesep of float+        (** Sets the minimum separation between nodes, in inches.  Default+            value is [0.25]. *)+    | `Nslimit of int+        (** If set of [f], bounds network simplex iterations by [f *+            <number of nodes>] when ranking nodes. *)+    | `Nslimit1 of int+        (** If set of [f], bounds network simplex iterations by [f *+            <number of nodes>] when setting x-coordinates. *)+    | `Ranksep of float+        (** Sets the minimum separation between ranks. *)+    | `Quantum of float+        (** If not [0.0], node label dimensions will be rounded to integral+	    multiples of it.  Default value is [0.0]. *)+    | `Rankdir of [ `TopToBottom | `LeftToRight ]+        (** Direction of rank ordering.  Default value is [`TopToBottom]. *)+    | `Ratio of [ `Float of float | `Fill | `Compress| `Auto ]+        (** Sets the aspect ratio. *)+    | `Samplepoints of int+        (** Number of points used to represent ellipses and circles on output.+	    Default value is [8]. *)+    | `Url of string+        (** URL associated with graph (format-dependent). *)+    ] ++  (** Attributes of nodes.  They include all common node attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: bottomlabel, group,+      shapefile and toplabel.+   *)+  type vertex =+    [ CommonAttributes.vertex+    | `Comment of string+        (** Comment string. *)+    | `Distortion of float+        (* TEMPORARY *)+    | `Fillcolor of color+        (** Sets the fill color (used when `Style filled).  Default value+            is [lightgrey]. *)+    | `Fixedsize of bool+        (** If [true], forces the given dimensions to be the actual ones.+            Default value is [false]. *)+    | `Layer of string+        (** Overlay. *)+    | `Url of string+        (** The  default  url  for  image  map  files; in PostScript files,+            the base URL for all relative URLs, as recognized by Acrobat+	    Distiller 3.0 and up. *)+    | `Z of float+        (** z coordinate for VRML output. *)+    ] ++  (** Attributes of edges.  They include all common edge attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: lhead and ltail.+   *)+  type edge =+    [ CommonAttributes.edge+    | `Arrowhead of arrow_style+        (** Sets the style of the head arrow.  Default value is [`Normal]. *)+    | `Arrowsize of float+        (** Sets the scaling factor of arrowheads.  Default value is [1.0]. *)+    | `Arrowtail of arrow_style+        (** Sets the style of the tail arrow.  Default value is [`Normal]. *)+    | `Comment of string+        (** Comment string. *)+    | `Constraints of bool+        (** If [false], causes an edge to be ignored for rank assignment. +            Default value is [true]. *)+    | `Headlabel of string+        (** Sets the label attached to the head arrow. *)+    | `Headport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]+        (* TEMPORARY *)+    | `Headurl of string+        (** Url attached to head label if output format is ismap. *)+    | `Labelangle of float+        (** Angle in degrees which head or tail label is rotated off edge. +            Default value is [-25.0]. *)+    | `Labeldistance of float+        (** Scaling factor for distance of head or tail label from node. +            Default value is [1.0]. *)+    | `Labelfloat of bool+        (** If [true], lessen constraints on edge label placement. +            Default value is [false]. *)+    | `Layer of string+        (** Overlay. *)+    | `Minlen of int+        (** Minimum rank distance between head an tail.  Default value is [1]. *)+    | `Samehead of string+        (** Tag for head node; edge heads with the same tag are merged onto the+	    same port. *)+    | `Sametail of string+        (** Tag for tail node; edge tails with the same tag are merged onto the+	    same port. *)+    | `Taillabel of string+        (** Sets the label attached to the tail arrow. *)+    | `Tailport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]+        (* TEMPORARY *)+    | `Tailurl of string+        (** Url attached to tail label if output format is ismap. *)+    | `Weight of int+        (** Sets the integer cost of stretching the edge.  Default value is+            [1]. *)+    ] ++    type subgraph = {+      sg_name : string;+      sg_attributes : vertex list;+    }++    (** {4 Pretty-print of attributes} *)++    let rec fprint_string_list ppf = function+      [] -> ()+      | [hd] -> fprintf ppf "%s" hd+      | hd :: tl -> fprintf ppf "%s,%a" hd fprint_string_list tl++    let fprint_ratio ppf = function+	`Float f -> fprintf ppf "%f" f+      | `Fill -> fprintf ppf "fill"+      | `Compress -> fprintf ppf "compress"+      | `Auto -> fprintf ppf "auto"++    let fprint_graph ppf = function+	#CommonAttributes.graph as att -> CommonAttributes.fprint_graph ppf att+      | `Bgcolor a -> fprintf ppf "bgcolor=%a" fprint_color a+      | `Comment s -> fprintf ppf "comment=%a" fprint_string s+      | `Concentrate b -> fprintf ppf "concentrate=%b" b+      | `Fontpath s -> fprintf ppf "fontpath=%a" fprint_string s+      | `Layers s -> fprintf ppf "layers=%a" fprint_string_list s+      | `Margin f -> fprintf ppf "margin=%f" f+      | `Mclimit f -> fprintf ppf "mclimit=%f" f+      | `Nodesep f -> fprintf ppf "nodesep=%f" f+      | `Nslimit i -> fprintf ppf "nslimit=%i" i+      | `Nslimit1 i -> fprintf ppf "nslimit1=%i" i+      | `Ranksep f -> fprintf ppf "ranksep=%f" f+      | `Quantum f -> fprintf ppf "quantum=%f" f+      | `Rankdir a -> fprintf ppf "rankdir=%a" fprint_dir a+      | `Ratio a -> fprintf ppf "ratio=%a" fprint_ratio a+      | `Samplepoints i -> fprintf ppf "samplepoints=%i" i+      | `Url s -> fprintf ppf "URL=\"%s\"" s (*(String.escaped s)*)++    let fprint_vertex ppf = function+	#CommonAttributes.vertex as att -> +	  CommonAttributes.fprint_vertex ppf att+      | `Comment s -> fprintf ppf "comment=%a" fprint_string s+      | `Distortion f -> fprintf ppf "distortion=%f" f+      | `Fillcolor a -> fprintf ppf "fillcolor=%a" fprint_color a+      | `Fixedsize b -> fprintf ppf "fixedsize=%b" b+      | `Layer s -> fprintf ppf "layer=%a" fprint_string s+      | `Url s -> fprintf ppf "URL=\"%s\"" s (*(String.escaped s)*)+      | `Z f -> fprintf ppf "z=%f" f++    let fprint_port ppf = function+	`N -> fprintf ppf "n"+      | `NE -> fprintf ppf "ne"+      | `E -> fprintf ppf "e"+      | `SE -> fprintf ppf "se"+      | `S -> fprintf ppf "s"+      | `SW -> fprintf ppf "sw"+      | `W -> fprintf ppf "w"+      | `NW -> fprintf ppf "nw"++    let fprint_edge ppf = function+	#CommonAttributes.edge as att -> CommonAttributes.fprint_edge ppf att+      | `Arrowhead a -> fprintf ppf "arrowhead=%a" fprint_arrow_style a+      | `Arrowsize f -> fprintf ppf "arrowsize=%f" f+      | `Arrowtail a -> fprintf ppf "arrowtail=%a" fprint_arrow_style a+      | `Comment s -> fprintf ppf "comment=%a" fprint_string s+      | `Constraints b -> fprintf ppf "constraints=%b" b+      | `Headlabel s -> fprintf ppf "headlabel=%a" fprint_string s+      | `Headport a -> fprintf ppf "headport=%a" fprint_port a+      | `Headurl s -> fprintf ppf "headURL=%a" fprint_string s+      | `Labelangle f -> fprintf ppf "labelangle=%f" f+      | `Labeldistance f -> fprintf ppf "labeldistance=%f" f+      | `Labelfloat b -> fprintf ppf "labelfloat=%b" b+      | `Layer s -> fprintf ppf "layer=%a" fprint_string s+      | `Minlen i -> fprintf ppf "minlen=%i" i+      | `Samehead s -> fprintf ppf "samehead=%a" fprint_string s+      | `Sametail s -> fprintf ppf "sametail=%a" fprint_string s+      | `Taillabel s -> fprintf ppf "taillabel=%a" fprint_string s+      | `Tailport a -> fprintf ppf "tailport=%a" fprint_port a+      | `Tailurl s -> fprintf ppf "tailURL=%a" fprint_string s+      | `Weight i -> fprintf ppf "weight=%i" i++end++module Dot = +  MakeEngine (struct+		module Attributes = DotAttributes+		let name = "dot"+		let opening = "digraph"+		let edge_arrow = "->"+	      end)++(***************************************************************************)+(** {2 Interface with the neato engine} *)++(** The [NeatoAttributes] module defines attributes for graphs, nodes and edges+    that are available in the neato engine. *)+module NeatoAttributes = struct++  (** Attributes of graphs.  They include all common graph attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled. *)+  type graph =+    [ CommonAttributes.graph+    | `Margin of float * float+        (** Sets the page margin (included in the page size).  Default value is+            [0.5, 0.5]. *)+    | `Start of int+        (** Seed for random number generator. *)+    | `Overlap of bool+	(** Default value is [true]. *)+    | `Spline of bool+	(** [true] makes edge splines if nodes don't overlap.+	    Default value is [false]. *)+    | `Sep of float+	(** Edge spline separation factor from nodes.  Default value +	    is [0.0]. *)+    ] ++  (** Attributes of nodes.  They include all common node attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled. *)+  type vertex =+    [ CommonAttributes.vertex+    | `Pos of float * float+        (** Initial coordinates of the node. *)+    ] ++  (** Attributes of edges.  They include all common edge attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled. *)+  type edge =+    [ CommonAttributes.edge+    | `Id of string+        (** Optional value to distinguish multiple edges. *)+    | `Len of float+        (** Preferred length of edge.  Default value is [1.0]. *)+    | `Weight of float+        (** Strength of edge spring.  Default value is [1.0]. *)+    ] ++    type subgraph = {+      sg_name : string;+      sg_attributes : vertex list;+    }++  (** {4 Pretty-print of attributes} *)++    let fprint_graph ppf = function+	#CommonAttributes.graph as att -> CommonAttributes.fprint_graph ppf att+      | `Margin (f1, f2) -> fprintf ppf "margin=\"%f,%f\"" f1 f2+      | `Start i -> fprintf ppf "start=%i" i+      | `Overlap b -> fprintf ppf "overlap=%b" b+      | `Spline b -> fprintf ppf "spline=%b" b+      | `Sep f -> fprintf ppf "sep=%f" f++    let fprint_vertex ppf = function+	#CommonAttributes.vertex as att -> +	  CommonAttributes.fprint_vertex ppf att+      | `Pos (f1, f2) -> fprintf ppf "pos=\"%f,%f\"" f1 f2++    let fprint_edge ppf = function+	#CommonAttributes.edge as att -> CommonAttributes.fprint_edge ppf att+      | `Id s -> fprintf ppf "id=%a" fprint_string s+      | `Len f -> fprintf ppf "len=%f" f+      | `Weight f -> fprintf ppf "weight=%f" f++end++module Neato = +  MakeEngine (struct+		module Attributes = NeatoAttributes+		let name = "neato"+		let opening = "graph"+		let edge_arrow = "--"+	      end)
+ external/ocamlgraph/src/graphviz.mli view
@@ -0,0 +1,469 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: graphviz.mli,v 1.4 2005-01-18 09:17:49 filliatr Exp $ *)++(** Interface with {i GraphViz}++    This module provides a basic interface with dot and neato,+    two programs of the GraphViz toolbox.+    These tools are available at the following URLs:++    {v http://www.graphviz.org/ v}++    {v http://www.research.att.com/sw/tools/graphviz/ v}++ *)++open Format++(***************************************************************************)+(** {2 Common stuff} *)++(** Because the neato and dot engines present a lot of common points -+    in particular in the graph description language, large parts of+    the code is shared.  The [CommonAttributes] module defines+    attributes of graphs, vertices and edges that are understood by the+    two engines.  Then module [DotAttributes] and [NeatoAttributes]+    define attributes specific to dot and neato respectively. *)++(*-------------------------------------------------------------------------*)+(** {3 Common types and signatures} *)++type color = int++type arrow_style =+  [ `None | `Normal | `Inv | `Dot | `Odot | `Invdot | `Invodot ] ++(** The [ATTRIBUTES] module type defines the interface for the engines. *)+module type ATTRIBUTES = sig++  type graph  (** Attributes of graphs. *)++  type vertex (** Attributes of vertices. *)++  type edge   (** Attributes of edges. *)++  (** Attributes of (optional) boxes around vertices. *) +  type subgraph = {+    sg_name : string;            (** Box name. *)+    sg_attributes : vertex list; (** Box attributes. *)+  }++end++(*-------------------------------------------------------------------------*)+(** {3 Common attributes} *)++(** The [CommonAttributes] module defines attributes for graphs, vertices and+    edges that are available in the two engines, dot and neato. *)+module CommonAttributes : sig++  (** Attributes of graphs. *)+  type graph =+    [ `Center of bool+        (** Centers the drawing on the page.  Default value is [false]. *)+    | `Fontcolor of color+        (** Sets the font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the font family name.  Default value is ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the type size (in points).  Default value is [14]. *)+    | `Label of string+        (** Caption for graph drawing. *)+    | `Orientation of [ `Portrait | `Landscape ]+        (** Sets the page orientation.  Default value is [`Portrait]. *)+    | `Page of float * float+        (** Sets the PostScript pagination unit, e.g [8.5, 11.0]. *)+    | `Pagedir of [ `TopToBottom | `LeftToRight ]+        (** Traversal order of pages.  Default value is [`TopToBottom]. *)+    | `Size of float * float+        (** Sets the bounding box of drawing (in inches). *)+    | `OrderingOut+        (** Constrains  order of out-edges in a subgraph according to+          their file sequence *)+    ] ++  (** Attributes of vertices.+   *)+  type vertex =+    [ `Color of color+        (** Sets the color of the border of the vertex. +	  Default value is [black] *)+    | `Fontcolor of color+        (** Sets the label font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the label font family name.  Default value is+            ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the label type size (in points).  Default value is [14].+         *)+    | `Height of float+        (** Sets the minimum height.  Default value is [0.5]. *)+    | `Label of string+        (** Sets the label printed in the vertex. +	    The string may include escaped+            newlines [\n], [\l], or [\r] for center, left, and right justified+	    lines.+            Record labels may contain recursive box lists delimited by { | }. +	*)+    | `Orientation of float+        (** Vertex rotation angle, in degrees.  Default value is [0.0]. *)+    | `Peripheries of int+        (** Sets  the  number  of periphery lines drawn around the polygon. *)+    | `Regular of bool+        (** If [true], then the polygon is made regular, i.e. symmetric about+	    the x and y axis, otherwise  the polygon   takes   on   the  aspect+	    ratio of the label.  Default value is [false]. *)+    | `Shape of+        [`Ellipse | `Box | `Circle | `Doublecircle | `Diamond+        | `Plaintext | `Record | `Polygon of int * float]+        (** Sets the shape of the vertex.  Default value is [`Ellipse].+            [`Polygon (i, f)] draws a polygon with [n] sides and a skewing+            of [f]. *)+    | `Style of [ `Filled | `Solid | `Dashed | `Dotted | `Bold | `Invis ]+        (** Sets the layout style of the vertex.  +	    Several styles may be combined simultaneously. *)+    | `Width of float+        (** Sets the minimum width.  Default value is [0.75]. *)+    ]     ++  (** Attributes of edges.+   *)+  type edge =+    [ `Color of color+        (** Sets the edge stroke color.  Default value is [black]. *)+    | `Decorate of bool+        (** If [true], draws a line connecting labels with their edges. *)+    | `Dir of [ `Forward | `Back | `Both | `None ] +        (** Sets arrow direction.  Default value is [`Forward]. *)+    | `Fontcolor of color+        (** Sets the label font color.  Default value is [black]. *)+    | `Fontname of string+        (** Sets the label font family name.  Default value is+	    ["Times-Roman"]. *)+    | `Fontsize of int+        (** Sets the label type size (in points).  Default value is [14]. *)+    | `Label of string+        (** Sets the label to be attached to the edge.  The string may include+	    escaped newlines [\n], [\l], or [\r] for centered, left, or right+	    justified lines. *)+    | `Labelfontcolor of color+        (** Sets the font color for head and tail labels.  Default value is+            [black]. *)+    | `Labelfontname of string+        (** Sets the font family name for head and tail labels.  Default+            value is ["Times-Roman"]. *)+    | `Labelfontsize of int+        (** Sets the font size for head and tail labels (in points). +            Default value is [14]. *)+    | `Style of [ `Solid | `Dashed | `Dotted | `Bold | `Invis ]+        (** Sets the layout style of the edge.  Several styles may be combined+            simultaneously. *)+    ]     ++end++(***************************************************************************)+(** {2 Interface with the dot engine} *)++(** [DotAttributes] extends [CommonAttributes] and implements [ATTRIBUTES]. *)+module DotAttributes : sig++  (** Attributes of graphs.  They include all common graph attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: clusterank, color,+      compound, labeljust, labelloc, ordering, rank, remincross, rotate,+      searchsize and style.+   *)+  type graph =+    [ CommonAttributes.graph+    | `Bgcolor of color+        (** Sets the background color and the inital fill color. *)+    | `Comment of string+        (** Comment string. *)+    | `Concentrate of bool+        (** If [true], enables edge concentrators.  Default value is [false]. *)+    | `Fontpath of string+        (** List of directories for fonts. *)+    | `Layers of string list+        (** List of layers. *)+    | `Margin of float+        (** Sets the page margin (included in the page size).  Default value is+            [0.5]. *)+    | `Mclimit of float+        (** Scale factor for mincross iterations.  Default value is [1.0]. *)+    | `Nodesep of float+        (** Sets the minimum separation between nodes, in inches.  Default+            value is [0.25]. *)+    | `Nslimit of int+        (** If set of [f], bounds network simplex iterations by [f *+            <number of nodes>] when ranking nodes. *)+    | `Nslimit1 of int+        (** If set of [f], bounds network simplex iterations by [f *+            <number of nodes>] when setting x-coordinates. *)+    | `Ranksep of float+        (** Sets the minimum separation between ranks. *)+    | `Quantum of float+        (** If not [0.0], node label dimensions will be rounded to integral+	    multiples of it.  Default value is [0.0]. *)+    | `Rankdir of [ `TopToBottom | `LeftToRight ]+        (** Direction of rank ordering.  Default value is [`TopToBottom]. *)+    | `Ratio of [ `Float of float | `Fill | `Compress| `Auto ]+        (** Sets the aspect ratio. *)+    | `Samplepoints of int+        (** Number of points used to represent ellipses and circles on output.+	    Default value is [8]. *)+    | `Url of string+        (** URL associated with graph (format-dependent). *)+    ] ++  (** Attributes of nodes.  They include all common node attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: bottomlabel, group,+      shapefile and toplabel.+   *)+  type vertex =+    [ CommonAttributes.vertex+    | `Comment of string+        (** Comment string. *)+    | `Distortion of float+        (* TEMPORARY *)+    | `Fillcolor of color+        (** Sets the fill color (used when `Style filled).  Default value+            is [lightgrey]. *)+    | `Fixedsize of bool+        (** If [true], forces the given dimensions to be the actual ones.+            Default value is [false]. *)+    | `Layer of string+        (** Overlay. *)+    | `Url of string+        (** The  default  url  for  image  map  files; in PostScript files,+            the base URL for all relative URLs, as recognized by Acrobat+	    Distiller 3.0 and up. *)+    | `Z of float+        (** z coordinate for VRML output. *)+    ] ++  (** Attributes of edges.  They include all common edge attributes and+      several specific ones.  All attributes described in the "dot User's+      Manual, February 4, 2002" are handled, excepted: lhead and ltail.+   *)+  type edge =+    [ CommonAttributes.edge+    | `Arrowhead of arrow_style+        (** Sets the style of the head arrow.  Default value is [`Normal]. *)+    | `Arrowsize of float+        (** Sets the scaling factor of arrowheads.  Default value is [1.0]. *)+    | `Arrowtail of arrow_style+        (** Sets the style of the tail arrow.  Default value is [`Normal]. *)+    | `Comment of string+        (** Comment string. *)+    | `Constraints of bool+        (** If [false], causes an edge to be ignored for rank assignment. +            Default value is [true]. *)+    | `Headlabel of string+        (** Sets the label attached to the head arrow. *)+    | `Headport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]+        (* TEMPORARY *)+    | `Headurl of string+        (** Url attached to head label if output format is ismap. *)+    | `Labelangle of float+        (** Angle in degrees which head or tail label is rotated off edge. +            Default value is [-25.0]. *)+    | `Labeldistance of float+        (** Scaling factor for distance of head or tail label from node. +            Default value is [1.0]. *)+    | `Labelfloat of bool+        (** If [true], lessen constraints on edge label placement. +            Default value is [false]. *)+    | `Layer of string+        (** Overlay. *)+    | `Minlen of int+        (** Minimum rank distance between head an tail.  +	    Default value is [1]. *)+    | `Samehead of string+        (** Tag for head node; edge heads with the same tag are merged onto the+	    same port. *)+    | `Sametail of string+        (** Tag for tail node; edge tails with the same tag are merged onto the+	    same port. *)+    | `Taillabel of string+        (** Sets the label attached to the tail arrow. *)+    | `Tailport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]+        (* TEMPORARY *)+    | `Tailurl of string+        (** Url attached to tail label if output format is ismap. *)+    | `Weight of int+        (** Sets the integer cost of stretching the edge.  Default value is+            [1]. *)+    ] ++    type subgraph = {+      sg_name : string;+      sg_attributes : vertex list;+    }++end++module Dot+  (X : sig++     (** Graph implementation. *)++     type t+     module V : sig type t end+     module E : sig type t val src : t -> V.t val dst : t -> V.t end+       +     val iter_vertex : (V.t -> unit) -> t -> unit+     val iter_edges_e : (E.t -> unit) -> t -> unit+       +     (** Graph, vertex and edge attributes. *)++     val graph_attributes: t -> DotAttributes.graph list+       +     val default_vertex_attributes: t -> DotAttributes.vertex list+     val vertex_name : V.t -> string+     val vertex_attributes: V.t -> DotAttributes.vertex list++     val get_subgraph : V.t -> DotAttributes.subgraph option+       (** The box (if exists) which the vertex belongs to. Boxes with same+	   names are not distinguished and so they should have the same+	   attributes. *)+       +     val default_edge_attributes: t -> DotAttributes.edge list+     val edge_attributes: E.t -> DotAttributes.edge list+       +   end) :+sig++  (** [fprint_graph ppf graph] pretty prints the graph [graph] in+    the CGL language on the formatter [ppf]. *)+  val fprint_graph: formatter -> X.t -> unit++  (** [output_graph oc graph] pretty prints the graph [graph] in the dot+    language on the channel [oc]. *)+  val output_graph: out_channel -> X.t -> unit++end++(***************************************************************************)+(** {2 The neato engine} *)++module NeatoAttributes : sig++  (** Attributes of graphs.  They include all common graph attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled.+   *)+  type graph =+    [ CommonAttributes.graph+    | `Margin of float * float+        (** Sets the page margin (included in the page size).  Default value is+            [0.5, 0.5]. *)+    | `Start of int+        (** Seed for random number generator. *)+    | `Overlap of bool+	(** Default value is [true]. *)+    | `Spline of bool+	(** [true] makes edge splines if nodes don't overlap.+	    Default value is [false]. *)+    | `Sep of float+	(** Edge spline separation factor from nodes.  Default value +	    is [0.0]. *)+    ] ++  (** Attributes of nodes.  They include all common node attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled.+   *)+  type vertex =+    [ CommonAttributes.vertex+    | `Pos of float * float+        (** Initial coordinates of the vertex. *)+    ] ++  (** Attributes of edges.  They include all common edge attributes and+      several specific ones.  All attributes described in the "Neato User's+      manual, April 10, 2002" are handled.+   *)+  type edge =+    [ CommonAttributes.edge+    | `Id of string+        (** Optional value to distinguish multiple edges. *)+    | `Len of float+        (** Preferred length of edge.  Default value is [1.0]. *)+    | `Weight of float+        (** Strength of edge spring.  Default value is [1.0]. *)+    ] ++  type subgraph = {+    sg_name : string;+    sg_attributes : vertex list;+  }++end++module Neato+  (X : sig++     (** Graph implementation. *)++     type t+     module V : sig type t end+     module E : sig type t val src : t -> V.t val dst : t -> V.t end+       +     val iter_vertex : (V.t -> unit) -> t -> unit+     val iter_edges_e : (E.t -> unit) -> t -> unit+       +     (** Graph, vertex and edge attributes. *)++     val graph_attributes: t -> NeatoAttributes.graph list+       +     val default_vertex_attributes: t -> NeatoAttributes.vertex list+     val vertex_name : V.t -> string+     val vertex_attributes: V.t -> NeatoAttributes.vertex list++     val get_subgraph : V.t -> NeatoAttributes.subgraph option+       (** The box (if exists) which the vertex belongs to. Boxes with same+	   names are not distinguished and so they should have the same+	   attributes. *)+       +     val default_edge_attributes: t -> NeatoAttributes.edge list+     val edge_attributes: E.t -> NeatoAttributes.edge list+       +   end) :+sig++  (** Several functions provided by this module run the external program+      {i neato}.  By default, this command is supposed to be in the default+      path and is invoked by {i neato}.  The function+      [set_command] allows to set an alternative path at run time. *)+  val set_command: string -> unit++  exception Error of string+  val handle_error: ('a -> 'b) -> 'a -> 'b++  (** [fprint_graph ppf graph] pretty prints the graph [graph] in+    the CGL language on the formatter [ppf]. *)+  val fprint_graph: formatter -> X.t -> unit++  (** [output_graph oc graph] pretty prints the graph [graph] in the dot+    language on the channel [oc]. *)+  val output_graph: out_channel -> X.t -> unit++end
+ external/ocamlgraph/src/imperative.ml view
@@ -0,0 +1,618 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: imperative.ml,v 1.27 2006-05-12 14:07:16 filliatr Exp $ *)++open Sig+open Blocks++module type S = sig++  (** Imperative Unlabeled Graphs *)+  module Concrete (V: COMPARABLE) : +    Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t++  (** Abstract Imperative Unlabeled Graphs *)+  module Abstract(V: sig type t end) : +    Sig.IM with type V.label = V.t and type E.label = unit++  (** Imperative Labeled Graphs *)+  module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :+    Sig.I with type V.t = V.t and type V.label = V.t +	    and type E.t = V.t * E.t * V.t and type E.label = E.t++  (** Abstract Imperative Labeled Graphs *)+  module AbstractLabeled (V: sig type t end)(E: ORDERED_TYPE_DFT) :+    Sig.IM with type V.label = V.t and type E.label = E.t++end++module I = Make(Make_Hashtbl)++type 'a abstract_vertex = { tag : int; label : 'a; mutable mark : int }++(* Implement the module [Mark]. *)+module Make_Mark+  (X: sig +     type graph+     type label +     val iter_vertex : (label abstract_vertex -> unit) -> graph -> unit+   end) = +struct+  type vertex = X.label abstract_vertex+  type graph = X.graph+  let get v = v.mark+  let set v m = v.mark <- m+  let clear g = X.iter_vertex (fun v -> set v 0) g+end++(* Vertex for the abstract imperative graphs. *)+module AbstractVertex(V: sig type t end) = struct++  type label = V.t+  type t = label abstract_vertex++  let compare x y = compare x.tag y.tag +  let hash x = Hashtbl.hash x.tag+  let equal x y = x.tag = y.tag+  let label x = x.label++  let create l = +    assert (!cpt_vertex < max_int);+    incr cpt_vertex;+    { tag = !cpt_vertex; label = l; mark = 0 }++end++module Digraph = struct++  module Concrete (V: COMPARABLE) = struct++    include I.Digraph.Concrete(V)++    let create ?(size=997) () = create size++    let add_vertex g v = ignore (add_vertex g v)+    let remove_vertex g v = ignore (remove_vertex g v)+    let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)+    let remove_edge_e g e = ignore (remove_edge_e g e)++    let add_edge g v1 v2 = +      add_vertex g v1;+      add_vertex g v2;+      ignore (unsafe_add_edge g v1 v2)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let copy = HM.copy++  end++  module ConcreteBidirectional (V: COMPARABLE) = struct++    include I.Digraph.ConcreteBidirectional(V)++    let create ?(size=997) () = create size++    let add_vertex g v = +      if not (HM.mem v g) then ignore (unsafe_add_vertex g v)++    let add_edge g v1 v2 = +      add_vertex g v1;+      add_vertex g v2;+      ignore (unsafe_add_edge g v1 v2)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_vertex g v =+      if HM.mem v g then begin+	iter_pred_e (fun e -> ignore (remove_edge_e g e)) g v;+	iter_succ_e (fun e -> ignore (remove_edge_e g e)) g v;+	ignore (HM.remove v g)+      end++    let copy = HM.copy++    let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)+    let remove_edge_e g e = ignore (remove_edge_e g e)++  end++  module ConcreteLabeled(V: COMPARABLE)(E: ORDERED_TYPE_DFT) = struct++    let default = E.default++    include I.Digraph.ConcreteLabeled(V)(E)++    let create ?(size=997) () = create size++    let add_vertex g v = ignore (add_vertex g v)+    let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)+    let remove_edge_e g e = ignore (remove_edge_e g e)++    let add_edge_e g (v1, l, v2) = +      add_vertex g v1;+      add_vertex g v2;+      ignore (unsafe_add_edge g v1 (v2, l))++    let add_edge g v1 v2 = add_edge_e g (v1, default, v2)++    let remove_vertex g v =+      if HM.mem v g then+	let remove s =+	  S.fold +	    (fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)+	    s S.empty+	in+	ignore (HM.remove v g);+	HM.iter (fun k s -> ignore (HM.add k (remove s) g)) g++    let copy = HM.copy++  end++  module Abstract(V: sig type t end) = struct+    +    include I.Digraph.Abstract(AbstractVertex(V))++    let create ?(size=997) () = { edges = G.create size; size = 0 }++    let add_vertex g v = +      if not (HM.mem v g.edges) then begin+	g.size <- Pervasives.succ g.size;+	ignore (G.unsafe_add_vertex g.edges v)+      end++    let add_edge g v1 v2 = +      add_vertex g v1;+      add_vertex g v2;+      ignore (unsafe_add_edge g.edges v1 v2)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_vertex g v = +      if HM.mem v g.edges then+	let e = g.edges in+	ignore (HM.remove v e);+	HM.iter (fun k s -> ignore (HM.add k (S.remove v s) e)) e;+	g.size <- Pervasives.pred g.size++    module Mark = Make_Mark(struct +			      type graph = t +			      type label = V.label +			      let iter_vertex = iter_vertex +			    end)++    let copy g =+      let h = HM.create 997 in+      let vertex v = +	try+	  HM.find v h+	with Not_found ->+	  let v' = V.create (V.label v) in+	  ignore (HM.add v v' h);+	  v'+      in+      map_vertex vertex g++    let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)+    let remove_edge_e g e = ignore (remove_edge_e g e)++  end++  module AbstractLabeled(V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct+    +    include I.Digraph.AbstractLabeled(AbstractVertex(V))(Edge)++    let create ?(size=997) () = { edges = G.create size; size = 0 }++    let add_vertex g v = +      if not (HM.mem v g.edges) then begin+	g.size <- Pervasives.succ g.size;+	ignore (G.unsafe_add_vertex g.edges v)+      end++    let add_edge_e g (v1, l, v2) =+      add_vertex g v1;+      add_vertex g v2;+      ignore (unsafe_add_edge g.edges v1 (v2, l))++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_vertex g v =+      if HM.mem v g.edges then+	let remove s =+	  S.fold +	    (fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)+	    s S.empty+	in+	let e = g.edges in+	ignore (HM.remove v e);+	HM.iter (fun k s -> ignore (HM.add k (remove s) e)) e;+	g.size <- Pervasives.pred g.size++    module Mark = Make_Mark(struct +			      type graph = t +			      type label = V.label +			      let iter_vertex = iter_vertex +			    end)++    let copy g =+      let h = HM.create 997 in+      let vertex v = +	try+	  HM.find v h+	with Not_found ->+	  let v' = V.create (V.label v) in+	  ignore (HM.add v v' h);+	  v'+      in+      map_vertex vertex g++    let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)+    let remove_edge_e g e = ignore (remove_edge_e g e)++  end++end++module Graph = struct++  module Concrete(V: COMPARABLE) = struct++    module G = Digraph.Concrete(V) ++    include Graph(G)++    (* Export some definitions of [G] *)++    let create = G.create+    let copy = G.copy+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge g v1 v2 = +      G.add_edge g v1 v2;+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      ignore (G.unsafe_add_edge g v2 v1)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_edge g v1 v2 =+      G.remove_edge g v1 v2;+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      ignore (G.unsafe_remove_edge g v2 v1)++    let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  end++  module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) = struct++    module G = Digraph.ConcreteLabeled(V)(E)++    include Graph(G)++    (* Export some definitions of [G] *)++    let create = G.create+    let copy = G.copy+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge_e g (v1, l, v2 as e) =+      G.add_edge_e g e;+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      ignore (G.unsafe_add_edge g v2 (v1, l))++    let add_edge g v1 v2 = add_edge_e g (v1, G.default, v2)++    let remove_edge g v1 v2 =+      G.remove_edge g v1 v2;+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      ignore (G.unsafe_remove_edge g v2 v1)++    let remove_edge_e g (v1, l, v2 as e) =+      G.remove_edge_e g e;+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      ignore (G.unsafe_remove_edge_e g (v2, l, v1))++  end++  module Abstract(V: sig type t end) = struct++    module G = Digraph.Abstract(V)++    include Graph(G)++    (* Export some definitions of [G] *)++    module Mark = G.Mark+    let create = G.create+    let copy = G.copy+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge g v1 v2 = +      G.add_edge g v1 v2;+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      ignore (G.unsafe_add_edge g.G.edges v2 v1)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_edge g v1 v2 =+      G.remove_edge g v1 v2;+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      ignore (G.unsafe_remove_edge g.G.edges v2 v1)++    let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  end++  module AbstractLabeled (V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct++    module G = Digraph.AbstractLabeled(V)(Edge)++    include Graph(G)++    (* Export some definitions of [G] *)++    module Mark = G.Mark+    let create = G.create+    let copy = G.copy+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge_e g (v1, l, v2 as e) = +      G.add_edge_e g e;+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      ignore (G.unsafe_add_edge g.G.edges v2 (v1, l))++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_edge g v1 v2 =+      G.remove_edge g v1 v2;+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      ignore (G.unsafe_remove_edge g.G.edges v2 v1)++    let remove_edge_e g (v1, l, v2 as e) =+      ignore (G.remove_edge_e g e);+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      ignore (G.unsafe_remove_edge_e g.G.edges (v2, l, v1))++  end++end++module Matrix = struct++  module type S = sig+    include Sig.I with type V.t = int and type V.label = int+		  and type E.t = int * int+    val make : int -> t+  end++  module Digraph = struct++    module V = struct+      type t = int+      type label = int+      let compare = Pervasives.compare+      let hash = Hashtbl.hash+      let equal = (==)+      let create i = i+      let label i = i+    end++    module E = struct+      type t = V.t * V.t+      type vertex = V.t+      let compare = Pervasives.compare+      type label = unit+      let create v1 _ v2 = (v1, v2)+      let src = fst+      let dst = snd+      let label _ = ()+    end++    type t = Bitv.t array+    type vertex = V.t+    type edge = E.t++    let create ?size () = +      failwith "do not use Matrix.create; please use Matrix.make instead"+		      +    let make n =+      if n < 0 then invalid_arg "Matrix.make";+      Array.init n (fun _ -> Bitv.create n false)++    let is_directed = true+			+    let nb_vertex = Array.length+    let is_empty g = nb_vertex g = 0+    let nb_edges =+      Array.fold_left (Bitv.fold_left (fun n b -> if b then n+1 else n)) 0+	+    let mem_vertex g v = 0 <= v && v < nb_vertex g+    let mem_edge g i j = Bitv.get g.(i) j+    let mem_edge_e g (i,j) = Bitv.get g.(i) j+    let find_edge g i j = if mem_edge g i j then i, j else raise Not_found+			       +    (* constructors *)+    let add_edge g i j = Bitv.set g.(i) j true+    let add_edge_e g (i,j) = Bitv.set g.(i) j true+			       +    let remove_edge g i j = Bitv.set g.(i) j false+    let remove_edge_e g (i,j) = Bitv.set g.(i) j false++    let unsafe_add_edge g i j = +      Bitv.unsafe_set (Array.unsafe_get g i) j true+    let unsafe_remove_edge g i j = +      Bitv.unsafe_set (Array.unsafe_get g i) j false+				  +    let remove_vertex g _ = ()+    let add_vertex g _ = ()+			   +    let copy g = Array.init (nb_vertex g) (fun i -> Bitv.copy g.(i))+		   +    (* iter/fold on all vertices/edges of a graph *)+    let iter_vertex f g = +      for i = 0 to nb_vertex g - 1 do f i done+      +    let iter_edges f g =+      for i = 0 to nb_vertex g - 1 do +	Bitv.iteri (fun j b -> if b then f i j) g.(i)+      done+      +    let fold_vertex f g a = +      let n = nb_vertex g in +      let rec fold i a = if i = n then a else fold (i+1) (f i a) in fold 0 a+								      +    let fold_edges f g a =+      fold_vertex+	(fun i a -> +	   Bitv.foldi_right (fun j b a -> if b then f i j a else a) g.(i) a)+	g a+	+    (* successors and predecessors of a vertex *)+    let succ g i = +      Bitv.foldi_left (fun l j b -> if b then j::l else l) [] g.(i)+	+    let pred g i = +      fold_vertex+	(fun j a -> if Bitv.unsafe_get g.(j) i then j :: a else a)+	g []+	+    (* iter/fold on all successor/predecessor of a vertex. *)+    let iter_succ f g i =+      let si = g.(i) in+      for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get si j then f j done+      (* optimization w.r.t. +	 [Bitv.iteri (fun j b -> if b then f j) g.(i)]+      *)++    let iter_pred f g i =+      for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get g.(j) i then f j done+      +    let fold_succ f g i a =+      Bitv.foldi_right (fun j b a -> if b then f j a else a) g.(i) a+	+    let fold_pred f g i a =+      fold_vertex+	(fun j a -> if Bitv.unsafe_get g.(j) i then f j a else a)+	g a+	+    (* degree *)+    let out_degree g i = fold_succ (fun _ n -> n + 1) g i 0+			   +    let in_degree g i = fold_pred (fun _ n -> n + 1) g i 0+			  +    (* map iterator on vertex *)+    let map_vertex f g =+      let n = nb_vertex g in+      let g' = make n in+      iter_edges+	(fun i j -> +	   let fi = f i in+	   let fj = f j in+	   if fi < 0 || fi >= n || fj < 0 || fj >= n then +	     invalid_arg "map_vertex";+	   Bitv.unsafe_set g'.(fi) fj true)+	g;+      g'++    (* labeled edges going from/to a vertex *)+    (* successors and predecessors of a vertex *)+    let succ_e g i = +      Bitv.foldi_left (fun l j b -> if b then (i,j)::l else l) [] g.(i)++    let pred_e g i = +      fold_vertex+	(fun j a -> if Bitv.unsafe_get g.(j) i then (j,i) :: a else a)+	g []+	+    (* iter/fold on all labeled edges of a graph *)+    let iter_edges_e f g =+      for i = 0 to nb_vertex g - 1 do +	Bitv.iteri (fun j b -> if b then f (i,j)) g.(i)+      done++    let fold_edges_e f g a =+      fold_vertex+	(fun i a -> +	   Bitv.foldi_right (fun j b a -> if b then f (i,j) a else a) g.(i) a)+	g a++    (* iter/fold on all edges going from/to a vertex *)+    let iter_succ_e f g i =+      let si = g.(i) in+      for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get si j then f (i,j) done+      +    let iter_pred_e f g i =+      for j = 0 to nb_vertex g - 1 do +	if Bitv.unsafe_get g.(j) i then f (j,i) +      done++    let fold_succ_e f g i a =+      Bitv.foldi_right (fun j b a -> if b then f (i,j) a else a) g.(i) a++    let fold_pred_e f g i a =+      fold_vertex+	(fun j a -> if Bitv.unsafe_get g.(j) i then f (j,i) a else a)+	g a++  end++  module Graph = struct++    module G = Digraph ++    include Blocks.Graph(G)		 +    (* Export some definitions of [G] *)++    let create = G.create+    let make = G.make+    let copy = G.copy+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge g v1 v2 = +      G.add_edge g v1 v2;+      ignore (G.unsafe_add_edge g v2 v1)++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_edge g v1 v2 =+      G.remove_edge g v1 v2;+      ignore (G.unsafe_remove_edge g v2 v1)++    let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  end++end+
+ external/ocamlgraph/src/imperative.mli view
@@ -0,0 +1,87 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: imperative.mli,v 1.18 2006-05-12 14:07:16 filliatr Exp $ *)++(** Imperative Implementations *)++open Sig++(** Signature of imperative graphs *)+module type S = sig++  (** Imperative Unlabeled Graphs *)+  module Concrete (V: COMPARABLE) : +    Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t++  (** Abstract Imperative Unlabeled Graphs *)+  module Abstract(V: ANY_TYPE) : +    Sig.IM with type V.label = V.t and type E.label = unit++  (** Imperative Labeled Graphs *)+  module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :+    Sig.I with type V.t = V.t and type V.label = V.t +	    and type E.t = V.t * E.t * V.t and type E.label = E.t++  (** Abstract Imperative Labeled Graphs *)+  module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :+    Sig.IM with type V.label = V.t and type E.label = E.t++end++(** Imperative Directed Graphs *)++module Digraph : sig +  include S   ++  (** Imperative Unlabeled, bidirectional graph (gives predecessors in+      constant time) *)+  module ConcreteBidirectional (V: COMPARABLE) : +    Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t +end++(** Imperative Undirected Graphs *)+module Graph : S++(** Imperative graphs implemented as adjacency matrices *)+module Matrix : sig++  module type S = sig++    (** Vertices are integers in [0..n-1]. +        A vertex label is the vertex itself. +        Edges are unlabeled. *)++    include Sig.I with type V.t = int and type V.label = int+		  and type E.t = int * int++    (** Creation. graphs are not resizeable: size is given at creation time.+        Thus [make] must be used instead of [create] *)+    val make : int -> t++    (** Note: [add_vertex] and [remove_vertex] have no effect *)++  end++  module Digraph : S+    (** Imperative Directed Graphs implemented with adjacency matrices *)++  module Graph : S+    (** Imperative Undirected Graphs implemented with adjacency matrices *)++end+
+ external/ocamlgraph/src/kruskal.ml view
@@ -0,0 +1,74 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: kruskal.ml,v 1.5 2005-06-30 10:48:55 filliatr Exp $ *)++open Util++module type UNIONFIND = sig+  type elt+  type t+    +  val init : elt list -> t+  val find : elt -> t -> elt+  val union : elt -> elt -> t -> unit+end++module type G = sig+  type t +  module V : Sig.COMPARABLE +  module E : sig +    type t +    type label +    val label : t -> label +    val dst : t -> V.t +    val src : t -> V.t+  end +  val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a+  val iter_edges_e : (E.t -> unit) -> t ->  unit+end++module Generic+  (G: G)+  (W : Sig.ORDERED_TYPE with type t=G.E.label)+  (UF: UNIONFIND with type elt=G.V.t) =+struct+    +  let spanningtree g =   +    let vertices = G.fold_vertex (fun v a -> v :: a) g [] in+    let uf = UF.init vertices in+    let edges = +      let l = ref [] in+      G.iter_edges_e (fun e -> l:=e::!l) g;+      List.sort (fun e e'-> W.compare (G.E.label e) (G.E.label e')) !l+    in+    let s = ref [] in+    let cover e =+      let u,v = G.E.src e , G.E.dst e in+      if G.V.compare (UF.find u uf) (UF.find v uf) <> 0 then+	(UF.union u v uf; s:=e::!s)+    in+    List.iter cover edges;!s++end++module Make+  (G: G)+  (W : Sig.ORDERED_TYPE with type t=G.E.label)+  = +  Generic(G)(W)(Unionfind.Make(G.V))+
+ external/ocamlgraph/src/kruskal.mli view
@@ -0,0 +1,65 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: kruskal.mli,v 1.5 2005-06-30 10:48:55 filliatr Exp $ *)++(** Kruskal's algorithm *)++(** Minimal graph signature for Kruskal *)+module type G = sig+  type t +  module V : Sig.COMPARABLE +  module E : sig +    type t +    type label +    val label : t -> label +    val dst : t -> V.t +    val src : t -> V.t+  end +  val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a+  val iter_edges_e : (E.t -> unit) -> t ->  unit+end++module Make+  (G: G)+  (W: Sig.ORDERED_TYPE with type t = G.E.label) :+sig+    +  val spanningtree : G.t -> G.E.t list++end  ++(** Generic version where union-find implementation is provided *)++module type UNIONFIND = sig+  type elt+  type t+    +  val init : elt list -> t+  val find : elt -> t -> elt+  val union : elt -> elt -> t -> unit+end++module Generic+  (G: G)+  (W: Sig.ORDERED_TYPE with type t=G.E.label)+  (UF: UNIONFIND with type elt=G.V.t) : +sig+    +  val spanningtree : G.t -> G.E.t list++end  
+ external/ocamlgraph/src/mcs_m.ml view
@@ -0,0 +1,203 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(**+  Maximal Cardinality Search (MCS-M).+  +  Based on the article:+  Maximal Cardinality Search for Computing Minimal Triangulations of Graphs.+  by A. Berry, Jean R. S. Blair, Pinar Heggernes & Barry W. Peyton.+  +  @author Matthieu Sozeau <mattam\@mattam.org>+  @author Pierre-Loic Garoche <ploc\@garoche.net>+  +  $Id: mcs_m.ml,v 1.5 2005-11-02 13:43:35 filliatr Exp $+*)+       +module MaximalCardinalitySearch = struct++  module WeightedV(V : Sig.COMPARABLE) = struct+    include Util.DataV(struct type t = int end)(V)+    let weight = data+    let set_weight = set_data+  end++  module P(Gr : Sig.P) = struct+    type edgelist = (Gr.V.t * Gr.V.t) list++    module NewV = WeightedV(Gr.V)+    module G = Persistent.Graph.Concrete(NewV)+    module EdgeSet = Set.Make(G.E)+    module VerticesSet = Set.Make(NewV)+    module Choose = Oper.Choose(G)+    module H = Hashtbl.Make(NewV)+      +    exception Found+      +    let check_path g u v =+      let h = H.create 97 in+      let maxw = NewV.weight u in+      let rec aux x : bool = +	if H.mem h x then+	  false+	else +	  if x = v then true+	  else+	    if NewV.weight x < maxw || x = u then+	      begin+		H.add h x ();+		G.fold_succ +		  (fun x found -> +		     if not found then aux x+		     else found)+		  g x false+	      end+	    else (H.add h x (); false)+      in aux u+	   +    module Copy = Gmap.Vertex(Gr)(struct include G include Builder.P(G) end)++    let fold f d =+      let rec aux = function+	  (true, a) -> aux (f a)+	| (false, a) -> a+      in aux d+	   +    let mcsm g =+      let g' = Copy.map (NewV.create 0) g in+      let (_, _, ord, triang) =+	fold +	  (fun ((i, g', a, f) as x)->+	     if i = 0 then (false, x)+	     else+	       let v =+		 G.fold_vertex+		   (fun x max -> +		      if NewV.weight x > NewV.weight max then x else max)+		   g' (ref 0, snd (Choose.choose_vertex g'))+	       in+	       let s =+		 G.fold_vertex+		   (fun x s ->+		      if x = v then s+		      else +			if check_path g' x v then+			  VerticesSet.add x s+			else s)+		   g' VerticesSet.empty+	       in+	       let f' = +		 VerticesSet.fold+		   (fun x f ->+		      NewV.set_weight x (succ (NewV.weight x));+		      if not (G.mem_edge g' x v) then+			EdgeSet.add (x,v) f+		      else f)+		   s f+	       in+	       let g' = G.remove_vertex g' v in+	       let a' = (i, NewV.label v) :: a in+		 (true, (i - 1, g', a', f')))+	  (true, (Gr.nb_vertex g, g', [], EdgeSet.empty))+      in+      (List.rev ord, +       EdgeSet.fold +	 (fun (x, y) e -> (NewV.label x, NewV.label y) :: e)+	 triang [])+	  +    let triangulate g =+      let (_, triang) = mcsm g in+      List.fold_left (fun g (x, y) -> Gr.add_edge g x y) g triang+  end++  module I(Gr : Sig.I) = struct+    type edgelist = (Gr.V.t * Gr.V.t) list	  ++    module NewV = WeightedV(Gr.V)+    module G = Imperative.Graph.Concrete(NewV)+    module EdgeSet = Set.Make(G.E)+    module VerticesSet = Set.Make(NewV)+    module Choose = Oper.Choose(G)+    module H = Hashtbl.Make(NewV)+      +    exception Found+      +    let check_path g u v =+      let h = H.create 97 in+      let maxw = NewV.weight u in+      let rec aux x : bool = +	if H.mem h x then+	  false+	else +	  if x = v then true+	  else+	    if NewV.weight x < maxw || x = u then begin+	      H.add h x ();+	      G.fold_succ +		(fun x found -> +		   if not found then aux x+		   else found)+		g x false+	    end else (H.add h x (); false)+      in aux u+	   +    module Copy = Gmap.Vertex(Gr)(struct include G include Builder.I(G) end)+      +    let mcsm g =+      let f = ref EdgeSet.empty+      and a = ref []+      and g' = Copy.map (NewV.create 0) g in+      for i = Gr.nb_vertex g downto 1 do+	let v =+	  G.fold_vertex+	    (fun x max -> +	       if NewV.weight x > NewV.weight max then x else max)+	    g' (ref 0, snd (Choose.choose_vertex g'))+	in+	let s =+	  G.fold_vertex+	    (fun x s ->+	       if x = v then s+	       else +		 if check_path g' x v then+		   VerticesSet.add x s+		 else s)+	    g' VerticesSet.empty+	in+	let f' = +	  VerticesSet.fold+	    (fun x f ->+	       NewV.set_weight x (succ (NewV.weight x));+	       if not (G.mem_edge g' x v) then+		 EdgeSet.add (x,v) f+	       else f)+	    s !f+	in+	f := f';+	G.remove_vertex g' v;+	a := (i, NewV.label v) :: !a;+      done;+      (List.rev !a, +       EdgeSet.fold +	 (fun (x, y) e -> (NewV.label x, NewV.label y) :: e)+	 !f [])+	  +    let triangulate g =+      let (_, triang) = mcsm g in+      List.iter (fun (x, y) -> Gr.add_edge g x y) triang+  end+end
+ external/ocamlgraph/src/mcs_m.mli view
@@ -0,0 +1,53 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(**+  Maximal Cardinality Search (MCS-M) algorithm+  +  Based on the article:+  Maximal Cardinality Search for Computing Minimal Triangulations of Graphs.+  by A. Berry, Jean R. S. Blair, Pinar Heggernes & Barry W. Peyton.+  +  @author Matthieu Sozeau+  @author Pierre-Loic Garoche+  +  $Id: mcs_m.mli,v 1.2 2004-10-19 15:21:44 signoles Exp $+*)++module MaximalCardinalitySearch : sig+  module P(G : Sig.P) : sig+    type edgelist = (G.V.t * G.V.t) list	  +	+    (** [mcsm g] returns a tuple [(o, e)] where [o] is a perfect elimination+      order of [g'] where [g'] is the triangulation [e] applied to [g]. *)+    val mcsm : G.t -> (int * G.V.t) list * edgelist++    (** [triangulate g] computes a triangulation of [g]+      using the MCS-M algorithm *)+    val triangulate : G.t -> G.t+  end+  module I(Gr : Sig.I) : sig+    type edgelist = (Gr.V.t * Gr.V.t) list	  +          +    (** [mcsm g] return a tuple [(o, e)] where o is a perfect elimination order+      of [g'] where [g'] is the triangulation [e] applied to [g]. *) +    val mcsm : Gr.t -> (int * Gr.V.t) list * edgelist+          +    (** [triangulate g] triangulates [g] using the MCS-M algorithm *)+    val triangulate : Gr.t -> unit+  end+end
+ external/ocamlgraph/src/md.ml view
@@ -0,0 +1,163 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: md.ml,v 1.6 2004-10-22 14:42:06 signoles Exp $ *)++(** Minimum Degree.+  +  Based on the article:+  The Minimum Degree Heuristic and the Minimal Triangulation Process+  by A. Berry, Pinar Heggernes & Geneviève Simonet.+  +  @author Matthieu Sozeau+  @author Pierre-Loic Garoche *)+  +module P(G : Sig.P) = struct++  module VertexSet = Set.Make(G.V)+  module CT = Cliquetree.CliqueTree(G)++  module Choose = Oper.Choose(G)+(*  module NG = Neighborhood.Graph(G)*)++  type edgeset = (G.V.t * G.V.t) list+      +  let md g =+    let gref = ref g in+    let gtri = ref g in+    let n = G.nb_vertex g in+    let tri = ref [] in+    let ord = ref [] in+    let i = ref 0 in+    while not (CT.is_chordal !gtri) && !i < n do+      let v = +	let x = +	  G.fold_vertex +	    (fun v' x ->+	       let deg' = G.out_degree !gref v' in+	       match x with+		   Some (v,deg) when deg' > deg -> x+		 | _ -> Some (v', deg'))+	    !gref None+	in match x with +	    Some (v,_) -> v+	  | None -> failwith "Expecting some vertex"+      in+      let ng = G.succ !gref v in+      let g', tri' =+	List.fold_left+	  (fun (g, tri) v ->+	     let tri' =+	       List.fold_left+		 (fun tri v' ->+		    if v <> v' && not (G.mem_edge g v v') then+		      (v, v') :: tri+		    else tri)+		 tri ng+	     in+	     let g' = +	       List.fold_left+		 (fun g v' ->+		    if v <> v' then+		      G.add_edge g v v'+		    else g)+		 g ng+	     in +	     (g', tri'))+	  (!gref, []) ng +      in+      ord := v :: !ord;+      gtri := List.fold_left +	(fun g (x,y) -> G.add_edge g x y) +	!gtri tri';+      gref := G.remove_vertex g' v;+      tri := tri' @ !tri;+      incr i;+    done;+    (!gtri, !tri, !ord)+	  +  let triangulate g = +    let gtri, _, _ = md g in +    gtri++end++module I(G : Sig.I) = struct++  module VertexSet = Set.Make(G.V)   +  module CT = Cliquetree.CliqueTree(G)++  module Choose = Oper.Choose(G)+(*  module NG = Neighborhood.Graph(G)*)+            +  type edgeset = (G.V.t * G.V.t) list+      +  module Copy = Gmap.Vertex(G)(struct include G include Builder.I(G) end)++  let md g =+    let gtri = Copy.map (fun x -> x) g in+    let gcur = Copy.map (fun x -> x) g in+    let n = G.nb_vertex g in+    let tri = ref [] in+    let ord = ref [] in+    let i = ref 0 in+    while not (CT.is_chordal gtri) && !i < n do+      let v = +	let x = +	  G.fold_vertex +	    (fun v' x ->+	       let deg' = G.out_degree gcur v' in+	       match x with+		   Some (v,deg) when deg' > deg -> x+		 | _ -> Some (v', deg'))+	    gcur None+	in match x with +	    Some (v,_) -> v+	  | None -> failwith "Expecting some vertex"+      in+      let ng = G.succ gcur v in+      let tri' =+	List.fold_left+	  (fun tri v ->+	     List.fold_left+	     (fun tri v' ->+		let tri' =+		  if v <> v' && not (G.mem_edge g v v') then+		    (v, v') :: tri+		  else +		    tri+		in+		List.iter (fun v' -> if v <> v' then G.add_edge gcur v v') ng;+		tri')+	     tri ng)+	  [] ng+      in+      ord := v :: !ord;+      List.iter+	(fun (x,y) -> G.add_edge gtri x y) +	tri';+      G.remove_vertex gcur v;+      tri := tri' @ !tri;+      incr i;+    done;+    (gtri, !tri, !ord)+	  +  let triangulate g = +    let gtri, _, _ = md g in +    gtri++end
+ external/ocamlgraph/src/md.mli view
@@ -0,0 +1,57 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: md.mli,v 1.2 2004-06-28 13:48:25 signoles Exp $ *)++(** Minimum Degree algorithm+  +  Based on the article:+  The Minimum Degree Heuristic and the Minimal Triangulation Process+  by A. Berry, Pinar Heggernes & Geneviève Simonet.+  +  @author Matthieu Sozeau+  @author Pierre-Loic Garoche *)++module P(G : Sig.P) : sig++  type edgeset = (G.V.t * G.V.t) list++  val md : G.t -> G.t * edgeset * G.V.t list+    (** [md g] return a tuple [(g', e, o)] where [g'] is +      a triangulated graph, [e] is the triangulation of [g] and+      [o] is a perfect elimination order of [g'] *)++  val triangulate : G.t -> G.t+    (** [triangulate g] return the graph [g'] produced by applying +      miminum degree to [g]. *)++end++module I(G : Sig.I) : sig+  +  type edgeset = (G.V.t * G.V.t) list+	+  val md : G.t -> G.t * edgeset * G.V.t list+    (** [md g] return a tuple [(g', e, o)] where [g'] is +      a triangulated graph, [e] is the triangulation of [g] and+      [o] is a perfect elimination order of [g'] *)++  val triangulate : G.t -> G.t+    (** [triangulate g] return the graph [g'] produced by applying +      miminum degree to [g]. *)++end
+ external/ocamlgraph/src/minsep.ml view
@@ -0,0 +1,131 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*i $Id: minsep.ml,v 1.7 2004-10-25 15:46:16 signoles Exp $ i*)++module type G = sig+  type t+  module V : Sig.COMPARABLE+  val succ: t -> V.t -> V.t list+  val iter_succ: (V.t -> unit) -> t -> V.t -> unit+  val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val iter_vertex: (V.t -> unit) -> t -> unit+  val fold_vertex: (V.t -> 'a -> 'a) -> t -> 'a -> 'a+end++module type MINSEP = sig+  module G : G+  module Vertex_Set : Set.S with type elt = G.V.t+  module VSetset : Set.S with type elt = Vertex_Set.t+  val allminsep : G.t -> Vertex_Set.t list+  val list_of_allminsep : G.t -> G.V.t list list+  val set_of_allminsep : G.t -> VSetset.t+end++module Make+  (G : sig +     include G+     val cc: t -> V.t list -> V.t list list +       (** compute the set of connected components of G(V \ l) *)+   end) =+struct++  module N = Oper.Neighbourhood(G)+  module Vertex_Set = N.Vertex_Set+  module VSetset = Set.Make(Vertex_Set)++  let initialisation g =+    let cc = G.cc g in+    let neighbourhood = N.list_from_vertex g in+    let neighbourhoods = N.set_from_vertices g in+    G.fold_vertex+      (fun v s -> +	 List.fold_left +	   (fun s l -> neighbourhoods l :: s)+	   s (cc (v :: neighbourhood v)))+      g []++  let generation g =+    let neighbourhood = N.list_from_vertex g in+    let neighbourhoods = N.set_from_vertices g in+    let cc = G.cc g in+    let rec gen_aux seen bigs = function+      | [] -> bigs+      | s :: tl ->+	  let l = Vertex_Set.elements s in+	  let seen = VSetset.add s seen in+	  let bigs, tl =+	    Vertex_Set.fold +	      (fun v c ->+		 let add_neighbourhoods (bigs, tl) l = +		   let s = neighbourhoods l in+		   s :: bigs, if VSetset.mem s seen then tl else s :: tl+		 in+		 List.fold_left +		   add_neighbourhoods+		   (bigs, tl) (cc (l @ neighbourhood v)))+	      s (bigs, tl)+	  in+	  gen_aux seen bigs tl+    in+    fun bigs -> gen_aux VSetset.empty bigs bigs++  let allminsep g = generation g (initialisation g)++  let set_of_allminsep g = +    List.fold_left +      (fun bigs s -> VSetset.add s bigs) VSetset.empty (allminsep g)++  let list_of_allminsep g = List.map Vertex_Set.elements (allminsep g)++end++module P(G : sig include G val remove_vertex : t -> V.t -> t end) = struct+  module G = G+  include Make(struct+		 include G+		 let cc =+		   let module CC = Components.Make(G) in+		   fun g l ->+		     let g = List.fold_left remove_vertex g l in+		     CC.scc_list g+	       end)+end++module I(G : sig +	   include G +	   module Mark : Sig.MARK with type graph = t and type vertex = V.t +	 end) =  +struct+  module G = G+  include Make(struct+		 include G+		 let cc = +		   let module CC = +		     Components.Make+		       (struct +			  include G +			  let iter_vertex f = +			    iter_vertex (fun v -> if Mark.get v=0 then f v)+			end) +		   in+		   fun g l ->+		     G.Mark.clear g;+		     List.iter (fun v -> G.Mark.set v 1) l;+		     CC.scc_list g+	       end)+end
+ external/ocamlgraph/src/minsep.mli view
@@ -0,0 +1,70 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*i $Id: minsep.mli,v 1.4 2004-10-22 16:31:03 conchon Exp $ i*)++(**+  Minimal separators of a graph+  +  Based on the article:+  Generating all the minimal separators of a graph.+  by A. Berry, J.-P. Bordat and O.Cogis+  http://www.isima.fr/berry/generating.html+  +  A set [S] of vertices is a minimal separator if it exists 2 distinct+  connected components [C] and [D] in [G \ S] such that each vertex of [S] has+  a successor in [C] and [D]. *)++(** Minimal signature for computing the minimal separators *)+module type G = sig+  type t+  module V : Sig.COMPARABLE+  val succ: t -> V.t -> V.t list+  val iter_succ: (V.t -> unit) -> t -> V.t -> unit+  val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val iter_vertex: (V.t -> unit) -> t -> unit+  val fold_vertex: (V.t -> 'a -> 'a) -> t -> 'a -> 'a+end++module type MINSEP = sig+  module G : G+    (** Implementation of a graph *)+  module Vertex_Set : Set.S with type elt = G.V.t+    (** Implementation of a set of vertex *)+  module VSetset : Set.S with type elt = Vertex_Set.t+    (** Implementation of a set of [Vertex_Set] *)++  val allminsep : G.t -> Vertex_Set.t list+    (** [allminsep g] computes the list of all minimal separators of g. *)+  val list_of_allminsep : G.t -> G.V.t list list+    (** Less efficient that [allminsep] *)+  val set_of_allminsep : G.t -> VSetset.t+    (** Less efficient that [allminsep] *)+end++(** Implementation for a persistent graph *)+module P(G : sig include G val remove_vertex : t -> V.t -> t end) : +  MINSEP with module G = G++(** Implementation for an imperative graph.+  Less efficient that the implementation for a persistent graph *)+module I(G : sig +	   include G +	   module Mark : Sig.MARK with type graph = t and type vertex = V.t+	 end) : +  MINSEP with module G = G+
+ external/ocamlgraph/src/oper.ml view
@@ -0,0 +1,171 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: oper.ml,v 1.13 2005-06-30 10:48:55 filliatr Exp $ *)++(* Basic operations over graphs *)++module type S = sig+  type g+  val transitive_closure : ?reflexive:bool -> g -> g+  val add_transitive_closure : ?reflexive:bool -> g -> g+  val mirror : g -> g+  val complement : g -> g+  val intersect : g -> g -> g+  val union : g -> g -> g+end++module Make(B : Builder.S) = struct++  open B++  (* Roy-Warshall's algorithm *)++  type g = G.t++  let add_transitive_closure ?(reflexive=false) g0 =+    let phi v g =+      let g = if reflexive then B.add_edge g v v else g in+      G.fold_succ+	(fun sv g -> G.fold_pred (fun pv g -> B.add_edge g pv sv) g v g) +	g v g+    in+    G.fold_vertex phi g0 g0++  let transitive_closure ?(reflexive=false) g0 = +    add_transitive_closure ~reflexive (B.copy g0)++  module H = Hashtbl.Make(G.V)++  let mirror g =+    if G.is_directed then begin+      let g' = B.empty () in+        G.fold_edges_e+	  (fun e g' -> +	     let v1 = (G.E.src e) in+	     let v2 = (G.E.dst e) in+	     B.add_edge_e g' (G.E.create v2 (G.E.label e) v1))+	  g g'+    end else+      B.copy g++  let complement g =+    G.fold_vertex+      (fun v g' ->+	 G.fold_vertex+	   (fun w g' ->+	      if G.mem_edge g v w then g'+	      else B.add_edge g' v w)+	 g g')+      g (B.empty ())++  let intersect g1 g2 = +    G.fold_vertex+      (fun v g ->+	 try+	   let succ = G.succ_e g2 v in+	   G.fold_succ_e +	     (fun e g -> +		if List.mem e succ +		then B.add_edge_e g e +		else B.add_vertex g (G.E.dst e))+	     g1 v (B.add_vertex g v)+	 with Invalid_argument _ -> +	   (* $v \notin g2$ *)+	   g)+      g1 (B.empty ())++  let union g1 g2 =+    let add g1 g2 = +      (* add the graph [g1] in [g2] *)+      G.fold_vertex +	(fun v g -> +	   G.fold_succ_e (fun e g -> B.add_edge_e g e) g1 v (B.add_vertex g v))+	g1 g2+    in+    add g1 (B.copy g2)++end++module P(G : Sig.P) = Make(Builder.P(G))+module I(G : Sig.I) = Make(Builder.I(G))++module Choose(G : sig+		type t +		type vertex +		type edge +		val iter_vertex : (vertex -> unit) -> t -> unit+		val iter_edges_e : (edge -> unit) -> t -> unit+	      end) =+struct++  exception Found_Vertex of G.vertex+  let choose_vertex g = +    try+      G.iter_vertex (fun v -> raise (Found_Vertex v)) g;+      invalid_arg "choose_vertex"+    with Found_Vertex v ->+      v++  exception Found_Edge of G.edge+  let choose_edge g =+    try+      G.iter_edges_e (fun v -> raise (Found_Edge v)) g;+      invalid_arg "choose_vertex"+    with Found_Edge v ->+      v++end++module Neighbourhood(G : sig +		      type t +		      module V : Sig.COMPARABLE+		      val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+		      val succ: t -> V.t -> V.t list+		    end) =+struct++  module Vertex_Set = Set.Make(G.V)++  let set_from_vertex g v =+    G.fold_succ +      (fun v' s -> if G.V.equal v v' then s else Vertex_Set.add v' s) +      g v Vertex_Set.empty ++  let list_from_vertex g v =+    let rec aux = function+      | [] -> []+      | v' :: l ->+	  if G.V.equal v v' then begin+	    assert (not (List.exists (G.V.equal v) l));+	    l+	  end else+	    v' :: aux l+    in+    aux (G.succ g v)++  let set_from_vertices g l =+    let fold_left f = List.fold_left f Vertex_Set.empty l in+    let env_init = fold_left (fun s v -> Vertex_Set.add v s) in+    let add x s = +      if Vertex_Set.mem x env_init then s else Vertex_Set.add x s +    in+    fold_left (fun s v -> G.fold_succ add g v s)++  let list_from_vertices g l = Vertex_Set.elements (set_from_vertices g l)++end
+ external/ocamlgraph/src/oper.mli view
@@ -0,0 +1,124 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: oper.mli,v 1.15 2005-01-18 16:40:14 signoles Exp $ *)++(** Basic operations over graphs *)++(** {1 Basic operations over graphs} *)++module type S = sig++  type g++  val transitive_closure : ?reflexive:bool -> g -> g+    (** [transitive_closure ?reflexive g] returns the transitive closure +      of [g] (as a new graph). Loops (i.e. edges from a vertex to itself) +      are added only if [reflexive] is [true] (default is [false]). *)++  val add_transitive_closure : ?reflexive:bool -> g -> g+    (** [add_transitive_closure ?reflexive g] replaces [g] by its+      transitive closure. Meaningless for persistent implementations+      (then acts as [transitive_closure]). *)++  val mirror : g -> g+    (** [mirror g] returns a new graph which is the mirror image of [g]:+      each edge from [u] to [v] has been replaced by an edge from [v] to [u].+      For undirected graphs, it simply returns a copy of [g]. *)++  val complement : g -> g+    (** [complement g] returns a new graph which is the complement of [g]:+      each edge present in [g] is not present in the resulting graph and+      vice-versa. Edges of the returned graph are unlabeled. *)++  val intersect : g -> g -> g+    (** [intersect g1 g2] returns a new graph which is the intersection of [g1]+      and [g2]: each vertex and edge present in [g1] *and* [g2] is present +      in the resulting graph. *)++  val union : g -> g -> g+    (** [union g1 g2] returns a new graph which is the union of [g1] and [g2]:+      each vertex and edge present in [g1] *or* [g2] is present in the +      resulting graph. *)+      +end++module Make(B : Builder.S) : S with type g = B.G.t+  (** Basic operations over graphs *)++module P(G : Sig.P) : S with type g = G.t+  (** Basic operations over persistent graphs *)++module I(G : Sig.I) : S with type g = G.t+  (** Basic operations over imperative graphs *)++(** {1 Choose} *)++(** Choose an element in a graph *)+module Choose(G : sig +		type t +		type vertex +		type edge +		val iter_vertex : (vertex -> unit) -> t -> unit+		val iter_edges_e : (edge -> unit) -> t -> unit+	      end) :+sig++  val choose_vertex : G.t -> G.vertex+    (** [choose_vertex g] returns a vertex from the graph.+      @raise Invalid_argument if the graph is empty. *)++  val choose_edge : G.t -> G.edge+    (** [choose_edge g] returns an edge from the graph.+      @raise Invalid_argument if the graph has no edge. *)++end++(** {1 Neighbourhood } *)++(** Neighbourhood of vertex / vertices *)+module Neighbourhood(G : sig +		      type t +		      module V : Sig.COMPARABLE+		      val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+		      val succ: t -> V.t -> V.t list+		    end) :+sig++  module Vertex_Set : Set.S with type elt = G.V.t++  (** The neighbourhood of a vertex [v] is +    \{ v' | (succ g v) and (v <> v') \} *)++  val list_from_vertex : G.t -> G.V.t -> G.V.t list+    (** Neighbourhood of a vertex as a list. *)++  val set_from_vertex : G.t -> G.V.t -> Vertex_Set.t+    (** Neighbourhood of a vertex as a set. +      Less efficient that [list_from_vertex]. *)++  (** The neighbourhood of a set [S] of vertices is [U \ S] where+    [U] is the union of neighbourhoods of each vertex of [S]. *)++  val list_from_vertices : G.t -> G.V.t list -> G.V.t list+    (** Neighbourhood of a list of vertices as a list. *)++  val set_from_vertices : G.t -> G.V.t list -> Vertex_Set.t+    (** Neighbourhood of a list of vertices as a set. +      More efficient that [list_from_vertices]. *)++end
+ external/ocamlgraph/src/pack.ml view
@@ -0,0 +1,180 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: pack.ml,v 1.13 2006-05-12 14:07:16 filliatr Exp $ *)++module Generic(G : Sig.IM with type V.label = int and type E.label = int) = +struct++  include G++  exception Found of V.t+  let find_vertex g i =+    try +      iter_vertex (fun v -> if V.label v = i then raise (Found v)) g;+      raise Not_found+    with Found v -> +      v++  module Builder = Builder.I(G)++  module Dfs = Traverse.Dfs(G)+  module Bfs = Traverse.Bfs(G)+  module Marking = Traverse.Mark(G)++  module Classic = Classic.I(G)++  module Rand = Rand.I(G)++  module Components = Components.Make(G)++  module W = struct +    type label = int+    type t = int+    let weight x = x+    let zero = 0+    let add = (+)+    let compare = compare+  end++  include Gpath.Dijkstra(G)(W)++  module F = struct+    type label = int+    type t = int+    let max_capacity x = x+    let min_capacity _ = 0+    let flow _ = 0+    let add = (+)+    let sub = (-)+    let compare = compare+    let max = max_int+    let min = 0+    let zero = 0+  end++  module FF = Flow.Ford_Fulkerson(G)(F)+  let ford_fulkerson g = +    if not G.is_directed then +      invalid_arg "ford_fulkerson: not a directed graph";+    FF.maxflow g++  module Goldberg = Flow.Goldberg(G)(F)+  let goldberg g = +    if not G.is_directed then invalid_arg "goldberg: not a directed graph";+    Goldberg.maxflow g++  include Oper.Make(Builder)++  module PathCheck = Gpath.Check(G)++  module Topological = Topological.Make(G)++  module Int = struct+    type t = int+    let compare = Pervasives.compare+  end++  include Kruskal.Make(G)(Int)++  module Display = struct+    include G+    let vertex_name v = string_of_int (V.label v)+    let graph_attributes _ = []+    let default_vertex_attributes _ = []+    let vertex_attributes _ = []+    let default_edge_attributes _ = []+    let edge_attributes _ = []+    let get_subgraph _ = None+  end+  module Dot_ = Graphviz.Dot(Display)+  module Neato = Graphviz.Neato(Display)++  let dot_output g f = +    let oc = open_out f in+    if is_directed then Dot_.output_graph oc g else Neato.output_graph oc g;+    close_out oc++  let display_with_gv g =+    let tmp = Filename.temp_file "graph" ".dot" in+    dot_output g tmp;+    ignore (Sys.command ("dot -Tps " ^ tmp ^ " | gv -"));+    Sys.remove tmp++  module GmlParser = +    Gml.Parse+      (Builder)+      (struct +	 let node l = +	   try match List.assoc "id" l with Gml.Int n -> n | _ -> -1+	   with Not_found -> -1+	 let edge _ =+	   0+       end)++  let parse_gml_file = GmlParser.parse++  module DotParser =+    Dot.Parse+      (Builder)+      (struct+ 	 let nodes = Hashtbl.create 97+	 let new_node = ref 0+	 let node (id,_) _ = +	   try +	     Hashtbl.find nodes id+	   with Not_found -> +	     incr new_node;+	     Hashtbl.add nodes id !new_node;+	     !new_node+	 let edge _ =+	   0+      end)++  let parse_dot_file = DotParser.parse++  open Format++  module GmlPrinter =+    Gml.Print+      (G)+      (struct+	 let node n = ["label", Gml.Int n]+	 let edge n = ["label", Gml.Int n]+       end)++  let print_gml_file g f =+    let c = open_out f in+    let fmt = formatter_of_out_channel c in+    fprintf fmt "%a@." GmlPrinter.print g;+    close_out c++end++module I = struct+  type t = int +  let compare = compare +  let hash = Hashtbl.hash +  let equal = (=)+  let default = 0+end++module Digraph = Generic(Imperative.Digraph.AbstractLabeled(I)(I))++module Graph = Generic(Imperative.Graph.AbstractLabeled(I)(I))++
+ external/ocamlgraph/src/pack.mli view
@@ -0,0 +1,28 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: pack.mli,v 1.1 2004-02-04 11:52:02 filliatr Exp $ *)++(** Immediate access to the library. *)++module Digraph : Sig_pack.S+  (** Directed graphs *)++module Graph : Sig_pack.S+  (** Undirected graphs *)++
+ external/ocamlgraph/src/persistent.ml view
@@ -0,0 +1,297 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: persistent.ml,v 1.18 2005-01-17 15:22:03 signoles Exp $ *)++open Sig+open Util+open Blocks++module type S = sig++  (** Persistent Unlabeled Graphs *)+  module Concrete (V: COMPARABLE) : +    Sig.P with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t++  (** Abstract Persistent Unlabeled Graphs *)+  module Abstract(V: sig type t end) : Sig.P with type V.label = V.t++  (** Persistent Labeled Graphs *)+  module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :+    Sig.P with type V.t = V.t and type V.label = V.t+	    and type E.t = V.t * E.t * V.t and type E.label = E.t++  (** Abstract Persistent Labeled Graphs *)+  module AbstractLabeled (V: sig type t end)(E: ORDERED_TYPE_DFT) :+    Sig.P with type V.label = V.t and type E.label = E.t++end++module P = Make(Make_Map)++type 'a abstract_vertex = { tag : int; label : 'a }++(* Vertex for the abstract persistent graphs. *)+module AbstractVertex(V: sig type t end) = struct++  type label = V.t+  type t = label abstract_vertex++  let compare x y = compare x.tag y.tag +  let hash x = Hashtbl.hash x.tag+  let equal x y = x.tag = y.tag+  let label x = x.label++  let create l = +    assert (!cpt_vertex < max_int);+    incr cpt_vertex;+    { tag = !cpt_vertex; label = l }+    +end++module Digraph = struct++  module Concrete = P.Digraph.Concrete++  module ConcreteLabeled(V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) = struct++    include P.Digraph.ConcreteLabeled(V)(Edge)++    let add_edge_e g (v1, l, v2) = +      let g = add_vertex g v1 in+      let g = add_vertex g v2 in+      unsafe_add_edge g v1 (v2, l)++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_vertex g v =+      if HM.mem v g then+	let remove v s =+	  S.fold +	    (fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)+	    s S.empty+	in+	let g = HM.remove v g in+	HM.fold (fun k s g -> HM.add k (remove v s) g) g HM.empty+      else+	g++  end++  module Abstract(V: sig type t end) = struct++    include P.Digraph.Abstract(AbstractVertex(V))++    let empty = { edges = G.empty; size = 0 }++    let add_vertex g v = +      if mem_vertex g v then +	g +      else+	{ edges = G.unsafe_add_vertex g.edges v; +	  size = Pervasives.succ g.size }++    let add_edge g v1 v2 = +      let g = add_vertex g v1 in+      let g = add_vertex g v2 in+      { g with edges = G.unsafe_add_edge g.edges v1 v2 }++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_vertex g v = +      if HM.mem v g.edges then+	let e = HM.remove v g.edges in+	let e = HM.fold (fun k s g -> HM.add k (S.remove v s) g) e HM.empty in+	{ edges = e; size = Pervasives.pred g.size }+      else+	g++    let remove_edge g v1 v2 = { g with edges = remove_edge g v1 v2 }+    let remove_edge_e g e = { g with edges = remove_edge_e g e }++  end++  module AbstractLabeled(V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct++    include P.Digraph.AbstractLabeled(AbstractVertex(V))(Edge)++    let empty = { edges = G.empty; size = 0 }++    let add_vertex g v = +      if mem_vertex g v then +	g +      else+	{ edges = G.unsafe_add_vertex g.edges v; +	  size = Pervasives.succ g.size }++    let add_edge_e g (v1, l, v2) = +      let g = add_vertex g v1 in+      let g = add_vertex g v2 in+      { g with edges = G.unsafe_add_edge g.edges v1 (v2, l) }++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_vertex g v =+      if HM.mem v g.edges then+	let remove v s =+	  S.fold +	    (fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)+	    s S.empty+	in+	let edges = HM.remove v g.edges in+	{ edges = +	    HM.fold (fun k s g -> HM.add k (remove v s) g) edges HM.empty;+	  size = Pervasives.pred g.size }+      else+	g++    let remove_edge g v1 v2 = { g with edges = remove_edge g v1 v2 }+    let remove_edge_e g e = { g with edges = remove_edge_e g e }++  end++end++module Graph = struct++  module Concrete(V: COMPARABLE) = struct++    module G = Digraph.Concrete(V) ++    include Graph(G)++    (* Export some definitions of [G] *)++    let empty = G.empty+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge g v1 v2 = +      let g = G.add_edge g v1 v2 in+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      G.unsafe_add_edge g v2 v1++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_edge g v1 v2 =+      let g = G.remove_edge g v1 v2 in+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      G.unsafe_remove_edge g v2 v1++    let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  end++  module ConcreteLabeled(V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) = struct++    module G = Digraph.ConcreteLabeled(V)(Edge)++    include Graph(G)++    (* Export some definitions of [G] *)++    let empty = G.empty+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge_e g (v1, l, v2 as e) = +      let g = G.add_edge_e g e in+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      G.unsafe_add_edge g v2 (v1, l)++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_edge g v1 v2 =+      let g = G.remove_edge g v1 v2 in+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      G.unsafe_remove_edge g v2 v1++    let remove_edge_e g (v1, l, v2 as e) =+      let g = G.remove_edge_e g e in+      assert (G.HM.mem v1 g && G.HM.mem v2 g);+      G.unsafe_remove_edge_e g (v2, l, v1)++  end++  module Abstract(V: sig type t end) = struct++    module G = Digraph.Abstract(V)++    include Graph(G)++    (* Export some definitions of [G] *)++    let empty = G.empty+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge g v1 v2 = +      let g = G.add_edge g v1 v2 in+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      { g with G.edges = G.unsafe_add_edge g.G.edges v2 v1 }++    let add_edge_e g (v1, v2) = add_edge g v1 v2++    let remove_edge g v1 v2 =+      let g = G.remove_edge g v1 v2 in+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      { g with G.edges = G.unsafe_remove_edge g.G.edges v2 v1 }++    let remove_edge_e g (v1, v2) = remove_edge g v1 v2++  end++  module AbstractLabeled (V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct++    module G = Digraph.AbstractLabeled(V)(Edge)++    include Graph(G)++    (* Export some definitions of [G] *)++    let empty = G.empty+    let add_vertex = G.add_vertex+    let remove_vertex = G.remove_vertex++    (* Redefine the [add_edge] and [remove_edge] operations *)++    let add_edge_e g (v1, l, v2 as e) = +      let g = G.add_edge_e g e in+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      { g with G.edges = G.unsafe_add_edge g.G.edges v2 (v1, l) }++    let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)++    let remove_edge g v1 v2 =+      let g = G.remove_edge g v1 v2 in+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      { g with G.edges = G.unsafe_remove_edge g.G.edges v2 v1 }++    let remove_edge_e g (v1, l, v2 as e) =+      let g = G.remove_edge_e g e in+      assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);+      { g with G.edges = G.unsafe_remove_edge_e g.G.edges (v2, l, v1) }++  end++end
+ external/ocamlgraph/src/persistent.mli view
@@ -0,0 +1,50 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: persistent.mli,v 1.13 2006-05-12 14:07:16 filliatr Exp $ *)++(** Persistent Implementations *)++open Sig++(** Signature of persistent graphs *)+module type S = sig++  (** Persistent Unlabeled Graphs *)+  module Concrete (V: COMPARABLE) : +    Sig.P with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t++  (** Abstract Persistent Unlabeled Graphs *)+  module Abstract(V: ANY_TYPE) : Sig.P with type V.label = V.t++  (** Persistent Labeled Graphs *)+  module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :+    Sig.P with type V.t = V.t and type V.label = V.t+	    and type E.t = V.t * E.t * V.t and type E.label = E.t++  (** Abstract Persistent Labeled Graphs *)+  module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :+    Sig.P with type V.label = V.t and type E.label = E.t++end++(** Persistent Directed Graphs *)+module Digraph : S++(** Persistent Undirected Graphs *)+module Graph : S+
+ external/ocamlgraph/src/rand.ml view
@@ -0,0 +1,207 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: rand.ml,v 1.18 2005-03-31 13:32:51 filliatr Exp $ *)++module type S = sig+  type graph +  type vertex+  type edge_label+  val graph : ?loops:bool -> v:int -> e:int -> unit -> graph+  val labeled : +    (vertex -> vertex -> edge_label) -> +    ?loops:bool -> v:int -> e:int -> unit -> graph+  (* DEBUG *)+  val random_few_edges : loops:bool -> v:int -> e:int -> graph+  val random_many_edges : loops:bool -> v:int -> e:int -> graph+end++module Make(B : Builder.INT) = struct++  open B+  type graph = G.t+  type vertex = G.V.t+  type edge_label = G.E.label++  open Int64++  let max_edges ~loops ~v ~e =+    if v <= 0 || e < 0 then invalid_arg "random";+    let v64 = of_int v in+    let max_e = mul v64 (pred v64) in+    let max_e = if G.is_directed then max_e else div max_e (of_int 2) in+    let max_e = if loops then add max_e v64 else max_e in+    if of_int e > max_e then invalid_arg "random: too many edges";+    max_e++  let fold_for i0 i1 f =+    let rec loop i v = if i > i1 then v else loop (i + 1) (f v i) in+    loop i0++  (* naive implementation: we randomly chose edges up to [e] different edges *)+  let random_few_edges add_edge ~loops ~v ~e =+    let _ = max_edges ~loops ~v ~e in+    let a = Array.init v G.V.create in+    let g = Array.fold_left add_vertex (empty ()) a in+    let rec random_edge g =+      let i = Random.int v in+      let j = Random.int v in+      if (i = j && not loops) || G.mem_edge g a.(i) a.(j) then +	random_edge g+      else+	add_edge g a.(i) a.(j)+    in+    fold_for 1 e (fun g _ -> random_edge g) g++  (* other implementation in O(v * v); faster when [e] is large *)+  let random_many_edges add_edge ~loops ~v ~e =+    let v64 = of_int v in+    let max_e = max_edges ~loops ~v ~e in+    let a = Array.init v G.V.create in+    let g = Array.fold_left add_vertex (empty ()) a in+    let rec add_edges i j max nb g =+      assert +	(max >= 0L &&+         max_e = +	   add max (add (mul (of_int i) v64) +           (of_int +  	    (j - +	    (match G.is_directed, loops with+	       | true, true -> 0+	       | true, false -> if j > i then i + 1 else i+	       | false, true -> i * (i - 1) / 2 + if j > i then i else j+	       | false, false -> i*(i+1)/2 + if j > i then i+1 else j)))));+      if nb = 0 then+	g+      else+	let add_edges = +	  let i, j = if j = v - 1 then i + 1, 0 else i, j + 1 in+	  add_edges i j +	in+	if (i = j && not loops) || (not G.is_directed && i > j) then +	  add_edges max nb g+	else+	  let add_edges = add_edges (pred max) in+	  if Random.int64 max < of_int nb then+	    add_edges (nb - 1) (add_edge g a.(i) a.(j))+	  else+	    add_edges nb g+    in+    add_edges 0 0 max_e e g++  let random ~loops ~v ~e = +    let r = float e /. (float v *. float v) in+    (if r < 0.4 then random_few_edges else random_many_edges) ~loops ~v ~e++  let graph ?(loops=false) ~v ~e () = random B.add_edge ~loops ~v ~e++  let labeled f ?(loops=false) ~v ~e () = +    random +      (fun g v1 v2 -> B.add_edge_e g (G.E.create v1 (f v1 v2) v2)) +      ~loops ~v ~e++  (* DEBUG *)+  let random_few_edges = random_few_edges B.add_edge+  let random_many_edges = random_many_edges B.add_edge++end++module P (G : Sig.P with type V.label = int) = Make(Builder.P(G))++module I (G : Sig.I with type V.label = int) = Make(Builder.I(G))+++(** Random planar graphs *)++module Planar = struct++  module type S = sig+    type graph +    val graph : +      ?loops:bool -> xrange:int*int -> yrange:int*int ->+	prob:float -> int -> graph+  end++  module Make+    (B : Builder.S with type G.V.label = int * int and type G.E.label = int) =+  struct++    type graph = B.G.t+    open B.G++    module Point = struct+      type point = V.t+      let ccw v1 v2 v3 = +	Delaunay.IntPoints.ccw (V.label v1) (V.label v2) (V.label v3)+      let in_circle v1 v2 v3 v4 =+	Delaunay.IntPoints.in_circle +	  (V.label v1) (V.label v2) (V.label v3) (V.label v4)+      let distance v1 v2 =+	let x1,y1 = V.label v1 in+	let x2,y2 = V.label v2 in+	let sqr x = let x = float x in x *. x in+	truncate (sqrt (sqr (x1 - x2) +. sqr (y1 - y2)))+    end++    module Triangulation = Delaunay.Make(Point)++    let graph ?(loops=false) ~xrange:(xmin,xmax) ~yrange:(ymin,ymax) ~prob v =+      if not (0.0 <= prob && prob <= 1.0) then invalid_arg "Planar.graph";+      if v < 2 then invalid_arg "Planar.graph";+      (* [v] random points and their Delaunay triangulation *)+      let random_point () =+	xmin + Random.int (1 + xmax - xmin),+	ymin + Random.int (1 + ymax - ymin)+      in+      let vertices = Array.init v (fun _ -> V.create (random_point ())) in+      let t = Triangulation.triangulate vertices in+      (* a graph with [v] vertices and random loops if any *)+      let g = Array.fold_left B.add_vertex (B.empty ()) vertices in+      let g = +	if loops then +	  Array.fold_left +	    (fun g v -> +	       if Random.float 1.0 < prob then +		 g+	       else+		 let e = E.create v 0 v in B.add_edge_e g e)+	    g vertices+	else +	  g+      in+      (* we keep some edges from the triangulation according to [prob] *)+      let add_edge v1 v2 g =+	if Random.float 1.0 < prob then +	  g+	else+	  let e = E.create v1 (Point.distance v1 v2) v2 in B.add_edge_e g e+      in+      Triangulation.fold+	(fun v1 v2 g -> +	   let g = add_edge v1 v2 g in+	   if is_directed then add_edge v2 v1 g else g)+	t g++  end++  module P (G : Sig.P with type V.label = int * int and type E.label = int) = +    Make(Builder.P(G))++  module I (G : Sig.I with type V.label = int * int and type E.label = int) = +    Make(Builder.I(G))++end
+ external/ocamlgraph/src/rand.mli view
@@ -0,0 +1,111 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: rand.mli,v 1.12 2005-03-31 13:32:51 filliatr Exp $ *)++(** Random graph generation *)++(** {1 Random graphs} *)++module type S = sig++  type graph +  type vertex+  type edge_label++  val graph : ?loops:bool -> v:int -> e:int -> unit -> graph+    (** [graph v e] generates a random graph with exactly [v] vertices +      and [e] edges. Vertices are labeled with [0] ... [v-1].+      The boolean [loops] indicates whether loops are allowed; +      default value is no loop ([false]). +      @raise Invalid_argument if [e] exceeds the maximal number of edges. *)++  val labeled : +    (vertex -> vertex -> edge_label) -> +    ?loops:bool -> v:int -> e:int -> unit -> graph+    (** [labeled f] is similar to [graph] except that edges are labeled+      using function [f].+      @raise Invalid_argument if there are too many edges. *)++  (** The two functions above actually make a choice between two+     different implementations according to the ratio e/(v*v).+     When this ratio is small, [random_few_edges] is selected; +     otherwise [random_many_edges] is selected. *)++  val random_few_edges : loops:bool -> v:int -> e:int -> graph+  val random_many_edges : loops:bool -> v:int -> e:int -> graph++end++module Make(B: Builder.INT) :+  S with type graph = B.G.t +    and type vertex = B.G.V.t +    and type edge_label = B.G.E.label+      (** Random graphs *)++module P (G : Sig.P with type V.label = int) : +  S with type graph = G.t +    and type vertex = G.V.t +    and type edge_label = G.E.label+      (** Random persistent graphs *)++module I (G : Sig.I with type V.label = int) : +  S with type graph = G.t+    and type vertex = G.V.t     +    and type edge_label = G.E.label+      (** Random imperative graphs *)++(** {1 Random planar graphs} *)++module Planar : sig++  module type S = sig++    type graph ++    val graph : +      ?loops:bool -> xrange:int*int -> yrange:int*int ->+	prob:float -> int -> graph+      (** [graph xrange yrange prob v] +        generates a random planar graph with exactly [v] vertices.+        Vertices are labeled with integer coordinates, randomly distributed+        according to [xrange] and [yrange].+        Edges are built as follows: the full Delaunay triangulation is+        constructed and then each edge is discarded with probabiblity [prob]+        (which should lie in [0..1]). In particular [prob = 0.0] gives the +        full triangulation.+        Edges are labeled with the (rounded) Euclidean distance between+        the two vertices.+        The boolean [loops] indicates whether loops are allowed; +        default value is no loop ([false]). *)++  end++  module Make+    (B : Builder.S with type G.V.label = int * int and type G.E.label = int) :+    S with type graph = B.G.t +	(** Random planar graphs *)++  module P (G : Sig.P with type V.label = int * int and type E.label = int) : +    S with type graph = G.t +	(** Random persistent planar graphs *)++  module I (G : Sig.I with type V.label = int * int and type E.label = int) : +    S with type graph = G.t+	(** Random imperative planar graphs *)+			      +end
+ external/ocamlgraph/src/sig.mli view
@@ -0,0 +1,309 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: sig.mli,v 1.21 2006-05-12 14:07:16 filliatr Exp $ *)++(** Signatures for graph implementations *)++(** {2 Signatures for graph implementations} *)++(** Interface for vertices *)++module type VERTEX = sig++  (** Vertices are [COMPARABLE] *)+  +  type t +  val compare : t -> t -> int +  val hash : t -> int +  val equal : t -> t -> bool+      +  (** Vertices are labeled. *)+      +  type label+  val create : label -> t+  val label : t -> label++end++(** Interface for edges *)++module type EDGE = sig++  (** Edges are [ORDERED]. *)++  type t+  val compare : t -> t -> int+      +  (** Edges are directed. *)++  type vertex+  val src : t -> vertex+  val dst : t -> vertex+      +  (** Edges are labeled. *)+      +  type label+  val create : vertex -> label -> vertex -> t+      (** [create v1 l v2] creates an edge from [v1] to [v2] with label [l] *)+  val label : t -> label++end++(** Common interface for all graph implementations *)++module type G = sig++  (** {2 Graph structure} *)++  (** Abstract type of graphs *)+  type t++  (** Vertices have type [V.t] and are labeled with type [V.label]+    (note that an implementation may identify the vertex with its+    label) *)+  module V : VERTEX++  type vertex = V.t++  (** Edges have type [E.t] and are labeled with type [E.label].+      [src] (resp. [dst]) returns the origin (resp. the destination) of a+      given edge. *)+  module E : EDGE with type vertex = vertex++  type edge = E.t++  (** Is this an implementation of directed graphs? *)+  val is_directed : bool++  (** {2 Size functions} *)++  val is_empty : t -> bool+  val nb_vertex : t -> int+  val nb_edges : t -> int++  (** Degree of a vertex *)++  val out_degree : t -> vertex -> int+    (** [out_degree g v] returns the out-degree of [v] in [g].+      @raise Invalid_argument if [v] is not in [g]. *)++  val in_degree : t -> vertex -> int+    (** [in_degree g v] returns the in-degree of [v] in [g].+      @raise Invalid_argument if [v] is not in [g]. *)++  (** {2 Membership functions} *)++  val mem_vertex : t -> vertex -> bool+  val mem_edge : t -> vertex -> vertex -> bool+  val mem_edge_e : t -> edge -> bool++  val find_edge : t -> vertex -> vertex -> edge+    (** [find_edge g v1 v2] returns the edge from [v1] to [v2] if it exists.+      The behaviour is unspecified if [g] has several edges from [v1] to [v2].+      @raise Not_found if no such edge exists. *)++  (** {2 Successors and predecessors} *)++  val succ : t -> vertex -> vertex list+    (** [succ g v] returns the successors of [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  val pred : t -> vertex -> vertex list+    (** [pred g v] returns the predecessors of [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  (** Labeled edges going from/to a vertex *)++  val succ_e : t -> vertex -> edge list+    (** [succ_e g v] returns the edges going from [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  val pred_e : t -> vertex -> edge list+    (** [pred_e g v] returns the edges going to [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  (** {2 Graph iterators} *)++  (** iter/fold on all vertices/edges of a graph *)++  val iter_vertex : (vertex -> unit) -> t -> unit+  val iter_edges : (vertex -> vertex -> unit) -> t -> unit+  val fold_vertex : (vertex -> 'a -> 'a) -> t  -> 'a -> 'a+  val fold_edges : (vertex -> vertex -> 'a -> 'a) -> t -> 'a -> 'a++  (** map iterator on vertex *)+  val map_vertex : (vertex -> vertex) -> t -> t++  (** iter/fold on all labeled edges of a graph *)++  val iter_edges_e : (edge -> unit) -> t -> unit+  val fold_edges_e : (edge -> 'a -> 'a) -> t -> 'a -> 'a++  (** {2 Vertex iterators} ++    Each iterator [iterator f v g] iters [f] to the successors/predecessors+    of [v] in the graph [g] and raises [Invalid_argument] if [v] is not in+    [g]. *)++  (** iter/fold on all successors/predecessors of a vertex. *)++  val iter_succ : (vertex -> unit) -> t -> vertex -> unit+  val iter_pred : (vertex -> unit) -> t -> vertex -> unit+  val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a+  val fold_pred : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a++  (** iter/fold on all edges going from/to a vertex. *)++  val iter_succ_e : (edge -> unit) -> t -> vertex -> unit+  val fold_succ_e : (edge -> 'a -> 'a) -> t -> vertex -> 'a -> 'a+  val iter_pred_e : (edge -> unit) -> t -> vertex -> unit+  val fold_pred_e : (edge -> 'a -> 'a) -> t -> vertex -> 'a -> 'a++end++(** Persistent (i.e. immutable) implementation *)++module type P = sig+  include G++  val empty : t+    (** The empty graph. *)++  val add_vertex : t -> vertex -> t+    (** [add_vertex g v] adds the vertex [v] from the graph [g].+      Just return [g] if [v] is already in [g]. *)++  val remove_vertex : t -> vertex -> t+    (** [remove g v] removes the vertex [v] from the graph [g] +      (and all the edges going from [v] in [g]).+      Just return [g] if [v] is not in [g]. *)++  val add_edge : t -> vertex -> vertex -> t+    (** [add_edge g v1 v2] adds an edge from the vertex [v1] to the vertex [v2]+      in the graph [g]. +      Add also [v1] (resp. [v2]) in [g] if [v1] (resp. [v2]) is not in [g]. +      Just return [g] if this edge is already in [g]. *) ++  val add_edge_e : t -> edge -> t+    (** [add_edge_e g e] adds the edge [e] in the graph [g].+      Add also [E.src e] (resp. [E.dst e]) in [g] if [E.src e] (resp. [E.dst+      e]) is not in [g]. +      Just return [g] if [e] is already in [g]. *)++  val remove_edge : t -> vertex -> vertex -> t+    (** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the+      graph [g]. If the graph is labelled, all the edges going from [v1] to+      [v2] are removed from [g].+      Just return [g] if this edge is not in [g].+      @raise Invalid_argument if [v1] or [v2] are not in [g]. *)++  val remove_edge_e : t -> edge -> t+    (** [remove_edge_e g e] removes the edge [e] from the graph [g].+      Just return [g] if [e] is not in [g]. +      @raise Invalid_argument if [E.src e] or [E.dst e] are not in [g]. *)++end++(** Imperative (i.e. mutable) implementation *)++module type I = sig+  include G++  val create : ?size:int -> unit -> t+    (** [create ()] returns an empty graph. Optionally, a size can be+        given, which should be on the order of the expected number of+        vertices that will be in the graph (for hash tables-based+        implementations).  The graph grows as needed, so [size] is+        just an initial guess. *)++  val copy : t -> t+    (** [copy g] returns a copy of [g]. Vertices and edges (and eventually+	marks, see module [Mark]) are duplicated. *)++  val add_vertex : t -> vertex -> unit+    (** [add_vertex g v] adds the vertex [v] from the graph [g].+      Do nothing if [v] is already in [g]. *)++  val remove_vertex : t -> vertex -> unit+    (** [remove g v] removes the vertex [v] from the graph [g] +      (and all the edges going from [v] in [g]).+      Do nothing if [v] is not in [g]. *)++  val add_edge : t -> vertex -> vertex -> unit+    (** [add_edge g v1 v2] adds an edge from the vertex [v1] to the vertex [v2]+      in the graph [g]. +      Add also [v1] (resp. [v2]) in [g] if [v1] (resp. [v2]) is not in [g]. +      Do nothing if this edge is already in [g]. *) ++  val add_edge_e : t -> edge -> unit+    (** [add_edge_e g e] adds the edge [e] in the graph [g].+      Add also [E.src e] (resp. [E.dst e]) in [g] if [E.src e] (resp. [E.dst+      e]) is not in [g]. +      Do nothing if [e] is already in [g]. *)++  val remove_edge : t -> vertex -> vertex -> unit+    (** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the+      graph [g]. If the graph is labelled, all the edges going from [v1] to+      [v2] are removed from [g].+      Do nothing if this edge is not in [g].+      @raise Invalid_argument if [v1] or [v2] are not in [g]. *)++  val remove_edge_e : t -> edge -> unit+    (** [remove_edge_e g e] removes the edge [e] from the graph [g].+      Do nothing if [e] is not in [g].+      @raise Invalid_argument if [E.src e] or [E.dst e] are not in [g]. *)++end++(** Imperative implementation with marks *)++module type MARK = sig+  type graph+  type vertex+  val clear : graph -> unit+      (** [clear g] sets all the marks to 0 for all the vertices of [g]. *)+  val get : vertex -> int+  val set : vertex -> int -> unit+end++module type IM = sig+  include I+  module Mark : MARK with type graph = t and type vertex = vertex+end++(** {2 Signature for ordered and hashable types} *)++module type ANY_TYPE = sig type t end++module type ORDERED_TYPE = sig type t val compare : t -> t -> int end++module type ORDERED_TYPE_DFT = sig include ORDERED_TYPE val default : t end++module type HASHABLE = sig+  type t +  val hash : t -> int +  val equal : t -> t -> bool+end++(** Comparable = Ordered + Hashable *)+module type COMPARABLE = sig +  type t +  val compare : t -> t -> int +  val hash : t -> int +  val equal : t -> t -> bool+end
+ external/ocamlgraph/src/sig_pack.mli view
@@ -0,0 +1,376 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: sig_pack.mli,v 1.23 2005-07-18 07:10:35 filliatr Exp $ *)++(** Immediate access to the library.+    Signature [S] gathers an imperative implementation and all algorithms into +    a single module. +    Vertices and edges are labeled with integers. *)++module type S = sig++  (** {2 Graph structure} *)++  (** abstract type of graphs *)+  type t++  (** Vertices *)+  module V : sig+    (** Vertices are [COMPARABLE] *)++    type t +    val compare : t -> t -> int +    val hash : t -> int +    val equal : t -> t -> bool++    (** vertices are labeled with integers *)++    type label = int+    val create : label -> t+    val label : t -> label+  end++  type vertex = V.t++  (** Edges *)+  module E : sig+    (** Edges are [ORDERED]. *)++    type t+    val compare : t -> t -> int++    (** Edges are directed. *)++    val src : t -> V.t+    val dst : t -> V.t++    (** Edges are labeled with integers. *)++    type label = int+    val create : V.t -> label -> V.t -> t+      (** [create v1 l v2] creates an edge from [v1] to [v2] with label [l] *)+    val label : t -> label++    type vertex = V.t+  end++  type edge = E.t++  (** is this an implementation of directed graphs? *)+  val is_directed : bool++  (** {2 Graph constructors and destructors} *)++  val create : ?size:int -> unit -> t+    (** Return an empty graph. Optionally, a size can be+        given, which should be on the order of the expected number of+        vertices that will be in the graph (for hash tables-based+        implementations).  The graph grows as needed, so [size] is+        just an initial guess. *)++  val copy : t -> t+    (** [copy g] returns a copy of [g]. Vertices and edges (and eventually+      marks, see module [Mark]) are duplicated. *)++  val add_vertex : t -> V.t -> unit+    (** [add_vertex g v] adds the vertex [v] from the graph [g].+      Do nothing if [v] is already in [g]. *)++  val remove_vertex : t -> V.t -> unit+    (** [remove g v] removes the vertex [v] from the graph [g] +      (and all the edges going from [v] in [g]).+      Do nothing if [v] is not in [g]. *)++  val add_edge : t -> V.t -> V.t -> unit+    (** [add_edge g v1 v2] adds an edge from the vertex [v1] to the vertex [v2]+      in the graph [g]. +      Add also [v1] (resp. [v2]) in [g] if [v1] (resp. [v2]) is not in [g]. +      Do nothing if this edge is already in [g]. *) ++  val add_edge_e : t -> E.t -> unit+    (** [add_edge_e g e] adds the edge [e] in the graph [g].+      Add also [E.src e] (resp. [E.dst e]) in [g] if [E.src e] (resp. [E.dst+      e]) is not in [g]. +      Do nothing if [e] is already in [g]. *)++  val remove_edge : t -> V.t -> V.t -> unit+    (** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the+      graph [g].+      Do nothing if this edge is not in [g].+      @raise Invalid_argument if [v1] or [v2] are not in [g]. *)++  val remove_edge_e : t -> E.t -> unit+    (** [remove_edge_e g e] removes the edge [e] from the graph [g].+      Do nothing if [e] is not in [g].+      @raise Invalid_argument if [E.src e] or [E.dst e] are not in [g]. *)++  (** Vertices contains integers marks, which can be set or used by some +      algorithms (see for instance module [Marking] below) *)+  module Mark : sig+    type graph = t+    type vertex = V.t+    val clear : t -> unit+      (** [clear g] sets all marks to 0 from all the vertives of [g]. *)+    val get : V.t -> int+    val set : V.t -> int -> unit+  end++  (** {2 Size functions} *)++  val is_empty : t -> bool+  val nb_vertex : t -> int+  val nb_edges : t -> int++  (** Degree of a vertex *)++  val out_degree : t -> V.t -> int+    (** [out_degree g v] returns the out-degree of [v] in [g].+      @raise Invalid_argument if [v] is not in [g]. *)++  val in_degree : t -> V.t -> int+    (** [in_degree g v] returns the in-degree of [v] in [g].+      @raise Invalid_argument if [v] is not in [g]. *)++  (** {2 Membership functions} *)++  val mem_vertex : t -> V.t -> bool+  val mem_edge : t -> V.t -> V.t -> bool+  val mem_edge_e : t -> E.t -> bool+  val find_edge : t -> V.t -> V.t -> E.t++  (** {2 Successors and predecessors of a vertex} *)++  val succ : t -> V.t -> V.t list+    (** [succ g v] returns the successors of [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  val pred : t -> V.t -> V.t list+    (** [pred g v] returns the predecessors of [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  (** Labeled edges going from/to a vertex *)++  val succ_e : t -> V.t -> E.t list+    (** [succ_e g v] returns the edges going from [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  val pred_e : t -> V.t -> E.t list+    (** [pred_e g v] returns the edges going to [v] in [g].+        @raise Invalid_argument if [v] is not in [g]. *)++  (** {2 Graph iterators} *)++  (** iter/fold on all vertices/edges of a graph *)++  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_edges : (V.t -> V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val fold_edges : (V.t -> V.t -> 'a -> 'a) -> t -> 'a -> 'a++  (** map iterator on vertex *)+  val map_vertex : (V.t -> V.t) -> t -> t++  (** iter/fold on all labeled edges of a graph *)++  val iter_edges_e : (E.t -> unit) -> t -> unit+  val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a++  (** {2 Vertex iterators}++    Each iterator [iterator f v g] iters [f] to the successors/predecessors+    of [v] in the graph [g] and raises [Invalid_argument] if [v] is not in+    [g]. *)++  (** iter/fold on all successors/predecessors of a vertex. *)++  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val iter_pred : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val fold_pred : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a++  (** iter/fold on all edges going from/to a vertex. *)++  val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit+  val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+  val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit+  val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a++  (** {2 Basic operations} *)++  val find_vertex : t -> int -> V.t+    (** [vertex g i] returns a vertex of label [i] in [g]. The behaviour is+      unspecified if [g] has several vertices with label [i]. +      Note: this function is inefficient (linear in the number of vertices);+      you should better keep the vertices as long as you create them. *)++  val transitive_closure : ?reflexive:bool -> t -> t+    (** [transitive_closure ?reflexive g] returns the transitive closure +      of [g] (as a new graph). Loops (i.e. edges from a vertex to itself) +      are added only if [reflexive] is [true] (default is [false]). *)++  val add_transitive_closure : ?reflexive:bool -> t -> t+    (** [add_transitive_closure ?reflexive g] replaces [g] by its+      transitive closure. Meaningless for persistent implementations+      (then acts as [transitive_closure]). *)++  val mirror : t -> t+    (** [mirror g] returns a new graph which is the mirror image of [g]:+      each edge from [u] to [v] has been replaced by an edge from [v] to [u].+      For undirected graphs, it simply returns a copy of [g]. *)++  val complement : t -> t+    (** [complement g] builds a new graph which is the complement of [g]:+      each edge present in [g] is not present in the resulting graph and+      vice-versa. Edges of the returned graph are unlabeled. *)++  val intersect : t -> t -> t+    (** [intersect g1 g2] returns a new graph which is the intersection of [g1]+      and [g2]: each vertex and edge present in [g1] *and* [g2] is present +      in the resulting graph. *)++  val union : t -> t -> t+    (** [union g1 g2] returns a new graph which is the union of [g1] and [g2]:+      each vertex and edge present in [g1] *or* [g2] is present in the +      resulting graph. *)++  (** {2 Traversal} *)++  (** Depth-first search *)+  module Dfs : sig+    val iter : ?pre:(V.t -> unit) -> +               ?post:(V.t -> unit) -> t -> unit+      (** [iter pre post g] visits all nodes of [g] in depth-first search, +	  applying [pre] to each visited node before its successors,+	  and [post] after them. Each node is visited exactly once. *)+    val prefix : (V.t -> unit) -> t -> unit+      (** applies only a prefix function *)+    val postfix : (V.t -> unit) -> t -> unit+      (** applies only a postfix function *)++    (** Same thing, but for a single connected component *)++    val iter_component : +               ?pre:(V.t -> unit) -> +               ?post:(V.t -> unit) -> t -> V.t -> unit+    val prefix_component : (V.t -> unit) -> t -> V.t -> unit+    val postfix_component : (V.t -> unit) -> t -> V.t -> unit++    val has_cycle : t -> bool+  end++  (** Breadth-first search *)+  module Bfs : sig+    val iter : (V.t -> unit) -> t -> unit+    val iter_component : (V.t -> unit) -> t -> V.t -> unit+  end++  (** Graph traversal with marking *)+  module Marking : sig+    val dfs : t -> unit+    val has_cycle : t -> bool+  end++  (** {2 Graph generators} *)++  (** Classic graphs *)+  module Classic : sig+    val divisors : int -> t+      (** [divisors n] builds the graph of divisors. +	Vertices are integers from [2] to [n]. [i] is connected to [j] if+        and only if [i] divides [j]. +	@raise Invalid_argument is [n < 2]. *)++    val de_bruijn : int -> t+      (** [de_bruijn n] builds the de Bruijn graph of order [n].+	Vertices are bit sequences of length [n] (encoded as their+	interpretation as binary integers). The sequence [xw] is connected+	to the sequence [wy] for any bits [x] and [y] and any bit sequence +        [w] of length [n-1]. +	@raise Invalid_argument is [n < 1] or [n > Sys.word_size-1]. *)++    val vertex_only : int -> t+      (** [vertex_only n] builds a graph with [n] vertices and no edge. *)++    val full : ?self:bool -> int -> t+      (** [full n] builds a graph with [n] vertices and all possible edges.+	The optional argument [self] indicates if loop edges should be added+        (default value is [true]). *)+  end++  (** Random graphs *)+  module Rand : sig+    val graph : ?loops:bool -> v:int -> e:int -> unit -> t+      (** [random v e] generates a random with [v] vertices and [e] edges. *)++    val labeled : +      (V.t -> V.t -> E.label) -> +	?loops:bool -> v:int -> e:int -> unit -> t+	  (** [random_labeled f] is similar to [random] except that edges are +            labeled using function [f] *)+  end++  (** Strongly connected components *)+  module Components : sig+    val scc : t -> int*(V.t -> int)+	(** strongly connected components *)+    val scc_array : t -> V.t list array+    val scc_list : t -> V.t list list+  end++  (** {2 Classical algorithms} *)++  val shortest_path : t -> V.t -> V.t -> E.t list * int+    (** Dijkstra's shortest path algorithm. Weights are the labels. *)++  val ford_fulkerson : t -> V.t -> V.t -> (E.t -> int) * int+    (** Ford Fulkerson maximum flow algorithm *)++  val goldberg : t -> V.t -> V.t -> (E.t -> int) * int+    (** Goldberg maximum flow algorithm *)++  (** Path checking *)+  module PathCheck : sig+    type path_checker+    val create : t -> path_checker+    val check_path : path_checker -> V.t -> V.t -> bool+  end++  (** Topological order *)+  module Topological : sig+    val fold : (V.t -> 'a -> 'a) -> t -> 'a -> 'a+    val iter : (V.t -> unit) -> t -> unit+  end++  val spanningtree : t -> E.t list+    (** Kruskal algorithm *)++  (** {2 Input / Output} *)++  val dot_output : t -> string -> unit +    (** DOT output *)++  val display_with_gv : t -> unit+    (** Displays the given graph using the external tools "dot" and "gv"+        and returns when gv's window is closed *)++  val parse_gml_file : string -> t+  val parse_dot_file : string -> t++  val print_gml_file : t -> string -> unit++end
+ external/ocamlgraph/src/strat.ml view
@@ -0,0 +1,233 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++(* Signature for graphs *)+module type G = sig++  type t++  module V : Sig.ORDERED_TYPE++  type vertex = V.t++  val mem_vertex : t -> vertex -> bool++  val succ : t -> vertex -> vertex list++  val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a+  val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a+end+++(* Signature for graph add-ons: an initial vertex, final vertices+   and membership of vertices to either true or false,+   i.e. first or second player *)+module type PLAYER = sig++  type t+  type vertex++  val get_initial : t -> vertex+  val is_final : t -> vertex -> bool++  val turn : t -> vertex -> bool++end+++(* Signature for strategies : for a given state, the strategy tells+   which state to go to *)+module type STRAT = sig++  type t+  type vertex++  val empty : t+  val add : t -> vertex -> vertex -> t++  val next : t -> vertex -> vertex+    (* Raises Invalid_argument if vertex's image is not defined *)++end+++(* Implements strategy algorithms on graphs *)+module Algo (G : G) (P : PLAYER with type vertex = G.vertex)+  (S : STRAT with type vertex = G.vertex) :+sig++  (* coherent_player g p returns true iff+     the completion p is coherent w.r.t.+     the graph g *)+  val coherent_player : G.t -> P.t -> bool++  (* coherent_strat g s returns true iff+     the strategy s is coherent w.r.t.+     the graph g *)+  val coherent_strat : G.t -> S.t -> bool++  (* game g p a b returns true iff a wins in g+     given the completion p (i.e. the game+     goes through a final state). *)+  val game : G.t -> P.t -> S.t -> S.t -> bool++  (* strategy g p s returns true iff s wins in g+     given the completion p, whatever strategy+     plays the other player. *)+  val strategy : G.t -> P.t -> S.t -> bool++  (* strategyA g p returns true iff there+     exists a winning stragegy for the true+     player. In this case, the winning+     strategy is provided. *)+  val strategyA : G.t -> P.t -> (bool * S.t)+end = struct++    module SetV = Set.Make (G.V)+++    let rec eq l1 l2 = match l1, l2 with+	[], [] -> true+      | e1 :: l1', e2 :: l2' ->+	  (e1 = e2) && (eq l1' l2')+      | _ -> false++    let rec eq_mem i l1 l2 = match l1, l2 with+	[], [] -> (true, false)+      | e1 :: l1', e2 :: l2' ->+	  if e1 = e2 then+	    if e1 = i then (eq l1' l2', true)+	    else eq_mem i l1' l2'+	  else (false, false)+      | _ -> (false, false)++    let puit g v = match G.succ g v with+	[] -> true+      | _ -> false+++    let get_finals g p =+      let f a l =+	if P.is_final p a then a :: l+	else l+      in G.fold_vertex f g []+++    let coherent_player g p =+      G.mem_vertex g (P.get_initial p)+++    let coherent_strat g s =+      let f v b =+	try+	  let v' = S.next s v in+	    b && (G.mem_vertex g v')+	with Invalid_argument _ -> true+      in+	G.fold_vertex f g true+++    let game g p a b =++      let rec game_aux l pi =+	let continue x =+	  try+	    game_aux (SetV.add pi l) (S.next x pi)+	  with Invalid_argument _ -> false+	in+	  (P.is_final p pi) ||+	    (if SetV.mem pi l then false+	     else+	       if P.turn p pi then continue a+	       else continue b)++      in+	game_aux SetV.empty (P.get_initial p)+++    let rec attract1 g p s l =+      let f v l1 =+	if not (List.mem v l1) then+	  if P.turn p v then+	    try+	      if List.mem (S.next s v) l1 then v :: l1+	      else l1+	    with Invalid_argument _ -> l1+	  else+	    if puit g v then l1+	    else+	      if G.fold_succ (fun v' b -> b && (List.mem v' l1)) g v true+	      then v :: l1+	      else l1+	else l1+      in+	G.fold_vertex f g l+++    let rec strategy g p s =++      let rec strategy_aux l1 l2 =+	let (b1, b2) = eq_mem (P.get_initial p) l1 l2 in+	  if b1 then b2+	  else strategy_aux (attract1 g p s l1) l1++      in+      let finaux = get_finals g p in+	strategy_aux (attract1 g p s finaux) finaux+	  ++    let rec attract g p (l, l') =+      let f v (l1, l1') =+	if not (List.mem v l1) then+	  if P.turn p v then+	    let f' v' l2 =+	      (match l2 with+		   [] ->+		     if List.mem v' l1 then [v']+		     else []+		 | _ -> l2) in+	      (match G.fold_succ f' g v [] with+		   [] -> (l1, l1')+		 | v' :: _ -> (v :: l1, S.add l1' v v' ))+	  else+	    if puit g v then (l1, l1')+	    else+	      if G.fold_succ (fun v' b -> b && (List.mem v' l1)) g v true+	      then (v :: l1, l1')+	      else (l1, l1')+	else (l1, l1')+      in+	G.fold_vertex f g (l, l')+++    let rec strategyA g p =++      let rec strategyA_aux l1 l2 f =+	let (b1, b2) = eq_mem (P.get_initial p) l1 l2 in+	  if b1 then (b2, f)+	  else+	    let (new_l1, new_f) = attract g p (l1, f) in+	      strategyA_aux new_l1 l1 new_f++      in+      let finaux = get_finals g p in+      let (l, r) = attract g p (finaux, S.empty) in+	strategyA_aux l finaux r;;++  end
+ external/ocamlgraph/src/strat.mli view
@@ -0,0 +1,103 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id:$ *)++(** Strategies ++    Implementation of a winning strategy of a graph: the graph+    represents a two players game, each vertex belongs to either player+    (whose turn it is to play) and describes a configuration of the+    game. The algorithm computes the winning strategy of a player, if any; +    i.e. the moves to play (which vertex to go to) so that for all+    possible moves of the other player, the game goes through a final+    state. ++    @author Nicolas Ayache *)++(** Signature for graphs *)+module type G = sig+  type t+  module V : Sig.ORDERED_TYPE+  type vertex = V.t+  val mem_vertex : t -> vertex -> bool+  val succ : t -> vertex -> vertex list+  val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a+  val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a+end++(** Signature for graph add-ons: an initial vertex, final vertices+   and membership of vertices to either true or false,+   i.e. first or second player *)+module type PLAYER = sig++  type t+  type vertex++  val get_initial : t -> vertex+  val is_final : t -> vertex -> bool++  val turn : t -> vertex -> bool++end++(** Signature for strategies: for a given state, the strategy tells+   which state to go to *)+module type STRAT = sig++  type t+  type vertex++  val empty : t+  val add : t -> vertex -> vertex -> t++  val next : t -> vertex -> vertex+    (* Raises [Invalid_argument] if vertex's image is not defined *)++end++(** Implements strategy algorithms on graphs *)+module Algo (G : G) (P : PLAYER with type vertex = G.vertex)+  (S : STRAT with type vertex = G.vertex) :+sig++  (** [coherent_player g p] returns [true] iff+     the completion [p] is coherent w.r.t.+     the graph g *)+  val coherent_player : G.t -> P.t -> bool++  (** [coherent_strat g s] returns [true] iff+     the strategy [s] is coherent w.r.t.+     the graph [g] *)+  val coherent_strat : G.t -> S.t -> bool++  (** [game g p a b] returns [true] iff [a] wins in [g]+     given the completion [p] (i.e. the game+     goes through a final state). *)+  val game : G.t -> P.t -> S.t -> S.t -> bool++  (** [strategy g p s] returns [true] iff [s] wins in [g]+     given the completion [p], whatever strategy+     plays the other player. *)+  val strategy : G.t -> P.t -> S.t -> bool++  (** [strategyA g p] returns [true] iff there+      exists [a] winning stragegy for the true+      player. In this case, the winning+      strategy is provided. *)+  val strategyA : G.t -> P.t -> (bool * S.t)+end
+ external/ocamlgraph/src/topological.ml view
@@ -0,0 +1,57 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(*i $Id: topological.ml,v 1.5 2004-02-20 14:37:41 signoles Exp $ i*)++module type G = sig+  type t+  module V : Sig.HASHABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val in_degree : t -> V.t -> int+end++module Make(G: G) = struct++  module H = Hashtbl.Make(G.V)++  let fold f g acc =+    let degree = H.create 997 in+    let todo = Queue.create () in+    let rec walk acc = +      try+	let v = Queue.pop todo in+	let acc = f v acc in+	G.iter_succ +	  (fun x-> let d = H.find degree x in+	   if d=1 then Queue.push x todo+	   else H.replace degree x (d-1))+	  g v; +	walk acc+      with Queue.Empty -> acc+    in+    G.iter_vertex +      (fun v -> +	 let d = G.in_degree g v in +	 if d = 0 then Queue.push v todo+	 else H.add degree v d)+      g;+    walk acc++  let iter f g = fold (fun v () -> f v) g ()++end
+ external/ocamlgraph/src/topological.mli view
@@ -0,0 +1,48 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: topological.mli,v 1.7 2004-12-20 13:35:42 filliatr Exp $ *)++(** Topological order.++  This functor provides functions which allow iterating over a+  directed graph in topological order *)++(** Minimal graph signature to provide *)+module type G = sig+  type t+  module V : Sig.HASHABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val in_degree : t -> V.t -> int+end++module Make(G: G) : sig++  val fold : (G.V.t -> 'a -> 'a) -> G.t -> 'a -> 'a+    (** [fold action g seed] allows iterating over the graph [g] +      in topological order. [action node accu] is called repeatedly,+      where [node] is the node being visited, and [accu] is the result of +      the [action]'s previous invocation, if any, and [seed] otherwise. *)++  val iter : (G.V.t -> unit) -> G.t -> unit+    (** [iter action] calls [action node] repeatedly. Nodes are (again) +      presented to [action] in topological order. *)++end++
+ external/ocamlgraph/src/traverse.ml view
@@ -0,0 +1,284 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: traverse.ml,v 1.17 2004-11-04 13:10:28 filliatr Exp $ *)++(* Graph traversal *)++module type G = sig+  type t+  module V : Sig.COMPARABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++(* depth-first search *)+module Dfs(G : G) = struct+  module H = Hashtbl.Make(G.V)++  let iter ?(pre=fun _ -> ()) ?(post=fun _ -> ()) g = +    let h = H.create 65537 in+    let rec visit v =+      if not (H.mem h v) then begin+	H.add h v ();+	pre v;+	G.iter_succ visit g v;+	post v+      end+    in+    G.iter_vertex visit g++  let postfix post g = iter ~post g++  let iter_component ?(pre=fun _ -> ()) ?(post=fun _ -> ()) g v = +    let h = H.create 65537 in+    let rec visit v =+      H.add h v ();+      pre v;+      G.iter_succ (fun w -> if not (H.mem h w) then visit w) g v;+      post v+    in+    visit v++  let prefix_component pre g = iter_component ~pre g+  let postfix_component post g = iter_component ~post g++  (* invariant: not in [h] means not visited at all; [h v = true] means+     already visited in the current component; [h v = false] means+     already visited in another tree *)+  let has_cycle g =+    let h = H.create 65537 in+    let rec visit v =+      H.add h v true;+      G.iter_succ +	(fun w -> try if H.find h w then raise Exit with Not_found -> visit w) +	g v;+      H.replace h v false+    in+    try G.iter_vertex (fun v -> if not (H.mem h v) then visit v) g; false +    with Exit -> true++  module Tail = struct++    let iter f g = +      let h = H.create 65537 in+      let stack = Stack.create () in+      (* invariant: [h] contains exactly the vertices which have been pushed *)+      let push v = +	if not (H.mem h v) then begin H.add h v (); Stack.push v stack end+      in+      let loop () =+	while not (Stack.is_empty stack) do+	  let v = Stack.pop stack in+	  f v;+	  G.iter_succ push g v+	done+      in+      G.iter_vertex (fun v -> push v; loop ()) g++    let iter_component f g v0 = +      let h = H.create 65537 in+      let stack = Stack.create () in+      (* invariant: [h] contains exactly the vertices which have been pushed *)+      let push v = +	if not (H.mem h v) then begin H.add h v (); Stack.push v stack end+      in+      push v0;+      while not (Stack.is_empty stack) do+	let v = Stack.pop stack in+	f v;+	G.iter_succ push g v+      done++  end++  let prefix = Tail.iter+  let prefix_component = Tail.iter_component++  (* step-by-step iterator *)+  module S = Set.Make(G.V)++  (* state is [(s,st,g)] : [s] contains elements never been pushed in [st] *)+  type iterator = S.t * G.V.t list * G.t++  let start g =+    let s = G.fold_vertex S.add g S.empty in+    s, [], g++  let get (s,st,_) = match st with+    | [] -> if S.is_empty s then raise Exit else S.choose s+    | v :: _ -> v++  let step (s,st,g) =+    let push v (s,st as acc) = +      if S.mem v s then +	S.remove v s, v :: st+      else+	acc +    in+    let v,s',st' = match st with+      | [] ->+	  if S.is_empty s then raise Exit;+	  let v = S.choose s in+	  (v, S.remove v s, [])+      | v :: st' ->+	  (v, s, st')+    in+    let s'',st'' = G.fold_succ push g v (s',st') in+    (s'',st'',g)++end++(* breadth-first search *)+module Bfs(G : G) = struct+  module H = Hashtbl.Make(G.V)++  let iter f g = +    let h = H.create 65537 in+    let q = Queue.create () in+    (* invariant: [h] contains exactly the vertices which have been pushed *)+    let push v = +      if not (H.mem h v) then begin H.add h v (); Queue.add v q end +    in+    let loop () =+      while not (Queue.is_empty q) do+	let v = Queue.pop q in+	f v;+	G.iter_succ push g v+      done+    in+    G.iter_vertex (fun v -> push v; loop ()) g++  let iter_component f g v0 = +    let h = H.create 65537 in+    let q = Queue.create () in+    (* invariant: [h] contains exactly the vertices which have been pushed *)+    let push v = +      if not (H.mem h v) then begin H.add h v (); Queue.add v q end +    in+    push v0;+    while not (Queue.is_empty q) do+      let v = Queue.pop q in+      f v;+      G.iter_succ push g v+    done++  (* step-by-step iterator *)++  (* simple, yet O(1)-amortized, persistent queues *)+  module Q = struct+    type 'a t = 'a list * 'a list+    exception Empty+    let empty = [], []+    let is_empty = function [], [] -> true | _ -> false+    let push x (i,o) = (x :: i, o)+    let pop = function +      | i, y :: o -> y, (i,o) +      | [], [] -> raise Empty+      | i, [] -> match List.rev i with +	  | x :: o -> x, ([], o) +	  | [] -> assert false+    let peek q = fst (pop q)+  end++  module S = Set.Make(G.V)++  (* state is [(s,q,g)] : [s] contains elements never been pushed in [q] *)+  type iterator = S.t * G.V.t Q.t * G.t++  let start g =+    let s = G.fold_vertex S.add g S.empty in+    s, Q.empty, g++  let get (s,q,g) = +    if Q.is_empty q then+      if S.is_empty s then raise Exit else S.choose s+    else+      Q.peek q++  let step (s,q,g) =+    let push v (s,q as acc) = +      if S.mem v s then +	S.remove v s, Q.push v q+      else+	acc +    in+    let v,s',q' = +      if Q.is_empty q then begin+	if S.is_empty s then raise Exit;+	let v = S.choose s in+	v, S.remove v s, q+      end else+	let v,q' = Q.pop q in +	v, s, q'+    in+    let s'',q'' = G.fold_succ push g v (s',q') in+    (s'',q'',g)++end+++(* Graph traversal with marking. *)++module type GM = sig+  type t+  module V : sig type t end+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  module Mark : sig+    val clear : t -> unit+    val get : V.t -> int+    val set : V.t -> int -> unit+  end+end++module Mark(G : GM) = struct++  let dfs g =+    G.Mark.clear g;+    let n = ref 0 in+    let rec visit v =+      if G.Mark.get v = 0 then begin+	incr n;+	G.Mark.set v !n;+	G.iter_succ visit g v+      end+    in+    G.iter_vertex visit g++  (* invariant: [h v = 0] means not visited at all; [h v = 1] means+     already visited in the current component; [h v = 2] means+     already visited in another tree *)+  let has_cycle g =+    G.Mark.clear g;+    let rec visit v =+      G.Mark.set v 1;+      G.iter_succ +	(fun w -> +	   let m = G.Mark.get w in+	   if m = 1 then raise Exit;+	   if m = 0 then visit w) +	g v;+      G.Mark.set v 2+    in+    try G.iter_vertex (fun v -> if G.Mark.get v = 0 then visit v) g; false +    with Exit -> true++end+
+ external/ocamlgraph/src/traverse.mli view
@@ -0,0 +1,127 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: traverse.mli,v 1.14 2005-04-01 07:13:24 filliatr Exp $ *)++(** Graph traversal *)++(** {1 Dfs and Bfs} *)++(** Minimal graph signature for [Dfs] or [Bfs] *)+module type G = sig+  type t+  module V : Sig.COMPARABLE+  val iter_vertex : (V.t -> unit) -> t -> unit+  val fold_vertex : (V.t -> 'a -> 'a) -> t  -> 'a -> 'a+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a+end++(** Depth-first search *)+module Dfs(G : G) : sig+  (** {2 Classical big-step iterators} *)++  val iter : ?pre:(G.V.t -> unit) -> +             ?post:(G.V.t -> unit) -> G.t -> unit+      (** [iter pre post g] visits all nodes of [g] in depth-first search, +	 applying [pre] to each visited node before its successors,+	 and [post] after them. Each node is visited exactly once. +         Not tail-recursive. *)++  val prefix : (G.V.t -> unit) -> G.t -> unit+    (** applies only a prefix function; note that this function is more+      efficient than [iter] and is tail-recursive. *)++  val postfix : (G.V.t -> unit) -> G.t -> unit+    (** applies only a postfix function. Not tail-recursive. *)++  (** Same thing, but for a single connected component+      (only [prefix_component] is tail-recursive) *)++  val iter_component : ?pre:(G.V.t -> unit) -> +             ?post:(G.V.t -> unit) -> G.t -> G.V.t -> unit+  val prefix_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit+  val postfix_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit++  (** {2 Step-by-step iterator}++    This is a variant of the iterators above where you can move on+    step by step. The abstract type [iterator] represents the current+    state of the iteration. The [step] function returns the next state. +    In each state, function [get] returns the currently visited vertex.+    On the final state both [get] and [step] raises exception [Exit]. ++    Note: the iterator type is persistent (i.e. is not modified by the +    [step] function) and thus can be used in backtracking algorithms. *)++  type iterator+  val start : G.t -> iterator+  val step : iterator -> iterator+  val get : iterator -> G.V.t++  (** {2 Cycle detection} *)++  val has_cycle : G.t -> bool+    (** [has_cycle g] checks for a cycle in [g]. Linear in time and space. *)++end++(** Breadth-first search *)+module Bfs(G : G) : sig+  (** {2 Classical big-step iterators} *)++  val iter : (G.V.t -> unit) -> G.t -> unit+  val iter_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit++  (** {2 Step-by-step iterator}+    See module [Dfs] *)++  type iterator+  val start : G.t -> iterator+  val step : iterator -> iterator+  val get : iterator -> G.V.t++end++(** {1 Traversal with marking} *)++(** Minimal graph signature for graph traversal with marking. *)+module type GM = sig+  type t+  module V : sig type t end+  val iter_vertex : (V.t -> unit) -> t -> unit+  val iter_succ : (V.t -> unit) -> t -> V.t -> unit+  module Mark : sig+    val clear : t -> unit+    val get : V.t -> int+    val set : V.t -> int -> unit+  end+end++(** Graph traversal with marking. +    Only applies to imperative graphs with marks. *)+module Mark(G : GM) : sig++  val dfs : G.t -> unit+    (** [dfs g] traverses [g] in depth-first search, marking all nodes. *)++  val has_cycle : G.t -> bool+    (** [has_cycle g] checks for a cycle in [g]. Modifies the marks.+      Linear time, constant space. *)++end+
+ external/ocamlgraph/src/util.ml view
@@ -0,0 +1,67 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: util.ml,v 1.14 2004-10-19 15:21:45 signoles Exp $ *)++open Sig++module OTProduct(X: ORDERED_TYPE)(Y: ORDERED_TYPE) = struct ++  type t = X.t * Y.t ++  let compare (x1, y1) (x2, y2) = +    let cv = X.compare x1 x2 in+    if cv != 0 then cv else Y.compare y1 y2++end++module HTProduct(X: HASHABLE)(Y: HASHABLE) = struct++  type t = X.t * Y.t++  let equal (x1, y1) (x2, y2) =+    X.equal x1 x2 && Y.equal y1 y2++  let hash (x, y) = +    Hashtbl.hash (X.hash x, Y.hash y)++end++module CMPProduct(X: COMPARABLE)(Y: COMPARABLE) = struct +  include HTProduct(X)(Y)+  include (OTProduct(X)(Y): sig val compare : t -> t -> int end)+end++module DataV(L : sig type t end)(V : Sig.COMPARABLE) = +struct+  type data = L.t+  type label = V.t+  type t = data ref * V.t+      +  let compare ((_, x) : t) ((_, x') : t) =+    V.compare x x'+      +  let hash ((_, x) : t) = V.hash x++  let equal ((_, x) : t) ((_, x') : t) = V.equal x x'+				   +  let create y lbl = (ref y, lbl)+  let label (_, z) = z+  let data (y, _) = !y+  let set_data (y, _) = (:=) y+end+
+ external/ocamlgraph/src/util.mli view
@@ -0,0 +1,47 @@+(**************************************************************************)+(*                                                                        *)+(*  Ocamlgraph: a generic graph library for OCaml                         *)+(*  Copyright (C) 2004-2007                                               *)+(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)+(*                                                                        *)+(*  This software is free software; you can redistribute it and/or        *)+(*  modify it under the terms of the GNU Library General Public           *)+(*  License version 2, with the special exception on linking              *)+(*  described in file LICENSE.                                            *)+(*                                                                        *)+(*  This software is distributed in the hope that it will be useful,      *)+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)+(*                                                                        *)+(**************************************************************************)++(* $Id: util.mli,v 1.12 2005-03-31 13:32:51 filliatr Exp $ *)++open Sig++module OTProduct(X: ORDERED_TYPE)(Y: ORDERED_TYPE) : +  ORDERED_TYPE with type t = X.t * Y.t++module HTProduct(X: HASHABLE)(Y: HASHABLE) :+  HASHABLE with type t = X.t * Y.t++module CMPProduct(X: COMPARABLE)(Y: COMPARABLE) : +  COMPARABLE with type t = X.t * Y.t++(** Create a vertex type with some data attached to it *)+module DataV +  (L : sig type t end)+  (V : Sig.COMPARABLE) :+sig+  type data = L.t+  and label = V.t+  and t = data ref * V.t+  val compare : t -> t -> int+  val hash : t -> int+  val equal : t -> t -> bool+  val create : data -> V.t -> t+  val label : t -> V.t+  val data : t -> data+  val set_data : t -> data -> unit+end+  
+ external/ocamlgraph/src/version.ml view
@@ -0,0 +1,2 @@+let version = "0.99b"+let date = "Sun Sep 22 21:13:17 PDT 2013"
+ external/z3/include/z3.h view
@@ -0,0 +1,70 @@+/*+++Copyright (c) 2007 Microsoft Corporation++Module Name:++    msmt.h++Abstract:++    Z3 API.++Author:++    Nikolaj Bjorner (nbjorner)+    Leonardo de Moura (leonardo) 2007-06-8++Notes:+    +--*/++#ifndef _Z3__H_+#define _Z3__H_++#include <stdio.h>++#ifndef __in+#define __in+#endif++#ifndef __in_z+#define __in_z __in+#endif++#ifndef __out+#define __out+#endif++#ifndef __out_z+#define __out_z+#endif++#ifndef __ecount+#define __ecount(num_args)+#endif ++#ifndef __in_ecount+#define __in_ecount(num_args) __in __ecount(num_args)+#endif ++#ifndef __out_ecount+#define __out_ecount(num_args) __out __ecount(num_args)+#endif ++#ifndef __inout_ecount+#define __inout_ecount(num_args) __in __out __ecount(num_args)+#endif ++#ifndef __inout+#define __inout __in __out+#endif++#define Z3_API++#define DEFINE_TYPE(T) typedef struct _ ## T *T+#define DEFINE_VOID(T) typedef void* T++#include"z3_api.h"++#endif+
+ external/z3/include/z3_api.h view
@@ -0,0 +1,4824 @@+DEFINE_TYPE(Z3_config);+DEFINE_TYPE(Z3_context);+DEFINE_TYPE(Z3_sort);+DEFINE_TYPE(Z3_func_decl);+DEFINE_TYPE(Z3_ast);+DEFINE_TYPE(Z3_app);+DEFINE_TYPE(Z3_pattern);+DEFINE_TYPE(Z3_symbol);+DEFINE_TYPE(Z3_parameter);+DEFINE_TYPE(Z3_model);+DEFINE_TYPE(Z3_literals);+DEFINE_TYPE(Z3_constructor);+DEFINE_TYPE(Z3_constructor_list);+DEFINE_TYPE(Z3_theory);+DEFINE_VOID(Z3_theory_data);+++#ifndef __int64+#define __int64 long long+#endif++#ifndef __uint64+#define __uint64 unsigned long long+#endif++// Backwards compatibility+#define Z3_type_ast            Z3_sort+#define Z3_const_decl_ast      Z3_func_decl+#define Z3_const               Z3_app+#define Z3_pattern_ast         Z3_pattern+#define Z3_UNINTERPRETED_TYPE  Z3_UNINTERPRETED_SORT+#define Z3_BOOL_TYPE           Z3_BOOL_SORT+#define Z3_INT_TYPE            Z3_INT_SORT+#define Z3_REAL_TYPE           Z3_REAL_SORT+#define Z3_BV_TYPE             Z3_BV_SORT+#define Z3_ARRAY_TYPE          Z3_ARRAY_SORT+#define Z3_TUPLE_TYPE          Z3_DATATYPE_SORT+#define Z3_UNKNOWN_TYPE        Z3_UNKNOWN_SORT+#define Z3_CONST_DECL_AST      Z3_FUNC_DECL_AST    +#define Z3_TYPE_AST            Z3_SORT_AST          +#define Z3_SORT_ERROR          Z3_TYPE_ERROR+#define Z3_mk_uninterpreted_type Z3_mk_uninterpreted_sort+#define Z3_mk_bool_type        Z3_mk_bool_sort+#define Z3_mk_int_type         Z3_mk_int_sort+#define Z3_mk_real_type        Z3_mk_real_sort+#define Z3_mk_bv_type          Z3_mk_bv_sort+#define Z3_mk_array_type       Z3_mk_array_sort+#define Z3_mk_tuple_type       Z3_mk_tuple_sort+#define Z3_get_type            Z3_get_sort+#define Z3_get_pattern_ast           Z3_get_pattern+#define Z3_get_type_kind             Z3_get_sort_kind+#define Z3_get_type_name             Z3_get_sort_name+#define Z3_get_bv_type_size          Z3_get_bv_sort_size+#define Z3_get_array_type_domain     Z3_get_array_sort_domain+#define Z3_get_array_type_range      Z3_get_array_sort_range+#define Z3_get_tuple_type_num_fields Z3_get_tuple_sort_num_fields+#define Z3_get_tuple_type_field_decl Z3_get_tuple_sort_field_decl+#define Z3_get_tuple_type_mk_decl    Z3_get_tuple_sort_mk_decl+#define Z3_to_const_ast              Z3_to_app+#define Z3_get_numeral_value_string  Z3_get_numeral_string+#define Z3_get_const_ast_decl        Z3_get_app_decl+#define Z3_get_value                 Z3_eval_func_decl++/**+   \defgroup capi C API++*/+/*@{*/++/**+   \conly @name Types+   +   \conly Most of the types in the C API are opaque pointers.++   \conly - \c Z3_config: a configuration object used to initialize logical contexts.+   \conly - \c Z3_context: logical context. This is the main Z3 data-structure.+   \conly - \c Z3_symbol: a Lisp-link symbol. It is used to name types, constants, and functions.  A symbol can be created using+   \conly string or integers. +   \conly - \c Z3_ast: abstract syntax tree node. That is, the data-structure used in Z3 to represent terms, formulas and types.+   \conly - \c Z3_sort: a kind of AST used to represent types.+   \conly - \c Z3_app: a kind of AST used to represent constant and function declarations.+   \conly - \c Z3_pattern: a kind of AST used to represent pattern and multi-patterns used to guide quantifier instantiation.+   \conly - \c Z3_model: a model for the constraints asserted into the logical context.+*/++#ifndef CAMLIDL+/**+   \conly \brief Z3 Boolean type. It is just an alias for \c int.+*/+typedef int Z3_bool;+#else+/**+   \conly \brief Z3 Boolean type. It is just an alias for \c Boolean.+*/+#define Z3_bool boolean+#endif // CAMLIDL++#ifndef CAMLIDL+/**+   \conly \brief Z3 string type. It is just an alias for <tt>const char *</tt>.+*/+typedef const char * Z3_string;+typedef Z3_string * Z3_string_ptr;+#else+/**+   \conly \brief Z3 string type. It is just an alias for <tt>[string] const char *</tt>.+*/+#define Z3_string [string] const char *+/* hack to make the IDL compiler happy */+#define Z3_string_ptr const char * *+#endif // CAMLIDL+    +#ifndef CAMLIDL+/**+   \conly \brief True value. It is just an alias for \c 1.+*/+#define Z3_TRUE  1++/**+   \conly \brief False value. It is just an alias for \c 0.+*/+#define Z3_FALSE 0++#endif // CAMLIDL++/**+   \conly \brief Lifted Boolean type: \c false, \c undefined, \c true.+*/+typedef enum +{+    Z3_L_FALSE = -1,+    Z3_L_UNDEF,+    Z3_L_TRUE+} Z3_lbool;++/**+   \conly \brief In Z3, a symbol can be represented using integers and strings (See #Z3_get_symbol_kind).++   \conly \sa Z3_mk_int_symbol+   \conly \sa Z3_mk_string_symbol+*/+typedef enum +{+    Z3_INT_SYMBOL,+    Z3_STRING_SYMBOL +} Z3_symbol_kind;+++/**+   \conly \brief The different kinds of parameters that can be associated with function symbols.+   \conly \sa Z3_get_decl_num_parameters+   \conly \sa Z3_get_decl_parameter_kind++   \conly - Z3_PARAMETER_INT is used for integer parameters.+   \conly - Z3_PARAMETER_DOUBLE is used for double parameters.+   \conly - Z3_PARAMETER_RATIONAL is used for parameters that are rational numbers.+   \conly - Z3_PARAMETER_SORT is used for sort parameters.+   \conly - Z3_PARAMETER_AST is used for expression parameters.+   \conly - Z3_PARAMETER_FUNC_DECL is used for function declaration parameters.+*/+typedef enum +{+    Z3_PARAMETER_INT,+    Z3_PARAMETER_DOUBLE,+    Z3_PARAMETER_RATIONAL,+    Z3_PARAMETER_SYMBOL,+    Z3_PARAMETER_SORT,+    Z3_PARAMETER_AST,+    Z3_PARAMETER_FUNC_DECL,+} Z3_parameter_kind;++/**+   \conly \brief The different kinds of Z3 types (See #Z3_get_sort_kind).+*/+typedef enum +{+    Z3_UNINTERPRETED_SORT,+    Z3_BOOL_SORT,+    Z3_INT_SORT,+    Z3_REAL_SORT,+    Z3_BV_SORT,+    Z3_ARRAY_SORT,+    Z3_DATATYPE_SORT,+    Z3_RELATION_SORT,+    Z3_FINITE_DOMAIN_SORT,+    Z3_UNKNOWN_SORT = 1000+} Z3_sort_kind;++/**+   \conly \brief The different kinds of Z3 AST (abstract syntax trees). That is, terms, formulas and types.++   \conly - Z3_APP_AST:            constant and applications +   \conly - Z3_NUMERAL_AST:        numeral constants+   \conly - Z3_VAR_AST:            bound variables +   \conly - Z3_QUANTIFIER_AST:     quantifiers +   \conly - Z3_UNKNOWN_AST:        internal +*/+typedef enum +{+    Z3_NUMERAL_AST,+    Z3_APP_AST,         +    Z3_VAR_AST,          +    Z3_QUANTIFIER_AST,    +    Z3_UNKNOWN_AST = 1000 +} Z3_ast_kind;++/**+   \conly \brief The different kinds of interpreted function kinds.++   (*+   - Z3_OP_TRUE The constant true.++   - Z3_OP_FALSE The constant false.++   - Z3_OP_EQ The equality predicate.++   - Z3_OP_DISTINCT The n-ary distinct predicate (every argument is mutually distinct).++   - Z3_OP_ITE The ternary if-then-else term.++   - Z3_OP_AND n-ary conjunction.++   - Z3_OP_OR n-ary disjunction.++   - Z3_OP_IFF equivalence (binary).++   - Z3_OP_XOR Exclusive or.++   - Z3_OP_NOT Negation.++   - Z3_OP_IMPLIES Implication.++   - Z3_OP_OEQ Binary equivalence modulo namings. This binary predicate is used in proof terms.+        It captures equisatisfiability and equivalence modulo renamings.++   - Z3_OP_ANUM Arithmetic numeral.++   - Z3_OP_LE <=.++   - Z3_OP_GE >=.++   - Z3_OP_LT <.++   - Z3_OP_GT >.++   - Z3_OP_ADD Addition - Binary.++   - Z3_OP_SUB Binary subtraction.++   - Z3_OP_UMINUS Unary minus.++   - Z3_OP_MUL Multiplication - Binary.++   - Z3_OP_DIV Division - Binary.++   - Z3_OP_IDIV Integer division - Binary.++   - Z3_OP_REM Remainder - Binary.++   - Z3_OP_MOD Modulus - Binary.++   - Z3_OP_TO_REAL Coercion of integer to real - Unary.++   - Z3_OP_TO_INT Coercion of real to integer - Unary.++   - Z3_OP_IS_INT Check if real is also an integer - Unary.++   - Z3_OP_STORE Array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j).+        Array store takes at least 3 arguments. ++   - Z3_OP_SELECT Array select. ++   - Z3_OP_CONST_ARRAY The constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary.++   - Z3_OP_ARRAY_DEFAULT Default value of arrays. For example default(const(v)) = v. The function is unary.++   - Z3_OP_ARRAY_MAP Array map operator.+         It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i.++   - Z3_OP_SET_UNION Set union between two Booelan arrays (two arrays whose range type is Boolean). The function is binary.++   - Z3_OP_SET_INTERSECT Set intersection between two Boolean arrays. The function is binary.++   - Z3_OP_SET_DIFFERENCE Set difference between two Boolean arrays. The function is binary.++   - Z3_OP_SET_COMPLEMENT Set complement of a Boolean array. The function is unary.++   - Z3_OP_SET_SUBSET Subset predicate between two Boolean arrays. The relation is binary.++   - Z3_OP_AS_ARRAY An array value that behaves as the function graph of the+                    function passed as parameter.++   - Z3_OP_BNUM Bit-vector numeral.++   - Z3_OP_BIT1 One bit bit-vector.++   - Z3_OP_BIT0 Zero bit bit-vector.++   - Z3_OP_BNEG Unary minus.++   - Z3_OP_BADD Binary addition.++   - Z3_OP_BSUB Binary subtraction.++   - Z3_OP_BMUL Binary multiplication.+    +   - Z3_OP_BSDIV Binary signed division.++   - Z3_OP_BUDIV Binary unsigned division.++   - Z3_OP_BSREM Binary signed remainder.++   - Z3_OP_BUREM Binary unsigned remainder.++   - Z3_OP_BSMOD Binary signed modulus.++   - Z3_OP_BSDIV0 Unary function. bsdiv(x,0) is congruent to bsdiv0(x).++   - Z3_OP_BUDIV0 Unary function. budiv(x,0) is congruent to budiv0(x).++   - Z3_OP_BSREM0 Unary function. bsrem(x,0) is congruent to bsrem0(x).++   - Z3_OP_BUREM0 Unary function. burem(x,0) is congruent to burem0(x).++   - Z3_OP_BSMOD0 Unary function. bsmod(x,0) is congruent to bsmod0(x).+    +   - Z3_OP_ULEQ Unsigned bit-vector <= - Binary relation.++   - Z3_OP_SLEQ Signed bit-vector  <= - Binary relation.++   - Z3_OP_UGEQ Unsigned bit-vector  >= - Binary relation.++   - Z3_OP_SGEQ Signed bit-vector  >= - Binary relation.++   - Z3_OP_ULT Unsigned bit-vector  < - Binary relation.++   - Z3_OP_SLT Signed bit-vector < - Binary relation.++   - Z3_OP_UGT Unsigned bit-vector > - Binary relation.++   - Z3_OP_SGT Signed bit-vector > - Binary relation.++   - Z3_OP_BAND Bit-wise and - Binary.++   - Z3_OP_BOR Bit-wise or - Binary.++   - Z3_OP_BNOT Bit-wise not - Unary.++   - Z3_OP_BXOR Bit-wise xor - Binary.++   - Z3_OP_BNAND Bit-wise nand - Binary.++   - Z3_OP_BNOR Bit-wise nor - Binary.++   - Z3_OP_BXNOR Bit-wise xnor - Binary.++   - Z3_OP_CONCAT Bit-vector concatenation - Binary.++   - Z3_OP_SIGN_EXT Bit-vector sign extension.++   - Z3_OP_ZERO_EXT Bit-vector zero extension.++   - Z3_OP_EXTRACT Bit-vector extraction.++   - Z3_OP_REPEAT Repeat bit-vector n times.++   - Z3_OP_BREDOR Bit-vector reduce or - Unary.++   - Z3_OP_BREDAND Bit-vector reduce and - Unary.++   - Z3_OP_BCOMP .++   - Z3_OP_BSHL Shift left.++   - Z3_OP_BLSHR Logical shift right.++   - Z3_OP_BASHR Arithmetical shift right.++   - Z3_OP_ROTATE_LEFT Left rotation.++   - Z3_OP_ROTATE_RIGHT Right rotation.++   - Z3_OP_EXT_ROTATE_LEFT (extended) Left rotation. Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one.++   - Z3_OP_EXT_ROTATE_RIGHT (extended) Right rotation. Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one.++   - Z3_OP_INT2BV Coerce integer to bit-vector. NB. This function+       is not supported by the decision procedures. Only the most+       rudimentary simplification rules are applied to this function.++   - Z3_OP_BV2INT Coerce bit-vector to integer. NB. This function+       is not supported by the decision procedures. Only the most+       rudimentary simplification rules are applied to this function.++   - Z3_OP_CARRY Compute the carry bit in a full-adder. +       The meaning is given by the equivalence+       (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3)))++   - Z3_OP_XOR3 Compute ternary XOR.+       The meaning is given by the equivalence+       (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3)++   - Z3_OP_PR_TRUE: Proof for the expression 'true'.++   - Z3_OP_PR_ASSERTED: Proof for a fact asserted by the user.+   +   - Z3_OP_PR_GOAL: Proof for a fact (tagged as goal) asserted by the user.++   - Z3_OP_PR_MODUS_PONENS: Given a proof for p and a proof for (implies p q), produces a proof for q.+       \nicebox{+          T1: p+          T2: (implies p q)+          [mp T1 T2]: q+          }+          The second antecedents may also be a proof for (iff p q).++   - Z3_OP_PR_REFLEXIVITY: A proof for (R t t), where R is a reflexive relation. This proof object has no antecedents.+        The only reflexive relations that are used are +        equivalence modulo namings, equality and equivalence.+        That is, R is either '~', '=' or 'iff'.++   - Z3_OP_PR_SYMMETRY: Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t).+          \nicebox{+          T1: (R t s)+          [symmetry T1]: (R s t)+          }+          T1 is the antecedent of this proof object.++   - Z3_OP_PR_TRANSITIVITY: Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof+       for (R t u).+       \nicebox{+       T1: (R t s)+       T2: (R s u)+       [trans T1 T2]: (R t u)+       }++   - Z3_OP_PR_TRANSITIVITY_STAR: Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1.+     It combines several symmetry and transitivity proofs. ++          Example:+          \nicebox{+          T1: (R a b)+          T2: (R c b)+          T3: (R c d)+          [trans* T1 T2 T3]: (R a d)+          }+          R must be a symmetric and transitive relation.++          Assuming that this proof object is a proof for (R s t), then+          a proof checker must check if it is possible to prove (R s t)+          using the antecedents, symmetry and transitivity.  That is, +          if there is a path from s to t, if we view every+          antecedent (R a b) as an edge between a and b.++   - Z3_OP_PR_MONOTONICITY: Monotonicity proof object.+          \nicebox{+          T1: (R t_1 s_1)+          ...+          Tn: (R t_n s_n)+          [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n))+          }+          Remark: if t_i == s_i, then the antecedent Ti is suppressed.+          That is, reflexivity proofs are supressed to save space.++   - Z3_OP_PR_QUANT_INTRO: Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)).++       T1: (~ p q)+       [quant-intro T1]: (~ (forall (x) p) (forall (x) q))+   +   - Z3_OP_PR_DISTRIBUTIVITY: Distributivity proof object. +          Given that f (= or) distributes over g (= and), produces a proof for++          (= (f a (g c d))+             (g (f a c) (f a d)))++          If f and g are associative, this proof also justifies the following equality:++          (= (f (g a b) (g c d))+             (g (f a c) (f a d) (f b c) (f b d)))++          where each f and g can have arbitrary number of arguments.++          This proof object has no antecedents.+          Remark. This rule is used by the CNF conversion pass and +          instantiated by f = or, and g = and.+    +   - Z3_OP_PR_AND_ELIM: Given a proof for (and l_1 ... l_n), produces a proof for l_i+        +       \nicebox{+       T1: (and l_1 ... l_n)+       [and-elim T1]: l_i+       }+   - Z3_OP_PR_NOT_OR_ELIM: Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i).++       \nicebox{+       T1: (not (or l_1 ... l_n))+       [not-or-elim T1]: (not l_i)+       }++   - Z3_OP_PR_REWRITE: A proof for a local rewriting step (= t s).+          The head function symbol of t is interpreted.++          This proof object has no antecedents.+          The conclusion of a rewrite rule is either an equality (= t s), +          an equivalence (iff t s), or equi-satisfiability (~ t s).+          Remark: if f is bool, then = is iff.+          ++          Examples:+          \nicebox{+          (= (+ x 0) x)+          (= (+ x 1 2) (+ 3 x))+          (iff (or x false) x)+          }++   - Z3_OP_PR_REWRITE_STAR: A proof for rewriting an expression t into an expression s.+       This proof object is used if the parameter PROOF_MODE is 1.+       This proof object can have n antecedents.+       The antecedents are proofs for equalities used as substitution rules.+       The object is also used in a few cases if the parameter PROOF_MODE is 2.+       The cases are:+         - When applying contextual simplification (CONTEXT_SIMPLIFIER=true)+         - When converting bit-vectors to Booleans (BIT2BOOL=true)+         - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true)++   - Z3_OP_PR_PULL_QUANT: A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents.++   - Z3_OP_PR_PULL_QUANT_STAR: A proof for (iff P Q) where Q is in prenex normal form.+       This proof object is only used if the parameter PROOF_MODE is 1.       +       This proof object has no antecedents.+  +   - Z3_OP_PR_PUSH_QUANT: A proof for:++       \nicebox{+          (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m]))+               (and (forall (x_1 ... x_m) p_1[x_1 ... x_m])+                 ... +               (forall (x_1 ... x_m) p_n[x_1 ... x_m])))+               }+         This proof object has no antecedents.++   - Z3_OP_PR_ELIM_UNUSED_VARS:  +          A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n])+                           (forall (x_1 ... x_n) p[x_1 ... x_n])) ++          It is used to justify the elimination of unused variables.+          This proof object has no antecedents.++   - Z3_OP_PR_DER: A proof for destructive equality resolution:+          (iff (forall (x) (or (not (= x t)) P[x])) P[t])+          if x does not occur in t.++          This proof object has no antecedents.+          +          Several variables can be eliminated simultaneously.++   - Z3_OP_PR_QUANT_INST: A proof of (or (not (forall (x) (P x))) (P a))++   - Z3_OP_PR_HYPOTHESIS: Mark a hypothesis in a natural deduction style proof.++   - Z3_OP_PR_LEMMA: ++       \nicebox{+          T1: false+          [lemma T1]: (or (not l_1) ... (not l_n))+          }+          This proof object has one antecedent: a hypothetical proof for false.+          It converts the proof in a proof for (or (not l_1) ... (not l_n)),+          when T1 contains the hypotheses: l_1, ..., l_n.++   - Z3_OP_PR_UNIT_RESOLUTION: +       \nicebox{+          T1:      (or l_1 ... l_n l_1' ... l_m')+          T2:      (not l_1)+          ...+          T(n+1):  (not l_n)+          [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m')+          }++   - Z3_OP_PR_IFF_TRUE: +      \nicebox{+       T1: p+       [iff-true T1]: (iff p true)+       }++   - Z3_OP_PR_IFF_FALSE:+      \nicebox{+       T1: (not p)+       [iff-false T1]: (iff p false)+       }++   - Z3_OP_PR_COMMUTATIVITY:++          [comm]: (= (f a b) (f b a))+          +          f is a commutative operator.++          This proof object has no antecedents.+          Remark: if f is bool, then = is iff.+   +   - Z3_OP_PR_DEF_AXIOM: Proof object used to justify Tseitin's like axioms:+       +          \nicebox{+          (or (not (and p q)) p)+          (or (not (and p q)) q)+          (or (not (and p q r)) p)+          (or (not (and p q r)) q)+          (or (not (and p q r)) r)+          ...+          (or (and p q) (not p) (not q))+          (or (not (or p q)) p q)+          (or (or p q) (not p))+          (or (or p q) (not q))+          (or (not (iff p q)) (not p) q)+          (or (not (iff p q)) p (not q))+          (or (iff p q) (not p) (not q))+          (or (iff p q) p q)+          (or (not (ite a b c)) (not a) b)+          (or (not (ite a b c)) a c)+          (or (ite a b c) (not a) (not b))+          (or (ite a b c) a (not c))+          (or (not (not a)) (not a))+          (or (not a) a)+          }+          This proof object has no antecedents.+          Note: all axioms are propositional tautologies.+          Note also that 'and' and 'or' can take multiple arguments.+          You can recover the propositional tautologies by+          unfolding the Boolean connectives in the axioms a small+          bounded number of steps (=3).+    +   - Z3_OP_PR_DEF_INTRO: Introduces a name for a formula/term.+       Suppose e is an expression with free variables x, and def-intro+       introduces the name n(x). The possible cases are:++       When e is of Boolean type:+       [def-intro]: (and (or n (not e)) (or (not n) e))++       or:+       [def-intro]: (or (not n) e)+       when e only occurs positively.++       When e is of the form (ite cond th el):+       [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el)))++       Otherwise:+       [def-intro]: (= n e)       ++   - Z3_OP_PR_APPLY_DEF: +       [apply-def T1]: F ~ n+       F is 'equivalent' to n, given that T1 is a proof that+       n is a name for F.+   +   - Z3_OP_PR_IFF_OEQ:+       T1: (iff p q)+       [iff~ T1]: (~ p q)+ +   - Z3_OP_PR_NNF_POS: Proof for a (positive) NNF step. Example:+       \nicebox{+          T1: (not s_1) ~ r_1+          T2: (not s_2) ~ r_2+          T3: s_1 ~ r_1'+          T4: s_2 ~ r_2'+          [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2)+                                    (and (or r_1 r_2') (or r_1' r_2)))+          }+       The negation normal form steps NNF_POS and NNF_NEG are used in the following cases:+       (a) When creating the NNF of a positive force quantifier.+        The quantifier is retained (unless the bound variables are eliminated).+        Example+        \nicebox{+           T1: q ~ q_new +           [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new))+        }+       (b) When recursively creating NNF over Boolean formulas, where the top-level+       connective is changed during NNF conversion. The relevant Boolean connectives+       for NNF_POS are 'implies', 'iff', 'xor', 'ite'.+       NNF_NEG furthermore handles the case where negation is pushed+       over Boolean connectives 'and' and 'or'.++    +   - Z3_OP_PR_NFF_NEG: Proof for a (negative) NNF step. Examples:+          \nicebox{+          T1: (not s_1) ~ r_1+          ...+          Tn: (not s_n) ~ r_n+         [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n)+      and+          T1: (not s_1) ~ r_1+          ...+          Tn: (not s_n) ~ r_n+         [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n)+      and+          T1: (not s_1) ~ r_1+          T2: (not s_2) ~ r_2+          T3: s_1 ~ r_1'+          T4: s_2 ~ r_2'+         [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2))+                                   (and (or r_1 r_2) (or r_1' r_2')))+       }+   - Z3_OP_PR_NNF_STAR: A proof for (~ P Q) where Q is in negation normal form.+       +       This proof object is only used if the parameter PROOF_MODE is 1.       +              +       This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO.++   - Z3_OP_PR_CNF_STAR: A proof for (~ P Q) where Q is in conjunctive normal form.+       This proof object is only used if the parameter PROOF_MODE is 1.       +       This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO.          ++   - Z3_OP_PR_SKOLEMIZE: Proof for:  +       +          \nicebox{+          [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y)))+          [sk]: (~ (exists x (p x y)) (p (sk y) y))+          }++          This proof object has no antecedents.+   +   - Z3_OP_PR_MODUS_PONENS_OEQ: Modus ponens style rule for equi-satisfiability.+       \nicebox{+          T1: p+          T2: (~ p q)+          [mp~ T1 T2]: q+          }++    - Z3_OP_PR_TH_LEMMA: Generic proof for theory lemmas.++         The theory lemma function comes with one or more parameters.+         The first parameter indicates the name of the theory.+         For the theory of arithmetic, additional parameters provide hints for+         checking the theory lemma. +         The hints for arithmetic are:+         +         - farkas - followed by rational coefficients. Multiply the coefficients to the+           inequalities in the lemma, add the (negated) inequalities and obtain a contradiction.++         - triangle-eq - Indicates a lemma related to the equivalence:+         \nicebox{+            (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1)))+         }++         - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test.+++      - Z3_OP_RA_STORE: Insert a record into a relation.+        The function takes \c n+1 arguments, where the first argument is the relation and the remaining \c n elements +        correspond to the \c n columns of the relation.++      - Z3_OP_RA_EMPTY: Creates the empty relation. +        +      - Z3_OP_RA_IS_EMPTY: Tests if the relation is empty.++      - Z3_OP_RA_JOIN: Create the relational join.++      - Z3_OP_RA_UNION: Create the union or convex hull of two relations. +        The function takes two arguments.++      - Z3_OP_RA_WIDEN: Widen two relations.+        The function takes two arguments.++      - Z3_OP_RA_PROJECT: Project the columns (provided as numbers in the parameters).+        The function takes one argument.++      - Z3_OP_RA_FILTER: Filter (restrict) a relation with respect to a predicate.+        The first argument is a relation. +        The second argument is a predicate with free de-Brujin indices+        corresponding to the columns of the relation.+        So the first column in the relation has index 0.++      - Z3_OP_RA_NEGATION_FILTER: Intersect the first relation with respect to negation+        of the second relation (the function takes two arguments).+        Logically, the specification can be described by a function++           target = filter_by_negation(pos, neg, columns)++        where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that+        target are elements in x in pos, such that there is no y in neg that agrees with+        x on the columns c1, d1, .., cN, dN.++    +      - Z3_OP_RA_RENAME: rename columns in the relation. +        The function takes one argument.+        The parameters contain the renaming as a cycle.+         +      - Z3_OP_RA_COMPLEMENT: Complement the relation.++      - Z3_OP_RA_SELECT: Check if a record is an element of the relation.+        The function takes \c n+1 arguments, where the first argument is a relation,+        and the remaining \c n arguments correspond to a record.++      - Z3_OP_RA_CLONE: Create a fresh copy (clone) of a relation. +        \conly The function is logically the identity, but+        \conly in the context of a register machine allows +        \conly for #Z3_OP_RA_UNION to perform destructive updates to the first argument.+        ++      - Z3_OP_FD_LT: A less than predicate over the finite domain Z3_FINITE_DOMAIN_SORT.++    *)++*/+typedef enum {+    Z3_OP_TRUE = 0x100,+    Z3_OP_FALSE,+    Z3_OP_EQ,+    Z3_OP_DISTINCT,+    Z3_OP_ITE,+    Z3_OP_AND,+    Z3_OP_OR,+    Z3_OP_IFF,+    Z3_OP_XOR,+    Z3_OP_NOT,+    Z3_OP_IMPLIES,+    Z3_OP_OEQ,+++    Z3_OP_ANUM = 0x200,+    Z3_OP_LE,+    Z3_OP_GE,+    Z3_OP_LT,+    Z3_OP_GT,+    Z3_OP_ADD,+    Z3_OP_SUB,+    Z3_OP_UMINUS,+    Z3_OP_MUL,+    Z3_OP_DIV,+    Z3_OP_IDIV,+    Z3_OP_REM,+    Z3_OP_MOD,+    Z3_OP_TO_REAL,+    Z3_OP_TO_INT,+    Z3_OP_IS_INT,++    Z3_OP_STORE = 0x300,+    Z3_OP_SELECT,+    Z3_OP_CONST_ARRAY,+    Z3_OP_ARRAY_MAP,+    Z3_OP_ARRAY_DEFAULT,+    Z3_OP_SET_UNION,+    Z3_OP_SET_INTERSECT,+    Z3_OP_SET_DIFFERENCE,+    Z3_OP_SET_COMPLEMENT,+    Z3_OP_SET_SUBSET,+    Z3_OP_AS_ARRAY,++    Z3_OP_BNUM = 0x400,+    Z3_OP_BIT1,+    Z3_OP_BIT0,+    Z3_OP_BNEG,+    Z3_OP_BADD,+    Z3_OP_BSUB,+    Z3_OP_BMUL,+    +    Z3_OP_BSDIV,+    Z3_OP_BUDIV,+    Z3_OP_BSREM,+    Z3_OP_BUREM,+    Z3_OP_BSMOD,++    // special functions to record the division by 0 cases+    // these are internal functions +    Z3_OP_BSDIV0, +    Z3_OP_BUDIV0,+    Z3_OP_BSREM0,+    Z3_OP_BUREM0,+    Z3_OP_BSMOD0,+    +    Z3_OP_ULEQ,+    Z3_OP_SLEQ,+    Z3_OP_UGEQ,+    Z3_OP_SGEQ,+    Z3_OP_ULT,+    Z3_OP_SLT,+    Z3_OP_UGT,+    Z3_OP_SGT,++    Z3_OP_BAND,+    Z3_OP_BOR,+    Z3_OP_BNOT,+    Z3_OP_BXOR,+    Z3_OP_BNAND,+    Z3_OP_BNOR,+    Z3_OP_BXNOR,++    Z3_OP_CONCAT,+    Z3_OP_SIGN_EXT,+    Z3_OP_ZERO_EXT,+    Z3_OP_EXTRACT,+    Z3_OP_REPEAT,++    Z3_OP_BREDOR,+    Z3_OP_BREDAND,+    Z3_OP_BCOMP,++    Z3_OP_BSHL,+    Z3_OP_BLSHR,+    Z3_OP_BASHR,+    Z3_OP_ROTATE_LEFT,+    Z3_OP_ROTATE_RIGHT,+    Z3_OP_EXT_ROTATE_LEFT,+    Z3_OP_EXT_ROTATE_RIGHT,++    Z3_OP_INT2BV,+    Z3_OP_BV2INT,+    Z3_OP_CARRY,+    Z3_OP_XOR3,++    Z3_OP_PR_UNDEF = 0x500, +    Z3_OP_PR_TRUE,+    Z3_OP_PR_ASSERTED, +    Z3_OP_PR_GOAL, +    Z3_OP_PR_MODUS_PONENS, +    Z3_OP_PR_REFLEXIVITY, +    Z3_OP_PR_SYMMETRY, +    Z3_OP_PR_TRANSITIVITY, +    Z3_OP_PR_TRANSITIVITY_STAR, +    Z3_OP_PR_MONOTONICITY, +    Z3_OP_PR_QUANT_INTRO,+    Z3_OP_PR_DISTRIBUTIVITY, +    Z3_OP_PR_AND_ELIM, +    Z3_OP_PR_NOT_OR_ELIM, +    Z3_OP_PR_REWRITE, +    Z3_OP_PR_REWRITE_STAR, +    Z3_OP_PR_PULL_QUANT, +    Z3_OP_PR_PULL_QUANT_STAR, +    Z3_OP_PR_PUSH_QUANT, +    Z3_OP_PR_ELIM_UNUSED_VARS, +    Z3_OP_PR_DER, +    Z3_OP_PR_QUANT_INST,+    Z3_OP_PR_HYPOTHESIS, +    Z3_OP_PR_LEMMA, +    Z3_OP_PR_UNIT_RESOLUTION, +    Z3_OP_PR_IFF_TRUE, +    Z3_OP_PR_IFF_FALSE, +    Z3_OP_PR_COMMUTATIVITY, +    Z3_OP_PR_DEF_AXIOM,+    Z3_OP_PR_DEF_INTRO, +    Z3_OP_PR_APPLY_DEF, +    Z3_OP_PR_IFF_OEQ, +    Z3_OP_PR_NNF_POS, +    Z3_OP_PR_NNF_NEG, +    Z3_OP_PR_NNF_STAR, +    Z3_OP_PR_CNF_STAR, +    Z3_OP_PR_SKOLEMIZE,+    Z3_OP_PR_MODUS_PONENS_OEQ, +    Z3_OP_PR_TH_LEMMA, ++    Z3_OP_RA_STORE = 0x600,+    Z3_OP_RA_EMPTY,+    Z3_OP_RA_IS_EMPTY,+    Z3_OP_RA_JOIN,+    Z3_OP_RA_UNION,+    Z3_OP_RA_WIDEN,+    Z3_OP_RA_PROJECT,+    Z3_OP_RA_FILTER,+    Z3_OP_RA_NEGATION_FILTER,+    Z3_OP_RA_RENAME,+    Z3_OP_RA_COMPLEMENT,+    Z3_OP_RA_SELECT,+    Z3_OP_RA_CLONE,+    Z3_OP_FD_LT,+++    Z3_OP_UNINTERPRETED+} Z3_decl_kind;++++/**+   \conly \brief The different kinds of search failure types.++   \conly - Z3_NO_FAILURE:         The last search was successful+   \conly - Z3_UNKNOWN:            Undocumented failure reason+   \conly - Z3_TIMEOUT:            Timeout+   \conly - Z3_MEMOUT_WATERMAK:    Search hit a memory high-watermak limit+   \conly - Z3_CANCELED:           External cancel flag was set+   \conly - Z3_NUM_CONFLICTS:      Maximum number of conflicts was reached+   \conly - Z3_THEORY:             Theory is incomplete+   \conly - Z3_QUANTIFIERS:        Logical context contains universal quantifiers+*/+typedef enum {+    Z3_NO_FAILURE,+    Z3_UNKNOWN,+    Z3_TIMEOUT,+    Z3_MEMOUT_WATERMARK,     +    Z3_CANCELED,      +    Z3_NUM_CONFLICTS, +    Z3_THEORY,        +    Z3_QUANTIFIERS    +} Z3_search_failure;++/**+   \conly \brief Z3 pretty printing modes (See #Z3_set_ast_print_mode).++   \conly - Z3_PRINT_SMTLIB_FULL:   Print AST nodes in SMTLIB verbose format.+   \conly - Z3_PRINT_LOW_LEVEL:     Print AST nodes using a low-level format.+   \conly - Z3_PRINT_SMTLIB_COMPLIANT: Print AST nodes in SMTLIB 1.x compliant format.+   \conly - Z3_PRINT_SMTLIB2_COMPLIANT: Print AST nodes in SMTLIB 2.x compliant format.+*/+typedef enum {+    Z3_PRINT_SMTLIB_FULL,+    Z3_PRINT_LOW_LEVEL,+    Z3_PRINT_SMTLIB_COMPLIANT,+    Z3_PRINT_SMTLIB2_COMPLIANT+} Z3_ast_print_mode;++#ifndef CAMLIDL++/**+   \conly \brief Z3 error codes (See #Z3_get_error_code). +   +   \conly - Z3_OK,            +   \conly - Z3_SORT_ERROR:    User tried to build an invalid (type incorrect) AST.+   \conly - Z3_IOB:           Index out of bounds +   \conly - Z3_INVALID_ARG:   Invalid argument was provided+   \conly - Z3_PARSER_ERROR:  An error occurred when parsing a string or file.+   \conly - Z3_NO_PARSER:     Parser output is not available, that is, user didn't invoke Z3_parse_smtlib_string or Z3_parse_smtlib_file.+   \conly - Z3_INVALID_PATTERN: Invalid pattern was used to build a quantifier.+   \conly - Z3_MEMOUT_FAIL:   A memory allocation failure was encountered.+   \conly - Z3_FILE_ACCESS_ERRROR: A file could not be accessed.+   \conly - Z3_INVALID_USAGE:   API call is invalid in the current state.+   \conly - Z3_INTERNAL_FATAL: An error internal to Z3 occurred. +   \conly - Z3_DEC_REF_ERROR: Trying decrement the reference counter of an AST that was deleted or the reference counter was not initialized with #Z3_inc_ref.+*/+typedef enum+{+    Z3_OK,            +    Z3_SORT_ERROR,    +    Z3_IOB,           +    Z3_INVALID_ARG,   +    Z3_PARSER_ERROR,  +    Z3_NO_PARSER,+    Z3_INVALID_PATTERN,+    Z3_MEMOUT_FAIL,+    Z3_FILE_ACCESS_ERROR,+    Z3_INTERNAL_FATAL,+    Z3_INVALID_USAGE,+    Z3_DEC_REF_ERROR+} Z3_error_code;++++/**+   \conly \brief Z3 custom error handler (See #Z3_set_error_handler). +*/+typedef void Z3_error_handler(Z3_error_code e);+++#endif // CAMLIDL++/*@}*/++#ifndef CAMLIDL+#ifdef __cplusplus+extern "C" {+#endif // __cplusplus+#else+[pointer_default(ref)] interface Z3 {+#endif // CAMLIDL+    +    /** +        @name Create configuration+    */+    /*@{*/++    /**+       \brief Create a configuration.++       Configurations are created in order to assign parameters prior to creating +       contexts for Z3 interaction. For example, if the users whishes to use model+       generation, then call:++       \ccode{Z3_set_param_value(cfg\, "MODEL"\, "true")}++       \mlonly \remark Consider using {!Z3.mk_context_x} instead of using+       explicit configuration objects. The function {!Z3.mk_context_x}+       receives an array of string pairs. This array represents the+       configuration options. \endmlonly++       \sa Z3_set_param_value+       \sa Z3_del_config+    */+    Z3_config Z3_API Z3_mk_config();++    /**+       \brief Delete the given configuration object.++       \sa Z3_mk_config+    */+    void Z3_API Z3_del_config(__in Z3_config c);+    +    /**+       \brief Set a configuration parameter.++       The list of all configuration parameters can be obtained using the Z3 executable:++       \verbatim+       z3.exe -ini?+       \endverbatim++       \sa Z3_mk_config+    */+    void Z3_API Z3_set_param_value(__in Z3_config c, __in_z Z3_string param_id, __in_z Z3_string param_value);+++    /*@}*/++    /**+       @name Create context+    */+    /*@{*/++    /**+       \brief Create a context using the given configuration. +    +       After a context is created, the configuration cannot be changed.+       All main interaction with Z3 happens in the context of a \c Z3_context.++       \mlonly \remark Consider using {!Z3.mk_context_x} instead of using+       explicit configuration objects. The function {!Z3.mk_context_x}+       receives an array of string pairs. This array represents the+       configuration options. \endmlonly++       \sa Z3_del_context+    */+    Z3_context Z3_API Z3_mk_context(__in Z3_config c);++    /**+       \brief Create a context using the given configuration.+       This function is similar to #Z3_mk_context. However,+       in the context returned by this function, the user+       is responsible for managing Z3_ast reference counters.+       Managing reference counters is a burden and error-prone,+       but allows the user to use the memory more efficiently. +       The user must invoke #Z3_inc_ref for any Z3_ast returned+       by Z3, and #Z3_dec_ref whenever the Z3_ast is not needed+       anymore. This idiom is similar to the one used in+       BDD (binary decision diagrams) packages such as CUDD.++       Remark: Z3_sort, Z3_func_decl, Z3_app, Z3_pattern are+       Z3_ast's.+ +       After a context is created, the configuration cannot be changed.+       All main interaction with Z3 happens in the context of a \c Z3_context.+    */+    Z3_context Z3_API Z3_mk_context_rc(__in Z3_config c);++    /**+       \brief Set the SMTLIB logic to be used in the given logical context.+       It is incorrect to invoke this function after invoking+       #Z3_check, #Z3_check_and_get_model, #Z3_check_assumptions and #Z3_push.+       Return \c Z3_TRUE if the logic was changed successfully, and \c Z3_FALSE otherwise.+    */+    Z3_bool Z3_API Z3_set_logic(__in Z3_context c, __in_z Z3_string logic);+    +    /**+       \brief Delete the given logical context.++       \sa Z3_mk_config+    */+    void Z3_API Z3_del_context(__in Z3_context c);+    +    /**+       \brief Increment the reference counter of the given AST.+       The context \c c should have been created using #Z3_mk_context_rc.+       This function is a NOOP if \c c was created using #Z3_mk_context.+    */+    void Z3_API Z3_inc_ref(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Decrement the reference counter of the given AST.+       The context \c c should have been created using #Z3_mk_context_rc.+       This function is a NOOP if \c c was created using #Z3_mk_context.+    */+    void Z3_API Z3_dec_ref(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Enable trace messages to a file++       When trace messages are enabled, Z3 will record the operations performed on a context in the given file file.+       Return \c Z3_TRUE if the file was opened successfully, and \c Z3_FALSE otherwise.++       \sa Z3_trace_off+    */+    Z3_bool Z3_API Z3_trace_to_file(__in Z3_context c, __in_z Z3_string trace_file);++    /**+       \brief Enable trace messages to a standard error.++       \sa Z3_trace_off+    */+    void Z3_API Z3_trace_to_stderr(__in Z3_context c);++    /**+       \brief Enable trace messages to a standard output.++       \sa Z3_trace_off+    */+    void Z3_API Z3_trace_to_stdout(__in Z3_context c);++    /**+       \brief Disable trace messages.++       \sa Z3_trace_to_file+       \sa Z3_trace_to_stdout+       \sa Z3_trace_to_stderr+    */+    void Z3_API Z3_trace_off(__in Z3_context c);++    /**+       \brief Enable/disable printing warning messages to the console.++       Warnings are printed after passing \c true, warning messages are+       suppressed after calling this method with \c false.       +    */+    void Z3_API Z3_toggle_warning_messages(__in Z3_bool enabled);++    /**+       \brief Update a mutable configuration parameter.++       The list of all configuration parameters can be obtained using the Z3 executable:++       \verbatim+       z3.exe -ini?+       \endverbatim++       Only a few configuration parameters are mutable once the context is created.+       The error handler is invoked when trying to modify an immutable parameter.++       \sa Z3_set_param_value+    */+    void Z3_API Z3_update_param_value(__in Z3_context c, __in_z Z3_string param_id, __in_z Z3_string param_value);++    /**+       \brief Get a configuration parameter.+      +       Returns false if the parameter value does not exist.++       \sa Z3_mk_config+       \sa Z3_set_param_value+    */++#ifndef CAMLIDL+    Z3_bool Z3_API Z3_get_param_value(__in Z3_context c, __in_z Z3_string param_id, __out_z Z3_string_ptr param_value);+#endif++    /*@}*/++    /**+       @name Symbols+    */+    /*@{*/+    /**+       \brief Create a Z3 symbol using an integer.++       Symbols are used to name several term and type constructors.++       NB. Not all integers can be passed to this function.+       The legal range of unsigned integers is 0 to 2^30-1.++       \sa Z3_mk_string_symbol+    */+    Z3_symbol Z3_API Z3_mk_int_symbol(__in Z3_context c, __in int i);++    /**+       \brief Create a Z3 symbol using a C string.++       Symbols are used to name several term and type constructors.++       \sa Z3_mk_int_symbol+    */+    Z3_symbol Z3_API Z3_mk_string_symbol(__in Z3_context c, __in_z Z3_string s);+    /*@}*/+    +    +    /**+       @name Sorts+    */+    /*@{*/+    +    /**+       \brief compare sorts.+    */+    Z3_bool Z3_API Z3_is_eq_sort(__in Z3_context c, __in Z3_sort s1, __in Z3_sort s2);++    /**+       \brief Create a free (uninterpreted) type using the given name (symbol).+       +       Two free types are considered the same iff the have the same name.+    */+    Z3_sort Z3_API Z3_mk_uninterpreted_sort(__in Z3_context c, __in Z3_symbol s);+    ++    /**+       \brief Create the Boolean type. ++       This type is used to create propositional variables and predicates.+    */+    Z3_sort Z3_API Z3_mk_bool_sort(__in Z3_context c);+    +    /**+       \brief Create an integer type.++       This type is not the int type found in programming languages.+       A machine integer can be represented using bit-vectors. The function+       #Z3_mk_bv_sort creates a bit-vector type.++       \sa Z3_mk_bv_sort+    */+    Z3_sort Z3_API Z3_mk_int_sort(__in Z3_context c);+    +    /**+       \brief Create a real type. ++       This type is not a floating point number.+       Z3 does not have support for floating point numbers yet.+    */+    Z3_sort Z3_API Z3_mk_real_sort(__in Z3_context c);++    /**+       \brief Create a bit-vector type of the given size.+    +       This type can also be seen as a machine integer.++       \remark The size of the bitvector type must be greater than zero.+    */+    Z3_sort Z3_API Z3_mk_bv_sort(__in Z3_context c, __in unsigned sz);++    /**+       \brief Create an array type. +       +       We usually represent the array type as: <tt>[domain -> range]</tt>.+       Arrays are usually used to model the heap/memory in software verification.++       \sa Z3_mk_select+       \sa Z3_mk_store+    */+    Z3_sort Z3_API Z3_mk_array_sort(__in Z3_context c, __in Z3_sort domain, __in Z3_sort range);++    /**+       \brief Create a tuple type.+       +       \mlonly [mk_tuple_sort c name field_names field_sorts] creates a tuple with a constructor named [name],+       a [n] fields, where [n] is the size of the arrays [field_names] and [field_sorts].+       \endmlonly++       \conly A tuple with \c n fields has a constructor and \c n projections.+       \conly This function will also declare the constructor and projection functions.++       \param c logical context+       \param mk_tuple_name name of the constructor function associated with the tuple type.+       \param num_fields number of fields in the tuple type.+       \param field_names name of the projection functions.+       \param field_sorts type of the tuple fields.+       \param mk_tuple_decl output parameter that will contain the constructor declaration.+       \param proj_decl output parameter that will contain the projection function declarations. This field must be a buffer of size \c num_fields allocated by the user.+    */+    Z3_sort Z3_API Z3_mk_tuple_sort(__in Z3_context c, +                                        __in Z3_symbol mk_tuple_name, +                                        __in unsigned num_fields, +                                        __in_ecount(num_fields) Z3_symbol   const field_names[],+                                        __in_ecount(num_fields) Z3_sort const field_sorts[],+                                        __out Z3_func_decl * mk_tuple_decl,+                                        __out_ecount(num_fields)  Z3_func_decl proj_decl[]);++    /**+       \brief Create a enumeration sort.+       +       \mlonly [mk_enumeration_sort c enums] creates an enumeration sort with enumeration names [enums], +               it also returns [n] predicates, where [n] is the number of [enums] corresponding+               to testing whether an element is one of the enumerants.+       \endmlonly++       \conly An enumeration sort with \c n elements.+       \conly This function will also declare the functions corresponding to the enumerations.++       \param c logical context+       \param name name of the enumeration sort.+       \param n number of elemenets in enumeration sort.+       \param enum_names names of the enumerated elements.+       \param enum_consts constants corresponding to the enumerated elements.+       \param enum_testers predicates testing if terms of the enumeration sort correspond to an enumeration.+    */+    Z3_sort Z3_API Z3_mk_enumeration_sort(__in Z3_context c, +                                          __in Z3_symbol name,+                                          __in unsigned n,+                                          __in_ecount(n)  Z3_symbol  const enum_names[],+                                          __out_ecount(n) Z3_func_decl enum_consts[],+                                          __out_ecount(n) Z3_func_decl enum_testers[]);++    /**+       \brief Create a list sort+       +       \mlonly [mk_list_sort c name elem_sort] creates a list sort of [name], over elements of sort [elem_sort].+       \endmlonly++       \conly A list sort over \c elem_sort +       \conly This function declares the corresponding constructors and testers for lists.++       \param c logical context+       \param name name of the list sort.+       \param elem_sort sort of list elements.+       \param nil_decl declaration for the empty list.+       \param is_nil_decl test for the empty list.+       \param cons_decl declaration for a cons cell.+       \param is_cons_decl cons cell test.+       \param head_decl list head.+       \param tail_decl list tail.+    */++    Z3_sort Z3_API Z3_mk_list_sort(__in Z3_context c,+                                   __in Z3_symbol name,+                                   __in Z3_sort   elem_sort,+                                   __out Z3_func_decl* nil_decl,+                                   __out Z3_func_decl* is_nil_decl,+                                   __out Z3_func_decl* cons_decl,+                                   __out Z3_func_decl* is_cons_decl,+                                   __out Z3_func_decl* head_decl,+                                   __out Z3_func_decl* tail_decl+                                   );++    /**+       \brief Create a constructor.+       +       \param c logical context.+       \param name constructor name.+       \param recognizer name of recognizer function.+       \param num_fields number of fields in constructor.+       \param field_names names of the constructor fields.+       \param sorts field sorts, 0 if the field sort refers to a recursive sort.+       \param sort_refs reference to datatype sort that is an argument to the constructor; if the corresponding+                        sort reference is 0, then the value in sort_refs should be an index referring to +                        one of the recursive datatypes that is declared.                        +    */++    Z3_constructor Z3_API Z3_mk_constructor(__in Z3_context c,+                                            __in Z3_symbol name,+                                            __in Z3_symbol recognizer,+                                            __in unsigned num_fields,+                                            __in_ecount(num_fields) Z3_symbol const field_names[],+                                            __in_ecount(num_fields) Z3_sort const sorts[],+                                            __in_ecount(num_fields) unsigned sort_refs[]+                                            );++    /**+       \brief Query constructor for declared funcions.+       +       \param c logical context.+       \param constr constructor container. The container must have been passed in to a #Z3_mk_datatype call.+       \param num_fields number of accessor fields in the constructor.+       \param constructor constructor function declaration.+       \param tester constructor test function declaration.+       \param accessors array of accessor function declarations.+    */++    void Z3_API Z3_query_constructor(__in Z3_context c,+                                     __in Z3_constructor constr,+                                     __in unsigned num_fields,+                                     __out Z3_func_decl* constructor,+                                     __out Z3_func_decl* tester,+                                     __out_ecount(num_fields) Z3_func_decl accessors[]);+    +    /**+       \brief Reclaim memory allocated to constructor.++       \param c logical context.+       \param constr constructor.+    */+       +    void Z3_API Z3_del_constructor(__in Z3_context c, __in Z3_constructor constr);++    /**+       \brief Create recursive datatype. Return the datatype sort.++       \param c logical context.+	   \param name name of datatype.+       \param num_constructors number of constructors passed in.+       \param constructors array of constructor containers.+    */++    Z3_sort Z3_API Z3_mk_datatype(__in Z3_context c,+                                  __in Z3_symbol name,+                                  __in unsigned num_constructors,+                                  __inout_ecount(num_constructors) Z3_constructor constructors[]);+++    /**+       \brief Create list of constructors.++       \param c logical context.+       \param num_constructors number of constructors in list.+       \param constructors list of constructors.+    */++    Z3_constructor_list Z3_API Z3_mk_constructor_list(__in Z3_context c,+                                                      __in unsigned num_constructors,+                                                      __in_ecount(num_constructors) Z3_constructor constructors[]);++    /**+       \brief reclaim memory allocated for constructor list.++       Each constructor inside the constructor list must be independently reclaimed using #Z3_del_constructor.++       \param c logical context.+       \param clist constructor list container.++    */++    void Z3_API Z3_del_constructor_list(__in Z3_context c, __in Z3_constructor_list clist);+                                        +    /**+       \brief Create mutually recursive datatypes.++       \param c logical context.+       \param num_sorts number of datatype sorts.+       \param sort_names names of datatype sorts.+       \param sorts array of datattype sorts.+       \param constructor_lists list of constructors, one list per sort.+    */++    void Z3_API Z3_mk_datatypes(__in Z3_context c,+                                __in unsigned num_sorts,+                                __in_ecount(num_sorts) Z3_symbol sort_names[],+                                __out_ecount(num_sorts) Z3_sort sorts[],+                                __inout_ecount(num_sorts) Z3_constructor_list constructor_lists[]);+    +    /*@}*/+++++    /**+       @name Injective functions+    */+    /*@{*/+    ++    /**+       \brief Create injective function declaration+    */+    Z3_func_decl Z3_API Z3_mk_injective_function(+        __in Z3_context c, +        __in Z3_symbol s, +        unsigned domain_size, __in_ecount(domain_size) Z3_sort const domain[],+        __in Z3_sort range+        );++    /*@}*/++    /**+       @name Constants and Applications+     */+    /*@{*/++    /**+       \brief compare terms.+    */+    Z3_bool Z3_API Z3_is_eq_ast(__in Z3_context c, __in Z3_ast t1, Z3_ast t2);+++    /**+       \brief compare terms.+    */+    Z3_bool Z3_API Z3_is_eq_func_decl(__in Z3_context c, __in Z3_func_decl f1, Z3_func_decl f2);+++    /**+       \brief Declare a constant or function.++       \mlonly [mk_func_decl c n d r] creates a function with name [n], domain [d], and range [r].+       The arity of the function is the size of the array [d]. \endmlonly++       \param c logical context.+       \param s name of the constant or function.+       \param domain_size number of arguments. It is 0 when declaring a constant.+       \param domain array containing the sort of each argument. The array must contain domain_size elements. It is 0 whe declaring a constant.+       \param range sort of the constant or the return sort of the function.++       After declaring a constant or function, the function+       #Z3_mk_app can be used to create a constant or function+       application.++       \sa Z3_mk_app+    */+    Z3_func_decl Z3_API Z3_mk_func_decl(__in Z3_context c, __in Z3_symbol s,+                                        __in unsigned domain_size, __in_ecount(domain_size) Z3_sort const domain[],+                                        __in Z3_sort range);++    +    /**+       \brief Create a constant or function application.++       \sa Z3_mk_func_decl+    */+    Z3_ast Z3_API Z3_mk_app(+        __in Z3_context c, +        __in Z3_func_decl d,+        __in unsigned num_args, +        __in_ecount(num_args) Z3_ast const args[]);++    /**+       \brief Declare and create a constant.+       +       \conly This function is a shorthand for:+       \conly \code+       \conly Z3_func_decl d = Z3_mk_func_decl(c, s, 0, 0, ty);+       \conly Z3_ast n            = Z3_mk_app(c, d, 0, 0);+       \conly \endcode+       +       \mlonly [mk_const c s t] is a shorthand for [mk_app c (mk_func_decl c s [||] t) [||]] \endmlonly++       \sa Z3_mk_func_decl+       \sa Z3_mk_app+    */+    Z3_ast Z3_API Z3_mk_const(__in Z3_context c, __in Z3_symbol s, __in Z3_sort ty);++    /**+       \brief Create a labeled formula.++       \param c logical context.+       \param s name of the label.+       \param is_pos label polarity.+       \param f formula being labeled.++       A label behaves as an identity function, so the truth value of the +       labeled formula is unchanged. Labels are used for identifying +       useful sub-formulas when generating counter-examples.+    */+    Z3_ast Z3_API Z3_mk_label(__in Z3_context c, __in Z3_symbol s, Z3_bool is_pos, Z3_ast f);++    /**+       \brief Declare a fresh constant or function.++       Z3 will generate an unique name for this function declaration.+       \conly If prefix is different from \c NULL, then the name generate by Z3 will start with \c prefix.+       +       \conly \remark If \c prefix is NULL, then it is assumed to be the empty string.++       \sa Z3_mk_func_decl+    */+    Z3_func_decl Z3_API Z3_mk_fresh_func_decl(__in Z3_context c, __in_z Z3_string prefix,+                                                   __in unsigned domain_size, __in_ecount(domain_size) Z3_sort const domain[],+                                                   __in Z3_sort range);+    +    /**+       \brief Declare and create a fresh constant.+       +       \conly This function is a shorthand for:+       \conly \code Z3_func_decl d = Z3_mk_fresh_func_decl(c, prefix, 0, 0, ty); Z3_ast n = Z3_mk_app(c, d, 0, 0); \endcode++       \mlonly [mk_fresh_const c p t] is a shorthand for [mk_app c (mk_fresh_func_decl c p [||] t) [||]]. \endmlonly++       \conly \remark If \c prefix is NULL, then it is assumed to be the empty string.+       +       \sa Z3_mk_func_decl+       \sa Z3_mk_app+    */+    Z3_ast Z3_API Z3_mk_fresh_const(__in Z3_context c, __in_z Z3_string prefix, __in Z3_sort ty);++    +    /** +        \brief Create an AST node representing \c true.+    */+    Z3_ast Z3_API Z3_mk_true(__in Z3_context c);++    /** +        \brief Create an AST node representing \c false.+    */+    Z3_ast Z3_API Z3_mk_false(__in Z3_context c);+    +    /** +        \brief \mlh mk_eq c l r \endmlh+        Create an AST node representing <tt>l = r</tt>.+        +        The nodes \c l and \c r must have the same type. +    */+    Z3_ast Z3_API Z3_mk_eq(__in Z3_context c, __in Z3_ast l, __in Z3_ast r);+    +    /**+       \conly \brief Create an AST node representing <tt>distinct(args[0], ..., args[num_args-1])</tt>.+       \mlonly \brief \[ [mk_distinct c [| t_1; ...; t_n |]] \] Create an AST+       node represeting a distinct construct. It is used for declaring+       the arguments t_i pairwise distinct. \endmlonly++       \conly The \c distinct construct is used for declaring the arguments pairwise distinct. +       \conly That is, <tt>Forall 0 <= i < j < num_args. not args[i] = args[j]</tt>.+       +       All arguments must have the same sort.++       \remark The number of arguments of a distinct construct must be greater than one.+    */+    Z3_ast Z3_API Z3_mk_distinct(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);++    /** +        \brief \mlh mk_not c a \endmlh +        Create an AST node representing <tt>not(a)</tt>.+        +        The node \c a must have Boolean sort.+    */+    Z3_ast Z3_API Z3_mk_not(__in Z3_context c, __in Z3_ast a);+    +    /**+       \brief \mlh mk_ite c t1 t2 t2 \endmlh +       Create an AST node representing an if-then-else: <tt>ite(t1, t2,+       t3)</tt>.++       The node \c t1 must have Boolean sort, \c t2 and \c t3 must have the same sort.+       The sort of the new node is equal to the sort of \c t2 and \c t3.+    */+    Z3_ast Z3_API Z3_mk_ite(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, __in Z3_ast t3);++    /**+       \brief \mlh mk_iff c t1 t2 \endmlh+       Create an AST node representing <tt>t1 iff t2</tt>.++       The nodes \c t1 and \c t2 must have Boolean sort.+    */+    Z3_ast Z3_API Z3_mk_iff(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_implies c t1 t2 \endmlh+       Create an AST node representing <tt>t1 implies t2</tt>.++       The nodes \c t1 and \c t2 must have Boolean sort.+    */+    Z3_ast Z3_API Z3_mk_implies(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \brief \mlh mk_xor c t1 t2 \endmlh+       Create an AST node representing <tt>t1 xor t2</tt>.++       The nodes \c t1 and \c t2 must have Boolean sort.+    */+    Z3_ast Z3_API Z3_mk_xor(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \conly \brief Create an AST node representing <tt>args[0] and ... and args[num_args-1]</tt>.+       \mlonly \brief \[ [mk_and c [| t_1; ...; t_n |]] \] Create the conjunction: {e t_1 and ... and t_n}. \endmlonly++       \conly The array \c args must have \c num_args elements. +       All arguments must have Boolean sort.+       +       \remark The number of arguments must be greater than zero.+    */+    Z3_ast Z3_API Z3_mk_and(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);+    +    /**+       \conly \brief Create an AST node representing <tt>args[0] or ... or args[num_args-1]</tt>.+       \mlonly \brief \[ [mk_or c [| t_1; ...; t_n |]] \] Create the disjunction: {e t_1 or ... or t_n}. \endmlonly++       \conly The array \c args must have \c num_args elements. +       All arguments must have Boolean sort.++       \remark The number of arguments must be greater than zero.+    */+    Z3_ast Z3_API Z3_mk_or(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);+    +    /**+       \conly \brief Create an AST node representing <tt>args[0] + ... + args[num_args-1]</tt>.+       \mlonly \brief \[ [mk_add c [| t_1; ...; t_n |]] \] Create the term: {e t_1 + ... + t_n}. \endmlonly++       \conly The array \c args must have \c num_args elements. +       All arguments must have int or real sort.++       \remark The number of arguments must be greater than zero.+    */+    Z3_ast Z3_API Z3_mk_add(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);+    +    /**+       \conly \brief Create an AST node representing <tt>args[0] * ... * args[num_args-1]</tt>.+       \mlonly \brief \[ [mk_mul c [| t_1; ...; t_n |]] \] Create the term: {e t_1 * ... * t_n}. \endmlonly++       \conly The array \c args must have \c num_args elements. +       All arguments must have int or real sort.+       +       \remark Z3 has limited support for non-linear arithmetic.+       \remark The number of arguments must be greater than zero.+    */+    Z3_ast Z3_API Z3_mk_mul(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);+    +    /**+       \conly \brief Create an AST node representing <tt>args[0] - ... - args[num_args - 1]</tt>.+       \mlonly \brief \[ [mk_sub c [| t_1; ...; t_n |]] \] Create the term: {e t_1 - ... - t_n}. \endmlonly++       \conly The array \c args must have \c num_args elements. +       All arguments must have int or real sort.++       \remark The number of arguments must be greater than zero.+    */+    Z3_ast Z3_API Z3_mk_sub(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);++    /**+       \conly \brief Create an AST node representing <tt>-arg</tt>.+       \mlonly \brief \[ [mk_unary_minus c arg] \] Create the term: {e - arg}. \endmlonly++       The argument must have int or real type.++    */+    Z3_ast Z3_API Z3_mk_unary_minus(__in Z3_context c, __in Z3_ast arg);+++    /**+       \conly \brief Create an AST node representing <tt>arg1 div arg2</tt>.+       \mlonly \brief \[ [mk_div c t_1 t_2] \] Create the term: {e t_1 div t_2}. \endmlonly++       The arguments must either both have int type or both have real type.+       If the arguments have int type, then the result type is an int type, otherwise the+       the result type is real.++    */+    Z3_ast Z3_API Z3_mk_div(__in Z3_context c, __in Z3_ast arg1, __in Z3_ast arg2);+++    /**+       \conly \brief Create an AST node representing <tt>arg1 mod arg2</tt>.+       \mlonly \brief \[ [mk_mod c t_1 t_2] \] Create the term: {e t_1 mod t_2}. \endmlonly++       The arguments must have int type.++    */+    Z3_ast Z3_API Z3_mk_mod(__in Z3_context c, __in Z3_ast arg1, __in Z3_ast arg2);++    /**+       \conly \brief Create an AST node representing <tt>arg1 rem arg2</tt>.+       \mlonly \brief \[ [mk_rem c t_1 t_2] \] Create the term: {e t_1 rem t_2}. \endmlonly++       The arguments must have int type.++    */+    Z3_ast Z3_API Z3_mk_rem(__in Z3_context c, __in Z3_ast arg1, __in Z3_ast arg2);++    /** +        \brief \mlh mk_lt c t1 t2 \endmlh +        Create less than.++        The nodes \c t1 and \c t2 must have the same sort, and must be int or real.+    */+    Z3_ast Z3_API Z3_mk_lt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_le c t1 t2 \endmlh+        Create less than or equal to.+        +        The nodes \c t1 and \c t2 must have the same sort, and must be int or real.+    */+    Z3_ast Z3_API Z3_mk_le(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_gt c t1 t2 \endmlh+        Create greater than.+        +        The nodes \c t1 and \c t2 must have the same sort, and must be int or real.+    */+    Z3_ast Z3_API Z3_mk_gt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_ge c t1 t2 \endmlh+        Create greater than or equal to.+        +        The nodes \c t1 and \c t2 must have the same sort, and must be int or real.+    */+    Z3_ast Z3_API Z3_mk_ge(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_int2real c t1 \endmlh+        Coerce an integer to a real.++        There is also a converse operation exposed.+        It follows the semantics prescribed by the SMT-LIB standard.++        You can take the floor of a real by +        creating an auxiliary integer constant \c k and+        and asserting <tt> mk_int2real(k) <= t1 < mk_int2real(k)+1</tt>.+        +        The node \c t1 must have sort integer.++        \sa Z3_mk_real2int+        \sa Z3_mk_is_int+    */+    Z3_ast Z3_API Z3_mk_int2real(__in Z3_context c, __in Z3_ast t1);++    /** +        \brief \mlh mk_real2int c t1 \endmlh+        Coerce a real to an integer.++        The semantics of this function follows the SMT-LIB standard+        for the function to_int++        \sa Z3_mk_int2real+        \sa Z3_mk_is_int+    */+    Z3_ast Z3_API Z3_mk_real2int(__in Z3_context c, __in Z3_ast t1);++    /** +        \brief \mlh mk_is_int c t1 \endmlh+        Check if a real number is an integer.++        \sa Z3_mk_int2real+        \sa Z3_mk_real2int+    */+    Z3_ast Z3_API Z3_mk_is_int(__in Z3_context c, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvnot c t1 \endmlh+       Bitwise negation.++       The node \c t1 must have a bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvnot(__in Z3_context c, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvredand c t1 \endmlh+       Take conjunction of bits in vector, return vector of length 1.++       The node \c t1 must have a bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvredand(__in Z3_context c, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvredor c t1 \endmlh+       Take disjunction of bits in vector, return vector of length 1.++       The node \c t1 must have a bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvredor(__in Z3_context c, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvand c t1 t2 \endmlh+       Bitwise and.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvand(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvor c t1 t2 \endmlh+       Bitwise or.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvor(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvxor c t1 t2 \endmlh+       Bitwise exclusive-or.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvxor(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvnand c t1 t2 \endmlh+       Bitwise nand. ++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvnand(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvnor c t1 t2 \endmlh+       Bitwise nor. ++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvnor(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvxnor c t1 t2 \endmlh+       Bitwise xnor. +       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvxnor(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvneg c t1 \endmlh+       Standard two's complement unary minus. ++       The node \c t1 must have bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvneg(__in Z3_context c, __in Z3_ast t1);+    +    /** +        \brief \mlh mk_bvadd c t1 t2 \endmlh+        Standard two's complement addition.+        +        The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvadd(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_bvsub c t1 t2 \endmlh+        Standard two's complement subtraction.+        +        The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsub(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /** +        \brief \mlh mk_bvmul c t1 t2 \endmlh+        Standard two's complement multiplication.+        +        The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvmul(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_bvudiv c t1 t2 \endmlh+        Unsigned division. ++        It is defined as the \c floor of <tt>t1/t2</tt> if \c t2 is+        different from zero. If <tt>t2</tt> is zero, then the result+        is undefined.+        +        The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvudiv(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /** +        \brief \mlh mk_bvsdiv c t1 t2 \endmlh+        Two's complement signed division. ++        It is defined in the following way:++        - The \c floor of <tt>t1/t2</tt> if \c t2 is different from zero, and <tt>t1*t2 >= 0</tt>.++        - The \c ceiling of <tt>t1/t2</tt> if \c t2 is different from zero, and <tt>t1*t2 < 0</tt>.+        +        If <tt>t2</tt> is zero, then the result is undefined.+        +        The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsdiv(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvurem c t1 t2 \endmlh+       Unsigned remainder.++       It is defined as <tt>t1 - (t1 /u t2) * t2</tt>, where <tt>/u</tt> represents unsigned division.+       +       If <tt>t2</tt> is zero, then the result is undefined.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvurem(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsrem c t1 t2 \endmlh+       Two's complement signed remainder (sign follows dividend).++       It is defined as <tt>t1 - (t1 /s t2) * t2</tt>, where <tt>/s</tt> represents signed division.+       The most significant bit (sign) of the result is equal to the most significant bit of \c t1.++       If <tt>t2</tt> is zero, then the result is undefined.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.++       \sa Z3_mk_bvsmod+    */+    Z3_ast Z3_API Z3_mk_bvsrem(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsmod c t1 t2 \endmlh+       Two's complement signed remainder (sign follows divisor).+       +       If <tt>t2</tt> is zero, then the result is undefined.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.++       \sa Z3_mk_bvsrem+    */+    Z3_ast Z3_API Z3_mk_bvsmod(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvult c t1 t2 \endmlh+       Unsigned less than.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvult(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \brief \mlh mk_bvslt c t1 t2 \endmlh+       Two's complement signed less than.+       +       It abbreviates:+       \code+      (or (and (= (extract[|m-1|:|m-1|] t1) bit1)+               (= (extract[|m-1|:|m-1|] t2) bit0))+          (and (= (extract[|m-1|:|m-1|] t1) (extract[|m-1|:|m-1|] t2))+               (bvult t1 t2)))+       \endcode++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvslt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvule c t1 t2 \endmlh+       Unsigned less than or equal to.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvule(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsle c t1 t2 \endmlh+       Two's complement signed less than or equal to.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsle(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvuge c t1 t2 \endmlh+       Unsigned greater than or equal to.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvuge(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsge c t1 t2 \endmlh+       Two's complement signed greater than or equal to.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsge(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvugt c t1 t2 \endmlh+       Unsigned greater than.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvugt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsgt c t1 t2 \endmlh+       Two's complement signed greater than.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsgt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_concat c t1 t2 \endmlh+       Concatenate the given bit-vectors.+       +       The nodes \c t1 and \c t2 must have (possibly different) bit-vector sorts++       The result is a bit-vector of size <tt>n1+n2</tt>, where \c n1 (\c n2) is the size+       of \c t1 (\c t2).+    */+    Z3_ast Z3_API Z3_mk_concat(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \brief \mlh mk_extract c high low t1 \endmlh+       Extract the bits \c high down to \c low from a bitvector of+       size \c m to yield a new bitvector of size \c n, where <tt>n =+       high - low + 1</tt>.++       The node \c t1 must have a bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_extract(__in Z3_context c, __in unsigned high, __in unsigned low, __in Z3_ast t1);++    /**+       \brief \mlh mk_sign_ext c i t1 \endmlh+       Sign-extend of the given bit-vector to the (signed) equivalent bitvector of+       size <tt>m+i</tt>, where \c m is the size of the given+       bit-vector.++       The node \c t1 must have a bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_sign_ext(__in Z3_context c, __in unsigned i, __in Z3_ast t1);++    /**+       \brief \mlh mk_zero_ext c i t1 \endmlh+       Extend the given bit-vector with zeros to the (unsigned) equivalent+       bitvector of size <tt>m+i</tt>, where \c m is the size of the+       given bit-vector.+       +       The node \c t1 must have a bit-vector sort. +    */+    Z3_ast Z3_API Z3_mk_zero_ext(__in Z3_context c, __in unsigned i, __in Z3_ast t1);++    /**+       \brief \mlh mk_repeat c i t1 \endmlh+       Repeat the given bit-vector up length <tt>i</tt>.+       +       The node \c t1 must have a bit-vector sort. +    */+    Z3_ast Z3_API Z3_mk_repeat(__in Z3_context c, __in unsigned i, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvshl c t1 t2 \endmlh+       Shift left.++       It is equivalent to multiplication by <tt>2^x</tt> where \c x is the value of the+       third argument.++       NB. The semantics of shift operations varies between environments. This +       definition does not necessarily capture directly the semantics of the +       programming language or assembly architecture you are modeling.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvshl(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvlshr c t1 t2 \endmlh+       Logical shift right.++       It is equivalent to unsigned division by <tt>2^x</tt> where \c x is the+       value of the third argument.++       NB. The semantics of shift operations varies between environments. This +       definition does not necessarily capture directly the semantics of the +       programming language or assembly architecture you are modeling.++       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvlshr(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvashr c t1 t2 \endmlh+       Arithmetic shift right.+       +       It is like logical shift right except that the most significant+       bits of the result always copy the most significant bit of the+       second argument.++       NB. The semantics of shift operations varies between environments. This +       definition does not necessarily capture directly the semantics of the +       programming language or assembly architecture you are modeling.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvashr(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \brief \mlh mk_rotate_left c i t1 \endmlh+       Rotate bits of \c t1 to the left \c i times.+       +       The node \c t1 must have a bit-vector sort. +    */+    Z3_ast Z3_API Z3_mk_rotate_left(__in Z3_context c, __in unsigned i, __in Z3_ast t1);+    +    /**+       \brief \mlh mk_rotate_right c i t1 \endmlh+       Rotate bits of \c t1 to the right \c i times.+       +       The node \c t1 must have a bit-vector sort. +    */+    Z3_ast Z3_API Z3_mk_rotate_right(__in Z3_context c, __in unsigned i, __in Z3_ast t1);++    /**+       \brief \mlh mk_ext_rotate_left c t1 t2 \endmlh+       Rotate bits of \c t1 to the left \c t2 times.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_ext_rotate_left(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_ext_rotate_right c t1 t2 \endmlh+       Rotate bits of \c t1 to the right \c t2 times.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_ext_rotate_right(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);+    +    /**+       \brief \mlh mk_int2bv c n t1 \endmlh+       Create an \c n bit bit-vector from the integer argument \c t1.++       NB. This function is essentially treated as uninterpreted. +       So you cannot expect Z3 to precisely reflect the semantics of this function+       when solving constraints with this function.+       +       The node \c t1 must have integer sort. +    */+    Z3_ast Z3_API Z3_mk_int2bv(__in Z3_context c, __in unsigned n, __in Z3_ast t1);++    /**+       \brief \mlh mk_bv2int c t1 is_signed \endmlh+       Create an integer from the bit-vector argument \c t1.+       If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. +       So the result is non-negative+       and in the range <tt>[0..2^N-1]</tt>, where N are the number of bits in \c t1.+       If \c is_signed is true, \c t1 is treated as a signed bit-vector.++       NB. This function is essentially treated as uninterpreted. +       So you cannot expect Z3 to precisely reflect the semantics of this function+       when solving constraints with this function.++       The node \c t1 must have a bit-vector sort. +    */+    Z3_ast Z3_API Z3_mk_bv2int(__in Z3_context c,__in Z3_ast t1, Z3_bool is_signed);++    /**+       \brief \mlh mk_bvadd_no_overflow c t1 t2 is_signed \endmlh+       Create a predicate that checks that the bit-wise addition+       of \c t1 and \c t2 does not overflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvadd_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, Z3_bool is_signed);++    /**+       \brief \mlh mk_bvadd_no_underflow c t1 t2 \endmlh+       Create a predicate that checks that the bit-wise signed addition+       of \c t1 and \c t2 does not underflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvadd_no_underflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsub_no_overflow c t1 t2 \endmlh+       Create a predicate that checks that the bit-wise signed subtraction+       of \c t1 and \c t2 does not overflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsub_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvsub_no_underflow c t1 t2 is_signed \endmlh+       Create a predicate that checks that the bit-wise subtraction+       of \c t1 and \c t2 does not underflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsub_no_underflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, Z3_bool is_signed);++    /**+       \brief \mlh mk_bvsdiv_no_overflow c t1 t2 \endmlh+       Create a predicate that checks that the bit-wise signed division +       of \c t1 and \c t2 does not overflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_bvneg_no_overflow c t1 \endmlh+       Check that bit-wise negation does not overflow when +       \c t1 is interpreted as a signed bit-vector.+       +       The node \c t1 must have bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvneg_no_overflow(__in Z3_context c, __in Z3_ast t1);++    /**+       \brief \mlh mk_bvmul_no_overflow c t1 t2 is_signed \endmlh+       Create a predicate that checks that the bit-wise multiplication+       of \c t1 and \c t2 does not overflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvmul_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, Z3_bool is_signed);++    /**+       \brief \mlh mk_bvmul_no_underflow c t1 t2 \endmlh+       Create a predicate that checks that the bit-wise signed multiplication+       of \c t1 and \c t2 does not underflow.+       +       The nodes \c t1 and \c t2 must have the same bit-vector sort.+    */+    Z3_ast Z3_API Z3_mk_bvmul_no_underflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2);++    /**+       \brief \mlh mk_select c a i \endmlh+       Array read.++       The node \c a must have an array sort <tt>[domain -> range]</tt>, and \c i must have the sort \c domain.+       The sort of the result is \c range.++       \sa Z3_mk_array_sort+       \sa Z3_mk_store+    */+    Z3_ast Z3_API Z3_mk_select(__in Z3_context c, __in Z3_ast a, __in Z3_ast i);+    +    /**+       \brief \mlh mk_store c a i v \endmlh+       Array update.+       +       The node \c a must have an array sort <tt>[domain -> range]</tt>, \c i must have sort \c domain,+       \c v must have sort range. The sort of the result is <tt>[domain -> range]</tt>.+       +       \sa Z3_mk_array_sort+       \sa Z3_mk_select+    */+    Z3_ast Z3_API Z3_mk_store(__in Z3_context c, __in Z3_ast a, __in Z3_ast i, __in Z3_ast v);++    /** +        \brief Create the constant array.++        \param c logical context.+        \param domain domain sort for the array.+        \param v value that the array maps to.+    */+    Z3_ast Z3_API Z3_mk_const_array(__in Z3_context c, __in Z3_sort domain, __in Z3_ast v);++    /**+       \brief \mlh mk_map f n args \endmlh+       map f on the the argument arrays.+       +       The \c n nodes \c args must be of array sorts <tt>[domain_i -> range_i]</tt>.+       The function declaration \c f must have type <tt> range_1 .. range_n -> range</tt>.+       \c v must have sort range. The sort of the result is <tt>[domain_i -> range]</tt>.+       +       \sa Z3_mk_array_sort+       \sa Z3_mk_store+       \sa Z3_mk_select+    */+    Z3_ast Z3_API Z3_mk_map(__in Z3_context c, __in Z3_func_decl f, unsigned n, __in Z3_ast const* args);++    /** +        \brief Access the array default value.+        Produces the default range value, for arrays that can be represented as +        finite maps with a default range value.++        \param c logical context.+        \param array array value whose default range value is accessed.++    */+    Z3_ast Z3_API Z3_mk_array_default(__in Z3_context c, __in Z3_ast array);+++    /*@}*/++    /**+       @name Sets+    */+    /*@{*/++    /**+       \brief Create Set type.+    */+    Z3_sort Z3_API Z3_mk_set_sort(__in Z3_context c, __in Z3_sort ty);++    /** +        \brief Create the empty set.+    */+    Z3_ast Z3_API Z3_mk_empty_set(__in Z3_context c, __in Z3_sort domain);++    /** +        \brief Create the full set.+    */+    Z3_ast Z3_API Z3_mk_full_set(__in Z3_context c, __in Z3_sort domain);++    /**+       \brief Add an element to a set.+       +       The first argument must be a set, the second an element.+    */+    Z3_ast Z3_API Z3_mk_set_add(__in Z3_context c, __in Z3_ast set, __in Z3_ast elem);++    /**+       \brief Remove an element to a set.+       +       The first argument must be a set, the second an element.+    */+    Z3_ast Z3_API Z3_mk_set_del(__in Z3_context c, __in Z3_ast set, __in Z3_ast elem);++    /**+       \brief Take the union of a list of sets.+    */+    Z3_ast Z3_API Z3_mk_set_union(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);++    /**+       \brief Take the intersection of a list of sets.+    */+    Z3_ast Z3_API Z3_mk_set_intersect(__in Z3_context c, __in unsigned num_args, __in_ecount(num_args) Z3_ast const args[]);++    /**+       \brief Take the set difference between two sets.+    */+    Z3_ast Z3_API Z3_mk_set_difference(__in Z3_context c, __in Z3_ast arg1, __in Z3_ast arg2);++    /**+       \brief Take the complement of a set.+    */+    Z3_ast Z3_API Z3_mk_set_complement(__in Z3_context c, __in Z3_ast arg);+++    /**+       \brief Check for set membership.+       +       The first argument should be an element type of the set.+    */+    Z3_ast Z3_API Z3_mk_set_member(__in Z3_context c, __in Z3_ast elem, __in Z3_ast set);++    /**+       \brief Check for subsetness of sets.+    */+    Z3_ast Z3_API Z3_mk_set_subset(__in Z3_context c, __in Z3_ast arg1, __in Z3_ast arg2);+    /*@}*/++    /**+       @name Numerals+    */+    /*@{*/++    /**+       \brief Create a numeral of a given sort. ++       \param c logical context.+       \param numeral A string representing the numeral value in decimal notation. If the given sort is a real, then the numeral can be a rational, that is, a string of the form <tt>[num]* / [num]*</tt>.+       \param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. +       +       \sa Z3_mk_int+       \sa Z3_mk_unsigned_int+    */+    Z3_ast Z3_API Z3_mk_numeral(__in Z3_context c, __in_z Z3_string numeral, __in Z3_sort ty);++    /**+       \brief Create a real from a fraction.++       \param c logical context.+       \param num numerator of rational.+       \param den denomerator of rational.++       \pre den != 0++       \sa Z3_mk_numeral+       \sa Z3_mk_int+       \sa Z3_mk_unsigned_int+    */+    Z3_ast Z3_API Z3_mk_real(__in Z3_context c, __in_z int num, __in_z int den);+    +    /**+       \brief Create a numeral of a given sort. +       +       This function can be use to create numerals that fit in a machine integer.+       It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.++       \sa Z3_mk_numeral+    */+    Z3_ast Z3_API Z3_mk_int(__in Z3_context c, __in int v, __in Z3_sort ty);+    +    /**+       \brief Create a numeral of a given sort. +       +       This function can be use to create numerals that fit in a machine unsinged integer.+       It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.++       \sa Z3_mk_numeral+    */+    Z3_ast Z3_API Z3_mk_unsigned_int(__in Z3_context c, __in unsigned v, __in Z3_sort ty);++#ifndef CAMLIDL+    /**+       \brief Create a numeral of a given sort. +       +       This function can be use to create numerals that fit in a machine __int64 integer.+       It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.++       \sa Z3_mk_numeral+    */+    Z3_ast Z3_API Z3_mk_int64(__in Z3_context c, __in __int64 v, __in Z3_sort ty);+#endif // CAMLIDL++#ifndef CAMLIDL+    /**+       \brief Create a numeral of a given sort. +       +       This function can be use to create numerals that fit in a machine unsigned __int64 integer.+       It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.++       \sa Z3_mk_numeral+    */+    Z3_ast Z3_API Z3_mk_unsigned_int64(__in Z3_context c, __in unsigned __int64 v, __in Z3_sort ty);+#endif // CAMLIDL++    /*@}*/++    /**+       @name Quantifiers+    */+    /*@{*/++    /**+       \brief Create a pattern for quantifier instantiation.++       Z3 uses pattern matching to instantiate quantifiers. If a+       pattern is not provided for a quantifier, then Z3 will+       automatically compute a set of patterns for it. However, for+       optimal performance, the user should provide the patterns.++       Patterns comprise a list of terms. The list should be+       non-empty.  If the list comprises of more than one term, it is+       a called a multi-pattern.+       +       In general, one can pass in a list of (multi-)patterns in the+       quantifier constructor.+++       \sa Z3_mk_forall+       \sa Z3_mk_exists+    */+    Z3_pattern Z3_API Z3_mk_pattern(+        __in Z3_context c,+        __in unsigned num_patterns, __in_ecount(num_patterns) Z3_ast const terms[]);++    /**+       \brief Create a bound variable.++       Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain+       the meaning of de-Bruijn indices by indicating the compilation process from+       non-de-Bruijn formulas to de-Bruijn format.++       \verbatim +       abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0)+       abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi))+       abs1(x, x, n) = b_n+       abs1(y, x, n) = y+       abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n))+       abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1))+       \endverbatim++       The last line is significant: the index of a bound variable is different depending+       on the scope in which it appears. The deeper x appears, the higher is its+       index.+       +       \param c logical context+       \param index de-Bruijn index+       \param ty sort of the bound variable++       \sa Z3_mk_forall+       \sa Z3_mk_exists+    */+    Z3_ast Z3_API Z3_mk_bound(__in Z3_context c, __in unsigned index, __in Z3_sort ty);+    +    /**+       \brief Create a forall formula.++       \mlonly [mk_forall c w p t n b] creates a forall formula, where+       [w] is the weight, [p] is an array of patterns, [t] is an array+       with the sorts of the bound variables, [n] is an array with the+       'names' of the bound variables, and [b] is the body of the+       quantifier. Quantifiers are associated with weights indicating+       the importance of using the quantifier during+       instantiation. \endmlonly+       +       \param c logical context.+       \param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0.+       \param num_patterns number of patterns.+       \param patterns array containing the patterns created using #Z3_mk_pattern.+       \param num_decls number of variables to be bound.+       \param sorts the sorts of the bound variables.+       \param decl_names names of the bound variables+       \param body the body of the quantifier.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_bound+       \sa Z3_mk_exists+    */+    Z3_ast Z3_API Z3_mk_forall(__in Z3_context c, __in unsigned weight,+                               __in unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const patterns[],+                               __in unsigned num_decls, __in_ecount(num_decls) Z3_sort const sorts[],+                               __in_ecount(num_decls) Z3_symbol const decl_names[],+                               __in Z3_ast body);++    /**+       \brief Create an exists formula. Similar to #Z3_mk_forall.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_bound+       \sa Z3_mk_forall+    */+    Z3_ast Z3_API Z3_mk_exists(__in Z3_context c, __in unsigned weight,+                               __in unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const patterns[],+                               __in unsigned num_decls, __in_ecount(num_decls) Z3_sort const sorts[],+                               __in_ecount(num_decls) Z3_symbol const decl_names[],+                               __in Z3_ast body);++    /**+       \brief Create a quantifier - universal or existential, with pattern hints.+       +       \param c logical context.+       \param is_forall flag to indicate if this is a universal or existential quantifier.+       \param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0.+       \param num_patterns number of patterns.+       \param patterns array containing the patterns created using #Z3_mk_pattern.+       \param num_decls number of variables to be bound.+       \param sorts array of sorts of the bound variables.+       \param decl_names names of the bound variables.+       \param body the body of the quantifier.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_bound+       \sa Z3_mk_forall+       \sa Z3_mk_exists+    */++    Z3_ast Z3_API Z3_mk_quantifier(+        __in Z3_context c, +        __in Z3_bool is_forall, +        __in unsigned weight, +        __in unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const* patterns, +        __in unsigned num_decls, __in_ecount(num_decls) Z3_sort const* sorts, +        __in_ecount(num_decls) Z3_symbol const* decl_names, +        __in Z3_ast body);+++    /**+       \brief Create a quantifier - universal or existential, with pattern hints, no patterns, and attributes+       +       \param c logical context.+       \param is_forall flag to indicate if this is a universal or existential quantifier.+       \param quantifier_id identifier to identify quantifier+       \param skolem_id identifier to identify skolem constants introduced by quantifier.+       \param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0.+       \param num_patterns number of patterns.+       \param patterns array containing the patterns created using #Z3_mk_pattern.+       \param num_no_patterns number of patterns.+       \param no_patterns array containing the patterns created using #Z3_mk_pattern.+       \param num_decls number of variables to be bound.+       \param sorts array of sorts of the bound variables.+       \param decl_names names of the bound variables.+       \param body the body of the quantifier.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_bound+       \sa Z3_mk_forall+       \sa Z3_mk_exists+    */++    Z3_ast Z3_API Z3_mk_quantifier_ex(+        __in Z3_context c, +        __in Z3_bool is_forall, +        __in unsigned weight, +        __in Z3_symbol quantifier_id,+        __in Z3_symbol skolem_id,+        __in unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const* patterns, +        __in unsigned num_no_patterns, __in_ecount(num_no_patterns) Z3_ast const* no_patterns, +        __in unsigned num_decls, __in_ecount(num_decls) Z3_sort const* sorts, +        __in_ecount(num_decls) Z3_symbol const* decl_names, +        __in Z3_ast body);++    /**+       \brief Create a universal quantifier using a list of constants that+       will form the set of bound variables.++       \param c logical context.+       \param weight quantifiers are associated with weights indicating the importance of using +              the quantifier during instantiation. By default, pass the weight 0.+       \param num_bound number of constants to be abstracted into bound variables.+       \param bound array of constants to be abstracted into bound variables.+       \param num_patterns number of patterns.+       \param patterns array containing the patterns created using #Z3_mk_pattern.+       \param body the body of the quantifier.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_exists_const++    */++    Z3_ast Z3_API Z3_mk_forall_const(+        __in Z3_context c, +        unsigned weight,+        unsigned num_bound,+        __in_ecount(num_bound) Z3_app const* bound,+        unsigned num_patterns,+        __in_ecount(num_patterns) Z3_pattern const* patterns,+        __in Z3_ast body+        );++    /**+       \brief Similar to #Z3_mk_forall_const.++       \brief Create an existential quantifier using a list of constants that+       will form the set of bound variables.++       \param c logical context.+       \param weight quantifiers are associated with weights indicating the importance of using +              the quantifier during instantiation. By default, pass the weight 0.+       \param num_bound number of constants to be abstracted into bound variables.+       \param bound array of constants to be abstracted into bound variables.+       \param num_patterns number of patterns.+       \param patterns array containing the patterns created using #Z3_mk_pattern.+       \param body the body of the quantifier.+       +       \sa Z3_mk_pattern+       \sa Z3_mk_forall_const+    */++    Z3_ast Z3_API Z3_mk_exists_const(+        __in Z3_context c, +        unsigned weight,+        unsigned num_bound,+        __in_ecount(num_bound) Z3_app const* bound,+        unsigned num_patterns,+        __in_ecount(num_patterns) Z3_pattern const* patterns,+        __in Z3_ast body+        );++    /**+       \brief Create a universal or existential +       quantifier using a list of constants that+       will form the set of bound variables.+    */++    Z3_ast Z3_API Z3_mk_quantifier_const(+        __in Z3_context c, +        Z3_bool is_forall,+        unsigned weight,+        unsigned num_bound,  __in_ecount(num_bound) Z3_app const* bound,+        unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const* patterns,+        __in Z3_ast body+        );++++    /**+       \brief Create a universal or existential +       quantifier using a list of constants that+       will form the set of bound variables.+    */++    Z3_ast Z3_API Z3_mk_quantifier_const_ex(+        __in Z3_context c, +        Z3_bool is_forall,+        unsigned weight,+        __in Z3_symbol quantifier_id,+        __in Z3_symbol skolem_id,+        unsigned num_bound,  __in_ecount(num_bound) Z3_app const* bound,+        unsigned num_patterns, __in_ecount(num_patterns) Z3_pattern const* patterns,+        unsigned num_no_patterns, __in_ecount(num_no_patterns) Z3_ast const* no_patterns,+        __in Z3_ast body+        );+++++    /*@}*/+++    /**+       @name Accessors+    */+    /*@{*/++    /** +        \brief Return a unique identifier for \c t.+    */+    unsigned Z3_API Z3_get_ast_id(__in Z3_context c, Z3_ast t);++    /** +        \brief Return a unique identifier for \c f.+    */+    unsigned Z3_API Z3_get_func_decl_id(__in Z3_context c, Z3_func_decl f);++    /** +        \brief Return a unique identifier for \c s.+    */+    unsigned Z3_API Z3_get_sort_id(__in Z3_context c, Z3_sort s);++++    /**+       \brief Return true if the given expression \c t is well sorted.+    */+    Z3_bool Z3_API Z3_is_well_sorted(__in Z3_context c, __in Z3_ast t);++    /**+       \brief Return \c Z3_INT_SYMBOL if the symbol was constructed+       using #Z3_mk_int_symbol, and \c Z3_STRING_SYMBOL if the symbol+       was constructed using #Z3_mk_string_symbol.+    */+    Z3_symbol_kind Z3_API Z3_get_symbol_kind(__in Z3_context c, __in Z3_symbol s);++    /**+       \brief \mlh get_symbol_int c s \endmlh+       Return the symbol int value. +       +       \pre Z3_get_symbol_kind(s) == Z3_INT_SYMBOL++       \sa Z3_mk_int_symbol+    */+    int Z3_API Z3_get_symbol_int(__in Z3_context c, __in Z3_symbol s);+    +    /**+       \brief \mlh get_symbol_string c s \endmlh+       Return the symbol name. ++       \pre Z3_get_symbol_string(s) == Z3_STRING_SYMBOL++       \conly \warning The returned buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_get_symbol_string.++       \sa Z3_mk_string_symbol+    */+    Z3_string Z3_API Z3_get_symbol_string(__in Z3_context c, __in Z3_symbol s);+++    /**+       \brief Return the kind of the given AST.+    */+    Z3_ast_kind Z3_API Z3_get_ast_kind(__in Z3_context c, __in Z3_ast a);++    +    /**+       \brief Return numeral value, as a string of a numeric constant term++       \pre Z3_get_ast_kind(c, a) == Z3_NUMERAL_AST+    */+    Z3_string Z3_API Z3_get_numeral_string(__in Z3_context c, __in Z3_ast a);+++    /**+       \brief Return numeral value, as a pair of 64 bit numbers if the representation fits.++       \param c logical context.+       \param a term.+       \param num numerator.+       \param den denominator.+       +       Preturn \c Z3_TRUE if the numeral value fits in 64 bit numerals, \c Z3_FALSE otherwise.++       \pre Z3_get_ast_kind(a) == Z3_NUMERAL_AST+    */+    Z3_bool Z3_API Z3_get_numeral_small(__in Z3_context c, __in Z3_ast a, __out __int64* num, __out __int64* den);+++    /**+       \brief \mlh get_numeral_int c v \endmlh+       Similar to #Z3_get_numeral_string, but only succeeds if+       the value can fit in a machine int. Return Z3_TRUE if the call succeeded.++       \pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST+      +       \sa Z3_get_numeral_string+    */+    Z3_bool Z3_API Z3_get_numeral_int(__in Z3_context c, __in Z3_ast v, __out int* i);++    /**+       \brief \mlh get_numeral_uint c v \endmlh+       Similar to #Z3_get_numeral_string, but only succeeds if+       the value can fit in a machine unsigned int. Return Z3_TRUE if the call succeeded.++       \pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST+      +       \sa Z3_get_numeral_string+    */+    Z3_bool Z3_API Z3_get_numeral_uint(__in Z3_context c, __in Z3_ast v, __out unsigned* u);++#ifndef CAMLIDL+    /**+       \brief \mlh get_numeral_uint64 c v \endmlh+       Similar to #Z3_get_numeral_string, but only succeeds if+       the value can fit in a machine unsigned __int64 int. Return Z3_TRUE if the call succeeded.++       \pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST+      +       \sa Z3_get_numeral_string+    */+    Z3_bool Z3_API Z3_get_numeral_uint64(__in Z3_context c, __in Z3_ast v, __out unsigned __int64* u);+#endif // CAMLIDL++#ifndef CAMLIDL+    /**+       \brief \mlh get_numeral_int64 c v \endmlh+       Similar to #Z3_get_numeral_string, but only succeeds if+       the value can fit in a machine __int64 int. Return Z3_TRUE if the call succeeded.++       \pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST++       \sa Z3_get_numeral_string+    */+    Z3_bool Z3_API Z3_get_numeral_int64(__in Z3_context c, __in Z3_ast v, __out __int64* i);+#endif // CAMLIDL++#ifndef CAMLIDL+    /**+       \brief \mlh get_numeral_rational_int64 c x y\endmlh+       Similar to #Z3_get_numeral_string, but only succeeds if+       the value can fit as a reational number as machine __int64 int. Return Z3_TRUE if the call succeeded.++       \pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST++       \sa Z3_get_numeral_string+    */+    Z3_bool Z3_API Z3_get_numeral_rational_int64(__in Z3_context c, __in Z3_ast v, __out __int64* num, __out __int64* den);+#endif // CAMLIDL++    /**+       \brief Return Z3_L_TRUE if \c a is true, Z3_L_FALSE if it is false, and Z3_L_UNDEF otherwise.+    */+    Z3_lbool Z3_API Z3_get_bool_value(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return the declaration of a constant or function application.+    */+    Z3_func_decl Z3_API Z3_get_app_decl(__in Z3_context c, __in Z3_app a);++    /**+       \brief \mlh get_app_num_args c a \endmlh+       Return the number of argument of an application. If \c t+       is an constant, then the number of arguments is 0.+    */+    unsigned Z3_API Z3_get_app_num_args(__in Z3_context c, __in Z3_app a);++    /**+       \brief \mlh get_app_arg c a i \endmlh+       Return the i-th argument of the given application.+       +       \pre i < Z3_get_num_args(c, a)+    */+    Z3_ast Z3_API Z3_get_app_arg(__in Z3_context c, __in Z3_app a, __in unsigned i);++    /**+       \brief Return index of de-Brujin bound variable.++       \pre Z3_get_ast_kind(a) == Z3_VAR_AST+    */+    unsigned Z3_API Z3_get_index_value(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Determine if quantifier is universal.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_bool Z3_API Z3_is_quantifier_forall(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Obtain weight of quantifier.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    unsigned Z3_API Z3_get_quantifier_weight(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return number of patterns used in quantifier.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    unsigned Z3_API Z3_get_quantifier_num_patterns(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return i'th pattern.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(__in Z3_context c, __in Z3_ast a, unsigned i);++    /**+       \brief Return number of no_patterns used in quantifier.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    unsigned Z3_API Z3_get_quantifier_num_no_patterns(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return i'th no_pattern.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(__in Z3_context c, __in Z3_ast a, unsigned i);++    /**+       \brief Return symbol of the i'th bound variable.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_symbol Z3_API Z3_get_quantifier_bound_name(__in Z3_context c, __in Z3_ast a, unsigned i);++    /**+       \brief Return sort of the i'th bound variable.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_sort Z3_API Z3_get_quantifier_bound_sort(__in Z3_context c, __in Z3_ast a, unsigned i);++    /**+       \brief Return body of quantifier.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    Z3_ast Z3_API Z3_get_quantifier_body(__in Z3_context c, __in Z3_ast a);++++    /**+       \brief Return number of bound variables of quantifier.+       +       \pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST+    */+    unsigned Z3_API Z3_get_quantifier_num_bound(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return the constant declaration name as a symbol. +    */+    Z3_symbol Z3_API Z3_get_decl_name(__in Z3_context c, __in Z3_func_decl d);++    /**+       \brief Return the number of parameters associated with a declaration.+    */+    unsigned Z3_API Z3_get_decl_num_parameters(__in Z3_context c, __in Z3_func_decl d);++    /**+       \brief Return the parameter type associated with a declaration.+       +       \param c the context+       \param d the function declaration+       \param idx is the index of the named parameter it should be between 0 and the number of parameters.+    */+    Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the integer value associated with an integer parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_INT+    */+    int Z3_API Z3_get_decl_int_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the double value associated with an double parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_DOUBLE+    */+    double Z3_API Z3_get_decl_double_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the double value associated with an double parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_SYMBOL+    */+    Z3_symbol Z3_API Z3_get_decl_symbol_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);+    /**+       \brief Return the sort value associated with a sort parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_SORT+    */+    Z3_sort Z3_API Z3_get_decl_sort_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the expresson value associated with an expression parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_AST+    */+    Z3_ast Z3_API Z3_get_decl_ast_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the expresson value associated with an expression parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_FUNC_DECL+    */+    Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the rational value, as a string, associated with a rational parameter.++       \pre Z3_get_decl_parameter_kind(c, d, idx) == Z3_PARAMETER_RATIONAL+    */+    Z3_string Z3_API Z3_get_decl_rational_parameter(__in Z3_context c, __in Z3_func_decl d, unsigned idx);++    /**+       \brief Return the sort name as a symbol. +    */+    Z3_symbol Z3_API Z3_get_sort_name(__in Z3_context c, __in Z3_sort d);++    /**+       \brief Return the sort of an AST node.+       +       The AST node must be a constant, application, numeral, bound variable, or quantifier.++    */+    Z3_sort Z3_API Z3_get_sort(__in Z3_context c, __in Z3_ast a);++    /**+       \brief Return the number of parameters of the given declaration.++       \sa Z3_get_domain_size+    */+    unsigned Z3_API Z3_get_domain_size(__in Z3_context c, __in Z3_func_decl d);++    /**+       \brief \mlh get_domain c d i \endmlh+       Return the sort of the i-th parameter of the given function declaration.+       +       \pre i < Z3_get_domain_size(d)++       \sa Z3_get_domain_size+    */+    Z3_sort Z3_API Z3_get_domain(__in Z3_context c, __in Z3_func_decl d, __in unsigned i);++    /**+       \brief \mlh get_range c d \endmlh+       Return the range of the given declaration. ++       If \c d is a constant (i.e., has zero arguments), then this+       function returns the sort of the constant.+    */+    Z3_sort Z3_API Z3_get_range(__in Z3_context c, __in Z3_func_decl d);++    /**+       \brief Return the sort kind (e.g., array, tuple, int, bool, etc).++       \sa Z3_sort_kind+    */+    Z3_sort_kind Z3_API Z3_get_sort_kind(__in Z3_context c, __in Z3_sort t);++    /**+       \brief \mlh get_bv_sort_size c t \endmlh+       Return the size of the given bit-vector sort. ++       \pre Z3_get_sort_kind(c, t) == Z3_BV_SORT++       \sa Z3_mk_bv_sort+       \sa Z3_get_sort_kind+    */+    unsigned Z3_API Z3_get_bv_sort_size(__in Z3_context c, __in Z3_sort t);++    /**+       \brief \mlh get_array_sort_domain c t \endmlh+       Return the domain of the given array sort.+       +       \pre Z3_get_sort_kind(c, t) == Z3_ARRAY_SORT++       \sa Z3_mk_array_sort+       \sa Z3_get_sort_kind+    */+    Z3_sort Z3_API Z3_get_array_sort_domain(__in Z3_context c, __in Z3_sort t);++    /**+       \brief \mlh get_array_sort_range c t \endmlh +       Return the range of the given array sort. ++       \pre Z3_get_sort_kind(c, t) == Z3_ARRAY_SORT++       \sa Z3_mk_array_sort+       \sa Z3_get_sort_kind+    */+    Z3_sort Z3_API Z3_get_array_sort_range(__in Z3_context c, __in Z3_sort t);++    /**+       \brief \mlh get_tuple_sort_mk_decl c t \endmlh+       Return the constructor declaration of the given tuple+       sort. ++       \pre Z3_get_sort_kind(c, t) == Z3_DATATYPE_SORT++       \sa Z3_mk_tuple_sort+       \sa Z3_get_sort_kind+    */+    Z3_func_decl Z3_API Z3_get_tuple_sort_mk_decl(__in Z3_context c, __in Z3_sort t);++    /**+       \brief Return declaration kind corresponding to declaration.+    */+    Z3_decl_kind Z3_API Z3_get_decl_kind(__in Z3_context c, __in Z3_func_decl d);+    +    /**+       \brief \mlh get_tuple_sort_num_fields c t \endmlh+       Return the number of fields of the given tuple sort. ++       \pre Z3_get_sort_kind(c, t) == Z3_DATATYPE_SORT++       \mlonly \remark Consider using the function {!Z3.get_tuple_sort}, which +       returns a tuple: tuple constructor, and an array of the tuple sort fields. \endmlonly++       \sa Z3_mk_tuple_sort+       \sa Z3_get_sort_kind+    */+    unsigned Z3_API Z3_get_tuple_sort_num_fields(__in Z3_context c, __in Z3_sort t);++    /**+       \brief \mlh get_tuple_sort_field_decl c t i \endmlh+       Return the i-th field declaration (i.e., projection function declaration)+       of the given tuple sort. ++       \mlonly \remark Consider using the function {!Z3.get_tuple_sort}, which +       returns a tuple: tuple constructor, and an array of the tuple sort fields. \endmlonly++       \pre Z3_get_sort_kind(t) == Z3_DATATYPE_SORT+       \pre i < Z3_get_tuple_sort_num_fields(c, t)+       +       \sa Z3_mk_tuple_sort+       \sa Z3_get_sort_kind+    */+    Z3_func_decl Z3_API Z3_get_tuple_sort_field_decl(__in Z3_context c, __in Z3_sort t, __in unsigned i);++    /** +        \brief Return number of constructors for datatype.++        \pre Z3_get_sort_kind(t) == Z3_DATATYPE_SORT++        \sa Z3_get_datatype_sort_constructor+        \sa Z3_get_datatype_sort_recognizer+        \sa Z3_get_datatype_sort_constructor_accessor++    */+    unsigned Z3_API Z3_get_datatype_sort_num_constructors(+        __in Z3_context c, __in Z3_sort t);++    /** +        \brief Return idx'th constructor.++        \pre Z3_get_sort_kind(t) == Z3_DATATYPE_SORT+        \pre idx < Z3_get_datatype_sort_num_constructors(c, t)++        \sa Z3_get_datatype_sort_num_constructors+        \sa Z3_get_datatype_sort_recognizer+        \sa Z3_get_datatype_sort_constructor_accessor++    */+    Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(+        __in Z3_context c, __in Z3_sort t, unsigned idx);++    /** +        \brief Return idx'th recognizer.++        \pre Z3_get_sort_kind(t) == Z3_DATATYPE_SORT+        \pre idx < Z3_get_datatype_sort_num_constructors(c, t)++        \sa Z3_get_datatype_sort_num_constructors+        \sa Z3_get_datatype_sort_constructor+        \sa Z3_get_datatype_sort_constructor_accessor++    */+    Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(+        __in Z3_context c, __in Z3_sort t, unsigned idx);++    /** +        \brief Return idx_a'th accessor for the idx_c'th constructor.++        \pre Z3_get_sort_kind(t) == Z3_DATATYPE_SORT+        \pre idx_c < Z3_get_datatype_sort_num_constructors(c, t)+        \pre idx_a < Z3_get_domain_size(c, Z3_get_datatype_sort_constructor(c, idx_c))++        \sa Z3_get_datatype_sort_num_constructors+        \sa Z3_get_datatype_sort_constructor+        \sa Z3_get_datatype_sort_recognizer+    */+    Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(+        __in Z3_context c, __in Z3_sort t, unsigned idx_c, unsigned idx_a);+++    /** +        \brief Return arity of relation.++        \pre Z3_get_sort_kind(s) == Z3_RELATION_SORT++        \sa Z3_get_relation_column+    */++    unsigned Z3_API Z3_get_relation_arity(__in Z3_context c, __in Z3_sort s);++    /** +        \brief Return sort at i'th column of relation sort.++        \pre Z3_get_sort_kind(c, s) == Z3_RELATION_SORT+        \pre col < Z3_get_relation_arity(c, s)++        \sa Z3_get_relation_arity+    */+    Z3_sort Z3_API Z3_get_relation_column(__in Z3_context c, __in Z3_sort s, unsigned col);+++#ifndef CAMLIDL+    /** +        \brief Store the size of the sort in \c r. Return Z3_TRUE if the call succeeded.+        That is, Z3_get_sort_kind(s) == Z3_FINITE_DOMAIN_SORT+    */+    Z3_bool Z3_API Z3_get_finite_domain_sort_size(__in Z3_context c, __in Z3_sort s, __out unsigned __int64* r);+#endif++    /** +        \brief Return number of terms in pattern.+    */+    unsigned Z3_API Z3_get_pattern_num_terms(__in Z3_context c, __in Z3_pattern p);+    +    /**+       \brief Return i'th ast in pattern.+    */+    Z3_ast Z3_API Z3_get_pattern(__in Z3_context c, __in Z3_pattern p, __in unsigned idx);++++    /** +        \brief Interface to simplifier.++        Provides an interface to the AST simplifier used by Z3.+        It allows clients to piggyback on top of the AST simplifier+        for their own term manipulation.+    */+    Z3_ast Z3_API Z3_simplify(__in Z3_context c, __in Z3_ast a);++    /*@}*/++    /**+       @name Modifiers+    */+    /*@{*/++    /**+       \brief Update the arguments of term \c a using the arguments \c args.+       The number of arguments \c num_args should coincide +       with the number of arguments to \c a.+       If \c a is a quantifier, then num_args has to be 1.+    */+    Z3_ast Z3_API Z3_update_term(__in Z3_context c, __in Z3_ast a, __in unsigned num_args, __in_ecount(num_args) Z3_ast args[]);++    /**+       \brief Substitute every occurrence of <tt>from[i]</tt> in \c a with <tt>to[i]</tt>, for \c i smaller than \c num_exprs.+       The result is the new AST. The arrays \c from and \c to must have size \c num_exprs.+       For every \c i smaller than \c num_exprs, we must have that sort of <tt>from[i]</tt> must be equal to sort of <tt>to[i]</tt>.+    */+    Z3_ast Z3_API Z3_substitute(__in Z3_context c, +                                __in Z3_ast a, +                                __in unsigned num_exprs, +                                __in_ecount(num_exprs) Z3_ast from[], +                                __in_ecount(num_exprs) Z3_ast to[]);++    /**+       \brief Substitute the free variables in \c a with the expressions in \c to.+       For every \c i smaller than \c num_exprs, the variable with de-Bruijn index \c i is replaced with term <tt>to[i]</tt>.+    */+    Z3_ast Z3_API Z3_substitute_vars(__in Z3_context c, +                                     __in Z3_ast a, +                                     __in unsigned num_exprs, +                                     __in_ecount(num_exprs) Z3_ast to[]);+    +    /*@}*/++    ++    /**+       @name Coercions+    */+    /*@{*/++    /**+       \brief Convert a Z3_sort into Z3_ast. This is just type casting.+    */+    Z3_ast Z3_API Z3_sort_to_ast(__in Z3_context c, __in Z3_sort s);+    +    /**+       \brief Convert a Z3_func_decl into Z3_ast. This is just type casting.+    */+    Z3_ast Z3_API Z3_func_decl_to_ast(__in Z3_context c, __in Z3_func_decl f);+    +    /**+       \brief Convert a Z3_pattern into Z3_ast. This is just type casting.+    */+    Z3_ast Z3_API Z3_pattern_to_ast(__in Z3_context c, __in Z3_pattern p);++    /**+       \brief Convert a APP_AST into an AST. This is just type casting.+    */+    Z3_ast Z3_API Z3_app_to_ast(__in Z3_context c, __in Z3_app a);++    /**+       \brief Convert an AST into a APP_AST. This is just type casting.+       +       \warning This conversion is only safe if #Z3_get_ast_kind returns \c Z3_app.+    */+    Z3_app Z3_API Z3_to_app(__in Z3_context c, __in Z3_ast a);++    /*@}*/+    +    /**+       @name Constraints+    */+    /*@{*/++    /** +        \brief Create a backtracking point.+        +        The logical context can be viewed as a stack of contexts.  The+        scope level is the number of elements on this stack. The stack+        of contexts is simulated using trail (undo) stacks.++        \sa Z3_pop+    */+    void Z3_API Z3_push(__in Z3_context c);+    +    /**+       \brief Backtrack.+       +       Restores the context from the top of the stack, and pops it off the+       stack.  Any changes to the logical context (by #Z3_assert_cnstr or+       other functions) between the matching #Z3_push and \c Z3_pop+       operators are flushed, and the context is completely restored to+       what it was right before the #Z3_push.+       +       \sa Z3_push+    */+    void Z3_API Z3_pop(__in Z3_context c, __in unsigned num_scopes);+++    /**+       \brief Retrieve the current scope level.+       +       It retrieves the number of scopes that have been pushed, but not yet popped.+       +       \sa Z3_push+       \sa Z3_pop+    */+    unsigned Z3_API Z3_get_num_scopes(__in Z3_context c);+    +    /**+       \brief Persist AST through num_scopes pops.+       This function is only relevant if \c c was created using #Z3_mk_context.+       If \c c was created using #Z3_mk_context_rc, this function is a NOOP.+       +       Normally, for contexts created using #Z3_mk_context, +       references to terms are no longer valid when +       popping scopes beyond the level where the terms are created.+       If you want to reference a term below the scope where it+       was created, use this method to specify how many pops+       the term should survive.+       The num_scopes should be at most equal to the number of+       calls to Z3_push subtracted with the calls to Z3_pop.+    */+    void Z3_API Z3_persist_ast(__in Z3_context c, __in Z3_ast a, __in unsigned num_scopes);+++    /**+       \brief Assert a constraing into the logical context.+       +       After one assertion, the logical context may become+       inconsistent.  +       +       The functions #Z3_check or #Z3_check_and_get_model should be+       used to check whether the logical context is consistent or not.++       \sa Z3_check+       \sa Z3_check_and_get_model+    */+    void Z3_API Z3_assert_cnstr(__in Z3_context c, __in Z3_ast a);+    +    /**+       \brief Check whether the given logical context is consistent or not.++       If the logical context is not unsatisfiable (i.e., the return value is different from \c Z3_L_FALSE)+       and model construction is enabled (see #Z3_mk_config), then a model is stored in \c m. Otherwise,+       the value \c 0 is stored in \c m.+       The caller is responsible for deleting the model using the function #Z3_del_model.+       +       \remark Model construction must be enabled using configuration+       parameters (See, #Z3_mk_config).++       \sa Z3_check+       \sa Z3_del_model+    */+    Z3_lbool Z3_API Z3_check_and_get_model(__in Z3_context c, __out Z3_model * m);+    +    /**+       \brief Check whether the given logical context is consistent or not.++       The function #Z3_check_and_get_model should be used when models are needed.++       \sa Z3_check_and_get_model+    */+    Z3_lbool Z3_API Z3_check(__in Z3_context c);++    /**+       \brief Check whether the given logical context and optional assumptions is consistent or not.++       If the logical context is not unsatisfiable (i.e., the return value is different from \c Z3_L_FALSE),+       a non-0 model argument is passed in,+       and model construction is enabled (see #Z3_mk_config), then a model is stored in \c m. +       Otherwise, \c m is left unchanged.+       The caller is responsible for deleting the model using the function #Z3_del_model.+       +       \remark If the model argument is non-0, then model construction must be enabled using configuration+       parameters (See, #Z3_mk_config).++       \param c logical context.+       \param num_assumptions number of auxiliary assumptions.+       \param assumptions array of auxiliary assumptions+       \param m optional pointer to a model.+       \param proof optional pointer to a proof term.+       \param core_size size of unsatisfiable core. +       \param core pointer to an array receiveing unsatisfiable core. +              The unsatisfiable core is a subset of the assumptions, so the array has the same size as the assumptions.+              The \c core array is not populated if \c core_size is set to 0.++       \pre assumptions comprises of propositional literals.+            In other words, you cannot use compound formulas for assumptions, +            but should use propositional variables or negations of propositional variables.+              +       \sa Z3_check+       \sa Z3_del_model+    */+    Z3_lbool Z3_API Z3_check_assumptions(+        __in Z3_context c, +        __in unsigned num_assumptions, __in_ecount(num_assumptions) Z3_ast assumptions[], +        __out Z3_model * m, __out Z3_ast* proof, +        __inout unsigned* core_size, __inout_ecount(num_assumptions) Z3_ast core[]+        );++    /**+       \brief Retrieve congruence class representatives for terms.++       The function can be used for relying on Z3 to identify equal terms under the current+       set of assumptions. The array of terms and array of class identifiers should have+       the same length. The class identifiers are numerals that are assigned to the same+       value for their corresponding terms if the current context forces the terms to be+       equal. You cannot deduce that terms corresponding to different numerals must be all different, +       (especially when using non-convex theories).+       All implied equalities are returned by this call.+       This means that two terms map to the same class identifier if and only if+       the current context implies that they are equal.++       A side-effect of the function is a satisfiability check.+       The function return Z3_L_FALSE if the current assertions are not satisfiable.++       \sa Z3_check_and_get_model+       \sa Z3_check+    */++    Z3_lbool Z3_API Z3_get_implied_equalities(+        __in Z3_context c, +        __in unsigned num_terms,+        __in_ecount(num_terms) Z3_ast terms[],+        __out_ecount(num_terms) unsigned class_ids[]+        );+++    /**+       \brief Delete a model object.+       +       \sa Z3_check_and_get_model+    */+    void Z3_API Z3_del_model(__in Z3_context c, __in Z3_model m);++    /**+       @name Search control.+    */+    /*@{*/+    /**+       \brief Cancel an ongoing check.+       +       Notifies the current check to abort and return.+       This method should be called from a different thread+       than the one performing the check.+    */++    void Z3_API Z3_soft_check_cancel(__in Z3_context c);+    /*@}*/++    /*@{*/++    /**+       \brief Retrieve reason for search failure.+       +       If a call to #Z3_check or #Z3_check_and_get_model returns Z3_L_UNDEF, +       use this facility to determine the more detailed cause of search failure.+    */+    Z3_search_failure Z3_API Z3_get_search_failure(__in Z3_context c);++    /*@}*/+++    /**+       @name Labels.+    */+    /*@{*/+    /** +        \brief Retrieve the set of labels that were relevant in+        the context of the current satisfied context.++        \sa Z3_del_literals+        \sa Z3_get_num_literals+        \sa Z3_get_label_symbol+        \sa Z3_get_literal+    */+    Z3_literals Z3_API Z3_get_relevant_labels(__in Z3_context c);++    /** +        \brief Retrieve the set of literals that satisfy the current context.++        \sa Z3_del_literals+        \sa Z3_get_num_literals+        \sa Z3_get_label_symbol+        \sa Z3_get_literal+    */+    Z3_literals Z3_API Z3_get_relevant_literals(__in Z3_context c);++    /** +        \brief Retrieve the set of literals that whose assignment were +        guess, but not propagated during the search.++        \sa Z3_del_literals+        \sa Z3_get_num_literals+        \sa Z3_get_label_symbol+        \sa Z3_get_literal+    */+    Z3_literals Z3_API Z3_get_guessed_literals(__in Z3_context c);+++    /**+       \brief Delete a labels context.+       +       \sa Z3_get_relevant_labels+    */+    void Z3_API Z3_del_literals(__in Z3_context c, __in Z3_literals lbls);++    /**+       \brief Retrieve the number of label symbols that were returned.+       +       \sa Z3_get_relevant_labels+    */+    unsigned Z3_API Z3_get_num_literals(__in Z3_context c, __in Z3_literals lbls);++    /**+       \brief Retrieve label symbol at idx.+    */+    Z3_symbol Z3_API Z3_get_label_symbol(__in Z3_context c, __in Z3_literals lbls, __in unsigned idx);++    /**+       \brief Retrieve literal expression at idx.+    */+    Z3_ast Z3_API Z3_get_literal(__in Z3_context c, __in Z3_literals lbls, __in unsigned idx);++    /**+       \brief Disable label.+       +       The disabled label is not going to be used when blocking the subsequent search.++       \sa Z3_block_literals+    */+    void Z3_API Z3_disable_literal(__in Z3_context c, __in Z3_literals lbls, __in unsigned idx);++    /**+       \brief Block subsequent checks using the remaining enabled labels.+    */+    void Z3_API Z3_block_literals(__in Z3_context c, __in Z3_literals lbls);++    /*@}*/++++    /**+       @name Model navigation+     */+    /*@{*/+    +    /**+       \brief Return the number of constants assigned by the given model.+       +       \mlonly \remark Consider using {!Z3.get_model_constants}. \endmlonly++       \sa Z3_get_model_constant+    */+    unsigned Z3_API Z3_get_model_num_constants(__in Z3_context c, __in Z3_model m);++    /**+       \brief \mlh get_model_constant c m i \endmlh+       Return the i-th constant in the given model. ++       \mlonly \remark Consider using {!Z3.get_model_constants}. \endmlonly++       \pre i < Z3_get_model_num_constants(c, m)++       \sa Z3_eval+    */+    Z3_func_decl Z3_API Z3_get_model_constant(__in Z3_context c, __in Z3_model m, __in unsigned i);++    /**+       \brief Return the value of the given constant or function +              in the given model.+       +    */+    Z3_bool Z3_API Z3_eval_func_decl(__in Z3_context c, __in Z3_model m, __in Z3_func_decl decl, __out Z3_ast* v);+++    /**+       \brief \mlh is_array_value c v \endmlh+       Determine whether the term encodes an array value.       +       Return the number of entries mapping to non-default values of the array.+    */+    Z3_bool Z3_API Z3_is_array_value(__in Z3_context c, __in Z3_model m, __in Z3_ast v, __out unsigned* num_entries);+++    /**+       \brief \mlh get_array_value c v \endmlh+       An array values is represented as a dictionary plus a+       default (else) value. This function returns the array graph.++       \pre Z3_TRUE == Z3_is_array_value(c, v, &num_entries)       +    */+    void Z3_API Z3_get_array_value(__in Z3_context c, +                                   __in Z3_model m,+                                   __in Z3_ast v,+                                   __in unsigned num_entries,+                                   __inout_ecount(num_entries) Z3_ast indices[],+                                   __inout_ecount(num_entries) Z3_ast values[],+                                   __out Z3_ast* else_value+                                   );++        +    /**+       \brief Return the number of function interpretations in the given model.+       +       A function interpretation is represented as a finite map and an 'else' value.+       Each entry in the finite map represents the value of a function given a set of arguments.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly+       +       \sa Z3_get_model_func_decl+       \sa Z3_get_model_func_else+       \sa Z3_get_model_func_num_entries+       \sa Z3_get_model_func_entry_num_args+       \sa Z3_get_model_func_entry_arg+     */+    unsigned Z3_API Z3_get_model_num_funcs(__in Z3_context c, __in Z3_model m);+    +    +    /**+       \brief \mlh get_model_func_decl c m i \endmlh+       Return the declaration of the i-th function in the given model.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly++       \pre i < Z3_get_model_num_funcs(c, m)++       \sa Z3_get_model_num_funcs+    */+    Z3_func_decl Z3_API Z3_get_model_func_decl(__in Z3_context c, __in Z3_model m, __in unsigned i);++    /**+       \brief \mlh get_model_func_else c m i \endmlh+       Return the 'else' value of the i-th function interpretation in the given model.+ +       A function interpretation is represented as a finite map and an 'else' value.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly+       +       \pre i < Z3_get_model_num_funcs(c, m)++       \sa Z3_get_model_num_funcs+       \sa Z3_get_model_func_num_entries+       \sa Z3_get_model_func_entry_num_args+       \sa Z3_get_model_func_entry_arg+    */+    Z3_ast Z3_API Z3_get_model_func_else(__in Z3_context c, __in Z3_model m, __in unsigned i);++    /**+       \brief \mlh get_model_func_num_entries c m i \endmlh+       Return the number of entries of the i-th function interpretation in the given model.+ +       A function interpretation is represented as a finite map and an 'else' value.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly+       +       \pre i < Z3_get_model_num_funcs(c, m)++       \sa Z3_get_model_num_funcs+       \sa Z3_get_model_func_else+       \sa Z3_get_model_func_entry_num_args+       \sa Z3_get_model_func_entry_arg+    */+    unsigned Z3_API Z3_get_model_func_num_entries(__in Z3_context c, __in Z3_model m, __in unsigned i);++    +    /**+       \brief \mlh get_model_func_entry_num_args c m i j \endmlh+       Return the number of arguments of the j-th entry of the i-th function interpretation in the given+       model.++       A function interpretation is represented as a finite map and an 'else' value.+       This function returns the j-th entry of this map.+      +       An entry represents the value of a function given a set of arguments.+       \conly That is: it has the following format <tt>f(args[0],...,args[num_args - 1]) = val</tt>.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly++       \pre i < Z3_get_model_num_funcs(c, m)+       \pre j < Z3_get_model_func_num_entries(c, m, i)++       \sa Z3_get_model_num_funcs+       \sa Z3_get_model_func_num_entries +       \sa Z3_get_model_func_entry_arg+    */+    unsigned Z3_API Z3_get_model_func_entry_num_args(__in Z3_context c,+                                                     __in Z3_model m,+                                                     __in unsigned i,+                                                     __in unsigned j);+    +    /**+       \brief \mlh get_model_func_entry_arg c m i j k \endmlh+       Return the k-th argument of the j-th entry of the i-th function interpretation in the given+       model.++       A function interpretation is represented as a finite map and an 'else' value.+       This function returns the j-th entry of this map.+      +       An entry represents the value of a function given a set of arguments.+       \conly That is: it has the following format <tt>f(args[0],...,args[num_args - 1]) = val</tt>.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly++       \pre i < Z3_get_model_num_funcs(c, m)+       \pre j < Z3_get_model_func_num_entries(c, m, i)+       \pre k < Z3_get_model_func_entry_num_args(c, m, i, j)++       \sa Z3_get_model_num_funcs+       \sa Z3_get_model_func_num_entries +       \sa Z3_get_model_func_entry_num_args+    */+    Z3_ast Z3_API Z3_get_model_func_entry_arg(__in Z3_context c,+                                                __in Z3_model m,+                                                __in unsigned i,+                                                __in unsigned j,+                                                __in unsigned k);+    +    /**+       \brief \mlh get_model_func_entry_value c m i j \endmlh+       Return the return value of the j-th entry of the i-th function interpretation in the given+       model.++       A function interpretation is represented as a finite map and an 'else' value.+       This function returns the j-th entry of this map.+      +       An entry represents the value of a function given a set of arguments.+       \conly That is: it has the following format <tt>f(args[0],...,args[num_args - 1]) = val</tt>.++       \mlonly \remark Consider using {!Z3.get_model_funcs}. \endmlonly++       \pre i < Z3_get_model_num_funcs(c, m)+       \pre j < Z3_get_model_func_num_entries(c, m, i)++       \sa Z3_get_model_num_funcs+       \sa Z3_get_model_func_num_entries +    */+    Z3_ast Z3_API Z3_get_model_func_entry_value(__in Z3_context c,+                                                  __in Z3_model m,+                                                  __in unsigned i,+                                                  __in unsigned j);+    +    /**+       \brief \mlh eval c m t \endmlh+       Evaluate the AST node \c t in the given model. +       \conly Return \c Z3_TRUE if succeeded, and store the result in \c v.+       \mlonly Return a pair: Boolean and value. The Boolean is true if the term was successfully evaluated. \endmlonly++       The evaluation may fail for the following reasons:++       - \c t contains a quantifier.++       - the model \c m is partial, that is, it doesn't have a complete interpretation for uninterpreted functions. +         That is, the option <tt>MODEL_PARTIAL=true</tt> was used.++       - \c t is type incorrect.+    */+    Z3_bool Z3_API Z3_eval(__in Z3_context c, __in Z3_model m, __in Z3_ast t, __out Z3_ast * v);++    /**+       \brief Evaluate declaration given values.++       Provides direct way to evaluate declarations+       without going over terms.+     */+    Z3_bool Z3_API Z3_eval_decl(__in Z3_context c, __in Z3_model m, +                                __in Z3_func_decl d, +                                __in unsigned num_args,+                                __in_ecount(num_args) Z3_ast args[],+                                __out Z3_ast* v);++++    +    /*@}*/++    /**+       @name Interaction logging.+    */+    /*@{*/+    +    /**+       \brief Log interaction to a file.+    */+    Z3_bool Z3_API Z3_open_log(__in Z3_context c, __in_z Z3_string filename);++    /**+       \brief Append user-defined string to interaction log.+       +       The interaction log is opened using Z3_open_log.+       It contains the formulas that are checked using Z3.+       You can use this command to append comments, for instance.+    */+    void Z3_API Z3_append_log(__in Z3_context c, __in_z Z3_string string);+++    /**+       \brief Close interaction log.+    */+    void Z3_API Z3_close_log(__in Z3_context c);+    /*@}*/+++    /**+       @name String conversion+    */+    /*@{*/++    /**+       \brief Select mode for the format used for pretty-printing AST nodes.++       The default mode for pretty printing AST nodes is to produce+       SMT-LIB style output where common subexpressions are printed +       at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL.+       To print shared common subexpressions only once, +       use the Z3_PRINT_LOW_LEVEL mode.+       To print in way that conforms to SMT-LIB standards and uses let+       expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT.++       \sa Z3_ast_to_string+       \sa Z3_pattern_to_string+       \sa Z3_func_decl_to_string++    */+    void Z3_API Z3_set_ast_print_mode(__in Z3_context c, __in Z3_ast_print_mode mode);++    /**+       \brief Convert the given AST node into a string.++       \conly \warning The result buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_ast_to_string.+       \sa Z3_pattern_to_string+       \sa Z3_sort_to_string+    */+    Z3_string Z3_API Z3_ast_to_string(__in Z3_context c, __in Z3_ast a);+    Z3_string Z3_API Z3_pattern_to_string(__in Z3_context c, __in Z3_pattern p);+    Z3_string Z3_API Z3_sort_to_string(__in Z3_context c, __in Z3_sort s);+    Z3_string Z3_API Z3_func_decl_to_string(__in Z3_context c, __in Z3_func_decl d);++    /**+       \brief Convert the given model into a string.++       \conly \warning The result buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_model_to_string.+    */+    Z3_string Z3_API Z3_model_to_string(__in Z3_context c, __in Z3_model m);++    /**+       \brief Convert the given benchmark into SMT-LIB formatted string.++       \conly \warning The result buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_benchmark_to_smtlib_string.++       \param c - context.+       \param name - name of benchmark. The argument is optional.+       \param logic - the benchmark logic. +       \param status - the status string (sat, unsat, or unknown)+       \param attributes - other attributes, such as source, difficulty or category.+       \param num_assumptions - number of assumptions.+       \param assumptions - auxiliary assumptions.+       \param formula - formula to be checked for consistency in conjunction with assumptions.+    */+    Z3_string Z3_API Z3_benchmark_to_smtlib_string(__in   Z3_context c, +                                                   __in_z Z3_string name,+                                                   __in_z Z3_string logic,+                                                   __in_z Z3_string status,+                                                   __in_z Z3_string attributes,+                                                   __in   unsigned num_assumptions,+                                                   __in_ecount(num_assumptions) Z3_ast assumptions[],+                                                   __in   Z3_ast formula);+    ++    /**+       \brief Convert the given logical context into a string.+       +       This function is mainly used for debugging purposes. It displays+       the internal structure of a logical context.++       \conly \warning The result buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_context_to_string.+    */+    Z3_string Z3_API Z3_context_to_string(__in Z3_context c);+++    /**+       \brief Return runtime statistics as a string.+       +       This function is mainly used for debugging purposes. It displays+       statistics of the search activity.++       \conly \warning The result buffer is statically allocated by Z3. It will+       \conly be automatically deallocated when #Z3_del_context is invoked.+       \conly So, the buffer is invalidated in the next call to \c Z3_context_to_string.+    */+    Z3_string Z3_API Z3_statistics_to_string(__in Z3_context c);+++    /**+       \brief Extract satisfying assignment from context as a conjunction.+       +       This function can be used for debugging purposes. It returns a conjunction+       of formulas that are assigned to true in the current context.+       This conjunction will contain not only the assertions that are set to true+       under the current assignment, but will also include additional literals+       if there has been a call to #Z3_check or #Z3_check_and_get_model.       +     */+    Z3_ast Z3_API Z3_get_context_assignment(__in Z3_context c);++    /*@}*/++    /**+       @name Parser interface+    */+    /*@{*/+    /**+       \brief \mlh parse_smtlib_string c str sort_names sorts decl_names decls \endmlh+       Parse the given string using the SMT-LIB parser. +              +       The symbol table of the parser can be initialized using the given sorts and declarations. +       The symbols in the arrays \c sort_names and \c decl_names don't need to match the names+       of the sorts and declarations in the arrays \c sorts and \c decls. This is an useful feature+       since we can use arbitrary names to reference sorts and declarations defined using the C API.++       The formulas, assumptions and declarations defined in \c str can be extracted using the functions:+       #Z3_get_smtlib_num_formulas, #Z3_get_smtlib_formula, #Z3_get_smtlib_num_assumptions, #Z3_get_smtlib_assumption, +       #Z3_get_smtlib_num_decls, and #Z3_get_smtlib_decl.+     */+    void Z3_API Z3_parse_smtlib_string(__in Z3_context c, +                                       __in_z Z3_string str,+                                       __in unsigned num_sorts,+                                       __in_ecount(num_sorts) Z3_symbol sort_names[],+                                       __in_ecount(num_sorts) Z3_sort sorts[],+                                       __in unsigned num_decls,+                                       __in_ecount(num_decls) Z3_symbol decl_names[],+                                       __in_ecount(num_decls) Z3_func_decl decls[]                     +                                       );+    +    /**+       \brief Similar to #Z3_parse_smtlib_string, but reads the benchmark from a file.+    */+    void Z3_API Z3_parse_smtlib_file(__in Z3_context c, +                                     __in_z Z3_string file_name,+                                     __in unsigned num_sorts,+                                     __in_ecount(num_sorts) Z3_symbol sort_names[],+                                     __in_ecount(num_sorts) Z3_sort sorts[],+                                     __in unsigned num_decls,+                                     __in_ecount(num_decls) Z3_symbol decl_names[],+                                     __in_ecount(num_decls) Z3_func_decl decls[]  +                                     );++    /**+       \brief Return the number of SMTLIB formulas parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.+    */+    unsigned Z3_API Z3_get_smtlib_num_formulas(__in Z3_context c);++    /**+       \brief \mlh get_smtlib_formula c i \endmlh+       Return the i-th formula parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.++       \pre i < Z3_get_smtlib_num_formulas(c)+    */+    Z3_ast Z3_API Z3_get_smtlib_formula(__in Z3_context c, __in unsigned i);++    /**+       \brief Return the number of SMTLIB assumptions parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.+    */+    unsigned Z3_API Z3_get_smtlib_num_assumptions(__in Z3_context c);++    /**+       \brief \mlh get_smtlib_assumption c i \endmlh+       Return the i-th assumption parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.++       \pre i < Z3_get_smtlib_num_assumptions(c)+    */+    Z3_ast Z3_API Z3_get_smtlib_assumption(__in Z3_context c, __in unsigned i);++    /**+       \brief Return the number of declarations parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.+    */+    unsigned Z3_API Z3_get_smtlib_num_decls(__in Z3_context c);++    /**+       \brief \mlh get_smtlib_decl c i \endmlh+       Return the i-th declaration parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.++       \pre i < Z3_get_smtlib_num_decls(c)+    */+    Z3_func_decl Z3_API Z3_get_smtlib_decl(__in Z3_context c, __in unsigned i);++    /**+       \brief Return the number of sorts parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.+    */+    unsigned Z3_API Z3_get_smtlib_num_sorts(__in Z3_context c);++    /**+       \brief \mlh get_smtlib_sort c i \endmlh+       Return the i-th sort parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.++       \pre i < Z3_get_smtlib_num_sorts(c)+    */+    Z3_sort Z3_API Z3_get_smtlib_sort(__in Z3_context c, __in unsigned i);++    /**+       \brief \mlh get_smtlib_error c \endmlh+       Retrieve that last error message information generated from parsing.+    */+    Z3_string Z3_API Z3_get_smtlib_error(__in Z3_context c);++    /**+       \brief \mlh parse_z3_string c str \endmlh+       Parse the given string using the Z3 native parser.+       +       Return the conjunction of asserts made in the input.+     */+    Z3_ast Z3_API Z3_parse_z3_string(__in Z3_context c, __in_z Z3_string str);+    +    /**+       \brief Similar to #Z3_parse_z3_string, but reads the benchmark from a file.+    */+    Z3_ast Z3_API Z3_parse_z3_file(__in Z3_context c, __in_z Z3_string file_name);++    /**+       \brief \mlh parse_smtlib2_string c str \endmlh+       Parse the given string using the SMT-LIB2 parser. +              +       It returns a formula comprising of the conjunction of assertions in the scope+       (up to push/pop) at the end of the string.+     */+    Z3_ast Z3_API Z3_parse_smtlib2_string(__in Z3_context c, +                                          __in_z Z3_string str,+                                          __in unsigned num_sorts,+                                          __in_ecount(num_sorts) Z3_symbol sort_names[],+                                          __in_ecount(num_sorts) Z3_sort sorts[],+                                          __in unsigned num_decls,+                                          __in_ecount(num_decls) Z3_symbol decl_names[],+                                          __in_ecount(num_decls) Z3_func_decl decls[]  +                                          );+    +    /**+       \brief Similar to #Z3_parse_smtlib2_string, but reads the benchmark from a file.+    */+    Z3_ast Z3_API Z3_parse_smtlib2_file(__in Z3_context c, +                                        __in_z Z3_string file_name,+                                          __in unsigned num_sorts,+                                          __in_ecount(num_sorts) Z3_symbol sort_names[],+                                          __in_ecount(num_sorts) Z3_sort sorts[],+                                          __in unsigned num_decls,+                                          __in_ecount(num_decls) Z3_symbol decl_names[],+                                          __in_ecount(num_decls) Z3_func_decl decls[]    +                                        );+++#ifndef CAMLIDL+    /**+       \brief \mlh parse_simplify_string c str \endmlh+       Parse the given string using the Simplify parser.+       +       Return the conjunction of asserts made in the input.+     */+    Z3_ast Z3_API Z3_parse_simplify_string(__in Z3_context c, __in_z Z3_string str, __out Z3_string* parser_output);+    +    /**+       \brief Similar to #Z3_parse_simplify_string, but reads the benchmark from a file.+    */+    Z3_ast Z3_API Z3_parse_simplify_file(__in Z3_context c, __in_z Z3_string file_name, __out Z3_string* parser_output);+#endif // CAMLIDL++    /*@}*/++#ifndef CAMLIDL+    /**+       @name Error Handling+    */+    /*@{*/++    /**+       \brief Return the error code for the last API call.+       +       A call to a Z3 function may return a non Z3_OK error code,+       when it is not used correctly.++       \sa Z3_set_error_handler+    */+    Z3_error_code Z3_API Z3_get_error_code(__in Z3_context c);++    /**+       \brief Register a Z3 error handler.+       +       A call to a Z3 function may return a non Z3_OK error code, when+       it is not used correctly.  An error handler can be registered+       and will be called in this case.  To disable the use of the+       error handler, simply register with h=NULL.++       \sa Z3_get_error_code+    */+    void Z3_API Z3_set_error_handler(__in Z3_context c, __in Z3_error_handler h);+    +    /**+       \brief Set an error.+    */+    void Z3_API Z3_set_error(__in Z3_context c, __in Z3_error_code e);++    /**+       \brief Return a string describing the given error code.+     */+    Z3_string Z3_API Z3_get_error_msg(__in Z3_error_code err);+    /*@}*/++#endif // CAMLIDL++    /**+       @name Miscellaneous+    */+    /*@{*/+    +    /**+       \brief Return Z3 version number information.+    */+    void Z3_API Z3_get_version(__out unsigned * major, +                               __out unsigned * minor, +                               __out unsigned * build_number, +                               __out unsigned * revision_number);+++    /**+       \brief Reset all allocated resources. ++       Use this facility on out-of memory errors. +       It allows discharging the previous state and resuming afresh.+       Any pointers previously returned by the API+       become invalid.+    */+    void Z3_API Z3_reset_memory(void);+    +    /*@}*/++    /** +        @name External Theory Plugins+    */+    /*@{*/+    +#ifndef CAMLIDL++    //+    // callbacks and void* don't work with CAMLIDL.+    // +    typedef Z3_bool Z3_reduce_eq_callback_fptr(__in Z3_theory t, __in Z3_ast a, __in Z3_ast b, __out Z3_ast * r);++    typedef Z3_bool Z3_reduce_app_callback_fptr(__in Z3_theory, __in Z3_func_decl, __in unsigned, __in Z3_ast const [], __out Z3_ast *);+++    typedef Z3_bool Z3_reduce_distinct_callback_fptr(__in Z3_theory, __in unsigned, __in Z3_ast const [], __out Z3_ast *);++    typedef void Z3_theory_callback_fptr(__in Z3_theory t);+    +    typedef Z3_bool Z3_theory_final_check_callback_fptr(__in Z3_theory);+    +    typedef void Z3_theory_ast_callback_fptr(__in Z3_theory, __in Z3_ast);+    +    typedef void Z3_theory_ast_bool_callback_fptr(__in Z3_theory, __in Z3_ast, __in Z3_bool);+    +    typedef void Z3_theory_ast_ast_callback_fptr(__in Z3_theory, __in Z3_ast, __in Z3_ast);+++    /**+       \brief Create a new user defined theory. The new theory will be identified by the name \c th_name.+       A theory must be created before asserting any assertion to the given context.+       Return NULL in case of failure.++       \c data is a pointer to an external data-structure that may be used to store+       theory specific additional data.+    */+    Z3_theory Z3_API Z3_mk_theory(__in Z3_context c, __in_z Z3_string th_name, __in Z3_theory_data data);++    /**+       \brief Return a pointer to the external data-structure supplied to the function #Z3_mk_theory.++       \see Z3_mk_theory+    */+    Z3_theory_data Z3_API Z3_theory_get_ext_data(__in Z3_theory t);++#endif+    +    /**+       \brief Create an interpreted theory sort.+    */+    Z3_sort Z3_API Z3_theory_mk_sort(__in Z3_context c, __in Z3_theory t, __in Z3_symbol s);+    +    /**+       \brief Create an interpreted theory constant value. Values are assumed to be different from each other.+    */+    Z3_ast Z3_API Z3_theory_mk_value(__in Z3_context c, __in Z3_theory t, __in Z3_symbol n, __in Z3_sort s);++    /**+       \brief Create an interpreted constant for the given theory.+    */+    Z3_ast Z3_API Z3_theory_mk_constant(__in Z3_context c, __in Z3_theory t, __in Z3_symbol n, __in Z3_sort s);+    +    /**+       \brief Create an interpreted function declaration for the given theory.+    */+    Z3_func_decl Z3_API Z3_theory_mk_func_decl(__in Z3_context c, __in Z3_theory t, __in Z3_symbol n,+                                               __in unsigned domain_size, __in_ecount(domain_size) Z3_sort const domain[],+                                               __in Z3_sort range);++    /**+       \brief Return the context where the given theory is installed.+    */+    Z3_context Z3_API Z3_theory_get_context(__in Z3_theory t);++++#ifndef CAMLIDL+    /**+       \brief Set a callback that is invoked when theory \c t is deleted.+       This callback should be used to delete external data-structures associated with the given theory.++       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+       +       \see Z3_mk_theory +       \see Z3_theory_get_ext_data+    */+    void Z3_API Z3_set_delete_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);+    +    /**+       \brief Set a callback for simplifying operators of the given theory.+       The callback \c f is invoked by Z3's simplifier.++       It is of the form <tt>f(t, d, n, args, r)</tt>, where:+         - \c t is the given theory+         - \c d is the declaration of the theory operator+         - \c n is the number of arguments in the array \c args+         - \c args are arguments for the theory operator+         - \c r should contain the result: an expression equivalent to <tt>d(args[0], ..., args[n-1])</tt>.++      If <tt>f(t, d, n, args, r)</tt> returns false, then \c r is ignored, and Z3 assumes that no simplification was performed.+    */+    void Z3_API Z3_set_reduce_app_callback(__in Z3_theory t, __in Z3_reduce_app_callback_fptr f);+    +    /**+       \brief Set a callback for simplifying the atom <tt>s_1 = s_2</tt>, when the+       sort of \c s_1 and \c s_2 is an interpreted sort of the given theory.+       The callback \c f is invoked by Z3's simplifier.+       +       It has the form <tt>f(t, s_1, s_2, r)</tt>, where:+         - \c t is the given theory+         - \c s_1 is the left-hand-side+         - \c s_2 is the right-hand-side+         - \c r should contain the result: an expression equivalent to <tt>s_1 = s_2</tt>.+         +       If <tt>f(t, s_1, s_2, r)</tt> returns false, then \c r is ignored, and Z3 assumes that no simplification was performed.+    */+    void Z3_API Z3_set_reduce_eq_callback(__in Z3_theory t, __in Z3_reduce_eq_callback_fptr f);++    /**+       \brief Set a callback for simplifying the atom <tt>distinct(s_1, ..., s_n)</tt>, when the+       sort of \c s_1, ..., \c s_n is an interpreted sort of the given theory.+       The callback \c f is invoked by Z3's simplifier.+       +       It has the form <tt>f(t, n, args, r)</tt>, where:+         - \c t is the given theory+         - \c n is the number of arguments in the array \c args+         - \c args are arguments for distinct.+         - \c r should contain the result: an expression equivalent to <tt>distinct(s_1, ..., s_n)</tt>.+         +       If <tt>f(t, n, args, r)</tt> returns false, then \c r is ignored, and Z3 assumes that no simplification was performed.+    */+    void Z3_API Z3_set_reduce_distinct_callback(__in Z3_theory t, __in Z3_reduce_distinct_callback_fptr f);+    +    /**+       \brief Set a callback that is invoked when a theory application+       is finally added into the logical context. Note that, not every+       application contained in an asserted expression is actually+       added into the logical context because it may be simplified+       during a preprocessing step.+    +       The callback has the form <tt>f(t, n)</tt>, where+       - \c t is the given theory+       +       - \c n is a theory application, that is, an expression of the form <tt>g(...)</tt> where \c g is a theory operator.++       \remark An expression \c n added to the logical context at search level \c n,+       will remain in the logical context until this level is backtracked.+    */+    void Z3_API Z3_set_new_app_callback(__in Z3_theory t, __in Z3_theory_ast_callback_fptr f);++    /**+       \brief Set a callback that is invoked when an expression of+       sort \c s, where \c s is an interpreted sort of the theory \c+       t, is finally added into the logical context. Note that, not+       every expression contained in an asserted expression is+       actually added into the logical context because it may be+       simplified during a preprocessing step.++       The callback has the form <tt>f(t, n)</tt>, where+       - \c t is the given theory+       +       - \c n is an expression of sort \c s, where \c s is an interpreted sort of \c t.++       \remark An expression \c n added to the logical context at search level \c n,+       will remain in the logical context until this level is backtracked.+    */+    void Z3_API Z3_set_new_elem_callback(__in Z3_theory t, __in Z3_theory_ast_callback_fptr f);++    /**+       \brief Set a callback that is invoked when Z3 starts searching for a+       satisfying assignment.+       +       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+    */+    void Z3_API Z3_set_init_search_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);+        +    /**+       \brief Set a callback that is invoked when Z3 creates a+       case-split (aka backtracking point). ++       When a case-split is created we say the search level is increased.+       +       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+    */+    void Z3_API Z3_set_push_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);+ +    /**+       \brief Set a callback that is invoked when Z3 backtracks a+       case-split.++       When a case-split is backtracked we say the search level is decreased.+       +       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+    */+    void Z3_API Z3_set_pop_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);++    /**+       \brief Set a callback that is invoked when Z3 restarts the+       search for a satisfying assignment.+       +       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+    */+    void Z3_API Z3_set_restart_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);++    /**+       \brief Set a callback that is invoked when the logical context+       is reset by the user. This callback is useful for reseting any+       data-structure maintained by the user theory solver.+       +       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory+    */+    void Z3_API Z3_set_reset_callback(__in Z3_theory t, __in Z3_theory_callback_fptr f);++    /**+       \brief Set a callback that is invoked before Z3 starts building a model.+       A theory may use this callback to perform expensive operations.++       The callback has the form <tt>f(t)</tt>, where+       - \c t is the given theory++       If the theory return \c Z3_false, Z3 will assume that theory is giving up,+       and it will assume that it was not possible to decide if the asserted constraints+       are satisfiable or not.+    */+    void Z3_API Z3_set_final_check_callback(__in Z3_theory t, __in Z3_theory_final_check_callback_fptr f);++    /**+       \brief Set a callback that is invoked when an equality <tt>s_1 = s_2</tt>+       is found by the logical context.++       The callback has the form <tt>f(t, s_1, s_2)</tt>, where:+         - \c t is the given theory+         - \c s_1 is the left-hand-side+         - \c s_2 is the right-hand-side+    */+    void Z3_API Z3_set_new_eq_callback(__in Z3_theory t, __in Z3_theory_ast_ast_callback_fptr f);++    /**+       \brief Set a callback that is invoked when a disequality <tt>s_1 != s_2</tt>+       is found by the logical context.++       The callback has the form <tt>f(t, s_1, s_2)</tt>, where:+         - \c t is the given theory+         - \c s_1 is the left-hand-side+         - \c s_2 is the right-hand-side+    */+    void Z3_API Z3_set_new_diseq_callback(__in Z3_theory t, __in Z3_theory_ast_ast_callback_fptr f);++    /**+       \brief Set a callback that is invoked when a theory predicate is assigned to true/false by Z3.+       +       The callback has the form <tt>f(t, p, v)</tt>, where:+         - \c t is the given theory+         - \c p is the assigned predicate.+         - \c v is the value (true/false) assigned to \c p.+    */+    void Z3_API Z3_set_new_assignment_callback(__in Z3_theory t, __in Z3_theory_ast_bool_callback_fptr f);++    /**+       \brief Set a callback that is invoked when an expression is+       marked as relevant during the search. This callback is only+       invoked when relevancy propagation is enabled.+       +       The callback has the form <tt>f(t, n)</tt>, where:+         - \c t is the given theory+         - \c n is the relevant expression+    */+    void Z3_API Z3_set_new_relevant_callback(__in Z3_theory t, __in Z3_theory_ast_callback_fptr f);++#endif // CAMLIDL+    /**+       \brief Assert a theory axiom/lemmas during the search.+       +       An axiom added at search level \c n will remain in the logical context until +       level \c n is backtracked. ++       The callbacks for push (#Z3_set_push_callback) and pop+       (#Z3_set_pop_callback) can be used to track when the search+       level is increased (i.e., new case-split) and decreased (i.e.,+       case-split is backtracked).+       +       Z3 tracks the theory axioms asserted. So, multiple assertions of the same axiom are+       ignored.+    */+    void Z3_API Z3_theory_assert_axiom(__in Z3_theory t, __in Z3_ast ax);++    /**+       \brief Inform to the logical context that \c lhs and \c rhs have the same interpretation+       in the model being built by theory \c t. If lhs = rhs is inconsistent with other theories,+       then the logical context will backtrack.++       For more information, see the paper "Model-Based Theory Combination" in the Z3 website.+    */+    void Z3_API Z3_theory_assume_eq(__in Z3_theory t, __in Z3_ast lhs, __in Z3_ast rhs);++    /**+       \brief Enable/disable the simplification of theory axioms asserted using #Z3_theory_assert_axiom.+       By default, the simplification of theory specific operators is disabled. +       That is, the reduce theory callbacks are not invoked for theory axioms.+       The default behavior is useful when asserting axioms stating properties of theory operators.+    */+    void Z3_API Z3_theory_enable_axiom_simplification(__in Z3_theory t, __in Z3_bool flag);++    /**+       \brief Return the root of the equivalence class containing \c n.+    */+    Z3_ast Z3_API Z3_theory_get_eqc_root(__in Z3_theory t, __in Z3_ast n);+    +    /**+       \brief Return the next element in the equivalence class containing \c n.++       The elements in an equivalence class are organized in a circular list.+       You can traverse the list by calling this function multiple times +       using the result from the previous call. This is illustrated in the+       code snippet below.+       \code+           Z3_ast curr = n;+           do+             curr = Z3_theory_get_eqc_next(theory, curr);+           while (curr != n);+       \endcode+    */+    Z3_ast Z3_API Z3_theory_get_eqc_next(__in Z3_theory t, __in Z3_ast n);++    /**+       \brief Return the number of parents of \c n that are operators of the given theory. +    */+    unsigned Z3_API Z3_theory_get_num_parents(__in Z3_theory t, __in Z3_ast n);+    +    /**+       \brief Return the i-th parent of \c n. +       See #Z3_theory_get_num_parents. +    */+    Z3_ast Z3_API Z3_theory_get_parent(__in Z3_theory t, __in Z3_ast n, __in unsigned i);++    /**+       \brief Return \c Z3_TRUE if \c n is an interpreted theory value.+    */+    Z3_bool Z3_API Z3_theory_is_value(__in Z3_theory t, __in Z3_ast n);++    /**+       \brief Return \c Z3_TRUE if \c d is an interpreted theory declaration.+    */+    Z3_bool Z3_API Z3_theory_is_decl(__in Z3_theory t, __in Z3_func_decl d);+    +    /**+       \brief Return the number of expressions of the given theory in+       the logical context. These are the expressions notified using the+       callback #Z3_set_new_elem_callback.+    */+    unsigned Z3_API Z3_theory_get_num_elems(__in Z3_theory t);+    +    /**+       \brief Return the i-th elem of the given theory in the logical context.+       +       \see Z3_theory_get_num_elems+    */+    Z3_ast Z3_API Z3_theory_get_elem(__in Z3_theory t, __in unsigned i);++    /**+       \brief Return the number of theory applications in the logical+       context. These are the expressions notified using the callback+       #Z3_set_new_app_callback.+    */+    unsigned Z3_API Z3_theory_get_num_apps(__in Z3_theory t);+    +    /**+       \brief Return the i-th application of the given theory in the logical context.+       +       \see Z3_theory_get_num_apps+    */+    Z3_ast Z3_API Z3_theory_get_app(__in Z3_theory t, __in unsigned i);++    /*@}*/++    +    /** +        @name Fixedpoint and Datalog facilities+    */+    /*@{*/+    /** +       \brief Add a universal Horn clause as a named rule.+       The \c horn_rule should be of the form:+ +       \code+           horn_rule ::= (forall (bound-vars) horn_rule)+                      |  (=> atoms horn_rule)+                      |  atom+       \endcode+    */+    void Z3_API Z3_datalog_add_rule(__in Z3_context c, __in Z3_ast horn_rule, __in Z3_symbol name);+    +    /** +        \brief Pose a query against the asserted rules.++        The query returns a formula that encodes the set of+        satisfying instances for the query.++        \code+           query ::= (exists (bound-vars) query)+                 |  literals +        \endcode++    */+    Z3_ast Z3_API Z3_datalog_query(__in Z3_context c,  __in Z3_ast q);++    /**+       \brief Configure the predicate representation.++       It sets the predicate to use a set of domains given by the list of symbols.+       The domains given by the list of symbols must belong to a set+       of built-in domains.+    */++    void Z3_API Z3_datalog_set_predicate_representation(+        __in Z3_context c, __in Z3_func_decl f, +        __in unsigned num_relations, +        __in_ecount(num_relations) Z3_symbol const relation_kinds[]);++    /**+         \brief Parse a file in Datalog format and process the queries in it.+    */+    void Z3_API Z3_datalog_parse_file(__in Z3_context c, Z3_string filename);++    /**+         \brief The following utilities allows adding user-defined domains.+    */++#ifndef CAMLIDL+    typedef void Z3_datalog_reduce_assign_callback_fptr(+        __in Z3_context, __in Z3_func_decl, +        __in unsigned, __in Z3_ast const [], +        __in unsigned, __in Z3_ast const []); ++    typedef void Z3_datalog_reduce_app_callback_fptr(+        __in Z3_context, __in Z3_func_decl, +        __in unsigned, __in Z3_ast const [], +        __out Z3_ast*);+++    /**+         \brief Initialize the context with a user-defined state.++    */+    void Z3_API Z3_datalog_init(__in Z3_context c, __in void* state);++    /**+         \brief Retrieve the user-define state.+    */+    void* Z3_API Z3_datalog_get_context(__in Z3_context c);+    ++    /**+         \brief Register a callback to destructive updates.++         Registers are identified with terms encoded as fresh constants,          +    */+    void Z3_API Z3_datalog_set_reduce_assign_callback(+        __in Z3_context c, __in Z3_datalog_reduce_assign_callback_fptr cb);++    /**+         \brief Register a callback for buildling terms based on +         the relational operators.+    */+    void Z3_API Z3_datalog_set_reduce_app_callback(+        __in Z3_context c, __in Z3_datalog_reduce_app_callback_fptr cb);++#endif++    /*@}*/+    +#ifndef CAMLIDL+#ifdef __cplusplus+};+#endif // __cplusplus+#else+}+#endif // CAMLIDL++/*@}*/
+ external/z3/lib/libz3-a-32b view

file too large to diff

+ external/z3/lib/libz3-a-64b view

file too large to diff

+ external/z3/lib/libz3-so-32b view

file too large to diff

+ external/z3/lib/libz3-so-64b view

file too large to diff

+ external/z3/ocaml/build-lib.sh view
@@ -0,0 +1,8 @@+#!/bin/bash++gcc -I../include -I`ocamlc -where` -c z3_stubs.c -c z3_theory_stubs.c+ocamlopt -c z3.mli+ocamlopt -c z3.ml+ar rcs libz3stubs.a z3_stubs.o z3_theory_stubs.o+ranlib libz3stubs.a+ocamlopt -a -o z3.cmxa -cclib -lz3stubs z3.cmx
+ external/z3/ocaml/z3.ml view
@@ -0,0 +1,1499 @@+(* File generated from z3.idl *)
+
+type config
+and context
+and sort
+and func_decl
+and ast
+and app
+and pattern
+and symbol
+and parameter
+and model
+and literals
+and constructor
+and constructor_list
+and theory
+and theory_data
+and enum_1 =
+  | L_FALSE
+  | L_UNDEF
+  | L_TRUE
+and lbool = enum_1
+and enum_2 =
+  | INT_SYMBOL
+  | STRING_SYMBOL
+and symbol_kind = enum_2
+and enum_3 =
+  | PARAMETER_INT
+  | PARAMETER_DOUBLE
+  | PARAMETER_RATIONAL
+  | PARAMETER_SYMBOL
+  | PARAMETER_SORT
+  | PARAMETER_AST
+  | PARAMETER_FUNC_DECL
+and parameter_kind = enum_3
+and enum_4 =
+  | UNINTERPRETED_SORT
+  | BOOL_SORT
+  | INT_SORT
+  | REAL_SORT
+  | BV_SORT
+  | ARRAY_SORT
+  | DATATYPE_SORT
+  | RELATION_SORT
+  | FINITE_DOMAIN_SORT
+  | UNKNOWN_SORT
+and sort_kind = enum_4
+and enum_5 =
+  | NUMERAL_AST
+  | APP_AST
+  | VAR_AST
+  | QUANTIFIER_AST
+  | UNKNOWN_AST
+and ast_kind = enum_5
+and enum_6 =
+  | OP_TRUE
+  | OP_FALSE
+  | OP_EQ
+  | OP_DISTINCT
+  | OP_ITE
+  | OP_AND
+  | OP_OR
+  | OP_IFF
+  | OP_XOR
+  | OP_NOT
+  | OP_IMPLIES
+  | OP_OEQ
+  | OP_ANUM
+  | OP_LE
+  | OP_GE
+  | OP_LT
+  | OP_GT
+  | OP_ADD
+  | OP_SUB
+  | OP_UMINUS
+  | OP_MUL
+  | OP_DIV
+  | OP_IDIV
+  | OP_REM
+  | OP_MOD
+  | OP_TO_REAL
+  | OP_TO_INT
+  | OP_IS_INT
+  | OP_STORE
+  | OP_SELECT
+  | OP_CONST_ARRAY
+  | OP_ARRAY_MAP
+  | OP_ARRAY_DEFAULT
+  | OP_SET_UNION
+  | OP_SET_INTERSECT
+  | OP_SET_DIFFERENCE
+  | OP_SET_COMPLEMENT
+  | OP_SET_SUBSET
+  | OP_AS_ARRAY
+  | OP_BNUM
+  | OP_BIT1
+  | OP_BIT0
+  | OP_BNEG
+  | OP_BADD
+  | OP_BSUB
+  | OP_BMUL
+  | OP_BSDIV
+  | OP_BUDIV
+  | OP_BSREM
+  | OP_BUREM
+  | OP_BSMOD
+  | OP_BSDIV0
+  | OP_BUDIV0
+  | OP_BSREM0
+  | OP_BUREM0
+  | OP_BSMOD0
+  | OP_ULEQ
+  | OP_SLEQ
+  | OP_UGEQ
+  | OP_SGEQ
+  | OP_ULT
+  | OP_SLT
+  | OP_UGT
+  | OP_SGT
+  | OP_BAND
+  | OP_BOR
+  | OP_BNOT
+  | OP_BXOR
+  | OP_BNAND
+  | OP_BNOR
+  | OP_BXNOR
+  | OP_CONCAT
+  | OP_SIGN_EXT
+  | OP_ZERO_EXT
+  | OP_EXTRACT
+  | OP_REPEAT
+  | OP_BREDOR
+  | OP_BREDAND
+  | OP_BCOMP
+  | OP_BSHL
+  | OP_BLSHR
+  | OP_BASHR
+  | OP_ROTATE_LEFT
+  | OP_ROTATE_RIGHT
+  | OP_EXT_ROTATE_LEFT
+  | OP_EXT_ROTATE_RIGHT
+  | OP_INT2BV
+  | OP_BV2INT
+  | OP_CARRY
+  | OP_XOR3
+  | OP_PR_UNDEF
+  | OP_PR_TRUE
+  | OP_PR_ASSERTED
+  | OP_PR_GOAL
+  | OP_PR_MODUS_PONENS
+  | OP_PR_REFLEXIVITY
+  | OP_PR_SYMMETRY
+  | OP_PR_TRANSITIVITY
+  | OP_PR_TRANSITIVITY_STAR
+  | OP_PR_MONOTONICITY
+  | OP_PR_QUANT_INTRO
+  | OP_PR_DISTRIBUTIVITY
+  | OP_PR_AND_ELIM
+  | OP_PR_NOT_OR_ELIM
+  | OP_PR_REWRITE
+  | OP_PR_REWRITE_STAR
+  | OP_PR_PULL_QUANT
+  | OP_PR_PULL_QUANT_STAR
+  | OP_PR_PUSH_QUANT
+  | OP_PR_ELIM_UNUSED_VARS
+  | OP_PR_DER
+  | OP_PR_QUANT_INST
+  | OP_PR_HYPOTHESIS
+  | OP_PR_LEMMA
+  | OP_PR_UNIT_RESOLUTION
+  | OP_PR_IFF_TRUE
+  | OP_PR_IFF_FALSE
+  | OP_PR_COMMUTATIVITY
+  | OP_PR_DEF_AXIOM
+  | OP_PR_DEF_INTRO
+  | OP_PR_APPLY_DEF
+  | OP_PR_IFF_OEQ
+  | OP_PR_NNF_POS
+  | OP_PR_NNF_NEG
+  | OP_PR_NNF_STAR
+  | OP_PR_CNF_STAR
+  | OP_PR_SKOLEMIZE
+  | OP_PR_MODUS_PONENS_OEQ
+  | OP_PR_TH_LEMMA
+  | OP_RA_STORE
+  | OP_RA_EMPTY
+  | OP_RA_IS_EMPTY
+  | OP_RA_JOIN
+  | OP_RA_UNION
+  | OP_RA_WIDEN
+  | OP_RA_PROJECT
+  | OP_RA_FILTER
+  | OP_RA_NEGATION_FILTER
+  | OP_RA_RENAME
+  | OP_RA_COMPLEMENT
+  | OP_RA_SELECT
+  | OP_RA_CLONE
+  | OP_FD_LT
+  | OP_UNINTERPRETED
+and decl_kind = enum_6
+and enum_7 =
+  | NO_FAILURE
+  | UNKNOWN
+  | TIMEOUT
+  | MEMOUT_WATERMARK
+  | CANCELED
+  | NUM_CONFLICTS
+  | THEORY
+  | QUANTIFIERS
+and search_failure = enum_7
+and enum_8 =
+  | PRINT_SMTLIB_FULL
+  | PRINT_LOW_LEVEL
+  | PRINT_SMTLIB_COMPLIANT
+  | PRINT_SMTLIB2_COMPLIANT
+and ast_print_mode = enum_8
+
+external mk_config : unit -> config
+	= "camlidl_z3_Z3_mk_config"
+
+external del_config : config -> unit
+	= "camlidl_z3_Z3_del_config"
+
+external set_param_value : config -> string -> string -> unit
+	= "camlidl_z3_Z3_set_param_value"
+
+external mk_context : config -> context
+	= "camlidl_z3_Z3_mk_context"
+
+external mk_context_rc : config -> context
+	= "camlidl_z3_Z3_mk_context_rc"
+
+external set_logic : context -> string -> bool
+	= "camlidl_z3_Z3_set_logic"
+
+external del_context : context -> unit
+	= "camlidl_z3_Z3_del_context"
+
+external inc_ref : context -> ast -> unit
+	= "camlidl_z3_Z3_inc_ref"
+
+external dec_ref : context -> ast -> unit
+	= "camlidl_z3_Z3_dec_ref"
+
+external trace_to_file : context -> string -> bool
+	= "camlidl_z3_Z3_trace_to_file"
+
+external trace_to_stderr : context -> unit
+	= "camlidl_z3_Z3_trace_to_stderr"
+
+external trace_to_stdout : context -> unit
+	= "camlidl_z3_Z3_trace_to_stdout"
+
+external trace_off : context -> unit
+	= "camlidl_z3_Z3_trace_off"
+
+external toggle_warning_messages : bool -> unit
+	= "camlidl_z3_Z3_toggle_warning_messages"
+
+external update_param_value : context -> string -> string -> unit
+	= "camlidl_z3_Z3_update_param_value"
+
+external mk_int_symbol : context -> int -> symbol
+	= "camlidl_z3_Z3_mk_int_symbol"
+
+external mk_string_symbol : context -> string -> symbol
+	= "camlidl_z3_Z3_mk_string_symbol"
+
+external is_eq_sort : context -> sort -> sort -> bool
+	= "camlidl_z3_Z3_is_eq_sort"
+
+external mk_uninterpreted_sort : context -> symbol -> sort
+	= "camlidl_z3_Z3_mk_uninterpreted_sort"
+
+external mk_bool_sort : context -> sort
+	= "camlidl_z3_Z3_mk_bool_sort"
+
+external mk_int_sort : context -> sort
+	= "camlidl_z3_Z3_mk_int_sort"
+
+external mk_real_sort : context -> sort
+	= "camlidl_z3_Z3_mk_real_sort"
+
+external mk_bv_sort : context -> int -> sort
+	= "camlidl_z3_Z3_mk_bv_sort"
+
+external mk_array_sort : context -> sort -> sort -> sort
+	= "camlidl_z3_Z3_mk_array_sort"
+
+external mk_tuple_sort : context -> symbol -> symbol array -> sort array -> sort * func_decl * func_decl array
+	= "camlidl_z3_Z3_mk_tuple_sort"
+
+external mk_enumeration_sort : context -> symbol -> symbol array -> sort * func_decl array * func_decl array
+	= "camlidl_z3_Z3_mk_enumeration_sort"
+
+external mk_list_sort : context -> symbol -> sort -> sort * func_decl * func_decl * func_decl * func_decl * func_decl * func_decl
+	= "camlidl_z3_Z3_mk_list_sort"
+
+external mk_constructor : context -> symbol -> symbol -> symbol array -> sort array -> int array -> constructor
+	= "camlidl_z3_Z3_mk_constructor_bytecode" "camlidl_z3_Z3_mk_constructor"
+
+external query_constructor : context -> constructor -> int -> func_decl * func_decl * func_decl array
+	= "camlidl_z3_Z3_query_constructor"
+
+external del_constructor : context -> constructor -> unit
+	= "camlidl_z3_Z3_del_constructor"
+
+external mk_datatype : context -> symbol -> constructor array -> sort * constructor array
+	= "camlidl_z3_Z3_mk_datatype"
+
+external mk_constructor_list : context -> constructor array -> constructor_list
+	= "camlidl_z3_Z3_mk_constructor_list"
+
+external del_constructor_list : context -> constructor_list -> unit
+	= "camlidl_z3_Z3_del_constructor_list"
+
+external mk_datatypes : context -> symbol array -> constructor_list array -> sort array * constructor_list array
+	= "camlidl_z3_Z3_mk_datatypes"
+
+external mk_injective_function : context -> symbol -> sort array -> sort -> func_decl
+	= "camlidl_z3_Z3_mk_injective_function"
+
+external is_eq_ast : context -> ast -> ast -> bool
+	= "camlidl_z3_Z3_is_eq_ast"
+
+external is_eq_func_decl : context -> func_decl -> func_decl -> bool
+	= "camlidl_z3_Z3_is_eq_func_decl"
+
+external mk_func_decl : context -> symbol -> sort array -> sort -> func_decl
+	= "camlidl_z3_Z3_mk_func_decl"
+
+external mk_app : context -> func_decl -> ast array -> ast
+	= "camlidl_z3_Z3_mk_app"
+
+external mk_const : context -> symbol -> sort -> ast
+	= "camlidl_z3_Z3_mk_const"
+
+external mk_label : context -> symbol -> bool -> ast -> ast
+	= "camlidl_z3_Z3_mk_label"
+
+external mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl
+	= "camlidl_z3_Z3_mk_fresh_func_decl"
+
+external mk_fresh_const : context -> string -> sort -> ast
+	= "camlidl_z3_Z3_mk_fresh_const"
+
+external mk_true : context -> ast
+	= "camlidl_z3_Z3_mk_true"
+
+external mk_false : context -> ast
+	= "camlidl_z3_Z3_mk_false"
+
+external mk_eq : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_eq"
+
+external mk_distinct : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_distinct"
+
+external mk_not : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_not"
+
+external mk_ite : context -> ast -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_ite"
+
+external mk_iff : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_iff"
+
+external mk_implies : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_implies"
+
+external mk_xor : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_xor"
+
+external mk_and : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_and"
+
+external mk_or : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_or"
+
+external mk_add : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_add"
+
+external mk_mul : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_mul"
+
+external mk_sub : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_sub"
+
+external mk_unary_minus : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_unary_minus"
+
+external mk_div : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_div"
+
+external mk_mod : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_mod"
+
+external mk_rem : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_rem"
+
+external mk_lt : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_lt"
+
+external mk_le : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_le"
+
+external mk_gt : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_gt"
+
+external mk_ge : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_ge"
+
+external mk_int2real : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_int2real"
+
+external mk_real2int : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_real2int"
+
+external mk_is_int : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_is_int"
+
+external mk_bvnot : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvnot"
+
+external mk_bvredand : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvredand"
+
+external mk_bvredor : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvredor"
+
+external mk_bvand : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvand"
+
+external mk_bvor : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvor"
+
+external mk_bvxor : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvxor"
+
+external mk_bvnand : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvnand"
+
+external mk_bvnor : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvnor"
+
+external mk_bvxnor : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvxnor"
+
+external mk_bvneg : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvneg"
+
+external mk_bvadd : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvadd"
+
+external mk_bvsub : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsub"
+
+external mk_bvmul : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvmul"
+
+external mk_bvudiv : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvudiv"
+
+external mk_bvsdiv : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsdiv"
+
+external mk_bvurem : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvurem"
+
+external mk_bvsrem : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsrem"
+
+external mk_bvsmod : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsmod"
+
+external mk_bvult : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvult"
+
+external mk_bvslt : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvslt"
+
+external mk_bvule : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvule"
+
+external mk_bvsle : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsle"
+
+external mk_bvuge : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvuge"
+
+external mk_bvsge : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsge"
+
+external mk_bvugt : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvugt"
+
+external mk_bvsgt : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsgt"
+
+external mk_concat : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_concat"
+
+external mk_extract : context -> int -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_extract"
+
+external mk_sign_ext : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_sign_ext"
+
+external mk_zero_ext : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_zero_ext"
+
+external mk_repeat : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_repeat"
+
+external mk_bvshl : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvshl"
+
+external mk_bvlshr : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvlshr"
+
+external mk_bvashr : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvashr"
+
+external mk_rotate_left : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_rotate_left"
+
+external mk_rotate_right : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_rotate_right"
+
+external mk_ext_rotate_left : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_ext_rotate_left"
+
+external mk_ext_rotate_right : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_ext_rotate_right"
+
+external mk_int2bv : context -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_int2bv"
+
+external mk_bv2int : context -> ast -> bool -> ast
+	= "camlidl_z3_Z3_mk_bv2int"
+
+external mk_bvadd_no_overflow : context -> ast -> ast -> bool -> ast
+	= "camlidl_z3_Z3_mk_bvadd_no_overflow"
+
+external mk_bvadd_no_underflow : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvadd_no_underflow"
+
+external mk_bvsub_no_overflow : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsub_no_overflow"
+
+external mk_bvsub_no_underflow : context -> ast -> ast -> bool -> ast
+	= "camlidl_z3_Z3_mk_bvsub_no_underflow"
+
+external mk_bvsdiv_no_overflow : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvsdiv_no_overflow"
+
+external mk_bvneg_no_overflow : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvneg_no_overflow"
+
+external mk_bvmul_no_overflow : context -> ast -> ast -> bool -> ast
+	= "camlidl_z3_Z3_mk_bvmul_no_overflow"
+
+external mk_bvmul_no_underflow : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_bvmul_no_underflow"
+
+external mk_select : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_select"
+
+external mk_store : context -> ast -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_store"
+
+external mk_const_array : context -> sort -> ast -> ast
+	= "camlidl_z3_Z3_mk_const_array"
+
+external mk_map : context -> func_decl -> int -> ast -> ast
+	= "camlidl_z3_Z3_mk_map"
+
+external mk_array_default : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_array_default"
+
+external mk_set_sort : context -> sort -> sort
+	= "camlidl_z3_Z3_mk_set_sort"
+
+external mk_empty_set : context -> sort -> ast
+	= "camlidl_z3_Z3_mk_empty_set"
+
+external mk_full_set : context -> sort -> ast
+	= "camlidl_z3_Z3_mk_full_set"
+
+external mk_set_add : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_add"
+
+external mk_set_del : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_del"
+
+external mk_set_union : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_set_union"
+
+external mk_set_intersect : context -> ast array -> ast
+	= "camlidl_z3_Z3_mk_set_intersect"
+
+external mk_set_difference : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_difference"
+
+external mk_set_complement : context -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_complement"
+
+external mk_set_member : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_member"
+
+external mk_set_subset : context -> ast -> ast -> ast
+	= "camlidl_z3_Z3_mk_set_subset"
+
+external mk_numeral : context -> string -> sort -> ast
+	= "camlidl_z3_Z3_mk_numeral"
+
+external mk_real : context -> int -> int -> ast
+	= "camlidl_z3_Z3_mk_real"
+
+external mk_int : context -> int -> sort -> ast
+	= "camlidl_z3_Z3_mk_int"
+
+external mk_unsigned_int : context -> int -> sort -> ast
+	= "camlidl_z3_Z3_mk_unsigned_int"
+
+external mk_pattern : context -> ast array -> pattern
+	= "camlidl_z3_Z3_mk_pattern"
+
+external mk_bound : context -> int -> sort -> ast
+	= "camlidl_z3_Z3_mk_bound"
+
+external mk_forall : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast
+	= "camlidl_z3_Z3_mk_forall_bytecode" "camlidl_z3_Z3_mk_forall"
+
+external mk_exists : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast
+	= "camlidl_z3_Z3_mk_exists_bytecode" "camlidl_z3_Z3_mk_exists"
+
+external mk_quantifier : context -> bool -> int -> pattern array -> sort array -> symbol array -> ast -> ast
+	= "camlidl_z3_Z3_mk_quantifier_bytecode" "camlidl_z3_Z3_mk_quantifier"
+
+external mk_quantifier_ex : context -> bool -> int -> symbol -> symbol -> pattern array -> ast array -> sort array -> symbol array -> ast -> ast
+	= "camlidl_z3_Z3_mk_quantifier_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_ex"
+
+external mk_forall_const : context -> int -> app array -> pattern array -> ast -> ast
+	= "camlidl_z3_Z3_mk_forall_const"
+
+external mk_exists_const : context -> int -> app array -> pattern array -> ast -> ast
+	= "camlidl_z3_Z3_mk_exists_const"
+
+external mk_quantifier_const : context -> bool -> int -> app array -> pattern array -> ast -> ast
+	= "camlidl_z3_Z3_mk_quantifier_const_bytecode" "camlidl_z3_Z3_mk_quantifier_const"
+
+external mk_quantifier_const_ex : context -> bool -> int -> symbol -> symbol -> app array -> pattern array -> ast array -> ast -> ast
+	= "camlidl_z3_Z3_mk_quantifier_const_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_const_ex"
+
+external get_ast_id : context -> ast -> int
+	= "camlidl_z3_Z3_get_ast_id"
+
+external get_func_decl_id : context -> func_decl -> int
+	= "camlidl_z3_Z3_get_func_decl_id"
+
+external get_sort_id : context -> sort -> int
+	= "camlidl_z3_Z3_get_sort_id"
+
+external is_well_sorted : context -> ast -> bool
+	= "camlidl_z3_Z3_is_well_sorted"
+
+external get_symbol_kind : context -> symbol -> symbol_kind
+	= "camlidl_z3_Z3_get_symbol_kind"
+
+external get_symbol_int : context -> symbol -> int
+	= "camlidl_z3_Z3_get_symbol_int"
+
+external get_symbol_string : context -> symbol -> string
+	= "camlidl_z3_Z3_get_symbol_string"
+
+external get_ast_kind : context -> ast -> ast_kind
+	= "camlidl_z3_Z3_get_ast_kind"
+
+external get_numeral_string : context -> ast -> string
+	= "camlidl_z3_Z3_get_numeral_string"
+
+external get_numeral_small : context -> ast -> bool * int64 * int64
+	= "camlidl_z3_Z3_get_numeral_small"
+
+external get_numeral_int : context -> ast -> bool * int
+	= "camlidl_z3_Z3_get_numeral_int"
+
+external get_numeral_uint : context -> ast -> bool * int
+	= "camlidl_z3_Z3_get_numeral_uint"
+
+external get_bool_value : context -> ast -> lbool
+	= "camlidl_z3_Z3_get_bool_value"
+
+external get_app_decl : context -> app -> func_decl
+	= "camlidl_z3_Z3_get_app_decl"
+
+external get_app_num_args : context -> app -> int
+	= "camlidl_z3_Z3_get_app_num_args"
+
+external get_app_arg : context -> app -> int -> ast
+	= "camlidl_z3_Z3_get_app_arg"
+
+external get_index_value : context -> ast -> int
+	= "camlidl_z3_Z3_get_index_value"
+
+external is_quantifier_forall : context -> ast -> bool
+	= "camlidl_z3_Z3_is_quantifier_forall"
+
+external get_quantifier_weight : context -> ast -> int
+	= "camlidl_z3_Z3_get_quantifier_weight"
+
+external get_quantifier_num_patterns : context -> ast -> int
+	= "camlidl_z3_Z3_get_quantifier_num_patterns"
+
+external get_quantifier_pattern_ast : context -> ast -> int -> pattern
+	= "camlidl_z3_Z3_get_quantifier_pattern_ast"
+
+external get_quantifier_num_no_patterns : context -> ast -> int
+	= "camlidl_z3_Z3_get_quantifier_num_no_patterns"
+
+external get_quantifier_no_pattern_ast : context -> ast -> int -> ast
+	= "camlidl_z3_Z3_get_quantifier_no_pattern_ast"
+
+external get_quantifier_bound_name : context -> ast -> int -> symbol
+	= "camlidl_z3_Z3_get_quantifier_bound_name"
+
+external get_quantifier_bound_sort : context -> ast -> int -> sort
+	= "camlidl_z3_Z3_get_quantifier_bound_sort"
+
+external get_quantifier_body : context -> ast -> ast
+	= "camlidl_z3_Z3_get_quantifier_body"
+
+external get_quantifier_num_bound : context -> ast -> int
+	= "camlidl_z3_Z3_get_quantifier_num_bound"
+
+external get_decl_name : context -> func_decl -> symbol
+	= "camlidl_z3_Z3_get_decl_name"
+
+external get_decl_num_parameters : context -> func_decl -> int
+	= "camlidl_z3_Z3_get_decl_num_parameters"
+
+external get_decl_parameter_kind : context -> func_decl -> int -> parameter_kind
+	= "camlidl_z3_Z3_get_decl_parameter_kind"
+
+external get_decl_int_parameter : context -> func_decl -> int -> int
+	= "camlidl_z3_Z3_get_decl_int_parameter"
+
+external get_decl_double_parameter : context -> func_decl -> int -> float
+	= "camlidl_z3_Z3_get_decl_double_parameter"
+
+external get_decl_symbol_parameter : context -> func_decl -> int -> symbol
+	= "camlidl_z3_Z3_get_decl_symbol_parameter"
+
+external get_decl_sort_parameter : context -> func_decl -> int -> sort
+	= "camlidl_z3_Z3_get_decl_sort_parameter"
+
+external get_decl_ast_parameter : context -> func_decl -> int -> ast
+	= "camlidl_z3_Z3_get_decl_ast_parameter"
+
+external get_decl_func_decl_parameter : context -> func_decl -> int -> func_decl
+	= "camlidl_z3_Z3_get_decl_func_decl_parameter"
+
+external get_decl_rational_parameter : context -> func_decl -> int -> string
+	= "camlidl_z3_Z3_get_decl_rational_parameter"
+
+external get_sort_name : context -> sort -> symbol
+	= "camlidl_z3_Z3_get_sort_name"
+
+external get_sort : context -> ast -> sort
+	= "camlidl_z3_Z3_get_sort"
+
+external get_domain_size : context -> func_decl -> int
+	= "camlidl_z3_Z3_get_domain_size"
+
+external get_domain : context -> func_decl -> int -> sort
+	= "camlidl_z3_Z3_get_domain"
+
+external get_range : context -> func_decl -> sort
+	= "camlidl_z3_Z3_get_range"
+
+external get_sort_kind : context -> sort -> sort_kind
+	= "camlidl_z3_Z3_get_sort_kind"
+
+external get_bv_sort_size : context -> sort -> int
+	= "camlidl_z3_Z3_get_bv_sort_size"
+
+external get_array_sort_domain : context -> sort -> sort
+	= "camlidl_z3_Z3_get_array_sort_domain"
+
+external get_array_sort_range : context -> sort -> sort
+	= "camlidl_z3_Z3_get_array_sort_range"
+
+external get_tuple_sort_mk_decl : context -> sort -> func_decl
+	= "camlidl_z3_Z3_get_tuple_sort_mk_decl"
+
+external get_decl_kind : context -> func_decl -> decl_kind
+	= "camlidl_z3_Z3_get_decl_kind"
+
+external get_tuple_sort_num_fields : context -> sort -> int
+	= "camlidl_z3_Z3_get_tuple_sort_num_fields"
+
+external get_tuple_sort_field_decl : context -> sort -> int -> func_decl
+	= "camlidl_z3_Z3_get_tuple_sort_field_decl"
+
+external get_datatype_sort_num_constructors : context -> sort -> int
+	= "camlidl_z3_Z3_get_datatype_sort_num_constructors"
+
+external get_datatype_sort_constructor : context -> sort -> int -> func_decl
+	= "camlidl_z3_Z3_get_datatype_sort_constructor"
+
+external get_datatype_sort_recognizer : context -> sort -> int -> func_decl
+	= "camlidl_z3_Z3_get_datatype_sort_recognizer"
+
+external get_datatype_sort_constructor_accessor : context -> sort -> int -> int -> func_decl
+	= "camlidl_z3_Z3_get_datatype_sort_constructor_accessor"
+
+external get_relation_arity : context -> sort -> int
+	= "camlidl_z3_Z3_get_relation_arity"
+
+external get_relation_column : context -> sort -> int -> sort
+	= "camlidl_z3_Z3_get_relation_column"
+
+external get_pattern_num_terms : context -> pattern -> int
+	= "camlidl_z3_Z3_get_pattern_num_terms"
+
+external get_pattern : context -> pattern -> int -> ast
+	= "camlidl_z3_Z3_get_pattern"
+
+external simplify : context -> ast -> ast
+	= "camlidl_z3_Z3_simplify"
+
+external update_term : context -> ast -> ast array -> ast
+	= "camlidl_z3_Z3_update_term"
+
+external substitute : context -> ast -> ast array -> ast array -> ast
+	= "camlidl_z3_Z3_substitute"
+
+external substitute_vars : context -> ast -> ast array -> ast
+	= "camlidl_z3_Z3_substitute_vars"
+
+external sort_to_ast : context -> sort -> ast
+	= "camlidl_z3_Z3_sort_to_ast"
+
+external func_decl_to_ast : context -> func_decl -> ast
+	= "camlidl_z3_Z3_func_decl_to_ast"
+
+external pattern_to_ast : context -> pattern -> ast
+	= "camlidl_z3_Z3_pattern_to_ast"
+
+external app_to_ast : context -> app -> ast
+	= "camlidl_z3_Z3_app_to_ast"
+
+external to_app : context -> ast -> app
+	= "camlidl_z3_Z3_to_app"
+
+external push : context -> unit
+	= "camlidl_z3_Z3_push"
+
+external pop : context -> int -> unit
+	= "camlidl_z3_Z3_pop"
+
+external get_num_scopes : context -> int
+	= "camlidl_z3_Z3_get_num_scopes"
+
+external persist_ast : context -> ast -> int -> unit
+	= "camlidl_z3_Z3_persist_ast"
+
+external assert_cnstr : context -> ast -> unit
+	= "camlidl_z3_Z3_assert_cnstr"
+
+external check_and_get_model : context -> lbool * model
+	= "camlidl_z3_Z3_check_and_get_model"
+
+external check : context -> lbool
+	= "camlidl_z3_Z3_check"
+
+external check_assumptions : context -> ast array -> int -> ast array -> lbool * model * ast * int * ast array
+	= "camlidl_z3_Z3_check_assumptions"
+
+external get_implied_equalities : context -> ast array -> lbool * int array
+	= "camlidl_z3_Z3_get_implied_equalities"
+
+external del_model : context -> model -> unit
+	= "camlidl_z3_Z3_del_model"
+
+external soft_check_cancel : context -> unit
+	= "camlidl_z3_Z3_soft_check_cancel"
+
+external get_search_failure : context -> search_failure
+	= "camlidl_z3_Z3_get_search_failure"
+
+external get_relevant_labels : context -> literals
+	= "camlidl_z3_Z3_get_relevant_labels"
+
+external get_relevant_literals : context -> literals
+	= "camlidl_z3_Z3_get_relevant_literals"
+
+external get_guessed_literals : context -> literals
+	= "camlidl_z3_Z3_get_guessed_literals"
+
+external del_literals : context -> literals -> unit
+	= "camlidl_z3_Z3_del_literals"
+
+external get_num_literals : context -> literals -> int
+	= "camlidl_z3_Z3_get_num_literals"
+
+external get_label_symbol : context -> literals -> int -> symbol
+	= "camlidl_z3_Z3_get_label_symbol"
+
+external get_literal : context -> literals -> int -> ast
+	= "camlidl_z3_Z3_get_literal"
+
+external disable_literal : context -> literals -> int -> unit
+	= "camlidl_z3_Z3_disable_literal"
+
+external block_literals : context -> literals -> unit
+	= "camlidl_z3_Z3_block_literals"
+
+external get_model_num_constants : context -> model -> int
+	= "camlidl_z3_Z3_get_model_num_constants"
+
+external get_model_constant : context -> model -> int -> func_decl
+	= "camlidl_z3_Z3_get_model_constant"
+
+external eval_func_decl : context -> model -> func_decl -> bool * ast
+	= "camlidl_z3_Z3_eval_func_decl"
+
+external is_array_value : context -> model -> ast -> bool * int
+	= "camlidl_z3_Z3_is_array_value"
+
+external get_array_value : context -> model -> ast -> ast array -> ast array -> ast array * ast array * ast
+	= "camlidl_z3_Z3_get_array_value"
+
+external get_model_num_funcs : context -> model -> int
+	= "camlidl_z3_Z3_get_model_num_funcs"
+
+external get_model_func_decl : context -> model -> int -> func_decl
+	= "camlidl_z3_Z3_get_model_func_decl"
+
+external get_model_func_else : context -> model -> int -> ast
+	= "camlidl_z3_Z3_get_model_func_else"
+
+external get_model_func_num_entries : context -> model -> int -> int
+	= "camlidl_z3_Z3_get_model_func_num_entries"
+
+external get_model_func_entry_num_args : context -> model -> int -> int -> int
+	= "camlidl_z3_Z3_get_model_func_entry_num_args"
+
+external get_model_func_entry_arg : context -> model -> int -> int -> int -> ast
+	= "camlidl_z3_Z3_get_model_func_entry_arg"
+
+external get_model_func_entry_value : context -> model -> int -> int -> ast
+	= "camlidl_z3_Z3_get_model_func_entry_value"
+
+external eval : context -> model -> ast -> bool * ast
+	= "camlidl_z3_Z3_eval"
+
+external eval_decl : context -> model -> func_decl -> ast array -> bool * ast
+	= "camlidl_z3_Z3_eval_decl"
+
+external open_log : context -> string -> bool
+	= "camlidl_z3_Z3_open_log"
+
+external append_log : context -> string -> unit
+	= "camlidl_z3_Z3_append_log"
+
+external close_log : context -> unit
+	= "camlidl_z3_Z3_close_log"
+
+external set_ast_print_mode : context -> ast_print_mode -> unit
+	= "camlidl_z3_Z3_set_ast_print_mode"
+
+external ast_to_string : context -> ast -> string
+	= "camlidl_z3_Z3_ast_to_string"
+
+external pattern_to_string : context -> pattern -> string
+	= "camlidl_z3_Z3_pattern_to_string"
+
+external sort_to_string : context -> sort -> string
+	= "camlidl_z3_Z3_sort_to_string"
+
+external func_decl_to_string : context -> func_decl -> string
+	= "camlidl_z3_Z3_func_decl_to_string"
+
+external model_to_string : context -> model -> string
+	= "camlidl_z3_Z3_model_to_string"
+
+external benchmark_to_smtlib_string : context -> string -> string -> string -> string -> ast array -> ast -> string
+	= "camlidl_z3_Z3_benchmark_to_smtlib_string_bytecode" "camlidl_z3_Z3_benchmark_to_smtlib_string"
+
+external context_to_string : context -> string
+	= "camlidl_z3_Z3_context_to_string"
+
+external statistics_to_string : context -> string
+	= "camlidl_z3_Z3_statistics_to_string"
+
+external get_context_assignment : context -> ast
+	= "camlidl_z3_Z3_get_context_assignment"
+
+external parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit
+	= "camlidl_z3_Z3_parse_smtlib_string_bytecode" "camlidl_z3_Z3_parse_smtlib_string"
+
+external parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit
+	= "camlidl_z3_Z3_parse_smtlib_file_bytecode" "camlidl_z3_Z3_parse_smtlib_file"
+
+external get_smtlib_num_formulas : context -> int
+	= "camlidl_z3_Z3_get_smtlib_num_formulas"
+
+external get_smtlib_formula : context -> int -> ast
+	= "camlidl_z3_Z3_get_smtlib_formula"
+
+external get_smtlib_num_assumptions : context -> int
+	= "camlidl_z3_Z3_get_smtlib_num_assumptions"
+
+external get_smtlib_assumption : context -> int -> ast
+	= "camlidl_z3_Z3_get_smtlib_assumption"
+
+external get_smtlib_num_decls : context -> int
+	= "camlidl_z3_Z3_get_smtlib_num_decls"
+
+external get_smtlib_decl : context -> int -> func_decl
+	= "camlidl_z3_Z3_get_smtlib_decl"
+
+external get_smtlib_num_sorts : context -> int
+	= "camlidl_z3_Z3_get_smtlib_num_sorts"
+
+external get_smtlib_sort : context -> int -> sort
+	= "camlidl_z3_Z3_get_smtlib_sort"
+
+external get_smtlib_error : context -> string
+	= "camlidl_z3_Z3_get_smtlib_error"
+
+external parse_z3_string : context -> string -> ast
+	= "camlidl_z3_Z3_parse_z3_string"
+
+external parse_z3_file : context -> string -> ast
+	= "camlidl_z3_Z3_parse_z3_file"
+
+external parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
+	= "camlidl_z3_Z3_parse_smtlib2_string_bytecode" "camlidl_z3_Z3_parse_smtlib2_string"
+
+external parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
+	= "camlidl_z3_Z3_parse_smtlib2_file_bytecode" "camlidl_z3_Z3_parse_smtlib2_file"
+
+external get_version : unit -> int * int * int * int
+	= "camlidl_z3_Z3_get_version"
+
+external reset_memory : unit -> unit
+	= "camlidl_z3_Z3_reset_memory"
+
+external theory_mk_sort : context -> theory -> symbol -> sort
+	= "camlidl_z3_Z3_theory_mk_sort"
+
+external theory_mk_value : context -> theory -> symbol -> sort -> ast
+	= "camlidl_z3_Z3_theory_mk_value"
+
+external theory_mk_constant : context -> theory -> symbol -> sort -> ast
+	= "camlidl_z3_Z3_theory_mk_constant"
+
+external theory_mk_func_decl : context -> theory -> symbol -> sort array -> sort -> func_decl
+	= "camlidl_z3_Z3_theory_mk_func_decl"
+
+external theory_get_context : theory -> context
+	= "camlidl_z3_Z3_theory_get_context"
+
+external theory_assert_axiom : theory -> ast -> unit
+	= "camlidl_z3_Z3_theory_assert_axiom"
+
+external theory_assume_eq : theory -> ast -> ast -> unit
+	= "camlidl_z3_Z3_theory_assume_eq"
+
+external theory_enable_axiom_simplification : theory -> bool -> unit
+	= "camlidl_z3_Z3_theory_enable_axiom_simplification"
+
+external theory_get_eqc_root : theory -> ast -> ast
+	= "camlidl_z3_Z3_theory_get_eqc_root"
+
+external theory_get_eqc_next : theory -> ast -> ast
+	= "camlidl_z3_Z3_theory_get_eqc_next"
+
+external theory_get_num_parents : theory -> ast -> int
+	= "camlidl_z3_Z3_theory_get_num_parents"
+
+external theory_get_parent : theory -> ast -> int -> ast
+	= "camlidl_z3_Z3_theory_get_parent"
+
+external theory_is_value : theory -> ast -> bool
+	= "camlidl_z3_Z3_theory_is_value"
+
+external theory_is_decl : theory -> func_decl -> bool
+	= "camlidl_z3_Z3_theory_is_decl"
+
+external theory_get_num_elems : theory -> int
+	= "camlidl_z3_Z3_theory_get_num_elems"
+
+external theory_get_elem : theory -> int -> ast
+	= "camlidl_z3_Z3_theory_get_elem"
+
+external theory_get_num_apps : theory -> int
+	= "camlidl_z3_Z3_theory_get_num_apps"
+
+external theory_get_app : theory -> int -> ast
+	= "camlidl_z3_Z3_theory_get_app"
+
+external datalog_add_rule : context -> ast -> symbol -> unit
+	= "camlidl_z3_Z3_datalog_add_rule"
+
+external datalog_query : context -> ast -> ast
+	= "camlidl_z3_Z3_datalog_query"
+
+external datalog_set_predicate_representation : context -> func_decl -> symbol array -> unit
+	= "camlidl_z3_Z3_datalog_set_predicate_representation"
+
+external datalog_parse_file : context -> string -> unit
+	= "camlidl_z3_Z3_datalog_parse_file"
+
+
+
+
+(* Internal auxillary functions: *)
+
+(* Transform a pair of arrays into an array of pairs *)
+let array_combine a b =
+  if Array.length a <> Array.length b then raise (Invalid_argument "array_combine");
+  Array.init (Array.length a) (fun i->(a.(i),b.(i)));;
+
+(* [a |> b] is the pipeline operator for [b(a)] *)
+let ( |> ) x f = f x;;
+
+
+(* Extensions, except for refinement: *)
+let mk_context_x configs = 
+  let config = mk_config() in
+  let f(param_id,param_value) = set_param_value config param_id param_value in
+  Array.iter f configs;
+  let context = mk_context config in
+  del_config config;
+  context;;
+
+let get_app_args c a =
+  Array.init (get_app_num_args c a) (get_app_arg c a);;
+
+let get_domains c d =
+  Array.init (get_domain_size c d) (get_domain c d);;
+
+let get_array_sort c t = (get_array_sort_domain c t, get_array_sort_range c t);;
+
+let get_tuple_sort c ty = 
+  (get_tuple_sort_mk_decl c ty,
+   Array.init (get_tuple_sort_num_fields c ty) (get_tuple_sort_field_decl c ty));;
+
+type datatype_constructor_refined = { 
+   constructor : func_decl; 
+   recognizer : func_decl; 
+   accessors : func_decl array 
+}
+
+let get_datatype_sort c ty = 
+  Array.init (get_datatype_sort_num_constructors c ty)
+  (fun idx_c -> 
+   let constr = get_datatype_sort_constructor c ty idx_c in
+   let recog = get_datatype_sort_recognizer  c ty idx_c in
+   let num_acc = get_domain_size c constr in
+   { constructor = constr;
+     recognizer = recog;
+     accessors = Array.init num_acc (get_datatype_sort_constructor_accessor c ty idx_c);
+   })
+
+let get_model_constants c m =
+  Array.init (get_model_num_constants c m) (get_model_constant c m);;
+
+
+let get_model_func_entry c m i j =
+  (Array.init
+     (get_model_func_entry_num_args c m i j)
+     (get_model_func_entry_arg c m i j),
+   get_model_func_entry_value c m i j);;
+
+let get_model_func_entries c m i =
+  Array.init (get_model_func_num_entries c m i) (get_model_func_entry c m i);;
+
+let get_model_funcs c m =
+  Array.init (get_model_num_funcs c m)
+    (fun i->(get_model_func_decl c m i |> get_decl_name c,
+             get_model_func_entries c m i,
+             get_model_func_else c m i));;
+ 
+let get_smtlib_formulas c = 
+  Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c);;
+
+let get_smtlib_assumptions c = 
+  Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c);;
+
+let get_smtlib_decls c =
+  Array.init (get_smtlib_num_decls c) (get_smtlib_decl c);;
+
+let get_smtlib_parse_results c =
+  (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c);;
+
+let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = 
+  (parse_smtlib_string c a1 a2 a3 a4 a5;
+   match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_string_formula");;
+
+let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = 
+  (parse_smtlib_file c a1 a2 a3 a4 a5;
+   match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_file_formula");;
+
+let parse_smtlib_string_x c a1 a2 a3 a4 a5 = 
+  (parse_smtlib_string c a1 a2 a3 a4 a5; get_smtlib_parse_results c);;
+
+let parse_smtlib_file_x c a1 a2 a3 a4 a5 = 
+  (parse_smtlib_file c a1 a2 a3 a4 a5; get_smtlib_parse_results c);;
+
+(* Refinement: *)
+
+type symbol_refined =
+  | Symbol_int of int
+  | Symbol_string of string
+  | Symbol_unknown;;
+
+let symbol_refine c s =
+  match get_symbol_kind c s with
+  | INT_SYMBOL -> Symbol_int (get_symbol_int c s)
+  | STRING_SYMBOL -> Symbol_string (get_symbol_string c s);;
+
+type sort_refined =
+  | Sort_uninterpreted of symbol
+  | Sort_bool
+  | Sort_int
+  | Sort_real
+  | Sort_bv of int
+  | Sort_array of (sort * sort)
+  | Sort_datatype of datatype_constructor_refined array
+  | Sort_relation
+  | Sort_finite_domain
+  | Sort_unknown of symbol;;
+
+let sort_refine c ty =
+  match get_sort_kind c ty with
+  | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c ty)
+  | BOOL_SORT -> Sort_bool
+  | INT_SORT -> Sort_int
+  | REAL_SORT -> Sort_real
+  | BV_SORT -> Sort_bv (get_bv_sort_size c ty)
+  | ARRAY_SORT -> Sort_array (get_array_sort_domain c ty, get_array_sort_range c ty)
+  | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c ty)
+  | RELATION_SORT -> Sort_relation 
+  | FINITE_DOMAIN_SORT -> Sort_finite_domain
+  | UNKNOWN_SORT -> Sort_unknown (get_sort_name c ty);;
+
+let get_pattern_terms c p = 
+  Array.init (get_pattern_num_terms c p) (get_pattern c p)
+
+type binder_type = | Forall | Exists 
+
+type numeral_refined = 
+  | Numeral_small  of int64 * int64
+  | Numeral_large  of string
+
+type term_refined = 
+  | Term_app        of decl_kind * func_decl * ast array
+  | Term_quantifier of binder_type * int * ast array array * (symbol *sort) array * ast
+  | Term_numeral    of numeral_refined * sort
+  | Term_var        of int * sort
+
+let term_refine c t = 
+  match get_ast_kind c t with
+  | NUMERAL_AST -> 
+      let (is_small, n, d) = get_numeral_small c t in
+      if is_small then 
+	Term_numeral(Numeral_small(n,d), get_sort c t)
+      else
+	Term_numeral(Numeral_large(get_numeral_string c t), get_sort c t)
+  | APP_AST   -> 
+      let t' = to_app c t in
+      let f =  get_app_decl c t' in
+      let num_args = get_app_num_args c t' in
+      let args = Array.init num_args (get_app_arg c t') in
+      let k = get_decl_kind c f in
+      Term_app (k, f, args)
+  | QUANTIFIER_AST -> 
+      let bt = if is_quantifier_forall c t then Forall else Exists in
+      let w = get_quantifier_weight c t                            in
+      let np = get_quantifier_num_patterns c t                     in
+      let pats = Array.init np (get_quantifier_pattern_ast c t)    in
+      let pats = Array.map (get_pattern_terms c) pats              in
+      let nb = get_quantifier_num_bound c t                        in
+      let bound = Array.init nb 
+	  (fun i -> (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i)) in
+      let body = get_quantifier_body c t in
+      Term_quantifier(bt, w, pats, bound, body)
+  | VAR_AST -> 
+      Term_var(get_index_value c t, get_sort c t)
+  | _ -> assert false
+
+
+type theory_callbacks = 
+  {
+     mutable delete_theory : unit -> unit;
+     mutable reduce_eq : ast -> ast -> ast option;
+     mutable reduce_app : func_decl -> ast array -> ast option;
+     mutable reduce_distinct : ast array -> ast option;
+     mutable final_check : unit -> bool;
+     mutable new_app : ast -> unit;
+     mutable new_elem : ast -> unit;
+     mutable init_search: unit -> unit;
+     mutable push: unit -> unit;
+     mutable pop: unit -> unit;
+     mutable restart : unit -> unit;
+     mutable reset: unit -> unit;
+     mutable new_eq : ast -> ast -> unit;
+     mutable new_diseq : ast -> ast -> unit;
+     mutable new_assignment: ast -> bool -> unit;
+     mutable new_relevant : ast -> unit;
+  }
+
+let mk_theory_callbacks() = 
+    {
+     delete_theory = (fun () -> ());
+     reduce_eq = (fun _ _ -> None);
+     reduce_app = (fun _ _ -> None);
+     reduce_distinct = (fun _ -> None);
+     final_check = (fun _ -> true);
+     new_app = (fun _ -> ());
+     new_elem = (fun _ -> ());
+     init_search= (fun () -> ());
+     push= (fun () -> ());
+     pop= (fun () -> ());
+     restart = (fun () -> ());
+     reset= (fun () -> ());
+     new_eq = (fun _ _ -> ());
+     new_diseq = (fun _ _ -> ());
+     new_assignment = (fun _ _ -> ());
+     new_relevant = (fun _ -> ());
+    }
+
+
+external get_theory_callbacks : theory -> theory_callbacks = "get_theory_callbacks"
+external mk_theory_register : context -> string -> theory_callbacks -> theory = "mk_theory_register"
+external set_delete_callback_register : theory -> unit = "set_delete_callback_register"
+external set_reduce_app_callback_register : theory -> unit = "set_reduce_app_callback_register"
+external set_reduce_eq_callback_register : theory -> unit = "set_reduce_eq_callback_register"
+external set_reduce_distinct_callback_register : theory -> unit = "set_reduce_distinct_callback_register"
+external set_new_app_callback_register : theory -> unit = "set_new_app_callback_register"
+external set_new_elem_callback_register : theory -> unit = "set_new_elem_callback_register"
+external set_init_search_callback_register : theory -> unit = "set_init_search_callback_register"
+external set_push_callback_register : theory -> unit = "set_push_callback_register"
+external set_pop_callback_register : theory -> unit = "set_pop_callback_register"
+external set_restart_callback_register : theory -> unit = "set_restart_callback_register"
+external set_reset_callback_register : theory -> unit = "set_reset_callback_register"
+external set_final_check_callback_register : theory -> unit = "set_final_check_callback_register"
+external set_new_eq_callback_register : theory -> unit = "set_new_eq_callback_register"
+external set_new_diseq_callback_register : theory -> unit = "set_new_diseq_callback_register"
+external set_new_assignment_callback_register : theory -> unit = "set_new_assignment_callback_register"
+external set_new_relevant_callback_register : theory -> unit = "set_new_relevant_callback_register"
+
+let is_some opt = 
+    match opt with
+    | Some v -> true
+    | None   -> false
+
+let get_some opt = 
+    match opt with
+    | Some v -> v
+    | None   -> failwith "None unexpected"
+
+  
+
+
+let apply_delete (th:theory_callbacks) = th.delete_theory ()
+let set_delete_callback th cb = 
+    let cbs = get_theory_callbacks th in
+    cbs.delete_theory <- cb;
+    set_delete_callback_register th
+
+let mk_theory context name = 
+    Callback.register "is_some" is_some;
+    Callback.register "get_some" get_some;
+    Callback.register "apply_delete" apply_delete;
+    let cbs = mk_theory_callbacks() in
+    mk_theory_register context name cbs
+
+
+let apply_reduce_app (th:theory_callbacks) f args = th.reduce_app f args
+let set_reduce_app_callback th cb = 
+    Callback.register "apply_reduce_app" apply_reduce_app;
+    let cbs = get_theory_callbacks th in
+    cbs.reduce_app <- cb;
+    set_reduce_app_callback_register th
+
+let apply_reduce_eq (th:theory_callbacks) a b = th.reduce_eq a b
+let set_reduce_eq_callback th cb = 
+    Callback.register "apply_reduce_eq" apply_reduce_eq;
+    let cbs = get_theory_callbacks th in
+    cbs.reduce_eq <- cb;
+    set_reduce_eq_callback_register th
+
+let apply_reduce_distinct (th:theory_callbacks) args = th.reduce_distinct args
+let set_reduce_distinct_callback th cb = 
+    Callback.register "apply_reduce_distinct" apply_reduce_distinct;
+    let cbs = get_theory_callbacks th in
+    cbs.reduce_distinct <- cb;
+    set_reduce_distinct_callback_register th
+ 
+
+let apply_new_app (th:theory_callbacks) a = th.new_app a
+let set_new_app_callback th cb = 
+    Callback.register "apply_new_app" apply_new_app;
+    let cbs = get_theory_callbacks th in
+    cbs.new_app <- cb;
+    set_new_app_callback_register th
+
+let apply_new_elem (th:theory_callbacks) a = th.new_elem a
+let set_new_elem_callback th cb = 
+    Callback.register "apply_new_elem" apply_new_elem;
+    let cbs = get_theory_callbacks th in
+    cbs.new_elem <- cb;
+    set_new_elem_callback_register th
+
+
+let apply_init_search (th:theory_callbacks) = th.init_search()
+let set_init_search_callback th cb = 
+    Callback.register "apply_init_search" apply_init_search;
+    let cbs = get_theory_callbacks th in
+    cbs.init_search <- cb;
+    set_init_search_callback_register th
+
+
+let apply_push (th:theory_callbacks) = th.push()
+let set_push_callback th cb = 
+    Callback.register "apply_push" apply_push;
+    let cbs = get_theory_callbacks th in
+    cbs.push <- cb;
+    set_push_callback_register th
+
+let apply_pop (th:theory_callbacks) = th.pop()
+let set_pop_callback th cb = 
+    Callback.register "apply_pop" apply_pop;
+    let cbs = get_theory_callbacks th in
+    cbs.pop <- cb;
+    set_pop_callback_register th
+ 
+
+let apply_restart (th:theory_callbacks) = th.restart()
+let set_restart_callback th cb = 
+    Callback.register "apply_restart" apply_restart;
+    let cbs = get_theory_callbacks th in
+    cbs.restart <- cb;
+    set_restart_callback_register th
+ 
+
+let apply_reset (th:theory_callbacks) = th.reset()
+let set_reset_callback th cb = 
+    Callback.register "apply_reset" apply_reset;
+    let cbs = get_theory_callbacks th in
+    cbs.reset <- cb;
+    set_reset_callback_register th
+
+let apply_final_check (th:theory_callbacks) = th.final_check()
+let set_final_check_callback th cb = 
+    Callback.register "apply_final_check" apply_final_check;
+    let cbs = get_theory_callbacks th in
+    cbs.final_check <- cb;
+    set_final_check_callback_register th
+
+let apply_new_eq (th:theory_callbacks) a b = th.new_eq a b
+let set_new_eq_callback th cb = 
+    Callback.register "apply_new_eq" apply_new_eq;
+    let cbs = get_theory_callbacks th in
+    cbs.new_eq <- cb;
+    set_new_eq_callback_register th
+
+
+let apply_new_diseq (th:theory_callbacks) a b = th.new_diseq a b
+let set_new_diseq_callback th cb = 
+    Callback.register "apply_new_diseq" apply_new_diseq;
+    let cbs = get_theory_callbacks th in
+    cbs.new_diseq <- cb;
+    set_new_diseq_callback_register th
+
+let apply_new_assignment (th:theory_callbacks) a b = th.new_assignment a b
+let set_new_assignment_callback th cb = 
+    Callback.register "apply_new_assignment" apply_new_assignment;
+    let cbs = get_theory_callbacks th in
+    cbs.new_assignment <- cb;
+    set_new_assignment_callback_register th
+
+let apply_new_relevant (th:theory_callbacks) a = th.new_relevant a
+let set_new_relevant_callback th cb = 
+    Callback.register "apply_new_relevant" apply_new_relevant;
+    let cbs = get_theory_callbacks th in
+    cbs.new_relevant <- cb;
+    set_new_relevant_callback_register th
+ 
+
+
+
+
+ external/z3/ocaml/z3_stubs.c view
@@ -0,0 +1,7761 @@+/* File generated from z3.idl */
+
+#include <stddef.h>
+#include <string.h>
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/callback.h>
+#ifdef Custom_tag
+#include <caml/custom.h>
+#include <caml/bigarray.h>
+#endif
+#include <caml/camlidlruntime.h>
+
+
+#include "z3.h"
+
+#pragma warning(disable:4090)
+#ifndef __int64
+#define __int64 long long
+#endif
+Z3_error_handler caml_z3_error_handler;
+void caml_z3_error_handler(Z3_error_code e) { static char buffer[128]; char * msg = Z3_get_error_msg(e); if (strlen(msg) > 100) { failwith("Z3: error message is too big"); } else { sprintf(buffer, "Z3: %s", msg); failwith(buffer); } }
+void camlidl_ml2c_z3_Z3_config(value _v1, Z3_config * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_config *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_config(Z3_config * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_config) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_config *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_context(value _v1, Z3_context * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_context *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_context(Z3_context * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_context) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_context *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_sort(value _v1, Z3_sort * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_sort *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_sort(Z3_sort * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_sort) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_sort *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_func_decl(value _v1, Z3_func_decl * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_func_decl *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_func_decl(Z3_func_decl * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_func_decl) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_func_decl *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_ast(value _v1, Z3_ast * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_ast *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_ast(Z3_ast * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_ast) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_ast *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_app(value _v1, Z3_app * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_app *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_app(Z3_app * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_app) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_app *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_pattern(value _v1, Z3_pattern * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_pattern *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_pattern(Z3_pattern * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_pattern) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_pattern *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_symbol(value _v1, Z3_symbol * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_symbol *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_symbol(Z3_symbol * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_symbol) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_symbol *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_parameter(value _v1, Z3_parameter * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_parameter *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_parameter(Z3_parameter * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_parameter) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_parameter *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_model(value _v1, Z3_model * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_model *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_model(Z3_model * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_model) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_model *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_literals(value _v1, Z3_literals * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_literals *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_literals(Z3_literals * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_literals) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_literals *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_constructor(value _v1, Z3_constructor * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_constructor *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_constructor(Z3_constructor * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_constructor) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_constructor *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_constructor_list(value _v1, Z3_constructor_list * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_constructor_list *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_constructor_list(Z3_constructor_list * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_constructor_list) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_constructor_list *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_theory(value _v1, Z3_theory * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_theory *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_theory(Z3_theory * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_theory) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_theory *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+void camlidl_ml2c_z3_Z3_theory_data(value _v1, Z3_theory_data * _c2, camlidl_ctx _ctx)
+{
+  *_c2 = *((Z3_theory_data *) Bp_val(_v1));
+}
+
+value camlidl_c2ml_z3_Z3_theory_data(Z3_theory_data * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_alloc((sizeof(Z3_theory_data) + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+  *((Z3_theory_data *) Bp_val(_v1)) = *_c2;
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_1[3] = {
+  Z3_L_FALSE,
+  Z3_L_UNDEF,
+  Z3_L_TRUE,
+};
+
+void camlidl_ml2c_z3_Z3_lbool(value _v1, Z3_lbool * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_1[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_lbool(Z3_lbool * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  switch((*_c2)) {
+  case Z3_L_FALSE: _v1 = Val_int(0); break;
+  case Z3_L_UNDEF: _v1 = Val_int(1); break;
+  case Z3_L_TRUE: _v1 = Val_int(2); break;
+  default: invalid_argument("typedef Z3_lbool: bad enum  value");
+  }
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_2[2] = {
+  Z3_INT_SYMBOL,
+  Z3_STRING_SYMBOL,
+};
+
+void camlidl_ml2c_z3_Z3_symbol_kind(value _v1, Z3_symbol_kind * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_2[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_symbol_kind(Z3_symbol_kind * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  switch((*_c2)) {
+  case Z3_INT_SYMBOL: _v1 = Val_int(0); break;
+  case Z3_STRING_SYMBOL: _v1 = Val_int(1); break;
+  default: invalid_argument("typedef Z3_symbol_kind: bad enum  value");
+  }
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_3[7] = {
+  Z3_PARAMETER_INT,
+  Z3_PARAMETER_DOUBLE,
+  Z3_PARAMETER_RATIONAL,
+  Z3_PARAMETER_SYMBOL,
+  Z3_PARAMETER_SORT,
+  Z3_PARAMETER_AST,
+  Z3_PARAMETER_FUNC_DECL,
+};
+
+void camlidl_ml2c_z3_Z3_parameter_kind(value _v1, Z3_parameter_kind * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_3[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_parameter_kind(Z3_parameter_kind * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_3, 7, "typedef Z3_parameter_kind: bad enum  value");
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_4[10] = {
+  Z3_UNINTERPRETED_SORT,
+  Z3_BOOL_SORT,
+  Z3_INT_SORT,
+  Z3_REAL_SORT,
+  Z3_BV_SORT,
+  Z3_ARRAY_SORT,
+  Z3_DATATYPE_SORT,
+  Z3_RELATION_SORT,
+  Z3_FINITE_DOMAIN_SORT,
+  Z3_UNKNOWN_SORT,
+};
+
+void camlidl_ml2c_z3_Z3_sort_kind(value _v1, Z3_sort_kind * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_4[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_sort_kind(Z3_sort_kind * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_4, 10, "typedef Z3_sort_kind: bad enum  value");
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_5[5] = {
+  Z3_NUMERAL_AST,
+  Z3_APP_AST,
+  Z3_VAR_AST,
+  Z3_QUANTIFIER_AST,
+  Z3_UNKNOWN_AST,
+};
+
+void camlidl_ml2c_z3_Z3_ast_kind(value _v1, Z3_ast_kind * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_5[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_ast_kind(Z3_ast_kind * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_5, 5, "typedef Z3_ast_kind: bad enum  value");
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_6[144] = {
+  Z3_OP_TRUE,
+  Z3_OP_FALSE,
+  Z3_OP_EQ,
+  Z3_OP_DISTINCT,
+  Z3_OP_ITE,
+  Z3_OP_AND,
+  Z3_OP_OR,
+  Z3_OP_IFF,
+  Z3_OP_XOR,
+  Z3_OP_NOT,
+  Z3_OP_IMPLIES,
+  Z3_OP_OEQ,
+  Z3_OP_ANUM,
+  Z3_OP_LE,
+  Z3_OP_GE,
+  Z3_OP_LT,
+  Z3_OP_GT,
+  Z3_OP_ADD,
+  Z3_OP_SUB,
+  Z3_OP_UMINUS,
+  Z3_OP_MUL,
+  Z3_OP_DIV,
+  Z3_OP_IDIV,
+  Z3_OP_REM,
+  Z3_OP_MOD,
+  Z3_OP_TO_REAL,
+  Z3_OP_TO_INT,
+  Z3_OP_IS_INT,
+  Z3_OP_STORE,
+  Z3_OP_SELECT,
+  Z3_OP_CONST_ARRAY,
+  Z3_OP_ARRAY_MAP,
+  Z3_OP_ARRAY_DEFAULT,
+  Z3_OP_SET_UNION,
+  Z3_OP_SET_INTERSECT,
+  Z3_OP_SET_DIFFERENCE,
+  Z3_OP_SET_COMPLEMENT,
+  Z3_OP_SET_SUBSET,
+  Z3_OP_AS_ARRAY,
+  Z3_OP_BNUM,
+  Z3_OP_BIT1,
+  Z3_OP_BIT0,
+  Z3_OP_BNEG,
+  Z3_OP_BADD,
+  Z3_OP_BSUB,
+  Z3_OP_BMUL,
+  Z3_OP_BSDIV,
+  Z3_OP_BUDIV,
+  Z3_OP_BSREM,
+  Z3_OP_BUREM,
+  Z3_OP_BSMOD,
+  Z3_OP_BSDIV0,
+  Z3_OP_BUDIV0,
+  Z3_OP_BSREM0,
+  Z3_OP_BUREM0,
+  Z3_OP_BSMOD0,
+  Z3_OP_ULEQ,
+  Z3_OP_SLEQ,
+  Z3_OP_UGEQ,
+  Z3_OP_SGEQ,
+  Z3_OP_ULT,
+  Z3_OP_SLT,
+  Z3_OP_UGT,
+  Z3_OP_SGT,
+  Z3_OP_BAND,
+  Z3_OP_BOR,
+  Z3_OP_BNOT,
+  Z3_OP_BXOR,
+  Z3_OP_BNAND,
+  Z3_OP_BNOR,
+  Z3_OP_BXNOR,
+  Z3_OP_CONCAT,
+  Z3_OP_SIGN_EXT,
+  Z3_OP_ZERO_EXT,
+  Z3_OP_EXTRACT,
+  Z3_OP_REPEAT,
+  Z3_OP_BREDOR,
+  Z3_OP_BREDAND,
+  Z3_OP_BCOMP,
+  Z3_OP_BSHL,
+  Z3_OP_BLSHR,
+  Z3_OP_BASHR,
+  Z3_OP_ROTATE_LEFT,
+  Z3_OP_ROTATE_RIGHT,
+  Z3_OP_EXT_ROTATE_LEFT,
+  Z3_OP_EXT_ROTATE_RIGHT,
+  Z3_OP_INT2BV,
+  Z3_OP_BV2INT,
+  Z3_OP_CARRY,
+  Z3_OP_XOR3,
+  Z3_OP_PR_UNDEF,
+  Z3_OP_PR_TRUE,
+  Z3_OP_PR_ASSERTED,
+  Z3_OP_PR_GOAL,
+  Z3_OP_PR_MODUS_PONENS,
+  Z3_OP_PR_REFLEXIVITY,
+  Z3_OP_PR_SYMMETRY,
+  Z3_OP_PR_TRANSITIVITY,
+  Z3_OP_PR_TRANSITIVITY_STAR,
+  Z3_OP_PR_MONOTONICITY,
+  Z3_OP_PR_QUANT_INTRO,
+  Z3_OP_PR_DISTRIBUTIVITY,
+  Z3_OP_PR_AND_ELIM,
+  Z3_OP_PR_NOT_OR_ELIM,
+  Z3_OP_PR_REWRITE,
+  Z3_OP_PR_REWRITE_STAR,
+  Z3_OP_PR_PULL_QUANT,
+  Z3_OP_PR_PULL_QUANT_STAR,
+  Z3_OP_PR_PUSH_QUANT,
+  Z3_OP_PR_ELIM_UNUSED_VARS,
+  Z3_OP_PR_DER,
+  Z3_OP_PR_QUANT_INST,
+  Z3_OP_PR_HYPOTHESIS,
+  Z3_OP_PR_LEMMA,
+  Z3_OP_PR_UNIT_RESOLUTION,
+  Z3_OP_PR_IFF_TRUE,
+  Z3_OP_PR_IFF_FALSE,
+  Z3_OP_PR_COMMUTATIVITY,
+  Z3_OP_PR_DEF_AXIOM,
+  Z3_OP_PR_DEF_INTRO,
+  Z3_OP_PR_APPLY_DEF,
+  Z3_OP_PR_IFF_OEQ,
+  Z3_OP_PR_NNF_POS,
+  Z3_OP_PR_NNF_NEG,
+  Z3_OP_PR_NNF_STAR,
+  Z3_OP_PR_CNF_STAR,
+  Z3_OP_PR_SKOLEMIZE,
+  Z3_OP_PR_MODUS_PONENS_OEQ,
+  Z3_OP_PR_TH_LEMMA,
+  Z3_OP_RA_STORE,
+  Z3_OP_RA_EMPTY,
+  Z3_OP_RA_IS_EMPTY,
+  Z3_OP_RA_JOIN,
+  Z3_OP_RA_UNION,
+  Z3_OP_RA_WIDEN,
+  Z3_OP_RA_PROJECT,
+  Z3_OP_RA_FILTER,
+  Z3_OP_RA_NEGATION_FILTER,
+  Z3_OP_RA_RENAME,
+  Z3_OP_RA_COMPLEMENT,
+  Z3_OP_RA_SELECT,
+  Z3_OP_RA_CLONE,
+  Z3_OP_FD_LT,
+  Z3_OP_UNINTERPRETED,
+};
+
+void camlidl_ml2c_z3_Z3_decl_kind(value _v1, Z3_decl_kind * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_6[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_decl_kind(Z3_decl_kind * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_6, 144, "typedef Z3_decl_kind: bad enum  value");
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_7[8] = {
+  Z3_NO_FAILURE,
+  Z3_UNKNOWN,
+  Z3_TIMEOUT,
+  Z3_MEMOUT_WATERMARK,
+  Z3_CANCELED,
+  Z3_NUM_CONFLICTS,
+  Z3_THEORY,
+  Z3_QUANTIFIERS,
+};
+
+void camlidl_ml2c_z3_Z3_search_failure(value _v1, Z3_search_failure * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_7[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_search_failure(Z3_search_failure * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_7, 8, "typedef Z3_search_failure: bad enum  value");
+  return _v1;
+}
+
+int camlidl_transl_table_z3_enum_8[4] = {
+  Z3_PRINT_SMTLIB_FULL,
+  Z3_PRINT_LOW_LEVEL,
+  Z3_PRINT_SMTLIB_COMPLIANT,
+  Z3_PRINT_SMTLIB2_COMPLIANT,
+};
+
+void camlidl_ml2c_z3_Z3_ast_print_mode(value _v1, Z3_ast_print_mode * _c2, camlidl_ctx _ctx)
+{
+  (*_c2) = camlidl_transl_table_z3_enum_8[Int_val(_v1)];
+}
+
+value camlidl_c2ml_z3_Z3_ast_print_mode(Z3_ast_print_mode * _c2, camlidl_ctx _ctx)
+{
+value _v1;
+  switch((*_c2)) {
+  case Z3_PRINT_SMTLIB_FULL: _v1 = Val_int(0); break;
+  case Z3_PRINT_LOW_LEVEL: _v1 = Val_int(1); break;
+  case Z3_PRINT_SMTLIB_COMPLIANT: _v1 = Val_int(2); break;
+  case Z3_PRINT_SMTLIB2_COMPLIANT: _v1 = Val_int(3); break;
+  default: invalid_argument("typedef Z3_ast_print_mode: bad enum  value");
+  }
+  return _v1;
+}
+
+value camlidl_z3_Z3_mk_config(value _unit)
+{
+  Z3_config _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  _res = Z3_mk_config();
+  _vres = camlidl_c2ml_z3_Z3_config(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_del_config(
+	value _v_c)
+{
+  Z3_config c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_config(_v_c, &c, _ctx);
+  Z3_del_config(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_set_param_value(
+	value _v_c,
+	value _v_param_id,
+	value _v_param_value)
+{
+  Z3_config c; /*in*/
+  char const *param_id; /*in*/
+  char const *param_value; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_config(_v_c, &c, _ctx);
+  param_id = String_val(_v_param_id);
+  param_value = String_val(_v_param_value);
+  Z3_set_param_value(c, param_id, param_value);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_mk_context(
+	value _v_c)
+{
+  Z3_config c; /*in*/
+  Z3_context _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_config(_v_c, &c, _ctx);
+  _res = Z3_mk_context(c);
+  _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx);
+  camlidl_free(_ctx);
+  /* begin user-supplied deallocation sequence */
+Z3_set_error_handler(_res, caml_z3_error_handler);
+  /* end user-supplied deallocation sequence */
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_context_rc(
+	value _v_c)
+{
+  Z3_config c; /*in*/
+  Z3_context _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_config(_v_c, &c, _ctx);
+  _res = Z3_mk_context_rc(c);
+  _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx);
+  camlidl_free(_ctx);
+  /* begin user-supplied deallocation sequence */
+Z3_set_error_handler(_res, caml_z3_error_handler);
+  /* end user-supplied deallocation sequence */
+  return _vres;
+}
+
+value camlidl_z3_Z3_set_logic(
+	value _v_c,
+	value _v_logic)
+{
+  Z3_context c; /*in*/
+  char const *logic; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  logic = String_val(_v_logic);
+  _res = Z3_set_logic(c, logic);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_del_context(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_del_context(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_inc_ref(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  Z3_inc_ref(c, a);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_dec_ref(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  Z3_dec_ref(c, a);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_trace_to_file(
+	value _v_c,
+	value _v_trace_file)
+{
+  Z3_context c; /*in*/
+  char const *trace_file; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  trace_file = String_val(_v_trace_file);
+  _res = Z3_trace_to_file(c, trace_file);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_trace_to_stderr(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_trace_to_stderr(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_trace_to_stdout(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_trace_to_stdout(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_trace_off(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_trace_off(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_toggle_warning_messages(
+	value _v_enabled)
+{
+  int enabled; /*in*/
+  enabled = Int_val(_v_enabled);
+  Z3_toggle_warning_messages(enabled);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_update_param_value(
+	value _v_c,
+	value _v_param_id,
+	value _v_param_value)
+{
+  Z3_context c; /*in*/
+  char const *param_id; /*in*/
+  char const *param_value; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  param_id = String_val(_v_param_id);
+  param_value = String_val(_v_param_value);
+  Z3_update_param_value(c, param_id, param_value);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_mk_int_symbol(
+	value _v_c,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  int i; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_mk_int_symbol(c, i);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_string_symbol(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  char const *s; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  s = String_val(_v_s);
+  _res = Z3_mk_string_symbol(c, s);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_is_eq_sort(
+	value _v_c,
+	value _v_s1,
+	value _v_s2)
+{
+  Z3_context c; /*in*/
+  Z3_sort s1; /*in*/
+  Z3_sort s2; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s1, &s1, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s2, &s2, _ctx);
+  _res = Z3_is_eq_sort(c, s1, s2);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_uninterpreted_sort(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _res = Z3_mk_uninterpreted_sort(c, s);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bool_sort(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_mk_bool_sort(c);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_int_sort(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_mk_int_sort(c);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_real_sort(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_mk_real_sort(c);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bv_sort(
+	value _v_c,
+	value _v_sz)
+{
+  Z3_context c; /*in*/
+  unsigned int sz; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  sz = Int_val(_v_sz);
+  _res = Z3_mk_bv_sort(c, sz);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_array_sort(
+	value _v_c,
+	value _v_domain,
+	value _v_range)
+{
+  Z3_context c; /*in*/
+  Z3_sort domain; /*in*/
+  Z3_sort range; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx);
+  _res = Z3_mk_array_sort(c, domain, range);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_tuple_sort(
+	value _v_c,
+	value _v_mk_tuple_name,
+	value _v_field_names,
+	value _v_field_sorts)
+{
+  Z3_context c; /*in*/
+  Z3_symbol mk_tuple_name; /*in*/
+  unsigned int num_fields; /*in*/
+  Z3_symbol const *field_names; /*in*/
+  Z3_sort const *field_sorts; /*in*/
+  Z3_func_decl *mk_tuple_decl; /*out*/
+  Z3_func_decl *proj_decl; /*out*/
+  Z3_sort _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  Z3_func_decl _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vresult;
+  value _vres[3] = { 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_mk_tuple_name, &mk_tuple_name, _ctx);
+  _c1 = Wosize_val(_v_field_names);
+  field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_field_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &field_names[_c2], _ctx);
+  }
+  num_fields = _c1;
+  _c4 = Wosize_val(_v_field_sorts);
+  field_sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_field_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &field_sorts[_c5], _ctx);
+  }
+  num_fields = _c4;
+  mk_tuple_decl = &_c7;
+  proj_decl = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx);
+  _res = Z3_mk_tuple_sort(c, mk_tuple_name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decl);
+  Begin_roots_block(_vres, 3)
+    _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+    _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*mk_tuple_decl, _ctx);
+    _vres[2] = camlidl_alloc(num_fields, 0);
+    Begin_root(_vres[2])
+      for (_c8 = 0; _c8 < num_fields; _c8++) {
+        _v9 = camlidl_c2ml_z3_Z3_func_decl(&proj_decl[_c8], _ctx);
+        modify(&Field(_vres[2], _c8), _v9);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(3, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_mk_enumeration_sort(
+	value _v_c,
+	value _v_name,
+	value _v_enum_names)
+{
+  Z3_context c; /*in*/
+  Z3_symbol name; /*in*/
+  unsigned int n; /*in*/
+  Z3_symbol const *enum_names; /*in*/
+  Z3_func_decl *enum_consts; /*out*/
+  Z3_func_decl *enum_testers; /*out*/
+  Z3_sort _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  value _v5;
+  mlsize_t _c6;
+  value _v7;
+  value _vresult;
+  value _vres[3] = { 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx);
+  _c1 = Wosize_val(_v_enum_names);
+  enum_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_enum_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &enum_names[_c2], _ctx);
+  }
+  n = _c1;
+  enum_consts = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx);
+  enum_testers = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx);
+  _res = Z3_mk_enumeration_sort(c, name, n, enum_names, enum_consts, enum_testers);
+  Begin_roots_block(_vres, 3)
+    _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+    _vres[1] = camlidl_alloc(n, 0);
+    Begin_root(_vres[1])
+      for (_c4 = 0; _c4 < n; _c4++) {
+        _v5 = camlidl_c2ml_z3_Z3_func_decl(&enum_consts[_c4], _ctx);
+        modify(&Field(_vres[1], _c4), _v5);
+      }
+    End_roots()
+    _vres[2] = camlidl_alloc(n, 0);
+    Begin_root(_vres[2])
+      for (_c6 = 0; _c6 < n; _c6++) {
+        _v7 = camlidl_c2ml_z3_Z3_func_decl(&enum_testers[_c6], _ctx);
+        modify(&Field(_vres[2], _c6), _v7);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(3, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_mk_list_sort(
+	value _v_c,
+	value _v_name,
+	value _v_elem_sort)
+{
+  Z3_context c; /*in*/
+  Z3_symbol name; /*in*/
+  Z3_sort elem_sort; /*in*/
+  Z3_func_decl *nil_decl; /*out*/
+  Z3_func_decl *is_nil_decl; /*out*/
+  Z3_func_decl *cons_decl; /*out*/
+  Z3_func_decl *is_cons_decl; /*out*/
+  Z3_func_decl *head_decl; /*out*/
+  Z3_func_decl *tail_decl; /*out*/
+  Z3_sort _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  Z3_func_decl _c1;
+  Z3_func_decl _c2;
+  Z3_func_decl _c3;
+  Z3_func_decl _c4;
+  Z3_func_decl _c5;
+  Z3_func_decl _c6;
+  value _vresult;
+  value _vres[7] = { 0, 0, 0, 0, 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_elem_sort, &elem_sort, _ctx);
+  nil_decl = &_c1;
+  is_nil_decl = &_c2;
+  cons_decl = &_c3;
+  is_cons_decl = &_c4;
+  head_decl = &_c5;
+  tail_decl = &_c6;
+  _res = Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl);
+  Begin_roots_block(_vres, 7)
+    _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+    _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*nil_decl, _ctx);
+    _vres[2] = camlidl_c2ml_z3_Z3_func_decl(&*is_nil_decl, _ctx);
+    _vres[3] = camlidl_c2ml_z3_Z3_func_decl(&*cons_decl, _ctx);
+    _vres[4] = camlidl_c2ml_z3_Z3_func_decl(&*is_cons_decl, _ctx);
+    _vres[5] = camlidl_c2ml_z3_Z3_func_decl(&*head_decl, _ctx);
+    _vres[6] = camlidl_c2ml_z3_Z3_func_decl(&*tail_decl, _ctx);
+    _vresult = camlidl_alloc_small(7, 0);
+    { mlsize_t _c7;
+      for (_c7 = 0; _c7 < 7; _c7++) Field(_vresult, _c7) = _vres[_c7];
+    }
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_mk_constructor(
+	value _v_c,
+	value _v_name,
+	value _v_recognizer,
+	value _v_field_names,
+	value _v_sorts,
+	value _v_sort_refs)
+{
+  Z3_context c; /*in*/
+  Z3_symbol name; /*in*/
+  Z3_symbol recognizer; /*in*/
+  unsigned int num_fields; /*in*/
+  Z3_symbol const *field_names; /*in*/
+  Z3_sort const *sorts; /*in*/
+  unsigned int *sort_refs; /*in*/
+  Z3_constructor _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_recognizer, &recognizer, _ctx);
+  _c1 = Wosize_val(_v_field_names);
+  field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_field_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &field_names[_c2], _ctx);
+  }
+  num_fields = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_fields = _c4;
+  _c7 = Wosize_val(_v_sort_refs);
+  sort_refs = camlidl_malloc(_c7 * sizeof(unsigned int ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_sort_refs, _c8);
+    sort_refs[_c8] = Int_val(_v9);
+  }
+  num_fields = _c7;
+  _res = Z3_mk_constructor(c, name, recognizer, num_fields, field_names, sorts, sort_refs);
+  _vres = camlidl_c2ml_z3_Z3_constructor(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_constructor_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_constructor(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_query_constructor(
+	value _v_c,
+	value _v_constr,
+	value _v_num_fields)
+{
+  Z3_context c; /*in*/
+  Z3_constructor constr; /*in*/
+  unsigned int num_fields; /*in*/
+  Z3_func_decl *constructor; /*out*/
+  Z3_func_decl *tester; /*out*/
+  Z3_func_decl *accessors; /*out*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  Z3_func_decl _c1;
+  Z3_func_decl _c2;
+  mlsize_t _c3;
+  value _v4;
+  value _vresult;
+  value _vres[3] = { 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_constructor(_v_constr, &constr, _ctx);
+  num_fields = Int_val(_v_num_fields);
+  constructor = &_c1;
+  tester = &_c2;
+  accessors = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx);
+  Z3_query_constructor(c, constr, num_fields, constructor, tester, accessors);
+  Begin_roots_block(_vres, 3)
+    _vres[0] = camlidl_c2ml_z3_Z3_func_decl(&*constructor, _ctx);
+    _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*tester, _ctx);
+    _vres[2] = camlidl_alloc(num_fields, 0);
+    Begin_root(_vres[2])
+      for (_c3 = 0; _c3 < num_fields; _c3++) {
+        _v4 = camlidl_c2ml_z3_Z3_func_decl(&accessors[_c3], _ctx);
+        modify(&Field(_vres[2], _c3), _v4);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(3, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_del_constructor(
+	value _v_c,
+	value _v_constr)
+{
+  Z3_context c; /*in*/
+  Z3_constructor constr; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_constructor(_v_constr, &constr, _ctx);
+  Z3_del_constructor(c, constr);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_mk_datatype(
+	value _v_c,
+	value _v_name,
+	value _v_constructors)
+{
+  Z3_context c; /*in*/
+  Z3_symbol name; /*in*/
+  unsigned int num_constructors; /*in*/
+  Z3_constructor *constructors; /*in,out*/
+  Z3_sort _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  value _v5;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx);
+  _c1 = Wosize_val(_v_constructors);
+  constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_constructors, _c2);
+    camlidl_ml2c_z3_Z3_constructor(_v3, &constructors[_c2], _ctx);
+  }
+  num_constructors = _c1;
+  _res = Z3_mk_datatype(c, name, num_constructors, constructors);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+    _vres[1] = camlidl_alloc(num_constructors, 0);
+    Begin_root(_vres[1])
+      for (_c4 = 0; _c4 < num_constructors; _c4++) {
+        _v5 = camlidl_c2ml_z3_Z3_constructor(&constructors[_c4], _ctx);
+        modify(&Field(_vres[1], _c4), _v5);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_mk_constructor_list(
+	value _v_c,
+	value _v_constructors)
+{
+  Z3_context c; /*in*/
+  unsigned int num_constructors; /*in*/
+  Z3_constructor *constructors; /*in*/
+  Z3_constructor_list _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_constructors);
+  constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_constructors, _c2);
+    camlidl_ml2c_z3_Z3_constructor(_v3, &constructors[_c2], _ctx);
+  }
+  num_constructors = _c1;
+  _res = Z3_mk_constructor_list(c, num_constructors, constructors);
+  _vres = camlidl_c2ml_z3_Z3_constructor_list(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_del_constructor_list(
+	value _v_c,
+	value _v_clist)
+{
+  Z3_context c; /*in*/
+  Z3_constructor_list clist; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_constructor_list(_v_clist, &clist, _ctx);
+  Z3_del_constructor_list(c, clist);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_mk_datatypes(
+	value _v_c,
+	value _v_sort_names,
+	value _v_constructor_lists)
+{
+  Z3_context c; /*in*/
+  unsigned int num_sorts; /*in*/
+  Z3_symbol *sort_names; /*in*/
+  Z3_sort *sorts; /*out*/
+  Z3_constructor_list *constructor_lists; /*in,out*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  value _v8;
+  mlsize_t _c9;
+  value _v10;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_sort_names);
+  sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_sort_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx);
+  }
+  num_sorts = _c1;
+  _c4 = Wosize_val(_v_constructor_lists);
+  constructor_lists = camlidl_malloc(_c4 * sizeof(Z3_constructor_list ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_constructor_lists, _c5);
+    camlidl_ml2c_z3_Z3_constructor_list(_v6, &constructor_lists[_c5], _ctx);
+  }
+  num_sorts = _c4;
+  sorts = camlidl_malloc(num_sorts * sizeof(Z3_sort ), _ctx);
+  Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = camlidl_alloc(num_sorts, 0);
+    Begin_root(_vres[0])
+      for (_c7 = 0; _c7 < num_sorts; _c7++) {
+        _v8 = camlidl_c2ml_z3_Z3_sort(&sorts[_c7], _ctx);
+        modify(&Field(_vres[0], _c7), _v8);
+      }
+    End_roots()
+    _vres[1] = camlidl_alloc(num_sorts, 0);
+    Begin_root(_vres[1])
+      for (_c9 = 0; _c9 < num_sorts; _c9++) {
+        _v10 = camlidl_c2ml_z3_Z3_constructor_list(&constructor_lists[_c9], _ctx);
+        modify(&Field(_vres[1], _c9), _v10);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_mk_injective_function(
+	value _v_c,
+	value _v_s,
+	value _v_domain,
+	value _v_range)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  unsigned int domain_size; /*in*/
+  Z3_sort const *domain; /*in*/
+  Z3_sort range; /*in*/
+  Z3_func_decl _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _c1 = Wosize_val(_v_domain);
+  domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_domain, _c2);
+    camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx);
+  }
+  domain_size = _c1;
+  camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx);
+  _res = Z3_mk_injective_function(c, s, domain_size, domain, range);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_is_eq_ast(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_is_eq_ast(c, t1, t2);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_is_eq_func_decl(
+	value _v_c,
+	value _v_f1,
+	value _v_f2)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl f1; /*in*/
+  Z3_func_decl f2; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f1, &f1, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f2, &f2, _ctx);
+  _res = Z3_is_eq_func_decl(c, f1, f2);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_func_decl(
+	value _v_c,
+	value _v_s,
+	value _v_domain,
+	value _v_range)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  unsigned int domain_size; /*in*/
+  Z3_sort const *domain; /*in*/
+  Z3_sort range; /*in*/
+  Z3_func_decl _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _c1 = Wosize_val(_v_domain);
+  domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_domain, _c2);
+    camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx);
+  }
+  domain_size = _c1;
+  camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx);
+  _res = Z3_mk_func_decl(c, s, domain_size, domain, range);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_app(
+	value _v_c,
+	value _v_d,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_app(c, d, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_const(
+	value _v_c,
+	value _v_s,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_const(c, s, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_label(
+	value _v_c,
+	value _v_s,
+	value _v_is_pos,
+	value _v_f)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  int is_pos; /*in*/
+  Z3_ast f; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  is_pos = Int_val(_v_is_pos);
+  camlidl_ml2c_z3_Z3_ast(_v_f, &f, _ctx);
+  _res = Z3_mk_label(c, s, is_pos, f);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_fresh_func_decl(
+	value _v_c,
+	value _v_prefix,
+	value _v_domain,
+	value _v_range)
+{
+  Z3_context c; /*in*/
+  char const *prefix; /*in*/
+  unsigned int domain_size; /*in*/
+  Z3_sort const *domain; /*in*/
+  Z3_sort range; /*in*/
+  Z3_func_decl _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  prefix = String_val(_v_prefix);
+  _c1 = Wosize_val(_v_domain);
+  domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_domain, _c2);
+    camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx);
+  }
+  domain_size = _c1;
+  camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx);
+  _res = Z3_mk_fresh_func_decl(c, prefix, domain_size, domain, range);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_fresh_const(
+	value _v_c,
+	value _v_prefix,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  char const *prefix; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  prefix = String_val(_v_prefix);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_fresh_const(c, prefix, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_true(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_mk_true(c);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_false(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_mk_false(c);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_eq(
+	value _v_c,
+	value _v_l,
+	value _v_r)
+{
+  Z3_context c; /*in*/
+  Z3_ast l; /*in*/
+  Z3_ast r; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_l, &l, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_r, &r, _ctx);
+  _res = Z3_mk_eq(c, l, r);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_distinct(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_distinct(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_not(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_mk_not(c, a);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_ite(
+	value _v_c,
+	value _v_t1,
+	value _v_t2,
+	value _v_t3)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast t3; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t3, &t3, _ctx);
+  _res = Z3_mk_ite(c, t1, t2, t3);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_iff(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_iff(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_implies(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_implies(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_xor(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_xor(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_and(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_and(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_or(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_or(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_add(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_add(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_mul(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_mul(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_sub(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_sub(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_unary_minus(
+	value _v_c,
+	value _v_arg)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg, &arg, _ctx);
+  _res = Z3_mk_unary_minus(c, arg);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_div(
+	value _v_c,
+	value _v_arg1,
+	value _v_arg2)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg1; /*in*/
+  Z3_ast arg2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx);
+  _res = Z3_mk_div(c, arg1, arg2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_mod(
+	value _v_c,
+	value _v_arg1,
+	value _v_arg2)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg1; /*in*/
+  Z3_ast arg2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx);
+  _res = Z3_mk_mod(c, arg1, arg2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_rem(
+	value _v_c,
+	value _v_arg1,
+	value _v_arg2)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg1; /*in*/
+  Z3_ast arg2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx);
+  _res = Z3_mk_rem(c, arg1, arg2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_lt(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_lt(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_le(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_le(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_gt(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_gt(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_ge(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_ge(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_int2real(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_int2real(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_real2int(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_real2int(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_is_int(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_is_int(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvnot(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_bvnot(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvredand(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_bvredand(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvredor(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_bvredor(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvand(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvand(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvor(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvor(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvxor(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvxor(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvnand(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvnand(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvnor(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvnor(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvxnor(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvxnor(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvneg(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_bvneg(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvadd(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvadd(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsub(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsub(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvmul(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvmul(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvudiv(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvudiv(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsdiv(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsdiv(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvurem(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvurem(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsrem(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsrem(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsmod(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsmod(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvult(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvult(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvslt(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvslt(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvule(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvule(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsle(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsle(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvuge(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvuge(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsge(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsge(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvugt(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvugt(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsgt(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsgt(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_concat(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_concat(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_extract(
+	value _v_c,
+	value _v_high,
+	value _v_low,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int high; /*in*/
+  unsigned int low; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  high = Int_val(_v_high);
+  low = Int_val(_v_low);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_extract(c, high, low, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_sign_ext(
+	value _v_c,
+	value _v_i,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_sign_ext(c, i, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_zero_ext(
+	value _v_c,
+	value _v_i,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_zero_ext(c, i, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_repeat(
+	value _v_c,
+	value _v_i,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_repeat(c, i, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvshl(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvshl(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvlshr(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvlshr(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvashr(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvashr(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_rotate_left(
+	value _v_c,
+	value _v_i,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_rotate_left(c, i, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_rotate_right(
+	value _v_c,
+	value _v_i,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_rotate_right(c, i, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_ext_rotate_left(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_ext_rotate_left(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_ext_rotate_right(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_ext_rotate_right(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_int2bv(
+	value _v_c,
+	value _v_n,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  unsigned int n; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  n = Int_val(_v_n);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_int2bv(c, n, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bv2int(
+	value _v_c,
+	value _v_t1,
+	value _v_is_signed)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  int is_signed; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  is_signed = Int_val(_v_is_signed);
+  _res = Z3_mk_bv2int(c, t1, is_signed);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvadd_no_overflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2,
+	value _v_is_signed)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  int is_signed; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  is_signed = Int_val(_v_is_signed);
+  _res = Z3_mk_bvadd_no_overflow(c, t1, t2, is_signed);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvadd_no_underflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvadd_no_underflow(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsub_no_overflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsub_no_overflow(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsub_no_underflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2,
+	value _v_is_signed)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  int is_signed; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  is_signed = Int_val(_v_is_signed);
+  _res = Z3_mk_bvsub_no_underflow(c, t1, t2, is_signed);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvsdiv_no_overflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvsdiv_no_overflow(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvneg_no_overflow(
+	value _v_c,
+	value _v_t1)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  _res = Z3_mk_bvneg_no_overflow(c, t1);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvmul_no_overflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2,
+	value _v_is_signed)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  int is_signed; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  is_signed = Int_val(_v_is_signed);
+  _res = Z3_mk_bvmul_no_overflow(c, t1, t2, is_signed);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bvmul_no_underflow(
+	value _v_c,
+	value _v_t1,
+	value _v_t2)
+{
+  Z3_context c; /*in*/
+  Z3_ast t1; /*in*/
+  Z3_ast t2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx);
+  _res = Z3_mk_bvmul_no_underflow(c, t1, t2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_select(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_i, &i, _ctx);
+  _res = Z3_mk_select(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_store(
+	value _v_c,
+	value _v_a,
+	value _v_i,
+	value _v_v)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast i; /*in*/
+  Z3_ast v; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_i, &i, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  _res = Z3_mk_store(c, a, i, v);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_const_array(
+	value _v_c,
+	value _v_domain,
+	value _v_v)
+{
+  Z3_context c; /*in*/
+  Z3_sort domain; /*in*/
+  Z3_ast v; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  _res = Z3_mk_const_array(c, domain, v);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_map(
+	value _v_c,
+	value _v_f,
+	value _v_n,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl f; /*in*/
+  unsigned int n; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  Z3_ast _c1;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx);
+  n = Int_val(_v_n);
+  args = &_c1;
+  camlidl_ml2c_z3_Z3_ast(_v_args, &_c1, _ctx);
+  _res = Z3_mk_map(c, f, n, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_array_default(
+	value _v_c,
+	value _v_array)
+{
+  Z3_context c; /*in*/
+  Z3_ast array; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_array, &array, _ctx);
+  _res = Z3_mk_array_default(c, array);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_sort(
+	value _v_c,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_set_sort(c, ty);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_empty_set(
+	value _v_c,
+	value _v_domain)
+{
+  Z3_context c; /*in*/
+  Z3_sort domain; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx);
+  _res = Z3_mk_empty_set(c, domain);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_full_set(
+	value _v_c,
+	value _v_domain)
+{
+  Z3_context c; /*in*/
+  Z3_sort domain; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx);
+  _res = Z3_mk_full_set(c, domain);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_add(
+	value _v_c,
+	value _v_set,
+	value _v_elem)
+{
+  Z3_context c; /*in*/
+  Z3_ast set; /*in*/
+  Z3_ast elem; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx);
+  _res = Z3_mk_set_add(c, set, elem);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_del(
+	value _v_c,
+	value _v_set,
+	value _v_elem)
+{
+  Z3_context c; /*in*/
+  Z3_ast set; /*in*/
+  Z3_ast elem; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx);
+  _res = Z3_mk_set_del(c, set, elem);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_union(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_set_union(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_intersect(
+	value _v_c,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast const *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_mk_set_intersect(c, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_difference(
+	value _v_c,
+	value _v_arg1,
+	value _v_arg2)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg1; /*in*/
+  Z3_ast arg2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx);
+  _res = Z3_mk_set_difference(c, arg1, arg2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_complement(
+	value _v_c,
+	value _v_arg)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg, &arg, _ctx);
+  _res = Z3_mk_set_complement(c, arg);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_member(
+	value _v_c,
+	value _v_elem,
+	value _v_set)
+{
+  Z3_context c; /*in*/
+  Z3_ast elem; /*in*/
+  Z3_ast set; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx);
+  _res = Z3_mk_set_member(c, elem, set);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_set_subset(
+	value _v_c,
+	value _v_arg1,
+	value _v_arg2)
+{
+  Z3_context c; /*in*/
+  Z3_ast arg1; /*in*/
+  Z3_ast arg2; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx);
+  _res = Z3_mk_set_subset(c, arg1, arg2);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_numeral(
+	value _v_c,
+	value _v_numeral,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  char const *numeral; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  numeral = String_val(_v_numeral);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_numeral(c, numeral, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_real(
+	value _v_c,
+	value _v_num,
+	value _v_den)
+{
+  Z3_context c; /*in*/
+  int num; /*in*/
+  int den; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  num = Int_val(_v_num);
+  den = Int_val(_v_den);
+  _res = Z3_mk_real(c, num, den);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_int(
+	value _v_c,
+	value _v_v,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  int v; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  v = Int_val(_v_v);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_int(c, v, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_unsigned_int(
+	value _v_c,
+	value _v_v,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  unsigned int v; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  v = Int_val(_v_v);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_unsigned_int(c, v, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_pattern(
+	value _v_c,
+	value _v_terms)
+{
+  Z3_context c; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_ast const *terms; /*in*/
+  Z3_pattern _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_terms);
+  terms = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_terms, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &terms[_c2], _ctx);
+  }
+  num_patterns = _c1;
+  _res = Z3_mk_pattern(c, num_patterns, terms);
+  _vres = camlidl_c2ml_z3_Z3_pattern(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_bound(
+	value _v_c,
+	value _v_index,
+	value _v_ty)
+{
+  Z3_context c; /*in*/
+  unsigned int index; /*in*/
+  Z3_sort ty; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  index = Int_val(_v_index);
+  camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx);
+  _res = Z3_mk_bound(c, index, ty);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_forall(
+	value _v_c,
+	value _v_weight,
+	value _v_patterns,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_sort const *sorts; /*in*/
+  Z3_symbol const *decl_names; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_patterns, _c2);
+    camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx);
+  }
+  num_patterns = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_decls = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_forall(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_forall_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_forall(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_mk_exists(
+	value _v_c,
+	value _v_weight,
+	value _v_patterns,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_sort const *sorts; /*in*/
+  Z3_symbol const *decl_names; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_patterns, _c2);
+    camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx);
+  }
+  num_patterns = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_decls = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_exists(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_exists_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_exists(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_mk_quantifier(
+	value _v_c,
+	value _v_is_forall,
+	value _v_weight,
+	value _v_patterns,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  int is_forall; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_sort const *sorts; /*in*/
+  Z3_symbol const *decl_names; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  is_forall = Int_val(_v_is_forall);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_patterns, _c2);
+    camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx);
+  }
+  num_patterns = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_decls = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_quantifier(c, is_forall, weight, num_patterns, patterns, num_decls, sorts, decl_names, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_quantifier_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_quantifier(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+}
+
+value camlidl_z3_Z3_mk_quantifier_ex(
+	value _v_c,
+	value _v_is_forall,
+	value _v_weight,
+	value _v_quantifier_id,
+	value _v_skolem_id,
+	value _v_patterns,
+	value _v_no_patterns,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  int is_forall; /*in*/
+  unsigned int weight; /*in*/
+  Z3_symbol quantifier_id; /*in*/
+  Z3_symbol skolem_id; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  unsigned int num_no_patterns; /*in*/
+  Z3_ast const *no_patterns; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_sort const *sorts; /*in*/
+  Z3_symbol const *decl_names; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  mlsize_t _c11;
+  value _v12;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  is_forall = Int_val(_v_is_forall);
+  weight = Int_val(_v_weight);
+  camlidl_ml2c_z3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx);
+  _c1 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_patterns, _c2);
+    camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx);
+  }
+  num_patterns = _c1;
+  _c4 = Wosize_val(_v_no_patterns);
+  no_patterns = camlidl_malloc(_c4 * sizeof(Z3_ast const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_no_patterns, _c5);
+    camlidl_ml2c_z3_Z3_ast(_v6, &no_patterns[_c5], _ctx);
+  }
+  num_no_patterns = _c4;
+  _c7 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c7 * sizeof(Z3_sort const ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_sorts, _c8);
+    camlidl_ml2c_z3_Z3_sort(_v9, &sorts[_c8], _ctx);
+  }
+  num_decls = _c7;
+  _c10 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c10 * sizeof(Z3_symbol const ), _ctx);
+  for (_c11 = 0; _c11 < _c10; _c11++) {
+    _v12 = Field(_v_decl_names, _c11);
+    camlidl_ml2c_z3_Z3_symbol(_v12, &decl_names[_c11], _ctx);
+  }
+  num_decls = _c10;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns, num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_quantifier_ex_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_quantifier_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
+}
+
+value camlidl_z3_Z3_mk_forall_const(
+	value _v_c,
+	value _v_weight,
+	value _v_bound,
+	value _v_patterns,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_bound; /*in*/
+  Z3_app const *bound; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_bound);
+  bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_bound, _c2);
+    camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx);
+  }
+  num_bound = _c1;
+  _c4 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_patterns, _c5);
+    camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx);
+  }
+  num_patterns = _c4;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_forall_const(c, weight, num_bound, bound, num_patterns, patterns, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_exists_const(
+	value _v_c,
+	value _v_weight,
+	value _v_bound,
+	value _v_patterns,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_bound; /*in*/
+  Z3_app const *bound; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_bound);
+  bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_bound, _c2);
+    camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx);
+  }
+  num_bound = _c1;
+  _c4 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_patterns, _c5);
+    camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx);
+  }
+  num_patterns = _c4;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_exists_const(c, weight, num_bound, bound, num_patterns, patterns, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_quantifier_const(
+	value _v_c,
+	value _v_is_forall,
+	value _v_weight,
+	value _v_bound,
+	value _v_patterns,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  int is_forall; /*in*/
+  unsigned int weight; /*in*/
+  unsigned int num_bound; /*in*/
+  Z3_app const *bound; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  is_forall = Int_val(_v_is_forall);
+  weight = Int_val(_v_weight);
+  _c1 = Wosize_val(_v_bound);
+  bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_bound, _c2);
+    camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx);
+  }
+  num_bound = _c1;
+  _c4 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_patterns, _c5);
+    camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx);
+  }
+  num_patterns = _c4;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_quantifier_const(c, is_forall, weight, num_bound, bound, num_patterns, patterns, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_quantifier_const_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_quantifier_const(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_mk_quantifier_const_ex(
+	value _v_c,
+	value _v_is_forall,
+	value _v_weight,
+	value _v_quantifier_id,
+	value _v_skolem_id,
+	value _v_bound,
+	value _v_patterns,
+	value _v_no_patterns,
+	value _v_body)
+{
+  Z3_context c; /*in*/
+  int is_forall; /*in*/
+  unsigned int weight; /*in*/
+  Z3_symbol quantifier_id; /*in*/
+  Z3_symbol skolem_id; /*in*/
+  unsigned int num_bound; /*in*/
+  Z3_app const *bound; /*in*/
+  unsigned int num_patterns; /*in*/
+  Z3_pattern const *patterns; /*in*/
+  unsigned int num_no_patterns; /*in*/
+  Z3_ast const *no_patterns; /*in*/
+  Z3_ast body; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  is_forall = Int_val(_v_is_forall);
+  weight = Int_val(_v_weight);
+  camlidl_ml2c_z3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx);
+  _c1 = Wosize_val(_v_bound);
+  bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_bound, _c2);
+    camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx);
+  }
+  num_bound = _c1;
+  _c4 = Wosize_val(_v_patterns);
+  patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_patterns, _c5);
+    camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx);
+  }
+  num_patterns = _c4;
+  _c7 = Wosize_val(_v_no_patterns);
+  no_patterns = camlidl_malloc(_c7 * sizeof(Z3_ast const ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_no_patterns, _c8);
+    camlidl_ml2c_z3_Z3_ast(_v9, &no_patterns[_c8], _ctx);
+  }
+  num_no_patterns = _c7;
+  camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx);
+  _res = Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns, num_no_patterns, no_patterns, body);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_mk_quantifier_const_ex_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_mk_quantifier_const_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
+}
+
+value camlidl_z3_Z3_get_ast_id(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_ast t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx);
+  _res = Z3_get_ast_id(c, t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_func_decl_id(
+	value _v_c,
+	value _v_f)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl f; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx);
+  _res = Z3_get_func_decl_id(c, f);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_sort_id(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_sort s; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_get_sort_id(c, s);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_is_well_sorted(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_ast t; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx);
+  _res = Z3_is_well_sorted(c, t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_symbol_kind(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  Z3_symbol_kind _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _res = Z3_get_symbol_kind(c, s);
+  _vres = camlidl_c2ml_z3_Z3_symbol_kind(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_symbol_int(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _res = Z3_get_symbol_int(c, s);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_symbol_string(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_symbol s; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _res = Z3_get_symbol_string(c, s);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_ast_kind(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast_kind _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_ast_kind(c, a);
+  _vres = camlidl_c2ml_z3_Z3_ast_kind(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_numeral_string(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_numeral_string(c, a);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_numeral_small(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  __int64 *num; /*out*/
+  __int64 *den; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  __int64 _c1;
+  __int64 _c2;
+  value _vresult;
+  value _vres[3] = { 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  num = &_c1;
+  den = &_c2;
+  _res = Z3_get_numeral_small(c, a, num, den);
+  Begin_roots_block(_vres, 3)
+    _vres[0] = Val_int(_res);
+    _vres[1] = copy_int64(*num);
+    _vres[2] = copy_int64(*den);
+    _vresult = camlidl_alloc_small(3, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_numeral_int(
+	value _v_c,
+	value _v_v)
+{
+  Z3_context c; /*in*/
+  Z3_ast v; /*in*/
+  int *i; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  int _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  i = &_c1;
+  _res = Z3_get_numeral_int(c, v, i);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = Val_int(*i);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_numeral_uint(
+	value _v_c,
+	value _v_v)
+{
+  Z3_context c; /*in*/
+  Z3_ast v; /*in*/
+  unsigned int *u; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  unsigned int _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  u = &_c1;
+  _res = Z3_get_numeral_uint(c, v, u);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = Val_int(*u);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_bool_value(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_lbool _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_bool_value(c, a);
+  _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_app_decl(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_app a; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx);
+  _res = Z3_get_app_decl(c, a);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_app_num_args(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_app a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx);
+  _res = Z3_get_app_num_args(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_app_arg(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_app a; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_app_arg(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_index_value(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_index_value(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_is_quantifier_forall(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_is_quantifier_forall(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_weight(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_quantifier_weight(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_num_patterns(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_quantifier_num_patterns(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_pattern_ast(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int i; /*in*/
+  Z3_pattern _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_quantifier_pattern_ast(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_pattern(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_num_no_patterns(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_quantifier_num_no_patterns(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_no_pattern_ast(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_quantifier_no_pattern_ast(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_bound_name(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int i; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_quantifier_bound_name(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_bound_sort(
+	value _v_c,
+	value _v_a,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int i; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_quantifier_bound_sort(c, a, i);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_body(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_quantifier_body(c, a);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_quantifier_num_bound(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_quantifier_num_bound(c, a);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_name(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_get_decl_name(c, d);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_num_parameters(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_get_decl_num_parameters(c, d);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_parameter_kind(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  Z3_parameter_kind _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_parameter_kind(c, d, idx);
+  _vres = camlidl_c2ml_z3_Z3_parameter_kind(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_int_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_int_parameter(c, d, idx);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_double_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  double _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_double_parameter(c, d, idx);
+  _vres = copy_double(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_symbol_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_symbol_parameter(c, d, idx);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_sort_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_sort_parameter(c, d, idx);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_ast_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_ast_parameter(c, d, idx);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_func_decl_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_func_decl_parameter(c, d, idx);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_rational_parameter(
+	value _v_c,
+	value _v_d,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int idx; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_decl_rational_parameter(c, d, idx);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_sort_name(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_sort d; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_d, &d, _ctx);
+  _res = Z3_get_sort_name(c, d);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_sort(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_get_sort(c, a);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_domain_size(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_get_domain_size(c, d);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_domain(
+	value _v_c,
+	value _v_d,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int i; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_domain(c, d, i);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_range(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_get_range(c, d);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_sort_kind(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  Z3_sort_kind _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_sort_kind(c, t);
+  _vres = camlidl_c2ml_z3_Z3_sort_kind(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_bv_sort_size(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_bv_sort_size(c, t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_array_sort_domain(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_array_sort_domain(c, t);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_array_sort_range(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_array_sort_range(c, t);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_tuple_sort_mk_decl(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_tuple_sort_mk_decl(c, t);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_decl_kind(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  Z3_decl_kind _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_get_decl_kind(c, d);
+  _vres = camlidl_c2ml_z3_Z3_decl_kind(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_tuple_sort_num_fields(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_tuple_sort_num_fields(c, t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_tuple_sort_field_decl(
+	value _v_c,
+	value _v_t,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int i; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_tuple_sort_field_decl(c, t, i);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_datatype_sort_num_constructors(
+	value _v_c,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  _res = Z3_get_datatype_sort_num_constructors(c, t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_datatype_sort_constructor(
+	value _v_c,
+	value _v_t,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int idx; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_datatype_sort_constructor(c, t, idx);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_datatype_sort_recognizer(
+	value _v_c,
+	value _v_t,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int idx; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_datatype_sort_recognizer(c, t, idx);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_datatype_sort_constructor_accessor(
+	value _v_c,
+	value _v_t,
+	value _v_idx_c,
+	value _v_idx_a)
+{
+  Z3_context c; /*in*/
+  Z3_sort t; /*in*/
+  unsigned int idx_c; /*in*/
+  unsigned int idx_a; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx);
+  idx_c = Int_val(_v_idx_c);
+  idx_a = Int_val(_v_idx_a);
+  _res = Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_relation_arity(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_sort s; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_get_relation_arity(c, s);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_relation_column(
+	value _v_c,
+	value _v_s,
+	value _v_col)
+{
+  Z3_context c; /*in*/
+  Z3_sort s; /*in*/
+  unsigned int col; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  col = Int_val(_v_col);
+  _res = Z3_get_relation_column(c, s, col);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_pattern_num_terms(
+	value _v_c,
+	value _v_p)
+{
+  Z3_context c; /*in*/
+  Z3_pattern p; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx);
+  _res = Z3_get_pattern_num_terms(c, p);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_pattern(
+	value _v_c,
+	value _v_p,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_pattern p; /*in*/
+  unsigned int idx; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_pattern(c, p, idx);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_simplify(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_simplify(c, a);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_update_term(
+	value _v_c,
+	value _v_a,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast *args; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  _res = Z3_update_term(c, a, num_args, args);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_substitute(
+	value _v_c,
+	value _v_a,
+	value _v_from,
+	value _v_to)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int num_exprs; /*in*/
+  Z3_ast *from; /*in*/
+  Z3_ast *to; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _c1 = Wosize_val(_v_from);
+  from = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_from, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &from[_c2], _ctx);
+  }
+  num_exprs = _c1;
+  _c4 = Wosize_val(_v_to);
+  to = camlidl_malloc(_c4 * sizeof(Z3_ast ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_to, _c5);
+    camlidl_ml2c_z3_Z3_ast(_v6, &to[_c5], _ctx);
+  }
+  num_exprs = _c4;
+  _res = Z3_substitute(c, a, num_exprs, from, to);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_substitute_vars(
+	value _v_c,
+	value _v_a,
+	value _v_to)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int num_exprs; /*in*/
+  Z3_ast *to; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _c1 = Wosize_val(_v_to);
+  to = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_to, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &to[_c2], _ctx);
+  }
+  num_exprs = _c1;
+  _res = Z3_substitute_vars(c, a, num_exprs, to);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_sort_to_ast(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_sort s; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_sort_to_ast(c, s);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_func_decl_to_ast(
+	value _v_c,
+	value _v_f)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl f; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx);
+  _res = Z3_func_decl_to_ast(c, f);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_pattern_to_ast(
+	value _v_c,
+	value _v_p)
+{
+  Z3_context c; /*in*/
+  Z3_pattern p; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx);
+  _res = Z3_pattern_to_ast(c, p);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_app_to_ast(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_app a; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx);
+  _res = Z3_app_to_ast(c, a);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_to_app(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  Z3_app _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_to_app(c, a);
+  _vres = camlidl_c2ml_z3_Z3_app(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_push(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_push(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_pop(
+	value _v_c,
+	value _v_num_scopes)
+{
+  Z3_context c; /*in*/
+  unsigned int num_scopes; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  num_scopes = Int_val(_v_num_scopes);
+  Z3_pop(c, num_scopes);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_get_num_scopes(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_num_scopes(c);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_persist_ast(
+	value _v_c,
+	value _v_a,
+	value _v_num_scopes)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  unsigned int num_scopes; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  num_scopes = Int_val(_v_num_scopes);
+  Z3_persist_ast(c, a, num_scopes);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_assert_cnstr(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  Z3_assert_cnstr(c, a);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_check_and_get_model(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_model *m; /*out*/
+  Z3_lbool _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  Z3_model _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  m = &_c1;
+  _res = Z3_check_and_get_model(c, m);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx);
+    _vres[1] = camlidl_c2ml_z3_Z3_model(&*m, _ctx);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_check(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_lbool _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_check(c);
+  _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_check_assumptions(
+	value _v_c,
+	value _v_assumptions,
+	value _v_core_size,
+	value _v_core)
+{
+  Z3_context c; /*in*/
+  unsigned int num_assumptions; /*in*/
+  Z3_ast *assumptions; /*in*/
+  Z3_model *m; /*out*/
+  Z3_ast *proof; /*out*/
+  unsigned int *core_size; /*in,out*/
+  Z3_ast *core; /*in,out*/
+  Z3_lbool _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  unsigned int _c4;
+  mlsize_t _c5;
+  mlsize_t _c6;
+  value _v7;
+  Z3_model _c8;
+  Z3_ast _c9;
+  mlsize_t _c10;
+  value _v11;
+  value _vresult;
+  value _vres[5] = { 0, 0, 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_assumptions);
+  assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_assumptions, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &assumptions[_c2], _ctx);
+  }
+  num_assumptions = _c1;
+  core_size = &_c4;
+  _c4 = Int_val(_v_core_size);
+  _c5 = Wosize_val(_v_core);
+  core = camlidl_malloc(_c5 * sizeof(Z3_ast ), _ctx);
+  for (_c6 = 0; _c6 < _c5; _c6++) {
+    _v7 = Field(_v_core, _c6);
+    camlidl_ml2c_z3_Z3_ast(_v7, &core[_c6], _ctx);
+  }
+  num_assumptions = _c5;
+  m = &_c8;
+  proof = &_c9;
+  _res = Z3_check_assumptions(c, num_assumptions, assumptions, m, proof, core_size, core);
+  Begin_roots_block(_vres, 5)
+    _vres[0] = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx);
+    _vres[1] = camlidl_c2ml_z3_Z3_model(&*m, _ctx);
+    _vres[2] = camlidl_c2ml_z3_Z3_ast(&*proof, _ctx);
+    _vres[3] = Val_int(*core_size);
+    _vres[4] = camlidl_alloc(num_assumptions, 0);
+    Begin_root(_vres[4])
+      for (_c10 = 0; _c10 < num_assumptions; _c10++) {
+        _v11 = camlidl_c2ml_z3_Z3_ast(&core[_c10], _ctx);
+        modify(&Field(_vres[4], _c10), _v11);
+      }
+    End_roots()
+    _vresult = camlidl_alloc_small(5, 0);
+    { mlsize_t _c12;
+      for (_c12 = 0; _c12 < 5; _c12++) Field(_vresult, _c12) = _vres[_c12];
+    }
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_implied_equalities(
+	value _v_c,
+	value _v_terms)
+{
+  Z3_context c; /*in*/
+  unsigned int num_terms; /*in*/
+  Z3_ast *terms; /*in*/
+  unsigned int *class_ids; /*out*/
+  Z3_lbool _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  value _v5;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _c1 = Wosize_val(_v_terms);
+  terms = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_terms, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &terms[_c2], _ctx);
+  }
+  num_terms = _c1;
+  class_ids = camlidl_malloc(num_terms * sizeof(unsigned int ), _ctx);
+  _res = Z3_get_implied_equalities(c, num_terms, terms, class_ids);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx);
+    _vres[1] = camlidl_alloc(num_terms, 0);
+    for (_c4 = 0; _c4 < num_terms; _c4++) {
+      _v5 = Val_int(class_ids[_c4]);
+      modify(&Field(_vres[1], _c4), _v5);
+    }
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_del_model(
+	value _v_c,
+	value _v_m)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  Z3_del_model(c, m);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_soft_check_cancel(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_soft_check_cancel(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_get_search_failure(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_search_failure _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_search_failure(c);
+  _vres = camlidl_c2ml_z3_Z3_search_failure(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_relevant_labels(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_literals _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_relevant_labels(c);
+  _vres = camlidl_c2ml_z3_Z3_literals(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_relevant_literals(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_literals _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_relevant_literals(c);
+  _vres = camlidl_c2ml_z3_Z3_literals(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_guessed_literals(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_literals _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_guessed_literals(c);
+  _vres = camlidl_c2ml_z3_Z3_literals(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_del_literals(
+	value _v_c,
+	value _v_lbls)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  Z3_del_literals(c, lbls);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_get_num_literals(
+	value _v_c,
+	value _v_lbls)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  _res = Z3_get_num_literals(c, lbls);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_label_symbol(
+	value _v_c,
+	value _v_lbls,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  unsigned int idx; /*in*/
+  Z3_symbol _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_label_symbol(c, lbls, idx);
+  _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_literal(
+	value _v_c,
+	value _v_lbls,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  unsigned int idx; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  idx = Int_val(_v_idx);
+  _res = Z3_get_literal(c, lbls, idx);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_disable_literal(
+	value _v_c,
+	value _v_lbls,
+	value _v_idx)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  unsigned int idx; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  idx = Int_val(_v_idx);
+  Z3_disable_literal(c, lbls, idx);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_block_literals(
+	value _v_c,
+	value _v_lbls)
+{
+  Z3_context c; /*in*/
+  Z3_literals lbls; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_literals(_v_lbls, &lbls, _ctx);
+  Z3_block_literals(c, lbls);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_get_model_num_constants(
+	value _v_c,
+	value _v_m)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  _res = Z3_get_model_num_constants(c, m);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_constant(
+	value _v_c,
+	value _v_m,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_model_constant(c, m, i);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_eval_func_decl(
+	value _v_c,
+	value _v_m,
+	value _v_decl)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  Z3_func_decl decl; /*in*/
+  Z3_ast *v; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  Z3_ast _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_decl, &decl, _ctx);
+  v = &_c1;
+  _res = Z3_eval_func_decl(c, m, decl, v);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = camlidl_c2ml_z3_Z3_ast(&*v, _ctx);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_is_array_value(
+	value _v_c,
+	value _v_m,
+	value _v_v)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  Z3_ast v; /*in*/
+  unsigned int *num_entries; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  unsigned int _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  num_entries = &_c1;
+  _res = Z3_is_array_value(c, m, v, num_entries);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = Val_int(*num_entries);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_array_value(
+	value _v_c,
+	value _v_m,
+	value _v_v,
+	value _v_indices,
+	value _v_values)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  Z3_ast v; /*in*/
+  unsigned int num_entries; /*in*/
+  Z3_ast *indices; /*in,out*/
+  Z3_ast *values; /*in,out*/
+  Z3_ast *else_value; /*out*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  Z3_ast _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  value _v11;
+  value _vresult;
+  value _vres[3] = { 0, 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx);
+  _c1 = Wosize_val(_v_indices);
+  indices = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_indices, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &indices[_c2], _ctx);
+  }
+  num_entries = _c1;
+  _c4 = Wosize_val(_v_values);
+  values = camlidl_malloc(_c4 * sizeof(Z3_ast ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_values, _c5);
+    camlidl_ml2c_z3_Z3_ast(_v6, &values[_c5], _ctx);
+  }
+  num_entries = _c4;
+  else_value = &_c7;
+  Z3_get_array_value(c, m, v, num_entries, indices, values, else_value);
+  Begin_roots_block(_vres, 3)
+    _vres[0] = camlidl_alloc(num_entries, 0);
+    Begin_root(_vres[0])
+      for (_c8 = 0; _c8 < num_entries; _c8++) {
+        _v9 = camlidl_c2ml_z3_Z3_ast(&indices[_c8], _ctx);
+        modify(&Field(_vres[0], _c8), _v9);
+      }
+    End_roots()
+    _vres[1] = camlidl_alloc(num_entries, 0);
+    Begin_root(_vres[1])
+      for (_c10 = 0; _c10 < num_entries; _c10++) {
+        _v11 = camlidl_c2ml_z3_Z3_ast(&values[_c10], _ctx);
+        modify(&Field(_vres[1], _c10), _v11);
+      }
+    End_roots()
+    _vres[2] = camlidl_c2ml_z3_Z3_ast(&*else_value, _ctx);
+    _vresult = camlidl_alloc_small(3, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_get_model_num_funcs(
+	value _v_c,
+	value _v_m)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  _res = Z3_get_model_num_funcs(c, m);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_decl(
+	value _v_c,
+	value _v_m,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_model_func_decl(c, m, i);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_else(
+	value _v_c,
+	value _v_m,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_model_func_else(c, m, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_num_entries(
+	value _v_c,
+	value _v_m,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_model_func_num_entries(c, m, i);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_entry_num_args(
+	value _v_c,
+	value _v_m,
+	value _v_i,
+	value _v_j)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  unsigned int j; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  j = Int_val(_v_j);
+  _res = Z3_get_model_func_entry_num_args(c, m, i, j);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_entry_arg(
+	value _v_c,
+	value _v_m,
+	value _v_i,
+	value _v_j,
+	value _v_k)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  unsigned int j; /*in*/
+  unsigned int k; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  j = Int_val(_v_j);
+  k = Int_val(_v_k);
+  _res = Z3_get_model_func_entry_arg(c, m, i, j, k);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_model_func_entry_value(
+	value _v_c,
+	value _v_m,
+	value _v_i,
+	value _v_j)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  unsigned int i; /*in*/
+  unsigned int j; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  i = Int_val(_v_i);
+  j = Int_val(_v_j);
+  _res = Z3_get_model_func_entry_value(c, m, i, j);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_eval(
+	value _v_c,
+	value _v_m,
+	value _v_t)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  Z3_ast t; /*in*/
+  Z3_ast *v; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  Z3_ast _c1;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx);
+  v = &_c1;
+  _res = Z3_eval(c, m, t, v);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = camlidl_c2ml_z3_Z3_ast(&*v, _ctx);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_eval_decl(
+	value _v_c,
+	value _v_m,
+	value _v_d,
+	value _v_args)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  Z3_func_decl d; /*in*/
+  unsigned int num_args; /*in*/
+  Z3_ast *args; /*in*/
+  Z3_ast *v; /*out*/
+  int _res;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  Z3_ast _c4;
+  value _vresult;
+  value _vres[2] = { 0, 0, };
+
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _c1 = Wosize_val(_v_args);
+  args = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_args, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx);
+  }
+  num_args = _c1;
+  v = &_c4;
+  _res = Z3_eval_decl(c, m, d, num_args, args, v);
+  Begin_roots_block(_vres, 2)
+    _vres[0] = Val_int(_res);
+    _vres[1] = camlidl_c2ml_z3_Z3_ast(&*v, _ctx);
+    _vresult = camlidl_alloc_small(2, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+  End_roots()
+  camlidl_free(_ctx);
+  return _vresult;
+}
+
+value camlidl_z3_Z3_open_log(
+	value _v_c,
+	value _v_filename)
+{
+  Z3_context c; /*in*/
+  char const *filename; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  filename = String_val(_v_filename);
+  _res = Z3_open_log(c, filename);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_append_log(
+	value _v_c,
+	value _v_string)
+{
+  Z3_context c; /*in*/
+  char const *string; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  string = String_val(_v_string);
+  Z3_append_log(c, string);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_close_log(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  Z3_close_log(c);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_set_ast_print_mode(
+	value _v_c,
+	value _v_mode)
+{
+  Z3_context c; /*in*/
+  Z3_ast_print_mode mode; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast_print_mode(_v_mode, &mode, _ctx);
+  Z3_set_ast_print_mode(c, mode);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_ast_to_string(
+	value _v_c,
+	value _v_a)
+{
+  Z3_context c; /*in*/
+  Z3_ast a; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx);
+  _res = Z3_ast_to_string(c, a);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_pattern_to_string(
+	value _v_c,
+	value _v_p)
+{
+  Z3_context c; /*in*/
+  Z3_pattern p; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx);
+  _res = Z3_pattern_to_string(c, p);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_sort_to_string(
+	value _v_c,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_sort s; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_sort_to_string(c, s);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_func_decl_to_string(
+	value _v_c,
+	value _v_d)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl d; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_func_decl_to_string(c, d);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_model_to_string(
+	value _v_c,
+	value _v_m)
+{
+  Z3_context c; /*in*/
+  Z3_model m; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx);
+  _res = Z3_model_to_string(c, m);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_benchmark_to_smtlib_string(
+	value _v_c,
+	value _v_name,
+	value _v_logic,
+	value _v_status,
+	value _v_attributes,
+	value _v_assumptions,
+	value _v_formula)
+{
+  Z3_context c; /*in*/
+  char const *name; /*in*/
+  char const *logic; /*in*/
+  char const *status; /*in*/
+  char const *attributes; /*in*/
+  unsigned int num_assumptions; /*in*/
+  Z3_ast *assumptions; /*in*/
+  Z3_ast formula; /*in*/
+  char const *_res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  name = String_val(_v_name);
+  logic = String_val(_v_logic);
+  status = String_val(_v_status);
+  attributes = String_val(_v_attributes);
+  _c1 = Wosize_val(_v_assumptions);
+  assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_assumptions, _c2);
+    camlidl_ml2c_z3_Z3_ast(_v3, &assumptions[_c2], _ctx);
+  }
+  num_assumptions = _c1;
+  camlidl_ml2c_z3_Z3_ast(_v_formula, &formula, _ctx);
+  _res = Z3_benchmark_to_smtlib_string(c, name, logic, status, attributes, num_assumptions, assumptions, formula);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_benchmark_to_smtlib_string_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_benchmark_to_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+}
+
+value camlidl_z3_Z3_context_to_string(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_context_to_string(c);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_statistics_to_string(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_statistics_to_string(c);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_context_assignment(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_context_assignment(c);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_smtlib_string(
+	value _v_c,
+	value _v_str,
+	value _v_sort_names,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_decls)
+{
+  Z3_context c; /*in*/
+  char const *str; /*in*/
+  unsigned int num_sorts; /*in*/
+  Z3_symbol *sort_names; /*in*/
+  Z3_sort *sorts; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_symbol *decl_names; /*in*/
+  Z3_func_decl *decls; /*in*/
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  mlsize_t _c11;
+  value _v12;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  str = String_val(_v_str);
+  _c1 = Wosize_val(_v_sort_names);
+  sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_sort_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx);
+  }
+  num_sorts = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_sorts = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  _c10 = Wosize_val(_v_decls);
+  decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl ), _ctx);
+  for (_c11 = 0; _c11 < _c10; _c11++) {
+    _v12 = Field(_v_decls, _c11);
+    camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx);
+  }
+  num_decls = _c10;
+  Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_parse_smtlib_string_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_parse_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_parse_smtlib_file(
+	value _v_c,
+	value _v_file_name,
+	value _v_sort_names,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_decls)
+{
+  Z3_context c; /*in*/
+  char const *file_name; /*in*/
+  unsigned int num_sorts; /*in*/
+  Z3_symbol *sort_names; /*in*/
+  Z3_sort *sorts; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_symbol *decl_names; /*in*/
+  Z3_func_decl *decls; /*in*/
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  mlsize_t _c11;
+  value _v12;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  file_name = String_val(_v_file_name);
+  _c1 = Wosize_val(_v_sort_names);
+  sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_sort_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx);
+  }
+  num_sorts = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_sorts = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  _c10 = Wosize_val(_v_decls);
+  decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl ), _ctx);
+  for (_c11 = 0; _c11 < _c10; _c11++) {
+    _v12 = Field(_v_decls, _c11);
+    camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx);
+  }
+  num_decls = _c10;
+  Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_parse_smtlib_file_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_parse_smtlib_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_get_smtlib_num_formulas(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_smtlib_num_formulas(c);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_formula(
+	value _v_c,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_smtlib_formula(c, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_num_assumptions(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_smtlib_num_assumptions(c);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_assumption(
+	value _v_c,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_smtlib_assumption(c, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_num_decls(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_smtlib_num_decls(c);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_decl(
+	value _v_c,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_func_decl _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_smtlib_decl(c, i);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_num_sorts(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_smtlib_num_sorts(c);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_sort(
+	value _v_c,
+	value _v_i)
+{
+  Z3_context c; /*in*/
+  unsigned int i; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_get_smtlib_sort(c, i);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_get_smtlib_error(
+	value _v_c)
+{
+  Z3_context c; /*in*/
+  char const *_res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  _res = Z3_get_smtlib_error(c);
+  _vres = copy_string(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_z3_string(
+	value _v_c,
+	value _v_str)
+{
+  Z3_context c; /*in*/
+  char const *str; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  str = String_val(_v_str);
+  _res = Z3_parse_z3_string(c, str);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_z3_file(
+	value _v_c,
+	value _v_file_name)
+{
+  Z3_context c; /*in*/
+  char const *file_name; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  file_name = String_val(_v_file_name);
+  _res = Z3_parse_z3_file(c, file_name);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_smtlib2_string(
+	value _v_c,
+	value _v_str,
+	value _v_sort_names,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_decls)
+{
+  Z3_context c; /*in*/
+  char const *str; /*in*/
+  unsigned int num_sorts; /*in*/
+  Z3_symbol *sort_names; /*in*/
+  Z3_sort *sorts; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_symbol *decl_names; /*in*/
+  Z3_func_decl *decls; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  mlsize_t _c11;
+  value _v12;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  str = String_val(_v_str);
+  _c1 = Wosize_val(_v_sort_names);
+  sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_sort_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx);
+  }
+  num_sorts = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_sorts = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  _c10 = Wosize_val(_v_decls);
+  decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl ), _ctx);
+  for (_c11 = 0; _c11 < _c10; _c11++) {
+    _v12 = Field(_v_decls, _c11);
+    camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx);
+  }
+  num_decls = _c10;
+  _res = Z3_parse_smtlib2_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_smtlib2_string_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_parse_smtlib2_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_parse_smtlib2_file(
+	value _v_c,
+	value _v_file_name,
+	value _v_sort_names,
+	value _v_sorts,
+	value _v_decl_names,
+	value _v_decls)
+{
+  Z3_context c; /*in*/
+  char const *file_name; /*in*/
+  unsigned int num_sorts; /*in*/
+  Z3_symbol *sort_names; /*in*/
+  Z3_sort *sorts; /*in*/
+  unsigned int num_decls; /*in*/
+  Z3_symbol *decl_names; /*in*/
+  Z3_func_decl *decls; /*in*/
+  Z3_ast _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  mlsize_t _c4;
+  mlsize_t _c5;
+  value _v6;
+  mlsize_t _c7;
+  mlsize_t _c8;
+  value _v9;
+  mlsize_t _c10;
+  mlsize_t _c11;
+  value _v12;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  file_name = String_val(_v_file_name);
+  _c1 = Wosize_val(_v_sort_names);
+  sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_sort_names, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx);
+  }
+  num_sorts = _c1;
+  _c4 = Wosize_val(_v_sorts);
+  sorts = camlidl_malloc(_c4 * sizeof(Z3_sort ), _ctx);
+  for (_c5 = 0; _c5 < _c4; _c5++) {
+    _v6 = Field(_v_sorts, _c5);
+    camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx);
+  }
+  num_sorts = _c4;
+  _c7 = Wosize_val(_v_decl_names);
+  decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol ), _ctx);
+  for (_c8 = 0; _c8 < _c7; _c8++) {
+    _v9 = Field(_v_decl_names, _c8);
+    camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx);
+  }
+  num_decls = _c7;
+  _c10 = Wosize_val(_v_decls);
+  decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl ), _ctx);
+  for (_c11 = 0; _c11 < _c10; _c11++) {
+    _v12 = Field(_v_decls, _c11);
+    camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx);
+  }
+  num_decls = _c10;
+  _res = Z3_parse_smtlib2_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_parse_smtlib2_file_bytecode(value * argv, int argn)
+{
+  return camlidl_z3_Z3_parse_smtlib2_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value camlidl_z3_Z3_get_version(value _unit)
+{
+  unsigned int *major; /*out*/
+  unsigned int *minor; /*out*/
+  unsigned int *build_number; /*out*/
+  unsigned int *revision_number; /*out*/
+  unsigned int _c1;
+  unsigned int _c2;
+  unsigned int _c3;
+  unsigned int _c4;
+  value _vresult;
+  value _vres[4] = { 0, 0, 0, 0, };
+
+  major = &_c1;
+  minor = &_c2;
+  build_number = &_c3;
+  revision_number = &_c4;
+  Z3_get_version(major, minor, build_number, revision_number);
+  Begin_roots_block(_vres, 4)
+    _vres[0] = Val_int(*major);
+    _vres[1] = Val_int(*minor);
+    _vres[2] = Val_int(*build_number);
+    _vres[3] = Val_int(*revision_number);
+    _vresult = camlidl_alloc_small(4, 0);
+    Field(_vresult, 0) = _vres[0];
+    Field(_vresult, 1) = _vres[1];
+    Field(_vresult, 2) = _vres[2];
+    Field(_vresult, 3) = _vres[3];
+  End_roots()
+  return _vresult;
+}
+
+value camlidl_z3_Z3_reset_memory(value _unit)
+{
+  Z3_reset_memory();
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_theory_mk_sort(
+	value _v_c,
+	value _v_t,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_theory t; /*in*/
+  Z3_symbol s; /*in*/
+  Z3_sort _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx);
+  _res = Z3_theory_mk_sort(c, t, s);
+  _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_mk_value(
+	value _v_c,
+	value _v_t,
+	value _v_n,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_theory t; /*in*/
+  Z3_symbol n; /*in*/
+  Z3_sort s; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_n, &n, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_theory_mk_value(c, t, n, s);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_mk_constant(
+	value _v_c,
+	value _v_t,
+	value _v_n,
+	value _v_s)
+{
+  Z3_context c; /*in*/
+  Z3_theory t; /*in*/
+  Z3_symbol n; /*in*/
+  Z3_sort s; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_n, &n, _ctx);
+  camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx);
+  _res = Z3_theory_mk_constant(c, t, n, s);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_mk_func_decl(
+	value _v_c,
+	value _v_t,
+	value _v_n,
+	value _v_domain,
+	value _v_range)
+{
+  Z3_context c; /*in*/
+  Z3_theory t; /*in*/
+  Z3_symbol n; /*in*/
+  unsigned int domain_size; /*in*/
+  Z3_sort const *domain; /*in*/
+  Z3_sort range; /*in*/
+  Z3_func_decl _res;
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_n, &n, _ctx);
+  _c1 = Wosize_val(_v_domain);
+  domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_domain, _c2);
+    camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx);
+  }
+  domain_size = _c1;
+  camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx);
+  _res = Z3_theory_mk_func_decl(c, t, n, domain_size, domain, range);
+  _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_context(
+	value _v_t)
+{
+  Z3_theory t; /*in*/
+  Z3_context _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  _res = Z3_theory_get_context(t);
+  _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_assert_axiom(
+	value _v_t,
+	value _v_ax)
+{
+  Z3_theory t; /*in*/
+  Z3_ast ax; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_ax, &ax, _ctx);
+  Z3_theory_assert_axiom(t, ax);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_theory_assume_eq(
+	value _v_t,
+	value _v_lhs,
+	value _v_rhs)
+{
+  Z3_theory t; /*in*/
+  Z3_ast lhs; /*in*/
+  Z3_ast rhs; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_lhs, &lhs, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_rhs, &rhs, _ctx);
+  Z3_theory_assume_eq(t, lhs, rhs);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_theory_enable_axiom_simplification(
+	value _v_t,
+	value _v_flag)
+{
+  Z3_theory t; /*in*/
+  int flag; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  flag = Int_val(_v_flag);
+  Z3_theory_enable_axiom_simplification(t, flag);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_theory_get_eqc_root(
+	value _v_t,
+	value _v_n)
+{
+  Z3_theory t; /*in*/
+  Z3_ast n; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_n, &n, _ctx);
+  _res = Z3_theory_get_eqc_root(t, n);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_eqc_next(
+	value _v_t,
+	value _v_n)
+{
+  Z3_theory t; /*in*/
+  Z3_ast n; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_n, &n, _ctx);
+  _res = Z3_theory_get_eqc_next(t, n);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_num_parents(
+	value _v_t,
+	value _v_n)
+{
+  Z3_theory t; /*in*/
+  Z3_ast n; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_n, &n, _ctx);
+  _res = Z3_theory_get_num_parents(t, n);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_parent(
+	value _v_t,
+	value _v_n,
+	value _v_i)
+{
+  Z3_theory t; /*in*/
+  Z3_ast n; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_n, &n, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_theory_get_parent(t, n, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_is_value(
+	value _v_t,
+	value _v_n)
+{
+  Z3_theory t; /*in*/
+  Z3_ast n; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_n, &n, _ctx);
+  _res = Z3_theory_is_value(t, n);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_is_decl(
+	value _v_t,
+	value _v_d)
+{
+  Z3_theory t; /*in*/
+  Z3_func_decl d; /*in*/
+  int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx);
+  _res = Z3_theory_is_decl(t, d);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_num_elems(
+	value _v_t)
+{
+  Z3_theory t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  _res = Z3_theory_get_num_elems(t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_elem(
+	value _v_t,
+	value _v_i)
+{
+  Z3_theory t; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_theory_get_elem(t, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_num_apps(
+	value _v_t)
+{
+  Z3_theory t; /*in*/
+  unsigned int _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  _res = Z3_theory_get_num_apps(t);
+  _vres = Val_int(_res);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_theory_get_app(
+	value _v_t,
+	value _v_i)
+{
+  Z3_theory t; /*in*/
+  unsigned int i; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_theory(_v_t, &t, _ctx);
+  i = Int_val(_v_i);
+  _res = Z3_theory_get_app(t, i);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_datalog_add_rule(
+	value _v_c,
+	value _v_horn_rule,
+	value _v_name)
+{
+  Z3_context c; /*in*/
+  Z3_ast horn_rule; /*in*/
+  Z3_symbol name; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_horn_rule, &horn_rule, _ctx);
+  camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx);
+  Z3_datalog_add_rule(c, horn_rule, name);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_datalog_query(
+	value _v_c,
+	value _v_q)
+{
+  Z3_context c; /*in*/
+  Z3_ast q; /*in*/
+  Z3_ast _res;
+  value _vres;
+
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_ast(_v_q, &q, _ctx);
+  _res = Z3_datalog_query(c, q);
+  _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx);
+  camlidl_free(_ctx);
+  return _vres;
+}
+
+value camlidl_z3_Z3_datalog_set_predicate_representation(
+	value _v_c,
+	value _v_f,
+	value _v_relation_kinds)
+{
+  Z3_context c; /*in*/
+  Z3_func_decl f; /*in*/
+  unsigned int num_relations; /*in*/
+  Z3_symbol const *relation_kinds; /*in*/
+  mlsize_t _c1;
+  mlsize_t _c2;
+  value _v3;
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx);
+  _c1 = Wosize_val(_v_relation_kinds);
+  relation_kinds = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx);
+  for (_c2 = 0; _c2 < _c1; _c2++) {
+    _v3 = Field(_v_relation_kinds, _c2);
+    camlidl_ml2c_z3_Z3_symbol(_v3, &relation_kinds[_c2], _ctx);
+  }
+  num_relations = _c1;
+  Z3_datalog_set_predicate_representation(c, f, num_relations, relation_kinds);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+value camlidl_z3_Z3_datalog_parse_file(
+	value _v_c,
+	value _v_filename)
+{
+  Z3_context c; /*in*/
+  char const *filename; /*in*/
+  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
+  camlidl_ctx _ctx = &_ctxs;
+  camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx);
+  filename = String_val(_v_filename);
+  Z3_datalog_parse_file(c, filename);
+  camlidl_free(_ctx);
+  return Val_unit;
+}
+
+ external/z3/ocaml/z3_theory_stubs.c view
@@ -0,0 +1,337 @@+/*++
+Copyright (c) 2010 Microsoft Corporation
+
+Module Name:
+
+    z3_theory_stubs.c
+
+Abstract:
+
+    OCaml C bindings for callbacks between OCaml and C for
+    theory plugins. 
+    The API for theory plugins require associating a set of
+    callbacks as C function pointers.  
+    We use the following strategy:
+
+    - store in the user_ext_data blob that theory constructors allow
+      a record of callback functions.
+
+    - define catch-all static callback functions that access the 
+      ML record with the callbacks. It then invokes these through user-registered
+      application functions that apply the callback stored in the record to the
+      actual parameters.
+      It is tempting to avoid this user-registered callback and directly access 
+      the record of callback functions and apply the proper field. 
+      However, the layout of records appears to be opaque, or at least we assume it is
+      so, from the C runtime.
+
+Author:
+
+
+Revision History:
+--*/
+
+#include <stddef.h>
+#include <string.h>
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/callback.h>
+#ifdef Custom_tag
+#include <caml/custom.h>
+#include <caml/bigarray.h>
+#endif
+
+#include "z3.h"
+
+#define ML_SIZE(_ty) ((sizeof(_ty) + sizeof(value) - 1)/ sizeof(value))
+
+static value mk_func_decl(Z3_func_decl f) {
+    value _f = alloc(ML_SIZE(Z3_func_decl), Abstract_tag);
+    *((Z3_func_decl*) Bp_val(_f)) = f;
+    return _f;
+}
+
+static value Val_ast(Z3_ast a) {
+    value _a = alloc(ML_SIZE(Z3_ast), Abstract_tag);
+    *((Z3_ast*) Bp_val(_a)) = a;
+    return _a;
+}
+
+
+static value Val_ast_array(unsigned int sz, Z3_ast const args[]) {
+    value res;
+    Z3_ast* args1;
+    unsigned int i;
+    args1 = malloc((sz+1)*sizeof(Z3_ast));
+    for (i = 0; i < sz; ++i) {
+        args1[i] = args[i];
+    }
+    args1[sz] = 0;
+    res = alloc_array((value (*)(char const*))Val_ast, (const char**)args1);
+    free(args1);
+    return res;
+}
+
+// ------------------
+// get_theory_callbacks
+// 
+
+value get_theory_callbacks(value th) 
+{
+    Z3_theory _th = *((Z3_theory*) Bp_val(th));
+    return (value) Z3_theory_get_ext_data(_th);
+}
+
+// ------------------
+// delete_theory
+// 
+static void delete_callback_static(Z3_theory th) 
+{
+    CAMLparam0();
+    CAMLlocal1(f);  
+    value user_data = (value) Z3_theory_get_ext_data(th);
+    f = *(caml_named_value("apply_delete")) ;
+    callback(f, user_data);
+    remove_global_root(&user_data);
+    CAMLreturn0;
+}
+
+#define SET_CALLBACK(_cb_name)                     \
+    value set_ ## _cb_name ## _callback_register(value th)  \
+    {                                              \
+        CAMLparam1(th);                                         \
+        Z3_theory _th = *((Z3_theory*) Bp_val(th));                     \
+        Z3_set_ ## _cb_name ## _callback(_th, _cb_name ## _callback_static);   \
+        CAMLreturn(Val_unit);                                           \
+    }                                                                   \
+
+SET_CALLBACK(delete);
+
+
+// ------------------
+// mk_theory
+// 
+
+value mk_theory_register(value context, value name, value user_data) 
+{
+    CAMLparam3(context, name, user_data);
+    Z3_context _context = *((Z3_context *) Bp_val(context));
+    value _th;
+    Z3_theory th;
+    register_global_root(&user_data);
+    th = Z3_mk_theory(_context, String_val(name), (void*)user_data);
+    Z3_set_delete_callback(th, delete_callback_static);
+    _th = alloc(ML_SIZE(Z3_context), Abstract_tag);
+    *((Z3_theory*) Bp_val(_th)) = th;
+    CAMLreturn(_th);
+}
+
+
+// -------------------
+// reduce_app_callback
+
+static Z3_bool reduce_app_callback_static(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r) {
+    CAMLparam0();
+    CAMLlocal4(cb, _r, _v, _args);
+    value user_data;
+    Z3_bool result;
+
+    _args = Val_ast_array(num_args, args);
+
+    user_data = (value) Z3_theory_get_ext_data(th);
+
+    cb = *(caml_named_value("apply_reduce_app"));
+    _r = callback3(cb, user_data, mk_func_decl(f), _args);
+
+    cb = *(caml_named_value("is_some"));
+    _v = callback(cb, _r);
+    result = 0 != Bool_val(_v);
+
+    if (result && r) {
+        cb = *(caml_named_value("get_some"));
+        _v = callback(cb, _r);
+        *r = *((Z3_ast*) Bp_val(_v));
+    }
+
+    CAMLreturn (result);
+}
+
+SET_CALLBACK(reduce_app);
+
+// -------------------
+// reduce_eq_callback
+
+static Z3_bool reduce_eq_callback_static(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast * r) 
+{
+    CAMLparam0();
+    CAMLlocal5(cb, _r, _a, _b, _v);
+    value user_data;
+    Z3_bool result;
+
+    _a = Val_ast(a);
+    _b = Val_ast(b);
+
+    user_data = (value) Z3_theory_get_ext_data(th);
+
+    cb = *(caml_named_value("apply_reduce_eq"));
+    _r = callback3(cb, user_data, _a, _b);
+
+    cb = *(caml_named_value("is_some"));
+    _v = callback(cb, _r);
+    result = 0 != Bool_val(_v);
+
+    if (result && r) {
+        cb = *(caml_named_value("get_some"));
+        _v = callback(cb, _r);
+        *r = *((Z3_ast*) Bp_val(_v));
+    }
+
+    CAMLreturn (result);
+}
+
+SET_CALLBACK(reduce_eq);
+
+
+// -------------------
+// reduce_distinct
+
+static Z3_bool reduce_distinct_callback_static(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast * r)
+{
+    CAMLparam0();
+    CAMLlocal4(cb, _r, _args, _v);
+    value user_data;
+    Z3_bool result;
+
+    _args = Val_ast_array(n, args);
+
+    user_data = (value) Z3_theory_get_ext_data(th);
+
+    cb = *(caml_named_value("apply_reduce_distinct"));
+    _r = callback2(cb, user_data, _args);
+
+    cb = *(caml_named_value("is_some"));
+    _v = callback(cb, _r);
+    result = 0 != Bool_val(_v);
+
+    if (result && r) {
+        cb = *(caml_named_value("get_some"));
+        _v = callback(cb, _r);
+        *r = *((Z3_ast*) Bp_val(_v));
+    }
+
+    CAMLreturn (result);
+}
+
+SET_CALLBACK(reduce_distinct);
+
+// -------------------
+// new_app
+
+#define AST_CALLBACK(_cb_name) \
+static void _cb_name##_callback_static(Z3_theory th, Z3_ast a)        \
+{                                                           \
+    CAMLparam0();                                           \
+    CAMLlocal3(cb, _a, user_data);                          \
+    _a = Val_ast(a);                                         \
+    user_data = (value) Z3_theory_get_ext_data(th);         \
+    cb = *(caml_named_value("apply_" #_cb_name));           \
+    callback2(cb, user_data, _a);                           \
+    CAMLreturn0;                                            \
+}                                                           \
+
+AST_CALLBACK(new_app);
+SET_CALLBACK(new_app);
+
+// -------------------
+// new_elem
+
+AST_CALLBACK(new_elem);
+SET_CALLBACK(new_elem);
+
+// -------------------
+// init_search
+
+#define TH_CALLBACK(_cb_name) \
+static void _cb_name##_callback_static(Z3_theory th)        \
+{                                                           \
+    CAMLparam0();                                           \
+    CAMLlocal2(cb, user_data);                              \
+    user_data = (value) Z3_theory_get_ext_data(th);         \
+    cb = *(caml_named_value("apply_" #_cb_name));           \
+    callback(cb, user_data);                                \
+    CAMLreturn0;                                            \
+}                                                           \
+
+TH_CALLBACK(init_search);
+SET_CALLBACK(init_search);
+
+// -------------------
+// push
+
+TH_CALLBACK(push);
+SET_CALLBACK(push);
+
+TH_CALLBACK(pop);
+SET_CALLBACK(pop);
+
+TH_CALLBACK(restart);
+SET_CALLBACK(restart);
+
+TH_CALLBACK(reset);
+SET_CALLBACK(reset);
+
+        
+#define FC_CALLBACK(_cb_name) \
+    static Z3_bool _cb_name##_callback_static(Z3_theory th)             \
+    {                                                                   \
+    CAMLparam0();                                                       \
+    CAMLlocal3(cb, r, user_data);                                       \
+    user_data = (value) Z3_theory_get_ext_data(th);                     \
+    cb = *(caml_named_value("apply_" #_cb_name));                       \
+    r = callback(cb, user_data);                                        \
+    CAMLreturn (Bool_val(r) != 0);                                      \
+    }                                                                   \
+    
+FC_CALLBACK(final_check);
+SET_CALLBACK(final_check);
+
+#define AST_AST_CALLBACK(_cb_name) \
+    static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_ast b)     \
+    {                                                                   \
+        CAMLparam0();                                                   \
+        CAMLlocal4(cb, _a, _b, user_data);                              \
+        _a = Val_ast(a);                                                \
+        _b = Val_ast(b);                                                \
+        user_data = (value) Z3_theory_get_ext_data(th);                 \
+        cb = *(caml_named_value("apply_" #_cb_name));                   \
+        callback3(cb, user_data, _a, _b);                               \
+        CAMLreturn0;                                                    \
+    }                                                                   \
+    
+AST_AST_CALLBACK(new_eq);
+SET_CALLBACK(new_eq);
+
+AST_AST_CALLBACK(new_diseq);
+SET_CALLBACK(new_diseq);
+
+#define AST_BOOL_CALLBACK(_cb_name) \
+    static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_bool b)     \
+    {                                                                   \
+        CAMLparam0();                                                   \
+        CAMLlocal4(cb, _a, _b, user_data);                              \
+        _a = Val_ast(a);                                                \
+        _b = Val_bool(b);                                               \
+        user_data = (value) Z3_theory_get_ext_data(th);                 \
+        cb = *(caml_named_value("apply_" #_cb_name));                   \
+        callback3(cb, user_data, _a, _b);                               \
+        CAMLreturn0;                                                    \
+    }                                                                   \
+
+    
+AST_BOOL_CALLBACK(new_assignment);
+SET_CALLBACK(new_assignment);
+
+AST_CALLBACK(new_relevant);
+SET_CALLBACK(new_relevant);
+ liquid-fixpoint.cabal view
@@ -0,0 +1,133 @@+name:                liquid-fixpoint+version:             0.1.0.0+synopsis:            Predicate Abstraction-based Horn-Clause/Implication Constraint Solver+homepage:            https://github.com/ucsd-progsys/liquid-fixpoint+license:             BSD3+license-file:        LICENSE+author:              Ranjit Jhala+maintainer:          jhala@cs.ucsd.edu+category:            Language+build-type:          Custom +cabal-version:       >=1.8++description:     This package is a Haskell wrapper to the SMTLIB-based+                 Horn-Clause/Logical Implication constraint solver used+                 for Liquid Types. +                 .+                 The solver itself is written in Ocaml. +                 .+                 The package includes: +                 .+                 1. Types for Expressions, Predicates, Constraints, Solutions+                 .+                 2. Code for serializing the above+                 .+                 3. Code for parsing the results from the fixpoint.native binary+                 .+                 4. The Ocaml fixpoint code+                 .+                 5. (Deprecated) Z3 binaries if you want to link against the API.+                 .+                 Requirements+                 .+                 In addition to the .cabal dependencies you require +                 .+                 - A Recent Ocaml compiler+                 .+                 - A Z3 Binary (<http://z3.codeplex.com>)+++Extra-Source-Files: configure+                  , external/fixpoint/Makefile+                  , external/fixpoint/*.ml+                  , external/fixpoint/smtZ3.mem.ml+                  , external/fixpoint/smtZ3.nomem.ml+                  , external/fixpoint/*.mli+                  , external/fixpoint/*.mll+                  , external/fixpoint/*.mly+                  , external/misc/*.ml+                  , external/misc/*.mli+                  , external/ocamlgraph/.depend+                  , external/ocamlgraph/Makefile+                  , external/ocamlgraph/Makefile.in+                  , external/ocamlgraph/META+                  , external/ocamlgraph/META.in+                  , external/ocamlgraph/configure+                  , external/ocamlgraph/configure.in+                  , external/ocamlgraph/lib/*.ml+                  , external/ocamlgraph/lib/*.mli+                  , external/ocamlgraph/src/*.ml+                  , external/ocamlgraph/src/*.mli+                  , external/ocamlgraph/src/*.mll+                  , external/ocamlgraph/src/*.mly+                  , external/z3/include/*.h+                  , external/z3/lib/libz3-a-32b+                  , external/z3/lib/libz3-a-64b+                  , external/z3/lib/libz3-so-32b+                  , external/z3/lib/libz3-so-64b+                  , external/z3/ocaml/build-lib.sh+                  , external/z3/ocaml/z3.ml+                  , external/z3/ocaml/*.c++Flag z3mem+  Description: Link to Z3+  Default:     False++Executable fixpoint+  Main-is:       Fixpoint.hs+  Build-Depends: base >= 4 && < 5+               , ghc==7.6.3+               , array+               , syb+               , cmdargs+               , ansi-terminal+               , bifunctors+               , bytestring+               , containers+               , deepseq+               , directory+               , filemanip+               , filepath+               , ghc-prim+               , mtl+               , parsec+               , pretty+               , process+               , text+               , hashable<1.2+               , unordered-containers+               , liquid-fixpoint++Library+  hs-source-dirs:  src+  Exposed-Modules: Language.Fixpoint.Names,+                   Language.Fixpoint.Files,+                   Language.Fixpoint.Config,+                   Language.Fixpoint.Types,+                   Language.Fixpoint.Sort,+                   Language.Fixpoint.Interface, +                   Language.Fixpoint.Parse,+                   Language.Fixpoint.PrettyPrint,+                   Language.Fixpoint.Misc+  +  Build-Depends: base+               , ghc==7.6.3+               , array+               , syb+               , cmdargs+               , ansi-terminal+               , bifunctors+               , bytestring+               , containers+               , deepseq+               , directory+               , filemanip+               , filepath+               , ghc-prim+               , mtl+               , parsec+               , pretty+               , process+               , text+               , hashable<1.2+               , unordered-containers
+ src/Language/Fixpoint/Config.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE DeriveGeneric             #-}+{-# LANGUAGE DeriveDataTypeable        #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE UndecidableInstances      #-}+++module Language.Fixpoint.Config (+    Config  (..)+  , Command (..)+  , SMTSolver (..)+  , GenQualifierSort (..)+  , withTarget +) where  +  +import Language.Fixpoint.Files+import System.FilePath       +import System.Console.CmdArgs.Default+import Data.Typeable        (Typeable)+import Data.Generics        (Data)+++class Command a  where+  command :: a -> String++------------------------------------------------------------------------+-- Configuration Options -----------------------------------------------+------------------------------------------------------------------------++withTarget        :: Config -> FilePath -> Config +withTarget cfg fq = cfg { inFile = fq } { outFile = fq `withExt` Out }++data Config +  = Config { +      inFile   :: FilePath         -- target fq-file +    , outFile  :: FilePath         -- output file+    , solver   :: SMTSolver        -- which SMT solver to use +    , genSorts :: GenQualifierSort -- generalize qualifier sorts+    } deriving (Eq,Data,Typeable,Show)++instance Default Config where+  def = Config "" def def def++instance Command Config where +  command c =  command (genSorts c)    +            ++ command (solver c) +            ++ " -out " +            ++ (outFile c) ++ " " ++ (inFile c)++---------------------------------------------------------------------------------------+-- newtype OFilePath = O FilePath +--     deriving (Eq, Data,Typeable,Show)+-- +-- instance Default OFilePath where +--   def = O "out"+-- +-- instance Command OFilePath where +--   command (O s) = " -out " ++ s++newtype GenQualifierSort = GQS Bool +    deriving (Eq, Data,Typeable,Show)++instance Default GenQualifierSort where+  def = GQS False++instance Command GenQualifierSort where+  command (GQS True)  = ""+  command (GQS False) = "-no-gen-qual-sorts" ++---------------------------------------------------------------------------------------++data SMTSolver = Z3 | Cvc4 | Mathsat | Z3mem+                 deriving (Eq,Data,Typeable)++instance Command SMTSolver where +  command s = " -smtsolver " ++ show s++instance Default SMTSolver where+  def = Z3++instance Show SMTSolver where +  show Z3      = "z3"+  show Cvc4    = "cvc4"+  show Mathsat = "mathsat"+  show Z3mem   = "z3mem"++smtSolver "z3"      = Z3+smtSolver "cvc4"    = Cvc4+smtSolver "mathsat" = Mathsat+smtSolver "z3mem"   = Z3mem+smtSolver other     = error $ "ERROR: unsupported SMT Solver = " ++ other++-- defaultSolver       :: Maybe SMTSolver -> SMTSolver+-- defaultSolver       = fromMaybe Z3 +++
+ src/Language/Fixpoint/Files.hs view
@@ -0,0 +1,139 @@+{-# LANGUAGE ScopedTypeVariables #-}++-- | This module contains Haskell variables representing globally visible +-- names for files, paths, extensions.+--+-- Rather than have strings floating around the system, all constant names+-- should be defined here, and the (exported) variables should be used and+-- manipulated elsewhere.++module Language.Fixpoint.Files (+  +  -- * Hardwired file extension names+    Ext (..)+  , extFileName+  , extModuleName+  , withExt+  , isExtFile+ +  -- * Hardwired paths +  , getFixpointPath, getZ3LibPath++  -- * Various generic utility functions for finding and removing files+  , getHsTargets+  , getFileInDirs+  , findFileInDirs+  , copyFiles+  +) where++import qualified Control.Exception            as Ex+import           Control.Monad -- .State+import           Data.Functor                 ((<$>))+import           Data.List                    hiding (find)+import           Data.Maybe                   (fromMaybe)+import           System.Directory+import           System.Environment+import           System.FilePath+import           System.FilePath.Find+import           Language.Fixpoint.Misc++------------------------------------------------------------+-- | Hardwired Paths and Files -----------------------------+------------------------------------------------------------++getFixpointPath = fromMaybe msg <$> findExecutable "fixpoint.native"+  where msg     = errorstar "Cannot find fixpoint binary [fixpoint.native]"++getZ3LibPath    = dropFileName <$> getFixpointPath+++checkM f msg p +  = do ex <- f p+       if ex then return p else errorstar $ "Cannot find " ++ msg ++ " at :" ++ p+++-----------------------------------------------------------------------------------++data Ext = Cgi    -- ^ Constraint Generation Information +         | Fq     -- ^ Input to constraint solving (fixpoint)+         | Out    -- ^ Output from constraint solving (fixpoint)+         | Html   -- ^ HTML file with inferred type annotations +         | Annot  -- ^ Text file with inferred types +         | Hs     -- ^ Target source +         | LHs    -- ^ Literate Haskell target source file+         | Spec   -- ^ Spec file (e.g. include/Prelude.spec) +         | Hquals -- ^ Qualifiers file (e.g. include/Prelude.hquals)+         | Result -- ^ Final result: SAFE/UNSAFE+         | Cst    -- ^ HTML file with templates?+         | Mkdn   -- ^ Markdown file (temporarily generated from .Lhs + annots) +         | Json   -- ^ JSON file containing result (annots + errors)+         | Saved  -- ^ Previous version of source (for incremental checking)+         | Pred   +         | PAss    +         | Dat    +         deriving (Eq, Ord, Show)++extMap e = go e+  where +    go Cgi    = ".cgi"+    go Pred   = ".pred"+    go PAss   = ".pass"+    go Dat    = ".dat"+    go Out    = ".fqout"+    go Fq     = ".fq"+    go Html   = ".html"+    go Cst    = ".cst"+    go Annot  = ".annot"+    go Hs     = ".hs"+    go LHs    = ".lhs"+    go Mkdn   = ".markdown"+    go Json   = ".json"+    go Spec   = ".spec"+    go Hquals = ".hquals" +    go Result = ".out"+    go Saved  = ".bak"+    go _      = errorstar $ "extMap: Unknown extension " ++ show e++withExt         :: FilePath -> Ext -> FilePath +withExt f ext   =  replaceExtension f (extMap ext)++extFileName     :: Ext -> FilePath -> FilePath+extFileName ext = (`addExtension` (extMap ext))++isExtFile ::  Ext -> FilePath -> Bool+isExtFile ext = ((extMap ext) ==) . takeExtension++extModuleName ::  String -> Ext -> FilePath+extModuleName modName ext =+  case explode modName of+    [] -> errorstar $ "malformed module name: " ++ modName+    ws -> extFileName ext $ foldr1 (</>) ws+  where explode = words . map (\c -> if c == '.' then ' ' else c)++copyFiles :: [FilePath] -> FilePath -> IO ()+copyFiles srcs tgt+  = do Ex.catch (removeFile tgt) $ \(_ :: Ex.IOException) -> return ()+       forM_ srcs (readFile >=> appendFile tgt)+++----------------------------------------------------------------------------------++getHsTargets p+  | hasTrailingPathSeparator p = getHsSourceFiles p+  | otherwise                  = return [p]++getHsSourceFiles = find dirs hs+  where hs   = extension ==? ".hs" ||? extension ==? ".lhs"+        dirs = liftM (not . ("dist" `isSuffixOf`)) directory++---------------------------------------------------------------------------+++getFileInDirs :: FilePath -> [FilePath] -> IO (Maybe FilePath)+getFileInDirs name = findFirst (testM doesFileExist . (</> name))++findFileInDirs ::  FilePath -> [FilePath] -> IO FilePath+findFileInDirs file dirs+  = liftM (fromMaybe err) (findFirst (find always (fileName ==? file)) dirs)+    where err = errorstar $ "findFileInDirs: cannot find " ++ file ++ " in " ++ show dirs
+ src/Language/Fixpoint/Interface.hs view
@@ -0,0 +1,127 @@+module Language.Fixpoint.Interface (+    +    -- * Containing Constraints+    FInfo (..)+ +    -- * Invoke Solver on Set of Constraints+  , solve+  , solveFile++    -- * Function to determine outcome+  , resultExit+ +    -- * Validity Query+  , checkValid ++) where++{- Interfacing with Fixpoint Binary -}++import Data.Hashable+import Data.Monoid+import Data.Functor+import Data.List+import qualified Data.HashMap.Strict as M+import System.IO        (hPutStr, withFile, IOMode (..))+import System.Exit+import System.Directory (getTemporaryDirectory)+import System.FilePath  ((</>))+import Text.Printf++import Language.Fixpoint.Config+import Language.Fixpoint.Types         hiding (kuts, lits)+import Language.Fixpoint.Misc+import Language.Fixpoint.Parse            (rr)+import Language.Fixpoint.Files+import Text.PrettyPrint.HughesPJ+import System.Console.CmdArgs.Default+import System.Console.CmdArgs.Verbosity++---------------------------------------------------------------------------+-- | One Shot validity query ----------------------------------------------+---------------------------------------------------------------------------++---------------------------------------------------------------------------+checkValid :: (Hashable a) => a -> [(Symbol, Sort)] -> Pred -> IO (FixResult a) +---------------------------------------------------------------------------+checkValid n xts p +  = do file   <- (</> show (hash n)) <$> getTemporaryDirectory+       (r, _) <- solve def file [] $ validFInfo n xts p+       return (sinfo <$> r)  ++validFInfo         :: a -> [(Symbol, Sort)] -> Pred -> FInfo a+validFInfo l xts p = FI constrm [] benv emptySEnv [] ksEmpty []+  where +    constrm        = M.singleton 0 $ validSubc l ibenv p +    binds          = [(x, trueSortedReft t) | (x, t) <- xts]+    ibenv          = insertsIBindEnv bids emptyIBindEnv+    (bids, benv)   = foldlMap (\e (x,t) -> insertBindEnv x t e) emptyBindEnv binds++validSubc         :: a -> IBindEnv -> Pred -> SubC a  +validSubc l env p = subC env PTrue lhs rhs i t l+  where +    lhs           = top+    rhs           = RR mempty (predReft p)+    i             = Just 0+    t             = []++result         :: a -> Bool -> FixResult a    +result _ True  = Safe +result x False = Unsafe [x]+++---------------------------------------------------------------------------+-- | Solve a system of horn-clause constraints ----------------------------+---------------------------------------------------------------------------++---------------------------------------------------------------------------+solve :: Config -> FilePath -> [FilePath] -> FInfo a +      -> IO (FixResult (SubC a), M.HashMap Symbol Pred)+---------------------------------------------------------------------------+solve cfg fn hqs fi+  =   {-# SCC "Solve" #-}  execFq cfg fn hqs fi+  >>= {-# SCC "exitFq" #-} exitFq fn (cm fi) +      +execFq cfg fn hqs fi+  = do copyFiles hqs fq+       appendFile fq qstr +       withFile fq AppendMode (\h -> {-# SCC "HPrintDump" #-} hPutStr h (render d))+       solveFile $ cfg `withTarget` fq+    where +       fq   = extFileName Fq fn+       d    = {-# SCC "FixPointify" #-} toFixpoint fi +       qstr = render ((vcat $ toFix <$> (quals fi)) $$ text "\n")++---------------------------------------------------------------------------+solveFile :: Config -> IO ExitCode +---------------------------------------------------------------------------+solveFile cfg+  = do fp  <- getFixpointPath+       z3  <- getZ3LibPath+       v   <- (\b -> if b then "-v 1" else "") <$> isLoud+       ec  <- {-# SCC "sysCall:Fixpoint" #-} executeShellCommand "fixpoint" $ fixCommand cfg fp z3 v+       return ec+ +fixCommand cfg fp z3 verbosity +  = printf "LD_LIBRARY_PATH=%s %s %s -notruekvars -refinesort -noslice -nosimple -strictsortcheck -sortedquals %s" +           z3 fp verbosity (command cfg)++exitFq _ _ (ExitFailure n) | (n /= 1) +  = return (Crash [] "Unknown Error", M.empty)+exitFq fn cm _ +  = do str <- {-# SCC "readOut" #-} readFile (extFileName Out fn)+       let (x, y) = {-# SCC "parseFixOut" #-} rr ({-# SCC "sanitizeFixpointOutput" #-} sanitizeFixpointOutput str)+       return  $ (plugC cm x, y) ++plugC = fmap . mlookup++sanitizeFixpointOutput +  = unlines +  . filter (not . ("//"     `isPrefixOf`)) +  . chopAfter ("//QUALIFIERS" `isPrefixOf`)+  . lines++resultExit Safe        = ExitSuccess+resultExit (Unsafe _)  = ExitFailure 1+resultExit _           = ExitFailure 2+
+ src/Language/Fixpoint/Misc.hs view
@@ -0,0 +1,358 @@+{-# LANGUAGE DeriveDataTypeable, TupleSections, NoMonomorphismRestriction, ScopedTypeVariables #-}++module Language.Fixpoint.Misc where++import Data.Hashable+import qualified Control.Exception     as Ex+-- import qualified Data.HashSet        as S +import qualified Data.HashMap.Strict   as M+import qualified Data.List             as L+import qualified Data.ByteString       as B+import Data.ByteString.Char8    (pack, unpack)+import Control.Applicative      ((<$>))+import Control.Monad            (forM_)+import Data.Maybe               (fromJust)+import Data.Maybe               (catMaybes, fromMaybe)++import System.Exit+import System.Process           (system)+import Debug.Trace              (trace)+import Data.Data+import System.Console.ANSI+import System.Console.CmdArgs.Verbosity (whenLoud)++import Text.PrettyPrint.HughesPJ++-----------------------------------------------------------------------------------+------------ Support for Colored Logging ------------------------------------------+-----------------------------------------------------------------------------------++data Moods = Ok | Loud | Sad | Happy | Angry ++moodColor Ok    = Black+moodColor Loud  = Blue +moodColor Sad   = Magenta +moodColor Happy = Green +moodColor Angry = Red ++wrapStars msg = "\n**** " ++ msg ++ " " ++ replicate (74 - length msg) '*'+    +withColor c act+  = do setSGR [ SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid c] +       act+       setSGR [ Reset]++colorStrLn c       = withColor (moodColor c) . putStrLn +colorPhaseLn c msg = colorStrLn c . wrapStars .  (msg ++)+startPhase c msg   = colorPhaseLn c "START: " msg >> colorStrLn Ok " "+doneLine   c msg   = colorPhaseLn c "DONE:  " msg >> colorStrLn Ok " "++donePhase c str +  = case lines str of +      (l:ls) -> doneLine c l >> forM_ ls (colorPhaseLn c "")+      _      -> return ()++-----------------------------------------------------------------------------------++data Empty = Emp deriving (Data, Typeable, Eq, Show)++unIntersperse x ys+  = case L.elemIndex x ys of+      Nothing -> [ys]+      Just i  -> let (y, _:ys') = splitAt i ys +                 in (y : unIntersperse x ys')++(=>>) m f = m >>= (\x -> f x >> return x)++wrap l r s = l ++ s ++ r++repeats n  = concat . replicate n++errorstar  = error . wrap (stars ++ "\n") (stars ++ "\n") +  where stars = repeats 3 $ wrapStars "ERROR"++errortext  = errorstar . render ++putDocLn :: Doc -> IO ()+putDocLn = putStrLn . render ++assertstar _   True  x = x+assertstar msg False x = errorstar msg ++findWithDefaultL f ls d = fromMaybe d (L.find f ls)++fst3 ::  (a, b, c) -> a+fst3 (x,_,_) = x++snd3 ::  (a, b, c) -> b+snd3 (_,x,_) = x++thd3 ::  (a, b, c) -> c+thd3 (_,_,x) = x+++single ::  a -> [a]+single x = [x]++mapFst f (x, y)  = (f x, y)+mapSnd f (x, y)  = (x, f y)++mapFst3 f (x, y, z) = (f x, y, z)+mapSnd3 f (x, y, z) = (x, f y, z)+mapThd3 f (x, y, z) = (x, y, f z)++expandSnd = concatMap (\(xs, y) -> (, y) <$> xs)++mapPair ::  (a -> b) -> (a, a) -> (b, b)+mapPair f (x, y) = (f x, f y)++-- mlookup ::  (Show k, Hashable k) => M.HashMap k v -> k -> v+mlookup m k +  = case M.lookup k m of+      Just v  -> v+      Nothing -> errorstar $ "mlookup: unknown key " ++ show k+++mfromJust ::  String -> Maybe a -> a+mfromJust _ (Just x) = x +mfromJust s Nothing  = errorstar $ "mfromJust: Nothing " ++ s++boxStrCat ::  String -> [String] -> String +boxStrCat sep = ("[" ++) . (++ "]") . L.intercalate sep ++tryIgnore :: String -> IO () -> IO ()+tryIgnore s a = Ex.catch a $ \e -> +                do let err = show (e :: Ex.IOException)+                   putStrLn ("Warning: Couldn't do " ++ s ++ ": " ++ err)+                   return ()++traceShow     ::  Show a => String -> a -> a+traceShow s x = trace ("\nTrace: [" ++ s ++ "] : " ++ show x) $ x++warnShow      ::  Show a => String -> a -> a+warnShow s x  = trace ("\nWarning: [" ++ s ++ "] : " ++ show x) $ x++-- inserts       ::  Hashable k => k -> v -> M.HashMap k [v] -> M.HashMap k [v]+inserts k v m = M.insert k (v : M.lookupDefault [] k m) m++-- group         :: Hashable k => [(k, v)] -> M.HashMap k [v]+group         = L.foldl' (\m (k, v) -> inserts k v m) M.empty ++groupList     = M.toList . group++-- groupMap      :: Hashable k => (a -> k) -> [a] -> M.HashMap k [a]+groupMap f xs = L.foldl' (\m x -> inserts (f x) x m) M.empty xs ++sortNub :: (Ord a) => [a] -> [a]+sortNub = nubOrd . L.sort+  where nubOrd (x:t@(y:_)) +          | x == y    = nubOrd t +          | otherwise = x : nubOrd t+        nubOrd xs = xs+++sortDiff :: (Ord a) => [a] -> [a] -> [a]+sortDiff x1s x2s                 = go (sortNub x1s) (sortNub x2s)+  where go xs@(x:xs') ys@(y:ys') +          | x <  y               = x : go xs' ys+          | x == y               = go xs' ys'+          | otherwise            = go xs ys'+        go xs []                 = xs+        go [] _                  = []+++++distinct ::  Ord a => [a] -> Bool+distinct xs = length xs == length (sortNub xs)++tr_reverse ::  [a] -> [a]+tr_reverse      = L.foldl' (flip (:)) []  ++tr_foldr' ::  (a -> b -> b) -> b -> [a] -> b+tr_foldr' f b   = L.foldl' (flip f) b . tr_reverse ++safeZip msg xs ys +  | nxs == nys +  = zip xs ys+  | otherwise              +  = errorstar $ "safeZip called on non-eq-sized lists (nxs = " ++ show nxs ++ ", nys = " ++ show nys ++ ") : " ++ msg+  where nxs = length xs+        nys = length ys++-- eqLen = on (==) length ++safeZipWith msg f xs ys +  | nxs == nys +  = zipWith f xs ys+  | otherwise              +  = errorstar $ "safeZipWith called on non-eq-sized lists (nxs = " ++ show nxs ++ ", nys = " ++ show nys ++ ") : " ++ msg+    where nxs = length xs+          nys = length ys++-- safe0ZipWith msg f xs ys +--   | length xs == length ys +--   = zipWith f xs ys+-- safe0ZipWith _ _ [] _+--   = []+-- safe0ZipWith _ _ _ []+--   = []+-- safe0ZipWith msg _ xs ys +--   = errorstar $ "safeZipWith called on non-eq-sized lists (nxs = " ++ show nxs ++ ", nys = " ++ show nys ++ ") : " ++ msg+--     where nxs = length xs+--           nys = length ys+++-- safeFromList :: (Hashable k, Show k, Show a) => String -> [(k, a)] -> M.HashMap k a+safeFromList msg = L.foldl' safeAdd M.empty +  where safeAdd m (k, v) +          | k `M.member` m = errorstar $ msg ++ "Duplicate key " ++ show k ++ "maps to: \n" ++ (show v) ++ "\n and \n" ++ show (m M.! k)+          | otherwise      = M.insert k v m++safeUnion msg m1 m2 = +  case L.find (`M.member` m1) (M.keys m2) of+    Just k  -> errorstar $ "safeUnion with common key = " ++ show k ++ " " ++ msg+    Nothing -> M.union m1 m2++safeHead _   (x:_) = x+safeHead msg _     = errorstar $ "safeHead with empty list " ++ msg++safeLast _ xs@(_:_) = last xs+safeLast msg _      = errorstar $ "safeLast with empty list " ++ msg++safeInit _ xs@(_:_) = init xs+safeInit msg _      = errorstar $ "safeInit with empty list " ++ msg+++-- memoIndex :: (Hashable b) => (a -> Maybe b) -> [a] -> [Maybe Int]+memoIndex f = snd . L.mapAccumL foo M.empty +  where +  foo memo z =+    case f z of +      Nothing -> (memo, Nothing)+      Just k  -> case k `M.lookup` memo of +                   Just i  -> (memo, Just i)+                   Nothing -> (M.insert k (M.size memo) memo, Just (M.size memo))++checkFail ::  [Char] -> (a -> Bool) -> a -> a+checkFail msg f x +  | f x+  = x+  | otherwise+  = errorstar $ "Check-Failure: " ++ msg++chopAfter ::  (a -> Bool) -> [a] -> [a]+chopAfter f xs +  = case L.findIndex f xs of+      Just n  -> take n xs+      Nothing -> xs++chopPrefix p xs +  | p `L.isPrefixOf` xs+  = Just $ drop (length p) xs+  | otherwise +  = Nothing++firstElem ::  (Eq a) => [(a, t)] -> [a] -> Maybe Int+firstElem seps str +  = case catMaybes [ L.elemIndex c str | (c, _) <- seps ] of +      [] -> Nothing+      is -> Just $ minimum is ++chopAlt ::  (Eq a) => [(a, a)] -> [a] -> [[a]]+chopAlt seps    = go +  where go  s   = maybe [s] (go' s) (firstElem seps s)+        go' s i = let (s0, s1@(c:_)) = splitAt i s +                      (Just c')      = lookup c seps +                  in case L.elemIndex c' s1 of+                       Nothing -> [s1]+                       Just i' -> let (s2, s3) = splitAt (i' + 1) s1 in +                                  s0 : s2 : go s3++firstElems ::  [(B.ByteString, B.ByteString)] -> B.ByteString -> Maybe (Int, B.ByteString, (B.ByteString, B.ByteString))+firstElems seps str +  = case splitters seps str of +      [] -> Nothing+      is -> Just $ L.minimumBy (\x y -> compare (fst3 x) (fst3 y)) is ++splitters seps str +  = [(i, c', z) | (c, c') <- seps+                , let z   = B.breakSubstring c str+                , let i   = B.length (fst z)+                , i < B.length str                 ]+++bchopAlts :: [(B.ByteString, B.ByteString)] -> B.ByteString -> [B.ByteString]+bchopAlts seps  = go +  where +    go  s                 = maybe [s] (go' s) (firstElems seps s)+    go' s (i,c',(s0, s1)) = if (B.length s2 == B.length s1) then [B.concat [s0,s1]] else (s0 : s2' : go s3')+                            where (s2, s3) = B.breakSubstring c' s1+                                  s2'      = B.append s2 c'+                                  s3'      = B.drop (B.length c') s3 ++chopAlts seps str = unpack <$> bchopAlts [(pack c, pack c') | (c, c') <- seps] (pack str)++findFirst ::  Monad m => (t -> m [a]) -> [t] -> m (Maybe a)+findFirst _ []     = return Nothing+findFirst f (x:xs) = do r <- f x+                        case r of +                          y:_ -> return (Just y)+                          []  -> findFirst f xs++testM f x = do b <- f x+               return $ if b then [x] else [] ++-- unions :: (Hashable a) => [S.HashSet a] -> S.HashSet a+-- unions = foldl' S.union S.empty+-- Just S.unions!++stripParens ('(':xs)  = stripParens xs+stripParens xs        = stripParens' (reverse xs)+stripParens' (')':xs) = stripParens' xs+stripParens' xs       = reverse xs++ifM :: (Monad m) => m Bool -> m a -> m a -> m a+ifM bm xm ym +  = do b <- bm+       if b then xm else ym++executeShellCommand phase cmd +  = do whenLoud $ putStrLn $ "EXEC: " ++ cmd +       Ex.bracket_ (startPhase Loud phase) (donePhase Loud phase) $ system cmd++checkExitCode _   (ExitSuccess)   = return ()+checkExitCode cmd (ExitFailure n) = errorstar $ "cmd: " ++ cmd ++ " failure code " ++ show n ++hashMapToAscList    ::  Ord a => M.HashMap a b -> [(a, b)]+hashMapToAscList    = L.sortBy (\x y -> compare (fst x) (fst y)) . M.toList++hashMapMapWithKey   :: (k -> v1 -> v2) -> M.HashMap k v1 -> M.HashMap k v2+hashMapMapWithKey f = fromJust . M.traverseWithKey (\k v -> Just (f k v)) ++hashMapMapKeys      :: (Eq k, Hashable k) => (t -> k) -> M.HashMap t v -> M.HashMap k v+hashMapMapKeys f    = M.fromList . fmap (mapFst f) . M.toList +++applyNonNull def _ [] = def+applyNonNull _   f xs = f xs++concatMapM f = fmap concat . mapM f ++++angleBrackets p    = char '<' <> p <> char '>'+dot                = char '.'+arrow              = text "->"+dcolon             = colon <> colon+intersperse d ds   = hsep $ punctuate d ds++tshow              = text . show++foldlMap           :: (a -> b -> (c, a)) -> a -> [b] -> ([c], a)+foldlMap f b xs    = (reverse zs, res)+  where +    (zs, res)      = L.foldl' ff ([], b) xs+    ff (ys, acc) x = let (y, acc') = f acc x in (y:ys, acc')++
+ src/Language/Fixpoint/Names.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE ScopedTypeVariables #-}++-- | This module contains Haskell variables representing globally visible names.+--   Rather than have strings floating around the system, all constant names+--   should be defined here, and the (exported) variables should be used and+--   manipulated elsewhere.++module Language.Fixpoint.Names (+  +  -- * Hardwired global names +    dummyName+  , preludeName+  , boolConName+  , funConName+  , listConName+  , tupConName+  , propConName+  , strConName+  , vvName+  , symSepName+  , dropModuleNames +  , takeModuleNames+) where++import Data.List                (intercalate)+import Language.Fixpoint.Misc   (errorstar, safeLast, stripParens)++----------------------------------------------------------------------------+--------------- Global Name Definitions ------------------------------------+----------------------------------------------------------------------------++preludeName  = "Prelude"+dummyName    = "_LIQUID_dummy"+boolConName  = "Bool"+funConName   = "->"+listConName  = "[]" -- "List"+tupConName   = "()" -- "Tuple"+propConName  = "Prop"+strConName   = "Str"+vvName       = "VV"+symSepName   = '#'++-- dropModuleNames []  = []+-- dropModuleNames s  +--   | s == tupConName = tupConName +--   | otherwise       = safeLast msg $ words $ dotWhite `fmap` stripParens s+--   where +--     msg             = "dropModuleNames: " ++ s +--     dotWhite '.'    = ' '+--     dotWhite c      = c++dropModuleNames          = mungeModuleNames safeLast "dropModuleNames: "+takeModuleNames          = mungeModuleNames safeInit "takeModuleNames: "++safeInit _ xs@(_:_)      = intercalate "." $ init xs+safeInit msg _           = errorstar $ "safeInit with empty list " ++ msg++mungeModuleNames _ _ []  = []+mungeModuleNames f msg s  +  | s == tupConName      = tupConName +  | otherwise            = f (msg ++ s) $ words $ dotWhite `fmap` stripParens s+  where +    dotWhite '.'         = ' '+    dotWhite c           = c+
+ src/Language/Fixpoint/Parse.hs view
@@ -0,0 +1,484 @@+{-# LANGUAGE NoMonomorphismRestriction, FlexibleInstances, UndecidableInstances, TypeSynonymInstances, TupleSections #-}++module Language.Fixpoint.Parse (+  +  -- * Top Level Class for Parseable Values  +    Inputable (..)+  +  -- * Top Level Class for Parseable Values  +  , Parser++  -- * Lexer to add new tokens+  , lexer ++  -- * Some Important keyword and parsers+  , reserved, reservedOp+  , parens  , brackets+  , semi    , comma     +  , colon   , dcolon +  , whiteSpace, blanks++  -- * Parsing basic entities+  , fTyConP     -- Type constructors+  , lowerIdP    -- Lower-case identifiers+  , upperIdP    -- Upper-case identifiers+  , symbolP     -- Arbitrary Symbols+  , constantP   -- (Integer) Constants+  , integer     -- Integer++  -- * Parsing recursive entities+  , exprP       -- Expressions+  , predP       -- Refinement Predicates+  , qualifierP  -- Qualifiers++  -- * Some Combinators+  , condIdP     -- condIdP  :: [Char] -> (String -> Bool) -> Parser String++  -- * Getting a Fresh Integer while parsing+  , freshIntP++  -- * Parsing Function+  , doParse' +  , parseFromFile+  , remainderP +  ) where++import Control.Applicative ((<*>), (<$>), (<*))+import Control.Monad+import Text.Parsec+import Text.Parsec.Expr+import Text.Parsec.Language+import Text.Parsec.String hiding (Parser, parseFromFile)+import Text.Printf  (printf)+import qualified Text.Parsec.Token as Token+import qualified Data.HashMap.Strict as M++import Data.Char (isLower, toUpper)+import Language.Fixpoint.Misc hiding (dcolon)+import Language.Fixpoint.Types+import Data.Maybe(maybe)++type Parser = Parsec String Integer ++--------------------------------------------------------------------++languageDef =+  emptyDef { Token.commentStart    = "/* "+           , Token.commentEnd      = " */"+           , Token.commentLine     = "--"+           , Token.identStart      = satisfy (\_ -> False) +           , Token.identLetter     = satisfy (\_ -> False)+           , Token.reservedNames   = [ "SAT"+                                     , "UNSAT"+                                     , "true"+                                     , "false"+                                     , "mod"+                                     , "data"+                                     , "Bexp"+                                     , "forall"+                                     , "exists"+                                     , "assume"+                                     , "measure"+                                     , "module"+                                     , "spec"+                                     , "where"+                                     , "True"+                                     , "Int"+                                     , "import"+                                     , "_|_"+                                     , "|"+                                     , "if", "then", "else"+                                     ]+           , Token.reservedOpNames = [ "+", "-", "*", "/", "\\"+                                     , "<", ">", "<=", ">=", "=", "!=" , "/="+                                     , "mod", "and", "or" +                                  --, "is"+                                     , "&&", "||"+                                     , "~", "=>", "<=>"+                                     , "->"+                                     , ":="+                                     , "&", "^", "<<", ">>", "--"+                                     , "?", "Bexp" -- , "'"+                                     ]+           }++lexer         = Token.makeTokenParser languageDef+reserved      = Token.reserved      lexer+reservedOp    = Token.reservedOp    lexer+parens        = Token.parens        lexer+brackets      = Token.brackets      lexer+semi          = Token.semi          lexer+colon         = Token.colon         lexer+comma         = Token.comma         lexer+whiteSpace    = Token.whiteSpace    lexer+stringLiteral = Token.stringLiteral lexer++-- identifier = Token.identifier lexer+++blanks  = many (satisfy (`elem` [' ', '\t']))++integer =   try (liftM toInt is) +       <|>  liftM (negate . toInt) (char '-' >> is)+  where is      = liftM2 (\is _ -> is) (many1 digit) blanks +        toInt s = (read s) :: Integer ++----------------------------------------------------------------+------------------------- Expressions --------------------------+----------------------------------------------------------------++condIdP  :: [Char] -> (String -> Bool) -> Parser String+condIdP chars f +  = do c  <- letter+       cs <- many (satisfy (`elem` chars))+       blanks+       if f (c:cs) then return (c:cs) else parserZero++upperIdP :: Parser String+upperIdP = condIdP symChars (not . isLower . head)++lowerIdP :: Parser String+lowerIdP = condIdP symChars (isLower . head)++symbolP :: Parser Symbol+symbolP = liftM stringSymbol symCharsP ++constantP :: Parser Constant+constantP = liftM I integer++symconstP :: Parser SymConst+symconstP = SL <$> stringLiteral ++exprP :: Parser Expr +exprP =  expr2P <|> lexprP++lexprP :: Parser Expr +lexprP   +  =  try (parens exprP)+ <|> try (parens exprCastP)+ <|> try (parens $ condP EIte exprP)+ <|> try exprFunP+ <|> try (liftM (EVar . stringSymbol) upperIdP)+ <|> liftM expr symbolP + <|> liftM ECon constantP+ <|> liftM ESym symconstP+ <|> (reserved "_|_" >> return EBot)++exprFunP           =  (try exprFunSpacesP) <|> (try exprFunSemisP) <|> exprFunCommasP+  where +    exprFunSpacesP = parens $ liftM2 EApp funSymbolP (sepBy exprP spaces) +    exprFunCommasP = liftM2 EApp funSymbolP (parens        $ sepBy exprP comma)+    exprFunSemisP  = liftM2 EApp funSymbolP (parenBrackets $ sepBy exprP semi)+    funSymbolP     = symbolP -- liftM stringSymbol lowerIdP+++parenBrackets  = parens . brackets ++expr2P = buildExpressionParser bops lexprP++bops = [ [Infix  (reservedOp "*"   >> return (EBin Times)) AssocLeft]+       , [Infix  (reservedOp "/"   >> return (EBin Div  )) AssocLeft]+       , [Infix  (reservedOp "+"   >> return (EBin Plus )) AssocLeft]+       , [Infix  (reservedOp "-"   >> return (EBin Minus)) AssocLeft]+       , [Infix  (reservedOp "mod" >> return (EBin Mod  )) AssocLeft]+       ]+++exprCastP+  = do e  <- exprP +       ((try dcolon) <|> colon)+       so <- sortP+       return $ ECst e so++dcolon = string "::" <* spaces++sortP+  =   try (string "Integer" >>  return FInt)+  <|> try (string "Int"     >>  return FInt)+  <|> try (string "int"     >>  return FInt)+  <|> try (FObj . stringSymbol <$> lowerIdP)+  <|> (FApp <$> fTyConP <*> many sortP     )++symCharsP  = (condIdP symChars (\_ -> True))++---------------------------------------------------------------------+-------------------------- Predicates -------------------------------+---------------------------------------------------------------------++predP :: Parser Pred+predP =  try (parens pred2P)+     <|> try (parens $ condP pIte predP)+     <|> try (reservedOp "not" >> liftM PNot predP)+     <|> try (reservedOp "&&" >> liftM PAnd predsP)+     <|> try (reservedOp "||" >> liftM POr  predsP)+     <|> (qmP >> liftM PBexp exprP)+     <|> (reserved "true"  >> return PTrue)+     <|> (reserved "false" >> return PFalse)+     <|> (try predrP)+     <|> (try (liftM PBexp exprFunP))++qmP    = reserved "?" <|> reserved "Bexp"++pred2P = buildExpressionParser lops predP ++predsP = brackets $ sepBy predP semi++lops = [ [Prefix (reservedOp "~"   >> return PNot)]+       , [Infix  (reservedOp "&&"  >> return (\x y -> PAnd [x,y])) AssocRight]+       , [Infix  (reservedOp "||"  >> return (\x y -> POr  [x,y])) AssocRight]+       , [Infix  (reservedOp "=>"  >> return PImp) AssocRight]+       , [Infix  (reservedOp "<=>" >> return PIff) AssocRight]]+       +predrP = do e1    <- expr2P+            r     <- brelP+            e2    <- expr2P +            return $ r e1 e2++brelP ::  Parser (Expr -> Expr -> Pred)+brelP =  (reservedOp "==" >> return (PAtom Eq))+     <|> (reservedOp "="  >> return (PAtom Eq))+     <|> (reservedOp "!=" >> return (PAtom Ne))+     <|> (reservedOp "/=" >> return (PAtom Ne))+     <|> (reservedOp "<"  >> return (PAtom Lt))+     <|> (reservedOp "<=" >> return (PAtom Le))+     <|> (reservedOp ">"  >> return (PAtom Gt))+     <|> (reservedOp ">=" >> return (PAtom Ge))++condIteP f bodyP +  = do reserved "if" +       p <- predP+       reserved "then"+       b1 <- bodyP +       reserved "else"+       b2 <- bodyP +       return $ f p b1 b2++condQmP f bodyP +  = do p  <- predP +       reserved "?"+       b1 <- bodyP +       colon+       b2 <- bodyP +       return $ f p b1 b2++condP f bodyP +   =   try (condIteP f bodyP)+   <|> (condQmP f bodyP)++----------------------------------------------------------------------------------+------------------------------------ BareTypes -----------------------------------+----------------------------------------------------------------------------------++fTyConP+  =   (reserved "int"  >> return intFTyCon)+  <|> (reserved "bool" >> return boolFTyCon)+  <|> (stringFTycon   <$> upperIdP)++refasP :: Parser [Refa]+refasP  =  (try (brackets $ sepBy (RConc <$> predP) semi)) +       <|> liftM ((:[]) . RConc) predP++---------------------------------------------------------------------+-- | Parsing Qualifiers ---------------------------------------------+---------------------------------------------------------------------++-- qualifierP = mkQual <$> upperIdP <*> parens $ sepBy1 sortBindP comma <*> predP++qualifierP = do n      <- upperIdP +                params <- parens $ sepBy1 sortBindP comma+                _      <- colon+                body   <- predP+                return  $ mkQual n params body++sortBindP  = (,) <$> symbolP <* colon <*> sortP++mkQual n xts p = Q n ((vv, t) : yts) (subst su p)+  where +    (vv,t):zts = xts+    yts        = mapFst mkParam <$> zts+    su         = mkSubst $ zipWith (\(z,_) (y,_) -> (z, eVar y)) zts yts +                       +mkParam s      = stringSymbolRaw ('~' : toUpper c : cs) +  where +    (c:cs)     = symbolString s +++---------------------------------------------------------------------+------------ Interacting with Fixpoint ------------------------------+---------------------------------------------------------------------++fixResultP :: Parser a -> Parser (FixResult a)+fixResultP pp +  =  (reserved "SAT"   >> return Safe)+ <|> (reserved "UNSAT" >> Unsafe <$> (brackets $ sepBy pp comma))  + <|> (reserved "CRASH" >> crashP pp)++++crashP pp+  = do i   <- pp+       msg <- many anyChar+       return $ Crash [i] msg++predSolP +  = parens $ (predP  <* (comma >> iQualP)) +    ++iQualP+  = upperIdP >> (parens $ sepBy symbolP comma)++solution1P+  = do reserved "solution:" +       k  <- symbolP +       reserved ":=" +       ps <- brackets $ sepBy predSolP semi+       return (k, simplify $ PAnd ps)++solutionP :: Parser (M.HashMap Symbol Pred)+solutionP +  = M.fromList <$> sepBy solution1P whiteSpace++solutionFileP +  = liftM2 (,) (fixResultP integer) solutionP++------------------------------------------------------------------------++remainderP p  +  = do res <- p+       str <- stateInput <$> getParserState+       return (res, str) ++doParse' parser f s+  = case runParser (remainderP p) 0 f s of+      Left e         -> errorstar $ printf "parseError %s\n when parsing from %s\n" +                                      (show e) f +      Right (r, "")  -> r+      Right (_, rem) -> errorstar $ printf "doParse has leftover when parsing: %s\nfrom file %s\n"+                                      rem f+  where p = whiteSpace >> parser+++parseFromFile :: Parser b -> SourceName -> IO b+parseFromFile p f = doParse' p f <$> readFile f++freshIntP :: Parser Integer+freshIntP = do n <- stateUser <$> getParserState+               updateState (+ 1)+               return n++----------------------------------------------------------------------------------------+------------------------ Bundling Parsers into a Typeclass -----------------------------+----------------------------------------------------------------------------------------++class Inputable a where+  rr  :: String -> a+  rr' :: String -> String -> a+  rr' = \_ -> rr+  rr  = rr' "" ++instance Inputable Symbol where+  rr' = doParse' symbolP++instance Inputable Constant where+  rr' = doParse' constantP ++instance Inputable Pred where+  rr' = doParse' predP ++instance Inputable Expr where+  rr' = doParse' exprP ++instance Inputable [Refa] where+  rr' = doParse' refasP++instance Inputable (FixResult Integer) where+  rr' = doParse' $ fixResultP integer++instance Inputable (FixResult Integer, FixSolution) where+  rr' = doParse' solutionFileP ++{-+---------------------------------------------------------------+--------------------------- Testing ---------------------------+---------------------------------------------------------------++sa  = "0"+sb  = "x"+sc  = "(x0 + y0 + z0) "+sd  = "(x+ y * 1)"+se  = "_|_ "+sf  = "(1 + x + _|_)"+sg  = "f(x,y,z)"+sh  = "(f((x+1), (y * a * b - 1), _|_))"+si  = "(2 + f((x+1), (y * a * b - 1), _|_))"++s0  = "true"+s1  = "false"+s2  = "v > 0"+s3  = "(0 < v && v < 100)"+s4  = "(x < v && v < y+10 && v < z)"+s6  = "[(v > 0)]"+s6' = "x"+s7' = "(x <=> y)"+s8' = "(x <=> a = b)"+s9' = "(x <=> (a <= b && b < c))"++s7  = "{ v: Int | [(v > 0)] }"+s8  = "x:{ v: Int | v > 0 } -> {v : Int | v >= x}"+s9  = "v = x+y"+s10 = "{v: Int | v = x + y}"++s11 = "x:{v:Int | true } -> {v:Int | true }" +s12 = "y : {v:Int | true } -> {v:Int | v = x }"+s13 = "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"+s14 = "x:{v:a  | true} -> y:{v:b | true } -> {v:a | (x < v && v < y) }"+s15 = "x:Int -> Bool"+s16 = "x:Int -> y:Int -> {v:Int | v = x + y}"+s17 = "a"+s18 = "x:a -> Bool"+s20 = "forall a . x:Int -> Bool"++s21 = "x:{v : GHC.Prim.Int# | true } -> {v : Int | true }" ++r0  = (rr s0) :: Pred+r0' = (rr s0) :: [Refa]+r1  = (rr s1) :: [Refa]+++e1, e2  :: Expr  +e1  = rr "(k_1 + k_2)"+e2  = rr "k_1" ++o1, o2, o3 :: FixResult Integer+o1  = rr "SAT " +o2  = rr "UNSAT [1, 2, 9,10]"+o3  = rr "UNSAT []" ++-- sol1 = doParse solution1P "solution: k_5 := [0 <= VV_int]"+-- sol2 = doParse solution1P "solution: k_4 := [(0 <= VV_int)]" ++b0, b1, b2, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13 :: BareType+b0  = rr "Int"+b1  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"+b2  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x - y}"+b4  = rr "forall a . x : a -> Bool"+b5  = rr "Int -> Int -> Int"+b6  = rr "(Int -> Int) -> Int"+b7  = rr "({v: Int | v > 10} -> Int) -> Int"+b8  = rr "(x:Int -> {v: Int | v > x}) -> {v: Int | v > 10}"+b9  = rr "x:Int -> {v: Int | v > x} -> {v: Int | v > 10}"+b10 = rr "[Int]"+b11 = rr "x:[Int] -> {v: Int | v > 10}"+b12 = rr "[Int] -> String"+b13 = rr "x:(Int, [Bool]) -> [(String, String)]"++-- b3 :: BareType+-- b3  = rr "x:Int -> y:Int -> {v:Bool | ((v is True) <=> x = y)}"++m1 = ["len :: [a] -> Int", "len (Nil) = 0", "len (Cons x xs) = 1 + len(xs)"]+m2 = ["tog :: LL a -> Int", "tog (Nil) = 100", "tog (Cons y ys) = 200"]++me1, me2 :: Measure.Measure BareType Symbol +me1 = (rr $ intercalate "\n" m1) +me2 = (rr $ intercalate "\n" m2)+-}
+ src/Language/Fixpoint/PrettyPrint.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE FlexibleContexts           #-} +{-# LANGUAGE FlexibleInstances          #-}+++module Language.Fixpoint.PrettyPrint where++import Text.PrettyPrint.HughesPJ+import Language.Fixpoint.Types+import Language.Fixpoint.Misc+import Control.Applicative      ((<$>))+import Text.Parsec++class PPrint a where+  pprint :: a -> Doc++showpp :: (PPrint a) => a -> String +showpp = render . pprint ++instance PPrint a => PPrint (Maybe a) where+  pprint = maybe (text "Nothing") ((text "Just" <+>) . pprint)++instance PPrint a => PPrint [a] where+  pprint = brackets . intersperse comma . map pprint++instance (PPrint a, PPrint b, PPrint c) => PPrint (a, b, c) where+  pprint (x, y, z)  = parens $ (pprint x) <> text "," <> (pprint y) <> text "," <> (pprint z) +++instance (PPrint a, PPrint b) => PPrint (a,b) where+  pprint (x, y)  = (pprint x) <+> text ":" <+> (pprint y)++instance PPrint SourcePos where+  pprint = text . show ++instance PPrint () where+  pprint = text . show ++instance PPrint String where +  pprint = text ++instance PPrint Int where+  pprint = toFix++instance PPrint Integer where+  pprint = toFix++instance PPrint Constant where+  pprint = toFix++instance PPrint Brel where+  pprint Eq = text "=="+  pprint Ne = text "/="+  pprint r  = toFix r++instance PPrint Bop where+  pprint  = toFix ++instance PPrint Sort where+  pprint = toFix  ++instance PPrint Symbol where+  pprint = toFix++instance PPrint SymConst where+  pprint (SL x)          = doubleQuotes $ text x++instance PPrint Expr where+  pprint (EApp f es)     = parens $ intersperse empty $ (pprint f) : (pprint <$> es) +  pprint (ESym c)        = pprint c +  pprint (ECon c)        = pprint c +  pprint (EVar s)        = pprint s+  pprint (ELit s _)      = pprint s+  pprint (EBin o e1 e2)  = parens $ pprint e1 <+> pprint o <+> pprint e2+  pprint (EIte p e1 e2)  = parens $ text "if" <+> pprint p <+> text "then" <+> pprint e1 <+> text "else" <+> pprint e2 +  pprint (ECst e so)     = parens $ pprint e <+> text " : " <+> pprint so +  pprint (EBot)          = text "_|_"++instance PPrint Pred where+  pprint PTop            = text "???"+  pprint PTrue           = trueD +  pprint PFalse          = falseD+  pprint (PBexp e)       = parens $ pprint e+  pprint (PNot p)        = parens $ text "not" <+> parens (pprint p)+  pprint (PImp p1 p2)    = parens $ (pprint p1) <+> text "=>"  <+> (pprint p2)+  pprint (PIff p1 p2)    = parens $ (pprint p1) <+> text "<=>" <+> (pprint p2)+  pprint (PAnd ps)       = parens $ pprintBin trueD  andD ps+  pprint (POr  ps)       = parens $ pprintBin falseD orD  ps +  pprint (PAtom r e1 e2) = parens $ pprint e1 <+> pprint r <+> pprint e2+  pprint (PAll xts p)    = text "forall" <+> toFix xts <+> text "." <+> pprint p++trueD  = text "true"+falseD = text "false"+andD   = text " &&"+orD    = text " ||"++pprintBin b _ [] = b+pprintBin _ o xs = intersperse o $ pprint <$> xs ++pprintBin b o []     = b+pprintBin b o [x]    = pprint x+pprintBin b o (x:xs) = pprint x <+> o <+> pprintBin b o xs ++instance PPrint Refa where+  pprint (RConc p)     = pprint p+  pprint k             = toFix k+ +instance PPrint Reft where +  pprint r@(Reft (_,ras)) +    | isTauto r        = text "true"+    | otherwise        = {- intersperse comma -} pprintBin trueD andD $ flattenRefas ras++ ++instance PPrint SortedReft where+  pprint (RR so (Reft (v, ras))) +    = braces +    $ (pprint v) <+> (text ":") <+> (toFix so) <+> (text "|") <+> pprint ras+++++++++
+ src/Language/Fixpoint/Sort.hs view
@@ -0,0 +1,323 @@++-- | This module has the functions that perform sort-checking, and related+-- operations on Fixpoint expressions and predicates.++module Language.Fixpoint.Sort  ( +  -- * Checking Well-Formedness+    checkSorted+  , checkSortedReft+  , checkSortedReftFull+  , pruneUnsortedReft+  ) where++++import Language.Fixpoint.Types+import Language.Fixpoint.Misc+import Text.PrettyPrint.HughesPJ+import Text.Printf+import Control.Monad.Error (catchError, throwError)+import Control.Monad+import Control.Applicative+import Data.Maybe           (fromMaybe, catMaybes)+import qualified Data.HashMap.Strict as M++import Debug.Trace          (trace)++-- | Types used throughout checker++type CheckM a = Either String a+type Env      = Symbol -> SESearch Sort+fProp         = FApp boolFTyCon [] +-- fProp         = FApp propFTyCon [] ++-------------------------------------------------------------------------+-- | Checking Refinements -----------------------------------------------+-------------------------------------------------------------------------++checkSortedReft :: SEnv SortedReft -> [Symbol] -> SortedReft -> Maybe Doc+checkSortedReft env xs sr = applyNonNull Nothing error unknowns +  where +    error                 = Just . (text "Unknown symbols:" <+>) . toFix +    unknowns              = [ x | x <- syms sr, not (x `elem` v : xs), not (x `memberSEnv` env)]    +    Reft (v,_)            = sr_reft sr ++checkSortedReftFull :: Checkable a => SEnv SortedReft -> a -> Maybe Doc+checkSortedReftFull γ t+  = case check γ' t of+      Left err -> Just (text err)+      Right _  -> Nothing+    where +      γ' = mapSEnv sr_sort γ  ++checkSorted :: Checkable a => SEnv Sort -> a -> Maybe Doc+checkSorted γ t+  = case check γ t of+      Left err -> Just (text err)+      Right _  -> Nothing++pruneUnsortedReft :: SEnv Sort -> SortedReft -> SortedReft+pruneUnsortedReft γ (RR s (Reft (v, ras)))+  = RR s (Reft (v, catMaybes (go <$> ras))) +  where +    go r = case checkRefa f r of+            Left war -> trace (wmsg war r) $ Nothing+            Right _  -> Just r+    γ' = insertSEnv v s γ+    f  = (`lookupSEnvWithDistance` γ')++    wmsg t r = "WARNING: prune unsorted reft:\n" ++ showFix r ++ "\n" ++ t++checkRefa f (RConc p) = checkPred f p+checkRefa f _         = return ()+++class Checkable a where+  check :: SEnv Sort -> a -> CheckM ()++instance Checkable Refa where+  check γ = checkRefa (`lookupSEnvWithDistance` γ)++instance Checkable Expr where+  check γ e = do {checkExpr f e; return ()}+   where f =  (`lookupSEnvWithDistance` γ)++instance Checkable Pred where+  check γ = checkPred f+   where f = (`lookupSEnvWithDistance` γ)++instance Checkable SortedReft where+  check γ (RR s (Reft (v, ras))) = mapM_ (check γ') ras+   where γ' = insertSEnv v s γ  ++-------------------------------------------------------------------------+-- | Checking Expressions -----------------------------------------------+-------------------------------------------------------------------------++checkExpr                  :: Env -> Expr -> CheckM Sort ++checkExpr _ EBot           = throwError "Type Error: Bot"+checkExpr _ (ECon _)       = return FInt +checkExpr f (EVar x)       = checkSym f x+checkExpr f (EBin o e1 e2) = checkOp f e1 o e2+checkExpr f (EIte p e1 e2) = checkIte f p e1 e2+checkExpr f (ECst e t)     = checkCst f t e+checkExpr f (EApp g es)    = checkApp f Nothing g es+checkExpr f (ELit _ t)     = return t++-- | Helper for checking symbol occurrences++checkSym f x               +  = case f x of +     Found s -> return s+     Alts xs -> throwError $ errUnboundAlts x xs+--   $ traceFix ("checkSym: x = " ++ showFix x) (f x)++-- | Helper for checking if-then-else expressions++checkIte f p e1 e2 +  = do tp <- checkPred f p+       t1 <- checkExpr f e1+       t2 <- checkExpr f e2+       if t1 == t2 +         then return t1+         else throwError (errIte e1 e2 t1 t2) ++-- | Helper for checking cast expressions ++checkCst f t (EApp g es) +  = checkApp f (Just t) g es+checkCst f t e           +  = do t' <- checkExpr f e+       if t == t' +         then return t+         else throwError (errCast e t' t)++-- | Helper for checking uninterpreted function applications++checkApp' f to g es +  = do gt           <- checkSym f g+       (n, its, ot) <- sortFunction gt+       unless (length its == length es) $ throwError (errArgArity g its es)+       ets          <- mapM (checkExpr f) es+       θ            <- unify its ets+       let t         = apply θ ot+       case to of+         Nothing    -> return (θ, t)+         Just t'    -> do θ' <- unifyMany θ [t] [t']+                          return (θ', apply θ' t)+++checkApp f to g es+  = snd <$> checkApp' f to g es+++-- | Helper for checking binary (numeric) operations++checkOp f e1 o e2 +  = do t1 <- checkExpr f e1+       t2 <- checkExpr f e2+       checkOpTy f (EBin o e1 e2) t1 t2++checkOpTy f _ FInt FInt          +  = return FInt++checkOpTy f e t@(FObj l) t'@(FObj l')+  | l == l'+  = checkNumeric f l >> return t++checkOpTy f e t t'+  = throwError $ errOp e t t'++checkNumeric f l+  = do t <- checkSym f l+       unless (t == FNum) (throwError $ errNonNumeric l)+       return ()++-------------------------------------------------------------------------+-- | Checking Predicates ------------------------------------------------+-------------------------------------------------------------------------++checkPred                  :: Env -> Pred -> CheckM () ++checkPred f PTrue          = return ()+checkPred f PFalse         = return ()+checkPred f (PBexp e)      = checkPredBExp f e +checkPred f (PNot p)       = checkPred f p+checkPred f (PImp p p')    = mapM_ (checkPred f) [p, p'] +checkPred f (PIff p p')    = mapM_ (checkPred f) [p, p']+checkPred f (PAnd ps)      = mapM_ (checkPred f) ps+checkPred f (POr ps)       = mapM_ (checkPred f) ps+checkPred f (PAtom r e e') = checkRel f r e e'+checkPred f p              = throwError $ errUnexpectedPred p++checkPredBExp f e          = do t <- checkExpr f e+                                unless (t == fProp) (throwError $ errBExp e t)+                                return ()+  ++-- | Checking Relations++checkRel f Eq (EVar x) (EApp g es) = checkRelEqVar f x g es+checkRel f Eq (EApp g es) (EVar x) = checkRelEqVar f x g es+checkRel f r  e1 e2                = do t1 <- checkExpr f e1+                                        t2 <- checkExpr f e2+                                        checkRelTy f (PAtom r e1 e2) r t1 t2++checkRelTy :: (Fixpoint a) => Env -> a -> Brel -> Sort -> Sort -> CheckM ()+checkRelTy f _ _ (FObj l) (FObj l') | l /= l' +  = (checkNumeric f l >> checkNumeric f l') `catchError` (\_ -> throwError $ errNonNumerics l l') +checkRelTy f _ _ FInt (FObj l)     = (checkNumeric f l) `catchError` (\_ -> throwError $ errNonNumeric l) +checkRelTy f _ _ (FObj l) FInt     = (checkNumeric f l) `catchError` (\_ -> throwError $ errNonNumeric l)+checkRelTy _ e Eq t1 t2            = unless (t1 == t2 && t1 /= fProp) (throwError $ errRel e t1 t2)+checkRelTy _ e Ne t1 t2            = unless (t1 == t2 && t1 /= fProp) (throwError $ errRel e t1 t2)+checkRelTy _ e _  t1 t2            = unless (t1 == t2)                (throwError $ errRel e t1 t2)+++-- | Special case for polymorphic singleton variable equality e.g. (x = Set_emp) ++checkRelEqVar f x g es             = do tx <- checkSym f x+                                        _  <- checkApp f (Just tx) g es+                                        return ()+++++-------------------------------------------------------------------------+-- | Error messages -----------------------------------------------------+-------------------------------------------------------------------------++errUnify t1 t2       = printf "Cannot unify %s with %s" (showFix t1) (showFix t2)++errUnifyMany ts ts'  = printf "Cannot unify types with different cardinalities %s and %s" +                         (showFix ts) (showFix ts')++errRel e t1 t2       = printf "Invalid Relation %s with operand types %s and %s" +                         (showFix e) (showFix t1) (showFix t2)++errBExp e t          = printf "BExp %s with non-propositional type %s" (showFix e) (showFix t)++errOp e t t' +  | t == t'          = printf "Operands have non-numeric types %s in %s"  +                         (showFix t) (showFix e)+  | otherwise        = printf "Operands have different types %s and %s in %s" +                         (showFix t) (showFix t') (showFix e)++errArgArity g its es = printf "Measure %s expects %d args but gets %d in %s" +                         (showFix g) (length its) (length es) (showFix (EApp g es))++errIte e1 e2 t1 t2   = printf "Mismatched branches in Ite: then %s : %s, else %s : %s" +                         (showFix e1) (showFix t1) (showFix e2) (showFix t2) ++errCast e t' t       = printf "Cannot cast %s of sort %s to incompatible sort %s" +                         (showFix e) (showFix t') (showFix t)++errUnbound x         = printf "Unbound Symbol %s" (showFix x)+errUnboundAlts x xs  = printf "Unbound Symbol %s\n Perhaps you meant: %s" +                        (showFix x) +                        (foldr1 (\w s -> w ++ ", " ++ s) (showFix <$> xs))++errNonFunction t     = printf "Sort %s is not a function" (showFix t)++errNonNumeric  l     = printf "FObj sort %s is not numeric" (showFix l)+errNonNumerics l l'   = printf "FObj sort %s and %s are different and not numeric" (showFix l) (showFix l')++errUnexpectedPred p  = printf "Sort Checking: Unexpected Predicate %s" (showFix p)++-------------------------------------------------------------------------+-- | Utilities for working with sorts -----------------------------------+-------------------------------------------------------------------------++-- | Unification of Sorts++unify                              = unifyMany (Th M.empty)++unifyMany θ ts ts' +  | length ts == length ts'        = foldM (uncurry . unify1) θ $ zip ts ts'+  | otherwise                      = throwError $ errUnifyMany ts ts'++-- unify1 _ FNum _                    = Nothing+unify1 θ (FVar i) t                = unifyVar θ i t+unify1 θ t (FVar i)                = unifyVar θ i t+unify1 θ (FApp c ts) (FApp c' ts')  +  | c == c'                        = unifyMany θ ts ts' +unify1 θ t1 t2  +  | t1 == t2                       = return θ+  | otherwise                      = throwError $ errUnify t1 t2++unifyVar θ i t +  = case lookupVar i θ of+      Just t' -> if t == t' then return θ else throwError (errUnify t t') +      Nothing -> return $ updateVar i t θ ++-- | Sort Substitutions+newtype TVSubst      = Th (M.HashMap Int Sort) ++-- | API for manipulating substitutions+lookupVar i (Th m)   = M.lookup i m+updateVar i t (Th m) = Th (M.insert i t m)++-------------------------------------------------------------------------+-- | Applying a Type Substitution ---------------------------------------+-------------------------------------------------------------------------++apply θ          = sortMap f+  where+    f t@(FVar i) = fromMaybe t (lookupVar i θ)+    f t          = t++sortMap f (FFunc n ts) = FFunc n (sortMap f <$> ts)+sortMap f (FApp  c ts) = FApp  c (sortMap f <$> ts)+sortMap f t            = f t++------------------------------------------------------------------------+-- | Deconstruct a function-sort ---------------------------------------+------------------------------------------------------------------------++sortFunction (FFunc n ts') = return (n, ts, t) +  where +    ts                     = take numArgs ts'+    t                      = last ts'+    numArgs                = length ts' - 1++sortFunction t             = throwError $ errNonFunction t 
+ src/Language/Fixpoint/Types.hs view
@@ -0,0 +1,1439 @@+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE DeriveGeneric             #-}+{-# LANGUAGE DeriveDataTypeable        #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE UndecidableInstances      #-}++-- | This module contains the data types, operations and serialization functions +-- for representing Fixpoint's implication (i.e. subtyping) and well-formedness +-- constraints in Haskell. The actual constraint solving is done by the+-- `fixpoint.native` which is written in Ocaml.++module Language.Fixpoint.Types (++  -- * Top level serialization  +    Fixpoint (..)+  , toFixpoint+  , FInfo (..)++  -- * Rendering+  , showFix+  , traceFix+  , resultDoc ++  -- * Embedding to Fixpoint Types+  , Sort (..), FTycon, TCEmb+  , intFTyCon, boolFTyCon, strFTyCon, propFTyCon+  , stringFTycon, fTyconString++  -- * Symbols+  , Symbol(..)+  , anfPrefix, tempPrefix, vv, intKvar+  , symChars, isNonSymbol, nonSymbol+  , isNontrivialVV+  , stringSymbol, symbolString+  +  -- * Creating Symbols+  , dummySymbol, intSymbol, tempSymbol+  , qualifySymbol, stringSymbolRaw+  , suffixSymbol++  -- * Expressions and Predicates+  , SymConst (..), Constant (..)+  , Bop (..), Brel (..)+  , Expr (..), Pred (..)+  , eVar+  , eProp+  , pAnd, pOr, pIte+  , isTautoPred++  -- * Generalizing Embedding with Typeclasses +  , Symbolic (..)+  , Expression (..)+  , Predicate (..)++  -- * Constraints and Solutions+  , SubC, WfC, subC, lhsCs, rhsCs, wfC, Tag, FixResult (..), FixSolution, addIds, sinfo +  , trueSubCKvar+  , removeLhsKvars++  -- * Environments+  , SEnv, SESearch(..)+  , emptySEnv, toListSEnv, fromListSEnv+  , mapSEnv+  , insertSEnv, deleteSEnv, memberSEnv, lookupSEnv+  , intersectWithSEnv+  , filterSEnv+  , lookupSEnvWithDistance++  , FEnv, insertFEnv +  , IBindEnv, BindId, insertsIBindEnv, deleteIBindEnv, emptyIBindEnv+  , BindEnv, insertBindEnv, emptyBindEnv++  -- * Refinements+  , Refa (..), SortedReft (..), Reft(..), Reftable(..) + +  -- * Constructing Refinements+  , trueSortedReft          -- trivial reft+  , trueRefa                -- trivial reft+  , exprReft                -- singleton: v == e+  , notExprReft             -- singleton: v /= e+  , symbolReft              -- singleton: v == x+  , propReft                -- singleton: Prop(v) <=> p+  , predReft                -- any pred : p+  , isFunctionSortedReft+  , isNonTrivialSortedReft+  , isTautoReft+  , isSingletonReft+  , isEVar+  , isFalse+  , flattenRefas, squishRefas+  , shiftVV++  -- * Substitutions +  , Subst, Subable (..)+  , emptySubst, mkSubst, catSubst+  , substExcept, substfExcept, subst1Except+  , sortSubst++  -- * Visitors+  , reftKVars++  -- * Functions on @Result@+  , colorResult ++  -- * Cut KVars+  , Kuts (..), ksEmpty, ksUnion++  -- * Qualifiers+  , Qualifier (..)++ ) where++import GHC.Generics         (Generic)+import Debug.Trace          (trace)++import Data.Typeable        (Typeable)+import Data.Generics        (Data)+import Data.Monoid hiding   ((<>))+import Data.Functor+import Data.Char            (ord, chr, isAlpha, isUpper, toLower)+import Data.List            (sort, stripPrefix)+import Data.Hashable        ++import Data.Maybe           (fromMaybe)+import Text.Printf          (printf)+import Control.DeepSeq+import Control.Arrow        ((***))++import Language.Fixpoint.Misc+import Text.PrettyPrint.HughesPJ++import qualified Data.HashMap.Strict as M+import qualified Data.HashSet        as S+import Data.Array            hiding (indices)+import Language.Fixpoint.Names++class Fixpoint a where+  toFix    :: a -> Doc++  simplify :: a -> a +  simplify =  id+++------------------------------------------------------------------------++showFix :: (Fixpoint a) => a -> String+showFix =  render . toFix++traceFix     ::  (Fixpoint a) => String -> a -> a+traceFix s x = trace ("\nTrace: [" ++ s ++ "] : " ++ showFix x) $ x++type TCEmb a    = M.HashMap a FTycon  ++-- instance (Eq a, Hashable a) => Monoid (TCEmb a) where+--   mappend m1 m2 = M.fromList (M.toList m1 ++ M.toList m2)+--   mempty        = M.empty++exprSymbols :: Expr -> [Symbol]+exprSymbols = go+  where +    go (EVar x)        = [x]+    -- go (EDat x _)      = [x]+    go (ELit x _)      = [x]+    go (EApp f es)     = f : concatMap go es+    go (EBin _ e1 e2)  = go e1 ++ go e2 +    go (EIte p e1 e2)  = predSymbols p ++ go e1 ++ go e2 +    go (ECst e _)      = go e+    go _               = []++predSymbols :: Pred -> [Symbol]+predSymbols = go+  where +    go (PAnd ps)        = concatMap go ps+    go (POr ps)         = concatMap go ps+    go (PNot p)         = go p+    go (PIff p1 p2)     = go p1 ++ go p2+    go (PImp p1 p2)     = go p1 ++ go p2+    go (PBexp e)        = exprSymbols e+    go (PAtom _ e1 e2)  = exprSymbols e1 ++ exprSymbols e2+    go (PAll xts p)     = (fst <$> xts) ++ go p+    go _                = []++reftKVars :: Reft -> [Symbol]+reftKVars (Reft (_,ras)) = [k | (RKvar k _) <- ras]++---------------------------------------------------------------+---------- (Kut) Sets of Kvars --------------------------------+---------------------------------------------------------------++newtype Kuts = KS (S.HashSet Symbol) ++instance NFData Kuts where+  rnf (KS _) = () -- rnf s++instance Fixpoint Kuts where+  toFix (KS s) = vcat $ ((text "cut " <>) . toFix) <$> S.toList s++ksEmpty             = KS S.empty+ksUnion kvs (KS s') = KS (S.union (S.fromList kvs) s')++---------------------------------------------------------------+---------- Converting Constraints to Fixpoint Input -----------+---------------------------------------------------------------++instance (Eq a, Hashable a, Fixpoint a) => Fixpoint (S.HashSet a) where+  toFix xs = brackets $ sep $ punctuate (text ";") (toFix <$> S.toList xs)+  simplify = S.fromList . map simplify . S.toList++instance Fixpoint a => Fixpoint (Maybe a) where+  toFix    = maybe (text "Nothing") ((text "Just" <+>) . toFix)+  simplify = fmap simplify++instance Fixpoint a => Fixpoint [a] where+  toFix xs = brackets $ sep $ punctuate (text ";") (fmap toFix xs)+  simplify = map simplify++instance (Fixpoint a, Fixpoint b) => Fixpoint (a,b) where+  toFix   (x,y)  = (toFix x) <+> text ":" <+> (toFix y)+  simplify (x,y) = (simplify x, simplify y) ++toFix_gs (SE e)        +  = vcat  $ map (toFix_constant . mapSnd sr_sort) $ hashMapToAscList e+toFix_constant (c, so) +  = text "constant" <+> toFix c <+> text ":" <+> toFix so ++++----------------------------------------------------------------------+------------------------ Type Constructors ---------------------------+----------------------------------------------------------------------++newtype FTycon = TC Symbol deriving (Eq, Ord, Show, Data, Typeable)+++intFTyCon  = TC (S "int")+boolFTyCon = TC (S "bool")+strFTyCon  = TC (S strConName)+propFTyCon = TC (S propConName)++-- listFTyCon = TC (S listConName)++-- isListTC   = (listFTyCon ==)+isListTC (TC (S c)) = c == listConName+isTupTC (TC (S c))  = c == tupConName++fTyconString (TC (S s)) = s++stringFTycon :: String -> FTycon+stringFTycon c +  | c == listConName = TC . S $ listConName+  | otherwise        = TC $ stringSymbol c+++----------------------------------------------------------------------+------------------------------- Sorts --------------------------------+----------------------------------------------------------------------++data Sort = FInt +          | FNum                 -- ^ numeric kind for Num tyvars+          | FObj  Symbol         -- ^ uninterpreted type+          | FVar  !Int           -- ^ fixpoint type variable+          | FFunc !Int ![Sort]   -- ^ type-var arity, in-ts ++ [out-t]+          | FApp FTycon [Sort]   -- ^ constructed type +	      deriving (Eq, Ord, Show, Generic, Data, Typeable)++instance Hashable Sort++newtype Sub = Sub [(Int, Sort)]++instance Fixpoint Sort where+  toFix = toFix_sort++toFix_sort (FVar i)     = text "@"   <> parens (toFix i)+toFix_sort FInt         = text "int"+toFix_sort (FObj x)     = toFix x+toFix_sort FNum         = text "num"+toFix_sort (FFunc n ts) = text "func" <> parens ((toFix n) <> (text ", ") <> (toFix ts))+toFix_sort (FApp c [t]) +  | isListTC c          = brackets $ toFix_sort t +toFix_sort (FApp c ts)  +  | isTupTC  c          = parens $ intersperse comma $ toFix_sort <$> ts +  | otherwise           = toFix c <+> intersperse space (fp <$> ts)+                          where fp s@(FApp _ (_:_)) = parens $ toFix_sort s +                                fp s                = toFix_sort s+++instance Fixpoint FTycon where+  toFix (TC s)       = toFix s++-------------------------------------------------------------------------------------------+sortSubst                  :: (M.HashMap Symbol Sort) -> Sort -> Sort+-------------------------------------------------------------------------------------------+sortSubst θ t@(FObj x)   = fromMaybe t (M.lookup x θ) +sortSubst θ (FFunc n ts) = FFunc n (sortSubst θ <$> ts)+sortSubst θ (FApp c ts)  = FApp c  (sortSubst θ <$> ts)+sortSubst _  t           = t+++---------------------------------------------------------------+---------------------------- Symbols --------------------------+---------------------------------------------------------------++symChars +  =  ['a' .. 'z']+  ++ ['A' .. 'Z'] +  ++ ['0' .. '9'] +  ++ ['_', '%', '.', '#']++data Symbol = S !String deriving (Eq, Ord, Data, Typeable)++instance Fixpoint Symbol where+  toFix (S x) = text x++instance Show Symbol where+  show (S x) = x++instance Show Subst where+  show = showFix++instance Fixpoint Subst where+  toFix (Su m) = case {- hashMapToAscList -} m of +                   []  -> empty+                   xys -> hcat $ map (\(x,y) -> brackets $ (toFix x) <> text ":=" <> (toFix y)) xys+++---------------------------------------------------------------------------+------ Converting Strings To Fixpoint ------------------------------------- +---------------------------------------------------------------------------++stringSymbolRaw :: String -> Symbol+stringSymbolRaw = S++stringSymbol :: String -> Symbol+stringSymbol s+  | isFixKey  s = encodeSym s +  | isFixSym' s = S s +  | otherwise   = encodeSym s -- S $ fixSymPrefix ++ concatMap encodeChar s++encodeSym s     = S $ fixSymPrefix ++ concatMap encodeChar s++symbolString :: Symbol -> String+symbolString (S str) +  = case chopPrefix fixSymPrefix str of+      Just s  -> concat $ zipWith tx indices $ chunks s +      Nothing -> str+    where +      chunks = unIntersperse symSepName +      tx i s = if even i then s else [decodeStr s]++indices :: [Integer]+indices = [0..]++okSymChars+  =  ['a' .. 'z']+  ++ ['A' .. 'Z'] +  ++ ['0' .. '9'] +  ++ ['_', '.'  ]++fixSymPrefix = "fix" ++ [symSepName]++suffixSymbol s suf = stringSymbol (symbolString s ++ suf)++isFixSym' (c:chs)  = isAlpha c && all (`elem` (symSepName:okSymChars)) chs+isFixSym' _        = False++isFixKey x = S.member x keywords+keywords   = S.fromList ["env", "id", "tag", "qualif", "constant", "cut", "bind", "constraint", "grd", "lhs", "rhs"]++encodeChar c +  | c `elem` okSymChars +  = [c]+  | otherwise+  = [symSepName] ++ (show $ ord c) ++ [symSepName]++decodeStr s +  = chr ((read s) :: Int)++qualifySymbol x sy +  | isQualified x' = sy +  | isParened x'   = stringSymbol (wrapParens (x ++ "." ++ stripParens x')) +  | otherwise      = stringSymbol (x ++ "." ++ x')+  where x' = symbolString sy ++isQualified y         = '.' `elem` y +wrapParens x          = "(" ++ x ++ ")"+isParened xs          = xs /= stripParens xs++---------------------------------------------------------------------++vv                  :: Maybe Integer -> Symbol+vv (Just i)         = S (vvName ++ [symSepName] ++ show i)+vv Nothing          = S vvName++vvCon               = S (vvName ++ [symSepName] ++ "F")++isNontrivialVV      = not . (vv_ ==) +++dummySymbol         = S dummyName+intSymbol x i       = S $ x ++ show i           ++tempSymbol          ::  String -> Integer -> Symbol+tempSymbol prefix n = intSymbol (tempPrefix ++ prefix) n++tempPrefix          = "lq_tmp_"+anfPrefix           = "lq_anf_" +nonSymbol           = S ""+isNonSymbol         = (0 ==) . length . symbolString++intKvar             :: Integer -> Symbol+intKvar             = intSymbol "k_" ++---------------------------------------------------------------+------------------------- Expressions -------------------------+---------------------------------------------------------------++-- | Uninterpreted constants that are embedded as  "constant symbol : Str"++data SymConst = SL !String+              deriving (Eq, Ord, Show, Data, Typeable)++data Constant = I  !Integer +              deriving (Eq, Ord, Show, Data, Typeable)++data Brel = Eq | Ne | Gt | Ge | Lt | Le +            deriving (Eq, Ord, Show, Data, Typeable)++data Bop  = Plus | Minus | Times | Div | Mod    +            deriving (Eq, Ord, Show, Data, Typeable) +	      -- NOTE: For "Mod" 2nd expr should be a constant or a var *)++data Expr = ESym !SymConst  +          | ECon !Constant +          | EVar !Symbol+          | ELit !Symbol !Sort+          | EApp !Symbol ![Expr]+          | EBin !Bop !Expr !Expr+          | EIte !Pred !Expr !Expr+          | ECst !Expr !Sort+          | EBot+          deriving (Eq, Ord, Show, Data, Typeable)++instance Fixpoint Integer where+  toFix = integer ++instance Fixpoint Constant where+  toFix (I i)  = toFix i++instance Fixpoint SymConst where +  toFix  = toFix . encodeSymConst++instance Fixpoint Brel where+  toFix Eq = text "="+  toFix Ne = text "!="+  toFix Gt = text ">"+  toFix Ge = text ">="+  toFix Lt = text "<"+  toFix Le = text "<="++instance Fixpoint Bop where+  toFix Plus  = text "+"+  toFix Minus = text "-"+  toFix Times = text "*"+  toFix Div   = text "/"+  toFix Mod   = text "mod"++instance Fixpoint Expr where+  toFix (ESym c)       = toFix $ encodeSymConst c+  toFix (ECon c)       = toFix c +  toFix (EVar s)       = toFix s+  toFix (ELit s _)     = toFix s+  toFix (EApp f es)    = (toFix f) <> (parens $ toFix es) +  toFix (EBin o e1 e2) = parens $ toFix e1 <+> toFix o <+> toFix e2+  toFix (EIte p e1 e2) = parens $ toFix p <+> text "?" <+> toFix e1 <+> text ":" <+> toFix e2 +  toFix (ECst e so)    = parens $ toFix e <+> text " : " <+> toFix so +  toFix (EBot)         = text "_|_"++----------------------------------------------------------+--------------------- Predicates -------------------------+----------------------------------------------------------++data Pred = PTrue+          | PFalse+          | PAnd  ![Pred]+          | POr   ![Pred]+          | PNot  !Pred+          | PImp  !Pred !Pred+          | PIff  !Pred !Pred+          | PBexp !Expr+          | PAtom !Brel !Expr !Expr+          | PAll  ![(Symbol, Sort)] !Pred+          | PTop+          deriving (Eq, Ord, Show, Data, Typeable)++instance Fixpoint Pred where+  toFix PTop             = text "???"+  toFix PTrue            = text "true"+  toFix PFalse           = text "false"+  toFix (PBexp e)        = parens $ text "?" <+> toFix e+  toFix (PNot p)         = parens $ text "~" <+> parens (toFix p)+  toFix (PImp p1 p2)     = parens $ (toFix p1) <+> text "=>" <+> (toFix p2)+  toFix (PIff p1 p2)     = parens $ (toFix p1) <+> text "<=>" <+> (toFix p2)+  toFix (PAnd ps)        = text "&&" <+> toFix ps+  toFix (POr  ps)        = text "||" <+> toFix ps+  toFix (PAtom r e1 e2)  = parens $ toFix e1 <+> toFix r <+> toFix e2+  toFix (PAll xts p)     = text "forall" <+> (toFix xts) <+> text "." <+> (toFix p)++  simplify (PAnd [])     = PTrue+  simplify (POr  [])     = PFalse+  simplify (PAnd [p])    = simplify p+  simplify (POr  [p])    = simplify p+  +  simplify (PAnd ps)    +    | any isContraPred ps = PFalse+    | otherwise           = PAnd $ filter (not . isTautoPred) $ map simplify ps+  +  simplify (POr  ps)    +    | any isTautoPred ps = PTrue+    | otherwise          = POr  $ filter (not . isContraPred) $ map simplify ps ++  simplify p            +    | isContraPred p     = PFalse+    | isTautoPred  p     = PTrue+    | otherwise          = p++zero           = ECon (I 0)+one            = ECon (I 1)++isContraPred z = eqC z || (z `elem` contras)+  where+    contras    = [PFalse]   +    +    eqC (PAtom Eq (ECon x) (ECon y))+               = x /= y+    eqC (PAtom Ne x y)+               = x == y+    eqC _      = False++isTautoPred z  = eqT z || (z `elem` tautos)+  where +    tautos     = [PTrue]+    +    eqT (PAtom Le x y) +               = x == y+    eqT (PAtom Ge x y) +               = x == y+    eqT (PAtom Eq x y) +               = x == y+    eqT (PAtom Ne (ECon x) (ECon y))+               = x /= y+    eqT _      = False ++++isTautoReft (Reft (_, ras)) = all isTautoRa ras+isTautoRa (RConc p)         = isTautoPred p+isTautoRa _                 = False++isEVar (EVar _) = True+isEVar _        = False++isSingletonReft (Reft (v, [RConc (PAtom Eq e1 e2)])) +  | e1 == EVar v = Just e2+  | e2 == EVar v = Just e1+isSingletonReft _    = Nothing ++pAnd          = simplify . PAnd +pOr           = simplify . POr +pIte p1 p2 p3 = pAnd [p1 `PImp` p2, (PNot p1) `PImp` p3] ++mkProp        = PBexp . EApp (S propConName) . (: [])++ppr_reft (Reft (v, ras)) d +  | all isTautoRa ras+  = d+  | otherwise+  = braces (toFix v <+> colon <+> d <+> text "|" <+> ppRas ras)++ppr_reft_pred (Reft (_, ras))+  | all isTautoRa ras+  = text "true"+  | otherwise+  = ppRas ras++ppRas = cat . punctuate comma . map toFix . flattenRefas++------------------------------------------------------------------------+-- | Generalizing Symbol, Expression, Predicate into Classes -----------+------------------------------------------------------------------------++-- | Values that can be viewed as Symbols++class Symbolic a where+  symbol :: a -> Symbol++-- | Values that can be viewed as Expressions++class Expression a where+  expr   :: a -> Expr++-- | Values that can be viewed as Predicates++class Predicate a where+  prop   :: a -> Pred++instance Symbolic String where +  symbol = stringSymbol++instance Symbolic Symbol where +  symbol = id ++instance Expression Expr where+  expr = id++-- | The symbol may be an encoding of a SymConst.++instance Expression Symbol where+  expr s = maybe (eVar s) ESym (decodeSymConst s)  +  -- expr = eVar++instance Expression String where +  expr = ESym . SL++instance Expression Integer where+  expr = ECon . I++instance Expression Int where+  expr = expr . toInteger++instance Predicate Symbol where+  prop = eProp++instance Predicate Pred where+  prop = id ++instance Predicate Bool where+  prop True  = PTrue +  prop False = PFalse ++eVar          ::  Symbolic a => a -> Expr +eVar          = EVar . symbol ++eProp         ::  Symbolic a => a -> Pred+eProp         = mkProp . eVar++exprReft, notExprReft  ::  (Expression a) => a -> Reft+exprReft e             = Reft (vv_, [RConc $ PAtom Eq (eVar vv_)  (expr e)])+notExprReft e          = Reft (vv_, [RConc $ PAtom Ne (eVar vv_)  (expr e)])++propReft               ::  (Predicate a) => a -> Reft+propReft p             = Reft (vv_, [RConc $ PIff     (eProp vv_) (prop p)]) ++predReft               :: (Predicate a) => a -> Reft+predReft p             = Reft (vv_, [RConc $ prop p])+++++---------------------------------------------------------------+----------------- Refinements ---------------------------------+---------------------------------------------------------------++data Refa +  = RConc !Pred +  | RKvar !Symbol !Subst+  deriving (Eq, Ord, Show, Data, Typeable)++newtype Reft = Reft (Symbol, [Refa]) deriving (Eq, Ord, Data, Typeable)++instance Show Reft where+  show (Reft x) = render $ toFix x ++data SortedReft = RR { sr_sort :: !Sort, sr_reft :: !Reft } deriving (Eq)++isNonTrivialSortedReft (RR _ (Reft (_, ras)))+  = not $ null ras++isFunctionSortedReft (RR (FFunc _ _) _)+  = True+isFunctionSortedReft _+  = False++sortedReftValueVariable (RR _ (Reft (v,_))) = v++---------------------------------------------------------------+----------------- Environments  -------------------------------+---------------------------------------------------------------++toListSEnv              ::  SEnv a -> [(Symbol, a)]+toListSEnv (SE env)     = M.toList env+fromListSEnv            ::  [(Symbol, a)] -> SEnv a+fromListSEnv            = SE . M.fromList+mapSEnv f (SE env)      = SE (fmap f env)+deleteSEnv x (SE env)   = SE (M.delete x env)+insertSEnv x y (SE env) = SE (M.insert x y env)+lookupSEnv x (SE env)   = M.lookup x env+emptySEnv               = SE M.empty+memberSEnv x (SE env)   = M.member x env+intersectWithSEnv f (SE m1) (SE m2) = SE (M.intersectionWith f m1 m2)+filterSEnv f (SE m)     = SE (M.filter f m)+lookupSEnvWithDistance x (SE env)+  = case M.lookup x env of +     Just x  -> Found x+     Nothing -> Alts $ stringSymbol <$> alts +  where alts    = takeMin $ (zip (editDistance x' <$> ss) ss)+        ss      = symbolString <$> fst <$> M.toList env+        x'      = symbolString x+        takeMin = \xs ->  [x | (d, x) <- xs, d == getMin xs] +        getMin  = minimum . (fst <$>) ++data SESearch a = Found a | Alts [Symbol]++-- | Functions for Indexed Bind Environment ++emptyIBindEnv :: IBindEnv+emptyIBindEnv = FB (S.empty)++deleteIBindEnv :: BindId -> IBindEnv -> IBindEnv+deleteIBindEnv i (FB s) = FB (S.delete i s)++insertsIBindEnv :: [BindId] -> IBindEnv -> IBindEnv+insertsIBindEnv is (FB s) = FB (foldr S.insert s is)++-- | Functions for Global Binder Environment+insertBindEnv :: Symbol -> SortedReft -> BindEnv -> (BindId, BindEnv)+insertBindEnv x r (BE n m) = (n, BE (n + 1) (M.insert n (x, r) m))++emptyBindEnv :: BindEnv+emptyBindEnv = BE 0 M.empty+++instance Functor SEnv where+  fmap f (SE m) = SE $ fmap f m++instance Fixpoint Refa where+  toFix (RConc p)    = toFix p+  toFix (RKvar k su) = toFix k <> toFix su+  -- toFix (RPvar p)    = toFix p++instance Fixpoint Reft where+  toFix = ppr_reft_pred++instance Fixpoint SortedReft where+  toFix (RR so (Reft (v, ras))) +    = braces +    $ (toFix v) <+> (text ":") <+> (toFix so) <+> (text "|") <+> toFix ras++instance Fixpoint FEnv where+  toFix (SE m)   = toFix (hashMapToAscList m)++instance Fixpoint BindEnv where+  toFix (BE _ m) = vcat $ map toFix_bind $ hashMapToAscList m ++toFix_bind (i, (x, r)) = text "bind" <+> toFix i <+> toFix x <+> text ":" <+> toFix r   ++insertFEnv   = insertSEnv . lower +  where lower x@(S (c:chs)) +          | isUpper c = S $ toLower c : chs+          | otherwise = x+        lower z       = z++instance (Fixpoint a) => Fixpoint (SEnv a) where+  toFix (SE e) = vcat $ map pprxt $ hashMapToAscList e+	where pprxt (x, t) = toFix x <+> colon <> colon  <+> toFix t++instance Fixpoint (SEnv a) => Show (SEnv a) where+  show = render . toFix ++-----------------------------------------------------------------------------+------------------- Constraints ---------------------------------------------+-----------------------------------------------------------------------------++{-@ type Tag = { v : [Int] | len(v) = 1 } @-}+type Tag           = [Int] ++type BindId        = Int+type FEnv          = SEnv SortedReft ++newtype IBindEnv   = FB (S.HashSet BindId)+newtype SEnv a     = SE { se_binds :: M.HashMap Symbol a } deriving (Eq, Data, Typeable)+data BindEnv       = BE { be_size  :: Int+                        , be_binds :: M.HashMap BindId (Symbol, SortedReft) +                        }+++data SubC a = SubC { senv  :: !IBindEnv+                   , sgrd  :: !Pred+                   , slhs  :: !SortedReft+                   , srhs  :: !SortedReft+                   , sid   :: !(Maybe Integer)+                   , stag  :: !Tag+                   , sinfo :: !a+                   }++data WfC a  = WfC  { wenv  :: !IBindEnv+                   , wrft  :: !SortedReft+                   , wid   :: !(Maybe Integer) +                   , winfo :: !a+                   } -- deriving (Eq)++data FixResult a = Crash [a] String +                 | Safe +                 | Unsafe ![a] +                 | UnknownError !Doc+                   deriving (Show)++type FixSolution = M.HashMap Symbol Pred++instance Eq a => Eq (FixResult a) where +  Crash xs _ == Crash ys _         = xs == ys+  Unsafe xs == Unsafe ys           = xs == ys+  Safe      == Safe                = True+  _         == _                   = False++instance Monoid (FixResult a) where+  mempty                          = Safe+  mappend Safe x                  = x+  mappend x Safe                  = x+  mappend _ c@(Crash _ _)         = c +  mappend c@(Crash _ _) _         = c +  mappend (Unsafe xs) (Unsafe ys) = Unsafe (xs ++ ys)+  mappend u@(UnknownError _) _    = u +  mappend _ u@(UnknownError _)    = u ++instance Functor FixResult where +  fmap f (Crash xs msg)   = Crash (f <$> xs) msg+  fmap f (Unsafe xs)      = Unsafe (f <$> xs)+  fmap _ Safe             = Safe+  fmap _ (UnknownError d) = UnknownError d++instance (Ord a, Fixpoint a) => Fixpoint (FixResult (SubC a)) where+  toFix Safe             = text "Safe"+  toFix (UnknownError d) = text "Unknown Error!" <+> d+  toFix (Crash xs msg)   = vcat $ [ text "Crash!" ] ++  ppr_sinfos "CRASH: " xs ++ [parens (text msg)] +  toFix (Unsafe xs)      = vcat $ text "Unsafe:" : ppr_sinfos "WARNING: " xs++ppr_sinfos :: (Ord a, Fixpoint a) => String -> [SubC a] -> [Doc]+ppr_sinfos msg = map ((text msg <>) . toFix) . sort . fmap sinfo+++resultDoc :: (Ord a, Fixpoint a) => FixResult a -> Doc+resultDoc Safe             = text "Safe"+resultDoc (UnknownError d) = text "Unknown Error!" <+> d+resultDoc (Crash xs msg)   = vcat $ (text ("Crash!: " ++ msg)) : (((text "CRASH:" <+>) . toFix) <$> xs)+resultDoc (Unsafe xs)      = vcat $ (text "Unsafe:")           : (((text "WARNING:" <+>) . toFix) <$> xs)++++++colorResult (Safe)      = Happy +colorResult (Unsafe _)  = Angry +colorResult (_)         = Sad +++instance Show (SubC a) where+  show = showFix ++instance Fixpoint (IBindEnv) where+  toFix (FB ids) = text "env" <+> toFix ids ++instance Fixpoint (SubC a) where+  toFix c     = hang (text "\n\nconstraint:") 2 bd+     where bd =   -- text "env" <+> toFix (senv c) +                  toFix (senv c)+              $+$ text "grd" <+> toFix (sgrd c) +              $+$ text "lhs" <+> toFix (slhs c) +              $+$ text "rhs" <+> toFix (srhs c)+              $+$ (pprId (sid c) <+> pprTag (stag c)) ++instance Fixpoint (WfC a) where +  toFix w     = hang (text "\n\nwf:") 2 bd +    where bd  =   -- text "env"  <+> toFix (wenv w)+                  toFix (wenv w)+              $+$ text "reft" <+> toFix (wrft w) +              $+$ pprId (wid w)++pprId (Just i)  = text "id" <+> tshow i+pprId _         = text ""++pprTag []       = text ""+pprTag is       = text "tag" <+> toFix is ++instance Fixpoint Int where+  toFix = tshow ++-------------------------------------------------------+------------------- Substitutions ---------------------+-------------------------------------------------------++class Subable a where+  syms   :: a -> [Symbol]+  substa :: (Symbol -> Symbol) -> a -> a+  -- substa f  = substf (EVar . f) +  +  substf :: (Symbol -> Expr) -> a -> a+  subst  :: Subst -> a -> a+  subst1 :: a -> (Symbol, Expr) -> a+  -- subst1 y (x, e) = subst (Su $ M.singleton x e) y+  subst1 y (x, e) = subst (Su [(x,e)]) y++subst1Except :: (Subable a) => [Symbol] -> a -> (Symbol, Expr) -> a+subst1Except xs z su@(x, _) +  | x `elem` xs = z+  | otherwise   = subst1 z su++substfExcept :: (Symbol -> Expr) -> [Symbol] -> (Symbol -> Expr)+substfExcept f xs y = if y `elem` xs then EVar y else f y++substExcept  :: Subst -> [Symbol] -> Subst+-- substExcept  (Su m) xs = Su (foldr M.delete m xs) +substExcept  (Su xes) xs = Su $ filter (not . (`elem` xs) . fst) xes++instance Subable Symbol where+  substa f x               = f x+  substf f x               = subSymbol (Just (f x)) x+  subst su x               = subSymbol (Just $ appSubst su x) x -- subSymbol (M.lookup x s) x+  syms x                   = [x]++subSymbol (Just (EVar y)) _ = y+subSymbol Nothing         x = x+subSymbol a               b = errorstar (printf "Cannot substitute symbol %s with expression %s" (showFix b) (showFix a))++instance Subable Expr where+  syms                     = exprSymbols+  substa f                 = substf (EVar . f) +  substf f (EApp s es)     = EApp (substf f s) $ map (substf f) es +  substf f (EBin op e1 e2) = EBin op (substf f e1) (substf f e2)+  substf f (EIte p e1 e2)  = EIte (substf f p) (substf f e1) (substf f e2)+  substf f (ECst e so)     = ECst (substf f e) so+  substf f e@(EVar x)      = f x +  substf _ e               = e+ +  subst su (EApp f es)     = EApp (subst su f) $ map (subst su) es +  subst su (EBin op e1 e2) = EBin op (subst su e1) (subst su e2)+  subst su (EIte p e1 e2)  = EIte (subst su p) (subst su e1) (subst  su e2)+  subst su (ECst e so)     = ECst (subst su e) so+  subst su (EVar x)        = appSubst su x+  subst _ e                = e+++instance Subable Pred where+  syms                     = predSymbols+  substa f                 = substf (EVar . f) +  substf f (PAnd ps)       = PAnd $ map (substf f) ps+  substf f (POr  ps)       = POr  $ map (substf f) ps+  substf f (PNot p)        = PNot $ substf f p+  substf f (PImp p1 p2)    = PImp (substf f p1) (substf f p2)+  substf f (PIff p1 p2)    = PIff (substf f p1) (substf f p2)+  substf f (PBexp e)       = PBexp $ substf f e+  substf f (PAtom r e1 e2) = PAtom r (substf f e1) (substf f e2)+  substf _  (PAll _ _)     = errorstar $ "substf: FORALL" +  substf _  p              = p++  subst su (PAnd ps)       = PAnd $ map (subst su) ps+  subst su (POr  ps)       = POr  $ map (subst su) ps+  subst su (PNot p)        = PNot $ subst su p+  subst su (PImp p1 p2)    = PImp (subst su p1) (subst su p2)+  subst su (PIff p1 p2)    = PIff (subst su p1) (subst su p2)+  subst su (PBexp e)       = PBexp $ subst su e+  subst su (PAtom r e1 e2) = PAtom r (subst su e1) (subst su e2)+  subst _  (PAll _ _)      = errorstar $ "subst: FORALL" +  subst _  p               = p++instance Subable Refa where+  syms (RConc p)           = syms p+  syms (RKvar k (Su su'))  = k : concatMap syms ({- M.elems -} su') +  subst su (RConc p)       = RConc   $ subst su p+  subst su (RKvar k su')   = RKvar k $ su' `catSubst` su +  -- subst _  (RPvar p)     = RPvar p+  substa f                 = substf (EVar . f) +  substf f (RConc p)       = RConc (substf f p)+  substf _ ra@(RKvar _ _)  = ra++instance (Subable a, Subable b) => Subable (a,b) where+  syms  (x, y)   = syms x ++ syms y+  subst su (x,y) = (subst su x, subst su y)+  substf f (x,y) = (substf f x, substf f y)+  substa f (x,y) = (substa f x, substa f y)++instance Subable a => Subable [a] where+  syms   = concatMap syms+  subst  = map . subst +  substf = map . substf +  substa = map . substa ++instance Subable a => Subable (M.HashMap k a) where+  syms   = syms . M.elems +  subst  = M.map . subst +  substf = M.map . substf +  substa = M.map . substa++instance Subable Reft where+  syms (Reft (v, ras))      = v : syms ras+  substa f (Reft (v, ras))  = Reft (f v, substa f ras) +  subst su (Reft (v, ras))  = Reft (v, subst (substExcept su [v]) ras)+  substf f (Reft (v, ras))  = Reft (v, substf (substfExcept f [v]) ras)+  subst1 (Reft (v, ras)) su = Reft (v, subst1Except [v] ras su)+++instance Subable SortedReft where+  syms               = syms . sr_reft +  subst su (RR so r) = RR so $ subst su r+  substf f (RR so r) = RR so $ substf f r+  substa f (RR so r) = RR so $ substa f r+++-- newtype Subst  = Su (M.HashMap Symbol Expr) deriving (Eq)+newtype Subst = Su [(Symbol, Expr)] deriving (Eq, Ord, Data, Typeable)++mkSubst                  = Su -- . M.fromList+appSubst (Su s) x        = fromMaybe (EVar x) (lookup x s)+emptySubst               = Su [] -- M.empty+catSubst (Su s1) (Su s2) = Su $ s1' ++ s2+  where s1' = mapSnd (subst (Su s2)) <$> s1+  -- = Su $ s1' `M.union` s2+  --   where s1' = subst (Su s2) `M.map` s1++instance Monoid Subst where+  mempty  = emptySubst+  mappend = catSubst ++------------------------------------------------------------+------------- Generally Useful Refinements -----------------+------------------------------------------------------------++symbolReft    = exprReft . eVar ++vv_           = vv Nothing++trueSortedReft :: Sort -> SortedReft+trueSortedReft = (`RR` trueReft) ++trueReft  = Reft (vv_, [])+falseReft = Reft (vv_, [RConc PFalse])++trueRefa  = RConc PTrue++flattenRefas ::  [Refa] -> [Refa]+flattenRefas         = concatMap flatRa+  where +    flatRa (RConc p) = RConc <$> flatP p+    flatRa ra        = [ra]+    flatP  (PAnd ps) = concatMap flatP ps+    flatP  p         = [p]++squishRefas     ::  [Refa] -> [Refa]+squishRefas ras = (squish [p | RConc p <- ras]) : []+  where +    squish      = RConc . pAnd . sortNub . filter (not . isTautoPred) . concatMap conjuncts   +    +conjuncts (PAnd ps)          = concatMap conjuncts ps+conjuncts p | isTautoPred p  = []+            | otherwise      = [p]+----------------------------------------------------------------+---------------------- Strictness ------------------------------+----------------------------------------------------------------++instance NFData Symbol where+  rnf (S x) = rnf x++instance NFData FTycon where+  rnf (TC c)       = rnf c++instance NFData Sort where+  rnf (FVar x)     = rnf x+  rnf (FFunc n ts) = rnf n `seq` (rnf <$> ts) `seq` () +  rnf (FApp c ts)  = rnf c `seq` (rnf <$> ts) `seq` ()+  rnf (z)          = z `seq` ()++instance NFData Sub where+  rnf (Sub x) = rnf x++instance NFData Subst where+  rnf (Su x) = rnf x++instance NFData FEnv where+  rnf (SE x) = rnf x++instance NFData IBindEnv where+  rnf (FB x) = rnf x++instance NFData BindEnv where+  rnf (BE x m) = rnf x `seq` rnf m++instance NFData Constant where+  rnf (I x) = rnf x++instance NFData SymConst where +  rnf (SL x) = rnf x++instance NFData Brel +instance NFData Bop++instance NFData Expr where+  rnf (ESym x)        = rnf x+  rnf (ECon x)        = rnf x+  rnf (EVar x)        = rnf x+  -- rnf (EDat x1 x2)    = rnf x1 `seq` rnf x2+  rnf (ELit x1 x2)    = rnf x1 `seq` rnf x2+  rnf (EApp x1 x2)    = rnf x1 `seq` rnf x2+  rnf (EBin x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3+  rnf (EIte x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3+  rnf (ECst x1 x2)    = rnf x1 `seq` rnf x2+  rnf (_)             = ()++instance NFData Pred where+  rnf (PAnd x)         = rnf x+  rnf (POr  x)         = rnf x+  rnf (PNot x)         = rnf x+  rnf (PBexp x)        = rnf x+  rnf (PImp x1 x2)     = rnf x1 `seq` rnf x2+  rnf (PIff x1 x2)     = rnf x1 `seq` rnf x2+  rnf (PAll x1 x2)     = rnf x1 `seq` rnf x2+  rnf (PAtom x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3+  rnf (_)              = ()++instance NFData Refa where+  rnf (RConc x)     = rnf x+  rnf (RKvar x1 x2) = rnf x1 `seq` rnf x2+  -- rnf (RPvar _)     = () -- rnf x++instance NFData Reft where +  rnf (Reft (v, ras)) = rnf v `seq` rnf ras++instance NFData SortedReft where +  rnf (RR so r) = rnf so `seq` rnf r++instance (NFData a) => NFData (SubC a) where+  rnf (SubC x1 x2 x3 x4 x5 x6 x7) +    = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7++instance (NFData a) => NFData (WfC a) where+  rnf (WfC x1 x2 x3 x4) +    = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4++----------------------------------------------------------------------------+-------------- Hashable Instances -----------------------------------------+---------------------------------------------------------------------------++instance Hashable Symbol where +  hashWithSalt i (S s) = hashWithSalt i s++instance Hashable FTycon where+  hashWithSalt i (TC s) = hashWithSalt i s++---------------------------------------------------------------------------+-------- Constraint Constructor Wrappers ----------------------------------+---------------------------------------------------------------------------++wfC  = WfC++-- subC γ p r1@(RR _ (Reft (v,_))) (RR t2 r2) x y z +--    = SubC γ p r1 (RR t2 (shiftVV r2 v)) x y z+subC γ p (RR t1 r1) (RR t2 r2) x y z +    = SubC γ p (RR t1 (shiftVV r1 vvCon)) (RR t2 (shiftVV r2 vvCon)) x y z++lhsCs = sr_reft . slhs+rhsCs = sr_reft . srhs++removeLhsKvars cs vs +  = cs{slhs = goRR (slhs cs)} +  where goRR rr                     = rr{sr_reft = goReft (sr_reft rr)} +        goReft (Reft(v, rs))        = Reft(v, filter f rs)+        f (RKvar v _) | v `elem` vs = False+        f r                         = True +        +trueSubCKvar v+  = subC emptyIBindEnv PTrue mempty (RR mempty (Reft(vv_, [RKvar v emptySubst]))) Nothing [0] ++shiftVV r@(Reft (v, ras)) v' +   | v == v'   = r+   | otherwise = Reft (v', (subst1 ras (v, EVar v')))+++addIds = zipWith (\i c -> (i, shiftId i $ c {sid = Just i})) [1..]+  where -- Adding shiftId to have distinct VV for SMT conversion +    shiftId i c = c { slhs = shiftSR i $ slhs c } +                    { srhs = shiftSR i $ srhs c }+    shiftSR i sr = sr { sr_reft = shiftR i $ sr_reft sr }+    shiftR i r@(Reft (S v, _)) = shiftVV r (S (v ++ show i))+++-- subC γ p r1 r2 x y z   = (vvsu, SubC γ p r1' r2' x y z)+--   where (vvsu, r1', r2') = unifySRefts r1 r2 ++-- unifySRefts (RR t1 r1) (RR t2 r2) = (z, RR t1 r1', RR t2 r2')+--   where (r1', r2')                =  unifyRefts r1 r2++-- unifyRefts r1@(Reft (v1, _)) r2@(Reft (v2, _))+--    | v1 == v2  = (r1, r2)+--    | otherwise = (r1, shiftVV r2 v1)++-- unifySRefts (RR t1 r1) (RR t2 r2) = (z, RR t1 r1', RR t2 r2')+--   where (z, r1', r2')             =  unifyRefts r1 r2+--+-- unifyRefts r1@(Reft (v1, _)) r2@(Reft (v2, _))+--   | v1 == v2  = ((v1, emptySubst), r1, r2)+--   | v1 /= vv_ = let (su, r2') = shiftVV r2 v1 in ((v1, su), r1 , r2')+--   | otherwise = let (su, r1') = shiftVV r1 v2 in ((v2, su), r1', r2 ) +--+-- shiftVV (Reft (v, ras)) v' = (su, (Reft (v', subst su ras))) +--   where su = mkSubst [(v, EVar v')]+++------------------------------------------------------------------------+----------------- Qualifiers -------------------------------------------+------------------------------------------------------------------------+++data Qualifier = Q { q_name   :: String           -- ^ Name+                   , q_params :: [(Symbol, Sort)] -- ^ Parameters+                   , q_body   :: Pred             -- ^ Predicate+                   }+               deriving (Eq, Ord, Show, Data, Typeable)++instance Fixpoint Qualifier where +  toFix = pprQual++instance NFData Qualifier where+  rnf (Q x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3++pprQual (Q n xts p) = text "qualif" <+> text n <> parens args  <> colon <+> toFix p +  where args = intersperse comma (toFix <$> xts)++data FInfo a = FI { cm    :: M.HashMap Integer (SubC a)+                  , ws    :: ![WfC a] +                  , bs    :: !BindEnv+                  , gs    :: !FEnv+                  , lits  :: ![(Symbol, Sort)]+                  , kuts  :: Kuts +                  , quals :: ![Qualifier]+                  }++-- toFixs = brackets . hsep . punctuate comma -- . map toFix ++toFixpoint x'    = kutsDoc x' $+$ gsDoc x' $+$ conDoc x' $+$ bindsDoc x' $+$ csDoc x' $+$ wsDoc x'+  where conDoc   = vcat     . map toFix_constant . getLits +        csDoc    = vcat     . map toFix . M.elems . cm +        wsDoc    = vcat     . map toFix . ws +        kutsDoc  = toFix    . kuts+        bindsDoc = toFix    . bs+        gsDoc    = toFix_gs . gs++getLits x = lits x ++ symConstLits x+++-------------------------------------------------------------------------+-- | A Class Predicates for Valid Refinements Types ---------------------+-------------------------------------------------------------------------++class (Monoid r, Subable r) => Reftable r where +  isTauto :: r -> Bool+  ppTy    :: r -> Doc -> Doc+  +  top     :: r+  top     =  mempty+ +  -- | should also refactor `top` so it takes a parameter.+  bot     :: r -> r++  meet    :: r -> r -> r+  meet    = mappend++  toReft  :: r -> Reft+  params  :: r -> [Symbol]          -- ^ parameters for Reft, vv + others++instance Monoid Pred where+  mempty      = PTrue +  mappend p q = pAnd [p, q]++instance Monoid Reft where+  mempty  = trueReft+  mappend = meetReft++meetReft r@(Reft (v, ras)) r'@(Reft (v', ras')) +  | v == v'          = Reft (v , ras  ++ ras')+  | v == dummySymbol = Reft (v', ras' ++ (ras `subst1`  (v , EVar v'))) +  | otherwise        = Reft (v , ras  ++ (ras' `subst1` (v', EVar v )))++instance Subable () where+  syms _      = []+  subst _ ()  = ()+  substf _ () = ()+  substa _ () = ()++instance Reftable () where+  isTauto _ = True+  ppTy _  d = d+  top       = ()+  bot  _    = ()+  meet _ _  = ()+  toReft _  = top+  params _  = []++instance Reftable Reft where+  isTauto  = isTautoReft+  ppTy     = ppr_reft+  toReft   = id+  params _ = []+  bot    _ = falseReft++instance Monoid Sort where+  mempty            = FObj (S "any")+  mappend t1 t2 +    | t1 == mempty  = t2+    | t2 == mempty  = t1+    | t1 == t2      = t1+    | otherwise     = errorstar $ "mappend-sort: conflicting sorts t1 =" ++ show t1 ++ " t2 = " ++ show t2++instance Monoid SortedReft where+  mempty        = RR mempty mempty+  mappend t1 t2 = RR (mappend (sr_sort t1) (sr_sort t2)) (mappend (sr_reft t1) (sr_reft t2))++instance Reftable SortedReft where+  isTauto  = isTauto . toReft+  ppTy     = ppTy . toReft+  toReft   = sr_reft+  params _ = []+  bot s    = s { sr_reft = falseReft }++class Falseable a where+  isFalse :: a -> Bool++instance Falseable Pred where+  isFalse (PFalse) = True+  isFalse _        = False++instance Falseable Refa where+  isFalse (RConc p) = isFalse p+  isFalse _         = False++instance Falseable Reft where+  isFalse (Reft(_, rs)) = or [isFalse p | RConc p <- rs]++-- instance Expression a => Reftable a where+--   isTauto _ = isTauto . toReft +--   ppTy      = ppTy . toReft+--   toReft    = exprReft +--   params _  = []++-- instance Predicate a => Reftable a where+--   isTauto   = isTauto . toReft +--   ppTy      = ppTy . toReft+--   toReft    = propReft +--   params _  = []+++---------------------------------------------------------------+-- |String Constants ------------------------------------------+---------------------------------------------------------------++symConstLits    :: FInfo a -> [(Symbol, Sort)]+symConstLits fi = [(encodeSymConst c, sortSymConst c) | c <- symConsts fi]++-- | Replace all symbol-representations-of-string-literals with string-literal+--   Used to transform parsed output from fixpoint back into fq.+++encodeSymConst        :: SymConst -> Symbol+encodeSymConst (SL s) = stringSymbol $ litPrefix ++ s++sortSymConst          :: SymConst -> Sort+sortSymConst (SL _)   = strSort++decodeSymConst :: Symbol -> Maybe SymConst +decodeSymConst = fmap SL . stripPrefix litPrefix . symbolString++litPrefix    :: String+litPrefix    = "lit" ++ [symSepName]++strSort      :: Sort+strSort      = FApp strFTyCon []++class SymConsts a where +  symConsts :: a -> [SymConst]++instance SymConsts (FInfo a) where +  symConsts fi = sortNub $ csLits ++ bsLits ++ gsLits ++ qsLits+    where+      csLits   = concatMap symConsts                     $ M.elems  $  cm    fi+      bsLits   = concatMap symConsts $ map snd $ M.elems $ be_binds $  bs    fi+      gsLits   = concatMap symConsts $           M.elems $ se_binds $  gs    fi+      qsLits   = concatMap symConsts $                     q_body  <$> quals fi ++instance SymConsts (SubC a) where +  symConsts c  = symConsts (sgrd c) ++ +                 symConsts (slhs c) ++ +                 symConsts (srhs c) ++instance SymConsts SortedReft where+  symConsts = symConsts . sr_reft++instance SymConsts Reft where+  symConsts (Reft (_, ras)) = concatMap symConsts ras++instance SymConsts Refa where+  symConsts (RConc p)          = symConsts p+  symConsts (RKvar _ (Su xes)) = concatMap symConsts $ snd <$> xes ++instance SymConsts Expr where+  symConsts (ESym c)       = [c] +  symConsts (EApp _ es)    = concatMap symConsts es+  symConsts (EBin _ e e')  = concatMap symConsts [e, e']+  symConsts (EIte p e e')  = symConsts p ++ concatMap symConsts [e, e']+  symConsts (ECst e _)     = symConsts e+  symConsts _              = []+ +instance SymConsts Pred where+  symConsts (PNot p)       = symConsts p+  symConsts (PAnd ps)      = concatMap symConsts ps+  symConsts (POr ps)       = concatMap symConsts ps+  symConsts (PImp p q)     = concatMap symConsts [p, q]+  symConsts (PIff p q)     = concatMap symConsts [p, q]+  symConsts (PAll _ p)     = symConsts p+  symConsts (PBexp e)      = symConsts e+  symConsts (PAtom _ e e') = concatMap symConsts [e, e']+  symConsts _              = []++---------------------------------------------------------------+-- | Edit Distance --------------------------------------------+---------------------------------------------------------------+++editDistance :: Eq a => [a] -> [a] -> Int+editDistance xs ys = table ! (m,n)+    where+    (m,n) = (length xs, length ys)+    x     = array (1,m) (zip [1..] xs)+    y     = array (1,n) (zip [1..] ys)+ +    table :: Array (Int,Int) Int+    table = array bnds [(ij, dist ij) | ij <- range bnds]+    bnds  = ((0,0),(m,n))+ +    dist (0,j) = j+    dist (i,0) = i+    dist (i,j) = minimum [table ! (i-1,j) + 1, table ! (i,j-1) + 1,+        if x ! i == y ! j then table ! (i-1,j-1) else 1 + table ! (i-1,j-1)]