src/HOL/Tools/refute.ML
changeset 41471 54a58904a598
parent 40720 b770df486e5c
child 41472 f6ab14e61604
equal deleted inserted replaced
41470:890b25753bf7 41471:54a58904a598
    75 end;
    75 end;
    76 
    76 
    77 structure Refute : REFUTE =
    77 structure Refute : REFUTE =
    78 struct
    78 struct
    79 
    79 
    80 open PropLogic;
    80 open Prop_Logic;
    81 
    81 
    82 (* We use 'REFUTE' only for internal error conditions that should    *)
    82 (* We use 'REFUTE' only for internal error conditions that should    *)
    83 (* never occur in the first place (i.e. errors caused by bugs in our *)
    83 (* never occur in the first place (i.e. errors caused by bugs in our *)
    84 (* code).  Otherwise (e.g. to indicate invalid input data) we use    *)
    84 (* code).  Otherwise (e.g. to indicate invalid input data) we use    *)
    85 (* 'error'.                                                          *)
    85 (* 'error'.                                                          *)
  1116                   wellformed = #wellformed a'}))
  1116                   wellformed = #wellformed a'}))
  1117               end) (u :: axioms) (init_model, init_args)
  1117               end) (u :: axioms) (init_model, init_args)
  1118             (* make 'u' either true or false, and make all axioms true, and *)
  1118             (* make 'u' either true or false, and make all axioms true, and *)
  1119             (* add the well-formedness side condition                       *)
  1119             (* add the well-formedness side condition                       *)
  1120             val fm_u = (if negate then toFalse else toTrue) (hd intrs)
  1120             val fm_u = (if negate then toFalse else toTrue) (hd intrs)
  1121             val fm_ax = PropLogic.all (map toTrue (tl intrs))
  1121             val fm_ax = Prop_Logic.all (map toTrue (tl intrs))
  1122             val fm = PropLogic.all [#wellformed args, fm_ax, fm_u]
  1122             val fm = Prop_Logic.all [#wellformed args, fm_ax, fm_u]
  1123             val _ =
  1123             val _ =
  1124               (if satsolver = "dpll" orelse satsolver = "enumerate" then
  1124               (if satsolver = "dpll" orelse satsolver = "enumerate" then
  1125                 warning ("Using SAT solver " ^ quote satsolver ^
  1125                 warning ("Using SAT solver " ^ quote satsolver ^
  1126                          "; for better performance, consider installing an \
  1126                          "; for better performance, consider installing an \
  1127                          \external solver.")
  1127                          \external solver.")
  1392     (* interpretation * interpretation -> prop_formula *)
  1392     (* interpretation * interpretation -> prop_formula *)
  1393     fun equal (i1, i2) =
  1393     fun equal (i1, i2) =
  1394       (case i1 of
  1394       (case i1 of
  1395         Leaf xs =>
  1395         Leaf xs =>
  1396           (case i2 of
  1396           (case i2 of
  1397             Leaf ys => PropLogic.dot_product (xs, ys)  (* defined and equal *)
  1397             Leaf ys => Prop_Logic.dot_product (xs, ys)  (* defined and equal *)
  1398           | Node _  => raise REFUTE ("make_equality",
  1398           | Node _  => raise REFUTE ("make_equality",
  1399             "second interpretation is higher"))
  1399             "second interpretation is higher"))
  1400       | Node xs =>
  1400       | Node xs =>
  1401           (case i2 of
  1401           (case i2 of
  1402             Leaf _  => raise REFUTE ("make_equality",
  1402             Leaf _  => raise REFUTE ("make_equality",
  1403             "first interpretation is higher")
  1403             "first interpretation is higher")
  1404           | Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1404           | Node ys => Prop_Logic.all (map equal (xs ~~ ys))))
  1405     (* interpretation * interpretation -> prop_formula *)
  1405     (* interpretation * interpretation -> prop_formula *)
  1406     fun not_equal (i1, i2) =
  1406     fun not_equal (i1, i2) =
  1407       (case i1 of
  1407       (case i1 of
  1408         Leaf xs =>
  1408         Leaf xs =>
  1409           (case i2 of
  1409           (case i2 of
  1410             (* defined and not equal *)
  1410             (* defined and not equal *)
  1411             Leaf ys => PropLogic.all ((PropLogic.exists xs)
  1411             Leaf ys => Prop_Logic.all ((Prop_Logic.exists xs)
  1412             :: (PropLogic.exists ys)
  1412             :: (Prop_Logic.exists ys)
  1413             :: (map (fn (x,y) => SOr (SNot x, SNot y)) (xs ~~ ys)))
  1413             :: (map (fn (x,y) => SOr (SNot x, SNot y)) (xs ~~ ys)))
  1414           | Node _  => raise REFUTE ("make_equality",
  1414           | Node _  => raise REFUTE ("make_equality",
  1415             "second interpretation is higher"))
  1415             "second interpretation is higher"))
  1416       | Node xs =>
  1416       | Node xs =>
  1417           (case i2 of
  1417           (case i2 of
  1418             Leaf _  => raise REFUTE ("make_equality",
  1418             Leaf _  => raise REFUTE ("make_equality",
  1419             "first interpretation is higher")
  1419             "first interpretation is higher")
  1420           | Node ys => PropLogic.exists (map not_equal (xs ~~ ys))))
  1420           | Node ys => Prop_Logic.exists (map not_equal (xs ~~ ys))))
  1421   in
  1421   in
  1422     (* a value may be undefined; therefore 'not_equal' is not just the *)
  1422     (* a value may be undefined; therefore 'not_equal' is not just the *)
  1423     (* negation of 'equal'                                             *)
  1423     (* negation of 'equal'                                             *)
  1424     Leaf [equal (i1, i2), not_equal (i1, i2)]
  1424     Leaf [equal (i1, i2), not_equal (i1, i2)]
  1425   end;
  1425   end;
  1441     fun equal (i1, i2) =
  1441     fun equal (i1, i2) =
  1442       (case i1 of
  1442       (case i1 of
  1443         Leaf xs =>
  1443         Leaf xs =>
  1444           (case i2 of
  1444           (case i2 of
  1445             (* defined and equal, or both undefined *)
  1445             (* defined and equal, or both undefined *)
  1446             Leaf ys => SOr (PropLogic.dot_product (xs, ys),
  1446             Leaf ys => SOr (Prop_Logic.dot_product (xs, ys),
  1447             SAnd (PropLogic.all (map SNot xs), PropLogic.all (map SNot ys)))
  1447             SAnd (Prop_Logic.all (map SNot xs), Prop_Logic.all (map SNot ys)))
  1448           | Node _  => raise REFUTE ("make_def_equality",
  1448           | Node _  => raise REFUTE ("make_def_equality",
  1449             "second interpretation is higher"))
  1449             "second interpretation is higher"))
  1450       | Node xs =>
  1450       | Node xs =>
  1451           (case i2 of
  1451           (case i2 of
  1452             Leaf _  => raise REFUTE ("make_def_equality",
  1452             Leaf _  => raise REFUTE ("make_def_equality",
  1453             "first interpretation is higher")
  1453             "first interpretation is higher")
  1454           | Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1454           | Node ys => Prop_Logic.all (map equal (xs ~~ ys))))
  1455     (* interpretation *)
  1455     (* interpretation *)
  1456     val eq = equal (i1, i2)
  1456     val eq = equal (i1, i2)
  1457   in
  1457   in
  1458     Leaf [eq, SNot eq]
  1458     Leaf [eq, SNot eq]
  1459   end;
  1459   end;
  1497           end
  1497           end
  1498       | pick_all _ = raise REFUTE ("interpretation_apply", "empty list (in pick_all)")
  1498       | pick_all _ = raise REFUTE ("interpretation_apply", "empty list (in pick_all)")
  1499     (* interpretation -> prop_formula list *)
  1499     (* interpretation -> prop_formula list *)
  1500     fun interpretation_to_prop_formula_list (Leaf xs) = xs
  1500     fun interpretation_to_prop_formula_list (Leaf xs) = xs
  1501       | interpretation_to_prop_formula_list (Node trees) =
  1501       | interpretation_to_prop_formula_list (Node trees) =
  1502           map PropLogic.all (pick_all
  1502           map Prop_Logic.all (pick_all
  1503             (map interpretation_to_prop_formula_list trees))
  1503             (map interpretation_to_prop_formula_list trees))
  1504   in
  1504   in
  1505     case i1 of
  1505     case i1 of
  1506       Leaf _ =>
  1506       Leaf _ =>
  1507         raise REFUTE ("interpretation_apply", "first interpretation is a leaf")
  1507         raise REFUTE ("interpretation_apply", "first interpretation is a leaf")
  1569             val fms  = map BoolVar (next_idx upto (next_idx + size - 1))
  1569             val fms  = map BoolVar (next_idx upto (next_idx + size - 1))
  1570             (* interpretation *)
  1570             (* interpretation *)
  1571             val intr = Leaf fms
  1571             val intr = Leaf fms
  1572             (* prop_formula list -> prop_formula *)
  1572             (* prop_formula list -> prop_formula *)
  1573             fun one_of_two_false [] = True
  1573             fun one_of_two_false [] = True
  1574               | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' =>
  1574               | one_of_two_false (x::xs) = SAnd (Prop_Logic.all (map (fn x' =>
  1575                   SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1575                   SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1576             (* prop_formula *)
  1576             (* prop_formula *)
  1577             val wf = one_of_two_false fms
  1577             val wf = one_of_two_false fms
  1578           in
  1578           in
  1579             (* extend the model, increase 'next_idx', add well-formedness *)
  1579             (* extend the model, increase 'next_idx', add well-formedness *)
  1670       in
  1670       in
  1671         case i of
  1671         case i of
  1672           Node xs =>
  1672           Node xs =>
  1673             (* 3-valued logic *)
  1673             (* 3-valued logic *)
  1674             let
  1674             let
  1675               val fmTrue  = PropLogic.all (map toTrue xs)
  1675               val fmTrue  = Prop_Logic.all (map toTrue xs)
  1676               val fmFalse = PropLogic.exists (map toFalse xs)
  1676               val fmFalse = Prop_Logic.exists (map toFalse xs)
  1677             in
  1677             in
  1678               SOME (Leaf [fmTrue, fmFalse], m, a)
  1678               SOME (Leaf [fmTrue, fmFalse], m, a)
  1679             end
  1679             end
  1680         | _ =>
  1680         | _ =>
  1681           raise REFUTE ("Pure_interpreter",
  1681           raise REFUTE ("Pure_interpreter",
  1699   | Const (@{const_name "==>"}, _) $ t1 $ t2 =>
  1699   | Const (@{const_name "==>"}, _) $ t1 $ t2 =>
  1700       (* 3-valued logic *)
  1700       (* 3-valued logic *)
  1701       let
  1701       let
  1702         val (i1, m1, a1) = interpret ctxt model args t1
  1702         val (i1, m1, a1) = interpret ctxt model args t1
  1703         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1703         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1704         val fmTrue       = PropLogic.SOr (toFalse i1, toTrue i2)
  1704         val fmTrue = Prop_Logic.SOr (toFalse i1, toTrue i2)
  1705         val fmFalse      = PropLogic.SAnd (toTrue i1, toFalse i2)
  1705         val fmFalse = Prop_Logic.SAnd (toTrue i1, toFalse i2)
  1706       in
  1706       in
  1707         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1707         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1708       end
  1708       end
  1709   | Const (@{const_name "==>"}, _) $ t1 =>
  1709   | Const (@{const_name "==>"}, _) $ t1 =>
  1710       SOME (interpret ctxt model args (eta_expand t 1))
  1710       SOME (interpret ctxt model args (eta_expand t 1))
  1733       in
  1733       in
  1734         case i of
  1734         case i of
  1735           Node xs =>
  1735           Node xs =>
  1736             (* 3-valued logic *)
  1736             (* 3-valued logic *)
  1737             let
  1737             let
  1738               val fmTrue  = PropLogic.all (map toTrue xs)
  1738               val fmTrue = Prop_Logic.all (map toTrue xs)
  1739               val fmFalse = PropLogic.exists (map toFalse xs)
  1739               val fmFalse = Prop_Logic.exists (map toFalse xs)
  1740             in
  1740             in
  1741               SOME (Leaf [fmTrue, fmFalse], m, a)
  1741               SOME (Leaf [fmTrue, fmFalse], m, a)
  1742             end
  1742             end
  1743         | _ =>
  1743         | _ =>
  1744           raise REFUTE ("HOLogic_interpreter",
  1744           raise REFUTE ("HOLogic_interpreter",
  1752       in
  1752       in
  1753         case i of
  1753         case i of
  1754           Node xs =>
  1754           Node xs =>
  1755             (* 3-valued logic *)
  1755             (* 3-valued logic *)
  1756             let
  1756             let
  1757               val fmTrue  = PropLogic.exists (map toTrue xs)
  1757               val fmTrue = Prop_Logic.exists (map toTrue xs)
  1758               val fmFalse = PropLogic.all (map toFalse xs)
  1758               val fmFalse = Prop_Logic.all (map toFalse xs)
  1759             in
  1759             in
  1760               SOME (Leaf [fmTrue, fmFalse], m, a)
  1760               SOME (Leaf [fmTrue, fmFalse], m, a)
  1761             end
  1761             end
  1762         | _ =>
  1762         | _ =>
  1763           raise REFUTE ("HOLogic_interpreter",
  1763           raise REFUTE ("HOLogic_interpreter",
  1779   | Const (@{const_name HOL.conj}, _) $ t1 $ t2 =>
  1779   | Const (@{const_name HOL.conj}, _) $ t1 $ t2 =>
  1780       (* 3-valued logic *)
  1780       (* 3-valued logic *)
  1781       let
  1781       let
  1782         val (i1, m1, a1) = interpret ctxt model args t1
  1782         val (i1, m1, a1) = interpret ctxt model args t1
  1783         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1783         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1784         val fmTrue       = PropLogic.SAnd (toTrue i1, toTrue i2)
  1784         val fmTrue = Prop_Logic.SAnd (toTrue i1, toTrue i2)
  1785         val fmFalse      = PropLogic.SOr (toFalse i1, toFalse i2)
  1785         val fmFalse = Prop_Logic.SOr (toFalse i1, toFalse i2)
  1786       in
  1786       in
  1787         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1787         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1788       end
  1788       end
  1789   | Const (@{const_name HOL.conj}, _) $ t1 =>
  1789   | Const (@{const_name HOL.conj}, _) $ t1 =>
  1790       SOME (interpret ctxt model args (eta_expand t 1))
  1790       SOME (interpret ctxt model args (eta_expand t 1))
  1796   | Const (@{const_name HOL.disj}, _) $ t1 $ t2 =>
  1796   | Const (@{const_name HOL.disj}, _) $ t1 $ t2 =>
  1797       (* 3-valued logic *)
  1797       (* 3-valued logic *)
  1798       let
  1798       let
  1799         val (i1, m1, a1) = interpret ctxt model args t1
  1799         val (i1, m1, a1) = interpret ctxt model args t1
  1800         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1800         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1801         val fmTrue       = PropLogic.SOr (toTrue i1, toTrue i2)
  1801         val fmTrue = Prop_Logic.SOr (toTrue i1, toTrue i2)
  1802         val fmFalse      = PropLogic.SAnd (toFalse i1, toFalse i2)
  1802         val fmFalse = Prop_Logic.SAnd (toFalse i1, toFalse i2)
  1803       in
  1803       in
  1804         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1804         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1805       end
  1805       end
  1806   | Const (@{const_name HOL.disj}, _) $ t1 =>
  1806   | Const (@{const_name HOL.disj}, _) $ t1 =>
  1807       SOME (interpret ctxt model args (eta_expand t 1))
  1807       SOME (interpret ctxt model args (eta_expand t 1))
  1813   | Const (@{const_name HOL.implies}, _) $ t1 $ t2 =>  (* similar to "==>" (Pure) *)
  1813   | Const (@{const_name HOL.implies}, _) $ t1 $ t2 =>  (* similar to "==>" (Pure) *)
  1814       (* 3-valued logic *)
  1814       (* 3-valued logic *)
  1815       let
  1815       let
  1816         val (i1, m1, a1) = interpret ctxt model args t1
  1816         val (i1, m1, a1) = interpret ctxt model args t1
  1817         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1817         val (i2, m2, a2) = interpret ctxt m1 a1 t2
  1818         val fmTrue       = PropLogic.SOr (toFalse i1, toTrue i2)
  1818         val fmTrue = Prop_Logic.SOr (toFalse i1, toTrue i2)
  1819         val fmFalse      = PropLogic.SAnd (toTrue i1, toFalse i2)
  1819         val fmFalse = Prop_Logic.SAnd (toTrue i1, toFalse i2)
  1820       in
  1820       in
  1821         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1821         SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1822       end
  1822       end
  1823   | Const (@{const_name HOL.implies}, _) $ t1 =>
  1823   | Const (@{const_name HOL.implies}, _) $ t1 =>
  1824       SOME (interpret ctxt model args (eta_expand t 1))
  1824       SOME (interpret ctxt model args (eta_expand t 1))
  1888                     val fms      = map BoolVar (next_idx upto (next_idx+size-1))
  1888                     val fms      = map BoolVar (next_idx upto (next_idx+size-1))
  1889                     (* interpretation *)
  1889                     (* interpretation *)
  1890                     val intr     = Leaf fms
  1890                     val intr     = Leaf fms
  1891                     (* prop_formula list -> prop_formula *)
  1891                     (* prop_formula list -> prop_formula *)
  1892                     fun one_of_two_false [] = True
  1892                     fun one_of_two_false [] = True
  1893                       | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' =>
  1893                       | one_of_two_false (x::xs) = SAnd (Prop_Logic.all (map (fn x' =>
  1894                           SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1894                           SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1895                     (* prop_formula *)
  1895                     (* prop_formula *)
  1896                     val wf = one_of_two_false fms
  1896                     val wf = one_of_two_false fms
  1897                   in
  1897                   in
  1898                     (* extend the model, increase 'next_idx', add well-formedness *)
  1898                     (* extend the model, increase 'next_idx', add well-formedness *)
  2959       | string_of_typ (TFree (x, _)) = strip_leading_quote x
  2959       | string_of_typ (TFree (x, _)) = strip_leading_quote x
  2960       | string_of_typ (TVar ((x,i), _)) =
  2960       | string_of_typ (TVar ((x,i), _)) =
  2961           strip_leading_quote x ^ string_of_int i
  2961           strip_leading_quote x ^ string_of_int i
  2962     (* interpretation -> int *)
  2962     (* interpretation -> int *)
  2963     fun index_from_interpretation (Leaf xs) =
  2963     fun index_from_interpretation (Leaf xs) =
  2964           find_index (PropLogic.eval assignment) xs
  2964           find_index (Prop_Logic.eval assignment) xs
  2965       | index_from_interpretation _ =
  2965       | index_from_interpretation _ =
  2966           raise REFUTE ("stlc_printer",
  2966           raise REFUTE ("stlc_printer",
  2967             "interpretation for ground type is not a leaf")
  2967             "interpretation for ground type is not a leaf")
  2968   in
  2968   in
  2969     case T of
  2969     case T of
  3043                     Syntax.string_of_typ ctxt (Type (s, Ts)) ^ ") is not a variable")
  3043                     Syntax.string_of_typ ctxt (Type (s, Ts)) ^ ") is not a variable")
  3044                 else ()
  3044                 else ()
  3045               (* the index of the element in the datatype *)
  3045               (* the index of the element in the datatype *)
  3046               val element =
  3046               val element =
  3047                 (case intr of
  3047                 (case intr of
  3048                   Leaf xs => find_index (PropLogic.eval assignment) xs
  3048                   Leaf xs => find_index (Prop_Logic.eval assignment) xs
  3049                 | Node _  => raise REFUTE ("IDT_printer",
  3049                 | Node _  => raise REFUTE ("IDT_printer",
  3050                   "interpretation is not a leaf"))
  3050                   "interpretation is not a leaf"))
  3051             in
  3051             in
  3052               if element < 0 then
  3052               if element < 0 then
  3053                 SOME (Const (@{const_name undefined}, Type (s, Ts)))
  3053                 SOME (Const (@{const_name undefined}, Type (s, Ts)))