src/HOL/Lattice/Lattice.thy
changeset 10157 6d3987f3aad9
child 10158 00fdd5c330ea
equal deleted inserted replaced
10156:9d4d5852eb47 10157:6d3987f3aad9
       
     1 (*  Title:      HOL/Lattice/Lattice.thy
       
     2     ID:         $Id$
       
     3     Author:     Markus Wenzel, TU Muenchen
       
     4 *)
       
     5 
       
     6 header {* Lattices *}
       
     7 
       
     8 theory Lattice = Bounds:
       
     9 
       
    10 subsection {* Lattice operations *}
       
    11 
       
    12 text {*
       
    13   A \emph{lattice} is a partial order with infimum and supremum of any
       
    14   two elements (thus any \emph{finite} number of elements have bounds
       
    15   as well).
       
    16 *}
       
    17 
       
    18 axclass lattice < partial_order
       
    19   ex_inf: "\<exists>inf. is_inf x y inf"
       
    20   ex_sup: "\<exists>sup. is_sup x y sup"
       
    21 
       
    22 text {*
       
    23   The @{text \<sqinter>} (meet) and @{text \<squnion>} (join) operations select such
       
    24   infimum and supremum elements.
       
    25 *}
       
    26 
       
    27 consts
       
    28   meet :: "'a::lattice \<Rightarrow> 'a \<Rightarrow> 'a"  (infixl "&&" 70)
       
    29   join :: "'a::lattice \<Rightarrow> 'a \<Rightarrow> 'a"  (infixl "||" 65)
       
    30 syntax (symbols)
       
    31   meet :: "'a::lattice \<Rightarrow> 'a \<Rightarrow> 'a"  (infixl "\<sqinter>" 70)
       
    32   join :: "'a::lattice \<Rightarrow> 'a \<Rightarrow> 'a"  (infixl "\<squnion>" 65)
       
    33 defs
       
    34   meet_def: "x && y \<equiv> SOME inf. is_inf x y inf"
       
    35   join_def: "x || y \<equiv> SOME sup. is_sup x y sup"
       
    36 
       
    37 text {*
       
    38   Due to unique existence of bounds, the lattice operations may be
       
    39   exhibited as follows.
       
    40 *}
       
    41 
       
    42 lemma meet_equality [elim?]: "is_inf x y inf \<Longrightarrow> x \<sqinter> y = inf"
       
    43 proof (unfold meet_def)
       
    44   assume "is_inf x y inf"
       
    45   thus "(SOME inf. is_inf x y inf) = inf"
       
    46     by (rule some_equality) (rule is_inf_uniq)
       
    47 qed
       
    48 
       
    49 lemma meetI [intro?]:
       
    50     "inf \<sqsubseteq> x \<Longrightarrow> inf \<sqsubseteq> y \<Longrightarrow> (\<And>z. z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> inf) \<Longrightarrow> x \<sqinter> y = inf"
       
    51   by (rule meet_equality, rule is_infI) blast+
       
    52 
       
    53 lemma join_equality [elim?]: "is_sup x y sup \<Longrightarrow> x \<squnion> y = sup"
       
    54 proof (unfold join_def)
       
    55   assume "is_sup x y sup"
       
    56   thus "(SOME sup. is_sup x y sup) = sup"
       
    57     by (rule some_equality) (rule is_sup_uniq)
       
    58 qed
       
    59 
       
    60 lemma joinI [intro?]: "x \<sqsubseteq> sup \<Longrightarrow> y \<sqsubseteq> sup \<Longrightarrow>
       
    61     (\<And>z. x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> sup \<sqsubseteq> z) \<Longrightarrow> x \<squnion> y = sup"
       
    62   by (rule join_equality, rule is_supI) blast+
       
    63 
       
    64 
       
    65 text {*
       
    66   \medskip The @{text \<sqinter>} and @{text \<squnion>} operations indeed determine
       
    67   bounds on a lattice structure.
       
    68 *}
       
    69 
       
    70 lemma is_inf_meet [intro?]: "is_inf x y (x \<sqinter> y)"
       
    71 proof (unfold meet_def)
       
    72   from ex_inf show "is_inf x y (SOME inf. is_inf x y inf)"
       
    73     by (rule ex_someI)
       
    74 qed
       
    75 
       
    76 lemma meet_greatest [intro?]: "z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> x \<sqinter> y"
       
    77   by (rule is_inf_greatest) (rule is_inf_meet)
       
    78 
       
    79 lemma meet_lower1 [intro?]: "x \<sqinter> y \<sqsubseteq> x"
       
    80   by (rule is_inf_lower) (rule is_inf_meet)
       
    81 
       
    82 lemma meet_lower2 [intro?]: "x \<sqinter> y \<sqsubseteq> y"
       
    83   by (rule is_inf_lower) (rule is_inf_meet)
       
    84 
       
    85 
       
    86 lemma is_sup_join [intro?]: "is_sup x y (x \<squnion> y)"
       
    87 proof (unfold join_def)
       
    88   from ex_sup show "is_sup x y (SOME sup. is_sup x y sup)"
       
    89     by (rule ex_someI)
       
    90 qed
       
    91 
       
    92 lemma join_least [intro?]: "x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<squnion> y \<sqsubseteq> z"
       
    93   by (rule is_sup_least) (rule is_sup_join)
       
    94 
       
    95 lemma join_upper1 [intro?]: "x \<sqsubseteq> x \<squnion> y"
       
    96   by (rule is_sup_upper) (rule is_sup_join)
       
    97 
       
    98 lemma join_upper2 [intro?]: "y \<sqsubseteq> x \<squnion> y"
       
    99   by (rule is_sup_upper) (rule is_sup_join)
       
   100 
       
   101 
       
   102 subsection {* Duality *}
       
   103 
       
   104 text {*
       
   105   The class of lattices is closed under formation of dual structures.
       
   106   This means that for any theorem of lattice theory, the dualized
       
   107   statement holds as well; this important fact simplifies many proofs
       
   108   of lattice theory.
       
   109 *}
       
   110 
       
   111 instance dual :: (lattice) lattice
       
   112 proof intro_classes
       
   113   fix x' y' :: "'a::lattice dual"
       
   114   show "\<exists>inf'. is_inf x' y' inf'"
       
   115   proof -
       
   116     have "\<exists>sup. is_sup (undual x') (undual y') sup" by (rule ex_sup)
       
   117     hence "\<exists>sup. is_inf (dual (undual x')) (dual (undual y')) (dual sup)"
       
   118       by (simp only: dual_inf)
       
   119     thus ?thesis by (simp add: dual_ex [symmetric])
       
   120   qed
       
   121   show "\<exists>sup'. is_sup x' y' sup'"
       
   122   proof -
       
   123     have "\<exists>inf. is_inf (undual x') (undual y') inf" by (rule ex_inf)
       
   124     hence "\<exists>inf. is_sup (dual (undual x')) (dual (undual y')) (dual inf)"
       
   125       by (simp only: dual_sup)
       
   126     thus ?thesis by (simp add: dual_ex [symmetric])
       
   127   qed
       
   128 qed
       
   129 
       
   130 text {*
       
   131   Apparently, the @{text \<sqinter>} and @{text \<squnion>} operations are dual to each
       
   132   other.
       
   133 *}
       
   134 
       
   135 theorem dual_meet [intro?]: "dual (x \<sqinter> y) = dual x \<squnion> dual y"
       
   136 proof -
       
   137   from is_inf_meet have "is_sup (dual x) (dual y) (dual (x \<sqinter> y))" ..
       
   138   hence "dual x \<squnion> dual y = dual (x \<sqinter> y)" ..
       
   139   thus ?thesis ..
       
   140 qed
       
   141 
       
   142 theorem dual_join [intro?]: "dual (x \<squnion> y) = dual x \<sqinter> dual y"
       
   143 proof -
       
   144   from is_sup_join have "is_inf (dual x) (dual y) (dual (x \<squnion> y))" ..
       
   145   hence "dual x \<sqinter> dual y = dual (x \<squnion> y)" ..
       
   146   thus ?thesis ..
       
   147 qed
       
   148 
       
   149 
       
   150 subsection {* Algebraic properties \label{sec:lattice-algebra} *}
       
   151 
       
   152 text {*
       
   153   The @{text \<sqinter>} and @{text \<squnion>} operations have to following
       
   154   characteristic algebraic properties: associative (A), commutative
       
   155   (C), and absorptive (AB).
       
   156 *}
       
   157 
       
   158 theorem meet_assoc: "(x \<sqinter> y) \<sqinter> z = x \<sqinter> (y \<sqinter> z)"
       
   159 proof
       
   160   show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x \<sqinter> y"
       
   161   proof
       
   162     show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x" ..
       
   163     show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y"
       
   164     proof -
       
   165       have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
       
   166       also have "\<dots> \<sqsubseteq> y" ..
       
   167       finally show ?thesis .
       
   168     qed
       
   169   qed
       
   170   show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> z"
       
   171   proof -
       
   172     have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
       
   173     also have "\<dots> \<sqsubseteq> z" ..
       
   174     finally show ?thesis .
       
   175   qed
       
   176   fix w assume "w \<sqsubseteq> x \<sqinter> y" and "w \<sqsubseteq> z"
       
   177   show "w \<sqsubseteq> x \<sqinter> (y \<sqinter> z)"
       
   178   proof
       
   179     show "w \<sqsubseteq> x"
       
   180     proof -
       
   181       have "w \<sqsubseteq> x \<sqinter> y" .
       
   182       also have "\<dots> \<sqsubseteq> x" ..
       
   183       finally show ?thesis .
       
   184     qed
       
   185     show "w \<sqsubseteq> y \<sqinter> z"
       
   186     proof
       
   187       show "w \<sqsubseteq> y"
       
   188       proof -
       
   189         have "w \<sqsubseteq> x \<sqinter> y" .
       
   190         also have "\<dots> \<sqsubseteq> y" ..
       
   191         finally show ?thesis .
       
   192       qed
       
   193       show "w \<sqsubseteq> z" .
       
   194     qed
       
   195   qed
       
   196 qed
       
   197 
       
   198 theorem join_assoc: "(x \<squnion> y) \<squnion> z = x \<squnion> (y \<squnion> z)"
       
   199 proof -
       
   200   have "dual ((x \<squnion> y) \<squnion> z) = (dual x \<sqinter> dual y) \<sqinter> dual z"
       
   201     by (simp only: dual_join)
       
   202   also have "\<dots> = dual x \<sqinter> (dual y \<sqinter> dual z)"
       
   203     by (rule meet_assoc)
       
   204   also have "\<dots> = dual (x \<squnion> (y \<squnion> z))"
       
   205     by (simp only: dual_join)
       
   206   finally show ?thesis ..
       
   207 qed
       
   208 
       
   209 theorem meet_commute: "x \<sqinter> y = y \<sqinter> x"
       
   210 proof
       
   211   show "y \<sqinter> x \<sqsubseteq> x" ..
       
   212   show "y \<sqinter> x \<sqsubseteq> y" ..
       
   213   fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y"
       
   214   show "z \<sqsubseteq> y \<sqinter> x" ..
       
   215 qed
       
   216 
       
   217 theorem join_commute: "x \<squnion> y = y \<squnion> x"
       
   218 proof -
       
   219   have "dual (x \<squnion> y) = dual x \<sqinter> dual y" ..
       
   220   also have "\<dots> = dual y \<sqinter> dual x"
       
   221     by (rule meet_commute)
       
   222   also have "\<dots> = dual (y \<squnion> x)"
       
   223     by (simp only: dual_join)
       
   224   finally show ?thesis ..
       
   225 qed
       
   226 
       
   227 theorem meet_join_absorb: "x \<sqinter> (x \<squnion> y) = x"
       
   228 proof
       
   229   show "x \<sqsubseteq> x" ..
       
   230   show "x \<sqsubseteq> x \<squnion> y" ..
       
   231   fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> x \<squnion> y"
       
   232   show "z \<sqsubseteq> x" .
       
   233 qed
       
   234 
       
   235 theorem join_meet_absorb: "x \<squnion> (x \<sqinter> y) = x"
       
   236 proof -
       
   237   have "dual x \<sqinter> (dual x \<squnion> dual y) = dual x"
       
   238     by (rule meet_join_absorb)
       
   239   hence "dual (x \<squnion> (x \<sqinter> y)) = dual x"
       
   240     by (simp only: dual_meet dual_join)
       
   241   thus ?thesis ..
       
   242 qed
       
   243 
       
   244 text {*
       
   245   \medskip Some further algebraic properties hold as well.  The
       
   246   property idempotent (I) is a basic algebraic consequence of (AB).
       
   247 *}
       
   248 
       
   249 theorem meet_idem: "x \<sqinter> x = x"
       
   250 proof -
       
   251   have "x \<sqinter> (x \<squnion> (x \<sqinter> x)) = x" by (rule meet_join_absorb)
       
   252   also have "x \<squnion> (x \<sqinter> x) = x" by (rule join_meet_absorb)
       
   253   finally show ?thesis .
       
   254 qed
       
   255 
       
   256 theorem join_idem: "x \<squnion> x = x"
       
   257 proof -
       
   258   have "dual x \<sqinter> dual x = dual x"
       
   259     by (rule meet_idem)
       
   260   hence "dual (x \<squnion> x) = dual x"
       
   261     by (simp only: dual_join)
       
   262   thus ?thesis ..
       
   263 qed
       
   264 
       
   265 text {*
       
   266   Meet and join are trivial for related elements.
       
   267 *}
       
   268 
       
   269 theorem meet_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<sqinter> y = x"
       
   270 proof
       
   271   assume "x \<sqsubseteq> y"
       
   272   show "x \<sqsubseteq> x" ..
       
   273   show "x \<sqsubseteq> y" .
       
   274   fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y" show "z \<sqsubseteq> x" .
       
   275 qed
       
   276 
       
   277 theorem join_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<squnion> y = y"
       
   278 proof -
       
   279   assume "x \<sqsubseteq> y" hence "dual y \<sqsubseteq> dual x" ..
       
   280   hence "dual y \<sqinter> dual x = dual y" by (rule meet_related)
       
   281   also have "dual y \<sqinter> dual x = dual (y \<squnion> x)" by (simp only: dual_join)
       
   282   also have "y \<squnion> x = x \<squnion> y" by (rule join_commute)
       
   283   finally show ?thesis ..
       
   284 qed
       
   285 
       
   286 
       
   287 subsection {* Order versus algebraic structure *}
       
   288 
       
   289 text {*
       
   290   The @{text \<sqinter>} and @{text \<squnion>} operations are connected with the
       
   291   underlying @{text \<sqsubseteq>} relation in a canonical manner.
       
   292 *}
       
   293 
       
   294 theorem meet_connection: "(x \<sqsubseteq> y) = (x \<sqinter> y = x)"
       
   295 proof
       
   296   assume "x \<sqsubseteq> y"
       
   297   hence "is_inf x y x" ..
       
   298   thus "x \<sqinter> y = x" ..
       
   299 next
       
   300   have "x \<sqinter> y \<sqsubseteq> y" ..
       
   301   also assume "x \<sqinter> y = x"
       
   302   finally show "x \<sqsubseteq> y" .
       
   303 qed
       
   304 
       
   305 theorem join_connection: "(x \<sqsubseteq> y) = (x \<squnion> y = y)"
       
   306 proof
       
   307   assume "x \<sqsubseteq> y"
       
   308   hence "is_sup x y y" ..
       
   309   thus "x \<squnion> y = y" ..
       
   310 next
       
   311   have "x \<sqsubseteq> x \<squnion> y" ..
       
   312   also assume "x \<squnion> y = y"
       
   313   finally show "x \<sqsubseteq> y" .
       
   314 qed
       
   315 
       
   316 text {*
       
   317   \medskip The most fundamental result of the meta-theory of lattices
       
   318   is as follows (we do not prove it here).
       
   319 
       
   320   Given a structure with binary operations @{text \<sqinter>} and @{text \<squnion>}
       
   321   such that (A), (C), and (AB) hold (cf.\
       
   322   \S\ref{sec:lattice-algebra}).  This structure represents a lattice,
       
   323   if the relation @{term "x \<sqsubseteq> y"} is defined as @{term "x \<sqinter> y = x"}
       
   324   (alternatively as @{term "x \<squnion> y = y"}).  Furthermore, infimum and
       
   325   supremum with respect to this ordering coincide with the original
       
   326   @{text \<sqinter>} and @{text \<squnion>} operations.
       
   327 *}
       
   328 
       
   329 
       
   330 subsection {* Example instances *}
       
   331 
       
   332 subsubsection {* Linear orders *}
       
   333 
       
   334 text {*
       
   335   Linear orders with @{term minimum} and @{term minimum} operations
       
   336   are a (degenerate) example of lattice structures.
       
   337 *}
       
   338 
       
   339 constdefs
       
   340   minimum :: "'a::linear_order \<Rightarrow> 'a \<Rightarrow> 'a"
       
   341   "minimum x y \<equiv> (if x \<sqsubseteq> y then x else y)"
       
   342   maximum :: "'a::linear_order \<Rightarrow> 'a \<Rightarrow> 'a"
       
   343   "maximum x y \<equiv> (if x \<sqsubseteq> y then y else x)"
       
   344 
       
   345 lemma is_inf_minimum: "is_inf x y (minimum x y)"
       
   346 proof
       
   347   let ?min = "minimum x y"
       
   348   from leq_linear show "?min \<sqsubseteq> x" by (auto simp add: minimum_def)
       
   349   from leq_linear show "?min \<sqsubseteq> y" by (auto simp add: minimum_def)
       
   350   fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y"
       
   351   with leq_linear show "z \<sqsubseteq> ?min" by (auto simp add: minimum_def)
       
   352 qed
       
   353 
       
   354 lemma is_sup_maximum: "is_sup x y (maximum x y)"      (* FIXME dualize!? *)
       
   355 proof
       
   356   let ?max = "maximum x y"
       
   357   from leq_linear show "x \<sqsubseteq> ?max" by (auto simp add: maximum_def)
       
   358   from leq_linear show "y \<sqsubseteq> ?max" by (auto simp add: maximum_def)
       
   359   fix z assume "x \<sqsubseteq> z" and "y \<sqsubseteq> z"
       
   360   with leq_linear show "?max \<sqsubseteq> z" by (auto simp add: maximum_def)
       
   361 qed
       
   362 
       
   363 instance linear_order < lattice
       
   364 proof intro_classes
       
   365   fix x y :: "'a::linear_order"
       
   366   from is_inf_minimum show "\<exists>inf. is_inf x y inf" ..
       
   367   from is_sup_maximum show "\<exists>sup. is_sup x y sup" ..
       
   368 qed
       
   369 
       
   370 text {*
       
   371   The lattice operations on linear orders indeed coincide with @{term
       
   372   minimum} and @{term maximum}.
       
   373 *}
       
   374 
       
   375 theorem meet_mimimum: "x \<sqinter> y = minimum x y"
       
   376   by (rule meet_equality) (rule is_inf_minimum)
       
   377 
       
   378 theorem meet_maximum: "x \<squnion> y = maximum x y"
       
   379   by (rule join_equality) (rule is_sup_maximum)
       
   380 
       
   381 
       
   382 
       
   383 subsubsection {* Binary products *}
       
   384 
       
   385 text {*
       
   386   The class of lattices is closed under direct binary products (cf.\
       
   387   also \S\ref{sec:prod-order}).
       
   388 *}
       
   389 
       
   390 lemma is_inf_prod: "is_inf p q (fst p \<sqinter> fst q, snd p \<sqinter> snd q)"
       
   391 proof
       
   392   show "(fst p \<sqinter> fst q, snd p \<sqinter> snd q) \<sqsubseteq> p"
       
   393   proof -
       
   394     have "fst p \<sqinter> fst q \<sqsubseteq> fst p" ..
       
   395     moreover have "snd p \<sqinter> snd q \<sqsubseteq> snd p" ..
       
   396     ultimately show ?thesis by (simp add: leq_prod_def)
       
   397   qed
       
   398   show "(fst p \<sqinter> fst q, snd p \<sqinter> snd q) \<sqsubseteq> q"
       
   399   proof -
       
   400     have "fst p \<sqinter> fst q \<sqsubseteq> fst q" ..
       
   401     moreover have "snd p \<sqinter> snd q \<sqsubseteq> snd q" ..
       
   402     ultimately show ?thesis by (simp add: leq_prod_def)
       
   403   qed
       
   404   fix r assume rp: "r \<sqsubseteq> p" and rq: "r \<sqsubseteq> q"
       
   405   show "r \<sqsubseteq> (fst p \<sqinter> fst q, snd p \<sqinter> snd q)"
       
   406   proof -
       
   407     have "fst r \<sqsubseteq> fst p \<sqinter> fst q"
       
   408     proof
       
   409       from rp show "fst r \<sqsubseteq> fst p" by (simp add: leq_prod_def)
       
   410       from rq show "fst r \<sqsubseteq> fst q" by (simp add: leq_prod_def)
       
   411     qed
       
   412     moreover have "snd r \<sqsubseteq> snd p \<sqinter> snd q"
       
   413     proof
       
   414       from rp show "snd r \<sqsubseteq> snd p" by (simp add: leq_prod_def)
       
   415       from rq show "snd r \<sqsubseteq> snd q" by (simp add: leq_prod_def)
       
   416     qed
       
   417     ultimately show ?thesis by (simp add: leq_prod_def)
       
   418   qed
       
   419 qed
       
   420 
       
   421 lemma is_sup_prod: "is_sup p q (fst p \<squnion> fst q, snd p \<squnion> snd q)"  (* FIXME dualize!? *)
       
   422 proof
       
   423   show "p \<sqsubseteq> (fst p \<squnion> fst q, snd p \<squnion> snd q)"
       
   424   proof -
       
   425     have "fst p \<sqsubseteq> fst p \<squnion> fst q" ..
       
   426     moreover have "snd p \<sqsubseteq> snd p \<squnion> snd q" ..
       
   427     ultimately show ?thesis by (simp add: leq_prod_def)
       
   428   qed
       
   429   show "q \<sqsubseteq> (fst p \<squnion> fst q, snd p \<squnion> snd q)"
       
   430   proof -
       
   431     have "fst q \<sqsubseteq> fst p \<squnion> fst q" ..
       
   432     moreover have "snd q \<sqsubseteq> snd p \<squnion> snd q" ..
       
   433     ultimately show ?thesis by (simp add: leq_prod_def)
       
   434   qed
       
   435   fix r assume "pr": "p \<sqsubseteq> r" and qr: "q \<sqsubseteq> r"
       
   436   show "(fst p \<squnion> fst q, snd p \<squnion> snd q) \<sqsubseteq> r"
       
   437   proof -
       
   438     have "fst p \<squnion> fst q \<sqsubseteq> fst r"
       
   439     proof
       
   440       from "pr" show "fst p \<sqsubseteq> fst r" by (simp add: leq_prod_def)
       
   441       from qr show "fst q \<sqsubseteq> fst r" by (simp add: leq_prod_def)
       
   442     qed
       
   443     moreover have "snd p \<squnion> snd q \<sqsubseteq> snd r"
       
   444     proof
       
   445       from "pr" show "snd p \<sqsubseteq> snd r" by (simp add: leq_prod_def)
       
   446       from qr show "snd q \<sqsubseteq> snd r" by (simp add: leq_prod_def)
       
   447     qed
       
   448     ultimately show ?thesis by (simp add: leq_prod_def)
       
   449   qed
       
   450 qed
       
   451 
       
   452 instance * :: (lattice, lattice) lattice
       
   453 proof intro_classes
       
   454   fix p q :: "'a::lattice \<times> 'b::lattice"
       
   455   from is_inf_prod show "\<exists>inf. is_inf p q inf" ..
       
   456   from is_sup_prod show "\<exists>sup. is_sup p q sup" ..
       
   457 qed
       
   458 
       
   459 text {*
       
   460   The lattice operations on a binary product structure indeed coincide
       
   461   with the products of the original ones.
       
   462 *}
       
   463 
       
   464 theorem meet_prod: "p \<sqinter> q = (fst p \<sqinter> fst q, snd p \<sqinter> snd q)"
       
   465   by (rule meet_equality) (rule is_inf_prod)
       
   466 
       
   467 theorem join_prod: "p \<squnion> q = (fst p \<squnion> fst q, snd p \<squnion> snd q)"
       
   468   by (rule join_equality) (rule is_sup_prod)
       
   469 
       
   470 
       
   471 subsubsection {* General products *}
       
   472 
       
   473 text {*
       
   474   The class of lattices is closed under general products (function
       
   475   spaces) as well (cf.\ also \S\ref{sec:fun-order}).
       
   476 *}
       
   477 
       
   478 lemma is_inf_fun: "is_inf f g (\<lambda>x. f x \<sqinter> g x)"
       
   479 proof
       
   480   show "(\<lambda>x. f x \<sqinter> g x) \<sqsubseteq> f"
       
   481   proof
       
   482     fix x show "f x \<sqinter> g x \<sqsubseteq> f x" ..
       
   483   qed
       
   484   show "(\<lambda>x. f x \<sqinter> g x) \<sqsubseteq> g"
       
   485   proof
       
   486     fix x show "f x \<sqinter> g x \<sqsubseteq> g x" ..
       
   487   qed
       
   488   fix h assume hf: "h \<sqsubseteq> f" and hg: "h \<sqsubseteq> g"
       
   489   show "h \<sqsubseteq> (\<lambda>x. f x \<sqinter> g x)"
       
   490   proof
       
   491     fix x
       
   492     show "h x \<sqsubseteq> f x \<sqinter> g x"
       
   493     proof
       
   494       from hf show "h x \<sqsubseteq> f x" ..
       
   495       from hg show "h x \<sqsubseteq> g x" ..
       
   496     qed
       
   497   qed
       
   498 qed
       
   499 
       
   500 lemma is_sup_fun: "is_sup f g (\<lambda>x. f x \<squnion> g x)"   (* FIXME dualize!? *)
       
   501 proof
       
   502   show "f \<sqsubseteq> (\<lambda>x. f x \<squnion> g x)"
       
   503   proof
       
   504     fix x show "f x \<sqsubseteq> f x \<squnion> g x" ..
       
   505   qed
       
   506   show "g \<sqsubseteq> (\<lambda>x. f x \<squnion> g x)"
       
   507   proof
       
   508     fix x show "g x \<sqsubseteq> f x \<squnion> g x" ..
       
   509   qed
       
   510   fix h assume fh: "f \<sqsubseteq> h" and gh: "g \<sqsubseteq> h"
       
   511   show "(\<lambda>x. f x \<squnion> g x) \<sqsubseteq> h"
       
   512   proof
       
   513     fix x
       
   514     show "f x \<squnion> g x \<sqsubseteq> h x"
       
   515     proof
       
   516       from fh show "f x \<sqsubseteq> h x" ..
       
   517       from gh show "g x \<sqsubseteq> h x" ..
       
   518     qed
       
   519   qed
       
   520 qed
       
   521 
       
   522 instance fun :: ("term", lattice) lattice
       
   523 proof intro_classes
       
   524   fix f g :: "'a \<Rightarrow> 'b::lattice"
       
   525   show "\<exists>inf. is_inf f g inf" by rule (rule is_inf_fun) (* FIXME @{text "from \<dots> show \<dots> .."} does not work!? unification incompleteness!? *)
       
   526   show "\<exists>sup. is_sup f g sup" by rule (rule is_sup_fun)
       
   527 qed
       
   528 
       
   529 text {*
       
   530   The lattice operations on a general product structure (function
       
   531   space) indeed emerge by point-wise lifting of the original ones.
       
   532 *}
       
   533 
       
   534 theorem meet_fun: "f \<sqinter> g = (\<lambda>x. f x \<sqinter> g x)"
       
   535   by (rule meet_equality) (rule is_inf_fun)
       
   536 
       
   537 theorem join_fun: "f \<squnion> g = (\<lambda>x. f x \<squnion> g x)"
       
   538   by (rule join_equality) (rule is_sup_fun)
       
   539 
       
   540 
       
   541 subsection {* Monotonicity and semi-morphisms *}
       
   542 
       
   543 text {*
       
   544   The lattice operations are monotone in both argument positions.  In
       
   545   fact, monotonicity of the second position is trivial due to
       
   546   commutativity.
       
   547 *}
       
   548 
       
   549 theorem meet_mono: "x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> w \<Longrightarrow> x \<sqinter> y \<sqsubseteq> z \<sqinter> w"
       
   550 proof -
       
   551   {
       
   552     fix a b c :: "'a::lattice"
       
   553     assume "a \<sqsubseteq> c" have "a \<sqinter> b \<sqsubseteq> c \<sqinter> b"
       
   554     proof
       
   555       have "a \<sqinter> b \<sqsubseteq> a" ..
       
   556       also have "\<dots> \<sqsubseteq> c" .
       
   557       finally show "a \<sqinter> b \<sqsubseteq> c" .
       
   558       show "a \<sqinter> b \<sqsubseteq> b" ..
       
   559     qed
       
   560   } note this [elim?]
       
   561   assume "x \<sqsubseteq> z" hence "x \<sqinter> y \<sqsubseteq> z \<sqinter> y" ..
       
   562   also have "\<dots> = y \<sqinter> z" by (rule meet_commute)
       
   563   also assume "y \<sqsubseteq> w" hence "y \<sqinter> z \<sqsubseteq> w \<sqinter> z" ..
       
   564   also have "\<dots> = z \<sqinter> w" by (rule meet_commute)
       
   565   finally show ?thesis .
       
   566 qed
       
   567 
       
   568 theorem join_mono: "x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> w \<Longrightarrow> x \<squnion> y \<sqsubseteq> z \<squnion> w"
       
   569 proof -
       
   570   assume "x \<sqsubseteq> z" hence "dual z \<sqsubseteq> dual x" ..
       
   571   moreover assume "y \<sqsubseteq> w" hence "dual w \<sqsubseteq> dual y" ..
       
   572   ultimately have "dual z \<sqinter> dual w \<sqsubseteq> dual x \<sqinter> dual y"
       
   573     by (rule meet_mono)
       
   574   hence "dual (z \<squnion> w) \<sqsubseteq> dual (x \<squnion> y)"
       
   575     by (simp only: dual_join)
       
   576   thus ?thesis ..
       
   577 qed
       
   578 
       
   579 text {*
       
   580   \medskip A semi-morphisms is a function $f$ that preserves the
       
   581   lattice operations in the following manner: @{term "f (x \<sqinter> y) \<sqsubseteq> f x
       
   582   \<sqinter> f y"} and @{term "f x \<squnion> f y \<sqsubseteq> f (x \<squnion> y)"}, respectively.  Any of
       
   583   these properties is equivalent with monotonicity.
       
   584 *}  (* FIXME dual version !? *)
       
   585 
       
   586 theorem meet_semimorph:
       
   587   "(\<And>x y. f (x \<sqinter> y) \<sqsubseteq> f x \<sqinter> f y) \<equiv> (\<And>x y. x \<sqsubseteq> y \<Longrightarrow> f x \<sqsubseteq> f y)"
       
   588 proof
       
   589   assume morph: "\<And>x y. f (x \<sqinter> y) \<sqsubseteq> f x \<sqinter> f y"
       
   590   fix x y :: "'a::lattice"
       
   591   assume "x \<sqsubseteq> y" hence "x \<sqinter> y = x" ..
       
   592   hence "x = x \<sqinter> y" ..
       
   593   also have "f \<dots> \<sqsubseteq> f x \<sqinter> f y" by (rule morph)
       
   594   also have "\<dots> \<sqsubseteq> f y" ..
       
   595   finally show "f x \<sqsubseteq> f y" .
       
   596 next
       
   597   assume mono: "\<And>x y. x \<sqsubseteq> y \<Longrightarrow> f x \<sqsubseteq> f y"
       
   598   show "\<And>x y. f (x \<sqinter> y) \<sqsubseteq> f x \<sqinter> f y"
       
   599   proof -
       
   600     fix x y
       
   601     show "f (x \<sqinter> y) \<sqsubseteq> f x \<sqinter> f y"
       
   602     proof
       
   603       have "x \<sqinter> y \<sqsubseteq> x" .. thus "f (x \<sqinter> y) \<sqsubseteq> f x" by (rule mono)
       
   604       have "x \<sqinter> y \<sqsubseteq> y" .. thus "f (x \<sqinter> y) \<sqsubseteq> f y" by (rule mono)
       
   605     qed
       
   606   qed
       
   607 qed
       
   608 
       
   609 end