src/HOL/Library/Eval_Witness.thy
author wenzelm
Wed, 03 Nov 2010 11:06:22 +0100
changeset 40316 665862241968
parent 39471 55e0ff582fa4
child 41472 f6ab14e61604
permissions -rw-r--r--
replaced ancient sys_error by raise Fail, assuming that the latter is not handled specifically by the environment;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     1
(*  Title:      HOL/Library/Eval_Witness.thy
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     2
    Author:     Alexander Krauss, TU Muenchen
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     3
*)
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     4
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     5
header {* Evaluation Oracle with ML witnesses *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     6
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     7
theory Eval_Witness
30663
0b6aff7451b2 Main is (Complex_Main) base entry point in library theories
haftmann
parents: 30549
diff changeset
     8
imports List Main
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
     9
begin
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    10
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    11
text {* 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    12
  We provide an oracle method similar to "eval", but with the
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    13
  possibility to provide ML values as witnesses for existential
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    14
  statements.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    15
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    16
  Our oracle can prove statements of the form @{term "EX x. P x"}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    17
  where @{term "P"} is an executable predicate that can be compiled to
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    18
  ML. The oracle generates code for @{term "P"} and applies
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    19
  it to a user-specified ML value. If the evaluation
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    20
  returns true, this is effectively a proof of  @{term "EX x. P x"}.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    21
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    22
  However, this is only sound if for every ML value of the given type
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    23
  there exists a corresponding HOL value, which could be used in an
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    24
  explicit proof. Unfortunately this is not true for function types,
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    25
  since ML functions are not equivalent to the pure HOL
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    26
  functions. Thus, the oracle can only be used on first-order
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    27
  types.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    28
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    29
  We define a type class to mark types that can be safely used
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    30
  with the oracle.  
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    31
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    32
29608
564ea783ace8 no base sort in class import
haftmann
parents: 28290
diff changeset
    33
class ml_equiv
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    34
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    35
text {*
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    36
  Instances of @{text "ml_equiv"} should only be declared for those types,
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    37
  where the universe of ML values coincides with the HOL values.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    38
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    39
  Since this is essentially a statement about ML, there is no
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    40
  logical characterization.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    41
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    42
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    43
instance nat :: ml_equiv .. (* Attention: This conflicts with the "EfficientNat" theory *)
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    44
instance bool :: ml_equiv ..
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    45
instance list :: (ml_equiv) ml_equiv ..
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    46
39471
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    47
ML {*
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    48
structure Eval_Method = Proof_Data (
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    49
  type T = unit -> bool
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    50
  fun init _ () = error "Eval_Method"
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    51
)
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    52
*}
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    53
28290
4cc2b6046258 simplified oracle interface;
wenzelm
parents: 28054
diff changeset
    54
oracle eval_witness_oracle = {* fn (cgoal, ws) =>
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    55
let
28290
4cc2b6046258 simplified oracle interface;
wenzelm
parents: 28054
diff changeset
    56
  val thy = Thm.theory_of_cterm cgoal;
4cc2b6046258 simplified oracle interface;
wenzelm
parents: 28054
diff changeset
    57
  val goal = Thm.term_of cgoal;
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    58
  fun check_type T = 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    59
    if Sorts.of_sort (Sign.classes_of thy) (T, ["Eval_Witness.ml_equiv"])
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    60
    then T
26939
1035c89b4c02 moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents: 26114
diff changeset
    61
    else error ("Type " ^ quote (Syntax.string_of_typ_global thy T) ^ " not allowed for ML witnesses")
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    62
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    63
  fun dest_exs  0 t = t
38558
32ad17fe2b9c tuned quotes
haftmann
parents: 38549
diff changeset
    64
    | dest_exs n (Const (@{const_name Ex}, _) $ Abs (v,T,b)) = 
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    65
      Abs (v, check_type T, dest_exs (n - 1) b)
40316
665862241968 replaced ancient sys_error by raise Fail, assuming that the latter is not handled specifically by the environment;
wenzelm
parents: 39471
diff changeset
    66
    | dest_exs _ _ = raise Fail "dest_exs";
24835
8c26128f8997 clarified relationship of code generator conversions and evaluations
haftmann
parents: 24281
diff changeset
    67
  val t = dest_exs (length ws) (HOLogic.dest_Trueprop goal);
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    68
in
39471
55e0ff582fa4 adjusted to changes in Code_Runtime
haftmann
parents: 39403
diff changeset
    69
  if Code_Runtime.dynamic_value_strict (Eval_Method.get, Eval_Method.put, "Eval_Method.put") thy NONE (K I) t ws
28290
4cc2b6046258 simplified oracle interface;
wenzelm
parents: 28054
diff changeset
    70
  then Thm.cterm_of thy goal
4cc2b6046258 simplified oracle interface;
wenzelm
parents: 28054
diff changeset
    71
  else @{cprop True} (*dummy*)
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    72
end
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    73
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    74
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    75
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    76
method_setup eval_witness = {*
30549
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
    77
  Scan.lift (Scan.repeat Args.name) >>
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
    78
  (fn ws => K (SIMPLE_METHOD'
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
    79
    (CSUBGOAL (fn (ct, i) => rtac (eval_witness_oracle (ct, ws)) i))))
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
    80
*} "evaluation with ML witnesses"
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    81
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    82
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    83
subsection {* Toy Examples *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    84
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    85
text {* 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    86
  Note that we must use the generated data structure for the
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    87
  naturals, since ML integers are different.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    88
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    89
26114
53eb3ff08cce non-operative code antiquotation
haftmann
parents: 25595
diff changeset
    90
(*lemma "\<exists>n::nat. n = 1"
53eb3ff08cce non-operative code antiquotation
haftmann
parents: 25595
diff changeset
    91
apply (eval_witness "Suc Zero_nat")
53eb3ff08cce non-operative code antiquotation
haftmann
parents: 25595
diff changeset
    92
done*)
24281
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    93
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    94
text {* 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    95
  Since polymorphism is not allowed, we must specify the
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    96
  type explicitly:
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    97
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    98
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
    99
lemma "\<exists>l. length (l::bool list) = 3"
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   100
apply (eval_witness "[true,true,true]")
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   101
done
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   102
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   103
text {* Multiple witnesses *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   104
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   105
lemma "\<exists>k l. length (k::bool list) = length (l::bool list)"
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   106
apply (eval_witness "[]" "[]")
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   107
done
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   108
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   109
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   110
subsection {* Discussion *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   111
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   112
subsubsection {* Conflicts *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   113
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   114
text {* 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   115
  This theory conflicts with EfficientNat, since the @{text ml_equiv} instance
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   116
  for natural numbers is not valid when they are mapped to ML
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   117
  integers. With that theory loaded, we could use our oracle to prove
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   118
  @{term "\<exists>n. n < 0"} by providing @{text "~1"} as a witness.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   119
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   120
  This shows that @{text ml_equiv} declarations have to be used with care,
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   121
  taking the configuration of the code generator into account.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   122
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   123
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   124
subsubsection {* Haskell *}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   125
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   126
text {*
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   127
  If we were able to run generated Haskell code, the situation would
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   128
  be much nicer, since Haskell functions are pure and could be used as
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   129
  witnesses for HOL functions: Although Haskell functions are partial,
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   130
  we know that if the evaluation terminates, they are ``sufficiently
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   131
  defined'' and could be completed arbitrarily to a total (HOL) function.
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   132
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   133
  This would allow us to provide access to very efficient data
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   134
  structures via lookup functions coded in Haskell and provided to HOL
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   135
  as witnesses. 
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   136
*}
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   137
7d0334b69711 added Eval_Witness theory
haftmann
parents:
diff changeset
   138
end