src/HOL/ex/coopereif.ML
author chaieb
Mon, 11 Jun 2007 11:06:13 +0200
changeset 23317 90be000da2a7
parent 23274 f997514ad8f4
child 23515 3e7f62e68fe4
permissions -rw-r--r--
Temporarily use int instead of IntInf.int but Code generator should map HOL's int to ML's IntInf.int --- To be fixed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23274
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     1
(* $Id$ *)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     2
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     3
(* Reification for the autimatically generated oracle for Presburger arithmetic 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     4
   in HOL/ex/Reflected_Presburger.thy 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     5
 Author : Amine Chaieb
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     6
*)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     7
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     8
structure Coopereif =
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
     9
struct
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    10
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    11
open GeneratedCooper;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    12
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    13
fun i_of_term vs t = 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    14
    case t of
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    15
	Free(xn,xT) => (case AList.lookup (op aconv) vs t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    16
			   NONE   => error "Variable not found in the list!!"
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    17
			 | SOME n => Bound n)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    18
      | @{term "0::int"} => C 0
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    19
      | @{term "1::int"} => C 1
23317
90be000da2a7 Temporarily use int instead of IntInf.int but Code generator should map HOL's int to ML's IntInf.int --- To be fixed
chaieb
parents: 23274
diff changeset
    20
      | Term.Bound i => Bound (nat i)
23274
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    21
      | Const(@{const_name "HOL.uminus"},_)$t' => Neg (i_of_term vs t')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    22
      | Const(@{const_name "HOL.plus"},_)$t1$t2 => Add (i_of_term vs t1,i_of_term vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    23
      | Const(@{const_name "HOL.minus"},_)$t1$t2 => Sub (i_of_term vs t1,i_of_term vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    24
      | Const(@{const_name "HOL.times"},_)$t1$t2 => 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    25
	     (Mul (HOLogic.dest_number t1 |> snd,i_of_term vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    26
        handle TERM _ => 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    27
           (Mul (HOLogic.dest_number t2 |> snd,i_of_term vs t1)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    28
            handle TERM _ => error "i_of_term: Unsupported kind of multiplication"))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    29
      | _ => (C (HOLogic.dest_number t |> snd) 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    30
               handle TERM _ => error "i_of_term: unknown term");
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    31
	
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    32
fun qf_of_term ps vs t = 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    33
    case t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    34
	Const("True",_) => T
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    35
      | Const("False",_) => F
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    36
      | Const(@{const_name "Orderings.less"},_)$t1$t2 => Lt (Sub (i_of_term vs t1,i_of_term vs t2))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    37
      | Const(@{const_name "Orderings.less_eq"},_)$t1$t2 => Le (Sub(i_of_term vs t1,i_of_term vs t2))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    38
      | Const(@{const_name "Divides.dvd"},_)$t1$t2 => 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    39
	(Dvd(HOLogic.dest_number t1 |> snd, i_of_term vs t2) handle _ => error "qf_of_term: unsupported dvd")
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    40
      | @{term "op = :: int => _"}$t1$t2 => Eq (Sub (i_of_term vs t1,i_of_term vs t2))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    41
      | @{term "op = :: bool => _ "}$t1$t2 => Iff(qf_of_term ps vs t1,qf_of_term ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    42
      | Const("op &",_)$t1$t2 => And(qf_of_term ps vs t1,qf_of_term ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    43
      | Const("op |",_)$t1$t2 => Or(qf_of_term ps vs t1,qf_of_term ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    44
      | Const("op -->",_)$t1$t2 => Imp(qf_of_term ps vs t1,qf_of_term ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    45
      | Const("Not",_)$t' => NOT(qf_of_term ps vs t')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    46
      | Const("Ex",_)$Abs(xn,xT,p) => 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    47
         let val (xn',p') = variant_abs (xn,xT,p)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    48
             val vs' = (Free (xn',xT), nat 0) :: (map (fn(v,n) => (v,1 + n)) vs)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    49
         in E (qf_of_term ps vs' p')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    50
         end
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    51
      | Const("All",_)$Abs(xn,xT,p) => 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    52
         let val (xn',p') = variant_abs (xn,xT,p)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    53
             val vs' = (Free (xn',xT), nat 0) :: (map (fn(v,n) => (v,1 + n)) vs)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    54
         in A (qf_of_term ps vs' p')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    55
         end
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    56
      | _ =>(case AList.lookup (op aconv) ps t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    57
               NONE => error "qf_of_term ps : unknown term!"
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    58
             | SOME n => Closed n);
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    59
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    60
local
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    61
 val ops = [@{term "op &"}, @{term "op |"}, @{term "op -->"}, @{term "op = :: bool => _"},
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    62
             @{term "op = :: int => _"}, @{term "op < :: int => _"}, 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    63
             @{term "op <= :: int => _"}, @{term "Not"}, @{term "All:: (int => _) => _"}, 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    64
             @{term "Ex:: (int => _) => _"}, @{term "True"}, @{term "False"}]
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    65
fun ty t = Bool.not (fastype_of t = HOLogic.boolT)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    66
in
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    67
fun term_bools acc t =
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    68
case t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    69
    (l as f $ a) $ b => if ty t orelse f mem ops then term_bools (term_bools acc l)b 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    70
            else insert (op aconv) t acc
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    71
  | f $ a => if ty t orelse f mem ops then term_bools (term_bools acc f) a  
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    72
            else insert (op aconv) t acc
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    73
  | Abs p => term_bools acc (snd (variant_abs p))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    74
  | _ => if ty t orelse t mem ops then acc else insert (op aconv) t acc
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    75
end;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    76
 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    77
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    78
fun start_vs t =
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    79
let
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    80
 val fs = term_frees t
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    81
 val ps = term_bools [] t
23317
90be000da2a7 Temporarily use int instead of IntInf.int but Code generator should map HOL's int to ML's IntInf.int --- To be fixed
chaieb
parents: 23274
diff changeset
    82
in (fs ~~ (map nat (0 upto  (length fs - 1))),
90be000da2a7 Temporarily use int instead of IntInf.int but Code generator should map HOL's int to ML's IntInf.int --- To be fixed
chaieb
parents: 23274
diff changeset
    83
    ps ~~ (map nat (0 upto  (length ps - 1))))
23274
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    84
end ;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    85
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    86
val iT = HOLogic.intT;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    87
val bT = HOLogic.boolT;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    88
fun myassoc2 l v =
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    89
    case l of
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    90
	[] => NONE
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    91
      | (x,v')::xs => if v = v' then SOME x
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    92
		      else myassoc2 xs v;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    93
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    94
fun term_of_i vs t =
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    95
    case t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    96
	C i => HOLogic.mk_number HOLogic.intT i
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    97
      | Bound n => valOf (myassoc2 vs n)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    98
      | Neg t' => @{term "uminus :: int => _"}$(term_of_i vs t')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
    99
      | Add(t1,t2) => @{term "op +:: int => _"}$ (term_of_i vs t1)$(term_of_i vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   100
      | Sub(t1,t2) => Const(@{const_name "HOL.minus"},[iT,iT] ---> iT)$
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   101
			   (term_of_i vs t1)$(term_of_i vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   102
      | Mul(i,t2) => Const(@{const_name "HOL.times"},[iT,iT] ---> iT)$
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   103
			   (HOLogic.mk_number HOLogic.intT i)$(term_of_i vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   104
      | CX(i,t')=> term_of_i vs (Add(Mul (i,Bound (nat 0)),t'));
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   105
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   106
fun term_of_qf ps vs t = 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   107
 case t of 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   108
   T => HOLogic.true_const 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   109
 | F => HOLogic.false_const
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   110
 | Lt t' => @{term "op < :: int => _ "}$ term_of_i vs t'$ @{term "0::int"}
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   111
 | Le t' => @{term "op <= :: int => _ "}$ term_of_i vs t' $ @{term "0::int"}
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   112
 | Gt t' => @{term "op < :: int => _ "}$ @{term "0::int"}$ term_of_i vs t'
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   113
 | Ge t' => @{term "op <= :: int => _ "}$ @{term "0::int"}$ term_of_i vs t'
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   114
 | Eq t' => @{term "op = :: int => _ "}$ term_of_i vs t'$ @{term "0::int"}
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   115
 | NEq t' => term_of_qf ps vs (NOT(Eq t'))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   116
 | Dvd(i,t') => @{term "op dvd :: int => _ "}$ 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   117
                 (HOLogic.mk_number HOLogic.intT i)$(term_of_i vs t')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   118
 | NDvd(i,t')=> term_of_qf ps vs (NOT(Dvd(i,t')))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   119
 | NOT t' => HOLogic.Not$(term_of_qf ps vs t')
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   120
 | And(t1,t2) => HOLogic.conj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   121
 | Or(t1,t2) => HOLogic.disj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   122
 | Imp(t1,t2) => HOLogic.imp$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   123
 | Iff(t1,t2) => (HOLogic.eq_const bT)$(term_of_qf ps vs t1)$ (term_of_qf ps vs t2)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   124
 | Closed n => valOf (myassoc2 ps n)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   125
 | NClosed n => term_of_qf ps vs (NOT (Closed n))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   126
 | _ => error "If this is raised, Isabelle/HOL or generate_code is inconsistent!";
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   127
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   128
(* The oracle *)
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   129
fun cooper_oracle thy t = 
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   130
    let val (vs,ps) = start_vs t
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   131
    in HOLogic.mk_Trueprop (HOLogic.mk_eq (t, term_of_qf ps vs (pa (qf_of_term ps vs t))))
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   132
    end;
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   133
f997514ad8f4 New Reflected Presburger added to HOL/ex
chaieb
parents:
diff changeset
   134
end;