1signature patternMatchesLib =
2sig
3  include Abbrev
4  type ssfrag = simpLib.ssfrag
5
6  (********************************)
7  (* parsing                      *)
8  (********************************)
9
10  (* ENABLE_PMATCH_CASES() turns on parsing for
11     PMATCH style case expressions. After calling it
12     expressions like `case ... of ...` are not parsed
13     to decision trees any more, but to PMATCH expressions.
14     Decision tree case expressions are afterwards available
15     via `dtcase ... of ...`. *)
16  val ENABLE_PMATCH_CASES : unit -> unit
17
18
19  (********************************)
20  (* Naming conventions           *)
21  (********************************)
22
23  (* Many PMATCH related tools need to prove various forms of
24     preconditions, in particular they need to prove that certain
25     patterns are injective or don't overlap. For this they need
26     information about the used constructors, in particular
27     injectivity theorems about the used constructors and theorems
28     about the distinctiveness of constructors. For most conversions
29     there are therefore 4 forms:
30
31     XXX_CONV : conv
32
33     uses a default set of theorem for proving preconditions enriched
34     with information from TypeBase.
35
36     XXX_CONV_GEN : ssfrag list -> conv
37
38     additionally uses the given list of ssfrags for proving preconditions.
39
40     XXX_ss : ssfrag
41
42     uses the default set + the simplifier using it as a callback to prove
43     preconditions.
44
45     XXX_ss_GEN : ssfrag list -> ssfrag
46
47     uses additionally the given list of ssfrags.
48  *)
49
50
51  (********************************)
52  (* Normalise PMATCH-terms       *)
53  (********************************)
54
55  (* remove unused pattern variables *)
56  val PMATCH_CLEANUP_PVARS_CONV : conv
57
58  (* Use same variable names for pattern, guard and rhs *)
59  val PMATCH_FORCE_SAME_VARS_CONV : conv
60
61  (* Rename pattern variables unused in guard and rhs into
62     wildcards. *)
63  val PMATCH_INTRO_WILDCARDS_CONV : conv
64
65  (* Enforce each pattern to have the same number of columns, i.e.
66     explicit elements of a top-level tuple. *)
67  val PMATCH_EXPAND_COLS_CONV : conv
68
69  (* A combination of the normalisations above. *)
70  val PMATCH_NORMALISE_CONV : conv
71  val PMATCH_NORMALISE_ss : simpLib.ssfrag
72
73  (********************************)
74  (* Evaluate PMATCH-terms        *)
75  (********************************)
76
77  (* PMATCH_CLEANUP_CONV removes rows that can't match,
78     removes all rows after the first matching row and
79     evaluates the whole expression in case the first row matches. *)
80  val PMATCH_CLEANUP_CONV : conv
81  val PMATCH_CLEANUP_CONV_GEN : ssfrag list -> conv
82
83  val PMATCH_CLEANUP_GEN_ss : ssfrag list -> ssfrag
84  val PMATCH_CLEANUP_ss : ssfrag
85
86  (* PMATCH_SIMP_COLS_CONV partially evaluates columns that all contain
87     either the same constructor or a variable. *)
88  val PMATCH_SIMP_COLS_CONV : conv
89  val PMATCH_SIMP_COLS_CONV_GEN : ssfrag list -> conv
90
91  (* A combination of PMATCH_CLEANUP_CONV and PMATCH_SIMP_COLS_CONV *)
92  val PMATCH_FAST_SIMP_CONV : conv
93  val PMATCH_FAST_SIMP_CONV_GEN : ssfrag list -> conv
94  val PMATCH_FAST_SIMP_GEN_ss : ssfrag list -> ssfrag
95  val PMATCH_FAST_SIMP_ss : ssfrag
96
97
98  (********************************)
99  (* simplify PMATCH-terms        *)
100  (********************************)
101
102  (* Remove easily detectable redundant rows *)
103  val PMATCH_REMOVE_FAST_REDUNDANT_CONV : conv
104  val PMATCH_REMOVE_FAST_REDUNDANT_CONV_GEN : ssfrag list -> conv
105
106  (* Remove easily detectable subsumed rows *)
107  val PMATCH_REMOVE_FAST_SUBSUMED_CONV : bool -> conv
108  val PMATCH_REMOVE_FAST_SUBSUMED_CONV_GEN : bool -> ssfrag list -> conv
109
110  (* Full simplification of PMATCH expressions:
111     normalise, partially evaluate rows and columns and
112     try to remove redundant and subsumed rows. *)
113  val PMATCH_SIMP_CONV : conv
114  val PMATCH_SIMP_CONV_GEN : ssfrag list -> conv
115  val PMATCH_SIMP_GEN_ss : ssfrag list -> ssfrag
116  val PMATCH_SIMP_ss : ssfrag
117
118
119  (********************************)
120  (* removing double variable     *)
121  (* bindings                     *)
122  (********************************)
123
124  val PMATCH_REMOVE_DOUBLE_BIND_CONV_GEN : ssfrag list -> conv
125  val PMATCH_REMOVE_DOUBLE_BIND_CONV : conv
126  val PMATCH_REMOVE_DOUBLE_BIND_GEN_ss : ssfrag list -> ssfrag
127  val PMATCH_REMOVE_DOUBLE_BIND_ss : ssfrag
128
129
130  (********************************)
131  (* removing GUARDS              *)
132  (********************************)
133
134  val PMATCH_REMOVE_GUARDS_CONV_GEN : ssfrag list -> conv
135  val PMATCH_REMOVE_GUARDS_CONV : conv
136  val PMATCH_REMOVE_GUARDS_GEN_ss : ssfrag list -> ssfrag
137  val PMATCH_REMOVE_GUARDS_ss : ssfrag
138
139
140  (********************************)
141  (* extending input              *)
142  (********************************)
143
144  val PMATCH_EXTEND_INPUT_CONV_GEN : ssfrag list -> term -> conv
145  val PMATCH_EXTEND_INPUT_CONV : term -> conv
146
147  (********************************)
148  (* removing PMATCH-terms        *)
149  (* via lifting it to the nearest*)
150  (* boolean term and then        *)
151  (* unfolding                    *)
152  (********************************)
153
154  (* One can eliminate PMATCHs by unfolding all
155     cases explicitly. This is often handy to
156     prove properties about functions defined
157     via pattern matches without the need to
158     do the case-splits manually.
159
160     This tactic looks for the smallest wrapper
161     around a PMATCH such that the term is of type
162     bool. This term is then expanded into a big
163     conjunction. For each case of the pattern match,
164     one conjunct is created.
165
166     If the flag "check_exh" is is set to true, the
167     conversion tries to prove the exhaustiveness of
168     the expanded pattern match. This is slow, but if
169     successful allows to eliminate the last
170     generated conjunct.
171  *)
172  val PMATCH_LIFT_BOOL_CONV : bool -> conv
173
174  (* There is also a more generic version that
175     allows to provide extra ssfrags. This might
176     be handy, if the PMATCH contains functions
177     not known by the default methods. *)
178  val PMATCH_LIFT_BOOL_CONV_GEN : ssfrag list -> bool -> conv
179
180  (* corresponding ssfrags *)
181  val PMATCH_LIFT_BOOL_GEN_ss : ssfrag list -> bool -> ssfrag
182  val PMATCH_LIFT_BOOL_ss : bool -> ssfrag
183
184  (* A special case of lifting are function definitions,
185     which use PMATCH. In order to use such definitions
186     with the rewriting tools, it is often handy to
187     move the PMATCH to the toplevel and introduce
188     multiple cases, one case for each row of the
189     PMATCH. This is automated by the following rules. *)
190  val PMATCH_TO_TOP_RULE_GEN : ssfrag list -> rule
191  val PMATCH_TO_TOP_RULE : rule
192
193  (********************************)
194  (* convert between              *)
195  (* case and pmatch              *)
196  (********************************)
197
198  (* without proof convert a case to a pmatch expression.
199     If the flag is set, optimise the result by
200     introducing wildcards reordering rows ... *)
201  val case2pmatch : bool -> term -> term
202
203  (* convert a pmatch expression to a case expression.
204     Fails, if the pmatch expression uses guards or
205     non-constructor patterns. *)
206  val pmatch2case : term -> term
207
208  (* The following conversions call
209     case2pmatch and pmatch2case and
210     afterwards prove the equivalence of
211     the result. *)
212  val PMATCH_INTRO_CONV : conv
213  val PMATCH_INTRO_CONV_NO_OPTIMISE : conv
214  val PMATCH_ELIM_CONV : conv
215
216
217  (*************************************)
218  (* Analyse PMATCH expressions to     *)
219  (* check whether they can be         *)
220  (* translated to ML or OCAML         *)
221  (*************************************)
222
223  (* Record storing detailed information about a PMATCH *)
224  type pmatch_info = {
225    (* Is it a well formed PMATCH, i.e. is it of
226       the from PMATCH input row_list, where
227       every row is given explicitly via PMATCH_MATCH_ROW
228       and is wellformed itself? *)
229    pmi_is_well_formed            : bool,
230
231    (* List of all rows that are not well-formed.
232       If this list is non-empty, pmi_is_well_formed is false. *)
233    pmi_ill_formed_rows           : int list,
234
235    (* List of rows that have guards *)
236    pmi_has_guards                : int list,
237
238    (* List of rows that contain variables in a pattern that
239       are not bound by the pattern. These free vars are
240       returned explicitly. *)
241    pmi_has_free_pat_vars         : (int * term list) list,
242
243    (* List of rows whose patterns bind variables that they
244       do not use. These unused vars are returned explicitly. *)
245    pmi_has_unused_pat_vars       : (int * term list) list,
246
247    (* List of rows whose patterns use a bound variable
248       multiple times. These vars are returned explicitly. *)
249    pmi_has_double_bound_pat_vars : (int * term list) list,
250
251    (* List of rows that uses constants that are neither
252       literals nor datatype-constructors in
253       patterns. These constants are returned. *)
254    pmi_has_non_contr_in_pat      : (int * term list) list,
255
256    (* List of rows that use lambda-abstractions in patterns. *)
257    pmi_has_lambda_in_pat         : int list,
258
259    (* Optional information about exhaustiveness.
260       Checking exhaustiveness is expensive, therefore it
261       can be skipped. However, if a theorem is stored here,
262       it is of the form `|- ~(cond) -> exhaustive`.
263       There are no other guarantees. We don't guarantee that
264       if the condition holds, the pattern match is inexhaustive.
265       This is usually the case, put we don't guarantee it.
266       To check, whether the match is exhaustive, check whether
267       the guard is T. See below for functions using this
268       field.
269     *)
270    pmi_exhaustiveness_cond       : thm option
271  }
272
273  (* Analyse a PMATCH term and return the result. If
274     the flag is set to true, an exhaustiveness check is
275     attempted, if no syntactic checks indicate that this
276     one would most likely fail. *)
277  val analyse_pmatch : bool -> term -> pmatch_info
278
279  (* Check whether the PMATCH is syntactically well-formed. *)
280  val is_well_formed_pmatch : pmatch_info -> bool
281
282  (* Check whether the PMATCH is falling into the subset
283     supported by OCAML *)
284  val is_ocaml_pmatch : pmatch_info -> bool
285
286  (* Check whether the PMATCH is falling into the subset
287     supported by SML. *)
288  val is_sml_pmatch : pmatch_info -> bool;
289
290  (* Was it proved that the PMATCH is exhaustive? If
291     the answer is no, we don't know much. *)
292  val is_proven_exhaustive_pmatch : pmatch_info -> bool
293
294  (* Get the list of patterns that are possibly missing.
295     If no exhaustiveness information is available, NONE
296     is returned. The missing patterns are returns as a list
297     of triples (`bound-vars`, `pattern`, `guard`) *)
298  val get_possibly_missing_patterns : pmatch_info ->
299    (term * term * term) list option
300
301  (** extend_possibly_missing_patterns t pmi
302      tries to extend the original pattern match t with
303      rows derived from the exhaustiveness information
304      from its info. It fails, if no exhaustiveness
305      information is available. The result should
306      be an exhaustive match, which is equivalent to
307      the input `t`. If you need a proof, use
308      PMATCH_COMPLETE_CONV and similar functions instead
309      of this syntactic one. *)
310  val extend_possibly_missing_patterns : term -> pmatch_info -> term
311
312
313  (********************************)
314  (* CASE SPLIT (pattern compile) *)
315  (********************************)
316
317  (*------------*)
318  (* Heuristics *)
319  (*------------*)
320
321  (* A column heuristic is used to figure out, in
322     which order to process columns. It gets a list of columns
323     and returns, which one to pick. *)
324  type column_heuristic = (term * (term list * term) list) list -> int
325
326  (* Many heuristics are build on ranking funs.
327     A ranking fun assigns an integer to a column. Larger
328     numbers are preferred. If two columns have the same
329     value, either another ranking fun is used to decide or
330     just the first one is used, if no ranking fun is available. *)
331  type column_ranking_fun = term * (term list * term) list -> int
332  val colHeu_rank : column_ranking_fun list -> column_heuristic
333
334  val colRank_first_row : column_ranking_fun
335  val colRank_first_row_constr : constrFamiliesLib.pmatch_compile_db ->
336                                 column_ranking_fun
337  val colRank_arity : constrFamiliesLib.pmatch_compile_db -> column_ranking_fun
338  val colRank_constr_prefix : column_ranking_fun
339  val colRank_small_branching_factor : constrFamiliesLib.pmatch_compile_db ->
340                                       column_ranking_fun
341
342  (* Some heuristics *)
343  val colHeu_first_col : column_heuristic
344  val colHeu_last_col : column_heuristic
345  val colHeu_first_row : column_heuristic
346  val colHeu_constr_prefix : column_heuristic
347  val colHeu_cqba : constrFamiliesLib.pmatch_compile_db -> column_heuristic
348  val colHeu_qba : constrFamiliesLib.pmatch_compile_db -> column_heuristic
349
350  (* the default heuristic, currently it is
351     colHeu_qba applied to the default db. However,
352     this might change. You can just rely on a decent heuristic,
353     that often works. No specific properties guaranteed. *)
354  val colHeu_default : column_heuristic
355
356
357  (*---------------------*)
358  (* PATTERN COMPILATION *)
359  (*---------------------*)
360
361  (* [PMATCH_CASE_SPLIT_CONV_GEN ssl db col_heu]
362     is a conversion that tries to compile PMATCH expressions
363     to decision trees using database [db], column heuristic
364     [col_heu] and additional ssfrags [ssl]. *)
365  val PMATCH_CASE_SPLIT_CONV_GEN :
366     ssfrag list ->
367     constrFamiliesLib.pmatch_compile_db ->
368     column_heuristic -> conv
369
370  (* A simplified version of PMATCH_CASE_SPLIT_CONV that
371     uses the default database and default column heuristic as
372     well as no extra ssfrags. *)
373  val PMATCH_CASE_SPLIT_CONV : conv
374
375  (* lets choose at least the heuristic *)
376  val PMATCH_CASE_SPLIT_CONV_HEU : column_heuristic -> conv
377
378  (* ssfrag corresponding to PMATCH_CASE_SPLIT_CONV_GEN *)
379  val PMATCH_CASE_SPLIT_GEN_ss :
380     ssfrag list ->
381     constrFamiliesLib.pmatch_compile_db ->
382     column_heuristic -> ssfrag
383
384  (* ssfrag corresponding to PMATCH_CASE_SPLIT_CONV, since
385     it needs to get the current version of the default db,
386     it gets a unit argument. *)
387  val PMATCH_CASE_SPLIT_ss : unit -> ssfrag
388
389  (* lets choose at least the heuristic *)
390  val PMATCH_CASE_SPLIT_HEU_ss : column_heuristic -> ssfrag
391
392
393  (* Pattern compilation builds for a list of patterns, implicitly
394     a nchotomy theorem, i.e. a list of patterns that cover all the
395     original ones and are exhaustive. Moreover these patterns usually
396     have some nice properties like e.g. not overlapping with each other.
397     Such a nchotomy theorem is often handy. We use it to check for
398     exhaustiveness for example. The interface
399     to compute such an nchotomy is exposed here as well. *)
400
401  (* [nchotomy_of_pats_GEN db colHeu pats] computes an nchotomy-theorem
402     for a list of patterns. A pattern is written as for PMATCH, i.e. in the form ``\(v1, ..., vn). p v1 ... vn``. *)
403  val nchotomy_of_pats_GEN : constrFamiliesLib.pmatch_compile_db ->
404                             column_heuristic -> term list -> thm
405  val nchotomy_of_pats : term list -> thm
406
407
408  (*-----------------------*)
409  (* Remove redundant rows *)
410  (*-----------------------*)
411
412  (* fancy, slow conversion for detecting and removing
413     redundant rows. Internally this uses [nchotomy_of_pats] and
414     therefore requires a pmatch-compile db and a column-heuristic. *)
415  val PMATCH_REMOVE_REDUNDANT_CONV_GEN :
416    constrFamiliesLib.pmatch_compile_db -> column_heuristic -> ssfrag list ->
417    conv
418  val PMATCH_REMOVE_REDUNDANT_CONV : conv
419
420  val PMATCH_REMOVE_REDUNDANT_GEN_ss :
421    constrFamiliesLib.pmatch_compile_db -> column_heuristic -> ssfrag list ->
422    ssfrag
423  val PMATCH_REMOVE_REDUNDANT_ss : unit -> ssfrag
424
425
426  (* The redundancy removal conversion works by
427     first creating a is-redundant-rows-info theorem and
428     then turning it into a PMATCH equation. One can
429     separate these steps, this allows using interactive proofs
430     for showing that a row is redundant. *)
431  val COMPUTE_REDUNDANT_ROWS_INFO_OF_PMATCH_GEN :
432    ssfrag list -> constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
433    term -> thm
434  val COMPUTE_REDUNDANT_ROWS_INFO_OF_PMATCH : term -> thm
435
436  (* Apply the resulting redundant rows-info *)
437  val IS_REDUNDANT_ROWS_INFO_TO_PMATCH_EQ_THM : thm -> thm
438
439
440  (* prove redundancy of given row given an info-thm *)
441  val IS_REDUNDANT_ROWS_INFO_SHOW_ROW_IS_REDUNDANT :
442    thm -> int -> tactic -> thm
443
444  val IS_REDUNDANT_ROWS_INFO_SHOW_ROW_IS_REDUNDANT_set_goal :
445    thm -> int -> proofManagerLib.proofs
446
447
448  (*-----------------------*)
449  (* Exhaustiveness        *)
450  (*-----------------------*)
451
452  (* A IS_REDUNDANT_ROW_INFO theorem contains already
453     information, whether the pattern match is exhaustive.
454
455     IS_REDUNDANT_ROWS_INFO_TO_PMATCH_IS_EXHAUSTIVE extracts
456     this information in the form of an implication. Ideally,
457     the precondition is ~F, but the user has to check. *)
458
459  val IS_REDUNDANT_ROWS_INFO_TO_PMATCH_IS_EXHAUSTIVE : thm -> thm
460
461  (* For convenience this is combined with the computation of the
462     IS_REDUNDANT_ROWS_INFO. So given a PMATCH term, the following
463     functions compute an implication, whose conclusion is the
464     exhaustiveness of the PMATCH. *)
465
466  val PMATCH_IS_EXHAUSTIVE_COMPILE_CONSEQ_CHECK : term -> thm
467  val PMATCH_IS_EXHAUSTIVE_COMPILE_CONSEQ_CHECK_GEN :
468     ssfrag list -> term -> thm
469  val PMATCH_IS_EXHAUSTIVE_COMPILE_CONSEQ_CHECK_FULLGEN :
470     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
471     (ssfrag list * conv option) -> term -> thm
472
473  (* One can usually even derive an equality.  *)
474
475  val PMATCH_IS_EXHAUSTIVE_COMPILE_CHECK : term -> thm
476  val PMATCH_IS_EXHAUSTIVE_COMPILE_CHECK_GEN :
477     ssfrag list -> term -> thm
478  val PMATCH_IS_EXHAUSTIVE_COMPILE_CHECK_FULLGEN :
479     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
480     (ssfrag list * conv option) -> term -> thm
481
482
483  (* Computing the IS_REDUNDANT_ROWS_INFO takes time and
484      is often not necessary. Many pattern matches contain
485      for example and catch-all pattern as the last row.
486      The following functions try to compute the redundancy
487      fast by searching such rows. If they succeed they result
488      in a theorem of the form
489
490      EHX_STATEMENT = T
491
492      or
493
494      EHX_STATEMENT = F
495
496      So, this time, there is an equation, not an implication
497      and the right-hand-side is always T or F.
498   *)
499   val PMATCH_IS_EXHAUSTIVE_FAST_CHECK : term -> thm
500   val PMATCH_IS_EXHAUSTIVE_FAST_CHECK_GEN : ssfrag list -> term -> thm
501
502
503   (* Both methods can be combined to combine the speed of
504      the fast version with the power of the slow one.
505
506      There are two versions of this, one resulting in an
507      equation and one resulting in an implication. The
508      equation one is suitable, if one just wants yes/no
509      answers, the implicational one to analyse what is missing
510      to make the pattern match exhaustive. *)
511
512   val PMATCH_IS_EXHAUSTIVE_CHECK : term -> thm
513   val PMATCH_IS_EXHAUSTIVE_CHECK_GEN : ssfrag list -> term -> thm
514   val PMATCH_IS_EXHAUSTIVE_CHECK_FULLGEN :
515      constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
516      (ssfrag list * conv option) -> term -> thm
517
518   val PMATCH_IS_EXHAUSTIVE_CONSEQ_CHECK : term -> thm
519   val PMATCH_IS_EXHAUSTIVE_CONSEQ_CHECK_GEN : ssfrag list -> term -> thm
520   val PMATCH_IS_EXHAUSTIVE_CONSEQ_CHECK_FULLGEN :
521      constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
522      (ssfrag list * conv option) -> term -> thm
523
524
525   (* More interesting than just computing whether a PMATCH
526      expression is exhaustive might be adding at the end
527      additional rows that explicitly list the missing pats
528      and return ARB for them. This is achieved by the following
529      functions.
530
531      The additional patterns can use guards or not. If not
532      guards are used, the added patterns are more coarse, but
533      simpler. *)
534
535   val PMATCH_COMPLETE_CONV : bool -> conv
536   val PMATCH_COMPLETE_ss : bool -> ssfrag
537
538   (* and as usual more general versions that allows using
539      own pattern compilation settings *)
540   val PMATCH_COMPLETE_CONV_GEN : ssfrag list ->
541     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
542     bool -> conv
543
544   val PMATCH_COMPLETE_GEN_ss :
545     ssfrag list ->
546     constrFamiliesLib.pmatch_compile_db ->
547     column_heuristic -> bool -> ssfrag
548
549
550   (* Versions with suffix "WITH_EXH_PROOF" return a theorem stating
551      that the resulting case split is exhaustive is returned as well.
552      In case the original case split is already exhaustive, no
553      conversion theorem is returned. However a theorem stating that the
554      original case split is exhaustive is still computed. *)
555   val PMATCH_COMPLETE_CONV_WITH_EXH_PROOF : bool -> (term -> (thm option * thm))
556
557   val PMATCH_COMPLETE_CONV_GEN_WITH_EXH_PROOF : ssfrag list ->
558     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
559     bool -> (term -> (thm option * thm))
560
561  (*-----------------------*)
562  (* Show nchotomy         *)
563  (*-----------------------*)
564
565  (* [show_nchotomy t] tries to prove an nchotomy-theorem.
566     Given an nchotomy theorem of the form
567     ``!x. (?xs1. v = p1 xs1 /\ g1 xs1) \/ ... \/
568           (?xsn. v = pn xsn /\ gn xsn)``.
569     It returns a theorem that is an implication with
570     the input as conclusion. *)
571  val SHOW_NCHOTOMY_CONSEQ_CONV : ConseqConv.conseq_conv
572
573  (* A generalised version that allows specifying additional
574     parameters. *)
575  val SHOW_NCHOTOMY_CONSEQ_CONV_GEN :
576    ssfrag list -> constrFamiliesLib.pmatch_compile_db ->
577    column_heuristic -> ConseqConv.conseq_conv
578
579
580  (********************************)
581  (* General Lifting              *)
582  (********************************)
583
584  (* One can also lift to arbitrary levels. This requires forcing the
585     lifted case expression to be exhaustive though.  Therefore,
586     PMATCH_COMPLETE_CONV is used internally and a compilation database
587     and a column heuristic are needed. Similarly to lifting, there is
588     also a version that returns an exhaustiveness statement of the
589     result. *)
590
591  val PMATCH_LIFT_CONV : conv
592
593  val PMATCH_LIFT_CONV_GEN : ssfrag list ->
594     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
595     conv
596
597  val PMATCH_LIFT_CONV_WITH_EXH_PROOF : term -> (thm * thm)
598
599  val PMATCH_LIFT_CONV_GEN_WITH_EXH_PROOF : ssfrag list ->
600     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
601     term -> (thm * thm)
602
603
604  (********************************)
605  (* Flattening                   *)
606  (********************************)
607
608  (* Flattening tries to flatten nested PMATCH case expressions into a
609     single one. It needs to enforce exhaustiveness. Therefore a
610     compilation database and a column heuristic are needed.  The
611     additional flag states whether lifting should be attempted.  If
612     set to false, only nested PMATCH expressions directly at the top
613     of the rhs of a row are considered for flattening. Otherwise,
614     lifting is attempted. *)
615
616  val PMATCH_FLATTEN_CONV_GEN : ssfrag list ->
617     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
618     bool -> conv
619
620  val PMATCH_FLATTEN_CONV : bool -> conv
621
622  val PMATCH_FLATTEN_GEN_ss : ssfrag list ->
623     constrFamiliesLib.pmatch_compile_db -> column_heuristic ->
624     bool -> ssfrag
625
626  val PMATCH_FLATTEN_ss : bool -> ssfrag
627
628  (********************************)
629  (* eliminating select           *)
630  (********************************)
631
632  (* PMATCH leads to selects consisting of
633     conjunctions that determine the value of one
634     component of the variable. An example is
635
636     @x. SND (SND x = ..) /\ (FST x = ..) /\ (FST (SND x) = ..)
637
638     by resorting these conjunctions, one can
639     easily derive a form
640
641     @x. x = ..
642
643     and therefore eliminate the select operator.
644     This is done by the following conversion + ssfrag.
645     These are used internally by the pattern matches
646     infrastructure. *)
647  val ELIM_FST_SND_SELECT_CONV : conv
648  val elim_fst_snd_select_ss : ssfrag
649
650end
651