src/HOL/Tools/SMT/smt_translate.ML
changeset 47533 5afe54e05406
parent 46529 a018d542e0ae
equal deleted inserted replaced
47532:8e1a120ed492 47533:5afe54e05406
   348     @{lemma "P = True == P" by (rule eq_reflection) simp},
   348     @{lemma "P = True == P" by (rule eq_reflection) simp},
   349     @{lemma "if P then True else False == P" by (rule eq_reflection) simp}]
   349     @{lemma "if P then True else False == P" by (rule eq_reflection) simp}]
   350 
   350 
   351   fun as_term t = @{const HOL.eq (bool)} $ t $ @{const SMT.term_true}
   351   fun as_term t = @{const HOL.eq (bool)} $ t $ @{const SMT.term_true}
   352 
   352 
   353   fun wrap_in_if t =
   353   exception BAD_PATTERN of unit
   354     @{const If (bool)} $ t $ @{const SMT.term_true} $ @{const SMT.term_false}
   354 
       
   355   fun wrap_in_if pat t =
       
   356     if pat then
       
   357       raise BAD_PATTERN ()
       
   358     else
       
   359       @{const If (bool)} $ t $ @{const SMT.term_true} $ @{const SMT.term_false}
   355 
   360 
   356   fun is_builtin_conn_or_pred ctxt c ts =
   361   fun is_builtin_conn_or_pred ctxt c ts =
   357     is_some (SMT_Builtin.dest_builtin_conn ctxt c ts) orelse
   362     is_some (SMT_Builtin.dest_builtin_conn ctxt c ts) orelse
   358     is_some (SMT_Builtin.dest_builtin_pred ctxt c ts)
   363     is_some (SMT_Builtin.dest_builtin_pred ctxt c ts)
   359 
   364 
   366     | _ => b ctxt c ts)
   371     | _ => b ctxt c ts)
   367 in
   372 in
   368 
   373 
   369 fun folify ctxt =
   374 fun folify ctxt =
   370   let
   375   let
   371     fun in_list T f t = HOLogic.mk_list T (map f (HOLogic.dest_list t))
   376     fun in_list T f t = HOLogic.mk_list T (map_filter f (HOLogic.dest_list t))
   372 
   377 
   373     fun in_term t =
   378     fun in_term pat t =
   374       (case Term.strip_comb t of
   379       (case Term.strip_comb t of
   375         (@{const True}, []) => @{const SMT.term_true}
   380         (@{const True}, []) => @{const SMT.term_true}
   376       | (@{const False}, []) => @{const SMT.term_false}
   381       | (@{const False}, []) => @{const SMT.term_false}
   377       | (u as Const (@{const_name If}, _), [t1, t2, t3]) =>
   382       | (u as Const (@{const_name If}, _), [t1, t2, t3]) =>
   378           u $ in_form t1 $ in_term t2 $ in_term t3
   383           if pat then raise BAD_PATTERN ()
       
   384           else u $ in_form t1 $ in_term pat t2 $ in_term pat t3
   379       | (Const (c as (n, _)), ts) =>
   385       | (Const (c as (n, _)), ts) =>
   380           if is_builtin_conn_or_pred ctxt c ts then wrap_in_if (in_form t)
   386           if is_builtin_conn_or_pred ctxt c ts then wrap_in_if pat (in_form t)
   381           else  if is_quant n then wrap_in_if (in_form t)
   387           else if is_quant n then wrap_in_if pat (in_form t)
   382           else Term.list_comb (Const c, map in_term ts)
   388           else Term.list_comb (Const c, map (in_term pat) ts)
   383       | (Free c, ts) => Term.list_comb (Free c, map in_term ts)
   389       | (Free c, ts) => Term.list_comb (Free c, map (in_term pat) ts)
   384       | _ => t)
   390       | _ => t)
   385 
   391 
   386     and in_weight ((c as @{const SMT.weight}) $ w $ t) = c $ w $ in_form t
   392     and in_weight ((c as @{const SMT.weight}) $ w $ t) = c $ w $ in_form t
   387       | in_weight t = in_form t 
   393       | in_weight t = in_form t 
   388 
   394 
   389     and in_pat ((p as Const (@{const_name SMT.pat}, _)) $ t) = p $ in_term t
   395     and in_pat ((p as Const (@{const_name SMT.pat}, _)) $ t) =
   390       | in_pat ((p as Const (@{const_name SMT.nopat}, _)) $ t) = p $ in_term t
   396           p $ in_term true t
       
   397       | in_pat ((p as Const (@{const_name SMT.nopat}, _)) $ t) =
       
   398           p $ in_term true t
   391       | in_pat t = raise TERM ("bad pattern", [t])
   399       | in_pat t = raise TERM ("bad pattern", [t])
   392 
   400 
   393     and in_pats ps =
   401     and in_pats ps =
   394       in_list @{typ "SMT.pattern list"} (in_list @{typ SMT.pattern} in_pat) ps
   402       in_list @{typ "SMT.pattern list"}
       
   403         (SOME o in_list @{typ SMT.pattern} (try in_pat)) ps
   395 
   404 
   396     and in_trigger ((c as @{const SMT.trigger}) $ p $ t) =
   405     and in_trigger ((c as @{const SMT.trigger}) $ p $ t) =
   397           c $ in_pats p $ in_weight t
   406           c $ in_pats p $ in_weight t
   398       | in_trigger t = in_weight t
   407       | in_trigger t = in_weight t
   399 
   408 
   400     and in_form t =
   409     and in_form t =
   401       (case Term.strip_comb t of
   410       (case Term.strip_comb t of
   402         (q as Const (qn, _), [Abs (n, T, u)]) =>
   411         (q as Const (qn, _), [Abs (n, T, u)]) =>
   403           if is_quant qn then q $ Abs (n, T, in_trigger u)
   412           if is_quant qn then q $ Abs (n, T, in_trigger u)
   404           else as_term (in_term t)
   413           else as_term (in_term false t)
   405       | (Const c, ts) =>
   414       | (Const c, ts) =>
   406           (case SMT_Builtin.dest_builtin_conn ctxt c ts of
   415           (case SMT_Builtin.dest_builtin_conn ctxt c ts of
   407             SOME (_, _, us, mk) => mk (map in_form us)
   416             SOME (_, _, us, mk) => mk (map in_form us)
   408           | NONE =>
   417           | NONE =>
   409               (case SMT_Builtin.dest_builtin_pred ctxt c ts of
   418               (case SMT_Builtin.dest_builtin_pred ctxt c ts of
   410                 SOME (_, _, us, mk) => mk (map in_term us)
   419                 SOME (_, _, us, mk) => mk (map (in_term false) us)
   411               | NONE => as_term (in_term t)))
   420               | NONE => as_term (in_term false t)))
   412       | _ => as_term (in_term t))
   421       | _ => as_term (in_term false t))
   413   in
   422   in
   414     map in_form #>
   423     map in_form #>
   415     cons (SMT_Utils.prop_of term_bool) #>
   424     cons (SMT_Utils.prop_of term_bool) #>
   416     pair (fol_rules, [term_bool], builtin)
   425     pair (fol_rules, [term_bool], builtin)
   417   end
   426   end