ITP Blatt 03

Besprechung: am 07.05.2026

{-# OPTIONS --allow-unsolved-metas #-}
open import Level using (Level)
open import Data.Nat
open import Data.List
open import Data.Product
open import Data.Bool hiding (_≤_; _<_)
open import Relation.Nullary.Decidable using (Dec; map′; yes; no)
open import Function.Base using (_∘_; id)
import Level as L
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary.Negation
open import Data.List.Membership.Propositional using (_∈_)
open import Data.List.Relation.Unary.Any using (Any; here; there)


module _ where

private
  variable
    a b c : Level
    A : Set a
    B : Set b
    C : Set c

n-ary Operation

Definieren Sie einen Typ einer n-ären Operation auf einem Typen X:

_-ary-on_ :   { : Level}  (X : Set )  Set 
_-ary-on_ = -- <LSG>
  _-ary-on'_
  where
   _-ary-on'_ :   { : Level}  (X : Set )  Set 
   _-ary-on'_ zero X = X
   _-ary-on'_ (suc k) X = X  k -ary-on' X
  -- </LSG>

-- <COMMENT>
_ : 2 -ary-on 
_ = _+_ -- addition is binary on ℕ
_ : 1 -ary-on 
_ =  x  x) -- identity is unary on ℕ
_ : 1 -ary-on Set
_ = ¬_ -- negation is a unary operation on sets 
_ : 0 -ary-on Bool
_ = true
-- </COMMENT>

Injektivität

-- <LSG>
open import Data.Unit
open import Data.Empty
-- </LSG>
module injectivity where

  _injective : (f : A  B)  Set _
  _injective f = -- <LSG>
     x x'  f x  f x'  x  x'
    -- </LSG>

  ∘-injective : {f : A  B} {g : B  C}  f injective  g injective  (g  f) injective
  ∘-injective {f = f} = -- <LSG>
    λ f-inj g-inj x x'  f-inj x x'  g-inj (f x) (f x')
    -- </LSG>

  ∘-cancelˡ-injective : {f : A  B} {g : B  C}  (g  f) injective  f injective
  ∘-cancelˡ-injective {g = g} = -- <LSG>
    λ g∘f-inj x x'  g∘f-inj x x'  cong g
    -- </LSG>
  no-∘-cancelʳ-injective : Σ[ A  Set ] Σ[ B  Set ] Σ[ C  Set ]
                           Σ[ f  (A  B) ] Σ[ g  (B  C) ]
                           ((g  f) injective × ¬ g injective)
  no-∘-cancelʳ-injective = _ , _ , _ , -- <LSG>
    f , g ,  x x' x₁  refl) , λ g-inj  h (g-inj true false refl)
    where
      f :   Bool
      f ()
      g : Bool  
      g _ = tt
      h : true  false  
      h ()
    -- </LSG>

Surjektivität

Definieren und Beweisen Sie die entsprechenden Eigenschaften für Surjektivität

module surjectivity where
  -- <LSG>
  _surjective : (f : A  B)  Set _
  _surjective f =  y  ∃[ x ] y  f x

  ∘-surjective : {f : A  B} {g : B  C}  f surjective  g surjective  (g  f) surjective
  ∘-surjective {g = g} f-surj g-surj z =
    let y , z≡g[y] = g-surj z in
    let x , y≡f[x] = f-surj y in
    x , subst  -  z  g -) y≡f[x] z≡g[y]
  -- </LSG>

  ∘-cancelʳ-surjective : {f : A  B} {g : B  C}  (g  f) surjective  g surjective
  ∘-cancelʳ-surjective {f = f} g∘f-surj =
    Data.Product.map f id  g∘f-surj
    -- ^- short version of:
    -- let x , z≡g[f[x]] = g∘f-surj z in
    -- f x , z≡g[f[x]]

Index-basierter Zugriff

Definieren Sie eine (totale) Funktion, die das k-te Element einer Liste zurückgibt.

_at[_] : (l : List A)  (k : )  k < length l  A
_at[_] = -- <LSG>
  _at[_]'
  where
  _at[_]' : (l : List A)  (k : )  k < length l  A
  ((x  l) at[ zero ]') k<l = x
  ((x  l) at[ suc k ]') (s≤s k<l) = (l at[ k ]') k<l
  -- </LSG>

Elementbeziehung Entscheiden

Entscheiden Sie, ob ein gegebenes Element in einer Liste vorkommt. (Tipp: bei Fallunterscheidung über etwas vom Typ Dec x ist es ratsam, die Fälle yes und no manuell einzutragen)

module decide-∈ (A : Set a) (_≟_ :  (x y : A)  Dec (x  y)) where
    _∈?_ : (x : A) (l : List A)  Dec (x  l)
    _∈?_ = -- <LSG>
      helper
      where
      helper : (x : A) (l : List A)  Dec (x  l)
      helper x [] = no  ())
      helper x (y  l) with (x  y)
      ... | (yes refl) = yes (here refl)
      ... | (no x≢y) = map′ there
                 { (here x≡y)  ⊥-elim (x≢y x≡y)
                   ; (there x∈l)  x∈l}
                   ) (helper x l)
      -- </LSG>

Agda Quellcode herunterladen