module Postulate.Bag-Nehemiah where
open import Relation.Binary.PropositionalEquality
open import Algebra.Structures
open import Data.Integer
postulate Bag : Set
postulate singletonBag : ℤ → Bag
postulate _++_ : Bag → Bag → Bag
infixr 5 _++_
postulate negateBag : Bag → Bag
postulate emptyBag : Bag
postulate abelian-bag : IsAbelianGroup _≡_ _++_ emptyBag negateBag
Homomorphic₁ :
{A B : Set} (f : A → B) (negA : A → A) (negB : B → B) → Set
Homomorphic₁ {A} {B} f negA negB = ∀ {x} → f (negA x) ≡ negB (f x)
Homomorphic₂ :
{A B : Set} (f : A → B) (_+_ : A → A → A) (_*_ : B → B → B) → Set
Homomorphic₂ {A} {B} f _+_ _*_ = ∀ {x y} → f (x + y) ≡ f x * f y
postulate mapBag : (f : ℤ → ℤ) (b : Bag) → Bag
postulate flatmapBag : (f : ℤ → Bag) (b : Bag) → Bag
postulate sumBag : Bag → ℤ
postulate homo-map : ∀ {f} → Homomorphic₂ (mapBag f) _++_ _++_
postulate homo-flatmap : ∀ {f} → Homomorphic₂ (flatmapBag f) _++_ _++_
postulate homo-sum : Homomorphic₂ sumBag _++_ _+_
postulate neg-map : ∀ {f} → Homomorphic₁ (mapBag f) negateBag negateBag
postulate neg-flatmap : ∀ {f} → Homomorphic₁ (flatmapBag f) negateBag negateBag