Theory Lifted_Predicates

(*<*)
theory Lifted_Predicates
imports
  HOL_Basis
begin

(*>*)
section‹ Point-free notation \label{sec:lifted_predicates} ›

text‹

Typically we define predicates as functions of a state. The following
provide a somewhat comfortable point-free imitation of Isabelle/HOL's
operators.

›

type_synonym 's pred = "'s ⇒ bool"

abbreviation (input)
  pred_K :: "'b ⇒ 'a ⇒ 'b" (‹⟨_⟩›) where
  "⟨f⟩ ≡ λs. f"

abbreviation (input)
  pred_not :: "'a pred ⇒ 'a pred" (‹¬ _› [40] 40) where
  "¬a ≡ λs. ¬a s"

abbreviation (input)
  pred_conj :: "'a pred ⇒ 'a pred ⇒ 'a pred" (infixr ‹∧› 35) where
  "a ∧ b ≡ λs. a s ∧ b s"

abbreviation (input)
  pred_disj :: "'a pred ⇒ 'a pred ⇒ 'a pred" (infixr ‹∨› 30) where
  "a ∨ b ≡ λs. a s ∨ b s"

abbreviation (input)
  pred_implies :: "'a pred ⇒ 'a pred ⇒ 'a pred" (infixr ‹⟶› 25) where
  "a ⟶ b ≡ λs. a s ⟶ b s"

abbreviation (input)
  pred_iff :: "'a pred ⇒ 'a pred ⇒ 'a pred" (infixr ‹⟷› 25) where
  "a ⟷ b ≡ λs. a s ⟷ b s"

abbreviation (input)
  pred_eq :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹=› 40) where
  "a = b ≡ λs. a s = b s"

abbreviation (input)
  pred_neq :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹≠› 40) where
  "a ≠ b ≡ λs. a s ≠ b s"

abbreviation (input)
  pred_If :: "'a pred ⇒ ('a ⇒ 'b) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" (‹(If (_)/ Then (_)/ Else (_))› [0, 0, 10] 10)
  where "If P Then x Else y ≡ λs. if P s then x s else y s"

abbreviation (input)
  pred_less :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹<› 40) where
  "a < b ≡ λs. a s < b s"

abbreviation (input)
  pred_less_eq :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹≤› 40) where
  "a ≤ b ≡ λs. a s ≤ b s"

abbreviation (input)
  pred_greater :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹>› 40) where
  "a > b ≡ λs. a s > b s"

abbreviation (input)
  pred_greater_eq :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a pred" (infix ‹≥› 40) where
  "a ≥ b ≡ λs. a s ≥ b s"

abbreviation (input)
  pred_plus :: "('a ⇒ 'b::plus) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" (infixl ‹+› 65) where
  "a + b ≡ λs. a s + b s"

abbreviation (input)
  pred_minus :: "('a ⇒ 'b::minus) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" (infixl ‹-› 65) where
  "a - b ≡ λs. a s - b s"

abbreviation (input)
  pred_times :: "('a ⇒ 'b::times) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" (infixl ‹*› 65) where
  "a * b ≡ λs. a s * b s"

abbreviation (input)
  pred_all :: "('b ⇒ 'a pred) ⇒ 'a pred" (binder ‹∀› 10) where
  "∀x. P x ≡ λs. ∀x. P x s"

abbreviation (input)
  pred_ex :: "('b ⇒ 'a pred) ⇒ 'a pred" (binder ‹∃› 10) where
  "∃x. P x ≡ λs. ∃x. P x s"

(* this one is applicative-functor ish *)
abbreviation (input)
  pred_app :: "('a ⇒ 'b ⇒ 'c) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'c" (infixl ‹$› 100) where
  "f $ g ≡ λs. f s (g s)"

(* this one is monadic postcondition ish *)
abbreviation (input)
  pred_app' :: "('b ⇒ 'a ⇒ 'c) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'c" (infixl ‹$$› 100) where
  "f $$ g ≡ λs. f (g s) s"

abbreviation (input)
  pred_member :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b set) ⇒ 'a pred" (infix ‹∈› 40) where
  "a ∈ b ≡ λs. a s ∈ b s"

abbreviation (input)
  pred_subseteq :: "('a ⇒ 'b set) ⇒ ('a ⇒ 'b set) ⇒ 'a pred" (infix ‹⊆› 50) where
  "A ⊆ B ≡ λs. A s ⊆ B s"

abbreviation (input)
  pred_union :: "('a ⇒ 'b set) ⇒ ('a ⇒ 'b set) ⇒ 'a ⇒ 'b set" (infixl ‹∪› 65) where
  "a ∪ b ≡ λs. a s ∪ b s"

abbreviation (input)
  pred_inter :: "('a ⇒ 'b set) ⇒ ('a ⇒ 'b set) ⇒ 'a ⇒ 'b set" (infixl ‹∩› 65) where
  "a ∩ b ≡ λs. a s ∩ b s"

abbreviation (input)
  pred_conjoin :: "'a pred list ⇒ 'a pred" where
  "pred_conjoin xs ≡ foldr (∧) xs ⟨True⟩"

abbreviation (input)
  pred_disjoin :: "'a pred list ⇒ 'a pred" where
  "pred_disjoin xs ≡ foldr (∨) xs ⟨False⟩"

abbreviation (input)
  pred_min :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" where
  "pred_min x y ≡ λs. min (x s) (y s)"

abbreviation (input)
  pred_max :: "('a ⇒ 'b::ord) ⇒ ('a ⇒ 'b) ⇒ 'a ⇒ 'b" where
  "pred_max x y ≡ λs. max (x s) (y s)"

abbreviation (input)
  NULL :: "('a ⇒ 'b option) ⇒ 'a pred" where
  "NULL a ≡ λs. a s = None"

abbreviation (input)
  EMPTY :: "('a ⇒ 'b set) ⇒ 'a pred" where
  "EMPTY a ≡ λs. a s = {}"

abbreviation (input)
  LIST_NULL :: "('a ⇒ 'b list) ⇒ 'a pred" where
  "LIST_NULL a ≡ λs. a s = []"

abbreviation (input)
  SIZE :: "('a ⇒ 'b::size) ⇒ 'a ⇒ nat" where
  "SIZE a ≡ λs. size (a s)"

abbreviation (input)
  SET :: "('a ⇒ 'b list) ⇒ 'a ⇒ 'b set" where
  "SET a ≡ λs. set (a s)"

abbreviation (input)
  pred_singleton :: "('a ⇒ 'b) ⇒ 'a ⇒ 'b set" where
  "pred_singleton x ≡ λs. {x s}"

abbreviation (input)
  pred_list_nth :: "('a ⇒ 'b list) ⇒ ('a ⇒ nat) ⇒ 'a ⇒ 'b" (infixl ‹!› 150) where
  "xs ! i ≡ λs. xs s ! i s"

abbreviation (input)
  pred_list_append :: "('a ⇒ 'b list) ⇒ ('a ⇒ 'b list) ⇒ 'a ⇒ 'b list" (infixr ‹@› 65) where
  "xs @ ys ≡ λs. xs s @ ys s"

abbreviation (input)
  FST :: "'a pred ⇒ ('a × 'b) pred" where
  "FST P ≡ λs. P (fst s)"

abbreviation (input)
  SND :: "'b pred ⇒ ('a × 'b) pred" where
  "SND P ≡ λs. P (snd s)"

abbreviation (input)
  pred_pair :: "('a ⇒ 'b) ⇒ ('a ⇒ 'c) ⇒ 'a ⇒ 'b × 'c" (infixr ‹⊗› 60) where
  "a ⊗ b ≡ λs. (a s, b s)"
(*<*)

end
(*>*)