(* Copyright (C) 2000, HELM Team. * * This file is part of HELM, an Hypertextual, Electronic * Library of Mathematics, developed at the Computer Science * Department, University of Bologna, Italy. * * HELM is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * HELM 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HELM; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * For details, see the HELM World-Wide-Web page, * http://cs.unibo.it/helm/. *) (* AUTOR: Ferruccio Guidi *) module T = MQGTypes let text_of_entries out entries = out "(** MatchConclusion: results of the term inspection **)\n"; let text_of_entry (u, b, v) = out (string_of_int v ^ " "); out (if b then "$MC " else "$IC "); out (u ^ "\n") in List.iter text_of_entry entries let sort_entries entries = let comparator (_, _, v1) (_, _, v2) = compare v1 v2 in List.fast_sort comparator entries let levels_of_term metasenv context term = let module TC = CicTypeChecker in let module Red = CicReduction in let module Misc = MQueryMisc in let degree t = let rec degree_aux = function | Cic.Sort _ -> 1 | Cic.Cast (u, _) -> degree_aux u | Cic.Prod (_, _, t) -> degree_aux t | _ -> 2 in let u = TC.type_of_aux' metasenv context t in degree_aux (Red.whd context u) in let entry_eq (s1, b1, v1) (s2, b2, v2) = s1 = s2 && b1 = b2 in let rec entry_in e = function | [] -> [e] | head :: tail -> head :: if entry_eq head e then tail else entry_in e tail in let inspect_uri main l uri tc v term = let d = degree term in entry_in (Misc.string_of_uriref (uri, tc), main, 2 * v + d - 1) l in let rec inspect_term main l v term = match term with Cic.Rel _ -> l | Cic.Meta _ -> l | Cic.Sort _ -> l | Cic.Implicit -> l | Cic.Var (u,exp_named_subst) -> let l' = inspect_uri main l u [] v term in inspect_exp_named_subst l' (succ v) exp_named_subst | Cic.Const (u,exp_named_subst) -> let l' = inspect_uri main l u [] v term in inspect_exp_named_subst l' (succ v) exp_named_subst | Cic.MutInd (u, t, exp_named_subst) -> let l' = inspect_uri main l u [t] v term in inspect_exp_named_subst l' (succ v) exp_named_subst | Cic.MutConstruct (u, t, c, exp_named_subst) -> let l' = inspect_uri main l u [t; c] v term in inspect_exp_named_subst l' (succ v) exp_named_subst | Cic.Cast (uu, _) -> inspect_term main l v uu | Cic.Prod (_, uu, tt) -> let luu = inspect_term false l (succ v) uu in inspect_term main luu (succ v) tt | Cic.Lambda (_, uu, tt) -> let luu = inspect_term false l (succ v) uu in inspect_term false luu (succ v) tt | Cic.LetIn (_, uu, tt) -> let luu = inspect_term false l (succ v) uu in inspect_term false luu (succ v) tt | Cic.Appl m -> inspect_list main l true v m | Cic.MutCase (u, t, tt, uu, m) -> let lu = inspect_uri main l u [t] (succ v) term in let ltt = inspect_term false lu (succ v) tt in let luu = inspect_term false ltt (succ v) uu in inspect_list main luu false (succ v) m | Cic.Fix (_, m) -> inspect_ind l (succ v) m | Cic.CoFix (_, m) -> inspect_coind l (succ v) m and inspect_list main l head v = function | [] -> l | tt :: m -> let ltt = inspect_term main l (if head then v else v + 1) tt in inspect_list false ltt false v m and inspect_exp_named_subst l v = function [] -> l | (_,t) :: tl -> let l' = inspect_term false l v t in inspect_exp_named_subst l' v tl and inspect_ind l v = function | [] -> l | (_, _, tt, uu) :: m -> let ltt = inspect_term false l v tt in let luu = inspect_term false ltt v uu in inspect_ind luu v m and inspect_coind l v = function | [] -> l | (_, tt, uu) :: m -> let ltt = inspect_term false l v tt in let luu = inspect_term false ltt v uu in inspect_coind luu v m in let rec inspect_backbone = function | Cic.Cast (uu, _) -> inspect_backbone uu | Cic.Prod (_, _, tt) -> inspect_backbone tt | Cic.LetIn (_, uu, tt) -> inspect_backbone tt | t -> inspect_term true [] 0 t in inspect_backbone term let get_constraints e c t = let can = sort_entries (levels_of_term e c t) in (* can restrictions *) text_of_entries prerr_string can; flush stderr; (* logging *) let rest_of (u, b, _) = let p = if b then `MainConclusion None else `InConclusion in (p, u) in let rec split vp = function | [], ((_, _, v) as hd) :: tl -> split v ([rest_of hd], tl) | prev, ((_, _, ve) as hd) :: tl when vp = ve -> split vp (rest_of hd :: prev, tl) | p, l -> p, l in let rec mk_musts prev acc = function | [] -> prev, acc | l -> let slice, next = split 0 ([], l) in let acc = acc @ slice in mk_musts (prev @ [acc]) acc next in mk_musts [] [] can let universe = [T.MainConclusion; T.InConclusion]