GP7YEIGGU3IPEBURKAKH5SIXYRVFYZILAQRSUDU3FDFI2G66HOQQC name: tabularinclude: ../../../src/ .
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
┌───┬───┬───┐│foo│bar│baz│├───┼───┼───┤│ 1│2 │ 3 │├───┼───┼───┤│ 6│5 │ 4 │└───┴───┴───┘┌───┬───┐│foo│bar│├───┼───┤│ 1│2 │├───┼───┤│ 4│3 │└───┴───┘+-------+|foo|bar||---+---|| 1|2 ||---+---|| 4|3 |+-------+foo bar1 24 3┌───┬───┐│foo│bar││ 1│2 ││ 4│3 │└───┴───┘foo│bar───┼───1│2───┼───4│3┌─────┬─────┐│ foo │ bar │├─────┼─────┤│ 1 │ 2 │├─────┼─────┤│ 4 │ 3 │└─────┴─────┘┌─────┬─────┐│ foo │ bar ││ 1 │ 2 ││ 4 │ 3 │└─────┴─────┘┌───────┬────┬───┬───┬─────────┐│ foo │ bar│ │ │ │├───────┼────┼───┼───┼─────────┤│partial│rows│are│ok │ │├───────┼────┼───┼───┼─────────┤│ 3 │ 2│1 │...│surprise!│└───────┴────┴───┴───┴─────────┘┌───┬───┐│foo│bar││ 1│ 2││ 4│ 3│└───┴───┘
-- This is taken from README.Text.Tabular{-# OPTIONS --guardedness #-}module Main whereopen import Function.Baseopen import Data.List.Baseopen import Data.String.Baseopen import Data.Vec.Baseopen import IO.Baseopen import IO.Finiteopen import Text.Tabular.Baseimport Text.Tabular.List as Tabularˡimport Text.Tabular.Vec as Tabularᵛmain : Mainmain = run $ doputStrLn $unlines (Tabularᵛ.display unicode(Right ∷ Left ∷ Center ∷ [])( ("foo" ∷ "bar" ∷ "baz" ∷ [])∷ ("1" ∷ "2" ∷ "3" ∷ [])∷ ("6" ∷ "5" ∷ "4" ∷ [])∷ []))let foobar = ("foo" ∷ "bar" ∷ [])∷ ("1" ∷ "2" ∷ [])∷ ("4" ∷ "3" ∷ [])∷ []putStrLn $unlines (Tabularᵛ.display unicode(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display ascii(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display whitespace(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display (compact unicode)(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display (noBorder unicode)(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display (addSpace unicode)(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularᵛ.display (compact (addSpace unicode))(Right ∷ Left ∷ [])foobar)putStrLn $unlines (Tabularˡ.display unicode(Center ∷ Right ∷ [])( ("foo" ∷ "bar" ∷ [])∷ ("partial" ∷ "rows" ∷ "are" ∷ "ok" ∷ [])∷ ("3" ∷ "2" ∷ "1" ∷ "..." ∷ "surprise!" ∷ [])∷ []))putStrLn $unlines (unsafeDisplay (compact unicode)( ("foo" ∷ "bar" ∷ [])∷ (" 1" ∷ " 2" ∷ [])∷ (" 4" ∷ " 3" ∷ [])∷ []))
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: regexinclude: ../../../src/ .
Match found: $1 --compile-dir=../../_build -c [Main.agda] > logMatch found: ./../../[_build/]Main > outputNo match foundMatch found: rm ../../[_build/]MainMatch found: rm ../../[_build/MAlonzo/Code/]Main*
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Bool.Base using (true; false)open import Data.List.Base using (_∷_; [])open import Data.List.Relation.Binary.Infix.Heterogeneous using (toView; MkView)open import Data.String using (String; toList; fromList; lines; concat)open import IOopen import Function.Base using (_$_; case_of_)open import Relation.Binary.PropositionalEquality using (_≡_)open import Relation.Nullaryopen import Text.Regex.Stringshow : ∀ e {xs} → Dec (Match (Span e _≡_) xs (Regex.expression e)) → Stringshow _ (no _) = "No match found"show e (yes match) = case toView (toInfix e (match .Match.related)) of λ where(MkView pref x suff) → concat$ "Match found: "∷ fromList pref∷ "["∷ fromList (match .Match.list)∷ "]"∷ fromList suff∷ []agdaFile : ExpagdaFile = [ 'a' ─ 'z' ∷ 'A' ─ 'Z' ∷ [] ] +∙ singleton '.'∙ singleton 'a'∙ singleton 'g'∙ singleton 'd'∙ singleton 'a'buildDir : ExpbuildDir = singleton '_'∙ ([ 'a' ─ 'z' ∷ 'A' ─ 'Z' ∷ [] ] + ∙ singleton '/') +regex : Regexregex .Regex.fromStart = falseregex .Regex.tillEnd = falseregex .Regex.expression= agdaFile ∣ buildDirmain : Mainmain = run $ dotext ← readFiniteFile "run"List.forM′ (lines text) $ λ l →putStrLn (show regex $ search (toList l) regex)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: printfinclude: ../../../src/ .
example: 3 + 2 ≡ 5example: 3 + -3 ≡ 0gcd(-9,15) ≡ 3lcm(-9,15) ≡ 45A char: cA float: 3.14
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Integer.Base as ℤ using (+_)open import Data.Integer.Literalsopen import Data.Integer.GCDopen import Data.Integer.LCMopen import Data.Nat.Baseopen import Data.String.Baseopen import Data.Unit.Baseopen import Function.Base using (_$_)open import IO.Baseopen import IO.Finiteopen import Text.Printfmain : Mainmain = run $ dolet instance _ = negativeputStrLn $ printf "%s: %u + %u ≡ %u" "example" 3 2 5putStrLn $ printf "%s: %u + %i ≡ %d" "example" 3 -3 (+ 3 ℤ.+ -3)putStrLn $ printf "gcd(%d,%i) ≡ %d" -9 (+ 15) (gcd -9 (+ 15))putStrLn $ printf "lcm(%d,%i) ≡ %d" -9 (+ 15) (lcm -9 (+ 15))putStrLn $ printf "A %s: %c" "char" 'c'putStrLn $ printf "A %s: %f" "float" 3.14
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: prettyinclude: ../../../src/ .
(setq column-number-mode t)(setq-default show-trailing-whitespacet)(add-hook 'write-file-hooks'delete-trailing-whitespace)(setq column-number-mode t)(setq-default show-trailing-whitespace t)(add-hook 'write-file-hooks 'delete-trailing-whitespace)
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Sizeopen import Data.List.Baseopen import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Nat.Base using (ℕ)open import Data.String.Base using (String)open import Data.Tree.Rose using (Rose; node)open import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_)open import Text.Pretty using (Doc; render)open module Pretty {w} = Text.Pretty w hiding (Doc; render)privatevariablei : Sizew : ℕpretty : Rose (Maybe String) i → Doc wpretty (node nothing ts) = vcat (map pretty ts)pretty (node (just a) []) = text apretty (node (just a) ts) = parens $ text a <+> sep (map pretty ts)SEXP = Rose (Maybe String) _atom : String → SEXPatom a = node (just a) []list : List SEXP → SEXPlist = node nothingcolMode : SEXPcolMode = node (just "setq") (atom "column-number-mode" ∷ atom "t" ∷ [])showTrailing : SEXPshowTrailing = node (just "setq-default")$ atom "show-trailing-whitespace" ∷ atom "t" ∷ []deleteTrailing : SEXPdeleteTrailing = node (just "add-hook")$ atom "'write-file-hooks"∷ atom "'delete-trailing-whitespace"∷ []dotEmacs : SEXPdotEmacs = node nothing$ colMode ∷ showTrailing ∷ deleteTrailing ∷ []main : Mainmain = run $ dolet doc : Doc w; doc = pretty dotEmacsputStrLn $ render 40 docputStrLn $ render 80 doc
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > random_valuestouch outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: ansiinclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Level using (0ℓ)open import Data.Unit.Polymorphic.Base using (⊤)import Data.Char.Base as Charimport Data.Fin.Base as Finimport Data.Fin.Show as Finimport Data.Float.Base as Floatopen import Data.Integer.Base using (-[1+_]; +_; -≤+)import Data.Integer.Show as ℤopen import Data.List.Base as List using ([]; _∷_)import Data.List.Show as Listimport Data.Nat.Baseimport Data.Nat.Properties as ℕimport Data.Nat.Show as ℕopen import Data.String.Base as Stringimport Data.Vec.Show as Vecimport Data.Word.Base as Word64open import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_; _∘_)open import System.Randomimport Data.Vec.Bounded.Show as Vec≤open import Relation.Binary.Construct.Closure.ReflexiveasA : String → String → IO {0ℓ} ⊤asA ty str = putStrLn (ty ++ ": " ++ str)main : Mainmain = run $ doasA "Char" ∘ Char.show =<< Char.randomIOasA "Char" ∘ Char.show ∘ InBounds.value =<< Char.randomRIO ' ' '~' [ ℕ.≤ᵇ⇒≤ _ _ _ ]asA "Float" ∘ Float.show =<< Float.randomIOasA "Float" ∘ Float.show ∘ InBounds.value =<< Float.randomRIO 0.0 1.0 _asA "Integer" ∘ ℤ.show =<< ℤ.randomIOasA "Integer" ∘ ℤ.show ∘ InBounds.value =<< ℤ.randomRIO -[1+ 2 ] (+ 5) -≤+asA "Nat" ∘ ℕ.show =<< ℕ.randomIOasA "Nat" ∘ ℕ.show ∘ InBounds.value =<< ℕ.randomRIO 1 10 (ℕ.≤ᵇ⇒≤ _ _ _)asA "Word" ∘ ℕ.show ∘ Word64.toℕ =<< Word64.randomIOasA "Word" ∘ ℕ.show ∘ Word64.toℕ ∘ InBounds.value =<<Word64.randomRIO (Word64.fromℕ 10) (Word64.fromℕ 20) (ℕ.≤ᵇ⇒≤ _ _ _)asA "Fin 10" ∘ Fin.show =<< Fin.randomIO {n = 10}asA "Fin 10" ∘ Fin.show ∘ InBounds.value =<<Fin.randomRIO {n = 10}(Fin.fromℕ< {m = 3} (ℕ.≤ᵇ⇒≤ _ _ _))(Fin.fromℕ< {m = 8} (ℕ.≤ᵇ⇒≤ _ _ _))(ℕ.≤ᵇ⇒≤ _ _ _)asA "Vec≤ Integer 10" ∘ Vec≤.show (ℤ.show ∘ InBounds.value) =<< Vec≤.randomIO (ℤ.randomRIO -[1+ 10 ] (+ 11) -≤+) 10asA "Vec Float 5" ∘ Vec.show (Float.show ∘ InBounds.value) =<< Vec.randomIO (Float.randomRIO -20.0 20.0 _) 5asA "String≤ 20" ∘ String.show =<< RangedString≤.randomIO ' ' '~' [ ℕ.≤ᵇ⇒≤ _ _ _ ] 20
random_values
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main hello world < input > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: ioinclude: ../../../src/ .
hellomynameisAgdaexit
echo< echo> helloecho< echo> myecho< echo> nameecho< echo> isecho< echo> Agdaecho<
{-# OPTIONS --guardedness #-}module Main whereopen import Data.String.Baseopen import Function.Base using (_$_; case_of_)open import IOopen import System.Exit using (exitSuccess)main : Mainmain = run $ do-- Ensure no buffering so that the prompt "echo< "-- gets outputed immediatelyhSetBuffering stdout noBufferingforever $ doputStr "echo< "-- Get a line from the user and immediately inspect it-- If it's a magic "exit" keyword then we exit, otherwise-- we print the echo'd message and let the `forever` action-- continuestr ← getLinecase str of λ where"exit" → exitSuccess_ → putStrLn ("echo> " ++ str)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main hello world > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
Mainhello worldhello back!
name: environmentinclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Maybe.Base using (fromMaybe)open import Data.String.Base using (unwords)open import IOopen import Function.Base using (_$_)open import System.Environmentmain : Mainmain = run $ doprog ← getProgNameputStrLn progargs ← getArgsputStrLn $ unwords argslet var = "AGDA_STDLIB_ENVIRONMENT_TEST"setEnv var "hello back!"msg ← lookupEnv varunsetEnv varputStrLn $ fromMaybe ":(" msg
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
Creating tmp1Creating tmp2Saw _buildSaw tmp1Saw tmp2Removing tmp1Removing tmp2
name: directoryinclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Bool.Base using (true; false)open import Data.List.Base as List using (_∷_; [])import Data.List.Sort as Sortopen import Data.String.Base using (_++_; unwords)import Data.String.Properties as Stringₚopen import IOopen import Function.Base using (_$_)open import Relation.Binary.Bundles using (DecTotalOrder)import Relation.Binary.Construct.On as Onopen import System.Directoryopen import System.FilePath.PosixdecTotalOrder : DecTotalOrder _ _ _decTotalOrder =On.decTotalOrder Stringₚ.≤-decTotalOrder-≈(getFilePath {n = Nature.relative})open Sort decTotalOrder using (sort)main : Mainmain = run $ dolet dirs = "tmp1" ∷ "tmp2" ∷ []List.forM′ dirs $ λ d → doputStrLn $ "Creating " ++ dcreateDirectory (mkFilePath d)ds ← listDirectory (mkFilePath ".")List.forM′ (sort ds) $ λ d → dotrue ← doesDirectoryExist dwhere false → pure _let str = getFilePath dputStrLn $ "Saw " ++ strList.forM′ dirs $ λ d → doputStrLn $ unwords $ "Removing" ∷ d ∷ []removeDirectory (mkFilePath d)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main hello world > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
[34;47mClassic blue on white[0m[37;104mWhite on bright blue[0m[1;93;104mBold bright yellow on bright blue[0m[3;91;43mItalic bright red on yellow[0m[6;21;1;41;90mPARTYYYY[0m
name: ansiinclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Data.List.Base using ([]; _∷_)open import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_)open import System.Console.ANSImain : Mainmain = run $ doputStrLn $ withCommands (setColour foreground classic blue∷ setColour background classic white∷ [])"Classic blue on white"putStrLn $ withCommands (setColour foreground classic white∷ setColour background bright blue∷ [])"White on bright blue"putStrLn $ withCommands (setWeight bold∷ setColour foreground bright yellow∷ setColour background bright blue∷ [])"Bold bright yellow on bright blue"putStrLn $ withCommands (setStyle italic∷ setColour foreground bright red∷ setColour background classic yellow∷ [])"Italic bright red on yellow"putStrLn $ withCommands (setBlinking rapid∷ setUnderline double∷ setWeight bold∷ setColour background classic red∷ setColour foreground bright black∷ [])"PARTYYYY"
name: standard-library-testsinclude: ../src/ .
name: treeinclude: ../../../src/ .
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
standard-library├ Agda│ ├ Haskell│ │ ├ Haskell (bootstrap)│ │ └ C│ ├ cabal│ │ └ Haskell│ │ ├ Haskell (bootstrap)│ │ └ C│ ├ alex│ │ └ Haskell│ │ ├ Haskell (bootstrap)│ │ └ C│ └ happy│ └ Haskell│ ├ Haskell (bootstrap)│ └ C├ cabal│ └ Haskell│ ├ Haskell (bootstrap)│ └ C└ Haskell├ Haskell (bootstrap)└ C
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Data.List.Base using (_∷_; [])open import Data.String.Base using (String; unlines)open import Data.Tree.Roseopen import Data.Tree.Rose.Showopen import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_; id)dependencies : Rose String _dependencies = node "standard-library"$ agda∷ cabal∷ haskell∷ [] wherehaskell : Rose String _haskell = node "Haskell"$ node "Haskell (bootstrap)" []∷ node "C" []∷ []cabal : Rose String _cabal = node "cabal" (haskell ∷ [])agda : Rose String _agda = node "Agda"$ haskell∷ cabal∷ node "alex" (haskell ∷ [])∷ node "happy" (haskell ∷ [])∷ []main : Mainmain = run $ doputStrLn $ unlines $ showSimple id dependencies
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: reflectioninclude: ../../../src/ .
Data.List.Base.map : Π ({A.a} : Agda.Primitive.Level) (Π ({A} : (Set (var 0))) (Π ({B.b} : Agda.Primitive.Level) (Π ({B} : (Set (var 0))) (Π (_ : (Π (_ : (var 2)) (var 1))) (Π (_ : (Agda.Builtin.List.List {var 4} (var 3))) (Agda.Builtin.List.List {var 3} (var 2)))))))Data.List.Base.map = function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(f : Π (_ : (var 2)) (var 1)) ] {pat-var 4} {pat-var 3} {pat-var 2} {pat-var 1} pat-var 0 Agda.Builtin.List.List.[] → Agda.Builtin.List.List.[] {unknown} {unknown} ; [ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(f : Π (_ : (var 2)) (var 1))(x : var 3)(xs : Agda.Builtin.List.List {var 5} (var 4)) ] {pat-var 6} {pat-var 5} {pat-var 4} {pat-var 3} pat-var 2 (Agda.Builtin.List.List._∷_ pat-var 1 pat-var 0) → Agda.Builtin.List.List._∷_ {unknown} {unknown} (var 2 (var 1)) (Data.List.Base.map {var 6} {var 5} {var 4} {var 3} (var 2) (var 0)) ;}
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Data.List.Base as List using (_∷_; [])open import Data.String.Base as String using (String)open import Data.Unit.Base using (⊤)open import Function.Base using (_$_; id)open import Reflection using (TC; Term; getType; getDefinition)open import Reflection.AST.ShowmacrorunTC : TC String → Term → TC ⊤runTC tc t = let open Reflection in dou ← tcunify t (lit (string u))open import IO.Base hiding (_<$>_)open import IO.Finiteopen import Reflection.TCM.Syntax using (_<$>_)main : Mainmain = run $ dolet name = quote List.mapputStr $ showName name String.++ " : "putStrLn $ runTC (showTerm <$> getType name)putStr $ showName name String.++ " = "putStrLn $ runTC (showDefinition <$> getDefinition name)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: numinclude: ../../../src/ .
00131101421010101024100000000000013-1342-421024-10240/1 * 1/14 ≡ 0/140/1 * 1/43 ≡ 0/430/1 * 1/1025 ≡ 0/102513/1 * 1/1 ≡ 13/113/1 * 1/43 ≡ 13/4313/1 * 1/1025 ≡ 13/102542/1 * 1/1 ≡ 42/142/1 * 1/14 ≡ 42/1442/1 * 1/1025 ≡ 42/10251024/1 * 1/1 ≡ 1024/11024/1 * 1/14 ≡ 1024/141024/1 * 1/43 ≡ 1024/430/1 * 1/14 ≡ 0/10/1 * 1/43 ≡ 0/10/1 * 1/1025 ≡ 0/113/1 * 1/1 ≡ 13/113/1 * 1/43 ≡ 13/4313/1 * 1/1025 ≡ 13/102542/1 * 1/1 ≡ 42/142/1 * 1/14 ≡ 3/142/1 * 1/1025 ≡ 42/10251024/1 * 1/1 ≡ 1024/11024/1 * 1/14 ≡ 512/71024/1 * 1/43 ≡ 1024/43
{-# OPTIONS --guardedness #-}module Main whereopen import Levelopen import Data.List.Base using (List; _∷_; [])open import Data.String using (unwords)open import IOopen import Function.Base using (_$_)import Data.Nat.Base as Natimport Data.Nat.Show as ShowNattests : List Nat.ℕtests = 0 ∷ 13 ∷ 42 ∷ 2 Nat.^ 10 ∷ []nats : IO {0ℓ} _nats = let open ShowNat inList.forM′ tests $ λ n → doputStrLn (show n)putStrLn (showInBase 2 n)import Data.Integer.Base as Intimport Data.Integer.Show as ShowIntints : IO {0ℓ} _ints = let open Int; open ShowInt inList.forM′ tests $ λ n → doputStrLn (show (+ n))putStrLn (show (- + n))import Data.Rational.Unnormalised.Base as URatimport Data.Rational.Unnormalised.Show as ShowURaturats : IO {0ℓ} _urats = let open URat; open ShowURat inList.forM′ tests $ λ num →List.forM′ tests $ λ denum →unless (num Nat.≡ᵇ denum) $ doputStrLn $ unwords$ show (mkℚᵘ (Int.+ num) 0)∷ "*"∷ show (mkℚᵘ (Int.+ 1) denum)∷ "≡"∷ show (mkℚᵘ (Int.+ num) denum)∷ []import Data.Rational.Base as Ratimport Data.Rational.Show as ShowRatopen import Data.Nat.Coprimalityrats : IO {0ℓ} _rats = let open Rat; open ShowRat inList.forM′ tests $ λ num →List.forM′ tests $ λ denum →unless (num Nat.≡ᵇ denum) $ doputStrLn $ unwords$ show (normalize num 1)∷ "*"∷ show (normalize 1 (Nat.suc denum))∷ "≡"∷ show (normalize num (Nat.suc denum))∷ []main : Mainmain = run $ donatsintsuratsrats
{-# OPTIONS --guardedness #-}module runtests whereopen import Data.List.Base as List using (_∷_; [])open import Data.String.Base using (String; _++_)open import IO.Baseopen import Function.Baseopen import Test.GoldendataTests : TestPooldataTests = mkTestPool "Data structures"$ "appending"∷ "colist"∷ "list"∷ "rational"∷ "rational-unnormalised"∷ "trie"∷ "bytestring"∷ []systemTests : TestPoolsystemTests = mkTestPool "System modules"$ "ansi"∷ "directory"∷ "environment"∷ "io"∷ "random"∷ []showTests : TestPoolshowTests = mkTestPool "Show instances"$ "num"∷ "reflection"∷ "tree"∷ []textTests : TestPooltextTests = mkTestPool "Text libraries"$ "pretty"∷ "printf"∷ "regex"∷ "tabular"∷ []monadTests : TestPoolmonadTests = mkTestPool "Monad transformers"$ "counting"∷ "fibonacci"∷ "pythagorean"∷ "tcm"∷ []reflectionTests : TestPoolreflectionTests = mkTestPool "Reflection machinery"$ "assumption"∷ []main : Mainmain = run $ ignore $ runner$ testPaths "data" dataTests∷ testPaths "monad" monadTests∷ testPaths "reflection" reflectionTests∷ testPaths "show" showTests∷ testPaths "system" systemTests∷ testPaths "text" textTests∷ [] wheretestPaths : String → TestPool → TestPooltestPaths dir pool =let testCases = List.map ((dir ++ "/") ++_) (pool .TestPool.testCases)in record pool { testCases = testCases }
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(x : var 2)(y : var 1) ] {pat-var 5} {pat-var 4} {pat-var 3} {pat-var 2} pat-var 1 pat-var 0 → var 0 ;}function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(x : var 2)(y : var 1) ] {pat-var 5} {pat-var 4} {pat-var 3} {pat-var 2} pat-var 1 pat-var 0 → var 1 ;}function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(x : var 2)(y : var 1)(z : var 2) ] {pat-var 6} {pat-var 5} {pat-var 4} {pat-var 3} pat-var 2 pat-var 1 pat-var 0 → var 2 ;}function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(x : Agda.Builtin.List.List {Agda.Primitive._⊔_ (var 3) (var 1)} (Π (_ : (var 2)) (var 1)))(y : var 3)(z : var 2)(a : var 3) ] {pat-var 7} {pat-var 6} {pat-var 5} {pat-var 4} pat-var 3 pat-var 2 pat-var 1 pat-var 0 → var 3 ;}function {[ {A.a : Agda.Primitive.Level}{A : Set (var 0)}{B.b : Agda.Primitive.Level}{B : Set (var 0)}(x : Π (_ : (var 2)) (Agda.Builtin.List.List {var 2} (var 1)))(y : var 3)(z : var 2)(a : Agda.Builtin.List.List {var 4} (var 3)) ] {pat-var 7} {pat-var 6} {pat-var 5} {pat-var 4} pat-var 3 pat-var 2 pat-var 1 pat-var 0 → var 3 ;}
name: assumptioninclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Data.String.Base using (String)open import Data.Bool.Base using (if_then_else_)open import Data.List.Base using (List; []; _∷_; concatMap; map)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Nat.Base using (ℕ; suc)open import Data.Product.Base using (_×_; _,_)open import Level using (Level)open import Data.Unit.Base using (⊤)open import Function.Base using (case_of_; _$_)open import Reflection.TCM hiding (pure)open import Reflection.AST.Termopen import Reflection.AST.Literal hiding (_≟_)open import Reflection.AST.Argument using (Arg; unArg; arg)open import Reflection.AST.DeBruijnopen import Reflection.AST.Showopen import Relation.Nullary.Decidable using (does)open import Effect.Monadopen RawMonad {{...}}open import Data.Maybe.Instancesopen import Reflection.TCM.Instancesprivatevariablea b : LevelA : Set aB : Set b-- As the doc states (cf. https://agda.readthedocs.io/en/latest/language/reflection.html#type-checking-computations)-- Note that the types in the context are valid in the rest of the context.-- To use in the current context they need to be weakened by 1 + their position-- in the list.-- That is to say that the type of the current goal needs to be strengthened-- before being compared to the type of the most local variable. The goal-- indeed lives below that variable's binding site!searchEntry : ℕ → Type → List (String × Arg Type) → Maybe ℕsearchEntry n ty [] = nothingsearchEntry n ty ((_ , e) ∷ es) = doty ← strengthen tyif does (ty ≟ unArg e)then just nelse searchEntry (suc n) ty esmacroassumption : Term → TC ⊤assumption hole = doasss ← getContextgoal ← inferType holedebugPrint "" 10(strErr "Context : "∷ concatMap (λ where (_ , arg info ty) → strErr "\n " ∷ termErr ty ∷ []) asss)let res = searchEntry 0 goal assscase res of λ wherenothing → typeError (strErr "Couldn't find an assumption of type: " ∷ termErr goal ∷ [])(just idx) → unify hole (var idx [])test₀ : A → B → Btest₀ x y = assumptiontest₁ : A → B → Atest₁ x y = assumptiontest₂ : A → B → B → Atest₂ x y z = assumptiontest₃ : List (A → B) → A → B → B → List (A → B)test₃ x y z a = assumptiontest₄ : (A → List B) → A → B → List B → A → List Btest₄ x y z a = assumptionopen import IO.Base using (Main; run)open import IO.Finiteopen import IO.InstancesmacrorunTC : TC String → Term → TC ⊤runTC tc t = dou ← tcunify t (lit (string u))main : Mainmain = run $ doputStrLn $ runTC (showDefinition <$> getDefinition (quote test₀))putStrLn $ runTC (showDefinition <$> getDefinition (quote test₁))putStrLn $ runTC (showDefinition <$> getDefinition (quote test₂))putStrLn $ runTC (showDefinition <$> getDefinition (quote test₃))putStrLn $ runTC (showDefinition <$> getDefinition (quote test₄))
name: tcminclude: ../../../src/ .
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
IO.Base.MainΠ ({a} : Agda.Primitive.Level) (Π (_ : Agda.Builtin.String.String) (IO.Base.IO {var 1} (Data.Unit.Polymorphic.Base.⊤ {var 1})))
{-# OPTIONS --guardedness #-}module Main where-- Taken from #1530open import Data.String.Base using (String)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Unit using (⊤; tt)open import Reflection.AST.Literalopen import Reflection.AST.Termopen import Reflection.AST.Show using (showTerm)open import Reflection.TCM using (TC; inferType; unify)open import Effect.Monadopen RawMonad {{...}} public using (pure; _>>=_; _>>_)open import Data.Maybe.Instancesopen import Reflection.TCM.InstancesmacrogoalErr : Term → Term → TC ⊤goalErr t goal = dogoalType ← inferType tunify goal (lit (string (showTerm goalType)))open import IO.Base hiding (_>>=_; _>>_)open import IO.Finiteopen import IO.Instancesopen import Function.Base using (_$_)main : Mainmain = run $ doputStrLn (goalErr main)putStrLn (goalErr putStrLn)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: pythagoreaninclude: ../../../src/ .
3² + 4² = 5²4² + 3² = 5²5² + 12² = 13²6² + 8² = 10²7² + 24² = 25²8² + 6² = 10²8² + 15² = 17²9² + 12² = 15²9² + 40² = 41²10² + 24² = 26²11² + 60² = 61²12² + 5² = 13²12² + 9² = 15²12² + 16² = 20²12² + 35² = 37²13² + 84² = 85²14² + 48² = 50²15² + 8² = 17²15² + 20² = 25²15² + 36² = 39²16² + 12² = 20²16² + 30² = 34²16² + 63² = 65²18² + 24² = 30²18² + 80² = 82²20² + 15² = 25²20² + 21² = 29²20² + 48² = 52²21² + 20² = 29²21² + 28² = 35²21² + 72² = 75²24² + 7² = 25²24² + 10² = 26²24² + 18² = 30²24² + 32² = 40²24² + 45² = 51²24² + 70² = 74²25² + 60² = 65²27² + 36² = 45²28² + 21² = 35²28² + 45² = 53²28² + 96² = 100²30² + 16² = 34²30² + 40² = 50²30² + 72² = 78²32² + 24² = 40²32² + 60² = 68²33² + 44² = 55²33² + 56² = 65²35² + 12² = 37²35² + 84² = 91²36² + 15² = 39²36² + 27² = 45²36² + 48² = 60²36² + 77² = 85²39² + 52² = 65²39² + 80² = 89²40² + 9² = 41²40² + 30² = 50²40² + 42² = 58²40² + 75² = 85²42² + 40² = 58²42² + 56² = 70²44² + 33² = 55²45² + 24² = 51²45² + 28² = 53²45² + 60² = 75²48² + 14² = 50²48² + 20² = 52²48² + 36² = 60²48² + 55² = 73²48² + 64² = 80²51² + 68² = 85²52² + 39² = 65²54² + 72² = 90²55² + 48² = 73²56² + 33² = 65²56² + 42² = 70²57² + 76² = 95²60² + 11² = 61²60² + 25² = 65²60² + 32² = 68²60² + 45² = 75²60² + 63² = 87²60² + 80² = 100²63² + 16² = 65²63² + 60² = 87²64² + 48² = 80²65² + 72² = 97²68² + 51² = 85²70² + 24² = 74²72² + 21² = 75²72² + 30² = 78²72² + 54² = 90²72² + 65² = 97²75² + 40² = 85²76² + 57² = 95²77² + 36² = 85²80² + 18² = 82²80² + 39² = 89²80² + 60² = 100²84² + 13² = 85²84² + 35² = 91²96² + 28² = 100²
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Bool.Base using (if_then_else_)open import Data.List.Base using (List; []; _∷_; catMaybes)open import Data.List.Effectful.Transformeropen import Data.List.Effectfulopen import Data.Maybe.Base using (just; nothing)open import Data.Maybe.Effectful.Transformeropen import Data.Nat.Base using (ℕ; zero; suc; _+_; _^_; _≡ᵇ_)open import Data.Nat.Show using (show)open import Data.Product.Base using (_×_; _,_)open import Data.String.Base using (_++_)open import Function.Base using (_$_)open import Effect.Applicativeopen import Effect.Monadopen import Effect.Monad.Identityopen import IO.Base using (Main; run)open import IO.Finite using (putStrLn)open import Data.List.Instancesopen import Data.Maybe.Instancesopen import Effect.Monad.Identity.Instancesopen import IO.Instancesopen RawMonad {{...}}open RawApplicativeZero {{...}} using (guard)open TraversableA {{...}}1⋯100 : List ℕ1⋯100 = rangeFrom 1 100 whererangeFrom : (start steps : ℕ) → List ℕrangeFrom start zero = []rangeFrom start (suc n) = start ∷ rangeFrom (suc start) ntriples : MaybeT (ListT Identity) (ℕ × ℕ × ℕ)triples = dolet range = mkMaybeT (mkListT (pure (pure <$> 1⋯100)))p ← rangeq ← ranger ← rangemkMaybeT (mkListT (pure (pure (guard (p ^ 2 + q ^ 2 ≡ᵇ r ^ 2)))))pure (p , q , r)main : Mainmain = run$ ignore $ forA (catMaybes $ runIdentity $ runListT $ runMaybeT triples)$ λ (p , q , r) → do let sqStr = λ x → show x ++ "²"putStrLn (sqStr p ++ " + " ++ sqStr q ++ " = " ++ sqStr r)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: fibonacciinclude: ../../../src/ .
fib 0 = 0fib 1 = 1fib 2 = 1fib 3 = 2fib 5 = 5fib 6 = 8fib 7 = 13fib 8 = 21fib 9 = 34fib 10 = 55
{-# OPTIONS --guardedness --rewriting #-}module Main whereopen import Data.Bool.Base using (Bool; true; false)open import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Nat.Show using (show)open import Data.Product.Base using (_,_)open import Data.String.Base using (String; _++_)open import Data.Defaultopen import Debug.Trace using (trace)open import IO.Base using (Main; run)open import IO.Finite using (putStrLn)open import Function.Base using (_$_)open import Effect.Monadopen import Effect.Monad.Stateopen import Effect.Monad.State.Instancesopen import Effect.Monad.Identity.Instancesopen import IO.Instancesopen RawMonad {{...}}open RawMonadState {{...}}record Fib : Set wherefield tracing : Boolindex : ℕcurrent : ℕnext : ℕopen FibinitFib : Bool → FibinitFib b = record{ tracing = b; index = 0; current = 0; next = 1}displayFib : ℕ → ℕ → StringdisplayFib idx fibn = "fib " ++ show idx ++ " = " ++ show fibnfibM : ℕ → State Fib ℕfibM 0 = gets currentfibM (suc n) = dob ← gets tracingwhen b $ doidx ← gets indexfibn ← gets currenttrace (displayFib idx fibn) (pure _)modify (λ r → record r { index = suc (index r) ; current = next r ; next = next r + current r })fibM nfib : ℕ → Bool → ℕfib n b = evalState (fibM n) (initFib b)fibStr : ℕ → {{WithDefault false}} → StringfibStr n {{b}} = displayFib n (fib n (value b))main : Mainmain = run $ doputStrLn $ fibStr 0putStrLn $ fibStr 1putStrLn $ fibStr 2putStrLn $ fibStr 3putStrLn $ fibStr 5putStrLn $ fibStr 6putStrLn $ fibStr 7putStrLn $ fibStr 8putStrLn $ fibStr 9putStrLn $ fibStr 10
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
First: 1Second: 3Third: 8
name: countinginclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Data.Nat.Baseopen import Data.Nat.Show using (show)open import Data.Product.Base using (_,_)open import Data.String.Base using (String; _++_)open import IO.Base as IO using (IO; Main; run)open import IO.Finite using (putStrLn)open import IO.Effectful as IOopen import Function.Base using (_∘′_; _$_; const)open import Level using (Lift; 0ℓ; lift; lower)open import Effect.Monadopen import Effect.Monad.Reader.Transformer as Readeropen import Effect.Monad.State.Transformer as Stateopen import Effect.Monad.IOopen import IO.Instancesopen import Effect.Monad.IO.Instancesopen import Effect.Monad.State.Instancesopen import Effect.Monad.Reader.Instancesopen RawMonad {{...}}open RawMonadReader {{...}}open RawMonadState {{...}}open RawMonadIO {{...}}step : ∀ {M : Set Level.zero → Set (Level.suc Level.zero)} →{{RawMonad M}} →{{RawMonadReader String M}} →{{RawMonadState ℕ M}} →{{RawMonadIO M}} →(ℕ → ℕ) →M _step f = domodify fstr ← askn ← getlet msg = str ++ show nliftIO (putStrLn msg)script : ∀ {M} →{{RawMonad M}} →{{RawMonadReader String M}} →{{RawMonadState ℕ M}} →{{RawMonadIO M}} →M _script = dostep suclocal (const "Second: ") $ step (3 *_)local (const "Third: ") $ step (2 ^_)it : ∀ {a} {A : Set a} → {{A}} → Ait {{x}} = xmain : Mainmain = run $ evalStateT it (runReaderT script "First: ") 0
name: trieinclude: ../../../src/ .
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
ID "fix"ID "f"ID "x"EQLETID "b"EQID "fix"ID "f"INLPARID "f"ID "b"RPARID "x"
-- Taken from README.Data.Trie.NonDependent{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Levelopen import Data.Unitopen import Data.Boolopen import Data.Char as Char hiding (show)import Data.Char.Properties as Charopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.Fresh as List# using (List#; []; _∷#_)open import Data.Maybe as Maybeopen import Data.Product as Prodopen import Data.String as String using (String; unlines; _++_)open import Data.These as Theseopen import Function.Base using (case_of_; _$_; _∘′_; id; _on_)open import Relation.Naryopen import Relation.Binary.Core using (Rel)open import Relation.Nullary.Decidable using (¬?)open import Data.Trie Char.<-strictTotalOrderopen import Data.Tree.AVL.Valueopen import IO.Baseopen import IO.Finiterecord Lexer t : Set (suc t) wherefieldTok : Set tKeyword : Set tKeyword = String × TokDistinct : Rel Keyword 0ℓDistinct a b = ⌊ ¬? ((proj₁ a) String.≟ (proj₁ b)) ⌋fieldkeywords : List# Keyword Distinctbreaking : Char → ∃ λ b → if b then Maybe Tok else Lift _ ⊤default : String → Tokmodule _ {t} (L : Lexer t) whereopen Lexer Ltokenize : String → List Toktokenize = start ∘′ String.toList wheremutualKeywords : Set _Keywords = Trie (const _ Tok) _init : Keywordsinit = fromList $ List.map (Prod.map₁ String.toList) $ proj₁ $ List#.toList keywordsstart : List Char → List Tokstart = loop [] initloop : (acc : List Char) → -- chars read so far in this token(toks : Keywords) → -- keyword candidates left at this point(input : List Char) → -- list of chars to tokenizeList Tokloop acc toks [] = push acc []loop acc toks (c ∷ cs) = case breaking c of λ where(true , m) → push acc $ maybe′ _∷_ id m $ start cs(false , _) → case lookupValue toks (c ∷ []) of λ where(just tok) → tok ∷ start csnothing → loop (c ∷ acc) (lookupTrie toks c) cspush : List Char → List Tok → List Tokpush [] ts = tspush cs ts = default (String.fromList (List.reverse cs)) ∷ tsmodule LetIn wheredata TOK : Set whereLET EQ IN : TOKLPAR RPAR : TOKID : String → TOKshow : TOK → Stringshow LET = "LET"show EQ = "EQ"show IN = "IN"show LPAR = "LPAR"show RPAR = "RPAR"show (ID x) = "ID \"" ++ x ++ "\""keywords : List# (String × TOK) (λ a b → ⌊ ¬? ((proj₁ a) String.≟ (proj₁ b)) ⌋)keywords = ("let" , LET)∷# ("=" , EQ)∷# ("in" , IN)∷# []breaking : Char → ∃ (λ b → if b then Maybe TOK else Lift 0ℓ ⊤)breaking c = if isSpace c then true , nothing else parens c whereparens : Char → _parens '(' = true , just LPARparens ')' = true , just RPARparens _ = false , _default : String → TOKdefault = IDletIn : Lexer 0ℓletIn = record { LetIn }main : Mainmain = run $ dolet open LetInputStrLn $ unlines $ List.map show $tokenize letIn "fix f x = let b = fix f in (f b) x"
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: rationalinclude: ../../../src/ .
[-4, -3, -2, -1, 0, 1, 2, 3][-3, -2, -1, 0, 1, 2, 3, 4][-3, -2, -1, 0, 0, 1, 2, 3][-4, -3, -2, 0, 0, 2, 3, 4][5/10, 7/10, 5/10, 3/10, 3/10, 5/10, 7/10, 5/10]
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Data.Integer.Base using (ℤ; +_)import Data.Integer.Show as ℤopen import Data.List.Base as List using (List; _∷_; [])import Data.Nat.Baseopen import Data.Rational.Unnormalised.Baseusing (ℚᵘ; -_; _/_; floor; ceiling; truncate; round; fracPart)import Data.Rational.Unnormalised.Show as ℚᵘopen import Data.String.Base as String using (String)open import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_)testList : List ℚᵘtestList = - (+ 35 / 10) ∷ - (+ 27 / 10) ∷ - (+ 15 / 10) ∷ - (+ 3 / 10)∷ + 3 / 10 ∷ + 15 / 10 ∷ + 27 / 10 ∷ + 35 / 10 ∷ []showInts : List ℤ → StringshowInts is = String.concat$ "["∷ String.intersperse ", " (List.map ℤ.show is)∷ "]" ∷ []showRats : List ℚᵘ → StringshowRats ps = String.concat$ "["∷ String.intersperse ", " (List.map ℚᵘ.show ps)∷ "]" ∷ []main : Mainmain = run $ doputStrLn $ showInts (List.map floor testList)putStrLn $ showInts (List.map ceiling testList)putStrLn $ showInts (List.map truncate testList)putStrLn $ showInts (List.map round testList)putStrLn $ showRats (List.map fracPart testList)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: rationalinclude: ../../../src/ .
[-4, -3, -2, -1, 0, 1, 2, 3][-3, -2, -1, 0, 1, 2, 3, 4][-3, -2, -1, 0, 0, 1, 2, 3][-4, -3, -2, 0, 0, 2, 3, 4][1/2, 7/10, 1/2, 3/10, 3/10, 1/2, 7/10, 1/2]
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Data.Integer.Base using (ℤ; +_)import Data.Integer.Show as ℤopen import Data.List.Base as List using (List; _∷_; [])import Data.Nat.Baseopen import Data.Rational.Baseusing (ℚ; -_; _/_; floor; ceiling; truncate; round; fracPart)import Data.Rational.Show as ℚopen import Data.String.Base as String using (String)open import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_)testList : List ℚtestList = - (+ 35 / 10) ∷ - (+ 27 / 10) ∷ - (+ 15 / 10) ∷ - (+ 3 / 10)∷ + 3 / 10 ∷ + 15 / 10 ∷ + 27 / 10 ∷ + 35 / 10 ∷ []showInts : List ℤ → StringshowInts is = String.concat$ "["∷ String.intersperse ", " (List.map ℤ.show is)∷ "]" ∷ []showRats : List ℚ → StringshowRats ps = String.concat$ "["∷ String.intersperse ", " (List.map ℚ.show ps)∷ "]" ∷ []main : Mainmain = run $ doputStrLn $ showInts (List.map floor testList)putStrLn $ showInts (List.map ceiling testList)putStrLn $ showInts (List.map truncate testList)putStrLn $ showInts (List.map round testList)putStrLn $ showRats (List.map fracPart testList)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
name: listinclude: ../../../src/ .
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19][14, 36, 20, 16, 15, 196, 13, 12, 11, 20, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 20, 20, 36, 196][14, 18, 17, 16, 15, 392, 13, 12, 11, 20, 9, 11, 7, 6, 5, 4, 3, 2, 1, 0][0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 11, 12, 13, 14, 15, 16, 17, 18, 20, 392]
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Levelopen import Data.List.Base as List using (List; _∷_; []; _++_; reverse)open import Data.List.Zipperimport Data.List.Sort as Sortopen import Data.Maybe.Baseopen import Data.Nat.Baseopen import Data.Nat.Show using (show)import Data.Nat.Properties as ℕₚopen import Data.String.Base as String using (String)import Data.Vec.Base as Vecopen import Codata.Sized.Stream using (nats; take)open Sort ℕₚ.≤-decTotalOrderopen import IO.Baseopen import IO.Finiteopen import Function.Base using (_$_; _∘_)privatevariablea : LevelA : Set adata Direction : Set where Left Right : Directionturn : Direction → Zipper A → Zipper Aturn Left zip = fromMaybe zip (left zip)turn Right zip = fromMaybe zip (right zip)follow : List Direction → Zipper A → Zipper Afollow dirs init = go dirs init wherego : List Direction → Zipper A → Zipper Ago [] zip = zipgo (d ∷ dirs) zip = go dirs (turn d zip)updateFocus : (A → A) → Zipper A → Zipper AupdateFocus f (mkZipper ctx (a ∷ val)) = mkZipper ctx (f a ∷ val)updateFocus f zip = zipupdateAt : List Direction → (A → A) → Zipper A → Zipper AupdateAt dirs f = updateFocus f ∘ follow dirsapplyAt : List Direction → (A → A) → List A → List AapplyAt dirs f xs = toList$ updateFocus f$ follow dirs$ fromList xssomeNats : List ℕsomeNats = Vec.toList $ take 20 $ natsotherNats : List ℕotherNats= applyAt (Right ∷ Right ∷ []) (3 +_)$ applyAt (List.replicate 10 Right ++ Left ∷ []) (10 +_)$ applyAt (List.replicate 10 Left) (_∸ 5)$ applyAt (Left ∷ Right ∷ Right ∷ Left ∷ []) (2 *_)$ applyAt (List.replicate 5 Right) (_^ 2)$ List.reverse someNatschaoticNats : List ℕchaoticNats= toList$ updateAt (Right ∷ Right ∷ []) (3 +_)$ updateAt (List.replicate 10 Right ++ Left ∷ []) (10 +_)$ updateAt (List.replicate 10 Left) (_∸ 5)$ updateAt (Left ∷ Right ∷ Right ∷ Left ∷ []) (2 *_)$ updateAt (List.replicate 5 Right) (_^ 2)$ fromList$ List.reverse someNatsshowNats : List ℕ → StringshowNats ns = String.concat$ "["∷ String.intersperse ", " (List.map show ns)∷ "]" ∷ []main : Mainmain = run $ doputStrLn $ showNats someNatsputStrLn $ showNats otherNatsputStrLn $ showNats $ sort otherNatsputStrLn $ showNats chaoticNatsputStrLn $ showNats $ sort chaoticNats
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
λ 0(λ 0) ((λ 0) (λ 0) ((λ 0) (λ 0)))(λ 0) (λ 0) ((λ 0) (λ 0))(λ 0) ((λ 0) (λ 0))(λ 0) (λ 0)λ 0
name: colistinclude: ../../../src/ .
{-# OPTIONS --guardedness --sized-types #-}module Main whereopen import Level using (0ℓ)open import Sizeopen import Data.Bool.Base using (Bool; true; false; if_then_else_)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Finimport Data.Fin.Show as Finopen import Data.String.Base using (String; _++_; parens)open import Data.Unit.Polymorphic.Base using (⊤)open import Codata.Sized.Thunkopen import Function.Base using (_$_; _∘_; id)open import Relation.Nullaryopen import Codata.Musical.Notationopen import Codata.Sized.Colist using (Colist; _∷_; [])open import Codata.Musical.Colist renaming (Colist to Colist♩) using (_∷_; [])open import Codata.Musical.Conversionvariablei : Sizem n : ℕA : Setdata Lam (n : ℕ) : Set wherevar : Fin n → Lam napp : Lam n → Lam n → Lam nlam : Lam (suc n) → Lam ndata Loc : Set where appL appR lam : LocappParens : Loc → String → StringappParens appR str = parens strappParens _ str = strlamParens : Loc → String → StringlamParens lam str = strlamParens _ str = parens strshow : Loc → Lam n → Stringshow i (var v) = Fin.show vshow i (app f t) = appParens i $ show appL f ++ " " ++ show appR tshow i (lam b) = lamParens i $ "λ " ++ show lam bvariableb f t : Lam n_∙_ : (Fin m → A) → A → Fin (suc m) → A(ρ ∙ v) zero = v(ρ ∙ v) (suc k) = ρ krename : (Fin m → Fin n) → Lam m → Lam nrename ρ (var v) = var (ρ v)rename ρ (app f t) = app (rename ρ f) (rename ρ t)rename ρ (lam b) = lam (rename ((suc ∘ ρ) ∙ zero) b)subst : (Fin m → Lam n) → Lam m → Lam nsubst ρ (var v) = ρ vsubst ρ (app f t) = app (subst ρ f) (subst ρ t)subst ρ (lam b) = lam (subst ((rename suc ∘ ρ) ∙ var zero) b)data Redex {n} : Lam n → Set wherehere : ∀ b t → Redex (app (lam b) t)lam : Redex b → Redex (lam b)appL : Redex f → ∀ t → Redex (app f t)appR : ∀ f → Redex t → Redex (app f t)redex : ∀ {n} (t : Lam n) → Dec (Redex t)redex (var v) = no (λ ())redex (app (lam b) t) = yes (here b t)redex (app f@(var _) t) with redex t... | yes rt = yes (appR f rt)... | no nrt = no λ where (appR _ rt) → nrt rtredex (app f@(app _ _) t) with redex f | redex t... | yes rf | _ = yes (appL rf t)... | _ | yes rt = yes (appR f rt)... | no nrf | no nrt = no λ where(appL rf _) → nrf rf(appR _ rt) → nrt rtredex (lam b) with redex b... | yes rb = yes (lam rb)... | no nrb = no λ where (lam rb) → nrb rbfire : Redex {n} t → Lam nfire (here b t) = subst (var ∙ t) bfire (lam rt) = lam (fire rt)fire (appL rf t) = app (fire rf) tfire (appR f rt) = app f (fire rt)eval : Lam n → Colist (Lam n) ieval t with redex t... | yes rt = t ∷ λ where .force → eval (fire rt)... | no nrt = t ∷ λ where .force → []open import IO.Baseopen import IO.Finitetrace : Colist♩ (Lam n) → IO {0ℓ} ⊤trace [] = pure _trace (t ∷ ts) = seq (♯ putStrLn (show lam t))(♯ trace (♭ ts))`id : Lam 0`id = lam (var (# 0))main : Mainmain = run $ dotrace (Colist.toMusical $ eval `id)trace (Colist.toMusical $ eval (app `id (app (app `id `id) (app `id `id))))
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
"\SOH\STX\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\ETX"------------------------------------------------------------------------1 = 0b000000011 = 0x011 = 1144 = 0b10010000144 = 0x90144 = 144------------------------------------------------------------------------2 = 0b00000000000000000000000000000000000000000000000000000000000000102 = 0x000000022 = 2------------------------------------------------------------------------3 = 0b00000000000000000000000000000000000000000000000000000000000000113 = 0x000000033 = 3------------------------------------------------------------------------2024 = 0b00000000000000000000000000000000000000000000000000000111111010002024 = 0x000007e82024 = 2024
name: bytestringinclude: ../../../src/ .
{-# OPTIONS --guardedness #-}module Main whereopen import Agda.Builtin.FromNatopen import Data.Bytestring.Base as Bytestringopen import Data.Bytestring.Builder.Baseopen import Data.List.Base using ([]; _∷_)import Data.Nat.Literals; instance numberNat = Data.Nat.Literals.numberopen import Data.Product.Base using (_×_; _,_)open import Data.String using (String; _++_; fromVec)open import Data.Unit.Base using (⊤; tt)import Data.Vec.Base as Vecopen import Data.Word8.Base as Word8import Data.Word8.Show as Word8import Data.Word8.Literals; instance numberWord8 = Data.Word8.Literals.numberopen import Data.Word64.Base as Word64 using (Word64)import Data.Word64.Unsafe as Word64import Data.Word64.Show as Word64import Data.Word64.Literals; instance numberWord64 = Data.Word64.Literals.numberopen import Function.Base using (_$_)open import IO.Baseopen import IO.Finite1⋯3 : Bytestring1⋯3 = toBytestring$ List.concat$ word8 1∷ word64LE 2∷ word64BE 3∷ []1,⋯,3 : Word8 × Word64 × Word641,⋯,3 = getWord8 1⋯3 0, getWord64LE 1⋯3 1, getWord64BE 1⋯3 9main : Mainmain = run $ dolet separation = fromVec (Vec.replicate 72 '-')putStrLn (Bytestring.show 1⋯3)putStrLn separationlet (one , two , three) = 1,⋯,3let word8test : Word8 → IO _word8test w = doputStrLn (Word8.show w ++ " = " ++ Word8.showBits w)putStrLn (Word8.show w ++ " = " ++ Word8.showHexa w)putStrLn (Word8.show w ++ " = " ++ Word8.show (Word8.fromBits (Word8.toBits w)))let word64test : Word64 → IO _word64test w = doputStrLn separationputStrLn (Word64.show w ++ " = " ++ Word64.showBits w)putStrLn (Word64.show w ++ " = " ++ Word64.showHexa w)putStrLn (Word64.show w ++ " = " ++ Word64.show (Word64.fromBits (Word64.toBits w)))word8test oneword8test (Word8.fromℕ 144)word64test twoword64test threeword64test (Word64.fromℕ 2024)
$1 --compile-dir=../../_build -c Main.agda > log./../../_build/Main < input > outputrm ../../_build/Mainrm ../../_build/MAlonzo/Code/Main*
helLoteSTparcequecestnotrePROJEEET
helteparcequecestnotre
name: listinclude: ../../../src/ .
{-# OPTIONS --safe --cubical-compatible #-}module TakeWhile whereopen import Levelopen import Data.List.Base hiding (takeWhile)open import Data.List.Relation.Unary.All as List using ([]; _∷_)open import Data.List.Relation.Binary.Pointwise using (Pointwise; []; _∷_; refl)open import Data.List.Relation.Ternary.Appending.Propositionalopen import Data.Product.Base using (_×_; proj₁)open import Data.Maybe.Relation.Unary.All as Maybe using (nothing; just)import Data.Natopen import Relation.Unaryopen import Relation.Binary.PropositionalEquality as P using (_≡_)open import Relation.Nullaryopen import Relation.Nullary.Product-- Original bug reported in #1765 by James Wood_ : Appending (3 ∷ []) (2 ∷ []) (3 ∷ 2 ∷ [])_ = P.refl ∷ []++ P.refl ∷ []variablea p : LevelA : Set aP : A → Set pinfix 1 _,_,_record TakeWhile {A : Set a} (P : A → Set p) xs : Set (a ⊔ p) whereconstructor _,_,_field{prefix rest} : List AgoodPrefix : List.All P prefixisPrefix : Appending prefix rest xsisBiggest : Maybe.All (proj₁ ⊢ ∁ P) (uncons rest)open TakeWhile publictakeWhile : Decidable P → Π[ TakeWhile P ]takeWhile P? [] = [] , []++ [] , nothingtakeWhile P? (x ∷ xs) with P? x... | yes px = let (pxs' , prf , biggest) = takeWhile P? xs inpx ∷ pxs' , P.refl ∷ prf , biggest... | no ¬px = [] , []++ refl P.refl , just ¬pxopen import Data.Charopen import Data.String using (toList)lower? : (c : Char) → Dec ('a' ≤ c × c ≤ 'z')lower? c = 'a' ≤? c ×-dec c ≤? 'z'_ : takeWhile lower? (toList "helLo")≡ record { prefix = toList "hel"; isPrefix = P.refl ∷ P.refl ∷ P.refl ∷ []++ P.refl ∷ P.refl ∷ []}_ = P.refl
{-# OPTIONS --guardedness #-}module Main whereopen import Data.List.Base using (replicate)open import Data.String using (toList; fromList)open import IOopen import Function.Base using (_$_)open import TakeWhilemain : Mainmain = run $ List.sequence′ $ replicate 3 $ dostr ← getLinelet taken = takeWhile lower? (toList str)putStrLn $ fromList (taken .prefix)
INTERACTIVE ?= --interactiveruntests: runtests.agdarm -f _build/runtestsrm -f _build/MAlonzo/Code/Qruntests*$(AGDA) --compile-dir=_build/ -c runtests.agdatest: runtests./_build/runtests $(AGDA_EXEC) $(INTERACTIVE) --timing --failure-file failures --only $(only)retest: runtests./_build/runtests $(AGDA_EXEC) $(INTERACTIVE) --timing --failure-file failures --only-file failures --only $(only)
name: standard-library-2.1include: srcflags:--warning=noUnsupportedIndexedMatch
resolver: nightly-2023-08-27compiler: ghc-9.6.2compiler-check: match-exactpackages:- '.'
resolver: lts-21.7compiler: ghc-9.4.5compiler-check: match-exactpackages:- '.'
resolver: lts-20.26compiler: ghc-9.2.8compiler-check: match-exactpackages:- '.'
resolver: lts-19.33compiler: ghc-9.0.2compiler-check: match-exactpackages:- '.'
resolver: lts-16.31compiler: ghc-8.8.4compiler-check: match-exactpackages:- '.'
resolver: lts-16.5compiler: ghc-8.8.3compiler-check: match-exactpackages:- '.'
resolver: lts-15.3compiler: ghc-8.8.2compiler-check: match-exactpackages:- '.'
resolver: lts-14.27compiler: ghc-8.6.5compiler-check: match-exactpackages:- '.'
resolver: lts-12.26compiler: ghc-8.4.4compiler-check: match-exactpackages:- '.'
resolver: lts-11.22compiler: ghc-8.2.2compiler-check: match-exactpackages:- '.'
resolver: lts-18.23compiler: ghc-8.10.7compiler-check: match-exact# extra-deps:# - filemanip-0.3.6.3# - unix-compat-0.5.2packages:- '.'
resolver: lts-18.0compiler: ghc-8.10.5compiler-check: match-exact# extra-deps:# - filemanip-0.3.6.3# - unix-compat-0.5.2packages:- '.'
resolver: lts-9.21compiler: ghc-8.0.2compiler-check: match-exactpackages:- '.'
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use the Data.Tree.Rose.Show module-- directly------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Text.Tree.Linear whereopen import Data.Tree.Rose.Show public using (display){-# WARNING_ON_IMPORT"Text.Tree.Linear was deprecated in v1.6. Use Data.Tree.Rose.Show instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Fancy display functions for Vec-based tables------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Text.Tabular.Vec whereopen import Data.List.Base using (List)open import Data.Product.Base as Prod using (uncurry)open import Data.String using (String; rectangle; fromAlignment)open import Data.Vec.Baseopen import Function.Baseopen import Text.Tabular.Basedisplay : ∀ {m n} → TabularConfig → Vec Alignment n → Vec (Vec String n) m →List Stringdisplay c a = unsafeDisplay c∘ toList∘ map toList∘ transpose∘ map (uncurry rectangle ∘ unzip)∘ transpose∘ map (zip (map fromAlignment a))
-------------------------------------------------------------------------- The Agda standard library---- Fancy display functions for List-based tables------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Text.Tabular.List whereopen import Data.String.Base using (String)open import Data.List.Baseimport Data.Nat.Properties as ℕopen import Data.Product.Base using (-,_; proj₂)open import Data.Vec.Base as Vec using (Vec)open import Data.Vec.Bounded.Base as Vec≤ using (Vec≤)open import Function.Baseopen import Text.Tabular.Baseimport Text.Tabular.Vec as Showdisplay : TabularConfig → List Alignment → List (List String) → List Stringdisplay c a rows = Show.display c alignment rectanglewherealignment : Vec Alignment _alignment = Vec≤.padRight Left$ Vec≤.≤-cast (ℕ.m⊓n≤m _ _)$ Vec≤.take _ (Vec≤.fromList a)rectangle : Vec (Vec String _) _rectangle = Vec.fromList$ map (Vec≤.padRight "")$ proj₂$ Vec≤.rectangle$ map (λ row → -, Vec≤.fromList row) rows
-------------------------------------------------------------------------- The Agda standard library---- Fancy display functions for List-based tables---- The functions in this module assume some (unenforced) invariants.-- If you cannot guarantee that your data respects these invariants,-- you should instead use Text.Tabular.List.------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Text.Tabular.Base whereopen import Data.Bool.Base using (if_then_else_)open import Data.Char.Base using (Char)open import Data.List.Base as Listusing (List; []; _∷_; _?∷_; _++_; _∷ʳ?_; null; map; intersperse)open import Data.Maybe.Base as Maybe using (Maybe; nothing; just; maybe)open import Data.Nat.Baseopen import Data.String.Base as Stringusing (String; fromChar; unlines; replicate; length)open import Function.Baseopen import Agda.Builtin.Equalityopen Stringusing ( Alignment; Left; Center; Right) publicrecord TabularLine : Set wherefieldleft : Maybe Stringcont : Maybe Charsep : Stringright : Maybe Stringopen TabularLinerecord TabularConfig : Set wherefieldtop : Maybe TabularLinesep : Maybe TabularLinerow : TabularLinebot : Maybe TabularLineopen TabularConfigunicode : TabularConfigunicode .top = just λ where.left → just "┌".cont → just '─'.sep → "┬".right → just "┐"unicode .sep = just λ where.left → just "├".cont → just '─'.sep → "┼".right → just "┤"unicode .row = λ where.left → just "│".cont → nothing.sep → "│".right → just "│"unicode .bot = just λ where.left → just "└".cont → just '─'.sep → "┴".right → just "┘"ascii : TabularConfigascii .top = just λ where.left → just "+".cont → just '-'.sep → "-".right → just "+"ascii .sep = just λ where.left → just "|".cont → just '-'.sep → "+".right → just "|"ascii .row = λ where.left → just "|".cont → nothing.sep → "|".right → just "|"ascii .bot = just λ where.left → just "+".cont → just '-'.sep → "-".right → just "+"compact : TabularConfig → TabularConfigcompact c = record c { sep = nothing }privatedropBorder : TabularLine → TabularLinedropBorder l = record l { left = nothing; right = nothing }noBorder : TabularConfig → TabularConfignoBorder c .top = nothingnoBorder c .sep = Maybe.map dropBorder (c .sep)noBorder c .row = dropBorder (c .row)noBorder c .bot = nothingprivatespace : TabularLine → TabularLinespace l = let pad = maybe fromChar " " (l .cont) in λ where.left → Maybe.map (String._++ pad) (l .left).cont → l .cont.sep → pad String.++ l .sep String.++ pad.right → Maybe.map (pad String.++_) (l .right)addSpace : TabularConfig → TabularConfigaddSpace c .top = Maybe.map space (c .top)addSpace c .sep = Maybe.map space (c .sep)addSpace c .row = space (c .row)addSpace c .bot = Maybe.map space (c .bot)whitespace : TabularConfigwhitespace .top = nothingwhitespace .sep = nothingwhitespace .row = λ where.left → nothing.cont → nothing.sep → " ".right → nothingwhitespace .bot = nothing-- /!\ Invariants:-- * the table is presented as a list of rows-- * header has the same length as each one of the rows-- i.e. we have a rectangular table-- * all of the strings in a given column have the same lengthunsafeDisplay : TabularConfig → List (List String) → List StringunsafeDisplay _ [] = []unsafeDisplay c (header ∷ rows) =map String.concat $ th ++ (trs ∷ʳ? lbot)wherecellsOf : Maybe Char → List String → List StringcellsOf nothing = idcellsOf (just c) = map (λ cell → replicate (length cell) c)lineOf : TabularLine → List String → List StringlineOf l xs = l .left?∷ intersperse (l .sep) (cellsOf (l .cont) xs)∷ʳ? l .rightmlineOf : Maybe TabularLine → List String → Maybe (List String)mlineOf l xs = Maybe.map (λ l → lineOf l xs) lltop : Maybe (List String)lsep : Maybe (List String)tr : List String → List Stringlbot : Maybe (List String)ltop = mlineOf (c. top) headerlsep = mlineOf (c. sep) headertr = lineOf (c. row)lbot = mlineOf (c. bot) headerth = ltop ?∷ tr header ∷ []trs = if null rows then id else (maybe _∷_ id lsep)$ maybe intersperse id lsep$ map tr rows
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions---- The content of this module (and others in the Regex subdirectory) is-- based on Alexandre Agular and Bassel Mannaa's 2009 technical report:-- Regular Expressions in Agda------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecPoset)module Text.Regex {a e r} (decPoset : DecPoset a e r) whereprivatepreorder = DecPoset.preorder decPosetimport Text.Regex.Base preorder as Regeximport Text.Regex.SmartConstructors preorder as Smartimport Text.Regex.Derivative.Brzozowski decPoset as Eatimport Text.Regex.Search decPoset as Search-------------------------------------------------------------------------- Re-exporting basic definition and semanticsopen Regex publicusing ( Range; module Range; [_]; _─_; Regex; module Regex; Exp; module Exp; ε; [^_]; ∅; ·; singleton; _∈ᴿ_; _∉ᴿ_; _∈_; _∉_; sum; prod; star)-------------------------------------------------------------------------- Re-exporting smart constructorsopen Smart publicusing (_∣_; _∙_; _⋆; _+; _⁇)-------------------------------------------------------------------------- Re-exporting semantics decidabilityopen Eat publicusing (_∈?_; _∉?_)-------------------------------------------------------------------------- Re-exporting search algorithmsopen Search publicusing (Span; toInfix; Match; mkMatch; search)
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions acting on strings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Text.Regex.String whereimport Data.Char.Properties as Char-------------------------------------------------------------------------- Re-exporting definitionsopen import Text.Regex Char.≤-decPoset public
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions acting on strings, using unsafe features------------------------------------------------------------------------{-# OPTIONS --with-K #-}module Text.Regex.String.Unsafe whereopen import Data.String.Base using (String; toList; fromList)import Data.String.Unsafe as Stringₚopen import Function.Base using (_on_; id)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.PropositionalEquality.Core using (_≡_; sym; subst)open import Relation.Nullary.Decidable using (map′)-------------------------------------------------------------------------- Re-exporting safe definitionsopen import Text.Regex.String as Regex publichiding (_∈_; _∉_; _∈?_; _∉?_; Span; Match; search)-------------------------------------------------------------------------- Specialised definitionsinfix 4 _∈_ _∉_ _∈?_ _∉?__∈_ : String → Exp → Setstr ∈ e = toList str Regex.∈ e_∉_ : String → Exp → Setstr ∉ e = toList str Regex.∉ e_∈?_ : Decidable _∈_str ∈? e = toList str Regex.∈? e_∉?_ : Decidable _∉_str ∉? e = toList str Regex.∉? eSpan : Regex → Rel String 0ℓSpan e = Regex.Span e _≡_ on toList-- A match is a string, a proof it matches the regular expression,-- and a proof it appears as the right sort of substring.record Match (str : String) (e : Regex) : Set whereconstructor mkMatchfieldstring : Stringmatch : string ∈ Regex.expression erelated : Span e string stropen Match publicsearch : Decidable Matchsearch str e = map′ from to (Regex.search input e) whereinput = toList strexp = Regex.expression efrom : Regex.Match (Regex.Span e _≡_) input exp → Match str efrom (Regex.mkMatch list match related) =let eq = sym (Stringₚ.toList∘fromList list) inmkMatch (fromList list)(subst (Regex._∈ exp) eq match)(subst (λ str → Regex.Span e _≡_ str input) eq related)to : Match str e → Regex.Match (Regex.Span e _≡_) input expto (mkMatch string match related) =Regex.mkMatch (toList string) match related
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions: smart constructors-- Computing the Brzozowski derivative of a regular expression may lead-- to a blow-up in the size of the expression. To keep it tractable it-- is crucial to use smart constructors.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder)module Text.Regex.SmartConstructors {a e r} (P : Preorder a e r) whereopen import Data.List.Base using ([])open import Data.List.Relation.Ternary.Appending.Propositionalopen import Data.Sum.Base using (inj₁; inj₂; fromInj₁; fromInj₂)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.PropositionalEquality.Core using (refl)open import Text.Regex.Base P as R hiding (_∣_; _∙_; _⋆)open import Text.Regex.Properties.Core P-------------------------------------------------------------------------- Suminfixr 5 _∣__∣_ : (e f : Exp) → Expe ∣ f with is-∅ e | is-∅ f... | yes _ | _ = f... | _ | yes _ = e... | _ | _ = e R.∣ f∣-sound : ∀ {w} e f → w ∈ (e ∣ f) → w ∈ (e R.∣ f)∣-sound e f p with is-∅ e | is-∅ f... | yes _ | _ = sum (inj₂ p)... | no _ | yes _ = sum (inj₁ p)... | no _ | no _ = p∣-complete : ∀ {w} e f → w ∈ (e R.∣ f) → w ∈ (e ∣ f)∣-complete e f pr@(sum p) with is-∅ e | is-∅ f... | yes refl | _ = fromInj₂ (λ p → contradiction p ∉∅) p... | no _ | yes refl = fromInj₁ (λ p → contradiction p ∉∅) p... | no _ | no _ = pr-------------------------------------------------------------------------- Productinfixr 6 _∙__∙_ : (e f : Exp) → Expe ∙ f with is-∅ e | is-ε e | is-∅ f | is-ε f... | yes _ | _ | _ | _ = R.∅... | _ | yes _ | _ | _ = f... | _ | _ | yes _ | _ = R.∅... | _ | _ | _ | yes _ = e... | _ | _ | _ | _ = e R.∙ f∙-sound : ∀ {w} e f → w ∈ (e ∙ f) → w ∈ (e R.∙ f)∙-sound e f p with is-∅ e | is-ε e | is-∅ f | is-ε f... | yes refl | _ | _ | _ = contradiction p ∉∅... | no _ | yes refl | _ | _ = prod ([] ++ _) ε p... | no _ | no _ | yes refl | _ = contradiction p ∉∅... | no _ | no _ | no _ | yes refl = prod (_ ++[]) p ε... | no _ | no _ | no _ | no _ = p∙-complete : ∀ {w} e f → w ∈ (e R.∙ f) → w ∈ (e ∙ f)∙-complete e f pr@(prod eq p q) with is-∅ e | is-ε e | is-∅ f | is-ε f... | yes refl | _ | _ | _ = contradiction p ∉∅... | no _ | yes refl | _ | _ = ∈ε∙e-inv pr... | no _ | no _ | yes refl | _ = contradiction q ∉∅... | no _ | no _ | no _ | yes refl = ∈e∙ε-inv pr... | no _ | no _ | no _ | no _ = pr-------------------------------------------------------------------------- Kleene starinfix 7 _⋆_⋆ : Exp → Expe ⋆ with is-∅ e | is-ε e... | yes _ | _ = R.ε... | _ | yes _ = R.ε... | _ | _ = e R.⋆⋆-sound : ∀ {w} e → w ∈ (e ⋆) → w ∈ (e R.⋆)⋆-sound e p with is-∅ e | is-ε e... | yes refl | _ = star (sum (inj₁ p))... | no _ | yes refl = star (sum (inj₁ p))... | no _ | no _ = p⋆-complete : ∀ {w} e → w ∈ (e R.⋆) → w ∈ (e ⋆)⋆-complete e pr with is-∅ e | is-ε e... | yes refl | no _ = ∈∅⋆-inv pr... | no _ | yes refl = ∈ε⋆-inv pr... | no _ | no _ = pr-------------------------------------------------------------------------- Derived notions: at least one and maybe oneinfixl 7 _+ _⁇_+ : Exp → Expe + = e ∙ e ⋆_⁇ : Exp → Exp∅ ⁇ = εe ⁇ = ε ∣ e
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions: search algorithms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecPoset)module Text.Regex.Search {a e r} (P? : DecPoset a e r) whereopen import Level using (_⊔_)open import Data.Bool.Base using (if_then_else_; true; false)open import Data.List.Base using (List; []; _∷_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (id; _∘′_; _∘_)open import Data.List.Relation.Binary.Prefix.Heterogeneoususing (Prefix; []; _∷_) hiding (module Prefix)open import Data.List.Relation.Binary.Infix.Heterogeneoususing (Infix; here; there) hiding (module Infix)import Data.List.Relation.Binary.Infix.Heterogeneous.Properties as Infixₚopen import Data.List.Relation.Binary.Pointwiseas Pointwise using (Pointwise; []; _∷_)open import Data.List.Relation.Binary.Suffix.Heterogeneoususing (Suffix; here; there) hiding (module Suffix)open import Relation.Nullary using (Dec; ¬_; yes; no)open import Relation.Nullary.Decidable using (map′)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.PropositionalEquality.Coreopen DecPoset P? using (preorder) renaming (Carrier to A)open import Text.Regex.Base preorderopen import Text.Regex.Properties P?open import Text.Regex.Derivative.Brzozowski P?-------------------------------------------------------------------------- Type corresponding to a match-- Users have control over whether the match should start at the-- beginning or stop at the end. So we have a precise type of spans-- ensuring their demands are respectedSpan : ∀ {r} → Regex → Rel A r → Rel (List A) (a ⊔ r)Span regex =if Regex.fromStart regexthen if Regex.tillEnd regexthen Pointwiseelse Prefixelse if Regex.tillEnd regexthen Suffixelse Infix-- All matches are selecting an infix sublisttoInfix : ∀ {r} {R : Rel A r} e → Span e R ⇒ Infix RtoInfix e with Regex.fromStart e | Regex.tillEnd e... | true | true = Infixₚ.fromPointwise... | true | false = here... | false | true = Infixₚ.fromSuffix... | false | false = id-- A match is a list, a proof it matches the regular expression,-- and a proof it is the right sort of sublist.record Match {s} (R : Rel (List A) s) (xs : List A) (exp : Exp): Set (a ⊔ e ⊔ r ⊔ s) whereconstructor mkMatchfieldlist : List Amatch : list ∈ exprelated : R list xsopen Match publicmap : ∀ {r s} {R : Rel (List A) r} {S : Rel (List A) s} {xs ys e} →(∀ {a} → R a xs → S a ys) → Match R xs e → Match S ys emap f (mkMatch ys ys∈e pys) = mkMatch ys ys∈e (f pys)-------------------------------------------------------------------------- Search algorithmsmodule Prefix where[]ᴹ : ∀ {xs e} → [] ∈ e → Match (Prefix _≡_) xs e[]ᴹ p = mkMatch [] p [][]⁻¹ᴹ : ∀ {e} → Match (Prefix _≡_) [] e → [] ∈ e[]⁻¹ᴹ (mkMatch .[] p []) = pinfixr 5 _∷ᴹ_ _∷⁻¹ᴹ__∷ᴹ_ : ∀ {xs e} x → Match (Prefix _≡_) xs (eat x e) → Match (Prefix _≡_) (x ∷ xs) ex ∷ᴹ (mkMatch ys ys∈e\x ys≤xs) = mkMatch (x ∷ ys) (eat-sound x _ ys∈e\x) (refl ∷ ys≤xs)_∷⁻¹ᴹ_ : ∀ {xs x e} → [] ∉ e →Match (Prefix _≡_) (x ∷ xs) e → Match (Prefix _≡_) xs (eat x e)[]∉e ∷⁻¹ᴹ (mkMatch .[] []∈e []) = contradiction []∈e []∉e[]∉e ∷⁻¹ᴹ (mkMatch (._ ∷ ys) ys∈e (refl ∷ ys≤xs)) = mkMatch ys (eat-complete _ _ ys∈e) ys≤xsshortest : Decidable (Match (Prefix _≡_))shortest xs ∅ = no (∉∅ ∘ match)shortest xs e with []∈? e... | yes []∈e = yes ([]ᴹ []∈e)shortest [] e | no []∉e = no ([]∉e ∘′ []⁻¹ᴹ)shortest (x ∷ xs) e | no []∉e with shortest xs (eat x e)... | yes p = yes (x ∷ᴹ p)... | no ¬p = no (¬p ∘ ([]∉e ∷⁻¹ᴹ_))longest : Decidable (Match (Prefix _≡_))longest [] e = map′ []ᴹ []⁻¹ᴹ ([]∈? e)longest xs ∅ = no (∉∅ ∘ match)longest (x ∷ xs) e with longest xs (eat x e)... | yes p = yes (x ∷ᴹ p)... | no ¬p with []∈? e... | yes []∈e = yes ([]ᴹ []∈e)... | no []∉e = no (¬p ∘ ([]∉e ∷⁻¹ᴹ_))module Infix where[]⁻¹ᴹ : ∀ {e acc} → Match (Infix _≡_) [] e ⊎ Match (Prefix _≡_) [] acc → [] ∈ e ⊎ [] ∈ acc[]⁻¹ᴹ (inj₁ (mkMatch .[] []∈e (here []))) = inj₁ []∈e[]⁻¹ᴹ (inj₂ (mkMatch .[] []∈acc [])) = inj₂ []∈accstep : ∀ {e acc} x {xs} → Match (Infix _≡_) xs e ⊎ Match (Prefix _≡_) xs (eat x (acc ∣ e)) →Match (Infix _≡_) (x ∷ xs) e ⊎ Match (Prefix _≡_) (x ∷ xs) accstep x (inj₁ (mkMatch ys ys∈e p)) = inj₁ (mkMatch ys ys∈e (there p))step {e} {acc} x (inj₂ (mkMatch ys ys∈e p)) with eat-sound x (acc ∣ e) ys∈e... | sum (inj₂ xys∈e) = inj₁ (mkMatch (x ∷ ys) xys∈e (here (refl ∷ p)))... | sum (inj₁ xys∈e) = inj₂ (mkMatch (x ∷ ys) xys∈e (refl ∷ p))step⁻¹ : ∀ {e acc} x {xs} →[] ∉ e → [] ∉ acc →Match (Infix _≡_) (x ∷ xs) e ⊎ Match (Prefix _≡_) (x ∷ xs) acc →Match (Infix _≡_) xs e ⊎ Match (Prefix _≡_) xs (eat x (acc ∣ e))-- can't possibly be the empty matchstep⁻¹ x []∉e []∉acc (inj₁ (mkMatch .[] ys∈e (here []))) = contradiction ys∈e []∉estep⁻¹ x []∉e []∉acc (inj₂ (mkMatch .[] ys∈e [])) = contradiction ys∈e []∉acc-- if it starts 'there', it's an infix solutionstep⁻¹ x []∉e []∉acc (inj₁ (mkMatch ys ys∈e (there p))) = inj₁ (mkMatch ys ys∈e p)-- if it starts 'here' we're in prefix territorystep⁻¹ {e} {acc} x []∉e []∉acc (inj₁ (mkMatch (.x ∷ ys) ys∈e (here (refl ∷ p))))= inj₂ (mkMatch ys (eat-complete x (acc ∣ e) (sum (inj₂ ys∈e))) p)step⁻¹ {e} {acc} x []∉e []∉acc (inj₂ (mkMatch (.x ∷ ys) ys∈e (refl ∷ p)))= inj₂ (mkMatch ys (eat-complete x (acc ∣ e) (sum (inj₁ ys∈e))) p)-- search non-deterministically: at each step, the `acc` regex is-- changed to accomodate the fact the match may be starting just nowsearchND : ∀ xs e acc → [] ∉ e → Dec (Match (Infix _≡_) xs e ⊎ Match (Prefix _≡_) xs acc)searchND xs e acc []∉e with []∈? acc... | yes []∈acc with Prefix.longest xs acc -- get the best match possible... | yes longer = yes (inj₂ longer)... | no noMatch = contradiction (mkMatch [] []∈acc []) noMatchsearchND [] e acc []∉e | no []∉acc = no ([ []∉e , []∉acc ]′ ∘′ []⁻¹ᴹ)searchND (x ∷ xs) e acc []∉e | no []∉acc= map′ (step x) (step⁻¹ x []∉e []∉acc) (searchND xs e (eat x (acc ∣ e)) []∉e)search : Decidable (Match (Infix _≡_))search xs e with []∈? e... | yes []∈e = yes (mkMatch [] []∈e (here []))... | no []∉e with searchND xs e ∅ []∉e... | no ¬p = no (¬p ∘′ inj₁)... | yes (inj₁ p) = yes p... | yes (inj₂ p) = contradiction (match p) ∉∅module Whole wherewhole : ∀ xs e → xs ∈ e → Match (Pointwise _≡_) xs ewhole xs e p = mkMatch xs p (Pointwise.refl refl)whole⁻¹ : ∀ xs e → Match (Pointwise _≡_) xs e → xs ∈ ewhole⁻¹ xs e (mkMatch ys ys∈e p) with Pointwise.Pointwise-≡⇒≡ pwhole⁻¹ xs e (mkMatch .xs xs∈e p) | refl = xs∈esearch : Decidable (Match (Pointwise _≡_))search xs e = map′ (whole xs e) (whole⁻¹ xs e) (xs ∈? e)module Suffix where[]⁻¹ᴹ : ∀ {e acc} → Match (Suffix _≡_) [] e ⊎ Match (Pointwise _≡_) [] acc → [] ∈ e ⊎ [] ∈ acc[]⁻¹ᴹ (inj₁ (mkMatch .[] ys∈e (here []))) = inj₁ ys∈e[]⁻¹ᴹ (inj₂ (mkMatch .[] ys∈acc [])) = inj₂ ys∈accstep : ∀ {e acc} x {xs} →Match (Suffix _≡_) xs e ⊎ Match (Pointwise _≡_) xs (eat x (e ∣ acc)) →Match (Suffix _≡_) (x ∷ xs) e ⊎ Match (Pointwise _≡_) (x ∷ xs) accstep x (inj₁ (mkMatch ys ys∈e p)) = inj₁ (mkMatch ys ys∈e (there p))step {e} {acc} x (inj₂ (mkMatch ys ys∈e p)) with eat-sound x (e ∣ acc) ys∈e... | sum (inj₁ xys∈e) = inj₁ (mkMatch (x ∷ ys) xys∈e (here (refl ∷ p)))... | sum (inj₂ xys∈acc) = inj₂ (mkMatch (x ∷ ys) xys∈acc (refl ∷ p))step⁻¹ : ∀ {e acc} x {xs} →Match (Suffix _≡_) (x ∷ xs) e ⊎ Match (Pointwise _≡_) (x ∷ xs) acc →Match (Suffix _≡_) xs e ⊎ Match (Pointwise _≡_) xs (eat x (e ∣ acc))-- match starts laterstep⁻¹ x (inj₁ (mkMatch ys ys∈e (there p))) = inj₁ (mkMatch ys ys∈e p)-- match starts here!step⁻¹ {e} {acc} x (inj₁ (mkMatch (.x ∷ ys) ys∈e (here (refl ∷ p))))= inj₂ (mkMatch ys (eat-complete x (e ∣ acc) (sum (inj₁ ys∈e))) p)step⁻¹ {e} {acc} x (inj₂ (mkMatch (.x ∷ ys) ys∈e (refl ∷ p)))= inj₂ (mkMatch ys (eat-complete x (e ∣ acc) (sum (inj₂ ys∈e))) p)searchND : ∀ xs e acc → Dec (Match (Suffix _≡_) xs e ⊎ Match (Pointwise _≡_) xs acc)searchND [] e acc with []∈? e | []∈? acc... | yes []∈e | _ = yes (inj₁ (mkMatch [] []∈e (here [])))... | _ | yes []∈acc = yes (inj₂ (mkMatch [] []∈acc []))... | no []∉e | no []∉acc = no ([ []∉e , []∉acc ]′ ∘′ []⁻¹ᴹ)searchND (x ∷ xs) e acc= map′ (step x) (step⁻¹ x) (searchND xs e (eat x (e ∣ acc)))search : Decidable (Match (Suffix _≡_))search xs e with searchND xs e ∅... | no ¬p = no (¬p ∘′ inj₁)... | yes (inj₁ p) = yes p... | yes (inj₂ p) = contradiction (match p) ∉∅-------------------------------------------------------------------------- Search for the user-specified spansearch : ∀ xs e → Dec (Match (Span e _≡_) xs (Regex.expression e))search xs e with Regex.fromStart e | Regex.tillEnd e... | true | true = Whole.search xs (Regex.expression e)... | true | false = Prefix.shortest xs (Regex.expression e)... | false | true = Suffix.search xs (Regex.expression e)... | false | false = Infix.search xs (Regex.expression e)
-------------------------------------------------------------------------- The Agda standard library---- Properties of regular expressions and their semantics------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecPoset)module Text.Regex.Properties {a e r} (P? : DecPoset a e r) whereopen import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Unary.All using (all?)open import Data.List.Relation.Unary.Any using (any?)open import Data.Product.Base using (_×_; _,_; uncurry)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (_$_)open import Relation.Nullary.Decidableusing (Dec; yes; no; map′; ¬?; _×-dec_; _⊎-dec_)open import Relation.Nullary.Negationusing (¬_; contradiction)import Relation.Unary as Uopen import Relation.Binary.Definitions using (Decidable)open DecPoset P? renaming (Carrier to A)open import Text.Regex.Base preorderopen import Data.List.Relation.Binary.Pointwise.Base using ([])open import Data.List.Relation.Ternary.Appending.Propositional {A = A}open import Data.List.Relation.Ternary.Appending.Propositional.Properties {A = A}-------------------------------------------------------------------------- Publicly re-export core propertiesopen import Text.Regex.Properties.Core preorder public-------------------------------------------------------------------------- Decidability results[]∈?_ : U.Decidable ([] ∈_)[]∈? ε = yes ε[]∈? [ rs ] = no (λ ())[]∈? [^ rs ] = no (λ ())[]∈? (e ∣ f) = map′ sum (λ where (sum pr) → pr)$ ([]∈? e) ⊎-dec ([]∈? f)[]∈? (e ∙ f) = map′ (uncurry (prod ([]++ []))) []∈e∙f-inv$ ([]∈? e) ×-dec ([]∈? f)[]∈? (e ⋆) = yes (star (sum (inj₁ ε)))infix 4 _∈ᴿ?_ _∉ᴿ?_ _∈?ε _∈?[_] _∈?[^_]_∈ᴿ?_ : Decidable _∈ᴿ_c ∈ᴿ? [ a ] = map′ [_] (λ where [ eq ] → eq) (c ≟ a)c ∈ᴿ? (lb ─ ub) = map′ (uncurry _─_) (λ where (ge ─ le) → ge , le)$ (lb ≤? c) ×-dec (c ≤? ub)_∉ᴿ?_ : Decidable _∉ᴿ_a ∉ᴿ? r = ¬? (a ∈ᴿ? r)_∈?ε : U.Decidable (_∈ ε)[] ∈?ε = yes ε(a ∷ _) ∈?ε = no (λ ())_∈?[_] : ∀ w rs → Dec (w ∈ [ rs ])[] ∈?[ rs ] = no (λ ())(a ∷ b ∷ _) ∈?[ rs ] = no (λ ())(a ∷ []) ∈?[ rs ] = map′ [_] (λ where [ p ] → p)$ any? (a ∈ᴿ?_) rs_∈?[^_] : ∀ w rs → Dec (w ∈ [^ rs ])[] ∈?[^ rs ] = no (λ ())(a ∷ []) ∈?[^ rs ] = map′ [^_] (λ where [^ p ] → p) $ all? (a ∉ᴿ?_) rs(a ∷ b ∷ _) ∈?[^ rs ] = no (λ ())
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions: core properties (only require a Preorder)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder)module Text.Regex.Properties.Core {a e r} (P : Preorder a e r) whereopen import Level using (_⊔_)open import Data.Bool.Base using (Bool)open import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.Product.Base using (_×_; _,_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Relation.Nullary using (¬_; Dec; yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Unary using (Pred)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open Preorder P using (_≈_) renaming (Carrier to A; _∼_ to _≤_)open import Text.Regex.Base Popen import Data.List.Relation.Ternary.Appending.Propositional.Properties {A = A}using (++[]⁻¹; []++⁻¹; conicalˡ; conicalʳ)-------------------------------------------------------------------------- Viewsis-∅ : ∀ (e : Exp) → Dec (e ≡ ∅)is-∅ ε = no (λ ())is-∅ [ [] ] = yes reflis-∅ [ r ∷ rs ] = no (λ ())is-∅ [^ rs ] = no (λ ())is-∅ (e ∣ f) = no (λ ())is-∅ (e ∙ f) = no (λ ())is-∅ (e ⋆) = no (λ ())is-ε : ∀ (e : Exp) → Dec (e ≡ ε)is-ε ε = yes reflis-ε [ rs ] = no (λ ())is-ε [^ rs ] = no (λ ())is-ε (e ∣ f) = no (λ ())is-ε (e ∙ f) = no (λ ())is-ε (e ⋆) = no (λ ())-------------------------------------------------------------------------- Inversion lemmas∉∅ : ∀ {xs} → xs ∉ ∅∉∅ [ () ]∈ε⋆-inv : ∀ {w} → w ∈ (ε ⋆) → w ∈ ε∈ε⋆-inv (star (sum (inj₁ ε))) = ε∈ε⋆-inv (star (sum (inj₂ (prod eq ε p)))) rewrite []++⁻¹ eq = ∈ε⋆-inv p∈∅⋆-inv : ∀ {w} → w ∈ (∅ ⋆) → w ∈ ε∈∅⋆-inv (star (sum (inj₁ ε))) = ε∈∅⋆-inv (star (sum (inj₂ (prod eq p q)))) = contradiction p ∉∅∈ε∙e-inv : ∀ {w e} → w ∈ (ε ∙ e) → w ∈ e∈ε∙e-inv (prod eq ε p) rewrite []++⁻¹ eq = p∈e∙ε-inv : ∀ {w e} → w ∈ (e ∙ ε) → w ∈ e∈e∙ε-inv (prod eq p ε) rewrite ++[]⁻¹ eq = p[]∈e∙f-inv : ∀ {e f} → [] ∈ (e ∙ f) → [] ∈ e × [] ∈ f[]∈e∙f-inv (prod eq p q) rewrite conicalˡ eq | conicalʳ eq = p , q
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions: Brzozowski derivative------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecPoset)module Text.Regex.Derivative.Brzozowski {a e r} (P? : DecPoset a e r) whereopen import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Binary.Equality.Propositionalopen import Data.Sum.Base as Sum using (inj₁; inj₂)open import Function.Base using (_$_; _∘′_; case_of_)open import Relation.Nullary.Decidable using (Dec; yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Nullary.Decidable using (map′; ¬?)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open DecPoset P? using (preorder) renaming (Carrier to A)open import Text.Regex.Base preorder as R hiding (_∣_; _∙_; _⋆)open import Text.Regex.Properties P?open import Text.Regex.SmartConstructors preorderopen import Data.List.Relation.Ternary.Appending.Propositional {A = A}open import Data.List.Relation.Ternary.Appending.Propositional.Properties {A = A}-------------------------------------------------------------------------- Action of characters on regular expressionsprivatedecToExp : ∀ {p} {P : Set p} → Dec P → ExpdecToExp (yes _) = εdecToExp (no _) = ∅eat : A → Exp → Expeat a ε = ∅eat a [ rs ] = decToExp ((a ∷ []) ∈?[ rs ])eat a [^ rs ] = decToExp ((a ∷ []) ∈?[^ rs ])eat a (e R.∣ f) = eat a e ∣ eat a feat a (e R.∙ f) = case []∈? e of λ where(yes _) → (eat a e ∙ f) ∣ (eat a f)(no ¬p) → eat a e ∙ feat a (e R.⋆) = eat a e ∙ (e ⋆)-------------------------------------------------------------------------- This action is sound and complete with respect to matchingeat-sound : ∀ x {xs} e → xs ∈ eat x e → (x ∷ xs) ∈ eeat-sound x ε pr = contradiction pr ∉∅eat-sound x [ rs ] pr with (x ∷ []) ∈?[ rs ]... | yes p = case pr of λ where ε → p... | no _ = contradiction pr ∉∅eat-sound x [^ rs ] pr with (x ∷ []) ∈?[^ rs ]... | yes p = case pr of λ where ε → p... | no _ = contradiction pr ∉∅eat-sound x (e R.∣ f) pr with ∣-sound (eat x e) (eat x f) pr... | sum pr′ = sum $ Sum.map (eat-sound x e) (eat-sound x f) pr′eat-sound x (e R.∙ f) pr with []∈? e... | yes []∈e with ∣-sound (eat x e ∙ f) (eat x f) pr... | sum (inj₂ pr') = prod ([] ++ _) []∈e (eat-sound x f pr')... | sum (inj₁ pr') with ∙-sound (eat x e) f pr'... | prod eq p q = prod (refl ∷ eq) (eat-sound x e p) qeat-sound x (e R.∙ f) pr | no ¬p with ∙-sound (eat x e) f pr... | prod eq p q = prod (refl ∷ eq) (eat-sound x e p) qeat-sound x (e R.⋆) pr with ∙-sound (eat x e) (e ⋆) pr... | prod eq p q =star (sum (inj₂ (prod (refl ∷ eq) (eat-sound x e p) (⋆-sound e q))))eat-complete′ : ∀ x {xs w} e → w ≋ (x ∷ xs) → w ∈ e → xs ∈ eat x eeat-complete : ∀ x {xs} e → (x ∷ xs) ∈ e → xs ∈ eat x eeat-complete x e = eat-complete′ x e ≋-refleat-complete′ x [ rs ] (refl ∷ []) [ p ]with (x ∷ []) ∈?[ rs ]... | yes _ = ε... | no ¬p = contradiction [ p ] ¬peat-complete′ x [^ rs ] (refl ∷ []) [^ p ]with (x ∷ []) ∈?[^ rs ]... | yes _ = ε... | no ¬p = contradiction [^ p ] ¬peat-complete′ x (e R.∣ f) eq (sum p) =∣-complete (eat x e) (eat x f) $ sum $Sum.map (eat-complete′ x e eq) (eat-complete′ x f eq) peat-complete′ x (e R.∙ f) eq p with []∈? eeat-complete′ x (e R.∙ f) (refl ∷ eq) (prod ([]++ _) p q) | no []∉e= contradiction p []∉eeat-complete′ x (e R.∙ f) (refl ∷ eq) (prod (refl ∷ app) p q) | no []∉e= ∙-complete (eat x e) f (prod (respʳ-≋ app eq) (eat-complete x e p) q)eat-complete′ x (e R.∙ f) eq (prod ([]++ eq′) p q) | yes []∈e= ∣-complete (eat x e ∙ f) (eat x f) $ sum $ inj₂$ eat-complete′ x f (≋-trans eq′ eq) qeat-complete′ x (e R.∙ f) (refl ∷ eq) (prod (refl ∷ app) p q) | yes []∈e= ∣-complete (eat x e ∙ f) (eat x f) $ sum $ inj₁$ ∙-complete (eat x e) f (prod (respʳ-≋ app eq) (eat-complete x e p) q)eat-complete′ x (e R.⋆) eq (star (sum (inj₂ (prod ([]++ app) p q))))= eat-complete′ x (e R.⋆) (≋-trans app eq) qeat-complete′ x (e R.⋆) (refl ∷ eq) (star (sum (inj₂ (prod (refl ∷ app) p q))))= ∙-complete (eat x e) (e ⋆) $ prod (respʳ-≋ app eq) (eat-complete x e p)$ ⋆-complete e q-------------------------------------------------------------------------- Consequence: matching is decidableinfix 4 _∈?_ _∉?__∈?_ : Decidable _∈_[] ∈? e = []∈? e(x ∷ xs) ∈? e = map′ (eat-sound x e) (eat-complete x e) (xs ∈? eat x e)_∉?_ : Decidable _∉_xs ∉? e = ¬? (xs ∈? e)
-------------------------------------------------------------------------- The Agda standard library---- Regular expressions: basic types and semantics------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder)module Text.Regex.Base {a e r} (P : Preorder a e r) whereopen import Level using (_⊔_)open import Data.Bool.Base using (Bool)open import Data.List.Base as L using (List; []; _∷_)open import Data.List.Relation.Unary.Any using (Any)open import Data.List.Relation.Unary.All using (All)open import Data.Sum.Base using (_⊎_)open import Relation.Nullary.Negation.Core using (¬_)open Preorder P using (_≈_) renaming (Carrier to A; _∼_ to _≤_)open import Data.List.Relation.Ternary.Appending.Propositional {A = A}-------------------------------------------------------------------------- Regular expressions on the alphabet Ainfix 10 [_] _─_data Range : Set a where[_] : (a : A) → Range_─_ : (lb ub : A) → Rangeinfixr 5 _∣_infixr 6 _∙_infixl 7 _⋆infix 10 [^_]data Exp : Set a whereε : Exp[_] : (rs : List Range) → Exp[^_] : (rs : List Range) → Exp_∣_ : (e f : Exp) → Exp_∙_ : (e f : Exp) → Exp_⋆ : (e : Exp) → Exp-- A regular expression has additional parameters:-- * should the match begin at the very start of the input?-- * should it span until the very end?record Regex : Set a wherefieldfromStart : BooltillEnd : Boolexpression : ExpupdateExp : (Exp → Exp) → Regex → RegexupdateExp f r = record r { expression = f (Regex.expression r) }-------------------------------------------------------------------------- Derived notions: nothing, anything, and singletonpattern ∅ = [ List.[] ]pattern · = [^ List.[] ]pattern singleton a = [ Range.[ a ] ∷ [] ]-------------------------------------------------------------------------- Semantics: matching wordsinfix 4 _∈ᴿ_ _∉ᴿ_data _∈ᴿ_ (c : A) : Range → Set (a ⊔ r ⊔ e) where[_] : ∀ {val} → c ≈ val → c ∈ᴿ [ val ]_─_ : ∀ {lb ub} → lb ≤ c → c ≤ ub → c ∈ᴿ (lb ─ ub)_∉ᴿ_ : A → Range → Set (a ⊔ r ⊔ e)a ∉ᴿ r = ¬ (a ∈ᴿ r)infix 4 _∈_ _∉_data _∈_ : List A → Exp → Set (a ⊔ r ⊔ e) whereε : [] ∈ ε[_] : ∀ {a rs} → Any (a ∈ᴿ_) rs → L.[ a ] ∈ [ rs ][^_] : ∀ {a rs} → All (a ∉ᴿ_) rs → L.[ a ] ∈ [^ rs ]sum : ∀ {w e f} → (w ∈ e) ⊎ (w ∈ f) → w ∈ (e ∣ f)prod : ∀ {v w vw e f} → Appending v w vw → v ∈ e → w ∈ f → vw ∈ (e ∙ f)star : ∀ {v e} → v ∈ (ε ∣ e ∙ (e ⋆)) → v ∈ (e ⋆)_∉_ : List A → Exp → Set (a ⊔ r ⊔ e)w ∉ e = ¬ (w ∈ e)
-------------------------------------------------------------------------- The Agda standard library---- Printf------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Text.Printf whereopen import Data.String.Base using (String; fromChar; concat)open import Function.Base using (id)import Data.Integer.Show as ℤimport Data.Float.Base as Floatimport Data.Nat.Show as ℕopen import Text.Format as Format hiding (Error)open import Text.Printf.GenericprintfSpec : PrintfSpec formatSpec StringprintfSpec .PrintfSpec.renderArg ℕArg = ℕ.showprintfSpec .PrintfSpec.renderArg ℤArg = ℤ.showprintfSpec .PrintfSpec.renderArg FloatArg = Float.showprintfSpec .PrintfSpec.renderArg CharArg = fromCharprintfSpec .PrintfSpec.renderArg StringArg = idprintfSpec .PrintfSpec.renderStr = idmodule Printf = Type formatSpecopen Printf public hiding (map)open Render printfSpec public renaming (printf to gprintf)printf : (fmt : String) → Printf (lexer fmt) Stringprintf fmt = Printf.map (lexer fmt) concat (gprintf fmt)
-------------------------------------------------------------------------- The Agda standard library---- Generic printf function.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Text.Printf.Generic whereopen import Level using (Level; 0ℓ; _⊔_; Lift)open import Data.List.Base as List using (List; []; _∷_)open import Data.Char.Baseopen import Data.Maybe.Base hiding (map)open import Data.Nat.Base using (ℕ)open import Data.Product.Base hiding (map)open import Data.Product.Nary.NonDependentopen import Data.String.Base using (String)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Unit.Base using (⊤)open import Function.Nary.NonDependentopen import Function.Baseopen import Text.Format.Genericprivatevariableℓ : LevelA B : Set ℓ-------------------------------------------------------------------------- Printf argument specifications.-- Defines the rendering of chunks.record PrintfSpec {ℓ} (spec : FormatSpec) (A : Set ℓ) : Set (Level.suc 0ℓ ⊔ ℓ) whereopen FormatSpec spec publicfieldrenderArg : ∀ arg → ArgType arg → ArenderStr : String → Amodule Type (spec : FormatSpec) whereopen Format spec renaming (Error to FormatError)record Error (e : FormatError) : Set ℓ whereprivateSize : FormatError ⊎ Format → ℕSize (inj₁ err) = 0Size (inj₂ fmt) = size fmtPrintf : ∀ pr → Set ℓ → Set (ℓ ⊔ ⨆ (Size pr) 0ℓs)Printf (inj₁ err) _ = Error errPrintf (inj₂ fmt) B = Arrows _ ⟦ fmt ⟧ Bmap : ∀ pr → (A → B) → Printf pr A → Printf pr Bmap (inj₁ err) f p = _map (inj₂ fmt) f p = mapₙ _ f pmodule Render {spec : FormatSpec} (render : PrintfSpec spec A) whereopen PrintfSpec renderopen Type specopen Format spec renaming (Error to FormatError)assemble : ∀ fmt → Product⊤ _ ⟦ fmt ⟧ → List Aassemble [] vs = []assemble (Arg a ∷ fmt) (x , vs) = renderArg a x ∷ assemble fmt vsassemble (Raw str ∷ fmt) vs = renderStr str ∷ assemble fmt vsprivateprintf′ : ∀ pr → Printf pr (List A)printf′ (inj₁ err) = _printf′ (inj₂ fmt) = curry⊤ₙ _ (assemble fmt)printf : (input : String) → Printf (lexer input) (List A)printf input = printf′ (lexer input)
-------------------------------------------------------------------------- The Agda standard library---- Pretty Printing-- This module is based on Jean-Philippe Bernardy's functional pearl-- "A Pretty But Not Greedy Printer"------------------------------------------------------------------------{-# OPTIONS --with-K #-}open import Data.Nat.Base using (ℕ)module Text.Pretty (width : ℕ) whereimport Levelopen import Data.Char.Base using (Char)open import Data.List.Baseusing (List; _∷_; []; [_]; uncons; _++_; map; filter)open import Data.List.NonEmpty as List⁺ using (foldr₁)open import Data.Maybe.Base using (maybe′)open import Data.Product.Base using (uncurry)open import Data.String.Base using (String; fromList; replicate)open import Function.Base using (_∘_; _∘′_; _$_)open import Effect.Monad using (RawMonad)import Data.List.Effectful as Listopen RawMonad (List.monad {Level.zero})import Data.Nat.Properties as ℕopen import Data.List.Extrema.Core ℕ.≤-totalOrder using (⊓ᴸ)-------------------------------------------------------------------------- Internal representation of documents and rendering functionimport Text.Pretty.Core as Corerecord Doc : Set whereconstructor mkDocfield runDoc : List Core.Blockopen Doc publicrender : Doc → Stringrender = Core.render∘ maybe′ (foldr₁ (⊓ᴸ Core.Block.height) ∘′ uncurry List⁺._∷_) Core.empty∘ uncons∘′ runDoc-------------------------------------------------------------------------- Basic building blocksfail : Docfail = mkDoc []text : String → Doctext = mkDoc ∘′ filter (Core.valid width) ∘ pure ∘ Core.textempty : Docempty = text ""char : Char → Docchar c = text (fromList (c ∷ []))spaces : ℕ → Docspaces n = text (replicate n ' ')semi colon comma space dot : Docsemi = char ';'; colon = char ':'comma = char ','; space = char ' '; dot = char '.'backslash forwardslash equal : Docbackslash = char '\\'; forwardslash = char '/'; equal = char '='squote dquote : Docsquote = char '\''; dquote = char '"'lparen rparen langle rangle : Doclparen = char '('; rparen = char ')'langle = char '<'; rangle = char '>'lbrace rbrace llbrace rrbrace : Doclbrace = char '{'; rbrace = char '}'llbrace = char '⦃'; rrbrace = char '⦄'lbracket rbracket llbracket rrbracket : Doclbracket = char '['; rbracket = char ']'llbracket = char '⟦'; rrbracket = char '⟧'-------------------------------------------------------------------------- Combining two documentsinfixr 5 _<>__<>_ : Doc → Doc → Docxs <> ys = mkDoc $let candidates = Core._<>_ <$> runDoc xs ⊛ runDoc ys infilter (Core.valid width) candidatesflush : Doc → Docflush = mkDoc ∘′ map Core.flush ∘′ runDocinfixr 5 _<+>__<+>_ : Doc → Doc → Docx <+> y = x <> space <> yinfixr 5 _$$__$$_ : Doc → Doc → Docx $$ y = flush x <> yinfixr 4 _<|>__<|>_ : Doc → Doc → Docx <|> y = mkDoc (runDoc x ++ runDoc y)-------------------------------------------------------------------------- Combining lists of documentsfoldDoc : (Doc → Doc → Doc) → List Doc → DocfoldDoc _ [] = emptyfoldDoc _ (x ∷ []) = xfoldDoc f (x ∷ xs) = f x (foldDoc f xs)hsep vcat : List Doc → Dochsep = foldDoc _<+>_vcat = foldDoc _$$_sep : List Doc → Docsep [] = emptysep xs = hsep xs <|> vcat xs-------------------------------------------------------------------------- Defined combinatorsparens : Doc → Docparens d = lparen <> d <> rparencommaSep : List Doc → DoccommaSep = foldDoc (λ d e → d <> comma <+> e)newline : Docnewline = flush empty
-------------------------------------------------------------------------- The Agda standard library---- Pretty Printing-- This module is based on Jean-Philippe Bernardy's functional pearl-- "A Pretty But Not Greedy Printer"------------------------------------------------------------------------{-# OPTIONS --with-K #-}module Text.Pretty.Core whereimport Levelopen import Data.Bool.Base using (Bool)open import Data.Irrelevant as Irrelevant using (Irrelevant) hiding (module Irrelevant)open import Data.List.Base as List using (List; []; _∷_)open import Data.Nat.Base using (ℕ; zero; suc; _+_; _⊔_; _≤_; z≤n)open import Data.Nat.Properties using (≤-refl; ≤-trans; +-identityʳ;module ≤-Reasoning; m≤n⊔m; +-monoʳ-≤; m≤m⊔n; +-comm; _≤?_)open import Data.Product.Base as Prod using (_×_; _,_; uncurry; proj₁; proj₂)import Data.Product.Relation.Unary.All as Allᴾopen import Data.Tree.Binary as Tree using (Tree; leaf; node; #nodes; mapₙ)open import Data.Tree.Binary.Relation.Unary.All as Allᵀ using (leaf; node)open import Data.Unit.Base using (⊤; tt)import Data.Tree.Binary.Relation.Unary.All.Properties as Allᵀimport Data.Tree.Binary.Properties as Treeopen import Data.Maybe.Base as Maybe using (Maybe; nothing; just; maybe′)open import Data.Maybe.Relation.Unary.All as Allᴹ using (nothing; just)open import Data.String.Base as Stringusing (String; length; replicate; _++_; unlines)import Data.String.Unsafe as Stringopen import Function.Base using (_∘_; flip; _on_; id; _∘′_; _$_)open import Relation.Nullary.Decidable.Core using (Dec)open import Relation.Unary using (IUniversal; _⇒_; U)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; cong; cong₂; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Data.Refinement using (Refinement-syntax; _,_; value; proof)import Data.Refinement.Relation.Unary.All as Allᴿ-------------------------------------------------------------------------- Block of text-- Content is a representation of the first line and the middle of the-- block. We use a tree rather than a list for the middle of the block-- so that we can extend it with lines on the left and on the line for-- free. We will ultimately render the block by traversing the tree left-- to right in a depth-first manner.Content : SetContent = Maybe (String × Tree String ⊤)size : Content → ℕsize = maybe′ (suc ∘ #nodes ∘ proj₂) 0All : ∀ {p} (P : String → Set p) → (Content → Set p)All P = Allᴹ.All (Allᴾ.All P (Allᵀ.All P U))All≤ : ℕ → Content → SetAll≤ n = All (λ s → length s ≤ n)record Block : Set wherefieldheight : ℕblock : [ xs ∈ Content ∣ size xs ≡ height ]-- last linelastWidth : ℕlast : [ s ∈ String ∣ length s ≡ lastWidth ]-- max of all the widthsmaxWidth : [ n ∈ ℕ ∣ lastWidth ≤ n × All≤ n (block .value) ]-------------------------------------------------------------------------- Raw stringtext : String → Blocktext s = record{ height = 0; block = nothing , ⦇ refl ⦈; lastWidth = width; last = s , ⦇ refl ⦈; maxWidth = width , ⦇ (≤-refl , nothing) ⦈} where width = length s; open Irrelevant-------------------------------------------------------------------------- Emptyempty : Blockempty = text ""-------------------------------------------------------------------------- Helper functionsnode? : Content → String → Tree String ⊤ → Contentnode? (just (x , xs)) y ys = just (x , node xs y ys)node? nothing y ys = just (y , ys)∣node?∣ : ∀ b y ys → size (node? b y ys)≡ size b + suc (#nodes ys)∣node?∣ (just (x , xs)) y ys = refl∣node?∣ nothing y ys = refl≤-Content : ∀ {m n} {b : Content} → m ≤ n → All≤ m b → All≤ n b≤-Content {m} {n} m≤n = Allᴹ.map (Prod.map step (Allᵀ.mapₙ step))wherestep : ∀ {p} → p ≤ m → p ≤ nstep = flip ≤-trans m≤nAll≤-node? : ∀ {l m r n} →All≤ n l → length m ≤ n → Allᵀ.All (λ s → length s ≤ n) U r →All≤ n (node? l m r)All≤-node? nothing py pys = just (py , pys)All≤-node? (just (px , pxs)) py pys = just (px , node pxs py pys)-------------------------------------------------------------------------- Appending two documentsprivatemodule append (x y : Block) wheremodule x = Block xmodule y = Block yblockx = x.block .valueblocky = y.block .valuewidthx = x.maxWidth .valuewidthy = y.maxWidth .valuelastx = x.last .valuelasty = y.last .valueheight : ℕheight = (_+_ on Block.height) x ylastWidth : ℕlastWidth = (_+_ on Block.lastWidth) x ypad : Maybe Stringpad with x.lastWidth... | 0 = nothing... | l@(suc _) = just (replicate l ' ')size-pad : maybe′ length 0 pad ≡ x.lastWidthsize-pad with x.lastWidth... | 0 = refl... | l@(suc _) = String.length-replicate lindent : Maybe String → String → Stringindent = maybe′ _++_ idsize-indent : ∀ ma str → length (indent ma str)≡ maybe′ length 0 ma + length strsize-indent nothing str = reflsize-indent (just pad) str = String.length-++ pad strindents : Maybe String → Tree String ⊤ → Tree String ⊤indents = maybe′ (mapₙ ∘ _++_) idsize-indents : ∀ ma t → #nodes (indents ma t) ≡ #nodes tsize-indents nothing t = reflsize-indents (just pad) t = Tree.#nodes-mapₙ (pad ++_) tunfold-indents : ∀ ma t → indents ma t ≡ mapₙ (indent ma) tunfold-indents nothing t = sym (Tree.map-id t)unfold-indents (just pad) t = reflvContent : Content × StringvContent with blocky... | nothing = blockx, lastx ++ lasty... | just (hd , tl) = node?{-,--------------,-}{-|-} blockx {-|-}{-|-} {-'---,-} {-,------------------,-}{-|-} (lastx {-|-} ++ {-|-} hd) {-|-}{-'------------------'-} {-|-} {-|-}(indents pad {-|-} tl) {-,----'-}, indent pad {-|-} lasty {-|-}{-'-------------'-}vBlock = proj₁ vContentvLast = proj₂ vContentisBlock : size blockx ≡ x.height → size blocky ≡ y.height →size vBlock ≡ heightisBlock ∣x∣ ∣y∣ with blocky... | nothing = beginsize blockx ≡⟨ ∣x∣ ⟩x.height ≡⟨ +-identityʳ x.height ⟨x.height + 0 ≡⟨ cong (_ +_) ∣y∣ ⟩x.height + y.height ∎ where open ≡-Reasoning... | just (hd , tl) = begin∣node∣ ≡⟨ ∣node?∣ blockx middle rest ⟩∣blockx∣ + suc (#nodes rest) ≡⟨ cong ((size blockx +_) ∘′ suc) ∣rest∣ ⟩∣blockx∣ + suc (#nodes tl) ≡⟨ cong₂ _+_ ∣x∣ ∣y∣ ⟩x.height + y.height ∎ whereopen ≡-Reasoning∣blockx∣ = size blockxmiddle = lastx ++ hdrest = indents pad tl∣rest∣ = size-indents pad tl∣node∣ = size (node? blockx middle rest)block : [ xs ∈ Content ∣ size xs ≡ height ]block .value = vBlockblock .proof = ⦇ isBlock (Block.block x .proof) (Block.block y .proof) ⦈where open IrrelevantisLastLine : length lastx ≡ x.lastWidth →length lasty ≡ y.lastWidth →length vLast ≡ lastWidthisLastLine ∣x∣ ∣y∣ with blocky... | nothing = beginlength (lastx ++ lasty) ≡⟨ String.length-++ lastx lasty ⟩length lastx + length lasty ≡⟨ cong₂ _+_ ∣x∣ ∣y∣ ⟩x.lastWidth + y.lastWidth ∎ where open ≡-Reasoning... | just (hd , tl) = beginlength (indent pad lasty) ≡⟨ size-indent pad lasty ⟩maybe′ length 0 pad + length lasty ≡⟨ cong₂ _+_ size-pad ∣y∣ ⟩x.lastWidth + y.lastWidth ∎ where open ≡-Reasoninglast : [ s ∈ String ∣ length s ≡ lastWidth ]last .value = vLastlast .proof = ⦇ isLastLine (Block.last x .proof) (Block.last y .proof) ⦈where open IrrelevantvMaxWidth : ℕvMaxWidth = widthx ⊔ (x.lastWidth + widthy)isMaxWidth₁ : y.lastWidth ≤ widthy → lastWidth ≤ vMaxWidthisMaxWidth₁ p = beginlastWidth ≤⟨ +-monoʳ-≤ x.lastWidth p ⟩x.lastWidth + widthy ≤⟨ m≤n⊔m _ _ ⟩vMaxWidth ∎ where open ≤-ReasoningisMaxWidth₂ : length lastx ≡ x.lastWidth →x.lastWidth ≤ widthx →All≤ widthx blockx →All≤ widthy blocky →All≤ vMaxWidth vBlockisMaxWidth₂ ∣x∣≡ ∣x∣≤ ∣xs∣ ∣ys∣ with blocky... | nothing = ≤-Content (m≤m⊔n _ _) ∣xs∣isMaxWidth₂ ∣x∣≡ ∣x∣≤ ∣xs∣ (just (∣hd∣ , ∣tl∣))| just (hd , tl) =All≤-node? (≤-Content (m≤m⊔n _ _) ∣xs∣)middle(subst (Allᵀ.All _ U) (sym $ unfold-indents pad tl)$ Allᵀ.mapₙ⁺ (indent pad) (Allᵀ.mapₙ (indented _) ∣tl∣))wheremiddle : length (lastx ++ hd) ≤ vMaxWidthmiddle = beginlength (lastx ++ hd) ≡⟨ String.length-++ lastx hd ⟩length lastx + length hd ≡⟨ cong (_+ _) ∣x∣≡ ⟩x.lastWidth + length hd ≤⟨ +-monoʳ-≤ x.lastWidth ∣hd∣ ⟩x.lastWidth + widthy ≤⟨ m≤n⊔m _ _ ⟩vMaxWidth ∎ where open ≤-Reasoningindented : ∀ s → length s ≤ widthy →length (indent pad s) ≤ vMaxWidthindented s ∣s∣ = beginlength (indent pad s) ≡⟨ size-indent pad s ⟩maybe′ length 0 pad + length s ≡⟨ cong (_+ _) size-pad ⟩x.lastWidth + length s ≤⟨ +-monoʳ-≤ x.lastWidth ∣s∣ ⟩x.lastWidth + widthy ≤⟨ m≤n⊔m (widthx) _ ⟩vMaxWidth ∎ where open ≤-ReasoningmaxWidth : [ n ∈ ℕ ∣ lastWidth ≤ n × All≤ n vBlock ]maxWidth .value = vMaxWidthmaxWidth .proof =⦇ _,_ ⦇ isMaxWidth₁ (map proj₁ (Block.maxWidth y .proof)) ⦈⦇ isMaxWidth₂ (Block.last x .proof)(map proj₁ (Block.maxWidth x .proof))(map proj₂ (Block.maxWidth x .proof))(map proj₂ (Block.maxWidth y .proof))⦈⦈ where open Irrelevantinfixl 4 _<>__<>_ : Block → Block → Blockx <> y = record { append x y }-------------------------------------------------------------------------- Flush (introduces a new line)privatemodule flush (x : Block) wheremodule x = Block xblockx = x.block .valuelastx = x.last .valuewidthx = x.maxWidth .valueheightx = x.heightheight = suc heightxlastWidth = 0vMaxWidth = widthxlast : [ s ∈ String ∣ length s ≡ lastWidth ]last = "" , ⦇ refl ⦈ where open IrrelevantvContent = node? blockx lastx (leaf tt)isBlock : size blockx ≡ heightx → size vContent ≡ heightisBlock ∣x∣ = beginsize vContent ≡⟨ ∣node?∣ blockx lastx (leaf tt) ⟩size blockx + 1 ≡⟨ cong (_+ 1) ∣x∣ ⟩heightx + 1 ≡⟨ +-comm heightx 1 ⟩height ∎ where open ≡-Reasoningblock : [ xs ∈ Content ∣ size xs ≡ height ]block .value = vContentblock .proof = Irrelevant.map isBlock $ Block.block x .proofmaxWidth : [ n ∈ ℕ ∣ lastWidth ≤ n × All≤ n vContent ]maxWidth .value = widthxmaxWidth .proof = map (z≤n ,_)⦇ All≤-node? ⦇ proj₂ (Block.maxWidth x .proof) ⦈⦇ middle (Block.last x .proof) ⦇ proj₁ (Block.maxWidth x .proof) ⦈ ⦈(pure (leaf tt))⦈ whereopen Irrelevantmiddle : length lastx ≡ x.lastWidth → x.lastWidth ≤ vMaxWidth →length lastx ≤ vMaxWidthmiddle p q = beginlength lastx ≡⟨ p ⟩x.lastWidth ≤⟨ q ⟩vMaxWidth ∎ where open ≤-Reasoningflush : Block → Blockflush x = record { flush x }-------------------------------------------------------------------------- Other functionsrender : Block → Stringrender x = unlines$ maybe′ (uncurry (λ hd tl → hd ∷ Tree.Infix.toList tl)) []$ node? (Block.block x .value) (Block.last x .value) (leaf tt)valid : (width : ℕ) (b : Block) → Dec (Block.maxWidth b .value ≤ width)valid width b = Block.maxWidth b .value ≤? width
-------------------------------------------------------------------------- The Agda standard library---- Format strings for Printf and Scanf------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Text.Format whereopen import Data.Maybe.Baseopen import Text.Format.Generic-- Formatted typesopen import Data.Char.Base using (Char)open import Data.Integer.Base using (ℤ)open import Data.Float.Base using (Float)open import Data.Nat.Base using (ℕ)open import Data.String.Base using (String)-------------------------------------------------------------------------- Basic typesdata ArgChunk : Set whereℕArg ℤArg FloatArg CharArg StringArg : ArgChunk-------------------------------------------------------------------------- SemanticsArgType : (fmt : ArgChunk) → SetArgType ℕArg = ℕArgType ℤArg = ℤArgType FloatArg = FloatArgType CharArg = CharArgType StringArg = StringlexArg : Char → Maybe ArgChunklexArg 'd' = just ℤArglexArg 'i' = just ℤArglexArg 'u' = just ℕArglexArg 'f' = just FloatArglexArg 'c' = just CharArglexArg 's' = just StringArglexArg _ = nothingformatSpec : FormatSpecformatSpec .FormatSpec.ArgChunk = ArgChunkformatSpec .FormatSpec.ArgType = ArgTypeformatSpec .FormatSpec.lexArg = lexArgopen Format formatSpec publicpattern `ℕ = Arg ℕArgpattern `ℤ = Arg ℤArgpattern `Float = Arg FloatArgpattern `Char = Arg CharArgpattern `String = Arg StringArg
-------------------------------------------------------------------------- The Agda standard library---- Format strings for Printf and Scanf------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Text.Format.Generic whereopen import Level using (0ℓ)open import Effect.Applicativeopen import Data.Char.Base using (Char)open import Data.List.Base as Listopen import Data.Maybe.Base as Maybeopen import Data.Nat.Baseopen import Data.Product.Base using (_,_)open import Data.Product.Nary.NonDependentopen import Data.Sum.Baseopen import Data.String.Baseimport Data.Sum.Effectful.Left as Sumₗopen import Function.Baseopen import Function.Nary.NonDependent using (0ℓs; Sets)open import Function.Strict-------------------------------------------------------------------------- Format specifications.-- Defines the supported %-codes.record FormatSpec : Set₁ wherefieldArgChunk : SetArgType : ArgChunk → SetlexArg : Char → Maybe ArgChunkmodule _ whereopen FormatSpec-- Left-biased union of format specs.unionSpec : FormatSpec → FormatSpec → FormatSpecunionSpec spec₁ spec₂ .ArgChunk = spec₁ .ArgChunk ⊎ spec₂ .ArgChunkunionSpec spec₁ spec₂ .ArgType (inj₁ a) = spec₁ .ArgType aunionSpec spec₁ spec₂ .ArgType (inj₂ a) = spec₂ .ArgType aunionSpec spec₁ spec₂ .lexArg c =Maybe.map inj₁ (spec₁ .lexArg c) <∣>Maybe.map inj₂ (spec₂ .lexArg c)module Format (spec : FormatSpec) whereopen FormatSpec spec------------------------------------------------------------------------ Basic typesdata Chunk : Set whereArg : ArgChunk → ChunkRaw : String → ChunkFormat : SetFormat = List Chunk------------------------------------------------------------------------ Semanticssize : Format → ℕsize = List.sum ∘′ List.map λ { (Raw _) → 0; _ → 1 }-- Meaning of a format as a list of value types⟦_⟧ : (fmt : Format) → Sets (size fmt) 0ℓs⟦ [] ⟧ = _⟦ Arg a ∷ cs ⟧ = ArgType a , ⟦ cs ⟧⟦ Raw _ ∷ cs ⟧ = ⟦ cs ⟧------------------------------------------------------------------------ Lexer: from Strings to Formats-- Lexing may fail. To have a useful error message, we defined the-- following enumerated typedata Error : Set whereUnexpectedEndOfString : String → Error-- ^ expected a type declaration; found an empty stringInvalidType : String → Char → String → Error-- ^ invalid type declaration-- return a focus: prefix processed, character causing failure, restlexer : String → Error ⊎ List Chunklexer input = loop [] [] (toList input) whereopen RawApplicative (Sumₗ.applicative Error 0ℓ)-- Type synonyms used locally to document the codeRevWord = List Char -- Mere characters accumulated so farPrefix = RevWord -- Prefix of the input String already readtoRevString : RevWord → StringtoRevString = fromList ∘′ reverse-- Push a Raw token if we have accumulated some mere characterspush : RevWord → List Chunk → List Chunkpush [] ks = kspush cs ks = Raw (toRevString cs) ∷ ks-- Main looploop : RevWord → Prefix → List Char → Error ⊎ List Chunktype : Prefix → List Char → Error ⊎ List Chunkloop acc bef [] = pure (push acc [])-- escaped '%' character: treat like a mere characterloop acc bef ('%' ∷ '%' ∷ cs) = loop ('%' ∷ acc) ('%' ∷ '%' ∷ bef) cs-- non escaped '%': type declaration followingloop acc bef ('%' ∷ cs) = push acc <$> type ('%' ∷ bef) cs-- mere character: push onto the accumulatorloop acc bef (c ∷ cs) = loop (c ∷ acc) (c ∷ bef) cstype bef [] = inj₁ (UnexpectedEndOfString input)type bef (c ∷ cs) = _∷_ <$> chunk c ⊛ loop [] (c ∷ bef) cs wherechunk : Char → Error ⊎ Chunkchunk c =case lexArg c of λ where(just ch) → pure (Arg ch)nothing →force′ (toRevString bef) λ prefix →force′ (fromList cs) λ suffix →inj₁ (InvalidType prefix c suffix)
-------------------------------------------------------------------------- The Agda standard library---- Golden testing framework-------------------------------------------------------------------------- This is a port of the golden testing framework used by the Idris2-- compiler and various Idris2 libraries.-- It provides the core features required to perform golden file testing.---- We provide the core functionality to run a *single* golden file test,-- or a whole test tree. This allows the developer freedom to use as is-- or design the rest of the test harness to their liking.-------------------------------------------------------------------------- Test Structure---- This harness works from the assumption that each individual golden-- test comprises of a directory with the following structure:---- + `run` a *shell* script that runs the test. We expect it to:-- * Use `$1` as the variable standing for the Agda executable to be tested-- * Clean up after itself (e.g. by running `rm -rf build/`)---- + `expected` a file containting the expected output of `run`---- During testing, the test harness will generate an `output` file.-- It will be compared to the `expected` golden file provided by the user.-- In case there is a mismatch, the framework will:-- + either display output & expected if the session is not interactive-- + or use the following command line to produce a diff and ask the user-- whether they want to overwrite the currently `expected` value:---- git diff --no-index --exit-code --word-diff=color expected output---- If `git` fails then the runner will simply present the expected and-- 'given' files side-by-side.---- Of note, it is helpful to add `output` to a local `.gitignore` instance-- to ensure that it is not mistakenly versioned.-------------------------------------------------------------------------- Options---- The test harness has several options that may be set:---- + `exeUnderTest` The path of the executable we are testing (typically `agda`)-- + `onlyNames` The tests to run relative to the generated executable.-- + `onlyFile` The file listing the tests to run relative to the generated executable.-- + `interactive` Whether to offer to update the expected file or not.-- + `timing` Whether to display time taken for each test.-- + `failureFile` The file in which to write the list of failing tests.-- + `colour` The output should use ANSI escape codes---- We provide an options parser (`options`) that takes the list of command line-- arguments and constructs this for you.---------------------------------------------------------------------------- Usage---- When compiled to an executable the expected usage is:----```sh--runtests <path to executable under test>-- [--timing]-- [--interactive]-- [--only-file PATH]-- [--failure-file PATH]-- [--no-colour]-- [--only [NAMES]]--```---- assuming that the test runner is compiled to an executable named `runtests`.{-# OPTIONS --cubical-compatible --guardedness #-}module Test.Golden whereopen import Data.Bool.Base using (Bool; true; false; if_then_else_)import Data.Char as Charopen import Data.Fin using (#_)import Data.Integer.Base as ℤopen import Data.List.Base as List using (List; []; _∷_; _++_; filter; partitionSums)open import Data.List.Relation.Binary.Infix.Heterogeneous.Properties using (infix?)open import Data.List.Relation.Unary.Any using (any?)open import Data.Maybe.Base using (Maybe; just; nothing; fromMaybe)open import Data.Nat.Base using (ℕ; _≡ᵇ_; _<ᵇ_; _+_; _∸_)import Data.Nat.Show as ℕ using (show)open import Data.Product.Base using (_×_; _,_)open import Data.String.Base as String using (String; lines; unlines; unwords; concat)open import Data.String.Properties as String using (_≟_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Unit.Base using (⊤)open import Function.Base using (id; _$_; case_of_)open import Relation.Nullary.Decidable.Core using (does)open import Codata.Musical.Notation using (♯_)open import IOopen import System.Clock as Clock using (time′; Time; seconds)open import System.Console.ANSIopen import System.Directory using (doesFileExist; doesDirectoryExist)open import System.Environment using (getArgs; lookupEnv)open import System.Exitopen import System.FilePath.Posix using (mkFilePath)open import System.Process using (callCommand; system)record Options : Set wherefield-- What is the name of the Agda executable?exeUnderTest : String-- Should we only run some specific cases?onlyNames : List String-- Should we run the test suite interactively?interactive : Bool-- Should we time and display the tests?timing : Bool-- Should we write the list of failing cases to a file?failureFile : Maybe String-- Should we use ANSI escape codes to colour the output?colour : Boolopen OptionsinitOptions : String → OptionsinitOptions exe = record{ exeUnderTest = exe; onlyNames = []; interactive = false; timing = false; failureFile = nothing; colour = true}usage : Stringusage = unwords$ "Usage:"∷ "runtests <path>"∷ "[--timing]"∷ "[--interactive]"∷ "[--failure-file PATH]"∷ "[--only-file PATH]"∷ "[--no-colour]"∷ "[--only [NAMES]]"∷ []data Error : Set whereMissingExecutable : ErrorInvalidArgument : String → Errorshow : Error → Stringshow MissingExecutable = "Expected a path to Agda, got nothing"show (InvalidArgument arg) = "Invalid argument: " String.++ arg-- Process the command line optionsoptions : List String → IO (Error ⊎ Options)options(exe ∷ rest) = mkOptions exe rest wherego : List String → Maybe String → Options → String ⊎ (Maybe String × Options)go [] mfp opts = inj₂ (mfp , opts)go ("--timing" ∷ args) mfp opts =go args mfp (record opts { timing = true })go ("--interactive" ∷ args) mfp opts =go args mfp (record opts { interactive = true })go ("--failure-file" ∷ fp ∷ args) mfp opts =go args mfp (record opts { failureFile = just fp })go ("--only" ∷ args) mfp opts =inj₂ (mfp , (record opts { onlyNames = args }))go ("--only-file" ∷ fp ∷ args) mfp opts =go args (just fp) (record opts { onlyNames = args })go ("--no-colour" ∷ args) mfp opts =go args mfp (record opts { colour = false })go (arg ∷ _) _ _ = inj₁ argmkOptions : String → List String → IO (Error ⊎ Options)mkOptions exe rest = doinj₂ (mfp , opts) ← pure $ go rest nothing (initOptions exe)where inj₁ arg → pure (inj₁ (InvalidArgument arg))term ← fromMaybe "" <$> lookupEnv "TERM"let opts = if does (term ≟ "DUMB")then record opts { colour = false }else optsjust fp ← pure mfpwhere _ → pure (inj₂ opts)only ← readFiniteFile fppure $ inj₂ $ record opts { onlyNames = lines only ++ onlyNames opts }options [] = pure (inj₁ MissingExecutable)-- The result of a test run-- `Left` corresponds to a failure and `Right` to a successResult : SetResult = String ⊎ String-- Run the specified golden test with the supplied options.runTest : Options → String → IO ResultrunTest opts testPath = dotrue ← doesDirectoryExist (mkFilePath testPath)where false → fail directoryNotFoundtime ← time′ $ callCommand $ unwords$ "cd" ∷ testPath∷ "&&" ∷ "sh ./run" ∷ opts .exeUnderTest∷ "| tr -d '\\r' > output"∷ []just out ← readLocalFile "output"where nothing → fail (fileNotFound "output")just exp ← readLocalFile "expected"where nothing → do if opts .interactivethen mayOverwrite nothing outelse putStrLn (fileNotFound "expected")pure (inj₁ testPath)let result = does (out String.≟ exp)if resultthen printTiming (opts .timing) time$ if opts .colourthen withCommand (setColour foreground classic green)else id$ "success"else do printTiming (opts .timing) time$ if opts .colourthen withCommand (setColour foreground bright red)else id$ "FAILURE"if opts .interactivethen mayOverwrite (just exp) outelse putStrLn (unlines (expVsOut exp out))pure $ if result then inj₂ testPath else inj₁ testPathwheredirectoryNotFound : StringdirectoryNotFound = unwords$ "Directory"∷ testPath∷ "does not exist" ∷ []fileNotFound : String → StringfileNotFound name = unwords$ "File"∷ (testPath String.++ "/output")∷ "does not exist" ∷ []fail : String → IO Resultfail msg = do putStrLn msgpure (inj₁ testPath)readLocalFile : String → IO (Maybe String)readLocalFile name = dolet fp = concat (testPath ∷ "/" ∷ name ∷ [])true ← doesFileExist (mkFilePath fp)where false → pure nothingjust <$> readFiniteFile fpgetAnswer : IO BoolgetAnswer = untilJust $ dostr ← getLinecase str of λ where"y" → pure $ just true"n" → pure $ just false"" → pure $ just false -- default answer is no_ → do putStrLn "Invalid answer."pure nothingexpVsOut : String → String → List StringexpVsOut exp out = "Expected:" ∷ exp ∷ "Given:" ∷ out ∷ []hasFailed : ExitCode → BoolhasFailed ExitSuccess = falsehasFailed (ExitFailure code) = code ℤ.≤ᵇ ℤ.+ 0mayOverwrite : Maybe String → String → IO _mayOverwrite mexp out = docase mexp of λ wherenothing → putStrLn $ unlines$ "Golden value missing. I computed the following result:"∷ out∷ "Accept new golden value? [y/N]"∷ [](just exp) → docode ← system $ concat$ "git diff --no-index --exit-code --word-diff=color "∷ testPath ∷ "/expected "∷ testPath ∷ "/output"∷ []putStrLn $ unlines$ "Golden value differs from actual value."∷ (if hasFailed code then expVsOut exp out else [])++ "Accept actual value as new golden value? [y/N]"∷ []b ← getAnswerwhen b $ writeFile (testPath String.++ "/expected") outprintTiming : Bool → Time → String → IO _printTiming false _ msg = putStrLn $ concat (testPath ∷ ": " ∷ msg ∷ [])printTiming true time msg =let time = ℕ.show (time .seconds) String.++ "s"spent = 9 + List.sum (List.map String.length (testPath ∷ time ∷ []))-- ^ hack: both "success" and "FAILURE" have the same length-- can't use `String.length msg` because the msg contains escape codespad = String.replicate (72 ∸ spent) ' 'in putStrLn (concat (testPath ∷ ": " ∷ msg ∷ pad ∷ time ∷ []))-- A test pool is characterised by-- + a name-- + and a list of directory pathsrecord TestPool : Set whereconstructor mkTestPoolfieldpoolName : StringtestCases : List Stringopen TestPoolmodule Summary where-- The summary of a test pool runrecord Summary : Set whereconstructor mkSummaryfieldsuccess : List Stringfailure : List Stringopen Summary publicinit : Summaryinit = mkSummary [] []merge : Summary → Summary → Summarymerge (mkSummary ws1 ls1) (mkSummary ws2 ls2) =mkSummary (ws2 ++ ws1) (ls2 ++ ls1)update : List Result → Summary → Summaryupdate res sum =let (ls2 , ws2) = partitionSums res inmerge sum (mkSummary ws2 ls2)open Summary using (Summary) hiding (module Summary)-- Only keep the tests that have been asked forfilterTests : Options → List String → List StringfilterTests opts = case onlyNames opts of λ where[] → idxs → let names = List.map String.toList xs infilter (λ n → any? (λ m → infix? Char._≟_ m (String.toList n)) names)poolRunner : Options → TestPool → IO SummarypoolRunner opts pool = do-- check there is a non-empty list of tests we want to runlet tests = filterTests opts (pool .testCases)(_ ∷ _) ← pure testswhere [] → pure Summary.init-- announce the test pool and run themputStrLn bannerloop Summary.init testswhereseparator : Stringseparator = String.replicate 72 '-'banner : Stringbanner = unlines$ "" ∷ separator∷ pool .poolName∷ separator ∷ ""∷ []loop : Summary → List String → IO Summaryloop acc [] = pure accloop acc (test ∷ tests) = dores <- runTest opts testloop (Summary.update (res ∷ []) acc) testsrunner : List TestPool → IO ⊤runner tests = do-- figure out the optionsargs ← getArgsinj₂ opts ← options argswhere inj₁ err → die (unlines (show err ∷ usage ∷ []))-- run the testsress ← List.mapM (poolRunner opts) testslet open Summarylet res = List.foldl merge init ress-- report the resultlet nsucc = List.length (res .success)let nfail = List.length (res .failure)let ntotal = nsucc + nfailputStrLn $ concat $ ℕ.show nsucc ∷ "/" ∷ ℕ.show ntotal ∷ " tests successful" ∷ []-- deal with failureslet list = unlines (res .failure)when (0 <ᵇ nfail) $ doputStrLn "Failing tests:"putStrLn listwhenJust (opts .failureFile) $ λ fp → writeFile fp list-- exitif 0 ≡ᵇ nfailthen exitSuccesselse exitFailure
-------------------------------------------------------------------------- The Agda standard library---- A solver that uses reflection to automatically obtain and solve-- equations over rings.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Tactic.RingSolver whereopen import Algebraopen import Data.Fin.Base as Fin using (Fin)open import Data.Vec.Base as Vec using (Vec; _∷_; [])open import Data.List.Base as List using (List; _∷_; [])open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; fromMaybe)open import Data.Nat.Base using (ℕ; suc; zero; _<ᵇ_)open import Data.Bool.Base using (Bool; if_then_else_; true; false)open import Data.Unit.Base using (⊤)open import Data.String.Base as String using (String; _++_; parens)open import Data.Product.Base using (_,_; proj₁)open import Function.Baseopen import Relation.Nullary.Decidableopen import Reflectionopen import Reflection.AST.Argumentopen import Reflection.AST.Term as Termopen import Reflection.AST.AlphaEqualityopen import Reflection.AST.Name as Nameopen import Reflection.TCM.Syntaxopen import Data.Nat.Reflectionopen import Data.List.Reflectionimport Data.Vec.Reflection as Vecopen import Tactic.RingSolver.NonReflective renaming (solve to solver)open import Tactic.RingSolver.Core.AlmostCommutativeRingopen import Tactic.RingSolver.Core.NatSet as NatSetopen AlmostCommutativeRing-------------------------------------------------------------------------- UtilitiesprivateVarMap : SetVarMap = ℕ → Maybe TermgetVisible : Arg Term → Maybe TermgetVisible (arg (arg-info visible _) x) = just xgetVisible _ = nothinggetVisibleArgs : ∀ n → Term → Maybe (Vec Term n)getVisibleArgs n (def _ xs) = Maybe.map Vec.reverse(List.foldl f c (List.mapMaybe getVisible xs) n)wheref : (∀ n → Maybe (Vec Term n)) → Term → ∀ n → Maybe (Vec Term n)f xs x zero = just []f xs x (suc n) = Maybe.map (x ∷_) (xs n)c : ∀ n → Maybe (Vec Term n)c zero = just []c (suc _ ) = nothinggetVisibleArgs _ _ = nothingcurriedTerm : NatSet → TermcurriedTerm = List.foldr go Vec.`[] ∘ NatSet.toListwherego : ℕ → Term → Termgo x xs = var x [] Vec.`∷ xs-------------------------------------------------------------------------- Reflection utilities for rings`AlmostCommutativeRing : Term`AlmostCommutativeRing = def (quote AlmostCommutativeRing) (2 ⋯⟨∷⟩ [])record RingOperatorTerms : Set whereconstructor add⇒_mul⇒_pow⇒_neg⇒_sub⇒_fieldadd mul pow neg sub : TermcheckIsRing : Term → TC TermcheckIsRing ring = checkType ring `AlmostCommutativeRingmodule RingReflection (`ring : Term) where-- Takes the name of a function that takes the ring as it's first-- explicit argument and the terms of it's arguments and inserts-- the required ring arguments-- e.g. "_+_" $ʳ xs = "_+_ {_} {_} ring xs"infixr 6 _$ʳ__$ʳ_ : Name → Args Term → Termnm $ʳ args = def nm (2 ⋯⟅∷⟆ `ring ⟨∷⟩ args)`Carrier : Term`Carrier = quote Carrier $ʳ []`refl : Term`refl = quote refl $ʳ (1 ⋯⟅∷⟆ [])`sym : Term → Term`sym x≈y = quote sym $ʳ (2 ⋯⟅∷⟆ x≈y ⟨∷⟩ [])`trans : Term → Term → Term`trans x≈y y≈z = quote trans $ʳ (3 ⋯⟅∷⟆ x≈y ⟨∷⟩ y≈z ⟨∷⟩ [])-- Normalises each of the fields of the ring operator so we can-- compare the result against the normalised definitions we come-- across when converting the term passed to the macro.getRingOperatorTerms : TC RingOperatorTermsgetRingOperatorTerms = ⦇add⇒ normalise (quote _+_ $ʳ [])mul⇒ normalise (quote _*_ $ʳ [])pow⇒ normalise (quote _^_ $ʳ [])neg⇒ normalise (quote (-_) $ʳ [])sub⇒ normalise (quote _-_ $ʳ [])⦈-------------------------------------------------------------------------- Reflection utilities for ring solvermodule RingSolverReflection (ring : Term) (numberOfVariables : ℕ) whereopen RingReflection ring`numberOfVariables : Term`numberOfVariables = toTerm numberOfVariables-- This function applies the hidden arguments that the constructors-- that Expr needs. The first is the universe level, the second is the-- type it contains, and the third is the number of variables it's-- indexed by. All three of these could likely be inferred, but to-- make things easier we supply the third because we know it.infix -1 _$ᵉ__$ᵉ_ : Name → List (Arg Term) → Terme $ᵉ xs = con e (1 ⋯⟅∷⟆ `Carrier ⟅∷⟆ `numberOfVariables ⟅∷⟆ xs)-- A constant expression.`Κ : Term → Term`Κ x = quote Κ $ᵉ (x ⟨∷⟩ [])`I : Term → Term`I x = quote Ι $ᵉ (x ⟨∷⟩ [])infixl 6 _`⊜__`⊜_ : Term → Term → Termx `⊜ y = quote _⊜_ $ʳ (`numberOfVariables ⟅∷⟆ x ⟨∷⟩ y ⟨∷⟩ [])`correct : Term → Term → Term`correct x ρ = quote Ops.correct $ʳ (1 ⋯⟅∷⟆ x ⟨∷⟩ ρ ⟨∷⟩ [])`solver : Term → Term → Term`solver `f `eq = quote solver $ʳ (`numberOfVariables ⟨∷⟩ `f ⟨∷⟩ `eq ⟨∷⟩ [])-- Converts the raw terms provided by the macro into the `Expr`s-- used internally by the solver.---- When trying to figure out the shape of an expression, one of-- the difficult tasks is recognizing where constants in the-- underlying ring are used. If we were only dealing with ℕ, we-- might look for its constructors: however, we want to deal with-- arbitrary types which implement AlmostCommutativeRing. If the-- Term type contained type information we might be able to-- recognize it there, but it doesn't.---- We're in luck, though, because all other cases in the following-- function *are* recognizable. As a result, the "catch-all" case-- will just assume that it has a constant expression.convertTerm : RingOperatorTerms → VarMap → Term → TC TermconvertTerm operatorTerms varMap = convertwhereopen RingOperatorTerms operatorTermsmutualconvert : Term → TC Term-- First try and match directly against the fieldsconvert (def (quote _+_) xs) = convertOp₂ (quote _⊕_) xsconvert (def (quote _*_) xs) = convertOp₂ (quote _⊗_) xsconvert (def (quote -_) xs) = convertOp₁ (quote ⊝_) xsconvert (def (quote _^_) xs) = convertExp xsconvert (def (quote _-_) xs) = convertSub xs-- Other definitions the underlying implementation of the ring's fieldsconvert (def nm xs) = convertUnknownName nm xs-- Variablesconvert v@(var x _) = pure $ fromMaybe (`Κ v) (varMap x)-- Special case to recognise "suc" for naturalsconvert (`suc x) = convertSuc x-- Otherwise we're forced to treat it as a constantconvert t = pure $ `Κ t-- Application of a ring operator often doesn't have a type as-- simple as "Carrier → Carrier → Carrier": there may be hidden-- arguments, etc. Here, we do our best to handle those cases,-- by just taking the last two explicit arguments.convertOp₂ : Name → Args Term → TC TermconvertOp₂ nm (x ⟨∷⟩ y ⟨∷⟩ []) = dox' ← convert xy' ← convert ypure (nm $ᵉ (x' ⟨∷⟩ y' ⟨∷⟩ []))convertOp₂ nm (x ∷ xs) = convertOp₂ nm xsconvertOp₂ _ _ = pure unknownconvertOp₁ : Name → Args Term → TC TermconvertOp₁ nm (x ⟨∷⟩ []) = dox' ← convert xpure (nm $ᵉ (x' ⟨∷⟩ []))convertOp₁ nm (x ∷ xs) = convertOp₁ nm xsconvertOp₁ _ _ = pure unknownconvertExp : Args Term → TC TermconvertExp (x ⟨∷⟩ y ⟨∷⟩ []) = dox' ← convert xpure (quote _⊛_ $ᵉ (x' ⟨∷⟩ y ⟨∷⟩ []))convertExp (x ∷ xs) = convertExp xsconvertExp _ = pure unknownconvertSub : Args Term → TC TermconvertSub (x ⟨∷⟩ y ⟨∷⟩ []) = dox' ← convert x-y' ← convertOp₁ (quote (⊝_)) (y ⟨∷⟩ [])pure (quote _⊕_ $ᵉ x' ⟨∷⟩ -y' ⟨∷⟩ [])convertSub (x ∷ xs) = convertSub xsconvertSub _ = pure unknownconvertUnknownName : Name → Args Term → TC TermconvertUnknownName nm xs = donameTerm ← normalise (def nm [])if (nameTerm =α= add) then convertOp₂ (quote _⊕_) xs elseif (nameTerm =α= mul) then convertOp₂ (quote _⊗_) xs elseif (nameTerm =α= neg) then convertOp₁ (quote ⊝_) xs elseif (nameTerm =α= pow) then convertExp xs elseif (nameTerm =α= sub) then convertSub xs elsepure (`Κ (def nm xs))convertSuc : Term → TC TermconvertSuc x = do x' ← convert x; pure (quote _⊕_ $ᵉ (`Κ (toTerm 1) ⟨∷⟩ x' ⟨∷⟩ []))-------------------------------------------------------------------------- Macros-------------------------------------------------------------------------- Quantified macroopen RingReflectionopen RingSolverReflectionmalformedForallTypeError : ∀ {a} {A : Set a} → Term → TC AmalformedForallTypeError found = typeError( strErr "Malformed call to solve."∷ strErr "Expected target type to be like: ∀ x y → x + y ≈ y + x."∷ strErr "Instead: "∷ termErr found∷ [])quantifiedVarMap : ℕ → VarMapquantifiedVarMap numVars i =if i <ᵇ numVarsthen just (var i [])else nothingconstructCallToSolver : Term → RingOperatorTerms → List String → Term → Term → TC TermconstructCallToSolver `ring opNames variables `lhs `rhs = do`lhsExpr ← conv `lhs`rhsExpr ← conv `rhspure $ `solver `ring numVars(prependVLams variables (_`⊜_ `ring numVars `lhsExpr `rhsExpr))(prependHLams variables (`refl `ring))wherenumVars : ℕnumVars = List.length variablesconv : Term → TC Termconv = convertTerm `ring numVars opNames (quantifiedVarMap numVars)-- This is the main macro which solves for equations in which the-- variables are universally quantified over:---- lemma : ∀ x y → x + y ≈ y + x-- lemma = solve-∀ ring---- where ring is your implementation of AlmostCommutativeRing.-- (Find some example implementations in-- Polynomial.Solver.Ring.AlmostCommutativeRing.Instances).solve-∀-macro : Name → Term → TC ⊤solve-∀-macro ring hole = do`ring ← checkIsRing (def ring [])commitTCoperatorTerms ← getRingOperatorTerms `ring-- Obtain and sanitise the goal type`hole ← inferType hole >>= reducelet variablesAndTypes , equation = stripPis `holelet variables = List.map proj₁ variablesAndTypesjust (lhs ∷ rhs ∷ []) ← pure (getVisibleArgs 2 equation)where nothing → malformedForallTypeError `holesolverCall ← constructCallToSolver `ring operatorTerms variables lhs rhsunify hole solverCallmacrosolve-∀ : Name → Term → TC ⊤solve-∀ = solve-∀-macro-------------------------------------------------------------------------- Unquantified macromalformedArgumentListError : ∀ {a} {A : Set a} → Term → TC AmalformedArgumentListError found = typeError( strErr "Malformed call to solve."∷ strErr "First argument should be a list of free variables."∷ strErr "Instead: "∷ termErr found∷ [])malformedGoalError : ∀ {a} {A : Set a} → Term → TC AmalformedGoalError found = typeError( strErr "Malformed call to solve."∷ strErr "Goal type should be of the form: LHS ≈ RHS"∷ strErr "Instead: "∷ termErr found∷ [])checkIsListOfVariables : Term → Term → TC TermcheckIsListOfVariables `ring `xs = checkType `xs (`List (`Carrier `ring)) >>= normalise-- Extracts the deBruijn indices from a list of variablesgetVariableIndices : Term → Maybe NatSetgetVariableIndices = go []wherego : NatSet → Term → Maybe NatSetgo t (var i [] `∷` xs) = go (insert i t) xsgo t `[]` = just tgo _ _ = nothingconstructSolution : Term → RingOperatorTerms → NatSet → Term → Term → TC TermconstructSolution `ring opTerms variables `lhs `rhs = do`lhsExpr ← conv `lhs`rhsExpr ← conv `rhspure $ `trans `ring (`sym `ring `lhsExpr) `rhsExprwherenumVars = List.length variablesvarMap : VarMapvarMap i = Maybe.map (λ x → `I `ring numVars (toFinTerm x)) (lookup variables i)ρ : Termρ = curriedTerm variablesconv = λ t → dot' ← convertTerm `ring numVars opTerms varMap tpure $ `correct `ring numVars t' ρ-- Use this macro when you want to solve something *under* a lambda.-- For example: say you have a long proof, and you just want the solver-- to deal with an intermediate step. Call it like so:---- lemma₃ : ∀ x y → x + y * 1 + 3 ≈ 2 + 1 + y + x-- lemma₃ x y = begin-- x + y * 1 + 3 ≈⟨ +-comm x (y * 1) ⟨ +-cong ⟩ refl ⟩-- y * 1 + x + 3 ≈⟨ solve (x ∷ y ∷ []) Int.ring ⟩-- 3 + y + x ≡⟨ refl ⟩-- 2 + 1 + y + x ∎---- The first argument is the free variables, and the second is the-- ring implementation (as before).solve-macro : Term → Name → Term → TC ⊤solve-macro variables ring hole = do`ring ← checkIsRing (def ring [])commitTCoperatorTerms ← getRingOperatorTerms `ring-- Obtain and sanitise the list of variableslistOfVariables′ ← checkIsListOfVariables `ring variablescommitTCjust variableIndices ← pure (getVariableIndices listOfVariables′)where nothing → malformedArgumentListError listOfVariables′-- Obtain and santise the goal typehole′ ← inferType hole >>= reducejust (lhs ∷ rhs ∷ []) ← pure (getVisibleArgs 2 hole′)where nothing → malformedGoalError hole′solution ← constructSolution `ring operatorTerms variableIndices lhs rhsunify hole solutionmacrosolve : Term → Name → Term → TC ⊤solve = solve-macro
-------------------------------------------------------------------------- The Agda standard library---- An implementation of the ring solver that requires you to manually-- pass the equation you wish to solve.-------------------------------------------------------------------------- You'll probably want to use `Tactic.RingSolver` instead which uses-- reflection to automatically extract the equation.{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.AlmostCommutativeRingmodule Tactic.RingSolver.NonReflective{ℓ₁ ℓ₂} (ring : AlmostCommutativeRing ℓ₁ ℓ₂)(let open AlmostCommutativeRing ring)whereopen import Algebra.Morphismopen import Function.Base using (id; _⟨_⟩_)open import Data.Bool.Base using (Bool; true; false; T; if_then_else_)open import Data.Maybe.Baseopen import Data.Empty using (⊥-elim)open import Data.Nat.Base using (ℕ)open import Data.Product.Base using (_×_; proj₁; proj₂; _,_)open import Data.Vec.Base using (Vec)open import Data.Vec.N-aryopen import Tactic.RingSolver.Core.Polynomial.Parametersopen import Tactic.RingSolver.Core.Expression publicopen import Algebra.Properties.Semiring.Exp.TCOptimised semiringmodule Ops wherezero-homo : ∀ x → T (is-just (0≟ x)) → 0# ≈ xzero-homo x _ with 0≟ xzero-homo x _ | just p = pzero-homo x () | nothinghomo : Homomorphism ℓ₁ ℓ₂ ℓ₁ ℓ₂homo = record{ from = record{ rawRing = AlmostCommutativeRing.rawRing ring; isZero = λ x → is-just (0≟ x)}; to = record{ isAlmostCommutativeRing = record{ isCommutativeSemiring = isCommutativeSemiring; -‿cong = -‿cong; -‿*-distribˡ = -‿*-distribˡ; -‿+-comm = -‿+-comm}}; morphism = -raw-almostCommutative⟶ ring; Zero-C⟶Zero-R = zero-homo}open Eval rawRing id publicopen import Tactic.RingSolver.Core.Polynomial.Base (Homomorphism.from homo)norm : ∀ {n} → Expr Carrier n → Poly nnorm (Κ x) = κ xnorm (Ι x) = ι xnorm (x ⊕ y) = norm x ⊞ norm ynorm (x ⊗ y) = norm x ⊠ norm ynorm (⊝ x) = ⊟ norm xnorm (x ⊛ i) = norm x ⊡ i⟦_⇓⟧ : ∀ {n} → Expr Carrier n → Vec Carrier n → Carrier⟦ expr ⇓⟧ = ⟦ norm expr ⟧ₚ whereopen import Tactic.RingSolver.Core.Polynomial.Semantics homorenaming (⟦_⟧ to ⟦_⟧ₚ)correct : ∀ {n} (expr : Expr Carrier n) ρ → ⟦ expr ⇓⟧ ρ ≈ ⟦ expr ⟧ ρcorrect {n = n} = gowhereopen import Tactic.RingSolver.Core.Polynomial.Homomorphism homogo : ∀ (expr : Expr Carrier n) ρ → ⟦ expr ⇓⟧ ρ ≈ ⟦ expr ⟧ ρgo (Κ x) ρ = κ-hom x ρgo (Ι x) ρ = ι-hom x ρgo (x ⊕ y) ρ = ⊞-hom (norm x) (norm y) ρ ⟨ trans ⟩ (go x ρ ⟨ +-cong ⟩ go y ρ)go (x ⊗ y) ρ = ⊠-hom (norm x) (norm y) ρ ⟨ trans ⟩ (go x ρ ⟨ *-cong ⟩ go y ρ)go (⊝ x) ρ = ⊟-hom (norm x) ρ ⟨ trans ⟩ -‿cong (go x ρ)go (x ⊛ i) ρ = ⊡-hom (norm x) i ρ ⟨ trans ⟩ ^-congˡ i (go x ρ)open import Relation.Binary.Reflection setoid Ι ⟦_⟧ ⟦_⇓⟧ correct publicsolve : ∀ (n : ℕ) →(f : N-ary n (Expr Carrier n) (Expr Carrier n × Expr Carrier n)) →Eqʰ n _≈_ (curryⁿ (Ops.⟦_⇓⟧ (proj₁ (Ops.close n f)))) (curryⁿ (Ops.⟦_⇓⟧ (proj₂ (Ops.close n f)))) →Eq n _≈_ (curryⁿ (Ops.⟦_⟧ (proj₁ (Ops.close n f)))) (curryⁿ (Ops.⟦_⟧ (proj₂ (Ops.close n f))))solve = Ops.solve{-# INLINE solve #-}infixl 6 _⊜__⊜_ : ∀ {n : ℕ} →Expr Carrier n →Expr Carrier n →Expr Carrier n × Expr Carrier n_⊜_ = _,_{-# INLINE _⊜_ #-}
-------------------------------------------------------------------------- The Agda standard library---- "Evaluating" a polynomial, using Horner's method.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Semantics{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Nat.Base using (ℕ; suc; zero; _≤′_; ≤′-step; ≤′-refl)open import Data.Vec.Base using (Vec; []; _∷_; uncons)open import Data.List.Base using ([]; _∷_)open import Data.Product.Base using (_,_; _×_)open import Data.List.Kleene using (_+; _*; ∹_; _&_; [])open Homomorphism homo hiding (_^_)open import Tactic.RingSolver.Core.Polynomial.Base fromopen import Algebra.Properties.Semiring.Exp.TCOptimised semiringdrop : ∀ {i n} → i ≤′ n → Vec Carrier n → Vec Carrier idrop ≤′-refl xs = xsdrop (≤′-step i+1≤n) (_ ∷ xs) = drop i+1≤n xsdrop-1 : ∀ {i n} → suc i ≤′ n → Vec Carrier n → Carrier × Vec Carrier idrop-1 si≤n xs = uncons (drop si≤n xs){-# INLINE drop-1 #-}_*⟨_⟩^_ : Carrier → Carrier → ℕ → Carrierx *⟨ ρ ⟩^ zero = xx *⟨ ρ ⟩^ suc i = ρ ^ (suc i) * x{-# INLINE _*⟨_⟩^_ #-}-------------------------------------------------------------------------- Evaluation-------------------------------------------------------------------------- Why do we have three functions here? Why are they so weird looking?---- These three functions are the main bottleneck for all of the proofs:-- as such, slight changes can dramatically affect the length of proof-- code.mutual_⟦∷⟧_ : ∀ {n} → Poly n × Coeff n * → Carrier × Vec Carrier n → Carrier(x , []) ⟦∷⟧ (ρ , ρs) = ⟦ x ⟧ ρs(x , (∹ xs)) ⟦∷⟧ (ρ , ρs) = ρ * ⅀⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs⅀⟦_⟧ : ∀ {n} → Coeff n + → (Carrier × Vec Carrier n) → Carrier⅀⟦ x ≠0 Δ i & xs ⟧ (ρ , ρs) = ((x , xs) ⟦∷⟧ (ρ , ρs)) *⟨ ρ ⟩^ i{-# INLINE ⅀⟦_⟧ #-}⟦_⟧ : ∀ {n} → Poly n → Vec Carrier n → Carrier⟦ Κ x ⊐ i≤n ⟧ _ = ⟦ x ⟧ᵣ⟦ ⅀ xs ⊐ i≤n ⟧ Ρ = ⅀⟦ xs ⟧ (drop-1 i≤n Ρ){-# INLINE ⟦_⟧ #-}-------------------------------------------------------------------------- Performance-------------------------------------------------------------------------- As you might imagine, the implementation of the functions above-- seriously affect performance. What you might not realise, though,-- is that the most important component is the *order of the arguments*.-- For instance, if we change:---- (x , xs) ⟦∷⟧ (ρ , ρs) = ρ * ⅀⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs---- To:---- (x , xs) ⟦∷⟧ (ρ , ρs) = ⟦ x ⟧ ρs + ⅀⟦ xs ⟧ (ρ , ρs) * ρ---- We get a function that's several orders of magnitude slower!
-------------------------------------------------------------------------- The Agda standard library---- Polynomial reasoning------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.AlmostCommutativeRing-- Some specialised tools for equational reasoning.module Tactic.RingSolver.Core.Polynomial.Reasoning{a ℓ} (ring : AlmostCommutativeRing a ℓ)whereopen AlmostCommutativeRing ringopen import Relation.Binary.Reasoning.Setoid setoid publicinfixr 1 ≪+_ +≫_ ≪*_ *≫_infixr 0 _⊙_≪+_ : ∀ {x₁ x₂ y} → x₁ ≈ x₂ → x₁ + y ≈ x₂ + y≪+ prf = +-cong prf refl{-# INLINE ≪+_ #-}+≫_ : ∀ {x y₁ y₂} → y₁ ≈ y₂ → x + y₁ ≈ x + y₂+≫_ = +-cong refl{-# INLINE +≫_ #-}≪*_ : ∀ {x₁ x₂ y} → x₁ ≈ x₂ → x₁ * y ≈ x₂ * y≪* prf = *-cong prf refl{-# INLINE ≪*_ #-}*≫_ : ∀ {x y₁ y₂} → y₁ ≈ y₂ → x * y₁ ≈ x * y₂*≫_ = *-cong refl{-# INLINE *≫_ #-}-- transitivity as an operator_⊙_ : ∀ {x y z} → x ≈ y → y ≈ z → x ≈ z_⊙_ = trans{-# INLINE _⊙_ #-}
-------------------------------------------------------------------------- The Agda standard library---- Bundles of parameters for passing to the Ring Solver------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module packages up all the stuff that's passed to the other-- modules in a convenient form.module Tactic.RingSolver.Core.Polynomial.Parameters whereopen import Algebra.Bundles using (RawRing)open import Data.Bool.Base using (Bool; T)open import Levelopen import Relation.Unaryopen import Tactic.RingSolver.Core.AlmostCommutativeRing-- This record stores all the stuff we need for the coefficients:---- * A raw ring-- * A (decidable) predicate on "zeroeness"---- It's used for defining the operations on the Horner normal form.record RawCoeff ℓ₁ ℓ₂ : Set (suc (ℓ₁ ⊔ ℓ₂)) wherefieldrawRing : RawRing ℓ₁ ℓ₂isZero : RawRing.Carrier rawRing → Boolopen RawRing rawRing public-- This record stores the full information we need for converting-- to the final ring.record Homomorphism ℓ₁ ℓ₂ ℓ₃ ℓ₄ : Set (suc (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄)) wherefieldfrom : RawCoeff ℓ₁ ℓ₂to : AlmostCommutativeRing ℓ₃ ℓ₄module Raw = RawCoeff fromopen AlmostCommutativeRing to publicfieldmorphism : Raw.rawRing -Raw-AlmostCommutative⟶ toopen _-Raw-AlmostCommutative⟶_ morphism renaming (⟦_⟧ to ⟦_⟧ᵣ) publicfieldZero-C⟶Zero-R : ∀ x → T (Raw.isZero x) → 0# ≈ ⟦ x ⟧ᵣ
-------------------------------------------------------------------------- The Agda standard library---- Some specialised instances of the ring solver------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parameters-- Here, we provide proofs of homomorphism between the operations-- defined on polynomials and those on the underlying ring.module Tactic.RingSolver.Core.Polynomial.Homomorphism{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)where-- Proofs for each component of the polynomialopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Addition homo using (⊞-hom) publicopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Multiplication homo using (⊠-hom) publicopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Negation homo using (⊟-hom) publicopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Exponentiation homo using (⊡-hom) publicopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Constants homo using (κ-hom) publicopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Variables homo using (ι-hom) public
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for variables and constants over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Variables{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Product.Base using (_,_)open import Data.Vec.Base as Vec using (Vec)open import Data.Fin.Base using (Fin)open import Data.List.Kleeneopen Homomorphism homoopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas homoopen import Tactic.RingSolver.Core.Polynomial.Base (Homomorphism.from homo)open import Tactic.RingSolver.Core.Polynomial.Reasoning (Homomorphism.to homo)open import Tactic.RingSolver.Core.Polynomial.Semantics homoι-hom : ∀ {n} (i : Fin n) (Ρ : Vec Carrier n) → ⟦ ι i ⟧ Ρ ≈ Vec.lookup Ρ iι-hom i Ρ′ = let (ρ , Ρ) = drop-1 (space≤′n i) Ρ′ in begin⟦ (κ Raw.1# Δ 1 ∷↓ []) ⊐↓ space≤′n i ⟧ Ρ′ ≈⟨ ⊐↓-hom (κ Raw.1# Δ 1 ∷↓ []) (space≤′n i) Ρ′ ⟩⅀?⟦ κ Raw.1# Δ 1 ∷↓ [] ⟧ (ρ , Ρ) ≈⟨ ∷↓-hom-s (κ Raw.1#) 0 [] ρ Ρ ⟩ρ * ⟦ κ Raw.1# ⟧ Ρ ≈⟨ *≫ 1-homo ⟩ρ * 1# ≈⟨ *-identityʳ ρ ⟩ρ ≡⟨ drop-1⇒lookup i Ρ′ ⟩Vec.lookup Ρ′ i ∎
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for negation over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Negation{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Vec.Base using (Vec)open import Data.Product.Base using (_,_)open import Data.Nat.Base using (_<′_)open import Data.Nat.Inductionopen import Function.Base using (_⟨_⟩_; flip)open Homomorphism homoopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas homoopen import Tactic.RingSolver.Core.Polynomial.Reasoning toopen import Tactic.RingSolver.Core.Polynomial.Base fromopen import Tactic.RingSolver.Core.Polynomial.Semantics homo⊟-step-hom : ∀ {n} (a : Acc _<′_ n) → (xs : Poly n) → ∀ ρ → ⟦ ⊟-step a xs ⟧ ρ ≈ - (⟦ xs ⟧ ρ)⊟-step-hom (acc _ ) (Κ x ⊐ i≤n) ρ = -‿homo x⊟-step-hom (acc wf) (⅀ xs ⊐ i≤n) ρ′ =let (ρ , ρs) = drop-1 i≤n ρ′neg-zero =begin0#≈⟨ sym (zeroʳ _) ⟩- 0# * 0#≈⟨ -‿*-distribˡ 0# 0# ⟩- (0# * 0#)≈⟨ -‿cong (zeroˡ 0#) ⟩- 0#∎inbegin⟦ poly-map (⊟-step (wf i≤n)) xs ⊐↓ i≤n ⟧ ρ′≈⟨ ⊐↓-hom (poly-map (⊟-step (wf i≤n)) xs) i≤n ρ′ ⟩⅀?⟦ poly-map (⊟-step (wf i≤n)) xs ⟧ (ρ , ρs)≈⟨ poly-mapR ρ ρs (⊟-step (wf i≤n)) -_ (-‿cong) (λ x y → *-comm x (- y) ⟨ trans ⟩ -‿*-distribˡ y x ⟨ trans ⟩ -‿cong (*-comm _ _)) (λ x y → sym (-‿+-comm x y)) (flip (⊟-step-hom (wf i≤n)) ρs) (sym neg-zero ) xs ⟩- ⅀⟦ xs ⟧ (ρ , ρs)∎⊟-hom : ∀ {n}→ (xs : Poly n)→ (Ρ : Vec Carrier n)→ ⟦ ⊟ xs ⟧ Ρ ≈ - ⟦ xs ⟧ Ρ⊟-hom = ⊟-step-hom (<′-wellFounded _)
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for multiplication over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Multiplication{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Nat.Base as ℕ using (ℕ; suc; zero; _<′_; _≤′_; ≤′-step; ≤′-refl)open import Data.Nat.Properties using (≤′-trans)open import Data.Nat.Inductionopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂; map₁)open import Data.List.Kleeneopen import Data.Vec.Base using (Vec)open import Function.Base using (_⟨_⟩_; flip)open import Induction.WellFoundedopen import Relation.Unaryopen Homomorphism homo hiding (_^_)open import Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas homoopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Addition homoopen import Tactic.RingSolver.Core.Polynomial.Base fromopen import Tactic.RingSolver.Core.Polynomial.Reasoning toopen import Tactic.RingSolver.Core.Polynomial.Semantics homoopen import Algebra.Definitions.RawSemiring rawSemiringusing () renaming (_^′_ to _^_)reassoc : ∀ {y} x z → x * (y * z) ≈ y * (x * z)reassoc {y} x z = sym (*-assoc x y z) ⟨ trans ⟩ ((≪* *-comm x y) ⟨ trans ⟩ *-assoc y x z)mutual⊠-step′-hom : ∀ {n} → (a : Acc _<′_ n) → (xs ys : Poly n) → ∀ ρ → ⟦ ⊠-step′ a xs ys ⟧ ρ ≈ ⟦ xs ⟧ ρ * ⟦ ys ⟧ ρ⊠-step′-hom a (x ⊐ p) = ⊠-step-hom a x p⊠-step-hom : ∀ {i n}→ (a : Acc _<′_ n)→ (xs : FlatPoly i)→ (i≤n : i ≤′ n)→ (ys : Poly n)→ ∀ ρ → ⟦ ⊠-step a xs i≤n ys ⟧ ρ ≈ ⟦ xs ⊐ i≤n ⟧ ρ * ⟦ ys ⟧ ρ⊠-step-hom a (Κ x) i≤n = ⊠-Κ-hom a x⊠-step-hom a (⅀ xs) i≤n = ⊠-⅀-hom a xs i≤n⊠-Κ-hom : ∀ {n}→ (a : Acc _<′_ n)→ ∀ x→ (ys : Poly n)→ ∀ ρ→ ⟦ ⊠-Κ a x ys ⟧ ρ ≈ ⟦ x ⟧ᵣ * ⟦ ys ⟧ ρ⊠-Κ-hom (acc _) x (Κ y ⊐ i≤n) ρ = *-homo x y⊠-Κ-hom (acc wf) x (⅀ xs ⊐ i≤n) ρ =begin⟦ ⊠-Κ-inj (wf i≤n) x xs ⊐↓ i≤n ⟧ ρ≈⟨ ⊐↓-hom (⊠-Κ-inj (wf i≤n) x xs) i≤n ρ ⟩⅀?⟦ ⊠-Κ-inj (wf i≤n) x xs ⟧ (drop-1 i≤n ρ)≈⟨ ⊠-Κ-inj-hom (wf i≤n) x xs (drop-1 i≤n ρ) ⟩⟦ x ⟧ᵣ * ⅀⟦ xs ⟧ (drop-1 i≤n ρ)∎⊠-Κ-inj-hom : ∀ {n}→ (a : Acc _<′_ n)→ (x : Raw.Carrier)→ (xs : Coeff n +)→ ∀ ρ→ ⅀?⟦ ⊠-Κ-inj a x xs ⟧ ρ ≈ ⟦ x ⟧ᵣ * ⅀⟦ xs ⟧ ρ⊠-Κ-inj-hom {n} a x xs (ρ , Ρ) =poly-mapRρΡ(⊠-Κ a x)(⟦ x ⟧ᵣ *_)(*-cong refl)reassoc(distribˡ ⟦ x ⟧ᵣ)(λ ys → ⊠-Κ-hom a x ys Ρ)(zeroʳ _)xs⊠-⅀-hom : ∀ {i n}→ (a : Acc _<′_ n)→ (xs : Coeff i +)→ (i<n : i <′ n)→ (ys : Poly n)→ ∀ ρ→ ⟦ ⊠-⅀ a xs i<n ys ⟧ ρ ≈ ⅀⟦ xs ⟧ (drop-1 i<n ρ) * ⟦ ys ⟧ ρ⊠-⅀-hom (acc wf) xs i<n (⅀ ys ⊐ j≤n) = ⊠-match-hom (acc wf) (inj-compare i<n j≤n) xs ys⊠-⅀-hom (acc wf) xs i<n (Κ y ⊐ _) ρ =begin⟦ ⊠-Κ-inj (wf i<n) y xs ⊐↓ i<n ⟧ ρ≈⟨ ⊐↓-hom (⊠-Κ-inj (wf i<n) y xs) i<n ρ ⟩⅀?⟦ ⊠-Κ-inj (wf i<n) y xs ⟧ (drop-1 i<n ρ)≈⟨ ⊠-Κ-inj-hom (wf i<n) y xs (drop-1 i<n ρ) ⟩⟦ y ⟧ᵣ * ⅀⟦ xs ⟧ (drop-1 i<n ρ)≈⟨ *-comm _ _ ⟩⅀⟦ xs ⟧ (drop-1 i<n ρ) * ⟦ y ⟧ᵣ∎⊠-⅀-inj-hom : ∀ {i k}→ (a : Acc _<′_ k)→ (i<k : i <′ k)→ (xs : Coeff i +)→ (ys : Poly k)→ ∀ ρ→ ⟦ ⊠-⅀-inj a i<k xs ys ⟧ ρ ≈ ⅀⟦ xs ⟧ (drop-1 i<k ρ) * ⟦ ys ⟧ ρ⊠-⅀-inj-hom (acc wf) i<k x (⅀ ys ⊐ j≤k) = ⊠-match-hom (acc wf) (inj-compare i<k j≤k) x ys⊠-⅀-inj-hom (acc wf) i<k x (Κ y ⊐ j≤k) ρ =begin⟦ ⊠-Κ-inj (wf i<k) y x ⊐↓ i<k ⟧ ρ≈⟨ ⊐↓-hom (⊠-Κ-inj (wf i<k) y x) i<k ρ ⟩⅀?⟦ ⊠-Κ-inj (wf i<k) y x ⟧ (drop-1 i<k ρ)≈⟨ ⊠-Κ-inj-hom (wf i<k) y x (drop-1 i<k ρ) ⟩⟦ y ⟧ᵣ * ⅀⟦ x ⟧ (drop-1 i<k ρ)≈⟨ *-comm _ _ ⟩⅀⟦ x ⟧ (drop-1 i<k ρ) * ⟦ y ⟧ᵣ∎⊠-match-hom : ∀ {i j n}→ (a : Acc _<′_ n)→ {i<n : i <′ n}→ {j<n : j <′ n}→ (ord : InjectionOrdering i<n j<n)→ (xs : Coeff i +)→ (ys : Coeff j +)→ (Ρ : Vec Carrier n)→ ⟦ ⊠-match a ord xs ys ⟧ Ρ≈ ⅀⟦ xs ⟧ (drop-1 i<n Ρ) * ⅀⟦ ys ⟧ (drop-1 j<n Ρ)⊠-match-hom {j = j} (acc wf) (inj-lt i≤j-1 j≤n) xs ys Ρ′ =let (ρ , Ρ) = drop-1 j≤n Ρ′xs′ = ⅀⟦ xs ⟧ (drop-1 (≤′-trans (≤′-step i≤j-1) j≤n) Ρ′)inbegin⟦ poly-map ( (⊠-⅀-inj (wf j≤n) i≤j-1 xs)) ys ⊐↓ j≤n ⟧ Ρ′≈⟨ ⊐↓-hom (poly-map ( (⊠-⅀-inj (wf j≤n) i≤j-1 xs)) ys) j≤n Ρ′ ⟩⅀?⟦ poly-map ( (⊠-⅀-inj (wf j≤n) i≤j-1 xs)) ys ⟧ (ρ , Ρ)≈⟨ poly-mapR ρ Ρ (⊠-⅀-inj (wf j≤n) i≤j-1 xs)(_ *_)(*-cong refl)reassoc(distribˡ _)(λ y → ⊠-⅀-inj-hom (wf j≤n) i≤j-1 xs y _)(zeroʳ _) ys ⟩⅀⟦ xs ⟧ (drop-1 i≤j-1 Ρ) * ⅀⟦ ys ⟧ (ρ , Ρ)≈⟨ ≪* trans-join-coeffs-hom i≤j-1 j≤n xs Ρ′ ⟩xs′ * ⅀⟦ ys ⟧ (ρ , Ρ)∎⊠-match-hom (acc wf) (inj-gt i≤n j≤i-1) xs ys Ρ′ =let (ρ , Ρ) = drop-1 i≤n Ρ′ys′ = ⅀⟦ ys ⟧ (drop-1 (≤′-step j≤i-1 ⟨ ≤′-trans ⟩ i≤n) Ρ′)inbegin⟦ poly-map ( (⊠-⅀-inj (wf i≤n) j≤i-1 ys)) xs ⊐↓ i≤n ⟧ Ρ′≈⟨ ⊐↓-hom (poly-map ( (⊠-⅀-inj (wf i≤n) j≤i-1 ys)) xs) i≤n Ρ′ ⟩⅀?⟦ poly-map ( (⊠-⅀-inj (wf i≤n) j≤i-1 ys)) xs ⟧ (ρ , Ρ)≈⟨ poly-mapR ρ Ρ (⊠-⅀-inj (wf i≤n) j≤i-1 ys)(_ *_)(*-cong refl)reassoc(distribˡ _)(λ x → ⊠-⅀-inj-hom (wf i≤n) j≤i-1 ys x _)(zeroʳ _) xs ⟩⅀⟦ ys ⟧ (drop-1 j≤i-1 Ρ) * ⅀⟦ xs ⟧ (ρ , Ρ)≈⟨ ≪* trans-join-coeffs-hom j≤i-1 i≤n ys Ρ′ ⟩ys′ * ⅀⟦ xs ⟧ (ρ , Ρ)≈⟨ *-comm ys′ _ ⟩⅀⟦ xs ⟧ (ρ , Ρ) * ys′∎⊠-match-hom (acc wf) (inj-eq ij≤n) xs ys Ρ =begin⟦ ⊠-coeffs (wf ij≤n) xs ys ⊐↓ ij≤n ⟧ Ρ≈⟨ ⊐↓-hom (⊠-coeffs (wf ij≤n) xs ys) ij≤n Ρ ⟩⅀?⟦ ⊠-coeffs (wf ij≤n) xs ys ⟧ (drop-1 ij≤n Ρ)≈⟨ ⊠-coeffs-hom (wf ij≤n) xs ys (drop-1 ij≤n Ρ) ⟩⅀⟦ xs ⟧ (drop-1 ij≤n Ρ) * ⅀⟦ ys ⟧ (drop-1 ij≤n Ρ)∎⊠-coeffs-hom : ∀ {n}→ (a : Acc _<′_ n)→ (xs ys : Coeff n +)→ ∀ ρ → ⅀?⟦ ⊠-coeffs a xs ys ⟧ ρ ≈ ⅀⟦ xs ⟧ ρ * ⅀⟦ ys ⟧ ρ⊠-coeffs-hom a xs (y ≠0 Δ j & []) (ρ , Ρ) =begin⅀?⟦ poly-map (⊠-step′ a y) xs ⍓* j ⟧ (ρ , Ρ)≈⟨ sym (pow′-hom j (poly-map (⊠-step′ a y) xs) ρ Ρ) ⟩⅀?⟦ poly-map (⊠-step′ a y) xs ⟧ (ρ , Ρ) *⟨ ρ ⟩^ j≈⟨ pow-mul-cong (poly-mapR ρ Ρ (⊠-step′ a y) (⟦ y ⟧ Ρ *_) (*-cong refl) reassoc (distribˡ _) (λ z → ⊠-step′-hom a y z Ρ) (zeroʳ _) xs) ρ j ⟩(⟦ y ⟧ Ρ * ⅀⟦ xs ⟧ (ρ , Ρ)) *⟨ ρ ⟩^ j≈⟨ pow-opt _ ρ j ⟩(ρ ^ j) * (⟦ y ⟧ Ρ * ⅀⟦ xs ⟧ (ρ , Ρ))≈⟨ sym (*-assoc _ _ _) ⟩(ρ ^ j) * ⟦ y ⟧ Ρ * ⅀⟦ xs ⟧ (ρ , Ρ)≈⟨ *-comm _ _ ⟩⅀⟦ xs ⟧ (ρ , Ρ) * ((ρ ^ j) * ⟦ y ⟧ Ρ)≈⟨ *≫ sym (pow-opt _ ρ j) ⟩⅀⟦ xs ⟧ (ρ , Ρ) * (⟦ y ⟧ Ρ *⟨ ρ ⟩^ j)∎⊠-coeffs-hom a xs (y ≠0 Δ j & ∹ ys) (ρ , Ρ) =let xs′ = ⅀⟦ xs ⟧ (ρ , Ρ)y′ = ⟦ y ⟧ Ρys′ = ⅀⟦ ys ⟧ (ρ , Ρ)inbegin⅀?⟦ para (⊠-cons a y ys) xs ⍓* j ⟧ (ρ , Ρ)≈⟨ sym (pow′-hom j (para (⊠-cons a y ys) xs) ρ Ρ) ⟨ trans ⟩ pow-opt _ ρ j ⟩ρ ^ j * ⅀?⟦ para (⊠-cons a y ys) xs ⟧ (ρ , Ρ)≈⟨ *≫ ⊠-cons-hom a y ys xs ρ Ρ ⟩ρ ^ j * (xs′ * (ρ * ys′ + y′))≈⟨ sym (*-assoc _ _ _) ⟨ trans ⟩ (≪* *-comm _ _) ⟨ trans ⟩ *-assoc _ _ _ ⟨ trans ⟩ (*≫ sym (pow-opt _ ρ j))⟩xs′ * ((ρ * ys′ + y′) *⟨ ρ ⟩^ j)∎⊠-cons-hom : ∀ {n}→ (a : Acc _<′_ n)→ (y : Poly n)→ (ys xs : Coeff n +)→ (ρ : Carrier)→ (Ρ : Vec Carrier n)→ ⅀?⟦ para (⊠-cons a y ys) xs ⟧ (ρ , Ρ)≈ ⅀⟦ xs ⟧ (ρ , Ρ) * (ρ * ⅀⟦ ys ⟧ (ρ , Ρ) + ⟦ y ⟧ Ρ)-- ⊠-cons-hom a y [] xs ρ Ρ = {!!}⊠-cons-hom a y ys xs ρ Ρ = poly-foldR ρ Ρ (⊠-cons a y ys) (flip _*_ (ρ * ⅀⟦ ys ⟧ (ρ , Ρ) + ⟦ y ⟧ Ρ)) (flip *-cong refl) (λ x y → sym (*-assoc x y _)) step (zeroˡ _) xswherestep = λ { (z ⊐ j≤n) {ys₁} zs ys≋zs →let x′ = ⟦ z ⊐ j≤n ⟧ Ρxs′ = ⅀?⟦ zs ⟧ (ρ , Ρ)y′ = ⟦ y ⟧ Ρys′ = ⅀⟦ ys ⟧ (ρ , Ρ)step = λ y → ⊠-step-hom a z j≤n y Ρinbeginρ * ⅀?⟦ ⊞-coeffs (poly-map ( (⊠-step a z j≤n)) ys) ys₁ ⟧ (ρ , Ρ) + ⟦ ⊠-step a z j≤n y ⟧ Ρ≈⟨ (*≫ ⊞-coeffs-hom (poly-map (⊠-step a z j≤n) ys) _ (ρ , Ρ)) ⟨ +-cong ⟩ ⊠-step-hom a z j≤n y Ρ ⟩ρ * (⅀?⟦ poly-map (⊠-step a z j≤n) ys ⟧ (ρ , Ρ) + ⅀?⟦ ys₁ ⟧ (ρ , Ρ)) + x′ * y′≈⟨ ≪+ *≫ (poly-mapR ρ Ρ (⊠-step a z j≤n) (x′ *_) (*-cong refl) reassoc (distribˡ _) step (zeroʳ _) ys ⟨ +-cong ⟩ ys≋zs) ⟩ρ * (x′ * ys′ + xs′ * (ρ * ys′ + y′)) + (x′ * y′)≈⟨ ≪+ distribˡ _ _ _ ⟩ρ * (x′ * ys′) + ρ * (xs′ * (ρ * ys′ + y′)) + (x′ * y′)≈⟨ (≪+ +-comm _ _) ⟨ trans ⟩ +-assoc _ _ _ ⟩ρ * (xs′ * (ρ * ys′ + y′)) + (ρ * (x′ * ys′) + (x′ * y′))≈⟨ sym (*-assoc _ _ _) ⟨ +-cong ⟩ ((≪+ (sym (*-assoc _ _ _) ⟨ trans ⟩ (≪* *-comm _ _) ⟨ trans ⟩ *-assoc _ _ _)) ⟨ trans ⟩ sym (distribˡ _ _ _)) ⟩ρ * xs′ * (ρ * ys′ + y′) + x′ * (ρ * ys′ + y′)≈⟨ sym (distribʳ _ _ _) ⟩(ρ * xs′ + x′) * (ρ * ys′ + y′)∎ }⊠-hom : ∀ {n} (xs ys : Poly n) →∀ ρ → ⟦ xs ⊠ ys ⟧ ρ ≈ ⟦ xs ⟧ ρ * ⟦ ys ⟧ ρ⊠-hom (xs ⊐ i≤n) = ⊠-step-hom (<′-wellFounded _) xs i≤n
-------------------------------------------------------------------------- The Agda standard library---- Lemmas for use in proving the polynomial homomorphism.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Bool.Base using (Bool;true;false)open import Data.Nat.Base as ℕ using (ℕ; suc; zero; compare; _≤′_; ≤′-step; ≤′-refl)open import Data.Nat.Properties as ℕ using (≤′-trans)open import Data.Vec.Base as Vec using (Vec; _∷_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base using (_∷_; [])open import Data.Unit.Base using (tt)open import Data.List.Kleeneopen import Data.Product.Base using (_,_; proj₁; proj₂; map₁; _×_)open import Data.Maybe.Base using (nothing; just)open import Function.Base using (_⟨_⟩_)open import Level using (lift)open import Relation.Nullary.Decidable.Core using (Dec; yes; no)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open Homomorphism homo hiding (_^_)open import Tactic.RingSolver.Core.Polynomial.Reasoning toopen import Tactic.RingSolver.Core.Polynomial.Base fromopen import Tactic.RingSolver.Core.Polynomial.Semantics homoopen import Algebra.Properties.Semiring.Exp.TCOptimised semiring-------------------------------------------------------------------------- Power lemmas---- We prove some things about our odd exponentiation operator-- First, that the optimised operator is the same as normal-- exponentiation.pow-opt : ∀ x ρ i → x *⟨ ρ ⟩^ i ≈ ρ ^ i * xpow-opt x ρ zero = sym (*-identityˡ x)pow-opt x ρ (suc i) = reflpow-add : ∀ x y i j → y ^ (suc j) * x *⟨ y ⟩^ i ≈ x *⟨ y ⟩^ (i ℕ.+ suc j)pow-add x y zero j = reflpow-add x y (suc i) j = go x y i jwherego : ∀ x y i j → (y ^ suc j) * ((y ^ suc i) * x) ≈ y ^ suc (i ℕ.+ suc j) * xgo x y zero j = sym (*-assoc _ _ _)go x y (suc i) j = begin(y ^ suc j) * (y ^ (suc i) * y * x) ≈⟨ *≫ *-assoc _ y x ⟩(y ^ suc j) * (y ^ (suc i) * (y * x)) ≈⟨ go (y * x) y i j ⟩y ^ suc (i ℕ.+ suc j) * (y * x) ≈⟨ sym (*-assoc _ y x) ⟩y ^ suc (suc i ℕ.+ suc j) * x ∎-- Here we show a homomorphism on exponentiation, i.e. that using the-- exponentiation function on polynomials and then evaluating is the-- same as evaluating and then exponentiating.pow-hom : ∀ {n} i→ (xs : Coeff n +)→ ∀ ρ ρs→ ⅀⟦ xs ⟧ (ρ , ρs) *⟨ ρ ⟩^ i ≈ ⅀⟦ xs ⍓+ i ⟧ (ρ , ρs)pow-hom zero (x Δ j & xs) ρ ρs rewrite ℕ.+-identityʳ j = reflpow-hom (suc i) (x ≠0 Δ j & xs) ρ ρs =beginρ ^ (suc i) * (((x , xs) ⟦∷⟧ (ρ , ρs)) *⟨ ρ ⟩^ j)≈⟨ pow-add _ ρ j i ⟩(((x , xs) ⟦∷⟧ (ρ , ρs)) *⟨ ρ ⟩^ (j ℕ.+ suc i))∎-- Proving a congruence (we don't get this for free because we're using-- setoids).pow-mul-cong : ∀ {x y} → x ≈ y → ∀ ρ i → x *⟨ ρ ⟩^ i ≈ y *⟨ ρ ⟩^ ipow-mul-cong x≈y ρ zero = x≈ypow-mul-cong x≈y ρ (suc i) = *≫ x≈y-- Demonstrating that the proof of zeroness is correct.zero-hom : ∀ {n} (p : Poly n) → Zero p → (ρs : Vec Carrier n) → 0# ≈ ⟦ p ⟧ ρszero-hom (Κ x ⊐ i≤n) p≡0 ρs = Zero-C⟶Zero-R x p≡0-- x¹⁺ⁿ = xxⁿpow-suc : ∀ x i → x ^ suc i ≈ x * x ^ ipow-suc x zero = sym (*-identityʳ _)pow-suc x (suc i) = *-comm _ _-- x¹⁺ⁿ = xⁿxpow-sucʳ : ∀ x i → x ^ suc i ≈ x ^ i * xpow-sucʳ x zero = sym (*-identityˡ _)pow-sucʳ x (suc i) = refl-- In the proper evaluation function, we avoid ever inserting an-- unnecessary 0# like we do here. However, it is easier to prove with-- the form that does insert 0#. So we write one here, and then prove-- that it's equivalent to the one that adds a 0#.⅀?⟦_⟧ : ∀ {n} (xs : Coeff n *) → Carrier × Vec Carrier n → Carrier⅀?⟦ [] ⟧ _ = 0#⅀?⟦ ∹ x ⟧ = ⅀⟦ x ⟧_⟦∷⟧?_ : ∀ {n} (x : Poly n × Coeff n *) → Carrier × Vec Carrier n → Carrier(x , xs) ⟦∷⟧? (ρ , ρs) = ρ * ⅀?⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs⅀?-hom : ∀ {n} (xs : Coeff n +) → ∀ ρ → ⅀?⟦ ∹ xs ⟧ ρ ≈ ⅀⟦ xs ⟧ ρ⅀?-hom _ _ = refl⟦∷⟧?-hom : ∀ {n} (x : Poly n) → ∀ xs ρ ρs → (x , xs) ⟦∷⟧? (ρ , ρs) ≈ (x , xs) ⟦∷⟧ (ρ , ρs)⟦∷⟧?-hom x (∹ xs ) ρ ρs = refl⟦∷⟧?-hom x [] ρ ρs = (≪+ zeroʳ _) ⟨ trans ⟩ +-identityˡ _pow′-hom : ∀ {n} i (xs : Coeff n *) → ∀ ρ ρs → ((⅀?⟦ xs ⟧ (ρ , ρs)) *⟨ ρ ⟩^ i) ≈ (⅀?⟦ xs ⍓* i ⟧ (ρ , ρs))pow′-hom i (∹ xs ) ρ ρs = pow-hom i xs ρ ρspow′-hom zero [] ρ ρs = reflpow′-hom (suc i) [] ρ ρs = zeroʳ _-- Here, we show that the normalising cons is correct.-- This lets us prove with respect to the non-normalising form,-- especially when we're using the folds.∷↓-hom-0 : ∀ {n} (x : Poly n) → ∀ xs ρ ρs → ⅀?⟦ x Δ 0 ∷↓ xs ⟧ (ρ , ρs) ≈ (x , xs) ⟦∷⟧ (ρ , ρs)∷↓-hom-0 x xs ρ ρs with zero? x∷↓-hom-0 x xs ρ ρs | no ¬p = refl∷↓-hom-0 x [] ρ ρs | yes p = zero-hom x p ρs∷↓-hom-0 x (∹ xs ) ρ ρs | yes p =begin⅀⟦ xs ⍓+ 1 ⟧ (ρ , ρs)≈⟨ sym (pow-hom 1 xs ρ ρs) ⟩ρ * ⅀⟦ xs ⟧ (ρ , ρs)≈⟨ sym (+-identityʳ _) ⟨ trans ⟩ (+≫ zero-hom x p ρs) ⟩ρ * ⅀⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs∎∷↓-hom-s : ∀ {n} (x : Poly n) → ∀ i xs ρ ρs → ⅀?⟦ x Δ suc i ∷↓ xs ⟧ (ρ , ρs) ≈ (ρ ^ suc i) * (x , xs) ⟦∷⟧ (ρ , ρs)∷↓-hom-s x i xs ρ ρs with zero? x∷↓-hom-s x i xs ρ ρs | no ¬p = refl∷↓-hom-s x i [] ρ ρs | yes p = sym ((*≫ sym (zero-hom x p ρs)) ⟨ trans ⟩ zeroʳ _)∷↓-hom-s x i (∹ xs ) ρ ρs | yes p =begin⅀⟦ xs ⍓+ (suc (suc i)) ⟧ (ρ , ρs)≈⟨ sym (pow-hom (suc (suc i)) xs ρ ρs) ⟩(ρ ^ suc (suc i)) * ⅀⟦ xs ⟧ (ρ , ρs)≈⟨ *-assoc _ _ _ ⟩(ρ ^ suc i) * (ρ * ⅀⟦ xs ⟧ (ρ , ρs))≈⟨ *≫ (sym (+-identityʳ _) ⟨ trans ⟩ (+≫ zero-hom x p ρs)) ⟩(ρ ^ suc i) * (ρ * ⅀⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs)∎∷↓-hom : ∀ {n}→ (x : Poly n)→ ∀ i xs ρ ρs→ ⅀?⟦ x Δ i ∷↓ xs ⟧ (ρ , ρs) ≈ ρ ^ i * ((x , xs) ⟦∷⟧ (ρ , ρs))∷↓-hom x zero xs ρ ρs = ∷↓-hom-0 x xs ρ ρs ⟨ trans ⟩ sym (*-identityˡ _)∷↓-hom x (suc i) xs ρ ρs = ∷↓-hom-s x i xs ρ ρs⟦∷⟧-hom : ∀ {n}→ (x : Poly n)→ (xs : Coeff n *)→ ∀ ρ ρs → (x , xs) ⟦∷⟧ (ρ , ρs) ≈ ρ * ⅀?⟦ xs ⟧ (ρ , ρs) + ⟦ x ⟧ ρs⟦∷⟧-hom x [] ρ ρs = sym ((≪+ zeroʳ _) ⟨ trans ⟩ +-identityˡ _)⟦∷⟧-hom x (∹ xs) ρ ρs = refl-- This proves that injecting a polynomial into more variables is-- correct. Basically, we show that if a polynomial doesn't care about-- the first few variables, we can drop them from the input vector.⅀-⊐↑-hom : ∀ {i n m}→ (xs : Coeff i +)→ (si≤n : suc i ≤′ n)→ (sn≤m : suc n ≤′ m)→ ∀ ρ→ ⅀⟦ xs ⟧ (drop-1 (≤′-step si≤n ⟨ ≤′-trans ⟩ sn≤m) ρ)≈ ⅀⟦ xs ⟧ (drop-1 si≤n (proj₂ (drop-1 sn≤m ρ)))⅀-⊐↑-hom xs si≤n ≤′-refl (_ ∷ _) = refl⅀-⊐↑-hom xs si≤n (≤′-step sn≤m) (_ ∷ ρ) = ⅀-⊐↑-hom xs si≤n sn≤m ρ⊐↑-hom : ∀ {n m}→ (x : Poly n)→ (sn≤m : suc n ≤′ m)→ ∀ ρ→ ⟦ x ⊐↑ sn≤m ⟧ ρ ≈ ⟦ x ⟧ (proj₂ (drop-1 sn≤m ρ))⊐↑-hom (Κ x ⊐ i≤sn) _ _ = refl⊐↑-hom (⅀ xs ⊐ i≤sn) = ⅀-⊐↑-hom xs i≤sntrans-join-coeffs-hom : ∀ {i j-1 n}→ (i≤j-1 : suc i ≤′ j-1)→ (j≤n : suc j-1 ≤′ n)→ (xs : Coeff i +)→ ∀ ρ→ ⅀⟦ xs ⟧ (drop-1 i≤j-1 (proj₂ (drop-1 j≤n ρ))) ≈ ⅀⟦ xs ⟧ (drop-1 (≤′-step i≤j-1 ⟨ ≤′-trans ⟩ j≤n) ρ)trans-join-coeffs-hom i<j-1 ≤′-refl xs (_ ∷ _) = refltrans-join-coeffs-hom i<j-1 (≤′-step j<n) xs (_ ∷ ρ) = trans-join-coeffs-hom i<j-1 j<n xs ρtrans-join-hom : ∀ {i j-1 n}→ (i≤j-1 : i ≤′ j-1)→ (j≤n : suc j-1 ≤′ n)→ (x : FlatPoly i)→ ∀ ρ→ ⟦ x ⊐ i≤j-1 ⟧ (proj₂ (drop-1 j≤n ρ)) ≈ ⟦ x ⊐ (≤′-step i≤j-1 ⟨ ≤′-trans ⟩ j≤n) ⟧ ρtrans-join-hom i≤j-1 j≤n (Κ x) _ = refltrans-join-hom i≤j-1 j≤n (⅀ x) = trans-join-coeffs-hom i≤j-1 j≤n x⊐↓-hom : ∀ {n m}→ (xs : Coeff n *)→ (sn≤m : suc n ≤′ m)→ ∀ ρ→ ⟦ xs ⊐↓ sn≤m ⟧ ρ ≈ ⅀?⟦ xs ⟧ (drop-1 sn≤m ρ)⊐↓-hom [] sn≤m _ = 0-homo⊐↓-hom (∹ x₁ Δ zero & ∹ xs) sn≤m _ = refl⊐↓-hom (∹ x Δ suc j & xs ) sn≤m _ = refl⊐↓-hom (∹ _≠0 x {x≠0} Δ zero & []) sn≤m ρs =let (ρ , ρs′) = drop-1 sn≤m ρsinbegin⟦ x ⊐↑ sn≤m ⟧ ρs≈⟨ ⊐↑-hom x sn≤m ρs ⟩⟦ x ⟧ ρs′∎drop-1⇒lookup : ∀ {n} (i : Fin n) (ρs : Vec Carrier n) →proj₁ (drop-1 (space≤′n i) ρs) ≡ Vec.lookup ρs idrop-1⇒lookup zero (ρ ∷ ρs) = ≡.refldrop-1⇒lookup (suc i) (ρ ∷ ρs) = drop-1⇒lookup i ρs-- The fold: this function saves us hundreds of lines of proofs in the-- rest of the homomorphism proof.-- Many of the functions on polynomials are defined using para: this-- function allows us to prove properties of those functions (in a-- foldr-fusion style) *ignoring* optimisations we have made to the-- polynomial structure.poly-foldR : ∀ {n} ρ ρs→ ([f] : Fold n)→ (f : Carrier → Carrier)→ (∀ {x y} → x ≈ y → f x ≈ f y)→ (∀ x y → x * f y ≈ f (x * y))→ (∀ y {ys} zs → ⅀?⟦ ys ⟧ (ρ , ρs) ≈ f (⅀?⟦ zs ⟧ (ρ , ρs)) → [f] (y , ys) ⟦∷⟧? (ρ , ρs) ≈ f ((y , zs) ⟦∷⟧? (ρ , ρs)) )→ (f 0# ≈ 0#)→ ∀ xs→ ⅀?⟦ para [f] xs ⟧ (ρ , ρs) ≈ f (⅀⟦ xs ⟧ (ρ , ρs))poly-foldR ρ ρs f e cng dist step base (x ≠0 Δ suc i & []) =let y,ys = f (x , [])y = proj₁ y,ysys = proj₂ y,ysinbegin⅀?⟦ y Δ suc i ∷↓ ys ⟧ (ρ , ρs)≈⟨ ∷↓-hom-s y i ys ρ ρs ⟩(ρ ^ suc i) * ((y , ys) ⟦∷⟧ (ρ , ρs))≈⟨ *≫ ⟦∷⟧?-hom y ys ρ ρs ⟨(ρ ^ suc i) * ((y , ys) ⟦∷⟧? (ρ , ρs))≈⟨ *≫ step x [] (sym base) ⟩(ρ ^ suc i) * e ((x , []) ⟦∷⟧? (ρ , ρs))≈⟨ *≫ cng (⟦∷⟧?-hom x [] ρ ρs) ⟩(ρ ^ suc i) * e ((x , []) ⟦∷⟧ (ρ , ρs))≈⟨ dist _ _ ⟩e ((ρ ^ suc i) * ((x , []) ⟦∷⟧ (ρ , ρs)))∎poly-foldR ρ ρs f e cng dist step base (x ≠0 Δ suc i & ∹ xs) =let ys = para f xsy,zs = f (x , ys)y = proj₁ y,zszs = proj₂ y,zsinbegin⅀?⟦ y Δ suc i ∷↓ zs ⟧ (ρ , ρs)≈⟨ ∷↓-hom-s y i zs ρ ρs ⟩(ρ ^ suc i) * ((y , zs) ⟦∷⟧ (ρ , ρs))≈⟨ *≫ ⟦∷⟧?-hom y zs ρ ρs ⟨(ρ ^ suc i) * ((y , zs) ⟦∷⟧? (ρ , ρs))≈⟨ *≫ step x (∹ xs) (poly-foldR ρ ρs f e cng dist step base xs) ⟩(ρ ^ suc i) * e ((x , (∹ xs )) ⟦∷⟧? (ρ , ρs))≈⟨ *≫ cng (⟦∷⟧?-hom x (∹ xs ) ρ ρs) ⟩(ρ ^ suc i) * e ((x , (∹ xs )) ⟦∷⟧ (ρ , ρs))≈⟨ dist _ _ ⟩e (ρ ^ suc i * ((x , (∹ xs )) ⟦∷⟧ (ρ , ρs)))∎poly-foldR ρ ρs f e cng dist step base (x ≠0 Δ ℕ.zero & []) =let y,zs = f (x , [])y = proj₁ y,zszs = proj₂ y,zsinbegin⅀?⟦ y Δ ℕ.zero ∷↓ zs ⟧ (ρ , ρs)≈⟨ ∷↓-hom-0 y zs ρ ρs ⟩((y , zs) ⟦∷⟧ (ρ , ρs))≈⟨ ⟦∷⟧?-hom y zs ρ ρs ⟨((y , zs) ⟦∷⟧? (ρ , ρs))≈⟨ step x [] (sym base) ⟩e ((x , []) ⟦∷⟧? (ρ , ρs))≈⟨ cng (⟦∷⟧?-hom x [] ρ ρs) ⟩e ((x , []) ⟦∷⟧ (ρ , ρs))∎poly-foldR ρ ρs f e cng dist step base (x ≠0 Δ ℕ.zero & (∹ xs )) =let ys = para f xsy,zs = f (x , ys)y = proj₁ y,zszs = proj₂ y,zsinbegin⅀?⟦ y Δ ℕ.zero ∷↓ zs ⟧ (ρ , ρs)≈⟨ ∷↓-hom-0 y zs ρ ρs ⟩((y , zs) ⟦∷⟧ (ρ , ρs))≈⟨ ⟦∷⟧?-hom y zs ρ ρs ⟨((y , zs) ⟦∷⟧? (ρ , ρs))≈⟨ step x (∹ xs ) (poly-foldR ρ ρs f e cng dist step base xs) ⟩e ((x , (∹ xs )) ⟦∷⟧ (ρ , ρs))≈⟨ cng (⟦∷⟧?-hom x (∹ xs ) ρ ρs) ⟩e ((x , (∹ xs )) ⟦∷⟧ (ρ , ρs))∎poly-mapR : ∀ {n} ρ ρs→ ([f] : Poly n → Poly n)→ (f : Carrier → Carrier)→ (∀ {x y} → x ≈ y → f x ≈ f y)→ (∀ x y → x * f y ≈ f (x * y))→ (∀ x y → f (x + y) ≈ f x + f y)→ (∀ y → ⟦ [f] y ⟧ ρs ≈ f (⟦ y ⟧ ρs) )→ (f 0# ≈ 0#)→ ∀ xs→ ⅀?⟦ poly-map [f] xs ⟧ (ρ , ρs) ≈ f (⅀⟦ xs ⟧ (ρ , ρs))poly-mapR ρ ρs [f] f cng *-dist +-dist step′ base xs = poly-foldR ρ ρs (map₁ [f]) f cng *-dist step base xswherestep : ∀ y {ys} zs → ⅀?⟦ ys ⟧ (ρ , ρs) ≈ f (⅀?⟦ zs ⟧ (ρ , ρs)) →(map₁ [f] (y , ys) ⟦∷⟧? (ρ , ρs)) ≈ f ((y , zs) ⟦∷⟧? (ρ , ρs))step y {ys} zs ys≋zs =beginmap₁ [f] (y , ys) ⟦∷⟧? (ρ , ρs)≡⟨⟩ρ * ⅀?⟦ ys ⟧ (ρ , ρs) + ⟦ [f] y ⟧ ρs≈⟨ ((*≫ ys≋zs) ⟨ trans ⟩ *-dist ρ _) ⟨ +-cong ⟩ step′ y ⟩f (ρ * ⅀?⟦ zs ⟧ (ρ , ρs)) + f (⟦ y ⟧ ρs)≈⟨ sym (+-dist _ _) ⟩f ((y , zs) ⟦∷⟧? (ρ , ρs))∎
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for exponentiation over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Exponentiation{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Function.Base using (_⟨_⟩_)open import Data.Nat.Base as ℕ using (ℕ; suc; zero; compare)open import Data.Product.Base using (_,_; _×_; proj₁; proj₂)open import Data.List.Kleeneopen import Data.Vec.Base using (Vec)import Data.Nat.Properties as ℕimport Relation.Binary.PropositionalEquality.Core as ≡open Homomorphism homoopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas homoopen import Tactic.RingSolver.Core.Polynomial.Base fromopen import Tactic.RingSolver.Core.Polynomial.Reasoning toopen import Tactic.RingSolver.Core.Polynomial.Homomorphism.Multiplication homoopen import Tactic.RingSolver.Core.Polynomial.Semantics homoimport Algebra.Properties.CommutativeSemiring.Exp.TCOptimised commutativeSemiring as RawPowimport Algebra.Definitions.RawSemiring (RawCoeff.rawSemiring from) as CoPowpow-eval-hom : ∀ x i → ⟦ x CoPow.^′ suc i ⟧ᵣ ≈ ⟦ x ⟧ᵣ RawPow.^ suc ipow-eval-hom x zero = reflpow-eval-hom x (suc i) = (*-homo _ x) ⟨ trans ⟩ (≪* pow-eval-hom x i)⊡-mult-hom : ∀ {n} i (xs : Poly n) ρ → ⟦ ⊡-mult i xs ⟧ ρ ≈ ⟦ xs ⟧ ρ RawPow.^ suc i⊡-mult-hom zero xs ρ = refl⊡-mult-hom (suc i) xs ρ = ⊠-hom (⊡-mult i xs) xs ρ ⟨ trans ⟩ (≪* ⊡-mult-hom i xs ρ)⊡-+1-hom : ∀ {n} → (xs : Poly n) → (i : ℕ) → ∀ ρ → ⟦ xs ⊡ i +1 ⟧ ρ ≈ ⟦ xs ⟧ ρ RawPow.^ suc i⊡-+1-hom (Κ x ⊐ i≤n) i ρ = pow-eval-hom x i⊡-+1-hom xs@(⅀ (_ & ∹ _) ⊐ i≤n) i ρ = ⊡-mult-hom i xs ρ⊡-+1-hom (⅀ (x ≠0 Δ j & []) ⊐ i≤n) i ρ =begin⟦ x ⊡ i +1 Δ (j ℕ.+ i ℕ.* j) ∷↓ [] ⊐↓ i≤n ⟧ ρ≈⟨ ⊐↓-hom (x ⊡ i +1 Δ (j ℕ.+ i ℕ.* j) ∷↓ []) i≤n ρ ⟩⅀?⟦ x ⊡ i +1 Δ (j ℕ.+ i ℕ.* j) ∷↓ [] ⟧ (drop-1 i≤n ρ)≈⟨ ∷↓-hom (x ⊡ i +1) (j ℕ.+ i ℕ.* j) [] ρ′ Ρ ⟩(ρ′ RawPow.^ (j ℕ.+ i ℕ.* j)) * (⟦ x ⊡ i +1 ⟧ Ρ)≈⟨ *≫ (( ⊡-+1-hom x i Ρ) ) ⟩(ρ′ RawPow.^ (j ℕ.+ i ℕ.* j)) * (⟦ x ⟧ Ρ RawPow.^ suc i)≈⟨ rearrange j ⟩(( ⟦ x ⟧ Ρ) *⟨ ρ′ ⟩^ j) RawPow.^ suc i∎whereρ′,Ρ = drop-1 i≤n ρρ′ = proj₁ ρ′,ΡΡ = proj₂ ρ′,Ρrearrange : ∀ j → (ρ′ RawPow.^ (j ℕ.+ i ℕ.* j)) * (⟦ x ⟧ Ρ RawPow.^ suc i)≈ (( ⟦ x ⟧ Ρ) *⟨ ρ′ ⟩^ j) RawPow.^ suc irearrange zero =begin(ρ′ RawPow.^ (i ℕ.* 0)) * (⟦ x ⟧ Ρ RawPow.^ suc i)≡⟨ ≡.cong (λ k → (ρ′ RawPow.^ k) * (⟦ x ⟧ Ρ RawPow.^ suc i)) (ℕ.*-zeroʳ i) ⟩1# * (⟦ x ⟧ Ρ RawPow.^ suc i)≈⟨ *-identityˡ _ ⟩⟦ x ⟧ Ρ RawPow.^ suc i∎rearrange j@(suc j′) =begin(ρ′ RawPow.^ (suc i ℕ.* j)) * (⟦ x ⟧ Ρ RawPow.^ suc i)≡⟨ ≡.cong (λ v → (ρ′ RawPow.^ v) * (⟦ x ⟧ Ρ RawPow.^ suc i)) (ℕ.*-comm (suc i) j) ⟩(ρ′ RawPow.^ (j ℕ.* suc i)) * (⟦ x ⟧ Ρ RawPow.^ suc i)≈⟨ ≪* sym (RawPow.^-assocʳ ρ′ j (suc i)) ⟩((ρ′ RawPow.^ suc j′) RawPow.^ suc i) * (⟦ x ⟧ Ρ RawPow.^ suc i)≈⟨ sym (RawPow.^-distrib-* _ (⟦ x ⟧ Ρ) (suc i)) ⟩((ρ′ RawPow.^ suc j′) * ⟦ x ⟧ Ρ) RawPow.^ suc i∎⊡-hom : ∀ {n} → (xs : Poly n) → (i : ℕ) → ∀ ρ → ⟦ xs ⊡ i ⟧ ρ ≈ ⟦ xs ⟧ ρ RawPow.^ i⊡-hom xs 0 ρ = 1-homo⊡-hom xs (suc i) ρ = ⊡-+1-hom xs i ρ
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for constants over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Constants{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen Homomorphism homoopen import Data.Vec.Base using (Vec)open import Tactic.RingSolver.Core.Polynomial.Base (Homomorphism.from homo)open import Tactic.RingSolver.Core.Polynomial.Semantics homoκ-hom : ∀ {n} (x : Raw.Carrier) (Ρ : Vec Carrier n) → ⟦ κ x ⟧ Ρ ≈ ⟦ x ⟧ᵣκ-hom x _ = refl
-------------------------------------------------------------------------- The Agda standard library---- Homomorphism proofs for addition over polynomials------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Homomorphism.Addition{r₁ r₂ r₃ r₄}(homo : Homomorphism r₁ r₂ r₃ r₄)whereopen import Data.Nat.Base as ℕ using (ℕ; suc; zero; compare; _≤′_; ≤′-step; ≤′-refl)open import Data.Nat.Properties as ℕ using (≤′-trans)open import Data.Product.Base using (_,_; _×_; proj₂)open import Data.List.Base using (_∷_; [])open import Data.List.Kleeneopen import Data.Vec.Base using (Vec)open import Function.Base using (_⟨_⟩_; flip)open import Relation.Unaryimport Relation.Binary.PropositionalEquality.Core as ≡open Homomorphism homo hiding (_^_)open import Tactic.RingSolver.Core.Polynomial.Homomorphism.Lemmas homoopen import Tactic.RingSolver.Core.Polynomial.Base fromopen import Tactic.RingSolver.Core.Polynomial.Reasoning toopen import Tactic.RingSolver.Core.Polynomial.Semantics homoopen import Algebra.Properties.Semiring.Exp.TCOptimised semiringmutual⊞-hom : ∀ {n} (xs ys : Poly n) →∀ ρ → ⟦ xs ⊞ ys ⟧ ρ ≈ ⟦ xs ⟧ ρ + ⟦ ys ⟧ ρ⊞-hom (xs ⊐ i≤n) (ys ⊐ j≤n) = ⊞-match-hom (inj-compare i≤n j≤n) xs ys⊞-match-hom : ∀ {i j n} {i≤n : i ≤′ n} {j≤n : j ≤′ n}(i-cmp-j : InjectionOrdering i≤n j≤n)(xs : FlatPoly i) (ys : FlatPoly j) →∀ ρ → ⟦ ⊞-match i-cmp-j xs ys ⟧ ρ ≈ ⟦ xs ⊐ i≤n ⟧ ρ + ⟦ ys ⊐ j≤n ⟧ ρ⊞-match-hom (inj-eq ij≤n) (Κ x) (Κ y) Ρ = +-homo x y⊞-match-hom (inj-eq ij≤n) (⅀ (x Δ i & xs)) (⅀ (y Δ j & ys)) Ρ =begin⟦ ⊞-zip (compare i j) x xs y ys ⊐↓ ij≤n ⟧ Ρ≈⟨ ⊐↓-hom (⊞-zip (compare i j) x xs y ys) ij≤n Ρ ⟩⅀?⟦ ⊞-zip (compare i j) x xs y ys ⟧ (drop-1 ij≤n Ρ)≈⟨ ⊞-zip-hom (compare i j) x xs y ys (drop-1 ij≤n Ρ) ⟩⅀⟦ x Δ i & xs ⟧ (drop-1 ij≤n Ρ) + ⅀⟦ y Δ j & ys ⟧ (drop-1 ij≤n Ρ)∎⊞-match-hom (inj-gt i≤n j≤i-1) (⅀ xs) ys Ρ =let (ρ , Ρ′) = drop-1 i≤n Ρinbegin⟦ ⊞-inj j≤i-1 ys xs ⊐↓ i≤n ⟧ Ρ≈⟨ ⊐↓-hom (⊞-inj j≤i-1 ys xs) i≤n Ρ ⟩⅀?⟦ ⊞-inj j≤i-1 ys xs ⟧ (drop-1 i≤n Ρ)≈⟨ ⊞-inj-hom j≤i-1 ys xs ρ Ρ′ ⟩⟦ ys ⊐ j≤i-1 ⟧ (proj₂ (drop-1 i≤n Ρ)) + ⅀⟦ xs ⟧ (drop-1 i≤n Ρ)≈⟨ ≪+ trans-join-hom j≤i-1 i≤n ys Ρ ⟩⟦ ys ⊐ (≤′-step j≤i-1 ⟨ ≤′-trans ⟩ i≤n) ⟧ Ρ + ⅀⟦ xs ⟧ (drop-1 i≤n Ρ)≈⟨ +-comm _ _ ⟩⅀⟦ xs ⟧ (drop-1 i≤n Ρ) + ⟦ ys ⊐ (≤′-step j≤i-1 ⟨ ≤′-trans ⟩ i≤n) ⟧ Ρ∎⊞-match-hom (inj-lt i≤j-1 j≤n) xs (⅀ ys) Ρ =let (ρ , Ρ′) = drop-1 j≤n Ρinbegin⟦ ⊞-inj i≤j-1 xs ys ⊐↓ j≤n ⟧ Ρ≈⟨ ⊐↓-hom (⊞-inj i≤j-1 xs ys) j≤n Ρ ⟩⅀?⟦ ⊞-inj i≤j-1 xs ys ⟧ (drop-1 j≤n Ρ)≈⟨ ⊞-inj-hom i≤j-1 xs ys ρ Ρ′ ⟩⟦ xs ⊐ i≤j-1 ⟧ (proj₂ (drop-1 j≤n Ρ)) + ⅀⟦ ys ⟧ (drop-1 j≤n Ρ)≈⟨ ≪+ trans-join-hom i≤j-1 j≤n xs Ρ ⟩⟦ xs ⊐ (≤′-step i≤j-1 ⟨ ≤′-trans ⟩ j≤n) ⟧ Ρ + ⅀⟦ ys ⟧ (drop-1 j≤n Ρ)∎⊞-inj-hom : ∀ {i k}→ (i≤k : i ≤′ k)→ (x : FlatPoly i)→ (ys : Coeff k +)→ (ρ : Carrier)→ (Ρ : Vec Carrier k)→ ⅀?⟦ ⊞-inj i≤k x ys ⟧ (ρ , Ρ) ≈ ⟦ x ⊐ i≤k ⟧ Ρ + ⅀⟦ ys ⟧ (ρ , Ρ)⊞-inj-hom i≤k xs (y ⊐ j≤k ≠0 Δ 0 & []) ρ Ρ =begin⅀?⟦ ⊞-match (inj-compare j≤k i≤k) y xs Δ 0 ∷↓ [] ⟧ (ρ , Ρ)≈⟨ ∷↓-hom-0 ((⊞-match (inj-compare j≤k i≤k) y xs)) [] ρ Ρ ⟩⟦ ⊞-match (inj-compare j≤k i≤k) y xs ⟧ Ρ≈⟨ ⊞-match-hom (inj-compare j≤k i≤k) y xs Ρ ⟩(⟦ y ⊐ j≤k ⟧ Ρ + ⟦ xs ⊐ i≤k ⟧ Ρ)≈⟨ +-comm _ _ ⟩⟦ xs ⊐ i≤k ⟧ Ρ + ( ⟦ y ⊐ j≤k ⟧ Ρ)∎⊞-inj-hom i≤k xs (y ⊐ j≤k ≠0 Δ 0 & (∹ ys )) ρ Ρ =begin⅀?⟦ ⊞-match (inj-compare j≤k i≤k) y xs Δ 0 ∷↓ (∹ ys ) ⟧ (ρ , Ρ)≈⟨ ∷↓-hom-0 ((⊞-match (inj-compare j≤k i≤k) y xs)) (∹ ys ) ρ Ρ ⟩ρ * ⅀⟦ ys ⟧ (ρ , Ρ) + ⟦ ⊞-match (inj-compare j≤k i≤k) y xs ⟧ Ρ≈⟨ +≫ ⊞-match-hom (inj-compare j≤k i≤k) y xs Ρ ⟩ρ * ⅀⟦ ys ⟧ (ρ , Ρ) + (⟦ y ⊐ j≤k ⟧ Ρ + ⟦ xs ⊐ i≤k ⟧ Ρ)≈⟨ sym (+-assoc _ _ _) ⟨ trans ⟩ +-comm _ _ ⟩⟦ xs ⊐ i≤k ⟧ Ρ + (ρ * ⅀⟦ ys ⟧ (ρ , Ρ) + ⟦ y ⊐ j≤k ⟧ Ρ)∎⊞-inj-hom i≤k xs (y Δ suc j & ys) ρ Ρ =begin⅀?⟦ ⊞-inj i≤k xs (y Δ suc j & ys) ⟧ (ρ , Ρ)≡⟨⟩⅀?⟦ xs ⊐ i≤k Δ 0 ∷↓ (∹ y Δ j & ys ) ⟧ (ρ , Ρ)≈⟨ ∷↓-hom-0 (xs ⊐ i≤k) (∹ y Δ j & ys ) ρ Ρ ⟩ρ * ⅀⟦ y Δ j & ys ⟧ (ρ , Ρ) + ⟦ xs ⊐ i≤k ⟧ Ρ≈⟨ +-comm _ _ ⟩⟦ xs ⊐ i≤k ⟧ Ρ + ρ * ⅀⟦ y Δ j & ys ⟧ (ρ , Ρ)≈⟨ +≫ (beginρ * ⅀⟦ y Δ j & ys ⟧ (ρ , Ρ)≡⟨⟩ρ * (((poly y , ys) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ j)≈⟨ *≫ pow-opt _ ρ j ⟩ρ * (ρ ^ j * ((poly y , ys) ⟦∷⟧ (ρ , Ρ)))≈⟨ sym (*-assoc ρ _ _) ⟩ρ * ρ ^ j * ((poly y , ys) ⟦∷⟧ (ρ , Ρ))≈⟨ ≪* sym (pow-suc ρ j) ⟩⅀⟦ y Δ suc j & ys ⟧ (ρ , Ρ)∎) ⟩⟦ xs ⊐ i≤k ⟧ Ρ + ⅀⟦ y Δ suc j & ys ⟧ (ρ , Ρ)∎⊞-coeffs-hom : ∀ {n} (xs : Coeff n *) (ys : Coeff n *) →∀ ρ → ⅀?⟦ ⊞-coeffs xs ys ⟧ ρ ≈ ⅀?⟦ xs ⟧ ρ + ⅀?⟦ ys ⟧ ρ⊞-coeffs-hom [] ys Ρ = sym (+-identityˡ (⅀?⟦ ys ⟧ Ρ))⊞-coeffs-hom (∹ x Δ i & xs ) = ⊞-zip-r-hom i x xs⊞-zip-hom : ∀ {n i j}→ (c : ℕ.Ordering i j)→ (x : NonZero n)→ (xs : Coeff n *)→ (y : NonZero n)→ (ys : Coeff n *)→ ∀ ρ → ⅀?⟦ ⊞-zip c x xs y ys ⟧ ρ ≈ ⅀⟦ x Δ i & xs ⟧ ρ + ⅀⟦ y Δ j & ys ⟧ ρ⊞-zip-hom (ℕ.equal i) (x ≠0) xs (y ≠0) ys (ρ , Ρ) =let x′ = ⟦ x ⟧ Ρy′ = ⟦ y ⟧ Ρxs′ = ⅀?⟦ xs ⟧ (ρ , Ρ)ys′ = ⅀?⟦ ys ⟧ (ρ , Ρ)inbegin⅀?⟦ x ⊞ y Δ i ∷↓ ⊞-coeffs xs ys ⟧ (ρ , Ρ)≈⟨ ∷↓-hom (x ⊞ y) i (⊞-coeffs xs ys) ρ Ρ ⟩ρ ^ i * (((x ⊞ y) , (⊞-coeffs xs ys)) ⟦∷⟧ (ρ , Ρ))≈⟨ *≫ ⟦∷⟧-hom (x ⊞ y) (⊞-coeffs xs ys) ρ Ρ ⟩ρ ^ i * (ρ * ⅀?⟦ ⊞-coeffs xs ys ⟧ (ρ , Ρ) + ⟦ x ⊞ y ⟧ Ρ)≈⟨ *≫ beginρ * ⅀?⟦ ⊞-coeffs xs ys ⟧ (ρ , Ρ) + ⟦ x ⊞ y ⟧ Ρ≈⟨ (*≫ ⊞-coeffs-hom xs ys (ρ , Ρ)) ⟨ +-cong ⟩ ⊞-hom x y Ρ ⟩ρ * (xs′ + ys′) + (x′ + y′)≈⟨ ≪+ distribˡ ρ xs′ ys′ ⟩ρ * xs′ + ρ * ys′ + (x′ + y′)≈⟨ +-assoc _ _ _ ⟨ trans ⟩ (+≫ (sym (+-assoc _ _ _) ⟨ trans ⟩ (≪+ +-comm _ _))) ⟩ρ * xs′ + (x′ + ρ * ys′ + y′)≈⟨ (+≫ +-assoc _ _ _) ⟨ trans ⟩ sym (+-assoc _ _ _) ⟩(ρ * xs′ + x′) + (ρ * ys′ + y′)∎ ⟩ρ ^ i * ((ρ * xs′ + x′) + (ρ * ys′ + y′))≈⟨ distribˡ (ρ ^ i) _ _ ⟩ρ ^ i * (ρ * xs′ + x′) + ρ ^ i * (ρ * ys′ + y′)≈⟨ sym (pow-opt _ ρ i ⟨ +-cong ⟩ pow-opt _ ρ i) ⟩(ρ * xs′ + x′) *⟨ ρ ⟩^ i + (ρ * ys′ + y′) *⟨ ρ ⟩^ i≈⟨ pow-mul-cong (sym (⟦∷⟧-hom x xs ρ Ρ)) ρ i ⟨ +-cong ⟩ pow-mul-cong (sym (⟦∷⟧-hom y ys ρ Ρ)) ρ i ⟩((x , xs) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ i + ((y , ys) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ i∎⊞-zip-hom (ℕ.less i k) x xs y ys (ρ , Ρ) = ⊞-zip-r-step-hom i k y ys x xs (ρ , Ρ) ⊙ +-comm _ _⊞-zip-hom (ℕ.greater j k) = ⊞-zip-r-step-hom j k⊞-zip-r-step-hom : ∀ {n} j k→ (x : NonZero n)→ (xs : Coeff n *)→ (y : NonZero n)→ (ys : Coeff n *)→ ∀ ρ → ⅀⟦ y Δ j & ⊞-zip-r x k xs ys ⟧ ρ ≈ ⅀⟦ x Δ suc (j ℕ.+ k) & xs ⟧ ρ + ⅀⟦ y Δ j & ys ⟧ ρ⊞-zip-r-step-hom j k x xs y ys (ρ , Ρ) =let x′ = ⟦ NonZero.poly x ⟧ Ρy′ = ⟦ NonZero.poly y ⟧ Ρxs′ = ⅀?⟦ xs ⟧ (ρ , Ρ)ys′ = ⅀?⟦ ys ⟧ (ρ , Ρ)inbegin((poly y , ⊞-zip-r x k xs ys) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ j≈⟨ pow-mul-cong (⟦∷⟧-hom (poly y) (⊞-zip-r x k xs ys) ρ Ρ) ρ j ⟩(ρ * ⅀?⟦ ⊞-zip-r x k xs ys ⟧ (ρ , Ρ) + y′) *⟨ ρ ⟩^ j≈⟨ pow-opt _ ρ j ⟩ρ ^ j * (ρ * ⅀?⟦ ⊞-zip-r x k xs ys ⟧ (ρ , Ρ) + y′)≈⟨ *≫ ≪+ *≫ (⊞-zip-r-hom k x xs ys (ρ , Ρ) ⟨ trans ⟩ (≪+ pow-mul-cong (⟦∷⟧-hom (poly x) xs ρ Ρ) ρ k)) ⟩ρ ^ j * (ρ * ((ρ * xs′ + x′) *⟨ ρ ⟩^ k + ys′) + y′)≈⟨ *≫ ≪+ distribˡ ρ _ _ ⟩ρ ^ j * ((ρ * (ρ * xs′ + x′) *⟨ ρ ⟩^ k + ρ * ys′) + y′)≈⟨ *≫ +-assoc _ _ _ ⟩ρ ^ j * (ρ * (ρ * xs′ + x′) *⟨ ρ ⟩^ k + (ρ * ys′ + y′))≈⟨ distribˡ _ _ _ ⟩ρ ^ j * (ρ * (ρ * xs′ + x′) *⟨ ρ ⟩^ k) + ρ ^ j * (ρ * ys′ + y′)≈⟨ sym (pow-opt _ ρ j) ⟨ flip +-cong ⟩(beginρ ^ j * (ρ * ((ρ * ⅀?⟦ xs ⟧ (ρ , Ρ) + ⟦ poly x ⟧ Ρ) *⟨ ρ ⟩^ k))≈⟨ (sym (*-assoc _ _ _) ⟨ trans ⟩ (≪* sym (pow-sucʳ ρ j))) ⟩ρ ^ suc j * ((ρ * ⅀?⟦ xs ⟧ (ρ , Ρ) + ⟦ poly x ⟧ Ρ) *⟨ ρ ⟩^ k)≈⟨ pow-add _ _ k j ⟩(ρ * ⅀?⟦ xs ⟧ (ρ , Ρ) + ⟦ poly x ⟧ Ρ) *⟨ ρ ⟩^ (k ℕ.+ suc j)≡⟨ ≡.cong (λ i → (ρ * ⅀?⟦ xs ⟧ (ρ , Ρ) + ⟦ poly x ⟧ Ρ) *⟨ ρ ⟩^ i) (ℕ.+-comm k (suc j)) ⟩(ρ * ⅀?⟦ xs ⟧ (ρ , Ρ) + ⟦ poly x ⟧ Ρ) *⟨ ρ ⟩^ (suc j ℕ.+ k)∎)⟩(ρ * xs′ + x′) *⟨ ρ ⟩^ suc (j ℕ.+ k) + (ρ * ys′ + y′) *⟨ ρ ⟩^ j≈⟨ pow-mul-cong (sym (⟦∷⟧-hom (poly x) xs ρ Ρ)) ρ (suc (j ℕ.+ k)) ⟨ +-cong ⟩ pow-mul-cong (sym (⟦∷⟧-hom (poly y) ys ρ Ρ)) ρ j ⟩((poly x , xs) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ suc (j ℕ.+ k) + ((poly y , ys) ⟦∷⟧ (ρ , Ρ)) *⟨ ρ ⟩^ j∎⊞-zip-r-hom : ∀ {n} i→ (x : NonZero n)→ (xs ys : Coeff n *)→ (Ρ : Carrier × Vec Carrier n)→ ⅀?⟦ ⊞-zip-r x i xs ys ⟧ (Ρ) ≈ ⅀⟦ x Δ i & xs ⟧ ( Ρ) + ⅀?⟦ ys ⟧ ( Ρ)⊞-zip-r-hom i x xs [] (ρ , Ρ) = sym (+-identityʳ _)⊞-zip-r-hom i x xs (∹ (y Δ j) & ys ) = ⊞-zip-hom (compare i j) x xs y ys
-------------------------------------------------------------------------- The Agda standard library---- Sparse polynomials in a commutative ring, encoded in Horner normal-- form.---- Horner normal form encodes a polynomial as a list of coefficients.-- As an example take the polynomial:---- 3 + 2x² + 4x⁵ + 2x⁷---- Then expand it out, filling in the missing coefficients:---- 3x⁰ + 0x¹ + 2x² + 0x³ + 0x⁴ + 4x⁵ + 0x⁶ + 2x⁷---- And then encode that as a list:---- [3, 0, 2, 0, 0, 4, 0, 2]---- The representation we use here is optimised from the above. First,-- we remove the zero terms, and add a "gap" index next to every-- coefficient:---- [(3,0),(2,1),(4,2),(2,1)]---- Which can be thought of as a representation of the expression:---- x⁰ * (3 + x * x¹ * (2 + x * x² * (4 + x * x¹ * (2 + x * 0))))---- This is "sparse" Horner normal form.---- The second optimisation deals with representing multiple variables-- in a polynomial. The standard trick is to encode a polynomial in n-- variables as a polynomial with coefficients in n-1 variables,-- recursing until you hit 0 which is simply the type of the coefficient-- itself.---- We again encode "gaps" here, with the injection index. Since the-- number of variables in a polynomial is contained in its type,-- however, operations on this gap are type-relevant, so it's not-- convenient to simply use ℕ. We use _≤′_ instead.------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}open import Tactic.RingSolver.Core.Polynomial.Parametersmodule Tactic.RingSolver.Core.Polynomial.Base{ℓ₁ ℓ₂} (coeffs : RawCoeff ℓ₁ ℓ₂) whereopen RawCoeff coeffsopen import Data.Bool.Base using (Bool; true; false; T)open import Data.Empty using (⊥)open import Data.Fin.Base as Fin using (Fin; zero; suc)open import Data.List.Kleeneopen import Data.Nat.Base as ℕ using (ℕ; suc; zero; _≤′_; compare; ≤′-refl; ≤′-step; _<′_)open import Data.Nat.Properties using (z≤′n; ≤′-trans)open import Data.Nat.Inductionopen import Data.Product.Base using (_×_; _,_; map₁; curry; uncurry)open import Data.Unit.Base using (⊤; tt)open import Function.Baseopen import Relation.Nullary using (¬_; Dec; yes; no)open import Algebra.Definitions.RawSemiring rawSemiringusing (_^′_)-------------------------------------------------------------------------- Injection indices.-------------------------------------------------------------------------- First, we define comparisons on _≤′_.-- The following is analagous to Ordering and compare from-- Data.Nat.Base.data InjectionOrdering {n : ℕ} : ∀ {i j} (i≤n : i ≤′ n) (j≤n : j ≤′ n) → Setwhereinj-lt : ∀ {i j-1} (i≤j-1 : i ≤′ j-1) (j≤n : suc j-1 ≤′ n) →InjectionOrdering (≤′-step i≤j-1 ⟨ ≤′-trans ⟩ j≤n) j≤ninj-gt : ∀ {i-1 j} (i≤n : suc i-1 ≤′ n) (j≤i-1 : j ≤′ i-1) →InjectionOrdering i≤n (≤′-step j≤i-1 ⟨ ≤′-trans ⟩ i≤n)inj-eq : ∀ {i} (i≤n : i ≤′ n) →InjectionOrdering i≤n i≤ninj-compare : ∀ {i j n} (x : i ≤′ n) (y : j ≤′ n) → InjectionOrdering x yinj-compare ≤′-refl ≤′-refl = inj-eq ≤′-reflinj-compare ≤′-refl (≤′-step y) = inj-gt ≤′-refl yinj-compare (≤′-step x) ≤′-refl = inj-lt x ≤′-reflinj-compare (≤′-step x) (≤′-step y) = case inj-compare x y ofλ { (inj-lt i≤j-1 y) → inj-lt i≤j-1 (≤′-step y); (inj-gt x j≤i-1) → inj-gt (≤′-step x) j≤i-1; (inj-eq x) → inj-eq (≤′-step x)}-- The "space" above a Fin n is the number of unique "Fin n"s greater-- than or equal to it.space : ∀ {n} → Fin n → ℕspace f = suc (go f)wherego : ∀ {n} → Fin n → ℕgo {suc n} Fin.zero = ngo (Fin.suc x) = go xspace≤′n : ∀ {n} (x : Fin n) → space x ≤′ nspace≤′n zero = ≤′-reflspace≤′n (suc x) = ≤′-step (space≤′n x)-------------------------------------------------------------------------- Definition------------------------------------------------------------------------infixl 6 _Δ_record PowInd {c} (C : Set c) : Set c whereconstructor _Δ_fieldcoeff : Cpow : ℕopen PowInd publicrecord Poly (n : ℕ) : Set ℓ₁data FlatPoly : ℕ → Set ℓ₁Coeff : ℕ → Set ℓ₁record NonZero (i : ℕ) : Set ℓ₁Zero : ∀ {n} → Poly n → SetNormalised : ∀ {i} → Coeff i + → Set-- A Polynomial is indexed by the number of variables it contains.infixl 6 _⊐_record Poly n whereinductiveconstructor _⊐_eta-equality -- To allow matching on constructorfield{i} : ℕflat : FlatPoly ii≤n : i ≤′ ndata FlatPoly whereΚ : Carrier → FlatPoly zero⅀ : ∀ {n} (xs : Coeff n +) {xn : Normalised xs} → FlatPoly (suc n)Coeff n = PowInd (NonZero n)-- We disallow zeroes in the coefficient list. This condition alone-- is enough to ensure a unique representation for any polynomial.infixl 6 _≠0record NonZero i whereinductiveconstructor _≠0fieldpoly : Poly i.{poly≠0} : ¬ Zero poly-- This predicate is used (in its negation) to ensure that no-- coefficient is zero, preventing any trailing zeroes.Zero (Κ x ⊐ _) = T (isZero x)Zero (⅀ _ ⊐ _) = ⊥-- This predicate is used to ensure that all polynomials are in-- normal form: if a particular level is constant, then it can-- be collapsed into the level below it.Normalised (_ Δ zero & []) = ⊥Normalised (_ Δ zero & ∹ _) = ⊤Normalised (_ Δ suc _ & _) = ⊤open NonZero publicopen Poly public-------------------------------------------------------------------------- Special operations-- Decision procedure for Zerozero? : ∀ {n} → (p : Poly n) → Dec (Zero p)zero? (⅀ _ ⊐ _) = no idzero? (Κ x ⊐ _) with isZero x... | true = yes tt... | false = no id{-# INLINE zero? #-}-- Exponentiate the first variable of a polynomialinfixr 8 _⍓*_ _⍓+__⍓*_ : ∀ {n} → Coeff n * → ℕ → Coeff n *_⍓+_ : ∀ {n} → Coeff n + → ℕ → Coeff n +[] ⍓* _ = [](∹ xs) ⍓* i = ∹ xs ⍓+ icoeff (head (xs ⍓+ i)) = coeff (head xs)pow (head (xs ⍓+ i)) = pow (head xs) ℕ.+ itail (xs ⍓+ i) = tail xsinfixr 5 _∷↓__∷↓_ : ∀ {n} → PowInd (Poly n) → Coeff n * → Coeff n *x Δ i ∷↓ xs = case zero? x ofλ { (yes p) → xs ⍓* suc i; (no ¬p) → ∹ _≠0 x {¬p} Δ i & xs}{-# INLINE _∷↓_ #-}-- Inject a polynomial into a larger polynomial with more variables_⊐↑_ : ∀ {n m} → Poly n → (suc n ≤′ m) → Poly m(xs ⊐ i≤n) ⊐↑ n≤m = xs ⊐ (≤′-step i≤n ⟨ ≤′-trans ⟩ n≤m){-# INLINE _⊐↑_ #-}infixr 4 _⊐↓__⊐↓_ : ∀ {i n} → Coeff i * → suc i ≤′ n → Poly n[] ⊐↓ i≤n = Κ 0# ⊐ z≤′n(∹ (x ≠0 Δ zero & [] )) ⊐↓ i≤n = x ⊐↑ i≤n(∹ (x Δ zero & ∹ xs)) ⊐↓ i≤n = ⅀ (x Δ zero & ∹ xs) ⊐ i≤n(∹ (x Δ suc j & xs )) ⊐↓ i≤n = ⅀ (x Δ suc j & xs) ⊐ i≤n{-# INLINE _⊐↓_ #-}-------------------------------------------------------------------------- Standard operations-------------------------------------------------------------------------------------------------------------------------------------------------- Folds-- These folds allow us to abstract over the proofs later: we try to-- avoid using ∷↓ and ⊐↓ directly anywhere except here, so if we prove-- that this fold acts the same on a normalised or non-normalised-- polynomial, we can prove th same about any operation which uses it.PolyF : ℕ → Set ℓ₁PolyF i = Poly i × Coeff i *Fold : ℕ → Set ℓ₁Fold i = PolyF i → PolyF ipara : ∀ {i} → Fold i → Coeff i + → Coeff i *para f (x ≠0 Δ i & []) = case f (x , []) of λ {(y , ys) → y Δ i ∷↓ ys}para f (x ≠0 Δ i & ∹ xs) = case f (x , para f xs) of λ {(y , ys) → y Δ i ∷↓ ys}poly-map : ∀ {i} → (Poly i → Poly i) → Coeff i + → Coeff i *poly-map f = para (map₁ f){-# INLINE poly-map #-}-------------------------------------------------------------------------- Addition-- The reason the following code is so verbose is termination-- checking. For instance, in the third case for ⊞-coeffs, we call a-- helper function. Instead, you could conceivably use a with-block-- (on ℕ.compare p q):---- ⊞-coeffs ((x , p) ∷ xs) ((y , q) ∷ ys) with (ℕ.compare p q)-- ... | ℕ.less p k = (x , p) ∷ ⊞-coeffs xs ((y , k) ∷ ys)-- ... | ℕ.equal p = (fst~ x ⊞ fst~ y , p) ∷↓ ⊞-coeffs xs ys-- ... | ℕ.greater q k = (y , q) ∷ ⊞-coeffs ((x , k) ∷ xs) ys---- However, because the first and third recursive calls each rewrap-- a list that was already pattern-matched on, the recursive call-- does not strictly decrease the size of its argument.---- Interestingly, if --cubical-compatible is turned off, we don't need-- the helper function ⊞-coeffs; we could pattern match on _⊞_ directly.---- _⊞_ {zero} (lift x) (lift y) = lift (x + y)-- _⊞_ {suc n} [] ys = ys-- _⊞_ {suc n} (x ∷ xs) [] = x ∷ xs-- _⊞_ {suc n} ((x , p) ∷ xs) ((y , q) ∷ ys) = ⊞-zip (ℕ.compare p q) x xs y ysmutualinfixl 6 _⊞__⊞_ : ∀ {n} → Poly n → Poly n → Poly n(xs ⊐ i≤n) ⊞ (ys ⊐ j≤n) = ⊞-match (inj-compare i≤n j≤n) xs ys⊞-match : ∀ {i j n}→ {i≤n : i ≤′ n}→ {j≤n : j ≤′ n}→ InjectionOrdering i≤n j≤n→ FlatPoly i→ FlatPoly j→ Poly n⊞-match (inj-eq i&j≤n) (Κ x) (Κ y) = Κ (x + y) ⊐ i&j≤n⊞-match (inj-eq i&j≤n) (⅀ (x Δ i & xs)) (⅀ (y Δ j & ys)) = ⊞-zip (compare i j) x xs y ys ⊐↓ i&j≤n⊞-match (inj-lt i≤j-1 j≤n) xs (⅀ ys) = ⊞-inj i≤j-1 xs ys ⊐↓ j≤n⊞-match (inj-gt i≤n j≤i-1) (⅀ xs) ys = ⊞-inj j≤i-1 ys xs ⊐↓ i≤n⊞-inj : ∀ {i k}→ (i ≤′ k)→ FlatPoly i→ Coeff k +→ Coeff k *⊞-inj i≤k xs (y ⊐ j≤k ≠0 Δ zero & ys) = ⊞-match (inj-compare j≤k i≤k) y xs Δ zero ∷↓ ys⊞-inj i≤k xs (y Δ suc j & ys) = xs ⊐ i≤k Δ zero ∷↓ ∹ y Δ j & ys⊞-coeffs : ∀ {n} → Coeff n * → Coeff n * → Coeff n *⊞-coeffs (∹ x Δ i & xs) ys = ⊞-zip-r x i xs ys⊞-coeffs [] ys = ys⊞-zip : ∀ {p q n}→ ℕ.Ordering p q→ NonZero n→ Coeff n *→ NonZero n→ Coeff n *→ Coeff n *⊞-zip (ℕ.less i k) x xs y ys = ∹ x Δ i & ⊞-zip-r y k ys xs⊞-zip (ℕ.greater j k) x xs y ys = ∹ y Δ j & ⊞-zip-r x k xs ys⊞-zip (ℕ.equal i ) x xs y ys = (x .poly ⊞ y .poly) Δ i ∷↓ ⊞-coeffs xs ys{-# INLINE ⊞-zip #-}⊞-zip-r : ∀ {n} → NonZero n → ℕ → Coeff n * → Coeff n * → Coeff n *⊞-zip-r x i xs [] = ∹ x Δ i & xs⊞-zip-r x i xs (∹ y Δ j & ys) = ⊞-zip (compare i j) x xs y ys-------------------------------------------------------------------------- Negation-- recurse on acc directly-- https://github.com/agda/agda/issues/3190#issuecomment-416900716⊟-step : ∀ {n} → Acc _<′_ n → Poly n → Poly n⊟-step (acc wf) (Κ x ⊐ i≤n) = Κ (- x) ⊐ i≤n⊟-step (acc wf) (⅀ xs ⊐ i≤n) = poly-map (⊟-step (wf i≤n)) xs ⊐↓ i≤n⊟_ : ∀ {n} → Poly n → Poly n⊟_ = ⊟-step (<′-wellFounded _){-# INLINE ⊟_ #-}-------------------------------------------------------------------------- Multiplicationmutual⊠-step′ : ∀ {n} → Acc _<′_ n → Poly n → Poly n → Poly n⊠-step′ a (x ⊐ i≤n) = ⊠-step a x i≤n⊠-step : ∀ {i n} → Acc _<′_ n → FlatPoly i → i ≤′ n → Poly n → Poly n⊠-step a (Κ x) _ = ⊠-Κ a x⊠-step a (⅀ xs) = ⊠-⅀ a xs⊠-Κ : ∀ {n} → Acc _<′_ n → Carrier → Poly n → Poly n⊠-Κ (acc _ ) x (Κ y ⊐ i≤n) = Κ (x * y) ⊐ i≤n⊠-Κ (acc wf) x (⅀ xs ⊐ i≤n) = ⊠-Κ-inj (wf i≤n) x xs ⊐↓ i≤n{-# INLINE ⊠-Κ #-}⊠-⅀ : ∀ {i n} → Acc _<′_ n → Coeff i + → i <′ n → Poly n → Poly n⊠-⅀ (acc wf) xs i≤n (⅀ ys ⊐ j≤n) = ⊠-match (acc wf) (inj-compare i≤n j≤n) xs ys⊠-⅀ (acc wf) xs i≤n (Κ y ⊐ _) = ⊠-Κ-inj (wf i≤n) y xs ⊐↓ i≤n⊠-Κ-inj : ∀ {i} → Acc _<′_ i → Carrier → Coeff i + → Coeff i *⊠-Κ-inj a x xs = poly-map (⊠-Κ a x) (xs)⊠-⅀-inj : ∀ {i k}→ Acc _<′_ k→ i <′ k→ Coeff i +→ Poly k→ Poly k⊠-⅀-inj (acc wf) i≤k x (⅀ y ⊐ j≤k) = ⊠-match (acc wf) (inj-compare i≤k j≤k) x y⊠-⅀-inj (acc wf) i≤k x (Κ y ⊐ j≤k) = ⊠-Κ-inj (wf i≤k) y x ⊐↓ i≤k⊠-match : ∀ {i j n}→ Acc _<′_ n→ {i≤n : i <′ n}→ {j≤n : j <′ n}→ InjectionOrdering i≤n j≤n→ Coeff i +→ Coeff j +→ Poly n⊠-match (acc wf) (inj-eq i&j≤n) xs ys = ⊠-coeffs (wf i&j≤n) xs ys ⊐↓ i&j≤n⊠-match (acc wf) (inj-lt i≤j-1 j≤n) xs ys = poly-map (⊠-⅀-inj (wf j≤n) i≤j-1 xs) (ys) ⊐↓ j≤n⊠-match (acc wf) (inj-gt i≤n j≤i-1) xs ys = poly-map (⊠-⅀-inj (wf i≤n) j≤i-1 ys) (xs) ⊐↓ i≤n⊠-coeffs : ∀ {n} → Acc _<′_ n → Coeff n + → Coeff n + → Coeff n *⊠-coeffs a (xs) (y ≠0 Δ j & []) = poly-map (⊠-step′ a y) (xs) ⍓* j⊠-coeffs a (xs) (y ≠0 Δ j & ∹ ys) = para (⊠-cons a y ys) (xs) ⍓* j{-# INLINE ⊠-coeffs #-}⊠-cons : ∀ {n}→ Acc _<′_ n→ Poly n→ Coeff n +→ Fold n⊠-cons a y ys (x ⊐ j≤n , xs) =⊠-step a x j≤n y , ⊞-coeffs (poly-map (⊠-step a x j≤n) ys) xs{-# INLINE ⊠-cons #-}infixl 7 _⊠__⊠_ : ∀ {n} → Poly n → Poly n → Poly n_⊠_ = ⊠-step′ (<′-wellFounded _){-# INLINE _⊠_ #-}-------------------------------------------------------------------------- Constants and variables-- The constant polynomialκ : ∀ {n} → Carrier → Poly nκ x = Κ x ⊐ z≤′n{-# INLINE κ #-}-- A variableι : ∀ {n} → Fin n → Poly nι i = (κ 1# Δ 1 ∷↓ []) ⊐↓ space≤′n i{-# INLINE ι #-}-------------------------------------------------------------------------- Exponentiation-- We try very hard to never do things like multiply by 1-- unnecessarily. That's what all the weirdness here is for.⊡-mult : ∀ {n} → ℕ → Poly n → Poly n⊡-mult zero xs = xs⊡-mult (suc n) xs = ⊡-mult n xs ⊠ xs_⊡_+1 : ∀ {n} → Poly n → ℕ → Poly n(Κ x ⊐ i≤n) ⊡ i +1 = Κ (x ^′ suc i) ⊐ i≤n(⅀ (x Δ j & []) ⊐ i≤n) ⊡ i +1 = x .poly ⊡ i +1 Δ (j ℕ.+ i ℕ.* j) ∷↓ [] ⊐↓ i≤nxs@(⅀ (_ & ∹ _) ⊐ i≤n) ⊡ i +1 = ⊡-mult i xsinfixr 8 _⊡__⊡_ : ∀ {n} → Poly n → ℕ → Poly n_ ⊡ zero = κ 1#xs ⊡ suc i = xs ⊡ i +1{-# INLINE _⊡_ #-}
-------------------------------------------------------------------------- The Agda standard library---- Simple implementation of sets of ℕ.---- Since ℕ is represented as unary numbers, simply having an ordered-- list of numbers to represent a set is quite inefficient. For-- instance, to see if 6 is in the set {1, 3, 4}, we have to do a-- comparison with 1, then 3, and then 4. But 4 is equal to suc 3, so-- we should be able to share the work accross those two comparisons.---- This module defines a type that represents {1, 3, 4} as:---- 1 ∷ 1 ∷ 0 ∷ []---- i.e. we only store the gaps. When checking if a number (the needle)-- is in the set (the haystack), we subtract each successive member of-- the haystack from the needle as we go. For example, to check if 6 is-- in the above set, we do the following:---- start: 6 ∈? (1 ∷ 1 ∷ 0 ∷ [])-- test head: 6 ≟ 1-- not equal, so continue: (6 - 1 - 1) ∈? (1 ∷ 0 ∷ [])-- compute: 4 ∈? (1 ∷ 0 ∷ [])-- test head: 4 ≟ 1-- not equal, so continue: (4 - 1 - 1) ∈? (0 ∷ [])-- compute: 2 ∈? (0 ∷ [])-- test head: 2 ≟ 0-- not equal, so continue: (2 - 1 - 1) ∈? []-- empty list: false---- In this way, we change the membership test from O(n²) to O(n).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Tactic.RingSolver.Core.NatSet whereopen import Data.Nat.Base as ℕ using (ℕ; suc; zero)open import Data.List.Base as List using (List; _∷_; [])open import Data.List.Scans.Base as Scans using (scanl)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)open import Data.Bool.Base as Bool using (Bool)open import Function.Base using (const; _∘_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl)-------------------------------------------------------------------------- Helper methodspara : ∀ {a b} {A : Set a} {B : Set b} →(A → List A → B → B) → B → List A → Bpara f b [] = bpara f b (x ∷ xs) = f x xs (para f b xs)-------------------------------------------------------------------------- DefinitionNatSet : SetNatSet = List ℕ-------------------------------------------------------------------------- Functionsinsert : ℕ → NatSet → NatSetinsert x xs = para f (_∷ []) xs xwheref : ℕ → NatSet → (ℕ → NatSet) → ℕ → NatSetf y ys c x with ℕ.compare x y... | ℕ.less x k = x ∷ k ∷ ys... | ℕ.equal x = x ∷ ys... | ℕ.greater y k = y ∷ c kdelete : ℕ → NatSet → NatSetdelete x xs = para f (const []) xs xwheref : ℕ → NatSet → (ℕ → NatSet) → ℕ → NatSetf y ys c x with ℕ.compare x yf y ys c x | ℕ.less x k = y ∷ ysf y [] c x | ℕ.equal x = []f y₁ (y₂ ∷ ys) c x | ℕ.equal x = suc x ℕ.+ y₂ ∷ ysf y ys c x | ℕ.greater y k = y ∷ c k-- Returns the position of the element, if it's present.lookup : NatSet → ℕ → Maybe ℕlookup xs x = List.foldr f (const (const nothing)) xs x 0wheref : ℕ → (ℕ → ℕ → Maybe ℕ) → ℕ → ℕ → Maybe ℕf y ys x i with ℕ.compare x y... | ℕ.less x k = nothing... | ℕ.equal y = just i... | ℕ.greater y k = ys k (suc i)member : ℕ → NatSet → Boolmember x xs = Maybe.is-just (lookup xs x)fromList : List ℕ → NatSetfromList = List.foldr insert []toList : NatSet → List ℕtoList = List.drop 1 ∘ List.map ℕ.pred ∘ Scans.scanl (λ x y → suc (y ℕ.+ x)) 0-------------------------------------------------------------------------- Testsprivateexample₁ : fromList (4 ∷ 3 ∷ 1 ∷ 0 ∷ 2 ∷ []) ≡ (0 ∷ 0 ∷ 0 ∷ 0 ∷ 0 ∷ [])example₁ = reflexample₂ : lookup (fromList (4 ∷ 3 ∷ 1 ∷ 0 ∷ 2 ∷ [])) 3 ≡ just 3example₂ = reflexample₃ : toList (fromList (4 ∷ 3 ∷ 1 ∷ 0 ∷ 2 ∷ [])) ≡ (0 ∷ 1 ∷ 2 ∷ 3 ∷ 4 ∷ [])example₃ = reflexample₄ : delete 3 (fromList (4 ∷ 3 ∷ 1 ∷ 2 ∷ [])) ≡ fromList (4 ∷ 1 ∷ 2 ∷ [])example₄ = reflexample₅ : delete 3 (fromList (4 ∷ 1 ∷ 2 ∷ [])) ≡ fromList (4 ∷ 1 ∷ 2 ∷ [])example₅ = refl
-------------------------------------------------------------------------- The Agda standard library---- A type for expressions over a raw ring.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Tactic.RingSolver.Core.Expression whereopen import Data.Nat.Base using (ℕ)open import Data.Fin.Base using (Fin)open import Data.Vec.Base as Vec using (Vec)open import Algebrainfixl 6 _⊕_infixl 7 _⊗_infixr 8 _⊛_infix 8 ⊝_data Expr {a} (A : Set a) (n : ℕ) : Set a whereΚ : A → Expr A n -- ConstantΙ : Fin n → Expr A n -- Variable_⊕_ : Expr A n → Expr A n → Expr A n -- Addition_⊗_ : Expr A n → Expr A n → Expr A n -- Multiplication_⊛_ : Expr A n → ℕ → Expr A n -- Exponentiation⊝_ : Expr A n → Expr A n -- Negationmodule Eval{ℓ₁ ℓ₂} (rawRing : RawRing ℓ₁ ℓ₂)(open RawRing rawRing){a} {A : Set a} (⟦_⟧ᵣ : A → Carrier) whereopen import Algebra.Definitions.RawSemiring rawSemiringusing (_^′_)⟦_⟧ : ∀ {n} → Expr A n → Vec Carrier n → Carrier⟦ Κ x ⟧ ρ = ⟦ x ⟧ᵣ⟦ Ι x ⟧ ρ = Vec.lookup ρ x⟦ x ⊕ y ⟧ ρ = ⟦ x ⟧ ρ + ⟦ y ⟧ ρ⟦ x ⊗ y ⟧ ρ = ⟦ x ⟧ ρ * ⟦ y ⟧ ρ⟦ ⊝ x ⟧ ρ = - ⟦ x ⟧ ρ⟦ x ⊛ i ⟧ ρ = ⟦ x ⟧ ρ ^′ i
-------------------------------------------------------------------------- The Agda standard library---- Almost commutative rings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Tactic.RingSolver.Core.AlmostCommutativeRing whereopen import Levelopen import Relation.Binary.Core using (Rel; _Preserves_⟶_)open import Algebra.Core using (Op₁; Op₂)open import Algebra.Structures using (IsCommutativeSemiring)open import Algebra.Definitionsopen import Algebra.Bundles using (RawRing; CommutativeRing; CommutativeSemiring)import Algebra.Morphism as Morphismopen import Function.Base using (id)open import Levelopen import Data.Maybe.Base as Maybe using (Maybe; just; nothing)record IsAlmostCommutativeRing{a ℓ} {A : Set a} (_≈_ : Rel A ℓ)(_+_ _*_ : A → A → A) (-_ : A → A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisCommutativeSemiring : IsCommutativeSemiring _≈_ _+_ _*_ 0# 1#-‿cong : -_ Preserves _≈_ ⟶ _≈_-‿*-distribˡ : ∀ x y → ((- x) * y) ≈ (- (x * y))-‿+-comm : ∀ x y → ((- x) + (- y)) ≈ (- (x + y))open IsCommutativeSemiring isCommutativeSemiring publicimport Algebra.Definitions.RawSemiring as Exprecord AlmostCommutativeRing c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_infixr 8 _^_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier0≟_ : (x : Carrier) → Maybe (0# ≈ x)1# : CarrierisAlmostCommutativeRing :IsAlmostCommutativeRing _≈_ _+_ _*_ -_ 0# 1#open IsAlmostCommutativeRing isAlmostCommutativeRing hiding (refl) publicopen import Data.Nat.Base as ℕ using (ℕ)commutativeSemiring : CommutativeSemiring _ _commutativeSemiring = record{ isCommutativeSemiring = isCommutativeSemiring}open CommutativeSemiring commutativeSemiring publicusing( +-semigroup; +-monoid; +-commutativeMonoid; *-semigroup; *-monoid; *-commutativeMonoid; rawSemiring; semiring)rawRing : RawRing _ _rawRing = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0#; 1# = 1#}_^_ : Carrier → ℕ → Carrier_^_ = Exp._^′_ rawSemiring{-# NOINLINE _^_ #-}_-_ : Carrier → Carrier → Carrier_-_ x y = x + (- y)refl : ∀ {x} → x ≈ xrefl = IsAlmostCommutativeRing.refl isAlmostCommutativeRingrecord _-Raw-AlmostCommutative⟶_{r₁ r₂ r₃ r₄}(From : RawRing r₁ r₂)(To : AlmostCommutativeRing r₃ r₄) : Set (r₁ ⊔ r₂ ⊔ r₃ ⊔ r₄) whereprivatemodule F = RawRing Frommodule T = AlmostCommutativeRing Toopen Morphism.Definitions F.Carrier T.Carrier T._≈_field⟦_⟧ : Morphism+-homo : Homomorphic₂ ⟦_⟧ F._+_ T._+_*-homo : Homomorphic₂ ⟦_⟧ F._*_ T._*_-‿homo : Homomorphic₁ ⟦_⟧ (F.-_) (T.-_)0-homo : Homomorphic₀ ⟦_⟧ F.0# T.0#1-homo : Homomorphic₀ ⟦_⟧ F.1# T.1#-raw-almostCommutative⟶: ∀ {r₁ r₂} (R : AlmostCommutativeRing r₁ r₂) →AlmostCommutativeRing.rawRing R -Raw-AlmostCommutative⟶ R-raw-almostCommutative⟶ R = record{ ⟦_⟧ = id; +-homo = λ _ _ → refl; *-homo = λ _ _ → refl; -‿homo = λ _ → refl; 0-homo = refl; 1-homo = refl}where open AlmostCommutativeRing R-- A homomorphism induces a notion of equivalence on the raw ring.Induced-equivalence :∀ {c₁ c₂ c₃ ℓ} {Coeff : RawRing c₁ c₂} {R : AlmostCommutativeRing c₃ ℓ} →Coeff -Raw-AlmostCommutative⟶ R → Rel (RawRing.Carrier Coeff) ℓInduced-equivalence {R = R} morphism a b = ⟦ a ⟧ ≈ ⟦ b ⟧whereopen AlmostCommutativeRing Ropen _-Raw-AlmostCommutative⟶_ morphism-------------------------------------------------------------------------- Conversions-- Commutative rings are almost commutative rings.fromCommutativeRing : ∀ {r₁ r₂} (CR : CommutativeRing r₁ r₂) →(open CommutativeRing CR) →(∀ x → Maybe (0# ≈ x)) →AlmostCommutativeRing _ _fromCommutativeRing CR 0≟_ = record{ isAlmostCommutativeRing = record{ isCommutativeSemiring = isCommutativeSemiring; -‿cong = -‿cong; -‿*-distribˡ = λ x y → sym (-‿distribˡ-* x y); -‿+-comm = ⁻¹-∙-comm}; 0≟_ = 0≟_}whereopen CommutativeRing CRopen import Algebra.Properties.Ring ringopen import Algebra.Properties.AbelianGroup +-abelianGroupfromCommutativeSemiring : ∀ {r₁ r₂} (CS : CommutativeSemiring r₁ r₂)(open CommutativeSemiring CS) →(∀ x → Maybe (0# ≈ x)) →AlmostCommutativeRing _ _fromCommutativeSemiring CS 0≟_ = record{ -_ = id; isAlmostCommutativeRing = record{ isCommutativeSemiring = isCommutativeSemiring; -‿cong = id; -‿*-distribˡ = λ _ _ → refl; -‿+-comm = λ _ _ → refl}; 0≟_ = 0≟_}where open CommutativeSemiring CS
-------------------------------------------------------------------------- The Agda standard library---- Reflection-based solver for monoid equalities---------------------------------------------------------------------------- This solver automates the construction of proofs of equivalences-- between monoid expressions.-- When called like so:---- proof : ∀ x y z → (x ∙ y) ∙ z ≈ x ∙ (y ∙ z) ∙ ε-- proof x y z = solve mon---- The following diagram describes what happens under the hood:---- ┌▸x ∙ (y ∙ (z ∙ ε)) ════ x ∙ (y ∙ (z ∙ ε))◂┐-- │ ║ ║ │-- │ ║ ║ │-- [_⇓] ║ ║ [_⇓]-- ╱ ║ ║ ╲-- ╱ ║ ║ ╲-- (x ∙′ y) ∙′ z homo homo x ∙′ (y ∙′ z) ∙′ ε′-- ▴ ╲ ║ ║ ╱ ▴-- │ ╲ ║ ║ ╱ │-- │ [_↓] ║ ║ [_↓] │-- │ │ ║ ║ │ │-- │ │ ║ ║ │ │-- │ └───▸(x ∙ y) ∙ z x ∙ (y ∙ z) ∙ ε◂─┘ │-- │ │ │ │-- │ │ │ │-- └────reflection────┘ └───reflection──────┘---- The actual output—the proof constructed by the solver—is represented-- by the double-lined path (══).---- We start at the bottom, with our two expressions.-- Through reflection, we convert these two expressions to their AST-- representations, in the Expr type.-- We then can evaluate the AST in two ways: one simply gives us back-- the two expressions we put in ([_↓]), and the other normalises-- ([_⇓]).-- We use the homo function to prove equivalence between these two-- forms: joining up these two proofs gives us the desired overall-- proof.-- Note: What's going on with the Monoid parameter?---- This module is not parameterised over a monoid, which is contrary-- to what you might expect. Instead, we take the monoid record as an-- argument to the solve macro, and then pass it around as an-- argument wherever we need it.---- We need to get the monoid record at the call site, not the import-- site, to ensure that it's consistent with the rest of the context.-- For instance, if we wanted to produce `x ∙ y` using the monoid record-- as imported, we would run into problems:-- * If we tried to just reflect on the expression itself-- (quoteTerm (x ∙ y)) we would likely get some de Bruijn indices-- wrong (in x and y), and ∙ might not even be in scope where the-- user wants us to solve! If they're solving an expression like-- x + (y + z), they can pass in the +-0-monoid, but don't have to-- open it themselves.-- * If instead we tried to construct a term which accesses the _∙_-- field on the reflection of the record, we'd run into similar-- problems again. While the record is a parameter for us, it might-- not be for the user.-- Basically, we need the Monoid we're looking at to be exactly the-- same as the one the user is looking at, and in order to do that we-- quote it at the call site.{-# OPTIONS --cubical-compatible --safe #-}module Tactic.MonoidSolver whereopen import Algebraopen import Function.Base using (_⟨_⟩_)open import Data.Bool.Base as Bool using (Bool; _∨_; if_then_else_)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe)open import Data.List.Base as List using (List; _∷_; [])open import Data.Nat.Base as ℕ using (ℕ; suc; zero)open import Data.Product.Base as Product using (_×_; _,_)open import Reflection.ASTopen import Reflection.AST.Termopen import Reflection.AST.Argumentimport Reflection.AST.Name as Nameopen import Reflection.TCMopen import Reflection.TCM.Syntaximport Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- The Expr type with homomorphism proofs------------------------------------------------------------------------infixl 7 _∙′_data Expr {a} (A : Set a) : Set a where_∙′_ : Expr A → Expr A → Expr Aε′ : Expr A[_↑] : A → Expr Amodule _ {m₁ m₂} (monoid : Monoid m₁ m₂) whereopen Monoid monoidopen ≈-Reasoning setoid-- Convert the AST to an expression (i.e. evaluate it) without-- normalising.[_↓] : Expr Carrier → Carrier[ x ∙′ y ↓] = [ x ↓] ∙ [ y ↓][ ε′ ↓] = ε[ [ x ↑] ↓] = x-- Convert an AST to an expression (i.e. evaluate it) while-- normalising.---- This first function actually converts an AST to the Cayley-- representation of the underlying monoid.-- This obeys the monoid laws up to beta-eta equality, which is the-- property which gives us the "normalising" behaviour we want.[_⇓]′ : Expr Carrier → Carrier → Carrier[ x ∙′ y ⇓]′ z = [ x ⇓]′ ([ y ⇓]′ z)[ ε′ ⇓]′ y = y[ [ x ↑] ⇓]′ y = x ∙ y[_⇓] : Expr Carrier → Carrier[ x ⇓] = [ x ⇓]′ εhomo′ : ∀ x y → [ x ⇓] ∙ y ≈ [ x ⇓]′ yhomo′ ε′ y = identityˡ yhomo′ [ x ↑] y = ∙-congʳ (identityʳ x)homo′ (x ∙′ y) z = begin[ x ∙′ y ⇓] ∙ z ≡⟨⟩[ x ⇓]′ [ y ⇓] ∙ z ≈⟨ ∙-congʳ (homo′ x [ y ⇓]) ⟨([ x ⇓] ∙ [ y ⇓]) ∙ z ≈⟨ assoc [ x ⇓] [ y ⇓] z ⟩[ x ⇓] ∙ ([ y ⇓] ∙ z) ≈⟨ ∙-congˡ (homo′ y z) ⟩[ x ⇓] ∙ ([ y ⇓]′ z) ≈⟨ homo′ x ([ y ⇓]′ z) ⟩[ x ⇓]′ ([ y ⇓]′ z) ∎homo : ∀ x → [ x ⇓] ≈ [ x ↓]homo ε′ = reflhomo [ x ↑] = identityʳ xhomo (x ∙′ y) = begin[ x ∙′ y ⇓] ≡⟨⟩[ x ⇓]′ [ y ⇓] ≈⟨ homo′ x [ y ⇓] ⟨[ x ⇓] ∙ [ y ⇓] ≈⟨ ∙-cong (homo x) (homo y) ⟩[ x ↓] ∙ [ y ↓] ∎-------------------------------------------------------------------------- Helpers for reflection------------------------------------------------------------------------getArgs : Term → Maybe (Term × Term)getArgs (def _ xs) = go xswherego : List (Arg Term) → Maybe (Term × Term)go (vArg x ∷ vArg y ∷ []) = just (x , y)go (x ∷ xs) = go xsgo _ = nothinggetArgs _ = nothing-------------------------------------------------------------------------- Getting monoid names-------------------------------------------------------------------------- We try to be flexible here, by matching two kinds of names.-- The first is the field accessor for the monoid record itself.-- However, users will likely want to use the solver with-- expressions like:---- xs ++ (ys ++ zs) ≡ (xs ++ ys) ++ zs---- So we also evaluate the field accessor to find functions like ++.record MonoidNames : Set wherefieldis-∙ : Name → Boolis-ε : Name → BoolbuildMatcher : Name → Maybe Name → Name → BoolbuildMatcher n nothing x = n Name.≡ᵇ xbuildMatcher n (just m) x = n Name.≡ᵇ x ∨ m Name.≡ᵇ xfindMonoidNames : Term → TC MonoidNamesfindMonoidNames mon = do∙-altName ← normalise (def (quote Monoid._∙_) (2 ⋯⟅∷⟆ mon ⟨∷⟩ []))ε-altName ← normalise (def (quote Monoid.ε) (2 ⋯⟅∷⟆ mon ⟨∷⟩ []))pure record{ is-∙ = buildMatcher (quote Monoid._∙_) (getName ∙-altName); is-ε = buildMatcher (quote Monoid.ε) (getName ε-altName)}-------------------------------------------------------------------------- Building Expr-------------------------------------------------------------------------- We now define a function that takes an AST representing the LHS-- or RHS of the equation to solve and converts it into an AST-- respresenting the corresponding Expr.″ε″ : Term″ε″ = quote ε′ ⟨ con ⟩ [][_↑]′ : Term → Term[ t ↑]′ = quote [_↑] ⟨ con ⟩ (t ⟨∷⟩ [])module _ (names : MonoidNames) whereopen MonoidNames namesmutual″∙″ : List (Arg Term) → Term″∙″ (x ⟨∷⟩ y ⟨∷⟩ []) = quote _∙′_ ⟨ con ⟩ buildExpr x ⟨∷⟩ buildExpr y ⟨∷⟩ []″∙″ (x ∷ xs) = ″∙″ xs″∙″ _ = unknownbuildExpr : Term → TermbuildExpr t@(def n xs) =if is-∙ nthen ″∙″ xselse if is-ε nthen ″ε″else[ t ↑]′buildExpr t@(con n xs) =if is-∙ nthen ″∙″ xselse if is-ε nthen ″ε″else [ t ↑]′buildExpr t = quote [_↑] ⟨ con ⟩ (t ⟨∷⟩ [])-------------------------------------------------------------------------- Constructing the solution-------------------------------------------------------------------------- This function joins up the two homomorphism proofs. It constructs-- a proof of the following form:---- trans (sym (homo x)) (homo y)---- where x and y are the Expr representations of each side of the-- goal equation.constructSoln : Term → MonoidNames → Term → Term → TermconstructSoln mon names lhs rhs =quote Monoid.trans ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩(quote Monoid.sym ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩(quote homo ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ buildExpr names lhs ⟨∷⟩ []) ⟨∷⟩ [])⟨∷⟩(quote homo ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ buildExpr names rhs ⟨∷⟩ []) ⟨∷⟩[]-------------------------------------------------------------------------- Macro------------------------------------------------------------------------solve-macro : Term → Term → TC _solve-macro mon hole = dohole′ ← inferType hole >>= normalisenames ← findMonoidNames monjust (lhs , rhs) ← pure (getArgs hole′)where nothing → typeError (termErr hole′ ∷ [])let soln = constructSoln mon names lhs rhsunify hole solnmacrosolve : Term → Term → TC _solve = solve-macro
-------------------------------------------------------------------------- The Agda standard library---- A simple tactic for used to automatically compute the function-- argument to cong.---- The main use for this tactic is getting a similar experience to-- 'rewrite' during equational reasoning. This allows us to write very-- succinct proofs:---- example : ∀ m n → m ≡ n → suc (suc (m + 0)) + m ≡ suc (suc n) + (n + 0)-- example m n eq = begin-- suc (suc (m + 0)) + m-- ≡⟨ cong! (+-identityʳ m) ⟩-- suc (suc m) + m-- ≡⟨ cong! eq ⟩-- suc (suc n) + n-- ≡⟨ cong! (+-identityʳ n) ⟨-- suc (suc n) + (n + 0)-- ∎---- Please see README.Tactic.Cong for more details.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Tactic.Cong whereopen import Function.Base using (_$_)open import Data.Bool.Base using (true; false; if_then_else_; _∧_)open import Data.Char.Base as Char using (toℕ)open import Data.Float.Base as Float using (_≡ᵇ_)open import Data.List.Base as List using ([]; _∷_)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _≡ᵇ_; _+_)open import Data.Unit.Base using (⊤)open import Data.Word64.Base as Word64 using (toℕ)open import Data.Product.Base using (_×_; map₁; _,_)open import Function using (flip; case_of_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Nullary.Decidable.Core using (yes; no)-- 'Data.String.Properties' defines this via 'Dec', so let's use the-- builtin for maximum speed.import Agda.Builtin.String as String renaming (primStringEquality to _≡ᵇ_)open import Reflectionopen import Reflection.AST.Abstractionopen import Reflection.AST.AlphaEquality as Alphaopen import Reflection.AST.Argument as Argopen import Reflection.AST.Argument.Information as ArgInfoopen import Reflection.AST.Argument.Visibility as Visibilityopen import Reflection.AST.Literal as Literalopen import Reflection.AST.Meta as Metaopen import Reflection.AST.Name as Nameopen import Reflection.AST.Term as Termimport Reflection.AST.Traversal as Traversalopen import Reflection.TCM.Syntaxopen import Reflection.TCM.Utilities-- Marker to keep anti-unification from descending into the wrapped-- subterm.---- For instance, anti-unification of ⌞ a + b ⌟ + c and b + a + c-- yields λ ϕ → ϕ + c, as opposed to λ ϕ → ϕ + ϕ + c without ⌞_⌟.---- The marker is only visible to the cong! tactic, which inhibits-- normalisation. Anywhere else, ⌞ a + b ⌟ reduces to a + b.---- Thus, proving ⌞ a + b ⌟ + c ≡ b + a + c via cong! (+-comm a b)-- also proves a + b + c ≡ b + a + c.⌞_⌟ : ∀ {a} {A : Set a} → A → A⌞_⌟ x = x-------------------------------------------------------------------------- Utilities------------------------------------------------------------------------private-- Descend past a variable.varDescend : ℕ → ℕ → ℕvarDescend ϕ x = if ϕ ℕ.≤ᵇ x then suc x else x-- Descend a variable underneath pattern variables.patternDescend : ℕ → Pattern → Pattern × ℕpatternsDescend : ℕ → Args Pattern → Args Pattern × ℕpatternDescend ϕ (con c ps) = map₁ (con c) (patternsDescend ϕ ps)patternDescend ϕ (dot t) = dot t , ϕpatternDescend ϕ (var x) = var (varDescend ϕ x) , suc ϕpatternDescend ϕ (lit l) = lit l , ϕpatternDescend ϕ (proj f) = proj f , ϕpatternDescend ϕ (absurd x) = absurd (varDescend ϕ x) , suc ϕpatternsDescend ϕ ((arg i p) ∷ ps) =let (p' , ϕ') = patternDescend ϕ p(ps' , ϕ'') = patternsDescend ϕ' psin (arg i p ∷ ps' , ϕ'')patternsDescend ϕ [] =[] , ϕ-- Construct an error when the goal is not 'x ≡ y' for some 'x' and 'y'.notEqualityError : ∀ {A : Set} Term → TC AnotEqualityError goal = typeError (strErr "Cannot rewrite a goal that is not equality: " ∷ termErr goal ∷ [])unificationError : ∀ {A : Set} → TC Term → TC Term → TC AunificationError term symTerm = doterm' ← termsymTerm' ← symTerm-- Don't show the same term twice.let symErr = case term' Term.≟ symTerm' of λ where(yes _) → [](no _) → strErr "\n" ∷ termErr symTerm' ∷ []typeError (strErr "cong! failed, tried:\n" ∷ termErr term' ∷ symErr)record EqualityGoal : Set whereconstructor equalsfieldlevel : Termtype : Termlhs : Termrhs : TermdestructEqualityGoal : Term → TC EqualityGoaldestructEqualityGoal goal@(def (quote _≡_) (lvl ∷ tp ∷ lhs ∷ rhs ∷ [])) =pure $ equals (unArg lvl) (unArg tp) (unArg lhs) (unArg rhs)destructEqualityGoal (meta m args) =blockOnMeta mdestructEqualityGoal goal =notEqualityError goal-- Helper for constructing applications of 'cong'`cong : ∀ {a} {A : Set a} {x y : A} → EqualityGoal → Term → x ≡ y → TC Term`cong {a = a} {A = A} {x = x} {y = y} eqGoal f x≡y = do-- NOTE: We apply all implicit arguments here to ensure that using-- equality proofs with implicits don't lead to unsolved metavariable-- errors.let open EqualityGoal eqGoaleq ← quoteTC x≡y`a ← quoteTC a`A ← quoteTC A`x ← quoteTC x`y ← quoteTC ypure $ def (quote cong) $ `a ⟅∷⟆ `A ⟅∷⟆ level ⟅∷⟆ type ⟅∷⟆ vLam "ϕ" f ⟨∷⟩ `x ⟅∷⟆ `y ⟅∷⟆ eq ⟨∷⟩ []-------------------------------------------------------------------------- Anti-Unification---- The core idea of the tactic is that we can compute the input-- to 'cong' by syntactically anti-unifying both sides of the-- equality, and then using that to construct a lambda-- where all the differences are replaced by the lambda-abstracted-- variable.---- For instance, the two terms 'suc (m + (m + 0)) + (m + 0)' and-- 'suc (m + m) + (m + 0)' would anti unify to 'suc (m + _) + (m + 0)'-- which we can then use to construct the lambda 'λ ϕ → suc (m + ϕ) + (m + 0)'.------------------------------------------------------------------------privateantiUnify : ℕ → Term → Term → TermantiUnifyArgs : ℕ → Args Term → Args Term → Maybe (Args Term)antiUnifyClauses : ℕ → Clauses → Clauses → Maybe ClausesantiUnifyClause : ℕ → Clause → Clause → Maybe Clausepattern apply-⌞⌟ t = (def (quote ⌞_⌟) (_ ∷ _ ∷ arg _ t ∷ []))antiUnify ϕ (var x args) (var y args') with x ℕ.≡ᵇ y | antiUnifyArgs ϕ args args'... | _ | nothing = var ϕ []... | false | just uargs = var ϕ uargs... | true | just uargs = var (varDescend ϕ x) uargsantiUnify ϕ (con c args) (con c' args') with c Name.≡ᵇ c' | antiUnifyArgs ϕ args args'... | _ | nothing = var ϕ []... | false | just uargs = var ϕ []... | true | just uargs = con c uargsantiUnify ϕ (def f args) (apply-⌞⌟ t) = antiUnify ϕ (def f args) tantiUnify ϕ (def f args) (def f' args') with f Name.≡ᵇ f' | antiUnifyArgs ϕ args args'... | _ | nothing = var ϕ []... | false | just uargs = var ϕ []... | true | just uargs = def f uargsantiUnify ϕ (lam v (abs s t)) (lam _ (abs _ t')) =lam v (abs s (antiUnify (suc ϕ) t t'))antiUnify ϕ (pat-lam cs args) (pat-lam cs' args') with antiUnifyClauses ϕ cs cs' | antiUnifyArgs ϕ args args'... | nothing | _ = var ϕ []... | _ | nothing = var ϕ []... | just ucs | just uargs = pat-lam ucs uargsantiUnify ϕ (Π[ s ∶ arg i a ] b) (Π[ _ ∶ arg _ a' ] b') =Π[ s ∶ arg i (antiUnify ϕ a a') ] antiUnify (suc ϕ) b b'antiUnify ϕ (sort (set t)) (sort (set t')) =sort (set (antiUnify ϕ t t'))antiUnify ϕ (sort (lit n)) (sort (lit n')) with n ℕ.≡ᵇ n'... | true = sort (lit n)... | false = var ϕ []antiUnify ϕ (sort (propLit n)) (sort (propLit n')) with n ℕ.≡ᵇ n'... | true = sort (propLit n)... | false = var ϕ []antiUnify ϕ (sort (inf n)) (sort (inf n')) with n ℕ.≡ᵇ n'... | true = sort (inf n)... | false = var ϕ []antiUnify ϕ (sort unknown) (sort unknown) =sort unknownantiUnify ϕ (lit l) (lit l') with l Literal.≡ᵇ l'... | true = lit l... | false = var ϕ []antiUnify ϕ (meta x args) (meta x' args') with x Meta.≡ᵇ x' | antiUnifyArgs ϕ args args'... | _ | nothing = var ϕ []... | false | _ = var ϕ []... | true | just uargs = meta x uargsantiUnify ϕ unknown unknown = unknownantiUnify ϕ _ _ = var ϕ []antiUnifyArgs ϕ (arg i t ∷ args) (arg _ t' ∷ args') =Maybe.map (arg i (antiUnify ϕ t t') ∷_) (antiUnifyArgs ϕ args args')antiUnifyArgs ϕ [] [] =just []antiUnifyArgs ϕ _ _ =nothingantiUnifyClause ϕ (clause Γ pats t) (clause Δ pats' t') =Maybe.when ((Γ =α= Δ) ∧ (pats =α= pats'))let (upats , ϕ') = patternsDescend ϕ patsin clause Γ upats (antiUnify ϕ' t t')antiUnifyClause ϕ (absurd-clause Γ pats) (absurd-clause Δ pats') =Maybe.when ((Γ =α= Δ) ∧ (pats =α= pats')) $absurd-clause Γ patsantiUnifyClause ϕ _ _ =nothingantiUnifyClauses ϕ (c ∷ cs) (c' ∷ cs') =Maybe.ap (Maybe.map _∷_ (antiUnifyClause ϕ c c')) (antiUnifyClauses ϕ cs cs')antiUnifyClauses ϕ _ _ =just []-------------------------------------------------------------------------- Rewriting------------------------------------------------------------------------macrocong! : ∀ {a} {A : Set a} {x y : A} → x ≡ y → Term → TC ⊤cong! x≡y hole =-- NOTE: We avoid doing normalisation here as this tactic-- is mainly meant for equational reasoning. In that context,-- the endpoints of the equality are already specified in-- the form that the -- programmer expects them to be in,-- so normalising buys us nothing.withNormalisation false $ dogoal ← inferType holeeqGoal ← destructEqualityGoal goallet makeTerm = λ lhs rhs → `cong eqGoal (antiUnify 0 lhs rhs) x≡ylet lhs = EqualityGoal.lhs eqGoallet rhs = EqualityGoal.rhs eqGoallet term = makeTerm lhs rhslet symTerm = makeTerm rhs lhslet uni = _>>= flip unify hole-- When using ⌞_⌟ with ≡⟨ ... ⟨, (uni term) fails and-- (uni symTerm) succeeds.catchTC (uni term) $catchTC (uni symTerm) $ do-- If we failed because of unresolved metas, restart.blockOnMetas goal-- If we failed for a different reason, show an error.unificationError term symTerm
-------------------------------------------------------------------------- The Agda standard library---- *Pseudo-random* number generation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Random whereimport System.Random.Primitive as Primopen import Data.Bool.Base using (T)open import Data.Nat.Base using (ℕ; z≤n) hiding (module ℕ)open import Foreign.Haskell.Pair using (_,_)open import Function.Base using (_$_; _∘_)open import IO.Base using (IO; lift; lift!; _<$>_; _>>=_; pure)import IO.Effectful as IOopen import Level using (0ℓ; suc; _⊔_; lift)open import Relation.Binary.Core using (Rel)-------------------------------------------------------------------------- Ranged generation shall return proofsrecord InBounds {a r} {A : Set a} (_≤_ : Rel A r) (lo hi : A) : Set (a ⊔ r) whereconstructor _∈[_,_]fieldvalue : A.isLowerBound : lo ≤ value.isUpperBound : value ≤ hiRandomRIO : ∀ {a r} {A : Set a} (_≤_ : Rel A r) → Set (suc (a ⊔ r))RandomRIO {A = A} _≤_ = (lo hi : A) → .(lo ≤ hi) → IO (InBounds _≤_ lo hi)-------------------------------------------------------------------------- Instancesmodule Char whereopen import Data.Char.Base using (Char; _≤_)randomIO : IO CharrandomIO = lift Prim.randomIO-CharrandomRIO : RandomRIO _≤_randomRIO lo hi _ = dovalue ← lift (Prim.randomRIO-Char (lo , hi))pure (value ∈[ trustMe , trustMe ])where postulate trustMe : ∀ {A} → Amodule Float whereopen import Data.Float.Base using (Float; _≤_)randomIO : IO FloatrandomIO = lift Prim.randomIO-FloatrandomRIO : RandomRIO _≤_randomRIO lo hi _ = dovalue ← lift (Prim.randomRIO-Float (lo , hi))pure (value ∈[ trustMe , trustMe ])where postulate trustMe : ∀ {A} → Amodule ℤ whereopen import Data.Integer.Base using (ℤ; _≤_)randomIO : IO ℤrandomIO = lift Prim.randomIO-IntrandomRIO : RandomRIO _≤_randomRIO lo hi _ = dovalue ← lift (Prim.randomRIO-Int (lo , hi))pure (value ∈[ trustMe , trustMe ])where postulate trustMe : ∀ {A} → Amodule ℕ whereopen import Data.Nat.Base using (ℕ; _≤_)randomIO : IO ℕrandomIO = lift Prim.randomIO-NatrandomRIO : RandomRIO _≤_randomRIO lo hi _ = dovalue ← lift (Prim.randomRIO-Nat (lo , hi))pure (value ∈[ trustMe , trustMe ])where postulate trustMe : ∀ {A} → Amodule Word64 whereopen import Data.Word64.Base using (Word64; _≤_)randomIO : IO Word64randomIO = lift Prim.randomIO-Word64randomRIO : RandomRIO _≤_randomRIO lo hi _ = dovalue ← lift (Prim.randomRIO-Word64 (lo , hi))pure (value ∈[ trustMe , trustMe ])where postulate trustMe : ∀ {A} → Amodule Fin whereopen import Data.Nat.Base as ℕ using (suc; NonZero; z≤n; s≤s)import Data.Nat.Properties as ℕopen import Data.Fin.Base using (Fin; _≤_; fromℕ<; toℕ)import Data.Fin.Properties as FinrandomIO : ∀ {n} → .{{NonZero n}} → IO (Fin n)randomIO {n = n@(suc _)} = dosuc k ∈[ lo≤k , k≤hi ] ← ℕ.randomRIO 1 n (s≤s z≤n)pure (fromℕ< k≤hi)toℕ-cancel-InBounds : ∀ {n} {lo hi : Fin n} →InBounds ℕ._≤_ (toℕ lo) (toℕ hi) →InBounds _≤_ lo hitoℕ-cancel-InBounds {n} {lo} {hi} (k ∈[ toℕlo≤k , k≤toℕhi ]) =let.k<n : k ℕ.< nk<n = ℕ.≤-<-trans k≤toℕhi (Fin.toℕ<n hi).lo≤k : lo ≤ fromℕ< k<nlo≤k = Fin.toℕ-cancel-≤ $ let open ℕ.≤-Reasoning in begintoℕ lo ≤⟨ toℕlo≤k ⟩k ≡⟨ Fin.toℕ-fromℕ< k<n ⟨toℕ (fromℕ< k<n) ∎.k≤hi : fromℕ< k<n ≤ hik≤hi = Fin.toℕ-cancel-≤ $ let open ℕ.≤-Reasoning in begintoℕ (fromℕ< k<n) ≡⟨ Fin.toℕ-fromℕ< k<n ⟩k ≤⟨ k≤toℕhi ⟩toℕ hi ∎in fromℕ< k<n ∈[ lo≤k , k≤hi ]randomRIO : ∀ {n} → RandomRIO {A = Fin n} _≤_randomRIO {n} lo hi p = dok ← ℕ.randomRIO (toℕ lo) (toℕ hi) (Fin.toℕ-mono-≤ p)pure (toℕ-cancel-InBounds k)module List {a} {A : Set a} (rIO : IO A) whereopen import Data.List.Base using (List; replicate)open import Data.List.Effectful using (module TraversableA)-- Careful: this can generate very long lists!-- You may want to use Vec≤ instead.randomIO : IO (List A)randomIO = dolift n ← lift! ℕ.randomIOTraversableA.sequenceA IO.applicative $ replicate n rIOmodule Vec {a} {A : Set a} (rIO : IO A) (n : ℕ) whereopen import Data.Vec.Base using (Vec; replicate)open import Data.Vec.Effectful using (module TraversableA)randomIO : IO (Vec A n)randomIO = TraversableA.sequenceA IO.applicative $ replicate n rIOmodule Vec≤ {a} {A : Set a} (rIO : IO A) (n : ℕ) whereopen import Data.Vec.Bounded.Base using (Vec≤; _,_)randomIO : IO (Vec≤ A n)randomIO = dolift (len ∈[ _ , len≤n ]) ← lift! (ℕ.randomRIO 0 n z≤n)vec ← Vec.randomIO rIO lenpure (vec , len≤n)module String whereopen import Data.String.Base using (String; fromList)-- Careful: this can generate very long lists!-- You may want to use String≤ instead.randomIO : IO StringrandomIO = fromList <$> List.randomIO Char.randomIOmodule String≤ (n : ℕ) whereimport Data.Vec.Bounded.Base as Vec≤open import Data.String.Base using (String; fromList)randomIO : IO StringrandomIO = fromList ∘ Vec≤.toList <$> Vec≤.randomIO Char.randomIO nopen import Data.Char.Base using (Char; _≤_)module RangedString≤ (a b : Char) .(a≤b : a ≤ b) (n : ℕ) whereimport Data.Vec.Bounded.Base as Vec≤open import Data.String.Base using (String; fromList)randomIO : IO StringrandomIO =fromList ∘ Vec≤.toList ∘ Vec≤.map InBounds.value<$> Vec≤.randomIO (Char.randomRIO a b a≤b) n
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Random simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module System.Random.Primitive whereopen import Agda.Builtin.IO using (IO)open import Agda.Builtin.Char using (Char)open import Agda.Builtin.Float using (Float)open import Agda.Builtin.Int using (Int)open import Agda.Builtin.Nat using (Nat)open import Agda.Builtin.Word using (Word64)open import Foreign.Haskell.Pair using (Pair)postulaterandomIO-Char : IO CharrandomRIO-Char : Pair Char Char → IO CharrandomIO-Int : IO IntrandomRIO-Int : Pair Int Int → IO IntrandomIO-Float : IO FloatrandomRIO-Float : Pair Float Float → IO FloatrandomIO-Nat : IO NatrandomRIO-Nat : Pair Nat Nat → IO NatrandomIO-Word64 : IO Word64randomRIO-Word64 : Pair Word64 Word64 → IO Word64{-# FOREIGN GHC import System.Random #-}{-# COMPILE GHC randomIO-Char = randomIO #-}{-# COMPILE GHC randomRIO-Char = randomRIO #-}{-# COMPILE GHC randomIO-Int = randomIO #-}{-# COMPILE GHC randomRIO-Int = randomRIO #-}{-# COMPILE GHC randomIO-Float = randomIO #-}{-# COMPILE GHC randomRIO-Float = randomRIO #-}{-# COMPILE GHC randomIO-Nat = abs <$> randomIO #-}{-# COMPILE GHC randomRIO-Nat = randomRIO #-}{-# COMPILE GHC randomIO-Word64 = randomIO #-}{-# COMPILE GHC randomRIO-Word64 = randomRIO #-}
-------------------------------------------------------------------------- The Agda standard library---- Calling external processes------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Process whereopen import Level using (Level)open import Data.List.Base using (List)open import Data.Product.Base using (_×_; proj₁)open import Data.String.Base using (String)open import Data.Unit.Polymorphic using (⊤)open import Foreign.Haskell.Coerceopen import IO.Baseopen import System.Exitimport System.Process.Primitive as Primprivatevariableℓ : LevelcallCommand : String → IO {ℓ} ⊤callCommand cmd = lift′ (Prim.callCommand cmd)system : String → IO ExitCodesystem cmd = lift (Prim.system cmd)callProcess : String → List String → IO {ℓ} ⊤callProcess exe args = lift′ (Prim.callProcess exe args)readProcess: String -- Filename of the executable→ List String -- any arguments→ String -- standard input→ IO String -- stdoutreadProcess exe args stdin = lift (Prim.readProcess exe args stdin)readProcessWithExitCode: String -- Filename of the executable→ List String -- any arguments→ String -- standard input→ IO (ExitCode × String × String) -- exitcode, stdout, stderrreadProcessWithExitCode exe args stdin =lift (coerce Prim.readProcessWithExitCode exe args stdin)callProcessWithExitCode : String → List String → IO ExitCodecallProcessWithExitCode exe args = proj₁ <$> readProcessWithExitCode exe args ""
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Process simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module System.Process.Primitive whereopen import Level using (Level)open import Agda.Builtin.Listopen import Agda.Builtin.Stringopen import Agda.Builtin.Unitopen import Foreign.Haskell using (Pair)open import IO.Primitive.Core using (IO)open import System.Exit.Primitive using (ExitCode)postulatecallCommand : String → IO ⊤system : String → IO ExitCodecallProcess : String → List String → IO ⊤readProcess: String -- Filename of the executable→ List String -- any arguments→ String -- standard input→ IO String -- stdoutreadProcessWithExitCode: String -- Filename of the executable→ List String -- any arguments→ String -- standard input→ IO (Pair ExitCode (Pair String String)) -- exitcode, stdout, stderr{-# FOREIGN GHC import System.Process #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# FOREIGN GHC import MAlonzo.Code.System.Exit.Primitive #-}{-# COMPILE GHC callCommand = \ cmd -> callCommand (T.unpack cmd) #-}{-# COMPILE GHC system = \ cmd -> fmap fromExitCode (system (T.unpack cmd)) #-}{-# COMPILE GHC callProcess = \ exe -> callProcess (T.unpack exe) . map T.unpack #-}{-# COMPILE GHC readProcess = \ exe args -> fmap T.pack . readProcess (T.unpack exe) (map T.unpack args) . T.unpack #-}{-# COMPILE GHC readProcessWithExitCode = \ exe args stdin ->do { (ex, out, err) <- readProcessWithExitCode (T.unpack exe) (map T.unpack args) (T.unpack stdin); pure (fromExitCode ex, (T.pack out, T.pack err))}#-}
-------------------------------------------------------------------------- The Agda standard library---- Posix filepaths------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.FilePath.Posix whereopen import Agda.Builtin.Bool using (Bool)open import Agda.Builtin.List using (List)open import Agda.Builtin.String using (String)open import IO.Base using (IO; lift)open import Data.Maybe.Base using (Maybe)open import Data.Product.Base using (_×_)open import Data.Sum.Base using (_⊎_)open import Foreign.Haskell.Coerceopen import System.FilePath.Posix.Primitive as Primpublic-- Some of these functions are not directly re-exported because their-- respective types mentions FFI-friendly versions of the stdlib's types-- e.g. `Pair` instead of `_×_`.-- A wrapper is systematically defined below using Foreign.Haskell.Coerce's-- zero-cost coercion to expose a more useful function to users.using ( module Nature; Nature; FilePath; mkFilePath; getFilePath; AbsolutePath; RelativePath; SomePath; Extension; mkExtension; getExtension-- Separator predicates; pathSeparator; pathSeparators; isPathSeparator; searchPathSeparator; isSearchPathSeparator; extSeparator; isExtSeparator-- $PATH methods; splitSearchPath-- ; getSearchPath see below: lift needed-- Extension functions-- ; splitExtension see below: coerce needed; takeExtension; replaceExtension; dropExtension; addExtension; hasExtension; takeExtensions; replaceExtensions; dropExtensions; isExtensionOf-- ; stripExtension see below: coerce needed-- Filename/directory functions-- ; splitFileName see below: coerce needed; takeFileName; replaceFileName; dropFileName; takeBaseName; replaceBaseName; takeDirectory; replaceDirectory; combine; splitPath; joinPath; splitDirectories-- Trailing slash functions; hasTrailingPathSeparator; addTrailingPathSeparator; dropTrailingPathSeparator-- File name manipulations; normalise; equalFilePath; makeRelative-- ; checkFilePath see below: coerce needed; isRelative; isAbsolute; isValid; makeValid)privatevariablem n : Nature-- singleton type for Naturedata KnownNature : Nature → Set whereinstanceabsolute : KnownNature Nature.absoluterelative : KnownNature Nature.relativecurrentDirectory : SomePathcurrentDirectory = mkFilePath "."splitExtension : FilePath n → FilePath n × ExtensionsplitExtension = coerce Prim.splitExtensionsplitExtensions : FilePath n → FilePath n × ExtensionsplitExtensions = coerce Prim.splitExtensionsstripExtension : Extension → FilePath n → Maybe (FilePath n)stripExtension = coerce Prim.stripExtensiongetSearchPath : IO (List SomePath)getSearchPath = lift Prim.getSearchPathsplitFileName : FilePath n → FilePath n × RelativePathsplitFileName = coerce Prim.splitFileNamecheckFilePath : FilePath n → RelativePath ⊎ AbsolutePathcheckFilePath = coerce Prim.checkFilePath
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.FilePath.Posix simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.FilePath.Posix.Primitive whereopen import Agda.Builtin.Bool using (Bool)open import Agda.Builtin.Char using (Char)open import Agda.Builtin.List using (List)open import Agda.Builtin.Maybe using (Maybe)open import Agda.Builtin.String using (String)open import Foreign.Haskell as FFI using (Pair; Either)open import IO.Primitive.Core using (IO)-- A filepath has a nature: it can be either relative or absolute.-- We postulate this nature rather than defining it as an inductive-- type so that the user cannot inspect it. The only way to cast an-- arbitrary filepath nature @n@ to either @relative@ or @absolute@-- is to use @checkFilePath@.module Nature wherepostulateNature : Setrelative absolute unknown : Nature-- In the Haskell backend these @natures@ are simply erased as the-- libraries represent all filepaths in the same way.{-# FOREIGN GHC import Data.Kind #-}{-# COMPILE GHC Nature = type Type #-}{-# COMPILE GHC relative = type () #-}{-# COMPILE GHC absolute = type () #-}{-# COMPILE GHC unknown = type () #-}open Nature using (Nature) publicprivatevariablem n : NaturepostulateFilePath : Nature → SetgetFilePath : FilePath n → StringExtension : SetmkExtension : String → ExtensiongetExtension : Extension → String{-# FOREIGN GHC import Data.Text #-}{-# FOREIGN GHC import System.FilePath.Posix #-}{-# FOREIGN GHC type AgdaFilePath n = FilePath #-}{-# COMPILE GHC FilePath = type AgdaFilePath #-}{-# COMPILE GHC getFilePath = const pack #-}{-# COMPILE GHC Extension = type String #-}{-# COMPILE GHC mkExtension = unpack #-}{-# COMPILE GHC getExtension = pack #-}-- We provide convenient short names for the two types of filepathsAbsolutePath = FilePath Nature.absoluteRelativePath = FilePath Nature.relativeSomePath = FilePath Nature.unknown-- In order to prevent users from picking whether a string gets-- converted to a @relative@ or an @absolute@ path we have:-- * a postulated @unknown@ nature-- * a function @mkFilePath@ producing filepaths of this postulated naturepostulatemkFilePath : String → SomePath{-# COMPILE GHC mkFilePath = unpack #-}postulate-- Separator predicatespathSeparator : CharpathSeparators : List CharisPathSeparator : Char → BoolsearchPathSeparator : CharisSearchPathSeparator : Char → BoolextSeparator : CharisExtSeparator : Char → Bool-- $PATH methodssplitSearchPath : String → List SomePathgetSearchPath : IO (List SomePath)-- Extension functionssplitExtension : FilePath n → Pair (FilePath n) ExtensiontakeExtension : FilePath n → ExtensionreplaceExtension : FilePath n → Extension → FilePath ndropExtension : FilePath n → FilePath naddExtension : FilePath n → Extension → FilePath nhasExtension : FilePath n → BoolsplitExtensions : FilePath n → Pair (FilePath n) ExtensiontakeExtensions : FilePath n → ExtensionreplaceExtensions : FilePath n → Extension → FilePath ndropExtensions : FilePath n → FilePath nisExtensionOf : Extension → FilePath n → BoolstripExtension : Extension → FilePath n → Maybe (FilePath n)-- Filename/directory functionssplitFileName : FilePath n → Pair (FilePath n) RelativePathtakeFileName : FilePath n → StringreplaceFileName : FilePath n → String → FilePath ndropFileName : FilePath n → FilePath ntakeBaseName : FilePath n → StringreplaceBaseName : FilePath n → String → FilePath ntakeDirectory : FilePath n → FilePath nreplaceDirectory : FilePath m → FilePath n → FilePath ncombine : FilePath n → RelativePath → FilePath nsplitPath : FilePath n → List RelativePathjoinPath : List RelativePath → RelativePathsplitDirectories : FilePath n → List RelativePath-- Drive functionssplitDrive : FilePath n → Pair (FilePath n) RelativePathjoinDrive : FilePath n → RelativePath → FilePath ntakeDrive : FilePath n → FilePath nhasDrive : FilePath n → BooldropDrive : FilePath n → RelativePathisDrive : FilePath n → Bool-- Trailing slash functionshasTrailingPathSeparator : FilePath n → BooladdTrailingPathSeparator : FilePath n → FilePath ndropTrailingPathSeparator : FilePath n → FilePath n-- File name manipulationsnormalise : FilePath n → FilePath nequalFilePath : FilePath m → FilePath n → BoolmakeRelative : FilePath m → FilePath n → RelativePathcheckFilePath : FilePath n → Either RelativePath AbsolutePathisRelative : FilePath n → BoolisAbsolute : FilePath n → BoolisValid : FilePath n → BoolmakeValid : FilePath n → FilePath n{-# FOREIGN GHCcheckFilePath fp| isRelative fp = Left fp| otherwise = Right fp#-}{-# COMPILE GHC pathSeparator = pathSeparator #-}{-# COMPILE GHC pathSeparators = pathSeparators #-}{-# COMPILE GHC isPathSeparator = isPathSeparator #-}{-# COMPILE GHC searchPathSeparator = searchPathSeparator #-}{-# COMPILE GHC isSearchPathSeparator = isSearchPathSeparator #-}{-# COMPILE GHC extSeparator = extSeparator #-}{-# COMPILE GHC isExtSeparator = isExtSeparator #-}{-# COMPILE GHC splitSearchPath = splitSearchPath . unpack #-}{-# COMPILE GHC getSearchPath = getSearchPath #-}{-# COMPILE GHC splitExtension = const splitExtension #-}{-# COMPILE GHC takeExtension = const takeExtension #-}{-# COMPILE GHC replaceExtension = const replaceExtension #-}{-# COMPILE GHC dropExtension = const dropExtension #-}{-# COMPILE GHC addExtension = const addExtension #-}{-# COMPILE GHC hasExtension = const hasExtension #-}{-# COMPILE GHC splitExtensions = const splitExtensions #-}{-# COMPILE GHC takeExtensions = const takeExtensions #-}{-# COMPILE GHC replaceExtensions = const replaceExtensions #-}{-# COMPILE GHC dropExtensions = const dropExtensions #-}{-# COMPILE GHC isExtensionOf = const isExtensionOf #-}{-# COMPILE GHC stripExtension = const stripExtension #-}{-# COMPILE GHC splitFileName = const splitFileName #-}{-# COMPILE GHC takeFileName = const $ pack . takeFileName #-}{-# COMPILE GHC replaceFileName = const $ fmap (. unpack) replaceFileName #-}{-# COMPILE GHC dropFileName = const dropFileName #-}{-# COMPILE GHC takeBaseName = const $ pack . takeBaseName #-}{-# COMPILE GHC replaceBaseName = const $ fmap (. unpack) replaceBaseName #-}{-# COMPILE GHC takeDirectory = const takeDirectory #-}{-# COMPILE GHC replaceDirectory = \ _ _ -> replaceDirectory #-}{-# COMPILE GHC combine = const combine #-}{-# COMPILE GHC splitPath = const splitPath #-}{-# COMPILE GHC joinPath = joinPath #-}{-# COMPILE GHC splitDirectories = const splitDirectories #-}{-# COMPILE GHC splitDrive = const splitDrive #-}{-# COMPILE GHC joinDrive = const joinDrive #-}{-# COMPILE GHC takeDrive = const takeDrive #-}{-# COMPILE GHC hasDrive = const hasDrive #-}{-# COMPILE GHC dropDrive = const dropDrive #-}{-# COMPILE GHC isDrive = const isDrive #-}{-# COMPILE GHC hasTrailingPathSeparator = const hasTrailingPathSeparator #-}{-# COMPILE GHC addTrailingPathSeparator = const addTrailingPathSeparator #-}{-# COMPILE GHC dropTrailingPathSeparator = const dropTrailingPathSeparator #-}{-# COMPILE GHC normalise = const normalise #-}{-# COMPILE GHC equalFilePath = \ _ _ -> equalFilePath #-}{-# COMPILE GHC makeRelative = \ _ _ -> makeRelative #-}{-# COMPILE GHC isRelative = const isRelative #-}{-# COMPILE GHC isAbsolute = const isAbsolute #-}{-# COMPILE GHC checkFilePath = const checkFilePath #-}{-# COMPILE GHC isValid = const isValid #-}{-# COMPILE GHC makeValid = const makeValid #-}
-------------------------------------------------------------------------- The Agda standard library---- Exiting the program.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Exit whereopen import Level using (Level)open import Data.Bool.Base using (Bool; true; false; not)open import Data.Integer.Base using (ℤ; +_)open import Data.String.Base using (String)open import Function.Base using (_$_; _∘′_)open import IO using (IO; lift; _>>_; putStrLn)-------------------------------------------------------------------------- Re-exporting the ExitCode data structureopen import System.Exit.Primitive as Primpublicusing ( ExitCode; ExitSuccess; ExitFailure)-------------------------------------------------------------------------- TestsisSuccess : ExitCode → BoolisSuccess ExitSuccess = trueisSuccess (ExitFailure _) = falseisFailure : ExitCode → BoolisFailure = not ∘′ isSuccess-------------------------------------------------------------------------- Various exiting functionprivatevariablea : LevelA : Set aexitWith : ExitCode → IO AexitWith c = lift (Prim.exitWith c)exitFailure : IO AexitFailure = exitWith (ExitFailure (+ 1))exitSuccess : IO AexitSuccess = exitWith ExitSuccessdie : String → IO Adie str = doputStrLn strexitFailure
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Exit simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module System.Exit.Primitive whereopen import Agda.Builtin.Int using (Int)open import Agda.Builtin.IO using (IO)data ExitCode : Set whereExitSuccess : ExitCodeExitFailure : Int → ExitCode{-# FOREIGN GHC data AgdaExitCode = AgdaExitSuccess | AgdaExitFailure Integer #-}{-# COMPILE GHC ExitCode = data AgdaExitCode (AgdaExitSuccess | AgdaExitFailure) #-}{-# FOREIGN GHC import qualified System.Exit as SE #-}{-# FOREIGN GHCtoExitCode :: AgdaExitCode -> SE.ExitCodetoExitCode AgdaExitSuccess = SE.ExitSuccesstoExitCode (AgdaExitFailure n) = SE.ExitFailure (fromIntegral n)fromExitCode :: SE.ExitCode -> AgdaExitCodefromExitCode SE.ExitSuccess = AgdaExitSuccessfromExitCode (SE.ExitFailure n) = AgdaExitFailure (fromIntegral n)#-}postulateexitWith : ∀ {a} {A : Set a} → ExitCode → IO A{-# COMPILE GHC exitWith = \ _ _ -> SE.exitWith . toExitCode #-}
-------------------------------------------------------------------------- The Agda standard library---- Miscellanous information about the system environment------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Environment whereopen import IO using (IO; lift; run; ignore)open import Data.List.Base using (List)open import Data.Maybe.Base using (Maybe)open import Data.Product.Base using (_×_)open import Data.String.Base using (String)open import Data.Unit.Polymorphic using (⊤)open import Foreign.Haskell.Coerceimport System.Environment.Primitive as PrimgetArgs : IO (List String)getArgs = lift Prim.getArgsgetProgName : IO StringgetProgName = lift Prim.getProgNamelookupEnv : String → IO (Maybe String)lookupEnv var = lift (coerce (Prim.lookupEnv var))setEnv : String → String → IO ⊤setEnv var val = ignore (lift (Prim.setEnv var val))unsetEnv : String → IO ⊤unsetEnv var = ignore (lift (Prim.unsetEnv var))withArgs : ∀ {a} {A : Set a} → List String → IO A → IO AwithArgs args io = lift (Prim.withArgs args (run io))withProgName : ∀ {a} {A : Set a} → String → IO A → IO AwithProgName name io = lift (Prim.withProgName name (run io))getEnvironment : IO (List (String × String))getEnvironment = lift (coerce Prim.getEnvironment)
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Environment: simple bindings to Haskell functions---- Note that we currently leave out:-- * filepath-related functions (until we have a good representation of-- absolute vs. relative & directory vs. file)-- * functions that may fail with an exception-- e.g. we provide `lookupEnv` but not `getEnv`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module System.Environment.Primitive whereopen import IO.Primitive.Core using (IO)open import Data.List.Base using (List)open import Data.Maybe.Base using (Maybe)open import Data.String.Base using (String)open import Data.Unit.Base using (⊤)open import Foreign.Haskell.Pair using (Pair){-# FOREIGN GHC import qualified System.Environment as SE #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# FOREIGN GHC import Data.Bifunctor (bimap) #-}{-# FOREIGN GHC import Data.Function (on) #-}postulategetArgs : IO (List String)getProgName : IO StringlookupEnv : String → IO (Maybe String)setEnv : String → String → IO ⊤unsetEnv : String → IO ⊤withArgs : ∀ {a} {A : Set a} → List String → IO A → IO AwithProgName : ∀ {a} {A : Set a} → String → IO A → IO AgetEnvironment : IO (List (Pair String String)){-# COMPILE GHC getArgs = fmap (fmap T.pack) SE.getArgs #-}{-# COMPILE GHC getProgName = fmap T.pack SE.getProgName #-}{-# COMPILE GHC lookupEnv = fmap (fmap T.pack) . SE.lookupEnv . T.unpack #-}{-# COMPILE GHC setEnv = SE.setEnv `on` T.unpack #-}{-# COMPILE GHC unsetEnv = SE.unsetEnv . T.unpack #-}{-# COMPILE GHC withArgs = \ _ _ -> SE.withArgs . fmap T.unpack #-}{-# COMPILE GHC withProgName = \ _ _ -> SE.withProgName . T.unpack #-}{-# COMPILE GHC getEnvironment = fmap (fmap (bimap T.pack T.pack)) SE.getEnvironment #-}
-------------------------------------------------------------------------- The Agda standard library---- Directory manipulation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Directory whereopen import Levelopen import IO.Baseopen import Data.Unit.Polymorphic.Base using (⊤)open import Data.Bool.Base using (Bool)open import Data.List.Base using (List)open import Data.Maybe.Base using (Maybe)open import Data.Nat.Base using (ℕ)open import Data.String.Base using (String)open import Foreign.Haskell.Coerce using (coerce)open import Function.Base using (_∘′_)open import System.FilePath.Posix hiding (makeRelative)open import System.Directory.Primitive as Primpublicusing ( XdgDirectory; XdgData; XdgConfig; XdgCache; XdgDirectoryList; XdgDataDirs; XdgConfigDirs; exeExtension)privatevariablea : Levelm n : Nature-- Actions on directoriescreateDirectory : FilePath n → IO {a} ⊤createDirectoryIfMissing : Bool → FilePath n → IO {a} ⊤removeDirectory : FilePath n → IO {a} ⊤removeDirectoryRecursive : FilePath n → IO {a} ⊤removePathForcibly : FilePath n → IO {a} ⊤renameDirectory : FilePath n → FilePath n → IO {a} ⊤listDirectory : FilePath n → IO (List RelativePath)-- Current working directorygetDirectoryContents : FilePath n → IO (List RelativePath)getCurrentDirectory : IO AbsolutePathsetCurrentDirectory : FilePath n → IO {a} ⊤withCurrentDirectory : {A : Set a} → FilePath n → IO A → IO A-- Pre-defined directoriesgetHomeDirectory : IO AbsolutePathgetXdgDirectory : XdgDirectory → RelativePath → IO AbsolutePathgetXdgDirectoryList : XdgDirectoryList → IO (List AbsolutePath)getAppUserDataDirectory : RelativePath → IO AbsolutePathgetUserDocumentsDirectory : IO AbsolutePathgetTemporaryDirectory : IO AbsolutePath-- Action on filesremoveFile : FilePath m → IO {a} ⊤renameFile : FilePath m → FilePath n → IO {a} ⊤renamePath : FilePath m → FilePath n → IO {a} ⊤copyFile : FilePath m → FilePath n → IO {a} ⊤copyFileWithMetadata : FilePath m → FilePath n → IO {a} ⊤getFileSize : FilePath n → IO ℕcanonicalizePath : FilePath n → IO AbsolutePathmakeAbsolute : FilePath n → IO AbsolutePathmakeRelative : FilePath n → IO RelativePathtoKnownNature : KnownNature m → FilePath n → IO (FilePath m)toKnownNature absolute = makeAbsolutetoKnownNature relative = makeRelativerelativeToKnownNature : KnownNature n → RelativePath → IO (FilePath n)absoluteToKnownNature : KnownNature n → AbsolutePath → IO (FilePath n)relativeToKnownNature absolute = makeAbsoluterelativeToKnownNature relative = pureabsoluteToKnownNature absolute = pureabsoluteToKnownNature relative = makeRelative-- Existence testsdoesPathExist : FilePath n → IO BooldoesFileExist : FilePath n → IO BooldoesDirectoryExist : FilePath n → IO BoolfindExecutable : String → IO (Maybe AbsolutePath)findExecutables : String → IO (List AbsolutePath)findExecutablesInDirectories : List (FilePath n) → String → IO (List (FilePath n))findFile : List (FilePath n) → String → IO (Maybe (FilePath n))findFiles : List (FilePath n) → String → IO (List (FilePath n))findFileWith : (FilePath n → IO Bool) → List (FilePath n) → String → IO (Maybe (FilePath n))findFilesWith : (FilePath n → IO Bool) → List (FilePath n) → String → IO (List (FilePath n))-- Symbolic linkscreateFileLink : FilePath m → FilePath n → IO {a} ⊤createDirectoryLink : FilePath m → FilePath n → IO {a} ⊤removeDirectoryLink : FilePath n → IO {a} ⊤pathIsSymbolicLink : FilePath n → IO BoolgetSymbolicLinkTarget : FilePath n → IO SomePathcreateDirectory = lift! ∘′ lift ∘′ Prim.createDirectorycreateDirectoryIfMissing = λ b → lift! ∘′ lift ∘′ Prim.createDirectoryIfMissing bremoveDirectory = lift! ∘′ lift ∘′ Prim.removeDirectoryremoveDirectoryRecursive = lift! ∘′ lift ∘′ Prim.removeDirectoryRecursiveremovePathForcibly = lift! ∘′ lift ∘′ Prim.removePathForciblyrenameDirectory = λ fp → lift! ∘′ lift ∘′ Prim.renameDirectory fplistDirectory = lift ∘′ Prim.listDirectorygetDirectoryContents = lift ∘′ Prim.getDirectoryContentsgetCurrentDirectory = lift Prim.getCurrentDirectorysetCurrentDirectory = lift! ∘′ lift ∘′ Prim.setCurrentDirectorywithCurrentDirectory = λ fp ma → lift (Prim.withCurrentDirectory fp (run ma))getHomeDirectory = lift Prim.getHomeDirectorygetXdgDirectory = λ d fp → lift (Prim.getXdgDirectory d fp)getXdgDirectoryList = lift ∘′ Prim.getXdgDirectoryListgetAppUserDataDirectory = lift ∘′ Prim.getAppUserDataDirectorygetUserDocumentsDirectory = lift Prim.getUserDocumentsDirectorygetTemporaryDirectory = lift Prim.getTemporaryDirectoryremoveFile = lift! ∘′ lift ∘′ Prim.removeFilerenameFile = λ a b → lift! (lift (Prim.renameFile a b))renamePath = λ a b → lift! (lift (Prim.renamePath a b))copyFile = λ a b → lift! (lift (Prim.copyFile a b))copyFileWithMetadata = λ a b → lift! (lift (Prim.copyFileWithMetadata a b))getFileSize = lift ∘′ Prim.getFileSizecanonicalizePath = lift ∘′ Prim.canonicalizePathmakeAbsolute = lift ∘′ Prim.makeAbsolutemakeRelative = lift ∘′ Prim.makeRelativeToCurrentDirectorydoesPathExist = lift ∘′ Prim.doesPathExistdoesFileExist = lift ∘′ Prim.doesFileExistdoesDirectoryExist = lift ∘′ Prim.doesDirectoryExistfindExecutable = lift ∘′ coerce ∘′ Prim.findExecutablefindExecutables = lift ∘′ Prim.findExecutablesfindExecutablesInDirectories = λ fps str → lift (Prim.findExecutablesInDirectories fps str)findFile = λ fps str → lift (coerce Prim.findFile fps str)findFiles = λ fps str → lift (Prim.findFiles fps str)findFileWith = λ p fps str → lift (coerce Prim.findFileWith (run ∘′ p) fps str)findFilesWith = λ p fps str → lift (Prim.findFilesWith (run ∘′ p) fps str)createFileLink = λ fp → lift! ∘′ lift ∘′ Prim.createFileLink fpcreateDirectoryLink = λ fp → lift! ∘′ lift ∘′ Prim.createDirectoryLink fpremoveDirectoryLink = lift! ∘′ lift ∘′ Prim.removeDirectoryLinkpathIsSymbolicLink = lift ∘′ Prim.pathIsSymbolicLinkgetSymbolicLinkTarget = lift ∘′ Prim.getSymbolicLinkTarget
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Direcotry simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Directory.Primitive whereopen import Agda.Builtin.Unit using (⊤)open import Agda.Builtin.Bool using (Bool)open import Agda.Builtin.IO using (IO)open import Agda.Builtin.List using (List)open import Agda.Builtin.Maybe using (Maybe)open import Agda.Builtin.Nat using (Nat)open import Agda.Builtin.String using (String)open import System.FilePath.Posix.Primitive{-# FOREIGN GHC import System.Directory #-}{-# FOREIGN GHC import Data.Text #-}data XdgDirectory : Set whereXdgData XdgConfig XdgCache XdgState : XdgDirectorydata XdgDirectoryList : Set whereXdgDataDirs XdgConfigDirs : XdgDirectoryList{-# COMPILE GHC XdgDirectory = data XdgDirectory (XdgData|XdgConfig|XdgCache|XdgState) #-}{-# COMPILE GHC XdgDirectoryList = data XdgDirectoryList (XdgDataDirs|XdgConfigDirs) #-}privatevariablem n : Naturepostulate-- Actions on directoriescreateDirectory : FilePath n → IO ⊤createDirectoryIfMissing : Bool → FilePath n → IO ⊤removeDirectory : FilePath n → IO ⊤removeDirectoryRecursive : FilePath n → IO ⊤removePathForcibly : FilePath n → IO ⊤renameDirectory : FilePath m → FilePath n → IO ⊤listDirectory : FilePath n → IO (List RelativePath)getDirectoryContents : FilePath n → IO (List RelativePath)-- Current working directorygetCurrentDirectory : IO AbsolutePathsetCurrentDirectory : FilePath n → IO ⊤withCurrentDirectory : ∀ {a} {A : Set a} → FilePath n → IO A → IO A-- Pre-defined directoriesgetHomeDirectory : IO AbsolutePathgetXdgDirectory : XdgDirectory → RelativePath → IO AbsolutePathgetXdgDirectoryList : XdgDirectoryList → IO (List AbsolutePath)getAppUserDataDirectory : RelativePath → IO AbsolutePathgetUserDocumentsDirectory : IO AbsolutePathgetTemporaryDirectory : IO AbsolutePath-- Actions on filesremoveFile : FilePath m → IO ⊤renameFile : FilePath m → FilePath n → IO ⊤renamePath : FilePath m → FilePath n → IO ⊤copyFile : FilePath m → FilePath n → IO ⊤copyFileWithMetadata : FilePath m → FilePath n → IO ⊤getFileSize : FilePath n → IO NatcanonicalizePath : FilePath n → IO AbsolutePathmakeAbsolute : FilePath n → IO AbsolutePathmakeRelativeToCurrentDirectory : FilePath n → IO RelativePath-- Existence testsdoesPathExist : FilePath n → IO BooldoesFileExist : FilePath n → IO BooldoesDirectoryExist : FilePath n → IO BoolfindExecutable : String → IO (Maybe AbsolutePath)findExecutables : String → IO (List AbsolutePath)findExecutablesInDirectories : List (FilePath n) → String → IO (List (FilePath n))findFile : List (FilePath n) → String → IO (Maybe (FilePath n))findFiles : List (FilePath n) → String → IO (List (FilePath n))findFileWith : (FilePath n → IO Bool) → List (FilePath n) → String → IO (Maybe (FilePath n))findFilesWith : (FilePath n → IO Bool) → List (FilePath n) → String → IO (List (FilePath n))exeExtension : String-- Symbolic linkscreateFileLink : FilePath m → FilePath n → IO ⊤createDirectoryLink : FilePath m → FilePath n → IO ⊤removeDirectoryLink : FilePath n → IO ⊤pathIsSymbolicLink : FilePath n → IO BoolgetSymbolicLinkTarget : FilePath n → IO SomePath{-# COMPILE GHC createDirectory = const createDirectory #-}{-# COMPILE GHC createDirectoryIfMissing = const createDirectoryIfMissing #-}{-# COMPILE GHC removeDirectory = const removeDirectory #-}{-# COMPILE GHC removeDirectoryRecursive = const removeDirectoryRecursive #-}{-# COMPILE GHC removePathForcibly = const removePathForcibly #-}{-# COMPILE GHC renameDirectory = \ _ _ -> renameDirectory #-}{-# COMPILE GHC listDirectory = const listDirectory #-}{-# COMPILE GHC getDirectoryContents = const getDirectoryContents #-}{-# COMPILE GHC getCurrentDirectory = getCurrentDirectory #-}{-# COMPILE GHC setCurrentDirectory = const setCurrentDirectory #-}{-# COMPILE GHC withCurrentDirectory = \ _ _ _ -> withCurrentDirectory #-}{-# COMPILE GHC getHomeDirectory = getHomeDirectory #-}{-# COMPILE GHC getXdgDirectory = getXdgDirectory #-}{-# COMPILE GHC getXdgDirectoryList = getXdgDirectoryList #-}{-# COMPILE GHC getAppUserDataDirectory = getAppUserDataDirectory #-}{-# COMPILE GHC getUserDocumentsDirectory = getUserDocumentsDirectory #-}{-# COMPILE GHC getTemporaryDirectory = getTemporaryDirectory #-}{-# COMPILE GHC removeFile = const removeFile #-}{-# COMPILE GHC renameFile = \ _ _ -> renameFile #-}{-# COMPILE GHC renamePath = \ _ _ -> renamePath #-}{-# COMPILE GHC copyFile = \ _ _ -> copyFile #-}{-# COMPILE GHC copyFileWithMetadata = \ _ _ -> copyFileWithMetadata #-}{-# COMPILE GHC getFileSize = const getFileSize #-}{-# COMPILE GHC canonicalizePath = const canonicalizePath #-}{-# COMPILE GHC makeAbsolute = const makeAbsolute #-}{-# COMPILE GHC makeRelativeToCurrentDirectory = const makeRelativeToCurrentDirectory #-}{-# COMPILE GHC doesPathExist = const doesPathExist #-}{-# COMPILE GHC doesFileExist = const doesFileExist #-}{-# COMPILE GHC doesDirectoryExist = const doesDirectoryExist #-}{-# COMPILE GHC findExecutable = findExecutable . unpack #-}{-# COMPILE GHC findExecutables = findExecutables . unpack #-}{-# COMPILE GHC findExecutablesInDirectories = \ _ fps -> findExecutablesInDirectories fps . unpack #-}{-# COMPILE GHC findFile = \ _ fps -> findFile fps . unpack #-}{-# COMPILE GHC findFiles = \ _ fps -> findFiles fps . unpack #-}{-# COMPILE GHC findFileWith = \ _ p fps -> findFileWith p fps . unpack #-}{-# COMPILE GHC findFilesWith = \ _ p fps -> findFilesWith p fps . unpack #-}{-# COMPILE GHC exeExtension = pack exeExtension #-}{-# COMPILE GHC createFileLink = \ _ _ -> createFileLink #-}{-# COMPILE GHC createDirectoryLink = \ _ _ -> createDirectoryLink #-}{-# COMPILE GHC removeDirectoryLink = const removeDirectoryLink #-}{-# COMPILE GHC pathIsSymbolicLink = const pathIsSymbolicLink #-}{-# COMPILE GHC getSymbolicLinkTarget = const getSymbolicLinkTarget #-}
-------------------------------------------------------------------------- The Agda standard library---- ANSI escape codes------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module System.Console.ANSI whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.Nat.Base using (ℕ; _+_)import Data.Nat.Show as ℕ using (show)open import Data.String.Base using (String; concat; intersperse)open import Function.Base using (_$_; case_of_)data Layer : Set whereforeground background : Layerdata Colour : Set whereblack red green yellow blue magenta cyan white : Colourdata Intensity : Set whereclassic bright : Intensitydata Weight : Set wherebold faint normal : Weightdata Underlining : Set wheresingle double : Underliningdata Style : Set whereitalic straight : Styledata Blinking : Set whereslow rapid : Blinkingdata Command : Set wherereset : CommandsetColour : Layer → Intensity → Colour → CommandsetWeight : Weight → CommandsetStyle : Style → CommandsetUnderline : Underlining → CommandsetBlinking : Blinking → Commandprivateescape : String → Stringescape txt = concat $ "\x1b[" ∷ txt ∷ "m" ∷ []encode : Command → Stringencode reset = "0"encode (setColour l i c) = ℕ.show (layer l + colour c + intensity i)wherelayer : Layer → ℕlayer foreground = 30layer background = 40colour : Colour → ℕcolour black = 0colour red = 1colour green = 2colour yellow = 3colour blue = 4colour magenta = 5colour cyan = 6colour white = 7intensity : Intensity → ℕintensity classic = 0intensity bright = 60encode (setWeight w) = case w of λ wherebold → "1"faint → "2"normal → "22"encode (setStyle s) = case s of λ whereitalic → "3"straight → "23"encode (setUnderline i) = case i of λ wheresingle → "4"double → "21"encode (setBlinking b) = case b of λ whereslow → "5"rapid → "6"command : Command → Stringcommand c = escape (encode c)withCommand : Command → String → StringwithCommand c txt = concat (command c ∷ txt ∷ command reset ∷ [])commands : List Command → Stringcommands [] = command resetcommands cs = escape (intersperse ";" $ List.map encode cs)withCommands : List Command → String → StringwithCommands cs txt = concat (commands cs ∷ txt ∷ command reset ∷ [])
-------------------------------------------------------------------------- The Agda standard library---- Measuring time------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module System.Clock whereopen import Level using (Level; 0ℓ; Lift; lower)open import Data.Bool.Base using (if_then_else_)open import Data.Fin.Base using (Fin; toℕ)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _+_; _∸_; _^_; _<ᵇ_)import Data.Nat.Show as ℕ using (show)open import Data.Nat.DivMod using (_/_)import Data.Nat.Properties as ℕopen import Data.String.Base using (String; _++_; padLeft)open import IO.Baseopen import Function.Base using (_$_; _∘′_)open import Foreign.Haskell using (_,_)open import Relation.Nullary.Decidable using (False; fromWitnessFalse; toWitnessFalse)privatevariablea : LevelA : Set a-------------------------------------------------------------------------- Re-exporting the Clock data structureopen import System.Clock.Primitive as Primpublicusing ( Clock-- System-wide monotonic time since an arbitrary point in the past; monotonic-- System-wide real time since the Epoch; realTime-- Amount of execution time of the current process; processCPUTime-- Amount of execution time of the current OS thread; threadCPUTime-- A raw hardware version of Monotonic ignoring adjustments; monotonicRaw-- Linux-specific clocks-- Similar to Monotonic, includes time spent suspended; bootTime-- Faster but less precise alternative to Monotonic; monotonicCoarse-- Faster but less precise alternative to RealTime; realTimeCoarse)-------------------------------------------------------------------------- Defining a more convenient representationrecord Time : Set whereconstructor mkTimefield seconds : ℕnanoseconds : ℕopen Time public-------------------------------------------------------------------------- Reading the clockgetTime : Clock → IO TimegetTime c = do(a , b) ← lift (Prim.getTime c)pure $ mkTime a b-------------------------------------------------------------------------- Measuring time periodsdiff : Time → Time → Timediff (mkTime ss sns) (mkTime es ens) =if ens <ᵇ snsthen mkTime (es ∸ suc ss) ((1000000000 + ens) ∸ sns)else mkTime (es ∸ ss) (ens ∸ sns)record Timed (A : Set a) : Set a whereconstructor mkTimedfield value : Atime : Timetime : IO A → IO (Timed A)time io = dostart ← lift! $ getTime realTimea ← ioend ← lift! $ getTime realTimepure $ mkTimed a $ diff (lower start) (lower end)time′ : IO {0ℓ} A → IO Timetime′ io = Timed.time <$> time io-------------------------------------------------------------------------- Showing timeshow : Time → -- Time in seconds and nanosecondsFin 10 → -- Number of decimals to show-- (in [0,9] because we are using nanoseconds)Stringshow (mkTime s ns) prec = secs ++ "s" ++ padLeft '0' decimals nsecs wheredecimals = toℕ precsecs = ℕ.show sprf = ℕ.m^n≢0 10 (9 ∸ decimals)nsecs = ℕ.show ((ns / (10 ^ (9 ∸ decimals))) {{prf}})
-------------------------------------------------------------------------- The Agda standard library---- Primitive System.Clock simple bindings to Haskell functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module System.Clock.Primitive whereopen import Agda.Builtin.Nat using (Nat)open import IO.Primitive.Core using (IO)open import Foreign.Haskell using (Pair)data Clock : Set wheremonotonic realTime processCPUTime : ClockthreadCPUTime monotonicRaw bootTime : ClockmonotonicCoarse realTimeCoarse : Clock{-# COMPILE GHC Clock = data Clock (Monotonic | Realtime | ProcessCPUTime| ThreadCPUTime | MonotonicRaw | Boottime| MonotonicCoarse | RealtimeCoarse )#-}postulate getTime : Clock → IO (Pair Nat Nat){-# FOREIGN GHC import System.Clock #-}{-# FOREIGN GHC import Data.Function #-}{-# COMPILE GHC getTime = fmap (\ (TimeSpec a b) -> ((,) `on` fromIntegral) a b) . getTime #-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED, please use `Function.Strict` directly.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Strict where{-# WARNING_ON_IMPORT"Strict was deprecated in v1.8.Use `Function.Strict instead (also re-exported by `Function`)."#-}open import Function.Strict publicusing( force ; force-≡ ; force′ ; force′-≡; seq ; seq-≡)
-------------------------------------------------------------------------- The Agda standard library---- Sizes for Agda's sized types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Size whereopen import Level-------------------------------------------------------------------------- Re-export builtinsopen import Agda.Builtin.Size public using( SizeUniv -- sort SizeUniv; Size -- : SizeUniv; Size<_ -- : Size → SizeUniv; ↑_ -- : Size → Size; _⊔ˢ_ -- : Size → Size → Size; ∞ -- : Size)-------------------------------------------------------------------------- Concept of sized typeSizedSet : (ℓ : Level) → Set (suc ℓ)SizedSet ℓ = Size → Set ℓ
-------------------------------------------------------------------------- The Agda standard library---- Unary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary whereopen import Data.Empty using (⊥)open import Data.Unit.Base using (⊤)open import Data.Product.Base using (_×_; _,_; Σ-syntax; ∃; uncurry; swap)open import Data.Sum.Base using (_⊎_; [_,_])open import Function.Base using (_∘_; _|>_)open import Level using (Level; _⊔_; 0ℓ; suc; Lift)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Nullary as Nullary using (¬_; Dec; True)privatevariablea b c ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definition-- Unary relations are known as predicates and `Pred A ℓ` can be viewed-- as some property that elements of type A might satisfy.-- Consequently `P : Pred A ℓ` can also be seen as a subset of A-- containing all the elements of A that satisfy property P. This view-- informs much of the notation used below.Pred : ∀ {a} → Set a → (ℓ : Level) → Set (a ⊔ suc ℓ)Pred A ℓ = A → Set ℓ-------------------------------------------------------------------------- Special sets-- The empty set.-- Explicitly not level polymorphic as this often causes unsolved metas;-- see `Relation.Unary.Polymorphic` for a level-polymorphic version.∅ : Pred A 0ℓ∅ = λ _ → ⊥-- The singleton set.{_} : A → Pred A _{ x } = x ≡_-- The universal set.-- Explicitly not level polymorphic (see comments for `∅` for more details)U : Pred A 0ℓU = λ _ → ⊤-------------------------------------------------------------------------- Membershipinfix 4 _∈_ _∉__∈_ : A → Pred A ℓ → Set _x ∈ P = P x_∉_ : A → Pred A ℓ → Set _x ∉ P = ¬ x ∈ P-------------------------------------------------------------------------- Subset relationsinfix 4 _⊆_ _⊇_ _⊈_ _⊉_ _⊂_ _⊃_ _⊄_ _⊅_ _≐_ _≐′__⊆_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊆ Q = ∀ {x} → x ∈ P → x ∈ Q_⊇_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊇ Q = Q ⊆ P_⊈_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊈ Q = ¬ (P ⊆ Q)_⊉_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊉ Q = ¬ (P ⊇ Q)_⊂_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊂ Q = P ⊆ Q × Q ⊈ P_⊃_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊃ Q = Q ⊂ P_⊄_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊄ Q = ¬ (P ⊂ Q)_⊅_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊅ Q = ¬ (P ⊃ Q)_≐_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ≐ Q = (P ⊆ Q) × (Q ⊆ P)-- The following primed variants of _⊆_ can be used when 'x' can't-- be inferred from 'x ∈ P'.infix 4 _⊆′_ _⊇′_ _⊈′_ _⊉′_ _⊂′_ _⊃′_ _⊄′_ _⊅′__⊆′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊆′ Q = ∀ x → x ∈ P → x ∈ Q_⊇′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _Q ⊇′ P = P ⊆′ Q_⊈′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊈′ Q = ¬ (P ⊆′ Q)_⊉′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊉′ Q = ¬ (P ⊇′ Q)_⊂′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊂′ Q = P ⊆′ Q × Q ⊈′ P_⊃′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊃′ Q = Q ⊂′ P_⊄′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊄′ Q = ¬ (P ⊂′ Q)_⊅′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ⊅′ Q = ¬ (P ⊃′ Q)_≐′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ≐′ Q = (P ⊆′ Q) × (Q ⊆′ P)-------------------------------------------------------------------------- Properties of setsinfix 10 Satisfiable Universal IUniversal-- Emptiness - no element satisfies P.Empty : Pred A ℓ → Set _Empty P = ∀ x → x ∉ P-- Satisfiable - at least one element satisfies P.Satisfiable : Pred A ℓ → Set _Satisfiable P = ∃ λ x → x ∈ Psyntax Satisfiable P = ∃⟨ P ⟩-- Universality - all elements satisfy P.Universal : Pred A ℓ → Set _Universal P = ∀ x → x ∈ Psyntax Universal P = Π[ P ]-- Implicit universality - all elements satisfy P.IUniversal : Pred A ℓ → Set _IUniversal P = ∀ {x} → x ∈ Psyntax IUniversal P = ∀[ P ]-- Irrelevance - any two proofs that an element satifies P are-- indistinguishable.Irrelevant : Pred A ℓ → Set _Irrelevant P = ∀ {x} → Nullary.Irrelevant (P x)-- Recomputability - we can rebuild a relevant proof given an-- irrelevant one.Recomputable : Pred A ℓ → Set _Recomputable P = ∀ {x} → Nullary.Recomputable (P x)-- Stability - instances of P are stable wrt double negationStable : Pred A ℓ → Set _Stable P = ∀ x → Nullary.Stable (P x)-- Weak DecidabilityWeaklyDecidable : Pred A ℓ → Set _WeaklyDecidable P = ∀ x → Nullary.WeaklyDecidable (P x)-- Decidability - it is possible to determine if an arbitrary element-- satisfies P.Decidable : Pred A ℓ → Set _Decidable P = ∀ x → Dec (P x)-- Erasure: A decidable predicate gives rise to another one, more-- amenable to η-expansion⌊_⌋ : {P : Pred A ℓ} → Decidable P → Pred A ℓ⌊ P? ⌋ a = Lift _ (True (P? a))-------------------------------------------------------------------------- Operations on setsinfix 10 ⋃ ⋂infixr 9 _⊢_infixr 8 _⇒_infixr 7 _∩_infixr 6 _∪_infixr 6 _∖_infix 4 _≬_-- Complement.∁ : Pred A ℓ → Pred A ℓ∁ P = λ x → x ∉ P-- Implication._⇒_ : Pred A ℓ₁ → Pred A ℓ₂ → Pred A _P ⇒ Q = λ x → x ∈ P → x ∈ Q-- Union._∪_ : Pred A ℓ₁ → Pred A ℓ₂ → Pred A _P ∪ Q = λ x → x ∈ P ⊎ x ∈ Q-- Intersection._∩_ : Pred A ℓ₁ → Pred A ℓ₂ → Pred A _P ∩ Q = λ x → x ∈ P × x ∈ Q-- Difference._∖_ : Pred A ℓ₁ → Pred A ℓ₂ → Pred A _P ∖ Q = λ x → x ∈ P × x ∉ Q-- Infinitary union.⋃ : ∀ {i} (I : Set i) → (I → Pred A ℓ) → Pred A _⋃ I P = λ x → Σ[ i ∈ I ] P i xsyntax ⋃ I (λ i → P) = ⋃[ i ∶ I ] P-- Infinitary intersection.⋂ : ∀ {i} (I : Set i) → (I → Pred A ℓ) → Pred A _⋂ I P = λ x → (i : I) → P i xsyntax ⋂ I (λ i → P) = ⋂[ i ∶ I ] P-- Positive version of non-disjointness, dual to inclusion._≬_ : Pred A ℓ₁ → Pred A ℓ₂ → Set _P ≬ Q = ∃ λ x → x ∈ P × x ∈ Q-- Update._⊢_ : (A → B) → Pred B ℓ → Pred A ℓf ⊢ P = λ x → P (f x)-------------------------------------------------------------------------- Predicate combinators-- These differ from the set operations above, as the carrier set of the-- resulting predicates are not the same as the carrier set of the-- component predicates.infixr 2 _⟨×⟩_infixr 2 _⟨⊙⟩_infixr 1 _⟨⊎⟩_infixr 0 _⟨→⟩_infixl 9 _⟨·⟩_infix 10 _~infixr 9 _⟨∘⟩_infixr 2 _//_ _\\_-- Product._⟨×⟩_ : Pred A ℓ₁ → Pred B ℓ₂ → Pred (A × B) _(P ⟨×⟩ Q) (x , y) = x ∈ P × y ∈ Q-- Sum over one element._⟨⊎⟩_ : Pred A ℓ → Pred B ℓ → Pred (A ⊎ B) _P ⟨⊎⟩ Q = [ P , Q ]-- Sum over two elements._⟨⊙⟩_ : Pred A ℓ₁ → Pred B ℓ₂ → Pred (A × B) _(P ⟨⊙⟩ Q) (x , y) = x ∈ P ⊎ y ∈ Q-- Implication._⟨→⟩_ : Pred A ℓ₁ → Pred B ℓ₂ → Pred (A → B) _(P ⟨→⟩ Q) f = P ⊆ Q ∘ f-- Product._⟨·⟩_ : (P : Pred A ℓ₁) (Q : Pred B ℓ₂) →(P ⟨×⟩ (P ⟨→⟩ Q)) ⊆ Q ∘ uncurry _|>_(P ⟨·⟩ Q) (p , f) = f p-- Converse._~ : Pred (A × B) ℓ → Pred (B × A) ℓP ~ = P ∘ swap-- Composition._⟨∘⟩_ : Pred (A × B) ℓ₁ → Pred (B × C) ℓ₂ → Pred (A × C) _(P ⟨∘⟩ Q) (x , z) = ∃ λ y → (x , y) ∈ P × (y , z) ∈ Q-- Post-division._//_ : Pred (A × C) ℓ₁ → Pred (B × C) ℓ₂ → Pred (A × B) _(P // Q) (x , y) = Q ∘ (y ,_) ⊆ P ∘ (x ,_)-- Pre-division._\\_ : Pred (A × C) ℓ₁ → Pred (A × B) ℓ₂ → Pred (B × C) _P \\ Q = (P ~ // Q ~) ~
-------------------------------------------------------------------------- The Agda standard library---- Indexed unary relations over sized types-------------------------------------------------------------------------- Sized types live in the special sort `SizeUniv` and therefore are no-- longer compatible with the ordinary combinators defined in-- `Relation.Unary`.{-# OPTIONS --cubical-compatible --sized-types #-}module Relation.Unary.Sized whereopen import Levelopen import Sizeprivatevariableℓ ℓ₁ ℓ₂ : Levelinfixr 8 _⇒__⇒_ : SizedSet ℓ₁ → SizedSet ℓ₂ → SizedSet (ℓ₁ ⊔ ℓ₂)F ⇒ G = λ i → F i → G i∀[_] : SizedSet ℓ → Set ℓ∀[ F ] = ∀{i} → F i
-------------------------------------------------------------------------- The Agda standard library---- Order properties of the subset relations _⊆_ and _⊂_------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Relation.Binary.Subset whereopen import Level using (Level)import Relation.Binary.Structures as BinaryStructuresopen import Relation.Binary.Bundlesopen import Relation.Unaryopen import Relation.Unary.Propertiesopen import Relation.Unary.Relation.Binary.Equality using (≐-isEquivalence; ≐′-isEquivalence)-------------------------------------------------------------------------- Structuresmodule _ {a : Level} {A : Set a} {ℓ : Level} whereopen BinaryStructures {A = Pred A ℓ} _≐_⊆-isPreorder : IsPreorder _⊆_⊆-isPreorder = record{ isEquivalence = ≐-isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-isPartialOrder : IsPartialOrder _⊆_⊆-isPartialOrder = record{ isPreorder = ⊆-isPreorder; antisym = ⊆-antisym}⊂-isStrictPartialOrder : IsStrictPartialOrder _⊂_⊂-isStrictPartialOrder = record{ isEquivalence = ≐-isEquivalence; irrefl = ⊂-irrefl; trans = ⊂-trans; <-resp-≈ = ⊂-resp-≐}module _ {a : Level} {A : Set a} {ℓ : Level} whereopen BinaryStructures {A = Pred A ℓ} _≐′_⊆′-isPreorder : IsPreorder _⊆′_⊆′-isPreorder = record{ isEquivalence = ≐′-isEquivalence; reflexive = ⊆′-reflexive; trans = ⊆′-trans}⊆′-isPartialOrder : IsPartialOrder _⊆′_⊆′-isPartialOrder = record{ isPreorder = ⊆′-isPreorder; antisym = ⊆′-antisym}⊂′-isStrictPartialOrder : IsStrictPartialOrder _⊂′_⊂′-isStrictPartialOrder = record{ isEquivalence = ≐′-isEquivalence; irrefl = ⊂′-irrefl; trans = ⊂′-trans; <-resp-≈ = ⊂′-resp-≐′}-------------------------------------------------------------------------- Bundlesmodule _ {a : Level} (A : Set a) (ℓ : Level) where⊆-preorder : Preorder _ _ _⊆-preorder = record{ isPreorder = ⊆-isPreorder {A = A} {ℓ}}⊆-poset : Poset _ _ _⊆-poset = record{ isPartialOrder = ⊆-isPartialOrder {A = A} {ℓ}}⊂-strictPartialOrder : StrictPartialOrder _ _ _⊂-strictPartialOrder = record{ isStrictPartialOrder = ⊂-isStrictPartialOrder {A = A} {ℓ}}⊆′-preorder : Preorder _ _ _⊆′-preorder = record{ isPreorder = ⊆′-isPreorder {A = A} {ℓ}}⊆′-poset : Poset _ _ _⊆′-poset = record{ isPartialOrder = ⊆′-isPartialOrder {A = A} {ℓ}}⊂′-strictPartialOrder : StrictPartialOrder _ _ _⊂′-strictPartialOrder = record{ isStrictPartialOrder = ⊂′-isStrictPartialOrder {A = A} {ℓ}}
-------------------------------------------------------------------------- The Agda standard library---- Equality of unary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Relation.Binary.Equality whereopen import Level using (Level)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Unary using (Pred; _≐_; _≐′_)open import Relation.Unary.Propertiesprivatevariablea ℓ : LevelA : Set a≐-isEquivalence : IsEquivalence {A = Pred A ℓ} _≐_≐-isEquivalence = record{ refl = ≐-refl; sym = ≐-sym; trans = ≐-trans}≐′-isEquivalence : IsEquivalence {A = Pred A ℓ} _≐′_≐′-isEquivalence = record{ refl = ≐′-refl; sym = ≐′-sym; trans = ≐′-trans}≐-setoid : ∀ {a} (A : Set a) ℓ → Setoid _ _≐-setoid A ℓ = record{ isEquivalence = ≐-isEquivalence {A = A} {ℓ}}≐′-setoid : ∀ {a} (A : Set a) ℓ → Setoid _ _≐′-setoid A ℓ = record{ isEquivalence = ≐′-isEquivalence {A = A} {ℓ}}
-------------------------------------------------------------------------- The Agda standard library---- Properties of constructions over unary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Properties whereopen import Data.Product.Base as Product using (_×_; _,_; swap; proj₁; zip′)open import Data.Sum.Base using (inj₁; inj₂)open import Data.Unit.Base using (tt)open import Level using (Level)open import Relation.Binary.Core as Binaryopen import Relation.Binary.Definitionshiding (Decidable; Universal; Irrelevant; Empty)open import Relation.Binary.PropositionalEquality.Core using (refl)open import Relation.Unaryopen import Relation.Nullary.Decidable using (yes; no; _⊎-dec_; _×-dec_; ¬?)open import Function.Base using (id; _$_; _∘_)privatevariablea b ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA : Set aB : Set b-------------------------------------------------------------------------- The empty set∅? : Decidable {A = A} ∅∅? _ = no λ()∅-Empty : Empty {A = A} ∅∅-Empty x ()∁∅-Universal : Universal {A = A} (∁ ∅)∁∅-Universal = λ x x∈∅ → x∈∅-------------------------------------------------------------------------- The universeU? : Decidable {A = A} UU? _ = yes ttU-Universal : Universal {A = A} UU-Universal = λ _ → _∁U-Empty : Empty {A = A} (∁ U)∁U-Empty = λ x x∈∁U → x∈∁U _-------------------------------------------------------------------------- Subset properties∅-⊆ : (P : Pred A ℓ) → ∅ ⊆ P∅-⊆ P ()⊆-U : (P : Pred A ℓ) → P ⊆ U⊆-U P _ = _⊆-refl : Reflexive {A = Pred A ℓ} _⊆_⊆-refl x∈P = x∈P⊆-reflexive : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐_ _⊆_⊆-reflexive (P⊆Q , Q⊆P) = P⊆Q⊆-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊆_ _⊆_ _⊆_⊆-trans P⊆Q Q⊆R x∈P = Q⊆R (P⊆Q x∈P)⊆-antisym : Antisymmetric {A = Pred A ℓ} _≐_ _⊆_⊆-antisym = _,_⊆-min : Min {B = Pred A ℓ} _⊆_ ∅⊆-min = ∅-⊆⊆-max : Max {A = Pred A ℓ} _⊆_ U⊆-max = ⊆-U⊂⇒⊆ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂_ _⊆_⊂⇒⊆ = proj₁⊂-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊂_ _⊂_ _⊂_⊂-trans (P⊆Q , Q⊈P) (Q⊆R , R⊈Q) = (λ x∈P → Q⊆R (P⊆Q x∈P)) , (λ R⊆P → R⊈Q (λ x∈R → P⊆Q (R⊆P x∈R)))⊂-⊆-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊂_ _⊆_ _⊂_⊂-⊆-trans (P⊆Q , Q⊈P) Q⊆R = (λ x∈P → Q⊆R (P⊆Q x∈P)) , (λ R⊆P → Q⊈P (λ x∈Q → R⊆P (Q⊆R x∈Q)))⊆-⊂-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊆_ _⊂_ _⊂_⊆-⊂-trans P⊆Q (Q⊆R , R⊈Q) = (λ x∈P → Q⊆R (P⊆Q x∈P)) , (λ R⊆P → R⊈Q (λ R⊆Q → P⊆Q (R⊆P R⊆Q)))⊂-respʳ-≐ : _Respectsʳ_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂_ _≐_⊂-respʳ-≐ (Q⊆R , _) P⊂Q = ⊂-⊆-trans P⊂Q Q⊆R⊂-respˡ-≐ : _Respectsˡ_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂_ _≐_⊂-respˡ-≐ (_ , R⊆Q) P⊂Q = ⊆-⊂-trans R⊆Q P⊂Q⊂-resp-≐ : _Respects₂_ {A = Pred A ℓ} _⊂_ _≐_⊂-resp-≐ = ⊂-respʳ-≐ , ⊂-respˡ-≐⊂-irrefl : Irreflexive {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐_ _⊂_⊂-irrefl (_ , Q⊆P) (_ , Q⊈P) = Q⊈P Q⊆P⊂-antisym : Antisymmetric {A = Pred A ℓ} _≐_ _⊂_⊂-antisym (P⊆Q , _) (Q⊆P , _) = ⊆-antisym P⊆Q Q⊆P⊂-asym : Asymmetric {A = Pred A ℓ} _⊂_⊂-asym (_ , Q⊈P) = Q⊈P ∘ proj₁∅-⊆′ : (P : Pred A ℓ) → ∅ ⊆′ P∅-⊆′ _ _ = λ ()⊆′-U : (P : Pred A ℓ) → P ⊆′ U⊆′-U _ _ _ = _⊆′-refl : Reflexive {A = Pred A ℓ} _⊆′_⊆′-refl x x∈P = x∈P⊆′-reflexive : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐′_ _⊆′_⊆′-reflexive (P⊆Q , Q⊆P) = P⊆Q⊆′-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊆′_ _⊆′_ _⊆′_⊆′-trans P⊆Q Q⊆R x x∈P = Q⊆R x (P⊆Q x x∈P)⊆′-antisym : Antisymmetric {A = Pred A ℓ} _≐′_ _⊆′_⊆′-antisym = _,_⊆′-min : Min {B = Pred A ℓ} _⊆′_ ∅⊆′-min = ∅-⊆′⊆′-max : Max {A = Pred A ℓ} _⊆′_ U⊆′-max = ⊆′-U⊂′⇒⊆′ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂′_ _⊆′_⊂′⇒⊆′ = proj₁⊂′-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊂′_ _⊂′_ _⊂′_⊂′-trans (P⊆Q , Q⊈P) (Q⊆R , R⊈Q) = ⊆′-trans P⊆Q Q⊆R , λ R⊆P → R⊈Q (⊆′-trans R⊆P P⊆Q)⊂′-⊆′-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊂′_ _⊆′_ _⊂′_⊂′-⊆′-trans (P⊆Q , Q⊈P) Q⊆R = ⊆′-trans P⊆Q Q⊆R , λ R⊆P → Q⊈P (⊆′-trans Q⊆R R⊆P)⊆′-⊂′-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _⊆′_ _⊂′_ _⊂′_⊆′-⊂′-trans P⊆Q (Q⊆R , R⊈Q) = ⊆′-trans P⊆Q Q⊆R , λ R⊆P → R⊈Q (⊆′-trans R⊆P P⊆Q)⊂′-respʳ-≐′ : _Respectsʳ_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂′_ _≐′_⊂′-respʳ-≐′ (Q⊆R , _) P⊂Q = ⊂′-⊆′-trans P⊂Q Q⊆R⊂′-respˡ-≐′ : _Respectsˡ_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂′_ _≐′_⊂′-respˡ-≐′ (_ , R⊆Q) P⊂Q = ⊆′-⊂′-trans R⊆Q P⊂Q⊂′-resp-≐′ : _Respects₂_ {A = Pred A ℓ₁} _⊂′_ _≐′_⊂′-resp-≐′ = ⊂′-respʳ-≐′ , ⊂′-respˡ-≐′⊂′-irrefl : Irreflexive {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐′_ _⊂′_⊂′-irrefl (_ , Q⊆P) (_ , Q⊈P) = Q⊈P Q⊆P⊂′-antisym : Antisymmetric {A = Pred A ℓ} _≐′_ _⊂′_⊂′-antisym (P⊆Q , _) (Q⊆P , _) = ⊆′-antisym P⊆Q Q⊆P⊆⇒⊆′ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆_ _⊆′_⊆⇒⊆′ P⊆Q _ x∈P = P⊆Q x∈P⊆′⇒⊆ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆′_ _⊆_⊆′⇒⊆ P⊆Q x∈P = P⊆Q _ x∈P⊂⇒⊂′ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂_ _⊂′_⊂⇒⊂′ = Product.map ⊆⇒⊆′ (_∘ ⊆′⇒⊆)⊂′⇒⊂ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊂′_ _⊂_⊂′⇒⊂ = Product.map ⊆′⇒⊆ (_∘ ⊆⇒⊆′)-------------------------------------------------------------------------- Equality properties≐-refl : Reflexive {A = Pred A ℓ} _≐_≐-refl = id , id≐-sym : Sym {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐_ _≐_≐-sym = swap≐-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _≐_ _≐_ _≐_≐-trans = zip′ (λ P⊆Q Q⊆R x∈P → Q⊆R (P⊆Q x∈P)) (λ Q⊆P R⊆Q x∈R → Q⊆P (R⊆Q x∈R))≐′-refl : Reflexive {A = Pred A ℓ} _≐′_≐′-refl = (λ _ → id) , (λ _ → id)≐′-sym : Sym {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐′_ _≐′_≐′-sym = swap≐′-trans : Trans {A = Pred A ℓ₁} {B = Pred A ℓ₂} {C = Pred A ℓ₃} _≐′_ _≐′_ _≐′_≐′-trans = zip′ (λ P⊆Q Q⊆R x x∈P → Q⊆R x (P⊆Q x x∈P)) λ Q⊆P R⊆Q x x∈R → Q⊆P x (R⊆Q x x∈R)≐⇒≐′ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐_ _≐′_≐⇒≐′ = Product.map ⊆⇒⊆′ ⊆⇒⊆′≐′⇒≐ : Binary._⇒_ {A = Pred A ℓ₁} {B = Pred A ℓ₂} _≐′_ _≐_≐′⇒≐ = Product.map ⊆′⇒⊆ ⊆′⇒⊆-------------------------------------------------------------------------- Decidability properties∁? : {P : Pred A ℓ} → Decidable P → Decidable (∁ P)∁? P? x = ¬? (P? x)infix 2 _×?_ _⊙?_infix 10 _~?infixr 1 _⊎?_infixr 7 _∩?_infixr 6 _∪?__∪?_ : {P : Pred A ℓ₁} {Q : Pred A ℓ₂} →Decidable P → Decidable Q → Decidable (P ∪ Q)_∪?_ P? Q? x = (P? x) ⊎-dec (Q? x)_∩?_ : {P : Pred A ℓ₁} {Q : Pred A ℓ₂} →Decidable P → Decidable Q → Decidable (P ∩ Q)_∩?_ P? Q? x = (P? x) ×-dec (Q? x)_×?_ : {P : Pred A ℓ₁} {Q : Pred B ℓ₂} →Decidable P → Decidable Q → Decidable (P ⟨×⟩ Q)_×?_ P? Q? (a , b) = (P? a) ×-dec (Q? b)_⊙?_ : {P : Pred A ℓ₁} {Q : Pred B ℓ₂} →Decidable P → Decidable Q → Decidable (P ⟨⊙⟩ Q)_⊙?_ P? Q? (a , b) = (P? a) ⊎-dec (Q? b)_⊎?_ : {P : Pred A ℓ} {Q : Pred B ℓ} →Decidable P → Decidable Q → Decidable (P ⟨⊎⟩ Q)_⊎?_ P? Q? (inj₁ a) = P? a_⊎?_ P? Q? (inj₂ b) = Q? b_~? : {P : Pred (A × B) ℓ} → Decidable P → Decidable (P ~)_~? P? = P? ∘ swap-------------------------------------------------------------------------- Irrelevant propertiesU-irrelevant : Irrelevant {A = A} UU-irrelevant a b = refl∁-irrelevant : (P : Pred A ℓ) → Irrelevant (∁ P)∁-irrelevant P a b = refl
-------------------------------------------------------------------------- The Agda standard library---- Predicate transformers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.PredicateTransformer whereopen import Data.Product.Base using (∃)open import Function.Base using (_∘_)open import Level hiding (_⊔_)open import Relation.Nullaryopen import Relation.Unaryopen import Relation.Binary.Core using (REL)privatevariablea b c i ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Heterogeneous and homogeneous predicate transformersPT : Set a → Set b → (ℓ₁ ℓ₂ : Level) → Set _PT A B ℓ₁ ℓ₂ = Pred A ℓ₁ → Pred B ℓ₂Pt : Set a → (ℓ : Level) → Set _Pt A ℓ = PT A A ℓ ℓ-------------------------------------------------------------------------- Composition and identityinfixr 9 _⍮__⍮_ : PT B C ℓ₂ ℓ₃ → PT A B ℓ₁ ℓ₂ → PT A C ℓ₁ _S ⍮ T = S ∘ Tskip : PT A A ℓ ℓskip P = P-------------------------------------------------------------------------- Operations on predicates extend pointwise to predicate transformers-- The bottom and the top of the predicate transformer lattice.abort : PT A B 0ℓ 0ℓabort = λ _ → ∅magic : PT A B 0ℓ 0ℓmagic = λ _ → U-- Negation.infix 8 ∼_∼_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂∼ T = ∁ ∘ T-- Refinement.infix 4 _⊑_ _⊒_ _⊑′_ _⊒′__⊑_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → Set _S ⊑ T = ∀ {X} → S X ⊆ T X_⊑′_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → Set _S ⊑′ T = ∀ X → S X ⊆ T X_⊒_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → Set _T ⊒ S = T ⊑ S_⊒′_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → Set _T ⊒′ S = S ⊑′ T-- The dual of refinement.infix 4 _⋢__⋢_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → Set _S ⋢ T = ∃ λ X → S X ≬ T X-- Union.infixl 6 _⊓__⊓_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂S ⊓ T = λ X → S X ∪ T X-- Intersection.infixl 7 _⊔__⊔_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂S ⊔ T = λ X → S X ∩ T X-- Implication.infixl 8 _⇛__⇛_ : PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂ → PT A B ℓ₁ ℓ₂S ⇛ T = λ X → S X ⇒ T X-- Infinitary union and intersection.infix 9 ⨆ ⨅⨆ : ∀ (I : Set i) → (I → PT A B ℓ₁ ℓ₂) → PT A B ℓ₁ _⨆ I T = λ X → ⋃[ i ∶ I ] T i Xsyntax ⨆ I (λ i → T) = ⨆[ i ∶ I ] T⨅ : ∀ (I : Set i) → (I → PT A B ℓ₁ ℓ₂) → PT A B ℓ₁ _⨅ I T = λ X → ⋂[ i ∶ I ] T i Xsyntax ⨅ I (λ i → T) = ⨅[ i ∶ I ] T-- Angelic and demonic update.⟨_⟩ : REL A B ℓ → PT B A ℓ _⟨ R ⟩ P = λ x → R x ≬ P[_] : REL A B ℓ → PT B A ℓ _[ R ] P = λ x → R x ⊆ P
-------------------------------------------------------------------------- The Agda standard library---- Polymorphic versions of standard definitions in Relation.Unary------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Polymorphic whereopen import Data.Empty.Polymorphic using (⊥)open import Data.Unit.Polymorphic using (⊤)open import Level using (Level)open import Relation.Unary using (Pred)privatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Special sets-- The empty set.∅ : Pred A ℓ∅ = λ _ → ⊥-- The universal set.U : Pred A ℓU = λ _ → ⊤
-------------------------------------------------------------------------- The Agda standard library---- Properties of polymorphic versions of standard definitions in-- Relation.Unary------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Polymorphic.Properties whereopen import Level using (Level)open import Relation.Binary.Definitions hiding (Decidable; Universal; Empty)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Unary hiding (∅; U)open import Relation.Unary.Polymorphicopen import Data.Unit.Polymorphic.Base using (tt)privatevariablea ℓ ℓ₁ ℓ₂ : LevelA : Set a-------------------------------------------------------------------------- The empty set∅? : Decidable {A = A} {ℓ} ∅∅? _ = no λ()∅-Empty : Empty {A = A} {ℓ} ∅∅-Empty _ ()∁∅-Universal : Universal {A = A} {ℓ} (∁ ∅)∁∅-Universal _ ()-------------------------------------------------------------------------- The universeU? : Decidable {A = A} {ℓ} UU? _ = yes ttU-Universal : Universal {A = A} {ℓ} UU-Universal _ = _∁U-Empty : Empty {A = A} {ℓ} (∁ U)∁U-Empty _ x∈∁U = x∈∁U _-------------------------------------------------------------------------- Subset properties∅-⊆ : (P : Pred A ℓ₁) → ∅ {ℓ = ℓ₂} ⊆ P∅-⊆ _ ()⊆-U : (P : Pred A ℓ₁) → P ⊆ U {ℓ = ℓ₂}⊆-U _ _ = _⊆-min : Min {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆_ ∅⊆-min = ∅-⊆⊆-max : Max {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆_ U⊆-max = ⊆-U∅-⊆′ : (P : Pred A ℓ₁) → ∅ {ℓ = ℓ₂} ⊆′ P∅-⊆′ _ _ = λ ()⊆′-U : (P : Pred A ℓ₁) → P ⊆′ U {ℓ = ℓ₂}⊆′-U _ _ _ = _⊆′-min : Min {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆′_ ∅⊆′-min = ∅-⊆′⊆′-max : Max {A = Pred A ℓ₁} {B = Pred A ℓ₂} _⊆′_ U⊆′-max = ⊆′-U
-------------------------------------------------------------------------- The Agda standard library---- Indexed unary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Indexed whereopen import Data.Product.Base using (∃; _×_)open import Levelopen import Relation.Nullary.Negation using (¬_)IPred : ∀ {i a} {I : Set i} → (I → Set a) → (ℓ : Level) → Set _IPred A ℓ = ∀ {i} → A i → Set ℓmodule _ {i a} {I : Set i} {A : I → Set a} whereinfix 4 _∈_ _∉__∈_ : ∀ {ℓ} → (∀ i → A i) → IPred A ℓ → Set _x ∈ P = ∀ i → P (x i)_∉_ : ∀ {ℓ} → (∀ i → A i) → IPred A ℓ → Set _t ∉ P = ¬ (t ∈ P)
-------------------------------------------------------------------------- The Agda standard library---- Some properties imply others------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Consequences whereopen import Relation.Unaryopen import Relation.Nullary using (recompute)dec⇒recomputable : {a ℓ : _} {A : Set a} {P : Pred A ℓ} → Decidable P → Recomputable Pdec⇒recomputable P-dec = recompute (P-dec _)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0dec⟶recomputable = dec⇒recomputable{-# WARNING_ON_USAGE dec⟶recomputable"Warning: dec⟶recomputable was deprecated in v2.0.Please use dec⇒recomputable instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Closures of a unary relation with respect to a strict partial order------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictPartialOrder)module Relation.Unary.Closure.StrictPartialOrder{a r e} (P : StrictPartialOrder a e r) whereopen StrictPartialOrder P renaming (_<_ to _∼_)open import Relation.Unary using (Pred)-- Specialising the results proven generically in `Base`.import Relation.Unary.Closure.Base _∼_ as Baseopen Base publicusing (□; ◇; Closed; curry; uncurry)hiding (module □; module ◇)module □ {t} {T : Pred Carrier t} wherereindex : ∀ {x y} → x ∼ y → □ T x → □ T yreindex = Base.□.reindex transduplicate : ∀ {x} → □ T x → □ (□ T) xduplicate = Base.□.duplicate transclosed : ∀ {t} {T : Pred Carrier t} → Closed (□ T)closed = Base.□.closed transopen Base.□ public using (map)module ◇ {t} {T : Pred Carrier t} wherereindex : ∀ {x y} → x ∼ y → ◇ T x → ◇ T yreindex = Base.◇.reindex transjoin : ∀ {x} → ◇ (◇ T) x → ◇ T xjoin = Base.◇.join transclosed : Closed (◇ T)closed = Base.◇.closed transopen Base.◇ public using (map; run)
-------------------------------------------------------------------------- The Agda standard library---- Closure of a unary relation with respect to a preorder------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder)module Relation.Unary.Closure.Preorder {a r e} (P : Preorder a e r) whereopen Preorder Popen import Relation.Unary using (Pred)-- Specialising the results proven generically in `Base`.import Relation.Unary.Closure.Base _∼_ as Baseopen Base publicusing (□; ◇; Closed; curry; uncurry)hiding (module □; module ◇)module □ {t} {T : Pred Carrier t} wherereindex : ∀ {x y} → x ∼ y → □ T x → □ T yreindex = Base.□.reindex transextract : ∀ {x} → □ T x → T xextract = Base.□.extract reflduplicate : ∀ {x} → □ T x → □ (□ T) xduplicate = Base.□.duplicate transclosed : ∀ {t} {T : Pred Carrier t} → Closed (□ T)closed = Base.□.closed transopen Base.□ public using (map)module ◇ {t} {T : Pred Carrier t} wherereindex : ∀ {x y} → x ∼ y → ◇ T x → ◇ T yreindex = Base.◇.reindex transpure : ∀ {x} → T x → ◇ T xpure = Base.◇.pure refljoin : ∀ {x} → ◇ (◇ T) x → ◇ T xjoin = Base.◇.join transclosed : Closed (◇ T)closed = Base.◇.closed transopen Base.◇ public using (map; run)
-------------------------------------------------------------------------- The Agda standard library---- Closures of a unary relation with respect to a binary one.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Transitive; Reflexive)module Relation.Unary.Closure.Base {a b} {A : Set a} (R : Rel A b) whereopen import Levelopen import Data.Product.Base using (Σ-syntax; _×_; _,_; -,_)open import Function.Base using (flip)open import Relation.Unary using (Pred)-------------------------------------------------------------------------- Definitions-- Box-- We start with the definition of □ ("box") which is named after the-- box modality in modal logic. `□ T x` states that all the elements one-- step away from `x` with respect to the relation R satisfy `T`.□ : ∀ {t} → Pred A t → Pred A (a ⊔ b ⊔ t)□ T x = ∀ {y} → R x y → T y-- Use cases of □ include:-- * The definition of the accessibility predicate corresponding to R:-- data Acc (x : A) : Set (a ⊔ b) where-- step : □ Acc x → Acc x-- * The characterization of stability under weakening: picking R to be-- `Data.List.Relation.Sublist.Inductive`, `∀ {Γ} → Tm Γ → □ T Γ`-- corresponds to the fact that we have a notion of weakening for `Tm`.-- Diamond-- We then have the definition of ◇ ("diamond") which is named after the-- diamond modality in modal logic. In modal logic, `◇ T x` states that-- there exists an element one step away from x with respect to the-- relation R that satisfies T. It is worth noting that the modal logic-- metaphor breaks down here: this only is a closure operator if the-- step we take is *backwards* with respect to R.◇ : ∀ {t} → Pred A t → Pred A (a ⊔ b ⊔ t)◇ T x = Σ[ support ∈ A ] (R support x × T support)-- Use cases of ◇ include:-- * The characterization of strengthening: picking R to be-- `Data.List.Relation.Sublist.Inductive`, `∀ {Γ} → Tm Γ → ◇ Tm Γ`-- is the type of a function strengthening a term to its support:-- all the unused variables are discarded early on by the `related`-- proof.-- Cf. Conor McBride's "Everybody's got to be somewhere" for a more-- detailed treatment of such an example.-- Closed-- Whenever we have a value in one context, we can get one in any-- related context.record Closed {t} (T : Pred A t) : Set (a ⊔ b ⊔ t) wherefield next : ∀ {x} → T x → □ T x-------------------------------------------------------------------------- Basic functions relating □ and ◇module _ {t p} {T : Pred A t} {P : Pred A p} wherecurry : (∀ {x} → ◇ T x → P x) → (∀ {x} → T x → □ P x)curry f tx x∼y = f (-, x∼y , tx)uncurry : (∀ {x} → T x → □ P x) → (∀ {x} → ◇ T x → P x)uncurry f (_ , y∼x , ty) = f ty y∼x-------------------------------------------------------------------------- Propertiesmodule □ {t} {T : Pred A t} wherereindex : Transitive R → ∀ {x y} → R x y → □ T x → □ T yreindex trans x∼y □Tx y∼z = □Tx (trans x∼y y∼z)-- Provided that R is reflexive and Transitive, □ is a comonadmap : ∀ {u} {U : Pred A u} {x} → (∀ {x} → T x → U x) → □ T x → □ U xmap f □Tx x~y = f (□Tx x~y)extract : Reflexive R → ∀ {x} → □ T x → T xextract refl □Tx = □Tx reflduplicate : Transitive R → ∀ {x} → □ T x → □ (□ T) xduplicate trans □Tx x∼y y∼z = □Tx (trans x∼y y∼z)-- Provided that R is transitive, □ is a closure operator-- i.e. for any `T`, `□ T` is closed.closed : Transitive R → Closed (□ T)closed trans = record { next = duplicate trans }module ◇ {t} {T : Pred A t} wherereindex : Transitive R → ∀ {x y} → R x y → ◇ T x → ◇ T yreindex trans x∼y (z , z∼x , tz) = z , trans z∼x x∼y , tz-- Provided that R is reflexive and Transitive, ◇ is a monadmap : ∀ {u} {U : Pred A u} {x} → (∀ {x} → T x → U x) → ◇ T x → ◇ U xmap f (y , y∼x , ty) = y , y∼x , f typure : Reflexive R → ∀ {x} → T x → ◇ T xpure refl tx = -, refl , txjoin : Transitive R → ∀ {x} → ◇ (◇ T) x → ◇ T xjoin trans (_ , y∼x , _ , z∼y , tz) = _ , trans z∼y y∼x , tz-- Provided that R is transitive, ◇ is a closure operator-- i.e. for any `T`, `◇ T` is closed.closed : Transitive R → Closed (◇ T)closed trans = record { next = λ ◇Tx x∼y → reindex trans x∼y ◇Tx }run : Closed T → ∀ {x} → ◇ T x → T xrun closed (_ , y∼x , ty) = Closed.next closed ty y∼x
-------------------------------------------------------------------------- The Agda standard library---- Algebraic properties of constructions over unary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Unary.Algebra whereopen import Algebra.Bundlesimport Algebra.Definitions as AlgebraicDefinitionsopen import Algebra.Lattice.Bundlesimport Algebra.Lattice.Structures as AlgebraicLatticeStructuresimport Algebra.Structures as AlgebraicStructuresopen import Data.Empty.Polymorphic using (⊥-elim)open import Data.Product.Base as Product using (_,_; proj₁; proj₂; <_,_>; curry; uncurry)open import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_])open import Data.Unit.Polymorphic using (tt)open import Function.Base using (id; const; _∘_)open import Levelopen import Relation.Unary hiding (∅; U)open import Relation.Unary.Polymorphic using (∅; U)open import Relation.Unary.Relation.Binary.Equality using (≐-isEquivalence)module _ {a ℓ : Level} {A : Set a} whereopen AlgebraicDefinitions {A = Pred A ℓ} _≐_-------------------------------------------------------------------------- Properties of _∩_∩-cong : Congruent₂ _∩_∩-cong (P⊆Q , Q⊆P) (R⊆S , S⊆R) = Product.map P⊆Q R⊆S , Product.map Q⊆P S⊆R∩-comm : Commutative _∩_∩-comm _ _ = Product.swap , Product.swap∩-assoc : Associative _∩_∩-assoc _ _ _ = Product.assocʳ′ , Product.assocˡ′∩-idem : Idempotent _∩_∩-idem _ = proj₁ , < id , id >∩-identityˡ : LeftIdentity U _∩_∩-identityˡ _ = proj₂ , < const tt , id >∩-identityʳ : RightIdentity U _∩_∩-identityʳ _ = proj₁ , < id , const tt >∩-identity : Identity U _∩_∩-identity = ∩-identityˡ , ∩-identityʳ∩-zeroˡ : LeftZero ∅ _∩_∩-zeroˡ _ = proj₁ , ⊥-elim∩-zeroʳ : RightZero ∅ _∩_∩-zeroʳ _ = proj₂ , ⊥-elim∩-zero : Zero ∅ _∩_∩-zero = ∩-zeroˡ , ∩-zeroʳ-------------------------------------------------------------------------- Properties of _∪_∪-cong : Congruent₂ _∪_∪-cong (P⊆Q , Q⊆P) (R⊆S , S⊆R) = Sum.map P⊆Q R⊆S , Sum.map Q⊆P S⊆R∪-comm : Commutative _∪_∪-comm _ _ = Sum.swap , Sum.swap∪-assoc : Associative _∪_∪-assoc _ _ _ = Sum.assocʳ , Sum.assocˡ∪-idem : Idempotent _∪_∪-idem _ = [ id , id ] , inj₁∪-identityˡ : LeftIdentity ∅ _∪_∪-identityˡ _ = [ ⊥-elim , id ] , inj₂∪-identityʳ : RightIdentity ∅ _∪_∪-identityʳ _ = [ id , ⊥-elim ] , inj₁∪-identity : Identity ∅ _∪_∪-identity = ∪-identityˡ , ∪-identityʳ-------------------------------------------------------------------------- Properties of _∩_ and _∪_∩-distribˡ-∪ : _∩_ DistributesOverˡ _∪_∩-distribˡ-∪ _ _ _ =( uncurry (λ x∈P → [ inj₁ ∘ (x∈P ,_) , inj₂ ∘ (x∈P ,_) ]), [ Product.map₂ inj₁ , Product.map₂ inj₂ ])∩-distribʳ-∪ : _∩_ DistributesOverʳ _∪_∩-distribʳ-∪ _ _ _ =( uncurry [ curry inj₁ , curry inj₂ ], [ Product.map₁ inj₁ , Product.map₁ inj₂ ])∩-distrib-∪ : _∩_ DistributesOver _∪_∩-distrib-∪ = ∩-distribˡ-∪ , ∩-distribʳ-∪∪-distribˡ-∩ : _∪_ DistributesOverˡ _∩_∪-distribˡ-∩ _ _ _ =( [ < inj₁ , inj₁ > , Product.map inj₂ inj₂ ], uncurry [ const ∘ inj₁ , (λ x∈Q → [ inj₁ , inj₂ ∘ (x∈Q ,_) ]) ])∪-distribʳ-∩ : _∪_ DistributesOverʳ _∩_∪-distribʳ-∩ _ _ _ =( [ Product.map inj₁ inj₁ , < inj₂ , inj₂ > ], uncurry [ (λ x∈Q → [ inj₁ ∘ (x∈Q ,_) , inj₂ ]) , const ∘ inj₂ ])∪-distrib-∩ : _∪_ DistributesOver _∩_∪-distrib-∩ = ∪-distribˡ-∩ , ∪-distribʳ-∩∩-abs-∪ : _∩_ Absorbs _∪_∩-abs-∪ _ _ = proj₁ , < id , inj₁ >∪-abs-∩ : _∪_ Absorbs _∩_∪-abs-∩ _ _ = [ id , proj₁ ] , inj₁∪-∩-absorptive : Absorptive _∪_ _∩_∪-∩-absorptive = ∪-abs-∩ , ∩-abs-∪∩-∪-absorptive : Absorptive _∩_ _∪_∩-∪-absorptive = ∩-abs-∪ , ∪-abs-∩module _ {a : Level} (A : Set a) (ℓ : Level) whereopen AlgebraicStructures {A = Pred A ℓ} _≐_open AlgebraicLatticeStructures {A = Pred A ℓ} _≐_-------------------------------------------------------------------------- Algebraic structures of _∩_∩-isMagma : IsMagma _∩_∩-isMagma = record{ isEquivalence = ≐-isEquivalence; ∙-cong = ∩-cong}∩-isSemigroup : IsSemigroup _∩_∩-isSemigroup = record{ isMagma = ∩-isMagma; assoc = ∩-assoc}∩-isBand : IsBand _∩_∩-isBand = record{ isSemigroup = ∩-isSemigroup; idem = ∩-idem}∩-isSemilattice : IsSemilattice _∩_∩-isSemilattice = record{ isBand = ∩-isBand; comm = ∩-comm}∩-isMonoid : IsMonoid _∩_ U∩-isMonoid = record{ isSemigroup = ∩-isSemigroup; identity = ∩-identity}∩-isCommutativeMonoid : IsCommutativeMonoid _∩_ U∩-isCommutativeMonoid = record{ isMonoid = ∩-isMonoid; comm = ∩-comm}∩-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∩_ U∩-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∩-isCommutativeMonoid; idem = ∩-idem}-------------------------------------------------------------------------- Algebraic structures of _∪_∪-isMagma : IsMagma _∪_∪-isMagma = record{ isEquivalence = ≐-isEquivalence; ∙-cong = ∪-cong}∪-isSemigroup : IsSemigroup _∪_∪-isSemigroup = record{ isMagma = ∪-isMagma; assoc = ∪-assoc}∪-isBand : IsBand _∪_∪-isBand = record{ isSemigroup = ∪-isSemigroup; idem = ∪-idem}∪-isSemilattice : IsSemilattice _∪_∪-isSemilattice = record{ isBand = ∪-isBand; comm = ∪-comm}∪-isMonoid : IsMonoid _∪_ ∅∪-isMonoid = record{ isSemigroup = ∪-isSemigroup; identity = ∪-identity}∪-isCommutativeMonoid : IsCommutativeMonoid _∪_ ∅∪-isCommutativeMonoid = record{ isMonoid = ∪-isMonoid; comm = ∪-comm}∪-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∪_ ∅∪-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∪-isCommutativeMonoid; idem = ∪-idem}-------------------------------------------------------------------------- Algebraic structures of _∩_ and _∪_∪-∩-isSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero _∪_ _∩_ ∅ U∪-∩-isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∪-isCommutativeMonoid; *-cong = ∩-cong; *-assoc = ∩-assoc; *-identity = ∩-identity; distrib = ∩-distrib-∪}∪-∩-isSemiring : IsSemiring _∪_ _∩_ ∅ U∪-∩-isSemiring = record{ isSemiringWithoutAnnihilatingZero = ∪-∩-isSemiringWithoutAnnihilatingZero; zero = ∩-zero}∪-∩-isCommutativeSemiring : IsCommutativeSemiring _∪_ _∩_ ∅ U∪-∩-isCommutativeSemiring = record{ isSemiring = ∪-∩-isSemiring; *-comm = ∩-comm}∪-∩-isLattice : IsLattice _∪_ _∩_∪-∩-isLattice = record{ isEquivalence = ≐-isEquivalence; ∨-comm = ∪-comm; ∨-assoc = ∪-assoc; ∨-cong = ∪-cong; ∧-comm = ∩-comm; ∧-assoc = ∩-assoc; ∧-cong = ∩-cong; absorptive = ∪-∩-absorptive}∪-∩-isDistributiveLattice : IsDistributiveLattice _∪_ _∩_∪-∩-isDistributiveLattice = record{ isLattice = ∪-∩-isLattice; ∨-distrib-∧ = ∪-distrib-∩; ∧-distrib-∨ = ∩-distrib-∪}∩-∪-isSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero _∩_ _∪_ U ∅∩-∪-isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∩-isCommutativeMonoid; *-cong = ∪-cong; *-assoc = ∪-assoc; *-identity = ∪-identity; distrib = ∪-distrib-∩}-------------------------------------------------------------------------- Algebraic bundles of _∩_∩-magma : Magma _ _∩-magma = record{ isMagma = ∩-isMagma}∩-semigroup : Semigroup _ _∩-semigroup = record{ isSemigroup = ∩-isSemigroup}∩-band : Band _ _∩-band = record{ isBand = ∩-isBand}∩-semilattice : Semilattice _ _∩-semilattice = record{ isSemilattice = ∩-isSemilattice}∩-monoid : Monoid _ _∩-monoid = record{ isMonoid = ∩-isMonoid}∩-commutativeMonoid : CommutativeMonoid _ _∩-commutativeMonoid = record{ isCommutativeMonoid = ∩-isCommutativeMonoid}∩-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∩-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∩-isIdempotentCommutativeMonoid}-------------------------------------------------------------------------- Algebraic bundles of _∪_∪-magma : Magma _ _∪-magma = record{ isMagma = ∪-isMagma}∪-semigroup : Semigroup _ _∪-semigroup = record{ isSemigroup = ∪-isSemigroup}∪-band : Band _ _∪-band = record{ isBand = ∪-isBand}∪-semilattice : Semilattice _ _∪-semilattice = record{ isSemilattice = ∪-isSemilattice}∪-monoid : Monoid _ _∪-monoid = record{ isMonoid = ∪-isMonoid}∪-commutativeMonoid : CommutativeMonoid _ _∪-commutativeMonoid = record{ isCommutativeMonoid = ∪-isCommutativeMonoid}∪-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∪-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∪-isIdempotentCommutativeMonoid}-------------------------------------------------------------------------- Algebraic bundles of _∩_ and _∪_∪-∩-semiringWithoutAnnihilatingZero : SemiringWithoutAnnihilatingZero _ _∪-∩-semiringWithoutAnnihilatingZero = record{ isSemiringWithoutAnnihilatingZero = ∪-∩-isSemiringWithoutAnnihilatingZero}∪-∩-semiring : Semiring _ _∪-∩-semiring = record{ isSemiring = ∪-∩-isSemiring}∪-∩-commutativeSemiring : CommutativeSemiring _ _∪-∩-commutativeSemiring = record{ isCommutativeSemiring = ∪-∩-isCommutativeSemiring}∪-∩-lattice : Lattice _ _∪-∩-lattice = record{ isLattice = ∪-∩-isLattice}∪-∩-distributiveLattice : DistributiveLattice _ _∪-∩-distributiveLattice = record{ isDistributiveLattice = ∪-∩-isDistributiveLattice}∩-∪-semiringWithoutAnnihilatingZero : SemiringWithoutAnnihilatingZero _ _∩-∪-semiringWithoutAnnihilatingZero = record{ isSemiringWithoutAnnihilatingZero = ∩-∪-isSemiringWithoutAnnihilatingZero}
-------------------------------------------------------------------------- The Agda standard library---- Operations on nullary relations (like negation and decidability)-------------------------------------------------------------------------- Some operations on/properties of nullary relations, i.e. sets.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary whereopen import Agda.Builtin.Equality using (_≡_)open import Agda.Builtin.Maybe using (Maybe)open import Level using (Level)privatevariablep : LevelP : Set p-------------------------------------------------------------------------- Re-exportsopen import Relation.Nullary.Recomputable public using (Recomputable)open import Relation.Nullary.Negation.Core publicopen import Relation.Nullary.Reflects public hiding (recompute; recompute-constant)open import Relation.Nullary.Decidable.Core public-------------------------------------------------------------------------- Irrelevant typesIrrelevant : Set p → Set pIrrelevant P = ∀ (p₁ p₂ : P) → p₁ ≡ p₂-------------------------------------------------------------------------- Weak decidability-- `nothing` is 'don't know'/'give up'; `just` is `yes`/`definitely`WeaklyDecidable : Set p → Set pWeaklyDecidable = Maybe
-------------------------------------------------------------------------- The Agda standard library---- A universe of proposition functors, along with some properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Universe whereopen import Relation.Nullaryopen import Relation.Nullary.Negationopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.Construct.Always as Alwaysopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)import Relation.Binary.PropositionalEquality.Properties as PropEqimport Relation.Binary.Indexed.Heterogeneous.Construct.Trivialas Trivialopen import Data.Sum.Base as Sum hiding (map)open import Data.Sum.Relation.Binary.Pointwise using (_⊎ₛ_; inj₁; inj₂)open import Data.Product.Base as Product hiding (map)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (_×ₛ_)open import Function.Base using (_∘_; id)open import Function.Indexed.Relation.Binary.Equality using (≡-setoid)open import Data.Emptyopen import Effect.Applicativeopen import Effect.Monadopen import Levelinfix 5 ¬¬_infixr 4 _⇒_infixr 3 _∧_infixr 2 _∨_infix 1 ⟨_⟩_≈_-- The universe.data PropF p : Set (suc p) whereId : PropF pK : (P : Set p) → PropF p_∨_ : (F₁ F₂ : PropF p) → PropF p_∧_ : (F₁ F₂ : PropF p) → PropF p_⇒_ : (P₁ : Set p) (F₂ : PropF p) → PropF p¬¬_ : (F : PropF p) → PropF p-- Equalities for universe inhabitants.mutualsetoid : ∀ {p} → PropF p → Set p → Setoid p psetoid Id P = PropEq.setoid Psetoid (K P) _ = PropEq.setoid Psetoid (F₁ ∨ F₂) P = (setoid F₁ P) ⊎ₛ (setoid F₂ P)setoid (F₁ ∧ F₂) P = (setoid F₁ P) ×ₛ (setoid F₂ P)setoid (P₁ ⇒ F₂) P = ≡-setoid P₁(Trivial.indexedSetoid (setoid F₂ P))setoid (¬¬ F) P = Always.setoid (¬ ¬ ⟦ F ⟧ P) _⟦_⟧ : ∀ {p} → PropF p → (Set p → Set p)⟦ F ⟧ P = Setoid.Carrier (setoid F P)⟨_⟩_≈_ : ∀ {p} (F : PropF p) {P : Set p} → Rel (⟦ F ⟧ P) p⟨_⟩_≈_ F = Setoid._≈_ (setoid F _)-- ⟦ F ⟧ is functorial.map : ∀ {p} (F : PropF p) {P Q} → (P → Q) → ⟦ F ⟧ P → ⟦ F ⟧ Qmap Id f p = f pmap (K P) f p = pmap (F₁ ∨ F₂) f FP = Sum.map (map F₁ f) (map F₂ f) FPmap (F₁ ∧ F₂) f FP = Product.map (map F₁ f) (map F₂ f) FPmap (P₁ ⇒ F₂) f FP = map F₂ f ∘ FPmap (¬¬ F) f FP = ¬¬-map (map F f) FPmap-id : ∀ {p} (F : PropF p) {P} → ⟨ ⟦ F ⟧ P ⇒ F ⟩ map F id ≈ idmap-id Id x = reflmap-id (K P) x = reflmap-id (F₁ ∨ F₂) (inj₁ x) = inj₁ (map-id F₁ x)map-id (F₁ ∨ F₂) (inj₂ y) = inj₂ (map-id F₂ y)map-id (F₁ ∧ F₂) (x , y) = (map-id F₁ x , map-id F₂ y)map-id (P₁ ⇒ F₂) f = λ x → map-id F₂ (f x)map-id (¬¬ F) ¬¬x = _map-∘ : ∀ {p} (F : PropF p) {P Q R} (f : Q → R) (g : P → Q) →⟨ ⟦ F ⟧ P ⇒ F ⟩ map F f ∘ map F g ≈ map F (f ∘ g)map-∘ Id f g x = reflmap-∘ (K P) f g x = reflmap-∘ (F₁ ∨ F₂) f g (inj₁ x) = inj₁ (map-∘ F₁ f g x)map-∘ (F₁ ∨ F₂) f g (inj₂ y) = inj₂ (map-∘ F₂ f g y)map-∘ (F₁ ∧ F₂) f g x = (map-∘ F₁ f g (proj₁ x) ,map-∘ F₂ f g (proj₂ x))map-∘ (P₁ ⇒ F₂) f g h = λ x → map-∘ F₂ f g (h x)map-∘ (¬¬ F) f g x = _-- A variant of sequence can be implemented for ⟦ F ⟧.sequence : ∀ {p AF} → RawApplicative AF →(AF (Lift p ⊥) → ⊥) →({A B : Set p} → (A → AF B) → AF (A → B)) →∀ F {P} → ⟦ F ⟧ (AF P) → AF (⟦ F ⟧ P)sequence {AF = AF} A extract-⊥ sequence-⇒ = helperwhereopen RawApplicative Ahelper : ∀ F {P} → ⟦ F ⟧ (AF P) → AF (⟦ F ⟧ P)helper Id x = xhelper (K P) x = pure xhelper (F₁ ∨ F₂) (inj₁ x) = inj₁ <$> helper F₁ xhelper (F₁ ∨ F₂) (inj₂ y) = inj₂ <$> helper F₂ yhelper (F₁ ∧ F₂) (x , y) = _,_ <$> helper F₁ x ⊛ helper F₂ yhelper (P₁ ⇒ F₂) f = sequence-⇒ (helper F₂ ∘ f)helper (¬¬ F) x =pure (λ ¬FP → x (λ fp → extract-⊥ (lift ∘ ¬FP <$> helper F fp)))-- Some lemmas about double negation.privateopen module M {a} = RawMonad (¬¬-Monad {a = a})¬¬-pull : ∀ {p} (F : PropF p) {P} →⟦ F ⟧ (¬ ¬ P) → ¬ ¬ ⟦ F ⟧ P¬¬-pull = sequence rawApplicative(λ f → f lower)(λ f g → g (λ x → ⊥-elim (f x (λ y → g (λ _ → y)))))¬¬-remove : ∀ {p} (F : PropF p) {P} →¬ ¬ ⟦ F ⟧ (¬ ¬ P) → ¬ ¬ ⟦ F ⟧ P¬¬-remove F = negated-stable ∘ ¬¬-pull (¬¬ F)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Sum where{-# WARNING_ON_IMPORT"Relation.Nullary.Sum was deprecated in v2.0.Use `Relation.Nullary.Decidable` or `Relation.Nullary` instead."#-}open import Relation.Nullary.Negation.Core public using (_¬-⊎_)open import Relation.Nullary.Reflects public using (_⊎-reflects_)open import Relation.Nullary.Decidable.Core public using (_⊎-dec_)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the `Reflects` construct------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Reflects whereopen import Agda.Builtin.Equalityopen import Data.Bool.Baseopen import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Level using (Level)open import Function.Base using (_$_; _∘_; const; id)open import Relation.Nullary.Negation.Coreusing (¬_; contradiction-irr; contradiction; _¬-⊎_)open import Relation.Nullary.Recomputable as Recomputable using (Recomputable)privatevariablea : LevelA B : Set a-------------------------------------------------------------------------- `Reflects` idiom.-- The truth value of A is reflected by a boolean value.-- `Reflects A b` is equivalent to `if b then A else ¬ A`.data Reflects (A : Set a) : Bool → Set a whereofʸ : ( a : A) → Reflects A trueofⁿ : (¬a : ¬ A) → Reflects A false-------------------------------------------------------------------------- Constructors and destructors-- These lemmas are intended to be used mostly when `b` is a value, so-- that the `if` expressions have already been evaluated away.-- In this case, `of` works like the relevant constructor (`ofⁿ` or-- `ofʸ`), and `invert` strips off the constructor to just give either-- the proof of `A` or the proof of `¬ A`.of : ∀ {b} → if b then A else ¬ A → Reflects A bof {b = false} ¬a = ofⁿ ¬aof {b = true } a = ofʸ ainvert : ∀ {b} → Reflects A b → if b then A else ¬ Ainvert (ofʸ a) = ainvert (ofⁿ ¬a) = ¬a-------------------------------------------------------------------------- recompute-- Given an irrelevant proof of a reflected type, a proof can-- be recomputed and subsequently used in relevant contexts.recompute : ∀ {b} → Reflects A b → Recomputable Arecompute (ofʸ a) _ = arecompute (ofⁿ ¬a) a = contradiction-irr a ¬arecompute-constant : ∀ {b} (r : Reflects A b) (p q : A) →recompute r p ≡ recompute r qrecompute-constant = Recomputable.recompute-constant ∘ recompute-------------------------------------------------------------------------- Interaction with negation, product, sums etc.infixr 1 _⊎-reflects_infixr 2 _×-reflects_ _→-reflects_T-reflects : ∀ b → Reflects (T b) bT-reflects true = of _T-reflects false = of id-- If we can decide A, then we can decide its negation.¬-reflects : ∀ {b} → Reflects A b → Reflects (¬ A) (not b)¬-reflects (ofʸ a) = of (_$ a)¬-reflects (ofⁿ ¬a) = of ¬a-- If we can decide A and Q then we can decide their product_×-reflects_ : ∀ {a b} → Reflects A a → Reflects B b →Reflects (A × B) (a ∧ b)ofʸ a ×-reflects ofʸ b = of (a , b)ofʸ a ×-reflects ofⁿ ¬b = of (¬b ∘ proj₂)ofⁿ ¬a ×-reflects _ = of (¬a ∘ proj₁)_⊎-reflects_ : ∀ {a b} → Reflects A a → Reflects B b →Reflects (A ⊎ B) (a ∨ b)ofʸ a ⊎-reflects _ = of (inj₁ a)ofⁿ ¬a ⊎-reflects ofʸ b = of (inj₂ b)ofⁿ ¬a ⊎-reflects ofⁿ ¬b = of (¬a ¬-⊎ ¬b)_→-reflects_ : ∀ {a b} → Reflects A a → Reflects B b →Reflects (A → B) (not a ∨ b)ofʸ a →-reflects ofʸ b = of (const b)ofʸ a →-reflects ofⁿ ¬b = of (¬b ∘ (_$ a))ofⁿ ¬a →-reflects _ = of (λ a → contradiction a ¬a)-------------------------------------------------------------------------- Other lemmasfromEquivalence : ∀ {b} → (T b → A) → (A → T b) → Reflects A bfromEquivalence {b = true} sound complete = of (sound _)fromEquivalence {b = false} sound complete = of complete-- `Reflects` is deterministic.det : ∀ {b b′} → Reflects A b → Reflects A b′ → b ≡ b′det (ofʸ a) (ofʸ _) = refldet (ofʸ a) (ofⁿ ¬a) = contradiction a ¬adet (ofⁿ ¬a) (ofʸ a) = contradiction a ¬adet (ofⁿ ¬a) (ofⁿ _) = reflT-reflects-elim : ∀ {a b} → Reflects (T a) b → b ≡ aT-reflects-elim {a} r = det r (T-reflects a)
-------------------------------------------------------------------------- The Agda standard library---- Recomputable types and their algebra as Harrop formulas------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Recomputable whereopen import Agda.Builtin.Equality using (_≡_; refl)open import Data.Empty using (⊥)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Level using (Level)open import Relation.Nullary.Negation.Core using (¬_)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definition---- The idea of being 'recomputable' is that, given an *irrelevant* proof-- of a proposition `A` (signalled by being a value of type `.A`, all of-- whose inhabitants are identified up to definitional equality, and hence-- do *not* admit pattern-matching), one may 'promote' such a value to a-- 'genuine' value of `A`, available for subsequent eg. pattern-matching.Recomputable : (A : Set a) → Set aRecomputable A = .A → A-------------------------------------------------------------------------- Fundamental property: 'promotion' is a constant functionrecompute-constant : (r : Recomputable A) (p q : A) → r p ≡ r qrecompute-constant r p q = refl-------------------------------------------------------------------------- Constructions⊥-recompute : Recomputable ⊥⊥-recompute ()_×-recompute_ : Recomputable A → Recomputable B → Recomputable (A × B)(rA ×-recompute rB) p = rA (p .proj₁) , rB (p .proj₂)_→-recompute_ : (A : Set a) → Recomputable B → Recomputable (A → B)(A →-recompute rB) f a = rB (f a)Π-recompute : (B : A → Set b) → (∀ x → Recomputable (B x)) → Recomputable (∀ x → B x)Π-recompute B rB f a = rB a (f a)∀-recompute : (B : A → Set b) → (∀ {x} → Recomputable (B x)) → Recomputable (∀ {x} → B x)∀-recompute B rB f = rB f-- corollary: negated propositions are Recomputable¬-recompute : Recomputable (¬ A)¬-recompute {A = A} = A →-recompute ⊥-recompute
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Product where{-# WARNING_ON_IMPORT"Relation.Nullary.Product was deprecated in v2.0.Use `Relation.Nullary.Decidable` or `Relation.Nullary` instead."#-}open import Relation.Nullary.Decidable.Core public using (_×-dec_)open import Relation.Nullary.Reflects public using (_×-reflects_)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to negation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Negation whereopen import Data.Bool.Base using (Bool; false; true; if_then_else_)open import Data.Product.Base as Product using (_,_; Σ; Σ-syntax; ∃; curry; uncurry)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_])open import Effect.Monad using (RawMonad; mkRawMonad)open import Function.Base using (flip; _∘_; const; _∘′_)open import Level using (Level)open import Relation.Nullary.Decidable.Core using (Dec; yes; no; ¬¬-excluded-middle)open import Relation.Unary using (Universal; Pred)privatevariablea b c d p w : LevelA B C D : Set aP : Pred A pWhatever : Set w-------------------------------------------------------------------------- Re-export public definitionsopen import Relation.Nullary.Negation.Core public-------------------------------------------------------------------------- Quantifier juggling∃⟶¬∀¬ : ∃ P → ¬ (∀ x → ¬ P x)∃⟶¬∀¬ = flip uncurry∀⟶¬∃¬ : (∀ x → P x) → ¬ ∃ λ x → ¬ P x∀⟶¬∃¬ ∀xPx (x , ¬Px) = ¬Px (∀xPx x)¬∃⟶∀¬ : ¬ ∃ (λ x → P x) → ∀ x → ¬ P x¬∃⟶∀¬ = curry∀¬⟶¬∃ : (∀ x → ¬ P x) → ¬ ∃ (λ x → P x)∀¬⟶¬∃ = uncurry∃¬⟶¬∀ : ∃ (λ x → ¬ P x) → ¬ (∀ x → P x)∃¬⟶¬∀ = flip ∀⟶¬∃¬-------------------------------------------------------------------------- Double Negation-- Double-negation is a monad (if we assume that all elements of ¬ ¬ P-- are equal).¬¬-Monad : RawMonad {a} DoubleNegation¬¬-Monad = mkRawMonadDoubleNegationcontradiction(λ x f → negated-stable (¬¬-map f x))¬¬-push : DoubleNegation Π[ P ] → Π[ DoubleNegation ∘ P ]¬¬-push ¬¬∀P a ¬Pa = ¬¬∀P (λ ∀P → ¬Pa (∀P a))-- If Whatever is instantiated with ¬ ¬ something, then this function-- is call with current continuation in the double-negation monad, or,-- if you will, a double-negation translation of Peirce's law.---- In order to prove ¬ ¬ P one can assume ¬ P and prove ⊥. However,-- sometimes it is nice to avoid leaving the double-negation monad; in-- that case this function can be used (with Whatever instantiated to-- ⊥).call/cc : ((A → Whatever) → DoubleNegation A) → DoubleNegation Acall/cc hyp ¬a = hyp (flip contradiction ¬a) ¬a-- The "independence of premise" rule, in the double-negation monad.-- It is assumed that the index set (A) is inhabited.independence-of-premise : A → (B → Σ A P) → DoubleNegation (Σ[ x ∈ A ] (B → P x))independence-of-premise {A = A} {B = B} {P = P} q f = ¬¬-map helper ¬¬-excluded-middlewherehelper : Dec B → Σ[ x ∈ A ] (B → P x)helper (yes p) = Product.map₂ const (f p)helper (no ¬p) = (q , flip contradiction ¬p)-- The independence of premise rule for binary sums.independence-of-premise-⊎ : (A → B ⊎ C) → DoubleNegation ((A → B) ⊎ (A → C))independence-of-premise-⊎ {A = A} {B = B} {C = C} f = ¬¬-map helper ¬¬-excluded-middlewherehelper : Dec A → (A → B) ⊎ (A → C)helper (yes p) = Sum.map const const (f p)helper (no ¬p) = inj₁ (flip contradiction ¬p)private-- Note that independence-of-premise-⊎ is a consequence of-- independence-of-premise (for simplicity it is assumed that Q and-- R have the same type here):corollary : {B C : Set b} → (A → B ⊎ C) → DoubleNegation ((A → B) ⊎ (A → C))corollary {A = A} {B = B} {C = C} f =¬¬-map helper (independence-of-premise true ([ _,_ true , _,_ false ] ∘′ f))wherehelper : ∃ (λ b → A → if b then B else C) → (A → B) ⊎ (A → C)helper (true , f) = inj₁ fhelper (false , f) = inj₂ f
-------------------------------------------------------------------------- The Agda standard library---- Core properties related to negation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Negation.Core whereopen import Data.Empty using (⊥; ⊥-elim-irr)open import Data.Sum.Base using (_⊎_; [_,_]; inj₁; inj₂)open import Function.Base using (flip; _∘_; const)open import Levelprivatevariablea p q w : LevelA B C : Set aWhatever : Set w-------------------------------------------------------------------------- Negation.infix 3 ¬_¬_ : Set a → Set a¬ A = A → ⊥-------------------------------------------------------------------------- Stability.-- Double-negationDoubleNegation : Set a → Set aDoubleNegation A = ¬ ¬ A-- Stability under double-negation.Stable : Set a → Set aStable A = ¬ ¬ A → A-------------------------------------------------------------------------- Relationship to suminfixr 1 _¬-⊎__¬-⊎_ : ¬ A → ¬ B → ¬ (A ⊎ B)_¬-⊎_ = [_,_]-------------------------------------------------------------------------- Uses of negationcontradiction-irr : .A → ¬ A → Whatevercontradiction-irr a ¬a = ⊥-elim-irr (¬a a)contradiction : A → ¬ A → Whatevercontradiction a = contradiction-irr acontradiction₂ : A ⊎ B → ¬ A → ¬ B → Whatevercontradiction₂ (inj₁ a) ¬a ¬b = contradiction a ¬acontradiction₂ (inj₂ b) ¬a ¬b = contradiction b ¬bcontraposition : (A → B) → ¬ B → ¬ Acontraposition f ¬b a = contradiction (f a) ¬b-- Everything is stable in the double-negation monad.stable : ¬ ¬ Stable Astable ¬[¬¬a→a] = ¬[¬¬a→a] (contradiction (¬[¬¬a→a] ∘ const))-- Negated predicates are stable.negated-stable : Stable (¬ A)negated-stable ¬¬¬a a = ¬¬¬a (contradiction a)¬¬-map : (A → B) → ¬ ¬ A → ¬ ¬ B¬¬-map f = contraposition (contraposition f)-- Note also the following use of flip:privatenote : (A → ¬ B) → B → ¬ Anote = flip
-------------------------------------------------------------------------- The Agda standard library---- Negation indexed by a Level------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Indexed whereopen import Data.Empty hiding (⊥-elim)open import Level-------------------------------------------------------------------------- Negation.-- level polymorphic version of ¬¬ : ∀ {ℓ} (b : Level) → Set ℓ → Set (ℓ ⊔ b)¬ b P = P → Lift b ⊥
-------------------------------------------------------------------------- The Agda standard library---- Properties of indexed negation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Indexed.Negation whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Empty.Polymorphicopen import Function.Bundles using (_↔_)open import Function.Propertiesimport Function.Construct.Identity as Identityopen import Relation.Nullary.Indexed-------------------------------------------------------------------------- ¬_ preserves ↔ (assuming extensionality)¬-cong : ∀ {a b c} {A : Set a} {B : Set b} →Extensionality a c → Extensionality b c →A ↔ B → (¬ c A) ↔ (¬ c B)¬-cong extA extB A≈B = →-cong-↔ extA extB A≈B (Identity.↔-id ⊥)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Implication where{-# WARNING_ON_IMPORT"Relation.Nullary.Implication was deprecated in v2.0.Use `Relation.Nullary.Decidable` or `Relation.Nullary` instead."#-}open import Relation.Nullary.Decidable.Core public using (_→-dec_)open import Relation.Nullary.Reflects public using (_→-reflects_)
-------------------------------------------------------------------------- The Agda standard library---- Operations on and properties of decidable relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Decidable whereopen import Level using (Level)open import Data.Bool.Base using (true; false)open import Data.Product.Base using (∃; _,_)open import Function.Bundles using(Injection; module Injection; module Equivalence; _⇔_; _↔_; mk↔ₛ′)open import Relation.Binary.Bundles using (Setoid; module Setoid)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary using (Irrelevant)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Reflects using (invert)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans; cong′)privatevariablea b ℓ₁ ℓ₂ : LevelA B : Set a-------------------------------------------------------------------------- Re-exporting the core definitionsopen import Relation.Nullary.Decidable.Core public-------------------------------------------------------------------------- Mapsmap : A ⇔ B → Dec A → Dec Bmap A⇔B = map′ to fromwhere open Equivalence A⇔B-- If there is an injection from one setoid to another, and the-- latter's equivalence relation is decidable, then the former's-- equivalence relation is also decidable.via-injection : {S : Setoid a ℓ₁} {T : Setoid b ℓ₂}(inj : Injection S T) (open Injection inj) →Decidable Eq₂._≈_ → Decidable Eq₁._≈_via-injection inj _≟_ x y = map′ injective cong (to x ≟ to y)where open Injection inj-------------------------------------------------------------------------- A lemma relating True and DecTrue-↔ : (a? : Dec A) → Irrelevant A → True a? ↔ ATrue-↔ (true because [a]) irr = let a = invert [a] in mk↔ₛ′ (λ _ → a) _ (irr a) cong′True-↔ (false because [¬a]) _ = let ¬a = invert [¬a] in mk↔ₛ′ (λ ()) ¬a (λ a → contradiction a ¬a) λ ()-------------------------------------------------------------------------- Result of decidabilityisYes≗does : (a? : Dec A) → isYes a? ≡ does a?isYes≗does (true because _) = reflisYes≗does (false because _) = refldec-true : (a? : Dec A) → A → does a? ≡ truedec-true (true because _ ) a = refldec-true (false because [¬a]) a = contradiction a (invert [¬a])dec-false : (a? : Dec A) → ¬ A → does a? ≡ falsedec-false (false because _ ) ¬a = refldec-false (true because [a]) ¬a = contradiction (invert [a]) ¬adec-yes : (a? : Dec A) → A → ∃ λ a → a? ≡ yes adec-yes a? a with yes a′ ← a? | refl ← dec-true a? a = a′ , refldec-no : (a? : Dec A) (¬a : ¬ A) → a? ≡ no ¬adec-no a? ¬a with no _ ← a? | refl ← dec-false a? ¬a = refldec-yes-irr : (a? : Dec A) → Irrelevant A → (a : A) → a? ≡ yes adec-yes-irr a? irr a with a′ , eq ← dec-yes a? a rewrite irr a a′ = eq⌊⌋-map′ : ∀ t f (a? : Dec A) → ⌊ map′ {B = B} t f a? ⌋ ≡ ⌊ a? ⌋⌊⌋-map′ t f a? = trans (isYes≗does (map′ t f a?)) (sym (isYes≗does a?))
-------------------------------------------------------------------------- The Agda standard library---- Operations on and properties of decidable relations---- This file contains some core definitions which are re-exported by-- Relation.Nullary.Decidable------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Decidable.Core where-- decToMaybe was deprecated in v2.1 #2330/#2336-- this can go through `Data.Maybe.Base` once that deprecation is fully done.open import Agda.Builtin.Maybe using (Maybe; just; nothing)open import Agda.Builtin.Equality using (_≡_)open import Level using (Level)open import Data.Bool.Base using (Bool; T; false; true; not; _∧_; _∨_)open import Data.Unit.Polymorphic.Base using (⊤)open import Data.Product.Base using (_×_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (_∘_; const; _$_; flip)open import Relation.Nullary.Recomputable as Recomputable hiding (recompute-constant)open import Relation.Nullary.Reflects as Reflects hiding (recompute; recompute-constant)open import Relation.Nullary.Negation.Coreusing (¬_; Stable; negated-stable; contradiction; DoubleNegation)privatevariablea b : LevelA B : Set a-------------------------------------------------------------------------- Definition.-- Decidability proofs have two parts: the `does` term which contains-- the boolean result and the `proof` term which contains a proof that-- reflects the boolean result. This definition allows the boolean-- part of the decision procedure to compute independently from the-- proof. This leads to better computational behaviour when we only care-- about the result and not the proof. See README.Design.Decidability-- for further details.infix 2 _because_record Dec (A : Set a) : Set a whereconstructor _because_fielddoes : Boolproof : Reflects A doesopen Dec publicpattern yes a = true because ofʸ apattern no ¬a = false because ofⁿ ¬a-------------------------------------------------------------------------- Flatteningmodule _ {A : Set a} whereFrom-yes : Dec A → Set aFrom-yes (true because _) = AFrom-yes (false because _) = ⊤From-no : Dec A → Set aFrom-no (false because _) = ¬ AFrom-no (true because _) = ⊤-------------------------------------------------------------------------- Recompute-- Given an irrelevant proof of a decidable type, a proof can-- be recomputed and subsequently used in relevant contexts.recompute : Dec A → Recomputable Arecompute = Reflects.recompute ∘ proofrecompute-constant : (a? : Dec A) (p q : A) → recompute a? p ≡ recompute a? qrecompute-constant = Recomputable.recompute-constant ∘ recompute-------------------------------------------------------------------------- Interaction with negation, sum, product etc.infixr 1 _⊎-dec_infixr 2 _×-dec_ _→-dec_T? : ∀ x → Dec (T x)T? x = x because T-reflects x¬? : Dec A → Dec (¬ A)does (¬? a?) = not (does a?)proof (¬? a?) = ¬-reflects (proof a?)_×-dec_ : Dec A → Dec B → Dec (A × B)does (a? ×-dec b?) = does a? ∧ does b?proof (a? ×-dec b?) = proof a? ×-reflects proof b?_⊎-dec_ : Dec A → Dec B → Dec (A ⊎ B)does (a? ⊎-dec b?) = does a? ∨ does b?proof (a? ⊎-dec b?) = proof a? ⊎-reflects proof b?_→-dec_ : Dec A → Dec B → Dec (A → B)does (a? →-dec b?) = not (does a?) ∨ does b?proof (a? →-dec b?) = proof a? →-reflects proof b?-------------------------------------------------------------------------- Relationship with Maybedec⇒maybe : Dec A → Maybe Adec⇒maybe ( true because [a]) = just (invert [a])dec⇒maybe (false because _ ) = nothing-------------------------------------------------------------------------- Relationship with SumtoSum : Dec A → A ⊎ ¬ AtoSum ( true because [p]) = inj₁ (invert [p])toSum (false because [¬p]) = inj₂ (invert [¬p])fromSum : A ⊎ ¬ A → Dec AfromSum (inj₁ p) = yes pfromSum (inj₂ ¬p) = no ¬p-------------------------------------------------------------------------- Relationship with booleans-- `isYes` is a stricter version of `does`. The lack of computation-- means that we can recover the proposition `P` from `isYes a?` by-- unification. This is useful when we are using the decision procedure-- for proof automation.isYes : Dec A → BoolisYes (true because _) = trueisYes (false because _) = falseisNo : Dec A → BoolisNo = not ∘ isYesTrue : Dec A → SetTrue = T ∘ isYesFalse : Dec A → SetFalse = T ∘ isNo-- The traditional name for isYes is ⌊_⌋, indicating the stripping of evidence.⌊_⌋ = isYes-------------------------------------------------------------------------- Witnesses-- Gives a witness to the "truth".toWitness : {a? : Dec A} → True a? → AtoWitness {a? = true because [a]} _ = invert [a]toWitness {a? = false because _ } ()-- Establishes a "truth", given a witness.fromWitness : {a? : Dec A} → A → True a?fromWitness {a? = true because _ } = const _fromWitness {a? = false because [¬a]} = invert [¬a]-- Variants for False.toWitnessFalse : {a? : Dec A} → False a? → ¬ AtoWitnessFalse {a? = true because _ } ()toWitnessFalse {a? = false because [¬a]} _ = invert [¬a]fromWitnessFalse : {a? : Dec A} → ¬ A → False a?fromWitnessFalse {a? = true because [a]} = flip _$_ (invert [a])fromWitnessFalse {a? = false because _ } = const _-- If a decision procedure returns "yes", then we can extract the-- proof using from-yes.from-yes : (a? : Dec A) → From-yes a?from-yes (true because [a]) = invert [a]from-yes (false because _ ) = _-- If a decision procedure returns "no", then we can extract the proof-- using from-no.from-no : (a? : Dec A) → From-no a?from-no (false because [¬a]) = invert [¬a]from-no (true because _ ) = _-------------------------------------------------------------------------- Mapsmap′ : (A → B) → (B → A) → Dec A → Dec Bdoes (map′ A→B B→A a?) = does a?proof (map′ A→B B→A (true because [a])) = of (A→B (invert [a]))proof (map′ A→B B→A (false because [¬a])) = of (invert [¬a] ∘ B→A)-------------------------------------------------------------------------- Relationship with double-negation-- Decidable predicates are stable.decidable-stable : Dec A → Stable Adecidable-stable (true because [a]) ¬¬a = invert [a]decidable-stable (false because [¬a]) ¬¬a = contradiction (invert [¬a]) ¬¬a¬-drop-Dec : Dec (¬ ¬ A) → Dec (¬ A)¬-drop-Dec ¬¬a? = map′ negated-stable contradiction (¬? ¬¬a?)-- A double-negation-translated variant of excluded middle (or: every-- nullary relation is decidable in the double-negation monad).¬¬-excluded-middle : DoubleNegation (Dec A)¬¬-excluded-middle ¬?a = ¬?a (no (λ a → ¬?a (yes a)))-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0excluded-middle = ¬¬-excluded-middle{-# WARNING_ON_USAGE excluded-middle"Warning: excluded-middle was deprecated in v2.0.Please use ¬¬-excluded-middle instead."#-}-- Version 2.1decToMaybe = dec⇒maybe{-# WARNING_ON_USAGE decToMaybe"Warning: decToMaybe was deprecated in v2.1.Please use Relation.Nullary.Decidable.Core.dec⇒maybe instead."#-}fromDec = toSum{-# WARNING_ON_USAGE fromDec"Warning: fromDec was deprecated in v2.1.Please use Relation.Nullary.Decidable.Core.toSum instead."#-}toDec = fromSum{-# WARNING_ON_USAGE toDec"Warning: toDec was deprecated in v2.1.Please use Relation.Nullary.Decidable.Core.fromSum instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Notation for freely adding a supremum to any set------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Construct.Add.Supremum whereopen import Relation.Nullary.Construct.Add.Pointrenaming (Pointed to _⁺; ∙ to ⊤⁺)public
-------------------------------------------------------------------------- The Agda standard library---- Notation for adding an additional point to any set------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Construct.Add.Point whereopen import Data.Maybe.Base publicusing () renaming (Maybe to Pointed; nothing to ∙; just to [_])open import Data.Maybe.Properties publicusing (≡-dec) renaming (just-injective to []-injective)
-------------------------------------------------------------------------- The Agda standard library---- Notation for freely adding an infimum to any set------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Construct.Add.Infimum whereopen import Relation.Nullary.Construct.Add.Point publicrenaming (Pointed to _₋; ∙ to ⊥₋)
-------------------------------------------------------------------------- The Agda standard library---- Notation for freely adding extrema to any set------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nullary.Construct.Add.Extrema whereopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Nullary.Construct.Add.Infimum as Infimum using (_₋)open import Relation.Nullary.Construct.Add.Supremum as Supremum using (_⁺)-------------------------------------------------------------------------- Definition_± : ∀ {a} → Set a → Set aA ± = A ₋ ⁺pattern ⊥± = Supremum.[ Infimum.⊥₋ ]pattern [_] k = Supremum.[ Infimum.[ k ] ]pattern ⊤± = Supremum.⊤⁺-------------------------------------------------------------------------- Properties[_]-injective : ∀ {a} {A : Set a} {k l : A} → [ k ] ≡ [ l ] → k ≡ l[_]-injective refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous N-ary Relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Nary where-------------------------------------------------------------------------- Concrete examples can be found in README.Nary. This file's comments-- are more focused on the implementation details and the motivations-- behind the design decisions.------------------------------------------------------------------------open import Level using (Level; _⊔_; Lift)open import Data.Unit.Baseopen import Data.Bool.Base using (true; false)open import Data.Emptyopen import Data.Nat.Base using (zero; suc)open import Data.Product.Base as Product using (_×_; _,_)open import Data.Product.Nary.NonDependentopen import Data.Sum.Base using (_⊎_)open import Function.Base using (_$_; _∘′_)open import Function.Nary.NonDependentopen import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Decidable as Dec using (Dec; yes; no; _because_; _×-dec_)import Relation.Unary as Unaryopen import Relation.Binary.PropositionalEquality.Core using (_≡_; cong; subst)privatevariabler : LevelR : Set r-------------------------------------------------------------------------- Generic type constructors-- `Relation.Unary` provides users with a wealth of combinators to work-- with indexed sets. We can generalise these to n-ary relations.-- The crucial thing to notice here is that because we are explicitly-- considering that the input function should be a `Set`-ended `Arrows`,-- all the other parameters are inferrable. This allows us to make the-- number arguments (`n`) implicit.-------------------------------------------------------------------------------------------------------------------------------------------------- Quantifiers-- If we already know how to quantify over one variable, we can easily-- describe how to quantify over `n` variables by induction over said `n`.quantₙ : (∀ {i l} {I : Set i} → (I → Set l) → Set (i ⊔ l)) →∀ n {ls} {as : Sets n ls} →Arrows n as (Set r) → Set (r ⊔ (⨆ n ls))quantₙ Q zero f = fquantₙ Q (suc n) f = Q (λ x → quantₙ Q n (f x))infix 5 ∃⟨_⟩ Π[_] ∀[_]-- existential quantifier∃⟨_⟩ : ∀ {n ls r} {as : Sets n ls} → as ⇉ Set r → Set (r ⊔ (⨆ n ls))∃⟨_⟩ = quantₙ Unary.Satisfiable _-- explicit universal quantifiersΠ[_] : ∀ {n ls r} {as : Sets n ls} → as ⇉ Set r → Set (r ⊔ (⨆ n ls))Π[_] = quantₙ Unary.Universal _-- implicit universal quantifiers∀[_] : ∀ {n ls r} {as : Sets n ls} → as ⇉ Set r → Set (r ⊔ (⨆ n ls))∀[_] = quantₙ Unary.IUniversal _-- ≟-mapₙ : ∀ n. (con : A₁ → ⋯ → Aₙ → R) →-- Injectiveₙ n con →-- ∀ a₁₁ a₁₂ ⋯ aₙ₁ aₙ₂ →-- Dec (a₁₁ ≡ a₁₂) → ⋯ → Dec (aₙ₁ ≡ aₙ₂) →-- Dec (con a₁₁ ⋯ aₙ₁ ≡ con a₁₂ ⋯ aₙ₂)≟-mapₙ : ∀ n {ls} {as : Sets n ls} (con : Arrows n as R) → Injectiveₙ n con →∀ {l r} → Arrows n (Dec <$> Equalₙ n l r) (Dec (uncurryₙ n con l ≡ uncurryₙ n con r))≟-mapₙ n con con-inj =curryₙ n λ a?s → let as? = Product-dec n a?s inDec.map′ (cong (uncurryₙ n con) ∘′ fromEqualₙ n) con-inj as?-------------------------------------------------------------------------- Substitutionmodule _ {n r ls} {as : Sets n ls} (P : as ⇉ Set r) where-- Substitutionₙ : ∀ n. ∀ a₁₁ a₁₂ ⋯ aₙ₁ aₙ₂ →-- a₁₁ ≡ a₁₂ → ⋯ → aₙ₁ ≡ aₙ₂ →-- P a₁₁ ⋯ aₙ₁ → P a₁₂ ⋯ aₙ₂Substitutionₙ : Set (r ⊔ (⨆ n ls))Substitutionₙ = ∀ {l r} → Equalₙ n l r ⇉ (uncurryₙ n P l → uncurryₙ n P r)substₙ : Substitutionₙsubstₙ = curryₙ n (subst (uncurryₙ n P) ∘′ fromEqualₙ n)-------------------------------------------------------------------------- Pointwise liftings of k-ary operators-- Rather than having multiple ad-hoc lifting functions for various-- arities we have a fully generic liftₙ functional which lifts a k-ary-- operator to work with k n-ary functions whose respective codomains-- match the domains of the operator.-- The type of liftₙ is fairly unreadable. Here it is written with ellipsis:-- liftₙ : ∀ k n. (B₁ → ⋯ → Bₖ → R) →-- (A₁ → ⋯ → Aₙ → B₁) →-- ⋮-- (A₁ → ⋯ → Aₙ → B₁) →-- (A₁ → ⋯ → Aₙ → R)liftₙ : ∀ k n {ls rs} {as : Sets n ls} {bs : Sets k rs} →Arrows k bs R → Arrows k (smap _ (Arrows n as) k bs) (Arrows n as R)liftₙ k n op = curry⊤ₙ k λ fs →curry⊤ₙ n λ vs →uncurry⊤ₙ k op $palg _ _ k (λ f → uncurry⊤ₙ n f vs) fs where-- The bulk of the work happens in this auxiliary definition:palg : ∀ f (F : ∀ {l} → Set l → Set (f l)) n {ls} {as : Sets n ls} →(∀ {l} {r : Set l} → F r → r) → Product⊤ n (smap f F n as) → Product⊤ n aspalg f F zero alg ps = _palg f F (suc n) alg (p , ps) = alg p , palg f F n alg ps-- implicationinfixr 6 _⇒__⇒_ : ∀ {n} {ls r s} {as : Sets n ls} →as ⇉ Set r → as ⇉ Set s → as ⇉ Set (r ⊔ s)_⇒_ = liftₙ 2 _ (λ A B → A → B)-- conjunctioninfixr 7 _∩__∩_ : ∀ {n} {ls r s} {as : Sets n ls} →as ⇉ Set r → as ⇉ Set s → as ⇉ Set (r ⊔ s)_∩_ = liftₙ 2 _ _×_-- disjunctioninfixr 8 _∪__∪_ : ∀ {n} {ls r s} {as : Sets n ls} →as ⇉ Set r → as ⇉ Set s → as ⇉ Set (r ⊔ s)_∪_ = liftₙ 2 _ _⊎_-- negation∁ : ∀ {n ls r} {as : Sets n ls} → as ⇉ Set r → as ⇉ Set r∁ = liftₙ 1 _ ¬_apply⊤ₙ : ∀ {n ls r} {as : Sets n ls} {R : as ⇉ Set r} →Π[ R ] → (vs : Product⊤ n as) → uncurry⊤ₙ n R vsapply⊤ₙ {zero} prf vs = prfapply⊤ₙ {suc n} prf (v , vs) = apply⊤ₙ (prf v) vsapplyₙ : ∀ {n ls r} {as : Sets n ls} {R : as ⇉ Set r} →Π[ R ] → (vs : Product n as) → uncurry⊤ₙ n R (toProduct⊤ n vs)applyₙ {n} prf vs = apply⊤ₙ prf (toProduct⊤ n vs)iapply⊤ₙ : ∀ {n ls r} {as : Sets n ls} {R : as ⇉ Set r} →∀[ R ] → {vs : Product⊤ n as} → uncurry⊤ₙ n R vsiapply⊤ₙ {zero} prf = prfiapply⊤ₙ {suc n} prf = iapply⊤ₙ {n} prfiapplyₙ : ∀ {n ls r} {as : Sets n ls} {R : as ⇉ Set r} →∀[ R ] → {vs : Product n as} → uncurry⊤ₙ n R (toProduct⊤ n vs)iapplyₙ {n} prf = iapply⊤ₙ {n} prf-------------------------------------------------------------------------- Properties of N-ary relations-- DecidabilityDecidable : ∀ {n ls r} {as : Sets n ls} → as ⇉ Set r → Set (r ⊔ ⨆ n ls)Decidable R = Π[ mapₙ _ Dec R ]-- erasure⌊_⌋ : ∀ {n ls r} {as : Sets n ls} {R : as ⇉ Set r} → Decidable R → as ⇉ Set r⌊_⌋ {zero} R? = Lift _ (Dec.True R?)⌊_⌋ {suc n} R? a = ⌊ R? a ⌋-- equivalence between R and its erasurefromWitness : ∀ {n ls r} {as : Sets n ls} (R : as ⇉ Set r) (R? : Decidable R) →∀[ ⌊ R? ⌋ ⇒ R ]fromWitness {zero} R R? with R?... | yes r = λ _ → r... | false because _ = λ ()fromWitness {suc n} R R? = fromWitness (R _) (R? _)toWitness : ∀ {n ls r} {as : Sets n ls} (R : as ⇉ Set r) (R? : Decidable R) →∀[ R ⇒ ⌊ R? ⌋ ]toWitness {zero} R R? with R?... | true because _ = _... | no ¬r = ⊥-elim ∘′ ¬rtoWitness {suc n} R R? = toWitness (R _) (R? _)
-------------------------------------------------------------------------- The Agda standard library---- Properties of homogeneous binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary where-------------------------------------------------------------------------- Re-export various components of the binary relation hierarchyopen import Relation.Binary.Core publicopen import Relation.Binary.Definitions publicopen import Relation.Binary.Structures publicopen import Relation.Binary.Structures.Biased publicopen import Relation.Binary.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Typeclasses for use with instance arguments------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.TypeClasses whereopen import Relation.Binary.Structures using (IsDecEquivalence; IsDecTotalOrder) publicopen IsDecEquivalence {{...}} using (_≟_) publicopen IsDecTotalOrder {{...}} using (_≤?_) public
-------------------------------------------------------------------------- The Agda standard library---- Structures for homogeneous binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via `Relation.Binary`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Relation.Binary.Structures{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhereopen import Data.Product.Base using (proj₁; proj₂; _,_)open import Level using (Level; _⊔_)open import Relation.Nullary.Negation.Core using (¬_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Consequencesopen import Relation.Binary.Definitionsprivatevariableℓ₂ : Level-------------------------------------------------------------------------- Equivalences-------------------------------------------------------------------------- Note all the following equivalences refer to the equality provided-- as a module parameter at the top of this file.record IsPartialEquivalence : Set (a ⊔ ℓ) wherefieldsym : Symmetric _≈_trans : Transitive _≈_-- The preorders of this library are defined in terms of an underlying-- equivalence relation, and hence equivalence relations are not-- defined in terms of preorders.-- To preserve backwards compatability, equivalence relations are-- not defined in terms of their partial counterparts.record IsEquivalence : Set (a ⊔ ℓ) wherefieldrefl : Reflexive _≈_sym : Symmetric _≈_trans : Transitive _≈_reflexive : _≡_ ⇒ _≈_reflexive ≡.refl = reflisPartialEquivalence : IsPartialEquivalenceisPartialEquivalence = record{ sym = sym; trans = trans}record IsDecEquivalence : Set (a ⊔ ℓ) whereinfix 4 _≟_fieldisEquivalence : IsEquivalence_≟_ : Decidable _≈_open IsEquivalence isEquivalence public-------------------------------------------------------------------------- Preorders------------------------------------------------------------------------record IsPreorder (_≲_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisEquivalence : IsEquivalence-- Reflexivity is expressed in terms of the underlying equality:reflexive : _≈_ ⇒ _≲_trans : Transitive _≲_module Eq = IsEquivalence isEquivalencerefl : Reflexive _≲_refl = reflexive Eq.refl≲-respˡ-≈ : _≲_ Respectsˡ _≈_≲-respˡ-≈ x≈y x∼z = trans (reflexive (Eq.sym x≈y)) x∼z≲-respʳ-≈ : _≲_ Respectsʳ _≈_≲-respʳ-≈ x≈y z∼x = trans z∼x (reflexive x≈y)≲-resp-≈ : _≲_ Respects₂ _≈_≲-resp-≈ = ≲-respʳ-≈ , ≲-respˡ-≈∼-respˡ-≈ = ≲-respˡ-≈{-# WARNING_ON_USAGE ∼-respˡ-≈"Warning: ∼-respˡ-≈ was deprecated in v2.0.Please use ≲-respˡ-≈ instead. "#-}∼-respʳ-≈ = ≲-respʳ-≈{-# WARNING_ON_USAGE ∼-respʳ-≈"Warning: ∼-respʳ-≈ was deprecated in v2.0.Please use ≲-respʳ-≈ instead. "#-}∼-resp-≈ = ≲-resp-≈{-# WARNING_ON_USAGE ∼-resp-≈"Warning: ∼-resp-≈ was deprecated in v2.0.Please use ≲-resp-≈ instead. "#-}record IsTotalPreorder (_≲_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisPreorder : IsPreorder _≲_total : Total _≲_open IsPreorder isPreorder public-------------------------------------------------------------------------- Partial orders------------------------------------------------------------------------record IsPartialOrder (_≤_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisPreorder : IsPreorder _≤_antisym : Antisymmetric _≈_ _≤_open IsPreorder isPreorder publicrenaming( ∼-respˡ-≈ to ≤-respˡ-≈; ∼-respʳ-≈ to ≤-respʳ-≈; ∼-resp-≈ to ≤-resp-≈)record IsDecPartialOrder (_≤_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) whereinfix 4 _≟_ _≤?_fieldisPartialOrder : IsPartialOrder _≤__≟_ : Decidable _≈__≤?_ : Decidable _≤_open IsPartialOrder isPartialOrder publichiding (module Eq)module Eq whereisDecEquivalence : IsDecEquivalenceisDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = _≟_}open IsDecEquivalence isDecEquivalence publicrecord IsStrictPartialOrder (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisEquivalence : IsEquivalenceirrefl : Irreflexive _≈_ _<_trans : Transitive _<_<-resp-≈ : _<_ Respects₂ _≈_module Eq = IsEquivalence isEquivalenceasym : Asymmetric _<_asym {x} {y} = trans∧irr⇒asym Eq.refl trans irrefl {x = x} {y}<-respʳ-≈ : _<_ Respectsʳ _≈_<-respʳ-≈ = proj₁ <-resp-≈<-respˡ-≈ : _<_ Respectsˡ _≈_<-respˡ-≈ = proj₂ <-resp-≈record IsDecStrictPartialOrder (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) whereinfix 4 _≟_ _<?_fieldisStrictPartialOrder : IsStrictPartialOrder _<__≟_ : Decidable _≈__<?_ : Decidable _<_privatemodule SPO = IsStrictPartialOrder isStrictPartialOrderopen SPO public hiding (module Eq)module Eq whereisDecEquivalence : IsDecEquivalenceisDecEquivalence = record{ isEquivalence = SPO.isEquivalence; _≟_ = _≟_}open IsDecEquivalence isDecEquivalence public-------------------------------------------------------------------------- Total orders------------------------------------------------------------------------record IsTotalOrder (_≤_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisPartialOrder : IsPartialOrder _≤_total : Total _≤_open IsPartialOrder isPartialOrder publicisTotalPreorder : IsTotalPreorder _≤_isTotalPreorder = record{ isPreorder = isPreorder; total = total}record IsDecTotalOrder (_≤_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) whereinfix 4 _≟_ _≤?_fieldisTotalOrder : IsTotalOrder _≤__≟_ : Decidable _≈__≤?_ : Decidable _≤_open IsTotalOrder isTotalOrder publichiding (module Eq)isDecPartialOrder : IsDecPartialOrder _≤_isDecPartialOrder = record{ isPartialOrder = isPartialOrder; _≟_ = _≟_; _≤?_ = _≤?_}module Eq whereisDecEquivalence : IsDecEquivalenceisDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = _≟_}open IsDecEquivalence isDecEquivalence public-- Note that these orders are decidable. The current implementation-- of `Trichotomous` subsumes irreflexivity and asymmetry. See-- `Relation.Binary.Structures.Biased` for ways of constructing this-- record without having to prove `isStrictPartialOrder`.record IsStrictTotalOrder (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisStrictPartialOrder : IsStrictPartialOrder _<_compare : Trichotomous _≈_ _<_open IsStrictPartialOrder isStrictPartialOrder publichiding (module Eq)-- `Trichotomous` necessarily separates out the equality case so-- it implies decidability.infix 4 _≟_ _<?__≟_ : Decidable _≈__≟_ = tri⇒dec≈ compare_<?_ : Decidable _<__<?_ = tri⇒dec< compareisDecStrictPartialOrder : IsDecStrictPartialOrder _<_isDecStrictPartialOrder = record{ isStrictPartialOrder = isStrictPartialOrder; _≟_ = _≟_; _<?_ = _<?_}-- Redefine the `Eq` module to include decidability proofsmodule Eq whereisDecEquivalence : IsDecEquivalenceisDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = _≟_}open IsDecEquivalence isDecEquivalence publicisDecEquivalence : IsDecEquivalenceisDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = _≟_}{-# WARNING_ON_USAGE isDecEquivalence"Warning: isDecEquivalence was deprecated in v2.0.Please use Eq.isDecEquivalence instead. "#-}record IsDenseLinearOrder (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisStrictTotalOrder : IsStrictTotalOrder _<_dense : Dense _<_open IsStrictTotalOrder isStrictTotalOrder public-------------------------------------------------------------------------- Apartness relations------------------------------------------------------------------------record IsApartnessRelation (_#_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldirrefl : Irreflexive _≈_ _#_sym : Symmetric _#_cotrans : Cotransitive _#__¬#_ : A → A → Set _x ¬# y = ¬ (x # y)
-------------------------------------------------------------------------- The Agda standard library---- Ways to give instances of certain structures where some fields can-- be given in terms of others-------------------------------------------------------------------------- The contents of this module should be accessed via `Relation.Binary`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Relation.Binary.Structures.Biased{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhereopen import Level using (Level; _⊔_)open import Relation.Binary.Consequencesopen import Relation.Binary.Definitionsopen import Relation.Binary.Structures _≈_privatevariableℓ₂ : Level-- To construct a StrictTotalOrder you only need to prove transitivity and-- trichotomy as the current implementation of `Trichotomous` subsumes-- irreflexivity and asymmetry.record IsStrictTotalOrderᶜ (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) wherefieldisEquivalence : IsEquivalencetrans : Transitive _<_compare : Trichotomous _≈_ _<_isStrictTotalOrderᶜ : IsStrictTotalOrder _<_isStrictTotalOrderᶜ = record{ isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = tri⇒irr compare; trans = trans; <-resp-≈ = trans∧tri⇒resp Eq.sym Eq.trans trans compare}; compare = compare} where module Eq = IsEquivalence isEquivalenceopen IsStrictTotalOrderᶜ publicusing (isStrictTotalOrderᶜ)
-------------------------------------------------------------------------- The Agda standard library---- Concepts from rewriting theory-- Definitions are based on "Term Rewriting Systems" by J.W. Klop------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Rewriting whereopen import Agda.Builtin.Equality using (_≡_ ; refl)open import Data.Product.Base using (_×_ ; ∃ ; -,_; _,_ ; proj₁ ; proj₂)open import Data.Empty using (⊥-elim)open import Function.Base using (flip)open import Induction.WellFounded using (WellFounded; Acc; acc)open import Relation.Binary.Core using (REL; Rel)open import Relation.Binary.Construct.Closure.Equivalence using (EqClosure)open import Relation.Binary.Construct.Closure.Equivalence.Propertiesusing (a—↠b&a—↠c⇒b↔c)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (Star; _◅_; ε; _◅◅_)open import Relation.Binary.Construct.Closure.Symmetric using (fwd; bwd)open import Relation.Binary.Construct.Closure.Transitiveusing (Plus; [_]; _∼⁺⟨_⟩_)open import Relation.Nullary.Negation.Core using (¬_)-- The following definitions are taken from Klop [5]module _ {a ℓ} {A : Set a} (_⟶_ : Rel A ℓ) whereprivate_⟵_ = flip _⟶__—↠_ = Star _⟶__↔_ = EqClosure _⟶_IsNormalForm : A → Set _IsNormalForm a = ¬ ∃ λ b → (a ⟶ b)HasNormalForm : A → Set _HasNormalForm b = ∃ λ a → IsNormalForm a × (b —↠ a)NormalForm : Set _NormalForm = ∀ {a b} → IsNormalForm a → b ↔ a → b —↠ aWeaklyNormalizing : Set _WeaklyNormalizing = ∀ a → HasNormalForm aStronglyNormalizing : Set _StronglyNormalizing = WellFounded _⟵_UniqueNormalForm : Set _UniqueNormalForm = ∀ {a b} → IsNormalForm a → IsNormalForm b → a ↔ b → a ≡ bConfluent : Set _Confluent = ∀ {A B C} → A —↠ B → A —↠ C → ∃ λ D → (B —↠ D) × (C —↠ D)WeaklyConfluent : Set _WeaklyConfluent = ∀ {A B C} → A ⟶ B → A ⟶ C → ∃ λ D → (B —↠ D) × (C —↠ D)Deterministic : ∀ {a b ℓ₁ ℓ₂} → {A : Set a} → {B : Set b} → Rel B ℓ₁ → REL A B ℓ₂ → Set _Deterministic _≈_ _—→_ = ∀ {x y z} → x —→ y → x —→ z → y ≈ zmodule _ {a ℓ} {A : Set a} {_⟶_ : Rel A ℓ} whereprivate_—↠_ = Star _⟶__↔_ = EqClosure _⟶__⟶₊_ = Plus _⟶_det⇒conf : Deterministic _≡_ _⟶_ → Confluent _⟶_det⇒conf det ε rs₂ = -, rs₂ , εdet⇒conf det rs₁ ε = -, ε , rs₁det⇒conf det (r₁ ◅ rs₁) (r₂ ◅ rs₂)rewrite det r₁ r₂ = det⇒conf det rs₁ rs₂conf⇒wcr : Confluent _⟶_ → WeaklyConfluent _⟶_conf⇒wcr c fst snd = c (fst ◅ ε) (snd ◅ ε)conf⇒nf : Confluent _⟶_ → NormalForm _⟶_conf⇒nf c aIsNF ε = εconf⇒nf c aIsNF (fwd x ◅ rest) = x ◅ conf⇒nf c aIsNF restconf⇒nf c aIsNF (bwd y ◅ rest) with c (y ◅ ε) (conf⇒nf c aIsNF rest)... | _ , _ , x ◅ _ = ⊥-elim (aIsNF (_ , x))... | _ , left , ε = leftconf⇒unf : Confluent _⟶_ → UniqueNormalForm _⟶_conf⇒unf _ _ _ ε = reflconf⇒unf _ aIsNF _ (fwd x ◅ _) = ⊥-elim (aIsNF (_ , x))conf⇒unf c aIsNF bIsNF (bwd y ◅ r) with c (y ◅ ε) (conf⇒nf c bIsNF r)... | _ , ε , x ◅ _ = ⊥-elim (bIsNF (_ , x))... | _ , x ◅ _ , _ = ⊥-elim (aIsNF (_ , x))... | _ , ε , ε = reflun&wn⇒cr : UniqueNormalForm _⟶_ → WeaklyNormalizing _⟶_ → Confluent _⟶_un&wn⇒cr un wn {a} {b} {c} aToB aToC with wn b | wn c... | (d , (d-nf , bToD)) | (e , (e-nf , cToE))with un d-nf e-nf (a—↠b&a—↠c⇒b↔c (aToB ◅◅ bToD) (aToC ◅◅ cToE))... | refl = d , bToD , cToE-- Newman's lemmasn&wcr⇒cr : StronglyNormalizing _⟶₊_ → WeaklyConfluent _⟶_ → Confluent _⟶_sn&wcr⇒cr sn wcr = helper (sn _) wherestarToPlus : ∀ {a b c} → (a ⟶ b) → b —↠ c → a ⟶₊ cstarToPlus aToB ε = [ aToB ]starToPlus {a} aToB (e ◅ bToC) = a ∼⁺⟨ [ aToB ] ⟩ (starToPlus e bToC)helper : ∀ {a b c} → (acc : Acc (flip _⟶₊_) a) →a —↠ b → a —↠ c → ∃ λ d → (b —↠ d) × (c —↠ d)helper _ ε snd = -, snd , εhelper _ fst ε = -, ε , fsthelper (acc g) (toJ ◅ fst) (toK ◅ snd) = result wherewcrProof = wcr toJ toKinnerPoint = proj₁ wcrProofjToInner = proj₁ (proj₂ wcrProof)kToInner = proj₂ (proj₂ wcrProof)lhs = helper (g [ toJ ]) fst jToInnerrhs = helper (g [ toK ]) snd kToInnerfromAB = proj₁ (proj₂ lhs)fromInnerB = proj₂ (proj₂ lhs)fromAC = proj₁ (proj₂ rhs)fromInnerC = proj₂ (proj₂ rhs)aToInner : _ ⟶₊ innerPointaToInner = starToPlus toJ jToInnerfinalRecursion = helper (g aToInner) fromInnerB fromInnerCbMidToDest = proj₁ (proj₂ finalRecursion)cMidToDest = proj₂ (proj₂ finalRecursion)result : ∃ λ d → (_ —↠ d) × (_ —↠ d)result = _ , fromAB ◅◅ bMidToDest , fromAC ◅◅ cMidToDest
-------------------------------------------------------------------------- The Agda standard library---- Helpers intended to ease the development of "tactics" which use-- proof by reflection------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Fin.Base using (Fin)open import Data.Nat.Base using (ℕ)open import Data.Vec.Base as Vec using (Vec; allFin)open import Function.Base using (id; _⟨_⟩_)open import Function.Bundles using (module Equivalence)open import Level using (Level)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.PropositionalEquality.Core as ≡-- Think of the parameters as follows:---- * Expr: A representation of code.-- * var: The Expr type should support a notion of variables.-- * ⟦_⟧: Computes the semantics of an expression. Takes an-- environment mapping variables to something.-- * ⟦_⇓⟧: Computes the semantics of the normal form of the-- expression.-- * correct: Normalisation preserves the semantics.---- Given these parameters two "tactics" are returned, prove and solve.---- For an example of the use of this module, see Algebra.RingSolver.module Relation.Binary.Reflection{e a s}{Expr : ℕ → Set e} {A : Set a}(Sem : Setoid a s)(var : ∀ {n} → Fin n → Expr n)(⟦_⟧ ⟦_⇓⟧ : ∀ {n} → Expr n → Vec A n → Setoid.Carrier Sem)(correct : ∀ {n} (e : Expr n) ρ →⟦ e ⇓⟧ ρ ⟨ Setoid._≈_ Sem ⟩ ⟦ e ⟧ ρ)whereopen import Data.Vec.N-aryopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen Setoid Semopen ≈-Reasoning Sem-- If two normalised expressions are semantically equal, then their-- non-normalised forms are also equal.prove : ∀ {n} (ρ : Vec A n) e₁ e₂ →⟦ e₁ ⇓⟧ ρ ≈ ⟦ e₂ ⇓⟧ ρ →⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρprove ρ e₁ e₂ hyp = begin⟦ e₁ ⟧ ρ ≈⟨ sym (correct e₁ ρ) ⟩⟦ e₁ ⇓⟧ ρ ≈⟨ hyp ⟩⟦ e₂ ⇓⟧ ρ ≈⟨ correct e₂ ρ ⟩⟦ e₂ ⟧ ρ ∎-- Applies the function to all possible "variables".close : ∀ {A : Set e} n → N-ary n (Expr n) A → Aclose n f = f $ⁿ Vec.map var (allFin n)-- A variant of prove which should in many cases be easier to use,-- because variables and environments are handled in a less explicit-- way.---- If the type signature of solve is a bit daunting, then it may be-- helpful to instantiate n with a small natural number and normalise-- the remainder of the type.solve : ∀ n (f : N-ary n (Expr n) (Expr n × Expr n)) →Eqʰ n _≈_ (curryⁿ ⟦ proj₁ (close n f) ⇓⟧) (curryⁿ ⟦ proj₂ (close n f) ⇓⟧) →Eq n _≈_ (curryⁿ ⟦ proj₁ (close n f) ⟧) (curryⁿ ⟦ proj₂ (close n f) ⟧)solve n f hyp =curryⁿ-cong _≈_ ⟦ proj₁ (close n f) ⟧ ⟦ proj₂ (close n f) ⟧(λ ρ → prove ρ (proj₁ (close n f)) (proj₂ (close n f))(curryⁿ-cong⁻¹ _≈_⟦ proj₁ (close n f) ⇓⟧ ⟦ proj₂ (close n f) ⇓⟧(Eqʰ-to-Eq n _≈_ hyp) ρ))-- A variant of solve which does not require that the normal form-- equality is proved for an arbitrary environment.solve₁ : ∀ n (f : N-ary n (Expr n) (Expr n × Expr n)) →∀ⁿ n (curryⁿ λ ρ →⟦ proj₁ (close n f) ⇓⟧ ρ ≈ ⟦ proj₂ (close n f) ⇓⟧ ρ →⟦ proj₁ (close n f) ⟧ ρ ≈ ⟦ proj₂ (close n f) ⟧ ρ)solve₁ n f =Equivalence.from (uncurry-∀ⁿ n) λ ρ →≡.subst id (≡.sym (left-inverse (λ _ → _ ≈ _ → _ ≈ _) ρ))(prove ρ (proj₁ (close n f)) (proj₂ (close n f)))-- A variant of _,_ which is intended to make uses of solve and solve₁-- look a bit nicer.infix 4 _⊜__⊜_ : ∀ {n} → Expr n → Expr n → Expr n × Expr n_⊜_ = _,_
-------------------------------------------------------------------------- The Agda standard library---- Syntax for the building blocks of equational reasoning modules------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_; suc)open import Relation.Nullary.Decidable.Coreusing (Dec; True; toWitness)open import Relation.Nullary.Negation.Core using (contradiction)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Definitionsusing (_Respectsʳ_; Asymmetric; Trans; Sym; Reflexive)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_)-- List of `Reasoning` modules that do not use this framework and so-- need to be updated manually if the syntax changes.---- Data/Vec/Relation/Binary/Equality/Cast-- Relation/Binary/HeterogeneousEquality-- Effect/Monad/Partiality-- Effect/Monad/Partiality/All-- Codata/Guarded/Stream/Relation/Binary/Pointwise-- Function/Reasoningmodule Relation.Binary.Reasoning.Syntax whereprivatevariablea ℓ₁ ℓ₂ ℓ₃ ℓ₄ : LevelA B C : Set ax y z : A-------------------------------------------------------------------------- Syntax for beginning a reasoning chain-------------------------------------------------------------------------------------------------------------------------------------------------- Basic begin syntaxmodule begin-syntax(R : REL A B ℓ₁){S : REL A B ℓ₂}(reflexive : R ⇒ S)whereinfix 1 begin_begin_ : R x y → S x ybegin_ = reflexive-------------------------------------------------------------------------- Begin subrelation syntax-- Sometimes we want to support sub-relations with the-- same reasoning operators as the main relations (e.g. perform equality-- proofs with non-strict reasoning operators). This record bundles all-- the parts needed to extract the sub-relation proofs.record SubRelation {A : Set a} (R : Rel A ℓ₁) ℓ₂ ℓ₃ : Set (a ⊔ ℓ₁ ⊔ suc ℓ₂ ⊔ suc ℓ₃) wherefieldS : Rel A ℓ₂IsS : R x y → Set ℓ₃IsS? : ∀ (xRy : R x y) → Dec (IsS xRy)extract : ∀ {xRy : R x y} → IsS xRy → S x ymodule begin-subrelation-syntax(R : Rel A ℓ₁)(sub : SubRelation R ℓ₂ ℓ₃)whereopen SubRelation subinfix 1 begin_begin_ : ∀ {x y} (xRy : R x y) → {s : True (IsS? xRy)} → S x ybegin_ r {s} = extract (toWitness s)-- Begin equality syntaxmodule begin-equality-syntax(R : Rel A ℓ₁)(sub : SubRelation R ℓ₂ ℓ₃) whereopen begin-subrelation-syntax R sub publicrenaming (begin_ to begin-equality_)-- Begin apartness syntaxmodule begin-apartness-syntax(R : Rel A ℓ₁)(sub : SubRelation R ℓ₂ ℓ₃) whereopen begin-subrelation-syntax R sub publicrenaming (begin_ to begin-apartness_)-- Begin strict syntaxmodule begin-strict-syntax(R : Rel A ℓ₁)(sub : SubRelation R ℓ₂ ℓ₃) whereopen begin-subrelation-syntax R sub publicrenaming (begin_ to begin-strict_)-------------------------------------------------------------------------- Begin membership syntaxmodule begin-membership-syntax(R : Rel A ℓ₁)(_∈_ : REL B A ℓ₂)(resp : _∈_ Respectsʳ R) whereinfix 1 step-∈step-∈ : ∀ (x : B) {xs ys} → R xs ys → x ∈ xs → x ∈ ysstep-∈ x = respsyntax step-∈ x xs⊆ys x∈xs = x ∈⟨ x∈xs ⟩ xs⊆ys-------------------------------------------------------------------------- Begin contradiction syntax-- Used with asymmetric subrelations to derive a contradiction from a-- proof that an element is related to itself.module begin-contradiction-syntax(R : Rel A ℓ₁)(sub : SubRelation R ℓ₂ ℓ₃)(asym : Asymmetric (SubRelation.S sub))whereopen SubRelation subinfix 1 begin-contradiction_begin-contradiction_ : ∀ (xRx : R x x) {s : True (IsS? xRx)} →∀ {b} {B : Set b} → Bbegin-contradiction_ {x} r {s} = contradiction x<x (asym x<x)wherex<x : S x xx<x = extract (toWitness s)-------------------------------------------------------------------------- Syntax for continuing a chain of reasoning steps-------------------------------------------------------------------------- Note that the arguments to the `step`s are not provided in their-- "natural" order and syntax declarations are later used to re-order-- them. This is because the `step` ordering allows the type-checker to-- better infer the middle argument `y` from the `_IsRelatedTo_`-- argument (see issue 622).---- This has two practical benefits. First it speeds up type-checking by-- approximately a factor of 5. Secondly it allows the combinators to be-- used with macros that use reflection, e.g. `Tactic.RingSolver`, where-- they need to be able to extract `y` using reflection.-------------------------------------------------------------------------- Syntax for unidirectional relations-- See https://github.com/agda/agda-stdlib/issues/2150 for a possible-- simplification.module _{R : REL A B ℓ₂}(S : REL B C ℓ₁)(T : REL A C ℓ₃)(step : Trans R S T)whereforward : ∀ (x : A) {y z} → S y z → R x y → T x zforward x yRz x∼y = step {x} x∼y yRz-- Arbitrary relation syntaxmodule ∼-syntax whereinfixr 2 step-∼step-∼ = forwardsyntax step-∼ x yRz x∼y = x ∼⟨ x∼y ⟩ yRz-- Preorder syntaxmodule ≲-syntax whereinfixr 2 step-≲step-≲ = forwardsyntax step-≲ x yRz x≲y = x ≲⟨ x≲y ⟩ yRz-- Partial order syntaxmodule ≤-syntax whereinfixr 2 step-≤step-≤ = forwardsyntax step-≤ x yRz x≤y = x ≤⟨ x≤y ⟩ yRz-- Strict partial order syntaxmodule <-syntax whereinfixr 2 step-<step-< = forwardsyntax step-< x yRz x<y = x <⟨ x<y ⟩ yRz-- Subset order syntaxmodule ⊆-syntax whereinfixr 2 step-⊆step-⊆ = forwardsyntax step-⊆ x yRz x⊆y = x ⊆⟨ x⊆y ⟩ yRz-- Strict subset order syntaxmodule ⊂-syntax whereinfixr 2 step-⊂step-⊂ = forwardsyntax step-⊂ x yRz x⊂y = x ⊂⟨ x⊂y ⟩ yRz-- Square subset order syntaxmodule ⊑-syntax whereinfixr 2 step-⊑step-⊑ = forwardsyntax step-⊑ x yRz x⊑y = x ⊑⟨ x⊑y ⟩ yRz-- Strict square subset order syntaxmodule ⊏-syntax whereinfixr 2 step-⊏step-⊏ = forwardsyntax step-⊏ x yRz x⊏y = x ⊏⟨ x⊏y ⟩ yRz-- Divisibility syntaxmodule ∣-syntax whereinfixr 2 step-∣step-∣ = forwardsyntax step-∣ x yRz x∣y = x ∣⟨ x∣y ⟩ yRz-- Single-step syntaxmodule ⟶-syntax whereinfixr 2 step-⟶step-⟶ = forwardsyntax step-⟶ x yRz x∣y = x ⟶⟨ x∣y ⟩ yRz-- Multi-step syntaxmodule ⟶*-syntax whereinfixr 2 step-⟶*step-⟶* = forwardsyntax step-⟶* x yRz x∣y = x ⟶*⟨ x∣y ⟩ yRz-------------------------------------------------------------------------- Syntax for bidirectional relationsmodule _{U : REL B A ℓ₄}(sym : Sym U R)wherebackward : ∀ x {y z} → S y z → U y x → T x zbackward x yRz x≈y = forward x yRz (sym x≈y)-- Setoid equality syntaxmodule ≈-syntax whereinfixr 2 step-≈-⟩ step-≈-⟨step-≈-⟩ = forwardstep-≈-⟨ = backwardsyntax step-≈-⟩ x yRz x≈y = x ≈⟨ x≈y ⟩ yRzsyntax step-≈-⟨ x yRz y≈x = x ≈⟨ y≈x ⟨ yRz-- Deprecatedinfixr 2 step-≈ step-≈˘step-≈ = step-≈-⟩{-# WARNING_ON_USAGE step-≈"Warning: step-≈ was deprecated in v2.0.Please use step-≈-⟩ instead."#-}step-≈˘ = step-≈-⟨{-# WARNING_ON_USAGE step-≈˘"Warning: step-≈˘ and _≈˘⟨_⟩_ was deprecated in v2.0.Please use step-≈-⟨ and _≈⟨_⟨_ instead."#-}syntax step-≈˘ x yRz y≈x = x ≈˘⟨ y≈x ⟩ yRz-- Container equality syntaxmodule ≋-syntax whereinfixr 2 step-≋-⟩ step-≋-⟨step-≋-⟩ = forwardstep-≋-⟨ = backwardsyntax step-≋-⟩ x yRz x≋y = x ≋⟨ x≋y ⟩ yRzsyntax step-≋-⟨ x yRz y≋x = x ≋⟨ y≋x ⟨ yRz-- Don't remove until https://github.com/agda/agda/issues/5617 fixed.infixr 2 step-≋ step-≋˘step-≋ = step-≋-⟩{-# WARNING_ON_USAGE step-≋"Warning: step-≋ was deprecated in v2.0.Please use step-≋-⟩ instead."#-}step-≋˘ = step-≋-⟨{-# WARNING_ON_USAGE step-≋˘"Warning: step-≋˘ and _≋˘⟨_⟩_ was deprecated in v2.0.Please use step-≋-⟨ and _≋⟨_⟨_ instead."#-}syntax step-≋˘ x yRz y≋x = x ≋˘⟨ y≋x ⟩ yRz-- Other equality syntaxmodule ≃-syntax whereinfixr 2 step-≃-⟩ step-≃-⟨step-≃-⟩ = forwardstep-≃-⟨ = backwardsyntax step-≃-⟩ x yRz x≃y = x ≃⟨ x≃y ⟩ yRzsyntax step-≃-⟨ x yRz y≃x = x ≃⟨ y≃x ⟨ yRz-- Apartness relation syntaxmodule #-syntax whereinfixr 2 step-#-⟩ step-#-⟨step-#-⟩ = forwardstep-#-⟨ = backwardsyntax step-#-⟩ x yRz x#y = x #⟨ x#y ⟩ yRzsyntax step-#-⟨ x yRz y#x = x #⟨ y#x ⟨ yRz-- Don't remove until https://github.com/agda/agda/issues/5617 fixed.infixr 2 step-# step-#˘step-# = step-#-⟩{-# WARNING_ON_USAGE step-#"Warning: step-# was deprecated in v2.0.Please use step-#-⟩ instead."#-}step-#˘ = step-#-⟨{-# WARNING_ON_USAGE step-#˘"Warning: step-#˘ and _#˘⟨_⟩_ was deprecated in v2.0.Please use step-#-⟨ and _#⟨_⟨_ instead."#-}syntax step-#˘ x yRz y#x = x #˘⟨ y#x ⟩ yRz-- Bijection syntaxmodule ⤖-syntax whereinfixr 2 step-⤖ step-⬻step-⤖ = forwardstep-⬻ = backwardsyntax step-⤖ x yRz x⤖y = x ⤖⟨ x⤖y ⟩ yRzsyntax step-⬻ x yRz y⤖x = x ⬻⟨ y⤖x ⟩ yRz-- Inverse syntaxmodule ↔-syntax whereinfixr 2 step-↔-⟩ step-↔-⟨step-↔-⟩ = forwardstep-↔-⟨ = backwardsyntax step-↔-⟩ x yRz x↔y = x ↔⟨ x↔y ⟩ yRzsyntax step-↔-⟨ x yRz y↔x = x ↔⟨ y↔x ⟨ yRz-- Inverse syntaxmodule ↭-syntax whereinfixr 2 step-↭-⟩ step-↭-⟨step-↭-⟩ = forwardstep-↭-⟨ = backwardsyntax step-↭-⟩ x yRz x↭y = x ↭⟨ x↭y ⟩ yRzsyntax step-↭-⟨ x yRz y↭x = x ↭⟨ y↭x ⟨ yRz-- Don't remove until https://github.com/agda/agda/issues/5617 fixed.infixr 2 step-↭ step-↭˘step-↭ = forward{-# WARNING_ON_USAGE step-↭"Warning: step-↭ was deprecated in v2.0.Please use step-↭-⟩ instead."#-}step-↭˘ = backward{-# WARNING_ON_USAGE step-↭˘"Warning: step-↭˘ and _↭˘⟨_⟩_ was deprecated in v2.0.Please use step-↭-⟨ and _↭⟨_⟨_ instead."#-}syntax step-↭˘ x yRz y↭x = x ↭˘⟨ y↭x ⟩ yRz-------------------------------------------------------------------------- Propositional equality-- Crucially often the step function cannot just be `subst` or pattern-- match on `refl` as we often want to compute which constructor the-- relation begins with, in order for the implicit subrelation-- arguments to resolve. See `≡-noncomputable-syntax` below if this-- is not required.module ≡-syntax(R : REL A B ℓ₁)(step : Trans _≡_ R R)whereinfixr 2 step-≡-⟩ step-≡-∣ step-≡-⟨step-≡-⟩ = forward R R stepstep-≡-∣ : ∀ x {y} → R x y → R x ystep-≡-∣ x xRy = xRystep-≡-⟨ = backward R R step ≡.symsyntax step-≡-⟩ x yRz x≡y = x ≡⟨ x≡y ⟩ yRzsyntax step-≡-∣ x xRy = x ≡⟨⟩ xRysyntax step-≡-⟨ x yRz y≡x = x ≡⟨ y≡x ⟨ yRz-- Don't remove until https://github.com/agda/agda/issues/5617 fixed.infixr 2 step-≡ step-≡˘step-≡ = step-≡-⟩{-# WARNING_ON_USAGE step-≡"Warning: step-≡ was deprecated in v2.0.Please use step-≡-⟩ instead."#-}step-≡˘ = step-≡-⟨{-# WARNING_ON_USAGE step-≡˘"Warning: step-≡˘ and _≡˘⟨_⟩_ was deprecated in v2.0.Please use step-≡-⟨ and _≡⟨_⟨_ instead."#-}syntax step-≡˘ x yRz y≡x = x ≡˘⟨ y≡x ⟩ yRz-- Unlike ≡-syntax above, chains of reasoning using this syntax will not-- reduce when proofs of propositional equality which are not definitionally-- equal to `refl` are passed.module ≡-noncomputing-syntax (R : REL A B ℓ₁) whereprivatestep : Trans _≡_ R Rstep ≡.refl xRy = xRyopen ≡-syntax R step public-------------------------------------------------------------------------- Syntax for ending a chain of reasoning------------------------------------------------------------------------module end-syntax(R : Rel A ℓ₁)(reflexive : Reflexive R)whereinfix 3 _∎_∎ : ∀ x → R x xx ∎ = reflexive
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for "equational reasoning" using a strict partial-- order.-------------------------------------------------------------------------- Example uses:---- u≤x : u ≤ x-- u≤x = begin-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w≤x ⟩-- x ∎---- u<x : u < x-- u<x = begin-strict-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w≤x ⟩-- x ∎---- u<e : u < e-- u<e = begin-strict-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w<x ⟩-- x ≤⟨ x≤y ⟩-- y <⟨ y<z ⟩-- z ≡⟨ d≡z ⟨-- d ≈⟨ e≈d ⟨-- e ∎---- u≈w : u ≈ w-- u≈w = begin-equality-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w ∎{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictPartialOrder)module Relation.Binary.Reasoning.StrictPartialOrder{p₁ p₂ p₃} (S : StrictPartialOrder p₁ p₂ p₃) whereopen StrictPartialOrder Simport Relation.Binary.Construct.StrictToNonStrict _≈_ _<_ as NonStrict-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Relation.Binary.Reasoning.Base.Triple(NonStrict.isPreorder₂ isStrictPartialOrder)asymtrans<-resp-≈NonStrict.<⇒≤(NonStrict.<-≤-trans trans <-respʳ-≈)(NonStrict.≤-<-trans Eq.sym trans <-respˡ-≈)public
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for reasoning with a setoid-------------------------------------------------------------------------- Example use:-- n*0≡0 : ∀ n → n * 0 ≡ 0-- n*0≡0 zero = refl-- n*0≡0 (suc n) = begin-- suc n * 0 ≈⟨ refl ⟩-- n * 0 + 0 ≈⟨ ... ⟩-- n * 0 ≈⟨ n*0≡0 n ⟩-- 0 ∎-- Module `≡-Reasoning` in `Relation.Binary.PropositionalEquality`-- is recommended for equational reasoning when the underlying equality-- is `_≡_`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Reasoning.Syntax using (module ≈-syntax)module Relation.Binary.Reasoning.Setoid {s₁ s₂} (S : Setoid s₁ s₂) whereopen Setoid Simport Relation.Binary.Reasoning.Base.Single _≈_ refl transas SingleRelReasoning-------------------------------------------------------------------------- Reasoning combinators-- Export the combinators for single relation reasoning, hiding the-- single misnamed combinator.open SingleRelReasoning publichiding (step-∼)renaming (∼-go to ≈-go)-- Re-export the equality-based combinators insteadopen ≈-syntax _IsRelatedTo_ _IsRelatedTo_ ≈-go sym public
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for "equational reasoning" using a preorder-------------------------------------------------------------------------- Example uses:---- u∼y : u ∼ y-- u∼y = begin-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w ∼⟨ w∼y ⟩-- y ≈⟨ z≈y ⟩-- z ∎---- u≈w : u ≈ w-- u≈w = begin-equality-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w ≡⟨ x≡w ⟨-- x ∎{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder)module Relation.Binary.Reasoning.Preorder{p₁ p₂ p₃} (P : Preorder p₁ p₂ p₃) whereopen Preorder P-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Relation.Binary.Reasoning.Base.Double isPreorder public
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for reasoning with a partial setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (PartialSetoid)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.PartialSetoid{s₁ s₂} (S : PartialSetoid s₁ s₂) whereopen PartialSetoid Simport Relation.Binary.Reasoning.Base.Partial _≈_ transas ≈-Reasoning-------------------------------------------------------------------------- Reasoning combinators-- Export the combinators for partial relation reasoning, hiding the-- single misnamed combinator.open ≈-Reasoning public hiding (step-∼)-- Re-export the equality-based combinators insteadopen ≈-syntax _IsRelatedTo_ _IsRelatedTo_ ≈-Reasoning.∼-go sym public
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for "equational reasoning" using a partial order-------------------------------------------------------------------------- Example uses:---- u≤x : u ≤ x-- u≤x = begin-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w≤x ⟩-- x ∎---- u<x : u < x-- u<x = begin-strict-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w≤x ⟩-- x ∎---- u<e : u < e-- u<e = begin-strict-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w <⟨ w<x ⟩-- x ≤⟨ x≤y ⟩-- y <⟨ y<z ⟩-- z ≡⟨ d≡z ⟨-- d ≈⟨ e≈d ⟨-- e ∎---- u≈w : u ≈ w-- u≈w = begin-equality-- u ≈⟨ u≈v ⟩-- v ≡⟨ v≡w ⟩-- w ∎{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Poset)module Relation.Binary.Reasoning.PartialOrder{p₁ p₂ p₃} (P : Poset p₁ p₂ p₃) whereopen Poset Popen import Relation.Binary.Construct.NonStrictToStrict _≈_ _≤_as Strictusing (_<_)-------------------------------------------------------------------------- Re-export contents of base moduleopen import Relation.Binary.Reasoning.Base.TripleisPreorder(Strict.<-asym antisym)(Strict.<-trans isPartialOrder)(Strict.<-resp-≈ isEquivalence ≤-resp-≈)Strict.<⇒≤(Strict.<-≤-trans Eq.sym trans antisym ≤-respʳ-≈)(Strict.≤-<-trans trans antisym ≤-respˡ-≈)public
-------------------------------------------------------------------------- The Agda standard library---- Convenient syntax for "equational reasoning" in multiple Setoids.-------------------------------------------------------------------------- Example use:---- open import Data.Maybe.Properties-- open import Data.Maybe.Relation.Binary.Equality-- open import Relation.Binary.Reasoning.MultiSetoid---- begin⟨ S ⟩-- x ≈⟨ drop-just (begin⟨ setoid S ⟩-- just x ≈⟨ justx≈mz ⟩-- mz ≈⟨ mz≈justy ⟩-- just y ∎)⟩-- y ≈⟨ y≈z ⟩-- z ∎-- Note this module is not reimplemented in terms of `Reasoning.Setoid`-- as this introduces unsolved metas as the underlying base module-- `Base.Single` does not require `_≈_` be symmetric.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Reasoning.MultiSetoid whereopen import Level using (Level; _⊔_)open import Function.Base using (case_of_)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Definitions using (Trans; Reflexive)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxprivatevariablea ℓ : Level-------------------------------------------------------------------------- Combinators that take the current setoid as an explicit argument.module _ (S : Setoid a ℓ) whereopen Setoid Sdata IsRelatedTo (x y : _) : Set (a ⊔ ℓ) whererelTo : (x≈y : x ≈ y) → IsRelatedTo x ystart : IsRelatedTo ⇒ _≈_start (relTo x≈y) = x≈y≡-go : Trans _≡_ IsRelatedTo IsRelatedTo≡-go x≡y (relTo y∼z) = relTo (case x≡y of λ where ≡.refl → y∼z)≈-go : Trans _≈_ IsRelatedTo IsRelatedTo≈-go x≈y (relTo y≈z) = relTo (trans x≈y y≈z)end : Reflexive IsRelatedToend = relTo refl-------------------------------------------------------------------------- Reasoning combinators-- Those that take the current setoid as an explicit argument.open begin-syntax IsRelatedTo start publicrenaming (begin_ to begin⟨_⟩_)-- Those that take the current setoid as an implicit argument.module _ {S : Setoid a ℓ} whereopen Setoid Sopen ≡-syntax (IsRelatedTo S) (≡-go S)open ≈-syntax (IsRelatedTo S) (IsRelatedTo S) (≈-go S) sym publicopen end-syntax (IsRelatedTo S) (end S) public
-------------------------------------------------------------------------- The Agda standard library---- The basic code for equational reasoning with three relations:-- equality, strict ordering and non-strict ordering.---------------------------------------------------------------------------- See `Data.Nat.Properties` or `Relation.Binary.Reasoning.PartialOrder`-- for examples of how to instantiate this module.{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (proj₁; proj₂)open import Level using (_⊔_)open import Function.Base using (case_of_)open import Relation.Nullary.Decidable.Coreusing (Dec; yes; no)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitionsusing (Transitive; _Respects₂_; Reflexive; Trans; Irreflexive; Asymmetric)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.Base.Triple {a ℓ₁ ℓ₂ ℓ₃} {A : Set a}{_≈_ : Rel A ℓ₁} {_≤_ : Rel A ℓ₂} {_<_ : Rel A ℓ₃}(isPreorder : IsPreorder _≈_ _≤_)(<-asym : Asymmetric _<_) (<-trans : Transitive _<_) (<-resp-≈ : _<_ Respects₂ _≈_)(<⇒≤ : _<_ ⇒ _≤_)(<-≤-trans : Trans _<_ _≤_ _<_) (≤-<-trans : Trans _≤_ _<_ _<_)whereopen IsPreorder isPreorder-------------------------------------------------------------------------- A datatype to abstract over the current relationinfix 4 _IsRelatedTo_data _IsRelatedTo_ (x y : A) : Set (a ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherestrict : (x<y : x < y) → x IsRelatedTo ynonstrict : (x≤y : x ≤ y) → x IsRelatedTo yequals : (x≈y : x ≈ y) → x IsRelatedTo ystart : _IsRelatedTo_ ⇒ _≤_start (equals x≈y) = reflexive x≈ystart (nonstrict x≤y) = x≤ystart (strict x<y) = <⇒≤ x<y≡-go : Trans _≡_ _IsRelatedTo_ _IsRelatedTo_≡-go x≡y (equals y≈z) = equals (case x≡y of λ where ≡.refl → y≈z)≡-go x≡y (nonstrict y≤z) = nonstrict (case x≡y of λ where ≡.refl → y≤z)≡-go x≡y (strict y<z) = strict (case x≡y of λ where ≡.refl → y<z)≈-go : Trans _≈_ _IsRelatedTo_ _IsRelatedTo_≈-go x≈y (equals y≈z) = equals (Eq.trans x≈y y≈z)≈-go x≈y (nonstrict y≤z) = nonstrict (∼-respˡ-≈ (Eq.sym x≈y) y≤z)≈-go x≈y (strict y<z) = strict (proj₂ <-resp-≈ (Eq.sym x≈y) y<z)≤-go : Trans _≤_ _IsRelatedTo_ _IsRelatedTo_≤-go x≤y (equals y≈z) = nonstrict (∼-respʳ-≈ y≈z x≤y)≤-go x≤y (nonstrict y≤z) = nonstrict (trans x≤y y≤z)≤-go x≤y (strict y<z) = strict (≤-<-trans x≤y y<z)<-go : Trans _<_ _IsRelatedTo_ _IsRelatedTo_<-go x<y (equals y≈z) = strict (proj₁ <-resp-≈ y≈z x<y)<-go x<y (nonstrict y≤z) = strict (<-≤-trans x<y y≤z)<-go x<y (strict y<z) = strict (<-trans x<y y<z)stop : Reflexive _IsRelatedTo_stop = equals Eq.refl-------------------------------------------------------------------------- Types that are used to ensure that the final relation proved by the-- chain of reasoning can be converted into the required relation.data IsStrict {x y} : x IsRelatedTo y → Set (a ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) whereisStrict : ∀ x<y → IsStrict (strict x<y)IsStrict? : ∀ {x y} (x≲y : x IsRelatedTo y) → Dec (IsStrict x≲y)IsStrict? (strict x<y) = yes (isStrict x<y)IsStrict? (nonstrict _) = no λ()IsStrict? (equals _) = no λ()extractStrict : ∀ {x y} {x≲y : x IsRelatedTo y} → IsStrict x≲y → x < yextractStrict (isStrict x<y) = x<ystrictRelation : SubRelation _IsRelatedTo_ _ _strictRelation = record{ IsS = IsStrict; IsS? = IsStrict?; extract = extractStrict}-------------------------------------------------------------------------- Equality sub-relationdata IsEquality {x y} : x IsRelatedTo y → Set (a ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) whereisEquality : ∀ x≈y → IsEquality (equals x≈y)IsEquality? : ∀ {x y} (x≲y : x IsRelatedTo y) → Dec (IsEquality x≲y)IsEquality? (strict _) = no λ()IsEquality? (nonstrict _) = no λ()IsEquality? (equals x≈y) = yes (isEquality x≈y)extractEquality : ∀ {x y} {x≲y : x IsRelatedTo y} → IsEquality x≲y → x ≈ yextractEquality (isEquality x≈y) = x≈yeqRelation : SubRelation _IsRelatedTo_ _ _eqRelation = record{ IsS = IsEquality; IsS? = IsEquality?; extract = extractEquality}-------------------------------------------------------------------------- Reasoning combinatorsopen begin-syntax _IsRelatedTo_ start publicopen begin-equality-syntax _IsRelatedTo_ eqRelation publicopen begin-strict-syntax _IsRelatedTo_ strictRelation publicopen begin-contradiction-syntax _IsRelatedTo_ strictRelation <-asym publicopen ≡-syntax _IsRelatedTo_ ≡-go publicopen ≈-syntax _IsRelatedTo_ _IsRelatedTo_ ≈-go Eq.sym publicopen ≤-syntax _IsRelatedTo_ _IsRelatedTo_ ≤-go publicopen <-syntax _IsRelatedTo_ _IsRelatedTo_ <-go publicopen end-syntax _IsRelatedTo_ stop public
-------------------------------------------------------------------------- The Agda standard library---- The basic code for equational reasoning with a single relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (_⊔_)open import Function.Base using (case_of_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Definitions using (Reflexive; Transitive; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.Base.Single{a ℓ} {A : Set a} (_∼_ : Rel A ℓ)(refl : Reflexive _∼_) (trans : Transitive _∼_)where-------------------------------------------------------------------------- Definition of "related to"-- This seemingly unnecessary type is used to make it possible to-- infer arguments even if the underlying equality evaluates.infix 4 _IsRelatedTo_data _IsRelatedTo_ (x y : A) : Set ℓ whererelTo : (x∼y : x ∼ y) → x IsRelatedTo ystart : _IsRelatedTo_ ⇒ _∼_start (relTo x∼y) = x∼y∼-go : Trans _∼_ _IsRelatedTo_ _IsRelatedTo_∼-go x∼y (relTo y∼z) = relTo (trans x∼y y∼z)≡-go : Trans _≡_ _IsRelatedTo_ _IsRelatedTo_≡-go x≡y (relTo y∼z) = relTo (case x≡y of λ where ≡.refl → y∼z)stop : Reflexive _IsRelatedTo_stop = relTo refl-------------------------------------------------------------------------- Reasoning combinatorsopen begin-syntax _IsRelatedTo_ start publicopen ≡-syntax _IsRelatedTo_ ≡-go publicopen ∼-syntax _IsRelatedTo_ _IsRelatedTo_ ∼-go publicopen end-syntax _IsRelatedTo_ stop public
-------------------------------------------------------------------------- The Agda standard library---- The basic code for equational reasoning with a non-reflexive relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Function.Base using (case_of_)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Transitive; Trans; Reflexive)open import Relation.Nullary.Decidable using (Dec; yes; no)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.Base.Partial{a ℓ} {A : Set a} (_∼_ : Rel A ℓ) (trans : Transitive _∼_)where-------------------------------------------------------------------------- Definition of "related to"-- This seemingly unnecessary type is used to make it possible to-- infer arguments even if the underlying equality evaluates.infix 4 _IsRelatedTo_data _IsRelatedTo_ : A → A → Set (a ⊔ ℓ) wheresingleStep : ∀ x → x IsRelatedTo xmultiStep : ∀ {x y} (x∼y : x ∼ y) → x IsRelatedTo y∼-go : Trans _∼_ _IsRelatedTo_ _IsRelatedTo_∼-go x∼y (singleStep y) = multiStep x∼y∼-go x∼y (multiStep y∼z) = multiStep (trans x∼y y∼z)stop : Reflexive _IsRelatedTo_stop = singleStep _-------------------------------------------------------------------------- Types that are used to ensure that the final relation proved by the-- chain of reasoning can be converted into the required relation.data IsMultiStep {x y} : x IsRelatedTo y → Set (a ⊔ ℓ) whereisMultiStep : ∀ x∼y → IsMultiStep (multiStep x∼y)IsMultiStep? : ∀ {x y} (x∼y : x IsRelatedTo y) → Dec (IsMultiStep x∼y)IsMultiStep? (multiStep x<y) = yes (isMultiStep x<y)IsMultiStep? (singleStep _) = no λ()extractMultiStep : ∀ {x y} {x∼y : x IsRelatedTo y} → IsMultiStep x∼y → x ∼ yextractMultiStep (isMultiStep x≈y) = x≈ymultiStepSubRelation : SubRelation _IsRelatedTo_ _ _multiStepSubRelation = record{ IsS = IsMultiStep; IsS? = IsMultiStep?; extract = extractMultiStep}-------------------------------------------------------------------------- Reasoning combinatorsopen begin-subrelation-syntax _IsRelatedTo_ multiStepSubRelation publicopen ≡-noncomputing-syntax _IsRelatedTo_ publicopen ∼-syntax _IsRelatedTo_ _IsRelatedTo_ ∼-go publicopen end-syntax _IsRelatedTo_ stop public-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.6infix 3 _∎⟨_⟩_∎⟨_⟩ : ∀ x → x ∼ x → x IsRelatedTo x_ ∎⟨ x∼x ⟩ = multiStep x∼x{-# WARNING_ON_USAGE _∎⟨_⟩"Warning: _∎⟨_⟩ was deprecated in v1.6.Please use _∎ instead if used in a chain, otherwise simply providethe proof of reflexivity directly without using these combinators."#-}
-------------------------------------------------------------------------- The Agda standard library---- The basic code for equational reasoning with two relations:-- equality and some other ordering.---------------------------------------------------------------------------- See `Data.Nat.Properties` or `Relation.Binary.Reasoning.PartialOrder`-- for examples of how to instantiate this module.{-# OPTIONS --cubical-compatible --safe #-}open import Level using (_⊔_)open import Function.Base using (case_of_)open import Relation.Nullary.Decidable.Core using (Dec; yes; no)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Definitions using (Reflexive; Trans)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.Base.Double {a ℓ₁ ℓ₂} {A : Set a}{_≈_ : Rel A ℓ₁} {_≲_ : Rel A ℓ₂} (isPreorder : IsPreorder _≈_ _≲_)whereopen IsPreorder isPreorder-------------------------------------------------------------------------- A datatype to hide the current relation typeinfix 4 _IsRelatedTo_data _IsRelatedTo_ (x y : A) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherenonstrict : (x≲y : x ≲ y) → x IsRelatedTo yequals : (x≈y : x ≈ y) → x IsRelatedTo ystart : _IsRelatedTo_ ⇒ _≲_start (equals x≈y) = reflexive x≈ystart (nonstrict x≲y) = x≲y≡-go : Trans _≡_ _IsRelatedTo_ _IsRelatedTo_≡-go x≡y (equals y≈z) = equals (case x≡y of λ where ≡.refl → y≈z)≡-go x≡y (nonstrict y≤z) = nonstrict (case x≡y of λ where ≡.refl → y≤z)≲-go : Trans _≲_ _IsRelatedTo_ _IsRelatedTo_≲-go x≲y (equals y≈z) = nonstrict (∼-respʳ-≈ y≈z x≲y)≲-go x≲y (nonstrict y≲z) = nonstrict (trans x≲y y≲z)≈-go : Trans _≈_ _IsRelatedTo_ _IsRelatedTo_≈-go x≈y (equals y≈z) = equals (Eq.trans x≈y y≈z)≈-go x≈y (nonstrict y≲z) = nonstrict (∼-respˡ-≈ (Eq.sym x≈y) y≲z)stop : Reflexive _IsRelatedTo_stop = equals Eq.refl-------------------------------------------------------------------------- A record that is used to ensure that the final relation proved by the-- chain of reasoning can be converted into the required relation.data IsEquality {x y} : x IsRelatedTo y → Set (a ⊔ ℓ₁ ⊔ ℓ₂) whereisEquality : ∀ x≈y → IsEquality (equals x≈y)IsEquality? : ∀ {x y} (x≲y : x IsRelatedTo y) → Dec (IsEquality x≲y)IsEquality? (nonstrict _) = no λ()IsEquality? (equals x≈y) = yes (isEquality x≈y)extractEquality : ∀ {x y} {x≲y : x IsRelatedTo y} → IsEquality x≲y → x ≈ yextractEquality (isEquality x≈y) = x≈yequalitySubRelation : SubRelation _IsRelatedTo_ _ _equalitySubRelation = record{ IsS = IsEquality; IsS? = IsEquality?; extract = extractEquality}-------------------------------------------------------------------------- Reasoning combinatorsopen begin-syntax _IsRelatedTo_ start publicopen begin-equality-syntax _IsRelatedTo_ equalitySubRelation publicopen ≡-syntax _IsRelatedTo_ ≡-go publicopen ≈-syntax _IsRelatedTo_ _IsRelatedTo_ ≈-go Eq.sym publicopen ≲-syntax _IsRelatedTo_ _IsRelatedTo_ ≲-go publicopen end-syntax _IsRelatedTo_ stop public-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0open ∼-syntax _IsRelatedTo_ _IsRelatedTo_ ≲-go public{-# WARNING_ON_USAGE step-∼"Warning: step-∼ and _∼⟨_⟩_ syntax was deprecated in v2.0.Please use step-≲ and _≲⟨_⟩_ instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- The basic code for equational reasoning with three relations:-- equality and apartness------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_)open import Function.Base using (case_of_)open import Relation.Nullary.Decidable using (Dec; yes; no)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Transitive; Symmetric; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Reasoning.Syntaxmodule Relation.Binary.Reasoning.Base.Apartness {a ℓ₁ ℓ₂} {A : Set a}{_≈_ : Rel A ℓ₁} {_#_ : Rel A ℓ₂}(≈-equiv : IsEquivalence _≈_)(#-trans : Transitive _#_) (#-sym : Symmetric _#_)(#-≈-trans : Trans _#_ _≈_ _#_) (≈-#-trans : Trans _≈_ _#_ _#_)wheremodule Eq = IsEquivalence ≈-equiv-------------------------------------------------------------------------- A datatype to hide the current relation typeinfix 4 _IsRelatedTo_data _IsRelatedTo_ (x y : A) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherenothing : x IsRelatedTo yapartness : (x#y : x # y) → x IsRelatedTo yequals : (x≈y : x ≈ y) → x IsRelatedTo y≡-go : Trans _≡_ _IsRelatedTo_ _IsRelatedTo_≡-go x≡y nothing = nothing≡-go x≡y (apartness y#z) = apartness (case x≡y of λ where ≡.refl → y#z)≡-go x≡y (equals y≈z) = equals (case x≡y of λ where ≡.refl → y≈z)≈-go : Trans _≈_ _IsRelatedTo_ _IsRelatedTo_≈-go x≈y nothing = nothing≈-go x≈y (apartness y#z) = apartness (≈-#-trans x≈y y#z)≈-go x≈y (equals y≈z) = equals (Eq.trans x≈y y≈z)#-go : Trans _#_ _IsRelatedTo_ _IsRelatedTo_#-go x#y nothing = nothing#-go x#y (apartness y#z) = nothing#-go x#y (equals y≈z) = apartness (#-≈-trans x#y y≈z)stop : Reflexive _IsRelatedTo_stop = equals Eq.refl-------------------------------------------------------------------------- Apartness subrelationdata IsApartness {x y} : x IsRelatedTo y → Set (a ⊔ ℓ₁ ⊔ ℓ₂) whereisApartness : ∀ x#y → IsApartness (apartness x#y)IsApartness? : ∀ {x y} (x#y : x IsRelatedTo y) → Dec (IsApartness x#y)IsApartness? nothing = no λ()IsApartness? (apartness x#y) = yes (isApartness x#y)IsApartness? (equals x≈y) = no (λ ())extractApartness : ∀ {x y} {x#y : x IsRelatedTo y} → IsApartness x#y → x # yextractApartness (isApartness x#y) = x#yapartnessRelation : SubRelation _IsRelatedTo_ _ _apartnessRelation = record{ IsS = IsApartness; IsS? = IsApartness?; extract = extractApartness}-------------------------------------------------------------------------- Equality subrelationdata IsEquality {x y} : x IsRelatedTo y → Set (a ⊔ ℓ₁ ⊔ ℓ₂) whereisEquality : ∀ x≈y → IsEquality (equals x≈y)IsEquality? : ∀ {x y} (x≲y : x IsRelatedTo y) → Dec (IsEquality x≲y)IsEquality? nothing = no λ()IsEquality? (apartness _) = no λ()IsEquality? (equals x≈y) = yes (isEquality x≈y)extractEquality : ∀ {x y} {x≲y : x IsRelatedTo y} → IsEquality x≲y → x ≈ yextractEquality (isEquality x≈y) = x≈yeqRelation : SubRelation _IsRelatedTo_ _ _eqRelation = record{ IsS = IsEquality; IsS? = IsEquality?; extract = extractEquality}-------------------------------------------------------------------------- Reasoning combinatorsopen begin-apartness-syntax _IsRelatedTo_ apartnessRelation publicopen begin-equality-syntax _IsRelatedTo_ eqRelation publicopen ≡-syntax _IsRelatedTo_ ≡-go publicopen #-syntax _IsRelatedTo_ _IsRelatedTo_ #-go #-sym publicopen ≈-syntax _IsRelatedTo_ _IsRelatedTo_ ≈-go Eq.sym publicopen end-syntax _IsRelatedTo_ stop public
-------------------------------------------------------------------------- The Agda standard library---- Propositional (intensional) equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.PropositionalEquality whereopen import Axiom.UniquenessOfIdentityProofsopen import Function.Base using (id; _∘_)import Function.Dependent.Bundles as Dependentopen import Function.Indexed.Relation.Binary.Equality using (≡-setoid)open import Level using (Level; _⊔_)open import Relation.Nullary using (Irrelevant)open import Relation.Nullary.Decidable using (yes; no; dec-yes-irr; dec-no)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.Indexed.Heterogeneoususing (IndexedSetoid)import Relation.Binary.Indexed.Heterogeneous.Construct.Trivialas Trivialprivatevariablea b c ℓ p : LevelA B C : Set a-------------------------------------------------------------------------- Re-export contents modules that make up the partsopen import Relation.Binary.PropositionalEquality.Core publicopen import Relation.Binary.PropositionalEquality.Properties publicopen import Relation.Binary.PropositionalEquality.Algebra public-------------------------------------------------------------------------- Pointwise equality_→-setoid_ : ∀ (A : Set a) (B : Set b) → Setoid _ _A →-setoid B = ≡-setoid A (Trivial.indexedSetoid (setoid B)):→-to-Π : ∀ {A : Set a} {B : IndexedSetoid A b ℓ} →((x : A) → IndexedSetoid.Carrier B x) →Dependent.Func (setoid A) B:→-to-Π {B = B} f = record{ to = f; cong = λ { refl → IndexedSetoid.refl B }}→-to-⟶ : ∀ {A : Set a} {B : Setoid b ℓ} →(A → Setoid.Carrier B) →Dependent.Func (setoid A) (Trivial.indexedSetoid B)→-to-⟶ = :→-to-Π-------------------------------------------------------------------------- More complex rearrangement lemmas-- A lemma that is very similar to Lemma 2.4.3 from the HoTT book.naturality : ∀ {x y} {x≡y : x ≡ y} {f g : A → B}(f≡g : ∀ x → f x ≡ g x) →trans (cong f x≡y) (f≡g y) ≡ trans (f≡g x) (cong g x≡y)naturality {x = x} {x≡y = refl} f≡g =f≡g x ≡⟨ sym (trans-reflʳ _) ⟩trans (f≡g x) refl ∎where open ≡-Reasoning-- A lemma that is very similar to Corollary 2.4.4 from the HoTT book.cong-≡id : ∀ {f : A → A} {x : A} (f≡id : ∀ x → f x ≡ x) →cong f (f≡id x) ≡ f≡id (f x)cong-≡id {f = f} {x} f≡id = begincong f fx≡x ≡⟨ sym (trans-reflʳ _) ⟩trans (cong f fx≡x) refl ≡⟨ cong (trans _) (sym (trans-symʳ fx≡x)) ⟩trans (cong f fx≡x) (trans fx≡x (sym fx≡x)) ≡⟨ sym (trans-assoc (cong f fx≡x)) ⟩trans (trans (cong f fx≡x) fx≡x) (sym fx≡x) ≡⟨ cong (λ p → trans p (sym _)) (naturality f≡id) ⟩trans (trans f²x≡x (cong id fx≡x)) (sym fx≡x) ≡⟨ cong (λ p → trans (trans f²x≡x p) (sym fx≡x)) (cong-id _) ⟩trans (trans f²x≡x fx≡x) (sym fx≡x) ≡⟨ trans-assoc f²x≡x ⟩trans f²x≡x (trans fx≡x (sym fx≡x)) ≡⟨ cong (trans _) (trans-symʳ fx≡x) ⟩trans f²x≡x refl ≡⟨ trans-reflʳ _ ⟩f≡id (f x) ∎where open ≡-Reasoning; fx≡x = f≡id x; f²x≡x = f≡id (f x)module _ (_≟_ : DecidableEquality A) {x y : A} where≡-≟-identity : (eq : x ≡ y) → x ≟ y ≡ yes eq≡-≟-identity eq = dec-yes-irr (x ≟ y) (Decidable⇒UIP.≡-irrelevant _≟_) eq≢-≟-identity : (x≢y : x ≢ y) → x ≟ y ≡ no x≢y≢-≟-identity = dec-no (x ≟ y)-------------------------------------------------------------------------- Inspect-- Inspect can be used when you want to pattern match on the result r-- of some expression e, and you also need to "remember" that r ≡ e.-- See README.Inspect for an explanation of how/why to use this.-- Normally (but not always) the new `with ... in` syntax described at-- https://agda.readthedocs.io/en/v2.6.4/language/with-abstraction.html#with-abstraction-equality-- can be used instead."record Reveal_·_is_ {A : Set a} {B : A → Set b}(f : (x : A) → B x) (x : A) (y : B x) :Set (a ⊔ b) whereconstructor [_]field eq : f x ≡ yinspect : ∀ {A : Set a} {B : A → Set b}(f : (x : A) → B x) (x : A) → Reveal f · x is f xinspect f x = [ refl ]-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0isPropositional : Set a → Set aisPropositional = Irrelevant{-# WARNING_ON_USAGE isPropositional"Warning: isPropositional was deprecated in v2.0.Please use Relation.Nullary.Irrelevant instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- Some code related to propositional equality that relies on the K-- rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Relation.Binary.PropositionalEquality.WithK whereopen import Axiom.UniquenessOfIdentityProofs.WithKopen import Relation.Binary.Definitions using (Irrelevant)open import Relation.Binary.PropositionalEquality.Core-------------------------------------------------------------------------- Re-exporting safe erasure function-- ≡-erase ignores its `x ≡ y` argument and reduces to refl whenever-- x and y are judgmentally equal. This is useful when the computation-- producing the proof `x ≡ y` is expensive.open import Agda.Builtin.Equality.Eraseusing ()renaming ( primEraseEquality to ≡-erase )public-------------------------------------------------------------------------- Proof irrelevance≡-irrelevant : ∀ {a} {A : Set a} → Irrelevant {A = A} _≡_≡-irrelevant = uip
-------------------------------------------------------------------------- The Agda standard library---- An equality postulate which evaluates------------------------------------------------------------------------{-# OPTIONS --with-K #-}module Relation.Binary.PropositionalEquality.TrustMe whereopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Agda.Builtin.TrustMe-- trustMe {x = x} {y = y} evaluates to refl if x and y are-- definitionally equal.trustMe : ∀ {a} {A : Set a} {x y : A} → x ≡ ytrustMe = primTrustMe-- "Erases" a proof. The original proof is not inspected. The-- resulting proof reduces to refl if the two sides are definitionally-- equal. Note that checking for definitional equality can be slow.erase : ∀ {a} {A : Set a} {x y : A} → x ≡ y → x ≡ yerase _ = trustMe-- A "postulate with a reduction": postulate[ a ↦ b ] a evaluates to b,-- while postulate[ a ↦ b ] a′ gets stuck if a′ is not definitionally-- equal to a. This can be used to define a postulate of type (x : A) → B x-- by only specifying the behaviour at B t for some t : A. Introduced in---- Alan Jeffrey, Univalence via Agda's primTrustMe again-- 23 January 2015-- https://lists.chalmers.se/pipermail/agda/2015/007418.htmlpostulate[_↦_] : ∀ {a b} {A : Set a}{B : A → Set b} →(t : A) → B t → (x : A) → B xpostulate[ a ↦ b ] a′ with trustMe {x = a} {a′}postulate[ a ↦ b ] .a | refl = b
-------------------------------------------------------------------------- The Agda standard library---- Propositional equality---- This file contains some core properies of propositional equality-- which are re-exported by Relation.Binary.PropositionalEquality. They-- are ``equality rearrangement'' lemmas.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.PropositionalEquality.Properties whereopen import Function.Base using (id; _∘_)open import Level using (Level)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; Poset)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder; IsPartialOrder)open import Relation.Binary.Definitionsusing (DecidableEquality)import Relation.Binary.Properties.Setoid as Setoidopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Unary using (Pred)open import Relation.Binary.Reasoning.Syntaxprivatevariablea b c p : LevelA B C : Set a-------------------------------------------------------------------------- Standard eliminator for the propositional equality typeJ : {A : Set a} {x : A} (B : (y : A) → x ≡ y → Set b){y : A} (p : x ≡ y) → B x refl → B y pJ B refl b = b-------------------------------------------------------------------------- Binary and/or dependent versions of standard operations on equalitydcong : ∀ {A : Set a} {B : A → Set b} (f : (x : A) → B x) {x y}→ (p : x ≡ y) → subst B p (f x) ≡ f ydcong f refl = refldcong₂ : ∀ {A : Set a} {B : A → Set b} {C : Set c}(f : (x : A) → B x → C) {x₁ x₂ y₁ y₂}→ (p : x₁ ≡ x₂) → subst B p y₁ ≡ y₂→ f x₁ y₁ ≡ f x₂ y₂dcong₂ f refl refl = refldsubst₂ : ∀ {A : Set a} {B : A → Set b} (C : (x : A) → B x → Set c){x₁ x₂ y₁ y₂} (p : x₁ ≡ x₂) → subst B p y₁ ≡ y₂→ C x₁ y₁ → C x₂ y₂dsubst₂ C refl refl c = cddcong₂ : ∀ {A : Set a} {B : A → Set b} {C : (x : A) → B x → Set c}(f : (x : A) (y : B x) → C x y) {x₁ x₂ y₁ y₂}(p : x₁ ≡ x₂) (q : subst B p y₁ ≡ y₂)→ dsubst₂ C p q (f x₁ y₁) ≡ f x₂ y₂ddcong₂ f refl refl = refl-------------------------------------------------------------------------- Various equality rearrangement lemmastrans-reflʳ : ∀ {x y : A} (p : x ≡ y) → trans p refl ≡ ptrans-reflʳ refl = refltrans-assoc : ∀ {x y z u : A} (p : x ≡ y) {q : y ≡ z} {r : z ≡ u} →trans (trans p q) r ≡ trans p (trans q r)trans-assoc refl = refltrans-symˡ : ∀ {x y : A} (p : x ≡ y) → trans (sym p) p ≡ refltrans-symˡ refl = refltrans-symʳ : ∀ {x y : A} (p : x ≡ y) → trans p (sym p) ≡ refltrans-symʳ refl = refltrans-injectiveˡ : ∀ {x y z : A} {p₁ p₂ : x ≡ y} (q : y ≡ z) →trans p₁ q ≡ trans p₂ q → p₁ ≡ p₂trans-injectiveˡ refl = subst₂ _≡_ (trans-reflʳ _) (trans-reflʳ _)trans-injectiveʳ : ∀ {x y z : A} (p : x ≡ y) {q₁ q₂ : y ≡ z} →trans p q₁ ≡ trans p q₂ → q₁ ≡ q₂trans-injectiveʳ refl eq = eqcong-id : ∀ {x y : A} (p : x ≡ y) → cong id p ≡ pcong-id refl = reflcong-∘ : ∀ {x y : A} {f : B → C} {g : A → B} (p : x ≡ y) →cong (f ∘ g) p ≡ cong f (cong g p)cong-∘ refl = reflsym-cong : ∀ {x y : A} {f : A → B} (p : x ≡ y) → sym (cong f p) ≡ cong f (sym p)sym-cong refl = refltrans-cong : ∀ {x y z : A} {f : A → B} (p : x ≡ y) {q : y ≡ z} →trans (cong f p) (cong f q) ≡ cong f (trans p q)trans-cong refl = reflcong₂-reflˡ : ∀ {_∙_ : A → B → C} {x u v} → (p : u ≡ v) →cong₂ _∙_ refl p ≡ cong (x ∙_) pcong₂-reflˡ refl = reflcong₂-reflʳ : ∀ {_∙_ : A → B → C} {x y u} → (p : x ≡ y) →cong₂ _∙_ p refl ≡ cong (_∙ u) pcong₂-reflʳ refl = reflmodule _ {P : Pred A p} {x y : A} wheresubst-injective : ∀ (x≡y : x ≡ y) {p q : P x} →subst P x≡y p ≡ subst P x≡y q → p ≡ qsubst-injective refl p≡q = p≡qsubst-subst : ∀ {z} (x≡y : x ≡ y) {y≡z : y ≡ z} {p : P x} →subst P y≡z (subst P x≡y p) ≡ subst P (trans x≡y y≡z) psubst-subst refl = reflsubst-subst-sym : (x≡y : x ≡ y) {p : P y} →subst P x≡y (subst P (sym x≡y) p) ≡ psubst-subst-sym refl = reflsubst-sym-subst : (x≡y : x ≡ y) {p : P x} →subst P (sym x≡y) (subst P x≡y p) ≡ psubst-sym-subst refl = reflsubst-∘ : ∀ {x y : A} {P : Pred B p} {f : A → B}(x≡y : x ≡ y) {p : P (f x)} →subst (P ∘ f) x≡y p ≡ subst P (cong f x≡y) psubst-∘ refl = refl-- Lemma 2.3.11 in the HoTT book, and `transport_map` in the UniMath-- librarysubst-application′ : ∀ {a b₁ b₂} {A : Set a}(B₁ : A → Set b₁) {B₂ : A → Set b₂}{x₁ x₂ : A} {y : B₁ x₁}(g : ∀ x → B₁ x → B₂ x) (eq : x₁ ≡ x₂) →subst B₂ eq (g x₁ y) ≡ g x₂ (subst B₁ eq y)subst-application′ _ _ refl = reflsubst-application : ∀ {a₁ a₂ b₁ b₂} {A₁ : Set a₁} {A₂ : Set a₂}(B₁ : A₁ → Set b₁) {B₂ : A₂ → Set b₂}{f : A₂ → A₁} {x₁ x₂ : A₂} {y : B₁ (f x₁)}(g : ∀ x → B₁ (f x) → B₂ x) (eq : x₁ ≡ x₂) →subst B₂ eq (g x₁ y) ≡ g x₂ (subst B₁ (cong f eq) y)subst-application _ _ refl = refl-------------------------------------------------------------------------- Structure of equality as a binary relationisEquivalence : IsEquivalence {A = A} _≡_isEquivalence = record{ refl = refl; sym = sym; trans = trans}isDecEquivalence : DecidableEquality A → IsDecEquivalence _≡_isDecEquivalence _≟_ = record{ isEquivalence = isEquivalence; _≟_ = _≟_}setoid : Set a → Setoid _ _setoid A = record{ Carrier = A; _≈_ = _≡_; isEquivalence = isEquivalence}decSetoid : DecidableEquality A → DecSetoid _ _decSetoid _≟_ = record{ _≈_ = _≡_; isDecEquivalence = isDecEquivalence _≟_}-------------------------------------------------------------------------- Bundles for equality as a binary relationisPreorder : IsPreorder {A = A} _≡_ _≡_isPreorder = Setoid.≈-isPreorder (setoid _)isPartialOrder : IsPartialOrder {A = A} _≡_ _≡_isPartialOrder = Setoid.≈-isPartialOrder (setoid _)preorder : Set a → Preorder _ _ _preorder A = Setoid.≈-preorder (setoid A)poset : Set a → Poset _ _ _poset A = Setoid.≈-poset (setoid A)-------------------------------------------------------------------------- Reasoning-- This is a special instance of `Relation.Binary.Reasoning.Setoid`.-- Rather than instantiating the latter with (setoid A), we reimplement-- equation chains from scratch since then goals are printed much more-- readably.module ≡-Reasoning {a} {A : Set a} whereopen begin-syntax {A = A} _≡_ id publicopen ≡-syntax {A = A} _≡_ trans publicopen end-syntax {A = A} _≡_ refl public
-------------------------------------------------------------------------- The Agda standard library---- Propositional equality---- This file contains some core definitions which are re-exported by-- Relation.Binary.PropositionalEquality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.PropositionalEquality.Core whereopen import Data.Product.Base using (_,_)open import Function.Base using (_∘_)open import Levelopen import Relation.Binary.Coreopen import Relation.Binary.Definitionsopen import Relation.Nullary.Negation.Core using (¬_)privatevariablea b ℓ : LevelA B C : Set a-------------------------------------------------------------------------- Propositional equalityopen import Agda.Builtin.Equality publicinfix 4 _≢__≢_ : {A : Set a} → Rel A ax ≢ y = ¬ x ≡ y-------------------------------------------------------------------------- Pointwise equalityinfix 4 _≗__≗_ : (f g : A → B) → Set __≗_ {A = A} {B = B} f g = ∀ x → f x ≡ g x-------------------------------------------------------------------------- A variant of `refl` where the argument is explicitpattern erefl x = refl {x = x}-------------------------------------------------------------------------- Congruence lemmascong : ∀ (f : A → B) {x y} → x ≡ y → f x ≡ f ycong f refl = reflcong′ : ∀ {f : A → B} x → f x ≡ f xcong′ _ = reflicong : ∀ {f : A → B} {x y} → x ≡ y → f x ≡ f yicong = cong _icong′ : ∀ {f : A → B} x → f x ≡ f xicong′ _ = reflcong₂ : ∀ (f : A → B → C) {x y u v} → x ≡ y → u ≡ v → f x u ≡ f y vcong₂ f refl refl = reflcong-app : ∀ {A : Set a} {B : A → Set b} {f g : (x : A) → B x} →f ≡ g → (x : A) → f x ≡ g xcong-app refl x = refl-------------------------------------------------------------------------- Properties of _≡_sym : Symmetric {A = A} _≡_sym refl = refltrans : Transitive {A = A} _≡_trans refl eq = eqsubst : Substitutive {A = A} _≡_ ℓsubst P refl p = psubst₂ : ∀ (_∼_ : REL A B ℓ) {x y u v} → x ≡ y → u ≡ v → x ∼ u → y ∼ vsubst₂ _ refl refl p = presp : ∀ (P : A → Set ℓ) → P Respects _≡_resp P refl p = prespˡ : ∀ (∼ : Rel A ℓ) → ∼ Respectsˡ _≡_respˡ _∼_ refl x∼y = x∼yrespʳ : ∀ (∼ : Rel A ℓ) → ∼ Respectsʳ _≡_respʳ _∼_ refl x∼y = x∼yresp₂ : ∀ (∼ : Rel A ℓ) → ∼ Respects₂ _≡_resp₂ _∼_ = respʳ _∼_ , respˡ _∼_-------------------------------------------------------------------------- Properties of _≢_≢-sym : Symmetric {A = A} _≢_≢-sym x≢y = x≢y ∘ sym
-------------------------------------------------------------------------- The Agda standard library---- Propositional (intensional) equality - Algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.PropositionalEquality.Algebra whereopen import Algebra.Bundles using (Magma)open import Algebra.Core using (Op₂)open import Algebra.Structures using (IsMagma)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong₂)open import Relation.Binary.PropositionalEquality.Properties using (isEquivalence)privatevariablea : LevelA : Set a-------------------------------------------------------------------------- Any operation forms a magma over _≡_isMagma : (_∙_ : Op₂ A) → IsMagma _≡_ _∙_isMagma _∙_ = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _∙_}magma : (_∙_ : Op₂ A) → Magma _ _magma _∙_ = record{ isMagma = isMagma _∙_}
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by total orders------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (TotalOrder; DecTotalOrder)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.Structures using (IsTotalOrder)module Relation.Binary.Properties.TotalOrder{t₁ t₂ t₃} (T : TotalOrder t₁ t₂ t₃) whereopen TotalOrder Topen import Data.Product.Base using (proj₁)open import Data.Sum.Base using (inj₁; inj₂)import Relation.Binary.Construct.Flip.EqAndOrd as EqAndOrdimport Relation.Binary.Construct.NonStrictToStrict _≈_ _≤_ as ToStrictimport Relation.Binary.Properties.Poset poset as PosetPropertiesopen import Relation.Binary.Consequences-------------------------------------------------------------------------- Total orders are almost decidable total ordersdecTotalOrder : Decidable _≈_ → DecTotalOrder _ _ _decTotalOrder ≟ = record{ isDecTotalOrder = record{ isTotalOrder = isTotalOrder; _≟_ = ≟; _≤?_ = total∧dec⇒dec reflexive antisym total ≟}}-------------------------------------------------------------------------- _≥_ - the flipped relation is also a total orderopen PosetProperties publicusing( ≥-refl; ≥-reflexive; ≥-trans; ≥-antisym; ≥-isPreorder; ≥-isPartialOrder; ≥-preorder; ≥-poset)≥-isTotalOrder : IsTotalOrder _≈_ _≥_≥-isTotalOrder = EqAndOrd.isTotalOrder isTotalOrder≥-totalOrder : TotalOrder _ _ _≥-totalOrder = record{ isTotalOrder = ≥-isTotalOrder}open TotalOrder ≥-totalOrder publicusing () renaming (total to ≥-total)-------------------------------------------------------------------------- _<_ - the strict version is a strict partial order-- Note that total orders can NOT be turned into strict total orders as-- in order to distinguish between the _≤_ and _<_ cases we must have-- decidable equality _≈_.open PosetProperties publicusing( _<_; <-resp-≈; <-respʳ-≈; <-respˡ-≈; <-irrefl; <-asym; <-trans; <-isStrictPartialOrder; <-strictPartialOrder; <⇒≉; ≤∧≉⇒<; <⇒≱; ≤⇒≯)-------------------------------------------------------------------------- _≰_ - the negated orderopen PosetProperties publicusing( ≰-respʳ-≈; ≰-respˡ-≈)≰⇒> : ∀ {x y} → x ≰ y → y < x≰⇒> = ToStrict.≰⇒> Eq.sym reflexive total≰⇒≥ : ∀ {x y} → x ≰ y → y ≤ x≰⇒≥ x≰y = proj₁ (≰⇒> x≰y)
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by strict partial orders------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder; DecTotalOrder)module Relation.Binary.Properties.StrictTotalOrder{s₁ s₂ s₃} (STO : StrictTotalOrder s₁ s₂ s₃)whereopen StrictTotalOrder STOopen import Relation.Binary.Construct.StrictToNonStrict _≈_ _<_import Relation.Binary.Properties.StrictPartialOrder as SPOopen import Relation.Binary.Consequences-------------------------------------------------------------------------- _<_ - the strict version is a decidable total orderdecTotalOrder : DecTotalOrder _ _ _decTotalOrder = record{ isDecTotalOrder = isDecTotalOrder isStrictTotalOrder}open DecTotalOrder decTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by strict partial orders------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictPartialOrder; Poset)module Relation.Binary.Properties.StrictPartialOrder{s₁ s₂ s₃} (SPO : StrictPartialOrder s₁ s₂ s₃) whereimport Relation.Binary.Construct.Flip.EqAndOrd as EqAndOrdimport Relation.Binary.Construct.StrictToNonStrictopen StrictPartialOrder SPO-------------------------------------------------------------------------- The converse relation is also a strict partial order.>-strictPartialOrder : StrictPartialOrder s₁ s₂ s₃>-strictPartialOrder = EqAndOrd.strictPartialOrder SPOopen StrictPartialOrder >-strictPartialOrder publicusing ()renaming( _<_ to _>_; irrefl to >-irrefl; trans to >-trans; <-resp-≈ to >-resp-≈; isStrictPartialOrder to >-isStrictPartialOrder)-------------------------------------------------------------------------- Strict partial orders can be converted to posetsopen Relation.Binary.Construct.StrictToNonStrict _≈_ _<_poset : Poset _ _ _poset = record{ isPartialOrder = isPartialOrder isStrictPartialOrder}open Poset poset public
-------------------------------------------------------------------------- The Agda standard library---- Additional properties for setoids------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (_,_)open import Function.Base using (_∘_; id; _$_; flip)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Bundles using (Setoid; Preorder; Poset)open import Relation.Binary.Definitionsusing (Symmetric; _Respectsˡ_; _Respectsʳ_; _Respects₂_; Irreflexive)open import Relation.Binary.Structures using (IsPreorder; IsPartialOrder)open import Relation.Binary.Construct.Compositionusing (_;_; impliesˡ; transitive⇒≈;≈⊆≈)module Relation.Binary.Properties.Setoid {a ℓ} (S : Setoid a ℓ) whereopen Setoid S-------------------------------------------------------------------------- Every setoid is a preorder and partial order with respect to-- propositional equalityisPreorder : IsPreorder _≡_ _≈_isPreorder = record{ isEquivalence = record{ refl = ≡.refl; sym = ≡.sym; trans = ≡.trans}; reflexive = reflexive; trans = trans}≈-isPreorder : IsPreorder _≈_ _≈_≈-isPreorder = record{ isEquivalence = isEquivalence; reflexive = id; trans = trans}≈-isPartialOrder : IsPartialOrder _≈_ _≈_≈-isPartialOrder = record{ isPreorder = ≈-isPreorder; antisym = λ i≈j _ → i≈j}preorder : Preorder a a ℓpreorder = record{ isPreorder = isPreorder}≈-preorder : Preorder a ℓ ℓ≈-preorder = record{ isPreorder = ≈-isPreorder}≈-poset : Poset a ℓ ℓ≈-poset = record{ isPartialOrder = ≈-isPartialOrder}-------------------------------------------------------------------------- Properties of _≉_≉-sym : Symmetric _≉_≉-sym x≉y = x≉y ∘ sym≉-respˡ : _≉_ Respectsˡ _≈_≉-respˡ x≈x′ x≉y = x≉y ∘ trans x≈x′≉-respʳ : _≉_ Respectsʳ _≈_≉-respʳ y≈y′ x≉y x≈y′ = x≉y $ trans x≈y′ (sym y≈y′)≉-resp₂ : _≉_ Respects₂ _≈_≉-resp₂ = ≉-respʳ , ≉-respˡ≉-irrefl : Irreflexive _≈_ _≉_≉-irrefl x≈y x≉y = contradiction x≈y x≉y-------------------------------------------------------------------------- Equality is closed under composition≈;≈⇒≈ : _≈_ ; _≈_ ⇒ _≈_≈;≈⇒≈ = transitive⇒≈;≈⊆≈ _ trans≈⇒≈;≈ : _≈_ ⇒ _≈_ ; _≈_≈⇒≈;≈ = impliesˡ _≈_ _≈_ refl id-------------------------------------------------------------------------- Other propertiesrespʳ-flip : _≈_ Respectsʳ (flip _≈_)respʳ-flip y≈z x≈z = trans x≈z (sym y≈z)respˡ-flip : _≈_ Respectsˡ (flip _≈_)respˡ-flip = trans
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by preorders------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Preorder; Setoid)open import Relation.Binary.Structures using (IsPreorder)module Relation.Binary.Properties.Preorder{p₁ p₂ p₃} (P : Preorder p₁ p₂ p₃) whereopen import Function.Base using (flip)open import Data.Product.Base as Product using (_×_; _,_; swap)import Relation.Binary.Construct.Flip.EqAndOrd as EqAndOrdopen Preorder P-------------------------------------------------------------------------- The converse relation is also a preorder.converse-isPreorder : IsPreorder _≈_ _≳_converse-isPreorder = EqAndOrd.isPreorder isPreorderconverse-preorder : Preorder p₁ p₂ p₃converse-preorder = EqAndOrd.preorder P-------------------------------------------------------------------------- For every preorder there is an induced equivalenceInducedEquivalence : Setoid _ _InducedEquivalence = record{ _≈_ = λ x y → x ≲ y × x ≳ y; isEquivalence = record{ refl = (refl , refl); sym = swap; trans = Product.zip trans (flip trans)}}-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0invIsPreorder = converse-isPreorder{-# WARNING_ON_USAGE invIsPreorder"Warning: invIsPreorder was deprecated in v2.0.Please use converse-isPreorder instead."#-}invPreorder = converse-preorder{-# WARNING_ON_USAGE invPreorder"Warning: invPreorder was deprecated in v2.0.Please use converse-preorder instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by posets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (_,_)open import Function.Base using (flip; _∘_)open import Relation.Binary.Core using (Rel; _Preserves_⟶_)open import Relation.Binary.Bundles using (Poset; StrictPartialOrder)open import Relation.Binary.Structuresusing (IsPartialOrder; IsStrictPartialOrder; IsDecPartialOrder)open import Relation.Binary.Definitionsusing (_Respectsˡ_; _Respectsʳ_; Decidable)import Relation.Binary.Consequences as Consequencesopen import Relation.Nullary using (¬_; yes; no)open import Relation.Nullary.Negation using (contradiction)module Relation.Binary.Properties.Poset{p₁ p₂ p₃} (P : Poset p₁ p₂ p₃) whereopen Poset P renaming (Carrier to A)import Relation.Binary.Construct.NonStrictToStrict _≈_ _≤_ as ToStrictimport Relation.Binary.Properties.Preorder preorder as PreorderPropertiesopen Eq using (_≉_)-------------------------------------------------------------------------- The _≥_ relation is also a poset.open PreorderProperties publicusing () renaming( converse-isPreorder to ≥-isPreorder; converse-preorder to ≥-preorder)≥-isPartialOrder : IsPartialOrder _≈_ _≥_≥-isPartialOrder = record{ isPreorder = ≥-isPreorder; antisym = flip antisym}≥-poset : Poset p₁ p₂ p₃≥-poset = record{ isPartialOrder = ≥-isPartialOrder}open Poset ≥-poset publicusing () renaming( refl to ≥-refl; reflexive to ≥-reflexive; trans to ≥-trans; antisym to ≥-antisym)-------------------------------------------------------------------------- Negated order≰-respˡ-≈ : _≰_ Respectsˡ _≈_≰-respˡ-≈ x≈y = _∘ ≤-respˡ-≈ (Eq.sym x≈y)≰-respʳ-≈ : _≰_ Respectsʳ _≈_≰-respʳ-≈ x≈y = _∘ ≤-respʳ-≈ (Eq.sym x≈y)-------------------------------------------------------------------------- Partial orders can be turned into strict partial ordersinfix 4 _<__<_ : Rel A __<_ = ToStrict._<_<-isStrictPartialOrder : IsStrictPartialOrder _≈_ _<_<-isStrictPartialOrder = ToStrict.<-isStrictPartialOrder isPartialOrder<-strictPartialOrder : StrictPartialOrder _ _ _<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}open StrictPartialOrder <-strictPartialOrder publicusing (_≮_; <-resp-≈; <-respʳ-≈; <-respˡ-≈)renaming( irrefl to <-irrefl; asym to <-asym; trans to <-trans)<⇒≉ : ∀ {x y} → x < y → x ≉ y<⇒≉ = ToStrict.<⇒≉≤∧≉⇒< : ∀ {x y} → x ≤ y → x ≉ y → x < y≤∧≉⇒< = ToStrict.≤∧≉⇒<<⇒≱ : ∀ {x y} → x < y → y ≰ x<⇒≱ = ToStrict.<⇒≱ antisym≤⇒≯ : ∀ {x y} → x ≤ y → y ≮ x≤⇒≯ = ToStrict.≤⇒≯ antisym-------------------------------------------------------------------------- If ≤ is decidable then so is ≈≤-dec⇒≈-dec : Decidable _≤_ → Decidable _≈_≤-dec⇒≈-dec _≤?_ x y with x ≤? y | y ≤? x... | yes x≤y | yes y≤x = yes (antisym x≤y y≤x)... | yes x≤y | no y≰x = no λ x≈y → contradiction (reflexive (Eq.sym x≈y)) y≰x... | no x≰y | _ = no λ x≈y → contradiction (reflexive x≈y) x≰y≤-dec⇒isDecPartialOrder : Decidable _≤_ → IsDecPartialOrder _≈_ _≤_≤-dec⇒isDecPartialOrder _≤?_ = record{ isPartialOrder = isPartialOrder; _≟_ = ≤-dec⇒≈-dec _≤?_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Other propertiesmono⇒cong : ∀ {f} → f Preserves _≤_ ⟶ _≤_ → f Preserves _≈_ ⟶ _≈_mono⇒cong = Consequences.mono⇒cong _≈_ _≈_ Eq.sym reflexive antisymantimono⇒cong : ∀ {f} → f Preserves _≤_ ⟶ _≥_ → f Preserves _≈_ ⟶ _≈_antimono⇒cong = Consequences.antimono⇒cong _≈_ _≈_ Eq.sym reflexive antisym
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.MeetSemilattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.MeetSemilattice{c ℓ₁ ℓ₂} (M : MeetSemilattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.MeetSemilattice M public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.MeetSemilattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.MeetSemilattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.Lattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.Lattice{c ℓ₁ ℓ₂} (L : Lattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.Lattice L public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.Lattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.Lattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.JoinSemilattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.JoinSemilattice{c ℓ₁ ℓ₂} (J : JoinSemilattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.JoinSemilattice J public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.JoinSemilattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.JoinSemilattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.HeytingAlgebra` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Lattice using (HeytingAlgebra)module Relation.Binary.Properties.HeytingAlgebra{c ℓ₁ ℓ₂} (L : HeytingAlgebra c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.HeytingAlgebra L public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.HeytingAlgebra was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.HeytingAlgebra instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.DistributiveLattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.DistributiveLattice{c ℓ₁ ℓ₂} (L : DistributiveLattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.DistributiveLattice L public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.DistributiveLattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.DistributiveLattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by decidable total orders------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Structuresusing (IsDecTotalOrder; IsStrictTotalOrder)open import Relation.Binary.Bundlesusing (DecTotalOrder; StrictTotalOrder)module Relation.Binary.Properties.DecTotalOrder{d₁ d₂ d₃} (DTO : DecTotalOrder d₁ d₂ d₃) whereopen DecTotalOrder DTO hiding (trans)import Relation.Binary.Construct.Flip.EqAndOrd as EqAndOrdimport Relation.Binary.Construct.NonStrictToStrict _≈_ _≤_ as ToStrictimport Relation.Binary.Properties.TotalOrder totalOrder as TotalOrderPropertiesopen import Relation.Nullary.Negation using (¬_)-------------------------------------------------------------------------- _≥_ - the flipped relation is also a total orderopen TotalOrderProperties publicusing( ≥-refl; ≥-reflexive; ≥-trans; ≥-antisym; ≥-total; ≥-isPreorder; ≥-isPartialOrder; ≥-isTotalOrder; ≥-preorder; ≥-poset; ≥-totalOrder)≥-isDecTotalOrder : IsDecTotalOrder _≈_ _≥_≥-isDecTotalOrder = EqAndOrd.isDecTotalOrder isDecTotalOrder≥-decTotalOrder : DecTotalOrder _ _ _≥-decTotalOrder = record{ isDecTotalOrder = ≥-isDecTotalOrder}open DecTotalOrder ≥-decTotalOrder publicusing () renaming (_≤?_ to _≥?_)-------------------------------------------------------------------------- _<_ - the strict version is a strict total orderopen TotalOrderProperties publicusing( _<_; <-resp-≈; <-respʳ-≈; <-respˡ-≈; <-irrefl; <-asym; <-trans; <-isStrictPartialOrder; <-strictPartialOrder; <⇒≉; ≤∧≉⇒<; <⇒≱; ≤⇒≯)<-isStrictTotalOrder : IsStrictTotalOrder _≈_ _<_<-isStrictTotalOrder = ToStrict.<-isStrictTotalOrder₂ isDecTotalOrder<-strictTotalOrder : StrictTotalOrder _ _ _<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}open StrictTotalOrder <-strictTotalOrder publicusing (_≮_) renaming (compare to <-compare)-------------------------------------------------------------------------- _≰_ - the negated orderopen TotalOrderProperties publicusing( ≰-respʳ-≈; ≰-respˡ-≈; ≰⇒>; ≰⇒≥)≮⇒≥ : ∀ {x y} → x ≮ y → y ≤ x≮⇒≥ = ToStrict.≮⇒≥ Eq.sym _≟_ reflexive total
-------------------------------------------------------------------------- The Agda standard library---- Every decidable setoid induces tight apartness relation.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid; ApartnessRelation)module Relation.Binary.Properties.DecSetoid {c ℓ} (S : DecSetoid c ℓ) whereopen import Data.Product using (_,_)open import Data.Sum using (inj₁; inj₂)open import Relation.Binary.Definitionsusing (Cotransitive; Tight)import Relation.Binary.Properties.Setoid as SetoidPropertiesopen import Relation.Binary.Structuresusing (IsApartnessRelation; IsDecEquivalence)open import Relation.Nullary.Decidable.Coreusing (yes; no; decidable-stable)open DecSetoid S using (_≈_; _≉_; _≟_; setoid; trans)open SetoidProperties setoid≉-cotrans : Cotransitive _≉_≉-cotrans {x} {y} x≉y z with x ≟ z | z ≟ y... | _ | no z≉y = inj₂ z≉y... | no x≉z | _ = inj₁ x≉z... | yes x≈z | yes z≈y = inj₁ λ _ → x≉y (trans x≈z z≈y)≉-isApartnessRelation : IsApartnessRelation _≈_ _≉_≉-isApartnessRelation = record{ irrefl = ≉-irrefl; sym = ≉-sym; cotrans = ≉-cotrans}≉-apartnessRelation : ApartnessRelation c ℓ ℓ≉-apartnessRelation = record { isApartnessRelation = ≉-isApartnessRelation }≉-tight : Tight _≈_ _≉_≉-tight x y = decidable-stable (x ≟ y) , ≉-irrefl
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.BoundedMeetSemilattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.BoundedMeetSemilattice{c ℓ₁ ℓ₂} (M : BoundedMeetSemilattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.BoundedMeetSemilattice M public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.BoundedMeetSemilattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.BoundedMeetSemilattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.BoundedLattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.BoundedLattice{c ℓ₁ ℓ₂} (L : BoundedLattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.BoundedLattice L public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.BoundedLattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.BoundedLattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Lattice.Properties.BoundedJoinSemilattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Properties.BoundedJoinSemilattice{c ℓ₁ ℓ₂} (J : BoundedJoinSemilattice c ℓ₁ ℓ₂) whereopen import Relation.Binary.Lattice.Properties.BoundedJoinSemilattice J public{-# WARNING_ON_IMPORT"Relation.Binary.Properties.BoundedJoinSemilattice was deprecated in v2.0.Use Relation.Binary.Lattice.Properties.BoundedJoinSemilattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Apartness properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)module Relation.Binary.Properties.ApartnessRelation{a ℓ₁ ℓ₂} {A : Set a}{_≈_ : Rel A ℓ₁}{_#_ : Rel A ℓ₂}whereopen import Function.Base using (_∘₂_)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.Consequences using (sym⇒¬-sym; cotrans⇒¬-trans)open import Relation.Binary.Structures using (IsEquivalence; IsApartnessRelation)open import Relation.Nullary.Negation using (¬_)¬#-isEquivalence : Reflexive _≈_ → IsApartnessRelation _≈_ _#_ →IsEquivalence (¬_ ∘₂ _#_)¬#-isEquivalence re apart = record{ refl = irrefl re; sym = λ {a} {b} → sym⇒¬-sym sym {a} {b}; trans = cotrans⇒¬-trans cotrans} where open IsApartnessRelation apart
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use `Relation.Binary.Morphism`-- instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.OrderMorphism where{-# WARNING_ON_IMPORT"Relation.Binary.OrderMorphism was deprecated in v1.5.Use Relation.Binary.Reasoning.Morphism instead."#-}open import Relation.Binary.Core using (_=[_]⇒_)open import Relation.Binary.Bundles using (Poset; DecTotalOrder)open Posetimport Function.Base as Fopen import Levelrecord _⇒-Poset_ {p₁ p₂ p₃ p₄ p₅ p₆}(P₁ : Poset p₁ p₂ p₃)(P₂ : Poset p₄ p₅ p₆) : Set (p₁ ⊔ p₃ ⊔ p₄ ⊔ p₆) wherefieldfun : Carrier P₁ → Carrier P₂monotone : _≤_ P₁ =[ fun ]⇒ _≤_ P₂_⇒-DTO_ : ∀ {p₁ p₂ p₃ p₄ p₅ p₆} →DecTotalOrder p₁ p₂ p₃ →DecTotalOrder p₄ p₅ p₆ → Set _DTO₁ ⇒-DTO DTO₂ = poset DTO₁ ⇒-Poset poset DTO₂where open DecTotalOrderopen _⇒-Poset_id : ∀ {p₁ p₂ p₃} {P : Poset p₁ p₂ p₃} → P ⇒-Poset Pid = record{ fun = F.id; monotone = F.id}_∘_ : ∀ {p₁ p₂ p₃ p₄ p₅ p₆ p₇ p₈ p₉}{P₁ : Poset p₁ p₂ p₃}{P₂ : Poset p₄ p₅ p₆}{P₃ : Poset p₇ p₈ p₉} →P₂ ⇒-Poset P₃ → P₁ ⇒-Poset P₂ → P₁ ⇒-Poset P₃f ∘ g = record{ fun = F._∘_ (fun f) (fun g); monotone = F._∘_ (monotone f) (monotone g)}const : ∀ {p₁ p₂ p₃ p₄ p₅ p₆}{P₁ : Poset p₁ p₂ p₃}{P₂ : Poset p₄ p₅ p₆} →Carrier P₂ → P₁ ⇒-Poset P₂const {P₂ = P₂} x = record{ fun = F.const x; monotone = F.const (refl P₂)}{-# WARNING_ON_USAGE _⇒-Poset_"Warning: _⇒-Poset_ was deprecated in v1.5.Please use `IsOrderHomomorphism` from `Relation.Binary.Morphism.Structures` instead."#-}{-# WARNING_ON_USAGE _⇒-DTO_"Warning: _⇒-DTO_ was deprecated in v1.5.Please use `IsOrderHomomorphism` from `Relation.Binary.Morphism.Structures` instead."#-}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v1.5.Please use `issOrderHomomorphism` from `Relation.Binary.Morphism.Construct.Constant` instead."#-}{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v1.5.Please use `isOrderHomomorphism` from `Relation.Binary.Morphism.Construct.Composition` instead."#-}{-# WARNING_ON_USAGE const"Warning: const was deprecated in v1.5.Please use `isOrderHomomorphism` from `Relation.Binary.Morphism.Construct.Constant` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Order morphisms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Relation.Binary.Morphism where-------------------------------------------------------------------------- Re-export contents of morphismsopen import Relation.Binary.Morphism.Definitions publicopen import Relation.Binary.Morphism.Structures publicopen import Relation.Binary.Morphism.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Order morphisms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)module Relation.Binary.Morphism.Structures{a b} {A : Set a} {B : Set b}whereopen import Data.Product.Base using (_,_)open import Function.Definitionsopen import Level using (Level; _⊔_)open import Relation.Binary.Morphism.Definitions A Bprivatevariableℓ₁ ℓ₂ ℓ₃ ℓ₄ : Level-------------------------------------------------------------------------- Relations------------------------------------------------------------------------record IsRelHomomorphism (_∼₁_ : Rel A ℓ₁) (_∼₂_ : Rel B ℓ₂)(⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldcong : Homomorphic₂ _∼₁_ _∼₂_ ⟦_⟧record IsRelMonomorphism (_∼₁_ : Rel A ℓ₁) (_∼₂_ : Rel B ℓ₂)(⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisHomomorphism : IsRelHomomorphism _∼₁_ _∼₂_ ⟦_⟧injective : Injective _∼₁_ _∼₂_ ⟦_⟧open IsRelHomomorphism isHomomorphism publicrecord IsRelIsomorphism (_∼₁_ : Rel A ℓ₁) (_∼₂_ : Rel B ℓ₂)(⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMonomorphism : IsRelMonomorphism _∼₁_ _∼₂_ ⟦_⟧surjective : Surjective _∼₁_ _∼₂_ ⟦_⟧open IsRelMonomorphism isMonomorphism publicbijective : Bijective _∼₁_ _∼₂_ ⟦_⟧bijective = injective , surjective-------------------------------------------------------------------------- Orders------------------------------------------------------------------------record IsOrderHomomorphism (_≈₁_ : Rel A ℓ₁) (_≈₂_ : Rel B ℓ₂)(_≲₁_ : Rel A ℓ₃) (_≲₂_ : Rel B ℓ₄)(⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄)wherefieldcong : Homomorphic₂ _≈₁_ _≈₂_ ⟦_⟧mono : Homomorphic₂ _≲₁_ _≲₂_ ⟦_⟧module Eq whereisRelHomomorphism : IsRelHomomorphism _≈₁_ _≈₂_ ⟦_⟧isRelHomomorphism = record { cong = cong }isRelHomomorphism : IsRelHomomorphism _≲₁_ _≲₂_ ⟦_⟧isRelHomomorphism = record { cong = mono }record IsOrderMonomorphism (_≈₁_ : Rel A ℓ₁) (_≈₂_ : Rel B ℓ₂)(_≲₁_ : Rel A ℓ₃) (_≲₂_ : Rel B ℓ₄)(⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄)wherefieldisOrderHomomorphism : IsOrderHomomorphism _≈₁_ _≈₂_ _≲₁_ _≲₂_ ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧cancel : Injective _≲₁_ _≲₂_ ⟦_⟧open IsOrderHomomorphism isOrderHomomorphism publichiding (module Eq)module Eq whereisRelMonomorphism : IsRelMonomorphism _≈₁_ _≈₂_ ⟦_⟧isRelMonomorphism = record{ isHomomorphism = IsOrderHomomorphism.Eq.isRelHomomorphism isOrderHomomorphism; injective = injective}isRelMonomorphism : IsRelMonomorphism _≲₁_ _≲₂_ ⟦_⟧isRelMonomorphism = record{ isHomomorphism = isRelHomomorphism; injective = cancel}record IsOrderIsomorphism (_≈₁_ : Rel A ℓ₁) (_≈₂_ : Rel B ℓ₂)(_≲₁_ : Rel A ℓ₃) (_≲₂_ : Rel B ℓ₄)(⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄)wherefieldisOrderMonomorphism : IsOrderMonomorphism _≈₁_ _≈₂_ _≲₁_ _≲₂_ ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsOrderMonomorphism isOrderMonomorphism publichiding (module Eq)module Eq whereisRelIsomorphism : IsRelIsomorphism _≈₁_ _≈₂_ ⟦_⟧isRelIsomorphism = record{ isMonomorphism = IsOrderMonomorphism.Eq.isRelMonomorphism isOrderMonomorphism; surjective = surjective}
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between binary relations-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Function.Baseopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Total; Asymmetric; Decidable)open import Relation.Binary.Morphismmodule Relation.Binary.Morphism.RelMonomorphism{a b ℓ₁ ℓ₂} {A : Set a} {B : Set b}{_∼₁_ : Rel A ℓ₁} {_∼₂_ : Rel B ℓ₂}{⟦_⟧ : A → B} (isMonomorphism : IsRelMonomorphism _∼₁_ _∼₂_ ⟦_⟧)whereopen import Data.Sum.Base as Sumopen import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Decidableopen IsRelMonomorphism isMonomorphism-------------------------------------------------------------------------- Propertiesrefl : Reflexive _∼₂_ → Reflexive _∼₁_refl refl = injective reflsym : Symmetric _∼₂_ → Symmetric _∼₁_sym sym x∼y = injective (sym (cong x∼y))trans : Transitive _∼₂_ → Transitive _∼₁_trans trans x∼y y∼z = injective (trans (cong x∼y) (cong y∼z))total : Total _∼₂_ → Total _∼₁_total total x y = Sum.map injective injective (total ⟦ x ⟧ ⟦ y ⟧)asym : Asymmetric _∼₂_ → Asymmetric _∼₁_asym asym x∼y y∼x = asym (cong x∼y) (cong y∼x)dec : Decidable _∼₂_ → Decidable _∼₁_dec _∼?_ x y = map′ injective cong (⟦ x ⟧ ∼? ⟦ y ⟧)-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence _∼₂_ → IsEquivalence _∼₁_isEquivalence isEq = record{ refl = refl E.refl; sym = sym E.sym; trans = trans E.trans} where module E = IsEquivalence isEqisDecEquivalence : IsDecEquivalence _∼₂_ → IsDecEquivalence _∼₁_isDecEquivalence isDecEq = record{ isEquivalence = isEquivalence E.isEquivalence; _≟_ = dec E._≟_} where module E = IsDecEquivalence isDecEq
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between orders-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Morphism.Definitionsopen import Function.Baseopen import Data.Product.Base using (_,_; map)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Irreflexive; Antisymmetric; Trichotomous; tri<; tri≈; tri>; _Respectsˡ_; _Respectsʳ_; _Respects₂_)open import Relation.Binary.Morphismimport Relation.Binary.Morphism.RelMonomorphism as RawRelationmodule Relation.Binary.Morphism.OrderMonomorphism{a b ℓ₁ ℓ₂ ℓ₃ ℓ₄} {A : Set a} {B : Set b}{_≈₁_ : Rel A ℓ₁} {_≈₂_ : Rel B ℓ₃}{_≲₁_ : Rel A ℓ₂} {_≲₂_ : Rel B ℓ₄}{⟦_⟧ : A → B}(isOrderMonomorphism : IsOrderMonomorphism _≈₁_ _≈₂_ _≲₁_ _≲₂_ ⟦_⟧)whereopen IsOrderMonomorphism isOrderMonomorphism-------------------------------------------------------------------------- Re-export equivalence proofsmodule EqM = RawRelation Eq.isRelMonomorphismopen RawRelation isRelMonomorphism public-------------------------------------------------------------------------- Propertiesreflexive : _≈₂_ ⇒ _≲₂_ → _≈₁_ ⇒ _≲₁_reflexive refl x≈y = cancel (refl (cong x≈y))irrefl : Irreflexive _≈₂_ _≲₂_ → Irreflexive _≈₁_ _≲₁_irrefl irrefl x≈y x∼y = irrefl (cong x≈y) (mono x∼y)antisym : Antisymmetric _≈₂_ _≲₂_ → Antisymmetric _≈₁_ _≲₁_antisym antisym x∼y y∼x = injective (antisym (mono x∼y) (mono y∼x))compare : Trichotomous _≈₂_ _≲₂_ → Trichotomous _≈₁_ _≲₁_compare compare x y with compare ⟦ x ⟧ ⟦ y ⟧... | tri< a ¬b ¬c = tri< (cancel a) (¬b ∘ cong) (¬c ∘ mono)... | tri≈ ¬a b ¬c = tri≈ (¬a ∘ mono) (injective b) (¬c ∘ mono)... | tri> ¬a ¬b c = tri> (¬a ∘ mono) (¬b ∘ cong) (cancel c)respˡ : _≲₂_ Respectsˡ _≈₂_ → _≲₁_ Respectsˡ _≈₁_respˡ resp x≈y x∼z = cancel (resp (cong x≈y) (mono x∼z))respʳ : _≲₂_ Respectsʳ _≈₂_ → _≲₁_ Respectsʳ _≈₁_respʳ resp x≈y y∼z = cancel (resp (cong x≈y) (mono y∼z))resp : _≲₂_ Respects₂ _≈₂_ → _≲₁_ Respects₂ _≈₁_resp = map respʳ respˡ-------------------------------------------------------------------------- StructuresisPreorder : IsPreorder _≈₂_ _≲₂_ → IsPreorder _≈₁_ _≲₁_isPreorder O = record{ isEquivalence = EqM.isEquivalence O.isEquivalence; reflexive = reflexive O.reflexive; trans = trans O.trans} where module O = IsPreorder OisPartialOrder : IsPartialOrder _≈₂_ _≲₂_ → IsPartialOrder _≈₁_ _≲₁_isPartialOrder O = record{ isPreorder = isPreorder O.isPreorder; antisym = antisym O.antisym} where module O = IsPartialOrder OisTotalOrder : IsTotalOrder _≈₂_ _≲₂_ → IsTotalOrder _≈₁_ _≲₁_isTotalOrder O = record{ isPartialOrder = isPartialOrder O.isPartialOrder; total = total O.total} where module O = IsTotalOrder OisDecTotalOrder : IsDecTotalOrder _≈₂_ _≲₂_ → IsDecTotalOrder _≈₁_ _≲₁_isDecTotalOrder O = record{ isTotalOrder = isTotalOrder O.isTotalOrder; _≟_ = EqM.dec O._≟_; _≤?_ = dec O._≤?_} where module O = IsDecTotalOrder OisStrictPartialOrder : IsStrictPartialOrder _≈₂_ _≲₂_ →IsStrictPartialOrder _≈₁_ _≲₁_isStrictPartialOrder O = record{ isEquivalence = EqM.isEquivalence O.isEquivalence; irrefl = irrefl O.irrefl; trans = trans O.trans; <-resp-≈ = resp O.<-resp-≈} where module O = IsStrictPartialOrder OisStrictTotalOrder : IsStrictTotalOrder _≈₂_ _≲₂_ →IsStrictTotalOrder _≈₁_ _≲₁_isStrictTotalOrder O = record{ isStrictPartialOrder = isStrictPartialOrder O.isStrictPartialOrder; compare = compare O.compare} where module O = IsStrictTotalOrder O
-------------------------------------------------------------------------- The Agda standard library---- Basic definitions for morphisms between algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Relation.Binary.Morphism.Definitions{a} (A : Set a) -- The domain of the morphism{b} (B : Set b) -- The codomain of the morphismwhereopen import Level using (Level)privatevariableℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Morphism definition in Function.Coreopen import Function.Core publicusing (Morphism)-------------------------------------------------------------------------- Basic definitionsHomomorphic₂ : Rel A ℓ₁ → Rel B ℓ₂ → (A → B) → Set _Homomorphic₂ _∼₁_ _∼₂_ ⟦_⟧ = ∀ {x y} → x ∼₁ y → ⟦ x ⟧ ∼₂ ⟦ y ⟧
-------------------------------------------------------------------------- The Agda standard library---- The identity morphism for binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (_,_)open import Function.Base using (id)import Function.Construct.Identity as Idopen import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid; Preorder; Poset)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.Morphism.Structuresopen import Relation.Binary.Morphism.Bundlesmodule Relation.Binary.Morphism.Construct.Identity whereprivatevariablea ℓ₁ ℓ₂ : LevelA : Set a-------------------------------------------------------------------------- Relations-------------------------------------------------------------------------- Structuresmodule _ (≈ : Rel A ℓ₁) whereisRelHomomorphism : IsRelHomomorphism ≈ ≈ idisRelHomomorphism = record{ cong = Id.congruent ≈}isRelMonomorphism : IsRelMonomorphism ≈ ≈ idisRelMonomorphism = record{ isHomomorphism = isRelHomomorphism; injective = Id.injective ≈}isRelIsomorphism : Reflexive ≈ → IsRelIsomorphism ≈ ≈ idisRelIsomorphism refl = record{ isMonomorphism = isRelMonomorphism; surjective = Id.surjective ≈}-------------------------------------------------------------------------- Bundlesmodule _ (S : Setoid a ℓ₁) whereopen Setoid SsetoidHomomorphism : SetoidHomomorphism S SsetoidHomomorphism = record { isRelHomomorphism = isRelHomomorphism _≈_ }setoidMonomorphism : SetoidMonomorphism S SsetoidMonomorphism = record { isRelMonomorphism = isRelMonomorphism _≈_ }setoidIsomorphism : SetoidIsomorphism S SsetoidIsomorphism = record { isRelIsomorphism = isRelIsomorphism _ refl }-------------------------------------------------------------------------- Orders-------------------------------------------------------------------------- Structuresmodule _ (≈ : Rel A ℓ₁) (∼ : Rel A ℓ₂) whereisOrderHomomorphism : IsOrderHomomorphism ≈ ≈ ∼ ∼ idisOrderHomomorphism = record{ cong = id; mono = id}isOrderMonomorphism : IsOrderMonomorphism ≈ ≈ ∼ ∼ idisOrderMonomorphism = record{ isOrderHomomorphism = isOrderHomomorphism; injective = Id.injective ≈; cancel = id}isOrderIsomorphism : Reflexive ≈ → IsOrderIsomorphism ≈ ≈ ∼ ∼ idisOrderIsomorphism refl = record{ isOrderMonomorphism = isOrderMonomorphism; surjective = Id.surjective ≈}-------------------------------------------------------------------------- Bundlesmodule _ (P : Preorder a ℓ₁ ℓ₂) wherepreorderHomomorphism : PreorderHomomorphism P PpreorderHomomorphism = record { isOrderHomomorphism = isOrderHomomorphism _ _ }module _ (P : Poset a ℓ₁ ℓ₂) whereposetHomomorphism : PosetHomomorphism P PposetHomomorphism = record { isOrderHomomorphism = isOrderHomomorphism _ _ }
-------------------------------------------------------------------------- The Agda standard library---- Constant morphisms between binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Function.Base using (const)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.Morphism.Structuresopen import Relation.Binary.Morphism.Bundlesmodule Relation.Binary.Morphism.Construct.Constant whereprivatevariablea b ℓ₁ ℓ₂ ℓ₃ ℓ₄ : LevelA B : Set a-------------------------------------------------------------------------- Relations------------------------------------------------------------------------module _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) whereisRelHomomorphism : Reflexive ≈₂ →∀ x → IsRelHomomorphism ≈₁ ≈₂ (const x)isRelHomomorphism refl x = record{ cong = const refl}module _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) wheresetoidHomomorphism : ∀ x → SetoidHomomorphism S TsetoidHomomorphism x = record{ isRelHomomorphism = isRelHomomorphism _ _ T.refl x} where module T = Setoid T-------------------------------------------------------------------------- Orders------------------------------------------------------------------------module _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) (∼₁ : Rel A ℓ₃) (∼₂ : Rel B ℓ₄) whereisOrderHomomorphism : Reflexive ≈₂ → Reflexive ∼₂ →∀ x → IsOrderHomomorphism ≈₁ ≈₂ ∼₁ ∼₂ (const x)isOrderHomomorphism ≈-refl ∼-refl x = record{ cong = const ≈-refl; mono = const ∼-refl}module _ (P : Preorder a ℓ₁ ℓ₂) (Q : Preorder b ℓ₃ ℓ₄) wherepreorderHomomorphism : ∀ x → PreorderHomomorphism P QpreorderHomomorphism x = record{ isOrderHomomorphism = isOrderHomomorphism _ _ _ _ Q.Eq.refl Q.refl x} where module Q = Preorder Q
-------------------------------------------------------------------------- The Agda standard library---- The composition of morphisms between binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Function.Base using (_∘_)open import Function.Construct.Composition using (surjective)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid; Preorder; Poset)open import Relation.Binary.Definitions using (Transitive)open import Relation.Binary.Morphism.Bundlesopen import Relation.Binary.Morphism.Structuresmodule Relation.Binary.Morphism.Construct.Composition whereprivatevariablea b c ℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ ℓ₆ : LevelA B C : Set a≈₁ ≈₂ ≈₃ ∼₁ ∼₂ ∼₃ : Rel A ℓ₁f g : A → B-------------------------------------------------------------------------- Relations-------------------------------------------------------------------------- StructuresisRelHomomorphism : IsRelHomomorphism ≈₁ ≈₂ f →IsRelHomomorphism ≈₂ ≈₃ g →IsRelHomomorphism ≈₁ ≈₃ (g ∘ f)isRelHomomorphism m₁ m₂ = record{ cong = G.cong ∘ F.cong} where module F = IsRelHomomorphism m₁; module G = IsRelHomomorphism m₂isRelMonomorphism : IsRelMonomorphism ≈₁ ≈₂ f →IsRelMonomorphism ≈₂ ≈₃ g →IsRelMonomorphism ≈₁ ≈₃ (g ∘ f)isRelMonomorphism m₁ m₂ = record{ isHomomorphism = isRelHomomorphism F.isHomomorphism G.isHomomorphism; injective = F.injective ∘ G.injective} where module F = IsRelMonomorphism m₁; module G = IsRelMonomorphism m₂isRelIsomorphism : Transitive ≈₃ →IsRelIsomorphism ≈₁ ≈₂ f →IsRelIsomorphism ≈₂ ≈₃ g →IsRelIsomorphism ≈₁ ≈₃ (g ∘ f)isRelIsomorphism {≈₃ = ≈₃} ≈₃-trans m₁ m₂ = record{ isMonomorphism = isRelMonomorphism F.isMonomorphism G.isMonomorphism; surjective = surjective _ _ ≈₃ F.surjective G.surjective} where module F = IsRelIsomorphism m₁; module G = IsRelIsomorphism m₂-------------------------------------------------------------------------- Bundlesmodule _ {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} {U : Setoid c ℓ₃} wheresetoidHomomorphism : SetoidHomomorphism S T →SetoidHomomorphism T U →SetoidHomomorphism S UsetoidHomomorphism ST TU = record{ isRelHomomorphism = isRelHomomorphism ST.isRelHomomorphism TU.isRelHomomorphism} where module ST = SetoidHomomorphism ST; module TU = SetoidHomomorphism TUsetoidMonomorphism : SetoidMonomorphism S T →SetoidMonomorphism T U →SetoidMonomorphism S UsetoidMonomorphism ST TU = record{ isRelMonomorphism = isRelMonomorphism ST.isRelMonomorphism TU.isRelMonomorphism} where module ST = SetoidMonomorphism ST; module TU = SetoidMonomorphism TUsetoidIsomorphism : SetoidIsomorphism S T →SetoidIsomorphism T U →SetoidIsomorphism S UsetoidIsomorphism ST TU = record{ isRelIsomorphism = isRelIsomorphism (Setoid.trans U) ST.isRelIsomorphism TU.isRelIsomorphism} where module ST = SetoidIsomorphism ST; module TU = SetoidIsomorphism TU-------------------------------------------------------------------------- Orders-------------------------------------------------------------------------- StructuresisOrderHomomorphism : IsOrderHomomorphism ≈₁ ≈₂ ∼₁ ∼₂ f →IsOrderHomomorphism ≈₂ ≈₃ ∼₂ ∼₃ g →IsOrderHomomorphism ≈₁ ≈₃ ∼₁ ∼₃ (g ∘ f)isOrderHomomorphism m₁ m₂ = record{ cong = G.cong ∘ F.cong; mono = G.mono ∘ F.mono} where module F = IsOrderHomomorphism m₁; module G = IsOrderHomomorphism m₂isOrderMonomorphism : IsOrderMonomorphism ≈₁ ≈₂ ∼₁ ∼₂ f →IsOrderMonomorphism ≈₂ ≈₃ ∼₂ ∼₃ g →IsOrderMonomorphism ≈₁ ≈₃ ∼₁ ∼₃ (g ∘ f)isOrderMonomorphism m₁ m₂ = record{ isOrderHomomorphism = isOrderHomomorphism F.isOrderHomomorphism G.isOrderHomomorphism; injective = F.injective ∘ G.injective; cancel = F.cancel ∘ G.cancel} where module F = IsOrderMonomorphism m₁; module G = IsOrderMonomorphism m₂isOrderIsomorphism : Transitive ≈₃ →IsOrderIsomorphism ≈₁ ≈₂ ∼₁ ∼₂ f →IsOrderIsomorphism ≈₂ ≈₃ ∼₂ ∼₃ g →IsOrderIsomorphism ≈₁ ≈₃ ∼₁ ∼₃ (g ∘ f)isOrderIsomorphism {≈₃ = ≈₃} ≈₃-trans m₁ m₂ = record{ isOrderMonomorphism = isOrderMonomorphism F.isOrderMonomorphism G.isOrderMonomorphism; surjective = surjective _ _ ≈₃ F.surjective G.surjective} where module F = IsOrderIsomorphism m₁; module G = IsOrderIsomorphism m₂-------------------------------------------------------------------------- Bundlesmodule _ {P : Preorder a ℓ₁ ℓ₂} {Q : Preorder b ℓ₃ ℓ₄} {R : Preorder c ℓ₅ ℓ₆} wherepreorderHomomorphism : PreorderHomomorphism P Q →PreorderHomomorphism Q R →PreorderHomomorphism P RpreorderHomomorphism PQ QR = record{ isOrderHomomorphism = isOrderHomomorphism PQ.isOrderHomomorphism QR.isOrderHomomorphism} where module PQ = PreorderHomomorphism PQ; module QR = PreorderHomomorphism QRmodule _ {P : Poset a ℓ₁ ℓ₂} {Q : Poset b ℓ₃ ℓ₄} {R : Poset c ℓ₅ ℓ₆} whereposetHomomorphism : PosetHomomorphism P Q →PosetHomomorphism Q R →PosetHomomorphism P RposetHomomorphism PQ QR = record{ isOrderHomomorphism = isOrderHomomorphism PQ.isOrderHomomorphism QR.isOrderHomomorphism} where module PQ = PosetHomomorphism PQ; module QR = PosetHomomorphism QR
-------------------------------------------------------------------------- The Agda standard library---- Bundles for morphisms between binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelopen import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundlesopen import Relation.Binary.Morphism.Structuresopen import Relation.Binary.Consequences using (mono⇒cong)module Relation.Binary.Morphism.Bundles whereprivatevariableℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ ℓ₆ : Level-------------------------------------------------------------------------- Setoids------------------------------------------------------------------------module _ (S₁ : Setoid ℓ₁ ℓ₂) (S₂ : Setoid ℓ₃ ℓ₄) whererecord SetoidHomomorphism : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄) whereopen Setoidfield⟦_⟧ : Carrier S₁ → Carrier S₂isRelHomomorphism : IsRelHomomorphism (_≈_ S₁) (_≈_ S₂) ⟦_⟧open IsRelHomomorphism isRelHomomorphism publicrecord SetoidMonomorphism : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄) whereopen Setoidfield⟦_⟧ : Carrier S₁ → Carrier S₂isRelMonomorphism : IsRelMonomorphism (_≈_ S₁) (_≈_ S₂) ⟦_⟧open IsRelMonomorphism isRelMonomorphism publichomomorphism : SetoidHomomorphismhomomorphism = record { isRelHomomorphism = isHomomorphism }record SetoidIsomorphism : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄) whereopen Setoidfield⟦_⟧ : Carrier S₁ → Carrier S₂isRelIsomorphism : IsRelIsomorphism (_≈_ S₁) (_≈_ S₂) ⟦_⟧open IsRelIsomorphism isRelIsomorphism publicmonomorphism : SetoidMonomorphismmonomorphism = record { isRelMonomorphism = isMonomorphism }open SetoidMonomorphism monomorphism publicusing (homomorphism)-------------------------------------------------------------------------- Preorders------------------------------------------------------------------------record PreorderHomomorphism (S₁ : Preorder ℓ₁ ℓ₂ ℓ₃)(S₂ : Preorder ℓ₄ ℓ₅ ℓ₆): Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄ ⊔ ℓ₅ ⊔ ℓ₆) whereopen Preorderfield⟦_⟧ : Carrier S₁ → Carrier S₂isOrderHomomorphism : IsOrderHomomorphism (_≈_ S₁) (_≈_ S₂) (_≲_ S₁) (_≲_ S₂) ⟦_⟧open IsOrderHomomorphism isOrderHomomorphism public-------------------------------------------------------------------------- Posets------------------------------------------------------------------------module _ (P : Poset ℓ₁ ℓ₂ ℓ₃) (Q : Poset ℓ₄ ℓ₅ ℓ₆) whereprivatemodule P = Poset Pmodule Q = Poset Qrecord PosetHomomorphism : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄ ⊔ ℓ₅ ⊔ ℓ₆) wherefield⟦_⟧ : P.Carrier → Q.CarrierisOrderHomomorphism : IsOrderHomomorphism P._≈_ Q._≈_ P._≤_ Q._≤_ ⟦_⟧open IsOrderHomomorphism isOrderHomomorphism public-- Smart constructor that automatically constructs the congruence-- proof from the monotonicity proofmkPosetHomo : ∀ f → f Preserves P._≤_ ⟶ Q._≤_ → PosetHomomorphismmkPosetHomo f mono = record{ ⟦_⟧ = f; isOrderHomomorphism = record{ cong = mono⇒cong P._≈_ Q._≈_ P.Eq.sym P.reflexive Q.antisym mono; mono = mono}}
-------------------------------------------------------------------------- The Agda standard library---- Order-theoretic lattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Lattice where-------------------------------------------------------------------------- Re-export various components of the lattice hierarchyopen import Relation.Binary.Lattice.Definitions publicopen import Relation.Binary.Lattice.Structures publicopen import Relation.Binary.Lattice.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Structures for order-theoretic lattices-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Lattice`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsPartialOrder)open import Relation.Binary.Definitions using (Minimum; Maximum)module Relation.Binary.Lattice.Structures{a ℓ₁ ℓ₂} {A : Set a}(_≈_ : Rel A ℓ₁) -- The underlying equality.(_≤_ : Rel A ℓ₂) -- The partial order.whereopen import Algebra.Coreopen import Algebra.Definitionsopen import Data.Product.Base using (_×_; _,_)open import Level using (suc; _⊔_)open import Relation.Binary.Lattice.Definitions-------------------------------------------------------------------------- Join semilatticesrecord IsJoinSemilattice (_∨_ : Op₂ A) -- The join operation.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisPartialOrder : IsPartialOrder _≈_ _≤_supremum : Supremum _≤_ _∨_x≤x∨y : ∀ x y → x ≤ (x ∨ y)x≤x∨y x y = let pf , _ , _ = supremum x y in pfy≤x∨y : ∀ x y → y ≤ (x ∨ y)y≤x∨y x y = let _ , pf , _ = supremum x y in pf∨-least : ∀ {x y z} → x ≤ z → y ≤ z → (x ∨ y) ≤ z∨-least {x} {y} {z} = let _ , _ , pf = supremum x y in pf zopen IsPartialOrder isPartialOrder publicrecord IsBoundedJoinSemilattice (_∨_ : Op₂ A) -- The join operation.(⊥ : A) -- The minimum.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisJoinSemilattice : IsJoinSemilattice _∨_minimum : Minimum _≤_ ⊥open IsJoinSemilattice isJoinSemilattice public-------------------------------------------------------------------------- Meet semilatticesrecord IsMeetSemilattice (_∧_ : Op₂ A) -- The meet operation.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisPartialOrder : IsPartialOrder _≈_ _≤_infimum : Infimum _≤_ _∧_x∧y≤x : ∀ x y → (x ∧ y) ≤ xx∧y≤x x y = let pf , _ , _ = infimum x y in pfx∧y≤y : ∀ x y → (x ∧ y) ≤ yx∧y≤y x y = let _ , pf , _ = infimum x y in pf∧-greatest : ∀ {x y z} → x ≤ y → x ≤ z → x ≤ (y ∧ z)∧-greatest {x} {y} {z} = let _ , _ , pf = infimum y z in pf xopen IsPartialOrder isPartialOrder publicrecord IsBoundedMeetSemilattice (_∧_ : Op₂ A) -- The join operation.(⊤ : A) -- The maximum.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMeetSemilattice : IsMeetSemilattice _∧_maximum : Maximum _≤_ ⊤open IsMeetSemilattice isMeetSemilattice public-------------------------------------------------------------------------- Latticesrecord IsLattice (_∨_ : Op₂ A) -- The join operation.(_∧_ : Op₂ A) -- The meet operation.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisPartialOrder : IsPartialOrder _≈_ _≤_supremum : Supremum _≤_ _∨_infimum : Infimum _≤_ _∧_isJoinSemilattice : IsJoinSemilattice _∨_isJoinSemilattice = record{ isPartialOrder = isPartialOrder; supremum = supremum}isMeetSemilattice : IsMeetSemilattice _∧_isMeetSemilattice = record{ isPartialOrder = isPartialOrder; infimum = infimum}open IsJoinSemilattice isJoinSemilattice publicusing (x≤x∨y; y≤x∨y; ∨-least)open IsMeetSemilattice isMeetSemilattice publicusing (x∧y≤x; x∧y≤y; ∧-greatest)open IsPartialOrder isPartialOrder publicrecord IsDistributiveLattice (_∨_ : Op₂ A) -- The join operation.(_∧_ : Op₂ A) -- The meet operation.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLattice : IsLattice _∨_ _∧_∧-distribˡ-∨ : _DistributesOverˡ_ _≈_ _∧_ _∨_open IsLattice isLattice publicrecord IsBoundedLattice (_∨_ : Op₂ A) -- The join operation.(_∧_ : Op₂ A) -- The meet operation.(⊤ : A) -- The maximum.(⊥ : A) -- The minimum.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLattice : IsLattice _∨_ _∧_maximum : Maximum _≤_ ⊤minimum : Minimum _≤_ ⊥open IsLattice isLattice publicisBoundedJoinSemilattice : IsBoundedJoinSemilattice _∨_ ⊥isBoundedJoinSemilattice = record{ isJoinSemilattice = isJoinSemilattice; minimum = minimum}isBoundedMeetSemilattice : IsBoundedMeetSemilattice _∧_ ⊤isBoundedMeetSemilattice = record{ isMeetSemilattice = isMeetSemilattice; maximum = maximum}-------------------------------------------------------------------------- Heyting algebras (a bounded lattice with exponential operator)record IsHeytingAlgebra (_∨_ : Op₂ A) -- The join operation.(_∧_ : Op₂ A) -- The meet operation.(_⇨_ : Op₂ A) -- The exponential operation.(⊤ : A) -- The maximum.(⊥ : A) -- The minimum.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisBoundedLattice : IsBoundedLattice _∨_ _∧_ ⊤ ⊥exponential : Exponential _≤_ _∧_ _⇨_transpose-⇨ : ∀ {w x y} → (w ∧ x) ≤ y → w ≤ (x ⇨ y)transpose-⇨ {w} {x} {y} = let pf , _ = exponential w x y in pftranspose-∧ : ∀ {w x y} → w ≤ (x ⇨ y) → (w ∧ x) ≤ ytranspose-∧ {w} {x} {y} = let _ , pf = exponential w x y in pfopen IsBoundedLattice isBoundedLattice public-------------------------------------------------------------------------- Boolean algebras (a specialized Heyting algebra)record IsBooleanAlgebra (_∨_ : Op₂ A) -- The join operation.(_∧_ : Op₂ A) -- The meet operation.(¬_ : Op₁ A) -- The negation operation.(⊤ : A) -- The maximum.(⊥ : A) -- The minimum.: Set (a ⊔ ℓ₁ ⊔ ℓ₂) whereinfixr 5 _⇨__⇨_ : Op₂ Ax ⇨ y = (¬ x) ∨ yfieldisHeytingAlgebra : IsHeytingAlgebra _∨_ _∧_ _⇨_ ⊤ ⊥open IsHeytingAlgebra isHeytingAlgebra public
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by meet semilattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.MeetSemilattice{c ℓ₁ ℓ₂} (M : MeetSemilattice c ℓ₁ ℓ₂) whereopen MeetSemilattice Mopen import Algebra.Definitions _≈_open import Function.Base using (flip)open import Relation.Binary.Structures using (IsDecPartialOrder)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.Properties.Poset posetimport Relation.Binary.Lattice.Properties.JoinSemilattice as J-- The dual construction is a join semilattice.dualIsJoinSemilattice : IsJoinSemilattice _≈_ (flip _≤_) _∧_dualIsJoinSemilattice = record{ isPartialOrder = ≥-isPartialOrder; supremum = infimum}dualJoinSemilattice : JoinSemilattice c ℓ₁ ℓ₂dualJoinSemilattice = record{ _∨_ = _∧_; isJoinSemilattice = dualIsJoinSemilattice}open J dualJoinSemilattice publicusing (isAlgSemilattice; algSemilattice)renaming( ∨-monotonic to ∧-monotonic; ∨-cong to ∧-cong; ∨-comm to ∧-comm; ∨-assoc to ∧-assoc; ∨-idempotent to ∧-idempotent; x≤y⇒x∨y≈y to y≤x⇒x∧y≈y; ≈-dec⇒≤-dec to ≈-dec⇒≥-dec)-- If ≈ is decidable then so is ≤≈-dec⇒≤-dec : Decidable _≈_ → Decidable _≤_≈-dec⇒≤-dec _≟_ = flip (≈-dec⇒≥-dec _≟_)≈-dec⇒isDecPartialOrder : Decidable _≈_ → IsDecPartialOrder _≈_ _≤_≈-dec⇒isDecPartialOrder _≟_ = record{ isPartialOrder = isPartialOrder; _≟_ = _≟_; _≤?_ = ≈-dec⇒≤-dec _≟_}
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by lattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.Lattice{c ℓ₁ ℓ₂} (L : Lattice c ℓ₁ ℓ₂) whereopen Lattice Limport Algebra.Lattice as Algimport Algebra.Structures as Algopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Function.Base using (flip)open import Relation.Binary.Properties.Poset posetimport Relation.Binary.Lattice.Properties.JoinSemilattice joinSemilattice as Jimport Relation.Binary.Lattice.Properties.MeetSemilattice meetSemilattice as Mimport Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Relation.Binary.Reasoning.PartialOrder as ≤-Reasoning∨-absorbs-∧ : _∨_ Absorbs _∧_∨-absorbs-∧ x y =let x≤x∨[x∧y] , _ , least = supremum x (x ∧ y)x∧y≤x , _ , _ = infimum x yin antisym (least x refl x∧y≤x) x≤x∨[x∧y]∧-absorbs-∨ : _∧_ Absorbs _∨_∧-absorbs-∨ x y =let x∧[x∨y]≤x , _ , greatest = infimum x (x ∨ y)x≤x∨y , _ , _ = supremum x yin antisym x∧[x∨y]≤x (greatest x refl x≤x∨y)absorptive : Absorptive _∨_ _∧_absorptive = ∨-absorbs-∧ , ∧-absorbs-∨∧≤∨ : ∀ {x y} → x ∧ y ≤ x ∨ y∧≤∨ {x} {y} = beginx ∧ y ≤⟨ x∧y≤x x y ⟩x ≤⟨ x≤x∨y x y ⟩x ∨ y ∎where open ≤-Reasoning poset-- two quadrilateral argumentsquadrilateral₁ : ∀ {x y} → x ∨ y ≈ x → x ∧ y ≈ yquadrilateral₁ {x} {y} x∨y≈x = beginx ∧ y ≈⟨ M.∧-cong (Eq.sym x∨y≈x) Eq.refl ⟩(x ∨ y) ∧ y ≈⟨ M.∧-comm _ _ ⟩y ∧ (x ∨ y) ≈⟨ M.∧-cong Eq.refl (J.∨-comm _ _) ⟩y ∧ (y ∨ x) ≈⟨ ∧-absorbs-∨ _ _ ⟩y ∎where open ≈-Reasoning setoidquadrilateral₂ : ∀ {x y} → x ∧ y ≈ y → x ∨ y ≈ xquadrilateral₂ {x} {y} x∧y≈y = beginx ∨ y ≈⟨ J.∨-cong Eq.refl (Eq.sym x∧y≈y) ⟩x ∨ (x ∧ y) ≈⟨ ∨-absorbs-∧ _ _ ⟩x ∎where open ≈-Reasoning setoid-- collapsing sublatticecollapse₁ : ∀ {x y} → x ≈ y → x ∧ y ≈ x ∨ ycollapse₁ {x} {y} x≈y = beginx ∧ y ≈⟨ M.y≤x⇒x∧y≈y y≤x ⟩y ≈⟨ Eq.sym x≈y ⟩x ≈⟨ Eq.sym (J.x≤y⇒x∨y≈y y≤x) ⟩y ∨ x ≈⟨ J.∨-comm _ _ ⟩x ∨ y ∎wherey≤x = reflexive (Eq.sym x≈y)open ≈-Reasoning setoid-- this can also be proved by quadrilateral argument, but it's much less symmetric.collapse₂ : ∀ {x y} → x ∨ y ≤ x ∧ y → x ≈ ycollapse₂ {x} {y} ∨≤∧ = antisym(begin x ≤⟨ x≤x∨y _ _ ⟩x ∨ y ≤⟨ ∨≤∧ ⟩x ∧ y ≤⟨ x∧y≤y _ _ ⟩y ∎)(begin y ≤⟨ y≤x∨y _ _ ⟩x ∨ y ≤⟨ ∨≤∧ ⟩x ∧ y ≤⟨ x∧y≤x _ _ ⟩x ∎)where open ≤-Reasoning poset-------------------------------------------------------------------------- The dual construction is also a lattice.∧-∨-isLattice : IsLattice _≈_ (flip _≤_) _∧_ _∨_∧-∨-isLattice = record{ isPartialOrder = ≥-isPartialOrder; supremum = infimum; infimum = supremum}∧-∨-lattice : Lattice c ℓ₁ ℓ₂∧-∨-lattice = record{ _∧_ = _∨_; _∨_ = _∧_; isLattice = ∧-∨-isLattice}-------------------------------------------------------------------------- Every order-theoretic lattice can be turned into an algebraic one.isAlgLattice : Alg.IsLattice _≈_ _∨_ _∧_isAlgLattice = record{ isEquivalence = isEquivalence; ∨-comm = J.∨-comm; ∨-assoc = J.∨-assoc; ∨-cong = J.∨-cong; ∧-comm = M.∧-comm; ∧-assoc = M.∧-assoc; ∧-cong = M.∧-cong; absorptive = absorptive}algLattice : Alg.Lattice c ℓ₁algLattice = record { isLattice = isAlgLattice }
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by join semilattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.JoinSemilattice{c ℓ₁ ℓ₂} (J : JoinSemilattice c ℓ₁ ℓ₂) whereopen JoinSemilattice Jimport Algebra.Lattice as Algimport Algebra.Structures as Algopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Function.Base using (_∘_; flip)open import Relation.Binary.Core using (_Preserves₂_⟶_⟶_)open import Relation.Binary.Structures using (IsDecPartialOrder)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.Properties.Poset posetopen import Relation.Nullary using (¬_; yes; no)open import Relation.Nullary.Negation using (contraposition)import Relation.Binary.Reasoning.PartialOrder as PoR-------------------------------------------------------------------------- Algebraic properties-- The join operation is monotonic.∨-monotonic : _∨_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_∨-monotonic {x} {y} {u} {v} x≤y u≤v =let _ , _ , least = supremum x uy≤y∨v , v≤y∨v , _ = supremum y vin least (y ∨ v) (trans x≤y y≤y∨v) (trans u≤v v≤y∨v)∨-cong : _∨_ Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_∨-cong x≈y u≈v = antisym (∨-monotonic (reflexive x≈y) (reflexive u≈v))(∨-monotonic (reflexive (Eq.sym x≈y))(reflexive (Eq.sym u≈v)))-- The join operation is commutative, associative and idempotent.∨-comm : Commutative _∨_∨-comm x y =let x≤x∨y , y≤x∨y , least = supremum x yy≤y∨x , x≤y∨x , least′ = supremum y xin antisym (least (y ∨ x) x≤y∨x y≤y∨x) (least′ (x ∨ y) y≤x∨y x≤x∨y)∨-assoc : Associative _∨_∨-assoc x y z =let x∨y≤[x∨y]∨z , z≤[x∨y]∨z , least = supremum (x ∨ y) zx≤x∨[y∨z] , y∨z≤x∨[y∨z] , least′ = supremum x (y ∨ z)y≤y∨z , z≤y∨z , _ = supremum y zx≤x∨y , y≤x∨y , _ = supremum x yin antisym (least (x ∨ (y ∨ z)) (∨-monotonic refl y≤y∨z)(trans z≤y∨z y∨z≤x∨[y∨z]))(least′ ((x ∨ y) ∨ z) (trans x≤x∨y x∨y≤[x∨y]∨z)(∨-monotonic y≤x∨y refl))∨-idempotent : Idempotent _∨_∨-idempotent x =let x≤x∨x , _ , least = supremum x xin antisym (least x refl refl) x≤x∨xx≤y⇒x∨y≈y : ∀ {x y} → x ≤ y → x ∨ y ≈ yx≤y⇒x∨y≈y {x} {y} x≤y = antisym(begin x ∨ y ≤⟨ ∨-monotonic x≤y refl ⟩y ∨ y ≈⟨ ∨-idempotent _ ⟩y ∎)(y≤x∨y _ _)where open PoR poset-- Every order-theoretic semilattice can be turned into an algebraic one.isAlgSemilattice : Alg.IsSemilattice _≈_ _∨_isAlgSemilattice = record{ isBand = record{ isSemigroup = record{ isMagma = record{ isEquivalence = isEquivalence; ∙-cong = ∨-cong}; assoc = ∨-assoc}; idem = ∨-idempotent}; comm = ∨-comm}algSemilattice : Alg.Semilattice c ℓ₁algSemilattice = record { isSemilattice = isAlgSemilattice }-------------------------------------------------------------------------- The dual construction is a meet semilattice.dualIsMeetSemilattice : IsMeetSemilattice _≈_ (flip _≤_) _∨_dualIsMeetSemilattice = record{ isPartialOrder = ≥-isPartialOrder; infimum = supremum}dualMeetSemilattice : MeetSemilattice c ℓ₁ ℓ₂dualMeetSemilattice = record{ _∧_ = _∨_; isMeetSemilattice = dualIsMeetSemilattice}-------------------------------------------------------------------------- If ≈ is decidable then so is ≤≈-dec⇒≤-dec : Decidable _≈_ → Decidable _≤_≈-dec⇒≤-dec _≟_ x y with (x ∨ y) ≟ y... | yes x∨y≈y = yes (trans (x≤x∨y x y) (reflexive x∨y≈y))... | no x∨y≉y = no (contraposition x≤y⇒x∨y≈y x∨y≉y)≈-dec⇒isDecPartialOrder : Decidable _≈_ → IsDecPartialOrder _≈_ _≤_≈-dec⇒isDecPartialOrder _≟_ = record{ isPartialOrder = isPartialOrder; _≟_ = _≟_; _≤?_ = ≈-dec⇒≤-dec _≟_}
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by Heyting Algebra------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.HeytingAlgebra{c ℓ₁ ℓ₂} (L : HeytingAlgebra c ℓ₁ ℓ₂) whereopen HeytingAlgebra Lopen import Algebra.Coreopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Function.Base using (_$_; flip; _∘_)open import Level using (_⊔_)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)import Relation.Binary.Reasoning.PartialOrder as ≤-Reasoningopen import Relation.Binary.Lattice.Properties.MeetSemilattice meetSemilatticeopen import Relation.Binary.Lattice.Properties.JoinSemilattice joinSemilatticeimport Relation.Binary.Lattice.Properties.BoundedMeetSemilattice boundedMeetSemilattice as BMopen import Relation.Binary.Lattice.Properties.Lattice latticeopen import Relation.Binary.Lattice.Properties.BoundedLattice boundedLatticeimport Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- Useful lemmas⇨-eval : ∀ {x y} → (x ⇨ y) ∧ x ≤ y⇨-eval {x} {y} = transpose-∧ reflswap-transpose-⇨ : ∀ {x y w} → x ∧ w ≤ y → w ≤ x ⇨ yswap-transpose-⇨ x∧w≤y = transpose-⇨ $ trans (reflexive $ ∧-comm _ _) x∧w≤y-------------------------------------------------------------------------- Properties of exponential⇨-unit : ∀ {x} → x ⇨ x ≈ ⊤⇨-unit = antisym (maximum _) (transpose-⇨ $ reflexive $ BM.identityˡ _)y≤x⇨y : ∀ {x y} → y ≤ x ⇨ yy≤x⇨y = transpose-⇨ (x∧y≤x _ _)⇨-drop : ∀ {x y} → (x ⇨ y) ∧ y ≈ y⇨-drop = antisym (x∧y≤y _ _) (∧-greatest y≤x⇨y refl)⇨-app : ∀ {x y} → (x ⇨ y) ∧ x ≈ y ∧ x⇨-app = antisym (∧-greatest ⇨-eval (x∧y≤y _ _)) (∧-monotonic y≤x⇨y refl)⇨ʳ-covariant : ∀ {x} → (x ⇨_) Preserves _≤_ ⟶ _≤_⇨ʳ-covariant y≤z = transpose-⇨ (trans ⇨-eval y≤z)⇨ˡ-contravariant : ∀ {x} → (_⇨ x) Preserves (flip _≤_) ⟶ _≤_⇨ˡ-contravariant z≤y = transpose-⇨ (trans (∧-monotonic refl z≤y) ⇨-eval)⇨-relax : _⇨_ Preserves₂ (flip _≤_) ⟶ _≤_ ⟶ _≤_⇨-relax {x} {y} {u} {v} y≤x u≤v = beginx ⇨ u ≤⟨ ⇨ʳ-covariant u≤v ⟩x ⇨ v ≤⟨ ⇨ˡ-contravariant y≤x ⟩y ⇨ v ∎where open ≤-Reasoning poset⇨-cong : _⇨_ Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_⇨-cong x≈y u≈v = antisym (⇨-relax (reflexive $ Eq.sym x≈y) (reflexive u≈v))(⇨-relax (reflexive x≈y) (reflexive $ Eq.sym u≈v))⇨-applyˡ : ∀ {w x y} → w ≤ x → (x ⇨ y) ∧ w ≤ y⇨-applyˡ = transpose-∧ ∘ ⇨ˡ-contravariant⇨-applyʳ : ∀ {w x y} → w ≤ x → w ∧ (x ⇨ y) ≤ y⇨-applyʳ w≤x = trans (reflexive (∧-comm _ _)) (⇨-applyˡ w≤x)⇨-curry : ∀ {x y z} → x ∧ y ⇨ z ≈ x ⇨ y ⇨ z⇨-curry = antisym (transpose-⇨ $ transpose-⇨ $ trans (reflexive $ ∧-assoc _ _ _) ⇨-eval)(transpose-⇨ $ trans (reflexive $ Eq.sym $ ∧-assoc _ _ _)(transpose-∧ $ ⇨-applyˡ refl))-------------------------------------------------------------------------- Various proofs of distributivity∧-distribˡ-∨-≤ : ∀ x y z → x ∧ (y ∨ z) ≤ x ∧ y ∨ x ∧ z∧-distribˡ-∨-≤ x y z = trans (reflexive $ ∧-comm _ _)(transpose-∧ $ ∨-least (swap-transpose-⇨ (x≤x∨y _ _)) $ swap-transpose-⇨ (y≤x∨y _ _))∧-distribˡ-∨-≥ : ∀ x y z → x ∧ y ∨ x ∧ z ≤ x ∧ (y ∨ z)∧-distribˡ-∨-≥ x y z = letx∧y≤x , x∧y≤y , _ = infimum x yx∧z≤x , x∧z≤z , _ = infimum x zy≤y∨z , z≤y∨z , _ = supremum y zin ∧-greatest (∨-least x∧y≤x x∧z≤x)(∨-least (trans x∧y≤y y≤y∨z) (trans x∧z≤z z≤y∨z))∧-distribˡ-∨ : _∧_ DistributesOverˡ _∨_∧-distribˡ-∨ x y z = antisym (∧-distribˡ-∨-≤ x y z) (∧-distribˡ-∨-≥ x y z)⇨-distribˡ-∧-≤ : ∀ x y z → x ⇨ y ∧ z ≤ (x ⇨ y) ∧ (x ⇨ z)⇨-distribˡ-∧-≤ x y z = lety∧z≤y , y∧z≤z , _ = infimum y zin ∧-greatest (transpose-⇨ $ trans ⇨-eval y∧z≤y)(transpose-⇨ $ trans ⇨-eval y∧z≤z)⇨-distribˡ-∧-≥ : ∀ x y z → (x ⇨ y) ∧ (x ⇨ z) ≤ x ⇨ y ∧ z⇨-distribˡ-∧-≥ x y z = transpose-⇨ (begin(((x ⇨ y) ∧ (x ⇨ z)) ∧ x) ≈⟨ ∧-cong Eq.refl $ Eq.sym $ ∧-idempotent _ ⟩(((x ⇨ y) ∧ (x ⇨ z)) ∧ x ∧ x) ≈⟨ Eq.sym $ ∧-assoc _ _ _ ⟩(((x ⇨ y) ∧ (x ⇨ z)) ∧ x) ∧ x ≈⟨ ∧-cong (∧-assoc _ _ _) Eq.refl ⟩(((x ⇨ y) ∧ (x ⇨ z) ∧ x) ∧ x) ≈⟨ ∧-cong (∧-cong Eq.refl $ ∧-comm _ _) Eq.refl ⟩(((x ⇨ y) ∧ x ∧ (x ⇨ z)) ∧ x) ≈⟨ ∧-cong (Eq.sym $ ∧-assoc _ _ _) Eq.refl ⟩(((x ⇨ y) ∧ x) ∧ (x ⇨ z)) ∧ x ≈⟨ ∧-assoc _ _ _ ⟩(((x ⇨ y) ∧ x) ∧ (x ⇨ z) ∧ x) ≤⟨ ∧-monotonic ⇨-eval ⇨-eval ⟩y ∧ z ∎)where open ≤-Reasoning poset⇨-distribˡ-∧ : _⇨_ DistributesOverˡ _∧_⇨-distribˡ-∧ x y z = antisym (⇨-distribˡ-∧-≤ x y z) (⇨-distribˡ-∧-≥ x y z)⇨-distribˡ-∨-∧-≤ : ∀ x y z → x ∨ y ⇨ z ≤ (x ⇨ z) ∧ (y ⇨ z)⇨-distribˡ-∨-∧-≤ x y z = let x≤x∨y , y≤x∨y , _ = supremum x yin ∧-greatest (transpose-⇨ $ trans (∧-monotonic refl x≤x∨y) ⇨-eval)(transpose-⇨ $ trans (∧-monotonic refl y≤x∨y) ⇨-eval)⇨-distribˡ-∨-∧-≥ : ∀ x y z → (x ⇨ z) ∧ (y ⇨ z) ≤ x ∨ y ⇨ z⇨-distribˡ-∨-∧-≥ x y z = transpose-⇨ (trans (reflexive $ ∧-distribˡ-∨ _ _ _)(∨-least (trans (transpose-∧ (x∧y≤x _ _)) refl)(trans (transpose-∧ (x∧y≤y _ _)) refl)))⇨-distribˡ-∨-∧ : ∀ x y z → x ∨ y ⇨ z ≈ (x ⇨ z) ∧ (y ⇨ z)⇨-distribˡ-∨-∧ x y z = antisym (⇨-distribˡ-∨-∧-≤ x y z) (⇨-distribˡ-∨-∧-≥ x y z)-------------------------------------------------------------------------- Heyting algebras are distributive latticesisDistributiveLattice : IsDistributiveLattice _≈_ _≤_ _∨_ _∧_isDistributiveLattice = record{ isLattice = isLattice; ∧-distribˡ-∨ = ∧-distribˡ-∨}distributiveLattice : DistributiveLattice _ _ _distributiveLattice = record{ isDistributiveLattice = isDistributiveLattice}-------------------------------------------------------------------------- Heyting algebras can define pseudo-complementinfix 8 ¬_¬_ : Op₁ Carrier¬ x = x ⇨ ⊥x≤¬¬x : ∀ x → x ≤ ¬ ¬ xx≤¬¬x x = transpose-⇨ (trans (reflexive (∧-comm _ _)) ⇨-eval)-------------------------------------------------------------------------- De-Morgan lawsde-morgan₁ : ∀ x y → ¬ (x ∨ y) ≈ ¬ x ∧ ¬ yde-morgan₁ x y = ⇨-distribˡ-∨-∧ _ _ _de-morgan₂-≤ : ∀ x y → ¬ (x ∧ y) ≤ ¬ ¬ (¬ x ∨ ¬ y)de-morgan₂-≤ x y = transpose-⇨ $ begin¬ (x ∧ y) ∧ ¬ (¬ x ∨ ¬ y) ≈⟨ ∧-cong ⇨-curry (de-morgan₁ _ _) ⟩(x ⇨ ¬ y) ∧ ¬ ¬ x ∧ ¬ ¬ y ≈⟨ ∧-cong Eq.refl (∧-comm _ _) ⟩(x ⇨ ¬ y) ∧ ¬ ¬ y ∧ ¬ ¬ x ≈⟨ Eq.sym $ ∧-assoc _ _ _ ⟩((x ⇨ ¬ y) ∧ ¬ ¬ y) ∧ ¬ ¬ x ≤⟨ ⇨-applyʳ $ transpose-⇨ $begin((x ⇨ ¬ y) ∧ ¬ ¬ y) ∧ x ≈⟨ ∧-cong (∧-comm _ _) Eq.refl ⟩((¬ ¬ y) ∧ (x ⇨ ¬ y)) ∧ x ≈⟨ ∧-assoc _ _ _ ⟩(¬ ¬ y) ∧ (x ⇨ ¬ y) ∧ x ≤⟨ ∧-monotonic refl ⇨-eval ⟩¬ ¬ y ∧ ¬ y ≤⟨ ⇨-eval ⟩⊥ ∎ ⟩⊥ ∎where open ≤-Reasoning posetde-morgan₂-≥ : ∀ x y → ¬ ¬ (¬ x ∨ ¬ y) ≤ ¬ (x ∧ y)de-morgan₂-≥ x y = transpose-⇨ $ ⇨-applyˡ $ transpose-⇨ $ begin(x ∧ y) ∧ (¬ x ∨ ¬ y) ≈⟨ ∧-distribˡ-∨ _ _ _ ⟩(x ∧ y) ∧ ¬ x ∨ (x ∧ y) ∧ ¬ y ≤⟨ ∨-monotonic (⇨-applyʳ (x∧y≤x _ _))(⇨-applyʳ (x∧y≤y _ _)) ⟩⊥ ∨ ⊥ ≈⟨ ∨-idempotent _ ⟩⊥ ∎where open ≤-Reasoning posetde-morgan₂ : ∀ x y → ¬ (x ∧ y) ≈ ¬ ¬ (¬ x ∨ ¬ y)de-morgan₂ x y = antisym (de-morgan₂-≤ x y) (de-morgan₂-≥ x y)weak-lem : ∀ {x} → ¬ ¬ (¬ x ∨ x) ≈ ⊤weak-lem {x} = begin¬ ¬ (¬ x ∨ x) ≈⟨ ⇨-cong (de-morgan₁ _ _) Eq.refl ⟩¬ (¬ ¬ x ∧ ¬ x) ≈⟨ ⇨-cong ⇨-app Eq.refl ⟩⊥ ∧ (x ⇨ ⊥) ⇨ ⊥ ≈⟨ ⇨-cong (∧-zeroˡ _) Eq.refl ⟩⊥ ⇨ ⊥ ≈⟨ ⇨-unit ⟩⊤ ∎where open ≈-Reasoning setoid
-------------------------------------------------------------------------- The Agda standard library---- Properties for distributive lattice------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.DistributiveLattice{c ℓ₁ ℓ₂} (L : DistributiveLattice c ℓ₁ ℓ₂) whereopen DistributiveLattice L hiding (refl)open import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Reasoning.Setoid setoidopen import Relation.Binary.Lattice.Properties.Lattice latticeopen import Relation.Binary.Lattice.Properties.MeetSemilattice meetSemilatticeopen import Relation.Binary.Lattice.Properties.JoinSemilattice joinSemilatticeopen Setoid setoid∧-distribʳ-∨ : _∧_ DistributesOverʳ _∨_∧-distribʳ-∨ x y z = begin(y ∨ z) ∧ x ≈⟨ ∧-comm _ _ ⟩x ∧ (y ∨ z) ≈⟨ ∧-distribˡ-∨ x y z ⟩x ∧ y ∨ x ∧ z ≈⟨ ∨-cong (∧-comm _ _) (∧-comm _ _) ⟩y ∧ x ∨ z ∧ x ∎∧-distrib-∨ : _∧_ DistributesOver _∨_∧-distrib-∨ = ∧-distribˡ-∨ , ∧-distribʳ-∨∨-distribˡ-∧ : _∨_ DistributesOverˡ _∧_∨-distribˡ-∧ x y z = beginx ∨ y ∧ z ≈⟨ ∨-cong (sym (∨-absorbs-∧ x y)) refl ⟩(x ∨ x ∧ y) ∨ y ∧ z ≈⟨ ∨-cong (∨-cong refl (∧-comm _ _)) refl ⟩(x ∨ y ∧ x) ∨ y ∧ z ≈⟨ ∨-assoc x (y ∧ x) (y ∧ z) ⟩x ∨ y ∧ x ∨ y ∧ z ≈⟨ ∨-cong refl (sym (∧-distribˡ-∨ y x z)) ⟩x ∨ y ∧ (x ∨ z) ≈⟨ ∨-cong (sym (∧-absorbs-∨ _ _)) refl ⟩x ∧ (x ∨ z) ∨ y ∧ (x ∨ z) ≈⟨ sym (∧-distribʳ-∨ (x ∨ z) x y) ⟩(x ∨ y) ∧ (x ∨ z) ∎∨-distribʳ-∧ : _∨_ DistributesOverʳ _∧_∨-distribʳ-∧ x y z = beginy ∧ z ∨ x ≈⟨ ∨-comm _ _ ⟩x ∨ y ∧ z ≈⟨ ∨-distribˡ-∧ _ _ _ ⟩(x ∨ y) ∧ (x ∨ z) ≈⟨ ∧-cong (∨-comm _ _) (∨-comm _ _) ⟩(y ∨ x) ∧ (z ∨ x) ∎∨-distrib-∧ : _∨_ DistributesOver _∧_∨-distrib-∧ = ∨-distribˡ-∧ , ∨-distribʳ-∧
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by bounded meet semilattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.BoundedMeetSemilattice{c ℓ₁ ℓ₂} (M : BoundedMeetSemilattice c ℓ₁ ℓ₂) whereopen BoundedMeetSemilattice Mopen import Algebra.Definitions _≈_open import Function.Base using (_∘_; flip)open import Relation.Binary.Properties.Poset posetimport Relation.Binary.Lattice.Properties.BoundedJoinSemilattice as J-- The dual construction is a bounded join semilattice.dualIsBoundedJoinSemilattice : IsBoundedJoinSemilattice _≈_ (flip _≤_) _∧_ ⊤dualIsBoundedJoinSemilattice = record{ isJoinSemilattice = record{ isPartialOrder = ≥-isPartialOrder; supremum = infimum}; minimum = maximum}dualBoundedJoinSemilattice : BoundedJoinSemilattice c ℓ₁ ℓ₂dualBoundedJoinSemilattice = record{ ⊥ = ⊤; isBoundedJoinSemilattice = dualIsBoundedJoinSemilattice}open J dualBoundedJoinSemilatticehiding (dualIsBoundedMeetSemilattice; dualBoundedMeetSemilattice) public
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by bounded lattice------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.BoundedLattice{c ℓ₁ ℓ₂} (L : BoundedLattice c ℓ₁ ℓ₂) whereopen BoundedLattice Lopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Lattice.Properties.MeetSemilattice meetSemilatticeopen import Relation.Binary.Lattice.Properties.JoinSemilattice joinSemilatticeopen Setoid setoid renaming (trans to ≈-trans)∧-zeroʳ : RightZero ⊥ _∧_∧-zeroʳ x = y≤x⇒x∧y≈y (minimum x)∧-zeroˡ : LeftZero ⊥ _∧_∧-zeroˡ x = ≈-trans (∧-comm ⊥ x) (∧-zeroʳ x)∧-zero : Zero ⊥ _∧_∧-zero = ∧-zeroˡ , ∧-zeroʳ∨-zeroʳ : RightZero ⊤ _∨_∨-zeroʳ x = x≤y⇒x∨y≈y (maximum x)∨-zeroˡ : LeftZero ⊤ _∨_∨-zeroˡ x = ≈-trans (∨-comm ⊤ x) (∨-zeroʳ x)∨-zero : Zero ⊤ _∨_∨-zero = ∨-zeroˡ , ∨-zeroʳ
-------------------------------------------------------------------------- The Agda standard library---- Properties satisfied by bounded join semilattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Latticemodule Relation.Binary.Lattice.Properties.BoundedJoinSemilattice{c ℓ₁ ℓ₂} (J : BoundedJoinSemilattice c ℓ₁ ℓ₂) whereopen BoundedJoinSemilattice Jopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)open import Function.Base using (_∘_; flip)open import Relation.Binary.Properties.Poset posetopen import Relation.Binary.Lattice.Properties.JoinSemilattice joinSemilatticeusing (∨-comm)-- Bottom is an identity of the meet operation.identityˡ : LeftIdentity ⊥ _∨_identityˡ x =let _ , x≤⊥∨x , least = supremum ⊥ xin antisym (least x (minimum x) refl) x≤⊥∨xidentityʳ : RightIdentity ⊥ _∨_identityʳ x =let x≤x∨⊥ , _ , least = supremum x ⊥in antisym (least x refl (minimum x)) x≤x∨⊥identity : Identity ⊥ _∨_identity = identityˡ , identityʳ-- The dual construction is a bounded meet semilattice.dualIsBoundedMeetSemilattice : IsBoundedMeetSemilattice _≈_ (flip _≤_) _∨_ ⊥dualIsBoundedMeetSemilattice = record{ isMeetSemilattice = record{ isPartialOrder = ≥-isPartialOrder; infimum = supremum}; maximum = minimum}dualBoundedMeetSemilattice : BoundedMeetSemilattice c ℓ₁ ℓ₂dualBoundedMeetSemilattice = record{ ⊤ = ⊥; isBoundedMeetSemilattice = dualIsBoundedMeetSemilattice}
-------------------------------------------------------------------------- The Agda standard library---- Definitions for order-theoretic lattices-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Lattice`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Lattice.Definitions whereopen import Algebra.Coreopen import Data.Product.Base using (_×_; _,_)open import Function.Base using (flip)open import Relation.Binary.Core using (Rel)open import Level using (Level)privatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Relationships between orders and operatorsSupremum : Rel A ℓ → Op₂ A → Set _Supremum _≤_ _∨_ =∀ x y → x ≤ (x ∨ y) × y ≤ (x ∨ y) × ∀ z → x ≤ z → y ≤ z → (x ∨ y) ≤ zInfimum : Rel A ℓ → Op₂ A → Set _Infimum _≤_ = Supremum (flip _≤_)Exponential : Rel A ℓ → Op₂ A → Op₂ A → Set _Exponential _≤_ _∧_ _⇨_ =∀ w x y → ((w ∧ x) ≤ y → w ≤ (x ⇨ y)) × (w ≤ (x ⇨ y) → (w ∧ x) ≤ y)
-------------------------------------------------------------------------- The Agda standard library---- Bundles for order-theoretic lattices-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Lattice`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Lattice.Bundles whereopen import Algebra.Coreopen import Level using (suc; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Poset; Setoid)open import Relation.Binary.Lattice.Structures-------------------------------------------------------------------------- Join semilatticesrecord JoinSemilattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation.isJoinSemilattice : IsJoinSemilattice _≈_ _≤_ _∨_open IsJoinSemilattice isJoinSemilattice publicposet : Poset c ℓ₁ ℓ₂poset = record { isPartialOrder = isPartialOrder }open Poset poset public using (preorder)record BoundedJoinSemilattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation.⊥ : Carrier -- The minimum.isBoundedJoinSemilattice : IsBoundedJoinSemilattice _≈_ _≤_ _∨_ ⊥open IsBoundedJoinSemilattice isBoundedJoinSemilattice publicjoinSemilattice : JoinSemilattice c ℓ₁ ℓ₂joinSemilattice = record { isJoinSemilattice = isJoinSemilattice }open JoinSemilattice joinSemilattice public using (preorder; poset)-------------------------------------------------------------------------- Meet semilatticesrecord MeetSemilattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∧_ : Op₂ Carrier -- The meet operation.isMeetSemilattice : IsMeetSemilattice _≈_ _≤_ _∧_open IsMeetSemilattice isMeetSemilattice publicposet : Poset c ℓ₁ ℓ₂poset = record { isPartialOrder = isPartialOrder }open Poset poset public using (preorder)record BoundedMeetSemilattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∧_ : Op₂ Carrier -- The join operation.⊤ : Carrier -- The maximum.isBoundedMeetSemilattice : IsBoundedMeetSemilattice _≈_ _≤_ _∧_ ⊤open IsBoundedMeetSemilattice isBoundedMeetSemilattice publicmeetSemilattice : MeetSemilattice c ℓ₁ ℓ₂meetSemilattice = record { isMeetSemilattice = isMeetSemilattice }open MeetSemilattice meetSemilattice public using (preorder; poset)-------------------------------------------------------------------------- Latticesrecord Lattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation._∧_ : Op₂ Carrier -- The meet operation.isLattice : IsLattice _≈_ _≤_ _∨_ _∧_open IsLattice isLattice publicsetoid : Setoid c ℓ₁setoid = record { isEquivalence = isEquivalence }joinSemilattice : JoinSemilattice c ℓ₁ ℓ₂joinSemilattice = record { isJoinSemilattice = isJoinSemilattice }meetSemilattice : MeetSemilattice c ℓ₁ ℓ₂meetSemilattice = record { isMeetSemilattice = isMeetSemilattice }open JoinSemilattice joinSemilattice public using (poset; preorder)record DistributiveLattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation._∧_ : Op₂ Carrier -- The meet operation.isDistributiveLattice : IsDistributiveLattice _≈_ _≤_ _∨_ _∧_open IsDistributiveLattice isDistributiveLattice using (∧-distribˡ-∨) publicopen IsDistributiveLattice isDistributiveLattice using (isLattice)lattice : Lattice c ℓ₁ ℓ₂lattice = record { isLattice = isLattice }open Lattice lattice hiding (Carrier; _≈_; _≤_; _∨_; _∧_) publicrecord BoundedLattice c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation._∧_ : Op₂ Carrier -- The meet operation.⊤ : Carrier -- The maximum.⊥ : Carrier -- The minimum.isBoundedLattice : IsBoundedLattice _≈_ _≤_ _∨_ _∧_ ⊤ ⊥open IsBoundedLattice isBoundedLattice publicboundedJoinSemilattice : BoundedJoinSemilattice c ℓ₁ ℓ₂boundedJoinSemilattice = record{ isBoundedJoinSemilattice = isBoundedJoinSemilattice }boundedMeetSemilattice : BoundedMeetSemilattice c ℓ₁ ℓ₂boundedMeetSemilattice = record{ isBoundedMeetSemilattice = isBoundedMeetSemilattice }lattice : Lattice c ℓ₁ ℓ₂lattice = record { isLattice = isLattice }open Lattice lattice publicusing (joinSemilattice; meetSemilattice; poset; preorder; setoid)-------------------------------------------------------------------------- Heyting algebras (a bounded lattice with exponential operator)record HeytingAlgebra c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 5 _⇨_infixr 6 _∨_infixr 7 _∧_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation._∧_ : Op₂ Carrier -- The meet operation._⇨_ : Op₂ Carrier -- The exponential operation.⊤ : Carrier -- The maximum.⊥ : Carrier -- The minimum.isHeytingAlgebra : IsHeytingAlgebra _≈_ _≤_ _∨_ _∧_ _⇨_ ⊤ ⊥boundedLattice : BoundedLattice c ℓ₁ ℓ₂boundedLattice = record{ isBoundedLattice = IsHeytingAlgebra.isBoundedLattice isHeytingAlgebra }open IsHeytingAlgebra isHeytingAlgebrausing (exponential; transpose-⇨; transpose-∧) publicopen BoundedLattice boundedLatticehiding (Carrier; _≈_; _≤_; _∨_; _∧_; ⊤; ⊥) public-------------------------------------------------------------------------- Boolean algebras (a specialized Heyting algebra)record BooleanAlgebra c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_infixr 6 _∨_infixr 7 _∧_infix 8 ¬_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≤_ : Rel Carrier ℓ₂ -- The partial order._∨_ : Op₂ Carrier -- The join operation._∧_ : Op₂ Carrier -- The meet operation.¬_ : Op₁ Carrier -- The negation operation.⊤ : Carrier -- The maximum.⊥ : Carrier -- The minimum.isBooleanAlgebra : IsBooleanAlgebra _≈_ _≤_ _∨_ _∧_ ¬_ ⊤ ⊥open IsBooleanAlgebra isBooleanAlgebra using (isHeytingAlgebra)heytingAlgebra : HeytingAlgebra c ℓ₁ ℓ₂heytingAlgebra = record { isHeytingAlgebra = isHeytingAlgebra }open HeytingAlgebra heytingAlgebra publichiding (Carrier; _≈_; _≤_; _∨_; _∧_; ⊤; ⊥)
-------------------------------------------------------------------------- The Agda standard library---- Homogeneously-indexed binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Homogeneous where-------------------------------------------------------------------------- Publicly export core definitionsopen import Relation.Binary.Indexed.Homogeneous.Core publicopen import Relation.Binary.Indexed.Homogeneous.Definitions publicopen import Relation.Binary.Indexed.Homogeneous.Structures publicopen import Relation.Binary.Indexed.Homogeneous.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Homogeneously-indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Homogeneous`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Indexed.Homogeneous.Coremodule Relation.Binary.Indexed.Homogeneous.Structures{i a ℓ} {I : Set i}(A : I → Set a) -- The underlying indexed sets(_≈ᵢ_ : IRel A ℓ) -- The underlying indexed equality relationwhereopen import Data.Product.Base using (_,_)open import Function.Base using (_⟨_⟩_)open import Level using (Level; _⊔_; suc)open import Relation.Binary.Core using (_⇒_)import Relation.Binary.Definitions as Bimport Relation.Binary.Structures as Bopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Indexed.Homogeneous.Definitions-------------------------------------------------------------------------- Equivalences-- Indexed structures are laid out in a similar manner as to those-- in Relation.Binary. The main difference is each structure also-- contains proofs for the lifted version of the relation.record IsIndexedEquivalence : Set (i ⊔ a ⊔ ℓ) wherefieldreflᵢ : Reflexive A _≈ᵢ_symᵢ : Symmetric A _≈ᵢ_transᵢ : Transitive A _≈ᵢ_reflexiveᵢ : ∀ {i} → _≡_ ⟨ _⇒_ ⟩ _≈ᵢ_ {i}reflexiveᵢ ≡.refl = reflᵢ-- Lift propertiesreflexive : _≡_ ⇒ (Lift A _≈ᵢ_)reflexive ≡.refl i = reflᵢrefl : B.Reflexive (Lift A _≈ᵢ_)refl i = reflᵢsym : B.Symmetric (Lift A _≈ᵢ_)sym x≈y i = symᵢ (x≈y i)trans : B.Transitive (Lift A _≈ᵢ_)trans x≈y y≈z i = transᵢ (x≈y i) (y≈z i)isEquivalence : B.IsEquivalence (Lift A _≈ᵢ_)isEquivalence = record{ refl = refl; sym = sym; trans = trans}record IsIndexedDecEquivalence : Set (i ⊔ a ⊔ ℓ) whereinfix 4 _≟ᵢ_field_≟ᵢ_ : Decidable A _≈ᵢ_isEquivalenceᵢ : IsIndexedEquivalenceopen IsIndexedEquivalence isEquivalenceᵢ public-------------------------------------------------------------------------- Preordersrecord IsIndexedPreorder {ℓ₂} (_∼ᵢ_ : IRel A ℓ₂): Set (i ⊔ a ⊔ ℓ ⊔ ℓ₂) wherefieldisEquivalenceᵢ : IsIndexedEquivalencereflexiveᵢ : _≈ᵢ_ ⇒[ A ] _∼ᵢ_transᵢ : Transitive A _∼ᵢ_module Eq = IsIndexedEquivalence isEquivalenceᵢreflᵢ : Reflexive A _∼ᵢ_reflᵢ = reflexiveᵢ Eq.reflᵢ∼ᵢ-respˡ-≈ᵢ : Respectsˡ A _∼ᵢ_ _≈ᵢ_∼ᵢ-respˡ-≈ᵢ x≈y x∼z = transᵢ (reflexiveᵢ (Eq.symᵢ x≈y)) x∼z∼ᵢ-respʳ-≈ᵢ : Respectsʳ A _∼ᵢ_ _≈ᵢ_∼ᵢ-respʳ-≈ᵢ x≈y z∼x = transᵢ z∼x (reflexiveᵢ x≈y)∼ᵢ-resp-≈ᵢ : Respects₂ A _∼ᵢ_ _≈ᵢ_∼ᵢ-resp-≈ᵢ = ∼ᵢ-respʳ-≈ᵢ , ∼ᵢ-respˡ-≈ᵢ-- Lifted propertiesreflexive : Lift A _≈ᵢ_ ⇒ Lift A _∼ᵢ_reflexive x≈y i = reflexiveᵢ (x≈y i)refl : B.Reflexive (Lift A _∼ᵢ_)refl i = reflᵢtrans : B.Transitive (Lift A _∼ᵢ_)trans x≈y y≈z i = transᵢ (x≈y i) (y≈z i)∼-respˡ-≈ : (Lift A _∼ᵢ_) B.Respectsˡ (Lift A _≈ᵢ_)∼-respˡ-≈ x≈y x∼z i = ∼ᵢ-respˡ-≈ᵢ (x≈y i) (x∼z i)∼-respʳ-≈ : (Lift A _∼ᵢ_) B.Respectsʳ (Lift A _≈ᵢ_)∼-respʳ-≈ x≈y z∼x i = ∼ᵢ-respʳ-≈ᵢ (x≈y i) (z∼x i)∼-resp-≈ : (Lift A _∼ᵢ_) B.Respects₂ (Lift A _≈ᵢ_)∼-resp-≈ = ∼-respʳ-≈ , ∼-respˡ-≈isPreorder : B.IsPreorder (Lift A _≈ᵢ_) (Lift A _∼ᵢ_)isPreorder = record{ isEquivalence = Eq.isEquivalence; reflexive = reflexive; trans = trans}-------------------------------------------------------------------------- Partial ordersrecord IsIndexedPartialOrder {ℓ₂} (_≤ᵢ_ : IRel A ℓ₂): Set (i ⊔ a ⊔ ℓ ⊔ ℓ₂) wherefieldisPreorderᵢ : IsIndexedPreorder _≤ᵢ_antisymᵢ : Antisymmetric A _≈ᵢ_ _≤ᵢ_open IsIndexedPreorder isPreorderᵢ publicrenaming( ∼ᵢ-respˡ-≈ᵢ to ≤ᵢ-respˡ-≈ᵢ; ∼ᵢ-respʳ-≈ᵢ to ≤ᵢ-respʳ-≈ᵢ; ∼ᵢ-resp-≈ᵢ to ≤ᵢ-resp-≈ᵢ; ∼-respˡ-≈ to ≤-respˡ-≈; ∼-respʳ-≈ to ≤-respʳ-≈; ∼-resp-≈ to ≤-resp-≈)antisym : B.Antisymmetric (Lift A _≈ᵢ_) (Lift A _≤ᵢ_)antisym x≤y y≤x i = antisymᵢ (x≤y i) (y≤x i)isPartialOrder : B.IsPartialOrder (Lift A _≈ᵢ_) (Lift A _≤ᵢ_)isPartialOrder = record{ isPreorder = isPreorder; antisym = antisym}
-------------------------------------------------------------------------- The Agda standard library---- Homogeneously-indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Homogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Homogeneous.Definitions whereopen import Data.Product.Base using (_×_)open import Level using (Level)open import Relation.Binary.Core using (_⇒_)import Relation.Binary.Definitions as Bopen import Relation.Unary.Indexed using (IPred)open import Relation.Binary.Indexed.Homogeneous.Coreprivatevariablei a ℓ ℓ₁ ℓ₂ : LevelI : Set i-------------------------------------------------------------------------- Definitionsmodule _ (A : I → Set a) wheresyntax Implies A _∼₁_ _∼₂_ = _∼₁_ ⇒[ A ] _∼₂_Implies : IRel A ℓ₁ → IRel A ℓ₂ → Set _Implies _∼₁_ _∼₂_ = ∀ {i} → _∼₁_ ⇒ (_∼₂_ {i})Reflexive : IRel A ℓ → Set _Reflexive _∼_ = ∀ {i} → B.Reflexive (_∼_ {i})Symmetric : IRel A ℓ → Set _Symmetric _∼_ = ∀ {i} → B.Symmetric (_∼_ {i})Transitive : IRel A ℓ → Set _Transitive _∼_ = ∀ {i} → B.Transitive (_∼_ {i})Antisymmetric : IRel A ℓ₁ → IRel A ℓ₂ → Set _Antisymmetric _≈_ _∼_ = ∀ {i} → B.Antisymmetric _≈_ (_∼_ {i})Decidable : IRel A ℓ → Set _Decidable _∼_ = ∀ {i} → B.Decidable (_∼_ {i})Respects : IPred A ℓ₁ → IRel A ℓ₂ → Set _Respects P _∼_ = ∀ {i} {x y : A i} → x ∼ y → P x → P yRespectsˡ : IRel A ℓ₁ → IRel A ℓ₂ → Set _Respectsˡ P _∼_ = ∀ {i} {x y z : A i} → x ∼ y → P x z → P y zRespectsʳ : IRel A ℓ₁ → IRel A ℓ₂ → Set _Respectsʳ P _∼_ = ∀ {i} {x y z : A i} → x ∼ y → P z x → P z yRespects₂ : IRel A ℓ₁ → IRel A ℓ₂ → Set _Respects₂ P _∼_ = (Respectsʳ P _∼_) × (Respectsˡ P _∼_)
-------------------------------------------------------------------------- The Agda standard library---- Homogeneously-indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Homogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Homogeneous.Core whereopen import Level using (Level; _⊔_)open import Data.Product.Base using (_×_)open import Relation.Binary.Core as B using (REL; Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)import Relation.Binary.Indexed.Heterogeneous as Iopen import Relation.Unary.Indexed using (IPred)privatevariablea b c ℓ : LevelI : Set c-------------------------------------------------------------------------- Homegeneously indexed binary relations-- Heterogeneous typesIREL : (I → Set a) → (I → Set b) → (ℓ : Level) → Set _IREL A B ℓ = ∀ {i} → REL (A i) (B i) ℓ-- Homogeneous typesIRel : (I → Set a) → (ℓ : Level) → Set _IRel A = IREL A A-------------------------------------------------------------------------- Lifting to non-indexed binary relations-- Ideally this should be in: `Construct.Lift` but we want this relation-- to be exported by the various structures & bundles.Lift : (A : I → Set a) → IRel A ℓ → Rel (∀ i → A i) _Lift _ _∼_ x y = ∀ i → x i ∼ y i-------------------------------------------------------------------------- Conversion between homogeneous and heterogeneously indexed relationsmodule _ {i a b} {I : Set i} {A : I → Set a} {B : I → Set b} whereOverPath : ∀ {ℓ} → IREL A B ℓ → ∀ {i j} → i ≡ j → REL (A i) (B j) ℓOverPath _∼_ refl = _∼_toHetIndexed : ∀ {ℓ} → IREL A B ℓ → I.IREL A B (i ⊔ ℓ)toHetIndexed _∼_ {i} {j} x y = (p : i ≡ j) → OverPath _∼_ p x yfromHetIndexed : ∀ {ℓ} → I.IREL A B ℓ → IREL A B ℓfromHetIndexed _∼_ = _∼_
-------------------------------------------------------------------------- The Agda standard library---- Instantiating homogeneously indexed bundles at a particular index------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelopen import Relation.Binary.Bundles using (Setoid; DecSetoid; Preorder)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder)open import Relation.Binary.Indexed.Homogeneousmodule Relation.Binary.Indexed.Homogeneous.Construct.At whereprivatevariablea i ℓ ℓ₁ ℓ₂ : LevelI : Set iAᵢ : I → Set a-------------------------------------------------------------------------- StructuresisEquivalence : ∀ {_≈_ : IRel Aᵢ ℓ} → IsIndexedEquivalence Aᵢ _≈_ →(index : I) → IsEquivalence (_≈_ {index})isEquivalence isEq index = record{ refl = reflᵢ; sym = symᵢ; trans = transᵢ} where open IsIndexedEquivalence isEqisDecEquivalence : ∀ {_≈_ : IRel Aᵢ ℓ} → IsIndexedDecEquivalence Aᵢ _≈_ →(index : I) → IsDecEquivalence (_≈_ {index})isDecEquivalence isEq index = record{ isEquivalence = isEquivalence E.isEquivalenceᵢ index; _≟_ = E._≟ᵢ_} where module E = IsIndexedDecEquivalence isEqisPreorder : ∀ {_≈_ : IRel Aᵢ ℓ₁} {_∼_ : IRel Aᵢ ℓ₂} →IsIndexedPreorder Aᵢ _≈_ _∼_ →(index : I) → IsPreorder (_≈_ {index}) _∼_isPreorder isPreorder index = record{ isEquivalence = isEquivalence O.isEquivalenceᵢ index; reflexive = O.reflexiveᵢ; trans = O.transᵢ} where module O = IsIndexedPreorder isPreorder-------------------------------------------------------------------------- Bundlessetoid : IndexedSetoid I a ℓ → I → Setoid a ℓsetoid S index = record{ isEquivalence = isEquivalence S.isEquivalenceᵢ index} where module S = IndexedSetoid SdecSetoid : IndexedDecSetoid I a ℓ → I → DecSetoid a ℓdecSetoid S index = record{ isDecEquivalence = isDecEquivalence DS.isDecEquivalenceᵢ index} where module DS = IndexedDecSetoid Spreorder : IndexedPreorder I a ℓ₁ ℓ₂ → I → Preorder a ℓ₁ ℓ₂preorder O index = record{ isPreorder = isPreorder O.isPreorderᵢ index} where module O = IndexedPreorder O-------------------------------------------------------------------------- Some useful shorthand infix notationinfixr -1 _atₛ__atₛ_ : ∀ {ℓ} → IndexedSetoid I a ℓ → I → Setoid a ℓ_atₛ_ = setoid
-------------------------------------------------------------------------- The Agda standard library---- Homogeneously-indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Homogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Homogeneous.Bundles whereopen import Level using (suc; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles as Bopen import Relation.Nullary.Negation using (¬_)open import Relation.Binary.Indexed.Homogeneous.Coreopen import Relation.Binary.Indexed.Homogeneous.Structures-- Indexed structures are laid out in a similar manner as to those-- in Relation.Binary. The main difference is each structure also-- contains proofs for the lifted version of the relation.-------------------------------------------------------------------------- Equivalencesrecord IndexedSetoid {i} (I : Set i) c ℓ : Set (suc (i ⊔ c ⊔ ℓ)) whereinfix 4 _≈ᵢ_ _≈_fieldCarrierᵢ : I → Set c_≈ᵢ_ : IRel Carrierᵢ ℓisEquivalenceᵢ : IsIndexedEquivalence Carrierᵢ _≈ᵢ_open IsIndexedEquivalence isEquivalenceᵢ publicCarrier : Set _Carrier = ∀ i → Carrierᵢ iinfix 4 _≉__≈_ : Rel Carrier __≈_ = Lift Carrierᵢ _≈ᵢ__≉_ : Rel Carrier _x ≉ y = ¬ (x ≈ y)setoid : B.Setoid _ _setoid = record{ isEquivalence = isEquivalence}record IndexedDecSetoid {i} (I : Set i) c ℓ : Set (suc (i ⊔ c ⊔ ℓ)) whereinfix 4 _≈ᵢ_fieldCarrierᵢ : I → Set c_≈ᵢ_ : IRel Carrierᵢ ℓisDecEquivalenceᵢ : IsIndexedDecEquivalence Carrierᵢ _≈ᵢ_open IsIndexedDecEquivalence isDecEquivalenceᵢ publicindexedSetoid : IndexedSetoid I c ℓindexedSetoid = record{ isEquivalenceᵢ = isEquivalenceᵢ}open IndexedSetoid indexedSetoid publicusing (Carrier; _≈_; _≉_; setoid)-------------------------------------------------------------------------- Preordersrecord IndexedPreorder {i} (I : Set i) c ℓ₁ ℓ₂ :Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈ᵢ_ _∼ᵢ_ _≈_ _∼_fieldCarrierᵢ : I → Set c_≈ᵢ_ : IRel Carrierᵢ ℓ₁_∼ᵢ_ : IRel Carrierᵢ ℓ₂isPreorderᵢ : IsIndexedPreorder Carrierᵢ _≈ᵢ_ _∼ᵢ_open IsIndexedPreorder isPreorderᵢ publicCarrier : Set _Carrier = ∀ i → Carrierᵢ i_≈_ : Rel Carrier _x ≈ y = ∀ i → x i ≈ᵢ y i_∼_ : Rel Carrier _x ∼ y = ∀ i → x i ∼ᵢ y ipreorder : B.Preorder _ _ _preorder = record{ isPreorder = isPreorder}-------------------------------------------------------------------------- Partial ordersrecord IndexedPoset {i} (I : Set i) c ℓ₁ ℓ₂ :Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈ᵢ_ _≤ᵢ_fieldCarrierᵢ : I → Set c_≈ᵢ_ : IRel Carrierᵢ ℓ₁_≤ᵢ_ : IRel Carrierᵢ ℓ₂isPartialOrderᵢ : IsIndexedPartialOrder Carrierᵢ _≈ᵢ_ _≤ᵢ_open IsIndexedPartialOrder isPartialOrderᵢ publicpreorderᵢ : IndexedPreorder I c ℓ₁ ℓ₂preorderᵢ = record{ isPreorderᵢ = isPreorderᵢ}open IndexedPreorder preorderᵢ publicusing (Carrier; _≈_; preorder) renaming (_∼_ to _≤_)poset : B.Poset _ _ _poset = record{ isPartialOrder = isPartialOrder}
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneously-indexed binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous where-------------------------------------------------------------------------- Publicly export core definitionsopen import Relation.Binary.Indexed.Heterogeneous.Core publicopen import Relation.Binary.Indexed.Heterogeneous.Definitions publicopen import Relation.Binary.Indexed.Heterogeneous.Structures publicopen import Relation.Binary.Indexed.Heterogeneous.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Heterogeneous`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Indexed.Heterogeneous.Coremodule Relation.Binary.Indexed.Heterogeneous.Structures{i a ℓ} {I : Set i} (A : I → Set a) (_≈_ : IRel A ℓ)whereopen import Function.Baseopen import Level using (suc; _⊔_)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Indexed.Heterogeneous.Definitions-------------------------------------------------------------------------- Equivalencesrecord IsIndexedEquivalence : Set (i ⊔ a ⊔ ℓ) wherefieldrefl : Reflexive A _≈_sym : Symmetric A _≈_trans : Transitive A _≈_reflexive : ∀ {i} → _≡_ ⟨ _⇒_ ⟩ _≈_ {i}reflexive ≡.refl = reflrecord IsIndexedPreorder {ℓ₂} (_≲_ : IRel A ℓ₂) : Set (i ⊔ a ⊔ ℓ ⊔ ℓ₂) wherefieldisEquivalence : IsIndexedEquivalencereflexive : ∀ {i j} → (_≈_ {i} {j}) ⟨ _⇒_ ⟩ _≲_trans : Transitive A _≲_module Eq = IsIndexedEquivalence isEquivalencerefl : Reflexive A _≲_refl = reflexive Eq.refl
-------------------------------------------------------------------------- The Agda standard library---- Indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Heterogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous.Definitions whereopen import Levelimport Relation.Binary.Definitions as Bopen import Relation.Binary.Indexed.Heterogeneous.Coreprivatevariablei a ℓ : LevelI : Set i-------------------------------------------------------------------------- Simple properties of indexed binary relationsReflexive : (A : I → Set a) → IRel A ℓ → Set _Reflexive _ _∼_ = ∀ {i} → B.Reflexive (_∼_ {i})Symmetric : (A : I → Set a) → IRel A ℓ → Set _Symmetric _ _∼_ = ∀ {i j} → B.Sym (_∼_ {i} {j}) _∼_Transitive : (A : I → Set a) → IRel A ℓ → Set _Transitive _ _∼_ = ∀ {i j k} → B.Trans _∼_ (_∼_ {j}) (_∼_ {i} {k})
-------------------------------------------------------------------------- The Agda standard library---- Indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Heterogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous.Core whereopen import Levelimport Relation.Binary.Core as B-------------------------------------------------------------------------- Indexed binary relations-- Heterogeneous typesIREL : ∀ {i₁ i₂ a₁ a₂} {I₁ : Set i₁} {I₂ : Set i₂} →(I₁ → Set a₁) → (I₂ → Set a₂) → (ℓ : Level) → Set _IREL A₁ A₂ ℓ = ∀ {i₁ i₂} → A₁ i₁ → A₂ i₂ → Set ℓ-- Homogeneous typesIRel : ∀ {i a} {I : Set i} → (I → Set a) → (ℓ : Level) → Set _IRel A ℓ = IREL A A ℓ-------------------------------------------------------------------------- Generalised implication.infixr 4 _=[_]⇒__=[_]⇒_ : ∀ {a b ℓ₁ ℓ₂} {A : Set a} {B : A → Set b} →B.Rel A ℓ₁ → ((x : A) → B x) → IRel B ℓ₂ → Set _P =[ f ]⇒ Q = ∀ {i j} → P i j → Q (f i) (f j)
-------------------------------------------------------------------------- The Agda standard library---- Creates trivially indexed records from their non-indexed counterpart.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous.Construct.Trivial{i} {I : Set i} whereopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsEquivalence; IsPreorder)open import Relation.Binary.Indexed.Heterogeneous-------------------------------------------------------------------------- Structuresmodule _ {a} {A : Set a} whereprivateAᵢ : I → Set aAᵢ i = AisIndexedEquivalence : ∀ {ℓ} {_≈_ : Rel A ℓ} → IsEquivalence _≈_ →IsIndexedEquivalence Aᵢ _≈_isIndexedEquivalence isEq = record{ refl = refl; sym = sym; trans = trans}where open IsEquivalence isEqisIndexedPreorder : ∀ {ℓ₁ ℓ₂} {_≈_ : Rel A ℓ₁} {_∼_ : Rel A ℓ₂} →IsPreorder _≈_ _∼_ →IsIndexedPreorder Aᵢ _≈_ _∼_isIndexedPreorder isPreorder = record{ isEquivalence = isIndexedEquivalence isEquivalence; reflexive = reflexive; trans = trans}where open IsPreorder isPreorder-------------------------------------------------------------------------- BundlesindexedSetoid : ∀ {a ℓ} → Setoid a ℓ → IndexedSetoid I a ℓindexedSetoid S = record{ isEquivalence = isIndexedEquivalence isEquivalence}where open Setoid SindexedPreorder : ∀ {a ℓ₁ ℓ₂} → Preorder a ℓ₁ ℓ₂ →IndexedPreorder I a ℓ₁ ℓ₂indexedPreorder O = record{ isPreorder = isIndexedPreorder isPreorder}where open Preorder O
-------------------------------------------------------------------------- The Agda standard library---- Instantiates indexed binary structures at an index to the equivalent-- non-indexed structures.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous.Construct.At whereopen import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsEquivalence; IsPreorder)open import Relation.Binary.Indexed.Heterogeneous-------------------------------------------------------------------------- Structuresmodule _ {a i} {I : Set i} {A : I → Set a} whereisEquivalence : ∀ {ℓ} {_≈_ : IRel A ℓ} → IsIndexedEquivalence A _≈_ →(index : I) → IsEquivalence (_≈_ {index})isEquivalence isEq index = record{ refl = refl; sym = sym; trans = trans}where open IsIndexedEquivalence isEqisPreorder : ∀ {ℓ₁ ℓ₂} {_≈_ : IRel A ℓ₁} {_≲_ : IRel A ℓ₂} →IsIndexedPreorder A _≈_ _≲_ →(index : I) → IsPreorder (_≈_ {index}) _≲_isPreorder isPreorder index = record{ isEquivalence = isEquivalence O.isEquivalence index; reflexive = O.reflexive; trans = O.trans}where module O = IsIndexedPreorder isPreorder-------------------------------------------------------------------------- Bundlesmodule _ {a i} {I : Set i} wheresetoid : ∀ {ℓ} → IndexedSetoid I a ℓ → I → Setoid a ℓsetoid S index = record{ Carrier = S.Carrier index; _≈_ = S._≈_; isEquivalence = isEquivalence S.isEquivalence index}where module S = IndexedSetoid Spreorder : ∀ {ℓ₁ ℓ₂} → IndexedPreorder I a ℓ₁ ℓ₂ → I → Preorder a ℓ₁ ℓ₂preorder O index = record{ Carrier = O.Carrier index; _≈_ = O._≈_; _≲_ = O._≲_; isPreorder = isPreorder O.isPreorder index}where module O = IndexedPreorder O-------------------------------------------------------------------------- Some useful shorthand infix notationmodule _ {a i} {I : Set i} whereinfixr -1 _atₛ__atₛ_ : ∀ {ℓ} → IndexedSetoid I a ℓ → I → Setoid a ℓ_atₛ_ = setoid
-------------------------------------------------------------------------- The Agda standard library---- Indexed binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via-- `Relation.Binary.Indexed.Heterogeneous`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Indexed.Heterogeneous.Bundles whereopen import Level using (suc; _⊔_)open import Relation.Binary.Indexed.Heterogeneous.Coreopen import Relation.Binary.Indexed.Heterogeneous.Structures-------------------------------------------------------------------------- Definitionsrecord IndexedSetoid {i} (I : Set i) c ℓ : Set (suc (i ⊔ c ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : I → Set c_≈_ : IRel Carrier ℓisEquivalence : IsIndexedEquivalence Carrier _≈_open IsIndexedEquivalence isEquivalence publicrecord IndexedPreorder {i} (I : Set i) c ℓ₁ ℓ₂ :Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≲_fieldCarrier : I → Set c_≈_ : IRel Carrier ℓ₁ -- The underlying equality._≲_ : IRel Carrier ℓ₂ -- The relation.isPreorder : IsIndexedPreorder Carrier _≈_ _≲_open IsIndexedPreorder isPreorder publicinfix 4 _∼__∼_ = _≲_-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0{-# WARNING_ON_USAGE IndexedPreorder._∼_"Warning: IndexedPreorder._∼_ was deprecated in v2.0. Please use IndexedPreorder._≲_ instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Relation.Binary.HeterogeneousEquality whereimport Axiom.Extensionality.Heterogeneous as Extopen import Data.Unit.NonEtaopen import Data.Product.Base using (_,_)open import Function.Baseopen import Function.Bundles using (Inverse)open import Levelopen import Relation.Nullary hiding (Irrelevant)open import Relation.Unary using (Pred)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Bundles using (Setoid; DecSetoid; Preorder)open import Relation.Binary.Structures using (IsEquivalence; IsPreorder)open import Relation.Binary.Definitions using (Substitutive; Irrelevant; Decidable; _Respects₂_; Trans; Reflexive)open import Relation.Binary.Consequencesopen import Relation.Binary.Indexed.Heterogeneoususing (IndexedSetoid)open import Relation.Binary.Indexed.Heterogeneous.Construct.Atusing (_atₛ_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; refl)open import Relation.Binary.Reasoning.Syntaximport Relation.Binary.PropositionalEquality.Properties as ≡import Relation.Binary.HeterogeneousEquality.Core as Coreprivatevariablea b c p r ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Heterogeneous equalityinfix 4 _≇_open Core public using (_≅_; refl)-- Nonequality._≇_ : ∀ {A : Set a} → A → {B : Set b} → B → Set ax ≇ y = ¬ x ≅ y-------------------------------------------------------------------------- Conversionopen Core public using (≅-to-≡; ≡-to-≅)≅-to-type-≡ : ∀ {A B : Set a} {x : A} {y : B} → x ≅ y → A ≡ B≅-to-type-≡ refl = refl≅-to-subst-≡ : ∀ {A B : Set a} {x : A} {y : B} → (p : x ≅ y) →≡.subst (λ x → x) (≅-to-type-≡ p) x ≡ y≅-to-subst-≡ refl = refl-------------------------------------------------------------------------- Some propertiesreflexive : _⇒_ {A = A} _≡_ (λ x y → x ≅ y)reflexive refl = reflsym : ∀ {x : A} {y : B} → x ≅ y → y ≅ xsym refl = refltrans : ∀ {x : A} {y : B} {z : C} → x ≅ y → y ≅ z → x ≅ ztrans refl eq = eqsubst : Substitutive {A = A} (λ x y → x ≅ y) ℓsubst P refl p = psubst₂ : ∀ (_∼_ : REL A B r) {x y u v} → x ≅ y → u ≅ v → x ∼ u → y ∼ vsubst₂ _∼_ refl refl z = zsubst-removable : ∀ (P : Pred A p) {x y} (eq : x ≅ y) (z : P x) →subst P eq z ≅ zsubst-removable P refl z = reflsubst₂-removable : ∀ (_∼_ : REL A B r) {x y u v} (eq₁ : x ≅ y) (eq₂ : u ≅ v) (z : x ∼ u) →subst₂ _∼_ eq₁ eq₂ z ≅ zsubst₂-removable _∼_ refl refl z = refl≡-subst-removable : ∀ (P : Pred A p) {x y} (eq : x ≡ y) (z : P x) →≡.subst P eq z ≅ z≡-subst-removable P refl z = reflcong : ∀ {A : Set a} {B : A → Set b} {x y}(f : (x : A) → B x) → x ≅ y → f x ≅ f ycong f refl = reflcong-app : ∀ {A : Set a} {B : A → Set b} {f g : (x : A) → B x} →f ≅ g → (x : A) → f x ≅ g xcong-app refl x = reflcong₂ : ∀ {A : Set a} {B : A → Set b} {C : ∀ x → B x → Set c} {x y u v}(f : (x : A) (y : B x) → C x y) → x ≅ y → u ≅ v → f x u ≅ f y vcong₂ f refl refl = reflresp₂ : ∀ (∼ : Rel A ℓ) → ∼ Respects₂ (λ x y → x ≅ y)resp₂ _∼_ = subst⇒resp₂ _∼_ substmodule _ {I : Set ℓ} (A : I → Set a) {B : {k : I} → A k → Set b} whereicong : {i j : I} {x : A i} {y : A j} →i ≡ j →(f : {k : I} → (z : A k) → B z) →x ≅ y →f x ≅ f yicong refl _ refl = reflicong₂ : {C : {k : I} → (a : A k) → B a → Set c}{i j : I} {x : A i} {y : A j} {u : B x} {v : B y} →i ≡ j →(f : {k : I} → (z : A k) → (w : B z) → C z w) →x ≅ y → u ≅ v →f x u ≅ f y vicong₂ refl _ refl refl = reflicong-subst-removable : {i j : I} (eq : i ≅ j)(f : {k : I} → (z : A k) → B z)(x : A i) →f (subst A eq x) ≅ f xicong-subst-removable refl _ _ = reflicong-≡-subst-removable : {i j : I} (eq : i ≡ j)(f : {k : I} → (z : A k) → B z)(x : A i) →f (≡.subst A eq x) ≅ f xicong-≡-subst-removable refl _ _ = refl--------------------------------------------------------------------------Proof irrelevance≅-irrelevant : {A B : Set ℓ} → Irrelevant ((A → B → Set ℓ) ∋ λ a → a ≅_)≅-irrelevant refl refl = reflmodule _ {A C : Set a} {B D : Set ℓ}{w : A} {x : B} {y : C} {z : D} where≅-heterogeneous-irrelevant : (p : w ≅ x) (q : y ≅ z) → x ≅ y → p ≅ q≅-heterogeneous-irrelevant refl refl refl = refl≅-heterogeneous-irrelevantˡ : (p : w ≅ x) (q : y ≅ z) → w ≅ y → p ≅ q≅-heterogeneous-irrelevantˡ refl refl refl = refl≅-heterogeneous-irrelevantʳ : (p : w ≅ x) (q : y ≅ z) → x ≅ z → p ≅ q≅-heterogeneous-irrelevantʳ refl refl refl = refl-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence {A = A} (λ x y → x ≅ y)isEquivalence = record{ refl = refl; sym = sym; trans = trans}setoid : Set ℓ → Setoid ℓ ℓsetoid A = record{ Carrier = A; _≈_ = λ x y → x ≅ y; isEquivalence = isEquivalence}indexedSetoid : (A → Set b) → IndexedSetoid A _ _indexedSetoid B = record{ Carrier = B; _≈_ = λ x y → x ≅ y; isEquivalence = record{ refl = refl; sym = sym; trans = trans}}≡↔≅ : ∀ {A : Set a} (B : A → Set b) {x : A} →Inverse (≡.setoid (B x)) ((indexedSetoid B) atₛ x)≡↔≅ B = record{ to = id; to-cong = ≡-to-≅; from = id; from-cong = ≅-to-≡; inverse = (λ { ≡.refl → refl }) , λ { refl → ≡.refl }}decSetoid : Decidable {A = A} {B = A} (λ x y → x ≅ y) →DecSetoid _ _decSetoid dec = record{ _≈_ = λ x y → x ≅ y; isDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = dec}}isPreorder : IsPreorder {A = A} (λ x y → x ≅ y) (λ x y → x ≅ y)isPreorder = record{ isEquivalence = isEquivalence; reflexive = id; trans = trans}isPreorder-≡ : IsPreorder {A = A} _≡_ (λ x y → x ≅ y)isPreorder-≡ = record{ isEquivalence = ≡.isEquivalence; reflexive = reflexive; trans = trans}preorder : Set ℓ → Preorder ℓ ℓ ℓpreorder A = record{ Carrier = A; _≈_ = _≡_; _≲_ = λ x y → x ≅ y; isPreorder = isPreorder-≡}-------------------------------------------------------------------------- Convenient syntax for equational reasoningmodule ≅-Reasoning where-- The code in `Relation.Binary.Reasoning.Setoid` cannot handle-- heterogeneous equalities, hence the code duplication here.infix 4 _IsRelatedTo_data _IsRelatedTo_ {A : Set ℓ} {B : Set ℓ} (x : A) (y : B) : Set ℓ whererelTo : (x≅y : x ≅ y) → x IsRelatedTo ystart : ∀ {x : A} {y : B} → x IsRelatedTo y → x ≅ ystart (relTo x≅y) = x≅y≡-go : ∀ {A : Set a} → Trans {A = A} {C = A} _≡_ _IsRelatedTo_ _IsRelatedTo_≡-go x≡y (relTo y≅z) = relTo (trans (reflexive x≡y) y≅z)-- Combinators with one heterogeneous relationmodule _ {A : Set ℓ} {B : Set ℓ} whereopen begin-syntax (_IsRelatedTo_ {A = A} {B}) start public-- Combinators with homogeneous relationsmodule _ {A : Set ℓ} whereopen ≡-syntax (_IsRelatedTo_ {A = A}) ≡-go publicopen end-syntax (_IsRelatedTo_ {A = A}) (relTo refl) public-- Can't create syntax in the standard `Syntax` module for-- heterogeneous steps because it would force that module to use-- the `--with-k` option.infixr 2 _≅⟨_⟩_ _≅⟨_⟨__≅⟨_⟩_ : ∀ (x : A) {y : B} {z : C} →x ≅ y → y IsRelatedTo z → x IsRelatedTo z_ ≅⟨ x≅y ⟩ relTo y≅z = relTo (trans x≅y y≅z)_≅⟨_⟨_ : ∀ (x : A) {y : B} {z : C} →y ≅ x → y IsRelatedTo z → x IsRelatedTo z_ ≅⟨ y≅x ⟨ relTo y≅z = relTo (trans (sym y≅x) y≅z)-- Deprecatedinfixr 2 _≅˘⟨_⟩__≅˘⟨_⟩_ = _≅⟨_⟨_{-# WARNING_ON_USAGE _≅˘⟨_⟩_"Warning: _≅˘⟨_⟩_ was deprecated in v2.0.Please use _≅⟨_⟨_ instead."#-}-------------------------------------------------------------------------- Inspect-- Inspect can be used when you want to pattern match on the result r-- of some expression e, and you also need to "remember" that r ≡ e.record Reveal_·_is_ {A : Set a} {B : A → Set b}(f : (x : A) → B x) (x : A) (y : B x) :Set (a ⊔ b) whereconstructor [_]field eq : f x ≅ yinspect : ∀ {A : Set a} {B : A → Set b}(f : (x : A) → B x) (x : A) → Reveal f · x is f xinspect f x = [ refl ]-- Example usage:-- f x y with g x | inspect g x-- f x y | c z | [ eq ] = ...
-------------------------------------------------------------------------- The Agda standard library---- Quotients for Heterogeneous equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Relation.Binary.HeterogeneousEquality.Quotients whereopen import Function.Base using (_$_; const; _∘_)open import Level hiding (lift)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.HeterogeneousEqualityopen ≅-Reasoningrecord Quotient {c ℓ} (S : Setoid c ℓ) : Set (suc (c ⊔ ℓ)) whereopen Setoid S renaming (Carrier to A)fieldQ : Set cabs : A → Qcompat : (B : Q → Set c) (f : ∀ a → B (abs a)) → Set (c ⊔ ℓ)compat _ f = {a a′ : A} → a ≈ a′ → f a ≅ f a′fieldcompat-abs : compat _ abslift : (B : Q → Set c) (f : ∀ a → B (abs a)) → compat B f → ∀ q → B qlift-conv : {B : Q → Set c} (f : ∀ a → B (abs a)) (p : compat B f) →∀ a → lift B f p (abs a) ≅ f aQuotients : ∀ c ℓ → Set (suc (c ⊔ ℓ))Quotients c ℓ = (S : Setoid c ℓ) → Quotient Smodule Properties {c ℓ} {S : Setoid c ℓ} (Qu : Quotient S) whereopen Setoid S renaming (Carrier to A) hiding (refl; sym; trans)open Quotient Qumodule _ {B B′ : Q → Set c} {f : ∀ a → B (abs a)} {p : compat B f} wherelift-unique : {g : ∀ q → B′ q} → (∀ a → g (abs a) ≅ f a) →∀ x → lift B f p x ≅ g xlift-unique {g} ext = lift _ liftf≅g liftf≅g-ext whereliftf≅g : ∀ a → lift B f p (abs a) ≅ g (abs a)liftf≅g x = beginlift _ f p (abs x) ≅⟨ lift-conv f p x ⟩f x ≅⟨ sym (ext x) ⟩g (abs x) ∎liftf≅g-ext : ∀ {a a′} → a ≈ a′ → liftf≅g a ≅ liftf≅g a′liftf≅g-ext eq = ≅-heterogeneous-irrelevantˡ _ _$ cong (lift B f p) (compat-abs eq)lift-ext : {g : ∀ a → B′ (abs a)} {p′ : compat B′ g} → (∀ x → f x ≅ g x) →∀ x → lift B f p x ≅ lift B′ g p′ xlift-ext {g} {p′} h = lift-unique $ λ a → beginlift B′ g p′ (abs a) ≅⟨ lift-conv g p′ a ⟩g a ≅⟨ sym (h a) ⟩f a ∎lift-conv-abs : ∀ a → lift (const Q) abs compat-abs a ≅ alift-conv-abs = lift-unique (λ _ → refl)lift-fold : {B : Q → Set c} (f : ∀ q → B q) →∀ a → lift B (f ∘ abs) (cong f ∘ compat-abs) a ≅ f alift-fold f = lift-unique (λ _ → refl)abs-epimorphism : {B : Q → Set c} {f g : ∀ q → B q} →(∀ x → f (abs x) ≅ g (abs x)) → ∀ q → f q ≅ g qabs-epimorphism {B} {f} {g} p q = beginf q ≅⟨ sym (lift-fold f q) ⟩lift B (f ∘ abs) (cong f ∘ compat-abs) q ≅⟨ lift-ext p q ⟩lift B (g ∘ abs) (cong g ∘ compat-abs) q ≅⟨ lift-fold g q ⟩g q ∎-------------------------------------------------------------------------- Properties provable with extensionalitymodule _ (ext : ∀ {a b} {A : Set a} {B₁ B₂ : A → Set b} {f₁ : ∀ a → B₁ a}{f₂ : ∀ a → B₂ a} → (∀ a → f₁ a ≅ f₂ a) → f₁ ≅ f₂) wheremodule Properties₂{c ℓ} {S₁ S₂ : Setoid c ℓ} (Qu₁ : Quotient S₁) (Qu₂ : Quotient S₂)wheremodule S₁ = Setoid S₁module S₂ = Setoid S₂module Qu₁ = Quotient Qu₁module Qu₂ = Quotient Qu₂module _ {B : _ → _ → Set c} (f : ∀ s₁ s₂ → B (Qu₁.abs s₁) (Qu₂.abs s₂)) wherecompat₂ : Set _compat₂ = ∀ {a b a′ b′} → a S₁.≈ a′ → b S₂.≈ b′ → f a b ≅ f a′ b′lift₂ : compat₂ → ∀ q q′ → B q q′lift₂ p = Qu₁.lift _ g (ext ∘ g-ext) module Lift₂ whereg : ∀ a q → B (Qu₁.abs a) qg a = Qu₂.lift (B (Qu₁.abs a)) (f a) (p S₁.refl)g-ext : ∀ {a a′} → a S₁.≈ a′ → ∀ q → g a q ≅ g a′ qg-ext a≈a′ = Properties.lift-ext Qu₂ (λ _ → p a≈a′ S₂.refl)lift₂-conv : (p : compat₂) → ∀ a a′ → lift₂ p (Qu₁.abs a) (Qu₂.abs a′) ≅ f a a′lift₂-conv p a a′ = beginlift₂ p (Qu₁.abs a) (Qu₂.abs a′)≅⟨ cong (_$ (Qu₂.abs a′)) (Qu₁.lift-conv (Lift₂.g p) (ext ∘ Lift₂.g-ext p) a) ⟩Lift₂.g p a (Qu₂.abs a′)≡⟨⟩Qu₂.lift (B (Qu₁.abs a)) (f a) (p S₁.refl) (Qu₂.abs a′)≅⟨ Qu₂.lift-conv (f a) (p S₁.refl) a′ ⟩f a a′∎module Properties₃ {c ℓ} {S₁ S₂ S₃ : Setoid c ℓ}(Qu₁ : Quotient S₁) (Qu₂ : Quotient S₂) (Qu₃ : Quotient S₃)wheremodule S₁ = Setoid S₁module S₂ = Setoid S₂module S₃ = Setoid S₃module Qu₁ = Quotient Qu₁module Qu₂ = Quotient Qu₂module Qu₃ = Quotient Qu₃module _ {B : _ → _ → _ → Set c}(f : ∀ s₁ s₂ s₃ → B (Qu₁.abs s₁) (Qu₂.abs s₂) (Qu₃.abs s₃)) wherecompat₃ : Set _compat₃ = ∀ {a b c a′ b′ c′} → a S₁.≈ a′ → b S₂.≈ b′ → c S₃.≈ c′ →f a b c ≅ f a′ b′ c′lift₃ : compat₃ → ∀ q₁ q₂ q₃ → B q₁ q₂ q₃lift₃ p = Qu₁.lift _ h (ext ∘ h-ext) module Lift₃ whereg : ∀ a b q → B (Qu₁.abs a) (Qu₂.abs b) qg a b = Qu₃.lift (B (Qu₁.abs a) (Qu₂.abs b)) (f a b) (p S₁.refl S₂.refl)g-ext : ∀ {a a′ b b′} → a S₁.≈ a′ → b S₂.≈ b′ → ∀ c → g a b c ≅ g a′ b′ cg-ext a≈a′ b≈b′ = Properties.lift-ext Qu₃ (λ _ → p a≈a′ b≈b′ S₃.refl)h : ∀ a q₂ q₃ → B (Qu₁.abs a) q₂ q₃h a = Qu₂.lift (λ b → ∀ q → B (Qu₁.abs a) b q) (g a) (ext ∘ g-ext S₁.refl)h-ext : ∀ {a a′} → a S₁.≈ a′ → ∀ b → h a b ≅ h a′ bh-ext a≈a′ = Properties.lift-ext Qu₂ $ λ _ → ext (g-ext a≈a′ S₂.refl)
-------------------------------------------------------------------------- The Agda standard library---- Example of a Quotient: ℤ as (ℕ × ℕ / ∼)------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Relation.Binary.HeterogeneousEquality.Quotients.Examples whereopen import Relation.Binary.HeterogeneousEquality.Quotientsopen import Level using (0ℓ)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.HeterogeneousEquality hiding (isEquivalence)import Relation.Binary.PropositionalEquality.Core as ≡open import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Data.Product.Base using (_×_; _,_)open import Function.Baseopen ≅-Reasoningℕ² = ℕ × ℕ_∼_ : ℕ² → ℕ² → Set(x , y) ∼ (x′ , y′) = x + y′ ≅ x′ + yinfix 10 _∼_∼-trans : ∀ {i j k} → i ∼ j → j ∼ k → i ∼ k∼-trans {x₁ , y₁} {x₂ , y₂} {x₃ , y₃} p q =≡-to-≅ $ +-cancelˡ-≡ y₂ _ _ $ ≅-to-≡ $ beginy₂ + (x₁ + y₃) ≡⟨ ≡.sym (+-assoc y₂ x₁ y₃) ⟩y₂ + x₁ + y₃ ≡⟨ ≡.cong (_+ y₃) (+-comm y₂ x₁) ⟩x₁ + y₂ + y₃ ≅⟨ cong (_+ y₃) p ⟩x₂ + y₁ + y₃ ≡⟨ ≡.cong (_+ y₃) (+-comm x₂ y₁) ⟩y₁ + x₂ + y₃ ≡⟨ +-assoc y₁ x₂ y₃ ⟩y₁ + (x₂ + y₃) ≅⟨ cong (y₁ +_) q ⟩y₁ + (x₃ + y₂) ≡⟨ +-comm y₁ (x₃ + y₂) ⟩x₃ + y₂ + y₁ ≡⟨ ≡.cong (_+ y₁) (+-comm x₃ y₂) ⟩y₂ + x₃ + y₁ ≡⟨ +-assoc y₂ x₃ y₁ ⟩y₂ + (x₃ + y₁) ∎∼-isEquivalence : IsEquivalence _∼_∼-isEquivalence = record{ refl = refl; sym = sym; trans = λ {i} {j} {k} → ∼-trans {i} {j} {k}}ℕ²-∼-setoid : Setoid 0ℓ 0ℓℕ²-∼-setoid = record { isEquivalence = ∼-isEquivalence }module Integers (quot : Quotients 0ℓ 0ℓ) whereInt : Quotient ℕ²-∼-setoidInt = quot _open Quotient Int renaming (Q to ℤ)infixl 6 _+²__+²_ : ℕ² → ℕ² → ℕ²(x₁ , y₁) +² (x₂ , y₂) = x₁ + x₂ , y₁ + y₂+²-cong : ∀{a b a′ b′} → a ∼ a′ → b ∼ b′ → (a +² b) ∼ (a′ +² b′)+²-cong {a₁ , b₁} {c₁ , d₁} {a₂ , b₂} {c₂ , d₂} ab∼cd₁ ab∼cd₂ = begin(a₁ + c₁) + (b₂ + d₂) ≡⟨ ≡.cong (_+ (b₂ + d₂)) (+-comm a₁ c₁) ⟩(c₁ + a₁) + (b₂ + d₂) ≡⟨ +-assoc c₁ a₁ (b₂ + d₂) ⟩c₁ + (a₁ + (b₂ + d₂)) ≡⟨ ≡.cong (c₁ +_) (≡.sym (+-assoc a₁ b₂ d₂)) ⟩c₁ + (a₁ + b₂ + d₂) ≅⟨ cong (λ n → c₁ + (n + d₂)) ab∼cd₁ ⟩c₁ + (a₂ + b₁ + d₂) ≡⟨ ≡.cong (c₁ +_) (+-assoc a₂ b₁ d₂) ⟩c₁ + (a₂ + (b₁ + d₂)) ≡⟨ ≡.cong (λ n → c₁ + (a₂ + n)) (+-comm b₁ d₂) ⟩c₁ + (a₂ + (d₂ + b₁)) ≡⟨ ≡.sym (+-assoc c₁ a₂ (d₂ + b₁)) ⟩(c₁ + a₂) + (d₂ + b₁) ≡⟨ ≡.cong (_+ (d₂ + b₁)) (+-comm c₁ a₂) ⟩(a₂ + c₁) + (d₂ + b₁) ≡⟨ +-assoc a₂ c₁ (d₂ + b₁) ⟩a₂ + (c₁ + (d₂ + b₁)) ≡⟨ ≡.cong (a₂ +_) (≡.sym (+-assoc c₁ d₂ b₁)) ⟩a₂ + (c₁ + d₂ + b₁) ≅⟨ cong (λ n → a₂ + (n + b₁)) ab∼cd₂ ⟩a₂ + (c₂ + d₁ + b₁) ≡⟨ ≡.cong (a₂ +_) (+-assoc c₂ d₁ b₁) ⟩a₂ + (c₂ + (d₁ + b₁)) ≡⟨ ≡.cong (λ n → a₂ + (c₂ + n)) (+-comm d₁ b₁) ⟩a₂ + (c₂ + (b₁ + d₁)) ≡⟨ ≡.sym (+-assoc a₂ c₂ (b₁ + d₁)) ⟩(a₂ + c₂) + (b₁ + d₁) ∎module _ (ext : ∀ {a b} {A : Set a} {B₁ B₂ : A → Set b} {f₁ : ∀ a → B₁ a}{f₂ : ∀ a → B₂ a} → (∀ a → f₁ a ≅ f₂ a) → f₁ ≅ f₂) whereinfixl 6 _+ℤ__+ℤ_ : ℤ → ℤ → ℤ_+ℤ_ = Properties₂.lift₂ ext Int Int (λ i j → abs (i +² j))$ λ {a} {b} {c} p p′ → compat-abs (+²-cong {a} {b} {c} p p′)zero² : ℕ²zero² = 0 , 0zeroℤ : ℤzeroℤ = abs zero²+²-identityʳ : (i : ℕ²) → (i +² zero²) ∼ i+²-identityʳ (x , y) = begin(x + 0) + y ≡⟨ ≡.cong (_+ y) (+-identityʳ x) ⟩x + y ≡⟨ ≡.cong (x +_) (≡.sym (+-identityʳ y)) ⟩x + (y + 0) ∎+ℤ-on-abs≅abs-+₂ : ∀ a b → abs a +ℤ abs b ≅ abs (a +² b)+ℤ-on-abs≅abs-+₂ = Properties₂.lift₂-conv ext Int Int _$ λ {a} {b} {c} p p′ → compat-abs (+²-cong {a} {b} {c} p p′)+ℤ-identityʳ : ∀ i → i +ℤ zeroℤ ≅ i+ℤ-identityʳ = lift _ eq (≅-heterogeneous-irrelevantʳ _ _ ∘ compat-abs) whereeq : ∀ a → abs a +ℤ zeroℤ ≅ abs aeq a = beginabs a +ℤ zeroℤ ≡⟨⟩abs a +ℤ abs zero² ≅⟨ +ℤ-on-abs≅abs-+₂ a zero² ⟩abs (a +² zero²) ≅⟨ compat-abs (+²-identityʳ a) ⟩abs a ∎+²-identityˡ : (i : ℕ²) → (zero² +² i) ∼ i+²-identityˡ i = refl+ℤ-identityˡ : (i : ℤ) → zeroℤ +ℤ i ≅ i+ℤ-identityˡ = lift _ eq (≅-heterogeneous-irrelevantʳ _ _ ∘ compat-abs) whereeq : ∀ a → zeroℤ +ℤ abs a ≅ abs aeq a = beginzeroℤ +ℤ abs a ≡⟨⟩abs zero² +ℤ abs a ≅⟨ +ℤ-on-abs≅abs-+₂ zero² a ⟩abs (zero² +² a) ≅⟨ compat-abs (+²-identityˡ a) ⟩abs a ∎+²-assoc : (i j k : ℕ²) → ((i +² j) +² k) ∼ (i +² (j +² k))+²-assoc (a , b) (c , d) (e , f) = begin((a + c) + e) + (b + (d + f)) ≡⟨ ≡.cong (_+ (b + (d + f))) (+-assoc a c e) ⟩(a + (c + e)) + (b + (d + f)) ≡⟨ ≡.cong ((a + (c + e)) +_) (≡.sym (+-assoc b d f)) ⟩(a + (c + e)) + ((b + d) + f) ∎+ℤ-assoc : ∀ i j k → (i +ℤ j) +ℤ k ≅ i +ℤ (j +ℤ k)+ℤ-assoc = Properties₃.lift₃ ext Int Int Int eq compat₃ whereeq : ∀ i j k → (abs i +ℤ abs j) +ℤ abs k ≅ abs i +ℤ (abs j +ℤ abs k)eq i j k = begin(abs i +ℤ abs j) +ℤ abs k ≅⟨ cong (_+ℤ abs k) (+ℤ-on-abs≅abs-+₂ i j) ⟩(abs (i +² j) +ℤ abs k) ≅⟨ +ℤ-on-abs≅abs-+₂ (i +² j) k ⟩abs ((i +² j) +² k) ≅⟨ compat-abs (+²-assoc i j k) ⟩abs (i +² (j +² k)) ≅⟨ sym (+ℤ-on-abs≅abs-+₂ i (j +² k)) ⟩(abs i +ℤ abs (j +² k)) ≅⟨ cong (abs i +ℤ_) (sym (+ℤ-on-abs≅abs-+₂ j k)) ⟩abs i +ℤ (abs j +ℤ abs k) ∎compat₃ : ∀ {a a′ b b′ c c′} → a ∼ a′ → b ∼ b′ → c ∼ c′ → eq a b c ≅ eq a′ b′ c′compat₃ p q r = ≅-heterogeneous-irrelevantˡ _ _$ cong₂ _+ℤ_ (cong₂ _+ℤ_ (compat-abs p) (compat-abs q))$ compat-abs r
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous equality-------------------------------------------------------------------------- This file contains some core definitions which are reexported by-- Relation.Binary.HeterogeneousEquality.{-# OPTIONS --with-K --safe #-}module Relation.Binary.HeterogeneousEquality.Core whereopen import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b : LevelA : Set a-------------------------------------------------------------------------- Heterogeneous equalityinfix 4 _≅_data _≅_ {A : Set a} (x : A) : {B : Set b} → B → Set a whererefl : x ≅ x-------------------------------------------------------------------------- Conversion≅-to-≡ : ∀ {x y : A} → x ≅ y → x ≡ y≅-to-≡ refl = refl≡-to-≅ : ∀ {x y : A} → x ≡ y → x ≅ y≡-to-≅ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Properties of binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via `Relation.Binary`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Definitions whereopen import Agda.Builtin.Equality using (_≡_)open import Data.Product.Base using (_×_; ∃-syntax)open import Data.Sum.Base using (_⊎_)open import Function.Base using (_on_; flip)open import Levelopen import Relation.Binary.Coreopen import Relation.Nullary as Nullary using (¬_; Dec)privatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitions-------------------------------------------------------------------------- Reflexivity - defined without an underlying equality. It could-- alternatively be defined as `_≈_ ⇒ _∼_` for some equality `_≈_`.-- Confusingly the convention in the library is to use the name "refl"-- for proofs of Reflexive and `reflexive` for proofs of type `_≈_ ⇒ _∼_`,-- e.g. in the definition of `IsEquivalence` later in this file. This-- convention is a legacy from the early days of the library.Reflexive : Rel A ℓ → Set _Reflexive _∼_ = ∀ {x} → x ∼ x-- Generalised symmetry.Sym : REL A B ℓ₁ → REL B A ℓ₂ → Set _Sym P Q = P ⇒ flip Q-- Symmetry.Symmetric : Rel A ℓ → Set _Symmetric _∼_ = Sym _∼_ _∼_-- Generalised transitivity.Trans : REL A B ℓ₁ → REL B C ℓ₂ → REL A C ℓ₃ → Set _Trans P Q R = ∀ {i j k} → P i j → Q j k → R i kRightTrans : REL A B ℓ₁ → REL B B ℓ₂ → Set _RightTrans R S = Trans R S RLeftTrans : REL A A ℓ₁ → REL A B ℓ₂ → Set _LeftTrans S R = Trans S R R-- A flipped variant of generalised transitivity.TransFlip : REL A B ℓ₁ → REL B C ℓ₂ → REL A C ℓ₃ → Set _TransFlip P Q R = ∀ {i j k} → Q j k → P i j → R i k-- Transitivity.Transitive : Rel A ℓ → Set _Transitive _∼_ = Trans _∼_ _∼_ _∼_-- Generalised antisymmetryAntisym : REL A B ℓ₁ → REL B A ℓ₂ → REL A B ℓ₃ → Set _Antisym R S E = ∀ {i j} → R i j → S j i → E i j-- Antisymmetry.Antisymmetric : Rel A ℓ₁ → Rel A ℓ₂ → Set _Antisymmetric _≈_ _≤_ = Antisym _≤_ _≤_ _≈_-- Irreflexivity - this is defined terms of the underlying equality.Irreflexive : REL A B ℓ₁ → REL A B ℓ₂ → Set _Irreflexive _≈_ _<_ = ∀ {x y} → x ≈ y → ¬ (x < y)-- Asymmetry.Asymmetric : Rel A ℓ → Set _Asymmetric _<_ = ∀ {x y} → x < y → ¬ (y < x)-- DensityDense : Rel A ℓ → Set _Dense _<_ = ∀ {x y} → x < y → ∃[ z ] x < z × z < y-- Generalised connex - at least one of the two relations holds.Connex : REL A B ℓ₁ → REL B A ℓ₂ → Set _Connex P Q = ∀ x y → P x y ⊎ Q y x-- Totality.Total : Rel A ℓ → Set _Total _∼_ = Connex _∼_ _∼_-- Generalised trichotomy - exactly one of three types has a witness.data Tri (A : Set a) (B : Set b) (C : Set c) : Set (a ⊔ b ⊔ c) wheretri< : ( a : A) (¬b : ¬ B) (¬c : ¬ C) → Tri A B Ctri≈ : (¬a : ¬ A) ( b : B) (¬c : ¬ C) → Tri A B Ctri> : (¬a : ¬ A) (¬b : ¬ B) ( c : C) → Tri A B C-- Trichotomy.Trichotomous : Rel A ℓ₁ → Rel A ℓ₂ → Set _Trichotomous _≈_ _<_ = ∀ x y → Tri (x < y) (x ≈ y) (x > y)where _>_ = flip _<_-- Generalised maximum element.Max : REL A B ℓ → B → Set _Max _≤_ T = ∀ x → x ≤ T-- Maximum element.Maximum : Rel A ℓ → A → Set _Maximum = Max-- Generalised minimum element.Min : REL A B ℓ → A → Set _Min R = Max (flip R)-- Minimum element.Minimum : Rel A ℓ → A → Set _Minimum = Min-- Definitions for apartness relations-- Note that Cotransitive's arguments are permuted with respect to Transitive's.Cotransitive : Rel A ℓ → Set _Cotransitive _#_ = ∀ {x y} → x # y → ∀ z → (x # z) ⊎ (z # y)Tight : Rel A ℓ₁ → Rel A ℓ₂ → Set _Tight _≈_ _#_ = ∀ x y → (¬ x # y → x ≈ y) × (x ≈ y → ¬ x # y)-- Properties of order morphisms, aka order-preserving mapsMonotonic₁ : Rel A ℓ₁ → Rel B ℓ₂ → (A → B) → Set _Monotonic₁ _≤_ _⊑_ f = f Preserves _≤_ ⟶ _⊑_Antitonic₁ : Rel A ℓ₁ → Rel B ℓ₂ → (A → B) → Set _Antitonic₁ _≤_ _⊑_ f = f Preserves (flip _≤_) ⟶ _⊑_Monotonic₂ : Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → (A → B → C) → Set _Monotonic₂ _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ _≤_ ⟶ _⊑_ ⟶ _≼_MonotonicAntitonic : Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → (A → B → C) → Set _MonotonicAntitonic _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ _≤_ ⟶ (flip _⊑_) ⟶ _≼_AntitonicMonotonic : Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → (A → B → C) → Set _AntitonicMonotonic _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ (flip _≤_) ⟶ _⊑_ ⟶ _≼_Antitonic₂ : Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → (A → B → C) → Set _Antitonic₂ _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ (flip _≤_) ⟶ (flip _⊑_) ⟶ _≼_Adjoint : Rel A ℓ₁ → Rel B ℓ₂ → (A → B) → (B → A) → Set _Adjoint _≤_ _⊑_ f g = ∀ {x y} → (f x ⊑ y → x ≤ g y) × (x ≤ g y → f x ⊑ y)-- Unary relations respecting a binary relation._⟶_Respects_ : (A → Set ℓ₁) → (B → Set ℓ₂) → REL A B ℓ₃ → Set _P ⟶ Q Respects _∼_ = ∀ {x y} → x ∼ y → P x → Q y-- Unary relation respects a binary relation._Respects_ : (A → Set ℓ₁) → Rel A ℓ₂ → Set _P Respects _∼_ = P ⟶ P Respects _∼_-- Right respecting - relatedness is preserved on the right by equality._Respectsʳ_ : REL A B ℓ₁ → Rel B ℓ₂ → Set __∼_ Respectsʳ _≈_ = ∀ {x} → (x ∼_) Respects _≈_-- Left respecting - relatedness is preserved on the left by equality._Respectsˡ_ : REL A B ℓ₁ → Rel A ℓ₂ → Set _P Respectsˡ _∼_ = ∀ {y} → (flip P y) Respects _∼_-- Respecting - relatedness is preserved on both sides by equality_Respects₂_ : Rel A ℓ₁ → Rel A ℓ₂ → Set _P Respects₂ _∼_ = (P Respectsʳ _∼_) × (P Respectsˡ _∼_)-- Substitutivity - any two related elements satisfy exactly the same-- set of unary relations. Note that only the various derivatives-- of propositional equality can satisfy this property.Substitutive : Rel A ℓ₁ → (ℓ₂ : Level) → Set _Substitutive {A = A} _∼_ p = (P : A → Set p) → P Respects _∼_-- Irrelevancy - all proofs that a given pair of elements are related-- are indistinguishable.Irrelevant : REL A B ℓ → Set _Irrelevant _∼_ = ∀ {x y} → Nullary.Irrelevant (x ∼ y)-- Recomputability - we can rebuild a relevant proof given an-- irrelevant one.Recomputable : REL A B ℓ → Set _Recomputable _∼_ = ∀ {x y} → Nullary.Recomputable (x ∼ y)-- StabilityStable : REL A B ℓ → Set _Stable _∼_ = ∀ x y → Nullary.Stable (x ∼ y)-- Weak decidability - it is sometimes possible to determine if a given-- pair of elements are related.WeaklyDecidable : REL A B ℓ → Set _WeaklyDecidable _∼_ = ∀ x y → Nullary.WeaklyDecidable (x ∼ y)-- Decidability - it is possible to determine whether a given pair of-- elements are related.Decidable : REL A B ℓ → Set _Decidable _∼_ = ∀ x y → Dec (x ∼ y)-- Propositional equality is decidable for the type.DecidableEquality : (A : Set a) → Set _DecidableEquality A = Decidable {A = A} _≡_-- Universal - all pairs of elements are relatedUniversal : REL A B ℓ → Set _Universal _∼_ = ∀ x y → x ∼ y-- Empty - no elements are relatedEmpty : REL A B ℓ → Set _Empty _∼_ = ∀ {x y} → ¬ (x ∼ y)-- Non-emptiness - at least one pair of elements are related.record NonEmpty {A : Set a} {B : Set b}(T : REL A B ℓ) : Set (a ⊔ b ⊔ ℓ) whereconstructor nonEmptyfield{x} : A{y} : Bproof : T x y
-------------------------------------------------------------------------- The Agda standard library---- Properties of binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via `Relation.Binary`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Core whereopen import Data.Product.Base using (_×_)open import Function.Base using (_on_)open import Level using (Level; _⊔_; suc)privatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitions-------------------------------------------------------------------------- Heterogeneous binary relationsREL : Set a → Set b → (ℓ : Level) → Set (a ⊔ b ⊔ suc ℓ)REL A B ℓ = A → B → Set ℓ-- Homogeneous binary relationsRel : Set a → (ℓ : Level) → Set (a ⊔ suc ℓ)Rel A ℓ = REL A A ℓ-------------------------------------------------------------------------- Relationships between relations------------------------------------------------------------------------infix 4 _⇒_ _⇔_ _=[_]⇒_-- Implication/containment - could also be written _⊆_.-- and corresponding notion of equivalence_⇒_ : REL A B ℓ₁ → REL A B ℓ₂ → Set _P ⇒ Q = ∀ {x y} → P x y → Q x y_⇔_ : REL A B ℓ₁ → REL A B ℓ₂ → Set _P ⇔ Q = P ⇒ Q × Q ⇒ P-- Generalised implication - if P ≡ Q it can be read as "f preserves P"._=[_]⇒_ : Rel A ℓ₁ → (A → B) → Rel B ℓ₂ → Set _P =[ f ]⇒ Q = P ⇒ (Q on f)-- A synonym for _=[_]⇒_._Preserves_⟶_ : (A → B) → Rel A ℓ₁ → Rel B ℓ₂ → Set _f Preserves P ⟶ Q = P =[ f ]⇒ Q-- A binary variant of _Preserves_⟶_._Preserves₂_⟶_⟶_ : (A → B → C) → Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → Set __∙_ Preserves₂ P ⟶ Q ⟶ R = ∀ {x y u v} → P x y → Q u v → R (x ∙ u) (y ∙ v)
-------------------------------------------------------------------------- The Agda standard library---- Union of two binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Union whereopen import Data.Product.Baseopen import Data.Sum.Base as Sumopen import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Definitionsusing (Reflexive; Total; Minimum; Maximum; Symmetric; Irreflexive; Decidable; _Respects_; _Respectsˡ_; _Respectsʳ_; _Respects₂_)open import Relation.Nullary.Decidable using (yes; no; _⊎-dec_)privatevariablea b ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definitioninfixr 6 _∪__∪_ : REL A B ℓ₁ → REL A B ℓ₂ → REL A B (ℓ₁ ⊔ ℓ₂)L ∪ R = λ i j → L i j ⊎ R i j-------------------------------------------------------------------------- Propertiesmodule _ (L : Rel A ℓ) (R : Rel A ℓ) wherereflexive : Reflexive L ⊎ Reflexive R → Reflexive (L ∪ R)reflexive (inj₁ L-refl) = inj₁ L-reflreflexive (inj₂ R-refl) = inj₂ R-refltotal : Total L ⊎ Total R → Total (L ∪ R)total (inj₁ L-total) x y = [ inj₁ ∘ inj₁ , inj₂ ∘ inj₁ ] (L-total x y)total (inj₂ R-total) x y = [ inj₁ ∘ inj₂ , inj₂ ∘ inj₂ ] (R-total x y)min : ∀ {⊤} → Minimum L ⊤ ⊎ Minimum R ⊤ → Minimum (L ∪ R) ⊤min = [ inj₁ ∘_ , inj₂ ∘_ ]max : ∀ {⊥} → Maximum L ⊥ ⊎ Maximum R ⊥ → Maximum (L ∪ R) ⊥max = [ inj₁ ∘_ , inj₂ ∘_ ]module _ {L : Rel A ℓ} {R : Rel A ℓ} wheresymmetric : Symmetric L → Symmetric R → Symmetric (L ∪ R)symmetric L-sym R-sym = [ inj₁ ∘ L-sym , inj₂ ∘ R-sym ]respects : ∀ {p} {P : A → Set p} →P Respects L → P Respects R → P Respects (L ∪ R)respects resp-L resp-R = [ resp-L , resp-R ]module _ {≈ : Rel A ℓ₁} (L : REL A B ℓ₂) (R : REL A B ℓ₃) whererespˡ : L Respectsˡ ≈ → R Respectsˡ ≈ → (L ∪ R) Respectsˡ ≈respˡ Lˡ Rˡ x≈y = Sum.map (Lˡ x≈y) (Rˡ x≈y)module _ {≈ : Rel B ℓ₁} (L : REL A B ℓ₂) (R : REL A B ℓ₃) whererespʳ : L Respectsʳ ≈ → R Respectsʳ ≈ → (L ∪ R) Respectsʳ ≈respʳ Lʳ Rʳ x≈y = Sum.map (Lʳ x≈y) (Rʳ x≈y)module _ {≈ : Rel A ℓ₁} {L : Rel A ℓ₂} {R : Rel A ℓ₃} whereresp₂ : L Respects₂ ≈ → R Respects₂ ≈ → (L ∪ R) Respects₂ ≈resp₂ (Lʳ , Lˡ) (Rʳ , Rˡ) = respʳ L R Lʳ Rʳ , respˡ L R Lˡ Rˡmodule _ (≈ : REL A B ℓ₁) (L : REL A B ℓ₂) (R : REL A B ℓ₃) whereimplies : (≈ ⇒ L) ⊎ (≈ ⇒ R) → ≈ ⇒ (L ∪ R)implies = [ inj₁ ∘_ , inj₂ ∘_ ]irreflexive : Irreflexive ≈ L → Irreflexive ≈ R → Irreflexive ≈ (L ∪ R)irreflexive L-irrefl R-irrefl x≈y = [ L-irrefl x≈y , R-irrefl x≈y ]module _ {L : REL A B ℓ₁} {R : REL A B ℓ₂} wheredecidable : Decidable L → Decidable R → Decidable (L ∪ R)decidable L? R? x y = L? x y ⊎-dec R? x y
-------------------------------------------------------------------------- The Agda standard library---- Substituting equalities for binary relations-------------------------------------------------------------------------- For more general transformations between binary relations-- see `Relation.Binary.Morphisms`.{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (_,_)open import Relation.Binary.Core using (Rel; _⇔_)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)module Relation.Binary.Construct.Subst.Equality{a ℓ₁ ℓ₂} {A : Set a} {≈₁ : Rel A ℓ₁} {≈₂ : Rel A ℓ₂}(equiv@(to , from) : ≈₁ ⇔ ≈₂)whereopen import Function.Base-------------------------------------------------------------------------- Definitionsrefl : Reflexive ≈₁ → Reflexive ≈₂refl refl = to reflsym : Symmetric ≈₁ → Symmetric ≈₂sym sym = to ∘′ sym ∘′ fromtrans : Transitive ≈₁ → Transitive ≈₂trans trans x≈y y≈z = to (trans (from x≈y) (from y≈z))-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence ≈₁ → IsEquivalence ≈₂isEquivalence E = record{ refl = refl E.refl; sym = sym E.sym; trans = trans E.trans} where module E = IsEquivalence E
-------------------------------------------------------------------------- The Agda standard library---- Conversion of < to ≤, along with a number of properties-------------------------------------------------------------------------- Possible TODO: Prove that a conversion ≤ → < → ≤ returns a-- relation equivalent to the original one (and similarly for-- < → ≤ → <).{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsEquivalence; IsPreorder; IsStrictPartialOrder; IsPartialOrder; IsStrictTotalOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Transitive; Symmetric; Irreflexive; Antisymmetric; Trichotomous; Decidable; Trans; Total; _Respects₂_; _Respectsʳ_; _Respectsˡ_; tri<; tri≈; tri>)module Relation.Binary.Construct.StrictToNonStrict{a ℓ₁ ℓ₂} {A : Set a}(_≈_ : Rel A ℓ₁) (_<_ : Rel A ℓ₂)whereopen import Data.Product.Baseopen import Data.Sum.Baseopen import Data.Emptyopen import Function.Baseopen import Relation.Binary.Consequencesopen import Relation.Nullary.Decidable using (_⊎-dec_; yes; no)-------------------------------------------------------------------------- Conversion-- _<_ can be turned into _≤_ as follows:infix 4 _≤__≤_ : Rel A _x ≤ y = (x < y) ⊎ (x ≈ y)-------------------------------------------------------------------------- The converted relations have certain properties-- (if the original relations have certain other properties)<⇒≤ : _<_ ⇒ _≤_<⇒≤ = inj₁reflexive : _≈_ ⇒ _≤_reflexive = inj₂antisym : IsEquivalence _≈_ → Transitive _<_ → Irreflexive _≈_ _<_ →Antisymmetric _≈_ _≤_antisym eq trans irrefl = aswheremodule Eq = IsEquivalence eqas : Antisymmetric _≈_ _≤_as (inj₂ x≈y) _ = x≈yas (inj₁ _) (inj₂ y≈x) = Eq.sym y≈xas (inj₁ x<y) (inj₁ y<x) =⊥-elim (trans∧irr⇒asym {_≈_ = _≈_} Eq.refl trans irrefl x<y y<x)trans : IsEquivalence _≈_ → _<_ Respects₂ _≈_ → Transitive _<_ →Transitive _≤_trans eq (respʳ , respˡ) <-trans = trwheremodule Eq = IsEquivalence eqtr : Transitive _≤_tr (inj₁ x<y) (inj₁ y<z) = inj₁ $ <-trans x<y y<ztr (inj₁ x<y) (inj₂ y≈z) = inj₁ $ respʳ y≈z x<ytr (inj₂ x≈y) (inj₁ y<z) = inj₁ $ respˡ (Eq.sym x≈y) y<ztr (inj₂ x≈y) (inj₂ y≈z) = inj₂ $ Eq.trans x≈y y≈z<-≤-trans : Transitive _<_ → _<_ Respectsʳ _≈_ → Trans _<_ _≤_ _<_<-≤-trans trans respʳ x<y (inj₁ y<z) = trans x<y y<z<-≤-trans trans respʳ x<y (inj₂ y≈z) = respʳ y≈z x<y≤-<-trans : Symmetric _≈_ → Transitive _<_ → _<_ Respectsˡ _≈_ → Trans _≤_ _<_ _<_≤-<-trans sym trans respˡ (inj₁ x<y) y<z = trans x<y y<z≤-<-trans sym trans respˡ (inj₂ x≈y) y<z = respˡ (sym x≈y) y<z≤-respʳ-≈ : Transitive _≈_ → _<_ Respectsʳ _≈_ → _≤_ Respectsʳ _≈_≤-respʳ-≈ trans respʳ y′≈y (inj₁ x<y′) = inj₁ (respʳ y′≈y x<y′)≤-respʳ-≈ trans respʳ y′≈y (inj₂ x≈y′) = inj₂ (trans x≈y′ y′≈y)≤-respˡ-≈ : Symmetric _≈_ → Transitive _≈_ → _<_ Respectsˡ _≈_ → _≤_ Respectsˡ _≈_≤-respˡ-≈ sym trans respˡ x′≈x (inj₁ x′<y) = inj₁ (respˡ x′≈x x′<y)≤-respˡ-≈ sym trans respˡ x′≈x (inj₂ x′≈y) = inj₂ (trans (sym x′≈x) x′≈y)≤-resp-≈ : IsEquivalence _≈_ → _<_ Respects₂ _≈_ → _≤_ Respects₂ _≈_≤-resp-≈ eq (respʳ , respˡ) = ≤-respʳ-≈ Eq.trans respʳ , ≤-respˡ-≈ Eq.sym Eq.trans respˡwhere module Eq = IsEquivalence eqtotal : Trichotomous _≈_ _<_ → Total _≤_total <-tri x y with <-tri x y... | tri< x<y x≉y x≯y = inj₁ (inj₁ x<y)... | tri≈ x≮y x≈y x≯y = inj₁ (inj₂ x≈y)... | tri> x≮y x≉y x>y = inj₂ (inj₁ x>y)decidable : Decidable _≈_ → Decidable _<_ → Decidable _≤_decidable ≈-dec <-dec x y = <-dec x y ⊎-dec ≈-dec x ydecidable′ : Trichotomous _≈_ _<_ → Decidable _≤_decidable′ compare x y with compare x y... | tri< x<y _ _ = yes (inj₁ x<y)... | tri≈ _ x≈y _ = yes (inj₂ x≈y)... | tri> x≮y x≉y _ = no [ x≮y , x≉y ]′-------------------------------------------------------------------------- Converting structuresisPreorder₁ : IsPreorder _≈_ _<_ → IsPreorder _≈_ _≤_isPreorder₁ PO = record{ isEquivalence = S.isEquivalence; reflexive = reflexive; trans = trans S.isEquivalence S.∼-resp-≈ S.trans}where module S = IsPreorder POisPreorder₂ : IsStrictPartialOrder _≈_ _<_ → IsPreorder _≈_ _≤_isPreorder₂ SPO = record{ isEquivalence = S.isEquivalence; reflexive = reflexive; trans = trans S.isEquivalence S.<-resp-≈ S.trans}where module S = IsStrictPartialOrder SPOisPartialOrder : IsStrictPartialOrder _≈_ _<_ → IsPartialOrder _≈_ _≤_isPartialOrder SPO = record{ isPreorder = isPreorder₂ SPO; antisym = antisym S.isEquivalence S.trans S.irrefl}where module S = IsStrictPartialOrder SPOisTotalOrder : IsStrictTotalOrder _≈_ _<_ → IsTotalOrder _≈_ _≤_isTotalOrder STO = record{ isPartialOrder = isPartialOrder S.isStrictPartialOrder; total = total S.compare}where module S = IsStrictTotalOrder STOisDecTotalOrder : IsStrictTotalOrder _≈_ _<_ → IsDecTotalOrder _≈_ _≤_isDecTotalOrder STO = record{ isTotalOrder = isTotalOrder STO; _≟_ = S._≟_; _≤?_ = decidable′ S.compare}where module S = IsStrictTotalOrder STO-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4decidable' : Trichotomous _≈_ _<_ → Decidable _≤_decidable' = decidable′{-# WARNING_ON_USAGE decidable'"Warning: decidable' (ending in an apostrophe) was deprecated in v1.4.Please use decidable′ (ending in a prime) instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Many properties which hold for `_∼_` also hold for `_∼_ on f`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.On whereopen import Data.Product.Base using (_,_)open import Function.Base using (_on_; _∘_)open import Induction.WellFounded using (WellFounded; Acc; acc)open import Level using (Level)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Preorder; Setoid; DecSetoid; Poset; DecPoset; StrictPartialOrder; TotalOrder; DecTotalOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder; IsPartialOrder; IsDecPartialOrder; IsStrictPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Reflexive; Irreflexive; Symmetric; Transitive; Antisymmetric; Asymmetric; Decidable; Total; Trichotomous; _Respects_; _Respects₂_)privatevariablea b p ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definitionsmodule _ (f : B → A) whereimplies : (≈ : Rel A ℓ₁) (∼ : Rel A ℓ₂) →≈ ⇒ ∼ → (≈ on f) ⇒ (∼ on f)implies _ _ impl = implreflexive : (∼ : Rel A ℓ) → Reflexive ∼ → Reflexive (∼ on f)reflexive _ refl = reflirreflexive : (≈ : Rel A ℓ₁) (∼ : Rel A ℓ₂) →Irreflexive ≈ ∼ → Irreflexive (≈ on f) (∼ on f)irreflexive _ _ irrefl = irreflsymmetric : (∼ : Rel A ℓ) → Symmetric ∼ → Symmetric (∼ on f)symmetric _ sym = symtransitive : (∼ : Rel A ℓ) → Transitive ∼ → Transitive (∼ on f)transitive _ trans = transantisymmetric : (≈ : Rel A ℓ₁) (≤ : Rel A ℓ₂) →Antisymmetric ≈ ≤ → Antisymmetric (≈ on f) (≤ on f)antisymmetric _ _ antisym = antisymasymmetric : (< : Rel A ℓ) → Asymmetric < → Asymmetric (< on f)asymmetric _ asym = asymrespects : (∼ : Rel A ℓ) (P : A → Set p) →P Respects ∼ → (P ∘ f) Respects (∼ on f)respects _ _ resp = resprespects₂ : (∼₁ : Rel A ℓ₁) (∼₂ : Rel A ℓ₂) →∼₁ Respects₂ ∼₂ → (∼₁ on f) Respects₂ (∼₂ on f)respects₂ _ _ (resp₁ , resp₂) = (resp₁ , resp₂)decidable : (∼ : Rel A ℓ) → Decidable ∼ → Decidable (∼ on f)decidable _ dec x y = dec (f x) (f y)total : (∼ : Rel A ℓ) → Total ∼ → Total (∼ on f)total _ tot x y = tot (f x) (f y)trichotomous : (≈ : Rel A ℓ₁) (< : Rel A ℓ₂) →Trichotomous ≈ < → Trichotomous (≈ on f) (< on f)trichotomous _ _ compare x y = compare (f x) (f y)accessible : ∀ {∼ : Rel A ℓ} {x} → Acc ∼ (f x) → Acc (∼ on f) xaccessible (acc rs) = acc (λ fy<fx → accessible (rs fy<fx))wellFounded : {∼ : Rel A ℓ} → WellFounded ∼ → WellFounded (∼ on f)wellFounded wf x = accessible (wf (f x))-------------------------------------------------------------------------- Structuresmodule _ (f : B → A) {≈ : Rel A ℓ₁} whereisEquivalence : IsEquivalence ≈ →IsEquivalence (≈ on f)isEquivalence eq = record{ refl = reflexive f ≈ Eq.refl; sym = symmetric f ≈ Eq.sym; trans = transitive f ≈ Eq.trans} where module Eq = IsEquivalence eqisDecEquivalence : IsDecEquivalence ≈ →IsDecEquivalence (≈ on f)isDecEquivalence dec = record{ isEquivalence = isEquivalence Dec.isEquivalence; _≟_ = decidable f ≈ Dec._≟_} where module Dec = IsDecEquivalence decmodule _ (f : B → A) {≈ : Rel A ℓ₁} {∼ : Rel A ℓ₂} whereisPreorder : IsPreorder ≈ ∼ → IsPreorder (≈ on f) (∼ on f)isPreorder pre = record{ isEquivalence = isEquivalence f Pre.isEquivalence; reflexive = implies f ≈ ∼ Pre.reflexive; trans = transitive f ∼ Pre.trans} where module Pre = IsPreorder preisPartialOrder : IsPartialOrder ≈ ∼ →IsPartialOrder (≈ on f) (∼ on f)isPartialOrder po = record{ isPreorder = isPreorder Po.isPreorder; antisym = antisymmetric f ≈ ∼ Po.antisym} where module Po = IsPartialOrder poisDecPartialOrder : IsDecPartialOrder ≈ ∼ →IsDecPartialOrder (≈ on f) (∼ on f)isDecPartialOrder dpo = record{ isPartialOrder = isPartialOrder DPO.isPartialOrder; _≟_ = decidable f _ DPO._≟_; _≤?_ = decidable f _ DPO._≤?_} where module DPO = IsDecPartialOrder dpoisStrictPartialOrder : IsStrictPartialOrder ≈ ∼ →IsStrictPartialOrder (≈ on f) (∼ on f)isStrictPartialOrder spo = record{ isEquivalence = isEquivalence f Spo.isEquivalence; irrefl = irreflexive f ≈ ∼ Spo.irrefl; trans = transitive f ∼ Spo.trans; <-resp-≈ = respects₂ f ∼ ≈ Spo.<-resp-≈} where module Spo = IsStrictPartialOrder spoisTotalOrder : IsTotalOrder ≈ ∼ →IsTotalOrder (≈ on f) (∼ on f)isTotalOrder to = record{ isPartialOrder = isPartialOrder To.isPartialOrder; total = total f ∼ To.total} where module To = IsTotalOrder toisDecTotalOrder : IsDecTotalOrder ≈ ∼ →IsDecTotalOrder (≈ on f) (∼ on f)isDecTotalOrder dec = record{ isTotalOrder = isTotalOrder Dec.isTotalOrder; _≟_ = decidable f ≈ Dec._≟_; _≤?_ = decidable f ∼ Dec._≤?_} where module Dec = IsDecTotalOrder decisStrictTotalOrder : IsStrictTotalOrder ≈ ∼ →IsStrictTotalOrder (≈ on f) (∼ on f)isStrictTotalOrder sto = record{ isStrictPartialOrder = isStrictPartialOrder Sto.isStrictPartialOrder; compare = trichotomous _ _ _ Sto.compare} where module Sto = IsStrictTotalOrder sto-------------------------------------------------------------------------- Bundlespreorder : (P : Preorder a ℓ₁ ℓ₂) →(B → Preorder.Carrier P) →Preorder _ _ _preorder P f = record{ isPreorder = isPreorder f (Preorder.isPreorder P)}setoid : (S : Setoid a ℓ) →(B → Setoid.Carrier S) →Setoid _ _setoid S f = record{ isEquivalence = isEquivalence f (Setoid.isEquivalence S)}decSetoid : (D : DecSetoid a ℓ) →(B → DecSetoid.Carrier D) →DecSetoid _ _decSetoid D f = record{ isDecEquivalence = isDecEquivalence f (DecSetoid.isDecEquivalence D)}poset : ∀ (P : Poset a ℓ₁ ℓ₂) →(B → Poset.Carrier P) →Poset _ _ _poset P f = record{ isPartialOrder = isPartialOrder f (Poset.isPartialOrder P)}decPoset : (D : DecPoset a ℓ₁ ℓ₂) →(B → DecPoset.Carrier D) →DecPoset _ _ _decPoset D f = record{ isDecPartialOrder =isDecPartialOrder f (DecPoset.isDecPartialOrder D)}strictPartialOrder : (S : StrictPartialOrder a ℓ₁ ℓ₂) →(B → StrictPartialOrder.Carrier S) →StrictPartialOrder _ _ _strictPartialOrder S f = record{ isStrictPartialOrder =isStrictPartialOrder f (StrictPartialOrder.isStrictPartialOrder S)}totalOrder : (T : TotalOrder a ℓ₁ ℓ₂) →(B → TotalOrder.Carrier T) →TotalOrder _ _ _totalOrder T f = record{ isTotalOrder = isTotalOrder f (TotalOrder.isTotalOrder T)}decTotalOrder : (D : DecTotalOrder a ℓ₁ ℓ₂) →(B → DecTotalOrder.Carrier D) →DecTotalOrder _ _ _decTotalOrder D f = record{ isDecTotalOrder = isDecTotalOrder f (DecTotalOrder.isDecTotalOrder D)}strictTotalOrder : (S : StrictTotalOrder a ℓ₁ ℓ₂) →(B → StrictTotalOrder.Carrier S) →StrictTotalOrder _ _ _strictTotalOrder S f = record{ isStrictTotalOrder =isStrictTotalOrder f (StrictTotalOrder.isStrictTotalOrder S)}
-------------------------------------------------------------------------- The Agda standard library---- Conversion of _≤_ to _<_------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsPartialOrder; IsEquivalence; IsStrictPartialOrder; IsDecPartialOrder; IsDecStrictPartialOrder; IsTotalOrder; IsStrictTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Trichotomous; Antisymmetric; Symmetric; Total; Decidable; Irreflexive; Transitive; _Respectsʳ_; _Respectsˡ_; _Respects₂_; Trans; Asymmetric; tri≈; tri<; tri>)module Relation.Binary.Construct.NonStrictToStrict{a ℓ₁ ℓ₂} {A : Set a} (_≈_ : Rel A ℓ₁) (_≤_ : Rel A ℓ₂) whereopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Sum.Base using (inj₁; inj₂)open import Function.Base using (_∘_; flip)open import Relation.Nullary using (¬_; yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Nullary.Decidable using (¬?; _×-dec_)private_≉_ : Rel A ℓ₁x ≉ y = ¬ (x ≈ y)-------------------------------------------------------------------------- _≤_ can be turned into _<_ as follows:infix 4 _<__<_ : Rel A _x < y = x ≤ y × x ≉ y-------------------------------------------------------------------------- Relationship between relations<⇒≤ : _<_ ⇒ _≤_<⇒≤ = proj₁<⇒≉ : ∀ {x y} → x < y → x ≉ y<⇒≉ = proj₂≤∧≉⇒< : ∀ {x y} → x ≤ y → x ≉ y → x < y≤∧≉⇒< = _,_<⇒≱ : Antisymmetric _≈_ _≤_ → ∀ {x y} → x < y → ¬ (y ≤ x)<⇒≱ antisym (x≤y , x≉y) y≤x = x≉y (antisym x≤y y≤x)≤⇒≯ : Antisymmetric _≈_ _≤_ → ∀ {x y} → x ≤ y → ¬ (y < x)≤⇒≯ antisym x≤y y<x = <⇒≱ antisym y<x x≤y≰⇒> : Symmetric _≈_ → (_≈_ ⇒ _≤_) → Total _≤_ →∀ {x y} → ¬ (x ≤ y) → y < x≰⇒> sym refl total {x} {y} x≰y with total x y... | inj₁ x≤y = contradiction x≤y x≰y... | inj₂ y≤x = y≤x , x≰y ∘ refl ∘ sym≮⇒≥ : Symmetric _≈_ → Decidable _≈_ → _≈_ ⇒ _≤_ → Total _≤_ →∀ {x y} → ¬ (x < y) → y ≤ x≮⇒≥ sym _≟_ ≤-refl _≤?_ {x} {y} x≮y with x ≟ y | y ≤? x... | yes x≈y | _ = ≤-refl (sym x≈y)... | _ | inj₁ y≤x = y≤x... | no x≉y | inj₂ x≤y = contradiction (x≤y , x≉y) x≮y-------------------------------------------------------------------------- Relational properties<-irrefl : Irreflexive _≈_ _<_<-irrefl x≈y (_ , x≉y) = x≉y x≈y<-trans : IsPartialOrder _≈_ _≤_ → Transitive _<_<-trans po (x≤y , x≉y) (y≤z , y≉z) =(trans x≤y y≤z , x≉y ∘ antisym x≤y ∘ trans y≤z ∘ reflexive ∘ Eq.sym)where open IsPartialOrder po<-≤-trans : Symmetric _≈_ → Transitive _≤_ → Antisymmetric _≈_ _≤_ →_≤_ Respectsʳ _≈_ → Trans _<_ _≤_ _<_<-≤-trans sym trans antisym respʳ (x≤y , x≉y) y≤z =trans x≤y y≤z , (λ x≈z → x≉y (antisym x≤y (respʳ (sym x≈z) y≤z)))≤-<-trans : Transitive _≤_ → Antisymmetric _≈_ _≤_ →_≤_ Respectsˡ _≈_ → Trans _≤_ _<_ _<_≤-<-trans trans antisym respʳ x≤y (y≤z , y≉z) =trans x≤y y≤z , (λ x≈z → y≉z (antisym y≤z (respʳ x≈z x≤y)))<-asym : Antisymmetric _≈_ _≤_ → Asymmetric _<_<-asym antisym (x≤y , x≉y) (y≤x , _) = x≉y (antisym x≤y y≤x)<-respˡ-≈ : Transitive _≈_ → _≤_ Respectsˡ _≈_ → _<_ Respectsˡ _≈_<-respˡ-≈ trans respˡ y≈z (y≤x , y≉x) =respˡ y≈z y≤x , y≉x ∘ trans y≈z<-respʳ-≈ : Symmetric _≈_ → Transitive _≈_ →_≤_ Respectsʳ _≈_ → _<_ Respectsʳ _≈_<-respʳ-≈ sym trans respʳ y≈z (x≤y , x≉y) =(respʳ y≈z x≤y) , λ x≈z → x≉y (trans x≈z (sym y≈z))<-resp-≈ : IsEquivalence _≈_ → _≤_ Respects₂ _≈_ → _<_ Respects₂ _≈_<-resp-≈ eq (respʳ , respˡ) =<-respʳ-≈ sym trans respʳ , <-respˡ-≈ trans respˡwhere open IsEquivalence eq<-trichotomous : Symmetric _≈_ → Decidable _≈_ →Antisymmetric _≈_ _≤_ → Total _≤_ →Trichotomous _≈_ _<_<-trichotomous ≈-sym _≟_ antisym total x y with x ≟ y... | yes x≈y = tri≈ (<-irrefl x≈y) x≈y (<-irrefl (≈-sym x≈y))... | no x≉y with total x y... | inj₁ x≤y = tri< (x≤y , x≉y) x≉y (x≉y ∘ antisym x≤y ∘ proj₁)... | inj₂ y≤x = tri> (x≉y ∘ flip antisym y≤x ∘ proj₁) x≉y (y≤x , x≉y ∘ ≈-sym)<-decidable : Decidable _≈_ → Decidable _≤_ → Decidable _<_<-decidable _≟_ _≤?_ x y = x ≤? y ×-dec ¬? (x ≟ y)-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsPartialOrder _≈_ _≤_ →IsStrictPartialOrder _≈_ _<_<-isStrictPartialOrder po = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans po; <-resp-≈ = <-resp-≈ isEquivalence ≤-resp-≈} where open IsPartialOrder po<-isDecStrictPartialOrder : IsDecPartialOrder _≈_ _≤_ →IsDecStrictPartialOrder _≈_ _<_<-isDecStrictPartialOrder dpo = record{ isStrictPartialOrder = <-isStrictPartialOrder isPartialOrder; _≟_ = _≟_; _<?_ = <-decidable _≟_ _≤?_} where open IsDecPartialOrder dpo<-isStrictTotalOrder₁ : Decidable _≈_ → IsTotalOrder _≈_ _≤_ →IsStrictTotalOrder _≈_ _<_<-isStrictTotalOrder₁ ≟ tot = record{ isStrictPartialOrder = <-isStrictPartialOrder isPartialOrder; compare = <-trichotomous Eq.sym ≟ antisym total} where open IsTotalOrder tot<-isStrictTotalOrder₂ : IsDecTotalOrder _≈_ _≤_ →IsStrictTotalOrder _≈_ _<_<-isStrictTotalOrder₂ dtot = <-isStrictTotalOrder₁ _≟_ isTotalOrderwhere open IsDecTotalOrder dtot
-------------------------------------------------------------------------- The Agda standard library---- The empty binary relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Never whereopen import Relation.Binary.Coreopen import Relation.Binary.Construct.Constantopen import Data.Empty.Polymorphic using (⊥)-------------------------------------------------------------------------- DefinitionNever : ∀ {a ℓ} {A : Set a} → Rel A ℓNever = Const ⊥
-------------------------------------------------------------------------- The Agda standard library---- Conversion of binary operators to binary relations via the right-- natural order.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Core using (Op₂)open import Data.Product.Base using (_,_; _×_)open import Data.Sum.Base using (inj₁; inj₂; map)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Preorder; Poset; DecPoset; TotalOrder; DecTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Symmetric; Transitive; Reflexive; Antisymmetric; Total; _Respectsʳ_; _Respectsˡ_; _Respects₂_; Decidable)open import Relation.Nullary.Negation using (¬_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningmodule Relation.Binary.Construct.NaturalOrder.Right{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) (_∙_ : Op₂ A) whereopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_open import Algebra.Lattice.Structures _≈_-------------------------------------------------------------------------- Definitioninfix 4 _≤__≤_ : Rel A ℓx ≤ y = x ≈ (y ∙ x)-------------------------------------------------------------------------- Relational propertiesreflexive : IsMagma _∙_ → Idempotent _∙_ → _≈_ ⇒ _≤_reflexive magma idem {x} {y} x≈y = beginx ≈⟨ sym (idem x) ⟩x ∙ x ≈⟨ ∙-cong x≈y refl ⟩y ∙ x ∎where open IsMagma magma; open ≈-Reasoning setoidrefl : Symmetric _≈_ → Idempotent _∙_ → Reflexive _≤_refl sym idem {x} = sym (idem x)antisym : IsEquivalence _≈_ → Commutative _∙_ → Antisymmetric _≈_ _≤_antisym isEq comm {x} {y} x≤y y≤x = beginx ≈⟨ x≤y ⟩y ∙ x ≈⟨ comm y x ⟩x ∙ y ≈⟨ y≤x ⟨y ∎where open ≈-Reasoning (record { isEquivalence = isEq })total : Symmetric _≈_ → Transitive _≈_ → Selective _∙_ → Commutative _∙_ → Total _≤_total sym trans sel comm x y =map (λ x∙y≈x → trans (sym x∙y≈x) (comm x y)) sym (sel x y)trans : IsSemigroup _∙_ → Transitive _≤_trans semi {x} {y} {z} x≤y y≤z = beginx ≈⟨ x≤y ⟩y ∙ x ≈⟨ ∙-cong y≤z S.refl ⟩(z ∙ y) ∙ x ≈⟨ assoc z y x ⟩z ∙ (y ∙ x) ≈⟨ ∙-cong S.refl (sym x≤y) ⟩z ∙ x ∎where open module S = IsSemigroup semi; open ≈-Reasoning S.setoidrespʳ : IsMagma _∙_ → _≤_ Respectsʳ _≈_respʳ magma {x} {y} {z} y≈z x≤y = beginx ≈⟨ x≤y ⟩y ∙ x ≈⟨ ∙-cong y≈z M.refl ⟩z ∙ x ∎where open module M = IsMagma magma; open ≈-Reasoning M.setoidrespˡ : IsMagma _∙_ → _≤_ Respectsˡ _≈_respˡ magma {x} {y} {z} y≈z y≤x = beginz ≈⟨ sym y≈z ⟩y ≈⟨ y≤x ⟩x ∙ y ≈⟨ ∙-cong M.refl y≈z ⟩x ∙ z ∎where open module M = IsMagma magma; open ≈-Reasoning M.setoidresp₂ : IsMagma _∙_ → _≤_ Respects₂ _≈_resp₂ magma = respʳ magma , respˡ magmadec : Decidable _≈_ → Decidable _≤_dec _≟_ x y = x ≟ (y ∙ x)-------------------------------------------------------------------------- StructuresisPreorder : IsBand _∙_ → IsPreorder _≈_ _≤_isPreorder band = record{ isEquivalence = isEquivalence; reflexive = reflexive isMagma idem; trans = trans isSemigroup}where open IsBand band hiding (reflexive; trans)isPartialOrder : IsSemilattice _∙_ → IsPartialOrder _≈_ _≤_isPartialOrder semilattice = record{ isPreorder = isPreorder isBand; antisym = antisym isEquivalence comm}where open IsSemilattice semilatticeisDecPartialOrder : IsSemilattice _∙_ → Decidable _≈_ →IsDecPartialOrder _≈_ _≤_isDecPartialOrder semilattice _≟_ = record{ isPartialOrder = isPartialOrder semilattice; _≟_ = _≟_; _≤?_ = dec _≟_}isTotalOrder : IsSemilattice _∙_ → Selective _∙_ → IsTotalOrder _≈_ _≤_isTotalOrder latt sel = record{ isPartialOrder = isPartialOrder latt; total = total sym S.trans sel comm}where open module S = IsSemilattice lattisDecTotalOrder : IsSemilattice _∙_ → Selective _∙_ →Decidable _≈_ → IsDecTotalOrder _≈_ _≤_isDecTotalOrder latt sel _≟_ = record{ isTotalOrder = isTotalOrder latt sel; _≟_ = _≟_; _≤?_ = dec _≟_}-------------------------------------------------------------------------- Bundlespreorder : IsBand _∙_ → Preorder a ℓ ℓpreorder band = record{ isPreorder = isPreorder band}poset : IsSemilattice _∙_ → Poset a ℓ ℓposet latt = record{ isPartialOrder = isPartialOrder latt}decPoset : IsSemilattice _∙_ → Decidable _≈_ → DecPoset a ℓ ℓdecPoset latt dec = record{ isDecPartialOrder = isDecPartialOrder latt dec}totalOrder : IsSemilattice _∙_ → Selective _∙_ → TotalOrder a ℓ ℓtotalOrder latt sel = record{ isTotalOrder = isTotalOrder latt sel}decTotalOrder : IsSemilattice _∙_ → Selective _∙_ →Decidable _≈_ → DecTotalOrder a ℓ ℓdecTotalOrder latt sel dec = record{ isDecTotalOrder = isDecTotalOrder latt sel dec}
-------------------------------------------------------------------------- The Agda standard library---- Conversion of binary operators to binary relations via the left-- natural order.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Data.Product.Base using (_,_; _×_)open import Data.Sum.Base using (inj₁; inj₂; map)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Preorder; Poset; DecPoset; TotalOrder; DecTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Symmetric; Transitive; Reflexive; Antisymmetric; Total; _Respectsʳ_; _Respectsˡ_; _Respects₂_; Decidable)open import Relation.Nullary.Negation using (¬_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen import Relation.Binary.Lattice using (Infimum)module Relation.Binary.Construct.NaturalOrder.Left{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) (_∙_ : Op₂ A) whereopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_open import Algebra.Lattice.Structures _≈_-------------------------------------------------------------------------- Definitioninfix 4 _≤__≤_ : Rel A ℓx ≤ y = x ≈ (x ∙ y)-------------------------------------------------------------------------- Relational propertiesreflexive : IsMagma _∙_ → Idempotent _∙_ → _≈_ ⇒ _≤_reflexive magma idem {x} {y} x≈y = beginx ≈⟨ sym (idem x) ⟩x ∙ x ≈⟨ ∙-cong refl x≈y ⟩x ∙ y ∎where open IsMagma magma; open ≈-Reasoning setoidrefl : Symmetric _≈_ → Idempotent _∙_ → Reflexive _≤_refl sym idem {x} = sym (idem x)antisym : IsEquivalence _≈_ → Commutative _∙_ → Antisymmetric _≈_ _≤_antisym isEq comm {x} {y} x≤y y≤x = beginx ≈⟨ x≤y ⟩x ∙ y ≈⟨ comm x y ⟩y ∙ x ≈⟨ sym y≤x ⟩y ∎where open IsEquivalence isEq; open ≈-Reasoning (record { isEquivalence = isEq })total : Symmetric _≈_ → Transitive _≈_ → Selective _∙_ → Commutative _∙_ → Total _≤_total sym trans sel comm x y = map sym (λ x∙y≈y → trans (sym x∙y≈y) (comm x y)) (sel x y)trans : IsSemigroup _∙_ → Transitive _≤_trans semi {x} {y} {z} x≤y y≤z = beginx ≈⟨ x≤y ⟩x ∙ y ≈⟨ ∙-cong S.refl y≤z ⟩x ∙ (y ∙ z) ≈⟨ sym (assoc x y z) ⟩(x ∙ y) ∙ z ≈⟨ ∙-cong (sym x≤y) S.refl ⟩x ∙ z ∎where open module S = IsSemigroup semi; open ≈-Reasoning S.setoidrespʳ : IsMagma _∙_ → _≤_ Respectsʳ _≈_respʳ magma {x} {y} {z} y≈z x≤y = beginx ≈⟨ x≤y ⟩x ∙ y ≈⟨ ∙-cong M.refl y≈z ⟩x ∙ z ∎where open module M = IsMagma magma; open ≈-Reasoning M.setoidrespˡ : IsMagma _∙_ → _≤_ Respectsˡ _≈_respˡ magma {x} {y} {z} y≈z y≤x = beginz ≈⟨ sym y≈z ⟩y ≈⟨ y≤x ⟩y ∙ x ≈⟨ ∙-cong y≈z M.refl ⟩z ∙ x ∎where open module M = IsMagma magma; open ≈-Reasoning M.setoidresp₂ : IsMagma _∙_ → _≤_ Respects₂ _≈_resp₂ magma = respʳ magma , respˡ magmadec : Decidable _≈_ → Decidable _≤_dec _≟_ x y = x ≟ (x ∙ y)module _ (semi : IsSemilattice _∙_) whereprivate open module S = IsSemilattice semiopen ≈-Reasoning setoidx∙y≤x : ∀ x y → (x ∙ y) ≤ xx∙y≤x x y = beginx ∙ y ≈⟨ ∙-cong (sym (idem x)) S.refl ⟩(x ∙ x) ∙ y ≈⟨ assoc x x y ⟩x ∙ (x ∙ y) ≈⟨ comm x (x ∙ y) ⟩(x ∙ y) ∙ x ∎x∙y≤y : ∀ x y → (x ∙ y) ≤ yx∙y≤y x y = beginx ∙ y ≈⟨ ∙-cong S.refl (sym (idem y)) ⟩x ∙ (y ∙ y) ≈⟨ sym (assoc x y y) ⟩(x ∙ y) ∙ y ∎∙-presʳ-≤ : ∀ {x y} z → z ≤ x → z ≤ y → z ≤ (x ∙ y)∙-presʳ-≤ {x} {y} z z≤x z≤y = beginz ≈⟨ z≤y ⟩z ∙ y ≈⟨ ∙-cong z≤x S.refl ⟩(z ∙ x) ∙ y ≈⟨ assoc z x y ⟩z ∙ (x ∙ y) ∎infimum : Infimum _≤_ _∙_infimum x y = x∙y≤x x y , x∙y≤y x y , ∙-presʳ-≤-------------------------------------------------------------------------- StructuresisPreorder : IsBand _∙_ → IsPreorder _≈_ _≤_isPreorder band = record{ isEquivalence = isEquivalence; reflexive = reflexive isMagma idem; trans = trans isSemigroup}where open IsBand band hiding (reflexive; trans)isPartialOrder : IsSemilattice _∙_ → IsPartialOrder _≈_ _≤_isPartialOrder semilattice = record{ isPreorder = isPreorder isBand; antisym = antisym isEquivalence comm}where open IsSemilattice semilatticeisDecPartialOrder : IsSemilattice _∙_ → Decidable _≈_ →IsDecPartialOrder _≈_ _≤_isDecPartialOrder semilattice _≟_ = record{ isPartialOrder = isPartialOrder semilattice; _≟_ = _≟_; _≤?_ = dec _≟_}isTotalOrder : IsSemilattice _∙_ → Selective _∙_ → IsTotalOrder _≈_ _≤_isTotalOrder latt sel = record{ isPartialOrder = isPartialOrder latt; total = total sym S.trans sel comm}where open module S = IsSemilattice lattisDecTotalOrder : IsSemilattice _∙_ → Selective _∙_ →Decidable _≈_ → IsDecTotalOrder _≈_ _≤_isDecTotalOrder latt sel _≟_ = record{ isTotalOrder = isTotalOrder latt sel; _≟_ = _≟_; _≤?_ = dec _≟_}-------------------------------------------------------------------------- Bundlespreorder : IsBand _∙_ → Preorder a ℓ ℓpreorder band = record{ isPreorder = isPreorder band}poset : IsSemilattice _∙_ → Poset a ℓ ℓposet latt = record{ isPartialOrder = isPartialOrder latt}decPoset : IsSemilattice _∙_ → Decidable _≈_ → DecPoset a ℓ ℓdecPoset latt dec = record{ isDecPartialOrder = isDecPartialOrder latt dec}totalOrder : IsSemilattice _∙_ → Selective _∙_ → TotalOrder a ℓ ℓtotalOrder latt sel = record{ isTotalOrder = isTotalOrder latt sel}decTotalOrder : IsSemilattice _∙_ → Selective _∙_ →Decidable _≈_ → DecTotalOrder a ℓ ℓdecTotalOrder latt sel dec = record{ isDecTotalOrder = isDecTotalOrder latt sel dec}
-------------------------------------------------------------------------- The Agda standard library---- Intersection of two binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Intersection whereopen import Data.Product.Baseopen import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder; IsPartialOrder; IsStrictPartialOrder)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Antisymmetric; Decidable; _Respects_; _Respectsˡ_; _Respectsʳ_; _Respects₂_; Minimum; Maximum; Irreflexive)open import Relation.Nullary.Decidable using (yes; no; _×-dec_)privatevariablea b ℓ₁ ℓ₂ ℓ₃ : LevelA B : Set a≈ L R : Rel A ℓ₁-------------------------------------------------------------------------- Definitioninfixl 6 _∩__∩_ : REL A B ℓ₁ → REL A B ℓ₂ → REL A B (ℓ₁ ⊔ ℓ₂)L ∩ R = λ i j → L i j × R i j-------------------------------------------------------------------------- Propertiesmodule _ (L : Rel A ℓ₁) (R : Rel A ℓ₂) wherereflexive : Reflexive L → Reflexive R → Reflexive (L ∩ R)reflexive L-refl R-refl = L-refl , R-reflsymmetric : Symmetric L → Symmetric R → Symmetric (L ∩ R)symmetric L-sym R-sym = map L-sym R-symtransitive : Transitive L → Transitive R → Transitive (L ∩ R)transitive L-trans R-trans = zip L-trans R-transrespects : ∀ {p} (P : A → Set p) →P Respects L ⊎ P Respects R → P Respects (L ∩ R)respects P resp (Lxy , Rxy) = [ (λ x → x Lxy) , (λ x → x Rxy) ] respmin : ∀ {⊤} → Minimum L ⊤ → Minimum R ⊤ → Minimum (L ∩ R) ⊤min L-min R-min = < L-min , R-min >max : ∀ {⊥} → Maximum L ⊥ → Maximum R ⊥ → Maximum (L ∩ R) ⊥max L-max R-max = < L-max , R-max >module _ (≈ : REL A B ℓ₁) {L : REL A B ℓ₂} {R : REL A B ℓ₃} whereimplies : (≈ ⇒ L) → (≈ ⇒ R) → ≈ ⇒ (L ∩ R)implies ≈⇒L ≈⇒R = < ≈⇒L , ≈⇒R >module _ (≈ : REL A B ℓ₁) (L : REL A B ℓ₂) (R : REL A B ℓ₃) whereirreflexive : Irreflexive ≈ L ⊎ Irreflexive ≈ R → Irreflexive ≈ (L ∩ R)irreflexive irrefl x≈y (Lxy , Rxy) = [ (λ x → x x≈y Lxy) , (λ x → x x≈y Rxy) ] irreflmodule _ (≈ : Rel A ℓ₁) (L : Rel A ℓ₂) (R : Rel A ℓ₃) whererespectsˡ : L Respectsˡ ≈ → R Respectsˡ ≈ → (L ∩ R) Respectsˡ ≈respectsˡ L-resp R-resp x≈y = map (L-resp x≈y) (R-resp x≈y)respectsʳ : L Respectsʳ ≈ → R Respectsʳ ≈ → (L ∩ R) Respectsʳ ≈respectsʳ L-resp R-resp x≈y = map (L-resp x≈y) (R-resp x≈y)respects₂ : L Respects₂ ≈ → R Respects₂ ≈ → (L ∩ R) Respects₂ ≈respects₂ (Lʳ , Lˡ) (Rʳ , Rˡ) = respectsʳ Lʳ Rʳ , respectsˡ Lˡ Rˡantisymmetric : Antisymmetric ≈ L ⊎ Antisymmetric ≈ R → Antisymmetric ≈ (L ∩ R)antisymmetric (inj₁ L-antisym) (Lxy , _) (Lyx , _) = L-antisym Lxy Lyxantisymmetric (inj₂ R-antisym) (_ , Rxy) (_ , Ryx) = R-antisym Rxy Ryxmodule _ {L : REL A B ℓ₁} {R : REL A B ℓ₂} wheredecidable : Decidable L → Decidable R → Decidable (L ∩ R)decidable L? R? x y = L? x y ×-dec R? x y-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence L → IsEquivalence R → IsEquivalence (L ∩ R)isEquivalence {L = L} {R = R} eqₗ eqᵣ = record{ refl = reflexive L R L.refl R.refl; sym = symmetric L R L.sym R.sym; trans = transitive L R L.trans R.trans} where module L = IsEquivalence eqₗ; module R = IsEquivalence eqᵣisDecEquivalence : IsDecEquivalence L → IsDecEquivalence R → IsDecEquivalence (L ∩ R)isDecEquivalence eqₗ eqᵣ = record{ isEquivalence = isEquivalence L.isEquivalence R.isEquivalence; _≟_ = decidable L._≟_ R._≟_} where module L = IsDecEquivalence eqₗ; module R = IsDecEquivalence eqᵣisPreorder : IsPreorder ≈ L → IsPreorder ≈ R → IsPreorder ≈ (L ∩ R)isPreorder {≈ = ≈} {L = L} {R = R} Oₗ Oᵣ = record{ isEquivalence = Oₗ.isEquivalence; reflexive = implies ≈ Oₗ.reflexive Oᵣ.reflexive; trans = transitive L R Oₗ.trans Oᵣ.trans}where module Oₗ = IsPreorder Oₗ; module Oᵣ = IsPreorder OᵣisPartialOrderˡ : IsPartialOrder ≈ L → IsPreorder ≈ R → IsPartialOrder ≈ (L ∩ R)isPartialOrderˡ {≈ = ≈} {L = L} {R = R} Oₗ Oᵣ = record{ isPreorder = isPreorder Oₗ.isPreorder Oᵣ; antisym = antisymmetric ≈ L R (inj₁ Oₗ.antisym)} where module Oₗ = IsPartialOrder Oₗ; module Oᵣ = IsPreorder OᵣisPartialOrderʳ : IsPreorder ≈ L → IsPartialOrder ≈ R → IsPartialOrder ≈ (L ∩ R)isPartialOrderʳ {≈ = ≈} {L = L} {R = R} Oₗ Oᵣ = record{ isPreorder = isPreorder Oₗ Oᵣ.isPreorder; antisym = antisymmetric ≈ L R (inj₂ Oᵣ.antisym)} where module Oₗ = IsPreorder Oₗ; module Oᵣ = IsPartialOrder OᵣisStrictPartialOrderˡ : IsStrictPartialOrder ≈ L →Transitive R → R Respects₂ ≈ →IsStrictPartialOrder ≈ (L ∩ R)isStrictPartialOrderˡ {≈ = ≈} {L = L} {R = R} Oₗ transᵣ respᵣ = record{ isEquivalence = Oₗ.isEquivalence; irrefl = irreflexive ≈ L R (inj₁ Oₗ.irrefl); trans = transitive L R Oₗ.trans transᵣ; <-resp-≈ = respects₂ ≈ L R Oₗ.<-resp-≈ respᵣ} where module Oₗ = IsStrictPartialOrder OₗisStrictPartialOrderʳ : Transitive L → L Respects₂ ≈ →IsStrictPartialOrder ≈ R →IsStrictPartialOrder ≈ (L ∩ R)isStrictPartialOrderʳ {L = L} {≈ = ≈} {R = R} transₗ respₗ Oᵣ = record{ isEquivalence = Oᵣ.isEquivalence; irrefl = irreflexive ≈ L R (inj₂ Oᵣ.irrefl); trans = transitive L R transₗ Oᵣ.trans; <-resp-≈ = respects₂ ≈ L R respₗ Oᵣ.<-resp-≈} where module Oᵣ = IsStrictPartialOrder Oᵣ
-------------------------------------------------------------------------- The Agda standard library---- Symmetric interior of a binary relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Interior.Symmetric whereopen import Function.Base using (flip)open import Levelopen import Relation.Binaryprivatevariablea b c ℓ r s t : LevelA : Set aR S T : Rel A r-------------------------------------------------------------------------- Definitionrecord SymInterior (R : Rel A ℓ) (x y : A) : Set ℓ whereconstructor _,_fieldlhs≤rhs : R x yrhs≤lhs : R y xopen SymInterior public-------------------------------------------------------------------------- Properties-- The symmetric interior is symmetric.symmetric : Symmetric (SymInterior R)symmetric (r , r′) = r′ , r-- The symmetric interior of R is greater than (or equal to) any other symmetric-- relation contained by R.unfold : Symmetric S → S ⇒ R → S ⇒ SymInterior Runfold sym f s = f s , f (sym s)-- SymInterior preserves various properties.reflexive : Reflexive R → Reflexive (SymInterior R)reflexive refl = refl , refltrans : Trans R S T → Trans S R T →Trans (SymInterior R) (SymInterior S) (SymInterior T)trans trans-rs trans-sr (r , r′) (s , s′) = trans-rs r s , trans-sr s′ r′transitive : Transitive R → Transitive (SymInterior R)transitive tr = trans tr tr-- The symmetric interior of a strict relation is empty.asymmetric⇒empty : Asymmetric R → Empty (SymInterior R)asymmetric⇒empty asym (r , r′) = asym r r′-- A reflexive transitive relation _≤_ gives rise to a poset in which the-- equivalence relation is SymInterior _≤_.isEquivalence : Reflexive R → Transitive R → IsEquivalence (SymInterior R)isEquivalence refl trans = record{ refl = reflexive refl; sym = symmetric; trans = transitive trans}isPartialOrder : Reflexive R → Transitive R → IsPartialOrder (SymInterior R) RisPartialOrder refl trans = record{ isPreorder = record{ isEquivalence = isEquivalence refl trans; reflexive = lhs≤rhs; trans = trans}; antisym = _,_}poset : ∀ {a} {A : Set a} {R : Rel A ℓ} → Reflexive R → Transitive R → Poset a ℓ ℓposet {R = R} refl trans = record{ _≤_ = R; isPartialOrder = isPartialOrder refl trans}
-------------------------------------------------------------------------- The Agda standard library---- Every respectful binary relation induces a preorder. No claim is-- made that this preorder is unique.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitions using (_Respects_; Transitive)open Setoid using (Carrier)module Relation.Binary.Construct.FromRel{s₁ s₂} (S : Setoid s₁ s₂) -- The underlying equality{a r} {A : Set a} (_R_ : REL A (Carrier S) r) -- The relationwhereopen import Function.Baseopen import Level using (_⊔_)open module Eq = Setoid S using (_≈_) renaming (Carrier to B)-------------------------------------------------------------------------- DefinitionResp : Rel B (a ⊔ r)Resp x y = ∀ {a} → a R x → a R y-------------------------------------------------------------------------- Propertiesreflexive : (∀ {a} → (a R_) Respects _≈_) → _≈_ ⇒ Respreflexive resp x≈y = resp x≈ytrans : Transitive Resptrans x∼y y∼z = y∼z ∘ x∼yisPreorder : (∀ {a} → (a R_) Respects _≈_) → IsPreorder _≈_ RespisPreorder resp = record{ isEquivalence = Eq.isEquivalence; reflexive = reflexive resp; trans = trans}preorder : (∀ {a} → (a R_) Respects _≈_) → Preorder _ _ _preorder resp = record{ isPreorder = isPreorder resp}
-------------------------------------------------------------------------- The Agda standard library---- Every respectful unary relation induces a preorder. No claim is-- made that this preorder is unique.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitions using (_Respects_; Reflexive; Transitive)open import Relation.Unary using (Pred)module Relation.Binary.Construct.FromPred{s₁ s₂} (S : Setoid s₁ s₂) -- The underlying equality{p} (P : Pred (Setoid.Carrier S) p) -- The predicatewhereopen import Function.Baseopen module Eq = Setoid S using (_≈_) renaming (Carrier to A)-------------------------------------------------------------------------- DefinitionResp : Rel A pResp x y = P x → P y-------------------------------------------------------------------------- Propertiesreflexive : P Respects _≈_ → _≈_ ⇒ Respreflexive resp = resprefl : P Respects _≈_ → Reflexive Resprefl resp = resp Eq.refltrans : Transitive Resptrans x⇒y y⇒z = y⇒z ∘ x⇒yisPreorder : P Respects _≈_ → IsPreorder _≈_ RespisPreorder resp = record{ isEquivalence = Eq.isEquivalence; reflexive = reflexive resp; trans = flip _∘′_}preorder : P Respects _≈_ → Preorder _ _ _preorder resp = record{ isPreorder = isPreorder resp}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Construct.Flip.Ord` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Flip whereopen import Relation.Binary.Construct.Flip.Ord public{-# WARNING_ON_IMPORT"Relation.Binary.Construct.Flip was deprecated in v2.0.Use Relation.Binary.Construct.Flip.Ord instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Many properties which hold for `∼` also hold for `flip ∼`. Unlike-- the module `Relation.Binary.Construct.Flip.EqAndOrd` this module-- flips both the relation and the underlying equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; Poset; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Asymmetric; Total; _Respects_; _Respects₂_; Minimum; Maximum; Irreflexive; Antisymmetric; Trichotomous; Decidable)module Relation.Binary.Construct.Flip.Ord whereopen import Data.Product.Base using (_,_)open import Function.Base using (flip; _∘_)open import Level using (Level)privatevariablea b p ℓ ℓ₁ ℓ₂ : LevelA B : Set a≈ ∼ ≤ < : Rel A ℓ-------------------------------------------------------------------------- Propertiesmodule _ (∼ : Rel A ℓ) wherereflexive : Reflexive ∼ → Reflexive (flip ∼)reflexive refl = reflsymmetric : Symmetric ∼ → Symmetric (flip ∼)symmetric sym = symtransitive : Transitive ∼ → Transitive (flip ∼)transitive trans = flip transasymmetric : Asymmetric ∼ → Asymmetric (flip ∼)asymmetric asym = asymtotal : Total ∼ → Total (flip ∼)total total x y = total y xrespects : ∀ (P : A → Set p) → Symmetric ∼ →P Respects ∼ → P Respects flip ∼respects _ sym resp ∼ = resp (sym ∼)max : ∀ {⊥} → Minimum ∼ ⊥ → Maximum (flip ∼) ⊥max min = minmin : ∀ {⊤} → Maximum ∼ ⊤ → Minimum (flip ∼) ⊤min max = maxmodule _ (≈ : REL A B ℓ₁) (∼ : REL A B ℓ₂) whereimplies : ≈ ⇒ ∼ → flip ≈ ⇒ flip ∼implies impl = implirreflexive : Irreflexive ≈ ∼ → Irreflexive (flip ≈) (flip ∼)irreflexive irrefl = irreflmodule _ (≈ : Rel A ℓ₁) (∼ : Rel A ℓ₂) whereantisymmetric : Antisymmetric ≈ ∼ → Antisymmetric (flip ≈) (flip ∼)antisymmetric antisym = antisymtrichotomous : Trichotomous ≈ ∼ → Trichotomous (flip ≈) (flip ∼)trichotomous compare x y = compare y xmodule _ (∼₁ : Rel A ℓ₁) (∼₂ : Rel A ℓ₂) whererespects₂ : Symmetric ∼₂ → ∼₁ Respects₂ ∼₂ → flip ∼₁ Respects₂ flip ∼₂respects₂ sym (resp₁ , resp₂) = (resp₂ ∘ sym , resp₁ ∘ sym)module _ (∼ : REL A B ℓ) wheredecidable : Decidable ∼ → Decidable (flip ∼)decidable dec x y = dec y x-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence ≈ → IsEquivalence (flip ≈)isEquivalence {≈ = ≈} eq = record{ refl = reflexive ≈ Eq.refl; sym = symmetric ≈ Eq.sym; trans = transitive ≈ Eq.trans} where module Eq = IsEquivalence eqisDecEquivalence : IsDecEquivalence ≈ → IsDecEquivalence (flip ≈)isDecEquivalence {≈ = ≈} dec = record{ isEquivalence = isEquivalence Dec.isEquivalence; _≟_ = decidable ≈ Dec._≟_} where module Dec = IsDecEquivalence decisPreorder : IsPreorder ≈ ∼ → IsPreorder (flip ≈) (flip ∼)isPreorder {≈ = ≈} {∼ = ∼} O = record{ isEquivalence = isEquivalence O.isEquivalence; reflexive = implies ≈ ∼ O.reflexive; trans = transitive ∼ O.trans} where module O = IsPreorder OisPartialOrder : IsPartialOrder ≈ ≤ → IsPartialOrder (flip ≈) (flip ≤)isPartialOrder {≈ = ≈} {≤ = ≤} O = record{ isPreorder = isPreorder O.isPreorder; antisym = antisymmetric ≈ ≤ O.antisym} where module O = IsPartialOrder OisTotalOrder : IsTotalOrder ≈ ≤ → IsTotalOrder (flip ≈) (flip ≤)isTotalOrder {≈ = ≈} {≤ = ≤} O = record{ isPartialOrder = isPartialOrder O.isPartialOrder; total = total ≤ O.total}where module O = IsTotalOrder OisDecTotalOrder : IsDecTotalOrder ≈ ≤ → IsDecTotalOrder (flip ≈) (flip ≤)isDecTotalOrder {≈ = ≈} {≤ = ≤} O = record{ isTotalOrder = isTotalOrder O.isTotalOrder; _≟_ = decidable ≈ O._≟_; _≤?_ = decidable ≤ O._≤?_} where module O = IsDecTotalOrder OisStrictPartialOrder : IsStrictPartialOrder ≈ < →IsStrictPartialOrder (flip ≈) (flip <)isStrictPartialOrder {≈ = ≈} {< = <} O = record{ isEquivalence = isEquivalence O.isEquivalence; irrefl = irreflexive ≈ < O.irrefl; trans = transitive < O.trans; <-resp-≈ = respects₂ < ≈ O.Eq.sym O.<-resp-≈} where module O = IsStrictPartialOrder OisStrictTotalOrder : IsStrictTotalOrder ≈ < →IsStrictTotalOrder (flip ≈) (flip <)isStrictTotalOrder {≈ = ≈} {< = <} O = record{ isStrictPartialOrder = isStrictPartialOrder O.isStrictPartialOrder; compare = trichotomous ≈ < O.compare} where module O = IsStrictTotalOrder O-------------------------------------------------------------------------- Bundlessetoid : Setoid a ℓ → Setoid a ℓsetoid S = record{ _≈_ = flip S._≈_; isEquivalence = isEquivalence S.isEquivalence} where module S = Setoid SdecSetoid : DecSetoid a ℓ → DecSetoid a ℓdecSetoid S = record{ _≈_ = flip S._≈_; isDecEquivalence = isDecEquivalence S.isDecEquivalence} where module S = DecSetoid Spreorder : Preorder a ℓ₁ ℓ₂ → Preorder a ℓ₁ ℓ₂preorder O = record{ isPreorder = isPreorder O.isPreorder} where module O = Preorder Oposet : Poset a ℓ₁ ℓ₂ → Poset a ℓ₁ ℓ₂poset O = record{ isPartialOrder = isPartialOrder O.isPartialOrder} where module O = Poset OtotalOrder : TotalOrder a ℓ₁ ℓ₂ → TotalOrder a ℓ₁ ℓ₂totalOrder O = record{ isTotalOrder = isTotalOrder O.isTotalOrder} where module O = TotalOrder OdecTotalOrder : DecTotalOrder a ℓ₁ ℓ₂ → DecTotalOrder a ℓ₁ ℓ₂decTotalOrder O = record{ isDecTotalOrder = isDecTotalOrder O.isDecTotalOrder} where module O = DecTotalOrder OstrictPartialOrder : StrictPartialOrder a ℓ₁ ℓ₂ →StrictPartialOrder a ℓ₁ ℓ₂strictPartialOrder O = record{ isStrictPartialOrder = isStrictPartialOrder O.isStrictPartialOrder} where module O = StrictPartialOrder OstrictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂ →StrictTotalOrder a ℓ₁ ℓ₂strictTotalOrder O = record{ isStrictTotalOrder = isStrictTotalOrder O.isStrictTotalOrder} where module O = StrictTotalOrder O
-------------------------------------------------------------------------- The Agda standard library---- Many properties which hold for `∼` also hold for `flip ∼`. Unlike-- the module `Relation.Binary.Construct.Flip.Ord` this module does not-- flip the underlying equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; Poset; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder; TotalPreorder)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder; IsTotalPreorder)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Asymmetric; Total; _Respects_; _Respects₂_; Minimum; Maximum; Irreflexive; Antisymmetric; Trichotomous; Decidable; tri<; tri>; tri≈)module Relation.Binary.Construct.Flip.EqAndOrd whereopen import Data.Product.Base using (_,_)open import Function.Base using (flip; _∘_)open import Level using (Level)privatevariablea b p ℓ ℓ₁ ℓ₂ : LevelA B : Set a≈ ∼ ≤ < : Rel A ℓ-------------------------------------------------------------------------- Propertiesmodule _ (∼ : Rel A ℓ) whererefl : Reflexive ∼ → Reflexive (flip ∼)refl refl = reflsym : Symmetric ∼ → Symmetric (flip ∼)sym sym = symtrans : Transitive ∼ → Transitive (flip ∼)trans trans = flip transasym : Asymmetric ∼ → Asymmetric (flip ∼)asym asym = asymtotal : Total ∼ → Total (flip ∼)total total x y = total y xresp : ∀ {p} (P : A → Set p) → Symmetric ∼ →P Respects ∼ → P Respects (flip ∼)resp _ sym resp ∼ = resp (sym ∼)max : ∀ {⊥} → Minimum ∼ ⊥ → Maximum (flip ∼) ⊥max min = minmin : ∀ {⊤} → Maximum ∼ ⊤ → Minimum (flip ∼) ⊤min max = maxmodule _ {≈ : Rel A ℓ₁} (∼ : Rel A ℓ₂) wherereflexive : Symmetric ≈ → (≈ ⇒ ∼) → (≈ ⇒ flip ∼)reflexive sym impl = impl ∘ symirrefl : Symmetric ≈ → Irreflexive ≈ ∼ → Irreflexive ≈ (flip ∼)irrefl sym irrefl x≈y y∼x = irrefl (sym x≈y) y∼xantisym : Antisymmetric ≈ ∼ → Antisymmetric ≈ (flip ∼)antisym antisym = flip antisymcompare : Trichotomous ≈ ∼ → Trichotomous ≈ (flip ∼)compare cmp x y with cmp x y... | tri< x<y x≉y y≮x = tri> y≮x x≉y x<y... | tri≈ x≮y x≈y y≮x = tri≈ y≮x x≈y x≮y... | tri> x≮y x≉y y<x = tri< y<x x≉y x≮ymodule _ (∼₁ : Rel A ℓ₁) (∼₂ : Rel A ℓ₂) whereresp₂ : ∼₁ Respects₂ ∼₂ → (flip ∼₁) Respects₂ ∼₂resp₂ (resp₁ , resp₂) = resp₂ , resp₁module _ (∼ : REL A B ℓ) wheredec : Decidable ∼ → Decidable (flip ∼)dec dec = flip dec-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence ≈ → IsEquivalence (flip ≈)isEquivalence {≈ = ≈} eq = record{ refl = refl ≈ Eq.refl; sym = sym ≈ Eq.sym; trans = trans ≈ Eq.trans} where module Eq = IsEquivalence eqisDecEquivalence : IsDecEquivalence ≈ → IsDecEquivalence (flip ≈)isDecEquivalence {≈ = ≈} eq = record{ isEquivalence = isEquivalence Dec.isEquivalence; _≟_ = dec ≈ Dec._≟_} where module Dec = IsDecEquivalence eqisPreorder : IsPreorder ≈ ∼ → IsPreorder ≈ (flip ∼)isPreorder {≈ = ≈} {∼ = ∼} O = record{ isEquivalence = O.isEquivalence; reflexive = reflexive ∼ O.Eq.sym O.reflexive; trans = trans ∼ O.trans} where module O = IsPreorder OisTotalPreorder : IsTotalPreorder ≈ ∼ → IsTotalPreorder ≈ (flip ∼)isTotalPreorder O = record{ isPreorder = isPreorder O.isPreorder; total = total _ O.total} where module O = IsTotalPreorder OisPartialOrder : IsPartialOrder ≈ ≤ → IsPartialOrder ≈ (flip ≤)isPartialOrder {≤ = ≤} O = record{ isPreorder = isPreorder O.isPreorder; antisym = antisym ≤ O.antisym} where module O = IsPartialOrder OisTotalOrder : IsTotalOrder ≈ ≤ → IsTotalOrder ≈ (flip ≤)isTotalOrder O = record{ isPartialOrder = isPartialOrder O.isPartialOrder; total = total _ O.total} where module O = IsTotalOrder OisDecTotalOrder : IsDecTotalOrder ≈ ≤ → IsDecTotalOrder ≈ (flip ≤)isDecTotalOrder O = record{ isTotalOrder = isTotalOrder O.isTotalOrder; _≟_ = O._≟_; _≤?_ = dec _ O._≤?_} where module O = IsDecTotalOrder OisStrictPartialOrder : IsStrictPartialOrder ≈ < →IsStrictPartialOrder ≈ (flip <)isStrictPartialOrder {< = <} O = record{ isEquivalence = O.isEquivalence; irrefl = irrefl < O.Eq.sym O.irrefl; trans = trans < O.trans; <-resp-≈ = resp₂ _ _ O.<-resp-≈} where module O = IsStrictPartialOrder OisStrictTotalOrder : IsStrictTotalOrder ≈ < →IsStrictTotalOrder ≈ (flip <)isStrictTotalOrder {< = <} O = record{ isStrictPartialOrder = isStrictPartialOrder O.isStrictPartialOrder; compare = compare _ O.compare} where module O = IsStrictTotalOrder O-------------------------------------------------------------------------- Bundlessetoid : Setoid a ℓ → Setoid a ℓsetoid S = record{ isEquivalence = isEquivalence S.isEquivalence} where module S = Setoid SdecSetoid : DecSetoid a ℓ → DecSetoid a ℓdecSetoid S = record{ isDecEquivalence = isDecEquivalence S.isDecEquivalence} where module S = DecSetoid Spreorder : Preorder a ℓ₁ ℓ₂ → Preorder a ℓ₁ ℓ₂preorder O = record{ isPreorder = isPreorder O.isPreorder} where module O = Preorder OtotalPreorder : TotalPreorder a ℓ₁ ℓ₂ → TotalPreorder a ℓ₁ ℓ₂totalPreorder O = record{ isTotalPreorder = isTotalPreorder O.isTotalPreorder} where module O = TotalPreorder Oposet : Poset a ℓ₁ ℓ₂ → Poset a ℓ₁ ℓ₂poset O = record{ isPartialOrder = isPartialOrder O.isPartialOrder} where module O = Poset OtotalOrder : TotalOrder a ℓ₁ ℓ₂ → TotalOrder a ℓ₁ ℓ₂totalOrder O = record{ isTotalOrder = isTotalOrder O.isTotalOrder} where module O = TotalOrder OdecTotalOrder : DecTotalOrder a ℓ₁ ℓ₂ → DecTotalOrder a ℓ₁ ℓ₂decTotalOrder O = record{ isDecTotalOrder = isDecTotalOrder O.isDecTotalOrder} where module O = DecTotalOrder OstrictPartialOrder : StrictPartialOrder a ℓ₁ ℓ₂ →StrictPartialOrder a ℓ₁ ℓ₂strictPartialOrder O = record{ isStrictPartialOrder = isStrictPartialOrder O.isStrictPartialOrder} where module O = StrictPartialOrder OstrictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂ →StrictTotalOrder a ℓ₁ ℓ₂strictTotalOrder O = record{ isStrictTotalOrder = isStrictTotalOrder O.isStrictTotalOrder} where module O = StrictTotalOrder O
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Relation.Binary.Construct.Flip.EqAndOrd` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Converse whereopen import Relation.Binary.Construct.Flip.EqAndOrd public{-# WARNING_ON_IMPORT"Relation.Binary.Construct.Converse was deprecated in v2.0.Use Relation.Binary.Construct.Flip.EqAndOrd instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The binary relation defined by a constant------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Constant whereopen import Levelopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)privatevariablea b c : LevelA : Set aB : Set b-------------------------------------------------------------------------- Re-export definitionopen import Relation.Binary.Construct.Constant.Core public-------------------------------------------------------------------------- Propertiesmodule _ {a c} (A : Set a) {C : Set c} whererefl : C → Reflexive {A = A} (Const C)refl c = csym : Symmetric {A = A} (Const C)sym c = ctrans : Transitive {A = A} (Const C)trans c d = cisEquivalence : C → IsEquivalence {A = A} (Const C)isEquivalence c = record{ refl = λ {x} → refl c {x}; sym = λ {x} {y} → sym {x} {y}; trans = λ {x} {y} {z} → trans {x} {y} {z}}setoid : C → Setoid a csetoid x = record { isEquivalence = isEquivalence x }
-------------------------------------------------------------------------- The Agda standard library---- The binary relation defined by a constant------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Constant.Core whereopen import Levelopen import Relation.Binary.Core using (REL)privatevariablea b c : LevelA : Set aB : Set b-------------------------------------------------------------------------- DefinitionConst : Set c → REL A B cConst I = λ _ _ → I
-------------------------------------------------------------------------- The Agda standard library---- Composition of two binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Composition whereopen import Data.Product.Base using (∃; _×_; _,_)open import Function.Baseopen import Levelopen import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitionsusing (_Respects_; _Respectsʳ_; _Respectsˡ_; _Respects₂_; Reflexive; Transitive)privatevariablea b c ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitioninfixr 9 _;__;_ : {A : Set a} {B : Set b} {C : Set c} →REL A B ℓ₁ → REL B C ℓ₂ → REL A C (b ⊔ ℓ₁ ⊔ ℓ₂)L ; R = λ i j → ∃ λ k → L i k × R k j-------------------------------------------------------------------------- Propertiesmodule _ (L : Rel A ℓ₁) (R : Rel A ℓ₂) wherereflexive : Reflexive L → Reflexive R → Reflexive (L ; R)reflexive L-refl R-refl = _ , L-refl , R-reflrespects : ∀ {p} {P : A → Set p} →P Respects L → P Respects R → P Respects (L ; R)respects resp-L resp-R (k , Lik , Rkj) = resp-R Rkj ∘ resp-L Likmodule _ {≈ : Rel A ℓ} (L : REL A B ℓ₁) (R : REL B C ℓ₂) whererespectsˡ : L Respectsˡ ≈ → (L ; R) Respectsˡ ≈respectsˡ Lˡ i≈i′ (k , Lik , Rkj) = k , Lˡ i≈i′ Lik , Rkjmodule _ {≈ : Rel C ℓ} (L : REL A B ℓ₁) (R : REL B C ℓ₂) whererespectsʳ : R Respectsʳ ≈ → (L ; R) Respectsʳ ≈respectsʳ Rʳ j≈j′ (k , Lik , Rkj) = k , Lik , Rʳ j≈j′ Rkjmodule _ {≈ : Rel A ℓ} (L : REL A B ℓ₁) (R : REL B A ℓ₂) whererespects₂ : L Respectsˡ ≈ → R Respectsʳ ≈ → (L ; R) Respects₂ ≈respects₂ Lˡ Rʳ = respectsʳ L R Rʳ , respectsˡ L R Lˡmodule _ {≈ : REL A B ℓ} (L : REL A B ℓ₁) (R : Rel B ℓ₂) whereimpliesˡ : Reflexive R → (≈ ⇒ L) → (≈ ⇒ L ; R)impliesˡ R-refl ≈⇒L {i} {j} i≈j = j , ≈⇒L i≈j , R-reflmodule _ {≈ : REL A B ℓ} (L : Rel A ℓ₁) (R : REL A B ℓ₂) whereimpliesʳ : Reflexive L → (≈ ⇒ R) → (≈ ⇒ L ; R)impliesʳ L-refl ≈⇒R {i} {j} i≈j = i , L-refl , ≈⇒R i≈jmodule _ (L : Rel A ℓ₁) (R : Rel A ℓ₂) (comm : R ; L ⇒ L ; R) wheretransitive : Transitive L → Transitive R → Transitive (L ; R)transitive L-trans R-trans {i} {j} {k} (x , Lix , Rxj) (y , Ljy , Ryk) =let z , Lxz , Rzy = comm (j , Rxj , Ljy) in z , L-trans Lix Lxz , R-trans Rzy RykisPreorder : {≈ : Rel A ℓ} → IsPreorder ≈ L → IsPreorder ≈ R → IsPreorder ≈ (L ; R)isPreorder Oˡ Oʳ = record{ isEquivalence = Oˡ.isEquivalence; reflexive = impliesˡ L R Oʳ.refl Oˡ.reflexive; trans = transitive Oˡ.trans Oʳ.trans}where module Oˡ = IsPreorder Oˡ; module Oʳ = IsPreorder Oʳtransitive⇒≈;≈⊆≈ : (≈ : Rel A ℓ) → Transitive ≈ → (≈ ; ≈) ⇒ ≈transitive⇒≈;≈⊆≈ _ trans (_ , l , r) = trans l r
-------------------------------------------------------------------------- The Agda standard library---- Transitive closures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.Transitive whereopen import Function.Baseopen import Function.Bundles using (_⇔_; mk⇔)open import Induction.WellFoundedopen import Levelopen import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea ℓ ℓ₁ ℓ₂ : LevelA B : Set a-------------------------------------------------------------------------- Definitioninfixr 5 _∷_infix 4 TransClosuredata TransClosure {A : Set a} (_∼_ : Rel A ℓ) : Rel A (a ⊔ ℓ) where[_] : ∀ {x y} (x∼y : x ∼ y) → TransClosure _∼_ x y_∷_ : ∀ {x y z} (x∼y : x ∼ y) (y∼⁺z : TransClosure _∼_ y z) → TransClosure _∼_ x zsyntax TransClosure R x y = x ⟨ R ⟩⁺ y-------------------------------------------------------------------------- Operationsmodule _ {_∼_ : Rel A ℓ} whereprivate_∼⁺_ = TransClosure _∼_infixr 5 _∷ʳ__∷ʳ_ : ∀ {x y z} → (x∼⁺y : x ∼⁺ y) (y∼z : y ∼ z) → x ∼⁺ z[ x∼y ] ∷ʳ y∼z = x∼y ∷ [ y∼z ](x∼y ∷ x∼⁺y) ∷ʳ y∼z = x∼y ∷ (x∼⁺y ∷ʳ y∼z)infixr 5 _++__++_ : ∀ {x y z} → x ∼⁺ y → y ∼⁺ z → x ∼⁺ z[ x∼y ] ++ y∼⁺z = x∼y ∷ y∼⁺z(x∼y ∷ y∼⁺z) ++ z∼⁺u = x∼y ∷ (y∼⁺z ++ z∼⁺u)-------------------------------------------------------------------------- Propertiesmodule _ (_∼_ : Rel A ℓ) whereprivate_∼⁺_ = TransClosure _∼_module ∼⊆∼⁺ = Subrelation {_<₂_ = _∼⁺_} [_]reflexive : Reflexive _∼_ → Reflexive _∼⁺_reflexive refl = [ refl ]symmetric : Symmetric _∼_ → Symmetric _∼⁺_symmetric sym [ x∼y ] = [ sym x∼y ]symmetric sym (x∼y ∷ y∼⁺z) = symmetric sym y∼⁺z ∷ʳ sym x∼ytransitive : Transitive _∼⁺_transitive = _++_transitive⁻ : Transitive _∼_ → _∼⁺_ ⇒ _∼_transitive⁻ trans [ x∼y ] = x∼ytransitive⁻ trans (x∼y ∷ x∼⁺y) = trans x∼y (transitive⁻ trans x∼⁺y)accessible⁻ : ∀ {x} → Acc _∼⁺_ x → Acc _∼_ xaccessible⁻ = ∼⊆∼⁺.accessiblewellFounded⁻ : WellFounded _∼⁺_ → WellFounded _∼_wellFounded⁻ = ∼⊆∼⁺.wellFoundedaccessible : ∀ {x} → Acc _∼_ x → Acc _∼⁺_ xaccessible acc[x] = acc (wf-acc acc[x])wherewf-acc : ∀ {x} → Acc _∼_ x → WfRec _∼⁺_ (Acc _∼⁺_) xwf-acc (acc rec) [ y∼x ] = acc (wf-acc (rec y∼x))wf-acc acc[x] (y∼z ∷ z∼⁺x) = acc-inverse (wf-acc acc[x] z∼⁺x) [ y∼z ]wellFounded : WellFounded _∼_ → WellFounded _∼⁺_wellFounded wf x = accessible (wf x)-------------------------------------------------------------------------- Alternative definition of transitive closureinfix 4 Plussyntax Plus R x y = x [ R ]⁺ ydata Plus {A : Set a} (_∼_ : Rel A ℓ) : Rel A (a ⊔ ℓ) where[_] : ∀ {x y} (x∼y : x ∼ y) → x [ _∼_ ]⁺ y_∼⁺⟨_⟩_ : ∀ x {y z} (x∼⁺y : x [ _∼_ ]⁺ y) (y∼⁺z : y [ _∼_ ]⁺ z) →x [ _∼_ ]⁺ zmodule _ {_∼_ : Rel A ℓ} where[]-injective : ∀ {x y p q} → (x [ _∼_ ]⁺ y ∋ [ p ]) ≡ [ q ] → p ≡ q[]-injective ≡.refl = ≡.refl-- See also ∼⁺⟨⟩-injectiveˡ and ∼⁺⟨⟩-injectiveʳ in-- Relation.Binary.Construct.Closure.Transitive.WithK.-- "Equational" reasoning notation. Example:---- lemma =-- x ∼⁺⟨ [ lemma₁ ] ⟩-- y ∼⁺⟨ lemma₂ ⟩∎-- z ∎finally : ∀ {_∼_ : Rel A ℓ} x y → x [ _∼_ ]⁺ y → x [ _∼_ ]⁺ yfinally _ _ = idsyntax finally x y x∼⁺y = x ∼⁺⟨ x∼⁺y ⟩∎ y ∎infixr 2 _∼⁺⟨_⟩_infix 3 finally-- Map.map : {_R₁_ : Rel A ℓ} {_R₂_ : Rel B ℓ₂} {f : A → B} →_R₁_ =[ f ]⇒ _R₂_ → Plus _R₁_ =[ f ]⇒ Plus _R₂_map R₁⇒R₂ [ xRy ] = [ R₁⇒R₂ xRy ]map R₁⇒R₂ (x ∼⁺⟨ xR⁺z ⟩ zR⁺y) =_ ∼⁺⟨ map R₁⇒R₂ xR⁺z ⟩ map R₁⇒R₂ zR⁺y-- Plus and TransClosure are equivalent.equivalent : ∀ {_∼_ : Rel A ℓ} {x y} →Plus _∼_ x y ⇔ TransClosure _∼_ x yequivalent {_∼_ = _∼_} = mk⇔ complete soundwherecomplete : Plus _∼_ ⇒ TransClosure _∼_complete [ x∼y ] = [ x∼y ]complete (x ∼⁺⟨ x∼⁺y ⟩ y∼⁺z) = complete x∼⁺y ++ complete y∼⁺zsound : TransClosure _∼_ ⇒ Plus _∼_sound [ x∼y ] = [ x∼y ]sound (x∼y ∷ y∼⁺z) = _ ∼⁺⟨ [ x∼y ] ⟩ sound y∼⁺z-------------------------------------------------------------------------- Deprecations-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- v1.5Plus′ = TransClosure{-# WARNING_ON_USAGE Plus′"Warning: Plus′ was deprecated in v1.5.Please use TransClosure instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some code related to transitive closures that relies on the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Relation.Binary.Construct.Closure.Transitive.WithK whereopen import Function.Base using (_∋_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Closure.Transitiveopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)module _ {a ℓ} {A : Set a} {_∼_ : Rel A ℓ} where∼⁺⟨⟩-injectiveˡ : ∀ {x y z} {p r : x [ _∼_ ]⁺ y} {q s} →(x [ _∼_ ]⁺ z ∋ x ∼⁺⟨ p ⟩ q) ≡ (x ∼⁺⟨ r ⟩ s) → p ≡ r∼⁺⟨⟩-injectiveˡ refl = refl∼⁺⟨⟩-injectiveʳ : ∀ {x y z} {p r : x [ _∼_ ]⁺ y} {q s} →(x [ _∼_ ]⁺ z ∋ x ∼⁺⟨ p ⟩ q) ≡ (x ∼⁺⟨ r ⟩ s) → q ≡ s∼⁺⟨⟩-injectiveʳ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Symmetric transitive closures of binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.SymmetricTransitive whereopen import Levelopen import Function.Baseopen import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Bundles using (PartialSetoid; Setoid)open import Relation.Binary.Structuresusing (IsPartialEquivalence; IsEquivalence)open import Relation.Binary.Definitionsusing (Transitive; Symmetric; Reflexive)privatevariablea c ℓ ℓ′ : LevelA B : Set amodule _ {A : Set a} (_≤_ : Rel A ℓ) wheredata Plus⇔ : Rel A (a ⊔ ℓ) whereforth : ∀ {x y} → x ≤ y → Plus⇔ x yback : ∀ {x y} → y ≤ x → Plus⇔ x yforth⁺ : ∀ {x y z} → x ≤ y → Plus⇔ y z → Plus⇔ x zback⁺ : ∀ {x y z} → y ≤ x → Plus⇔ y z → Plus⇔ x ztrans : Transitive Plus⇔trans (forth r) rel′ = forth⁺ r rel′trans (back r) rel′ = back⁺ r rel′trans (forth⁺ r rel) rel′ = forth⁺ r (trans rel rel′)trans (back⁺ r rel) rel′ = back⁺ r (trans rel rel′)sym : Symmetric Plus⇔sym (forth r) = back rsym (back r) = forth rsym (forth⁺ r rel) = trans (sym rel) (back r)sym (back⁺ r rel) = trans (sym rel) (forth r)isPartialEquivalence : IsPartialEquivalence Plus⇔isPartialEquivalence = record{ sym = sym; trans = trans}partialSetoid : PartialSetoid _ _partialSetoid = record{ Carrier = A; _≈_ = Plus⇔; isPartialEquivalence = isPartialEquivalence}module _ (refl : Reflexive _≤_) whereisEquivalence : IsEquivalence Plus⇔isEquivalence = record{ refl = forth refl; sym = sym; trans = trans}setoid : Setoid _ _setoid = record{ Carrier = A; _≈_ = Plus⇔; isEquivalence = isEquivalence}module _ (S : Setoid c ℓ) whereprivatemodule S = Setoid Sminimal : (f : A → S.Carrier) →_≤_ =[ f ]⇒ S._≈_ →Plus⇔ =[ f ]⇒ S._≈_minimal f inj (forth r) = inj rminimal f inj (back r) = S.sym (inj r)minimal f inj (forth⁺ r rel) = S.trans (inj r) (minimal f inj rel)minimal f inj (back⁺ r rel) = S.trans (S.sym (inj r)) (minimal f inj rel)module Plus⇔Reasoning (_≤_ : Rel A ℓ) whereinfix 3 forth-syntax back-syntaxinfixr 2 forth⁺-syntax back⁺-syntaxforth-syntax : ∀ x y → x ≤ y → Plus⇔ _≤_ x yforth-syntax _ _ = forthsyntax forth-syntax x y x≤y = x ⇒⟨ x≤y ⟩∎ y ∎back-syntax : ∀ x y → y ≤ x → Plus⇔ _≤_ x yback-syntax _ _ = backsyntax back-syntax x y y≤x = x ⇐⟨ y≤x ⟩∎ y ∎forth⁺-syntax : ∀ x {y z} → x ≤ y → Plus⇔ _≤_ y z → Plus⇔ _≤_ x zforth⁺-syntax _ = forth⁺syntax forth⁺-syntax x x≤y y⇔z = x ⇒⟨ x≤y ⟩ y⇔zback⁺-syntax : ∀ x {y z} → y ≤ x → Plus⇔ _≤_ y z → Plus⇔ _≤_ x zback⁺-syntax _ = back⁺syntax back⁺-syntax x y≤x y⇔z = x ⇐⟨ y≤x ⟩ y⇔zmodule _ {_≤_ : Rel A ℓ} {_≼_ : Rel B ℓ′} wheregmap : (f : A → B) (inj : _≤_ =[ f ]⇒ _≼_) → Plus⇔ _≤_ =[ f ]⇒ Plus⇔ _≼_gmap f inj (forth r) = forth (inj r)gmap f inj (back r) = back (inj r)gmap f inj (forth⁺ r rel) = forth⁺ (inj r) (gmap f inj rel)gmap f inj (back⁺ r rel) = back⁺ (inj r) (gmap f inj rel)map : {_≤_ : Rel A ℓ} {_≼_ : Rel A ℓ′} (inj : _≤_ ⇒ _≼_) → Plus⇔ _≤_ ⇒ Plus⇔ _≼_map = gmap id
-------------------------------------------------------------------------- The Agda standard library---- Symmetric closures of binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.Symmetric whereopen import Function.Base using (id; _on_)open import Level using (Level)open import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Definitions using (Symmetric)import Relation.Binary.Construct.On as Onprivatevariablea ℓ ℓ₁ ℓ₂ : LevelA B : Set aR S : Rel A ℓ-------------------------------------------------------------------------- Definitiondata SymClosure {A : Set a} (R : Rel A ℓ) (a b : A) : Set ℓ wherefwd : R a b → SymClosure R a bbwd : R b a → SymClosure R a b-------------------------------------------------------------------------- Properties-- Symmetric closures are symmetric.symmetric : (R : Rel A ℓ) → Symmetric (SymClosure R)symmetric _ (fwd aRb) = bwd aRbsymmetric _ (bwd bRa) = fwd bRa-------------------------------------------------------------------------- Operations-- A generalised variant of `map` which allows the index type to change.gmap : (f : A → B) → R =[ f ]⇒ S → SymClosure R =[ f ]⇒ SymClosure Sgmap _ g (fwd aRb) = fwd (g aRb)gmap _ g (bwd bRa) = bwd (g bRa)map : R ⇒ S → SymClosure R ⇒ SymClosure Smap = gmap idfold : Symmetric S → R ⇒ S → SymClosure R ⇒ Sfold S-sym R⇒S (fwd aRb) = R⇒S aRbfold S-sym R⇒S (bwd bRa) = S-sym (R⇒S bRa)-- A generalised variant of `fold`.gfold : Symmetric S → (f : A → B) → R =[ f ]⇒ S → SymClosure R =[ f ]⇒ Sgfold {S = S} S-sym f R⇒S = fold (On.symmetric f S S-sym) R⇒S-- `return` could also be called `singleton`.return : R ⇒ SymClosure Rreturn = fwd-- `join` could also be called `concat`.join : SymClosure (SymClosure R) ⇒ SymClosure Rjoin = fold (symmetric _) idinfix 10 _⋆_⋆ : R ⇒ SymClosure S → SymClosure R ⇒ SymClosure S_⋆ f m = join (map f m)
-------------------------------------------------------------------------- The Agda standard library---- The reflexive transitive closures of McBride, Norell and Jansson------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.ReflexiveTransitive whereopen import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Definitionsusing (Transitive; Trans; Sym; TransFlip; Reflexive)open import Function.Baseopen import Level using (_⊔_)infixr 5 _◅_-- Reflexive transitive closure.data Star {i t} {I : Set i} (T : Rel I t) : Rel I (i ⊔ t) whereε : Reflexive (Star T)_◅_ : ∀ {i j k} (x : T i j) (xs : Star T j k) → Star T i k-- The type of _◅_ is Trans T (Star T) (Star T); The-- definition is expanded in order to be able to name-- the arguments (x and xs).-- Append/transitivity.infixr 5 _◅◅__◅◅_ : ∀ {i t} {I : Set i} {T : Rel I t} → Transitive (Star T)ε ◅◅ ys = ys(x ◅ xs) ◅◅ ys = x ◅ (xs ◅◅ ys)-- Sometimes you want to view cons-lists as snoc-lists. Then the-- following "constructor" is handy. Note that this is _not_ snoc for-- cons-lists, it is just a synonym for cons (with a different-- argument order).infixl 5 _▻__▻_ : ∀ {i t} {I : Set i} {T : Rel I t} {i j k} →Star T j k → T i j → Star T i k_▻_ = flip _◅_-- A corresponding variant of append.infixr 5 _▻▻__▻▻_ : ∀ {i t} {I : Set i} {T : Rel I t} {i j k} →Star T j k → Star T i j → Star T i k_▻▻_ = flip _◅◅_-- A generalised variant of map which allows the index type to change.gmap : ∀ {i j t u} {I : Set i} {T : Rel I t} {J : Set j} {U : Rel J u} →(f : I → J) → T =[ f ]⇒ U → Star T =[ f ]⇒ Star Ugmap f g ε = εgmap f g (x ◅ xs) = g x ◅ gmap f g xsmap : ∀ {i t u} {I : Set i} {T : Rel I t} {U : Rel I u} →T ⇒ U → Star T ⇒ Star Umap = gmap id-- A generalised variant of fold.gfold : ∀ {i j t p} {I : Set i} {J : Set j} {T : Rel I t}(f : I → J) (P : Rel J p) →Trans T (P on f) (P on f) →TransFlip (Star T) (P on f) (P on f)gfold f P _⊕_ ∅ ε = ∅gfold f P _⊕_ ∅ (x ◅ xs) = x ⊕ gfold f P _⊕_ ∅ xsfold : ∀ {i t p} {I : Set i} {T : Rel I t} (P : Rel I p) →Trans T P P → Reflexive P → Star T ⇒ Pfold P _⊕_ ∅ = gfold id P _⊕_ ∅gfoldl : ∀ {i j t p} {I : Set i} {J : Set j} {T : Rel I t}(f : I → J) (P : Rel J p) →Trans (P on f) T (P on f) →Trans (P on f) (Star T) (P on f)gfoldl f P _⊕_ ∅ ε = ∅gfoldl f P _⊕_ ∅ (x ◅ xs) = gfoldl f P _⊕_ (∅ ⊕ x) xsfoldl : ∀ {i t p} {I : Set i} {T : Rel I t} (P : Rel I p) →Trans P T P → Reflexive P → Star T ⇒ Pfoldl P _⊕_ ∅ = gfoldl id P _⊕_ ∅concat : ∀ {i t} {I : Set i} {T : Rel I t} → Star (Star T) ⇒ Star Tconcat {T = T} = fold (Star T) _◅◅_ ε-- If the underlying relation is symmetric, then the reflexive-- transitive closure is also symmetric.revApp : ∀ {i t u} {I : Set i} {T : Rel I t} {U : Rel I u} →Sym T U → ∀ {i j k} → Star T j i → Star U j k → Star U i krevApp rev ε ys = ysrevApp rev (x ◅ xs) ys = revApp rev xs (rev x ◅ ys)reverse : ∀ {i t u} {I : Set i} {T : Rel I t} {U : Rel I u} →Sym T U → Sym (Star T) (Star U)reverse rev xs = revApp rev xs ε-- Reflexive transitive closures form a (generalised) monad.-- return could also be called singleton.return : ∀ {i t} {I : Set i} {T : Rel I t} → T ⇒ Star Treturn x = x ◅ ε-- A generalised variant of the Kleisli star (flip bind, or-- concatMap).kleisliStar : ∀ {i j t u}{I : Set i} {J : Set j} {T : Rel I t} {U : Rel J u}(f : I → J) → T =[ f ]⇒ Star U → Star T =[ f ]⇒ Star UkleisliStar f g = concat ∘′ gmap f ginfix 10 _⋆_⋆ : ∀ {i t u} {I : Set i} {T : Rel I t} {U : Rel I u} →T ⇒ Star U → Star T ⇒ Star U_⋆ = kleisliStar idinfixl 1 _>>=__>>=_ : ∀ {i t u} {I : Set i} {T : Rel I t} {U : Rel I u} {j k} →Star T j k → T ⇒ Star U → Star U j km >>= f = (f ⋆) m-- Note that the monad-like structure above is not an indexed monad-- (as defined in Effect.Monad.Indexed). If it were, then _>>=_-- would have a type similar to---- ∀ {I} {T U : Rel I t} {i j k} →-- Star T i j → (T i j → Star U j k) → Star U i k.-- ^^^^^-- Note, however, that there is no scope for applying T to any indices-- in the definition used in Effect.Monad.Indexed.
-------------------------------------------------------------------------- The Agda standard library---- Some properties of reflexive transitive closures.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.ReflexiveTransitive.Properties whereopen import Function.Base using (id; _∘_; _$_)open import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Bundles using (Preorder)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitions using (Transitive; Reflexive)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveopen import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; refl; sym; cong; cong₂)import Relation.Binary.PropositionalEquality.Properties as ≡import Relation.Binary.Reasoning.Preorder as ≲-Reasoningopen import Relation.Binary.Reasoning.Syntax-------------------------------------------------------------------------- _◅◅_module _ {i t} {I : Set i} {T : Rel I t} where◅◅-assoc : ∀ {i j k l}(xs : Star T i j) (ys : Star T j k) (zs : Star T k l) →(xs ◅◅ ys) ◅◅ zs ≡ xs ◅◅ (ys ◅◅ zs)◅◅-assoc ε ys zs = refl◅◅-assoc (x ◅ xs) ys zs = cong (_◅_ x) (◅◅-assoc xs ys zs)-------------------------------------------------------------------------- gmapgmap-id : ∀ {i t} {I : Set i} {T : Rel I t} {i j} (xs : Star T i j) →gmap id id xs ≡ xsgmap-id ε = reflgmap-id (x ◅ xs) = cong (_◅_ x) (gmap-id xs)gmap-∘ : ∀ {i t} {I : Set i} {T : Rel I t}{j u} {J : Set j} {U : Rel J u}{k v} {K : Set k} {V : Rel K v}(f : J → K) (g : U =[ f ]⇒ V)(f′ : I → J) (g′ : T =[ f′ ]⇒ U){i j} (xs : Star T i j) →(gmap {U = V} f g ∘ gmap f′ g′) xs ≡ gmap (f ∘ f′) (g ∘ g′) xsgmap-∘ f g f′ g′ ε = reflgmap-∘ f g f′ g′ (x ◅ xs) = cong (_◅_ (g (g′ x))) (gmap-∘ f g f′ g′ xs)gmap-◅◅ : ∀ {i t j u}{I : Set i} {T : Rel I t} {J : Set j} {U : Rel J u}(f : I → J) (g : T =[ f ]⇒ U){i j k} (xs : Star T i j) (ys : Star T j k) →gmap {U = U} f g (xs ◅◅ ys) ≡ gmap f g xs ◅◅ gmap f g ysgmap-◅◅ f g ε ys = reflgmap-◅◅ f g (x ◅ xs) ys = cong (_◅_ (g x)) (gmap-◅◅ f g xs ys)gmap-cong : ∀ {i t j u}{I : Set i} {T : Rel I t} {J : Set j} {U : Rel J u}(f : I → J) (g : T =[ f ]⇒ U) (g′ : T =[ f ]⇒ U) →(∀ {i j} (x : T i j) → g x ≡ g′ x) →∀ {i j} (xs : Star T i j) →gmap {U = U} f g xs ≡ gmap f g′ xsgmap-cong f g g′ eq ε = reflgmap-cong f g g′ eq (x ◅ xs) = cong₂ _◅_ (eq x) (gmap-cong f g g′ eq xs)-------------------------------------------------------------------------- foldfold-◅◅ : ∀ {i p} {I : Set i}(P : Rel I p) (_⊕_ : Transitive P) (∅ : Reflexive P) →(∀ {i j} (x : P i j) → (∅ ⊕ x) ≡ x) →(∀ {i j k l} (x : P i j) (y : P j k) (z : P k l) →((x ⊕ y) ⊕ z) ≡ (x ⊕ (y ⊕ z))) →∀ {i j k} (xs : Star P i j) (ys : Star P j k) →fold P _⊕_ ∅ (xs ◅◅ ys) ≡ (fold P _⊕_ ∅ xs ⊕ fold P _⊕_ ∅ ys)fold-◅◅ P _⊕_ ∅ left-unit assoc ε ys = sym (left-unit _)fold-◅◅ P _⊕_ ∅ left-unit assoc (x ◅ xs) ys = begin(x ⊕ fold P _⊕_ ∅ (xs ◅◅ ys)) ≡⟨ cong (_⊕_ x) $fold-◅◅ P _⊕_ ∅ left-unit assoc xs ys ⟩(x ⊕ (fold P _⊕_ ∅ xs ⊕ fold P _⊕_ ∅ ys)) ≡⟨ sym (assoc x _ _) ⟩((x ⊕ fold P _⊕_ ∅ xs) ⊕ fold P _⊕_ ∅ ys) ∎where open ≡.≡-Reasoning-------------------------------------------------------------------------- Relational propertiesmodule _ {i t} {I : Set i} (T : Rel I t) wherereflexive : _≡_ ⇒ Star Treflexive refl = εtrans : Transitive (Star T)trans = _◅◅_isPreorder : IsPreorder _≡_ (Star T)isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = reflexive; trans = trans}preorder : Preorder _ _ _preorder = record{ _≈_ = _≡_; _≲_ = Star T; isPreorder = isPreorder}-------------------------------------------------------------------------- Preorder reasoning for Starmodule StarReasoning {i t} {I : Set i} (T : Rel I t) whereprivate module Base = ≲-Reasoning (preorder T)open Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨; step-∼; step-≲)renaming (≲-go to ⟶-go)open ⟶-syntax _IsRelatedTo_ _IsRelatedTo_ (⟶-go ∘ (_◅ ε)) publicopen ⟶*-syntax _IsRelatedTo_ _IsRelatedTo_ ⟶-go public
-------------------------------------------------------------------------- The Agda standard library---- Properties, related to reflexive transitive closures, that rely on-- the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}moduleRelation.Binary.Construct.Closure.ReflexiveTransitive.Properties.WithKwhereopen import Function.Base using (_∋_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Closure.ReflexiveTransitive using (Star; _◅_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)-------------------------------------------------------------------------- Equalitymodule _ {i t} {I : Set i} {T : Rel I t} {i j k} {x y : T i j} {xs ys}where◅-injectiveˡ : (Star T i k ∋ x ◅ xs) ≡ y ◅ ys → x ≡ y◅-injectiveˡ refl = refl◅-injectiveʳ : (Star T i k ∋ x ◅ xs) ≡ y ◅ ys → xs ≡ ys◅-injectiveʳ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Reflexive closures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.Reflexive whereopen import Data.Unit.Baseopen import Levelopen import Function.Base using (_∋_)open import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.Construct.Constant.Core using (Const)open import Relation.Binary.PropositionalEquality.Core using (_≡_ ; refl)privatevariablea ℓ ℓ₁ ℓ₂ : LevelA B : Set a-------------------------------------------------------------------------- Definitiondata ReflClosure {A : Set a} (_∼_ : Rel A ℓ) : Rel A (a ⊔ ℓ) whererefl : Reflexive (ReflClosure _∼_)[_] : ∀ {x y} (x∼y : x ∼ y) → ReflClosure _∼_ x y-------------------------------------------------------------------------- Operationsmap : ∀ {R : Rel A ℓ₁} {S : Rel B ℓ₂} {f : A → B} →R =[ f ]⇒ S → ReflClosure R =[ f ]⇒ ReflClosure Smap R⇒S [ xRy ] = [ R⇒S xRy ]map R⇒S refl = refl-------------------------------------------------------------------------- Properties-- The reflexive closure has no effect on reflexive relations.drop-refl : {R : Rel A ℓ} → Reflexive R → ReflClosure R ⇒ Rdrop-refl rfl [ xRy ] = xRydrop-refl rfl refl = rflreflexive : {R : Rel A ℓ} → _≡_ ⇒ ReflClosure Rreflexive refl = refl[]-injective : {R : Rel A ℓ} → ∀ {x y p q} →(ReflClosure R x y ∋ [ p ]) ≡ [ q ] → p ≡ q[]-injective refl = refl-------------------------------------------------------------------------- Example usageprivatemodule Maybe whereMaybe : Set a → Set aMaybe A = ReflClosure (Const A) tt ttnothing : Maybe Anothing = refljust : A → Maybe Ajust = [_]-------------------------------------------------------------------------- Deprecations-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- v1.5Refl = ReflClosure{-# WARNING_ON_USAGE Refl"Warning: Refl was deprecated in v1.5.Please use ReflClosure instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some properties of reflexive closures------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Relation.Binary.Construct.Closure.Reflexive.Properties whereopen import Data.Product.Base as Productopen import Data.Sum.Base as Sumopen import Function.Bundles using (_⇔_; mk⇔)open import Function.Base using (id)open import Levelopen import Relation.Binary.Core using (Rel; REL; _=[_]⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsStrictPartialOrder; IsPartialOrder; IsDecStrictPartialOrder; IsDecPartialOrder; IsStrictTotalOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Symmetric; Transitive; Reflexive; Asymmetric; Antisymmetric; Trichotomous; Total; Decidable; DecidableEquality; tri<; tri≈; tri>; _Respectsˡ_; _Respectsʳ_; _Respects_; _Respects₂_)open import Relation.Binary.Construct.Closure.Reflexiveopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Nullary.Negation.Core using (contradiction)open import Relation.Nullary.Decidable as Dec using (yes; no)open import Relation.Unary using (Pred)privatevariablea b ℓ p q : LevelA : Set aB : Set b-------------------------------------------------------------------------- Relational propertiesmodule _ {P : Rel A p} {Q : Rel B q} where=[]⇒ : ∀ {f : A → B} → P =[ f ]⇒ Q → ReflClosure P =[ f ]⇒ ReflClosure Q=[]⇒ x [ x∼y ] = [ x x∼y ]=[]⇒ x refl = reflmodule _ {_~_ : Rel A ℓ} whereprivate_~ᵒ_ = ReflClosure _~_fromSum : ∀ {x y} → x ≡ y ⊎ x ~ y → x ~ᵒ yfromSum (inj₁ refl) = reflfromSum (inj₂ y) = [ y ]toSum : ∀ {x y} → x ~ᵒ y → x ≡ y ⊎ x ~ ytoSum [ x∼y ] = inj₂ x∼ytoSum refl = inj₁ refl⊎⇔Refl : ∀ {a b} → (a ≡ b ⊎ a ~ b) ⇔ a ~ᵒ b⊎⇔Refl = mk⇔ fromSum toSumsym : Symmetric _~_ → Symmetric _~ᵒ_sym ~-sym [ x∼y ] = [ ~-sym x∼y ]sym ~-sym refl = refltrans : Transitive _~_ → Transitive _~ᵒ_trans ~-trans [ x∼y ] [ x∼y₁ ] = [ ~-trans x∼y x∼y₁ ]trans ~-trans [ x∼y ] refl = [ x∼y ]trans ~-trans refl [ x∼y ] = [ x∼y ]trans ~-trans refl refl = reflantisym : (_≈_ : Rel A p) → Reflexive _≈_ →Asymmetric _~_ → Antisymmetric _≈_ _~ᵒ_antisym _≈_ ref asym [ x∼y ] [ y∼x ] = contradiction x∼y (asym y∼x)antisym _≈_ ref asym [ x∼y ] refl = refantisym _≈_ ref asym refl _ = reftotal : Trichotomous _≡_ _~_ → Total _~ᵒ_total compare x y with compare x y... | tri< a _ _ = inj₁ [ a ]... | tri≈ _ refl _ = inj₁ refl... | tri> _ _ c = inj₂ [ c ]dec : DecidableEquality A → Decidable _~_ → Decidable _~ᵒ_dec ≡-dec ~-dec a b = Dec.map ⊎⇔Refl (≡-dec a b Dec.⊎-dec ~-dec a b)decidable : Trichotomous _≡_ _~_ → Decidable _~ᵒ_decidable ~-tri a b with ~-tri a b... | tri< a~b _ _ = yes [ a~b ]... | tri≈ _ refl _ = yes refl... | tri> ¬a ¬b _ = no λ { refl → ¬b refl ; [ p ] → ¬a p }respˡ : ∀ {P : REL A B p} → P Respectsˡ _~_ → P Respectsˡ _~ᵒ_respˡ p-respˡ-~ [ x∼y ] = p-respˡ-~ x∼yrespˡ _ refl = idrespʳ : ∀ {P : REL B A p} → P Respectsʳ _~_ → P Respectsʳ _~ᵒ_respʳ = respˡmodule _ {_~_ : Rel A ℓ} {P : Pred A p} whereresp : P Respects _~_ → P Respects (ReflClosure _~_)resp p-resp-~ [ x∼y ] = p-resp-~ x∼yresp _ refl = idmodule _ {_~_ : Rel A ℓ} {P : Rel A p} whereresp₂ : P Respects₂ _~_ → P Respects₂ (ReflClosure _~_)resp₂ = Product.map respˡ respʳ-------------------------------------------------------------------------- Structuresmodule _ {_~_ : Rel A ℓ} whereprivate_~ᵒ_ = ReflClosure _~_isPreorder : Transitive _~_ → IsPreorder _≡_ _~ᵒ_isPreorder ~-trans = record{ isEquivalence = ≡.isEquivalence; reflexive = λ { refl → refl }; trans = trans ~-trans}isPartialOrder : IsStrictPartialOrder _≡_ _~_ → IsPartialOrder _≡_ _~ᵒ_isPartialOrder O = record{ isPreorder = isPreorder O.trans; antisym = antisym _≡_ refl O.asym} where module O = IsStrictPartialOrder OisDecPartialOrder : IsDecStrictPartialOrder _≡_ _~_ → IsDecPartialOrder _≡_ _~ᵒ_isDecPartialOrder O = record{ isPartialOrder = isPartialOrder O.isStrictPartialOrder; _≟_ = O._≟_; _≤?_ = dec O._≟_ O._<?_} where module O = IsDecStrictPartialOrder OisTotalOrder : IsStrictTotalOrder _≡_ _~_ → IsTotalOrder _≡_ _~ᵒ_isTotalOrder O = record{ isPartialOrder = isPartialOrder isStrictPartialOrder; total = total compare} where open IsStrictTotalOrder OisDecTotalOrder : IsStrictTotalOrder _≡_ _~_ → IsDecTotalOrder _≡_ _~ᵒ_isDecTotalOrder O = record{ isTotalOrder = isTotalOrder O; _≟_ = _≟_; _≤?_ = dec _≟_ _<?_} where open IsStrictTotalOrder O
-------------------------------------------------------------------------- The Agda standard library---- Some properties of reflexive closures which rely on the K rule------------------------------------------------------------------------{-# OPTIONS --safe --with-K #-}module Relation.Binary.Construct.Closure.Reflexive.Properties.WithK whereopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Irrelevant; Irreflexive)open import Relation.Binary.Construct.Closure.Reflexiveopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.Construct.Closure.Reflexive.Properties publicmodule _ {a ℓ} {A : Set a} {_∼_ : Rel A ℓ} whereirrel : Irrelevant _∼_ → Irreflexive _≡_ _∼_ → Irrelevant (ReflClosure _∼_)irrel irrel irrefl [ x∼y₁ ] [ x∼y₂ ] = cong [_] (irrel x∼y₁ x∼y₂)irrel irrel irrefl [ x∼y ] refl = contradiction x∼y (irrefl refl)irrel irrel irrefl refl [ x∼y ] = contradiction x∼y (irrefl refl)irrel irrel irrefl refl refl = refl
-------------------------------------------------------------------------- The Agda standard library---- The reflexive, symmetric and transitive closure of a binary-- relation (aka the equivalence closure).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.Equivalence whereopen import Function.Base using (flip; id; _∘_; _on_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; Symmetric)open import Relation.Binary.Construct.Closure.ReflexiveTransitive as Starusing (Star; ε; _◅◅_; reverse)open import Relation.Binary.Construct.Closure.Symmetric as SCusing (SymClosure)import Relation.Binary.Construct.On as Onprivatevariablea ℓ ℓ₁ ℓ₂ : LevelA B : Set aR S : Rel A ℓ-------------------------------------------------------------------------- DefinitionEqClosure : {A : Set a} → Rel A ℓ → Rel A (a ⊔ ℓ)EqClosure R = Star (SymClosure R)-------------------------------------------------------------------------- Propertiesmodule _ (_∼_ : Rel A ℓ) wherereflexive : Reflexive (EqClosure _∼_)reflexive = εtransitive : Transitive (EqClosure _∼_)transitive = _◅◅_symmetric : Symmetric (EqClosure _∼_)symmetric = reverse (SC.symmetric _∼_)isEquivalence : IsEquivalence (EqClosure _∼_)isEquivalence = record{ refl = reflexive; sym = symmetric; trans = transitive}setoid : {A : Set a} (_∼_ : Rel A ℓ) → Setoid a (a ⊔ ℓ)setoid _∼_ = record{ _≈_ = EqClosure _∼_; isEquivalence = isEquivalence _∼_}-------------------------------------------------------------------------- Operations-- A generalised variant of `map` which allows the index type to change.gmap : (f : A → B) → R =[ f ]⇒ S → EqClosure R =[ f ]⇒ EqClosure Sgmap f = Star.gmap f ∘ SC.gmap fmap : R ⇒ S → EqClosure R ⇒ EqClosure Smap = gmap idfold : IsEquivalence S → R ⇒ S → EqClosure R ⇒ Sfold S-equiv R⇒S = Star.fold _ (trans ∘ SC.fold sym R⇒S) reflwhere open IsEquivalence S-equiv-- A generalised variant of `fold`.gfold : IsEquivalence S → (f : A → B) → R =[ f ]⇒ S → EqClosure R =[ f ]⇒ Sgfold S-equiv f R⇒S = fold (On.isEquivalence f S-equiv) R⇒S-- `return` could also be called `singleton`.return : R ⇒ EqClosure Rreturn = Star.return ∘ SC.return-- `join` could also be called `concat`.join : EqClosure (EqClosure R) ⇒ EqClosure Rjoin = fold (isEquivalence _) idinfix 10 _⋆_⋆ : R ⇒ EqClosure S → EqClosure R ⇒ EqClosure S_⋆ f m = join (map f m)
-------------------------------------------------------------------------- The Agda standard library---- Some properties of equivalence closures.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Closure.Equivalence.Properties whereopen import Function.Base using (_∘′_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Closure.Equivalenceopen import Relation.Binary.Construct.Closure.ReflexiveTransitive as RTransimport Relation.Binary.Construct.Closure.Symmetric as SymClosuremodule _ {a ℓ} {A : Set a} {_⟶_ : Rel A ℓ} whereprivate_—↠_ = Star _⟶__↔_ = EqClosure _⟶_a—↠b⇒a↔b : ∀ {a b} → a —↠ b → a ↔ ba—↠b⇒a↔b = RTrans.map SymClosure.fwda—↠b⇒b↔a : ∀ {a b} → a —↠ b → b ↔ aa—↠b⇒b↔a = symmetric _ ∘′ a—↠b⇒a↔ba—↠b&a—↠c⇒b↔c : ∀ {a b c} → a —↠ b → a —↠ c → b ↔ ca—↠b&a—↠c⇒b↔c a—↠b b—↠c = a—↠b⇒b↔a a—↠b ◅◅ a—↠b⇒a↔b b—↠c
-------------------------------------------------------------------------- The Agda standard library---- The universal binary relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Construct.Always whereopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)open import Relation.Binary.Construct.Constant using (Const)open import Data.Unit.Polymorphic using (⊤; tt)-------------------------------------------------------------------------- DefinitionAlways : ∀ {a ℓ} {A : Set a} → Rel A ℓAlways = Const ⊤-------------------------------------------------------------------------- Propertiesmodule _ {a} (A : Set a) ℓ whererefl : Reflexive {A = A} {ℓ = ℓ} Alwaysrefl = _sym : Symmetric {A = A} {ℓ = ℓ} Alwayssym _ = _trans : Transitive {A = A} {ℓ = ℓ} Alwaystrans _ _ = _isEquivalence : IsEquivalence {ℓ = ℓ} {A} AlwaysisEquivalence = record {}setoid : Setoid a ℓsetoid = record{ isEquivalence = isEquivalence}
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a strict order to incorporate a new supremum------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Supremumopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structuresusing (IsStrictPartialOrder; IsDecStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Asymmetric; Transitive; Decidable; Irrelevant; Irreflexive; Trans; Trichotomous; tri≈; tri>; tri<; _Respectsˡ_; _Respectsʳ_; _Respects₂_)module Relation.Binary.Construct.Add.Supremum.Strict{a r} {A : Set a} (_<_ : Rel A r) whereopen import Level using (_⊔_)open import Data.Product.Base using (_,_; map)open import Function.Baseopen import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Decopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; subst)import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Nullary.Construct.Add.Supremumimport Relation.Binary.Construct.Add.Supremum.Equality as Equalityimport Relation.Binary.Construct.Add.Supremum.NonStrict as NonStrict-------------------------------------------------------------------------- Definitioninfix 4 _<⁺_data _<⁺_ : Rel (A ⁺) (a ⊔ r) where[_] : {k l : A} → k < l → [ k ] <⁺ [ l ][_]<⊤⁺ : (k : A) → [ k ] <⁺ ⊤⁺-------------------------------------------------------------------------- Relational properties[<]-injective : ∀ {k l} → [ k ] <⁺ [ l ] → k < l[<]-injective [ p ] = p<⁺-asym : Asymmetric _<_ → Asymmetric _<⁺_<⁺-asym <-asym [ p ] [ q ] = <-asym p q<⁺-trans : Transitive _<_ → Transitive _<⁺_<⁺-trans <-trans [ p ] [ q ] = [ <-trans p q ]<⁺-trans <-trans [ p ] [ k ]<⊤⁺ = [ _ ]<⊤⁺<⁺-dec : Decidable _<_ → Decidable _<⁺_<⁺-dec _<?_ [ k ] [ l ] = Dec.map′ [_] [<]-injective (k <? l)<⁺-dec _<?_ [ k ] ⊤⁺ = yes [ k ]<⊤⁺<⁺-dec _<?_ ⊤⁺ [ l ] = no (λ ())<⁺-dec _<?_ ⊤⁺ ⊤⁺ = no (λ ())<⁺-irrelevant : Irrelevant _<_ → Irrelevant _<⁺_<⁺-irrelevant <-irr [ p ] [ q ] = cong _ (<-irr p q)<⁺-irrelevant <-irr [ k ]<⊤⁺ [ k ]<⊤⁺ = reflmodule _ {r} {_≤_ : Rel A r} whereopen NonStrict _≤_<⁺-transʳ : Trans _≤_ _<_ _<_ → Trans _≤⁺_ _<⁺_ _<⁺_<⁺-transʳ <-transʳ [ p ] [ q ] = [ <-transʳ p q ]<⁺-transʳ <-transʳ [ p ] [ k ]<⊤⁺ = [ _ ]<⊤⁺<⁺-transˡ : Trans _<_ _≤_ _<_ → Trans _<⁺_ _≤⁺_ _<⁺_<⁺-transˡ <-transˡ [ p ] [ q ] = [ <-transˡ p q ]<⁺-transˡ <-transˡ [ p ] ([ _ ] ≤⊤⁺) = [ _ ]<⊤⁺<⁺-transˡ <-transˡ [ k ]<⊤⁺ (⊤⁺ ≤⊤⁺) = [ k ]<⊤⁺-------------------------------------------------------------------------- Relational properties + propositional equality<⁺-cmp-≡ : Trichotomous _≡_ _<_ → Trichotomous _≡_ _<⁺_<⁺-cmp-≡ <-cmp ⊤⁺ ⊤⁺ = tri≈ (λ ()) refl (λ ())<⁺-cmp-≡ <-cmp ⊤⁺ [ l ] = tri> (λ ()) (λ ()) [ l ]<⊤⁺<⁺-cmp-≡ <-cmp [ k ] ⊤⁺ = tri< [ k ]<⊤⁺ (λ ()) (λ ())<⁺-cmp-≡ <-cmp [ k ] [ l ] with <-cmp k l... | tri< a ¬b ¬c = tri< [ a ] (¬b ∘ []-injective) (¬c ∘ [<]-injective)... | tri≈ ¬a refl ¬c = tri≈ (¬a ∘ [<]-injective) refl (¬c ∘ [<]-injective)... | tri> ¬a ¬b c = tri> (¬a ∘ [<]-injective) (¬b ∘ []-injective) [ c ]<⁺-irrefl-≡ : Irreflexive _≡_ _<_ → Irreflexive _≡_ _<⁺_<⁺-irrefl-≡ <-irrefl refl [ x ] = <-irrefl refl x<⁺-respˡ-≡ : _<⁺_ Respectsˡ _≡_<⁺-respˡ-≡ = subst (_<⁺ _)<⁺-respʳ-≡ : _<⁺_ Respectsʳ _≡_<⁺-respʳ-≡ = subst (_ <⁺_)<⁺-resp-≡ : _<⁺_ Respects₂ _≡_<⁺-resp-≡ = <⁺-respʳ-≡ , <⁺-respˡ-≡-------------------------------------------------------------------------- Relational properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<⁺-cmp : Trichotomous _≈_ _<_ → Trichotomous _≈⁺_ _<⁺_<⁺-cmp <-cmp ⊤⁺ ⊤⁺ = tri≈ (λ ()) ⊤⁺≈⊤⁺ (λ ())<⁺-cmp <-cmp ⊤⁺ [ l ] = tri> (λ ()) (λ ()) [ l ]<⊤⁺<⁺-cmp <-cmp [ k ] ⊤⁺ = tri< [ k ]<⊤⁺ (λ ()) (λ ())<⁺-cmp <-cmp [ k ] [ l ] with <-cmp k l... | tri< a ¬b ¬c = tri< [ a ] (¬b ∘ [≈]-injective) (¬c ∘ [<]-injective)... | tri≈ ¬a b ¬c = tri≈ (¬a ∘ [<]-injective) [ b ] (¬c ∘ [<]-injective)... | tri> ¬a ¬b c = tri> (¬a ∘ [<]-injective) (¬b ∘ [≈]-injective) [ c ]<⁺-irrefl : Irreflexive _≈_ _<_ → Irreflexive _≈⁺_ _<⁺_<⁺-irrefl <-irrefl [ p ] [ q ] = <-irrefl p q<⁺-respˡ-≈⁺ : _<_ Respectsˡ _≈_ → _<⁺_ Respectsˡ _≈⁺_<⁺-respˡ-≈⁺ <-respˡ-≈ [ p ] [ q ] = [ <-respˡ-≈ p q ]<⁺-respˡ-≈⁺ <-respˡ-≈ [ p ] ([ l ]<⊤⁺) = [ _ ]<⊤⁺<⁺-respˡ-≈⁺ <-respˡ-≈ ⊤⁺≈⊤⁺ q = q<⁺-respʳ-≈⁺ : _<_ Respectsʳ _≈_ → _<⁺_ Respectsʳ _≈⁺_<⁺-respʳ-≈⁺ <-respʳ-≈ [ p ] [ q ] = [ <-respʳ-≈ p q ]<⁺-respʳ-≈⁺ <-respʳ-≈ ⊤⁺≈⊤⁺ q = q<⁺-resp-≈⁺ : _<_ Respects₂ _≈_ → _<⁺_ Respects₂ _≈⁺_<⁺-resp-≈⁺ = map <⁺-respʳ-≈⁺ <⁺-respˡ-≈⁺-------------------------------------------------------------------------- Structures + propositional equality<⁺-isStrictPartialOrder-≡ : IsStrictPartialOrder _≡_ _<_ →IsStrictPartialOrder _≡_ _<⁺_<⁺-isStrictPartialOrder-≡ strict = record{ isEquivalence = ≡.isEquivalence; irrefl = <⁺-irrefl-≡ irrefl; trans = <⁺-trans trans; <-resp-≈ = <⁺-resp-≡} where open IsStrictPartialOrder strict<⁺-isDecStrictPartialOrder-≡ : IsDecStrictPartialOrder _≡_ _<_ →IsDecStrictPartialOrder _≡_ _<⁺_<⁺-isDecStrictPartialOrder-≡ dectot = record{ isStrictPartialOrder = <⁺-isStrictPartialOrder-≡ isStrictPartialOrder; _≟_ = ≡-dec _≟_; _<?_ = <⁺-dec _<?_} where open IsDecStrictPartialOrder dectot<⁺-isStrictTotalOrder-≡ : IsStrictTotalOrder _≡_ _<_ →IsStrictTotalOrder _≡_ _<⁺_<⁺-isStrictTotalOrder-≡ strictot = record{ isStrictPartialOrder = <⁺-isStrictPartialOrder-≡ isStrictPartialOrder; compare = <⁺-cmp-≡ compare} where open IsStrictTotalOrder strictot-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<⁺-isStrictPartialOrder : IsStrictPartialOrder _≈_ _<_ →IsStrictPartialOrder _≈⁺_ _<⁺_<⁺-isStrictPartialOrder strict = record{ isEquivalence = ≈⁺-isEquivalence isEquivalence; irrefl = <⁺-irrefl irrefl; trans = <⁺-trans trans; <-resp-≈ = <⁺-resp-≈⁺ <-resp-≈} where open IsStrictPartialOrder strict<⁺-isDecStrictPartialOrder : IsDecStrictPartialOrder _≈_ _<_ →IsDecStrictPartialOrder _≈⁺_ _<⁺_<⁺-isDecStrictPartialOrder dectot = record{ isStrictPartialOrder = <⁺-isStrictPartialOrder isStrictPartialOrder; _≟_ = ≈⁺-dec _≟_; _<?_ = <⁺-dec _<?_} where open IsDecStrictPartialOrder dectot<⁺-isStrictTotalOrder : IsStrictTotalOrder _≈_ _<_ →IsStrictTotalOrder _≈⁺_ _<⁺_<⁺-isStrictTotalOrder strictot = record{ isStrictPartialOrder = <⁺-isStrictPartialOrder isStrictPartialOrder; compare = <⁺-cmp compare} where open IsStrictTotalOrder strictot
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a non-strict order to incorporate a new supremum------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Supremumopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Maximum; Transitive; Total; Decidable; Irrelevant; Antisymmetric)module Relation.Binary.Construct.Add.Supremum.NonStrict{a ℓ} {A : Set a} (_≤_ : Rel A ℓ) whereopen import Level using (_⊔_)open import Data.Sum.Base as Sumopen import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Decopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong)import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Nullary.Construct.Add.Supremumimport Relation.Binary.Construct.Add.Supremum.Equality as Equality-------------------------------------------------------------------------- Definitioninfix 4 _≤⁺_ _≤⊤⁺data _≤⁺_ : Rel (A ⁺) (a ⊔ ℓ) where[_] : {k l : A} → k ≤ l → [ k ] ≤⁺ [ l ]_≤⊤⁺ : (k : A ⁺) → k ≤⁺ ⊤⁺-------------------------------------------------------------------------- Properties[≤]-injective : ∀ {k l} → [ k ] ≤⁺ [ l ] → k ≤ l[≤]-injective [ p ] = p≤⁺-trans : Transitive _≤_ → Transitive _≤⁺_≤⁺-trans ≤-trans [ p ] [ q ] = [ ≤-trans p q ]≤⁺-trans ≤-trans p (l ≤⊤⁺) = _ ≤⊤⁺≤⁺-maximum : Maximum _≤⁺_ ⊤⁺≤⁺-maximum = _≤⊤⁺≤⁺-dec : Decidable _≤_ → Decidable _≤⁺_≤⁺-dec _≤?_ k ⊤⁺ = yes (k ≤⊤⁺)≤⁺-dec _≤?_ ⊤⁺ [ l ] = no (λ ())≤⁺-dec _≤?_ [ k ] [ l ] = Dec.map′ [_] [≤]-injective (k ≤? l)≤⁺-total : Total _≤_ → Total _≤⁺_≤⁺-total ≤-total k ⊤⁺ = inj₁ (k ≤⊤⁺)≤⁺-total ≤-total ⊤⁺ l = inj₂ (l ≤⊤⁺)≤⁺-total ≤-total [ k ] [ l ] = Sum.map [_] [_] (≤-total k l)≤⁺-irrelevant : Irrelevant _≤_ → Irrelevant _≤⁺_≤⁺-irrelevant ≤-irr [ p ] [ q ] = cong _ (≤-irr p q)≤⁺-irrelevant ≤-irr (k ≤⊤⁺) (k ≤⊤⁺) = refl-------------------------------------------------------------------------- Relational properties + propositional equality≤⁺-reflexive-≡ : (_≡_ ⇒ _≤_) → (_≡_ ⇒ _≤⁺_)≤⁺-reflexive-≡ ≤-reflexive {[ x ]} refl = [ ≤-reflexive refl ]≤⁺-reflexive-≡ ≤-reflexive {⊤⁺} refl = ⊤⁺ ≤⊤⁺≤⁺-antisym-≡ : Antisymmetric _≡_ _≤_ → Antisymmetric _≡_ _≤⁺_≤⁺-antisym-≡ antisym (_ ≤⊤⁺) (_ ≤⊤⁺) = refl≤⁺-antisym-≡ antisym [ p ] [ q ] = cong [_] (antisym p q)-------------------------------------------------------------------------- Relation properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤⁺-reflexive : (_≈_ ⇒ _≤_) → (_≈⁺_ ⇒ _≤⁺_)≤⁺-reflexive ≤-reflexive [ p ] = [ ≤-reflexive p ]≤⁺-reflexive ≤-reflexive ⊤⁺≈⊤⁺ = ⊤⁺ ≤⊤⁺≤⁺-antisym : Antisymmetric _≈_ _≤_ → Antisymmetric _≈⁺_ _≤⁺_≤⁺-antisym ≤-antisym [ p ] [ q ] = [ ≤-antisym p q ]≤⁺-antisym ≤-antisym (_ ≤⊤⁺) (_ ≤⊤⁺) = ⊤⁺≈⊤⁺-------------------------------------------------------------------------- Structures + propositional equality≤⁺-isPreorder-≡ : IsPreorder _≡_ _≤_ → IsPreorder _≡_ _≤⁺_≤⁺-isPreorder-≡ ≤-isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = ≤⁺-reflexive-≡ reflexive; trans = ≤⁺-trans trans} where open IsPreorder ≤-isPreorder≤⁺-isPartialOrder-≡ : IsPartialOrder _≡_ _≤_ → IsPartialOrder _≡_ _≤⁺_≤⁺-isPartialOrder-≡ ≤-isPartialOrder = record{ isPreorder = ≤⁺-isPreorder-≡ isPreorder; antisym = ≤⁺-antisym-≡ antisym} where open IsPartialOrder ≤-isPartialOrder≤⁺-isDecPartialOrder-≡ : IsDecPartialOrder _≡_ _≤_ → IsDecPartialOrder _≡_ _≤⁺_≤⁺-isDecPartialOrder-≡ ≤-isDecPartialOrder = record{ isPartialOrder = ≤⁺-isPartialOrder-≡ isPartialOrder; _≟_ = ≡-dec _≟_; _≤?_ = ≤⁺-dec _≤?_} where open IsDecPartialOrder ≤-isDecPartialOrder≤⁺-isTotalOrder-≡ : IsTotalOrder _≡_ _≤_ → IsTotalOrder _≡_ _≤⁺_≤⁺-isTotalOrder-≡ ≤-isTotalOrder = record{ isPartialOrder = ≤⁺-isPartialOrder-≡ isPartialOrder; total = ≤⁺-total total} where open IsTotalOrder ≤-isTotalOrder≤⁺-isDecTotalOrder-≡ : IsDecTotalOrder _≡_ _≤_ → IsDecTotalOrder _≡_ _≤⁺_≤⁺-isDecTotalOrder-≡ ≤-isDecTotalOrder = record{ isTotalOrder = ≤⁺-isTotalOrder-≡ isTotalOrder; _≟_ = ≡-dec _≟_; _≤?_ = ≤⁺-dec _≤?_} where open IsDecTotalOrder ≤-isDecTotalOrder-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤⁺-isPreorder : IsPreorder _≈_ _≤_ → IsPreorder _≈⁺_ _≤⁺_≤⁺-isPreorder ≤-isPreorder = record{ isEquivalence = ≈⁺-isEquivalence isEquivalence; reflexive = ≤⁺-reflexive reflexive; trans = ≤⁺-trans trans} where open IsPreorder ≤-isPreorder≤⁺-isPartialOrder : IsPartialOrder _≈_ _≤_ → IsPartialOrder _≈⁺_ _≤⁺_≤⁺-isPartialOrder ≤-isPartialOrder = record{ isPreorder = ≤⁺-isPreorder isPreorder; antisym = ≤⁺-antisym antisym} where open IsPartialOrder ≤-isPartialOrder≤⁺-isDecPartialOrder : IsDecPartialOrder _≈_ _≤_ → IsDecPartialOrder _≈⁺_ _≤⁺_≤⁺-isDecPartialOrder ≤-isDecPartialOrder = record{ isPartialOrder = ≤⁺-isPartialOrder isPartialOrder; _≟_ = ≈⁺-dec _≟_; _≤?_ = ≤⁺-dec _≤?_} where open IsDecPartialOrder ≤-isDecPartialOrder≤⁺-isTotalOrder : IsTotalOrder _≈_ _≤_ → IsTotalOrder _≈⁺_ _≤⁺_≤⁺-isTotalOrder ≤-isTotalOrder = record{ isPartialOrder = ≤⁺-isPartialOrder isPartialOrder; total = ≤⁺-total total} where open IsTotalOrder ≤-isTotalOrder≤⁺-isDecTotalOrder : IsDecTotalOrder _≈_ _≤_ → IsDecTotalOrder _≈⁺_ _≤⁺_≤⁺-isDecTotalOrder ≤-isDecTotalOrder = record{ isTotalOrder = ≤⁺-isTotalOrder isTotalOrder; _≟_ = ≈⁺-dec _≟_; _≤?_ = ≤⁺-dec _≤?_} where open IsDecTotalOrder ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- A pointwise lifting of a relation to incorporate a new supremum.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Supremumopen import Relation.Binary.Core using (Rel)module Relation.Binary.Construct.Add.Supremum.Equality{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) whereopen import Relation.Binary.Construct.Add.Point.Equality _≈_ publicrenaming(_≈∙_ to _≈⁺_; ∙≈∙ to ⊤⁺≈⊤⁺; ≈∙-refl to ≈⁺-refl; ≈∙-sym to ≈⁺-sym; ≈∙-trans to ≈⁺-trans; ≈∙-dec to ≈⁺-dec; ≈∙-irrelevant to ≈⁺-irrelevant; ≈∙-substitutive to ≈⁺-substitutive; ≈∙-isEquivalence to ≈⁺-isEquivalence; ≈∙-isDecEquivalence to ≈⁺-isDecEquivalence)
-------------------------------------------------------------------------- The Agda standard library---- A pointwise lifting of a relation to incorporate an additional point.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Pointopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Decidable; Irrelevant; Substitutive)module Relation.Binary.Construct.Add.Point.Equality{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) whereopen import Level using (_⊔_)open import Function.Baseimport Relation.Binary.PropositionalEquality.Core as ≡open import Relation.Nullary hiding (Irrelevant)open import Relation.Nullary.Construct.Add.Pointimport Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitioninfix 4 _≈∙_data _≈∙_ : Rel (Pointed A) (a ⊔ ℓ) where∙≈∙ : ∙ ≈∙ ∙[_] : {k l : A} → k ≈ l → [ k ] ≈∙ [ l ]-------------------------------------------------------------------------- Relational properties[≈]-injective : ∀ {k l} → [ k ] ≈∙ [ l ] → k ≈ l[≈]-injective [ k≈l ] = k≈l≈∙-refl : Reflexive _≈_ → Reflexive _≈∙_≈∙-refl ≈-refl {∙} = ∙≈∙≈∙-refl ≈-refl {[ k ]} = [ ≈-refl ]≈∙-sym : Symmetric _≈_ → Symmetric _≈∙_≈∙-sym ≈-sym ∙≈∙ = ∙≈∙≈∙-sym ≈-sym [ x≈y ] = [ ≈-sym x≈y ]≈∙-trans : Transitive _≈_ → Transitive _≈∙_≈∙-trans ≈-trans ∙≈∙ ∙≈z = ∙≈z≈∙-trans ≈-trans [ x≈y ] [ y≈z ] = [ ≈-trans x≈y y≈z ]≈∙-dec : Decidable _≈_ → Decidable _≈∙_≈∙-dec _≟_ ∙ ∙ = yes ∙≈∙≈∙-dec _≟_ ∙ [ l ] = no (λ ())≈∙-dec _≟_ [ k ] ∙ = no (λ ())≈∙-dec _≟_ [ k ] [ l ] = Dec.map′ [_] [≈]-injective (k ≟ l)≈∙-irrelevant : Irrelevant _≈_ → Irrelevant _≈∙_≈∙-irrelevant ≈-irr ∙≈∙ ∙≈∙ = ≡.refl≈∙-irrelevant ≈-irr [ p ] [ q ] = ≡.cong _ (≈-irr p q)≈∙-substitutive : ∀ {ℓ} → Substitutive _≈_ ℓ → Substitutive _≈∙_ ℓ≈∙-substitutive ≈-subst P ∙≈∙ = id≈∙-substitutive ≈-subst P [ p ] = ≈-subst (P ∘′ [_]) p-------------------------------------------------------------------------- Structures≈∙-isEquivalence : IsEquivalence _≈_ → IsEquivalence _≈∙_≈∙-isEquivalence ≈-isEquivalence = record{ refl = ≈∙-refl refl; sym = ≈∙-sym sym; trans = ≈∙-trans trans} where open IsEquivalence ≈-isEquivalence≈∙-isDecEquivalence : IsDecEquivalence _≈_ → IsDecEquivalence _≈∙_≈∙-isDecEquivalence ≈-isDecEquivalence = record{ isEquivalence = ≈∙-isEquivalence isEquivalence; _≟_ = ≈∙-dec _≟_} where open IsDecEquivalence ≈-isDecEquivalence
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a non-strict order to incorporate a new infimum------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Infimumopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structuresusing (IsStrictPartialOrder; IsDecStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Asymmetric; Transitive; Decidable; Irrelevant; Irreflexive; Trans; Trichotomous; tri≈; tri<; tri>; _Respectsˡ_; _Respectsʳ_; _Respects₂_)module Relation.Binary.Construct.Add.Infimum.Strict{a ℓ} {A : Set a} (_<_ : Rel A ℓ) whereopen import Level using (_⊔_)open import Data.Product.Base using (_,_; map)open import Function.Baseopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; subst)import Relation.Binary.PropositionalEquality.Properties as ≡import Relation.Binary.Construct.Add.Infimum.Equality as Equalityimport Relation.Binary.Construct.Add.Infimum.NonStrict as NonStrictopen import Relation.Nullary hiding (Irrelevant)open import Relation.Nullary.Construct.Add.Infimumimport Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitioninfix 4 _<₋_data _<₋_ : Rel (A ₋) (a ⊔ ℓ) where⊥₋<[_] : (l : A) → ⊥₋ <₋ [ l ][_] : {k l : A} → k < l → [ k ] <₋ [ l ]-------------------------------------------------------------------------- Relational properties[<]-injective : ∀ {k l} → [ k ] <₋ [ l ] → k < l[<]-injective [ p ] = p<₋-asym : Asymmetric _<_ → Asymmetric _<₋_<₋-asym <-asym [ p ] [ q ] = <-asym p q<₋-trans : Transitive _<_ → Transitive _<₋_<₋-trans <-trans ⊥₋<[ l ] [ q ] = ⊥₋<[ _ ]<₋-trans <-trans [ p ] [ q ] = [ <-trans p q ]<₋-dec : Decidable _<_ → Decidable _<₋_<₋-dec _<?_ ⊥₋ ⊥₋ = no (λ ())<₋-dec _<?_ ⊥₋ [ l ] = yes ⊥₋<[ l ]<₋-dec _<?_ [ k ] ⊥₋ = no (λ ())<₋-dec _<?_ [ k ] [ l ] = Dec.map′ [_] [<]-injective (k <? l)<₋-irrelevant : Irrelevant _<_ → Irrelevant _<₋_<₋-irrelevant <-irr ⊥₋<[ l ] ⊥₋<[ l ] = refl<₋-irrelevant <-irr [ p ] [ q ] = cong _ (<-irr p q)module _ {r} {_≤_ : Rel A r} whereopen NonStrict _≤_<₋-transʳ : Trans _≤_ _<_ _<_ → Trans _≤₋_ _<₋_ _<₋_<₋-transʳ <-transʳ (⊥₋≤ .⊥₋) (⊥₋<[ l ]) = ⊥₋<[ l ]<₋-transʳ <-transʳ (⊥₋≤ l) [ q ] = ⊥₋<[ _ ]<₋-transʳ <-transʳ [ p ] [ q ] = [ <-transʳ p q ]<₋-transˡ : Trans _<_ _≤_ _<_ → Trans _<₋_ _≤₋_ _<₋_<₋-transˡ <-transˡ ⊥₋<[ l ] [ q ] = ⊥₋<[ _ ]<₋-transˡ <-transˡ [ p ] [ q ] = [ <-transˡ p q ]-------------------------------------------------------------------------- Relational properties + propositional equality<₋-cmp-≡ : Trichotomous _≡_ _<_ → Trichotomous _≡_ _<₋_<₋-cmp-≡ <-cmp ⊥₋ ⊥₋ = tri≈ (λ ()) refl (λ ())<₋-cmp-≡ <-cmp ⊥₋ [ l ] = tri< ⊥₋<[ l ] (λ ()) (λ ())<₋-cmp-≡ <-cmp [ k ] ⊥₋ = tri> (λ ()) (λ ()) ⊥₋<[ k ]<₋-cmp-≡ <-cmp [ k ] [ l ] with <-cmp k l... | tri< a ¬b ¬c = tri< [ a ] (¬b ∘ []-injective) (¬c ∘ [<]-injective)... | tri≈ ¬a refl ¬c = tri≈ (¬a ∘ [<]-injective) refl (¬c ∘ [<]-injective)... | tri> ¬a ¬b c = tri> (¬a ∘ [<]-injective) (¬b ∘ []-injective) [ c ]<₋-irrefl-≡ : Irreflexive _≡_ _<_ → Irreflexive _≡_ _<₋_<₋-irrefl-≡ <-irrefl refl [ x ] = <-irrefl refl x<₋-respˡ-≡ : _<₋_ Respectsˡ _≡_<₋-respˡ-≡ = subst (_<₋ _)<₋-respʳ-≡ : _<₋_ Respectsʳ _≡_<₋-respʳ-≡ = subst (_ <₋_)<₋-resp-≡ : _<₋_ Respects₂ _≡_<₋-resp-≡ = <₋-respʳ-≡ , <₋-respˡ-≡-------------------------------------------------------------------------- Relational properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<₋-cmp : Trichotomous _≈_ _<_ → Trichotomous _≈₋_ _<₋_<₋-cmp <-cmp ⊥₋ ⊥₋ = tri≈ (λ ()) ⊥₋≈⊥₋ (λ ())<₋-cmp <-cmp ⊥₋ [ l ] = tri< ⊥₋<[ l ] (λ ()) (λ ())<₋-cmp <-cmp [ k ] ⊥₋ = tri> (λ ()) (λ ()) ⊥₋<[ k ]<₋-cmp <-cmp [ k ] [ l ] with <-cmp k l... | tri< a ¬b ¬c = tri< [ a ] (¬b ∘ [≈]-injective) (¬c ∘ [<]-injective)... | tri≈ ¬a b ¬c = tri≈ (¬a ∘ [<]-injective) [ b ] (¬c ∘ [<]-injective)... | tri> ¬a ¬b c = tri> (¬a ∘ [<]-injective) (¬b ∘ [≈]-injective) [ c ]<₋-irrefl : Irreflexive _≈_ _<_ → Irreflexive _≈₋_ _<₋_<₋-irrefl <-irrefl [ p ] [ q ] = <-irrefl p q<₋-respˡ-≈₋ : _<_ Respectsˡ _≈_ → _<₋_ Respectsˡ _≈₋_<₋-respˡ-≈₋ <-respˡ-≈ ⊥₋≈⊥₋ q = q<₋-respˡ-≈₋ <-respˡ-≈ [ p ] [ q ] = [ <-respˡ-≈ p q ]<₋-respʳ-≈₋ : _<_ Respectsʳ _≈_ → _<₋_ Respectsʳ _≈₋_<₋-respʳ-≈₋ <-respʳ-≈ ⊥₋≈⊥₋ q = q<₋-respʳ-≈₋ <-respʳ-≈ [ p ] ⊥₋<[ l ] = ⊥₋<[ _ ]<₋-respʳ-≈₋ <-respʳ-≈ [ p ] [ q ] = [ <-respʳ-≈ p q ]<₋-resp-≈₋ : _<_ Respects₂ _≈_ → _<₋_ Respects₂ _≈₋_<₋-resp-≈₋ = map <₋-respʳ-≈₋ <₋-respˡ-≈₋-------------------------------------------------------------------------- Structures + propositional equality<₋-isStrictPartialOrder-≡ : IsStrictPartialOrder _≡_ _<_ →IsStrictPartialOrder _≡_ _<₋_<₋-isStrictPartialOrder-≡ strict = record{ isEquivalence = ≡.isEquivalence; irrefl = <₋-irrefl-≡ irrefl; trans = <₋-trans trans; <-resp-≈ = <₋-resp-≡} where open IsStrictPartialOrder strict<₋-isDecStrictPartialOrder-≡ : IsDecStrictPartialOrder _≡_ _<_ →IsDecStrictPartialOrder _≡_ _<₋_<₋-isDecStrictPartialOrder-≡ dectot = record{ isStrictPartialOrder = <₋-isStrictPartialOrder-≡ isStrictPartialOrder; _≟_ = ≡-dec _≟_; _<?_ = <₋-dec _<?_} where open IsDecStrictPartialOrder dectot<₋-isStrictTotalOrder-≡ : IsStrictTotalOrder _≡_ _<_ →IsStrictTotalOrder _≡_ _<₋_<₋-isStrictTotalOrder-≡ strictot = record{ isStrictPartialOrder = <₋-isStrictPartialOrder-≡ isStrictPartialOrder; compare = <₋-cmp-≡ compare} where open IsStrictTotalOrder strictot-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<₋-isStrictPartialOrder : IsStrictPartialOrder _≈_ _<_ →IsStrictPartialOrder _≈₋_ _<₋_<₋-isStrictPartialOrder strict = record{ isEquivalence = ≈₋-isEquivalence isEquivalence; irrefl = <₋-irrefl irrefl; trans = <₋-trans trans; <-resp-≈ = <₋-resp-≈₋ <-resp-≈} where open IsStrictPartialOrder strict<₋-isDecStrictPartialOrder : IsDecStrictPartialOrder _≈_ _<_ →IsDecStrictPartialOrder _≈₋_ _<₋_<₋-isDecStrictPartialOrder dectot = record{ isStrictPartialOrder = <₋-isStrictPartialOrder isStrictPartialOrder; _≟_ = ≈₋-dec _≟_; _<?_ = <₋-dec _<?_} where open IsDecStrictPartialOrder dectot<₋-isStrictTotalOrder : IsStrictTotalOrder _≈_ _<_ →IsStrictTotalOrder _≈₋_ _<₋_<₋-isStrictTotalOrder strictot = record{ isStrictPartialOrder = <₋-isStrictPartialOrder isStrictPartialOrder; compare = <₋-cmp compare} where open IsStrictTotalOrder strictot
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a non-strict order to incorporate a new infimum------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Infimumopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Minimum; Transitive; Total; Decidable; Irrelevant; Antisymmetric)module Relation.Binary.Construct.Add.Infimum.NonStrict{a ℓ} {A : Set a} (_≤_ : Rel A ℓ) whereopen import Level using (_⊔_)open import Data.Sum.Base as Sumopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)import Relation.Binary.PropositionalEquality.Properties as ≡import Relation.Binary.Construct.Add.Infimum.Equality as Equalityopen import Relation.Nullary hiding (Irrelevant)open import Relation.Nullary.Construct.Add.Infimumimport Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitioninfix 5 _≤₋_data _≤₋_ : Rel (A ₋) (a ⊔ ℓ) where⊥₋≤_ : (l : A ₋) → ⊥₋ ≤₋ l[_] : {k l : A} → k ≤ l → [ k ] ≤₋ [ l ]-------------------------------------------------------------------------- Relational properties[≤]-injective : ∀ {k l} → [ k ] ≤₋ [ l ] → k ≤ l[≤]-injective [ p ] = p≤₋-trans : Transitive _≤_ → Transitive _≤₋_≤₋-trans ≤-trans (⊥₋≤ l) q = ⊥₋≤ _≤₋-trans ≤-trans [ p ] [ q ] = [ ≤-trans p q ]≤₋-minimum : Minimum _≤₋_ ⊥₋≤₋-minimum = ⊥₋≤_≤₋-dec : Decidable _≤_ → Decidable _≤₋_≤₋-dec _≤?_ ⊥₋ l = yes (⊥₋≤ l)≤₋-dec _≤?_ [ k ] ⊥₋ = no (λ ())≤₋-dec _≤?_ [ k ] [ l ] = Dec.map′ [_] [≤]-injective (k ≤? l)≤₋-total : Total _≤_ → Total _≤₋_≤₋-total ≤-total ⊥₋ l = inj₁ (⊥₋≤ l)≤₋-total ≤-total k ⊥₋ = inj₂ (⊥₋≤ k)≤₋-total ≤-total [ k ] [ l ] = Sum.map [_] [_] (≤-total k l)≤₋-irrelevant : Irrelevant _≤_ → Irrelevant _≤₋_≤₋-irrelevant ≤-irr (⊥₋≤ k) (⊥₋≤ k) = refl≤₋-irrelevant ≤-irr [ p ] [ q ] = cong _ (≤-irr p q)-------------------------------------------------------------------------- Relational properties + propositional equality≤₋-reflexive-≡ : (_≡_ ⇒ _≤_) → (_≡_ ⇒ _≤₋_)≤₋-reflexive-≡ ≤-reflexive {[ x ]} refl = [ ≤-reflexive refl ]≤₋-reflexive-≡ ≤-reflexive {⊥₋} refl = ⊥₋≤ ⊥₋≤₋-antisym-≡ : Antisymmetric _≡_ _≤_ → Antisymmetric _≡_ _≤₋_≤₋-antisym-≡ antisym (⊥₋≤ _) (⊥₋≤ _) = refl≤₋-antisym-≡ antisym [ p ] [ q ] = cong [_] (antisym p q)-------------------------------------------------------------------------- Relational properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤₋-reflexive : (_≈_ ⇒ _≤_) → (_≈₋_ ⇒ _≤₋_)≤₋-reflexive ≤-reflexive ⊥₋≈⊥₋ = ⊥₋≤ ⊥₋≤₋-reflexive ≤-reflexive [ p ] = [ ≤-reflexive p ]≤₋-antisym : Antisymmetric _≈_ _≤_ → Antisymmetric _≈₋_ _≤₋_≤₋-antisym ≤≥⇒≈ (⊥₋≤ _) (⊥₋≤ _) = ⊥₋≈⊥₋≤₋-antisym ≤≥⇒≈ [ p ] [ q ] = [ ≤≥⇒≈ p q ]-------------------------------------------------------------------------- Structures + propositional equality≤₋-isPreorder-≡ : IsPreorder _≡_ _≤_ → IsPreorder _≡_ _≤₋_≤₋-isPreorder-≡ ≤-isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = ≤₋-reflexive-≡ reflexive; trans = ≤₋-trans trans} where open IsPreorder ≤-isPreorder≤₋-isPartialOrder-≡ : IsPartialOrder _≡_ _≤_ → IsPartialOrder _≡_ _≤₋_≤₋-isPartialOrder-≡ ≤-isPartialOrder = record{ isPreorder = ≤₋-isPreorder-≡ isPreorder; antisym = ≤₋-antisym-≡ antisym} where open IsPartialOrder ≤-isPartialOrder≤₋-isDecPartialOrder-≡ : IsDecPartialOrder _≡_ _≤_ → IsDecPartialOrder _≡_ _≤₋_≤₋-isDecPartialOrder-≡ ≤-isDecPartialOrder = record{ isPartialOrder = ≤₋-isPartialOrder-≡ isPartialOrder; _≟_ = ≡-dec _≟_; _≤?_ = ≤₋-dec _≤?_} where open IsDecPartialOrder ≤-isDecPartialOrder≤₋-isTotalOrder-≡ : IsTotalOrder _≡_ _≤_ → IsTotalOrder _≡_ _≤₋_≤₋-isTotalOrder-≡ ≤-isTotalOrder = record{ isPartialOrder = ≤₋-isPartialOrder-≡ isPartialOrder; total = ≤₋-total total} where open IsTotalOrder ≤-isTotalOrder≤₋-isDecTotalOrder-≡ : IsDecTotalOrder _≡_ _≤_ → IsDecTotalOrder _≡_ _≤₋_≤₋-isDecTotalOrder-≡ ≤-isDecTotalOrder = record{ isTotalOrder = ≤₋-isTotalOrder-≡ isTotalOrder; _≟_ = ≡-dec _≟_; _≤?_ = ≤₋-dec _≤?_} where open IsDecTotalOrder ≤-isDecTotalOrder-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤₋-isPreorder : IsPreorder _≈_ _≤_ → IsPreorder _≈₋_ _≤₋_≤₋-isPreorder ≤-isPreorder = record{ isEquivalence = ≈₋-isEquivalence isEquivalence; reflexive = ≤₋-reflexive reflexive; trans = ≤₋-trans trans} where open IsPreorder ≤-isPreorder≤₋-isPartialOrder : IsPartialOrder _≈_ _≤_ → IsPartialOrder _≈₋_ _≤₋_≤₋-isPartialOrder ≤-isPartialOrder = record{ isPreorder = ≤₋-isPreorder isPreorder; antisym = ≤₋-antisym antisym} where open IsPartialOrder ≤-isPartialOrder≤₋-isDecPartialOrder : IsDecPartialOrder _≈_ _≤_ → IsDecPartialOrder _≈₋_ _≤₋_≤₋-isDecPartialOrder ≤-isDecPartialOrder = record{ isPartialOrder = ≤₋-isPartialOrder isPartialOrder; _≟_ = ≈₋-dec _≟_; _≤?_ = ≤₋-dec _≤?_} where open IsDecPartialOrder ≤-isDecPartialOrder≤₋-isTotalOrder : IsTotalOrder _≈_ _≤_ → IsTotalOrder _≈₋_ _≤₋_≤₋-isTotalOrder ≤-isTotalOrder = record{ isPartialOrder = ≤₋-isPartialOrder isPartialOrder; total = ≤₋-total total} where open IsTotalOrder ≤-isTotalOrder≤₋-isDecTotalOrder : IsDecTotalOrder _≈_ _≤_ → IsDecTotalOrder _≈₋_ _≤₋_≤₋-isDecTotalOrder ≤-isDecTotalOrder = record{ isTotalOrder = ≤₋-isTotalOrder isTotalOrder; _≟_ = ≈₋-dec _≟_; _≤?_ = ≤₋-dec _≤?_} where open IsDecTotalOrder ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- A pointwise lifting of a relation to incorporate a new infimum.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Infimumopen import Relation.Binary.Core using (Rel)module Relation.Binary.Construct.Add.Infimum.Equality{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) whereopen import Relation.Binary.Construct.Add.Point.Equality _≈_ publicrenaming(_≈∙_ to _≈₋_; ∙≈∙ to ⊥₋≈⊥₋; ≈∙-refl to ≈₋-refl; ≈∙-sym to ≈₋-sym; ≈∙-trans to ≈₋-trans; ≈∙-dec to ≈₋-dec; ≈∙-irrelevant to ≈₋-irrelevant; ≈∙-substitutive to ≈₋-substitutive; ≈∙-isEquivalence to ≈₋-isEquivalence; ≈∙-isDecEquivalence to ≈₋-isDecEquivalence)
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a strict order to incorporate new extrema------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Extremaopen import Relation.Binary.Core using (Rel)module Relation.Binary.Construct.Add.Extrema.Strict{a ℓ} {A : Set a} (_<_ : Rel A ℓ) whereopen import Levelopen import Function.Base using (_∘′_)import Relation.Nullary.Construct.Add.Infimum as Iopen import Relation.Nullary.Construct.Add.Extremaopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl)import Relation.Binary.Construct.Add.Infimum.Strict as AddInfimumimport Relation.Binary.Construct.Add.Supremum.Strict as AddSupremumimport Relation.Binary.Construct.Add.Extrema.Equality as Equalityimport Relation.Binary.Construct.Add.Extrema.NonStrict as NonStrictopen import Relation.Binary.Definitionsusing (Asymmetric; Transitive; Decidable; Irrelevant; Trichotomous; Irreflexive; Trans; _Respectsˡ_; _Respectsʳ_; _Respects₂_)open import Relation.Binary.Structuresusing (IsStrictPartialOrder; IsDecStrictPartialOrder; IsStrictTotalOrder)-------------------------------------------------------------------------- Definitionprivatemodule Inf = AddInfimum _<_module Sup = AddSupremum Inf._<₋_open Sup using () renaming (_<⁺_ to _<±_) public-------------------------------------------------------------------------- Useful pattern synonymspattern ⊥±<[_] l = Sup.[ Inf.⊥₋<[ l ] ]pattern [_] p = Sup.[ Inf.[ p ] ]pattern ⊥±<⊤± = Sup.[ I.⊥₋ ]<⊤⁺pattern [_]<⊤± k = Sup.[ I.[ k ] ]<⊤⁺-------------------------------------------------------------------------- Relational properties[<]-injective : ∀ {k l} → [ k ] <± [ l ] → k < l[<]-injective = Inf.[<]-injective ∘′ Sup.[<]-injective<±-asym : Asymmetric _<_ → Asymmetric _<±_<±-asym = Sup.<⁺-asym ∘′ Inf.<₋-asym<±-trans : Transitive _<_ → Transitive _<±_<±-trans = Sup.<⁺-trans ∘′ Inf.<₋-trans<±-dec : Decidable _<_ → Decidable _<±_<±-dec = Sup.<⁺-dec ∘′ Inf.<₋-dec<±-irrelevant : Irrelevant _<_ → Irrelevant _<±_<±-irrelevant = Sup.<⁺-irrelevant ∘′ Inf.<₋-irrelevantmodule _ {r} {_≤_ : Rel A r} whereopen NonStrict _≤_<±-transʳ : Trans _≤_ _<_ _<_ → Trans _≤±_ _<±_ _<±_<±-transʳ = Sup.<⁺-transʳ ∘′ Inf.<₋-transʳ<±-transˡ : Trans _<_ _≤_ _<_ → Trans _<±_ _≤±_ _<±_<±-transˡ = Sup.<⁺-transˡ ∘′ Inf.<₋-transˡ-------------------------------------------------------------------------- Relational properties + propositional equality<±-cmp-≡ : Trichotomous _≡_ _<_ → Trichotomous _≡_ _<±_<±-cmp-≡ = Sup.<⁺-cmp-≡ ∘′ Inf.<₋-cmp-≡<±-irrefl-≡ : Irreflexive _≡_ _<_ → Irreflexive _≡_ _<±_<±-irrefl-≡ = Sup.<⁺-irrefl-≡ ∘′ Inf.<₋-irrefl-≡<±-respˡ-≡ : _<±_ Respectsˡ _≡_<±-respˡ-≡ = Sup.<⁺-respˡ-≡<±-respʳ-≡ : _<±_ Respectsʳ _≡_<±-respʳ-≡ = Sup.<⁺-respʳ-≡<±-resp-≡ : _<±_ Respects₂ _≡_<±-resp-≡ = Sup.<⁺-resp-≡-------------------------------------------------------------------------- Relational properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<±-cmp : Trichotomous _≈_ _<_ → Trichotomous _≈±_ _<±_<±-cmp = Sup.<⁺-cmp ∘′ Inf.<₋-cmp<±-irrefl : Irreflexive _≈_ _<_ → Irreflexive _≈±_ _<±_<±-irrefl = Sup.<⁺-irrefl ∘′ Inf.<₋-irrefl<±-respˡ-≈± : _<_ Respectsˡ _≈_ → _<±_ Respectsˡ _≈±_<±-respˡ-≈± = Sup.<⁺-respˡ-≈⁺ ∘′ Inf.<₋-respˡ-≈₋<±-respʳ-≈± : _<_ Respectsʳ _≈_ → _<±_ Respectsʳ _≈±_<±-respʳ-≈± = Sup.<⁺-respʳ-≈⁺ ∘′ Inf.<₋-respʳ-≈₋<±-resp-≈± : _<_ Respects₂ _≈_ → _<±_ Respects₂ _≈±_<±-resp-≈± = Sup.<⁺-resp-≈⁺ ∘′ Inf.<₋-resp-≈₋-------------------------------------------------------------------------- Structures + propositional equality<±-isStrictPartialOrder-≡ : IsStrictPartialOrder _≡_ _<_ →IsStrictPartialOrder _≡_ _<±_<±-isStrictPartialOrder-≡ =Sup.<⁺-isStrictPartialOrder-≡ ∘′ Inf.<₋-isStrictPartialOrder-≡<±-isDecStrictPartialOrder-≡ : IsDecStrictPartialOrder _≡_ _<_ →IsDecStrictPartialOrder _≡_ _<±_<±-isDecStrictPartialOrder-≡ =Sup.<⁺-isDecStrictPartialOrder-≡ ∘′ Inf.<₋-isDecStrictPartialOrder-≡<±-isStrictTotalOrder-≡ : IsStrictTotalOrder _≡_ _<_ →IsStrictTotalOrder _≡_ _<±_<±-isStrictTotalOrder-≡ =Sup.<⁺-isStrictTotalOrder-≡ ∘′ Inf.<₋-isStrictTotalOrder-≡-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_<±-isStrictPartialOrder : IsStrictPartialOrder _≈_ _<_ →IsStrictPartialOrder _≈±_ _<±_<±-isStrictPartialOrder =Sup.<⁺-isStrictPartialOrder ∘′ Inf.<₋-isStrictPartialOrder<±-isDecStrictPartialOrder : IsDecStrictPartialOrder _≈_ _<_ →IsDecStrictPartialOrder _≈±_ _<±_<±-isDecStrictPartialOrder =Sup.<⁺-isDecStrictPartialOrder ∘′ Inf.<₋-isDecStrictPartialOrder<±-isStrictTotalOrder : IsStrictTotalOrder _≈_ _<_ →IsStrictTotalOrder _≈±_ _<±_<±-isStrictTotalOrder =Sup.<⁺-isStrictTotalOrder ∘′ Inf.<₋-isStrictTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- The lifting of a non-strict order to incorporate new extrema------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Extremaopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Decidable; Transitive; Minimum; Maximum; Total; Irrelevant; Antisymmetric)module Relation.Binary.Construct.Add.Extrema.NonStrict{a ℓ} {A : Set a} (_≤_ : Rel A ℓ) whereopen import Function.Baseopen import Relation.Nullary.Construct.Add.Extremaimport Relation.Nullary.Construct.Add.Infimum as Iopen import Relation.Binary.PropositionalEquality.Core using (_≡_)import Relation.Binary.Construct.Add.Infimum.NonStrict as AddInfimumimport Relation.Binary.Construct.Add.Supremum.NonStrict as AddSupremumimport Relation.Binary.Construct.Add.Extrema.Equality as Equality-------------------------------------------------------------------------- Definitionprivatemodule Inf = AddInfimum _≤_module Sup = AddSupremum Inf._≤₋_open Sup using () renaming (_≤⁺_ to _≤±_) public-------------------------------------------------------------------------- Useful pattern synonymspattern ⊥±≤⊥± = Sup.[ Inf.⊥₋≤ I.⊥₋ ]pattern ⊥±≤[_] l = Sup.[ Inf.⊥₋≤ I.[ l ] ]pattern [_] p = Sup.[ Inf.[ p ] ]pattern ⊥±≤⊤± = ⊥± Sup.≤⊤⁺pattern [_]≤⊤± k = [ k ] Sup.≤⊤⁺pattern ⊤±≤⊤± = ⊤± Sup.≤⊤⁺⊥±≤_ : ∀ k → ⊥± ≤± k⊥±≤ ⊥± = ⊥±≤⊥±⊥±≤ [ k ] = ⊥±≤[ k ]⊥±≤ ⊤± = ⊥±≤⊤±_≤⊤± : ∀ k → k ≤± ⊤±⊥± ≤⊤± = ⊥±≤⊤±[ k ] ≤⊤± = [ k ]≤⊤±⊤± ≤⊤± = ⊤±≤⊤±-------------------------------------------------------------------------- Relational properties[≤]-injective : ∀ {k l} → [ k ] ≤± [ l ] → k ≤ l[≤]-injective = Inf.[≤]-injective ∘′ Sup.[≤]-injective≤±-trans : Transitive _≤_ → Transitive _≤±_≤±-trans = Sup.≤⁺-trans ∘′ Inf.≤₋-trans≤±-minimum : Minimum _≤±_ ⊥±≤±-minimum = ⊥±≤_≤±-maximum : Maximum _≤±_ ⊤±≤±-maximum = _≤⊤±≤±-dec : Decidable _≤_ → Decidable _≤±_≤±-dec = Sup.≤⁺-dec ∘′ Inf.≤₋-dec≤±-total : Total _≤_ → Total _≤±_≤±-total = Sup.≤⁺-total ∘′ Inf.≤₋-total≤±-irrelevant : Irrelevant _≤_ → Irrelevant _≤±_≤±-irrelevant = Sup.≤⁺-irrelevant ∘′ Inf.≤₋-irrelevant-------------------------------------------------------------------------- Relational properties + propositional equality≤±-reflexive-≡ : (_≡_ ⇒ _≤_) → (_≡_ ⇒ _≤±_)≤±-reflexive-≡ = Sup.≤⁺-reflexive-≡ ∘′ Inf.≤₋-reflexive-≡≤±-antisym-≡ : Antisymmetric _≡_ _≤_ → Antisymmetric _≡_ _≤±_≤±-antisym-≡ = Sup.≤⁺-antisym-≡ ∘′ Inf.≤₋-antisym-≡-------------------------------------------------------------------------- Relational properties + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤±-reflexive : (_≈_ ⇒ _≤_) → (_≈±_ ⇒ _≤±_)≤±-reflexive = Sup.≤⁺-reflexive ∘′ Inf.≤₋-reflexive≤±-antisym : Antisymmetric _≈_ _≤_ → Antisymmetric _≈±_ _≤±_≤±-antisym = Sup.≤⁺-antisym ∘′ Inf.≤₋-antisym-------------------------------------------------------------------------- Structures + propositional equality≤±-isPreorder-≡ : IsPreorder _≡_ _≤_ → IsPreorder _≡_ _≤±_≤±-isPreorder-≡ = Sup.≤⁺-isPreorder-≡ ∘′ Inf.≤₋-isPreorder-≡≤±-isPartialOrder-≡ : IsPartialOrder _≡_ _≤_ → IsPartialOrder _≡_ _≤±_≤±-isPartialOrder-≡ = Sup.≤⁺-isPartialOrder-≡ ∘′ Inf.≤₋-isPartialOrder-≡≤±-isDecPartialOrder-≡ : IsDecPartialOrder _≡_ _≤_ → IsDecPartialOrder _≡_ _≤±_≤±-isDecPartialOrder-≡ = Sup.≤⁺-isDecPartialOrder-≡ ∘′ Inf.≤₋-isDecPartialOrder-≡≤±-isTotalOrder-≡ : IsTotalOrder _≡_ _≤_ → IsTotalOrder _≡_ _≤±_≤±-isTotalOrder-≡ = Sup.≤⁺-isTotalOrder-≡ ∘′ Inf.≤₋-isTotalOrder-≡≤±-isDecTotalOrder-≡ : IsDecTotalOrder _≡_ _≤_ → IsDecTotalOrder _≡_ _≤±_≤±-isDecTotalOrder-≡ = Sup.≤⁺-isDecTotalOrder-≡ ∘′ Inf.≤₋-isDecTotalOrder-≡-------------------------------------------------------------------------- Structures + setoid equalitymodule _ {e} {_≈_ : Rel A e} whereopen Equality _≈_≤±-isPreorder : IsPreorder _≈_ _≤_ → IsPreorder _≈±_ _≤±_≤±-isPreorder = Sup.≤⁺-isPreorder ∘′ Inf.≤₋-isPreorder≤±-isPartialOrder : IsPartialOrder _≈_ _≤_ → IsPartialOrder _≈±_ _≤±_≤±-isPartialOrder = Sup.≤⁺-isPartialOrder ∘′ Inf.≤₋-isPartialOrder≤±-isDecPartialOrder : IsDecPartialOrder _≈_ _≤_ → IsDecPartialOrder _≈±_ _≤±_≤±-isDecPartialOrder = Sup.≤⁺-isDecPartialOrder ∘′ Inf.≤₋-isDecPartialOrder≤±-isTotalOrder : IsTotalOrder _≈_ _≤_ → IsTotalOrder _≈±_ _≤±_≤±-isTotalOrder = Sup.≤⁺-isTotalOrder ∘′ Inf.≤₋-isTotalOrder≤±-isDecTotalOrder : IsDecTotalOrder _≈_ _≤_ → IsDecTotalOrder _≈±_ _≤±_≤±-isDecTotalOrder = Sup.≤⁺-isDecTotalOrder ∘′ Inf.≤₋-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- A pointwise lifting of a relation to incorporate new extrema.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This module is designed to be used with-- Relation.Nullary.Construct.Add.Extremaopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Decidable; Irrelevant; Substitutive)module Relation.Binary.Construct.Add.Extrema.Equality{a ℓ} {A : Set a} (_≈_ : Rel A ℓ) whereopen import Function.Base using (_∘′_)import Relation.Binary.Construct.Add.Infimum.Equality as AddInfimumimport Relation.Binary.Construct.Add.Supremum.Equality as AddSupremumopen import Relation.Nullary.Construct.Add.Extrema-------------------------------------------------------------------------- Definitionprivatemodule Inf = AddInfimum _≈_module Sup = AddSupremum (Inf._≈₋_)open Sup using () renaming (_≈⁺_ to _≈±_) public-------------------------------------------------------------------------- Useful pattern synonymspattern ⊥±≈⊥± = Sup.[ Inf.⊥₋≈⊥₋ ]pattern [_] p = Sup.[ Inf.[ p ] ]pattern ⊤±≈⊤± = Sup.⊤⁺≈⊤⁺-------------------------------------------------------------------------- Relational properties[≈]-injective : ∀ {k l} → [ k ] ≈± [ l ] → k ≈ l[≈]-injective = Inf.[≈]-injective ∘′ Sup.[≈]-injective≈±-refl : Reflexive _≈_ → Reflexive _≈±_≈±-refl = Sup.≈⁺-refl ∘′ Inf.≈₋-refl≈±-sym : Symmetric _≈_ → Symmetric _≈±_≈±-sym = Sup.≈⁺-sym ∘′ Inf.≈₋-sym≈±-trans : Transitive _≈_ → Transitive _≈±_≈±-trans = Sup.≈⁺-trans ∘′ Inf.≈₋-trans≈±-dec : Decidable _≈_ → Decidable _≈±_≈±-dec = Sup.≈⁺-dec ∘′ Inf.≈₋-dec≈±-irrelevant : Irrelevant _≈_ → Irrelevant _≈±_≈±-irrelevant = Sup.≈⁺-irrelevant ∘′ Inf.≈₋-irrelevant≈±-substitutive : ∀ {ℓ} → Substitutive _≈_ ℓ → Substitutive _≈±_ ℓ≈±-substitutive = Sup.≈⁺-substitutive ∘′ Inf.≈₋-substitutive-------------------------------------------------------------------------- Structures≈±-isEquivalence : IsEquivalence _≈_ → IsEquivalence _≈±_≈±-isEquivalence = Sup.≈⁺-isEquivalence ∘′ Inf.≈₋-isEquivalence≈±-isDecEquivalence : IsDecEquivalence _≈_ → IsDecEquivalence _≈±_≈±-isDecEquivalence = Sup.≈⁺-isDecEquivalence ∘′ Inf.≈₋-isDecEquivalence
-------------------------------------------------------------------------- The Agda standard library---- Some properties imply others------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Consequences whereopen import Data.Empty using (⊥-elim)open import Data.Product.Base using (_,_)open import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_]′)open import Function.Base using (_∘_; _∘₂_; _$_; flip)open import Level using (Level)open import Relation.Binary.Coreopen import Relation.Binary.Definitionsopen import Relation.Nullary.Negation.Core using (¬_)open import Relation.Nullary.Decidable.Coreusing (yes; no; recompute; map′; dec⇒maybe)open import Relation.Unary using (∁; Pred)privatevariablea ℓ ℓ₁ ℓ₂ ℓ₃ ℓ₄ p : LevelA B : Set a-------------------------------------------------------------------------- Substitutive propertiesmodule _ {_∼_ : Rel A ℓ} (R : Rel A p) wheresubst⇒respˡ : Substitutive _∼_ p → R Respectsˡ _∼_subst⇒respˡ subst {y} x′∼x Px′y = subst (flip R y) x′∼x Px′ysubst⇒respʳ : Substitutive _∼_ p → R Respectsʳ _∼_subst⇒respʳ subst {x} y′∼y Pxy′ = subst (R x) y′∼y Pxy′subst⇒resp₂ : Substitutive _∼_ p → R Respects₂ _∼_subst⇒resp₂ subst = subst⇒respʳ subst , subst⇒respˡ substmodule _ {_∼_ : Rel A ℓ} {P : Pred A p} whereresp⇒¬-resp : Symmetric _∼_ → P Respects _∼_ → (∁ P) Respects _∼_resp⇒¬-resp sym resp x∼y ¬Px Py = ¬Px (resp (sym x∼y) Py)-------------------------------------------------------------------------- Proofs for negationmodule _ {_∼_ : Rel A ℓ} wheresym⇒¬-sym : Symmetric _∼_ → Symmetric (¬_ ∘₂ _∼_)sym⇒¬-sym sym≁ x≁y y∼x = x≁y (sym≁ y∼x)-- N.B. the implicit arguments to Cotransitive are permuted w.r.t.-- those of Transitivecotrans⇒¬-trans : Cotransitive _∼_ → Transitive (¬_ ∘₂ _∼_)cotrans⇒¬-trans cotrans {j = z} x≁z z≁y x∼y =[ x≁z , z≁y ]′ (cotrans x∼y z)-------------------------------------------------------------------------- Proofs for Irreflexive relationsmodule _ {_≈_ : Rel A ℓ₁} {_∼_ : Rel A ℓ₂} whereirrefl⇒¬-refl : Reflexive _≈_ → Irreflexive _≈_ _∼_ →Reflexive (¬_ ∘₂ _∼_)irrefl⇒¬-refl re irr = irr re-------------------------------------------------------------------------- Proofs for non-strict ordersmodule _ {_≈_ : Rel A ℓ₁} {_≤_ : Rel A ℓ₂} wheretotal⇒refl : _≤_ Respects₂ _≈_ → Symmetric _≈_ →Total _≤_ → _≈_ ⇒ _≤_total⇒refl (respʳ , respˡ) sym total {x} {y} x≈y with total x y... | inj₁ x∼y = x∼y... | inj₂ y∼x = respʳ x≈y (respˡ (sym x≈y) y∼x)total∧dec⇒dec : _≈_ ⇒ _≤_ → Antisymmetric _≈_ _≤_ →Total _≤_ → Decidable _≈_ → Decidable _≤_total∧dec⇒dec refl antisym total _≟_ x y with total x y... | inj₁ x≤y = yes x≤y... | inj₂ y≤x = map′ refl (flip antisym y≤x) (x ≟ y)module _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) {≤₁ : Rel A ℓ₃} {≤₂ : Rel B ℓ₄} wheremono⇒cong : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ →∀ {f} → f Preserves ≤₁ ⟶ ≤₂ → f Preserves ≈₁ ⟶ ≈₂mono⇒cong sym reflexive antisym mono x≈y = antisym(mono (reflexive x≈y))(mono (reflexive (sym x≈y)))antimono⇒cong : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ →∀ {f} → f Preserves ≤₁ ⟶ (flip ≤₂) → f Preserves ≈₁ ⟶ ≈₂antimono⇒cong sym reflexive antisym antimono p≈q = antisym(antimono (reflexive (sym p≈q)))(antimono (reflexive p≈q))mono₂⇒cong₂ : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ → ∀ {f} →f Preserves₂ ≤₁ ⟶ ≤₁ ⟶ ≤₂ →f Preserves₂ ≈₁ ⟶ ≈₁ ⟶ ≈₂mono₂⇒cong₂ sym reflexive antisym mono x≈y u≈v = antisym(mono (reflexive x≈y) (reflexive u≈v))(mono (reflexive (sym x≈y)) (reflexive (sym u≈v)))-------------------------------------------------------------------------- Proofs for strict ordersmodule _ {_≈_ : Rel A ℓ₁} {_<_ : Rel A ℓ₂} wheretrans∧irr⇒asym : Reflexive _≈_ → Transitive _<_ →Irreflexive _≈_ _<_ → Asymmetric _<_trans∧irr⇒asym refl trans irrefl x<y y<x =irrefl refl (trans x<y y<x)irr∧antisym⇒asym : Irreflexive _≈_ _<_ → Antisymmetric _≈_ _<_ →Asymmetric _<_irr∧antisym⇒asym irrefl antisym x<y y<x =irrefl (antisym x<y y<x) x<yasym⇒antisym : Asymmetric _<_ → Antisymmetric _≈_ _<_asym⇒antisym asym x<y y<x = ⊥-elim (asym x<y y<x)asym⇒irr : _<_ Respects₂ _≈_ → Symmetric _≈_ →Asymmetric _<_ → Irreflexive _≈_ _<_asym⇒irr (respʳ , respˡ) sym asym {x} {y} x≈y x<y =asym x<y (respʳ (sym x≈y) (respˡ x≈y x<y))tri⇒asym : Trichotomous _≈_ _<_ → Asymmetric _<_tri⇒asym tri {x} {y} x<y x>y with tri x y... | tri< _ _ x≯y = x≯y x>y... | tri≈ _ _ x≯y = x≯y x>y... | tri> x≮y _ _ = x≮y x<ytri⇒irr : Trichotomous _≈_ _<_ → Irreflexive _≈_ _<_tri⇒irr compare {x} {y} x≈y x<y with compare x y... | tri< _ x≉y y≮x = x≉y x≈y... | tri> x≮y x≉y y<x = x≉y x≈y... | tri≈ x≮y _ y≮x = x≮y x<ytri⇒dec≈ : Trichotomous _≈_ _<_ → Decidable _≈_tri⇒dec≈ compare x y with compare x y... | tri< _ x≉y _ = no x≉y... | tri≈ _ x≈y _ = yes x≈y... | tri> _ x≉y _ = no x≉ytri⇒dec< : Trichotomous _≈_ _<_ → Decidable _<_tri⇒dec< compare x y with compare x y... | tri< x<y _ _ = yes x<y... | tri≈ x≮y _ _ = no x≮y... | tri> x≮y _ _ = no x≮ytrans∧tri⇒respʳ : Symmetric _≈_ → Transitive _≈_ →Transitive _<_ → Trichotomous _≈_ _<_ →_<_ Respectsʳ _≈_trans∧tri⇒respʳ sym ≈-tr <-tr tri {x} {y} {z} y≈z x<y with tri x z... | tri< x<z _ _ = x<z... | tri≈ _ x≈z _ = ⊥-elim (tri⇒irr tri (≈-tr x≈z (sym y≈z)) x<y)... | tri> _ _ z<x = ⊥-elim (tri⇒irr tri (sym y≈z) (<-tr z<x x<y))trans∧tri⇒respˡ : Transitive _≈_ →Transitive _<_ → Trichotomous _≈_ _<_ →_<_ Respectsˡ _≈_trans∧tri⇒respˡ ≈-tr <-tr tri {z} {_} {y} x≈y x<z with tri y z... | tri< y<z _ _ = y<z... | tri≈ _ y≈z _ = ⊥-elim (tri⇒irr tri (≈-tr x≈y y≈z) x<z)... | tri> _ _ z<y = ⊥-elim (tri⇒irr tri x≈y (<-tr x<z z<y))trans∧tri⇒resp : Symmetric _≈_ → Transitive _≈_ →Transitive _<_ → Trichotomous _≈_ _<_ →_<_ Respects₂ _≈_trans∧tri⇒resp sym ≈-tr <-tr tri =trans∧tri⇒respʳ sym ≈-tr <-tr tri ,trans∧tri⇒respˡ ≈-tr <-tr tri-------------------------------------------------------------------------- Without Loss of Generalitymodule _ {_R_ : Rel A ℓ₁} {Q : Rel A ℓ₂} wherewlog : Total _R_ → Symmetric Q →(∀ a b → a R b → Q a b) →∀ a b → Q a bwlog r-total q-sym prf a b with r-total a b... | inj₁ aRb = prf a b aRb... | inj₂ bRa = q-sym (prf b a bRa)-------------------------------------------------------------------------- Other proofsmodule _ {R : REL A B p} wheredec⇒weaklyDec : Decidable R → WeaklyDecidable Rdec⇒weaklyDec dec x y = dec⇒maybe (dec x y)dec⇒recomputable : Decidable R → Recomputable Rdec⇒recomputable dec {a} {b} = recompute $ dec a bmodule _ {R : REL A B ℓ₁} {S : REL A B ℓ₂} wheremap-NonEmpty : R ⇒ S → NonEmpty R → NonEmpty Smap-NonEmpty f x = nonEmpty (f (NonEmpty.proof x))module _ {R : REL A B ℓ₁} {S : REL B A ℓ₂} whereflip-Connex : Connex R S → Connex S Rflip-Connex f x y = Sum.swap (f y x)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.6subst⟶respˡ = subst⇒respˡ{-# WARNING_ON_USAGE subst⟶respˡ"Warning: subst⟶respˡ was deprecated in v1.6.Please use subst⇒respˡ instead."#-}subst⟶respʳ = subst⇒respʳ{-# WARNING_ON_USAGE subst⟶respʳ"Warning: subst⟶respʳ was deprecated in v1.6.Please use subst⇒respʳ instead."#-}subst⟶resp₂ = subst⇒resp₂{-# WARNING_ON_USAGE subst⟶resp₂"Warning: subst⟶resp₂ was deprecated in v1.6.Please use subst⇒resp₂ instead."#-}P-resp⟶¬P-resp = resp⇒¬-resp{-# WARNING_ON_USAGE P-resp⟶¬P-resp"Warning: P-resp⟶¬P-resp was deprecated in v1.6.Please use resp⇒¬-resp instead."#-}total⟶refl = total⇒refl{-# WARNING_ON_USAGE total⟶refl"Warning: total⟶refl was deprecated in v1.6.Please use total⇒refl instead."#-}total+dec⟶dec = total∧dec⇒dec{-# WARNING_ON_USAGE total+dec⟶dec"Warning: total+dec⟶dec was deprecated in v1.6.Please use total∧dec⇒dec instead."#-}trans∧irr⟶asym = trans∧irr⇒asym{-# WARNING_ON_USAGE trans∧irr⟶asym"Warning: trans∧irr⟶asym was deprecated in v1.6.Please use trans∧irr⇒asym instead."#-}irr∧antisym⟶asym = irr∧antisym⇒asym{-# WARNING_ON_USAGE irr∧antisym⟶asym"Warning: irr∧antisym⟶asym was deprecated in v1.6.Please use irr∧antisym⇒asym instead."#-}asym⟶antisym = asym⇒antisym{-# WARNING_ON_USAGE asym⟶antisym"Warning: asym⟶antisym was deprecated in v1.6.Please use asym⇒antisym instead."#-}asym⟶irr = asym⇒irr{-# WARNING_ON_USAGE asym⟶irr"Warning: asym⟶irr was deprecated in v1.6.Please use asym⇒irr instead."#-}tri⟶asym = tri⇒asym{-# WARNING_ON_USAGE tri⟶asym"Warning: tri⟶asym was deprecated in v1.6.Please use tri⇒asym instead."#-}tri⟶irr = tri⇒irr{-# WARNING_ON_USAGE tri⟶irr"Warning: tri⟶irr was deprecated in v1.6.Please use tri⇒irr instead."#-}tri⟶dec≈ = tri⇒dec≈{-# WARNING_ON_USAGE tri⟶dec≈"Warning: tri⟶dec≈ was deprecated in v1.6.Please use tri⇒dec≈ instead."#-}tri⟶dec< = tri⇒dec<{-# WARNING_ON_USAGE tri⟶dec<"Warning: tri⟶dec< was deprecated in v1.6.Please use tri⇒dec< instead."#-}trans∧tri⟶respʳ≈ = trans∧tri⇒respʳ{-# WARNING_ON_USAGE trans∧tri⟶respʳ≈"Warning: trans∧tri⟶respʳ≈ was deprecated in v1.6.Please use trans∧tri⇒respʳ instead."#-}trans∧tri⟶respˡ≈ = trans∧tri⇒respˡ{-# WARNING_ON_USAGE trans∧tri⟶respˡ≈"Warning: trans∧tri⟶respˡ≈ was deprecated in v1.6.Please use trans∧tri⇒respˡ instead."#-}trans∧tri⟶resp≈ = trans∧tri⇒resp{-# WARNING_ON_USAGE trans∧tri⟶resp≈"Warning: trans∧tri⟶resp≈ was deprecated in v1.6.Please use trans∧tri⇒resp instead."#-}dec⟶weaklyDec = dec⇒weaklyDec{-# WARNING_ON_USAGE dec⟶weaklyDec"Warning: dec⟶weaklyDec was deprecated in v1.6.Please use dec⇒weaklyDec instead."#-}dec⟶recomputable = dec⇒recomputable{-# WARNING_ON_USAGE dec⟶recomputable"Warning: dec⟶recomputable was deprecated in v1.6.Please use dec⇒recomputable instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bundles for homogeneous binary relations-------------------------------------------------------------------------- The contents of this module should be accessed via `Relation.Binary`.{-# OPTIONS --cubical-compatible --safe #-}module Relation.Binary.Bundles whereopen import Function.Base using (flip)open import Level using (Level; suc; _⊔_)open import Relation.Nullary.Negation.Core using (¬_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures -- most of it-------------------------------------------------------------------------- Setoids------------------------------------------------------------------------record PartialSetoid a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓisPartialEquivalence : IsPartialEquivalence _≈_open IsPartialEquivalence isPartialEquivalence publicinfix 4 _≉__≉_ : Rel Carrier _x ≉ y = ¬ (x ≈ y)record Setoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓisEquivalence : IsEquivalence _≈_open IsEquivalence isEquivalence publicusing (refl; reflexive; isPartialEquivalence)partialSetoid : PartialSetoid c ℓpartialSetoid = record{ isPartialEquivalence = isPartialEquivalence}open PartialSetoid partialSetoid publichiding (Carrier; _≈_; isPartialEquivalence)record DecSetoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓisDecEquivalence : IsDecEquivalence _≈_open IsDecEquivalence isDecEquivalence publicusing (_≟_; isEquivalence)setoid : Setoid c ℓsetoid = record{ isEquivalence = isEquivalence}open Setoid setoid publichiding (Carrier; _≈_; isEquivalence)-------------------------------------------------------------------------- Preorders------------------------------------------------------------------------record Preorder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≲_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≲_ : Rel Carrier ℓ₂ -- The relation.isPreorder : IsPreorder _≈_ _≲_open IsPreorder isPreorder publichiding (module Eq)module Eq wheresetoid : Setoid c ℓ₁setoid = record{ isEquivalence = isEquivalence}open Setoid setoid publicinfix 4 _⋦__⋦_ : Rel Carrier _x ⋦ y = ¬ (x ≲ y)infix 4 _≳__≳_ = flip _≲_infix 4 _⋧__⋧_ = flip _⋦_-- Deprecated.infix 4 _∼__∼_ = _≲_{-# WARNING_ON_USAGE _∼_"Warning: _∼_ was deprecated in v2.0.Please use _≲_ instead. "#-}record TotalPreorder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≲_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁ -- The underlying equality._≲_ : Rel Carrier ℓ₂ -- The relation.isTotalPreorder : IsTotalPreorder _≈_ _≲_open IsTotalPreorder isTotalPreorder publicusing (total; isPreorder)preorder : Preorder c ℓ₁ ℓ₂preorder = record{ isPreorder = isPreorder}open Preorder preorder publichiding (Carrier; _≈_; _≲_; isPreorder)-------------------------------------------------------------------------- Partial orders------------------------------------------------------------------------record Poset c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_≤_ : Rel Carrier ℓ₂isPartialOrder : IsPartialOrder _≈_ _≤_open IsPartialOrder isPartialOrder publicusing (antisym; isPreorder)preorder : Preorder c ℓ₁ ℓ₂preorder = record{ isPreorder = isPreorder}open Preorder preorder publichiding (Carrier; _≈_; _≲_; isPreorder)renaming( _⋦_ to _≰_; _≳_ to _≥_; _⋧_ to _≱_; ≲-respˡ-≈ to ≤-respˡ-≈; ≲-respʳ-≈ to ≤-respʳ-≈; ≲-resp-≈ to ≤-resp-≈)record DecPoset c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_≤_ : Rel Carrier ℓ₂isDecPartialOrder : IsDecPartialOrder _≈_ _≤_private module DPO = IsDecPartialOrder isDecPartialOrderopen DPO publicusing (_≟_; _≤?_; isPartialOrder)poset : Poset c ℓ₁ ℓ₂poset = record{ isPartialOrder = isPartialOrder}open Poset poset publichiding (Carrier; _≈_; _≤_; isPartialOrder; module Eq)module Eq wheredecSetoid : DecSetoid c ℓ₁decSetoid = record{ isDecEquivalence = DPO.Eq.isDecEquivalence}open DecSetoid decSetoid publicrecord StrictPartialOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _<_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_<_ : Rel Carrier ℓ₂isStrictPartialOrder : IsStrictPartialOrder _≈_ _<_open IsStrictPartialOrder isStrictPartialOrder publichiding (module Eq)module Eq wheresetoid : Setoid c ℓ₁setoid = record{ isEquivalence = isEquivalence}open Setoid setoid publicinfix 4 _≮__≮_ : Rel Carrier _x ≮ y = ¬ (x < y)infix 4 _>__>_ = flip _<_infix 4 _≯__≯_ = flip _≮_record DecStrictPartialOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _<_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_<_ : Rel Carrier ℓ₂isDecStrictPartialOrder : IsDecStrictPartialOrder _≈_ _<_private module DSPO = IsDecStrictPartialOrder isDecStrictPartialOrderopen DSPO publicusing (_<?_; _≟_; isStrictPartialOrder)strictPartialOrder : StrictPartialOrder c ℓ₁ ℓ₂strictPartialOrder = record{ isStrictPartialOrder = isStrictPartialOrder}open StrictPartialOrder strictPartialOrder publichiding (Carrier; _≈_; _<_; isStrictPartialOrder; module Eq)module Eq wheredecSetoid : DecSetoid c ℓ₁decSetoid = record{ isDecEquivalence = DSPO.Eq.isDecEquivalence}open DecSetoid decSetoid public-------------------------------------------------------------------------- Total orders------------------------------------------------------------------------record TotalOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_≤_ : Rel Carrier ℓ₂isTotalOrder : IsTotalOrder _≈_ _≤_open IsTotalOrder isTotalOrder publicusing (total; isPartialOrder; isTotalPreorder)poset : Poset c ℓ₁ ℓ₂poset = record{ isPartialOrder = isPartialOrder}open Poset poset publichiding (Carrier; _≈_; _≤_; isPartialOrder)totalPreorder : TotalPreorder c ℓ₁ ℓ₂totalPreorder = record{ isTotalPreorder = isTotalPreorder}record DecTotalOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _≤_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_≤_ : Rel Carrier ℓ₂isDecTotalOrder : IsDecTotalOrder _≈_ _≤_private module DTO = IsDecTotalOrder isDecTotalOrderopen DTO publicusing (_≟_; _≤?_; isTotalOrder; isDecPartialOrder)totalOrder : TotalOrder c ℓ₁ ℓ₂totalOrder = record{ isTotalOrder = isTotalOrder}open TotalOrder totalOrder publichiding (Carrier; _≈_; _≤_; isTotalOrder; module Eq)decPoset : DecPoset c ℓ₁ ℓ₂decPoset = record{ isDecPartialOrder = isDecPartialOrder}open DecPoset decPoset publicusing (module Eq)-- Note that these orders are decidable. The current implementation-- of `Trichotomous` subsumes irreflexivity and asymmetry. Any reasonable-- definition capturing these three properties implies decidability-- as `Trichotomous` necessarily separates out the equality case.record StrictTotalOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _<_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_<_ : Rel Carrier ℓ₂isStrictTotalOrder : IsStrictTotalOrder _≈_ _<_open IsStrictTotalOrder isStrictTotalOrder publicusing( _≟_; _<?_; compare; isStrictPartialOrder; isDecStrictPartialOrder; isDecEquivalence)strictPartialOrder : StrictPartialOrder c ℓ₁ ℓ₂strictPartialOrder = record{ isStrictPartialOrder = isStrictPartialOrder}open StrictPartialOrder strictPartialOrder publichiding (Carrier; _≈_; _<_; isStrictPartialOrder; module Eq)decStrictPartialOrder : DecStrictPartialOrder c ℓ₁ ℓ₂decStrictPartialOrder = record{ isDecStrictPartialOrder = isDecStrictPartialOrder}open DecStrictPartialOrder decStrictPartialOrder publicusing (module Eq)decSetoid : DecSetoid c ℓ₁decSetoid = record{ isDecEquivalence = Eq.isDecEquivalence}{-# WARNING_ON_USAGE decSetoid"Warning: decSetoid was deprecated in v1.3.Please use Eq.decSetoid instead."#-}record DenseLinearOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _<_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_<_ : Rel Carrier ℓ₂isDenseLinearOrder : IsDenseLinearOrder _≈_ _<_open IsDenseLinearOrder isDenseLinearOrder publicusing (isStrictTotalOrder; dense)strictTotalOrder : StrictTotalOrder c ℓ₁ ℓ₂strictTotalOrder = record{ isStrictTotalOrder = isStrictTotalOrder}open StrictTotalOrder strictTotalOrder publichiding (Carrier; _≈_; _<_; isStrictTotalOrder)-------------------------------------------------------------------------- Apartness relations------------------------------------------------------------------------record ApartnessRelation c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 4 _≈_ _#_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_#_ : Rel Carrier ℓ₂isApartnessRelation : IsApartnessRelation _≈_ _#_open IsApartnessRelation isApartnessRelation public
-------------------------------------------------------------------------- The Agda standard library---- Support for reflection------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection where-------------------------------------------------------------------------- Re-export contents publiclyopen import Reflection.AST publicopen import Reflection.TCM publicopen import Reflection.TCM.Syntax publicusing (_>>=_; _>>_)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.import Reflection.AST.Abstraction as Abstractionimport Reflection.AST.Argument as Argumentimport Reflection.AST.Definition as Definitionimport Reflection.AST.Meta as Metaimport Reflection.AST.Name as Nameimport Reflection.AST.Literal as Literalimport Reflection.AST.Pattern as Patternimport Reflection.AST.Term as Termimport Reflection.AST.Argument.Modality as Modalityimport Reflection.AST.Argument.Quantity as Quantityimport Reflection.AST.Argument.Relevance as Relevanceimport Reflection.AST.Argument.Visibility as Visibilityimport Reflection.AST.Argument.Information as Information-- Version 1.3Arg-info = Information.ArgInfo{-# WARNING_ON_USAGE Arg-info"Warning: Arg-info was deprecated in v1.3.Please use Reflection.AST.Argument.Information's ArgInfo instead."#-}infix 4 _≟-Lit_ _≟-Name_ _≟-Meta_ _≟-Visibility_ _≟-Relevance_ _≟-Arg-info__≟-Pattern_ _≟-ArgPatterns__≟-Lit_ = Literal._≟_{-# WARNING_ON_USAGE _≟-Lit_"Warning: _≟-Lit_ was deprecated in v1.3.Please use Reflection.AST.Literal's _≟_ instead."#-}_≟-Name_ = Name._≟_{-# WARNING_ON_USAGE _≟-Name_"Warning: _≟-Name_ was deprecated in v1.3.Please use Reflection.AST.Name's _≟_ instead."#-}_≟-Meta_ = Meta._≟_{-# WARNING_ON_USAGE _≟-Meta_"Warning: _≟-Meta_ was deprecated in v1.3.Please use Reflection.AST.Meta's _≟_ instead."#-}_≟-Visibility_ = Visibility._≟_{-# WARNING_ON_USAGE _≟-Visibility_"Warning: _≟-Visibility_ was deprecated in v1.3.Please use Reflection.AST.Argument.Visibility's _≟_ instead."#-}_≟-Relevance_ = Relevance._≟_{-# WARNING_ON_USAGE _≟-Relevance_"Warning: _≟-Relevance_ was deprecated in v1.3.Please use Reflection.AST.Argument.Relevance's _≟_ instead."#-}_≟-Arg-info_ = Information._≟_{-# WARNING_ON_USAGE _≟-Arg-info_"Warning: _≟-Arg-info_ was deprecated in v1.3.Please use Reflection.AST.Argument.Information's _≟_ instead."#-}_≟-Pattern_ = Pattern._≟_{-# WARNING_ON_USAGE _≟-Pattern_"Warning: _≟-Pattern_ was deprecated in v1.3.Please use Reflection.AST.Pattern's _≟_ instead."#-}_≟-ArgPatterns_ = Pattern._≟s_{-# WARNING_ON_USAGE _≟-ArgPatterns_"Warning: _≟-ArgPatterns_ was deprecated in v1.3.Please use Reflection.AST.Pattern's _≟s_ instead."#-}map-Abs = Abstraction.map{-# WARNING_ON_USAGE map-Abs"Warning: map-Abs was deprecated in v1.3.Please use Reflection.AST.Abstraction's map instead."#-}map-Arg = Argument.map{-# WARNING_ON_USAGE map-Arg"Warning: map-Arg was deprecated in v1.3.Please use Reflection.AST.Argument's map instead."#-}map-Args = Argument.map-Args{-# WARNING_ON_USAGE map-Args"Warning: map-Args was deprecated in v1.3.Please use Reflection.AST.Argument's map-Args instead."#-}visibility = Information.visibility{-# WARNING_ON_USAGE visibility"Warning: visibility was deprecated in v1.3.Please use Reflection.AST.Argument.Information's visibility instead."#-}relevance = Modality.relevance{-# WARNING_ON_USAGE relevance"Warning: relevance was deprecated in v1.3.Please use Reflection.AST.Argument.Modality's relevance instead."#-}infix 4 _≟-AbsTerm_ _≟-AbsType_ _≟-ArgTerm_ _≟-ArgType_ _≟-Args__≟-Clause_ _≟-Clauses_ _≟__≟-Sort__≟-AbsTerm_ = Term._≟-AbsTerm_{-# WARNING_ON_USAGE _≟-AbsTerm_"Warning: _≟-AbsTerm_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-AbsTerm_ instead."#-}_≟-AbsType_ = Term._≟-AbsType_{-# WARNING_ON_USAGE _≟-AbsType_"Warning: _≟-AbsType_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-AbsType_ instead."#-}_≟-ArgTerm_ = Term._≟-ArgTerm_{-# WARNING_ON_USAGE _≟-ArgTerm_"Warning: _≟-ArgTerm_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-ArgTerm_ instead."#-}_≟-ArgType_ = Term._≟-ArgType_{-# WARNING_ON_USAGE _≟-ArgType_"Warning: _≟-ArgType_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-ArgType_ instead."#-}_≟-Args_ = Term._≟-Args_{-# WARNING_ON_USAGE _≟-Args_"Warning: _≟-Args_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-Args_ instead."#-}_≟-Clause_ = Term._≟-Clause_{-# WARNING_ON_USAGE _≟-Clause_"Warning: _≟-Clause_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-Clause_ instead."#-}_≟-Clauses_ = Term._≟-Clauses_{-# WARNING_ON_USAGE _≟-Clauses_"Warning: _≟-Clauses_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-Clauses_ instead."#-}_≟_ = Term._≟_{-# WARNING_ON_USAGE _≟_"Warning: _≟_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟_ instead."#-}_≟-Sort_ = Term._≟-Sort_{-# WARNING_ON_USAGE _≟-Sort_"Warning: _≟-Sort_ was deprecated in v1.3.Please use Reflection.AST.Term's _≟-Sort_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The TC (Type Checking) monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM whereimport Agda.Builtin.Reflection as Builtinopen import Reflection.AST.Termimport Reflection.TCM.Format as Format-------------------------------------------------------------------------- Type errorsopen Builtin publicusing (ErrorPart; strErr; termErr; nameErr)-------------------------------------------------------------------------- The monadopen Builtin publicusing( TC; bindTC; unify; typeError; inferType; checkType; normalise; reduce; catchTC; quoteTC; unquoteTC; getContext; extendContext; inContext; freshName; declareDef; declarePostulate; defineFun; getType; getDefinition; blockOnMeta; commitTC; isMacro; withNormalisation; debugPrint; noConstraints; runSpeculative; Blocker; blockerMeta; blockerAny; blockerAll; blockTC)renaming (returnTC to pure)open Format publicusing (typeErrorFmt; debugPrintFmt; errorPartFmt)-------------------------------------------------------------------------- Utility functionsnewMeta : Type → TC TermnewMeta = checkType unknown
-------------------------------------------------------------------------- The Agda standard library---- Reflection utilities------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Utilities whereopen import Data.List using (List; []; _∷_; _++_; map)open import Data.Unit using (⊤; tt)open import Effect.Applicative using (RawApplicative; mkRawApplicative)open import Function using (case_of_)open import Reflection.AST.Meta using (Meta)open import Reflection.AST.Term using (Term)open import Reflection.TCM using (TC; pure; blockTC; blockerAll; blockerMeta)import Reflection.AST.Traversal as TraversalblockOnMetas : Term → TC ⊤blockOnMetas t =case traverseTerm actions (0 , []) t of λ where[] → pure ttxs@(_ ∷ _) → blockTC (blockerAll (map blockerMeta xs))whereapplicative : ∀ {ℓ} → RawApplicative {ℓ} (λ _ → List Meta)applicative = mkRawApplicative (λ _ → List Meta) (λ _ → []) _++_open Traversal applicativeactions : Actionsactions = record defaultActions { onMeta = λ _ x → x ∷ [] }
-------------------------------------------------------------------------- The Agda standard library---- Monad syntax for the TC monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Syntax whereopen import Agda.Builtin.Reflectionopen import Level using (Level)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Monad syntaxinfixl 3 _<|>__<|>_ : TC A → TC A → TC A_<|>_ = catchTC{-# INLINE _<|>_ #-}infixl 1 _>>=_ _>>_ _<&>__>>=_ : TC A → (A → TC B) → TC B_>>=_ = bindTC{-# INLINE _>>=_ #-}_>>_ : TC A → TC B → TC Bxs >> ys = bindTC xs (λ _ → ys){-# INLINE _>>_ #-}infixl 4 _<$>_ _<*>_ _<$__<*>_ : TC (A → B) → TC A → TC Bfs <*> xs = bindTC fs (λ f → bindTC xs (λ x → returnTC (f x))){-# INLINE _<*>_ #-}_<$>_ : (A → B) → TC A → TC Bf <$> xs = bindTC xs (λ x → returnTC (f x)){-# INLINE _<$>_ #-}_<$_ : A → TC B → TC Ax <$ xs = bindTC xs (λ _ → returnTC x){-# INLINE _<$_ #-}_<&>_ : TC A → (A → B) → TC Bxs <&> f = bindTC xs (λ x → returnTC (f x)){-# INLINE _<&>_ #-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for TC------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Instances whereopen import Reflection.TCM.EffectfulinstancetcFunctor = functortcApplicative = applicativetcApplicativeZero = applicativeZerotcAlternative = alternativetcMonad = monadtcMonadZero = monadZerotcMonadPlus = monadPlus
-------------------------------------------------------------------------- The Agda standard library---- Printf-style versions of typeError and debugPrint------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Format whereopen import Agda.Builtin.Reflection using (Name; Term; ErrorPart; termErr; nameErr; strErr;TC; typeError; debugPrint)open import Level using (Level)open import Function.Base using (_∘_)open import Data.List.Base using (List; [_]; concat)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Nat.Base using (ℕ)open import Data.String.Base using (String)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Unit.Base using (⊤)import Text.Format as StdFormat using (formatSpec)import Text.Printf as StdPrintf using (printfSpec)open import Text.Format.Genericopen import Text.Printf.Genericprivatevariableℓ : LevelA : Set ℓ-------------------------------------------------------------------------- Format specification.-- This extends the formats from Text.Printf with-- %t - Term-- %q - Name-- %e - List ErrorPart-- Rendering goes to List ErrorPart.module Specification wheredata ErrorChunk : Set where`Term `Name `Parts : ErrorChunkerrorSpec : FormatSpecerrorSpec .FormatSpec.ArgChunk = ErrorChunkerrorSpec .FormatSpec.ArgType `Term = TermerrorSpec .FormatSpec.ArgType `Name = NameerrorSpec .FormatSpec.ArgType `Parts = List ErrorParterrorSpec .FormatSpec.lexArg 't' = just `TermerrorSpec .FormatSpec.lexArg 'q' = just `NameerrorSpec .FormatSpec.lexArg 'e' = just `PartserrorSpec .FormatSpec.lexArg _ = nothingformatSpec : FormatSpecformatSpec = unionSpec errorSpec StdFormat.formatSpecopen PrintfSpecprintfSpec : PrintfSpec formatSpec (List ErrorPart)printfSpec .renderArg (inj₁ `Term) t = [ termErr t ]printfSpec .renderArg (inj₁ `Name) n = [ nameErr n ]printfSpec .renderArg (inj₁ `Parts) es = esprintfSpec .renderArg (inj₂ arg) x = [ strErr (StdPrintf.printfSpec .renderArg arg x) ]printfSpec .renderStr s = [ strErr s ]open Specificationopen Format formatSpecopen Type formatSpec renaming (map to mapPrintf)open Render printfSpec-------------------------------------------------------------------------- Printf versions of typeError and debugPrinttypeErrorFmt : (fmt : String) → Printf (lexer fmt) (TC A)typeErrorFmt fmt = mapPrintf (lexer fmt) (typeError ∘ concat) (printf fmt)debugPrintFmt : String → ℕ → (fmt : String) → Printf (lexer fmt) (TC ⊤)debugPrintFmt tag lvl fmt = mapPrintf (lexer fmt) (debugPrint tag lvl ∘ concat) (printf fmt)-- Combine with "%e" format for nested format calls.errorPartFmt : (fmt : String) → Printf (lexer fmt) (List ErrorPart)errorPartFmt fmt = mapPrintf (lexer fmt) concat (printf fmt)
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for TC------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Effectful whereopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Data.List.Base using ([])open import Function.Base using (_∘_)open import Levelopen import Reflection.TCMprivatevariableℓ : Levelfunctor : RawFunctor {ℓ} TCfunctor = record{ _<$>_ = λ f mx → bindTC mx (pure ∘ f)}applicative : RawApplicative {ℓ} TCapplicative = record{ rawFunctor = functor; pure = pure; _<*>_ = λ mf mx → bindTC mf λ f → bindTC mx (pure ∘ f)}empty : RawEmpty {ℓ} TCempty = record { empty = typeError [] }applicativeZero : RawApplicativeZero {ℓ} TCapplicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}choice : RawChoice {ℓ} TCchoice = record { _<|>_ = catchTC }alternative : RawAlternative {ℓ} TCalternative = record{ rawApplicativeZero = applicativeZero; rawChoice = choice}monad : RawMonad {ℓ} TCmonad = record{ rawApplicative = applicative; _>>=_ = bindTC}monadZero : RawMonadZero {ℓ} TCmonadZero = record{ rawMonad = monad; rawEmpty = empty}monadPlus : RawMonadPlus {ℓ} TCmonadPlus = record{ rawMonadZero = monadZero; rawChoice = choice}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Reflection.TCM.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.TCM.Categorical whereopen import Reflection.TCM.Effectful public{-# WARNING_ON_IMPORT"Reflection.TCM.Categorical was deprecated in v2.0.Use Reflection.TCM.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Support for system calls as part of reflection------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.External whereimport Agda.Builtin.Reflection.External as Builtinopen import Data.Nat.Base using (ℕ; suc; zero; NonZero)open import Data.List.Base using (List; _∷_; [])open import Data.Product.Base using (_×_; _,_)open import Data.String.Base as String using (String; _++_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Data.Unit.Base using (⊤; tt)open import Function.Base using (case_of_; _$_; _∘_)open import Reflection hiding (name)-- Type aliases for the various strings.CmdName = StringStdIn = StringStdErr = StringStdOut = String-- Representation for exit codes, assuming 0 is consistently used to-- indicate success across platforms.data ExitCode : Set whereexitSuccess : ExitCodeexitFailure : (n : ℕ) {n≢0 : NonZero n} → ExitCode-- Specification for a command.record CmdSpec : Set whereconstructor cmdSpecfieldname : CmdName -- ^ Executable name (see ~/.agda/executables)args : List String -- ^ Command-line arguments for executableinput : StdIn -- ^ Contents of standard input-- Result of running a command.record Result : Set whereconstructor resultfieldexitCode : ExitCode -- ^ Exit code returned by the processoutput : StdOut -- ^ Contents of standard outputerror : StdErr -- ^ Contents of standard error-- Convert a natural number to an exit code.toExitCode : ℕ → ExitCodetoExitCode zero = exitSuccesstoExitCode (suc n) = exitFailure (suc n)-- Quote an exit code as an Agda term.quoteExitCode : ExitCode → TermquoteExitCode exitSuccess =con (quote exitSuccess) []quoteExitCode (exitFailure n) =con (quote exitFailure) (vArg (lit (nat n)) ∷ hArg (con (quote tt) []) ∷ [])-- Quote a result as an Agda term.quoteResult : Result → TermquoteResult (result exitCode output error) =con (quote result) $ vArg (quoteExitCode exitCode)∷ vArg (lit (string output))∷ vArg (lit (string error))∷ []-- Run command from specification and return the full result.---- NOTE: If the command fails, this macro still succeeds, and returns the-- full result, including exit code and the contents of stderr.--unsafeRunCmdTC : CmdSpec → TC ResultunsafeRunCmdTC c = do(exitCode , (stdOut , stdErr))← Builtin.execTC (CmdSpec.name c) (CmdSpec.args c) (CmdSpec.input c)pure $ result (toExitCode exitCode) stdOut stdErrmacrounsafeRunCmd : CmdSpec → Term → TC ⊤unsafeRunCmd c hole = unsafeRunCmdTC c >>= unify hole ∘ quoteResult-- Show a command for the user.showCmdSpec : CmdSpec → StringshowCmdSpec c = String.unwords $ CmdSpec.name c ∷ CmdSpec.args cprivate-- Helper function for throwing an error from reflection.userError : ∀ {a} {A : Set a} → CmdSpec → StdOut × StdErr → TC AuserError c (stdout , stderr) = typeError (strErr errMsg ∷ [])whereerrMsg : StringerrMsg = String.unlines$ ("Error while running command '" ++ showCmdSpec c ++ "'")∷ ("Input:\n" ++ CmdSpec.input c)∷ ("Output:\n" ++ stdout)∷ ("Error:\n" ++ stderr)∷ []-- Run command from specification. If the command succeeds, it returns the-- contents of stdout. Otherwise, it throws a type error with the contents-- of stderr.runCmdTC : CmdSpec → TC StdOutrunCmdTC c = dor ← unsafeRunCmdTC clet debugPrefix = ("user." ++ CmdSpec.name c)case Result.exitCode r of λ{ exitSuccess → dodebugPrint (debugPrefix ++ ".stderr") 10 (strErr (Result.error r) ∷ [])pure $ Result.output r; (exitFailure n) → douserError c (Result.output r , Result.error r)}macrorunCmd : CmdSpec → Term → TC ⊤runCmd c hole = runCmdTC c >>= unify hole ∘ lit ∘ string
-------------------------------------------------------------------------- The Agda standard library---- Annotated reflected syntax.---- NOTE: This file does not check under --cubical-compatible due to-- restrictions in the termination checker. In particular-- recursive functions over a universe of types is not supported-- by --cubical-compatible.------------------------------------------------------------------------{-# OPTIONS --safe --with-K #-}module Reflection.AnnotatedAST whereopen import Level using (Level; 0ℓ; suc; _⊔_)open import Effect.Applicative using (RawApplicative)open import Data.Bool.Base using (Bool; false; true; if_then_else_)open import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Unary.All using (All; _∷_; [])open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.String.Base using (String)open import Reflection hiding (pure)open import Reflection.AST.Universeopen Clauseopen Patternopen Sort-------------------------------------------------------------------------- Annotations and annotated types-- An Annotation is a type indexed by a reflected term.Annotation : ∀ ℓ → Set (suc ℓ)Annotation ℓ = ∀ {u} → ⟦ u ⟧ → Set ℓ-- An annotated type is a family over an Annotation and a reflected term.Typeₐ : ∀ ℓ → Univ → Set (suc (suc ℓ))Typeₐ ℓ u = Annotation ℓ → ⟦ u ⟧ → Set (suc ℓ)privatevariableℓ : Levelu : UnivAnn Ann₁ Ann₂ : Annotation ℓ-- ⟪_⟫ packs up an element of an annotated type with a top-level annotation.infixr 30 ⟨_⟩_data ⟪_⟫ {u} (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ u where⟨_⟩_ : ∀ {t} → Ann t → Tyₐ Ann t → ⟪ Tyₐ ⟫ Ann tann : {Tyₐ : Typeₐ ℓ u} {t : ⟦ u ⟧} → ⟪ Tyₐ ⟫ Ann t → Ann tann (⟨ α ⟩ _) = α-------------------------------------------------------------------------- Annotated reflected syntax-- Annotated lists are lists (All) of annotated values. No top-level-- annotation added, since we don't want an annotation for every tail-- of a list. Instead a top-level annotation is added on the outside.-- See Argsₐ.Listₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨list⟩ u)Listₐ Tyₐ Ann = All (Tyₐ Ann)-- We define the rest of the annotated types in two variants:-- The primed variant which has annotations on subterms, and the-- non-primed variant which adds a top-level annotation to the primed-- one.data Absₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨abs⟩ u) whereabs : ∀ {t} x → Tyₐ Ann t → Absₐ′ Tyₐ Ann (abs x t)Absₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨abs⟩ u)Absₐ Tyₐ = ⟪ Absₐ′ Tyₐ ⟫data Argₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨arg⟩ u) wherearg : ∀ {t} i → Tyₐ Ann t → Argₐ′ Tyₐ Ann (arg i t)Argₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨arg⟩ u)Argₐ Tyₐ = ⟪ Argₐ′ Tyₐ ⟫data Namedₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨named⟩ u) where_,_ : ∀ {t} x → Tyₐ Ann t → Namedₐ′ Tyₐ Ann (x , t)infixr 4 _,_Namedₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨named⟩ u)Namedₐ Tyₐ = ⟪ Namedₐ′ Tyₐ ⟫-- Add a top-level annotation for Args.Argsₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨list⟩ (⟨arg⟩ u))Argsₐ Tyₐ = ⟪ Listₐ (Argₐ Tyₐ) ⟫mutualTermₐ : Typeₐ ℓ ⟨term⟩Termₐ = ⟪ Termₐ′ ⟫Patternₐ : Typeₐ ℓ ⟨pat⟩Patternₐ = ⟪ Patternₐ′ ⟫Sortₐ : Typeₐ ℓ ⟨sort⟩Sortₐ = ⟪ Sortₐ′ ⟫Clauseₐ : Typeₐ ℓ ⟨clause⟩Clauseₐ = ⟪ Clauseₐ′ ⟫Clausesₐ : Typeₐ ℓ (⟨list⟩ ⟨clause⟩)Clausesₐ = ⟪ Listₐ Clauseₐ ⟫Telₐ : Typeₐ ℓ ⟨tel⟩Telₐ = ⟪ Listₐ (Namedₐ (Argₐ Termₐ)) ⟫data Termₐ′ {ℓ} : Typeₐ ℓ ⟨term⟩ wherevar : ∀ x {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (var x args)con : ∀ c {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (con c args)def : ∀ f {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (def f args)lam : ∀ v {b} → Absₐ Termₐ Ann b → Termₐ′ Ann (lam v b)pat-lam : ∀ {cs args} → Clausesₐ Ann cs → Argsₐ Termₐ Ann args →Termₐ′ Ann (pat-lam cs args)pi : ∀ {a b} → Argₐ Termₐ Ann a → Absₐ Termₐ Ann b → Termₐ′ Ann (pi a b)agda-sort : ∀ {s} → Sortₐ Ann s → Termₐ′ Ann (agda-sort s)lit : ∀ l → Termₐ′ Ann (lit l)meta : ∀ x {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (meta x args)unknown : Termₐ′ Ann unknowndata Clauseₐ′ {ℓ} : Typeₐ ℓ ⟨clause⟩ whereclause : ∀ {tel ps t} → Telₐ Ann tel → Argsₐ Patternₐ Ann ps →Termₐ Ann t → Clauseₐ′ Ann (clause tel ps t)absurd-clause : ∀ {tel ps} → Telₐ Ann tel → Argsₐ Patternₐ Ann ps →Clauseₐ′ Ann (absurd-clause tel ps)data Sortₐ′ {ℓ} : Typeₐ ℓ ⟨sort⟩ whereset : ∀ {t} → Termₐ Ann t → Sortₐ′ Ann (set t)lit : ∀ n → Sortₐ′ Ann (lit n)prop : ∀ {t} → Termₐ Ann t → Sortₐ′ Ann (prop t)propLit : ∀ n → Sortₐ′ Ann (propLit n)inf : ∀ n → Sortₐ′ Ann (inf n)unknown : Sortₐ′ Ann unknowndata Patternₐ′ {ℓ} : Typeₐ ℓ ⟨pat⟩ wherecon : ∀ c {ps} → Argsₐ Patternₐ Ann ps → Patternₐ′ Ann (con c ps)dot : ∀ {t} → Termₐ Ann t → Patternₐ′ Ann (dot t)var : ∀ x → Patternₐ′ Ann (var x)lit : ∀ l → Patternₐ′ Ann (lit l)proj : ∀ f → Patternₐ′ Ann (proj f)absurd : ∀ x → Patternₐ′ Ann (absurd x)-- Mapping a code in the universe to its corresponding primed and-- non-primed annotated type.mutualAnnotated′ : Typeₐ ℓ uAnnotated′ {u = ⟨term⟩} = Termₐ′Annotated′ {u = ⟨pat⟩} = Patternₐ′Annotated′ {u = ⟨sort⟩} = Sortₐ′Annotated′ {u = ⟨clause⟩} = Clauseₐ′Annotated′ {u = ⟨list⟩ u} = Listₐ AnnotatedAnnotated′ {u = ⟨arg⟩ u} = Argₐ′ AnnotatedAnnotated′ {u = ⟨abs⟩ u} = Absₐ′ AnnotatedAnnotated′ {u = ⟨named⟩ u} = Namedₐ′ AnnotatedAnnotated : Typeₐ ℓ uAnnotated = ⟪ Annotated′ ⟫-------------------------------------------------------------------------- Annotating terms-- An annotation function computes the top-level annotation given a-- term annotated at all sub-terms.AnnotationFun : Annotation ℓ → Set (suc ℓ)AnnotationFun Ann = ∀ u {t : ⟦ u ⟧} → Annotated′ Ann t → Ann t-- Given an annotation function we can do the bottom-up traversal of a-- reflected term to compute an annotated version.module _ (annFun : AnnotationFun Ann) whereprivateannotated : {t : ⟦ u ⟧} → Annotated′ Ann t → Annotated Ann tannotated ps = ⟨ annFun _ ps ⟩ psmutualannotate′ : (t : ⟦ u ⟧) → Annotated′ Ann tannotate′ {⟨term⟩} (var x args) = var x (annotate args)annotate′ {⟨term⟩} (con c args) = con c (annotate args)annotate′ {⟨term⟩} (def f args) = def f (annotate args)annotate′ {⟨term⟩} (lam v t) = lam v (annotate t)annotate′ {⟨term⟩} (pat-lam cs args) = pat-lam (annotate cs) (annotate args)annotate′ {⟨term⟩} (pi a b) = pi (annotate a) (annotate b)annotate′ {⟨term⟩} (agda-sort s) = agda-sort (annotate s)annotate′ {⟨term⟩} (lit l) = lit lannotate′ {⟨term⟩} (meta x args) = meta x (annotate args)annotate′ {⟨term⟩} unknown = unknownannotate′ {⟨pat⟩} (con c ps) = con c (annotate ps)annotate′ {⟨pat⟩} (dot t) = dot (annotate t)annotate′ {⟨pat⟩} (var x) = var xannotate′ {⟨pat⟩} (lit l) = lit lannotate′ {⟨pat⟩} (proj f) = proj fannotate′ {⟨pat⟩} (absurd x) = absurd xannotate′ {⟨sort⟩} (set t) = set (annotate t)annotate′ {⟨sort⟩} (lit n) = lit nannotate′ {⟨sort⟩} (prop t) = prop (annotate t)annotate′ {⟨sort⟩} (propLit n) = propLit nannotate′ {⟨sort⟩} (inf n) = inf nannotate′ {⟨sort⟩} unknown = unknownannotate′ {⟨clause⟩} (clause tel ps t) = clause (annotate tel) (annotate ps) (annotate t)annotate′ {⟨clause⟩} (absurd-clause tel ps) = absurd-clause (annotate tel) (annotate ps)annotate′ {⟨abs⟩ u} (abs x t) = abs x (annotate t)annotate′ {⟨arg⟩ u} (arg i t) = arg i (annotate t)annotate′ {⟨list⟩ u} [] = []annotate′ {⟨list⟩ u} (x ∷ xs) = annotate x ∷ annotate′ xsannotate′ {⟨named⟩ u} (x , t) = x , annotate tannotate : (t : ⟦ u ⟧) → Annotated Ann tannotate t = annotated (annotate′ t)-------------------------------------------------------------------------- Annotation function combinators-- Mapping over annotationsmutualmap′ : ∀ u → (∀ {u} {t : ⟦ u ⟧} → Ann₁ t → Ann₂ t) → {t : ⟦ u ⟧} → Annotated′ Ann₁ t → Annotated′ Ann₂ tmap′ ⟨term⟩ f (var x args) = var x (map f args)map′ ⟨term⟩ f (con c args) = con c (map f args)map′ ⟨term⟩ f (def h args) = def h (map f args)map′ ⟨term⟩ f (lam v b) = lam v (map f b)map′ ⟨term⟩ f (pat-lam cs args) = pat-lam (map f cs) (map f args)map′ ⟨term⟩ f (pi a b) = pi (map f a) (map f b)map′ ⟨term⟩ f (agda-sort s) = agda-sort (map f s)map′ ⟨term⟩ f (lit l) = lit lmap′ ⟨term⟩ f (meta x args) = meta x (map f args)map′ ⟨term⟩ f unknown = unknownmap′ ⟨pat⟩ f (con c ps) = con c (map f ps)map′ ⟨pat⟩ f (dot t) = dot (map f t)map′ ⟨pat⟩ f (var x) = var xmap′ ⟨pat⟩ f (lit l) = lit lmap′ ⟨pat⟩ f (proj g) = proj gmap′ ⟨pat⟩ f (absurd x) = absurd xmap′ ⟨sort⟩ f (set t) = set (map f t)map′ ⟨sort⟩ f (lit n) = lit nmap′ ⟨sort⟩ f (prop t) = prop (map f t)map′ ⟨sort⟩ f (propLit n) = propLit nmap′ ⟨sort⟩ f (inf n) = inf nmap′ ⟨sort⟩ f unknown = unknownmap′ ⟨clause⟩ f (clause Γ ps args) = clause (map f Γ) (map f ps) (map f args)map′ ⟨clause⟩ f (absurd-clause Γ ps) = absurd-clause (map f Γ) (map f ps)map′ (⟨list⟩ u) f [] = []map′ (⟨list⟩ u) f (x ∷ xs) = map f x ∷ map′ _ f xsmap′ (⟨arg⟩ u) f (arg i x) = arg i (map f x)map′ (⟨abs⟩ u) f (abs x t) = abs x (map f t)map′ (⟨named⟩ u) f (x , t) = x , map f tmap : (∀ {u} {t : ⟦ u ⟧} → Ann₁ t → Ann₂ t) → ∀ {u} {t : ⟦ u ⟧} → Annotated Ann₁ t → Annotated Ann₂ tmap f {u = u} (⟨ α ⟩ t) = ⟨ f α ⟩ map′ u f tmodule _ {W : Set ℓ} (ε : W) (_∪_ : W → W → W) where-- This annotation function does nothing except combine ε's with _∪_.-- Lets you skip the boring cases when defining non-dependent-- annotation functions by adding a catch-all calling defaultAnn.defaultAnn : AnnotationFun (λ _ → W)defaultAnn ⟨term⟩ (var x args) = ann argsdefaultAnn ⟨term⟩ (con c args) = ann argsdefaultAnn ⟨term⟩ (def f args) = ann argsdefaultAnn ⟨term⟩ (lam v b) = ann bdefaultAnn ⟨term⟩ (pat-lam cs args) = ann cs ∪ ann argsdefaultAnn ⟨term⟩ (pi a b) = ann a ∪ ann bdefaultAnn ⟨term⟩ (agda-sort s) = ann sdefaultAnn ⟨term⟩ (lit l) = εdefaultAnn ⟨term⟩ (meta x args) = ann argsdefaultAnn ⟨term⟩ unknown = εdefaultAnn ⟨pat⟩ (con c args) = ann argsdefaultAnn ⟨pat⟩ (dot t) = ann tdefaultAnn ⟨pat⟩ (var x) = εdefaultAnn ⟨pat⟩ (lit l) = εdefaultAnn ⟨pat⟩ (proj f) = εdefaultAnn ⟨pat⟩ (absurd x) = εdefaultAnn ⟨sort⟩ (set t) = ann tdefaultAnn ⟨sort⟩ (lit n) = εdefaultAnn ⟨sort⟩ (prop t) = ann tdefaultAnn ⟨sort⟩ (propLit n) = εdefaultAnn ⟨sort⟩ (inf n) = εdefaultAnn ⟨sort⟩ unknown = εdefaultAnn ⟨clause⟩ (clause Γ ps t) = ann Γ ∪ (ann ps ∪ ann t)defaultAnn ⟨clause⟩ (absurd-clause Γ ps) = ann Γ ∪ ann psdefaultAnn (⟨list⟩ u) [] = εdefaultAnn (⟨list⟩ u) (x ∷ xs) = ann x ∪ defaultAnn _ xsdefaultAnn (⟨arg⟩ u) (arg i x) = ann xdefaultAnn (⟨abs⟩ u) (abs x t) = ann tdefaultAnn (⟨named⟩ u) (x , t) = ann t-- Cartisian product of two annotation functions.infixr 4 _⊗__⊗_ : AnnotationFun Ann₁ → AnnotationFun Ann₂ → AnnotationFun (λ t → Ann₁ t × Ann₂ t)(f ⊗ g) u t = f u (map′ u proj₁ t) , g u (map′ u proj₂ t)-------------------------------------------------------------------------- Annotation-driven traversal-- Top-down applicative traversal of an annotated term. Applies an-- action (without going into subterms) to terms whose annotation-- satisfies a given criterion. Returns an unannotated term.module Traverse {M : Set → Set} (appl : RawApplicative M) whereopen RawApplicative applmodule _ (apply? : ∀ {u} {t : ⟦ u ⟧} → Ann t → Bool)(action : ∀ {u} {t : ⟦ u ⟧} → Annotated Ann t → M ⟦ u ⟧) wheremutualtraverse′ : {t : ⟦ u ⟧} → Annotated′ Ann t → M ⟦ u ⟧traverse′ {⟨term⟩} (var x args) = var x <$> traverse argstraverse′ {⟨term⟩} (con c args) = con c <$> traverse argstraverse′ {⟨term⟩} (def f args) = def f <$> traverse argstraverse′ {⟨term⟩} (lam v b) = lam v <$> traverse btraverse′ {⟨term⟩} (pat-lam cs args) = pat-lam <$> traverse cs <*> traverse argstraverse′ {⟨term⟩} (pi a b) = pi <$> traverse a <*> traverse btraverse′ {⟨term⟩} (agda-sort s) = agda-sort <$> traverse straverse′ {⟨term⟩} (lit l) = pure (lit l)traverse′ {⟨term⟩} (meta x args) = meta x <$> traverse argstraverse′ {⟨term⟩} unknown = pure unknowntraverse′ {⟨pat⟩} (con c args) = con c <$> traverse argstraverse′ {⟨pat⟩} (dot t) = dot <$> traverse ttraverse′ {⟨pat⟩} (var x) = pure (var x)traverse′ {⟨pat⟩} (lit l) = pure (lit l)traverse′ {⟨pat⟩} (proj f) = pure (proj f)traverse′ {⟨pat⟩} (absurd x) = pure (absurd x)traverse′ {⟨sort⟩} (set t) = set <$> traverse ttraverse′ {⟨sort⟩} (lit n) = pure (lit n)traverse′ {⟨sort⟩} (prop t) = prop <$> traverse ttraverse′ {⟨sort⟩} (propLit n) = pure (propLit n)traverse′ {⟨sort⟩} (inf n) = pure (inf n)traverse′ {⟨sort⟩} unknown = pure unknowntraverse′ {⟨clause⟩} (clause Γ ps t) = clause <$> traverse Γ <*> traverse ps <*> traverse ttraverse′ {⟨clause⟩} (absurd-clause Γ ps) = absurd-clause <$> traverse Γ <*> traverse pstraverse′ {⟨list⟩ u} [] = pure []traverse′ {⟨list⟩ u} (x ∷ xs) = _∷_ <$> traverse x <*> traverse′ xstraverse′ {⟨arg⟩ u} (arg i x) = arg i <$> traverse xtraverse′ {⟨abs⟩ u} (abs x t) = abs x <$> traverse ttraverse′ {⟨named⟩ u} (x , t) = x ,_ <$> traverse ttraverse : {t : ⟦ u ⟧} → Annotated Ann t → M ⟦ u ⟧traverse t@(⟨ α ⟩ tₐ) = if apply? α then action t else traverse′ tₐ
-------------------------------------------------------------------------- The Agda standard library---- Computing free variable annotations on reflected syntax.------------------------------------------------------------------------{-# OPTIONS --safe --with-K #-}module Reflection.AnnotatedAST.Free whereopen import Data.Bool.Base using (if_then_else_)open import Data.Nat.Base using (ℕ; _∸_; compare; _<ᵇ_; less; equal; greater)open import Data.List.Base using (List; []; _∷_; [_]; concatMap; length)open import Data.List.Relation.Unary.All using (_∷_)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.String.Base using (String)open import Reflectionopen import Reflection.AST.Universeopen import Reflection.AnnotatedAST-------------------------------------------------------------------------- Free variable sets as lists of natural numbersFVs : SetFVs = List ℕ -- ordered, no duplicatesprivateinfixr 3 _∪__∪_ : FVs → FVs → FVs[] ∪ ys = ysxs ∪ [] = xsx ∷ xs ∪ y ∷ ys with compare x y | x ∷ xs ∪ ys... | less x _ | _ = x ∷ (xs ∪ y ∷ ys)... | equal x | _ = x ∷ (xs ∪ ys)... | greater y _ | rec = y ∷ recinsert : ℕ → FVs → FVsinsert x [] = x ∷ []insert x (y ∷ xs) with compare x y... | less x k = x ∷ y ∷ xs... | equal x = y ∷ xs... | greater y k = y ∷ insert x xsclose : ℕ → FVs → FVsclose k = concatMap λ x → if x <ᵇ k then [] else [ x ∸ k ]-------------------------------------------------------------------------- Annotation function computing free variablesfreeVars : AnnotationFun (λ _ → FVs)freeVars ⟨term⟩ (var x (⟨ fv ⟩ _)) = insert x fvfreeVars ⟨pat⟩ (var x) = x ∷ []freeVars ⟨pat⟩ (absurd x) = x ∷ []-- Note: variables are bound in the clause telescope, so we treat pattern variables as freefreeVars ⟨clause⟩ (clause {tel = Γ} (⟨ fvΓ ⟩ _) (⟨ fvps ⟩ _) (⟨ fvt ⟩ _)) = fvΓ ∪ close (length Γ) (fvps ∪ fvt)freeVars ⟨clause⟩ (absurd-clause {tel = Γ} (⟨ fvΓ ⟩ _) (⟨ fvps ⟩ _)) = fvΓ ∪ close (length Γ) fvpsfreeVars (⟨abs⟩ u) (abs _ (⟨ fv ⟩ _)) = close 1 fvfreeVars ⟨tel⟩ (⟨ fv ⟩ _ ∷ xs) = fv ∪ close 1 (freeVars _ xs)freeVars u t = defaultAnn [] _∪_ u tannotateFVs : ∀ {u} → (t : ⟦ u ⟧) → Annotated (λ _ → FVs) tannotateFVs = annotate freeVars
-------------------------------------------------------------------------- The Agda standard library---- The reflected abstract syntax tree------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST whereimport Agda.Builtin.Reflection as Builtin-------------------------------------------------------------------------- Names, Metas, and Literals re-exported publiclyopen import Reflection.AST.Abstraction as Abstraction publicusing (Abs; abs)open import Reflection.AST.Argument as Argument publicusing (Arg; arg; Args; vArg; hArg; iArg; defaultModality)open import Reflection.AST.Definition as Definition publicusing (Definition)open import Reflection.AST.Meta as Meta publicusing (Meta)open import Reflection.AST.Name as Name publicusing (Name; Names)open import Reflection.AST.Literal as Literal publicusing (Literal)open import Reflection.AST.Pattern as Pattern publicusing (Pattern)open import Reflection.AST.Term as Term publicusing (Term; Type; Clause; Clauses; Sort)import Reflection.AST.Argument.Modality as Modalityimport Reflection.AST.Argument.Quantity as Quantityimport Reflection.AST.Argument.Relevance as Relevanceimport Reflection.AST.Argument.Visibility as Visibilityimport Reflection.AST.Argument.Information as Informationopen Definition.Definition publicopen Information.ArgInfo publicopen Literal.Literal publicopen Modality.Modality publicopen Quantity.Quantity publicopen Relevance.Relevance publicopen Term.Term publicopen Visibility.Visibility publicopen import Reflection.AST.Show public-------------------------------------------------------------------------- Fixityopen Builtin publicusing (non-assoc; related; unrelated; fixity)renaming( left-assoc to assocˡ; right-assoc to assocʳ; primQNameFixity to getFixity)
-------------------------------------------------------------------------- The Agda standard library---- A universe for the types involved in the reflected syntax.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Universe whereopen import Data.List.Base using (List)open import Data.String.Base using (String)open import Data.Product.Base using (_×_)open import Reflection.AST.Argument using (Arg)open import Reflection.AST.Abstraction using (Abs)open import Reflection.AST.Term using (Term; Pattern; Sort; Clause)data Univ : Set where⟨term⟩ : Univ⟨pat⟩ : Univ⟨sort⟩ : Univ⟨clause⟩ : Univ⟨list⟩ : Univ → Univ⟨arg⟩ : Univ → Univ⟨abs⟩ : Univ → Univ⟨named⟩ : Univ → Univpattern ⟨tel⟩ = ⟨list⟩ (⟨named⟩ (⟨arg⟩ ⟨term⟩))⟦_⟧ : Univ → Set⟦ ⟨term⟩ ⟧ = Term⟦ ⟨pat⟩ ⟧ = Pattern⟦ ⟨sort⟩ ⟧ = Sort⟦ ⟨clause⟩ ⟧ = Clause⟦ ⟨list⟩ k ⟧ = List ⟦ k ⟧⟦ ⟨arg⟩ k ⟧ = Arg ⟦ k ⟧⟦ ⟨abs⟩ k ⟧ = Abs ⟦ k ⟧⟦ ⟨named⟩ k ⟧ = String × ⟦ k ⟧
-------------------------------------------------------------------------- The Agda standard library---- de Bruijn-aware generic traversal of reflected terms.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Effect.Applicative using (RawApplicative)module Reflection.AST.Traversal{F : Set → Set} (AppF : RawApplicative F) whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.List.Base using (List; []; _∷_; _++_; reverse; length)open import Data.String.Base using (String)open import Data.Product.Base using (_×_; _,_)open import Function.Base using (_∘_)open import Reflection hiding (pure)open RawApplicative AppF-------------------------------------------------------------------------- Context representation-- Track both number of variables and actual context, to avoid having to-- compute the length of the context everytime it's needed.record Cxt : Set whereconstructor _,_patternfieldlen : ℕcontext : List (String × Arg Term)infixr 4 _,_private_∷cxt_ : String × Arg Term → Cxt → Cxte ∷cxt (n , Γ) = (suc n , e ∷ Γ)_++cxt_ : List (String × Arg Term) → Cxt → Cxtes ++cxt (n , Γ) = (length es + n , es ++ Γ)-------------------------------------------------------------------------- ActionsAction : Set → SetAction A = Cxt → A → F A-- A traversal gets to operate on variables, metas, and names.record Actions : Set wherefieldonVar : Action ℕonMeta : Action MetaonCon : Action NameonDef : Action Name-- Default action: do nothing.defaultActions : ActionsdefaultActions .Actions.onVar _ = puredefaultActions .Actions.onMeta _ = puredefaultActions .Actions.onCon _ = puredefaultActions .Actions.onDef _ = pure-------------------------------------------------------------------------- Traversal functionsmodule _ (actions : Actions) whereopen Actions actionstraverseTerm : Action TermtraverseSort : Action SorttraversePattern : Action PatterntraverseArgs : Action (List (Arg Term))traverseArg : Action (Arg Term)traversePats : Action (List (Arg Pattern))traverseAbs : Arg Term → Action (Abs Term)traverseClauses : Action ClausestraverseClause : Action ClausetraverseTel : Action (List (String × Arg Term))traverseTerm Γ (var x args) = var <$> onVar Γ x ⊛ traverseArgs Γ argstraverseTerm Γ (con c args) = con <$> onCon Γ c ⊛ traverseArgs Γ argstraverseTerm Γ (def f args) = def <$> onDef Γ f ⊛ traverseArgs Γ argstraverseTerm Γ (pat-lam cs args) = pat-lam <$> traverseClauses Γ cs ⊛ traverseArgs Γ argstraverseTerm Γ (pi a b) = pi <$> traverseArg Γ a ⊛ traverseAbs a Γ btraverseTerm Γ (agda-sort s) = agda-sort <$> traverseSort Γ straverseTerm Γ (meta x args) = meta <$> onMeta Γ x ⊛ traverseArgs Γ argstraverseTerm Γ t@(lit _) = pure ttraverseTerm Γ t@unknown = pure ttraverseTerm Γ (lam v t) = lam v <$> traverseAbs (arg (arg-info v m) unknown) Γ twherem = defaultModalitytraverseArg Γ (arg i t) = arg i <$> traverseTerm Γ ttraverseArgs Γ [] = pure []traverseArgs Γ (a ∷ as) = _∷_ <$> traverseArg Γ a ⊛ traverseArgs Γ astraverseAbs ty Γ (abs x t) = abs x <$> traverseTerm ((x , ty) ∷cxt Γ) ttraverseClauses Γ [] = pure []traverseClauses Γ (c ∷ cs) = _∷_ <$> traverseClause Γ c ⊛ traverseClauses Γ cstraverseClause Γ (Clause.clause tel ps t) =Clause.clause <$> traverseTel Γ tel⊛ traversePats Γ′ ps⊛ traverseTerm Γ′ twhere Γ′ = reverse tel ++cxt ΓtraverseClause Γ (Clause.absurd-clause tel ps) =Clause.absurd-clause <$> traverseTel Γ tel⊛ traversePats Γ′ pswhere Γ′ = reverse tel ++cxt ΓtraverseTel Γ [] = pure []traverseTel Γ ((x , ty) ∷ tel) =_∷_ ∘ (x ,_) <$> traverseArg Γ ty ⊛ traverseTel ((x , ty) ∷cxt Γ) teltraverseSort Γ (Sort.set t) = Sort.set <$> traverseTerm Γ ttraverseSort Γ t@(Sort.lit _) = pure ttraverseSort Γ (Sort.prop t) = Sort.prop <$> traverseTerm Γ ttraverseSort Γ t@(Sort.propLit _) = pure ttraverseSort Γ t@(Sort.inf _) = pure ttraverseSort Γ t@Sort.unknown = pure ttraversePattern Γ (Pattern.con c ps) = Pattern.con <$> onCon Γ c ⊛ traversePats Γ pstraversePattern Γ (Pattern.dot t) = Pattern.dot <$> traverseTerm Γ ttraversePattern Γ (Pattern.var x) = Pattern.var <$> onVar Γ xtraversePattern Γ p@(Pattern.lit _) = pure ptraversePattern Γ p@(Pattern.proj _) = pure ptraversePattern Γ (Pattern.absurd x) = Pattern.absurd <$> onVar Γ xtraversePats Γ [] = pure []traversePats Γ (arg i p ∷ ps) = _∷_ ∘ arg i <$> traversePattern Γ p ⊛ traversePats Γ ps
-------------------------------------------------------------------------- The Agda standard library---- Terms used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Term whereopen import Data.List.Base as List hiding (_++_)open import Data.List.Properties using (∷-dec)open import Data.Nat.Base using (ℕ; zero; suc)import Data.Nat.Properties as ℕopen import Data.Product.Base using (_×_; _,_; <_,_>; uncurry; map₁)open import Data.Product.Properties using (,-injective)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.String.Base using (String)open import Data.String.Properties as String hiding (_≟_)open import Relation.Nullary.Decidable using (map′; _×-dec_; yes; no)open import Relation.Binary.Definitions using (Decidable; DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂)open import Reflection.AST.Abstractionopen import Reflection.AST.Argumentopen import Reflection.AST.Argument.Information using (visibility)open import Reflection.AST.Argument.Visibility as Visibility hiding (_≟_)import Reflection.AST.Literal as Literalimport Reflection.AST.Meta as Metaopen import Reflection.AST.Name as Name using (Name)-------------------------------------------------------------------------- Re-exporting the builtin type and constructorsopen import Agda.Builtin.Reflection as Builtin publicusing (Sort; Type; Term; Clause; Pattern)open Term publicrenaming (agda-sort to sort)open Sort publicopen Clause publicopen Pattern public-------------------------------------------------------------------------- Handy synonymsClauses : SetClauses = List ClauseTelescope : SetTelescope = List (String × Arg Type)-- Pattern synonyms for more compact presentationpattern vLam s t = lam visible (abs s t)pattern hLam s t = lam hidden (abs s t)pattern iLam s t = lam instance′ (abs s t)pattern Π[_∶_]_ s a ty = pi a (abs s ty)pattern vΠ[_∶_]_ s a ty = Π[ s ∶ (vArg a) ] typattern hΠ[_∶_]_ s a ty = Π[ s ∶ (hArg a) ] typattern iΠ[_∶_]_ s a ty = Π[ s ∶ (iArg a) ] ty-------------------------------------------------------------------------- Utility functionsgetName : Term → Maybe NamegetName (con c args) = just cgetName (def f args) = just fgetName _ = nothing-- "n ⋯⟨∷⟩ xs" prepends "n" visible unknown arguments to the list of-- arguments. Useful when constructing the list of arguments for a-- function with initial inferrable arguments.infixr 5 _⋯⟨∷⟩__⋯⟨∷⟩_ : ℕ → Args Term → Args Termzero ⋯⟨∷⟩ xs = xssuc i ⋯⟨∷⟩ xs = unknown ⟨∷⟩ (i ⋯⟨∷⟩ xs){-# INLINE _⋯⟨∷⟩_ #-}-- "n ⋯⟅∷⟆ xs" prepends "n" hidden unknown arguments to the list of-- arguments. Useful when constructing the list of arguments for a-- function with initial implicit arguments.infixr 5 _⋯⟅∷⟆__⋯⟅∷⟆_ : ℕ → Args Term → Args Termzero ⋯⟅∷⟆ xs = xssuc i ⋯⟅∷⟆ xs = unknown ⟅∷⟆ (i ⋯⟅∷⟆ xs){-# INLINE _⋯⟅∷⟆_ #-}-- Strips off any pi bindings returning the list of variables removed-- and the eventual body of the expression, e.g.---- stripPis `∀ x {y} → f x y` = (["x", "y"], f x y)stripPis : Term → List (String × Arg Type) × TermstripPis (Π[ s ∶ t ] x) = map₁ ((s , t) ∷_) (stripPis x)stripPis x = [] , xprependLams : List (String × Visibility) → Term → TermprependLams xs t = foldr (λ {(s , v) t → lam v (abs s t)}) t (reverse xs)prependHLams : List String → Term → TermprependHLams vs = prependLams (List.map (_, hidden) vs)prependVLams : List String → Term → TermprependVLams vs = prependLams (List.map (_, visible) vs)-------------------------------------------------------------------------- Decidable equalityclause-injective₁ : ∀ {tel tel′ ps ps′ b b′} → clause tel ps b ≡ clause tel′ ps′ b′ → tel ≡ tel′clause-injective₁ refl = reflclause-injective₂ : ∀ {tel tel′ ps ps′ b b′} → clause tel ps b ≡ clause tel′ ps′ b′ → ps ≡ ps′clause-injective₂ refl = reflclause-injective₃ : ∀ {tel tel′ ps ps′ b b′} → clause tel ps b ≡ clause tel′ ps′ b′ → b ≡ b′clause-injective₃ refl = reflclause-injective : ∀ {tel tel′ ps ps′ b b′} → clause tel ps b ≡ clause tel′ ps′ b′ → tel ≡ tel′ × ps ≡ ps′ × b ≡ b′clause-injective = < clause-injective₁ , < clause-injective₂ , clause-injective₃ > >absurd-clause-injective₁ : ∀ {tel tel′ ps ps′} → absurd-clause tel ps ≡ absurd-clause tel′ ps′ → tel ≡ tel′absurd-clause-injective₁ refl = reflabsurd-clause-injective₂ : ∀ {tel tel′ ps ps′} → absurd-clause tel ps ≡ absurd-clause tel′ ps′ → ps ≡ ps′absurd-clause-injective₂ refl = reflabsurd-clause-injective : ∀ {tel tel′ ps ps′} → absurd-clause tel ps ≡ absurd-clause tel′ ps′ → tel ≡ tel′ × ps ≡ ps′absurd-clause-injective = < absurd-clause-injective₁ , absurd-clause-injective₂ >infix 4 _≟-AbsTerm_ _≟-AbsType_ _≟-ArgTerm_ _≟-ArgType_ _≟-Args__≟-Clause_ _≟-Clauses_ _≟__≟-Sort_ _≟-Pattern_ _≟-Patterns_ _≟-Telescope__≟-AbsTerm_ : DecidableEquality (Abs Term)_≟-AbsType_ : DecidableEquality (Abs Type)_≟-ArgTerm_ : DecidableEquality (Arg Term)_≟-ArgType_ : DecidableEquality (Arg Type)_≟-Args_ : DecidableEquality (Args Term)_≟-Clause_ : DecidableEquality Clause_≟-Clauses_ : DecidableEquality Clauses_≟_ : DecidableEquality Term_≟-Sort_ : DecidableEquality Sort_≟-Patterns_ : DecidableEquality (Args Pattern)_≟-Pattern_ : DecidableEquality Pattern-- Decidable equality 'transformers'-- We need to inline these because the terms are not sized so-- termination would not obvious if we were to use higher-order-- functions such as Data.List.Properties' ≡-decabs s a ≟-AbsTerm abs s′ a′ = unAbs-dec (a ≟ a′)abs s a ≟-AbsType abs s′ a′ = unAbs-dec (a ≟ a′)arg i a ≟-ArgTerm arg i′ a′ = unArg-dec (a ≟ a′)arg i a ≟-ArgType arg i′ a′ = unArg-dec (a ≟ a′)[] ≟-Args [] = yes refl(x ∷ xs) ≟-Args (y ∷ ys) = ∷-dec (x ≟-ArgTerm y) (xs ≟-Args ys)[] ≟-Args (_ ∷ _) = no λ()(_ ∷ _) ≟-Args [] = no λ()[] ≟-Clauses [] = yes refl(x ∷ xs) ≟-Clauses (y ∷ ys) = ∷-dec (x ≟-Clause y) (xs ≟-Clauses ys)[] ≟-Clauses (_ ∷ _) = no λ()(_ ∷ _) ≟-Clauses [] = no λ()_≟-Telescope_ : DecidableEquality Telescope[] ≟-Telescope [] = yes refl((x , t) ∷ tel) ≟-Telescope ((x′ , t′) ∷ tel′) = ∷-dec(map′ (uncurry (cong₂ _,_)) ,-injective ((x String.≟ x′) ×-dec (t ≟-ArgTerm t′)))(tel ≟-Telescope tel′)[] ≟-Telescope (_ ∷ _) = no λ ()(_ ∷ _) ≟-Telescope [] = no λ ()clause tel ps b ≟-Clause clause tel′ ps′ b′ =map′ (λ (tel≡tel′ , ps≡ps′ , b≡b′) → cong₂ (uncurry clause) (cong₂ _,_ tel≡tel′ ps≡ps′) b≡b′)clause-injective(tel ≟-Telescope tel′ ×-dec ps ≟-Patterns ps′ ×-dec b ≟ b′)absurd-clause tel ps ≟-Clause absurd-clause tel′ ps′ =map′ (uncurry (cong₂ absurd-clause))absurd-clause-injective(tel ≟-Telescope tel′ ×-dec ps ≟-Patterns ps′)clause _ _ _ ≟-Clause absurd-clause _ _ = no λ()absurd-clause _ _ ≟-Clause clause _ _ _ = no λ()var-injective₁ : ∀ {x x′ args args′} → Term.var x args ≡ var x′ args′ → x ≡ x′var-injective₁ refl = reflvar-injective₂ : ∀ {x x′ args args′} → Term.var x args ≡ var x′ args′ → args ≡ args′var-injective₂ refl = reflvar-injective : ∀ {x x′ args args′} → var x args ≡ var x′ args′ → x ≡ x′ × args ≡ args′var-injective = < var-injective₁ , var-injective₂ >con-injective₁ : ∀ {c c′ args args′} → Term.con c args ≡ con c′ args′ → c ≡ c′con-injective₁ refl = reflcon-injective₂ : ∀ {c c′ args args′} → Term.con c args ≡ con c′ args′ → args ≡ args′con-injective₂ refl = reflcon-injective : ∀ {c c′ args args′} → con c args ≡ con c′ args′ → c ≡ c′ × args ≡ args′con-injective = < con-injective₁ , con-injective₂ >def-injective₁ : ∀ {f f′ args args′} → def f args ≡ def f′ args′ → f ≡ f′def-injective₁ refl = refldef-injective₂ : ∀ {f f′ args args′} → def f args ≡ def f′ args′ → args ≡ args′def-injective₂ refl = refldef-injective : ∀ {f f′ args args′} → def f args ≡ def f′ args′ → f ≡ f′ × args ≡ args′def-injective = < def-injective₁ , def-injective₂ >meta-injective₁ : ∀ {x x′ args args′} → meta x args ≡ meta x′ args′ → x ≡ x′meta-injective₁ refl = reflmeta-injective₂ : ∀ {x x′ args args′} → meta x args ≡ meta x′ args′ → args ≡ args′meta-injective₂ refl = reflmeta-injective : ∀ {x x′ args args′} → meta x args ≡ meta x′ args′ → x ≡ x′ × args ≡ args′meta-injective = < meta-injective₁ , meta-injective₂ >lam-injective₁ : ∀ {v v′ t t′} → lam v t ≡ lam v′ t′ → v ≡ v′lam-injective₁ refl = refllam-injective₂ : ∀ {v v′ t t′} → lam v t ≡ lam v′ t′ → t ≡ t′lam-injective₂ refl = refllam-injective : ∀ {v v′ t t′} → lam v t ≡ lam v′ t′ → v ≡ v′ × t ≡ t′lam-injective = < lam-injective₁ , lam-injective₂ >pat-lam-injective₁ : ∀ {cs cs′ args args′} → pat-lam cs args ≡ pat-lam cs′ args′ → cs ≡ cs′pat-lam-injective₁ refl = reflpat-lam-injective₂ : ∀ {cs cs′ args args′} → pat-lam cs args ≡ pat-lam cs′ args′ → args ≡ args′pat-lam-injective₂ refl = reflpat-lam-injective : ∀ {cs cs′ args args′} → pat-lam cs args ≡ pat-lam cs′ args′ → cs ≡ cs′ × args ≡ args′pat-lam-injective = < pat-lam-injective₁ , pat-lam-injective₂ >pi-injective₁ : ∀ {t₁ t₁′ t₂ t₂′} → pi t₁ t₂ ≡ pi t₁′ t₂′ → t₁ ≡ t₁′pi-injective₁ refl = reflpi-injective₂ : ∀ {t₁ t₁′ t₂ t₂′} → pi t₁ t₂ ≡ pi t₁′ t₂′ → t₂ ≡ t₂′pi-injective₂ refl = reflpi-injective : ∀ {t₁ t₁′ t₂ t₂′} → pi t₁ t₂ ≡ pi t₁′ t₂′ → t₁ ≡ t₁′ × t₂ ≡ t₂′pi-injective = < pi-injective₁ , pi-injective₂ >sort-injective : ∀ {x y} → sort x ≡ sort y → x ≡ ysort-injective refl = refllit-injective : ∀ {x y} → lit x ≡ lit y → x ≡ ylit-injective refl = reflset-injective : ∀ {x y} → set x ≡ set y → x ≡ yset-injective refl = reflslit-injective : ∀ {x y} → Sort.lit x ≡ lit y → x ≡ yslit-injective refl = reflprop-injective : ∀ {x y} → prop x ≡ prop y → x ≡ yprop-injective refl = reflpropLit-injective : ∀ {x y} → propLit x ≡ propLit y → x ≡ ypropLit-injective refl = reflinf-injective : ∀ {x y} → inf x ≡ inf y → x ≡ yinf-injective refl = reflvar x args ≟ var x′ args′ =map′ (uncurry (cong₂ var)) var-injective (x ℕ.≟ x′ ×-dec args ≟-Args args′)con c args ≟ con c′ args′ =map′ (uncurry (cong₂ con)) con-injective (c Name.≟ c′ ×-dec args ≟-Args args′)def f args ≟ def f′ args′ =map′ (uncurry (cong₂ def)) def-injective (f Name.≟ f′ ×-dec args ≟-Args args′)meta x args ≟ meta x′ args′ =map′ (uncurry (cong₂ meta)) meta-injective (x Meta.≟ x′ ×-dec args ≟-Args args′)lam v t ≟ lam v′ t′ =map′ (uncurry (cong₂ lam)) lam-injective (v Visibility.≟ v′ ×-dec t ≟-AbsTerm t′)pat-lam cs args ≟ pat-lam cs′ args′ =map′ (uncurry (cong₂ pat-lam)) pat-lam-injective (cs ≟-Clauses cs′ ×-dec args ≟-Args args′)pi t₁ t₂ ≟ pi t₁′ t₂′ =map′ (uncurry (cong₂ pi)) pi-injective (t₁ ≟-ArgType t₁′ ×-dec t₂ ≟-AbsType t₂′)sort s ≟ sort s′ = map′ (cong sort) sort-injective (s ≟-Sort s′)lit l ≟ lit l′ = map′ (cong lit) lit-injective (l Literal.≟ l′)unknown ≟ unknown = yes reflvar x args ≟ con c args′ = no λ()var x args ≟ def f args′ = no λ()var x args ≟ lam v t = no λ()var x args ≟ pi t₁ t₂ = no λ()var x args ≟ sort _ = no λ()var x args ≟ lit _ = no λ()var x args ≟ meta _ _ = no λ()var x args ≟ unknown = no λ()con c args ≟ var x args′ = no λ()con c args ≟ def f args′ = no λ()con c args ≟ lam v t = no λ()con c args ≟ pi t₁ t₂ = no λ()con c args ≟ sort _ = no λ()con c args ≟ lit _ = no λ()con c args ≟ meta _ _ = no λ()con c args ≟ unknown = no λ()def f args ≟ var x args′ = no λ()def f args ≟ con c args′ = no λ()def f args ≟ lam v t = no λ()def f args ≟ pi t₁ t₂ = no λ()def f args ≟ sort _ = no λ()def f args ≟ lit _ = no λ()def f args ≟ meta _ _ = no λ()def f args ≟ unknown = no λ()lam v t ≟ var x args = no λ()lam v t ≟ con c args = no λ()lam v t ≟ def f args = no λ()lam v t ≟ pi t₁ t₂ = no λ()lam v t ≟ sort _ = no λ()lam v t ≟ lit _ = no λ()lam v t ≟ meta _ _ = no λ()lam v t ≟ unknown = no λ()pi t₁ t₂ ≟ var x args = no λ()pi t₁ t₂ ≟ con c args = no λ()pi t₁ t₂ ≟ def f args = no λ()pi t₁ t₂ ≟ lam v t = no λ()pi t₁ t₂ ≟ sort _ = no λ()pi t₁ t₂ ≟ lit _ = no λ()pi t₁ t₂ ≟ meta _ _ = no λ()pi t₁ t₂ ≟ unknown = no λ()sort _ ≟ var x args = no λ()sort _ ≟ con c args = no λ()sort _ ≟ def f args = no λ()sort _ ≟ lam v t = no λ()sort _ ≟ pi t₁ t₂ = no λ()sort _ ≟ lit _ = no λ()sort _ ≟ meta _ _ = no λ()sort _ ≟ unknown = no λ()lit _ ≟ var x args = no λ()lit _ ≟ con c args = no λ()lit _ ≟ def f args = no λ()lit _ ≟ lam v t = no λ()lit _ ≟ pi t₁ t₂ = no λ()lit _ ≟ sort _ = no λ()lit _ ≟ meta _ _ = no λ()lit _ ≟ unknown = no λ()meta _ _ ≟ var x args = no λ()meta _ _ ≟ con c args = no λ()meta _ _ ≟ def f args = no λ()meta _ _ ≟ lam v t = no λ()meta _ _ ≟ pi t₁ t₂ = no λ()meta _ _ ≟ sort _ = no λ()meta _ _ ≟ lit _ = no λ()meta _ _ ≟ unknown = no λ()unknown ≟ var x args = no λ()unknown ≟ con c args = no λ()unknown ≟ def f args = no λ()unknown ≟ lam v t = no λ()unknown ≟ pi t₁ t₂ = no λ()unknown ≟ sort _ = no λ()unknown ≟ lit _ = no λ()unknown ≟ meta _ _ = no λ()pat-lam _ _ ≟ var x args = no λ()pat-lam _ _ ≟ con c args = no λ()pat-lam _ _ ≟ def f args = no λ()pat-lam _ _ ≟ lam v t = no λ()pat-lam _ _ ≟ pi t₁ t₂ = no λ()pat-lam _ _ ≟ sort _ = no λ()pat-lam _ _ ≟ lit _ = no λ()pat-lam _ _ ≟ meta _ _ = no λ()pat-lam _ _ ≟ unknown = no λ()var x args ≟ pat-lam _ _ = no λ()con c args ≟ pat-lam _ _ = no λ()def f args ≟ pat-lam _ _ = no λ()lam v t ≟ pat-lam _ _ = no λ()pi t₁ t₂ ≟ pat-lam _ _ = no λ()sort _ ≟ pat-lam _ _ = no λ()lit _ ≟ pat-lam _ _ = no λ()meta _ _ ≟ pat-lam _ _ = no λ()unknown ≟ pat-lam _ _ = no λ()set t ≟-Sort set t′ = map′ (cong set) set-injective (t ≟ t′)lit n ≟-Sort lit n′ = map′ (cong lit) slit-injective (n ℕ.≟ n′)prop t ≟-Sort prop t′ = map′ (cong prop) prop-injective (t ≟ t′)propLit n ≟-Sort propLit n′ = map′ (cong propLit) propLit-injective (n ℕ.≟ n′)inf n ≟-Sort inf n′ = map′ (cong inf) inf-injective (n ℕ.≟ n′)unknown ≟-Sort unknown = yes reflset _ ≟-Sort lit _ = no λ()set _ ≟-Sort prop _ = no λ()set _ ≟-Sort propLit _ = no λ()set _ ≟-Sort inf _ = no λ()set _ ≟-Sort unknown = no λ()lit _ ≟-Sort set _ = no λ()lit _ ≟-Sort prop _ = no λ()lit _ ≟-Sort propLit _ = no λ()lit _ ≟-Sort inf _ = no λ()lit _ ≟-Sort unknown = no λ()prop _ ≟-Sort set _ = no λ()prop _ ≟-Sort lit _ = no λ()prop _ ≟-Sort propLit _ = no λ()prop _ ≟-Sort inf _ = no λ()prop _ ≟-Sort unknown = no λ()propLit _ ≟-Sort set _ = no λ()propLit _ ≟-Sort lit _ = no λ()propLit _ ≟-Sort prop _ = no λ()propLit _ ≟-Sort inf _ = no λ()propLit _ ≟-Sort unknown = no λ()inf _ ≟-Sort set _ = no λ()inf _ ≟-Sort lit _ = no λ()inf _ ≟-Sort prop _ = no λ()inf _ ≟-Sort propLit _ = no λ()inf _ ≟-Sort unknown = no λ()unknown ≟-Sort set _ = no λ()unknown ≟-Sort lit _ = no λ()unknown ≟-Sort prop _ = no λ()unknown ≟-Sort propLit _ = no λ()unknown ≟-Sort inf _ = no λ()pat-con-injective₁ : ∀ {c c′ args args′} → Pattern.con c args ≡ con c′ args′ → c ≡ c′pat-con-injective₁ refl = reflpat-con-injective₂ : ∀ {c c′ args args′} → Pattern.con c args ≡ con c′ args′ → args ≡ args′pat-con-injective₂ refl = reflpat-con-injective : ∀ {c c′ args args′} → Pattern.con c args ≡ con c′ args′ → c ≡ c′ × args ≡ args′pat-con-injective = < pat-con-injective₁ , pat-con-injective₂ >pat-var-injective : ∀ {x y} → var x ≡ var y → x ≡ ypat-var-injective refl = reflpat-lit-injective : ∀ {x y} → Pattern.lit x ≡ lit y → x ≡ ypat-lit-injective refl = reflproj-injective : ∀ {x y} → proj x ≡ proj y → x ≡ yproj-injective refl = refldot-injective : ∀ {x y} → dot x ≡ dot y → x ≡ ydot-injective refl = reflabsurd-injective : ∀ {x y} → absurd x ≡ absurd y → x ≡ yabsurd-injective refl = reflcon c ps ≟-Pattern con c′ ps′ = map′ (uncurry (cong₂ con)) pat-con-injective (c Name.≟ c′ ×-dec ps ≟-Patterns ps′)var x ≟-Pattern var x′ = map′ (cong var) pat-var-injective (x ℕ.≟ x′)lit l ≟-Pattern lit l′ = map′ (cong lit) pat-lit-injective (l Literal.≟ l′)proj a ≟-Pattern proj a′ = map′ (cong proj) proj-injective (a Name.≟ a′)dot t ≟-Pattern dot t′ = map′ (cong dot) dot-injective (t ≟ t′)absurd x ≟-Pattern absurd x′ = map′ (cong absurd) absurd-injective (x ℕ.≟ x′)con x x₁ ≟-Pattern dot x₂ = no (λ ())con x x₁ ≟-Pattern var x₂ = no (λ ())con x x₁ ≟-Pattern lit x₂ = no (λ ())con x x₁ ≟-Pattern proj x₂ = no (λ ())con x x₁ ≟-Pattern absurd x₂ = no (λ ())dot x ≟-Pattern con x₁ x₂ = no (λ ())dot x ≟-Pattern var x₁ = no (λ ())dot x ≟-Pattern lit x₁ = no (λ ())dot x ≟-Pattern proj x₁ = no (λ ())dot x ≟-Pattern absurd x₁ = no (λ ())var s ≟-Pattern con x x₁ = no (λ ())var s ≟-Pattern dot x = no (λ ())var s ≟-Pattern lit x = no (λ ())var s ≟-Pattern proj x = no (λ ())var s ≟-Pattern absurd x = no (λ ())lit x ≟-Pattern con x₁ x₂ = no (λ ())lit x ≟-Pattern dot x₁ = no (λ ())lit x ≟-Pattern var _ = no (λ ())lit x ≟-Pattern proj x₁ = no (λ ())lit x ≟-Pattern absurd x₁ = no (λ ())proj x ≟-Pattern con x₁ x₂ = no (λ ())proj x ≟-Pattern dot x₁ = no (λ ())proj x ≟-Pattern var _ = no (λ ())proj x ≟-Pattern lit x₁ = no (λ ())proj x ≟-Pattern absurd x₁ = no (λ ())absurd x ≟-Pattern con x₁ x₂ = no (λ ())absurd x ≟-Pattern dot x₁ = no (λ ())absurd x ≟-Pattern var _ = no (λ ())absurd x ≟-Pattern lit x₁ = no (λ ())absurd x ≟-Pattern proj x₁ = no (λ ())[] ≟-Patterns [] = yes refl(arg i p ∷ xs) ≟-Patterns (arg j q ∷ ys) = ∷-dec (unArg-dec (p ≟-Pattern q)) (xs ≟-Patterns ys)[] ≟-Patterns (_ ∷ _) = no λ()(_ ∷ _) ≟-Patterns [] = no λ()
-------------------------------------------------------------------------- The Agda standard library---- Converting reflection machinery to strings-------------------------------------------------------------------------- Note that Reflection.termErr can also be used directly in tactic-- error messages.{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Show whereimport Data.Char.Base as Charimport Data.Float.Base as Floatopen import Data.List.Base hiding (_++_; intersperse)import Data.Nat.Show as ℕopen import Data.String.Base as String using (String; _++_; intersperse; braces; parens; _<+>_)open import Data.String as String using (parensIfSpace)open import Data.Product.Base using (_×_; _,_)import Data.Word64.Base as Word64open import Function.Base using (id; _∘′_; case_of_)open import Relation.Nullary.Decidable.Core using (yes; no)open import Reflection.AST.Abstraction hiding (map)open import Reflection.AST.Argument hiding (map)open import Reflection.AST.Argument.Relevanceopen import Reflection.AST.Argument.Visibilityopen import Reflection.AST.Argument.Modalityopen import Reflection.AST.Argument.Informationopen import Reflection.AST.Definitionopen import Reflection.AST.Literalopen import Reflection.AST.Patternopen import Reflection.AST.Term-------------------------------------------------------------------------- Re-export primitive show functionsopen import Agda.Builtin.Reflection publicusing () renaming( primShowMeta to showMeta; primShowQName to showName)-------------------------------------------------------------------------- Non-primitive show functionsshowRelevance : Relevance → StringshowRelevance relevant = "relevant"showRelevance irrelevant = "irrelevant"showRel : Relevance → StringshowRel relevant = ""showRel irrelevant = "."showVisibility : Visibility → StringshowVisibility visible = "visible"showVisibility hidden = "hidden"showVisibility instance′ = "instance"showLiteral : Literal → StringshowLiteral (nat x) = ℕ.show xshowLiteral (word64 x) = ℕ.show (Word64.toℕ x)showLiteral (float x) = Float.show xshowLiteral (char x) = Char.show xshowLiteral (string x) = String.show xshowLiteral (name x) = showName xshowLiteral (meta x) = showMeta xprivate-- add appropriate parens depending on the given visibilityvisibilityParen : Visibility → String → StringvisibilityParen visible s = parensIfSpace svisibilityParen hidden s = braces svisibilityParen instance′ s = braces (braces s)mutualshowTerms : List (Arg Term) → StringshowTerms [] = ""showTerms (arg i t ∷ ts) = visibilityParen (visibility i) (showTerm t) <+> showTerms tsshowTerm : Term → StringshowTerm (var x args) = "var" <+> ℕ.show x <+> showTerms argsshowTerm (con c args) = showName c <+> showTerms argsshowTerm (def f args) = showName f <+> showTerms argsshowTerm (lam v (abs s x)) = "λ" <+> visibilityParen v s <+> "→" <+> showTerm xshowTerm (pat-lam cs args) ="λ {" <+> showClauses cs <+> "}" <+> showTerms argsshowTerm (Π[ x ∶ arg i a ] b) ="Π (" ++ visibilityParen (visibility i) x <+> ":" <+>parensIfSpace (showTerm a) ++ ")" <+> parensIfSpace (showTerm b)showTerm (sort s) = showSort sshowTerm (lit l) = showLiteral lshowTerm (meta x args) = showMeta x <+> showTerms argsshowTerm unknown = "unknown"showSort : Sort → StringshowSort (set t) = "Set" <+> parensIfSpace (showTerm t)showSort (lit n) = "Set" ++ ℕ.show n -- no space to disambiguate from set tshowSort (prop t) = "Prop" <+> parensIfSpace (showTerm t)showSort (propLit n) = "Prop" ++ ℕ.show n -- no space to disambiguate from prop tshowSort (inf n) = "Setω" ++ ℕ.show nshowSort unknown = "unknown"showPatterns : List (Arg Pattern) → StringshowPatterns [] = ""showPatterns (a ∷ ps) = showArg a <+> showPatterns pswhere-- Quantities are ignored.showArg : Arg Pattern → StringshowArg (arg (arg-info h (modality r _)) p) =braces? (showRel r ++ showPattern p)wherebraces? = case h of λ wherevisible → idhidden → bracesinstance′ → braces ∘′ bracesshowPattern : Pattern → StringshowPattern (con c []) = showName cshowPattern (con c ps) = parens (showName c <+> showPatterns ps)showPattern (dot t) = "." ++ parens (showTerm t)showPattern (var x) = "pat-var" <+> ℕ.show xshowPattern (lit l) = showLiteral lshowPattern (proj f) = showName fshowPattern (absurd _) = "()"showClause : Clause → StringshowClause (clause tel ps t) = "[" <+> showTel tel <+> "]" <+> showPatterns ps <+> "→" <+> showTerm tshowClause (absurd-clause tel ps) = "[" <+> showTel tel <+> "]" <+> showPatterns psshowClauses : List Clause → StringshowClauses [] = ""showClauses (c ∷ cs) = showClause c <+> ";" <+> showClauses csshowTel : List (String × Arg Type) → StringshowTel [] = ""showTel ((x , arg i t) ∷ tel) = visibilityParen (visibility i) (x <+> ":" <+> showTerm t) ++ showTel telshowDefinition : Definition → StringshowDefinition (function cs) = "function" <+> braces (showClauses cs)showDefinition (data-type pars cs) ="datatype" <+> ℕ.show pars <+> braces (intersperse ", " (map showName cs))showDefinition (record′ c fs) ="record" <+> showName c <+> braces (intersperse ", " (map (showName ∘′ unArg) fs))showDefinition (constructor′ d) = "constructor" <+> showName dshowDefinition axiom = "axiom"showDefinition primitive′ = "primitive"
-------------------------------------------------------------------------- The Agda standard library---- Patterns used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Pattern where-------------------------------------------------------------------------- Re-exporting the builtin type and constructorsopen import Agda.Builtin.Reflection public using (Pattern)open Pattern public-------------------------------------------------------------------------- Re-exporting definitions that used to be hereopen import Reflection.AST.Term publicusing ( proj-injective )renaming ( pat-con-injective₁ to con-injective₁; pat-con-injective₂ to con-injective₂; pat-con-injective to con-injective; pat-var-injective to var-injective; pat-lit-injective to lit-injective; _≟-Patterns_ to _≟s_; _≟-Pattern_ to _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Names used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Name whereopen import Data.List.Base using (List)import Data.Product.Properties as Prodₚ using (≡-dec)import Data.Word64.Properties as Wₚ using (_≟_)open import Function.Base using (_on_)open import Relation.Nullary.Decidable.Core using (map′)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable; DecidableEquality)open import Relation.Binary.Construct.On using (decidable)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)-------------------------------------------------------------------------- Re-export built-insopen import Agda.Builtin.Reflection publicusing (Name) renaming (primQNameToWord64s to toWords; primQNameEquality to _≡ᵇ_)open import Agda.Builtin.Reflection.Properties publicrenaming (primQNameToWord64sInjective to toWords-injective)-------------------------------------------------------------------------- More definitions------------------------------------------------------------------------Names : SetNames = List Name-------------------------------------------------------------------------- Decidable equality for names------------------------------------------------------------------------infix 4 _≈?_ _≟_ _≈__≈_ : Rel Name __≈_ = _≡_ on toWords_≈?_ : Decidable _≈__≈?_ = decidable toWords _≡_ (Prodₚ.≡-dec Wₚ._≟_ Wₚ._≟_)_≟_ : DecidableEquality Namem ≟ n = map′ (toWords-injective _ _) (cong toWords) (m ≈? n)
-------------------------------------------------------------------------- The Agda standard library---- Metavariables used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Meta whereimport Data.Nat.Properties as ℕopen import Function.Base using (_on_)open import Relation.Nullary.Decidable.Core using (map′)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable; DecidableEquality)import Relation.Binary.Construct.On as Onopen import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)open import Agda.Builtin.Reflection publicusing (Meta) renaming (primMetaToNat to toℕ; primMetaEquality to _≡ᵇ_)open import Agda.Builtin.Reflection.Properties publicrenaming (primMetaToNatInjective to toℕ-injective)-- Equality of metas is decidable.infix 4 _≈?_ _≟_ _≈__≈_ : Rel Meta __≈_ = _≡_ on toℕ_≈?_ : Decidable _≈__≈?_ = On.decidable toℕ _≡_ ℕ._≟__≟_ : DecidableEquality Metam ≟ n = map′ (toℕ-injective _ _) (cong toℕ) (m ≈? n)
-------------------------------------------------------------------------- The Agda standard library---- Literals used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Literal whereopen import Data.Bool.Base using (Bool; true; false)import Data.Char.Properties as Charimport Data.Float.Properties as Floatimport Data.Nat.Properties as ℕimport Data.String.Properties as Stringimport Data.Word64.Properties as Word64import Reflection.AST.Meta as Metaimport Reflection.AST.Name as Nameopen import Relation.Nullary.Decidable.Core using (yes; no; map′; isYes)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)-------------------------------------------------------------------------- Re-exporting the builtin type and constructorsopen import Agda.Builtin.Reflection publicusing ( Literal )open Literal public-------------------------------------------------------------------------- Decidable equalitymeta-injective : ∀ {x y} → meta x ≡ meta y → x ≡ ymeta-injective refl = reflnat-injective : ∀ {x y} → nat x ≡ nat y → x ≡ ynat-injective refl = reflword64-injective : ∀ {x y} → word64 x ≡ word64 y → x ≡ yword64-injective refl = reflfloat-injective : ∀ {x y} → float x ≡ float y → x ≡ yfloat-injective refl = reflchar-injective : ∀ {x y} → char x ≡ char y → x ≡ ychar-injective refl = reflstring-injective : ∀ {x y} → string x ≡ string y → x ≡ ystring-injective refl = reflname-injective : ∀ {x y} → name x ≡ name y → x ≡ yname-injective refl = reflinfix 4 _≟__≟_ : DecidableEquality Literalnat x ≟ nat x₁ = map′ (cong nat) nat-injective (x ℕ.≟ x₁)nat x ≟ word64 x₁ = no (λ ())nat x ≟ float x₁ = no (λ ())nat x ≟ char x₁ = no (λ ())nat x ≟ string x₁ = no (λ ())nat x ≟ name x₁ = no (λ ())nat x ≟ meta x₁ = no (λ ())word64 x ≟ word64 x₁ = map′ (cong word64) word64-injective (x Word64.≟ x₁)word64 x ≟ nat x₁ = no (λ ())word64 x ≟ float x₁ = no (λ ())word64 x ≟ char x₁ = no (λ ())word64 x ≟ string x₁ = no (λ ())word64 x ≟ name x₁ = no (λ ())word64 x ≟ meta x₁ = no (λ ())float x ≟ nat x₁ = no (λ ())float x ≟ word64 x₁ = no (λ ())float x ≟ float x₁ = map′ (cong float) float-injective (x Float.≟ x₁)float x ≟ char x₁ = no (λ ())float x ≟ string x₁ = no (λ ())float x ≟ name x₁ = no (λ ())float x ≟ meta x₁ = no (λ ())char x ≟ nat x₁ = no (λ ())char x ≟ word64 x₁ = no (λ ())char x ≟ float x₁ = no (λ ())char x ≟ char x₁ = map′ (cong char) char-injective (x Char.≟ x₁)char x ≟ string x₁ = no (λ ())char x ≟ name x₁ = no (λ ())char x ≟ meta x₁ = no (λ ())string x ≟ nat x₁ = no (λ ())string x ≟ word64 x₁ = no (λ ())string x ≟ float x₁ = no (λ ())string x ≟ char x₁ = no (λ ())string x ≟ string x₁ = map′ (cong string) string-injective (x String.≟ x₁)string x ≟ name x₁ = no (λ ())string x ≟ meta x₁ = no (λ ())name x ≟ nat x₁ = no (λ ())name x ≟ word64 x₁ = no (λ ())name x ≟ float x₁ = no (λ ())name x ≟ char x₁ = no (λ ())name x ≟ string x₁ = no (λ ())name x ≟ name x₁ = map′ (cong name) name-injective (x Name.≟ x₁)name x ≟ meta x₁ = no (λ ())meta x ≟ nat x₁ = no (λ ())meta x ≟ word64 x₁ = no (λ ())meta x ≟ float x₁ = no (λ ())meta x ≟ char x₁ = no (λ ())meta x ≟ string x₁ = no (λ ())meta x ≟ name x₁ = no (λ ())meta x ≟ meta x₁ = map′ (cong meta) meta-injective (x Meta.≟ x₁)infix 4 _≡ᵇ__≡ᵇ_ : Literal → Literal → Booll ≡ᵇ l′ = isYes (l ≟ l′)
-------------------------------------------------------------------------- The Agda standard library---- Instances for reflected syntax------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Instances whereopen import Levelimport Reflection.AST.Literal as Literalimport Reflection.AST.Name as Nameimport Reflection.AST.Meta as Metaimport Reflection.AST.Abstraction as Abstractionimport Reflection.AST.Argument as Argumentimport Reflection.AST.Argument.Visibility as Visibilityimport Reflection.AST.Argument.Relevance as Relevanceimport Reflection.AST.Argument.Information as Informationimport Reflection.AST.Pattern as Patternimport Reflection.AST.Term as Termopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.TypeClassesprivatevariablea : LevelA : Set ainstanceLit-≡-isDecEquivalence = isDecEquivalence Literal._≟_Name-≡-isDecEquivalence = isDecEquivalence Name._≟_Meta-≡-isDecEquivalence = isDecEquivalence Meta._≟_Visibility-≡-isDecEquivalence = isDecEquivalence Visibility._≟_Relevance-≡-isDecEquivalence = isDecEquivalence Relevance._≟_ArgInfo-≡-isDecEquivalence = isDecEquivalence Information._≟_Pattern-≡-isDecEquivalence = isDecEquivalence Pattern._≟_Clause-≡-isDecEquivalence = isDecEquivalence Term._≟-Clause_Term-≡-isDecEquivalence = isDecEquivalence Term._≟_Sort-≡-isDecEquivalence = isDecEquivalence Term._≟-Sort_Abs-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → IsDecEquivalence {A = Abstraction.Abs A} _≡_Abs-≡-isDecEquivalence = isDecEquivalence (Abstraction.≡-dec _≟_)Arg-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → IsDecEquivalence {A = Argument.Arg A} _≡_Arg-≡-isDecEquivalence = isDecEquivalence (Argument.≡-dec _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Definitions used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Definition whereimport Data.List.Properties as List using (≡-dec)import Data.Nat.Properties as ℕ using (_≟_)open import Data.Product.Base using (_×_; <_,_>; uncurry)open import Relation.Nullary.Decidable.Core using (map′; _×-dec_; yes; no)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂)import Reflection.AST.Argument as Argimport Reflection.AST.Name as Nameimport Reflection.AST.Term as Term-------------------------------------------------------------------------- Re-exporting type publicallyopen import Agda.Builtin.Reflection publicusing ( Definition; function; data-type; axiom)renaming ( record-type to record′; data-cons to constructor′; prim-fun to primitive′ )-------------------------------------------------------------------------- Decidable equalityfunction-injective : ∀ {cs cs′} → function cs ≡ function cs′ → cs ≡ cs′function-injective refl = refldata-type-injective₁ : ∀ {pars pars′ cs cs′} → data-type pars cs ≡ data-type pars′ cs′ → pars ≡ pars′data-type-injective₁ refl = refldata-type-injective₂ : ∀ {pars pars′ cs cs′} → data-type pars cs ≡ data-type pars′ cs′ → cs ≡ cs′data-type-injective₂ refl = refldata-type-injective : ∀ {pars pars′ cs cs′} → data-type pars cs ≡ data-type pars′ cs′ → pars ≡ pars′ × cs ≡ cs′data-type-injective = < data-type-injective₁ , data-type-injective₂ >record′-injective₁ : ∀ {c c′ fs fs′} → record′ c fs ≡ record′ c′ fs′ → c ≡ c′record′-injective₁ refl = reflrecord′-injective₂ : ∀ {c c′ fs fs′} → record′ c fs ≡ record′ c′ fs′ → fs ≡ fs′record′-injective₂ refl = reflrecord′-injective : ∀ {c c′ fs fs′} → record′ c fs ≡ record′ c′ fs′ → c ≡ c′ × fs ≡ fs′record′-injective = < record′-injective₁ , record′-injective₂ >constructor′-injective : ∀ {c c′} → constructor′ c ≡ constructor′ c′ → c ≡ c′constructor′-injective refl = reflinfix 4 _≟__≟_ : DecidableEquality Definitionfunction cs ≟ function cs′ =map′ (cong function) function-injective (cs Term.≟-Clauses cs′)data-type pars cs ≟ data-type pars′ cs′ =map′ (uncurry (cong₂ data-type)) data-type-injective(pars ℕ.≟ pars′ ×-dec List.≡-dec Name._≟_ cs cs′)record′ c fs ≟ record′ c′ fs′ =map′ (uncurry (cong₂ record′)) record′-injective(c Name.≟ c′ ×-dec List.≡-dec (Arg.≡-dec Name._≟_) fs fs′)constructor′ d ≟ constructor′ d′ =map′ (cong constructor′) constructor′-injective (d Name.≟ d′)axiom ≟ axiom = yes reflprimitive′ ≟ primitive′ = yes refl-- antidiagonalfunction cs ≟ data-type pars cs₁ = no (λ ())function cs ≟ record′ c fs = no (λ ())function cs ≟ constructor′ d = no (λ ())function cs ≟ axiom = no (λ ())function cs ≟ primitive′ = no (λ ())data-type pars cs ≟ function cs₁ = no (λ ())data-type pars cs ≟ record′ c fs = no (λ ())data-type pars cs ≟ constructor′ d = no (λ ())data-type pars cs ≟ axiom = no (λ ())data-type pars cs ≟ primitive′ = no (λ ())record′ c fs ≟ function cs = no (λ ())record′ c fs ≟ data-type pars cs = no (λ ())record′ c fs ≟ constructor′ d = no (λ ())record′ c fs ≟ axiom = no (λ ())record′ c fs ≟ primitive′ = no (λ ())constructor′ d ≟ function cs = no (λ ())constructor′ d ≟ data-type pars cs = no (λ ())constructor′ d ≟ record′ c fs = no (λ ())constructor′ d ≟ axiom = no (λ ())constructor′ d ≟ primitive′ = no (λ ())axiom ≟ function cs = no (λ ())axiom ≟ data-type pars cs = no (λ ())axiom ≟ record′ c fs = no (λ ())axiom ≟ constructor′ d = no (λ ())axiom ≟ primitive′ = no (λ ())primitive′ ≟ function cs = no (λ ())primitive′ ≟ data-type pars cs = no (λ ())primitive′ ≟ record′ c fs = no (λ ())primitive′ ≟ constructor′ d = no (λ ())primitive′ ≟ axiom = no (λ ())
-------------------------------------------------------------------------- The Agda standard library---- Weakening, strengthening and free variable check for reflected terms.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.DeBruijn whereopen import Data.Bool.Base using (Bool; true; false; _∨_; if_then_else_)open import Data.Nat.Base using (ℕ; zero; suc; _+_; _∸_; _<ᵇ_; _≡ᵇ_)open import Data.List.Base using (List; []; _∷_; _++_)open import Data.Maybe.Base using (Maybe; nothing; just)import Data.Maybe.Effectful as Maybeimport Function.Identity.Effectful as Identityopen import Effect.Applicative using (RawApplicative; mkRawApplicative)open import Reflectionopen import Reflection.AST.Argument.Visibility using (Visibility)import Reflection.AST.Traversal as Traverseprivatevariable A : Set-------------------------------------------------------------------------- Weakeningmodule _ whereopen Traverse Identity.applicativeprivatewkVar : ℕ → Cxt → ℕ → ℕwkVar by (from , _) i = if i <ᵇ from then i else i + byactions : ℕ → Actionsactions k = record defaultActions { onVar = wkVar k }weakenFrom′ : (Actions → Cxt → A → A) → (from by : ℕ) → A → AweakenFrom′ trav from by = trav (actions by) (from , []) -- not using the context partweakenFrom : (from by : ℕ) → Term → TermweakenFrom = weakenFrom′ traverseTermweaken : (by : ℕ) → Term → Termweaken = weakenFrom 0weakenArgs : (by : ℕ) → Args Term → Args TermweakenArgs = weakenFrom′ traverseArgs 0weakenClauses : (by : ℕ) → Clauses → ClausesweakenClauses = weakenFrom′ traverseClauses 0-------------------------------------------------------------------------- η-expansionprivateη : Visibility → (Args Term → Term) → Args Term → Termη h f args =lam h (abs "x" (f (weakenArgs 1 args ++arg (arg-info h defaultModality) (var 0 []) ∷[])))η-expand : Visibility → Term → Termη-expand h (var x args) = η h (var (suc x)) argsη-expand h (con c args) = η h (con c) argsη-expand h (def f args) = η h (def f) argsη-expand h (pat-lam cs args) = η h (pat-lam (weakenClauses 1 cs)) argsη-expand h (meta x args) = η h (meta x) argsη-expand h t@(lam _ _) = tη-expand h t@(pi _ _) = tη-expand h t@(agda-sort _) = tη-expand h t@(lit _) = tη-expand h t@unknown = t-------------------------------------------------------------------------- Strengtheningmodule _ whereopen Traverse Maybe.applicativeprivatestrVar : ℕ → Cxt → ℕ → Maybe ℕstrVar by (from , Γ) i with i <ᵇ from | i <ᵇ from + by... | true | _ = just i... | _ | true = nothing... | _ | _ = just (i ∸ by)actions : ℕ → Actionsactions by = record defaultActions { onVar = strVar by }strengthenFromBy′ : (Actions → Cxt → A → Maybe A) → (from by : ℕ) → A → Maybe AstrengthenFromBy′ trav from by = trav (actions by) (from , []) -- not using the context partstrengthenFromBy : (from by : ℕ) → Term → Maybe TermstrengthenFromBy = strengthenFromBy′ traverseTermstrengthenBy : (by : ℕ) → Term → Maybe TermstrengthenBy = strengthenFromBy 0strengthenFrom : (from : ℕ) → Term → Maybe TermstrengthenFrom from = strengthenFromBy from 1strengthen : Term → Maybe Termstrengthen = strengthenFromBy 0 1-------------------------------------------------------------------------- Free variable checkmodule _ whereprivateanyApplicative : ∀ {ℓ} → RawApplicative {ℓ} (λ _ → Bool)anyApplicative = mkRawApplicative _ (λ _ → false) _∨_open Traverse anyApplicativeprivatefvVar : ℕ → Cxt → ℕ → BoolfvVar i (n , _) x = i + n ≡ᵇ xactions : ℕ → Actionsactions i = record defaultActions { onVar = fvVar i }infix 4 _∈FV__∈FV_ : ℕ → Term → Booli ∈FV t = traverseTerm (actions i) (0 , []) t
-------------------------------------------------------------------------- The Agda standard library---- Arguments used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.Product.Base using (_×_; <_,_>; uncurry)open import Relation.Nullary.Decidable.Core using (Dec; map′; _×-dec_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Levelopen import Reflection.AST.Argument.Visibilityopen import Reflection.AST.Argument.Relevanceopen import Reflection.AST.Argument.Quantityopen import Reflection.AST.Argument.Modalityopen import Reflection.AST.Argument.Information as Informationprivatevariablea b : LevelA B : Set ai j : ArgInfox y : A-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (Arg)open Arg public-- Pattern synonymspattern defaultModality = modality relevant quantity-ωpattern vArg ty = arg (arg-info visible defaultModality) typattern hArg ty = arg (arg-info hidden defaultModality) typattern iArg ty = arg (arg-info instance′ defaultModality) ty-------------------------------------------------------------------------- Lists of argumentsArgs : (A : Set a) → Set aArgs A = List (Arg A)-- Pattern for appending a visible argumentinfixr 5 _⟨∷⟩_pattern _⟨∷⟩_ x args = vArg x ∷ args-- Pattern for appending a hidden argumentinfixr 5 _⟅∷⟆_pattern _⟅∷⟆_ x args = hArg x ∷ args-------------------------------------------------------------------------- Operationsmap : (A → B) → Arg A → Arg Bmap f (arg i x) = arg i (f x)map-Args : (A → B) → Args A → Args Bmap-Args f xs = List.map (map f) xs-------------------------------------------------------------------------- Decidable equalityarg-injective₁ : arg i x ≡ arg j y → i ≡ jarg-injective₁ refl = reflarg-injective₂ : arg i x ≡ arg j y → x ≡ yarg-injective₂ refl = reflarg-injective : arg i x ≡ arg j y → i ≡ j × x ≡ yarg-injective = < arg-injective₁ , arg-injective₂ >-- We often need decidability of equality for Arg A when implementing it-- for A. Unfortunately ≡-dec makes the termination checker unhappy.-- Instead, we can match on both Arg A and use unArg-dec for an-- obviously decreasing recursive call.unArg : Arg A → AunArg (arg i a) = aunArg-dec : {arg1 arg2 : Arg A} → Dec (unArg arg1 ≡ unArg arg2) → Dec (arg1 ≡ arg2)unArg-dec {arg1 = arg i x} {arg j y} arg1≟arg2 =map′ (uncurry (cong₂ arg)) arg-injective (i Information.≟ j ×-dec arg1≟arg2)≡-dec : DecidableEquality A → DecidableEquality (Arg A)≡-dec _≟_ x y = unArg-dec (unArg x ≟ unArg y)
-------------------------------------------------------------------------- The Agda standard library---- Argument visibility used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument.Visibility whereopen import Relation.Nullary.Decidable.Core using (yes; no)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (refl)-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (Visibility)open Visibility public-------------------------------------------------------------------------- Decidable equalityinfix 4 _≟__≟_ : DecidableEquality Visibilityvisible ≟ visible = yes reflhidden ≟ hidden = yes reflinstance′ ≟ instance′ = yes reflvisible ≟ hidden = no λ()visible ≟ instance′ = no λ()hidden ≟ visible = no λ()hidden ≟ instance′ = no λ()instance′ ≟ visible = no λ()instance′ ≟ hidden = no λ()
-------------------------------------------------------------------------- The Agda standard library---- Argument relevance used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument.Relevance whereopen import Relation.Nullary.Decidable.Core using (yes; no)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (refl)-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (Relevance)open Relevance public-------------------------------------------------------------------------- Decidable equalityinfix 4 _≟__≟_ : DecidableEquality Relevancerelevant ≟ relevant = yes reflirrelevant ≟ irrelevant = yes reflrelevant ≟ irrelevant = no λ()irrelevant ≟ relevant = no λ()
-------------------------------------------------------------------------- The Agda standard library---- Argument quantities used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument.Quantity whereopen import Relation.Nullary.Decidable.Core using (yes; no)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (refl)-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (Quantity)open Quantity public-------------------------------------------------------------------------- Decidable equalityinfix 4 _≟__≟_ : DecidableEquality Quantityquantity-ω ≟ quantity-ω = yes reflquantity-0 ≟ quantity-0 = yes reflquantity-ω ≟ quantity-0 = no λ()quantity-0 ≟ quantity-ω = no λ()
-------------------------------------------------------------------------- The Agda standard library---- Modalities used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument.Modality whereopen import Data.Product.Base using (_×_; <_,_>; uncurry)open import Relation.Nullary.Decidable.Core using (map′; _×-dec_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Reflection.AST.Argument.Relevance as Relevance using (Relevance)open import Reflection.AST.Argument.Quantity as Quantity using (Quantity)privatevariabler r′ : Relevanceq q′ : Quantity-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (Modality)open Modality public-------------------------------------------------------------------------- Operationsrelevance : Modality → Relevancerelevance (modality r _) = rquantity : Modality → Quantityquantity (modality _ q) = q-------------------------------------------------------------------------- Decidable equalitymodality-injective₁ : modality r q ≡ modality r′ q′ → r ≡ r′modality-injective₁ refl = reflmodality-injective₂ : modality r q ≡ modality r′ q′ → q ≡ q′modality-injective₂ refl = reflmodality-injective : modality r q ≡ modality r′ q′ → r ≡ r′ × q ≡ q′modality-injective = < modality-injective₁ , modality-injective₂ >infix 4 _≟__≟_ : DecidableEquality Modalitymodality r q ≟ modality r′ q′ =map′(uncurry (cong₂ modality))modality-injective(r Relevance.≟ r′ ×-dec q Quantity.≟ q′)
-------------------------------------------------------------------------- The Agda standard library---- Argument information used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Argument.Information whereopen import Data.Product.Base using (_×_; <_,_>; uncurry)open import Relation.Nullary.Decidable.Core using (map′; _×-dec_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Reflection.AST.Argument.Modality as Modality using (Modality)open import Reflection.AST.Argument.Visibility as Visibility using (Visibility)privatevariablev v′ : Visibilitym m′ : Modality-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection public using (ArgInfo)open ArgInfo public-------------------------------------------------------------------------- Operationsvisibility : ArgInfo → Visibilityvisibility (arg-info v _) = vmodality : ArgInfo → Modalitymodality (arg-info _ m) = m-------------------------------------------------------------------------- Decidable equalityarg-info-injective₁ : arg-info v m ≡ arg-info v′ m′ → v ≡ v′arg-info-injective₁ refl = reflarg-info-injective₂ : arg-info v m ≡ arg-info v′ m′ → m ≡ m′arg-info-injective₂ refl = reflarg-info-injective : arg-info v m ≡ arg-info v′ m′ → v ≡ v′ × m ≡ m′arg-info-injective = < arg-info-injective₁ , arg-info-injective₂ >infix 4 _≟__≟_ : DecidableEquality ArgInfoarg-info v m ≟ arg-info v′ m′ =map′(uncurry (cong₂ arg-info))arg-info-injective(v Visibility.≟ v′ ×-dec m Modality.≟ m′)
-------------------------------------------------------------------------- The Agda standard library---- Alpha equality over terms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.AlphaEquality whereopen import Data.Bool.Base using (Bool; true; false; _∧_)open import Data.List.Base using ([]; _∷_)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _≡ᵇ_)open import Data.Product.Base using (_,_)open import Relation.Nullary.Decidable.Core using (⌊_⌋)open import Relation.Binary.Definitions using (DecidableEquality)open import Reflection.AST.Abstractionopen import Reflection.AST.Argumentopen import Reflection.AST.Argument.Information as ArgInfoopen import Reflection.AST.Argument.Modality as Modalityopen import Reflection.AST.Argument.Visibility as Visibilityopen import Reflection.AST.Meta as Metaopen import Reflection.AST.Name as Nameopen import Reflection.AST.Literal as Literalopen import Reflection.AST.Termopen import Level using (Level)privatevariablea : LevelA : Set a-------------------------------------------------------------------------- Definitionrecord AlphaEquality (A : Set) : Set whereconstructor mkAlphaEqualityinfix 4 _=α=_field_=α=_ : A → A → Boolopen AlphaEquality {{...}} public-------------------------------------------------------------------------- Utilities≟⇒α : DecidableEquality A → AlphaEquality A≟⇒α _≟_ = mkAlphaEquality (λ x y → ⌊ x ≟ y ⌋)-------------------------------------------------------------------------- Propositional cases-- In the following cases alpha equality coincides with propositiona-- equalityinstanceα-Visibility : AlphaEquality Visibilityα-Visibility = ≟⇒α Visibility._≟_α-Modality : AlphaEquality Modalityα-Modality = ≟⇒α Modality._≟_α-ArgInfo : AlphaEquality ArgInfoα-ArgInfo = ≟⇒α ArgInfo._≟_α-Literal : AlphaEquality Literalα-Literal = ≟⇒α Literal._≟_α-Meta : AlphaEquality Metaα-Meta = ≟⇒α Meta._≟_α-Name : AlphaEquality Nameα-Name = ≟⇒α Name._≟_-------------------------------------------------------------------------- Interesting cases-- This is where we deviate from propositional equality and ignore the-- names of the binders.-- Unfortunately we can't declare these as instances directly as the-- termination checker isn't clever enough to peer inside the records.mutual_=α=-AbsTerm_ : Abs Term → Abs Term → Bool(abs s a) =α=-AbsTerm (abs s′ a′) = a =α=-Term a′_=α=-Telescope_ : Telescope → Telescope → Bool[] =α=-Telescope [] = true((s , x) ∷ xs) =α=-Telescope ((s' , x′) ∷ xs′) = (x =α=-ArgTerm x′) ∧ (xs =α=-Telescope xs′)[] =α=-Telescope (_ ∷ _) = false(_ ∷ _) =α=-Telescope [] = false-------------------------------------------------------------------------- Remaining cases-- The following cases simply recurse over the remaining AST in exactly-- the same way as propositional equality._=α=-ArgTerm_ : Arg Term → Arg Term → Bool(arg i a) =α=-ArgTerm (arg i′ a′) = a =α=-Term a′_=α=-ArgPattern_ : Arg Pattern → Arg Pattern → Bool(arg i a) =α=-ArgPattern (arg i′ a′) = a =α=-Pattern a′_=α=-Term_ : Term → Term → Bool(var x args) =α=-Term (var x′ args′) = (x ℕ.≡ᵇ x′) ∧ (args =α=-ArgsTerm args′)(con c args) =α=-Term (con c′ args′) = (c =α= c′) ∧ (args =α=-ArgsTerm args′)(def f args) =α=-Term (def f′ args′) = (f =α= f′) ∧ (args =α=-ArgsTerm args′)(meta x args) =α=-Term (meta x′ args′) = (x =α= x′) ∧ (args =α=-ArgsTerm args′)(pat-lam cs args) =α=-Term (pat-lam cs′ args′) = (cs =α=-Clauses cs′) ∧ (args =α=-ArgsTerm args′)(pi t₁ t₂ ) =α=-Term (pi t₁′ t₂′ ) = (t₁ =α=-ArgTerm t₁′) ∧ (t₂ =α=-AbsTerm t₂′)(sort s ) =α=-Term (sort s′ ) = s =α=-Sort s′(lam v t ) =α=-Term (lam v′ t′ ) = (v =α= v′) ∧ (t =α=-AbsTerm t′)(lit l ) =α=-Term (lit l′ ) = l =α= l′(unknown ) =α=-Term (unknown ) = true(var x args ) =α=-Term (con c args′) = false(var x args ) =α=-Term (def f args′) = false(var x args ) =α=-Term (lam v t ) = false(var x args ) =α=-Term (pi t₁ t₂ ) = false(var x args ) =α=-Term (sort _ ) = false(var x args ) =α=-Term (lit _ ) = false(var x args ) =α=-Term (meta _ _ ) = false(var x args ) =α=-Term (unknown ) = false(con c args ) =α=-Term (var x args′) = false(con c args ) =α=-Term (def f args′) = false(con c args ) =α=-Term (lam v t ) = false(con c args ) =α=-Term (pi t₁ t₂ ) = false(con c args ) =α=-Term (sort _ ) = false(con c args ) =α=-Term (lit _ ) = false(con c args ) =α=-Term (meta _ _ ) = false(con c args ) =α=-Term (unknown ) = false(def f args ) =α=-Term (var x args′) = false(def f args ) =α=-Term (con c args′) = false(def f args ) =α=-Term (lam v t ) = false(def f args ) =α=-Term (pi t₁ t₂ ) = false(def f args ) =α=-Term (sort _ ) = false(def f args ) =α=-Term (lit _ ) = false(def f args ) =α=-Term (meta _ _ ) = false(def f args ) =α=-Term (unknown ) = false(lam v t ) =α=-Term (var x args ) = false(lam v t ) =α=-Term (con c args ) = false(lam v t ) =α=-Term (def f args ) = false(lam v t ) =α=-Term (pi t₁ t₂ ) = false(lam v t ) =α=-Term (sort _ ) = false(lam v t ) =α=-Term (lit _ ) = false(lam v t ) =α=-Term (meta _ _ ) = false(lam v t ) =α=-Term (unknown ) = false(pi t₁ t₂ ) =α=-Term (var x args ) = false(pi t₁ t₂ ) =α=-Term (con c args ) = false(pi t₁ t₂ ) =α=-Term (def f args ) = false(pi t₁ t₂ ) =α=-Term (lam v t ) = false(pi t₁ t₂ ) =α=-Term (sort _ ) = false(pi t₁ t₂ ) =α=-Term (lit _ ) = false(pi t₁ t₂ ) =α=-Term (meta _ _ ) = false(pi t₁ t₂ ) =α=-Term (unknown ) = false(sort _ ) =α=-Term (var x args ) = false(sort _ ) =α=-Term (con c args ) = false(sort _ ) =α=-Term (def f args ) = false(sort _ ) =α=-Term (lam v t ) = false(sort _ ) =α=-Term (pi t₁ t₂ ) = false(sort _ ) =α=-Term (lit _ ) = false(sort _ ) =α=-Term (meta _ _ ) = false(sort _ ) =α=-Term (unknown ) = false(lit _ ) =α=-Term (var x args ) = false(lit _ ) =α=-Term (con c args ) = false(lit _ ) =α=-Term (def f args ) = false(lit _ ) =α=-Term (lam v t ) = false(lit _ ) =α=-Term (pi t₁ t₂ ) = false(lit _ ) =α=-Term (sort _ ) = false(lit _ ) =α=-Term (meta _ _ ) = false(lit _ ) =α=-Term (unknown ) = false(meta _ _ ) =α=-Term (var x args ) = false(meta _ _ ) =α=-Term (con c args ) = false(meta _ _ ) =α=-Term (def f args ) = false(meta _ _ ) =α=-Term (lam v t ) = false(meta _ _ ) =α=-Term (pi t₁ t₂ ) = false(meta _ _ ) =α=-Term (sort _ ) = false(meta _ _ ) =α=-Term (lit _ ) = false(meta _ _ ) =α=-Term (unknown ) = false(unknown ) =α=-Term (var x args ) = false(unknown ) =α=-Term (con c args ) = false(unknown ) =α=-Term (def f args ) = false(unknown ) =α=-Term (lam v t ) = false(unknown ) =α=-Term (pi t₁ t₂ ) = false(unknown ) =α=-Term (sort _ ) = false(unknown ) =α=-Term (lit _ ) = false(unknown ) =α=-Term (meta _ _ ) = false(pat-lam _ _) =α=-Term (var x args ) = false(pat-lam _ _) =α=-Term (con c args ) = false(pat-lam _ _) =α=-Term (def f args ) = false(pat-lam _ _) =α=-Term (lam v t ) = false(pat-lam _ _) =α=-Term (pi t₁ t₂ ) = false(pat-lam _ _) =α=-Term (sort _ ) = false(pat-lam _ _) =α=-Term (lit _ ) = false(pat-lam _ _) =α=-Term (meta _ _ ) = false(pat-lam _ _) =α=-Term (unknown ) = false(var x args ) =α=-Term (pat-lam _ _) = false(con c args ) =α=-Term (pat-lam _ _) = false(def f args ) =α=-Term (pat-lam _ _) = false(lam v t ) =α=-Term (pat-lam _ _) = false(pi t₁ t₂ ) =α=-Term (pat-lam _ _) = false(sort _ ) =α=-Term (pat-lam _ _) = false(lit _ ) =α=-Term (pat-lam _ _) = false(meta _ _ ) =α=-Term (pat-lam _ _) = false(unknown ) =α=-Term (pat-lam _ _) = false_=α=-Sort_ : Sort → Sort → Bool(set t ) =α=-Sort (set t′ ) = t =α=-Term t′(lit n ) =α=-Sort (lit n′ ) = n ℕ.≡ᵇ n′(prop t ) =α=-Sort (prop t′ ) = t =α=-Term t′(propLit n) =α=-Sort (propLit n′) = n ℕ.≡ᵇ n′(inf n ) =α=-Sort (inf n′ ) = n ℕ.≡ᵇ n′(unknown ) =α=-Sort (unknown ) = true(set _ ) =α=-Sort (lit _ ) = false(set _ ) =α=-Sort (prop _ ) = false(set _ ) =α=-Sort (propLit _) = false(set _ ) =α=-Sort (inf _ ) = false(set _ ) =α=-Sort (unknown ) = false(lit _ ) =α=-Sort (set _ ) = false(lit _ ) =α=-Sort (prop _ ) = false(lit _ ) =α=-Sort (propLit _) = false(lit _ ) =α=-Sort (inf _ ) = false(lit _ ) =α=-Sort (unknown ) = false(prop _ ) =α=-Sort (set _ ) = false(prop _ ) =α=-Sort (lit _ ) = false(prop _ ) =α=-Sort (propLit _) = false(prop _ ) =α=-Sort (inf _ ) = false(prop _ ) =α=-Sort (unknown ) = false(propLit _) =α=-Sort (set _ ) = false(propLit _) =α=-Sort (lit _ ) = false(propLit _) =α=-Sort (prop _ ) = false(propLit _) =α=-Sort (inf _ ) = false(propLit _) =α=-Sort (unknown ) = false(inf _ ) =α=-Sort (set _ ) = false(inf _ ) =α=-Sort (lit _ ) = false(inf _ ) =α=-Sort (prop _ ) = false(inf _ ) =α=-Sort (propLit _) = false(inf _ ) =α=-Sort (unknown ) = false(unknown ) =α=-Sort (set _ ) = false(unknown ) =α=-Sort (lit _ ) = false(unknown ) =α=-Sort (prop _ ) = false(unknown ) =α=-Sort (propLit _) = false(unknown ) =α=-Sort (inf _ ) = false_=α=-Clause_ : Clause → Clause → Bool(clause tel ps b) =α=-Clause (clause tel′ ps′ b′) = (tel =α=-Telescope tel′) ∧ (ps =α=-ArgsPattern ps′) ∧ (b =α=-Term b′)(absurd-clause tel ps) =α=-Clause (absurd-clause tel′ ps′) = (tel =α=-Telescope tel′) ∧ (ps =α=-ArgsPattern ps′)(clause _ _ _) =α=-Clause (absurd-clause _ _) = false(absurd-clause _ _) =α=-Clause (clause _ _ _) = false_=α=-Clauses_ : Clauses → Clauses → Bool[] =α=-Clauses [] = true(x ∷ xs) =α=-Clauses (x′ ∷ xs′) = (x =α=-Clause x′) ∧ (xs =α=-Clauses xs′)[] =α=-Clauses (_ ∷ _) = false(_ ∷ _) =α=-Clauses [] = false_=α=-ArgsTerm_ : Args Term → Args Term → Bool[] =α=-ArgsTerm [] = true(x ∷ xs) =α=-ArgsTerm (x′ ∷ xs′) = (x =α=-ArgTerm x′) ∧ (xs =α=-ArgsTerm xs′)[] =α=-ArgsTerm (_ ∷ _) = false(_ ∷ _) =α=-ArgsTerm [] = false_=α=-Pattern_ : Pattern → Pattern → Bool(con c ps) =α=-Pattern (con c′ ps′) = (c =α= c′) ∧ (ps =α=-ArgsPattern ps′)(var x ) =α=-Pattern (var x′ ) = x ℕ.≡ᵇ x′(lit l ) =α=-Pattern (lit l′ ) = l =α= l′(proj a ) =α=-Pattern (proj a′ ) = a =α= a′(dot t ) =α=-Pattern (dot t′ ) = t =α=-Term t′(absurd x) =α=-Pattern (absurd x′ ) = x ℕ.≡ᵇ x′(con x x₁) =α=-Pattern (dot x₂ ) = false(con x x₁) =α=-Pattern (var x₂ ) = false(con x x₁) =α=-Pattern (lit x₂ ) = false(con x x₁) =α=-Pattern (proj x₂ ) = false(con x x₁) =α=-Pattern (absurd x₂ ) = false(dot x ) =α=-Pattern (con x₁ x₂ ) = false(dot x ) =α=-Pattern (var x₁ ) = false(dot x ) =α=-Pattern (lit x₁ ) = false(dot x ) =α=-Pattern (proj x₁ ) = false(dot x ) =α=-Pattern (absurd x₁ ) = false(var s ) =α=-Pattern (con x x₁ ) = false(var s ) =α=-Pattern (dot x ) = false(var s ) =α=-Pattern (lit x ) = false(var s ) =α=-Pattern (proj x ) = false(var s ) =α=-Pattern (absurd x ) = false(lit x ) =α=-Pattern (con x₁ x₂ ) = false(lit x ) =α=-Pattern (dot x₁ ) = false(lit x ) =α=-Pattern (var _ ) = false(lit x ) =α=-Pattern (proj x₁ ) = false(lit x ) =α=-Pattern (absurd x₁ ) = false(proj x ) =α=-Pattern (con x₁ x₂ ) = false(proj x ) =α=-Pattern (dot x₁ ) = false(proj x ) =α=-Pattern (var _ ) = false(proj x ) =α=-Pattern (lit x₁ ) = false(proj x ) =α=-Pattern (absurd x₁ ) = false(absurd x) =α=-Pattern (con x₁ x₂ ) = false(absurd x) =α=-Pattern (dot x₁ ) = false(absurd x) =α=-Pattern (var _ ) = false(absurd x) =α=-Pattern (lit x₁ ) = false(absurd x) =α=-Pattern (proj x₁ ) = false_=α=-ArgsPattern_ : Args Pattern → Args Pattern → Bool[] =α=-ArgsPattern [] = true(x ∷ xs) =α=-ArgsPattern (x′ ∷ xs′) = (x =α=-ArgPattern x′) ∧ (xs =α=-ArgsPattern xs′)[] =α=-ArgsPattern (_ ∷ _) = false(_ ∷ _) =α=-ArgsPattern [] = false-------------------------------------------------------------------------- Instance declarations for mutually recursive casesinstanceα-AbsTerm : AlphaEquality (Abs Term)α-AbsTerm = mkAlphaEquality _=α=-AbsTerm_α-ArgTerm : AlphaEquality (Arg Term)α-ArgTerm = mkAlphaEquality _=α=-ArgTerm_α-ArgPattern : AlphaEquality (Arg Pattern)α-ArgPattern = mkAlphaEquality _=α=-ArgPattern_α-Telescope : AlphaEquality Telescopeα-Telescope = mkAlphaEquality _=α=-Telescope_α-Term : AlphaEquality Termα-Term = mkAlphaEquality _=α=-Term_α-Sort : AlphaEquality Sortα-Sort = mkAlphaEquality _=α=-Sort_α-Clause : AlphaEquality Clauseα-Clause = mkAlphaEquality _=α=-Clause_α-Clauses : AlphaEquality Clausesα-Clauses = mkAlphaEquality _=α=-Clauses_α-ArgsTerm : AlphaEquality (Args Term)α-ArgsTerm = mkAlphaEquality _=α=-ArgsTerm_α-Pattern : AlphaEquality Patternα-Pattern = mkAlphaEquality _=α=-Pattern_α-ArgsPattern : AlphaEquality (Args Pattern)α-ArgsPattern = mkAlphaEquality _=α=-ArgsPattern_
-------------------------------------------------------------------------- The Agda standard library---- Abstractions used in the reflection machinery------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Reflection.AST.Abstraction whereopen import Data.String.Base as String using (String)open import Data.String.Properties as String using (_≟_)open import Data.Product.Base using (_×_; <_,_>; uncurry)open import Level using (Level)open import Relation.Nullary.Decidable.Core using (Dec; map′; _×-dec_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)privatevariablea b : LevelA B : Set as t : Stringx y : A-------------------------------------------------------------------------- Re-exporting the builtins publiclyopen import Agda.Builtin.Reflection publicusing (Abs)open Abs public-------------------------------------------------------------------------- Operationsmap : (A → B) → Abs A → Abs Bmap f (abs s x) = abs s (f x)-------------------------------------------------------------------------- Decidable equalityabs-injective₁ : abs s x ≡ abs t y → s ≡ tabs-injective₁ refl = reflabs-injective₂ : abs s x ≡ abs t y → x ≡ yabs-injective₂ refl = reflabs-injective : abs s x ≡ abs t y → s ≡ t × x ≡ yabs-injective = < abs-injective₁ , abs-injective₂ >-- We often need decidability of equality for Abs A when implementing it-- for A. Unfortunately ≡-dec makes the termination checker unhappy.-- Instead, we can match on both Abs A and use unAbs-dec for an-- obviously decreasing recursive call.unAbs : Abs A → AunAbs (abs s a) = aunAbs-dec : {abs1 abs2 : Abs A} → Dec (unAbs abs1 ≡ unAbs abs2) → Dec (abs1 ≡ abs2)unAbs-dec {abs1 = abs s a} {abs t a′} a≟a′ =map′ (uncurry (cong₂ abs)) abs-injective (s String.≟ t ×-dec a≟a′)≡-dec : DecidableEquality A → DecidableEquality (Abs A)≡-dec _≟_ x y = unAbs-dec (unAbs x ≟ unAbs y)
-------------------------------------------------------------------------- The Agda standard library---- Universe levels------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Level where-- Levels.open import Agda.Primitive as Prim publicusing (Level; _⊔_; Setω)renaming (lzero to zero; lsuc to suc)-- Lifting.record Lift {a} ℓ (A : Set a) : Set (a ⊔ ℓ) whereconstructor liftfield lower : Aopen Lift public-- Synonyms0ℓ : Level0ℓ = zerolevelOfType : ∀ {a} → Set a → LevellevelOfType {a} _ = alevelOfTerm : ∀ {a} {A : Set a} → A → LevellevelOfTerm {a} _ = a
-------------------------------------------------------------------------- The Agda standard library---- Conversion from naturals to universe levels------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Level.Literals whereopen import Agda.Builtin.Nat renaming (Nat to ℕ)open import Agda.Builtin.FromNatopen import Agda.Builtin.Unitopen import Level using (Level; 0ℓ)-- Increase a Level by a number of sucs.infixl 6 _ℕ+__ℕ+_ : ℕ → Level → Levelzero ℕ+ ℓ = ℓsuc n ℕ+ ℓ = Level.suc (n ℕ+ ℓ)-- Nat-computed Level.infix 10 #_#_ : ℕ → Level#_ = _ℕ+ 0ℓ-- Literal overloading for levels.Levelℕ : Number LevelLevelℕ .Number.Constraint _ = ⊤Levelℕ .Number.fromNat n = # n
-------------------------------------------------------------------------- The Agda standard library---- An abstraction of various forms of recursion/induction-------------------------------------------------------------------------- The idea underlying Induction.* comes from Epigram 1, see Section 4-- of "The view from the left" by McBride and McKinna.-- Note: The types in this module can perhaps be easier to understand-- if they are normalised. Note also that Agda can do the-- normalisation for you.{-# OPTIONS --cubical-compatible --safe #-}module Induction whereopen import Levelopen import Relation.Unaryopen import Relation.Unary.PredicateTransformer using (PT)privatevariablea ℓ ℓ₁ ℓ₂ : LevelA : Set aQ : Pred A ℓRec : PT A A ℓ₁ ℓ₂-------------------------------------------------------------------------- A RecStruct describes the allowed structure of recursion. The-- examples in Data.Nat.Induction should explain what this is all-- about.RecStruct : Set a → (ℓ₁ ℓ₂ : Level) → Set _RecStruct A = PT A A-- A recursor builder constructs an instance of a recursion structure-- for a given input.RecursorBuilder : RecStruct A ℓ₁ ℓ₂ → Set _RecursorBuilder Rec = ∀ P → Rec P ⊆′ P → Universal (Rec P)-- A recursor can be used to actually compute/prove something useful.Recursor : RecStruct A ℓ₁ ℓ₂ → Set _Recursor Rec = ∀ P → Rec P ⊆′ P → Universal P-- And recursors can be constructed from recursor builders.build : RecursorBuilder Rec → Recursor Recbuild builder P f x = f x (builder P f x)-- We can repeat the exercise above for subsets of the type we are-- recursing over.SubsetRecursorBuilder : Pred A ℓ → RecStruct A ℓ₁ ℓ₂ → Set _SubsetRecursorBuilder Q Rec = ∀ P → Rec P ⊆′ P → Q ⊆′ Rec PSubsetRecursor : Pred A ℓ → RecStruct A ℓ₁ ℓ₂ → Set _SubsetRecursor Q Rec = ∀ P → Rec P ⊆′ P → Q ⊆′ PsubsetBuild : SubsetRecursorBuilder Q Rec → SubsetRecursor Q RecsubsetBuild builder P f x q = f x (builder P f x q)
-------------------------------------------------------------------------- The Agda standard library---- Well-founded induction------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Induction.WellFounded whereopen import Data.Product.Base using (Σ; _,_; proj₁; proj₂)open import Function.Base using (_∘_; flip; _on_)open import Inductionopen import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitionsusing (Symmetric; Asymmetric; Irreflexive; _Respects₂_;_Respectsʳ_; _Respects_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Binary.Consequences using (asym⇒irr)open import Relation.Unaryopen import Relation.Nullary.Negation.Core using (¬_)privatevariablea b ℓ ℓ₁ ℓ₂ r : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definitions-- When using well-founded recursion you can recurse arbitrarily, as-- long as the arguments become smaller, and "smaller" is-- well-founded.WfRec : Rel A r → ∀ {ℓ} → RecStruct A ℓ _WfRec _<_ P x = ∀ {y} → y < x → P y-- The accessibility predicate: x is accessible if everything which is-- smaller than x is also accessible (inductively).data Acc {A : Set a} (_<_ : Rel A ℓ) (x : A) : Set (a ⊔ ℓ) whereacc : (rs : WfRec _<_ (Acc _<_) x) → Acc _<_ x-- The accessibility predicate encodes what it means to be-- well-founded; if all elements are accessible, then _<_ is-- well-founded.WellFounded : Rel A ℓ → Set _WellFounded _<_ = ∀ x → Acc _<_ x-------------------------------------------------------------------------- Basic propertiesacc-inverse : ∀ {_<_ : Rel A ℓ} {x : A} (q : Acc _<_ x) →WfRec _<_ (Acc _<_) xacc-inverse (acc rs) y<x = rs y<xmodule _ {_≈_ : Rel A ℓ₁} {_<_ : Rel A ℓ₂} whereAcc-resp-flip-≈ : _<_ Respectsʳ (flip _≈_) → (Acc _<_) Respects _≈_Acc-resp-flip-≈ respʳ x≈y (acc rec) = acc λ z<y → rec (respʳ x≈y z<y)Acc-resp-≈ : Symmetric _≈_ → _<_ Respectsʳ _≈_ → (Acc _<_) Respects _≈_Acc-resp-≈ sym respʳ x≈y wf = Acc-resp-flip-≈ (respʳ ∘ sym) x≈y wf-------------------------------------------------------------------------- Well-founded induction for the subset of accessible elements:module Some {_<_ : Rel A r} {ℓ} wherewfRecBuilder : SubsetRecursorBuilder (Acc _<_) (WfRec _<_ {ℓ = ℓ})wfRecBuilder P f x (acc rs) = λ y<x → f _ (wfRecBuilder P f _ (rs y<x))wfRec : SubsetRecursor (Acc _<_) (WfRec _<_)wfRec = subsetBuild wfRecBuilderunfold-wfRec : (P : Pred A ℓ) (f : WfRec _<_ P ⊆′ P) {x : A} (q : Acc _<_ x) →wfRec P f x q ≡ f x λ y<x → wfRec P f _ (acc-inverse q y<x)unfold-wfRec P f (acc rs) = refl-------------------------------------------------------------------------- Well-founded induction for all elements, assuming they are all-- accessible:module All {_<_ : Rel A r} (wf : WellFounded _<_) ℓ wherewfRecBuilder : RecursorBuilder (WfRec _<_ {ℓ = ℓ})wfRecBuilder P f x = Some.wfRecBuilder P f x (wf x)wfRec : Recursor (WfRec _<_)wfRec = build wfRecBuilderwfRec-builder = wfRecBuildermodule FixPoint{_<_ : Rel A r} (wf : WellFounded _<_)(P : Pred A ℓ) (f : WfRec _<_ P ⊆′ P)(f-ext : (x : A) {IH IH′ : WfRec _<_ P x} →(∀ {y} y<x → IH {y} y<x ≡ IH′ y<x) →f x IH ≡ f x IH′)wheresome-wfrec-Irrelevant : Pred A _some-wfrec-Irrelevant x = ∀ q q′ → Some.wfRec P f x q ≡ Some.wfRec P f x q′some-wfRec-irrelevant : ∀ x → some-wfrec-Irrelevant xsome-wfRec-irrelevant = All.wfRec wf _ some-wfrec-Irrelevantλ { x IH (acc rs) (acc rs′) → f-ext x λ y<x → IH y<x (rs y<x) (rs′ y<x) }open All wf ℓwfRecBuilder-wfRec : ∀ {x y} y<x → wfRecBuilder P f x y<x ≡ wfRec P f ywfRecBuilder-wfRec {x} {y} y<x with acc rs ← wf x= some-wfRec-irrelevant y (rs y<x) (wf y)unfold-wfRec : ∀ {x} → wfRec P f x ≡ f x λ _ → wfRec P f _unfold-wfRec {x} = f-ext x wfRecBuilder-wfRec-------------------------------------------------------------------------- Well-founded relations are asymmetric and irreflexive.module _ {_<_ : Rel A r} whereacc⇒asym : ∀ {x y} → Acc _<_ x → x < y → ¬ (y < x)acc⇒asym {x} hx =Some.wfRec (λ x → ∀ {y} → x < y → ¬ (y < x)) (λ _ hx x<y y<x → hx y<x y<x x<y) _ hxwf⇒asym : WellFounded _<_ → Asymmetric _<_wf⇒asym wf = acc⇒asym (wf _)wf⇒irrefl : {_≈_ : Rel A ℓ} → _<_ Respects₂ _≈_ →Symmetric _≈_ → WellFounded _<_ → Irreflexive _≈_ _<_wf⇒irrefl r s wf = asym⇒irr r s (wf⇒asym wf)-------------------------------------------------------------------------- It might be useful to establish proofs of Acc or Well-founded using-- combinators such as the ones below (see, for instance,-- "Constructing Recursion Operators in Intuitionistic Type Theory" by-- Lawrence C Paulson).module Subrelation {_<₁_ : Rel A ℓ₁} {_<₂_ : Rel A ℓ₂}(<₁⇒<₂ : ∀ {x y} → x <₁ y → x <₂ y) whereaccessible : Acc _<₂_ ⊆ Acc _<₁_accessible (acc rs) = acc λ y<x → accessible (rs (<₁⇒<₂ y<x))wellFounded : WellFounded _<₂_ → WellFounded _<₁_wellFounded wf = λ x → accessible (wf x)-- DEPRECATED in v1.4.-- Please use proofs in `Relation.Binary.Construct.On` instead.module InverseImage {_<_ : Rel B ℓ} (f : A → B) whereaccessible : ∀ {x} → Acc _<_ (f x) → Acc (_<_ on f) xaccessible (acc rs) = acc λ fy<fx → accessible (rs fy<fx)wellFounded : WellFounded _<_ → WellFounded (_<_ on f)wellFounded wf = λ x → accessible (wf (f x))well-founded = wellFounded{-# WARNING_ON_USAGE accessible"Warning: accessible was deprecated in v1.4.\ \Please use accessible from `Relation.Binary.Construct.On` instead."#-}{-# WARNING_ON_USAGE wellFounded"Warning: wellFounded was deprecated in v1.4.\ \Please use wellFounded from `Relation.Binary.Construct.On` instead."#-}-- DEPRECATED in v1.5.-- Please use `TransClosure` from `Relation.Binary.Construct.Closure.Transitive` instead.module TransitiveClosure {A : Set a} (_<_ : Rel A ℓ) whereinfix 4 _<⁺_data _<⁺_ : Rel A (a ⊔ ℓ) where[_] : ∀ {x y} (x<y : x < y) → x <⁺ ytrans : ∀ {x y z} (x<y : x <⁺ y) (y<z : y <⁺ z) → x <⁺ zdownwardsClosed : ∀ {x y} → Acc _<⁺_ y → x <⁺ y → Acc _<⁺_ xdownwardsClosed (acc rs) x<y = acc λ z<x → rs (trans z<x x<y)mutualaccessible : ∀ {x} → Acc _<_ x → Acc _<⁺_ xaccessible acc-x = acc (accessible′ acc-x)accessible′ : ∀ {x} → Acc _<_ x → WfRec _<⁺_ (Acc _<⁺_) xaccessible′ (acc rs) [ y<x ] = accessible (rs y<x)accessible′ acc-x (trans y<z z<x) =downwardsClosed (accessible′ acc-x z<x) y<zwellFounded : WellFounded _<_ → WellFounded _<⁺_wellFounded wf = λ x → accessible (wf x){-# WARNING_ON_USAGE _<⁺_"Warning: _<⁺_ was deprecated in v1.5.\ \Please use TransClosure from Relation.Binary.Construct.Closure.Transitive instead."#-}-- DEPRECATED in v1.3.-- Please use `×-Lex` from `Data.Product.Relation.Binary.Lex.Strict` instead.module Lexicographic {A : Set a} {B : A → Set b}(RelA : Rel A ℓ₁)(RelB : ∀ x → Rel (B x) ℓ₂) whereinfix 4 _<_data _<_ : Rel (Σ A B) (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) whereleft : ∀ {x₁ y₁ x₂ y₂} (x₁<x₂ : RelA x₁ x₂) → (x₁ , y₁) < (x₂ , y₂)right : ∀ {x y₁ y₂} (y₁<y₂ : RelB x y₁ y₂) → (x , y₁) < (x , y₂)mutualaccessible : ∀ {x y} →Acc RelA x → (∀ {x} → WellFounded (RelB x)) →Acc _<_ (x , y)accessible accA wfB = acc (accessible′ accA (wfB _) wfB)accessible′ :∀ {x y} →Acc RelA x → Acc (RelB x) y → (∀ {x} → WellFounded (RelB x)) →WfRec _<_ (Acc _<_) (x , y)accessible′ (acc rsA) _ wfB (left x′<x) = accessible (rsA x′<x) wfBaccessible′ accA (acc rsB) wfB (right y′<y) =acc (accessible′ accA (rsB y′<y) wfB)wellFounded : WellFounded RelA → (∀ {x} → WellFounded (RelB x)) →WellFounded _<_wellFounded wfA wfB p = accessible (wfA (proj₁ p)) wfBwell-founded = wellFounded{-# WARNING_ON_USAGE _<_"Warning: _<_ was deprecated in v1.3.\ \Please use `×-Lex` from `Data.Product.Relation.Binary.Lex.Strict` instead."#-}{-# WARNING_ON_USAGE accessible"Warning: accessible was deprecated in v1.3."#-}{-# WARNING_ON_USAGE accessible′"Warning: accessible′ was deprecated in v1.3."#-}{-# WARNING_ON_USAGE wellFounded"Warning: wellFounded was deprecated in v1.3.\ \Please use `×-wellFounded` from `Data.Product.Relation.Binary.Lex.Strict` instead."#-}-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.0module Inverse-image = InverseImagemodule Transitive-closure = TransitiveClosure
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic induction------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Induction.Lexicographic whereopen import Data.Product.Base using (Σ; _,_; _×_)open import Inductionopen import Level-- The structure of lexicographic induction.Σ-Rec : ∀ {a b ℓ₁ ℓ₂ ℓ₃} {A : Set a} {B : A → Set b} →RecStruct A (ℓ₁ ⊔ b) ℓ₂ → (∀ x → RecStruct (B x) ℓ₁ ℓ₃) →RecStruct (Σ A B) _ _Σ-Rec RecA RecB P (x , y) =-- Either x is constant and y is "smaller", ...RecB x (λ y′ → P (x , y′)) y×-- ...or x is "smaller" and y is arbitrary.RecA (λ x′ → ∀ y′ → P (x′ , y′)) xinfixr 2 _⊗__⊗_ : ∀ {a b ℓ₁ ℓ₂ ℓ₃} {A : Set a} {B : Set b} →RecStruct A (ℓ₁ ⊔ b) ℓ₂ → RecStruct B ℓ₁ ℓ₃ →RecStruct (A × B) _ _RecA ⊗ RecB = Σ-Rec RecA (λ _ → RecB)-- Constructs a recursor builder for lexicographic induction.Σ-rec-builder :∀ {a b ℓ₁ ℓ₂ ℓ₃} {A : Set a} {B : A → Set b}{RecA : RecStruct A (ℓ₁ ⊔ b) ℓ₂}{RecB : ∀ x → RecStruct (B x) ℓ₁ ℓ₃} →RecursorBuilder RecA → (∀ x → RecursorBuilder (RecB x)) →RecursorBuilder (Σ-Rec RecA RecB)Σ-rec-builder {RecA = RecA} {RecB = RecB} recA recB P f (x , y) =(p₁ x y p₂x , p₂x)wherep₁ : ∀ x y →RecA (λ x′ → ∀ y′ → P (x′ , y′)) x →RecB x (λ y′ → P (x , y′)) yp₁ x y x-rec = recB x(λ y′ → P (x , y′))(λ y y-rec → f (x , y) (y-rec , x-rec))yp₂ : ∀ x → RecA (λ x′ → ∀ y′ → P (x′ , y′)) xp₂ = recA (λ x → ∀ y → P (x , y))(λ x x-rec y → f (x , y) (p₁ x y x-rec , x-rec))p₂x = p₂ x[_⊗_] : ∀ {a b ℓ₁ ℓ₂ ℓ₃} {A : Set a} {B : Set b}{RecA : RecStruct A (ℓ₁ ⊔ b) ℓ₂} {RecB : RecStruct B ℓ₁ ℓ₃} →RecursorBuilder RecA → RecursorBuilder RecB →RecursorBuilder (RecA ⊗ RecB)[ recA ⊗ recB ] = Σ-rec-builder recA (λ _ → recB)-------------------------------------------------------------------------- Exampleprivateopen import Data.Nat.Baseopen import Data.Nat.Induction as ℕ-- The Ackermann function à la Rózsa Péter.ackermann : ℕ → ℕ → ℕackermann m n =build [ ℕ.recBuilder ⊗ ℕ.recBuilder ](λ _ → ℕ)(λ { (zero , n) _ → 1 + n; (suc m , zero) (_ , ackm•) → ackm• 1; (suc m , suc n) (ack[1+m]n , ackm•) → ackm• ack[1+m]n})(m , n)
-------------------------------------------------------------------------- The Agda standard library---- A standard consequence of accessibility/well-foundedness:-- the impossibility of 'infinite descent' from any (accessible)-- element x satisfying P to 'smaller' y also satisfying P------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Induction.InfiniteDescent whereopen import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Data.Nat.Properties as ℕopen import Data.Product.Base using (_,_; proj₁; ∃-syntax; _×_)open import Function.Base using (_∘_)open import Induction.WellFoundedusing (WellFounded; Acc; acc; acc-inverse; module Some)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Closure.Transitiveopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Nullary.Negation.Core as Negation using (¬_)open import Relation.Unaryusing (Pred; ∁; _∩_; _⊆_; _⇒_; Universal; IUniversal; Stable; Empty)privatevariablea r ℓ : LevelA : Set af : ℕ → A_<_ : Rel A rP : Pred A ℓ-------------------------------------------------------------------------- DefinitionsInfiniteDescendingSequence : Rel A r → (ℕ → A) → Set _InfiniteDescendingSequence _<_ f = ∀ n → f (suc n) < f nInfiniteDescendingSequenceFrom : Rel A r → (ℕ → A) → Pred A _InfiniteDescendingSequenceFrom _<_ f x = f zero ≡ x × InfiniteDescendingSequence _<_ fInfiniteDescendingSequence⁺ : Rel A r → (ℕ → A) → Set _InfiniteDescendingSequence⁺ _<_ f = ∀ {m n} → m ℕ.< n → TransClosure _<_ (f n) (f m)InfiniteDescendingSequenceFrom⁺ : Rel A r → (ℕ → A) → Pred A _InfiniteDescendingSequenceFrom⁺ _<_ f x = f zero ≡ x × InfiniteDescendingSequence⁺ _<_ fDescentFrom : Rel A r → Pred A ℓ → Pred A _DescentFrom _<_ P x = P x → ∃[ y ] y < x × P yDescent : Rel A r → Pred A ℓ → Set _Descent _<_ P = ∀ {x} → DescentFrom _<_ P xInfiniteDescentFrom : Rel A r → Pred A ℓ → Pred A _InfiniteDescentFrom _<_ P x = P x → ∃[ f ] InfiniteDescendingSequenceFrom _<_ f x × ∀ n → P (f n)InfiniteDescent : Rel A r → Pred A ℓ → Set _InfiniteDescent _<_ P = ∀ {x} → InfiniteDescentFrom _<_ P xInfiniteDescentFrom⁺ : Rel A r → Pred A ℓ → Pred A _InfiniteDescentFrom⁺ _<_ P x = P x → ∃[ f ] InfiniteDescendingSequenceFrom⁺ _<_ f x × ∀ n → P (f n)InfiniteDescent⁺ : Rel A r → Pred A ℓ → Set _InfiniteDescent⁺ _<_ P = ∀ {x} → InfiniteDescentFrom⁺ _<_ P xNoSmallestCounterExample : Rel A r → Pred A ℓ → Set _NoSmallestCounterExample _<_ P = ∀ {x} → Acc _<_ x → DescentFrom (TransClosure _<_) (∁ P) x-------------------------------------------------------------------------- We can swap between transitively closed and non-transitively closed-- definitionssequence⁺ : InfiniteDescendingSequence (TransClosure _<_) f →InfiniteDescendingSequence⁺ _<_ fsequence⁺ {_<_ = _<_} {f = f} seq[f] = seq⁺[f]′ ∘ ℕ.<⇒<′whereseq⁺[f]′ : ∀ {m n} → m ℕ.<′ n → TransClosure _<_ (f n) (f m)seq⁺[f]′ ℕ.<′-base = seq[f] _seq⁺[f]′ (ℕ.<′-step m<′n) = seq[f] _ ++ seq⁺[f]′ m<′nsequence⁻ : InfiniteDescendingSequence⁺ _<_ f →InfiniteDescendingSequence (TransClosure _<_) fsequence⁻ seq[f] = seq[f] ∘ n<1+n-------------------------------------------------------------------------- Results about unrestricted descentmodule _ (descent : Descent _<_ P) wheredescent∧acc⇒infiniteDescentFrom : (Acc _<_) ⊆ (InfiniteDescentFrom _<_ P)descent∧acc⇒infiniteDescentFrom {x} =Some.wfRec (InfiniteDescentFrom _<_ P) rec xwhererec : _rec y rec[y] pywith z , z<y , pz ← descent pywith g , (g0≡z , g<P) , Π[P∘g] ← rec[y] z<y pz= h , (h0≡y , h<P) , Π[P∘h]whereh : ℕ → _h zero = yh (suc n) = g nh0≡y : h zero ≡ yh0≡y = reflh<P : ∀ n → h (suc n) < h nh<P zero rewrite g0≡z = z<yh<P (suc n) = g<P nΠ[P∘h] : ∀ n → P (h n)Π[P∘h] zero rewrite g0≡z = pyΠ[P∘h] (suc n) = Π[P∘g] ndescent∧wf⇒infiniteDescent : WellFounded _<_ → InfiniteDescent _<_ Pdescent∧wf⇒infiniteDescent wf = descent∧acc⇒infiniteDescentFrom (wf _)descent∧acc⇒unsatisfiable : Acc _<_ ⊆ ∁ Pdescent∧acc⇒unsatisfiable {x} = Some.wfRec (∁ P) rec xwhererec : _rec y rec[y] py = let z , z<y , pz = descent py in rec[y] z<y pzdescent∧wf⇒empty : WellFounded _<_ → Empty Pdescent∧wf⇒empty wf x = descent∧acc⇒unsatisfiable (wf x)-------------------------------------------------------------------------- Results about descent only from accessible elementsmodule _ (accDescent : Acc _<_ ⊆ DescentFrom _<_ P) whereprivatedescent∩ : Descent _<_ (P ∩ Acc _<_)descent∩ (px , acc[x]) =let y , y<x , py = accDescent acc[x] pxin y , y<x , py , acc-inverse acc[x] y<xaccDescent∧acc⇒infiniteDescentFrom : Acc _<_ ⊆ InfiniteDescentFrom _<_ PaccDescent∧acc⇒infiniteDescentFrom acc[x] px =let f , sequence[f] , Π[[P∩Acc]∘f] = descent∧acc⇒infiniteDescentFrom descent∩ acc[x] (px , acc[x])in f , sequence[f] , proj₁ ∘ Π[[P∩Acc]∘f]accDescent∧wf⇒infiniteDescent : WellFounded _<_ → InfiniteDescent _<_ PaccDescent∧wf⇒infiniteDescent wf = accDescent∧acc⇒infiniteDescentFrom (wf _)accDescent∧acc⇒unsatisfiable : Acc _<_ ⊆ ∁ PaccDescent∧acc⇒unsatisfiable acc[x] px = descent∧acc⇒unsatisfiable descent∩ acc[x] (px , acc[x])wf⇒empty : WellFounded _<_ → Empty Pwf⇒empty wf x = accDescent∧acc⇒unsatisfiable (wf x)-------------------------------------------------------------------------- Results about transitively-closed descent only from accessible elementsmodule _ (accDescent⁺ : Acc _<_ ⊆ DescentFrom (TransClosure _<_) P) whereprivatedescent : Acc (TransClosure _<_) ⊆ DescentFrom (TransClosure _<_) Pdescent = accDescent⁺ ∘ accessible⁻ _accDescent⁺∧acc⇒infiniteDescentFrom⁺ : Acc _<_ ⊆ InfiniteDescentFrom⁺ _<_ PaccDescent⁺∧acc⇒infiniteDescentFrom⁺ acc[x] pxwith f , (f0≡x , sequence[f]) , Π[P∘f]← accDescent∧acc⇒infiniteDescentFrom descent (accessible _ acc[x]) px= f , (f0≡x , sequence⁺ sequence[f]) , Π[P∘f]accDescent⁺∧wf⇒infiniteDescent⁺ : WellFounded _<_ → InfiniteDescent⁺ _<_ PaccDescent⁺∧wf⇒infiniteDescent⁺ wf = accDescent⁺∧acc⇒infiniteDescentFrom⁺ (wf _)accDescent⁺∧acc⇒unsatisfiable : Acc _<_ ⊆ ∁ PaccDescent⁺∧acc⇒unsatisfiable = accDescent∧acc⇒unsatisfiable descent ∘ accessible _accDescent⁺∧wf⇒empty : WellFounded _<_ → Empty PaccDescent⁺∧wf⇒empty = wf⇒empty descent ∘ (wellFounded _)-------------------------------------------------------------------------- Finally: the (classical) no smallest counterexample principle itselfmodule _ (stable : Stable P) (noSmallest : NoSmallestCounterExample _<_ P) wherenoSmallestCounterExample∧acc⇒satisfiable : Acc _<_ ⊆ PnoSmallestCounterExample∧acc⇒satisfiable =stable _ ∘ accDescent⁺∧acc⇒unsatisfiable noSmallestnoSmallestCounterExample∧wf⇒universal : WellFounded _<_ → Universal PnoSmallestCounterExample∧wf⇒universal wf =stable _ ∘ accDescent⁺∧wf⇒empty noSmallest wf
-------------------------------------------------------------------------- The Agda standard library---- IO------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO whereopen import Codata.Musical.Notationopen import Codata.Musical.Costringopen import Data.Unit.Polymorphic.Baseopen import Data.String.Base using (String)import Data.Unit.Base as Unit0open import Function.Base using (_∘_; flip)import IO.Primitive.Core as Primopen import Levelprivatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Re-exporting the basic type and functionsopen import IO.Base publicopen import IO.Handle public-------------------------------------------------------------------------- Utilitiesmodule Colist whereopen import Codata.Musical.Colist.Basesequence : Colist (IO A) → IO (Colist A)sequence [] = pure []sequence (c ∷ cs) = bind (♯ c) λ x → ♯bind (♯ sequence (♭ cs)) λ xs → ♯pure (x ∷ ♯ xs)-- The reason for not defining sequence′ in terms of sequence is-- efficiency (the unused results could cause unnecessary memory use).sequence′ : Colist (IO A) → IO ⊤sequence′ [] = pure _sequence′ (c ∷ cs) = seq (♯ c) (♯ sequence′ (♭ cs))mapM : (A → IO B) → Colist A → IO (Colist B)mapM f = sequence ∘ map fmapM′ : (A → IO B) → Colist A → IO ⊤mapM′ f = sequence′ ∘ map fforM : Colist A → (A → IO B) → IO (Colist B)forM = flip mapMforM′ : Colist A → (A → IO B) → IO ⊤forM′ = flip mapM′module List whereopen import Data.List.Basesequence : List (IO A) → IO (List A)sequence [] = ⦇ [] ⦈sequence (c ∷ cs) = ⦇ c ∷ sequence cs ⦈-- The reason for not defining sequence′ in terms of sequence is-- efficiency (the unused results could cause unnecessary memory use).sequence′ : List (IO A) → IO ⊤sequence′ [] = pure _sequence′ (c ∷ cs) = c >> sequence′ csmapM : (A → IO B) → List A → IO (List B)mapM f = sequence ∘ map fmapM′ : (A → IO B) → List A → IO ⊤mapM′ f = sequence′ ∘ map fforM : List A → (A → IO B) → IO (List B)forM = flip mapMforM′ : List A → (A → IO B) → IO ⊤forM′ = flip mapM′-------------------------------------------------------------------------- Simple lazy IO-- Note that the functions below produce commands which, when-- executed, may raise exceptions.-- Note also that the semantics of these functions depends on the-- version of the Haskell base library. If the version is 4.2.0.0 (or-- later?), then the functions use the character encoding specified by-- the locale. For older versions of the library (going back to at-- least version 3) the functions use ISO-8859-1.open import IO.Finite publicrenaming (readFile to readFiniteFile)open import IO.Infinite publicrenaming ( writeFile to writeFile∞; appendFile to appendFile∞; putStr to putStr∞; putStrLn to putStrLn∞)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use IO.Primitive.Core instead------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module IO.Primitive whereopen import IO.Primitive.Core public{-# WARNING_ON_IMPORT"IO.Primitive was deprecated in v2.1. Use IO.Primitive.Core instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Primitive IO: simple bindings to Haskell types and functions-- manipulating potentially infinite objects------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Primitive.Infinite where-- NOTE: the contents of this module should be accessed via `IO` or-- `IO.Infinite`.open import Codata.Musical.Costringopen import Agda.Builtin.Stringopen import Agda.Builtin.Unit renaming (⊤ to Unit)-------------------------------------------------------------------------- The IO monadopen import Agda.Builtin.IO public using (IO)-------------------------------------------------------------------------- Simple lazy IO-- Note that the functions below produce commands which, when-- executed, may raise exceptions.-- Note also that the semantics of these functions depends on the-- version of the Haskell base library. If the version is 4.2.0.0 (or-- later?), then the functions use the character encoding specified by-- the locale. For older versions of the library (going back to at-- least version 3) the functions use ISO-8859-1.postulategetContents : IO CostringreadFile : String → IO CostringwriteFile : String → Costring → IO UnitappendFile : String → Costring → IO UnitputStr : Costring → IO UnitputStrLn : Costring → IO Unit{-# FOREIGN GHC import qualified Data.Text #-}{-# FOREIGN GHCfromColist :: MAlonzo.Code.Codata.Musical.Colist.Base.AgdaColist a -> [a]fromColist MAlonzo.Code.Codata.Musical.Colist.Base.Nil = []fromColist (MAlonzo.Code.Codata.Musical.Colist.Base.Cons x xs) =x : fromColist (MAlonzo.RTE.flat xs)toColist :: [a] -> MAlonzo.Code.Codata.Musical.Colist.Base.AgdaColist atoColist [] = MAlonzo.Code.Codata.Musical.Colist.Base.NiltoColist (x : xs) =MAlonzo.Code.Codata.Musical.Colist.Base.Cons x (MAlonzo.RTE.Sharp (toColist xs))#-}{-# COMPILE GHC getContents = fmap toColist getContents #-}{-# COMPILE GHC readFile = fmap toColist . readFile . Data.Text.unpack #-}{-# COMPILE GHC writeFile = \x -> writeFile (Data.Text.unpack x) . fromColist #-}{-# COMPILE GHC appendFile = \x -> appendFile (Data.Text.unpack x) . fromColist #-}{-# COMPILE GHC putStr = putStr . fromColist #-}{-# COMPILE GHC putStrLn = putStrLn . fromColist #-}{-# COMPILE UHC getContents = UHC.Agda.Builtins.primGetContents #-}{-# COMPILE UHC readFile = UHC.Agda.Builtins.primReadFile #-}{-# COMPILE UHC writeFile = UHC.Agda.Builtins.primWriteFile #-}{-# COMPILE UHC appendFile = UHC.Agda.Builtins.primAppendFile #-}{-# COMPILE UHC putStr = UHC.Agda.Builtins.primPutStr #-}{-# COMPILE UHC putStrLn = UHC.Agda.Builtins.primPutStrLn #-}
-------------------------------------------------------------------------- The Agda standard library---- Primitive IO handles: simple bindings to Haskell types and functions-------------------------------------------------------------------------- NOTE: the contents of this module should be accessed via `IO`.{-# OPTIONS --cubical-compatible #-}module IO.Primitive.Handle whereopen import Data.Maybe.Base using (Maybe)open import Data.Nat.Base using (ℕ)data BufferMode : Set wherenoBuffering lineBuffering : BufferModeblockBuffering : Maybe ℕ → BufferMode{-# FOREIGN GHC import System.IO #-}{-# FOREIGN GHCdata AgdaBufferMode= AgdaNoBuffering| AgdaLineBuffering| AgdaBlockBuffering (Maybe Integer)toBufferMode :: AgdaBufferMode -> BufferModetoBufferMode x = case x ofAgdaNoBuffering -> NoBufferingAgdaLineBuffering -> LineBufferingAgdaBlockBuffering mi -> BlockBuffering (fromIntegral <$> mi)fromBufferMode :: BufferMode -> AgdaBufferModefromBufferMode x = case x ofNoBuffering -> AgdaNoBufferingLineBuffering -> AgdaLineBufferingBlockBuffering mi -> AgdaBlockBuffering (fromIntegral <$> mi)#-}{-# COMPILE GHC BufferMode = data AgdaBufferMode( AgdaNoBuffering| AgdaLineBuffering| AgdaBlockBuffering)#-}open import Data.Unit.Base using (⊤)open import IO.Primitive.Core using (IO)postulateHandle : Setstdin stdout stderr : HandlehSetBuffering : Handle → BufferMode → IO ⊤hGetBuffering : Handle → IO BufferModehFlush : Handle → IO ⊤{-# FOREIGN GHC import System.IO #-}{-# COMPILE GHC Handle = type Handle #-}{-# COMPILE GHC stdin = stdin #-}{-# COMPILE GHC stdout = stdout #-}{-# COMPILE GHC stderr = stderr #-}{-# COMPILE GHC hSetBuffering = \ h -> hSetBuffering h . toBufferMode #-}{-# COMPILE GHC hGetBuffering = fmap fromBufferMode . hGetBuffering #-}{-# COMPILE GHC hFlush = hFlush #-}
-------------------------------------------------------------------------- The Agda standard library---- Primitive IO: simple bindings to Haskell types and functions-- Everything is assumed to be finite------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module IO.Primitive.Finite where-- NOTE: the contents of this module should be accessed via `IO` or-- `IO.Finite`.open import Agda.Builtin.IOopen import Agda.Builtin.Stringopen import Agda.Builtin.Unit using () renaming (⊤ to Unit)-------------------------------------------------------------------------- Simple lazy IO-- Note that the functions below produce commands which, when-- executed, may raise exceptions.-- Note also that the semantics of these functions depends on the-- version of the Haskell base library. If the version is 4.2.0.0 (or-- later?), then the functions use the character encoding specified by-- the locale. For older versions of the library (going back to at-- least version 3) the functions use ISO-8859-1.postulategetLine : IO StringreadFile : String → IO StringwriteFile : String → String → IO UnitappendFile : String → String → IO UnitputStr : String → IO UnitputStrLn : String → IO Unit{-# FOREIGN GHC import qualified Data.Text as T #-}{-# FOREIGN GHC import qualified Data.Text.IO as TIO #-}{-# FOREIGN GHC import qualified System.IO #-}{-# FOREIGN GHC import qualified Control.Exception #-}{-# FOREIGN GHC-- Reads a finite file. Raises an exception if the file path refers-- to a non-physical file (like "/dev/zero").readFiniteFile :: T.Text -> IO T.TextreadFiniteFile f = doh <- System.IO.openFile (T.unpack f) System.IO.ReadModeControl.Exception.bracketOnError (return ()) (\_ -> System.IO.hClose h)(\_ -> System.IO.hFileSize h)TIO.hGetContents h#-}{-# COMPILE GHC getLine = TIO.getLine #-}{-# COMPILE GHC readFile = readFiniteFile #-}{-# COMPILE GHC writeFile = TIO.writeFile . T.unpack #-}{-# COMPILE GHC appendFile = TIO.appendFile . T.unpack #-}{-# COMPILE GHC putStr = TIO.putStr #-}{-# COMPILE GHC putStrLn = TIO.putStrLn #-}{-# COMPILE UHC readFile = UHC.Agda.Builtins.primReadFiniteFile #-}
-------------------------------------------------------------------------- The Agda standard library---- Primitive IO: simple bindings to Haskell types and functions-------------------------------------------------------------------------- NOTE: the contents of this module should be accessed via `IO`.{-# OPTIONS --cubical-compatible #-}module IO.Primitive.Core whereopen import Level using (Level)privatevariablea : LevelA B : Set a-------------------------------------------------------------------------- The IO monadopen import Agda.Builtin.IO publicusing (IO)infixl 1 _>>=_postulatepure : A → IO A_>>=_ : IO A → (A → IO B) → IO B{-# COMPILE GHC pure = \_ _ -> return #-}{-# COMPILE GHC _>>=_ = \_ _ _ _ -> (>>=) #-}{-# COMPILE UHC pure = \_ _ x -> UHC.Agda.Builtins.primReturn x #-}{-# COMPILE UHC _>>=_ = \_ _ _ _ x y -> UHC.Agda.Builtins.primBind x y #-}-- Haskell-style alternative syntaxreturn : A → IO Areturn = pure_>>_ : IO A → IO B → IO Ba >> b = a >>= λ _ → b
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for IO------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Instances whereopen import IO.Baseopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import IO.EffectfulinstanceioFunctor = functorioApplicative = applicativeioMonad = monad
-------------------------------------------------------------------------- The Agda standard library---- IO only involving infinite objects------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Infinite whereopen import Codata.Musical.Costringopen import Agda.Builtin.Stringopen import Data.Unit.Polymorphic.Baseimport Data.Unit.Base as Unit0open import IO.Baseimport IO.Primitive.Core as Primimport IO.Primitive.Infinite as Primopen import Levelprivatevariablea : Level-------------------------------------------------------------------------- Simple lazy IO-- Note that the functions below produce commands which, when-- executed, may raise exceptions.-- Note also that the semantics of these functions depends on the-- version of the Haskell base library. If the version is 4.2.0.0 (or-- later?), then the functions use the character encoding specified by-- the locale. For older versions of the library (going back to at-- least version 3) the functions use ISO-8859-1.getContents : IO CostringgetContents = lift Prim.getContentswriteFile : String → Costring → IO {a} ⊤writeFile f s = lift′ (Prim.writeFile f s)appendFile : String → Costring → IO {a} ⊤appendFile f s = lift′ (Prim.appendFile f s)putStr : Costring → IO {a} ⊤putStr s = lift′ (Prim.putStr s)putStrLn : Costring → IO {a} ⊤putStrLn s = lift′ (Prim.putStrLn s)
-------------------------------------------------------------------------- The Agda standard library---- IO handles: simple bindings to Haskell types and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Handle whereopen import Level using (Level)open import Data.Unit.Polymorphic.Base using (⊤)open import IO.Base using (IO; lift; lift′)private variable a : Level-------------------------------------------------------------------------- Re-exporting types and constructorsopen import IO.Primitive.Handle as Prim publicusing ( BufferMode; noBuffering; lineBuffering; blockBuffering; Handle; stdin; stdout; stderr)-------------------------------------------------------------------------- Wrapping functionshSetBuffering : Handle → BufferMode → IO {a} ⊤hSetBuffering hdl bm = lift′ (Prim.hSetBuffering hdl bm)hGetBuffering : Handle → IO BufferModehGetBuffering hdl = lift (Prim.hGetBuffering hdl)hFlush : Handle → IO {a} ⊤hFlush hdl = lift′ (Prim.hFlush hdl)
-------------------------------------------------------------------------- The Agda standard library---- IO only involving finite objects------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Finite whereopen import Data.Unit.Polymorphic.Baseopen import Agda.Builtin.Stringimport Data.Unit.Base as Unit0open import IO.Baseimport IO.Primitive.Core as Primimport IO.Primitive.Finite as Primopen import Levelprivatevariablea : Level-------------------------------------------------------------------------- Simple lazy IO-- Note that the functions below produce commands which, when-- executed, may raise exceptions.-- Note also that the semantics of these functions depends on the-- version of the Haskell base library. If the version is 4.2.0.0 (or-- later?), then the functions use the character encoding specified by-- the locale. For older versions of the library (going back to at-- least version 3) the functions use ISO-8859-1.getLine : IO StringgetLine = lift Prim.getLine-- Reads a finite file. Raises an exception if the file path refers to-- a non-physical file (like "/dev/zero").readFile : String → IO StringreadFile f = lift (Prim.readFile f)writeFile : String → String → IO {a} ⊤writeFile f s = lift′ (Prim.writeFile f s)appendFile : String → String → IO {a} ⊤appendFile f s = lift′ (Prim.appendFile f s)putStr : String → IO {a} ⊤putStr s = lift′ (Prim.putStr s)putStrLn : String → IO {a} ⊤putStrLn s = lift′ (Prim.putStrLn s)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of IO------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Effectful whereopen import Levelopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import IO.Baseprivatevariablef : Level-------------------------------------------------------------------------- Structurefunctor : RawFunctor {f} IOfunctor = record { _<$>_ = _<$>_ }applicative : RawApplicative {f} IOapplicative = record{ rawFunctor = functor; pure = pure; _<*>_ = _<*>_}monad : RawMonad {f} IOmonad = record{ rawApplicative = applicative; _>>=_ = _>>=_}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `IO.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Categorical whereopen import IO.Effectful public{-# WARNING_ON_IMPORT"IO.Categorical was deprecated in v2.0.Use IO.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- IO: basic types and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module IO.Base whereopen import Levelopen import Codata.Musical.Notationopen import Data.Bool.Base using (Bool; true; false; not)open import Agda.Builtin.Maybe using (Maybe; nothing; just)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)import Agda.Builtin.Unit as Unit0open import Data.Unit.Polymorphic.Baseopen import Function.Base using (_∘′_; const; flip)import IO.Primitive.Core as Primprivatevariablea b e : LevelA : Set aB : Set bE : Set e-------------------------------------------------------------------------- The IO monad-- One cannot write "infinitely large" computations with the-- postulated IO monad in IO.Primitive without turning off the-- termination checker (or going via the FFI, or perhaps abusing-- something else). The following coinductive deep embedding is-- introduced to avoid this problem. Possible non-termination is-- isolated to the run function below.data IO (A : Set a) : Set (suc a) wherelift : (m : Prim.IO A) → IO Apure : (x : A) → IO Abind : {B : Set a} (m : ∞ (IO B)) (f : (x : B) → ∞ (IO A)) → IO Aseq : {B : Set a} (m₁ : ∞ (IO B)) (m₂ : ∞ (IO A)) → IO Alift! : IO A → IO (Lift b A)lift! (lift io) = lift (io Prim.>>= λ a → Prim.pure (Level.lift a))lift! (pure a) = pure (Level.lift a)lift! {b = b} (bind m f) = bind (♯ lift! {b = b} (♭ m))(λ x → ♯ lift! (♭ (f (lower x))))lift! {b = b} (seq m₁ m₂) = seq (♯ lift! {b = b} (♭ m₁))(♯ lift! (♭ m₂))module _ {A B : Set a} whereinfixl 1 _<$>_ _<*>_ _>>=_ _>>_infixr 1 _=<<__<*>_ : IO (A → B) → IO A → IO Bmf <*> mx = bind (♯ mf) λ f → ♯ (bind (♯ mx) λ x → ♯ pure (f x))_<$>_ : (A → B) → IO A → IO Bf <$> m = pure f <*> m_<$_ : B → IO A → IO Bb <$ m = (const b) <$> m_>>=_ : IO A → (A → IO B) → IO Bm >>= f = bind (♯ m) λ x → ♯ f x_=<<_ : (A → IO B) → IO A → IO B_=<<_ = flip _>>=__>>_ : IO A → IO B → IO Bm₁ >> m₂ = seq (♯ m₁) (♯ m₂)_<<_ : IO B → IO A → IO B_<<_ = flip _>>_-------------------------------------------------------------------------- Running programs-- A value of type `IO A` is a description of a computation that may-- eventually produce an `A`. The `run` function converts this-- description of a computation into calls to primitive functions that-- will actually perform it.{-# NON_TERMINATING #-}run : IO A → Prim.IO Arun (lift m) = mrun (pure x) = Prim.pure xrun (bind m f) = run (♭ m ) Prim.>>= λ x → run (♭ (f x))run (seq m₁ m₂) = run (♭ m₁) Prim.>>= λ _ → run (♭ m₂)-- The entrypoint of an Agda program will be assigned type `Main` and-- implemented using `run` on some `IO ⊤` program.Main : SetMain = Prim.IO {0ℓ} ⊤-------------------------------------------------------------------------- Utilities-- Make a unit-returning primitive level polymorphiclift′ : Prim.IO Unit0.⊤ → IO {a} ⊤lift′ io = lift (io Prim.>>= λ _ → Prim.pure _)-- Throw away the resultignore : IO A → IO ⊤ignore io = io >> pure _-------------------------------------------------------------------------- Conditional executions-- Only run the action if the boolean is truewhen : Bool → IO {a} ⊤ → IO ⊤when true m = mwhen false _ = pure _-- Only run the action if the boolean is falseunless : Bool → IO {a} ⊤ → IO ⊤unless = when ∘′ not-- Run the action if the `Maybe` computation was successfulwhenJust : Maybe A → (A → IO {a} ⊤) → IO ⊤whenJust (just a) k = k awhenJust nothing _ = pure _-- Run the action if the `E ⊎_` computation was successfulwhenInj₂ : E ⊎ A → (A → IO {a} ⊤) → IO ⊤whenInj₂ (inj₂ a) k = k awhenInj₂ (inj₁ _) _ = pure _-------------------------------------------------------------------------- Loops-- Keep running the action foreverforever : IO {a} ⊤ → IO {a} ⊤forever act = seq (♯ act) (♯ forever act)-- Keep running an IO action until we get a value. Convenient when user-- input is involved and it may be malformed.untilJust : IO (Maybe A) → IO A-- Note that here we are forced to use `bind` & the musical notation-- explicitly to guarantee that the corecursive call is guardeduntilJust m = bind (♯ m) λ wherenothing → ♯ untilJust m(just a) → ♯ pure auntilInj₂ : {A B : Set a} → (A → IO (A ⊎ B)) → A → IO BuntilInj₂ f x = bind (♯ f x) λ where(inj₁ x′) → ♯ untilInj₂ f x′(inj₂ y) → ♯ pure y-------------------------------------------------------------------------- DEPRECATIONSuntilRight = untilInj₂{-# WARNING_ON_USAGE untilRight"Warning: untilRight was deprecated in v2.1.Please use untilInj₂ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function whereopen import Function.Core publicopen import Function.Base publicopen import Function.Strict publicopen import Function.Definitions publicopen import Function.Structures publicopen import Function.Structures.Biased publicopen import Function.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Surjection where{-# WARNING_ON_IMPORT"Function.Surjection was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Levelopen import Function.Equality as Fusing (_⟶_) renaming (_∘_ to _⟪∘⟫_)open import Function.Equivalence using (Equivalence)open import Function.Injection hiding (id; _∘_; injection)open import Function.LeftInverse as Left hiding (id; _∘_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality as ≡ using (_≡_)-------------------------------------------------------------------------- Surjective functions.record Surjective {f₁ f₂ t₁ t₂}{From : Setoid f₁ f₂} {To : Setoid t₁ t₂}(to : From ⟶ To) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldfrom : To ⟶ Fromright-inverse-of : from RightInverseOf to{-# WARNING_ON_USAGE Surjective"Warning: Surjective was deprecated in v2.0.Please use Function.(Definitions.)Surjective instead."#-}-------------------------------------------------------------------------- The set of all surjections from one setoid to another.record Surjection {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Tosurjective : Surjective toopen Surjective surjective publicright-inverse : RightInverse From Toright-inverse = record{ to = from; from = to; left-inverse-of = right-inverse-of}open LeftInverse right-inverse publicusing () renaming (to-from to from-to)injective : Injective frominjective = LeftInverse.injective right-inverseinjection : Injection To Frominjection = LeftInverse.injection right-inverseequivalence : Equivalence From Toequivalence = record{ to = to; from = from}{-# WARNING_ON_USAGE Surjection"Warning: Surjection was deprecated in v2.0.Please use Function.(Bundles.)Surjection instead."#-}-- Right inverses can be turned into surjections.fromRightInverse :∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →RightInverse From To → Surjection From TofromRightInverse r = record{ to = from; surjective = record{ from = to; right-inverse-of = left-inverse-of}} where open LeftInverse r{-# WARNING_ON_USAGE fromRightInverse"Warning: fromRightInverse was deprecated in v2.0.Please use Function.(Properties.)RightInverse.RightInverse⇒Surjection instead."#-}-------------------------------------------------------------------------- The set of all surjections from one set to another (i.e. sujections-- with propositional equality)infix 3 _↠__↠_ : ∀ {f t} → Set f → Set t → Set _From ↠ To = Surjection (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _↠_"Warning: _↠_ was deprecated in v2.0.Please use Function.(Bundles.)_↠_ instead."#-}surjection : ∀ {f t} {From : Set f} {To : Set t} →(to : From → To) (from : To → From) →(∀ x → to (from x) ≡ x) →From ↠ Tosurjection to from surjective = record{ to = F.→-to-⟶ to; surjective = record{ from = F.→-to-⟶ from; right-inverse-of = surjective}}{-# WARNING_ON_USAGE surjection"Warning: surjection was deprecated in v2.0.Please use Function.(Bundles.)mk↠ instead."#-}-------------------------------------------------------------------------- Identity and composition.id : ∀ {s₁ s₂} {S : Setoid s₁ s₂} → Surjection S Sid {S = S} = record{ to = F.id; surjective = record{ from = LeftInverse.to id′; right-inverse-of = LeftInverse.left-inverse-of id′}} where id′ = Left.id {S = S}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use Function.Properties.Surjection.refl orFunction.Construct.Identity.surjection instead."#-}infixr 9 _∘__∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂}{F : Setoid f₁ f₂} {M : Setoid m₁ m₂} {T : Setoid t₁ t₂} →Surjection M T → Surjection F M → Surjection F Tf ∘ g = record{ to = to f ⟪∘⟫ to g; surjective = record{ from = LeftInverse.to g∘f; right-inverse-of = LeftInverse.left-inverse-of g∘f}}whereopen Surjectiong∘f = Left._∘_ (right-inverse g) (right-inverse f){-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use Function.Properties.Surjection.trans orFunction.Construct.Composition.surjection instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Structures for types of functions-------------------------------------------------------------------------- The contents of this file should usually be accessed from `Function`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Function.Structures {a b ℓ₁ ℓ₂}{A : Set a} (_≈₁_ : Rel A ℓ₁) -- Equality over the domain{B : Set b} (_≈₂_ : Rel B ℓ₂) -- Equality over the codomainwhereopen import Data.Product.Base as Product using (∃; _×_; _,_)open import Function.Baseopen import Function.Definitionsopen import Level using (_⊔_)-------------------------------------------------------------------------- One element structures------------------------------------------------------------------------record IsCongruent (to : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldcong : Congruent _≈₁_ _≈₂_ toisEquivalence₁ : IsEquivalence _≈₁_isEquivalence₂ : IsEquivalence _≈₂_module Eq₁ wheresetoid : Setoid a ℓ₁setoid = record{ isEquivalence = isEquivalence₁}open Setoid setoid publicmodule Eq₂ wheresetoid : Setoid b ℓ₂setoid = record{ isEquivalence = isEquivalence₂}open Setoid setoid publicrecord IsInjection (to : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent toinjective : Injective _≈₁_ _≈₂_ toopen IsCongruent isCongruent publicrecord IsSurjection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent fsurjective : Surjective _≈₁_ _≈₂_ fopen IsCongruent isCongruent publicstrictlySurjective : StrictlySurjective _≈₂_ fstrictlySurjective x = Product.map₂ (λ v → v Eq₁.refl) (surjective x)record IsBijection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisInjection : IsInjection fsurjective : Surjective _≈₁_ _≈₂_ fopen IsInjection isInjection publicbijective : Bijective _≈₁_ _≈₂_ fbijective = injective , surjectiveisSurjection : IsSurjection fisSurjection = record{ isCongruent = isCongruent; surjective = surjective}open IsSurjection isSurjection publicusing (strictlySurjective)-------------------------------------------------------------------------- Two element structures------------------------------------------------------------------------record IsLeftInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent tofrom-cong : Congruent _≈₂_ _≈₁_ frominverseˡ : Inverseˡ _≈₁_ _≈₂_ to fromopen IsCongruent isCongruent publicrenaming (cong to to-cong)strictlyInverseˡ : StrictlyInverseˡ _≈₂_ to fromstrictlyInverseˡ x = inverseˡ Eq₁.reflisSurjection : IsSurjection toisSurjection = record{ isCongruent = isCongruent; surjective = λ y → from y , inverseˡ}record IsRightInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent tofrom-cong : Congruent _≈₂_ _≈₁_ frominverseʳ : Inverseʳ _≈₁_ _≈₂_ to fromopen IsCongruent isCongruent publicrenaming (cong to to-cong)strictlyInverseʳ : StrictlyInverseʳ _≈₁_ to fromstrictlyInverseʳ x = inverseʳ Eq₂.reflrecord IsInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLeftInverse : IsLeftInverse to frominverseʳ : Inverseʳ _≈₁_ _≈₂_ to fromopen IsLeftInverse isLeftInverse publicisRightInverse : IsRightInverse to fromisRightInverse = record{ isCongruent = isCongruent; from-cong = from-cong; inverseʳ = inverseʳ}open IsRightInverse isRightInverse publicusing (strictlyInverseʳ)inverse : Inverseᵇ _≈₁_ _≈₂_ to frominverse = inverseˡ , inverseʳ-------------------------------------------------------------------------- Three element structures------------------------------------------------------------------------record IsBiEquivalence(to : A → B) (from₁ : B → A) (from₂ : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto-isCongruent : IsCongruent tofrom₁-cong : Congruent _≈₂_ _≈₁_ from₁from₂-cong : Congruent _≈₂_ _≈₁_ from₂open IsCongruent to-isCongruent publicrenaming (cong to to-cong₁)record IsBiInverse(to : A → B) (from₁ : B → A) (from₂ : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto-isCongruent : IsCongruent tofrom₁-cong : Congruent _≈₂_ _≈₁_ from₁from₂-cong : Congruent _≈₂_ _≈₁_ from₂inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from₁inverseʳ : Inverseʳ _≈₁_ _≈₂_ to from₂open IsCongruent to-isCongruent publicrenaming (cong to to-cong)-------------------------------------------------------------------------- Other-------------------------------------------------------------------------- See the comment on `SplitSurjection` in `Function.Bundles` for an-- explanation of (split) surjections.record IsSplitSurjection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldfrom : B → AisLeftInverse : IsLeftInverse f fromopen IsLeftInverse isLeftInverse public
-------------------------------------------------------------------------- The Agda standard library---- Ways to give instances of certain structures where some fields can-- be given in terms of others.-- The contents of this file should usually be accessed from `Function`.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Function.Structures.Biased {a b ℓ₁ ℓ₂}{A : Set a} (_≈₁_ : Rel A ℓ₁) -- Equality over the domain{B : Set b} (_≈₂_ : Rel B ℓ₂) -- Equality over the codomainwhereopen import Data.Product.Base as Product using (∃; _×_; _,_)open import Function.Baseopen import Function.Definitionsopen import Function.Structures _≈₁_ _≈₂_open import Function.Consequences.Setoidopen import Level using (_⊔_)-------------------------------------------------------------------------- Surjection------------------------------------------------------------------------record IsStrictSurjection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent fstrictlySurjective : StrictlySurjective _≈₂_ fopen IsCongruent isCongruent publicisSurjection : IsSurjection fisSurjection = record{ isCongruent = isCongruent; surjective = strictlySurjective⇒surjectiveEq₁.setoid Eq₂.setoid cong strictlySurjective}open IsStrictSurjection publicusing () renaming (isSurjection to isStrictSurjection)-------------------------------------------------------------------------- Bijection------------------------------------------------------------------------record IsStrictBijection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisInjection : IsInjection fstrictlySurjective : StrictlySurjective _≈₂_ fisBijection : IsBijection fisBijection = record{ isInjection = isInjection; surjective = strictlySurjective⇒surjectiveEq₁.setoid Eq₂.setoid cong strictlySurjective} where open IsInjection isInjectionopen IsStrictBijection publicusing () renaming (isBijection to isStrictBijection)-------------------------------------------------------------------------- Left inverse------------------------------------------------------------------------record IsStrictLeftInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent tofrom-cong : Congruent _≈₂_ _≈₁_ fromstrictlyInverseˡ : StrictlyInverseˡ _≈₂_ to fromisLeftInverse : IsLeftInverse to fromisLeftInverse = record{ isCongruent = isCongruent; from-cong = from-cong; inverseˡ = strictlyInverseˡ⇒inverseˡEq₁.setoid Eq₂.setoid cong strictlyInverseˡ} where open IsCongruent isCongruentopen IsStrictLeftInverse publicusing () renaming (isLeftInverse to isStrictLeftInverse)-------------------------------------------------------------------------- Right inverse------------------------------------------------------------------------record IsStrictRightInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCongruent : IsCongruent tofrom-cong : Congruent _≈₂_ _≈₁_ fromstrictlyInverseʳ : StrictlyInverseʳ _≈₁_ to fromisRightInverse : IsRightInverse to fromisRightInverse = record{ isCongruent = isCongruent; from-cong = from-cong; inverseʳ = strictlyInverseʳ⇒inverseʳEq₁.setoid Eq₂.setoid from-cong strictlyInverseʳ} where open IsCongruent isCongruentopen IsStrictRightInverse publicusing () renaming (isRightInverse to isStrictRightInverse)-------------------------------------------------------------------------- Inverse------------------------------------------------------------------------record IsStrictInverse (to : A → B) (from : B → A) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLeftInverse : IsLeftInverse to fromstrictlyInverseʳ : StrictlyInverseʳ _≈₁_ to fromisInverse : IsInverse to fromisInverse = record{ isLeftInverse = isLeftInverse; inverseʳ = strictlyInverseʳ⇒inverseʳEq₁.setoid Eq₂.setoid from-cong strictlyInverseʳ} where open IsLeftInverse isLeftInverseopen IsStrictInverse publicusing () renaming (isInverse to isStrictInverse)
-------------------------------------------------------------------------- The Agda standard library---- Strict combinators (i.e. that use call-by-value)-------------------------------------------------------------------------- The contents of this module is also accessible via the `Function`-- module.{-# OPTIONS --cubical-compatible --safe #-}module Function.Strict whereopen import Agda.Builtin.Equality using (_≡_)open import Function.Base using (flip)open import Level using (Level)privatevariablea b : LevelA B : Set ainfixl 0 _!|>_ _!|>′_infixr -1 _$!_ _$!′_-------------------------------------------------------------------------- Dependent combinators-- These are functions whose output has a type that depends on the-- value of the input to the function.open import Agda.Builtin.Strict publicrenaming( primForce to force; primForceLemma to force-≡)-- Application_$!_ : ∀ {A : Set a} {B : A → Set b} →((x : A) → B x) → ((x : A) → B x)f $! x = force x f-- Flipped application_!|>_ : ∀ {A : Set a} {B : A → Set b} →(a : A) → (∀ a → B a) → B a_!|>_ = flip _$!_-------------------------------------------------------------------------- Non-dependent combinators-- Any of the above operations for dependent functions will also work-- for non-dependent functions but sometimes Agda has difficulty-- inferring the non-dependency. Primed (′ = \prime) versions of the-- operations are therefore provided below that sometimes have better-- inference properties.seq : A → B → Bseq a b = force a (λ _ → b)seq-≡ : (a : A) (b : B) → seq a b ≡ bseq-≡ a b = force-≡ a (λ _ → b)force′ : A → (A → B) → Bforce′ = forceforce′-≡ : (a : A) (f : A → B) → force′ a f ≡ f aforce′-≡ = force-≡-- Application_$!′_ : (A → B) → (A → B)_$!′_ = _$!_-- Flipped application_!|>′_ : A → (A → B) → B_!|>′_ = _!|>_
-------------------------------------------------------------------------- The Agda standard library---- Function Equality setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_)open import Relation.Binary.Bundles using (Setoid)module Function.Relation.Binary.Setoid.Equality {a₁ a₂ b₁ b₂ : Level}(From : Setoid a₁ a₂) (To : Setoid b₁ b₂) whereopen import Function.Bundles using (Func; _⟨$⟩_)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.Structuresusing (IsEquivalence)privatemodule To = Setoid Tomodule From = Setoid Frominfix 4 _≈__≈_ : (f g : Func From To) → Set (a₁ ⊔ b₂)f ≈ g = ∀ x → f ⟨$⟩ x To.≈ g ⟨$⟩ xrefl : Reflexive _≈_refl _ = To.reflsym : Symmetric _≈_sym f≈g x = To.sym (f≈g x)trans : Transitive _≈_trans f≈g g≈h x = To.trans (f≈g x) (g≈h x)isEquivalence : IsEquivalence _≈_isEquivalence = record -- need to η-expand else Agda gets confused{ refl = λ {f} → refl {f}; sym = λ {f} {g} → sym {f} {g}; trans = λ {f} {g} {h} → trans {f} {g} {h}}setoid : Setoid _ _setoid = record { isEquivalence = isEquivalence }-- most of the time, this infix version is nicer to useinfixr 9 _⇨__⇨_ : Setoid _ __⇨_ = setoid
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Related where{-# WARNING_ON_IMPORT"Function.Related was deprecated in v2.0.Use Function.Related.Propositional instead."#-}open import Levelopen import Function.Baseopen import Function.Equality using (_⟨$⟩_)open import Function.Equivalence as Eq using (Equivalence)open import Function.Injection as Inj using (Injection; _↣_)open import Function.Inverse as Inv using (Inverse; _↔_)open import Function.LeftInverse as LeftInv using (LeftInverse)open import Function.Surjection as Surj using (Surjection)open import Function.Consequences.Propositionalopen import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsEquivalence; IsPreorder)open import Relation.Binary.Definitions using (Reflexive; Trans; Sym)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡open import Data.Product.Base using (_,_; proj₁; proj₂; <_,_>)import Function.Related.Propositional as Rimport Function.Bundles as Bprivatevariableℓ₁ ℓ₂ : LevelA : Set ℓ₁B : Set ℓ₂-------------------------------------------------------------------------- Re-export core concepts from non-deprecated Related codeopen R public using( Kind; implication; equivalence; injection; surjection; bijection) renaming( reverseImplication to reverse-implication; reverseInjection to reverse-injection; leftInverse to left-inverse)-------------------------------------------------------------------------- Wrapper types-- Synonyms which are used to make _∼[_]_ below "constructor-headed"-- (which implies that Agda can deduce the universe code from an-- expression matching any of the right-hand sides).infix 3 _←_ _↢_record _←_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) whereconstructor lamfield app-← : B → Aopen _←_ publicrecord _↢_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) whereconstructor lamfield app-↢ : B ↣ Aopen _↢_ public-------------------------------------------------------------------------- Relatedness-- There are several kinds of "relatedness".-- The idea to include kinds other than equivalence and bijection came-- from Simon Thompson and Bengt Nordström. /NADinfix 4 _∼[_]__∼[_]_ : ∀ {ℓ₁ ℓ₂} → Set ℓ₁ → Kind → Set ℓ₂ → Set _A ∼[ implication ] B = A → BA ∼[ reverse-implication ] B = A ← BA ∼[ equivalence ] B = Equivalence (≡.setoid A) (≡.setoid B)A ∼[ injection ] B = Injection (≡.setoid A) (≡.setoid B)A ∼[ reverse-injection ] B = A ↢ BA ∼[ left-inverse ] B = LeftInverse (≡.setoid A) (≡.setoid B)A ∼[ surjection ] B = Surjection (≡.setoid A) (≡.setoid B)A ∼[ bijection ] B = Inverse (≡.setoid A) (≡.setoid B)-- A non-infix synonym.Related : Kind → ∀ {ℓ₁ ℓ₂} → Set ℓ₁ → Set ℓ₂ → Set _Related k A B = A ∼[ k ] BtoRelated : {K : Kind} → A R.∼[ K ] B → A ∼[ K ] BtoRelated {K = implication} rel = B.Func.to reltoRelated {K = reverse-implication} rel = lam (B.Func.to rel)toRelated {K = equivalence} rel = Eq.equivalence (B.Equivalence.to rel) (B.Equivalence.from rel)toRelated {K = injection} rel = Inj.injection (B.Injection.to rel) (B.Injection.injective rel)toRelated {K = reverse-injection} rel = lam (Inj.injection (B.Injection.to rel) (B.Injection.injective rel))toRelated {K = left-inverse} rel = LeftInv.leftInverse to from strictlyInverseʳ where open B.RightInverse reltoRelated {K = surjection} rel = Surj.surjection to (proj₁ ∘ strictlySurjective) (proj₂ ∘ strictlySurjective)where open B.Surjection reltoRelated {K = bijection} rel =Inv.inverse to from strictlyInverseʳ strictlyInverseˡwhere open B.Inverse relfromRelated : {K : Kind} → A ∼[ K ] B → A R.∼[ K ] BfromRelated {K = implication} rel = B.mk⟶ relfromRelated {K = reverse-implication} rel = B.mk⟶ (app-← rel)fromRelated {K = equivalence} record { to = to ; from = from } = B.mk⇔ (to ⟨$⟩_) (from ⟨$⟩_)fromRelated {K = injection} rel = B.mk↣ (Inj.Injection.injective rel)fromRelated {K = reverse-injection} (lam app-↢) = B.mk↣ (Inj.Injection.injective app-↢)fromRelated {K = left-inverse} record { to = to ; from = from ; left-inverse-of = left-inverse-of } =B.mk↪ {to = to ⟨$⟩_} {from = from ⟨$⟩_} (strictlyInverseʳ⇒inverseʳ (to ⟨$⟩_) left-inverse-of)fromRelated {K = surjection} record { to = to ; surjective = surjective } with surjective... | record { from = from ; right-inverse-of = right-inverse-of } =B.mk↠ {to = to ⟨$⟩_} < from ⟨$⟩_ , (λ { x ≡.refl → right-inverse-of x }) >fromRelated {K = bijection} rel = B.mk↔ₛ′ (to ⟨$⟩_) (from ⟨$⟩_) right-inverse-of left-inverse-ofwhere open Inverse rel-- The bijective equality implies any kind of relatedness.↔⇒ : ∀ {k x y} {X : Set x} {Y : Set y} →X ∼[ bijection ] Y → X ∼[ k ] Y↔⇒ {implication} = _⟨$⟩_ ∘ Inverse.to↔⇒ {reverse-implication} = lam ∘′ _⟨$⟩_ ∘ Inverse.from↔⇒ {equivalence} = Inverse.equivalence↔⇒ {injection} = Inverse.injection↔⇒ {reverse-injection} = lam ∘′ Inverse.injection ∘ Inv.sym↔⇒ {left-inverse} = Inverse.left-inverse↔⇒ {surjection} = Inverse.surjection↔⇒ {bijection} = id-- Actual equality also implies any kind of relatedness.≡⇒ : ∀ {k ℓ} {X Y : Set ℓ} → X ≡ Y → X ∼[ k ] Y≡⇒ ≡.refl = ↔⇒ Inv.id-------------------------------------------------------------------------- Special kinds of kinds-- Kinds whose interpretation is symmetric.data Symmetric-kind : Set whereequivalence : Symmetric-kindbijection : Symmetric-kind-- Forgetful map.⌊_⌋ : Symmetric-kind → Kind⌊ equivalence ⌋ = equivalence⌊ bijection ⌋ = bijection-- The proof of symmetry can be found below.-- Kinds whose interpretation include a function which "goes in the-- forward direction".data Forward-kind : Set whereimplication : Forward-kindequivalence : Forward-kindinjection : Forward-kindleft-inverse : Forward-kindsurjection : Forward-kindbijection : Forward-kind-- Forgetful map.⌊_⌋→ : Forward-kind → Kind⌊ implication ⌋→ = implication⌊ equivalence ⌋→ = equivalence⌊ injection ⌋→ = injection⌊ left-inverse ⌋→ = left-inverse⌊ surjection ⌋→ = surjection⌊ bijection ⌋→ = bijection-- The function.⇒→ : ∀ {k x y} {X : Set x} {Y : Set y} → X ∼[ ⌊ k ⌋→ ] Y → X → Y⇒→ {implication} = id⇒→ {equivalence} = _⟨$⟩_ ∘ Equivalence.to⇒→ {injection} = _⟨$⟩_ ∘ Injection.to⇒→ {left-inverse} = _⟨$⟩_ ∘ LeftInverse.to⇒→ {surjection} = _⟨$⟩_ ∘ Surjection.to⇒→ {bijection} = _⟨$⟩_ ∘ Inverse.to-- Kinds whose interpretation include a function which "goes backwards".data Backward-kind : Set wherereverse-implication : Backward-kindequivalence : Backward-kindreverse-injection : Backward-kindleft-inverse : Backward-kindsurjection : Backward-kindbijection : Backward-kind-- Forgetful map.⌊_⌋← : Backward-kind → Kind⌊ reverse-implication ⌋← = reverse-implication⌊ equivalence ⌋← = equivalence⌊ reverse-injection ⌋← = reverse-injection⌊ left-inverse ⌋← = left-inverse⌊ surjection ⌋← = surjection⌊ bijection ⌋← = bijection-- The function.⇒← : ∀ {k x y} {X : Set x} {Y : Set y} → X ∼[ ⌊ k ⌋← ] Y → Y → X⇒← {reverse-implication} = app-←⇒← {equivalence} = _⟨$⟩_ ∘ Equivalence.from⇒← {reverse-injection} = _⟨$⟩_ ∘ Injection.to ∘ app-↢⇒← {left-inverse} = _⟨$⟩_ ∘ LeftInverse.from⇒← {surjection} = _⟨$⟩_ ∘ Surjection.from⇒← {bijection} = _⟨$⟩_ ∘ Inverse.from-- Kinds whose interpretation include functions going in both-- directions.data Equivalence-kind : Set whereequivalence : Equivalence-kindleft-inverse : Equivalence-kindsurjection : Equivalence-kindbijection : Equivalence-kind-- Forgetful map.⌊_⌋⇔ : Equivalence-kind → Kind⌊ equivalence ⌋⇔ = equivalence⌊ left-inverse ⌋⇔ = left-inverse⌊ surjection ⌋⇔ = surjection⌊ bijection ⌋⇔ = bijection-- The functions.⇒⇔ : ∀ {k x y} {X : Set x} {Y : Set y} →X ∼[ ⌊ k ⌋⇔ ] Y → X ∼[ equivalence ] Y⇒⇔ {equivalence} = id⇒⇔ {left-inverse} = LeftInverse.equivalence⇒⇔ {surjection} = Surjection.equivalence⇒⇔ {bijection} = Inverse.equivalence-- Conversions between special kinds.⇔⌊_⌋ : Symmetric-kind → Equivalence-kind⇔⌊ equivalence ⌋ = equivalence⇔⌊ bijection ⌋ = bijection→⌊_⌋ : Equivalence-kind → Forward-kind→⌊ equivalence ⌋ = equivalence→⌊ left-inverse ⌋ = left-inverse→⌊ surjection ⌋ = surjection→⌊ bijection ⌋ = bijection←⌊_⌋ : Equivalence-kind → Backward-kind←⌊ equivalence ⌋ = equivalence←⌊ left-inverse ⌋ = left-inverse←⌊ surjection ⌋ = surjection←⌊ bijection ⌋ = bijection-------------------------------------------------------------------------- Opposites-- For every kind there is an opposite kind._op : Kind → Kindimplication op = reverse-implicationreverse-implication op = implicationequivalence op = equivalenceinjection op = reverse-injectionreverse-injection op = injectionleft-inverse op = surjectionsurjection op = left-inversebijection op = bijection-- For every morphism there is a corresponding reverse morphism of the-- opposite kind.reverse : ∀ {k a b} {A : Set a} {B : Set b} →A ∼[ k ] B → B ∼[ k op ] Areverse {implication} = lamreverse {reverse-implication} = app-←reverse {equivalence} = Eq.symreverse {injection} = lamreverse {reverse-injection} = app-↢reverse {left-inverse} = Surj.fromRightInversereverse {surjection} = Surjection.right-inversereverse {bijection} = Inv.sym-------------------------------------------------------------------------- For a fixed universe level every kind is a preorder and each-- symmetric kind is an equivalenceK-refl : ∀ {k ℓ} → Reflexive (Related k {ℓ})K-refl {implication} = idK-refl {reverse-implication} = lam idK-refl {equivalence} = Eq.idK-refl {injection} = Inj.idK-refl {reverse-injection} = lam Inj.idK-refl {left-inverse} = LeftInv.idK-refl {surjection} = Surj.idK-refl {bijection} = Inv.idK-reflexive : ∀ {k ℓ} → _≡_ ⇒ Related k {ℓ}K-reflexive ≡.refl = K-reflK-trans : ∀ {k ℓ₁ ℓ₂ ℓ₃} → Trans (Related k {ℓ₁} {ℓ₂})(Related k {ℓ₂} {ℓ₃})(Related k {ℓ₁} {ℓ₃})K-trans {implication} = flip _∘′_K-trans {reverse-implication} = λ f g → lam (app-← f ∘ app-← g)K-trans {equivalence} = flip Eq._∘_K-trans {injection} = flip Inj._∘_K-trans {reverse-injection} = λ f g → lam (Inj._∘_ (app-↢ f) (app-↢ g))K-trans {left-inverse} = flip LeftInv._∘_K-trans {surjection} = flip Surj._∘_K-trans {bijection} = flip Inv._∘_SK-sym : ∀ {k ℓ₁ ℓ₂} → Sym (Related ⌊ k ⌋ {ℓ₁} {ℓ₂})(Related ⌊ k ⌋ {ℓ₂} {ℓ₁})SK-sym {equivalence} = Eq.symSK-sym {bijection} = Inv.symSK-isEquivalence : ∀ k ℓ → IsEquivalence {ℓ = ℓ} (Related ⌊ k ⌋)SK-isEquivalence k ℓ = record{ refl = K-refl; sym = SK-sym; trans = K-trans}SK-setoid : Symmetric-kind → (ℓ : Level) → Setoid _ _SK-setoid k ℓ = record { isEquivalence = SK-isEquivalence k ℓ }K-isPreorder : ∀ k ℓ → IsPreorder _↔_ (Related k)K-isPreorder k ℓ = record{ isEquivalence = SK-isEquivalence bijection ℓ; reflexive = ↔⇒; trans = K-trans}K-preorder : Kind → (ℓ : Level) → Preorder _ _ _K-preorder k ℓ = record { isPreorder = K-isPreorder k ℓ }-------------------------------------------------------------------------- Equational reasoning-- Equational reasoning for related things.module EquationalReasoning whereinfix 3 _∎infixr 2 _∼⟨_⟩_ _↔⟨_⟩_ _↔⟨⟩_ _≡⟨_⟩_ _≡˘⟨_⟩_infix 1 begin_begin_ : ∀ {k x y} {X : Set x} {Y : Set y} →X ∼[ k ] Y → X ∼[ k ] Ybegin_ x∼y = x∼y_∼⟨_⟩_ : ∀ {k x y z} (X : Set x) {Y : Set y} {Z : Set z} →X ∼[ k ] Y → Y ∼[ k ] Z → X ∼[ k ] Z_ ∼⟨ X↝Y ⟩ Y↝Z = K-trans X↝Y Y↝Z-- Isomorphisms can be combined with any other kind of relatedness._↔⟨_⟩_ : ∀ {k x y z} (X : Set x) {Y : Set y} {Z : Set z} →X ↔ Y → Y ∼[ k ] Z → X ∼[ k ] ZX ↔⟨ X↔Y ⟩ Y⇔Z = X ∼⟨ ↔⇒ X↔Y ⟩ Y⇔Z_↔⟨⟩_ : ∀ {k x y} (X : Set x) {Y : Set y} →X ∼[ k ] Y → X ∼[ k ] YX ↔⟨⟩ X⇔Y = X⇔Y_≡˘⟨_⟩_ : ∀ {k ℓ z} (X : Set ℓ) {Y : Set ℓ} {Z : Set z} →Y ≡ X → Y ∼[ k ] Z → X ∼[ k ] ZX ≡˘⟨ Y≡X ⟩ Y⇔Z = X ∼⟨ ≡⇒ (≡.sym Y≡X) ⟩ Y⇔Z_≡⟨_⟩_ : ∀ {k ℓ z} (X : Set ℓ) {Y : Set ℓ} {Z : Set z} →X ≡ Y → Y ∼[ k ] Z → X ∼[ k ] ZX ≡⟨ X≡Y ⟩ Y⇔Z = X ∼⟨ ≡⇒ X≡Y ⟩ Y⇔Z_∎ : ∀ {k x} (X : Set x) → X ∼[ k ] XX ∎ = K-refl-------------------------------------------------------------------------- Every unary relation induces a preorder and, for symmetric kinds,-- an equivalence. (No claim is made that these relations are unique.)InducedRelation₁ : Kind → ∀ {a s} {A : Set a} →(A → Set s) → A → A → Set _InducedRelation₁ k S = λ x y → S x ∼[ k ] S yInducedPreorder₁ : Kind → ∀ {a s} {A : Set a} →(A → Set s) → Preorder _ _ _InducedPreorder₁ k S = record{ _≈_ = _≡_; _≲_ = InducedRelation₁ k S; isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = reflexive ∘K-reflexive ∘≡.cong S; trans = K-trans}} where open Preorder (K-preorder _ _)InducedEquivalence₁ : Symmetric-kind → ∀ {a s} {A : Set a} →(A → Set s) → Setoid _ _InducedEquivalence₁ k S = record{ _≈_ = InducedRelation₁ ⌊ k ⌋ S; isEquivalence = record{ refl = K-refl; sym = SK-sym; trans = K-trans}}-------------------------------------------------------------------------- Every binary relation induces a preorder and, for symmetric kinds,-- an equivalence. (No claim is made that these relations are unique.)InducedRelation₂ : Kind → ∀ {a b s} {A : Set a} {B : Set b} →(A → B → Set s) → B → B → Set _InducedRelation₂ k _S_ = λ x y → ∀ {z} → (z S x) ∼[ k ] (z S y)InducedPreorder₂ : Kind → ∀ {a b s} {A : Set a} {B : Set b} →(A → B → Set s) → Preorder _ _ _InducedPreorder₂ k _S_ = record{ _≈_ = _≡_; _≲_ = InducedRelation₂ k _S_; isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = λ x≡y {z} →reflexive $K-reflexive $≡.cong (_S_ z) x≡y; trans = λ i↝j j↝k → K-trans i↝j j↝k}} where open Preorder (K-preorder _ _)InducedEquivalence₂ : Symmetric-kind →∀ {a b s} {A : Set a} {B : Set b} →(A → B → Set s) → Setoid _ _InducedEquivalence₂ k _S_ = record{ _≈_ = InducedRelation₂ ⌊ k ⌋ _S_; isEquivalence = record{ refl = refl; sym = λ i↝j → sym i↝j; trans = λ i↝j j↝k → trans i↝j j↝k}} where open Setoid (SK-setoid _ _)
-------------------------------------------------------------------------- The Agda standard library---- Basic lemmas showing that various types are related (isomorphic or-- equivalent or…)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Related.TypeIsomorphisms whereopen import Algebraopen import Algebra.Structures.Biased using (isCommutativeSemiringˡ)open import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Bool.Base using (true; false)open import Data.Empty.Polymorphic using (⊥; ⊥-elim)open import Data.Product.Base as Productusing (_×_; Σ; curry; uncurry; _,_; -,_; <_,_>; proj₁; proj₂; ∃₂; ∃)open import Data.Product.Function.NonDependent.Propositionalopen import Data.Sum.Base as Sumopen import Data.Sum.Properties using (swap-involutive)open import Data.Sum.Function.Propositional using (_⊎-cong_)open import Data.Unit.Polymorphic.Base using (⊤)open import Level using (Level; Lift; 0ℓ; suc)open import Function.Baseopen import Function.Bundlesopen import Function.Related.Propositionalimport Function.Construct.Identity as Identityopen import Relation.Binary hiding (_⇔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Nullary.Reflects using (invert)open import Relation.Nullary using (Dec; ¬_; _because_; ofⁿ; contradiction)import Relation.Nullary.Indexed as Iopen import Relation.Nullary.Decidable using (True)privatevariablea b c d : LevelA B C D : Set a-------------------------------------------------------------------------- Properties of Σ and _×_-- Σ is associativeΣ-assoc : ∀ {A : Set a} {B : A → Set b} {C : (a : A) → B a → Set c} →Σ (Σ A B) (uncurry C) ↔ Σ A (λ a → Σ (B a) (C a))Σ-assoc = mk↔ₛ′ Product.assocʳ Product.assocˡ (λ _ → refl) (λ _ → refl)-- × is commutative×-comm : ∀ (A : Set a) (B : Set b) → (A × B) ↔ (B × A)×-comm _ _ = mk↔ₛ′ Product.swap Product.swap (λ _ → refl) λ _ → refl-- × has ⊤ as its identity×-identityˡ : ∀ ℓ → LeftIdentity {ℓ = ℓ} _↔_ ⊤ _×_×-identityˡ _ _ = mk↔ₛ′ proj₂ -,_ (λ _ → refl) (λ _ → refl)×-identityʳ : ∀ ℓ → RightIdentity {ℓ = ℓ} _↔_ ⊤ _×_×-identityʳ _ _ = mk↔ₛ′ proj₁ (_, _) (λ _ → refl) (λ _ → refl)×-identity : ∀ ℓ → Identity _↔_ ⊤ _×_×-identity ℓ = ×-identityˡ ℓ , ×-identityʳ ℓ-- × has ⊥ has its zero×-zeroˡ : ∀ ℓ → LeftZero {ℓ = ℓ} _↔_ ⊥ _×_×-zeroˡ ℓ A = mk↔ₛ′ proj₁ < id , ⊥-elim > (λ _ → refl) (λ { () })×-zeroʳ : ∀ ℓ → RightZero {ℓ = ℓ} _↔_ ⊥ _×_×-zeroʳ ℓ A = mk↔ₛ′ proj₂ < ⊥-elim , id > (λ _ → refl) (λ { () })×-zero : ∀ ℓ → Zero _↔_ ⊥ _×_×-zero ℓ = ×-zeroˡ ℓ , ×-zeroʳ ℓ-------------------------------------------------------------------------- Properties of ⊎-- ⊎ is associative⊎-assoc : ∀ ℓ → Associative {ℓ = ℓ} _↔_ _⊎_⊎-assoc ℓ _ _ _ = mk↔ₛ′[ [ inj₁ , inj₂ ∘′ inj₁ ]′ , inj₂ ∘′ inj₂ ]′[ inj₁ ∘′ inj₁ , [ inj₁ ∘′ inj₂ , inj₂ ]′ ]′[ (λ _ → refl) , [ (λ _ → refl) , (λ _ → refl) ] ][ [ (λ _ → refl) , (λ _ → refl) ] , (λ _ → refl) ]-- ⊎ is commutative⊎-comm : ∀ (A : Set a) (B : Set b) → (A ⊎ B) ↔ (B ⊎ A)⊎-comm _ _ = mk↔ₛ′ swap swap swap-involutive swap-involutive-- ⊎ has ⊥ as its identity⊎-identityˡ : ∀ ℓ → LeftIdentity _↔_ (⊥ {ℓ}) _⊎_⊎-identityˡ _ _ = mk↔ₛ′ [ (λ ()) , id ]′ inj₂ (λ _ → refl)[ (λ ()) , (λ _ → refl) ]⊎-identityʳ : ∀ ℓ → RightIdentity _↔_ (⊥ {ℓ}) _⊎_⊎-identityʳ _ _ = mk↔ₛ′ [ id , (λ ()) ]′ inj₁ (λ _ → refl)[ (λ _ → refl) , (λ ()) ]⊎-identity : ∀ ℓ → Identity _↔_ ⊥ _⊎_⊎-identity ℓ = ⊎-identityˡ ℓ , ⊎-identityʳ ℓ-------------------------------------------------------------------------- Properties of × and ⊎-- × distributes over ⊎×-distribˡ-⊎ : ∀ ℓ → _DistributesOverˡ_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distribˡ-⊎ ℓ _ _ _ = mk↔ₛ′(uncurry λ x → [ inj₁ ∘′ (x ,_) , inj₂ ∘′ (x ,_) ]′)[ Product.map₂ inj₁ , Product.map₂ inj₂ ]′[ (λ _ → refl) , (λ _ → refl) ](uncurry λ _ → [ (λ _ → refl) , (λ _ → refl) ])×-distribʳ-⊎ : ∀ ℓ → _DistributesOverʳ_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distribʳ-⊎ ℓ _ _ _ = mk↔ₛ′(uncurry [ curry inj₁ , curry inj₂ ]′)[ Product.map₁ inj₁ , Product.map₁ inj₂ ]′[ (λ _ → refl) , (λ _ → refl) ](uncurry [ (λ _ _ → refl) , (λ _ _ → refl) ])×-distrib-⊎ : ∀ ℓ → _DistributesOver_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distrib-⊎ ℓ = ×-distribˡ-⊎ ℓ , ×-distribʳ-⊎ ℓ-------------------------------------------------------------------------- ⊥, ⊤, _×_ and _⊎_ form a commutative semiring-- ⊤, _×_ form a commutative monoid×-isMagma : ∀ k ℓ → IsMagma {Level.suc ℓ} (Related ⌊ k ⌋) _×_×-isMagma k ℓ = record{ isEquivalence = SK-isEquivalence k; ∙-cong = _×-cong_}×-magma : SymmetricKind → (ℓ : Level) → Magma _ _×-magma k ℓ = record{ isMagma = ×-isMagma k ℓ}×-isSemigroup : ∀ k ℓ → IsSemigroup {Level.suc ℓ} (Related ⌊ k ⌋) _×_×-isSemigroup k ℓ = record{ isMagma = ×-isMagma k ℓ; assoc = λ _ _ _ → ↔⇒ Σ-assoc}×-semigroup : SymmetricKind → (ℓ : Level) → Semigroup _ _×-semigroup k ℓ = record{ isSemigroup = ×-isSemigroup k ℓ}×-isMonoid : ∀ k ℓ → IsMonoid (Related ⌊ k ⌋) _×_ ⊤×-isMonoid k ℓ = record{ isSemigroup = ×-isSemigroup k ℓ; identity = (↔⇒ ∘ ×-identityˡ ℓ) , (↔⇒ ∘ ×-identityʳ ℓ)}×-monoid : SymmetricKind → (ℓ : Level) → Monoid _ _×-monoid k ℓ = record{ isMonoid = ×-isMonoid k ℓ}×-isCommutativeMonoid : ∀ k ℓ → IsCommutativeMonoid (Related ⌊ k ⌋) _×_ ⊤×-isCommutativeMonoid k ℓ = record{ isMonoid = ×-isMonoid k ℓ; comm = λ _ _ → ↔⇒ (×-comm _ _)}×-commutativeMonoid : SymmetricKind → (ℓ : Level) → CommutativeMonoid _ _×-commutativeMonoid k ℓ = record{ isCommutativeMonoid = ×-isCommutativeMonoid k ℓ}-- ⊥, _⊎_ form a commutative monoid⊎-isMagma : ∀ k ℓ → IsMagma {Level.suc ℓ} (Related ⌊ k ⌋) _⊎_⊎-isMagma k ℓ = record{ isEquivalence = SK-isEquivalence k; ∙-cong = _⊎-cong_}⊎-magma : SymmetricKind → (ℓ : Level) → Magma _ _⊎-magma k ℓ = record{ isMagma = ⊎-isMagma k ℓ}⊎-isSemigroup : ∀ k ℓ → IsSemigroup {Level.suc ℓ} (Related ⌊ k ⌋) _⊎_⊎-isSemigroup k ℓ = record{ isMagma = ⊎-isMagma k ℓ; assoc = λ A B C → ↔⇒ (⊎-assoc ℓ A B C)}⊎-semigroup : SymmetricKind → (ℓ : Level) → Semigroup _ _⊎-semigroup k ℓ = record{ isSemigroup = ⊎-isSemigroup k ℓ}⊎-isMonoid : ∀ k ℓ → IsMonoid (Related ⌊ k ⌋) _⊎_ ⊥⊎-isMonoid k ℓ = record{ isSemigroup = ⊎-isSemigroup k ℓ; identity = (↔⇒ ∘ ⊎-identityˡ ℓ) , (↔⇒ ∘ ⊎-identityʳ ℓ)}⊎-monoid : SymmetricKind → (ℓ : Level) → Monoid _ _⊎-monoid k ℓ = record{ isMonoid = ⊎-isMonoid k ℓ}⊎-isCommutativeMonoid : ∀ k ℓ → IsCommutativeMonoid (Related ⌊ k ⌋) _⊎_ ⊥⊎-isCommutativeMonoid k ℓ = record{ isMonoid = ⊎-isMonoid k ℓ; comm = λ _ _ → ↔⇒ (⊎-comm _ _)}⊎-commutativeMonoid : SymmetricKind → (ℓ : Level) →CommutativeMonoid _ _⊎-commutativeMonoid k ℓ = record{ isCommutativeMonoid = ⊎-isCommutativeMonoid k ℓ}×-⊎-isCommutativeSemiring : ∀ k ℓ →IsCommutativeSemiring (Related ⌊ k ⌋) _⊎_ _×_ ⊥ ⊤×-⊎-isCommutativeSemiring k ℓ = isCommutativeSemiringˡ record{ +-isCommutativeMonoid = ⊎-isCommutativeMonoid k ℓ; *-isCommutativeMonoid = ×-isCommutativeMonoid k ℓ; distribʳ = λ A B C → ↔⇒ (×-distribʳ-⊎ ℓ A B C); zeroˡ = ↔⇒ ∘ ×-zeroˡ ℓ}×-⊎-commutativeSemiring : SymmetricKind → (ℓ : Level) →CommutativeSemiring (Level.suc ℓ) ℓ×-⊎-commutativeSemiring k ℓ = record{ isCommutativeSemiring = ×-⊎-isCommutativeSemiring k ℓ}-------------------------------------------------------------------------- Some reordering lemmasΠΠ↔ΠΠ : ∀ {a b p} {A : Set a} {B : Set b} (P : A → B → Set p) →((x : A) (y : B) → P x y) ↔ ((y : B) (x : A) → P x y)ΠΠ↔ΠΠ _ = mk↔ₛ′ flip flip (λ _ → refl) (λ _ → refl)∃∃↔∃∃ : ∀ {a b p} {A : Set a} {B : Set b} (P : A → B → Set p) →(∃₂ λ x y → P x y) ↔ (∃₂ λ y x → P x y)∃∃↔∃∃ P = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)whereto : (∃₂ λ x y → P x y) → (∃₂ λ y x → P x y)to (x , y , Pxy) = (y , x , Pxy)from : (∃₂ λ y x → P x y) → (∃₂ λ x y → P x y)from (y , x , Pxy) = (x , y , Pxy)-------------------------------------------------------------------------- Implicit and explicit function spaces are isomorphicΠ↔Π : ∀ {A : Set a} {B : A → Set b} →((x : A) → B x) ↔ ({x : A} → B x)Π↔Π = mk↔ₛ′ _$- λ- (λ _ → refl) (λ _ → refl)-------------------------------------------------------------------------- _→_ preserves the symmetric relations→-cong-⇔ : A ⇔ B → C ⇔ D → (A → C) ⇔ (B → D)→-cong-⇔ A⇔B C⇔D = mk⇔(λ f → to C⇔D ∘ f ∘ from A⇔B)(λ f → from C⇔D ∘ f ∘ to A⇔B)where open Equivalence→-cong-↔ : Extensionality a c → Extensionality b d →{A : Set a} {B : Set b} {C : Set c} {D : Set d} →A ↔ B → C ↔ D → (A → C) ↔ (B → D)→-cong-↔ ext₁ ext₂ A↔B C↔D = mk↔ₛ′(λ f → to C↔D ∘ f ∘ from A↔B)(λ f → from C↔D ∘ f ∘ to A↔B)(λ f → ext₂ λ x → beginto C↔D (from C↔D (f (to A↔B (from A↔B x)))) ≡⟨ strictlyInverseˡ C↔D _ ⟩f (to A↔B (from A↔B x)) ≡⟨ cong f $ strictlyInverseˡ A↔B x ⟩f x ∎)(λ f → ext₁ λ x → beginfrom C↔D (to C↔D (f (from A↔B (to A↔B x)))) ≡⟨ strictlyInverseʳ C↔D _ ⟩f (from A↔B (to A↔B x)) ≡⟨ cong f $ strictlyInverseʳ A↔B x ⟩f x ∎)where open Inverse; open ≡-Reasoning→-cong : Extensionality a c → Extensionality b d →∀ {k} {A : Set a} {B : Set b} {C : Set c} {D : Set d} →A ∼[ ⌊ k ⌋ ] B → C ∼[ ⌊ k ⌋ ] D → (A → C) ∼[ ⌊ k ⌋ ] (B → D)→-cong extAC extBD {equivalence} = →-cong-⇔→-cong extAC extBD {bijection} = →-cong-↔ extAC extBD-------------------------------------------------------------------------- ¬_ (at Level 0) preserves the symmetric relations¬-cong-⇔ : A ⇔ B → (¬ A) ⇔ (¬ B)¬-cong-⇔ A⇔B = →-cong-⇔ A⇔B (Identity.⇔-id _)¬-cong : Extensionality a 0ℓ → Extensionality b 0ℓ →∀ {k} {A : Set a} {B : Set b} →A ∼[ ⌊ k ⌋ ] B → (¬ A) ∼[ ⌊ k ⌋ ] (¬ B)¬-cong extA extB A≈B = →-cong extA extB A≈B (K-reflexive refl)-------------------------------------------------------------------------- _⇔_ preserves _⇔_-- The type of the following proof is a bit more general.Related-cong :∀ {k} →A ∼[ ⌊ k ⌋ ] B → C ∼[ ⌊ k ⌋ ] D → (A ∼[ ⌊ k ⌋ ] C) ⇔ (B ∼[ ⌊ k ⌋ ] D)Related-cong {A = A} {B = B} {C = C} {D = D} A≈B C≈D = mk⇔(λ A≈C → B ∼⟨ SK-sym A≈B ⟩A ∼⟨ A≈C ⟩C ∼⟨ C≈D ⟩D ∎)(λ B≈D → A ∼⟨ A≈B ⟩B ∼⟨ B≈D ⟩D ∼⟨ SK-sym C≈D ⟩C ∎)where open EquationalReasoning-------------------------------------------------------------------------- A lemma relating True dec and P, where dec : Dec PTrue↔ : ∀ {p} {P : Set p}(dec : Dec P) → ((p₁ p₂ : P) → p₁ ≡ p₂) → True dec ↔ PTrue↔ ( true because [p]) irr =mk↔ₛ′ (λ _ → invert [p]) (λ _ → _) (irr _) (λ _ → refl)True↔ (false because ofⁿ ¬p) _ =mk↔ₛ′ (λ()) (invert (ofⁿ ¬p)) (λ x → flip contradiction ¬p x) (λ ())
-------------------------------------------------------------------------- The Agda standard library---- Automatic solver for equations over product and sum types---- See examples at the bottom of the file for how to use this solver------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Related.TypeIsomorphisms.Solver whereopen import Algebra using (CommutativeSemiring)import Algebra.Solver.Ring.NaturalCoefficients.Defaultopen import Data.Empty.Polymorphic using (⊥)open import Data.Product.Base using (_×_)open import Data.Sum.Base using (_⊎_)open import Data.Unit.Polymorphic using (⊤)open import Level using (Level)open import Function.Bundles using (_↔_)open import Function.Properties.Inverse using (↔-refl)open import Function.Related.Propositional as Relatedopen import Function.Related.TypeIsomorphisms-------------------------------------------------------------------------- The solvermodule ×-⊎-Solver (k : SymmetricKind) {ℓ} =Algebra.Solver.Ring.NaturalCoefficients.Default(×-⊎-commutativeSemiring k ℓ)-------------------------------------------------------------------------- Testsprivate-- A test of the solver above.test : {ℓ : Level} (A B C : Set ℓ) →(⊤ × A × (B ⊎ C)) ↔ (A × B ⊎ C × (⊥ ⊎ A))test = solve 3 (λ A B C → con 1 :* (A :* (B :+ C)) :=A :* B :+ C :* (con 0 :+ A))↔-reflwhere open ×-⊎-Solver bijection
-------------------------------------------------------------------------- The Agda standard library---- Relatedness for the function hierarchy------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Related.Propositional whereopen import Levelopen import Relation.Binaryusing (Rel; REL; Sym; Reflexive; Trans; IsEquivalence; Setoid; IsPreorder; Preorder)open import Function.Bundlesopen import Function.Baseopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Binary.Reasoning.Syntaxopen import Function.Properties.Surjection using (↠⇒↪; ↠⇒⇔)open import Function.Properties.RightInverse using (↪⇒↠)open import Function.Properties.Bijection using (⤖⇒↔; ⤖⇒⇔)open import Function.Properties.Inverse using (↔⇒⤖; ↔⇒⇔; ↔⇒↣; ↔⇒↠)import Function.Construct.Symmetry as Symmetryimport Function.Construct.Identity as Identityimport Function.Construct.Composition as Composition-------------------------------------------------------------------------- Relatedness-- There are several kinds of "relatedness".-- The idea to include kinds other than equivalence and bijection came-- from Simon Thompson and Bengt Nordström. /NADdata Kind : Set whereimplication : KindreverseImplication : Kindequivalence : Kindinjection : KindreverseInjection : KindleftInverse : Kindsurjection : Kindbijection : Kindprivatevariablea b c p : LevelA B C : Set ak : Kind-- Interpretation of the codes above. The code "bijection" is-- interpreted as Inverse rather than Bijection; the two types are-- equivalent.infix 4 _∼[_]__∼[_]_ : Set a → Kind → Set b → Set _A ∼[ implication ] B = A ⟶ BA ∼[ reverseImplication ] B = B ⟶ AA ∼[ equivalence ] B = A ⇔ BA ∼[ injection ] B = A ↣ BA ∼[ reverseInjection ] B = B ↣ AA ∼[ leftInverse ] B = A ↪ BA ∼[ surjection ] B = A ↠ BA ∼[ bijection ] B = A ↔ B-- A non-infix synonym.Related : Kind → Set a → Set b → Set _Related k A B = A ∼[ k ] B-- The bijective equality implies any kind of relatedness.↔⇒ : A ∼[ bijection ] B → A ∼[ k ] B↔⇒ {k = implication} = mk⟶ ∘ Inverse.to↔⇒ {k = reverseImplication} = mk⟶ ∘ Inverse.from↔⇒ {k = equivalence} = ↔⇒⇔↔⇒ {k = injection} = ↔⇒↣↔⇒ {k = reverseInjection} = ↔⇒↣ ∘ Symmetry.inverse↔⇒ {k = leftInverse} = Inverse.rightInverse↔⇒ {k = surjection} = ↔⇒↠↔⇒ {k = bijection} = id-- Propositional equality also implies any kind of relatedness.≡⇒ : A ≡ B → A ∼[ k ] B≡⇒ ≡.refl = ↔⇒ (Identity.↔-id _)-------------------------------------------------------------------------- Special kinds of kinds-- Kinds whose interpretation is symmetric.data SymmetricKind : Set whereequivalence : SymmetricKindbijection : SymmetricKind-- Forgetful map.⌊_⌋ : SymmetricKind → Kind⌊ equivalence ⌋ = equivalence⌊ bijection ⌋ = bijection-- The proof of symmetry can be found below.-- Kinds whose interpretation include a function which "goes in the-- forward direction".data ForwardKind : Set whereimplication : ForwardKindequivalence : ForwardKindinjection : ForwardKindleftInverse : ForwardKindsurjection : ForwardKindbijection : ForwardKind-- Forgetful map.⌊_⌋→ : ForwardKind → Kind⌊ implication ⌋→ = implication⌊ equivalence ⌋→ = equivalence⌊ injection ⌋→ = injection⌊ leftInverse ⌋→ = leftInverse⌊ surjection ⌋→ = surjection⌊ bijection ⌋→ = bijection-- The function.⇒→ : ∀ {k} → A ∼[ ⌊ k ⌋→ ] B → A → B⇒→ {k = implication} = Func.to⇒→ {k = equivalence} = Equivalence.to⇒→ {k = injection} = Injection.to⇒→ {k = leftInverse} = RightInverse.to⇒→ {k = surjection} = Surjection.to⇒→ {k = bijection} = Inverse.to-- Kinds whose interpretation include a function which "goes backwards".data BackwardKind : Set wherereverseImplication : BackwardKindequivalence : BackwardKindreverseInjection : BackwardKindleftInverse : BackwardKindsurjection : BackwardKindbijection : BackwardKind-- Forgetful map.⌊_⌋← : BackwardKind → Kind⌊ reverseImplication ⌋← = reverseImplication⌊ equivalence ⌋← = equivalence⌊ reverseInjection ⌋← = reverseInjection⌊ leftInverse ⌋← = leftInverse⌊ surjection ⌋← = surjection⌊ bijection ⌋← = bijection-- The function.⇒← : ∀ {k} → A ∼[ ⌊ k ⌋← ] B → B → A⇒← {k = reverseImplication} = Func.to⇒← {k = equivalence} = Equivalence.from⇒← {k = reverseInjection} = Injection.to⇒← {k = leftInverse} = RightInverse.from⇒← {k = surjection} = RightInverse.to ∘ ↠⇒↪⇒← {k = bijection} = Inverse.from-- Kinds whose interpretation include functions going in both-- directions.data EquivalenceKind : Set whereequivalence : EquivalenceKindleftInverse : EquivalenceKindsurjection : EquivalenceKindbijection : EquivalenceKind-- Forgetful map.⌊_⌋⇔ : EquivalenceKind → Kind⌊ equivalence ⌋⇔ = equivalence⌊ leftInverse ⌋⇔ = leftInverse⌊ surjection ⌋⇔ = surjection⌊ bijection ⌋⇔ = bijection-- The functions.⇒⇔ : ∀ {k} → A ∼[ ⌊ k ⌋⇔ ] B → A ∼[ equivalence ] B⇒⇔ {k = equivalence} = id⇒⇔ {k = leftInverse} = RightInverse.equivalence⇒⇔ {k = surjection} = ↠⇒⇔⇒⇔ {k = bijection} = ↔⇒⇔-- Conversions between special kinds.⇔⌊_⌋ : SymmetricKind → EquivalenceKind⇔⌊ equivalence ⌋ = equivalence⇔⌊ bijection ⌋ = bijection→⌊_⌋ : EquivalenceKind → ForwardKind→⌊ equivalence ⌋ = equivalence→⌊ leftInverse ⌋ = leftInverse→⌊ surjection ⌋ = surjection→⌊ bijection ⌋ = bijection←⌊_⌋ : EquivalenceKind → BackwardKind←⌊ equivalence ⌋ = equivalence←⌊ leftInverse ⌋ = leftInverse←⌊ surjection ⌋ = surjection←⌊ bijection ⌋ = bijection-------------------------------------------------------------------------- Opposites-- For every kind there is an opposite kind._op : Kind → Kindimplication op = reverseImplicationreverseImplication op = implicationequivalence op = equivalenceinjection op = reverseInjectionreverseInjection op = injectionleftInverse op = surjectionsurjection op = leftInversebijection op = bijection-- For every morphism there is a corresponding reverse morphism of the-- opposite kind.reverse : A ∼[ k ] B → B ∼[ k op ] Areverse {k = implication} = idreverse {k = reverseImplication} = idreverse {k = equivalence} = Symmetry.⇔-symreverse {k = injection} = idreverse {k = reverseInjection} = idreverse {k = leftInverse} = ↪⇒↠reverse {k = surjection} = ↠⇒↪reverse {k = bijection} = Symmetry.↔-sym-------------------------------------------------------------------------- For a fixed universe level every kind is a preorder and each-- symmetric kind is an equivalenceK-refl : Reflexive (Related {a} k)K-refl {k = implication} = Identity.⟶-id _K-refl {k = reverseImplication} = Identity.⟶-id _K-refl {k = equivalence} = Identity.⇔-id _K-refl {k = injection} = Identity.↣-id _K-refl {k = reverseInjection} = Identity.↣-id _K-refl {k = leftInverse} = Identity.↪-id _K-refl {k = surjection} = Identity.↠-id _K-refl {k = bijection} = Identity.↔-id _K-reflexive : _≡_ Relation.Binary.⇒ Related {a} kK-reflexive ≡.refl = K-reflK-trans : Trans (Related {a} {b} k)(Related {b} {c} k)(Related {a} {c} k)K-trans {k = implication} = flip Composition._⟶-∘_K-trans {k = reverseImplication} = Composition._⟶-∘_K-trans {k = equivalence} = flip Composition._⇔-∘_K-trans {k = injection} = flip Composition._↣-∘_K-trans {k = reverseInjection} = Composition._↣-∘_K-trans {k = leftInverse} = flip Composition._↪-∘_K-trans {k = surjection} = flip Composition._↠-∘_K-trans {k = bijection} = flip Composition._↔-∘_SK-sym : ∀ {k} → Sym (Related {a} {b} ⌊ k ⌋)(Related {b} {a} ⌊ k ⌋)SK-sym {k = equivalence} = reverseSK-sym {k = bijection} = reverseSK-isEquivalence : ∀ k → IsEquivalence {ℓ = a} (Related ⌊ k ⌋)SK-isEquivalence k = record{ refl = K-refl; sym = SK-sym; trans = K-trans}SK-setoid : SymmetricKind → (ℓ : Level) → Setoid _ _SK-setoid k ℓ = record { isEquivalence = SK-isEquivalence {ℓ} k }K-isPreorder : ∀ k → IsPreorder {ℓ = a} _↔_ (Related k)K-isPreorder k = record{ isEquivalence = SK-isEquivalence bijection; reflexive = ↔⇒; trans = K-trans}K-preorder : Kind → (ℓ : Level) → Preorder _ ℓ _K-preorder k ℓ = record { isPreorder = K-isPreorder k }-------------------------------------------------------------------------- Equational reasoning-- Equational reasoning for related things. Note that we don't use-- the `Relation.Binary.Reasoning.Syntax` for this as this relation-- is heterogeneous.module EquationalReasoning {k : Kind} where-- Combinators with one heterogeneous relationmodule _ {a b : Level} whereopen begin-syntax (Related {a} {b} k) id publicopen ≡-noncomputing-syntax (Related {a} {b} k) public-- Combinators with two heterogeneous relationsmodule _ {a b c : Level} whereprivaterel1 = Related {b} {c} krel2 = Related {a} {c} kopen ∼-syntax rel1 rel2 K-trans publicopen ⤖-syntax rel1 rel2 (K-trans ∘′ ↔⇒ ∘′ ⤖⇒↔) Symmetry.⤖-sym publicopen ↔-syntax rel1 rel2 (K-trans ∘′ ↔⇒) Symmetry.↔-sym public-- Combinators with homogeneous relationsmodule _ {a : Level} whereopen end-syntax (Related {a} k) K-refl publicinfixr 2 _↔⟨⟩__↔⟨⟩_ : (A : Set a) → A ∼[ k ] B → A ∼[ k ] BA ↔⟨⟩ A⇔B = A⇔B{-# WARNING_ON_USAGE _↔⟨⟩_"Warning: _↔⟨⟩_ was deprecated in v2.0.Please use _≡⟨⟩_ instead. "#-}-------------------------------------------------------------------------- Every unary relation induces a preorder and, for symmetric kinds,-- an equivalence. (No claim is made that these relations are unique.)InducedRelation₁ : Kind → (P : A → Set p) → A → A → Set _InducedRelation₁ k P = λ x y → P x ∼[ k ] P yInducedPreorder₁ : Kind → (P : A → Set p) → Preorder _ _ _InducedPreorder₁ k P = record{ _≈_ = _≡_; _≲_ = InducedRelation₁ k P; isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = reflexive ∘K-reflexive ∘≡.cong P; trans = K-trans}} where open Preorder (K-preorder _ _)InducedEquivalence₁ : SymmetricKind → (P : A → Set p) → Setoid _ _InducedEquivalence₁ k P = record{ _≈_ = InducedRelation₁ ⌊ k ⌋ P; isEquivalence = record{ refl = K-refl; sym = SK-sym; trans = K-trans}}-------------------------------------------------------------------------- Every binary relation induces a preorder and, for symmetric kinds,-- an equivalence. (No claim is made that these relations are unique.)InducedRelation₂ : Kind → ∀ {s} → (A → B → Set s) → B → B → Set _InducedRelation₂ k _S_ = λ x y → ∀ {z} → (z S x) ∼[ k ] (z S y)InducedPreorder₂ : Kind → ∀ {s} → (A → B → Set s) → Preorder _ _ _InducedPreorder₂ k _S_ = record{ _≈_ = _≡_; _≲_ = InducedRelation₂ k _S_; isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = λ x≡y {z} →reflexive $K-reflexive $≡.cong (_S_ z) x≡y; trans = λ i↝j j↝k → K-trans i↝j j↝k}} where open Preorder (K-preorder _ _)InducedEquivalence₂ : SymmetricKind → ∀ {s} → (A → B → Set s) → Setoid _ _InducedEquivalence₂ k _S_ = record{ _≈_ = InducedRelation₂ ⌊ k ⌋ _S_; isEquivalence = record{ refl = refl; sym = λ i↝j → sym i↝j; trans = λ i↝j j↝k → trans i↝j j↝k}} where open Setoid (SK-setoid _ _)
-------------------------------------------------------------------------- The Agda standard library---- A module used for creating function pipelines, see-- README.Function.Reasoning for examples------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Reasoning whereopen import Function.Base using (_∋_)-- Need to give _∋_ a new name as syntax cannot contain underscoresinfixl 0 ∋-syntax∋-syntax = _∋_-- Create ∶ syntaxsyntax ∋-syntax A a = a ∶ A-- Export pipeline functionsopen import Function.Base public using (_|>_; _|>′_)
-------------------------------------------------------------------------- The Agda standard library---- Basic properties of the function type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Function.Base using (flip; _∘_)open import Function.Bundles using (_↔_; mk↔ₛ′; Inverse)open import Levelopen import Relation.Binary.PropositionalEquality.Coreusing (trans; cong; cong′)privatevariablea b c d p : LevelA : Set aB : Set b-------------------------------------------------------------------------- Implicit and explicit function spaces are isomorphicΠ↔Π : {B : A → Set b} → ((x : A) → B x) ↔ ({x : A} → B x)Π↔Π = mk↔ₛ′ (λ f {x} → f x) (λ f _ → f) cong′ cong′-------------------------------------------------------------------------- Function spaces can be reorderedΠΠ↔ΠΠ : (R : A → B → Set p) →((x : A) (y : B) → R x y) ↔ ((y : B) (x : A) → R x y)ΠΠ↔ΠΠ _ = mk↔ₛ′ flip flip cong′ cong′-------------------------------------------------------------------------- Assuming extensionality then → preserves ↔→-cong-↔ : {A : Set a} {B : Set b} {C : Set c} {D : Set d} →Extensionality a c → Extensionality b d →A ↔ B → C ↔ D → (A → C) ↔ (B → D)→-cong-↔ extAC extBD A↔B C↔D = mk↔ₛ′(λ h → C↔D.to ∘ h ∘ A↔B.from)(λ g → C↔D.from ∘ g ∘ A↔B.to )(λ h → extBD λ x → trans (C↔D.strictlyInverseˡ _) (cong h (A↔B.strictlyInverseˡ x)))(λ g → extAC λ x → trans (C↔D.strictlyInverseʳ _) (cong g (A↔B.strictlyInverseʳ x)))where module A↔B = Inverse A↔B; module C↔D = Inverse C↔D
-------------------------------------------------------------------------- The Agda standard library---- Properties of surjections------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Surjection whereopen import Function.Base using (_∘_; _$_)open import Function.Definitions using (Surjective; Injective; Congruent)open import Function.Bundles using (Func; Surjection; _↠_; _⟶_; _↪_; mk↪;_⇔_; mk⇔)import Function.Construct.Identity as Identityimport Function.Construct.Composition as Composeopen import Level using (Level)open import Data.Product.Base using (proj₁; proj₂)import Relation.Binary.PropositionalEquality.Core as ≡open import Relation.Binary.Definitions using (Reflexive; Trans)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA B : Set aT S : Setoid a ℓ-------------------------------------------------------------------------- ConstructorsmkSurjection : (f : Func S T) (open Func f) →Surjective Eq₁._≈_ Eq₂._≈_ to →Surjection S TmkSurjection f surjective = record{ Func f; surjective = surjective}-------------------------------------------------------------------------- Conversion functions↠⇒⟶ : A ↠ B → A ⟶ B↠⇒⟶ = Surjection.function↠⇒↪ : A ↠ B → B ↪ A↠⇒↪ s = mk↪ {from = to} λ { ≡.refl → proj₂ (strictlySurjective _)}where open Surjection s↠⇒⇔ : A ↠ B → A ⇔ B↠⇒⇔ s = mk⇔ to (proj₁ ∘ surjective)where open Surjection s-------------------------------------------------------------------------- Setoid propertiesrefl : Reflexive (Surjection {a} {ℓ})refl {x = x} = Identity.surjection xtrans : Trans (Surjection {a} {ℓ₁} {b} {ℓ₂})(Surjection {b} {ℓ₂} {c} {ℓ₃})(Surjection {a} {ℓ₁} {c} {ℓ₃})trans = Compose.surjection-------------------------------------------------------------------------- Otherinjective⇒to⁻-cong : (surj : Surjection S T) →(open Surjection surj) →Injective Eq₁._≈_ Eq₂._≈_ to →Congruent Eq₂._≈_ Eq₁._≈_ to⁻injective⇒to⁻-cong {T = T} surj injective {x} {y} x≈y = injective $ beginto (to⁻ x) ≈⟨ to∘to⁻ x ⟩x ≈⟨ x≈y ⟩y ≈⟨ to∘to⁻ y ⟨to (to⁻ y) ∎whereopen ≈-Reasoning Topen Surjection surj
-------------------------------------------------------------------------- The Agda standard library---- Properties of right inverses------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.RightInverse whereopen import Function.Baseopen import Function.Definitionsopen import Function.Bundlesopen import Function.Consequences using (inverseˡ⇒surjective)open import Level using (Level)open import Data.Product.Base using (_,_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)privatevariableℓ₁ ℓ₂ a b : LevelA B : Set aS T : Setoid a ℓ₁-------------------------------------------------------------------------- ConstructorsmkRightInverse : (e : Equivalence S T) (open Equivalence e) →Inverseʳ Eq₁._≈_ Eq₂._≈_ to from →RightInverse S TmkRightInverse eq invʳ = record{ Equivalence eq; inverseʳ = invʳ}-------------------------------------------------------------------------- ConversionRightInverse⇒LeftInverse : RightInverse S T → LeftInverse T SRightInverse⇒LeftInverse I = record{ to = from; from = to; to-cong = from-cong; from-cong = to-cong; inverseˡ = inverseʳ} where open RightInverse ILeftInverse⇒RightInverse : LeftInverse S T → RightInverse T SLeftInverse⇒RightInverse I = record{ to = from; from = to; to-cong = from-cong; from-cong = to-cong; inverseʳ = inverseˡ} where open LeftInverse IRightInverse⇒Surjection : RightInverse S T → Surjection T SRightInverse⇒Surjection I = record{ to = from; cong = from-cong; surjective = inverseˡ⇒surjective Eq₁._≈_ inverseʳ} where open RightInverse I↪⇒↠ : B ↪ A → A ↠ B↪⇒↠ = RightInverse⇒Surjection↪⇒↩ : B ↪ A → A ↩ B↪⇒↩ = RightInverse⇒LeftInverse↩⇒↪ : B ↩ A → A ↪ B↩⇒↪ = LeftInverse⇒RightInverse-------------------------------------------------------------------------- Othermodule _ (R : RightInverse S T) whereopen RightInverse Rto-from : ∀ {x y} → to x Eq₂.≈ y → from y Eq₁.≈ xto-from eq = Eq₁.trans (from-cong (Eq₂.sym eq)) (strictlyInverseʳ _)
-------------------------------------------------------------------------- The Agda standard library---- Properties of inverses.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Inverse whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Function.Bundlesimport Function.Properties.RightInverse as RightInverseopen import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡import Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Function.Consequences.Setoid as Consequencesimport Function.Construct.Identity as Identityimport Function.Construct.Symmetry as Symmetryimport Function.Construct.Composition as Compositionprivatevariablea b ℓ ℓ₁ ℓ₂ : LevelA B C D : Set aS T U V : Setoid a ℓ-------------------------------------------------------------------------- Setoid bundlesopen Identity public using () renaming (inverse to refl)open Symmetry public using () renaming (inverse to sym)open Composition public using () renaming (inverse to trans)isEquivalence : IsEquivalence (Inverse {a} {b})isEquivalence = record{ refl = λ {x} → Identity.inverse x; sym = sym; trans = trans}-------------------------------------------------------------------------- Propositional bundles↔-refl : A ↔ A↔-refl = Identity.↔-id _↔-sym : A ↔ B → B ↔ A↔-sym = Symmetry.↔-sym↔-trans : A ↔ B → B ↔ C → A ↔ C↔-trans = Composition.inverse-- need to η-expand for everything to line up properly↔-isEquivalence : IsEquivalence {ℓ = ℓ} _↔_↔-isEquivalence = record{ refl = ↔-refl; sym = ↔-sym; trans = ↔-trans}-------------------------------------------------------------------------- Conversion functionstoFunction : Inverse S T → Func S TtoFunction I = record { to = to ; cong = to-cong }where open Inverse IfromFunction : Inverse S T → Func T SfromFunction I = record { to = from ; cong = from-cong }where open Inverse IInverse⇒Injection : Inverse S T → Injection S TInverse⇒Injection {S = S} {T = T} I = record{ to = to; cong = to-cong; injective = inverseʳ⇒injective to inverseʳ} where open Inverse I; open Consequences S TInverse⇒Surjection : Inverse S T → Surjection S TInverse⇒Surjection {S = S} {T = T} I = record{ to = to; cong = to-cong; surjective = inverseˡ⇒surjective inverseˡ} where open Inverse I; open Consequences S TInverse⇒Bijection : Inverse S T → Bijection S TInverse⇒Bijection {S = S} {T = T} I = record{ to = to; cong = to-cong; bijective = inverseᵇ⇒bijective inverse} where open Inverse I; open Consequences S TInverse⇒Equivalence : Inverse S T → Equivalence S TInverse⇒Equivalence I = record{ to = to; from = from; to-cong = to-cong; from-cong = from-cong} where open Inverse I↔⇒⟶ : A ↔ B → A ⟶ B↔⇒⟶ = toFunction↔⇒⟵ : A ↔ B → B ⟶ A↔⇒⟵ = fromFunction↔⇒↣ : A ↔ B → A ↣ B↔⇒↣ = Inverse⇒Injection↔⇒↠ : A ↔ B → A ↠ B↔⇒↠ = Inverse⇒Surjection↔⇒⤖ : A ↔ B → A ⤖ B↔⇒⤖ = Inverse⇒Bijection↔⇒⇔ : A ↔ B → A ⇔ B↔⇒⇔ = Inverse⇒Equivalence↔⇒↩ : A ↔ B → A ↩ B↔⇒↩ = Inverse.leftInverse↔⇒↪ : A ↔ B → A ↪ B↔⇒↪ = Inverse.rightInverse-- The functions above can be combined with the following lemma to-- transport an arbitrary relation R (e.g. Injection) across-- inverses.transportVia : {R : ∀ {a b ℓ₁ ℓ₂} → REL (Setoid a ℓ₁) (Setoid b ℓ₂) (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)} →(∀ {a b c ℓ₁ ℓ₂ ℓ₃} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} {U : Setoid c ℓ₃} → R S T → R T U → R S U) →(∀ {a b ℓ₁ ℓ₂} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} → Inverse S T → R S T) →Inverse S T → R T U → Inverse U V → R S VtransportVia R-trans inv⇒R IBA RBC ICD =R-trans (inv⇒R IBA) (R-trans RBC (inv⇒R ICD))-------------------------------------------------------------------------- Othermodule _ (ext : ∀ {a b} → Extensionality a b) where↔-fun : A ↔ B → C ↔ D → (A → C) ↔ (B → D)↔-fun A↔B C↔D = mk↔ₛ′(λ a→c b → to C↔D (a→c (from A↔B b)))(λ b→d a → from C↔D (b→d (to A↔B a)))(λ b→d → ext λ _ → ≡.trans (strictlyInverseˡ C↔D _ ) (≡.cong b→d (strictlyInverseˡ A↔B _)))(λ a→c → ext λ _ → ≡.trans (strictlyInverseʳ C↔D _ ) (≡.cong a→c (strictlyInverseʳ A↔B _)))where open Inversemodule _ (I : Inverse S T) whereopen Inverse Ito-from : ∀ {x y} → to x Eq₂.≈ y → from y Eq₁.≈ xto-from = RightInverse.to-from rightInverse
-------------------------------------------------------------------------- The Agda standard library---- Half adjoint equivalences------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Inverse.HalfAdjointEquivalence whereopen import Function.Base using (id; _∘_)open import Function.Bundles using (Inverse; _↔_; mk↔ₛ′)open import Level using (Level; _⊔_)open import Relation.Binary.PropositionalEqualityusing (_≡_; refl; cong; sym; trans; trans-reflʳ; cong-≡id; cong-∘; naturality;cong-id; trans-assoc; trans-symˡ; module ≡-Reasoning)privatevariablea b : LevelA B : Set a-- Half adjoint equivalences (see the HoTT book).---- They are inverses with an extra coherence condition that the left-- and right inversion proofs interact the right way with `cong`.infix 4 _≃_record _≃_ (A : Set a) (B : Set b) : Set (a ⊔ b) wherefieldto : A → Bfrom : B → Aleft-inverse-of : ∀ x → from (to x) ≡ xright-inverse-of : ∀ x → to (from x) ≡ xleft-right : ∀ x → cong to (left-inverse-of x) ≡ right-inverse-of (to x)-- The forward direction of a half adjoint equivalence is injective.injective : ∀ {x y} → to x ≡ to y → x ≡ yinjective {x} {y} to-x≡to-y =x ≡⟨ sym (left-inverse-of _) ⟩from (to x) ≡⟨ cong from to-x≡to-y ⟩from (to y) ≡⟨ left-inverse-of _ ⟩y ∎where open ≡-Reasoning-- Half adjoint equivalences can be turned into inverses.≃⇒↔ : A ≃ B → A ↔ B≃⇒↔ A≃B = mk↔ₛ′ to from right-inverse-of left-inverse-ofwhere open _≃_ A≃B-- Inverses can be turned into half adjoint equivalences.---- (This proof is based on one in the HoTT book.)↔⇒≃ : A ↔ B → A ≃ B↔⇒≃ A↔B = record{ to = to; from = from; left-inverse-of = strictlyInverseʳ; right-inverse-of = right-inverse-of; left-right = left-right}whereopen ≡-Reasoningopen module A↔B = Inverse A↔Bright-inverse-of : ∀ x → to (from x) ≡ xright-inverse-of x =to (from x) ≡⟨ sym (A↔B.strictlyInverseˡ _) ⟩to (from (to (from x))) ≡⟨ cong to (strictlyInverseʳ _) ⟩to (from x) ≡⟨ A↔B.strictlyInverseˡ _ ⟩x ∎left-right :∀ x →cong to (strictlyInverseʳ x) ≡ right-inverse-of (to x)left-right x =cong to (strictlyInverseʳ x) ≡⟨⟩trans refl (cong to (strictlyInverseʳ _)) ≡⟨ cong (λ p → trans p (cong to (strictlyInverseʳ _)))(sym (trans-symˡ (A↔B.strictlyInverseˡ _))) ⟩trans (trans (sym (A↔B.strictlyInverseˡ _))(A↔B.strictlyInverseˡ _))(cong to (strictlyInverseʳ _)) ≡⟨ trans-assoc (sym (A↔B.strictlyInverseˡ _)) ⟩trans (sym (A↔B.strictlyInverseˡ _))(trans (A↔B.strictlyInverseˡ _)(cong to (strictlyInverseʳ _))) ≡⟨ cong (trans (sym (A↔B.strictlyInverseˡ _))) lemma ⟩trans (sym (A↔B.strictlyInverseˡ _))(trans (cong to (strictlyInverseʳ _))(trans (A↔B.strictlyInverseˡ _) refl)) ≡⟨⟩right-inverse-of (to x) ∎wherelemma =trans (A↔B.strictlyInverseˡ _)(cong to (strictlyInverseʳ _)) ≡⟨ cong (trans (A↔B.strictlyInverseˡ _)) (sym (cong-id _)) ⟩trans (A↔B.strictlyInverseˡ _)(cong id (cong to (strictlyInverseʳ _))) ≡⟨ sym (naturality A↔B.strictlyInverseˡ) ⟩trans (cong (to ∘ from)(cong to (strictlyInverseʳ _)))(A↔B.strictlyInverseˡ _) ≡⟨ cong (λ p → trans p (A↔B.strictlyInverseˡ _))(sym (cong-∘ _)) ⟩trans (cong (to ∘ from ∘ to)(strictlyInverseʳ _))(A↔B.strictlyInverseˡ _) ≡⟨ cong (λ p → trans p (A↔B.strictlyInverseˡ _))(cong-∘ _) ⟩trans (cong to(cong (from ∘ to)(strictlyInverseʳ _)))(A↔B.strictlyInverseˡ _) ≡⟨ cong (λ p → trans (cong to p) (strictlyInverseˡ (to x)))(cong-≡id strictlyInverseʳ) ⟩trans (cong to (strictlyInverseʳ _))(A↔B.strictlyInverseˡ _) ≡⟨ cong (trans (cong to (strictlyInverseʳ _)))(sym (trans-reflʳ _)) ⟩trans (cong to (strictlyInverseʳ _))(trans (A↔B.strictlyInverseˡ _) refl) ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties for injections------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Injection whereopen import Function.Baseopen import Function.Definitionsopen import Function.Bundlesimport Function.Construct.Identity as Identityimport Function.Construct.Composition as Composeopen import Level using (Level)open import Data.Product.Base using (proj₁; proj₂)open import Relation.Binary.Definitionsopen import Relation.Binary using (Setoid)privatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA B : Set aT S U : Setoid a ℓ-------------------------------------------------------------------------- ConstructorsmkInjection : (f : Func S T) (open Func f) →Injective Eq₁._≈_ Eq₂._≈_ to →Injection S TmkInjection f injective = record{ Func f; injective = injective}-------------------------------------------------------------------------- Conversion functions↣⇒⟶ : A ↣ B → A ⟶ B↣⇒⟶ = Injection.function-------------------------------------------------------------------------- Setoid propertiesrefl : Reflexive (Injection {a} {ℓ})refl {x = x} = Identity.injection xtrans : Trans (Injection {a} {ℓ₁} {b} {ℓ₂})(Injection {b} {ℓ₂} {c} {ℓ₃})(Injection {a} {ℓ₁} {c} {ℓ₃})trans = Compose.injection-------------------------------------------------------------------------- Propositonal properties↣-refl : Injection S S↣-refl = refl↣-trans : Injection S T → Injection T U → Injection S U↣-trans = trans
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of equivalences. This file is designed to be-- imported qualified.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Equivalence whereopen import Function.Bundlesopen import Levelopen import Relation.Binary.Definitionsopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)import Relation.Binary.PropositionalEquality.Properties as ≡import Function.Construct.Identity as Identityimport Function.Construct.Symmetry as Symmetryimport Function.Construct.Composition as Compositionprivatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA B : Set aS T : Setoid a ℓ-------------------------------------------------------------------------- ConstructorsmkEquivalence : Func S T → Func T S → Equivalence S TmkEquivalence f g = record{ to = to f; from = to g; to-cong = cong f; from-cong = cong g} where open Func⟶×⟵⇒⇔ : A ⟶ B → B ⟶ A → A ⇔ B⟶×⟵⇒⇔ = mkEquivalence-------------------------------------------------------------------------- Destructors⇔⇒⟶ : A ⇔ B → A ⟶ B⇔⇒⟶ = Equivalence.toFunction⇔⇒⟵ : A ⇔ B → B ⟶ A⇔⇒⟵ = Equivalence.fromFunction-------------------------------------------------------------------------- Setoid bundlesrefl : Reflexive (Equivalence {a} {ℓ})refl {x = x} = Identity.equivalence xsym : Sym (Equivalence {a} {ℓ₁} {b} {ℓ₂})(Equivalence {b} {ℓ₂} {a} {ℓ₁})sym = Symmetry.equivalencetrans : Trans (Equivalence {a} {ℓ₁} {b} {ℓ₂})(Equivalence {b} {ℓ₂} {c} {ℓ₃})(Equivalence {a} {ℓ₁} {c} {ℓ₃})trans = Composition.equivalenceisEquivalence : IsEquivalence (Equivalence {a} {ℓ})isEquivalence = record{ refl = refl; sym = sym; trans = Composition.equivalence}setoid : (s₁ s₂ : Level) → Setoid (suc (s₁ ⊔ s₂)) (s₁ ⊔ s₂)setoid s₁ s₂ = record{ Carrier = Setoid s₁ s₂; _≈_ = Equivalence; isEquivalence = isEquivalence}-------------------------------------------------------------------------- Propositional bundles⇔-isEquivalence : IsEquivalence {ℓ = ℓ} _⇔_⇔-isEquivalence = record{ refl = λ {x} → Identity.equivalence (≡.setoid x); sym = Symmetry.equivalence; trans = Composition.equivalence}⇔-setoid : (ℓ : Level) → Setoid (suc ℓ) ℓ⇔-setoid ℓ = record{ Carrier = Set ℓ; _≈_ = _⇔_; isEquivalence = ⇔-isEquivalence}
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of bijections.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Properties.Bijection whereopen import Function.Bundles using (Bijection; Inverse; Equivalence;_⤖_; _↔_; _⇔_)open import Level using (Level)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Trans)open import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Function.Base using (_∘_)open import Function.Properties.Surjection using (injective⇒to⁻-cong)open import Function.Properties.Inverse using (Inverse⇒Equivalence)import Function.Construct.Identity as Identityimport Function.Construct.Symmetry as Symmetryimport Function.Construct.Composition as Compositionprivatevariablea b c ℓ ℓ₁ ℓ₂ ℓ₃ : LevelA B : Set aT S : Setoid a ℓ-------------------------------------------------------------------------- Setoid propertiesrefl : Reflexive (Bijection {a} {ℓ})refl = Identity.bijection _-- Can't prove full symmetry as we have no proof that the witness-- produced by the surjection proof preserves equalitysym-≡ : Bijection S (setoid B) → Bijection (setoid B) Ssym-≡ = Symmetry.bijection-≡trans : Trans (Bijection {a} {ℓ₁} {b} {ℓ₂}) (Bijection {b} {ℓ₂} {c} {ℓ₃}) Bijectiontrans = Composition.bijection-------------------------------------------------------------------------- Propositional properties⤖-isEquivalence : IsEquivalence {ℓ = ℓ} _⤖_⤖-isEquivalence = record{ refl = refl; sym = sym-≡; trans = trans}-------------------------------------------------------------------------- Conversion functionsBijection⇒Inverse : Bijection S T → Inverse S TBijection⇒Inverse bij = record{ to = to; from = to⁻; to-cong = cong; from-cong = injective⇒to⁻-cong surjection injective; inverse = (λ y≈to⁻[x] → Eq₂.trans (cong y≈to⁻[x]) (to∘to⁻ _)) ,(λ y≈to[x] → injective (Eq₂.trans (to∘to⁻ _) y≈to[x]))}where open Bijection bij; to∘to⁻ = proj₂ ∘ strictlySurjectiveBijection⇒Equivalence : Bijection T S → Equivalence T SBijection⇒Equivalence = Inverse⇒Equivalence ∘ Bijection⇒Inverse⤖⇒↔ : A ⤖ B → A ↔ B⤖⇒↔ = Bijection⇒Inverse⤖⇒⇔ : A ⤖ B → A ⇔ B⤖⇒⇔ = Bijection⇒Equivalence
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous N-ary Functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Nary.NonDependent where-------------------------------------------------------------------------- Concrete examples can be found in README.Nary. This file's comments-- are more focused on the implementation details and the motivations-- behind the design decisions.------------------------------------------------------------------------open import Level using (Level; 0ℓ; _⊔_; Lift)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Product.Base using (_×_; _,_)open import Data.Product.Nary.NonDependentusing (Product; uncurryₙ; Equalₙ; curryₙ; fromEqualₙ; toEqualₙ)open import Function.Base using (_∘′_; _$′_; const; flip)open import Relation.Unary using (IUniversal)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong)privatevariablea b r : LevelA : Set aB : Set b-------------------------------------------------------------------------- Re-exporting the basic operationsopen import Function.Nary.NonDependent.Base public-------------------------------------------------------------------------- Additional operations on Levelsltabulate : ∀ n → (Fin n → Level) → Levels nltabulate zero f = _ltabulate (suc n) f = f zero , ltabulate n (f ∘′ suc)lreplicate : ∀ n → Level → Levels nlreplicate n ℓ = ltabulate n (const ℓ)0ℓs : ∀[ Levels ]0ℓs = lreplicate _ 0ℓ-------------------------------------------------------------------------- Congruencemodule _ n {ls} {as : Sets n ls} {R : Set r} (f : as ⇉ R) whereprivateg : Product n as → Rg = uncurryₙ n f-- Congruentₙ : ∀ n. ∀ a₁₁ a₁₂ ⋯ aₙ₁ aₙ₂ →-- a₁₁ ≡ a₁₂ → ⋯ → aₙ₁ ≡ aₙ₂ →-- f a₁₁ ⋯ aₙ₁ ≡ f a₁₂ ⋯ aₙ₂Congruentₙ : Set (r Level.⊔ ⨆ n ls)Congruentₙ = ∀ {l r} → Equalₙ n l r ⇉ (g l ≡ g r)congₙ : Congruentₙcongₙ = curryₙ n (cong g ∘′ fromEqualₙ n)-- Congruence at a specific locationmodule _ m n {ls ls′} {as : Sets m ls} {bs : Sets n ls′}(f : as ⇉ (A → bs ⇉ B)) whereprivateg : Product m as → A → Product n bs → Bg vs a ws = uncurryₙ n (uncurryₙ m f vs a) wscongAt : ∀ {vs ws a₁ a₂} → a₁ ≡ a₂ → g vs a₁ ws ≡ g vs a₂ wscongAt {vs} {ws} = cong (λ a → g vs a ws)-------------------------------------------------------------------------- Injectivitymodule _ n {ls} {as : Sets n ls} {R : Set r} (con : as ⇉ R) where-- Injectiveₙ : ∀ n. ∀ a₁₁ a₁₂ ⋯ aₙ₁ aₙ₂ →-- con a₁₁ ⋯ aₙ₁ ≡ con a₁₂ ⋯ aₙ₂ →-- a₁₁ ≡ a₁₂ × ⋯ × aₙ₁ ≡ aₙ₂privatec : Product n as → Rc = uncurryₙ n conInjectiveₙ : Set (r Level.⊔ ⨆ n ls)Injectiveₙ = ∀ {l r} → c l ≡ c r → Product n (Equalₙ n l r)injectiveₙ : (∀ {l r} → c l ≡ c r → l ≡ r) → Injectiveₙinjectiveₙ con-inj eq = toEqualₙ n (con-inj eq)
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous N-ary Functions: basic types and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Nary.NonDependent.Base where-------------------------------------------------------------------------- Concrete examples can be found in README.Nary. This file's comments-- are more focused on the implementation details and the motivations-- behind the design decisions.------------------------------------------------------------------------open import Level using (Level; 0ℓ; _⊔_)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (_×_; _,_)open import Data.Unit.Polymorphic.Baseopen import Function.Base using (_∘′_; _$′_; const; flip)privatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Type Definitions-- We want to define n-ary function spaces and generic n-ary operations-- on them such as (un)currying, zipWith, alignWith, etc.-- We want users to be able to use these seamlessly whenever n is concrete.-- In other words, we want Agda to infer the sets `A₁, ⋯, Aₙ` when we-- write `uncurryₙ n f` where `f` has type `A₁ → ⋯ → Aₙ → B`. For this-- to happen, we need the structure in which these Sets are stored to-- effectively η-expand to `A₁, ⋯, Aₙ` when the parameter `n` is known.-- Hence the following definitions:-------------------------------------------------------------------------- First, a "vector" of `n` Levels (defined by induction on n so that it-- may be built by η-expansion and unification). Each Level will be that-- of one of the Sets we want to take the n-ary product of.Levels : ℕ → SetLevels zero = ⊤Levels (suc n) = Level × Levels n-- The overall Level of a `n` Sets of respective levels `l₁, ⋯, lₙ` will-- be the least upper bound `l₁ ⊔ ⋯ ⊔ lₙ` of all of the Levels involved.-- Hence the following definition of n-ary least upper bound:⨆ : ∀ n → Levels n → Level⨆ zero _ = Level.zero⨆ (suc n) (l , ls) = l ⊔ (⨆ n ls)-- Second, a "vector" of `n` Sets whose respective Levels are determined-- by the `Levels n` input.Sets : ∀ n (ls : Levels n) → Set (Level.suc (⨆ n ls))Sets zero _ = ⊤Sets (suc n) (l , ls) = Set l × Sets n ls-- Third, a function type whose domains are given by a "vector" of `n`-- Sets `A₁, ⋯, Aₙ` and whose codomain is `B`. `Arrows` forms such a-- type of shape `A₁ → ⋯ → Aₙ → B` by induction on `n`.Arrows : ∀ n {r ls} → Sets n ls → Set r → Set (r ⊔ (⨆ n ls))Arrows zero _ b = bArrows (suc n) (a , as) b = a → Arrows n as b-- We introduce a notation for this definitioninfixr 0 _⇉__⇉_ : ∀ {n ls r} → Sets n ls → Set r → Set (r ⊔ (⨆ n ls))_⇉_ = Arrows _-------------------------------------------------------------------------- Operations on Sets-- Level-respecting mapinfixr -1 _<$>__<$>_ : (∀ {l} → Set l → Set l) →∀ {n ls} → Sets n ls → Sets n ls_<$>_ f {zero} as = __<$>_ f {suc n} (a , as) = f a , (f <$> as)-- Level-modifying generalised maplmap : (Level → Level) → ∀ n → Levels n → Levels nlmap f zero ls = _lmap f (suc n) (l , ls) = f l , lmap f n lssmap : ∀ f → (∀ {l} → Set l → Set (f l)) →∀ n {ls} → Sets n ls → Sets n (lmap f n ls)smap f F zero as = _smap f F (suc n) (a , as) = F a , smap f F n as-------------------------------------------------------------------------- Operations on Functions-- mapping under n argumentsmapₙ : ∀ n {ls} {as : Sets n ls} → (B → C) → as ⇉ B → as ⇉ Cmapₙ zero f v = f vmapₙ (suc n) f g = mapₙ n f ∘′ g-- compose function at the n-th positioninfix 1 _%=_⊢__%=_⊢_ : ∀ n {ls} {as : Sets n ls} → (A → B) → as ⇉ (B → C) → as ⇉ (A → C)n %= f ⊢ g = mapₙ n (_∘′ f) g-- partially apply function at the n-th positioninfix 1 _∷=_⊢__∷=_⊢_ : ∀ n {ls} {as : Sets n ls} → A → as ⇉ (A → B) → as ⇉ Bn ∷= x ⊢ g = mapₙ n (_$′ x) g-- hole at the n-th positionholeₙ : ∀ n {ls} {as : Sets n ls} → (A → as ⇉ B) → as ⇉ (A → B)holeₙ zero f = fholeₙ (suc n) f = holeₙ n ∘′ flip f-- function constant in its n first arguments-- Note that its type will only be inferred if it is used in a context-- specifying what the type of the function ought to be. Just like the-- usual const: there is no way to infer its domain from its argument.constₙ : ∀ n {ls r} {as : Sets n ls} {b : Set r} → b → as ⇉ bconstₙ zero v = vconstₙ (suc n) v = const (constₙ n v)
-------------------------------------------------------------------------- The Agda standard library---- Metrics with arbitrary domains and codomains------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric whereopen import Function.Metric.Core publicopen import Function.Metric.Definitions publicopen import Function.Metric.Structures publicopen import Function.Metric.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Some metric structures (not packed up with sets, operations, etc.)-------------------------------------------------------------------------- The contents of this module should usually be accessed via-- `Function.Metric`.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsPartialOrder; IsEquivalence)module Function.Metric.Structures{a i ℓ₁ ℓ₂ ℓ₃} {A : Set a} {I : Set i}(_≈ₐ_ : Rel A ℓ₁) (_≈ᵢ_ : Rel I ℓ₂) (_≤_ : Rel I ℓ₃) (0# : I) whereopen import Algebra.Core using (Op₂)open import Function.Metric.Coreopen import Function.Metric.Definitionsopen import Level using (_⊔_)-------------------------------------------------------------------------- Proto-metrics-- We do not insist that the ordering relation is total as otherwise-- we would exclude the real numbers.record IsProtoMetric (d : DistanceFunction A I): Set (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherefieldisPartialOrder : IsPartialOrder _≈ᵢ_ _≤_≈-isEquivalence : IsEquivalence _≈ₐ_cong : Congruent _≈ₐ_ _≈ᵢ_ dnonNegative : NonNegative _≤_ d 0#open IsPartialOrder isPartialOrder publicrenaming (module Eq to EqI)module EqC = IsEquivalence ≈-isEquivalence-------------------------------------------------------------------------- Pre-metricsrecord IsPreMetric (d : DistanceFunction A I): Set (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherefieldisProtoMetric : IsProtoMetric d≈⇒0 : Definite _≈ₐ_ _≈ᵢ_ d 0#open IsProtoMetric isProtoMetric public-------------------------------------------------------------------------- Quasi-semi-metricsrecord IsQuasiSemiMetric (d : DistanceFunction A I): Set (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherefieldisPreMetric : IsPreMetric d0⇒≈ : Indiscernable _≈ₐ_ _≈ᵢ_ d 0#open IsPreMetric isPreMetric public-------------------------------------------------------------------------- Semi-metricsrecord IsSemiMetric (d : DistanceFunction A I): Set (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherefieldisQuasiSemiMetric : IsQuasiSemiMetric dsym : Symmetric _≈ᵢ_ dopen IsQuasiSemiMetric isQuasiSemiMetric public-------------------------------------------------------------------------- General metrics-- A general metric obeys a generalised form of the triangle inequality.-- It can be specialised to a standard metric/ultrametric/inframetric-- etc. by providing the correct operator.---- Furthermore we do not assume that _∙_ & 0# form a monoid as-- associativity does not hold for p-relaxed metrics/p-inframetrics and-- the identity laws do not hold for ultrametrics over negative-- codomains.---- See "Properties of distance spaces with power triangle inequalities"-- by Daniel J. Greenhoe, 2016 (arXiv)record IsGeneralMetric (_∙_ : Op₂ I) (d : DistanceFunction A I): Set (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) wherefieldisSemiMetric : IsSemiMetric dtriangle : TriangleInequality _≤_ _∙_ dopen IsSemiMetric isSemiMetric public
-------------------------------------------------------------------------- The Agda standard library---- Metrics with ℚ as the codomain of the metric function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Rational whereopen import Function.Metric.Rational.Core publicopen import Function.Metric.Rational.Definitions publicopen import Function.Metric.Rational.Structures publicopen import Function.Metric.Rational.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℚ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Rational.Baseopen import Function.Base using (const)open import Level using (Level; suc)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Function.Metric.Rational.Coreopen import Function.Metric.Rational.Definitionsimport Function.Metric.Structures as Basemodule Function.Metric.Rational.Structures whereprivatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Proto-metricsIsProtoMetric : Rel A ℓ → DistanceFunction A → Set _IsProtoMetric _≈_ = Base.IsProtoMetric _≈_ _≡_ _≤_ 0ℚopen Base using (module IsProtoMetric) public-------------------------------------------------------------------------- Pre-metricsIsPreMetric : Rel A ℓ → DistanceFunction A → Set _IsPreMetric _≈_ = Base.IsPreMetric _≈_ _≡_ _≤_ 0ℚopen Base using (module IsPreMetric) public-------------------------------------------------------------------------- Quasi-semi-metricsIsQuasiSemiMetric : Rel A ℓ → DistanceFunction A → Set _IsQuasiSemiMetric _≈_ = Base.IsQuasiSemiMetric _≈_ _≡_ _≤_ 0ℚopen Base using (module IsQuasiSemiMetric) public-------------------------------------------------------------------------- Semi-metricsIsSemiMetric : Rel A ℓ → DistanceFunction A → Set _IsSemiMetric _≈_ = Base.IsSemiMetric _≈_ _≡_ _≤_ 0ℚopen Base using (module IsSemiMetric) public-------------------------------------------------------------------------- MetricsIsMetric : Rel A ℓ → DistanceFunction A → Set _IsMetric _≈_ = Base.IsGeneralMetric _≈_ _≡_ _≤_ 0ℚ _+_module IsMetric {_≈_ : Rel A ℓ} {d : DistanceFunction A}(M : IsMetric _≈_ d) whereopen Base.IsGeneralMetric M public-------------------------------------------------------------------------- Ultra-metricsIsUltraMetric : Rel A ℓ → DistanceFunction A → Set _IsUltraMetric _≈_ = Base.IsGeneralMetric _≈_ _≡_ _≤_ 0ℚ _⊔_module IsUltraMetric {_≈_ : Rel A ℓ} {d : DistanceFunction A}(UM : IsUltraMetric _≈_ d) whereopen Base.IsGeneralMetric UM public
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℚ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Core using (Op₂)open import Data.Rational.Baseopen import Level using (Level)open import Relation.Binary.Coreopen import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Function.Metric.Rational.Coreimport Function.Metric.Definitions as Basemodule Function.Metric.Rational.Definitions whereprivatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Properties-- BasicCongruent : Rel A ℓ → DistanceFunction A → Set _Congruent _≈ₐ_ d = Base.Congruent _≈ₐ_ _≡_ dIndiscernable : Rel A ℓ → DistanceFunction A → Set _Indiscernable _≈ₐ_ d = Base.Indiscernable _≈ₐ_ _≡_ d 0ℚDefinite : Rel A ℓ → DistanceFunction A → Set _Definite _≈ₐ_ d = Base.Definite _≈ₐ_ _≡_ d 0ℚSymmetric : DistanceFunction A → Set _Symmetric = Base.Symmetric _≡_Bounded : DistanceFunction A → Set _Bounded = Base.Bounded _≤_TranslationInvariant : Op₂ A → DistanceFunction A → Set _TranslationInvariant = Base.TranslationInvariant _≡_-- InequalitiesTriangleInequality : DistanceFunction A → Set _TriangleInequality = Base.TriangleInequality _≤_ _+_MaxTriangleInequality : DistanceFunction A → Set _MaxTriangleInequality = Base.TriangleInequality _≤_ _⊔_-- ContractionsContracting : (A → A) → DistanceFunction A → Set _Contracting = Base.Contracting _≤_ContractingOnOrbits : (A → A) → DistanceFunction A → Set _ContractingOnOrbits = Base.ContractingOnOrbits _≤_StrictlyContracting : Rel A ℓ → (A → A) → DistanceFunction A → Set _StrictlyContracting _≈_ = Base.StrictlyContracting _≈_ _<_StrictlyContractingOnOrbits : Rel A ℓ → (A → A) → DistanceFunction A → Set _StrictlyContractingOnOrbits _≈_ = Base.StrictlyContractingOnOrbits _≈_ _<_
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℕ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Rational.Base using (ℚ)import Function.Metric.Core as Basemodule Function.Metric.Rational.Core where-------------------------------------------------------------------------- DefinitionDistanceFunction : ∀ {a} → Set a → Set aDistanceFunction A = Base.DistanceFunction A ℚ
-------------------------------------------------------------------------- The Agda standard library---- Bundles for metrics over ℚ-------------------------------------------------------------------------- Unfortunately, unlike definitions and structures, the bundles over-- general metric spaces cannot be reused as it is impossible to-- constrain the image set to ℚ.{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Rational.Bundles whereopen import Function.Base using (const)open import Level using (Level; suc; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (isEquivalence)open import Function.Metric.Rational.Core using (DistanceFunction)open import Function.Metric.Rational.Structuresopen import Function.Metric.Bundles as Baseusing (GeneralMetric)-------------------------------------------------------------------------- Proto-metricrecord ProtoMetric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisProtoMetric : IsProtoMetric _≈_ dinfix 4 _≈_open IsProtoMetric isProtoMetric public-------------------------------------------------------------------------- PreMetricrecord PreMetric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisPreMetric : IsPreMetric _≈_ dinfix 4 _≈_open IsPreMetric isPreMetric publicprotoMetric : ProtoMetric a ℓprotoMetric = record{ isProtoMetric = isProtoMetric}-------------------------------------------------------------------------- QuasiSemiMetricrecord QuasiSemiMetric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisQuasiSemiMetric : IsQuasiSemiMetric _≈_ dinfix 4 _≈_open IsQuasiSemiMetric isQuasiSemiMetric publicpreMetric : PreMetric a ℓpreMetric = record{ isPreMetric = isPreMetric}open PreMetric preMetric publicusing (protoMetric)-------------------------------------------------------------------------- SemiMetricrecord SemiMetric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisSemiMetric : IsSemiMetric _≈_ dinfix 4 _≈_open IsSemiMetric isSemiMetric publicquasiSemiMetric : QuasiSemiMetric a ℓquasiSemiMetric = record{ isQuasiSemiMetric = isQuasiSemiMetric}open QuasiSemiMetric quasiSemiMetric publicusing (protoMetric; preMetric)-------------------------------------------------------------------------- Metricsrecord Metric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisMetric : IsMetric _≈_ dinfix 4 _≈_open IsMetric isMetric publicsemiMetric : SemiMetric a ℓsemiMetric = record{ isSemiMetric = isSemiMetric}open SemiMetric semiMetric publicusing (protoMetric; preMetric; quasiSemiMetric)-------------------------------------------------------------------------- UltraMetricsrecord UltraMetric a ℓ : Set (suc (a ⊔ ℓ)) wherefieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisUltraMetric : IsUltraMetric _≈_ dinfix 4 _≈_open IsUltraMetric isUltraMetric publicsemiMetric : SemiMetric a ℓsemiMetric = record{ isSemiMetric = isSemiMetric}open SemiMetric semiMetric publicusing (protoMetric; preMetric; quasiSemiMetric)
-------------------------------------------------------------------------- The Agda standard library---- Metrics with ℕ as the codomain of the metric function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Nat whereopen import Function.Metric.Nat.Core publicopen import Function.Metric.Nat.Definitions publicopen import Function.Metric.Nat.Structures publicopen import Function.Metric.Nat.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℕ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Nat.Structures whereopen import Data.Nat.Base hiding (suc)open import Function.Base using (const)open import Level using (Level; suc)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Function.Metric.Nat.Coreopen import Function.Metric.Nat.Definitionsimport Function.Metric.Structures as Baseprivatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Proto-metricsIsProtoMetric : Rel A ℓ → DistanceFunction A → Set _IsProtoMetric _≈_ = Base.IsProtoMetric _≈_ _≡_ _≤_ 0open Base using (module IsProtoMetric) public-------------------------------------------------------------------------- Pre-metricsIsPreMetric : Rel A ℓ → DistanceFunction A → Set _IsPreMetric _≈_ = Base.IsPreMetric _≈_ _≡_ _≤_ 0open Base using (module IsPreMetric) public-------------------------------------------------------------------------- Quasi-semi-metricsIsQuasiSemiMetric : Rel A ℓ → DistanceFunction A → Set _IsQuasiSemiMetric _≈_ = Base.IsQuasiSemiMetric _≈_ _≡_ _≤_ 0open Base using (module IsQuasiSemiMetric) public-------------------------------------------------------------------------- Semi-metricsIsSemiMetric : Rel A ℓ → DistanceFunction A → Set _IsSemiMetric _≈_ = Base.IsSemiMetric _≈_ _≡_ _≤_ 0open Base using (module IsSemiMetric) public-------------------------------------------------------------------------- MetricsIsMetric : Rel A ℓ → DistanceFunction A → Set _IsMetric _≈_ = Base.IsGeneralMetric _≈_ _≡_ _≤_ 0 _+_module IsMetric {_≈_ : Rel A ℓ} {d : DistanceFunction A}(M : IsMetric _≈_ d) whereopen Base.IsGeneralMetric M public-------------------------------------------------------------------------- Ultra-metricsIsUltraMetric : Rel A ℓ → DistanceFunction A → Set _IsUltraMetric _≈_ = Base.IsGeneralMetric _≈_ _≡_ _≤_ 0 _⊔_module IsUltraMetric {_≈_ : Rel A ℓ} {d : DistanceFunction A}(UM : IsUltraMetric _≈_ d) whereopen Base.IsGeneralMetric UM public
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℕ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Nat.Definitions whereopen import Algebra.Core using (Op₂)open import Data.Nat.Baseopen import Level using (Level)open import Relation.Binary.Coreopen import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Function.Metric.Nat.Coreimport Function.Metric.Definitions as Baseprivatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Properties-- BasicCongruent : Rel A ℓ → DistanceFunction A → Set _Congruent _≈ₐ_ d = Base.Congruent _≈ₐ_ _≡_ dIndiscernable : Rel A ℓ → DistanceFunction A → Set _Indiscernable _≈ₐ_ d = Base.Indiscernable _≈ₐ_ _≡_ d 0Definite : Rel A ℓ → DistanceFunction A → Set _Definite _≈ₐ_ d = Base.Definite _≈ₐ_ _≡_ d 0Symmetric : DistanceFunction A → Set _Symmetric = Base.Symmetric _≡_Bounded : DistanceFunction A → Set _Bounded = Base.Bounded _≤_TranslationInvariant : Op₂ A → DistanceFunction A → Set _TranslationInvariant = Base.TranslationInvariant _≡_-- InequalitiesTriangleInequality : DistanceFunction A → Set _TriangleInequality = Base.TriangleInequality _≤_ _+_MaxTriangleInequality : DistanceFunction A → Set _MaxTriangleInequality = Base.TriangleInequality _≤_ _⊔_-- ContractionsContracting : (A → A) → DistanceFunction A → Set _Contracting = Base.Contracting _≤_ContractingOnOrbits : (A → A) → DistanceFunction A → Set _ContractingOnOrbits = Base.ContractingOnOrbits _≤_StrictlyContracting : Rel A ℓ → (A → A) → DistanceFunction A → Set _StrictlyContracting _≈_ = Base.StrictlyContracting _≈_ _<_StrictlyContractingOnOrbits : Rel A ℓ → (A → A) → DistanceFunction A → Set _StrictlyContractingOnOrbits _≈_ = Base.StrictlyContractingOnOrbits _≈_ _<_
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for metrics over ℕ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Nat.Core whereopen import Data.Nat.Base using (ℕ)import Function.Metric.Core as Base-------------------------------------------------------------------------- DefinitionDistanceFunction : ∀ {a} → Set a → Set aDistanceFunction A = Base.DistanceFunction A ℕ
-------------------------------------------------------------------------- The Agda standard library---- Bundles for metrics over ℕ-------------------------------------------------------------------------- Unfortunately, unlike definitions and structures, the bundles over-- general metric spaces cannot be reused as it is impossible to-- constrain the image set to ℕ.{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Nat.Bundles whereopen import Data.Nat.Base hiding (suc; _⊔_)open import Function.Base using (const)open import Level using (Level; suc; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (isEquivalence)open import Function.Metric.Nat.Core using (DistanceFunction)open import Function.Metric.Nat.Structuresopen import Function.Metric.Bundles as Baseusing (GeneralMetric)-------------------------------------------------------------------------- Proto-metricrecord ProtoMetric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisProtoMetric : IsProtoMetric _≈_ dopen IsProtoMetric isProtoMetric public-------------------------------------------------------------------------- PreMetricrecord PreMetric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisPreMetric : IsPreMetric _≈_ dopen IsPreMetric isPreMetric publicprotoMetric : ProtoMetric a ℓprotoMetric = record{ isProtoMetric = isProtoMetric}-------------------------------------------------------------------------- QuasiSemiMetricrecord QuasiSemiMetric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisQuasiSemiMetric : IsQuasiSemiMetric _≈_ dopen IsQuasiSemiMetric isQuasiSemiMetric publicpreMetric : PreMetric a ℓpreMetric = record{ isPreMetric = isPreMetric}open PreMetric preMetric publicusing (protoMetric)-------------------------------------------------------------------------- SemiMetricrecord SemiMetric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisSemiMetric : IsSemiMetric _≈_ dopen IsSemiMetric isSemiMetric publicquasiSemiMetric : QuasiSemiMetric a ℓquasiSemiMetric = record{ isQuasiSemiMetric = isQuasiSemiMetric}open QuasiSemiMetric quasiSemiMetric publicusing (protoMetric; preMetric)-------------------------------------------------------------------------- Metricsrecord Metric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisMetric : IsMetric _≈_ dopen IsMetric isMetric publicsemiMetric : SemiMetric a ℓsemiMetric = record{ isSemiMetric = isSemiMetric}open SemiMetric semiMetric publicusing (protoMetric; preMetric; quasiSemiMetric)-------------------------------------------------------------------------- UltraMetricsrecord UltraMetric a ℓ : Set (suc (a ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓd : DistanceFunction CarrierisUltraMetric : IsUltraMetric _≈_ dopen IsUltraMetric isUltraMetric publicsemiMetric : SemiMetric a ℓsemiMetric = record{ isSemiMetric = isSemiMetric}open SemiMetric semiMetric publicusing (protoMetric; preMetric; quasiSemiMetric)
-------------------------------------------------------------------------- The Agda standard library---- Definitions of properties over distance functions-------------------------------------------------------------------------- The contents of this module should be accessed via `Function.Metric`.{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Definitions whereopen import Algebra.Core using (Op₂)open import Data.Product.Base using (∃)open import Function.Metric.Core using (DistanceFunction)open import Level using (Level)open import Relation.Binary.Core using (Rel; _Preserves₂_⟶_⟶_)open import Relation.Nullary.Negation using (¬_)privatevariablea i ℓ ℓ₁ ℓ₂ : LevelA : Set aI : Set i-------------------------------------------------------------------------- PropertiesCongruent : Rel A ℓ₁ → Rel I ℓ₂ → DistanceFunction A I → Set _Congruent _≈ₐ_ _≈ᵢ_ d = d Preserves₂ _≈ₐ_ ⟶ _≈ₐ_ ⟶ _≈ᵢ_Indiscernable : Rel A ℓ₁ → Rel I ℓ₂ → DistanceFunction A I → I → Set _Indiscernable _≈ₐ_ _≈ᵢ_ d 0# = ∀ {x y} → d x y ≈ᵢ 0# → x ≈ₐ yDefinite : Rel A ℓ₁ → Rel I ℓ₂ → DistanceFunction A I → I → Set _Definite _≈ₐ_ _≈ᵢ_ d 0# = ∀ {x y} → x ≈ₐ y → d x y ≈ᵢ 0#NonNegative : Rel I ℓ₂ → DistanceFunction A I → I → Set _NonNegative _≤_ d 0# = ∀ {x y} → 0# ≤ d x ySymmetric : Rel I ℓ → DistanceFunction A I → Set _Symmetric _≈_ d = ∀ x y → d x y ≈ d y xTriangleInequality : Rel I ℓ → Op₂ I → DistanceFunction A I → _TriangleInequality _≤_ _∙_ d = ∀ x y z → d x z ≤ (d x y ∙ d y z)Bounded : Rel I ℓ → DistanceFunction A I → Set _Bounded _≤_ d = ∃ λ n → ∀ x y → d x y ≤ nTranslationInvariant : Rel I ℓ₂ → Op₂ A → DistanceFunction A I → Set _TranslationInvariant _≈_ _∙_ d = ∀ {x y a} → d (x ∙ a) (y ∙ a) ≈ d x yContracting : Rel I ℓ → (A → A) → DistanceFunction A I → Set _Contracting _≤_ f d = ∀ x y → d (f x) (f y) ≤ d x yContractingOnOrbits : Rel I ℓ → (A → A) → DistanceFunction A I → Set _ContractingOnOrbits _≤_ f d = ∀ x → d (f x) (f (f x)) ≤ d x (f x)StrictlyContracting : Rel A ℓ₁ → Rel I ℓ₂ → (A → A) → DistanceFunction A I → Set _StrictlyContracting _≈_ _<_ f d = ∀ {x y} → ¬ (y ≈ x) → d (f x) (f y) < d x yStrictlyContractingOnOrbits : Rel A ℓ₁ → Rel I ℓ₂ → (A → A) → DistanceFunction A I → Set _StrictlyContractingOnOrbits _≈_ _<_ f d = ∀ {x} → ¬ (f x ≈ x) → d (f x) (f (f x)) < d x (f x)
-------------------------------------------------------------------------- The Agda standard library---- Core metric definitions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Core whereopen import Level using (Level)privatevariablea i : Level-------------------------------------------------------------------------- Distance functionsDistanceFunction : Set a → Set i → Set _DistanceFunction A I = A → A → I
-------------------------------------------------------------------------- The Agda standard library---- Bundles for metrics-------------------------------------------------------------------------- The contents of this module should be accessed via `Function.Metric`.{-# OPTIONS --cubical-compatible --safe #-}module Function.Metric.Bundles whereopen import Algebra.Core using (Op₂)open import Level using (Level; suc; _⊔_)open import Relation.Binary.Core using (Rel)open import Function.Metric.Structuresopen import Function.Metric.Core-------------------------------------------------------------------------- ProtoMetricrecord ProtoMetric (a i ℓ₁ ℓ₂ ℓ₃ : Level): Set (suc (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃)) whereinfix 4 _≈_ _≈ᵢ_ _≤_fieldCarrier : Set aImage : Set i_≈_ : Rel Carrier ℓ₁_≈ᵢ_ : Rel Image ℓ₂_≤_ : Rel Image ℓ₃0# : Imaged : DistanceFunction Carrier ImageisProtoMetric : IsProtoMetric _≈_ _≈ᵢ_ _≤_ 0# dopen IsProtoMetric isProtoMetric public-------------------------------------------------------------------------- PreMetricrecord PreMetric (a i ℓ₁ ℓ₂ ℓ₃ : Level): Set (suc (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃)) whereinfix 4 _≈_ _≈ᵢ_ _≤_fieldCarrier : Set aImage : Set i_≈_ : Rel Carrier ℓ₁_≈ᵢ_ : Rel Image ℓ₂_≤_ : Rel Image ℓ₃0# : Imaged : DistanceFunction Carrier ImageisPreMetric : IsPreMetric _≈_ _≈ᵢ_ _≤_ 0# dopen IsPreMetric isPreMetric publicprotoMetric : ProtoMetric a i ℓ₁ ℓ₂ ℓ₃protoMetric = record{ isProtoMetric = isProtoMetric}-------------------------------------------------------------------------- QuasiSemiMetricrecord QuasiSemiMetric (a i ℓ₁ ℓ₂ ℓ₃ : Level): Set (suc (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃)) whereinfix 4 _≈_ _≈ᵢ_ _≤_fieldCarrier : Set aImage : Set i_≈_ : Rel Carrier ℓ₁_≈ᵢ_ : Rel Image ℓ₂_≤_ : Rel Image ℓ₃0# : Imaged : DistanceFunction Carrier ImageisQuasiSemiMetric : IsQuasiSemiMetric _≈_ _≈ᵢ_ _≤_ 0# dopen IsQuasiSemiMetric isQuasiSemiMetric publicpreMetric : PreMetric a i ℓ₁ ℓ₂ ℓ₃preMetric = record{ isPreMetric = isPreMetric}open PreMetric preMetric publicusing (protoMetric)-------------------------------------------------------------------------- SemiMetricrecord SemiMetric (a i ℓ₁ ℓ₂ ℓ₃ : Level): Set (suc (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃)) whereinfix 4 _≈_ _≈ᵢ_ _≤_fieldCarrier : Set aImage : Set i_≈_ : Rel Carrier ℓ₁_≈ᵢ_ : Rel Image ℓ₂_≤_ : Rel Image ℓ₃0# : Imaged : DistanceFunction Carrier ImageisSemiMetric : IsSemiMetric _≈_ _≈ᵢ_ _≤_ 0# dopen IsSemiMetric isSemiMetric publicquasiSemiMetric : QuasiSemiMetric a i ℓ₁ ℓ₂ ℓ₃quasiSemiMetric = record{ isQuasiSemiMetric = isQuasiSemiMetric}open QuasiSemiMetric quasiSemiMetric publicusing (protoMetric; preMetric)-------------------------------------------------------------------------- GeneralMetric-- Note that this package is not necessarily a metric in the classical-- sense as there is no way to ensure that the _∙_ operator really-- represents addition. See `Function.Metric.Nat` and-- `Function.Metric.Rational` for more specialised `Metric` and-- `UltraMetric` packages.-- See the discussion accompanying the `IsGeneralMetric` structure for-- more details.record GeneralMetric (a i ℓ₁ ℓ₂ ℓ₃ : Level): Set (suc (a ⊔ i ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃)) whereinfix 4 _≈_ _≈ᵢ_ _≤_infixl 6 _∙_fieldCarrier : Set aImage : Set i_≈_ : Rel Carrier ℓ₁_≈ᵢ_ : Rel Image ℓ₂_≤_ : Rel Image ℓ₃0# : Image_∙_ : Op₂ Imaged : DistanceFunction Carrier ImageisGeneralMetric : IsGeneralMetric _≈_ _≈ᵢ_ _≤_ 0# _∙_ dopen IsGeneralMetric isGeneralMetric publicsemiMetric : SemiMetric a i ℓ₁ ℓ₂ ℓ₃semiMetric = record{ isSemiMetric = isSemiMetric}open SemiMetric semiMetric publicusing (protoMetric; preMetric; quasiSemiMetric)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.LeftInverse where{-# WARNING_ON_IMPORT"Function.LeftInverse was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Levelimport Relation.Binary.Reasoning.Setoid as EqReasoningopen import Relation.Binary.Bundles using (Setoid)open import Function.Equality as Equsing (_⟶_; _⟨$⟩_) renaming (_∘_ to _⟪∘⟫_)open import Function.Equivalence using (Equivalence)open import Function.Injection using (Injective; Injection)open import Relation.Binary.PropositionalEquality as ≡ using (_≡_)-------------------------------------------------------------------------- Left and right inverses._LeftInverseOf_ :∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →To ⟶ From → From ⟶ To → Set __LeftInverseOf_ {From = From} f g = ∀ x → f ⟨$⟩ (g ⟨$⟩ x) ≈ xwhere open Setoid From{-# WARNING_ON_USAGE _LeftInverseOf_"Warning: _LeftInverseOf_ was deprecated in v2.0.Please use Function.(Structures.)IsRightInverse instead."#-}_RightInverseOf_ :∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →To ⟶ From → From ⟶ To → Set _f RightInverseOf g = g LeftInverseOf f{-# WARNING_ON_USAGE _RightInverseOf_"Warning: _RightInverseOf_ was deprecated in v2.0.Please use Function.(Structures.)IsLeftInverse instead."#-}-------------------------------------------------------------------------- The set of all left inverses between two setoids.record LeftInverse {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Tofrom : To ⟶ Fromleft-inverse-of : from LeftInverseOf toprivateopen module F = Setoid Fromopen module T = Setoid Toopen EqReasoning Frominjective : Injective toinjective {x} {y} eq = beginx ≈⟨ F.sym (left-inverse-of x) ⟩from ⟨$⟩ (to ⟨$⟩ x) ≈⟨ Eq.cong from eq ⟩from ⟨$⟩ (to ⟨$⟩ y) ≈⟨ left-inverse-of y ⟩y ∎injection : Injection From Toinjection = record { to = to; injective = injective }equivalence : Equivalence From Toequivalence = record{ to = to; from = from}to-from : ∀ {x y} → to ⟨$⟩ x T.≈ y → from ⟨$⟩ y F.≈ xto-from {x} {y} to-x≈y = beginfrom ⟨$⟩ y ≈⟨ Eq.cong from (T.sym to-x≈y) ⟩from ⟨$⟩ (to ⟨$⟩ x) ≈⟨ left-inverse-of x ⟩x ∎{-# WARNING_ON_USAGE LeftInverse"Warning: LeftInverse was deprecated in v2.0.Please use Function.(Bundles.)RightInverse instead."#-}-- The set of all right inverses between two setoids.RightInverse : ∀ {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) → Set _RightInverse From To = LeftInverse To From{-# WARNING_ON_USAGE RightInverse"Warning: RightInverse was deprecated in v2.0.Please use Function.(Bundles.)LeftInverse instead."#-}-------------------------------------------------------------------------- The set of all left inverses from one set to another (i.e. left-- inverses with propositional equality).---- Read A ↞ B as "surjection from B to A".infix 3 _↞__↞_ : ∀ {f t} → Set f → Set t → Set _From ↞ To = LeftInverse (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _↞_"Warning: _↞_ was deprecated in v2.0.Please use Function.(Bundles.)_↪_ instead."#-}leftInverse : ∀ {f t} {From : Set f} {To : Set t} →(to : From → To) (from : To → From) →(∀ x → from (to x) ≡ x) →From ↞ ToleftInverse to from invˡ = record{ to = Eq.→-to-⟶ to; from = Eq.→-to-⟶ from; left-inverse-of = invˡ}{-# WARNING_ON_USAGE leftInverse"Warning: leftInverse was deprecated in v2.0.Please use Function.(Bundles.)mk↪ instead."#-}-------------------------------------------------------------------------- Identity and composition.id : ∀ {s₁ s₂} {S : Setoid s₁ s₂} → LeftInverse S Sid {S = S} = record{ to = Eq.id; from = Eq.id; left-inverse-of = λ _ → Setoid.refl S}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use either Function.Properties.RightInverse.refl orFunction.Construct.Identity.rightInverse instead."#-}infixr 9 _∘__∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂}{F : Setoid f₁ f₂} {M : Setoid m₁ m₂} {T : Setoid t₁ t₂} →LeftInverse M T → LeftInverse F M → LeftInverse F T_∘_ {F = F} f g = record{ to = to f ⟪∘⟫ to g; from = from g ⟪∘⟫ from f; left-inverse-of = λ x → beginfrom g ⟨$⟩ (from f ⟨$⟩ (to f ⟨$⟩ (to g ⟨$⟩ x))) ≈⟨ Eq.cong (from g) (left-inverse-of f (to g ⟨$⟩ x)) ⟩from g ⟨$⟩ (to g ⟨$⟩ x) ≈⟨ left-inverse-of g x ⟩x ∎}whereopen LeftInverseopen EqReasoning F{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use either Function.Properties.RightInverse.trans orFunction.Construct.Composition.rightInverse instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Inverse where{-# WARNING_ON_IMPORT"Function.Inverse was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Levelopen import Function.Base using (flip)open import Function.Bijection hiding (id; _∘_; bijection)open import Function.Equality as Fusing (_⟶_) renaming (_∘_ to _⟪∘⟫_)open import Function.LeftInverse as Left hiding (id; _∘_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Reflexive; TransFlip; Sym)open import Relation.Binary.PropositionalEquality as ≡ using (_≗_; _≡_)open import Relation.Unary using (Pred)-------------------------------------------------------------------------- Inversesrecord _InverseOf_ {f₁ f₂ t₁ t₂}{From : Setoid f₁ f₂} {To : Setoid t₁ t₂}(from : To ⟶ From) (to : From ⟶ To) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldleft-inverse-of : from LeftInverseOf toright-inverse-of : from RightInverseOf to{-# WARNING_ON_USAGE _InverseOf_"Warning: _InverseOf_ was deprecated in v2.0.Please use Function.(Structures.)IsInverse instead."#-}-------------------------------------------------------------------------- The set of all inverses between two setoidsrecord Inverse {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Tofrom : To ⟶ Frominverse-of : from InverseOf toopen _InverseOf_ inverse-of publicleft-inverse : LeftInverse From Toleft-inverse = record{ to = to; from = from; left-inverse-of = left-inverse-of}open LeftInverse left-inverse publicusing (injective; injection)bijection : Bijection From Tobijection = record{ to = to; bijective = record{ injective = injective; surjective = record{ from = from; right-inverse-of = right-inverse-of}}}open Bijection bijection publicusing (equivalence; surjective; surjection; right-inverse;to-from; from-to){-# WARNING_ON_USAGE Inverse"Warning: Inverse was deprecated in v2.0.Please use Function.(Bundles.)Inverse instead."#-}-------------------------------------------------------------------------- The set of all inverses between two sets (i.e. inverses with-- propositional equality)infix 3 _↔_ _↔̇__↔_ : ∀ {f t} → Set f → Set t → Set _From ↔ To = Inverse (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _↔_"Warning: _↔_ was deprecated in v2.0.Please use Function.(Bundles.)_↔_ instead."#-}_↔̇_ : ∀ {i f t} {I : Set i} → Pred I f → Pred I t → Set _From ↔̇ To = ∀ {i} → From i ↔ To i{-# WARNING_ON_USAGE _↔̇_"Warning: _↔̇_ was deprecated in v2.0.Please use Function.Indexed.(Bundles.)_↔ᵢ_ instead."#-}inverse : ∀ {f t} {From : Set f} {To : Set t} →(to : From → To) (from : To → From) →(∀ x → from (to x) ≡ x) →(∀ x → to (from x) ≡ x) →From ↔ Toinverse to from from∘to to∘from = record{ to = F.→-to-⟶ to; from = F.→-to-⟶ from; inverse-of = record{ left-inverse-of = from∘to; right-inverse-of = to∘from}}{-# WARNING_ON_USAGE inverse"Warning: inverse was deprecated in v2.0.Please use Function.(Bundles.)mk↔ instead."#-}-------------------------------------------------------------------------- If two setoids are in bijective correspondence, then there is an-- inverse between themfromBijection :∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →Bijection From To → Inverse From TofromBijection b = record{ to = Bijection.to b; from = Bijection.from b; inverse-of = record{ left-inverse-of = Bijection.left-inverse-of b; right-inverse-of = Bijection.right-inverse-of b}}-------------------------------------------------------------------------- Inverse is an equivalence relation-- Reflexivityid : ∀ {s₁ s₂} → Reflexive (Inverse {s₁} {s₂})id {x = S} = record{ to = F.id; from = F.id; inverse-of = record{ left-inverse-of = LeftInverse.left-inverse-of id′; right-inverse-of = LeftInverse.left-inverse-of id′}} where id′ = Left.id {S = S}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use either Function.Properties.Inverse.refl orFunction.Construct.Identity.inverse instead."#-}-- Transitivityinfixr 9 _∘__∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂} →TransFlip (Inverse {f₁} {f₂} {m₁} {m₂})(Inverse {m₁} {m₂} {t₁} {t₂})(Inverse {f₁} {f₂} {t₁} {t₂})f ∘ g = record{ to = to f ⟪∘⟫ to g; from = from g ⟪∘⟫ from f; inverse-of = record{ left-inverse-of = LeftInverse.left-inverse-of (Left._∘_ (left-inverse f) (left-inverse g)); right-inverse-of = LeftInverse.left-inverse-of (Left._∘_ (right-inverse g) (right-inverse f))}} where open Inverse{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use either Function.Properties.Inverse.trans orFunction.Construct.Composition.inverse instead."#-}-- Symmetry.sym : ∀ {f₁ f₂ t₁ t₂} →Sym (Inverse {f₁} {f₂} {t₁} {t₂}) (Inverse {t₁} {t₂} {f₁} {f₂})sym inv = record{ from = to; to = from; inverse-of = record{ left-inverse-of = right-inverse-of; right-inverse-of = left-inverse-of}} where open Inverse inv{-# WARNING_ON_USAGE sym"Warning: sym was deprecated in v2.0.Please use either Function.Properties.Inverse.sym orFunction.Construct.Symmetry.inverse instead."#-}-------------------------------------------------------------------------- Transformationsmap : ∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂}{f₁′ f₂′ t₁′ t₂′}{From′ : Setoid f₁′ f₂′} {To′ : Setoid t₁′ t₂′} →(t : (From ⟶ To) → (From′ ⟶ To′)) →(f : (To ⟶ From) → (To′ ⟶ From′)) →(∀ {to from} → from InverseOf to → f from InverseOf t to) →Inverse From To → Inverse From′ To′map t f pres eq = record{ to = t to; from = f from; inverse-of = pres inverse-of} where open Inverse eqzip : ∀ {f₁₁ f₂₁ t₁₁ t₂₁}{From₁ : Setoid f₁₁ f₂₁} {To₁ : Setoid t₁₁ t₂₁}{f₁₂ f₂₂ t₁₂ t₂₂}{From₂ : Setoid f₁₂ f₂₂} {To₂ : Setoid t₁₂ t₂₂}{f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →(t : (From₁ ⟶ To₁) → (From₂ ⟶ To₂) → (From ⟶ To)) →(f : (To₁ ⟶ From₁) → (To₂ ⟶ From₂) → (To ⟶ From)) →(∀ {to₁ from₁ to₂ from₂} →from₁ InverseOf to₁ → from₂ InverseOf to₂ →f from₁ from₂ InverseOf t to₁ to₂) →Inverse From₁ To₁ → Inverse From₂ To₂ → Inverse From Tozip t f pres eq₁ eq₂ = record{ to = t (to eq₁) (to eq₂); from = f (from eq₁) (from eq₂); inverse-of = pres (inverse-of eq₁) (inverse-of eq₂)} where open Inverse
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Injection where{-# WARNING_ON_IMPORT"Function.Injection was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Function.Base as Fun using () renaming (_∘_ to _⟨∘⟩_)open import Levelopen import Relation.Binary.Bundles using (Setoid)open import Function.Equality as Fusing (_⟶_; _⟨$⟩_ ; Π) renaming (_∘_ to _⟪∘⟫_)open import Relation.Binary.PropositionalEquality as ≡ using (_≡_)-------------------------------------------------------------------------- Injective functionsInjective : ∀ {a₁ a₂ b₁ b₂} {A : Setoid a₁ a₂} {B : Setoid b₁ b₂} →A ⟶ B → Set _Injective {A = A} {B} f = ∀ {x y} → f ⟨$⟩ x ≈₂ f ⟨$⟩ y → x ≈₁ ywhereopen Setoid A renaming (_≈_ to _≈₁_)open Setoid B renaming (_≈_ to _≈₂_){-# WARNING_ON_USAGE Injective"Warning: Injective was deprecated in v2.0.Please use Function.(Definitions.)Injective instead."#-}-------------------------------------------------------------------------- The set of all injections between two setoidsrecord Injection {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Toinjective : Injective toopen Π to public{-# WARNING_ON_USAGE Injection"Warning: Injection was deprecated in v2.0.Please use Function.(Bundles.)Injection instead."#-}-------------------------------------------------------------------------- The set of all injections from one set to another (i.e. injections-- with propositional equality)infix 3 _↣__↣_ : ∀ {f t} → Set f → Set t → Set _From ↣ To = Injection (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _↣_"Warning: _↣_ was deprecated in v2.0.Please use Function.(Bundles.)_↣_ instead."#-}injection : ∀ {f t} {From : Set f} {To : Set t} → (to : From → To) →(∀ {x y} → to x ≡ to y → x ≡ y) → From ↣ Toinjection to injective = record{ to = record{ _⟨$⟩_ = to; cong = ≡.cong to}; injective = injective}{-# WARNING_ON_USAGE injection"Warning: injection was deprecated in v2.0.Please use Function.(Bundles.)mk↣ instead."#-}-------------------------------------------------------------------------- Identity and composition.infixr 9 _∘_id : ∀ {s₁ s₂} {S : Setoid s₁ s₂} → Injection S Sid = record{ to = F.id; injective = Fun.id}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use Function.Properties.Injection.refl orFunction.Construct.Identity.injection instead."#-}_∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂}{F : Setoid f₁ f₂} {M : Setoid m₁ m₂} {T : Setoid t₁ t₂} →Injection M T → Injection F M → Injection F Tf ∘ g = record{ to = to f ⟪∘⟫ to g; injective = (λ {_} → injective g) ⟨∘⟩ injective f} where open Injection{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use Function.Properties.Injection.trans orFunction.Construct.Composition.injection instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Function setoids and related constructions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Indexed.Relation.Binary.Equality whereopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Indexed.Heterogeneous using (IndexedSetoid)-- A variant of setoid which uses the propositional equality setoid-- for the domain, and a more convenient definition of _≈_.≡-setoid : ∀ {f t₁ t₂} (From : Set f) → IndexedSetoid From t₁ t₂ → Setoid _ _≡-setoid From To = record{ Carrier = (x : From) → Carrier x; _≈_ = λ f g → ∀ x → f x ≈ g x; isEquivalence = record{ refl = λ {f} x → refl; sym = λ f∼g x → sym (f∼g x); trans = λ f∼g g∼h x → trans (f∼g x) (g∼h x)}} where open IndexedSetoid To
-------------------------------------------------------------------------- The Agda standard library---- Operations on Relations for Indexed sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Indexed.Bundles whereopen import Relation.Unary using (Pred)open import Function.Bundles using (_⟶_; _↣_; _↠_; _⤖_; _⇔_; _↩_; _↪_; _↩↪_; _↔_)open import Relation.Binary.Core hiding (_⇔_)open import Level using (Level)privatevariablea b i : LevelI : Set i-------------------------------------------------------------------------- Bundles specialised for lifting relations to indexed sets------------------------------------------------------------------------infix 3 _⟶ᵢ_ _↣ᵢ_ _↠ᵢ_ _⤖ᵢ_ _⇔ᵢ_ _↩ᵢ_ _↪ᵢ_ _↩↪ᵢ_ _↔ᵢ__⟶ᵢ_ : Pred I a → Pred I b → Set _A ⟶ᵢ B = ∀ {i} → A i ⟶ B i_↣ᵢ_ : Pred I a → Pred I b → Set _A ↣ᵢ B = ∀ {i} → A i ↣ B i_↠ᵢ_ : Pred I a → Pred I b → Set _A ↠ᵢ B = ∀ {i} → A i ↠ B i_⤖ᵢ_ : Pred I a → Pred I b → Set _A ⤖ᵢ B = ∀ {i} → A i ⤖ B i_⇔ᵢ_ : Pred I a → Pred I b → Set _A ⇔ᵢ B = ∀ {i} → A i ⇔ B i_↩ᵢ_ : Pred I a → Pred I b → Set _A ↩ᵢ B = ∀ {i} → A i ↩ B i_↪ᵢ_ : Pred I a → Pred I b → Set _A ↪ᵢ B = ∀ {i} → A i ↪ B i_↩↪ᵢ_ : Pred I a → Pred I b → Set _A ↩↪ᵢ B = ∀ {i} → A i ↩↪ B i_↔ᵢ_ : Pred I a → Pred I b → Set _A ↔ᵢ B = ∀ {i} → A i ↔ B i
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the identity function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Identity.Effectful whereopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Effect.Comonadopen import Function.Base using (id; _∘′_; _|>′_; _$′_; flip)open import Levelprivatevariableℓ : LevelIdentity : (A : Set ℓ) → Set ℓIdentity A = Afunctor : RawFunctor {ℓ} Identityfunctor = record{ _<$>_ = id}applicative : RawApplicative {ℓ} Identityapplicative = record{ rawFunctor = functor; pure = id; _<*>_ = _$′_}monad : RawMonad {ℓ} Identitymonad = record{ rawApplicative = applicative; _>>=_ = _|>′_}comonad : RawComonad {ℓ} Identitycomonad = record{ extract = id; extend = _$′_}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Function.Identity.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Identity.Categorical whereopen import Function.Identity.Effectful public{-# WARNING_ON_IMPORT"Function.Identity.Categorical was deprecated in v2.0.Use Function.Identity.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.HalfAdjointEquivalence where{-# WARNING_ON_IMPORT"Function.HalfAdjointEquivalence was deprecated in v2.0.Use Function.Properties.Inverse.HalfAdjointEquivalence instead."#-}open import Function.Baseopen import Function.Equality using (_⟨$⟩_)open import Function.Inverse as Inv using (_↔_; module Inverse)open import Levelopen import Relation.Binary.PropositionalEquality-- Half adjoint equivalences (see the HoTT book).infix 4 _≃_record _≃_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) wherefieldto : A → Bfrom : B → Aleft-inverse-of : ∀ x → from (to x) ≡ xright-inverse-of : ∀ x → to (from x) ≡ xleft-right :∀ x → cong to (left-inverse-of x) ≡ right-inverse-of (to x)-- Half adjoint equivalences can be turned into inverses.inverse : A ↔ Binverse = Inv.inverse to from left-inverse-of right-inverse-of-- The forward direction of a half adjoint equivalence is injective.injective : ∀ {x y} → to x ≡ to y → x ≡ yinjective {x} {y} to-x≡to-y =x ≡⟨ sym (left-inverse-of _) ⟩from (to x) ≡⟨ cong from to-x≡to-y ⟩from (to y) ≡⟨ left-inverse-of _ ⟩y ∎whereopen ≡-Reasoning-- Inverses can be turned into half adjoint equivalences.---- (This proof is based on one in the HoTT book.)↔→≃ : ∀ {a b} {A : Set a} {B : Set b} → A ↔ B → A ≃ B↔→≃ A↔B = record{ to = to ⟨$⟩_; from = from ⟨$⟩_; left-inverse-of = left-inverse-of; right-inverse-of = right-inverse-of; left-right = left-right}whereopen ≡-Reasoningopen module A↔B = Inverse A↔B using (to; from; left-inverse-of)right-inverse-of : ∀ x → to ⟨$⟩ (from ⟨$⟩ x) ≡ xright-inverse-of x =to ⟨$⟩ (from ⟨$⟩ x) ≡⟨ sym (A↔B.right-inverse-of _) ⟩to ⟨$⟩ (from ⟨$⟩ (to ⟨$⟩ (from ⟨$⟩ x))) ≡⟨ cong (to ⟨$⟩_) (left-inverse-of _) ⟩to ⟨$⟩ (from ⟨$⟩ x) ≡⟨ A↔B.right-inverse-of _ ⟩x ∎left-right :∀ x →cong (to ⟨$⟩_) (left-inverse-of x) ≡ right-inverse-of (to ⟨$⟩ x)left-right x =cong (to ⟨$⟩_) (left-inverse-of x) ≡⟨⟩trans refl (cong (to ⟨$⟩_) (left-inverse-of _)) ≡⟨ cong (λ p → trans p (cong (to ⟨$⟩_) _))(sym (trans-symˡ (A↔B.right-inverse-of _))) ⟩trans (trans (sym (A↔B.right-inverse-of _))(A↔B.right-inverse-of _))(cong (to ⟨$⟩_) (left-inverse-of _)) ≡⟨ trans-assoc (sym (A↔B.right-inverse-of _)) ⟩trans (sym (A↔B.right-inverse-of _))(trans (A↔B.right-inverse-of _)(cong (to ⟨$⟩_) (left-inverse-of _))) ≡⟨ cong (trans (sym (A↔B.right-inverse-of _))) lemma ⟩trans (sym (A↔B.right-inverse-of _))(trans (cong (to ⟨$⟩_) (left-inverse-of _))(trans (A↔B.right-inverse-of _) refl)) ≡⟨⟩right-inverse-of (to ⟨$⟩ x) ∎wherelemma =trans (A↔B.right-inverse-of _)(cong (to ⟨$⟩_) (left-inverse-of _)) ≡⟨ cong (trans (A↔B.right-inverse-of _)) (sym (cong-id _)) ⟩trans (A↔B.right-inverse-of _)(cong id (cong (to ⟨$⟩_) (left-inverse-of _))) ≡⟨ sym (naturality A↔B.right-inverse-of) ⟩trans (cong ((to ⟨$⟩_) ∘ (from ⟨$⟩_))(cong (to ⟨$⟩_) (left-inverse-of _)))(A↔B.right-inverse-of _) ≡⟨ cong (λ p → trans p (A↔B.right-inverse-of _))(sym (cong-∘ _)) ⟩trans (cong ((to ⟨$⟩_) ∘ (from ⟨$⟩_) ∘ (to ⟨$⟩_))(left-inverse-of _))(A↔B.right-inverse-of _) ≡⟨ cong (λ p → trans p (A↔B.right-inverse-of _))(cong-∘ _) ⟩trans (cong (to ⟨$⟩_)(cong ((from ⟨$⟩_) ∘ (to ⟨$⟩_))(left-inverse-of _)))(A↔B.right-inverse-of _) ≡⟨ cong (λ p → trans (cong (to ⟨$⟩_) p) _)(cong-≡id left-inverse-of) ⟩trans (cong (to ⟨$⟩_) (left-inverse-of _))(A↔B.right-inverse-of _) ≡⟨ cong (trans (cong (to ⟨$⟩_) (left-inverse-of _)))(sym (trans-reflʳ _)) ⟩trans (cong (to ⟨$⟩_) (left-inverse-of _))(trans (A↔B.right-inverse-of _) refl) ∎
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Equivalence where{-# WARNING_ON_IMPORT"Function.Equivalence was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Function.Base using (flip)open import Function.Equality as Fusing (_⟶_; _⟨$⟩_; →-to-⟶) renaming (_∘_ to _⟪∘⟫_)open import Levelopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Reflexive; TransFlip; Sym)import Relation.Binary.PropositionalEquality as ≡-------------------------------------------------------------------------- Setoid equivalencerecord Equivalence {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Tofrom : To ⟶ From{-# WARNING_ON_USAGE Equivalence"Warning: Equivalence was deprecated in v2.0.Please use Function.(Bundles.)Equivalence instead."#-}-------------------------------------------------------------------------- The set of all equivalences between two sets (i.e. equivalences-- with propositional equality)infix 3 _⇔__⇔_ : ∀ {f t} → Set f → Set t → Set _From ⇔ To = Equivalence (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _⇔_"Warning: _⇔_ was deprecated in v2.0.Please use Function.(Bundles.)_⇔_ instead."#-}equivalence : ∀ {f t} {From : Set f} {To : Set t} →(From → To) → (To → From) → From ⇔ Toequivalence to from = record{ to = →-to-⟶ to; from = →-to-⟶ from}{-# WARNING_ON_USAGE equivalence"Warning: equivalence was deprecated in v2.0.Please use Function.Properties.Equivalence.mkEquivalence instead."#-}-------------------------------------------------------------------------- Equivalence is an equivalence relation-- Identity and composition (reflexivity and transitivity).id : ∀ {s₁ s₂} → Reflexive (Equivalence {s₁} {s₂})id {x = S} = record{ to = F.id; from = F.id}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use Function.Properties.Equivalence.refl orFunction.Construct.Identity.equivalence instead."#-}infixr 9 _∘__∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂} →TransFlip (Equivalence {f₁} {f₂} {m₁} {m₂})(Equivalence {m₁} {m₂} {t₁} {t₂})(Equivalence {f₁} {f₂} {t₁} {t₂})f ∘ g = record{ to = to f ⟪∘⟫ to g; from = from g ⟪∘⟫ from f} where open Equivalence{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use Function.Properties.Equivalence.trans orFunction.Construct.Composition.equivalence instead."#-}-- Symmetry.sym : ∀ {f₁ f₂ t₁ t₂} →Sym (Equivalence {f₁} {f₂} {t₁} {t₂})(Equivalence {t₁} {t₂} {f₁} {f₂})sym eq = record{ from = to; to = from} where open Equivalence eq{-# WARNING_ON_USAGE sym"Warning: sym was deprecated in v2.0.Please use Function.Properties.Equivalence.sym orFunction.Construct.Symmetry.equivalence instead."#-}-- For fixed universe levels we can construct setoids.setoid : (s₁ s₂ : Level) → Setoid (suc (s₁ ⊔ s₂)) (s₁ ⊔ s₂)setoid s₁ s₂ = record{ Carrier = Setoid s₁ s₂; _≈_ = Equivalence; isEquivalence = record{ refl = id; sym = sym; trans = flip _∘_}}{-# WARNING_ON_USAGE setoid"Warning: setoid was deprecated in v2.0.Please use Function.Properties.Equivalence.setoid instead."#-}⇔-setoid : (ℓ : Level) → Setoid (suc ℓ) ℓ⇔-setoid ℓ = record{ Carrier = Set ℓ; _≈_ = _⇔_; isEquivalence = record{ refl = id; sym = sym; trans = flip _∘_}}{-# WARNING_ON_USAGE ⇔-setoid"Warning: ⇔-setoid was deprecated in v2.0.Please use Function.Properties.Equivalence.⇔-setoid instead."#-}-------------------------------------------------------------------------- Transformationsmap : ∀ {f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂}{f₁′ f₂′ t₁′ t₂′}{From′ : Setoid f₁′ f₂′} {To′ : Setoid t₁′ t₂′} →((From ⟶ To) → (From′ ⟶ To′)) →((To ⟶ From) → (To′ ⟶ From′)) →Equivalence From To → Equivalence From′ To′map t f eq = record { to = t to; from = f from }where open Equivalence eqzip : ∀ {f₁₁ f₂₁ t₁₁ t₂₁}{From₁ : Setoid f₁₁ f₂₁} {To₁ : Setoid t₁₁ t₂₁}{f₁₂ f₂₂ t₁₂ t₂₂}{From₂ : Setoid f₁₂ f₂₂} {To₂ : Setoid t₁₂ t₂₂}{f₁ f₂ t₁ t₂} {From : Setoid f₁ f₂} {To : Setoid t₁ t₂} →((From₁ ⟶ To₁) → (From₂ ⟶ To₂) → (From ⟶ To)) →((To₁ ⟶ From₁) → (To₂ ⟶ From₂) → (To ⟶ From)) →Equivalence From₁ To₁ → Equivalence From₂ To₂ →Equivalence From Tozip t f eq₁ eq₂ =record { to = t (to eq₁) (to eq₂); from = f (from eq₁) (from eq₂) }where open Equivalence
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Equality where{-# WARNING_ON_IMPORT"Function.Equality was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}import Function.Base as Funopen import Level using (Level; _⊔_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Indexed.Heterogeneoususing (IndexedSetoid; _=[_]⇒_)import Relation.Binary.Indexed.Heterogeneous.Construct.Trivialas Trivialimport Relation.Binary.PropositionalEquality.Core as ≡import Relation.Binary.PropositionalEquality.Properties as ≡-------------------------------------------------------------------------- Functions which preserve equalityrecord Π {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂)(To : IndexedSetoid (Setoid.Carrier From) t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) whereinfixl 5 _⟨$⟩_field_⟨$⟩_ : (x : Setoid.Carrier From) → IndexedSetoid.Carrier To xcong : Setoid._≈_ From =[ _⟨$⟩_ ]⇒ IndexedSetoid._≈_ To{-# WARNING_ON_USAGE Π"Warning: Π was deprecated in v2.0.Please use Function.Dependent.Bundles.Func instead."#-}open Π publicinfixr 0 _⟶__⟶_ : ∀ {f₁ f₂ t₁ t₂} → Setoid f₁ f₂ → Setoid t₁ t₂ → Set _From ⟶ To = Π From (Trivial.indexedSetoid To){-# WARNING_ON_USAGE _⟶_"Warning: _⟶_ was deprecated in v2.0.Please use Function.(Bundles.)Func instead."#-}-------------------------------------------------------------------------- Identity and composition.id : ∀ {a₁ a₂} {A : Setoid a₁ a₂} → A ⟶ Aid = record { _⟨$⟩_ = Fun.id; cong = Fun.id }{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use Function.Construct.Identity.function instead."#-}infixr 9 _∘__∘_ : ∀ {a₁ a₂} {A : Setoid a₁ a₂}{b₁ b₂} {B : Setoid b₁ b₂}{c₁ c₂} {C : Setoid c₁ c₂} →B ⟶ C → A ⟶ B → A ⟶ Cf ∘ g = record{ _⟨$⟩_ = Fun._∘_ (_⟨$⟩_ f) (_⟨$⟩_ g); cong = Fun._∘_ (cong f) (cong g)}{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use Function.Construct.Composition.function instead."#-}-- Constant equality-preserving function.const : ∀ {a₁ a₂} {A : Setoid a₁ a₂}{b₁ b₂} {B : Setoid b₁ b₂} →Setoid.Carrier B → A ⟶ Bconst {B = B} b = record{ _⟨$⟩_ = Fun.const b; cong = Fun.const (Setoid.refl B)}{-# WARNING_ON_USAGE const"Warning: const was deprecated in v2.0.Please use Function.Construct.Constant.function instead."#-}-------------------------------------------------------------------------- Function setoids-- Dependent.setoid : ∀ {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) →IndexedSetoid (Setoid.Carrier From) t₁ t₂ →Setoid _ _setoid From To = record{ Carrier = Π From To; _≈_ = λ f g → ∀ {x y} → x ≈₁ y → f ⟨$⟩ x ≈₂ g ⟨$⟩ y; isEquivalence = record{ refl = λ {f} → cong f; sym = λ f∼g x∼y → To.sym (f∼g (From.sym x∼y)); trans = λ f∼g g∼h x∼y → To.trans (f∼g From.refl) (g∼h x∼y)}}whereopen module From = Setoid From using () renaming (_≈_ to _≈₁_)open module To = IndexedSetoid To using () renaming (_≈_ to _≈₂_)-- Non-dependent.infixr 0 _⇨__⇨_ : ∀ {f₁ f₂ t₁ t₂} → Setoid f₁ f₂ → Setoid t₁ t₂ → Setoid _ _From ⇨ To = setoid From (Trivial.indexedSetoid To)-- A variant of setoid which uses the propositional equality setoid-- for the domain, and a more convenient definition of _≈_.≡-setoid : ∀ {f t₁ t₂} (From : Set f) → IndexedSetoid From t₁ t₂ → Setoid _ _≡-setoid From To = record{ Carrier = (x : From) → Carrier x; _≈_ = λ f g → ∀ x → f x ≈ g x; isEquivalence = record{ refl = λ {f} x → refl; sym = λ f∼g x → sym (f∼g x); trans = λ f∼g g∼h x → trans (f∼g x) (g∼h x)}} where open IndexedSetoid To-- Parameter swapping function.flip : ∀ {a₁ a₂} {A : Setoid a₁ a₂}{b₁ b₂} {B : Setoid b₁ b₂}{c₁ c₂} {C : Setoid c₁ c₂} →A ⟶ B ⇨ C → B ⟶ A ⇨ Cflip {B = B} f = record{ _⟨$⟩_ = λ b → record{ _⟨$⟩_ = λ a → f ⟨$⟩ a ⟨$⟩ b; cong = λ a₁≈a₂ → cong f a₁≈a₂ (Setoid.refl B) }; cong = λ b₁≈b₂ a₁≈a₂ → cong f a₁≈a₂ b₁≈b₂}→-to-⟶ : ∀ {a b ℓ} {A : Set a} {B : Setoid b ℓ} →(A → Setoid.Carrier B) → ≡.setoid A ⟶ B→-to-⟶ {B = B} to = record{ _⟨$⟩_ = to; cong = λ { ≡.refl → Setoid.refl B }}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundles using (Setoid)module Function.Endomorphism.Setoid {c e} (S : Setoid c e) where{-# WARNING_ON_IMPORT"Function.Endomorphism.Setoid was deprecated in v2.1.Use Function.Endo.Setoid instead."#-}open import Agda.Builtin.Equalityopen import Algebraopen import Algebra.Structuresopen import Algebra.Morphism; open Definitionsopen import Function.Equality using (setoid; _⟶_; id; _∘_; cong)open import Data.Nat.Base using (ℕ; _+_); open ℕopen import Data.Nat.Propertiesopen import Data.Product.Base using (_,_)import Relation.Binary.Indexed.Heterogeneous.Construct.Trivial as Trivialprivatemodule E = Setoid (setoid S (Trivial.indexedSetoid S))open E hiding (refl)-------------------------------------------------------------------------- Basic type and functionsEndo : Set _Endo = S ⟶ Sinfixr 8 _^__^_ : Endo → ℕ → Endof ^ zero = idf ^ suc n = f ∘ (f ^ n)^-cong₂ : ∀ f → (f ^_) Preserves _≡_ ⟶ _≈_^-cong₂ f {n} refl = cong (f ^ n)^-homo : ∀ f → Homomorphic₂ ℕ Endo _≈_ (f ^_) _+_ _∘_^-homo f zero n x≈y = cong (f ^ n) x≈y^-homo f (suc m) n x≈y = cong f (^-homo f m n x≈y)-------------------------------------------------------------------------- Structures∘-isMagma : IsMagma _≈_ _∘_∘-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = λ g f x → g (f x)}∘-magma : Magma _ _∘-magma = record { isMagma = ∘-isMagma }∘-isSemigroup : IsSemigroup _≈_ _∘_∘-isSemigroup = record{ isMagma = ∘-isMagma; assoc = λ h g f x≈y → cong h (cong g (cong f x≈y))}∘-semigroup : Semigroup _ _∘-semigroup = record { isSemigroup = ∘-isSemigroup }∘-id-isMonoid : IsMonoid _≈_ _∘_ id∘-id-isMonoid = record{ isSemigroup = ∘-isSemigroup; identity = cong , cong}∘-id-monoid : Monoid _ _∘-id-monoid = record { isMonoid = ∘-id-isMonoid }-------------------------------------------------------------------------- Homomorphism^-isSemigroupMorphism : ∀ f → IsSemigroupMorphism +-semigroup ∘-semigroup (f ^_)^-isSemigroupMorphism f = record{ ⟦⟧-cong = ^-cong₂ f; ∙-homo = ^-homo f}^-isMonoidMorphism : ∀ f → IsMonoidMorphism +-0-monoid ∘-id-monoid (f ^_)^-isMonoidMorphism f = record{ sm-homo = ^-isSemigroupMorphism f; ε-homo = λ x≈y → x≈y}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Endomorphism.Propositional {a} (A : Set a) where{-# WARNING_ON_IMPORT"Function.Endomorphism.Propositional was deprecated in v2.1.Use Function.Endo.Propositional instead."#-}open import Algebraopen import Algebra.Morphism; open Definitionsopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Nat.Properties using (+-0-monoid; +-semigroup)open import Data.Product.Base using (_,_)open import Function.Base using (id; _∘′_; _∋_)open import Function.Equality using (_⟨$⟩_)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂)import Relation.Binary.PropositionalEquality.Properties as ≡import Function.Endomorphism.Setoid (≡.setoid A) as SetoidEndo : Set aEndo = A → A-------------------------------------------------------------------------- Conversion back and forth with the Setoid-based notion of EndomorphismfromSetoidEndo : Setoid.Endo → EndofromSetoidEndo = _⟨$⟩_toSetoidEndo : Endo → Setoid.EndotoSetoidEndo f = record{ _⟨$⟩_ = f; cong = cong f}-------------------------------------------------------------------------- N-th compositioninfixr 8 _^__^_ : Endo → ℕ → Endof ^ zero = idf ^ suc n = f ∘′ (f ^ n)^-homo : ∀ f → Homomorphic₂ ℕ Endo _≡_ (f ^_) _+_ _∘′_^-homo f zero n = refl^-homo f (suc m) n = cong (f ∘′_) (^-homo f m n)-------------------------------------------------------------------------- Structures∘-isMagma : IsMagma _≡_ (Op₂ Endo ∋ _∘′_)∘-isMagma = record{ isEquivalence = ≡.isEquivalence; ∙-cong = cong₂ _∘′_}∘-magma : Magma _ _∘-magma = record { isMagma = ∘-isMagma }∘-isSemigroup : IsSemigroup _≡_ (Op₂ Endo ∋ _∘′_)∘-isSemigroup = record{ isMagma = ∘-isMagma; assoc = λ _ _ _ → refl}∘-semigroup : Semigroup _ _∘-semigroup = record { isSemigroup = ∘-isSemigroup }∘-id-isMonoid : IsMonoid _≡_ _∘′_ id∘-id-isMonoid = record{ isSemigroup = ∘-isSemigroup; identity = (λ _ → refl) , (λ _ → refl)}∘-id-monoid : Monoid _ _∘-id-monoid = record { isMonoid = ∘-id-isMonoid }-------------------------------------------------------------------------- Homomorphism^-isSemigroupMorphism : ∀ f → IsSemigroupMorphism +-semigroup ∘-semigroup (f ^_)^-isSemigroupMorphism f = record{ ⟦⟧-cong = cong (f ^_); ∙-homo = ^-homo f}^-isMonoidMorphism : ∀ f → IsMonoidMorphism +-0-monoid ∘-id-monoid (f ^_)^-isMonoidMorphism f = record{ sm-homo = ^-isSemigroupMorphism f; ε-homo = refl}
-------------------------------------------------------------------------- The Agda standard library---- Endomorphisms on a Setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Function.Endo.Setoid {c e} (S : Setoid c e) whereopen import Agda.Builtin.Equality using (_≡_)open import Algebra using (Semigroup; Magma; RawMagma; Monoid; RawMonoid)import Algebra.Definitions.RawMonoid as RawMonoidDefinitionsimport Algebra.Properties.Monoid.Mult as MonoidMultPropertiesopen import Algebra.Structures using (IsMagma; IsSemigroup; IsMonoid)open import Algebra.Morphismusing (module Definitions; IsMagmaHomomorphism; IsMonoidHomomorphism)open Definitions using (Homomorphic₂)open import Data.Nat.Base using (ℕ; zero; suc; _+_; +-rawMagma; +-0-rawMonoid)open import Data.Nat.Properties using (+-semigroup; +-identityʳ)open import Data.Product.Base using (_,_)open import Function.Bundles using (Func; _⟶ₛ_; _⟨$⟩_)open import Function.Construct.Identity using () renaming (function to identity)open import Function.Construct.Composition using () renaming (function to _∘_)open import Function.Relation.Binary.Setoid.Equality as Eq using (_⇨_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (_Preserves_⟶_)privateopen module E = Setoid (S ⇨ S) hiding (refl)module S = Setoid Sopen Func using (cong)-------------------------------------------------------------------------- Basic type and raw bundlesEndo : Set _Endo = S ⟶ₛ Sprivateid : Endoid = identity S∘-id-rawMonoid : RawMonoid (c ⊔ e) (c ⊔ e)∘-id-rawMonoid = record { Carrier = Endo; _≈_ = _≈_ ; _∙_ = _∘_ ; ε = id }open RawMonoid ∘-id-rawMonoidusing ()renaming (rawMagma to ∘-rawMagma)---------------------------------------------------------------- Structures∘-isMagma : IsMagma _≈_ _∘_∘-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = λ {_} {_} {_} {k} f≈g h≈k x → S.trans (h≈k _) (cong k (f≈g x))}∘-magma : Magma (c ⊔ e) (c ⊔ e)∘-magma = record { isMagma = ∘-isMagma }∘-isSemigroup : IsSemigroup _≈_ _∘_∘-isSemigroup = record{ isMagma = ∘-isMagma; assoc = λ _ _ _ _ → S.refl}∘-semigroup : Semigroup (c ⊔ e) (c ⊔ e)∘-semigroup = record { isSemigroup = ∘-isSemigroup }∘-id-isMonoid : IsMonoid _≈_ _∘_ id∘-id-isMonoid = record{ isSemigroup = ∘-isSemigroup; identity = (λ _ _ → S.refl) , (λ _ _ → S.refl)}∘-id-monoid : Monoid (c ⊔ e) (c ⊔ e)∘-id-monoid = record { isMonoid = ∘-id-isMonoid }-------------------------------------------------------------------------- -- n-th iterated compositioninfixr 8 _^__^_ : Endo → ℕ → Endof ^ n = n × f where open RawMonoidDefinitions ∘-id-rawMonoid using (_×_)-------------------------------------------------------------------------- Homomorphismmodule _ (f : Endo) whereopen MonoidMultProperties ∘-id-monoid using (×-congˡ; ×-homo-+)^-cong₂ : (f ^_) Preserves _≡_ ⟶ _≈_^-cong₂ = ×-congˡ {f}^-homo : Homomorphic₂ ℕ Endo _≈_ (f ^_) _+_ _∘_^-homo = ×-homo-+ f^-isMagmaHomomorphism : IsMagmaHomomorphism +-rawMagma ∘-rawMagma (f ^_)^-isMagmaHomomorphism = record{ isRelHomomorphism = record { cong = ^-cong₂ }; homo = ^-homo}^-isMonoidHomomorphism : IsMonoidHomomorphism +-0-rawMonoid ∘-id-rawMonoid (f ^_)^-isMonoidHomomorphism = record{ isMagmaHomomorphism = ^-isMagmaHomomorphism; ε-homo = λ _ → S.refl}
-------------------------------------------------------------------------- The Agda standard library---- Endomorphisms on a Set------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Endo.Propositional {a} (A : Set a) whereopen import Algebra using (Semigroup; Magma; RawMagma; Monoid; RawMonoid)open import Algebra.Coreimport Algebra.Definitions.RawMonoid as RawMonoidDefinitionsimport Algebra.Properties.Monoid.Mult as MonoidMultPropertiesopen import Algebra.Structures using (IsMagma; IsSemigroup; IsMonoid)open import Algebra.Morphismusing (module Definitions; IsMagmaHomomorphism; IsMonoidHomomorphism)open Definitions using (Homomorphic₂)open import Data.Nat.Base using (ℕ; zero; suc; _+_; +-rawMagma; +-0-rawMonoid)open import Data.Nat.Properties using (+-0-monoid; +-semigroup)open import Data.Product.Base using (_,_)open import Function.Base using (id; _∘′_; _∋_; flip)open import Function.Bundles using (Func; _⟶ₛ_; _⟨$⟩_)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂)import Relation.Binary.PropositionalEquality.Properties as ≡import Function.Endo.Setoid (≡.setoid A) as Setoid-------------------------------------------------------------------------- Basic type and raw bundlesEndo : Set aEndo = A → Aprivate_∘_ : Op₂ Endo_∘_ = _∘′_∘-id-rawMonoid : RawMonoid a a∘-id-rawMonoid = record { Carrier = Endo; _≈_ = _≡_ ; _∙_ = _∘_ ; ε = id }open RawMonoid ∘-id-rawMonoidusing ()renaming (rawMagma to ∘-rawMagma)-------------------------------------------------------------------------- Conversion back and forth with the Setoid-based notion of EndomorphismfromSetoidEndo : Setoid.Endo → EndofromSetoidEndo = _⟨$⟩_toSetoidEndo : Endo → Setoid.EndotoSetoidEndo f = record{ to = f; cong = cong f}-------------------------------------------------------------------------- Structures∘-isMagma : IsMagma _≡_ _∘_∘-isMagma = record{ isEquivalence = ≡.isEquivalence; ∙-cong = cong₂ _∘_}∘-magma : Magma _ _∘-magma = record { isMagma = ∘-isMagma }∘-isSemigroup : IsSemigroup _≡_ _∘_∘-isSemigroup = record{ isMagma = ∘-isMagma; assoc = λ _ _ _ → refl}∘-semigroup : Semigroup _ _∘-semigroup = record { isSemigroup = ∘-isSemigroup }∘-id-isMonoid : IsMonoid _≡_ _∘_ id∘-id-isMonoid = record{ isSemigroup = ∘-isSemigroup; identity = (λ _ → refl) , (λ _ → refl)}∘-id-monoid : Monoid _ _∘-id-monoid = record { isMonoid = ∘-id-isMonoid }-------------------------------------------------------------------------- n-th iterated compositioninfixr 8 _^__^_ : Endo → ℕ → Endo_^_ = flip _×_ where open RawMonoidDefinitions ∘-id-rawMonoid using (_×_)-------------------------------------------------------------------------- Homomorphismmodule _ (f : Endo) whereopen MonoidMultProperties ∘-id-monoid using (×-homo-+)^-homo : Homomorphic₂ ℕ Endo _≡_ (f ^_) _+_ _∘_^-homo = ×-homo-+ f^-isMagmaHomomorphism : IsMagmaHomomorphism +-rawMagma ∘-rawMagma (f ^_)^-isMagmaHomomorphism = record{ isRelHomomorphism = record { cong = cong (f ^_) }; homo = ^-homo}^-isMonoidHomomorphism : IsMonoidHomomorphism +-0-rawMonoid ∘-id-rawMonoid (f ^_)^-isMonoidHomomorphism = record{ isMagmaHomomorphism = ^-isMagmaHomomorphism; ε-homo = refl}
-------------------------------------------------------------------------- The Agda standard library---- Bundles for types of functions-------------------------------------------------------------------------- The contents of this file should usually be accessed from `Function`.-- Note that these bundles differ from those found elsewhere in other-- library hierarchies as they take Setoids as parameters. This is-- because a function is of no use without knowing what its domain and-- codomain is, as well which equalities are being considered over them.-- One consequence of this is that they are not built from the-- definitions found in `Function.Structures` as is usually the case in-- other library hierarchies, as this would duplicate the equality-- axioms.{-# OPTIONS --cubical-compatible --safe #-}module Function.Dependent.Bundles whereopen import Level using (Level; _⊔_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Indexed.Heterogeneous using (IndexedSetoid)privatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Setoid bundles------------------------------------------------------------------------module _(From : Setoid a ℓ₁)(To : IndexedSetoid (Setoid.Carrier From) b ℓ₂)whereopen Setoid From using () renaming (Carrier to A; _≈_ to _≈₁_)open IndexedSetoid To using () renaming (Carrier to B; _≈_ to _≈₂_)-------------------------------------------------------------------------- Bundles with one element-- Called `Func` rather than `Function` in order to avoid clashing-- with the top-level module.record Func : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : (x : A) → B xcong : ∀ {x y} → x ≈₁ y → to x ≈₂ to y
-------------------------------------------------------------------------- The Agda standard library---- Definitions for types of functions.-------------------------------------------------------------------------- The contents of this file should usually be accessed from `Function`.{-# OPTIONS --cubical-compatible --safe #-}module Function.Definitions whereopen import Data.Product.Base using (∃; _×_)open import Level using (Level)open import Relation.Binary.Core using (Rel)privatevariablea ℓ₁ ℓ₂ : LevelA B : Set a-------------------------------------------------------------------------- Basic definitionsmodule _(_≈₁_ : Rel A ℓ₁) -- Equality over the domain(_≈₂_ : Rel B ℓ₂) -- Equality over the codomainwhereCongruent : (A → B) → Set _Congruent f = ∀ {x y} → x ≈₁ y → f x ≈₂ f yInjective : (A → B) → Set _Injective f = ∀ {x y} → f x ≈₂ f y → x ≈₁ ySurjective : (A → B) → Set _Surjective f = ∀ y → ∃ λ x → ∀ {z} → z ≈₁ x → f z ≈₂ yBijective : (A → B) → Set _Bijective f = Injective f × Surjective fInverseˡ : (A → B) → (B → A) → Set _Inverseˡ f g = ∀ {x y} → y ≈₁ g x → f y ≈₂ xInverseʳ : (A → B) → (B → A) → Set _Inverseʳ f g = ∀ {x y} → y ≈₂ f x → g y ≈₁ xInverseᵇ : (A → B) → (B → A) → Set _Inverseᵇ f g = Inverseˡ f g × Inverseʳ f g-------------------------------------------------------------------------- Strict definitions-- These are often easier to use once but much harder to compose and-- reason about.StrictlySurjective : Rel B ℓ₂ → (A → B) → Set _StrictlySurjective _≈₂_ f = ∀ y → ∃ λ x → f x ≈₂ yStrictlyInverseˡ : Rel B ℓ₂ → (A → B) → (B → A) → Set _StrictlyInverseˡ _≈₂_ f g = ∀ y → f (g y) ≈₂ yStrictlyInverseʳ : Rel A ℓ₁ → (A → B) → (B → A) → Set _StrictlyInverseʳ _≈₁_ f g = ∀ x → g (f x) ≈₁ x
-------------------------------------------------------------------------- The Agda standard library---- Core definitions for Functions-------------------------------------------------------------------------- The contents of this file should always be accessed from `Function`.{-# OPTIONS --cubical-compatible --safe #-}module Function.Core whereopen import Level using (_⊔_)-------------------------------------------------------------------------- TypesFun₁ : ∀ {a} → Set a → Set aFun₁ A = A → AFun₂ : ∀ {a} → Set a → Set aFun₂ A = A → A → A-------------------------------------------------------------------------- MorphismMorphism : ∀ {a} → ∀ {b} → Set a → Set b → Set (a ⊔ b)Morphism A B = A → B
-------------------------------------------------------------------------- The Agda standard library---- Some functional properties are symmetric------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Construct.Symmetry whereopen import Data.Product.Base using (_,_; swap; proj₁; proj₂)open import Function.Base using (_∘_)open import Function.Definitionsusing (Bijective; Injective; Surjective; Inverseˡ; Inverseʳ; Inverseᵇ; Congruent)open import Function.Structuresusing (IsBijection; IsCongruent; IsRightInverse; IsLeftInverse; IsInverse)open import Function.Bundlesusing (Bijection; Equivalence; LeftInverse; RightInverse; Inverse; _⤖_; _⇔_; _↩_; _↪_; _↔_)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)open import Relation.Binary.PropositionalEquality.Properties using (setoid)privatevariablea b c ℓ₁ ℓ₂ ℓ₃ : LevelA B C : Set a-------------------------------------------------------------------------- Propertiesmodule _ {≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂} {f : A → B}((inj , surj) : Bijective ≈₁ ≈₂ f)whereprivatef⁻¹ = proj₁ ∘ surjf∘f⁻¹≡id = proj₂ ∘ surjinjective : Reflexive ≈₁ → Symmetric ≈₂ → Transitive ≈₂ →Congruent ≈₁ ≈₂ f → Injective ≈₂ ≈₁ f⁻¹injective refl sym trans cong gx≈gy =trans (trans (sym (f∘f⁻¹≡id _ refl)) (cong gx≈gy)) (f∘f⁻¹≡id _ refl)surjective : Reflexive ≈₁ → Transitive ≈₂ → Surjective ≈₂ ≈₁ f⁻¹surjective refl trans x = f x , inj ∘ trans (f∘f⁻¹≡id _ refl)bijective : Reflexive ≈₁ → Symmetric ≈₂ → Transitive ≈₂ →Congruent ≈₁ ≈₂ f → Bijective ≈₂ ≈₁ f⁻¹bijective refl sym trans cong = injective refl sym trans cong , surjective refl transmodule _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) {f : A → B} {f⁻¹ : B → A} whereinverseʳ : Inverseˡ ≈₁ ≈₂ f f⁻¹ → Inverseʳ ≈₂ ≈₁ f⁻¹ finverseʳ inv = invinverseˡ : Inverseʳ ≈₁ ≈₂ f f⁻¹ → Inverseˡ ≈₂ ≈₁ f⁻¹ finverseˡ inv = invinverseᵇ : Inverseᵇ ≈₁ ≈₂ f f⁻¹ → Inverseᵇ ≈₂ ≈₁ f⁻¹ finverseᵇ (invˡ , invʳ) = (invʳ , invˡ)-------------------------------------------------------------------------- Structuresmodule _ {≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂}{f : A → B} (isBij : IsBijection ≈₁ ≈₂ f)whereprivatemodule IB = IsBijection isBijf⁻¹ = proj₁ ∘ IB.surjective-- We can only flip a bijection if the witness produced by the-- surjection proof respects the equality on the codomain.isBijection : Congruent ≈₂ ≈₁ f⁻¹ → IsBijection ≈₂ ≈₁ f⁻¹isBijection f⁻¹-cong = record{ isInjection = record{ isCongruent = record{ cong = f⁻¹-cong; isEquivalence₁ = IB.Eq₂.isEquivalence; isEquivalence₂ = IB.Eq₁.isEquivalence}; injective = injective IB.bijective IB.Eq₁.refl IB.Eq₂.sym IB.Eq₂.trans IB.cong}; surjective = surjective IB.bijective IB.Eq₁.refl IB.Eq₂.trans}module _ {≈₁ : Rel A ℓ₁} {f : A → B} (isBij : IsBijection ≈₁ _≡_ f) where-- We can always flip a bijection if using the equality over the-- codomain is propositional equality.isBijection-≡ : IsBijection _≡_ ≈₁ _isBijection-≡ = isBijection isBij (IB.Eq₁.reflexive ∘ cong _)where module IB = IsBijection isBijmodule _ {≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂} {f : A → B} {f⁻¹ : B → A} whereisCongruent : IsCongruent ≈₁ ≈₂ f → Congruent ≈₂ ≈₁ f⁻¹ → IsCongruent ≈₂ ≈₁ f⁻¹isCongruent ic cg = record{ cong = cg; isEquivalence₁ = F.isEquivalence₂; isEquivalence₂ = F.isEquivalence₁} where module F = IsCongruent icisLeftInverse : IsRightInverse ≈₁ ≈₂ f f⁻¹ → IsLeftInverse ≈₂ ≈₁ f⁻¹ fisLeftInverse inv = record{ isCongruent = isCongruent F.isCongruent F.from-cong; from-cong = F.to-cong; inverseˡ = inverseˡ ≈₁ ≈₂ F.inverseʳ} where module F = IsRightInverse invisRightInverse : IsLeftInverse ≈₁ ≈₂ f f⁻¹ → IsRightInverse ≈₂ ≈₁ f⁻¹ fisRightInverse inv = record{ isCongruent = isCongruent F.isCongruent F.from-cong; from-cong = F.to-cong; inverseʳ = inverseʳ ≈₁ ≈₂ F.inverseˡ} where module F = IsLeftInverse invisInverse : IsInverse ≈₁ ≈₂ f f⁻¹ → IsInverse ≈₂ ≈₁ f⁻¹ fisInverse f-inv = record{ isLeftInverse = isLeftInverse F.isRightInverse; inverseʳ = inverseʳ ≈₁ ≈₂ F.inverseˡ} where module F = IsInverse f-inv-------------------------------------------------------------------------- Setoid bundlesmodule _ {R : Setoid a ℓ₁} {S : Setoid b ℓ₂} (bij : Bijection R S) whereprivatemodule IB = Bijection bijfrom = proj₁ ∘ IB.surjective-- We can only flip a bijection if the witness produced by the-- surjection proof respects the equality on the codomain.bijection : Congruent IB.Eq₂._≈_ IB.Eq₁._≈_ from → Bijection S Rbijection cong = record{ to = from; cong = cong; bijective = bijective IB.bijective IB.Eq₁.refl IB.Eq₂.sym IB.Eq₂.trans IB.cong}-- We can always flip a bijection if using the equality over the-- codomain is propositional equality.bijection-≡ : {R : Setoid a ℓ₁} {B : Set b} →Bijection R (setoid B) → Bijection (setoid B) Rbijection-≡ bij = bijection bij (B.Eq₁.reflexive ∘ cong _)where module B = Bijection bijmodule _ {R : Setoid a ℓ₁} {S : Setoid b ℓ₂} whereequivalence : Equivalence R S → Equivalence S Requivalence equiv = record{ to = E.from; from = E.to; to-cong = E.from-cong; from-cong = E.to-cong} where module E = Equivalence equivrightInverse : LeftInverse R S → RightInverse S RrightInverse left = record{ to = L.from; from = L.to; to-cong = L.from-cong; from-cong = L.to-cong; inverseʳ = L.inverseˡ} where module L = LeftInverse leftleftInverse : RightInverse R S → LeftInverse S RleftInverse right = record{ to = R.from; from = R.to; to-cong = R.from-cong; from-cong = R.to-cong; inverseˡ = R.inverseʳ} where module R = RightInverse rightinverse : Inverse R S → Inverse S Rinverse inv = record{ to = I.from; from = I.to; to-cong = I.from-cong; from-cong = I.to-cong; inverse = swap I.inverse} where module I = Inverse inv-------------------------------------------------------------------------- Propositional bundles⤖-sym : A ⤖ B → B ⤖ A⤖-sym b = bijection b (cong _)⇔-sym : A ⇔ B → B ⇔ A⇔-sym = equivalence↩-sym : A ↩ B → B ↪ A↩-sym = rightInverse↪-sym : A ↪ B → B ↩ A↪-sym = leftInverse↔-sym : A ↔ B → B ↔ A↔-sym = inverse-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version v2.0sym-⤖ = ⤖-sym{-# WARNING_ON_USAGE sym-⤖"Warning: sym-⤖ was deprecated in v2.0.Please use ⤖-sym instead."#-}sym-⇔ = ⇔-sym{-# WARNING_ON_USAGE sym-⇔"Warning: sym-⇔ was deprecated in v2.0.Please use ⇔-sym instead."#-}sym-↩ = ↩-sym{-# WARNING_ON_USAGE sym-↩"Warning: sym-↩ was deprecated in v2.0.Please use ↩-sym instead."#-}sym-↪ = ↪-sym{-# WARNING_ON_USAGE sym-↪"Warning: sym-↪ was deprecated in v2.0.Please use ↪-sym instead."#-}sym-↔ = ↔-sym{-# WARNING_ON_USAGE sym-↔"Warning: sym-↔ was deprecated in v2.0.Please use ↔-sym instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The identity function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Construct.Identity whereopen import Data.Product.Base using (_,_)open import Function.Base using (id)open import Function.Bundlesimport Function.Definitions as Definitionsimport Function.Structures as Structuresopen import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures as B hiding (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (setoid)privatevariablea ℓ : LevelA : Set a-------------------------------------------------------------------------- Propertiesmodule _ (_≈_ : Rel A ℓ) whereopen Definitionscongruent : Congruent _≈_ _≈_ idcongruent = idinjective : Injective _≈_ _≈_ idinjective = idsurjective : Surjective _≈_ _≈_ idsurjective x = x , idbijective : Bijective _≈_ _≈_ idbijective = injective , surjectiveinverseˡ : Inverseˡ _≈_ _≈_ id idinverseˡ = idinverseʳ : Inverseʳ _≈_ _≈_ id idinverseʳ = idinverseᵇ : Inverseᵇ _≈_ _≈_ id idinverseᵇ = inverseˡ , inverseʳ-------------------------------------------------------------------------- Structuresmodule _ {_≈_ : Rel A ℓ} (isEq : B.IsEquivalence _≈_) whereopen Structures _≈_ _≈_open B.IsEquivalence isEqisCongruent : IsCongruent idisCongruent = record{ cong = id; isEquivalence₁ = isEq; isEquivalence₂ = isEq}isInjection : IsInjection idisInjection = record{ isCongruent = isCongruent; injective = injective _≈_}isSurjection : IsSurjection idisSurjection = record{ isCongruent = isCongruent; surjective = surjective _≈_}isBijection : IsBijection idisBijection = record{ isInjection = isInjection; surjective = surjective _≈_}isLeftInverse : IsLeftInverse id idisLeftInverse = record{ isCongruent = isCongruent; from-cong = id; inverseˡ = inverseˡ _≈_}isRightInverse : IsRightInverse id idisRightInverse = record{ isCongruent = isCongruent; from-cong = id; inverseʳ = inverseʳ _≈_}isInverse : IsInverse id idisInverse = record{ isLeftInverse = isLeftInverse; inverseʳ = inverseʳ _≈_}-------------------------------------------------------------------------- Setoid bundlesmodule _ (S : Setoid a ℓ) whereopen Setoid Sfunction : Func S Sfunction = record{ to = id; cong = id}injection : Injection S Sinjection = record{ to = id; cong = id; injective = injective _≈_}surjection : Surjection S Ssurjection = record{ to = id; cong = id; surjective = surjective _≈_}bijection : Bijection S Sbijection = record{ to = id; cong = id; bijective = bijective _≈_}equivalence : Equivalence S Sequivalence = record{ to = id; from = id; to-cong = id; from-cong = id}leftInverse : LeftInverse S SleftInverse = record{ to = id; from = id; to-cong = id; from-cong = id; inverseˡ = inverseˡ _≈_}rightInverse : RightInverse S SrightInverse = record{ to = id; from = id; to-cong = id; from-cong = id; inverseʳ = inverseʳ _≈_}inverse : Inverse S Sinverse = record{ to = id; from = id; to-cong = id; from-cong = id; inverse = inverseᵇ _≈_}-------------------------------------------------------------------------- Propositional bundlesmodule _ (A : Set a) where⟶-id : A ⟶ A⟶-id = function (setoid A)↣-id : A ↣ A↣-id = injection (setoid A)↠-id : A ↠ A↠-id = surjection (setoid A)⤖-id : A ⤖ A⤖-id = bijection (setoid A)⇔-id : A ⇔ A⇔-id = equivalence (setoid A)↩-id : A ↩ A↩-id = leftInverse (setoid A)↪-id : A ↪ A↪-id = rightInverse (setoid A)↔-id : A ↔ A↔-id = inverse (setoid A)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version v2.0id-⟶ = ⟶-id{-# WARNING_ON_USAGE id-⟶"Warning: id-⟶ was deprecated in v2.0.Please use ⟶-id instead."#-}id-↣ = ↣-id{-# WARNING_ON_USAGE id-↣"Warning: id-↣ was deprecated in v2.0.Please use ↣-id instead."#-}id-↠ = ↠-id{-# WARNING_ON_USAGE id-↠"Warning: id-↠ was deprecated in v2.0.Please use ↠-id instead."#-}id-⤖ = ⤖-id{-# WARNING_ON_USAGE id-⤖"Warning: id-⤖ was deprecated in v2.0.Please use ⤖-id instead."#-}id-⇔ = ⇔-id{-# WARNING_ON_USAGE id-⇔"Warning: id-⇔ was deprecated in v2.0.Please use ⇔-id instead."#-}id-↩ = ↩-id{-# WARNING_ON_USAGE id-↩"Warning: id-↩ was deprecated in v2.0.Please use ↩-id instead."#-}id-↪ = ↪-id{-# WARNING_ON_USAGE id-↪"Warning: id-↪ was deprecated in v2.0.Please use ↪-id instead."#-}id-↔ = ↔-id{-# WARNING_ON_USAGE id-↔"Warning: id-↔ was deprecated in v2.0.Please use ↔-id instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The constant function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Construct.Constant whereopen import Function.Base using (const)open import Function.Bundlesimport Function.Definitions as Definitionsimport Function.Structures as Structuresopen import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures as B hiding (IsEquivalence)privatevariablea b ℓ₁ ℓ₂ : LevelA B : Set a-------------------------------------------------------------------------- Propertiesmodule _ (_≈₁_ : Rel A ℓ₁) (_≈₂_ : Rel B ℓ₂) whereopen Definitionscongruent : ∀ {b} → b ≈₂ b → Congruent _≈₁_ _≈₂_ (const b)congruent refl _ = refl-------------------------------------------------------------------------- Structuresmodule _{≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂}(isEq₁ : B.IsEquivalence ≈₁)(isEq₂ : B.IsEquivalence ≈₂) whereopen Structures ≈₁ ≈₂open B.IsEquivalenceisCongruent : ∀ b → IsCongruent (const b)isCongruent b = record{ cong = congruent ≈₁ ≈₂ (refl isEq₂); isEquivalence₁ = isEq₁; isEquivalence₂ = isEq₂}-------------------------------------------------------------------------- Setoid bundlesmodule _ (S : Setoid a ℓ₂) (T : Setoid b ℓ₂) whereopen Setoidfunction : Carrier T → Func S Tfunction b = record{ to = const b; cong = congruent (_≈_ S) (_≈_ T) (refl T)}
-------------------------------------------------------------------------- The Agda standard library---- Composition of functional properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Construct.Composition whereopen import Data.Product.Base as Product using (_,_)open import Function.Base using (_∘_; flip)open import Function.Bundlesopen import Function.Definitionsopen import Function.Structuresopen import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Transitive)privatevariablea b c ℓ₁ ℓ₂ ℓ₃ : LevelA B C : Set a-------------------------------------------------------------------------- Propertiesmodule _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) (≈₃ : Rel C ℓ₃){f : A → B} {g : B → C}wherecongruent : Congruent ≈₁ ≈₂ f → Congruent ≈₂ ≈₃ g →Congruent ≈₁ ≈₃ (g ∘ f)congruent f-cong g-cong = g-cong ∘ f-conginjective : Injective ≈₁ ≈₂ f → Injective ≈₂ ≈₃ g →Injective ≈₁ ≈₃ (g ∘ f)injective f-inj g-inj = f-inj ∘ g-injsurjective : Surjective ≈₁ ≈₂ f → Surjective ≈₂ ≈₃ g →Surjective ≈₁ ≈₃ (g ∘ f)surjective f-sur g-sur x with g-sur x... | y , gproof with f-sur y... | z , fproof = z , gproof ∘ fproofbijective : Bijective ≈₁ ≈₂ f → Bijective ≈₂ ≈₃ g →Bijective ≈₁ ≈₃ (g ∘ f)bijective = Product.zip′ injective surjectivemodule _ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) (≈₃ : Rel C ℓ₃){f : A → B} {f⁻¹ : B → A} {g : B → C} {g⁻¹ : C → B}whereinverseˡ : Inverseˡ ≈₁ ≈₂ f f⁻¹ → Inverseˡ ≈₂ ≈₃ g g⁻¹ →Inverseˡ ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)inverseˡ f-inv g-inv = g-inv ∘ f-invinverseʳ : Inverseʳ ≈₁ ≈₂ f f⁻¹ → Inverseʳ ≈₂ ≈₃ g g⁻¹ →Inverseʳ ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)inverseʳ f-inv g-inv = f-inv ∘ g-invinverseᵇ : Inverseᵇ ≈₁ ≈₂ f f⁻¹ → Inverseᵇ ≈₂ ≈₃ g g⁻¹ →Inverseᵇ ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)inverseᵇ = Product.zip′ inverseˡ inverseʳ-------------------------------------------------------------------------- Structuresmodule _ {≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂} {≈₃ : Rel C ℓ₃}{f : A → B} {g : B → C}whereisCongruent : IsCongruent ≈₁ ≈₂ f → IsCongruent ≈₂ ≈₃ g →IsCongruent ≈₁ ≈₃ (g ∘ f)isCongruent f-cong g-cong = record{ cong = G.cong ∘ F.cong; isEquivalence₁ = F.isEquivalence₁; isEquivalence₂ = G.isEquivalence₂} where module F = IsCongruent f-cong; module G = IsCongruent g-congisInjection : IsInjection ≈₁ ≈₂ f → IsInjection ≈₂ ≈₃ g →IsInjection ≈₁ ≈₃ (g ∘ f)isInjection f-inj g-inj = record{ isCongruent = isCongruent F.isCongruent G.isCongruent; injective = injective ≈₁ ≈₂ ≈₃ F.injective G.injective} where module F = IsInjection f-inj; module G = IsInjection g-injisSurjection : IsSurjection ≈₁ ≈₂ f → IsSurjection ≈₂ ≈₃ g →IsSurjection ≈₁ ≈₃ (g ∘ f)isSurjection f-surj g-surj = record{ isCongruent = isCongruent F.isCongruent G.isCongruent; surjective = surjective ≈₁ ≈₂ ≈₃ F.surjective G.surjective} where module F = IsSurjection f-surj; module G = IsSurjection g-surjisBijection : IsBijection ≈₁ ≈₂ f → IsBijection ≈₂ ≈₃ g →IsBijection ≈₁ ≈₃ (g ∘ f)isBijection f-bij g-bij = record{ isInjection = isInjection F.isInjection G.isInjection; surjective = surjective ≈₁ ≈₂ ≈₃ F.surjective G.surjective} where module F = IsBijection f-bij; module G = IsBijection g-bijmodule _ {≈₁ : Rel A ℓ₁} {≈₂ : Rel B ℓ₂} {≈₃ : Rel C ℓ₃}{f : A → B} {g : B → C} {f⁻¹ : B → A} {g⁻¹ : C → B}whereisLeftInverse : IsLeftInverse ≈₁ ≈₂ f f⁻¹ → IsLeftInverse ≈₂ ≈₃ g g⁻¹ →IsLeftInverse ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)isLeftInverse f-invˡ g-invˡ = record{ isCongruent = isCongruent F.isCongruent G.isCongruent; from-cong = congruent ≈₃ ≈₂ ≈₁ G.from-cong F.from-cong; inverseˡ = inverseˡ ≈₁ ≈₂ ≈₃ F.inverseˡ G.inverseˡ} where module F = IsLeftInverse f-invˡ; module G = IsLeftInverse g-invˡisRightInverse : IsRightInverse ≈₁ ≈₂ f f⁻¹ → IsRightInverse ≈₂ ≈₃ g g⁻¹ →IsRightInverse ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)isRightInverse f-invʳ g-invʳ = record{ isCongruent = isCongruent F.isCongruent G.isCongruent; from-cong = congruent ≈₃ ≈₂ ≈₁ G.from-cong F.from-cong; inverseʳ = inverseʳ ≈₁ ≈₂ ≈₃ F.inverseʳ G.inverseʳ} where module F = IsRightInverse f-invʳ; module G = IsRightInverse g-invʳisInverse : IsInverse ≈₁ ≈₂ f f⁻¹ → IsInverse ≈₂ ≈₃ g g⁻¹ →IsInverse ≈₁ ≈₃ (g ∘ f) (f⁻¹ ∘ g⁻¹)isInverse f-inv g-inv = record{ isLeftInverse = isLeftInverse F.isLeftInverse G.isLeftInverse; inverseʳ = inverseʳ ≈₁ ≈₂ ≈₃ F.inverseʳ G.inverseʳ} where module F = IsInverse f-inv; module G = IsInverse g-inv-------------------------------------------------------------------------- Setoid bundlesmodule _ {R : Setoid a ℓ₁} {S : Setoid b ℓ₂} {T : Setoid c ℓ₃} whereopen Setoid renaming (_≈_ to ≈)function : Func R S → Func S T → Func R Tfunction f g = record{ to = G.to ∘ F.to; cong = congruent (≈ R) (≈ S) (≈ T) F.cong G.cong} where module F = Func f; module G = Func ginjection : Injection R S → Injection S T → Injection R Tinjection inj₁ inj₂ = record{ to = G.to ∘ F.to; cong = congruent (≈ R) (≈ S) (≈ T) F.cong G.cong; injective = injective (≈ R) (≈ S) (≈ T) F.injective G.injective} where module F = Injection inj₁; module G = Injection inj₂surjection : Surjection R S → Surjection S T → Surjection R Tsurjection surj₁ surj₂ = record{ to = G.to ∘ F.to; cong = congruent (≈ R) (≈ S) (≈ T) F.cong G.cong; surjective = surjective (≈ R) (≈ S) (≈ T) F.surjective G.surjective} where module F = Surjection surj₁; module G = Surjection surj₂bijection : Bijection R S → Bijection S T → Bijection R Tbijection bij₁ bij₂ = record{ to = G.to ∘ F.to; cong = congruent (≈ R) (≈ S) (≈ T) F.cong G.cong; bijective = bijective (≈ R) (≈ S) (≈ T) F.bijective G.bijective} where module F = Bijection bij₁; module G = Bijection bij₂equivalence : Equivalence R S → Equivalence S T → Equivalence R Tequivalence equiv₁ equiv₂ = record{ to = G.to ∘ F.to; from = F.from ∘ G.from; to-cong = congruent (≈ R) (≈ S) (≈ T) F.to-cong G.to-cong; from-cong = congruent (≈ T) (≈ S) (≈ R) G.from-cong F.from-cong} where module F = Equivalence equiv₁; module G = Equivalence equiv₂leftInverse : LeftInverse R S → LeftInverse S T → LeftInverse R TleftInverse invˡ₁ invˡ₂ = record{ to = G.to ∘ F.to; from = F.from ∘ G.from; to-cong = congruent (≈ R) (≈ S) (≈ T) F.to-cong G.to-cong; from-cong = congruent (≈ T) (≈ S) (≈ R) G.from-cong F.from-cong; inverseˡ = inverseˡ (≈ R) (≈ S) (≈ T) F.inverseˡ G.inverseˡ} where module F = LeftInverse invˡ₁; module G = LeftInverse invˡ₂rightInverse : RightInverse R S → RightInverse S T → RightInverse R TrightInverse invʳ₁ invʳ₂ = record{ to = G.to ∘ F.to; from = F.from ∘ G.from; to-cong = congruent (≈ R) (≈ S) (≈ T) F.to-cong G.to-cong; from-cong = congruent (≈ T) (≈ S) (≈ R) G.from-cong F.from-cong; inverseʳ = inverseʳ (≈ R) (≈ S) (≈ T) F.inverseʳ G.inverseʳ} where module F = RightInverse invʳ₁; module G = RightInverse invʳ₂inverse : Inverse R S → Inverse S T → Inverse R Tinverse inv₁ inv₂ = record{ to = G.to ∘ F.to; from = F.from ∘ G.from; to-cong = congruent (≈ R) (≈ S) (≈ T) F.to-cong G.to-cong; from-cong = congruent (≈ T) (≈ S) (≈ R) G.from-cong F.from-cong; inverse = inverseᵇ (≈ R) (≈ S) (≈ T) F.inverse G.inverse} where module F = Inverse inv₁; module G = Inverse inv₂-------------------------------------------------------------------------- Propositional bundles-- Notice the flipped order of the arguments to mirror composition.infix 8 _⟶-∘_ _↣-∘_ _↠-∘_ _⤖-∘_ _⇔-∘_ _↩-∘_ _↪-∘_ _↔-∘__⟶-∘_ : (B ⟶ C) → (A ⟶ B) → (A ⟶ C)_⟶-∘_ = flip function_↣-∘_ : B ↣ C → A ↣ B → A ↣ C_↣-∘_ = flip injection_↠-∘_ : B ↠ C → A ↠ B → A ↠ C_↠-∘_ = flip surjection_⤖-∘_ : B ⤖ C → A ⤖ B → A ⤖ C_⤖-∘_ = flip bijection_⇔-∘_ : B ⇔ C → A ⇔ B → A ⇔ C_⇔-∘_ = flip equivalence_↩-∘_ : B ↩ C → A ↩ B → A ↩ C_↩-∘_ = flip leftInverse_↪-∘_ : B ↪ C → A ↪ B → A ↪ C_↪-∘_ = flip rightInverse_↔-∘_ : B ↔ C → A ↔ B → A ↔ C_↔-∘_ = flip inverse-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version v2.0infix 8 _∘-⟶_ _∘-↣_ _∘-↠_ _∘-⤖_ _∘-⇔_ _∘-↩_ _∘-↪_ _∘-↔__∘-⟶_ = _⟶-∘_{-# WARNING_ON_USAGE _∘-⟶_"Warning: _∘-⟶_ was deprecated in v2.0.Please use _⟶-∘_ instead."#-}_∘-↣_ = _↣-∘_{-# WARNING_ON_USAGE _∘-↣_"Warning: _∘-↣_ was deprecated in v2.0.Please use _↣-∘_ instead."#-}_∘-↠_ = _↠-∘_{-# WARNING_ON_USAGE _∘-↠_"Warning: _∘-↠_ was deprecated in v2.0.Please use _↠-∘_ instead."#-}_∘-⤖_ = _⤖-∘_{-# WARNING_ON_USAGE _∘-⤖_"Warning: _∘-⤖_ was deprecated in v2.0.Please use _⤖-∘_ instead."#-}_∘-⇔_ = _⇔-∘_{-# WARNING_ON_USAGE _∘-⇔_"Warning: _∘-⇔_ was deprecated in v2.0.Please use _⇔-∘_ instead."#-}_∘-↩_ = _↩-∘_{-# WARNING_ON_USAGE _∘-↩_"Warning: _∘-↩_ was deprecated in v2.0.Please use _↩-∘_ instead."#-}_∘-↪_ = _↪-∘_{-# WARNING_ON_USAGE _∘-↪_"Warning: _∘-↪_ was deprecated in v2.0.Please use _↪-∘_ instead."#-}_∘-↔_ = _↔-∘_{-# WARNING_ON_USAGE _∘-↔_"Warning: _∘-↔_ was deprecated in v2.0.Please use _↔-∘_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Relationships between properties of functions. See-- `Function.Consequences.Propositional` for specialisations to-- propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Consequences whereopen import Data.Product.Base as Productopen import Function.Definitionsopen import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)open import Relation.Nullary.Negation.Core using (¬_; contraposition)privatevariablea b ℓ₁ ℓ₂ : LevelA B : Set a≈₁ ≈₂ : Rel A ℓ₁f f⁻¹ : A → B-------------------------------------------------------------------------- InjectivecontraInjective : ∀ (≈₂ : Rel B ℓ₂) → Injective ≈₁ ≈₂ f →∀ {x y} → ¬ (≈₁ x y) → ¬ (≈₂ (f x) (f y))contraInjective _ inj p = contraposition inj p-------------------------------------------------------------------------- Inverseˡinverseˡ⇒surjective : ∀ (≈₂ : Rel B ℓ₂) →Inverseˡ ≈₁ ≈₂ f f⁻¹ →Surjective ≈₁ ≈₂ finverseˡ⇒surjective ≈₂ invˡ y = (_ , invˡ)-------------------------------------------------------------------------- Inverseʳinverseʳ⇒injective : ∀ (≈₂ : Rel B ℓ₂) f →Reflexive ≈₂ →Symmetric ≈₁ →Transitive ≈₁ →Inverseʳ ≈₁ ≈₂ f f⁻¹ →Injective ≈₁ ≈₂ finverseʳ⇒injective ≈₂ f refl sym trans invʳ {x} {y} fx≈fy =trans (sym (invʳ refl)) (invʳ fx≈fy)-------------------------------------------------------------------------- Inverseᵇinverseᵇ⇒bijective : ∀ (≈₂ : Rel B ℓ₂) →Reflexive ≈₂ →Symmetric ≈₁ →Transitive ≈₁ →Inverseᵇ ≈₁ ≈₂ f f⁻¹ →Bijective ≈₁ ≈₂ finverseᵇ⇒bijective {f = f} ≈₂ refl sym trans (invˡ , invʳ) =(inverseʳ⇒injective ≈₂ f refl sym trans invʳ , inverseˡ⇒surjective ≈₂ invˡ)-------------------------------------------------------------------------- StrictlySurjectivesurjective⇒strictlySurjective : ∀ (≈₂ : Rel B ℓ₂) →Reflexive ≈₁ →Surjective ≈₁ ≈₂ f →StrictlySurjective ≈₂ fsurjective⇒strictlySurjective _ refl surj x =Product.map₂ (λ v → v refl) (surj x)strictlySurjective⇒surjective : Transitive ≈₂ →Congruent ≈₁ ≈₂ f →StrictlySurjective ≈₂ f →Surjective ≈₁ ≈₂ fstrictlySurjective⇒surjective trans cong surj x =Product.map₂ (λ fy≈x z≈y → trans (cong z≈y) fy≈x) (surj x)-------------------------------------------------------------------------- StrictlyInverseˡinverseˡ⇒strictlyInverseˡ : ∀ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) →Reflexive ≈₁ →Inverseˡ ≈₁ ≈₂ f f⁻¹ →StrictlyInverseˡ ≈₂ f f⁻¹inverseˡ⇒strictlyInverseˡ _ _ refl sinv x = sinv reflstrictlyInverseˡ⇒inverseˡ : Transitive ≈₂ →Congruent ≈₁ ≈₂ f →StrictlyInverseˡ ≈₂ f f⁻¹ →Inverseˡ ≈₁ ≈₂ f f⁻¹strictlyInverseˡ⇒inverseˡ trans cong sinv {x} y≈f⁻¹x =trans (cong y≈f⁻¹x) (sinv x)-------------------------------------------------------------------------- StrictlyInverseʳinverseʳ⇒strictlyInverseʳ : ∀ (≈₁ : Rel A ℓ₁) (≈₂ : Rel B ℓ₂) →Reflexive ≈₂ →Inverseʳ ≈₁ ≈₂ f f⁻¹ →StrictlyInverseʳ ≈₁ f f⁻¹inverseʳ⇒strictlyInverseʳ _ _ refl sinv x = sinv reflstrictlyInverseʳ⇒inverseʳ : Transitive ≈₁ →Congruent ≈₂ ≈₁ f⁻¹ →StrictlyInverseʳ ≈₁ f f⁻¹ →Inverseʳ ≈₁ ≈₂ f f⁻¹strictlyInverseʳ⇒inverseʳ trans cong sinv {x} y≈f⁻¹x =trans (cong y≈f⁻¹x) (sinv x)
-------------------------------------------------------------------------- The Agda standard library---- Relationships between properties of functions where the equality-- over both the domain and codomain are assumed to be setoids.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Function.Consequences.Setoid{a b ℓ₁ ℓ₂}(S : Setoid a ℓ₁)(T : Setoid b ℓ₂)whereopen import Function.Definitionsopen import Relation.Nullary.Negation.Coreimport Function.Consequences as Cprivateopen module S = Setoid S using () renaming (Carrier to A; _≈_ to ≈₁)open module T = Setoid T using () renaming (Carrier to B; _≈_ to ≈₂)variablef : A → Bf⁻¹ : B → A-------------------------------------------------------------------------- InjectivecontraInjective : Injective ≈₁ ≈₂ f →∀ {x y} → ¬ (≈₁ x y) → ¬ (≈₂ (f x) (f y))contraInjective = C.contraInjective ≈₂-------------------------------------------------------------------------- Inverseˡinverseˡ⇒surjective : Inverseˡ ≈₁ ≈₂ f f⁻¹ → Surjective ≈₁ ≈₂ finverseˡ⇒surjective = C.inverseˡ⇒surjective ≈₂-------------------------------------------------------------------------- Inverseʳinverseʳ⇒injective : ∀ f → Inverseʳ ≈₁ ≈₂ f f⁻¹ → Injective ≈₁ ≈₂ finverseʳ⇒injective f = C.inverseʳ⇒injective ≈₂ f T.refl S.sym S.trans-------------------------------------------------------------------------- Inverseᵇinverseᵇ⇒bijective : Inverseᵇ ≈₁ ≈₂ f f⁻¹ → Bijective ≈₁ ≈₂ finverseᵇ⇒bijective = C.inverseᵇ⇒bijective ≈₂ T.refl S.sym S.trans-------------------------------------------------------------------------- StrictlySurjectivesurjective⇒strictlySurjective : Surjective ≈₁ ≈₂ f →StrictlySurjective ≈₂ fsurjective⇒strictlySurjective =C.surjective⇒strictlySurjective ≈₂ S.reflstrictlySurjective⇒surjective : Congruent ≈₁ ≈₂ f →StrictlySurjective ≈₂ f →Surjective ≈₁ ≈₂ fstrictlySurjective⇒surjective =C.strictlySurjective⇒surjective T.trans-------------------------------------------------------------------------- StrictlyInverseˡinverseˡ⇒strictlyInverseˡ : Inverseˡ ≈₁ ≈₂ f f⁻¹ →StrictlyInverseˡ ≈₂ f f⁻¹inverseˡ⇒strictlyInverseˡ = C.inverseˡ⇒strictlyInverseˡ ≈₁ ≈₂ S.reflstrictlyInverseˡ⇒inverseˡ : Congruent ≈₁ ≈₂ f →StrictlyInverseˡ ≈₂ f f⁻¹ →Inverseˡ ≈₁ ≈₂ f f⁻¹strictlyInverseˡ⇒inverseˡ = C.strictlyInverseˡ⇒inverseˡ T.trans-------------------------------------------------------------------------- StrictlyInverseʳinverseʳ⇒strictlyInverseʳ : Inverseʳ ≈₁ ≈₂ f f⁻¹ →StrictlyInverseʳ ≈₁ f f⁻¹inverseʳ⇒strictlyInverseʳ = C.inverseʳ⇒strictlyInverseʳ ≈₁ ≈₂ T.reflstrictlyInverseʳ⇒inverseʳ : Congruent ≈₂ ≈₁ f⁻¹ →StrictlyInverseʳ ≈₁ f f⁻¹ →Inverseʳ ≈₁ ≈₂ f f⁻¹strictlyInverseʳ⇒inverseʳ = C.strictlyInverseʳ⇒inverseʳ S.trans
-------------------------------------------------------------------------- The Agda standard library---- Relationships between properties of functions where the equality-- over both the domain and codomain is assumed to be _≡_------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Function.Consequences.Propositional{a b} {A : Set a} {B : Set b}whereopen import Relation.Binary.PropositionalEquality.Core using (_≡_; _≢_; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid)open import Function.Definitionsopen import Relation.Nullary.Negation.Core using (contraposition)import Function.Consequences.Setoid (setoid A) (setoid B) as Setoid-------------------------------------------------------------------------- Re-export setoid propertiesopen Setoid publichiding( strictlySurjective⇒surjective; strictlyInverseˡ⇒inverseˡ; strictlyInverseʳ⇒inverseʳ)-------------------------------------------------------------------------- Properties that rely on congruenceprivatevariablef : A → Bf⁻¹ : B → AstrictlySurjective⇒surjective : StrictlySurjective _≡_ f →Surjective _≡_ _≡_ fstrictlySurjective⇒surjective =Setoid.strictlySurjective⇒surjective (cong _)strictlyInverseˡ⇒inverseˡ : ∀ f → StrictlyInverseˡ _≡_ f f⁻¹ →Inverseˡ _≡_ _≡_ f f⁻¹strictlyInverseˡ⇒inverseˡ f =Setoid.strictlyInverseˡ⇒inverseˡ (cong _)strictlyInverseʳ⇒inverseʳ : ∀ f → StrictlyInverseʳ _≡_ f f⁻¹ →Inverseʳ _≡_ _≡_ f f⁻¹strictlyInverseʳ⇒inverseʳ f =Setoid.strictlyInverseʳ⇒inverseʳ (cong _)
-------------------------------------------------------------------------- The Agda standard library---- Bundles for types of functions-------------------------------------------------------------------------- The contents of this file should usually be accessed from `Function`.-- Note that these bundles differ from those found elsewhere in other-- library hierarchies as they take Setoids as parameters. This is-- because a function is of no use without knowing what its domain and-- codomain is, as well which equalities are being considered over them.-- One consequence of this is that they are not built from the-- definitions found in `Function.Structures` as is usually the case in-- other library hierarchies, as this would duplicate the equality-- axioms.{-# OPTIONS --cubical-compatible --safe #-}module Function.Bundles whereopen import Function.Base using (_∘_)open import Function.Definitionsimport Function.Structures as FunctionStructuresopen import Level using (Level; _⊔_; suc)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡open import Function.Consequences.Propositionalopen Setoid using (isEquivalence)privatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Setoid bundles------------------------------------------------------------------------module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) whereopen Setoid From using () renaming (Carrier to A; _≈_ to _≈₁_)open Setoid To using () renaming (Carrier to B; _≈_ to _≈₂_)open FunctionStructures _≈₁_ _≈₂_-------------------------------------------------------------------------- Bundles with one element-- Called `Func` rather than `Function` in order to avoid clashing-- with the top-level module.record Func : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bcong : Congruent _≈₁_ _≈₂_ toisCongruent : IsCongruent toisCongruent = record{ cong = cong; isEquivalence₁ = isEquivalence From; isEquivalence₂ = isEquivalence To}open IsCongruent isCongruent publicusing (module Eq₁; module Eq₂)record Injection : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bcong : Congruent _≈₁_ _≈₂_ toinjective : Injective _≈₁_ _≈₂_ tofunction : Funcfunction = record{ to = to; cong = cong}open Func function publichiding (to; cong)isInjection : IsInjection toisInjection = record{ isCongruent = isCongruent; injective = injective}record Surjection : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bcong : Congruent _≈₁_ _≈₂_ tosurjective : Surjective _≈₁_ _≈₂_ tofunction : Funcfunction = record{ to = to; cong = cong}open Func function publichiding (to; cong)isSurjection : IsSurjection toisSurjection = record{ isCongruent = isCongruent; surjective = surjective}open IsSurjection isSurjection publicusing( strictlySurjective)to⁻ : B → Ato⁻ = proj₁ ∘ surjectiveto∘to⁻ : ∀ x → to (to⁻ x) ≈₂ xto∘to⁻ = proj₂ ∘ strictlySurjectiverecord Bijection : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bcong : Congruent _≈₁_ _≈₂_ tobijective : Bijective _≈₁_ _≈₂_ toinjective : Injective _≈₁_ _≈₂_ toinjective = proj₁ bijectivesurjective : Surjective _≈₁_ _≈₂_ tosurjective = proj₂ bijectiveinjection : Injectioninjection = record{ cong = cong; injective = injective}surjection : Surjectionsurjection = record{ cong = cong; surjective = surjective}open Injection injection public using (isInjection)open Surjection surjection public using (isSurjection; to⁻; strictlySurjective)isBijection : IsBijection toisBijection = record{ isInjection = isInjection; surjective = surjective}open IsBijection isBijection public using (module Eq₁; module Eq₂)-------------------------------------------------------------------------- Bundles with two elementsmodule _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) whereopen Setoid From using () renaming (Carrier to A; _≈_ to _≈₁_)open Setoid To using () renaming (Carrier to B; _≈_ to _≈₂_)open FunctionStructures _≈₁_ _≈₂_record Equivalence : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom-cong : Congruent _≈₂_ _≈₁_ fromtoFunction : Func From TotoFunction = record{ to = to; cong = to-cong}open Func toFunction publicusing (module Eq₁; module Eq₂)renaming (isCongruent to to-isCongruent)fromFunction : Func To FromfromFunction = record{ to = from; cong = from-cong}open Func fromFunction publicusing ()renaming (isCongruent to from-isCongruent)record LeftInverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom-cong : Congruent _≈₂_ _≈₁_ frominverseˡ : Inverseˡ _≈₁_ _≈₂_ to fromisCongruent : IsCongruent toisCongruent = record{ cong = to-cong; isEquivalence₁ = isEquivalence From; isEquivalence₂ = isEquivalence To}isLeftInverse : IsLeftInverse to fromisLeftInverse = record{ isCongruent = isCongruent; from-cong = from-cong; inverseˡ = inverseˡ}open IsLeftInverse isLeftInverse publicusing (module Eq₁; module Eq₂; strictlyInverseˡ; isSurjection)equivalence : Equivalenceequivalence = record{ to-cong = to-cong; from-cong = from-cong}isSplitSurjection : IsSplitSurjection toisSplitSurjection = record{ from = from; isLeftInverse = isLeftInverse}surjection : Surjection From Tosurjection = record{ to = to; cong = to-cong; surjective = λ y → from y , inverseˡ}record RightInverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom-cong : from Preserves _≈₂_ ⟶ _≈₁_inverseʳ : Inverseʳ _≈₁_ _≈₂_ to fromisCongruent : IsCongruent toisCongruent = record{ cong = to-cong; isEquivalence₁ = isEquivalence From; isEquivalence₂ = isEquivalence To}isRightInverse : IsRightInverse to fromisRightInverse = record{ isCongruent = isCongruent; from-cong = from-cong; inverseʳ = inverseʳ}open IsRightInverse isRightInverse publicusing (module Eq₁; module Eq₂; strictlyInverseʳ)equivalence : Equivalenceequivalence = record{ to-cong = to-cong; from-cong = from-cong}record Inverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom-cong : Congruent _≈₂_ _≈₁_ frominverse : Inverseᵇ _≈₁_ _≈₂_ to frominverseˡ : Inverseˡ _≈₁_ _≈₂_ to frominverseˡ = proj₁ inverseinverseʳ : Inverseʳ _≈₁_ _≈₂_ to frominverseʳ = proj₂ inverseleftInverse : LeftInverseleftInverse = record{ to-cong = to-cong; from-cong = from-cong; inverseˡ = inverseˡ}rightInverse : RightInverserightInverse = record{ to-cong = to-cong; from-cong = from-cong; inverseʳ = inverseʳ}open LeftInverse leftInverse public using (isLeftInverse; strictlyInverseˡ)open RightInverse rightInverse public using (isRightInverse; strictlyInverseʳ)isInverse : IsInverse to fromisInverse = record{ isLeftInverse = isLeftInverse; inverseʳ = inverseʳ}open IsInverse isInverse public using (module Eq₁; module Eq₂)-------------------------------------------------------------------------- Bundles with three elementsrecord BiEquivalence : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom₁ : B → Afrom₂ : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom₁-cong : Congruent _≈₂_ _≈₁_ from₁from₂-cong : Congruent _≈₂_ _≈₁_ from₂record BiInverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldto : A → Bfrom₁ : B → Afrom₂ : B → Ato-cong : Congruent _≈₁_ _≈₂_ tofrom₁-cong : Congruent _≈₂_ _≈₁_ from₁from₂-cong : Congruent _≈₂_ _≈₁_ from₂inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from₁inverseʳ : Inverseʳ _≈₁_ _≈₂_ to from₂to-isCongruent : IsCongruent toto-isCongruent = record{ cong = to-cong; isEquivalence₁ = isEquivalence From; isEquivalence₂ = isEquivalence To}isBiInverse : IsBiInverse to from₁ from₂isBiInverse = record{ to-isCongruent = to-isCongruent; from₁-cong = from₁-cong; from₂-cong = from₂-cong; inverseˡ = inverseˡ; inverseʳ = inverseʳ}biEquivalence : BiEquivalencebiEquivalence = record{ to-cong = to-cong; from₁-cong = from₁-cong; from₂-cong = from₂-cong}-------------------------------------------------------------------------- Other-- A left inverse is also known as a “split surjection”.---- As the name implies, a split surjection is a special kind of-- surjection where the witness generated in the domain in the-- function for elements `x₁` and `x₂` are equal if `x₁ ≈ x₂` .---- The difference is the `from-cong` law --- generally, the section-- (called `Surjection.to⁻` or `SplitSurjection.from`) of a surjection-- need not respect equality, whereas it must in a split surjection.---- The two notions coincide when the equivalence relation on `B` is-- propositional equality (because all functions respect propositional-- equality).---- For further background on (split) surjections, one may consult any-- general mathematical references which work without the principle-- of choice. For example:---- https://ncatlab.org/nlab/show/split+epimorphism.---- The connection to set-theoretic notions with the same names is-- justified by the setoid type theory/homotopy type theory-- observation/definition that (∃x : A. P) = ∥ Σx : A. P ∥ --- i.e.,-- we can read set-theoretic ∃ as squashed/propositionally truncated Σ.---- We see working with setoids as working in the MLTT model of a setoid-- type theory, in which ∥ X ∥ is interpreted as the setoid with carrier-- set X and the equivalence relation that relates all elements.-- All maps into ∥ X ∥ respect equality, so in the idiomatic definitions-- here, we drop the corresponding trivial `cong` field completely.SplitSurjection : Set _SplitSurjection = LeftInversemodule SplitSurjection (splitSurjection : SplitSurjection) =LeftInverse splitSurjection-------------------------------------------------------------------------- Infix abbreviations for oft-used items-------------------------------------------------------------------------- Same naming convention as used for propositional equality below, with-- appended ₛ (for 'S'etoid).infixr 0 _⟶ₛ__⟶ₛ_ : Setoid a ℓ₁ → Setoid b ℓ₂ → Set __⟶ₛ_ = Func-------------------------------------------------------------------------- Bundles specialised for propositional equality------------------------------------------------------------------------infix 3 _⟶_ _↣_ _↠_ _⤖_ _⇔_ _↩_ _↪_ _↩↪_ _↔__⟶_ : Set a → Set b → Set _A ⟶ B = Func (≡.setoid A) (≡.setoid B)_↣_ : Set a → Set b → Set _A ↣ B = Injection (≡.setoid A) (≡.setoid B)_↠_ : Set a → Set b → Set _A ↠ B = Surjection (≡.setoid A) (≡.setoid B)_⤖_ : Set a → Set b → Set _A ⤖ B = Bijection (≡.setoid A) (≡.setoid B)_⇔_ : Set a → Set b → Set _A ⇔ B = Equivalence (≡.setoid A) (≡.setoid B)_↩_ : Set a → Set b → Set _A ↩ B = LeftInverse (≡.setoid A) (≡.setoid B)_↪_ : Set a → Set b → Set _A ↪ B = RightInverse (≡.setoid A) (≡.setoid B)_↩↪_ : Set a → Set b → Set _A ↩↪ B = BiInverse (≡.setoid A) (≡.setoid B)_↔_ : Set a → Set b → Set _A ↔ B = Inverse (≡.setoid A) (≡.setoid B)-- We now define some constructors for the above that-- automatically provide the required congruency proofs.module _ {A : Set a} {B : Set b} wheremk⟶ : (A → B) → A ⟶ Bmk⟶ to = record{ to = to; cong = ≡.cong to}mk↣ : ∀ {to : A → B} → Injective _≡_ _≡_ to → A ↣ Bmk↣ {to} inj = record{ to = to; cong = ≡.cong to; injective = inj}mk↠ : ∀ {to : A → B} → Surjective _≡_ _≡_ to → A ↠ Bmk↠ {to} surj = record{ to = to; cong = ≡.cong to; surjective = surj}mk⤖ : ∀ {to : A → B} → Bijective _≡_ _≡_ to → A ⤖ Bmk⤖ {to} bij = record{ to = to; cong = ≡.cong to; bijective = bij}mk⇔ : ∀ (to : A → B) (from : B → A) → A ⇔ Bmk⇔ to from = record{ to = to; from = from; to-cong = ≡.cong to; from-cong = ≡.cong from}mk↩ : ∀ {to : A → B} {from : B → A} → Inverseˡ _≡_ _≡_ to from → A ↩ Bmk↩ {to} {from} invˡ = record{ to = to; from = from; to-cong = ≡.cong to; from-cong = ≡.cong from; inverseˡ = invˡ}mk↪ : ∀ {to : A → B} {from : B → A} → Inverseʳ _≡_ _≡_ to from → A ↪ Bmk↪ {to} {from} invʳ = record{ to = to; from = from; to-cong = ≡.cong to; from-cong = ≡.cong from; inverseʳ = invʳ}mk↩↪ : ∀ {to : A → B} {from₁ : B → A} {from₂ : B → A} →Inverseˡ _≡_ _≡_ to from₁ → Inverseʳ _≡_ _≡_ to from₂ → A ↩↪ Bmk↩↪ {to} {from₁} {from₂} invˡ invʳ = record{ to = to; from₁ = from₁; from₂ = from₂; to-cong = ≡.cong to; from₁-cong = ≡.cong from₁; from₂-cong = ≡.cong from₂; inverseˡ = invˡ; inverseʳ = invʳ}mk↔ : ∀ {to : A → B} {from : B → A} → Inverseᵇ _≡_ _≡_ to from → A ↔ Bmk↔ {to} {from} inv = record{ to = to; from = from; to-cong = ≡.cong to; from-cong = ≡.cong from; inverse = inv}-- Strict variant of the above.mk↠ₛ : ∀ {to : A → B} → StrictlySurjective _≡_ to → A ↠ Bmk↠ₛ = mk↠ ∘ strictlySurjective⇒surjectivemk↔ₛ′ : ∀ (to : A → B) (from : B → A) →StrictlyInverseˡ _≡_ to from →StrictlyInverseʳ _≡_ to from →A ↔ Bmk↔ₛ′ to from invˡ invʳ = mk↔ {to} {from}( strictlyInverseˡ⇒inverseˡ to invˡ, strictlyInverseʳ⇒inverseʳ to invʳ)-------------------------------------------------------------------------- Other-------------------------------------------------------------------------- Alternative syntax for the application of functionsmodule _ {From : Setoid a ℓ₁} {To : Setoid b ℓ₂} whereopen Setoidinfixl 5 _⟨$⟩__⟨$⟩_ : Func From To → Carrier From → Carrier To_⟨$⟩_ = Func.to
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-}module Function.Bijection where{-# WARNING_ON_IMPORT"Function.Bijection was deprecated in v2.0.Use the standard function hierarchy in Function/Function.Bundles instead."#-}open import Levelopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality as ≡open import Function.Equality as Fusing (_⟶_; _⟨$⟩_) renaming (_∘_ to _⟪∘⟫_)open import Function.Injection as Inj hiding (id; _∘_; injection)open import Function.Surjection as Surj hiding (id; _∘_; surjection)open import Function.LeftInverse as Left hiding (id; _∘_; leftInverse)-------------------------------------------------------------------------- Bijective functions.record Bijective {f₁ f₂ t₁ t₂}{From : Setoid f₁ f₂} {To : Setoid t₁ t₂}(to : From ⟶ To) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldinjective : Injective tosurjective : Surjective toopen Surjective surjective publicleft-inverse-of : from LeftInverseOf toleft-inverse-of x = injective (right-inverse-of (to ⟨$⟩ x)){-# WARNING_ON_USAGE Bijective"Warning: Bijective was deprecated in v2.0.Please use Function.(Structures.)IsBijection instead."#-}-------------------------------------------------------------------------- The set of all bijections between two setoids.record Bijection {f₁ f₂ t₁ t₂}(From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :Set (f₁ ⊔ f₂ ⊔ t₁ ⊔ t₂) wherefieldto : From ⟶ Tobijective : Bijective toopen Bijective bijective publicinjection : Injection From Toinjection = record{ to = to; injective = injective}surjection : Surjection From Tosurjection = record{ to = to; surjective = surjective}open Surjection surjection publicusing (equivalence; right-inverse; from-to)left-inverse : LeftInverse From Toleft-inverse = record{ to = to; from = from; left-inverse-of = left-inverse-of}open LeftInverse left-inverse public using (to-from){-# WARNING_ON_USAGE Bijection"Warning: Bijection was deprecated in v2.0.Please use Function.(Bundles.)Bijection instead."#-}-------------------------------------------------------------------------- The set of all bijections between two sets (i.e. bijections with-- propositional equality)infix 3 _⤖__⤖_ : ∀ {f t} → Set f → Set t → Set _From ⤖ To = Bijection (≡.setoid From) (≡.setoid To){-# WARNING_ON_USAGE _⤖_"Warning: _⤖_ was deprecated in v2.0.Please use Function.(Bundles.)mk⤖ instead."#-}bijection : ∀ {f t} {From : Set f} {To : Set t} →(to : From → To) (from : To → From) →(∀ {x y} → to x ≡ to y → x ≡ y) →(∀ x → to (from x) ≡ x) →From ⤖ Tobijection to from inj invʳ = record{ to = F.→-to-⟶ to; bijective = record{ injective = inj; surjective = record{ from = F.→-to-⟶ from; right-inverse-of = invʳ}}}{-# WARNING_ON_USAGE bijection"Warning: bijection was deprecated in v2.0.Please use either Function.Properties.Bijection.trans orFunction.Construct.Composition.bijection instead."#-}-------------------------------------------------------------------------- Identity and composition. (Note that these proofs are superfluous,-- given that Bijection is equivalent to Function.Inverse.Inverse.)id : ∀ {s₁ s₂} {S : Setoid s₁ s₂} → Bijection S Sid {S = S} = record{ to = F.id; bijective = record{ injective = Injection.injective (Inj.id {S = S}); surjective = Surjection.surjective (Surj.id {S = S})}}{-# WARNING_ON_USAGE id"Warning: id was deprecated in v2.0.Please use either Function.Properties.Bijection.refl orFunction.Construct.Identity.bijection instead."#-}infixr 9 _∘__∘_ : ∀ {f₁ f₂ m₁ m₂ t₁ t₂}{F : Setoid f₁ f₂} {M : Setoid m₁ m₂} {T : Setoid t₁ t₂} →Bijection M T → Bijection F M → Bijection F Tf ∘ g = record{ to = to f ⟪∘⟫ to g; bijective = record{ injective = Injection.injective (Inj._∘_ (injection f) (injection g)); surjective = Surjection.surjective (Surj._∘_ (surjection f) (surjection g))}} where open Bijection{-# WARNING_ON_USAGE _∘_"Warning: _∘_ was deprecated in v2.0.Please use either Function.Properties.Bijection.trans orFunction.Construct.Composition.bijection instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Simple combinators working solely on and with functions-------------------------------------------------------------------------- The contents of this module is also accessible via the `Function`-- module. See `Function.Strict` for strict versions of these-- combinators.{-# OPTIONS --cubical-compatible --safe #-}module Function.Base whereopen import Level using (Level)privatevariablea b c d e : LevelA : Set aB : Set bC : Set cD : Set dE : Set e-------------------------------------------------------------------------- Some simple functionsid : A → Aid x = xconst : A → B → Aconst x = λ _ → xconstᵣ : A → B → Bconstᵣ _ = id-------------------------------------------------------------------------- Operations on dependent functions-- These are functions whose output has a type that depends on the-- value of the input to the function.infixr 9 _∘_ _∘₂_infixl 8 _ˢ_infixl 0 _|>_infix 0 case_return_of_infixr -1 _$_-- Composition_∘_ : ∀ {A : Set a} {B : A → Set b} {C : {x : A} → B x → Set c} →(∀ {x} (y : B x) → C y) → (g : (x : A) → B x) →((x : A) → C (g x))f ∘ g = λ x → f (g x){-# INLINE _∘_ #-}_∘₂_ : ∀ {A₁ : Set a} {A₂ : A₁ → Set d}{B : (x : A₁) → A₂ x → Set b}{C : {x : A₁} → {y : A₂ x} → B x y → Set c} →({x : A₁} → {y : A₂ x} → (z : B x y) → C z) →(g : (x : A₁) → (y : A₂ x) → B x y) →((x : A₁) → (y : A₂ x) → C (g x y))f ∘₂ g = λ x y → f (g x y)-- Flipping order of argumentsflip : ∀ {A : Set a} {B : Set b} {C : A → B → Set c} →((x : A) (y : B) → C x y) → ((y : B) (x : A) → C x y)flip f = λ y x → f x y{-# INLINE flip #-}-- Application - note that _$_ is right associative, as in Haskell.-- If you want a left associative infix application operator, use-- RawFunctor._<$>_ from Effect.Functor._$_ : ∀ {A : Set a} {B : A → Set b} →((x : A) → B x) → ((x : A) → B x)f $ x = f x{-# INLINE _$_ #-}-- Flipped application (aka pipe-forward)_|>_ : ∀ {A : Set a} {B : A → Set b} →(a : A) → (∀ a → B a) → B a_|>_ = flip _$_{-# INLINE _|>_ #-}-- The S combinator - written infix as in Conor McBride's paper-- "Outrageous but Meaningful Coincidences: Dependent type-safe syntax-- and evaluation"._ˢ_ : ∀ {A : Set a} {B : A → Set b} {C : (x : A) → B x → Set c} →((x : A) (y : B x) → C x y) →(g : (x : A) → B x) →((x : A) → C x (g x))f ˢ g = λ x → f x (g x){-# INLINE _ˢ_ #-}-- Converting between implicit and explicit function spaces._$- : ∀ {A : Set a} {B : A → Set b} → ((x : A) → B x) → ({x : A} → B x)f $- = f _{-# INLINE _$- #-}λ- : ∀ {A : Set a} {B : A → Set b} → ({x : A} → B x) → ((x : A) → B x)λ- f = λ x → f{-# INLINE λ- #-}-- Case expressions (to be used with pattern-matching lambdas, see-- README.Case).case_returning_of_ : ∀ {A : Set a} (x : A) (B : A → Set b) →((x : A) → B x) → B xcase x returning B of f = f x{-# INLINE case_returning_of_ #-}-------------------------------------------------------------------------- Non-dependent versions of dependent operations-- Any of the above operations for dependent functions will also work-- for non-dependent functions but sometimes Agda has difficulty-- inferring the non-dependency. Primed (′ = \prime) versions of the-- operations are therefore provided below that sometimes have better-- inference properties.infixr 9 _∘′_ _∘₂′_infixl 0 _|>′_infix 0 case_of_infixr -1 _$′_-- Composition_∘′_ : (B → C) → (A → B) → (A → C)f ∘′ g = _∘_ f g_∘₂′_ : (C → D) → (A → B → C) → (A → B → D)f ∘₂′ g = _∘₂_ f g-- Flipping order of argumentsflip′ : (A → B → C) → (B → A → C)flip′ = flip-- Application_$′_ : (A → B) → (A → B)_$′_ = _$_-- Flipped application (aka pipe-forward)_|>′_ : A → (A → B) → B_|>′_ = _|>_-- Case expressions (to be used with pattern-matching lambdas, see-- README.Case).case_of_ : A → (A → B) → Bcase x of f = case x returning _ of f{-# INLINE case_of_ #-}-------------------------------------------------------------------------- Operations that are only defined for non-dependent functionsinfixl 1 _⟨_⟩_infixl 0 _∋_-- Binary application_⟨_⟩_ : A → (A → B → C) → B → Cx ⟨ f ⟩ y = f x y-- In Agda you cannot annotate every subexpression with a type-- signature. This function can be used instead._∋_ : (A : Set a) → A → AA ∋ x = x-- Conversely it is sometimes useful to be able to extract the-- type of a given expression.typeOf : {A : Set a} → A → Set atypeOf {A = A} _ = A-- Construct an element of the given type by instance search.it : {A : Set a} → {{A}} → Ait {{x}} = x-------------------------------------------------------------------------- Composition of a binary function with other functionsinfixr 0 _-⟪_⟫-_ _-⟨_⟫-_infixl 0 _-⟪_⟩-_infixr 1 _-⟨_⟩-_ ∣_⟫-_ ∣_⟩-_infixl 1 _on_ _on₂_ _-⟪_∣ _-⟨_∣-- Two binary functions_-⟪_⟫-_ : (A → B → C) → (C → D → E) → (A → B → D) → (A → B → E)f -⟪ _*_ ⟫- g = λ x y → f x y * g x y-- A single binary function on the left_-⟪_∣ : (A → B → C) → (C → B → D) → (A → B → D)f -⟪ _*_ ∣ = f -⟪ _*_ ⟫- constᵣ-- A single binary function on the right∣_⟫-_ : (A → C → D) → (A → B → C) → (A → B → D)∣ _*_ ⟫- g = const -⟪ _*_ ⟫- g-- A single unary function on the left_-⟨_∣ : (A → C) → (C → B → D) → (A → B → D)f -⟨ _*_ ∣ = f ∘₂ const -⟪ _*_ ∣-- A single unary function on the right∣_⟩-_ : (A → C → D) → (B → C) → (A → B → D)∣ _*_ ⟩- g = ∣ _*_ ⟫- g ∘₂ constᵣ-- A binary function and a unary function_-⟪_⟩-_ : (A → B → C) → (C → D → E) → (B → D) → (A → B → E)f -⟪ _*_ ⟩- g = f -⟪ _*_ ⟫- ∣ constᵣ ⟩- g-- A unary function and a binary function_-⟨_⟫-_ : (A → C) → (C → D → E) → (A → B → D) → (A → B → E)f -⟨ _*_ ⟫- g = f -⟨ const ∣ -⟪ _*_ ⟫- g-- Two unary functions_-⟨_⟩-_ : (A → C) → (C → D → E) → (B → D) → (A → B → E)f -⟨ _*_ ⟩- g = f -⟨ const ∣ -⟪ _*_ ⟫- ∣ constᵣ ⟩- g-- A single binary function on both sides_on₂_ : (C → C → D) → (A → B → C) → (A → B → D)_*_ on₂ f = f -⟪ _*_ ⟫- f-- A single unary function on both sides_on_ : (B → B → C) → (A → B) → (A → A → C)_*_ on f = f -⟨ _*_ ⟩- f-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4_-[_]-_ = _-⟪_⟫-_{-# WARNING_ON_USAGE _-[_]-_"Warning: Function._-[_]-_ was deprecated in v1.4.Please use _-⟪_⟫-_ instead."#-}-- Version 2.0case_return_of_ = case_returning_of_{-# WARNING_ON_USAGE case_return_of_"case_return_of_ was deprecated in v2.0.Please use case_returning_of_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Type(s) used (only) when calling out to Haskell via the FFI------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Foreign.Haskell whereopen import Level-------------------------------------------------------------------------- Pairsopen import Foreign.Haskell.Pair publicrenaming( toForeign to toForeignPair; fromForeign to fromForeignPair)-------------------------------------------------------------------------- Sumsopen import Foreign.Haskell.Either publicrenaming( toForeign to toForeignEither; fromForeign to fromForeignEither)
-------------------------------------------------------------------------- The Agda standard library---- Monads-------------------------------------------------------------------------- Note that currently the monad laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad whereopen import Data.Bool.Base using (Bool; true; false; not)open import Data.Unit.Polymorphic.Base using (⊤)open import Effect.Choiceopen import Effect.Emptyopen import Effect.Applicativeopen import Function.Base using (id; flip; _$′_; _∘′_)open import Level using (Level; suc; _⊔_)privatevariablef g g₁ g₂ : LevelA B C : Set f-------------------------------------------------------------------------- The type of raw monadsrecord RawMonad (F : Set f → Set g) : Set (suc f ⊔ g) whereinfixl 1 _>>=_ _>>_ _>=>_infixr 1 _=<<_ _<=<_fieldrawApplicative : RawApplicative F_>>=_ : F A → (A → F B) → F Bopen RawApplicative rawApplicative public_>>_ : F A → F B → F B_>>_ = _*>__=<<_ : (A → F B) → F A → F B_=<<_ = flip _>>=_Kleisli : Set f → Set f → Set (f ⊔ g)Kleisli A B = A → F B_>=>_ : Kleisli A B → Kleisli B C → Kleisli A C(f >=> g) a = f a >>= g_<=<_ : Kleisli B C → Kleisli A B → Kleisli A C_<=<_ = flip _>=>_when : Bool → F ⊤ → F ⊤when true m = mwhen false m = pure _unless : Bool → F ⊤ → F ⊤unless = when ∘′ not-- When level g=f, a join/μ operator is definablemodule Join {F : Set f → Set f} (M : RawMonad F) whereopen RawMonad Mjoin : F (F A) → F Ajoin = _>>= id-- Smart constructormodule _ whereopen RawMonadopen RawApplicativemkRawMonad :(F : Set f → Set g) →(pure : ∀ {A} → A → F A) →(bind : ∀ {A B} → F A → (A → F B) → F B) →RawMonad FmkRawMonad F pure _>>=_ .rawApplicative =mkRawApplicative _ pure $′ λ mf mx → dof ← mfx ← mxpure (f x)mkRawMonad F pure _>>=_ ._>>=_ = _>>=_-------------------------------------------------------------------------- The type of raw monads with a zerorecord RawMonadZero (F : Set f → Set g) : Set (suc f ⊔ g) wherefieldrawMonad : RawMonad FrawEmpty : RawEmpty Fopen RawMonad rawMonad publicopen RawEmpty rawEmpty publicrawApplicativeZero : RawApplicativeZero FrawApplicativeZero = record{ rawApplicative = rawApplicative; rawEmpty = rawEmpty}-------------------------------------------------------------------------- The type of raw monadplusrecord RawMonadPlus (F : Set f → Set g) : Set (suc f ⊔ g) wherefieldrawMonadZero : RawMonadZero FrawChoice : RawChoice Fopen RawMonadZero rawMonadZero publicopen RawChoice rawChoice publicrawAlternative : RawAlternative FrawAlternative = record{ rawApplicativeZero = rawApplicativeZero; rawChoice = rawChoice}-------------------------------------------------------------------------- The type of raw monad transformer-- F has been RawMonadT'd as TFrecord RawMonadTd (F : Set f → Set g₁) (TF : Set f → Set g₂) : Set (suc f ⊔ g₁ ⊔ g₂) wherefieldlift : F A → TF ArawMonad : RawMonad TFopen RawMonad rawMonad publicRawMonadT : (T : (Set f → Set g₁) → (Set f → Set g₂)) → Set (suc f ⊔ suc g₁ ⊔ g₂)RawMonadT T = ∀ {M} → RawMonad M → RawMonadTd M (T M)
-------------------------------------------------------------------------- The Agda standard library---- The writer monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Writer whereopen import Algebra using (RawMonoid)open import Data.Product.Base using (_×_)open import Effect.Applicative using (RawApplicative)open import Effect.Functor using (RawFunctor)open import Effect.Monad using (RawMonad; module Join)open import Effect.Monad.Identity as Id using (Identity; runIdentity)open import Level using (Level)import Effect.Monad.Writer.Transformer as Transprivatevariablew ℓ : LevelA : Set w𝕎 : RawMonoid w ℓ-------------------------------------------------------------------------- Re-export the monad writer operationsopen Trans publicusing (RawMonadWriter)-------------------------------------------------------------------------- Writer monadWriter : (𝕎 : RawMonoid w ℓ) (A : Set w) → Set wWriter 𝕎 = Trans.WriterT 𝕎 Identityfunctor : RawFunctor (Writer 𝕎)functor = Trans.functor Id.functormodule _ {𝕎 : RawMonoid w ℓ} whereopen RawMonoid 𝕎 renaming (Carrier to W)runWriter : Writer 𝕎 A → W × ArunWriter ma = runIdentity (Trans.runWriterT ma ε)applicative : RawApplicative (Writer 𝕎)applicative = Trans.applicative Id.applicativemonad : RawMonad (Writer 𝕎)monad = Trans.monad Id.monadjoin : Writer 𝕎 (Writer 𝕎 A) → Writer 𝕎 Ajoin = Join.join monad------------------------------------------------------------------------ Writer monad specificsmonadWriter : RawMonadWriter 𝕎 (Writer 𝕎)monadWriter = Trans.monadWriter Id.monad
-------------------------------------------------------------------------- The Agda standard library---- The writer monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Writer.Transformer whereopen import Algebra using (RawMonoid)open import Data.Product.Base using (_×_; _,_; proj₂; map₂)open import Effect.Applicative using (RawApplicative; RawApplicativeZero; RawAlternative)open import Effect.Choice using (RawChoice)open import Effect.Empty using (RawEmpty)open import Effect.Functor using (RawFunctor)open import Effect.Monad using (RawMonad; RawMonadZero; RawMonadPlus; RawMonadT)open import Function.Base using (_∘′_; const; _$_)open import Level using (Level)privatevariablew g g₁ g₂ : LevelA B : Set wM : Set w → Set g𝕎 : RawMonoid w g-------------------------------------------------------------------------- Re-export the basic type definitionsopen import Effect.Monad.Writer.Transformer.Base publicusing ( RawMonadWriter; WriterT; mkWriterT; runWriterT)-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor (WriterT 𝕎 M)functor M = record{ _<$>_ = λ f ma → mkWriterT λ w → map₂ f <$> runWriterT ma w} where open RawFunctor Mempty : RawEmpty M → RawEmpty (WriterT 𝕎 M)empty M = record{ empty = mkWriterT (const (RawEmpty.empty M))}choice : RawChoice M → RawChoice (WriterT 𝕎 M)choice M = record{ _<|>_ = λ ma₁ ma₂ → mkWriterT λ w →WriterT.runWriterT ma₁ w<|> WriterT.runWriterT ma₂ w} where open RawChoice Mmodule _ {𝕎 : RawMonoid w g} whereopen RawMonoid 𝕎 renaming (Carrier to W)applicative : RawApplicative M → RawApplicative (WriterT 𝕎 M)applicative M = record{ rawFunctor = functor rawFunctor; pure = λ a → mkWriterT (pure ∘′ (_, a)); _<*>_ = λ mf mx → mkWriterT $ λ w →(go <$> runWriterT mf w) <*> runWriterT mx ε} whereopen RawApplicative Mgo : W × (A → B) → W × A → W × Bgo (w₁ , f) (w₂ , x) = w₁ ∙ w₂ , f xapplicativeZero : RawApplicativeZero M → RawApplicativeZero (WriterT 𝕎 M)applicativeZero M = record{ rawApplicative = applicative rawApplicative; rawEmpty = empty rawEmpty} where open RawApplicativeZero M using (rawApplicative; rawEmpty)alternative : RawAlternative M → RawAlternative (WriterT 𝕎 M)alternative M = record{ rawApplicativeZero = applicativeZero rawApplicativeZero; rawChoice = choice rawChoice} where open RawAlternative Mmonad : RawMonad M → RawMonad (WriterT 𝕎 M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma f → mkWriterT λ w → dow₁ , a ← runWriterT ma wrunWriterT (f a) w₁} where open RawMonad MmonadZero : RawMonadZero M → RawMonadZero (WriterT 𝕎 M)monadZero M = record{ rawMonad = monad (RawMonadZero.rawMonad M); rawEmpty = empty (RawMonadZero.rawEmpty M)}monadPlus : RawMonadPlus M → RawMonadPlus (WriterT 𝕎 M)monadPlus M = record{ rawMonadZero = monadZero rawMonadZero; rawChoice = choice rawChoice} where open RawMonadPlus M------------------------------------------------------------------------ Monad writer transformer specificsmonadT : RawMonadT {g₁ = g₁} {g₂ = _} (WriterT 𝕎)monadT M = record{ lift = mkWriterT ∘′ λ ma w → (w ,_) <$> ma; rawMonad = monad M} where open RawMonad MmonadWriter : RawMonad M → RawMonadWriter 𝕎 (WriterT 𝕎 M)monadWriter M = record{ writer = mkWriterT ∘′ λ (w' , a) w → pure (w ∙ w' , a); listen = λ ma → mkWriterT λ w → dow , a ← runWriterT ma wpure (w , w , a); pass = λ mx → mkWriterT λ w → dow , f , a ← runWriterT mx wpure (f w , a)} where open RawMonad Mmodule _ {𝕎₁ : RawMonoid w g₁} whereopen RawMonoid 𝕎₁ renaming (Carrier to W₁)liftWriterT : (𝕎₂ : RawMonoid w g₂) →RawFunctor M →RawMonadWriter 𝕎₁ M →RawMonadWriter 𝕎₁ (WriterT 𝕎₂ M)liftWriterT 𝕎₂ M MWrite = record{ writer = λ (w , a) → mkWriterT λ w' → (writer (w , w' , a )); listen = λ mx → mkWriterT λ w' → ((λ (w₁ , w₂ , a) → w₂ , w₁ , a) <$> listen (runWriterT mx w')); pass = λ mx → mkWriterT λ w' → (pass ((λ (w , f , a) → f , w , a) <$> runWriterT mx w'))} where open RawMonadWriter MWriteopen RawFunctor MprivatevariableW₂ : Set g₂open import Effect.Monad.Reader.Transformer.BaseliftReaderT : RawFunctor M →RawMonadWriter 𝕎₁ M →RawMonadWriter 𝕎₁ (ReaderT W₂ M)liftReaderT M MWrite = record{ writer = mkReaderT ∘′ const ∘′ writer; listen = λ ma → mkReaderT (listen ∘′ runReaderT ma); pass = λ ma → mkReaderT (pass ∘′ runReaderT ma)} where open RawMonadWriter MWriteopen import Effect.Monad.State.Transformer.BaseliftStateT : RawFunctor M →RawMonadWriter 𝕎₁ M →RawMonadWriter 𝕎₁ (StateT W₂ M)liftStateT M MWrite = record{ writer = λ x → mkStateT λ w₂ → (w₂ ,_) <$>writer x; listen = λ mx → mkStateT λ w₂ → (w₂ ,_) <$>listen (proj₂ <$> runStateT mx w₂); pass = λ mx → mkStateT λ w₂ → (w₂ ,_) <$>pass ((λ (_ , f , a) → f , a) <$> runStateT mx w₂)} where open RawMonadWriter MWriteopen RawFunctor M
-------------------------------------------------------------------------- The Agda standard library---- Basic type and definition of the writer monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Writer.Transformer.Base whereopen import Algebra using (RawMonoid)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Unit.Polymorphic using (⊤; tt)open import Function.Base using (id; _∘′_)open import Level using (Level; suc; _⊔_)open import Effect.Functor using (RawFunctor)privatevariablew f g : LevelA : Set gM : Set w → Set g𝕎 : RawMonoid w g-------------------------------------------------------------------------- Writer monad operationsrecord RawMonadWriter(𝕎 : RawMonoid w f)(M : Set w → Set g): Set (suc w ⊔ g) whereopen RawMonoid 𝕎 renaming (Carrier to W)fieldwriter : W × A → M Alisten : M A → M (W × A)pass : M ((W → W) × A) → M Atell : W → M ⊤tell w = writer (w , tt)-------------------------------------------------------------------------- Writer monad transformer (CPS-encoded)record WriterT(𝕎 : RawMonoid w f)(M : Set w → Set g)(A : Set w): Set (w ⊔ g) whereconstructor mkWriterTopen RawMonoid 𝕎 renaming (Carrier to W)field runWriterT : W → M (W × A)open WriterT publicmodule _ {𝕎 : RawMonoid w f} whereopen RawMonoid 𝕎 renaming (Carrier to W)evalWriterT : RawFunctor M → WriterT 𝕎 M A → M AevalWriterT M ma = proj₂ <$> runWriterT ma εwhere open RawFunctor MexecWriterT : RawFunctor M → WriterT 𝕎 M A → M WexecWriterT M ma = proj₁ <$> runWriterT ma εwhere open RawFunctor M
-------------------------------------------------------------------------- The Agda standard library---- Instances for the writer monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Writer.Instances whereopen import Effect.Monad.Writer.TransformerinstancewriterTFunctor = λ {s} {S} {f} {M} {{fun}} {{mo}} → functor {s} {S} {f} {M} {mo} funwriterTApplicative = λ {s} {S} {f} {M} {{mo}} {{mon}} → applicative {s} {S} {f} {M} {mo} monwriterTEmpty = λ {s} {S} {f} {M} {{e}} {{mo}} → empty {s} {S} {f} {M} {mo} ewriterTChoice = λ {s} {S} {f} {M} {{ch}} {{mo}} → choice {s} {S} {f} {M} {mo} chwriterTApplicativeZero = λ {s} {S} {f} {M} {{mo}} {{mon}} → applicativeZero {s} {S} {f} {M} {mo} monwriterTAlternative = λ {s} {S} {f} {M} {{mo}} {{mpl}} → alternative {s} {S} {f} {M} {mo} mplwriterTMonad = λ {s} {S} {f} {M} {{mo}} {{mon}} → monad {s} {S} {f} {M} {mo} monwriterTMonadZero = λ {s} {S} {f} {M} {{mo}} {{mz}} → monadZero {s} {S} {f} {M} {mo} mzwriterTMonadPlus = λ {s} {S} {f} {M} {{mo}} {{mpl}} → monadPlus {s} {S} {f} {M} {mo} mplwriterTMonadT = λ {s} {S} {f} {M} {{mo}} {{mon}} → monadT {s} {S} {f} {M} {mo} monwriterTMonadWriter = λ {s} {S} {f} {M} {{mo}} {{mon}} → monadWriter {s} {S} {f} {M} {mo} monwriterTLiftReaderT = λ {s} {S₁} {S₂} {f} {g} {M} {{fun}} {{mw}} → liftReaderT {s} {S₁} {S₂} {f} {g} {M} fun mwwriterTLiftStateT = λ {s} {S₁} {S₂} {f} {g} {M} {{fun}} {{mw}} → liftStateT {s} {S₁} {S₂} {f} {g} {M} fun mw
-------------------------------------------------------------------------- The Agda standard library---- The indexed writer monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Effect.Monad.Writer.Indexed (a : Level) whereopen import Algebra using (RawMonoid)open import Data.Product.Base using (_×_; _,_; map₁)open import Data.Unit.Polymorphicopen import Effect.Applicative.Indexedopen import Effect.Monadopen import Effect.Monad.Indexedopen import Function.Base using (_∘′_)open import Function.Identity.Effectful as Id using (Identity)privatevariablew ℓ : LevelA B I : Set ℓ-------------------------------------------------------------------------- Indexed writerIWriterT : (𝕎 : RawMonoid w ℓ) → IFun I (w ⊔ a) → IFun I (w ⊔ a)IWriterT 𝕎 M i j A = M i j (RawMonoid.Carrier 𝕎 × A)module _ {M : IFun I (w ⊔ a)} {𝕎 : RawMonoid w ℓ} whereopen RawMonoid 𝕎 renaming (Carrier to W)------------------------------------------------------------------------ Indexed writer applicativeWriterTIApplicative : RawIApplicative M → RawIApplicative (IWriterT 𝕎 M)WriterTIApplicative App = record{ pure = λ x → pure (ε , x); _⊛_ = λ m n → go <$> m ⊛ n} whereopen RawIApplicative Appgo : W × (A → B) → W × A → W × Bgo (w₁ , f) (w₂ , x) = w₁ ∙ w₂ , f xWriterTIApplicativeZero : RawIApplicativeZero M →RawIApplicativeZero (IWriterT 𝕎 M)WriterTIApplicativeZero App = record{ applicative = WriterTIApplicative applicative; ∅ = ∅} where open RawIApplicativeZero AppWriterTIAlternative : RawIAlternative M → RawIAlternative (IWriterT 𝕎 M)WriterTIAlternative Alt = record{ applicativeZero = WriterTIApplicativeZero applicativeZero; _∣_ = _∣_} where open RawIAlternative Alt------------------------------------------------------------------------ Indexed writer monadWriterTIMonad : RawIMonad M → RawIMonad (IWriterT 𝕎 M)WriterTIMonad Mon = record{ return = λ x → return (ε , x); _>>=_ = λ m f → dow₁ , x ← mw₂ , fx ← f xreturn (w₁ ∙ w₂ , fx)} where open RawIMonad MonWriterTIMonadZero : RawIMonadZero M → RawIMonadZero (IWriterT 𝕎 M)WriterTIMonadZero Mon = record{ monad = WriterTIMonad monad; applicativeZero = WriterTIApplicativeZero applicativeZero} where open RawIMonadZero MonWriterTIMonadPlus : RawIMonadPlus M → RawIMonadPlus (IWriterT 𝕎 M)WriterTIMonadPlus Mon = record{ monad = WriterTIMonad monad; alternative = WriterTIAlternative alternative} where open RawIMonadPlus Mon-------------------------------------------------------------------------- Writer monad operationsrecord RawIMonadWriter {I : Set ℓ} (𝕎 : RawMonoid w ℓ) (M : IFun I (w ⊔ a)): Set (ℓ ⊔ suc (w ⊔ a)) whereopen RawMonoid 𝕎 renaming (Carrier to W)fieldmonad : RawIMonad Mwriter : ∀ {i} → (W × A) → M i i Alisten : ∀ {i j} → M i j A → M i j (W × A)pass : ∀ {i j} → M i j ((W → W) × A) → M i j Aopen RawIMonad monad publictell : ∀ {i} → W → M i i ⊤tell = writer ∘′ (_, tt)listens : ∀ {i j} {Z : Set w} → (W → Z) → M i j A → M i j (Z × A)listens f m = listen m >>= return ∘′ map₁ fcensor : ∀ {i j} → (W → W) → M i j A → M i j Acensor f m = pass (m >>= return ∘′ (f ,_))WriterTIMonadWriter : {I : Set ℓ} {𝕎 : RawMonoid w ℓ} {M : IFun I (w ⊔ a)} →RawIMonad M → RawIMonadWriter 𝕎 (IWriterT 𝕎 M)WriterTIMonadWriter {𝕎 = 𝕎} Mon = record{ monad = WriterTIMonad {𝕎 = 𝕎} Mon; writer = return; listen = λ m → dow , a ← mreturn (w , w , a); pass = λ m → dow , f , a ← mreturn (f w , a)} where open RawIMonad Monopen RawMonoid 𝕎 renaming (Carrier to W)
-------------------------------------------------------------------------- The Agda standard library---- The state monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.State whereopen import Data.Product.Base using (_×_)open import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; module Join)open import Effect.Monad.Identity as Id using (Identity; runIdentity)open import Level using (Level)import Effect.Monad.State.Transformer as Transprivatevariables : LevelS A : Set s-------------------------------------------------------------------------- Re-export the state monad operationsopen Trans publicusing (RawMonadState)-------------------------------------------------------------------------- State monadState : (S : Set s) (A : Set s) → Set sState S = Trans.StateT S IdentityrunState : State S A → S → S × ArunState ma s = runIdentity (Trans.runStateT ma s)evalState : State S A → S → AevalState ma s = runIdentity (Trans.evalStateT Id.functor ma s)execState : State S A → S → SexecState ma s = runIdentity (Trans.execStateT Id.functor ma s)-------------------------------------------------------------------------- Structurefunctor : RawFunctor (State S)functor = Trans.functor Id.functorapplicative : RawApplicative (State S)applicative = Trans.applicative Id.monadmonad : RawMonad (State S)monad = Trans.monad Id.monadjoin : State S (State S A) → State S Ajoin = Join.join monad-------------------------------------------------------------------------- State monad specificsmonadState : RawMonadState S (State S)monadState = Trans.monadState Id.monad
-------------------------------------------------------------------------- The Agda standard library---- The state monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.State.Transformer whereopen import Algebra using (RawMonoid)open import Data.Product.Base using (_×_; _,_; map₂; proj₁; proj₂)open import Data.Unit.Polymorphic.Base using (tt)open import Effect.Choice using (RawChoice)open import Effect.Empty using (RawEmpty)open import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative; RawApplicativeZero; RawAlternative)open import Effect.Monad using (RawMonad; RawMonadZero; RawMonadPlus; RawMonadT; RawMonadTd)open import Function.Base using (_∘′_; _$_; const)open import Level using (Level; _⊔_)privatevariablef s : LevelA B : Set sS S₁ S₂ : Set sM : Set s → Set f-------------------------------------------------------------------------- Re-export the basic type and definitionsopen import Effect.Monad.State.Transformer.Base publicusing ( RawMonadState; StateT; mkStateT; runStateT; evalStateT; execStateT)-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor (StateT S M)functor M = record{ _<$>_ = λ f ma → mkStateT (λ s → map₂ f <$> StateT.runStateT ma s)} where open RawFunctor Mapplicative : RawMonad M → RawApplicative (StateT S M)applicative M = record{ rawFunctor = functor rawFunctor; pure = λ a → mkStateT (pure ∘′ (_, a)); _<*>_ = λ mf mx → mkStateT $ λ s →do (s , f) ← StateT.runStateT mf s(s , x) ← StateT.runStateT mx spure (s , f x)} where open RawMonad Mempty : RawEmpty M → RawEmpty (StateT S M)empty M = record{ empty = mkStateT (const (RawEmpty.empty M))}choice : RawChoice M → RawChoice (StateT S M)choice M = record{ _<|>_ = λ ma₁ ma₂ → mkStateT $ λ s →StateT.runStateT ma₁ s<|> StateT.runStateT ma₂ s} where open RawChoice MapplicativeZero : RawMonadZero M → RawApplicativeZero (StateT S M)applicativeZero M = record{ rawApplicative = applicative (RawMonadZero.rawMonad M); rawEmpty = empty (RawMonadZero.rawEmpty M)}alternative : RawMonadPlus M → RawAlternative (StateT S M)alternative M = record{ rawApplicativeZero = applicativeZero rawMonadZero; rawChoice = choice rawChoice} where open RawMonadPlus Mmonad : RawMonad M → RawMonad (StateT S M)monad M = record{ rawApplicative = applicative M; _>>=_ = λ ma f → mkStateT $ λ s →do (s , a) ← StateT.runStateT ma sStateT.runStateT (f a) s} where open RawMonad MmonadZero : RawMonadZero M → RawMonadZero (StateT S M)monadZero M = record{ rawMonad = monad (RawMonadZero.rawMonad M); rawEmpty = empty (RawMonadZero.rawEmpty M)}monadPlus : RawMonadPlus M → RawMonadPlus (StateT S M)monadPlus M = record{ rawMonadZero = monadZero rawMonadZero; rawChoice = choice rawChoice} where open RawMonadPlus M-------------------------------------------------------------------------- State monad transformer specificsmonadT : RawMonadT {f = s} {g₁ = f} {g₂ = s ⊔ f} (StateT S)monadT M = record{ lift = λ ma → mkStateT (λ s → (s ,_) <$> ma); rawMonad = monad M} where open RawMonad MmonadState : RawMonad M → RawMonadState S (StateT S M)monadState M = record{ gets = λ f → mkStateT (λ s → pure (s , f s)); modify = λ f → mkStateT (λ s → pure (f s , _))} where open RawMonad M-------------------------------------------------------------------------- State monad transformer specificsliftStateT : RawMonad M →RawMonadState S₁ M →RawMonadState S₁ (StateT S₂ M)liftStateT M Mon = record{ gets = λ f₁ → lift (gets f₁); modify = λ f₁ → lift (modify f₁)} where open RawMonadTd (monadT M) using (lift); open RawMonadState Monopen import Effect.Monad.Reader.Transformer.BaseliftReaderT : RawMonadState S₁ M →RawMonadState S₁ (ReaderT S₂ M)liftReaderT Mon = record{ gets = λ f → mkReaderT (const (gets f)); modify = λ f → mkReaderT (const (modify f))} where open RawMonadState Monopen import Effect.Monad.Writer.Transformer.BaseliftWriterT : (MS : RawMonoid s f) →RawFunctor M →RawMonadState S M →RawMonadState S (WriterT MS M)liftWriterT MS M Mon = record{ gets = λ f → mkWriterT λ w → (gets ((w ,_) ∘′ f)); modify = λ f → mkWriterT λ w → (const (w , tt) <$> modify f)} where open RawMonadState Monopen RawFunctor M
-------------------------------------------------------------------------- The Agda standard library---- Basic definition and functions on the state monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.State.Transformer.Base whereopen import Data.Product.Base using (_×_; proj₁; proj₂)open import Data.Unit.Polymorphic.Base using (⊤)open import Function.Base using (_∘′_; const; id)open import Level using (Level; suc; _⊔_)open import Effect.Functorprivatevariablef s : LevelA : Set sS : Set sM : Set s → Set f-------------------------------------------------------------------------- State monad operationsrecord RawMonadState(S : Set s)(M : Set s → Set f): Set (suc s ⊔ f) wherefieldgets : (S → A) → M Amodify : (S → S) → M ⊤put = modify ∘′ constget = gets id-------------------------------------------------------------------------- State monad transformerrecord StateT(S : Set s)(M : Set s → Set f)(A : Set s): Set (s ⊔ f) whereconstructor mkStateTfield runStateT : S → M (S × A)open StateT publicevalStateT : RawFunctor M → StateT S M A → S → M AevalStateT M ma s = let open RawFunctor M in proj₂ <$> runStateT ma sexecStateT : RawFunctor M → StateT S M A → S → M SexecStateT M ma s = let open RawFunctor M in proj₁ <$> runStateT ma s
-------------------------------------------------------------------------- The Agda standard library---- Instances for the state monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.State.Instances whereopen import Effect.Monad.State.TransformerinstancestateTFunctor = λ {s} {S} {f} {M} {{fun}} → functor {s} {S} {f} {M} funstateTApplicative = λ {s} {S} {f} {M} {{mon}} → applicative {s} {S} {f} {M} monstateTEmpty = λ {s} {S} {f} {M} {{e}} → empty {s} {S} {f} {M} estateTChoice = λ {s} {S} {f} {M} {{ch}} → choice {s} {S} {f} {M} chstateTApplicativeZero = λ {s} {S} {f} {M} {{mon}} → applicativeZero {s} {S} {f} {M} monstateTAlternative = λ {s} {S} {f} {M} {{mpl}} → alternative {s} {S} {f} {M} mplstateTMonad = λ {s} {S} {f} {M} {{mon}} → monad {s} {S} {f} {M} monstateTMonadZero = λ {s} {S} {f} {M} {{mz}} → monadZero {s} {S} {f} {M} mzstateTMonadPlus = λ {s} {S} {f} {M} {{mpl}} → monadPlus {s} {S} {f} {M} mplstateTMonadT = λ {s} {S} {f} {M} {{mon}} → monadT {s} {S} {f} {M} monstateTMonadState = λ {s} {S} {f} {M} {{mon}} → monadState {s} {S} {f} {M} monstateTLiftReaderT = λ {R} {s} {S} {f} {M} {{ms}} → liftReaderT {R} {s} {S} {f} {M} msstateTLiftWriterT = λ {R} {s} {S} {f} {M} {{fun}} {{mo}} {{ms}} → liftWriterT {R} {s} {S} {f} {M} mo fun ms-- the following instances conflicts with stateTMonadState so we don't include it-- stateTLiftStateT = λ {s} {S₁} {S₂} {f} {M} {{mon}} {{ms}} → liftStateT {s} {S₁} {S₂} {f} {M} mon ms
-------------------------------------------------------------------------- The Agda standard library---- The indexed state monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.State.Indexed whereopen import Effect.Applicative.Indexedusing (IFun; RawIApplicative; RawIApplicativeZero; RawIAlternative)open import Effect.Monad using (RawMonad; RawMonadZero; RawMonadPlus)open import Function.Identity.Effectful as Id using (Identity)open import Effect.Monad.Indexed using (RawIMonad; RawIMonadZero;RawIMonadPlus)open import Data.Product.Base using (_×_; _,_; uncurry)open import Data.Unit.Polymorphic using (⊤)open import Function.Base using (const; _∘_)open import Level using (Level; _⊔_; suc)privatevariablei f : LevelI : Set i-------------------------------------------------------------------------- Indexed stateIStateT : (I → Set f) → (Set f → Set f) → IFun I fIStateT S M i j A = S i → M (A × S j)-------------------------------------------------------------------------- Indexed state applicativeStateTIApplicative : ∀ (S : I → Set f) {M} →RawMonad M → RawIApplicative (IStateT S M)StateTIApplicative S Mon = record{ pure = λ a s → pure (a , s); _⊛_ = λ f t s → do(f′ , s′) ← f s(t′ , s′′) ← t s′pure (f′ t′ , s′′)} where open RawMonad MonStateTIApplicativeZero : ∀ (S : I → Set f) {M} →RawMonadZero M → RawIApplicativeZero (IStateT S M)StateTIApplicativeZero S Mon = record{ applicative = StateTIApplicative S rawMonad; ∅ = const ∅} where open RawMonadZero MonStateTIAlternative : ∀ (S : I → Set f) {M} →RawMonadPlus M → RawIAlternative (IStateT S M)StateTIAlternative S Mon = record{ applicativeZero = StateTIApplicativeZero S rawMonadZero; _∣_ = λ m n s → m s ∣ n s} where open RawMonadPlus Mon-------------------------------------------------------------------------- Indexed state monadStateTIMonad : ∀ (S : I → Set f) {M} → RawMonad M → RawIMonad (IStateT S M)StateTIMonad S Mon = record{ return = λ x s → pure (x , s); _>>=_ = λ m f s → m s >>= uncurry f} where open RawMonad MonStateTIMonadZero : ∀ (S : I → Set f) {M} →RawMonadZero M → RawIMonadZero (IStateT S M)StateTIMonadZero S Mon = record{ monad = StateTIMonad S (RawMonadZero.rawMonad Mon); applicativeZero = StateTIApplicativeZero S Mon} where open RawMonadZero MonStateTIMonadPlus : ∀ (S : I → Set f) {M} →RawMonadPlus M → RawIMonadPlus (IStateT S M)StateTIMonadPlus S Mon = record{ monad = StateTIMonad S rawMonad; alternative = StateTIAlternative S Mon} where open RawMonadPlus Mon-------------------------------------------------------------------------- State monad operationsrecord RawIMonadState {I : Set i} (S : I → Set f)(M : IFun I f) : Set (i ⊔ suc f) wherefieldmonad : RawIMonad Mget : ∀ {i} → M i i (S i)put : ∀ {i j} → S j → M i j ⊤open RawIMonad monad publicmodify : ∀ {i j} → (S i → S j) → M i j ⊤modify f = get >>= put ∘ fStateTIMonadState : ∀ {i f} {I : Set i} (S : I → Set f) {M} →RawMonad M → RawIMonadState S (IStateT S M)StateTIMonadState S Mon = record{ monad = StateTIMonad S Mon; get = λ s → pure (s , s); put = λ s _ → pure (_ , s)}where open RawMonad Mon
-------------------------------------------------------------------------- The Agda standard library---- The reader monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Reader whereopen import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; module Join)open import Effect.Monad.Identity as Id using (Identity; runIdentity)open import Level using (Level)import Effect.Monad.Reader.Transformer as Transprivatevariabler : LevelR A : Set r-------------------------------------------------------------------------- Re-export the monad reader operationsopen Trans publicusing (RawMonadReader)-------------------------------------------------------------------------- Reader monadReader : (R A : Set r) → Set rReader R = Trans.ReaderT R IdentityrunReader : Reader R A → R → ArunReader mr r = runIdentity (Trans.runReaderT mr r)-------------------------------------------------------------------------- Structurefunctor : RawFunctor (Reader R)functor = Trans.functor Id.functorapplicative : RawApplicative (Reader R)applicative = Trans.applicative Id.applicativemonad : RawMonad (Reader R)monad = Trans.monad Id.monadjoin : Reader R (Reader R A) → Reader R Ajoin = Join.join monad-------------------------------------------------------------------------- Reader monad specificsmonadReader : RawMonadReader R (Reader R)monadReader = Trans.monadReader Id.monad
-------------------------------------------------------------------------- The Agda standard library---- The reader monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Reader.Transformer whereopen import Algebra using (RawMonoid)open import Effect.Choice using (RawChoice)open import Effect.Empty using (RawEmpty)open import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative; RawApplicativeZero; RawAlternative)open import Effect.Monad using (RawMonad; RawMonadZero; RawMonadPlus; RawMonadT)open import Function.Base using (_∘′_; const; _$_)open import Level using (Level; _⊔_)privatevariabler g g₁ g₂ : LevelR R₁ R₂ : Set rA B : Set rM : Set r → Set g-------------------------------------------------------------------------- Re-export the basic type definitionsopen import Effect.Monad.Reader.Transformer.Base publicusing ( RawMonadReader; ReaderT; mkReaderT; runReaderT)-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor (ReaderT R M)functor M = record{ _<$>_ = λ f ma → mkReaderT (λ r → f <$> ReaderT.runReaderT ma r)} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative (ReaderT R M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkReaderT ∘′ const ∘′ pure; _<*>_ = λ mf mx → mkReaderT (λ r → ReaderT.runReaderT mf r <*> ReaderT.runReaderT mx r)} where open RawApplicative Mempty : RawEmpty M → RawEmpty (ReaderT R M)empty M = record{ empty = mkReaderT (const (RawEmpty.empty M))}choice : RawChoice M → RawChoice (ReaderT R M)choice M = record{ _<|>_ = λ ma₁ ma₂ → mkReaderT $ λ r →ReaderT.runReaderT ma₁ r<|> ReaderT.runReaderT ma₂ r} where open RawChoice MapplicativeZero : RawApplicativeZero M → RawApplicativeZero (ReaderT R M)applicativeZero M = record{ rawApplicative = applicative rawApplicative; rawEmpty = empty rawEmpty} where open RawApplicativeZero M using (rawApplicative; rawEmpty)alternative : RawAlternative M → RawAlternative (ReaderT R M)alternative M = record{ rawApplicativeZero = applicativeZero rawApplicativeZero; rawChoice = choice rawChoice} where open RawAlternative Mmonad : RawMonad M → RawMonad (ReaderT R M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma f → mkReaderT $ λ r →do a ← ReaderT.runReaderT ma rReaderT.runReaderT (f a) r} where open RawMonad MmonadZero : RawMonadZero M → RawMonadZero (ReaderT R M)monadZero M = record{ rawMonad = monad (RawMonadZero.rawMonad M); rawEmpty = empty (RawMonadZero.rawEmpty M)}monadPlus : RawMonadPlus M → RawMonadPlus (ReaderT R M)monadPlus M = record{ rawMonadZero = monadZero rawMonadZero; rawChoice = choice rawChoice} where open RawMonadPlus M-------------------------------------------------------------------------- Monad reader transformer specificsmonadT : RawMonadT {g₁ = g₁} {g₂ = r ⊔ g₁} (ReaderT {r} R)monadT M = record{ lift = mkReaderT ∘′ const; rawMonad = monad M}monadReader : RawMonad M → RawMonadReader R (ReaderT R M)monadReader M = record{ reader = λ f → mkReaderT (pure ∘′ f); local = λ f ma → mkReaderT (ReaderT.runReaderT ma ∘′ f)} where open RawMonad MliftReaderT : RawMonadReader R₁ M →RawMonadReader R₁ (ReaderT R₂ M)liftReaderT MRead = record{ reader = λ k → mkReaderT (const (reader k)); local = λ f mx → mkReaderT (λ r₂ → local f (runReaderT mx r₂))} where open RawMonadReader MReadopen import Data.Product.Base using (_×_; _,_)open import Effect.Monad.Writer.Transformer.BaseliftWriterT : (MR : RawMonoid r g) →RawFunctor M →RawMonadReader R M →RawMonadReader R (WriterT MR M)liftWriterT MR M MRead = record{ reader = λ k → mkWriterT λ w → ((w ,_) <$> reader k); local = λ f mx → mkWriterT λ w → (local f (runWriterT mx w))} where open RawMonadReader MReadopen RawFunctor Mopen import Effect.Monad.State.Transformer.BaseliftStateT : RawFunctor M →RawMonadReader R₁ M →RawMonadReader R₁ (StateT R₂ M)liftStateT M MRead = record{ reader = λ k → mkStateT (λ s → (s ,_) <$> reader k); local = λ f mx → mkStateT (λ s → local f (runStateT mx s))} where open RawMonadReader MReadopen RawFunctor M
-------------------------------------------------------------------------- The Agda standard library---- Basic type and definition of the reader monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Reader.Transformer.Base {r} (R : Set r) whereopen import Level using (Level; suc; _⊔_)open import Function.Base using (id)privatevariableg : LevelA : Set r-------------------------------------------------------------------------- Reader monad operationsrecord RawMonadReader(M : Set r → Set g): Set (suc r ⊔ g) wherefieldreader : (R → A) → M Alocal : (R → R) → M A → M Aask : M Rask = reader id-------------------------------------------------------------------------- Reader monad transformerrecord ReaderT(M : Set r → Set g)(A : Set r): Set (r ⊔ g) whereconstructor mkReaderTfield runReaderT : R → M Aopen ReaderT public
-------------------------------------------------------------------------- The Agda standard library---- Instances for the reader monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Reader.Instances whereopen import Effect.Monad.Reader.TransformerinstancereaderTFunctor = λ {s} {S} {f} {M} {{fun}} → functor {s} {S} {f} {M} funreaderTApplicative = λ {s} {S} {f} {M} {{mon}} → applicative {s} {S} {f} {M} monreaderTEmpty = λ {s} {S} {f} {M} {{e}} → empty {s} {S} {f} {M} ereaderTChoice = λ {s} {S} {f} {M} {{ch}} → choice {s} {S} {f} {M} chreaderTApplicativeZero = λ {s} {S} {f} {M} {{mon}} → applicativeZero {s} {S} {f} {M} monreaderTAlternative = λ {s} {S} {f} {M} {{mpl}} → alternative {s} {S} {f} {M} mplreaderTMonad = λ {s} {S} {f} {M} {{mon}} → monad {s} {S} {f} {M} monreaderTMonadZero = λ {s} {S} {f} {M} {{mz}} → monadZero {s} {S} {f} {M} mzreaderTMonadPlus = λ {s} {S} {f} {M} {{mpl}} → monadPlus {s} {S} {f} {M} mplreaderTMonadT = λ {s} {S} {f} {M} {{mon}} → monadT {s} {S} {f} {M} monreaderTMonadReader = λ {s} {S} {f} {M} {{mon}} → monadReader {s} {S} {f} {M} monreaderTLiftWriterT = λ {s} {S₁} {S₂} {f} {M} {{mo}} {{fun}} {{mr}} → liftWriterT {s} {S₁} {S₂} {f} {M} mo fun mrreaderTLiftStateT = λ {s} {S₁} {S₂} {f} {M} {{fun}} {{mr}} → liftStateT {s} {S₁} {S₂} {f} {M} fun mr-- the following instance conflicts with readerTMonadReader so we don't include it-- readerTLiftReaderT = λ {R} {s} {S} {f} {M} {{ms}} → liftReaderT {R} {s} {S} {f} {M} ms
-------------------------------------------------------------------------- The Agda standard library---- The indexed reader monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_; suc; Lift; lift)module Effect.Monad.Reader.Indexed {r} (R : Set r) (a : Level) whereopen import Function.Base using (const; flip; _∘_)open import Function.Identity.Effectful as Id using (Identity)open import Effect.Applicative.Indexedusing (IFun; RawIApplicative; RawIApplicativeZero; RawIAlternative)open import Effect.Monad.Indexed using (RawIMonad; RawIMonadZero;RawIMonadPlus)privatevariableℓ : LevelA B I : Set ℓ-------------------------------------------------------------------------- Indexed readerIReaderT : IFun I (r ⊔ a) → IFun I (r ⊔ a)IReaderT M i j A = R → M i j Amodule _ {M : IFun I (r ⊔ a)} where------------------------------------------------------------------------ Indexed reader applicativeReaderTIApplicative : RawIApplicative M → RawIApplicative (IReaderT M)ReaderTIApplicative App = record{ pure = λ x r → pure x; _⊛_ = λ m n r → m r ⊛ n r} where open RawIApplicative AppReaderTIApplicativeZero : RawIApplicativeZero M →RawIApplicativeZero (IReaderT M)ReaderTIApplicativeZero App = record{ applicative = ReaderTIApplicative applicative; ∅ = const ∅} where open RawIApplicativeZero AppReaderTIAlternative : RawIAlternative M → RawIAlternative (IReaderT M)ReaderTIAlternative Alt = record{ applicativeZero = ReaderTIApplicativeZero applicativeZero; _∣_ = λ m n r → m r ∣ n r} where open RawIAlternative Alt------------------------------------------------------------------------ Indexed reader monadReaderTIMonad : RawIMonad M → RawIMonad (IReaderT M)ReaderTIMonad Mon = record{ return = λ x r → return x; _>>=_ = λ m f r → m r >>= flip f r} where open RawIMonad MonReaderTIMonadZero : RawIMonadZero M → RawIMonadZero (IReaderT M)ReaderTIMonadZero Mon = record{ monad = ReaderTIMonad monad; applicativeZero = ReaderTIApplicativeZero applicativeZero} where open RawIMonadZero MonReaderTIMonadPlus : RawIMonadPlus M → RawIMonadPlus (IReaderT M)ReaderTIMonadPlus Mon = record{ monad = ReaderTIMonad monad; alternative = ReaderTIAlternative alternative} where open RawIMonadPlus Mon-------------------------------------------------------------------------- Reader monad operationsrecord RawIMonadReader {I : Set ℓ} (M : IFun I (r ⊔ a)): Set (ℓ ⊔ suc (r ⊔ a)) wherefieldmonad : RawIMonad Mreader : ∀ {i} → (R → A) → M i i Alocal : ∀ {i j} → (R → R) → M i j A → M i j Aopen RawIMonad monad publicask : ∀ {i} → M i i (Lift (r ⊔ a) R)ask = reader liftasks : ∀ {i} → (R → A) → M i i Aasks = readerReaderTIMonadReader : {I : Set ℓ} {M : IFun I (r ⊔ a)} →RawIMonad M → RawIMonadReader (IReaderT M)ReaderTIMonadReader Mon = record{ monad = ReaderTIMonad Mon; reader = λ f r → return (f r); local = λ f m → m ∘ f} where open RawIMonad Mon
-------------------------------------------------------------------------- The Agda standard library---- Monads on indexed sets (predicates)-------------------------------------------------------------------------- Note that currently the monad laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Predicate whereopen import Data.Product.Base using (_,_)open import Effect.Monad.Indexed using (RawIMonad)open import Function.Base using (const; id; _∘_)open import Level using (Level; _⊔_; suc)open import Relation.Binary.PropositionalEquality.Core using (refl)open import Relation.Unary using (_⊆_; _⇒_; _∈_; _∩_; {_})open import Relation.Unary.PredicateTransformer using (Pt)privatevariablei ℓ : Level------------------------------------------------------------------------record RawPMonad {I : Set i} (M : Pt I (i ⊔ ℓ)) : Set (suc (i ⊔ ℓ)) whereinfixl 1 _?>=_ _?>_ _>?>_ _?>=′_infixr 1 _=<?_ _<?<_-- ``Demonic'' operations (the opponent chooses the state).fieldreturn? : ∀ {P} → P ⊆ M P_=<?_ : ∀ {P Q} → P ⊆ M Q → M P ⊆ M Q_?>=_ : ∀ {P Q} → M P ⊆ const (P ⊆ M Q) ⇒ M Qm ?>= f = f =<? m_?>=′_ : ∀ {P Q} → M P ⊆ const (∀ j → {_ : P j} → j ∈ M Q) ⇒ M Qm ?>=′ f = m ?>= λ {j} p → f j {p}_?>_ : ∀ {P Q} → M P ⊆ const (∀ {j} → j ∈ M Q) ⇒ M Qm₁ ?> m₂ = m₁ ?>= λ _ → m₂join? : ∀ {P} → M (M P) ⊆ M Pjoin? m = m ?>= id_>?>_ : {P Q R : _} → P ⊆ M Q → Q ⊆ M R → P ⊆ M Rf >?> g = _=<?_ g ∘ f_<?<_ : ∀ {P Q R} → Q ⊆ M R → P ⊆ M Q → P ⊆ M Rg <?< f = f >?> g-- ``Angelic'' operations (the player knows the state).rawIMonad : RawIMonad (λ i j A → i ∈ M (const A ∩ { j }))rawIMonad = record{ return = λ x → return? (x , refl); _>>=_ = λ m k → m ?>= λ { {._} (x , refl) → k x }}open RawIMonad rawIMonad public
-------------------------------------------------------------------------- The Agda standard library---- The partiality monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Effect.Monad.Partiality whereopen import Codata.Musical.Notation using (∞; ♯_; ♭)open import Data.Bool.Base using (Bool; false; true)open import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Product as Prod using (∃; ∄; -,_; ∃₂; _,_; _×_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; module Join)open import Function.Base using (_∘′_; flip; id; _∘_; _$_; _⟨_⟩_)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (Level; _⊔_)open import Relation.Binary.Core as B hiding (Rel; _⇔_)open import Relation.Binary.Definitionsusing (DecidableEquality; Reflexive; Symmetric; Transitive)open import Relation.Binary.Structuresusing (IsPreorder; IsEquivalence)open import Relation.Binary.Bundlesusing (Preorder; Setoid; Poset)import Relation.Binary.Properties.Setoid as SetoidPropertiesopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Nullary.Decidable using (yes; no; False; Dec; ¬¬-excluded-middle)open import Relation.Nullary.Negation using (¬_; ¬¬-Monad)privatevariablea b c f s ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- The partiality monaddata _⊥ (A : Set a) : Set a wherenow : (x : A) → A ⊥later : (x : ∞ (A ⊥)) → A ⊥bind : A ⊥ → (A → B ⊥) → B ⊥bind (now x) f = f xbind (later x) f = later (♯ (bind (♭ x) f))functor : RawFunctor {ℓ} _⊥functor = record { _<$>_ = map } wheremap : (A → B) → A ⊥ → B ⊥map f (now a) = now (f a)map f (later d) = later (♯ map f (♭ d))applicative : RawApplicative {f = f} _⊥applicative = record{ rawFunctor = functor; pure = now; _<*>_ = λ mf mx → bind mf (λ f → bind mx (now ∘′ f))}monad : RawMonad {f = f} _⊥monad = record{ rawApplicative = applicative; _>>=_ = bind}join : (A ⊥) ⊥ → A ⊥join = Join.join monadprivate module M {f} = RawMonad (monad {f})-- Non-termination.never : A ⊥never = later (♯ never)-- run x for n steps peels off at most n "later" constructors from x.run_for_steps : A ⊥ → ℕ → A ⊥run now x for n steps = now xrun later x for zero steps = later xrun later x for suc n steps = run ♭ x for n steps-- Is the computation done?isNow : A ⊥ → BoolisNow (now x) = trueisNow (later x) = false-------------------------------------------------------------------------- Kinds-- The partiality monad comes with two forms of equality (weak and-- strong) and one ordering. Strong equality is stronger than the-- ordering, which is stronger than weak equality.-- The three relations are defined using a single data type, indexed-- by a "kind".data OtherKind : Set wheregeq weak : OtherKinddata Kind : Set wherestrong : Kindother : (k : OtherKind) → Kind-- Kind equality is decidable.infix 4 _≟-Kind__≟-Kind_ : DecidableEquality Kind_≟-Kind_ strong strong = yes ≡.refl_≟-Kind_ strong (other k) = no λ()_≟-Kind_ (other k) strong = no λ()_≟-Kind_ (other geq) (other geq) = yes ≡.refl_≟-Kind_ (other geq) (other weak) = no λ()_≟-Kind_ (other weak) (other geq) = no λ()_≟-Kind_ (other weak) (other weak) = yes ≡.refl-- A predicate which is satisfied only for equalities. Note that, for-- concrete inputs, this predicate evaluates to ⊤ or ⊥.Equality : Kind → SetEquality k = False (k ≟-Kind other geq)-------------------------------------------------------------------------- Equality/orderingmodule Equality {A : Set a} -- The "return type".(_∼_ : A → A → Set ℓ) where-- The three relations.data Rel : Kind → A ⊥ → A ⊥ → Set (a ⊔ ℓ) wherenow : ∀ {k x y} (x∼y : x ∼ y) → Rel k (now x) (now y)later : ∀ {k x y} (x∼y : ∞ (Rel k (♭ x) (♭ y))) → Rel k (later x) (later y)laterʳ : ∀ {x y} (x≈y : Rel (other weak) x (♭ y) ) → Rel (other weak) x (later y)laterˡ : ∀ {k x y} (x∼y : Rel (other k) (♭ x) y ) → Rel (other k) (later x) yinfix 4 _≅_ _≳_ _≲_ _≈__≅_ : A ⊥ → A ⊥ → Set __≅_ = Rel strong_≳_ : A ⊥ → A ⊥ → Set __≳_ = Rel (other geq)_≲_ : A ⊥ → A ⊥ → Set __≲_ = flip _≳__≈_ : A ⊥ → A ⊥ → Set __≈_ = Rel (other weak)-- x ⇓ y means that x terminates with y.infix 4 _⇓[_]_ _⇓__⇓[_]_ : A ⊥ → Kind → A → Set _x ⇓[ k ] y = Rel k x (now y)_⇓_ : A ⊥ → A → Set _x ⇓ y = x ⇓[ other weak ] y-- x ⇓ means that x terminates.infix 4 _⇓_⇓ : A ⊥ → Set _x ⇓ = ∃ λ v → x ⇓ v-- x ⇑ means that x does not terminate.infix 4 _⇑[_] _⇑_⇑[_] : A ⊥ → Kind → Set _x ⇑[ k ] = Rel k x never_⇑ : A ⊥ → Set _x ⇑ = x ⇑[ other weak ]-------------------------------------------------------------------------- Lemmas relating the three relationsmodule _ {A : Set a} {_∼_ : A → A → Set ℓ} whereopen Equality _∼_ using (Rel; _≅_; _≳_; _≲_; _≈_; _⇓[_]_; _⇑[_])open Equality.Rel-- All relations include strong equality.≅⇒ : ∀ {k} {x y : A ⊥} → x ≅ y → Rel k x y≅⇒ (now x∼y) = now x∼y≅⇒ (later x≅y) = later (♯ ≅⇒ (♭ x≅y))-- The weak equality includes the ordering.≳⇒ : ∀ {k} {x y : A ⊥} → x ≳ y → Rel (other k) x y≳⇒ (now x∼y) = now x∼y≳⇒ (later x≳y) = later (♯ ≳⇒ (♭ x≳y))≳⇒ (laterˡ x≳y) = laterˡ (≳⇒ x≳y )-- Weak equality includes the other relations.⇒≈ : ∀ {k} {x y : A ⊥} → Rel k x y → x ≈ y⇒≈ {strong} = ≅⇒⇒≈ {other geq} = ≳⇒⇒≈ {other weak} = id-- The relations agree for non-terminating computations.never⇒never : ∀ {k₁ k₂} {x : A ⊥} →Rel k₁ x never → Rel k₂ x nevernever⇒never (later x∼never) = later (♯ never⇒never (♭ x∼never))never⇒never (laterʳ x≈never) = never⇒never x≈nevernever⇒never (laterˡ x∼never) = later (♯ never⇒never x∼never)-- The "other" relations agree when the right-hand side is a value.now⇒now : ∀ {k₁ k₂} {x} {y : A} →Rel (other k₁) x (now y) → Rel (other k₂) x (now y)now⇒now (now x∼y) = now x∼ynow⇒now (laterˡ x∼now) = laterˡ (now⇒now x∼now)-------------------------------------------------------------------------- Later can be droppedlaterʳ⁻¹ : ∀ {k} {x : A ⊥} {y} →Rel (other k) x (later y) → Rel (other k) x (♭ y)laterʳ⁻¹ (later x∼y) = laterˡ (♭ x∼y)laterʳ⁻¹ (laterʳ x≈y) = x≈ylaterʳ⁻¹ (laterˡ x∼ly) = laterˡ (laterʳ⁻¹ x∼ly)laterˡ⁻¹ : ∀ {x} {y : A ⊥} → later x ≈ y → ♭ x ≈ ylaterˡ⁻¹ (later x≈y) = laterʳ (♭ x≈y)laterˡ⁻¹ (laterʳ lx≈y) = laterʳ (laterˡ⁻¹ lx≈y)laterˡ⁻¹ (laterˡ x≈y) = x≈ylater⁻¹ : ∀ {k} {x y : ∞ (A ⊥)} →Rel k (later x) (later y) → Rel k (♭ x) (♭ y)later⁻¹ (later x∼y) = ♭ x∼ylater⁻¹ (laterʳ lx≈y) = laterˡ⁻¹ lx≈ylater⁻¹ (laterˡ x∼ly) = laterʳ⁻¹ x∼ly-------------------------------------------------------------------------- The relations are equivalences or partial orders, given suitable-- assumptions about the underlying relationmodule Equivalence where-- Reflexivity.refl : Reflexive _∼_ → ∀ {k} → Reflexive (Rel k)refl refl-∼ {x = now v} = now refl-∼refl refl-∼ {x = later x} = later (♯ refl refl-∼)-- Symmetry.sym : Symmetric _∼_ → ∀ {k} → Equality k → Symmetric (Rel k)sym sym-∼ eq (now x∼y) = now (sym-∼ x∼y)sym sym-∼ eq (later x∼y) = later (♯ sym sym-∼ eq (♭ x∼y))sym sym-∼ eq (laterʳ x≈y) = laterˡ (sym sym-∼ eq x≈y )sym sym-∼ eq (laterˡ {weak} x≈y) = laterʳ (sym sym-∼ eq x≈y )-- Transitivity.privatemodule Trans (trans-∼ : Transitive _∼_) wherenow-trans : ∀ {k x y} {v : A} →Rel k x y → Rel k y (now v) → Rel k x (now v)now-trans (now x∼y) (now y∼z) = now (trans-∼ x∼y y∼z)now-trans (laterˡ x∼y) y∼z = laterˡ (now-trans x∼y y∼z)now-trans x∼ly (laterˡ y∼z) = now-trans (laterʳ⁻¹ x∼ly) y∼zmutuallater-trans : ∀ {k} {x y : A ⊥} {z} →Rel k x y → Rel k y (later z) → Rel k x (later z)later-trans (later x∼y) ly∼lz = later (♯ trans (♭ x∼y) (later⁻¹ ly∼lz))later-trans (laterˡ x∼y) y∼lz = later (♯ trans x∼y (laterʳ⁻¹ y∼lz))later-trans (laterʳ x≈y) ly≈lz = later-trans x≈y (laterˡ⁻¹ ly≈lz)later-trans x≈y (laterʳ y≈z) = laterʳ ( trans x≈y y≈z )trans : ∀ {k} {x y z : A ⊥} → Rel k x y → Rel k y z → Rel k x ztrans {z = now v} x∼y y∼v = now-trans x∼y y∼vtrans {z = later z} x∼y y∼lz = later-trans x∼y y∼lzopen Trans public using (trans)-- All the relations are preorders.preorder : IsPreorder _≡_ _∼_ → Kind → Preorder _ _ _preorder pre k = record{ Carrier = A ⊥; _≈_ = _≡_; _≲_ = Rel k; isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = refl′; trans = Equivalence.trans (IsPreorder.trans pre)}}whererefl′ : ∀ {k} {x y : A ⊥} → x ≡ y → Rel k x yrefl′ ≡.refl = Equivalence.refl (IsPreorder.refl pre)privatepreorder′ : IsEquivalence _∼_ → Kind → Preorder _ _ _preorder′ equiv =preorder (SetoidProperties.isPreorder (record { isEquivalence = equiv }))-- The two equalities are equivalence relations.setoid : IsEquivalence _∼_ →(k : Kind) {eq : Equality k} → Setoid _ _setoid equiv k {eq} = record{ Carrier = A ⊥; _≈_ = Rel k; isEquivalence = record{ refl = Pre.refl; sym = Equivalence.sym (IsEquivalence.sym equiv) eq; trans = Pre.trans}} where module Pre = Preorder (preorder′ equiv k)-- The order is a partial order, with strong equality as the-- underlying equality.≳-poset : IsEquivalence _∼_ → Poset _ _ _≳-poset equiv = record{ Carrier = A ⊥; _≈_ = _≅_; _≤_ = _≳_; isPartialOrder = record{ antisym = antisym; isPreorder = record{ isEquivalence = S.isEquivalence; reflexive = ≅⇒; trans = Pre.trans}}}wheremodule S = Setoid (setoid equiv strong)module Pre = Preorder (preorder′ equiv (other geq))antisym : {x y : A ⊥} → x ≳ y → x ≲ y → x ≅ yantisym (now x∼y) (now _) = now x∼yantisym (later x≳y) (later x≲y) = later (♯ antisym (♭ x≳y) (♭ x≲y))antisym (later x≳y) (laterˡ x≲ly) = later (♯ antisym (♭ x≳y) (laterʳ⁻¹ x≲ly))antisym (laterˡ x≳ly) (later x≲y) = later (♯ antisym (laterʳ⁻¹ x≳ly) (♭ x≲y))antisym (laterˡ x≳ly) (laterˡ x≲ly) = later (♯ antisym (laterʳ⁻¹ x≳ly) (laterʳ⁻¹ x≲ly))-- Equational reasoning.module Reasoning (isEquivalence : IsEquivalence _∼_) whereprivatemodule Pre {k} = Preorder (preorder′ isEquivalence k)module S {k eq} = Setoid (setoid isEquivalence k {eq})infix 3 _∎infixr 2 _≡⟨_⟩_ _≅⟨_⟩_ _≳⟨_⟩_ _≈⟨_⟩__≡⟨_⟩_ : ∀ {k} x {y z : A ⊥} → x ≡ y → Rel k y z → Rel k x z_ ≡⟨ ≡.refl ⟩ y∼z = y∼z_≅⟨_⟩_ : ∀ {k} x {y z : A ⊥} → x ≅ y → Rel k y z → Rel k x z_ ≅⟨ x≅y ⟩ y∼z = Pre.trans (≅⇒ x≅y) y∼z_≳⟨_⟩_ : ∀ {k} x {y z : A ⊥} →x ≳ y → Rel (other k) y z → Rel (other k) x z_ ≳⟨ x≳y ⟩ y∼z = Pre.trans (≳⇒ x≳y) y∼z_≈⟨_⟩_ : ∀ x {y z : A ⊥} → x ≈ y → y ≈ z → x ≈ z_ ≈⟨ x≈y ⟩ y≈z = Pre.trans x≈y y≈zsym : ∀ {k} {eq : Equality k} {x y : A ⊥} →Rel k x y → Rel k y xsym {eq = eq} = S.sym {eq = eq}_∎ : ∀ {k} (x : A ⊥) → Rel k x xx ∎ = Pre.refl-------------------------------------------------------------------------- Lemmas related to now and never-- Now is not never.now≉never : ∀ {k} {x : A} → ¬ Rel k (now x) nevernow≉never (laterʳ hyp) = now≉never hyp-- A partial value is either now or never (classically, when the-- underlying relation is reflexive).now-or-never : Reflexive _∼_ →∀ {k} (x : A ⊥) →¬ ¬ ((∃ λ y → x ⇓[ other k ] y) ⊎ x ⇑[ other k ])now-or-never refl x = helper <$> ¬¬-excluded-middlewhereopen RawMonad ¬¬-Monadnot-now-is-never : (x : A ⊥) → (∄ λ y → x ≳ now y) → x ≳ nevernot-now-is-never (now x) hyp with hyp (-, now refl)... | ()not-now-is-never (later x) hyp =later (♯ not-now-is-never (♭ x) (hyp ∘ Prod.map id laterˡ))helper : Dec (∃ λ y → x ≳ now y) → _helper (yes ≳now) = inj₁ $ Prod.map id ≳⇒ ≳nowhelper (no ≵now) = inj₂ $ ≳⇒ $ not-now-is-never x ≵now-------------------------------------------------------------------------- Map-like results-- Map.map : ∀ {_∼′_ : A → A → Set a} {k} →_∼′_ ⇒ _∼_ → Equality.Rel _∼′_ k ⇒ Equality.Rel _∼_ kmap ∼′⇒∼ (now x∼y) = now (∼′⇒∼ x∼y)map ∼′⇒∼ (later x∼y) = later (♯ map ∼′⇒∼ (♭ x∼y))map ∼′⇒∼ (laterʳ x≈y) = laterʳ (map ∼′⇒∼ x≈y)map ∼′⇒∼ (laterˡ x∼y) = laterˡ (map ∼′⇒∼ x∼y)-- If a statement can be proved using propositional equality as the-- underlying relation, then it can also be proved for any other-- reflexive underlying relation.≡⇒ : Reflexive _∼_ →∀ {k x y} → Equality.Rel _≡_ k x y → Rel k x y≡⇒ refl-∼ = map (flip (≡.subst (_∼_ _)) refl-∼)-------------------------------------------------------------------------- Steps-- The number of later constructors (steps) in the terminating-- computation x.steps : ∀ {k} {x : A ⊥} {y} → x ⇓[ k ] y → ℕsteps (now _) = zerosteps .{x = later x} (laterˡ {x = x} x⇓) = suc (steps {x = ♭ x} x⇓)module Steps {trans-∼ : Transitive _∼_} whereleft-identity :∀ {k x y} {z : A}(x≅y : x ≅ y) (y⇓z : y ⇓[ k ] z) →steps (Equivalence.trans trans-∼ (≅⇒ x≅y) y⇓z) ≡ steps y⇓zleft-identity (now _) (now _) = ≡.reflleft-identity (later x≅y) (laterˡ y⇓z) =≡.cong suc $ left-identity (♭ x≅y) y⇓zright-identity :∀ {k x} {y z : A}(x⇓y : x ⇓[ k ] y) (y≈z : now y ⇓[ k ] z) →steps (Equivalence.trans trans-∼ x⇓y y≈z) ≡ steps x⇓yright-identity (now x∼y) (now y∼z) = ≡.reflright-identity (laterˡ x∼y) (now y∼z) =≡.cong suc $ right-identity x∼y (now y∼z)-------------------------------------------------------------------------- Laws related to bind-- Never is a left and right "zero" of bind.left-zero : (f : B → A ⊥) → let open M in(never >>= f) ≅ neverleft-zero f = later (♯ left-zero f)right-zero : (x : B ⊥) → let open M in(x >>= λ _ → never) ≅ neverright-zero (later x) = later (♯ right-zero (♭ x))right-zero (now x) = never≅neverwhere never≅never : never ≅ nevernever≅never = later (♯ never≅never)-- Now is a left and right identity of bind (for a reflexive-- underlying relation).left-identity : Reflexive _∼_ →(x : B) (f : B → A ⊥) → let open M in(now x >>= f) ≅ f xleft-identity refl-∼ x f = Equivalence.refl refl-∼right-identity : Reflexive _∼_ →(x : A ⊥) → let open M in(x >>= now) ≅ xright-identity refl (now x) = now reflright-identity refl (later x) = later (♯ right-identity refl (♭ x))-- Bind is associative (for a reflexive underlying relation).associative : Reflexive _∼_ →(x : C ⊥) (f : C → B ⊥) (g : B → A ⊥) →let open M in(x >>= f >>= g) ≅ (x >>= λ y → f y >>= g)associative refl-∼ (now x) f g = Equivalence.refl refl-∼associative refl-∼ (later x) f g =later (♯ associative refl-∼ (♭ x) f g)module _ {A B : Set s}{_∼A_ : A → A → Set ℓ}{_∼B_ : B → B → Set ℓ} whereopen Equalityprivateopen module EqA = Equality _∼A_ using () renaming (_⇓[_]_ to _⇓[_]A_; _⇑[_] to _⇑[_]A)open module EqB = Equality _∼B_ using () renaming (_⇓[_]_ to _⇓[_]B_; _⇑[_] to _⇑[_]B)-- Bind preserves all the relations.infixl 1 _>>=-cong__>>=-cong_ :∀ {k} {x₁ x₂ : A ⊥} {f₁ f₂ : A → B ⊥} → let open M inRel _∼A_ k x₁ x₂ →(∀ {x₁ x₂} → x₁ ∼A x₂ → Rel _∼B_ k (f₁ x₁) (f₂ x₂)) →Rel _∼B_ k (x₁ >>= f₁) (x₂ >>= f₂)now x₁∼x₂ >>=-cong f₁∼f₂ = f₁∼f₂ x₁∼x₂later x₁∼x₂ >>=-cong f₁∼f₂ = later (♯ (♭ x₁∼x₂ >>=-cong f₁∼f₂))laterʳ x₁≈x₂ >>=-cong f₁≈f₂ = laterʳ (x₁≈x₂ >>=-cong f₁≈f₂)laterˡ x₁∼x₂ >>=-cong f₁∼f₂ = laterˡ (x₁∼x₂ >>=-cong f₁∼f₂)-- Inversion lemmas for bind.>>=-inversion-⇓ :Reflexive _∼A_ →∀ {k} x {f : A → B ⊥} {y} → let open M in(x>>=f⇓ : (x >>= f) ⇓[ k ]B y) →∃ λ z → ∃₂ λ (x⇓ : x ⇓[ k ]A z) (fz⇓ : f z ⇓[ k ]B y) →steps x⇓ + steps fz⇓ ≡ steps x>>=f⇓>>=-inversion-⇓ refl (now x) fx⇓ =(x , now refl , fx⇓ , ≡.refl)>>=-inversion-⇓ refl (later x) (laterˡ x>>=f⇓) =Prod.map id (Prod.map laterˡ (Prod.map id (≡.cong suc))) $>>=-inversion-⇓ refl (♭ x) x>>=f⇓>>=-inversion-⇑ : IsEquivalence _∼A_ →∀ {k} x {f : A → B ⊥} → let open M inRel _∼B_ (other k) (x >>= f) never →¬ ¬ (x ⇑[ other k ]A ⊎∃ λ y → x ⇓[ other k ]A y × f y ⇑[ other k ]B)>>=-inversion-⇑ eqA {k} x {f} ∼never =helper <$> now-or-never IsEqA.refl xwhereopen RawMonad ¬¬-Monad using (_<$>_)open M using (_>>=_)open Reasoning eqAmodule IsEqA = IsEquivalence eqAk≳ = other geqis-never : ∀ {x y} →x ⇓[ k≳ ]A y → (x >>= f) ⇑[ k≳ ]B →∃ λ z → (y ∼A z) × f z ⇑[ k≳ ]Bis-never (now x∼y) = λ fx⇑ → (_ , IsEqA.sym x∼y , fx⇑)is-never (laterˡ ≳now) = is-never ≳now ∘ later⁻¹helper : (∃ λ y → x ⇓[ k≳ ]A y) ⊎ x ⇑[ k≳ ]A →x ⇑[ other k ]A ⊎∃ λ y → x ⇓[ other k ]A y × f y ⇑[ other k ]Bhelper (inj₂ ≳never) = inj₁ (≳⇒ ≳never)helper (inj₁ (y , ≳now)) with is-never ≳now (never⇒never ∼never)... | (z , y∼z , fz⇑) = inj₂ (z , ≳⇒ (x ≳⟨ ≳now ⟩now y ≅⟨ now y∼z ⟩now z ∎), ≳⇒ fz⇑)module _ {A B : Set ℓ} {_∼_ : B → B → Set ℓ} whereopen Equality-- A variant of _>>=-cong_.infixl 1 _≡->>=-cong__≡->>=-cong_ :∀ {k} {x₁ x₂ : A ⊥} {f₁ f₂ : A → B ⊥} → let open M inRel _≡_ k x₁ x₂ →(∀ x → Rel _∼_ k (f₁ x) (f₂ x)) →Rel _∼_ k (x₁ >>= f₁) (x₂ >>= f₂)_≡->>=-cong_ {k} {f₁ = f₁} {f₂} x₁≈x₂ f₁≈f₂ =x₁≈x₂ >>=-cong λ {x} x≡x′ →≡.subst (λ y → Rel _∼_ k (f₁ x) (f₂ y)) x≡x′ (f₁≈f₂ x)-------------------------------------------------------------------------- Productivity checker workaround-- The monad can be awkward to use, due to the limitations of guarded-- coinduction. The following code provides a (limited) workaround.module Workaround {a} whereinfixl 1 _>>=_data _⊥P : Set a → Set (Level.suc a) wherenow : (x : A) → A ⊥Plater : (x : ∞ (A ⊥P)) → A ⊥P_>>=_ : (x : A ⊥P) (f : A → B ⊥P) → B ⊥Pprivatedata _⊥W : Set a → Set (Level.suc a) wherenow : (x : A) → A ⊥Wlater : (x : A ⊥P) → A ⊥Wmutual_>>=W_ : A ⊥W → (A → B ⊥P) → B ⊥Wnow x >>=W f = whnf (f x)later x >>=W f = later (x >>= f)whnf : A ⊥P → A ⊥Wwhnf (now x) = now xwhnf (later x) = later (♭ x)whnf (x >>= f) = whnf x >>=W fmutualprivate⟦_⟧W : A ⊥W → A ⊥⟦ now x ⟧W = now x⟦ later x ⟧W = later (♯ ⟦ x ⟧P)⟦_⟧P : A ⊥P → A ⊥⟦ x ⟧P = ⟦ whnf x ⟧W-- The definitions above make sense. ⟦_⟧P is homomorphic with-- respect to now, later and _>>=_.module Correct whereprivateopen module Eq {A : Set a} = Equality {A = A} _≡_open module R {A : Set a} = Reasoning (≡.isEquivalence {A = A})now-hom : (x : A) → ⟦ now x ⟧P ≅ now xnow-hom x = now x ∎later-hom : (x : ∞ (A ⊥P)) → ⟦ later x ⟧P ≅ later (♯ ⟦ ♭ x ⟧P)later-hom x = later (♯ (⟦ ♭ x ⟧P ∎))mutualprivate>>=-homW : (x : B ⊥W) (f : B → A ⊥P) →⟦ x >>=W f ⟧W ≅ M._>>=_ ⟦ x ⟧W (λ y → ⟦ f y ⟧P)>>=-homW (now x) f = ⟦ f x ⟧P ∎>>=-homW (later x) f = later (♯ >>=-hom x f)>>=-hom : (x : B ⊥P) (f : B → A ⊥P) →⟦ x >>= f ⟧P ≅ M._>>=_ ⟦ x ⟧P (λ y → ⟦ f y ⟧P)>>=-hom x f = >>=-homW (whnf x) f-------------------------------------------------------------------------- An alternative, but equivalent, formulation of equality/orderingmodule AlternativeEquality {a ℓ} whereprivateEl : Setoid a ℓ → Set _El = Setoid.CarrierEq : ∀ S → B.Rel (El S) _Eq = Setoid._≈_open Equality using (Rel)open Equality.Relinfix 4 _∣_≅P_ _∣_≳P_ _∣_≈P_infix 3 _∎infixr 2 _≡⟨_⟩_ _≅⟨_⟩_ _≳⟨_⟩_ _≳⟨_⟩≅_ _≳⟨_⟩≈_ _≈⟨_⟩≅_ _≈⟨_⟩≲_infixl 1 _>>=_mutual-- Proof "programs"._∣_≅P_ : ∀ S → B.Rel (El S ⊥) __∣_≅P_ = flip RelP strong_∣_≳P_ : ∀ S → B.Rel (El S ⊥) __∣_≳P_ = flip RelP (other geq)_∣_≈P_ : ∀ S → B.Rel (El S ⊥) __∣_≈P_ = flip RelP (other weak)data RelP S : Kind → B.Rel (El S ⊥) (Level.suc (a ⊔ ℓ)) where-- Congruences.now : ∀ {k x y} (xRy : x ⟨ Eq S ⟩ y) → RelP S k (now x) (now y)later : ∀ {k x y} (x∼y : ∞ (RelP S k (♭ x) (♭ y))) →RelP S k (later x) (later y)_>>=_ : ∀ {S′ : Setoid a ℓ} {k} {x₁ x₂}{f₁ f₂ : El S′ → El S ⊥} →let open M in(x₁∼x₂ : RelP S′ k x₁ x₂)(f₁∼f₂ : ∀ {x y} → x ⟨ Eq S′ ⟩ y →RelP S k (f₁ x) (f₂ y)) →RelP S k (x₁ >>= f₁) (x₂ >>= f₂)-- Ordering/weak equality.laterʳ : ∀ {x y} (x≈y : RelP S (other weak) x (♭ y)) → RelP S (other weak) x (later y)laterˡ : ∀ {k x y} (x∼y : RelP S (other k) (♭ x) y) → RelP S (other k) (later x) y-- Equational reasoning. Note that including full transitivity-- for weak equality would make _∣_≈P_ trivial; a similar-- problem applies to _∣_≳P_ (A ∣ never ≳P now x would be-- provable). Instead the definition of RelP includes limited-- notions of transitivity, similar to weak bisimulation up-to-- various things._∎ : ∀ {k} x → RelP S k x xsym : ∀ {k x y} {eq : Equality k} (x∼y : RelP S k x y) → RelP S k y x_≡⟨_⟩_ : ∀ {k} x {y z} (x≡y : x ≡ y) (y∼z : RelP S k y z) → RelP S k x z_≅⟨_⟩_ : ∀ {k} x {y z} (x≅y : S ∣ x ≅P y) (y∼z : RelP S k y z) → RelP S k x z_≳⟨_⟩_ : let open Equality (Eq S) in∀ x {y z} (x≳y : x ≳ y) (y≳z : S ∣ y ≳P z) → S ∣ x ≳P z_≳⟨_⟩≅_ : ∀ x {y z} (x≳y : S ∣ x ≳P y) (y≅z : S ∣ y ≅P z) → S ∣ x ≳P z_≳⟨_⟩≈_ : ∀ x {y z} (x≳y : S ∣ x ≳P y) (y≈z : S ∣ y ≈P z) → S ∣ x ≈P z_≈⟨_⟩≅_ : ∀ x {y z} (x≈y : S ∣ x ≈P y) (y≅z : S ∣ y ≅P z) → S ∣ x ≈P z_≈⟨_⟩≲_ : ∀ x {y z} (x≈y : S ∣ x ≈P y) (y≲z : S ∣ z ≳P y) → S ∣ x ≈P z-- If any of the following transitivity-like rules were added to-- RelP, then RelP and Rel would no longer be equivalent:---- x ≳P y → y ≳P z → x ≳P z-- x ≳P y → y ≳ z → x ≳P z-- x ≲P y → y ≈P z → x ≈P z-- x ≈P y → y ≳P z → x ≈P z-- x ≲ y → y ≈P z → x ≈P z-- x ≈P y → y ≳ z → x ≈P z-- x ≈P y → y ≈P z → x ≈P z-- x ≈P y → y ≈ z → x ≈P z-- x ≈ y → y ≈P z → x ≈P z---- The reason is that any of these rules would make it possible-- to derive that never and now x are related.-- RelP is complete with respect to Rel.complete : ∀ {S k} {x y : El S ⊥} →Equality.Rel (Eq S) k x y → RelP S k x ycomplete (now xRy) = now xRycomplete (later x∼y) = later (♯ complete (♭ x∼y))complete (laterʳ x≈y) = laterʳ (complete x≈y)complete (laterˡ x∼y) = laterˡ (complete x∼y)-- RelP is sound with respect to Rel.private-- Proof WHNFs.data RelW S : Kind → B.Rel (El S ⊥) (Level.suc (a ⊔ ℓ)) wherenow : ∀ {k x y} (xRy : x ⟨ Eq S ⟩ y) → RelW S k (now x) (now y)later : ∀ {k x y} (x∼y : RelP S k (♭ x) (♭ y)) → RelW S k (later x) (later y)laterʳ : ∀ {x y} (x≈y : RelW S (other weak) x (♭ y)) → RelW S (other weak) x (later y)laterˡ : ∀ {k x y} (x∼y : RelW S (other k) (♭ x) y) → RelW S (other k) (later x) y-- WHNFs can be turned into programs.program : ∀ {S k x y} → RelW S k x y → RelP S k x yprogram (now xRy) = now xRyprogram (later x∼y) = later (♯ x∼y)program (laterˡ x∼y) = laterˡ (program x∼y)program (laterʳ x≈y) = laterʳ (program x≈y)-- Lemmas for WHNFs._>>=W_ : ∀ {A B k x₁ x₂} {f₁ f₂ : El A → El B ⊥} →RelW A k x₁ x₂ →(∀ {x y} → x ⟨ Eq A ⟩ y → RelW B k (f₁ x) (f₂ y)) →RelW B k (M._>>=_ x₁ f₁) (M._>>=_ x₂ f₂)now xRy >>=W f₁∼f₂ = f₁∼f₂ xRylater x∼y >>=W f₁∼f₂ = later (x∼y >>= program ∘ f₁∼f₂)laterʳ x≈y >>=W f₁≈f₂ = laterʳ (x≈y >>=W f₁≈f₂)laterˡ x∼y >>=W f₁∼f₂ = laterˡ (x∼y >>=W f₁∼f₂)reflW : ∀ {S k} x → RelW S k x xreflW {S} (now x) = now (Setoid.refl S)reflW (later x) = later (♭ x ∎)symW : ∀ {S k x y} → Equality k → RelW S k x y → RelW S k y xsymW {S} eq (now xRy) = now (Setoid.sym S xRy)symW eq (later x≈y) = later (sym {eq = eq} x≈y)symW eq (laterʳ x≈y) = laterˡ (symW eq x≈y)symW eq (laterˡ {weak} x≈y) = laterʳ (symW eq x≈y)trans≅W : ∀ {S x y z} →RelW S strong x y → RelW S strong y z → RelW S strong x ztrans≅W {S} (now xRy) (now yRz) = now (Setoid.trans S xRy yRz)trans≅W (later x≅y) (later y≅z) = later (_ ≅⟨ x≅y ⟩ y≅z)trans≳-W : ∀ {S x y z} → let open Equality (Eq S) inx ≳ y → RelW S (other geq) y z → RelW S (other geq) x ztrans≳-W {S} (now xRy) (now yRz) = now (Setoid.trans S xRy yRz)trans≳-W (later x≳y) (later y≳z) = later (_ ≳⟨ ♭ x≳y ⟩ y≳z)trans≳-W (later x≳y) (laterˡ y≳z) = laterˡ (trans≳-W (♭ x≳y) y≳z)trans≳-W (laterˡ x≳y) y≳z = laterˡ (trans≳-W x≳y y≳z)-- Strong equality programs can be turned into WHNFs.whnf≅ : ∀ {S x y} → S ∣ x ≅P y → RelW S strong x ywhnf≅ (now xRy) = now xRywhnf≅ (later x≅y) = later (♭ x≅y)whnf≅ (x₁≅x₂ >>= f₁≅f₂) = whnf≅ x₁≅x₂ >>=W λ xRy → whnf≅ (f₁≅f₂ xRy)whnf≅ (x ∎) = reflW xwhnf≅ (sym x≅y) = symW _ (whnf≅ x≅y)whnf≅ (x ≡⟨ ≡.refl ⟩ y≅z) = whnf≅ y≅zwhnf≅ (x ≅⟨ x≅y ⟩ y≅z) = trans≅W (whnf≅ x≅y) (whnf≅ y≅z)-- More transitivity lemmas._⟨_⟩≅_ : ∀ {S k} x {y z} →RelP S k x y → S ∣ y ≅P z → RelP S k x z_⟨_⟩≅_ {k = strong} x x≅y y≅z = x ≅⟨ x≅y ⟩ y≅z_⟨_⟩≅_ {k = other geq} x x≳y y≅z = x ≳⟨ x≳y ⟩≅ y≅z_⟨_⟩≅_ {k = other weak} x x≈y y≅z = x ≈⟨ x≈y ⟩≅ y≅ztrans∼≅W : ∀ {S k x y z} →RelW S k x y → RelW S strong y z → RelW S k x ztrans∼≅W {S} (now xRy) (now yRz) = now (Setoid.trans S xRy yRz)trans∼≅W (later x∼y) (later y≅z) = later (_ ⟨ x∼y ⟩≅ y≅z)trans∼≅W (laterʳ x≈y) (later y≅z) = laterʳ (trans∼≅W x≈y (whnf≅ y≅z))trans∼≅W (laterˡ x∼y) y≅z = laterˡ (trans∼≅W x∼y y≅z)trans≅∼W : ∀ {S k x y z} →RelW S strong x y → RelW S k y z → RelW S k x ztrans≅∼W {S} (now xRy) (now yRz) = now (Setoid.trans S xRy yRz)trans≅∼W (later x≅y) (later y∼z) = later (_ ≅⟨ x≅y ⟩ y∼z)trans≅∼W (later x≅y) (laterˡ y∼z) = laterˡ (trans≅∼W (whnf≅ x≅y) y∼z)trans≅∼W x≅y (laterʳ ly≈z) = laterʳ (trans≅∼W x≅y ly≈z)-- Order programs can be turned into WHNFs.whnf≳ : ∀ {S x y} → S ∣ x ≳P y → RelW S (other geq) x ywhnf≳ (now xRy) = now xRywhnf≳ (later x∼y) = later (♭ x∼y)whnf≳ (laterˡ x≲y) = laterˡ (whnf≳ x≲y)whnf≳ (x₁∼x₂ >>= f₁∼f₂) = whnf≳ x₁∼x₂ >>=W λ xRy → whnf≳ (f₁∼f₂ xRy)whnf≳ (x ∎) = reflW xwhnf≳ (x ≡⟨ ≡.refl ⟩ y≳z) = whnf≳ y≳zwhnf≳ (x ≅⟨ x≅y ⟩ y≳z) = trans≅∼W (whnf≅ x≅y) (whnf≳ y≳z)whnf≳ (x ≳⟨ x≳y ⟩ y≳z) = trans≳-W x≳y (whnf≳ y≳z)whnf≳ (x ≳⟨ x≳y ⟩≅ y≅z) = trans∼≅W (whnf≳ x≳y) (whnf≅ y≅z)-- Another transitivity lemma.trans≳≈W : ∀ {S x y z} →RelW S (other geq) x y → RelW S (other weak) y z →RelW S (other weak) x ztrans≳≈W {S} (now xRy) (now yRz) = now (Setoid.trans S xRy yRz)trans≳≈W (later x≳y) (later y≈z) = later (_ ≳⟨ x≳y ⟩≈ y≈z)trans≳≈W (laterˡ x≳y) y≈z = laterˡ (trans≳≈W x≳y y≈z)trans≳≈W x≳y (laterʳ y≈z) = laterʳ (trans≳≈W x≳y y≈z)trans≳≈W (later x≳y) (laterˡ y≈z) = laterˡ (trans≳≈W (whnf≳ x≳y) y≈z)-- All programs can be turned into WHNFs.whnf : ∀ {S k x y} → RelP S k x y → RelW S k x ywhnf (now xRy) = now xRywhnf (later x∼y) = later (♭ x∼y)whnf (laterʳ x≈y) = laterʳ (whnf x≈y)whnf (laterˡ x∼y) = laterˡ (whnf x∼y)whnf (x₁∼x₂ >>= f₁∼f₂) = whnf x₁∼x₂ >>=W λ xRy → whnf (f₁∼f₂ xRy)whnf (x ∎) = reflW xwhnf (sym {eq = eq} x≈y) = symW eq (whnf x≈y)whnf (x ≡⟨ ≡.refl ⟩ y∼z) = whnf y∼zwhnf (x ≅⟨ x≅y ⟩ y∼z) = trans≅∼W (whnf x≅y) (whnf y∼z)whnf (x ≳⟨ x≳y ⟩ y≳z) = trans≳-W x≳y (whnf y≳z)whnf (x ≳⟨ x≳y ⟩≅ y≅z) = trans∼≅W (whnf x≳y) (whnf y≅z)whnf (x ≳⟨ x≳y ⟩≈ y≈z) = trans≳≈W (whnf x≳y) (whnf y≈z)whnf (x ≈⟨ x≈y ⟩≅ y≅z) = trans∼≅W (whnf x≈y) (whnf y≅z)whnf (x ≈⟨ x≈y ⟩≲ y≲z) = symW _ (trans≳≈W (whnf y≲z) (symW _ (whnf x≈y)))mutual-- Soundness.privatesoundW : ∀ {S k x y} → RelW S k x y → Rel (Eq S) k x ysoundW (now xRy) = now xRysoundW (later x∼y) = later (♯ sound x∼y)soundW (laterʳ x≈y) = laterʳ (soundW x≈y)soundW (laterˡ x∼y) = laterˡ (soundW x∼y)sound : ∀ {S k x y} → RelP S k x y → Rel (Eq S) k x ysound x∼y = soundW (whnf x∼y)-- RelP and Rel are equivalent (when the underlying relation is an-- equivalence).correct : ∀ {S k x y} → RelP S k x y ⇔ Rel (Eq S) k x ycorrect = mk⇔ sound complete-------------------------------------------------------------------------- Another lemma-- Bind is "idempotent".idempotent :(B : Setoid ℓ ℓ) →let open M; open Setoid B using (_≈_; Carrier); open Equality _≈_ in(x : A ⊥) (f : A → A → Carrier ⊥) →(x >>= λ y′ → x >>= λ y″ → f y′ y″) ≳ (x >>= λ y′ → f y′ y′)idempotent {A = A} B x f = sound (idem x)whereopen AlternativeEquality hiding (_>>=_)open Mopen Equality.Rel using (laterˡ)open Equivalence using (refl)idem : (x : A ⊥) →B ∣ (x >>= λ y′ → x >>= λ y″ → f y′ y″) ≳P(x >>= λ y′ → f y′ y′)idem (now x) = f x x ∎idem (later x) = later (♯ ((♭ x >>= λ y′ → later x >>= λ y″ → f y′ y″) ≳⟨ (refl ≡.refl {x = ♭ x} ≡->>=-cong λ _ →laterˡ (refl (Setoid.refl B))) ⟩(♭ x >>= λ y′ → ♭ x >>= λ y″ → f y′ y″) ≳⟨ idem (♭ x) ⟩≅(♭ x >>= λ y′ → f y′ y′) ∎))
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for _⊥------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Effect.Monad.Partiality.Instances whereopen import Effect.Monad.PartialityinstancepartialityMonad = monad
-------------------------------------------------------------------------- The Agda standard library---- An All predicate for the partiality monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Effect.Monad.Partiality.All whereopen import Effect.Monadopen import Effect.Monad.Partiality as Partiality using (_⊥; ⇒≈)open import Codata.Musical.Notationopen import Function.Base using (flip; _∘_)open import Levelopen import Relation.Binary.Definitions using (_Respects_)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open Partiality._⊥open Partiality.Equality using (Rel)open Partiality.Equality.Relprivateopen module E {a} {A : Set a} = Partiality.Equality (_≡_ {A = A})using (_≅_; _≳_)open module M {f} = RawMonad (Partiality.monad {f = f})using (_>>=_)privatevariablea b p ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- All, along with some lemmas-- All P x means that if x terminates with the value v, then P v-- holds.data All {A : Set a} (P : A → Set p) : A ⊥ → Set (a ⊔ p) wherenow : ∀ {v} (p : P v) → All P (now v)later : ∀ {x} (p : ∞ (All P (♭ x))) → All P (later x)-- Bind preserves All in the following way:infixl 1 _>>=-cong__>>=-cong_ : ∀ {p q} {P : A → Set p} {Q : B → Set q}{x : A ⊥} {f : A → B ⊥} →All P x → (∀ {x} → P x → All Q (f x)) →All Q (x >>= f)now p >>=-cong f = f plater p >>=-cong f = later (♯ (♭ p >>=-cong f))-- All respects all the relations, given that the predicate respects-- the underlying relation.respects :∀ {k} {P : A → Set p} {_∼_ : A → A → Set ℓ} →P Respects _∼_ → All P Respects Rel _∼_ krespects resp (now x∼y) (now p) = now (resp x∼y p)respects resp (later x∼y) (later p) = later (♯ respects resp (♭ x∼y) (♭ p))respects resp (laterˡ x∼y) (later p) = respects resp x∼y (♭ p)respects resp (laterʳ x≈y) p = later (♯ respects resp x≈y p)respects-flip :∀ {k} {P : A → Set p} {_∼_ : A → A → Set ℓ} →P Respects flip _∼_ → All P Respects flip (Rel _∼_ k)respects-flip resp (now x∼y) (now p) = now (resp x∼y p)respects-flip resp (later x∼y) (later p) = later (♯ respects-flip resp (♭ x∼y) (♭ p))respects-flip resp (laterˡ x∼y) p = later (♯ respects-flip resp x∼y p)respects-flip resp (laterʳ x≈y) (later p) = respects-flip resp x≈y (♭ p)-- "Equational" reasoning.module Reasoning {P : A → Set p}{_∼_ : A → A → Set ℓ}(resp : P Respects flip _∼_) whereinfix 3 finallyinfixr 2 _≡⟨_⟩_ _∼⟨_⟩__≡⟨_⟩_ : ∀ x {y} → x ≡ y → All P y → All P x_ ≡⟨ ≡.refl ⟩ p = p_∼⟨_⟩_ : ∀ {k} x {y} → Rel _∼_ k x y → All P y → All P x_ ∼⟨ x∼y ⟩ p = respects-flip resp (⇒≈ x∼y) p-- A cosmetic combinator.finally : (x : A ⊥) → All P x → All P xfinally _ p = psyntax finally x p = x ⟨ p ⟩-- "Equational" reasoning with _∼_ instantiated to propositional-- equality.module Reasoning-≡ {a p} {A : Set a} {P : A → Set p}= Reasoning {P = P} {_∼_ = _≡_} (≡.subst P ∘ ≡.sym)-------------------------------------------------------------------------- An alternative, but equivalent, formulation of Allmodule Alternative {a p : Level} whereinfix 3 _⟨_⟩Pinfixr 2 _≅⟨_⟩P_ _≳⟨_⟩P_-- All "programs".data AllP {A : Set a} (P : A → Set p) : A ⊥ → Set (suc (a ⊔ p)) wherenow : ∀ {x} (p : P x) → AllP P (now x)later : ∀ {x} (p : ∞ (AllP P (♭ x))) → AllP P (later x)_>>=-congP_ : ∀ {B : Set a} {Q : B → Set p} {x f}(p-x : AllP Q x) (p-f : ∀ {v} → Q v → AllP P (f v)) →AllP P (x >>= f)_≅⟨_⟩P_ : ∀ x {y} (x≅y : x ≅ y) (p : AllP P y) → AllP P x_≳⟨_⟩P_ : ∀ x {y} (x≳y : x ≳ y) (p : AllP P y) → AllP P x_⟨_⟩P : ∀ x (p : AllP P x) → AllP P xinfixl 1 _>>=-congP_private-- WHNFs.data AllW {A} (P : A → Set p) : A ⊥ → Set (suc (a ⊔ p)) wherenow : ∀ {x} (p : P x) → AllW P (now x)later : ∀ {x} (p : AllP P (♭ x)) → AllW P (later x)-- A function which turns WHNFs into programs.program : ∀ {P : A → Set p} {x} → AllW P x → AllP P xprogram (now p) = now pprogram (later p) = later (♯ p)-- Functions which turn programs into WHNFs.trans-≅ : {P : A → Set p} {x y : A ⊥} →x ≅ y → AllW P y → AllW P xtrans-≅ (now ≡.refl) (now p) = now ptrans-≅ (later x≅y) (later p) = later (_ ≅⟨ ♭ x≅y ⟩P p)trans-≳ : {P : A → Set p} {x y : A ⊥} →x ≳ y → AllW P y → AllW P xtrans-≳ (now ≡.refl) (now p) = now ptrans-≳ (later x≳y) (later p) = later (_ ≳⟨ ♭ x≳y ⟩P p)trans-≳ (laterˡ x≳y) p = later (_ ≳⟨ x≳y ⟩P program p)mutual_>>=-congW_ : ∀ {P : A → Set p} {Q : B → Set p} {x f} →AllW P x → (∀ {v} → P v → AllP Q (f v)) →AllW Q (x >>= f)now p >>=-congW p-f = whnf (p-f p)later p >>=-congW p-f = later (p >>=-congP p-f)whnf : ∀ {P : A → Set p} {x} → AllP P x → AllW P xwhnf (now p) = now pwhnf (later p) = later (♭ p)whnf (p-x >>=-congP p-f) = whnf p-x >>=-congW p-fwhnf (_ ≅⟨ x≅y ⟩P p) = trans-≅ x≅y (whnf p)whnf (_ ≳⟨ x≳y ⟩P p) = trans-≳ x≳y (whnf p)whnf (_ ⟨ p ⟩P) = whnf p-- AllP P is sound and complete with respect to All P.sound : ∀ {P : A → Set p} {x} → AllP P x → All P xsound = λ p → soundW (whnf p)wheresoundW : ∀ {A} {P : A → Set p} {x} → AllW P x → All P xsoundW (now p) = now psoundW (later p) = later (♯ sound p)complete : ∀ {P : A → Set p} {x} → All P x → AllP P xcomplete (now p) = now pcomplete (later p) = later (♯ complete (♭ p))
-------------------------------------------------------------------------- The Agda standard library---- Indexed monads-------------------------------------------------------------------------- Note that currently the monad laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Indexed whereopen import Effect.Applicative.Indexedopen import Function.Baseopen import Levelprivatevariablea b c i f : LevelA : Set aB : Set bC : Set cI : Set irecord RawIMonad {I : Set i} (M : IFun I f) : Set (i ⊔ suc f) whereinfixl 1 _>>=_ _>>_ _>=>_infixr 1 _=<<_ _<=<_fieldreturn : ∀ {i} → A → M i i A_>>=_ : ∀ {i j k} → M i j A → (A → M j k B) → M i k B_>>_ : ∀ {i j k} → M i j A → M j k B → M i k Bm₁ >> m₂ = m₁ >>= λ _ → m₂_=<<_ : ∀ {i j k} → (A → M j k B) → M i j A → M i k Bf =<< c = c >>= f_>=>_ : ∀ {i j k} → (A → M i j B) → (B → M j k C) → (A → M i k C)f >=> g = _=<<_ g ∘ f_<=<_ : ∀ {i j k} → (B → M j k C) → (A → M i j B) → (A → M i k C)g <=< f = f >=> gjoin : ∀ {i j k} → M i j (M j k A) → M i k Ajoin m = m >>= idrawIApplicative : RawIApplicative MrawIApplicative = record{ pure = return; _⊛_ = λ f x → f >>= λ f′ → x >>= λ x′ → return (f′ x′)}open RawIApplicative rawIApplicative publicRawIMonadT : {I : Set i} (T : IFun I f → IFun I f) → Set (i ⊔ suc f)RawIMonadT T = ∀ {M} → RawIMonad M → RawIMonad (T M)record RawIMonadZero {I : Set i} (M : IFun I f) : Set (i ⊔ suc f) wherefieldmonad : RawIMonad MapplicativeZero : RawIApplicativeZero Mopen RawIMonad monad publicopen RawIApplicativeZero applicativeZero using (∅) publicrecord RawIMonadPlus {I : Set i} (M : IFun I f) : Set (i ⊔ suc f) wherefieldmonad : RawIMonad Malternative : RawIAlternative Mopen RawIMonad monad publicopen RawIAlternative alternative using (∅; _∣_) publicmonadZero : RawIMonadZero MmonadZero = record{ monad = monad; applicativeZero = RawIAlternative.applicativeZero alternative}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the identity function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Identity whereopen import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; module Join)open import Effect.Comonad using (RawComonad)open import Function.Base using (id; _∘′_; _|>′_; _$′_; flip)open import Level using (Level)privatevariablea : LevelA : Set arecord Identity (A : Set a) : Set a whereconstructor mkIdentityfield runIdentity : Aopen Identity publicfunctor : RawFunctor {a} Identityfunctor = record{ _<$>_ = λ f a → mkIdentity (f (runIdentity a))}applicative : RawApplicative {a} Identityapplicative = record{ rawFunctor = functor; pure = mkIdentity; _<*>_ = λ f a → mkIdentity (runIdentity f $′ runIdentity a)}monad : RawMonad {a} Identitymonad = record{ rawApplicative = applicative; _>>=_ = _|>′_ ∘′ runIdentity}comonad : RawComonad {a} Identitycomonad = record{ extract = runIdentity; extend = λ f a → mkIdentity (f a)}join : Identity (Identity A) → Identity Ajoin = Join.join monad
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for Identity------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Identity.Instances whereopen import Effect.Monad.IdentityinstanceidentityFunctor = functoridentityApplicative = applicativeidentityMonad = monadidentityComonad = comonad
-------------------------------------------------------------------------- The Agda standard library---- The IO monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Effect.Monad.IO whereopen import Data.Product.Base using (_,_)open import Effect.Functor using (RawFunctor)open import Function.Base using (id)open import IO.Base using (IO)open import Level using (Level; suc)privatevariablef g : LevelA : Set fM : Set f → Set g-------------------------------------------------------------------------- IO monad operationsrecord RawMonadIO(M : Set f → Set (suc f)): Set (suc f) wherefieldliftIO : IO A → M A-------------------------------------------------------------------------- IO monad specificsmonadIO : RawMonadIO {f} IOmonadIO = record { liftIO = id }open import Effect.Monad.State.Transformer.Base using (StateT; mkStateT)liftStateT : ∀ {S} → RawFunctor M → RawMonadIO M → RawMonadIO (StateT S M)liftStateT M MIO = record{ liftIO = λ io → mkStateT (λ s → (s ,_) <$> liftIO io)} where open RawFunctor M; open RawMonadIO MIOopen import Effect.Monad.Reader.Transformer.Base using (ReaderT; mkReaderT)liftReaderT : ∀ {R} → RawMonadIO M → RawMonadIO (ReaderT R M)liftReaderT MIO = record{ liftIO = λ io → mkReaderT (λ r → liftIO io)} where open RawMonadIO MIOopen import Effect.Monad.Writer.Transformer.Base using (WriterT; mkWriterT)liftWriterT : ∀ {f 𝕎} → RawFunctor M → RawMonadIO M → RawMonadIO (WriterT {f = f} 𝕎 M)liftWriterT M MIO = record{ liftIO = λ io → mkWriterT (λ w → (w ,_) <$> liftIO io)} where open RawFunctor M; open RawMonadIO MIO
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for the IO monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Effect.Monad.IO.Instances whereopen import Effect.Monad.IOinstanceioMonadIO = monadIOstateTMonadIO = λ {s} {S} {M} {{m}} {{mio}} → liftStateT {s} {S} {M} m mioreaderTMonadIO = λ {r} {R} {M} {{mio}} → liftReaderT {r} {R} {M} miowriterTMonadIO = λ {f} {w} {W} {M} {{m}} {{mio}} → liftWriterT {f} {w} {W} {M} m mio
-------------------------------------------------------------------------- The Agda standard library---- The error monad transformer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_; suc)module Effect.Monad.Error.Transformer {e} (E : Set e) (a : Level) whereopen import Effect.Monad using (RawMonad)open import Function.Base using (_∘′_; _$_)privatevariablef ℓ : LevelA B : Set ℓM : Set f → Set ℓ-------------------------------------------------------------------------- Error monad operationsrecord RawMonadError(M : Set (e ⊔ a) → Set ℓ): Set (suc (e ⊔ a) ⊔ ℓ) wherefieldthrow : E → M Acatch : M A → (E → M A) → M Aduring : (E → E) → M A → M Aduring f ma = catch ma (throw ∘′ f)-------------------------------------------------------------------------- Monad error transformer specificsmodule Sumₗ whereopen import Data.Sum.Base using (inj₁; inj₂; [_,_]′)open import Data.Sum.Effectful.Left.Transformer E amonadError : RawMonad M → RawMonadError (SumₗT M)monadError M = record{ throw = mkSumₗT ∘′ pure ∘′ inj₁; catch = λ ma k → mkSumₗT $ doa ← runSumₗT ma[ runSumₗT ∘′ k , pure ∘′ inj₂ ]′ a} where open RawMonad Mmodule Sumᵣ whereopen import Data.Sum.Base using (inj₁; inj₂; [_,_]′)open import Data.Sum.Effectful.Right.Transformer a EmonadError : RawMonad M → RawMonadError (SumᵣT M)monadError M = record{ throw = mkSumᵣT ∘′ pure ∘′ inj₂; catch = λ ma k → mkSumᵣT $ doa ← runSumᵣT ma[ pure ∘′ inj₁ , runSumᵣT ∘′ k ]′ a} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- A delimited continuation monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Monad.Continuation whereopen import Effect.Applicative.Indexed using (IFun)open import Effect.Monad using (RawMonad)open import Function.Identity.Effectful as Id using (Identity)open import Effect.Monad.Indexed using (RawIMonad)open import Function.Base using (flip)open import Level using (Level; _⊔_; suc)privatevariablei f : LevelI : Set i-------------------------------------------------------------------------- Delimited continuation monadsDContT : (I → Set f) → (Set f → Set f) → IFun I fDContT K M r₂ r₁ a = (a → M (K r₁)) → M (K r₂)DCont : (I → Set f) → IFun I fDCont K = DContT K IdentityDContTIMonad : ∀ (K : I → Set f) {M} → RawMonad M → RawIMonad (DContT K M)DContTIMonad K Mon = record{ return = λ a k → k a; _>>=_ = λ c f k → c (flip f k)}where open RawMonad MonDContIMonad : (K : I → Set f) → RawIMonad (DCont K)DContIMonad K = DContTIMonad K Id.monad-------------------------------------------------------------------------- Delimited continuation operationsrecord RawIMonadDCont {I : Set i} (K : I → Set f)(M : IFun I f) : Set (i ⊔ suc f) wherefieldmonad : RawIMonad Mreset : ∀ {r₁ r₂ r₃} → M r₁ r₂ (K r₂) → M r₃ r₃ (K r₁)shift : ∀ {a r₁ r₂ r₃ r₄} →((a → M r₁ r₁ (K r₂)) → M r₃ r₄ (K r₄)) → M r₃ r₂ aopen RawIMonad monad publicDContTIMonadDCont : ∀ (K : I → Set f) {M} →RawMonad M → RawIMonadDCont K (DContT K M)DContTIMonadDCont K Mon = record{ monad = DContTIMonad K Mon; reset = λ e k → e pure >>= k; shift = λ e k → e (λ a k′ → (k a) >>= k′) pure}whereopen RawMonad MonDContIMonadDCont : (K : I → Set f) → RawIMonadDCont K (DCont K)DContIMonadDCont K = DContTIMonadDCont K Id.monad
-------------------------------------------------------------------------- The Agda standard library---- Functors-------------------------------------------------------------------------- Note that currently the functor laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Functor whereopen import Data.Unit.Polymorphic.Base using (⊤)open import Function.Base using (const; flip)open import Levelopen import Relation.Binary.PropositionalEquality.Core using (_≡_)privatevariableℓ ℓ′ ℓ″ : LevelA B X Y : Set ℓrecord RawFunctor (F : Set ℓ → Set ℓ′) : Set (suc ℓ ⊔ ℓ′) whereinfixl 4 _<$>_ _<$_infixl 1 _<&>_field_<$>_ : (A → B) → F A → F B_<$_ : A → F B → F Ax <$ y = const x <$> y_<&>_ : F A → (A → B) → F B_<&>_ = flip _<$>_ignore : F A → F ⊤ignore = _ <$_-- A functor morphism from F₁ to F₂ is an operation op such that-- op (F₁ f x) ≡ F₂ f (op x)record Morphism {F₁ : Set ℓ → Set ℓ′} {F₂ : Set ℓ → Set ℓ″}(fun₁ : RawFunctor F₁)(fun₂ : RawFunctor F₂) : Set (suc ℓ ⊔ ℓ′ ⊔ ℓ″) whereopen RawFunctorfieldop : F₁ X → F₂ Xop-<$> : (f : X → Y) (x : F₁ X) →op (fun₁ ._<$>_ f x) ≡ fun₂ ._<$>_ f (op x)
-------------------------------------------------------------------------- The Agda standard library---- Functors on indexed sets (predicates)-------------------------------------------------------------------------- Note that currently the functor laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Functor.Predicate whereopen import Function.Base using (const)open import Levelopen import Relation.Unaryopen import Relation.Unary.PredicateTransformer using (PT)privatevariablei j ℓ₁ ℓ₂ : Levelrecord RawPFunctor {I : Set i} {J : Set j}(F : PT I J ℓ₁ ℓ₂) : Set (i ⊔ j ⊔ suc ℓ₁ ⊔ suc ℓ₂)whereinfixl 4 _<$>_ _<$_field_<$>_ : ∀ {P Q} → P ⊆ Q → F P ⊆ F Q_<$_ : ∀ {P Q} → (∀ {i} → P i) → F Q ⊆ F Px <$ y = const x <$> y
-------------------------------------------------------------------------- The Agda standard library---- Empty values (e.g. [] for List, nothing for Maybe)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Empty whereopen import Levelprivatevariableℓ ℓ′ : LevelA : Set ℓrecord RawEmpty (F : Set ℓ → Set ℓ′) : Set (suc ℓ ⊔ ℓ′) wherefieldempty : F A-- backwards compatibility: unicode variants∅ : F A∅ = empty
-------------------------------------------------------------------------- The Agda standard library---- Comonads-------------------------------------------------------------------------- Note that currently the monad laws are not included here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Comonad whereopen import Levelopen import Function.Base using (id; _∘′_; flip)privatevariablea b c f : LevelA : Set aB : Set bC : Set crecord RawComonad (W : Set f → Set f) : Set (suc f) whereinfixl 1 _=>>_ _=>=_infixr 1 _<<=_ _=<=_fieldextract : W A → Aextend : (W A → B) → (W A → W B)duplicate : W A → W (W A)duplicate = extend idliftW : (A → B) → W A → W BliftW f = extend (f ∘′ extract)_=>>_ : W A → (W A → B) → W B_=>>_ = flip extend_=>=_ : (W A → B) → (W B → C) → W A → Cf =>= g = g ∘′ extend f_<<=_ : (W A → B) → W A → W B_<<=_ = extend_=<=_ : (W B → C) → (W A → B) → W A → C_=<=_ = flip _=>=_
-------------------------------------------------------------------------- The Agda standard library---- Type constructors giving rise to a semigroup at every type-- e.g. (List, _++_)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Effect.Choice whereopen import Levelprivatevariableℓ ℓ′ : LevelA : Set ℓrecord RawChoice (F : Set ℓ → Set ℓ′) : Set (suc ℓ ⊔ ℓ′) whereinfixr 3 _<|>_ _∣_field_<|>_ : F A → F A → F A-- backwards compatibility: unicode variants_∣_ : F A → F A → F A_∣_ = _<|>_
-------------------------------------------------------------------------- The Agda standard library---- Applicative functors-------------------------------------------------------------------------- Note that currently the applicative functor laws are not included-- here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Applicative whereopen import Data.Bool.Base using (Bool; true; false)open import Data.Product.Base using (_×_; _,_)open import Data.Unit.Polymorphic.Base using (⊤)open import Effect.Choice using (RawChoice)open import Effect.Empty using (RawEmpty)open import Effect.Functor as Fun using (RawFunctor)open import Function.Base using (const; flip; _∘′_)open import Level using (Level; suc; _⊔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_)privatevariablef g : LevelA B C : Set f-------------------------------------------------------------------------- The type of raw applicativesrecord RawApplicative (F : Set f → Set g) : Set (suc f ⊔ g) whereinfixl 4 _<*>_ _<*_ _*>_infixl 4 _⊛_ _<⊛_ _⊛>_infix 4 _⊗_fieldrawFunctor : RawFunctor Fpure : A → F A_<*>_ : F (A → B) → F A → F Bopen RawFunctor rawFunctor public_<*_ : F A → F B → F Aa <* b = const <$> a <*> b_*>_ : F A → F B → F Ba *> b = flip const <$> a <*> bzipWith : (A → B → C) → F A → F B → F CzipWith f x y = f <$> x <*> yzip : F A → F B → F (A × B)zip = zipWith _,_-- Haskell-style alternative name for purereturn : A → F Areturn = pure-- backwards compatibility: unicode variants_⊛_ : F (A → B) → F A → F B_⊛_ = _<*>__<⊛_ : F A → F B → F A_<⊛_ = _<*__⊛>_ : F A → F B → F B_⊛>_ = _*>__⊗_ : F A → F B → F (A × B)_⊗_ = zipmodule _ whereopen RawApplicativeopen RawFunctor-- Smart constructormkRawApplicative :(F : Set f → Set g) →(pure : ∀ {A} → A → F A) →(app : ∀ {A B} → F (A → B) → F A → F B) →RawApplicative FmkRawApplicative F pure app .rawFunctor ._<$>_ = app ∘′ puremkRawApplicative F pure app .pure = puremkRawApplicative F pure app ._<*>_ = app-------------------------------------------------------------------------- The type of raw applicatives with a zerorecord RawApplicativeZero (F : Set f → Set g) : Set (suc f ⊔ g) wherefieldrawApplicative : RawApplicative FrawEmpty : RawEmpty Fopen RawApplicative rawApplicative publicopen RawEmpty rawEmpty publicguard : Bool → F ⊤guard true = pure _guard false = empty-------------------------------------------------------------------------- The type of raw alternative applicativesrecord RawAlternative (F : Set f → Set g) : Set (suc f ⊔ g) wherefieldrawApplicativeZero : RawApplicativeZero FrawChoice : RawChoice Fopen RawApplicativeZero rawApplicativeZero publicopen RawChoice rawChoice public-------------------------------------------------------------------------- The type of applicative morphismsrecord Morphism {F₁ F₂ : Set f → Set g}(A₁ : RawApplicative F₁)(A₂ : RawApplicative F₂) : Set (suc f ⊔ g) wheremodule A₁ = RawApplicative A₁module A₂ = RawApplicative A₂fieldfunctorMorphism : Fun.Morphism A₁.rawFunctor A₂.rawFunctoropen Fun.Morphism functorMorphism publicfieldop-pure : (x : A) → op (A₁.pure x) ≡ A₂.pure xop-<*> : (f : F₁ (A → B)) (x : F₁ A) →op (f A₁.⊛ x) ≡ (op f A₂.⊛ op x)-- backwards compatibility: unicode variantsop-⊛ = op-<*>
-------------------------------------------------------------------------- The Agda standard library---- Applicative functors on indexed sets (predicates)-------------------------------------------------------------------------- Note that currently the applicative functor laws are not included-- here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Applicative.Predicate whereopen import Effect.Functor.Predicateopen import Data.Product.Base using (_,_)open import Function.Base using (const; constᵣ)open import Levelopen import Relation.Unaryopen import Relation.Unary.PredicateTransformer using (Pt)privatevariablei ℓ : Level------------------------------------------------------------------------record RawPApplicative {I : Set i} (F : Pt I ℓ) :Set (i ⊔ suc ℓ) whereinfixl 4 _⊛_ _<⊛_ _⊛>_infix 4 _⊗_fieldpure : ∀ {P} → P ⊆ F P_⊛_ : ∀ {P Q} → F (P ⇒ Q) ⊆ F P ⇒ F QrawPFunctor : RawPFunctor FrawPFunctor = record{ _<$>_ = λ g x → pure g ⊛ x}privateopen module RF = RawPFunctor rawPFunctor public_<⊛_ : ∀ {P Q} → F P ⊆ const (∀ {j} → F Q j) ⇒ F Px <⊛ y = const <$> x ⊛ y_⊛>_ : ∀ {P Q} → const (∀ {i} → F P i) ⊆ F Q ⇒ F Qx ⊛> y = constᵣ <$> x ⊛ y_⊗_ : ∀ {P Q} → F P ⊆ F Q ⇒ F (P ∩ Q)x ⊗ y = (_,_) <$> x ⊛ yzipWith : ∀ {P Q R} → (P ⊆ Q ⇒ R) → F P ⊆ F Q ⇒ F RzipWith f x y = f <$> x ⊛ y
-------------------------------------------------------------------------- The Agda standard library---- Indexed applicative functors-------------------------------------------------------------------------- Note that currently the applicative functor laws are not included-- here.{-# OPTIONS --cubical-compatible --safe #-}module Effect.Applicative.Indexed whereopen import Effect.Functor using (RawFunctor)open import Data.Product.Base using (_×_; _,_)open import Function.Baseopen import Levelopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablea b c i f : LevelA : Set aB : Set bC : Set cIFun : Set i → (ℓ : Level) → Set (i ⊔ suc ℓ)IFun I ℓ = I → I → Set ℓ → Set ℓ-------------------------------------------------------------------------- Type, and usual combinatorsrecord RawIApplicative {I : Set i} (F : IFun I f) :Set (i ⊔ suc f) whereinfixl 4 _⊛_ _<⊛_ _⊛>_infix 4 _⊗_fieldpure : ∀ {i} → A → F i i A_⊛_ : ∀ {i j k} → F i j (A → B) → F j k A → F i k BrawFunctor : ∀ {i j} → RawFunctor (F i j)rawFunctor = record{ _<$>_ = λ g x → pure g ⊛ x}privateopen module RF {i j : I} =RawFunctor (rawFunctor {i = i} {j = j})public_<⊛_ : ∀ {i j k} → F i j A → F j k B → F i k Ax <⊛ y = const <$> x ⊛ y_⊛>_ : ∀ {i j k} → F i j A → F j k B → F i k Bx ⊛> y = constᵣ <$> x ⊛ y_⊗_ : ∀ {i j k} → F i j A → F j k B → F i k (A × B)x ⊗ y = (_,_) <$> x ⊛ yzipWith : ∀ {i j k} → (A → B → C) → F i j A → F j k B → F i k CzipWith f x y = f <$> x ⊛ yzip : ∀ {i j k} → F i j A → F j k B → F i k (A × B)zip = zipWith _,_-------------------------------------------------------------------------- Applicative with a zerorecord RawIApplicativeZero{I : Set i} (F : IFun I f) :Set (i ⊔ suc f) wherefieldapplicative : RawIApplicative F∅ : ∀ {i j} → F i j Aopen RawIApplicative applicative public-------------------------------------------------------------------------- Alternative functors: `F i j A` is a monoidrecord RawIAlternative{I : Set i} (F : IFun I f) :Set (i ⊔ suc f) whereinfixr 3 _∣_fieldapplicativeZero : RawIApplicativeZero F_∣_ : ∀ {i j} → F i j A → F i j A → F i j Aopen RawIApplicativeZero applicativeZero public-------------------------------------------------------------------------- Applicative functor morphisms, specialised to propositional-- equality.record Morphism {I : Set i} {F₁ F₂ : IFun I f}(A₁ : RawIApplicative F₁)(A₂ : RawIApplicative F₂) : Set (i ⊔ suc f) wheremodule A₁ = RawIApplicative A₁module A₂ = RawIApplicative A₂fieldop : ∀ {i j} → F₁ i j A → F₂ i j Aop-pure : ∀ {i} (x : A) → op (A₁.pure {i = i} x) ≡ A₂.pure xop-⊛ : ∀ {i j k} (f : F₁ i j (A → B)) (x : F₁ j k A) →op (f A₁.⊛ x) ≡ (op f A₂.⊛ op x)op-<$> : ∀ {i j} (f : A → B) (x : F₁ i j A) →op (f A₁.<$> x) ≡ (f A₂.<$> op x)op-<$> f x = beginop (A₁._⊛_ (A₁.pure f) x) ≡⟨ op-⊛ _ _ ⟩A₂._⊛_ (op (A₁.pure f)) (op x) ≡⟨ cong₂ A₂._⊛_ (op-pure _) refl ⟩A₂._⊛_ (A₂.pure f) (op x) ∎where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Printing Strings During Evaluation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --rewriting #-}-- see README.Debug.Trace for a use-casemodule Debug.Trace whereopen import Agda.Builtin.Stringopen import Agda.Builtin.Equality-- Postulating the `trace` function and explaining how to compile itpostulatetrace : ∀ {a} {A : Set a} → String → A → A{-# FOREIGN GHC import qualified Debug.Trace as Debug #-}{-# FOREIGN GHC import qualified Data.Text as Text #-}{-# COMPILE GHC trace = const (const (Debug.trace . Text.unpack)) #-}-- Because expressions involving postulates get stuck during evaluation,-- we also postulate an equality characterising `trace`'s behaviour. By-- declaring it as a rewrite rule we internalise that evaluation rule.postulatetrace-eq : ∀ {a} {A : Set a} (a : A) str → trace str a ≡ a{-# BUILTIN REWRITE _≡_ #-}{-# REWRITE trace-eq #-}-- Specialised version of `trace` returning the traced message.traceId : String → StringtraceId str = trace str str
-------------------------------------------------------------------------- The Agda standard library---- Turn a relation into a record definition so as to remember the things-- being related.-- This module has a readme file: README.Data.Wrap------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Wrap whereopen import Data.Product.Nary.NonDependentopen import Function.Nary.NonDependentopen import Level using (Level)open import Relation.Naryprivatevariableℓ : Levelrecord Wrap′ {n} {ls} {A : Sets n ls} (F : A ⇉ Set ℓ) (xs : Product n A): Set ℓ whereconstructor [_]fieldget : uncurryₙ n F xsopen Wrap′ publicWrap : ∀ {n ls} {A : Sets n ls} → A ⇉ Set ℓ → A ⇉ Set ℓWrap {n = n} F = curryₙ n (Wrap′ F)
-------------------------------------------------------------------------- The Agda standard library---- Bytes: showing bit patterns------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word8.Show whereopen import Agda.Builtin.String using (String)open import Data.Bool.Show using (showBit)open import Data.Fin.Base as Fin using (Fin)import Data.Nat.Show as ℕopen import Data.String using (_++_; fromVec; padLeft)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Word8.Baseopen import Function.Base using (_$_)showBits : Word8 → StringshowBits w= "0b" ++_$ fromVec$ Vec.reverse$ Vec.map showBit$ toBits wshowHexa : Word8 → StringshowHexa w= "0x" ++_$ padLeft '0' 2$ ℕ.showInBase 16 (toℕ w)
-------------------------------------------------------------------------- The Agda standard library---- Bytes: simple bindings to Haskell types and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word8.Primitive whereopen import Agda.Builtin.Bool using (Bool)open import Agda.Builtin.Nat using (Nat)open import Agda.Builtin.String using (String)postulateWord8 : SettestBit : Word8 → Nat → BoolsetBit : Word8 → Nat → Word8clearBit : Word8 → Nat → Word8fromNat : Nat → Word8toNat : Word8 → Nat_+_ : Word8 → Word8 → Word8show : Word8 → String{-# FOREIGN GHC import GHC.Word #-}{-# FOREIGN GHC import qualified Data.Bits as B #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# COMPILE GHC Word8 = type Word8 #-}{-# COMPILE GHC testBit = \ w -> B.testBit w . fromIntegral #-}{-# COMPILE GHC setBit = \ w -> B.setBit w . fromIntegral #-}{-# COMPILE GHC clearBit = \ w -> B.clearBit w . fromIntegral #-}{-# COMPILE GHC fromNat = fromIntegral #-}{-# COMPILE GHC toNat = fromIntegral #-}{-# COMPILE GHC _+_ = (+) #-}{-# COMPILE GHC show = T.pack . Prelude.show #-}
-------------------------------------------------------------------------- The Agda standard library---- Byte Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word8.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Data.Unit.Base using (⊤)open import Data.Word8.Base using (Word8; fromℕ)number : Number Word8number = record{ Constraint = λ _ → ⊤; fromNat = λ w → fromℕ w}
-------------------------------------------------------------------------- The Agda standard library---- Bytes: base type and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word8.Base whereopen import Agda.Builtin.Bool using (Bool; true; false)open import Agda.Builtin.Char using (Char)open import Agda.Builtin.Nat using (Nat; _==_)open import Agda.Builtin.Unit using (⊤)open import Data.Fin.Base as Fin using (Fin)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Function.Base using (_$_; _|>_)-------------------------------------------------------------------------------- Re-export type and operationsopen import Data.Word8.Primitive as Prim publicusing ( Word8; _+_; show)renaming ( fromNat to fromℕ; toNat to toℕ)testBit : Word8 → Fin 8 → BooltestBit w i = Prim.testBit w (Fin.toℕ i)_[_]≔_ : Word8 → Fin 8 → Bool → Word8w [ i ]≔ false = Prim.clearBit w (Fin.toℕ i)w [ i ]≔ true = Prim.setBit w (Fin.toℕ i)-------------------------------------------------------------------------------- Basic functionstoBits : Word8 → Vec Bool 8toBits w = Vec.tabulate (testBit w)fromBits : Vec Bool 8 → Word8fromBits bs = Vec.foldl′ _|>_ (fromℕ 0)$ Vec.zipWith (λ i b → _[ i ]≔ b) (Vec.allFin 8) bs_≡ᵇ_ : Word8 → Word8 → Boolw ≡ᵇ w′ = toℕ w == toℕ w′
-------------------------------------------------------------------------- The Agda standard library---- Machine words------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word64 where-------------------------------------------------------------------------- Re-export base definitions and decidability of equalityopen import Data.Word64.Base publicopen import Data.Word64.Properties using (_≈?_; _<?_; _≟_; _==_) public
-------------------------------------------------------------------------- The Agda standard library---- Machine words: unsafe functions using the FFI------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word64.Unsafe whereopen import Agda.Builtin.Bool using (Bool; true; false)open import Data.Fin.Base as Fin using (Fin)open import Data.Product.Base using (proj₁)open import Data.Vec.Base as Vec using (Vec)open import Data.Word8.Base as Word8 using (Word8)open import Data.Word64.Baseopen import Function.Base using (_$_; _|>_)-------------------------------------------------------------------------- Re-export primitives publiclyopen import Data.Word64.Primitive as Prim publicusing ( show )testBit : Word64 → Fin 64 → BooltestBit w i = Prim.testBit w (Fin.toℕ i)_[_]≔_ : Word64 → Fin 64 → Bool → Word64w [ i ]≔ false = Prim.clearBit w (Fin.toℕ i)w [ i ]≔ true = Prim.setBit w (Fin.toℕ i)-------------------------------------------------------------------------- Convert to its componentstoBits : Word64 → Vec Bool 64toBits w = Vec.tabulate (testBit w)fromBits : Vec Bool 64 → Word64fromBits bs = Vec.foldl′ _|>_ (fromℕ 0)$ Vec.zipWith (λ i b → _[ i ]≔ b) (Vec.allFin 64) bstoWord64s : Word64 → Vec Word8 8toWord64s w =let ws = proj₁ (Vec.group 8 8 (toBits w)) inVec.map Word8.fromBits ws
-------------------------------------------------------------------------- The Agda standard library---- Bytes: showing bit patterns------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word64.Show whereopen import Agda.Builtin.String using (String)open import Data.Bool.Show using (showBit)open import Data.Fin.Base as Fin using (Fin)import Data.Nat.Show as ℕopen import Data.String using (_++_; fromVec; padLeft)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Word64.Baseopen import Data.Word64.Unsafeopen import Function.Base using (_$_)showBits : Word64 → StringshowBits w= "0b" ++_$ fromVec$ Vec.reverse$ Vec.map showBit$ toBits wshowHexa : Word64 → StringshowHexa w= "0x" ++_$ padLeft '0' 8$ ℕ.showInBase 16 (toℕ w)
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on machine words------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word64.Properties whereimport Data.Nat.Base as ℕopen import Data.Bool.Base using (Bool)open import Data.Word64.Base using (_≈_; toℕ; Word64; _<_)import Data.Nat.Properties as ℕopen import Relation.Nullary.Decidable.Core using (map′; ⌊_⌋)open import Relation.Binaryusing ( _⇒_; Reflexive; Symmetric; Transitive; Substitutive; Decidable; DecidableEquality; IsEquivalence; IsDecEquivalence; Setoid; DecSetoid; StrictTotalOrder)import Relation.Binary.Construct.On as Onopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym; trans; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; decSetoid)-------------------------------------------------------------------------- Primitive propertiesopen import Agda.Builtin.Word.Propertiesrenaming (primWord64ToNatInjective to toℕ-injective)public-------------------------------------------------------------------------- Properties of _≈_≈⇒≡ : _≈_ ⇒ _≡_≈⇒≡ = toℕ-injective _ _≈-reflexive : _≡_ ⇒ _≈_≈-reflexive = cong toℕ≈-refl : Reflexive _≈_≈-refl = refl≈-sym : Symmetric _≈_≈-sym = sym≈-trans : Transitive _≈_≈-trans = trans≈-subst : ∀ {ℓ} → Substitutive _≈_ ℓ≈-subst P x≈y p = subst P (≈⇒≡ x≈y) pinfix 4 _≈?__≈?_ : Decidable _≈_x ≈? y = toℕ x ℕ.≟ toℕ y≈-isEquivalence : IsEquivalence _≈_≈-isEquivalence = record{ refl = λ {i} → ≈-refl {i}; sym = λ {i j} → ≈-sym {i} {j}; trans = λ {i j k} → ≈-trans {i} {j} {k}}≈-setoid : Setoid _ _≈-setoid = record{ isEquivalence = ≈-isEquivalence}≈-isDecEquivalence : IsDecEquivalence _≈_≈-isDecEquivalence = record{ isEquivalence = ≈-isEquivalence; _≟_ = _≈?_}≈-decSetoid : DecSetoid _ _≈-decSetoid = record{ isDecEquivalence = ≈-isDecEquivalence}-------------------------------------------------------------------------- Properties of _≡_infix 4 _≟__≟_ : DecidableEquality Word64x ≟ y = map′ ≈⇒≡ ≈-reflexive (x ≈? y)≡-setoid : Setoid _ _≡-setoid = setoid Word64≡-decSetoid : DecSetoid _ _≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- Boolean equality test.infix 4 _==__==_ : Word64 → Word64 → Boolw₁ == w₂ = ⌊ w₁ ≟ w₂ ⌋-------------------------------------------------------------------------- Properties of _<_infix 4 _<?__<?_ : Decidable _<__<?_ = On.decidable toℕ ℕ._<_ ℕ._<?_<-strictTotalOrder-≈ : StrictTotalOrder _ _ _<-strictTotalOrder-≈ = On.strictTotalOrder ℕ.<-strictTotalOrder toℕ
-------------------------------------------------------------------------- The Agda standard library---- Word64: simple bindings to Haskell types and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Word64.Primitive whereopen import Agda.Builtin.Bool using (Bool)open import Agda.Builtin.Nat using (Nat)open import Agda.Builtin.String using (String)open import Agda.Builtin.Word using (Word64)postulatetestBit : Word64 → Nat → BoolsetBit : Word64 → Nat → Word64clearBit : Word64 → Nat → Word64show : Word64 → String{-# FOREIGN GHC import GHC.Word #-}{-# FOREIGN GHC import qualified Data.Bits as B #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# COMPILE GHC testBit = \ w -> B.testBit w . fromIntegral #-}{-# COMPILE GHC setBit = \ w -> B.setBit w . fromIntegral #-}{-# COMPILE GHC clearBit = \ w -> B.clearBit w . fromIntegral #-}{-# COMPILE GHC show = T.pack . Prelude.show #-}
-------------------------------------------------------------------------- The Agda standard library---- Word64 Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word64.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Data.Unit.Base using (⊤)open import Data.Word64.Base using (Word64; fromℕ)number : Number Word64number = record{ Constraint = λ _ → ⊤; fromNat = λ w → fromℕ w}
-------------------------------------------------------------------------- The Agda standard library---- Instances for words------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word64.Instances whereopen import Data.Word64.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceWord64-≡-isDecEquivalence = isDecEquivalence _≟_
-------------------------------------------------------------------------- The Agda standard library---- Machine words: basic type and conversion functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word64.Base whereopen import Algebra.Core using (Op₂)open import Data.Nat.Base as ℕ using (ℕ)open import Function.Base using (_on_; _∘₂′_)open import Level using (zero)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Re-export built-ins publiclyopen import Agda.Builtin.Word publicusing (Word64)renaming( primWord64ToNat to toℕ; primWord64FromNat to fromℕ)liftOp₂ : Op₂ ℕ → Op₂ Word64liftOp₂ op = fromℕ ∘₂′ op on toℕinfix 4 _≈__≈_ : Rel Word64 zero_≈_ = _≡_ on toℕinfix 4 _<__<_ : Rel Word64 zero_<_ = ℕ._<_ on toℕinfix 4 _≤__≤_ : Rel Word64 zero_≤_ = ℕ._≤_ on toℕ
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use Data.Word64 instead------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word whereopen import Data.Word64 public{-# WARNING_ON_IMPORT"Data.Word was deprecated in v2.1. Use Data.Word64 instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use Data.Word64.Properties instead------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word.Properties whereopen import Data.Word64.Properties public{-# WARNING_ON_IMPORT"Data.Word.Properties was deprecated in v2.1. Use Data.Word64.Properties instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use Data.Word64.Instances instead------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word.Instances whereopen import Data.Word64.Instances public{-# WARNING_ON_IMPORT"Data.Word.Instances was deprecated in v2.1. Use Data.Word64.Instances instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use Data.Word64.Base instead------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Word.Base whereopen import Data.Word64.Base public{-# WARNING_ON_IMPORT"Data.Word.Base was deprecated in v2.1. Use Data.Word64.Base instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- W-types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.W whereopen import Level using (Level; _⊔_)open import Function.Base using (_$_; _∘_; const)open import Data.Product.Base using (_,_; -,_; proj₂)open import Data.Container.Core using (Container; ⟦_⟧; Shape; Position; _⇒_; ⟪_⟫)open import Data.Container.Relation.Unary.All using (□; all)open import Relation.Nullary.Negation using (¬_)open import Agda.Builtin.Equality using (_≡_; refl)privatevariables p s₁ s₂ p₁ p₂ ℓ : LevelC : Container s pC₁ : Container s₁ p₁C₂ : Container s₂ p₂-- The family of W-types.data W (C : Container s p) : Set (s ⊔ p) wheresup : ⟦ C ⟧ (W C) → W Csup-injective₁ : ∀ {s t : Shape C} {f : Position C s → W C} {g} →sup (s , f) ≡ sup (t , g) → s ≡ tsup-injective₁ refl = refl-- See also Data.W.WithK.sup-injective₂.-- Projections.head : W C → Shape Chead (sup (x , f)) = xtail : (x : W C) → Position C (head x) → W Ctail (sup (x , f)) = f-- mapmap : (m : C₁ ⇒ C₂) → W C₁ → W C₂map m (sup (x , f)) = sup (⟪ m ⟫ (x , λ p → map m (f p)))-- inductionmodule _ (P : W C → Set ℓ)(alg : ∀ {t} → □ C P t → P (sup t)) whereinduction : (w : W C) → P winduction (sup (s , f)) = alg $ all (induction ∘ f)module _ {P : Set ℓ} (alg : ⟦ C ⟧ P → P) wherefoldr : W C → Pfoldr = induction (const P) (alg ∘ -,_ ∘ □.proof)-- If Position is always inhabited, then W_C is empty.inhabited⇒empty : (∀ s → Position C s) → ¬ W Cinhabited⇒empty b = foldr ((_$ b _) ∘ proj₂)
-------------------------------------------------------------------------- The Agda standard library---- Some code related to the W type that relies on the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.W.WithK whereopen import Data.Product.Base using (_,_)open import Data.Container.Coreopen import Data.Wopen import Agda.Builtin.Equalitymodule _ {s p} {C : Container s p}{s : Shape C} {f : Position C s → W C} wheresup-injective₂ : ∀ {g} → sup (s , f) ≡ sup (s , g) → f ≡ gsup-injective₂ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Sized W-types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Data.W.Sized whereopen import Levelopen import Sizeopen import Function.Base using (_$_; _∘_; const)open import Data.Product.Base using (_,_; -,_; proj₂)open import Data.Container.Core as Container using (Container; ⟦_⟧; Shape; Position; _⇒_; ⟪_⟫)open import Data.Container.Relation.Unary.All using (□; all)open import Relation.Nullary.Negation using (¬_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablei : Sizes p s₁ s₂ p₁ p₂ ℓ : LevelC : Container s pC₁ : Container s₁ p₁C₂ : Container s₂ p₂-- The family of W-types.data W (C : Container s p) : Size → Set (s ⊔ p) wheresup : ⟦ C ⟧ (W C i) → W C (↑ i)sup-injective₁ : ∀ {s t : Shape C} {f : Position C s → W C i} {g} →sup (s , f) ≡ sup (t , g) → s ≡ tsup-injective₁ refl = refl-- See also Data.W.WithK.sup-injective₂.-- Projections.head : W C i → Shape Chead (sup (x , f)) = xtail : (x : W C i) → Position C (head x) → W C itail (sup (x , f)) = f-- mapmap : (m : C₁ ⇒ C₂) → W C₁ i → W C₂ imap m (sup c) = sup (⟪ m ⟫ (Container.map (map m) c))-- inductionmodule _ (P : W C ∞ → Set ℓ)(alg : ∀ {t} → □ C P t → P (sup t)) whereinduction : (w : W C _) → P winduction (sup (s , f)) = alg $ all (induction ∘ f)module _ {P : Set ℓ} (alg : ⟦ C ⟧ P → P) wherefoldr : W C _ → Pfoldr = induction (const P) (alg ∘ -,_ ∘ □.proof)-- If Position is always inhabited, then W_C is empty.inhabited⇒empty : (∀ s → Position C s) → ¬ W C iinhabited⇒empty b = foldr ((_$ b _) ∘ proj₂)
-------------------------------------------------------------------------- The Agda standard library---- Indexed W-types aka Petersson-Synek trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.W.Indexed whereopen import Levelopen import Data.Container.Indexed.Coreopen import Data.Product.Base using (_,_; Σ)open import Relation.Unary-- The family of indexed W-types.module _ {ℓ c r} {O : Set ℓ} (C : Container O O c r) whereopen Container Cdata W (o : O) : Set (ℓ ⊔ c ⊔ r) wheresup : ⟦ C ⟧ W o → W o-- Projections.head : W ⊆ Commandhead (sup (c , _)) = ctail : ∀ {o} (w : W o) (r : Response (head w)) → W (next (head w) r)tail (sup (_ , k)) r = k r-- Induction, (primitive) recursion and iteration.ind : ∀ {ℓ} (P : Pred (Σ O W) ℓ) →(∀ {o} (cs : ⟦ C ⟧ W o) → □ C P (o , cs) → P (o , sup cs)) →∀ {o} (w : W o) → P (o , w)ind P φ (sup (c , k)) = φ (c , k) (λ r → ind P φ (k r))rec : ∀ {ℓ} {X : Pred O ℓ} → (⟦ C ⟧ (W ∩ X) ⊆ X) → W ⊆ Xrec φ (sup (c , k))= φ (c , λ r → (k r , rec φ (k r)))iter : ∀ {ℓ} {X : Pred O ℓ} → (⟦ C ⟧ X ⊆ X) → W ⊆ Xiter φ (sup (c , k))= φ (c , λ r → iter φ (k r))
-------------------------------------------------------------------------- The Agda standard library---- Vectors-------------------------------------------------------------------------- This implementation is designed for reasoning about dynamic-- vectors which may increase or decrease in size.-- See `Data.Vec.Functional` for an alternative implementation as-- functions from finite sets, which is more suitable for reasoning-- about fixed sized vectors and for when ease of retrieval is-- important.{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec whereopen import Levelopen import Data.Bool.Baseimport Data.Nat.Properties as ℕopen import Data.Vec.Bounded.Base as Vec≤using (Vec≤; ≤-cast; fromVec)open import Function.Base using (_$_)open import Relation.Nullaryopen import Relation.Unaryprivatevariablea p : LevelA : Set a-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Data.Vec.Base public-------------------------------------------------------------------------- Additional operationsmodule _ {P : A → Set p} (P? : Decidable P) wherefilter : ∀ {n} → Vec A n → Vec≤ A nfilter [] = Vec≤.[]filter (a ∷ as) = if does (P? a) then a Vec≤.∷_ else ≤-cast (ℕ.n≤1+n _) $ filter astakeWhile : ∀ {n} → Vec A n → Vec≤ A ntakeWhile [] = Vec≤.[]takeWhile (a ∷ as) = if does (P? a) then a Vec≤.∷ takeWhile as else Vec≤.[]dropWhile : ∀ {n} → Vec A n → Vec≤ A ndropWhile Vec.[] = Vec≤.[]dropWhile (a Vec.∷ as) =if does (P? a) then ≤-cast (ℕ.n≤1+n _) (dropWhile as)else fromVec (a Vec.∷ as)
-------------------------------------------------------------------------- The Agda standard library---- Showing vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Show whereimport Data.List.Show as Listopen import Data.String.Base using (String)open import Data.Vec.Base using (Vec; toList)open import Function.Base using (_∘_)show : ∀ {a} {A : Set a} {n} → (A → String) → (Vec A n → String)show s = List.show s ∘ toList
-------------------------------------------------------------------------- The Agda standard library---- Vectors made up entirely of unique elements (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.Vec.Relation.Unary.Unique.Setoid {a ℓ} (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open import Data.Vec.Baseimport Data.Vec.Relation.Unary.AllPairs as AllPairsMopen import Level using (_⊔_)open import Relation.Unary using (Pred)open import Relation.Nullary.Negation using (¬_)-------------------------------------------------------------------------- DefinitionprivateDistinct : Rel A ℓDistinct x y = ¬ (x ≈ y)open import Data.Vec.Relation.Unary.AllPairs.Core Distinct publicrenaming (AllPairs to Unique)open import Data.Vec.Relation.Unary.AllPairs {R = Distinct} publicusing (head; tail)
-------------------------------------------------------------------------- The Agda standard library---- Properties of unique vectors (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Unique.Setoid.Properties whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.Vec.Base as Vecopen import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)import Data.Vec.Relation.Unary.All.Properties as Allopen import Data.Vec.Relation.Unary.AllPairs as AllPairs using (AllPairs)open import Data.Vec.Relation.Unary.Unique.Setoidimport Data.Vec.Relation.Unary.AllPairs.Properties as AllPairsopen import Data.Nat.Base using (ℕ; _+_)open import Function.Base using (_∘_; id)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary.Negation using (contradiction; contraposition)privatevariablea b c p ℓ ℓ₁ ℓ₂ ℓ₃ : Level-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ (S : Setoid a ℓ₁) (R : Setoid b ℓ₂) whereopen Setoid S renaming (_≈_ to _≈₁_)open Setoid R renaming (_≈_ to _≈₂_)map⁺ : ∀ {f} → (∀ {x y} → f x ≈₂ f y → x ≈₁ y) →∀ {n xs} → Unique S {n} xs → Unique R {n} (map f xs)map⁺ inj xs! = AllPairs.map⁺ (AllPairs.map (contraposition inj) xs!)-------------------------------------------------------------------------- take & dropmodule _ (S : Setoid a ℓ) wheredrop⁺ : ∀ {n} m {xs} → Unique S {m + n} xs → Unique S {n} (drop m xs)drop⁺ = AllPairs.drop⁺take⁺ : ∀ {n} m {xs} → Unique S {m + n} xs → Unique S {m} (take m xs)take⁺ = AllPairs.take⁺-------------------------------------------------------------------------- tabulatemodule _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)tabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → f i ≈ f j → i ≡ j) →Unique S (tabulate f)tabulate⁺ f-inj = AllPairs.tabulate⁺ (_∘ f-inj)-------------------------------------------------------------------------- lookupmodule _ (S : Setoid a ℓ) whereopen Setoid Slookup-injective : ∀ {n xs} → Unique S {n} xs → ∀ i j → lookup xs i ≈ lookup xs j → i ≡ jlookup-injective (px ∷ pxs) zero zero eq = ≡.refllookup-injective (px ∷ pxs) zero (suc j) eq = contradiction eq (All.lookup⁺ px j)lookup-injective (px ∷ pxs) (suc i) zero eq = contradiction (sym eq) (All.lookup⁺ px i)lookup-injective (px ∷ pxs) (suc i) (suc j) eq = ≡.cong suc (lookup-injective pxs i j eq)
-------------------------------------------------------------------------- The Agda standard library---- Vectors made up entirely of unique elements (propositional equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Unique.Propositional {a} {A : Set a} whereopen import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Data.Vec.Relation.Unary.Unique.Setoid as SetoidUnique-------------------------------------------------------------------------- Re-export the contents of setoid uniquenessopen SetoidUnique (setoid A) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of unique vectors (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Unique.Propositional.Properties whereopen import Data.Vec.Base using (Vec; map; take; drop; tabulate; lookup)open import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)open import Data.Vec.Relation.Unary.AllPairs as AllPairs using (AllPairs)open import Data.Vec.Relation.Unary.Unique.Propositional using (Unique)import Data.Vec.Relation.Unary.Unique.Setoid.Properties as Setoidopen import Data.Fin.Base using (Fin)open import Data.Nat.Base using (_+_)open import Data.Nat.Properties using (<⇒≢)open import Data.Product.Base using (_×_; _,_)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (≡⇒≡×≡)open import Function.Base using (id; _∘_)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Coreusing (refl; _≡_; _≢_; sym)open import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Negation.Core using (¬_)privatevariablea b c p : Level-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ {A : Set a} {B : Set b} wheremap⁺ : ∀ {f} → (∀ {x y} → f x ≡ f y → x ≡ y) →∀ {n} {xs : Vec A n} → Unique xs → Unique (map f xs)map⁺ = Setoid.map⁺ (setoid A) (setoid B)-------------------------------------------------------------------------- take & dropmodule _ {A : Set a} wheredrop⁺ : ∀ {n} m {xs : Vec A (m + n)} → Unique xs → Unique (drop m xs)drop⁺ = Setoid.drop⁺ (setoid A)take⁺ : ∀ {n} m {xs : Vec A (m + n)} → Unique xs → Unique (take m xs)take⁺ = Setoid.take⁺ (setoid A)-------------------------------------------------------------------------- tabulatemodule _ {A : Set a} wheretabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → f i ≡ f j → i ≡ j) → Unique (tabulate f)tabulate⁺ = Setoid.tabulate⁺ (setoid A)-------------------------------------------------------------------------- lookupmodule _ {A : Set a} wherelookup-injective : ∀ {n} {xs : Vec A n} → Unique xs → ∀ i j → lookup xs i ≡ lookup xs j → i ≡ jlookup-injective = Setoid.lookup-injective (setoid A)
-------------------------------------------------------------------------- The Agda standard library---- Vectors where every consecutative pair of elements is related.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Linked {a} {A : Set a} whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)open import Data.Product.Base as Product using (_,_; _×_; uncurry; <_,_>)open import Function.Base using (id; _∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; _⇒_)import Relation.Binary.Definitions as Bopen import Relation.Binary.Construct.Intersection renaming (_∩_ to _∩ᵇ_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Relation.Unary as U renaming (_∩_ to _∩ᵘ_) hiding (_⇒_)open import Relation.Nullary.Decidable as Dec using (yes; no; _×-dec_; map′)privatevariablep q r s ℓ : LevelP : Rel A pQ : Rel A qR : Rel A rS : Rel A sn : ℕ-------------------------------------------------------------------------- Definition-- Linked R xs means that every consecutative pair of elements in xs is-- a member of relation R.infixr 5 _∷_data Linked (R : Rel A ℓ) : Vec A n → Set (a ⊔ ℓ) where[] : Linked R [][-] : ∀ {x} → Linked R (x ∷ [])_∷_ : ∀ {x} {xs : Vec A (suc n)} → R x (Vec.head xs) → Linked R xs → Linked R (x ∷ xs)-------------------------------------------------------------------------- Operationshead : ∀ {x} {xs : Vec A (suc n)} → Linked R (x ∷ xs) → R x (Vec.head xs)head (Rxy ∷ Rxs) = Rxytail : ∀ {xs : Vec A (suc n)} → Linked R xs → Linked R (Vec.tail xs)tail [-] = []tail (_ ∷ Rxs) = Rxsmap : R ⇒ S → Linked R {n} ⊆ Linked Smap R⇒S [] = []map R⇒S [-] = [-]map R⇒S (x~xs ∷ pxs) = R⇒S x~xs ∷ map R⇒S pxszipWith : P ∩ᵇ Q ⇒ R → Linked P {n} ∩ᵘ Linked Q ⊆ Linked RzipWith f ([] , []) = []zipWith f ([-] , [-]) = [-]zipWith f (px ∷ pxs , qx ∷ qxs) = f (px , qx) ∷ zipWith f (pxs , qxs)unzipWith : R ⇒ P ∩ᵇ Q → Linked R {n} ⊆ Linked P ∩ᵘ Linked QunzipWith f [] = [] , []unzipWith f [-] = [-] , [-]unzipWith f (rx ∷ rxs) = Product.zip _∷_ _∷_ (f rx) (unzipWith f rxs)zip : Linked P {n} ∩ᵘ Linked Q ⊆ Linked (P ∩ᵇ Q)zip = zipWith idunzip : Linked (P ∩ᵇ Q) {n} ⊆ Linked P ∩ᵘ Linked Qunzip = unzipWith id-------------------------------------------------------------------------- Properties of predicates preserved by Linkedlinked? : B.Decidable R → U.Decidable (Linked R {n})linked? R? [] = yes []linked? R? (x ∷ []) = yes [-]linked? R? (x ∷ y ∷ xs) =map′ (uncurry _∷_) < head , tail > (R? x y ×-dec linked? R? (y ∷ xs))irrelevant : B.Irrelevant R → U.Irrelevant (Linked R {n})irrelevant irr [] [] = reflirrelevant irr [-] [-] = reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =cong₂ _∷_ (irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : U.Satisfiable (Linked R)satisfiable = [] , []
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Linked------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Linked.Properties whereopen import Data.Vec.Base as Vecopen import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)import Data.Vec.Relation.Unary.All.Properties as Allopen import Data.Vec.Relation.Unary.Linked as Linkedusing (Linked; []; [-]; _∷_)open import Data.Fin.Base using (zero; suc; _<_)open import Data.Nat.Base using (ℕ; zero; suc; s<s⁻¹)open import Level using (Level)open import Function.Base using (_on_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Transitive)open import Relation.Unary using (Pred; Decidable)privatevariablea b p r ℓ : Levelm n : ℕA : Set aB : Set bR : Rel A r-------------------------------------------------------------------------- Relationship to other predicates------------------------------------------------------------------------module _ (trans : Transitive R) whereLinked⇒All : ∀ {v} {xs : Vec _ (suc n)} → R v (head xs) →Linked R xs → All (R v) xsLinked⇒All Rvx [-] = Rvx ∷ []Linked⇒All Rvx (Rxy ∷ Rxs) = Rvx ∷ Linked⇒All (trans Rvx Rxy) Rxslookup⁺ : ∀ {i j} {xs : Vec _ n} →Linked R xs → i < j →R (lookup xs i) (lookup xs j)lookup⁺ {i = zero} {j = suc j} (rx ∷ rxs) i<j = All.lookup⁺ (Linked⇒All rx rxs) jlookup⁺ {i = suc i} {j = suc j} (_ ∷ rxs) i<j = lookup⁺ rxs (s<s⁻¹ i<j)-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for vec operations-------------------------------------------------------------------------- mapmap⁺ : ∀ {f : B → A} {xs} → Linked (R on f) {n} xs → Linked R (map f xs)map⁺ [] = []map⁺ [-] = [-]map⁺ (Rxy ∷ [-]) = Rxy ∷ [-]map⁺ (Rxy ∷ Rxs@(_ ∷ _)) = Rxy ∷ map⁺ Rxsmap⁻ : ∀ {f : B → A} {xs} → Linked R {n} (map f xs) → Linked (R on f) xsmap⁻ {xs = []} [] = []map⁻ {xs = x ∷ []} [-] = [-]map⁻ {xs = x ∷ _ ∷ _} (Rxy ∷ Rxs) = Rxy ∷ map⁻ Rxs
-------------------------------------------------------------------------- The Agda standard library---- Vectors where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Any {a} {A : Set a} whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.Nat.Base using (ℕ; zero; suc; NonZero)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Vec.Base as Vec using (Vec; []; [_]; _∷_)open import Data.Product.Base as Product using (∃; _,_)open import Level using (Level; _⊔_)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Nullary.Decidable as Dec using (no; _⊎-dec_)open import Relation.Unaryprivatevariablep q : LevelP : Pred A pQ : Pred A qn : ℕxs : Vec A n-------------------------------------------------------------------------- Any P xs means that at least one element in xs satisfies P.data Any (P : Pred A p) : ∀ {n} → Vec A n → Set (a ⊔ p) wherehere : ∀ {n x} {xs : Vec A n} (px : P x) → Any P (x ∷ xs)there : ∀ {n x} {xs : Vec A n} (pxs : Any P xs) → Any P (x ∷ xs)-------------------------------------------------------------------------- Operations on Any-- If the tail does not satisfy the predicate, then the head will.head : ∀ {x} → ¬ Any P xs → Any P (x ∷ xs) → P xhead ¬pxs (here px) = pxhead ¬pxs (there pxs) = contradiction pxs ¬pxs-- If the head does not satisfy the predicate, then the tail will.tail : ∀ {x} → ¬ P x → Any P (x ∷ xs) → Any P xstail ¬px (here px) = contradiction px ¬pxtail ¬px (there pxs) = pxs-- Convert back and forth with sumtoSum : ∀ {x} → Any P (x ∷ xs) → P x ⊎ Any P xstoSum (here px) = inj₁ pxtoSum (there pxs) = inj₂ pxsfromSum : ∀ {x} → P x ⊎ Any P xs → Any P (x ∷ xs)fromSum = [ here , there ]′map : P ⊆ Q → ∀ {n} → Any P {n} ⊆ Any Q {n}map g (here px) = here (g px)map g (there pxs) = there (map g pxs)index : Any P {n} xs → Fin nindex (here px) = zeroindex (there pxs) = suc (index pxs)lookup : Any P xs → Alookup {xs = xs} p = Vec.lookup xs (index p)-- If any element satisfies P, then P is satisfied.satisfied : Any P xs → ∃ Psatisfied (here px) = _ , pxsatisfied (there pxs) = satisfied pxs-------------------------------------------------------------------------- Properties of predicates preserved by Anyany? : Decidable P → ∀ {n} → Decidable (Any P {n})any? P? [] = no λ()any? P? (x ∷ xs) = Dec.map′ fromSum toSum (P? x ⊎-dec any? P? xs)satisfiable : Satisfiable P → ∀ {n} → Satisfiable (Any P {suc n})satisfiable (x , p) {zero} = x ∷ [] , here psatisfiable (x , p) {suc n} = Product.map (x ∷_) there (satisfiable (x , p))any = any?{-# WARNING_ON_USAGE any"Warning: any was deprecated in v1.4.Please use any? instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties of vector's Any------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.Any.Properties whereopen import Data.Nat.Base using (suc; zero)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Empty using (⊥)open import Data.List.Base using ([]; _∷_)import Data.List.Relation.Unary.Any as Listopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Sum.Function.Propositional using (_⊎-cong_)open import Data.Product.Base as Product using (∃; ∃₂; _×_; _,_; proj₁; proj₂)open import Data.Vec.Base hiding (here; there)open import Data.Vec.Relation.Unary.Any as Any using (Any; here; there)open import Data.Vec.Membership.Propositionalusing (_∈_; mapWith∈; find; lose)open import Data.Vec.Relation.Binary.Pointwise.Inductiveusing (Pointwise; []; _∷_)open import Function.Baseopen import Function.Bundles using (_↔_; mk↔ₛ′)open import Function.Properties.Inverse using (↔-refl; ↔-trans)open import Level using (Level)open import Relation.Nullary.Negation using (¬_)open import Relation.Unary hiding (_∈_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (_Respects_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans; cong)privatevariablea b p q r ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Equality propertiesmodule _ {P : Pred A p} {_≈_ : Rel A ℓ} wherelift-resp : ∀ {n} → P Respects _≈_ → (Any P {n}) Respects (Pointwise _≈_)lift-resp resp (x∼y ∷ xs∼ys) (here px) = here (resp x∼y px)lift-resp resp (x∼y ∷ xs∼ys) (there pxs) = there (lift-resp resp xs∼ys pxs)module _ {P : Pred A p} wherehere-injective : ∀ {n x xs} {p q : P x} →here {P = P} {n = n} {xs = xs} p ≡ here q → p ≡ qhere-injective refl = reflthere-injective : ∀ {n x xs} {p q : Any P xs} →there {n = n} {x = x} p ≡ there q → p ≡ qthere-injective refl = refl-------------------------------------------------------------------------- Misc¬Any[] : ¬ Any P []¬Any[] ()lookup-index : ∀ {m} {xs : Vec A m} (p : Any P xs) →P (lookup xs (Any.index p))lookup-index (here px) = pxlookup-index (there p) = lookup-index p-------------------------------------------------------------------------- Convert from/to List.AnyfromList⁺ : ∀ {xs} → List.Any P xs → Any P (fromList xs)fromList⁺ (List.here px) = here pxfromList⁺ (List.there v) = there (fromList⁺ v)fromList⁻ : ∀ {xs} → Any P (fromList xs) → List.Any P xsfromList⁻ {x ∷ xs} (here px) = List.here pxfromList⁻ {x ∷ xs} (there pxs) = List.there (fromList⁻ pxs)toList⁺ : ∀ {n} {xs : Vec A n} → Any P xs → List.Any P (toList xs)toList⁺ (here px) = List.here pxtoList⁺ (there v) = List.there (toList⁺ v)toList⁻ : ∀ {n} {xs : Vec A n} → List.Any P (toList xs) → Any P xstoList⁻ {xs = x ∷ xs} (List.here px) = here pxtoList⁻ {xs = x ∷ xs} (List.there pxs) = there (toList⁻ pxs)-------------------------------------------------------------------------- mapmap-id : ∀ {P : Pred A p} (f : P ⊆ P) {n xs} →(∀ {x} (p : P x) → f p ≡ p) →(p : Any P {n} xs) → Any.map f p ≡ pmap-id f hyp (here p) = cong here (hyp p)map-id f hyp (there p) = cong there $ map-id f hyp pmap-∘ : ∀ {P : Pred A p} {Q : A → Set q} {R : A → Set r}(f : Q ⊆ R) (g : P ⊆ Q){n xs} (p : Any P {n} xs) →Any.map (f ∘ g) p ≡ Any.map f (Any.map g p)map-∘ f g (here p) = reflmap-∘ f g (there p) = cong there $ map-∘ f g p-------------------------------------------------------------------------- Swappingmodule _ {P : A → B → Set ℓ} whereswap : ∀ {n m} {xs : Vec A n} {ys : Vec B m} →Any (λ x → Any (P x) ys) xs →Any (λ y → Any (flip P y) xs) ysswap (here pys) = Any.map here pysswap (there pxys) = Any.map there (swap pxys)swap-there : ∀ {n m x xs ys} → (any : Any (λ x → Any (P x) {n} ys) {m} xs) →swap (Any.map (there {x = x}) any) ≡ there (swap any)swap-there (here pys) = reflswap-there (there pxys) = cong (Any.map there) (swap-there pxys)module _ {P : A → B → Set ℓ} whereswap-invol : ∀ {n m} {xs : Vec A n} {ys : Vec B m} →(any : Any (λ x → Any (P x) ys) xs) →swap (swap any) ≡ anyswap-invol (here (here _)) = reflswap-invol (here (there pys)) = cong (Any.map there) (swap-invol (here pys))swap-invol (there pxys) = trans (swap-there (swap pxys))$ cong there (swap-invol pxys)module _ {P : A → B → Set ℓ} whereswap↔ : ∀ {n m} {xs : Vec A n} {ys : Vec B m} →Any (λ x → Any (P x) ys) xs ↔ Any (λ y → Any (flip P y) xs) ysswap↔ = mk↔ₛ′ swap swap swap-invol swap-invol-------------------------------------------------------------------------- Lemmas relating Any to ⊥⊥↔Any⊥ : ∀ {n} {xs : Vec A n} → ⊥ ↔ Any (const ⊥) xs⊥↔Any⊥ = mk↔ₛ′ (λ ()) (λ p → from p) (λ p → from p) (λ ())wherefrom : ∀ {n xs} → Any (const ⊥) {n} xs → ∀ {b} {B : Set b} → Bfrom (there p) = from p⊥↔Any[] : ∀ {P : Pred A p} → ⊥ ↔ Any P []⊥↔Any[] = mk↔ₛ′ (λ()) (λ()) (λ()) (λ())-------------------------------------------------------------------------- Sums commute with Anymodule _ {P : Pred A p} {Q : A → Set q} whereAny-⊎⁺ : ∀ {n} {xs : Vec A n} → Any P xs ⊎ Any Q xs → Any (λ x → P x ⊎ Q x) xsAny-⊎⁺ = [ Any.map inj₁ , Any.map inj₂ ]′Any-⊎⁻ : ∀ {n} {xs : Vec A n} → Any (λ x → P x ⊎ Q x) xs → Any P xs ⊎ Any Q xsAny-⊎⁻ (here (inj₁ p)) = inj₁ (here p)Any-⊎⁻ (here (inj₂ q)) = inj₂ (here q)Any-⊎⁻ (there p) = Sum.map there there (Any-⊎⁻ p)⊎↔ : ∀ {n} {xs : Vec A n} → (Any P xs ⊎ Any Q xs) ↔ Any (λ x → P x ⊎ Q x) xs⊎↔ = mk↔ₛ′ Any-⊎⁺ Any-⊎⁻ to∘from from∘towherefrom∘to : ∀ {n} {xs : Vec A n} (p : Any P xs ⊎ Any Q xs) → Any-⊎⁻ (Any-⊎⁺ p) ≡ pfrom∘to (inj₁ (here p)) = reflfrom∘to (inj₁ (there p)) rewrite from∘to (inj₁ p) = reflfrom∘to (inj₂ (here q)) = reflfrom∘to (inj₂ (there q)) rewrite from∘to (inj₂ q) = reflto∘from : ∀ {n} {xs : Vec A n} (p : Any (λ x → P x ⊎ Q x) xs) →Any-⊎⁺ (Any-⊎⁻ p) ≡ pto∘from (here (inj₁ p)) = reflto∘from (here (inj₂ q)) = reflto∘from (there p) with Any-⊎⁻ p | to∘from pto∘from (there .(Any.map inj₁ p)) | inj₁ p | refl = reflto∘from (there .(Any.map inj₂ q)) | inj₂ q | refl = refl-------------------------------------------------------------------------- Products "commute" with Any.module _ {P : Pred A p} {Q : Pred B q} whereAny-×⁺ : ∀ {n m} {xs : Vec A n} {ys : Vec B m} → Any P xs × Any Q ys →Any (λ x → Any (λ y → P x × Q y) ys) xsAny-×⁺ (p , q) = Any.map (λ p → Any.map (p ,_) q) pAny-×⁻ : ∀ {n m} {xs : Vec A n} {ys : Vec B m} →Any (λ x → Any (λ y → P x × Q y) ys) xs →Any P xs × Any Q ysAny-×⁻ pq with find pq... | x , x∈xs , pxys with find pxys... | y , y∈ys , px , py = lose x∈xs px , lose y∈ys py-------------------------------------------------------------------------- Invertible introduction (⁺) and elimination (⁻) rules for various-- vector functions-------------------------------------------------------------------------- Singleton ([_])module _ {P : Pred A p} wheresingleton⁺ : ∀ {x} → P x → Any P [ x ]singleton⁺ Px = here Pxsingleton⁻ : ∀ {x} → Any P [ x ] → P xsingleton⁻ (here Px) = Pxsingleton⁺∘singleton⁻ : ∀ {x} (p : Any P [ x ]) →singleton⁺ (singleton⁻ p) ≡ psingleton⁺∘singleton⁻ (here px) = reflsingleton⁻∘singleton⁺ : ∀ {x} (p : P x) →singleton⁻ (singleton⁺ p) ≡ psingleton⁻∘singleton⁺ p = reflsingleton↔ : ∀ {x} → P x ↔ Any P [ x ]singleton↔ = mk↔ₛ′ singleton⁺ singleton⁻ singleton⁺∘singleton⁻ singleton⁻∘singleton⁺-------------------------------------------------------------------------- mapmodule _ {f : A → B} wheremap⁺ : ∀ {P : Pred B p} {n} {xs : Vec A n} →Any (P ∘ f) xs → Any P (map f xs)map⁺ (here p) = here pmap⁺ (there p) = there $ map⁺ pmap⁻ : ∀ {P : Pred B p} {n} {xs : Vec A n} →Any P (map f xs) → Any (P ∘ f) xsmap⁻ {xs = x ∷ xs} (here p) = here pmap⁻ {xs = x ∷ xs} (there p) = there $ map⁻ pmap⁺∘map⁻ : ∀ {P : Pred B p} {n} {xs : Vec A n} →(p : Any P (map f xs)) → map⁺ (map⁻ p) ≡ pmap⁺∘map⁻ {xs = x ∷ xs} (here p) = reflmap⁺∘map⁻ {xs = x ∷ xs} (there p) = cong there (map⁺∘map⁻ p)map⁻∘map⁺ : ∀ (P : Pred B p) {n} {xs : Vec A n} →(p : Any (P ∘ f) xs) → map⁻ {P = P} (map⁺ p) ≡ pmap⁻∘map⁺ P (here p) = reflmap⁻∘map⁺ P (there p) = cong there (map⁻∘map⁺ P p)map↔ : ∀ {P : Pred B p} {n} {xs : Vec A n} →Any (P ∘ f) xs ↔ Any P (map f xs)map↔ = mk↔ₛ′ map⁺ map⁻ map⁺∘map⁻ (map⁻∘map⁺ _)-------------------------------------------------------------------------- _++_module _ {P : Pred A p} where++⁺ˡ : ∀ {n m} {xs : Vec A n} {ys : Vec A m} → Any P xs → Any P (xs ++ ys)++⁺ˡ (here p) = here p++⁺ˡ (there p) = there (++⁺ˡ p)++⁺ʳ : ∀ {n m} (xs : Vec A n) {ys : Vec A m} → Any P ys → Any P (xs ++ ys)++⁺ʳ [] p = p++⁺ʳ (x ∷ xs) p = there (++⁺ʳ xs p)++⁻ : ∀ {n m} (xs : Vec A n) {ys : Vec A m} → Any P (xs ++ ys) → Any P xs ⊎ Any P ys++⁻ [] p = inj₂ p++⁻ (x ∷ xs) (here p) = inj₁ (here p)++⁻ (x ∷ xs) (there p) = Sum.map there id (++⁻ xs p)++⁺∘++⁻ : ∀ {n m} (xs : Vec A n) {ys : Vec A m} (p : Any P (xs ++ ys)) →[ ++⁺ˡ , ++⁺ʳ xs ]′ (++⁻ xs p) ≡ p++⁺∘++⁻ [] p = refl++⁺∘++⁻ (x ∷ xs) (here p) = refl++⁺∘++⁻ (x ∷ xs) (there p) with ++⁻ xs p | ++⁺∘++⁻ xs p++⁺∘++⁻ (x ∷ xs) (there p) | inj₁ p′ | ih = cong there ih++⁺∘++⁻ (x ∷ xs) (there p) | inj₂ p′ | ih = cong there ih++⁻∘++⁺ : ∀ {n m} (xs : Vec A n) {ys : Vec A m} (p : Any P xs ⊎ Any P ys) →++⁻ xs ([ ++⁺ˡ , ++⁺ʳ xs ]′ p) ≡ p++⁻∘++⁺ [] (inj₂ p) = refl++⁻∘++⁺ (x ∷ xs) (inj₁ (here p)) = refl++⁻∘++⁺ (x ∷ xs) {ys} (inj₁ (there p)) rewrite ++⁻∘++⁺ xs {ys} (inj₁ p) = refl++⁻∘++⁺ (x ∷ xs) (inj₂ p) rewrite ++⁻∘++⁺ xs (inj₂ p) = refl++↔ : ∀ {n m} {xs : Vec A n} {ys : Vec A m} →(Any P xs ⊎ Any P ys) ↔ Any P (xs ++ ys)++↔ {xs = xs} = mk↔ₛ′ [ ++⁺ˡ , ++⁺ʳ xs ]′ (++⁻ xs) (++⁺∘++⁻ xs) (++⁻∘++⁺ xs)++-comm : ∀ {n m} (xs : Vec A n) (ys : Vec A m) →Any P (xs ++ ys) → Any P (ys ++ xs)++-comm xs ys = [ ++⁺ʳ ys , ++⁺ˡ ]′ ∘ ++⁻ xs++-comm∘++-comm : ∀ {n m} (xs : Vec A n) {ys : Vec A m} (p : Any P (xs ++ ys)) →++-comm ys xs (++-comm xs ys p) ≡ p++-comm∘++-comm [] {ys} prewrite ++⁻∘++⁺ ys {ys = []} (inj₁ p) = refl++-comm∘++-comm (x ∷ xs) {ys} (here p)rewrite ++⁻∘++⁺ ys {ys = x ∷ xs} (inj₂ (here p)) = refl++-comm∘++-comm (x ∷ xs) (there p) with ++⁻ xs p | ++-comm∘++-comm xs p++-comm∘++-comm (x ∷ xs) {ys} (there .([ ++⁺ʳ xs , ++⁺ˡ ]′ (++⁻ ys (++⁺ʳ ys p))))| inj₁ p | reflrewrite ++⁻∘++⁺ ys (inj₂ p)| ++⁻∘++⁺ ys (inj₂ $ there {x = x} p) = refl++-comm∘++-comm (x ∷ xs) {ys} (there .([ ++⁺ʳ xs , ++⁺ˡ ]′ (++⁻ ys (++⁺ˡ p))))| inj₂ p | reflrewrite ++⁻∘++⁺ ys {ys = xs} (inj₁ p)| ++⁻∘++⁺ ys {ys = x ∷ xs} (inj₁ p) = refl++↔++ : ∀ {n m} (xs : Vec A n) (ys : Vec A m) → Any P (xs ++ ys) ↔ Any P (ys ++ xs)++↔++ xs ys = mk↔ₛ′ (++-comm xs ys) (++-comm ys xs)(++-comm∘++-comm ys) (++-comm∘++-comm xs)++-insert : ∀ {n m x} (xs : Vec A n) {ys : Vec A m} → P x → Any P (xs ++ [ x ] ++ ys)++-insert xs Px = ++⁺ʳ xs (++⁺ˡ (singleton⁺ Px))-------------------------------------------------------------------------- concatmodule _ {P : Pred A p} whereconcat⁺ : ∀ {n m} {xss : Vec (Vec A n) m} → Any (Any P) xss → Any P (concat xss)concat⁺ (here p) = ++⁺ˡ pconcat⁺ (there {x = xs} p) = ++⁺ʳ xs (concat⁺ p)concat⁻ : ∀ {n m} (xss : Vec (Vec A n) m) → Any P (concat xss) → Any (Any P) xssconcat⁻ (xs ∷ xss) p = [ here , there ∘ concat⁻ xss ]′ (++⁻ xs p)concat⁻∘++⁺ˡ : ∀ {n m xs} (xss : Vec (Vec A n) m) (p : Any P xs) →concat⁻ (xs ∷ xss) (++⁺ˡ p) ≡ here pconcat⁻∘++⁺ˡ xss p rewrite ++⁻∘++⁺ _ {concat xss} (inj₁ p) = reflconcat⁻∘++⁺ʳ : ∀ {n m} xs (xss : Vec (Vec A n) m) (p : Any P (concat xss)) →concat⁻ (xs ∷ xss) (++⁺ʳ xs p) ≡ there (concat⁻ xss p)concat⁻∘++⁺ʳ xs xss p rewrite ++⁻∘++⁺ xs (inj₂ p) = reflconcat⁺∘concat⁻ : ∀ {n m} (xss : Vec (Vec A n) m) (p : Any P (concat xss)) →concat⁺ (concat⁻ xss p) ≡ pconcat⁺∘concat⁻ (xs ∷ xss) p with ++⁻ xs p in eq... | inj₁ pxs= trans (cong [ ++⁺ˡ , ++⁺ʳ xs ]′ (sym eq))$ ++⁺∘++⁻ xs p... | inj₂ pxss rewrite concat⁺∘concat⁻ xss pxss= trans (cong [ ++⁺ˡ , ++⁺ʳ xs ]′ (sym eq))$ ++⁺∘++⁻ xs pconcat⁻∘concat⁺ : ∀ {n m} {xss : Vec (Vec A n) m} (p : Any (Any P) xss) →concat⁻ xss (concat⁺ p) ≡ pconcat⁻∘concat⁺ {xss = xs ∷ xss} (here p)rewrite ++⁻∘++⁺ xs {concat xss} (inj₁ p) = reflconcat⁻∘concat⁺ {xss = xs ∷ xss} (there p)rewrite ++⁻∘++⁺ xs {concat xss} (inj₂ (concat⁺ p))| concat⁻∘concat⁺ p = reflconcat↔ : ∀ {n m} {xss : Vec (Vec A n) m} → Any (Any P) xss ↔ Any P (concat xss)concat↔ {xss = xss} = mk↔ₛ′ concat⁺ (concat⁻ xss) (concat⁺∘concat⁻ xss) concat⁻∘concat⁺-------------------------------------------------------------------------- tabulatemodule _ {P : Pred A p} wheretabulate⁺ : ∀ {n} {f : Fin n → A} i → P (f i) → Any P (tabulate f)tabulate⁺ zero p = here ptabulate⁺ (suc i) p = there (tabulate⁺ i p)tabulate⁻ : ∀ {n} {f : Fin n → A} →Any P (tabulate f) → ∃ λ i → P (f i)tabulate⁻ (here p) = zero , ptabulate⁻ (there p) = Product.map suc id (tabulate⁻ p)-------------------------------------------------------------------------- mapWith∈module _ {P : Pred B p} wheremapWith∈⁺ : ∀ {n} {xs : Vec A n} (f : ∀ {x} → x ∈ xs → B) →(∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) →Any P (mapWith∈ xs f)mapWith∈⁺ f (_ , here refl , p) = here pmapWith∈⁺ f (_ , there x∈xs , p) =there $ mapWith∈⁺ (f ∘ there) (_ , x∈xs , p)mapWith∈⁻ : ∀ {n} (xs : Vec A n) (f : ∀ {x} → x ∈ xs → B) →Any P (mapWith∈ xs f) →∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)mapWith∈⁻ (y ∷ xs) f (here p) = (y , here refl , p)mapWith∈⁻ (y ∷ xs) f (there p) =Product.map id (Product.map there id) $ mapWith∈⁻ xs (f ∘ there) pmapWith∈↔ : ∀ {n} {xs : Vec A n} {f : ∀ {x} → x ∈ xs → B} →(∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) ↔ Any P (mapWith∈ xs f)mapWith∈↔ = mk↔ₛ′ (mapWith∈⁺ _) (mapWith∈⁻ _ _) (to∘from _ _) (from∘to _)wherefrom∘to : ∀ {n} {xs : Vec A n} (f : ∀ {x} → x ∈ xs → B)(p : ∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) →mapWith∈⁻ xs f (mapWith∈⁺ f p) ≡ pfrom∘to f (_ , here refl , p) = reflfrom∘to f (_ , there x∈xs , p)rewrite from∘to (f ∘ there) (_ , x∈xs , p) = reflto∘from : ∀ {n} (xs : Vec A n) (f : ∀ {x} → x ∈ xs → B)(p : Any P (mapWith∈ xs f)) →mapWith∈⁺ f (mapWith∈⁻ xs f p) ≡ pto∘from (y ∷ xs) f (here p) = reflto∘from (y ∷ xs) f (there p) =cong there $ to∘from xs (f ∘ there) p-------------------------------------------------------------------------- _∷_∷↔ : ∀ {n} (P : Pred A p) {x} {xs : Vec A n} →(P x ⊎ Any P xs) ↔ Any P (x ∷ xs)∷↔ P {x} {xs} = ↔-trans (singleton↔ ⊎-cong ↔-refl) ++↔-------------------------------------------------------------------------- _>>=_module _ {A B : Set a} {P : Pred B p} {m} {f : A → Vec B m} whereopen CartesianBind>>=↔ : ∀ {n} {xs : Vec A n} → Any (Any P ∘ f) xs ↔ Any P (xs >>= f)>>=↔ = ↔-trans map↔ concat↔
-------------------------------------------------------------------------- The Agda standard library---- Vectors where every pair of elements are related (symmetrically)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_)module Data.Vec.Relation.Unary.AllPairs{a ℓ} {A : Set a} {R : Rel A ℓ} whereopen import Data.Nat.Base using (suc)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)open import Data.Product.Base as Prod using (_,_; _×_; uncurry; <_,_>)open import Function.Base using (id; _∘_)open import Level using (_⊔_)open import Relation.Binary.Definitions as Bopen import Relation.Binary.Construct.Intersection renaming (_∩_ to _∩ᵇ_)open import Relation.Binary.PropositionalEquality.Core using (refl; cong₂)open import Relation.Unary as U renaming (_∩_ to _∩ᵘ_) hiding (_⇒_)open import Relation.Nullary.Decidable as Dec using (yes; no; _×-dec_)-------------------------------------------------------------------------- Definitionopen import Data.Vec.Relation.Unary.AllPairs.Core public-------------------------------------------------------------------------- Operationshead : ∀ {n} {xs : Vec A (suc n)} → AllPairs R xs → All (R (Vec.head xs)) (Vec.tail xs)head (px ∷ pxs) = pxtail : ∀ {n} {xs : Vec A (suc n)} → AllPairs R xs → AllPairs R (Vec.tail xs)tail (px ∷ pxs) = pxsuncons : ∀ {n} {xs : Vec A (suc n)} → AllPairs R xs →All (R (Vec.head xs)) (Vec.tail xs) × AllPairs R (Vec.tail xs)uncons = < head , tail >module _ {s} {S : Rel A s} wheremap : ∀ {n} → R ⇒ S → AllPairs R {n} ⊆ AllPairs S {n}map ~₁⇒~₂ [] = []map ~₁⇒~₂ (x~xs ∷ pxs) = All.map ~₁⇒~₂ x~xs ∷ (map ~₁⇒~₂ pxs)module _ {s t} {S : Rel A s} {T : Rel A t} wherezipWith : ∀ {n} → R ∩ᵇ S ⇒ T → AllPairs R {n} ∩ᵘ AllPairs S {n} ⊆ AllPairs T {n}zipWith f ([] , []) = []zipWith f (px ∷ pxs , qx ∷ qxs) = All.map f (All.zip (px , qx)) ∷ zipWith f (pxs , qxs)unzipWith : ∀ {n} → T ⇒ R ∩ᵇ S → AllPairs T {n} ⊆ AllPairs R {n} ∩ᵘ AllPairs S {n}unzipWith f [] = [] , []unzipWith f (rx ∷ rxs) = Prod.zip _∷_ _∷_ (All.unzip (All.map f rx)) (unzipWith f rxs)module _ {s} {S : Rel A s} wherezip : ∀ {n} → AllPairs R {n} ∩ᵘ AllPairs S {n} ⊆ AllPairs (R ∩ᵇ S) {n}zip = zipWith idunzip : ∀ {n} → AllPairs (R ∩ᵇ S) {n} ⊆ AllPairs R {n} ∩ᵘ AllPairs S {n}unzip = unzipWith id-------------------------------------------------------------------------- Properties of predicates preserved by AllPairsallPairs? : ∀ {n} → B.Decidable R → U.Decidable (AllPairs R {n})allPairs? R? [] = yes []allPairs? R? (x ∷ xs) =Dec.map′ (uncurry _∷_) uncons (All.all? (R? x) xs ×-dec allPairs? R? xs)irrelevant : ∀ {n} → B.Irrelevant R → U.Irrelevant (AllPairs R {n})irrelevant irr [] [] = reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =cong₂ _∷_ (All.irrelevant irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : U.Satisfiable (AllPairs R)satisfiable = [] , []
-------------------------------------------------------------------------- The Agda standard library---- Properties related to AllPairs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.AllPairs.Properties whereopen import Data.Vec.Base using (_∷_; map; _++_; concat; take; drop; tabulate)import Data.Vec.Properties as Vecopen import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)import Data.Vec.Relation.Unary.All.Properties as Allopen import Data.Vec.Relation.Unary.AllPairs as AllPairs using (AllPairs; []; _∷_)open import Data.Bool.Base using (true; false)open import Data.Fin.Base using (Fin)open import Data.Fin.Properties using (suc-injective)open import Data.Nat.Base using (zero; suc; _+_)open import Function.Base using (_∘_)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≢_)privatevariablea b c p ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for vector operations-------------------------------------------------------------------------- mapmodule _ {R : Rel A ℓ} {f : B → A} wheremap⁺ : ∀ {n xs} → AllPairs (λ x y → R (f x) (f y)) {n} xs →AllPairs R {n} (map f xs)map⁺ [] = []map⁺ (x∉xs ∷ xs!) = All.map⁺ x∉xs ∷ map⁺ xs!-------------------------------------------------------------------------- ++module _ {R : Rel A ℓ} where++⁺ : ∀ {n m xs ys} → AllPairs R {n} xs → AllPairs R {m} ys →All (λ x → All (R x) ys) xs → AllPairs R (xs ++ ys)++⁺ [] Rys _ = Rys++⁺ (px ∷ Rxs) Rys (Rxys ∷ Rxsys) = All.++⁺ px Rxys ∷ ++⁺ Rxs Rys Rxsys-------------------------------------------------------------------------- concatmodule _ {R : Rel A ℓ} whereconcat⁺ : ∀ {n m xss} → All (AllPairs R {n}) {m} xss →AllPairs (λ xs ys → All (λ x → All (R x) ys) xs) xss →AllPairs R (concat xss)concat⁺ [] [] = []concat⁺ (pxs ∷ pxss) (Rxsxss ∷ Rxss) = ++⁺ pxs (concat⁺ pxss Rxss)(All.map All.concat⁺ (All.All-swap Rxsxss))-------------------------------------------------------------------------- take and dropmodule _ {R : Rel A ℓ} wheretake⁺ : ∀ {n} m {xs} → AllPairs R {m + n} xs → AllPairs R {m} (take m xs)take⁺ zero pxs = []take⁺ (suc m) {x ∷ xs} (px ∷ pxs) = All.take⁺ m px ∷ take⁺ m pxsdrop⁺ : ∀ {n} m {xs} → AllPairs R {m + n} xs → AllPairs R {n} (drop m xs)drop⁺ zero pxs = pxsdrop⁺ (suc m) (_ ∷ pxs) = drop⁺ m pxs-------------------------------------------------------------------------- tabulatemodule _ {R : Rel A ℓ} wheretabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → i ≢ j → R (f i) (f j)) →AllPairs R (tabulate f)tabulate⁺ {zero} fᵢ~fⱼ = []tabulate⁺ {suc n} fᵢ~fⱼ =All.tabulate⁺ (λ j → fᵢ~fⱼ λ()) ∷tabulate⁺ (fᵢ~fⱼ ∘ (_∘ suc-injective))
-------------------------------------------------------------------------- The Agda standard library---- Vectors where every pair of elements are related (symmetrically)-------------------------------------------------------------------------- Core modules are not meant to be used directly outside of the-- standard library.-- This module should be removable if and when Agda issue-- https://github.com/agda/agda/issues/3210 is fixed{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)module Data.Vec.Relation.Unary.AllPairs.Core{a ℓ} {A : Set a} (R : Rel A ℓ) whereopen import Levelopen import Data.Vec.Baseopen import Data.Vec.Relation.Unary.All-------------------------------------------------------------------------- Definition-- AllPairs R xs means that every pair of elements (x , y) in xs is a-- member of relation R (as long as x comes before y in the vector).infixr 5 _∷_data AllPairs : ∀ {n} → Vec A n → Set (a ⊔ ℓ) where[] : AllPairs []_∷_ : ∀ {n x} {xs : Vec A n} → All (R x) xs → AllPairs xs → AllPairs (x ∷ xs)
-------------------------------------------------------------------------- The Agda standard library---- Vectors where all elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.All whereopen import Data.Nat.Base using (ℕ; zero; suc; NonZero)open import Data.Product.Base as Product using (_×_; _,_; uncurry; <_,_>)open import Data.Sum.Base as Sum using (inj₁; inj₂)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Relation.Unary.Any as Any using (Any; here; there)open import Data.Vec.Membership.Propositional renaming (_∈_ to _∈ₚ_)import Data.Vec.Membership.Setoid as SetoidMembershipopen import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Nullary.Decidable as Dec using (_×-dec_; yes; no)open import Relation.Unary hiding (_∈_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (_Respects_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)privatevariablea b c p q r ℓ : LevelA : Set aB : Set bC : Set cP : Pred A pQ : Pred A qR : Pred A rn : ℕx : Axs : Vec A n-------------------------------------------------------------------------- All P xs means that all elements in xs satisfy P.infixr 5 _∷_data All {A : Set a} (P : Pred A p) : Vec A n → Set (p ⊔ a) where[] : All P []_∷_ : (px : P x) (pxs : All P xs) → All P (x ∷ xs)-------------------------------------------------------------------------- Operations on Allhead : All P (x ∷ xs) → P xhead (px ∷ pxs) = pxtail : All P (x ∷ xs) → All P xstail (px ∷ pxs) = pxsreduce : (f : ∀ {x} → P x → B) → ∀ {n} {xs : Vec A n} → All P xs → Vec B nreduce f [] = []reduce f (px ∷ pxs) = f px ∷ reduce f pxsuncons : All P (x ∷ xs) → P x × All P xsuncons = < head , tail >map : P ⊆ Q → All P ⊆ All Q {n}map g [] = []map g (px ∷ pxs) = g px ∷ map g pxszip : All P ∩ All Q ⊆ All (P ∩ Q) {n}zip ([] , []) = []zip (px ∷ pxs , qx ∷ qxs) = (px , qx) ∷ zip (pxs , qxs)unzip : All (P ∩ Q) {n} ⊆ All P ∩ All Qunzip [] = [] , []unzip (pqx ∷ pqxs) = Product.zip _∷_ _∷_ pqx (unzip pqxs)module _ {P : Pred A p} {Q : Pred B q} {R : Pred C r} wherezipWith : ∀ {_⊕_ : A → B → C} →(∀ {x y} → P x → Q y → R (x ⊕ y)) →∀ {n xs ys} → All P {n} xs → All Q {n} ys →All R {n} (Vec.zipWith _⊕_ xs ys)zipWith _⊕_ {xs = []} {[]} [] [] = []zipWith _⊕_ {xs = x ∷ xs} {y ∷ ys} (px ∷ pxs) (qy ∷ qys) =px ⊕ qy ∷ zipWith _⊕_ pxs qys-------------------------------------------------------------------------- Generalised lookup based on a proof of AnylookupAny : All P xs → (i : Any Q xs) → (P ∩ Q) (Any.lookup i)lookupAny (px ∷ pxs) (here qx) = px , qxlookupAny (px ∷ pxs) (there i) = lookupAny pxs ilookupWith : ∀[ P ⇒ Q ⇒ R ] → All P xs → (i : Any Q xs) → R (Any.lookup i)lookupWith f pxs i = Product.uncurry f (lookupAny pxs i)lookup : All P xs → (∀ {x} → x ∈ₚ xs → P x)lookup pxs = lookupWith (λ { px refl → px }) pxsmodule _(S : Setoid a ℓ) {P : Pred (Setoid.Carrier S) p} whereopen Setoid S renaming (sym to sym₁)open SetoidMembership Slookupₛ : P Respects _≈_ → All P xs → (∀ {x} → x ∈ xs → P x)lookupₛ resp pxs = lookupWith (λ py x=y → resp (sym₁ x=y) py) pxs-------------------------------------------------------------------------- Properties of predicates preserved by Allall? : ∀ {n} → Decidable P → Decidable (All P {n})all? P? [] = yes []all? P? (x ∷ xs) = Dec.map′ (uncurry _∷_) uncons (P? x ×-dec all? P? xs)universal : Universal P → ∀ {n} → Universal (All P {n})universal u [] = []universal u (x ∷ xs) = u x ∷ universal u xsirrelevant : Irrelevant P → ∀ {n} → Irrelevant (All P {n})irrelevant irr [] [] = reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =cong₂ _∷_ (irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : Satisfiable P → ∀ {n} → Satisfiable (All P {n})satisfiable (x , p) {zero} = [] , []satisfiable (x , p) {suc n} = Product.map (x ∷_) (p ∷_) (satisfiable (x , p))-------------------------------------------------------------------------- Generalised decidability proceduredecide : Π[ P ∪ Q ] → Π[ All P {n} ∪ Any Q ]decide p∪q [] = inj₁ []decide p∪q (x ∷ xs) with p∪q x... | inj₂ qx = inj₂ (here qx)... | inj₁ px = Sum.map (px ∷_) there (decide p∪q xs)all = all?{-# WARNING_ON_USAGE all"Warning: all was deprecated in v1.4.Please use all? instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties related to All------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Unary.All.Properties whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base using ([]; _∷_)open import Data.List.Relation.Unary.All as List using ([]; _∷_)open import Data.Product.Base as Product using (_×_; _,_; uncurry; uncurry′)open import Data.Vec.Base as Vec using (Vec; []; _∷_; map; _++_; concat;tabulate; drop; take; toList; fromList)open import Data.Vec.Relation.Unary.All as All using (All; []; _∷_)open import Level using (Level)open import Function.Base using (_∘_; id)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Relation.Unary using (Pred) renaming (_⊆_ to _⋐_)open import Relation.Binary.Core using (REL)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂)privatevariablea b p q : LevelA : Set aB : Set bP : Pred A pQ : Pred B qm n : ℕxs : Vec A n-------------------------------------------------------------------------- lookuplookup⁺ : All P xs → ∀ i → P (Vec.lookup xs i)lookup⁺ (px ∷ _) zero = pxlookup⁺ (_ ∷ pxs) (suc i) = lookup⁺ pxs ilookup⁻ : (∀ i → P (Vec.lookup xs i)) → All P xslookup⁻ {xs = []} pxs = []lookup⁻ {xs = _ ∷ _} pxs = pxs zero ∷ lookup⁻ (pxs ∘ suc)-------------------------------------------------------------------------- mapmap⁺ : {f : A → B} → All (P ∘ f) xs → All P (map f xs)map⁺ [] = []map⁺ (px ∷ pxs) = px ∷ map⁺ pxsmap⁻ : {f : A → B} → All P (map f xs) → All (P ∘ f) xsmap⁻ {xs = []} [] = []map⁻ {xs = _ ∷ _} (px ∷ pxs) = px ∷ map⁻ pxs-- A variant of All.mapgmap : {f : A → B} → P ⋐ Q ∘ f → All P {n} ⋐ All Q {n} ∘ map fgmap g = map⁺ ∘ All.map g-------------------------------------------------------------------------- _++_++⁺ : {xs : Vec A m} {ys : Vec A n} →All P xs → All P ys → All P (xs ++ ys)++⁺ [] pys = pys++⁺ (px ∷ pxs) pys = px ∷ ++⁺ pxs pys++ˡ⁻ : (xs : Vec A m) {ys : Vec A n} →All P (xs ++ ys) → All P xs++ˡ⁻ [] _ = []++ˡ⁻ (x ∷ xs) (px ∷ pxs) = px ∷ ++ˡ⁻ xs pxs++ʳ⁻ : (xs : Vec A m) {ys : Vec A n} →All P (xs ++ ys) → All P ys++ʳ⁻ [] pys = pys++ʳ⁻ (x ∷ xs) (px ∷ pxs) = ++ʳ⁻ xs pxs++⁻ : (xs : Vec A m) {ys : Vec A n} →All P (xs ++ ys) → All P xs × All P ys++⁻ [] p = [] , p++⁻ (x ∷ xs) (px ∷ pxs) = Product.map₁ (px ∷_) (++⁻ _ pxs)++⁺∘++⁻ : (xs : Vec A m) {ys : Vec A n} →(p : All P (xs ++ ys)) →uncurry′ ++⁺ (++⁻ xs p) ≡ p++⁺∘++⁻ [] p = refl++⁺∘++⁻ (x ∷ xs) (px ∷ pxs) = cong (px ∷_) (++⁺∘++⁻ xs pxs)++⁻∘++⁺ : {xs : Vec A m} {ys : Vec A n} →(p : All P xs × All P ys) →++⁻ xs (uncurry ++⁺ p) ≡ p++⁻∘++⁺ ([] , pys) = refl++⁻∘++⁺ (px ∷ pxs , pys) rewrite ++⁻∘++⁺ (pxs , pys) = refl++↔ : {xs : Vec A m} {ys : Vec A n} →(All P xs × All P ys) ↔ All P (xs ++ ys)++↔ {xs = xs} = mk↔ₛ′ (uncurry ++⁺) (++⁻ xs) (++⁺∘++⁻ xs) ++⁻∘++⁺-------------------------------------------------------------------------- concatconcat⁺ : {xss : Vec (Vec A m) n} →All (All P) xss → All P (concat xss)concat⁺ [] = []concat⁺ (pxs ∷ pxss) = ++⁺ pxs (concat⁺ pxss)concat⁻ : (xss : Vec (Vec A m) n) →All P (concat xss) → All (All P) xssconcat⁻ [] [] = []concat⁻ (xs ∷ xss) pxss = ++ˡ⁻ xs pxss ∷ concat⁻ xss (++ʳ⁻ xs pxss)-------------------------------------------------------------------------- swapmodule _ {_~_ : REL A B p} whereAll-swap : ∀ {n m xs ys} →All (λ x → All (x ~_) ys) {n} xs →All (λ y → All (_~ y) xs) {m} ysAll-swap {ys = []} _ = []All-swap {ys = y ∷ ys} [] = All.universal (λ _ → []) (y ∷ ys)All-swap {ys = y ∷ ys} ((x~y ∷ x~ys) ∷ pxs) =(x~y ∷ (All.map All.head pxs)) ∷All-swap (x~ys ∷ (All.map All.tail pxs))-------------------------------------------------------------------------- tabulatemodule _ {P : A → Set p} wheretabulate⁺ : ∀ {n} {f : Fin n → A} →(∀ i → P (f i)) → All P (tabulate f)tabulate⁺ {zero} Pf = []tabulate⁺ {suc n} Pf = Pf zero ∷ tabulate⁺ (Pf ∘ suc)tabulate⁻ : ∀ {n} {f : Fin n → A} →All P (tabulate f) → (∀ i → P (f i))tabulate⁻ (px ∷ _) zero = pxtabulate⁻ (_ ∷ pf) (suc i) = tabulate⁻ pf i-------------------------------------------------------------------------- take and dropdrop⁺ : ∀ m {xs} → All P {m + n} xs → All P {n} (drop m xs)drop⁺ zero pxs = pxsdrop⁺ (suc m) {x ∷ xs} (px ∷ pxs) = drop⁺ m pxstake⁺ : ∀ m {xs} → All P {m + n} xs → All P {m} (take m xs)take⁺ zero pxs = []take⁺ (suc m) {x ∷ xs} (px ∷ pxs) = px ∷ take⁺ m pxs-------------------------------------------------------------------------- toListmodule _ {P : Pred A p} wheretoList⁺ : ∀ {n} {xs : Vec A n} → All P xs → List.All P (toList xs)toList⁺ [] = []toList⁺ (px ∷ pxs) = px ∷ toList⁺ pxstoList⁻ : ∀ {n} {xs : Vec A n} → List.All P (toList xs) → All P xstoList⁻ {xs = []} [] = []toList⁻ {xs = x ∷ xs} (px ∷ pxs) = px ∷ toList⁻ pxs-------------------------------------------------------------------------- fromListmodule _ {P : Pred A p} wherefromList⁺ : ∀ {xs} → List.All P xs → All P (fromList xs)fromList⁺ [] = []fromList⁺ (px ∷ pxs) = px ∷ fromList⁺ pxsfromList⁻ : ∀ {xs} → All P (fromList xs) → List.All P xsfromList⁻ {[]} [] = []fromList⁻ {x ∷ xs} (px ∷ pxs) = px ∷ (fromList⁻ pxs)
-------------------------------------------------------------------------- The Agda standard library---- Inductive pointwise lifting of relations to vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Pointwise.Inductive whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (_×_; _,_; uncurry; <_,_>)open import Data.Vec.Base as Vec hiding ([_]; head; tail; map; lookup; uncons)open import Data.Vec.Relation.Unary.All using (All; []; _∷_)open import Level using (Level; _⊔_)open import Function.Base using (_∘_)open import Function.Bundles using (_⇔_; mk⇔)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid; DecSetoid)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Trans; Decidable; Reflexive; Sym)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary.Decidable using (yes; no; _×-dec_; map′)open import Relation.Unary using (Pred)privatevariablea b c d ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set bC : Set cD : Set d-------------------------------------------------------------------------- Definitioninfixr 5 _∷_data Pointwise {a b ℓ} {A : Set a} {B : Set b} (_∼_ : REL A B ℓ) :∀ {m n} (xs : Vec A m) (ys : Vec B n) → Set (a ⊔ b ⊔ ℓ)where[] : Pointwise _∼_ [] []_∷_ : ∀ {m n x y} {xs : Vec A m} {ys : Vec B n}(x∼y : x ∼ y) (xs∼ys : Pointwise _∼_ xs ys) →Pointwise _∼_ (x ∷ xs) (y ∷ ys)-------------------------------------------------------------------------- Propertieslength-equal : ∀ {m n} {_∼_ : REL A B ℓ} {xs : Vec A m} {ys : Vec B n} →Pointwise _∼_ xs ys → m ≡ nlength-equal [] = ≡.refllength-equal (_ ∷ xs∼ys) = ≡.cong suc (length-equal xs∼ys)-------------------------------------------------------------------------- Operationsmodule _ {_∼_ : REL A B ℓ} wherehead : ∀ {m n x y} {xs : Vec A m} {ys : Vec B n} →Pointwise _∼_ (x ∷ xs) (y ∷ ys) → x ∼ yhead (x∼y ∷ xs∼ys) = x∼ytail : ∀ {m n x y} {xs : Vec A m} {ys : Vec B n} →Pointwise _∼_ (x ∷ xs) (y ∷ ys) → Pointwise _∼_ xs ystail (x∼y ∷ xs∼ys) = xs∼ysuncons : ∀ {m n x y} {xs : Vec A m} {ys : Vec B n} →Pointwise _∼_ (x ∷ xs) (y ∷ ys) → x ∼ y × Pointwise _∼_ xs ysuncons = < head , tail >lookup : ∀ {n} {xs : Vec A n} {ys : Vec B n} → Pointwise _∼_ xs ys →∀ i → (Vec.lookup xs i) ∼ (Vec.lookup ys i)lookup (x∼y ∷ _) zero = x∼ylookup (_ ∷ xs∼ys) (suc i) = lookup xs∼ys imap : ∀ {ℓ₂} {_≈_ : REL A B ℓ₂} →_≈_ ⇒ _∼_ → ∀ {m n} → Pointwise _≈_ ⇒ Pointwise _∼_ {m} {n}map ∼₁⇒∼₂ [] = []map ∼₁⇒∼₂ (x∼y ∷ xs∼ys) = ∼₁⇒∼₂ x∼y ∷ map ∼₁⇒∼₂ xs∼ys-------------------------------------------------------------------------- Relational propertiesrefl : ∀ {_∼_ : Rel A ℓ} {n} →Reflexive _∼_ → Reflexive (Pointwise _∼_ {n})refl ∼-refl {[]} = []refl ∼-refl {x ∷ xs} = ∼-refl ∷ refl ∼-reflsym : ∀ {P : REL A B ℓ} {Q : REL B A ℓ} {m n} →Sym P Q → Sym (Pointwise P) (Pointwise Q {m} {n})sym sm [] = []sym sm (x∼y ∷ xs∼ys) = sm x∼y ∷ sym sm xs∼ystrans : ∀ {P : REL A B ℓ} {Q : REL B C ℓ} {R : REL A C ℓ} {m n o} →Trans P Q R →Trans (Pointwise P {m}) (Pointwise Q {n} {o}) (Pointwise R)trans trns [] [] = []trans trns (x∼y ∷ xs∼ys) (y∼z ∷ ys∼zs) =trns x∼y y∼z ∷ trans trns xs∼ys ys∼zsdecidable : ∀ {_∼_ : REL A B ℓ} →Decidable _∼_ → ∀ {m n} → Decidable (Pointwise _∼_ {m} {n})decidable dec [] [] = yes []decidable dec [] (y ∷ ys) = no λ()decidable dec (x ∷ xs) [] = no λ()decidable dec (x ∷ xs) (y ∷ ys) =map′ (uncurry _∷_) uncons (dec x y ×-dec decidable dec xs ys)-------------------------------------------------------------------------- Structuresmodule _ {_∼_ : Rel A ℓ} whereisEquivalence : IsEquivalence _∼_ → ∀ n →IsEquivalence (Pointwise _∼_ {n})isEquivalence equiv n = record{ refl = refl Eq.refl; sym = sym Eq.sym; trans = trans Eq.trans} where module Eq = IsEquivalence equivisDecEquivalence : IsDecEquivalence _∼_ → ∀ n →IsDecEquivalence (Pointwise _∼_ {n})isDecEquivalence decEquiv n = record{ isEquivalence = isEquivalence Eq.isEquivalence n; _≟_ = decidable Eq._≟_} where module Eq = IsDecEquivalence decEquiv-------------------------------------------------------------------------- Bundlessetoid : Setoid a ℓ → ℕ → Setoid a (a ⊔ ℓ)setoid S n = record{ isEquivalence = isEquivalence Eq.isEquivalence n} where module Eq = Setoid SdecSetoid : DecSetoid a ℓ → ℕ → DecSetoid a (a ⊔ ℓ)decSetoid S n = record{ isDecEquivalence = isDecEquivalence Eq.isDecEquivalence n} where module Eq = DecSetoid S-------------------------------------------------------------------------- mapmodule _ {_∼₁_ : REL A B ℓ₁} {_∼₂_ : REL C D ℓ₂}{f : A → C} {g : B → D}wheremap⁺ : (∀ {x y} → x ∼₁ y → f x ∼₂ g y) →∀ {m n xs ys} → Pointwise _∼₁_ {m} {n} xs ys →Pointwise _∼₂_ (Vec.map f xs) (Vec.map g ys)map⁺ ∼₁⇒∼₂ [] = []map⁺ ∼₁⇒∼₂ (x∼y ∷ xs∼ys) = ∼₁⇒∼₂ x∼y ∷ map⁺ ∼₁⇒∼₂ xs∼ys-------------------------------------------------------------------------- _++_module _ {_∼_ : REL A B ℓ} where++⁺ : ∀ {m n p q}{ws : Vec A m} {xs : Vec B p} {ys : Vec A n} {zs : Vec B q} →Pointwise _∼_ ws xs → Pointwise _∼_ ys zs →Pointwise _∼_ (ws ++ ys) (xs ++ zs)++⁺ [] ys∼zs = ys∼zs++⁺ (w∼x ∷ ws∼xs) ys∼zs = w∼x ∷ (++⁺ ws∼xs ys∼zs)++ˡ⁻ : ∀ {m n}(ws : Vec A m) (xs : Vec B m) {ys : Vec A n} {zs : Vec B n} →Pointwise _∼_ (ws ++ ys) (xs ++ zs) → Pointwise _∼_ ws xs++ˡ⁻ [] [] _ = []++ˡ⁻ (w ∷ ws) (x ∷ xs) (w∼x ∷ ps) = w∼x ∷ ++ˡ⁻ ws xs ps++ʳ⁻ : ∀ {m n}(ws : Vec A m) (xs : Vec B m) {ys : Vec A n} {zs : Vec B n} →Pointwise _∼_ (ws ++ ys) (xs ++ zs) → Pointwise _∼_ ys zs++ʳ⁻ [] [] ys∼zs = ys∼zs++ʳ⁻ (w ∷ ws) (x ∷ xs) (_ ∷ ps) = ++ʳ⁻ ws xs ps++⁻ : ∀ {m n}(ws : Vec A m) (xs : Vec B m) {ys : Vec A n} {zs : Vec B n} →Pointwise _∼_ (ws ++ ys) (xs ++ zs) →Pointwise _∼_ ws xs × Pointwise _∼_ ys zs++⁻ ws xs ps = ++ˡ⁻ ws xs ps , ++ʳ⁻ ws xs ps-------------------------------------------------------------------------- concatmodule _ {_∼_ : REL A B ℓ} whereconcat⁺ : ∀ {m n p q}{xss : Vec (Vec A m) n} {yss : Vec (Vec B p) q} →Pointwise (Pointwise _∼_) xss yss →Pointwise _∼_ (concat xss) (concat yss)concat⁺ [] = []concat⁺ (xs∼ys ∷ ps) = ++⁺ xs∼ys (concat⁺ ps)concat⁻ : ∀ {m n} (xss : Vec (Vec A m) n) (yss : Vec (Vec B m) n) →Pointwise _∼_ (concat xss) (concat yss) →Pointwise (Pointwise _∼_) xss yssconcat⁻ [] [] [] = []concat⁻ (xs ∷ xss) (ys ∷ yss) ps =++ˡ⁻ xs ys ps ∷ concat⁻ xss yss (++ʳ⁻ xs ys ps)-------------------------------------------------------------------------- tabulatemodule _ {_∼_ : REL A B ℓ} wheretabulate⁺ : ∀ {n} {f : Fin n → A} {g : Fin n → B} →(∀ i → f i ∼ g i) →Pointwise _∼_ (tabulate f) (tabulate g)tabulate⁺ {zero} f∼g = []tabulate⁺ {suc n} f∼g = f∼g zero ∷ tabulate⁺ (f∼g ∘ suc)tabulate⁻ : ∀ {n} {f : Fin n → A} {g : Fin n → B} →Pointwise _∼_ (tabulate f) (tabulate g) →(∀ i → f i ∼ g i)tabulate⁻ (f₀∼g₀ ∷ _) zero = f₀∼g₀tabulate⁻ (_ ∷ f∼g) (suc i) = tabulate⁻ f∼g i-------------------------------------------------------------------------- congmodule _ {_∼_ : Rel A ℓ} (refl : Reflexive _∼_) wherecong-[_]≔ : ∀ {n} i p {xs} {ys} →Pointwise _∼_ {n} xs ys →Pointwise _∼_ (xs [ i ]≔ p) (ys [ i ]≔ p)cong-[ zero ]≔ p (_ ∷ eqn) = refl ∷ eqncong-[ suc i ]≔ p (x∼y ∷ eqn) = x∼y ∷ cong-[ i ]≔ p eqn-------------------------------------------------------------------------- Degenerate pointwise relationsmodule _ {P : Pred A ℓ} wherePointwiseˡ⇒All : ∀ {m n} {xs : Vec A m} {ys : Vec B n} →Pointwise (λ x y → P x) xs ys → All P xsPointwiseˡ⇒All [] = []Pointwiseˡ⇒All (p ∷ ps) = p ∷ Pointwiseˡ⇒All psPointwiseʳ⇒All : ∀ {n} {xs : Vec B n} {ys : Vec A n} →Pointwise (λ x y → P y) xs ys → All P ysPointwiseʳ⇒All [] = []Pointwiseʳ⇒All (p ∷ ps) = p ∷ Pointwiseʳ⇒All psAll⇒Pointwiseˡ : ∀ {n} {xs : Vec A n} {ys : Vec B n} →All P xs → Pointwise (λ x y → P x) xs ysAll⇒Pointwiseˡ {ys = []} [] = []All⇒Pointwiseˡ {ys = _ ∷ _} (p ∷ ps) = p ∷ All⇒Pointwiseˡ psAll⇒Pointwiseʳ : ∀ {n} {xs : Vec B n} {ys : Vec A n} →All P ys → Pointwise (λ x y → P y) xs ysAll⇒Pointwiseʳ {xs = []} [] = []All⇒Pointwiseʳ {xs = _ ∷ _} (p ∷ ps) = p ∷ All⇒Pointwiseʳ ps-------------------------------------------------------------------------- Pointwise _≡_ is equivalent to _≡_Pointwise-≡⇒≡ : ∀ {n} {xs ys : Vec A n} → Pointwise _≡_ xs ys → xs ≡ ysPointwise-≡⇒≡ [] = ≡.reflPointwise-≡⇒≡ (≡.refl ∷ xs∼ys) = ≡.cong (_ ∷_) (Pointwise-≡⇒≡ xs∼ys)≡⇒Pointwise-≡ : ∀ {n} {xs ys : Vec A n} → xs ≡ ys → Pointwise _≡_ xs ys≡⇒Pointwise-≡ ≡.refl = refl ≡.reflPointwise-≡↔≡ : ∀ {n} {xs ys : Vec A n} → Pointwise _≡_ xs ys ⇔ xs ≡ ysPointwise-≡↔≡ = mk⇔ Pointwise-≡⇒≡ ≡⇒Pointwise-≡
-------------------------------------------------------------------------- The Agda standard library---- Extensional pointwise lifting of relations to vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Pointwise.Extensional whereopen import Data.Fin.Base using (zero; suc)open import Data.Vec.Base as Vec hiding ([_]; head; tail; map)open import Data.Vec.Relation.Binary.Pointwise.Inductive as Inductiveusing ([]; _∷_)renaming (Pointwise to IPointwise)open import Level using (_⊔_)open import Function.Base using (_∘_)open import Function.Bundles using (module Equivalence; _⇔_; mk⇔)open import Function.Properties.Equivalence using (⇔-setoid)open import Level using (Level; _⊔_; 0ℓ)open import Relation.Binary.Core using (Rel; REL; _⇒_; _=[_]⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitions using (Reflexive; Sym; Trans; Decidable)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Construct.Closure.Transitive as Plushiding (equivalent; map)open import Relation.Nullaryimport Relation.Nullary.Decidable as Decprivatevariablea b c ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitionrecord Pointwise {a b ℓ} {A : Set a} {B : Set b} (_∼_ : REL A B ℓ){n} (xs : Vec A n) (ys : Vec B n) : Set (a ⊔ b ⊔ ℓ)whereconstructor extfield app : ∀ i → lookup xs i ∼ lookup ys i-------------------------------------------------------------------------- Operationshead : ∀ {_∼_ : REL A B ℓ} {n x y xs} {ys : Vec B n} →Pointwise _∼_ (x ∷ xs) (y ∷ ys) → x ∼ yhead (ext app) = app zerotail : ∀ {_∼_ : REL A B ℓ} {n x y xs} {ys : Vec B n} →Pointwise _∼_ (x ∷ xs) (y ∷ ys) → Pointwise _∼_ xs ystail (ext app) = ext (app ∘ suc)map : ∀ {_∼_ _∼′_ : REL A B ℓ} {n} →_∼_ ⇒ _∼′_ → Pointwise _∼_ ⇒ Pointwise _∼′_ {n}map ∼⇒∼′ xs∼ys = ext (∼⇒∼′ ∘ Pointwise.app xs∼ys)gmap : ∀ {_∼_ : Rel A ℓ} {_∼′_ : Rel B ℓ} {f : A → B} {n} →_∼_ =[ f ]⇒ _∼′_ →Pointwise _∼_ =[ Vec.map {n = n} f ]⇒ Pointwise _∼′_gmap {_} ∼⇒∼′ {[]} {[]} xs∼ys = ext λ()gmap {_∼′_ = _∼′_} ∼⇒∼′ {x ∷ xs} {y ∷ ys} xs∼ys = ext λ{ zero → ∼⇒∼′ (head xs∼ys); (suc i) → Pointwise.app (gmap {_∼′_ = _∼′_} ∼⇒∼′ (tail xs∼ys)) i}-------------------------------------------------------------------------- The inductive and extensional definitions are equivalent.module _ {_∼_ : REL A B ℓ} whereextensional⇒inductive : ∀ {n} {xs : Vec A n} {ys : Vec B n} →Pointwise _∼_ xs ys → IPointwise _∼_ xs ysextensional⇒inductive {xs = []} {[]} xs∼ys = []extensional⇒inductive {xs = x ∷ xs} {y ∷ ys} xs∼ys =(head xs∼ys) ∷ extensional⇒inductive (tail xs∼ys)inductive⇒extensional : ∀ {n} {xs : Vec A n} {ys : Vec B n} →IPointwise _∼_ xs ys → Pointwise _∼_ xs ysinductive⇒extensional [] = ext λ()inductive⇒extensional (x∼y ∷ xs∼ys) = ext λ{ zero → x∼y; (suc i) → Pointwise.app (inductive⇒extensional xs∼ys) i}equivalent : ∀ {n} {xs : Vec A n} {ys : Vec B n} →Pointwise _∼_ xs ys ⇔ IPointwise _∼_ xs ysequivalent = mk⇔ extensional⇒inductive inductive⇒extensional-------------------------------------------------------------------------- Relational propertiesrefl : ∀ {_∼_ : Rel A ℓ} {n} →Reflexive _∼_ → Reflexive (Pointwise _∼_ {n = n})refl ∼-rfl = ext (λ _ → ∼-rfl)sym : ∀ {P : REL A B ℓ} {Q : REL B A ℓ} {n} →Sym P Q → Sym (Pointwise P) (Pointwise Q {n = n})sym sm xs∼ys = ext λ i → sm (Pointwise.app xs∼ys i)trans : ∀ {P : REL A B ℓ} {Q : REL B C ℓ} {R : REL A C ℓ} {n} →Trans P Q R →Trans (Pointwise P) (Pointwise Q) (Pointwise R {n = n})trans trns xs∼ys ys∼zs = ext λ i →trns (Pointwise.app xs∼ys i) (Pointwise.app ys∼zs i)decidable : ∀ {_∼_ : REL A B ℓ} →Decidable _∼_ → ∀ {n} → Decidable (Pointwise _∼_ {n = n})decidable dec xs ys = Dec.map(Setoid.sym (⇔-setoid _) equivalent)(Inductive.decidable dec xs ys)isEquivalence : ∀ {_∼_ : Rel A ℓ} {n} →IsEquivalence _∼_ → IsEquivalence (Pointwise _∼_ {n = n})isEquivalence equiv = record{ refl = refl Eq.refl; sym = sym Eq.sym; trans = trans Eq.trans} where module Eq = IsEquivalence equivisDecEquivalence : ∀ {_∼_ : Rel A ℓ} {n} →IsDecEquivalence _∼_ →IsDecEquivalence (Pointwise _∼_ {n = n})isDecEquivalence decEquiv = record{ isEquivalence = isEquivalence DecEq.isEquivalence; _≟_ = decidable DecEq._≟_} where module DecEq = IsDecEquivalence decEquiv-------------------------------------------------------------------------- Pointwise _≡_ is equivalent to _≡_.Pointwise-≡⇒≡ : ∀ {n} {xs ys : Vec A n} → Pointwise _≡_ xs ys → xs ≡ ysPointwise-≡⇒≡ {xs = []} {[]} (ext app) = ≡.reflPointwise-≡⇒≡ {xs = x ∷ xs} {y ∷ ys} xs∼ys =≡.cong₂ _∷_ (head xs∼ys) (Pointwise-≡⇒≡ (tail xs∼ys))≡⇒Pointwise-≡ : ∀ {n} {xs ys : Vec A n} → xs ≡ ys → Pointwise _≡_ xs ys≡⇒Pointwise-≡ ≡.refl = refl ≡.reflPointwise-≡↔≡ : ∀ {n} {xs ys : Vec A n} → Pointwise _≡_ xs ys ⇔ xs ≡ ysPointwise-≡↔≡ {ℓ} {A} = mk⇔ Pointwise-≡⇒≡ ≡⇒Pointwise-≡-------------------------------------------------------------------------- Pointwise and Plus commute when the underlying relation is-- reflexive.module _ {_∼_ : Rel A ℓ} where⁺∙⇒∙⁺ : ∀ {n} {xs ys : Vec A n} →Plus (Pointwise _∼_) xs ys → Pointwise (Plus _∼_) xs ys⁺∙⇒∙⁺ [ ρ≈ρ′ ] = ext (λ x → [ Pointwise.app ρ≈ρ′ x ])⁺∙⇒∙⁺ (ρ ∼⁺⟨ ρ≈ρ′ ⟩ ρ′≈ρ″) = ext (λ x →_ ∼⁺⟨ Pointwise.app (⁺∙⇒∙⁺ ρ≈ρ′ ) x ⟩Pointwise.app (⁺∙⇒∙⁺ ρ′≈ρ″) x)∙⁺⇒⁺∙ : ∀ {n} {xs ys : Vec A n} → Reflexive _∼_ →Pointwise (Plus _∼_) xs ys → Plus (Pointwise _∼_) xs ys∙⁺⇒⁺∙ rfl =Plus.map (Equivalence.from equivalent) ∘helper ∘Equivalence.to equivalentwherehelper : ∀ {n} {xs ys : Vec A n} →IPointwise (Plus _∼_) xs ys → Plus (IPointwise _∼_) xs yshelper [] = [ [] ]helper (_∷_ {x = x} {y = y} {xs = xs} {ys = ys} x∼y xs∼ys) =x ∷ xs ∼⁺⟨ Plus.map (_∷ Inductive.refl rfl) x∼y ⟩y ∷ xs ∼⁺⟨ Plus.map (rfl ∷_) (helper xs∼ys) ⟩∎y ∷ ys ∎-- ∙⁺⇒⁺∙ cannot be defined if the requirement of reflexivity-- is dropped.privatemodule Counterexample wheredata D : Set wherei j x y z : Ddata _R_ : Rel D 0ℓ whereiRj : i R jxRy : x R yyRz : y R zxR⁺z : x [ _R_ ]⁺ zxR⁺z =x ∼⁺⟨ [ xRy ] ⟩y ∼⁺⟨ [ yRz ] ⟩∎z ∎ix : Vec D 2ix = i ∷ x ∷ []jz : Vec D 2jz = j ∷ z ∷ []ix∙⁺jz : IPointwise (Plus _R_) ix jzix∙⁺jz = [ iRj ] ∷ xR⁺z ∷ []¬ix⁺∙jz : ¬ TransClosure (IPointwise _R_) ix jz¬ix⁺∙jz [ iRj ∷ () ∷ [] ]¬ix⁺∙jz ((iRj ∷ xRy ∷ []) ∷ [ () ∷ yRz ∷ [] ])¬ix⁺∙jz ((iRj ∷ xRy ∷ []) ∷ (() ∷ yRz ∷ []) ∷ _)counterexample :¬ (∀ {n} {xs ys : Vec D n} →Pointwise (Plus _R_) xs ys →Plus (Pointwise _R_) xs ys)counterexample ∙⁺⇒⁺∙ =¬ix⁺∙jz (Equivalence.to Plus.equivalent(Plus.map (Equivalence.to equivalent)(∙⁺⇒⁺∙ (Equivalence.from equivalent ix∙⁺jz))))
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of lists of same-length vectors-------------------------------------------------------------------------- The definitions of lexicographic ordering used here are suitable if-- the argument order is a strict partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Lex.Strict whereopen import Data.Empty using (⊥; ⊥-elim)open import Data.Unit.Base using (⊤; tt)open import Data.Unit.Properties using (⊤-irrelevant)open import Data.Nat.Base using (ℕ; suc)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Lex.Strictopen import Data.Sum.Base using (inj₁; inj₂)open import Data.Vec.Base using (Vec; []; _∷_; uncons)open import Data.Vec.Relation.Binary.Pointwise.Inductive as Pointwiseusing (Pointwise; []; _∷_; head; tail)open import Function.Base using (id; _on_; _∘_)open import Induction.WellFoundedopen import Relation.Nullary using (yes; no; ¬_)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundlesusing (Poset; StrictPartialOrder; DecPoset; DecStrictPartialOrder; DecTotalOrder; StrictTotalOrder; Preorder; TotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPartialOrder; IsStrictPartialOrder; IsDecPartialOrder; IsDecStrictPartialOrder; IsDecTotalOrder; IsStrictTotalOrder; IsPreorder; IsTotalOrder; IsPartialEquivalence)open import Relation.Binary.Definitionsusing (Irreflexive; _Respects₂_; _Respectsˡ_; _Respectsʳ_; Antisymmetric; Asymmetric; Symmetric; Trans; Decidable; Total; Trichotomous; Transitive; Irrelevant; tri≈; tri>; tri<)open import Relation.Binary.Consequencesopen import Relation.Binary.Construct.On as On using (wellFounded)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Level using (Level; _⊔_)privatevariablea ℓ₁ ℓ₂ : LevelA : Set a-------------------------------------------------------------------------- Re-exports------------------------------------------------------------------------open import Data.Vec.Relation.Binary.Lex.Core as Core publicusing (base; this; next; ≰-this; ≰-next)-------------------------------------------------------------------------- Definitions------------------------------------------------------------------------module _ {A : Set a} (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) whereLex-< : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-< = Core.Lex {A = A} ⊥ _≈_ _≺_Lex-≤ : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-≤ = Core.Lex {A = A} ⊤ _≈_ _≺_-------------------------------------------------------------------------- Properties of Lex-<------------------------------------------------------------------------module _ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≺_xs≮[] : ∀ {n} {xs : Vec A n} → ¬ xs < []xs≮[] (base ())¬[]<[] : ¬ [] < []¬[]<[] = xs≮[]module _ (≺-irrefl : Irreflexive _≈_ _≺_) where<-irrefl : ∀ {m n} → Irreflexive (_≋_ {m} {n}) (_<_ {m} {n})<-irrefl [] (base ())<-irrefl (x≈y ∷ xs≋ys) (this x≺y m≡n) = ≺-irrefl x≈y x≺y<-irrefl (x≈y ∷ xs≋ys) (next _ xs<ys) = <-irrefl xs≋ys xs<ysmodule _ (≈-sym : Symmetric _≈_) (≺-resp-≈ : _≺_ Respects₂ _≈_) (≺-asym : Asymmetric _≺_) where<-asym : ∀ {n} → Asymmetric (_<_ {n} {n})<-asym (this x≺y m≡n) (this y≺x n≡m) = ≺-asym x≺y y≺x<-asym (this x≺y m≡n) (next y≈x ys<xs) = asym⇒irr ≺-resp-≈ ≈-sym ≺-asym (≈-sym y≈x) x≺y<-asym (next x≈y xs<ys) (this y≺x n≡m) = asym⇒irr ≺-resp-≈ ≈-sym ≺-asym (≈-sym x≈y) y≺x<-asym (next x≈y xs<ys) (next y≈x ys<xs) = <-asym xs<ys ys<xs<-antisym : Symmetric _≈_ → Irreflexive _≈_ _≺_ → Asymmetric _≺_ →∀ {n} → Antisymmetric (_≋_ {n} {n}) _<_<-antisym = Core.antisym<-trans : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ →∀ {m n o} → Trans (_<_ {m} {n}) (_<_ {n} {o}) _<_<-trans = Core.transitivemodule _ (≈-sym : Symmetric _≈_) (≺-cmp : Trichotomous _≈_ _≺_) where<-cmp : ∀ {n} → Trichotomous _≋_ (_<_ {n})<-cmp [] [] = tri≈ ¬[]<[] [] ¬[]<[]<-cmp (x ∷ xs) (y ∷ ys) with ≺-cmp x y... | tri< x≺y x≉y x⊁y = tri< (this x≺y refl) (x≉y ∘ head) (≰-this (x≉y ∘ ≈-sym) x⊁y)... | tri> x⊀y x≉y x≻y = tri> (≰-this x≉y x⊀y) (x≉y ∘ head) (this x≻y refl)... | tri≈ x⊀y x≈y x⊁y with <-cmp xs ys... | tri< xs<ys xs≋̸ys xs≯ys = tri< (next x≈y xs<ys) (xs≋̸ys ∘ tail) (≰-next x⊁y xs≯ys)... | tri≈ xs≮ys xs≋ys xs≯ys = tri≈ (≰-next x⊀y xs≮ys) (x≈y ∷ xs≋ys) (≰-next x⊁y xs≯ys)... | tri> xs≮ys xs≋̸ys xs>ys = tri> (≰-next x⊀y xs≮ys) (xs≋̸ys ∘ tail) (next (≈-sym x≈y) xs>ys)<-decidable : Decidable _≈_ → Decidable _≺_ →∀ {m n} → Decidable (_<_ {m} {n})<-decidable = Core.decidable (no id)<-respectsˡ : IsPartialEquivalence _≈_ → _≺_ Respectsˡ _≈_ →∀ {m n} → _Respectsˡ_ (_<_ {m} {n}) _≋_<-respectsˡ = Core.respectsˡ<-respectsʳ : IsPartialEquivalence _≈_ → _≺_ Respectsʳ _≈_ →∀ {m n} → _Respectsʳ_ (_<_ {m} {n}) _≋_<-respectsʳ = Core.respectsʳ<-respects₂ : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ →∀ {n} → _Respects₂_ (_<_ {n} {n}) _≋_<-respects₂ = Core.respects₂<-irrelevant : Irrelevant _≈_ → Irrelevant _≺_ → Irreflexive _≈_ _≺_ →∀ {m n} → Irrelevant (_<_ {m} {n})<-irrelevant = Core.irrelevant (λ ())module _ (≈-trans : Transitive _≈_) (≺-respʳ : _≺_ Respectsʳ _≈_ ) (≺-wf : WellFounded _≺_)where<-wellFounded : ∀ {n} → WellFounded (_<_ {n})<-wellFounded {0} [] = acc λ ys<[] → ⊥-elim (xs≮[] ys<[])<-wellFounded {suc n} xs = Subrelation.wellFounded <⇒uncons-Lex uncons-Lex-wellFounded xswhere<⇒uncons-Lex : {xs ys : Vec A (suc n)} → xs < ys → (×-Lex _≈_ _≺_ _<_ on uncons) xs ys<⇒uncons-Lex {x ∷ xs} {y ∷ ys} (this x<y _) = inj₁ x<y<⇒uncons-Lex {x ∷ xs} {y ∷ ys} (next x≈y xs<ys) = inj₂ (x≈y , xs<ys)uncons-Lex-wellFounded : WellFounded (×-Lex _≈_ _≺_ _<_ on uncons)uncons-Lex-wellFounded = On.wellFounded uncons (×-wellFounded' ≈-trans ≺-respʳ ≺-wf <-wellFounded)-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsStrictPartialOrder _≈_ _≺_ →∀ {n} → IsStrictPartialOrder (_≋_ {n} {n}) _<_<-isStrictPartialOrder ≺-isStrictPartialOrder {n} = record{ isEquivalence = Pointwise.isEquivalence O.isEquivalence n; irrefl = <-irrefl O.irrefl; trans = <-trans O.Eq.isPartialEquivalence O.<-resp-≈ O.trans; <-resp-≈ = <-respects₂ O.Eq.isPartialEquivalence O.<-resp-≈} where module O = IsStrictPartialOrder ≺-isStrictPartialOrder<-isDecStrictPartialOrder : IsDecStrictPartialOrder _≈_ _≺_ →∀ {n} → IsDecStrictPartialOrder (_≋_ {n} {n}) _<_<-isDecStrictPartialOrder ≺-isDecStrictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder O.isStrictPartialOrder; _≟_ = Pointwise.decidable O._≟_; _<?_ = <-decidable O._≟_ O._<?_} where module O = IsDecStrictPartialOrder ≺-isDecStrictPartialOrder<-isStrictTotalOrder : IsStrictTotalOrder _≈_ _≺_ →∀ {n} → IsStrictTotalOrder (_≋_ {n} {n}) _<_<-isStrictTotalOrder ≺-isStrictTotalOrder {n} = record{ isStrictPartialOrder = <-isStrictPartialOrder O.isStrictPartialOrder; compare = <-cmp O.Eq.sym O.compare} where module O = IsStrictTotalOrder ≺-isStrictTotalOrder-------------------------------------------------------------------------- Bundles for Lex-<<-strictPartialOrder : StrictPartialOrder a ℓ₁ ℓ₂ → ℕ → StrictPartialOrder _ _ _<-strictPartialOrder ≺-spo n = record{ isStrictPartialOrder = <-isStrictPartialOrder isStrictPartialOrder {n = n}} where open StrictPartialOrder ≺-spo<-decStrictPartialOrder : DecStrictPartialOrder a ℓ₁ ℓ₂ → ℕ → DecStrictPartialOrder _ _ _<-decStrictPartialOrder ≺-dspo n = record{ isDecStrictPartialOrder = <-isDecStrictPartialOrder isDecStrictPartialOrder {n = n}} where open DecStrictPartialOrder ≺-dspo<-strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂ → ℕ → StrictTotalOrder _ _ _<-strictTotalOrder ≺-sto n = record{ isStrictTotalOrder = <-isStrictTotalOrder isStrictTotalOrder {n = n}} where open StrictTotalOrder ≺-sto-------------------------------------------------------------------------- Properties of Lex-≤------------------------------------------------------------------------module _ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≺__≤_ = Lex-≤ _≈_ _≺_<⇒≤ : ∀ {m n} {xs : Vec A m} {ys : Vec A n} → xs < ys → xs ≤ ys<⇒≤ = Core.map-P ⊥-elim≤-refl : ∀ {m n} → (_≋_ {m} {n}) ⇒ _≤_≤-refl [] = base tt≤-refl (x≈y ∷ xs≋ys) = next x≈y (≤-refl xs≋ys)≤-antisym : Symmetric _≈_ → Irreflexive _≈_ _≺_ → Asymmetric _≺_ →∀ {n} → Antisymmetric (_≋_ {n} {n}) _≤_≤-antisym = Core.antisym≤-resp₂ : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ →∀ {n} → _Respects₂_ (_≤_ {n} {n}) _≋_≤-resp₂ = Core.respects₂≤-trans : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ →∀ {m n o} → Trans (_≤_ {m} {n}) (_≤_ {n} {o}) _≤_≤-trans = Core.transitive<-transʳ : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ →∀ {m n o} → Trans (_≤_ {m} {n}) (_<_ {n} {o}) _<_<-transʳ ≈-equiv ≺-resp-≈ ≺-trans xs≤ys ys<zs = Core.map-P proj₂(Core.transitive′ ≈-equiv ≺-resp-≈ ≺-trans xs≤ys ys<zs)<-transˡ : IsPartialEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ →∀ {m n o} → Trans (_<_ {m} {n}) (_≤_ {n} {o}) _<_<-transˡ ≈-equiv ≺-resp-≈ ≺-trans xs<ys ys≤zs = Core.map-P proj₁(Core.transitive′ ≈-equiv ≺-resp-≈ ≺-trans xs<ys ys≤zs)-- Note that trichotomy is an unnecessarily strong precondition for-- the following lemma.module _ (≈-sym : Symmetric _≈_) (≺-cmp : Trichotomous _≈_ _≺_) where≤-total : ∀ {n} → Total (_≤_ {n} {n})≤-total [] [] = inj₁ (base tt)≤-total (x ∷ xs) (y ∷ ys) with ≺-cmp x y... | tri< x≺y _ _ = inj₁ (this x≺y refl)... | tri> _ _ x≻y = inj₂ (this x≻y refl)... | tri≈ _ x≈y _ with ≤-total xs ys... | inj₁ xs<ys = inj₁ (next x≈y xs<ys)... | inj₂ xs>ys = inj₂ (next (≈-sym x≈y) xs>ys)≤-dec : Decidable _≈_ → Decidable _≺_ →∀ {m n} → Decidable (_≤_ {m} {n})≤-dec = Core.decidable (yes tt)≤-irrelevant : Irrelevant _≈_ → Irrelevant _≺_ → Irreflexive _≈_ _≺_ →∀ {m n} → Irrelevant (_≤_ {m} {n})≤-irrelevant = Core.irrelevant ⊤-irrelevant-------------------------------------------------------------------------- Structures≤-isPreorder : IsEquivalence _≈_ → Transitive _≺_ → _≺_ Respects₂ _≈_ →∀ {n} → IsPreorder (_≋_ {n} {n}) _≤_≤-isPreorder ≈-equiv ≺-trans ≺-resp-≈ {n} = record{ isEquivalence = Pointwise.isEquivalence ≈-equiv n; reflexive = ≤-refl; trans = ≤-trans (IsEquivalence.isPartialEquivalence ≈-equiv) ≺-resp-≈ ≺-trans}≤-isPartialOrder : IsStrictPartialOrder _≈_ _≺_ →∀ {n} → IsPartialOrder (_≋_ {n} {n}) _≤_≤-isPartialOrder ≺-isStrictPartialOrder = record{ isPreorder = ≤-isPreorder isEquivalence trans <-resp-≈; antisym = ≤-antisym Eq.sym irrefl asym} where open IsStrictPartialOrder ≺-isStrictPartialOrder≤-isDecPartialOrder : IsDecStrictPartialOrder _≈_ _≺_ →∀ {n} → IsDecPartialOrder (_≋_ {n} {n}) _≤_≤-isDecPartialOrder ≺-isDecStrictPartialOrder = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder; _≟_ = Pointwise.decidable _≟_; _≤?_ = ≤-dec _≟_ _<?_} where open IsDecStrictPartialOrder ≺-isDecStrictPartialOrder≤-isTotalOrder : IsStrictTotalOrder _≈_ _≺_ →∀ {n} → IsTotalOrder (_≋_ {n} {n}) _≤_≤-isTotalOrder ≺-isStrictTotalOrder = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder; total = ≤-total Eq.sym compare} where open IsStrictTotalOrder ≺-isStrictTotalOrder≤-isDecTotalOrder : IsStrictTotalOrder _≈_ _≺_ →∀ {n} → IsDecTotalOrder (_≋_ {n} {n}) _≤_≤-isDecTotalOrder ≺-isStrictTotalOrder = record{ isTotalOrder = ≤-isTotalOrder ≺-isStrictTotalOrder; _≟_ = Pointwise.decidable _≟_; _≤?_ = ≤-dec _≟_ _<?_} where open IsStrictTotalOrder ≺-isStrictTotalOrder-------------------------------------------------------------------------- Bundles≤-preorder : Preorder a ℓ₁ ℓ₂ → ℕ → Preorder _ _ _≤-preorder ≺-pre n = record{ isPreorder = ≤-isPreorder isEquivalence trans ∼-resp-≈ {n = n}} where open Preorder ≺-pre≤-partialOrder : StrictPartialOrder a ℓ₁ ℓ₂ → ℕ → Poset _ _ _≤-partialOrder ≺-spo n = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder {n = n}} where open StrictPartialOrder ≺-spo≤-decPartialOrder : DecStrictPartialOrder a ℓ₁ ℓ₂ → ℕ → DecPoset _ _ _≤-decPartialOrder ≺-spo n = record{ isDecPartialOrder = ≤-isDecPartialOrder isDecStrictPartialOrder {n = n}} where open DecStrictPartialOrder ≺-spo≤-totalOrder : StrictTotalOrder a ℓ₁ ℓ₂ → ℕ → TotalOrder _ _ _≤-totalOrder ≺-sto n = record{ isTotalOrder = ≤-isTotalOrder isStrictTotalOrder {n = n}} where open StrictTotalOrder ≺-sto≤-decTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂ → ℕ → DecTotalOrder _ _ _≤-decTotalOrder ≺-sto n = record{ isDecTotalOrder = ≤-isDecTotalOrder isStrictTotalOrder {n = n}} where open StrictTotalOrder ≺-sto-------------------------------------------------------------------------- Equational Reasoning------------------------------------------------------------------------module ≤-Reasoning{_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂}(≺-isStrictPartialOrder : IsStrictPartialOrder _≈_ _≺_)(n : ℕ)whereopen IsStrictPartialOrder ≺-isStrictPartialOrderopen import Relation.Binary.Reasoning.Base.Triple(≤-isPreorder isEquivalence trans <-resp-≈)(<-asym Eq.sym <-resp-≈ asym)(<-trans Eq.isPartialEquivalence <-resp-≈ trans)(<-respects₂ Eq.isPartialEquivalence <-resp-≈)(<⇒≤ {m = n})(<-transˡ Eq.isPartialEquivalence <-resp-≈ trans)(<-transʳ Eq.isPartialEquivalence <-resp-≈ trans)public
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of same-length vector-------------------------------------------------------------------------- The definitions of lexicographic orderings used here is suitable if-- the argument order is a (non-strict) partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Lex.NonStrict whereopen import Data.Emptyopen import Data.Unit.Base using (⊤; tt)open import Data.Product.Base using (proj₁; proj₂)open import Data.Nat.Base using (ℕ)open import Data.Vec.Base using (Vec; []; _∷_)import Data.Vec.Relation.Binary.Lex.Strict as Strictopen import Data.Vec.Relation.Binary.Pointwise.Inductive as Pointwiseusing (Pointwise; []; _∷_; head; tail)open import Function.Base using (id)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundlesusing (Poset; StrictPartialOrder; DecPoset; DecStrictPartialOrder; DecTotalOrder; StrictTotalOrder; Preorder; TotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPartialOrder; IsStrictPartialOrder; IsDecPartialOrder; IsDecStrictPartialOrder; IsDecTotalOrder; IsStrictTotalOrder; IsPreorder; IsTotalOrder)open import Relation.Binary.Definitionsusing (Irreflexive; _Respects₂_; Antisymmetric; Asymmetric; Symmetric; Trans; Decidable; Total; Trichotomous)import Relation.Binary.Construct.NonStrictToStrict as Convopen import Relation.Nullary hiding (Irrelevant)privatevariablea ℓ₁ ℓ₂ : LevelA : Set a-------------------------------------------------------------------------- Publicly re-export definitions from Core------------------------------------------------------------------------open import Data.Vec.Relation.Binary.Lex.Core as Core publicusing (base; this; next; ≰-this; ≰-next)-------------------------------------------------------------------------- Definitions------------------------------------------------------------------------module _ {A : Set a} (_≈_ : Rel A ℓ₁) (_≼_ : Rel A ℓ₂) whereLex-< : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-< = Core.Lex {A = A} ⊥ _≈_ (Conv._<_ _≈_ _≼_)Lex-≤ : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-≤ = Core.Lex {A = A} ⊤ _≈_ (Conv._<_ _≈_ _≼_)-------------------------------------------------------------------------- Properties of Lex-<------------------------------------------------------------------------module _ {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≼_<-irrefl : ∀ {m n} → Irreflexive (_≋_ {m} {n}) _<_<-irrefl = Strict.<-irrefl (Conv.<-irrefl _≈_ _≼_)<-asym : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ → Antisymmetric _≈_ _≼_ →∀ {n} → Asymmetric (_<_ {n} {n})<-asym ≈-equiv ≼-resp-≈ ≼-antisym = Strict.<-asym sym(Conv.<-resp-≈ _ _ ≈-equiv ≼-resp-≈)(Conv.<-asym _≈_ _ ≼-antisym)where open IsEquivalence ≈-equiv<-antisym : Symmetric _≈_ → Antisymmetric _≈_ _≼_ →∀ {n} → Antisymmetric (_≋_ {n} {n}) _<_<-antisym ≈-sym ≼-antisym = Core.antisym ≈-sym(Conv.<-irrefl _≈_ _≼_)(Conv.<-asym _≈_ _≼_ ≼-antisym)<-trans : IsPartialOrder _≈_ _≼_ →∀ {m n o} → Trans (_<_ {m} {n}) (_<_ {n} {o}) _<_<-trans ≼-isPartialOrder = Core.transitive Eq.isPartialEquivalence(Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)(Conv.<-trans _ _ ≼-isPartialOrder)where open IsPartialOrder ≼-isPartialOrder<-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ →∀ {n} → _Respects₂_ (_<_ {n} {n}) _≋_<-resp₂ ≈-equiv ≼-resp-≈ = Core.respects₂(IsEquivalence.isPartialEquivalence ≈-equiv)(Conv.<-resp-≈ _ _ ≈-equiv ≼-resp-≈)<-cmp : Symmetric _≈_ → Decidable _≈_ → Antisymmetric _≈_ _≼_ → Total _≼_ →∀ {n} → Trichotomous (_≋_ {n} {n}) _<_<-cmp ≈-sym _≟_ ≼-antisym ≼-total = Strict.<-cmp ≈-sym(Conv.<-trichotomous _ _ ≈-sym _≟_ ≼-antisym ≼-total)<-dec : Decidable _≈_ → Decidable _≼_ → ∀ {m n} → Decidable (_<_ {m} {n})<-dec _≟_ _≼?_ = Core.decidable (no id) _≟_(Conv.<-decidable _ _ _≟_ _≼?_)-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsPartialOrder _≈_ _≼_ →∀ {n} → IsStrictPartialOrder (_≋_ {n} {n}) _<_<-isStrictPartialOrder ≼-isPartialOrder {n} = Strict.<-isStrictPartialOrder(Conv.<-isStrictPartialOrder _ _ ≼-isPartialOrder)<-isDecStrictPartialOrder : IsDecPartialOrder _≈_ _≼_ →∀ {n} → IsDecStrictPartialOrder (_≋_ {n} {n}) _<_<-isDecStrictPartialOrder ≼-isDecPartialOrder {n} = Strict.<-isDecStrictPartialOrder(Conv.<-isDecStrictPartialOrder _ _ ≼-isDecPartialOrder)<-isStrictTotalOrder : IsDecTotalOrder _≈_ _≼_ →∀ {n} → IsStrictTotalOrder (_≋_ {n} {n}) _<_<-isStrictTotalOrder ≼-isDecTotalOrder {n} = Strict.<-isStrictTotalOrder(Conv.<-isStrictTotalOrder₂ _ _ ≼-isDecTotalOrder)-------------------------------------------------------------------------- Bundles<-strictPartialOrder : Poset a ℓ₁ ℓ₂ → ℕ → StrictPartialOrder _ _ _<-strictPartialOrder ≼-po n = record{ isStrictPartialOrder = <-isStrictPartialOrder isPartialOrder {n = n}} where open Poset ≼-po<-decStrictPartialOrder : DecPoset a ℓ₁ ℓ₂ → ℕ → DecStrictPartialOrder _ _ _<-decStrictPartialOrder ≼-dpo n = record{ isDecStrictPartialOrder = <-isDecStrictPartialOrder isDecPartialOrder {n = n}} where open DecPoset ≼-dpo<-strictTotalOrder : DecTotalOrder a ℓ₁ ℓ₂ → ℕ → StrictTotalOrder _ _ _<-strictTotalOrder ≼-dto n = record{ isStrictTotalOrder = <-isStrictTotalOrder isDecTotalOrder {n = n}} where open DecTotalOrder ≼-dto-------------------------------------------------------------------------- Properties of Lex-≤------------------------------------------------------------------------module _ {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≼__≤_ = Lex-≤ _≈_ _≼_<⇒≤ : ∀ {m n} {xs : Vec A m} {ys : Vec A n} → xs < ys → xs ≤ ys<⇒≤ = Core.map-P ⊥-elim≤-refl : ∀ {m n} → (_≋_ {m} {n}) ⇒ _≤_≤-refl = Strict.≤-refl≤-antisym : Symmetric _≈_ → Antisymmetric _≈_ _≼_ →∀ {n} → Antisymmetric (_≋_ {n} {n}) _≤_≤-antisym ≈-sym ≼-antisym = Core.antisym ≈-sym(Conv.<-irrefl _≈_ _≼_)(Conv.<-asym _ _≼_ ≼-antisym)privatetrans : IsPartialOrder _≈_ _≼_ → ∀ {P₁ P₂} {m n o} →Trans (Core.Lex P₁ _≈_ (Conv._<_ _≈_ _≼_) {m} {n}) (Core.Lex P₂ _≈_ (Conv._<_ _≈_ _≼_) {n} {o}) _trans ≼-po = Core.transitive′(IsEquivalence.isPartialEquivalence isEquivalence)(Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)(Conv.<-trans _ _≼_ ≼-po)where open IsPartialOrder ≼-po≤-trans : IsPartialOrder _≈_ _≼_ → ∀ {m n o} → Trans (_≤_ {m} {n}) (_≤_ {n} {o}) _≤_≤-trans ≼-po xs≤ys ys≤zs = Core.map-P proj₁ (trans ≼-po xs≤ys ys≤zs)<-transʳ : IsPartialOrder _≈_ _≼_ → ∀ {m n o} → Trans (_≤_ {m} {n}) (_<_ {n} {o}) _<_<-transʳ ≼-po xs≤ys ys<zs = Core.map-P proj₂ (trans ≼-po xs≤ys ys<zs)<-transˡ : IsPartialOrder _≈_ _≼_ → ∀ {m n o} → Trans (_<_ {m} {n}) (_≤_ {n} {o}) _<_<-transˡ ≼-po xs<ys ys≤zs = Core.map-P proj₁ (trans ≼-po xs<ys ys≤zs)≤-total : Symmetric _≈_ → Decidable _≈_ → Antisymmetric _≈_ _≼_ → Total _≼_ →∀ {n} → Total (_≤_ {n})≤-total ≈-sym _≟_ ≼-antisym ≼-total = Strict.≤-total ≈-sym(Conv.<-trichotomous _ _ ≈-sym _≟_ ≼-antisym ≼-total)≤-dec : Decidable _≈_ → Decidable _≼_ →∀ {m n} → Decidable (_≤_ {m} {n})≤-dec _≟_ _≼?_ = Core.decidable (yes tt) _≟_(Conv.<-decidable _ _ _≟_ _≼?_)≤-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ →∀ {n} → _Respects₂_ (_≤_ {n} {n}) _≋_≤-resp₂ ≈-equiv ≼-resp-≈ = Core.respects₂(IsEquivalence.isPartialEquivalence ≈-equiv)(Conv.<-resp-≈ _ _ ≈-equiv ≼-resp-≈)-------------------------------------------------------------------------- Structures≤-isPreorder : IsPartialOrder _≈_ _≼_ →∀ {n} → IsPreorder (_≋_ {n} {n}) _≤_≤-isPreorder ≼-po = Strict.≤-isPreorder isEquivalence (Conv.<-trans _ _ ≼-po) (Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)where open IsPartialOrder ≼-po≤-isPartialOrder : IsPartialOrder _≈_ _≼_ →∀ {n} → IsPartialOrder (_≋_ {n} {n}) _≤_≤-isPartialOrder ≼-po = Strict.≤-isPartialOrder (Conv.<-isStrictPartialOrder _ _ ≼-po)≤-isDecPartialOrder : IsDecPartialOrder _≈_ _≼_ →∀ {n} → IsDecPartialOrder (_≋_ {n} {n}) _≤_≤-isDecPartialOrder ≼-dpo = Strict.≤-isDecPartialOrder (Conv.<-isDecStrictPartialOrder _ _ ≼-dpo)≤-isTotalOrder : Decidable _≈_ → IsTotalOrder _≈_ _≼_ →∀ {n} → IsTotalOrder (_≋_ {n} {n}) _≤_≤-isTotalOrder _≟_ ≼-isTotalOrder = Strict.≤-isTotalOrder (Conv.<-isStrictTotalOrder₁ _ _ _≟_ ≼-isTotalOrder)≤-isDecTotalOrder : IsDecTotalOrder _≈_ _≼_ →∀ {n} → IsDecTotalOrder (_≋_ {n} {n}) _≤_≤-isDecTotalOrder ≼-isDecTotalOrder = Strict.≤-isDecTotalOrder (Conv.<-isStrictTotalOrder₂ _ _ ≼-isDecTotalOrder)-------------------------------------------------------------------------- Bundles≤-preorder : Poset a ℓ₁ ℓ₂ → ℕ → Preorder _ _ _≤-preorder ≼-po n = record{ isPreorder = ≤-isPreorder isPartialOrder {n = n}} where open Poset ≼-po≤-poset : Poset a ℓ₁ ℓ₂ → ℕ → Poset _ _ _≤-poset ≼-po n = record{ isPartialOrder = ≤-isPartialOrder isPartialOrder {n = n}} where open Poset ≼-po≤-decPoset : DecPoset a ℓ₁ ℓ₂ → ℕ → DecPoset _ _ _≤-decPoset ≼-dpo n = record{ isDecPartialOrder = ≤-isDecPartialOrder isDecPartialOrder {n = n}} where open DecPoset ≼-dpo≤-totalOrder : (≼-dto : TotalOrder a ℓ₁ ℓ₂) → Decidable (TotalOrder._≈_ ≼-dto) → ℕ → TotalOrder _ _ _≤-totalOrder ≼-dto _≟_ n = record{ isTotalOrder = ≤-isTotalOrder _≟_ isTotalOrder {n = n}} where open TotalOrder ≼-dto≤-decTotalOrder : DecTotalOrder a ℓ₁ ℓ₂ → ℕ → DecTotalOrder _ _ _≤-decTotalOrder ≼-dto n = record{ isDecTotalOrder = ≤-isDecTotalOrder isDecTotalOrder {n = n}} where open DecTotalOrder ≼-dto-------------------------------------------------------------------------- Reasoning------------------------------------------------------------------------module ≤-Reasoning {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂}(≼-po : IsPartialOrder _≈_ _≼_)(n : ℕ)whereopen IsPartialOrder ≼-poopen import Relation.Binary.Reasoning.Base.Triple(≤-isPreorder ≼-po {n})(<-asym isEquivalence ≤-resp-≈ antisym)(<-trans ≼-po)(<-resp₂ isEquivalence ≤-resp-≈)<⇒≤(<-transˡ ≼-po)(<-transʳ ≼-po)public
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of same-length vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Lex.Core {a} {A : Set a} whereopen import Data.Emptyopen import Data.Nat.Base using (ℕ; suc)import Data.Nat.Properties as ℕopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂; uncurry)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Data.Vec.Relation.Binary.Pointwise.Inductive using (Pointwise; []; _∷_)open import Function.Base using (flip)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; REL)open import Relation.Binary.Definitionsusing (Transitive; Symmetric; Asymmetric; Antisymmetric; Irreflexive; Trans; _Respects₂_; _Respectsˡ_; _Respectsʳ_; Decidable; Irrelevant)open import Relation.Binary.Structures using (IsPartialEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; refl; cong)import Relation.Nullary as Nullaryopen import Relation.Nullary.Decidable as Dec using (Dec; yes; no; _×-dec_; _⊎-dec_)open import Relation.Nullary.Negationprivatevariableℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Definition-- The lexicographic ordering itself can be either strict or non-strict,-- depending on whether type P is inhabited.data Lex {A : Set a} (P : Set) (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂): ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂) wherebase : (p : P) → Lex P _≈_ _≺_ [] []this : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n}(x≺y : x ≺ y) (m≡n : m ≡ n) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys)next : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n}(x≈y : x ≈ y) (xs<ys : Lex P _≈_ _≺_ xs ys) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys)-------------------------------------------------------------------------- Operationsmap-P : ∀ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} {P₁ P₂ : Set} → (P₁ → P₂) →∀ {m n} {xs : Vec A m} {ys : Vec A n} →Lex P₁ _≈_ _≺_ xs ys → Lex P₂ _≈_ _≺_ xs ysmap-P f (base p) = base (f p)map-P f (this x≺y m≡n) = this x≺y m≡nmap-P f (next x≈y xs<ys) = next x≈y (map-P f xs<ys)-------------------------------------------------------------------------- Propertiesmodule _ {P : Set} {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} wherelength-equal : ∀ {m n} {xs : Vec A m} {ys : Vec A n} →Lex P _≈_ _≺_ xs ys → m ≡ nlength-equal (base _) = refllength-equal (this x≺y m≡n) = cong suc m≡nlength-equal (next x≈y xs<ys) = cong suc (length-equal xs<ys)module _ {P : Set} {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<ₗₑₓ_ = Lex P _≈_ _≺_≰-this : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} →¬ (x ≈ y) → ¬ (x ≺ y) → ¬ (x ∷ xs) <ₗₑₓ (y ∷ ys)≰-this x≉y x≮y (this x≺y m≡n) = contradiction x≺y x≮y≰-this x≉y x≮y (next x≈y xs<ys) = contradiction x≈y x≉y≰-next : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} →¬ (x ≺ y) → ¬ (xs <ₗₑₓ ys) → ¬ (x ∷ xs) <ₗₑₓ (y ∷ ys)≰-next x≮y xs≮ys (this x≺y m≡n) = contradiction x≺y x≮y≰-next x≮y xs≮ys (next x≈y xs<ys) = contradiction xs<ys xs≮ysP⇔[]<[] : P ⇔ [] <ₗₑₓ []P⇔[]<[] = mk⇔ base (λ { (base p) → p })toSum : ∀ {x y n} {xs ys : Vec A n} → (x ∷ xs) <ₗₑₓ (y ∷ ys) → (x ≺ y ⊎ (x ≈ y × xs <ₗₑₓ ys))toSum (this x≺y m≡n) = inj₁ x≺ytoSum (next x≈y xs<ys) = inj₂ (x≈y , xs<ys)∷<∷-⇔ : ∀ {x y n} {xs ys : Vec A n} → (x ≺ y ⊎ (x ≈ y × xs <ₗₑₓ ys)) ⇔ (x ∷ xs) <ₗₑₓ (y ∷ ys)∷<∷-⇔ = mk⇔ [ flip this refl , uncurry next ] toSummodule _ (≈-equiv : IsPartialEquivalence _≈_)((≺-respʳ-≈ , ≺-respˡ-≈) : _≺_ Respects₂ _≈_)(≺-trans : Transitive _≺_)(open IsPartialEquivalence ≈-equiv)wheretransitive′ : ∀ {m n o P₂} → Trans (Lex P _≈_ _≺_ {m} {n}) (Lex P₂ _≈_ _≺_ {n} {o}) (Lex (P × P₂) _≈_ _≺_)transitive′ (base p₁) (base p₂) = base (p₁ , p₂)transitive′ (this x≺y m≡n) (this y≺z n≡o) = this (≺-trans x≺y y≺z) (≡.trans m≡n n≡o)transitive′ (this x≺y m≡n) (next y≈z ys<zs) = this (≺-respʳ-≈ y≈z x≺y) (≡.trans m≡n (length-equal ys<zs))transitive′ (next x≈y xs<ys) (this y≺z n≡o) = this (≺-respˡ-≈ (sym x≈y) y≺z) (≡.trans (length-equal xs<ys) n≡o)transitive′ (next x≈y xs<ys) (next y≈z ys<zs) = next (trans x≈y y≈z) (transitive′ xs<ys ys<zs)transitive : ∀ {m n o} → Trans (_<ₗₑₓ_ {m} {n}) (_<ₗₑₓ_ {n} {o}) _<ₗₑₓ_transitive xs<ys ys<zs = map-P proj₁ (transitive′ xs<ys ys<zs)module _ (≈-sym : Symmetric _≈_) (≺-irrefl : Irreflexive _≈_ _≺_) (≺-asym : Asymmetric _≺_) whereantisym : ∀ {n} → Antisymmetric (_≋_ {n}) (_<ₗₑₓ_)antisym (base _) (base _) = []antisym (this x≺y m≡n) (this y≺x n≡m) = ⊥-elim (≺-asym x≺y y≺x)antisym (this x≺y m≡n) (next y≈x ys<xs) = ⊥-elim (≺-irrefl (≈-sym y≈x) x≺y)antisym (next x≈y xs<ys) (this y≺x m≡n) = ⊥-elim (≺-irrefl (≈-sym x≈y) y≺x)antisym (next x≈y xs<ys) (next y≈x ys<xs) = x≈y ∷ (antisym xs<ys ys<xs)module _ (≈-equiv : IsPartialEquivalence _≈_) (open IsPartialEquivalence ≈-equiv) whererespectsˡ : _≺_ Respectsˡ _≈_ → ∀ {m n} → (_<ₗₑₓ_ {m} {n}) Respectsˡ _≋_respectsˡ resp [] (base p) = base prespectsˡ resp (x≈y ∷ xs≋ys) (this x≺z m≡n) = this (resp x≈y x≺z) m≡nrespectsˡ resp (x≈y ∷ xs≋ys) (next x≈z xs<zs) = next (trans (sym x≈y) x≈z) (respectsˡ resp xs≋ys xs<zs)respectsʳ : _≺_ Respectsʳ _≈_ → ∀ {m n} → (_<ₗₑₓ_ {m} {n}) Respectsʳ _≋_respectsʳ resp [] (base p) = base prespectsʳ resp (x≈y ∷ xs≋ys) (this x≺z m≡n) = this (resp x≈y x≺z) m≡nrespectsʳ resp (x≈y ∷ xs≋ys) (next x≈z xs<zs) = next (trans x≈z x≈y) (respectsʳ resp xs≋ys xs<zs)respects₂ : _≺_ Respects₂ _≈_ → ∀ {n} → (_<ₗₑₓ_ {n} {n}) Respects₂ _≋_respects₂ (≺-resp-≈ʳ , ≺-resp-≈ˡ) = respectsʳ ≺-resp-≈ʳ , respectsˡ ≺-resp-≈ˡmodule _ (P? : Dec P) (_≈?_ : Decidable _≈_) (_≺?_ : Decidable _≺_) wheredecidable : ∀ {m n} → Decidable (_<ₗₑₓ_ {m} {n})decidable {m} {n} xs ys with m ℕ.≟ ndecidable {_} {_} [] [] | yes refl = Dec.map P⇔[]<[] P?decidable {_} {_} (x ∷ xs) (y ∷ ys) | yes refl = Dec.map ∷<∷-⇔ ((x ≺? y) ⊎-dec (x ≈? y) ×-dec (decidable xs ys))decidable {_} {_} _ _ | no m≢n = no (λ xs<ys → contradiction (length-equal xs<ys) m≢n)module _ (P-irrel : Nullary.Irrelevant P)(≈-irrel : Irrelevant _≈_)(≺-irrel : Irrelevant _≺_)(≺-irrefl : Irreflexive _≈_ _≺_)whereirrelevant : ∀ {m n} → Irrelevant (_<ₗₑₓ_ {m} {n})irrelevant (base p₁) (base p₂) rewrite P-irrel p₁ p₂ = reflirrelevant (this x≺y₁ m≡n₁) (this x≺y₂ m≡n₂) rewrite ≺-irrel x≺y₁ x≺y₂ | ℕ.≡-irrelevant m≡n₁ m≡n₂ = reflirrelevant (this x≺y m≡n) (next x≈y xs<ys₂) = contradiction x≺y (≺-irrefl x≈y)irrelevant (next x≈y xs<ys₁) (this x≺y m≡n) = contradiction x≺y (≺-irrefl x≈y)irrelevant (next x≈y₁ xs<ys₁) (next x≈y₂ xs<ys₂) rewrite ≈-irrel x≈y₁ x≈y₂ | irrelevant xs<ys₁ xs<ys₂ = refl
-------------------------------------------------------------------------- The Agda standard library---- Semi-heterogeneous vector equality over setoids------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.Vec.Relation.Binary.Equality.Setoid{a ℓ} (S : Setoid a ℓ) whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Fin.Base using (zero; suc)open import Data.Vec.Baseopen import Data.Vec.Relation.Binary.Pointwise.Inductive as PWusing (Pointwise)open import Level using (_⊔_)open import Relation.Binary.Core using (REL)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Sym; Trans)open Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Definition of equalityinfix 4 _≋__≋_ : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ)_≋_ = Pointwise _≈_open Pointwise public using ([]; _∷_)open PW public using (length-equal)-------------------------------------------------------------------------- Relational properties≋-refl : ∀ {n} → Reflexive (_≋_ {n})≋-refl = PW.refl refl≋-sym : ∀ {n m} → Sym _≋_ (_≋_ {m} {n})≋-sym = PW.sym sym≋-trans : ∀ {n m o} → Trans (_≋_ {m}) (_≋_ {n} {o}) (_≋_)≋-trans = PW.trans trans≋-isEquivalence : ∀ n → IsEquivalence (_≋_ {n})≋-isEquivalence = PW.isEquivalence isEquivalence≋-setoid : ℕ → Setoid a (a ⊔ ℓ)≋-setoid = PW.setoid S-------------------------------------------------------------------------- mapopen PW public using ( map⁺)-------------------------------------------------------------------------- ++open PW public using (++⁺ ; ++⁻ ; ++ˡ⁻; ++ʳ⁻)++-identityˡ : ∀ {n} (xs : Vec A n) → [] ++ xs ≋ xs++-identityˡ _ = ≋-refl++-identityʳ : ∀ {n} (xs : Vec A n) → xs ++ [] ≋ xs++-identityʳ [] = []++-identityʳ (x ∷ xs) = refl ∷ ++-identityʳ xs++-assoc : ∀ {n m k} (xs : Vec A n) (ys : Vec A m) (zs : Vec A k) →(xs ++ ys) ++ zs ≋ xs ++ (ys ++ zs)++-assoc [] ys zs = ≋-refl++-assoc (x ∷ xs) ys zs = refl ∷ ++-assoc xs ys zsmap-++ : ∀ {b m n} {B : Set b}(f : B → A) (xs : Vec B m) {ys : Vec B n} →map f (xs ++ ys) ≋ map f xs ++ map f ysmap-++ f [] = ≋-reflmap-++ f (x ∷ xs) = refl ∷ map-++ f xsmap-[]≔ : ∀ {b n} {B : Set b}(f : B → A) (xs : Vec B n) i p →map f (xs [ i ]≔ p) ≋ map f xs [ i ]≔ f pmap-[]≔ f (x ∷ xs) zero p = refl ∷ ≋-reflmap-[]≔ f (x ∷ xs) (suc i) p = refl ∷ map-[]≔ f xs i p-------------------------------------------------------------------------- concatopen PW public using (concat⁺; concat⁻)-------------------------------------------------------------------------- replicatereplicate-shiftʳ : ∀ {m} n x (xs : Vec A m) →replicate n x ++ (x ∷ xs) ≋replicate (1 + n) x ++ xsreplicate-shiftʳ zero x xs = ≋-reflreplicate-shiftʳ (suc n) x xs = refl ∷ (replicate-shiftʳ n x xs)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-++-commute = map-++{-# WARNING_ON_USAGE map-++-commute"Warning: map-++-commute was deprecated in v2.0.Please use map-++ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Vector equality over propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Equality.Propositional {a} {A : Set a} whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Vec.Base using (Vec)open import Data.Vec.Relation.Binary.Pointwise.Inductiveusing (Pointwise-≡⇒≡; ≡⇒Pointwise-≡)import Data.Vec.Relation.Binary.Equality.Setoid as SEqopen import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (setoid)-------------------------------------------------------------------------- Publically re-export everything from setoid equalityopen SEq (setoid A) public-------------------------------------------------------------------------- ≋ is propositional≋⇒≡ : ∀ {n} {xs ys : Vec A n} → xs ≋ ys → xs ≡ ys≋⇒≡ = Pointwise-≡⇒≡≡⇒≋ : ∀ {n} {xs ys : Vec A n} → xs ≡ ys → xs ≋ ys≡⇒≋ = ≡⇒Pointwise-≡-- See also Data.Vec.Relation.Binary.Equality.Propositional.WithK.≋⇒≅.
-------------------------------------------------------------------------- The Agda standard library---- Code related to vector equality over propositional equality that-- makes use of heterogeneous equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Vec.Relation.Binary.Equality.Propositional.WithK{a} {A : Set a} whereopen import Data.Vec.Base using (Vec)open import Data.Vec.Relation.Binary.Equality.Propositional {A = A}open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Binary.HeterogeneousEquality using (_≅_; ≡-to-≅)≋⇒≅ : ∀ {m n} {xs : Vec A m} {ys : Vec A n} →xs ≋ ys → xs ≅ ys≋⇒≅ p with refl <- length-equal p = ≡-to-≅ (≋⇒≡ p)
-------------------------------------------------------------------------- The Agda standard library---- Decidable semi-heterogeneous vector equality over setoids------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)open import Relation.Binary.Structures using (IsDecEquivalence)module Data.Vec.Relation.Binary.Equality.DecSetoid{a ℓ} (DS : DecSetoid a ℓ) whereopen import Data.Nat.Base using (ℕ)import Data.Vec.Relation.Binary.Equality.Setoid as Equalityimport Data.Vec.Relation.Binary.Pointwise.Inductive as PWopen import Level using (_⊔_)open import Relation.Binary.Definitions using (Decidable)open DecSetoid DS-------------------------------------------------------------------------- Make all definitions from equality availableopen Equality setoid public-------------------------------------------------------------------------- Additional propertiesinfix 4 _≋?__≋?_ : ∀ {m n} → Decidable (_≋_ {m} {n})_≋?_ = PW.decidable _≟_≋-isDecEquivalence : ∀ n → IsDecEquivalence (_≋_ {n})≋-isDecEquivalence = PW.isDecEquivalence isDecEquivalence≋-decSetoid : ℕ → DecSetoid a (a ⊔ ℓ)≋-decSetoid = PW.decSetoid DS
-------------------------------------------------------------------------- The Agda standard library---- Decidable vector equality over propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.Vec.Relation.Binary.Equality.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A) whereimport Data.Vec.Relation.Binary.Equality.Propositional as PEqimport Data.Vec.Relation.Binary.Equality.DecSetoid as DSEqopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Publicly re-export everything from decSetoid and propositional-- equalityopen PEq publicopen DSEq (decSetoid _≟_) publicusing (_≋?_; ≋-isDecEquivalence; ≋-decSetoid)
-------------------------------------------------------------------------- The Agda standard library---- An equational reasoning library for propositional equality over-- vectors of different indices using cast.---- See README.Data.Vec.Relation.Binary.Equality.Cast for-- documentation and examples.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Relation.Binary.Equality.Cast {a} {A : Set a} whereopen import Data.Nat.Base using (ℕ; zero; suc)open import Data.Nat.Properties using (suc-injective)open import Data.Vec.Baseopen import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Definitions using (Sym; Trans)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; trans; sym; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablel m n o : ℕxs ys zs : Vec A ncast-is-id : .(eq : m ≡ m) (xs : Vec A m) → cast eq xs ≡ xscast-is-id eq [] = reflcast-is-id eq (x ∷ xs) = cong (x ∷_) (cast-is-id (suc-injective eq) xs)cast-trans : .(eq₁ : m ≡ n) .(eq₂ : n ≡ o) (xs : Vec A m) →cast eq₂ (cast eq₁ xs) ≡ cast (trans eq₁ eq₂) xscast-trans {m = zero} {n = zero} {o = zero} eq₁ eq₂ [] = reflcast-trans {m = suc _} {n = suc _} {o = suc _} eq₁ eq₂ (x ∷ xs) =cong (x ∷_) (cast-trans (suc-injective eq₁) (suc-injective eq₂) xs)infix 3 _≈[_]__≈[_]_ : ∀ {n m} → Vec A n → .(eq : n ≡ m) → Vec A m → Set axs ≈[ eq ] ys = cast eq xs ≡ ys-------------------------------------------------------------------------- _≈[_]_ is ‘reflexive’, ‘symmetric’ and ‘transitive’≈-reflexive : ∀ {n} → _≡_ ⇒ (λ xs ys → _≈[_]_ {n} xs refl ys)≈-reflexive {x = x} eq = trans (cast-is-id refl x) eq≈-sym : .{m≡n : m ≡ n} → Sym _≈[ m≡n ]_ _≈[ sym m≡n ]_≈-sym {m≡n = m≡n} {xs} {ys} xs≈ys = begincast (sym m≡n) ys ≡⟨ cong (cast (sym m≡n)) xs≈ys ⟨cast (sym m≡n) (cast m≡n xs) ≡⟨ cast-trans m≡n (sym m≡n) xs ⟩cast (trans m≡n (sym m≡n)) xs ≡⟨ cast-is-id (trans m≡n (sym m≡n)) xs ⟩xs ∎where open ≡-Reasoning≈-trans : ∀ .{m≡n : m ≡ n} .{n≡o : n ≡ o} → Trans _≈[ m≡n ]_ _≈[ n≡o ]_ _≈[ trans m≡n n≡o ]_≈-trans {m≡n = m≡n} {n≡o} {xs} {ys} {zs} xs≈ys ys≈zs = begincast (trans m≡n n≡o) xs ≡⟨ cast-trans m≡n n≡o xs ⟨cast n≡o (cast m≡n xs) ≡⟨ cong (cast n≡o) xs≈ys ⟩cast n≡o ys ≡⟨ ys≈zs ⟩zs ∎where open ≡-Reasoning-------------------------------------------------------------------------- Reasoning combinatorsmodule CastReasoning whereopen ≡-Reasoning publicrenaming (begin_ to begin-≡_; _∎ to _≡-∎)begin_ : ∀ .{m≡n : m ≡ n} {xs : Vec A m} {ys} → xs ≈[ m≡n ] ys → cast m≡n xs ≡ ysbegin xs≈ys = xs≈ys_∎ : (xs : Vec A n) → cast refl xs ≡ xs_∎ xs = ≈-reflexive refl_≈⟨⟩_ : ∀ .{m≡n : m ≡ n} (xs : Vec A m) {ys} → xs ≈[ m≡n ] ys → xs ≈[ m≡n ] ysxs ≈⟨⟩ xs≈ys = xs≈ys-- composition of _≈[_]_step-≈-⟩ : ∀ .{m≡n : m ≡ n}.{m≡o : m ≡ o} (xs : Vec A m) {ys : Vec A n} {zs : Vec A o} →ys ≈[ trans (sym m≡n) m≡o ] zs → xs ≈[ m≡n ] ys → xs ≈[ m≡o ] zsstep-≈-⟩ xs ys≈zs xs≈ys = ≈-trans xs≈ys ys≈zsstep-≈-⟨ : ∀ .{n≡m : n ≡ m}.{m≡o : m ≡ o} (xs : Vec A m) {ys : Vec A n} {zs : Vec A o} →ys ≈[ trans n≡m m≡o ] zs → ys ≈[ n≡m ] xs → xs ≈[ m≡o ] zsstep-≈-⟨ xs ys≈zs ys≈xs = step-≈-⟩ xs ys≈zs (≈-sym ys≈xs)-- composition of the equality type on the right-hand side of _≈[_]_,-- or escaping to ordinary _≡_step-≃-⟩ : ∀ .{m≡n : m ≡ n} (xs : Vec A m) {ys zs} → ys ≡ zs → xs ≈[ m≡n ] ys → xs ≈[ m≡n ] zsstep-≃-⟩ xs ys≡zs xs≈ys = ≈-trans xs≈ys (≈-reflexive ys≡zs)step-≃-⟨ : ∀ .{m≡n : m ≡ n} (xs : Vec A m) {ys zs} → ys ≡ zs → ys ≈[ sym m≡n ] xs → xs ≈[ m≡n ] zsstep-≃-⟨ xs ys≡zs ys≈xs = step-≃-⟩ xs ys≡zs (≈-sym ys≈xs)-- composition of the equality type on the left-hand side of _≈[_]_step-≂-⟩ : ∀ .{m≡n : m ≡ n} (xs : Vec A m) {ys zs} → ys ≈[ m≡n ] zs → xs ≡ ys → xs ≈[ m≡n ] zsstep-≂-⟩ xs ys≈zs xs≡ys = ≈-trans (≈-reflexive xs≡ys) ys≈zsstep-≂-⟨ : ∀ .{m≡n : m ≡ n} (xs : Vec A m) {ys zs} → ys ≈[ m≡n ] zs → ys ≡ xs → xs ≈[ m≡n ] zsstep-≂-⟨ xs ys≈zs ys≡xs = step-≂-⟩ xs ys≈zs (sym ys≡xs)-- `cong` after a `_≈[_]_` step that exposes the `cast` to the `cong`-- operation≈-cong : ∀ .{l≡o : l ≡ o} .{m≡n : m ≡ n} {xs : Vec A m} {ys zs} (f : Vec A o → Vec A n) →xs ≈[ m≡n ] f (cast l≡o ys) → ys ≈[ l≡o ] zs → xs ≈[ m≡n ] f zs≈-cong f xs≈fys ys≈zs = trans xs≈fys (cong f ys≈zs)-------------------------------------------------------------------------- convenient syntax for ‘equational’ reasoninginfix 1 begin_infixr 2 step-≃-⟩ step-≃-⟨ step-≂-⟩ step-≂-⟨ step-≈-⟩ step-≈-⟨ _≈⟨⟩_ ≈-conginfix 3 _∎syntax step-≃-⟩ xs ys≡zs xs≈ys = xs ≃⟨ xs≈ys ⟩ ys≡zssyntax step-≃-⟨ xs ys≡zs xs≈ys = xs ≃⟨ xs≈ys ⟨ ys≡zssyntax step-≂-⟩ xs ys≈zs xs≡ys = xs ≂⟨ xs≡ys ⟩ ys≈zssyntax step-≂-⟨ xs ys≈zs ys≡xs = xs ≂⟨ ys≡xs ⟨ ys≈zssyntax step-≈-⟩ xs ys≈zs xs≈ys = xs ≈⟨ xs≈ys ⟩ ys≈zssyntax step-≈-⟨ xs ys≈zs ys≈xs = xs ≈⟨ ys≈xs ⟨ ys≈zs
-------------------------------------------------------------------------- The Agda standard library---- Reflection utilities for Vector------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Reflection whereimport Data.List.Base as Listopen import Data.Vec.Baseopen import Reflection.AST.Termopen import Reflection.AST.Argument-------------------------------------------------------------------------- Type`Vector : Term → Term → Term`Vector `A `n = def (quote Vec) (1 ⋯⟅∷⟆ `A ⟨∷⟩ `n ⟨∷⟩ List.[])-------------------------------------------------------------------------- Constructors`[] : Term`[] = con (quote []) (2 ⋯⟅∷⟆ List.[])infixr 5 _`∷__`∷_ : Term → Term → Term_`∷_ x xs = con (quote _∷_) (3 ⋯⟅∷⟆ x ⟨∷⟩ xs ⟨∷⟩ List.[])-------------------------------------------------------------------------- Patterns-- Can't be used on the RHS as the omitted args aren't inferable.pattern `[]` = con (quote []) (_ ∷ _ ∷ [])pattern _`∷`_ x xs = con (quote _∷_) (_ ∷ _ ∷ _ ∷ x ⟨∷⟩ xs ⟨∷⟩ _)
-------------------------------------------------------------------------- The Agda standard library---- Vectors defined by recursion-------------------------------------------------------------------------- What is the point of this module? The n-ary products below are-- intended to be used with a fixed n, in which case the nil constructor-- can be avoided: pairs are represented as pairs (x , y), not as-- triples (x , y , unit).-- Additionally, vectors defined by recursion enjoy η-rules. That is to-- say that two vectors of known length are definitionally equal-- whenever their elements are.{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Recursive whereopen import Data.Nat.Base as Nat using (ℕ; zero; suc; NonZero; pred)open import Data.Nat.Properties using (+-comm; *-comm)open import Data.Empty.Polymorphicopen import Data.Fin.Base as Fin using (Fin; zero; suc)open import Data.Fin.Properties using (1↔⊤; *↔×)open import Data.Product.Base as Product using (_×_; _,_; proj₁; proj₂)open import Data.Product.Algebra using (×-cong)open import Data.Sum.Base as Sum using (_⊎_)open import Data.Unit.Base using (tt)open import Data.Unit.Polymorphic.Base using (⊤)open import Data.Unit.Polymorphic.Properties using (⊤↔⊤*)open import Data.Vec.Base as Vec using (Vec; _∷_)open import Data.Vec.N-ary using (N-ary)open import Function.Base using (_∘′_; _∘_; id; const)open import Function.Bundles using (_↔_; mk↔ₛ′; mk↔)open import Function.Properties.Inverse using (↔-isEquivalence; ↔-refl; ↔-sym; ↔-trans)open import Level using (Level; lift)open import Relation.Unary using (IUniversal; Universal; _⇒_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; sym; trans; cong; subst)open import Relation.Binary.Structures using (IsEquivalence)privatevariablea b c p : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Types and patternsinfix 8 _^__^_ : Set a → ℕ → Set aA ^ 0 = ⊤A ^ 1 = AA ^ (suc n@(suc _)) = A × A ^ npattern [] = lift ttinfix 3 _∈[_]__∈[_]_ : {A : Set a} → A → ∀ n → A ^ n → Set aa ∈[ 0 ] as = ⊥a ∈[ 1 ] a′ = a ≡ a′a ∈[ suc n@(suc _) ] a′ , as = a ≡ a′ ⊎ a ∈[ n ] as-------------------------------------------------------------------------- Basic operationscons : ∀ n → A → A ^ n → A ^ suc ncons 0 a _ = acons (suc n) a as = a , asuncons : ∀ n → A ^ suc n → A × A ^ nuncons 0 a = a , lift ttuncons (suc n) (a , as) = a , ashead : ∀ n → A ^ suc n → Ahead n as = proj₁ (uncons n as)tail : ∀ n → A ^ suc n → A ^ ntail n as = proj₂ (uncons n as)fromVec : ∀[ Vec A ⇒ (A ^_) ]fromVec = Vec.foldr (_ ^_) (cons _) _toVec : Π[ (A ^_) ⇒ Vec A ]toVec 0 as = Vec.[]toVec (suc n) as = head n as ∷ toVec n (tail n as)lookup : ∀ {n} → A ^ n → Fin n → Alookup as (zero {n}) = head n aslookup as (suc {n} k) = lookup (tail n as) kreplicate : ∀ n → A → A ^ nreplicate n a = fromVec (Vec.replicate n a)tabulate : ∀ n → (Fin n → A) → A ^ ntabulate n f = fromVec (Vec.tabulate f)append : ∀ m n → A ^ m → A ^ n → A ^ (m Nat.+ n)append 0 n xs ys = ysappend 1 n x ys = cons n x ysappend (suc m@(suc _)) n (x , xs) ys = x , append m n xs yssplitAt : ∀ m n → A ^ (m Nat.+ n) → A ^ m × A ^ nsplitAt 0 n xs = [] , xssplitAt (suc m) n xs =let (ys , zs) = splitAt m n (tail (m Nat.+ n) xs) incons m (head (m Nat.+ n) xs) ys , zs-------------------------------------------------------------------------- Manipulating N-ary productsmap : (A → B) → ∀ n → A ^ n → B ^ nmap f 0 as = lift ttmap f 1 a = f amap f (suc n@(suc _)) (a , as) = f a , map f n asap : ∀ n → (A → B) ^ n → A ^ n → B ^ nap 0 fs ts = []ap 1 f t = f tap (suc n@(suc _)) (f , fs) (t , ts) = f t , ap n fs tsmodule _ {P : ℕ → Set p} wherefoldr : P 0 → (A → P 1) → (∀ n → A → P (suc n) → P (suc (suc n))) →∀ n → A ^ n → P nfoldr p0 p1 p2+ 0 as = p0foldr p0 p1 p2+ 1 a = p1 afoldr p0 p1 p2+ (suc n′@(suc n)) (a , as) = p2+ n a (foldr p0 p1 p2+ n′ as)foldl : (P : ℕ → Set p) →P 0 → (A → P 1) → (∀ n → A → P (suc n) → P (suc (suc n))) →∀ n → A ^ n → P nfoldl P p0 p1 p2+ 0 as = p0foldl P p0 p1 p2+ 1 a = p1 afoldl P p0 p1 p2+ (suc n@(suc _)) (a , as) = let p1′ = p1 a infoldl (P ∘′ suc) p1′ (λ a → p2+ 0 a p1′) (p2+ ∘ suc) n asreverse : ∀ n → A ^ n → A ^ nreverse = foldl (_ ^_) [] id (λ n → _,_)zipWith : (A → B → C) → ∀ n → A ^ n → B ^ n → C ^ nzipWith f 0 as bs = []zipWith f 1 a b = f a bzipWith f ((suc n@(suc _))) (a , as) (b , bs) = f a b , zipWith f n as bsunzipWith : (A → B × C) → ∀ n → A ^ n → B ^ n × C ^ nunzipWith f 0 as = [] , []unzipWith f 1 a = f aunzipWith f (suc n@(suc _)) (a , as) = Product.zip _,_ _,_ (f a) (unzipWith f n as)zip : ∀ n → A ^ n → B ^ n → (A × B) ^ nzip = zipWith _,_unzip : ∀ n → (A × B) ^ n → A ^ n × B ^ nunzip = unzipWith idlift↔ : ∀ n → A ↔ B → A ^ n ↔ B ^ nlift↔ 0 A↔B = mk↔ₛ′ _ _ (const refl) (const refl)lift↔ 1 A↔B = A↔Blift↔ (suc n@(suc _)) A↔B = ×-cong A↔B (lift↔ n A↔B)Fin[m^n]↔Fin[m]^n : ∀ m n → Fin (m Nat.^ n) ↔ Fin m ^ nFin[m^n]↔Fin[m]^n m 0 = ↔-trans 1↔⊤ (↔-sym ⊤↔⊤*)Fin[m^n]↔Fin[m]^n m 1 = subst (λ x → Fin x ↔ Fin m)(trans (sym (+-comm m zero)) (*-comm 1 m)) ↔-reflFin[m^n]↔Fin[m]^n m (suc (suc n)) = ↔-trans (*↔× {m = m}) (×-cong ↔-refl (Fin[m^n]↔Fin[m]^n _ _))
-------------------------------------------------------------------------- The Agda standard library---- Properties of n-ary products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Recursive.Properties whereopen import Level using (Level)open import Data.Nat.Base hiding (_^_)open import Data.Product.Baseopen import Data.Vec.Recursiveopen import Data.Vec.Base using (Vec; _∷_)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablea : LevelA : Set a-------------------------------------------------------------------------- Basic proofscons-head-tail-identity : ∀ n (as : A ^ suc n) → cons n (head n as) (tail n as) ≡ ascons-head-tail-identity 0 as = reflcons-head-tail-identity (suc n) as = reflhead-cons-identity : ∀ n a (as : A ^ n) → head n (cons n a as) ≡ ahead-cons-identity 0 a as = reflhead-cons-identity (suc n) a as = refltail-cons-identity : ∀ n a (as : A ^ n) → tail n (cons n a as) ≡ astail-cons-identity 0 a as = refltail-cons-identity (suc n) a as = reflappend-cons : ∀ m n a (xs : A ^ m) ys →append (suc m) n (cons m a xs) ys ≡ cons (m + n) a (append m n xs ys)append-cons 0 n a xs ys = reflappend-cons (suc m) n a xs ys = reflappend-splitAt-identity : ∀ m n (as : A ^ (m + n)) → uncurry (append m n) (splitAt m n as) ≡ asappend-splitAt-identity 0 n as = reflappend-splitAt-identity (suc m) n as = beginlet x = head (m + n) as inlet (xs , ys) = splitAt m n (tail (m + n) as) inappend (suc m) n (cons m (head (m + n) as) xs) ys≡⟨ append-cons m n x xs ys ⟩cons (m + n) x (append m n xs ys)≡⟨ cong (cons (m + n) x) (append-splitAt-identity m n (tail (m + n) as)) ⟩cons (m + n) x (tail (m + n) as)≡⟨ cons-head-tail-identity (m + n) as ⟩as∎-------------------------------------------------------------------------- Conversion to and from VecfromVec∘toVec : ∀ n (xs : A ^ n) → fromVec (toVec n xs) ≡ xsfromVec∘toVec 0 _ = reflfromVec∘toVec (suc n) xs = begincons n (head n xs) (fromVec (toVec n (tail n xs)))≡⟨ cong (cons n (head n xs)) (fromVec∘toVec n (tail n xs)) ⟩cons n (head n xs) (tail n xs)≡⟨ cons-head-tail-identity n xs ⟩xs ∎toVec∘fromVec : ∀ {n} (xs : Vec A n) → toVec n (fromVec xs) ≡ xstoVec∘fromVec Vec.[] = refltoVec∘fromVec {n = suc n} (x Vec.∷ xs) = beginhead n (cons n x (fromVec xs)) Vec.∷ toVec n (tail n (cons n x (fromVec xs)))≡⟨ cong₂ (λ x xs → x Vec.∷ toVec n xs) hd-prf tl-prf ⟩x Vec.∷ toVec n (fromVec xs)≡⟨ cong (x Vec.∷_) (toVec∘fromVec xs) ⟩x Vec.∷ xs∎ wherehd-prf = head-cons-identity _ x (fromVec xs)tl-prf = tail-cons-identity _ x (fromVec xs)↔Vec : ∀ n → A ^ n ↔ Vec A n↔Vec n = mk↔ₛ′ (toVec n) fromVec toVec∘fromVec (fromVec∘toVec n)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0append-cons-commute = append-cons{-# WARNING_ON_USAGE append-cons-commute"Warning: append-cons-commute was deprecated in v2.0.Please use append-cons instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of vectors defined by recursion------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Recursive.Effectful whereopen import Agda.Builtin.Natopen import Data.Product.Base hiding (map)open import Data.Vec.Recursiveopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Base using (_∘_; flip)-------------------------------------------------------------------------- Functor and applicativefunctor : ∀ {ℓ} n → RawFunctor {ℓ} (_^ n)functor n = record { _<$>_ = λ f → map f n }applicative : ∀ {ℓ} n → RawApplicative {ℓ} (_^ n)applicative n = record{ rawFunctor = functor n; pure = replicate n; _<*>_ = ap n}-------------------------------------------------------------------------- Get access to other monadic functionsmodule _ {f g F} (App : RawApplicative {f} {g} F) whereopen RawApplicative AppsequenceA : ∀ {n A} → F A ^ n → F (A ^ n)sequenceA {0} _ = pure _sequenceA {1} fa = fasequenceA {suc (suc _)} (fa , fas) = _,_ <$> fa ⊛ sequenceA fasmapA : ∀ {n a} {A : Set a} {B} → (A → F B) → A ^ n → F (B ^ n)mapA f = sequenceA ∘ map f _forA : ∀ {n a} {A : Set a} {B} → A ^ n → (A → F B) → F (B ^ n)forA = flip mapAmodule _ {m n M} (Mon : RawMonad {m} {n} M) whereprivate App = RawMonad.rawApplicative MonsequenceM : ∀ {n A} → M A ^ n → M (A ^ n)sequenceM = sequenceA AppmapM : ∀ {n a} {A : Set a} {B} → (A → M B) → A ^ n → M (B ^ n)mapM = mapA AppforM : ∀ {n a} {A : Set a} {B} → A ^ n → (A → M B) → M (B ^ n)forM = forA App
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Vec.Recursive.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Recursive.Categorical whereopen import Data.Vec.Recursive.Effectful public{-# WARNING_ON_IMPORT"Data.Vec.Recursive.Categorical was deprecated in v2.0.Use Data.Vec.Recursive.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some Vec-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Properties whereopen import Algebra.Definitionsopen import Data.Bool.Base using (true; false)open import Data.Fin.Base as Finusing (Fin; zero; suc; toℕ; fromℕ<; _↑ˡ_; _↑ʳ_)open import Data.List.Base as List using (List)import Data.List.Properties as Listopen import Data.Nat.Base using (ℕ; zero; suc; _+_; _≤_; _<_; s≤s; pred; s<s⁻¹; _≥_;s≤s⁻¹; z≤n)open import Data.Nat.Propertiesusing (+-assoc; m≤n⇒m≤1+n; m≤m+n; ≤-refl; ≤-trans; ≤-irrelevant; ≤⇒≤″; suc-injective; +-comm; +-suc)open import Data.Product.Base as Productusing (_×_; _,_; proj₁; proj₂; <_,_>; uncurry)open import Data.Sum.Base using ([_,_]′)open import Data.Sum.Properties using ([,]-map)open import Data.Vec.Baseopen import Data.Vec.Relation.Binary.Equality.Cast as VecCastusing (_≈[_]_; ≈-sym; module CastReasoning)open import Function.Base using (_∘_; id; _$_; const; _ˢ_; flip)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Level using (Level)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; _≗_; refl; sym; trans; cong; cong₂; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Decidable.Core using (Dec; does; yes; _×-dec_; map′)open import Relation.Nullary.Negation.Core using (contradiction)import Data.Nat.GeneralisedArithmetic as ℕprivatevariablea b c d p : LevelA B C D : Set aw x y z : Am n o : ℕws xs ys zs : Vec A n-------------------------------------------------------------------------- Properties of propositional equality over vectors∷-injectiveˡ : x ∷ xs ≡ y ∷ ys → x ≡ y∷-injectiveˡ refl = refl∷-injectiveʳ : x ∷ xs ≡ y ∷ ys → xs ≡ ys∷-injectiveʳ refl = refl∷-injective : x ∷ xs ≡ y ∷ ys → x ≡ y × xs ≡ ys∷-injective refl = refl , refl≡-dec : DecidableEquality A → DecidableEquality (Vec A n)≡-dec _≟_ [] [] = yes refl≡-dec _≟_ (x ∷ xs) (y ∷ ys) = map′ (uncurry (cong₂ _∷_))∷-injective (x ≟ y ×-dec ≡-dec _≟_ xs ys)-------------------------------------------------------------------------- _[_]=_[]=-injective : ∀ {i} → xs [ i ]= x → xs [ i ]= y → x ≡ y[]=-injective here here = refl[]=-injective (there xsᵢ≡x) (there xsᵢ≡y) = []=-injective xsᵢ≡x xsᵢ≡y-- See also Data.Vec.Properties.WithK.[]=-irrelevant.-------------------------------------------------------------------------- takeunfold-take : ∀ n x (xs : Vec A (n + m)) → take (suc n) (x ∷ xs) ≡ x ∷ take n xsunfold-take n x xs = refltake-zipWith : ∀ (f : A → B → C) →(xs : Vec A (m + n)) (ys : Vec B (m + n)) →take m (zipWith f xs ys) ≡ zipWith f (take m xs) (take m ys)take-zipWith {m = zero} f xs ys = refltake-zipWith {m = suc m} f (x ∷ xs) (y ∷ ys) = cong (f x y ∷_) (take-zipWith f xs ys)take-map : ∀ (f : A → B) (m : ℕ) (xs : Vec A (m + n)) →take m (map f xs) ≡ map f (take m xs)take-map f zero xs = refltake-map f (suc m) (x ∷ xs) = cong (f x ∷_) (take-map f m xs)-------------------------------------------------------------------------- dropunfold-drop : ∀ n x (xs : Vec A (n + m)) →drop (suc n) (x ∷ xs) ≡ drop n xsunfold-drop n x xs = refldrop-zipWith : (f : A → B → C) →(xs : Vec A (m + n)) (ys : Vec B (m + n)) →drop m (zipWith f xs ys) ≡ zipWith f (drop m xs) (drop m ys)drop-zipWith {m = zero} f xs ys = refldrop-zipWith {m = suc m} f (x ∷ xs) (y ∷ ys) = drop-zipWith f xs ysdrop-map : ∀ (f : A → B) (m : ℕ) (xs : Vec A (m + n)) →drop m (map f xs) ≡ map f (drop m xs)drop-map f zero xs = refldrop-map f (suc m) (x ∷ xs) = drop-map f m xs-------------------------------------------------------------------------- take and drop togethertake++drop≡id : ∀ (m : ℕ) (xs : Vec A (m + n)) → take m xs ++ drop m xs ≡ xstake++drop≡id zero xs = refltake++drop≡id (suc m) (x ∷ xs) = cong (x ∷_) (take++drop≡id m xs)-------------------------------------------------------------------------- truncatetruncate-refl : (xs : Vec A n) → truncate ≤-refl xs ≡ xstruncate-refl [] = refltruncate-refl (x ∷ xs) = cong (x ∷_) (truncate-refl xs)truncate-trans : ∀ {p} (m≤n : m ≤ n) (n≤p : n ≤ p) (xs : Vec A p) →truncate (≤-trans m≤n n≤p) xs ≡ truncate m≤n (truncate n≤p xs)truncate-trans z≤n n≤p xs = refltruncate-trans (s≤s m≤n) (s≤s n≤p) (x ∷ xs) = cong (x ∷_) (truncate-trans m≤n n≤p xs)truncate-irrelevant : (m≤n₁ m≤n₂ : m ≤ n) → truncate {A = A} m≤n₁ ≗ truncate m≤n₂truncate-irrelevant m≤n₁ m≤n₂ xs = cong (λ m≤n → truncate m≤n xs) (≤-irrelevant m≤n₁ m≤n₂)truncate≡take : (m≤n : m ≤ n) (xs : Vec A n) .(eq : n ≡ m + o) →truncate m≤n xs ≡ take m (cast eq xs)truncate≡take z≤n _ eq = refltruncate≡take (s≤s m≤n) (x ∷ xs) eq = cong (x ∷_) (truncate≡take m≤n xs (suc-injective eq))take≡truncate : ∀ m (xs : Vec A (m + n)) →take m xs ≡ truncate (m≤m+n m n) xstake≡truncate zero _ = refltake≡truncate (suc m) (x ∷ xs) = cong (x ∷_) (take≡truncate m xs)-------------------------------------------------------------------------- padpadRight-refl : (a : A) (xs : Vec A n) → padRight ≤-refl a xs ≡ xspadRight-refl a [] = reflpadRight-refl a (x ∷ xs) = cong (x ∷_) (padRight-refl a xs)padRight-replicate : (m≤n : m ≤ n) (a : A) → replicate n a ≡ padRight m≤n a (replicate m a)padRight-replicate z≤n a = reflpadRight-replicate (s≤s m≤n) a = cong (a ∷_) (padRight-replicate m≤n a)padRight-trans : ∀ {p} (m≤n : m ≤ n) (n≤p : n ≤ p) (a : A) (xs : Vec A m) →padRight (≤-trans m≤n n≤p) a xs ≡ padRight n≤p a (padRight m≤n a xs)padRight-trans z≤n n≤p a [] = padRight-replicate n≤p apadRight-trans (s≤s m≤n) (s≤s n≤p) a (x ∷ xs) = cong (x ∷_) (padRight-trans m≤n n≤p a xs)-------------------------------------------------------------------------- truncate and padRight togethertruncate-padRight : (m≤n : m ≤ n) (a : A) (xs : Vec A m) →truncate m≤n (padRight m≤n a xs) ≡ xstruncate-padRight z≤n a [] = refltruncate-padRight (s≤s m≤n) a (x ∷ xs) = cong (x ∷_) (truncate-padRight m≤n a xs)-------------------------------------------------------------------------- lookup[]=⇒lookup : ∀ {i} → xs [ i ]= x → lookup xs i ≡ x[]=⇒lookup here = refl[]=⇒lookup (there xs[i]=x) = []=⇒lookup xs[i]=xlookup⇒[]= : ∀ (i : Fin n) xs → lookup xs i ≡ x → xs [ i ]= xlookup⇒[]= zero (_ ∷ _) refl = herelookup⇒[]= (suc i) (_ ∷ xs) p = there (lookup⇒[]= i xs p)[]=↔lookup : ∀ {i} → xs [ i ]= x ↔ lookup xs i ≡ x[]=↔lookup {xs = ys} {i = i} =mk↔ₛ′ []=⇒lookup (lookup⇒[]= i ys) ([]=⇒lookup∘lookup⇒[]= _ i) lookup⇒[]=∘[]=⇒lookupwherelookup⇒[]=∘[]=⇒lookup : ∀ {i} (p : xs [ i ]= x) →lookup⇒[]= i xs ([]=⇒lookup p) ≡ plookup⇒[]=∘[]=⇒lookup here = refllookup⇒[]=∘[]=⇒lookup (there p) = cong there (lookup⇒[]=∘[]=⇒lookup p)[]=⇒lookup∘lookup⇒[]= : ∀ xs (i : Fin n) (p : lookup xs i ≡ x) →[]=⇒lookup (lookup⇒[]= i xs p) ≡ p[]=⇒lookup∘lookup⇒[]= (x ∷ xs) zero refl = refl[]=⇒lookup∘lookup⇒[]= (x ∷ xs) (suc i) p = []=⇒lookup∘lookup⇒[]= xs i plookup-truncate : (m≤n : m ≤ n) (xs : Vec A n) (i : Fin m) →lookup (truncate m≤n xs) i ≡ lookup xs (Fin.inject≤ i m≤n)lookup-truncate (s≤s m≤m+n) (_ ∷ _) zero = refllookup-truncate (s≤s m≤m+n) (_ ∷ xs) (suc i) = lookup-truncate m≤m+n xs ilookup-take-inject≤ : (xs : Vec A (m + n)) (i : Fin m) →lookup (take m xs) i ≡ lookup xs (Fin.inject≤ i (m≤m+n m n))lookup-take-inject≤ {m = m} {n = n} xs i = beginlookup (take _ xs) i≡⟨ cong (λ ys → lookup ys i) (take≡truncate m xs) ⟩lookup (truncate _ xs) i≡⟨ lookup-truncate (m≤m+n m n) xs i ⟩lookup xs (Fin.inject≤ i (m≤m+n m n))∎ where open ≡-Reasoning-------------------------------------------------------------------------- updateAt (_[_]%=_)-- (+) updateAt i actually updates the element at index i.updateAt-updates : ∀ (i : Fin n) {f : A → A} (xs : Vec A n) →xs [ i ]= x → (updateAt xs i f) [ i ]= f xupdateAt-updates zero (x ∷ xs) here = hereupdateAt-updates (suc i) (x ∷ xs) (there loc) = there (updateAt-updates i xs loc)-- (-) updateAt i does not touch the elements at other indices.updateAt-minimal : ∀ (i j : Fin n) {f : A → A} (xs : Vec A n) →i ≢ j → xs [ i ]= x → (updateAt xs j f) [ i ]= xupdateAt-minimal zero zero (x ∷ xs) 0≢0 here = contradiction refl 0≢0updateAt-minimal zero (suc j) (x ∷ xs) _ here = hereupdateAt-minimal (suc i) zero (x ∷ xs) _ (there loc) = there locupdateAt-minimal (suc i) (suc j) (x ∷ xs) i≢j (there loc) =there (updateAt-minimal i j xs (i≢j ∘ cong suc) loc)-- The other properties are consequences of (+) and (-).-- We spell the most natural properties out.-- Direct inductive proofs are in most cases easier than just using-- the defining properties.-- In the explanations, we make use of shorthand f = g ↾ x-- meaning that f and g agree locally at point x, i.e. f x ≡ g x.-- updateAt i is a morphism from the monoid of endofunctions A → A-- to the monoid of endofunctions Vec A n → Vec A n-- 1a. local identity: f = id ↾ (lookup xs i)-- implies updateAt i f = id ↾ xsupdateAt-id-local : ∀ (i : Fin n) {f : A → A} (xs : Vec A n) →f (lookup xs i) ≡ lookup xs i →updateAt xs i f ≡ xsupdateAt-id-local zero (x ∷ xs) eq = cong (_∷ xs) equpdateAt-id-local (suc i) (x ∷ xs) eq = cong (x ∷_) (updateAt-id-local i xs eq)-- 1b. identity: updateAt i id ≗ idupdateAt-id : ∀ (i : Fin n) (xs : Vec A n) → updateAt xs i id ≡ xsupdateAt-id i xs = updateAt-id-local i xs refl-- 2a. local composition: f ∘ g = h ↾ (lookup xs i)-- implies updateAt i f ∘ updateAt i g = updateAt i h ↾ xsupdateAt-updateAt-local : ∀ (i : Fin n) {f g h : A → A} (xs : Vec A n) →f (g (lookup xs i)) ≡ h (lookup xs i) →updateAt (updateAt xs i g) i f ≡ updateAt xs i hupdateAt-updateAt-local zero (x ∷ xs) fg=h = cong (_∷ xs) fg=hupdateAt-updateAt-local (suc i) (x ∷ xs) fg=h = cong (x ∷_) (updateAt-updateAt-local i xs fg=h)-- 2b. composition: updateAt i f ∘ updateAt i g ≗ updateAt i (f ∘ g)updateAt-updateAt : ∀ (i : Fin n) {f g : A → A} (xs : Vec A n) →updateAt (updateAt xs i g) i f ≡ updateAt xs i (f ∘ g)updateAt-updateAt i xs = updateAt-updateAt-local i xs refl-- 3. congruence: updateAt i is a congruence wrt. extensional equality.-- 3a. If f = g ↾ (lookup xs i)-- then updateAt i f = updateAt i g ↾ xsupdateAt-cong-local : ∀ (i : Fin n) {f g : A → A} (xs : Vec A n) →f (lookup xs i) ≡ g (lookup xs i) →updateAt xs i f ≡ updateAt xs i gupdateAt-cong-local zero (x ∷ xs) f=g = cong (_∷ xs) f=gupdateAt-cong-local (suc i) (x ∷ xs) f=g = cong (x ∷_) (updateAt-cong-local i xs f=g)-- 3b. congruence: f ≗ g → updateAt i f ≗ updateAt i gupdateAt-cong : ∀ (i : Fin n) {f g : A → A} → f ≗ g → (xs : Vec A n) →updateAt xs i f ≡ updateAt xs i gupdateAt-cong i f≗g xs = updateAt-cong-local i xs (f≗g (lookup xs i))-- The order of updates at different indices i ≢ j does not matter.-- This a consequence of updateAt-updates and updateAt-minimal-- but easier to prove inductively.updateAt-commutes : ∀ (i j : Fin n) {f g : A → A} → i ≢ j → (xs : Vec A n) →updateAt (updateAt xs j g) i f ≡ updateAt (updateAt xs i f) j gupdateAt-commutes zero zero 0≢0 (x ∷ xs) = contradiction refl 0≢0updateAt-commutes zero (suc j) i≢j (x ∷ xs) = reflupdateAt-commutes (suc i) zero i≢j (x ∷ xs) = reflupdateAt-commutes (suc i) (suc j) i≢j (x ∷ xs) =cong (x ∷_) (updateAt-commutes i j (i≢j ∘ cong suc) xs)-- lookup after updateAt reduces.-- For same index this is an easy consequence of updateAt-updates-- using []=↔lookup.lookup∘updateAt : ∀ (i : Fin n) {f : A → A} xs →lookup (updateAt xs i f) i ≡ f (lookup xs i)lookup∘updateAt i xs =[]=⇒lookup (updateAt-updates i xs (lookup⇒[]= i _ refl))-- For different indices it easily follows from updateAt-minimal.lookup∘updateAt′ : ∀ (i j : Fin n) {f : A → A} → i ≢ j → ∀ xs →lookup (updateAt xs j f) i ≡ lookup xs ilookup∘updateAt′ i j xs i≢j =[]=⇒lookup (updateAt-minimal i j i≢j xs (lookup⇒[]= i _ refl))-- Aliases for notation _[_]%=_[]%=-id : ∀ (xs : Vec A n) (i : Fin n) → xs [ i ]%= id ≡ xs[]%=-id xs i = updateAt-id i xs[]%=-∘ : ∀ (xs : Vec A n) (i : Fin n) {f g : A → A} →xs [ i ]%= f[ i ]%= g≡ xs [ i ]%= g ∘ f[]%=-∘ xs i = updateAt-updateAt i xs-------------------------------------------------------------------------- _[_]≔_ (update)---- _[_]≔_ is defined in terms of updateAt, and all of its properties-- are special cases of the ones for updateAt.[]≔-idempotent : ∀ (xs : Vec A n) (i : Fin n) →(xs [ i ]≔ x) [ i ]≔ y ≡ xs [ i ]≔ y[]≔-idempotent xs i = updateAt-updateAt i xs[]≔-commutes : ∀ (xs : Vec A n) (i j : Fin n) → i ≢ j →(xs [ i ]≔ x) [ j ]≔ y ≡ (xs [ j ]≔ y) [ i ]≔ x[]≔-commutes xs i j i≢j = updateAt-commutes j i (i≢j ∘ sym) xs[]≔-updates : ∀ (xs : Vec A n) (i : Fin n) → (xs [ i ]≔ x) [ i ]= x[]≔-updates xs i = updateAt-updates i xs (lookup⇒[]= i xs refl)[]≔-minimal : ∀ (xs : Vec A n) (i j : Fin n) → i ≢ j →xs [ i ]= x → (xs [ j ]≔ y) [ i ]= x[]≔-minimal xs i j i≢j loc = updateAt-minimal i j xs i≢j loc[]≔-lookup : ∀ (xs : Vec A n) (i : Fin n) → xs [ i ]≔ lookup xs i ≡ xs[]≔-lookup xs i = updateAt-id-local i xs refl[]≔-++-↑ˡ : ∀ (xs : Vec A m) (ys : Vec A n) i →(xs ++ ys) [ i ↑ˡ n ]≔ x ≡ (xs [ i ]≔ x) ++ ys[]≔-++-↑ˡ (x ∷ xs) ys zero = refl[]≔-++-↑ˡ (x ∷ xs) ys (suc i) =cong (x ∷_) $ []≔-++-↑ˡ xs ys i[]≔-++-↑ʳ : ∀ (xs : Vec A m) (ys : Vec A n) i →(xs ++ ys) [ m ↑ʳ i ]≔ y ≡ xs ++ (ys [ i ]≔ y)[]≔-++-↑ʳ {m = zero} [] (y ∷ ys) i = refl[]≔-++-↑ʳ {m = suc n} (x ∷ xs) (y ∷ ys) i = cong (x ∷_) $ []≔-++-↑ʳ xs (y ∷ ys) ilookup∘update : ∀ (i : Fin n) (xs : Vec A n) x →lookup (xs [ i ]≔ x) i ≡ xlookup∘update i xs x = lookup∘updateAt i xslookup∘update′ : ∀ {i j} → i ≢ j → ∀ (xs : Vec A n) y →lookup (xs [ j ]≔ y) i ≡ lookup xs ilookup∘update′ {i = i} {j} i≢j xs y = lookup∘updateAt′ i j i≢j xs-------------------------------------------------------------------------- castopen VecCast publicusing (cast-is-id; cast-trans)subst-is-cast : (eq : m ≡ n) (xs : Vec A m) → subst (Vec A) eq xs ≡ cast eq xssubst-is-cast refl xs = sym (cast-is-id refl xs)cast-sym : .(eq : m ≡ n) {xs : Vec A m} {ys : Vec A n} →cast eq xs ≡ ys → cast (sym eq) ys ≡ xscast-sym eq {xs = []} {ys = []} _ = reflcast-sym eq {xs = x ∷ xs} {ys = y ∷ ys} xxs[eq]≡yys =let x≡y , xs[eq]≡ys = ∷-injective xxs[eq]≡yysin cong₂ _∷_ (sym x≡y) (cast-sym (suc-injective eq) xs[eq]≡ys)-------------------------------------------------------------------------- mapmap-id : map id ≗ id {A = Vec A n}map-id [] = reflmap-id (x ∷ xs) = cong (x ∷_) (map-id xs)map-const : ∀ (xs : Vec A n) (y : B) → map (const y) xs ≡ replicate n ymap-const [] _ = reflmap-const (_ ∷ xs) y = cong (y ∷_) (map-const xs y)map-cast : (f : A → B) .(eq : m ≡ n) (xs : Vec A m) →map f (cast eq xs) ≡ cast eq (map f xs)map-cast {n = zero} f eq [] = reflmap-cast {n = suc _} f eq (x ∷ xs)= cong (f x ∷_) (map-cast f (suc-injective eq) xs)map-++ : ∀ (f : A → B) (xs : Vec A m) (ys : Vec A n) →map f (xs ++ ys) ≡ map f xs ++ map f ysmap-++ f [] ys = reflmap-++ f (x ∷ xs) ys = cong (f x ∷_) (map-++ f xs ys)map-cong : ∀ {f g : A → B} → f ≗ g → map {n = n} f ≗ map gmap-cong f≗g [] = reflmap-cong f≗g (x ∷ xs) = cong₂ _∷_ (f≗g x) (map-cong f≗g xs)map-∘ : ∀ (f : B → C) (g : A → B) →map {n = n} (f ∘ g) ≗ map f ∘ map gmap-∘ f g [] = reflmap-∘ f g (x ∷ xs) = cong (f (g x) ∷_) (map-∘ f g xs)lookup-map : ∀ (i : Fin n) (f : A → B) (xs : Vec A n) →lookup (map f xs) i ≡ f (lookup xs i)lookup-map zero f (x ∷ xs) = refllookup-map (suc i) f (x ∷ xs) = lookup-map i f xsmap-updateAt : ∀ {f : A → B} {g : A → A} {h : B → B}(xs : Vec A n) (i : Fin n) →f (g (lookup xs i)) ≡ h (f (lookup xs i)) →map f (updateAt xs i g) ≡ updateAt (map f xs) i hmap-updateAt (x ∷ xs) zero eq = cong (_∷ _) eqmap-updateAt (x ∷ xs) (suc i) eq = cong (_ ∷_) (map-updateAt xs i eq)map-insertAt : ∀ (f : A → B) (x : A) (xs : Vec A n) (i : Fin (suc n)) →map f (insertAt xs i x) ≡ insertAt (map f xs) i (f x)map-insertAt f _ [] Fin.zero = reflmap-insertAt f _ (x' ∷ xs) Fin.zero = reflmap-insertAt f x (x' ∷ xs) (Fin.suc i) = cong (_ ∷_) (map-insertAt f x xs i)map-[]≔ : ∀ (f : A → B) (xs : Vec A n) (i : Fin n) →map f (xs [ i ]≔ x) ≡ map f xs [ i ]≔ f xmap-[]≔ f xs i = map-updateAt xs i reflmap-⊛ : ∀ (f : A → B → C) (g : A → B) (xs : Vec A n) →(map f xs ⊛ map g xs) ≡ map (f ˢ g) xsmap-⊛ f g [] = reflmap-⊛ f g (x ∷ xs) = cong (f x (g x) ∷_) (map-⊛ f g xs)toList-map : ∀ (f : A → B) (xs : Vec A n) →toList (map f xs) ≡ List.map f (toList xs)toList-map f [] = refltoList-map f (x ∷ xs) = cong (f x List.∷_) (toList-map f xs)-------------------------------------------------------------------------- _++_-- See also Data.Vec.Properties.WithK.++-assoc.++-injectiveˡ : ∀ {n} (ws xs : Vec A n) → ws ++ ys ≡ xs ++ zs → ws ≡ xs++-injectiveˡ [] [] _ = refl++-injectiveˡ (_ ∷ ws) (_ ∷ xs) eq =cong₂ _∷_ (∷-injectiveˡ eq) (++-injectiveˡ _ _ (∷-injectiveʳ eq))++-injectiveʳ : ∀ {n} (ws xs : Vec A n) → ws ++ ys ≡ xs ++ zs → ys ≡ zs++-injectiveʳ [] [] eq = eq++-injectiveʳ (x ∷ ws) (x′ ∷ xs) eq =++-injectiveʳ ws xs (∷-injectiveʳ eq)++-injective : ∀ (ws xs : Vec A n) →ws ++ ys ≡ xs ++ zs → ws ≡ xs × ys ≡ zs++-injective ws xs eq =(++-injectiveˡ ws xs eq , ++-injectiveʳ ws xs eq)++-assoc : ∀ .(eq : (m + n) + o ≡ m + (n + o)) (xs : Vec A m) (ys : Vec A n) (zs : Vec A o) →cast eq ((xs ++ ys) ++ zs) ≡ xs ++ (ys ++ zs)++-assoc eq [] ys zs = cast-is-id eq (ys ++ zs)++-assoc eq (x ∷ xs) ys zs = cong (x ∷_) (++-assoc (cong pred eq) xs ys zs)++-identityʳ : ∀ .(eq : n + zero ≡ n) (xs : Vec A n) → cast eq (xs ++ []) ≡ xs++-identityʳ eq [] = refl++-identityʳ eq (x ∷ xs) = cong (x ∷_) (++-identityʳ (cong pred eq) xs)cast-++ˡ : ∀ .(eq : m ≡ o) (xs : Vec A m) {ys : Vec A n} →cast (cong (_+ n) eq) (xs ++ ys) ≡ cast eq xs ++ yscast-++ˡ {o = zero} eq [] {ys} = cast-is-id refl (cast eq [] ++ ys)cast-++ˡ {o = suc o} eq (x ∷ xs) {ys} = cong (x ∷_) (cast-++ˡ (cong pred eq) xs)cast-++ʳ : ∀ .(eq : n ≡ o) (xs : Vec A m) {ys : Vec A n} →cast (cong (m +_) eq) (xs ++ ys) ≡ xs ++ cast eq yscast-++ʳ {m = zero} eq [] {ys} = reflcast-++ʳ {m = suc m} eq (x ∷ xs) {ys} = cong (x ∷_) (cast-++ʳ eq xs)lookup-++-< : ∀ (xs : Vec A m) (ys : Vec A n) →∀ i (i<m : toℕ i < m) →lookup (xs ++ ys) i ≡ lookup xs (Fin.fromℕ< i<m)lookup-++-< (x ∷ xs) ys zero _ = refllookup-++-< (x ∷ xs) ys (suc i) si<sm = lookup-++-< xs ys i (s<s⁻¹ si<sm)lookup-++-≥ : ∀ (xs : Vec A m) (ys : Vec A n) →∀ i (i≥m : toℕ i ≥ m) →lookup (xs ++ ys) i ≡ lookup ys (Fin.reduce≥ i i≥m)lookup-++-≥ [] ys i _ = refllookup-++-≥ (x ∷ xs) ys (suc i) si≥sm = lookup-++-≥ xs ys i (s≤s⁻¹ si≥sm)lookup-++ˡ : ∀ (xs : Vec A m) (ys : Vec A n) i →lookup (xs ++ ys) (i ↑ˡ n) ≡ lookup xs ilookup-++ˡ (x ∷ xs) ys zero = refllookup-++ˡ (x ∷ xs) ys (suc i) = lookup-++ˡ xs ys ilookup-++ʳ : ∀ (xs : Vec A m) (ys : Vec A n) i →lookup (xs ++ ys) (m ↑ʳ i) ≡ lookup ys ilookup-++ʳ [] ys zero = refllookup-++ʳ [] (y ∷ xs) (suc i) = lookup-++ʳ [] xs ilookup-++ʳ (x ∷ xs) ys i = lookup-++ʳ xs ys ilookup-splitAt : ∀ m (xs : Vec A m) (ys : Vec A n) i →lookup (xs ++ ys) i ≡ [ lookup xs , lookup ys ]′(Fin.splitAt m i)lookup-splitAt zero [] ys i = refllookup-splitAt (suc m) (x ∷ xs) ys zero = refllookup-splitAt (suc m) (x ∷ xs) ys (suc i) = trans(lookup-splitAt m xs ys i)(sym ([,]-map (Fin.splitAt m i)))toList-++ : (xs : Vec A n) (ys : Vec A m) →toList (xs ++ ys) ≡ toList xs List.++ toList ystoList-++ [] ys = refltoList-++ (x ∷ xs) ys = cong (x List.∷_) (toList-++ xs ys)-------------------------------------------------------------------------- concatlookup-cast : .(eq : m ≡ n) (xs : Vec A m) (i : Fin m) →lookup (cast eq xs) (Fin.cast eq i) ≡ lookup xs ilookup-cast {n = suc _} eq (x ∷ _) zero = refllookup-cast {n = suc _} eq (_ ∷ xs) (suc i) =lookup-cast (suc-injective eq) xs ilookup-cast₁ : .(eq : m ≡ n) (xs : Vec A m) (i : Fin n) →lookup (cast eq xs) i ≡ lookup xs (Fin.cast (sym eq) i)lookup-cast₁ eq (x ∷ _) zero = refllookup-cast₁ eq (_ ∷ xs) (suc i) =lookup-cast₁ (suc-injective eq) xs ilookup-cast₂ : .(eq : m ≡ n) (xs : Vec A n) (i : Fin m) →lookup xs (Fin.cast eq i) ≡ lookup (cast (sym eq) xs) ilookup-cast₂ eq (x ∷ _) zero = refllookup-cast₂ eq (_ ∷ xs) (suc i) =lookup-cast₂ (suc-injective eq) xs ilookup-concat : ∀ (xss : Vec (Vec A m) n) i j →lookup (concat xss) (Fin.combine i j) ≡ lookup (lookup xss i) jlookup-concat (xs ∷ xss) zero j = lookup-++ˡ xs (concat xss) jlookup-concat (xs ∷ xss) (suc i) j = beginlookup (concat (xs ∷ xss)) (Fin.combine (suc i) j)≡⟨ lookup-++ʳ xs (concat xss) (Fin.combine i j) ⟩lookup (concat xss) (Fin.combine i j)≡⟨ lookup-concat xss i j ⟩lookup (lookup (xs ∷ xss) (suc i)) j∎ where open ≡-Reasoning-------------------------------------------------------------------------- zipWithmodule _ {f : A → A → A} wherezipWith-assoc : Associative _≡_ f →Associative _≡_ (zipWith {n = n} f)zipWith-assoc assoc [] [] [] = reflzipWith-assoc assoc (x ∷ xs) (y ∷ ys) (z ∷ zs) =cong₂ _∷_ (assoc x y z) (zipWith-assoc assoc xs ys zs)zipWith-idem : Idempotent _≡_ f →Idempotent _≡_ (zipWith {n = n} f)zipWith-idem idem [] = reflzipWith-idem idem (x ∷ xs) =cong₂ _∷_ (idem x) (zipWith-idem idem xs)module _ {f : A → A → A} {e : A} wherezipWith-identityˡ : LeftIdentity _≡_ e f →LeftIdentity _≡_ (replicate n e) (zipWith f)zipWith-identityˡ idˡ [] = reflzipWith-identityˡ idˡ (x ∷ xs) =cong₂ _∷_ (idˡ x) (zipWith-identityˡ idˡ xs)zipWith-identityʳ : RightIdentity _≡_ e f →RightIdentity _≡_ (replicate n e) (zipWith f)zipWith-identityʳ idʳ [] = reflzipWith-identityʳ idʳ (x ∷ xs) =cong₂ _∷_ (idʳ x) (zipWith-identityʳ idʳ xs)zipWith-zeroˡ : LeftZero _≡_ e f →LeftZero _≡_ (replicate n e) (zipWith f)zipWith-zeroˡ zeˡ [] = reflzipWith-zeroˡ zeˡ (x ∷ xs) =cong₂ _∷_ (zeˡ x) (zipWith-zeroˡ zeˡ xs)zipWith-zeroʳ : RightZero _≡_ e f →RightZero _≡_ (replicate n e) (zipWith f)zipWith-zeroʳ zeʳ [] = reflzipWith-zeroʳ zeʳ (x ∷ xs) =cong₂ _∷_ (zeʳ x) (zipWith-zeroʳ zeʳ xs)module _ {f : A → A → A} {e : A} {⁻¹ : A → A} wherezipWith-inverseˡ : LeftInverse _≡_ e ⁻¹ f →LeftInverse _≡_ (replicate n e) (map ⁻¹) (zipWith f)zipWith-inverseˡ invˡ [] = reflzipWith-inverseˡ invˡ (x ∷ xs) =cong₂ _∷_ (invˡ x) (zipWith-inverseˡ invˡ xs)zipWith-inverseʳ : RightInverse _≡_ e ⁻¹ f →RightInverse _≡_ (replicate n e) (map ⁻¹) (zipWith f)zipWith-inverseʳ invʳ [] = reflzipWith-inverseʳ invʳ (x ∷ xs) =cong₂ _∷_ (invʳ x) (zipWith-inverseʳ invʳ xs)module _ {f g : A → A → A} wherezipWith-distribˡ : _DistributesOverˡ_ _≡_ f g →_DistributesOverˡ_ _≡_ (zipWith {n = n} f) (zipWith g)zipWith-distribˡ distribˡ [] [] [] = reflzipWith-distribˡ distribˡ (x ∷ xs) (y ∷ ys) (z ∷ zs) =cong₂ _∷_ (distribˡ x y z) (zipWith-distribˡ distribˡ xs ys zs)zipWith-distribʳ : _DistributesOverʳ_ _≡_ f g →_DistributesOverʳ_ _≡_ (zipWith {n = n} f) (zipWith g)zipWith-distribʳ distribʳ [] [] [] = reflzipWith-distribʳ distribʳ (x ∷ xs) (y ∷ ys) (z ∷ zs) =cong₂ _∷_ (distribʳ x y z) (zipWith-distribʳ distribʳ xs ys zs)zipWith-absorbs : _Absorbs_ _≡_ f g →_Absorbs_ _≡_ (zipWith {n = n} f) (zipWith g)zipWith-absorbs abs [] [] = reflzipWith-absorbs abs (x ∷ xs) (y ∷ ys) =cong₂ _∷_ (abs x y) (zipWith-absorbs abs xs ys)module _ {f : A → B → C} {g : B → A → C} wherezipWith-comm : ∀ (comm : ∀ x y → f x y ≡ g y x) (xs : Vec A n) ys →zipWith f xs ys ≡ zipWith g ys xszipWith-comm comm [] [] = reflzipWith-comm comm (x ∷ xs) (y ∷ ys) =cong₂ _∷_ (comm x y) (zipWith-comm comm xs ys)zipWith-map₁ : ∀ (_⊕_ : B → C → D) (f : A → B)(xs : Vec A n) (ys : Vec C n) →zipWith _⊕_ (map f xs) ys ≡ zipWith (λ x y → f x ⊕ y) xs yszipWith-map₁ _⊕_ f [] [] = reflzipWith-map₁ _⊕_ f (x ∷ xs) (y ∷ ys) =cong (f x ⊕ y ∷_) (zipWith-map₁ _⊕_ f xs ys)zipWith-map₂ : ∀ (_⊕_ : A → C → D) (f : B → C)(xs : Vec A n) (ys : Vec B n) →zipWith _⊕_ xs (map f ys) ≡ zipWith (λ x y → x ⊕ f y) xs yszipWith-map₂ _⊕_ f [] [] = reflzipWith-map₂ _⊕_ f (x ∷ xs) (y ∷ ys) =cong (x ⊕ f y ∷_) (zipWith-map₂ _⊕_ f xs ys)lookup-zipWith : ∀ (f : A → B → C) (i : Fin n) xs ys →lookup (zipWith f xs ys) i ≡ f (lookup xs i) (lookup ys i)lookup-zipWith _ zero (x ∷ _) (y ∷ _) = refllookup-zipWith _ (suc i) (_ ∷ xs) (_ ∷ ys) = lookup-zipWith _ i xs yszipWith-++ : ∀ (f : A → B → C)(xs : Vec A n) (ys : Vec A m)(xs' : Vec B n) (ys' : Vec B m) →zipWith f (xs ++ ys) (xs' ++ ys') ≡zipWith f xs xs' ++ zipWith f ys ys'zipWith-++ f [] ys [] ys' = reflzipWith-++ f (x ∷ xs) ys (x' ∷ xs') ys' =cong (_ ∷_) (zipWith-++ f xs ys xs' ys')-------------------------------------------------------------------------- ziplookup-zip : ∀ (i : Fin n) (xs : Vec A n) (ys : Vec B n) →lookup (zip xs ys) i ≡ (lookup xs i , lookup ys i)lookup-zip = lookup-zipWith _,_-- map lifts projections to vectors of products.map-proj₁-zip : ∀ (xs : Vec A n) (ys : Vec B n) →map proj₁ (zip xs ys) ≡ xsmap-proj₁-zip [] [] = reflmap-proj₁-zip (x ∷ xs) (y ∷ ys) = cong (x ∷_) (map-proj₁-zip xs ys)map-proj₂-zip : ∀ (xs : Vec A n) (ys : Vec B n) →map proj₂ (zip xs ys) ≡ ysmap-proj₂-zip [] [] = reflmap-proj₂-zip (x ∷ xs) (y ∷ ys) = cong (y ∷_) (map-proj₂-zip xs ys)-- map lifts pairing to vectors of products.map-<,>-zip : ∀ (f : A → B) (g : A → C) (xs : Vec A n) →map < f , g > xs ≡ zip (map f xs) (map g xs)map-<,>-zip f g [] = reflmap-<,>-zip f g (x ∷ xs) = cong (_ ∷_) (map-<,>-zip f g xs)map-zip : ∀ (f : A → B) (g : C → D) (xs : Vec A n) (ys : Vec C n) →map (Product.map f g) (zip xs ys) ≡ zip (map f xs) (map g ys)map-zip f g [] [] = reflmap-zip f g (x ∷ xs) (y ∷ ys) = cong (_ ∷_) (map-zip f g xs ys)-------------------------------------------------------------------------- unziplookup-unzip : ∀ (i : Fin n) (xys : Vec (A × B) n) →let xs , ys = unzip xysin (lookup xs i , lookup ys i) ≡ lookup xys ilookup-unzip () []lookup-unzip zero ((x , y) ∷ xys) = refllookup-unzip (suc i) ((x , y) ∷ xys) = lookup-unzip i xysmap-unzip : ∀ (f : A → B) (g : C → D) (xys : Vec (A × C) n) →let xs , ys = unzip xysin (map f xs , map g ys) ≡ unzip (map (Product.map f g) xys)map-unzip f g [] = reflmap-unzip f g ((x , y) ∷ xys) =cong (Product.map (f x ∷_) (g y ∷_)) (map-unzip f g xys)-- Products of vectors are isomorphic to vectors of products.unzip∘zip : ∀ (xs : Vec A n) (ys : Vec B n) →unzip (zip xs ys) ≡ (xs , ys)unzip∘zip [] [] = reflunzip∘zip (x ∷ xs) (y ∷ ys) =cong (Product.map (x ∷_) (y ∷_)) (unzip∘zip xs ys)zip∘unzip : ∀ (xys : Vec (A × B) n) → uncurry zip (unzip xys) ≡ xyszip∘unzip [] = reflzip∘unzip (xy ∷ xys) = cong (xy ∷_) (zip∘unzip xys)×v↔v× : (Vec A n × Vec B n) ↔ Vec (A × B) n×v↔v× = mk↔ₛ′ (uncurry zip) unzip zip∘unzip (uncurry unzip∘zip)-------------------------------------------------------------------------- _⊛_lookup-⊛ : ∀ i (fs : Vec (A → B) n) (xs : Vec A n) →lookup (fs ⊛ xs) i ≡ (lookup fs i $ lookup xs i)lookup-⊛ zero (f ∷ fs) (x ∷ xs) = refllookup-⊛ (suc i) (f ∷ fs) (x ∷ xs) = lookup-⊛ i fs xsmap-is-⊛ : ∀ (f : A → B) (xs : Vec A n) →map f xs ≡ (replicate n f ⊛ xs)map-is-⊛ f [] = reflmap-is-⊛ f (x ∷ xs) = cong (_ ∷_) (map-is-⊛ f xs)⊛-is-zipWith : ∀ (fs : Vec (A → B) n) (xs : Vec A n) →(fs ⊛ xs) ≡ zipWith _$_ fs xs⊛-is-zipWith [] [] = refl⊛-is-zipWith (f ∷ fs) (x ∷ xs) = cong (f x ∷_) (⊛-is-zipWith fs xs)zipWith-is-⊛ : ∀ (f : A → B → C) (xs : Vec A n) (ys : Vec B n) →zipWith f xs ys ≡ (replicate n f ⊛ xs ⊛ ys)zipWith-is-⊛ f [] [] = reflzipWith-is-⊛ f (x ∷ xs) (y ∷ ys) = cong (_ ∷_) (zipWith-is-⊛ f xs ys)⊛-is->>= : ∀ (fs : Vec (A → B) n) (xs : Vec A n) →(fs ⊛ xs) ≡ (fs DiagonalBind.>>= flip map xs)⊛-is->>= [] [] = refl⊛-is->>= (f ∷ fs) (x ∷ xs) = cong (f x ∷_) $ beginfs ⊛ xs ≡⟨ ⊛-is->>= fs xs ⟩diagonal (map (flip map xs) fs) ≡⟨⟩diagonal (map (tail ∘ flip map (x ∷ xs)) fs) ≡⟨ cong diagonal (map-∘ _ _ _) ⟩diagonal (map tail (map (flip map (x ∷ xs)) fs)) ∎where open ≡-Reasoning-------------------------------------------------------------------------- _⊛*_lookup-⊛* : ∀ (fs : Vec (A → B) m) (xs : Vec A n) i j →lookup (fs ⊛* xs) (Fin.combine i j) ≡ (lookup fs i $ lookup xs j)lookup-⊛* (f ∷ fs) xs zero j = trans (lookup-++ˡ (map f xs) _ j) (lookup-map j f xs)lookup-⊛* (f ∷ fs) xs (suc i) j = trans (lookup-++ʳ (map f xs) _ (Fin.combine i j)) (lookup-⊛* fs xs i j)-------------------------------------------------------------------------- foldl-- The (uniqueness part of the) universality property for foldl.foldl-universal : ∀ (B : ℕ → Set b) (f : FoldlOp A B) e(h : ∀ {c} (C : ℕ → Set c) (g : FoldlOp A C) (e : C zero) →∀ {n} → Vec A n → C n) →(∀ {c} {C} {g : FoldlOp A C} e → h {c} C g e [] ≡ e) →(∀ {c} {C} {g : FoldlOp A C} e {n} x →(h {c} C g e {suc n}) ∘ (x ∷_) ≗ h (C ∘ suc) g (g e x)) →h B f e ≗ foldl {n = n} B f efoldl-universal B f e h base step [] = base efoldl-universal B f e h base step (x ∷ xs) = beginh B f e (x ∷ xs) ≡⟨ step e x xs ⟩h (B ∘ suc) f (f e x) xs ≡⟨ foldl-universal _ f (f e x) h base step xs ⟩foldl (B ∘ suc) f (f e x) xs ≡⟨⟩foldl B f e (x ∷ xs) ∎where open ≡-Reasoningfoldl-fusion : ∀ {B : ℕ → Set b} {C : ℕ → Set c}(h : ∀ {n} → B n → C n) →{f : FoldlOp A B} {d : B zero} →{g : FoldlOp A C} {e : C zero} →(h d ≡ e) →(∀ {n} b x → h (f {n} b x) ≡ g (h b) x) →h ∘ foldl {n = n} B f d ≗ foldl C g efoldl-fusion h {f} {d} {g} {e} base fuse [] = basefoldl-fusion h {f} {d} {g} {e} base fuse (x ∷ xs) =foldl-fusion h eq fuse xswhereopen ≡-Reasoningeq : h (f d x) ≡ g e xeq = beginh (f d x) ≡⟨ fuse d x ⟩g (h d) x ≡⟨ cong (λ e → g e x) base ⟩g e x ∎foldl-[] : ∀ (B : ℕ → Set b) (f : FoldlOp A B) {e} → foldl B f e [] ≡ efoldl-[] _ _ = refl-------------------------------------------------------------------------- foldr-- See also Data.Vec.Properties.WithK.foldr-cong.-- The (uniqueness part of the) universality property for foldr.module _ (B : ℕ → Set b) (f : FoldrOp A B) {e : B zero} wherefoldr-universal : (h : ∀ {n} → Vec A n → B n) →h [] ≡ e →(∀ {n} x → h ∘ (x ∷_) ≗ f {n} x ∘ h) →h ≗ foldr {n = n} B f efoldr-universal h base step [] = basefoldr-universal h base step (x ∷ xs) = beginh (x ∷ xs) ≡⟨ step x xs ⟩f x (h xs) ≡⟨ cong (f x) (foldr-universal h base step xs) ⟩f x (foldr B f e xs) ∎where open ≡-Reasoningfoldr-[] : foldr B f e [] ≡ efoldr-[] = reflfoldr-++ : ∀ (xs : Vec A m) →foldr B f e (xs ++ ys) ≡ foldr (B ∘ (_+ n)) f (foldr B f e ys) xsfoldr-++ [] = reflfoldr-++ (x ∷ xs) = cong (f x) (foldr-++ xs)-- fusion and identity as consequences of universalityfoldr-fusion : ∀ {B : ℕ → Set b} {f : FoldrOp A B} e{C : ℕ → Set c} {g : FoldrOp A C}(h : ∀ {n} → B n → C n) →(∀ {n} x → h ∘ f {n} x ≗ g x ∘ h) →h ∘ foldr {n = n} B f e ≗ foldr C g (h e)foldr-fusion {B = B} {f} e {C} h fuse =foldr-universal C _ _ refl (λ x xs → fuse x (foldr B f e xs))id-is-foldr : id ≗ foldr {n = n} (Vec A) _∷_ []id-is-foldr = foldr-universal _ _ id refl (λ _ _ → refl)map-is-foldr : ∀ (f : A → B) →map {n = n} f ≗ foldr (Vec B) (λ x ys → f x ∷ ys) []map-is-foldr f = foldr-universal (Vec _) (λ x ys → f x ∷ ys) (map f) refl (λ _ _ → refl)++-is-foldr : ∀ (xs : Vec A m) →xs ++ ys ≡ foldr (Vec A ∘ (_+ n)) _∷_ ys xs++-is-foldr {A = A} {n = n} {ys} xs =foldr-universal (Vec A ∘ (_+ n)) _∷_ (_++ ys) refl (λ _ _ → refl) xs-------------------------------------------------------------------------- _∷ʳ_-- snoc is snocunfold-∷ʳ : ∀ .(eq : suc n ≡ n + 1) x (xs : Vec A n) → cast eq (xs ∷ʳ x) ≡ xs ++ [ x ]unfold-∷ʳ eq x [] = reflunfold-∷ʳ eq x (y ∷ xs) = cong (y ∷_) (unfold-∷ʳ (cong pred eq) x xs)∷ʳ-injective : ∀ (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y∷ʳ-injective [] [] refl = (refl , refl)∷ʳ-injective (x ∷ xs) (y ∷ ys) eq with ∷-injective eq... | refl , eq′ = Product.map₁ (cong (x ∷_)) (∷ʳ-injective xs ys eq′)∷ʳ-injectiveˡ : ∀ (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys∷ʳ-injectiveˡ xs ys eq = proj₁ (∷ʳ-injective xs ys eq)∷ʳ-injectiveʳ : ∀ (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y∷ʳ-injectiveʳ xs ys eq = proj₂ (∷ʳ-injective xs ys eq)foldl-∷ʳ : ∀ (B : ℕ → Set b) (f : FoldlOp A B) e y (ys : Vec A n) →foldl B f e (ys ∷ʳ y) ≡ f (foldl B f e ys) yfoldl-∷ʳ B f e y [] = reflfoldl-∷ʳ B f e y (x ∷ xs) = foldl-∷ʳ (B ∘ suc) f (f e x) y xsfoldr-∷ʳ : ∀ (B : ℕ → Set b) (f : FoldrOp A B) {e} y (ys : Vec A n) →foldr B f e (ys ∷ʳ y) ≡ foldr (B ∘ suc) f (f y e) ysfoldr-∷ʳ B f y [] = reflfoldr-∷ʳ B f y (x ∷ xs) = cong (f x) (foldr-∷ʳ B f y xs)-- init, last and _∷ʳ_init-∷ʳ : ∀ x (xs : Vec A n) → init (xs ∷ʳ x) ≡ xsinit-∷ʳ x [] = reflinit-∷ʳ x (y ∷ xs) = cong (y ∷_) (init-∷ʳ x xs)last-∷ʳ : ∀ x (xs : Vec A n) → last (xs ∷ʳ x) ≡ xlast-∷ʳ x [] = refllast-∷ʳ x (y ∷ xs) = last-∷ʳ x xs-- map and _∷ʳ_map-∷ʳ : ∀ (f : A → B) x (xs : Vec A n) → map f (xs ∷ʳ x) ≡ map f xs ∷ʳ f xmap-∷ʳ f x [] = reflmap-∷ʳ f x (y ∷ xs) = cong (f y ∷_) (map-∷ʳ f x xs)-- cast and _∷ʳ_cast-∷ʳ : ∀ .(eq : suc n ≡ suc m) x (xs : Vec A n) →cast eq (xs ∷ʳ x) ≡ (cast (cong pred eq) xs) ∷ʳ xcast-∷ʳ {m = zero} eq x [] = reflcast-∷ʳ {m = suc m} eq x (y ∷ xs) = cong (y ∷_) (cast-∷ʳ (cong pred eq) x xs)-- _++_ and _∷ʳ_++-∷ʳ : ∀ .(eq : suc (m + n) ≡ m + suc n) z (xs : Vec A m) (ys : Vec A n) →cast eq ((xs ++ ys) ∷ʳ z) ≡ xs ++ (ys ∷ʳ z)++-∷ʳ {m = zero} eq z [] [] = refl++-∷ʳ {m = zero} eq z [] (y ∷ ys) = cong (y ∷_) (++-∷ʳ refl z [] ys)++-∷ʳ {m = suc m} eq z (x ∷ xs) ys = cong (x ∷_) (++-∷ʳ (cong pred eq) z xs ys)∷ʳ-++ : ∀ .(eq : (suc n) + m ≡ n + suc m) a (xs : Vec A n) {ys} →cast eq ((xs ∷ʳ a) ++ ys) ≡ xs ++ (a ∷ ys)∷ʳ-++ eq a [] {ys} = cong (a ∷_) (cast-is-id (cong pred eq) ys)∷ʳ-++ eq a (x ∷ xs) {ys} = cong (x ∷_) (∷ʳ-++ (cong pred eq) a xs)-------------------------------------------------------------------------- reverse-- reverse of cons is snoc of reverse.reverse-∷ : ∀ x (xs : Vec A n) → reverse (x ∷ xs) ≡ reverse xs ∷ʳ xreverse-∷ x xs = sym (foldl-fusion (_∷ʳ x) refl (λ b x → refl) xs)-- foldl after a reverse is a foldrfoldl-reverse : ∀ (B : ℕ → Set b) (f : FoldlOp A B) {e} →foldl {n = n} B f e ∘ reverse ≗ foldr B (flip f) efoldl-reverse _ _ {e} [] = reflfoldl-reverse B f {e} (x ∷ xs) = beginfoldl B f e (reverse (x ∷ xs)) ≡⟨ cong (foldl B f e) (reverse-∷ x xs) ⟩foldl B f e (reverse xs ∷ʳ x) ≡⟨ foldl-∷ʳ B f e x (reverse xs) ⟩f (foldl B f e (reverse xs)) x ≡⟨ cong (flip f x) (foldl-reverse B f xs) ⟩f (foldr B (flip f) e xs) x ≡⟨⟩foldr B (flip f) e (x ∷ xs) ∎where open ≡-Reasoning-- foldr after a reverse is a foldlfoldr-reverse : ∀ (B : ℕ → Set b) (f : FoldrOp A B) {e} →foldr {n = n} B f e ∘ reverse ≗ foldl B (flip f) efoldr-reverse B f {e} xs = foldl-fusion (foldr B f e) refl (λ _ _ → refl) xs-- reverse is involutive.reverse-involutive : Involutive {A = Vec A n} _≡_ reversereverse-involutive xs = beginreverse (reverse xs) ≡⟨ foldl-reverse (Vec _) (flip _∷_) xs ⟩foldr (Vec _) _∷_ [] xs ≡⟨ id-is-foldr xs ⟨xs ∎where open ≡-Reasoningreverse-reverse : reverse xs ≡ ys → reverse ys ≡ xsreverse-reverse {xs = xs} {ys} eq = beginreverse ys ≡⟨ cong reverse eq ⟨reverse (reverse xs) ≡⟨ reverse-involutive xs ⟩xs ∎where open ≡-Reasoning-- reverse is injective.reverse-injective : reverse xs ≡ reverse ys → xs ≡ ysreverse-injective {xs = xs} {ys} eq = beginxs ≡⟨ reverse-reverse eq ⟨reverse (reverse ys) ≡⟨ reverse-involutive ys ⟩ys ∎where open ≡-Reasoning-- init and last of reverseinit-reverse : init ∘ reverse ≗ reverse ∘ tail {A = A} {n = n}init-reverse (x ∷ xs) = begininit (reverse (x ∷ xs)) ≡⟨ cong init (reverse-∷ x xs) ⟩init (reverse xs ∷ʳ x) ≡⟨ init-∷ʳ x (reverse xs) ⟩reverse xs ∎where open ≡-Reasoninglast-reverse : last ∘ reverse ≗ head {A = A} {n = n}last-reverse (x ∷ xs) = beginlast (reverse (x ∷ xs)) ≡⟨ cong last (reverse-∷ x xs) ⟩last (reverse xs ∷ʳ x) ≡⟨ last-∷ʳ x (reverse xs) ⟩x ∎where open ≡-Reasoning-- map and reversemap-reverse : ∀ (f : A → B) (xs : Vec A n) →map f (reverse xs) ≡ reverse (map f xs)map-reverse f [] = reflmap-reverse f (x ∷ xs) = beginmap f (reverse (x ∷ xs)) ≡⟨ cong (map f) (reverse-∷ x xs) ⟩map f (reverse xs ∷ʳ x) ≡⟨ map-∷ʳ f x (reverse xs) ⟩map f (reverse xs) ∷ʳ f x ≡⟨ cong (_∷ʳ f x) (map-reverse f xs ) ⟩reverse (map f xs) ∷ʳ f x ≡⟨ reverse-∷ (f x) (map f xs) ⟨reverse (f x ∷ map f xs) ≡⟨⟩reverse (map f (x ∷ xs)) ∎where open ≡-Reasoning-- append and reversereverse-++ : ∀ .(eq : m + n ≡ n + m) (xs : Vec A m) (ys : Vec A n) →cast eq (reverse (xs ++ ys)) ≡ reverse ys ++ reverse xsreverse-++ {m = zero} {n = n} eq [] ys = ≈-sym (++-identityʳ (sym eq) (reverse ys))reverse-++ {m = suc m} {n = n} eq (x ∷ xs) ys = beginreverse (x ∷ xs ++ ys) ≂⟨ reverse-∷ x (xs ++ ys) ⟩reverse (xs ++ ys) ∷ʳ x ≈⟨ ≈-cong (_∷ʳ x) (cast-∷ʳ (cong suc (+-comm m n)) x (reverse (xs ++ ys)))(reverse-++ _ xs ys) ⟩(reverse ys ++ reverse xs) ∷ʳ x ≈⟨ ++-∷ʳ (sym (+-suc n m)) x (reverse ys) (reverse xs) ⟩reverse ys ++ (reverse xs ∷ʳ x) ≂⟨ cong (reverse ys ++_) (reverse-∷ x xs) ⟨reverse ys ++ (reverse (x ∷ xs)) ∎where open CastReasoningcast-reverse : ∀ .(eq : m ≡ n) → cast eq ∘ reverse {A = A} {n = m} ≗ reverse ∘ cast eqcast-reverse {n = zero} eq [] = reflcast-reverse {n = suc n} eq (x ∷ xs) = beginreverse (x ∷ xs) ≂⟨ reverse-∷ x xs ⟩reverse xs ∷ʳ x ≈⟨ ≈-cong (_∷ʳ x) (cast-∷ʳ eq x (reverse xs))(cast-reverse (cong pred eq) xs) ⟩reverse (cast _ xs) ∷ʳ x ≂⟨ reverse-∷ x (cast (cong pred eq) xs) ⟨reverse (x ∷ cast _ xs) ≈⟨⟩reverse (cast eq (x ∷ xs)) ∎where open CastReasoning-------------------------------------------------------------------------- _ʳ++_-- reverse-append is append of reverse.unfold-ʳ++ : ∀ (xs : Vec A m) (ys : Vec A n) → xs ʳ++ ys ≡ reverse xs ++ ysunfold-ʳ++ xs ys = sym (foldl-fusion (_++ ys) refl (λ b x → refl) xs)-- foldr after a reverse-append is a foldlfoldr-ʳ++ : ∀ (B : ℕ → Set b) (f : FoldrOp A B) {e}(xs : Vec A m) {ys : Vec A n} →foldr B f e (xs ʳ++ ys) ≡foldl (B ∘ (_+ n)) (flip f) (foldr B f e ys) xsfoldr-ʳ++ B f {e} xs = foldl-fusion (foldr B f e) refl (λ _ _ → refl) xs-- map and _ʳ++_map-ʳ++ : ∀ (f : A → B) (xs : Vec A m) →map f (xs ʳ++ ys) ≡ map f xs ʳ++ map f ysmap-ʳ++ {ys = ys} f xs = beginmap f (xs ʳ++ ys) ≡⟨ cong (map f) (unfold-ʳ++ xs ys) ⟩map f (reverse xs ++ ys) ≡⟨ map-++ f (reverse xs) ys ⟩map f (reverse xs) ++ map f ys ≡⟨ cong (_++ map f ys) (map-reverse f xs) ⟩reverse (map f xs) ++ map f ys ≡⟨ unfold-ʳ++ (map f xs) (map f ys) ⟨map f xs ʳ++ map f ys ∎where open ≡-Reasoning∷-ʳ++ : ∀ .(eq : (suc m) + n ≡ m + suc n) a (xs : Vec A m) {ys} →cast eq ((a ∷ xs) ʳ++ ys) ≡ xs ʳ++ (a ∷ ys)∷-ʳ++ eq a xs {ys} = begin(a ∷ xs) ʳ++ ys ≂⟨ unfold-ʳ++ (a ∷ xs) ys ⟩reverse (a ∷ xs) ++ ys ≂⟨ cong (_++ ys) (reverse-∷ a xs) ⟩(reverse xs ∷ʳ a) ++ ys ≈⟨ ∷ʳ-++ eq a (reverse xs) ⟩reverse xs ++ (a ∷ ys) ≂⟨ unfold-ʳ++ xs (a ∷ ys) ⟨xs ʳ++ (a ∷ ys) ∎where open CastReasoning++-ʳ++ : ∀ .(eq : m + n + o ≡ n + (m + o)) (xs : Vec A m) {ys : Vec A n} {zs : Vec A o} →cast eq ((xs ++ ys) ʳ++ zs) ≡ ys ʳ++ (xs ʳ++ zs)++-ʳ++ {m = m} {n} {o} eq xs {ys} {zs} = begin((xs ++ ys) ʳ++ zs) ≂⟨ unfold-ʳ++ (xs ++ ys) zs ⟩reverse (xs ++ ys) ++ zs ≈⟨ ≈-cong (_++ zs) (cast-++ˡ (+-comm m n) (reverse (xs ++ ys)))(reverse-++ (+-comm m n) xs ys) ⟩(reverse ys ++ reverse xs) ++ zs ≈⟨ ++-assoc (trans (cong (_+ o) (+-comm n m)) eq) (reverse ys) (reverse xs) zs ⟩reverse ys ++ (reverse xs ++ zs) ≂⟨ cong (reverse ys ++_) (unfold-ʳ++ xs zs) ⟨reverse ys ++ (xs ʳ++ zs) ≂⟨ unfold-ʳ++ ys (xs ʳ++ zs) ⟨ys ʳ++ (xs ʳ++ zs) ∎where open CastReasoningʳ++-ʳ++ : ∀ .(eq : (m + n) + o ≡ n + (m + o)) (xs : Vec A m) {ys : Vec A n} {zs} →cast eq ((xs ʳ++ ys) ʳ++ zs) ≡ ys ʳ++ (xs ++ zs)ʳ++-ʳ++ {m = m} {n} {o} eq xs {ys} {zs} = begin(xs ʳ++ ys) ʳ++ zs ≂⟨ cong (_ʳ++ zs) (unfold-ʳ++ xs ys) ⟩(reverse xs ++ ys) ʳ++ zs ≂⟨ unfold-ʳ++ (reverse xs ++ ys) zs ⟩reverse (reverse xs ++ ys) ++ zs ≈⟨ ≈-cong (_++ zs) (cast-++ˡ (+-comm m n) (reverse (reverse xs ++ ys)))(reverse-++ (+-comm m n) (reverse xs) ys) ⟩(reverse ys ++ reverse (reverse xs)) ++ zs ≂⟨ cong ((_++ zs) ∘ (reverse ys ++_)) (reverse-involutive xs) ⟩(reverse ys ++ xs) ++ zs ≈⟨ ++-assoc (+-assoc n m o) (reverse ys) xs zs ⟩reverse ys ++ (xs ++ zs) ≂⟨ unfold-ʳ++ ys (xs ++ zs) ⟨ys ʳ++ (xs ++ zs) ∎where open CastReasoning-------------------------------------------------------------------------- sumsum-++ : ∀ (xs : Vec ℕ m) → sum (xs ++ ys) ≡ sum xs + sum yssum-++ {_} [] = reflsum-++ {ys = ys} (x ∷ xs) = beginx + sum (xs ++ ys) ≡⟨ cong (x +_) (sum-++ xs) ⟩x + (sum xs + sum ys) ≡⟨ +-assoc x (sum xs) (sum ys) ⟨sum (x ∷ xs) + sum ys ∎where open ≡-Reasoning-------------------------------------------------------------------------- replicatelookup-replicate : ∀ (i : Fin n) (x : A) → lookup (replicate n x) i ≡ xlookup-replicate zero x = refllookup-replicate (suc i) x = lookup-replicate i xmap-replicate : ∀ (f : A → B) (x : A) n →map f (replicate n x) ≡ replicate n (f x)map-replicate f x zero = reflmap-replicate f x (suc n) = cong (f x ∷_) (map-replicate f x n)transpose-replicate : ∀ (xs : Vec A m) →transpose (replicate n xs) ≡ map (replicate n) xstranspose-replicate {n = zero} _ = sym (map-const _ [])transpose-replicate {n = suc n} xs = begintranspose (replicate (suc n) xs) ≡⟨⟩(replicate _ _∷_ ⊛ xs ⊛ transpose (replicate _ xs)) ≡⟨ cong₂ _⊛_ (sym (map-is-⊛ _∷_ xs)) (transpose-replicate xs) ⟩(map _∷_ xs ⊛ map (replicate n) xs) ≡⟨ map-⊛ _∷_ (replicate n) xs ⟩map (replicate (suc n)) xs ∎where open ≡-ReasoningzipWith-replicate : ∀ (_⊕_ : A → B → C) (x : A) (y : B) →zipWith _⊕_ (replicate n x) (replicate n y) ≡ replicate n (x ⊕ y)zipWith-replicate {n = zero} _⊕_ x y = reflzipWith-replicate {n = suc n} _⊕_ x y = cong (x ⊕ y ∷_) (zipWith-replicate _⊕_ x y)zipWith-replicate₁ : ∀ (_⊕_ : A → B → C) (x : A) (ys : Vec B n) →zipWith _⊕_ (replicate n x) ys ≡ map (x ⊕_) yszipWith-replicate₁ _⊕_ x [] = reflzipWith-replicate₁ _⊕_ x (y ∷ ys) =cong (x ⊕ y ∷_) (zipWith-replicate₁ _⊕_ x ys)zipWith-replicate₂ : ∀ (_⊕_ : A → B → C) (xs : Vec A n) (y : B) →zipWith _⊕_ xs (replicate n y) ≡ map (_⊕ y) xszipWith-replicate₂ _⊕_ [] y = reflzipWith-replicate₂ _⊕_ (x ∷ xs) y =cong (x ⊕ y ∷_) (zipWith-replicate₂ _⊕_ xs y)toList-replicate : ∀ (n : ℕ) (x : A) →toList (replicate n x) ≡ List.replicate n xtoList-replicate zero x = refltoList-replicate (suc n) x = cong (_ List.∷_) (toList-replicate n x)-------------------------------------------------------------------------- iterateiterate-id : ∀ (x : A) n → iterate id x n ≡ replicate n xiterate-id x zero = refliterate-id x (suc n) = cong (_ ∷_) (iterate-id (id x) n)take-iterate : ∀ n f (x : A) → take n (iterate f x (n + m)) ≡ iterate f x ntake-iterate zero f x = refltake-iterate (suc n) f x = cong (_ ∷_) (take-iterate n f (f x))drop-iterate : ∀ n f (x : A) → drop n (iterate f x (n + zero)) ≡ []drop-iterate zero f x = refldrop-iterate (suc n) f x = drop-iterate n f (f x)lookup-iterate : ∀ f (x : A) (i : Fin n) → lookup (iterate f x n) i ≡ ℕ.iterate f x (toℕ i)lookup-iterate f x zero = refllookup-iterate f x (suc i) = lookup-iterate f (f x) itoList-iterate : ∀ f (x : A) n → toList (iterate f x n) ≡ List.iterate f x ntoList-iterate f x zero = refltoList-iterate f x (suc n) = cong (_ List.∷_) (toList-iterate f (f x) n)-------------------------------------------------------------------------- tabulatelookup∘tabulate : ∀ (f : Fin n → A) (i : Fin n) →lookup (tabulate f) i ≡ f ilookup∘tabulate f zero = refllookup∘tabulate f (suc i) = lookup∘tabulate (f ∘ suc) itabulate∘lookup : ∀ (xs : Vec A n) → tabulate (lookup xs) ≡ xstabulate∘lookup [] = refltabulate∘lookup (x ∷ xs) = cong (x ∷_) (tabulate∘lookup xs)tabulate-∘ : ∀ (f : A → B) (g : Fin n → A) →tabulate (f ∘ g) ≡ map f (tabulate g)tabulate-∘ {n = zero} f g = refltabulate-∘ {n = suc n} f g = cong (f (g zero) ∷_) (tabulate-∘ f (g ∘ suc))tabulate-cong : ∀ {f g : Fin n → A} → f ≗ g → tabulate f ≡ tabulate gtabulate-cong {n = zero} p = refltabulate-cong {n = suc n} p = cong₂ _∷_ (p zero) (tabulate-cong (p ∘ suc))-------------------------------------------------------------------------- allFinlookup-allFin : ∀ (i : Fin n) → lookup (allFin n) i ≡ ilookup-allFin = lookup∘tabulate idallFin-map : ∀ n → allFin (suc n) ≡ zero ∷ map suc (allFin n)allFin-map n = cong (zero ∷_) $ tabulate-∘ suc idtabulate-allFin : ∀ (f : Fin n → A) → tabulate f ≡ map f (allFin n)tabulate-allFin f = tabulate-∘ f id-- If you look up every possible index, in increasing order, then you-- get back the vector you started with.map-lookup-allFin : ∀ (xs : Vec A n) → map (lookup xs) (allFin n) ≡ xsmap-lookup-allFin {n = n} xs = beginmap (lookup xs) (allFin n) ≡⟨ tabulate-∘ (lookup xs) id ⟨tabulate (lookup xs) ≡⟨ tabulate∘lookup xs ⟩xs ∎where open ≡-Reasoning-------------------------------------------------------------------------- countmodule _ {P : Pred A p} (P? : Decidable P) wherecount≤n : ∀ (xs : Vec A n) → count P? xs ≤ ncount≤n [] = z≤ncount≤n (x ∷ xs) with does (P? x)... | true = s≤s (count≤n xs)... | false = m≤n⇒m≤1+n (count≤n xs)-------------------------------------------------------------------------- lengthlength-toList : (xs : Vec A n) → List.length (toList xs) ≡ length xslength-toList [] = refllength-toList (x ∷ xs) = cong suc (length-toList xs)-------------------------------------------------------------------------- insertAtinsertAt-lookup : ∀ (xs : Vec A n) (i : Fin (suc n)) (v : A) →lookup (insertAt xs i v) i ≡ vinsertAt-lookup xs zero v = reflinsertAt-lookup (x ∷ xs) (suc i) v = insertAt-lookup xs i vinsertAt-punchIn : ∀ (xs : Vec A n) (i : Fin (suc n)) (v : A) (j : Fin n) →lookup (insertAt xs i v) (Fin.punchIn i j) ≡ lookup xs jinsertAt-punchIn xs zero v j = reflinsertAt-punchIn (x ∷ xs) (suc i) v zero = reflinsertAt-punchIn (x ∷ xs) (suc i) v (suc j) = insertAt-punchIn xs i v jtoList-insertAt : ∀ (xs : Vec A n) (i : Fin (suc n)) (v : A) →toList (insertAt xs i v) ≡ List.insertAt (toList xs) (Fin.cast (cong suc (sym (length-toList xs))) i) vtoList-insertAt xs zero v = refltoList-insertAt (x ∷ xs) (suc i) v = cong (_ List.∷_) (toList-insertAt xs i v)-------------------------------------------------------------------------- removeAtremoveAt-punchOut : ∀ (xs : Vec A (suc n)) {i} {j} (i≢j : i ≢ j) →lookup (removeAt xs i) (Fin.punchOut i≢j) ≡ lookup xs jremoveAt-punchOut (x ∷ xs) {zero} {zero} i≢j = contradiction refl i≢jremoveAt-punchOut (x ∷ xs) {zero} {suc j} i≢j = reflremoveAt-punchOut (x ∷ y ∷ xs) {suc i} {zero} i≢j = reflremoveAt-punchOut (x ∷ y ∷ xs) {suc i} {suc j} i≢j =removeAt-punchOut (y ∷ xs) (i≢j ∘ cong suc)-------------------------------------------------------------------------- insertAt and removeAtremoveAt-insertAt : ∀ (xs : Vec A n) (i : Fin (suc n)) (v : A) →removeAt (insertAt xs i v) i ≡ xsremoveAt-insertAt xs zero v = reflremoveAt-insertAt (x ∷ xs) (suc zero) v = reflremoveAt-insertAt (x ∷ xs@(_ ∷ _)) (suc (suc i)) v =cong (x ∷_) (removeAt-insertAt xs (suc i) v)insertAt-removeAt : ∀ (xs : Vec A (suc n)) (i : Fin (suc n)) →insertAt (removeAt xs i) i (lookup xs i) ≡ xsinsertAt-removeAt (x ∷ xs) zero = reflinsertAt-removeAt (x ∷ xs@(_ ∷ _)) (suc i) =cong (x ∷_) (insertAt-removeAt xs i)-------------------------------------------------------------------------- Conversion functiontoList∘fromList : (xs : List A) → toList (fromList xs) ≡ xstoList∘fromList List.[] = refltoList∘fromList (x List.∷ xs) = cong (x List.∷_) (toList∘fromList xs)toList-cast : ∀ .(eq : m ≡ n) (xs : Vec A m) → toList (cast eq xs) ≡ toList xstoList-cast {n = zero} eq [] = refltoList-cast {n = suc _} eq (x ∷ xs) =cong (x List.∷_) (toList-cast (cong pred eq) xs)cast-fromList : ∀ {xs ys : List A} (eq : xs ≡ ys) →cast (cong List.length eq) (fromList xs) ≡ fromList yscast-fromList {xs = List.[]} {ys = List.[]} eq = reflcast-fromList {xs = x List.∷ xs} {ys = y List.∷ ys} eq =let x≡y , xs≡ys = List.∷-injective eq in beginx ∷ cast (cong (pred ∘ List.length) eq) (fromList xs) ≡⟨ cong (_ ∷_) (cast-fromList xs≡ys) ⟩x ∷ fromList ys ≡⟨ cong (_∷ _) x≡y ⟩y ∷ fromList ys ∎where open ≡-ReasoningfromList-map : ∀ (f : A → B) (xs : List A) →cast (List.length-map f xs) (fromList (List.map f xs)) ≡ map f (fromList xs)fromList-map f List.[] = reflfromList-map f (x List.∷ xs) = cong (f x ∷_) (fromList-map f xs)fromList-++ : ∀ (xs : List A) {ys : List A} →cast (List.length-++ xs) (fromList (xs List.++ ys)) ≡ fromList xs ++ fromList ysfromList-++ List.[] {ys} = cast-is-id refl (fromList ys)fromList-++ (x List.∷ xs) {ys} = cong (x ∷_) (fromList-++ xs)fromList-reverse : (xs : List A) → cast (List.length-reverse xs) (fromList (List.reverse xs)) ≡ reverse (fromList xs)fromList-reverse List.[] = reflfromList-reverse (x List.∷ xs) = beginfromList (List.reverse (x List.∷ xs)) ≈⟨ cast-fromList (List.ʳ++-defn xs) ⟩fromList (List.reverse xs List.++ List.[ x ]) ≈⟨ fromList-++ (List.reverse xs) ⟩fromList (List.reverse xs) ++ [ x ] ≈⟨ unfold-∷ʳ (+-comm 1 _) x (fromList (List.reverse xs)) ⟨fromList (List.reverse xs) ∷ʳ x ≈⟨ ≈-cong (_∷ʳ x) (cast-∷ʳ (cong suc (List.length-reverse xs)) _ _)(fromList-reverse xs) ⟩reverse (fromList xs) ∷ʳ x ≂⟨ reverse-∷ x (fromList xs) ⟨reverse (x ∷ fromList xs) ≈⟨⟩reverse (fromList (x List.∷ xs)) ∎where open CastReasoning-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0updateAt-id-relative = updateAt-id-local{-# WARNING_ON_USAGE updateAt-id-relative"Warning: updateAt-id-relative was deprecated in v2.0.Please use updateAt-id-local instead."#-}updateAt-compose-relative = updateAt-updateAt-local{-# WARNING_ON_USAGE updateAt-compose-relative"Warning: updateAt-compose-relative was deprecated in v2.0.Please use updateAt-updateAt-local instead."#-}updateAt-compose = updateAt-updateAt{-# WARNING_ON_USAGE updateAt-compose"Warning: updateAt-compose was deprecated in v2.0.Please use updateAt-updateAt instead."#-}updateAt-cong-relative = updateAt-cong-local{-# WARNING_ON_USAGE updateAt-cong-relative"Warning: updateAt-cong-relative was deprecated in v2.0.Please use updateAt-cong-local instead."#-}[]%=-compose = []%=-∘{-# WARNING_ON_USAGE []%=-compose"Warning: []%=-compose was deprecated in v2.0.Please use []%=-∘ instead."#-}[]≔-++-inject+ : ∀ {m n x} (xs : Vec A m) (ys : Vec A n) i →(xs ++ ys) [ i ↑ˡ n ]≔ x ≡ (xs [ i ]≔ x) ++ ys[]≔-++-inject+ = []≔-++-↑ˡ{-# WARNING_ON_USAGE []≔-++-inject+"Warning: []≔-++-inject+ was deprecated in v2.0.Please use []≔-++-↑ˡ instead."#-}idIsFold = id-is-foldr{-# WARNING_ON_USAGE idIsFold"Warning: idIsFold was deprecated in v2.0.Please use id-is-foldr instead."#-}sum-++-commute = sum-++{-# WARNING_ON_USAGE sum-++-commute"Warning: sum-++-commute was deprecated in v2.0.Please use sum-++ instead."#-}take-drop-id = take++drop≡id{-# WARNING_ON_USAGE take-drop-id"Warning: take-drop-id was deprecated in v2.0.Please use take++drop≡id instead."#-}take-distr-zipWith = take-zipWith{-# WARNING_ON_USAGE take-distr-zipWith"Warning: take-distr-zipWith was deprecated in v2.0.Please use take-zipWith instead."#-}take-distr-map = take-map{-# WARNING_ON_USAGE take-distr-map"Warning: take-distr-map was deprecated in v2.0.Please use take-map instead."#-}drop-distr-zipWith = drop-zipWith{-# WARNING_ON_USAGE drop-distr-zipWith"Warning: drop-distr-zipWith was deprecated in v2.0.Please use drop-zipWith instead."#-}drop-distr-map = drop-map{-# WARNING_ON_USAGE drop-distr-map"Warning: drop-distr-map was deprecated in v2.0.Please use drop-map instead."#-}map-insert = map-insertAt{-# WARNING_ON_USAGE map-insert"Warning: map-insert was deprecated in v2.0.Please use map-insertAt instead."#-}insert-lookup = insertAt-lookup{-# WARNING_ON_USAGE insert-lookup"Warning: insert-lookup was deprecated in v2.0.Please use insertAt-lookup instead."#-}insert-punchIn = insertAt-punchIn{-# WARNING_ON_USAGE insert-punchIn"Warning: insert-punchIn was deprecated in v2.0.Please use insertAt-punchIn instead."#-}remove-PunchOut = removeAt-punchOut{-# WARNING_ON_USAGE remove-PunchOut"Warning: remove-PunchOut was deprecated in v2.0.Please use removeAt-punchOut instead."#-}remove-insert = removeAt-insertAt{-# WARNING_ON_USAGE remove-insert"Warning: remove-insert was deprecated in v2.0.Please use removeAt-insertAt instead."#-}insert-remove = insertAt-removeAt{-# WARNING_ON_USAGE insert-remove"Warning: insert-remove was deprecated in v2.0.Please use insertAt-removeAt instead."#-}lookup-inject≤-take : ∀ m (m≤m+n : m ≤ m + n) (i : Fin m) (xs : Vec A (m + n)) →lookup xs (Fin.inject≤ i m≤m+n) ≡ lookup (take m xs) ilookup-inject≤-take m m≤m+n i xs = sym (beginlookup (take m xs) i≡⟨ lookup-take-inject≤ xs i ⟩lookup xs (Fin.inject≤ i _)≡⟨⟩lookup xs (Fin.inject≤ i m≤m+n)∎) where open ≡-Reasoning{-# WARNING_ON_USAGE lookup-inject≤-take"Warning: lookup-inject≤-take was deprecated in v2.0.Please use lookup-take-inject≤ or lookup-truncate, take≡truncate instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some Vec-related properties that depend on the K rule or make use-- of heterogeneous equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Vec.Properties.WithK whereopen import Data.Nat.Baseopen import Data.Nat.Properties using (+-assoc)open import Data.Vec.Baseopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Binary.HeterogeneousEquality as ≅ using (_≅_; refl)-------------------------------------------------------------------------- _[_]=_module _ {a} {A : Set a} where[]=-irrelevant : ∀ {n} {xs : Vec A n} {i x} →(p q : xs [ i ]= x) → p ≡ q[]=-irrelevant here here = refl[]=-irrelevant (there xs[i]=x) (there xs[i]=x′) =cong there ([]=-irrelevant xs[i]=x xs[i]=x′)-------------------------------------------------------------------------- _++_module _ {a} {A : Set a} where++-assoc : ∀ {m n k} (xs : Vec A m) (ys : Vec A n) (zs : Vec A k) →(xs ++ ys) ++ zs ≅ xs ++ (ys ++ zs)++-assoc [] ys zs = refl++-assoc {suc m} (x ∷ xs) ys zs =≅.icong (Vec A) (+-assoc m _ _) (x ∷_) (++-assoc xs ys zs)-------------------------------------------------------------------------- foldrfoldr-cong : ∀ {a b} {A : Set a}{B : ℕ → Set b} {f : ∀ {n} → A → B n → B (suc n)} {d}{C : ℕ → Set b} {g : ∀ {n} → A → C n → C (suc n)} {e} →(∀ {n x} {y : B n} {z : C n} → y ≅ z → f x y ≅ g x z) →d ≅ e → ∀ {n} (xs : Vec A n) →foldr B f d xs ≅ foldr C g e xsfoldr-cong _ d≅e [] = d≅efoldr-cong f≅g d≅e (x ∷ xs) = f≅g (foldr-cong f≅g d≅e xs)-------------------------------------------------------------------------- foldlfoldl-cong : ∀ {a b} {A : Set a}{B : ℕ → Set b} {f : ∀ {n} → B n → A → B (suc n)} {d}{C : ℕ → Set b} {g : ∀ {n} → C n → A → C (suc n)} {e} →(∀ {n x} {y : B n} {z : C n} → y ≅ z → f y x ≅ g z x) →d ≅ e → ∀ {n} (xs : Vec A n) →foldl B f d xs ≅ foldl C g e xsfoldl-cong _ d≅e [] = d≅efoldl-cong f≅g d≅e (x ∷ xs) = foldl-cong f≅g (f≅g d≅e) xs
-------------------------------------------------------------------------- The Agda standard library---- Code for converting Vec A n → B to and from n-ary functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.N-ary whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Function.Bundles using (_↔_; Inverse; mk↔ₛ′)open import Data.Nat.Base hiding (_⊔_)open import Data.Product.Base as Product using (∃; _,_)open import Data.Vec.Base using (Vec; []; _∷_; head; tail)open import Function.Base using (_∘_; id; flip; constᵣ)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)privatevariablea b c ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- N-ary functionsN-ary-level : Level → Level → ℕ → LevelN-ary-level ℓ₁ ℓ₂ zero = ℓ₂N-ary-level ℓ₁ ℓ₂ (suc n) = ℓ₁ ⊔ N-ary-level ℓ₁ ℓ₂ nN-ary : ∀ (n : ℕ) → Set ℓ₁ → Set ℓ₂ → Set (N-ary-level ℓ₁ ℓ₂ n)N-ary zero A B = BN-ary (suc n) A B = A → N-ary n A B-------------------------------------------------------------------------- Conversioncurryⁿ : ∀ {n} → (Vec A n → B) → N-ary n A Bcurryⁿ {n = zero} f = f []curryⁿ {n = suc n} f = λ x → curryⁿ (f ∘ _∷_ x)infix -1 _$ⁿ__$ⁿ_ : ∀ {n} → N-ary n A B → (Vec A n → B)f $ⁿ [] = ff $ⁿ (x ∷ xs) = f x $ⁿ xs-------------------------------------------------------------------------- Quantifiersmodule _ {A : Set a} where-- Universal quantifier.∀ⁿ : ∀ n → N-ary n A (Set ℓ) → Set (N-ary-level a ℓ n)∀ⁿ zero P = P∀ⁿ (suc n) P = ∀ x → ∀ⁿ n (P x)-- Universal quantifier with implicit (hidden) arguments.∀ⁿʰ : ∀ n → N-ary n A (Set ℓ) → Set (N-ary-level a ℓ n)∀ⁿʰ zero P = P∀ⁿʰ (suc n) P = ∀ {x} → ∀ⁿʰ n (P x)-- Existential quantifier.∃ⁿ : ∀ n → N-ary n A (Set ℓ) → Set (N-ary-level a ℓ n)∃ⁿ zero P = P∃ⁿ (suc n) P = ∃ λ x → ∃ⁿ n (P x)-------------------------------------------------------------------------- N-ary function equalityEq : ∀ {A : Set a} {B : Set b} {C : Set c} n →REL B C ℓ → REL (N-ary n A B) (N-ary n A C) (N-ary-level a ℓ n)Eq n _∼_ f g = ∀ⁿ n (curryⁿ {n = n} λ xs → (f $ⁿ xs) ∼ (g $ⁿ xs))-- A variant where all the arguments are implicit (hidden).Eqʰ : ∀ {A : Set a} {B : Set b} {C : Set c} n →REL B C ℓ → REL (N-ary n A B) (N-ary n A C) (N-ary-level a ℓ n)Eqʰ n _∼_ f g = ∀ⁿʰ n (curryⁿ {n = n} λ xs → (f $ⁿ xs) ∼ (g $ⁿ xs))-------------------------------------------------------------------------- Some lemmas-- The functions curryⁿ and _$ⁿ_ are inverses.left-inverse : ∀ {n} (f : Vec A n → B) →∀ xs → (curryⁿ f $ⁿ xs) ≡ f xsleft-inverse f [] = reflleft-inverse f (x ∷ xs) = left-inverse (f ∘ _∷_ x) xsright-inverse : ∀ n (f : N-ary n A B) →Eq n _≡_ (curryⁿ (_$ⁿ_ {n = n} f)) fright-inverse zero f = reflright-inverse (suc n) f = λ x → right-inverse n (f x)-- ∀ⁿ can be expressed in an "uncurried" way.uncurry-∀ⁿ : ∀ n {P : N-ary n A (Set ℓ)} →∀ⁿ n P ⇔ (∀ (xs : Vec A n) → P $ⁿ xs)uncurry-∀ⁿ {a} {A} {ℓ} n = mk⇔ (⇒ n) (⇐ n)where⇒ : ∀ n {P : N-ary n A (Set ℓ)} →∀ⁿ n P → (∀ (xs : Vec A n) → P $ⁿ xs)⇒ zero p [] = p⇒ (suc n) p (x ∷ xs) = ⇒ n (p x) xs⇐ : ∀ n {P : N-ary n A (Set ℓ)} →(∀ (xs : Vec A n) → P $ⁿ xs) → ∀ⁿ n P⇐ zero p = p []⇐ (suc n) p = λ x → ⇐ n (p ∘ _∷_ x)-- ∃ⁿ can be expressed in an "uncurried" way.uncurry-∃ⁿ : ∀ n {P : N-ary n A (Set ℓ)} →∃ⁿ n P ⇔ (∃ λ (xs : Vec A n) → P $ⁿ xs)uncurry-∃ⁿ {a} {A} {ℓ} n = mk⇔ (⇒ n) (⇐ n)where⇒ : ∀ n {P : N-ary n A (Set ℓ)} →∃ⁿ n P → (∃ λ (xs : Vec A n) → P $ⁿ xs)⇒ zero p = ([] , p)⇒ (suc n) (x , p) = Product.map (_∷_ x) id (⇒ n p)⇐ : ∀ n {P : N-ary n A (Set ℓ)} →(∃ λ (xs : Vec A n) → P $ⁿ xs) → ∃ⁿ n P⇐ zero ([] , p) = p⇐ (suc n) (x ∷ xs , p) = (x , ⇐ n (xs , p))-- Conversion preserves equality.module _ (_∼_ : REL B C ℓ) wherecurryⁿ-cong : ∀ {n} (f : Vec A n → B) (g : Vec A n → C) →(∀ xs → f xs ∼ g xs) →Eq n _∼_ (curryⁿ f) (curryⁿ g)curryⁿ-cong {n = zero} f g hyp = hyp []curryⁿ-cong {n = suc n} f g hyp = λ x →curryⁿ-cong (f ∘ _∷_ x) (g ∘ _∷_ x) (λ xs → hyp (x ∷ xs))curryⁿ-cong⁻¹ : ∀ {n} (f : Vec A n → B) (g : Vec A n → C) →Eq n _∼_ (curryⁿ f) (curryⁿ g) →∀ xs → f xs ∼ g xscurryⁿ-cong⁻¹ f g hyp [] = hypcurryⁿ-cong⁻¹ f g hyp (x ∷ xs) =curryⁿ-cong⁻¹ (f ∘ _∷_ x) (g ∘ _∷_ x) (hyp x) xsappⁿ-cong : ∀ {n} (f : N-ary n A B) (g : N-ary n A C) →Eq n _∼_ f g →(xs : Vec A n) → (f $ⁿ xs) ∼ (g $ⁿ xs)appⁿ-cong f g hyp [] = hypappⁿ-cong f g hyp (x ∷ xs) = appⁿ-cong (f x) (g x) (hyp x) xsappⁿ-cong⁻¹ : ∀ {n} (f : N-ary n A B) (g : N-ary n A C) →((xs : Vec A n) → (f $ⁿ xs) ∼ (g $ⁿ xs)) →Eq n _∼_ f gappⁿ-cong⁻¹ {n = zero} f g hyp = hyp []appⁿ-cong⁻¹ {n = suc n} f g hyp = λ x →appⁿ-cong⁻¹ (f x) (g x) (λ xs → hyp (x ∷ xs))-- Eq and Eqʰ are equivalent.Eq-to-Eqʰ : ∀ n (_∼_ : REL B C ℓ) {f : N-ary n A B} {g : N-ary n A C} →Eq n _∼_ f g → Eqʰ n _∼_ f gEq-to-Eqʰ zero _∼_ eq = eqEq-to-Eqʰ (suc n) _∼_ eq = Eq-to-Eqʰ n _∼_ (eq _)Eqʰ-to-Eq : ∀ n (_∼_ : REL B C ℓ) {f : N-ary n A B} {g : N-ary n A C} →Eqʰ n _∼_ f g → Eq n _∼_ f gEqʰ-to-Eq zero _∼_ eq = eqEqʰ-to-Eq (suc n) _∼_ eq = λ _ → Eqʰ-to-Eq n _∼_ eqmodule _ (ext : ∀ {a b} → Extensionality a b) whereVec↔N-ary : ∀ n → (Vec A n → B) ↔ N-ary n A BVec↔N-ary zero = mk↔ₛ′ (λ vxs → vxs []) (flip constᵣ) (λ _ → refl)(λ vxs → ext λ where [] → refl)Vec↔N-ary (suc n) = let open Inverse (Vec↔N-ary n) inmk↔ₛ′ (λ vxs x → to λ xs → vxs (x ∷ xs))(λ any xs → from (any (head xs)) (tail xs))(λ any → ext λ x → strictlyInverseˡ _)(λ vxs → ext λ where (x ∷ xs) → cong (λ f → f xs) (strictlyInverseʳ (λ ys → vxs (x ∷ ys))))
-------------------------------------------------------------------------- The Agda standard library---- Membership of vectors, along with some additional definitions.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (_Respects_)module Data.Vec.Membership.Setoid {c ℓ} (S : Setoid c ℓ) whereopen import Function.Base using (_∘_; flip)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Relation.Unary.Any as Anyusing (Any; here; there; index)open import Data.Product.Base using (∃; _×_; _,_)open import Relation.Nullary.Negation using (¬_)open import Relation.Unary using (Pred)open Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Definitionsinfix 4 _∈_ _∉__∈_ : A → ∀ {n} → Vec A n → Set _x ∈ xs = Any (x ≈_) xs_∉_ : A → ∀ {n} → Vec A n → Set _x ∉ xs = ¬ x ∈ xs-------------------------------------------------------------------------- OperationsmapWith∈ : ∀ {b} {B : Set b} {n}(xs : Vec A n) → (∀ {x} → x ∈ xs → B) → Vec B nmapWith∈ [] f = []mapWith∈ (x ∷ xs) f = f (here refl) ∷ mapWith∈ xs (f ∘ there)infixr 5 _∷=__∷=_ : ∀ {n} {xs : Vec A n} {x} → x ∈ xs → A → Vec A n_∷=_ {xs = xs} x∈xs v = xs Vec.[ index x∈xs ]≔ v-------------------------------------------------------------------------- Finding and losing witnessesmodule _ {p} {P : Pred A p} wherefind : ∀ {n} {xs : Vec A n} → Any P xs → ∃ λ x → x ∈ xs × P xfind (here px) = _ , here refl , pxfind (there pxs) = let x , x∈xs , px = find pxs in x , there x∈xs , pxlose : P Respects _≈_ → ∀ {x n} {xs : Vec A n} → x ∈ xs → P x → Any P xslose resp x∈xs px = Any.map (flip resp px) x∈xs
-------------------------------------------------------------------------- The Agda standard library---- Data.Vec.Any.Membership instantiated with propositional equality,-- along with some additional definitions.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Membership.Propositional {a} {A : Set a} whereopen import Data.Vec.Base using (Vec)open import Data.Vec.Relation.Unary.Any using (Any)open import Relation.Binary.PropositionalEquality.Core using (subst)open import Relation.Binary.PropositionalEquality.Properties using (setoid)import Data.Vec.Membership.Setoid as SetoidMembership-------------------------------------------------------------------------- Re-export contents of setoid membershipopen SetoidMembership (setoid A) public hiding (lose)-------------------------------------------------------------------------- Other operationslose : ∀ {p} {P : A → Set p} {x n} {xs : Vec A n} → x ∈ xs → P x → Any P xslose = SetoidMembership.lose (setoid A) (subst _)
-------------------------------------------------------------------------- The Agda standard library---- Properties of membership of vectors based on propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Membership.Propositional.Properties whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.Product.Base using (_,_; ∃; _×_; -,_; map₁; map₂)open import Data.Vec.Baseopen import Data.Vec.Relation.Unary.Any using (here; there)open import Data.List.Base using ([]; _∷_)open import Data.List.Relation.Unary.Any as ListAny using (here; there)open import Data.Vec.Relation.Unary.Any as Any using (Any; here; there)open import Data.Vec.Membership.Propositionalopen import Data.List.Membership.Propositionalusing () renaming (_∈_ to _∈ₗ_)open import Level using (Level)open import Function.Base using (_∘_; id)open import Relation.Unary using (Pred)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)privatevariablea b p : LevelA : Set aB : Set b-------------------------------------------------------------------------- lookup∈-lookup : ∀ {n} i (xs : Vec A n) → lookup xs i ∈ xs∈-lookup zero (x ∷ xs) = here refl∈-lookup (suc i) (x ∷ xs) = there (∈-lookup i xs)index-∈-lookup : ∀ {n} (i : Fin n) (xs : Vec A n) → Any.index (∈-lookup i xs) ≡ iindex-∈-lookup zero (x ∷ xs) = reflindex-∈-lookup (suc i) (x ∷ xs) = cong suc (index-∈-lookup i xs)-------------------------------------------------------------------------- map∈-map⁺ : (f : A → B) → ∀ {m v} {xs : Vec A m} → v ∈ xs → f v ∈ map f xs∈-map⁺ f (here refl) = here refl∈-map⁺ f (there x∈xs) = there (∈-map⁺ f x∈xs)-------------------------------------------------------------------------- _++_∈-++⁺ˡ : ∀ {m n v} {xs : Vec A m} {ys : Vec A n} → v ∈ xs → v ∈ xs ++ ys∈-++⁺ˡ (here refl) = here refl∈-++⁺ˡ (there x∈xs) = there (∈-++⁺ˡ x∈xs)∈-++⁺ʳ : ∀ {m n v} (xs : Vec A m) {ys : Vec A n} → v ∈ ys → v ∈ xs ++ ys∈-++⁺ʳ [] x∈ys = x∈ys∈-++⁺ʳ (x ∷ xs) x∈ys = there (∈-++⁺ʳ xs x∈ys)-------------------------------------------------------------------------- tabulate∈-tabulate⁺ : ∀ {n} (f : Fin n → A) i → f i ∈ tabulate f∈-tabulate⁺ f zero = here refl∈-tabulate⁺ f (suc i) = there (∈-tabulate⁺ (f ∘ suc) i)-------------------------------------------------------------------------- allFin∈-allFin⁺ : ∀ {n} (i : Fin n) → i ∈ allFin n∈-allFin⁺ = ∈-tabulate⁺ id-------------------------------------------------------------------------- allPairs∈-allPairs⁺ : ∀ {m n x y} {xs : Vec A m} {ys : Vec B n} →x ∈ xs → y ∈ ys → (x , y) ∈ allPairs xs ys∈-allPairs⁺ {xs = x ∷ xs} (here refl) = ∈-++⁺ˡ ∘ ∈-map⁺ (x ,_)∈-allPairs⁺ {xs = x ∷ _} (there x∈xs) =∈-++⁺ʳ (map (x ,_) _) ∘ ∈-allPairs⁺ x∈xs-------------------------------------------------------------------------- toList∈-toList⁺ : ∀ {n} {v : A} {xs : Vec A n} → v ∈ xs → v ∈ₗ toList xs∈-toList⁺ (here refl) = here refl∈-toList⁺ (there x∈) = there (∈-toList⁺ x∈)∈-toList⁻ : ∀ {n} {v : A} {xs : Vec A n} → v ∈ₗ toList xs → v ∈ xs∈-toList⁻ {xs = x ∷ xs} (here refl) = here refl∈-toList⁻ {xs = x ∷ xs} (there v∈xs) = there (∈-toList⁻ v∈xs)-------------------------------------------------------------------------- fromList∈-fromList⁺ : ∀ {v : A} {xs} → v ∈ₗ xs → v ∈ fromList xs∈-fromList⁺ (here refl) = here refl∈-fromList⁺ (there x∈) = there (∈-fromList⁺ x∈)∈-fromList⁻ : ∀ {v : A} {xs} → v ∈ fromList xs → v ∈ₗ xs∈-fromList⁻ {xs = _ ∷ _} (here refl) = here refl∈-fromList⁻ {xs = _ ∷ _} (there v∈xs) = there (∈-fromList⁻ v∈xs)index-∈-fromList⁺ : ∀ {v : A} {xs} → (v∈xs : v ∈ₗ xs) →Any.index (∈-fromList⁺ v∈xs) ≡ ListAny.index v∈xsindex-∈-fromList⁺ (here refl) = reflindex-∈-fromList⁺ (there v∈xs) = cong suc (index-∈-fromList⁺ v∈xs)-------------------------------------------------------------------------- Relationship to Anymodule _ {P : Pred A p} wherefromAny : ∀ {n} {xs : Vec A n} → Any P xs → ∃ λ x → x ∈ xs × P xfromAny (here px) = -, here refl , pxfromAny (there v) = map₂ (map₁ there) (fromAny v)toAny : ∀ {n x} {xs : Vec A n} → x ∈ xs → P x → Any P xstoAny (here refl) px = here pxtoAny (there v) px = there (toAny v px)
-------------------------------------------------------------------------- The Agda standard library---- Decidable setoid membership over vectors.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)module Data.Vec.Membership.DecSetoid {c ℓ} (DS : DecSetoid c ℓ) whereopen import Data.Vec.Base using (Vec)open import Data.Vec.Relation.Unary.Any using (any?)open import Relation.Nullary.Decidable using (Dec)open DecSetoid DS renaming (Carrier to A)-------------------------------------------------------------------------- Re-export contents of propositional membershipopen import Data.Vec.Membership.Setoid setoid public-------------------------------------------------------------------------- Other operationsinfix 4 _∈?__∈?_ : ∀ x {n} (xs : Vec A n) → Dec (x ∈ xs)x ∈? xs = any? (x ≟_) xs
-------------------------------------------------------------------------- The Agda standard library---- Decidable propositional membership over vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.Vec.Membership.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A) whereopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Re-export contents of propositional membershipopen import Data.Vec.Membership.Propositional {A = A} publicopen import Data.Vec.Membership.DecSetoid (decSetoid _≟_) publicusing (_∈?_)
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for Vec------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Instances whereopen import Data.Vec.Baseopen import Data.Vec.Effectfulopen import Data.Vec.Propertiesusing (≡-dec)open import Levelopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Data.Vec.Relation.Binary.Equality.DecPropositionalopen import Relation.Binary.TypeClassesprivatevariablea : LevelA : Set ainstancevecFunctor = functorvecApplicative = applicativeVec-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → ∀ {n} → IsDecEquivalence {A = Vec A n} _≡_Vec-≡-isDecEquivalence = isDecEquivalence (≡-dec _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Vectors defined as functions from a finite set to a type.-------------------------------------------------------------------------- This implementation is designed for reasoning about fixed-size-- vectors where ease of retrieval of elements is prioritised.-- See `Data.Vec` for an alternative implementation using inductive-- data-types, which is more suitable for reasoning about vectors that-- will grow or shrink in size.{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional whereopen import Data.Fin.Baseopen import Data.List.Base as L using (List)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; NonZero; pred)open import Data.Product.Base using (Σ; ∃; _×_; _,_; proj₁; proj₂; uncurry)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Data.Vec.Base as V using (Vec)open import Function.Base using (_∘_; const; flip; _ˢ_; id)open import Level using (Level)infixr 5 _∷_ _++_infixl 4 _⊛_infixl 1 _>>=_privatevariablea b c : LevelA B C : Set am n : ℕ-------------------------------------------------------------------------- DefinitionVector : Set a → ℕ → Set aVector A n = Fin n → A-------------------------------------------------------------------------- ConversiontoVec : Vector A n → Vec A ntoVec = V.tabulatefromVec : Vec A n → Vector A nfromVec = V.lookuptoList : Vector A n → List AtoList = L.tabulatefromList : ∀ (xs : List A) → Vector A (L.length xs)fromList = L.lookup-------------------------------------------------------------------------- Basic operations[] : Vector A zero[] ()_∷_ : A → Vector A n → Vector A (suc n)(x ∷ xs) zero = x(x ∷ xs) (suc i) = xs ilength : Vector A n → ℕlength {n = n} _ = nhead : Vector A (suc n) → Ahead xs = xs zerotail : Vector A (suc n) → Vector A ntail xs = xs ∘ sucuncons : Vector A (suc n) → A × Vector A nuncons xs = head xs , tail xsreplicate : (n : ℕ) → A → Vector A nreplicate n = constinsertAt : Vector A n → Fin (suc n) → A → Vector A (suc n)insertAt {n = n} xs zero v zero = vinsertAt {n = n} xs zero v (suc j) = xs jinsertAt {n = suc n} xs (suc i) v zero = head xsinsertAt {n = suc n} xs (suc i) v (suc j) = insertAt (tail xs) i v jremoveAt : Vector A (suc n) → Fin (suc n) → Vector A nremoveAt t i = t ∘ punchIn iupdateAt : Vector A n → Fin n → (A → A) → Vector A nupdateAt {n = suc n} xs zero f zero = f (head xs)updateAt {n = suc n} xs zero f (suc j) = xs (suc j)updateAt {n = suc n} xs (suc i) f zero = head xsupdateAt {n = suc n} xs (suc i) f (suc j) = updateAt (tail xs) i f j-------------------------------------------------------------------------- Transformationsmap : (A → B) → ∀ {n} → Vector A n → Vector B nmap f xs = f ∘ xs_++_ : Vector A m → Vector A n → Vector A (m ℕ.+ n)_++_ {m = m} xs ys i = [ xs , ys ] (splitAt m i)concat : Vector (Vector A m) n → Vector A (n ℕ.* m)concat {m = m} xss i = uncurry (flip xss) (quotRem m i)foldr : (A → B → B) → B → ∀ {n} → Vector A n → Bfoldr f z {n = zero} xs = zfoldr f z {n = suc n} xs = f (head xs) (foldr f z (tail xs))foldl : (B → A → B) → B → ∀ {n} → Vector A n → Bfoldl f z {n = zero} xs = zfoldl f z {n = suc n} xs = foldl f (f z (head xs)) (tail xs)rearrange : (Fin m → Fin n) → Vector A n → Vector A mrearrange r xs = xs ∘ r_⊛_ : Vector (A → B) n → Vector A n → Vector B n_⊛_ = _ˢ__>>=_ : Vector A m → (A → Vector B n) → Vector B (m ℕ.* n)xs >>= f = concat (map f xs)zipWith : (A → B → C) → ∀ {n} → Vector A n → Vector B n → Vector C nzipWith f xs ys i = f (xs i) (ys i)unzipWith : (A → B × C) → Vector A n → Vector B n × Vector C nunzipWith f xs = proj₁ ∘ f ∘ xs , proj₂ ∘ f ∘ xszip : Vector A n → Vector B n → Vector (A × B) nzip = zipWith _,_unzip : Vector (A × B) n → Vector A n × Vector B nunzip = unzipWith idtake : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A mtake _ {n = n} xs = xs ∘ (_↑ˡ n)drop : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A ndrop m xs = xs ∘ (m ↑ʳ_)reverse : Vector A n → Vector A nreverse xs = xs ∘ oppositeinit : Vector A (suc n) → Vector A ninit xs = xs ∘ inject₁last : Vector A (suc n) → Alast {n = n} xs = xs (fromℕ n)transpose : Vector (Vector A n) m → Vector (Vector A m) ntranspose = flip-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0remove : Fin (suc n) → Vector A (suc n) → Vector A nremove = flip removeAt{-# WARNING_ON_USAGE remove"Warning: remove was deprecated in v2.0.Please use removeAt instead.NOTE: argument order has been flipped."#-}insert = insertAt{-# WARNING_ON_USAGE insert"Warning: insert was deprecated in v2.0.Please use insertAt instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Existential lifting of predicates over Vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Unary.Any whereopen import Data.Fin.Base using (zero; suc)open import Data.Fin.Properties using (any?)open import Data.Nat.Baseopen import Data.Product.Base as Σ using (Σ; ∃; _×_; _,_; proj₁; proj₂)open import Data.Vec.Functional as VF hiding (map)open import Function.Base using (id)open import Level using (Level)open import Relation.Unaryprivatevariablea b p q ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- DefinitionAny : Pred A ℓ → ∀ {n} → Vector A n → Set ℓAny P xs = ∃ λ i → P (xs i)-------------------------------------------------------------------------- Operationsmodule _ {P : Pred A p} wherehere : ∀ {x n} {v : Vector A n} → P x → Any P (x ∷ v)here px = zero , pxthere : ∀ {x n} {v : Vector A n} → Any P v → Any P (x ∷ v)there = Σ.map suc idmodule _ {P : Pred A p} {Q : Pred A q} wheremap : P ⊆ Q → ∀ {n} → Any P {n = n} ⊆ Any Qmap p⊆q = Σ.map id p⊆q-------------------------------------------------------------------------- Properties of predicates preserved by Anymodule _ {P : Pred A p} whereany : Decidable P → ∀ {n} → Decidable (Any P {n = n})any p? xs = any? λ i → p? (xs i)
-------------------------------------------------------------------------- The Agda standard library---- Universal lifting of predicates over Vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Unary.All whereopen import Data.Fin.Properties using (all?)open import Data.Product.Base using (_,_)open import Data.Vec.Functional as VF hiding (map)open import Level using (Level)open import Relation.Unaryprivatevariablea p q ℓ : LevelA : Set a-------------------------------------------------------------------------- DefinitionAll : Pred A ℓ → ∀ {n} → Vector A n → Set ℓAll P xs = ∀ i → P (xs i)-------------------------------------------------------------------------- Operationsmodule _ {P : Pred A p} {Q : Pred A q} wheremap : P ⊆ Q → ∀ {n} → All P {n = n} ⊆ All Qmap p⊆q ps i = p⊆q (ps i)-------------------------------------------------------------------------- Properties of predicates preserved by Allmodule _ {P : Pred A p} whereall : Decidable P → ∀ {n} → Decidable (All P {n = n})all p? xs = all? λ i → p? (xs i)universal : Universal P → ∀ {n} → Universal (All P {n = n})universal uni xs i = uni (xs i)satisfiable : Satisfiable P → ∀ {n} → Satisfiable (All P {n = n})satisfiable (x , px) = (λ _ → x) , (λ _ → px)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to All------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Unary.All.Properties whereopen import Data.Nat.Base using (ℕ)open import Data.Fin.Base using (zero; suc; _↑ˡ_; _↑ʳ_; splitAt)open import Data.Fin.Properties using (splitAt-↑ˡ; splitAt-↑ʳ)open import Data.Product.Base as Σ using (_×_; _,_; proj₁; proj₂; uncurry)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Data.Vec.Functional as VF hiding (map)open import Data.Vec.Functional.Relation.Unary.Allopen import Function.Base using (const; _∘_)open import Level using (Level)open import Relation.Unaryprivatevariablea p ℓ : LevelA B C : Set aP Q R : Pred A pm n : ℕx y : Axs ys : Vector A n-------------------------------------------------------------------------- mapmap⁺ : ∀ {f : A → B} → (∀ {x} → P x → Q (f x)) →All P xs → All Q (VF.map f xs)map⁺ pq ps i = pq (ps i)-------------------------------------------------------------------------- replicatereplicate⁺ : P x → All P (replicate n x)replicate⁺ = const-------------------------------------------------------------------------- _⊛_⊛⁺ : ∀ {fs : Vector (A → B) n} →All (λ f → ∀ {x} → P x → Q (f x)) fs →All P xs → All Q (fs ⊛ xs)⊛⁺ pqs ps i = (pqs i) (ps i)-------------------------------------------------------------------------- zipWithzipWith⁺ : ∀ {f} → (∀ {x y} → P x → Q y → R (f x y)) →All P xs → All Q ys → All R (zipWith f xs ys)zipWith⁺ pqr ps qs i = pqr (ps i) (qs i)-------------------------------------------------------------------------- zipzip⁺ : All P xs → All Q ys → All (P ⟨×⟩ Q) (zip xs ys)zip⁺ ps qs i = ps i , qs izip⁻ : All (P ⟨×⟩ Q) (zip xs ys) → All P xs × All Q yszip⁻ pqs = proj₁ ∘ pqs , proj₂ ∘ pqs-------------------------------------------------------------------------- headhead⁺ : ∀ (P : Pred A p) → All P xs → P (head xs)head⁺ P ps = ps zero-------------------------------------------------------------------------- tailtail⁺ : ∀ (P : Pred A p) → All P xs → All P (tail xs)tail⁺ P xs = xs ∘ suc-------------------------------------------------------------------------- ++module _ (P : Pred A p) {xs : Vector A m} {ys : Vector A n} where++⁺ : All P xs → All P ys → All P (xs ++ ys)++⁺ pxs pys i with splitAt m i... | inj₁ i′ = pxs i′... | inj₂ j′ = pys j′module _ (P : Pred A p) (xs : Vector A m) {ys : Vector A n} where++⁻ˡ : All P (xs ++ ys) → All P xs++⁻ˡ ps i with ps (i ↑ˡ n)... | p rewrite splitAt-↑ˡ m i n = p++⁻ʳ : All P (xs ++ ys) → All P ys++⁻ʳ ps i with ps (m ↑ʳ i)... | p rewrite splitAt-↑ʳ m n i = p++⁻ : All P (xs ++ ys) → All P xs × All P ys++⁻ ps = ++⁻ˡ ps , ++⁻ʳ ps
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of relations over Vector------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Binary.Pointwise whereopen import Data.Vec.Functional as VF hiding (map)open import Level using (Level)open import Relation.Binary.Core using (REL; _⇒_)privatevariablea b r s ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- DefinitionPointwise : REL A B ℓ → ∀ {n} → Vector A n → Vector B n → Set ℓPointwise R xs ys = ∀ i → R (xs i) (ys i)-------------------------------------------------------------------------- Operationsmodule _ {R : REL A B r} {S : REL A B s} wheremap : R ⇒ S → ∀ {n} → Pointwise R ⇒ Pointwise S {n = n}map f rs i = f (rs i)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Pointwise------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Binary.Pointwise.Properties whereopen import Data.Fin.Base using (zero; suc; _↑ˡ_; _↑ʳ_; splitAt)open import Data.Fin.Properties using (all?; splitAt-↑ˡ; splitAt-↑ʳ)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependentusing () renaming (Pointwise to ×-Pointwise)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Data.Vec.Functional as VF hiding (map)open import Data.Vec.Functional.Relation.Binary.Pointwiseopen import Function.Baseopen import Level using (Level)open import Relation.Binary.Core using (Rel; REL)open import Relation.Binary.Bundles using (Setoid; DecSetoid)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; Symmetric; Decidable)open import Relation.Binary.PropositionalEquality.Core using (_≡_)privatevariablea a′ a″ b b′ b″ r s t ℓ : LevelA : Set aB : Set bA′ : Set a′B′ : Set b′A″ : Set a″B″ : Set b″-------------------------------------------------------------------------- Relational propertiesmodule _ {R : Rel A ℓ} whererefl : Reflexive R → ∀ {n} → Reflexive (Pointwise R {n})refl r i = rsym : Symmetric R → ∀ {n} → Symmetric (Pointwise R {n})sym s xsys i = s (xsys i)trans : Transitive R → ∀ {n} → Transitive (Pointwise R {n})trans t xsys yszs i = t (xsys i) (yszs i)decidable : Decidable R → ∀ {n} → Decidable (Pointwise R {n})decidable r? xs ys = all? λ i → r? (xs i) (ys i)-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence R → ∀ n → IsEquivalence (Pointwise R {n})isEquivalence isEq n = record{ refl = refl Eq.refl; sym = sym Eq.sym; trans = trans Eq.trans} where module Eq = IsEquivalence isEqisDecEquivalence : IsDecEquivalence R →∀ n → IsDecEquivalence (Pointwise R {n})isDecEquivalence isDecEq n = record{ isEquivalence = isEquivalence Eq.isEquivalence n; _≟_ = decidable Eq._≟_} where module Eq = IsDecEquivalence isDecEq-------------------------------------------------------------------------- Bundlessetoid : Setoid a ℓ → ℕ → Setoid a ℓsetoid S n = record{ isEquivalence = isEquivalence S.isEquivalence n} where module S = Setoid SdecSetoid : DecSetoid a ℓ → ℕ → DecSetoid a ℓdecSetoid S n = record{ isDecEquivalence = isDecEquivalence S.isDecEquivalence n} where module S = DecSetoid S-------------------------------------------------------------------------- mapmodule _ {R : REL A B r} {S : REL A′ B′ s} {f : A → A′} {g : B → B′} wheremap⁺ : (∀ {x y} → R x y → S (f x) (g y)) →∀ {n} {xs : Vector A n} {ys : Vector B n} →Pointwise R xs ys → Pointwise S (VF.map f xs) (VF.map g ys)map⁺ f rs i = f (rs i)-------------------------------------------------------------------------- headmodule _ (R : REL A B r) {n} {xs : Vector A (suc n)} {ys} wherehead⁺ : Pointwise R xs ys → R (head xs) (head ys)head⁺ rs = rs zero-------------------------------------------------------------------------- tailmodule _ (R : REL A B r) {n} {xs : Vector A (suc n)} {ys} wheretail⁺ : Pointwise R xs ys → Pointwise R (tail xs) (tail ys)tail⁺ rs = rs ∘ suc-------------------------------------------------------------------------- _++_module _ (R : REL A B r) where++⁺ : ∀ {m n xs ys xs′ ys′} →Pointwise R {n = m} xs ys → Pointwise R {n = n} xs′ ys′ →Pointwise R (xs ++ xs′) (ys ++ ys′)++⁺ {m} rs rs′ i with splitAt m i... | inj₁ i′ = rs i′... | inj₂ j′ = rs′ j′++⁻ˡ : ∀ {m n} (xs : Vector A m) (ys : Vector B m) {xs′ ys′} →Pointwise R (xs ++ xs′) (ys ++ ys′) → Pointwise R xs ys++⁻ˡ {m} {n} _ _ rs i with rs (i ↑ˡ n)... | r rewrite splitAt-↑ˡ m i n = r++⁻ʳ : ∀ {m n} (xs : Vector A m) (ys : Vector B m) {xs′ ys′} →Pointwise R (xs ++ xs′) (ys ++ ys′) → Pointwise R xs′ ys′++⁻ʳ {m} {n} _ _ rs i with rs (m ↑ʳ i)... | r rewrite splitAt-↑ʳ m n i = r++⁻ : ∀ {m n} xs ys {xs′ ys′} →Pointwise R (xs ++ xs′) (ys ++ ys′) →Pointwise R {n = m} xs ys × Pointwise R {n = n} xs′ ys′++⁻ _ _ rs = ++⁻ˡ _ _ rs , ++⁻ʳ _ _ rs-------------------------------------------------------------------------- replicatemodule _ {R : REL A B r} {x y n} wherereplicate⁺ : R x y → Pointwise R {n = n} (replicate n x) (replicate n y)replicate⁺ = const-------------------------------------------------------------------------- _⊛_module _ {R : REL A B r} {S : REL A′ B′ s} {n} where⊛⁺ : ∀ {fs : Vector (A → A′) n} {gs : Vector (B → B′) n} →Pointwise (λ f g → ∀ {x y} → R x y → S (f x) (g y)) fs gs →∀ {xs ys} → Pointwise R xs ys → Pointwise S (fs ⊛ xs) (gs ⊛ ys)⊛⁺ rss rs i = (rss i) (rs i)-------------------------------------------------------------------------- zipWithmodule _ {R : REL A B r} {S : REL A′ B′ s} {T : REL A″ B″ t} wherezipWith⁺ : ∀ {n xs ys xs′ ys′ f f′} →(∀ {x y x′ y′} → R x y → S x′ y′ → T (f x x′) (f′ y y′)) →Pointwise R xs ys → Pointwise S xs′ ys′ →Pointwise T (zipWith f xs xs′) (zipWith f′ {n = n} ys ys′)zipWith⁺ t rs ss i = t (rs i) (ss i)-------------------------------------------------------------------------- zipmodule _ {R : REL A B r} {S : REL A′ B′ s} {n xs ys xs′ ys′} wherezip⁺ : Pointwise R xs ys → Pointwise S xs′ ys′ →Pointwise (×-Pointwise R S) (zip xs xs′) (zip {n = n} ys ys′)zip⁺ rs ss i = rs i , ss izip⁻ : Pointwise (×-Pointwise R S) (zip xs xs′) (zip {n = n} ys ys′) →Pointwise R xs ys × Pointwise S xs′ ys′zip⁻ rss = proj₁ ∘ rss , proj₂ ∘ rss-------------------------------------------------------------------------- foldrmodule _ {R : REL A B r} {S : REL A′ B′ s}{f : A → A′ → A′} {g : B → B′ → B′}wherefoldr-cong : (∀ {w x y z} → R w x → S y z → S (f w y) (g x z)) →∀ {d : A′} {e : B′} → S d e →∀ {n} {xs : Vector A n} {ys : Vector B n} →Pointwise R xs ys → S (foldr f d xs) (foldr g e ys)foldr-cong fg-cong d~e {zero} rss = d~efoldr-cong fg-cong d~e {suc n} rss =fg-cong (rss zero) (foldr-cong fg-cong d~e (rss ∘ suc))
-------------------------------------------------------------------------- The Agda standard library---- Permutation relations over Vector------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Binary.Permutation whereopen import Level using (Level)open import Data.Product.Base using (Σ-syntax)open import Data.Fin.Permutation using (Permutation; _⟨$⟩ʳ_)open import Data.Vec.Functional using (Vector)open import Relation.Binary.Indexed.Heterogeneous.Core using (IRel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)privatevariablea : LevelA : Set ainfix 3 _↭__↭_ : IRel (Vector A) _xs ↭ ys = Σ[ ρ ∈ Permutation _ _ ] (∀ i → xs (ρ ⟨$⟩ʳ i) ≡ ys i)
-------------------------------------------------------------------------- The Agda standard library---- Properties of permutation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Relation.Binary.Permutation.Properties whereopen import Level using (Level)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Data.Nat.Base using (ℕ)open import Data.Fin.Permutation using (id; flip; _⟨$⟩ʳ_; inverseʳ; _∘ₚ_)open import Data.Vec.Functional using (Vector)open import Data.Vec.Functional.Relation.Binary.Permutation using (_↭_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; trans; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Binary.Indexed.Heterogeneoususing (Reflexive; Symmetric; Transitive; IsIndexedEquivalence; IndexedSetoid)privatevariablea : LevelA : Set an : ℕxs ys : Vector A n-------------------------------------------------------------------------- Basics↭-refl : Reflexive (Vector A) _↭_↭-refl = id , λ _ → refl↭-reflexive : xs ≡ ys → xs ↭ ys↭-reflexive refl = ↭-refl↭-sym : Symmetric (Vector A) _↭_proj₁ (↭-sym (xs↭ys , _)) = flip xs↭ysproj₂ (↭-sym {x = xs} {ys} (xs↭ys , xs↭ys≡)) i = beginys (flip xs↭ys ⟨$⟩ʳ i) ≡⟨ xs↭ys≡ _ ⟨xs (xs↭ys ⟨$⟩ʳ (flip xs↭ys ⟨$⟩ʳ i)) ≡⟨ cong xs (inverseʳ xs↭ys) ⟩xs i ∎where open ≡-Reasoning↭-trans : Transitive (Vector A) _↭_proj₁ (↭-trans (xs↭ys , _) (ys↭zs , _)) = ys↭zs ∘ₚ xs↭ysproj₂ (↭-trans (_ , xs↭ys) (_ , ys↭zs)) _ = trans (xs↭ys _) (ys↭zs _)-------------------------------------------------------------------------- StructureisIndexedEquivalence : IsIndexedEquivalence (Vector A) _↭_isIndexedEquivalence {A = A} = record{ refl = ↭-refl; sym = ↭-sym; trans = λ {n₁ n₂ n₃} {xs : Vector A n₁} {ys : Vector A n₂} {zs : Vector A n₃}xs↭ys ys↭zs → ↭-trans {i = n₁} {i = xs} xs↭ys ys↭zs}-------------------------------------------------------------------------- BundleindexedSetoid : {A : Set a} → IndexedSetoid ℕ a _indexedSetoid {A = A} = record{ Carrier = Vector A; _≈_ = _↭_; isEquivalence = isIndexedEquivalence}
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of relations over Vector------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Nat.Base using (ℕ)open import Data.Vec.Functional hiding (map)open import Data.Vec.Functional.Relation.Binary.Pointwiseusing (Pointwise)import Data.Vec.Functional.Relation.Binary.Pointwise.Properties as PWopen import Level using (Level)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)module Data.Vec.Functional.Relation.Binary.Equality.Setoid{a ℓ} (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Definition------------------------------------------------------------------------infix 4 _≋__≋_ : ∀ {n} → Vector A n → Vector A n → Set ℓ_≋_ = Pointwise _≈_-------------------------------------------------------------------------- Relational properties------------------------------------------------------------------------≋-refl : ∀ {n} → Reflexive (_≋_ {n = n})≋-refl {n} = PW.refl {R = _≈_} refl≋-reflexive : ∀ {n} → _≡_ ⇒ (_≋_ {n = n})≋-reflexive ≡.refl = ≋-refl≋-sym : ∀ {n} → Symmetric (_≋_ {n = n})≋-sym = PW.sym {R = _≈_} sym≋-trans : ∀ {n} → Transitive (_≋_ {n = n})≋-trans = PW.trans {R = _≈_} trans≋-isEquivalence : ∀ n → IsEquivalence (_≋_ {n = n})≋-isEquivalence = PW.isEquivalence isEquivalence≋-setoid : ℕ → Setoid _ _≋-setoid = PW.setoid S-------------------------------------------------------------------------- Properties------------------------------------------------------------------------open PW publicusing( map⁺; head⁺; tail⁺; ++⁺; ++⁻ˡ; ++⁻ʳ; ++⁻; replicate⁺; ⊛⁺; zipWith⁺; zip⁺; zip⁻)foldr-cong : ∀ {f g} → (∀ {w x y z} → w ≈ x → y ≈ z → f w y ≈ g x z) →∀ {d e : A} → d ≈ e →∀ {n} {xs ys : Vector A n} → xs ≋ ys →foldr f d xs ≈ foldr g e ysfoldr-cong = PW.foldr-cong
-------------------------------------------------------------------------- The Agda standard library---- Some Vector-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Functional.Properties whereopen import Data.Empty using (⊥-elim)open import Data.Fin.Base using (Fin; zero; suc; toℕ; fromℕ<; reduce≥;_↑ˡ_; _↑ʳ_; punchIn; punchOut)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)import Data.Nat.Properties as ℕopen import Data.Product.Base as Product using (_×_; _,_; proj₁; proj₂)open import Data.List.Base as List using (List)import Data.List.Properties as Listopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Data.Vec.Base as Vec using (Vec)import Data.Vec.Properties as Vecopen import Data.Vec.Functional using (Vector; head; tail; updateAt;map; _++_; insertAt; removeAt; toVec; fromVec; toList; fromList)open import Function.Base using (_∘_; id)open import Level using (Level)open import Relation.Binary.Definitions using (DecidableEquality; Decidable)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; refl; _≢_; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Nullary.Decidableusing (Dec; does; yes; no; map′; _×-dec_)import Data.Fin.Properties as Finₚprivatevariablea b c : LevelA B C : Set am n : ℕ------------------------------------------------------------------------module _ {xs ys : Vector A (suc n)} where∷-cong : head xs ≡ head ys → tail xs ≗ tail ys → xs ≗ ys∷-cong eq _ zero = eq∷-cong _ eq (suc i) = eq i∷-injective : xs ≗ ys → head xs ≡ head ys × tail xs ≗ tail ys∷-injective eq = eq zero , eq ∘ suc≗-dec : DecidableEquality A → Decidable {A = Vector A n} _≗_≗-dec {n = zero} _≟_ xs ys = yes λ ()≗-dec {n = suc n} _≟_ xs ys =map′ (Product.uncurry ∷-cong) ∷-injective(head xs ≟ head ys ×-dec ≗-dec _≟_ (tail xs) (tail ys))-------------------------------------------------------------------------- updateAt-- (+) updateAt i actually updates the element at index i.updateAt-updates : ∀ (i : Fin n) {f : A → A} (xs : Vector A n) →updateAt xs i f i ≡ f (xs i)updateAt-updates zero xs = reflupdateAt-updates (suc i) xs = updateAt-updates i (tail xs)-- (-) updateAt i does not touch the elements at other indices.updateAt-minimal : ∀ (i j : Fin n) {f : A → A} (xs : Vector A n) →i ≢ j → updateAt xs j f i ≡ xs iupdateAt-minimal zero zero xs 0≢0 = ⊥-elim (0≢0 refl)updateAt-minimal zero (suc j) xs _ = reflupdateAt-minimal (suc i) zero xs _ = reflupdateAt-minimal (suc i) (suc j) xs i≢j = updateAt-minimal i j (tail xs) (i≢j ∘ cong suc)-- updateAt i is a monoid morphism from A → A to Vector A n → Vector A n.updateAt-id-local : ∀ (i : Fin n) {f : A → A} (xs : Vector A n) →f (xs i) ≡ xs i →updateAt xs i f ≗ xsupdateAt-id-local zero xs eq zero = equpdateAt-id-local zero xs eq (suc j) = reflupdateAt-id-local (suc i) xs eq zero = reflupdateAt-id-local (suc i) xs eq (suc j) = updateAt-id-local i (tail xs) eq jupdateAt-id : ∀ (i : Fin n) (xs : Vector A n) →updateAt xs i id ≗ xsupdateAt-id i xs = updateAt-id-local i xs reflupdateAt-updateAt-local : ∀ (i : Fin n) {f g h : A → A} (xs : Vector A n) →f (g (xs i)) ≡ h (xs i) →updateAt (updateAt xs i g) i f ≗ updateAt xs i hupdateAt-updateAt-local zero xs eq zero = equpdateAt-updateAt-local zero xs eq (suc j) = reflupdateAt-updateAt-local (suc i) xs eq zero = reflupdateAt-updateAt-local (suc i) xs eq (suc j) = updateAt-updateAt-local i (tail xs) eq jupdateAt-updateAt : ∀ (i : Fin n) {f g : A → A} (xs : Vector A n) →updateAt (updateAt xs i g) i f ≗ updateAt xs i (f ∘ g)updateAt-updateAt i xs = updateAt-updateAt-local i xs reflupdateAt-cong-local : ∀ (i : Fin n) {f g : A → A} (xs : Vector A n) →f (xs i) ≡ g (xs i) →updateAt xs i f ≗ updateAt xs i gupdateAt-cong-local zero xs eq zero = equpdateAt-cong-local zero xs eq (suc j) = reflupdateAt-cong-local (suc i) xs eq zero = reflupdateAt-cong-local (suc i) xs eq (suc j) = updateAt-cong-local i (tail xs) eq jupdateAt-cong : ∀ (i : Fin n) {f g : A → A} → f ≗ g → (xs : Vector A n) →updateAt xs i f ≗ updateAt xs i gupdateAt-cong i eq xs = updateAt-cong-local i xs (eq (xs i))-- The order of updates at different indices i ≢ j does not matter.updateAt-commutes : ∀ (i j : Fin n) {f g : A → A} → i ≢ j → (xs : Vector A n) →updateAt (updateAt xs j g) i f ≗ updateAt (updateAt xs i f) j gupdateAt-commutes zero zero 0≢0 xs k = ⊥-elim (0≢0 refl)updateAt-commutes zero (suc j) _ xs zero = reflupdateAt-commutes zero (suc j) _ xs (suc k) = reflupdateAt-commutes (suc i) zero _ xs zero = reflupdateAt-commutes (suc i) zero _ xs (suc k) = reflupdateAt-commutes (suc i) (suc j) _ xs zero = reflupdateAt-commutes (suc i) (suc j) i≢j xs (suc k) = updateAt-commutes i j (i≢j ∘ cong suc) (tail xs) k-------------------------------------------------------------------------- mapmap-id : (xs : Vector A n) → map id xs ≗ xsmap-id xs = λ _ → reflmap-cong : ∀ {f g : A → B} → f ≗ g → (xs : Vector A n) → map f xs ≗ map g xsmap-cong f≗g xs = f≗g ∘ xsmap-∘ : ∀ {f : B → C} {g : A → B} (xs : Vector A n) →map (f ∘ g) xs ≗ map f (map g xs)map-∘ xs = λ _ → refllookup-map : ∀ (i : Fin n) (f : A → B) (xs : Vector A n) →map f xs i ≡ f (xs i)lookup-map i f xs = reflmap-updateAt-local : ∀ {f : A → B} {g : A → A} {h : B → B}(xs : Vector A n) (i : Fin n) →f (g (xs i)) ≡ h (f (xs i)) →map f (updateAt xs i g) ≗ updateAt (map f xs) i hmap-updateAt-local {n = suc n} {f = f} xs zero eq zero = eqmap-updateAt-local {n = suc n} {f = f} xs zero eq (suc j) = reflmap-updateAt-local {n = suc (suc n)} {f = f} xs (suc i) eq zero = reflmap-updateAt-local {n = suc (suc n)} {f = f} xs (suc i) eq (suc j) = map-updateAt-local {f = f} (tail xs) i eq jmap-updateAt : ∀ {f : A → B} {g : A → A} {h : B → B} →f ∘ g ≗ h ∘ f →(xs : Vector A n) (i : Fin n) →map f (updateAt xs i g) ≗ updateAt (map f xs) i hmap-updateAt {f = f} {g = g} f∘g≗h∘f xs i = map-updateAt-local {f = f} {g = g} xs i (f∘g≗h∘f (xs i))-------------------------------------------------------------------------- _++_lookup-++-< : ∀ (xs : Vector A m) (ys : Vector A n) →∀ i (i<m : toℕ i ℕ.< m) →(xs ++ ys) i ≡ xs (fromℕ< i<m)lookup-++-< {m = m} xs ys i i<m = cong Sum.[ xs , ys ] (Finₚ.splitAt-< m i i<m)lookup-++-≥ : ∀ (xs : Vector A m) (ys : Vector A n) →∀ i (i≥m : toℕ i ℕ.≥ m) →(xs ++ ys) i ≡ ys (reduce≥ i i≥m)lookup-++-≥ {m = m} xs ys i i≥m = cong Sum.[ xs , ys ] (Finₚ.splitAt-≥ m i i≥m)lookup-++ˡ : ∀ (xs : Vector A m) (ys : Vector A n) i →(xs ++ ys) (i ↑ˡ n) ≡ xs ilookup-++ˡ {m = m} {n = n} xs ys i = cong Sum.[ xs , ys ] (Finₚ.splitAt-↑ˡ m i n)lookup-++ʳ : ∀ (xs : Vector A m) (ys : Vector A n) i →(xs ++ ys) (m ↑ʳ i) ≡ ys ilookup-++ʳ {m = m} {n = n} xs ys i = cong Sum.[ xs , ys ] (Finₚ.splitAt-↑ʳ m n i)module _ {ys ys′ : Vector A m} where++-cong : ∀ (xs xs′ : Vector A n) →xs ≗ xs′ → ys ≗ ys′ → xs ++ ys ≗ xs′ ++ ys′++-cong {n} xs xs′ eq₁ eq₂ i with toℕ i ℕ.<? n... | yes i<n = begin(xs ++ ys) i ≡⟨ lookup-++-< xs ys i i<n ⟩xs (fromℕ< i<n) ≡⟨ eq₁ (fromℕ< i<n) ⟩xs′ (fromℕ< i<n) ≡⟨ lookup-++-< xs′ ys′ i i<n ⟨(xs′ ++ ys′) i ∎where open ≡-Reasoning... | no i≮n = begin(xs ++ ys) i ≡⟨ lookup-++-≥ xs ys i (ℕ.≮⇒≥ i≮n) ⟩ys (reduce≥ i (ℕ.≮⇒≥ i≮n)) ≡⟨ eq₂ (reduce≥ i (ℕ.≮⇒≥ i≮n)) ⟩ys′ (reduce≥ i (ℕ.≮⇒≥ i≮n)) ≡⟨ lookup-++-≥ xs′ ys′ i (ℕ.≮⇒≥ i≮n) ⟨(xs′ ++ ys′) i ∎where open ≡-Reasoning++-injectiveˡ : ∀ (xs xs′ : Vector A n) →xs ++ ys ≗ xs′ ++ ys′ → xs ≗ xs′++-injectiveˡ xs xs′ eq i = beginxs i ≡⟨ lookup-++ˡ xs ys i ⟨(xs ++ ys) (i ↑ˡ m) ≡⟨ eq (i ↑ˡ m) ⟩(xs′ ++ ys′) (i ↑ˡ m) ≡⟨ lookup-++ˡ xs′ ys′ i ⟩xs′ i ∎where open ≡-Reasoning++-injectiveʳ : ∀ (xs xs′ : Vector A n) → xs ++ ys ≗ xs′ ++ ys′ → ys ≗ ys′++-injectiveʳ {n} xs xs′ eq i = beginys i ≡⟨ lookup-++ʳ xs ys i ⟨(xs ++ ys) (n ↑ʳ i) ≡⟨ eq (n ↑ʳ i) ⟩(xs′ ++ ys′) (n ↑ʳ i) ≡⟨ lookup-++ʳ xs′ ys′ i ⟩ys′ i ∎where open ≡-Reasoning++-injective : ∀ (xs xs′ : Vector A n) →xs ++ ys ≗ xs′ ++ ys′ → xs ≗ xs′ × ys ≗ ys′++-injective xs xs′ eq = ++-injectiveˡ xs xs′ eq , ++-injectiveʳ xs xs′ eq-------------------------------------------------------------------------- insertAtinsertAt-lookup : ∀ (xs : Vector A n) (i : Fin (suc n)) (v : A) →insertAt xs i v i ≡ vinsertAt-lookup {n = n} xs zero v = reflinsertAt-lookup {n = suc n} xs (suc i) v = insertAt-lookup (tail xs) i vinsertAt-punchIn : ∀ (xs : Vector A n) (i : Fin (suc n)) (v : A)(j : Fin n) →insertAt xs i v (punchIn i j) ≡ xs jinsertAt-punchIn {n = suc n} xs zero v j = reflinsertAt-punchIn {n = suc n} xs (suc i) v zero = reflinsertAt-punchIn {n = suc n} xs (suc i) v (suc j) = insertAt-punchIn (tail xs) i v j-------------------------------------------------------------------------- removeAtremoveAt-punchOut : ∀ (xs : Vector A (suc n)){i : Fin (suc n)} {j : Fin (suc n)} (i≢j : i ≢ j) →removeAt xs i (punchOut i≢j) ≡ xs jremoveAt-punchOut {n = n} xs {zero} {zero} i≢j = ⊥-elim (i≢j refl)removeAt-punchOut {n = suc n} xs {zero} {suc j} i≢j = reflremoveAt-punchOut {n = suc n} xs {suc i} {zero} i≢j = reflremoveAt-punchOut {n = suc n} xs {suc i} {suc j} i≢j = removeAt-punchOut (tail xs) (i≢j ∘ cong suc)removeAt-insertAt : ∀ (xs : Vector A n) (i : Fin (suc n)) (v : A) →removeAt (insertAt xs i v) i ≗ xsremoveAt-insertAt xs zero v j = reflremoveAt-insertAt xs (suc i) v zero = reflremoveAt-insertAt xs (suc i) v (suc j) = removeAt-insertAt (tail xs) i v jinsertAt-removeAt : ∀ (xs : Vector A (suc n)) (i : Fin (suc n)) →insertAt (removeAt xs i) i (xs i) ≗ xsinsertAt-removeAt {n = n} xs zero zero = reflinsertAt-removeAt {n = n} xs zero (suc j) = reflinsertAt-removeAt {n = suc n} xs (suc i) zero = reflinsertAt-removeAt {n = suc n} xs (suc i) (suc j) = insertAt-removeAt (tail xs) i j-------------------------------------------------------------------------- Conversion functionstoVec∘fromVec : (xs : Vec A n) → toVec (fromVec xs) ≡ xstoVec∘fromVec = Vec.tabulate∘lookupfromVec∘toVec : (xs : Vector A n) → fromVec (toVec xs) ≗ xsfromVec∘toVec = Vec.lookup∘tabulatetoList∘fromList : (xs : List A) → toList (fromList xs) ≡ xstoList∘fromList = List.tabulate-lookup-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0updateAt-id-relative = updateAt-id-local{-# WARNING_ON_USAGE updateAt-id-relative"Warning: updateAt-id-relative was deprecated in v2.0.Please use updateAt-id-local instead."#-}updateAt-compose-relative = updateAt-updateAt-local{-# WARNING_ON_USAGE updateAt-compose-relative"Warning: updateAt-compose-relative was deprecated in v2.0.Please use updateAt-updateAt-local instead."#-}updateAt-compose = updateAt-updateAt{-# WARNING_ON_USAGE updateAt-compose"Warning: updateAt-compose was deprecated in v2.0.Please use updateAt-updateAt instead."#-}updateAt-cong-relative = updateAt-cong-local{-# WARNING_ON_USAGE updateAt-cong-relative"Warning: updateAt-cong-relative was deprecated in v2.0.Please use updateAt-cong-local instead."#-}insert-lookup = insertAt-lookup{-# WARNING_ON_USAGE insert-lookup"Warning: insert-lookup was deprecated in v2.0.Please use insertAt-lookup instead."#-}insert-punchIn = insertAt-punchIn{-# WARNING_ON_USAGE insert-punchIn"Warning: insert-punchIn was deprecated in v2.0.Please use insertAt-punchIn instead."#-}remove-punchOut = removeAt-punchOut{-# WARNING_ON_USAGE remove-punchOut"Warning: remove-punchOut was deprecated in v2.0.Please use removeAt-punchOut instead."#-}remove-insert = removeAt-insertAt{-# WARNING_ON_USAGE remove-insert"Warning: remove-insert was deprecated in v2.0.Please use removeAt-insertAt instead."#-}insert-remove = insertAt-removeAt{-# WARNING_ON_USAGE insert-remove"Warning: insert-remove was deprecated in v2.0.Please use insertAt-removeAt instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Vec------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Effectful whereopen import Data.Nat.Base using (ℕ)open import Data.Fin.Base using (Fin)open import Data.Vec.Base as Vec hiding (_⊛_)open import Data.Vec.Propertiesopen import Effect.Applicative as App using (RawApplicative)open import Effect.Functor as Fun using (RawFunctor)open import Effect.Monad using (RawMonad; module Join; RawMonadT; mkRawMonad)import Function.Identity.Effectful as Idopen import Function.Baseopen import Level using (Level)privatevariablea : LevelA : Set an : ℕ-------------------------------------------------------------------------- Functor and applicativefunctor : RawFunctor (λ (A : Set a) → Vec A n)functor = record{ _<$>_ = map}applicative : RawApplicative (λ (A : Set a) → Vec A n)applicative {n = n} = record{ rawFunctor = functor; pure = replicate n; _<*>_ = Vec._⊛_}monad : RawMonad (λ (A : Set a) → Vec A n)monad = record{ rawApplicative = applicative; _>>=_ = DiagonalBind._>>=_}join : Vec (Vec A n) n → Vec A njoin = Join.join monad-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {f g F} (App : RawApplicative {f} {g} F) whereopen RawApplicative AppsequenceA : ∀ {A n} → Vec (F A) n → F (Vec A n)sequenceA [] = pure []sequenceA (x ∷ xs) = _∷_ <$> x ⊛ sequenceA xsmapA : ∀ {a} {A : Set a} {B n} → (A → F B) → Vec A n → F (Vec B n)mapA f = sequenceA ∘ map fforA : ∀ {a} {A : Set a} {B n} → Vec A n → (A → F B) → F (Vec B n)forA = flip mapAmodule TraversableM {m n M} (Mon : RawMonad {m} {n} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)-------------------------------------------------------------------------- Other-- lookup is a functor morphism from Vec to Identity.lookup-functor-morphism : (i : Fin n) → Fun.Morphism (functor {a}) Id.functorlookup-functor-morphism i = record{ op = flip lookup i; op-<$> = lookup-map i}-- lookup is an applicative functor morphism.lookup-morphism : (i : Fin n) → App.Morphism (applicative {a}) Id.applicativelookup-morphism i = record{ functorMorphism = lookup-functor-morphism i; op-pure = lookup-replicate i; op-<*> = lookup-⊛ i}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Vec------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Effectful.Transformer whereopen import Data.Nat.Base using (ℕ)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Baseopen import Levelimport Data.Vec.Effectful as Vecprivatevariablef g : Leveln : ℕM : Set f → Set g-------------------------------------------------------------------------- Vec monad transformerrecord VecT (n : ℕ) (M : Set f → Set g) (A : Set f) : Set g whereconstructor mkVecTfield runVecT : M (Vec A n)open VecT publicfunctor : RawFunctor M → RawFunctor {f} (VecT n M)functor M = record{ _<$>_ = λ f → mkVecT ∘′ (Vec.map f <$>_) ∘′ runVecT} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative {f} (VecT n M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkVecT ∘′ pure ∘′ Vec.replicate _; _<*>_ = λ mf ma → mkVecT (Vec.zipWith _$_ <$> runVecT mf <*> runVecT ma)} where open RawApplicative Mmonad : {M : Set f → Set g} → RawMonad M → RawMonad (VecT n M)monad {f} {g} M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma k → mkVecT $ doa ← runVecT mabs ← mapM {a = f} (runVecT ∘′ k) apure (Vec.diagonal bs)} where open RawMonad M; open Vec.TraversableM {m = f} {n = g} MmonadT : RawMonadT {f} {g} (VecT n)monadT M = record{ lift = mkVecT ∘′ (Vec.replicate _ <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Vec.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Categorical whereopen import Data.Vec.Effectful public{-# WARNING_ON_IMPORT"Data.Vec.Categorical was deprecated in v2.0.Use Data.Vec.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Vec.Effectful.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Categorical.Transformer whereopen import Data.Vec.Effectful.Transformer public{-# WARNING_ON_IMPORT"Data.Vec.Categorical.Transformer was deprecated in v2.0.Use Data.Vec.Effectful.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bounded vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Bounded whereopen import Level using (Level)open import Data.Nat.Base using (_≤_)open import Data.Vec.Base using (Vec)import Data.Vec as Vec using (filter; takeWhile; dropWhile)open import Function.Base using (id)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Unary using (Pred; Decidable)privatevariablea p : LevelA : Set a-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Data.Vec.Bounded.Base public-------------------------------------------------------------------------- Additional operationslift : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →(∀ {n} → Vec A n → Vec≤ A (f n)) →∀ {n} → Vec≤ A n → Vec≤ A (f n)lift incr f (as , p) = ≤-cast (incr p) (f as)lift′ : (∀ {n} → Vec A n → Vec≤ A n) →(∀ {n} → Vec≤ A n → Vec≤ A n)lift′ = lift id-------------------------------------------------------------------------- Additional operationsmodule _ {P : Pred A p} (P? : Decidable P) wherefilter : ∀ {n} → Vec≤ A n → Vec≤ A nfilter = lift′ (Vec.filter P?)takeWhile : ∀ {n} → Vec≤ A n → Vec≤ A ntakeWhile = lift′ (Vec.takeWhile P?)dropWhile : ∀ {n} → Vec≤ A n → Vec≤ A ndropWhile = lift′ (Vec.dropWhile P?)
-------------------------------------------------------------------------- The Agda standard library---- Showing bounded vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Bounded.Show whereopen import Data.String.Base using (String)open import Data.Vec.Bounded.Base using (Vec≤)import Data.Vec.Show as Vecopen import Function.Base using (_∘_)show : ∀ {a} {A : Set a} {n} → (A → String) → (Vec≤ A n → String)show s = Vec.show s ∘ Vec≤.vec
-------------------------------------------------------------------------- The Agda standard library---- Bounded vectors, basic types and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Bounded.Base whereopen import Data.Nat.Baseimport Data.Nat.Properties as ℕopen import Data.List.Base as List using (List)open import Data.List.Extrema ℕ.≤-totalOrderopen import Data.List.Relation.Unary.All as All using (All)import Data.List.Relation.Unary.All.Properties as Allopen import Data.List.Membership.Propositional using (mapWith∈)open import Data.Product.Base using (∃; _×_; _,_; proj₁; proj₂)open import Data.Vec.Base as Vec using (Vec)open import Data.These.Base as These using (These)open import Function.Base using (_∘_; id; _$_)open import Level using (Level)open import Relation.Nullary.Decidable.Core using (recompute)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; refl)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablea b c p : LevelA : Set aB : Set bC : Set cm n : ℕ-------------------------------------------------------------------------- Typesinfix 4 _,_record Vec≤ (A : Set a) (n : ℕ) : Set a whereconstructor _,_field {length} : ℕvec : Vec A length.bound : length ≤ n-- projection to recompute irrelevant fieldisBounded : (as : Vec≤ A n) → Vec≤.length as ≤ nisBounded as@(_ , m≤n) = recompute (_ ℕ.≤? _) m≤n-------------------------------------------------------------------------- Conversion functionstoVec : (as : Vec≤ A n) → Vec A (Vec≤.length as)toVec as@(vs , _) = vsfromVec : Vec A n → Vec≤ A nfromVec v = v , ℕ.≤-reflpadRight : A → Vec≤ A n → Vec A npadRight a as@(vs , m≤n)with k , refl ← ℕ.m≤n⇒∃[o]m+o≡n m≤n= vs Vec.++ Vec.replicate k apadLeft : A → Vec≤ A n → Vec A npadLeft a record { length = m ; vec = vs ; bound = m≤n }with k , refl ← ℕ.m≤n⇒∃[o]m+o≡n m≤nrewrite ℕ.+-comm m k= Vec.replicate k a Vec.++ vsprivatesplit : ∀ m k → m + k ≡ ⌊ k /2⌋ + (m + ⌈ k /2⌉)split m k = beginm + k ≡⟨ ≡.cong (m +_) (ℕ.⌊n/2⌋+⌈n/2⌉≡n k) ⟨m + (⌊ k /2⌋ + ⌈ k /2⌉) ≡⟨ ≡.cong (m +_) (ℕ.+-comm ⌊ k /2⌋ ⌈ k /2⌉) ⟩m + (⌈ k /2⌉ + ⌊ k /2⌋) ≡⟨ ℕ.+-assoc m ⌈ k /2⌉ ⌊ k /2⌋ ⟨m + ⌈ k /2⌉ + ⌊ k /2⌋ ≡⟨ ℕ.+-comm _ ⌊ k /2⌋ ⟩⌊ k /2⌋ + (m + ⌈ k /2⌉) ∎where open ≡-ReasoningpadBoth : A → A → Vec≤ A n → Vec A npadBoth aₗ aᵣ record { length = m ; vec = vs ; bound = m≤n }with k , refl ← ℕ.m≤n⇒∃[o]m+o≡n m≤nrewrite split m k= Vec.replicate ⌊ k /2⌋ aₗVec.++ vsVec.++ Vec.replicate ⌈ k /2⌉ aᵣfromList : (as : List A) → Vec≤ A (List.length as)fromList = fromVec ∘ Vec.fromListtoList : Vec≤ A n → List AtoList = Vec.toList ∘ toVec-------------------------------------------------------------------------- Creating new Vec≤ vectorsreplicate : .(m≤n : m ≤ n) → A → Vec≤ A nreplicate m≤n a = Vec.replicate _ a , m≤n[] : Vec≤ A n[] = Vec.[] , z≤ninfixr 5 _∷__∷_ : A → Vec≤ A n → Vec≤ A (suc n)a ∷ (as , p) = a Vec.∷ as , s≤s p-------------------------------------------------------------------------- Modifying Vec≤ vectors≤-cast : .(m≤n : m ≤ n) → Vec≤ A m → Vec≤ A n≤-cast m≤n (v , p) = v , ℕ.≤-trans p m≤n≡-cast : .(eq : m ≡ n) → Vec≤ A m → Vec≤ A n≡-cast m≡n = ≤-cast (ℕ.≤-reflexive m≡n)map : (A → B) → Vec≤ A n → Vec≤ B nmap f (v , p) = Vec.map f v , preverse : Vec≤ A n → Vec≤ A nreverse (v , p) = Vec.reverse v , p-- Align and Zip.alignWith : (These A B → C) → Vec≤ A n → Vec≤ B n → Vec≤ C nalignWith f (as , p) (bs , q) = Vec.alignWith f as bs , ℕ.⊔-lub p qzipWith : (A → B → C) → Vec≤ A n → Vec≤ B n → Vec≤ C nzipWith f (as , p) (bs , q) = Vec.restrictWith f as bs , ℕ.m≤n⇒m⊓o≤n _ pzip : Vec≤ A n → Vec≤ B n → Vec≤ (A × B) nzip = zipWith _,_align : Vec≤ A n → Vec≤ B n → Vec≤ (These A B) nalign = alignWith id-- take and droptake : ∀ n → Vec≤ A m → Vec≤ A (n ⊓ m)take zero _ = []take (suc n) (Vec.[] , p) = []take {m = suc m} (suc n) (a Vec.∷ as , p) = a ∷ take n (as , s≤s⁻¹ p)drop : ∀ n → Vec≤ A m → Vec≤ A (m ∸ n)drop zero v = vdrop (suc n) (Vec.[] , p) = []drop {m = suc m} (suc n) (a Vec.∷ as , p) = drop n (as , s≤s⁻¹ p)-------------------------------------------------------------------------- Lifting a collection of bounded vectors to the same sizerectangle : List (∃ (Vec≤ A)) → ∃ (List ∘ Vec≤ A)rectangle {A = A} rows = width , padded wheresizes = List.map proj₁ rowswidth = max 0 sizesall≤ : All (λ v → proj₁ v ≤ width) rowsall≤ = All.map⁻ (xs≤max 0 sizes)padded : List (Vec≤ A width)padded = mapWith∈ rows $ λ {x} x∈rows →≤-cast (All.lookup all≤ x∈rows) (proj₂ x)
-------------------------------------------------------------------------- The Agda standard library---- Vectors, basic types and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Vec.Base whereopen import Data.Bool.Base using (Bool; true; false; if_then_else_)open import Data.Nat.Baseopen import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base as List using (List)open import Data.Product.Base as Product using (∃; ∃₂; _×_; _,_; proj₁; proj₂)open import Data.These.Base as These using (These; this; that; these)open import Function.Base using (const; _∘′_; id; _∘_; _$_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; trans; cong)open import Relation.Nullary.Decidable.Core using (does; T?)open import Relation.Unary using (Pred; Decidable)privatevariablea b c p : LevelA : Set aB : Set bC : Set cm n : ℕ-------------------------------------------------------------------------- Typesinfixr 5 _∷_data Vec (A : Set a) : ℕ → Set a where[] : Vec A zero_∷_ : ∀ (x : A) (xs : Vec A n) → Vec A (suc n)infix 4 _[_]=_data _[_]=_ {A : Set a} : Vec A n → Fin n → A → Set a wherehere : ∀ {x} {xs : Vec A n} → x ∷ xs [ zero ]= xthere : ∀ {i} {x y} {xs : Vec A n}(xs[i]=x : xs [ i ]= x) → y ∷ xs [ suc i ]= x-------------------------------------------------------------------------- Basic operationslength : Vec A n → ℕlength {n = n} _ = nhead : Vec A (1 + n) → Ahead (x ∷ xs) = xtail : Vec A (1 + n) → Vec A ntail (x ∷ xs) = xslookup : Vec A n → Fin n → Alookup (x ∷ xs) zero = xlookup (x ∷ xs) (suc i) = lookup xs iiterate : (A → A) → A → ∀ n → Vec A niterate s z zero = []iterate s z (suc n) = z ∷ iterate s (s z) ninsertAt : Vec A n → Fin (suc n) → A → Vec A (suc n)insertAt xs zero v = v ∷ xsinsertAt (x ∷ xs) (suc i) v = x ∷ insertAt xs i vremoveAt : Vec A (suc n) → Fin (suc n) → Vec A nremoveAt (x ∷ xs) zero = xsremoveAt (x ∷ xs@(_ ∷ _)) (suc i) = x ∷ removeAt xs iupdateAt : Vec A n → Fin n → (A → A) → Vec A nupdateAt (x ∷ xs) zero f = f x ∷ xsupdateAt (x ∷ xs) (suc i) f = x ∷ updateAt xs i f-- xs [ i ]%= f modifies the i-th element of xs according to finfixl 6 _[_]%=_ _[_]≔__[_]%=_ : Vec A n → Fin n → (A → A) → Vec A nxs [ i ]%= f = updateAt xs i f-- xs [ i ]≔ y overwrites the i-th element of xs with y_[_]≔_ : Vec A n → Fin n → A → Vec A nxs [ i ]≔ y = xs [ i ]%= const y-------------------------------------------------------------------------- Operations for transforming vectors-- See README.Data.Vec.Relation.Binary.Equality.Cast for the reasoning-- system of `cast`-ed equality.cast : .(eq : m ≡ n) → Vec A m → Vec A ncast {n = zero} eq [] = []cast {n = suc _} eq (x ∷ xs) = x ∷ cast (cong pred eq) xsmap : (A → B) → Vec A n → Vec B nmap f [] = []map f (x ∷ xs) = f x ∷ map f xs-- Concatenation.infixr 5 _++__++_ : Vec A m → Vec A n → Vec A (m + n)[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ (xs ++ ys)concat : Vec (Vec A m) n → Vec A (n * m)concat [] = []concat (xs ∷ xss) = xs ++ concat xss-- Align, Restrict, and Zip.alignWith : (These A B → C) → Vec A m → Vec B n → Vec C (m ⊔ n)alignWith f [] bs = map (f ∘′ that) bsalignWith f as@(_ ∷ _) [] = map (f ∘′ this) asalignWith f (a ∷ as) (b ∷ bs) = f (these a b) ∷ alignWith f as bsrestrictWith : (A → B → C) → Vec A m → Vec B n → Vec C (m ⊓ n)restrictWith f [] bs = []restrictWith f (_ ∷ _) [] = []restrictWith f (a ∷ as) (b ∷ bs) = f a b ∷ restrictWith f as bszipWith : (A → B → C) → Vec A n → Vec B n → Vec C nzipWith f [] [] = []zipWith f (x ∷ xs) (y ∷ ys) = f x y ∷ zipWith f xs ysunzipWith : (A → B × C) → Vec A n → Vec B n × Vec C nunzipWith f [] = [] , []unzipWith f (a ∷ as) = Product.zip _∷_ _∷_ (f a) (unzipWith f as)align : Vec A m → Vec B n → Vec (These A B) (m ⊔ n)align = alignWith idrestrict : Vec A m → Vec B n → Vec (A × B) (m ⊓ n)restrict = restrictWith _,_zip : Vec A n → Vec B n → Vec (A × B) nzip = zipWith _,_unzip : Vec (A × B) n → Vec A n × Vec B nunzip = unzipWith id-- Interleaving.infixr 5 _⋎__⋎_ : Vec A m → Vec A n → Vec A (m +⋎ n)[] ⋎ ys = ys(x ∷ xs) ⋎ ys = x ∷ (ys ⋎ xs)-- Pointwise applicationinfixl 4 _⊛__⊛_ : Vec (A → B) n → Vec A n → Vec B n[] ⊛ [] = [](f ∷ fs) ⊛ (x ∷ xs) = f x ∷ (fs ⊛ xs)-- Multiplicationmodule CartesianBind whereinfixl 1 _>>=__>>=_ : Vec A m → (A → Vec B n) → Vec B (m * n)xs >>= f = concat (map f xs)infixl 4 _⊛*__⊛*_ : Vec (A → B) m → Vec A n → Vec B (m * n)fs ⊛* xs = fs CartesianBind.>>= λ f → map f xsallPairs : Vec A m → Vec B n → Vec (A × B) (m * n)allPairs xs ys = map _,_ xs ⊛* ys-- Diagonaldiagonal : Vec (Vec A n) n → Vec A ndiagonal [] = []diagonal (xs ∷ xss) = head xs ∷ diagonal (map tail xss)module DiagonalBind whereinfixl 1 _>>=__>>=_ : Vec A n → (A → Vec B n) → Vec B nxs >>= f = diagonal (map f xs)-------------------------------------------------------------------------- Operations for reducing vectors-- Dependent foldsmodule _ (A : Set a) (B : ℕ → Set b) whereFoldrOp = ∀ {n} → A → B n → B (suc n)FoldlOp = ∀ {n} → B n → A → B (suc n)foldr : ∀ (B : ℕ → Set b) → FoldrOp A B → B zero → Vec A n → B nfoldr B _⊕_ e [] = efoldr B _⊕_ e (x ∷ xs) = x ⊕ foldr B _⊕_ e xsfoldl : ∀ (B : ℕ → Set b) → FoldlOp A B → B zero → Vec A n → B nfoldl B _⊕_ e [] = efoldl B _⊕_ e (x ∷ xs) = foldl (B ∘ suc) _⊕_ (e ⊕ x) xs-- Non-dependent foldsfoldr′ : (A → B → B) → B → Vec A n → Bfoldr′ _⊕_ = foldr _ _⊕_foldl′ : (B → A → B) → B → Vec A n → Bfoldl′ _⊕_ = foldl _ _⊕_-- Non-empty foldsfoldr₁ : (A → A → A) → Vec A (suc n) → Afoldr₁ _⊕_ (x ∷ []) = xfoldr₁ _⊕_ (x ∷ y ∷ ys) = x ⊕ foldr₁ _⊕_ (y ∷ ys)foldl₁ : (A → A → A) → Vec A (suc n) → Afoldl₁ _⊕_ (x ∷ xs) = foldl _ _⊕_ x xs-- Special foldssum : Vec ℕ n → ℕsum = foldr _ _+_ 0count : ∀ {P : Pred A p} → Decidable P → Vec A n → ℕcount P? [] = zerocount P? (x ∷ xs) = if does (P? x) then suc else id $ count P? xscountᵇ : (A → Bool) → Vec A n → ℕcountᵇ p = count (T? ∘ p)-------------------------------------------------------------------------- Operations for building vectors[_] : A → Vec A 1[ x ] = x ∷ []replicate : (n : ℕ) → A → Vec A nreplicate zero x = []replicate (suc n) x = x ∷ replicate n xtabulate : (Fin n → A) → Vec A ntabulate {n = zero} f = []tabulate {n = suc n} f = f zero ∷ tabulate (f ∘ suc)allFin : ∀ n → Vec (Fin n) nallFin _ = tabulate id-------------------------------------------------------------------------- Operations for dividing vectorssplitAt : ∀ m {n} (xs : Vec A (m + n)) →∃₂ λ (ys : Vec A m) (zs : Vec A n) → xs ≡ ys ++ zssplitAt zero xs = [] , xs , reflsplitAt (suc m) (x ∷ xs) =let ys , zs , eq = splitAt m xs in x ∷ ys , zs , cong (x ∷_) eqtake : ∀ m {n} → Vec A (m + n) → Vec A mtake m xs = proj₁ (splitAt m xs)drop : ∀ m {n} → Vec A (m + n) → Vec A ndrop m xs = proj₁ (proj₂ (splitAt m xs))group : ∀ n k (xs : Vec A (n * k)) →∃ λ (xss : Vec (Vec A k) n) → xs ≡ concat xssgroup zero k [] = ([] , refl)group (suc n) k xs =let ys , zs , eq-split = splitAt k xs inlet zss , eq-group = group n k zs in(ys ∷ zss) , trans eq-split (cong (ys ++_) eq-group)split : Vec A n → Vec A ⌈ n /2⌉ × Vec A ⌊ n /2⌋split [] = ([] , [])split (x ∷ []) = (x ∷ [] , [])split (x ∷ y ∷ xs) = Product.map (x ∷_) (y ∷_) (split xs)uncons : Vec A (suc n) → A × Vec A nuncons (x ∷ xs) = x , xs-------------------------------------------------------------------------- Operations involving ≤-- Take the first 'm' elements of a vector.truncate : ∀ {m n} → m ≤ n → Vec A n → Vec A mtruncate {m = zero} _ _ = []truncate (s≤s le) (x ∷ xs) = x ∷ (truncate le xs)-- Pad out a vector with extra elements.padRight : ∀ {m n} → m ≤ n → A → Vec A m → Vec A npadRight z≤n a xs = replicate _ apadRight (s≤s le) a (x ∷ xs) = x ∷ padRight le a xs-------------------------------------------------------------------------- Operations for converting between liststoList : Vec A n → List AtoList [] = List.[]toList (x ∷ xs) = List._∷_ x (toList xs)fromList : (xs : List A) → Vec A (List.length xs)fromList List.[] = []fromList (List._∷_ x xs) = x ∷ fromList xs-------------------------------------------------------------------------- Operations for reversing vectors-- snocinfixl 5 _∷ʳ__∷ʳ_ : Vec A n → A → Vec A (suc n)[] ∷ʳ y = [ y ](x ∷ xs) ∷ʳ y = x ∷ (xs ∷ʳ y)-- vanilla reversereverse : Vec A n → Vec A nreverse = foldl (Vec _) (λ rev x → x ∷ rev) []-- reverse-appendinfix 5 _ʳ++__ʳ++_ : Vec A m → Vec A n → Vec A (m + n)xs ʳ++ ys = foldl (Vec _ ∘ (_+ _)) (λ rev x → x ∷ rev) ys xs-- init and lastinitLast : ∀ (xs : Vec A (1 + n)) → ∃₂ λ ys y → xs ≡ ys ∷ʳ yinitLast {n = zero} (x ∷ []) = [] , x , reflinitLast {n = suc n} (x ∷ xs) =let ys , y , eq = initLast xs inx ∷ ys , y , cong (x ∷_) eqinit : Vec A (1 + n) → Vec A ninit xs = proj₁ (initLast xs)last : Vec A (1 + n) → Alast xs = proj₁ (proj₂ (initLast xs))-------------------------------------------------------------------------- Other operationstranspose : Vec (Vec A n) m → Vec (Vec A m) ntranspose {n = n} [] = replicate n []transpose {n = n} (as ∷ ass) = ((replicate n _∷_) ⊛ as) ⊛ transpose ass-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0remove = removeAt{-# WARNING_ON_USAGE remove"Warning: remove was deprecated in v2.0.Please use removeAt instead."#-}insert = insertAt{-# WARNING_ON_USAGE insert"Warning: insert was deprecated in v2.0.Please use insertAt instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Universes------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Universe whereopen import Level-------------------------------------------------------------------------- Definitionrecord Universe u e : Set (suc (u ⊔ e)) wherefieldU : Set u -- Codes.El : U → Set e -- Decoding function.
-------------------------------------------------------------------------- The Agda standard library---- Indexed universes------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Universe.Indexed whereopen import Data.Product.Base using (∃; proj₂)open import Data.Universeopen import Function.Base using (_∘_)open import Level-------------------------------------------------------------------------- Definitionsrecord IndexedUniverse i u e : Set (suc (i ⊔ u ⊔ e)) wherefieldI : Set i -- Index set.U : I → Set u -- Codes.El : ∀ {i} → U i → Set e -- Decoding function.-- An indexed universe can be turned into an unindexed one.unindexed-universe : Universe (i ⊔ u) eunindexed-universe = record{ U = ∃ λ i → U i; El = El ∘ proj₂}
-------------------------------------------------------------------------- The Agda standard library---- The unit type, Level-monomorphic version------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit where-------------------------------------------------------------------------- Re-export contents of base moduleopen import Data.Unit.Base public-------------------------------------------------------------------------- Re-export query operationsopen import Data.Unit.Properties publicusing (_≟_)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the unit type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Properties whereopen import Data.Sum.Base using (inj₁)open import Data.Unit.Base using (⊤)open import Level using (0ℓ)open import Relation.Nullary using (Irrelevant; yes)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Poset; DecTotalOrder)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitions using (DecidableEquality; Total; Antisymmetric)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; trans)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; decSetoid; isEquivalence)-------------------------------------------------------------------------- Irrelevancy⊤-irrelevant : Irrelevant ⊤⊤-irrelevant _ _ = refl-------------------------------------------------------------------------- Equalityinfix 4 _≟__≟_ : DecidableEquality ⊤_ ≟ _ = yes refl≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid ⊤≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- Relational properties≡-total : Total {A = ⊤} _≡_≡-total _ _ = inj₁ refl≡-antisym : Antisymmetric {A = ⊤} _≡_ _≡_≡-antisym eq _ = eq-------------------------------------------------------------------------- Structures≡-isPreorder : IsPreorder {A = ⊤} _≡_ _≡_≡-isPreorder = record{ isEquivalence = isEquivalence; reflexive = λ x → x; trans = trans}≡-isPartialOrder : IsPartialOrder _≡_ _≡_≡-isPartialOrder = record{ isPreorder = ≡-isPreorder; antisym = ≡-antisym}≡-isTotalOrder : IsTotalOrder _≡_ _≡_≡-isTotalOrder = record{ isPartialOrder = ≡-isPartialOrder; total = ≡-total}≡-isDecTotalOrder : IsDecTotalOrder _≡_ _≡_≡-isDecTotalOrder = record{ isTotalOrder = ≡-isTotalOrder; _≟_ = _≟_; _≤?_ = _≟_}-------------------------------------------------------------------------- Bundles≡-poset : Poset 0ℓ 0ℓ 0ℓ≡-poset = record{ isPartialOrder = ≡-isPartialOrder}≡-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≡-decTotalOrder = record{ isDecTotalOrder = ≡-isDecTotalOrder}
-------------------------------------------------------------------------- The Agda standard library---- The universe polymorphic unit type and the total relation on unit------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Polymorphic where-------------------------------------------------------------------------- Re-export contents of Base moduleopen import Data.Unit.Polymorphic.Base public-------------------------------------------------------------------------- Re-export query operationsopen import Data.Unit.Polymorphic.Properties public using (_≟_)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the polymorphic unit type-- Defines Decidable Equality and Decidable Ordering as well------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Polymorphic.Properties whereopen import Level using (Level)open import Function.Bundles using (_↔_; mk↔)open import Data.Product.Base using (_,_)open import Data.Sum.Base using (inj₁)open import Data.Unit.Base renaming (⊤ to ⊤*)open import Data.Unit.Polymorphic.Base using (⊤; tt)open import Relation.Nullary.Decidable using (yes)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; Poset; TotalOrder; DecTotalOrder)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (DecidableEquality; Antisymmetric; Total)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; trans)open import Relation.Binary.PropositionalEquality.Propertiesusing (decSetoid; setoid; isEquivalence)privatevariableℓ : Level-------------------------------------------------------------------------- Equality------------------------------------------------------------------------infix 4 _≟__≟_ : DecidableEquality (⊤ {ℓ})_ ≟ _ = yes refl≡-setoid : ∀ ℓ → Setoid ℓ ℓ≡-setoid _ = setoid ⊤≡-decSetoid : ∀ ℓ → DecSetoid ℓ ℓ≡-decSetoid _ = decSetoid _≟_-------------------------------------------------------------------------- Ordering------------------------------------------------------------------------≡-total : Total {A = ⊤ {ℓ}} _≡_≡-total _ _ = inj₁ refl≡-antisym : Antisymmetric {A = ⊤ {ℓ}} _≡_ _≡_≡-antisym p _ = p-------------------------------------------------------------------------- Structures≡-isPreorder : ∀ ℓ → IsPreorder {ℓ} {_} {⊤} _≡_ _≡_≡-isPreorder ℓ = record{ isEquivalence = isEquivalence; reflexive = λ x → x; trans = trans}≡-isPartialOrder : ∀ ℓ → IsPartialOrder {ℓ} _≡_ _≡_≡-isPartialOrder ℓ = record{ isPreorder = ≡-isPreorder ℓ; antisym = ≡-antisym}≡-isTotalOrder : ∀ ℓ → IsTotalOrder {ℓ} _≡_ _≡_≡-isTotalOrder ℓ = record{ isPartialOrder = ≡-isPartialOrder ℓ; total = ≡-total}≡-isDecTotalOrder : ∀ ℓ → IsDecTotalOrder {ℓ} _≡_ _≡_≡-isDecTotalOrder ℓ = record{ isTotalOrder = ≡-isTotalOrder ℓ; _≟_ = _≟_; _≤?_ = _≟_}-------------------------------------------------------------------------- Bundles≡-preorder : ∀ ℓ → Preorder ℓ ℓ ℓ≡-preorder ℓ = record{ isPreorder = ≡-isPreorder ℓ}≡-poset : ∀ ℓ → Poset ℓ ℓ ℓ≡-poset ℓ = record{ isPartialOrder = ≡-isPartialOrder ℓ}≡-totalOrder : ∀ ℓ → TotalOrder ℓ ℓ ℓ≡-totalOrder ℓ = record{ isTotalOrder = ≡-isTotalOrder ℓ}≡-decTotalOrder : ∀ ℓ → DecTotalOrder ℓ ℓ ℓ≡-decTotalOrder ℓ = record{ isDecTotalOrder = ≡-isDecTotalOrder ℓ}⊤↔⊤* : ⊤ {ℓ} ↔ ⊤*⊤↔⊤* = mk↔ ((λ _ → refl) , (λ _ → refl))
-------------------------------------------------------------------------- The Agda standard library---- Instances for the polymorphic unit type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Polymorphic.Instances whereopen import Data.Unit.Polymorphic.Baseopen import Data.Unit.Polymorphic.Propertiesopen import Levelopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.TypeClassesusing (IsDecEquivalence; IsDecTotalOrder)privatevariablea : Levelinstance⊤-≡-isDecEquivalence : IsDecEquivalence {A = ⊤ {a}} _≡_⊤-≡-isDecEquivalence = isDecEquivalence _≟_⊤-≤-isDecTotalOrder : IsDecTotalOrder {A = ⊤ {a}} _≡_ _≡_⊤-≤-isDecTotalOrder = ≡-isDecTotalOrder _
-------------------------------------------------------------------------- The Agda standard library---- A universe polymorphic unit type, as a Lift of the Level 0 one.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Polymorphic.Base whereopen import Levelimport Data.Unit.Base as ⊤-------------------------------------------------------------------------- A unit type defined as a synonym⊤ : {ℓ : Level} → Set ℓ⊤ {ℓ} = Lift ℓ ⊤.⊤tt : {ℓ : Level} → ⊤ {ℓ}tt = lift ⊤.tt
-------------------------------------------------------------------------- The Agda standard library---- Some unit types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.NonEta whereopen import Level-------------------------------------------------------------------------- A unit type defined as a data-type-- The ⊤ type (see Data.Unit) comes with η-equality, which is often-- nice to have, but sometimes it is convenient to be able to stop-- unfolding (see "Hidden types" below).data Unit : Set whereunit : Unit-------------------------------------------------------------------------- Hidden types-- "Hidden" values.Hidden : ∀ {a} → Set a → Set aHidden A = Unit → A-- The hide function can be used to hide function applications. Note-- that the type-checker doesn't see that "hide f x" contains the-- application "f x".hide : ∀ {a b} {A : Set a} {B : A → Set b} →((x : A) → B x) → ((x : A) → Hidden (B x))hide f x unit = f x-- Reveals a hidden value.reveal : ∀ {a} {A : Set a} → Hidden A → Areveal f = f unit
-------------------------------------------------------------------------- The Agda standard library---- Instances for the unit type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Instances whereopen import Data.Unit.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instance⊤-≡-isDecEquivalence = isDecEquivalence _≟_⊤-≤-isDecTotalOrder = ≡-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- The unit type and the total relation on unit------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Unit.Base where-------------------------------------------------------------------------- A unit type defined as a record type-- Note that by default the unit type is not universe polymorphic as it-- often results in unsolved metas. See `Data.Unit.Polymorphic` for a-- universe polymorphic variant.-- Note also that the name of this type is "\top", not T.open import Agda.Builtin.Unit publicusing (⊤; tt)
-------------------------------------------------------------------------- The Agda standard library---- Trie, basic type and operations-------------------------------------------------------------------------- See README.Data.Trie.NonDependent for an example of using a trie to-- build a lexer.{-# OPTIONS --cubical-compatible --sized-types #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Trie {k e r} (S : StrictTotalOrder k e r) whereopen import Levelopen import Sizeopen import Data.List.Base using (List; []; _∷_; _++_)import Data.List.NonEmpty as List⁺open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe′)open import Data.Product.Base using (∃)open import Data.These.Base as These using (These)open import Function.Base using (_∘′_; const)open import Relation.Unary using (IUniversal; _⇒_)open StrictTotalOrder Susing (module Eq)renaming (Carrier to Key)open import Data.List.Relation.Binary.Equality.Setoid Eq.setoidopen import Data.Tree.AVL.Value ≋-setoid using (Value)-------------------------------------------------------------------------- Definition-- Trie is defined in terms of Trie⁺, the type of non-empty trie. This-- guarantees that the trie is minimal: each path in the tree leads to-- either a value or a number of non-empty sub-tries.open import Data.Trie.NonEmpty S as Trie⁺ publicusing (Trie⁺; Tries⁺; Word; eat)Trie : ∀ {v} (V : Value v) → Size → Set (v ⊔ k ⊔ e ⊔ r)Trie V i = Maybe (Trie⁺ V i)-------------------------------------------------------------------------- Operations-- Functions acting on Trie are wrappers for functions acting on Tries.-- Sometimes the empty case is handled in a special way (e.g. insertWith-- calls singleton when faced with an empty Trie).module _ {v} {V : Value v} whereprivate Val = Value.family V-------------------------------------------------------------------------- Lookuplookup : Trie V ∞ → ∀ ks → Maybe (These (Val ks) (Tries⁺ (eat V ks) ∞))lookup t ks = t Maybe.>>= λ ts → Trie⁺.lookup ts kslookupValue : Trie V ∞ → ∀ ks → Maybe (Val ks)lookupValue t ks = t Maybe.>>= λ ts → Trie⁺.lookupValue ts kslookupTries⁺ : Trie V ∞ → ∀ ks → Maybe (Tries⁺ (eat V ks) ∞)lookupTries⁺ t ks = t Maybe.>>= λ ts → Trie⁺.lookupTries⁺ ts kslookupTrie : Trie V ∞ → ∀ k → Trie (eat V (k ∷ [])) ∞lookupTrie t k = t Maybe.>>= λ ts → Trie⁺.lookupTrie⁺ ts k-------------------------------------------------------------------------- Constructionempty : Trie V ∞empty = nothingsingleton : ∀ ks → Val ks → Trie V ∞singleton ks v = just (Trie⁺.singleton ks v)insertWith : ∀ ks → (Maybe (Val ks) → Val ks) → Trie V ∞ → Trie V ∞insertWith ks f (just t) = just (Trie⁺.insertWith ks f t)insertWith ks f nothing = singleton ks (f nothing)insert : ∀ ks → Val ks → Trie V ∞ → Trie V ∞insert ks = insertWith ks ∘′ constfromList : List (∃ Val) → Trie V ∞fromList = Maybe.map Trie⁺.fromList⁺ ∘′ List⁺.fromListtoList : Trie V ∞ → List (∃ Val)toList (just t) = List⁺.toList (Trie⁺.toList⁺ t)toList nothing = []-------------------------------------------------------------------------- Modificationmodule _ {v w} {V : Value v} {W : Value w} whereprivateVal = Value.family VWal = Value.family Wmap : ∀ {i} → ∀[ Val ⇒ Wal ] → Trie V i → Trie W imap = Maybe.map ∘′ Trie⁺.map V W-- Deletionmodule _ {v} {V : Value v} where-- Use a function to decide how to modify the sub-Trie⁺ whose root is-- at the end of path ks.deleteWith : ∀ {i} (ks : Word) →(∀ {i} → Trie⁺ (eat V ks) i → Maybe (Trie⁺ (eat V ks) i)) →Trie V i → Trie V ideleteWith ks f t = t Maybe.>>= Trie⁺.deleteWith ks f-- Remove the whole nodedeleteTrie⁺ : ∀ {i} (ks : Word) → Trie V i → Trie V ideleteTrie⁺ ks t = t Maybe.>>= Trie⁺.deleteTrie⁺ ks-- Remove the value and keep the sub-Tries (if any)deleteValue : ∀ {i} (ks : Word) → Trie V i → Trie V ideleteValue ks t = t Maybe.>>= Trie⁺.deleteValue ks-- Remove the sub-Tries and keep the value (if any)deleteTries⁺ : ∀ {i} (ks : Word) → Trie V i → Trie V ideleteTries⁺ ks t = t Maybe.>>= Trie⁺.deleteTries⁺ ks
-------------------------------------------------------------------------- The Agda standard library---- Non empty trie, basic type and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Trie.NonEmpty {k e r} (S : StrictTotalOrder k e r) whereopen import Levelopen import Sizeopen import Effect.Monadopen import Data.Product.Base as Product using (∃; uncurry; -,_)open import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.NonEmpty as List⁺ using (List⁺; [_]; concatMap)open import Data.Maybe.Base as Maybe using (Maybe; nothing; just; maybe′) hiding (module Maybe)open import Data.These as These using (These; this; that; these)open import Function.Base as Fimport Function.Identity.Effectful as Identityopen import Relation.Unary using (_⇒_; IUniversal)open StrictTotalOrder Susing (module Eq)renaming (Carrier to Key)open import Data.List.Relation.Binary.Equality.Setoid Eq.setoidopen import Data.Tree.AVL.Value hiding (Value)open import Data.Tree.AVL.Value ≋-setoid using (Value)open import Data.Tree.AVL.NonEmpty S as Tree⁺ using (Tree⁺)open Value-------------------------------------------------------------------------- Definition-- A Trie⁺ is a tree branching over an alphabet of Keys. It stores-- values indexed over the Word (i.e. List Key) that was read to reach-- them. Each node in the Trie⁺ contains either a value, a non-empty-- Tree of sub-Trie⁺ reached by reading an extra letter, or both.Word : Set kWord = List Keyeat : ∀ {v} → Value v → Word → Value vfamily (eat V ks) = family V ∘′ (ks ++_)respects (eat V ks) = respects V ∘′ ++⁺ ≋-refldata Trie⁺ {v} (V : Value v) : Size → Set (v ⊔ k ⊔ e ⊔ r)Tries⁺ : ∀ {v} (V : Value v) (i : Size) → Set (v ⊔ k ⊔ e ⊔ r)map : ∀ {v w} (V : Value v) (W : Value w) {i} →∀[ family V ⇒ family W ] →Trie⁺ V i → Trie⁺ W idata Trie⁺ V wherenode : ∀ {i} → These (family V []) (Tries⁺ V i) → Trie⁺ V (↑ i)Tries⁺ V j = Tree⁺ $ MkValue (λ k → Trie⁺ (eat V (k ∷ [])) j)$ λ eq → map _ _ (respects V (eq ∷ ≋-refl))map V W f (node t) = node $ These.map f (Tree⁺.map (map _ _ f)) t-------------------------------------------------------------------------- Querylookup : ∀ {v} {V : Value v} → Trie⁺ V ∞ → ∀ ks →Maybe (These (family V ks) (Tries⁺ (eat V ks) ∞))lookup (node nd) [] = just (These.map₂ (Tree⁺.map id) nd)lookup (node nd) (k ∷ ks) = let open Maybe in dots ← These.fromThat ndt ← Tree⁺.lookup ts klookup t ksmodule _ {v} {V : Value v} wherelookupValue : Trie⁺ V ∞ → (ks : Word) → Maybe (family V ks)lookupValue t ks = lookup t ks Maybe.>>= These.fromThislookupTries⁺ : Trie⁺ V ∞ → ∀ ks → Maybe (Tries⁺ (eat V ks) ∞)lookupTries⁺ t ks = lookup t ks Maybe.>>= These.fromThatlookupTrie⁺ : Trie⁺ V ∞ → ∀ k → Maybe (Trie⁺ (eat V (k ∷ [])) ∞)lookupTrie⁺ t k = lookupTries⁺ t [] Maybe.>>= λ ts → Tree⁺.lookup ts k-------------------------------------------------------------------------- Constructionsingleton : ∀ {v} {V : Value v} ks → family V ks → Trie⁺ V ∞singleton [] v = node (this v)singleton (k ∷ ks) v = node (that (Tree⁺.singleton k (singleton ks v)))insertWith : ∀ {v} {V : Value v} ks → (Maybe (family V ks) → family V ks) →Trie⁺ V ∞ → Trie⁺ V ∞insertWith [] f (node nd) =node (These.fold (this ∘ f ∘ just) (these (f nothing)) (these ∘ f ∘ just) nd)insertWith {v} {V} (k ∷ ks) f (node {j} nd) = node $These.fold (λ v → these v (Tree⁺.singleton k end))(that ∘′ rec)(λ v → these v ∘′ rec)ndwhereend : Trie⁺ (eat V (k ∷ [])) ∞end = singleton ks (f nothing)rec : Tries⁺ V ∞ → Tries⁺ V ∞rec = Tree⁺.insertWith k (maybe′ (insertWith ks f) end)module _ {v} {V : Value v} whereprivate Val = family Vinsert : ∀ ks → Val ks → Trie⁺ V ∞ → Trie⁺ V ∞insert ks = insertWith ks ∘′ F.constfromList⁺ : List⁺ (∃ Val) → Trie⁺ V ∞fromList⁺ = List⁺.foldr (uncurry insert) (uncurry singleton)toList⁺ : ∀ {v} {V : Value v} {i} → let Val = Value.family V inTrie⁺ V i → List⁺ (∃ Val)toList⁺ (node nd) = These.mergeThese List⁺._⁺++⁺_$ These.map fromVal fromTries⁺ ndwherefromVal = [_] ∘′ -,_fromTrie⁺ = λ (k , v) → List⁺.map (Product.map (k ∷_) id) (toList⁺ v)fromTries⁺ = concatMap fromTrie⁺ ∘′ Tree⁺.toList⁺-------------------------------------------------------------------------- Modification-- DeletiondeleteWith : ∀ {v} {V : Value v} {i} ks →(∀ {i} → Trie⁺ (eat V ks) i → Maybe (Trie⁺ (eat V ks) i)) →Trie⁺ V i → Maybe (Trie⁺ V i)deleteWith [] f t = f tdeleteWith (k ∷ ks) f t@(node nd) = let open RawMonad Identity.monad in dojust ts ← These.fromThat nd where _ → just t-- This would be a lot cleaner if we had-- Tree⁺.updateWith : ∀ k → (Maybe (V k) → Maybe (V k)) → AVL → AVL-- Instead we lookup the subtree, update it and either put it back in-- or delete the corresponding leaf depending on whether the result is successful.just t′ ← Tree⁺.lookup ts k where _ → just tMaybe.map node ∘′ Maybe.align (These.fromThis nd) $′ case deleteWith ks f t′ of λ wherenothing → Tree⁺.delete k ts(just u) → just (Tree⁺.insert k u ts)module _ {v} {V : Value v} wheredeleteTrie⁺ : ∀ {i} (ks : Word) → Trie⁺ V i → Maybe (Trie⁺ V i)deleteTrie⁺ ks = deleteWith ks (F.const nothing)deleteValue : ∀ {i} (ks : Word) → Trie⁺ V i → Maybe (Trie⁺ V i)deleteValue ks = deleteWith ks $ λ where(node nd) → Maybe.map node $′ These.deleteThis nddeleteTries⁺ : ∀ {i} (ks : Word) → Trie⁺ V i → Maybe (Trie⁺ V i)deleteTries⁺ ks = deleteWith ks $ λ where(node nd) → Maybe.map node $′ These.deleteThat nd
-------------------------------------------------------------------------- The Agda standard library---- Rose trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Data.Tree.Rose whereopen import Level using (Level)open import Sizeopen import Data.List.Base as List using (List; []; _∷_)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Data.List.Extrema.Natimport Data.Tree.Binary as Binopen import Function.Base using (_∘_)privatevariablea : LevelA B C : Set ai : Size-------------------------------------------------------------------------- Type and basic constructionsdata Rose (A : Set a) : Size → Set a wherenode : (a : A) (ts : List (Rose A i)) → Rose A (↑ i)leaf : A → Rose A ∞leaf a = node a []-------------------------------------------------------------------------- Transforming rose treesmap : (A → B) → Rose A i → Rose B imap f (node a ts) = node (f a) (List.map (map f) ts)-------------------------------------------------------------------------- Reducing rose treesfoldr : (A → List B → B) → Rose A i → Bfoldr n (node a ts) = n a (List.map (foldr n) ts)depth : Rose A i → ℕdepth (node a ts) = suc (max 0 (List.map depth ts))-------------------------------------------------------------------------- Conversion from binary treesmodule _ (fromNode : A → C) (fromLeaf : B → C) wherefromBinary : Bin.Tree A B → Rose C ∞fromBinary (Bin.leaf x) = node (fromLeaf x) []fromBinary (Bin.node l x r) = node (fromNode x)(fromBinary l ∷ fromBinary r ∷ [])
-------------------------------------------------------------------------- The Agda standard library---- 1 dimensional pretty printing of rose trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Data.Tree.Rose.Show whereopen import Level using (Level)open import Sizeopen import Data.Bool.Base using (Bool; true; false; if_then_else_; _∧_)open import Data.DifferenceList as DList renaming (DiffList to DList) using ()open import Data.List.Base as List using (List; []; [_]; _∷_; _∷ʳ_)open import Data.Nat.Base using (ℕ; _∸_)open import Data.Product.Base using (_×_; _,_)open import Data.String.Base using (String; _++_)open import Data.Tree.Rose using (Rose; node; map; fromBinary)open import Function.Base using (flip; _∘′_; id)privatevariablea : LevelA : Set ai : Sizedisplay : Rose (List String) i → List Stringdisplay t = DList.toList (go (([] , t) ∷ []))wherepadding : Bool → List Bool → String → Stringpadding dir? [] str = strpadding dir? (b ∷ bs) str =(if dir? ∧ List.null bsthen if b then " ├ " else " └ "else if b then " │ " else " ")++ padding dir? bs strnodePrefixes : List A → List BoolnodePrefixes as = true ∷ List.replicate (List.length as ∸ 1) falsechildrenPrefixes : List A → List BoolchildrenPrefixes as = List.replicate (List.length as ∸ 1) true ∷ʳ falsego : List (List Bool × Rose (List String) i) → DList Stringgo [] = DList.[]go ((bs , node a ts₁) ∷ ts) =let bs′ = List.reverse bs inDList.fromList (List.zipWith (flip padding bs′) (nodePrefixes a) a)DList.++ go (List.zip (List.map (_∷ bs) (childrenPrefixes ts₁)) ts₁)DList.++ go tsshow : (A → List String) → Rose A i → List Stringshow toString = display ∘′ map toStringshowSimple : (A → String) → Rose A i → List StringshowSimple toString = show ([_] ∘′ toString)
-------------------------------------------------------------------------- The Agda standard library---- Properties of rose trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Data.Tree.Rose.Properties whereopen import Level using (Level)open import Sizeopen import Data.List.Base as List using (List)open import Data.List.Extrema.Nat using (max)import Data.List.Properties as Listopen import Data.Nat.Base using (ℕ; zero; suc)open import Data.Tree.Rose using (Rose; node; map; depth; foldr)open import Function.Base using (_∘′_; _$_; _∘_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablea b c : LevelA : Set aB : Set bC : Set ci : Size-------------------------------------------------------------------------- map propertiesmap-∘ : (f : A → B) (g : B → C) →map {i = i} (g ∘′ f) ≗ map {i = i} g ∘′ map {i = i} fmap-∘ f g (node a ts) = cong (node (g (f a))) $ beginList.map (map (g ∘′ f)) ts ≡⟨ List.map-cong (map-∘ f g) ts ⟩List.map (map g ∘ map f) ts ≡⟨ List.map-∘ ts ⟩List.map (map g) (List.map (map f) ts) ∎depth-map : (f : A → B) (t : Rose A i) → depth {i = i} (map {i = i} f t) ≡ depth {i = i} tdepth-map f (node a ts) = cong (suc ∘′ max 0) $ beginList.map depth (List.map (map f) ts) ≡⟨ List.map-∘ ts ⟨List.map (depth ∘′ map f) ts ≡⟨ List.map-cong (depth-map f) ts ⟩List.map depth ts ∎-------------------------------------------------------------------------- foldr propertiesfoldr-map : (f : A → B) (n : B → List C → C) (ts : Rose A i) →foldr {i = i} n (map {i = i} f ts) ≡ foldr {i = i} (n ∘′ f) tsfoldr-map f n (node a ts) = cong (n (f a)) $ beginList.map (foldr n) (List.map (map f) ts) ≡⟨ List.map-∘ ts ⟨List.map (foldr n ∘′ map f) ts ≡⟨ List.map-cong (foldr-map f n) ts ⟩List.map (foldr (n ∘′ f)) ts ∎-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.0.Please use map-∘ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Binary Trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary whereopen import Level using (Level; _⊔_)open import Data.List.Base using (List)open import Data.DifferenceList as DiffList using (DiffList; []; _∷_; _∷ʳ_; _++_; [_])open import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Function.Baseprivatevariablen l n₁ l₁ a : LevelN : Set nL : Set lN₁ : Set n₁L₁ : Set l₁A : Set a-- Trees with node values of type N and leaf values of type Ldata Tree (N : Set n) (L : Set l) : Set (n ⊔ l) whereleaf : L → Tree N Lnode : Tree N L → N → Tree N L → Tree N Lmap : (N → N₁) → (L → L₁) → Tree N L → Tree N₁ L₁map f g (leaf x) = leaf (g x)map f g (node l m r) = node (map f g l) (f m) (map f g r)mapₙ : (N → N₁) → Tree N L → Tree N₁ Lmapₙ f t = map f id tmapₗ : (L → L₁) → Tree N L → Tree N L₁mapₗ f t = map id f t#nodes : Tree N L → ℕ#nodes (leaf x) = 0#nodes (node l m r) = #nodes l + suc (#nodes r)#leaves : Tree N L → ℕ#leaves (leaf x) = 1#leaves (node l m r) = #leaves l + #leaves rfoldr : (A → N → A → A) → (L → A) → Tree N L → Afoldr f g (leaf x) = g xfoldr f g (node l m r) = f (foldr f g l) m (foldr f g r)-------------------------------------------------------------------------- Extraction to lists, depth first and left to right.module Prefix wheretoDiffList : Tree N L → DiffList NtoDiffList = foldr (λ l m r → m ∷ l ++ r) (λ _ → [])toList : Tree N L → List NtoList = DiffList.toList ∘′ toDiffListmodule Infix wheretoDiffList : Tree N L → DiffList NtoDiffList = foldr (λ l m r → l ++ m ∷ r) (λ _ → [])toList : Tree N L → List NtoList = DiffList.toList ∘′ toDiffListmodule Suffix wheretoDiffList : Tree N L → DiffList NtoDiffList = foldr (λ l m r → l ++ r ∷ʳ m) (λ _ → [])toList : Tree N L → List NtoList = DiffList.toList ∘′ toDiffListmodule Leaves wheretoDiffList : Tree N L → DiffList LtoDiffList (leaf x) = [ x ]toDiffList (node l m r) = toDiffList l ++ toDiffList rtoList : Tree N L → List LtoList = DiffList.toList ∘′ toDiffList
-------------------------------------------------------------------------- The Agda standard library---- Zippers for Binary Trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary.Zipper whereopen import Level using (Level; _⊔_)open import Data.Tree.Binary as BT using (Tree; node; leaf)open import Data.List.Base as List using (List; []; _∷_; sum; _++_; [_])open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Nat.Base using (ℕ; suc; _+_)open import Function.Base using (_$_; _∘_)privatevariablea n n₁ l l₁ : LevelA : Set aN : Set nN₁ : Set n₁L : Set lL₁ : Set l₁data Crumb (N : Set n) (L : Set l) : Set (n ⊔ l) whereleftBranch : N → Tree N L → Crumb N LrightBranch : N → Tree N L → Crumb N Lrecord Zipper (N : Set n) (L : Set l) : Set (n ⊔ l) whereconstructor mkZipperfieldcontext : List (Crumb N L)focus : Tree N Lopen Zipper public-------------------------------------------------------------------------- Fundamental operations of a Zipper: Moving aroundup : Zipper N L → Maybe (Zipper N L)up (mkZipper [] foc) = nothingup (mkZipper (leftBranch m l ∷ ctx) foc) = just $ mkZipper ctx (node l m foc)up (mkZipper (rightBranch m r ∷ ctx) foc) = just $ mkZipper ctx (node foc m r)left : Zipper N L → Maybe (Zipper N L)left (mkZipper ctx (leaf x)) = nothingleft (mkZipper ctx (node l m r)) = just $ mkZipper (rightBranch m r ∷ ctx) lright : Zipper N L → Maybe (Zipper N L)right (mkZipper ctx (leaf x)) = nothingright (mkZipper ctx (node l m r)) = just $ mkZipper (leftBranch m l ∷ ctx) r-------------------------------------------------------------------------- To and from treesplug : List (Crumb N L) → Tree N L → Tree N Lplug [] t = tplug (leftBranch m l ∷ xs) t = plug xs (node l m t)plug (rightBranch m r ∷ xs) t = plug xs (node t m r)toTree : Zipper N L → Tree N LtoTree (mkZipper ctx foc) = plug ctx focfromTree : Tree N L → Zipper N LfromTree = mkZipper []-------------------------------------------------------------------------- Tree-like operationsgetTree : Crumb N L → Tree N LgetTree (leftBranch m x) = xgetTree (rightBranch m x) = xmapCrumb : (N → N₁) → (L → L₁) → Crumb N L → Crumb N₁ L₁mapCrumb f g (leftBranch m x) = leftBranch (f m) (BT.map f g x)mapCrumb f g (rightBranch m x) = rightBranch (f m) (BT.map f g x)#nodes : Zipper N L → ℕ#nodes (mkZipper ctx foc) = BT.#nodes foc + sum (List.map (suc ∘ BT.#nodes ∘ getTree) ctx)#leaves : Zipper N L → ℕ#leaves (mkZipper ctx foc) = BT.#leaves foc + sum (List.map (BT.#leaves ∘ getTree) ctx)map : (N → N₁) → (L → L₁) → Zipper N L → Zipper N₁ L₁map f g (mkZipper ctx foc) = mkZipper (List.map (mapCrumb f g) ctx) (BT.map f g foc)foldr : (A → N → A → A) → (L → A) → Zipper N L → Afoldr {A = A} {N = N} {L = L} f g (mkZipper ctx foc) = List.foldl step (BT.foldr f g foc) ctxwherestep : A → Crumb N L → Astep val (leftBranch m x) = f (BT.foldr f g x) m valstep val (rightBranch m x) = f val m (BT.foldr f g x)-------------------------------------------------------------------------- Attach nodes to the top most part of the zipperattach : Zipper N L → List (Crumb N L) → Zipper N Lattach (mkZipper ctx foc) xs = mkZipper (ctx ++ xs) focinfixr 5 _⟪_⟫ˡ_infixl 5 _⟪_⟫ʳ__⟪_⟫ˡ_ : Tree N L → N → Zipper N L → Zipper N Ll ⟪ m ⟫ˡ zp = attach zp [ leftBranch m l ]_⟪_⟫ʳ_ : Zipper N L → N → Tree N L → Zipper N Lzp ⟪ m ⟫ʳ r = attach zp [ rightBranch m r ]
-------------------------------------------------------------------------- The Agda standard library---- Tree Zipper-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary.Zipper.Properties whereopen import Data.List.Base as List using (List ; [] ; _∷_; sum)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.All using (All; just; nothing)open import Data.Nat.Base using (ℕ; suc; _+_)open import Data.Nat.Properties using (+-identityʳ; +-comm; +-assoc)open import Data.Tree.Binary as BT using (Tree; node; leaf)open import Data.Tree.Binary.Zipper using (Zipper; toTree; up; mkZipper;leftBranch; rightBranch; left; right; #nodes; Crumb; getTree; #leaves;map; foldr; _⟪_⟫ˡ_; _⟪_⟫ʳ_)open import Function.Base using (_on_; _∘_; _$_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablea n l n₁ l₁ : LevelA : Set aN : Set nL : Set lN₁ : Set n₁L₁ : Set l₁-- Invariant: Zipper represents a given tree-- Stability under movingtoTree-up-identity : (zp : Zipper N L) → All ((_≡_ on toTree) zp) (up zp)toTree-up-identity (mkZipper [] foc) = nothingtoTree-up-identity (mkZipper (leftBranch m l ∷ ctx) foc) = just refltoTree-up-identity (mkZipper (rightBranch m r ∷ ctx) foc) = just refltoTree-left-identity : (zp : Zipper N L) → All ((_≡_ on toTree) zp) (left zp)toTree-left-identity (mkZipper ctx (leaf x)) = nothingtoTree-left-identity (mkZipper ctx (node l m r)) = just refltoTree-right-identity : (zp : Zipper N L) → All ((_≡_ on toTree) zp) (right zp)toTree-right-identity (mkZipper ctx (leaf x)) = nothingtoTree-right-identity (mkZipper ctx (node l m r)) = just refl-------------------------------------------------------------------------- Tree-like operations indeed correspond to their counterpartstoTree-#nodes : ∀ (zp : Zipper N L) → #nodes zp ≡ BT.#nodes (toTree zp)toTree-#nodes (mkZipper c v) = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →#nodes (mkZipper cs t) ≡ BT.#nodes (toTree (mkZipper cs t))helper [] foc = +-identityʳ (BT.#nodes foc)helper cs@(leftBranch m l ∷ ctx) foc = let#ctx = sum (List.map (suc ∘ BT.#nodes ∘ getTree) ctx)#foc = BT.#nodes foc#l = BT.#nodes l in begin#foc + (1 + (#l + #ctx)) ≡⟨ +-assoc #foc 1 (#l + #ctx) ⟨#foc + 1 + (#l + #ctx) ≡⟨ cong (_+ (#l + #ctx)) (+-comm #foc 1) ⟩1 + #foc + (#l + #ctx) ≡⟨ +-assoc (1 + #foc) #l #ctx ⟨1 + #foc + #l + #ctx ≡⟨ cong (_+ #ctx) (+-comm (1 + #foc) #l) ⟩#nodes (mkZipper ctx (node l m foc)) ≡⟨ helper ctx (node l m foc) ⟩BT.#nodes (toTree (mkZipper cs foc)) ∎helper cs@(rightBranch m r ∷ ctx) foc = let#ctx = sum (List.map (suc ∘ BT.#nodes ∘ getTree) ctx)#foc = BT.#nodes foc#r = BT.#nodes r in begin#foc + (1 + (#r + #ctx)) ≡⟨ cong (#foc +_) (+-assoc 1 #r #ctx) ⟨#foc + (1 + #r + #ctx) ≡⟨ +-assoc #foc (suc #r) #ctx ⟨#nodes (mkZipper ctx (node foc m r)) ≡⟨ helper ctx (node foc m r) ⟩BT.#nodes (toTree (mkZipper cs foc)) ∎toTree-#leaves : ∀ (zp : Zipper N L) → #leaves zp ≡ BT.#leaves (toTree zp)toTree-#leaves (mkZipper c v) = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →#leaves (mkZipper cs t) ≡ BT.#leaves (toTree (mkZipper cs t))helper [] foc = +-identityʳ (BT.#leaves foc)helper cs@(leftBranch m l ∷ ctx) foc = let#ctx = sum (List.map (BT.#leaves ∘ getTree) ctx)#foc = BT.#leaves foc#l = BT.#leaves l in begin#foc + (#l + #ctx) ≡⟨ +-assoc #foc #l #ctx ⟨#foc + #l + #ctx ≡⟨ cong (_+ #ctx) (+-comm #foc #l) ⟩#leaves (mkZipper ctx (node l m foc)) ≡⟨ helper ctx (node l m foc) ⟩BT.#leaves (toTree (mkZipper cs foc)) ∎helper cs@(rightBranch m r ∷ ctx) foc = let#ctx = sum (List.map (BT.#leaves ∘ getTree) ctx)#foc = BT.#leaves foc#r = BT.#leaves r in begin#foc + (#r + #ctx) ≡⟨ +-assoc #foc #r #ctx ⟨#leaves (mkZipper ctx (node foc m r)) ≡⟨ helper ctx (node foc m r) ⟩BT.#leaves (toTree (mkZipper cs foc)) ∎toTree-map : ∀ (f : N → N₁) (g : L → L₁) zp → toTree (map f g zp) ≡ BT.map f g (toTree zp)toTree-map {N = N} {L = L} f g (mkZipper c v) = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →toTree (map f g (mkZipper cs t)) ≡ BT.map f g (toTree (mkZipper cs t))helper [] foc = reflhelper (leftBranch m l ∷ ctx) foc = helper ctx (node l m foc)helper (rightBranch m r ∷ ctx) foc = helper ctx (node foc m r)toTree-foldr : ∀ (f : A → N → A → A) (g : L → A) zp → foldr f g zp ≡ BT.foldr f g (toTree zp)toTree-foldr {N = N} {L = L} f g (mkZipper c v) = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →foldr f g (mkZipper cs t) ≡ BT.foldr f g (toTree (mkZipper cs t))helper [] foc = reflhelper (leftBranch m l ∷ ctx) foc = helper ctx (node l m foc)helper (rightBranch m r ∷ ctx) foc = helper ctx (node foc m r)-------------------------------------------------------------------------- Properties of the building functions-- _⟪_⟫ˡ_ propertiestoTree-⟪⟫ˡ : ∀ l m (zp : Zipper N L) → toTree (l ⟪ m ⟫ˡ zp) ≡ node l m (toTree zp)toTree-⟪⟫ˡ {N = N} {L = L} l m (mkZipper c v) = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →toTree (l ⟪ m ⟫ˡ mkZipper cs t) ≡ node l m (toTree $ mkZipper cs t)helper [] foc = reflhelper (leftBranch m l ∷ ctx) foc = helper ctx (node l m foc)helper (rightBranch m r ∷ ctx) foc = helper ctx (node foc m r)-- _⟪_⟫ʳ_ propertiestoTree-⟪⟫ʳ : ∀ (zp : Zipper N L) m r → toTree (zp ⟪ m ⟫ʳ r) ≡ node (toTree zp) m rtoTree-⟪⟫ʳ {N = N} {L = L} (mkZipper c v) m r = helper c vwherehelper : (cs : List (Crumb N L)) →(t : Tree N L) →toTree (mkZipper cs t ⟪ m ⟫ʳ r) ≡ node (toTree $ mkZipper cs t) m rhelper [] foc = reflhelper (leftBranch m l ∷ ctx) foc = helper ctx (node l m foc)helper (rightBranch m r ∷ ctx) foc = helper ctx (node foc m r)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0toTree-#nodes-commute = toTree-#nodes{-# WARNING_ON_USAGE toTree-#nodes-commute"Warning: toTree-#nodes-commute was deprecated in v2.0.Please use toTree-#nodes instead."#-}toTree-#leaves-commute = toTree-#leaves{-# WARNING_ON_USAGE toTree-#leaves-commute"Warning: toTree-#leaves-commute was deprecated in v2.0.Please use toTree-#leaves instead."#-}toTree-map-commute = toTree-map{-# WARNING_ON_USAGE toTree-map-commute"Warning: toTree-map-commute was deprecated in v2.0.Please use toTree-map instead."#-}toTree-foldr-commute = toTree-foldr{-# WARNING_ON_USAGE toTree-foldr-commute"Warning: toTree-foldr-commute was deprecated in v2.0.Please use toTree-foldr instead."#-}toTree-⟪⟫ˡ-commute = toTree-⟪⟫ˡ{-# WARNING_ON_USAGE toTree-⟪⟫ˡ-commute"Warning: toTree-⟪⟫ˡ-commute was deprecated in v2.0.Please use toTree-⟪⟫ˡ instead."#-}toTree-⟪⟫ʳ-commute = toTree-⟪⟫ʳ{-# WARNING_ON_USAGE toTree-⟪⟫ʳ-commute"Warning: toTree-⟪⟫ʳ-commute was deprecated in v2.0.Please use toTree-⟪⟫ʳ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- 1 dimensional pretty printing of binary trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}open import Level using (Level)open import Data.List.Base as List using (List; []; [_]; _∷_; _∷ʳ_)open import Data.String.Base using (String)import Data.Tree.Rose as Roseimport Data.Tree.Rose.Show as Roseopen import Data.Tree.Binary using (Tree; map)open import Function.Base using (_∘′_; id)module Data.Tree.Binary.Show whereprivatevariablea : LevelN L : Set adisplay : Tree (List String) (List String) → List Stringdisplay = Rose.display ∘′ Rose.fromBinary id idshow : (N → List String) → (L → List String) → Tree N L → List Stringshow nodeStr leafStr = display ∘′ map nodeStr leafStrshowSimple : (N → String) → (L → String) → Tree N L → List StringshowSimple nodeStr leafStr = show ([_] ∘′ nodeStr) ([_] ∘′ leafStr)
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of a predicate to a binary tree------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary.Relation.Unary.All whereopen import Levelopen import Data.Tree.Binary as Tree using (Tree; leaf; node)open import Relation.Unaryopen import Relation.Unary.Properties using (⊆-refl)privatevariablen l p q r s : LevelN : Set nL : Set lP : N → Set pQ : L → Set qR : N → Set rS : L → Set sdata All {N : Set n} {L : Set l} (P : N → Set p) (Q : L → Set q) : Tree N L → Set (n ⊔ l ⊔ p ⊔ q) whereleaf : ∀ {x} → Q x → All P Q (leaf x)node : ∀ {l m r} → All P Q l → P m → All P Q r → All P Q (node l m r)map : ∀[ P ⇒ R ] → ∀[ Q ⇒ S ] → ∀[ All P Q ⇒ All R S ]map f g (leaf x) = leaf (g x)map f g (node l m r) = node (map f g l) (f m) (map f g r)mapₙ : ∀[ P ⇒ R ] → ∀[ All P Q ⇒ All R Q ]mapₙ {Q = Q} f = map f (⊆-refl {x = Q})mapₗ : ∀[ Q ⇒ S ] → ∀[ All P Q ⇒ All P S ]mapₗ {P = P} f = map (⊆-refl {x = P}) f
-------------------------------------------------------------------------- The Agda standard library---- Properties of the pointwise lifting of a predicate to a binary tree------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary.Relation.Unary.All.Properties whereopen import Levelopen import Data.Tree.Binary as Tree using (Tree; leaf; node)open import Data.Tree.Binary.Relation.Unary.Allopen import Relation.Unaryopen import Function.Base using (id)privatevariablen l n₁ l₁ p q : LevelN : Set nL : Set lN₁ : Set n₁L₁ : Set l₁P : N₁ → Set pQ : L₁ → Set qmap⁺ : (f : N → N₁) → (g : L → L₁) → All (f ⊢ P) (g ⊢ Q) ⊆ Tree.map f g ⊢ All P Qmap⁺ f g (leaf x) = leaf xmap⁺ f g (node l m r) = node (map⁺ f g l) m (map⁺ f g r)mapₙ⁺ : (f : N → N₁) → All (f ⊢ P) Q ⊆ Tree.mapₙ f ⊢ All P Qmapₙ⁺ f = map⁺ f idmapₗ⁺ : (g : L → L₁) → All P (g ⊢ Q) ⊆ Tree.mapₗ g ⊢ All P Qmapₗ⁺ g = map⁺ id g
-------------------------------------------------------------------------- The Agda standard library---- Properties of binary trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.Binary.Properties whereopen import Function.Base using (_∘_)open import Function.Nary.NonDependent using (congₙ)open import Level using (Level)open import Data.Nat.Base using (suc; _+_)open import Data.Tree.Binaryopen import Function.Base using (id; flip)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; _≗_)privatevariablea n n₁ n₂ l l₁ l₂ : LevelA : Set aN : Set nN₁ : Set n₁N₂ : Set n₂L : Set lL₁ : Set l₁L₂ : Set l₂#nodes-map : ∀ (f : N → N₁) (g : L → L₁) t → #nodes (map f g t) ≡ #nodes t#nodes-map f g (leaf x) = refl#nodes-map f g (node l m r) =cong₂ (λ l r → l + suc r) (#nodes-map f g l) (#nodes-map f g r)#nodes-mapₙ : ∀ (f : N → N₁) (t : Tree N L) → #nodes (mapₙ f t) ≡ #nodes t#nodes-mapₙ f = #nodes-map f id#nodes-mapₗ : ∀ (g : L → L₁) (t : Tree N L) → #nodes (mapₗ g t) ≡ #nodes t#nodes-mapₗ = #nodes-map id#leaves-map : ∀ (f : N → N₁) (g : L → L₁) t → #leaves (map f g t) ≡ #leaves t#leaves-map f g (leaf x) = refl#leaves-map f g (node l m r) =cong₂ _+_ (#leaves-map f g l) (#leaves-map f g r)#leaves-mapₙ : ∀ (f : N → N₁) (t : Tree N L) → #leaves (mapₙ f t) ≡ #leaves t#leaves-mapₙ f = #leaves-map f id#leaves-mapₗ : ∀ (g : L → L₁) (t : Tree N L) → #leaves (mapₗ g t) ≡ #leaves t#leaves-mapₗ = #leaves-map idmap-id : ∀ (t : Tree N L) → map id id t ≡ tmap-id (leaf x) = reflmap-id (node l v r) = cong₂ (flip node v) (map-id l) (map-id r)map-compose : ∀ {f₁ : N₁ → N₂} {f₂ : N → N₁} {g₁ : L₁ → L₂} {g₂ : L → L₁} →map (f₁ ∘ f₂) (g₁ ∘ g₂) ≗ map f₁ g₁ ∘ map f₂ g₂map-compose (leaf x) = reflmap-compose (node l v r) = cong₂ (λ l r → node l _ r) (map-compose l) (map-compose r)map-cong : ∀ {f₁ f₂ : N → N₁} {g₁ g₂ : L → L₁} → f₁ ≗ f₂ → g₁ ≗ g₂ → map f₁ g₁ ≗ map f₂ g₂map-cong p q (leaf x) = cong leaf (q x)map-cong p q (node l v r) = congₙ 3 node (map-cong p q l) (p v) (map-cong p q r)
-------------------------------------------------------------------------- The Agda standard library---- AVL trees-------------------------------------------------------------------------- AVL trees are balanced binary search trees.-- The search tree invariant is specified using the technique-- described by Conor McBride in his talk "Pivotal pragmatism".-- See README.Data.Tree.AVL for examples of how to use AVL trees.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (Bool)import Data.DifferenceList as DiffListopen import Data.List.Base as List using (List; []; _∷_)open import Data.Maybe.Base using (Maybe; nothing; just; is-just)open import Data.Nat.Base using (ℕ; suc)open import Data.Product.Base hiding (map)open import Function.Base as Fopen import Level using (Level; _⊔_)open import Relation.Unary using (IUniversal; _⇒_)privatevariablel : LevelA : Set lopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)import Data.Tree.AVL.Indexed strictTotalOrder as Indexedopen Indexed using (⊥⁺; ⊤⁺; ⊥⁺<⊤⁺; ⊥⁺<[_]<⊤⁺; ⊥⁺<[_]; [_]<⊤⁺)-------------------------------------------------------------------------- Re-export some core definitions publicallyopen Indexed using (K&_;_,_; toPair; fromPair; Value; MkValue; const) public-------------------------------------------------------------------------- Types and functions with hidden indicesdata Tree {v} (V : Value v) : Set (a ⊔ v ⊔ ℓ₂) wheretree : ∀ {h} → Indexed.Tree V ⊥⁺ ⊤⁺ h → Tree Vmodule _ {v} {V : Value v} whereprivateVal = Value.family Vempty : Tree Vempty = tree $′ Indexed.empty ⊥⁺<⊤⁺singleton : (k : Key) → Val k → Tree Vsingleton k v = tree (Indexed.singleton k v ⊥⁺<[ k ]<⊤⁺)insert : (k : Key) → Val k → Tree V → Tree Vinsert k v (tree t) = tree $′ proj₂ $ Indexed.insert k v t ⊥⁺<[ k ]<⊤⁺insertWith : (k : Key) → (Maybe (Val k) → Val k) →Tree V → Tree VinsertWith k f (tree t) = tree $′ proj₂ $ Indexed.insertWith k f t ⊥⁺<[ k ]<⊤⁺delete : Key → Tree V → Tree Vdelete k (tree t) = tree $′ proj₂ $ Indexed.delete k t ⊥⁺<[ k ]<⊤⁺lookup : Tree V → (k : Key) → Maybe (Val k)lookup (tree t) k = Indexed.lookup t k ⊥⁺<[ k ]<⊤⁺module _ {v w} {V : Value v} {W : Value w} whereprivateVal = Value.family VWal = Value.family Wmap : ∀[ Val ⇒ Wal ] → Tree V → Tree Wmap f (tree t) = tree $ Indexed.map f tmodule _ {v} {V : Value v} whereprivateVal = Value.family Vmember : Key → Tree V → Boolmember k t = is-just (lookup t k)headTail : Tree V → Maybe (K& V × Tree V)headTail (tree (Indexed.leaf _)) = nothingheadTail (tree {h = suc _} t) with (k , _ , _ , t′) ← Indexed.headTail t= just (k , tree (Indexed.castˡ ⊥⁺<[ _ ] t′))initLast : Tree V → Maybe (Tree V × K& V)initLast (tree (Indexed.leaf _)) = nothinginitLast (tree {h = suc _} t) with (k , _ , _ , t′) ← Indexed.initLast t= just (tree (Indexed.castʳ t′ [ _ ]<⊤⁺) , k)foldr : (∀ {k} → Val k → A → A) → A → Tree V → Afoldr cons nil (tree t) = Indexed.foldr cons nil t-- The input does not need to be ordered.fromList : List (K& V) → Tree VfromList = List.foldr (uncurry insert ∘′ toPair) empty-- Returns an ordered list.toList : Tree V → List (K& V)toList (tree t) = DiffList.toList (Indexed.toDiffList t)size : Tree V → ℕsize (tree t) = Indexed.size t-------------------------------------------------------------------------- Naive implementation of unionmodule _ {v w} {V : Value v} {W : Value w} whereprivateVal = Value.family VWal = Value.family WunionWith : (∀ {k} → Val k → Maybe (Wal k) → Wal k) →-- left → right → result.Tree V → Tree W → Tree WunionWith f t₁ t₂ = foldr (λ {k} v → insertWith k (f v)) t₂ t₁module _ {v} {V : Value v} whereprivate Val = Value.family V-- Left-biased.union : Tree V → Tree V → Tree Vunion = unionWith F.constunionsWith : (∀ {k} → Val k → Maybe (Val k) → Val k) → List (Tree V) → Tree VunionsWith f ts = List.foldr (unionWith f) empty ts-- Left-biased.unions : List (Tree V) → Tree Vunions = unionsWith F.const-------------------------------------------------------------------------- Naive implementation of intersectionmodule _ {v w x} {V : Value v} {W : Value w} {X : Value x} whereprivateVal = Value.family VWal = Value.family WXal = Value.family XintersectionWith : (∀ {k} → Val k → Wal k → Xal k) →Tree V → Tree W → Tree XintersectionWith f t₁ t₂ = foldr cons empty t₁ wherecons : ∀ {k} → Val k → Tree X → Tree Xcons {k} v = case lookup t₂ k of λ wherenothing → id(just w) → insert k (f v w)module _ {v} {V : Value v} whereprivateVal = Value.family V-- Left-biased.intersection : Tree V → Tree V → Tree Vintersection = intersectionWith F.constintersectionsWith : (∀ {k} → Val k → Val k → Val k) →List (Tree V) → Tree VintersectionsWith f [] = emptyintersectionsWith f (t ∷ ts) = List.foldl (intersectionWith f) t ts-- We are using foldl so that we are indeed forming t₁ ∩ ⋯ ∩ tₙ for-- the input list [t₁,⋯,tₙ]. If we were to use foldr, we would form-- t₂ ∩ ⋯ ∩ tₙ ∩ t₁ instead!-- Left-biased.intersections : List (Tree V) → Tree Vintersections = intersectionsWith F.const-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infixl 4 _∈?__∈?_ : ∀ {v} {V : Value v} → Key → Tree V → Bool_∈?_ = member{-# WARNING_ON_USAGE _∈?_"Warning: _∈?_ was deprecated in v2.0.Please use member instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Values for AVL trees-- Values must respect the underlying equivalence on keys------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (_Respects_)module Data.Tree.AVL.Value {a ℓ} (S : Setoid a ℓ) whereopen import Data.Product.Base using (Σ; _,_)open import Level using (suc; _⊔_)import Function.Base as Fopen Setoid S renaming (Carrier to Key)-------------------------------------------------------------------------- A Valuerecord Value v : Set (a ⊔ ℓ ⊔ suc v) whereconstructor MkValuefieldfamily : Key → Set vrespects : family Respects _≈_-------------------------------------------------------------------------- A Key together with its valuerecord K&_ {v} (V : Value v) : Set (a ⊔ v) whereconstructor _,_fieldkey : Keyvalue : Value.family V keyinfixr 4 _,_open K&_ publicmodule _ {v} {V : Value v} wheretoPair : K& V → Σ Key (Value.family V)toPair (k , v) = k , vfromPair : Σ Key (Value.family V) → K& VfromPair (k , v) = k , v-------------------------------------------------------------------------- The constant family of values-- The function `const` is defined using copatterns to prevent eager-- unfolding of the function in goal types.const : ∀ {v} → Set v → Value vValue.family (const V) = F.const VValue.respects (const V) = F.const F.id
-------------------------------------------------------------------------- The Agda standard library---- Finite sets, based on AVL trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Sets{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (Bool)open import Data.List.Base as List using (List)open import Data.Maybe.Base as Maybeopen import Data.Nat.Base using (ℕ)open import Data.Product.Base as Product using (_×_; _,_; proj₁)open import Data.Unit.Baseopen import Function.Baseopen import Level using (Level; _⊔_)privatevariableb : LevelB : Set bimport Data.Tree.AVL.Map strictTotalOrder as AVLopen StrictTotalOrder strictTotalOrder renaming (Carrier to A)-------------------------------------------------------------------------- The set type (note that Set is a reserved word)⟨Set⟩ : Set (a ⊔ ℓ₂)⟨Set⟩ = AVL.Map ⊤-------------------------------------------------------------------------- Repackaged functionsempty : ⟨Set⟩empty = AVL.emptysingleton : A → ⟨Set⟩singleton k = AVL.singleton k _insert : A → ⟨Set⟩ → ⟨Set⟩insert k = AVL.insert k _delete : A → ⟨Set⟩ → ⟨Set⟩delete = AVL.deletemember : A → ⟨Set⟩ → Boolmember = AVL.memberheadTail : ⟨Set⟩ → Maybe (A × ⟨Set⟩)headTail s = Maybe.map (Product.map₁ proj₁) (AVL.headTail s)initLast : ⟨Set⟩ → Maybe (⟨Set⟩ × A)initLast s = Maybe.map (Product.map₂ proj₁) (AVL.initLast s)fromList : List A → ⟨Set⟩fromList = AVL.fromList ∘ List.map (_, _)toList : ⟨Set⟩ → List AtoList = List.map proj₁ ∘ AVL.toListfoldr : (A → B → B) → B → ⟨Set⟩ → Bfoldr cons nil = AVL.foldr (const ∘′ cons) nilsize : ⟨Set⟩ → ℕsize = AVL.size-------------------------------------------------------------------------- Naïve implementations of union and intersectionunion : ⟨Set⟩ → ⟨Set⟩ → ⟨Set⟩union = AVL.unionunions : List ⟨Set⟩ → ⟨Set⟩unions = AVL.unionsintersection : ⟨Set⟩ → ⟨Set⟩ → ⟨Set⟩intersection = AVL.intersectionintersections : List ⟨Set⟩ → ⟨Set⟩intersections = AVL.intersections-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infixl 4 _∈?__∈?_ : A → ⟨Set⟩ → Bool_∈?_ = member{-# WARNING_ON_USAGE _∈?_"Warning: _∈?_ was deprecated in v2.0.Please use member instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Membership relation for AVL sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Sets.Membership{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (true; false)open import Data.Product.Base as Product using (_,_; proj₁; proj₂)open import Data.Sum.Base as Sum using (_⊎_)open import Data.Unit.Base using (tt)open import Function.Base using (_∘_; _∘′_; const)open import Relation.Nullary using (¬_; yes; no; Reflects)open import Relation.Nullary.Reflects using (fromEquivalence)open StrictTotalOrder strictTotalOrder renaming (Carrier to A)open import Data.Tree.AVL.Sets strictTotalOrderopen import Data.Tree.AVL.Map.Relation.Unary.Any strictTotalOrder as Mapₚ-------------------------------------------------------------------------- ∈infix 4 _∈_ _∉__∈_ : A → ⟨Set⟩ → Set _x ∈ s = Any ((x ≈_) ∘ proj₁) s_∉_ : A → ⟨Set⟩ → Set _x ∉ s = ¬ x ∈ s
-------------------------------------------------------------------------- The Agda standard library---- Properties of membership for AVL sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Sets.Membership.Properties{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (true; false)open import Data.Product.Base as Product using (_,_; proj₁; proj₂)open import Data.Sum.Base as Sum using (_⊎_)open import Data.Unit.Base using (tt)open import Function.Base using (_∘_; _∘′_; const)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Nullary using (¬_; yes; no; Reflects)open import Relation.Nullary.Reflects using (fromEquivalence)open StrictTotalOrder strictTotalOrder renaming (Carrier to A)open import Data.Tree.AVL.Sets strictTotalOrderopen import Data.Tree.AVL.Sets.Membership strictTotalOrderopen import Data.Tree.AVL.Map.Membership.Propositional strictTotalOrder using (_∈ₖᵥ_)import Data.Tree.AVL.Map.Membership.Propositional.Properties strictTotalOrder as Mapopen import Data.Tree.AVL.Map.Relation.Unary.Any strictTotalOrder as Mapₚprivatevariablex y : As : ⟨Set⟩∈toMap : x ∈ s → (x , tt) ∈ₖᵥ s∈toMap = Mapₚ.map (_, refl)∈fromMap : (x , tt) ∈ₖᵥ s → x ∈ s∈fromMap = Mapₚ.map proj₁-------------------------------------------------------------------------- empty∈-empty : x ∉ empty∈-empty = Map.∈ₖᵥ-empty ∘ ∈toMap-------------------------------------------------------------------------- singleton∈-singleton⁺ : x ∈ singleton x∈-singleton⁺ = ∈fromMap Map.∈ₖᵥ-singleton⁺∈-singleton⁻ : x ∈ singleton y → x ≈ y∈-singleton⁻ p = proj₁ (Map.∈ₖᵥ-singleton⁻ (∈toMap p))-------------------------------------------------------------------------- insert∈-insert⁺ : x ∈ s → x ∈ insert y s∈-insert⁺ {x = x} {s = s} {y = y} x∈s with x ≟ y... | yes x≈y = ∈fromMap (Map.∈ₖᵥ-Respectsˡ (Eq.sym x≈y , refl) Map.∈ₖᵥ-insert⁺⁺)... | no x≉y = ∈fromMap (Map.∈ₖᵥ-insert⁺ x≉y (∈toMap x∈s))∈-insert⁺⁺ : x ∈ insert x s∈-insert⁺⁺ = ∈fromMap Map.∈ₖᵥ-insert⁺⁺∈-insert⁻ : x ∈ insert y s → x ≈ y ⊎ x ∈ s∈-insert⁻ = Sum.map proj₁ (∈fromMap ∘ proj₂) ∘ Map.∈ₖᵥ-insert⁻ ∘ ∈toMap-------------------------------------------------------------------------- member∈-member : x ∈ s → member x s ≡ true∈-member = Map.∈ₖᵥ-member ∘′ ∈toMap∉-member : x ∉ s → member x s ≡ false∉-member x∉s = Map.∉ₖᵥ-member (const (x∉s ∘ ∈fromMap))member-∈ : member x s ≡ true → x ∈ smember-∈ = ∈fromMap ∘′ proj₂ ∘′ Map.member-∈ₖᵥmember-∉ : member x s ≡ false → x ∉ smember-∉ p = Map.member-∉ₖᵥ p tt ∘ ∈toMapmember-Reflects-∈ : Reflects (x ∈ s) (member x s)member-Reflects-∈ {x = x} {s = s} with member x s in eq... | true = Reflects.ofʸ (member-∈ eq)... | false = Reflects.ofⁿ (member-∉ eq)
-------------------------------------------------------------------------- The Agda standard library---- AVL trees where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Relation.Unary.Any{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Product.Base as Product using (∃)open import Function.Base using (_∘_; _$_)open import Level using (Level; _⊔_)open import Relation.Nullary.Decidable using (map′)open import Relation.Unaryopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)open import Data.Tree.AVL.Indexed strictTotalOrder as Indexed using (K&_; _,_)open import Data.Tree.AVL strictTotalOrder using (Tree; tree; Value)import Data.Tree.AVL.Indexed.Relation.Unary.Any strictTotalOrder as AVLₚprivatevariablev p q : LevelV : Value vt : Tree VP : Pred (K& V) pQ : Pred (K& V) q-------------------------------------------------------------------------- Definition-- Given a predicate P, Any P t describes a path in t to an element that-- satisfies P. There may be others.-- See `Relation.Unary` for an explanation of predicates.data Any {V : Value v} (P : Pred (K& V) p) :Tree V → Set (p ⊔ a ⊔ v ⊔ ℓ₂) wheretree : ∀ {h t} → AVLₚ.Any P t → Any P (tree {h = h} t)-------------------------------------------------------------------------- Operations on Anymap : P ⊆ Q → Any P t → Any Q tmap f (tree p) = tree (AVLₚ.map f p)lookup : Any {V = V} P t → K& Vlookup (tree p) = AVLₚ.lookup plookupKey : Any P t → KeylookupKey (tree p) = AVLₚ.lookupKey p-- If any element satisfies P, then P is satisfied.satisfied : Any P t → ∃ Psatisfied (tree p) = AVLₚ.satisfied p-------------------------------------------------------------------------- Properties of predicates preserved by Anyany? : Decidable P → Decidable (Any {V = V} P)any? P? (tree p) = map′ tree (λ where (tree p) → p) (AVLₚ.any? P? p)satisfiable : (k : Key) → Satisfiable (P ∘ (k ,_)) → Satisfiable (Any {V = V} P)satisfiable k sat = Product.map tree tree$ AVLₚ.satisfiable Indexed.⊥⁺<[ k ] Indexed.[ k ]<⊤⁺ sat
-------------------------------------------------------------------------- The Agda standard library---- Non-empty AVL trees-------------------------------------------------------------------------- AVL trees are balanced binary search trees.-- The search tree invariant is specified using the technique-- described by Conor McBride in his talk "Pivotal pragmatism".{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.NonEmpty{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂) whereopen import Data.Bool.Base using (Bool)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_; _++⁺_)open import Data.Maybe.Base hiding (map)open import Data.Nat.Base hiding (_<_; _⊔_; compare)open import Data.Product.Base hiding (map)open import Function.Base using (_$_; _∘′_)open import Level using (_⊔_)open import Relation.Unary using (IUniversal; _⇒_)open StrictTotalOrder strictTotalOrder renaming (Carrier to Key)open import Data.Tree.AVL.Value Eq.setoidimport Data.Tree.AVL.Indexed strictTotalOrder as Indexedopen Indexed using (⊥⁺; ⊤⁺; ⊥⁺<⊤⁺; ⊥⁺<[_]<⊤⁺; ⊥⁺<[_]; [_]<⊤⁺; node; toList)-------------------------------------------------------------------------- Types and functions with hidden indices-- NB: the height is non-zero thus guaranteeing that the AVL tree-- contains at least one value.data Tree⁺ {v} (V : Value v) : Set (a ⊔ v ⊔ ℓ₂) wheretree : ∀ {h} → Indexed.Tree V ⊥⁺ ⊤⁺ (suc h) → Tree⁺ Vmodule _ {v} {V : Value v} whereprivateVal = Value.family Vsingleton : (k : Key) → Val k → Tree⁺ Vsingleton k v = tree (Indexed.singleton k v ⊥⁺<[ k ]<⊤⁺)insert : (k : Key) → Val k → Tree⁺ V → Tree⁺ Vinsert k v (tree t) with Indexed.insert k v t ⊥⁺<[ k ]<⊤⁺... | Indexed.0# , t′ = tree t′... | Indexed.1# , t′ = tree t′insertWith : (k : Key) → (Maybe (Val k) → Val k) → Tree⁺ V → Tree⁺ VinsertWith k f (tree t) with Indexed.insertWith k f t ⊥⁺<[ k ]<⊤⁺... | Indexed.0# , t′ = tree t′... | Indexed.1# , t′ = tree t′delete : Key → Tree⁺ V → Maybe (Tree⁺ V)delete k (tree {h} t) with Indexed.delete k t ⊥⁺<[ k ]<⊤⁺delete k (tree {h} t) | Indexed.1# , t′ = just (tree t′)delete k (tree {0} t) | Indexed.0# , t′ = nothingdelete k (tree {suc h} t) | Indexed.0# , t′ = just (tree t′)lookup : Tree⁺ V → (k : Key) → Maybe (Val k)lookup (tree t) k = Indexed.lookup t k ⊥⁺<[ k ]<⊤⁺module _ {v w} {V : Value v} {W : Value w} whereprivateVal = Value.family VWal = Value.family Wmap : ∀[ Val ⇒ Wal ] → Tree⁺ V → Tree⁺ Wmap f (tree t) = tree $ Indexed.map f tmodule _ {v} {V : Value v} where-- The input does not need to be ordered.fromList⁺ : List⁺ (K& V) → Tree⁺ VfromList⁺ = List⁺.foldr (uncurry insert ∘′ toPair) (uncurry singleton ∘′ toPair)-- The output is orderedtoList⁺ : Tree⁺ V → List⁺ (K& V)toList⁺ (tree (node k&v l r bal)) = toList l ++⁺ k&v ∷ toList r
-------------------------------------------------------------------------- The Agda standard library---- Non-empty AVL trees, where equality for keys is propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.Bundles using (StrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; subst)module Data.Tree.AVL.NonEmpty.Propositional{k r} {Key : Set k} {_<_ : Rel Key r}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) whereopen import LevelprivatestrictTotalOrder : StrictTotalOrder _ _ _strictTotalOrder = record { isStrictTotalOrder = isStrictTotalOrder}open import Data.Tree.AVL.Value (StrictTotalOrder.Eq.setoid strictTotalOrder)import Data.Tree.AVL.NonEmpty strictTotalOrder as AVL⁺Tree⁺ : ∀ {v} (V : Key → Set v) → Set (k ⊔ v ⊔ r)Tree⁺ V = AVL⁺.Tree⁺ λ where.Value.family → V.Value.respects refl t → topen AVL⁺ hiding (Tree⁺) public
-------------------------------------------------------------------------- The Agda standard library---- Maps from keys to values, based on AVL trees-- This modules provides a simpler map interface, without a dependency-- between the key and value types.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Map{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (Bool)open import Data.List.Base as List using (List)open import Data.Maybe.Base as Maybe using (Maybe)open import Data.Nat.Base using (ℕ)open import Data.Product.Base as Prod using (_×_)open import Function.Base using (_∘′_)open import Level using (Level; _⊔_)privatevariablel v w x : LevelA : Set lV : Set vW : Set wX : Set ximport Data.Tree.AVL strictTotalOrder as AVLopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)-------------------------------------------------------------------------- The map typeMap : (V : Set v) → Set (a ⊔ v ⊔ ℓ₂)Map V = AVL.Tree (AVL.const V)-------------------------------------------------------------------------- Repackaged functionsempty : Map Vempty = AVL.emptysingleton : Key → V → Map Vsingleton = AVL.singletoninsert : Key → V → Map V → Map Vinsert = AVL.insertinsertWith : Key → (Maybe V → V) → Map V → Map VinsertWith = AVL.insertWithdelete : Key → Map V → Map Vdelete = AVL.deletelookup : Map V → Key → Maybe Vlookup = AVL.lookupmap : (V → W) → Map V → Map Wmap f = AVL.map fmember : Key → Map V → Boolmember = AVL.memberheadTail : Map V → Maybe ((Key × V) × Map V)headTail = Maybe.map (Prod.map₁ AVL.toPair) ∘′ AVL.headTailinitLast : Map V → Maybe (Map V × (Key × V))initLast = Maybe.map (Prod.map₂ AVL.toPair) ∘′ AVL.initLastfoldr : (Key → V → A → A) → A → Map V → Afoldr cons = AVL.foldr (λ {k} → cons k)fromList : List (Key × V) → Map VfromList = AVL.fromList ∘′ List.map AVL.fromPairtoList : Map V → List (Key × V)toList = List.map AVL.toPair ∘′ AVL.toListsize : Map V → ℕsize = AVL.size-------------------------------------------------------------------------- Naïve implementations of unionunionWith : (V → Maybe W → W) →Map V → Map W → Map WunionWith f = AVL.unionWith funion : Map V → Map V → Map Vunion = AVL.unionunionsWith : (V → Maybe V → V) → List (Map V) → Map VunionsWith f = AVL.unionsWith funions : List (Map V) → Map Vunions = AVL.unions-------------------------------------------------------------------------- Naïve implementations of intersectionintersectionWith : (V → W → X) → Map V → Map W → Map XintersectionWith f = AVL.intersectionWith fintersection : Map V → Map V → Map Vintersection = AVL.intersectionintersectionsWith : (V → V → V) → List (Map V) → Map VintersectionsWith f = AVL.intersectionsWith fintersections : List (Map V) → Map Vintersections = AVL.intersections-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infixl 4 _∈?__∈?_ : Key → Map V → Bool_∈?_ = member{-# WARNING_ON_USAGE _∈?_"Warning: _∈?_ was deprecated in v2.0.Please use member instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- AVL trees where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Map.Relation.Unary.Any{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Product.Base as Product using (_×_; ∃; _,_)open import Function.Base using (_∘_; _∘′_; id)open import Level using (Level; _⊔_)open import Relation.Unaryopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)open import Data.Tree.AVL.Map strictTotalOrder using (Map)open import Data.Tree.AVL.Indexed strictTotalOrder using (toPair)import Data.Tree.AVL.Relation.Unary.Any strictTotalOrder as Mapprivatevariablev p q : LevelV : Set vP : Pred V pQ : Pred V qm : Map V-------------------------------------------------------------------------- Definition-- Given a predicate P, Any P t describes a path in t to an element that-- satisfies P. There may be others.-- See `Relation.Unary` for an explanation of predicates.Any : {V : Set v} → Pred (Key × V) p → Pred (Map V) (a ⊔ ℓ₂ ⊔ v ⊔ p)Any P = Map.Any (P ∘′ toPair)-------------------------------------------------------------------------- Operations on Anymap : P ⊆ Q → Any P ⊆ Any Qmap f = Map.map flookup : Any {V = V} P m → Key × Vlookup = toPair ∘′ Map.lookuplookupKey : Any P m → KeylookupKey = Map.lookupKey-- If any element satisfies P, then P is satisfied.satisfied : Any P m → ∃ Psatisfied = Product.map toPair id ∘′ Map.satisfied-------------------------------------------------------------------------- Properties of predicates preserved by Anyany? : Decidable P → Decidable (Any P)any? P? = Map.any? (P? ∘ toPair)satisfiable : Satisfiable P → Satisfiable (Any P)satisfiable ((k , v) , p) = Map.satisfiable k (v , p)
-------------------------------------------------------------------------- The Agda standard library---- Membership relation for AVL Maps identifying values up to-- propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Map.Membership.Propositional{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (true; false)open import Data.Maybe.Base using (just; nothing; is-just)open import Data.Product.Base using (_×_; ∃-syntax; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependent renaming (Pointwise to _×ᴿ_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (_∘_; _∘′_)open import Level using (Level)open import Relation.Binary.Definitions using (Transitive; Symmetric; _Respectsˡ_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Intersection using (_∩_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong) renaming (refl to ≡-refl; sym to ≡-sym; trans to ≡-trans)open import Relation.Nullary using (Reflects; ¬_; yes; no)open import Relation.Nullary.Negation using (contradiction)open StrictTotalOrder strictTotalOrder renaming (Carrier to Key) hiding (trans)open Eq using (_≉_; refl; sym; trans)open import Data.Tree.AVL strictTotalOrder using (tree)open import Data.Tree.AVL.Indexed strictTotalOrder using (key)import Data.Tree.AVL.Indexed.Relation.Unary.Any strictTotalOrder as IAnyimport Data.Tree.AVL.Indexed.Relation.Unary.Any.Properties strictTotalOrder as IAnyₚopen import Data.Tree.AVL.Key strictTotalOrder using (⊥⁺<[_]<⊤⁺)open import Data.Tree.AVL.Map strictTotalOrderopen import Data.Tree.AVL.Map.Relation.Unary.Any strictTotalOrder as Mapₚ using (Any)open import Data.Tree.AVL.Relation.Unary.Any strictTotalOrder as Any using (tree)privatevariablev p q : LevelV : Set vm : Map Vk k′ : Keyx x′ y y′ : Vkx : Key × Vinfix 4 _≈ₖᵥ__≈ₖᵥ_ : Rel (Key × V) __≈ₖᵥ_ = _≈_ ×ᴿ _≡_-------------------------------------------------------------------------- Membership: ∈ₖᵥinfix 4 _∈ₖᵥ_ _∉ₖᵥ__∈ₖᵥ_ : Key × V → Map V → Set _kx ∈ₖᵥ m = Any (_≈ₖᵥ_ kx) m_∉ₖᵥ_ : Key × V → Map V → Set _kx ∉ₖᵥ m = ¬ kx ∈ₖᵥ m
-------------------------------------------------------------------------- The Agda standard library---- Properties of the membership relation for AVL Maps identifying values-- up to propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Map.Membership.Propositional.Properties{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Bool.Base using (true; false)open import Data.Maybe.Base using (just; nothing; is-just)open import Data.Product.Base as Product using (_×_; ∃-syntax; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependent renaming (Pointwise to _×ᴿ_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (_∘_; _∘′_)open import Level using (Level)open import Relation.Binary.Definitions using (Transitive; Symmetric; _Respectsˡ_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Intersection using (_∩_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong) renaming (refl to ≡-refl; sym to ≡-sym; trans to ≡-trans)open import Relation.Nullary using (Reflects; ¬_; yes; no)open import Relation.Nullary.Negation using (contradiction)open StrictTotalOrder strictTotalOrder renaming (Carrier to Key) hiding (trans)open Eq using (_≉_; refl; sym; trans)open import Data.Tree.AVL strictTotalOrder using (tree)open import Data.Tree.AVL.Indexed strictTotalOrder using (key)import Data.Tree.AVL.Indexed.Relation.Unary.Any strictTotalOrder as IAnyimport Data.Tree.AVL.Indexed.Relation.Unary.Any.Properties strictTotalOrder as IAnyₚopen import Data.Tree.AVL.Key strictTotalOrder using (⊥⁺<[_]<⊤⁺)open import Data.Tree.AVL.Map strictTotalOrderopen import Data.Tree.AVL.Map.Relation.Unary.Any strictTotalOrder as Map using (Any)open import Data.Tree.AVL.Map.Membership.Propositional strictTotalOrderopen import Data.Tree.AVL.Relation.Unary.Any strictTotalOrder as Any using (tree)privatevariablev p q : LevelV : Set vm : Map Vk k′ : Keyx x′ y y′ : Vkx : Key × V≈ₖᵥ-trans : Transitive (_≈ₖᵥ_ {V = V})≈ₖᵥ-trans {i = i} {k = k} = ×-transitive Eq.trans ≡-trans {i = i} {k = k}≈ₖᵥ-sym : Symmetric (_≈ₖᵥ_ {V = V})≈ₖᵥ-sym {x = x} {y = y} = ×-symmetric sym ≡-sym {x} {y}∈ₖᵥ-Respectsˡ : _∈ₖᵥ_ {V = V} Respectsˡ _≈ₖᵥ_∈ₖᵥ-Respectsˡ x~y = Any.map (≈ₖᵥ-trans (≈ₖᵥ-sym x~y))∈ₖᵥ-empty : kx ∉ₖᵥ empty∈ₖᵥ-empty (tree ())-------------------------------------------------------------------------- singleton∈ₖᵥ-singleton⁺ : (k , x) ∈ₖᵥ singleton k x∈ₖᵥ-singleton⁺ = tree (IAnyₚ.singleton⁺ _ _ _ (refl , ≡-refl))∈ₖᵥ-singleton⁻ : (k , x) ∈ₖᵥ singleton k′ x′ → k ≈ k′ × x ≡ x′∈ₖᵥ-singleton⁻ (tree p) = IAnyₚ.singleton⁻ _ _ _ pprivate≈-lookup : (p : (k , x) ∈ₖᵥ m) → k ≈ Any.lookupKey p≈-lookup (tree p) = proj₁ (IAnyₚ.lookup-result p)-------------------------------------------------------------------------- insert∈ₖᵥ-insert⁺ : k ≉ k′ → (k , x) ∈ₖᵥ m → (k , x) ∈ₖᵥ insert k′ x′ m∈ₖᵥ-insert⁺ {k′ = k′} {m = m@(tree t)} k≉k′ (tree p) =tree (IAnyₚ.insert⁺ _ _ _ (⊥⁺<[ _ ]<⊤⁺) p k′≉key-p)wherek′≉key-p : k′ ≉ Any.lookupKey (tree p)k′≉key-p k′≈key-p = k≉k′ (Eq.trans (≈-lookup (tree p)) (Eq.sym k′≈key-p))∈ₖᵥ-insert⁺⁺ : (k , x) ∈ₖᵥ insert k x m∈ₖᵥ-insert⁺⁺ {k = k} {m = tree t} with IAny.any? ((k ≟_) ∘ key) t... | yes k∈ = tree (IAnyₚ.Any-insert-just _ _ _ _ (λ k′ → _, ≡-refl) k∈)... | no ¬k∈ = tree (IAnyₚ.Any-insert-nothing _ _ _ _ (refl , ≡-refl) ¬k∈)private≈ₖᵥ-Resp : k ≈ k′ → kx ≈ₖᵥ (k′ , x) → kx ≈ₖᵥ (k , x)≈ₖᵥ-Resp = (λ{ k′≈l (k≈l , x≡) → (trans k≈l (sym k′≈l) , x≡)})∈ₖᵥ-insert⁻ : (k , x) ∈ₖᵥ insert k′ x′ m → (k ≈ k′ × x ≡ x′) ⊎ (k ≉ k′ × (k , x) ∈ₖᵥ m)∈ₖᵥ-insert⁻ {m = tree t} (tree kx∈insert)with IAnyₚ.insert⁻ ≈ₖᵥ-Resp _ _ t (⊥⁺<[ _ ]<⊤⁺) kx∈insert... | inj₁ p = inj₁ p... | inj₂ p = let k′≉p , k≈p , _ = IAnyₚ.lookup-result pk≉k′ = λ k≈k′ → k′≉p (trans (sym k≈k′) k≈p)in inj₂ (k≉k′ , tree (IAny.map proj₂ p))-------------------------------------------------------------------------- lookup∈ₖᵥ-lookup⁺ : (k , x) ∈ₖᵥ m → lookup m k ≡ just x∈ₖᵥ-lookup⁺ {k = k} {m = tree t} (tree kx∈m)with IAnyₚ.lookup⁺ t k (⊥⁺<[ _ ]<⊤⁺) kx∈m | IAnyₚ.lookup-result kx∈m... | inj₁ p≉k | k≈p , x≡p = contradiction (sym k≈p) p≉k... | inj₂ (p≈k , eq) | k≈p , x≡p = ≡-trans eq (cong just (≡-sym x≡p))∈ₖᵥ-lookup⁻ : lookup m k ≡ just x → (k , x) ∈ₖᵥ m∈ₖᵥ-lookup⁻ {m = tree t} {k = k} {x = x} eq= tree (IAny.map (Product.map sym ≡-sym) (IAnyₚ.lookup⁻ t k x (⊥⁺<[ _ ]<⊤⁺) eq))∈ₖᵥ-lookup-nothing⁺ : (∀ x → (k , x) ∉ₖᵥ m) → lookup m k ≡ nothing∈ₖᵥ-lookup-nothing⁺ {k = k} {m = m@(tree t)} k∉m with lookup m k in eq... | nothing = ≡-refl... | just x = contradiction (∈ₖᵥ-lookup⁻ eq) (k∉m x)∈ₖᵥ-lookup-nothing⁻ : lookup m k ≡ nothing → (k , x) ∉ₖᵥ m∈ₖᵥ-lookup-nothing⁻ eq kx∈m with ≡-trans (≡-sym eq) (∈ₖᵥ-lookup⁺ kx∈m)... | ()-------------------------------------------------------------------------- member∈ₖᵥ-member : (k , x) ∈ₖᵥ m → member k m ≡ true∈ₖᵥ-member = cong is-just ∘ ∈ₖᵥ-lookup⁺∉ₖᵥ-member : (∀ x → (k , x) ∉ₖᵥ m) → member k m ≡ false∉ₖᵥ-member = cong is-just ∘ ∈ₖᵥ-lookup-nothing⁺member-∈ₖᵥ : member k m ≡ true → ∃[ x ] (k , x) ∈ₖᵥ mmember-∈ₖᵥ {k = k} {m = m} ≡true with lookup m k in eq... | just x = x , ∈ₖᵥ-lookup⁻ eqmember-∉ₖᵥ : member k m ≡ false → ∀ x → (k , x) ∉ₖᵥ mmember-∉ₖᵥ {k = k} {m = m} ≡false x with lookup m k in eq... | nothing = ∈ₖᵥ-lookup-nothing⁻ eqmember-Reflects-∈ₖᵥ : Reflects (∃[ x ] (k , x) ∈ₖᵥ m) (member k m)member-Reflects-∈ₖᵥ {k = k} {m = m} with lookup m k in eq... | just x = Reflects.ofʸ (x , ∈ₖᵥ-lookup⁻ eq)... | nothing = Reflects.ofⁿ (∈ₖᵥ-lookup-nothing⁻ eq ∘ proj₂)
-------------------------------------------------------------------------- The Agda standard library---- Keys for AVL trees -- the original key type extended with a new-- minimum and maximum.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundlesusing (StrictTotalOrder; StrictPartialOrder)module Data.Tree.AVL.Key{a ℓ₁ ℓ₂} (sto : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Level using (Level; _⊔_)open import Data.Product.Base using (_×_; _,_)open import Relation.Binary.Definitions using (Reflexive)open import Relation.Binary.PropositionalEquality.Core using (_≡_ ; refl)open import Relation.Nullary.Negation.Core using (¬_)open import Relation.Nullary.Construct.Add.Extremaas AddExtremaToSet using (_±)import Relation.Binary.Construct.Add.Extrema.Equalityas AddExtremaToEqualityimport Relation.Binary.Construct.Add.Extrema.Strictas AddExtremaToOrderopen StrictTotalOrder sto renaming (Carrier to Key)using (_≈_; _<_; trans; irrefl; module Eq)-------------------------------------------------------------------------- Keys are augmented with new extrema (i.e. an artificial minimum and-- maximum)Key⁺ : Set aKey⁺ = Key ±open AddExtremaToSet publicusing ([_]; [_]-injective)renaming( ⊥± to ⊥⁺; ⊤± to ⊤⁺)-------------------------------------------------------------------------- The equality is extended in a corresponding manneropen AddExtremaToEquality _≈_ publicusing ()renaming( _≈±_ to _≈⁺_; [_] to [_]ᴱ)-------------------------------------------------------------------------- The order is extended in a corresponding manneropen AddExtremaToOrder _<_ publicusing () renaming(_<±_ to _<⁺_; [_] to [_]ᴿ; ⊥±<⊤± to ⊥⁺<⊤⁺; [_]<⊤± to [_]<⊤⁺; ⊥±<[_] to ⊥⁺<[_])-- A pair of ordering constraints.infix 4 _<_<__<_<_ : Key⁺ → Key → Key⁺ → Set (a ⊔ ℓ₂)l < x < u = l <⁺ [ x ] × [ x ] <⁺ u-- Properties⊥⁺<[_]<⊤⁺ : ∀ k → ⊥⁺ < k < ⊤⁺⊥⁺<[ k ]<⊤⁺ = ⊥⁺<[ k ] , [ k ]<⊤⁺refl⁺ : Reflexive _≈⁺_refl⁺ = AddExtremaToEquality.≈±-refl _≈_ Eq.reflsym⁺ : ∀ {l u} → l ≈⁺ u → u ≈⁺ lsym⁺ = AddExtremaToEquality.≈±-sym _≈_ Eq.symtrans⁺ : ∀ l {m u} → l <⁺ m → m <⁺ u → l <⁺ utrans⁺ l = AddExtremaToOrder.<±-trans _<_ transirrefl⁺ : ∀ k → ¬ (k <⁺ k)irrefl⁺ k = AddExtremaToOrder.<±-irrefl _<_ irrefl refl⁺-- BundlestrictPartialOrder : StrictPartialOrder _ _ _strictPartialOrder = record{ isStrictPartialOrder = AddExtremaToOrder.<±-isStrictPartialOrder STO._<_ STO.isStrictPartialOrder} where module STO = StrictTotalOrder stostrictTotalOrder : StrictTotalOrder _ _ _strictTotalOrder = record{ isStrictTotalOrder = AddExtremaToOrder.<±-isStrictTotalOrder STO._<_ STO.isStrictTotalOrder} where module STO = StrictTotalOrder sto
-------------------------------------------------------------------------- The Agda standard library---- Finite maps with indexed keys and values, based on AVL trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Baseusing (map₁; map₂; ∃; _×_; Σ-syntax; proj₁; _,_; -,_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong; subst)import Data.Tree.AVL.Valuemodule Data.Tree.AVL.IndexedMap{i k v ℓ}{Index : Set i} {Key : Index → Set k} (Value : Index → Set v){_<_ : Rel (∃ Key) ℓ}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_)whereimport Data.Tree.AVLopen import Data.Bool.Base using (Bool)open import Data.List.Base as List using (List)open import Data.Maybe.Base as Maybe using (Maybe)open import Data.Nat.Base using (ℕ)open import Function.Baseopen import Level using (Level; _⊔_)privatevariablea : LevelA : Set a-- Key/value pairs.KV : Set (i ⊔ k ⊔ v)KV = ∃ λ i → Key i × Value i-- Conversions.privatefromKV : KV → Σ[ ik ∈ ∃ Key ] Value (proj₁ ik)fromKV (i , k , v) = ((i , k) , v)toKV : Σ[ ik ∈ ∃ Key ] Value (proj₁ ik) → KVtoKV ((i , k) , v) = (i , k , v)-- The map type.privateopen module AVL =Data.Tree.AVL (record { isStrictTotalOrder = isStrictTotalOrder })using () renaming (Tree to Map′)Map = Map′ (AVL.MkValue (Value ∘ proj₁) (subst Value ∘′ cong proj₁))-- Repackaged functions.empty : Mapempty = AVL.emptysingleton : ∀ {i} → Key i → Value i → Mapsingleton k v = AVL.singleton (-, k) vinsert : ∀ {i} → Key i → Value i → Map → Mapinsert k v = AVL.insert (-, k) vdelete : ∀ {i} → Key i → Map → Mapdelete k = AVL.delete (-, k)lookup : ∀ {i} → Map → Key i → Maybe (Value i)lookup m k = AVL.lookup m (-, k)member : ∀ {i} → Key i → Map → Boolmember k = AVL.member (-, k)headTail : Map → Maybe (KV × Map)headTail m = Maybe.map (map₁ (toKV ∘′ AVL.toPair)) (AVL.headTail m)initLast : Map → Maybe (Map × KV)initLast m = Maybe.map (map₂ (toKV ∘′ AVL.toPair)) (AVL.initLast m)foldr : (∀ {k} → Value k → A → A) → A → Map → Afoldr cons = AVL.foldr consfromList : List KV → MapfromList = AVL.fromList ∘ List.map (AVL.fromPair ∘′ fromKV)toList : Map → List KVtoList = List.map (toKV ∘′ AVL.toPair) ∘ AVL.toListsize : Map → ℕsize = AVL.size-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infixl 4 _∈?__∈?_ : ∀ {i} → Key i → Map → Bool_∈?_ = member{-# WARNING_ON_USAGE _∈?_"Warning: _∈?_ was deprecated in v2.0.Please use member instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- AVL trees where the stored values may depend on their key------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Indexed{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂) whereopen import Level using (Level; _⊔_)open import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Product.Base using (Σ; ∃; _×_; _,_; proj₁)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.List.Base as List using (List)open import Data.DifferenceList using (DiffList; []; _∷_; _++_)open import Function.Base as F hiding (const)open import Relation.Unaryopen import Relation.Binary.Definitions using (_Respects_; Tri; tri<; tri≈; tri>)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablel v : LevelA : Set lopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)-------------------------------------------------------------------------- Re-export core definitions publiclyopen import Data.Tree.AVL.Key strictTotalOrder publicopen import Data.Tree.AVL.Value Eq.setoid publicopen import Data.Tree.AVL.Height public-------------------------------------------------------------------------- Definitions of the tree-- The trees have three parameters/indices: a lower bound on the-- keys, an upper bound, and a height.---- (The bal argument is the balance factor.)data Tree {v} (V : Value v) (l u : Key⁺) : ℕ → Set (a ⊔ v ⊔ ℓ₂) whereleaf : (l<u : l <⁺ u) → Tree V l u 0node : ∀ {hˡ hʳ h}(kv : K& V)(lk : Tree V l [ kv .key ] hˡ)(ku : Tree V [ kv .key ] u hʳ)(bal : hˡ ∼ hʳ ⊔ h) →Tree V l u (suc h)module _ {v} {V : Value v} whereordered : ∀ {l u n} → Tree V l u n → l <⁺ uordered (leaf l<u) = l<uordered (node kv lk ku bal) = trans⁺ _ (ordered lk) (ordered ku)privateVal = Value.family VV≈ = Value.respects Vleaf-injective : ∀ {l u} {p q : l <⁺ u} → (Tree V l u 0 ∋ leaf p) ≡ leaf q → p ≡ qleaf-injective refl = reflnode-injective-key :∀ {hˡ₁ hˡ₂ hʳ₁ hʳ₂ h l u k₁ k₂}{lk₁ : Tree V l [ k₁ .key ] hˡ₁} {lk₂ : Tree V l [ k₂ .key ] hˡ₂}{ku₁ : Tree V [ k₁ .key ] u hʳ₁} {ku₂ : Tree V [ k₂ .key ] u hʳ₂}{bal₁ : hˡ₁ ∼ hʳ₁ ⊔ h} {bal₂ : hˡ₂ ∼ hʳ₂ ⊔ h} →node k₁ lk₁ ku₁ bal₁ ≡ node k₂ lk₂ ku₂ bal₂ → k₁ ≡ k₂node-injective-key refl = refl-- See also node-injectiveˡ, node-injectiveʳ, and node-injective-bal-- in Data.Tree.AVL.Indexed.WithK.-- Cast operations. Logarithmic in the size of the tree, if we don't-- count the time needed to construct the new proofs in the leaf-- cases. (The same kind of caveat applies to other operations-- below.)---- Perhaps it would be worthwhile changing the data structure so-- that the casts could be implemented in constant time (excluding-- proof manipulation). However, note that this would not change the-- worst-case time complexity of the operations below (up to Θ).castˡ : ∀ {l m u h} → l <⁺ m → Tree V m u h → Tree V l u hcastˡ {l} l<m (leaf m<u) = leaf (trans⁺ l l<m m<u)castˡ l<m (node k mk ku bal) = node k (castˡ l<m mk) ku balcastʳ : ∀ {l m u h} → Tree V l m h → m <⁺ u → Tree V l u hcastʳ {l} (leaf l<m) m<u = leaf (trans⁺ l l<m m<u)castʳ (node k lk km bal) m<u = node k lk (castʳ km m<u) bal-- Various constant-time functions which construct trees out of-- smaller pieces, sometimes using rotation.pattern node⁺ k₁ t₁ k₂ t₂ t₃ bal = node k₁ t₁ (node k₂ t₂ t₃ bal) ∼+joinˡ⁺ : ∀ {l u hˡ hʳ h} →(k : K& V) →(∃ λ i → Tree V l [ k .key ] (i ⊕ hˡ)) →Tree V [ k .key ] u hʳ →(bal : hˡ ∼ hʳ ⊔ h) →∃ λ i → Tree V l u (i ⊕ (1 + h))joinˡ⁺ k₂ (0# , t₁) t₃ bal = (0# , node k₂ t₁ t₃ bal)joinˡ⁺ k₂ (1# , t₁) t₃ ∼0 = (1# , node k₂ t₁ t₃ ∼-)joinˡ⁺ k₂ (1# , t₁) t₃ ∼+ = (0# , node k₂ t₁ t₃ ∼0)joinˡ⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- = (0# , node k₂ t₁ (node k₄ t₃ t₅ ∼0) ∼0)joinˡ⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- = (1# , node k₂ t₁ (node k₄ t₃ t₅ ∼-) ∼+)joinˡ⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼-= (0# , node k₄ (node k₂ t₁ t₃ (max∼ bal))(node k₆ t₅ t₇ (∼max bal))∼0)pattern node⁻ k₁ k₂ t₁ t₂ bal t₃ = node k₁ (node k₂ t₁ t₂ bal) t₃ ∼-joinʳ⁺ : ∀ {l u hˡ hʳ h} →(k : K& V) →Tree V l [ k .key ] hˡ →(∃ λ i → Tree V [ k .key ] u (i ⊕ hʳ)) →(bal : hˡ ∼ hʳ ⊔ h) →∃ λ i → Tree V l u (i ⊕ (1 + h))joinʳ⁺ k₂ t₁ (0# , t₃) bal = (0# , node k₂ t₁ t₃ bal)joinʳ⁺ k₂ t₁ (1# , t₃) ∼0 = (1# , node k₂ t₁ t₃ ∼+)joinʳ⁺ k₂ t₁ (1# , t₃) ∼- = (0# , node k₂ t₁ t₃ ∼0)joinʳ⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ = (0# , node k₄ (node k₂ t₁ t₃ ∼0) t₅ ∼0)joinʳ⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ = (1# , node k₄ (node k₂ t₁ t₃ ∼+) t₅ ∼-)joinʳ⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+= (0# , node k₄ (node k₂ t₁ t₃ (max∼ bal))(node k₆ t₅ t₇ (∼max bal))∼0)joinˡ⁻ : ∀ {l u} hˡ {hʳ h} →(k : K& V) →(∃ λ i → Tree V l [ k .key ] pred[ i ⊕ hˡ ]) →Tree V [ k .key ] u hʳ →(bal : hˡ ∼ hʳ ⊔ h) →∃ λ i → Tree V l u (i ⊕ h)joinˡ⁻ zero k₂ (0# , t₁) t₃ bal = (1# , node k₂ t₁ t₃ bal)joinˡ⁻ zero k₂ (1# , t₁) t₃ bal = (1# , node k₂ t₁ t₃ bal)joinˡ⁻ (suc _) k₂ (0# , t₁) t₃ ∼+ = joinʳ⁺ k₂ t₁ (1# , t₃) ∼+joinˡ⁻ (suc _) k₂ (0# , t₁) t₃ ∼0 = (1# , node k₂ t₁ t₃ ∼+)joinˡ⁻ (suc _) k₂ (0# , t₁) t₃ ∼- = (0# , node k₂ t₁ t₃ ∼0)joinˡ⁻ (suc _) k₂ (1# , t₁) t₃ bal = (1# , node k₂ t₁ t₃ bal)joinʳ⁻ : ∀ {l u hˡ} hʳ {h} →(k : K& V) →Tree V l [ k .key ] hˡ →(∃ λ i → Tree V [ k .key ] u pred[ i ⊕ hʳ ]) →(bal : hˡ ∼ hʳ ⊔ h) →∃ λ i → Tree V l u (i ⊕ h)joinʳ⁻ zero k₂ t₁ (0# , t₃) bal = (1# , node k₂ t₁ t₃ bal)joinʳ⁻ zero k₂ t₁ (1# , t₃) bal = (1# , node k₂ t₁ t₃ bal)joinʳ⁻ (suc _) k₂ t₁ (0# , t₃) ∼- = joinˡ⁺ k₂ (1# , t₁) t₃ ∼-joinʳ⁻ (suc _) k₂ t₁ (0# , t₃) ∼0 = (1# , node k₂ t₁ t₃ ∼-)joinʳ⁻ (suc _) k₂ t₁ (0# , t₃) ∼+ = (0# , node k₂ t₁ t₃ ∼0)joinʳ⁻ (suc _) k₂ t₁ (1# , t₃) bal = (1# , node k₂ t₁ t₃ bal)-- Extracts the smallest element from the tree, plus the rest.-- Logarithmic in the size of the tree.headTail : ∀ {l u h} → Tree V l u (1 + h) →∃ λ (k : K& V) → l <⁺ [ k .key ] ×∃ λ i → Tree V [ k .key ] u (i ⊕ h)headTail (node k₁ (leaf l<k₁) t₂ ∼+) = (k₁ , l<k₁ , 0# , t₂)headTail (node k₁ (leaf l<k₁) t₂ ∼0) = (k₁ , l<k₁ , 0# , t₂)headTail (node {hˡ = suc _} k₃ t₁₂ t₄ bal) with headTail t₁₂... | (k₁ , l<k₁ , t₂) = (k₁ , l<k₁ , joinˡ⁻ _ k₃ t₂ t₄ bal)-- Extracts the largest element from the tree, plus the rest.-- Logarithmic in the size of the tree.initLast : ∀ {l u h} → Tree V l u (1 + h) →∃ λ (k : K& V) → [ k .key ] <⁺ u ×∃ λ i → Tree V l [ k .key ] (i ⊕ h)initLast (node k₂ t₁ (leaf k₂<u) ∼-) = (k₂ , k₂<u , (0# , t₁))initLast (node k₂ t₁ (leaf k₂<u) ∼0) = (k₂ , k₂<u , (0# , t₁))initLast (node {hʳ = suc _} k₂ t₁ t₃₄ bal) with initLast t₃₄... | (k₄ , k₄<u , t₃) = (k₄ , k₄<u , joinʳ⁻ _ k₂ t₁ t₃ bal)-- Another joining function. Logarithmic in the size of either of-- the input trees (which need to have almost equal heights).join : ∀ {l m u hˡ hʳ h} →Tree V l m hˡ → Tree V m u hʳ → (bal : hˡ ∼ hʳ ⊔ h) →∃ λ i → Tree V l u (i ⊕ h)join t₁ (leaf m<u) ∼0 = (0# , castʳ t₁ m<u)join t₁ (leaf m<u) ∼- = (0# , castʳ t₁ m<u)join {hʳ = suc _} t₁ t₂₃ bal with headTail t₂₃... | (k₂ , m<k₂ , t₃) = joinʳ⁻ _ k₂ (castʳ t₁ m<k₂) t₃ bal-- An empty tree.empty : ∀ {l u} → l <⁺ u → Tree V l u 0empty = leaf-- A singleton tree.singleton : ∀ {l u} (k : Key) → Val k → l < k < u → Tree V l u 1singleton k v (l<k , k<u) = node (k , v) (leaf l<k) (leaf k<u) ∼0-- Inserts a key into the tree, using a function to combine any-- existing value with the new value. Logarithmic in the size of the-- tree (assuming constant-time comparisons and a constant-time-- combining function).insertWith : ∀ {l u h} (k : Key) → (Maybe (Val k) → Val k) → -- Maybe old → result.Tree V l u h → l < k < u →∃ λ i → Tree V l u (i ⊕ h)insertWith k f (leaf l<u) l<k<u = (1# , singleton k (f nothing) l<k<u)insertWith k f (node (k′ , v′) lp pu bal) (l<k , k<u) with compare k k′... | tri< k<k′ _ _ = joinˡ⁺ (k′ , v′) (insertWith k f lp (l<k , [ k<k′ ]ᴿ)) pu bal... | tri> _ _ k′<k = joinʳ⁺ (k′ , v′) lp (insertWith k f pu ([ k′<k ]ᴿ , k<u)) bal... | tri≈ _ k≈k′ _ = (0# , node (k′ , V≈ k≈k′ (f (just (V≈ (Eq.sym k≈k′) v′)))) lp pu bal)-- Inserts a key into the tree. If the key already exists, then it-- is replaced. Logarithmic in the size of the tree (assuming-- constant-time comparisons).insert : ∀ {l u h} → (k : Key) → Val k → Tree V l u h → l < k < u →∃ λ i → Tree V l u (i ⊕ h)insert k v = insertWith k (F.const v)-- Deletes the key/value pair containing the given key, if any.-- Logarithmic in the size of the tree (assuming constant-time-- comparisons).delete : ∀ {l u h} (k : Key) → Tree V l u h → l < k < u →∃ λ i → Tree V l u pred[ i ⊕ h ]delete k (leaf l<u) l<k<u = (0# , leaf l<u)delete k (node p@(k′ , v) lp pu bal) (l<k , k<u) with compare k′ k... | tri< k′<k _ _ = joinʳ⁻ _ p lp (delete k pu ([ k′<k ]ᴿ , k<u)) bal... | tri> _ _ k′>k = joinˡ⁻ _ p (delete k lp (l<k , [ k′>k ]ᴿ)) pu bal... | tri≈ _ k′≡k _ = join lp pu bal-- Looks up a key. Logarithmic in the size of the tree (assuming-- constant-time comparisons).lookup : ∀ {l u h} → Tree V l u h → (k : Key) → l < k < u → Maybe (Val k)lookup (leaf _) k l<k<u = nothinglookup (node (k′ , v) lk′ k′u _) k (l<k , k<u) with compare k′ k... | tri< k′<k _ _ = lookup k′u k ([ k′<k ]ᴿ , k<u)... | tri> _ _ k′>k = lookup lk′ k (l<k , [ k′>k ]ᴿ)... | tri≈ _ k′≡k _ = just (V≈ k′≡k v)-- Converts the tree to an ordered list. Linear in the size of the-- tree.foldr : ∀ {l u h} → (∀ {k} → Val k → A → A) → A → Tree V l u h → Afoldr cons nil (leaf l<u) = nilfoldr cons nil (node (_ , v) l r bal) = foldr cons (cons v (foldr cons nil r)) ltoDiffList : ∀ {l u h} → Tree V l u h → DiffList (K& V)toDiffList (leaf _) = []toDiffList (node k l r _) = toDiffList l ++ k ∷ toDiffList rtoList : ∀ {l u h} → Tree V l u h → List (K& V)toList t = toDiffList t List.[]size : ∀ {l u h} → Tree V l u h → ℕsize = List.length ∘′ toListmodule _ {v w} {V : Value v} {W : Value w} whereprivateVal = Value.family VWal = Value.family W-- Maps a function over all values in the tree.map : ∀[ Val ⇒ Wal ] → ∀ {l u h} → Tree V l u h → Tree W l u hmap f (leaf l<u) = leaf l<umap f (node (k , v) l r bal) = node (k , f v) (map f l) (map f r) bal
-------------------------------------------------------------------------- The Agda standard library---- Some code related to indexed AVL trees that relies on the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.Bundles using (StrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; subst)module Data.Tree.AVL.Indexed.WithK{k r} (Key : Set k) {_<_ : Rel Key r}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) wherestrictTotalOrder : StrictTotalOrder _ _ _strictTotalOrder = record { isStrictTotalOrder = isStrictTotalOrder }open import Data.Tree.AVL.Indexed strictTotalOrder as AVL hiding (Value)module _ {v} {V′ : Key → Set v} whereprivateV : AVL.Value vV = AVL.MkValue V′ (subst V′)node-injectiveˡ : ∀ {hˡ hʳ h l u k}{lk₁ : Tree V l [ k .key ] hˡ} {lk₂ : Tree V l [ k .key ] hˡ}{ku₁ : Tree V [ k .key ] u hʳ} {ku₂ : Tree V [ k .key ] u hʳ}{bal₁ bal₂ : hˡ ∼ hʳ ⊔ h} →node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → lk₁ ≡ lk₂node-injectiveˡ refl = reflnode-injectiveʳ : ∀ {hˡ hʳ h l u k}{lk₁ : Tree V l [ k .key ] hˡ} {lk₂ : Tree V l [ k .key ] hˡ}{ku₁ : Tree V [ k .key ] u hʳ} {ku₂ : Tree V [ k .key ] u hʳ}{bal₁ bal₂ : hˡ ∼ hʳ ⊔ h} →node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → ku₁ ≡ ku₂node-injectiveʳ refl = reflnode-injective-bal : ∀ {hˡ hʳ h l u k}{lk₁ : Tree V l [ k .key ] hˡ} {lk₂ : Tree V l [ k .key ] hˡ}{ku₁ : Tree V [ k .key ] u hʳ} {ku₂ : Tree V [ k .key ] u hʳ}{bal₁ bal₂ : hˡ ∼ hʳ ⊔ h} →node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → bal₁ ≡ bal₂node-injective-bal refl = refl
-------------------------------------------------------------------------- The Agda standard library---- AVL trees where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Indexed.Relation.Unary.Any{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Nat.Base using (ℕ)open import Data.Product.Base using (_,_; ∃; -,_; proj₁; proj₂)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (_∘′_; _∘_)open import Level using (Level; _⊔_)open import Relation.Nullary.Decidable using (Dec; no; map′; _⊎-dec_)open import Relation.Unaryopen StrictTotalOrder strictTotalOrder renaming (Carrier to Key)open import Data.Tree.AVL.Indexed strictTotalOrderusing (Tree; Value; Key⁺; [_]; _<⁺_; K&_; _,_; key; _∼_⊔_; ∼0; leaf; node)privatevariablev p q : LevelV : Value vP : Pred (K& V) pQ : Pred (K& V) ql u : Key⁺n : ℕt : Tree V l u n-------------------------------------------------------------------------- Definition-- Given a predicate P, Any P t describes a path in t to an element that-- satisfies P. There may be others.-- See `Relation.Unary` for an explanation of predicates.data Any {V : Value v} (P : Pred (K& V) p) {l u}: ∀ {n} → Tree V l u n → Set (p ⊔ a ⊔ v ⊔ ℓ₂) wherehere : ∀ {hˡ hʳ h} {kv : K& V} → P kv →{lk : Tree V l [ kv .key ] hˡ}{ku : Tree V [ kv .key ] u hʳ}{bal : hˡ ∼ hʳ ⊔ h} →Any P (node kv lk ku bal)left : ∀ {hˡ hʳ h} {kv : K& V}{lk : Tree V l [ kv .key ] hˡ} →Any P lk →{ku : Tree V [ kv .key ] u hʳ}{bal : hˡ ∼ hʳ ⊔ h} →Any P (node kv lk ku bal)right : ∀ {hˡ hʳ h} {kv : K& V}{lk : Tree V l [ kv .key ] hˡ}{ku : Tree V [ kv .key ] u hʳ} →Any P ku →{bal : hˡ ∼ hʳ ⊔ h} →Any P (node kv lk ku bal)-------------------------------------------------------------------------- Operations on Anymap : P ⊆ Q → Any P t → Any Q tmap f (here p) = here (f p)map f (left p) = left (map f p)map f (right p) = right (map f p)lookup : Any {V = V} P t → K& Vlookup (here {kv = kv} _) = kvlookup (left p) = lookup plookup (right p) = lookup plookupKey : Any P t → KeylookupKey = key ∘′ lookup-- If any element satisfies P, then P is satisfied.satisfied : Any P t → ∃ Psatisfied (here p) = -, psatisfied (left p) = satisfied psatisfied (right p) = satisfied pmodule _ {hˡ hʳ h} {kv : K& V}{lk : Tree V l [ kv .key ] hˡ}{ku : Tree V [ kv .key ] u hʳ}{bal : hˡ ∼ hʳ ⊔ h}wheretoSum : Any P (node kv lk ku bal) → P kv ⊎ Any P lk ⊎ Any P kutoSum (here p) = inj₁ ptoSum (left p) = inj₂ (inj₁ p)toSum (right p) = inj₂ (inj₂ p)fromSum : P kv ⊎ Any P lk ⊎ Any P ku → Any P (node kv lk ku bal)fromSum (inj₁ p) = here pfromSum (inj₂ (inj₁ p)) = left pfromSum (inj₂ (inj₂ p)) = right p-------------------------------------------------------------------------- Properties of predicates preserved by Anyany? : Decidable P → (t : Tree V l u n) → Dec (Any P t)any? P? (leaf _) = no λ ()any? P? (node kv l r bal) = map′ fromSum toSum(P? kv ⊎-dec any? P? l ⊎-dec any? P? r)satisfiable : ∀ {k l u} → l <⁺ [ k ] → [ k ] <⁺ u →Satisfiable (P ∘ (k ,_)) →Satisfiable {A = Tree V l u 1} (Any P)satisfiable {k = k} lb ub sat = node (k , proj₁ sat) (leaf lb) (leaf ub) ∼0, here (proj₂ sat)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Any------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Indexed.Relation.Unary.Any.Properties{a ℓ₁ ℓ₂} (sto : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Maybe.Base as Maybe using (Maybe; nothing; just; maybe′)open import Data.Maybe.Properties using (just-injective)open import Data.Maybe.Relation.Unary.All as Maybe using (nothing; just)open import Data.Nat.Base using (ℕ)open import Data.Product.Base as Prod using (∃; ∃-syntax; _×_; _,_; proj₁; proj₂)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Function.Base as Fopen import Level using (Level)open import Relation.Binary.Definitions using (_Respects_; tri<; tri≈; tri>)open import Relation.Binary.PropositionalEquality.Core using (_≡_) renaming (refl to ≡-refl)open import Relation.Nullary using (¬_; Dec; yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Unary using (Pred; _∩_)open import Data.Tree.AVL.Indexed sto as AVLopen import Data.Tree.AVL.Indexed.Relation.Unary.Any sto as Anyopen StrictTotalOrder sto renaming (Carrier to Key; trans to <-trans); open Eq using (_≉_; sym; trans)open import Relation.Binary.Construct.Add.Extrema.Strict _<_ using ([<]-injective)import Relation.Binary.Reasoning.StrictPartialOrder as <-Reasoningprivatevariablev p q : Levelk : KeyV : Value vl u : Key⁺n : ℕP Q : Pred (K& V) p-------------------------------------------------------------------------- Any.lookuplookup-result : {t : Tree V l u n} (p : Any P t) → P (Any.lookup p)lookup-result (here p) = plookup-result (left p) = lookup-result plookup-result (right p) = lookup-result plookup-bounded : {t : Tree V l u n} (p : Any P t) → l < Any.lookup p .key < ulookup-bounded {t = node kv lk ku bal} (here p) = ordered lk , ordered kulookup-bounded {t = node kv lk ku bal} (left p) =Prod.map₂ (flip (trans⁺ _) (ordered ku)) (lookup-bounded p)lookup-bounded {t = node kv lk ku bal} (right p) =Prod.map₁ (trans⁺ _ (ordered lk)) (lookup-bounded p)lookup-rebuild : {t : Tree V l u n} (p : Any P t) → Q (Any.lookup p) → Any Q tlookup-rebuild (here _) q = here qlookup-rebuild (left p) q = left (lookup-rebuild p q)lookup-rebuild (right p) q = right (lookup-rebuild p q)lookup-rebuild-accum : {t : Tree V l u n} (p : Any P t) → Q (Any.lookup p) → Any (Q ∩ P) tlookup-rebuild-accum p q = lookup-rebuild p (q , lookup-result p)joinˡ⁺-here⁺ : ∀ {l u hˡ hʳ h} →(kv : K& V) →(l : ∃ λ i → Tree V l [ kv .key ] (i ⊕ hˡ)) →(r : Tree V [ kv .key ] u hʳ) →(bal : hˡ ∼ hʳ ⊔ h) →P kv → Any P (proj₂ (joinˡ⁺ kv l r bal))joinˡ⁺-here⁺ k₂ (0# , t₁) t₃ bal p = here pjoinˡ⁺-here⁺ k₂ (1# , t₁) t₃ ∼0 p = here pjoinˡ⁺-here⁺ k₂ (1# , t₁) t₃ ∼+ p = here pjoinˡ⁺-here⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- p = right (here p)joinˡ⁺-here⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- p = right (here p)joinˡ⁺-here⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- p = right (here p)joinˡ⁺-left⁺ : ∀ {l u hˡ hʳ h} →(k : K& V) →(l : ∃ λ i → Tree V l [ k .key ] (i ⊕ hˡ)) →(r : Tree V [ k .key ] u hʳ) →(bal : hˡ ∼ hʳ ⊔ h) →Any P (proj₂ l) → Any P (proj₂ (joinˡ⁺ k l r bal))joinˡ⁺-left⁺ k₂ (0# , t₁) t₃ bal p = left pjoinˡ⁺-left⁺ k₂ (1# , t₁) t₃ ∼0 p = left pjoinˡ⁺-left⁺ k₂ (1# , t₁) t₃ ∼+ p = left pjoinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- (here p) = here pjoinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- (left p) = left pjoinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- (right p) = right (left p)joinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- (here p) = here pjoinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- (left p) = left pjoinˡ⁺-left⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- (right p) = right (left p)joinˡ⁺-left⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- (here p) = left (here p)joinˡ⁺-left⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- (left p) = left (left p)joinˡ⁺-left⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- (right (here p)) = here pjoinˡ⁺-left⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- (right (left p)) = left (right p)joinˡ⁺-left⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- (right (right p)) = right (left p)joinˡ⁺-right⁺ : ∀ {l u hˡ hʳ h} →(kv@(k , v) : K& V) →(l : ∃ λ i → Tree V l [ k ] (i ⊕ hˡ)) →(r : Tree V [ k ] u hʳ) →(bal : hˡ ∼ hʳ ⊔ h) →Any P r → Any P (proj₂ (joinˡ⁺ kv l r bal))joinˡ⁺-right⁺ k₂ (0# , t₁) t₃ bal p = right pjoinˡ⁺-right⁺ k₂ (1# , t₁) t₃ ∼0 p = right pjoinˡ⁺-right⁺ k₂ (1# , t₁) t₃ ∼+ p = right pjoinˡ⁺-right⁺ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- p = right (right p)joinˡ⁺-right⁺ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- p = right (right p)joinˡ⁺-right⁺ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- p = right (right p)joinʳ⁺-here⁺ : ∀ {l u hˡ hʳ h} →(kv : K& V) →(l : Tree V l [ kv .key ] hˡ) →(r : ∃ λ i → Tree V [ kv .key ] u (i ⊕ hʳ)) →(bal : hˡ ∼ hʳ ⊔ h) →P kv → Any P (proj₂ (joinʳ⁺ kv l r bal))joinʳ⁺-here⁺ k₂ t₁ (0# , t₃) bal p = here pjoinʳ⁺-here⁺ k₂ t₁ (1# , t₃) ∼0 p = here pjoinʳ⁺-here⁺ k₂ t₁ (1# , t₃) ∼- p = here pjoinʳ⁺-here⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ p = left (here p)joinʳ⁺-here⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ p = left (here p)joinʳ⁺-here⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ p = left (here p)joinʳ⁺-left⁺ : ∀ {l u hˡ hʳ h} →(kv : K& V) →(l : Tree V l [ kv .key ] hˡ) →(r : ∃ λ i → Tree V [ kv .key ] u (i ⊕ hʳ)) →(bal : hˡ ∼ hʳ ⊔ h) →Any P l → Any P (proj₂ (joinʳ⁺ kv l r bal))joinʳ⁺-left⁺ k₂ t₁ (0# , t₃) bal p = left pjoinʳ⁺-left⁺ k₂ t₁ (1# , t₃) ∼0 p = left pjoinʳ⁺-left⁺ k₂ t₁ (1# , t₃) ∼- p = left pjoinʳ⁺-left⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ p = left (left p)joinʳ⁺-left⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ p = left (left p)joinʳ⁺-left⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ p = left (left p)joinʳ⁺-right⁺ : ∀ {l u hˡ hʳ h} →(kv : K& V) →(l : Tree V l [ kv .key ] hˡ) →(r : ∃ λ i → Tree V [ kv .key ] u (i ⊕ hʳ)) →(bal : hˡ ∼ hʳ ⊔ h) →Any P (proj₂ r) → Any P (proj₂ (joinʳ⁺ kv l r bal))joinʳ⁺-right⁺ k₂ t₁ (0# , t₃) bal p = right pjoinʳ⁺-right⁺ k₂ t₁ (1# , t₃) ∼0 p = right pjoinʳ⁺-right⁺ k₂ t₁ (1# , t₃) ∼- p = right pjoinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ (here p) = here pjoinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ (left p) = left (right p)joinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ (right p) = right pjoinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ (here p) = here pjoinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ (left p) = left (right p)joinʳ⁺-right⁺ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ (right p) = right pjoinʳ⁺-right⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ (here p) = right (here p)joinʳ⁺-right⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ (left (here p)) = here pjoinʳ⁺-right⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ (left (left p)) = left (right p)joinʳ⁺-right⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ (left (right p)) = right (left p)joinʳ⁺-right⁺ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ (right p) = right (right p)joinˡ⁺⁻ : ∀ {l u hˡ hʳ h} →(kv@(k , v) : K& V) →(l : ∃ λ i → Tree V l [ k ] (i ⊕ hˡ)) →(r : Tree V [ k ] u hʳ) →(bal : hˡ ∼ hʳ ⊔ h) →Any P (proj₂ (joinˡ⁺ kv l r bal)) →P kv ⊎ Any P (proj₂ l) ⊎ Any P rjoinˡ⁺⁻ k₂ (0# , t₁) t₃ ba = Any.toSumjoinˡ⁺⁻ k₂ (1# , t₁) t₃ ∼0 = Any.toSumjoinˡ⁺⁻ k₂ (1# , t₁) t₃ ∼+ = Any.toSumjoinˡ⁺⁻ k₄ (1# , node k₂ t₁ t₃ ∼-) t₅ ∼- = λ where(left p) → inj₂ (inj₁ (left p))(here p) → inj₂ (inj₁ (here p))(right (left p)) → inj₂ (inj₁ (right p))(right (here p)) → inj₁ p(right (right p)) → inj₂ (inj₂ p)joinˡ⁺⁻ k₄ (1# , node k₂ t₁ t₃ ∼0) t₅ ∼- = λ where(left p) → inj₂ (inj₁ (left p))(here p) → inj₂ (inj₁ (here p))(right (left p)) → inj₂ (inj₁ (right p))(right (here p)) → inj₁ p(right (right p)) → inj₂ (inj₂ p)joinˡ⁺⁻ k₆ (1# , node⁺ k₂ t₁ k₄ t₃ t₅ bal) t₇ ∼- = λ where(left (left p)) → inj₂ (inj₁ (left p))(left (here p)) → inj₂ (inj₁ (here p))(left (right p)) → inj₂ (inj₁ (right (left p)))(here p) → inj₂ (inj₁ (right (here p)))(right (left p)) → inj₂ (inj₁ (right (right p)))(right (here p)) → inj₁ p(right (right p)) → inj₂ (inj₂ p)joinʳ⁺⁻ : ∀ {l u hˡ hʳ h} →(kv : K& V) →(l : Tree V l [ kv .key ] hˡ) →(r : ∃ λ i → Tree V [ kv .key ] u (i ⊕ hʳ)) →(bal : hˡ ∼ hʳ ⊔ h) →Any P (proj₂ (joinʳ⁺ kv l r bal)) →P kv ⊎ Any P l ⊎ Any P (proj₂ r)joinʳ⁺⁻ k₂ t₁ (0# , t₃) bal = Any.toSumjoinʳ⁺⁻ k₂ t₁ (1# , t₃) ∼0 = Any.toSumjoinʳ⁺⁻ k₂ t₁ (1# , t₃) ∼- = Any.toSumjoinʳ⁺⁻ k₂ t₁ (1# , node k₄ t₃ t₅ ∼+) ∼+ = λ where(left (left p)) → inj₂ (inj₁ p)(left (here p)) → inj₁ p(left (right p)) → inj₂ (inj₂ (left p))(here p) → inj₂ (inj₂ (here p))(right p) → inj₂ (inj₂ (right p))joinʳ⁺⁻ k₂ t₁ (1# , node k₄ t₃ t₅ ∼0) ∼+ = λ where(left (left p)) → inj₂ (inj₁ p)(left (here p)) → inj₁ p(left (right p)) → inj₂ (inj₂ (left p))(here p) → inj₂ (inj₂ (here p))(right p) → inj₂ (inj₂ (right p))joinʳ⁺⁻ k₂ t₁ (1# , node⁻ k₆ k₄ t₃ t₅ bal t₇) ∼+ = λ where(left (left p)) → inj₂ (inj₁ p)(left (here p)) → inj₁ p(left (right p)) → inj₂ (inj₂ (left (left p)))(here p) → inj₂ (inj₂ (left (here p)))(right (left p)) → inj₂ (inj₂ (left (right p)))(right (here p)) → inj₂ (inj₂ (here p))(right (right p)) → inj₂ (inj₂ (right p))module _ {V : Value v} whereprivateVal = Value.family VVal≈ = Value.respects Vsingleton⁺ : {P : Pred (K& V) p} →(k : Key) →(v : Val k) →(l<k<u : l < k < u) →P (k , v) → Any P (singleton k v l<k<u)singleton⁺ k v l<k<u Pkv = here Pkvsingleton⁻ : {P : Pred (K& V) p} →(k : Key) →(v : Val k) →(l<k<u : l < k < u) →Any P (singleton k v l<k<u) → P (k , v)singleton⁻ k v l<k<u (here Pkv) = Pkv------------------------------------------------------------------------ insertmodule _ (k : Key) (f : Maybe (Val k) → Val k) whereopen <-Reasoning AVL.strictPartialOrderAny-insertWith-nothing : (t : Tree V l u n) (seg : l < k < u) →P (k , f nothing) →¬ (Any ((k ≈_) ∘′ key) t) → Any P (proj₂ (insertWith k f t seg))Any-insertWith-nothing (leaf l<u) seg pr ¬p = here prAny-insertWith-nothing (node kv@(k′ , v) lk ku bal) (l<k , k<u) pr ¬pwith compare k k′... | tri≈ _ k≈k′ _ = contradiction (here k≈k′) ¬p... | tri< k<k′ _ _ = let seg′ = l<k , [ k<k′ ]ᴿ; lk′ = insertWith k f lk seg′ih = Any-insertWith-nothing lk seg′ pr (λ p → ¬p (left p))in joinˡ⁺-left⁺ kv lk′ ku bal ih... | tri> _ _ k>k′ = let seg′ = [ k>k′ ]ᴿ , k<u; ku′ = insertWith k f ku seg′ih = Any-insertWith-nothing ku seg′ pr (λ p → ¬p (right p))in joinʳ⁺-right⁺ kv lk ku′ bal ihAny-insertWith-just : (t : Tree V l u n) (seg : l < k < u) →(pr : ∀ k′ v → (eq : k ≈ k′) → P (k′ , Val≈ eq (f (just (Val≈ (sym eq) v))))) →Any ((k ≈_) ∘′ key) t → Any P (proj₂ (insertWith k f t seg))Any-insertWith-just (node kv@(k′ , v) lk ku bal) (l<k , k<u) pr pwith p | compare k k′-- happy paths... | here _ | tri≈ _ k≈k′ _ = here (pr k′ v k≈k′)... | left lp | tri< k<k′ _ _ = let seg′ = l<k , [ k<k′ ]ᴿ; lk′ = insertWith k f lk seg′ injoinˡ⁺-left⁺ kv lk′ ku bal (Any-insertWith-just lk seg′ pr lp)... | right rp | tri> _ _ k>k′ = let seg′ = [ k>k′ ]ᴿ , k<u; ku′ = insertWith k f ku seg′ injoinʳ⁺-right⁺ kv lk ku′ bal (Any-insertWith-just ku seg′ pr rp)-- impossible cases... | here eq | tri< k<k′ _ _ = begin-contradiction[ k ] <⟨ [ k<k′ ]ᴿ ⟩[ k′ ] ≈⟨ [ sym eq ]ᴱ ⟩[ k ] ∎... | here eq | tri> _ _ k>k′ = begin-contradiction[ k ] ≈⟨ [ eq ]ᴱ ⟩[ k′ ] <⟨ [ k>k′ ]ᴿ ⟩[ k ] ∎... | left lp | tri≈ _ k≈k′ _ = begin-contradictionlet k″ = Any.lookup lp .key; k≈k″ = lookup-result lp; (_ , k″<k′) = lookup-bounded lp in[ k ] ≈⟨ [ k≈k″ ]ᴱ ⟩[ k″ ] <⟨ k″<k′ ⟩[ k′ ] ≈⟨ [ sym k≈k′ ]ᴱ ⟩[ k ] ∎... | left lp | tri> _ _ k>k′ = begin-contradictionlet k″ = Any.lookup lp .key; k≈k″ = lookup-result lp; (_ , k″<k′) = lookup-bounded lp in[ k ] ≈⟨ [ k≈k″ ]ᴱ ⟩[ k″ ] <⟨ k″<k′ ⟩[ k′ ] <⟨ [ k>k′ ]ᴿ ⟩[ k ] ∎... | right rp | tri< k<k′ _ _ = begin-contradictionlet k″ = Any.lookup rp .key; k≈k″ = lookup-result rp; (k′<k″ , _) = lookup-bounded rp in[ k ] <⟨ [ k<k′ ]ᴿ ⟩[ k′ ] <⟨ k′<k″ ⟩[ k″ ] ≈⟨ [ sym k≈k″ ]ᴱ ⟩[ k ] ∎... | right rp | tri≈ _ k≈k′ _ = begin-contradictionlet k″ = Any.lookup rp .key; k≈k″ = lookup-result rp; (k′<k″ , _) = lookup-bounded rp in[ k ] ≈⟨ [ k≈k′ ]ᴱ ⟩[ k′ ] <⟨ k′<k″ ⟩[ k″ ] ≈⟨ [ sym k≈k″ ]ᴱ ⟩[ k ] ∎module _ (k : Key) (v : Val k) (t : Tree V l u n) (seg : l < k < u) whereAny-insert-nothing : P (k , v) → ¬ (Any ((k ≈_) ∘′ key) t) → Any P (proj₂ (insert k v t seg))Any-insert-nothing = Any-insertWith-nothing k (F.const v) t segAny-insert-just : (pr : ∀ k′ → (eq : k ≈ k′) → P (k′ , Val≈ eq v)) →Any ((k ≈_) ∘′ key) t → Any P (proj₂ (insert k v t seg))Any-insert-just pr = Any-insertWith-just k (F.const v) t seg (λ k′ _ eq → pr k′ eq)module _ (k : Key) (f : Maybe (Val k) → Val k) whereinsertWith⁺ : (t : Tree V l u n) (seg : l < k < u) →(p : Any P t) → k ≉ Any.lookupKey p →Any P (proj₂ (insertWith k f t seg))insertWith⁺ (node kv@(k′ , v′) l r bal) (l<k , k<u) (here p) k≉with compare k k′... | tri< k<k′ _ _ = let l′ = insertWith k f l (l<k , [ k<k′ ]ᴿ)in joinˡ⁺-here⁺ kv l′ r bal p... | tri≈ _ k≈k′ _ = contradiction k≈k′ k≉... | tri> _ _ k′<k = let r′ = insertWith k f r ([ k′<k ]ᴿ , k<u)in joinʳ⁺-here⁺ kv l r′ bal pinsertWith⁺ (node kv@(k′ , v′) l r bal) (l<k , k<u) (left p) k≉with compare k k′... | tri< k<k′ _ _ = let l′ = insertWith k f l (l<k , [ k<k′ ]ᴿ)ih = insertWith⁺ l (l<k , [ k<k′ ]ᴿ) p k≉in joinˡ⁺-left⁺ kv l′ r bal ih... | tri≈ _ k≈k′ _ = left p... | tri> _ _ k′<k = let r′ = insertWith k f r ([ k′<k ]ᴿ , k<u)in joinʳ⁺-left⁺ kv l r′ bal pinsertWith⁺ (node kv@(k′ , v′) l r bal) (l<k , k<u) (right p) k≉with compare k k′... | tri< k<k′ _ _ = let l′ = insertWith k f l (l<k , [ k<k′ ]ᴿ)in joinˡ⁺-right⁺ kv l′ r bal p... | tri≈ _ k≈k′ _ = right p... | tri> _ _ k′<k = let r′ = insertWith k f r ([ k′<k ]ᴿ , k<u)ih = insertWith⁺ r ([ k′<k ]ᴿ , k<u) p k≉in joinʳ⁺-right⁺ kv l r′ bal ihinsert⁺ : (k : Key) (v : Val k) (t : Tree V l u n) (seg : l < k < u) →(p : Any P t) → k ≉ Any.lookupKey p →Any P (proj₂ (insert k v t seg))insert⁺ k v = insertWith⁺ k (F.const v)module _{P : Pred (K& V) p}(P-Resp : ∀ {k k′ v} → (k≈k′ : k ≈ k′) → P (k′ , Val≈ k≈k′ v) → P (k , v))(k : Key) (v : Val k)whereinsert⁻ : (t : Tree V l u n) (seg : l < k < u) →Any P (proj₂ (insert k v t seg)) →P (k , v) ⊎ Any (λ{ (k′ , v′) → k ≉ k′ × P (k′ , v′)}) tinsert⁻ (leaf l<u) seg (here p) = inj₁ pinsert⁻ (node kv′@(k′ , v′) l r bal) (l<k , k<u) p with compare k k′insert⁻ (node kv′@(k′ , v′) l r bal) (l<k , k<u) p | tri< k<k′ k≉k′ _with joinˡ⁺⁻ kv′ (insert k v l (l<k , [ k<k′ ]ᴿ)) r bal p... | inj₁ p = inj₂ (here (k≉k′ , p))... | inj₂ (inj₂ p) = inj₂ (right (lookup-rebuild-accum p k≉p))wherek′<p = [<]-injective (proj₁ (lookup-bounded p))k≉p = λ k≈p → irrefl k≈p (<-trans k<k′ k′<p)... | inj₂ (inj₁ p) = Sum.map₂ (λ q → left q) (insert⁻ l (l<k , [ k<k′ ]ᴿ) p)insert⁻ (node kv′@(k′ , v′) l r bal) (l<k , k<u) p | tri> _ k≉k′ k′<kwith joinʳ⁺⁻ kv′ l (insert k v r ([ k′<k ]ᴿ , k<u)) bal p... | inj₁ p = inj₂ (here (k≉k′ , p))... | inj₂ (inj₁ p) = inj₂ (left (lookup-rebuild-accum p k≉p))wherep<k′ = [<]-injective (proj₂ (lookup-bounded p))k≉p = λ k≈p → irrefl (sym k≈p) (<-trans p<k′ k′<k)... | inj₂ (inj₂ p) = Sum.map₂ (λ q → right q) (insert⁻ r ([ k′<k ]ᴿ , k<u) p)insert⁻ (node kv′@(k′ , v′) l r bal) (l<k , k<u) p | tri≈ _ k≈k′ _with p... | left p = inj₂ (left (lookup-rebuild-accum p k≉p))wherep<k′ = [<]-injective (proj₂ (lookup-bounded p))k≉p = λ k≈p → irrefl (trans (sym k≈p) k≈k′) p<k′... | here p = inj₁ (P-Resp k≈k′ p)... | right p = inj₂ (right (lookup-rebuild-accum p k≉p))wherek′<p = [<]-injective (proj₁ (lookup-bounded p))k≉p = λ k≈p → irrefl (trans (sym k≈k′) k≈p) k′<plookup⁺ : (t : Tree V l u n) (k : Key) (seg : l < k < u) →(p : Any P t) →key (Any.lookup p) ≉ k ⊎ ∃[ p≈k ] AVL.lookup t k seg ≡ just (Val≈ p≈k (value (Any.lookup p)))lookup⁺ (node (k′ , v′) l r bal) k (l<k , k<u) pwith compare k′ k | p... | tri< k′<k _ _ | right p = lookup⁺ r k ([ k′<k ]ᴿ , k<u) p... | tri≈ _ k′≈k _ | here p = inj₂ (k′≈k , ≡-refl)... | tri> _ _ k<k′ | left p = lookup⁺ l k (l<k , [ k<k′ ]ᴿ) p... | tri< k′<k _ _ | left p = inj₁ (λ p≈k → irrefl p≈k (<-trans p<k′ k′<k))where p<k′ = [<]-injective (proj₂ (lookup-bounded p))... | tri< k′<k _ _ | here p = inj₁ (λ p≈k → irrefl p≈k k′<k)... | tri≈ _ k′≈k _ | left p = inj₁ (λ p≈k → irrefl (trans p≈k (sym k′≈k)) p<k′)where p<k′ = [<]-injective (proj₂ (lookup-bounded p))... | tri≈ _ k′≈k _ | right p = inj₁ (λ p≈k → irrefl (trans k′≈k (sym p≈k)) k′<p)where k′<p = [<]-injective (proj₁ (lookup-bounded p))... | tri> _ _ k<k′ | here p = inj₁ (λ p≈k → irrefl (sym p≈k) k<k′)... | tri> _ _ k<k′ | right p = inj₁ (λ p≈k → irrefl (sym p≈k) (<-trans k<k′ k′<p))where k′<p = [<]-injective (proj₁ (lookup-bounded p))lookup⁻ : (t : Tree V l u n) (k : Key) (v : Val k) (seg : l < k < u) →AVL.lookup t k seg ≡ just v →Any (λ{ (k′ , v′) → ∃ λ k′≈k → Val≈ k′≈k v′ ≡ v}) tlookup⁻ (node (k′ , v′) l r bal) k v (l<k , k<u) eq with compare k′ k... | tri< k′<k _ _ = right (lookup⁻ r k v ([ k′<k ]ᴿ , k<u) eq)... | tri≈ _ k′≈k _ = here (k′≈k , just-injective eq)... | tri> _ _ k<k′ = left (lookup⁻ l k v (l<k , [ k<k′ ]ᴿ) eq)
-------------------------------------------------------------------------- The Agda standard library---- AVL trees whose elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.Tree.AVL.Indexed.Relation.Unary.All{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)whereopen import Data.Nat.Base using (ℕ)open import Data.Product.Base using (_,_; _×_)open import Data.Product.Nary.NonDependentopen import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Baseopen import Function.Nary.NonDependent using (congₙ)open import Level using (Level; _⊔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Nullary.Decidable using (Dec; yes; map′; _×-dec_)open import Relation.Unary using (Pred; Decidable; Universal; Irrelevant; _⊆_; _∪_)open StrictTotalOrder strictTotalOrder renaming (Carrier to Key)open import Data.Tree.AVL.Indexed strictTotalOrderusing (Tree; Value; Key⁺; [_]; _<⁺_; K&_; key; _∼_⊔_; ∼0; leaf; node)open import Data.Tree.AVL.Indexed.Relation.Unary.Any strictTotalOrderusing (Any; here; left; right)privatevariablev p q : LevelV : Value vP : Pred (K& V) pQ : Pred (K& V) ql u : Key⁺n : ℕt : Tree V l u n-------------------------------------------------------------------------- Definition-- Given a predicate P, All P t is a proof that all of the elements in t-- satisfy P.-- See `Relation.Unary` for an explanation of predicates.data All {V : Value v} (P : Pred (K& V) p) {l u}: ∀ {n} → Tree V l u n → Set (p ⊔ a ⊔ v ⊔ ℓ₂) whereleaf : {p : l <⁺ u} → All P (leaf p)node : ∀ {hˡ hʳ h} {kv : K& V}{lk : Tree V l [ kv .key ] hˡ}{ku : Tree V [ kv .key ] u hʳ} →{bal : hˡ ∼ hʳ ⊔ h} →P kv → All P lk → All P ku → All P (node kv lk ku bal)-------------------------------------------------------------------------- Operations on Allmap : P ⊆ Q → All P t → All Q tmap f leaf = leafmap f (node p l r) = node (f p) (map f l) (map f r)decide : Π[ P ∪ Q ] → (t : Tree V l u n) → All P t ⊎ Any Q tdecide p⊎q (leaf l<u) = inj₁ leafdecide p⊎q (node kv l r bal) with p⊎q kv | decide p⊎q l | decide p⊎q r... | inj₂ q | _ | _ = inj₂ (here q)... | _ | inj₂ q | _ = inj₂ (left q)... | _ | _ | inj₂ q = inj₂ (right q)... | inj₁ pv | inj₁ pl | inj₁ pr = inj₁ (node pv pl pr)unnode : ∀ {hˡ hʳ h} {kv : K& V}{lk : Tree V l [ kv .key ] hˡ}{ku : Tree V [ kv .key ] u hʳ}{bal : hˡ ∼ hʳ ⊔ h} →All P (node kv lk ku bal) → P kv × All P lk × All P kuunnode (node p l r) = p , l , rall? : Decidable P → ∀ (t : Tree V l u n) → Dec (All P t)all? p? (leaf l<u) = yes leafall? p? (node kv l r bal) = map′ (uncurryₙ 3 node) unnode(p? kv ×-dec all? p? l ×-dec all? p? r)universal : Universal P → (t : Tree V l u n) → All P tuniversal u (leaf l<u) = leafuniversal u (node kv l r bal) = node (u kv) (universal u l) (universal u r)irrelevant : Irrelevant P → (p q : All P t) → p ≡ qirrelevant irr leaf leaf = reflirrelevant irr (node p l₁ r₁) (node q l₂ r₂) =congₙ 3 node (irr p q) (irrelevant irr l₁ l₂) (irrelevant irr r₁ r₂)
-------------------------------------------------------------------------- The Agda standard library---- Types and functions which are used to keep track of height-- invariants in AVL Trees------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Tree.AVL.Height whereopen import Data.Nat.Baseopen import Data.Fin.Base using (Fin; zero; suc)ℕ₂ = Fin 2pattern 0# = zeropattern 1# = suc zeropattern ## = suc (suc ())-- Addition.infixl 6 _⊕__⊕_ : ℕ₂ → ℕ → ℕ0# ⊕ n = n1# ⊕ n = 1 + n-- pred[ i ⊕ n ] = pred (i ⊕ n).pred[_⊕_] : ℕ₂ → ℕ → ℕpred[ i ⊕ zero ] = 0pred[ i ⊕ suc n ] = i ⊕ ninfix 4 _∼_⊔_-- If i ∼ j ⊔ m, then the difference between i and j is at most 1,-- and the maximum of i and j is m. _∼_⊔_ is used to record the-- balance factor of the AVL trees, and also to ensure that the-- absolute value of the balance factor is never more than 1.data _∼_⊔_ : ℕ → ℕ → ℕ → Set where∼+ : ∀ {n} → n ∼ 1 + n ⊔ 1 + n∼0 : ∀ {n} → n ∼ n ⊔ n∼- : ∀ {n} → 1 + n ∼ n ⊔ 1 + n-- Some lemmas.max∼ : ∀ {i j m} → i ∼ j ⊔ m → m ∼ i ⊔ mmax∼ ∼+ = ∼-max∼ ∼0 = ∼0max∼ ∼- = ∼0∼max : ∀ {i j m} → i ∼ j ⊔ m → j ∼ m ⊔ m∼max ∼+ = ∼0∼max ∼0 = ∼0∼max ∼- = ∼+
-------------------------------------------------------------------------- The Agda standard library---- An either-or-both data type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These whereopen import Levelopen import Data.Maybe.Base using (Maybe; just; nothing; maybe′)open import Data.Sum.Base using (_⊎_; [_,_]′)open import Function.Base using (const; _∘′_; id; constᵣ)-------------------------------------------------------------------------- Re-exporting the datatype and its operationsopen import Data.These.Base publicprivatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Additional operations-- projectionsfromThis : These A B → Maybe AfromThis = fold just (const nothing) (const ∘′ just)fromThat : These A B → Maybe BfromThat = fold (const nothing) just (const just)leftMost : These A A → AleftMost = fold id id constrightMost : These A A → ArightMost = fold id id constᵣmergeThese : (A → A → A) → These A A → AmergeThese = fold id id-- deletionsdeleteThis : These A B → Maybe (These A B)deleteThis = fold (const nothing) (just ∘′ that) (const (just ∘′ that))deleteThat : These A B → Maybe (These A B)deleteThat = fold (just ∘′ this) (const nothing) (const ∘′ just ∘′ this)
-------------------------------------------------------------------------- The Agda standard library---- Properties of These------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Properties whereopen import Data.Product.Base using (_×_; _,_; <_,_>; uncurry)open import Data.These.Base using (These; this; that; these)open import Function.Base using (_∘_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂)open import Relation.Nullary.Decidable using (yes; no; map′; _×-dec_)-------------------------------------------------------------------------- Equalitymodule _ {a b} {A : Set a} {B : Set b} wherethis-injective : ∀ {x y : A} → this {B = B} x ≡ this y → x ≡ ythis-injective refl = reflthat-injective : ∀ {a b : B} → that {A = A} a ≡ that b → a ≡ bthat-injective refl = reflthese-injectiveˡ : ∀ {x y : A} {a b : B} → these x a ≡ these y b → x ≡ ythese-injectiveˡ refl = reflthese-injectiveʳ : ∀ {x y : A} {a b : B} → these x a ≡ these y b → a ≡ bthese-injectiveʳ refl = reflthese-injective : ∀ {x y : A} {a b : B} → these x a ≡ these y b → x ≡ y × a ≡ bthese-injective = < these-injectiveˡ , these-injectiveʳ >≡-dec : DecidableEquality A → DecidableEquality B → DecidableEquality (These A B)≡-dec dec₁ dec₂ (this x) (this y) =map′ (cong this) this-injective (dec₁ x y)≡-dec dec₁ dec₂ (this x) (that y) = no λ()≡-dec dec₁ dec₂ (this x) (these y b) = no λ()≡-dec dec₁ dec₂ (that x) (this y) = no λ()≡-dec dec₁ dec₂ (that x) (that y) =map′ (cong that) that-injective (dec₂ x y)≡-dec dec₁ dec₂ (that x) (these y b) = no λ()≡-dec dec₁ dec₂ (these x a) (this y) = no λ()≡-dec dec₁ dec₂ (these x a) (that y) = no λ()≡-dec dec₁ dec₂ (these x a) (these y b) =map′ (uncurry (cong₂ these)) these-injective (dec₁ x y ×-dec dec₂ a b)
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for These------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Instances whereopen import Data.These.Baseopen import Data.These.Propertiesopen import Levelopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.TypeClassesprivatevariablea b : LevelA : Set aB : Set binstanceThese-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → {{IsDecEquivalence {A = B} _≡_}} → IsDecEquivalence {A = These A B} _≡_These-≡-isDecEquivalence = isDecEquivalence (≡-dec _≟_ _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Right-biased universe-sensitive functor and monad instances for These.-------------------------------------------------------------------------- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b).-- See the Data.Product.Effectful.Examples for how this is done in a-- Product-based similar setting.-- This functor can be understood as a notion of computation which can-- either fail (that), succeed (this) or accumulate warnings whilst-- delivering a successful computation (these).-- It is a good alternative to Data.Product.Effectful when the notion-- of warnings does not have a neutral element (e.g. List⁺).{-# OPTIONS --cubical-compatible --safe #-}open import Levelopen import Algebramodule Data.These.Effectful.Right (a : Level) {c ℓ} (W : Semigroup c ℓ) whereopen Semigroup Wopen import Data.These.Effectful.Right.Base a Carrier publicopen import Data.These.Baseopen import Effect.Applicativeopen import Effect.Monadmodule _ {a b} {A : Set a} {B : Set b} whereapplicative : RawApplicative Theseᵣapplicative = record{ rawFunctor = functor; pure = this; _<*>_ = ap} whereap : ∀ {A B}→ Theseᵣ (A → B) → Theseᵣ A → Theseᵣ Bap (this f) t = map₁ f tap (that w) t = that wap (these f w) t = map f (w ∙_) tmonad : RawMonad Theseᵣmonad = record{ rawApplicative = applicative; _>>=_ = bind} wherebind : ∀ {A B} → Theseᵣ A → (A → Theseᵣ B) → Theseᵣ Bbind (this t) f = f tbind (that w) f = that wbind (these t w) f = map₂ (w ∙_) (f t)
-------------------------------------------------------------------------- The Agda standard library---- Base definitions for the right-biased universe-sensitive functor and-- monad instances for These.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b).-- See the Data.Product.Effectful.Examples for how this is done in a-- Product-based similar setting.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.These.Effectful.Right.Base (a : Level) {b} (B : Set b) whereopen import Data.These.Baseopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Base using (flip; _∘_)Theseᵣ : Set (a ⊔ b) → Set (a ⊔ b)Theseᵣ A = These A Bfunctor : RawFunctor Theseᵣfunctor = record { _<$>_ = map₁ }-------------------------------------------------------------------------- Get access to other monadic functionsmodule _ {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Theseᵣ (F A) → F (Theseᵣ A)sequenceA (this a) = this <$> asequenceA (that b) = pure (that b)sequenceA (these a b) = flip these b <$> amapA : ∀ {A B} → (A → F B) → Theseᵣ A → F (Theseᵣ B)mapA f = sequenceA ∘ map₁ fforA : ∀ {A B} → Theseᵣ A → (A → F B) → F (Theseᵣ B)forA = flip mapAmodule _ {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereprivate App = RawMonad.rawApplicative MonsequenceM : ∀ {A} → Theseᵣ (M A) → M (Theseᵣ A)sequenceM = sequenceA AppmapM : ∀ {A B} → (A → M B) → Theseᵣ A → M (Theseᵣ B)mapM = mapA AppforM : ∀ {A B} → Theseᵣ A → (A → M B) → M (Theseᵣ B)forM = forA App
-------------------------------------------------------------------------- The Agda standard library---- Left-biased universe-sensitive functor and monad instances for These.---------------------------------------------------------------------------- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b).-- See the Data.Product.Effectful.Examples for how this is done in a-- Product-based similar setting.-- This functor can be understood as a notion of computation which can-- either fail (this), succeed (that) or accumulate warnings whilst-- delivering a successful computation (these).-- It is a good alternative to Data.Product.Effectful when the notion-- of warnings does not have a neutral element (e.g. List⁺).{-# OPTIONS --cubical-compatible --safe #-}open import Levelopen import Algebramodule Data.These.Effectful.Left {c ℓ} (W : Semigroup c ℓ) (b : Level) whereopen Semigroup Wopen import Data.These.Effectful.Left.Base Carrier b publicopen import Data.These.Baseopen import Effect.Applicativeopen import Effect.Monadmodule _ {a b} {A : Set a} {B : Set b} whereapplicative : RawApplicative Theseₗapplicative = record{ rawFunctor = functor; pure = that; _<*>_ = ap} whereap : ∀ {A B} → Theseₗ (A → B) → Theseₗ A → Theseₗ Bap (this w) t = this wap (that f) t = map₂ f tap (these w f) t = map (w ∙_) f tmonad : RawMonad Theseₗmonad = record{ rawApplicative = applicative; _>>=_ = bind} wherebind : ∀ {A B} → Theseₗ A → (A → Theseₗ B) → Theseₗ Bbind (this w) f = this wbind (that t) f = f tbind (these w t) f = map₁ (w ∙_) (f t)
-------------------------------------------------------------------------- The Agda standard library---- Base definitions for the left-biased universe-sensitive functor and-- monad instances for These.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b).-- See the Data.Product.Effectful.Examples for how this is done in a-- Product-based similar setting.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.These.Effectful.Left.Base {a} (A : Set a) (b : Level) whereopen import Data.These.Baseopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Base using (_∘_; flip)Theseₗ : Set (a ⊔ b) → Set (a ⊔ b)Theseₗ B = These A Bfunctor : RawFunctor Theseₗfunctor = record { _<$>_ = map₂ }-------------------------------------------------------------------------- Get access to other monadic functionsmodule _ {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Theseₗ (F A) → F (Theseₗ A)sequenceA (this a) = pure (this a)sequenceA (that b) = that <$> bsequenceA (these a b) = these a <$> bmapA : ∀ {A B} → (A → F B) → Theseₗ A → F (Theseₗ B)mapA f = sequenceA ∘ map₂ fforA : ∀ {A B} → Theseₗ A → (A → F B) → F (Theseₗ B)forA = flip mapAmodule _ {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereprivate App = RawMonad.rawApplicative MonsequenceM : ∀ {A} → Theseₗ (M A) → M (Theseₗ A)sequenceM = sequenceA AppmapM : ∀ {A B} → (A → M B) → Theseₗ A → M (Theseₗ B)mapM = mapA AppforM : ∀ {A B} → Theseₗ A → (A → M B) → M (Theseₗ B)forM = forA App
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.These.Categorical.Right` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Categorical.Right whereopen import Data.These.Effectful.Right public{-# WARNING_ON_IMPORT"Data.These.Categorical.Right was deprecated in v2.0.Use Data.These.Effectful.Right instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.These.Categorical.Right.Base` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Categorical.Right.Base whereopen import Data.These.Effectful.Right.Base public{-# WARNING_ON_IMPORT"Data.These.Categorical.Right.Base was deprecated in v2.0.Use Data.These.Effectful.Right.Base instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.These.Categorical.Left` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Categorical.Left whereopen import Data.These.Effectful.Left public{-# WARNING_ON_IMPORT"Data.These.Categorical.Left was deprecated in v2.0.Use Data.These.Effectful.Left instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.These.Categorical.Left.Base` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Categorical.Left.Base whereopen import Data.These.Effectful.Left.Base public{-# WARNING_ON_IMPORT"Data.These.Categorical.Left.Base was deprecated in v2.0.Use Data.These.Effectful.Left.Base instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An either-or-both data type, basic type and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.These.Base whereopen import Levelopen import Data.Sum.Base using (_⊎_; [_,_]′)open import Function.Baseprivatevariablea b c d e f : LevelA : Set aB : Set bC : Set cD : Set dE : Set eF : Set fdata These {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) wherethis : A → These A Bthat : B → These A Bthese : A → B → These A B-------------------------------------------------------------------------- Operations-- injectionfromSum : A ⊎ B → These A BfromSum = [ this , that ]′-- mapmap : (f : A → B) (g : C → D) → These A C → These B Dmap f g (this a) = this (f a)map f g (that b) = that (g b)map f g (these a b) = these (f a) (g b)map₁ : (f : A → B) → These A C → These B Cmap₁ f = map f idmap₂ : (g : B → C) → These A B → These A Cmap₂ = map id-- foldfold : (A → C) → (B → C) → (A → B → C) → These A B → Cfold l r lr (this a) = l afold l r lr (that b) = r bfold l r lr (these a b) = lr a bfoldWithDefaults : A → B → (A → B → C) → These A B → CfoldWithDefaults a b lr = fold (flip lr b) (lr a) lr-- swapswap : These A B → These B Aswap = fold that this (flip these)-- alignalignWith : (These A C → E) → (These B D → F) → These A B → These C D → These E FalignWith f g (this a) (this c) = this (f (these a c))alignWith f g (this a) (that d) = these (f (this a)) (g (that d))alignWith f g (this a) (these c d) = these (f (these a c)) (g (that d))alignWith f g (that b) (this c) = these (f (that c)) (g (this b))alignWith f g (that b) (that d) = that (g (these b d))alignWith f g (that b) (these c d) = these (f (that c)) (g (these b d))alignWith f g (these a b) (this c) = these (f (these a c)) (g (this b))alignWith f g (these a b) (that d) = these (f (this a)) (g (these b d))alignWith f g (these a b) (these c d) = these (f (these a c)) (g (these b d))align : These A B → These C D → These (These A C) (These B D)align = alignWith id id
-------------------------------------------------------------------------- The Agda standard library---- Sums (disjoint unions)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum whereopen import Data.Unit.Polymorphic.Base using (⊤; tt)open import Data.Maybe.Base using (Maybe; just; nothing)open import Levelimport Relation.Nullary.Decidable.Core as Decprivatevariablea b : LevelA B : Set a-------------------------------------------------------------------------- Re-export content from base moduleopen import Data.Sum.Base public-------------------------------------------------------------------------- Additional functionsmodule _ {A : Set a} {B : Set b} whereisInj₁ : A ⊎ B → Maybe AisInj₁ (inj₁ x) = just xisInj₁ (inj₂ y) = nothingisInj₂ : A ⊎ B → Maybe BisInj₂ (inj₁ x) = nothingisInj₂ (inj₂ y) = just yFrom-inj₁ : A ⊎ B → Set aFrom-inj₁ (inj₁ _) = AFrom-inj₁ (inj₂ _) = ⊤from-inj₁ : (x : A ⊎ B) → From-inj₁ xfrom-inj₁ (inj₁ x) = xfrom-inj₁ (inj₂ _) = _From-inj₂ : A ⊎ B → Set bFrom-inj₂ (inj₁ _) = ⊤From-inj₂ (inj₂ _) = Bfrom-inj₂ : (x : A ⊎ B) → From-inj₂ xfrom-inj₂ (inj₁ _) = _from-inj₂ (inj₂ x) = x-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.1open Dec public using (fromDec; toDec)
-------------------------------------------------------------------------- The Agda standard library---- Heterogeneous `All` predicate for disjoint sums------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Relation.Unary.All whereopen import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Level using (Level; _⊔_)open import Relation.Unary using (Pred)privatevariablea b c p q : LevelA B : Set _P Q : Pred A p-------------------------------------------------------------------------- Definitiondata All {A : Set a} {B : Set b} (P : Pred A p) (Q : Pred B q): Pred (A ⊎ B) (a ⊔ b ⊔ p ⊔ q) whereinj₁ : ∀ {a} → P a → All P Q (inj₁ a)inj₂ : ∀ {b} → Q b → All P Q (inj₂ b)-------------------------------------------------------------------------- Operations-- Elimination[_,_] : ∀ {C : (x : A ⊎ B) → All P Q x → Set c} →((x : A) (y : P x) → C (inj₁ x) (inj₁ y)) →((x : B) (y : Q x) → C (inj₂ x) (inj₂ y)) →(x : A ⊎ B) (y : All P Q x) → C x y[ f , g ] (inj₁ x) (inj₁ y) = f x y[ f , g ] (inj₂ x) (inj₂ y) = g x y
-------------------------------------------------------------------------- The Agda standard library---- Pointwise sum------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Relation.Binary.Pointwise whereopen import Data.Product.Base using (_,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Data.Sum.Propertiesopen import Level using (Level; _⊔_)open import Function.Base using (const; _∘_; id)open import Function.Bundles using (Inverse; mk↔)open import Relation.Nullaryimport Relation.Nullary.Decidable as Decopen import Relation.Binaryopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b c d ℓ₁ ℓ₂ ℓ₃ ℓ : LevelA B C D : Set ℓR S T U : REL A B ℓ≈₁ ≈₂ : Rel A ℓ-------------------------------------------------------------------------- Definitiondata Pointwise {A : Set a} {B : Set b} {C : Set c} {D : Set d}(R : REL A C ℓ₁) (S : REL B D ℓ₂): REL (A ⊎ B) (C ⊎ D) (a ⊔ b ⊔ c ⊔ d ⊔ ℓ₁ ⊔ ℓ₂) whereinj₁ : ∀ {a c} → R a c → Pointwise R S (inj₁ a) (inj₁ c)inj₂ : ∀ {b d} → S b d → Pointwise R S (inj₂ b) (inj₂ d)------------------------------------------------------------------------ Functionsmap : ∀ {f : A → C} {g : B → D} →R =[ f ]⇒ T → S =[ g ]⇒ U →Pointwise R S =[ Sum.map f g ]⇒ Pointwise T Umap R⇒T _ (inj₁ x) = inj₁ (R⇒T x)map _ S⇒U (inj₂ x) = inj₂ (S⇒U x)-------------------------------------------------------------------------- Relational propertiesdrop-inj₁ : ∀ {x y} → Pointwise R S (inj₁ x) (inj₁ y) → R x ydrop-inj₁ (inj₁ x) = xdrop-inj₂ : ∀ {x y} → Pointwise R S (inj₂ x) (inj₂ y) → S x ydrop-inj₂ (inj₂ x) = x⊎-refl : Reflexive R → Reflexive S → Reflexive (Pointwise R S)⊎-refl refl₁ refl₂ {inj₁ x} = inj₁ refl₁⊎-refl refl₁ refl₂ {inj₂ y} = inj₂ refl₂⊎-symmetric : Symmetric R → Symmetric S →Symmetric (Pointwise R S)⊎-symmetric sym₁ sym₂ (inj₁ x) = inj₁ (sym₁ x)⊎-symmetric sym₁ sym₂ (inj₂ x) = inj₂ (sym₂ x)⊎-transitive : Transitive R → Transitive S →Transitive (Pointwise R S)⊎-transitive trans₁ trans₂ (inj₁ x) (inj₁ y) = inj₁ (trans₁ x y)⊎-transitive trans₁ trans₂ (inj₂ x) (inj₂ y) = inj₂ (trans₂ x y)⊎-asymmetric : Asymmetric R → Asymmetric S →Asymmetric (Pointwise R S)⊎-asymmetric asym₁ asym₂ (inj₁ x) = λ { (inj₁ y) → asym₁ x y }⊎-asymmetric asym₁ asym₂ (inj₂ x) = λ { (inj₂ y) → asym₂ x y }⊎-substitutive : Substitutive R ℓ₃ → Substitutive S ℓ₃ →Substitutive (Pointwise R S) ℓ₃⊎-substitutive subst₁ subst₂ P (inj₁ x) = subst₁ (P ∘ inj₁) x⊎-substitutive subst₁ subst₂ P (inj₂ x) = subst₂ (P ∘ inj₂) x⊎-decidable : Decidable R → Decidable S → Decidable (Pointwise R S)⊎-decidable _≟₁_ _≟₂_ (inj₁ x) (inj₁ y) = Dec.map′ inj₁ drop-inj₁ (x ≟₁ y)⊎-decidable _≟₁_ _≟₂_ (inj₁ x) (inj₂ y) = no λ()⊎-decidable _≟₁_ _≟₂_ (inj₂ x) (inj₁ y) = no λ()⊎-decidable _≟₁_ _≟₂_ (inj₂ x) (inj₂ y) = Dec.map′ inj₂ drop-inj₂ (x ≟₂ y)⊎-reflexive : ≈₁ ⇒ R → ≈₂ ⇒ S →(Pointwise ≈₁ ≈₂) ⇒ (Pointwise R S)⊎-reflexive refl₁ refl₂ (inj₁ x) = inj₁ (refl₁ x)⊎-reflexive refl₁ refl₂ (inj₂ x) = inj₂ (refl₂ x)⊎-irreflexive : Irreflexive ≈₁ R → Irreflexive ≈₂ S →Irreflexive (Pointwise ≈₁ ≈₂) (Pointwise R S)⊎-irreflexive irrefl₁ irrefl₂ (inj₁ x) (inj₁ y) = irrefl₁ x y⊎-irreflexive irrefl₁ irrefl₂ (inj₂ x) (inj₂ y) = irrefl₂ x y⊎-antisymmetric : Antisymmetric ≈₁ R → Antisymmetric ≈₂ S →Antisymmetric (Pointwise ≈₁ ≈₂) (Pointwise R S)⊎-antisymmetric antisym₁ antisym₂ (inj₁ x) (inj₁ y) = inj₁ (antisym₁ x y)⊎-antisymmetric antisym₁ antisym₂ (inj₂ x) (inj₂ y) = inj₂ (antisym₂ x y)⊎-respectsˡ : R Respectsˡ ≈₁ → S Respectsˡ ≈₂ →(Pointwise R S) Respectsˡ (Pointwise ≈₁ ≈₂)⊎-respectsˡ resp₁ resp₂ (inj₁ x) (inj₁ y) = inj₁ (resp₁ x y)⊎-respectsˡ resp₁ resp₂ (inj₂ x) (inj₂ y) = inj₂ (resp₂ x y)⊎-respectsʳ : R Respectsʳ ≈₁ → S Respectsʳ ≈₂ →(Pointwise R S) Respectsʳ (Pointwise ≈₁ ≈₂)⊎-respectsʳ resp₁ resp₂ (inj₁ x) (inj₁ y) = inj₁ (resp₁ x y)⊎-respectsʳ resp₁ resp₂ (inj₂ x) (inj₂ y) = inj₂ (resp₂ x y)⊎-respects₂ : R Respects₂ ≈₁ → S Respects₂ ≈₂ →(Pointwise R S) Respects₂ (Pointwise ≈₁ ≈₂)⊎-respects₂ (r₁ , l₁) (r₂ , l₂) = ⊎-respectsʳ r₁ r₂ , ⊎-respectsˡ l₁ l₂-------------------------------------------------------------------------- Structures⊎-isEquivalence : IsEquivalence ≈₁ → IsEquivalence ≈₂ →IsEquivalence (Pointwise ≈₁ ≈₂)⊎-isEquivalence eq₁ eq₂ = record{ refl = ⊎-refl (refl eq₁) (refl eq₂); sym = ⊎-symmetric (sym eq₁) (sym eq₂); trans = ⊎-transitive (trans eq₁) (trans eq₂)} where open IsEquivalence⊎-isDecEquivalence : IsDecEquivalence ≈₁ → IsDecEquivalence ≈₂ →IsDecEquivalence (Pointwise ≈₁ ≈₂)⊎-isDecEquivalence eq₁ eq₂ = record{ isEquivalence =⊎-isEquivalence (isEquivalence eq₁) (isEquivalence eq₂); _≟_ = ⊎-decidable (_≟_ eq₁) (_≟_ eq₂)} where open IsDecEquivalence⊎-isPreorder : IsPreorder ≈₁ R → IsPreorder ≈₂ S →IsPreorder (Pointwise ≈₁ ≈₂) (Pointwise R S)⊎-isPreorder pre₁ pre₂ = record{ isEquivalence =⊎-isEquivalence (isEquivalence pre₁) (isEquivalence pre₂); reflexive = ⊎-reflexive (reflexive pre₁) (reflexive pre₂); trans = ⊎-transitive (trans pre₁) (trans pre₂)} where open IsPreorder⊎-isPartialOrder : IsPartialOrder ≈₁ R → IsPartialOrder ≈₂ S →IsPartialOrder(Pointwise ≈₁ ≈₂) (Pointwise R S)⊎-isPartialOrder po₁ po₂ = record{ isPreorder = ⊎-isPreorder (isPreorder po₁) (isPreorder po₂); antisym = ⊎-antisymmetric (antisym po₁) (antisym po₂)} where open IsPartialOrder⊎-isStrictPartialOrder : IsStrictPartialOrder ≈₁ R →IsStrictPartialOrder ≈₂ S →IsStrictPartialOrder(Pointwise ≈₁ ≈₂) (Pointwise R S)⊎-isStrictPartialOrder spo₁ spo₂ = record{ isEquivalence =⊎-isEquivalence (isEquivalence spo₁) (isEquivalence spo₂); irrefl = ⊎-irreflexive (irrefl spo₁) (irrefl spo₂); trans = ⊎-transitive (trans spo₁) (trans spo₂); <-resp-≈ = ⊎-respects₂ (<-resp-≈ spo₁) (<-resp-≈ spo₂)} where open IsStrictPartialOrder-------------------------------------------------------------------------- Bundles⊎-setoid : Setoid a b → Setoid c d → Setoid _ _⊎-setoid s₁ s₂ = record{ isEquivalence =⊎-isEquivalence (isEquivalence s₁) (isEquivalence s₂)} where open Setoid⊎-decSetoid : DecSetoid a b → DecSetoid c d → DecSetoid _ _⊎-decSetoid ds₁ ds₂ = record{ isDecEquivalence =⊎-isDecEquivalence (isDecEquivalence ds₁) (isDecEquivalence ds₂)} where open DecSetoid⊎-preorder : Preorder a b ℓ₁ → Preorder c d ℓ₂ → Preorder _ _ _⊎-preorder p₁ p₂ = record{ isPreorder =⊎-isPreorder (isPreorder p₁) (isPreorder p₂)} where open Preorder⊎-poset : Poset a b c → Poset a b c → Poset _ _ _⊎-poset po₁ po₂ = record{ isPartialOrder =⊎-isPartialOrder (isPartialOrder po₁) (isPartialOrder po₂)} where open Poset-------------------------------------------------------------------------- Additional notation-- Infix combining setoidsinfix 4 _⊎ₛ__⊎ₛ_ : Setoid a b → Setoid c d → Setoid _ __⊎ₛ_ = ⊎-setoid-------------------------------------------------------------------------- The propositional equality setoid over products can be-- decomposed using PointwisePointwise-≡⇒≡ : (Pointwise _≡_ _≡_) ⇒ _≡_ {A = A ⊎ B}Pointwise-≡⇒≡ (inj₁ x) = ≡.cong inj₁ xPointwise-≡⇒≡ (inj₂ x) = ≡.cong inj₂ x≡⇒Pointwise-≡ : _≡_ {A = A ⊎ B} ⇒ (Pointwise _≡_ _≡_)≡⇒Pointwise-≡ ≡.refl = ⊎-refl ≡.refl ≡.reflPointwise-≡↔≡ : (A : Set a) (B : Set b) →Inverse (≡.setoid A ⊎ₛ ≡.setoid B) (≡.setoid (A ⊎ B))Pointwise-≡↔≡ _ _ = record{ to = id; from = id; to-cong = Pointwise-≡⇒≡; from-cong = ≡⇒Pointwise-≡; inverse = Pointwise-≡⇒≡ , ≡⇒Pointwise-≡}
-------------------------------------------------------------------------- The Agda standard library---- Sums of binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Relation.Binary.LeftOrder whereopen import Data.Sum.Base as Sumopen import Data.Sum.Relation.Binary.Pointwise as PWusing (Pointwise; inj₁; inj₂)open import Data.Product.Base using (_,_)open import Data.Emptyopen import Function.Base using (_$_; _∘_)open import Levelopen import Relation.Nullaryimport Relation.Nullary.Decidable as Decopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Preorder; Poset; StrictPartialOrder; TotalOrder; DecTotalOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsStrictPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; Asymmetric; Total; Decidable; Irreflexive; Antisymmetric; Trichotomous; _Respectsʳ_; _Respectsˡ_; _Respects₂_; tri<; tri>; tri≈)open import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Definitioninfixr 1 _⊎-<_data _⊎-<_ {a₁ a₂} {A₁ : Set a₁} {A₂ : Set a₂}{ℓ₁ ℓ₂} (_∼₁_ : Rel A₁ ℓ₁) (_∼₂_ : Rel A₂ ℓ₂) :Rel (A₁ ⊎ A₂) (a₁ ⊔ a₂ ⊔ ℓ₁ ⊔ ℓ₂) where₁∼₂ : ∀ {x y} → (_∼₁_ ⊎-< _∼₂_) (inj₁ x) (inj₂ y)₁∼₁ : ∀ {x y} (x∼₁y : x ∼₁ y) → (_∼₁_ ⊎-< _∼₂_) (inj₁ x) (inj₁ y)₂∼₂ : ∀ {x y} (x∼₂y : x ∼₂ y) → (_∼₁_ ⊎-< _∼₂_) (inj₂ x) (inj₂ y)-------------------------------------------------------------------------- Some properties which are preserved by _⊎-<_module _ {a₁ a₂} {A₁ : Set a₁} {A₂ : Set a₂}{ℓ₁ ℓ₂} {∼₁ : Rel A₁ ℓ₁} {∼₂ : Rel A₂ ℓ₂}wheredrop-inj₁ : ∀ {x y} → (∼₁ ⊎-< ∼₂) (inj₁ x) (inj₁ y) → ∼₁ x ydrop-inj₁ (₁∼₁ x∼₁y) = x∼₁ydrop-inj₂ : ∀ {x y} → (∼₁ ⊎-< ∼₂) (inj₂ x) (inj₂ y) → ∼₂ x ydrop-inj₂ (₂∼₂ x∼₂y) = x∼₂y⊎-<-refl : Reflexive ∼₁ → Reflexive ∼₂ →Reflexive (∼₁ ⊎-< ∼₂)⊎-<-refl refl₁ refl₂ {inj₁ x} = ₁∼₁ refl₁⊎-<-refl refl₁ refl₂ {inj₂ y} = ₂∼₂ refl₂⊎-<-transitive : Transitive ∼₁ → Transitive ∼₂ →Transitive (∼₁ ⊎-< ∼₂)⊎-<-transitive trans₁ trans₂ ₁∼₂ (₂∼₂ x∼₂y) = ₁∼₂⊎-<-transitive trans₁ trans₂ (₁∼₁ x∼₁y) ₁∼₂ = ₁∼₂⊎-<-transitive trans₁ trans₂ (₁∼₁ x∼₁y) (₁∼₁ x∼₁y₁) = ₁∼₁ (trans₁ x∼₁y x∼₁y₁)⊎-<-transitive trans₁ trans₂ (₂∼₂ x∼₂y) (₂∼₂ x∼₂y₁) = ₂∼₂ (trans₂ x∼₂y x∼₂y₁)⊎-<-asymmetric : Asymmetric ∼₁ → Asymmetric ∼₂ →Asymmetric (∼₁ ⊎-< ∼₂)⊎-<-asymmetric asym₁ asym₂ (₁∼₁ x∼₁y) (₁∼₁ x∼₁y₁) = asym₁ x∼₁y x∼₁y₁⊎-<-asymmetric asym₁ asym₂ (₂∼₂ x∼₂y) (₂∼₂ x∼₂y₁) = asym₂ x∼₂y x∼₂y₁⊎-<-total : Total ∼₁ → Total ∼₂ → Total (∼₁ ⊎-< ∼₂)⊎-<-total total₁ total₂ = totalwheretotal : Total (_ ⊎-< _)total (inj₁ x) (inj₁ y) = Sum.map ₁∼₁ ₁∼₁ $ total₁ x ytotal (inj₁ x) (inj₂ y) = inj₁ ₁∼₂total (inj₂ x) (inj₁ y) = inj₂ ₁∼₂total (inj₂ x) (inj₂ y) = Sum.map ₂∼₂ ₂∼₂ $ total₂ x y⊎-<-decidable : Decidable ∼₁ → Decidable ∼₂ →Decidable (∼₁ ⊎-< ∼₂)⊎-<-decidable dec₁ dec₂ (inj₁ x) (inj₁ y) = Dec.map′ ₁∼₁ drop-inj₁ (dec₁ x y)⊎-<-decidable dec₁ dec₂ (inj₁ x) (inj₂ y) = yes ₁∼₂⊎-<-decidable dec₁ dec₂ (inj₂ x) (inj₁ y) = no λ()⊎-<-decidable dec₁ dec₂ (inj₂ x) (inj₂ y) = Dec.map′ ₂∼₂ drop-inj₂ (dec₂ x y)module _ {a₁ a₂} {A₁ : Set a₁} {A₂ : Set a₂}{ℓ₁ ℓ₂} {∼₁ : Rel A₁ ℓ₁} {≈₁ : Rel A₁ ℓ₂}{ℓ₃ ℓ₄} {∼₂ : Rel A₂ ℓ₃} {≈₂ : Rel A₂ ℓ₄}where⊎-<-reflexive : ≈₁ ⇒ ∼₁ → ≈₂ ⇒ ∼₂ →(Pointwise ≈₁ ≈₂) ⇒ (∼₁ ⊎-< ∼₂)⊎-<-reflexive refl₁ refl₂ (inj₁ x) = ₁∼₁ (refl₁ x)⊎-<-reflexive refl₁ refl₂ (inj₂ x) = ₂∼₂ (refl₂ x)⊎-<-irreflexive : Irreflexive ≈₁ ∼₁ → Irreflexive ≈₂ ∼₂ →Irreflexive (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-irreflexive irrefl₁ irrefl₂ (inj₁ x) (₁∼₁ x∼₁y) = irrefl₁ x x∼₁y⊎-<-irreflexive irrefl₁ irrefl₂ (inj₂ x) (₂∼₂ x∼₂y) = irrefl₂ x x∼₂y⊎-<-antisymmetric : Antisymmetric ≈₁ ∼₁ → Antisymmetric ≈₂ ∼₂ →Antisymmetric (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-antisymmetric antisym₁ antisym₂ (₁∼₁ x∼₁y) (₁∼₁ x∼₁y₁) = inj₁ (antisym₁ x∼₁y x∼₁y₁)⊎-<-antisymmetric antisym₁ antisym₂ (₂∼₂ x∼₂y) (₂∼₂ x∼₂y₁) = inj₂ (antisym₂ x∼₂y x∼₂y₁)⊎-<-respectsʳ : ∼₁ Respectsʳ ≈₁ → ∼₂ Respectsʳ ≈₂ →(∼₁ ⊎-< ∼₂) Respectsʳ (Pointwise ≈₁ ≈₂)⊎-<-respectsʳ resp₁ resp₂ (inj₁ x₁) (₁∼₁ x∼₁y) = ₁∼₁ (resp₁ x₁ x∼₁y)⊎-<-respectsʳ resp₁ resp₂ (inj₂ x₁) ₁∼₂ = ₁∼₂⊎-<-respectsʳ resp₁ resp₂ (inj₂ x₁) (₂∼₂ x∼₂y) = ₂∼₂ (resp₂ x₁ x∼₂y)⊎-<-respectsˡ : ∼₁ Respectsˡ ≈₁ → ∼₂ Respectsˡ ≈₂ →(∼₁ ⊎-< ∼₂) Respectsˡ (Pointwise ≈₁ ≈₂)⊎-<-respectsˡ resp₁ resp₂ (inj₁ x) ₁∼₂ = ₁∼₂⊎-<-respectsˡ resp₁ resp₂ (inj₁ x) (₁∼₁ x∼₁y) = ₁∼₁ (resp₁ x x∼₁y)⊎-<-respectsˡ resp₁ resp₂ (inj₂ x) (₂∼₂ x∼₂y) = ₂∼₂ (resp₂ x x∼₂y)⊎-<-respects₂ : ∼₁ Respects₂ ≈₁ → ∼₂ Respects₂ ≈₂ →(∼₁ ⊎-< ∼₂) Respects₂ (Pointwise ≈₁ ≈₂)⊎-<-respects₂ (r₁ , l₁) (r₂ , l₂) = ⊎-<-respectsʳ r₁ r₂ , ⊎-<-respectsˡ l₁ l₂⊎-<-trichotomous : Trichotomous ≈₁ ∼₁ → Trichotomous ≈₂ ∼₂ →Trichotomous (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-trichotomous tri₁ tri₂ (inj₁ x) (inj₂ y) = tri< ₁∼₂ (λ()) (λ())⊎-<-trichotomous tri₁ tri₂ (inj₂ x) (inj₁ y) = tri> (λ()) (λ()) ₁∼₂⊎-<-trichotomous tri₁ tri₂ (inj₁ x) (inj₁ y) with tri₁ x y... | tri< x<y x≉y x≯y = tri< (₁∼₁ x<y) (x≉y ∘ PW.drop-inj₁) (x≯y ∘ drop-inj₁)... | tri≈ x≮y x≈y x≯y = tri≈ (x≮y ∘ drop-inj₁) (inj₁ x≈y) (x≯y ∘ drop-inj₁)... | tri> x≮y x≉y x>y = tri> (x≮y ∘ drop-inj₁) (x≉y ∘ PW.drop-inj₁) (₁∼₁ x>y)⊎-<-trichotomous tri₁ tri₂ (inj₂ x) (inj₂ y) with tri₂ x y... | tri< x<y x≉y x≯y = tri< (₂∼₂ x<y) (x≉y ∘ PW.drop-inj₂) (x≯y ∘ drop-inj₂)... | tri≈ x≮y x≈y x≯y = tri≈ (x≮y ∘ drop-inj₂) (inj₂ x≈y) (x≯y ∘ drop-inj₂)... | tri> x≮y x≉y x>y = tri> (x≮y ∘ drop-inj₂) (x≉y ∘ PW.drop-inj₂) (₂∼₂ x>y)-------------------------------------------------------------------------- Some collections of properties which are preservedmodule _ {a₁ a₂} {A₁ : Set a₁} {A₂ : Set a₂}{ℓ₁ ℓ₂} {≈₁ : Rel A₁ ℓ₁} {∼₁ : Rel A₁ ℓ₂}{ℓ₃ ℓ₄} {≈₂ : Rel A₂ ℓ₃} {∼₂ : Rel A₂ ℓ₄} where⊎-<-isPreorder : IsPreorder ≈₁ ∼₁ → IsPreorder ≈₂ ∼₂ →IsPreorder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isPreorder pre₁ pre₂ = record{ isEquivalence = PW.⊎-isEquivalence (isEquivalence pre₁) (isEquivalence pre₂); reflexive = ⊎-<-reflexive (reflexive pre₁) (reflexive pre₂); trans = ⊎-<-transitive (trans pre₁) (trans pre₂)}where open IsPreorder⊎-<-isPartialOrder : IsPartialOrder ≈₁ ∼₁ →IsPartialOrder ≈₂ ∼₂ →IsPartialOrder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isPartialOrder po₁ po₂ = record{ isPreorder = ⊎-<-isPreorder (isPreorder po₁) (isPreorder po₂); antisym = ⊎-<-antisymmetric (antisym po₁) (antisym po₂)}where open IsPartialOrder⊎-<-isStrictPartialOrder : IsStrictPartialOrder ≈₁ ∼₁ →IsStrictPartialOrder ≈₂ ∼₂ →IsStrictPartialOrder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isStrictPartialOrder spo₁ spo₂ = record{ isEquivalence = PW.⊎-isEquivalence (isEquivalence spo₁) (isEquivalence spo₂); irrefl = ⊎-<-irreflexive (irrefl spo₁) (irrefl spo₂); trans = ⊎-<-transitive (trans spo₁) (trans spo₂); <-resp-≈ = ⊎-<-respects₂ (<-resp-≈ spo₁) (<-resp-≈ spo₂)}where open IsStrictPartialOrder⊎-<-isTotalOrder : IsTotalOrder ≈₁ ∼₁ →IsTotalOrder ≈₂ ∼₂ →IsTotalOrder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isTotalOrder to₁ to₂ = record{ isPartialOrder = ⊎-<-isPartialOrder (isPartialOrder to₁) (isPartialOrder to₂); total = ⊎-<-total (total to₁) (total to₂)}where open IsTotalOrder⊎-<-isDecTotalOrder : IsDecTotalOrder ≈₁ ∼₁ →IsDecTotalOrder ≈₂ ∼₂ →IsDecTotalOrder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isDecTotalOrder to₁ to₂ = record{ isTotalOrder = ⊎-<-isTotalOrder (isTotalOrder to₁) (isTotalOrder to₂); _≟_ = PW.⊎-decidable (_≟_ to₁) (_≟_ to₂); _≤?_ = ⊎-<-decidable (_≤?_ to₁) (_≤?_ to₂)}where open IsDecTotalOrder⊎-<-isStrictTotalOrder : IsStrictTotalOrder ≈₁ ∼₁ →IsStrictTotalOrder ≈₂ ∼₂ →IsStrictTotalOrder (Pointwise ≈₁ ≈₂) (∼₁ ⊎-< ∼₂)⊎-<-isStrictTotalOrder sto₁ sto₂ = record{ isStrictPartialOrder = ⊎-<-isStrictPartialOrder (isStrictPartialOrder sto₁) (isStrictPartialOrder sto₂); compare = ⊎-<-trichotomous (compare sto₁) (compare sto₂)}where open IsStrictTotalOrder-------------------------------------------------------------------------- "Bundles" can also be combined.module _ {a b c d e f} where⊎-<-preorder : Preorder a b c →Preorder d e f →Preorder _ _ _⊎-<-preorder p₁ p₂ = record{ isPreorder =⊎-<-isPreorder (isPreorder p₁) (isPreorder p₂)} where open Preorder⊎-<-poset : Poset a b c →Poset a b c →Poset _ _ _⊎-<-poset po₁ po₂ = record{ isPartialOrder =⊎-<-isPartialOrder (isPartialOrder po₁) (isPartialOrder po₂)} where open Poset⊎-<-strictPartialOrder : StrictPartialOrder a b c →StrictPartialOrder d e f →StrictPartialOrder _ _ _⊎-<-strictPartialOrder spo₁ spo₂ = record{ isStrictPartialOrder =⊎-<-isStrictPartialOrder (isStrictPartialOrder spo₁) (isStrictPartialOrder spo₂)} where open StrictPartialOrder⊎-<-totalOrder : TotalOrder a b c →TotalOrder d e f →TotalOrder _ _ _⊎-<-totalOrder to₁ to₂ = record{ isTotalOrder = ⊎-<-isTotalOrder (isTotalOrder to₁) (isTotalOrder to₂)} where open TotalOrder⊎-<-decTotalOrder : DecTotalOrder a b c →DecTotalOrder d e f →DecTotalOrder _ _ _⊎-<-decTotalOrder to₁ to₂ = record{ isDecTotalOrder = ⊎-<-isDecTotalOrder (isDecTotalOrder to₁) (isDecTotalOrder to₂)} where open DecTotalOrder⊎-<-strictTotalOrder : StrictTotalOrder a b c →StrictTotalOrder a b c →StrictTotalOrder _ _ _⊎-<-strictTotalOrder sto₁ sto₂ = record{ isStrictTotalOrder = ⊎-<-isStrictTotalOrder (isStrictTotalOrder sto₁) (isStrictTotalOrder sto₂)} where open StrictTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Properties of sums (disjoint unions)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Properties whereopen import Level using (Level)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; swap; [_,_]; map;map₁; map₂; assocˡ; assocʳ)open import Function.Base using (_∋_; _∘_; id)open import Function.Bundles using (mk↔ₛ′; _↔_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; refl; cong)open import Relation.Nullary.Decidable.Core using (yes; no; map′)privatevariablea b c d e f : LevelA : Set aB : Set bC : Set cD : Set dE : Set eF : Set finj₁-injective : ∀ {x y} → (A ⊎ B ∋ inj₁ x) ≡ inj₁ y → x ≡ yinj₁-injective refl = reflinj₂-injective : ∀ {x y} → (A ⊎ B ∋ inj₂ x) ≡ inj₂ y → x ≡ yinj₂-injective refl = reflmodule _ (dec₁ : DecidableEquality A)(dec₂ : DecidableEquality B) where≡-dec : DecidableEquality (A ⊎ B)≡-dec (inj₁ x) (inj₁ y) = map′ (cong inj₁) inj₁-injective (dec₁ x y)≡-dec (inj₁ x) (inj₂ y) = no λ()≡-dec (inj₂ x) (inj₁ y) = no λ()≡-dec (inj₂ x) (inj₂ y) = map′ (cong inj₂) inj₂-injective (dec₂ x y)swap-involutive : swap {A = A} {B = B} ∘ swap ≗ idswap-involutive = [ (λ _ → refl) , (λ _ → refl) ]swap-↔ : (A ⊎ B) ↔ (B ⊎ A)swap-↔ = mk↔ₛ′ swap swap swap-involutive swap-involutivemap-id : map {A = A} {B = B} id id ≗ idmap-id (inj₁ _) = reflmap-id (inj₂ _) = refl[,]-∘ : (f : A → B){g : C → A} {h : D → A} →f ∘ [ g , h ] ≗ [ f ∘ g , f ∘ h ][,]-∘ _ (inj₁ _) = refl[,]-∘ _ (inj₂ _) = refl[,]-map : {f : A → B} {g : C → D}{f′ : B → E} {g′ : D → E} →[ f′ , g′ ] ∘ map f g ≗ [ f′ ∘ f , g′ ∘ g ][,]-map (inj₁ _) = refl[,]-map (inj₂ _) = reflmap-map : {f : A → B} {g : C → D}{f′ : B → E} {g′ : D → F} →map f′ g′ ∘ map f g ≗ map (f′ ∘ f) (g′ ∘ g)map-map (inj₁ _) = reflmap-map (inj₂ _) = reflmap₁₂-map₂₁ : {f : A → B} {g : C → D} →map₁ f ∘ map₂ g ≗ map₂ g ∘ map₁ fmap₁₂-map₂₁ (inj₁ _) = reflmap₁₂-map₂₁ (inj₂ _) = reflmap-assocˡ : (f : A → C) (g : B → D) (h : C → F) →map (map f g) h ∘ assocˡ ≗ assocˡ ∘ map f (map g h)map-assocˡ _ _ _ (inj₁ x ) = reflmap-assocˡ _ _ _ (inj₂ (inj₁ y)) = reflmap-assocˡ _ _ _ (inj₂ (inj₂ z)) = reflmap-assocʳ : (f : A → C) (g : B → D) (h : C → F) →map f (map g h) ∘ assocʳ ≗ assocʳ ∘ map (map f g) hmap-assocʳ _ _ _ (inj₁ (inj₁ x)) = reflmap-assocʳ _ _ _ (inj₁ (inj₂ y)) = reflmap-assocʳ _ _ _ (inj₂ z ) = refl[,]-cong : {f f′ : A → B} {g g′ : C → B} →f ≗ f′ → g ≗ g′ →[ f , g ] ≗ [ f′ , g′ ][,]-cong = [_,_][-,]-cong : {f f′ : A → B} {g : C → B} →f ≗ f′ →[ f , g ] ≗ [ f′ , g ][-,]-cong = [_, (λ _ → refl) ][,-]-cong : {f : A → B} {g g′ : C → B} →g ≗ g′ →[ f , g ] ≗ [ f , g′ ][,-]-cong = [ (λ _ → refl) ,_]map-cong : {f f′ : A → B} {g g′ : C → D} →f ≗ f′ → g ≗ g′ →map f g ≗ map f′ g′map-cong f≗f′ g≗g′ (inj₁ x) = cong inj₁ (f≗f′ x)map-cong f≗f′ g≗g′ (inj₂ x) = cong inj₂ (g≗g′ x)map₁-cong : {f f′ : A → B} →f ≗ f′ →map₁ {B = C} f ≗ map₁ f′map₁-cong f≗f′ = [-,]-cong ((cong inj₁) ∘ f≗f′)map₂-cong : {g g′ : C → D} →g ≗ g′ →map₂ {A = A} g ≗ map₂ g′map₂-cong g≗g′ = [,-]-cong ((cong inj₂) ∘ g≗g′)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0[,]-∘-distr = [,]-∘{-# WARNING_ON_USAGE [,]-∘-distr"Warning: [,]-∘-distr was deprecated in v2.0.Please use [,]-∘ instead."#-}[,]-map-commute = [,]-map{-# WARNING_ON_USAGE [,]-map-commute"Warning: [,]-map-commute was deprecated in v2.0.Please use [,]-map instead."#-}map-commute = map-map{-# WARNING_ON_USAGE map-commute"Warning: map-commute was deprecated in v2.0.Please use map-map instead."#-}map₁₂-commute = map₁₂-map₂₁{-# WARNING_ON_USAGE map₁₂-commute"Warning: map₁₂-commute was deprecated in v2.0.Please use map₁₂-map₂₁ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for sums------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Instances whereopen import Data.Sum.Baseopen import Data.Sum.Propertiesopen import Levelopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.TypeClassesprivatevariablea b : LevelA : Set aB : Set binstance⊎-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → {{IsDecEquivalence {A = B} _≡_}} → IsDecEquivalence {A = A ⊎ B} _≡_⊎-≡-isDecEquivalence = isDecEquivalence (≡-dec _≟_ _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Sum combinators for setoid equality preserving functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Function.Setoid whereopen import Data.Product.Base as Product using (_,_)open import Data.Sum.Base as Sumopen import Data.Sum.Relation.Binary.Pointwise as Pointwiseopen import Relation.Binaryopen import Function.Baseopen import Function.Bundlesopen import Function.Definitionsopen import Levelprivatevariablea₁ a₂ b₁ b₂ c₁ c₂ d₁ d₂ : Levela ℓ : LevelA B C D : Set a≈₁ ≈₂ ≈₃ ≈₄ : Rel A ℓS T U V : Setoid a ℓ-------------------------------------------------------------------------- Combinators for equality preserving functionsinj₁ₛ : Func S (S ⊎ₛ T)inj₁ₛ = record { to = inj₁ ; cong = inj₁ }inj₂ₛ : Func T (S ⊎ₛ T)inj₂ₛ = record { to = inj₂ ; cong = inj₂ }[_,_]ₛ : Func S U → Func T U → Func (S ⊎ₛ T) U[ f , g ]ₛ = record{ to = [ to f , to g ]; cong = λ where(inj₁ x∼₁y) → cong f x∼₁y(inj₂ x∼₂y) → cong g x∼₂y} where open Funcswapₛ : Func (S ⊎ₛ T) (T ⊎ₛ S)swapₛ = [ inj₂ₛ , inj₁ₛ ]ₛ-------------------------------------------------------------------------- Definitions⊎-injective : ∀ {f g} →Injective ≈₁ ≈₂ f →Injective ≈₃ ≈₄ g →Injective (Pointwise ≈₁ ≈₃) (Pointwise ≈₂ ≈₄) (Sum.map f g)⊎-injective f-inj g-inj {inj₁ x} {inj₁ y} (inj₁ x∼₁y) = inj₁ (f-inj x∼₁y)⊎-injective f-inj g-inj {inj₂ x} {inj₂ y} (inj₂ x∼₂y) = inj₂ (g-inj x∼₂y)⊎-strictlySurjective : ∀ {f : A → B} {g : C → D} →StrictlySurjective ≈₁ f →StrictlySurjective ≈₂ g →StrictlySurjective (Pointwise ≈₁ ≈₂) (Sum.map f g)⊎-strictlySurjective f-sur g-sur =[ Product.map inj₁ inj₁ ∘ f-sur, Product.map inj₂ inj₂ ∘ g-sur]⊎-surjective : ∀ {f : A → B} {g : C → D} →Surjective ≈₁ ≈₂ f →Surjective ≈₃ ≈₄ g →Surjective (Pointwise ≈₁ ≈₃) (Pointwise ≈₂ ≈₄) (Sum.map f g)⊎-surjective f-sur g-sur =[ Product.map inj₁ (λ { fwd (inj₁ x) → inj₁ (fwd x)}) ∘ f-sur, Product.map inj₂ (λ { fwd (inj₂ y) → inj₂ (fwd y)}) ∘ g-sur]infixr 1 _⊎-equivalence_ _⊎-injection_ _⊎-left-inverse_-------------------------------------------------------------------------- Function bundles_⊎-function_ : Func S T → Func U V → Func (S ⊎ₛ U) (T ⊎ₛ V)S→T ⊎-function U→V = record{ to = Sum.map (to S→T) (to U→V); cong = Pointwise.map (cong S→T) (cong U→V)} where open Func_⊎-equivalence_ : Equivalence S T → Equivalence U V →Equivalence (S ⊎ₛ U) (T ⊎ₛ V)S⇔T ⊎-equivalence U⇔V = record{ to = Sum.map (to S⇔T) (to U⇔V); from = Sum.map (from S⇔T) (from U⇔V); to-cong = Pointwise.map (to-cong S⇔T) (to-cong U⇔V); from-cong = Pointwise.map (from-cong S⇔T) (from-cong U⇔V)} where open Equivalence_⊎-injection_ : Injection S T → Injection U V →Injection (S ⊎ₛ U) (T ⊎ₛ V)S↣T ⊎-injection U↣V = record{ to = Sum.map (to S↣T) (to U↣V); cong = Pointwise.map (cong S↣T) (cong U↣V); injective = ⊎-injective (injective S↣T) (injective U↣V)} where open Injectioninfixr 1 _⊎-surjection_ _⊎-inverse__⊎-surjection_ : Surjection S T → Surjection U V →Surjection (S ⊎ₛ U) (T ⊎ₛ V)S↠T ⊎-surjection U↠V = record{ to = Sum.map (to S↠T) (to U↠V); cong = Pointwise.map (cong S↠T) (cong U↠V); surjective = ⊎-surjective (surjective S↠T) (surjective U↠V)} where open Surjection_⊎-bijection_ : Bijection S T → Bijection U V →Bijection (S ⊎ₛ U) (T ⊎ₛ V)S⤖T ⊎-bijection U⤖V = record{ to = Sum.map (to S⤖T) (to U⤖V); cong = Pointwise.map (cong S⤖T) (cong U⤖V); bijective = ⊎-injective (injective S⤖T) (injective U⤖V) ,⊎-surjective (surjective S⤖T) (surjective U⤖V)} where open Bijection_⊎-leftInverse_ : LeftInverse S T → LeftInverse U V →LeftInverse (S ⊎ₛ U) (T ⊎ₛ V)S↩T ⊎-leftInverse U↩V = record{ to = Sum.map (to S↩T) (to U↩V); from = Sum.map (from S↩T) (from U↩V); to-cong = Pointwise.map (to-cong S↩T) (to-cong U↩V); from-cong = Pointwise.map (from-cong S↩T) (from-cong U↩V); inverseˡ = λ { {inj₁ _} {.(inj₁ _)} (inj₁ x) → inj₁ (inverseˡ S↩T x); {inj₂ _} {.(inj₂ _)} (inj₂ x) → inj₂ (inverseˡ U↩V x)}} where open LeftInverse_⊎-rightInverse_ : RightInverse S T → RightInverse U V →RightInverse (S ⊎ₛ U) (T ⊎ₛ V)S↪T ⊎-rightInverse U↪V = record{ to = Sum.map (to S↪T) (to U↪V); from = Sum.map (from S↪T) (from U↪V); to-cong = Pointwise.map (to-cong S↪T) (to-cong U↪V); from-cong = Pointwise.map (from-cong S↪T) (from-cong U↪V); inverseʳ = λ { {inj₁ _} (inj₁ x) → inj₁ (inverseʳ S↪T x); {inj₂ _} (inj₂ x) → inj₂ (inverseʳ U↪V x)}} where open RightInverse_⊎-inverse_ : Inverse S T → Inverse U V →Inverse (S ⊎ₛ U) (T ⊎ₛ V)S↔T ⊎-inverse U↔V = record{ to = Sum.map (to S↔T) (to U↔V); from = Sum.map (from S↔T) (from U↔V); to-cong = Pointwise.map (to-cong S↔T) (to-cong U↔V); from-cong = Pointwise.map (from-cong S↔T) (from-cong U↔V); inverse = (λ { {inj₁ _} (inj₁ x) → inj₁ (inverseˡ S↔T x); {inj₂ _} (inj₂ x) → inj₂ (inverseˡ U↔V x)}) ,λ { {inj₁ _} (inj₁ x) → inj₁ (inverseʳ S↔T x); {inj₂ _} (inj₂ x) → inj₂ (inverseʳ U↔V x)}} where open Inverse-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0_⊎-left-inverse_ = _⊎-leftInverse_{-# WARNING_ON_USAGE _⊎-left-inverse_"Warning: _⊎-left-inverse_ was deprecated in v2.0.Please use _⊎-leftInverse_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Sum combinators for propositional equality preserving functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Function.Propositional whereopen import Data.Sum.Base using (_⊎_)open import Data.Sum.Function.Setoidopen import Data.Sum.Relation.Binary.Pointwise using (Pointwise-≡↔≡; _⊎ₛ_)open import Function.Construct.Composition as Composeopen import Function.Related.Propositionalusing (_∼[_]_; implication; reverseImplication; equivalence; injection;reverseInjection; leftInverse; surjection; bijection)open import Function.Base using (id)open import Function.Bundlesusing (Inverse; _⟶_; _⇔_; _↣_; _↠_; _↩_; _↪_; _⤖_; _↔_)open import Function.Properties.Inverse as Invopen import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Properties using (setoid)privatevariablea b c d : LevelA B C D : Set a-------------------------------------------------------------------------- Helper lemmaprivateliftViaInverse : {R : ∀ {a b ℓ₁ ℓ₂} → REL (Setoid a ℓ₁) (Setoid b ℓ₂) (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)} →(∀ {a b c ℓ₁ ℓ₂ ℓ₃} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} {U : Setoid c ℓ₃} → R S T → R T U → R S U) →(∀ {a b ℓ₁ ℓ₂} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} → Inverse S T → R S T) →(R (setoid A) (setoid C) → R (setoid B) (setoid D) → R (setoid A ⊎ₛ setoid B) (setoid C ⊎ₛ setoid D)) →R (setoid A) (setoid C) → R (setoid B) (setoid D) →R (setoid (A ⊎ B)) (setoid (C ⊎ D))liftViaInverse trans inv⇒R lift RAC RBD =Inv.transportVia trans inv⇒R (Inv.sym (Pointwise-≡↔≡ _ _)) (lift RAC RBD) (Pointwise-≡↔≡ _ _)-------------------------------------------------------------------------- Combinators for various function typesinfixr 1 _⊎-⟶_ _⊎-⇔_ _⊎-↣_ _⊎-↩_ _⊎-↪_ _⊎-↔__⊎-⟶_ : A ⟶ B → C ⟶ D → (A ⊎ C) ⟶ (B ⊎ D)_⊎-⟶_ = liftViaInverse Compose.function Inv.toFunction _⊎-function__⊎-⇔_ : A ⇔ B → C ⇔ D → (A ⊎ C) ⇔ (B ⊎ D)_⊎-⇔_ = liftViaInverse Compose.equivalence Inverse⇒Equivalence _⊎-equivalence__⊎-↣_ : A ↣ B → C ↣ D → (A ⊎ C) ↣ (B ⊎ D)_⊎-↣_ = liftViaInverse Compose.injection Inverse⇒Injection _⊎-injection__⊎-↠_ : A ↠ B → C ↠ D → (A ⊎ C) ↠ (B ⊎ D)_⊎-↠_ = liftViaInverse Compose.surjection Inverse⇒Surjection _⊎-surjection__⊎-↩_ : A ↩ B → C ↩ D → (A ⊎ C) ↩ (B ⊎ D)_⊎-↩_ = liftViaInverse Compose.leftInverse Inverse.leftInverse _⊎-leftInverse__⊎-↪_ : A ↪ B → C ↪ D → (A ⊎ C) ↪ (B ⊎ D)_⊎-↪_ = liftViaInverse Compose.rightInverse Inverse.rightInverse _⊎-rightInverse__⊎-⤖_ : A ⤖ B → C ⤖ D → (A ⊎ C) ⤖ (B ⊎ D)_⊎-⤖_ = liftViaInverse Compose.bijection Inverse⇒Bijection _⊎-bijection__⊎-↔_ : A ↔ B → C ↔ D → (A ⊎ C) ↔ (B ⊎ D)_⊎-↔_ = liftViaInverse Compose.inverse id _⊎-inverse_infixr 1 _⊎-cong__⊎-cong_ : ∀ {k} → A ∼[ k ] B → C ∼[ k ] D → (A ⊎ C) ∼[ k ] (B ⊎ D)_⊎-cong_ {k = implication} = _⊎-⟶__⊎-cong_ {k = reverseImplication} = _⊎-⟶__⊎-cong_ {k = equivalence} = _⊎-⇔__⊎-cong_ {k = injection} = _⊎-↣__⊎-cong_ {k = reverseInjection} = _⊎-↣__⊎-cong_ {k = leftInverse} = _⊎-↪__⊎-cong_ {k = surjection} = _⊎-↠__⊎-cong_ {k = bijection} = _⊎-↔_
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the Sum type (Right-biased)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Sum.Effectful.Right (a : Level) {b} (B : Set b) whereopen import Algebra.Bundles using (RawMonoid)open import Data.Sum.Baseopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.BaseSumᵣ : Set (a ⊔ b) → Set (a ⊔ b)Sumᵣ A = A ⊎ Bfunctor : RawFunctor Sumᵣfunctor = record { _<$>_ = map₁ }empty : B → RawEmpty Sumᵣempty b = record { empty = inj₂ b }choice : RawChoice Sumᵣchoice = record { _<|>_ = [ const ∘′ inj₁ , flip const ]′ }applicative : RawApplicative Sumᵣapplicative = record{ rawFunctor = functor; pure = inj₁; _<*>_ = [ map₁ , const ∘ inj₂ ]′}applicativeZero : B → RawApplicativeZero SumᵣapplicativeZero b = record{ rawApplicative = applicative; rawEmpty = empty b}alternative : B → RawAlternative Sumᵣalternative b = record{ rawApplicativeZero = applicativeZero b; rawChoice = choice}monad : RawMonad Sumᵣmonad = record{ rawApplicative = applicative; _>>=_ = [ _|>′_ , const ∘′ inj₂ ]′}join : {A : Set (a ⊔ b)} → Sumᵣ (Sumᵣ A) → Sumᵣ Ajoin = Join.join monadmonadZero : B → RawMonadZero SumᵣmonadZero b = record{ rawMonad = monad; rawEmpty = empty b}monadPlus : B → RawMonadPlus SumᵣmonadPlus b = record{ rawMonadZero = monadZero b; rawChoice = choice}-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Sumᵣ (F A) → F (Sumᵣ A)sequenceA (inj₂ a) = pure (inj₂ a)sequenceA (inj₁ x) = inj₁ <$> xmapA : ∀ {A B} → (A → F B) → Sumᵣ A → F (Sumᵣ B)mapA f = sequenceA ∘ map₁ fforA : ∀ {A B} → Sumᵣ A → (A → F B) → F (Sumᵣ B)forA = flip mapAmodule TraversableM {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the Sum type (Right-biased)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Sum.Effectful.Right.Transformer (a : Level) {b} (B : Set b) whereopen import Data.Sum.Baseopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.BaseprivatevariableM : Set (a ⊔ b) → Set (a ⊔ b)-- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the examples for how this is done.open import Data.Sum.Effectful.Right a B using (Sumᵣ)-------------------------------------------------------------------------- Right-biased monad transformer instance for _⊎_record SumᵣT(M : Set (a ⊔ b) → Set (a ⊔ b))(B : Set (a ⊔ b)) : Set (a ⊔ b) whereconstructor mkSumᵣTfield runSumᵣT : M (Sumᵣ B)open SumᵣT public-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor (SumᵣT M)functor M = record{ _<$>_ = λ f → mkSumᵣT ∘′ (map₁ f <$>_) ∘′ runSumᵣT} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative (SumᵣT M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkSumᵣT ∘′ pure ∘′ inj₁; _<*>_ = λ mf mx → mkSumᵣT ([ map₁ , const ∘′ inj₂ ]′ <$> runSumᵣT mf <*> runSumᵣT mx)} where open RawApplicative Mempty : RawApplicative M → B → RawEmpty (SumᵣT M)empty M a = record{ empty = mkSumᵣT (pure (inj₂ a))} where open RawApplicative Mchoice : RawApplicative M → RawChoice (SumᵣT M)choice M = record{ _<|>_ = λ ma₁ ma₁ → mkSumᵣT ([ const ∘ inj₁ , flip const ]′ <$> runSumᵣT ma₁ <*> runSumᵣT ma₁)} where open RawApplicative MapplicativeZero : RawApplicative M → B → RawApplicativeZero (SumᵣT M)applicativeZero M a = record{ rawApplicative = applicative M; rawEmpty = empty M a}alternative : RawApplicative M → B → RawAlternative (SumᵣT M)alternative M a = record{ rawApplicativeZero = applicativeZero M a; rawChoice = choice M}monad : RawMonad M → RawMonad (SumᵣT M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma f → mkSumᵣT $ doa ← runSumᵣT ma[ runSumᵣT ∘′ f , pure ∘′ inj₂ ]′ a} where open RawMonad MmonadT : RawMonadT SumᵣTmonadT M = record{ lift = mkSumᵣT ∘′ (inj₁ <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the Sum type (Left-biased)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Sum.Effectful.Left {a} (A : Set a) (b : Level) whereopen import Data.Sum.Baseopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Base-- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the examples for how this is done.-------------------------------------------------------------------------- Left-biased monad instance for _⊎_Sumₗ : Set (a ⊔ b) → Set (a ⊔ b)Sumₗ B = A ⊎ Bfunctor : RawFunctor Sumₗfunctor = record { _<$>_ = map₂ }applicative : RawApplicative Sumₗapplicative = record{ rawFunctor = functor; pure = inj₂; _<*>_ = [ const ∘ inj₁ , map₂ ]′}empty : A → RawEmpty Sumₗempty a = record { empty = inj₁ a }choice : RawChoice Sumₗchoice = record { _<|>_ = [ flip const , const ∘ inj₂ ]′ }applicativeZero : A → RawApplicativeZero SumₗapplicativeZero a = record{ rawApplicative = applicative; rawEmpty = empty a}alternative : A → RawAlternative Sumₗalternative a = record{ rawApplicativeZero = applicativeZero a; rawChoice = choice}monad : RawMonad Sumₗmonad = record{ rawApplicative = applicative; _>>=_ = [ const ∘′ inj₁ , _|>′_ ]′}join : {B : Set (a ⊔ b)} → Sumₗ (Sumₗ B) → Sumₗ Bjoin = Join.join monad-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Sumₗ (F A) → F (Sumₗ A)sequenceA (inj₁ a) = pure (inj₁ a)sequenceA (inj₂ x) = inj₂ <$> xmapA : ∀ {A B} → (A → F B) → Sumₗ A → F (Sumₗ B)mapA f = sequenceA ∘ map₂ fforA : ∀ {A B} → Sumₗ A → (A → F B) → F (Sumₗ B)forA = flip mapAmodule TraversableM {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of the Sum type (Left-biased)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Sum.Effectful.Left.Transformer {a} (A : Set a) (b : Level) whereopen import Data.Sum.Baseopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.BaseprivatevariableM : Set (a ⊔ b) → Set (a ⊔ b)-- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the examples for how this is done.open import Data.Sum.Effectful.Left A b using (Sumₗ)-------------------------------------------------------------------------- Left-biased monad transformer instance for _⊎_record SumₗT(M : Set (a ⊔ b) → Set (a ⊔ b))(B : Set (a ⊔ b)) : Set (a ⊔ b) whereconstructor mkSumₗTfield runSumₗT : M (Sumₗ B)open SumₗT public-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor (SumₗT M)functor M = record{ _<$>_ = λ f → mkSumₗT ∘′ (map₂ f <$>_) ∘′ runSumₗT} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative (SumₗT M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkSumₗT ∘′ pure ∘′ inj₂; _<*>_ = λ mf mx → mkSumₗT ([ const ∘′ inj₁ , map₂ ]′ <$> runSumₗT mf <*> runSumₗT mx)} where open RawApplicative Mempty : RawApplicative M → A → RawEmpty (SumₗT M)empty M a = record{ empty = mkSumₗT (pure (inj₁ a))} where open RawApplicative Mchoice : RawApplicative M → RawChoice (SumₗT M)choice M = record{ _<|>_ = λ ma₁ ma₂ → mkSumₗT ([ flip const , const ∘ inj₂ ]′ <$> runSumₗT ma₁ <*> runSumₗT ma₂)} where open RawApplicative MapplicativeZero : RawApplicative M → A → RawApplicativeZero (SumₗT M)applicativeZero M a = record{ rawApplicative = applicative M; rawEmpty = empty M a}alternative : RawApplicative M → A → RawAlternative (SumₗT M)alternative M a = record{ rawApplicativeZero = applicativeZero M a; rawChoice = choice M}monad : RawMonad M → RawMonad (SumₗT M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma f → mkSumₗT $ doa ← runSumₗT ma[ pure ∘′ inj₁ , runSumₗT ∘′ f ]′ a} where open RawMonad MmonadT : RawMonadT SumₗTmonadT M = record{ lift = mkSumₗT ∘′ (inj₂ <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- Usage examples of the effectful view of the Sum type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Effectful.Examples whereopen import Levelopen import Data.Sum.Baseimport Data.Sum.Effectful.Left as Sumₗopen import Effect.Functoropen import Effect.Monad-- Note that these examples are simple unit tests, because the type-- checker verifies them.privatemodule Examplesₗ {a b} {A : Set a} {B : Set b} whereopen import Agda.Builtin.Equalityopen import Function.Base using (id)module Sₗ = Sumₗ A bopen RawFunctor Sₗ.functor-- This type to the right of ⊎ needs to be a "lifted" version of-- (B : Set b) that lives in the universe (Set (a ⊔ b)).fmapId : (x : A ⊎ (Lift a B)) → (id <$> x) ≡ xfmapId (inj₁ x) = reflfmapId (inj₂ y) = reflopen RawMonad Sₗ.monad-- Now, let's show that "pure" is a unit for >>=. We use Lift in-- exactly the same way as above. The data (x : B) then needs to be-- "lifted" to this new type (Lift B).pureUnitL : ∀ {x : B} {f : Lift a B → A ⊎ (Lift a B)}→ (pure (lift x) >>= f) ≡ f (lift x)pureUnitL = reflpureUnitR : (x : A ⊎ (Lift a B)) → (x >>= pure) ≡ xpureUnitR (inj₁ _) = reflpureUnitR (inj₂ _) = refl-- And another (limited version of a) monad law...bindCompose : ∀ {f g : Lift a B → A ⊎ (Lift a B)}→ (x : A ⊎ (Lift a B))→ ((x >>= f) >>= g) ≡ (x >>= (λ y → (f y >>= g)))bindCompose (inj₁ x) = reflbindCompose (inj₂ y) = refl
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Sum.Categorical.Right` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Categorical.Right whereopen import Data.Sum.Effectful.Right public{-# WARNING_ON_IMPORT"Data.Sum.Categorical.Right was deprecated in v2.0.Use Data.Sum.Effectful.Right instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Sum.Categorical.Right.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Categorical.Right.Transformer whereopen import Data.Sum.Effectful.Right.Transformer public{-# WARNING_ON_IMPORT"Data.Sum.Categorical.Right.Transformer was deprecated in v2.0.Use Data.Sum.Effectful.Right.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Sum.Categorical.Left` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Categorical.Left whereopen import Data.Sum.Effectful.Left public{-# WARNING_ON_IMPORT"Data.Sum.Categorical.Left was deprecated in v2.0.Use Data.Sum.Effectful.Left instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Sum.Categorical.Left.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Categorical.Left.Transformer whereopen import Data.Sum.Effectful.Left.Transformer public{-# WARNING_ON_IMPORT"Data.Sum.Categorical.Left.Transformer was deprecated in v2.0.Use Data.Sum.Effectful.Left.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Sum.Categorical.Examples` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Categorical.Examples whereopen import Data.Sum.Effectful.Examples public{-# WARNING_ON_IMPORT"Data.Sum.Categorical.Examples was deprecated in v2.0.Use Data.Sum.Effectful.Examples instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Sums (disjoint unions)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Base whereopen import Data.Bool.Base using (true; false)open import Function.Base using (_∘_; _∘′_; _-⟪_⟫-_ ; id)open import Level using (Level; _⊔_)privatevariablea b c d : LevelA : Set aB : Set bC : Set cD : Set d-------------------------------------------------------------------------- Definitioninfixr 1 _⊎_data _⊎_ (A : Set a) (B : Set b) : Set (a ⊔ b) whereinj₁ : (x : A) → A ⊎ Binj₂ : (y : B) → A ⊎ B-------------------------------------------------------------------------- Functions[_,_] : ∀ {C : A ⊎ B → Set c} →((x : A) → C (inj₁ x)) → ((x : B) → C (inj₂ x)) →((x : A ⊎ B) → C x)[ f , g ] (inj₁ x) = f x[ f , g ] (inj₂ y) = g y[_,_]′ : (A → C) → (B → C) → (A ⊎ B → C)[_,_]′ = [_,_]fromInj₁ : (B → A) → A ⊎ B → AfromInj₁ = [ id ,_]′fromInj₂ : (A → B) → A ⊎ B → BfromInj₂ = [_, id ]′reduce : A ⊎ A → Areduce = [ id , id ]′swap : A ⊎ B → B ⊎ Aswap (inj₁ x) = inj₂ xswap (inj₂ x) = inj₁ xmap : (A → C) → (B → D) → (A ⊎ B → C ⊎ D)map f g = [ inj₁ ∘ f , inj₂ ∘ g ]′map₁ : (A → C) → (A ⊎ B → C ⊎ B)map₁ f = map f idmap₂ : (B → D) → (A ⊎ B → A ⊎ D)map₂ = map idassocʳ : (A ⊎ B) ⊎ C → A ⊎ B ⊎ Cassocʳ = [ map₂ inj₁ , inj₂ ∘′ inj₂ ]′assocˡ : A ⊎ B ⊎ C → (A ⊎ B) ⊎ Cassocˡ = [ inj₁ ∘′ inj₁ , map₁ inj₂ ]′infixr 1 _-⊎-__-⊎-_ : (A → B → Set c) → (A → B → Set d) → (A → B → Set (c ⊔ d))f -⊎- g = f -⟪ _⊎_ ⟫- g
-------------------------------------------------------------------------- The Agda standard library---- Algebraic properties of sums (disjoint unions)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sum.Algebra whereopen import Algebra.Bundlesusing (Magma; Semigroup; Monoid; CommutativeMonoid)open import Algebra.Definitionsopen import Algebra.Structuresusing (IsMagma; IsSemigroup; IsMonoid; IsCommutativeMonoid)open import Data.Empty.Polymorphic using (⊥)open import Data.Product.Base using (_,_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; map; [_,_]; swap; assocʳ; assocˡ)open import Data.Sum.Properties using (swap-involutive)open import Data.Unit.Polymorphic.Base using (⊤; tt)open import Function.Base using (id; _∘_)open import Function.Properties.Inverse using (↔-isEquivalence)open import Function.Bundles using (_↔_; Inverse; mk↔ₛ′)open import Level using (Level; suc)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong′)import Function.Definitions as FuncDef-------------------------------------------------------------------------- Setupprivatevariablea b c d : LevelA B C D : Set a♯ : {B : ⊥ {a} → Set b} → (w : ⊥) → B w♯ ()-------------------------------------------------------------------------- Algebraic properties⊎-cong : A ↔ B → C ↔ D → (A ⊎ C) ↔ (B ⊎ D)⊎-cong i j = mk↔ₛ′ (map I.to J.to) (map I.from J.from)[ cong inj₁ ∘ I.strictlyInverseˡ , cong inj₂ ∘ J.strictlyInverseˡ ][ cong inj₁ ∘ I.strictlyInverseʳ , cong inj₂ ∘ J.strictlyInverseʳ ]where module I = Inverse i; module J = Inverse j-- ⊎ is commutative.-- We don't use Commutative because it isn't polymorphic enough.⊎-comm : (A : Set a) (B : Set b) → (A ⊎ B) ↔ (B ⊎ A)⊎-comm _ _ = mk↔ₛ′ swap swap swap-involutive swap-involutivemodule _ (ℓ : Level) where-- ⊎ is associative⊎-assoc : Associative {ℓ = ℓ} _↔_ _⊎_⊎-assoc _ _ _ = mk↔ₛ′ assocʳ assocˡ[ cong′ , [ cong′ , cong′ ] ] [ [ cong′ , cong′ ] , cong′ ]-- ⊥ is an identity for ⊎⊎-identityˡ : LeftIdentity {ℓ = ℓ} _↔_ ⊥ _⊎_⊎-identityˡ A = mk↔ₛ′ [ ♯ , id ] inj₂ cong′ [ ♯ , cong′ ]⊎-identityʳ : RightIdentity {ℓ = ℓ} _↔_ ⊥ _⊎_⊎-identityʳ _ = mk↔ₛ′ [ id , ♯ ] inj₁ cong′ [ cong′ , ♯ ]⊎-identity : Identity _↔_ ⊥ _⊎_⊎-identity = ⊎-identityˡ , ⊎-identityʳ-------------------------------------------------------------------------- Algebraic structures⊎-isMagma : IsMagma {ℓ = ℓ} _↔_ _⊎_⊎-isMagma = record{ isEquivalence = ↔-isEquivalence; ∙-cong = ⊎-cong}⊎-isSemigroup : IsSemigroup _↔_ _⊎_⊎-isSemigroup = record{ isMagma = ⊎-isMagma; assoc = ⊎-assoc}⊎-isMonoid : IsMonoid _↔_ _⊎_ ⊥⊎-isMonoid = record{ isSemigroup = ⊎-isSemigroup; identity = ⊎-identityˡ , ⊎-identityʳ}⊎-isCommutativeMonoid : IsCommutativeMonoid _↔_ _⊎_ ⊥⊎-isCommutativeMonoid = record{ isMonoid = ⊎-isMonoid; comm = ⊎-comm}-------------------------------------------------------------------------- Algebraic bundles⊎-magma : Magma (suc ℓ) ℓ⊎-magma = record{ isMagma = ⊎-isMagma}⊎-semigroup : Semigroup (suc ℓ) ℓ⊎-semigroup = record{ isSemigroup = ⊎-isSemigroup}⊎-monoid : Monoid (suc ℓ) ℓ⊎-monoid = record{ isMonoid = ⊎-isMonoid}⊎-commutativeMonoid : CommutativeMonoid (suc ℓ) ℓ⊎-commutativeMonoid = record{ isCommutativeMonoid = ⊎-isCommutativeMonoid}
-------------------------------------------------------------------------- The Agda standard library---- Strings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.String whereopen import Data.Bool.Base using (if_then_else_)open import Data.Char.Base as Char using (Char)open import Function.Base using (_∘_; _$_)open import Data.Nat.Base as ℕ using (ℕ)import Data.Nat.Properties as ℕopen import Data.List.Base as List using (List)open import Data.List.Extrema ℕ.≤-totalOrderopen import Data.Vec.Base as Vec using (Vec)open import Data.Char.Base as Char using (Char)import Data.Char.Properties as Char using (_≟_)open import Relation.Nullary.Decidable.Core using (does)open import Data.List.Membership.DecPropositional Char._≟_-------------------------------------------------------------------------- Re-export contents of base, and decidability of equalityopen import Data.String.Base publicopen import Data.String.Properties using (_≈?_; _≟_; _<?_; _==_) public-------------------------------------------------------------------------- Conversion functionstoVec : (s : String) → Vec Char (length s)toVec s = Vec.fromList (toList s)fromVec : ∀ {n} → Vec Char n → StringfromVec = fromList ∘ Vec.toList-- enclose string with parens if it contains a space characterparensIfSpace : String → StringparensIfSpace s = if does (' ' ∈? toList s) then parens s else s-------------------------------------------------------------------------- Rectangle-- Build a rectangular column by:-- Given a vector of cells and a padding function for each one-- Compute the max of the widths, and pad the strings accordingly.rectangle : ∀ {n} → Vec (ℕ → String → String) n →Vec String n → Vec String nrectangle pads cells = Vec.zipWith (λ p c → p width c) pads cells wheresizes = List.map length (Vec.toList cells)width = max 0 sizes-- Special cases for left, center, and right alignmentrectangleˡ : ∀ {n} → Char → Vec String n → Vec String nrectangleˡ c = rectangle (Vec.replicate _ $ padLeft c)rectangleʳ : ∀ {n} → Char → Vec String n → Vec String nrectangleʳ c = rectangle (Vec.replicate _ $ padRight c)rectangleᶜ : ∀ {n} → Char → Char → Vec String n → Vec String nrectangleᶜ cₗ cᵣ = rectangle (Vec.replicate _ $ padBoth cₗ cᵣ)
-------------------------------------------------------------------------- The Agda standard library---- Unsafe String operations and proofs------------------------------------------------------------------------{-# OPTIONS --with-K #-}module Data.String.Unsafe whereimport Data.List.Base as Listimport Data.List.Properties as Listₚopen import Data.Maybe.Base using (maybe′)open import Data.Nat.Base using (zero; suc; _+_)open import Data.Product.Base using (proj₂)open import Data.String.Baseopen import Function.Base using (_∘′_)open import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Binary.PropositionalEquality.TrustMe using (trustMe)open ≡-Reasoning-------------------------------------------------------------------------- Properties of taillength-tail : ∀ s → length s ≡ maybe′ (suc ∘′ length) zero (tail s)length-tail s = trustMe-------------------------------------------------------------------------- Properties of conversion functionstoList∘fromList : ∀ s → toList (fromList s) ≡ stoList∘fromList s = trustMefromList∘toList : ∀ s → fromList (toList s) ≡ sfromList∘toList s = trustMetoList-++ : ∀ s t → toList (s ++ t) ≡ toList s List.++ toList ttoList-++ s t = trustMelength-++ : ∀ s t → length (s ++ t) ≡ length s + length tlength-++ s t = beginlength (s ++ t) ≡⟨⟩List.length (toList (s ++ t)) ≡⟨ cong List.length (toList-++ s t) ⟩List.length (toList s List.++ toList t) ≡⟨ Listₚ.length-++ (toList s) ⟩length s + length t ∎length-replicate : ∀ n {c} → length (replicate n c) ≡ nlength-replicate n {c} = let cs = List.replicate n c in beginlength (replicate n c) ≡⟨ cong List.length (toList∘fromList cs) ⟩List.length cs ≡⟨ Listₚ.length-replicate n ⟩n ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on strings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.String.Properties whereopen import Data.Bool.Base using (Bool)import Data.Char.Properties as Charimport Data.List.Properties as Listimport Data.List.Relation.Binary.Pointwise as Pointwiseimport Data.List.Relation.Binary.Lex.Strict as StrictLexopen import Data.String.Baseopen import Function.Baseopen import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Decidable using (map′; isYes)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; StrictPartialOrder; StrictTotalOrder; DecTotalOrder; DecPoset)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsStrictPartialOrder; IsStrictTotalOrder; IsDecPartialOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Substitutive; Decidable; DecidableEquality)open import Relation.Binary.PropositionalEquality.Coreimport Relation.Binary.Construct.On as Onimport Relation.Binary.PropositionalEquality.Properties as PropEq-------------------------------------------------------------------------- Primitive propertiesopen import Agda.Builtin.String.Properties publicrenaming ( primStringToListInjective to toList-injective)-------------------------------------------------------------------------- Properties of _≈_≈⇒≡ : _≈_ ⇒ _≡_≈⇒≡ = toList-injective _ _∘ Pointwise.Pointwise-≡⇒≡≈-reflexive : _≡_ ⇒ _≈_≈-reflexive = Pointwise.≡⇒Pointwise-≡∘ cong toList≈-refl : Reflexive _≈_≈-refl {x} = ≈-reflexive {x} {x} refl≈-sym : Symmetric _≈_≈-sym = Pointwise.symmetric sym≈-trans : Transitive _≈_≈-trans = Pointwise.transitive trans≈-subst : ∀ {ℓ} → Substitutive _≈_ ℓ≈-subst P x≈y p = subst P (≈⇒≡ x≈y) pinfix 4 _≈?__≈?_ : Decidable _≈_x ≈? y = Pointwise.decidable Char._≟_ (toList x) (toList y)≈-isEquivalence : IsEquivalence _≈_≈-isEquivalence = record{ refl = λ {i} → ≈-refl {i}; sym = λ {i j} → ≈-sym {i} {j}; trans = λ {i j k} → ≈-trans {i} {j} {k}}≈-setoid : Setoid _ _≈-setoid = record{ isEquivalence = ≈-isEquivalence}≈-isDecEquivalence : IsDecEquivalence _≈_≈-isDecEquivalence = record{ isEquivalence = ≈-isEquivalence; _≟_ = _≈?_}≈-decSetoid : DecSetoid _ _≈-decSetoid = record{ isDecEquivalence = ≈-isDecEquivalence}-------------------------------------------------------------------------- Properties of _≡_infix 4 _≟__≟_ : DecidableEquality Stringx ≟ y = map′ ≈⇒≡ ≈-reflexive $ x ≈? y≡-setoid : Setoid _ _≡-setoid = PropEq.setoid String≡-decSetoid : DecSetoid _ _≡-decSetoid = PropEq.decSetoid _≟_-------------------------------------------------------------------------- Properties of _<_infix 4 _<?__<?_ : Decidable _<_x <? y = StrictLex.<-decidable Char._≟_ Char._<?_ (toList x) (toList y)<-isStrictPartialOrder-≈ : IsStrictPartialOrder _≈_ _<_<-isStrictPartialOrder-≈ =On.isStrictPartialOrdertoList(StrictLex.<-isStrictPartialOrder Char.<-isStrictPartialOrder)<-isStrictTotalOrder-≈ : IsStrictTotalOrder _≈_ _<_<-isStrictTotalOrder-≈ =On.isStrictTotalOrdertoList(StrictLex.<-isStrictTotalOrder Char.<-isStrictTotalOrder)<-strictPartialOrder-≈ : StrictPartialOrder _ _ _<-strictPartialOrder-≈ =On.strictPartialOrder(StrictLex.<-strictPartialOrder Char.<-strictPartialOrder)toList<-strictTotalOrder-≈ : StrictTotalOrder _ _ _<-strictTotalOrder-≈ =On.strictTotalOrder(StrictLex.<-strictTotalOrder Char.<-strictTotalOrder)toList≤-isDecPartialOrder-≈ : IsDecPartialOrder _≈_ _≤_≤-isDecPartialOrder-≈ =On.isDecPartialOrdertoList(StrictLex.≤-isDecPartialOrder Char.<-isStrictTotalOrder)≤-isDecTotalOrder-≈ : IsDecTotalOrder _≈_ _≤_≤-isDecTotalOrder-≈ =On.isDecTotalOrdertoList(StrictLex.≤-isDecTotalOrder Char.<-isStrictTotalOrder)≤-decTotalOrder-≈ : DecTotalOrder _ _ _≤-decTotalOrder-≈ =On.decTotalOrder(StrictLex.≤-decTotalOrder Char.<-strictTotalOrder)toList≤-decPoset-≈ : DecPoset _ _ _≤-decPoset-≈ =On.decPoset(StrictLex.≤-decPoset Char.<-strictTotalOrder)toList-------------------------------------------------------------------------- Alternative Boolean equality test.---- Why is the definition _==_ = primStringEquality not used? One-- reason is that the present definition can sometimes improve type-- inference, at least with the version of Agda that is current at the-- time of writing: see unit-test below.infix 4 _==__==_ : String → String → Bools₁ == s₂ = isYes (s₁ ≟ s₂)private-- The following unit test does not type-check (at the time of-- writing) if _==_ is replaced by primStringEquality.data P : (String → Bool) → Set wherep : (c : String) → P (_==_ c)unit-test : P (_==_ "")unit-test = p _
-------------------------------------------------------------------------- The Agda standard library---- String Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.String.Literals whereopen import Agda.Builtin.FromString using (IsString)open import Data.Unit.Base using (⊤)open import Agda.Builtin.String using (String)isString : IsString StringisString = record{ Constraint = λ _ → ⊤; fromString = λ s → s}
-------------------------------------------------------------------------- The Agda standard library---- Instances for strings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.String.Instances whereopen import Data.String.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceString-≡-isDecEquivalence = isDecEquivalence _≟_
-------------------------------------------------------------------------- The Agda standard library---- Strings: builtin type and basic operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.String.Base whereopen import Data.Bool.Base using (Bool; true; false; if_then_else_)open import Data.Char.Base as Char using (Char)open import Data.List.Base as List using (List; [_]; _∷_; [])open import Data.List.NonEmpty.Base as NE using (List⁺)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise)open import Data.List.Relation.Binary.Lex.Core using (Lex-<; Lex-≤)open import Data.Maybe.Base as Maybe using (Maybe)open import Data.Nat.Base using (ℕ; _∸_; ⌊_/2⌋; ⌈_/2⌉; _≡ᵇ_)open import Data.Product.Base using (proj₁; proj₂)open import Function.Base using (_on_; _∘′_; _∘_)open import Level using (Level; 0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Decidable.Core using (does; T?)-------------------------------------------------------------------------- From Agda.Builtin: type and renamed primitives-- Note that we do not re-export primStringAppend because we want to-- give it an infix definition and be able to assign it a level.import Agda.Builtin.String as Stringopen String public using ( String )renaming( primStringUncons to uncons; primStringToList to toList; primStringFromList to fromList; primShowString to show)-------------------------------------------------------------------------- Relations-- Pointwise equality on Stringsinfix 4 _≈__≈_ : Rel String 0ℓ_≈_ = Pointwise _≡_ on toList-- Lexicographic ordering on Stringsinfix 4 _<__<_ : Rel String 0ℓ_<_ = Lex-< _≡_ Char._<_ on toListinfix 4 _≤__≤_ : Rel String 0ℓ_≤_ = Lex-≤ _≡_ Char._<_ on toList-------------------------------------------------------------------------- Operations-- List-like operationshead : String → Maybe Charhead = Maybe.map proj₁ ∘′ unconstail : String → Maybe Stringtail = Maybe.map proj₂ ∘′ uncons-- Additional conversion functionsfromChar : Char → StringfromChar = fromList ∘′ [_]fromList⁺ : List⁺ Char → StringfromList⁺ = fromList ∘′ NE.toList-- List-like functionsinfixr 5 _++__++_ : String → String → String_++_ = String.primStringAppendlength : String → ℕlength = List.length ∘ toListreplicate : ℕ → Char → Stringreplicate n = fromList ∘ List.replicate nconcat : List String → Stringconcat = List.foldr _++_ ""intersperse : String → List String → Stringintersperse sep = concat ∘′ (List.intersperse sep)unwords : List String → Stringunwords = intersperse " "unlines : List String → Stringunlines = intersperse "\n"between : String → String → String → Stringbetween left right middle = left ++ middle ++ rightparens : String → Stringparens = between "(" ")"braces : String → Stringbraces = between "{" "}"-- append that also introduces spaces, if necessaryinfixr 5 _<+>__<+>_ : String → String → String"" <+> b = ba <+> "" = aa <+> b = a ++ " " ++ b-------------------------------------------------------------------------- Padding-- Each one of the padding functions should verify the following-- invariant:-- If length str ≤ n then length (padLeft c n str) ≡ n-- and otherwise padLeft c n str ≡ str.-- Appending an empty string is expensive (append for Haskell's-- Text creates a fresh Text value in which both contents are-- copied) so we precompute `n ∸ length str` and check whether-- it is equal to 0.padLeft : Char → ℕ → String → StringpadLeft c n str =let l = n ∸ length str inif l ≡ᵇ 0 then str else replicate l c ++ strpadRight : Char → ℕ → String → StringpadRight c n str =let l = n ∸ length str inif l ≡ᵇ 0 then str else str ++ replicate l cpadBoth : Char → Char → ℕ → String → StringpadBoth cₗ cᵣ n str =let l = n ∸ length str inif l ≡ᵇ 0 then str else replicate ⌊ l /2⌋ cₗ ++ str ++ replicate ⌈ l /2⌉ cᵣ-------------------------------------------------------------------------- Alignment-- We can align a String left, center or right in a column of a given-- width by padding it with whitespace.data Alignment : Set whereLeft Center Right : AlignmentfromAlignment : Alignment → ℕ → String → StringfromAlignment Left = padRight ' 'fromAlignment Center = padBoth ' ' ' 'fromAlignment Right = padLeft ' '-------------------------------------------------------------------------- Splitting stringswordsBy : ∀ {p} {P : Pred Char p} → Decidable P → String → List StringwordsBy P? = List.map fromList ∘ List.wordsBy P? ∘ toListwordsByᵇ : (Char → Bool) → String → List StringwordsByᵇ p = wordsBy (T? ∘ p)words : String → List Stringwords = wordsByᵇ Char.isSpace-- `words` ignores contiguous whitespace_ : words " abc b " ≡ "abc" ∷ "b" ∷ []_ = refllinesBy : ∀ {p} {P : Pred Char p} → Decidable P → String → List StringlinesBy P? = List.map fromList ∘ List.linesBy P? ∘ toListlinesByᵇ : (Char → Bool) → String → List StringlinesByᵇ p = linesBy (T? ∘ p)lines : String → List Stringlines = linesByᵇ ('\n' Char.≈ᵇ_)-- `lines` preserves empty lines_ : lines "\nabc\n\nb\n\n\n" ≡ "" ∷ "abc" ∷ "" ∷ "b" ∷ "" ∷ "" ∷ []_ = reflmap : (Char → Char) → String → Stringmap f = fromList ∘ List.map f ∘ toList_ : map Char.toUpper "abc" ≡ "ABC"_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Vectors defined in terms of the reflexive-transitive closure, Star------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Star.Vec whereopen import Data.Star.Nat using (ℕ; zero; suc; 1#; _+_; length)open import Data.Star.Fin using (Fin)open import Data.Star.Decoration using (All; ↦; _◅◅◅_; decoration)open import Data.Star.Pointer as Pointer using (result)open import Data.Star.List using (List)open import Level using (Level)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (ε; _◅_; gmap)open import Function.Base using (const; case_of_)open import Data.Unit.Base using (tt)privatevariablea : LevelA : Set a-- The vector type. Vectors are natural numbers decorated with extra-- information (i.e. elements).Vec : Set a → ℕ → Set aVec A = All (λ _ → A)-- Nil and cons.[] : Vec A zero[] = εinfixr 5 _∷__∷_ : ∀ {n} → A → Vec A n → Vec A (suc n)x ∷ xs = ↦ x ◅ xs-- Projections.head : ∀ {n} → Vec A (1# + n) → Ahead (↦ x ◅ _) = xtail : ∀ {n} → Vec A (1# + n) → Vec A ntail (↦ _ ◅ xs) = xs-- Append.infixr 5 _++__++_ : ∀ {m n} → Vec A m → Vec A n → Vec A (m + n)_++_ = _◅◅◅_-- Safe lookup.lookup : ∀ {n} → Vec A n → Fin n → Alookup xs i with result _ x ← Pointer.lookup xs i = x-------------------------------------------------------------------------- ConversionsfromList : (xs : List A) → Vec A (length xs)fromList ε = []fromList (x ◅ xs) = x ∷ fromList xstoList : ∀ {n} → Vec A n → List AtoList = gmap (const tt) decoration
-------------------------------------------------------------------------- The Agda standard library---- Pointers into star-lists------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Star.Pointer {ℓ} {I : Set ℓ} whereopen import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Star.Decorationopen import Data.Unit.Baseopen import Function.Base using (const; case_of_)open import Levelopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (NonEmpty; nonEmpty)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveprivatevariabler p q : Level-- Pointers into star-lists. The edge pointed to is decorated with Q,-- while other edges are decorated with P.data Pointer {T : Rel I r}(P : EdgePred p T) (Q : EdgePred q T): Rel (Maybe (NonEmpty (Star T))) (ℓ ⊔ r ⊔ p ⊔ q) wherestep : ∀ {i j k} {x : T i j} {xs : Star T j k}(p : P x) → Pointer P Q (just (nonEmpty (x ◅ xs)))(just (nonEmpty xs))done : ∀ {i j k} {x : T i j} {xs : Star T j k}(q : Q x) → Pointer P Q (just (nonEmpty (x ◅ xs))) nothing-- Any P Q xs means that some edge in xs satisfies Q, while all-- preceding edges satisfy P. A star-list of type Any Always Always xs-- is basically a prefix of xs; the existence of such a prefix-- guarantees that xs is non-empty.Any : {T : Rel I r} (P : EdgePred p T) (Q : EdgePred q T) →EdgePred (ℓ ⊔ (r ⊔ (p ⊔ q))) (Star T)Any P Q xs = Star (Pointer P Q) (just (nonEmpty xs)) nothingmodule _ {T : Rel I r} {P : EdgePred p T} {Q : EdgePred q T} wherethis : ∀ {i j k} {x : T i j} {xs : Star T j k} →Q x → Any P Q (x ◅ xs)this q = done q ◅ εthat : ∀ {i j k} {x : T i j} {xs : Star T j k} →P x → Any P Q xs → Any P Q (x ◅ xs)that p = _◅_ (step p)-- Safe lookup.data Result (T : Rel I r)(P : EdgePred p T) (Q : EdgePred q T) : Set (ℓ ⊔ r ⊔ p ⊔ q) whereresult : ∀ {i j} {x : T i j} (p : P x) (q : Q x) → Result T P Q-- The first argument points out which edge to extract. The edge is-- returned, together with proofs that it satisfies Q and R.module _ {T : Rel I r} {P : EdgePred p T} {Q : EdgePred q T} wherelookup : ∀ {r} {R : EdgePred r T} {i j} {xs : Star T i j} →All R xs → Any P Q xs → Result T Q Rlookup (↦ r ◅ _) (done q ◅ ε) = result q rlookup (↦ _ ◅ rs) (step p ◅ ps) = lookup rs ps-- We can define something resembling init.prefixIndex : ∀ {i j} {xs : Star T i j} → Any P Q xs → IprefixIndex (done {i = i} q ◅ _) = iprefixIndex (step p ◅ ps) = prefixIndex psprefix : ∀ {i j} {xs : Star T i j} →(ps : Any P Q xs) → Star T i (prefixIndex ps)prefix (done q ◅ _) = εprefix (step {x = x} p ◅ ps) = x ◅ prefix ps-- Here we are taking the initial segment of ps (all elements but the-- last, i.e. all edges satisfying P).init : ∀ {i j} {xs : Star T i j} →(ps : Any P Q xs) → All P (prefix ps)init (done q ◅ _) = εinit (step p ◅ ps) = ↦ p ◅ init ps-- One can simplify the implementation by not carrying around the-- indices in the type:last : ∀ {i j} {xs : Star T i j} →Any P Q xs → NonEmptyEdgePred T Qlast ps with result q _ ← lookup {r = p} (decorate (const (lift tt)) _) ps =nonEmptyEdgePred q
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers defined using the reflexive-transitive closure, Star------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Star.Nat whereopen import Data.Unit.Base using (tt)open import Function.Base using (const)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveopen import Relation.Binary.Construct.Always using (Always)-- Natural numbers.ℕ : Setℕ = Star Always tt tt-- Zero and successor.zero : ℕzero = εsuc : ℕ → ℕsuc = _◅_ _-- The length of a star-list.length : ∀ {i t} {I : Set i} {T : Rel I t} {i j} → Star T i j → ℕlength = gmap (const _) (const _)-- Arithmetic.infixl 7 _*_infixl 6 _+_ _∸__+_ : ℕ → ℕ → ℕ_+_ = _◅◅__*_ : ℕ → ℕ → ℕ_*_ m = const m ⋆_∸_ : ℕ → ℕ → ℕm ∸ ε = mε ∸ (_ ◅ n) = zero(_ ◅ m) ∸ (_ ◅ n) = m ∸ n-- Some constants.0# = zero1# = suc 0#2# = suc 1#3# = suc 2#4# = suc 3#5# = suc 4#
-------------------------------------------------------------------------- The Agda standard library---- Lists defined in terms of the reflexive-transitive closure, Star------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Star.List whereopen import Data.Star.Nat using (ℕ; _+_; zero)open import Data.Unit.Base using (tt)open import Relation.Binary.Construct.Always using (Always)open import Relation.Binary.Construct.Constant using (Const)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (Star; ε; _◅_; fold)-- Lists.List : ∀ {a} → Set a → Set aList A = Star (Const A) tt tt-- Nil and cons.[] : ∀ {a} {A : Set a} → List A[] = εinfixr 5 _∷__∷_ : ∀ {a} {A : Set a} → A → List A → List A_∷_ = _◅_-- The sum of the elements in a list containing natural numbers.sum : List ℕ → ℕsum = fold (Star Always) _+_ zero
-------------------------------------------------------------------------- The Agda standard library---- Finite sets defined using the reflexive-transitive closure, Star------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Star.Fin whereopen import Data.Star.Nat as ℕ using (ℕ)open import Data.Star.Pointer using (Any; this; that)open import Data.Unit.Base using (⊤; tt)-- Finite sets are undecorated pointers into natural numbers.Fin : ℕ → SetFin = Any (λ _ → ⊤) (λ _ → ⊤)-- "Constructors".zero : ∀ {n} → Fin (ℕ.suc n)zero = this ttsuc : ∀ {n} → Fin n → Fin (ℕ.suc n)suc = that tt
-------------------------------------------------------------------------- The Agda standard library---- Environments (heterogeneous collections)------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Star.Environment {ℓ} (Ty : Set ℓ) whereopen import Level using (_⊔_)open import Data.Star.List using (List)open import Data.Star.Decoration using (All)open import Data.Star.Pointer as Pointer using (Any; this; that; result)open import Data.Unit.Polymorphic.Base using (⊤)open import Function.Base using (const; case_of_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (_▻_)-- Contexts, listing the types of all the elements in an environment.Ctxt : Set ℓCtxt = List Ty-- Variables (de Bruijn indices); pointers into environments.infix 4 _∋__∋_ : Ctxt → Ty → Set ℓΓ ∋ σ = Any (const (⊤ {ℓ})) (σ ≡_) Γvz : ∀ {Γ σ} → Γ ▻ σ ∋ σvz = this reflvs : ∀ {Γ σ τ} → Γ ∋ τ → Γ ▻ σ ∋ τvs = that _-- Environments. The T function maps types to element types.Env : ∀ {e} → (Ty → Set e) → (Ctxt → Set (ℓ ⊔ e))Env T Γ = All T Γ-- A safe lookup function for environments.lookup : ∀ {Γ σ} {T : Ty → Set} → Env T Γ → Γ ∋ σ → T σlookup ρ i with result refl x ← Pointer.lookup ρ i = x
-------------------------------------------------------------------------- The Agda standard library---- Decorated star-lists------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Star.Decoration whereopen import Data.Unit.Base using (⊤; tt)open import Function.Base using (flip)open import Level using (Level; suc; _⊔_)open import Relation.Binary.Core using (Rel; _=[_]⇒_; _⇒_)open import Relation.Binary.Definitions using (NonEmpty; nonEmpty)open import Relation.Binary.Construct.Closure.ReflexiveTransitive-- A predicate on relation "edges" (think of the relation as a graph).EdgePred : {ℓ r : Level} (p : Level) {I : Set ℓ} → Rel I r → Set (suc p ⊔ ℓ ⊔ r)EdgePred p T = ∀ {i j} → T i j → Set pdata NonEmptyEdgePred {ℓ r p : Level} {I : Set ℓ} (T : Rel I r)(P : EdgePred p T) : Set (ℓ ⊔ r ⊔ p) wherenonEmptyEdgePred : ∀ {i j} {x : T i j}(p : P x) → NonEmptyEdgePred T P-- Decorating an edge with more information.data DecoratedWith {ℓ r p : Level} {I : Set ℓ} {T : Rel I r} (P : EdgePred p T): Rel (NonEmpty (Star T)) (ℓ ⊔ r ⊔ p) where↦ : ∀ {i j k} {x : T i j} {xs : Star T j k}(p : P x) → DecoratedWith P (nonEmpty (x ◅ xs)) (nonEmpty xs)module _ {ℓ r p : Level} {I : Set ℓ} {T : Rel I r} {P : EdgePred p T} whereedge : ∀ {i j} → DecoratedWith {T = T} P i j → NonEmpty Tedge (↦ {x = x} p) = nonEmpty xdecoration : ∀ {i j} → (d : DecoratedWith {T = T} P i j) →P (NonEmpty.proof (edge d))decoration (↦ p) = p-- Star-lists decorated with extra information. All P xs means that-- all edges in xs satisfy P.All : ∀ {ℓ r p} {I : Set ℓ} {T : Rel I r} → EdgePred p T → EdgePred (ℓ ⊔ (r ⊔ p)) (Star T)All P {j = j} xs =Star (DecoratedWith P) (nonEmpty xs) (nonEmpty {y = j} ε)-- We can map over decorated vectors.gmapAll : ∀ {ℓ ℓ′ r p q} {I : Set ℓ} {T : Rel I r} {P : EdgePred p T}{J : Set ℓ′} {U : Rel J r} {Q : EdgePred q U}{i j} {xs : Star T i j}(f : I → J) (g : T =[ f ]⇒ U) →(∀ {i j} {x : T i j} → P x → Q (g x)) →All P xs → All {T = U} Q (gmap f g xs)gmapAll f g h ε = εgmapAll f g h (↦ x ◅ xs) = ↦ (h x) ◅ gmapAll f g h xs-- Since we don't automatically have gmap id id xs ≡ xs it is easier-- to implement mapAll in terms of map than in terms of gmapAll.mapAll : ∀ {ℓ r p q} {I : Set ℓ} {T : Rel I r}{P : EdgePred p T} {Q : EdgePred q T} {i j} {xs : Star T i j} →(∀ {i j} {x : T i j} → P x → Q x) →All P xs → All Q xsmapAll {P = P} {Q} f ps = map F pswhereF : DecoratedWith P ⇒ DecoratedWith QF (↦ x) = ↦ (f x)-- We can decorate star-lists with universally true predicates.decorate : ∀ {ℓ r p} {I : Set ℓ} {T : Rel I r} {P : EdgePred p T} {i j} →(∀ {i j} (x : T i j) → P x) →(xs : Star T i j) → All P xsdecorate f ε = εdecorate f (x ◅ xs) = ↦ (f x) ◅ decorate f xs-- We can append Alls. Unfortunately _◅◅_ does not quite work.infixr 5 _◅◅◅_ _▻▻▻__◅◅◅_ : ∀ {ℓ r p} {I : Set ℓ} {T : Rel I r} {P : EdgePred p T}{i j k} {xs : Star T i j} {ys : Star T j k} →All P xs → All P ys → All P (xs ◅◅ ys)ε ◅◅◅ ys = ys(↦ x ◅ xs) ◅◅◅ ys = ↦ x ◅ xs ◅◅◅ ys_▻▻▻_ : ∀ {ℓ r p} {I : Set ℓ} {T : Rel I r} {P : EdgePred p T}{i j k} {xs : Star T j k} {ys : Star T i j} →All P xs → All P ys → All P (xs ▻▻ ys)_▻▻▻_ = flip _◅◅◅_
-------------------------------------------------------------------------- The Agda standard library---- Bounded vectors (inefficient implementation)-------------------------------------------------------------------------- Vectors of a specified maximum length.{-# OPTIONS --with-K --safe #-}module Data.Star.BoundedVec whereimport Data.Maybe.Base as Maybeopen import Data.Star.Nat using (ℕ; suc; length)open import Data.Star.Decoration using (decoration)open import Data.Star.Pointerusing (Any; this; that; Pointer; step; done; init)open import Data.Star.List using (List)open import Data.Unit.Base using (⊤; tt)open import Function.Base using (const)open import Relation.Binary.Core using (_=[_]⇒_)open import Relation.Binary.Consequences using (map-NonEmpty)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (gmap; ε; _◅_)-------------------------------------------------------------------------- The type-- Finite sets decorated with elements (note the use of suc).BoundedVec : Set → ℕ → SetBoundedVec a n = Any (λ _ → a) (λ _ → ⊤) (suc n)[] : ∀ {a n} → BoundedVec a n[] = this ttinfixr 5 _∷__∷_ : ∀ {a n} → a → BoundedVec a n → BoundedVec a (suc n)_∷_ = that-------------------------------------------------------------------------- Increasing the bound-- Note that this operation is linear in the length of the list.↑ : ∀ {a n} → BoundedVec a n → BoundedVec a (suc n)↑ {a} = gmap inc liftwhereinc = Maybe.map (map-NonEmpty suc)lift : Pointer (λ _ → a) (λ _ → ⊤) =[ inc ]⇒Pointer (λ _ → a) (λ _ → ⊤)lift (step x) = step xlift (done _) = done _-------------------------------------------------------------------------- ConversionsfromList : ∀ {a} → (xs : List a) → BoundedVec a (length xs)fromList ε = []fromList (x ◅ xs) = x ∷ fromList xstoList : ∀ {a n} → BoundedVec a n → List atoList xs = gmap (const tt) decoration (init xs)
-------------------------------------------------------------------------- The Agda standard library---- Signs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sign where-------------------------------------------------------------------------- Definitionopen import Data.Sign.Base publicopen import Data.Sign.Properties publicusing (_≟_)
-------------------------------------------------------------------------- The Agda standard library---- Some properties about signs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sign.Properties whereopen import Algebra.Bundles using (Magma; Semigroup; CommutativeSemigroup;Monoid; CommutativeMonoid; Group; AbelianGroup)open import Data.Sign.Base using (Sign; opposite; _*_; +; -)open import Data.Product.Base using (_,_)open import Function.Base using (_$_; id)open import Function.Definitions using (Injective)open import Level using (0ℓ)open import Relation.Binaryusing (Decidable; DecidableEquality; Setoid; DecSetoid; IsDecEquivalence)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; _≢_; sym; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; decSetoid; isDecEquivalence; isEquivalence)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation.Core using (contradiction)open import Algebra.Structures {A = Sign} _≡_open import Algebra.Definitions {A = Sign} _≡_open import Algebra.Consequences.Propositionalusing (selfInverse⇒involutive; selfInverse⇒injective)-------------------------------------------------------------------------- Equalityinfix 4 _≟__≟_ : DecidableEquality Sign- ≟ - = yes refl- ≟ + = no λ()+ ≟ - = no λ()+ ≟ + = yes refl≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid Sign≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_≡-isDecEquivalence : IsDecEquivalence _≡_≡-isDecEquivalence = isDecEquivalence _≟_-------------------------------------------------------------------------- opposite-- Algebraic properties of oppositeopposite-selfInverse : SelfInverse oppositeopposite-selfInverse { - } { + } refl = reflopposite-selfInverse { + } { - } refl = reflopposite-involutive : Involutive oppositeopposite-involutive = selfInverse⇒involutive opposite-selfInverseopposite-injective : Injective _≡_ _≡_ oppositeopposite-injective = selfInverse⇒injective opposite-selfInverse-------------------------------------------------------------------------- other properties of opposites≢opposite[s] : ∀ s → s ≢ opposite ss≢opposite[s] - ()s≢opposite[s] + ()-------------------------------------------------------------------------- _*_-- Algebraic properties of _*_s*s≡+ : ∀ s → s * s ≡ +s*s≡+ + = refls*s≡+ - = refl*-identityˡ : LeftIdentity + _*_*-identityˡ _ = refl*-identityʳ : RightIdentity + _*_*-identityʳ - = refl*-identityʳ + = refl*-identity : Identity + _*_*-identity = *-identityˡ , *-identityʳ*-comm : Commutative _*_*-comm + + = refl*-comm + - = refl*-comm - + = refl*-comm - - = refl*-assoc : Associative _*_*-assoc + + _ = refl*-assoc + - _ = refl*-assoc - + _ = refl*-assoc - - + = refl*-assoc - - - = refl*-cancelʳ-≡ : RightCancellative _*_*-cancelʳ-≡ _ - - _ = refl*-cancelʳ-≡ _ - + eq = contradiction (sym eq) (s≢opposite[s] _)*-cancelʳ-≡ _ + - eq = contradiction eq (s≢opposite[s] _)*-cancelʳ-≡ _ + + _ = refl*-cancelˡ-≡ : LeftCancellative _*_*-cancelˡ-≡ - _ _ eq = opposite-injective eq*-cancelˡ-≡ + _ _ eq = eq*-cancel-≡ : Cancellative _*_*-cancel-≡ = *-cancelˡ-≡ , *-cancelʳ-≡*-inverse : Inverse + id _*_*-inverse = s*s≡+ , s*s≡+*-isMagma : IsMagma _*_*-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _*_}*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-isSemigroup : IsSemigroup _*_*-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-isCommutativeSemigroup : IsCommutativeSemigroup _*_*-isCommutativeSemigroup = record{ isSemigroup = *-isSemigroup; comm = *-comm}*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeSemigroup = record{ isCommutativeSemigroup = *-isCommutativeSemigroup}*-isMonoid : IsMonoid _*_ +*-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}*-monoid : Monoid 0ℓ 0ℓ*-monoid = record{ isMonoid = *-isMonoid}*-isCommutativeMonoid : IsCommutativeMonoid _*_ +*-isCommutativeMonoid = record{ isMonoid = *-isMonoid; comm = *-comm}*-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-commutativeMonoid = record{ isCommutativeMonoid = *-isCommutativeMonoid}*-isGroup : IsGroup _*_ + id*-isGroup = record{ isMonoid = *-isMonoid; inverse = *-inverse; ⁻¹-cong = id}*-group : Group 0ℓ 0ℓ*-group = record{ isGroup = *-isGroup}*-isAbelianGroup : IsAbelianGroup _*_ + id*-isAbelianGroup = record{ isGroup = *-isGroup; comm = *-comm}*-abelianGroup : AbelianGroup 0ℓ 0ℓ*-abelianGroup = record{ isAbelianGroup = *-isAbelianGroup}-- Other properties of _*_s*opposite[s]≡- : ∀ s → s * opposite s ≡ -s*opposite[s]≡- + = refls*opposite[s]≡- - = reflopposite[s]*s≡- : ∀ s → opposite s * s ≡ -opposite[s]*s≡- + = reflopposite[s]*s≡- - = refl
-------------------------------------------------------------------------- The Agda standard library---- Instances for signs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sign.Instances whereopen import Data.Sign.PropertiesinstanceSign-≡-isDecEquivalence = ≡-isDecEquivalence
-------------------------------------------------------------------------- The Agda standard library---- Signs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Sign.Base whereopen import Algebra.Bundles.Raw using (RawMagma; RawMonoid; RawGroup)open import Level using (0ℓ)open import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Definitiondata Sign : Set where- : Sign+ : Sign-------------------------------------------------------------------------- Operations-- The opposite sign.opposite : Sign → Signopposite - = +opposite + = --- "Multiplication".infixl 7 _*__*_ : Sign → Sign → Sign+ * s₂ = s₂- * s₂ = opposite s₂-------------------------------------------------------------------------- Raw Bundles*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≡_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≡_; _∙_ = _*_; ε = +}*-1-rawGroup : RawGroup 0ℓ 0ℓ*-1-rawGroup = record{ _≈_ = _≡_; _∙_ = _*_; _⁻¹ = opposite; ε = +}
-------------------------------------------------------------------------- The Agda standard library---- Refinement type: a value together with a proof irrelevant witness.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Refinement whereopen import Levelopen import Data.Irrelevant as Irrelevant using (Irrelevant)open import Function.Baseopen import Relation.Unary using (IUniversal; _⇒_; _⊢_)privatevariablea b p q : LevelA : Set aB : Set brecord Refinement {a p} (A : Set a) (P : A → Set p) : Set (a ⊔ p) whereconstructor _,_field value : Aproof : Irrelevant (P value)infixr 4 _,_open Refinement public-- The syntax declaration below is meant to mimick set comprehension.-- It is attached to Refinement-syntax, to make it easy to import-- Data.Refinement without the special syntax.infix 2 Refinement-syntaxRefinement-syntax = Refinementsyntax Refinement-syntax A (λ x → P) = [ x ∈ A ∣ P ]module _ {P : A → Set p} {Q : B → Set q} wheremap : (f : A → B) → ∀[ P ⇒ f ⊢ Q ] →[ a ∈ A ∣ P a ] → [ b ∈ B ∣ Q b ]map f prf (a , p) = f a , Irrelevant.map prf pmodule _ {P : A → Set p} {Q : A → Set q} whererefine : ∀[ P ⇒ Q ] → [ a ∈ A ∣ P a ] → [ a ∈ A ∣ Q a ]refine = map id
-------------------------------------------------------------------------- The Agda standard library---- Predicate lifting for refinement types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Refinement.Relation.Unary.All whereopen import Levelopen import Data.Refinementopen import Function.Baseopen import Relation.Unaryprivatevariablea b p q : LevelA : Set aB : Set bmodule _ {P : A → Set p} whereAll : (A → Set q) → Refinement A P → Set qAll P (a , _) = P a
-------------------------------------------------------------------------- The Agda standard library---- Record types with manifest fields and "with", based on Randy-- Pollack's "Dependently Typed Records in Type Theory"-------------------------------------------------------------------------- For an example of how this module can be used, see README.Record.{-# OPTIONS --cubical-compatible --safe #-}open import Data.Bool.Base using (true; false; if_then_else_)open import Data.Empty using (⊥)open import Data.List.Base using (List; []; _∷_; foldr)open import Data.Product.Base hiding (proj₁; proj₂)open import Data.Unit.Polymorphic using (⊤)open import Function.Base using (id; _∘_)open import Level using (suc; _⊔_)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Nullary.Decidable using (does)-- The module is parametrised by the type of labels, which should come-- with decidable equality.module Data.Record {ℓ} (Label : Set ℓ) (_≟_ : DecidableEquality Label) where-------------------------------------------------------------------------- A Σ-type with a manifest field-- A variant of Σ where the value of the second field is "manifest"-- (given by the first).infix 4 _,record Manifest-Σ {a b} (A : Set a) {B : A → Set b}(f : (x : A) → B x) : Set a whereconstructor _,field proj₁ : Aproj₂ : B proj₁proj₂ = f proj₁-------------------------------------------------------------------------- Signatures and recordsmutualinfixl 5 _,_∶_ _,_≔_data Signature s : Set (suc s ⊔ ℓ) where∅ : Signature s_,_∶_ : (Sig : Signature s)(ℓ : Label)(A : Record Sig → Set s) →Signature s_,_≔_ : (Sig : Signature s)(ℓ : Label){A : Record Sig → Set s}(a : (r : Record Sig) → A r) →Signature s-- Record is a record type to ensure that the signature can be-- inferred from a value of type Record Sig.record Record {s} (Sig : Signature s) : Set s whereeta-equalityinductiveconstructor recfield fun : Record-fun SigRecord-fun : ∀ {s} → Signature s → Set sRecord-fun ∅ = ⊤Record-fun (Sig , ℓ ∶ A) = Σ (Record Sig) ARecord-fun (Sig , ℓ ≔ a) = Manifest-Σ (Record Sig) a-------------------------------------------------------------------------- Labels-- A signature's labels, starting with the last one.labels : ∀ {s} → Signature s → List Labellabels ∅ = []labels (Sig , ℓ ∶ A) = ℓ ∷ labels Siglabels (Sig , ℓ ≔ a) = ℓ ∷ labels Sig-- Inhabited if the label is part of the signature.infix 4 _∈__∈_ : ∀ {s} → Label → Signature s → Setℓ ∈ Sig =foldr (λ ℓ′ → if does (ℓ ≟ ℓ′) then (λ _ → ⊤) else id) ⊥ (labels Sig)-------------------------------------------------------------------------- Projections-- Signature restriction and projection. (Restriction means removal of-- a given field and all subsequent fields.)Restrict : ∀ {s} (Sig : Signature s) (ℓ : Label) → ℓ ∈ Sig →Signature sRestrict ∅ ℓ ()Restrict (Sig , ℓ′ ∶ A) ℓ ℓ∈ with does (ℓ ≟ ℓ′)... | true = Sig... | false = Restrict Sig ℓ ℓ∈Restrict (Sig , ℓ′ ≔ a) ℓ ℓ∈ with does (ℓ ≟ ℓ′)... | true = Sig... | false = Restrict Sig ℓ ℓ∈Restricted : ∀ {s} (Sig : Signature s) (ℓ : Label) → ℓ ∈ Sig → Set sRestricted Sig ℓ ℓ∈ = Record (Restrict Sig ℓ ℓ∈)Proj : ∀ {s} (Sig : Signature s) (ℓ : Label) {ℓ∈ : ℓ ∈ Sig} →Restricted Sig ℓ ℓ∈ → Set sProj ∅ ℓ {}Proj (Sig , ℓ′ ∶ A) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = A... | false = Proj Sig ℓ {ℓ∈}Proj (_,_≔_ Sig ℓ′ {A = A} a) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = A... | false = Proj Sig ℓ {ℓ∈}-- Record restriction and projection.infixl 5 _∣__∣_ : ∀ {s} {Sig : Signature s} → Record Sig →(ℓ : Label) {ℓ∈ : ℓ ∈ Sig} → Restricted Sig ℓ ℓ∈_∣_ {Sig = ∅} r ℓ {}_∣_ {Sig = Sig , ℓ′ ∶ A} (rec r) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = Σ.proj₁ r... | false = _∣_ (Σ.proj₁ r) ℓ {ℓ∈}_∣_ {Sig = Sig , ℓ′ ≔ a} (rec r) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = Manifest-Σ.proj₁ r... | false = _∣_ (Manifest-Σ.proj₁ r) ℓ {ℓ∈}infixl 5 _·__·_ : ∀ {s} {Sig : Signature s} (r : Record Sig)(ℓ : Label) {ℓ∈ : ℓ ∈ Sig} →Proj Sig ℓ {ℓ∈} (r ∣ ℓ)_·_ {Sig = ∅} r ℓ {}_·_ {Sig = Sig , ℓ′ ∶ A} (rec r) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = Σ.proj₂ r... | false = _·_ (Σ.proj₁ r) ℓ {ℓ∈}_·_ {Sig = Sig , ℓ′ ≔ a} (rec r) ℓ {ℓ∈} with does (ℓ ≟ ℓ′)... | true = Manifest-Σ.proj₂ r... | false = _·_ (Manifest-Σ.proj₁ r) ℓ {ℓ∈}-------------------------------------------------------------------------- With-- Sig With ℓ ≔ a is the signature Sig, but with the ℓ field set to a.mutualinfixl 5 _With_≔__With_≔_ : ∀ {s} (Sig : Signature s) (ℓ : Label) {ℓ∈ : ℓ ∈ Sig} →((r : Restricted Sig ℓ ℓ∈) → Proj Sig ℓ r) → Signature s_With_≔_ ∅ ℓ {} a_With_≔_ (Sig , ℓ′ ∶ A) ℓ {ℓ∈} a with does (ℓ ≟ ℓ′)... | true = Sig , ℓ′ ≔ a... | false = _With_≔_ Sig ℓ {ℓ∈} a , ℓ′ ∶ A ∘ drop-With_With_≔_ (Sig , ℓ′ ≔ a′) ℓ {ℓ∈} a with does (ℓ ≟ ℓ′)... | true = Sig , ℓ′ ≔ a... | false = _With_≔_ Sig ℓ {ℓ∈} a , ℓ′ ≔ a′ ∘ drop-Withdrop-With : ∀ {s} {Sig : Signature s} {ℓ : Label} {ℓ∈ : ℓ ∈ Sig}{a : (r : Restricted Sig ℓ ℓ∈) → Proj Sig ℓ r} →Record (_With_≔_ Sig ℓ {ℓ∈} a) → Record Sigdrop-With {Sig = ∅} {ℓ∈ = ()} rdrop-With {Sig = Sig , ℓ′ ∶ A} {ℓ} (rec r) with does (ℓ ≟ ℓ′)... | true = rec (Manifest-Σ.proj₁ r , Manifest-Σ.proj₂ r)... | false = rec (drop-With (Σ.proj₁ r) , Σ.proj₂ r)drop-With {Sig = Sig , ℓ′ ≔ a} {ℓ} (rec r) with does (ℓ ≟ ℓ′)... | true = rec (Manifest-Σ.proj₁ r ,)... | false = rec (drop-With (Manifest-Σ.proj₁ r) ,)
-------------------------------------------------------------------------- The Agda standard library---- Rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational where-------------------------------------------------------------------------- Publicly re-export contents of core module and queriesopen import Data.Rational.Base publicopen import Data.Rational.Properties publicusing (_≟_; _≤?_; _<?_; _≥?_; _>?_)-------------------------------------------------------------------------- Deprecated-- Version 1.0open import Data.Rational.Properties publicusing (drop-*≤*; ≃⇒≡; ≡⇒≃)-- Version 1.5import Data.Integer.Show as ℤopen import Data.String.Base using (String; _++_)show : ℚ → Stringshow p = ℤ.show (↥ p) ++ "/" ++ ℤ.show (↧ p){-# WARNING_ON_USAGE show"Warning: show was deprecated in v1.5.Please use Data.Rational.Show's show instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Rational numbers in non-reduced form.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Unnormalised where-- Re-export basic definition, operations and queriesopen import Data.Rational.Unnormalised.Base publicopen import Data.Rational.Unnormalised.Properties publicusing (_≃?_; _≤?_; _<?_; _≥?_; _>?_)
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over rationals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Unnormalised.Solver whereimport Algebra.Solver.Ring.Simple as Solverimport Algebra.Solver.Ring.AlmostCommutativeRing as ACRopen import Data.Rational.Unnormalised.Properties using (_≃?_; +-*-commutativeRing)-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_module +-*-Solver =Solver (ACR.fromCommutativeRing +-*-commutativeRing) _≃?_
-------------------------------------------------------------------------- The Agda standard library---- Showing unnormalised rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Unnormalised.Show whereimport Data.Integer.Show as ℤopen import Data.Rational.Unnormalised.Baseopen import Data.String.Base using (String; _++_)show : ℚᵘ → Stringshow p = ℤ.show (↥ p) ++ "/" ++ ℤ.show (↧ p)
------------------------------------------------------------------------- The Agda standard library---- Properties of unnormalized Rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for +-rawMonoid, *-rawMonoid (issue #1865, #1844, #1755)module Data.Rational.Unnormalised.Properties whereopen import Algebraopen import Algebra.Apartnessopen import Algebra.Latticeimport Algebra.Consequences.Setoid as Consequencesopen import Algebra.Consequences.Propositionalopen import Algebra.Construct.NaturalChoice.Baseimport Algebra.Construct.NaturalChoice.MinMaxOp as MinMaxOpimport Algebra.Lattice.Construct.NaturalChoice.MinMaxOp as LatticeMinMaxOpopen import Data.Bool.Base using (T; true; false)open import Data.Nat.Base as ℕ using (suc; pred)import Data.Nat.Properties as ℕopen import Data.Integer.Base as ℤ using (ℤ; +0; +[1+_]; -[1+_]; 0ℤ; 1ℤ; -1ℤ)open import Data.Integer.Solver renaming (module +-*-Solver to ℤ-solver)import Data.Integer.Properties as ℤopen import Data.Rational.Unnormalised.Baseopen import Data.Product.Base using (_,_; proj₁; proj₂)open import Data.Sum.Base using (_⊎_; [_,_]′; inj₁; inj₂)import Data.Sign as Signopen import Function.Base using (_on_; _$_; _∘_; flip)open import Level using (0ℓ)open import Relation.Nullary.Decidable.Core as Dec using (yes; no)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Binary.Core using (_⇒_; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; TotalPreorder; Poset; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder; DenseLinearOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence; IsApartnessRelation; IsTotalPreorder; IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder; IsDenseLinearOrder)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Cotransitive; Tight; Decidable; Antisymmetric; Asymmetric; Dense; Total; Trans; Trichotomous; Irreflexive; Irrelevant; _Respectsˡ_; _Respectsʳ_; _Respects₂_; tri≈; tri<; tri>)import Relation.Binary.Consequences as BCopen import Relation.Binary.PropositionalEqualityimport Relation.Binary.Properties.Poset as PosetPropertiesimport Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen import Relation.Binary.Reasoning.Syntaxopen import Algebra.Properties.CommutativeSemigroup ℤ.*-commutativeSemigroupprivatevariablep q r : ℚᵘ-------------------------------------------------------------------------- Properties of ↥_ and ↧_------------------------------------------------------------------------↥↧≡⇒≡ : ∀ {p q} → ↥ p ≡ ↥ q → ↧ₙ p ≡ ↧ₙ q → p ≡ q↥↧≡⇒≡ {mkℚᵘ _ _} {mkℚᵘ _ _} refl refl = refl-------------------------------------------------------------------------- Properties of _/_------------------------------------------------------------------------/-cong : ∀ {n₁ d₁ n₂ d₂} .{{_ : ℕ.NonZero d₁}} .{{_ : ℕ.NonZero d₂}} →n₁ ≡ n₂ → d₁ ≡ d₂ → n₁ / d₁ ≡ n₂ / d₂/-cong refl refl = refl↥[n/d]≡n : ∀ n d .{{_ : ℕ.NonZero d}} → ↥ (n / d) ≡ n↥[n/d]≡n n (suc d) = refl↧[n/d]≡d : ∀ n d .{{_ : ℕ.NonZero d}} → ↧ (n / d) ≡ ℤ.+ d↧[n/d]≡d n (suc d) = refl-------------------------------------------------------------------------- Properties of _≃_------------------------------------------------------------------------drop-*≡* : ∀ {p q} → p ≃ q → ↥ p ℤ.* ↧ q ≡ ↥ q ℤ.* ↧ pdrop-*≡* (*≡* eq) = eq≃-refl : Reflexive _≃_≃-refl = *≡* refl≃-reflexive : _≡_ ⇒ _≃_≃-reflexive refl = *≡* refl≃-sym : Symmetric _≃_≃-sym (*≡* eq) = *≡* (sym eq)≃-trans : Transitive _≃_≃-trans {x} {y} {z} (*≡* ad≡cb) (*≡* cf≡ed) =*≡* (ℤ.*-cancelʳ-≡ (↥ x ℤ.* ↧ z) (↥ z ℤ.* ↧ x) (↧ y) (begin↥ x ℤ.* ↧ z ℤ.* ↧ y ≡⟨ xy∙z≈xz∙y (↥ x) _ _ ⟩↥ x ℤ.* ↧ y ℤ.* ↧ z ≡⟨ cong (ℤ._* ↧ z) ad≡cb ⟩↥ y ℤ.* ↧ x ℤ.* ↧ z ≡⟨ xy∙z≈xz∙y (↥ y) _ _ ⟩↥ y ℤ.* ↧ z ℤ.* ↧ x ≡⟨ cong (ℤ._* ↧ x) cf≡ed ⟩↥ z ℤ.* ↧ y ℤ.* ↧ x ≡⟨ xy∙z≈xz∙y (↥ z) _ _ ⟩↥ z ℤ.* ↧ x ℤ.* ↧ y ∎))where open ≡-Reasoninginfix 4 _≃?__≃?_ : Decidable _≃_p ≃? q = Dec.map′ *≡* drop-*≡* (↥ p ℤ.* ↧ q ℤ.≟ ↥ q ℤ.* ↧ p)0≄1 : 0ℚᵘ ≄ 1ℚᵘ0≄1 = Dec.from-no (0ℚᵘ ≃? 1ℚᵘ)≃-≄-irreflexive : Irreflexive _≃_ _≄_≃-≄-irreflexive x≃y x≄y = x≄y x≃y≄-symmetric : Symmetric _≄_≄-symmetric x≄y y≃x = x≄y (≃-sym y≃x)≄-cotransitive : Cotransitive _≄_≄-cotransitive {x} {y} x≄y z with x ≃? z | z ≃? y... | no x≄z | _ = inj₁ x≄z... | yes _ | no z≄y = inj₂ z≄y... | yes x≃z | yes z≃y = contradiction (≃-trans x≃z z≃y) x≄y≃-isEquivalence : IsEquivalence _≃_≃-isEquivalence = record{ refl = ≃-refl; sym = ≃-sym; trans = ≃-trans}≃-isDecEquivalence : IsDecEquivalence _≃_≃-isDecEquivalence = record{ isEquivalence = ≃-isEquivalence; _≟_ = _≃?_}≄-isApartnessRelation : IsApartnessRelation _≃_ _≄_≄-isApartnessRelation = record{ irrefl = ≃-≄-irreflexive; sym = ≄-symmetric; cotrans = ≄-cotransitive}≄-tight : Tight _≃_ _≄_proj₁ (≄-tight p q) ¬p≄q = Dec.decidable-stable (p ≃? q) ¬p≄qproj₂ (≄-tight p q) p≃q p≄q = p≄q p≃q≃-setoid : Setoid 0ℓ 0ℓ≃-setoid = record{ isEquivalence = ≃-isEquivalence}≃-decSetoid : DecSetoid 0ℓ 0ℓ≃-decSetoid = record{ isDecEquivalence = ≃-isDecEquivalence}module ≃-Reasoning = ≈-Reasoning ≃-setoid↥p≡0⇒p≃0 : ∀ p → ↥ p ≡ 0ℤ → p ≃ 0ℚᵘ↥p≡0⇒p≃0 p ↥p≡0 = *≡* (cong (ℤ._* (↧ 0ℚᵘ)) ↥p≡0)p≃0⇒↥p≡0 : ∀ p → p ≃ 0ℚᵘ → ↥ p ≡ 0ℤp≃0⇒↥p≡0 p (*≡* eq) = begin↥ p ≡⟨ ℤ.*-identityʳ (↥ p) ⟨↥ p ℤ.* 1ℤ ≡⟨ eq ⟩0ℤ ∎where open ≡-Reasoning↥p≡↥q≡0⇒p≃q : ∀ p q → ↥ p ≡ 0ℤ → ↥ q ≡ 0ℤ → p ≃ q↥p≡↥q≡0⇒p≃q p q ↥p≡0 ↥q≡0 = ≃-trans (↥p≡0⇒p≃0 p ↥p≡0) (≃-sym (↥p≡0⇒p≃0 _ ↥q≡0))-------------------------------------------------------------------------- Properties of -_------------------------------------------------------------------------neg-involutive-≡ : Involutive _≡_ (-_)neg-involutive-≡ (mkℚᵘ n d) = cong (λ n → mkℚᵘ n d) (ℤ.neg-involutive n)neg-involutive : Involutive _≃_ (-_)neg-involutive p rewrite neg-involutive-≡ p = ≃-refl-‿cong : Congruent₁ _≃_ (-_)-‿cong {p@record{}} {q@record{}} (*≡* p≡q) = *≡* (begin↥(- p) ℤ.* ↧ q ≡⟨ ℤ.*-identityˡ (ℤ.- (↥ p) ℤ.* ↧ q) ⟨1ℤ ℤ.* (↥(- p) ℤ.* ↧ q) ≡⟨ ℤ.*-assoc 1ℤ (↥ (- p)) (↧ q) ⟨(1ℤ ℤ.* ℤ.-(↥ p)) ℤ.* ↧ q ≡⟨ cong (ℤ._* ↧ q) (ℤ.neg-distribʳ-* 1ℤ (↥ p)) ⟨ℤ.-(1ℤ ℤ.* ↥ p) ℤ.* ↧ q ≡⟨ cong (ℤ._* ↧ q) (ℤ.neg-distribˡ-* 1ℤ (↥ p)) ⟩(-1ℤ ℤ.* ↥ p) ℤ.* ↧ q ≡⟨ ℤ.*-assoc ℤ.-1ℤ (↥ p) (↧ q) ⟩-1ℤ ℤ.* (↥ p ℤ.* ↧ q) ≡⟨ cong (ℤ.-1ℤ ℤ.*_) p≡q ⟩-1ℤ ℤ.* (↥ q ℤ.* ↧ p) ≡⟨ ℤ.*-assoc ℤ.-1ℤ (↥ q) (↧ p) ⟨(-1ℤ ℤ.* ↥ q) ℤ.* ↧ p ≡⟨ cong (ℤ._* ↧ p) (ℤ.neg-distribˡ-* 1ℤ (↥ q)) ⟨ℤ.-(1ℤ ℤ.* ↥ q) ℤ.* ↧ p ≡⟨ cong (ℤ._* ↧ p) (ℤ.neg-distribʳ-* 1ℤ (↥ q)) ⟩(1ℤ ℤ.* ↥(- q)) ℤ.* ↧ p ≡⟨ ℤ.*-assoc 1ℤ (ℤ.- (↥ q)) (↧ p) ⟩1ℤ ℤ.* (↥(- q) ℤ.* ↧ p) ≡⟨ ℤ.*-identityˡ (↥ (- q) ℤ.* ↧ p) ⟩↥(- q) ℤ.* ↧ p ∎)where open ≡-Reasoningneg-mono-< : -_ Preserves _<_ ⟶ _>_neg-mono-< {p@record{}} {q@record{}} (*<* p<q) = *<* $ begin-strictℤ.- ↥ q ℤ.* ↧ p ≡⟨ ℤ.neg-distribˡ-* (↥ q) (↧ p) ⟨ℤ.- (↥ q ℤ.* ↧ p) <⟨ ℤ.neg-mono-< p<q ⟩ℤ.- (↥ p ℤ.* ↧ q) ≡⟨ ℤ.neg-distribˡ-* (↥ p) (↧ q) ⟩↥ (- p) ℤ.* ↧ (- q) ∎where open ℤ.≤-Reasoningneg-cancel-< : ∀ {p q} → - p < - q → q < pneg-cancel-< {p@record{}} {q@record{}} (*<* -↥p↧q<-↥q↧p) = *<* $ begin-strict↥ q ℤ.* ↧ p ≡⟨ ℤ.neg-involutive (↥ q ℤ.* ↧ p) ⟨ℤ.- ℤ.- (↥ q ℤ.* ↧ p) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ q) (↧ p)) ⟩ℤ.- ((ℤ.- ↥ q) ℤ.* ↧ p) <⟨ ℤ.neg-mono-< -↥p↧q<-↥q↧p ⟩ℤ.- ((ℤ.- ↥ p) ℤ.* ↧ q) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ p) (↧ q)) ⟨ℤ.- ℤ.- (↥ p ℤ.* ↧ q) ≡⟨ ℤ.neg-involutive (↥ p ℤ.* ↧ q) ⟩↥ p ℤ.* ↧ q ∎where open ℤ.≤-Reasoning-------------------------------------------------------------------------- Properties of _≤_-------------------------------------------------------------------------- Relational propertiesdrop-*≤* : p ≤ q → (↥ p ℤ.* ↧ q) ℤ.≤ (↥ q ℤ.* ↧ p)drop-*≤* (*≤* pq≤qp) = pq≤qp≤-reflexive : _≃_ ⇒ _≤_≤-reflexive (*≡* eq) = *≤* (ℤ.≤-reflexive eq)≤-refl : Reflexive _≤_≤-refl = ≤-reflexive ≃-refl≤-reflexive-≡ : _≡_ ⇒ _≤_≤-reflexive-≡ refl = ≤-refl≤-trans : Transitive _≤_≤-trans {p} {q} {r} (*≤* eq₁) (*≤* eq₂)= let n₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; d₁ = ↧ p; d₂ = ↧ q; d₃ = ↧ r in *≤* $ℤ.*-cancelʳ-≤-pos (n₁ ℤ.* d₃) (n₃ ℤ.* d₁) d₂ $ begin(n₁ ℤ.* d₃) ℤ.* d₂ ≡⟨ ℤ.*-assoc n₁ d₃ d₂ ⟩n₁ ℤ.* (d₃ ℤ.* d₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm d₃ d₂) ⟩n₁ ℤ.* (d₂ ℤ.* d₃) ≡⟨ ℤ.*-assoc n₁ d₂ d₃ ⟨(n₁ ℤ.* d₂) ℤ.* d₃ ≤⟨ ℤ.*-monoʳ-≤-nonNeg d₃ eq₁ ⟩(n₂ ℤ.* d₁) ℤ.* d₃ ≡⟨ cong (ℤ._* d₃) (ℤ.*-comm n₂ d₁) ⟩(d₁ ℤ.* n₂) ℤ.* d₃ ≡⟨ ℤ.*-assoc d₁ n₂ d₃ ⟩d₁ ℤ.* (n₂ ℤ.* d₃) ≤⟨ ℤ.*-monoˡ-≤-nonNeg d₁ eq₂ ⟩d₁ ℤ.* (n₃ ℤ.* d₂) ≡⟨ ℤ.*-assoc d₁ n₃ d₂ ⟨(d₁ ℤ.* n₃) ℤ.* d₂ ≡⟨ cong (ℤ._* d₂) (ℤ.*-comm d₁ n₃) ⟩(n₃ ℤ.* d₁) ℤ.* d₂ ∎ where open ℤ.≤-Reasoning≤-antisym : Antisymmetric _≃_ _≤_≤-antisym (*≤* le₁) (*≤* le₂) = *≡* (ℤ.≤-antisym le₁ le₂)≤-total : Total _≤_≤-total p q = [ inj₁ ∘ *≤* , inj₂ ∘ *≤* ]′ (ℤ.≤-total(↥ p ℤ.* ↧ q)(↥ q ℤ.* ↧ p))≤-respˡ-≃ : _≤_ Respectsˡ _≃_≤-respˡ-≃ x≈y = ≤-trans (≤-reflexive (≃-sym x≈y))≤-respʳ-≃ : _≤_ Respectsʳ _≃_≤-respʳ-≃ x≈y z≤x = ≤-trans z≤x (≤-reflexive x≈y)≤-resp₂-≃ : _≤_ Respects₂ _≃_≤-resp₂-≃ = ≤-respʳ-≃ , ≤-respˡ-≃infix 4 _≤?_ _≥?__≤?_ : Decidable _≤_p ≤? q = Dec.map′ *≤* drop-*≤* (↥ p ℤ.* ↧ q ℤ.≤? ↥ q ℤ.* ↧ p)_≥?_ : Decidable _≥__≥?_ = flip _≤?_≤-irrelevant : Irrelevant _≤_≤-irrelevant (*≤* p≤q₁) (*≤* p≤q₂) = cong *≤* (ℤ.≤-irrelevant p≤q₁ p≤q₂)-------------------------------------------------------------------------- Structures over _≃_≤-isPreorder : IsPreorder _≃_ _≤_≤-isPreorder = record{ isEquivalence = ≃-isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isTotalPreorder : IsTotalPreorder _≃_ _≤_≤-isTotalPreorder = record{ isPreorder = ≤-isPreorder; total = ≤-total}≤-isPartialOrder : IsPartialOrder _≃_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≃_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≃_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≃?_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles over _≃_≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder = record{ isPreorder = ≤-isPreorder}≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder = record{ isTotalPreorder = ≤-isTotalPreorder}≤-poset : Poset 0ℓ 0ℓ 0ℓ≤-poset = record{ isPartialOrder = ≤-isPartialOrder}≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-totalOrder = record{ isTotalOrder = ≤-isTotalOrder}≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder = record{ isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Structures over _≡_≤-isPreorder-≡ : IsPreorder _≡_ _≤_≤-isPreorder-≡ = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive-≡; trans = ≤-trans}≤-isTotalPreorder-≡ : IsTotalPreorder _≡_ _≤_≤-isTotalPreorder-≡ = record{ isPreorder = ≤-isPreorder-≡; total = ≤-total}-------------------------------------------------------------------------- Bundles over _≡_≤-preorder-≡ : Preorder 0ℓ 0ℓ 0ℓ≤-preorder-≡ = record{ isPreorder = ≤-isPreorder-≡}≤-totalPreorder-≡ : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder-≡ = record{ isTotalPreorder = ≤-isTotalPreorder-≡}-------------------------------------------------------------------------- Other properties of _≤_mono⇒cong : ∀ {f} → f Preserves _≤_ ⟶ _≤_ → f Preserves _≃_ ⟶ _≃_mono⇒cong = BC.mono⇒cong _≃_ _≃_ ≃-sym ≤-reflexive ≤-antisymantimono⇒cong : ∀ {f} → f Preserves _≤_ ⟶ _≥_ → f Preserves _≃_ ⟶ _≃_antimono⇒cong = BC.antimono⇒cong _≃_ _≃_ ≃-sym ≤-reflexive ≤-antisym-------------------------------------------------------------------------- Properties of _≤ᵇ_------------------------------------------------------------------------≤ᵇ⇒≤ : T (p ≤ᵇ q) → p ≤ q≤ᵇ⇒≤ = *≤* ∘ ℤ.≤ᵇ⇒≤≤⇒≤ᵇ : p ≤ q → T (p ≤ᵇ q)≤⇒≤ᵇ = ℤ.≤⇒≤ᵇ ∘ drop-*≤*-------------------------------------------------------------------------- Properties of _<_------------------------------------------------------------------------drop-*<* : p < q → (↥ p ℤ.* ↧ q) ℤ.< (↥ q ℤ.* ↧ p)drop-*<* (*<* pq<qp) = pq<qp-------------------------------------------------------------------------- Relationship between other operators<⇒≤ : _<_ ⇒ _≤_<⇒≤ (*<* p<q) = *≤* (ℤ.<⇒≤ p<q)<⇒≢ : _<_ ⇒ _≢_<⇒≢ (*<* x<y) refl = ℤ.<⇒≢ x<y refl<⇒≱ : _<_ ⇒ _≱_<⇒≱ (*<* x<y) = ℤ.<⇒≱ x<y ∘ drop-*≤*≰⇒> : _≰_ ⇒ _>_≰⇒> p≰q = *<* (ℤ.≰⇒> (p≰q ∘ *≤*))≮⇒≥ : _≮_ ⇒ _≥_≮⇒≥ p≮q = *≤* (ℤ.≮⇒≥ (p≮q ∘ *<*))≰⇒≥ : _≰_ ⇒ _≥_≰⇒≥ = <⇒≤ ∘ ≰⇒>-------------------------------------------------------------------------- Relational properties<-irrefl-≡ : Irreflexive _≡_ _<_<-irrefl-≡ refl (*<* x<x) = ℤ.<-irrefl refl x<x<-irrefl : Irreflexive _≃_ _<_<-irrefl (*≡* x≡y) (*<* x<y) = ℤ.<-irrefl x≡y x<y<-asym : Asymmetric _<_<-asym (*<* x<y) = ℤ.<-asym x<y ∘ drop-*<*<-dense : Dense _<_<-dense {p} {q} (*<* p<q) = m , p<m , m<qwhereopen ℤ.≤-Reasoningm : ℚᵘm = mkℚᵘ (↥ p ℤ.+ ↥ q) (pred (↧ₙ p ℕ.+ ↧ₙ q))p<m : p < mp<m = *<* (begin-strict↥ p ℤ.* ↧ m≡⟨⟩↥ p ℤ.* (↧ p ℤ.+ ↧ q)≡⟨ ℤ.*-distribˡ-+ (↥ p) (↧ p) (↧ q) ⟩↥ p ℤ.* ↧ p ℤ.+ ↥ p ℤ.* ↧ q<⟨ ℤ.+-monoʳ-< (↥ p ℤ.* ↧ p) p<q ⟩↥ p ℤ.* ↧ p ℤ.+ ↥ q ℤ.* ↧ p≡⟨ ℤ.*-distribʳ-+ (↧ p) (↥ p) (↥ q) ⟨(↥ p ℤ.+ ↥ q) ℤ.* ↧ p≡⟨⟩↥ m ℤ.* ↧ p ∎)m<q : m < qm<q = *<* (begin-strict↥ m ℤ.* ↧ q≡⟨ ℤ.*-distribʳ-+ (↧ q) (↥ p) (↥ q) ⟩↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ q<⟨ ℤ.+-monoˡ-< (↥ q ℤ.* ↧ q) p<q ⟩↥ q ℤ.* ↧ p ℤ.+ ↥ q ℤ.* ↧ q≡⟨ ℤ.*-distribˡ-+ (↥ q) (↧ p) (↧ q) ⟨↥ q ℤ.* (↧ p ℤ.+ ↧ q)≡⟨⟩↥ q ℤ.* ↧ m ∎)≤-<-trans : Trans _≤_ _<_ _<_≤-<-trans {p} {q} {r} (*≤* p≤q) (*<* q<r) = *<* $ℤ.*-cancelʳ-<-nonNeg _ $ begin-strictn₁ ℤ.* d₃ ℤ.* d₂ ≡⟨ ℤ.*-assoc n₁ d₃ d₂ ⟩n₁ ℤ.* (d₃ ℤ.* d₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm d₃ d₂) ⟩n₁ ℤ.* (d₂ ℤ.* d₃) ≡⟨ ℤ.*-assoc n₁ d₂ d₃ ⟨n₁ ℤ.* d₂ ℤ.* d₃ ≤⟨ ℤ.*-monoʳ-≤-nonNeg (↧ r) p≤q ⟩n₂ ℤ.* d₁ ℤ.* d₃ ≡⟨ cong (ℤ._* d₃) (ℤ.*-comm n₂ d₁) ⟩d₁ ℤ.* n₂ ℤ.* d₃ ≡⟨ ℤ.*-assoc d₁ n₂ d₃ ⟩d₁ ℤ.* (n₂ ℤ.* d₃) <⟨ ℤ.*-monoˡ-<-pos (↧ p) q<r ⟩d₁ ℤ.* (n₃ ℤ.* d₂) ≡⟨ ℤ.*-assoc d₁ n₃ d₂ ⟨d₁ ℤ.* n₃ ℤ.* d₂ ≡⟨ cong (ℤ._* d₂) (ℤ.*-comm d₁ n₃) ⟩n₃ ℤ.* d₁ ℤ.* d₂ ∎where open ℤ.≤-Reasoningn₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; d₁ = ↧ p; d₂ = ↧ q; d₃ = ↧ r<-≤-trans : Trans _<_ _≤_ _<_<-≤-trans {p} {q} {r} (*<* p<q) (*≤* q≤r) = *<* $ℤ.*-cancelʳ-<-nonNeg _ $ begin-strictn₁ ℤ.* d₃ ℤ.* d₂ ≡⟨ ℤ.*-assoc n₁ d₃ d₂ ⟩n₁ ℤ.* (d₃ ℤ.* d₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm d₃ d₂) ⟩n₁ ℤ.* (d₂ ℤ.* d₃) ≡⟨ ℤ.*-assoc n₁ d₂ d₃ ⟨n₁ ℤ.* d₂ ℤ.* d₃ <⟨ ℤ.*-monoʳ-<-pos (↧ r) p<q ⟩n₂ ℤ.* d₁ ℤ.* d₃ ≡⟨ cong (ℤ._* d₃) (ℤ.*-comm n₂ d₁) ⟩d₁ ℤ.* n₂ ℤ.* d₃ ≡⟨ ℤ.*-assoc d₁ n₂ d₃ ⟩d₁ ℤ.* (n₂ ℤ.* d₃) ≤⟨ ℤ.*-monoˡ-≤-nonNeg (↧ p) q≤r ⟩d₁ ℤ.* (n₃ ℤ.* d₂) ≡⟨ ℤ.*-assoc d₁ n₃ d₂ ⟨d₁ ℤ.* n₃ ℤ.* d₂ ≡⟨ cong (ℤ._* d₂) (ℤ.*-comm d₁ n₃) ⟩n₃ ℤ.* d₁ ℤ.* d₂ ∎where open ℤ.≤-Reasoningn₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; d₁ = ↧ p; d₂ = ↧ q; d₃ = ↧ r<-trans : Transitive _<_<-trans = ≤-<-trans ∘ <⇒≤<-cmp : Trichotomous _≃_ _<_<-cmp p q with ℤ.<-cmp (↥ p ℤ.* ↧ q) (↥ q ℤ.* ↧ p)... | tri< x<y x≉y x≯y = tri< (*<* x<y) (x≉y ∘ drop-*≡*) (x≯y ∘ drop-*<*)... | tri≈ x≮y x≈y x≯y = tri≈ (x≮y ∘ drop-*<*) (*≡* x≈y) (x≯y ∘ drop-*<*)... | tri> x≮y x≉y x>y = tri> (x≮y ∘ drop-*<*) (x≉y ∘ drop-*≡*) (*<* x>y)infix 4 _<?_ _>?__<?_ : Decidable _<_p <? q = Dec.map′ *<* drop-*<* (↥ p ℤ.* ↧ q ℤ.<? ↥ q ℤ.* ↧ p)_>?_ : Decidable _>__>?_ = flip _<?_<-irrelevant : Irrelevant _<_<-irrelevant (*<* p<q₁) (*<* p<q₂) = cong *<* (ℤ.<-irrelevant p<q₁ p<q₂)<-respʳ-≃ : _<_ Respectsʳ _≃_<-respʳ-≃ {p} {q} {r} (*≡* q≡r) (*<* p<q) = *<* $ℤ.*-cancelʳ-<-nonNeg _ $ begin-strictn₁ ℤ.* d₃ ℤ.* d₂ ≡⟨ ℤ.*-assoc n₁ d₃ d₂ ⟩n₁ ℤ.* (d₃ ℤ.* d₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm d₃ d₂) ⟩n₁ ℤ.* (d₂ ℤ.* d₃) ≡⟨ ℤ.*-assoc n₁ d₂ d₃ ⟨n₁ ℤ.* d₂ ℤ.* d₃ <⟨ ℤ.*-monoʳ-<-pos (↧ r) p<q ⟩n₂ ℤ.* d₁ ℤ.* d₃ ≡⟨ ℤ.*-assoc n₂ d₁ d₃ ⟩n₂ ℤ.* (d₁ ℤ.* d₃) ≡⟨ cong (n₂ ℤ.*_) (ℤ.*-comm d₁ d₃) ⟩n₂ ℤ.* (d₃ ℤ.* d₁) ≡⟨ ℤ.*-assoc n₂ d₃ d₁ ⟨n₂ ℤ.* d₃ ℤ.* d₁ ≡⟨ cong (ℤ._* d₁) q≡r ⟩n₃ ℤ.* d₂ ℤ.* d₁ ≡⟨ ℤ.*-assoc n₃ d₂ d₁ ⟩n₃ ℤ.* (d₂ ℤ.* d₁) ≡⟨ cong (n₃ ℤ.*_) (ℤ.*-comm d₂ d₁) ⟩n₃ ℤ.* (d₁ ℤ.* d₂) ≡⟨ ℤ.*-assoc n₃ d₁ d₂ ⟨n₃ ℤ.* d₁ ℤ.* d₂ ∎where open ℤ.≤-Reasoningn₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; d₁ = ↧ p; d₂ = ↧ q; d₃ = ↧ r<-respˡ-≃ : _<_ Respectsˡ _≃_<-respˡ-≃ q≃r q<p= subst (_< _) (neg-involutive-≡ _)$ subst (_ <_) (neg-involutive-≡ _)$ neg-mono-< (<-respʳ-≃ (-‿cong q≃r) (neg-mono-< q<p))<-resp-≃ : _<_ Respects₂ _≃_<-resp-≃ = <-respʳ-≃ , <-respˡ-≃-------------------------------------------------------------------------- Structures<-isStrictPartialOrder-≡ : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder-≡ = record{ isEquivalence = isEquivalence; irrefl = <-irrefl-≡; trans = <-trans; <-resp-≈ = subst (_ <_) , subst (_< _)}<-isStrictPartialOrder : IsStrictPartialOrder _≃_ _<_<-isStrictPartialOrder = record{ isEquivalence = ≃-isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = <-resp-≃}<-isStrictTotalOrder : IsStrictTotalOrder _≃_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}<-isDenseLinearOrder : IsDenseLinearOrder _≃_ _<_<-isDenseLinearOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder; dense = <-dense}-------------------------------------------------------------------------- Bundles<-strictPartialOrder-≡ : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder-≡ = record{ isStrictPartialOrder = <-isStrictPartialOrder-≡}<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}<-denseLinearOrder : DenseLinearOrder 0ℓ 0ℓ 0ℓ<-denseLinearOrder = record{ isDenseLinearOrder = <-isDenseLinearOrder}-------------------------------------------------------------------------- A specialised module for reasoning about the _≤_ and _<_ relations------------------------------------------------------------------------module ≤-Reasoning whereimport Relation.Binary.Reasoning.Base.Triple≤-isPreorder<-asym<-trans<-resp-≃<⇒≤<-≤-trans≤-<-transas Tripleopen Triple publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)renaming (≈-go to ≃-go)open ≃-syntax _IsRelatedTo_ _IsRelatedTo_ ≃-go ≃-sym public-------------------------------------------------------------------------- Properties of ↥_/↧_≥0⇒↥≥0 : ∀ {n dm} → mkℚᵘ n dm ≥ 0ℚᵘ → n ℤ.≥ 0ℤ≥0⇒↥≥0 {n} {dm} r≥0 = ℤ.≤-trans (drop-*≤* r≥0)(ℤ.≤-reflexive $ ℤ.*-identityʳ n)>0⇒↥>0 : ∀ {n dm} → mkℚᵘ n dm > 0ℚᵘ → n ℤ.> 0ℤ>0⇒↥>0 {n} {dm} r>0 = ℤ.<-≤-trans (drop-*<* r>0)(ℤ.≤-reflexive $ ℤ.*-identityʳ n)-------------------------------------------------------------------------- Properties of sign predicatespositive⁻¹ : ∀ p → .{{Positive p}} → p > 0ℚᵘpositive⁻¹ (mkℚᵘ +[1+ n ] _) = *<* (ℤ.+<+ ℕ.z<s)nonNegative⁻¹ : ∀ p → .{{NonNegative p}} → p ≥ 0ℚᵘnonNegative⁻¹ (mkℚᵘ +0 _) = *≤* (ℤ.+≤+ ℕ.z≤n)nonNegative⁻¹ (mkℚᵘ +[1+ n ] _) = *≤* (ℤ.+≤+ ℕ.z≤n)negative⁻¹ : ∀ p → .{{Negative p}} → p < 0ℚᵘnegative⁻¹ (mkℚᵘ -[1+ n ] _) = *<* ℤ.-<+nonPositive⁻¹ : ∀ p → .{{NonPositive p}} → p ≤ 0ℚᵘnonPositive⁻¹ (mkℚᵘ +0 _) = *≤* (ℤ.+≤+ ℕ.z≤n)nonPositive⁻¹ (mkℚᵘ -[1+ n ] _) = *≤* ℤ.-≤+pos⇒nonNeg : ∀ p → .{{Positive p}} → NonNegative ppos⇒nonNeg (mkℚᵘ +0 _) = _pos⇒nonNeg (mkℚᵘ +[1+ n ] _) = _neg⇒nonPos : ∀ p → .{{Negative p}} → NonPositive pneg⇒nonPos (mkℚᵘ +0 _) = _neg⇒nonPos (mkℚᵘ -[1+ n ] _) = _neg<pos : ∀ p q → .{{Negative p}} → .{{Positive q}} → p < qneg<pos p q = <-trans (negative⁻¹ p) (positive⁻¹ q)pos⇒nonZero : ∀ p → .{{Positive p}} → NonZero ppos⇒nonZero (mkℚᵘ (+[1+ _ ]) _) = _nonNeg∧nonPos⇒0 : ∀ p → .{{NonNegative p}} → .{{NonPositive p}} → p ≃ 0ℚᵘnonNeg∧nonPos⇒0 (mkℚᵘ +0 _) = *≡* reflnonNeg<⇒pos : ∀ {p q} .{{_ : NonNegative p}} → p < q → Positive qnonNeg<⇒pos {p} p<q = positive (≤-<-trans (nonNegative⁻¹ p) p<q)nonNeg≤⇒nonNeg : ∀ {p q} .{{_ : NonNegative p}} → p ≤ q → NonNegative qnonNeg≤⇒nonNeg {p} p≤q = nonNegative (≤-trans (nonNegative⁻¹ p) p≤q)neg⇒nonZero : ∀ p → .{{Negative p}} → NonZero pneg⇒nonZero (mkℚᵘ (-[1+ _ ]) _) = _-------------------------------------------------------------------------- Properties of _+_-------------------------------------------------------------------------------------------------------------------------------------------------- Algebraic properties-- Congruence+-cong : Congruent₂ _≃_ _+_+-cong {x@record{}} {y@record{}} {u@record{}} {v@record{}} (*≡* ab′∼a′b) (*≡* cd′∼c′d) = *≡* (begin(↥x ℤ.* ↧u ℤ.+ ↥u ℤ.* ↧x) ℤ.* (↧y ℤ.* ↧v) ≡⟨ solve 6 (λ ↥x ↧x ↧y ↥u ↧u ↧v →(↥x :* ↧u :+ ↥u :* ↧x) :* (↧y :* ↧v) :=(↥x :* ↧y :* (↧u :* ↧v)) :+ ↥u :* ↧v :* (↧x :* ↧y))refl (↥ x) (↧ x) (↧ y) (↥ u) (↧ u) (↧ v) ⟩↥x ℤ.* ↧y ℤ.* (↧u ℤ.* ↧v) ℤ.+ ↥u ℤ.* ↧v ℤ.* (↧x ℤ.* ↧y) ≡⟨ cong₂ ℤ._+_ (cong (ℤ._* (↧u ℤ.* ↧v)) ab′∼a′b)(cong (ℤ._* (↧x ℤ.* ↧y)) cd′∼c′d) ⟩↥y ℤ.* ↧x ℤ.* (↧u ℤ.* ↧v) ℤ.+ ↥v ℤ.* ↧u ℤ.* (↧x ℤ.* ↧y) ≡⟨ solve 6 (λ ↧x ↥y ↧y ↧u ↥v ↧v →(↥y :* ↧x :* (↧u :* ↧v)) :+ ↥v :* ↧u :* (↧x :* ↧y) :=(↥y :* ↧v :+ ↥v :* ↧y) :* (↧x :* ↧u))refl (↧ x) (↥ y) (↧ y) (↧ u) (↥ v) (↧ v) ⟩(↥y ℤ.* ↧v ℤ.+ ↥v ℤ.* ↧y) ℤ.* (↧x ℤ.* ↧u) ∎)where↥x = ↥ x; ↧x = ↧ x; ↥y = ↥ y; ↧y = ↧ y; ↥u = ↥ u; ↧u = ↧ u; ↥v = ↥ v; ↧v = ↧ vopen ≡-Reasoningopen ℤ-solver+-congʳ : ∀ p → q ≃ r → p + q ≃ p + r+-congʳ p q≃r = +-cong (≃-refl {p}) q≃r+-congˡ : ∀ p → q ≃ r → q + p ≃ r + p+-congˡ p q≃r = +-cong q≃r (≃-refl {p})-- Associativity+-assoc-↥ : Associative (_≡_ on ↥_) _+_+-assoc-↥ p@record{} q@record{} r@record{} = solve 6 (λ ↥p ↧p ↥q ↧q ↥r ↧r →(↥p :* ↧q :+ ↥q :* ↧p) :* ↧r :+ ↥r :* (↧p :* ↧q) :=↥p :* (↧q :* ↧r) :+ (↥q :* ↧r :+ ↥r :* ↧q) :* ↧p)refl (↥ p) (↧ p) (↥ q) (↧ q) (↥ r) (↧ r)where open ℤ-solver+-assoc-↧ : Associative (_≡_ on ↧ₙ_) _+_+-assoc-↧ p@record{} q@record{} r@record{} = ℕ.*-assoc (↧ₙ p) (↧ₙ q) (↧ₙ r)+-assoc-≡ : Associative _≡_ _+_+-assoc-≡ p q r = ↥↧≡⇒≡ (+-assoc-↥ p q r) (+-assoc-↧ p q r)+-assoc : Associative _≃_ _+_+-assoc p q r = ≃-reflexive (+-assoc-≡ p q r)-- Commutativity+-comm-↥ : Commutative (_≡_ on ↥_) _+_+-comm-↥ p@record{} q@record{} = ℤ.+-comm (↥ p ℤ.* ↧ q) (↥ q ℤ.* ↧ p)+-comm-↧ : Commutative (_≡_ on ↧ₙ_) _+_+-comm-↧ p@record{} q@record{} = ℕ.*-comm (↧ₙ p) (↧ₙ q)+-comm-≡ : Commutative _≡_ _+_+-comm-≡ p q = ↥↧≡⇒≡ (+-comm-↥ p q) (+-comm-↧ p q)+-comm : Commutative _≃_ _+_+-comm p q = ≃-reflexive (+-comm-≡ p q)-- Identities+-identityˡ-↥ : LeftIdentity (_≡_ on ↥_) 0ℚᵘ _+_+-identityˡ-↥ p@record{} = begin0ℤ ℤ.* ↧ p ℤ.+ ↥ p ℤ.* 1ℤ ≡⟨ cong₂ ℤ._+_ (ℤ.*-zeroˡ (↧ p)) (ℤ.*-identityʳ (↥ p)) ⟩0ℤ ℤ.+ ↥ p ≡⟨ ℤ.+-identityˡ (↥ p) ⟩↥ p ∎ where open ≡-Reasoning+-identityˡ-↧ : LeftIdentity (_≡_ on ↧ₙ_) 0ℚᵘ _+_+-identityˡ-↧ p@record{} = ℕ.+-identityʳ (↧ₙ p)+-identityˡ-≡ : LeftIdentity _≡_ 0ℚᵘ _+_+-identityˡ-≡ p = ↥↧≡⇒≡ (+-identityˡ-↥ p) (+-identityˡ-↧ p)+-identityˡ : LeftIdentity _≃_ 0ℚᵘ _+_+-identityˡ p = ≃-reflexive (+-identityˡ-≡ p)+-identityʳ-≡ : RightIdentity _≡_ 0ℚᵘ _+_+-identityʳ-≡ = comm+idˡ⇒idʳ +-comm-≡ {e = 0ℚᵘ} +-identityˡ-≡+-identityʳ : RightIdentity _≃_ 0ℚᵘ _+_+-identityʳ p = ≃-reflexive (+-identityʳ-≡ p)+-identity-≡ : Identity _≡_ 0ℚᵘ _+_+-identity-≡ = +-identityˡ-≡ , +-identityʳ-≡+-identity : Identity _≃_ 0ℚᵘ _+_+-identity = +-identityˡ , +-identityʳ+-inverseˡ : LeftInverse _≃_ 0ℚᵘ -_ _+_+-inverseˡ p@record{} = *≡* let n = ↥ p; d = ↧ p in((ℤ.- n) ℤ.* d ℤ.+ n ℤ.* d) ℤ.* 1ℤ ≡⟨ ℤ.*-identityʳ ((ℤ.- n) ℤ.* d ℤ.+ n ℤ.* d) ⟩(ℤ.- n) ℤ.* d ℤ.+ n ℤ.* d ≡⟨ cong (ℤ._+ (n ℤ.* d)) (ℤ.neg-distribˡ-* n d) ⟨ℤ.- (n ℤ.* d) ℤ.+ n ℤ.* d ≡⟨ ℤ.+-inverseˡ (n ℤ.* d) ⟩0ℤ ∎ where open ≡-Reasoning+-inverseʳ : RightInverse _≃_ 0ℚᵘ -_ _+_+-inverseʳ p@record{} = *≡* let n = ↥ p; d = ↧ p in(n ℤ.* d ℤ.+ (ℤ.- n) ℤ.* d) ℤ.* 1ℤ ≡⟨ ℤ.*-identityʳ (n ℤ.* d ℤ.+ (ℤ.- n) ℤ.* d) ⟩n ℤ.* d ℤ.+ (ℤ.- n) ℤ.* d ≡⟨ cong (λ n+d → n ℤ.* d ℤ.+ n+d) (ℤ.neg-distribˡ-* n d) ⟨n ℤ.* d ℤ.+ ℤ.- (n ℤ.* d) ≡⟨ ℤ.+-inverseʳ (n ℤ.* d) ⟩0ℤ ∎ where open ≡-Reasoning+-inverse : Inverse _≃_ 0ℚᵘ -_ _+_+-inverse = +-inverseˡ , +-inverseʳ+-cancelˡ : ∀ {r p q} → r + p ≃ r + q → p ≃ q+-cancelˡ {r} {p} {q} r+p≃r+q = begin-equalityp ≃⟨ +-identityʳ p ⟨p + 0ℚᵘ ≃⟨ +-congʳ p (+-inverseʳ r) ⟨p + (r - r) ≃⟨ +-assoc p r (- r) ⟨(p + r) - r ≃⟨ +-congˡ (- r) (+-comm p r) ⟩(r + p) - r ≃⟨ +-congˡ (- r) r+p≃r+q ⟩(r + q) - r ≃⟨ +-congˡ (- r) (+-comm r q) ⟩(q + r) - r ≃⟨ +-assoc q r (- r) ⟩q + (r - r) ≃⟨ +-congʳ q (+-inverseʳ r) ⟩q + 0ℚᵘ ≃⟨ +-identityʳ q ⟩q ∎ where open ≤-Reasoning+-cancelʳ : ∀ {r p q} → p + r ≃ q + r → p ≃ q+-cancelʳ {r} {p} {q} p+r≃q+r = +-cancelˡ {r} $ begin-equalityr + p ≃⟨ +-comm r p ⟩p + r ≃⟨ p+r≃q+r ⟩q + r ≃⟨ +-comm q r ⟩r + q ∎ where open ≤-Reasoningp+p≃0⇒p≃0 : ∀ p → p + p ≃ 0ℚᵘ → p ≃ 0ℚᵘp+p≃0⇒p≃0 (mkℚᵘ ℤ.+0 _) (*≡* _) = *≡* refl-------------------------------------------------------------------------- Properties of _+_ and -_neg-distrib-+ : ∀ p q → - (p + q) ≡ (- p) + (- q)neg-distrib-+ p@record{} q@record{} = ↥↧≡⇒≡ (beginℤ.- (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) ≡⟨ ℤ.neg-distrib-+ (↥ p ℤ.* ↧ q) _ ⟩ℤ.- (↥ p ℤ.* ↧ q) ℤ.+ ℤ.- (↥ q ℤ.* ↧ p) ≡⟨ cong₂ ℤ._+_ (ℤ.neg-distribˡ-* (↥ p) _)(ℤ.neg-distribˡ-* (↥ q) _) ⟩(ℤ.- ↥ p) ℤ.* ↧ q ℤ.+ (ℤ.- ↥ q) ℤ.* ↧ p ∎) reflwhere open ≡-Reasoningp≃-p⇒p≃0 : ∀ p → p ≃ - p → p ≃ 0ℚᵘp≃-p⇒p≃0 p p≃-p = p+p≃0⇒p≃0 p (begin-equalityp + p ≃⟨ +-congʳ p p≃-p ⟩p - p ≃⟨ +-inverseʳ p ⟩0ℚᵘ ∎)where open ≤-Reasoning-------------------------------------------------------------------------- Properties of _+_ and _≤_privatelemma : ∀ r p q → (↥ r ℤ.* ↧ p ℤ.+ ↥ p ℤ.* ↧ r) ℤ.* (↧ r ℤ.* ↧ q)≡ (↥ r ℤ.* ↧ r) ℤ.* (↧ p ℤ.* ↧ q) ℤ.+ (↧ r ℤ.* ↧ r) ℤ.* (↥ p ℤ.* ↧ q)lemma r p q = solve 5 (λ ↥r ↧r ↧p ↥p ↧q →(↥r :* ↧p :+ ↥p :* ↧r) :* (↧r :* ↧q) :=(↥r :* ↧r) :* (↧p :* ↧q) :+ (↧r :* ↧r) :* (↥p :* ↧q))refl (↥ r) (↧ r) (↧ p) (↥ p) (↧ q)where open ℤ-solver+-monoʳ-≤ : ∀ r → (r +_) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ r@record{} {p@record{}} {q@record{}} (*≤* x≤y) = *≤* $ begin↥ (r + p) ℤ.* ↧ (r + q) ≡⟨ lemma r p q ⟩r₂ ℤ.* (↧ p ℤ.* ↧ q) ℤ.+ (↧ r ℤ.* ↧ r) ℤ.* (↥ p ℤ.* ↧ q) ≤⟨ leq ⟩r₂ ℤ.* (↧ q ℤ.* ↧ p) ℤ.+ (↧ r ℤ.* ↧ r) ℤ.* (↥ q ℤ.* ↧ p) ≡⟨ sym $ lemma r q p ⟩↥ (r + q) ℤ.* (↧ (r + p)) ∎whereopen ℤ.≤-Reasoning; r₂ = ↥ r ℤ.* ↧ rleq = ℤ.+-mono-≤(ℤ.≤-reflexive $ cong (r₂ ℤ.*_) (ℤ.*-comm (↧ p) (↧ q)))(ℤ.*-monoˡ-≤-nonNeg (↧ r ℤ.* ↧ r) x≤y)+-monoˡ-≤ : ∀ r → (_+ r) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ r {p} {q} rewrite +-comm-≡ p r | +-comm-≡ q r = +-monoʳ-≤ r+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-≤ {p} {q} {u} {v} p≤q u≤v = ≤-trans (+-monoˡ-≤ u p≤q) (+-monoʳ-≤ q u≤v)p≤q⇒p≤r+q : ∀ r .{{_ : NonNegative r}} → p ≤ q → p ≤ r + qp≤q⇒p≤r+q {p} {q} r p≤q = subst (_≤ r + q) (+-identityˡ-≡ p) (+-mono-≤ (nonNegative⁻¹ r) p≤q)p≤q+p : ∀ p q .{{_ : NonNegative q}} → p ≤ q + pp≤q+p p q = p≤q⇒p≤r+q q ≤-reflp≤p+q : ∀ p q .{{_ : NonNegative q}} → p ≤ p + qp≤p+q p q rewrite +-comm-≡ p q = p≤q+p p q-------------------------------------------------------------------------- Properties of _+_ and _<_+-monoʳ-< : ∀ r → (r +_) Preserves _<_ ⟶ _<_+-monoʳ-< r@record{} {p@record{}} {q@record{}} (*<* x<y) = *<* $ begin-strict↥ (r + p) ℤ.* (↧ (r + q)) ≡⟨ lemma r p q ⟩↥r↧r ℤ.* (↧ p ℤ.* ↧ q) ℤ.+ ↧r↧r ℤ.* (↥ p ℤ.* ↧ q) <⟨ leq ⟩↥r↧r ℤ.* (↧ q ℤ.* ↧ p) ℤ.+ ↧r↧r ℤ.* (↥ q ℤ.* ↧ p) ≡⟨ sym $ lemma r q p ⟩↥ (r + q) ℤ.* (↧ (r + p)) ∎whereopen ℤ.≤-Reasoning; ↥r↧r = ↥ r ℤ.* ↧ r; ↧r↧r = ↧ r ℤ.* ↧ rleq = ℤ.+-mono-≤-<(ℤ.≤-reflexive $ cong (↥r↧r ℤ.*_) (ℤ.*-comm (↧ p) (↧ q)))(ℤ.*-monoˡ-<-pos ↧r↧r x<y)+-monoˡ-< : ∀ r → (_+ r) Preserves _<_ ⟶ _<_+-monoˡ-< r {p} {q} rewrite +-comm-≡ p r | +-comm-≡ q r = +-monoʳ-< r+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-mono-< {p} {q} {u} {v} p<q u<v = <-trans (+-monoˡ-< u p<q) (+-monoʳ-< q u<v)+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-≤-< {p} {q} {r} p≤q q<r = ≤-<-trans (+-monoˡ-≤ r p≤q) (+-monoʳ-< q q<r)+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-<-≤ {p} {q} {r} p<q q≤r = <-≤-trans (+-monoˡ-< r p<q) (+-monoʳ-≤ q q≤r)-------------------------------------------------------------------------- Properties of _+_ and predicatespos+pos⇒pos : ∀ p .{{_ : Positive p}} →∀ q .{{_ : Positive q}} →Positive (p + q)pos+pos⇒pos p q = positive (+-mono-< (positive⁻¹ p) (positive⁻¹ q))nonNeg+nonNeg⇒nonNeg : ∀ p .{{_ : NonNegative p}} →∀ q .{{_ : NonNegative q}} →NonNegative (p + q)nonNeg+nonNeg⇒nonNeg p q = nonNegative(+-mono-≤ (nonNegative⁻¹ p) (nonNegative⁻¹ q))-------------------------------------------------------------------------- Properties of _-_+-minus-telescope : ∀ p q r → (p - q) + (q - r) ≃ p - r+-minus-telescope p q r = begin-equality(p - q) + (q - r) ≃⟨ ≃-sym (+-assoc (p - q) q (- r)) ⟩(p - q) + q - r ≃⟨ +-congˡ (- r) (+-assoc p (- q) q) ⟩(p + (- q + q)) - r ≃⟨ +-congˡ (- r) (+-congʳ p (+-inverseˡ q)) ⟩(p + 0ℚᵘ) - r ≃⟨ +-congˡ (- r) (+-identityʳ p) ⟩p - r ∎ where open ≤-Reasoningp≃q⇒p-q≃0 : ∀ p q → p ≃ q → p - q ≃ 0ℚᵘp≃q⇒p-q≃0 p q p≃q = begin-equalityp - q ≃⟨ +-congˡ (- q) p≃q ⟩q - q ≃⟨ +-inverseʳ q ⟩0ℚᵘ ∎ where open ≤-Reasoningp-q≃0⇒p≃q : ∀ p q → p - q ≃ 0ℚᵘ → p ≃ qp-q≃0⇒p≃q p q p-q≃0 = begin-equalityp ≡⟨ +-identityʳ-≡ p ⟨p + 0ℚᵘ ≃⟨ +-congʳ p (≃-sym (+-inverseˡ q)) ⟩p + (- q + q) ≡⟨ +-assoc-≡ p (- q) q ⟨(p - q) + q ≃⟨ +-congˡ q p-q≃0 ⟩0ℚᵘ + q ≡⟨ +-identityˡ-≡ q ⟩q ∎ where open ≤-Reasoningneg-mono-≤ : -_ Preserves _≤_ ⟶ _≥_neg-mono-≤ {p@record{}} {q@record{}} (*≤* p≤q) = *≤* $ beginℤ.- ↥ q ℤ.* ↧ p ≡⟨ ℤ.neg-distribˡ-* (↥ q) (↧ p) ⟨ℤ.- (↥ q ℤ.* ↧ p) ≤⟨ ℤ.neg-mono-≤ p≤q ⟩ℤ.- (↥ p ℤ.* ↧ q) ≡⟨ ℤ.neg-distribˡ-* (↥ p) (↧ q) ⟩ℤ.- ↥ p ℤ.* ↧ q ∎ where open ℤ.≤-Reasoningneg-cancel-≤ : ∀ {p q} → - p ≤ - q → q ≤ pneg-cancel-≤ {p@record{}} {q@record{}} (*≤* -↥p↧q≤-↥q↧p) = *≤* $ begin↥ q ℤ.* ↧ p ≡⟨ ℤ.neg-involutive (↥ q ℤ.* ↧ p) ⟨ℤ.- ℤ.- (↥ q ℤ.* ↧ p) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ q) (↧ p)) ⟩ℤ.- ((ℤ.- ↥ q) ℤ.* ↧ p) ≤⟨ ℤ.neg-mono-≤ -↥p↧q≤-↥q↧p ⟩ℤ.- ((ℤ.- ↥ p) ℤ.* ↧ q) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ p) (↧ q)) ⟨ℤ.- ℤ.- (↥ p ℤ.* ↧ q) ≡⟨ ℤ.neg-involutive (↥ p ℤ.* ↧ q) ⟩↥ p ℤ.* ↧ q ∎whereopen ℤ.≤-Reasoningp≤q⇒p-q≤0 : ∀ {p q} → p ≤ q → p - q ≤ 0ℚᵘp≤q⇒p-q≤0 {p} {q} p≤q = beginp - q ≤⟨ +-monoˡ-≤ (- q) p≤q ⟩q - q ≃⟨ +-inverseʳ q ⟩0ℚᵘ ∎ where open ≤-Reasoningp-q≤0⇒p≤q : ∀ {p q} → p - q ≤ 0ℚᵘ → p ≤ qp-q≤0⇒p≤q {p} {q} p-q≤0 = beginp ≡⟨ +-identityʳ-≡ p ⟨p + 0ℚᵘ ≃⟨ +-congʳ p (≃-sym (+-inverseˡ q)) ⟩p + (- q + q) ≡⟨ +-assoc-≡ p (- q) q ⟨(p - q) + q ≤⟨ +-monoˡ-≤ q p-q≤0 ⟩0ℚᵘ + q ≡⟨ +-identityˡ-≡ q ⟩q ∎ where open ≤-Reasoningp≤q⇒0≤q-p : ∀ {p q} → p ≤ q → 0ℚᵘ ≤ q - pp≤q⇒0≤q-p {p} {q} p≤q = begin0ℚᵘ ≃⟨ ≃-sym (+-inverseʳ p) ⟩p - p ≤⟨ +-monoˡ-≤ (- p) p≤q ⟩q - p ∎ where open ≤-Reasoning0≤q-p⇒p≤q : ∀ {p q} → 0ℚᵘ ≤ q - p → p ≤ q0≤q-p⇒p≤q {p} {q} 0≤p-q = beginp ≡⟨ +-identityˡ-≡ p ⟨0ℚᵘ + p ≤⟨ +-monoˡ-≤ p 0≤p-q ⟩q - p + p ≡⟨ +-assoc-≡ q (- p) p ⟩q + (- p + p) ≃⟨ +-congʳ q (+-inverseˡ p) ⟩q + 0ℚᵘ ≡⟨ +-identityʳ-≡ q ⟩q ∎ where open ≤-Reasoning-------------------------------------------------------------------------- Algebraic structures+-isMagma : IsMagma _≃_ _+_+-isMagma = record{ isEquivalence = ≃-isEquivalence; ∙-cong = +-cong}+-isSemigroup : IsSemigroup _≃_ _+_+-isSemigroup = record{ isMagma = +-isMagma; assoc = +-assoc}+-0-isMonoid : IsMonoid _≃_ _+_ 0ℚᵘ+-0-isMonoid = record{ isSemigroup = +-isSemigroup; identity = +-identity}+-0-isCommutativeMonoid : IsCommutativeMonoid _≃_ _+_ 0ℚᵘ+-0-isCommutativeMonoid = record{ isMonoid = +-0-isMonoid; comm = +-comm}+-0-isGroup : IsGroup _≃_ _+_ 0ℚᵘ (-_)+-0-isGroup = record{ isMonoid = +-0-isMonoid; inverse = +-inverse; ⁻¹-cong = -‿cong}+-0-isAbelianGroup : IsAbelianGroup _≃_ _+_ 0ℚᵘ (-_)+-0-isAbelianGroup = record{ isGroup = +-0-isGroup; comm = +-comm}-------------------------------------------------------------------------- Algebraic bundles+-magma : Magma 0ℓ 0ℓ+-magma = record{ isMagma = +-isMagma}+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ isMonoid = +-0-isMonoid}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}+-0-group : Group 0ℓ 0ℓ+-0-group = record{ isGroup = +-0-isGroup}+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ+-0-abelianGroup = record{ isAbelianGroup = +-0-isAbelianGroup}-------------------------------------------------------------------------- Properties of _*_-------------------------------------------------------------------------------------------------------------------------------------------------- Algebraic properties*-cong : Congruent₂ _≃_ _*_*-cong {x@record{}} {y@record{}} {u@record{}} {v@record{}} (*≡* ↥x↧y≡↥y↧x) (*≡* ↥u↧v≡↥v↧u) = *≡* (begin(↥ x ℤ.* ↥ u) ℤ.* (↧ y ℤ.* ↧ v) ≡⟨ solve 4 (λ ↥x ↥u ↧y ↧v →(↥x :* ↥u) :* (↧y :* ↧v) :=(↥u :* ↧v) :* (↥x :* ↧y))refl (↥ x) (↥ u) (↧ y) (↧ v) ⟩(↥ u ℤ.* ↧ v) ℤ.* (↥ x ℤ.* ↧ y) ≡⟨ cong₂ ℤ._*_ ↥u↧v≡↥v↧u ↥x↧y≡↥y↧x ⟩(↥ v ℤ.* ↧ u) ℤ.* (↥ y ℤ.* ↧ x) ≡⟨ solve 4 (λ ↥v ↧u ↥y ↧x →(↥v :* ↧u) :* (↥y :* ↧x) :=(↥y :* ↥v) :* (↧x :* ↧u))refl (↥ v) (↧ u) (↥ y) (↧ x) ⟩(↥ y ℤ.* ↥ v) ℤ.* (↧ x ℤ.* ↧ u) ∎)where open ≡-Reasoning; open ℤ-solver*-congˡ : LeftCongruent _≃_ _*_*-congˡ {p} q≃r = *-cong (≃-refl {p}) q≃r*-congʳ : RightCongruent _≃_ _*_*-congʳ {p} q≃r = *-cong q≃r (≃-refl {p})-- Associativity*-assoc-↥ : Associative (_≡_ on ↥_) _*_*-assoc-↥ p@record{} q@record{} r@record{} = ℤ.*-assoc (↥ p) (↥ q) (↥ r)*-assoc-↧ : Associative (_≡_ on ↧ₙ_) _*_*-assoc-↧ p@record{} q@record{} r@record{} = ℕ.*-assoc (↧ₙ p) (↧ₙ q) (↧ₙ r)*-assoc-≡ : Associative _≡_ _*_*-assoc-≡ p q r = ↥↧≡⇒≡ (*-assoc-↥ p q r) (*-assoc-↧ p q r)*-assoc : Associative _≃_ _*_*-assoc p q r = ≃-reflexive (*-assoc-≡ p q r)-- Commutativity*-comm-↥ : Commutative (_≡_ on ↥_) _*_*-comm-↥ p@record{} q@record{} = ℤ.*-comm (↥ p) (↥ q)*-comm-↧ : Commutative (_≡_ on ↧ₙ_) _*_*-comm-↧ p@record{} q@record{} = ℕ.*-comm (↧ₙ p) (↧ₙ q)*-comm-≡ : Commutative _≡_ _*_*-comm-≡ p q = ↥↧≡⇒≡ (*-comm-↥ p q) (*-comm-↧ p q)*-comm : Commutative _≃_ _*_*-comm p q = ≃-reflexive (*-comm-≡ p q)-- Identities*-identityˡ-≡ : LeftIdentity _≡_ 1ℚᵘ _*_*-identityˡ-≡ p@record{} = ↥↧≡⇒≡ (ℤ.*-identityˡ (↥ p)) (ℕ.+-identityʳ (↧ₙ p))*-identityʳ-≡ : RightIdentity _≡_ 1ℚᵘ _*_*-identityʳ-≡ = comm+idˡ⇒idʳ *-comm-≡ {e = 1ℚᵘ} *-identityˡ-≡*-identity-≡ : Identity _≡_ 1ℚᵘ _*_*-identity-≡ = *-identityˡ-≡ , *-identityʳ-≡*-identityˡ : LeftIdentity _≃_ 1ℚᵘ _*_*-identityˡ p = ≃-reflexive (*-identityˡ-≡ p)*-identityʳ : RightIdentity _≃_ 1ℚᵘ _*_*-identityʳ p = ≃-reflexive (*-identityʳ-≡ p)*-identity : Identity _≃_ 1ℚᵘ _*_*-identity = *-identityˡ , *-identityʳ*-inverseˡ : ∀ p .{{_ : NonZero p}} → (1/ p) * p ≃ 1ℚᵘ*-inverseˡ p@(mkℚᵘ -[1+ n ] d) = *-inverseˡ (mkℚᵘ +[1+ n ] d)*-inverseˡ p@(mkℚᵘ +[1+ n ] d) = *≡* $ cong +[1+_] $ begin(n ℕ.+ d ℕ.* suc n) ℕ.* 1 ≡⟨ ℕ.*-identityʳ _ ⟩n ℕ.+ d ℕ.* suc n ≡⟨ cong (n ℕ.+_) (ℕ.*-suc d n) ⟩n ℕ.+ (d ℕ.+ d ℕ.* n) ≡⟨ trans (sym $ ℕ.+-assoc n d _) (trans(cong₂ ℕ._+_ (ℕ.+-comm n d) (ℕ.*-comm d n))(ℕ.+-assoc d n _)) ⟩d ℕ.+ (n ℕ.+ n ℕ.* d) ≡⟨ cong (d ℕ.+_) (sym (ℕ.*-suc n d)) ⟩d ℕ.+ n ℕ.* suc d ≡⟨ ℕ.+-identityʳ _ ⟨d ℕ.+ n ℕ.* suc d ℕ.+ 0 ∎where open ≡-Reasoning*-inverseʳ : ∀ p .{{_ : NonZero p}} → p * 1/ p ≃ 1ℚᵘ*-inverseʳ p = ≃-trans (*-comm p (1/ p)) (*-inverseˡ p)≄⇒invertible : p ≄ q → Invertible _≃_ 1ℚᵘ _*_ (p - q)≄⇒invertible {p} {q} p≄q = _ , *-inverseˡ (p - q) , *-inverseʳ (p - q)where instance_ : NonZero (p - q)_ = ≢-nonZero (p≄q ∘ p-q≃0⇒p≃q p q)*-zeroˡ : LeftZero _≃_ 0ℚᵘ _*_*-zeroˡ p@record{} = *≡* refl*-zeroʳ : RightZero _≃_ 0ℚᵘ _*_*-zeroʳ = Consequences.comm+zeˡ⇒zeʳ ≃-setoid *-comm *-zeroˡ*-zero : Zero _≃_ 0ℚᵘ _*_*-zero = *-zeroˡ , *-zeroʳinvertible⇒≄ : Invertible _≃_ 1ℚᵘ _*_ (p - q) → p ≄ qinvertible⇒≄ {p} {q} (1/p-q , 1/x*x≃1 , x*1/x≃1) p≃q = 0≄1 (begin0ℚᵘ ≈⟨ *-zeroˡ 1/p-q ⟨0ℚᵘ * 1/p-q ≈⟨ *-congʳ (p≃q⇒p-q≃0 p q p≃q) ⟨(p - q) * 1/p-q ≈⟨ x*1/x≃1 ⟩1ℚᵘ ∎)where open ≃-Reasoning*-distribˡ-+ : _DistributesOverˡ_ _≃_ _*_ _+_*-distribˡ-+ p@record{} q@record{} r@record{} =let ↥p = ↥ p; ↧p = ↧ p↥q = ↥ q; ↧q = ↧ q↥r = ↥ r; ↧r = ↧ req : (↥p ℤ.* (↥q ℤ.* ↧r ℤ.+ ↥r ℤ.* ↧q)) ℤ.* (↧p ℤ.* ↧q ℤ.* (↧p ℤ.* ↧r)) ≡(↥p ℤ.* ↥q ℤ.* (↧p ℤ.* ↧r) ℤ.+ ↥p ℤ.* ↥r ℤ.* (↧p ℤ.* ↧q)) ℤ.* (↧p ℤ.* (↧q ℤ.* ↧r))eq = solve 6 (λ ↥p ↧p ↥q d e f →(↥p :* (↥q :* f :+ e :* d)) :* (↧p :* d :* (↧p :* f)) :=(↥p :* ↥q :* (↧p :* f) :+ ↥p :* e :* (↧p :* d)) :* (↧p :* (d :* f)))refl ↥p ↧p ↥q ↧q ↥r ↧rin *≡* eq where open ℤ-solver*-distribʳ-+ : _DistributesOverʳ_ _≃_ _*_ _+_*-distribʳ-+ = Consequences.comm+distrˡ⇒distrʳ ≃-setoid +-cong *-comm *-distribˡ-+*-distrib-+ : _DistributesOver_ _≃_ _*_ _+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+-------------------------------------------------------------------------- Properties of _*_ and -_neg-distribˡ-* : ∀ p q → - (p * q) ≃ - p * qneg-distribˡ-* p@record{} q@record{} =*≡* $ cong (ℤ._* (↧ p ℤ.* ↧ q)) $ ℤ.neg-distribˡ-* (↥ p) (↥ q)neg-distribʳ-* : ∀ p q → - (p * q) ≃ p * - qneg-distribʳ-* p@record{} q@record{} =*≡* $ cong (ℤ._* (↧ p ℤ.* ↧ q)) $ ℤ.neg-distribʳ-* (↥ p) (↥ q)-------------------------------------------------------------------------- Properties of _*_ and _/_*-cancelˡ-/ : ∀ p {q r} .{{_ : ℕ.NonZero r}} .{{_ : ℕ.NonZero (p ℕ.* r)}} →((ℤ.+ p ℤ.* q) / (p ℕ.* r)) ≃ (q / r)*-cancelˡ-/ p {q} {r} = *≡* (begin-equality(↥ ((ℤ.+ p ℤ.* q) / (p ℕ.* r))) ℤ.* (↧ (q / r)) ≡⟨ cong (ℤ._* ↧ (q / r)) (↥[n/d]≡n (ℤ.+ p ℤ.* q) (p ℕ.* r)) ⟩(ℤ.+ p ℤ.* q) ℤ.* (↧ (q / r)) ≡⟨ cong ((ℤ.+ p ℤ.* q) ℤ.*_) (↧[n/d]≡d q r) ⟩(ℤ.+ p ℤ.* q) ℤ.* ℤ.+ r ≡⟨ xy∙z≈y∙xz (ℤ.+ p) q (ℤ.+ r) ⟩(q ℤ.* (ℤ.+ p ℤ.* ℤ.+ r)) ≡⟨ cong (ℤ._* (ℤ.+ p ℤ.* ℤ.+ r)) (↥[n/d]≡n q r) ⟨(↥ (q / r)) ℤ.* (ℤ.+ p ℤ.* ℤ.+ r) ≡⟨ cong (↥ (q / r) ℤ.*_) (ℤ.pos-* p r) ⟨(↥ (q / r)) ℤ.* (ℤ.+ (p ℕ.* r)) ≡⟨ cong (↥ (q / r) ℤ.*_) (↧[n/d]≡d (ℤ.+ p ℤ.* q) (p ℕ.* r)) ⟨(↥ (q / r)) ℤ.* (↧ ((ℤ.+ p ℤ.* q) / (p ℕ.* r))) ∎)where open ℤ.≤-Reasoning*-cancelʳ-/ : ∀ p {q r} .{{_ : ℕ.NonZero r}} .{{_ : ℕ.NonZero (r ℕ.* p)}} →((q ℤ.* ℤ.+ p) / (r ℕ.* p)) ≃ (q / r)*-cancelʳ-/ p {q} {r} rewrite ℕ.*-comm r p | ℤ.*-comm q (ℤ.+ p) = *-cancelˡ-/ p-------------------------------------------------------------------------- Properties of _*_ and _≤_privatereorder₁ : ∀ a b c d → a ℤ.* b ℤ.* (c ℤ.* d) ≡ a ℤ.* c ℤ.* b ℤ.* dreorder₁ = solve 4 (λ a b c d → (a :* b) :* (c :* d) := (a :* c) :* b :* d) reflwhere open ℤ-solverreorder₂ : ∀ a b c d → a ℤ.* b ℤ.* (c ℤ.* d) ≡ a ℤ.* c ℤ.* (b ℤ.* d)reorder₂ = solve 4 (λ a b c d → (a :* b) :* (c :* d) := (a :* c) :* (b :* d)) reflwhere open ℤ-solver+▹-nonNeg : ∀ n → ℤ.NonNegative (Sign.+ ℤ.◃ n)+▹-nonNeg 0 = _+▹-nonNeg (suc _) = _*-cancelʳ-≤-pos : ∀ r .{{_ : Positive r}} → p * r ≤ q * r → p ≤ q*-cancelʳ-≤-pos {p@record{}} {q@record{}} r@(mkℚᵘ +[1+ _ ] _) (*≤* x≤y) =*≤* $ ℤ.*-cancelʳ-≤-pos _ _ (↥ r ℤ.* ↧ r) $ begin(↥ p ℤ.* ↧ q) ℤ.* (↥ r ℤ.* ↧ r) ≡⟨ reorder₂ (↥ p) _ _ (↧ r) ⟩(↥ p ℤ.* ↥ r) ℤ.* (↧ q ℤ.* ↧ r) ≤⟨ x≤y ⟩(↥ q ℤ.* ↥ r) ℤ.* (↧ p ℤ.* ↧ r) ≡⟨ reorder₂ (↥ q) _ _ (↧ r) ⟩(↥ q ℤ.* ↧ p) ℤ.* (↥ r ℤ.* ↧ r) ∎ where open ℤ.≤-Reasoning*-cancelˡ-≤-pos : ∀ r .{{_ : Positive r}} → r * p ≤ r * q → p ≤ q*-cancelˡ-≤-pos {p} {q} r rewrite *-comm-≡ r p | *-comm-≡ r q = *-cancelʳ-≤-pos r*-cancelʳ-≤-neg : ∀ r .{{_ : Negative r}} → p * r ≤ q * r → q ≤ p*-cancelʳ-≤-neg {p} {q} r@(mkℚᵘ -[1+ _ ] _) pr≤qr = neg-cancel-≤ (*-cancelʳ-≤-pos (- r) (begin- p * - r ≃⟨ neg-distribˡ-* p (- r) ⟨- (p * - r) ≃⟨ -‿cong (neg-distribʳ-* p r) ⟨- - (p * r) ≃⟨ neg-involutive (p * r) ⟩p * r ≤⟨ pr≤qr ⟩q * r ≃⟨ neg-involutive (q * r) ⟨- - (q * r) ≃⟨ -‿cong (neg-distribʳ-* q r) ⟩- (q * - r) ≃⟨ neg-distribˡ-* q (- r) ⟩- q * - r ∎))where open ≤-Reasoning*-cancelˡ-≤-neg : ∀ r .{{_ : Negative r}} → r * p ≤ r * q → q ≤ p*-cancelˡ-≤-neg {p} {q} r rewrite *-comm-≡ r p | *-comm-≡ r q = *-cancelʳ-≤-neg r*-monoˡ-≤-nonNeg : ∀ r .{{_ : NonNegative r}} → (_* r) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg r@(mkℚᵘ (ℤ.+ n) _) {p@record{}} {q@record{}} (*≤* x<y) = *≤* $ begin↥ p ℤ.* ↥ r ℤ.* (↧ q ℤ.* ↧ r) ≡⟨ reorder₂ (↥ p) _ _ _ ⟩l₁ ℤ.* (ℤ.+ n ℤ.* ↧ r) ≡⟨ cong (l₁ ℤ.*_) (ℤ.pos-* n _) ⟨l₁ ℤ.* ℤ.+ (n ℕ.* ↧ₙ r) ≤⟨ ℤ.*-monoʳ-≤-nonNeg (ℤ.+ (n ℕ.* ↧ₙ r)) x<y ⟩l₂ ℤ.* ℤ.+ (n ℕ.* ↧ₙ r) ≡⟨ cong (l₂ ℤ.*_) (ℤ.pos-* n _) ⟩l₂ ℤ.* (ℤ.+ n ℤ.* ↧ r) ≡⟨ reorder₂ (↥ q) _ _ _ ⟩↥ q ℤ.* ↥ r ℤ.* (↧ p ℤ.* ↧ r) ∎where open ℤ.≤-Reasoning; l₁ = ↥ p ℤ.* ↧ q ; l₂ = ↥ q ℤ.* ↧ p*-monoʳ-≤-nonNeg : ∀ r .{{_ : NonNegative r}} → (r *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonNeg r {p} {q} rewrite *-comm-≡ r p | *-comm-≡ r q = *-monoˡ-≤-nonNeg r*-mono-≤-nonNeg : ∀ {p q r s} .{{_ : NonNegative p}} .{{_ : NonNegative r}} →p ≤ q → r ≤ s → p * r ≤ q * s*-mono-≤-nonNeg {p} {q} {r} {s} p≤q r≤s = beginp * r ≤⟨ *-monoˡ-≤-nonNeg r p≤q ⟩q * r ≤⟨ *-monoʳ-≤-nonNeg q {{nonNeg≤⇒nonNeg p≤q}} r≤s ⟩q * s ∎where open ≤-Reasoning*-monoˡ-≤-nonPos : ∀ r .{{_ : NonPositive r}} → (_* r) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-nonPos r {p} {q} p≤q = beginq * r ≃⟨ neg-involutive (q * r) ⟨- - (q * r) ≃⟨ -‿cong (neg-distribʳ-* q r) ⟩- (q * - r) ≤⟨ neg-mono-≤ (*-monoˡ-≤-nonNeg (- r) {{ -r≥0}} p≤q) ⟩- (p * - r) ≃⟨ -‿cong (neg-distribʳ-* p r) ⟨- - (p * r) ≃⟨ neg-involutive (p * r) ⟩p * r ∎where open ≤-Reasoning; -r≥0 = nonNegative (neg-mono-≤ (nonPositive⁻¹ r))*-monoʳ-≤-nonPos : ∀ r .{{_ : NonPositive r}} → (r *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos r {p} {q} rewrite *-comm-≡ r q | *-comm-≡ r p = *-monoˡ-≤-nonPos r-------------------------------------------------------------------------- Properties of _*_ and _<_*-monoˡ-<-pos : ∀ r .{{_ : Positive r}} → (_* r) Preserves _<_ ⟶ _<_*-monoˡ-<-pos r@record{} {p@record{}} {q@record{}} (*<* x<y) = *<* $ begin-strict↥ p ℤ.* ↥ r ℤ.* (↧ q ℤ.* ↧ r) ≡⟨ reorder₁ (↥ p) _ _ _ ⟩↥ p ℤ.* ↧ q ℤ.* ↥ r ℤ.* ↧ r <⟨ ℤ.*-monoʳ-<-pos (↧ r) (ℤ.*-monoʳ-<-pos (↥ r) x<y) ⟩↥ q ℤ.* ↧ p ℤ.* ↥ r ℤ.* ↧ r ≡⟨ reorder₁ (↥ q) _ _ _ ⟨↥ q ℤ.* ↥ r ℤ.* (↧ p ℤ.* ↧ r) ∎ where open ℤ.≤-Reasoning*-monoʳ-<-pos : ∀ r .{{_ : Positive r}} → (r *_) Preserves _<_ ⟶ _<_*-monoʳ-<-pos r {p} {q} rewrite *-comm-≡ r p | *-comm-≡ r q = *-monoˡ-<-pos r*-mono-<-nonNeg : ∀ {p q r s} .{{_ : NonNegative p}} .{{_ : NonNegative r}} →p < q → r < s → p * r < q * s*-mono-<-nonNeg {p} {q} {r} {s} p<q r<s = begin-strictp * r ≤⟨ *-monoˡ-≤-nonNeg r (<⇒≤ p<q) ⟩q * r <⟨ *-monoʳ-<-pos q {{nonNeg<⇒pos p<q}} r<s ⟩q * s ∎where open ≤-Reasoning*-cancelʳ-<-nonNeg : ∀ r .{{_ : NonNegative r}} → p * r < q * r → p < q*-cancelʳ-<-nonNeg {p@record{}} {q@record{}} r@(mkℚᵘ (ℤ.+ _) _) (*<* x<y) =*<* $ ℤ.*-cancelʳ-<-nonNeg (↥ r ℤ.* ↧ r) {{+▹-nonNeg _}} $ begin-strict(↥ p ℤ.* ↧ q) ℤ.* (↥ r ℤ.* ↧ r) ≡⟨ reorder₂ (↥ p) _ _ (↧ r) ⟩(↥ p ℤ.* ↥ r) ℤ.* (↧ q ℤ.* ↧ r) <⟨ x<y ⟩(↥ q ℤ.* ↥ r) ℤ.* (↧ p ℤ.* ↧ r) ≡⟨ reorder₂ (↥ q) _ _ (↧ r) ⟩(↥ q ℤ.* ↧ p) ℤ.* (↥ r ℤ.* ↧ r) ∎ where open ℤ.≤-Reasoning*-cancelˡ-<-nonNeg : ∀ r .{{_ : NonNegative r}} → r * p < r * q → p < q*-cancelˡ-<-nonNeg {p} {q} r rewrite *-comm-≡ r p | *-comm-≡ r q = *-cancelʳ-<-nonNeg r*-monoˡ-<-neg : ∀ r .{{_ : Negative r}} → (_* r) Preserves _<_ ⟶ _>_*-monoˡ-<-neg r {p} {q} p<q = begin-strictq * r ≃⟨ neg-involutive (q * r) ⟨- - (q * r) ≃⟨ -‿cong (neg-distribʳ-* q r) ⟩- (q * - r) <⟨ neg-mono-< (*-monoˡ-<-pos (- r) {{ -r>0}} p<q) ⟩- (p * - r) ≃⟨ -‿cong (neg-distribʳ-* p r) ⟨- - (p * r) ≃⟨ neg-involutive (p * r) ⟩p * r ∎where open ≤-Reasoning; -r>0 = positive (neg-mono-< (negative⁻¹ r))*-monoʳ-<-neg : ∀ r .{{_ : Negative r}} → (r *_) Preserves _<_ ⟶ _>_*-monoʳ-<-neg r {p} {q} rewrite *-comm-≡ r q | *-comm-≡ r p = *-monoˡ-<-neg r*-cancelˡ-<-nonPos : ∀ r .{{_ : NonPositive r}} → r * p < r * q → q < p*-cancelˡ-<-nonPos {p} {q} r rp<rq =*-cancelˡ-<-nonNeg (- r) {{ -r≥0}} $ begin-strict- r * q ≃⟨ neg-distribˡ-* r q ⟨- (r * q) <⟨ neg-mono-< rp<rq ⟩- (r * p) ≃⟨ neg-distribˡ-* r p ⟩- r * p ∎where open ≤-Reasoning; -r≥0 = nonNegative (neg-mono-≤ (nonPositive⁻¹ r))*-cancelʳ-<-nonPos : ∀ r .{{_ : NonPositive r}} → p * r < q * r → q < p*-cancelʳ-<-nonPos {p} {q} r rewrite *-comm-≡ p r | *-comm-≡ q r = *-cancelˡ-<-nonPos r-------------------------------------------------------------------------- Properties of _*_ and predicatespos*pos⇒pos : ∀ p .{{_ : Positive p}} →∀ q .{{_ : Positive q}} →Positive (p * q)pos*pos⇒pos p q = positive(*-mono-<-nonNeg (positive⁻¹ p) (positive⁻¹ q))nonNeg*nonNeg⇒nonNeg : ∀ p .{{_ : NonNegative p}} →∀ q .{{_ : NonNegative q}} →NonNegative (p * q)nonNeg*nonNeg⇒nonNeg p q = nonNegative(*-mono-≤-nonNeg (nonNegative⁻¹ p) (nonNegative⁻¹ q))-------------------------------------------------------------------------- Algebraic structures*-isMagma : IsMagma _≃_ _*_*-isMagma = record{ isEquivalence = ≃-isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup _≃_ _*_*-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-1-isMonoid : IsMonoid _≃_ _*_ 1ℚᵘ*-1-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}*-1-isCommutativeMonoid : IsCommutativeMonoid _≃_ _*_ 1ℚᵘ*-1-isCommutativeMonoid = record{ isMonoid = *-1-isMonoid; comm = *-comm}+-*-isRing : IsRing _≃_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-isRing = record{ +-isAbelianGroup = +-0-isAbelianGroup; *-cong = *-cong; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}+-*-isCommutativeRing : IsCommutativeRing _≃_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-isCommutativeRing = record{ isRing = +-*-isRing; *-comm = *-comm}+-*-isHeytingCommutativeRing : IsHeytingCommutativeRing _≃_ _≄_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-isHeytingCommutativeRing = record{ isCommutativeRing = +-*-isCommutativeRing; isApartnessRelation = ≄-isApartnessRelation; #⇒invertible = ≄⇒invertible; invertible⇒# = invertible⇒≄}+-*-isHeytingField : IsHeytingField _≃_ _≄_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-isHeytingField = record{ isHeytingCommutativeRing = +-*-isHeytingCommutativeRing; tight = ≄-tight}-------------------------------------------------------------------------- Algebraic bundles*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-ring : Ring 0ℓ 0ℓ+-*-ring = record{ isRing = +-*-isRing}+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ+-*-commutativeRing = record{ isCommutativeRing = +-*-isCommutativeRing}+-*-heytingCommutativeRing : HeytingCommutativeRing 0ℓ 0ℓ 0ℓ+-*-heytingCommutativeRing = record{ isHeytingCommutativeRing = +-*-isHeytingCommutativeRing}+-*-heytingField : HeytingField 0ℓ 0ℓ 0ℓ+-*-heytingField = record{ isHeytingField = +-*-isHeytingField}-------------------------------------------------------------------------- Properties of 1/_------------------------------------------------------------------------privatep>1⇒p≢0 : p > 1ℚᵘ → NonZero pp>1⇒p≢0 {p} p>1 = pos⇒nonZero p {{positive (<-trans (*<* (ℤ.+<+ ℕ.≤-refl)) p>1)}}1/nonZero⇒nonZero : ∀ p .{{_ : NonZero p}} → NonZero (1/ p)1/nonZero⇒nonZero (mkℚᵘ (+[1+ _ ]) _) = _1/nonZero⇒nonZero (mkℚᵘ (-[1+ _ ]) _) = _1/-involutive-≡ : ∀ p .{{_ : NonZero p}} →(1/ (1/ p)) {{1/nonZero⇒nonZero p}} ≡ p1/-involutive-≡ (mkℚᵘ +[1+ n ] d-1) = refl1/-involutive-≡ (mkℚᵘ -[1+ n ] d-1) = refl1/-involutive : ∀ p .{{_ : NonZero p}} →(1/ (1/ p)) {{1/nonZero⇒nonZero p}} ≃ p1/-involutive p = ≃-reflexive (1/-involutive-≡ p)1/pos⇒pos : ∀ p .{{p>0 : Positive p}} → Positive ((1/ p) {{pos⇒nonZero p}})1/pos⇒pos (mkℚᵘ +[1+ n ] d-1) = _1/neg⇒neg : ∀ p .{{p<0 : Negative p}} → Negative ((1/ p) {{neg⇒nonZero p}})1/neg⇒neg (mkℚᵘ -[1+ n ] d-1) = _p>1⇒1/p<1 : ∀ {p} → (p>1 : p > 1ℚᵘ) → (1/ p) {{p>1⇒p≢0 p>1}} < 1ℚᵘp>1⇒1/p<1 {p} p>1 = lemma′ p (p>1⇒p≢0 p>1) p>1wherelemma′ : ∀ p p≢0 → p > 1ℚᵘ → (1/ p) {{p≢0}} < 1ℚᵘlemma′ (mkℚᵘ n@(+[1+ _ ]) d-1) _ (*<* ↥p1>1↧p) = *<* (begin-strict↥ (1/ mkℚᵘ n d-1) ℤ.* 1ℤ ≡⟨⟩+[1+ d-1 ] ℤ.* 1ℤ ≡⟨ ℤ.*-comm +[1+ d-1 ] 1ℤ ⟩1ℤ ℤ.* +[1+ d-1 ] <⟨ ↥p1>1↧p ⟩n ℤ.* 1ℤ ≡⟨ ℤ.*-comm n 1ℤ ⟩1ℤ ℤ.* n ≡⟨⟩(↥ 1ℚᵘ) ℤ.* (↧ (1/ mkℚᵘ n d-1)) ∎)where open ℤ.≤-Reasoning1/-antimono-≤-pos : ∀ {p q} .{{_ : Positive p}} .{{_ : Positive q}} →p ≤ q → (1/ q) {{pos⇒nonZero q}} ≤ (1/ p) {{pos⇒nonZero p}}1/-antimono-≤-pos {p} {q} p≤q = begin1/q ≃⟨ *-identityˡ 1/q ⟨1ℚᵘ * 1/q ≃⟨ *-congʳ (*-inverseˡ p) ⟨(1/p * p) * 1/q ≤⟨ *-monoˡ-≤-nonNeg 1/q (*-monoʳ-≤-nonNeg 1/p p≤q) ⟩(1/p * q) * 1/q ≃⟨ *-assoc 1/p q 1/q ⟩1/p * (q * 1/q) ≃⟨ *-congˡ {1/p} (*-inverseʳ q) ⟩1/p * 1ℚᵘ ≃⟨ *-identityʳ (1/p) ⟩1/p ∎whereopen ≤-Reasoninginstance_ = pos⇒nonZero p_ = pos⇒nonZero q1/p = 1/ p1/q = 1/ qinstance1/p≥0 : NonNegative 1/p1/p≥0 = pos⇒nonNeg 1/p {{1/pos⇒pos p}}1/q≥0 : NonNegative 1/q1/q≥0 = pos⇒nonNeg 1/q {{1/pos⇒pos q}}-------------------------------------------------------------------------- Properties of _⊓_ and _⊔_-------------------------------------------------------------------------- Basic specification in terms of _≤_p≤q⇒p⊔q≃q : p ≤ q → p ⊔ q ≃ qp≤q⇒p⊔q≃q {p@record{}} {q@record{}} p≤q with p ≤ᵇ q | inspect (p ≤ᵇ_) q... | true | _ = ≃-refl... | false | [ p≰q ] = contradiction (≤⇒≤ᵇ p≤q) (subst (¬_ ∘ T) (sym p≰q) λ())p≥q⇒p⊔q≃p : p ≥ q → p ⊔ q ≃ pp≥q⇒p⊔q≃p {p@record{}} {q@record{}} p≥q with p ≤ᵇ q | inspect (p ≤ᵇ_) q... | true | [ p≤q ] = ≤-antisym p≥q (≤ᵇ⇒≤ (subst T (sym p≤q) _))... | false | [ p≤q ] = ≃-reflp≤q⇒p⊓q≃p : p ≤ q → p ⊓ q ≃ pp≤q⇒p⊓q≃p {p@record{}} {q@record{}} p≤q with p ≤ᵇ q | inspect (p ≤ᵇ_) q... | true | _ = ≃-refl... | false | [ p≰q ] = contradiction (≤⇒≤ᵇ p≤q) (subst (¬_ ∘ T) (sym p≰q) λ())p≥q⇒p⊓q≃q : p ≥ q → p ⊓ q ≃ qp≥q⇒p⊓q≃q {p@record{}} {q@record{}} p≥q with p ≤ᵇ q | inspect (p ≤ᵇ_) q... | true | [ p≤q ] = ≤-antisym (≤ᵇ⇒≤ (subst T (sym p≤q) _)) p≥q... | false | [ p≤q ] = ≃-refl⊓-operator : MinOperator ≤-totalPreorder⊓-operator = record{ x≤y⇒x⊓y≈x = p≤q⇒p⊓q≃p; x≥y⇒x⊓y≈y = p≥q⇒p⊓q≃q}⊔-operator : MaxOperator ≤-totalPreorder⊔-operator = record{ x≤y⇒x⊔y≈y = p≤q⇒p⊔q≃q; x≥y⇒x⊔y≈x = p≥q⇒p⊔q≃p}-------------------------------------------------------------------------- Derived properties of _⊓_ and _⊔_privatemodule ⊓-⊔-properties = MinMaxOp ⊓-operator ⊔-operatormodule ⊓-⊔-latticeProperties = LatticeMinMaxOp ⊓-operator ⊔-operatoropen ⊓-⊔-properties publicusing( ⊓-congˡ -- : LeftCongruent _≃_ _⊓_; ⊓-congʳ -- : RightCongruent _≃_ _⊓_; ⊓-cong -- : Congruent₂ _≃_ _⊓_; ⊓-idem -- : Idempotent _≃_ _⊓_; ⊓-sel -- : Selective _≃_ _⊓_; ⊓-assoc -- : Associative _≃_ _⊓_; ⊓-comm -- : Commutative _≃_ _⊓_; ⊔-congˡ -- : LeftCongruent _≃_ _⊔_; ⊔-congʳ -- : RightCongruent _≃_ _⊔_; ⊔-cong -- : Congruent₂ _≃_ _⊔_; ⊔-idem -- : Idempotent _≃_ _⊔_; ⊔-sel -- : Selective _≃_ _⊔_; ⊔-assoc -- : Associative _≃_ _⊔_; ⊔-comm -- : Commutative _≃_ _⊔_; ⊓-distribˡ-⊔ -- : _DistributesOverˡ_ _≃_ _⊓_ _⊔_; ⊓-distribʳ-⊔ -- : _DistributesOverʳ_ _≃_ _⊓_ _⊔_; ⊓-distrib-⊔ -- : _DistributesOver_ _≃_ _⊓_ _⊔_; ⊔-distribˡ-⊓ -- : _DistributesOverˡ_ _≃_ _⊔_ _⊓_; ⊔-distribʳ-⊓ -- : _DistributesOverʳ_ _≃_ _⊔_ _⊓_; ⊔-distrib-⊓ -- : _DistributesOver_ _≃_ _⊔_ _⊓_; ⊓-absorbs-⊔ -- : _Absorbs_ _≃_ _⊓_ _⊔_; ⊔-absorbs-⊓ -- : _Absorbs_ _≃_ _⊔_ _⊓_; ⊔-⊓-absorptive -- : Absorptive _≃_ _⊔_ _⊓_; ⊓-⊔-absorptive -- : Absorptive _≃_ _⊓_ _⊔_; ⊓-isMagma -- : IsMagma _≃_ _⊓_; ⊓-isSemigroup -- : IsSemigroup _≃_ _⊓_; ⊓-isCommutativeSemigroup -- : IsCommutativeSemigroup _≃_ _⊓_; ⊓-isBand -- : IsBand _≃_ _⊓_; ⊓-isSelectiveMagma -- : IsSelectiveMagma _≃_ _⊓_; ⊔-isMagma -- : IsMagma _≃_ _⊔_; ⊔-isSemigroup -- : IsSemigroup _≃_ _⊔_; ⊔-isCommutativeSemigroup -- : IsCommutativeSemigroup _≃_ _⊔_; ⊔-isBand -- : IsBand _≃_ _⊔_; ⊔-isSelectiveMagma -- : IsSelectiveMagma _≃_ _⊔_; ⊓-magma -- : Magma _ _; ⊓-semigroup -- : Semigroup _ _; ⊓-band -- : Band _ _; ⊓-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊓-selectiveMagma -- : SelectiveMagma _ _; ⊔-magma -- : Magma _ _; ⊔-semigroup -- : Semigroup _ _; ⊔-band -- : Band _ _; ⊔-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊔-selectiveMagma -- : SelectiveMagma _ _; ⊓-triangulate -- : ∀ p q r → p ⊓ q ⊓ r ≃ (p ⊓ q) ⊓ (q ⊓ r); ⊔-triangulate -- : ∀ p q r → p ⊔ q ⊔ r ≃ (p ⊔ q) ⊔ (q ⊔ r); ⊓-glb -- : ∀ {p q r} → p ≥ r → q ≥ r → p ⊓ q ≥ r; ⊓-mono-≤ -- : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊓-monoˡ-≤ -- : ∀ p → (_⊓ p) Preserves _≤_ ⟶ _≤_; ⊓-monoʳ-≤ -- : ∀ p → (p ⊓_) Preserves _≤_ ⟶ _≤_; ⊔-lub -- : ∀ {p q r} → p ≤ r → q ≤ r → p ⊔ q ≤ r; ⊔-mono-≤ -- : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊔-monoˡ-≤ -- : ∀ p → (_⊔ p) Preserves _≤_ ⟶ _≤_; ⊔-monoʳ-≤ -- : ∀ p → (p ⊔_) Preserves _≤_ ⟶ _≤_)renaming( x⊓y≈y⇒y≤x to p⊓q≃q⇒q≤p -- : ∀ {p q} → p ⊓ q ≃ q → q ≤ p; x⊓y≈x⇒x≤y to p⊓q≃p⇒p≤q -- : ∀ {p q} → p ⊓ q ≃ p → p ≤ q; x⊔y≈y⇒x≤y to p⊔q≃q⇒p≤q -- : ∀ {p q} → p ⊔ q ≃ q → p ≤ q; x⊔y≈x⇒y≤x to p⊔q≃p⇒q≤p -- : ∀ {p q} → p ⊔ q ≃ p → q ≤ p; x⊓y≤x to p⊓q≤p -- : ∀ p q → p ⊓ q ≤ p; x⊓y≤y to p⊓q≤q -- : ∀ p q → p ⊓ q ≤ q; x≤y⇒x⊓z≤y to p≤q⇒p⊓r≤q -- : ∀ {p q} r → p ≤ q → p ⊓ r ≤ q; x≤y⇒z⊓x≤y to p≤q⇒r⊓p≤q -- : ∀ {p q} r → p ≤ q → r ⊓ p ≤ q; x≤y⊓z⇒x≤y to p≤q⊓r⇒p≤q -- : ∀ {p} q r → p ≤ q ⊓ r → p ≤ q; x≤y⊓z⇒x≤z to p≤q⊓r⇒p≤r -- : ∀ {p} q r → p ≤ q ⊓ r → p ≤ r; x≤x⊔y to p≤p⊔q -- : ∀ p q → p ≤ p ⊔ q; x≤y⊔x to p≤q⊔p -- : ∀ p q → p ≤ q ⊔ p; x≤y⇒x≤y⊔z to p≤q⇒p≤q⊔r -- : ∀ {p q} r → p ≤ q → p ≤ q ⊔ r; x≤y⇒x≤z⊔y to p≤q⇒p≤r⊔q -- : ∀ {p q} r → p ≤ q → p ≤ r ⊔ q; x⊔y≤z⇒x≤z to p⊔q≤r⇒p≤r -- : ∀ p q {r} → p ⊔ q ≤ r → p ≤ r; x⊔y≤z⇒y≤z to p⊔q≤r⇒q≤r -- : ∀ p q {r} → p ⊔ q ≤ r → q ≤ r; x⊓y≤x⊔y to p⊓q≤p⊔q -- : ∀ p q → p ⊓ q ≤ p ⊔ q)open ⊓-⊔-latticeProperties publicusing( ⊓-semilattice -- : Semilattice _ _; ⊔-semilattice -- : Semilattice _ _; ⊔-⊓-lattice -- : Lattice _ _; ⊓-⊔-lattice -- : Lattice _ _; ⊔-⊓-distributiveLattice -- : DistributiveLattice _ _; ⊓-⊔-distributiveLattice -- : DistributiveLattice _ _; ⊓-isSemilattice -- : IsSemilattice _≃_ _⊓_; ⊔-isSemilattice -- : IsSemilattice _≃_ _⊔_; ⊔-⊓-isLattice -- : IsLattice _≃_ _⊔_ _⊓_; ⊓-⊔-isLattice -- : IsLattice _≃_ _⊓_ _⊔_; ⊔-⊓-isDistributiveLattice -- : IsDistributiveLattice _≃_ _⊔_ _⊓_; ⊓-⊔-isDistributiveLattice -- : IsDistributiveLattice _≃_ _⊓_ _⊔_)-------------------------------------------------------------------------- Raw bundles⊓-rawMagma : RawMagma _ _⊓-rawMagma = Magma.rawMagma ⊓-magma⊔-rawMagma : RawMagma _ _⊔-rawMagma = Magma.rawMagma ⊔-magma⊔-⊓-rawLattice : RawLattice _ _⊔-⊓-rawLattice = Lattice.rawLattice ⊔-⊓-lattice-------------------------------------------------------------------------- Monotonic or antimonotic functions distribute over _⊓_ and _⊔_mono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ m n → f (m ⊔ n) ≃ f m ⊔ f nmono-≤-distrib-⊔ pres = ⊓-⊔-properties.mono-≤-distrib-⊔ (mono⇒cong pres) presmono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ m n → f (m ⊓ n) ≃ f m ⊓ f nmono-≤-distrib-⊓ pres = ⊓-⊔-properties.mono-≤-distrib-⊓ (mono⇒cong pres) presantimono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ m n → f (m ⊓ n) ≃ f m ⊔ f nantimono-≤-distrib-⊓ pres = ⊓-⊔-properties.antimono-≤-distrib-⊓ (antimono⇒cong pres) presantimono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ m n → f (m ⊔ n) ≃ f m ⊓ f nantimono-≤-distrib-⊔ pres = ⊓-⊔-properties.antimono-≤-distrib-⊔ (antimono⇒cong pres) pres-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and -_neg-distrib-⊔-⊓ : ∀ p q → - (p ⊔ q) ≃ - p ⊓ - qneg-distrib-⊔-⊓ = antimono-≤-distrib-⊔ neg-mono-≤neg-distrib-⊓-⊔ : ∀ p q → - (p ⊓ q) ≃ - p ⊔ - qneg-distrib-⊓-⊔ = antimono-≤-distrib-⊓ neg-mono-≤-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and _*_*-distribˡ-⊓-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → p * (q ⊓ r) ≃ (p * q) ⊓ (p * r)*-distribˡ-⊓-nonNeg p = mono-≤-distrib-⊓ (*-monoʳ-≤-nonNeg p)*-distribʳ-⊓-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → (q ⊓ r) * p ≃ (q * p) ⊓ (r * p)*-distribʳ-⊓-nonNeg p = mono-≤-distrib-⊓ (*-monoˡ-≤-nonNeg p)*-distribˡ-⊔-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → p * (q ⊔ r) ≃ (p * q) ⊔ (p * r)*-distribˡ-⊔-nonNeg p = mono-≤-distrib-⊔ (*-monoʳ-≤-nonNeg p)*-distribʳ-⊔-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → (q ⊔ r) * p ≃ (q * p) ⊔ (r * p)*-distribʳ-⊔-nonNeg p = mono-≤-distrib-⊔ (*-monoˡ-≤-nonNeg p)-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and _*_*-distribˡ-⊔-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → p * (q ⊔ r) ≃ (p * q) ⊓ (p * r)*-distribˡ-⊔-nonPos p = antimono-≤-distrib-⊔ (*-monoʳ-≤-nonPos p)*-distribʳ-⊔-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → (q ⊔ r) * p ≃ (q * p) ⊓ (r * p)*-distribʳ-⊔-nonPos p = antimono-≤-distrib-⊔ (*-monoˡ-≤-nonPos p)*-distribˡ-⊓-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → p * (q ⊓ r) ≃ (p * q) ⊔ (p * r)*-distribˡ-⊓-nonPos p = antimono-≤-distrib-⊓ (*-monoʳ-≤-nonPos p)*-distribʳ-⊓-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → (q ⊓ r) * p ≃ (q * p) ⊔ (r * p)*-distribʳ-⊓-nonPos p = antimono-≤-distrib-⊓ (*-monoˡ-≤-nonPos p)-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and _<_⊓-mono-< : _⊓_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊓-mono-< {p} {r} {q} {s} p<r q<s with ⊓-sel r s... | inj₁ r⊓s≃r = <-respʳ-≃ (≃-sym r⊓s≃r) (≤-<-trans (p⊓q≤p p q) p<r)... | inj₂ r⊓s≃s = <-respʳ-≃ (≃-sym r⊓s≃s) (≤-<-trans (p⊓q≤q p q) q<s)⊔-mono-< : _⊔_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊔-mono-< {p} {r} {q} {s} p<r q<s with ⊔-sel p q... | inj₁ p⊔q≃p = <-respˡ-≃ (≃-sym p⊔q≃p) (<-≤-trans p<r (p≤p⊔q r s))... | inj₂ p⊔q≃q = <-respˡ-≃ (≃-sym p⊔q≃q) (<-≤-trans q<s (p≤q⊔p r s))-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and predicatespos⊓pos⇒pos : ∀ p .{{_ : Positive p}} →∀ q .{{_ : Positive q}} →Positive (p ⊓ q)pos⊓pos⇒pos p q = positive (⊓-mono-< (positive⁻¹ p) (positive⁻¹ q))pos⊔pos⇒pos : ∀ p .{{_ : Positive p}} →∀ q .{{_ : Positive q}} →Positive (p ⊔ q)pos⊔pos⇒pos p q = positive (⊔-mono-< (positive⁻¹ p) (positive⁻¹ q))-------------------------------------------------------------------------- Properties of ∣_∣------------------------------------------------------------------------∣-∣-cong : p ≃ q → ∣ p ∣ ≃ ∣ q ∣∣-∣-cong p@{mkℚᵘ +[1+ _ ] _} q@{mkℚᵘ +[1+ _ ] _} (*≡* ↥p↧q≡↥q↧p) = *≡* ↥p↧q≡↥q↧p∣-∣-cong p@{mkℚᵘ +0 _} q@{mkℚᵘ +0 _} (*≡* ↥p↧q≡↥q↧p) = *≡* ↥p↧q≡↥q↧p∣-∣-cong p@{mkℚᵘ -[1+ _ ] _} q@{mkℚᵘ +0 _} (*≡* ())∣-∣-cong p@{mkℚᵘ -[1+ _ ] _} q@{mkℚᵘ -[1+ _ ] _} (*≡* ↥p↧q≡↥q↧p) = *≡* (begin↥ ∣ p ∣ ℤ.* ↧ q ≡⟨ ℤ.neg-involutive _ ⟩ℤ.- ℤ.- (↥ ∣ p ∣ ℤ.* ↧ q) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ ∣ p ∣) (↧ q)) ⟩ℤ.- (↥ p ℤ.* ↧ q) ≡⟨ cong ℤ.-_ ↥p↧q≡↥q↧p ⟩ℤ.- (↥ q ℤ.* ↧ p) ≡⟨ cong ℤ.-_ (ℤ.neg-distribˡ-* (↥ ∣ q ∣) (↧ p)) ⟩ℤ.- ℤ.- (↥ ∣ q ∣ ℤ.* ↧ p) ≡⟨ ℤ.neg-involutive _ ⟨↥ ∣ q ∣ ℤ.* ↧ p ∎)where open ≡-Reasoning∣p∣≃0⇒p≃0 : ∣ p ∣ ≃ 0ℚᵘ → p ≃ 0ℚᵘ∣p∣≃0⇒p≃0 {mkℚᵘ (ℤ.+ n) d-1} p≃0ℚ = p≃0ℚ∣p∣≃0⇒p≃0 {mkℚᵘ -[1+ n ] d-1} (*≡* ())0≤∣p∣ : ∀ p → 0ℚᵘ ≤ ∣ p ∣0≤∣p∣ (mkℚᵘ +0 _) = *≤* (ℤ.+≤+ ℕ.z≤n)0≤∣p∣ (mkℚᵘ +[1+ _ ] _) = *≤* (ℤ.+≤+ ℕ.z≤n)0≤∣p∣ (mkℚᵘ -[1+ _ ] _) = *≤* (ℤ.+≤+ ℕ.z≤n)∣-p∣≡∣p∣ : ∀ p → ∣ - p ∣ ≡ ∣ p ∣∣-p∣≡∣p∣ (mkℚᵘ +[1+ n ] d) = refl∣-p∣≡∣p∣ (mkℚᵘ +0 d) = refl∣-p∣≡∣p∣ (mkℚᵘ -[1+ n ] d) = refl∣-p∣≃∣p∣ : ∀ p → ∣ - p ∣ ≃ ∣ p ∣∣-p∣≃∣p∣ = ≃-reflexive ∘ ∣-p∣≡∣p∣0≤p⇒∣p∣≡p : 0ℚᵘ ≤ p → ∣ p ∣ ≡ p0≤p⇒∣p∣≡p {mkℚᵘ (ℤ.+ n) d-1} 0≤p = refl0≤p⇒∣p∣≡p {mkℚᵘ -[1+ n ] d-1} 0≤p = contradiction 0≤p (<⇒≱ (*<* ℤ.-<+))0≤p⇒∣p∣≃p : 0ℚᵘ ≤ p → ∣ p ∣ ≃ p0≤p⇒∣p∣≃p {p} = ≃-reflexive ∘ 0≤p⇒∣p∣≡p {p}∣p∣≡p⇒0≤p : ∣ p ∣ ≡ p → 0ℚᵘ ≤ p∣p∣≡p⇒0≤p {mkℚᵘ (ℤ.+ n) d-1} ∣p∣≡p = *≤* (begin0ℤ ℤ.* +[1+ d-1 ] ≡⟨ ℤ.*-zeroˡ (ℤ.+ d-1) ⟩0ℤ ≤⟨ ℤ.+≤+ ℕ.z≤n ⟩ℤ.+ n ≡⟨ ℤ.*-identityʳ (ℤ.+ n) ⟨ℤ.+ n ℤ.* 1ℤ ∎)where open ℤ.≤-Reasoning∣p∣≡p∨∣p∣≡-p : ∀ p → (∣ p ∣ ≡ p) ⊎ (∣ p ∣ ≡ - p)∣p∣≡p∨∣p∣≡-p (mkℚᵘ (ℤ.+ n) d-1) = inj₁ refl∣p∣≡p∨∣p∣≡-p (mkℚᵘ (-[1+ n ]) d-1) = inj₂ refl∣p∣≃p⇒0≤p : ∣ p ∣ ≃ p → 0ℚᵘ ≤ p∣p∣≃p⇒0≤p {p} ∣p∣≃p with ∣p∣≡p∨∣p∣≡-p p... | inj₁ ∣p∣≡p = ∣p∣≡p⇒0≤p ∣p∣≡p... | inj₂ ∣p∣≡-p rewrite ∣p∣≡-p = ≤-reflexive (≃-sym (p≃-p⇒p≃0 p (≃-sym ∣p∣≃p)))∣p+q∣≤∣p∣+∣q∣ : ∀ p q → ∣ p + q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p+q∣≤∣p∣+∣q∣ p@record{} q@record{} = *≤* (begin↥ ∣ p + q ∣ ℤ.* ↧ (∣ p ∣ + ∣ q ∣) ≡⟨⟩↥ ∣ (↥p↧q ℤ.+ ↥q↧p) / ↧p↧q ∣ ℤ.* ℤ.+ ↧p↧q ≡⟨⟩↥ (ℤ.+ ℤ.∣ ↥p↧q ℤ.+ ↥q↧p ∣ / ↧p↧q) ℤ.* ℤ.+ ↧p↧q ≡⟨ cong (ℤ._* ℤ.+ ↧p↧q) (↥[n/d]≡n (ℤ.+ ℤ.∣ ↥p↧q ℤ.+ ↥q↧p ∣) ↧p↧q) ⟩ℤ.+ ℤ.∣ ↥p↧q ℤ.+ ↥q↧p ∣ ℤ.* ℤ.+ ↧p↧q ≤⟨ ℤ.*-monoʳ-≤-nonNeg (ℤ.+ ↧p↧q) (ℤ.+≤+ (ℤ.∣i+j∣≤∣i∣+∣j∣ ↥p↧q ↥q↧p)) ⟩(ℤ.+ ℤ.∣ ↥p↧q ∣ ℤ.+ ℤ.+ ℤ.∣ ↥q↧p ∣) ℤ.* ℤ.+ ↧p↧q ≡⟨ cong₂ (λ h₁ h₂ → (h₁ ℤ.+ h₂) ℤ.* ℤ.+ ↧p↧q) ∣↥p∣↧q≡∣↥p↧q∣ ∣↥q∣↧p≡∣↥q↧p∣ ⟨(∣↥p∣↧q ℤ.+ ∣↥q∣↧p) ℤ.* ℤ.+ ↧p↧q ≡⟨⟩(↥∣p∣↧q ℤ.+ ↥∣q∣↧p) ℤ.* ℤ.+ ↧p↧q ≡⟨ cong (ℤ._* ℤ.+ ↧p↧q) (↥[n/d]≡n (↥∣p∣↧q ℤ.+ ↥∣q∣↧p) ↧p↧q) ⟩↥ ((↥∣p∣↧q ℤ.+ ↥∣q∣↧p) / ↧p↧q) ℤ.* ℤ.+ ↧p↧q ≡⟨⟩↥ (∣ p ∣ + ∣ q ∣) ℤ.* ↧ ∣ p + q ∣ ∎)whereopen ℤ.≤-Reasoning↥p↧q = ↥ p ℤ.* ↧ q↥q↧p = ↥ q ℤ.* ↧ p↥∣p∣↧q = ↥ ∣ p ∣ ℤ.* ↧ q↥∣q∣↧p = ↥ ∣ q ∣ ℤ.* ↧ p∣↥p∣↧q = ℤ.+ ℤ.∣ ↥ p ∣ ℤ.* ↧ q∣↥q∣↧p = ℤ.+ ℤ.∣ ↥ q ∣ ℤ.* ↧ p↧p↧q = ↧ₙ p ℕ.* ↧ₙ q∣m∣n≡∣mn∣ : ∀ m n → ℤ.+ ℤ.∣ m ∣ ℤ.* ℤ.+ n ≡ ℤ.+ ℤ.∣ m ℤ.* ℤ.+ n ∣∣m∣n≡∣mn∣ m n = begin-equalityℤ.+ ℤ.∣ m ∣ ℤ.* ℤ.+ n ≡⟨⟩ℤ.+ ℤ.∣ m ∣ ℤ.* ℤ.+ ℤ.∣ ℤ.+ n ∣ ≡⟨ ℤ.pos-* ℤ.∣ m ∣ ℤ.∣ ℤ.+ n ∣ ⟨ℤ.+ (ℤ.∣ m ∣ ℕ.* n) ≡⟨⟩ℤ.+ (ℤ.∣ m ∣ ℕ.* ℤ.∣ ℤ.+ n ∣) ≡⟨ cong ℤ.+_ (ℤ.∣i*j∣≡∣i∣*∣j∣ m (ℤ.+ n)) ⟨ℤ.+ (ℤ.∣ m ℤ.* ℤ.+ n ∣) ∎∣↥p∣↧q≡∣↥p↧q∣ : ∣↥p∣↧q ≡ ℤ.+ ℤ.∣ ↥p↧q ∣∣↥p∣↧q≡∣↥p↧q∣ = ∣m∣n≡∣mn∣ (↥ p) (↧ₙ q)∣↥q∣↧p≡∣↥q↧p∣ : ∣↥q∣↧p ≡ ℤ.+ ℤ.∣ ↥q↧p ∣∣↥q∣↧p≡∣↥q↧p∣ = ∣m∣n≡∣mn∣ (↥ q) (↧ₙ p)∣p-q∣≤∣p∣+∣q∣ : ∀ p q → ∣ p - q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p-q∣≤∣p∣+∣q∣ p q = begin∣ p - q ∣ ≤⟨ ∣p+q∣≤∣p∣+∣q∣ p (- q) ⟩∣ p ∣ + ∣ - q ∣ ≡⟨ cong (∣ p ∣ +_) (∣-p∣≡∣p∣ q) ⟩∣ p ∣ + ∣ q ∣ ∎where open ≤-Reasoning∣p*q∣≡∣p∣*∣q∣ : ∀ p q → ∣ p * q ∣ ≡ ∣ p ∣ * ∣ q ∣∣p*q∣≡∣p∣*∣q∣ p@record{} q@record{} = begin∣ p * q ∣ ≡⟨⟩∣ (↥ p ℤ.* ↥ q) / (↧ₙ p ℕ.* ↧ₙ q) ∣ ≡⟨⟩ℤ.+ ℤ.∣ ↥ p ℤ.* ↥ q ∣ / (↧ₙ p ℕ.* ↧ₙ q) ≡⟨ cong (λ h → ℤ.+ h / ((↧ₙ p) ℕ.* (↧ₙ q))) (ℤ.∣i*j∣≡∣i∣*∣j∣ (↥ p) (↥ q)) ⟩ℤ.+ (ℤ.∣ ↥ p ∣ ℕ.* ℤ.∣ ↥ q ∣) / (↧ₙ p ℕ.* ↧ₙ q) ≡⟨ cong (_/ (↧ₙ p ℕ.* ↧ₙ q)) (ℤ.pos-* ℤ.∣ ↥ p ∣ ℤ.∣ ↥ q ∣) ⟩(ℤ.+ ℤ.∣ ↥ p ∣ ℤ.* ℤ.+ ℤ.∣ ↥ q ∣) / (↧ₙ p ℕ.* ↧ₙ q) ≡⟨⟩(ℤ.+ ℤ.∣ ↥ p ∣ / ↧ₙ p) * (ℤ.+ ℤ.∣ ↥ q ∣ / ↧ₙ q) ≡⟨⟩∣ p ∣ * ∣ q ∣ ∎where open ≡-Reasoning∣p*q∣≃∣p∣*∣q∣ : ∀ p q → ∣ p * q ∣ ≃ ∣ p ∣ * ∣ q ∣∣p*q∣≃∣p∣*∣q∣ p q = ≃-reflexive (∣p*q∣≡∣p∣*∣q∣ p q)∣∣p∣∣≡∣p∣ : ∀ p → ∣ ∣ p ∣ ∣ ≡ ∣ p ∣∣∣p∣∣≡∣p∣ p = 0≤p⇒∣p∣≡p (0≤∣p∣ p)∣∣p∣∣≃∣p∣ : ∀ p → ∣ ∣ p ∣ ∣ ≃ ∣ p ∣∣∣p∣∣≃∣p∣ p = ≃-reflexive (∣∣p∣∣≡∣p∣ p)∣-∣-nonNeg : ∀ p → NonNegative ∣ p ∣∣-∣-nonNeg (mkℚᵘ +[1+ _ ] _) = _∣-∣-nonNeg (mkℚᵘ +0 _) = _∣-∣-nonNeg (mkℚᵘ -[1+ _ ] _) = _-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.5neg-mono-<-> = neg-mono-<{-# WARNING_ON_USAGE neg-mono-<->"Warning: neg-mono-<-> was deprecated in v1.5.Please use neg-mono-< instead."#-}-- Version 2.0↥[p/q]≡p = ↥[n/d]≡n{-# WARNING_ON_USAGE ↥[p/q]≡p"Warning: ↥[p/q]≡p was deprecated in v2.0.Please use ↥[n/d]≡n instead."#-}↧[p/q]≡q = ↧[n/d]≡d{-# WARNING_ON_USAGE ↧[p/q]≡q"Warning: ↧[p/q]≡q was deprecated in v2.0.Please use ↧[n/d]≡d instead."#-}*-monoʳ-≤-pos : ∀ {r} → Positive r → (r *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-pos r@{mkℚᵘ +[1+ _ ] _} _ = *-monoʳ-≤-nonNeg r{-# WARNING_ON_USAGE *-monoʳ-≤-pos"Warning: *-monoʳ-≤-pos was deprecated in v2.0.Please use *-monoʳ-≤-nonNeg instead."#-}*-monoˡ-≤-pos : ∀ {r} → Positive r → (_* r) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-pos r@{mkℚᵘ +[1+ _ ] _} _ = *-monoˡ-≤-nonNeg r{-# WARNING_ON_USAGE *-monoˡ-≤-pos"Warning: *-monoˡ-≤-nonNeg was deprecated in v2.0.Please use *-monoˡ-≤-nonNeg instead."#-}≤-steps = p≤q⇒p≤r+q{-# WARNING_ON_USAGE ≤-steps"Warning: ≤-steps was deprecated in v2.0Please use p≤q⇒p≤r+q instead."#-}*-monoˡ-≤-neg : ∀ r → Negative r → (_* r) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg r@(mkℚᵘ -[1+ _ ] _) _ = *-monoˡ-≤-nonPos r{-# WARNING_ON_USAGE *-monoˡ-≤-neg"Warning: *-monoˡ-≤-neg was deprecated in v2.0.Please use *-monoˡ-≤-nonPos instead."#-}*-monoʳ-≤-neg : ∀ r → Negative r → (r *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-neg r@(mkℚᵘ -[1+ _ ] _) _ = *-monoʳ-≤-nonPos r{-# WARNING_ON_USAGE *-monoʳ-≤-neg"Warning: *-monoʳ-≤-neg was deprecated in v2.0.Please use *-monoʳ-≤-nonPos instead."#-}*-cancelˡ-<-pos : ∀ r → Positive r → ∀ {p q} → r * p < r * q → p < q*-cancelˡ-<-pos r@(mkℚᵘ +[1+ _ ] _) r>0 = *-cancelˡ-<-nonNeg r{-# WARNING_ON_USAGE *-cancelˡ-<-pos"Warning: *-cancelˡ-<-pos was deprecated in v2.0.Please use *-cancelˡ-<-nonNeg instead."#-}*-cancelʳ-<-pos : ∀ r → Positive r → ∀ {p q} → p * r < q * r → p < q*-cancelʳ-<-pos r@(mkℚᵘ +[1+ _ ] _) r>0 = *-cancelʳ-<-nonNeg r{-# WARNING_ON_USAGE *-cancelʳ-<-pos"Warning: *-cancelʳ-<-pos was deprecated in v2.0.Please use *-cancelʳ-<-nonNeg instead."#-}*-cancelˡ-<-neg : ∀ r → Negative r → ∀ {p q} → r * p < r * q → q < p*-cancelˡ-<-neg r@(mkℚᵘ -[1+ _ ] _) _ = *-cancelˡ-<-nonPos r{-# WARNING_ON_USAGE *-cancelˡ-<-neg"Warning: *-cancelˡ-<-neg was deprecated in v2.0.Please use *-cancelˡ-<-nonPos instead."#-}*-cancelʳ-<-neg : ∀ r → Negative r → ∀ {p q} → p * r < q * r → q < p*-cancelʳ-<-neg r@(mkℚᵘ -[1+ _ ] _) _ = *-cancelʳ-<-nonPos r{-# WARNING_ON_USAGE *-cancelʳ-<-neg"Warning: *-cancelʳ-<-neg was deprecated in v2.0.Please use *-cancelʳ-<-nonPos instead."#-}positive⇒nonNegative : ∀ {p} → Positive p → NonNegative ppositive⇒nonNegative {p} p>0 = pos⇒nonNeg p {{p>0}}{-# WARNING_ON_USAGE positive⇒nonNegative"Warning: positive⇒nonNegative was deprecated in v2.0.Please use pos⇒nonNeg instead."#-}negative⇒nonPositive : ∀ {p} → Negative p → NonPositive pnegative⇒nonPositive {p} p<0 = neg⇒nonPos p {{p<0}}{-# WARNING_ON_USAGE negative⇒nonPositive"Warning: negative⇒nonPositive was deprecated in v2.0.Please use neg⇒nonPos instead."#-}negative<positive : ∀ {p q} → .(Negative p) → .(Positive q) → p < qnegative<positive {p} {q} p<0 q>0 = neg<pos p q {{p<0}} {{q>0}}{-# WARNING_ON_USAGE negative<positive"Warning: negative<positive was deprecated in v2.0.Please use neg<pos instead."#-}{- issue1865/issue1755: raw bundles have moved to `Data.X.Base` -}open Data.Rational.Unnormalised.Base publicusing (+-rawMagma; +-0-rawGroup; *-rawMagma; +-*-rawNearSemiring; +-*-rawSemiring; +-*-rawRing)renaming (+-0-rawMonoid to +-rawMonoid; *-1-rawMonoid to *-rawMonoid)
-------------------------------------------------------------------------- The Agda standard library---- Rational numbers in non-reduced form.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Unnormalised.Base whereopen import Algebra.Bundles.Rawusing (RawMagma; RawMonoid; RawGroup; RawNearSemiring; RawSemiring; RawRing)open import Data.Bool.Base using (Bool; true; false; if_then_else_)open import Data.Integer.Base as ℤusing (ℤ; +_; +0; +[1+_]; -[1+_]; +<+; +≤+)hiding (module ℤ)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Level using (0ℓ)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Unary using (Pred)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl)-------------------------------------------------------------------------- Definition-- Here we define rationals that are not necessarily in reduced form.-- Consequently there are multiple ways of representing a given rational-- number, and the performance of the arithmetic operations may suffer-- due to blowup of the numerator and denominator.-- Nonetheless they are much easier to reason about. In general proofs-- are first proved for these unnormalised rationals and then translated-- into the normalised rationals.record ℚᵘ : Set where-- We add "no-eta-equality; pattern" to the record to stop Agda-- automatically unfolding rationals when arithmetic operations are-- applied to them (see definition of operators below and Issue #1753-- for details).no-eta-equality; patternconstructor mkℚᵘfieldnumerator : ℤdenominator-1 : ℕdenominatorℕ : ℕdenominatorℕ = suc denominator-1denominator : ℤdenominator = + denominatorℕopen ℚᵘ public using ()renaming( numerator to ↥_; denominator to ↧_; denominatorℕ to ↧ₙ_)-------------------------------------------------------------------------- Equality of rational numbers (does not coincide with _≡_)infix 4 _≃_ _≠_data _≃_ : Rel ℚᵘ 0ℓ where*≡* : ∀ {p q} → (↥ p ℤ.* ↧ q) ≡ (↥ q ℤ.* ↧ p) → p ≃ q_≄_ : Rel ℚᵘ 0ℓp ≄ q = ¬ (p ≃ q)-------------------------------------------------------------------------- Ordering of rationalsinfix 4 _≤_ _<_ _≥_ _>_ _≰_ _≱_ _≮_ _≯_data _≤_ : Rel ℚᵘ 0ℓ where*≤* : ∀ {p q} → (↥ p ℤ.* ↧ q) ℤ.≤ (↥ q ℤ.* ↧ p) → p ≤ qdata _<_ : Rel ℚᵘ 0ℓ where*<* : ∀ {p q} → (↥ p ℤ.* ↧ q) ℤ.< (↥ q ℤ.* ↧ p) → p < q_≥_ : Rel ℚᵘ 0ℓx ≥ y = y ≤ x_>_ : Rel ℚᵘ 0ℓx > y = y < x_≰_ : Rel ℚᵘ 0ℓx ≰ y = ¬ (x ≤ y)_≱_ : Rel ℚᵘ 0ℓx ≱ y = ¬ (x ≥ y)_≮_ : Rel ℚᵘ 0ℓx ≮ y = ¬ (x < y)_≯_ : Rel ℚᵘ 0ℓx ≯ y = ¬ (x > y)-------------------------------------------------------------------------- Boolean orderinginfix 4 _≤ᵇ__≤ᵇ_ : ℚᵘ → ℚᵘ → Boolp ≤ᵇ q = (↥ p ℤ.* ↧ q) ℤ.≤ᵇ (↥ q ℤ.* ↧ p)-------------------------------------------------------------------------- Constructing rationals-- An alternative constructor for ℚᵘ. See the constants section below-- for examples of how to use this operator.infixl 7 _/__/_ : (n : ℤ) (d : ℕ) .{{_ : ℕ.NonZero d}} → ℚᵘn / suc d = mkℚᵘ n d-------------------------------------------------------------------------- Some constants0ℚᵘ : ℚᵘ0ℚᵘ = + 0 / 11ℚᵘ : ℚᵘ1ℚᵘ = + 1 / 1½ : ℚᵘ½ = + 1 / 2-½ : ℚᵘ-½ = ℤ.- (+ 1) / 2-------------------------------------------------------------------------- Simple predicatesNonZero : Pred ℚᵘ 0ℓNonZero p = ℤ.NonZero (↥ p)Positive : Pred ℚᵘ 0ℓPositive p = ℤ.Positive (↥ p)Negative : Pred ℚᵘ 0ℓNegative p = ℤ.Negative (↥ p)NonPositive : Pred ℚᵘ 0ℓNonPositive p = ℤ.NonPositive (↥ p)NonNegative : Pred ℚᵘ 0ℓNonNegative p = ℤ.NonNegative (↥ p)-- Instancesopen ℤ publicusing (nonZero; pos; nonNeg; nonPos0; nonPos; neg)-- Constructors and destructors-- Note: these could be proved more elegantly using the constructors-- from ℤ but it requires importing `Data.Integer.Properties` which-- we would like to avoid doing.≢-nonZero : ∀ {p} → p ≄ 0ℚᵘ → NonZero p≢-nonZero {mkℚᵘ -[1+ _ ] _ } _ = _≢-nonZero {mkℚᵘ +[1+ _ ] _ } _ = _≢-nonZero {mkℚᵘ +0 zero } p≢0 = contradiction (*≡* refl) p≢0≢-nonZero {mkℚᵘ +0 (suc d)} p≢0 = contradiction (*≡* refl) p≢0>-nonZero : ∀ {p} → p > 0ℚᵘ → NonZero p>-nonZero {mkℚᵘ +0 _} (*<* (+<+ ()))>-nonZero {mkℚᵘ +[1+ n ] _} (*<* _) = _<-nonZero : ∀ {p} → p < 0ℚᵘ → NonZero p<-nonZero {mkℚᵘ +[1+ n ] _} (*<* _) = _<-nonZero {mkℚᵘ +0 _} (*<* (+<+ ()))<-nonZero {mkℚᵘ -[1+ n ] _} (*<* _) = _positive : ∀ {p} → p > 0ℚᵘ → Positive ppositive {mkℚᵘ +[1+ n ] _} (*<* _) = _positive {mkℚᵘ +0 _} (*<* (+<+ ()))positive {mkℚᵘ (-[1+_] n) _} (*<* ())negative : ∀ {p} → p < 0ℚᵘ → Negative pnegative {mkℚᵘ +[1+ n ] _} (*<* (+<+ ()))negative {mkℚᵘ +0 _} (*<* (+<+ ()))negative {mkℚᵘ (-[1+_] n) _} (*<* _ ) = _nonPositive : ∀ {p} → p ≤ 0ℚᵘ → NonPositive pnonPositive {mkℚᵘ +[1+ n ] _} (*≤* (+≤+ ()))nonPositive {mkℚᵘ +0 _} (*≤* _) = _nonPositive {mkℚᵘ -[1+ n ] _} (*≤* _) = _nonNegative : ∀ {p} → p ≥ 0ℚᵘ → NonNegative pnonNegative {mkℚᵘ +0 _} (*≤* _) = _nonNegative {mkℚᵘ +[1+ n ] _} (*≤* _) = _-------------------------------------------------------------------------- Operations on rationals-- Explanation for `@record{}` everywhere: combined with no-eta-equality-- on the record definition of ℚᵘ above, these annotations prevent the-- operations from automatically expanding unless their arguments are-- explicitly pattern matched on.---- For example prior to their addition, `p + q` would often be-- normalised by Agda to `(↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)`.-- While in this small example this isn't a big problem, it leads to an-- exponential blowup when you have large arithmetic expressions which-- would often choke both type-checking and the display code. For-- example, the normalised form of `p + q + r + s + t + u` would be-- ~300 lines long.---- This is fundementally a problem with Agda, so if over-eager-- normalisation is ever fixed in Agda (e.g. with glued representation-- of terms) these annotations can be removed.infix 8 -_ 1/_infixl 7 _*_ _÷_ _⊓_infixl 6 _-_ _+_ _⊔_-- negation-_ : ℚᵘ → ℚᵘ- mkℚᵘ n d = mkℚᵘ (ℤ.- n) d-- addition_+_ : ℚᵘ → ℚᵘ → ℚᵘp@record{} + q@record{} = (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)-- multiplication_*_ : ℚᵘ → ℚᵘ → ℚᵘp@record{} * q@record{} = (↥ p ℤ.* ↥ q) / (↧ₙ p ℕ.* ↧ₙ q)-- subtraction_-_ : ℚᵘ → ℚᵘ → ℚᵘp - q = p + (- q)-- reciprocal: requires a proof that the numerator is not zero1/_ : (p : ℚᵘ) → .{{_ : NonZero p}} → ℚᵘ1/ mkℚᵘ +[1+ n ] d = mkℚᵘ +[1+ d ] n1/ mkℚᵘ -[1+ n ] d = mkℚᵘ -[1+ d ] n-- division: requires a proof that the denominator is not zero_÷_ : (p q : ℚᵘ) → .{{_ : NonZero q}} → ℚᵘp@record{} ÷ q@record{} = p * (1/ q)-- max_⊔_ : (p q : ℚᵘ) → ℚᵘp@record{} ⊔ q@record{} = if p ≤ᵇ q then q else p-- min_⊓_ : (p q : ℚᵘ) → ℚᵘp@record{} ⊓ q@record{} = if p ≤ᵇ q then p else q-- absolute value∣_∣ : ℚᵘ → ℚᵘ∣ mkℚᵘ p q ∣ = mkℚᵘ (+ ℤ.∣ p ∣) q-------------------------------------------------------------------------- Rounding functions-- Floor (round towards -∞)floor : ℚᵘ → ℤfloor p@record{} = ↥ p ℤ./ ↧ p-- Ceiling (round towards +∞)ceiling : ℚᵘ → ℤceiling p@record{} = ℤ.- floor (- p)-- Truncate (round towards 0)truncate : ℚᵘ → ℤtruncate p = if p ≤ᵇ 0ℚᵘ then ceiling p else floor p-- Round (to nearest integer)round : ℚᵘ → ℤround p = if p ≤ᵇ 0ℚᵘ then ceiling (p - ½) else floor (p + ½)-- Fractional part (remainder after floor)fracPart : ℚᵘ → ℚᵘfracPart p@record{} = ∣ p - truncate p / 1 ∣-- Extra notations ⌊ ⌋ floor, ⌈ ⌉ ceiling, [ ] truncatesyntax floor p = ⌊ p ⌋syntax ceiling p = ⌈ p ⌉syntax truncate p = [ p ]-------------------------------------------------------------------------- Raw bundles for _+_+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record{ _≈_ = _≃_; _∙_ = _+_}+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record{ _≈_ = _≃_; _∙_ = _+_; ε = 0ℚᵘ}+-0-rawGroup : RawGroup 0ℓ 0ℓ+-0-rawGroup = record{ Carrier = ℚᵘ; _≈_ = _≃_; _∙_ = _+_; ε = 0ℚᵘ; _⁻¹ = -_}+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawNearSemiring = record{ Carrier = ℚᵘ; _≈_ = _≃_; _+_ = _+_; _*_ = _*_; 0# = 0ℚᵘ}+-*-rawSemiring : RawSemiring 0ℓ 0ℓ+-*-rawSemiring = record{ Carrier = ℚᵘ; _≈_ = _≃_; _+_ = _+_; _*_ = _*_; 0# = 0ℚᵘ; 1# = 1ℚᵘ}+-*-rawRing : RawRing 0ℓ 0ℓ+-*-rawRing = record{ Carrier = ℚᵘ; _≈_ = _≃_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0ℚᵘ; 1# = 1ℚᵘ}-------------------------------------------------------------------------- Raw bundles for _*_*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≃_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≃_; _∙_ = _*_; ε = 1ℚᵘ}-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0+-rawMonoid = +-0-rawMonoid{-# WARNING_ON_USAGE +-rawMonoid"Warning: +-rawMonoid was deprecated in v2.0Please use +-0-rawMonoid instead."#-}*-rawMonoid = *-1-rawMonoid{-# WARNING_ON_USAGE *-rawMonoid"Warning: *-rawMonoid was deprecated in v2.0Please use *-1-rawMonoid instead."#-}_≠_ = _≄_{-# WARNING_ON_USAGE _≠_"Warning: _≠_ was deprecated in v2.0Please use _≄_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over rationals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Solver whereimport Algebra.Solver.Ring.Simple as Solverimport Algebra.Solver.Ring.AlmostCommutativeRing as ACRopen import Data.Rational.Properties using (_≟_; +-*-commutativeRing)-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_module +-*-Solver =Solver (ACR.fromCommutativeRing +-*-commutativeRing) _≟_
-------------------------------------------------------------------------- The Agda standard library---- Showing rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Show whereimport Data.Integer.Show as ℤopen import Data.Rational.Baseopen import Data.String.Base using (String; _++_)show : ℚ → Stringshow p = ℤ.show (↥ p) ++ "/" ++ ℤ.show (↧ p)
-------------------------------------------------------------------------- The Agda standard library---- Properties of Rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for +-rawMonoid, *-rawMonoid (issue #1865, #1844, #1755)module Data.Rational.Properties whereopen import Algebra.Apartnessopen import Algebra.Construct.NaturalChoice.Baseimport Algebra.Construct.NaturalChoice.MinMaxOp as MinMaxOpimport Algebra.Lattice.Construct.NaturalChoice.MinMaxOp as LatticeMinMaxOpopen import Algebra.Consequences.Propositionalopen import Algebra.Morphismopen import Algebra.Bundlesimport Algebra.Morphism.MagmaMonomorphism as MagmaMonomorphismsimport Algebra.Morphism.MonoidMonomorphism as MonoidMonomorphismsimport Algebra.Morphism.GroupMonomorphism as GroupMonomorphismsimport Algebra.Morphism.RingMonomorphism as RingMonomorphismsimport Algebra.Lattice.Morphism.LatticeMonomorphism as LatticeMonomorphismsimport Algebra.Properties.CommutativeSemigroup as CommSemigroupPropertiesimport Algebra.Properties.Group as GroupPropertiesopen import Data.Bool.Base using (T; true; false)open import Data.Integer.Base as ℤ using (ℤ; +_; -[1+_]; +[1+_]; +0; 0ℤ; 1ℤ; _◃_)open import Data.Integer.Coprimality using (coprime-divisor)import Data.Integer.Properties as ℤopen import Data.Integer.GCD using (gcd; gcd[i,j]≡0⇒i≡0; gcd[i,j]≡0⇒j≡0)open import Data.Integer.Solver renaming (module +-*-Solver to ℤ-solver)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)import Data.Nat.Properties as ℕopen import Data.Nat.Coprimality as C using (Coprime; coprime?)open import Data.Nat.Divisibility using (_∣_; divides; ∣-antisym; *-pres-∣)import Data.Nat.GCD as ℕimport Data.Nat.DivMod as ℕopen import Data.Product.Base using (proj₁; proj₂; _×_; _,_; uncurry)open import Data.Rational.Baseopen import Data.Rational.Unnormalised.Base as ℚᵘusing (ℚᵘ; mkℚᵘ; *≡*; *≤*; *<*)renaming( ↥_ to ↥ᵘ_; ↧_ to ↧ᵘ_; ↧ₙ_ to ↧ₙᵘ_; _≃_ to _≃ᵘ_; _≤_ to _≤ᵘ_; _<_ to _<ᵘ_; _+_ to _+ᵘ_)import Data.Rational.Unnormalised.Properties as ℚᵘopen import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_]′; _⊎_)import Data.Sign.Base as Signopen import Function.Base using (_∘_; _∘′_; _∘₂_; _$_; flip)open import Function.Definitions using (Injective)open import Level using (0ℓ)open import Relation.Binaryopen import Relation.Binary.Morphism.Structuresimport Relation.Binary.Morphism.OrderMonomorphism as OrderMonomorphismsimport Relation.Binary.Properties.DecSetoid as DecSetoidPropertiesopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; sym; trans; _≢_; subst; subst₂; resp₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; decSetoid; module ≡-Reasoning; isEquivalence)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen import Relation.Binary.Reasoning.Syntax using (module ≃-syntax)open import Relation.Nullary.Decidable.Core as Decusing (yes; no; recompute; map′; _×-dec_)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Algebra.Definitions {A = ℚ} _≡_open import Algebra.Structures {A = ℚ} _≡_privatevariablep q r : ℚ-------------------------------------------------------------------------- Propositional equality------------------------------------------------------------------------mkℚ-cong : ∀ {n₁ n₂ d₁ d₂}.{c₁ : Coprime ℤ.∣ n₁ ∣ (suc d₁)}.{c₂ : Coprime ℤ.∣ n₂ ∣ (suc d₂)} →n₁ ≡ n₂ → d₁ ≡ d₂ → mkℚ n₁ d₁ c₁ ≡ mkℚ n₂ d₂ c₂mkℚ-cong refl refl = reflmkℚ-injective : ∀ {n₁ n₂ d₁ d₂}.{c₁ : Coprime ℤ.∣ n₁ ∣ (suc d₁)}.{c₂ : Coprime ℤ.∣ n₂ ∣ (suc d₂)} →mkℚ n₁ d₁ c₁ ≡ mkℚ n₂ d₂ c₂ → n₁ ≡ n₂ × d₁ ≡ d₂mkℚ-injective refl = refl , reflinfix 4 _≟__≟_ : DecidableEquality ℚmkℚ n₁ d₁ _ ≟ mkℚ n₂ d₂ _ = map′(uncurry mkℚ-cong)mkℚ-injective(n₁ ℤ.≟ n₂ ×-dec d₁ ℕ.≟ d₂)≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid ℚ≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_1≢0 : 1ℚ ≢ 0ℚ1≢0 = λ ()-------------------------------------------------------------------------- mkℚ+------------------------------------------------------------------------mkℚ+-cong : ∀ {n₁ n₂ d₁ d₂} .{{_ : ℕ.NonZero d₁}} .{{_ : ℕ.NonZero d₂}}.{c₁ : Coprime n₁ d₁}.{c₂ : Coprime n₂ d₂} →n₁ ≡ n₂ → d₁ ≡ d₂ →mkℚ+ n₁ d₁ c₁ ≡ mkℚ+ n₂ d₂ c₂mkℚ+-cong refl refl = reflmkℚ+-injective : ∀ {n₁ n₂ d₁ d₂} .{{_ : ℕ.NonZero d₁}} .{{_ : ℕ.NonZero d₂}}.{c₁ : Coprime n₁ d₁}.{c₂ : Coprime n₂ d₂} →mkℚ+ n₁ d₁ c₁ ≡ mkℚ+ n₂ d₂ c₂ →n₁ ≡ n₂ × d₁ ≡ d₂mkℚ+-injective {d₁ = suc _} {suc _} refl = refl , refl↥-mkℚ+ : ∀ n d .{{_ : ℕ.NonZero d}} .{c : Coprime n d} → ↥ (mkℚ+ n d c) ≡ + n↥-mkℚ+ n (suc d) = refl↧-mkℚ+ : ∀ n d .{{_ : ℕ.NonZero d}} .{c : Coprime n d} → ↧ (mkℚ+ n d c) ≡ + d↧-mkℚ+ n (suc d) = reflmkℚ+-nonNeg : ∀ n d .{{_ : ℕ.NonZero d}} .{c : Coprime n d} →NonNegative (mkℚ+ n d c)mkℚ+-nonNeg n (suc d) = _mkℚ+-pos : ∀ n d .{{_ : ℕ.NonZero n}} .{{_ : ℕ.NonZero d}}.{c : Coprime n d} → Positive (mkℚ+ n d c)mkℚ+-pos (suc n) (suc d) = _-------------------------------------------------------------------------- Numerator and denominator equality------------------------------------------------------------------------drop-*≡* : p ≃ q → ↥ p ℤ.* ↧ q ≡ ↥ q ℤ.* ↧ pdrop-*≡* (*≡* eq) = eq≡⇒≃ : _≡_ ⇒ _≃_≡⇒≃ refl = *≡* refl≃⇒≡ : _≃_ ⇒ _≡_≃⇒≡ {x = mkℚ n₁ d₁ c₁} {y = mkℚ n₂ d₂ c₂} (*≡* eq) = helperwhereopen ≡-Reasoning1+d₁∣1+d₂ : suc d₁ ∣ suc d₂1+d₁∣1+d₂ = coprime-divisor (+ suc d₁) n₁ (+ suc d₂)(C.sym (C.recompute c₁)) $divides ℤ.∣ n₂ ∣ $ beginℤ.∣ n₁ ℤ.* + suc d₂ ∣ ≡⟨ cong ℤ.∣_∣ eq ⟩ℤ.∣ n₂ ℤ.* + suc d₁ ∣ ≡⟨ ℤ.abs-* n₂ (+ suc d₁) ⟩ℤ.∣ n₂ ∣ ℕ.* suc d₁ ∎1+d₂∣1+d₁ : suc d₂ ∣ suc d₁1+d₂∣1+d₁ = coprime-divisor (+ suc d₂) n₂ (+ suc d₁)(C.sym (C.recompute c₂)) $divides ℤ.∣ n₁ ∣ (beginℤ.∣ n₂ ℤ.* + suc d₁ ∣ ≡⟨ cong ℤ.∣_∣ (sym eq) ⟩ℤ.∣ n₁ ℤ.* + suc d₂ ∣ ≡⟨ ℤ.abs-* n₁ (+ suc d₂) ⟩ℤ.∣ n₁ ∣ ℕ.* suc d₂ ∎)helper : mkℚ n₁ d₁ c₁ ≡ mkℚ n₂ d₂ c₂helper with ∣-antisym 1+d₁∣1+d₂ 1+d₂∣1+d₁... | refl with ℤ.*-cancelʳ-≡ n₁ n₂ (+ suc d₁) eq... | refl = refl≃-sym : Symmetric _≃_≃-sym = ≡⇒≃ ∘′ sym ∘′ ≃⇒≡-------------------------------------------------------------------------- Properties of ↥------------------------------------------------------------------------↥p≡0⇒p≡0 : ∀ p → ↥ p ≡ 0ℤ → p ≡ 0ℚ↥p≡0⇒p≡0 (mkℚ +0 d-1 0-coprime-d) ↥p≡0 = mkℚ-cong refl d-1≡0where d-1≡0 = ℕ.suc-injective (C.0-coprimeTo-m⇒m≡1 (C.recompute 0-coprime-d))p≡0⇒↥p≡0 : ∀ p → p ≡ 0ℚ → ↥ p ≡ 0ℤp≡0⇒↥p≡0 p refl = refl↥p≡↥q≡0⇒p≡q : ∀ p q → ↥ p ≡ 0ℤ → ↥ q ≡ 0ℤ → p ≡ q↥p≡↥q≡0⇒p≡q p q ↥p≡0 ↥q≡0 = trans (↥p≡0⇒p≡0 p ↥p≡0) (sym (↥p≡0⇒p≡0 q ↥q≡0))-------------------------------------------------------------------------- Basic properties of sign predicates------------------------------------------------------------------------nonNeg≢neg : ∀ p q → .{{NonNegative p}} → .{{Negative q}} → p ≢ qnonNeg≢neg (mkℚ (+ _) _ _) (mkℚ -[1+ _ ] _ _) ()pos⇒nonNeg : ∀ p → .{{Positive p}} → NonNegative ppos⇒nonNeg p = ℚᵘ.pos⇒nonNeg (toℚᵘ p)neg⇒nonPos : ∀ p → .{{Negative p}} → NonPositive pneg⇒nonPos p = ℚᵘ.neg⇒nonPos (toℚᵘ p)nonNeg∧nonZero⇒pos : ∀ p → .{{NonNegative p}} → .{{NonZero p}} → Positive pnonNeg∧nonZero⇒pos (mkℚ +[1+ _ ] _ _) = _pos⇒nonZero : ∀ p → .{{Positive p}} → NonZero ppos⇒nonZero (mkℚ +[1+ _ ] _ _) = _neg⇒nonZero : ∀ p → .{{Negative p}} → NonZero pneg⇒nonZero (mkℚ -[1+ _ ] _ _) = _-------------------------------------------------------------------------- Properties of -_------------------------------------------------------------------------↥-neg : ∀ p → ↥ (- p) ≡ ℤ.- (↥ p)↥-neg (mkℚ -[1+ _ ] _ _) = refl↥-neg (mkℚ +0 _ _) = refl↥-neg (mkℚ +[1+ _ ] _ _) = refl↧-neg : ∀ p → ↧ (- p) ≡ ↧ p↧-neg (mkℚ -[1+ _ ] _ _) = refl↧-neg (mkℚ +0 _ _) = refl↧-neg (mkℚ +[1+ _ ] _ _) = reflneg-injective : - p ≡ - q → p ≡ qneg-injective {mkℚ +[1+ m ] _ _} {mkℚ +[1+ n ] _ _} refl = reflneg-injective {mkℚ +0 _ _} {mkℚ +0 _ _} refl = reflneg-injective {mkℚ -[1+ m ] _ _} {mkℚ -[1+ n ] _ _} refl = reflneg-injective {mkℚ +[1+ m ] _ _} {mkℚ -[1+ n ] _ _} ()neg-injective {mkℚ +0 _ _} {mkℚ -[1+ n ] _ _} ()neg-injective {mkℚ -[1+ m ] _ _} {mkℚ +[1+ n ] _ _} ()neg-injective {mkℚ -[1+ m ] _ _} {mkℚ +0 _ _} ()neg-pos : Positive p → Negative (- p)neg-pos {mkℚ +[1+ _ ] _ _} _ = _-------------------------------------------------------------------------- Properties of normalize------------------------------------------------------------------------normalize-coprime : ∀ {n d-1} .(c : Coprime n (suc d-1)) →normalize n (suc d-1) ≡ mkℚ (+ n) d-1 cnormalize-coprime {n} {d-1} c = beginnormalize n d ≡⟨⟩mkℚ+ ((n ℕ./ g) {{g≢0}}) ((d ℕ./ g) {{g≢0}}) _ ≡⟨ mkℚ+-cong {c₂ = c₂} (ℕ./-congʳ {{g≢0}} g≡1) (ℕ./-congʳ {{g≢0}} g≡1) ⟩mkℚ+ (n ℕ./ 1) (d ℕ./ 1) _ ≡⟨ mkℚ+-cong {c₂ = c} (ℕ.n/1≡n n) (ℕ.n/1≡n d) ⟩mkℚ+ n d _ ≡⟨⟩mkℚ (+ n) d-1 _ ∎whereopen ≡-Reasoning; d = suc d-1; g = ℕ.gcd n dc′ = C.recompute cc₂ : Coprime (n ℕ./ 1) (d ℕ./ 1)c₂ = subst₂ Coprime (sym (ℕ.n/1≡n n)) (sym (ℕ.n/1≡n d)) c′g≡1 = C.coprime⇒gcd≡1 c′instanceg≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 n d (inj₂ λ()))n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 n d {{_}} {{g≢0}})d/1≢0 = ℕ.≢-nonZero (subst (_≢ 0) (sym (ℕ.n/1≡n d)) λ())↥-normalize : ∀ i n .{{_ : ℕ.NonZero n}} → ↥ (normalize i n) ℤ.* gcd (+ i) (+ n) ≡ + i↥-normalize i n = begin↥ (normalize i n) ℤ.* + g ≡⟨ cong (ℤ._* + g) (↥-mkℚ+ _ (n ℕ./ g)) ⟩+ i/g ℤ.* + g ≡⟨⟩Sign.+ ◃ i/g ℕ.* g ≡⟨ cong (Sign.+ ◃_) (ℕ.m/n*n≡m (ℕ.gcd[m,n]∣m i n)) ⟩Sign.+ ◃ i ≡⟨ ℤ.+◃n≡+n i ⟩+ i ∎whereopen ≡-Reasoningg = ℕ.gcd i ninstance g≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 i n (inj₂ (ℕ.≢-nonZero⁻¹ n)))instance n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 i n {{gcd≢0 = g≢0}})i/g = (i ℕ./ g) {{g≢0}}↧-normalize : ∀ i n .{{_ : ℕ.NonZero n}} → ↧ (normalize i n) ℤ.* gcd (+ i) (+ n) ≡ + n↧-normalize i n = begin↧ (normalize i n) ℤ.* + g ≡⟨ cong (ℤ._* + g) (↧-mkℚ+ _ (n ℕ./ g)) ⟩+ (n ℕ./ g) ℤ.* + g ≡⟨⟩Sign.+ ◃ n ℕ./ g ℕ.* g ≡⟨ cong (Sign.+ ◃_) (ℕ.m/n*n≡m (ℕ.gcd[m,n]∣n i n)) ⟩Sign.+ ◃ n ≡⟨ ℤ.+◃n≡+n n ⟩+ n ∎whereopen ≡-Reasoningg = ℕ.gcd i ninstance g≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 i n (inj₂ (ℕ.≢-nonZero⁻¹ n)))instance n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 i n {{gcd≢0 = g≢0}})normalize-cong : ∀ {m₁ n₁ m₂ n₂} .{{_ : ℕ.NonZero n₁}} .{{_ : ℕ.NonZero n₂}} →m₁ ≡ m₂ → n₁ ≡ n₂ → normalize m₁ n₁ ≡ normalize m₂ n₂normalize-cong {m} {n} refl refl =mkℚ+-cong (ℕ./-congʳ {n = g} refl) (ℕ./-congʳ {n = g} refl)whereg = ℕ.gcd m ninstanceg≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 m n (inj₂ (ℕ.≢-nonZero⁻¹ n)))n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 m n {{gcd≢0 = g≢0}})normalize-nonNeg : ∀ m n .{{_ : ℕ.NonZero n}} → NonNegative (normalize m n)normalize-nonNeg m n = mkℚ+-nonNeg (m ℕ./ g) (n ℕ./ g)whereg = ℕ.gcd m ninstanceg≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 m n (inj₂ (ℕ.≢-nonZero⁻¹ n)))n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 m n {{gcd≢0 = g≢0}})normalize-pos : ∀ m n .{{_ : ℕ.NonZero n}} .{{_ : ℕ.NonZero m}} → Positive (normalize m n)normalize-pos m n = mkℚ+-pos (m ℕ./ ℕ.gcd m n) (n ℕ./ ℕ.gcd m n)whereg = ℕ.gcd m ninstanceg≢0 = ℕ.≢-nonZero (ℕ.gcd[m,n]≢0 m n (inj₂ (ℕ.≢-nonZero⁻¹ n)))n/g≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 m n {{gcd≢0 = g≢0}})m/g≢0 = ℕ.≢-nonZero (ℕ.m/gcd[m,n]≢0 m n {{gcd≢0 = g≢0}})normalize-injective-≃ : ∀ m n c d {{_ : ℕ.NonZero c}} {{_ : ℕ.NonZero d}} →normalize m c ≡ normalize n d →m ℕ.* d ≡ n ℕ.* cnormalize-injective-≃ m n c d eq = ℕ./-cancelʳ-≡md∣gcd[m,c]gcd[n,d]nc∣gcd[m,c]gcd[n,d]$ begin(m ℕ.* d) ℕ./ (gcd[m,c] ℕ.* gcd[n,d]) ≡⟨ ℕ./-*-interchange gcd[m,c]∣m gcd[n,d]∣d ⟩(m ℕ./ gcd[m,c]) ℕ.* (d ℕ./ gcd[n,d]) ≡⟨ cong₂ ℕ._*_ m/gcd[m,c]≡n/gcd[n,d] (sym c/gcd[m,c]≡d/gcd[n,d]) ⟩(n ℕ./ gcd[n,d]) ℕ.* (c ℕ./ gcd[m,c]) ≡⟨ ℕ./-*-interchange gcd[n,d]∣n gcd[m,c]∣c ⟨(n ℕ.* c) ℕ./ (gcd[n,d] ℕ.* gcd[m,c]) ≡⟨ ℕ./-congʳ (ℕ.*-comm gcd[n,d] gcd[m,c]) ⟩(n ℕ.* c) ℕ./ (gcd[m,c] ℕ.* gcd[n,d]) ∎whereopen ≡-Reasoninggcd[m,c] = ℕ.gcd m cgcd[n,d] = ℕ.gcd n dgcd[m,c]∣m = ℕ.gcd[m,n]∣m m cgcd[m,c]∣c = ℕ.gcd[m,n]∣n m cgcd[n,d]∣n = ℕ.gcd[m,n]∣m n dgcd[n,d]∣d = ℕ.gcd[m,n]∣n n dmd∣gcd[m,c]gcd[n,d] = *-pres-∣ gcd[m,c]∣m gcd[n,d]∣dnc∣gcd[n,d]gcd[m,c] = *-pres-∣ gcd[n,d]∣n gcd[m,c]∣cnc∣gcd[m,c]gcd[n,d] = subst (_∣ n ℕ.* c) (ℕ.*-comm gcd[n,d] gcd[m,c]) nc∣gcd[n,d]gcd[m,c]gcd[m,c]≢0′ = ℕ.gcd[m,n]≢0 m c (inj₂ (ℕ.≢-nonZero⁻¹ c))gcd[n,d]≢0′ = ℕ.gcd[m,n]≢0 n d (inj₂ (ℕ.≢-nonZero⁻¹ d))instancegcd[m,c]≢0 = ℕ.≢-nonZero gcd[m,c]≢0′gcd[n,d]≢0 = ℕ.≢-nonZero gcd[n,d]≢0′c/gcd[m,c]≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 m c {{gcd≢0 = gcd[m,c]≢0}})d/gcd[n,d]≢0 = ℕ.≢-nonZero (ℕ.n/gcd[m,n]≢0 n d {{gcd≢0 = gcd[n,d]≢0}})gcd[m,c]*gcd[n,d]≢0 = ℕ.m*n≢0 gcd[m,c] gcd[n,d]gcd[n,d]*gcd[m,c]≢0 = ℕ.m*n≢0 gcd[n,d] gcd[m,c]div = mkℚ+-injective eqm/gcd[m,c]≡n/gcd[n,d] = proj₁ divc/gcd[m,c]≡d/gcd[n,d] = proj₂ div-------------------------------------------------------------------------- Properties of _/_------------------------------------------------------------------------↥-/ : ∀ i n .{{_ : ℕ.NonZero n}} → ↥ (i / n) ℤ.* gcd i (+ n) ≡ i↥-/ (+ m) n = ↥-normalize m n↥-/ -[1+ m ] n = begin-equality↥ (- norm) ℤ.* + g ≡⟨ cong (ℤ._* + g) (↥-neg norm) ⟩ℤ.- (↥ norm) ℤ.* + g ≡⟨ sym (ℤ.neg-distribˡ-* (↥ norm) (+ g)) ⟩ℤ.- (↥ norm ℤ.* + g) ≡⟨ cong (ℤ.-_) (↥-normalize (suc m) n) ⟩Sign.- ◃ suc m ≡⟨⟩-[1+ m ] ∎whereopen ℤ.≤-Reasoningg = ℕ.gcd (suc m) nnorm = normalize (suc m) n↧-/ : ∀ i n .{{_ : ℕ.NonZero n}} → ↧ (i / n) ℤ.* gcd i (+ n) ≡ + n↧-/ (+ m) n = ↧-normalize m n↧-/ -[1+ m ] n = begin-equality↧ (- norm) ℤ.* + g ≡⟨ cong (ℤ._* + g) (↧-neg norm) ⟩↧ norm ℤ.* + g ≡⟨ ↧-normalize (suc m) n ⟩+ n ∎whereopen ℤ.≤-Reasoningg = ℕ.gcd (suc m) nnorm = normalize (suc m) n↥p/↧p≡p : ∀ p → ↥ p / ↧ₙ p ≡ p↥p/↧p≡p (mkℚ (+ n) d-1 prf) = normalize-coprime prf↥p/↧p≡p (mkℚ -[1+ n ] d-1 prf) = cong (-_) (normalize-coprime prf)0/n≡0 : ∀ n .{{_ : ℕ.NonZero n}} → 0ℤ / n ≡ 0ℚ0/n≡0 n@(suc n-1) {{n≢0}} = mkℚ+-cong {{n/n≢0}} {c₂ = 0-cop-1} (ℕ.0/n≡0 (ℕ.gcd 0 n)) (ℕ.n/n≡1 n)where0-cop-1 = C.sym (C.1-coprimeTo 0)n/n≢0 = ℕ.>-nonZero (subst (ℕ._> 0) (sym (ℕ.n/n≡1 n)) (ℕ.z<s))/-cong : ∀ {p₁ q₁ p₂ q₂} .{{_ : ℕ.NonZero q₁}} .{{_ : ℕ.NonZero q₂}} →p₁ ≡ p₂ → q₁ ≡ q₂ → p₁ / q₁ ≡ p₂ / q₂/-cong {+ n} refl = normalize-cong {n} refl/-cong { -[1+ n ]} refl = cong -_ ∘′ normalize-cong {suc n} reflprivate/-injective-≃-helper : ∀ {m n c d} .{{_ : ℕ.NonZero c}} .{{_ : ℕ.NonZero d}} →- normalize (suc m) c ≡ normalize n d →mkℚᵘ -[1+ m ] (ℕ.pred c) ≃ᵘ mkℚᵘ (+ n) (ℕ.pred d)/-injective-≃-helper {m} {n} {c} {d} -norm≡norm = contradiction(sym -norm≡norm)(nonNeg≢neg (normalize n d) (- normalize (suc m) c))where instance_ : NonNegative (normalize n d)_ = normalize-nonNeg n d_ : Negative (- normalize (suc m) c)_ = neg-pos {normalize (suc m) c} (normalize-pos (suc m) c)/-injective-≃ : ∀ p q → ↥ᵘ p / ↧ₙᵘ p ≡ ↥ᵘ q / ↧ₙᵘ q → p ≃ᵘ q/-injective-≃ (mkℚᵘ (+ m) c-1) (mkℚᵘ (+ n) d-1) eq =*≡* (cong (Sign.+ ◃_) (normalize-injective-≃ m n _ _ eq))/-injective-≃ (mkℚᵘ (+ m) c-1) (mkℚᵘ -[1+ n ] d-1) eq =ℚᵘ.≃-sym (/-injective-≃-helper (sym eq))/-injective-≃ (mkℚᵘ -[1+ m ] c-1) (mkℚᵘ (+ n) d-1) eq =/-injective-≃-helper eq/-injective-≃ (mkℚᵘ -[1+ m ] c-1) (mkℚᵘ -[1+ n ] d-1) eq =*≡* (cong (Sign.- ◃_) (normalize-injective-≃ (suc m) (suc n) _ _ (neg-injective eq)))-------------------------------------------------------------------------- Properties of toℚ/fromℚ------------------------------------------------------------------------↥ᵘ-toℚᵘ : ∀ p → ↥ᵘ (toℚᵘ p) ≡ ↥ p↥ᵘ-toℚᵘ p@record{} = refl↧ᵘ-toℚᵘ : ∀ p → ↧ᵘ (toℚᵘ p) ≡ ↧ p↧ᵘ-toℚᵘ p@record{} = refltoℚᵘ-injective : Injective _≡_ _≃ᵘ_ toℚᵘtoℚᵘ-injective {x@record{}} {y@record{}} (*≡* eq) = ≃⇒≡ (*≡* eq)fromℚᵘ-injective : Injective _≃ᵘ_ _≡_ fromℚᵘfromℚᵘ-injective {p@record{}} {q@record{}} = /-injective-≃ p qfromℚᵘ-toℚᵘ : ∀ p → fromℚᵘ (toℚᵘ p) ≡ pfromℚᵘ-toℚᵘ (mkℚ (+ n) d-1 c) = normalize-coprime cfromℚᵘ-toℚᵘ (mkℚ (-[1+ n ]) d-1 c) = cong (-_) (normalize-coprime c)toℚᵘ-fromℚᵘ : ∀ p → toℚᵘ (fromℚᵘ p) ≃ᵘ ptoℚᵘ-fromℚᵘ p = fromℚᵘ-injective (fromℚᵘ-toℚᵘ (fromℚᵘ p))toℚᵘ-cong : toℚᵘ Preserves _≡_ ⟶ _≃ᵘ_toℚᵘ-cong refl = *≡* reflfromℚᵘ-cong : fromℚᵘ Preserves _≃ᵘ_ ⟶ _≡_fromℚᵘ-cong {p} {q} p≃q = toℚᵘ-injective (begin-equalitytoℚᵘ (fromℚᵘ p) ≃⟨ toℚᵘ-fromℚᵘ p ⟩p ≃⟨ p≃q ⟩q ≃⟨ toℚᵘ-fromℚᵘ q ⟨toℚᵘ (fromℚᵘ q) ∎)where open ℚᵘ.≤-Reasoningtoℚᵘ-isRelHomomorphism : IsRelHomomorphism _≡_ _≃ᵘ_ toℚᵘtoℚᵘ-isRelHomomorphism = record{ cong = toℚᵘ-cong}toℚᵘ-isRelMonomorphism : IsRelMonomorphism _≡_ _≃ᵘ_ toℚᵘtoℚᵘ-isRelMonomorphism = record{ isHomomorphism = toℚᵘ-isRelHomomorphism; injective = toℚᵘ-injective}-------------------------------------------------------------------------- Properties of _≤_------------------------------------------------------------------------drop-*≤* : p ≤ q → (↥ p ℤ.* ↧ q) ℤ.≤ (↥ q ℤ.* ↧ p)drop-*≤* (*≤* pq≤qp) = pq≤qp-------------------------------------------------------------------------- toℚᵘ is a isomorphismtoℚᵘ-mono-≤ : p ≤ q → toℚᵘ p ≤ᵘ toℚᵘ qtoℚᵘ-mono-≤ {p@record{}} {q@record{}} (*≤* p≤q) = *≤* p≤qtoℚᵘ-cancel-≤ : toℚᵘ p ≤ᵘ toℚᵘ q → p ≤ qtoℚᵘ-cancel-≤ {p@record{}} {q@record{}} (*≤* p≤q) = *≤* p≤qtoℚᵘ-isOrderHomomorphism-≤ : IsOrderHomomorphism _≡_ _≃ᵘ_ _≤_ _≤ᵘ_ toℚᵘtoℚᵘ-isOrderHomomorphism-≤ = record{ cong = toℚᵘ-cong; mono = toℚᵘ-mono-≤}toℚᵘ-isOrderMonomorphism-≤ : IsOrderMonomorphism _≡_ _≃ᵘ_ _≤_ _≤ᵘ_ toℚᵘtoℚᵘ-isOrderMonomorphism-≤ = record{ isOrderHomomorphism = toℚᵘ-isOrderHomomorphism-≤; injective = toℚᵘ-injective; cancel = toℚᵘ-cancel-≤}-------------------------------------------------------------------------- Relational propertiesprivatemodule ≤-Monomorphism = OrderMonomorphisms toℚᵘ-isOrderMonomorphism-≤≤-reflexive : _≡_ ⇒ _≤_≤-reflexive refl = *≤* ℤ.≤-refl≤-refl : Reflexive _≤_≤-refl = ≤-reflexive refl≤-trans : Transitive _≤_≤-trans = ≤-Monomorphism.trans ℚᵘ.≤-trans≤-antisym : Antisymmetric _≡_ _≤_≤-antisym (*≤* le₁) (*≤* le₂) = ≃⇒≡ (*≡* (ℤ.≤-antisym le₁ le₂))≤-total : Total _≤_≤-total p q = [ inj₁ ∘ *≤* , inj₂ ∘ *≤* ]′ (ℤ.≤-total (↥ p ℤ.* ↧ q) (↥ q ℤ.* ↧ p))infix 4 _≤?_ _≥?__≤?_ : Decidable _≤_p ≤? q = Dec.map′ *≤* drop-*≤* (↥ p ℤ.* ↧ q ℤ.≤? ↥ q ℤ.* ↧ p)_≥?_ : Decidable _≥__≥?_ = flip _≤?_≤-irrelevant : Irrelevant _≤_≤-irrelevant (*≤* p≤q₁) (*≤* p≤q₂) = cong *≤* (ℤ.≤-irrelevant p≤q₁ p≤q₂)-------------------------------------------------------------------------- Structures≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-isTotalPreorder = record{ isPreorder = ≤-isPreorder; total = ≤-total}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder = record{ isTotalPreorder = ≤-isTotalPreorder}≤-decTotalOrder : DecTotalOrder _ _ _≤-decTotalOrder = record{ Carrier = ℚ; _≈_ = _≡_; _≤_ = _≤_; isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Properties of _<_------------------------------------------------------------------------drop-*<* : p < q → (↥ p ℤ.* ↧ q) ℤ.< (↥ q ℤ.* ↧ p)drop-*<* (*<* pq<qp) = pq<qp-------------------------------------------------------------------------- toℚᵘ is a isomorphismtoℚᵘ-mono-< : p < q → toℚᵘ p <ᵘ toℚᵘ qtoℚᵘ-mono-< {p@record{}} {q@record{}} (*<* p<q) = *<* p<qtoℚᵘ-cancel-< : toℚᵘ p <ᵘ toℚᵘ q → p < qtoℚᵘ-cancel-< {p@record{}} {q@record{}} (*<* p<q) = *<* p<qtoℚᵘ-isOrderHomomorphism-< : IsOrderHomomorphism _≡_ _≃ᵘ_ _<_ _<ᵘ_ toℚᵘtoℚᵘ-isOrderHomomorphism-< = record{ cong = toℚᵘ-cong; mono = toℚᵘ-mono-<}toℚᵘ-isOrderMonomorphism-< : IsOrderMonomorphism _≡_ _≃ᵘ_ _<_ _<ᵘ_ toℚᵘtoℚᵘ-isOrderMonomorphism-< = record{ isOrderHomomorphism = toℚᵘ-isOrderHomomorphism-<; injective = toℚᵘ-injective; cancel = toℚᵘ-cancel-<}-------------------------------------------------------------------------- Relational properties<⇒≤ : _<_ ⇒ _≤_<⇒≤ (*<* p<q) = *≤* (ℤ.<⇒≤ p<q)≮⇒≥ : _≮_ ⇒ _≥_≮⇒≥ {p} {q} p≮q = *≤* (ℤ.≮⇒≥ (p≮q ∘ *<*))≰⇒> : _≰_ ⇒ _>_≰⇒> {p} {q} p≰q = *<* (ℤ.≰⇒> (p≰q ∘ *≤*))<⇒≢ : _<_ ⇒ _≢_<⇒≢ {p} {q} (*<* p<q) = ℤ.<⇒≢ p<q ∘ drop-*≡* ∘ ≡⇒≃<-irrefl : Irreflexive _≡_ _<_<-irrefl refl (*<* p<p) = ℤ.<-irrefl refl p<p<-asym : Asymmetric _<_<-asym (*<* p<q) (*<* q<p) = ℤ.<-asym p<q q<p<-dense : Dense _<_<-dense {p} {q} p<q = letm , p<ᵘm , m<ᵘq = ℚᵘ.<-dense (toℚᵘ-mono-< p<q)m≃m : m ≃ᵘ toℚᵘ (fromℚᵘ m)m≃m = ℚᵘ.≃-sym (toℚᵘ-fromℚᵘ m)p<m : p < fromℚᵘ mp<m = toℚᵘ-cancel-< (ℚᵘ.<-respʳ-≃ m≃m p<ᵘm)m<q : fromℚᵘ m < qm<q = toℚᵘ-cancel-< (ℚᵘ.<-respˡ-≃ m≃m m<ᵘq)in fromℚᵘ m , p<m , m<q<-≤-trans : Trans _<_ _≤_ _<_<-≤-trans {p} {q} {r} (*<* p<q) (*≤* q≤r) = *<*(ℤ.*-cancelʳ-<-nonNeg _ (begin-strictlet n₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; sd₁ = ↧ p; sd₂ = ↧ q; sd₃ = ↧ r in(n₁ ℤ.* sd₃) ℤ.* sd₂ ≡⟨ ℤ.*-assoc n₁ sd₃ sd₂ ⟩n₁ ℤ.* (sd₃ ℤ.* sd₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm sd₃ sd₂) ⟩n₁ ℤ.* (sd₂ ℤ.* sd₃) ≡⟨ sym (ℤ.*-assoc n₁ sd₂ sd₃) ⟩(n₁ ℤ.* sd₂) ℤ.* sd₃ <⟨ ℤ.*-monoʳ-<-pos (↧ r) p<q ⟩(n₂ ℤ.* sd₁) ℤ.* sd₃ ≡⟨ cong (ℤ._* sd₃) (ℤ.*-comm n₂ sd₁) ⟩(sd₁ ℤ.* n₂) ℤ.* sd₃ ≡⟨ ℤ.*-assoc sd₁ n₂ sd₃ ⟩sd₁ ℤ.* (n₂ ℤ.* sd₃) ≤⟨ ℤ.*-monoˡ-≤-nonNeg (↧ p) q≤r ⟩sd₁ ℤ.* (n₃ ℤ.* sd₂) ≡⟨ sym (ℤ.*-assoc sd₁ n₃ sd₂) ⟩(sd₁ ℤ.* n₃) ℤ.* sd₂ ≡⟨ cong (ℤ._* sd₂) (ℤ.*-comm sd₁ n₃) ⟩(n₃ ℤ.* sd₁) ℤ.* sd₂ ∎))where open ℤ.≤-Reasoning≤-<-trans : Trans _≤_ _<_ _<_≤-<-trans {p} {q} {r} (*≤* p≤q) (*<* q<r) = *<*(ℤ.*-cancelʳ-<-nonNeg _ (begin-strictlet n₁ = ↥ p; n₂ = ↥ q; n₃ = ↥ r; sd₁ = ↧ p; sd₂ = ↧ q; sd₃ = ↧ r in(n₁ ℤ.* sd₃) ℤ.* sd₂ ≡⟨ ℤ.*-assoc n₁ sd₃ sd₂ ⟩n₁ ℤ.* (sd₃ ℤ.* sd₂) ≡⟨ cong (n₁ ℤ.*_) (ℤ.*-comm sd₃ sd₂) ⟩n₁ ℤ.* (sd₂ ℤ.* sd₃) ≡⟨ sym (ℤ.*-assoc n₁ sd₂ sd₃) ⟩(n₁ ℤ.* sd₂) ℤ.* sd₃ ≤⟨ ℤ.*-monoʳ-≤-nonNeg (↧ r) p≤q ⟩(n₂ ℤ.* sd₁) ℤ.* sd₃ ≡⟨ cong (ℤ._* sd₃) (ℤ.*-comm n₂ sd₁) ⟩(sd₁ ℤ.* n₂) ℤ.* sd₃ ≡⟨ ℤ.*-assoc sd₁ n₂ sd₃ ⟩sd₁ ℤ.* (n₂ ℤ.* sd₃) <⟨ ℤ.*-monoˡ-<-pos (↧ p) q<r ⟩sd₁ ℤ.* (n₃ ℤ.* sd₂) ≡⟨ sym (ℤ.*-assoc sd₁ n₃ sd₂) ⟩(sd₁ ℤ.* n₃) ℤ.* sd₂ ≡⟨ cong (ℤ._* sd₂) (ℤ.*-comm sd₁ n₃) ⟩(n₃ ℤ.* sd₁) ℤ.* sd₂ ∎))where open ℤ.≤-Reasoning<-trans : Transitive _<_<-trans p<q = ≤-<-trans (<⇒≤ p<q)infix 4 _<?_ _>?__<?_ : Decidable _<_p <? q = Dec.map′ *<* drop-*<* ((↥ p ℤ.* ↧ q) ℤ.<? (↥ q ℤ.* ↧ p))_>?_ : Decidable _>__>?_ = flip _<?_<-cmp : Trichotomous _≡_ _<_<-cmp p q with ℤ.<-cmp (↥ p ℤ.* ↧ q) (↥ q ℤ.* ↧ p)... | tri< < ≢ ≯ = tri< (*<* <) (≢ ∘ drop-*≡* ∘ ≡⇒≃) (≯ ∘ drop-*<*)... | tri≈ ≮ ≡ ≯ = tri≈ (≮ ∘ drop-*<*) (≃⇒≡ (*≡* ≡)) (≯ ∘ drop-*<*)... | tri> ≮ ≢ > = tri> (≮ ∘ drop-*<*) (≢ ∘ drop-*≡* ∘ ≡⇒≃) (*<* >)<-irrelevant : Irrelevant _<_<-irrelevant (*<* p<q₁) (*<* p<q₂) = cong *<* (ℤ.<-irrelevant p<q₁ p<q₂)<-respʳ-≡ : _<_ Respectsʳ _≡_<-respʳ-≡ = subst (_ <_)<-respˡ-≡ : _<_ Respectsˡ _≡_<-respˡ-≡ = subst (_< _)<-resp-≡ : _<_ Respects₂ _≡_<-resp-≡ = <-respʳ-≡ , <-respˡ-≡-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = <-resp-≡}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}<-isDenseLinearOrder : IsDenseLinearOrder _≡_ _<_<-isDenseLinearOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder; dense = <-dense}-------------------------------------------------------------------------- Bundles<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}<-denseLinearOrder : DenseLinearOrder 0ℓ 0ℓ 0ℓ<-denseLinearOrder = record{ isDenseLinearOrder = <-isDenseLinearOrder}-------------------------------------------------------------------------- A specialised module for reasoning about the _≤_ and _<_ relations------------------------------------------------------------------------module ≤-Reasoning whereimport Relation.Binary.Reasoning.Base.Triple≤-isPreorder<-asym<-trans(resp₂ _<_)<⇒≤<-≤-trans≤-<-transas Tripleopen Triple publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)≃-go : Trans _≃_ _IsRelatedTo_ _IsRelatedTo_≃-go = Triple.≈-go ∘′ ≃⇒≡open ≃-syntax _IsRelatedTo_ _IsRelatedTo_ ≃-go (λ {x y} → ≃-sym {x} {y}) public-------------------------------------------------------------------------- Properties of Positive/NonPositive/Negative/NonNegative and _≤_/_<_positive⁻¹ : ∀ p → .{{Positive p}} → p > 0ℚpositive⁻¹ p = toℚᵘ-cancel-< (ℚᵘ.positive⁻¹ (toℚᵘ p))nonNegative⁻¹ : ∀ p → .{{NonNegative p}} → p ≥ 0ℚnonNegative⁻¹ p = toℚᵘ-cancel-≤ (ℚᵘ.nonNegative⁻¹ (toℚᵘ p))negative⁻¹ : ∀ p → .{{Negative p}} → p < 0ℚnegative⁻¹ p = toℚᵘ-cancel-< (ℚᵘ.negative⁻¹ (toℚᵘ p))nonPositive⁻¹ : ∀ p → .{{NonPositive p}} → p ≤ 0ℚnonPositive⁻¹ p = toℚᵘ-cancel-≤ (ℚᵘ.nonPositive⁻¹ (toℚᵘ p))neg<pos : ∀ p q → .{{Negative p}} → .{{Positive q}} → p < qneg<pos p q = toℚᵘ-cancel-< (ℚᵘ.neg<pos (toℚᵘ p) (toℚᵘ q))-------------------------------------------------------------------------- Properties of -_ and _≤_/_<_neg-antimono-< : -_ Preserves _<_ ⟶ _>_neg-antimono-< {mkℚ -[1+ _ ] _ _} {mkℚ -[1+ _ ] _ _} (*<* (ℤ.-<- n<m)) = *<* (ℤ.+<+ (ℕ.s<s n<m))neg-antimono-< {mkℚ -[1+ _ ] _ _} {mkℚ +0 _ _} (*<* ℤ.-<+) = *<* (ℤ.+<+ ℕ.z<s)neg-antimono-< {mkℚ -[1+ _ ] _ _} {mkℚ +[1+ _ ] _ _} (*<* ℤ.-<+) = *<* ℤ.-<+neg-antimono-< {mkℚ +0 _ _} {mkℚ +0 _ _} (*<* (ℤ.+<+ m<n)) = *<* (ℤ.+<+ m<n)neg-antimono-< {mkℚ +0 _ _} {mkℚ +[1+ _ ] _ _} (*<* (ℤ.+<+ m<n)) = *<* ℤ.-<+neg-antimono-< {mkℚ +[1+ _ ] _ _} {mkℚ +0 _ _} (*<* (ℤ.+<+ ()))neg-antimono-< {mkℚ +[1+ _ ] _ _} {mkℚ +[1+ _ ] _ _} (*<* (ℤ.+<+ (ℕ.s<s m<n))) = *<* (ℤ.-<- m<n)neg-antimono-≤ : -_ Preserves _≤_ ⟶ _≥_neg-antimono-≤ {mkℚ -[1+ _ ] _ _} {mkℚ -[1+ _ ] _ _} (*≤* (ℤ.-≤- n≤m)) = *≤* (ℤ.+≤+ (ℕ.s≤s n≤m))neg-antimono-≤ {mkℚ -[1+ _ ] _ _} {mkℚ +0 _ _} (*≤* ℤ.-≤+) = *≤* (ℤ.+≤+ ℕ.z≤n)neg-antimono-≤ {mkℚ -[1+ _ ] _ _} {mkℚ +[1+ _ ] _ _} (*≤* ℤ.-≤+) = *≤* ℤ.-≤+neg-antimono-≤ {mkℚ +0 _ _} {mkℚ +0 _ _} (*≤* (ℤ.+≤+ m≤n)) = *≤* (ℤ.+≤+ m≤n)neg-antimono-≤ {mkℚ +0 _ _} {mkℚ +[1+ _ ] _ _} (*≤* (ℤ.+≤+ m≤n)) = *≤* ℤ.-≤+neg-antimono-≤ {mkℚ +[1+ _ ] _ _} {mkℚ +0 _ _} (*≤* (ℤ.+≤+ ()))neg-antimono-≤ {mkℚ +[1+ _ ] _ _} {mkℚ +[1+ _ ] _ _} (*≤* (ℤ.+≤+ (ℕ.s≤s m≤n))) = *≤* (ℤ.-≤- m≤n)-------------------------------------------------------------------------- Properties of _≤ᵇ_------------------------------------------------------------------------≤ᵇ⇒≤ : T (p ≤ᵇ q) → p ≤ q≤ᵇ⇒≤ = *≤* ∘′ ℤ.≤ᵇ⇒≤≤⇒≤ᵇ : p ≤ q → T (p ≤ᵇ q)≤⇒≤ᵇ = ℤ.≤⇒≤ᵇ ∘′ drop-*≤*-------------------------------------------------------------------------- Properties of _+_------------------------------------------------------------------------private↥+ᵘ : ℚ → ℚ → ℤ↥+ᵘ p q = ↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p↧+ᵘ : ℚ → ℚ → ℤ↧+ᵘ p q = ↧ p ℤ.* ↧ q+-nf : ℚ → ℚ → ℤ+-nf p q = gcd (↥+ᵘ p q) (↧+ᵘ p q)↥-+ : ∀ p q → ↥ (p + q) ℤ.* +-nf p q ≡ ↥+ᵘ p q↥-+ p@record{} q@record{} = ↥-/ (↥+ᵘ p q) (↧ₙ p ℕ.* ↧ₙ q)↧-+ : ∀ p q → ↧ (p + q) ℤ.* +-nf p q ≡ ↧+ᵘ p q↧-+ p@record{} q@record{} = ↧-/ (↥+ᵘ p q) (↧ₙ p ℕ.* ↧ₙ q)-------------------------------------------------------------------------- Monomorphic to unnormalised _+_open Definitions ℚ ℚᵘ ℚᵘ._≃_toℚᵘ-homo-+ : Homomorphic₂ toℚᵘ _+_ ℚᵘ._+_toℚᵘ-homo-+ p@record{} q@record{} with +-nf p q ℤ.≟ 0ℤ... | yes nf[p,q]≡0 = *≡* $ begin↥ᵘ (toℚᵘ (p + q)) ℤ.* ↧+ᵘ p q ≡⟨ cong (ℤ._* ↧+ᵘ p q) (↥ᵘ-toℚᵘ (p + q)) ⟩↥ (p + q) ℤ.* ↧+ᵘ p q ≡⟨ cong (ℤ._* ↧+ᵘ p q) eq ⟩0ℤ ℤ.* ↧+ᵘ p q ≡⟨⟩0ℤ ℤ.* ↧ (p + q) ≡⟨ cong (ℤ._* ↧ (p + q)) (sym eq2) ⟩↥+ᵘ p q ℤ.* ↧ (p + q) ≡⟨ cong (↥+ᵘ p q ℤ.*_) (sym (↧ᵘ-toℚᵘ (p + q))) ⟩↥+ᵘ p q ℤ.* ↧ᵘ (toℚᵘ (p + q)) ∎whereopen ≡-Reasoningeq2 : ↥+ᵘ p q ≡ 0ℤeq2 = gcd[i,j]≡0⇒i≡0 (↥+ᵘ p q) (↧+ᵘ p q) nf[p,q]≡0eq : ↥ (p + q) ≡ 0ℤeq rewrite eq2 = cong ↥_ (0/n≡0 (↧ₙ p ℕ.* ↧ₙ q))... | no nf[p,q]≢0 = *≡* (ℤ.*-cancelʳ-≡ _ _ (+-nf p q) {{ℤ.≢-nonZero nf[p,q]≢0}} $ begin(↥ᵘ (toℚᵘ (p + q))) ℤ.* ↧+ᵘ p q ℤ.* +-nf p q ≡⟨ cong (λ v → v ℤ.* ↧+ᵘ p q ℤ.* +-nf p q) (↥ᵘ-toℚᵘ (p + q)) ⟩↥ (p + q) ℤ.* ↧+ᵘ p q ℤ.* +-nf p q ≡⟨ xy∙z≈xz∙y (↥ (p + q)) _ _ ⟩↥ (p + q) ℤ.* +-nf p q ℤ.* ↧+ᵘ p q ≡⟨ cong (ℤ._* ↧+ᵘ p q) (↥-+ p q) ⟩↥+ᵘ p q ℤ.* ↧+ᵘ p q ≡⟨ cong (↥+ᵘ p q ℤ.*_) (sym (↧-+ p q)) ⟩↥+ᵘ p q ℤ.* (↧ (p + q) ℤ.* +-nf p q) ≡⟨ x∙yz≈xy∙z (↥+ᵘ p q) _ _ ⟩↥+ᵘ p q ℤ.* ↧ (p + q) ℤ.* +-nf p q ≡⟨ cong (λ v → ↥+ᵘ p q ℤ.* v ℤ.* +-nf p q) (↧ᵘ-toℚᵘ (p + q)) ⟨↥+ᵘ p q ℤ.* ↧ᵘ (toℚᵘ (p + q)) ℤ.* +-nf p q ∎)where open ≡-Reasoning; open CommSemigroupProperties ℤ.*-commutativeSemigrouptoℚᵘ-isMagmaHomomorphism-+ : IsMagmaHomomorphism +-rawMagma ℚᵘ.+-rawMagma toℚᵘtoℚᵘ-isMagmaHomomorphism-+ = record{ isRelHomomorphism = toℚᵘ-isRelHomomorphism; homo = toℚᵘ-homo-+}toℚᵘ-isMonoidHomomorphism-+ : IsMonoidHomomorphism +-0-rawMonoid ℚᵘ.+-0-rawMonoid toℚᵘtoℚᵘ-isMonoidHomomorphism-+ = record{ isMagmaHomomorphism = toℚᵘ-isMagmaHomomorphism-+; ε-homo = ℚᵘ.≃-refl}toℚᵘ-isMonoidMonomorphism-+ : IsMonoidMonomorphism +-0-rawMonoid ℚᵘ.+-0-rawMonoid toℚᵘtoℚᵘ-isMonoidMonomorphism-+ = record{ isMonoidHomomorphism = toℚᵘ-isMonoidHomomorphism-+; injective = toℚᵘ-injective}-------------------------------------------------------------------------- Monomorphic to unnormalised -_toℚᵘ-homo‿- : Homomorphic₁ toℚᵘ (-_) (ℚᵘ.-_)toℚᵘ-homo‿- (mkℚ +0 _ _) = *≡* refltoℚᵘ-homo‿- (mkℚ +[1+ _ ] _ _) = *≡* refltoℚᵘ-homo‿- (mkℚ -[1+ _ ] _ _) = *≡* refltoℚᵘ-isGroupHomomorphism-+ : IsGroupHomomorphism +-0-rawGroup ℚᵘ.+-0-rawGroup toℚᵘtoℚᵘ-isGroupHomomorphism-+ = record{ isMonoidHomomorphism = toℚᵘ-isMonoidHomomorphism-+; ⁻¹-homo = toℚᵘ-homo‿-}toℚᵘ-isGroupMonomorphism-+ : IsGroupMonomorphism +-0-rawGroup ℚᵘ.+-0-rawGroup toℚᵘtoℚᵘ-isGroupMonomorphism-+ = record{ isGroupHomomorphism = toℚᵘ-isGroupHomomorphism-+; injective = toℚᵘ-injective}-------------------------------------------------------------------------- Algebraic propertiesprivatemodule +-Monomorphism = GroupMonomorphisms toℚᵘ-isGroupMonomorphism-++-assoc : Associative _+_+-assoc = +-Monomorphism.assoc ℚᵘ.+-isMagma ℚᵘ.+-assoc+-comm : Commutative _+_+-comm = +-Monomorphism.comm ℚᵘ.+-isMagma ℚᵘ.+-comm+-identityˡ : LeftIdentity 0ℚ _+_+-identityˡ = +-Monomorphism.identityˡ ℚᵘ.+-isMagma ℚᵘ.+-identityˡ+-identityʳ : RightIdentity 0ℚ _+_+-identityʳ = +-Monomorphism.identityʳ ℚᵘ.+-isMagma ℚᵘ.+-identityʳ+-identity : Identity 0ℚ _+_+-identity = +-identityˡ , +-identityʳ+-inverseˡ : LeftInverse 0ℚ -_ _+_+-inverseˡ = +-Monomorphism.inverseˡ ℚᵘ.+-isMagma ℚᵘ.+-inverseˡ+-inverseʳ : RightInverse 0ℚ -_ _+_+-inverseʳ = +-Monomorphism.inverseʳ ℚᵘ.+-isMagma ℚᵘ.+-inverseʳ+-inverse : Inverse 0ℚ -_ _+_+-inverse = +-Monomorphism.inverse ℚᵘ.+-isMagma ℚᵘ.+-inverse-‿cong : Congruent₁ (-_)-‿cong = +-Monomorphism.⁻¹-cong ℚᵘ.+-isMagma ℚᵘ.-‿congneg-distrib-+ : ∀ p q → - (p + q) ≡ (- p) + (- q)neg-distrib-+ = +-Monomorphism.⁻¹-distrib-∙ ℚᵘ.+-0-isAbelianGroup (ℚᵘ.≃-reflexive ∘₂ ℚᵘ.neg-distrib-+)-------------------------------------------------------------------------- Structures+-isMagma : IsMagma _+_+-isMagma = +-Monomorphism.isMagma ℚᵘ.+-isMagma+-isSemigroup : IsSemigroup _+_+-isSemigroup = +-Monomorphism.isSemigroup ℚᵘ.+-isSemigroup+-0-isMonoid : IsMonoid _+_ 0ℚ+-0-isMonoid = +-Monomorphism.isMonoid ℚᵘ.+-0-isMonoid+-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0ℚ+-0-isCommutativeMonoid = +-Monomorphism.isCommutativeMonoid ℚᵘ.+-0-isCommutativeMonoid+-0-isGroup : IsGroup _+_ 0ℚ (-_)+-0-isGroup = +-Monomorphism.isGroup ℚᵘ.+-0-isGroup+-0-isAbelianGroup : IsAbelianGroup _+_ 0ℚ (-_)+-0-isAbelianGroup = +-Monomorphism.isAbelianGroup ℚᵘ.+-0-isAbelianGroup-------------------------------------------------------------------------- Packages+-magma : Magma 0ℓ 0ℓ+-magma = record{ isMagma = +-isMagma}+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ isMonoid = +-0-isMonoid}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}+-0-group : Group 0ℓ 0ℓ+-0-group = record{ isGroup = +-0-isGroup}+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ+-0-abelianGroup = record{ isAbelianGroup = +-0-isAbelianGroup}-------------------------------------------------------------------------- Properties of _+_ and _≤_+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-≤ {p} {q} {r} {s} p≤q r≤s = toℚᵘ-cancel-≤ (begintoℚᵘ(p + r) ≃⟨ toℚᵘ-homo-+ p r ⟩toℚᵘ(p) ℚᵘ.+ toℚᵘ(r) ≤⟨ ℚᵘ.+-mono-≤ (toℚᵘ-mono-≤ p≤q) (toℚᵘ-mono-≤ r≤s) ⟩toℚᵘ(q) ℚᵘ.+ toℚᵘ(s) ≃⟨ ℚᵘ.≃-sym (toℚᵘ-homo-+ q s) ⟩toℚᵘ(q + s) ∎)where open ℚᵘ.≤-Reasoning+-monoˡ-≤ : ∀ r → (_+ r) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ r p≤q = +-mono-≤ p≤q (≤-refl {r})+-monoʳ-≤ : ∀ r → (_+_ r) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ r p≤q = +-mono-≤ (≤-refl {r}) p≤q-------------------------------------------------------------------------- Properties of _+_ and _<_+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-<-≤ {p} {q} {r} {s} p<q r≤s = toℚᵘ-cancel-< (begin-stricttoℚᵘ(p + r) ≃⟨ toℚᵘ-homo-+ p r ⟩toℚᵘ(p) ℚᵘ.+ toℚᵘ(r) <⟨ ℚᵘ.+-mono-<-≤ (toℚᵘ-mono-< p<q) (toℚᵘ-mono-≤ r≤s) ⟩toℚᵘ(q) ℚᵘ.+ toℚᵘ(s) ≃⟨ ℚᵘ.≃-sym (toℚᵘ-homo-+ q s) ⟩toℚᵘ(q + s) ∎)where open ℚᵘ.≤-Reasoning+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-≤-< {p} {q} {r} {s} p≤q r<s rewrite +-comm p r | +-comm q s = +-mono-<-≤ r<s p≤q+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-mono-< {p} {q} {r} {s} p<q r<s = <-trans (+-mono-<-≤ p<q (≤-refl {r})) (+-mono-≤-< (≤-refl {q}) r<s)+-monoˡ-< : ∀ r → (_+ r) Preserves _<_ ⟶ _<_+-monoˡ-< r p<q = +-mono-<-≤ p<q (≤-refl {r})+-monoʳ-< : ∀ r → (_+_ r) Preserves _<_ ⟶ _<_+-monoʳ-< r p<q = +-mono-≤-< (≤-refl {r}) p<q-------------------------------------------------------------------------- Properties of _*_------------------------------------------------------------------------private*-nf : ℚ → ℚ → ℤ*-nf p q = gcd (↥ p ℤ.* ↥ q) (↧ p ℤ.* ↧ q)↥-* : ∀ p q → ↥ (p * q) ℤ.* *-nf p q ≡ ↥ p ℤ.* ↥ q↥-* p@record{} q@record{} = ↥-/ (↥ p ℤ.* ↥ q) (↧ₙ p ℕ.* ↧ₙ q)↧-* : ∀ p q → ↧ (p * q) ℤ.* *-nf p q ≡ ↧ p ℤ.* ↧ q↧-* p@record{} q@record{} = ↧-/ (↥ p ℤ.* ↥ q) (↧ₙ p ℕ.* ↧ₙ q)-------------------------------------------------------------------------- Monomorphic to unnormalised _*_toℚᵘ-homo-* : Homomorphic₂ toℚᵘ _*_ ℚᵘ._*_toℚᵘ-homo-* p@record{} q@record{} with *-nf p q ℤ.≟ 0ℤ... | yes nf[p,q]≡0 = *≡* $ begin↥ᵘ (toℚᵘ (p * q)) ℤ.* (↧ p ℤ.* ↧ q) ≡⟨ cong (ℤ._* (↧ p ℤ.* ↧ q)) (↥ᵘ-toℚᵘ (p * q)) ⟩↥ (p * q) ℤ.* (↧ p ℤ.* ↧ q) ≡⟨ cong (ℤ._* (↧ p ℤ.* ↧ q)) eq ⟩0ℤ ℤ.* (↧ p ℤ.* ↧ q) ≡⟨⟩0ℤ ℤ.* ↧ (p * q) ≡⟨ cong (ℤ._* ↧ (p * q)) (sym eq2) ⟩(↥ p ℤ.* ↥ q) ℤ.* ↧ (p * q) ≡⟨ cong ((↥ p ℤ.* ↥ q) ℤ.*_) (sym (↧ᵘ-toℚᵘ (p * q))) ⟩(↥ p ℤ.* ↥ q) ℤ.* ↧ᵘ (toℚᵘ (p * q)) ∎whereopen ≡-Reasoningeq2 : ↥ p ℤ.* ↥ q ≡ 0ℤeq2 = gcd[i,j]≡0⇒i≡0 (↥ p ℤ.* ↥ q) (↧ p ℤ.* ↧ q) nf[p,q]≡0eq : ↥ (p * q) ≡ 0ℤeq rewrite eq2 = cong ↥_ (0/n≡0 (↧ₙ p ℕ.* ↧ₙ q))... | no nf[p,q]≢0 = *≡* (ℤ.*-cancelʳ-≡ _ _ (*-nf p q) {{ℤ.≢-nonZero nf[p,q]≢0}} $ begin↥ᵘ (toℚᵘ (p * q)) ℤ.* (↧ p ℤ.* ↧ q) ℤ.* *-nf p q ≡⟨ cong (λ v → v ℤ.* (↧ p ℤ.* ↧ q) ℤ.* *-nf p q) (↥ᵘ-toℚᵘ (p * q)) ⟩↥ (p * q) ℤ.* (↧ p ℤ.* ↧ q) ℤ.* *-nf p q ≡⟨ xy∙z≈xz∙y (↥ (p * q)) _ _ ⟩↥ (p * q) ℤ.* *-nf p q ℤ.* (↧ p ℤ.* ↧ q) ≡⟨ cong (ℤ._* (↧ p ℤ.* ↧ q)) (↥-* p q) ⟩(↥ p ℤ.* ↥ q) ℤ.* (↧ p ℤ.* ↧ q) ≡⟨ cong ((↥ p ℤ.* ↥ q) ℤ.*_) (sym (↧-* p q)) ⟩(↥ p ℤ.* ↥ q) ℤ.* (↧ (p * q) ℤ.* *-nf p q) ≡⟨ x∙yz≈xy∙z (↥ p ℤ.* ↥ q) _ _ ⟩(↥ p ℤ.* ↥ q) ℤ.* ↧ (p * q) ℤ.* *-nf p q ≡⟨ cong (λ v → (↥ p ℤ.* ↥ q) ℤ.* v ℤ.* *-nf p q) (↧ᵘ-toℚᵘ (p * q)) ⟨(↥ p ℤ.* ↥ q) ℤ.* ↧ᵘ (toℚᵘ (p * q)) ℤ.* *-nf p q ∎)where open ≡-Reasoning; open CommSemigroupProperties ℤ.*-commutativeSemigrouptoℚᵘ-homo-1/ : ∀ p .{{_ : NonZero p}} → toℚᵘ (1/ p) ℚᵘ.≃ (ℚᵘ.1/ toℚᵘ p)toℚᵘ-homo-1/ (mkℚ +[1+ _ ] _ _) = ℚᵘ.≃-refltoℚᵘ-homo-1/ (mkℚ -[1+ _ ] _ _) = ℚᵘ.≃-refltoℚᵘ-isMagmaHomomorphism-* : IsMagmaHomomorphism *-rawMagma ℚᵘ.*-rawMagma toℚᵘtoℚᵘ-isMagmaHomomorphism-* = record{ isRelHomomorphism = toℚᵘ-isRelHomomorphism; homo = toℚᵘ-homo-*}toℚᵘ-isMonoidHomomorphism-* : IsMonoidHomomorphism *-1-rawMonoid ℚᵘ.*-1-rawMonoid toℚᵘtoℚᵘ-isMonoidHomomorphism-* = record{ isMagmaHomomorphism = toℚᵘ-isMagmaHomomorphism-*; ε-homo = ℚᵘ.≃-refl}toℚᵘ-isMonoidMonomorphism-* : IsMonoidMonomorphism *-1-rawMonoid ℚᵘ.*-1-rawMonoid toℚᵘtoℚᵘ-isMonoidMonomorphism-* = record{ isMonoidHomomorphism = toℚᵘ-isMonoidHomomorphism-*; injective = toℚᵘ-injective}toℚᵘ-isNearSemiringHomomorphism-+-* : IsNearSemiringHomomorphism +-*-rawNearSemiring ℚᵘ.+-*-rawNearSemiring toℚᵘtoℚᵘ-isNearSemiringHomomorphism-+-* = record{ +-isMonoidHomomorphism = toℚᵘ-isMonoidHomomorphism-+; *-homo = toℚᵘ-homo-*}toℚᵘ-isNearSemiringMonomorphism-+-* : IsNearSemiringMonomorphism +-*-rawNearSemiring ℚᵘ.+-*-rawNearSemiring toℚᵘtoℚᵘ-isNearSemiringMonomorphism-+-* = record{ isNearSemiringHomomorphism = toℚᵘ-isNearSemiringHomomorphism-+-*; injective = toℚᵘ-injective}toℚᵘ-isSemiringHomomorphism-+-* : IsSemiringHomomorphism +-*-rawSemiring ℚᵘ.+-*-rawSemiring toℚᵘtoℚᵘ-isSemiringHomomorphism-+-* = record{ isNearSemiringHomomorphism = toℚᵘ-isNearSemiringHomomorphism-+-*; 1#-homo = ℚᵘ.≃-refl}toℚᵘ-isSemiringMonomorphism-+-* : IsSemiringMonomorphism +-*-rawSemiring ℚᵘ.+-*-rawSemiring toℚᵘtoℚᵘ-isSemiringMonomorphism-+-* = record{ isSemiringHomomorphism = toℚᵘ-isSemiringHomomorphism-+-*; injective = toℚᵘ-injective}toℚᵘ-isRingHomomorphism-+-* : IsRingHomomorphism +-*-rawRing ℚᵘ.+-*-rawRing toℚᵘtoℚᵘ-isRingHomomorphism-+-* = record{ isSemiringHomomorphism = toℚᵘ-isSemiringHomomorphism-+-*; -‿homo = toℚᵘ-homo‿-}toℚᵘ-isRingMonomorphism-+-* : IsRingMonomorphism +-*-rawRing ℚᵘ.+-*-rawRing toℚᵘtoℚᵘ-isRingMonomorphism-+-* = record{ isRingHomomorphism = toℚᵘ-isRingHomomorphism-+-*; injective = toℚᵘ-injective}-------------------------------------------------------------------------- Algebraic propertiesprivatemodule +-*-Monomorphism = RingMonomorphisms toℚᵘ-isRingMonomorphism-+-**-assoc : Associative _*_*-assoc = +-*-Monomorphism.*-assoc ℚᵘ.*-isMagma ℚᵘ.*-assoc*-comm : Commutative _*_*-comm = +-*-Monomorphism.*-comm ℚᵘ.*-isMagma ℚᵘ.*-comm*-identityˡ : LeftIdentity 1ℚ _*_*-identityˡ = +-*-Monomorphism.*-identityˡ ℚᵘ.*-isMagma ℚᵘ.*-identityˡ*-identityʳ : RightIdentity 1ℚ _*_*-identityʳ = +-*-Monomorphism.*-identityʳ ℚᵘ.*-isMagma ℚᵘ.*-identityʳ*-identity : Identity 1ℚ _*_*-identity = *-identityˡ , *-identityʳ*-zeroˡ : LeftZero 0ℚ _*_*-zeroˡ = +-*-Monomorphism.zeroˡ ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.*-zeroˡ*-zeroʳ : RightZero 0ℚ _*_*-zeroʳ = +-*-Monomorphism.zeroʳ ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.*-zeroʳ*-zero : Zero 0ℚ _*_*-zero = *-zeroˡ , *-zeroʳ*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distribˡ-+ = +-*-Monomorphism.distribˡ ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.*-distribˡ-+*-distribʳ-+ : _*_ DistributesOverʳ _+_*-distribʳ-+ = +-*-Monomorphism.distribʳ ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.*-distribʳ-+*-distrib-+ : _*_ DistributesOver _+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+*-inverseˡ : ∀ p .{{_ : NonZero p}} → (1/ p) * p ≡ 1ℚ*-inverseˡ p = toℚᵘ-injective (begin-equalitytoℚᵘ (1/ p * p) ≃⟨ toℚᵘ-homo-* (1/ p) p ⟩toℚᵘ (1/ p) ℚᵘ.* toℚᵘ p ≃⟨ ℚᵘ.*-congʳ (toℚᵘ-homo-1/ p) ⟩ℚᵘ.1/ (toℚᵘ p) ℚᵘ.* toℚᵘ p ≃⟨ ℚᵘ.*-inverseˡ (toℚᵘ p) ⟩ℚᵘ.1ℚᵘ ∎)where open ℚᵘ.≤-Reasoning*-inverseʳ : ∀ p .{{_ : NonZero p}} → p * (1/ p) ≡ 1ℚ*-inverseʳ p = trans (*-comm p (1/ p)) (*-inverseˡ p)neg-distribˡ-* : ∀ p q → - (p * q) ≡ - p * qneg-distribˡ-* = +-*-Monomorphism.neg-distribˡ-* ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.neg-distribˡ-*neg-distribʳ-* : ∀ p q → - (p * q) ≡ p * - qneg-distribʳ-* = +-*-Monomorphism.neg-distribʳ-* ℚᵘ.+-0-isGroup ℚᵘ.*-isMagma ℚᵘ.neg-distribʳ-*-------------------------------------------------------------------------- Structures*-isMagma : IsMagma _*_*-isMagma = +-*-Monomorphism.*-isMagma ℚᵘ.*-isMagma*-isSemigroup : IsSemigroup _*_*-isSemigroup = +-*-Monomorphism.*-isSemigroup ℚᵘ.*-isSemigroup*-1-isMonoid : IsMonoid _*_ 1ℚ*-1-isMonoid = +-*-Monomorphism.*-isMonoid ℚᵘ.*-1-isMonoid*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1ℚ*-1-isCommutativeMonoid = +-*-Monomorphism.*-isCommutativeMonoid ℚᵘ.*-1-isCommutativeMonoid+-*-isRing : IsRing _+_ _*_ -_ 0ℚ 1ℚ+-*-isRing = +-*-Monomorphism.isRing ℚᵘ.+-*-isRing+-*-isCommutativeRing : IsCommutativeRing _+_ _*_ -_ 0ℚ 1ℚ+-*-isCommutativeRing = +-*-Monomorphism.isCommutativeRing ℚᵘ.+-*-isCommutativeRing-------------------------------------------------------------------------- Packages*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-ring : Ring 0ℓ 0ℓ+-*-ring = record{ isRing = +-*-isRing}+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ+-*-commutativeRing = record{ isCommutativeRing = +-*-isCommutativeRing}-------------------------------------------------------------------------- HeytingField structures and bundlesmodule _ whereopen CommutativeRing +-*-commutativeRingusing (+-group; zeroˡ; *-congʳ; isCommutativeRing)open GroupProperties +-groupopen DecSetoidProperties ≡-decSetoid#⇒invertible : p ≢ q → Invertible 1ℚ _*_ (p - q)#⇒invertible {p} {q} p≢q = let r = p - q in 1/ r , *-inverseˡ r , *-inverseʳ rwhere instance _ = ≢-nonZero (p≢q ∘ (x∙y⁻¹≈ε⇒x≈y p q))invertible⇒# : Invertible 1ℚ _*_ (p - q) → p ≢ qinvertible⇒# {p} {q} (1/[p-q] , _ , [p-q]/[p-q]≡1) p≡q = contradiction 1≡0 1≢0whereopen ≈-Reasoning ≡-setoid1≡0 : 1ℚ ≡ 0ℚ1≡0 = begin1ℚ ≈⟨ [p-q]/[p-q]≡1 ⟨(p - q) * 1/[p-q] ≈⟨ *-congʳ (x≈y⇒x∙y⁻¹≈ε p≡q) ⟩0ℚ * 1/[p-q] ≈⟨ zeroˡ 1/[p-q] ⟩0ℚ ∎isHeytingCommutativeRing : IsHeytingCommutativeRing _≡_ _≢_ _+_ _*_ -_ 0ℚ 1ℚisHeytingCommutativeRing = record{ isCommutativeRing = isCommutativeRing; isApartnessRelation = ≉-isApartnessRelation; #⇒invertible = #⇒invertible; invertible⇒# = invertible⇒#}isHeytingField : IsHeytingField _≡_ _≢_ _+_ _*_ -_ 0ℚ 1ℚisHeytingField = record{ isHeytingCommutativeRing = isHeytingCommutativeRing; tight = ≉-tight}heytingCommutativeRing : HeytingCommutativeRing 0ℓ 0ℓ 0ℓheytingCommutativeRing = record { isHeytingCommutativeRing = isHeytingCommutativeRing }heytingField : HeytingField 0ℓ 0ℓ 0ℓheytingField = record { isHeytingField = isHeytingField }-------------------------------------------------------------------------- Properties of _*_ and _≤_*-cancelʳ-≤-pos : ∀ r .{{_ : Positive r}} → p * r ≤ q * r → p ≤ q*-cancelʳ-≤-pos {p} {q} r pr≤qr = toℚᵘ-cancel-≤ (ℚᵘ.*-cancelʳ-≤-pos (toℚᵘ r) (begintoℚᵘ p ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* p r ⟨toℚᵘ (p * r) ≤⟨ toℚᵘ-mono-≤ pr≤qr ⟩toℚᵘ (q * r) ≃⟨ toℚᵘ-homo-* q r ⟩toℚᵘ q ℚᵘ.* toℚᵘ r ∎))where open ℚᵘ.≤-Reasoning*-cancelˡ-≤-pos : ∀ r .{{_ : Positive r}} → r * p ≤ r * q → p ≤ q*-cancelˡ-≤-pos {p} {q} r rewrite *-comm r p | *-comm r q = *-cancelʳ-≤-pos r*-monoʳ-≤-nonNeg : ∀ r .{{_ : NonNegative r}} → (_* r) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonNeg r {p} {q} p≤q = toℚᵘ-cancel-≤ (begintoℚᵘ (p * r) ≃⟨ toℚᵘ-homo-* p r ⟩toℚᵘ p ℚᵘ.* toℚᵘ r ≤⟨ ℚᵘ.*-monoˡ-≤-nonNeg (toℚᵘ r) (toℚᵘ-mono-≤ p≤q) ⟩toℚᵘ q ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* q r ⟨toℚᵘ (q * r) ∎)where open ℚᵘ.≤-Reasoning*-monoˡ-≤-nonNeg : ∀ r .{{_ : NonNegative r}} → (r *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg r {p} {q} rewrite *-comm r p | *-comm r q = *-monoʳ-≤-nonNeg r*-monoʳ-≤-nonPos : ∀ r .{{_ : NonPositive r}} → (_* r) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos r {p} {q} p≤q = toℚᵘ-cancel-≤ (begintoℚᵘ (q * r) ≃⟨ toℚᵘ-homo-* q r ⟩toℚᵘ q ℚᵘ.* toℚᵘ r ≤⟨ ℚᵘ.*-monoˡ-≤-nonPos (toℚᵘ r) (toℚᵘ-mono-≤ p≤q) ⟩toℚᵘ p ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* p r ⟨toℚᵘ (p * r) ∎)where open ℚᵘ.≤-Reasoning*-monoˡ-≤-nonPos : ∀ r .{{_ : NonPositive r}} → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-nonPos r {p} {q} rewrite *-comm r p | *-comm r q = *-monoʳ-≤-nonPos r*-cancelʳ-≤-neg : ∀ r .{{_ : Negative r}} → p * r ≤ q * r → p ≥ q*-cancelʳ-≤-neg {p} {q} r pr≤qr = toℚᵘ-cancel-≤ (ℚᵘ.*-cancelʳ-≤-neg _ (begintoℚᵘ p ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* p r ⟨toℚᵘ (p * r) ≤⟨ toℚᵘ-mono-≤ pr≤qr ⟩toℚᵘ (q * r) ≃⟨ toℚᵘ-homo-* q r ⟩toℚᵘ q ℚᵘ.* toℚᵘ r ∎))where open ℚᵘ.≤-Reasoning*-cancelˡ-≤-neg : ∀ r .{{_ : Negative r}} → r * p ≤ r * q → p ≥ q*-cancelˡ-≤-neg {p} {q} r rewrite *-comm r p | *-comm r q = *-cancelʳ-≤-neg r-------------------------------------------------------------------------- Properties of _*_ and _<_*-monoˡ-<-pos : ∀ r .{{_ : Positive r}} → (_* r) Preserves _<_ ⟶ _<_*-monoˡ-<-pos r {p} {q} p<q = toℚᵘ-cancel-< (begin-stricttoℚᵘ (p * r) ≃⟨ toℚᵘ-homo-* p r ⟩toℚᵘ p ℚᵘ.* toℚᵘ r <⟨ ℚᵘ.*-monoˡ-<-pos (toℚᵘ r) (toℚᵘ-mono-< p<q) ⟩toℚᵘ q ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* q r ⟨toℚᵘ (q * r) ∎)where open ℚᵘ.≤-Reasoning*-monoʳ-<-pos : ∀ r .{{_ : Positive r}} → (r *_) Preserves _<_ ⟶ _<_*-monoʳ-<-pos r {p} {q} rewrite *-comm r p | *-comm r q = *-monoˡ-<-pos r*-cancelˡ-<-nonNeg : ∀ r .{{_ : NonNegative r}} → ∀ {p q} → r * p < r * q → p < q*-cancelˡ-<-nonNeg r {p} {q} rp<rq = toℚᵘ-cancel-< (ℚᵘ.*-cancelˡ-<-nonNeg (toℚᵘ r) (begin-stricttoℚᵘ r ℚᵘ.* toℚᵘ p ≃⟨ toℚᵘ-homo-* r p ⟨toℚᵘ (r * p) <⟨ toℚᵘ-mono-< rp<rq ⟩toℚᵘ (r * q) ≃⟨ toℚᵘ-homo-* r q ⟩toℚᵘ r ℚᵘ.* toℚᵘ q ∎))where open ℚᵘ.≤-Reasoning*-cancelʳ-<-nonNeg : ∀ r .{{_ : NonNegative r}} → ∀ {p q} → p * r < q * r → p < q*-cancelʳ-<-nonNeg r {p} {q} rewrite *-comm p r | *-comm q r = *-cancelˡ-<-nonNeg r*-monoˡ-<-neg : ∀ r .{{_ : Negative r}} → (_* r) Preserves _<_ ⟶ _>_*-monoˡ-<-neg r {p} {q} p<q = toℚᵘ-cancel-< (begin-stricttoℚᵘ (q * r) ≃⟨ toℚᵘ-homo-* q r ⟩toℚᵘ q ℚᵘ.* toℚᵘ r <⟨ ℚᵘ.*-monoˡ-<-neg (toℚᵘ r) (toℚᵘ-mono-< p<q) ⟩toℚᵘ p ℚᵘ.* toℚᵘ r ≃⟨ toℚᵘ-homo-* p r ⟨toℚᵘ (p * r) ∎)where open ℚᵘ.≤-Reasoning*-monoʳ-<-neg : ∀ r .{{_ : Negative r}} → (r *_) Preserves _<_ ⟶ _>_*-monoʳ-<-neg r {p} {q} rewrite *-comm r p | *-comm r q = *-monoˡ-<-neg r*-cancelˡ-<-nonPos : ∀ r .{{_ : NonPositive r}} → r * p < r * q → p > q*-cancelˡ-<-nonPos {p} {q} r rp<rq = toℚᵘ-cancel-< (ℚᵘ.*-cancelˡ-<-nonPos (toℚᵘ r) (begin-stricttoℚᵘ r ℚᵘ.* toℚᵘ p ≃⟨ toℚᵘ-homo-* r p ⟨toℚᵘ (r * p) <⟨ toℚᵘ-mono-< rp<rq ⟩toℚᵘ (r * q) ≃⟨ toℚᵘ-homo-* r q ⟩toℚᵘ r ℚᵘ.* toℚᵘ q ∎))where open ℚᵘ.≤-Reasoning*-cancelʳ-<-nonPos : ∀ r .{{_ : NonPositive r}} → p * r < q * r → p > q*-cancelʳ-<-nonPos {p} {q} r rewrite *-comm p r | *-comm q r = *-cancelˡ-<-nonPos r-------------------------------------------------------------------------- Properties of _⊓_------------------------------------------------------------------------p≤q⇒p⊔q≡q : p ≤ q → p ⊔ q ≡ qp≤q⇒p⊔q≡q {p@record{}} {q@record{}} p≤q with p ≤ᵇ q in p≰q... | true = refl... | false = contradiction (≤⇒≤ᵇ p≤q) (subst (¬_ ∘ T) (sym p≰q) λ())p≥q⇒p⊔q≡p : p ≥ q → p ⊔ q ≡ pp≥q⇒p⊔q≡p {p@record{}} {q@record{}} p≥q with p ≤ᵇ q in p≤q... | true = ≤-antisym p≥q (≤ᵇ⇒≤ (subst T (sym p≤q) _))... | false = reflp≤q⇒p⊓q≡p : p ≤ q → p ⊓ q ≡ pp≤q⇒p⊓q≡p {p@record{}} {q@record{}} p≤q with p ≤ᵇ q in p≰q... | true = refl... | false = contradiction (≤⇒≤ᵇ p≤q) (subst (¬_ ∘ T) (sym p≰q) λ())p≥q⇒p⊓q≡q : p ≥ q → p ⊓ q ≡ qp≥q⇒p⊓q≡q {p@record{}} {q@record{}} p≥q with p ≤ᵇ q in p≤q... | true = ≤-antisym (≤ᵇ⇒≤ (subst T (sym p≤q) _)) p≥q... | false = refl⊓-operator : MinOperator ≤-totalPreorder⊓-operator = record{ x≤y⇒x⊓y≈x = p≤q⇒p⊓q≡p; x≥y⇒x⊓y≈y = p≥q⇒p⊓q≡q}⊔-operator : MaxOperator ≤-totalPreorder⊔-operator = record{ x≤y⇒x⊔y≈y = p≤q⇒p⊔q≡q; x≥y⇒x⊔y≈x = p≥q⇒p⊔q≡p}-------------------------------------------------------------------------- Automatically derived properties of _⊓_ and _⊔_privatemodule ⊓-⊔-properties = MinMaxOp ⊓-operator ⊔-operatormodule ⊓-⊔-latticeProperties = LatticeMinMaxOp ⊓-operator ⊔-operatoropen ⊓-⊔-properties publicusing( ⊓-idem -- : Idempotent _⊓_; ⊓-sel -- : Selective _⊓_; ⊓-assoc -- : Associative _⊓_; ⊓-comm -- : Commutative _⊓_; ⊔-idem -- : Idempotent _⊔_; ⊔-sel -- : Selective _⊔_; ⊔-assoc -- : Associative _⊔_; ⊔-comm -- : Commutative _⊔_; ⊓-distribˡ-⊔ -- : _⊓_ DistributesOverˡ _⊔_; ⊓-distribʳ-⊔ -- : _⊓_ DistributesOverʳ _⊔_; ⊓-distrib-⊔ -- : _⊓_ DistributesOver _⊔_; ⊔-distribˡ-⊓ -- : _⊔_ DistributesOverˡ _⊓_; ⊔-distribʳ-⊓ -- : _⊔_ DistributesOverʳ _⊓_; ⊔-distrib-⊓ -- : _⊔_ DistributesOver _⊓_; ⊓-absorbs-⊔ -- : _⊓_ Absorbs _⊔_; ⊔-absorbs-⊓ -- : _⊔_ Absorbs _⊓_; ⊔-⊓-absorptive -- : Absorptive _⊔_ _⊓_; ⊓-⊔-absorptive -- : Absorptive _⊓_ _⊔_; ⊓-isMagma -- : IsMagma _⊓_; ⊓-isSemigroup -- : IsSemigroup _⊓_; ⊓-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊓_; ⊓-isBand -- : IsBand _⊓_; ⊓-isSelectiveMagma -- : IsSelectiveMagma _⊓_; ⊔-isMagma -- : IsMagma _⊔_; ⊔-isSemigroup -- : IsSemigroup _⊔_; ⊔-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊔_; ⊔-isBand -- : IsBand _⊔_; ⊔-isSelectiveMagma -- : IsSelectiveMagma _⊔_; ⊓-magma -- : Magma _ _; ⊓-semigroup -- : Semigroup _ _; ⊓-band -- : Band _ _; ⊓-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊓-selectiveMagma -- : SelectiveMagma _ _; ⊔-magma -- : Magma _ _; ⊔-semigroup -- : Semigroup _ _; ⊔-band -- : Band _ _; ⊔-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊔-selectiveMagma -- : SelectiveMagma _ _; ⊓-glb -- : ∀ {p q r} → p ≥ r → q ≥ r → p ⊓ q ≥ r; ⊓-triangulate -- : ∀ p q r → p ⊓ q ⊓ r ≡ (p ⊓ q) ⊓ (q ⊓ r); ⊓-mono-≤ -- : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊓-monoˡ-≤ -- : ∀ p → (_⊓ p) Preserves _≤_ ⟶ _≤_; ⊓-monoʳ-≤ -- : ∀ p → (p ⊓_) Preserves _≤_ ⟶ _≤_; ⊔-lub -- : ∀ {p q r} → p ≤ r → q ≤ r → p ⊔ q ≤ r; ⊔-triangulate -- : ∀ p q r → p ⊔ q ⊔ r ≡ (p ⊔ q) ⊔ (q ⊔ r); ⊔-mono-≤ -- : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊔-monoˡ-≤ -- : ∀ p → (_⊔ p) Preserves _≤_ ⟶ _≤_; ⊔-monoʳ-≤ -- : ∀ p → (p ⊔_) Preserves _≤_ ⟶ _≤_)renaming( x⊓y≈y⇒y≤x to p⊓q≡q⇒q≤p -- : ∀ {p q} → p ⊓ q ≡ q → q ≤ p; x⊓y≈x⇒x≤y to p⊓q≡p⇒p≤q -- : ∀ {p q} → p ⊓ q ≡ p → p ≤ q; x⊓y≤x to p⊓q≤p -- : ∀ p q → p ⊓ q ≤ p; x⊓y≤y to p⊓q≤q -- : ∀ p q → p ⊓ q ≤ q; x≤y⇒x⊓z≤y to p≤q⇒p⊓r≤q -- : ∀ {p q} r → p ≤ q → p ⊓ r ≤ q; x≤y⇒z⊓x≤y to p≤q⇒r⊓p≤q -- : ∀ {p q} r → p ≤ q → r ⊓ p ≤ q; x≤y⊓z⇒x≤y to p≤q⊓r⇒p≤q -- : ∀ {p} q r → p ≤ q ⊓ r → p ≤ q; x≤y⊓z⇒x≤z to p≤q⊓r⇒p≤r -- : ∀ {p} q r → p ≤ q ⊓ r → p ≤ r; x⊔y≈y⇒x≤y to p⊔q≡q⇒p≤q -- : ∀ {p q} → p ⊔ q ≡ q → p ≤ q; x⊔y≈x⇒y≤x to p⊔q≡p⇒q≤p -- : ∀ {p q} → p ⊔ q ≡ p → q ≤ p; x≤x⊔y to p≤p⊔q -- : ∀ p q → p ≤ p ⊔ q; x≤y⊔x to p≤q⊔p -- : ∀ p q → p ≤ q ⊔ p; x≤y⇒x≤y⊔z to p≤q⇒p≤q⊔r -- : ∀ {p q} r → p ≤ q → p ≤ q ⊔ r; x≤y⇒x≤z⊔y to p≤q⇒p≤r⊔q -- : ∀ {p q} r → p ≤ q → p ≤ r ⊔ q; x⊔y≤z⇒x≤z to p⊔q≤r⇒p≤r -- : ∀ p q {r} → p ⊔ q ≤ r → p ≤ r; x⊔y≤z⇒y≤z to p⊔q≤r⇒q≤r -- : ∀ p q {r} → p ⊔ q ≤ r → q ≤ r; x⊓y≤x⊔y to p⊓q≤p⊔q -- : ∀ p q → p ⊓ q ≤ p ⊔ q)open ⊓-⊔-latticeProperties publicusing( ⊓-isSemilattice -- : IsSemilattice _⊓_; ⊔-isSemilattice -- : IsSemilattice _⊔_; ⊔-⊓-isLattice -- : IsLattice _⊔_ _⊓_; ⊓-⊔-isLattice -- : IsLattice _⊓_ _⊔_; ⊔-⊓-isDistributiveLattice -- : IsDistributiveLattice _⊔_ _⊓_; ⊓-⊔-isDistributiveLattice -- : IsDistributiveLattice _⊓_ _⊔_; ⊓-semilattice -- : Semilattice _ _; ⊔-semilattice -- : Semilattice _ _; ⊔-⊓-lattice -- : Lattice _ _; ⊓-⊔-lattice -- : Lattice _ _; ⊔-⊓-distributiveLattice -- : DistributiveLattice _ _; ⊓-⊔-distributiveLattice -- : DistributiveLattice _ _)-------------------------------------------------------------------------- Other properties of _⊓_ and _⊔_mono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ p q → f (p ⊔ q) ≡ f p ⊔ f qmono-≤-distrib-⊔ {f} = ⊓-⊔-properties.mono-≤-distrib-⊔ (cong f)mono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ p q → f (p ⊓ q) ≡ f p ⊓ f qmono-≤-distrib-⊓ {f} = ⊓-⊔-properties.mono-≤-distrib-⊓ (cong f)mono-<-distrib-⊓ : ∀ {f} → f Preserves _<_ ⟶ _<_ →∀ p q → f (p ⊓ q) ≡ f p ⊓ f qmono-<-distrib-⊓ {f} f-mono-< p q with <-cmp p q... | tri< p<q p≢r p≯q = beginf (p ⊓ q) ≡⟨ cong f (p≤q⇒p⊓q≡p (<⇒≤ p<q)) ⟩f p ≡⟨ p≤q⇒p⊓q≡p (<⇒≤ (f-mono-< p<q)) ⟨f p ⊓ f q ∎where open ≡-Reasoning... | tri≈ p≮q refl p≯q = beginf (p ⊓ q) ≡⟨ cong f (⊓-idem p) ⟩f p ≡⟨ ⊓-idem (f p) ⟨f p ⊓ f q ∎where open ≡-Reasoning... | tri> p≮q p≡r p>q = beginf (p ⊓ q) ≡⟨ cong f (p≥q⇒p⊓q≡q (<⇒≤ p>q)) ⟩f q ≡⟨ p≥q⇒p⊓q≡q (<⇒≤ (f-mono-< p>q)) ⟨f p ⊓ f q ∎where open ≡-Reasoningmono-<-distrib-⊔ : ∀ {f} → f Preserves _<_ ⟶ _<_ →∀ p q → f (p ⊔ q) ≡ f p ⊔ f qmono-<-distrib-⊔ {f} f-mono-< p q with <-cmp p q... | tri< p<q p≢r p≯q = beginf (p ⊔ q) ≡⟨ cong f (p≤q⇒p⊔q≡q (<⇒≤ p<q)) ⟩f q ≡⟨ p≤q⇒p⊔q≡q (<⇒≤ (f-mono-< p<q)) ⟨f p ⊔ f q ∎where open ≡-Reasoning... | tri≈ p≮q refl p≯q = beginf (p ⊔ q) ≡⟨ cong f (⊔-idem p) ⟩f q ≡⟨ ⊔-idem (f p) ⟨f p ⊔ f q ∎where open ≡-Reasoning... | tri> p≮q p≡r p>q = beginf (p ⊔ q) ≡⟨ cong f (p≥q⇒p⊔q≡p (<⇒≤ p>q)) ⟩f p ≡⟨ p≥q⇒p⊔q≡p (<⇒≤ (f-mono-< p>q)) ⟨f p ⊔ f q ∎where open ≡-Reasoningantimono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ p q → f (p ⊓ q) ≡ f p ⊔ f qantimono-≤-distrib-⊓ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊓ (cong f)antimono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ p q → f (p ⊔ q) ≡ f p ⊓ f qantimono-≤-distrib-⊔ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊔ (cong f)-------------------------------------------------------------------------- Properties of _⊓_ and _*_*-distribˡ-⊓-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → p * (q ⊓ r) ≡ (p * q) ⊓ (p * r)*-distribˡ-⊓-nonNeg p = mono-≤-distrib-⊓ (*-monoˡ-≤-nonNeg p)*-distribʳ-⊓-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → (q ⊓ r) * p ≡ (q * p) ⊓ (r * p)*-distribʳ-⊓-nonNeg p = mono-≤-distrib-⊓ (*-monoʳ-≤-nonNeg p)*-distribˡ-⊔-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → p * (q ⊔ r) ≡ (p * q) ⊔ (p * r)*-distribˡ-⊔-nonNeg p = mono-≤-distrib-⊔ (*-monoˡ-≤-nonNeg p)*-distribʳ-⊔-nonNeg : ∀ p .{{_ : NonNegative p}} → ∀ q r → (q ⊔ r) * p ≡ (q * p) ⊔ (r * p)*-distribʳ-⊔-nonNeg p = mono-≤-distrib-⊔ (*-monoʳ-≤-nonNeg p)-------------------------------------------------------------------------- Properties of _⊓_, _⊔_ and _*_*-distribˡ-⊔-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → p * (q ⊔ r) ≡ (p * q) ⊓ (p * r)*-distribˡ-⊔-nonPos p = antimono-≤-distrib-⊔ (*-monoˡ-≤-nonPos p)*-distribʳ-⊔-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → (q ⊔ r) * p ≡ (q * p) ⊓ (r * p)*-distribʳ-⊔-nonPos p = antimono-≤-distrib-⊔ (*-monoʳ-≤-nonPos p)*-distribˡ-⊓-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → p * (q ⊓ r) ≡ (p * q) ⊔ (p * r)*-distribˡ-⊓-nonPos p = antimono-≤-distrib-⊓ (*-monoˡ-≤-nonPos p)*-distribʳ-⊓-nonPos : ∀ p .{{_ : NonPositive p}} → ∀ q r → (q ⊓ r) * p ≡ (q * p) ⊔ (r * p)*-distribʳ-⊓-nonPos p = antimono-≤-distrib-⊓ (*-monoʳ-≤-nonPos p)-------------------------------------------------------------------------- Properties of 1/_------------------------------------------------------------------------nonZero⇒1/nonZero : ∀ p .{{_ : NonZero p}} → NonZero (1/ p)nonZero⇒1/nonZero (mkℚ +[1+ _ ] _ _) = _nonZero⇒1/nonZero (mkℚ -[1+ _ ] _ _) = _1/-involutive : ∀ p .{{_ : NonZero p}} → (1/ (1/ p)) {{nonZero⇒1/nonZero p}} ≡ p1/-involutive (mkℚ +[1+ n ] d-1 _) = refl1/-involutive (mkℚ -[1+ n ] d-1 _) = refl1/pos⇒pos : ∀ p .{{_ : Positive p}} → Positive ((1/ p) {{pos⇒nonZero p}})1/pos⇒pos (mkℚ +[1+ _ ] _ _) = _1/neg⇒neg : ∀ p .{{_ : Negative p}} → Negative ((1/ p) {{neg⇒nonZero p}})1/neg⇒neg (mkℚ -[1+ _ ] _ _) = _pos⇒1/pos : ∀ p .{{_ : NonZero p}} .{{_ : Positive (1/ p)}} → Positive ppos⇒1/pos p = subst Positive (1/-involutive p) (1/pos⇒pos (1/ p))neg⇒1/neg : ∀ p .{{_ : NonZero p}} .{{_ : Negative (1/ p)}} → Negative pneg⇒1/neg p = subst Negative (1/-involutive p) (1/neg⇒neg (1/ p))-------------------------------------------------------------------------- Properties of ∣_∣-------------------------------------------------------------------------------------------------------------------------------------------------- Monomorphic to unnormalised -_toℚᵘ-homo-∣-∣ : Homomorphic₁ toℚᵘ ∣_∣ ℚᵘ.∣_∣toℚᵘ-homo-∣-∣ (mkℚ +[1+ _ ] _ _) = *≡* refltoℚᵘ-homo-∣-∣ (mkℚ +0 _ _) = *≡* refltoℚᵘ-homo-∣-∣ (mkℚ -[1+ _ ] _ _) = *≡* refl-------------------------------------------------------------------------- Properties∣p∣≡0⇒p≡0 : ∀ p → ∣ p ∣ ≡ 0ℚ → p ≡ 0ℚ∣p∣≡0⇒p≡0 (mkℚ +0 zero _) ∣p∣≡0 = refl0≤∣p∣ : ∀ p → 0ℚ ≤ ∣ p ∣0≤∣p∣ p@record{} = *≤* (begin(↥ 0ℚ) ℤ.* (↧ ∣ p ∣) ≡⟨ ℤ.*-zeroˡ (↧ ∣ p ∣) ⟩0ℤ ≤⟨ ℤ.+≤+ ℕ.z≤n ⟩↥ ∣ p ∣ ≡⟨ ℤ.*-identityʳ (↥ ∣ p ∣) ⟨↥ ∣ p ∣ ℤ.* 1ℤ ∎)where open ℤ.≤-Reasoning0≤p⇒∣p∣≡p : 0ℚ ≤ p → ∣ p ∣ ≡ p0≤p⇒∣p∣≡p {p@record{}} 0≤p = toℚᵘ-injective (ℚᵘ.0≤p⇒∣p∣≃p (toℚᵘ-mono-≤ 0≤p))∣-p∣≡∣p∣ : ∀ p → ∣ - p ∣ ≡ ∣ p ∣∣-p∣≡∣p∣ (mkℚ +[1+ n ] d-1 _) = refl∣-p∣≡∣p∣ (mkℚ +0 d-1 _) = refl∣-p∣≡∣p∣ (mkℚ -[1+ n ] d-1 _) = refl∣p∣≡p⇒0≤p : ∀ {p} → ∣ p ∣ ≡ p → 0ℚ ≤ p∣p∣≡p⇒0≤p {p} ∣p∣≡p = toℚᵘ-cancel-≤ (ℚᵘ.∣p∣≃p⇒0≤p (begin-equalityℚᵘ.∣ toℚᵘ p ∣ ≃⟨ ℚᵘ.≃-sym (toℚᵘ-homo-∣-∣ p) ⟩toℚᵘ ∣ p ∣ ≡⟨ cong toℚᵘ ∣p∣≡p ⟩toℚᵘ p ∎))where open ℚᵘ.≤-Reasoning∣p∣≡p∨∣p∣≡-p : ∀ p → ∣ p ∣ ≡ p ⊎ ∣ p ∣ ≡ - p∣p∣≡p∨∣p∣≡-p (mkℚ (+ n) d-1 _) = inj₁ refl∣p∣≡p∨∣p∣≡-p (mkℚ (-[1+ n ]) d-1 _) = inj₂ refl∣p+q∣≤∣p∣+∣q∣ : ∀ p q → ∣ p + q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p+q∣≤∣p∣+∣q∣ p q = toℚᵘ-cancel-≤ (begintoℚᵘ ∣ p + q ∣ ≃⟨ toℚᵘ-homo-∣-∣ (p + q) ⟩ℚᵘ.∣ toℚᵘ (p + q) ∣ ≃⟨ ℚᵘ.∣-∣-cong (toℚᵘ-homo-+ p q) ⟩ℚᵘ.∣ toℚᵘ p ℚᵘ.+ toℚᵘ q ∣ ≤⟨ ℚᵘ.∣p+q∣≤∣p∣+∣q∣ (toℚᵘ p) (toℚᵘ q) ⟩ℚᵘ.∣ toℚᵘ p ∣ ℚᵘ.+ ℚᵘ.∣ toℚᵘ q ∣ ≃⟨ ℚᵘ.+-cong (toℚᵘ-homo-∣-∣ p) (toℚᵘ-homo-∣-∣ q) ⟨toℚᵘ ∣ p ∣ ℚᵘ.+ toℚᵘ ∣ q ∣ ≃⟨ toℚᵘ-homo-+ ∣ p ∣ ∣ q ∣ ⟨toℚᵘ (∣ p ∣ + ∣ q ∣) ∎)where open ℚᵘ.≤-Reasoning∣p-q∣≤∣p∣+∣q∣ : ∀ p q → ∣ p - q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p-q∣≤∣p∣+∣q∣ p@record{} q@record{} = begin∣ p - q ∣ ≤⟨ ∣p+q∣≤∣p∣+∣q∣ p (- q) ⟩∣ p ∣ + ∣ - q ∣ ≡⟨ cong (λ h → ∣ p ∣ + h) (∣-p∣≡∣p∣ q) ⟩∣ p ∣ + ∣ q ∣ ∎where open ≤-Reasoning∣p*q∣≡∣p∣*∣q∣ : ∀ p q → ∣ p * q ∣ ≡ ∣ p ∣ * ∣ q ∣∣p*q∣≡∣p∣*∣q∣ p q = toℚᵘ-injective (begin-equalitytoℚᵘ ∣ p * q ∣ ≃⟨ toℚᵘ-homo-∣-∣ (p * q) ⟩ℚᵘ.∣ toℚᵘ (p * q) ∣ ≃⟨ ℚᵘ.∣-∣-cong (toℚᵘ-homo-* p q) ⟩ℚᵘ.∣ toℚᵘ p ℚᵘ.* toℚᵘ q ∣ ≃⟨ ℚᵘ.∣p*q∣≃∣p∣*∣q∣ (toℚᵘ p) (toℚᵘ q) ⟩ℚᵘ.∣ toℚᵘ p ∣ ℚᵘ.* ℚᵘ.∣ toℚᵘ q ∣ ≃⟨ ℚᵘ.*-cong (toℚᵘ-homo-∣-∣ p) (toℚᵘ-homo-∣-∣ q) ⟨toℚᵘ ∣ p ∣ ℚᵘ.* toℚᵘ ∣ q ∣ ≃⟨ toℚᵘ-homo-* ∣ p ∣ ∣ q ∣ ⟨toℚᵘ (∣ p ∣ * ∣ q ∣) ∎)where open ℚᵘ.≤-Reasoning∣-∣-nonNeg : ∀ p → NonNegative ∣ p ∣∣-∣-nonNeg (mkℚ +[1+ _ ] _ _) = _∣-∣-nonNeg (mkℚ +0 _ _) = _∣-∣-nonNeg (mkℚ -[1+ _ ] _ _) = _∣∣p∣∣≡∣p∣ : ∀ p → ∣ ∣ p ∣ ∣ ≡ ∣ p ∣∣∣p∣∣≡∣p∣ p = 0≤p⇒∣p∣≡p (0≤∣p∣ p)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0*-monoʳ-≤-neg : ∀ r → Negative r → (_* r) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-neg r@(mkℚ -[1+ _ ] _ _) _ = *-monoʳ-≤-nonPos r{-# WARNING_ON_USAGE *-monoʳ-≤-neg"Warning: *-monoʳ-≤-neg was deprecated in v2.0.Please use *-monoʳ-≤-nonPos instead."#-}*-monoˡ-≤-neg : ∀ r → Negative r → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg r@(mkℚ -[1+ _ ] _ _) _ = *-monoˡ-≤-nonPos r{-# WARNING_ON_USAGE *-monoˡ-≤-neg"Warning: *-monoˡ-≤-neg was deprecated in v2.0.Please use *-monoˡ-≤-nonPos instead."#-}*-monoʳ-≤-pos : ∀ r → Positive r → (_* r) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-pos r@(mkℚ +[1+ _ ] _ _) _ = *-monoʳ-≤-nonNeg r{-# WARNING_ON_USAGE *-monoʳ-≤-pos"Warning: *-monoʳ-≤-pos was deprecated in v2.0.Please use *-monoʳ-≤-nonNeg instead."#-}*-monoˡ-≤-pos : ∀ r → Positive r → (r *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-pos r@(mkℚ +[1+ _ ] _ _) _ = *-monoˡ-≤-nonNeg r{-# WARNING_ON_USAGE *-monoˡ-≤-pos"Warning: *-monoˡ-≤-pos was deprecated in v2.0.Please use *-monoˡ-≤-nonNeg instead."#-}*-cancelˡ-<-pos : ∀ r → Positive r → ∀ {p q} → r * p < r * q → p < q*-cancelˡ-<-pos r@(mkℚ +[1+ _ ] _ _) _ = *-cancelˡ-<-nonNeg r{-# WARNING_ON_USAGE *-cancelˡ-<-pos"Warning: *-cancelˡ-<-pos was deprecated in v2.0.Please use *-cancelˡ-<-nonNeg instead."#-}*-cancelʳ-<-pos : ∀ r → Positive r → ∀ {p q} → p * r < q * r → p < q*-cancelʳ-<-pos r@(mkℚ +[1+ _ ] _ _) _ = *-cancelʳ-<-nonNeg r{-# WARNING_ON_USAGE *-cancelʳ-<-pos"Warning: *-cancelʳ-<-pos was deprecated in v2.0.Please use *-cancelʳ-<-nonNeg instead."#-}*-cancelˡ-<-neg : ∀ r → Negative r → ∀ {p q} → r * p < r * q → p > q*-cancelˡ-<-neg r@(mkℚ -[1+ _ ] _ _) _ = *-cancelˡ-<-nonPos r{-# WARNING_ON_USAGE *-cancelˡ-<-neg"Warning: *-cancelˡ-<-neg was deprecated in v2.0.Please use *-cancelˡ-<-nonPos instead."#-}*-cancelʳ-<-neg : ∀ r → Negative r → ∀ {p q} → p * r < q * r → p > q*-cancelʳ-<-neg r@(mkℚ -[1+ _ ] _ _) _ = *-cancelʳ-<-nonPos r{-# WARNING_ON_USAGE *-cancelʳ-<-neg"Warning: *-cancelʳ-<-neg was deprecated in v2.0.Please use *-cancelʳ-<-nonPos instead."#-}negative<positive : Negative p → Positive q → p < qnegative<positive {p} {q} p<0 q>0 = neg<pos p q {{p<0}} {{q>0}}{-# WARNING_ON_USAGE negative<positive"Warning: negative<positive was deprecated in v2.0.Please use neg<pos instead."#-}{- issue1865/issue1755: raw bundles have moved to `Data.X.Base` -}open Data.Rational.Base publicusing (+-rawMagma; +-0-rawGroup; *-rawMagma; +-*-rawNearSemiring; +-*-rawSemiring; +-*-rawRing)renaming (+-0-rawMonoid to +-rawMonoid; *-1-rawMonoid to *-rawMonoid)
-------------------------------------------------------------------------- The Agda standard library---- Rational Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Agda.Builtin.FromNeg using (Negative)open import Data.Unit.Base using (⊤)open import Data.Nat.Base using (ℕ; zero)open import Data.Nat.Coprimality using (sym; 1-coprimeTo)open import Data.Integer.Base using (ℤ; ∣_∣; +_; -_)open import Data.Rational.Base using (ℚ)fromℤ : ℤ → ℚfromℤ z = record{ numerator = z; denominator-1 = zero; isCoprime = sym (1-coprimeTo ∣ z ∣)}number : Number ℚnumber = record{ Constraint = λ _ → ⊤; fromNat = λ n → fromℤ (+ n)}negative : Negative ℚnegative = record{ Constraint = λ _ → ⊤; fromNeg = λ n → fromℤ (- (+ n))}
-------------------------------------------------------------------------- The Agda standard library---- Instances for rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Instances whereopen import Data.Rational.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceℚ-≡-isDecEquivalence = isDecEquivalence _≟_ℚ-≤-isDecTotalOrder = ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Rational numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Rational.Base whereopen import Algebra.Bundles.Rawopen import Data.Bool.Base using (Bool; true; false; if_then_else_)open import Data.Integer.Base as ℤusing (ℤ; +_; +0; +[1+_]; -[1+_])hiding (module ℤ)open import Data.Nat.GCDopen import Data.Nat.Coprimality as ℕusing (Coprime; Bézout-coprime; coprime-/gcd; coprime?; ¬0-coprimeTo-2+)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; 2+) hiding (module ℕ)open import Data.Rational.Unnormalised.Base as ℚᵘ using (ℚᵘ; mkℚᵘ)open import Data.Sum.Base using (inj₂)open import Function.Base using (id)open import Level using (0ℓ)open import Relation.Nullary.Decidable.Core using (recompute)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Unary using (Pred)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl)-------------------------------------------------------------------------- Rational numbers in reduced form. Note that there is exactly one-- way to represent every rational number.record ℚ : Set where-- We add "no-eta-equality; pattern" to the record to stop Agda-- automatically unfolding rationals when arithmetic operations are-- applied to them (see definition of operators below and Issue #1753-- for details).no-eta-equality; patternconstructor mkℚfieldnumerator : ℤdenominator-1 : ℕ.isCoprime : Coprime ℤ.∣ numerator ∣ (suc denominator-1)denominatorℕ : ℕdenominatorℕ = suc denominator-1denominator : ℤdenominator = + denominatorℕopen ℚ public using ()renaming( numerator to ↥_; denominator to ↧_; denominatorℕ to ↧ₙ_)mkℚ+ : ∀ n d → .{{_ : ℕ.NonZero d}} → .(Coprime n d) → ℚmkℚ+ n (suc d) coprime = mkℚ (+ n) d coprime-------------------------------------------------------------------------- Equality of rational numbers (coincides with _≡_)infix 4 _≃_data _≃_ : Rel ℚ 0ℓ where*≡* : ∀ {p q} → (↥ p ℤ.* ↧ q) ≡ (↥ q ℤ.* ↧ p) → p ≃ q_≄_ : Rel ℚ 0ℓp ≄ q = ¬ (p ≃ q)-------------------------------------------------------------------------- Ordering of rationalsinfix 4 _≤_ _<_ _≥_ _>_ _≰_ _≱_ _≮_ _≯_data _≤_ : Rel ℚ 0ℓ where*≤* : ∀ {p q} → (↥ p ℤ.* ↧ q) ℤ.≤ (↥ q ℤ.* ↧ p) → p ≤ qdata _<_ : Rel ℚ 0ℓ where*<* : ∀ {p q} → (↥ p ℤ.* ↧ q) ℤ.< (↥ q ℤ.* ↧ p) → p < q_≥_ : Rel ℚ 0ℓx ≥ y = y ≤ x_>_ : Rel ℚ 0ℓx > y = y < x_≰_ : Rel ℚ 0ℓx ≰ y = ¬ (x ≤ y)_≱_ : Rel ℚ 0ℓx ≱ y = ¬ (x ≥ y)_≮_ : Rel ℚ 0ℓx ≮ y = ¬ (x < y)_≯_ : Rel ℚ 0ℓx ≯ y = ¬ (x > y)-------------------------------------------------------------------------- Boolean orderinginfix 4 _≤ᵇ__≤ᵇ_ : ℚ → ℚ → Boolp ≤ᵇ q = (↥ p ℤ.* ↧ q) ℤ.≤ᵇ (↥ q ℤ.* ↧ p)-------------------------------------------------------------------------- Negation-_ : ℚ → ℚ- mkℚ -[1+ n ] d prf = mkℚ +[1+ n ] d prf- mkℚ +0 d prf = mkℚ +0 d prf- mkℚ +[1+ n ] d prf = mkℚ -[1+ n ] d prf-------------------------------------------------------------------------- Constructing rationals-- A constructor for ℚ that takes two natural numbers, say 6 and 21,-- and returns them in a normalized form, e.g. say 2 and 7normalize : ∀ (m n : ℕ) .{{_ : ℕ.NonZero n}} → ℚnormalize m n = mkℚ+ (m ℕ./ gcd m n) (n ℕ./ gcd m n) (coprime-/gcd m n)whereinstanceg≢0 = ℕ.≢-nonZero (gcd[m,n]≢0 m n (inj₂ (ℕ.≢-nonZero⁻¹ n)))n/g≢0 = ℕ.≢-nonZero (n/gcd[m,n]≢0 m n {{gcd≢0 = g≢0}})-- A constructor for ℚ that (unlike mkℚ) automatically normalises it's-- arguments. See the constants section below for how to use this operator.infixl 7 _/__/_ : (n : ℤ) (d : ℕ) → .{{_ : ℕ.NonZero d}} → ℚ(+ n / d) = normalize n d(-[1+ n ] / d) = - normalize (suc n) d-------------------------------------------------------------------------- Conversion to and from unnormalized rationalstoℚᵘ : ℚ → ℚᵘtoℚᵘ (mkℚ n d-1 _) = mkℚᵘ n d-1fromℚᵘ : ℚᵘ → ℚfromℚᵘ (mkℚᵘ n d-1) = n / suc d-1-------------------------------------------------------------------------- Some constants0ℚ : ℚ0ℚ = + 0 / 11ℚ : ℚ1ℚ = + 1 / 1½ : ℚ½ = + 1 / 2-½ : ℚ-½ = - ½-------------------------------------------------------------------------- Simple predicatesNonZero : Pred ℚ 0ℓNonZero p = ℚᵘ.NonZero (toℚᵘ p)Positive : Pred ℚ 0ℓPositive p = ℚᵘ.Positive (toℚᵘ p)Negative : Pred ℚ 0ℓNegative p = ℚᵘ.Negative (toℚᵘ p)NonPositive : Pred ℚ 0ℓNonPositive p = ℚᵘ.NonPositive (toℚᵘ p)NonNegative : Pred ℚ 0ℓNonNegative p = ℚᵘ.NonNegative (toℚᵘ p)-- Instancesopen ℤ publicusing (nonZero; pos; nonNeg; nonPos0; nonPos; neg)-- Constructors≢-nonZero : ∀ {p} → p ≢ 0ℚ → NonZero p≢-nonZero {mkℚ -[1+ _ ] _ _} _ = _≢-nonZero {mkℚ +[1+ _ ] _ _} _ = _≢-nonZero {mkℚ +0 zero _} p≢0 = contradiction refl p≢0≢-nonZero {mkℚ +0 d@(suc m) c} p≢0 =contradiction (λ {d} → ℕ.recompute c {d}) (¬0-coprimeTo-2+ {{ℕ.nonTrivial {m}}})>-nonZero : ∀ {p} → p > 0ℚ → NonZero p>-nonZero {p@(mkℚ _ _ _)} (*<* p<q) = ℚᵘ.>-nonZero {toℚᵘ p} (ℚᵘ.*<* p<q)<-nonZero : ∀ {p} → p < 0ℚ → NonZero p<-nonZero {p@(mkℚ _ _ _)} (*<* p<q) = ℚᵘ.<-nonZero {toℚᵘ p} (ℚᵘ.*<* p<q)positive : ∀ {p} → p > 0ℚ → Positive ppositive {p@(mkℚ _ _ _)} (*<* p<q) = ℚᵘ.positive {toℚᵘ p} (ℚᵘ.*<* p<q)negative : ∀ {p} → p < 0ℚ → Negative pnegative {p@(mkℚ _ _ _)} (*<* p<q) = ℚᵘ.negative {toℚᵘ p} (ℚᵘ.*<* p<q)nonPositive : ∀ {p} → p ≤ 0ℚ → NonPositive pnonPositive {p@(mkℚ _ _ _)} (*≤* p≤q) = ℚᵘ.nonPositive {toℚᵘ p} (ℚᵘ.*≤* p≤q)nonNegative : ∀ {p} → p ≥ 0ℚ → NonNegative pnonNegative {p@(mkℚ _ _ _)} (*≤* p≤q) = ℚᵘ.nonNegative {toℚᵘ p} (ℚᵘ.*≤* p≤q)-------------------------------------------------------------------------- Operations on rationals-- For explanation of the `@record{}` annotations see notes in the-- equivalent place in `Data.Rational.Unnormalised.Base`.infix 8 -_ 1/_infixl 7 _*_ _÷_ _⊓_infixl 6 _-_ _+_ _⊔_-- addition_+_ : ℚ → ℚ → ℚp@record{} + q@record{} = (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)-- multiplication_*_ : ℚ → ℚ → ℚp@record{} * q@record{} = (↥ p ℤ.* ↥ q) / (↧ₙ p ℕ.* ↧ₙ q)-- subtraction_-_ : ℚ → ℚ → ℚp - q = p + (- q)-- reciprocal: requires a proof that the numerator is not zero1/_ : (p : ℚ) → .{{_ : NonZero p}} → ℚ1/ mkℚ +[1+ n ] d prf = mkℚ +[1+ d ] n (ℕ.sym prf)1/ mkℚ -[1+ n ] d prf = mkℚ -[1+ d ] n (ℕ.sym prf)-- division: requires a proof that the denominator is not zero_÷_ : (p q : ℚ) → .{{_ : NonZero q}} → ℚp ÷ q = p * (1/ q)-- max_⊔_ : (p q : ℚ) → ℚp@record{} ⊔ q@record{} = if p ≤ᵇ q then q else p-- min_⊓_ : (p q : ℚ) → ℚp@record{} ⊓ q@record{} = if p ≤ᵇ q then p else q-- absolute value∣_∣ : ℚ → ℚ∣ mkℚ n d c ∣ = mkℚ (+ ℤ.∣ n ∣) d c-------------------------------------------------------------------------- Rounding functions-- Floor (round towards -∞)floor : ℚ → ℤfloor p@record{} = ↥ p ℤ./ ↧ p-- Ceiling (round towards +∞)ceiling : ℚ → ℤceiling p@record{} = ℤ.- floor (- p)-- Truncate (round towards 0)truncate : ℚ → ℤtruncate p = if p ≤ᵇ 0ℚ then ceiling p else floor p-- Round (to nearest integer)round : ℚ → ℤround p = if p ≤ᵇ 0ℚ then ceiling (p - ½) else floor (p + ½)-- Fractional part (remainder after floor)fracPart : ℚ → ℚfracPart p@record{} = ∣ p - truncate p / 1 ∣-- Extra notations ⌊ ⌋ floor, ⌈ ⌉ ceiling, [ ] truncatesyntax floor p = ⌊ p ⌋syntax ceiling p = ⌈ p ⌉syntax truncate p = [ p ]-------------------------------------------------------------------------- Raw bundles+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record{ _≈_ = _≡_; _∙_ = _+_}+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record{ _≈_ = _≡_; _∙_ = _+_; ε = 0ℚ}+-0-rawGroup : RawGroup 0ℓ 0ℓ+-0-rawGroup = record{ _≈_ = _≡_; _∙_ = _+_; ε = 0ℚ; _⁻¹ = -_}+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawNearSemiring = record{ _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℚ}+-*-rawSemiring : RawSemiring 0ℓ 0ℓ+-*-rawSemiring = record{ _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℚ; 1# = 1ℚ}+-*-rawRing : RawRing 0ℓ 0ℓ+-*-rawRing = record{ _≈_ = _≡_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0ℚ; 1# = 1ℚ}*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≡_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≡_; _∙_ = _*_; ε = 1ℚ}-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0+-rawMonoid = +-0-rawMonoid{-# WARNING_ON_USAGE +-rawMonoid"Warning: +-rawMonoid was deprecated in v2.0Please use +-0-rawMonoid instead."#-}*-rawMonoid = *-1-rawMonoid{-# WARNING_ON_USAGE *-rawMonoid"Warning: *-rawMonoid was deprecated in v2.0Please use *-1-rawMonoid instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product whereopen import Level using (Level; _⊔_)open import Relation.Nullary.Negation.Core using (¬_)privatevariablea b c ℓ p q r s : LevelA B C : Set a-------------------------------------------------------------------------- Definition of dependent productsopen import Data.Product.Base public-- These are here as they are not 'basic' but instead "very dependent",-- i.e. the result type depends on the full input 'point' (x , y).map-Σ : {B : A → Set b} {P : A → Set p} {Q : {x : A} → P x → B x → Set q} →(f : (x : A) → B x) → (∀ {x} → (y : P x) → Q y (f x)) →((x , y) : Σ A P) → Σ (B x) (Q y)map-Σ f g (x , y) = (f x , g y)-- This is a "non-dependent" version of map-Σ whereby the input is actually-- a pair (i.e. _×_ ) but the output type still depends on the input 'point' (x , y).map-Σ′ : {B : A → Set b} {P : Set p} {Q : P → Set q} →(f : (x : A) → B x) → ((x : P) → Q x) → ((x , y) : A × P) → B x × Q ymap-Σ′ f g (x , y) = (f x , g y)-- This is a generic zipWith for Σ where different functions are applied to each-- component pair, and recombined.zipWith : {P : A → Set p} {Q : B → Set q} {R : C → Set r} {S : (x : C) → R x → Set s}(_∙_ : A → B → C) → (_∘_ : ∀ {x y} → P x → Q y → R (x ∙ y)) →(_*_ : (x : C) → (y : R x) → S x y) →((a , p) : Σ A P) → ((b , q) : Σ B Q) → S (a ∙ b) (p ∘ q)zipWith _∙_ _∘_ _*_ (a , p) (b , q) = (a ∙ b) * (p ∘ q)-------------------------------------------------------------------------- Negation of existential quantifier∄ : ∀ {A : Set a} → (A → Set b) → Set (a ⊔ b)∄ P = ¬ ∃ P-- Unique existence (parametrised by an underlying equality).∃! : {A : Set a} → (A → A → Set ℓ) → (A → Set b) → Set (a ⊔ b ⊔ ℓ)∃! _≈_ B = ∃ λ x → B x × (∀ {y} → B y → x ≈ y)-- Syntaxinfix 2 ∄-syntax∄-syntax : ∀ {A : Set a} → (A → Set b) → Set (a ⊔ b)∄-syntax = ∄syntax ∄-syntax (λ x → B) = ∄[ x ] B
-------------------------------------------------------------------------- The Agda standard library---- Lifting of two predicates------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Relation.Unary.All whereopen import Level using (Level; _⊔_)open import Data.Product.Base using (_×_; _,_)privatevariablea b p q : LevelA : Set aB : Set bAll : (A → Set p) → (B → Set q) → (A × B → Set (p ⊔ q))All P Q (a , b) = P a × Q b
-------------------------------------------------------------------------- The Agda standard library---- Pointwise products of binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Relation.Binary.Pointwise.NonDependent whereopen import Data.Product.Base as Productopen import Data.Sum.Base using (inj₁; inj₂)open import Level using (Level; _⊔_; 0ℓ)open import Function.Base using (id)open import Function.Bundles using (Inverse)open import Relation.Nullary.Decidable using (_×-dec_)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Preorder; Poset; StrictPartialOrder)open import Relation.Binary.Definitionsopen import Relation.Binary.Structuresopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b ℓ₁ ℓ₂ ℓ₃ ℓ₄ : LevelA B C D : Set aR S ≈₁ ≈₂ : Rel A ℓ₁-------------------------------------------------------------------------- DefinitionPointwise : REL A B ℓ₁ → REL C D ℓ₂ → REL (A × C) (B × D) (ℓ₁ ⊔ ℓ₂)Pointwise R S (a , c) (b , d) = (R a b) × (S c d)-------------------------------------------------------------------------- Pointwise preserves many relational properties×-reflexive : ≈₁ ⇒ R → ≈₂ ⇒ S → Pointwise ≈₁ ≈₂ ⇒ Pointwise R S×-reflexive refl₁ refl₂ = Product.map refl₁ refl₂×-refl : Reflexive R → Reflexive S → Reflexive (Pointwise R S)×-refl refl₁ refl₂ = refl₁ , refl₂×-irreflexive₁ : Irreflexive ≈₁ R →Irreflexive (Pointwise ≈₁ ≈₂) (Pointwise R S)×-irreflexive₁ ir x≈y x<y = ir (proj₁ x≈y) (proj₁ x<y)×-irreflexive₂ : Irreflexive ≈₂ S →Irreflexive (Pointwise ≈₁ ≈₂) (Pointwise R S)×-irreflexive₂ ir x≈y x<y = ir (proj₂ x≈y) (proj₂ x<y)×-symmetric : Symmetric R → Symmetric S → Symmetric (Pointwise R S)×-symmetric sym₁ sym₂ = Product.map sym₁ sym₂×-transitive : Transitive R → Transitive S → Transitive (Pointwise R S)×-transitive trans₁ trans₂ = Product.zip trans₁ trans₂×-antisymmetric : Antisymmetric ≈₁ R → Antisymmetric ≈₂ S →Antisymmetric (Pointwise ≈₁ ≈₂) (Pointwise R S)×-antisymmetric antisym₁ antisym₂ = Product.zip antisym₁ antisym₂×-asymmetric₁ : Asymmetric R → Asymmetric (Pointwise R S)×-asymmetric₁ asym₁ x<y y<x = asym₁ (proj₁ x<y) (proj₁ y<x)×-asymmetric₂ : Asymmetric S → Asymmetric (Pointwise R S)×-asymmetric₂ asym₂ x<y y<x = asym₂ (proj₂ x<y) (proj₂ y<x)×-respectsʳ : R Respectsʳ ≈₁ → S Respectsʳ ≈₂ →(Pointwise R S) Respectsʳ (Pointwise ≈₁ ≈₂)×-respectsʳ resp₁ resp₂ = Product.zip resp₁ resp₂×-respectsˡ : R Respectsˡ ≈₁ → S Respectsˡ ≈₂ →(Pointwise R S) Respectsˡ (Pointwise ≈₁ ≈₂)×-respectsˡ resp₁ resp₂ = Product.zip resp₁ resp₂×-respects₂ : R Respects₂ ≈₁ → S Respects₂ ≈₂ →(Pointwise R S) Respects₂ (Pointwise ≈₁ ≈₂)×-respects₂ = Product.zip ×-respectsʳ ×-respectsˡ×-total : Symmetric R → Total R → Total S → Total (Pointwise R S)×-total sym₁ total₁ total₂ (x₁ , x₂) (y₁ , y₂)with total₁ x₁ y₁ | total₂ x₂ y₂... | inj₁ x₁∼y₁ | inj₁ x₂∼y₂ = inj₁ ( x₁∼y₁ , x₂∼y₂)... | inj₁ x₁∼y₁ | inj₂ y₂∼x₂ = inj₂ (sym₁ x₁∼y₁ , y₂∼x₂)... | inj₂ y₁∼x₁ | inj₂ y₂∼x₂ = inj₂ ( y₁∼x₁ , y₂∼x₂)... | inj₂ y₁∼x₁ | inj₁ x₂∼y₂ = inj₁ (sym₁ y₁∼x₁ , x₂∼y₂)×-decidable : Decidable R → Decidable S → Decidable (Pointwise R S)×-decidable _≟₁_ _≟₂_ (x₁ , x₂) (y₁ , y₂) = (x₁ ≟₁ y₁) ×-dec (x₂ ≟₂ y₂)-------------------------------------------------------------------------- Structures can also be combined.-- Some collections of properties which are preserved by ×-Rel.×-isEquivalence : IsEquivalence R → IsEquivalence S →IsEquivalence (Pointwise R S)×-isEquivalence {R = R} {S = S} eq₁ eq₂ = record{ refl = ×-refl {R = R} {S = S} (refl eq₁) (refl eq₂); sym = ×-symmetric {R = R} {S = S} (sym eq₁) (sym eq₂); trans = ×-transitive {R = R} {S = S} (trans eq₁) (trans eq₂)} where open IsEquivalence×-isDecEquivalence : IsDecEquivalence R → IsDecEquivalence S →IsDecEquivalence (Pointwise R S)×-isDecEquivalence eq₁ eq₂ = record{ isEquivalence = ×-isEquivalence(isEquivalence eq₁) (isEquivalence eq₂); _≟_ = ×-decidable (_≟_ eq₁) (_≟_ eq₂)} where open IsDecEquivalence×-isPreorder : IsPreorder ≈₁ R → IsPreorder ≈₂ S →IsPreorder (Pointwise ≈₁ ≈₂) (Pointwise R S)×-isPreorder {R = R} {S = S} pre₁ pre₂ = record{ isEquivalence = ×-isEquivalence(isEquivalence pre₁) (isEquivalence pre₂); reflexive = ×-reflexive {R = R} {S = S}(reflexive pre₁) (reflexive pre₂); trans = ×-transitive {R = R} {S = S}(trans pre₁) (trans pre₂)} where open IsPreorder×-isPartialOrder : IsPartialOrder ≈₁ R → IsPartialOrder ≈₂ S →IsPartialOrder (Pointwise ≈₁ ≈₂) (Pointwise R S)×-isPartialOrder {R = R} {S = S} po₁ po₂ = record{ isPreorder = ×-isPreorder (isPreorder po₁) (isPreorder po₂); antisym = ×-antisymmetric {R = R} {S = S}(antisym po₁) (antisym po₂)} where open IsPartialOrder×-isStrictPartialOrder : IsStrictPartialOrder ≈₁ R →IsStrictPartialOrder ≈₂ S →IsStrictPartialOrder (Pointwise ≈₁ ≈₂) (Pointwise R S)×-isStrictPartialOrder {R = R} {≈₂ = ≈₂} {S = S} spo₁ spo₂ = record{ isEquivalence = ×-isEquivalence(isEquivalence spo₁) (isEquivalence spo₂); irrefl = ×-irreflexive₁ {R = R} {≈₂ = ≈₂} {S = S}(irrefl spo₁); trans = ×-transitive {R = R} {S = S}(trans spo₁) (trans spo₂); <-resp-≈ = ×-respects₂ (<-resp-≈ spo₁) (<-resp-≈ spo₂)} where open IsStrictPartialOrder-------------------------------------------------------------------------- Bundles×-setoid : Setoid a ℓ₁ → Setoid b ℓ₂ → Setoid _ _×-setoid s₁ s₂ = record{ isEquivalence =×-isEquivalence (isEquivalence s₁) (isEquivalence s₂)} where open Setoid×-decSetoid : DecSetoid a ℓ₁ → DecSetoid b ℓ₂ → DecSetoid _ _×-decSetoid s₁ s₂ = record{ isDecEquivalence =×-isDecEquivalence (isDecEquivalence s₁) (isDecEquivalence s₂)} where open DecSetoid×-preorder : Preorder a ℓ₁ ℓ₂ → Preorder b ℓ₃ ℓ₄ → Preorder _ _ _×-preorder p₁ p₂ = record{ isPreorder = ×-isPreorder (isPreorder p₁) (isPreorder p₂)} where open Preorder×-poset : Poset a ℓ₁ ℓ₂ → Poset b ℓ₃ ℓ₄ → Poset _ _ _×-poset s₁ s₂ = record{ isPartialOrder = ×-isPartialOrder (isPartialOrder s₁)(isPartialOrder s₂)} where open Poset×-strictPartialOrder : StrictPartialOrder a ℓ₁ ℓ₂ →StrictPartialOrder b ℓ₃ ℓ₄ →StrictPartialOrder _ _ _×-strictPartialOrder s₁ s₂ = record{ isStrictPartialOrder = ×-isStrictPartialOrder(isStrictPartialOrder s₁)(isStrictPartialOrder s₂)} where open StrictPartialOrder-------------------------------------------------------------------------- Additional notation-- Infix combining setoidsinfix 4 _×ₛ__×ₛ_ : Setoid a ℓ₁ → Setoid b ℓ₂ → Setoid _ __×ₛ_ = ×-setoid-------------------------------------------------------------------------- The propositional equality setoid over products can be-- decomposed using ×-Rel≡×≡⇒≡ : Pointwise _≡_ _≡_ ⇒ _≡_ {A = A × B}≡×≡⇒≡ (≡.refl , ≡.refl) = ≡.refl≡⇒≡×≡ : _≡_ {A = A × B} ⇒ Pointwise _≡_ _≡_≡⇒≡×≡ ≡.refl = (≡.refl , ≡.refl)Pointwise-≡↔≡ : Inverse (≡.setoid A ×ₛ ≡.setoid B) (≡.setoid (A × B))Pointwise-≡↔≡ = record{ to = id; from = id; to-cong = ≡×≡⇒≡; from-cong = ≡⇒≡×≡; inverse = ≡×≡⇒≡ , ≡⇒≡×≡}
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of binary relations to sigma types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Relation.Binary.Pointwise.Dependent whereopen import Data.Product.Base as Productopen import Levelopen import Function.Baseopen import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions as Bopen import Relation.Binary.Indexed.Heterogeneous as Iusing (IREL; IRel; IndexedSetoid; IsIndexedEquivalence)open import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Pointwise liftinginfixr 4 _,_record POINTWISE {a₁ a₂ b₁ b₂ ℓ₁ ℓ₂}{A₁ : Set a₁} (B₁ : A₁ → Set b₁){A₂ : Set a₂} (B₂ : A₂ → Set b₂)(_R₁_ : REL A₁ A₂ ℓ₁) (_R₂_ : IREL B₁ B₂ ℓ₂)(xy₁ : Σ A₁ B₁) (xy₂ : Σ A₂ B₂): Set (a₁ ⊔ a₂ ⊔ b₁ ⊔ b₂ ⊔ ℓ₁ ⊔ ℓ₂) whereconstructor _,_fieldproj₁ : (proj₁ xy₁) R₁ (proj₁ xy₂)proj₂ : (proj₂ xy₁) R₂ (proj₂ xy₂)open POINTWISE publicPointwise : ∀ {a b ℓ₁ ℓ₂} {A : Set a} (B : A → Set b)(_R₁_ : Rel A ℓ₁) (_R₂_ : IRel B ℓ₂) → Rel (Σ A B) _Pointwise B = POINTWISE B B-------------------------------------------------------------------------- Pointwise preserves many relational propertiesmodule _ {a b ℓ₁ ℓ₂} {A : Set a} {B : A → Set b}{R : Rel A ℓ₁} {S : IRel B ℓ₂} whereprivateR×S = Pointwise B R Srefl : B.Reflexive R → I.Reflexive B S → B.Reflexive R×Srefl refl₁ refl₂ = (refl₁ , refl₂)symmetric : B.Symmetric R → I.Symmetric B S → B.Symmetric R×Ssymmetric sym₁ sym₂ (x₁Rx₂ , y₁Ry₂) = (sym₁ x₁Rx₂ , sym₂ y₁Ry₂)transitive : B.Transitive R → I.Transitive B S → B.Transitive R×Stransitive trans₁ trans₂ (x₁Rx₂ , y₁Ry₂) (x₂Rx₃ , y₂Ry₃) =(trans₁ x₁Rx₂ x₂Rx₃ , trans₂ y₁Ry₂ y₂Ry₃)isEquivalence : IsEquivalence R → IsIndexedEquivalence B S →IsEquivalence R×SisEquivalence eq₁ eq₂ = record{ refl = refl Eq.refl IEq.refl; sym = symmetric Eq.sym IEq.sym; trans = transitive Eq.trans IEq.trans} wheremodule Eq = IsEquivalence eq₁module IEq = IsIndexedEquivalence eq₂module _ {a b ℓ₁ ℓ₂} wheresetoid : (A : Setoid a ℓ₁) →IndexedSetoid (Setoid.Carrier A) b ℓ₂ →Setoid _ _setoid s₁ s₂ = record{ isEquivalence = isEquivalence Eq.isEquivalence IEq.isEquivalence} wheremodule Eq = Setoid s₁module IEq = IndexedSetoid s₂
-------------------------------------------------------------------------- The Agda standard library---- Properties that are related to pointwise lifting of binary-- relations to sigma types and make use of heterogeneous equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Product.Relation.Binary.Pointwise.Dependent.WithK whereopen import Data.Product.Base using (Σ; uncurry; _,_)open import Data.Product.Relation.Binary.Pointwise.Dependentopen import Function.Baseopen import Function.Bundles using (Inverse)open import Level using (Level)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.HeterogeneousEquality as ≅ using (_≅_)open import Relation.Binary.Indexed.Heterogeneous using (IndexedSetoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b : LevelI : Set aA : I → Set a-------------------------------------------------------------------------- The propositional equality setoid over sigma types can be-- decomposed using PointwisePointwise-≡⇒≡ : Pointwise A _≡_ (λ x y → x ≅ y) ⇒ _≡_Pointwise-≡⇒≡ (≡.refl , ≅.refl) = ≡.refl≡⇒Pointwise-≡ : _≡_ ⇒ Pointwise A _≡_ (λ x y → x ≅ y)≡⇒Pointwise-≡ ≡.refl = (≡.refl , ≅.refl)Pointwise-≡↔≡ : Inverse (setoid (≡.setoid I) (≅.indexedSetoid A)) (≡.setoid (Σ I A))Pointwise-≡↔≡ = record{ to = id; to-cong = Pointwise-≡⇒≡; from = id; from-cong = ≡⇒Pointwise-≡; inverse = (λ {(≡.refl , ≅.refl) → ≡.refl}) , λ {≡.refl → (≡.refl , ≅.refl)}}
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic products of binary relations-------------------------------------------------------------------------- The definition of lexicographic product used here is suitable if-- the left-hand relation is a strict partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Relation.Binary.Lex.Strict whereopen import Data.Product.Baseopen import Data.Product.Relation.Binary.Pointwise.NonDependent as Pointwiseusing (Pointwise)open import Data.Sum.Base using (inj₁; inj₂; _-⊎-_; [_,_])open import Data.Emptyopen import Function.Baseopen import Induction.WellFoundedopen import Levelopen import Relation.Nullary.Decidableopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Preorder; StrictPartialOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPreorder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (Transitive; Symmetric; Irreflexive; Asymmetric; Total; Decidable; Antisymmetric; Trichotomous; _Respects₂_; _Respectsʳ_; _Respectsˡ_; tri<; tri>; tri≈)open import Relation.Binary.Consequencesopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea b ℓ₁ ℓ₂ ℓ₃ ℓ₄ : LevelA : Set aB : Set b-------------------------------------------------------------------------- A lexicographic ordering over products×-Lex : (_≈₁_ : Rel A ℓ₁) (_<₁_ : Rel A ℓ₂) (_≤₂_ : Rel B ℓ₃) →Rel (A × B) _×-Lex _≈₁_ _<₁_ _≤₂_ =(_<₁_ on proj₁) -⊎- (_≈₁_ on proj₁) -×- (_≤₂_ on proj₂)-------------------------------------------------------------------------- Some properties which are preserved by ×-Lex (under certain-- assumptions).×-reflexive : (_≈₁_ : Rel A ℓ₁) (_∼₁_ : Rel A ℓ₂){_≈₂_ : Rel B ℓ₃} (_≤₂_ : Rel B ℓ₄) →_≈₂_ ⇒ _≤₂_ → (Pointwise _≈₁_ _≈₂_) ⇒ (×-Lex _≈₁_ _∼₁_ _≤₂_)×-reflexive _ _ _ refl₂ = λ x≈y →inj₂ (proj₁ x≈y , refl₂ (proj₂ x≈y))module _ {_≈₁_ : Rel A ℓ₁} {_<₁_ : Rel A ℓ₂} {_<₂_ : Rel B ℓ₃} whereprivate_<ₗₑₓ_ = ×-Lex _≈₁_ _<₁_ _<₂_×-transitive : IsEquivalence _≈₁_ → _<₁_ Respects₂ _≈₁_ → Transitive _<₁_ →Transitive _<₂_ → Transitive _<ₗₑₓ_×-transitive eq₁ resp₁ trans₁ trans₂ = transwheremodule Eq₁ = IsEquivalence eq₁trans : Transitive _<ₗₑₓ_trans (inj₁ x₁<y₁) (inj₁ y₁<z₁) = inj₁ (trans₁ x₁<y₁ y₁<z₁)trans (inj₁ x₁<y₁) (inj₂ y≈≤z) =inj₁ (proj₁ resp₁ (proj₁ y≈≤z) x₁<y₁)trans (inj₂ x≈≤y) (inj₁ y₁<z₁) =inj₁ (proj₂ resp₁ (Eq₁.sym $ proj₁ x≈≤y) y₁<z₁)trans (inj₂ x≈≤y) (inj₂ y≈≤z) =inj₂ ( Eq₁.trans (proj₁ x≈≤y) (proj₁ y≈≤z), trans₂ (proj₂ x≈≤y) (proj₂ y≈≤z))×-asymmetric : Symmetric _≈₁_ → _<₁_ Respects₂ _≈₁_ →Asymmetric _<₁_ → Asymmetric _<₂_ →Asymmetric _<ₗₑₓ_×-asymmetric sym₁ resp₁ asym₁ asym₂ = asymwhereirrefl₁ : Irreflexive _≈₁_ _<₁_irrefl₁ = asym⇒irr resp₁ sym₁ asym₁asym : Asymmetric _<ₗₑₓ_asym (inj₁ x₁<y₁) (inj₁ y₁<x₁) = asym₁ x₁<y₁ y₁<x₁asym (inj₁ x₁<y₁) (inj₂ y≈<x) = irrefl₁ (sym₁ $ proj₁ y≈<x) x₁<y₁asym (inj₂ x≈<y) (inj₁ y₁<x₁) = irrefl₁ (sym₁ $ proj₁ x≈<y) y₁<x₁asym (inj₂ x≈<y) (inj₂ y≈<x) = asym₂ (proj₂ x≈<y) (proj₂ y≈<x)×-total₁ : Total _<₁_ → Total _<ₗₑₓ_×-total₁ total₁ x y with total₁ (proj₁ x) (proj₁ y)... | inj₁ x₁<y₁ = inj₁ (inj₁ x₁<y₁)... | inj₂ x₁>y₁ = inj₂ (inj₁ x₁>y₁)×-total₂ : Symmetric _≈₁_ →Trichotomous _≈₁_ _<₁_ → Total _<₂_ →Total _<ₗₑₓ_×-total₂ sym tri₁ total₂ x y with tri₁ (proj₁ x) (proj₁ y)... | tri< x₁<y₁ _ _ = inj₁ (inj₁ x₁<y₁)... | tri> _ _ y₁<x₁ = inj₂ (inj₁ y₁<x₁)... | tri≈ _ x₁≈y₁ _ with total₂ (proj₂ x) (proj₂ y)... | inj₁ x₂≤y₂ = inj₁ (inj₂ (x₁≈y₁ , x₂≤y₂))... | inj₂ y₂≤x₂ = inj₂ (inj₂ (sym x₁≈y₁ , y₂≤x₂))×-decidable : Decidable _≈₁_ → Decidable _<₁_ → Decidable _<₂_ →Decidable _<ₗₑₓ_×-decidable dec-≈₁ dec-<₁ dec-≤₂ x y =dec-<₁ (proj₁ x) (proj₁ y)⊎-dec(dec-≈₁ (proj₁ x) (proj₁ y)×-decdec-≤₂ (proj₂ x) (proj₂ y))module _ {_≈₁_ : Rel A ℓ₁} {_<₁_ : Rel A ℓ₂}{_≈₂_ : Rel B ℓ₃} {_<₂_ : Rel B ℓ₄} whereprivate_≋_ = Pointwise _≈₁_ _≈₂__<ₗₑₓ_ = ×-Lex _≈₁_ _<₁_ _<₂_×-irreflexive : Irreflexive _≈₁_ _<₁_ → Irreflexive _≈₂_ _<₂_ →Irreflexive (Pointwise _≈₁_ _≈₂_) _<ₗₑₓ_×-irreflexive ir₁ ir₂ x≈y (inj₁ x₁<y₁) = ir₁ (proj₁ x≈y) x₁<y₁×-irreflexive ir₁ ir₂ x≈y (inj₂ x≈<y) = ir₂ (proj₂ x≈y) (proj₂ x≈<y)×-antisymmetric : Symmetric _≈₁_ → Irreflexive _≈₁_ _<₁_ → Asymmetric _<₁_ →Antisymmetric _≈₂_ _<₂_ → Antisymmetric _≋_ _<ₗₑₓ_×-antisymmetric sym₁ irrefl₁ asym₁ antisym₂ = antisymwhereantisym : Antisymmetric _≋_ _<ₗₑₓ_antisym (inj₁ x₁<y₁) (inj₁ y₁<x₁) =⊥-elim $ asym₁ x₁<y₁ y₁<x₁antisym (inj₁ x₁<y₁) (inj₂ y≈≤x) =⊥-elim $ irrefl₁ (sym₁ $ proj₁ y≈≤x) x₁<y₁antisym (inj₂ x≈≤y) (inj₁ y₁<x₁) =⊥-elim $ irrefl₁ (sym₁ $ proj₁ x≈≤y) y₁<x₁antisym (inj₂ x≈≤y) (inj₂ y≈≤x) =proj₁ x≈≤y , antisym₂ (proj₂ x≈≤y) (proj₂ y≈≤x)×-respectsʳ : Transitive _≈₁_ →_<₁_ Respectsʳ _≈₁_ → _<₂_ Respectsʳ _≈₂_ →_<ₗₑₓ_ Respectsʳ _≋_×-respectsʳ trans resp₁ resp₂ y≈y' (inj₁ x₁<y₁) = inj₁ (resp₁ (proj₁ y≈y') x₁<y₁)×-respectsʳ trans resp₁ resp₂ y≈y' (inj₂ x≈<y) = inj₂ (trans (proj₁ x≈<y) (proj₁ y≈y'), (resp₂ (proj₂ y≈y') (proj₂ x≈<y)))×-respectsˡ : Symmetric _≈₁_ → Transitive _≈₁_ →_<₁_ Respectsˡ _≈₁_ → _<₂_ Respectsˡ _≈₂_ →_<ₗₑₓ_ Respectsˡ _≋_×-respectsˡ sym trans resp₁ resp₂ x≈x' (inj₁ x₁<y₁) = inj₁ (resp₁ (proj₁ x≈x') x₁<y₁)×-respectsˡ sym trans resp₁ resp₂ x≈x' (inj₂ x≈<y) = inj₂ (trans (sym $ proj₁ x≈x') (proj₁ x≈<y), (resp₂ (proj₂ x≈x') (proj₂ x≈<y)))×-respects₂ : IsEquivalence _≈₁_ →_<₁_ Respects₂ _≈₁_ → _<₂_ Respects₂ _≈₂_ →_<ₗₑₓ_ Respects₂ _≋_×-respects₂ eq₁ resp₁ resp₂ = ×-respectsʳ trans (proj₁ resp₁) (proj₁ resp₂), ×-respectsˡ sym trans (proj₂ resp₁) (proj₂ resp₂)where open IsEquivalence eq₁×-compare : Symmetric _≈₁_ →Trichotomous _≈₁_ _<₁_ → Trichotomous _≈₂_ _<₂_ →Trichotomous _≋_ _<ₗₑₓ_×-compare sym₁ cmp₁ cmp₂ (x₁ , x₂) (y₁ , y₂) with cmp₁ x₁ y₁... | (tri< x₁<y₁ x₁≉y₁ x₁≯y₁) =tri< (inj₁ x₁<y₁)(x₁≉y₁ ∘ proj₁)[ x₁≯y₁ , x₁≉y₁ ∘ sym₁ ∘ proj₁ ]... | (tri> x₁≮y₁ x₁≉y₁ x₁>y₁) =tri> [ x₁≮y₁ , x₁≉y₁ ∘ proj₁ ](x₁≉y₁ ∘ proj₁)(inj₁ x₁>y₁)... | (tri≈ x₁≮y₁ x₁≈y₁ x₁≯y₁) with cmp₂ x₂ y₂... | (tri< x₂<y₂ x₂≉y₂ x₂≯y₂) =tri< (inj₂ (x₁≈y₁ , x₂<y₂))(x₂≉y₂ ∘ proj₂)[ x₁≯y₁ , x₂≯y₂ ∘ proj₂ ]... | (tri> x₂≮y₂ x₂≉y₂ x₂>y₂) =tri> [ x₁≮y₁ , x₂≮y₂ ∘ proj₂ ](x₂≉y₂ ∘ proj₂)(inj₂ (sym₁ x₁≈y₁ , x₂>y₂))... | (tri≈ x₂≮y₂ x₂≈y₂ x₂≯y₂) =tri≈ [ x₁≮y₁ , x₂≮y₂ ∘ proj₂ ](x₁≈y₁ , x₂≈y₂)[ x₁≯y₁ , x₂≯y₂ ∘ proj₂ ]module _ {_≈₁_ : Rel A ℓ₁} {_<₁_ : Rel A ℓ₂} {_<₂_ : Rel B ℓ₃} whereprivate_<ₗₑₓ_ = ×-Lex _≈₁_ _<₁_ _<₂_×-wellFounded' : Transitive _≈₁_ →_<₁_ Respectsʳ _≈₁_ →WellFounded _<₁_ →WellFounded _<₂_ →WellFounded _<ₗₑₓ_×-wellFounded' trans resp wf₁ wf₂ (x , y) = acc (×-acc (wf₁ x) (wf₂ y))where×-acc : ∀ {x y} →Acc _<₁_ x → Acc _<₂_ y →WfRec _<ₗₑₓ_ (Acc _<ₗₑₓ_) (x , y)×-acc (acc rec₁) acc₂ (inj₁ u<x)= acc (×-acc (rec₁ u<x) (wf₂ _))×-acc acc₁ (acc rec₂) (inj₂ (u≈x , v<y))= Acc-resp-flip-≈(×-respectsʳ {_<₁_ = _<₁_} {_<₂_ = _<₂_} trans resp (≡.respʳ _<₂_))(u≈x , ≡.refl)(acc (×-acc acc₁ (rec₂ v<y)))module _ {_<₁_ : Rel A ℓ₁} {_<₂_ : Rel B ℓ₂} whereprivate_<ₗₑₓ_ = ×-Lex _≡_ _<₁_ _<₂_×-wellFounded : WellFounded _<₁_ →WellFounded _<₂_ →WellFounded _<ₗₑₓ_×-wellFounded = ×-wellFounded' ≡.trans (≡.respʳ _<₁_)-------------------------------------------------------------------------- Collections of properties which are preserved by ×-Lex.module _ {_≈₁_ : Rel A ℓ₁} {_<₁_ : Rel A ℓ₂}{_≈₂_ : Rel B ℓ₃} {_<₂_ : Rel B ℓ₄} whereprivate_≋_ = Pointwise _≈₁_ _≈₂__<ₗₑₓ_ = ×-Lex _≈₁_ _<₁_ _<₂_×-isPreorder : IsPreorder _≈₁_ _<₁_ →IsPreorder _≈₂_ _<₂_ →IsPreorder _≋_ _<ₗₑₓ_×-isPreorder pre₁ pre₂ =record{ isEquivalence = Pointwise.×-isEquivalence(isEquivalence pre₁) (isEquivalence pre₂); reflexive = ×-reflexive _≈₁_ _<₁_ _<₂_ (reflexive pre₂); trans = ×-transitive {_<₂_ = _<₂_}(isEquivalence pre₁) (≲-resp-≈ pre₁)(trans pre₁) (trans pre₂)}where open IsPreorder×-isStrictPartialOrder : IsStrictPartialOrder _≈₁_ _<₁_ →IsStrictPartialOrder _≈₂_ _<₂_ →IsStrictPartialOrder _≋_ _<ₗₑₓ_×-isStrictPartialOrder spo₁ spo₂ =record{ isEquivalence = Pointwise.×-isEquivalence(isEquivalence spo₁) (isEquivalence spo₂); irrefl = ×-irreflexive {_<₁_ = _<₁_} {_<₂_ = _<₂_}(irrefl spo₁) (irrefl spo₂); trans = ×-transitive {_<₁_ = _<₁_} {_<₂_ = _<₂_}(isEquivalence spo₁)(<-resp-≈ spo₁) (trans spo₁)(trans spo₂); <-resp-≈ = ×-respects₂ (isEquivalence spo₁)(<-resp-≈ spo₁)(<-resp-≈ spo₂)}where open IsStrictPartialOrder×-isStrictTotalOrder : IsStrictTotalOrder _≈₁_ _<₁_ →IsStrictTotalOrder _≈₂_ _<₂_ →IsStrictTotalOrder _≋_ _<ₗₑₓ_×-isStrictTotalOrder spo₁ spo₂ =record{ isStrictPartialOrder = ×-isStrictPartialOrder(isStrictPartialOrder spo₁)(isStrictPartialOrder spo₂); compare = ×-compare (Eq.sym spo₁) (compare spo₁)(compare spo₂)}where open IsStrictTotalOrder-------------------------------------------------------------------------- "Bundles" can also be combined.×-preorder : Preorder a ℓ₁ ℓ₂ →Preorder b ℓ₃ ℓ₄ →Preorder _ _ _×-preorder p₁ p₂ = record{ isPreorder = ×-isPreorder (isPreorder p₁) (isPreorder p₂)} where open Preorder×-strictPartialOrder : StrictPartialOrder a ℓ₁ ℓ₂ →StrictPartialOrder b ℓ₃ ℓ₄ →StrictPartialOrder _ _ _×-strictPartialOrder s₁ s₂ = record{ isStrictPartialOrder = ×-isStrictPartialOrder(isStrictPartialOrder s₁) (isStrictPartialOrder s₂)} where open StrictPartialOrder×-strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂ →StrictTotalOrder b ℓ₃ ℓ₄ →StrictTotalOrder _ _ _×-strictTotalOrder s₁ s₂ = record{ isStrictTotalOrder = ×-isStrictTotalOrder(isStrictTotalOrder s₁) (isStrictTotalOrder s₂)} where open StrictTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic products of binary relations-------------------------------------------------------------------------- The definition of lexicographic product used here is suitable if-- the left-hand relation is a (non-strict) partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Relation.Binary.Lex.NonStrict whereopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Sum.Base using (inj₁; inj₂)open import Level using (Level)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Poset; DecTotalOrder; TotalOrder)open import Relation.Binary.Structuresusing (IsPartialOrder; IsEquivalence; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Transitive; Symmetric; Decidable; Antisymmetric; Total; Trichotomous; Irreflexive; Asymmetric; _Respects₂_; tri<; tri>; tri≈)open import Relation.Binary.Consequencesimport Relation.Binary.Construct.NonStrictToStrict as Convopen import Data.Product.Relation.Binary.Pointwise.NonDependent as Pointwiseusing (Pointwise)import Data.Product.Relation.Binary.Lex.Strict as Strictprivatevariablea b ℓ₁ ℓ₂ ℓ₃ ℓ₄ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definition×-Lex : (_≈₁_ : Rel A ℓ₁) (_≤₁_ : Rel A ℓ₂) (_≤₂_ : Rel B ℓ₃) →Rel (A × B) _×-Lex _≈₁_ _≤₁_ _≤₂_ = Strict.×-Lex _≈₁_ (Conv._<_ _≈₁_ _≤₁_) _≤₂_-------------------------------------------------------------------------- Properties×-reflexive : (_≈₁_ : Rel A ℓ₁) (_≤₁_ : Rel A ℓ₂){_≈₂_ : Rel B ℓ₃} (_≤₂_ : Rel B ℓ₄) →_≈₂_ ⇒ _≤₂_ →(Pointwise _≈₁_ _≈₂_) ⇒ (×-Lex _≈₁_ _≤₁_ _≤₂_)×-reflexive _≈₁_ _≤₁_ _≤₂_ refl₂ =Strict.×-reflexive _≈₁_ (Conv._<_ _≈₁_ _≤₁_) _≤₂_ refl₂module _ {_≈₁_ : Rel A ℓ₁} {_≤₁_ : Rel A ℓ₂} {_≤₂_ : Rel B ℓ₃} whereprivate_≤ₗₑₓ_ = ×-Lex _≈₁_ _≤₁_ _≤₂_×-transitive : IsPartialOrder _≈₁_ _≤₁_ → Transitive _≤₂_ →Transitive _≤ₗₑₓ_×-transitive po₁ trans₂ =Strict.×-transitive {_≈₁_ = _≈₁_} {_<₂_ = _≤₂_}isEquivalence (Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)(Conv.<-trans _ _ po₁)trans₂where open IsPartialOrder po₁×-total : Symmetric _≈₁_ → Decidable _≈₁_ → Antisymmetric _≈₁_ _≤₁_ →Total _≤₁_ → Total _≤₂_ → Total _≤ₗₑₓ_×-total sym₁ dec₁ antisym₁ total₁ total₂ =totalwheretri₁ : Trichotomous _≈₁_ (Conv._<_ _≈₁_ _≤₁_)tri₁ = Conv.<-trichotomous _ _ sym₁ dec₁ antisym₁ total₁total : Total _≤ₗₑₓ_total x y with tri₁ (proj₁ x) (proj₁ y)... | tri< x₁<y₁ x₁≉y₁ x₁≯y₁ = inj₁ (inj₁ x₁<y₁)... | tri> x₁≮y₁ x₁≉y₁ x₁>y₁ = inj₂ (inj₁ x₁>y₁)... | tri≈ x₁≮y₁ x₁≈y₁ x₁≯y₁ with total₂ (proj₂ x) (proj₂ y)... | inj₁ x₂≤y₂ = inj₁ (inj₂ (x₁≈y₁ , x₂≤y₂))... | inj₂ x₂≥y₂ = inj₂ (inj₂ (sym₁ x₁≈y₁ , x₂≥y₂))×-decidable : Decidable _≈₁_ → Decidable _≤₁_ → Decidable _≤₂_ →Decidable _≤ₗₑₓ_×-decidable dec-≈₁ dec-≤₁ dec-≤₂ =Strict.×-decidable dec-≈₁ (Conv.<-decidable _ _ dec-≈₁ dec-≤₁)dec-≤₂module _ {_≈₁_ : Rel A ℓ₁} {_≤₁_ : Rel A ℓ₂}{_≈₂_ : Rel B ℓ₃} {_≤₂_ : Rel B ℓ₄}whereprivate_≤ₗₑₓ_ = ×-Lex _≈₁_ _≤₁_ _≤₂__≋_ = Pointwise _≈₁_ _≈₂_×-antisymmetric : IsPartialOrder _≈₁_ _≤₁_ → Antisymmetric _≈₂_ _≤₂_ →Antisymmetric _≋_ _≤ₗₑₓ_×-antisymmetric po₁ antisym₂ =Strict.×-antisymmetric {_≈₁_ = _≈₁_} {_<₂_ = _≤₂_}≈-sym₁ irrefl₁ asym₁ antisym₂whereopen IsPartialOrder po₁open Eq renaming (refl to ≈-refl₁; sym to ≈-sym₁)irrefl₁ : Irreflexive _≈₁_ (Conv._<_ _≈₁_ _≤₁_)irrefl₁ = Conv.<-irrefl _≈₁_ _≤₁_asym₁ : Asymmetric (Conv._<_ _≈₁_ _≤₁_)asym₁ = trans∧irr⇒asym {_≈_ = _≈₁_}≈-refl₁ (Conv.<-trans _ _ po₁) irrefl₁×-respects₂ : IsEquivalence _≈₁_ →_≤₁_ Respects₂ _≈₁_ → _≤₂_ Respects₂ _≈₂_ →_≤ₗₑₓ_ Respects₂ _≋_×-respects₂ eq₁ resp₁ resp₂ =Strict.×-respects₂ eq₁ (Conv.<-resp-≈ _ _ eq₁ resp₁) resp₂-------------------------------------------------------------------------- Structures×-isPartialOrder : IsPartialOrder _≈₁_ _≤₁_ →IsPartialOrder _≈₂_ _≤₂_ →IsPartialOrder _≋_ _≤ₗₑₓ_×-isPartialOrder po₁ po₂ = record{ isPreorder = record{ isEquivalence = Pointwise.×-isEquivalence(isEquivalence po₁)(isEquivalence po₂); reflexive = ×-reflexive _≈₁_ _≤₁_ _≤₂_ (reflexive po₂); trans = ×-transitive {_≤₂_ = _≤₂_} po₁ (trans po₂)}; antisym = ×-antisymmetric po₁ (antisym po₂)}where open IsPartialOrder×-isTotalOrder : Decidable _≈₁_ →IsTotalOrder _≈₁_ _≤₁_ →IsTotalOrder _≈₂_ _≤₂_ →IsTotalOrder _≋_ _≤ₗₑₓ_×-isTotalOrder ≈₁-dec to₁ to₂ = record{ isPartialOrder = ×-isPartialOrder(isPartialOrder to₁) (isPartialOrder to₂); total = ×-total (Eq.sym to₁) ≈₁-dec(antisym to₁) (total to₁)(total to₂)}where open IsTotalOrder×-isDecTotalOrder : IsDecTotalOrder _≈₁_ _≤₁_ →IsDecTotalOrder _≈₂_ _≤₂_ →IsDecTotalOrder _≋_ _≤ₗₑₓ_×-isDecTotalOrder to₁ to₂ = record{ isTotalOrder = ×-isTotalOrder (_≟_ to₁)(isTotalOrder to₁)(isTotalOrder to₂); _≟_ = Pointwise.×-decidable (_≟_ to₁) (_≟_ to₂); _≤?_ = ×-decidable (_≟_ to₁) (_≤?_ to₁) (_≤?_ to₂)}where open IsDecTotalOrder-------------------------------------------------------------------------- Bundles×-poset : Poset a ℓ₁ ℓ₂ → Poset b ℓ₃ ℓ₄ → Poset _ _ _×-poset p₁ p₂ = record{ isPartialOrder = ×-isPartialOrder O₁.isPartialOrder O₂.isPartialOrder} where module O₁ = Poset p₁; module O₂ = Poset p₂×-totalOrder : DecTotalOrder a ℓ₁ ℓ₂ →TotalOrder b ℓ₃ ℓ₄ →TotalOrder _ _ _×-totalOrder t₁ t₂ = record{ isTotalOrder = ×-isTotalOrder T₁._≟_ T₁.isTotalOrder T₂.isTotalOrder} where module T₁ = DecTotalOrder t₁; module T₂ = TotalOrder t₂×-decTotalOrder : DecTotalOrder a ℓ₁ ℓ₂ →DecTotalOrder b ℓ₃ ℓ₄ →DecTotalOrder _ _ _×-decTotalOrder t₁ t₂ = record{ isDecTotalOrder = ×-isDecTotalOrder O₁.isDecTotalOrder O₂.isDecTotalOrder} where module O₁ = DecTotalOrder t₁; module O₂ = DecTotalOrder t₂
-------------------------------------------------------------------------- The Agda standard library---- Properties of products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Properties whereopen import Axiom.UniquenessOfIdentityProofs using (UIP; module Decidable⇒UIP)open import Data.Product.Base using (_,_; Σ; _×_; map; swap; ∃; ∃₂)open import Function.Base using (_∋_; _∘_; id)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Level using (Level)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; _≗_; subst; cong; cong₂; cong′)open import Relation.Nullary.Decidable as Dec using (Dec; yes; no)privatevariablea b c d ℓ : LevelA : Set aB : Set bC : Set cD : Set d-------------------------------------------------------------------------- Equality (dependent)module _ {B : A → Set b} where,-injectiveˡ : ∀ {a c} {b : B a} {d : B c} → (a , b) ≡ (c , d) → a ≡ c,-injectiveˡ refl = refl,-injectiveʳ-≡ : ∀ {a b} {c : B a} {d : B b} → UIP A → (a , c) ≡ (b , d) → (q : a ≡ b) → subst B q c ≡ d,-injectiveʳ-≡ {c = c} u refl q = cong (λ x → subst B x c) (u q refl),-injectiveʳ-UIP : ∀ {a} {b c : B a} → UIP A → (Σ A B ∋ (a , b)) ≡ (a , c) → b ≡ c,-injectiveʳ-UIP u p = ,-injectiveʳ-≡ u p refl≡-dec : DecidableEquality A → (∀ {a} → DecidableEquality (B a)) →DecidableEquality (Σ A B)≡-dec dec₁ dec₂ (a , x) (b , y) with dec₁ a b... | no [a≢b] = no ([a≢b] ∘ ,-injectiveˡ)... | yes refl = Dec.map′ (cong (a ,_)) (,-injectiveʳ-UIP (Decidable⇒UIP.≡-irrelevant dec₁)) (dec₂ x y)-------------------------------------------------------------------------- Equality (non-dependent),-injectiveʳ : ∀ {a c : A} {b d : B} → (a , b) ≡ (c , d) → b ≡ d,-injectiveʳ refl = refl,-injective : ∀ {a c : A} {b d : B} → (a , b) ≡ (c , d) → a ≡ c × b ≡ d,-injective refl = refl , reflmap-cong : ∀ {f g : A → C} {h i : B → D} → f ≗ g → h ≗ i → map f h ≗ map g imap-cong f≗g h≗i (x , y) = cong₂ _,_ (f≗g x) (h≗i y)-- The following properties are definitionally true (because of η)-- but for symmetry with ⊎ it is convenient to define and name them.swap-involutive : swap {A = A} {B = B} ∘ swap ≗ idswap-involutive _ = refl-------------------------------------------------------------------------- Equality between pairs can be expressed as a pair of equalitiesmodule _ {A : Set a} {B : A → Set b} {p₁@(a₁ , b₁) p₂@(a₂ , b₂) : Σ A B} whereΣ-≡,≡→≡ : Σ (a₁ ≡ a₂) (λ p → subst B p b₁ ≡ b₂) → p₁ ≡ p₂Σ-≡,≡→≡ (refl , refl) = reflΣ-≡,≡←≡ : p₁ ≡ p₂ → Σ (a₁ ≡ a₂) (λ p → subst B p b₁ ≡ b₂)Σ-≡,≡←≡ refl = refl , reflprivateleft-inverse-of : (p : Σ (a₁ ≡ a₂) (λ x → subst B x b₁ ≡ b₂)) →Σ-≡,≡←≡ (Σ-≡,≡→≡ p) ≡ pleft-inverse-of (refl , refl) = reflright-inverse-of : (p : p₁ ≡ p₂) → Σ-≡,≡→≡ (Σ-≡,≡←≡ p) ≡ pright-inverse-of refl = reflΣ-≡,≡↔≡ : (∃ λ (p : a₁ ≡ a₂) → subst B p b₁ ≡ b₂) ↔ p₁ ≡ p₂Σ-≡,≡↔≡ = mk↔ₛ′ Σ-≡,≡→≡ Σ-≡,≡←≡ right-inverse-of left-inverse-of-- the non-dependent case. Proofs are exactly as above, and straightforward.module _ {p₁@(a₁ , b₁) p₂@(a₂ , b₂) : A × B} where×-≡,≡→≡ : (a₁ ≡ a₂ × b₁ ≡ b₂) → p₁ ≡ p₂×-≡,≡→≡ (refl , refl) = refl×-≡,≡←≡ : p₁ ≡ p₂ → (a₁ ≡ a₂ × b₁ ≡ b₂)×-≡,≡←≡ refl = refl , refl×-≡,≡↔≡ : (a₁ ≡ a₂ × b₁ ≡ b₂) ↔ p₁ ≡ p₂×-≡,≡↔≡ = mk↔ₛ′×-≡,≡→≡×-≡,≡←≡(λ { refl → refl })(λ { (refl , refl) → refl })-------------------------------------------------------------------------- The order of ∃₂ can be swapped∃∃↔∃∃ : (R : A → B → Set ℓ) → (∃₂ λ x y → R x y) ↔ (∃₂ λ y x → R x y)∃∃↔∃∃ R = mk↔ₛ′ to from cong′ cong′whereto : (∃₂ λ x y → R x y) → (∃₂ λ y x → R x y)to (x , y , Rxy) = (y , x , Rxy)from : (∃₂ λ y x → R x y) → (∃₂ λ x y → R x y)from (y , x , Rxy) = (x , y , Rxy)
-------------------------------------------------------------------------- The Agda standard library---- Properties, related to products, that rely on the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Product.Properties.WithK whereopen import Data.Product.Base using (Σ; _,_)open import Function.Base using (_∋_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl)-------------------------------------------------------------------------- Equality-- These exports are deprecated from v1.4open import Data.Product.Properties using (,-injective; ≡-dec) publicmodule _ {a b} {A : Set a} {B : A → Set b} where,-injectiveʳ : ∀ {a} {b c : B a} → (Σ A B ∋ (a , b)) ≡ (a , c) → b ≡ c,-injectiveʳ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Properties of 'very dependent' map / zipWith over products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Properties.Dependent whereopen import Data.Product using (Σ; _×_; _,_; map-Σ; map-Σ′; zipWith)open import Function.Base using (id; flip)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; cong₂; refl)privatevariablea b p q r s : LevelA B C : Set a-------------------------------------------------------------------------- map-Σmodule _ {B : A → Set b} {P : A → Set p} {Q : {x : A} → P x → B x → Set q} wheremap-Σ-cong : {f g : (x : A) → B x} → {h k : ∀ {x} → (y : P x) → Q y (f x)} →(∀ x → f x ≡ g x) →(∀ {x} → (y : P x) → h y ≡ k y) →(v : Σ A P) → map-Σ f h v ≡ map-Σ g k vmap-Σ-cong f≗g h≗k (x , y) = cong₂ _,_ (f≗g x) (h≗k y)-------------------------------------------------------------------------- map-Σ′module _ {B : A → Set b} {P : Set p} {Q : P → Set q} wheremap-Σ′-cong : {f g : (x : A) → B x} → {h k : (x : P) → Q x} →(∀ x → f x ≡ g x) →((y : P) → h y ≡ k y) →(v : A × P) → map-Σ′ f h v ≡ map-Σ′ g k vmap-Σ′-cong f≗g h≗k (x , y) = cong₂ _,_ (f≗g x) (h≗k y)-------------------------------------------------------------------------- zipWithmodule _ {P : A → Set p} {Q : B → Set q} {R : C → Set r} {S : (x : C) → R x → Set s} wherezipWith-flip : (_∙_ : A → B → C) → (_∘_ : ∀ {x y} → P x → Q y → R (x ∙ y)) →(_*_ : (x : C) → (y : R x) → S x y) →{x : Σ A P} → {y : Σ B Q} →zipWith _∙_ _∘_ _*_ x y ≡ zipWith (flip _∙_) (flip _∘_) _*_ y xzipWith-flip _∙_ _∘_ _*_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Nondependent heterogeneous N-ary products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Nary.NonDependent where-------------------------------------------------------------------------- Concrete examples can be found in README.Nary. This file's comments-- are more focused on the implementation details and the motivations-- behind the design decisions.------------------------------------------------------------------------open import Level using (Level)open import Agda.Builtin.Unitopen import Data.Product.Base as Prodimport Data.Product.Properties as Prodₚopen import Data.Sum.Base using (_⊎_)open import Data.Nat.Base using (ℕ; zero; suc; pred)open import Data.Fin.Base using (Fin; zero; suc)open import Function.Base using (const; _∘′_; _∘_)open import Relation.Nullary.Decidable.Core using (Dec; yes; no; _×-dec_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong₂)open import Function.Nary.NonDependent.Base-- Provided n Levels and a corresponding "vector" of `n` Sets, we can-- build a big right-nested product type packing a value for each one-- of these Sets.-- We have two distinct but equivalent definitions:-- the first which is always ⊤-terminated-- the other which has a special case for n = 1 because we want our-- `(un)curryₙ` functions to work for user-written functions and-- products and they rarely are ⊤-terminated.Product⊤ : ∀ n {ls} → Sets n ls → Set (⨆ n ls)Product⊤ zero as = ⊤Product⊤ (suc n) (a , as) = a × Product⊤ n asProduct : ∀ n {ls} → Sets n ls → Set (⨆ n ls)Product 0 _ = ⊤Product 1 (a , _) = aProduct (suc n) (a , as) = a × Product n as-- Pointwise lifting of a relation on productsAllₙ : (∀ {a} {A : Set a} → Rel A a) →∀ n {ls} {as : Sets n ls} (l r : Product n as) → Sets n lsAllₙ R 0 l r = _Allₙ R 1 a b = R a b , _Allₙ R (suc n@(suc _)) (a , l) (b , r) = R a b , Allₙ R n l rEqualₙ : ∀ n {ls} {as : Sets n ls} (l r : Product n as) → Sets n lsEqualₙ = Allₙ _≡_-------------------------------------------------------------------------- Generic Programs-- Once we have these type definitions, we can write generic programs-- over them. They will typically be split into two or three definitions:-- 1. action on the vector of n levels (if any)-- 2. action on the corresponding vector of n Sets-- 3. actual program, typed thank to the function defined in step 2.-------------------------------------------------------------------------- see Relation.Binary.PropositionalEquality for congₙ and substₙ, two-- equality-related generic programs.-------------------------------------------------------------------------- equivalence of Product and Product⊤toProduct : ∀ n {ls} {as : Sets n ls} → Product⊤ n as → Product n astoProduct 0 _ = _toProduct 1 (v , _) = vtoProduct (suc n@(suc _)) (v , vs) = v , toProduct n vstoProduct⊤ : ∀ n {ls} {as : Sets n ls} → Product n as → Product⊤ n astoProduct⊤ 0 _ = _toProduct⊤ 1 v = v , _toProduct⊤ (suc n@(suc _)) (v , vs) = v , toProduct⊤ n vs-------------------------------------------------------------------------- (un)curry-- We start by defining `curryₙ` and `uncurryₙ` converting back and forth-- between `A₁ → ⋯ → Aₙ → B` and `(A₁ × ⋯ × Aₙ) → B` by induction on `n`.curryₙ : ∀ n {ls} {as : Sets n ls} {r} {b : Set r} →(Product n as → b) → as ⇉ bcurryₙ 0 f = f _curryₙ 1 f = fcurryₙ (suc n@(suc _)) f = curryₙ n ∘′ curry funcurryₙ : ∀ n {ls} {as : Sets n ls} {r} {b : Set r} →as ⇉ b → (Product n as → b)uncurryₙ 0 f = const funcurryₙ 1 f = funcurryₙ (suc n@(suc _)) f = uncurry (uncurryₙ n ∘′ f)-- Variants for Product⊤curry⊤ₙ : ∀ n {ls} {as : Sets n ls} {r} {b : Set r} →(Product⊤ n as → b) → as ⇉ bcurry⊤ₙ zero f = f _curry⊤ₙ (suc n) f = curry⊤ₙ n ∘′ curry funcurry⊤ₙ : ∀ n {ls} {as : Sets n ls} {r} {b : Set r} →as ⇉ b → (Product⊤ n as → b)uncurry⊤ₙ zero f = const funcurry⊤ₙ (suc n) f = uncurry (uncurry⊤ₙ n ∘′ f)-------------------------------------------------------------------------- decidabilityProduct⊤-dec : ∀ n {ls} {as : Sets n ls} → Product⊤ n (Dec <$> as) → Dec (Product⊤ n as)Product⊤-dec zero _ = yes _Product⊤-dec (suc n) (p? , ps?) = p? ×-dec Product⊤-dec n ps?Product-dec : ∀ n {ls} {as : Sets n ls} → Product n (Dec <$> as) → Dec (Product n as)Product-dec 0 _ = yes _Product-dec 1 p? = p?Product-dec (suc n@(suc _)) (p? , ps?) = p? ×-dec Product-dec n ps?-------------------------------------------------------------------------- pointwise liftingstoEqualₙ : ∀ n {ls} {as : Sets n ls} {l r : Product n as} →l ≡ r → Product n (Equalₙ n l r)toEqualₙ 0 eq = _toEqualₙ 1 eq = eqtoEqualₙ (suc n@(suc _)) eq = Prod.map₂ (toEqualₙ n) (Prodₚ.,-injective eq)fromEqualₙ : ∀ n {ls} {as : Sets n ls} {l r : Product n as} →Product n (Equalₙ n l r) → l ≡ rfromEqualₙ 0 eq = reflfromEqualₙ 1 eq = eqfromEqualₙ (suc n@(suc _)) eq = uncurry (cong₂ _,_) (Prod.map₂ (fromEqualₙ n) eq)-------------------------------------------------------------------------- projection of the k-th component-- To know at which Set level the k-th projection out of an n-ary-- product lives, we need to extract said level, by induction on k.Levelₙ : ∀ {n} → Levels n → Fin n → LevelLevelₙ (l , _) zero = lLevelₙ (_ , ls) (suc k) = Levelₙ ls k-- Once we have the Sets used in the product, we can extract the one we-- are interested in, once more by induction on k.Projₙ : ∀ {n ls} → Sets n ls → ∀ k → Set (Levelₙ ls k)Projₙ (a , _) zero = aProjₙ (_ , as) (suc k) = Projₙ as k-- Finally, provided a Product of these sets, we can extract the k-th-- value. `projₙ` takes both `n` and `k` explicitly because we expect-- the user will be using a concrete `k` (potentially manufactured-- using `Data.Fin`'s `#_`) and it will not be possible to infer `n`-- from it.projₙ : ∀ n {ls} {as : Sets n ls} k → Product n as → Projₙ as kprojₙ 1 zero v = vprojₙ (suc n@(suc _)) zero (v , _) = vprojₙ (suc n@(suc _)) (suc k) (_ , vs) = projₙ n k vsprojₙ 1 (suc ()) v-------------------------------------------------------------------------- zipzipWith : ∀ n {lsa lsb lsc}{as : Sets n lsa} {bs : Sets n lsb} {cs : Sets n lsc} →(∀ k → Projₙ as k → Projₙ bs k → Projₙ cs k) →Product n as → Product n bs → Product n cszipWith 0 f _ _ = _zipWith 1 f v w = f zero v wzipWith (suc n@(suc _)) f (v , vs) (w , ws) =f zero v w , zipWith n (λ k → f (suc k)) vs ws-------------------------------------------------------------------------- removal of the k-th componentLevelₙ⁻ : ∀ {n} → Levels n → Fin n → Levels (pred n)Levelₙ⁻ (_ , ls) zero = lsLevelₙ⁻ {suc (suc _)} (l , ls) (suc k) = l , Levelₙ⁻ ls kLevelₙ⁻ {1} _ (suc ())Removeₙ : ∀ {n ls} → Sets n ls → ∀ k → Sets (pred n) (Levelₙ⁻ ls k)Removeₙ (_ , as) zero = asRemoveₙ {suc (suc _)} (a , as) (suc k) = a , Removeₙ as kRemoveₙ {1} _ (suc ())removeₙ : ∀ n {ls} {as : Sets n ls} k →Product n as → Product (pred n) (Removeₙ as k)removeₙ (suc zero) zero _ = _removeₙ (suc (suc _)) zero (_ , vs) = vsremoveₙ (suc (suc zero)) (suc k) (v , _) = vremoveₙ (suc (suc (suc _))) (suc k) (v , vs) = v , removeₙ _ k vsremoveₙ (suc zero) (suc ()) _-------------------------------------------------------------------------- insertion of a k-th componentLevelₙ⁺ : ∀ {n} → Levels n → Fin (suc n) → Level → Levels (suc n)Levelₙ⁺ ls zero l⁺ = l⁺ , lsLevelₙ⁺ {suc _} (l , ls) (suc k) l⁺ = l , Levelₙ⁺ ls k l⁺Levelₙ⁺ {0} _ (suc ())Insertₙ : ∀ {n ls l⁺} → Sets n ls → ∀ k (a⁺ : Set l⁺) → Sets (suc n) (Levelₙ⁺ ls k l⁺)Insertₙ as zero a⁺ = a⁺ , asInsertₙ {suc _} (a , as) (suc k) a⁺ = a , Insertₙ as k a⁺Insertₙ {zero} _ (suc ()) _insertₙ : ∀ n {ls l⁺} {as : Sets n ls} {a⁺ : Set l⁺} k (v⁺ : a⁺) →Product n as → Product (suc n) (Insertₙ as k a⁺)insertₙ 0 zero v⁺ vs = v⁺insertₙ (suc n) zero v⁺ vs = v⁺ , vsinsertₙ 1 (suc k) v⁺ vs = vs , insertₙ 0 k v⁺ _insertₙ (suc n@(suc _)) (suc k) v⁺ (v , vs) = v , insertₙ n k v⁺ vsinsertₙ 0 (suc ()) _ _-------------------------------------------------------------------------- update of a k-th componentLevelₙᵘ : ∀ {n} → Levels n → Fin n → Level → Levels nLevelₙᵘ (_ , ls) zero lᵘ = lᵘ , lsLevelₙᵘ (l , ls) (suc k) lᵘ = l , Levelₙᵘ ls k lᵘUpdateₙ : ∀ {n ls lᵘ} (as : Sets n ls) k (aᵘ : Set lᵘ) → Sets n (Levelₙᵘ ls k lᵘ)Updateₙ (_ , as) zero aᵘ = aᵘ , asUpdateₙ (a , as) (suc k) aᵘ = a , Updateₙ as k aᵘupdateₙ : ∀ n {ls lᵘ} {as : Sets n ls} k {aᵘ : _ → Set lᵘ} (f : ∀ v → aᵘ v)(vs : Product n as) → Product n (Updateₙ as k (aᵘ (projₙ n k vs)))updateₙ 1 zero f v = f vupdateₙ (suc (suc _)) zero f (v , vs) = f v , vsupdateₙ (suc n@(suc _)) (suc k) f (v , vs) = v , updateₙ n k f vsupdateₙ 1 (suc ()) _ _updateₙ′ : ∀ n {ls lᵘ} {as : Sets n ls} k {aᵘ : Set lᵘ} (f : Projₙ as k → aᵘ) →Product n as → Product n (Updateₙ as k aᵘ)updateₙ′ n k = updateₙ n k
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Instances whereopen import Data.Product.Baseusing (Σ)open import Data.Product.Propertiesopen import Levelopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_)open import Relation.Binary.Structuresusing (IsDecEquivalence)open import Relation.Binary.TypeClassesprivatevariablea b : LevelA : Set ainstanceΣ-≡-isDecEquivalence : ∀ {B : A → Set b} {{_ : IsDecEquivalence {A = A} _≡_}} {{_ : ∀ {a} → IsDecEquivalence {A = B a} _≡_}} → IsDecEquivalence {A = Σ A B} _≡_Σ-≡-isDecEquivalence = isDecEquivalence (≡-dec _≟_ _≟_)
-------------------------------------------------------------------------- The Agda standard library---- Non-dependent product combinators for setoid equality preserving-- functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Function.NonDependent.Setoid whereopen import Data.Product.Base as Productopen import Data.Product.Relation.Binary.Pointwise.NonDependent using (_×ₛ_)open import Level using (Level)open import Relation.Binary.Bundles using (Setoid)open import Function.Bundlesusing (Func; Equivalence; Injection; Surjection; Bijection; LeftInverse;RightInverse; Inverse)privatevariablea₁ a₂ b₁ b₂ c₁ c₂ d₁ d₂ : Levela ℓ : LevelA B C D : Setoid a ℓ-------------------------------------------------------------------------- Combinators for equality preserving functionsproj₁ₛ : Func (A ×ₛ B) Aproj₁ₛ = record { to = proj₁ ; cong = proj₁ }proj₂ₛ : Func (A ×ₛ B) Bproj₂ₛ = record { to = proj₂ ; cong = proj₂ }<_,_>ₛ : Func A B → Func A C → Func A (B ×ₛ C)< f , g >ₛ = record{ to = < to f , to g >; cong = < cong f , cong g >} where open Funcswapₛ : Func (A ×ₛ B) (B ×ₛ A)swapₛ = < proj₂ₛ , proj₁ₛ >ₛ-------------------------------------------------------------------------- Function bundles_×-function_ : Func A B → Func C D → Func (A ×ₛ C) (B ×ₛ D)f ×-function g = record{ to = Product.map (to f) (to g); cong = Product.map (cong f) (cong g)} where open Funcinfixr 2 _×-equivalence_ _×-injection_ _×-left-inverse__×-equivalence_ : Equivalence A B → Equivalence C D →Equivalence (A ×ₛ C) (B ×ₛ D)_×-equivalence_ f g = record{ to = Product.map (to f) (to g); from = Product.map (from f) (from g); to-cong = Product.map (to-cong f) (to-cong g); from-cong = Product.map (from-cong f) (from-cong g)} where open Equivalence_×-injection_ : Injection A B → Injection C D →Injection (A ×ₛ C) (B ×ₛ D)f ×-injection g = record{ to = Product.map (to f) (to g); cong = Product.map (cong f) (cong g); injective = Product.map (injective f) (injective g)} where open Injection_×-surjection_ : Surjection A B → Surjection C D →Surjection (A ×ₛ C) (B ×ₛ D)f ×-surjection g = record{ to = Product.map (to f) (to g); cong = Product.map (cong f) (cong g); surjective = λ y → Product.zip _,_ (λ ff gg x₂ → (ff (proj₁ x₂)) , (gg (proj₂ x₂))) (surjective f (proj₁ y)) (surjective g (proj₂ y))} where open Surjection_×-bijection_ : Bijection A B → Bijection C D →Bijection (A ×ₛ C) (B ×ₛ D)f ×-bijection g = record{ to = Product.map (to f) (to g); cong = Product.map (cong f) (cong g); bijective = Product.map (injective f) (injective g) ,λ { (y₀ , y₁) → Product.zip _,_ (λ {ff gg (x₀ , x₁) → ff x₀ , gg x₁}) (surjective f y₀) (surjective g y₁)}} where open Bijection_×-leftInverse_ : LeftInverse A B → LeftInverse C D →LeftInverse (A ×ₛ C) (B ×ₛ D)f ×-leftInverse g = record{ to = Product.map (to f) (to g); from = Product.map (from f) (from g); to-cong = Product.map (to-cong f) (to-cong g); from-cong = Product.map (from-cong f) (from-cong g); inverseˡ = λ x → inverseˡ f (proj₁ x) , inverseˡ g (proj₂ x)} where open LeftInverse_×-rightInverse_ : RightInverse A B → RightInverse C D →RightInverse (A ×ₛ C) (B ×ₛ D)f ×-rightInverse g = record{ to = Product.map (to f) (to g); from = Product.map (from f) (from g); to-cong = Product.map (to-cong f) (to-cong g); from-cong = Product.map (from-cong f) (from-cong g); inverseʳ = λ x → inverseʳ f (proj₁ x) , inverseʳ g (proj₂ x)} where open RightInverseinfixr 2 _×-surjection_ _×-inverse__×-inverse_ : Inverse A B → Inverse C D →Inverse (A ×ₛ C) (B ×ₛ D)f ×-inverse g = record{ to = Product.map (to f) (to g); from = Product.map (from f) (from g); to-cong = Product.map (to-cong f) (to-cong g); from-cong = Product.map (from-cong f) (from-cong g); inverse = (λ x → inverseˡ f (proj₁ x) , inverseˡ g (proj₂ x)) ,(λ x → inverseʳ f (proj₁ x) , inverseʳ g (proj₂ x))} where open Inverse-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0_×-left-inverse_ = _×-leftInverse_{-# WARNING_ON_USAGE _×-left-inverse_"Warning: _×-left-inverse_ was deprecated in v2.0.Please use _×-leftInverse_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Non-dependent product combinators for propositional equality-- preserving functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Function.NonDependent.Propositional whereopen import Data.Product.Base using (_×_; map)open import Data.Product.Function.NonDependent.Setoidopen import Data.Product.Relation.Binary.Pointwise.NonDependentusing (_×ₛ_; Pointwise-≡↔≡)open import Function.Base using (id)open import Function.Bundlesusing (Inverse; _⟶_; _⇔_; _↣_; _↠_; _⤖_; _↩_; _↪_; _↔_)open import Function.Properties.Inverse as Invusing (Inverse⇒Equivalence; Inverse⇒Injection; Inverse⇒Surjection;Inverse⇒Bijection)open import Function.Related.Propositionalusing (_∼[_]_; implication; reverseImplication; equivalence; injection;reverseInjection; leftInverse; surjection; bijection)import Function.Construct.Composition as Composeopen import Level using (Level; _⊔_)open import Relation.Binary hiding (_⇔_)open import Relation.Binary.PropositionalEquality.Properties using (setoid)privatevariablea b c d : LevelA B C D : Set a-------------------------------------------------------------------------- Helper lemmaprivateliftViaInverse : {R : ∀ {a b ℓ₁ ℓ₂} → REL (Setoid a ℓ₁) (Setoid b ℓ₂) (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)} →(∀ {a b c ℓ₁ ℓ₂ ℓ₃} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} {U : Setoid c ℓ₃} → R S T → R T U → R S U) →(∀ {a b ℓ₁ ℓ₂} {S : Setoid a ℓ₁} {T : Setoid b ℓ₂} → Inverse S T → R S T) →(R (setoid A) (setoid C) → R (setoid B) (setoid D) → R (setoid A ×ₛ setoid B) (setoid C ×ₛ setoid D)) →R (setoid A) (setoid C) → R (setoid B) (setoid D) →R (setoid (A × B)) (setoid (C × D))liftViaInverse trans inv⇒R lift RAC RBD =Inv.transportVia trans inv⇒R (Inv.sym Pointwise-≡↔≡) (lift RAC RBD) Pointwise-≡↔≡-------------------------------------------------------------------------- Combinators for various function typesinfixr 2 _×-⟶_ _×-⇔_ _×-↣_ _×-↠_ _×-⤖_ _×-↩_ _×-↪_ _×-↔__×-⟶_ : A ⟶ B → C ⟶ D → (A × C) ⟶ (B × D)_×-⟶_ = liftViaInverse Compose.function Inv.toFunction _×-function__×-⇔_ : A ⇔ B → C ⇔ D → (A × C) ⇔ (B × D)_×-⇔_ = liftViaInverse Compose.equivalence Inverse⇒Equivalence _×-equivalence__×-↣_ : A ↣ B → C ↣ D → (A × C) ↣ (B × D)_×-↣_ = liftViaInverse Compose.injection Inverse⇒Injection _×-injection__×-↠_ : A ↠ B → C ↠ D → (A × C) ↠ (B × D)_×-↠_ = liftViaInverse Compose.surjection Inverse⇒Surjection _×-surjection__×-⤖_ : A ⤖ B → C ⤖ D → (A × C) ⤖ (B × D)_×-⤖_ = liftViaInverse Compose.bijection Inverse⇒Bijection _×-bijection__×-↩_ : A ↩ B → C ↩ D → (A × C) ↩ (B × D)_×-↩_ = liftViaInverse Compose.leftInverse Inverse.leftInverse _×-leftInverse__×-↪_ : A ↪ B → C ↪ D → (A × C) ↪ (B × D)_×-↪_ = liftViaInverse Compose.rightInverse Inverse.rightInverse _×-rightInverse__×-↔_ : A ↔ B → C ↔ D → (A × C) ↔ (B × D)_×-↔_ = liftViaInverse Compose.inverse id _×-inverse_infixr 2 _×-cong__×-cong_ : ∀ {k} → A ∼[ k ] B → C ∼[ k ] D → (A × C) ∼[ k ] (B × D)_×-cong_ {k = implication} = _×-⟶__×-cong_ {k = reverseImplication} = _×-⟶__×-cong_ {k = equivalence} = _×-⇔__×-cong_ {k = injection} = _×-↣__×-cong_ {k = reverseInjection} = _×-↣__×-cong_ {k = leftInverse} = _×-↪__×-cong_ {k = surjection} = _×-↠__×-cong_ {k = bijection} = _×-↔_
-------------------------------------------------------------------------- The Agda standard library---- Dependent product combinators for setoid equality preserving-- functions.---- NOTE: the first component of the equality is propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Function.Dependent.Setoid whereopen import Data.Product.Base using (map; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.Dependent as Σopen import Level using (Level)open import Functionopen import Function.Consequences.Setoidopen import Function.Properties.Injection using (mkInjection)open import Function.Properties.Surjection using (mkSurjection; ↠⇒⇔)open import Function.Properties.Equivalence using (mkEquivalence; ⇔⇒⟶; ⇔⇒⟵)open import Function.Properties.RightInverse using (mkRightInverse)open import Relation.Binary.Core using (_=[_]⇒_)open import Relation.Binary.Bundles as Bopen import Relation.Binary.Indexed.Heterogeneoususing (IndexedSetoid)open import Relation.Binary.Indexed.Heterogeneous.Construct.Atusing (_atₛ_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablei a b ℓ₁ ℓ₂ : LevelI J : Set iA B : IndexedSetoid I a ℓ₁-------------------------------------------------------------------------- Properties related to "relatedness"------------------------------------------------------------------------private module _ (A : IndexedSetoid I a ℓ₁) whereopen IndexedSetoid Acast : ∀ {i j} → j ≡ i → Carrier i → Carrier jcast j≡i = ≡.subst Carrier (≡.sym $ j≡i)cast-cong : ∀ {i j} {x y : Carrier i}(j≡i : j ≡ i) →x ≈ y →cast j≡i x ≈ cast j≡i ycast-cong ≡.refl p = pcast-eq : ∀ {i j x} (eq : i ≡ j) → cast eq x ≈ xcast-eq ≡.refl = IndexedSetoid.refl Aprivate_×ₛ_ : (I : Set i) → IndexedSetoid I a ℓ₁ → Setoid _ _I ×ₛ A = Σ.setoid (≡.setoid I) A-------------------------------------------------------------------------- Functionsmodule _ whereopen Funcopen Setoidfunction :(f : I ⟶ J) →(∀ {i} → Func (A atₛ i) (B atₛ (to f i))) →Func (I ×ₛ A) (J ×ₛ B)function {I = I} {J = J} {A = A} {B = B} I⟶J A⟶B = record{ to = to′; cong = cong′}whereto′ = map (to I⟶J) (to A⟶B)cong′ : Congruent (_≈_ (I ×ₛ A)) (_≈_ (J ×ₛ B)) to′cong′ (≡.refl , ∼) = (≡.refl , cong A⟶B ∼)-------------------------------------------------------------------------- Equivalencesmodule _ whereopen Equivalenceequivalence :(I⇔J : I ⇔ J) →(∀ {i} → Func (A atₛ i) (B atₛ (to I⇔J i))) →(∀ {j} → Func (B atₛ j) (A atₛ (from I⇔J j))) →Equivalence (I ×ₛ A) (J ×ₛ B)equivalence I⇔J A⟶B B⟶A = mkEquivalence(function (⇔⇒⟶ I⇔J) A⟶B)(function (⇔⇒⟵ I⇔J) B⟶A)equivalence-↪ :(I↪J : I ↪ J) →(∀ {i} → Equivalence (A atₛ (RightInverse.from I↪J i)) (B atₛ i)) →Equivalence (I ×ₛ A) (J ×ₛ B)equivalence-↪ {A = A} {B = B} I↪J A⇔B =equivalence (RightInverse.equivalence I↪J) A→B (fromFunction A⇔B)whereA→B : ∀ {i} → Func (A atₛ i) (B atₛ (RightInverse.to I↪J i))A→B = record{ to = to A⇔B ∘ cast A (RightInverse.strictlyInverseʳ I↪J _); cong = to-cong A⇔B ∘ cast-cong A (RightInverse.strictlyInverseʳ I↪J _)}equivalence-↠ :(I↠J : I ↠ J) →(∀ {x} → Equivalence (A atₛ x) (B atₛ (Surjection.to I↠J x))) →Equivalence (I ×ₛ A) (J ×ₛ B)equivalence-↠ {A = A} {B = B} I↠J A⇔B =equivalence (↠⇒⇔ I↠J) B-to B-fromwhereB-to : ∀ {x} → Func (A atₛ x) (B atₛ (Surjection.to I↠J x))B-to = toFunction A⇔BB-from : ∀ {y} → Func (B atₛ y) (A atₛ (Surjection.to⁻ I↠J y))B-from = record{ to = from A⇔B ∘ cast B (Surjection.to∘to⁻ I↠J _); cong = from-cong A⇔B ∘ cast-cong B (Surjection.to∘to⁻ I↠J _)}-------------------------------------------------------------------------- Injectionsmodule _ whereopen Injection hiding (function)open IndexedSetoidinjection :(I↣J : I ↣ J) →(∀ {i} → Injection (A atₛ i) (B atₛ (Injection.to I↣J i))) →Injection (I ×ₛ A) (J ×ₛ B)injection {I = I} {J = J} {A = A} {B = B} I↣J A↣B = mkInjection func injwherefunc : Func (I ×ₛ A) (J ×ₛ B)func = function (Injection.function I↣J) (Injection.function A↣B)inj : Injective (Func.Eq₁._≈_ func) (Func.Eq₂._≈_ func) (Func.to func)inj (to[i]≡to[j] , y) =injective I↣J to[i]≡to[j] ,lemma (injective I↣J to[i]≡to[j]) ywherelemma :∀ {i j} {x : Carrier A i} {y : Carrier A j} →i ≡ j →(_≈_ B (to A↣B x) (to A↣B y)) →_≈_ A x ylemma ≡.refl = Injection.injective A↣B-------------------------------------------------------------------------- Surjectionsmodule _ whereopen Surjection hiding (function)open Setoidsurjection :(I↠J : I ↠ J) →(∀ {x} → Surjection (A atₛ x) (B atₛ (to I↠J x))) →Surjection (I ×ₛ A) (J ×ₛ B)surjection {I = I} {J = J} {A = A} {B = B} I↠J A↠B =mkSurjection func surjwherefunc : Func (I ×ₛ A) (J ×ₛ B)func = function (Surjection.function I↠J) (Surjection.function A↠B)to⁻′ : Carrier (J ×ₛ B) → Carrier (I ×ₛ A)to⁻′ (j , y) = to⁻ I↠J j , to⁻ A↠B (cast B (Surjection.to∘to⁻ I↠J _) y)strictlySurj : StrictlySurjective (Func.Eq₂._≈_ func) (Func.to func)strictlySurj (j , y) = to⁻′ (j , y) ,to∘to⁻ I↠J j , IndexedSetoid.trans B (to∘to⁻ A↠B _) (cast-eq B (to∘to⁻ I↠J j))surj : Surjective (Func.Eq₁._≈_ func) (Func.Eq₂._≈_ func) (Func.to func)surj = strictlySurjective⇒surjective (I ×ₛ A) (J ×ₛ B) (Func.cong func) strictlySurj-------------------------------------------------------------------------- LeftInversemodule _ whereopen RightInverseopen Setoidleft-inverse :(I↪J : I ↪ J) →(∀ {j} → RightInverse (A atₛ (from I↪J j)) (B atₛ j)) →RightInverse (I ×ₛ A) (J ×ₛ B)left-inverse {I = I} {J = J} {A = A} {B = B} I↪J A↪B =mkRightInverse equiv invʳwhereequiv : Equivalence (I ×ₛ A) (J ×ₛ B)equiv = equivalence-↪ I↪J (RightInverse.equivalence A↪B)strictlyInvʳ : StrictlyInverseʳ (_≈_ (I ×ₛ A)) (Equivalence.to equiv) (Equivalence.from equiv)strictlyInvʳ (i , x) = strictlyInverseʳ I↪J i , IndexedSetoid.trans A (strictlyInverseʳ A↪B _) (cast-eq A (strictlyInverseʳ I↪J i))invʳ : Inverseʳ (_≈_ (I ×ₛ A)) (_≈_ (J ×ₛ B)) (Equivalence.to equiv) (Equivalence.from equiv)invʳ = strictlyInverseʳ⇒inverseʳ (I ×ₛ A) (J ×ₛ B) (Equivalence.from-cong equiv) strictlyInvʳ-------------------------------------------------------------------------- Inversesmodule _ whereopen Inverse hiding (inverse)open Setoidinverse : (I↔J : I ↔ J) →(∀ {i} → Inverse (A atₛ i) (B atₛ (to I↔J i))) →Inverse (I ×ₛ A) (J ×ₛ B)inverse {I = I} {J = J} {A = A} {B = B} I↔J A↔B = record{ to = to′; from = from′; to-cong = to′-cong; from-cong = from′-cong; inverse = invˡ , invʳ}whereto′ : Carrier (I ×ₛ A) → Carrier (J ×ₛ B)to′ (i , x) = to I↔J i , to A↔B xto′-cong : Congruent (_≈_ (I ×ₛ A)) (_≈_ (J ×ₛ B)) to′to′-cong (≡.refl , x≈y) = to-cong I↔J ≡.refl , to-cong A↔B x≈yfrom′ : Carrier (J ×ₛ B) → Carrier (I ×ₛ A)from′ (j , y) = from I↔J j , from A↔B (cast B (strictlyInverseˡ I↔J _) y)from′-cong : Congruent (_≈_ (J ×ₛ B)) (_≈_ (I ×ₛ A)) from′from′-cong (≡.refl , x≈y) = from-cong I↔J ≡.refl , from-cong A↔B (cast-cong B (strictlyInverseˡ I↔J _) x≈y)strictlyInvˡ : StrictlyInverseˡ (_≈_ (J ×ₛ B)) to′ from′strictlyInvˡ (i , x) = strictlyInverseˡ I↔J i ,IndexedSetoid.trans B (strictlyInverseˡ A↔B _)(cast-eq B (strictlyInverseˡ I↔J i))invˡ : Inverseˡ (_≈_ (I ×ₛ A)) (_≈_ (J ×ₛ B)) to′ from′invˡ = strictlyInverseˡ⇒inverseˡ (I ×ₛ A) (J ×ₛ B) to′-cong strictlyInvˡlem : ∀ {i j} → i ≡ j → ∀ {x : IndexedSetoid.Carrier B (to I↔J i)} {y : IndexedSetoid.Carrier B (to I↔J j)} →IndexedSetoid._≈_ B x y →IndexedSetoid._≈_ A (from A↔B x) (from A↔B y)lem ≡.refl x≈y = from-cong A↔B x≈ystrictlyInvʳ : StrictlyInverseʳ (_≈_ (I ×ₛ A)) to′ from′strictlyInvʳ (i , x) = strictlyInverseʳ I↔J i ,IndexedSetoid.trans A (lem (strictlyInverseʳ I↔J _) (cast-eq B (strictlyInverseˡ I↔J _))) (strictlyInverseʳ A↔B _)invʳ : Inverseʳ (_≈_ (I ×ₛ A)) (_≈_ (J ×ₛ B)) to′ from′invʳ = strictlyInverseʳ⇒inverseʳ (I ×ₛ A) (J ×ₛ B) from′-cong strictlyInvʳ
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Product.Function.Dependent.Setoid.WithK whereopen import Data.Product.Function.Dependent.Setoid publicusing (inverse){-# WARNING_ON_IMPORT"Data.Product.Function.Dependent.Setoid.WithK was deprecated in v2.0.Use Data.Product.Function.Dependent.Setoid instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Dependent product combinators for propositional equality-- preserving functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Function.Dependent.Propositional whereopen import Data.Product.Base as Product using (Σ; map; proj₂; _,_)open import Data.Product.Properties using (Σ-≡,≡→≡; Σ-≡,≡↔≡; Σ-≡,≡←≡)open import Level using (Level; 0ℓ)open import Function.Related.Propositionalusing (_∼[_]_; module EquationalReasoning; K-reflexive;implication; reverseImplication; equivalence; injection;reverseInjection; leftInverse; surjection; bijection)open import Function.Base using (_$_; _∘_; _∘′_)open import Function.Properties.Inverse using (↔⇒↠; ↔⇒⟶; ↔⇒⟵; ↔-sym; ↔⇒↩)open import Function.Properties.RightInverse using (↩⇒↪; ↪⇒↩)open import Function.Properties.Inverse.HalfAdjointEquivalenceusing (↔⇒≃; _≃_; ≃⇒↔)open import Function.Consequences.Propositionalusing (inverseʳ⇒injective; strictlySurjective⇒surjective)open import Function.Definitions using (Inverseˡ; Inverseʳ; Injective; StrictlySurjective)open import Function.Bundlesopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.PropositionalEquality.Properties as ≡using (module ≡-Reasoning)privatevariablei a b c d : LevelI J : Set iA B : I → Set a-------------------------------------------------------------------------- Functionsmodule _ whereopen FuncΣ-⟶ : (I⟶J : I ⟶ J) →(∀ {i} → A i ⟶ B (to I⟶J i)) →Σ I A ⟶ Σ J BΣ-⟶ I⟶J A⟶B = mk⟶ $ Product.map (to I⟶J) (to A⟶B)-------------------------------------------------------------------------- Equivalencesmodule _ whereopen SurjectionΣ-⇔ : (I↠J : I ↠ J) →(∀ {i} → A i ⇔ B (to I↠J i)) →Σ I A ⇔ Σ J BΣ-⇔ {B = B} I↠J A⇔B = mk⇔(map (to I↠J) (Equivalence.to A⇔B))(map (to⁻ I↠J) (Equivalence.from A⇔B ∘ ≡.subst B (≡.sym (proj₂ (surjective I↠J _) ≡.refl))))-- See also Data.Product.Relation.Binary.Pointwise.Dependent.WithK.↣.-------------------------------------------------------------------------- Injectionsmodule _ whereΣ-↣ : (I↔J : I ↔ J) →(∀ {i} → A i ↣ B (Inverse.to I↔J i)) →Σ I A ↣ Σ J BΣ-↣ {I = I} {J = J} {A = A} {B = B} I↔J A↣B = mk↣ to-injectivewhereopen ≡.≡-ReasoningI≃J = ↔⇒≃ I↔Jsubst-application′ :let open _≃_ I≃J in{x₁ x₂ : I} {y : A (from (to x₁))}(g : ∀ x → A (from (to x)) → B (to x))(eq : to x₁ ≡ to x₂) →≡.subst B eq (g x₁ y) ≡ g x₂ (≡.subst A (≡.cong from eq) y)subst-application′ {x₁} {x₂} {y} g eq =≡.subst B eq (g x₁ y) ≡⟨ ≡.cong (≡.subst B eq) (≡.sym (g′-lemma _ _)) ⟩≡.subst B eq (g′ (to x₁) y) ≡⟨ ≡.subst-application A g′ eq ⟩g′ (to x₂) (≡.subst A (≡.cong from eq) y) ≡⟨ g′-lemma _ _ ⟩g x₂ (≡.subst A (≡.cong from eq) y) ∎whereopen _≃_ I≃Jg′ : ∀ x → A (from x) → B xg′ x =≡.subst B (right-inverse-of x) ∘g (from x) ∘≡.subst A (≡.sym (≡.cong from (right-inverse-of x)))g′-lemma : ∀ x y → g′ (to x) y ≡ g x yg′-lemma x y =≡.subst B (right-inverse-of (to x))(g (from (to x)) $≡.subst A (≡.sym (≡.cong from (right-inverse-of (to x)))) y) ≡⟨ ≡.cong (λ p → ≡.subst B p (g (from (to x))(≡.subst A (≡.sym (≡.cong from p)) y)))(≡.sym (left-right x)) ⟩≡.subst B (≡.cong to (left-inverse-of x))(g (from (to x)) $≡.subst A(≡.sym (≡.cong from (≡.cong to (left-inverse-of x))))y) ≡⟨ lemma _ ⟩g x y ∎wherelemma : ∀ {x′} eq {y : A (from (to x′))} →≡.subst B (≡.cong to eq)(g (from (to x))(≡.subst A (≡.sym (≡.cong from (≡.cong to eq))) y)) ≡g x′ ylemma ≡.refl = ≡.reflopen Injectionto′ : Σ I A → Σ J Bto′ = Product.map (_≃_.to I≃J) (to A↣B)to-injective : Injective _≡_ _≡_ to′to-injective {(x₁ , x₂)} {(y₁ , y₂)} =Σ-≡,≡→≡ ∘′map (_≃_.injective I≃J) (λ {eq₁} eq₂ → injective A↣B (to A↣B (≡.subst A (_≃_.injective I≃J eq₁) x₂) ≡⟨⟩(let eq =≡.trans (≡.sym (_≃_.left-inverse-of I≃J x₁))(≡.trans (≡.cong (_≃_.from I≃J) eq₁)(≡.trans (_≃_.left-inverse-of I≃J y₁)≡.refl)) into A↣B (≡.subst A eq x₂)) ≡⟨ ≡.cong (λ p → to A↣B(≡.subst A(≡.trans (≡.sym (_≃_.left-inverse-of I≃J _))(≡.trans (≡.cong (_≃_.from I≃J) eq₁) p))x₂))(≡.trans-reflʳ _) ⟩(let eq = ≡.trans (≡.sym (_≃_.left-inverse-of I≃J x₁))(≡.trans (≡.cong (_≃_.from I≃J) eq₁)(_≃_.left-inverse-of I≃J y₁)) into A↣B (≡.subst A eq x₂)) ≡⟨ ≡.cong (to A↣B)(≡.sym (≡.subst-subst (≡.sym (_≃_.left-inverse-of I≃J _)))) ⟩to A↣B ((≡.subst A (≡.trans (≡.cong (_≃_.from I≃J) eq₁)(_≃_.left-inverse-of I≃J y₁)) $≡.subst A (≡.sym (_≃_.left-inverse-of I≃J x₁)) x₂)) ≡⟨ ≡.cong (to A↣B)(≡.sym (≡.subst-subst (≡.cong (_≃_.from I≃J) eq₁))) ⟩to A↣B ((≡.subst A (_≃_.left-inverse-of I≃J y₁) $≡.subst A (≡.cong (_≃_.from I≃J) eq₁) $≡.subst A (≡.sym (_≃_.left-inverse-of I≃J x₁)) x₂)) ≡⟨ ≡.sym (subst-application′(λ x y → to A↣B(≡.subst A (_≃_.left-inverse-of I≃J x) y))eq₁) ⟩≡.subst B eq₁ (to A↣B $(≡.subst A (_≃_.left-inverse-of I≃J x₁) $≡.subst A (≡.sym (_≃_.left-inverse-of I≃J x₁)) x₂)) ≡⟨ ≡.cong (≡.subst B eq₁ ∘ to A↣B)(≡.subst-subst (≡.sym (_≃_.left-inverse-of I≃J _))) ⟩(let eq = ≡.trans (≡.sym (_≃_.left-inverse-of I≃J x₁))(_≃_.left-inverse-of I≃J x₁) in≡.subst B eq₁ (to A↣B (≡.subst A eq x₂))) ≡⟨ ≡.cong (λ p → ≡.subst B eq₁ (to A↣B (≡.subst A p x₂)))(≡.trans-symˡ (_≃_.left-inverse-of I≃J _)) ⟩≡.subst B eq₁ (to A↣B (≡.subst A ≡.refl x₂)) ≡⟨⟩≡.subst B eq₁ (to A↣B x₂) ≡⟨ eq₂ ⟩to A↣B y₂ ∎)) ∘Σ-≡,≡←≡-------------------------------------------------------------------------- Surjectionsmodule _ whereopen SurjectionΣ-↠ : (I↠J : I ↠ J) →(∀ {x} → A x ↠ B (to I↠J x)) →Σ I A ↠ Σ J BΣ-↠ {I = I} {J = J} {A = A} {B = B} I↠J A↠B =mk↠ₛ strictlySurjective′whereto′ : Σ I A → Σ J Bto′ = map (to I↠J) (to A↠B)backcast : ∀ {i} → B i → B (to I↠J (to⁻ I↠J i))backcast = ≡.subst B (≡.sym (to∘to⁻ I↠J _))to⁻′ : Σ J B → Σ I Ato⁻′ = map (to⁻ I↠J) (Surjection.to⁻ A↠B ∘ backcast)strictlySurjective′ : StrictlySurjective _≡_ to′strictlySurjective′ (x , y) = to⁻′ (x , y) , Σ-≡,≡→≡( to∘to⁻ I↠J x, (≡.subst B (to∘to⁻ I↠J x) (to A↠B (to⁻ A↠B (backcast y))) ≡⟨ ≡.cong (≡.subst B _) (to∘to⁻ A↠B _) ⟩≡.subst B (to∘to⁻ I↠J x) (backcast y) ≡⟨ ≡.subst-subst-sym (to∘to⁻ I↠J x) ⟩y ∎)) where open ≡.≡-Reasoning-------------------------------------------------------------------------- Left inversesmodule _ whereopen LeftInverseΣ-↩ : (I↩J : I ↩ J) →(∀ {i} → A i ↩ B (to I↩J i)) →Σ I A ↩ Σ J BΣ-↩ {I = I} {J = J} {A = A} {B = B} I↩J A↩B = mk↩ {to = to′ } {from = from′} invwhereto′ : Σ I A → Σ J Bto′ = map (to I↩J) (to A↩B)backcast : ∀ {j} → B j → B (to I↩J (from I↩J j))backcast = ≡.subst B (≡.sym (inverseˡ I↩J ≡.refl))from′ : Σ J B → Σ I Afrom′ = map (from I↩J) (from A↩B ∘ backcast)inv : Inverseˡ _≡_ _≡_ to′ from′inv {j , b} ≡.refl = Σ-≡,≡→≡ (strictlyInverseˡ I↩J j , (begin≡.subst B (inverseˡ I↩J ≡.refl) (to A↩B (from A↩B (backcast b))) ≡⟨ ≡.cong (≡.subst B _) (inverseˡ A↩B ≡.refl) ⟩≡.subst B (inverseˡ I↩J ≡.refl) (backcast b) ≡⟨ ≡.subst-subst-sym (inverseˡ I↩J _) ⟩b ∎)) where open ≡.≡-Reasoning-------------------------------------------------------------------------- Right inverses-------------------------------------------------------------------------- Inversesmodule _ whereopen InverseΣ-↔ : (I↔J : I ↔ J) →(∀ {x} → A x ↔ B (to I↔J x)) →Σ I A ↔ Σ J BΣ-↔ {I = I} {J = J} {A = A} {B = B} I↔J A↔B = mk↔ₛ′(Surjection.to surjection′)(Surjection.to⁻ surjection′)(Surjection.to∘to⁻ surjection′)left-inverse-ofwhereopen ≡.≡-ReasoningI≃J = ↔⇒≃ I↔Jsurjection′ : Σ I A ↠ Σ J Bsurjection′ = Σ-↠ (↔⇒↠ (≃⇒↔ I≃J)) (↔⇒↠ A↔B)left-inverse-of : ∀ p → Surjection.to⁻ surjection′ (Surjection.to surjection′ p) ≡ pleft-inverse-of (x , y) = to Σ-≡,≡↔≡( _≃_.left-inverse-of I≃J x, (≡.subst A (_≃_.left-inverse-of I≃J x)(from A↔B(≡.subst B (≡.sym (_≃_.right-inverse-of I≃J(_≃_.to I≃J x)))(to A↔B y))) ≡⟨ ≡.subst-application B (λ _ → from A↔B) _ ⟩from A↔B(≡.subst B (≡.cong (_≃_.to I≃J)(_≃_.left-inverse-of I≃J x))(≡.subst B (≡.sym (_≃_.right-inverse-of I≃J(_≃_.to I≃J x)))(to A↔B y))) ≡⟨ ≡.cong (λ eq → from A↔B (≡.subst B eq(≡.subst B (≡.sym (_≃_.right-inverse-of I≃J _)) _)))(_≃_.left-right I≃J _) ⟩from A↔B(≡.subst B (_≃_.right-inverse-of I≃J(_≃_.to I≃J x))(≡.subst B (≡.sym (_≃_.right-inverse-of I≃J(_≃_.to I≃J x)))(to A↔B y))) ≡⟨ ≡.cong (from A↔B)(≡.subst-subst-sym (_≃_.right-inverse-of I≃J _)) ⟩from A↔B (to A↔B y) ≡⟨ Inverse.strictlyInverseʳ A↔B _ ⟩y ∎))private module _ whereopen Inverseswap-coercions : ∀ {k} (B : J → Set b)(I↔J : _↔_ I J) →(∀ {x} → A x ∼[ k ] B (to I↔J x)) →∀ {x} → A (from I↔J x) ∼[ k ] B xswap-coercions {A = A} B I↔J eq {x} =A (from I↔J x) ∼⟨ eq ⟩B (to I↔J (from I↔J x)) ↔⟨ K-reflexive (≡.cong B $ strictlyInverseˡ I↔J x) ⟩B x ∎where open EquationalReasoningcong : ∀ {k} (I↔J : I ↔ J) →(∀ {x} → A x ∼[ k ] B (Inverse.to I↔J x)) →Σ I A ∼[ k ] Σ J Bcong {k = implication} I↔J A⟶B = Σ-⟶ (↔⇒⟶ I↔J) A⟶Bcong {B = B} {k = reverseImplication} I↔J A⟵B = Σ-⟶ (↔⇒⟵ I↔J) (swap-coercions {k = reverseImplication} B I↔J A⟵B)cong {k = equivalence} I↔J A⇔B = Σ-⇔ (↔⇒↠ I↔J) A⇔Bcong {k = injection} I↔J A↣B = Σ-↣ I↔J A↣Bcong {B = B} {k = reverseInjection} I↔J A↢B = Σ-↣ (↔-sym I↔J) (swap-coercions {k = reverseInjection} B I↔J A↢B)cong {B = B} {k = leftInverse} I↔J A↩B = ↩⇒↪ (Σ-↩ (↔⇒↩ (↔-sym I↔J)) (↪⇒↩ (swap-coercions {k = leftInverse} B I↔J A↩B)))cong {k = surjection} I↔J A↠B = Σ-↠ (↔⇒↠ I↔J) A↠Bcong {k = bijection} I↔J A↔B = Σ-↔ I↔J A↔B
-------------------------------------------------------------------------- The Agda standard library---- Dependent product combinators for propositional equality-- preserving functions------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Product.Function.Dependent.Propositional.WithK whereopen import Data.Product.Baseopen import Data.Product.Propertiesopen import Data.Product.Function.Dependent.Setoid using (injection)open import Data.Product.Relation.Binary.Pointwise.Dependentopen import Data.Product.Relation.Binary.Pointwise.Dependent.WithKopen import Relation.Binary.Indexed.Heterogeneous.Construct.At using (_atₛ_)open import Relation.Binary.HeterogeneousEquality as Hopen import Level using (Level)open import Functionopen import Function.Properties.Injectionopen import Function.Properties.Inverse as Inverseprivatevariablei a : LevelI J : Set iA B : I → Set a-------------------------------------------------------------------------- Combinator for Injectionmodule _ whereopen InjectionΣ-↣ : (I↣J : I ↣ J) →(∀ {i} → A i ↣ B (to I↣J i)) →Σ I A ↣ Σ J BΣ-↣ {A = A} {B = B} I↣J A↣B =↣-trans (Inverse⇒Injection (Inverse.sym Pointwise-≡↔≡)) $↣-trans (injection I↣J Aᵢ↣Bᵢ) $Inverse⇒Injection Pointwise-≡↔≡whereAᵢ↣Bᵢ : (∀ {i} → Injection (H.indexedSetoid A atₛ i) (H.indexedSetoid B atₛ (Injection.to I↣J i)))Aᵢ↣Bᵢ =↣-trans (Inverse⇒Injection (Inverse.sym (H.≡↔≅ A))) $↣-trans A↣B $Inverse⇒Injection (H.≡↔≅ B)
-------------------------------------------------------------------------- The Agda standard library---- Right-biased universe-sensitive functor and monad instances for the-- Product type.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the Data.Product.Effectful.Examples for how this is-- done.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Levelmodule Data.Product.Effectful.Right(a : Level) {b e} (B : RawMonoid b e) whereopen import Data.Product.Baseimport Data.Product.Effectful.Right.Base as Baseopen import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; RawMonadT; mkRawMonad)open import Function.Base using (id; flip; _∘_; _∘′_)import Function.Identity.Effectful as Idopen RawMonoid B-------------------------------------------------------------------------- Re-export the base contents publicallyopen Base Carrier a public-------------------------------------------------------------------------- Basic recordsapplicative : RawApplicative Productᵣapplicative = record{ rawFunctor = functor; pure = _, ε; _<*>_ = zip id _∙_}monad : RawMonad Productᵣmonad = record{ rawApplicative = applicative; _>>=_ = uncurry λ a w₁ f → map₂ (w₁ ∙_) (f a)}monadT : ∀ {ℓ} → RawMonadT {g₁ = ℓ} (_∘′ Productᵣ)monadT M = record{ lift = (_, ε) <$>_; rawMonad = mkRawMonad _(pure ∘′ (_, ε))(λ ma f → ma >>= uncurry λ x b → map₂ (b ∙_) <$> f x)} where open RawMonad M-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Productᵣ (F A) → F (Productᵣ A)sequenceA (fa , y) = (_, y) <$> famapA : ∀ {A B} → (A → F B) → Productᵣ A → F (Productᵣ B)mapA f = sequenceA ∘ map₁ fforA : ∀ {A B} → Productᵣ A → (A → F B) → F (Productᵣ B)forA = flip mapAmodule TraversableM {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- Base definitions for the right-biased universe-sensitive functor-- and monad instances for the Product type.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the Data.Product.Effectful.Examples for how this is-- done.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Product.Effectful.Right.Base{b} (B : Set b) (a : Level) whereopen import Data.Product.Base using (_×_; map₁; proj₁; proj₂; <_,_>)open import Effect.Functor using (RawFunctor)open import Effect.Comonad using (RawComonad)-------------------------------------------------------------------------- DefinitionsProductᵣ : Set (a ⊔ b) → Set (a ⊔ b)Productᵣ A = A × Bfunctor : RawFunctor Productᵣfunctor = record { _<$>_ = map₁ }comonad : RawComonad Productᵣcomonad = record{ extract = proj₁; extend = <_, proj₂ >}
-------------------------------------------------------------------------- The Agda standard library---- Left-biased universe-sensitive functor and monad instances for the-- Product type.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the Data.Product.Effectful.Examples for how this is-- done.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Levelmodule Data.Product.Effectful.Left{a e} (A : RawMonoid a e) (b : Level) whereopen import Data.Product.Baseimport Data.Product.Effectful.Left.Base as Baseopen import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad; RawMonadT; mkRawMonad)open import Function.Base using (id; flip; _∘_; _∘′_)import Function.Identity.Effectful as Idopen RawMonoid A-------------------------------------------------------------------------- Re-export the base contents publicallyopen Base Carrier b public-------------------------------------------------------------------------- Basic recordsapplicative : RawApplicative Productₗapplicative = record{ rawFunctor = functor; pure = ε ,_; _<*>_ = zip _∙_ id}monad : RawMonad Productₗmonad = record{ rawApplicative = applicative; _>>=_ = uncurry λ w₁ a f → map₁ (w₁ ∙_) (f a)}-- The monad instance also requires some mucking about with universe levels.monadT : ∀ {ℓ} → RawMonadT {g₁ = ℓ} (_∘′ Productₗ)monadT M = record{ lift = (ε ,_) <$>_; rawMonad = mkRawMonad _(pure ∘′ (ε ,_))(λ ma f → ma >>= uncurry λ a x → map₁ (a ∙_) <$> f x)} where open RawMonad M-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {F} (App : RawApplicative {a ⊔ b} {a ⊔ b} F) whereopen RawApplicative AppsequenceA : ∀ {A} → Productₗ (F A) → F (Productₗ A)sequenceA (x , fa) = (x ,_) <$> famapA : ∀ {A B} → (A → F B) → Productₗ A → F (Productₗ B)mapA f = sequenceA ∘ map₂ fforA : ∀ {A B} → Productₗ A → (A → F B) → F (Productₗ B)forA = flip mapAmodule TraversableM {M} (Mon : RawMonad {a ⊔ b} {a ⊔ b} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- Base definitions for the left-biased universe-sensitive functor and-- monad instances for the Product type.---- To minimize the universe level of the RawFunctor, we require that-- elements of B are "lifted" to a copy of B at a higher universe level-- (a ⊔ b). See the Data.Product.Effectful.Examples for how this is-- done.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Data.Product.Effectful.Left.Base{a} (A : Set a) (b : Level) whereopen import Data.Product.Base using (_×_; map₂; proj₁; proj₂; <_,_>)open import Effect.Functor using (RawFunctor)open import Effect.Comonad using (RawComonad)-------------------------------------------------------------------------- DefinitionsProductₗ : Set (a ⊔ b) → Set (a ⊔ b)Productₗ B = A × Bfunctor : RawFunctor Productₗfunctor = record { _<$>_ = λ f → map₂ f }comonad : RawComonad Productₗcomonad = record{ extract = proj₂; extend = < proj₁ ,_>}
-------------------------------------------------------------------------- The Agda standard library---- Universe-sensitive functor and monad instances for the Product type.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Data.Product.Effectful.Examples{a e b} {A : Monoid a e} {B : Set b} whereopen import Level using (Lift; lift; _⊔_)open import Effect.Functor using (RawFunctor)open import Effect.Monad using (RawMonad)open import Data.Product.Base using (_×_; _,_)open import Data.Product.Relation.Binary.Pointwise.NonDependentopen import Function.Base using (id)import Function.Identity.Effectful as Idopen import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)-------------------------------------------------------------------------- Examples-- Note that these examples are simple unit tests, because the type-- checker verifies them.privatemodule A = Monoid Aopen import Data.Product.Effectful.Left A.rawMonoid b_≈_ : Rel (A.Carrier × Lift a B) (e ⊔ a ⊔ b)_≈_ = Pointwise A._≈_ _≡_open RawFunctor functor-- This type to the right of × needs to be a "lifted" version of-- (B : Set b) that lives in the universe (Set (a ⊔ b)).fmapIdₗ : (x : A.Carrier × Lift a B) → (id <$> x) ≈ xfmapIdₗ x = A.refl , reflopen RawMonad monad-- Now, let's show that "pure" is a unit for >>=. We use Lift in-- exactly the same way as above. The data (x : B) then needs to be-- "lifted" to this new type (Lift B).pureUnitL : ∀ {x : B} {f : Lift a B → A.Carrier × Lift a B} →(pure (lift x) >>= f) ≈ f (lift x)pureUnitL = A.identityˡ _ , reflpureUnitR : {x : A.Carrier × Lift a B} → (x >>= pure) ≈ xpureUnitR = A.identityʳ _ , refl-- And another (limited version of a) monad law...bindCompose : ∀ {f g : Lift a B → A.Carrier × Lift a B} →{x : A.Carrier × Lift a B} →((x >>= f) >>= g) ≈ (x >>= (λ y → (f y >>= g)))bindCompose = A.assoc _ _ _ , refl
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Product.Categorical.Right` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Categorical.Right whereopen import Data.Product.Effectful.Right public{-# WARNING_ON_IMPORT"Data.Product.Categorical.Right was deprecated in v2.0.Use Data.Product.Effectful.Right instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Product.Categorical.Right.Base` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Categorical.Right.Base whereopen import Data.Product.Effectful.Right.Base public{-# WARNING_ON_IMPORT"Data.Product.Categorical.Right.Base was deprecated in v2.0.Use Data.Product.Effectful.Right.Base instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Product.Categorical.Left` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Categorical.Left whereopen import Data.Product.Effectful.Left public{-# WARNING_ON_IMPORT"Data.Product.Categorical.Left was deprecated in v2.0.Use Data.Product.Effectful.Left instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Product.Categorical.Left.Base` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Categorical.Left.Base whereopen import Data.Product.Effectful.Left.Base public{-# WARNING_ON_IMPORT"Data.Product.Categorical.Left.Base was deprecated in v2.0.Use Data.Product.Effectful.Left.Base instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Product.Categorical.Examples` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Categorical.Examples whereopen import Data.Product.Effectful.Examples public{-# WARNING_ON_IMPORT"Data.Product.Categorical.Examples was deprecated in v2.0.Use Data.Product.Effectful.Examples instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Base whereopen import Function.Baseopen import Level using (Level; _⊔_)privatevariablea b c d e f ℓ p q r : LevelA : Set aB : Set bC : Set cD : Set dE : Set eF : Set f-------------------------------------------------------------------------- Definition of dependent productsopen import Agda.Builtin.Sigma publicrenaming (fst to proj₁; snd to proj₂)hiding (module Σ)module Σ = Agda.Builtin.Sigma.Σrenaming (fst to proj₁; snd to proj₂)-------------------------------------------------------------------------- Existential quantifiers∃ : ∀ {A : Set a} → (A → Set b) → Set (a ⊔ b)∃ = Σ _∃₂ : ∀ {A : Set a} {B : A → Set b}(C : (x : A) → B x → Set c) → Set (a ⊔ b ⊔ c)∃₂ C = ∃ λ a → ∃ λ b → C a b-------------------------------------------------------------------------- Syntaxes-- The syntax declaration below is attached to Σ-syntax, to make it-- easy to import Σ without the special syntax.infix 2 Σ-syntaxΣ-syntax : (A : Set a) → (A → Set b) → Set (a ⊔ b)Σ-syntax = Σsyntax Σ-syntax A (λ x → B) = Σ[ x ∈ A ] Binfix 2 ∃-syntax∃-syntax : ∀ {A : Set a} → (A → Set b) → Set (a ⊔ b)∃-syntax = ∃syntax ∃-syntax (λ x → B) = ∃[ x ] B-------------------------------------------------------------------------- Definition of non-dependent productsinfixr 4 _,′_infixr 2 _×__×_ : ∀ (A : Set a) (B : Set b) → Set (a ⊔ b)A × B = Σ[ x ∈ A ] B_,′_ : A → B → A × B_,′_ = _,_-------------------------------------------------------------------------- Operations over dependent productsinfix 4 -,_infixr 2 _-×-_ _-,-_infixl 2 _<*>_-- Sometimes the first component can be inferred.-,_ : ∀ {A : Set a} {B : A → Set b} {x} → B x → Σ _ B-, y = _ , y<_,_> : ∀ {A : Set a} {B : A → Set b} {C : ∀ {x} → B x → Set c}(f : (x : A) → B x) → ((x : A) → C (f x)) →((x : A) → Σ (B x) C)< f , g > x = (f x , g x)map : ∀ {P : A → Set p} {Q : B → Set q} →(f : A → B) → (∀ {x} → P x → Q (f x)) →Σ A P → Σ B Qmap f g (x , y) = (f x , g y)map₁ : (A → B) → A × C → B × Cmap₁ f = map f idmap₂ : ∀ {A : Set a} {B : A → Set b} {C : A → Set c} →(∀ {x} → B x → C x) → Σ A B → Σ A Cmap₂ f = map id f-- A version of map where the output can depend on the inputdmap : ∀ {B : A → Set b} {P : A → Set p} {Q : ∀ {a} → P a → B a → Set q} →(f : (a : A) → B a) → (∀ {a} (b : P a) → Q b (f a)) →((a , b) : Σ A P) → Σ (B a) (Q b)dmap f g (x , y) = f x , g yzip : ∀ {P : A → Set p} {Q : B → Set q} {R : C → Set r} →(_∙_ : A → B → C) →(∀ {x y} → P x → Q y → R (x ∙ y)) →Σ A P → Σ B Q → Σ C Rzip _∙_ _∘_ (a , p) (b , q) = ((a ∙ b) , (p ∘ q))curry : ∀ {A : Set a} {B : A → Set b} {C : Σ A B → Set c} →((p : Σ A B) → C p) →((x : A) → (y : B x) → C (x , y))curry f x y = f (x , y)uncurry : ∀ {A : Set a} {B : A → Set b} {C : Σ A B → Set c} →((x : A) → (y : B x) → C (x , y)) →((p : Σ A B) → C p)uncurry f (x , y) = f x y-- Rewriting dependent productsassocʳ : {B : A → Set b} {C : (a : A) → B a → Set c} →Σ (Σ A B) (uncurry C) → Σ A (λ a → Σ (B a) (C a))assocʳ ((a , b) , c) = (a , (b , c))assocˡ : {B : A → Set b} {C : (a : A) → B a → Set c} →Σ A (λ a → Σ (B a) (C a)) → Σ (Σ A B) (uncurry C)assocˡ (a , (b , c)) = ((a , b) , c)-- Alternate form of associativity for dependent products-- where the C parameter is uncurried.assocʳ-curried : {B : A → Set b} {C : Σ A B → Set c} →Σ (Σ A B) C → Σ A (λ a → Σ (B a) (curry C a))assocʳ-curried ((a , b) , c) = (a , (b , c))assocˡ-curried : {B : A → Set b} {C : Σ A B → Set c} →Σ A (λ a → Σ (B a) (curry C a)) → Σ (Σ A B) Cassocˡ-curried (a , (b , c)) = ((a , b) , c)-------------------------------------------------------------------------- Operations for non-dependent products-- Any of the above operations for dependent products will also work for-- non-dependent products but sometimes Agda has difficulty inferring-- the non-dependency. Primed (′ = \prime) versions of the operations-- are therefore provided below that sometimes have better inference-- properties.zip′ : (A → B → C) → (D → E → F) → A × D → B × E → C × Fzip′ f g = zip f gcurry′ : (A × B → C) → (A → B → C)curry′ = curryuncurry′ : (A → B → C) → (A × B → C)uncurry′ = uncurrymap₂′ : (B → C) → A × B → A × Cmap₂′ f = map₂ fdmap′ : ∀ {x y} {X : A → Set x} {Y : B → Set y} →((a : A) → X a) → ((b : B) → Y b) →((a , b) : A × B) → X a × Y bdmap′ f g = dmap f g_<*>_ : ∀ {x y} {X : A → Set x} {Y : B → Set y} →((a : A) → X a) × ((b : B) → Y b) →((a , b) : A × B) → X a × Y b_<*>_ = uncurry dmap′-- Operations that can only be defined for non-dependent productsswap : A × B → B × Aswap (x , y) = (y , x)_-×-_ : (A → B → Set p) → (A → B → Set q) → (A → B → Set _)f -×- g = f -⟪ _×_ ⟫- g_-,-_ : (A → B → C) → (A → B → D) → (A → B → C × D)f -,- g = f -⟪ _,_ ⟫- g-- Rewriting non-dependent productsassocʳ′ : (A × B) × C → A × (B × C)assocʳ′ ((a , b) , c) = (a , (b , c))assocˡ′ : A × (B × C) → (A × B) × Cassocˡ′ (a , (b , c)) = ((a , b) , c)
-------------------------------------------------------------------------- The Agda standard library---- Algebraic properties of products------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Product.Algebra whereopen import Algebraopen import Data.Bool.Base using (true; false)open import Data.Empty.Polymorphic using (⊥; ⊥-elim)open import Data.Product.Baseopen import Data.Product.Propertiesopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Sum.Algebraopen import Data.Unit.Polymorphic using (⊤; tt)open import Function.Base using (_∘′_)open import Function.Bundles using (_↔_; Inverse; mk↔ₛ′)open import Function.Properties.Inverse using (↔-isEquivalence)open import Level using (Level; suc)open import Relation.Binary.PropositionalEquality.Coreimport Function.Definitions as FuncDef------------------------------------------------------------------------privatevariablea b c d p : LevelA B C D : Set a-------------------------------------------------------------------------- Properties of Σ-- Σ is associativeΣ-assoc : {B : A → Set b} {C : (a : A) → B a → Set c} →Σ (Σ A B) (uncurry C) ↔ Σ A (λ a → Σ (B a) (C a))Σ-assoc = mk↔ₛ′ assocʳ assocˡ cong′ cong′-- Σ is associative, alternate formulationΣ-assoc-alt : {B : A → Set b} {C : Σ A B → Set c} →Σ (Σ A B) C ↔ Σ A (λ a → Σ (B a) (curry C a))Σ-assoc-alt = mk↔ₛ′ assocʳ-curried assocˡ-curried cong′ cong′-------------------------------------------------------------------------- Algebraic properties-- × is a congruence×-cong : A ↔ B → C ↔ D → (A × C) ↔ (B × D)×-cong i j = mk↔ₛ′ (map I.to J.to) (map I.from J.from)(λ {(a , b) → cong₂ _,_ (I.strictlyInverseˡ a) (J.strictlyInverseˡ b)})(λ {(a , b) → cong₂ _,_ (I.strictlyInverseʳ a) (J.strictlyInverseʳ b)})where module I = Inverse i; module J = Inverse j-- × is commutative.-- (we don't use Commutative because it isn't polymorphic enough)×-comm : (A : Set a) (B : Set b) → (A × B) ↔ (B × A)×-comm _ _ = mk↔ₛ′ swap swap swap-involutive swap-involutivemodule _ (ℓ : Level) where-- × is associative×-assoc : Associative {ℓ = ℓ} _↔_ _×_×-assoc _ _ _ = mk↔ₛ′ assocʳ′ assocˡ′ cong′ cong′-- ⊤ is the identity for ××-identityˡ : LeftIdentity {ℓ = ℓ} _↔_ ⊤ _×_×-identityˡ _ = mk↔ₛ′ proj₂ (tt ,_) cong′ cong′×-identityʳ : RightIdentity {ℓ = ℓ} _↔_ ⊤ _×_×-identityʳ _ = mk↔ₛ′ proj₁ (_, tt) cong′ cong′×-identity : Identity _↔_ ⊤ _×_×-identity = ×-identityˡ , ×-identityʳ-- ⊥ is the zero for ××-zeroˡ : LeftZero {ℓ = ℓ} _↔_ ⊥ _×_×-zeroˡ A = mk↔ₛ′ proj₁ ⊥-elim ⊥-elim λ ()×-zeroʳ : RightZero {ℓ = ℓ} _↔_ ⊥ _×_×-zeroʳ A = mk↔ₛ′ proj₂ ⊥-elim ⊥-elim λ ()×-zero : Zero _↔_ ⊥ _×_×-zero = ×-zeroˡ , ×-zeroʳ-- × distributes over ⊎×-distribˡ-⊎ : _DistributesOverˡ_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distribˡ-⊎ _ _ _ = mk↔ₛ′(uncurry λ x → [ inj₁ ∘′ (x ,_) , inj₂ ∘′ (x ,_) ]′)[ map₂ inj₁ , map₂ inj₂ ]′Sum.[ cong′ , cong′ ](uncurry λ _ → Sum.[ cong′ , cong′ ])×-distribʳ-⊎ : _DistributesOverʳ_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distribʳ-⊎ _ _ _ = mk↔ₛ′(uncurry [ curry inj₁ , curry inj₂ ]′)[ map₁ inj₁ , map₁ inj₂ ]′Sum.[ cong′ , cong′ ](uncurry Sum.[ (λ _ → cong′) , (λ _ → cong′) ])×-distrib-⊎ : _DistributesOver_ {ℓ = ℓ} _↔_ _×_ _⊎_×-distrib-⊎ = ×-distribˡ-⊎ , ×-distribʳ-⊎-------------------------------------------------------------------------- Algebraic structures×-isMagma : IsMagma {ℓ = ℓ} _↔_ _×_×-isMagma = record{ isEquivalence = ↔-isEquivalence; ∙-cong = ×-cong}×-isSemigroup : IsSemigroup _↔_ _×_×-isSemigroup = record{ isMagma = ×-isMagma; assoc = λ _ _ _ → Σ-assoc}×-isMonoid : IsMonoid _↔_ _×_ ⊤×-isMonoid = record{ isSemigroup = ×-isSemigroup; identity = ×-identityˡ , ×-identityʳ}×-isCommutativeMonoid : IsCommutativeMonoid _↔_ _×_ ⊤×-isCommutativeMonoid = record{ isMonoid = ×-isMonoid; comm = ×-comm}⊎-×-isSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero _↔_ _⊎_ _×_ ⊥ ⊤⊎-×-isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ⊎-isCommutativeMonoid ℓ; *-cong = ×-cong; *-assoc = ×-assoc; *-identity = ×-identity; distrib = ×-distrib-⊎}⊎-×-isSemiring : IsSemiring _↔_ _⊎_ _×_ ⊥ ⊤⊎-×-isSemiring = record{ isSemiringWithoutAnnihilatingZero = ⊎-×-isSemiringWithoutAnnihilatingZero; zero = ×-zero}⊎-×-isCommutativeSemiring : IsCommutativeSemiring _↔_ _⊎_ _×_ ⊥ ⊤⊎-×-isCommutativeSemiring = record{ isSemiring = ⊎-×-isSemiring; *-comm = ×-comm}-------------------------------------------------------------------------- Algebraic bundles×-magma : Magma (suc ℓ) ℓ×-magma = record{ isMagma = ×-isMagma}×-semigroup : Semigroup (suc ℓ) ℓ×-semigroup = record{ isSemigroup = ×-isSemigroup}×-monoid : Monoid (suc ℓ) ℓ×-monoid = record{ isMonoid = ×-isMonoid}×-commutativeMonoid : CommutativeMonoid (suc ℓ) ℓ×-commutativeMonoid = record{ isCommutativeMonoid = ×-isCommutativeMonoid}×-⊎-commutativeSemiring : CommutativeSemiring (suc ℓ) ℓ×-⊎-commutativeSemiring = record{ isCommutativeSemiring = ⊎-×-isCommutativeSemiring}
-------------------------------------------------------------------------- The Agda standard library---- Parity------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Parity where-------------------------------------------------------------------------- Definitionopen import Data.Parity.Base publicopen import Data.Parity.Properties publicusing (_≟_)
-------------------------------------------------------------------------- The Agda standard library---- Some properties about parities------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Parity.Properties whereopen import Algebra.Bundlesopen import Data.Nat.Base as ℕ using (zero; suc; parity)open import Data.Parity.Base as ℙ using (Parity; 0ℙ; 1ℙ; _⁻¹; toSign; fromSign)open import Data.Product.Base using (_,_)import Data.Sign.Base as 𝕊open import Function.Base using (_$_; id)open import Function.Definitionsopen import Function.Consequences.Propositionalusing (inverseʳ⇒injective; inverseˡ⇒surjective)open import Level using (0ℓ)open import Relation.Binaryusing (Decidable; DecidableEquality; Setoid; DecSetoid; IsDecEquivalence)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; sym; cong; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning; setoid; isEquivalence; decSetoid; isDecEquivalence)open import Relation.Nullary using (yes; no)open import Relation.Nullary.Negation.Core using (contradiction)open import Algebra.Structures {A = Parity} _≡_open import Algebra.Definitions {A = Parity} _≡_open import Algebra.Consequences.Propositionalusing (selfInverse⇒involutive; selfInverse⇒injective; comm∧distrˡ⇒distrʳ)open import Algebra.Morphism.Structures-------------------------------------------------------------------------- Equalityinfix 4 _≟__≟_ : DecidableEquality Parity1ℙ ≟ 1ℙ = yes refl1ℙ ≟ 0ℙ = no λ()0ℙ ≟ 1ℙ = no λ()0ℙ ≟ 0ℙ = yes refl≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid Parity≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_≡-isDecEquivalence : IsDecEquivalence _≡_≡-isDecEquivalence = isDecEquivalence _≟_-------------------------------------------------------------------------- _⁻¹-- Algebraic properties of _⁻¹⁻¹-selfInverse : SelfInverse _⁻¹⁻¹-selfInverse { 1ℙ } { 0ℙ } refl = refl⁻¹-selfInverse { 0ℙ } { 1ℙ } refl = refl⁻¹-involutive : Involutive _⁻¹⁻¹-involutive = selfInverse⇒involutive ⁻¹-selfInverse⁻¹-injective : Injective _≡_ _≡_ _⁻¹⁻¹-injective = selfInverse⇒injective ⁻¹-selfInverse-------------------------------------------------------------------------- other properties of _⁻¹p≢p⁻¹ : ∀ p → p ≢ p ⁻¹p≢p⁻¹ 1ℙ ()p≢p⁻¹ 0ℙ ()-------------------------------------------------------------------------- ⁻¹ and _+_p+p⁻¹≡1ℙ : ∀ p → p ℙ.+ p ⁻¹ ≡ 1ℙp+p⁻¹≡1ℙ 0ℙ = reflp+p⁻¹≡1ℙ 1ℙ = reflp⁻¹+p≡1ℙ : ∀ p → p ⁻¹ ℙ.+ p ≡ 1ℙp⁻¹+p≡1ℙ 0ℙ = reflp⁻¹+p≡1ℙ 1ℙ = refl-------------------------------------------------------------------------- ⁻¹ and _*_p*p⁻¹≡0ℙ : ∀ p → p ℙ.* p ⁻¹ ≡ 0ℙp*p⁻¹≡0ℙ 0ℙ = reflp*p⁻¹≡0ℙ 1ℙ = reflp⁻¹*p≡0ℙ : ∀ p → p ⁻¹ ℙ.* p ≡ 0ℙp⁻¹*p≡0ℙ 0ℙ = reflp⁻¹*p≡0ℙ 1ℙ = refl-------------------------------------------------------------------------- _+_-- Algebraic properties of _+_p+p≡0ℙ : ∀ p → p ℙ.+ p ≡ 0ℙp+p≡0ℙ 0ℙ = reflp+p≡0ℙ 1ℙ = refl+-identityˡ : LeftIdentity 0ℙ ℙ._+_+-identityˡ _ = refl+-identityʳ : RightIdentity 0ℙ ℙ._+_+-identityʳ 1ℙ = refl+-identityʳ 0ℙ = refl+-identity : Identity 0ℙ ℙ._+_+-identity = +-identityˡ , +-identityʳ+-comm : Commutative ℙ._+_+-comm 0ℙ 0ℙ = refl+-comm 0ℙ 1ℙ = refl+-comm 1ℙ 0ℙ = refl+-comm 1ℙ 1ℙ = refl+-assoc : Associative ℙ._+_+-assoc 0ℙ 0ℙ _ = refl+-assoc 0ℙ 1ℙ _ = refl+-assoc 1ℙ 0ℙ _ = refl+-assoc 1ℙ 1ℙ 0ℙ = refl+-assoc 1ℙ 1ℙ 1ℙ = refl+-cancelʳ-≡ : RightCancellative ℙ._+_+-cancelʳ-≡ _ 1ℙ 1ℙ _ = refl+-cancelʳ-≡ _ 1ℙ 0ℙ eq = contradiction (sym eq) (p≢p⁻¹ _)+-cancelʳ-≡ _ 0ℙ 1ℙ eq = contradiction eq (p≢p⁻¹ _)+-cancelʳ-≡ _ 0ℙ 0ℙ _ = refl+-cancelˡ-≡ : LeftCancellative ℙ._+_+-cancelˡ-≡ 1ℙ _ _ eq = ⁻¹-injective eq+-cancelˡ-≡ 0ℙ _ _ eq = eq+-cancel-≡ : Cancellative ℙ._+_+-cancel-≡ = +-cancelˡ-≡ , +-cancelʳ-≡+-inverse : Inverse 0ℙ id ℙ._+_+-inverse = p+p≡0ℙ , p+p≡0ℙ-------------------------------------------------------------------------- Bundles+-isMagma : IsMagma ℙ._+_+-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ ℙ._+_}+-magma : Magma 0ℓ 0ℓ+-magma = record{ isMagma = +-isMagma}+-isSemigroup : IsSemigroup ℙ._+_+-isSemigroup = record{ isMagma = +-isMagma; assoc = +-assoc}+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-isCommutativeSemigroup : IsCommutativeSemigroup ℙ._+_+-isCommutativeSemigroup = record{ isSemigroup = +-isSemigroup; comm = +-comm}+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ+-commutativeSemigroup = record{ isCommutativeSemigroup = +-isCommutativeSemigroup}+-0-isMonoid : IsMonoid ℙ._+_ 0ℙ+-0-isMonoid = record{ isSemigroup = +-isSemigroup; identity = +-identity}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ isMonoid = +-0-isMonoid}+-0-isCommutativeMonoid : IsCommutativeMonoid ℙ._+_ 0ℙ+-0-isCommutativeMonoid = record{ isMonoid = +-0-isMonoid; comm = +-comm}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}+-0-isGroup : IsGroup ℙ._+_ 0ℙ id+-0-isGroup = record{ isMonoid = +-0-isMonoid; inverse = +-inverse; ⁻¹-cong = id}+-0-group : Group 0ℓ 0ℓ+-0-group = record{ isGroup = +-0-isGroup}+-0-isAbelianGroup : IsAbelianGroup ℙ._+_ 0ℙ id+-0-isAbelianGroup = record{ isGroup = +-0-isGroup; comm = +-comm}+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ+-0-abelianGroup = record{ isAbelianGroup = +-0-isAbelianGroup}-------------------------------------------------------------------------- _*_-- Algebraic properties of _*_*-idem : Idempotent ℙ._*_*-idem 0ℙ = refl*-idem 1ℙ = refl*-comm : Commutative ℙ._*_*-comm 0ℙ 0ℙ = refl*-comm 0ℙ 1ℙ = refl*-comm 1ℙ 0ℙ = refl*-comm 1ℙ 1ℙ = refl*-assoc : Associative ℙ._*_*-assoc 0ℙ 0ℙ _ = refl*-assoc 0ℙ 1ℙ _ = refl*-assoc 1ℙ 0ℙ _ = refl*-assoc 1ℙ 1ℙ 0ℙ = refl*-assoc 1ℙ 1ℙ 1ℙ = refl*-distribˡ-+ : ℙ._*_ DistributesOverˡ ℙ._+_*-distribˡ-+ 0ℙ q r = refl*-distribˡ-+ 1ℙ 0ℙ 0ℙ = refl*-distribˡ-+ 1ℙ 0ℙ 1ℙ = refl*-distribˡ-+ 1ℙ 1ℙ 0ℙ = refl*-distribˡ-+ 1ℙ 1ℙ 1ℙ = refl*-distribʳ-+ : ℙ._*_ DistributesOverʳ ℙ._+_*-distribʳ-+ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-+*-distrib-+ : ℙ._*_ DistributesOver ℙ._+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+*-zeroˡ : LeftZero 0ℙ ℙ._*_*-zeroˡ p = refl*-zeroʳ : RightZero 0ℙ ℙ._*_*-zeroʳ p = *-comm p 0ℙ*-zero : Zero 0ℙ ℙ._*_*-zero = *-zeroˡ , *-zeroʳ*-identityˡ : LeftIdentity 1ℙ ℙ._*_*-identityˡ _ = refl*-identityʳ : RightIdentity 1ℙ ℙ._*_*-identityʳ 1ℙ = refl*-identityʳ 0ℙ = refl*-identity : Identity 1ℙ ℙ._*_*-identity = *-identityˡ , *-identityʳ-------------------------------------------------------------------------- Structures and Bundles*-isMagma : IsMagma ℙ._*_*-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ ℙ._*_}*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-isSemigroup : IsSemigroup ℙ._*_*-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-isCommutativeSemigroup : IsCommutativeSemigroup ℙ._*_*-isCommutativeSemigroup = record{ isSemigroup = *-isSemigroup; comm = *-comm}*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeSemigroup = record{ isCommutativeSemigroup = *-isCommutativeSemigroup}*-1-isMonoid : IsMonoid ℙ._*_ 1ℙ*-1-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-isCommutativeMonoid : IsCommutativeMonoid ℙ._*_ 1ℙ*-1-isCommutativeMonoid = record{ isMonoid = *-1-isMonoid; comm = *-comm}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-isSemiring : IsSemiring ℙ._+_ ℙ._*_ 0ℙ 1ℙ+-*-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-0-isCommutativeMonoid; *-cong = cong₂ ℙ._*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}; zero = *-zero}+-*-semiring : Semiring 0ℓ 0ℓ+-*-semiring = record{ isSemiring = +-*-isSemiring}+-*-isCommutativeSemiring : IsCommutativeSemiring ℙ._+_ ℙ._*_ 0ℙ 1ℙ+-*-isCommutativeSemiring = record{ isSemiring = +-*-isSemiring; *-comm = *-comm}+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ+-*-commutativeSemiring = record{ isCommutativeSemiring = +-*-isCommutativeSemiring}+-*-isRing : IsRing ℙ._+_ ℙ._*_ id 0ℙ 1ℙ+-*-isRing = record{ +-isAbelianGroup = +-0-isAbelianGroup; *-cong = cong₂ ℙ._*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}+-*-ring : Ring 0ℓ 0ℓ+-*-ring = record{ isRing = +-*-isRing}+-*-isCommutativeRing : IsCommutativeRing ℙ._+_ ℙ._*_ id 0ℙ 1ℙ+-*-isCommutativeRing = record{ isRing = +-*-isRing; *-comm = *-comm}+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ+-*-commutativeRing = record{ isCommutativeRing = +-*-isCommutativeRing}-------------------------------------------------------------------------- relating Parity and Sign+-homo-* : ∀ p q → toSign (p ℙ.+ q) ≡ (toSign p) 𝕊.* (toSign q)+-homo-* 0ℙ 0ℙ = refl+-homo-* 0ℙ 1ℙ = refl+-homo-* 1ℙ 0ℙ = refl+-homo-* 1ℙ 1ℙ = refl⁻¹-homo-opposite : ∀ p → toSign (p ⁻¹) ≡ 𝕊.opposite (toSign p)⁻¹-homo-opposite 0ℙ = refl⁻¹-homo-opposite 1ℙ = refltoSign-inverseʳ : Inverseʳ _≡_ _≡_ toSign fromSigntoSign-inverseʳ {0ℙ} refl = refltoSign-inverseʳ {1ℙ} refl = refltoSign-inverseˡ : Inverseˡ _≡_ _≡_ toSign fromSigntoSign-inverseˡ { 𝕊.+ } refl = refltoSign-inverseˡ { 𝕊.- } refl = refltoSign-injective : Injective _≡_ _≡_ toSigntoSign-injective = inverseʳ⇒injective toSign toSign-inverseʳtoSign-surjective : Surjective _≡_ _≡_ toSigntoSign-surjective = inverseˡ⇒surjective toSign-inverseˡtoSign-isMagmaHomomorphism : IsMagmaHomomorphism ℙ.+-rawMagma 𝕊.*-rawMagma toSigntoSign-isMagmaHomomorphism = record{ isRelHomomorphism = record{ cong = cong toSign }; homo = +-homo-*}toSign-isMagmaMonomorphism : IsMagmaMonomorphism ℙ.+-rawMagma 𝕊.*-rawMagma toSigntoSign-isMagmaMonomorphism = record{ isMagmaHomomorphism = toSign-isMagmaHomomorphism; injective = toSign-injective}toSign-isMagmaIsomorphism : IsMagmaIsomorphism ℙ.+-rawMagma 𝕊.*-rawMagma toSigntoSign-isMagmaIsomorphism = record{ isMagmaMonomorphism = toSign-isMagmaMonomorphism; surjective = toSign-surjective}toSign-isMonoidHomomorphism : IsMonoidHomomorphism ℙ.+-0-rawMonoid 𝕊.*-1-rawMonoid toSigntoSign-isMonoidHomomorphism = record{ isMagmaHomomorphism = toSign-isMagmaHomomorphism; ε-homo = refl}toSign-isMonoidMonomorphism : IsMonoidMonomorphism ℙ.+-0-rawMonoid 𝕊.*-1-rawMonoid toSigntoSign-isMonoidMonomorphism = record{ isMonoidHomomorphism = toSign-isMonoidHomomorphism; injective = toSign-injective}toSign-isMonoidIsomorphism : IsMonoidIsomorphism ℙ.+-0-rawMonoid 𝕊.*-1-rawMonoid toSigntoSign-isMonoidIsomorphism = record{ isMonoidMonomorphism = toSign-isMonoidMonomorphism; surjective = toSign-surjective}toSign-isGroupHomomorphism : IsGroupHomomorphism ℙ.+-0-rawGroup 𝕊.*-1-rawGroup toSigntoSign-isGroupHomomorphism = record{ isMonoidHomomorphism = toSign-isMonoidHomomorphism; ⁻¹-homo = ⁻¹-homo-opposite}toSign-isGroupMonomorphism : IsGroupMonomorphism ℙ.+-0-rawGroup 𝕊.*-1-rawGroup toSigntoSign-isGroupMonomorphism = record{ isGroupHomomorphism = toSign-isGroupHomomorphism; injective = toSign-injective}toSign-isGroupIsomorphism : IsGroupIsomorphism ℙ.+-0-rawGroup 𝕊.*-1-rawGroup toSigntoSign-isGroupIsomorphism = record{ isGroupMonomorphism = toSign-isGroupMonomorphism; surjective = toSign-surjective}-------------------------------------------------------------------------- Relating Nat and Parity-- successor and (_⁻¹)suc-homo-⁻¹ : ∀ n → (parity (suc n)) ⁻¹ ≡ parity nsuc-homo-⁻¹ zero = reflsuc-homo-⁻¹ (suc n) = ⁻¹-selfInverse (suc-homo-⁻¹ n)-- parity is a _+_ homomorphism+-homo-+ : ∀ m n → parity (m ℕ.+ n) ≡ parity m ℙ.+ parity n+-homo-+ zero n = refl+-homo-+ (suc m) n = beginparity (suc m ℕ.+ n) ≡⟨ suc-+-homo-⁻¹ m n ⟩(parity m) ⁻¹ ℙ.+ parity n ≡⟨ cong (ℙ._+ parity n) (suc-homo-⁻¹ (suc m)) ⟩parity (suc m) ℙ.+ parity n ∎whereopen ≡-Reasoningsuc-+-homo-⁻¹ : ∀ m n → parity (suc m ℕ.+ n) ≡ (parity m) ⁻¹ ℙ.+ parity nsuc-+-homo-⁻¹ zero n = sym (suc-homo-⁻¹ (suc n))suc-+-homo-⁻¹ (suc m) n = beginparity (suc (suc m) ℕ.+ n) ≡⟨⟩parity (m ℕ.+ n) ≡⟨ +-homo-+ m n ⟩parity m ℙ.+ parity n ≡⟨ cong (ℙ._+ parity n) (sym (suc-homo-⁻¹ m)) ⟩(parity (suc m)) ⁻¹ ℙ.+ parity n ∎-- parity is a _*_ homomorphism*-homo-* : ∀ m n → parity (m ℕ.* n) ≡ parity m ℙ.* parity n*-homo-* zero n = refl*-homo-* (suc m) n = beginparity (suc m ℕ.* n) ≡⟨⟩parity (n ℕ.+ m ℕ.* n) ≡⟨ +-homo-+ n (m ℕ.* n) ⟩q ℙ.+ parity (m ℕ.* n) ≡⟨ cong (q ℙ.+_) (*-homo-* m n) ⟩q ℙ.+ (p ℙ.* q) ≡⟨ lemma p q ⟩(p ⁻¹) ℙ.* q ≡⟨⟩(parity m) ⁻¹ ℙ.* q ≡⟨ cong (ℙ._* q) (suc-homo-⁻¹ (suc m)) ⟩parity (suc m) ℙ.* q ≡⟨⟩parity (suc m) ℙ.* parity n ∎whereopen ≡-Reasoningp = parity mq = parity n-- this lemma simplifies things a lotlemma : ∀ p q → q ℙ.+ (p ℙ.* q) ≡ (p ⁻¹) ℙ.* qlemma 0ℙ 0ℙ = refllemma 0ℙ 1ℙ = refllemma 1ℙ 0ℙ = refllemma 1ℙ 1ℙ = refl-------------------------------------------------------------------------- parity is a Semiring homomorphism from Nat to Parityparity-isMagmaHomomorphism : IsMagmaHomomorphism ℕ.+-rawMagma ℙ.+-rawMagma parityparity-isMagmaHomomorphism = record{ isRelHomomorphism = record{ cong = cong parity }; homo = +-homo-+}parity-isMonoidHomomorphism : IsMonoidHomomorphism ℕ.+-0-rawMonoid ℙ.+-0-rawMonoid parityparity-isMonoidHomomorphism = record{ isMagmaHomomorphism = parity-isMagmaHomomorphism; ε-homo = refl}parity-isNearSemiringHomomorphism : IsNearSemiringHomomorphism ℕ.+-*-rawNearSemiring ℙ.+-*-rawNearSemiring parityparity-isNearSemiringHomomorphism = record{ +-isMonoidHomomorphism = parity-isMonoidHomomorphism; *-homo = *-homo-*}parity-isSemiringHomomorphism : IsSemiringHomomorphism ℕ.+-*-rawSemiring ℙ.+-*-rawSemiring parityparity-isSemiringHomomorphism = record{ isNearSemiringHomomorphism = parity-isNearSemiringHomomorphism; 1#-homo = refl}
-------------------------------------------------------------------------- The Agda standard library---- Instances for parities------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Parity.Instances whereopen import Data.Parity.PropertiesinstanceParity-≡-isDecEquivalence = ≡-isDecEquivalence
-------------------------------------------------------------------------- The Agda standard library---- Parity------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Parity.Base whereopen import Algebra.Bundles.Rawusing (RawMagma; RawMonoid; RawGroup; RawNearSemiring; RawSemiring)open import Data.Sign.Base using (Sign; +; -)open import Level using (0ℓ)open import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Definitiondata Parity : Set where0ℙ : Parity1ℙ : Parity-------------------------------------------------------------------------- Operations-- The opposite parity.infix 8 _⁻¹_⁻¹ : Parity → Parity1ℙ ⁻¹ = 0ℙ0ℙ ⁻¹ = 1ℙ-- Addition.infixl 7 _+__+_ : Parity → Parity → Parity0ℙ + p = p1ℙ + p = p ⁻¹-- Multiplication.infixl 7 _*__*_ : Parity → Parity → Parity0ℙ * p = 0ℙ1ℙ * p = p-------------------------------------------------------------------------- Raw Bundles+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record{ _≈_ = _≡_; _∙_ = _+_}+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record{ _≈_ = _≡_; _∙_ = _+_; ε = 0ℙ}+-0-rawGroup : RawGroup 0ℓ 0ℓ+-0-rawGroup = record{ _≈_ = _≡_; _∙_ = _+_; _⁻¹ = _⁻¹; ε = 0ℙ}*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≡_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≡_; _∙_ = _*_; ε = 1ℙ}+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawNearSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℙ}+-*-rawSemiring : RawSemiring 0ℓ 0ℓ+-*-rawSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℙ; 1# = 1ℙ}-------------------------------------------------------------------------- Homomorphisms between Parity and SigntoSign : Parity → SigntoSign 0ℙ = +toSign 1ℙ = -fromSign : Sign → ParityfromSign + = 0ℙfromSign - = 1ℙ
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers-------------------------------------------------------------------------- See README.Data.Nat for examples of how to use and reason about-- naturals.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat where-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Data.Nat.Base public-------------------------------------------------------------------------- Publicly re-export queriesopen import Data.Nat.Properties publicusing-- key values( nonZero?-- equalities; _≟_ ; eq?-- standard orders & their relationship; _≤?_ ; _≥?_ ; _<?_ ; _>?_; ≤-<-connex ; ≥->-connex ; <-≤-connex ; >-≥-connex; <-cmp-- alternative definitions of the orders; _≤′?_; _≥′?_; _<′?_; _>′?_; _≤″?_; _<″?_; _≥″?_; _>″?_; _<‴?_; _≤‴?_; _≥‴?_; _>‴?_-- bounded predicates; anyUpTo? ; allUpTo?)-------------------------------------------------------------------------- Deprecated-- Version 0.17-- Version 2.0-- solely for the re-export of this name, formerly in `Data.Nat.Properties.Core`open import Data.Nat.Properties publicusing (≤-pred)
-------------------------------------------------------------------------- The Agda standard library---- Natural number types and operations requiring the axiom K.------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Nat.WithK whereopen import Algebra.Definitions.RawMagma using (_,_)open import Data.Nat.Baseopen import Relation.Binary.PropositionalEquality.WithK≤″-erase : ∀ {m n} → m ≤″ n → m ≤″ n≤″-erase (_ , eq) = _ , ≡-erase eq
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over naturals-------------------------------------------------------------------------- See README.Tactic.RingSolver for examples of how to use this solver{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Tactic.RingSolver whereopen import Agda.Builtin.Reflection using (Term; TC)open import Data.Maybe.Base using (just; nothing)open import Data.Nat.Base using (zero)open import Data.Nat.Properties using (+-*-commutativeSemiring)open import Level using (0ℓ)open import Data.Unit.Base using (⊤)open import Relation.Binary.PropositionalEquality.Core using (refl)import Tactic.RingSolver as Solverimport Tactic.RingSolver.Core.AlmostCommutativeRing as ACR-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_ring : ACR.AlmostCommutativeRing 0ℓ 0ℓring = ACR.fromCommutativeSemiring +-*-commutativeSemiringλ { zero → just refl; _ → nothing }macrosolve-∀ : Term → TC ⊤solve-∀ = Solver.solve-∀-macro (quote ring)macrosolve : Term → Term → TC ⊤solve n = Solver.solve-macro n (quote ring)
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over naturals-------------------------------------------------------------------------- See README.Data.Nat for examples of how to use this solver{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Solver whereimport Algebra.Solver.Ring.Simple as Solverimport Algebra.Solver.Ring.AlmostCommutativeRing as ACRopen import Data.Nat.Properties-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_module +-*-Solver =Solver (ACR.fromCommutativeSemiring +-*-commutativeSemiring) _≟_
-------------------------------------------------------------------------- The Agda standard library---- Showing natural numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Show whereopen import Data.Bool.Base using (_∧_)open import Data.Char.Base as Char using (Char)open import Data.Digit using (showDigit; toDigits; toNatDigits)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.Effectful using (module TraversableA)open import Data.Maybe.Base as Maybe using (Maybe; nothing; _<∣>_; when)import Data.Maybe.Effectful as Maybeopen import Data.Natopen import Data.Product.Base using (proj₁)open import Data.String.Base using (toList; fromList; String)open import Function.Base using (_∘′_; _∘_)open import Relation.Nullary.Decidable using (True)-------------------------------------------------------------------------- ReadreadMaybe : ∀ base {base≤16 : True (base ≤? 16)} → String → Maybe ℕreadMaybe _ "" = nothingreadMaybe base = Maybe.map convert∘′ TraversableA.mapA Maybe.applicative readDigit∘′ toListwhereconvert : List ℕ → ℕconvert = List.foldl (λ acc d → base * acc + d) 0char0 = Char.toℕ '0'char9 = Char.toℕ '9'chara = Char.toℕ 'a'charf = Char.toℕ 'f'readDigit : Char → Maybe ℕreadDigit c = digit Maybe.>>= λ n → when (n <ᵇ base) n wherecharc = Char.toℕ cdec = when ((char0 ≤ᵇ charc) ∧ (charc ≤ᵇ char9)) (charc ∸ char0)hex = when ((chara ≤ᵇ charc) ∧ (charc ≤ᵇ charf)) (10 + charc ∸ chara)digit = dec <∣> hex-------------------------------------------------------------------------- Show-- Decimal notation-- Time complexity is O(log₁₀(n))toDigitChar : ℕ → ChartoDigitChar n = Char.fromℕ (n + Char.toℕ '0')toDecimalChars : ℕ → List ChartoDecimalChars = List.map toDigitChar ∘′ toNatDigits 10show : ℕ → Stringshow = fromList ∘′ toDecimalChars-- Arbitrary base betwen 2 & 16.-- Warning: when compiled the time complexity of `showInBase b n` is-- O(n) instead of the expected O(log(n)).charsInBase : (base : ℕ){base≥2 : True (2 ≤? base)}{base≤16 : True (base ≤? 16)} →ℕ → List CharcharsInBase base {base≥2} {base≤16} = List.map (showDigit {base≤16 = base≤16})∘ List.reverse∘ proj₁∘ toDigits base {base≥2 = base≥2}showInBase : (base : ℕ){base≥2 : True (2 ≤? base)}{base≤16 : True (base ≤? 16)} →ℕ → StringshowInBase base {base≥2} {base≤16} = fromList∘ charsInBase base {base≥2} {base≤16}
-------------------------------------------------------------------------- The Agda standard library---- Properties of showing natural numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Digit.Properties using (toDigits-injective; showDigit-injective)import Data.List.Properties as Listₚopen import Data.Nat.Base using (ℕ)open import Data.Nat.Properties using (_≤?_)open import Data.Nat.Show using (charsInBase)open import Function.Base using (_∘_)open import Relation.Nullary.Decidable using (True)open import Relation.Binary.PropositionalEquality.Core using (_≡_)module Data.Nat.Show.Properties wheremodule _ (base : ℕ) {base≥2 : True (2 ≤? base)} {base≤16 : True (base ≤? 16)} whereprivatecharsInBase-base = charsInBase base {base≥2} {base≤16}toDigits-injective-base = toDigits-injective base {base≥2} {base≥2}showDigit-injective-base = showDigit-injective base {base≤16} {base≤16}charsInBase-injective : ∀ n m → charsInBase-base n ≡ charsInBase-base m → n ≡ mcharsInBase-injective n m = toDigits-injective-base _ _∘ Listₚ.reverse-injective∘ Listₚ.map-injective (showDigit-injective-base _ _)
-------------------------------------------------------------------------- The Agda standard library---- Reflection utilities for ℕ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Reflection whereopen import Data.Nat.Base as ℕimport Data.Fin.Base as Finopen import Data.List.Base using ([])open import Reflection.AST.Termopen import Reflection.AST.Argument-------------------------------------------------------------------------- Termpattern `ℕ = def (quote ℕ) []pattern `zero = con (quote zero) []pattern `suc x = con (quote suc) (x ⟨∷⟩ [])toTerm : ℕ → TermtoTerm zero = `zerotoTerm (suc i) = `suc (toTerm i)toFinTerm : ℕ → TermtoFinTerm zero = con (quote Fin.zero) (1 ⋯⟅∷⟆ [])toFinTerm (suc i) = con (quote Fin.suc) (1 ⋯⟅∷⟆ toFinTerm i ⟨∷⟩ [])
-------------------------------------------------------------------------- The Agda standard library---- Linear congruential pseudo random generators for natural numbers-- /!\ NB: LCGs must not be used for cryptographic applications------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.PseudoRandom.LCG whereopen import Data.Nat.Baseopen import Data.Nat.DivMod using (_%_)open import Data.List.Base using (List; []; _∷_)-------------------------------------------------------------------------- Type and generatorrecord Generator : Set wherefield multiplier : ℕincrement : ℕmodulus : ℕ.{{modulus≢0}} : NonZero modulusstep : Generator → ℕ → ℕstep gen x =let open Generator gen in((multiplier * x + increment) % modulus)list : ℕ → Generator → ℕ → List ℕlist zero gen x = []list (suc k) gen x = x ∷ list k gen (step gen x)-------------------------------------------------------------------------- Examples of parameters-- Taken from https://en.wikipedia.org/wiki/Linear_congruential_generator-- /!\ As explained in that wikipedia entry, none of these are claimed-- to be good parameters.-- Note also that if you need your output to have good properties you-- may need to postprocess the stream of values to only use some of the-- bits of the output!glibc : Generatorglibc = record{ multiplier = 1103515245; increment = 12345; modulus = 2 ^ 31}random0 : Generatorrandom0 = record{ multiplier = 8121; increment = 28411; modulus = 134456}
-------------------------------------------------------------------------- The Agda standard library---- Unsafe operations over linear congruential pseudo random generators-- for natural numbers-- /!\ NB: LCGs must not be used for cryptographic applications------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}open import Codata.Sized.Stream using (Stream; unfold)open import Data.Nat.PseudoRandom.LCG using (Generator; step)open import Data.Nat.Base using (ℕ)open import Data.Product.Base using (<_,_>)open import Function.Base using (id)module Data.Nat.PseudoRandom.LCG.Unsafe where-------------------------------------------------------------------------- An infinite stream of random numbersstream : Generator → ℕ → Stream ℕ _stream gen = unfold < step gen , id >
-------------------------------------------------------------------------- The Agda standard library---- A bunch of properties about natural number operations-------------------------------------------------------------------------- See README.Data.Nat for some examples showing how this module can be-- used.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Properties whereopen import Axiom.UniquenessOfIdentityProofs using (module Decidable⇒UIP)open import Algebra.Bundles using (Magma; Semigroup; CommutativeSemigroup;CommutativeMonoid; Monoid; Semiring; CommutativeSemiring; CommutativeSemiringWithoutOne)open import Algebra.Definitions.RawMagma using (_,_)open import Algebra.Morphismopen import Algebra.Consequences.Propositionalusing (comm+cancelˡ⇒cancelʳ; comm∧distrʳ⇒distrˡ; comm∧distrˡ⇒distrʳ)open import Algebra.Construct.NaturalChoice.Baseusing (MinOperator; MaxOperator)import Algebra.Construct.NaturalChoice.MinMaxOp as MinMaxOpimport Algebra.Lattice.Construct.NaturalChoice.MinMaxOp as LatticeMinMaxOpimport Algebra.Properties.CommutativeSemigroup as CommSemigroupPropertiesopen import Data.Bool.Base using (Bool; false; true; T)open import Data.Bool.Properties using (T?)open import Data.Nat.Baseopen import Data.Product.Base using (∃; _×_; _,_)open import Data.Sum.Base as Sum using (inj₁; inj₂; _⊎_; [_,_]′)open import Data.Unit.Base using (tt)open import Function.Base using (_∘_; flip; _$_; id; _∘′_; _$′_)open import Function.Bundles using (_↣_)open import Function.Metric.Nat using (TriangleInequality; IsProtoMetric; IsPreMetric;IsQuasiSemiMetric; IsSemiMetric; IsMetric; PreMetric; QuasiSemiMetric;SemiMetric; Metric)open import Level using (0ℓ)open import Relation.Unary as U using (Pred)open import Relation.Binary.Coreusing (_⇒_; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binaryopen import Relation.Binary.Consequences using (flip-Connex)open import Relation.Binary.PropositionalEqualityopen import Relation.Nullary hiding (Irrelevant)open import Relation.Nullary.Decidable using (True; via-injection; map′; recompute)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Reflects using (fromEquivalence)open import Algebra.Definitions {A = ℕ} _≡_hiding (LeftCancellative; RightCancellative; Cancellative)open import Algebra.Definitionsusing (LeftCancellative; RightCancellative; Cancellative)open import Algebra.Structures {A = ℕ} _≡_privatevariablem n o k : ℕ-------------------------------------------------------------------------- Properties of NonZero------------------------------------------------------------------------nonZero? : U.Decidable NonZerononZero? zero = no NonZero.nonZerononZero? (suc n) = yes _-------------------------------------------------------------------------- Properties of NonTrivial------------------------------------------------------------------------nonTrivial? : U.Decidable NonTrivialnonTrivial? 0 = no λ()nonTrivial? 1 = no λ()nonTrivial? (2+ n) = yes _-------------------------------------------------------------------------- Properties of _≡_------------------------------------------------------------------------suc-injective : suc m ≡ suc n → m ≡ nsuc-injective = cong pred≡ᵇ⇒≡ : ∀ m n → T (m ≡ᵇ n) → m ≡ n≡ᵇ⇒≡ zero zero _ = refl≡ᵇ⇒≡ (suc m) (suc n) eq = cong suc (≡ᵇ⇒≡ m n eq)≡⇒≡ᵇ : ∀ m n → m ≡ n → T (m ≡ᵇ n)≡⇒≡ᵇ zero zero eq = _≡⇒≡ᵇ (suc m) (suc n) eq = ≡⇒≡ᵇ m n (suc-injective eq)-- NB: we use the builtin function `_≡ᵇ_` here so that the function-- quickly decides whether to return `yes` or `no`. It still takes-- a linear amount of time to generate the proof if it is inspected.-- We expect the main benefit to be visible in compiled code as the-- backend erases proofs.infix 4 _≟__≟_ : DecidableEquality ℕm ≟ n = map′ (≡ᵇ⇒≡ m n) (≡⇒≡ᵇ m n) (T? (m ≡ᵇ n))≡-irrelevant : Irrelevant {A = ℕ} _≡_≡-irrelevant = Decidable⇒UIP.≡-irrelevant _≟_≟-diag : (eq : m ≡ n) → (m ≟ n) ≡ yes eq≟-diag = ≡-≟-identity _≟_≡-isDecEquivalence : IsDecEquivalence (_≡_ {A = ℕ})≡-isDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = _≟_}≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = record{ Carrier = ℕ; _≈_ = _≡_; isDecEquivalence = ≡-isDecEquivalence}0≢1+n : 0 ≢ suc n0≢1+n ()1+n≢0 : suc n ≢ 01+n≢0 ()1+n≢n : suc n ≢ n1+n≢n {suc n} = 1+n≢n ∘ suc-injective-------------------------------------------------------------------------- Properties of _<ᵇ_------------------------------------------------------------------------<ᵇ⇒< : ∀ m n → T (m <ᵇ n) → m < n<ᵇ⇒< zero (suc n) m<n = z<s<ᵇ⇒< (suc m) (suc n) m<n = s<s (<ᵇ⇒< m n m<n)<⇒<ᵇ : m < n → T (m <ᵇ n)<⇒<ᵇ z<s = tt<⇒<ᵇ (s<s m<n@(s≤s _)) = <⇒<ᵇ m<n<ᵇ-reflects-< : ∀ m n → Reflects (m < n) (m <ᵇ n)<ᵇ-reflects-< m n = fromEquivalence (<ᵇ⇒< m n) <⇒<ᵇ-------------------------------------------------------------------------- Properties of _≤ᵇ_------------------------------------------------------------------------≤ᵇ⇒≤ : ∀ m n → T (m ≤ᵇ n) → m ≤ n≤ᵇ⇒≤ zero n m≤n = z≤n≤ᵇ⇒≤ (suc m) n m≤n = <ᵇ⇒< m n m≤n≤⇒≤ᵇ : m ≤ n → T (m ≤ᵇ n)≤⇒≤ᵇ z≤n = tt≤⇒≤ᵇ m≤n@(s≤s _) = <⇒<ᵇ m≤n≤ᵇ-reflects-≤ : ∀ m n → Reflects (m ≤ n) (m ≤ᵇ n)≤ᵇ-reflects-≤ m n = fromEquivalence (≤ᵇ⇒≤ m n) ≤⇒≤ᵇ-------------------------------------------------------------------------- Properties of _≤_-------------------------------------------------------------------------------------------------------------------------------------------------- Relational properties of _≤_≤-reflexive : _≡_ ⇒ _≤_≤-reflexive {zero} refl = z≤n≤-reflexive {suc m} refl = s≤s (≤-reflexive refl)≤-refl : Reflexive _≤_≤-refl = ≤-reflexive refl≤-antisym : Antisymmetric _≡_ _≤_≤-antisym z≤n z≤n = refl≤-antisym (s≤s m≤n) (s≤s n≤m) = cong suc (≤-antisym m≤n n≤m)≤-trans : Transitive _≤_≤-trans z≤n _ = z≤n≤-trans (s≤s m≤n) (s≤s n≤o) = s≤s (≤-trans m≤n n≤o)≤-total : Total _≤_≤-total zero _ = inj₁ z≤n≤-total _ zero = inj₂ z≤n≤-total (suc m) (suc n) = Sum.map s≤s s≤s (≤-total m n)≤-irrelevant : Irrelevant _≤_≤-irrelevant z≤n z≤n = refl≤-irrelevant (s≤s m≤n₁) (s≤s m≤n₂) = cong s≤s (≤-irrelevant m≤n₁ m≤n₂)-- NB: we use the builtin function `_<ᵇ_` here so that the function-- quickly decides whether to return `yes` or `no`. It still takes-- a linear amount of time to generate the proof if it is inspected.-- We expect the main benefit to be visible in compiled code as the-- backend erases proofs.infix 4 _≤?_ _≥?__≤?_ : Decidable _≤_m ≤? n = map′ (≤ᵇ⇒≤ m n) ≤⇒≤ᵇ (T? (m ≤ᵇ n))_≥?_ : Decidable _≥__≥?_ = flip _≤?_-------------------------------------------------------------------------- Structures≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-isTotalPreorder = record{ isPreorder = ≤-isPreorder; total = ≤-total}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder = record{ isPreorder = ≤-isPreorder}≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder = record{ isTotalPreorder = ≤-isTotalPreorder}≤-poset : Poset 0ℓ 0ℓ 0ℓ≤-poset = record{ isPartialOrder = ≤-isPartialOrder}≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-totalOrder = record{ isTotalOrder = ≤-isTotalOrder}≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder = record{ isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Other properties of _≤_s≤s-injective : {p q : m ≤ n} → s≤s p ≡ s≤s q → p ≡ qs≤s-injective refl = refl≤-pred : suc m ≤ suc n → m ≤ n≤-pred = s≤s⁻¹m≤n⇒m≤1+n : m ≤ n → m ≤ 1 + nm≤n⇒m≤1+n z≤n = z≤nm≤n⇒m≤1+n (s≤s m≤n) = s≤s (m≤n⇒m≤1+n m≤n)n≤1+n : ∀ n → n ≤ 1 + nn≤1+n _ = m≤n⇒m≤1+n ≤-refl1+n≰n : 1 + n ≰ n1+n≰n (s≤s 1+n≤n) = 1+n≰n 1+n≤nn≤0⇒n≡0 : n ≤ 0 → n ≡ 0n≤0⇒n≡0 z≤n = refln≤1⇒n≡0∨n≡1 : n ≤ 1 → n ≡ 0 ⊎ n ≡ 1n≤1⇒n≡0∨n≡1 z≤n = inj₁ refln≤1⇒n≡0∨n≡1 (s≤s z≤n) = inj₂ refl-------------------------------------------------------------------------- Properties of _<_-------------------------------------------------------------------------- Relationships between the various relations<⇒≤ : _<_ ⇒ _≤_<⇒≤ z<s = z≤n<⇒≤ (s<s m<n@(s≤s _)) = s≤s (<⇒≤ m<n)<⇒≢ : _<_ ⇒ _≢_<⇒≢ m<n refl = 1+n≰n m<n>⇒≢ : _>_ ⇒ _≢_>⇒≢ = ≢-sym ∘ <⇒≢≤⇒≯ : _≤_ ⇒ _≯_≤⇒≯ (s≤s m≤n) (s≤s n≤m) = ≤⇒≯ m≤n n≤m<⇒≱ : _<_ ⇒ _≱_<⇒≱ (s≤s m+1≤n) (s≤s n≤m) = <⇒≱ m+1≤n n≤m<⇒≯ : _<_ ⇒ _≯_<⇒≯ (s≤s m<n) (s≤s n<m) = <⇒≯ m<n n<m≰⇒≮ : _≰_ ⇒ _≮_≰⇒≮ m≰n 1+m≤n = m≰n (<⇒≤ 1+m≤n)≰⇒> : _≰_ ⇒ _>_≰⇒> {zero} z≰n = contradiction z≤n z≰n≰⇒> {suc m} {zero} _ = z<s≰⇒> {suc m} {suc n} m≰n = s<s (≰⇒> (m≰n ∘ s≤s))≰⇒≥ : _≰_ ⇒ _≥_≰⇒≥ = <⇒≤ ∘ ≰⇒>≮⇒≥ : _≮_ ⇒ _≥_≮⇒≥ {_} {zero} _ = z≤n≮⇒≥ {zero} {suc j} 1≮j+1 = contradiction z<s 1≮j+1≮⇒≥ {suc i} {suc j} i+1≮j+1 = s≤s (≮⇒≥ (i+1≮j+1 ∘ s<s))≤∧≢⇒< : ∀ {m n} → m ≤ n → m ≢ n → m < n≤∧≢⇒< {_} {zero} z≤n m≢n = contradiction refl m≢n≤∧≢⇒< {_} {suc n} z≤n m≢n = z<s≤∧≢⇒< {_} {suc n} (s≤s m≤n) 1+m≢1+n =s<s (≤∧≢⇒< m≤n (1+m≢1+n ∘ cong suc))≤∧≮⇒≡ : ∀ {m n} → m ≤ n → m ≮ n → m ≡ n≤∧≮⇒≡ m≤n m≮n = ≤-antisym m≤n (≮⇒≥ m≮n)≤-<-connex : Connex _≤_ _<_≤-<-connex m n with m ≤? n... | yes m≤n = inj₁ m≤n... | no ¬m≤n = inj₂ (≰⇒> ¬m≤n)≥->-connex : Connex _≥_ _>_≥->-connex = flip ≤-<-connex<-≤-connex : Connex _<_ _≤_<-≤-connex = flip-Connex ≤-<-connex>-≥-connex : Connex _>_ _≥_>-≥-connex = flip-Connex ≥->-connex-------------------------------------------------------------------------- Relational properties of _<_<-irrefl : Irreflexive _≡_ _<_<-irrefl refl (s<s n<n) = <-irrefl refl n<n<-asym : Asymmetric _<_<-asym (s<s n<m) (s<s m<n) = <-asym n<m m<n<-trans : Transitive _<_<-trans (s≤s i≤j) (s≤s j<k) = s≤s (≤-trans i≤j (≤-trans (n≤1+n _) j<k))≤-<-trans : LeftTrans _≤_ _<_≤-<-trans m≤n (s<s n≤o) = s≤s (≤-trans m≤n n≤o)<-≤-trans : RightTrans _<_ _≤_<-≤-trans (s<s m≤n) (s≤s n≤o) = s≤s (≤-trans m≤n n≤o)-- NB: we use the builtin function `_<ᵇ_` here so that the function-- quickly decides which constructor to return. It still takes a-- linear amount of time to generate the proof if it is inspected.-- We expect the main benefit to be visible in compiled code as the-- backend erases proofs.<-cmp : Trichotomous _≡_ _<_<-cmp m n with m ≟ n | T? (m <ᵇ n)... | yes m≡n | _ = tri≈ (<-irrefl m≡n) m≡n (<-irrefl (sym m≡n))... | no m≢n | yes m<n = tri< (<ᵇ⇒< m n m<n) m≢n (<⇒≯ (<ᵇ⇒< m n m<n))... | no m≢n | no m≮n = tri> (m≮n ∘ <⇒<ᵇ) m≢n (≤∧≢⇒< (≮⇒≥ (m≮n ∘ <⇒<ᵇ)) (m≢n ∘ sym))infix 4 _<?_ _>?__<?_ : Decidable _<_m <? n = suc m ≤? n_>?_ : Decidable _>__>?_ = flip _<?_<-irrelevant : Irrelevant _<_<-irrelevant = ≤-irrelevant<-resp₂-≡ : _<_ Respects₂ _≡_<-resp₂-≡ = subst (_ <_) , subst (_< _)-------------------------------------------------------------------------- Bundles<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = <-resp₂-≡}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = isStrictTotalOrderᶜ record{ isEquivalence = isEquivalence; trans = <-trans; compare = <-cmp}<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}-------------------------------------------------------------------------- Other properties of _<_s<s-injective : {p q : m < n} → s<s p ≡ s<s q → p ≡ qs<s-injective refl = refl<-pred : suc m < suc n → m < n<-pred = s<s⁻¹m<n⇒m<1+n : m < n → m < 1 + nm<n⇒m<1+n z<s = z<sm<n⇒m<1+n (s<s m<n@(s≤s _)) = s<s (m<n⇒m<1+n m<n)n≮0 : n ≮ 0n≮0 ()n≮n : ∀ n → n ≮ n -- implicit?n≮n n = <-irrefl (refl {x = n})0<1+n : 0 < suc n0<1+n = z<sn<1+n : ∀ n → n < suc nn<1+n n = ≤-refln<1⇒n≡0 : n < 1 → n ≡ 0n<1⇒n≡0 (s≤s n≤0) = n≤0⇒n≡0 n≤0n>0⇒n≢0 : n > 0 → n ≢ 0n>0⇒n≢0 {suc n} _ ()n≢0⇒n>0 : n ≢ 0 → n > 0n≢0⇒n>0 {zero} 0≢0 = contradiction refl 0≢0n≢0⇒n>0 {suc n} _ = 0<1+nm<n⇒0<n : m < n → 0 < nm<n⇒0<n = ≤-trans 0<1+nm<n⇒n≢0 : m < n → n ≢ 0m<n⇒n≢0 (s≤s m≤n) ()m<n⇒m≤1+n : m < n → m ≤ suc nm<n⇒m≤1+n = m≤n⇒m≤1+n ∘ <⇒≤m<1+n⇒m<n∨m≡n : ∀ {m n} → m < suc n → m < n ⊎ m ≡ nm<1+n⇒m<n∨m≡n {0} {0} _ = inj₂ reflm<1+n⇒m<n∨m≡n {0} {suc n} _ = inj₁ 0<1+nm<1+n⇒m<n∨m≡n {suc m} {suc n} (s<s m<1+n) = Sum.map s<s (cong suc) (m<1+n⇒m<n∨m≡n m<1+n)m≤n⇒m<n∨m≡n : m ≤ n → m < n ⊎ m ≡ nm≤n⇒m<n∨m≡n m≤n = m<1+n⇒m<n∨m≡n (s≤s m≤n)m<1+n⇒m≤n : m < suc n → m ≤ nm<1+n⇒m≤n (s≤s m≤n) = m≤n∀[m≤n⇒m≢o]⇒n<o : ∀ n o → (∀ {m} → m ≤ n → m ≢ o) → n < o∀[m≤n⇒m≢o]⇒n<o _ zero m≤n⇒n≢0 = contradiction refl (m≤n⇒n≢0 z≤n)∀[m≤n⇒m≢o]⇒n<o zero (suc o) _ = 0<1+n∀[m≤n⇒m≢o]⇒n<o (suc n) (suc o) m≤n⇒n≢o = s≤s (∀[m≤n⇒m≢o]⇒n<o n o rec)whererec : ∀ {m} → m ≤ n → m ≢ orec m≤n refl = m≤n⇒n≢o (s≤s m≤n) refl∀[m<n⇒m≢o]⇒n≤o : ∀ n o → (∀ {m} → m < n → m ≢ o) → n ≤ o∀[m<n⇒m≢o]⇒n≤o zero n _ = z≤n∀[m<n⇒m≢o]⇒n≤o (suc n) zero m<n⇒m≢0 = contradiction refl (m<n⇒m≢0 0<1+n)∀[m<n⇒m≢o]⇒n≤o (suc n) (suc o) m<n⇒m≢o = s≤s (∀[m<n⇒m≢o]⇒n≤o n o rec)whererec : ∀ {m} → m < n → m ≢ orec o<n refl = m<n⇒m≢o (s<s o<n) refl-------------------------------------------------------------------------- A module for reasoning about the _≤_ and _<_ relations------------------------------------------------------------------------module ≤-Reasoning whereopen import Relation.Binary.Reasoning.Base.Triple≤-isPreorder<-asym<-trans(resp₂ _<_)<⇒≤<-≤-trans≤-<-transpublichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)open ≤-Reasoning-------------------------------------------------------------------------- Properties of _+_------------------------------------------------------------------------+-suc : ∀ m n → m + suc n ≡ suc (m + n)+-suc zero n = refl+-suc (suc m) n = cong suc (+-suc m n)-------------------------------------------------------------------------- Algebraic properties of _+_+-assoc : Associative _+_+-assoc zero _ _ = refl+-assoc (suc m) n o = cong suc (+-assoc m n o)+-identityˡ : LeftIdentity 0 _+_+-identityˡ _ = refl+-identityʳ : RightIdentity 0 _+_+-identityʳ zero = refl+-identityʳ (suc n) = cong suc (+-identityʳ n)+-identity : Identity 0 _+_+-identity = +-identityˡ , +-identityʳ+-comm : Commutative _+_+-comm zero n = sym (+-identityʳ n)+-comm (suc m) n = begin-equalitysuc m + n ≡⟨⟩suc (m + n) ≡⟨ cong suc (+-comm m n) ⟩suc (n + m) ≡⟨ sym (+-suc n m) ⟩n + suc m ∎+-cancelˡ-≡ : LeftCancellative _≡_ _+_+-cancelˡ-≡ zero _ _ eq = eq+-cancelˡ-≡ (suc m) _ _ eq = +-cancelˡ-≡ m _ _ (cong pred eq)+-cancelʳ-≡ : RightCancellative _≡_ _+_+-cancelʳ-≡ = comm+cancelˡ⇒cancelʳ +-comm +-cancelˡ-≡+-cancel-≡ : Cancellative _≡_ _+_+-cancel-≡ = +-cancelˡ-≡ , +-cancelʳ-≡-------------------------------------------------------------------------- Structures+-isMagma : IsMagma _+_+-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _+_}+-isSemigroup : IsSemigroup _+_+-isSemigroup = record{ isMagma = +-isMagma; assoc = +-assoc}+-isCommutativeSemigroup : IsCommutativeSemigroup _+_+-isCommutativeSemigroup = record{ isSemigroup = +-isSemigroup; comm = +-comm}+-0-isMonoid : IsMonoid _+_ 0+-0-isMonoid = record{ isSemigroup = +-isSemigroup; identity = +-identity}+-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0+-0-isCommutativeMonoid = record{ isMonoid = +-0-isMonoid; comm = +-comm}-------------------------------------------------------------------------- Bundles+-magma : Magma 0ℓ 0ℓ+-magma = record{ isMagma = +-isMagma}+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ+-commutativeSemigroup = record{ isCommutativeSemigroup = +-isCommutativeSemigroup}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ isMonoid = +-0-isMonoid}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}∸-magma : Magma 0ℓ 0ℓ∸-magma = magma _∸_-------------------------------------------------------------------------- Other properties of _+_ and _≡_m≢1+m+n : ∀ m {n} → m ≢ suc (m + n)m≢1+m+n (suc m) eq = m≢1+m+n m (cong pred eq)m≢1+n+m : ∀ m {n} → m ≢ suc (n + m)m≢1+n+m m m≡1+n+m = m≢1+m+n m (trans m≡1+n+m (cong suc (+-comm _ m)))m+1+n≢m : ∀ m {n} → m + suc n ≢ mm+1+n≢m (suc m) = (m+1+n≢m m) ∘ suc-injectivem+1+n≢n : ∀ m {n} → m + suc n ≢ nm+1+n≢n m {n} rewrite +-suc m n = ≢-sym (m≢1+n+m n)m+1+n≢0 : ∀ m {n} → m + suc n ≢ 0m+1+n≢0 m {n} rewrite +-suc m n = λ()m+n≡0⇒m≡0 : ∀ m {n} → m + n ≡ 0 → m ≡ 0m+n≡0⇒m≡0 zero eq = reflm+n≡0⇒n≡0 : ∀ m {n} → m + n ≡ 0 → n ≡ 0m+n≡0⇒n≡0 m {n} m+n≡0 = m+n≡0⇒m≡0 n (trans (+-comm n m) (m+n≡0))-------------------------------------------------------------------------- Properties of _+_ and _≤_/_<_+-cancelˡ-≤ : LeftCancellative _≤_ _+_+-cancelˡ-≤ zero _ _ le = le+-cancelˡ-≤ (suc m) _ _ (s≤s le) = +-cancelˡ-≤ m _ _ le+-cancelʳ-≤ : RightCancellative _≤_ _+_+-cancelʳ-≤ m n o le =+-cancelˡ-≤ m _ _ (subst₂ _≤_ (+-comm n m) (+-comm o m) le)+-cancel-≤ : Cancellative _≤_ _+_+-cancel-≤ = +-cancelˡ-≤ , +-cancelʳ-≤+-cancelˡ-< : LeftCancellative _<_ _+_+-cancelˡ-< m n o = +-cancelˡ-≤ m (suc n) o ∘ subst (_≤ m + o) (sym (+-suc m n))+-cancelʳ-< : RightCancellative _<_ _+_+-cancelʳ-< m n o n+m<o+m = +-cancelʳ-≤ m (suc n) o n+m<o+m+-cancel-< : Cancellative _<_ _+_+-cancel-< = +-cancelˡ-< , +-cancelʳ-<m≤n⇒m≤o+n : ∀ o → m ≤ n → m ≤ o + nm≤n⇒m≤o+n zero m≤n = m≤nm≤n⇒m≤o+n (suc o) m≤n = m≤n⇒m≤1+n (m≤n⇒m≤o+n o m≤n)m≤n⇒m≤n+o : ∀ o → m ≤ n → m ≤ n + om≤n⇒m≤n+o {m} o m≤n = subst (m ≤_) (+-comm o _) (m≤n⇒m≤o+n o m≤n)m≤m+n : ∀ m n → m ≤ m + nm≤m+n zero n = z≤nm≤m+n (suc m) n = s≤s (m≤m+n m n)m≤n+m : ∀ m n → m ≤ n + mm≤n+m m n = subst (m ≤_) (+-comm m n) (m≤m+n m n)m+n≤o⇒m≤o : ∀ m {n o} → m + n ≤ o → m ≤ om+n≤o⇒m≤o zero m+n≤o = z≤nm+n≤o⇒m≤o (suc m) (s≤s m+n≤o) = s≤s (m+n≤o⇒m≤o m m+n≤o)m+n≤o⇒n≤o : ∀ m {n o} → m + n ≤ o → n ≤ om+n≤o⇒n≤o zero n≤o = n≤om+n≤o⇒n≤o (suc m) m+n<o = m+n≤o⇒n≤o m (<⇒≤ m+n<o)+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-≤ {_} {m} z≤n o≤p = ≤-trans o≤p (m≤n+m _ m)+-mono-≤ {_} {_} (s≤s m≤n) o≤p = s≤s (+-mono-≤ m≤n o≤p)+-monoˡ-≤ : ∀ n → (_+ n) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ n m≤o = +-mono-≤ m≤o (≤-refl {n})+-monoʳ-≤ : ∀ n → (n +_) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ n m≤o = +-mono-≤ (≤-refl {n}) m≤o+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-<-≤ {_} {suc n} z<s o≤p = s≤s (m≤n⇒m≤o+n n o≤p)+-mono-<-≤ {_} {_} (s<s m<n@(s≤s _)) o≤p = s≤s (+-mono-<-≤ m<n o≤p)+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-≤-< {_} {n} z≤n o<p = ≤-trans o<p (m≤n+m _ n)+-mono-≤-< {_} {_} (s≤s m≤n) o<p = s≤s (+-mono-≤-< m≤n o<p)+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-mono-< m≤n = +-mono-≤-< (<⇒≤ m≤n)+-monoˡ-< : ∀ n → (_+ n) Preserves _<_ ⟶ _<_+-monoˡ-< n = +-monoˡ-≤ n+-monoʳ-< : ∀ n → (n +_) Preserves _<_ ⟶ _<_+-monoʳ-< zero m≤o = m≤o+-monoʳ-< (suc n) m≤o = s≤s (+-monoʳ-< n m≤o)m+1+n≰m : ∀ m {n} → m + suc n ≰ mm+1+n≰m (suc m) m+1+n≤m = m+1+n≰m m (s≤s⁻¹ m+1+n≤m)m<m+n : ∀ m {n} → n > 0 → m < m + nm<m+n zero n>0 = n>0m<m+n (suc m) n>0 = s<s (m<m+n m n>0)m<n+m : ∀ m {n} → n > 0 → m < n + mm<n+m m {n} n>0 rewrite +-comm n m = m<m+n m n>0m+n≮n : ∀ m n → m + n ≮ nm+n≮n zero n = n≮n nm+n≮n (suc m) n@(suc _) sm+n<n = m+n≮n m n (m<n⇒m<1+n (s<s⁻¹ sm+n<n))m+n≮m : ∀ m n → m + n ≮ mm+n≮m m n = subst (_≮ m) (+-comm n m) (m+n≮n n m)-------------------------------------------------------------------------- Properties of _*_------------------------------------------------------------------------*-suc : ∀ m n → m * suc n ≡ m + m * n*-suc zero n = refl*-suc (suc m) n = begin-equalitysuc m * suc n ≡⟨⟩suc n + m * suc n ≡⟨ cong (suc n +_) (*-suc m n) ⟩suc n + (m + m * n) ≡⟨⟩suc (n + (m + m * n)) ≡⟨ cong suc (sym (+-assoc n m (m * n))) ⟩suc (n + m + m * n) ≡⟨ cong (λ x → suc (x + m * n)) (+-comm n m) ⟩suc (m + n + m * n) ≡⟨ cong suc (+-assoc m n (m * n)) ⟩suc (m + (n + m * n)) ≡⟨⟩suc m + suc m * n ∎-------------------------------------------------------------------------- Algebraic properties of _*_*-identityˡ : LeftIdentity 1 _*_*-identityˡ n = +-identityʳ n*-identityʳ : RightIdentity 1 _*_*-identityʳ zero = refl*-identityʳ (suc n) = cong suc (*-identityʳ n)*-identity : Identity 1 _*_*-identity = *-identityˡ , *-identityʳ*-zeroˡ : LeftZero 0 _*_*-zeroˡ _ = refl*-zeroʳ : RightZero 0 _*_*-zeroʳ zero = refl*-zeroʳ (suc n) = *-zeroʳ n*-zero : Zero 0 _*_*-zero = *-zeroˡ , *-zeroʳ*-comm : Commutative _*_*-comm zero n = sym (*-zeroʳ n)*-comm (suc m) n = begin-equalitysuc m * n ≡⟨⟩n + m * n ≡⟨ cong (n +_) (*-comm m n) ⟩n + n * m ≡⟨ sym (*-suc n m) ⟩n * suc m ∎*-distribʳ-+ : _*_ DistributesOverʳ _+_*-distribʳ-+ m zero o = refl*-distribʳ-+ m (suc n) o = begin-equality(suc n + o) * m ≡⟨⟩m + (n + o) * m ≡⟨ cong (m +_) (*-distribʳ-+ m n o) ⟩m + (n * m + o * m) ≡⟨ sym (+-assoc m (n * m) (o * m)) ⟩m + n * m + o * m ≡⟨⟩suc n * m + o * m ∎*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distribˡ-+ = comm∧distrʳ⇒distrˡ *-comm *-distribʳ-+*-distrib-+ : _*_ DistributesOver _+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+*-assoc : Associative _*_*-assoc zero n o = refl*-assoc (suc m) n o = begin-equality(suc m * n) * o ≡⟨⟩(n + m * n) * o ≡⟨ *-distribʳ-+ o n (m * n) ⟩n * o + (m * n) * o ≡⟨ cong (n * o +_) (*-assoc m n o) ⟩n * o + m * (n * o) ≡⟨⟩suc m * (n * o) ∎-------------------------------------------------------------------------- Structures*-isMagma : IsMagma _*_*-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _*_}*-isSemigroup : IsSemigroup _*_*-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-isCommutativeSemigroup : IsCommutativeSemigroup _*_*-isCommutativeSemigroup = record{ isSemigroup = *-isSemigroup; comm = *-comm}*-1-isMonoid : IsMonoid _*_ 1*-1-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1*-1-isCommutativeMonoid = record{ isMonoid = *-1-isMonoid; comm = *-comm}+-*-isSemiring : IsSemiring _+_ _*_ 0 1+-*-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-0-isCommutativeMonoid; *-cong = cong₂ _*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}; zero = *-zero}+-*-isCommutativeSemiring : IsCommutativeSemiring _+_ _*_ 0 1+-*-isCommutativeSemiring = record{ isSemiring = +-*-isSemiring; *-comm = *-comm}-------------------------------------------------------------------------- Bundles*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeSemigroup = record{ isCommutativeSemigroup = *-isCommutativeSemigroup}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-semiring : Semiring 0ℓ 0ℓ+-*-semiring = record{ isSemiring = +-*-isSemiring}+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ+-*-commutativeSemiring = record{ isCommutativeSemiring = +-*-isCommutativeSemiring}-------------------------------------------------------------------------- Other properties of _*_ and _≡_*-cancelʳ-≡ : ∀ m n o .{{_ : NonZero o}} → m * o ≡ n * o → m ≡ n*-cancelʳ-≡ zero zero (suc o) eq = refl*-cancelʳ-≡ (suc m) (suc n) (suc o) eq =cong suc (*-cancelʳ-≡ m n (suc o) (+-cancelˡ-≡ (suc o) (m * suc o) (n * suc o) eq))*-cancelˡ-≡ : ∀ m n o .{{_ : NonZero o}} → o * m ≡ o * n → m ≡ n*-cancelˡ-≡ m n o rewrite *-comm o m | *-comm o n = *-cancelʳ-≡ m n om*n≡0⇒m≡0∨n≡0 : ∀ m {n} → m * n ≡ 0 → m ≡ 0 ⊎ n ≡ 0m*n≡0⇒m≡0∨n≡0 zero {n} eq = inj₁ reflm*n≡0⇒m≡0∨n≡0 (suc m) {zero} eq = inj₂ reflm*n≢0 : ∀ m n .{{_ : NonZero m}} .{{_ : NonZero n}} → NonZero (m * n)m*n≢0 (suc m) (suc n) = _m*n≢0⇒m≢0 : ∀ m {n} → .{{NonZero (m * n)}} → NonZero mm*n≢0⇒m≢0 (suc _) = _m*n≢0⇒n≢0 : ∀ m {n} → .{{NonZero (m * n)}} → NonZero nm*n≢0⇒n≢0 m {n} rewrite *-comm m n = m*n≢0⇒m≢0 n {m}m*n≡0⇒m≡0 : ∀ m n .{{_ : NonZero n}} → m * n ≡ 0 → m ≡ 0m*n≡0⇒m≡0 zero (suc _) eq = reflm*n≡1⇒m≡1 : ∀ m n → m * n ≡ 1 → m ≡ 1m*n≡1⇒m≡1 (suc zero) n _ = reflm*n≡1⇒m≡1 (suc (suc m)) (suc zero) ()m*n≡1⇒m≡1 (suc (suc m)) zero eq =contradiction (trans (sym $ *-zeroʳ m) eq) λ()m*n≡1⇒n≡1 : ∀ m n → m * n ≡ 1 → n ≡ 1m*n≡1⇒n≡1 m n eq = m*n≡1⇒m≡1 n m (trans (*-comm n m) eq)[m*n]*[o*p]≡[m*o]*[n*p] : ∀ m n o p → (m * n) * (o * p) ≡ (m * o) * (n * p)[m*n]*[o*p]≡[m*o]*[n*p] m n o p = begin-equality(m * n) * (o * p) ≡⟨ *-assoc m n (o * p) ⟩m * (n * (o * p)) ≡⟨ cong (m *_) (x∙yz≈y∙xz n o p) ⟩m * (o * (n * p)) ≡⟨ *-assoc m o (n * p) ⟨(m * o) * (n * p) ∎where open CommSemigroupProperties *-commutativeSemigroupm≢0∧n>1⇒m*n>1 : ∀ m n .{{_ : NonZero m}} .{{_ : NonTrivial n}} → NonTrivial (m * n)m≢0∧n>1⇒m*n>1 (suc m) (2+ n) = _n≢0∧m>1⇒m*n>1 : ∀ m n .{{_ : NonZero n}} .{{_ : NonTrivial m}} → NonTrivial (m * n)n≢0∧m>1⇒m*n>1 m n rewrite *-comm m n = m≢0∧n>1⇒m*n>1 n m-------------------------------------------------------------------------- Other properties of _*_ and _≤_/_<_*-cancelʳ-≤ : ∀ m n o .{{_ : NonZero o}} → m * o ≤ n * o → m ≤ n*-cancelʳ-≤ zero _ _ _ = z≤n*-cancelʳ-≤ (suc m) (suc n) o@(suc _) le =s≤s (*-cancelʳ-≤ m n o (+-cancelˡ-≤ _ _ _ le))*-cancelˡ-≤ : ∀ o .{{_ : NonZero o}} → o * m ≤ o * n → m ≤ n*-cancelˡ-≤ {m} {n} o rewrite *-comm o m | *-comm o n = *-cancelʳ-≤ m n o*-mono-≤ : _*_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_*-mono-≤ z≤n _ = z≤n*-mono-≤ (s≤s m≤n) u≤v = +-mono-≤ u≤v (*-mono-≤ m≤n u≤v)*-monoˡ-≤ : ∀ n → (_* n) Preserves _≤_ ⟶ _≤_*-monoˡ-≤ n m≤o = *-mono-≤ m≤o (≤-refl {n})*-monoʳ-≤ : ∀ n → (n *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤ n m≤o = *-mono-≤ (≤-refl {n}) m≤o*-mono-< : _*_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_*-mono-< z<s u<v@(s≤s _) = 0<1+n*-mono-< (s<s m<n@(s≤s _)) u<v@(s≤s _) = +-mono-< u<v (*-mono-< m<n u<v)*-monoˡ-< : ∀ n .{{_ : NonZero n}} → (_* n) Preserves _<_ ⟶ _<_*-monoˡ-< n@(suc _) z<s = 0<1+n*-monoˡ-< n@(suc _) (s<s m<o@(s≤s _)) = +-mono-≤-< ≤-refl (*-monoˡ-< n m<o)*-monoʳ-< : ∀ n .{{_ : NonZero n}} → (n *_) Preserves _<_ ⟶ _<_*-monoʳ-< (suc zero) m<o@(s≤s _) = +-mono-≤ m<o z≤n*-monoʳ-< (suc n@(suc _)) m<o@(s≤s _) = +-mono-≤ m<o (<⇒≤ (*-monoʳ-< n m<o))m≤m*n : ∀ m n .{{_ : NonZero n}} → m ≤ m * nm≤m*n m n@(suc _) = beginm ≡⟨ sym (*-identityʳ m) ⟩m * 1 ≤⟨ *-monoʳ-≤ m 0<1+n ⟩m * n ∎m≤n*m : ∀ m n .{{_ : NonZero n}} → m ≤ n * mm≤n*m m n@(suc _) = beginm ≤⟨ m≤m*n m n ⟩m * n ≡⟨ *-comm m n ⟩n * m ∎m<m*n : ∀ m n .{{_ : NonZero m}} → 1 < n → m < m * nm<m*n m@(suc m-1) n@(suc (suc n-2)) (s≤s (s≤s _)) = begin-strictm <⟨ s≤s (s≤s (m≤n+m m-1 n-2)) ⟩n + m-1 ≤⟨ +-monoʳ-≤ n (m≤m*n m-1 n) ⟩n + m-1 * n ≡⟨⟩m * n ∎m<n⇒m<n*o : ∀ o .{{_ : NonZero o}} → m < n → m < n * om<n⇒m<n*o {n = n} o m<n = <-≤-trans m<n (m≤m*n n o)m<n⇒m<o*n : ∀ {m n} o .{{_ : NonZero o}} → m < n → m < o * nm<n⇒m<o*n {m} {n} o m<n = begin-strictm <⟨ m<n⇒m<n*o o m<n ⟩n * o ≡⟨ *-comm n o ⟩o * n ∎*-cancelʳ-< : RightCancellative _<_ _*_*-cancelʳ-< zero zero (suc o) _ = 0<1+n*-cancelʳ-< (suc m) zero (suc o) _ = 0<1+n*-cancelʳ-< m (suc n) (suc o) nm<om =s≤s (*-cancelʳ-< m n o (+-cancelˡ-< m _ _ nm<om))*-cancelˡ-< : LeftCancellative _<_ _*_*-cancelˡ-< x y z rewrite *-comm x y | *-comm x z = *-cancelʳ-< x y z*-cancel-< : Cancellative _<_ _*_*-cancel-< = *-cancelˡ-< , *-cancelʳ-<-------------------------------------------------------------------------- Properties of _^_------------------------------------------------------------------------^-identityʳ : RightIdentity 1 _^_^-identityʳ zero = refl^-identityʳ (suc n) = cong suc (^-identityʳ n)^-zeroˡ : LeftZero 1 _^_^-zeroˡ zero = refl^-zeroˡ (suc n) = begin-equality1 ^ suc n ≡⟨⟩1 * (1 ^ n) ≡⟨ *-identityˡ (1 ^ n) ⟩1 ^ n ≡⟨ ^-zeroˡ n ⟩1 ∎^-distribˡ-+-* : ∀ m n o → m ^ (n + o) ≡ m ^ n * m ^ o^-distribˡ-+-* m zero o = sym (+-identityʳ (m ^ o))^-distribˡ-+-* m (suc n) o = begin-equalitym * (m ^ (n + o)) ≡⟨ cong (m *_) (^-distribˡ-+-* m n o) ⟩m * ((m ^ n) * (m ^ o)) ≡⟨ sym (*-assoc m _ _) ⟩(m * (m ^ n)) * (m ^ o) ∎^-semigroup-morphism : ∀ {n} → (n ^_) Is +-semigroup -Semigroup⟶ *-semigroup^-semigroup-morphism = record{ ⟦⟧-cong = cong (_ ^_); ∙-homo = ^-distribˡ-+-* _}^-monoid-morphism : ∀ {n} → (n ^_) Is +-0-monoid -Monoid⟶ *-1-monoid^-monoid-morphism = record{ sm-homo = ^-semigroup-morphism; ε-homo = refl}^-*-assoc : ∀ m n o → (m ^ n) ^ o ≡ m ^ (n * o)^-*-assoc m n zero = cong (m ^_) (sym $ *-zeroʳ n)^-*-assoc m n (suc o) = begin-equality(m ^ n) * ((m ^ n) ^ o) ≡⟨ cong ((m ^ n) *_) (^-*-assoc m n o) ⟩(m ^ n) * (m ^ (n * o)) ≡⟨ sym (^-distribˡ-+-* m n (n * o)) ⟩m ^ (n + n * o) ≡⟨ cong (m ^_) (sym (*-suc n o)) ⟩m ^ (n * (suc o)) ∎m^n≡0⇒m≡0 : ∀ m n → m ^ n ≡ 0 → m ≡ 0m^n≡0⇒m≡0 m (suc n) eq = [ id , m^n≡0⇒m≡0 m n ]′ (m*n≡0⇒m≡0∨n≡0 m eq)m^n≡1⇒n≡0∨m≡1 : ∀ m n → m ^ n ≡ 1 → n ≡ 0 ⊎ m ≡ 1m^n≡1⇒n≡0∨m≡1 m zero _ = inj₁ reflm^n≡1⇒n≡0∨m≡1 m (suc n) eq = inj₂ (m*n≡1⇒m≡1 m (m ^ n) eq)m^n≢0 : ∀ m n .{{_ : NonZero m}} → NonZero (m ^ n)m^n≢0 m n = ≢-nonZero (≢-nonZero⁻¹ m ∘′ m^n≡0⇒m≡0 m n)m^n>0 : ∀ m .{{_ : NonZero m}} n → m ^ n > 0m^n>0 m n = >-nonZero⁻¹ (m ^ n) {{m^n≢0 m n}}^-monoˡ-≤ : ∀ n → (_^ n) Preserves _≤_ ⟶ _≤_^-monoˡ-≤ zero m≤o = s≤s z≤n^-monoˡ-≤ (suc n) m≤o = *-mono-≤ m≤o (^-monoˡ-≤ n m≤o)^-monoʳ-≤ : ∀ m .{{_ : NonZero m}} → (m ^_) Preserves _≤_ ⟶ _≤_^-monoʳ-≤ m {_} {o} z≤n = n≢0⇒n>0 (≢-nonZero⁻¹ (m ^ o) {{m^n≢0 m o}})^-monoʳ-≤ m (s≤s n≤o) = *-monoʳ-≤ m (^-monoʳ-≤ m n≤o)^-monoˡ-< : ∀ n .{{_ : NonZero n}} → (_^ n) Preserves _<_ ⟶ _<_^-monoˡ-< (suc zero) m<o = *-monoˡ-< 1 m<o^-monoˡ-< (suc n@(suc _)) m<o = *-mono-< m<o (^-monoˡ-< n m<o)^-monoʳ-< : ∀ m → 1 < m → (m ^_) Preserves _<_ ⟶ _<_^-monoʳ-< m@(suc _) 1<m {zero} {suc o} z<s = *-mono-≤ 1<m (m^n>0 m o)^-monoʳ-< m@(suc _) 1<m {suc n} {suc o} (s<s n<o) = *-monoʳ-< m (^-monoʳ-< m 1<m n<o)-------------------------------------------------------------------------- Properties of _⊓_ and _⊔_-------------------------------------------------------------------------- Basic specification in terms of _≤_m≤n⇒m⊔n≡n : m ≤ n → m ⊔ n ≡ nm≤n⇒m⊔n≡n {zero} _ = reflm≤n⇒m⊔n≡n {suc m} (s≤s m≤n) = cong suc (m≤n⇒m⊔n≡n m≤n)m≥n⇒m⊔n≡m : m ≥ n → m ⊔ n ≡ mm≥n⇒m⊔n≡m {zero} {zero} z≤n = reflm≥n⇒m⊔n≡m {suc m} {zero} z≤n = reflm≥n⇒m⊔n≡m {suc m} {suc n} (s≤s m≥n) = cong suc (m≥n⇒m⊔n≡m m≥n)m≤n⇒m⊓n≡m : m ≤ n → m ⊓ n ≡ mm≤n⇒m⊓n≡m {zero} z≤n = reflm≤n⇒m⊓n≡m {suc m} (s≤s m≤n) = cong suc (m≤n⇒m⊓n≡m m≤n)m≥n⇒m⊓n≡n : m ≥ n → m ⊓ n ≡ nm≥n⇒m⊓n≡n {zero} {zero} z≤n = reflm≥n⇒m⊓n≡n {suc m} {zero} z≤n = reflm≥n⇒m⊓n≡n {suc m} {suc n} (s≤s m≤n) = cong suc (m≥n⇒m⊓n≡n m≤n)⊓-operator : MinOperator ≤-totalPreorder⊓-operator = record{ x≤y⇒x⊓y≈x = m≤n⇒m⊓n≡m; x≥y⇒x⊓y≈y = m≥n⇒m⊓n≡n}⊔-operator : MaxOperator ≤-totalPreorder⊔-operator = record{ x≤y⇒x⊔y≈y = m≤n⇒m⊔n≡n; x≥y⇒x⊔y≈x = m≥n⇒m⊔n≡m}-------------------------------------------------------------------------- Equality to their counterparts defined in terms of primitive operations⊔≡⊔′ : ∀ m n → m ⊔ n ≡ m ⊔′ n⊔≡⊔′ m n with m <ᵇ n in eq... | false = m≥n⇒m⊔n≡m (≮⇒≥ (λ m<n → subst T eq (<⇒<ᵇ m<n)))... | true = m≤n⇒m⊔n≡n (<⇒≤ (<ᵇ⇒< m n (subst T (sym eq) _)))⊓≡⊓′ : ∀ m n → m ⊓ n ≡ m ⊓′ n⊓≡⊓′ m n with m <ᵇ n in eq... | false = m≥n⇒m⊓n≡n (≮⇒≥ (λ m<n → subst T eq (<⇒<ᵇ m<n)))... | true = m≤n⇒m⊓n≡m (<⇒≤ (<ᵇ⇒< m n (subst T (sym eq) _)))-------------------------------------------------------------------------- Derived properties of _⊓_ and _⊔_privatemodule ⊓-⊔-properties = MinMaxOp ⊓-operator ⊔-operatormodule ⊓-⊔-latticeProperties = LatticeMinMaxOp ⊓-operator ⊔-operatoropen ⊓-⊔-properties publicusing( ⊓-idem -- : Idempotent _⊓_; ⊓-sel -- : Selective _⊓_; ⊓-assoc -- : Associative _⊓_; ⊓-comm -- : Commutative _⊓_; ⊔-idem -- : Idempotent _⊔_; ⊔-sel -- : Selective _⊔_; ⊔-assoc -- : Associative _⊔_; ⊔-comm -- : Commutative _⊔_; ⊓-distribˡ-⊔ -- : _⊓_ DistributesOverˡ _⊔_; ⊓-distribʳ-⊔ -- : _⊓_ DistributesOverʳ _⊔_; ⊓-distrib-⊔ -- : _⊓_ DistributesOver _⊔_; ⊔-distribˡ-⊓ -- : _⊔_ DistributesOverˡ _⊓_; ⊔-distribʳ-⊓ -- : _⊔_ DistributesOverʳ _⊓_; ⊔-distrib-⊓ -- : _⊔_ DistributesOver _⊓_; ⊓-absorbs-⊔ -- : _⊓_ Absorbs _⊔_; ⊔-absorbs-⊓ -- : _⊔_ Absorbs _⊓_; ⊔-⊓-absorptive -- : Absorptive _⊔_ _⊓_; ⊓-⊔-absorptive -- : Absorptive _⊓_ _⊔_; ⊓-isMagma -- : IsMagma _⊓_; ⊓-isSemigroup -- : IsSemigroup _⊓_; ⊓-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊓_; ⊓-isBand -- : IsBand _⊓_; ⊓-isSelectiveMagma -- : IsSelectiveMagma _⊓_; ⊔-isMagma -- : IsMagma _⊔_; ⊔-isSemigroup -- : IsSemigroup _⊔_; ⊔-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊔_; ⊔-isBand -- : IsBand _⊔_; ⊔-isSelectiveMagma -- : IsSelectiveMagma _⊔_; ⊓-magma -- : Magma _ _; ⊓-semigroup -- : Semigroup _ _; ⊓-band -- : Band _ _; ⊓-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊓-selectiveMagma -- : SelectiveMagma _ _; ⊔-magma -- : Magma _ _; ⊔-semigroup -- : Semigroup _ _; ⊔-band -- : Band _ _; ⊔-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊔-selectiveMagma -- : SelectiveMagma _ _; ⊓-glb -- : ∀ {m n o} → m ≥ o → n ≥ o → m ⊓ n ≥ o; ⊓-triangulate -- : ∀ m n o → m ⊓ n ⊓ o ≡ (m ⊓ n) ⊓ (n ⊓ o); ⊓-mono-≤ -- : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊓-monoˡ-≤ -- : ∀ n → (_⊓ n) Preserves _≤_ ⟶ _≤_; ⊓-monoʳ-≤ -- : ∀ n → (n ⊓_) Preserves _≤_ ⟶ _≤_; ⊔-lub -- : ∀ {m n o} → m ≤ o → n ≤ o → m ⊔ n ≤ o; ⊔-triangulate -- : ∀ m n o → m ⊔ n ⊔ o ≡ (m ⊔ n) ⊔ (n ⊔ o); ⊔-mono-≤ -- : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊔-monoˡ-≤ -- : ∀ n → (_⊔ n) Preserves _≤_ ⟶ _≤_; ⊔-monoʳ-≤ -- : ∀ n → (n ⊔_) Preserves _≤_ ⟶ _≤_)renaming( x⊓y≈y⇒y≤x to m⊓n≡n⇒n≤m -- : ∀ {m n} → m ⊓ n ≡ n → n ≤ m; x⊓y≈x⇒x≤y to m⊓n≡m⇒m≤n -- : ∀ {m n} → m ⊓ n ≡ m → m ≤ n; x⊓y≤x to m⊓n≤m -- : ∀ m n → m ⊓ n ≤ m; x⊓y≤y to m⊓n≤n -- : ∀ m n → m ⊓ n ≤ n; x≤y⇒x⊓z≤y to m≤n⇒m⊓o≤n -- : ∀ {m n} o → m ≤ n → m ⊓ o ≤ n; x≤y⇒z⊓x≤y to m≤n⇒o⊓m≤n -- : ∀ {m n} o → m ≤ n → o ⊓ m ≤ n; x≤y⊓z⇒x≤y to m≤n⊓o⇒m≤n -- : ∀ {m} n o → m ≤ n ⊓ o → m ≤ n; x≤y⊓z⇒x≤z to m≤n⊓o⇒m≤o -- : ∀ {m} n o → m ≤ n ⊓ o → m ≤ o; x⊔y≈y⇒x≤y to m⊔n≡n⇒m≤n -- : ∀ {m n} → m ⊔ n ≡ n → m ≤ n; x⊔y≈x⇒y≤x to m⊔n≡m⇒n≤m -- : ∀ {m n} → m ⊔ n ≡ m → n ≤ m; x≤x⊔y to m≤m⊔n -- : ∀ m n → m ≤ m ⊔ n; x≤y⊔x to m≤n⊔m -- : ∀ m n → m ≤ n ⊔ m; x≤y⇒x≤y⊔z to m≤n⇒m≤n⊔o -- : ∀ {m n} o → m ≤ n → m ≤ n ⊔ o; x≤y⇒x≤z⊔y to m≤n⇒m≤o⊔n -- : ∀ {m n} o → m ≤ n → m ≤ o ⊔ n; x⊔y≤z⇒x≤z to m⊔n≤o⇒m≤o -- : ∀ m n {o} → m ⊔ n ≤ o → m ≤ o; x⊔y≤z⇒y≤z to m⊔n≤o⇒n≤o -- : ∀ m n {o} → m ⊔ n ≤ o → n ≤ o; x⊓y≤x⊔y to m⊓n≤m⊔n -- : ∀ m n → m ⊓ n ≤ m ⊔ n)open ⊓-⊔-latticeProperties publicusing( ⊓-isSemilattice -- : IsSemilattice _⊓_; ⊔-isSemilattice -- : IsSemilattice _⊔_; ⊔-⊓-isLattice -- : IsLattice _⊔_ _⊓_; ⊓-⊔-isLattice -- : IsLattice _⊓_ _⊔_; ⊔-⊓-isDistributiveLattice -- : IsDistributiveLattice _⊔_ _⊓_; ⊓-⊔-isDistributiveLattice -- : IsDistributiveLattice _⊓_ _⊔_; ⊓-semilattice -- : Semilattice _ _; ⊔-semilattice -- : Semilattice _ _; ⊔-⊓-lattice -- : Lattice _ _; ⊓-⊔-lattice -- : Lattice _ _; ⊔-⊓-distributiveLattice -- : DistributiveLattice _ _; ⊓-⊔-distributiveLattice -- : DistributiveLattice _ _)-------------------------------------------------------------------------- Automatically derived properties of _⊓_ and _⊔_⊔-identityˡ : LeftIdentity 0 _⊔_⊔-identityˡ _ = refl⊔-identityʳ : RightIdentity 0 _⊔_⊔-identityʳ zero = refl⊔-identityʳ (suc n) = refl⊔-identity : Identity 0 _⊔_⊔-identity = ⊔-identityˡ , ⊔-identityʳ-------------------------------------------------------------------------- Structures⊔-0-isMonoid : IsMonoid _⊔_ 0⊔-0-isMonoid = record{ isSemigroup = ⊔-isSemigroup; identity = ⊔-identity}⊔-0-isCommutativeMonoid : IsCommutativeMonoid _⊔_ 0⊔-0-isCommutativeMonoid = record{ isMonoid = ⊔-0-isMonoid; comm = ⊔-comm}-------------------------------------------------------------------------- Bundles⊔-0-monoid : Monoid 0ℓ 0ℓ⊔-0-monoid = record{ isMonoid = ⊔-0-isMonoid}⊔-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ⊔-0-commutativeMonoid = record{ isCommutativeMonoid = ⊔-0-isCommutativeMonoid}-------------------------------------------------------------------------- Other properties of _⊔_ and _≤_/_<_mono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ m n → f (m ⊔ n) ≡ f m ⊔ f nmono-≤-distrib-⊔ {f} = ⊓-⊔-properties.mono-≤-distrib-⊔ (cong f)mono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ m n → f (m ⊓ n) ≡ f m ⊓ f nmono-≤-distrib-⊓ {f} = ⊓-⊔-properties.mono-≤-distrib-⊓ (cong f)antimono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ m n → f (m ⊓ n) ≡ f m ⊔ f nantimono-≤-distrib-⊓ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊓ (cong f)antimono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ m n → f (m ⊔ n) ≡ f m ⊓ f nantimono-≤-distrib-⊔ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊔ (cong f)m<n⇒m<n⊔o : ∀ o → m < n → m < n ⊔ om<n⇒m<n⊔o = m≤n⇒m≤n⊔om<n⇒m<o⊔n : ∀ o → m < n → m < o ⊔ nm<n⇒m<o⊔n = m≤n⇒m≤o⊔nm⊔n<o⇒m<o : ∀ m n {o} → m ⊔ n < o → m < om⊔n<o⇒m<o m n m⊔n<o = ≤-<-trans (m≤m⊔n m n) m⊔n<om⊔n<o⇒n<o : ∀ m n {o} → m ⊔ n < o → n < om⊔n<o⇒n<o m n m⊔n<o = ≤-<-trans (m≤n⊔m m n) m⊔n<o⊔-mono-< : _⊔_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊔-mono-< = ⊔-mono-≤⊔-pres-<m : n < m → o < m → n ⊔ o < m⊔-pres-<m {m = m} n<m o<m = subst (_ <_) (⊔-idem m) (⊔-mono-< n<m o<m)-------------------------------------------------------------------------- Other properties of _⊔_ and _+_+-distribˡ-⊔ : _+_ DistributesOverˡ _⊔_+-distribˡ-⊔ zero n o = refl+-distribˡ-⊔ (suc m) n o = cong suc (+-distribˡ-⊔ m n o)+-distribʳ-⊔ : _+_ DistributesOverʳ _⊔_+-distribʳ-⊔ = comm∧distrˡ⇒distrʳ +-comm +-distribˡ-⊔+-distrib-⊔ : _+_ DistributesOver _⊔_+-distrib-⊔ = +-distribˡ-⊔ , +-distribʳ-⊔m⊔n≤m+n : ∀ m n → m ⊔ n ≤ m + nm⊔n≤m+n m n with ⊔-sel m n... | inj₁ m⊔n≡m rewrite m⊔n≡m = m≤m+n m n... | inj₂ m⊔n≡n rewrite m⊔n≡n = m≤n+m n m-------------------------------------------------------------------------- Other properties of _⊔_ and _*_*-distribˡ-⊔ : _*_ DistributesOverˡ _⊔_*-distribˡ-⊔ m zero o = sym (cong (_⊔ m * o) (*-zeroʳ m))*-distribˡ-⊔ m (suc n) zero = begin-equalitym * (suc n ⊔ zero) ≡⟨⟩m * suc n ≡⟨ ⊔-identityʳ (m * suc n) ⟨m * suc n ⊔ zero ≡⟨ cong (m * suc n ⊔_) (*-zeroʳ m) ⟨m * suc n ⊔ m * zero ∎*-distribˡ-⊔ m (suc n) (suc o) = begin-equalitym * (suc n ⊔ suc o) ≡⟨⟩m * suc (n ⊔ o) ≡⟨ *-suc m (n ⊔ o) ⟩m + m * (n ⊔ o) ≡⟨ cong (m +_) (*-distribˡ-⊔ m n o) ⟩m + (m * n ⊔ m * o) ≡⟨ +-distribˡ-⊔ m (m * n) (m * o) ⟩(m + m * n) ⊔ (m + m * o) ≡⟨ cong₂ _⊔_ (*-suc m n) (*-suc m o) ⟨(m * suc n) ⊔ (m * suc o) ∎*-distribʳ-⊔ : _*_ DistributesOverʳ _⊔_*-distribʳ-⊔ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-⊔*-distrib-⊔ : _*_ DistributesOver _⊔_*-distrib-⊔ = *-distribˡ-⊔ , *-distribʳ-⊔-------------------------------------------------------------------------- Properties of _⊓_-------------------------------------------------------------------------------------------------------------------------------------------------- Algebraic properties⊓-zeroˡ : LeftZero 0 _⊓_⊓-zeroˡ _ = refl⊓-zeroʳ : RightZero 0 _⊓_⊓-zeroʳ zero = refl⊓-zeroʳ (suc n) = refl⊓-zero : Zero 0 _⊓_⊓-zero = ⊓-zeroˡ , ⊓-zeroʳ-------------------------------------------------------------------------- Structures⊔-⊓-isSemiringWithoutOne : IsSemiringWithoutOne _⊔_ _⊓_ 0⊔-⊓-isSemiringWithoutOne = record{ +-isCommutativeMonoid = ⊔-0-isCommutativeMonoid; *-cong = cong₂ _⊓_; *-assoc = ⊓-assoc; distrib = ⊓-distrib-⊔; zero = ⊓-zero}⊔-⊓-isCommutativeSemiringWithoutOne: IsCommutativeSemiringWithoutOne _⊔_ _⊓_ 0⊔-⊓-isCommutativeSemiringWithoutOne = record{ isSemiringWithoutOne = ⊔-⊓-isSemiringWithoutOne; *-comm = ⊓-comm}-------------------------------------------------------------------------- Bundles⊔-⊓-commutativeSemiringWithoutOne : CommutativeSemiringWithoutOne 0ℓ 0ℓ⊔-⊓-commutativeSemiringWithoutOne = record{ isCommutativeSemiringWithoutOne =⊔-⊓-isCommutativeSemiringWithoutOne}-------------------------------------------------------------------------- Other properties of _⊓_ and _≤_/_<_m<n⇒m⊓o<n : ∀ o → m < n → m ⊓ o < nm<n⇒m⊓o<n o m<n = ≤-<-trans (m⊓n≤m _ o) m<nm<n⇒o⊓m<n : ∀ o → m < n → o ⊓ m < nm<n⇒o⊓m<n o m<n = ≤-<-trans (m⊓n≤n o _) m<nm<n⊓o⇒m<n : ∀ n o → m < n ⊓ o → m < nm<n⊓o⇒m<n = m≤n⊓o⇒m≤nm<n⊓o⇒m<o : ∀ n o → m < n ⊓ o → m < om<n⊓o⇒m<o = m≤n⊓o⇒m≤o⊓-mono-< : _⊓_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊓-mono-< = ⊓-mono-≤⊓-pres-m< : m < n → m < o → m < n ⊓ o⊓-pres-m< {m} m<n m<o = subst (_< _) (⊓-idem m) (⊓-mono-< m<n m<o)-------------------------------------------------------------------------- Other properties of _⊓_ and _+_+-distribˡ-⊓ : _+_ DistributesOverˡ _⊓_+-distribˡ-⊓ zero n o = refl+-distribˡ-⊓ (suc m) n o = cong suc (+-distribˡ-⊓ m n o)+-distribʳ-⊓ : _+_ DistributesOverʳ _⊓_+-distribʳ-⊓ = comm∧distrˡ⇒distrʳ +-comm +-distribˡ-⊓+-distrib-⊓ : _+_ DistributesOver _⊓_+-distrib-⊓ = +-distribˡ-⊓ , +-distribʳ-⊓m⊓n≤m+n : ∀ m n → m ⊓ n ≤ m + nm⊓n≤m+n m n with ⊓-sel m n... | inj₁ m⊓n≡m rewrite m⊓n≡m = m≤m+n m n... | inj₂ m⊓n≡n rewrite m⊓n≡n = m≤n+m n m-------------------------------------------------------------------------- Other properties of _⊓_ and _*_*-distribˡ-⊓ : _*_ DistributesOverˡ _⊓_*-distribˡ-⊓ m 0 o = begin-equalitym * (0 ⊓ o) ≡⟨⟩m * 0 ≡⟨ *-zeroʳ m ⟩0 ≡⟨⟩0 ⊓ (m * o) ≡⟨ cong (_⊓ (m * o)) (*-zeroʳ m) ⟨(m * 0) ⊓ (m * o) ∎*-distribˡ-⊓ m (suc n) 0 = begin-equalitym * (suc n ⊓ 0) ≡⟨⟩m * 0 ≡⟨ *-zeroʳ m ⟩0 ≡⟨ ⊓-zeroʳ (m * suc n) ⟨(m * suc n) ⊓ 0 ≡⟨ cong (m * suc n ⊓_) (*-zeroʳ m) ⟨(m * suc n) ⊓ (m * 0) ∎*-distribˡ-⊓ m (suc n) (suc o) = begin-equalitym * (suc n ⊓ suc o) ≡⟨⟩m * suc (n ⊓ o) ≡⟨ *-suc m (n ⊓ o) ⟩m + m * (n ⊓ o) ≡⟨ cong (m +_) (*-distribˡ-⊓ m n o) ⟩m + (m * n) ⊓ (m * o) ≡⟨ +-distribˡ-⊓ m (m * n) (m * o) ⟩(m + m * n) ⊓ (m + m * o) ≡⟨ cong₂ _⊓_ (*-suc m n) (*-suc m o) ⟨(m * suc n) ⊓ (m * suc o) ∎*-distribʳ-⊓ : _*_ DistributesOverʳ _⊓_*-distribʳ-⊓ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-⊓*-distrib-⊓ : _*_ DistributesOver _⊓_*-distrib-⊓ = *-distribˡ-⊓ , *-distribʳ-⊓-------------------------------------------------------------------------- Properties of _∸_------------------------------------------------------------------------0∸n≡0 : LeftZero zero _∸_0∸n≡0 zero = refl0∸n≡0 (suc _) = refln∸n≡0 : ∀ n → n ∸ n ≡ 0n∸n≡0 zero = refln∸n≡0 (suc n) = n∸n≡0 n-------------------------------------------------------------------------- Properties of _∸_ and predpred[m∸n]≡m∸[1+n] : ∀ m n → pred (m ∸ n) ≡ m ∸ suc npred[m∸n]≡m∸[1+n] zero zero = reflpred[m∸n]≡m∸[1+n] (suc m) zero = reflpred[m∸n]≡m∸[1+n] zero (suc n) = reflpred[m∸n]≡m∸[1+n] (suc m) (suc n) = pred[m∸n]≡m∸[1+n] m n-------------------------------------------------------------------------- Properties of _∸_ and _≤_/_<_m∸n≤m : ∀ m n → m ∸ n ≤ mm∸n≤m n zero = ≤-reflm∸n≤m zero (suc n) = ≤-reflm∸n≤m (suc m) (suc n) = ≤-trans (m∸n≤m m n) (n≤1+n m)m≮m∸n : ∀ m n → m ≮ m ∸ nm≮m∸n m zero = n≮n mm≮m∸n (suc m) (suc n) = m≮m∸n m n ∘ ≤-trans (n≤1+n (suc m))1+m≢m∸n : ∀ {m} n → suc m ≢ m ∸ n1+m≢m∸n {m} n eq = m≮m∸n m n (≤-reflexive eq)∸-mono : _∸_ Preserves₂ _≤_ ⟶ _≥_ ⟶ _≤_∸-mono z≤n (s≤s n₁≥n₂) = z≤n∸-mono (s≤s m₁≤m₂) (s≤s n₁≥n₂) = ∸-mono m₁≤m₂ n₁≥n₂∸-mono m₁≤m₂ (z≤n {n = n₁}) = ≤-trans (m∸n≤m _ n₁) m₁≤m₂∸-monoˡ-≤ : ∀ o → m ≤ n → m ∸ o ≤ n ∸ o∸-monoˡ-≤ o m≤n = ∸-mono {u = o} m≤n ≤-refl∸-monoʳ-≤ : ∀ o → m ≤ n → o ∸ m ≥ o ∸ n∸-monoʳ-≤ _ m≤n = ∸-mono ≤-refl m≤n∸-monoˡ-< : ∀ {m n o} → m < o → n ≤ m → m ∸ n < o ∸ n∸-monoˡ-< {m} {zero} {o} m<o n≤m = m<o∸-monoˡ-< {suc m} {suc n} {suc o} (s≤s m<o) (s≤s n≤m) = ∸-monoˡ-< m<o n≤m∸-monoʳ-< : ∀ {m n o} → o < n → n ≤ m → m ∸ n < m ∸ o∸-monoʳ-< {n = suc n} {zero} (s≤s o<n) (s≤s n<m) = s≤s (m∸n≤m _ n)∸-monoʳ-< {n = suc n} {suc o} (s≤s o<n) (s≤s n<m) = ∸-monoʳ-< o<n n<m∸-cancelʳ-≤ : ∀ {m n o} → m ≤ o → o ∸ n ≤ o ∸ m → m ≤ n∸-cancelʳ-≤ {_} {_} z≤n _ = z≤n∸-cancelʳ-≤ {suc m} {zero} (s≤s _) o<o∸m = contradiction o<o∸m (m≮m∸n _ m)∸-cancelʳ-≤ {suc m} {suc n} (s≤s m≤o) o∸n<o∸m = s≤s (∸-cancelʳ-≤ m≤o o∸n<o∸m)∸-cancelʳ-< : ∀ {m n o} → o ∸ m < o ∸ n → n < m∸-cancelʳ-< {zero} {n} {o} o<o∸n = contradiction o<o∸n (m≮m∸n o n)∸-cancelʳ-< {suc m} {zero} {_} o∸n<o∸m = 0<1+n∸-cancelʳ-< {suc m} {suc n} {suc o} o∸n<o∸m = s≤s (∸-cancelʳ-< o∸n<o∸m)∸-cancelˡ-≡ : n ≤ m → o ≤ m → m ∸ n ≡ m ∸ o → n ≡ o∸-cancelˡ-≡ {_} z≤n z≤n _ = refl∸-cancelˡ-≡ {o = suc o} z≤n (s≤s _) eq = contradiction eq (1+m≢m∸n o)∸-cancelˡ-≡ {n = suc n} (s≤s _) z≤n eq = contradiction (sym eq) (1+m≢m∸n n)∸-cancelˡ-≡ {_} (s≤s n≤m) (s≤s o≤m) eq = cong suc (∸-cancelˡ-≡ n≤m o≤m eq)∸-cancelʳ-≡ : o ≤ m → o ≤ n → m ∸ o ≡ n ∸ o → m ≡ n∸-cancelʳ-≡ z≤n z≤n eq = eq∸-cancelʳ-≡ (s≤s o≤m) (s≤s o≤n) eq = cong suc (∸-cancelʳ-≡ o≤m o≤n eq)m∸n≡0⇒m≤n : m ∸ n ≡ 0 → m ≤ nm∸n≡0⇒m≤n {zero} {_} _ = z≤nm∸n≡0⇒m≤n {suc m} {suc n} eq = s≤s (m∸n≡0⇒m≤n eq)m≤n⇒m∸n≡0 : m ≤ n → m ∸ n ≡ 0m≤n⇒m∸n≡0 {n = n} z≤n = 0∸n≡0 nm≤n⇒m∸n≡0 {_} (s≤s m≤n) = m≤n⇒m∸n≡0 m≤nm<n⇒0<n∸m : m < n → 0 < n ∸ mm<n⇒0<n∸m {zero} {suc n} _ = 0<1+nm<n⇒0<n∸m {suc m} {suc n} (s≤s m<n) = m<n⇒0<n∸m m<nm∸n≢0⇒n<m : m ∸ n ≢ 0 → n < mm∸n≢0⇒n<m {m} {n} m∸n≢0 with n <? m... | yes n<m = n<m... | no n≮m = contradiction (m≤n⇒m∸n≡0 (≮⇒≥ n≮m)) m∸n≢0m>n⇒m∸n≢0 : m > n → m ∸ n ≢ 0m>n⇒m∸n≢0 {n = suc n} (s≤s m>n) = m>n⇒m∸n≢0 m>nm≤n⇒n∸m≤n : m ≤ n → n ∸ m ≤ nm≤n⇒n∸m≤n z≤n = ≤-reflm≤n⇒n∸m≤n (s≤s m≤n) = m≤n⇒m≤1+n (m≤n⇒n∸m≤n m≤n)-------------------------------------------------------------------------- Properties of _∸_ and _+_+-∸-comm : ∀ {m} n {o} → o ≤ m → (m + n) ∸ o ≡ (m ∸ o) + n+-∸-comm {zero} _ {zero} _ = refl+-∸-comm {suc m} _ {zero} _ = refl+-∸-comm {suc m} n {suc o} (s≤s o≤m) = +-∸-comm n o≤m∸-+-assoc : ∀ m n o → (m ∸ n) ∸ o ≡ m ∸ (n + o)∸-+-assoc zero zero o = refl∸-+-assoc zero (suc n) o = 0∸n≡0 o∸-+-assoc (suc m) zero o = refl∸-+-assoc (suc m) (suc n) o = ∸-+-assoc m n o+-∸-assoc : ∀ m {n o} → o ≤ n → (m + n) ∸ o ≡ m + (n ∸ o)+-∸-assoc m (z≤n {n = n}) = begin-equality m + n ∎+-∸-assoc m (s≤s {m = o} {n = n} o≤n) = begin-equality(m + suc n) ∸ suc o ≡⟨ cong (_∸ suc o) (+-suc m n) ⟩suc (m + n) ∸ suc o ≡⟨⟩(m + n) ∸ o ≡⟨ +-∸-assoc m o≤n ⟩m + (n ∸ o) ∎m≤n+o⇒m∸n≤o : ∀ m n {o} → m ≤ n + o → m ∸ n ≤ om≤n+o⇒m∸n≤o m zero le = lem≤n+o⇒m∸n≤o zero (suc n) _ = z≤nm≤n+o⇒m∸n≤o (suc m) (suc n) le = m≤n+o⇒m∸n≤o m n (s≤s⁻¹ le)m<n+o⇒m∸n<o : ∀ m n {o} → .{{NonZero o}} → m < n + o → m ∸ n < om<n+o⇒m∸n<o m zero lt = ltm<n+o⇒m∸n<o zero (suc n) {o@(suc _)} lt = z<sm<n+o⇒m∸n<o (suc m) (suc n) lt = m<n+o⇒m∸n<o m n (s<s⁻¹ lt)m+n≤o⇒m≤o∸n : ∀ m {n o} → m + n ≤ o → m ≤ o ∸ nm+n≤o⇒m≤o∸n zero le = z≤nm+n≤o⇒m≤o∸n (suc m) (s≤s le)rewrite +-∸-assoc 1 (m+n≤o⇒n≤o m le) = s≤s (m+n≤o⇒m≤o∸n m le)m≤o∸n⇒m+n≤o : ∀ m {n o} (n≤o : n ≤ o) → m ≤ o ∸ n → m + n ≤ om≤o∸n⇒m+n≤o m z≤n le rewrite +-identityʳ m = lem≤o∸n⇒m+n≤o m {suc n} (s≤s n≤o) le rewrite +-suc m n = s≤s (m≤o∸n⇒m+n≤o m n≤o le)m≤n+m∸n : ∀ m n → m ≤ n + (m ∸ n)m≤n+m∸n zero n = z≤nm≤n+m∸n (suc m) zero = ≤-reflm≤n+m∸n (suc m) (suc n) = s≤s (m≤n+m∸n m n)m+n∸n≡m : ∀ m n → m + n ∸ n ≡ mm+n∸n≡m m n = begin-equality(m + n) ∸ n ≡⟨ +-∸-assoc m (≤-refl {x = n}) ⟩m + (n ∸ n) ≡⟨ cong (m +_) (n∸n≡0 n) ⟩m + 0 ≡⟨ +-identityʳ m ⟩m ∎m+n∸m≡n : ∀ m n → m + n ∸ m ≡ nm+n∸m≡n m n = trans (cong (_∸ m) (+-comm m n)) (m+n∸n≡m n m)m+[n∸m]≡n : m ≤ n → m + (n ∸ m) ≡ nm+[n∸m]≡n {m} {n} m≤n = begin-equalitym + (n ∸ m) ≡⟨ sym $ +-∸-assoc m m≤n ⟩(m + n) ∸ m ≡⟨ cong (_∸ m) (+-comm m n) ⟩(n + m) ∸ m ≡⟨ m+n∸n≡m n m ⟩n ∎m∸n+n≡m : ∀ {m n} → n ≤ m → (m ∸ n) + n ≡ mm∸n+n≡m {m} {n} n≤m = begin-equality(m ∸ n) + n ≡⟨ sym (+-∸-comm n n≤m) ⟩(m + n) ∸ n ≡⟨ m+n∸n≡m m n ⟩m ∎m∸[m∸n]≡n : ∀ {m n} → n ≤ m → m ∸ (m ∸ n) ≡ nm∸[m∸n]≡n {m} {_} z≤n = n∸n≡0 mm∸[m∸n]≡n {suc m} {suc n} (s≤s n≤m) = begin-equalitysuc m ∸ (m ∸ n) ≡⟨ +-∸-assoc 1 (m∸n≤m m n) ⟩suc (m ∸ (m ∸ n)) ≡⟨ cong suc (m∸[m∸n]≡n n≤m) ⟩suc n ∎[m+n]∸[m+o]≡n∸o : ∀ m n o → (m + n) ∸ (m + o) ≡ n ∸ o[m+n]∸[m+o]≡n∸o zero n o = refl[m+n]∸[m+o]≡n∸o (suc m) n o = [m+n]∸[m+o]≡n∸o m n o-------------------------------------------------------------------------- Properties of _∸_ and _*_*-distribʳ-∸ : _*_ DistributesOverʳ _∸_*-distribʳ-∸ m zero zero = refl*-distribʳ-∸ zero zero (suc o) = sym (0∸n≡0 (o * zero))*-distribʳ-∸ (suc m) zero (suc o) = refl*-distribʳ-∸ m (suc n) zero = refl*-distribʳ-∸ m (suc n) (suc o) = begin-equality(n ∸ o) * m ≡⟨ *-distribʳ-∸ m n o ⟩n * m ∸ o * m ≡⟨ sym $ [m+n]∸[m+o]≡n∸o m _ _ ⟩m + n * m ∸ (m + o * m) ∎*-distribˡ-∸ : _*_ DistributesOverˡ _∸_*-distribˡ-∸ = comm∧distrʳ⇒distrˡ *-comm *-distribʳ-∸*-distrib-∸ : _*_ DistributesOver _∸_*-distrib-∸ = *-distribˡ-∸ , *-distribʳ-∸even≢odd : ∀ m n → 2 * m ≢ suc (2 * n)even≢odd (suc m) zero eq = contradiction (suc-injective eq) (m+1+n≢0 m)even≢odd (suc m) (suc n) eq = even≢odd m n (suc-injective (begin-equalitysuc (2 * m) ≡⟨ sym (+-suc m _) ⟩m + suc (m + 0) ≡⟨ suc-injective eq ⟩suc n + suc (n + 0) ≡⟨ cong suc (+-suc n _) ⟩suc (suc (2 * n)) ∎))-------------------------------------------------------------------------- Properties of _∸_ and _⊓_ and _⊔_m⊓n+n∸m≡n : ∀ m n → (m ⊓ n) + (n ∸ m) ≡ nm⊓n+n∸m≡n zero n = reflm⊓n+n∸m≡n (suc m) zero = reflm⊓n+n∸m≡n (suc m) (suc n) = cong suc $ m⊓n+n∸m≡n m n[m∸n]⊓[n∸m]≡0 : ∀ m n → (m ∸ n) ⊓ (n ∸ m) ≡ 0[m∸n]⊓[n∸m]≡0 zero zero = refl[m∸n]⊓[n∸m]≡0 zero (suc n) = refl[m∸n]⊓[n∸m]≡0 (suc m) zero = refl[m∸n]⊓[n∸m]≡0 (suc m) (suc n) = [m∸n]⊓[n∸m]≡0 m n∸-distribˡ-⊓-⊔ : ∀ m n o → m ∸ (n ⊓ o) ≡ (m ∸ n) ⊔ (m ∸ o)∸-distribˡ-⊓-⊔ m n o = antimono-≤-distrib-⊓ (∸-monoʳ-≤ m) n o∸-distribʳ-⊓ : _∸_ DistributesOverʳ _⊓_∸-distribʳ-⊓ m n o = mono-≤-distrib-⊓ (∸-monoˡ-≤ m) n o∸-distribˡ-⊔-⊓ : ∀ m n o → m ∸ (n ⊔ o) ≡ (m ∸ n) ⊓ (m ∸ o)∸-distribˡ-⊔-⊓ m n o = antimono-≤-distrib-⊔ (∸-monoʳ-≤ m) n o∸-distribʳ-⊔ : _∸_ DistributesOverʳ _⊔_∸-distribʳ-⊔ m n o = mono-≤-distrib-⊔ (∸-monoˡ-≤ m) n o-------------------------------------------------------------------------- Properties of pred------------------------------------------------------------------------pred[n]≤n : pred n ≤ npred[n]≤n {zero} = z≤npred[n]≤n {suc n} = n≤1+n n≤pred⇒≤ : m ≤ pred n → m ≤ n≤pred⇒≤ {n = zero} le = le≤pred⇒≤ {n = suc n} le = m≤n⇒m≤1+n le≤⇒pred≤ : m ≤ n → pred m ≤ n≤⇒pred≤ {zero} le = le≤⇒pred≤ {suc m} le = ≤-trans (n≤1+n m) le<⇒≤pred : m < n → m ≤ pred n<⇒≤pred (s≤s le) = lesuc-pred : ∀ n .{{_ : NonZero n}} → suc (pred n) ≡ nsuc-pred (suc n) = reflpred-mono-≤ : pred Preserves _≤_ ⟶ _≤_pred-mono-≤ {zero} _ = z≤npred-mono-≤ {suc _} {suc _} m≤n = s≤s⁻¹ m≤npred-mono-< : .{{NonZero m}} → m < n → pred m < pred npred-mono-< {m = suc _} {n = suc _} = s<s⁻¹pred-cancel-≤ : pred m ≤ pred n → (m ≡ 1 × n ≡ 0) ⊎ m ≤ npred-cancel-≤ {m = zero} {n = zero} _ = inj₂ z≤npred-cancel-≤ {m = zero} {n = suc _} _ = inj₂ z≤npred-cancel-≤ {m = suc _} {n = zero} z≤n = inj₁ (refl , refl)pred-cancel-≤ {m = suc _} {n = suc _} le = inj₂ (s≤s le)pred-cancel-< : pred m < pred n → m < npred-cancel-< {m = zero} {n = suc _} _ = z<spred-cancel-< {m = suc _} {n = suc _} = s<spred-injective : .{{NonZero m}} → .{{NonZero n}} → pred m ≡ pred n → m ≡ npred-injective {suc m} {suc n} = cong sucpred-cancel-≡ : pred m ≡ pred n → ((m ≡ 0 × n ≡ 1) ⊎ (m ≡ 1 × n ≡ 0)) ⊎ m ≡ npred-cancel-≡ {m = zero} {n = zero} _ = inj₂ reflpred-cancel-≡ {m = zero} {n = suc _} refl = inj₁ (inj₁ (refl , refl))pred-cancel-≡ {m = suc _} {n = zero} refl = inj₁ (inj₂ (refl , refl))pred-cancel-≡ {m = suc _} {n = suc _} = inj₂ ∘ pred-injective-------------------------------------------------------------------------- Properties of ∣_-_∣-------------------------------------------------------------------------------------------------------------------------------------------------- Basicm≡n⇒∣m-n∣≡0 : m ≡ n → ∣ m - n ∣ ≡ 0m≡n⇒∣m-n∣≡0 {zero} refl = reflm≡n⇒∣m-n∣≡0 {suc m} refl = m≡n⇒∣m-n∣≡0 {m} refl∣m-n∣≡0⇒m≡n : ∣ m - n ∣ ≡ 0 → m ≡ n∣m-n∣≡0⇒m≡n {zero} {zero} eq = refl∣m-n∣≡0⇒m≡n {suc m} {suc n} eq = cong suc (∣m-n∣≡0⇒m≡n eq)m≤n⇒∣n-m∣≡n∸m : m ≤ n → ∣ n - m ∣ ≡ n ∸ mm≤n⇒∣n-m∣≡n∸m {n = zero} z≤n = reflm≤n⇒∣n-m∣≡n∸m {n = suc n} z≤n = reflm≤n⇒∣n-m∣≡n∸m {n = _} (s≤s m≤n) = m≤n⇒∣n-m∣≡n∸m m≤nm≤n⇒∣m-n∣≡n∸m : m ≤ n → ∣ m - n ∣ ≡ n ∸ mm≤n⇒∣m-n∣≡n∸m {n = zero} z≤n = reflm≤n⇒∣m-n∣≡n∸m {n = suc n} z≤n = reflm≤n⇒∣m-n∣≡n∸m {n = _} (s≤s m≤n) = m≤n⇒∣m-n∣≡n∸m m≤n∣m-n∣≡m∸n⇒n≤m : ∣ m - n ∣ ≡ m ∸ n → n ≤ m∣m-n∣≡m∸n⇒n≤m {zero} {zero} eq = z≤n∣m-n∣≡m∸n⇒n≤m {suc m} {zero} eq = z≤n∣m-n∣≡m∸n⇒n≤m {suc m} {suc n} eq = s≤s (∣m-n∣≡m∸n⇒n≤m eq)∣n-n∣≡0 : ∀ n → ∣ n - n ∣ ≡ 0∣n-n∣≡0 n = m≡n⇒∣m-n∣≡0 {n} refl∣m-m+n∣≡n : ∀ m n → ∣ m - m + n ∣ ≡ n∣m-m+n∣≡n zero n = refl∣m-m+n∣≡n (suc m) n = ∣m-m+n∣≡n m n∣m+n-m+o∣≡∣n-o∣ : ∀ m n o → ∣ m + n - m + o ∣ ≡ ∣ n - o ∣∣m+n-m+o∣≡∣n-o∣ zero n o = refl∣m+n-m+o∣≡∣n-o∣ (suc m) n o = ∣m+n-m+o∣≡∣n-o∣ m n om∸n≤∣m-n∣ : ∀ m n → m ∸ n ≤ ∣ m - n ∣m∸n≤∣m-n∣ m n with ≤-total m n... | inj₁ m≤n = subst (_≤ ∣ m - n ∣) (sym (m≤n⇒m∸n≡0 m≤n)) z≤n... | inj₂ n≤m = subst (m ∸ n ≤_) (sym (m≤n⇒∣n-m∣≡n∸m n≤m)) ≤-refl∣m-n∣≤m⊔n : ∀ m n → ∣ m - n ∣ ≤ m ⊔ n∣m-n∣≤m⊔n zero m = ≤-refl∣m-n∣≤m⊔n (suc m) zero = ≤-refl∣m-n∣≤m⊔n (suc m) (suc n) = m≤n⇒m≤1+n (∣m-n∣≤m⊔n m n)∣-∣-identityˡ : LeftIdentity 0 ∣_-_∣∣-∣-identityˡ x = refl∣-∣-identityʳ : RightIdentity 0 ∣_-_∣∣-∣-identityʳ zero = refl∣-∣-identityʳ (suc x) = refl∣-∣-identity : Identity 0 ∣_-_∣∣-∣-identity = ∣-∣-identityˡ , ∣-∣-identityʳ∣-∣-comm : Commutative ∣_-_∣∣-∣-comm zero zero = refl∣-∣-comm zero (suc n) = refl∣-∣-comm (suc m) zero = refl∣-∣-comm (suc m) (suc n) = ∣-∣-comm m n∣m-n∣≡[m∸n]∨[n∸m] : ∀ m n → (∣ m - n ∣ ≡ m ∸ n) ⊎ (∣ m - n ∣ ≡ n ∸ m)∣m-n∣≡[m∸n]∨[n∸m] m n with ≤-total m n... | inj₂ n≤m = inj₁ $ m≤n⇒∣n-m∣≡n∸m n≤m... | inj₁ m≤n = inj₂ $ begin-equality∣ m - n ∣ ≡⟨ ∣-∣-comm m n ⟩∣ n - m ∣ ≡⟨ m≤n⇒∣n-m∣≡n∸m m≤n ⟩n ∸ m ∎private*-distribˡ-∣-∣-aux : ∀ a m n → m ≤ n → a * ∣ n - m ∣ ≡ ∣ a * n - a * m ∣*-distribˡ-∣-∣-aux a m n m≤n = begin-equalitya * ∣ n - m ∣ ≡⟨ cong (a *_) (m≤n⇒∣n-m∣≡n∸m m≤n) ⟩a * (n ∸ m) ≡⟨ *-distribˡ-∸ a n m ⟩a * n ∸ a * m ≡⟨ sym $′ m≤n⇒∣n-m∣≡n∸m (*-monoʳ-≤ a m≤n) ⟩∣ a * n - a * m ∣ ∎*-distribˡ-∣-∣ : _*_ DistributesOverˡ ∣_-_∣*-distribˡ-∣-∣ a m n with ≤-total m n... | inj₂ n≤m = *-distribˡ-∣-∣-aux a n m n≤m... | inj₁ m≤n = begin-equalitya * ∣ m - n ∣ ≡⟨ cong (a *_) (∣-∣-comm m n) ⟩a * ∣ n - m ∣ ≡⟨ *-distribˡ-∣-∣-aux a m n m≤n ⟩∣ a * n - a * m ∣ ≡⟨ ∣-∣-comm (a * n) (a * m) ⟩∣ a * m - a * n ∣ ∎*-distribʳ-∣-∣ : _*_ DistributesOverʳ ∣_-_∣*-distribʳ-∣-∣ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-∣-∣*-distrib-∣-∣ : _*_ DistributesOver ∣_-_∣*-distrib-∣-∣ = *-distribˡ-∣-∣ , *-distribʳ-∣-∣m≤n+∣n-m∣ : ∀ m n → m ≤ n + ∣ n - m ∣m≤n+∣n-m∣ zero n = z≤nm≤n+∣n-m∣ (suc m) zero = ≤-reflm≤n+∣n-m∣ (suc m) (suc n) = s≤s (m≤n+∣n-m∣ m n)m≤n+∣m-n∣ : ∀ m n → m ≤ n + ∣ m - n ∣m≤n+∣m-n∣ m n = subst (m ≤_) (cong (n +_) (∣-∣-comm n m)) (m≤n+∣n-m∣ m n)m≤∣m-n∣+n : ∀ m n → m ≤ ∣ m - n ∣ + nm≤∣m-n∣+n m n = subst (m ≤_) (+-comm n _) (m≤n+∣m-n∣ m n)∣-∣-triangle : TriangleInequality ∣_-_∣∣-∣-triangle zero y z = m≤n+∣n-m∣ z y∣-∣-triangle x zero z = begin∣ x - z ∣ ≤⟨ ∣m-n∣≤m⊔n x z ⟩x ⊔ z ≤⟨ m⊔n≤m+n x z ⟩x + z ≡⟨ cong₂ _+_ (sym (∣-∣-identityʳ x)) refl ⟩∣ x - 0 ∣ + z ∎where open ≤-Reasoning∣-∣-triangle x y zero = begin∣ x - 0 ∣ ≡⟨ ∣-∣-identityʳ x ⟩x ≤⟨ m≤∣m-n∣+n x y ⟩∣ x - y ∣ + y ≡⟨ cong₂ _+_ refl (sym (∣-∣-identityʳ y)) ⟩∣ x - y ∣ + ∣ y - 0 ∣ ∎where open ≤-Reasoning∣-∣-triangle (suc x) (suc y) (suc z) = ∣-∣-triangle x y z∣-∣≡∣-∣′ : ∀ m n → ∣ m - n ∣ ≡ ∣ m - n ∣′∣-∣≡∣-∣′ m n with m <ᵇ n in eq... | false = m≤n⇒∣n-m∣≡n∸m {n} {m} (≮⇒≥ (λ m<n → subst T eq (<⇒<ᵇ m<n)))... | true = m≤n⇒∣m-n∣≡n∸m {m} {n} (<⇒≤ (<ᵇ⇒< m n (subst T (sym eq) _)))-------------------------------------------------------------------------- Metric structures∣-∣-isProtoMetric : IsProtoMetric _≡_ ∣_-_∣∣-∣-isProtoMetric = record{ isPartialOrder = ≤-isPartialOrder; ≈-isEquivalence = isEquivalence; cong = cong₂ ∣_-_∣; nonNegative = z≤n}∣-∣-isPreMetric : IsPreMetric _≡_ ∣_-_∣∣-∣-isPreMetric = record{ isProtoMetric = ∣-∣-isProtoMetric; ≈⇒0 = m≡n⇒∣m-n∣≡0}∣-∣-isQuasiSemiMetric : IsQuasiSemiMetric _≡_ ∣_-_∣∣-∣-isQuasiSemiMetric = record{ isPreMetric = ∣-∣-isPreMetric; 0⇒≈ = ∣m-n∣≡0⇒m≡n}∣-∣-isSemiMetric : IsSemiMetric _≡_ ∣_-_∣∣-∣-isSemiMetric = record{ isQuasiSemiMetric = ∣-∣-isQuasiSemiMetric; sym = ∣-∣-comm}∣-∣-isMetric : IsMetric _≡_ ∣_-_∣∣-∣-isMetric = record{ isSemiMetric = ∣-∣-isSemiMetric; triangle = ∣-∣-triangle}-------------------------------------------------------------------------- Metric bundles∣-∣-quasiSemiMetric : QuasiSemiMetric 0ℓ 0ℓ∣-∣-quasiSemiMetric = record{ isQuasiSemiMetric = ∣-∣-isQuasiSemiMetric}∣-∣-semiMetric : SemiMetric 0ℓ 0ℓ∣-∣-semiMetric = record{ isSemiMetric = ∣-∣-isSemiMetric}∣-∣-preMetric : PreMetric 0ℓ 0ℓ∣-∣-preMetric = record{ isPreMetric = ∣-∣-isPreMetric}∣-∣-metric : Metric 0ℓ 0ℓ∣-∣-metric = record{ isMetric = ∣-∣-isMetric}-------------------------------------------------------------------------- Properties of ⌊_/2⌋ and ⌈_/2⌉------------------------------------------------------------------------⌊n/2⌋-mono : ⌊_/2⌋ Preserves _≤_ ⟶ _≤_⌊n/2⌋-mono z≤n = z≤n⌊n/2⌋-mono (s≤s z≤n) = z≤n⌊n/2⌋-mono (s≤s (s≤s m≤n)) = s≤s (⌊n/2⌋-mono m≤n)⌈n/2⌉-mono : ⌈_/2⌉ Preserves _≤_ ⟶ _≤_⌈n/2⌉-mono m≤n = ⌊n/2⌋-mono (s≤s m≤n)⌊n/2⌋≤⌈n/2⌉ : ∀ n → ⌊ n /2⌋ ≤ ⌈ n /2⌉⌊n/2⌋≤⌈n/2⌉ zero = z≤n⌊n/2⌋≤⌈n/2⌉ (suc zero) = z≤n⌊n/2⌋≤⌈n/2⌉ (suc (suc n)) = s≤s (⌊n/2⌋≤⌈n/2⌉ n)⌊n/2⌋+⌈n/2⌉≡n : ∀ n → ⌊ n /2⌋ + ⌈ n /2⌉ ≡ n⌊n/2⌋+⌈n/2⌉≡n zero = refl⌊n/2⌋+⌈n/2⌉≡n (suc n) = begin-equality⌊ suc n /2⌋ + suc ⌊ n /2⌋ ≡⟨ +-comm ⌊ suc n /2⌋ (suc ⌊ n /2⌋) ⟩suc ⌊ n /2⌋ + ⌊ suc n /2⌋ ≡⟨⟩suc (⌊ n /2⌋ + ⌊ suc n /2⌋) ≡⟨ cong suc (⌊n/2⌋+⌈n/2⌉≡n n) ⟩suc n ∎⌊n/2⌋≤n : ∀ n → ⌊ n /2⌋ ≤ n⌊n/2⌋≤n zero = z≤n⌊n/2⌋≤n (suc zero) = z≤n⌊n/2⌋≤n (suc (suc n)) = s≤s (m≤n⇒m≤1+n (⌊n/2⌋≤n n))⌊n/2⌋<n : ∀ n → ⌊ suc n /2⌋ < suc n⌊n/2⌋<n zero = z<s⌊n/2⌋<n (suc n) = s<s (s≤s (⌊n/2⌋≤n n))n≡⌊n+n/2⌋ : ∀ n → n ≡ ⌊ n + n /2⌋n≡⌊n+n/2⌋ zero = refln≡⌊n+n/2⌋ (suc zero) = refln≡⌊n+n/2⌋ (suc n′@(suc n)) =cong suc (trans (n≡⌊n+n/2⌋ _) (cong ⌊_/2⌋ (sym (+-suc n n′))))⌈n/2⌉≤n : ∀ n → ⌈ n /2⌉ ≤ n⌈n/2⌉≤n zero = z≤n⌈n/2⌉≤n (suc n) = s≤s (⌊n/2⌋≤n n)⌈n/2⌉<n : ∀ n → ⌈ suc (suc n) /2⌉ < suc (suc n)⌈n/2⌉<n n = s<s (⌊n/2⌋<n n)n≡⌈n+n/2⌉ : ∀ n → n ≡ ⌈ n + n /2⌉n≡⌈n+n/2⌉ zero = refln≡⌈n+n/2⌉ (suc zero) = refln≡⌈n+n/2⌉ (suc n′@(suc n)) =cong suc (trans (n≡⌈n+n/2⌉ _) (cong ⌈_/2⌉ (sym (+-suc n n′))))-------------------------------------------------------------------------- Properties of !_1≤n! : ∀ n → 1 ≤ n !1≤n! zero = ≤-refl1≤n! (suc n) = *-mono-≤ (m≤m+n 1 n) (1≤n! n)infix 4 _!≢0 _!*_!≢0_!≢0 : ∀ n → NonZero (n !)n !≢0 = >-nonZero (1≤n! n)_!*_!≢0 : ∀ m n → NonZero (m ! * n !)m !* n !≢0 = m*n≢0 _ _ {{m !≢0}} {{n !≢0}}-------------------------------------------------------------------------- Properties of _≤′_ and _<′_≤′-trans : Transitive _≤′_≤′-trans m≤n ≤′-refl = m≤n≤′-trans m≤n (≤′-step n≤o) = ≤′-step (≤′-trans m≤n n≤o)z≤′n : zero ≤′ nz≤′n {zero} = ≤′-reflz≤′n {suc n} = ≤′-step z≤′ns≤′s : m ≤′ n → suc m ≤′ suc ns≤′s ≤′-refl = ≤′-refls≤′s (≤′-step m≤′n) = ≤′-step (s≤′s m≤′n)≤′⇒≤ : _≤′_ ⇒ _≤_≤′⇒≤ ≤′-refl = ≤-refl≤′⇒≤ (≤′-step m≤′n) = m≤n⇒m≤1+n (≤′⇒≤ m≤′n)≤⇒≤′ : _≤_ ⇒ _≤′_≤⇒≤′ z≤n = z≤′n≤⇒≤′ (s≤s m≤n) = s≤′s (≤⇒≤′ m≤n)≤′-step-injective : {p q : m ≤′ n} → ≤′-step p ≡ ≤′-step q → p ≡ q≤′-step-injective refl = refl-------------------------------------------------------------------------- Properties of _<′_ and _<_------------------------------------------------------------------------z<′s : zero <′ suc nz<′s {zero} = <′-basez<′s {suc n} = <′-step (z<′s {n})s<′s : m <′ n → suc m <′ suc ns<′s <′-base = <′-bases<′s (<′-step m<′n) = <′-step (s<′s m<′n)<⇒<′ : m < n → m <′ n<⇒<′ z<s = z<′s<⇒<′ (s<s m<n@(s≤s _)) = s<′s (<⇒<′ m<n)<′⇒< : m <′ n → m < n<′⇒< <′-base = n<1+n _<′⇒< (<′-step m<′n) = m<n⇒m<1+n (<′⇒< m<′n)m<1+n⇒m<n∨m≡n′ : m < suc n → m < n ⊎ m ≡ nm<1+n⇒m<n∨m≡n′ m<n with <⇒<′ m<n... | <′-base = inj₂ refl... | <′-step m<′n = inj₁ (<′⇒< m<′n)-------------------------------------------------------------------------- Other properties of _≤′_ and _<′_------------------------------------------------------------------------infix 4 _≤′?_ _<′?_ _≥′?_ _>′?__≤′?_ : Decidable _≤′_m ≤′? n = map′ ≤⇒≤′ ≤′⇒≤ (m ≤? n)_<′?_ : Decidable _<′_m <′? n = suc m ≤′? n_≥′?_ : Decidable _≥′__≥′?_ = flip _≤′?__>′?_ : Decidable _>′__>′?_ = flip _<′?_m≤′m+n : ∀ m n → m ≤′ m + nm≤′m+n m n = ≤⇒≤′ (m≤m+n m n)n≤′m+n : ∀ m n → n ≤′ m + nn≤′m+n zero n = ≤′-refln≤′m+n (suc m) n = ≤′-step (n≤′m+n m n)⌈n/2⌉≤′n : ∀ n → ⌈ n /2⌉ ≤′ n⌈n/2⌉≤′n zero = ≤′-refl⌈n/2⌉≤′n (suc zero) = ≤′-refl⌈n/2⌉≤′n (suc (suc n)) = s≤′s (≤′-step (⌈n/2⌉≤′n n))⌊n/2⌋≤′n : ∀ n → ⌊ n /2⌋ ≤′ n⌊n/2⌋≤′n zero = ≤′-refl⌊n/2⌋≤′n (suc n) = ≤′-step (⌈n/2⌉≤′n n)-------------------------------------------------------------------------- Properties of _≤″_ and _<″_-------------------------------------------------------------------------- equivalence of _≤″_ to _≤_≤⇒≤″ : _≤_ ⇒ _≤″_≤⇒≤″ = (_ ,_) ∘ m+[n∸m]≡n<⇒<″ : _<_ ⇒ _<″_<⇒<″ = ≤⇒≤″≤″⇒≤ : _≤″_ ⇒ _≤_≤″⇒≤ (k , refl) = m≤m+n _ k-- equivalence to the old definition of _≤″_≤″-proof : (le : m ≤″ n) → let k , _ = le in m + k ≡ n≤″-proof (_ , prf) = prf-- yielding analogous proof for _≤_m≤n⇒∃[o]m+o≡n : .(m ≤ n) → ∃ λ k → m + k ≡ nm≤n⇒∃[o]m+o≡n m≤n = _ , m+[n∸m]≡n (recompute (_ ≤? _) m≤n)-- whose witness is equal to monusguarded-∸≗∸ : ∀ {m n} → .(m≤n : m ≤ n) →let k , _ = m≤n⇒∃[o]m+o≡n m≤n in k ≡ n ∸ mguarded-∸≗∸ m≤n = refl-- equivalence of _<″_ to _<ᵇ_m<ᵇn⇒1+m+[n-1+m]≡n : ∀ m n → T (m <ᵇ n) → suc m + (n ∸ suc m) ≡ nm<ᵇn⇒1+m+[n-1+m]≡n m n lt = m+[n∸m]≡n (<ᵇ⇒< m n lt)m<ᵇ1+m+n : ∀ m {n} → T (m <ᵇ suc (m + n))m<ᵇ1+m+n m = <⇒<ᵇ (m≤m+n (suc m) _)<ᵇ⇒<″ : T (m <ᵇ n) → m <″ n<ᵇ⇒<″ {m} {n} = <⇒<″ ∘ (<ᵇ⇒< m n)<″⇒<ᵇ : ∀ {m n} → m <″ n → T (m <ᵇ n)<″⇒<ᵇ {m} (k , refl) = <⇒<ᵇ (m≤m+n (suc m) k)-- NB: we use the builtin function `_<ᵇ_ : (m n : ℕ) → Bool` here so-- that the function quickly decides whether to return `yes` or `no`.-- It still takes a linear amount of time to generate the proof if it-- is inspected. We expect the main benefit to be visible for compiled-- code: the backend erases proofs.infix 4 _<″?_ _≤″?_ _≥″?_ _>″?__<″?_ : Decidable _<″_m <″? n = map′ <ᵇ⇒<″ <″⇒<ᵇ (T? (m <ᵇ n))_≤″?_ : Decidable _≤″_zero ≤″? n = yes (n , refl)suc m ≤″? n = m <″? n_≥″?_ : Decidable _≥″__≥″?_ = flip _≤″?__>″?_ : Decidable _>″__>″?_ = flip _<″?_≤″-irrelevant : Irrelevant _≤″_≤″-irrelevant {m} (_ , eq₁) (_ , eq₂)with refl ← +-cancelˡ-≡ m _ _ (trans eq₁ (sym eq₂))= cong (_ ,_) (≡-irrelevant eq₁ eq₂)<″-irrelevant : Irrelevant _<″_<″-irrelevant = ≤″-irrelevant>″-irrelevant : Irrelevant _>″_>″-irrelevant = ≤″-irrelevant≥″-irrelevant : Irrelevant _≥″_≥″-irrelevant = ≤″-irrelevant-------------------------------------------------------------------------- Properties of _≤‴_------------------------------------------------------------------------≤‴⇒≤″ : ∀{m n} → m ≤‴ n → m ≤″ n≤‴⇒≤″ {m = m} ≤‴-refl = 0 , +-identityʳ m≤‴⇒≤″ {m = m} (≤‴-step m≤n) = _ , trans (+-suc m _) (≤″-proof (≤‴⇒≤″ m≤n))m≤‴m+k : ∀{m n k} → m + k ≡ n → m ≤‴ nm≤‴m+k {m} {k = zero} refl = subst (λ z → m ≤‴ z) (sym (+-identityʳ m)) (≤‴-refl {m})m≤‴m+k {m} {k = suc k} prf = ≤‴-step (m≤‴m+k {k = k} (trans (sym (+-suc m _)) prf))≤″⇒≤‴ : ∀{m n} → m ≤″ n → m ≤‴ n≤″⇒≤‴ m≤n = m≤‴m+k (≤″-proof m≤n)0≤‴n : 0 ≤‴ n0≤‴n = m≤‴m+k refl<ᵇ⇒<‴ : T (m <ᵇ n) → m <‴ n<ᵇ⇒<‴ leq = ≤″⇒≤‴ (<ᵇ⇒<″ leq)<‴⇒<ᵇ : ∀ {m n} → m <‴ n → T (m <ᵇ n)<‴⇒<ᵇ leq = <″⇒<ᵇ (≤‴⇒≤″ leq)infix 4 _<‴?_ _≤‴?_ _≥‴?_ _>‴?__<‴?_ : Decidable _<‴_m <‴? n = map′ <ᵇ⇒<‴ <‴⇒<ᵇ (T? (m <ᵇ n))_≤‴?_ : Decidable _≤‴_zero ≤‴? n = yes 0≤‴nsuc m ≤‴? n = m <‴? n_≥‴?_ : Decidable _≥‴__≥‴?_ = flip _≤‴?__>‴?_ : Decidable _>‴__>‴?_ = flip _<‴?_≤⇒≤‴ : _≤_ ⇒ _≤‴_≤⇒≤‴ = ≤″⇒≤‴ ∘ ≤⇒≤″≤‴⇒≤ : _≤‴_ ⇒ _≤_≤‴⇒≤ = ≤″⇒≤ ∘ ≤‴⇒≤″-------------------------------------------------------------------------- Other properties-------------------------------------------------------------------------- If there is an injection from a type to ℕ, then the type has-- decidable equality.eq? : ∀ {a} {A : Set a} → A ↣ ℕ → DecidableEquality Aeq? inj = via-injection inj _≟_-- It's possible to decide existential and universal predicates up to-- a limit.module _ {p} {P : Pred ℕ p} (P? : U.Decidable P) whereanyUpTo? : ∀ v → Dec (∃ λ n → n < v × P n)anyUpTo? zero = no λ {(_ , () , _)}anyUpTo? (suc v) with P? v | anyUpTo? v... | yes Pv | _ = yes (v , ≤-refl , Pv)... | _ | yes (n , n<v , Pn) = yes (n , m≤n⇒m≤1+n n<v , Pn)... | no ¬Pv | no ¬Pn<v = no ¬Pn<1+vwhere¬Pn<1+v : ¬ (∃ λ n → n < suc v × P n)¬Pn<1+v (n , s≤s n≤v , Pn) with n ≟ v... | yes refl = ¬Pv Pn... | no n≢v = ¬Pn<v (n , ≤∧≢⇒< n≤v n≢v , Pn)allUpTo? : ∀ v → Dec (∀ {n} → n < v → P n)allUpTo? zero = yes λ()allUpTo? (suc v) with P? v | allUpTo? v... | no ¬Pv | _ = no λ prf → ¬Pv (prf ≤-refl)... | _ | no ¬Pn<v = no λ prf → ¬Pn<v (prf ∘ m≤n⇒m≤1+n)... | yes Pn | yes Pn<v = yes Pn<1+vwherePn<1+v : ∀ {n} → n < suc v → P nPn<1+v {n} (s≤s n≤v) with n ≟ v... | yes refl = Pn... | no n≢v = Pn<v (≤∧≢⇒< n≤v n≢v)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.3∀[m≤n⇒m≢o]⇒o<n : ∀ n o → (∀ {m} → m ≤ n → m ≢ o) → n < o∀[m≤n⇒m≢o]⇒o<n = ∀[m≤n⇒m≢o]⇒n<o{-# WARNING_ON_USAGE ∀[m≤n⇒m≢o]⇒o<n"Warning: ∀[m≤n⇒m≢o]⇒o<n was deprecated in v1.3.Please use ∀[m≤n⇒m≢o]⇒n<o instead."#-}∀[m<n⇒m≢o]⇒o≤n : ∀ n o → (∀ {m} → m < n → m ≢ o) → n ≤ o∀[m<n⇒m≢o]⇒o≤n = ∀[m<n⇒m≢o]⇒n≤o{-# WARNING_ON_USAGE ∀[m<n⇒m≢o]⇒o≤n"Warning: ∀[m<n⇒m≢o]⇒o≤n was deprecated in v1.3.Please use ∀[m<n⇒m≢o]⇒n≤o instead."#-}-- Version 1.4*-+-isSemiring = +-*-isSemiring{-# WARNING_ON_USAGE *-+-isSemiring"Warning: *-+-isSemiring was deprecated in v1.4.Please use +-*-isSemiring instead."#-}*-+-isCommutativeSemiring = +-*-isCommutativeSemiring{-# WARNING_ON_USAGE *-+-isCommutativeSemiring"Warning: *-+-isCommutativeSemiring was deprecated in v1.4.Please use +-*-isCommutativeSemiring instead."#-}*-+-semiring = +-*-semiring{-# WARNING_ON_USAGE *-+-semiring"Warning: *-+-semiring was deprecated in v1.4.Please use +-*-semiring instead."#-}*-+-commutativeSemiring = +-*-commutativeSemiring{-# WARNING_ON_USAGE *-+-commutativeSemiring"Warning: *-+-commutativeSemiring was deprecated in v1.4.Please use +-*-commutativeSemiring instead."#-}-- Version 1.6∣m+n-m+o∣≡∣n-o| = ∣m+n-m+o∣≡∣n-o∣{-# WARNING_ON_USAGE ∣m+n-m+o∣≡∣n-o|"Warning: ∣m+n-m+o∣≡∣n-o| was deprecated in v1.6.Please use ∣m+n-m+o∣≡∣n-o∣ instead. Note the final is a \\| rather than a |"#-}m≤n⇒n⊔m≡n = m≥n⇒m⊔n≡m{-# WARNING_ON_USAGE m≤n⇒n⊔m≡n"Warning: m≤n⇒n⊔m≡n was deprecated in v1.6. Please use m≥n⇒m⊔n≡m instead."#-}m≤n⇒n⊓m≡m = m≥n⇒m⊓n≡n{-# WARNING_ON_USAGE m≤n⇒n⊓m≡m"Warning: m≤n⇒n⊓m≡m was deprecated in v1.6. Please use m≥n⇒m⊓n≡n instead."#-}n⊔m≡m⇒n≤m = m⊔n≡n⇒m≤n{-# WARNING_ON_USAGE n⊔m≡m⇒n≤m"Warning: n⊔m≡m⇒n≤m was deprecated in v1.6. Please use m⊔n≡n⇒m≤n instead."#-}n⊔m≡n⇒m≤n = m⊔n≡m⇒n≤m{-# WARNING_ON_USAGE n⊔m≡n⇒m≤n"Warning: n⊔m≡n⇒m≤n was deprecated in v1.6. Please use m⊔n≡m⇒n≤m instead."#-}n≤m⊔n = m≤n⊔m{-# WARNING_ON_USAGE n≤m⊔n"Warning: n≤m⊔n was deprecated in v1.6. Please use m≤n⊔m instead."#-}⊔-least = ⊔-lub{-# WARNING_ON_USAGE ⊔-least"Warning: ⊔-least was deprecated in v1.6. Please use ⊔-lub instead."#-}⊓-greatest = ⊓-glb{-# WARNING_ON_USAGE ⊓-greatest"Warning: ⊓-greatest was deprecated in v1.6. Please use ⊓-glb instead."#-}⊔-pres-≤m = ⊔-lub{-# WARNING_ON_USAGE ⊔-pres-≤m"Warning: ⊔-pres-≤m was deprecated in v1.6. Please use ⊔-lub instead."#-}⊓-pres-m≤ = ⊓-glb{-# WARNING_ON_USAGE ⊓-pres-m≤"Warning: ⊓-pres-m≤ was deprecated in v1.6. Please use ⊓-glb instead."#-}⊔-abs-⊓ = ⊔-absorbs-⊓{-# WARNING_ON_USAGE ⊔-abs-⊓"Warning: ⊔-abs-⊓ was deprecated in v1.6. Please use ⊔-absorbs-⊓ instead."#-}⊓-abs-⊔ = ⊓-absorbs-⊔{-# WARNING_ON_USAGE ⊓-abs-⊔"Warning: ⊓-abs-⊔ was deprecated in v1.6. Please use ⊓-absorbs-⊔ instead."#-}-- Version 2.0suc[pred[n]]≡n : n ≢ 0 → suc (pred n) ≡ nsuc[pred[n]]≡n {zero} 0≢0 = contradiction refl 0≢0suc[pred[n]]≡n {suc n} _ = refl{-# WARNING_ON_USAGE suc[pred[n]]≡n"Warning: suc[pred[n]]≡n was deprecated in v2.0. Please use suc-pred instead. Note that the proof now uses instance arguments"#-}≤-step = m≤n⇒m≤1+n{-# WARNING_ON_USAGE ≤-step"Warning: ≤-step was deprecated in v2.0. Please use m≤n⇒m≤1+n instead. "#-}≤-stepsˡ = m≤n⇒m≤o+n{-# WARNING_ON_USAGE ≤-stepsˡ"Warning: ≤-stepsˡ was deprecated in v2.0. Please use m≤n⇒m≤o+n instead. "#-}≤-stepsʳ = m≤n⇒m≤n+o{-# WARNING_ON_USAGE ≤-stepsʳ"Warning: ≤-stepsʳ was deprecated in v2.0. Please use m≤n⇒m≤n+o instead. "#-}<-step = m<n⇒m<1+n{-# WARNING_ON_USAGE <-step"Warning: <-step was deprecated in v2.0. Please use m<n⇒m<1+n instead. "#-}pred-mono = pred-mono-≤{-# WARNING_ON_USAGE pred-mono"Warning: pred-mono was deprecated in v2.0. Please use pred-mono-≤ instead. "#-}{- issue1844/issue1755: raw bundles have moved to `Data.X.Base` -}open Data.Nat.Base publicusing (*-rawMagma; *-1-rawMonoid)<-transʳ = ≤-<-trans{-# WARNING_ON_USAGE <-transʳ"Warning: <-transʳ was deprecated in v2.0. Please use ≤-<-trans instead. "#-}<-transˡ = <-≤-trans{-# WARNING_ON_USAGE <-transˡ"Warning: <-transˡ was deprecated in v2.0. Please use <-≤-trans instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Nat.Base directly.--------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Properties.Core where{-# WARNING_ON_IMPORT"Data.Nat.Properties.Core was deprecated in v2.0.Use Data.Nat.Base instead."#-}open import Data.Nat.Base-------------------------------------------------------------------------- Properties of _≤_------------------------------------------------------------------------≤-pred : ∀ {m n} → suc m ≤ suc n → m ≤ n≤-pred = s≤s⁻¹
-------------------------------------------------------------------------- The Agda standard library---- Primality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Primality whereopen import Data.List.Base using ([]; _∷_; product)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.Nat.Baseopen import Data.Nat.Divisibilityopen import Data.Nat.GCD using (module GCD; module Bézout)open import Data.Nat.Propertiesopen import Data.Product.Base using (∃-syntax; _×_; map₂; _,_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (flip; _∘_; _∘′_)open import Function.Bundles using (_⇔_; mk⇔)open import Relation.Nullary.Decidable as Decusing (yes; no; from-yes; from-no; ¬?; _×-dec_; _⊎-dec_; _→-dec_; decidable-stable)open import Relation.Nullary.Negation using (¬_; contradiction; contradiction₂)open import Relation.Unary using (Pred; Decidable)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; cong)privatevariabled m n o p : ℕrecompute-nonTrivial : .{{NonTrivial n}} → NonTrivial nrecompute-nonTrivial {n} {{nontrivial}} =Dec.recompute (nonTrivial? n) nontrivial-------------------------------------------------------------------------- Definitions-------------------------------------------------------------------------- The positive/existential relation `BoundedNonTrivialDivisor` is-- the basis for the whole development, as it captures the possible-- non-trivial divisors of a given number; its complement, `Rough`,-- therefore sets *lower* bounds on any possible such divisors.-- The predicate `Composite` is then defined as the 'diagonal' instance-- of `BoundedNonTrivialDivisor`, while `Prime` is essentially defined as-- the complement of `Composite`. Finally, `Irreducible` is the positive-- analogue of `Prime`.-------------------------------------------------------------------------- Roughness-- A number is m-rough if all its non-trivial divisors are bounded below-- by m.infix 10 _Rough__Rough_ : ℕ → Pred ℕ _m Rough n = ¬ (n HasNonTrivialDivisorLessThan m)-------------------------------------------------------------------------- Compositeness-- A number is composite if it has a proper non-trivial divisor.Composite : Pred ℕ _Composite n = n HasNonTrivialDivisorLessThan n-- A shorter pattern synonym for the record constructor producing a-- witness for `Composite`.patterncomposite {d} d<n d∣n = hasNonTrivialDivisor {divisor = d} d<n d∣n-------------------------------------------------------------------------- Primality-- Prime as the complement of Composite (and hence the diagonal of Rough-- as defined above). The constructor `prime` takes a proof `notComposite`-- that NonTrivial p is not composite and thereby enforces that:-- * p is a fortiori NonZero and NonUnit-- * p is p-Rough, i.e. any proper divisor must be at least p, i.e. p itselfrecord Prime (p : ℕ) : Set whereconstructor primefield.{{nontrivial}} : NonTrivial pnotComposite : ¬ Composite p-------------------------------------------------------------------------- IrreducibilityIrreducible : Pred ℕ _Irreducible n = ∀ {d} → d ∣ n → d ≡ 1 ⊎ d ≡ n-------------------------------------------------------------------------- Properties-------------------------------------------------------------------------------------------------------------------------------------------------- Roughness-- 1 is always n-roughrough-1 : ∀ n → n Rough 1rough-1 _ (hasNonTrivialDivisor _ d∣1) =contradiction (∣1⇒≡1 d∣1) nonTrivial⇒≢1-- Any number is 0-, 1- and 2-rough,-- because no proper divisor d can be strictly less than 0, 1, or 20-rough : 0 Rough n0-rough (hasNonTrivialDivisor () _)1-rough : 1 Rough n1-rough (hasNonTrivialDivisor {{()}} z<s _)2-rough : 2 Rough n2-rough (hasNonTrivialDivisor {{()}} (s<s z<s) _)-- If a number n > 1 is m-rough, then m ≤ nrough⇒≤ : .{{NonTrivial n}} → m Rough n → m ≤ nrough⇒≤ rough = ≮⇒≥ n≮mwhere n≮m = λ m>n → rough (hasNonTrivialDivisor m>n ∣-refl)-- If a number n is m-rough, and m ∤ n, then n is (suc m)-rough∤⇒rough-suc : m ∤ n → m Rough n → (suc m) Rough n∤⇒rough-suc m∤n r (hasNonTrivialDivisor d<1+m d∣n)with m<1+n⇒m<n∨m≡n d<1+m... | inj₁ d<m = r (hasNonTrivialDivisor d<m d∣n)... | inj₂ d≡m@refl = contradiction d∣n m∤n-- If a number is m-rough, then so are all of its divisorsrough∧∣⇒rough : m Rough o → n ∣ o → m Rough nrough∧∣⇒rough r n∣o bntd = r (hasNonTrivialDivisor-∣ bntd n∣o)-------------------------------------------------------------------------- Compositeness-- Smart constructorscomposite-≢ : ∀ d → .{{NonTrivial d}} → .{{NonZero n}} →d ≢ n → d ∣ n → Composite ncomposite-≢ d = hasNonTrivialDivisor-≢ {d}composite-∣ : .{{NonZero n}} → Composite m → m ∣ n → Composite ncomposite-∣ (composite {d} d<m d∣n) m∣n@(divides-refl q)= composite (*-monoʳ-< q d<m) (*-monoʳ-∣ q d∣n)where instance_ = m≢0∧n>1⇒m*n>1 q d_ = m*n≢0⇒m≢0 q-- Basic (counter-)examples of Composite¬composite[0] : ¬ Composite 0¬composite[0] = 0-rough¬composite[1] : ¬ Composite 1¬composite[1] = 1-roughcomposite[4] : Composite 4composite[4] = composite-≢ 2 (λ()) (divides-refl 2)composite[6] : Composite 6composite[6] = composite-≢ 3 (λ()) (divides-refl 2)composite⇒nonZero : Composite n → NonZero ncomposite⇒nonZero {suc _} _ = _composite⇒nonTrivial : Composite n → NonTrivial ncomposite⇒nonTrivial {1} composite[1] =contradiction composite[1] ¬composite[1]composite⇒nonTrivial {2+ _} _ = _composite? : Decidable Compositecomposite? n = Dec.map CompositeUpTo⇔Composite (compositeUpTo? n)where-- For technical reasons, in order to be able to prove decidability-- via the `all?` and `any?` combinators for *bounded* predicates on-- `ℕ`, we further define the bounded counterparts to predicates-- `P...` as `P...UpTo` and show the equivalence of the two.-- Equivalent bounded predicate definitionCompositeUpTo : Pred ℕ _CompositeUpTo n = ∃[ d ] d < n × NonTrivial d × d ∣ n-- Proof of equivalencecomp-upto⇒comp : CompositeUpTo n → Composite ncomp-upto⇒comp (_ , d<n , ntd , d∣n) = composite d<n d∣nwhere instance _ = ntdcomp⇒comp-upto : Composite n → CompositeUpTo ncomp⇒comp-upto (composite d<n d∣n) = _ , d<n , recompute-nonTrivial , d∣nCompositeUpTo⇔Composite : CompositeUpTo n ⇔ Composite nCompositeUpTo⇔Composite = mk⇔ comp-upto⇒comp comp⇒comp-upto-- Proof of decidabilitycompositeUpTo? : Decidable CompositeUpTocompositeUpTo? n = anyUpTo? (λ d → nonTrivial? d ×-dec d ∣? n) n-------------------------------------------------------------------------- Primality-- Basic (counter-)examples¬prime[0] : ¬ Prime 0¬prime[0] ()¬prime[1] : ¬ Prime 1¬prime[1] ()prime[2] : Prime 2prime[2] = prime 2-roughprime⇒nonZero : Prime p → NonZero pprime⇒nonZero _ = nonTrivial⇒nonZero _prime⇒nonTrivial : Prime p → NonTrivial pprime⇒nonTrivial _ = recompute-nonTrivialprime? : Decidable Primeprime? 0 = no ¬prime[0]prime? 1 = no ¬prime[1]prime? n@(2+ _) = Dec.map PrimeUpTo⇔Prime (primeUpTo? n)where-- Equivalent bounded predicate definitionPrimeUpTo : Pred ℕ _PrimeUpTo n = ∀ {d} → d < n → NonTrivial d → d ∤ n-- Proof of equivalenceprime⇒prime-upto : Prime n → PrimeUpTo nprime⇒prime-upto (prime p) {d} d<n ntd d∣n= p (composite d<n d∣n) where instance _ = ntdprime-upto⇒prime : .{{NonTrivial n}} → PrimeUpTo n → Prime nprime-upto⇒prime upto = primeλ (composite d<n d∣n) → upto d<n recompute-nonTrivial d∣nPrimeUpTo⇔Prime : .{{NonTrivial n}} → PrimeUpTo n ⇔ Prime nPrimeUpTo⇔Prime = mk⇔ prime-upto⇒prime prime⇒prime-upto-- Proof of decidabilityprimeUpTo? : Decidable PrimeUpToprimeUpTo? n = allUpTo? (λ d → nonTrivial? d →-dec ¬? (d ∣? n)) n-- Euclid's lemma - for p prime, if p ∣ m * n, then either p ∣ m or p ∣ n.---- This demonstrates that the usual definition of prime numbers matches-- the ring theoretic definition of a prime element of the semiring ℕ.-- This is useful for proving many other theorems involving prime numbers.euclidsLemma : ∀ m n {p} → Prime p → p ∣ m * n → p ∣ m ⊎ p ∣ neuclidsLemma m n {p} pp@(prime pr) p∣m*n = resultwhereopen ∣-Reasoninginstance _ = prime⇒nonZero ppp∣rmn : ∀ r → p ∣ r * m * np∣rmn r = beginp ∣⟨ p∣m*n ⟩m * n ∣⟨ n∣m*n r ⟩r * (m * n) ≡⟨ *-assoc r m n ⟨r * m * n ∎result : p ∣ m ⊎ p ∣ nresult with Bézout.lemma m p-- if the GCD of m and p is zero then p must be zero, which is-- impossible as p is a prime.-- note: this should be a typechecker-rejectable case!?... | Bézout.result 0 g _ =contradiction (0∣⇒≡0 (GCD.gcd∣n g)) (≢-nonZero⁻¹ _)-- if the GCD of m and p is one then m and p are coprime, and we know-- that for some integers s and r, sm + rp = 1. We can use this fact-- to determine that p divides n... | Bézout.result 1 _ (Bézout.+- r s 1+sp≡rm) =inj₂ (flip ∣m+n∣m⇒∣n (n∣m*n*o s n) (beginp ∣⟨ p∣rmn r ⟩r * m * n ≡⟨ cong (_* n) 1+sp≡rm ⟨n + s * p * n ≡⟨ +-comm n (s * p * n) ⟩s * p * n + n ∎))... | Bézout.result 1 _ (Bézout.-+ r s 1+rm≡sp) =inj₂ (flip ∣m+n∣m⇒∣n (p∣rmn r) (beginp ∣⟨ n∣m*n*o s n ⟩s * p * n ≡⟨ cong (_* n) 1+rm≡sp ⟨n + r * m * n ≡⟨ +-comm n (r * m * n) ⟩r * m * n + n ∎))-- if the GCD of m and p is greater than one, then it must be p and-- hence p ∣ m.... | Bézout.result d@(2+ _) g _ with d ≟ p... | yes d≡p@refl = inj₁ (GCD.gcd∣m g)... | no d≢p = contradiction (composite-≢ d d≢p (GCD.gcd∣n g)) pr-- Relationship between roughness and primality.prime⇒rough : Prime p → p Rough pprime⇒rough (prime pr) = pr-- If a number n is p-rough, and p > 1 divides n, then p must be primerough∧∣⇒prime : .{{NonTrivial p}} → p Rough n → p ∣ n → Prime prough∧∣⇒prime r p∣n = prime (rough∧∣⇒rough r p∣n)-- If a number n is m-rough, and m * m > n, then n must be prime.rough∧square>⇒prime : .{{NonTrivial n}} → m Rough n → m * m > n → Prime nrough∧square>⇒prime rough m*m>n = prime ¬compositewhere¬composite : ¬ Composite _¬composite (composite d<n d∣n) = contradiction (m∣n⇒n≡quotient*m d∣n)(<⇒≢ (<-≤-trans m*m>n (*-mono-≤(rough⇒≤ (rough∧∣⇒rough rough (quotient-∣ d∣n)))(rough⇒≤ (rough∧∣⇒rough rough d∣n)))))where instance _ = n>1⇒nonTrivial (quotient>1 d∣n d<n)-- Relationship between compositeness and primality.composite⇒¬prime : Composite n → ¬ Prime ncomposite⇒¬prime composite[d] (prime p) = p composite[d]¬composite⇒prime : .{{NonTrivial n}} → ¬ Composite n → Prime n¬composite⇒prime = primeprime⇒¬composite : Prime n → ¬ Composite nprime⇒¬composite (prime p) = p-- Note that this has to recompute the factor!¬prime⇒composite : .{{NonTrivial n}} → ¬ Prime n → Composite n¬prime⇒composite {n} ¬prime[n] =decidable-stable (composite? n) (¬prime[n] ∘′ ¬composite⇒prime)productOfPrimes≢0 : ∀ {as} → All Prime as → NonZero (product as)productOfPrimes≢0 pas = product≢0 (All.map prime⇒nonZero pas)whereproduct≢0 : ∀ {ns} → All NonZero ns → NonZero (product ns)product≢0 [] = _product≢0 {n ∷ ns} (nzn ∷ nzns) = m*n≢0 n _ {{nzn}} {{product≢0 nzns}}productOfPrimes≥1 : ∀ {as} → All Prime as → product as ≥ 1productOfPrimes≥1 {as} pas = >-nonZero⁻¹ _ {{productOfPrimes≢0 pas}}-------------------------------------------------------------------------- Basic (counter-)examples of Irreducible¬irreducible[0] : ¬ Irreducible 0¬irreducible[0] irr[0] = contradiction₂ 2≡1⊎2≡0 (λ ()) (λ ())where 2≡1⊎2≡0 = irr[0] {2} (divides-refl 0)irreducible[1] : Irreducible 1irreducible[1] m∣1 = inj₁ (∣1⇒≡1 m∣1)irreducible[2] : Irreducible 2irreducible[2] {zero} 0∣2 with () ← 0∣⇒≡0 0∣2irreducible[2] {suc _} d∣2 with ∣⇒≤ d∣2... | z<s = inj₁ refl... | s<s z<s = inj₂ reflirreducible⇒nonZero : Irreducible n → NonZero nirreducible⇒nonZero {zero} = flip contradiction ¬irreducible[0]irreducible⇒nonZero {suc _} _ = _irreducible? : Decidable Irreducibleirreducible? zero = no ¬irreducible[0]irreducible? n@(suc _) =Dec.map IrreducibleUpTo⇔Irreducible (irreducibleUpTo? n)where-- Equivalent bounded predicate definitionIrreducibleUpTo : Pred ℕ _IrreducibleUpTo n = ∀ {d} → d < n → d ∣ n → d ≡ 1 ⊎ d ≡ n-- Proof of equivalenceirr-upto⇒irr : .{{NonZero n}} → IrreducibleUpTo n → Irreducible nirr-upto⇒irr irr-upto m∣n= [ flip irr-upto m∣n , inj₂ ]′ (m≤n⇒m<n∨m≡n (∣⇒≤ m∣n))irr⇒irr-upto : Irreducible n → IrreducibleUpTo nirr⇒irr-upto irr m<n m∣n = irr m∣nIrreducibleUpTo⇔Irreducible : .{{NonZero n}} →IrreducibleUpTo n ⇔ Irreducible nIrreducibleUpTo⇔Irreducible = mk⇔ irr-upto⇒irr irr⇒irr-upto-- DecidabilityirreducibleUpTo? : Decidable IrreducibleUpToirreducibleUpTo? n = allUpTo?(λ m → (m ∣? n) →-dec (m ≟ 1 ⊎-dec m ≟ n)) n-- Relationship between primality and irreducibility.prime⇒irreducible : Prime p → Irreducible pprime⇒irreducible {p} pp@(prime pr) = irrwhereinstance _ = prime⇒nonZero ppirr : .{{NonZero p}} → Irreducible pirr {0} 0∣p = contradiction (0∣⇒≡0 0∣p) (≢-nonZero⁻¹ p)irr {1} 1∣p = inj₁ reflirr {2+ _} d∣p = inj₂ (≤∧≮⇒≡ (∣⇒≤ d∣p) d≮p)where d≮p = λ d<p → pr (composite d<p d∣p)irreducible⇒prime : .{{NonTrivial p}} → Irreducible p → Prime pirreducible⇒prime irr = primeλ (composite d<p d∣p) → [ nonTrivial⇒≢1 , (<⇒≢ d<p) ]′ (irr d∣p)-------------------------------------------------------------------------- Using decidability-- Once we have the above decision procedures, then instead of-- constructing proofs of e.g. Prime-ness by hand, we call the-- appropriate function, and use the witness extraction functions-- `from-yes`, `from-no` to return the checked proofs.private-- Example: 2 is prime, but not-composite.2-is-prime : Prime 22-is-prime = from-yes (prime? 2)2-is-not-composite : ¬ Composite 22-is-not-composite = from-no (composite? 2)-- Example: 4 and 6 are composite, hence not-prime4-is-composite : Composite 44-is-composite = from-yes (composite? 4)4-is-not-prime : ¬ Prime 44-is-not-prime = from-no (prime? 4)6-is-composite : Composite 66-is-composite = from-yes (composite? 6)6-is-not-prime : ¬ Prime 66-is-not-prime = from-no (prime? 6)
-------------------------------------------------------------------------- The Agda standard library---- Prime factorisation of natural numbers and its properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Primality.Factorisation whereopen import Data.Nat.Baseopen import Data.Nat.Divisibilityusing (_∣?_; quotient; quotient>1; quotient-<; quotient-∣; m∣n⇒n≡m*quotient; _∣_; ∣1⇒≡1;divides)open import Data.Nat.Propertiesopen import Data.Nat.Induction using (<-Rec; <-rec; <-recBuilder)open import Data.Nat.Primalityusing (Prime; _Rough_; rough∧square>⇒prime; ∤⇒rough-suc; rough∧∣⇒rough; rough∧∣⇒prime;2-rough; euclidsLemma; prime⇒irreducible; ¬prime[1]; productOfPrimes≥1; prime⇒nonZero)open import Data.Product.Base using (∃-syntax; _×_; _,_; proj₁; proj₂)open import Data.List.Base using (List; []; _∷_; _++_; product)open import Data.List.Membership.Propositional using (_∈_)open import Data.List.Membership.Propositional.Properties using (∈-∃++)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.Any using (here; there)open import Data.List.Relation.Binary.Permutation.Propositionalusing (_↭_; prep; swap; ↭-reflexive; ↭-refl; ↭-trans; refl; module PermutationReasoning)open import Data.List.Relation.Binary.Permutation.Propositional.Propertiesusing (product-↭; All-resp-↭; shift)open import Data.Sum.Base using (inj₁; inj₂)open import Function.Base using (_$_; _∘_; _|>_; flip)open import Induction using (build)open import Induction.Lexicographic using (_⊗_; [_⊗_])open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablen : ℕ-------------------------------------------------------------------------- Core definitionrecord PrimeFactorisation (n : ℕ) : Set wherefieldfactors : List ℕisFactorisation : n ≡ product factorsfactorsPrime : All Prime factorsopen PrimeFactorisation public using (factors)open PrimeFactorisation-------------------------------------------------------------------------- Finding a factorisationprimeFactorisation[1] : PrimeFactorisation 1primeFactorisation[1] = record{ factors = []; isFactorisation = refl; factorsPrime = []}primeFactorisation[p] : Prime n → PrimeFactorisation nprimeFactorisation[p] {n} pr = record{ factors = n ∷ []; isFactorisation = sym (*-identityʳ n); factorsPrime = pr ∷ []}-- This builds up three important things:-- * a proof that every number we've gotten to so far has increasingly higher-- possible least prime factor, so we don't have to repeat smaller factors-- over and over (this is the "m" and "rough" parameters)-- * a witness that this limit is getting closer to the number of interest, in a-- way that helps the termination checker (the "k" and "eq" parameters)-- * a proof that we can factorise any smaller number, which is useful when we-- encounter a factor, as we can then divide by that factor and continue from-- there without termination issuesfactorise : ∀ n → .{{NonZero n}} → PrimeFactorisation nfactorise 1 = primeFactorisation[1]factorise n₀@(2+ _) = build [ <-recBuilder ⊗ <-recBuilder ] P facRec (n₀ , suc n₀ ∸ 4) 2-rough reflwhereP : ℕ × ℕ → SetP (n , k) = ∀ {m} → .{{NonTrivial n}} → .{{NonTrivial m}} → m Rough n → suc n ∸ m * m ≡ k → PrimeFactorisation nfacRec : ∀ n×k → (<-Rec ⊗ <-Rec) P n×k → P n×kfacRec (n , zero) _ rough eq =-- Case 1: m * m > n, ∴ Prime nprimeFactorisation[p] (rough∧square>⇒prime rough (m∸n≡0⇒m≤n eq))facRec (n@(2+ _) , suc k) (recFactor , recQuotient) {m@(2+ _)} rough eq with m ∣? n-- Case 2: m ∤ n, try larger m, reducing k accordingly... | no m∤n = recFactor (≤-<-trans (m∸n≤m k (m + m)) (n<1+n k)) {suc m} (∤⇒rough-suc m∤n rough) $ beginsuc n ∸ (suc m + m * suc m) ≡⟨ cong (λ # → suc n ∸ (suc m + #)) (*-suc m m) ⟩suc n ∸ (suc m + (m + m * m)) ≡⟨ cong (suc n ∸_) (+-assoc (suc m) m (m * m)) ⟨suc n ∸ (suc (m + m) + m * m) ≡⟨ cong (suc n ∸_) (+-comm (suc (m + m)) (m * m)) ⟩suc n ∸ (m * m + suc (m + m)) ≡⟨ ∸-+-assoc (suc n) (m * m) (suc (m + m)) ⟨(suc n ∸ m * m) ∸ suc (m + m) ≡⟨ cong (_∸ suc (m + m)) eq ⟩suc k ∸ suc (m + m) ∎where open ≡-Reasoning-- Case 3: m ∣ n, record m and recurse on the quotient... | yes m∣n = record{ factors = m ∷ ps; isFactorisation = sym m*Πps≡n; factorsPrime = rough∧∣⇒prime rough m∣n ∷ primes}wherem<n : m < nm<n = begin-strictm <⟨ s≤s (≤-trans (m≤n+m m _) (+-monoʳ-≤ _ (m≤m+n m _))) ⟩pred (m * m) <⟨ s<s⁻¹ (m∸n≢0⇒n<m λ eq′ → 0≢1+n (trans (sym eq′) eq)) ⟩n ∎where open ≤-Reasoningq = quotient m∣ninstance _ = n>1⇒nonTrivial (quotient>1 m∣n m<n)factorisation[q] : PrimeFactorisation qfactorisation[q] = recQuotient (quotient-< m∣n) (suc q ∸ m * m) (rough∧∣⇒rough rough (quotient-∣ m∣n)) reflps = factors factorisation[q]primes = factorsPrime factorisation[q]m*Πps≡n : m * product ps ≡ nm*Πps≡n = beginm * product ps ≡⟨ cong (m *_) (isFactorisation factorisation[q]) ⟨m * q ≡⟨ m∣n⇒n≡m*quotient m∣n ⟨n ∎where open ≡-Reasoning-------------------------------------------------------------------------- Properties of a factorisationfactorisationHasAllPrimeFactors : ∀ {as} {p} → Prime p → p ∣ product as → All Prime as → p ∈ asfactorisationHasAllPrimeFactors {[]} {2+ p} pPrime p∣Πas [] = contradiction (∣1⇒≡1 p∣Πas) λ ()factorisationHasAllPrimeFactors {a ∷ as} {p} pPrime p∣aΠas (aPrime ∷ asPrime) with euclidsLemma a (product as) pPrime p∣aΠas... | inj₂ p∣Πas = there (factorisationHasAllPrimeFactors pPrime p∣Πas asPrime)... | inj₁ p∣a with prime⇒irreducible aPrime p∣a... | inj₁ refl = contradiction pPrime ¬prime[1]... | inj₂ refl = here reflprivatefactorisationUnique′ : (as bs : List ℕ) → product as ≡ product bs → All Prime as → All Prime bs → as ↭ bsfactorisationUnique′ [] [] Πas≡Πbs asPrime bsPrime = reflfactorisationUnique′ [] (b@(2+ _) ∷ bs) Πas≡Πbs prime[as] (_ ∷ prime[bs]) =contradiction Πas≡Πbs (<⇒≢ Πas<Πbs)whereΠas<Πbs : product [] < product (b ∷ bs)Πas<Πbs = begin-strict1 ≡⟨⟩1 * 1 <⟨ *-monoˡ-< 1 {1} {b} sz<ss ⟩b * 1 ≤⟨ *-monoʳ-≤ b (productOfPrimes≥1 prime[bs]) ⟩b * product bs ≡⟨⟩product (b ∷ bs) ∎where open ≤-ReasoningfactorisationUnique′ (a ∷ as) bs Πas≡Πbs (prime[a] ∷ prime[as]) prime[bs] = a∷as↭bswherea∣Πbs : a ∣ product bsa∣Πbs = divides (product as) $ beginproduct bs ≡⟨ Πas≡Πbs ⟨product (a ∷ as) ≡⟨⟩a * product as ≡⟨ *-comm a (product as) ⟩product as * a ∎where open ≡-Reasoningshuffle : ∃[ bs′ ] bs ↭ a ∷ bs′shuffle with ys , zs , p ← ∈-∃++ (factorisationHasAllPrimeFactors prime[a] a∣Πbs prime[bs])= ys ++ zs , ↭-trans (↭-reflexive p) (shift a ys zs)bs′ = proj₁ shufflebs↭a∷bs′ = proj₂ shuffleΠas≡Πbs′ : product as ≡ product bs′Πas≡Πbs′ = *-cancelˡ-≡ (product as) (product bs′) a {{prime⇒nonZero prime[a]}} $ begina * product as ≡⟨ Πas≡Πbs ⟩product bs ≡⟨ product-↭ bs↭a∷bs′ ⟩a * product bs′ ∎where open ≡-Reasoningprime[bs'] : All Prime bs′prime[bs'] = All.tail (All-resp-↭ bs↭a∷bs′ prime[bs])a∷as↭bs : a ∷ as ↭ bsa∷as↭bs = begina ∷ as <⟨ factorisationUnique′ as bs′ Πas≡Πbs′ prime[as] prime[bs'] ⟩a ∷ bs′ ↭⟨ bs↭a∷bs′ ⟨bs ∎where open PermutationReasoningfactorisationUnique : (f f′ : PrimeFactorisation n) → factors f ↭ factors f′factorisationUnique {n} f f′ =factorisationUnique′ (factors f) (factors f′) Πf≡Πf′ (factorsPrime f) (factorsPrime f′)whereΠf≡Πf′ : product (factors f) ≡ product (factors f′)Πf≡Πf′ = beginproduct (factors f) ≡⟨ isFactorisation f ⟨n ≡⟨ isFactorisation f′ ⟩product (factors f′) ∎where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Logarithm base 2 and respective properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Logarithm whereopen import Data.Nat.Baseopen import Data.Nat.Induction using (<-wellFounded)open import Data.Nat.Logarithm.Coreopen import Relation.Binary.PropositionalEquality.Core using (_≡_)-------------------------------------------------------------------------- Logarithm base 2-- Floor version⌊log₂_⌋ : ℕ → ℕ⌊log₂ n ⌋ = ⌊log2⌋ n (<-wellFounded n)-- Ceil version⌈log₂_⌉ : ℕ → ℕ⌈log₂ n ⌉ = ⌈log2⌉ n (<-wellFounded n)-------------------------------------------------------------------------- Properties of ⌊log₂_⌋⌊log₂⌋-mono-≤ : ∀ {m n} → m ≤ n → ⌊log₂ m ⌋ ≤ ⌊log₂ n ⌋⌊log₂⌋-mono-≤ p = ⌊log2⌋-mono-≤ p⌊log₂⌊n/2⌋⌋≡⌊log₂n⌋∸1 : ∀ n → ⌊log₂ ⌊ n /2⌋ ⌋ ≡ ⌊log₂ n ⌋ ∸ 1⌊log₂⌊n/2⌋⌋≡⌊log₂n⌋∸1 n = ⌊log2⌋⌊n/2⌋≡⌊log2⌋n∸1 n⌊log₂[2*b]⌋≡1+⌊log₂b⌋ : ∀ n .{{_ : NonZero n}} → ⌊log₂ (2 * n) ⌋ ≡ 1 + ⌊log₂ n ⌋⌊log₂[2*b]⌋≡1+⌊log₂b⌋ n = ⌊log2⌋2*b≡1+⌊log2⌋b n⌊log₂[2^n]⌋≡n : ∀ n → ⌊log₂ (2 ^ n) ⌋ ≡ n⌊log₂[2^n]⌋≡n n = ⌊log2⌋2^n≡n n-------------------------------------------------------------------------- Properties of ⌈log₂_⌉⌈log₂⌉-mono-≤ : ∀ {m n} → m ≤ n → ⌈log₂ m ⌉ ≤ ⌈log₂ n ⌉⌈log₂⌉-mono-≤ p = ⌈log2⌉-mono-≤ p⌈log₂⌈n/2⌉⌉≡⌈log₂n⌉∸1 : ∀ n → ⌈log₂ ⌈ n /2⌉ ⌉ ≡ ⌈log₂ n ⌉ ∸ 1⌈log₂⌈n/2⌉⌉≡⌈log₂n⌉∸1 n = ⌈log2⌉⌈n/2⌉≡⌈log2⌉n∸1 n⌈log₂2*n⌉≡1+⌈log₂n⌉ : ∀ n .{{_ : NonZero n}} → ⌈log₂ (2 * n) ⌉ ≡ 1 + ⌈log₂ n ⌉⌈log₂2*n⌉≡1+⌈log₂n⌉ n = ⌈log2⌉2*n≡1+⌈log2⌉n n⌈log₂2^n⌉≡n : ∀ n → ⌈log₂ (2 ^ n) ⌉ ≡ n⌈log₂2^n⌉≡n n = ⌈log2⌉2^n≡n n
-------------------------------------------------------------------------- The Agda standard library---- Logarithm base 2 core definitions and properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Logarithm.Core whereopen import Data.Nat.Base using (ℕ; _<_; zero; suc; _+_; ⌊_/2⌋; ⌈_/2⌉;_≤_; z≤n; s≤s; _∸_; NonZero; _*_; _^_)open import Data.Nat.Propertiesopen import Data.Nat.Induction using (<-wellFounded)open import Induction.WellFounded using (Acc; acc)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)-------------------------------------------------------------------------- Logarithm base 2-- Floor version⌊log2⌋ : ∀ n → Acc _<_ n → ℕ⌊log2⌋ 0 _ = 0⌊log2⌋ 1 _ = 0⌊log2⌋ (suc n′@(suc n)) (acc rs) = 1 + ⌊log2⌋ (suc ⌊ n /2⌋) (rs (⌊n/2⌋<n n′))-- Ceil version⌈log2⌉ : ∀ n → Acc _<_ n → ℕ⌈log2⌉ 0 _ = 0⌈log2⌉ 1 _ = 0⌈log2⌉ (suc (suc n)) (acc rs) = 1 + ⌈log2⌉ (suc ⌈ n /2⌉) (rs (⌈n/2⌉<n n))-------------------------------------------------------------------------- Properties of ⌊log2⌋⌊log2⌋-acc-irrelevant : ∀ a {acc acc'} → ⌊log2⌋ a acc ≡ ⌊log2⌋ a acc'⌊log2⌋-acc-irrelevant 0 {_} {_} = refl⌊log2⌋-acc-irrelevant 1 {_} {_} = refl⌊log2⌋-acc-irrelevant (suc (suc n)) {acc rs} {acc rs'} =cong suc (⌊log2⌋-acc-irrelevant (suc ⌊ n /2⌋))⌊log2⌋-cong-irr : ∀ {a b} {acc acc'} → (p : a ≡ b) →⌊log2⌋ a acc ≡ ⌊log2⌋ b acc'⌊log2⌋-cong-irr {acc = ac} refl = ⌊log2⌋-acc-irrelevant _ {ac}⌊log2⌋-mono-≤ : ∀ {a b} {acc acc'} → a ≤ b → ⌊log2⌋ a acc ≤ ⌊log2⌋ b acc'⌊log2⌋-mono-≤ {_} {_} z≤n = z≤n⌊log2⌋-mono-≤ {_} {_} (s≤s z≤n) = z≤n⌊log2⌋-mono-≤ {acc = acc _} {acc _} (s≤s (s≤s p)) =s≤s (⌊log2⌋-mono-≤ (⌊n/2⌋-mono (+-monoʳ-≤ 2 p)))⌊log2⌋⌊n/2⌋≡⌊log2⌋n∸1 : ∀ n {acc} {acc'} →⌊log2⌋ ⌊ n /2⌋ acc ≡ ⌊log2⌋ n acc' ∸ 1⌊log2⌋⌊n/2⌋≡⌊log2⌋n∸1 0 {_} {_} = refl⌊log2⌋⌊n/2⌋≡⌊log2⌋n∸1 1 {_} {_} = refl⌊log2⌋⌊n/2⌋≡⌊log2⌋n∸1 (suc (suc n)) {acc rs} {acc rs'} =⌊log2⌋-acc-irrelevant (suc ⌊ n /2⌋)⌊log2⌋2*b≡1+⌊log2⌋b : ∀ n {acc acc'} .{{ _ : NonZero n}} →⌊log2⌋ (2 * n) acc ≡ 1 + ⌊log2⌋ n acc'⌊log2⌋2*b≡1+⌊log2⌋b (suc n) = begin⌊log2⌋ (suc (n + suc (n + zero))) _ ≡⟨ ⌊log2⌋-cong-irr (cong (λ x → suc (n + suc x)) (+-comm n zero)) ⟩⌊log2⌋ (suc (n + suc n)) (<-wellFounded _) ≡⟨ ⌊log2⌋-cong-irr {acc' = <-wellFounded _} (cong suc (+-comm n (suc n))) ⟩⌊log2⌋ (suc (suc n + n)) (<-wellFounded _) ≡⟨ cong suc (⌊log2⌋-cong-irr {a = suc ⌊ n + n /2⌋} refl) ⟩suc (⌊log2⌋ (suc ⌊ n + n /2⌋) (<-wellFounded _)) ≡⟨ cong suc (⌊log2⌋-cong-irr (cong suc (sym (n≡⌊n+n/2⌋ n)))) ⟩suc (⌊log2⌋ (suc n) _) ∎where open ≡-Reasoning⌊log2⌋2^n≡n : ∀ n {acc} → ⌊log2⌋ (2 ^ n) acc ≡ n⌊log2⌋2^n≡n zero = refl⌊log2⌋2^n≡n (suc n) = begin⌊log2⌋ ((2 ^ n) + ((2 ^ n) + zero)) _ ≡⟨ ⌊log2⌋2*b≡1+⌊log2⌋b (2 ^ n) {{m^n≢0 2 n}} ⟩1 + ⌊log2⌋ (2 ^ n) (<-wellFounded _) ≡⟨ cong suc (⌊log2⌋2^n≡n n) ⟩suc n ∎where open ≡-Reasoning-------------------------------------------------------------------------- Properties of ⌈log2⌉⌈log2⌉-acc-irrelevant : ∀ n {acc acc'} → ⌈log2⌉ n acc ≡ ⌈log2⌉ n acc'⌈log2⌉-acc-irrelevant zero {acc rs} {acc rs₁} = refl⌈log2⌉-acc-irrelevant (suc zero) {acc rs} {acc rs₁} = refl⌈log2⌉-acc-irrelevant (suc (suc n)) {acc rs} {acc rs'} =cong suc (⌈log2⌉-acc-irrelevant (suc ⌊ suc n /2⌋))⌈log2⌉-cong-irr : ∀ {m n} {acc acc'} → (_ : m ≡ n) →⌈log2⌉ m acc ≡ ⌈log2⌉ n acc'⌈log2⌉-cong-irr {acc = ac} refl = ⌈log2⌉-acc-irrelevant _ {ac}⌈log2⌉-mono-≤ : ∀ {m n} {acc acc'} → m ≤ n → ⌈log2⌉ m acc ≤ ⌈log2⌉ n acc'⌈log2⌉-mono-≤ {_} {_} z≤n = z≤n⌈log2⌉-mono-≤ {_} {_} (s≤s z≤n) = z≤n⌈log2⌉-mono-≤ {acc = acc rs} {acc rs'} (s≤s (s≤s p)) =s≤s (⌈log2⌉-mono-≤ (⌈n/2⌉-mono (+-monoʳ-≤ 2 p)))⌈log2⌉⌈n/2⌉≡⌈log2⌉n∸1 : ∀ n {acc} {acc'} →⌈log2⌉ ⌈ n /2⌉ acc ≡ ⌈log2⌉ n acc' ∸ 1⌈log2⌉⌈n/2⌉≡⌈log2⌉n∸1 zero {_} {_} = refl⌈log2⌉⌈n/2⌉≡⌈log2⌉n∸1 (suc zero) {_} {_} = refl⌈log2⌉⌈n/2⌉≡⌈log2⌉n∸1 (suc (suc n)) {acc rs} {acc rs'} =⌈log2⌉-acc-irrelevant (suc ⌊ suc n /2⌋)⌈log2⌉2*n≡1+⌈log2⌉n : ∀ n {acc acc'} .{{_ : NonZero n}} →⌈log2⌉ (2 * n) acc ≡ 1 + ⌈log2⌉ n acc'⌈log2⌉2*n≡1+⌈log2⌉n (suc n) = begin⌈log2⌉ (suc (n + suc (n + zero))) _ ≡⟨ ⌈log2⌉-cong-irr (cong (λ x → suc (n + suc x)) (+-comm n zero)) ⟩⌈log2⌉ (suc (n + suc n)) (<-wellFounded _) ≡⟨ ⌈log2⌉-cong-irr {acc' = <-wellFounded _} (cong suc (+-comm n (suc n))) ⟩⌈log2⌉ (suc (suc n + n)) (<-wellFounded _) ≡⟨ cong suc (⌈log2⌉-cong-irr {m = suc ⌈ n + n /2⌉} refl) ⟩suc (⌈log2⌉ (suc ⌈ n + n /2⌉) (<-wellFounded _)) ≡⟨ cong suc (⌈log2⌉-cong-irr (cong suc (sym (n≡⌈n+n/2⌉ n)))) ⟩suc (⌈log2⌉ (suc n) _) ∎where open ≡-Reasoning⌈log2⌉2^n≡n : ∀ n {acc} → ⌈log2⌉ (2 ^ n) acc ≡ n⌈log2⌉2^n≡n zero = refl⌈log2⌉2^n≡n (suc n) = begin⌈log2⌉ ((2 ^ n) + ((2 ^ n) + zero)) _ ≡⟨ ⌈log2⌉2*n≡1+⌈log2⌉n (2 ^ n) {{m^n≢0 2 n}} ⟩1 + ⌈log2⌉ (2 ^ n) (<-wellFounded _) ≡⟨ cong suc (⌈log2⌉2^n≡n n) ⟩suc n ∎where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Natural Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Agda.Builtin.Nat using (Nat)open import Data.Unit.Base using (⊤)number : Number Natnumber = record{ Constraint = λ _ → ⊤; fromNat = λ n → n}
-------------------------------------------------------------------------- The Agda standard library---- Least common multiple------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.LCM whereopen import Algebraopen import Data.Nat.Baseopen import Data.Nat.Coprimality using (Coprime)open import Data.Nat.Divisibilityopen import Data.Nat.DivModopen import Data.Nat.Propertiesopen import Data.Nat.GCDopen import Data.Product.Base using (_×_; _,_; uncurry′; ∃)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans; cong; cong₂; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Nullary.Decidable using (False; fromWitnessFalse)private-- instancegcd≢0ˡ : ∀ {m n} {{_ : NonZero m}} → NonZero (gcd m n)gcd≢0ˡ {m@(suc _)} {n} = ≢-nonZero (gcd[m,n]≢0 m n (inj₁ λ()))-------------------------------------------------------------------------- Definitionlcm : ℕ → ℕ → ℕlcm zero n = zerolcm m@(suc _) n = m * (n / gcd m n)where instance _ = gcd≢0ˡ {m} {n}-------------------------------------------------------------------------- Core propertiesprivaterearrange : ∀ m n .{{_ : NonZero m}} →lcm m n ≡ (m * n / gcd m n) {{gcd≢0ˡ {m} {n}}}rearrange m@(suc _) n = sym (*-/-assoc m {{gcd≢0ˡ {m} {n}}} (gcd[m,n]∣n m n))m∣lcm[m,n] : ∀ m n → m ∣ lcm m nm∣lcm[m,n] zero n = 0 ∣0m∣lcm[m,n] m@(suc _) n = m∣m*n (n / gcd m n)where instance _ = gcd≢0ˡ {m} {n}n∣lcm[m,n] : ∀ m n → n ∣ lcm m nn∣lcm[m,n] zero n = n ∣0n∣lcm[m,n] m@(suc m-1) n = beginn ∣⟨ m∣m*n (m / gcd m n) ⟩n * (m / gcd m n) ≡⟨ *-/-assoc n (gcd[m,n]∣m m n) ⟨n * m / gcd m n ≡⟨ cong (_/ gcd m n) (*-comm n m) ⟩m * n / gcd m n ≡⟨ rearrange m n ⟨m * (n / gcd m n) ∎where open ∣-Reasoning; instance _ = gcd≢0ˡ {m} {n}lcm-least : ∀ {m n c} → m ∣ c → n ∣ c → lcm m n ∣ clcm-least {zero} {n} {c} 0∣c _ = 0∣clcm-least {m@(suc _)} {n} {c} m∣c n∣c = subst (_∣ c) (sym (rearrange m n))(m∣n*o⇒m/n∣o gcd[m,n]∣m*n mn∣c*gcd)whereinstance _ = gcd≢0ˡ {m} {n}open ∣-Reasoninggcd[m,n]∣m*n : gcd m n ∣ m * ngcd[m,n]∣m*n = ∣-trans (gcd[m,n]∣m m n) (m∣m*n n)mn∣c*gcd : m * n ∣ c * gcd m nmn∣c*gcd = beginm * n ∣⟨ gcd-greatest (subst (_∣ c * m) (*-comm n m) (*-monoˡ-∣ m n∣c)) (*-monoˡ-∣ n m∣c) ⟩gcd (c * m) (c * n) ≡⟨ c*gcd[m,n]≡gcd[cm,cn] c m n ⟨c * gcd m n ∎-------------------------------------------------------------------------- Other properties-- Note that all other properties of `gcd` should be inferable from the-- 3 core properties above.gcd*lcm : ∀ m n → gcd m n * lcm m n ≡ m * ngcd*lcm zero n = *-zeroʳ (gcd 0 n)gcd*lcm m@(suc m-1) n = trans (cong (gcd m n *_) (rearrange m n)) (m*[n/m]≡n (begingcd m n ∣⟨ gcd[m,n]∣m m n ⟩m ∣⟨ m∣m*n n ⟩m * n ∎))where open ∣-Reasoning; instance gcd≢0 = gcd≢0ˡ {m} {n}lcm[0,n]≡0 : ∀ n → lcm 0 n ≡ 0lcm[0,n]≡0 n = 0∣⇒≡0 (m∣lcm[m,n] 0 n)lcm[n,0]≡0 : ∀ n → lcm n 0 ≡ 0lcm[n,0]≡0 n = 0∣⇒≡0 (n∣lcm[m,n] n 0)lcm-comm : ∀ m n → lcm m n ≡ lcm n mlcm-comm m n = ∣-antisym(lcm-least (n∣lcm[m,n] n m) (m∣lcm[m,n] n m))(lcm-least (n∣lcm[m,n] m n) (m∣lcm[m,n] m n))-------------------------------------------------------------------------- Least common multiple (lcm).module LCM where-- Specification of the least common multiple (lcm) of two natural-- numbers.record LCM (i j lcm : ℕ) : Set wherefield-- The lcm is a common multiple.commonMultiple : i ∣ lcm × j ∣ lcm-- The lcm divides all common multiples, i.e. the lcm is the least-- common multiple according to the partial order _∣_.least : ∀ {m} → i ∣ m × j ∣ m → lcm ∣ mopen LCM public-- The lcm is unique.unique : ∀ {d₁ d₂ m n} → LCM m n d₁ → LCM m n d₂ → d₁ ≡ d₂unique d₁ d₂ = ∣-antisym (LCM.least d₁ (LCM.commonMultiple d₂))(LCM.least d₂ (LCM.commonMultiple d₁))open LCM public using (LCM) hiding (module LCM)-------------------------------------------------------------------------- Calculating the LCMlcm-LCM : ∀ m n → LCM m n (lcm m n)lcm-LCM m n = record{ commonMultiple = m∣lcm[m,n] m n , n∣lcm[m,n] m n; least = uncurry′ lcm-least}mkLCM : ∀ m n → ∃ λ d → LCM m n dmkLCM m n = lcm m n , lcm-LCM m nGCD*LCM : ∀ {m n g l} → GCD m n g → LCM m n l → m * n ≡ g * lGCD*LCM {m} {n} {g} {l} gc lc = sym (beging * l ≡⟨ cong₂ _*_ (GCD.unique gc (gcd-GCD m n)) (LCM.unique lc (lcm-LCM m n)) ⟩gcd m n * lcm m n ≡⟨ gcd*lcm m n ⟩m * n ∎)where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Instances for natural numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Instances whereopen import Data.Nat.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceℕ-≡-isDecEquivalence = isDecEquivalence _≟_ℕ-≤-isDecTotalOrder = ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Definition of and lemmas related to "true infinitely often"------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.InfinitelyOften whereopen import Effect.Monad using (RawMonad)open import Level using (Level; 0ℓ)open import Data.Empty using (⊥-elim)open import Data.Nat.Base using (ℕ; _≤_; _⊔_; _+_; suc; zero; s≤s)open import Data.Nat.Propertiesopen import Data.Product.Base as Prod hiding (map)open import Data.Sum.Base using (inj₁; inj₂; _⊎_)open import Function.Base using (_∘_; id)open import Relation.Binary.PropositionalEquality.Core using (_≢_)open import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Negation using (¬¬-Monad; call/cc)open import Relation.Unary using (Pred; _∪_; _⊆_)open RawMonad (¬¬-Monad {a = 0ℓ})privatevariableℓ : Levelinfixr 1 _∪-Fin_-- Only true finitely often.Fin : Pred ℕ ℓ → Set ℓFin P = ∃ λ i → ∀ j → i ≤ j → ¬ P j-- A non-constructive definition of "true infinitely often".Inf : Pred ℕ ℓ → Set ℓInf P = ¬ Fin P-- Fin is preserved by binary sums._∪-Fin_ : ∀ {ℓp ℓq P Q} → Fin {ℓp} P → Fin {ℓq} Q → Fin (P ∪ Q)_∪-Fin_ {P = P} {Q} (i , ¬p) (j , ¬q) = (i ⊔ j , helper)whereopen ≤-Reasoninghelper : ∀ k → i ⊔ j ≤ k → ¬ (P ∪ Q) khelper k i⊔j≤k (inj₁ p) = ¬p k (begini ≤⟨ m≤m⊔n i j ⟩i ⊔ j ≤⟨ i⊔j≤k ⟩k ∎) phelper k i⊔j≤k (inj₂ q) = ¬q k (beginj ≤⟨ m≤m⊔n j i ⟩j ⊔ i ≡⟨ ⊔-comm j i ⟩i ⊔ j ≤⟨ i⊔j≤k ⟩k ∎) q-- Inf commutes with binary sums (in the double-negation monad).commutes-with-∪ : ∀ {P Q} → Inf (P ∪ Q) → ¬ ¬ (Inf P ⊎ Inf Q)commutes-with-∪ p∪q =call/cc λ ¬[p⊎q] →(λ ¬p ¬q → ⊥-elim (p∪q (¬p ∪-Fin ¬q)))<$> ¬[p⊎q] ∘ inj₁ ⊛ ¬[p⊎q] ∘ inj₂-- Inf is functorial.map : ∀ {ℓp ℓq P Q} → P ⊆ Q → Inf {ℓp} P → Inf {ℓq} Qmap P⊆Q ¬fin = ¬fin ∘ Prod.map id (λ fin j i≤j → fin j i≤j ∘ P⊆Q)-- Inf is upwards closed.up : ∀ {P} n → Inf {ℓ} P → Inf (P ∘ _+_ n)up zero = idup {P = P} (suc n) = up n ∘ up₁whereup₁ : Inf P → Inf (P ∘ suc)up₁ ¬fin (i , fin) = ¬fin (suc i , helper)wherehelper : ∀ j → 1 + i ≤ j → ¬ P jhelper ._ (s≤s i≤j) = fin _ i≤j-- A witness.witness : ∀ {P} → Inf {ℓ} P → ¬ ¬ ∃ Pwitness ¬fin ¬p = ¬fin (0 , λ i _ Pi → ¬p (i , Pi))-- Two different witnesses.twoDifferentWitnesses: ∀ {P} → Inf P → ¬ ¬ ∃₂ λ m n → m ≢ n × P m × P ntwoDifferentWitnesses inf =witness inf >>= λ w₁ →witness (up (1 + proj₁ w₁) inf) >>= λ w₂ →pure (_ , _ , m≢1+m+n (proj₁ w₁) , proj₂ w₁ , proj₂ w₂)
-------------------------------------------------------------------------- The Agda standard library---- Various forms of induction for natural numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Induction whereopen import Data.Nat.Baseopen import Data.Nat.Properties using (<⇒<′)open import Data.Product.Base using (_×_; _,_)open import Data.Unit.Polymorphic.Baseopen import Inductionopen import Induction.WellFounded as WFopen import Level using (Level)privatevariableℓ : Level-------------------------------------------------------------------------- Re-export accessabilityopen WF public using (Acc; acc)-------------------------------------------------------------------------- Ordinary inductionRec : ∀ ℓ → RecStruct ℕ ℓ ℓRec ℓ P zero = ⊤Rec ℓ P (suc n) = P nrecBuilder : RecursorBuilder (Rec ℓ)recBuilder P f zero = _recBuilder P f (suc n) = f n (recBuilder P f n)rec : Recursor (Rec ℓ)rec = build recBuilder-------------------------------------------------------------------------- Complete inductionCRec : ∀ ℓ → RecStruct ℕ ℓ ℓCRec ℓ P zero = ⊤CRec ℓ P (suc n) = P n × CRec ℓ P ncRecBuilder : RecursorBuilder (CRec ℓ)cRecBuilder P f zero = _cRecBuilder P f (suc n) = f n ih , ihwhere ih = cRecBuilder P f ncRec : Recursor (CRec ℓ)cRec = build cRecBuilder-------------------------------------------------------------------------- Complete induction based on _<′_<′-Rec : RecStruct ℕ ℓ ℓ<′-Rec = WfRec _<′_-- mutual definition<′-wellFounded : WellFounded _<′_<′-wellFounded′ : ∀ n → <′-Rec (Acc _<′_) n<′-wellFounded n = acc (<′-wellFounded′ n)<′-wellFounded′ (suc n) <′-base = <′-wellFounded n<′-wellFounded′ (suc n) (<′-step m<n) = <′-wellFounded′ n m<nmodule _ {ℓ : Level} whereopen WF.All <′-wellFounded ℓ publicrenaming ( wfRecBuilder to <′-recBuilder; wfRec to <′-rec)hiding (wfRec-builder)-------------------------------------------------------------------------- Complete induction based on _<_<-Rec : RecStruct ℕ ℓ ℓ<-Rec = WfRec _<_<-wellFounded : WellFounded _<_<-wellFounded = Subrelation.wellFounded <⇒<′ <′-wellFounded-- A version of `<-wellFounded` that cheats by skipping building-- the first billion proofs. Use this when you require the function-- using the proof of well-foundedness to evaluate fast.---- IMPORTANT: You have to be a little bit careful when using this to-- always make the function be strict in some other argument than the-- accessibility proof, otherwise you will have neutral terms unfolding-- a billion times before getting stuck.<-wellFounded-fast : WellFounded _<_<-wellFounded-fast = <-wellFounded-skip 1000000000where<-wellFounded-skip : ∀ (k : ℕ) → WellFounded _<_<-wellFounded-skip zero n = <-wellFounded n<-wellFounded-skip (suc k) zero = <-wellFounded 0<-wellFounded-skip (suc k) (suc n) = acc λ {m} _ → <-wellFounded-skip k mmodule _ {ℓ : Level} whereopen WF.All <-wellFounded ℓ publicrenaming ( wfRecBuilder to <-recBuilder; wfRec to <-rec)hiding (wfRec-builder)
-------------------------------------------------------------------------- The Agda standard library---- A generalisation of the arithmetic operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.GeneralisedArithmetic whereopen import Data.Nat.Base using (ℕ; zero; suc; _+_; _*_; _^_)open import Data.Nat.Properties using (+-comm; +-assoc; *-identityˡ;*-assoc)open import Function.Base using (_∘′_; _∘_; id)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablea : LevelA : Set afold : A → (A → A) → ℕ → Afold z s zero = zfold z s (suc n) = s (fold z s n)iterate : (A → A) → A → ℕ → Aiterate f x zero = xiterate f x (suc n) = iterate f (f x) nadd : (0# : A) (1+ : A → A) → ℕ → A → Aadd 0# 1+ n z = fold z 1+ nmul : (0# : A) (1+ : A → A) → (+ : A → A → A) → (ℕ → A → A)mul 0# 1+ _+_ n x = fold 0# (λ s → x + s) n-- Propertiesfold-+ : ∀ (z : A) (s : A → A) m {n} →fold z s (m + n) ≡ fold (fold z s n) s mfold-+ z s zero = reflfold-+ z s (suc m) = cong s (fold-+ z s m)fold-k : ∀ (z : A) (s : A → A) {k} m →fold k (s ∘′_) m z ≡ fold (k z) s mfold-k z s zero = reflfold-k z s (suc m) = cong s (fold-k z s m)fold-* : ∀ (z : A) (s : A → A) m {n} →fold z s (m * n) ≡ fold z (fold id (s ∘_) n) mfold-* z s zero = reflfold-* z s (suc m) {n} = let +n = fold id (s ∘′_) n in beginfold z s (n + m * n) ≡⟨ fold-+ z s n ⟩fold (fold z s (m * n)) s n ≡⟨ cong (λ z → fold z s n) (fold-* z s m) ⟩fold (fold z +n m) s n ≡⟨ sym (fold-k _ s n) ⟩fold z +n (suc m) ∎fold-pull : ∀ (z : A) (s : A → A) (g : A → A → A) (p : A)(eqz : g z p ≡ p)(eqs : ∀ l → s (g l p) ≡ g (s l) p) →∀ m → fold p s m ≡ g (fold z s m) pfold-pull z s _ _ eqz _ zero = sym eqzfold-pull z s g p eqz eqs (suc m) = begins (fold p s m) ≡⟨ cong s (fold-pull z s g p eqz eqs m) ⟩s (g (fold z s m) p) ≡⟨ eqs (fold z s m) ⟩g (s (fold z s m)) p ∎iterate-is-fold : ∀ (z : A) s m → fold z s m ≡ iterate s z miterate-is-fold z s zero = refliterate-is-fold z s (suc m) = beginfold z s (suc m) ≡⟨ cong (fold z s) (+-comm 1 m) ⟩fold z s (m + 1) ≡⟨ fold-+ z s m ⟩fold (s z) s m ≡⟨ iterate-is-fold (s z) s m ⟩iterate s (s z) m ∎id-is-fold : ∀ m → fold zero suc m ≡ mid-is-fold zero = reflid-is-fold (suc m) = cong suc (id-is-fold m)+-is-fold : ∀ m {n} → fold n suc m ≡ m + n+-is-fold zero = refl+-is-fold (suc m) = cong suc (+-is-fold m)*-is-fold : ∀ m {n} → fold zero (n +_) m ≡ m * n*-is-fold zero = refl*-is-fold (suc m) {n} = cong (n +_) (*-is-fold m)^-is-fold : ∀ {m} n → fold 1 (m *_) n ≡ m ^ n^-is-fold zero = refl^-is-fold {m} (suc n) = cong (m *_) (^-is-fold n)*+-is-fold : ∀ m n {p} → fold p (n +_) m ≡ m * n + p*+-is-fold m n {p} = beginfold p (n +_) m ≡⟨ fold-pull _ _ _+_ p refl(λ l → sym (+-assoc n l p)) m ⟩fold 0 (n +_) m + p ≡⟨ cong (_+ p) (*-is-fold m) ⟩m * n + p ∎^*-is-fold : ∀ m n {p} → fold p (m *_) n ≡ m ^ n * p^*-is-fold m n {p} = beginfold p (m *_) n ≡⟨ fold-pull _ _ _*_ p (*-identityˡ p)(λ l → sym (*-assoc m l p)) n ⟩fold 1 (m *_) n * p ≡⟨ cong (_* p) (^-is-fold n) ⟩m ^ n * p ∎
-------------------------------------------------------------------------- The Agda standard library---- Greatest common divisor------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.GCD whereopen import Data.Nat.Baseopen import Data.Nat.Divisibilityopen import Data.Nat.DivModopen import Data.Nat.GCD.Lemmasopen import Data.Nat.Propertiesopen import Data.Nat.Inductionusing (Acc; acc; <′-Rec; <′-recBuilder; <-wellFounded-fast)open import Data.Product.Baseusing (_×_; _,_; proj₂; proj₁; swap; uncurry′; ∃; map)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Function.Base using (_$_; _∘_)open import Induction using (build)open import Induction.Lexicographic using (_⊗_; [_⊗_])open import Relation.Binary.Definitions using (tri<; tri>; tri≈; Symmetric)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; subst; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Nullary.Decidable using (Dec)open import Relation.Nullary.Negation using (contradiction)import Relation.Nullary.Decidable as Decopen import Algebra.Definitions {A = ℕ} _≡_ as Algebrausing (Associative; Commutative; LeftIdentity; RightIdentity; LeftZero; RightZero; Zero)-------------------------------------------------------------------------- Definition-- Calculated via Euclid's algorithm. In order to show progress,-- avoiding the initial step where the first argument may increase, it-- is necessary to first define a version `gcd′` which assumes that the-- second argument is strictly smaller than the first. The full `gcd`-- function then compares the two arguments and applies `gcd′`-- accordingly.gcd′ : ∀ m n → Acc _<_ m → n < m → ℕgcd′ m zero _ _ = mgcd′ m n@(suc _) (acc rec) n<m = gcd′ n (m % n) (rec n<m) (m%n<n m n)gcd : ℕ → ℕ → ℕgcd m n with <-cmp m n... | tri< m<n _ _ = gcd′ n m (<-wellFounded-fast n) m<n... | tri≈ _ _ _ = m... | tri> _ _ n<m = gcd′ m n (<-wellFounded-fast m) n<m-------------------------------------------------------------------------- Core properties of gcd′gcd′[m,n]∣m,n : ∀ {m n} rec n<m → gcd′ m n rec n<m ∣ m × gcd′ m n rec n<m ∣ ngcd′[m,n]∣m,n {m} {zero} rec n<m = ∣-refl , m ∣0gcd′[m,n]∣m,n {m} {n@(suc _)} (acc rec) n<mwith gcd∣n , gcd∣m%n ← gcd′[m,n]∣m,n (rec n<m) (m%n<n m n)= ∣n∣m%n⇒∣m gcd∣n gcd∣m%n , gcd∣ngcd′-greatest : ∀ {m n c} rec n<m → c ∣ m → c ∣ n → c ∣ gcd′ m n rec n<mgcd′-greatest {m} {zero} rec n<m c∣m c∣n = c∣mgcd′-greatest {m} {n@(suc _)} (acc rec) n<m c∣m c∣n =gcd′-greatest (rec n<m) (m%n<n m n) c∣n (%-presˡ-∣ c∣m c∣n)-------------------------------------------------------------------------- Core properties of gcdgcd[m,n]∣m : ∀ m n → gcd m n ∣ mgcd[m,n]∣m m n with <-cmp m n... | tri< n<m _ _ = proj₂ (gcd′[m,n]∣m,n {n} {m} _ _)... | tri≈ _ _ _ = ∣-refl... | tri> _ _ m<n = proj₁ (gcd′[m,n]∣m,n {m} {n} _ _)gcd[m,n]∣n : ∀ m n → gcd m n ∣ ngcd[m,n]∣n m n with <-cmp m n... | tri< n<m _ _ = proj₁ (gcd′[m,n]∣m,n {n} {m} _ _)... | tri≈ _ ≡.refl _ = ∣-refl... | tri> _ _ m<n = proj₂ (gcd′[m,n]∣m,n {m} {n} _ _)gcd-greatest : ∀ {m n c} → c ∣ m → c ∣ n → c ∣ gcd m ngcd-greatest {m} {n} c∣m c∣n with <-cmp m n... | tri< n<m _ _ = gcd′-greatest _ _ c∣n c∣m... | tri≈ _ _ _ = c∣m... | tri> _ _ m<n = gcd′-greatest _ _ c∣m c∣n-------------------------------------------------------------------------- Other properties-- Note that all other properties of `gcd` should be inferable from the-- 3 core properties above.gcd[0,0]≡0 : gcd 0 0 ≡ 0gcd[0,0]≡0 = ∣-antisym (gcd 0 0 ∣0) (gcd-greatest (0 ∣0) (0 ∣0))gcd[m,n]≢0 : ∀ m n → m ≢ 0 ⊎ n ≢ 0 → gcd m n ≢ 0gcd[m,n]≢0 m n (inj₁ m≢0) eq = m≢0 (0∣⇒≡0 (subst (_∣ m) eq (gcd[m,n]∣m m n)))gcd[m,n]≢0 m n (inj₂ n≢0) eq = n≢0 (0∣⇒≡0 (subst (_∣ n) eq (gcd[m,n]∣n m n)))gcd[m,n]≡0⇒m≡0 : ∀ {m n} → gcd m n ≡ 0 → m ≡ 0gcd[m,n]≡0⇒m≡0 {zero} {n} eq = ≡.reflgcd[m,n]≡0⇒m≡0 {suc m} {n} eq = contradiction eq (gcd[m,n]≢0 (suc m) n (inj₁ λ()))gcd[m,n]≡0⇒n≡0 : ∀ m {n} → gcd m n ≡ 0 → n ≡ 0gcd[m,n]≡0⇒n≡0 m {zero} eq = ≡.reflgcd[m,n]≡0⇒n≡0 m {suc n} eq = contradiction eq (gcd[m,n]≢0 m (suc n) (inj₂ λ()))gcd-comm : Commutative gcdgcd-comm m n = ∣-antisym(gcd-greatest (gcd[m,n]∣n m n) (gcd[m,n]∣m m n))(gcd-greatest (gcd[m,n]∣n n m) (gcd[m,n]∣m n m))gcd-assoc : Associative gcdgcd-assoc m n p = ∣-antisym(gcd-greatest gcd[gcd[m,n],p]|m (gcd-greatest gcd[gcd[m,n],p]∣n gcd[gcd[m,n],p]∣p))(gcd-greatest (gcd-greatest gcd[m,gcd[n,p]]∣m gcd[m,gcd[n,p]]∣n) gcd[m,gcd[n,p]]∣p)whereopen ∣-Reasoninggcd[gcd[m,n],p]|m = begingcd (gcd m n) p ∣⟨ gcd[m,n]∣m (gcd m n) p ⟩gcd m n ∣⟨ gcd[m,n]∣m m n ⟩m ∎gcd[gcd[m,n],p]∣n = begingcd (gcd m n) p ∣⟨ gcd[m,n]∣m (gcd m n) p ⟩gcd m n ∣⟨ gcd[m,n]∣n m n ⟩n ∎gcd[gcd[m,n],p]∣p = gcd[m,n]∣n (gcd m n) pgcd[m,gcd[n,p]]∣m = gcd[m,n]∣m m (gcd n p)gcd[m,gcd[n,p]]∣n = begingcd m (gcd n p) ∣⟨ gcd[m,n]∣n m (gcd n p) ⟩gcd n p ∣⟨ gcd[m,n]∣m n p ⟩n ∎gcd[m,gcd[n,p]]∣p = begingcd m (gcd n p) ∣⟨ gcd[m,n]∣n m (gcd n p) ⟩gcd n p ∣⟨ gcd[m,n]∣n n p ⟩p ∎gcd-identityˡ : LeftIdentity 0 gcdgcd-identityˡ zero = ≡.reflgcd-identityˡ (suc _) = ≡.reflgcd-identityʳ : RightIdentity 0 gcdgcd-identityʳ zero = ≡.reflgcd-identityʳ (suc _) = ≡.reflgcd-identity : Algebra.Identity 0 gcdgcd-identity = gcd-identityˡ , gcd-identityʳgcd-zeroˡ : LeftZero 1 gcdgcd-zeroˡ n = ∣-antisym gcd[1,n]∣1 1∣gcd[1,n]wheregcd[1,n]∣1 = gcd[m,n]∣m 1 n1∣gcd[1,n] = 1∣ gcd 1 ngcd-zeroʳ : RightZero 1 gcdgcd-zeroʳ n = ∣-antisym gcd[n,1]∣1 1∣gcd[n,1]wheregcd[n,1]∣1 = gcd[m,n]∣n n 11∣gcd[n,1] = 1∣ gcd n 1gcd-zero : Zero 1 gcdgcd-zero = gcd-zeroˡ , gcd-zeroʳgcd-universality : ∀ {m n g} →(∀ {d} → d ∣ m × d ∣ n → d ∣ g) →(∀ {d} → d ∣ g → d ∣ m × d ∣ n) →g ≡ gcd m ngcd-universality {m} {n} forwards backwards with back₁ , back₂ ← backwards ∣-refl= ∣-antisym (gcd-greatest back₁ back₂) (forwards (gcd[m,n]∣m m n , gcd[m,n]∣n m n))-- This could be simplified with some nice backwards/forwards reasoning-- after the new function hierarchy is up and running.gcd[cm,cn]/c≡gcd[m,n] : ∀ c m n .{{_ : NonZero c}} → gcd (c * m) (c * n) / c ≡ gcd m ngcd[cm,cn]/c≡gcd[m,n] c m n = gcd-universality forwards backwardswhereforwards : ∀ {d : ℕ} → d ∣ m × d ∣ n → d ∣ gcd (c * m) (c * n) / cforwards {d} (d∣m , d∣n) = m*n∣o⇒n∣o/m c d (gcd-greatest (*-monoʳ-∣ c d∣m) (*-monoʳ-∣ c d∣n))backwards : ∀ {d : ℕ} → d ∣ gcd (c * m) (c * n) / c → d ∣ m × d ∣ nbackwards {d} d∣gcd[cm,cn]/cwith cd∣gcd[cm,n] ← m∣n/o⇒o*m∣n (gcd-greatest (m∣m*n m) (m∣m*n n)) d∣gcd[cm,cn]/c= *-cancelˡ-∣ c (∣-trans cd∣gcd[cm,n] (gcd[m,n]∣m (c * m) _)) ,*-cancelˡ-∣ c (∣-trans cd∣gcd[cm,n] (gcd[m,n]∣n (c * m) _))c*gcd[m,n]≡gcd[cm,cn] : ∀ c m n → c * gcd m n ≡ gcd (c * m) (c * n)c*gcd[m,n]≡gcd[cm,cn] zero m n = ≡.sym gcd[0,0]≡0c*gcd[m,n]≡gcd[cm,cn] c@(suc _) m n = beginc * gcd m n ≡⟨ cong (c *_) (≡.sym (gcd[cm,cn]/c≡gcd[m,n] c m n)) ⟩c * (gcd (c * m) (c * n) / c) ≡⟨ m*[n/m]≡n (gcd-greatest (m∣m*n m) (m∣m*n n)) ⟩gcd (c * m) (c * n) ∎where open ≡-Reasoninggcd[m,n]≤n : ∀ m n .{{_ : NonZero n}} → gcd m n ≤ ngcd[m,n]≤n m n = ∣⇒≤ (gcd[m,n]∣n m n)n/gcd[m,n]≢0 : ∀ m n .{{_ : NonZero n}} .{{gcd≢0 : NonZero (gcd m n)}} →n / gcd m n ≢ 0n/gcd[m,n]≢0 m n = m<n⇒n≢0 (m≥n⇒m/n>0 {n} {gcd m n} (gcd[m,n]≤n m n))m/gcd[m,n]≢0 : ∀ m n .{{_ : NonZero m}} .{{gcd≢0 : NonZero (gcd m n)}} →m / gcd m n ≢ 0m/gcd[m,n]≢0 m n rewrite gcd-comm m n = n/gcd[m,n]≢0 n m-------------------------------------------------------------------------- A formal specification of GCDmodule GCD where-- Specification of the greatest common divisor (gcd) of two natural-- numbers.record GCD (m n gcd : ℕ) : Set whereconstructor isfield-- The gcd is a common divisor.commonDivisor : gcd ∣ m × gcd ∣ n-- All common divisors divide the gcd, i.e. the gcd is the-- greatest common divisor according to the partial order _∣_.greatest : ∀ {d} → d ∣ m × d ∣ n → d ∣ gcdgcd∣m : gcd ∣ mgcd∣m = proj₁ commonDivisorgcd∣n : gcd ∣ ngcd∣n = proj₂ commonDivisoropen GCD public-- The gcd is unique.unique : ∀ {d₁ d₂ m n} → GCD m n d₁ → GCD m n d₂ → d₁ ≡ d₂unique d₁ d₂ = ∣-antisym (GCD.greatest d₂ (GCD.commonDivisor d₁))(GCD.greatest d₁ (GCD.commonDivisor d₂))-- The gcd relation is "symmetric".sym : ∀ {d m n} → GCD m n d → GCD n m dsym g = is (swap $ GCD.commonDivisor g) (GCD.greatest g ∘ swap)-- The gcd relation is "reflexive".refl : ∀ {n} → GCD n n nrefl = is (∣-refl , ∣-refl) proj₁-- The GCD of 0 and n is n.base : ∀ {n} → GCD 0 n nbase {n} = is (n ∣0 , ∣-refl) proj₂-- If d is the gcd of n and k, then it is also the gcd of n and-- n + k.step : ∀ {n k d} → GCD n k d → GCD n (n + k) dstep {n} {k} {d} g with d₁ , d₂ ← GCD.commonDivisor g= is (d₁ , ∣m∣n⇒∣m+n d₁ d₂) greatest′wheregreatest′ : ∀ {d′} → d′ ∣ n × d′ ∣ n + k → d′ ∣ dgreatest′ (d₁ , d₂) = GCD.greatest g (d₁ , ∣m+n∣m⇒∣n d₂ d₁)open GCD public using (GCD) hiding (module GCD)-- The function gcd fulfils the conditions required of GCDgcd-GCD : ∀ m n → GCD m n (gcd m n)gcd-GCD m n = record{ commonDivisor = gcd[m,n]∣m m n , gcd[m,n]∣n m n; greatest = uncurry′ gcd-greatest}-- Calculates the gcd of the arguments.mkGCD : ∀ m n → ∃ λ d → GCD m n dmkGCD m n = gcd m n , gcd-GCD m n-- gcd as a proposition is decidablegcd? : (m n d : ℕ) → Dec (GCD m n d)gcd? m n d =Dec.map′ (λ { ≡.refl → gcd-GCD m n }) (GCD.unique (gcd-GCD m n))(gcd m n ≟ d)GCD-* : ∀ {m n d c} .{{_ : NonZero c}} → GCD (m * c) (n * c) (d * c) → GCD m n dGCD-* {c = suc _} (GCD.is (dc∣nc , dc∣mc) dc-greatest) =GCD.is (*-cancelʳ-∣ _ dc∣nc , *-cancelʳ-∣ _ dc∣mc)λ {_} → *-cancelʳ-∣ _ ∘ dc-greatest ∘ map (*-monoˡ-∣ _) (*-monoˡ-∣ _)GCD-/ : ∀ {m n d c} .{{_ : NonZero c}} → c ∣ m → c ∣ n → c ∣ d →GCD m n d → GCD (m / c) (n / c) (d / c)GCD-/ {m} {n} {d} {c} {{x}}(divides-refl p) (divides-refl q) (divides-refl r) gcdrewrite m*n/n≡m p c {{x}} | m*n/n≡m q c {{x}} | m*n/n≡m r c {{x}} = GCD-* gcdGCD-/gcd : ∀ m n .{{_ : NonZero (gcd m n)}} → GCD (m / gcd m n) (n / gcd m n) 1GCD-/gcd m n rewrite ≡.sym (n/n≡1 (gcd m n)) =GCD-/ (gcd[m,n]∣m m n) (gcd[m,n]∣n m n) ∣-refl (gcd-GCD m n)-------------------------------------------------------------------------- Calculating the gcd-- The calculation also proves Bézout's lemma.module Bézout wheremodule Identity where-- If m and n have greatest common divisor d, then one of the-- following two equations is satisfied, for some numbers x and y.-- The proof is "lemma" below (Bézout's lemma).---- (If this identity was stated using integers instead of natural-- numbers, then it would not be necessary to have two equations.)data Identity (d m n : ℕ) : Set where+- : (x y : ℕ) (eq : d + y * n ≡ x * m) → Identity d m n-+ : (x y : ℕ) (eq : d + x * m ≡ y * n) → Identity d m n-- Various properties about Identity.sym : ∀ {d} → Symmetric (Identity d)sym (+- x y eq) = -+ y x eqsym (-+ x y eq) = +- y x eqrefl : ∀ {d} → Identity d d drefl = -+ 0 1 ≡.reflbase : ∀ {d} → Identity d 0 dbase = -+ 0 1 ≡.reflprivateinfixl 7 _⊕__⊕_ : ℕ → ℕ → ℕm ⊕ n = 1 + m + nstep : ∀ {d n k} → Identity d n k → Identity d n (n + k)step {d} {n} (+- x y eq) with compare x y... | equal x = +- (2 * x) x (lem₂ d x eq)... | less x i = +- (2 * x ⊕ i) (x ⊕ i) (lem₃ d x eq)... | greater y i = +- (2 * y ⊕ i) y (lem₄ d y n eq)step {d} {n} (-+ x y eq) with compare x y... | equal x = -+ (2 * x) x (lem₅ d x eq)... | less x i = -+ (2 * x ⊕ i) (x ⊕ i) (lem₆ d x eq)... | greater y i = -+ (2 * y ⊕ i) y (lem₇ d y n eq)open Identity public using (Identity; +-; -+) hiding (module Identity)module Lemma where-- This type packs up the gcd, the proof that it is a gcd, and the-- proof that it satisfies Bézout's identity.data Lemma (m n : ℕ) : Set whereresult : (d : ℕ) (g : GCD m n d) (b : Identity d m n) → Lemma m n-- Various properties about Lemma.sym : Symmetric Lemmasym (result d g b) = result d (GCD.sym g) (Identity.sym b)base : ∀ d → Lemma 0 dbase d = result d GCD.base Identity.baserefl : ∀ d → Lemma d drefl d = result d GCD.refl Identity.reflstepˡ : ∀ {n k} → Lemma n (suc k) → Lemma n (suc (n + k))stepˡ {n} {k} (result d g b) =subst (Lemma n) (+-suc n k) $result d (GCD.step g) (Identity.step b)stepʳ : ∀ {n k} → Lemma (suc k) n → Lemma (suc (n + k)) nstepʳ = sym ∘ stepˡ ∘ symopen Lemma public using (Lemma; result) hiding (module Lemma)-- Bézout's lemma proved using some variant of the extended-- Euclidean algorithm.lemma : (m n : ℕ) → Lemma m nlemma m n = build [ <′-recBuilder ⊗ <′-recBuilder ] P gcd″ (m , n)whereP : ℕ × ℕ → SetP (m , n) = Lemma m ngcd″ : ∀ p → (<′-Rec ⊗ <′-Rec) P p → P pgcd″ (zero , n) rec = Lemma.base ngcd″ (m@(suc _) , zero) rec = Lemma.sym (Lemma.base m)gcd″ (m′@(suc m) , n′@(suc n)) rec with compare m n... | equal m = Lemma.refl m′... | less m k = Lemma.stepˡ $ proj₁ rec (lem₁ k m)-- "gcd (suc m) (suc k)"... | greater n k = Lemma.stepʳ $ proj₂ rec (lem₁ k n) n′-- "gcd (suc k) (suc n)"-- Bézout's identity can be recovered from the GCD.identity : ∀ {m n d} → GCD m n d → Identity d m nidentity {m} {n} g with result d g′ b ← lemma m n rewrite GCD.unique g g′ = b
-------------------------------------------------------------------------- The Agda standard library---- Boring lemmas used in Data.Nat.GCD and Data.Nat.Coprimality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.GCD.Lemmas whereopen import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Function.Base using (_$_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; sym)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatecomm-factor : ∀ x k n → x * k + x * n ≡ x * (n + k)comm-factor x k n = beginx * k + x * n ≡⟨ +-comm (x * k) _ ⟩x * n + x * k ≡⟨ *-distribˡ-+ x n k ⟨x * (n + k) ∎distrib-comm₂ : ∀ d x k n → d + x * (n + k) ≡ d + x * k + x * ndistrib-comm₂ d x k n = begind + x * (n + k) ≡⟨ cong (d +_) (comm-factor x k n) ⟨d + (x * k + x * n) ≡⟨ +-assoc d _ _ ⟨d + x * k + x * n ∎-- Other properties-- TODO: Can this proof be simplified? An automatic solver which can-- handle ∸ would be nice...lem₀ : ∀ i j m n → i * m ≡ j * m + n → (i ∸ j) * m ≡ nlem₀ i j m n eq = begin(i ∸ j) * m ≡⟨ *-distribʳ-∸ m i j ⟩(i * m) ∸ (j * m) ≡⟨ cong (_∸ j * m) eq ⟩(j * m + n) ∸ (j * m) ≡⟨ cong (_∸ j * m) (+-comm (j * m) n) ⟩(n + j * m) ∸ (j * m) ≡⟨ m+n∸n≡m n (j * m) ⟩n ∎lem₁ : ∀ i j → 2 + i ≤′ 2 + j + ilem₁ i j = ≤⇒≤′ $ s≤s $ s≤s $ m≤n+m i jprivatetimes2 : ∀ x → x + x ≡ 2 * xtimes2 x = cong (x +_) (sym (+-identityʳ x))times2′ : ∀ x y → x * y + x * y ≡ 2 * x * ytimes2′ x y = beginx * y + x * y ≡⟨ times2 (x * y) ⟩2 * (x * y) ≡⟨ *-assoc 2 x y ⟨2 * x * y ∎lem₂ : ∀ d x {k n} →d + x * k ≡ x * n → d + x * (n + k) ≡ 2 * x * nlem₂ d x {k} {n} eq = begind + x * (n + k) ≡⟨ distrib-comm₂ d x k n ⟩d + x * k + x * n ≡⟨ cong (_+ x * n) eq ⟩x * n + x * n ≡⟨ times2′ x n ⟩2 * x * n ∎privatedistrib₃ : ∀ a b c x → (a + b + c) * x ≡ a * x + b * x + c * xdistrib₃ a b c x = begin(a + b + c) * x ≡⟨ *-distribʳ-+ x (a + b) c ⟩(a + b) * x + c * x ≡⟨ cong (_+ c * x) (*-distribʳ-+ x a b) ⟩a * x + b * x + c * x ∎lem₃₁ : ∀ a b c → a + (b + c) ≡ b + a + clem₃₁ a b c = begina + (b + c) ≡⟨ +-assoc a b c ⟨(a + b) + c ≡⟨ cong (_+ c) (+-comm a b) ⟩b + a + c ∎+-assoc-comm : ∀ a b c d → a + (b + c + d) ≡ (a + c) + (b + d)+-assoc-comm a b c d = begina + (b + c + d) ≡⟨ cong (a +_) (cong (_+ d) (+-comm b c)) ⟩a + (c + b + d) ≡⟨ cong (a +_) (+-assoc c b d) ⟩a + (c + (b + d)) ≡⟨ +-assoc a c _ ⟨(a + c) + (b + d) ∎*-on-right : ∀ a b c {d} → b * c ≡ d → a * b * c ≡ a * d*-on-right a b c {d} eq = begina * b * c ≡⟨ *-assoc a b c ⟩a * (b * c) ≡⟨ cong (a *_) eq ⟩a * d ∎*-on-left : ∀ a b c {d} → a * b ≡ d → a * (b * c) ≡ d * c*-on-left a b c {d} eq = begina * (b * c) ≡⟨ *-assoc a b c ⟨a * b * c ≡⟨ cong (_* c) eq ⟩d * c ∎+-on-right : ∀ a b c {d} → b + c ≡ d → a + b + c ≡ a + d+-on-right a b c {d} eq = begina + b + c ≡⟨ +-assoc a b c ⟩a + (b + c) ≡⟨ cong (a +_) eq ⟩a + d ∎+-on-left : ∀ a b c d → a + b ≡ d → a + (b + c) ≡ d + c+-on-left a b c d eq = begina + (b + c) ≡⟨ +-assoc a b c ⟨a + b + c ≡⟨ cong (_+ c) eq ⟩d + c ∎+-focus-mid : ∀ a b c d → a + b + c + d ≡ a + (b + c) + d+-focus-mid a b c d = begina + b + c + d ≡⟨ cong (_+ d) (+-assoc a b c) ⟩a + (b + c) + d ∎+-assoc-comm′ : ∀ a b c d → a + b + c + d ≡ a + (b + d) + c+-assoc-comm′ a b c d = begina + b + c + d ≡⟨ +-on-left a (b + c) d (a + b + c) (sym $ +-assoc a b c) ⟨a + (b + c + d) ≡⟨ cong (a +_) (+-on-right b c d (+-comm c d)) ⟩a + (b + (d + c)) ≡⟨ cong (a +_) (+-assoc b d c) ⟨a + (b + d + c) ≡⟨ +-assoc a _ c ⟨a + (b + d) + c ∎lem₃₂ : ∀ a b c n → a * n + (b * n + a * n + c * n) ≡ (a + a + (b + c)) * nlem₃₂ a b c n = begina * n + (b * n + a * n + c * n) ≡⟨ cong (a * n +_) (distrib₃ b a c n) ⟨a * n + (b + a + c) * n ≡⟨ *-distribʳ-+ n a _ ⟨(a + (b + a + c)) * n ≡⟨ cong (_* n) (+-assoc-comm a b a c) ⟩(a + a + (b + c)) * n ∎mid-to-right : ∀ a b c → a + 2 * b + c ≡ (a + b + c) + bmid-to-right a b c = begina + 2 * b + c ≡⟨ cong (λ x → a + x + c) (times2 b) ⟨a + (b + b) + c ≡⟨ +-assoc-comm′ a b c b ⟨a + b + c + b ∎mid-to-left : ∀ a b c → a + 2 * b + c ≡ b + (a + b + c)mid-to-left a b c = begina + 2 * b + c ≡⟨ cong (λ x → a + x + c) (times2 b) ⟨a + (b + b) + c ≡⟨ cong (_+ c) (+-on-left a b b _ (+-comm a b)) ⟩b + a + b + c ≡⟨ +-on-left b (a + b) c (b + a + b) (sym $ +-assoc b a b) ⟨b + (a + b + c) ∎lem₃ : ∀ d x {i k n} →d + (1 + x + i) * k ≡ x * n →d + (1 + x + i) * (n + k) ≡ (1 + 2 * x + i) * nlem₃ d x {i} {k} {n} eq = begind + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩d + y * k + y * n ≡⟨ cong (_+ y * n) eq ⟩x * n + y * n ≡⟨ cong (x * n +_) (distrib₃ 1 x i n) ⟩x * n + (1 * n + x * n + i * n) ≡⟨ lem₃₂ x 1 i n ⟩(x + x + (1 + i)) * n ≡⟨ cong (_* n) (cong (_+ (1 + i)) (times2 x)) ⟩(2 * x + (1 + i)) * n ≡⟨ cong (_* n) (lem₃₁ (2 * x) 1 i) ⟩(1 + 2 * x + i) * n ∎where y = 1 + x + ilem₄ : ∀ d y {k i} n →d + y * k ≡ (1 + y + i) * n →d + y * (n + k) ≡ (1 + 2 * y + i) * nlem₄ d y {k} {i} n eq = begind + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩d + y * k + y * n ≡⟨ cong (_+ y * n) eq ⟩(1 + y + i) * n + y * n ≡⟨ *-distribʳ-+ n (1 + y + i) y ⟨(1 + y + i + y) * n ≡⟨ cong (_* n) (mid-to-right 1 y i) ⟨(1 + 2 * y + i) * n ∎lem₅ : ∀ d x {n k} →d + x * n ≡ x * k →d + 2 * x * n ≡ x * (n + k)lem₅ d x {n} {k} eq = begind + 2 * x * n ≡⟨ cong (d +_) (times2′ x n) ⟨d + (x * n + x * n) ≡⟨ +-assoc d (x * n) _ ⟨d + x * n + x * n ≡⟨ cong (_+ x * n) eq ⟩x * k + x * n ≡⟨ comm-factor x k n ⟩x * (n + k) ∎lem₆ : ∀ d x {n i k} →d + x * n ≡ (1 + x + i) * k →d + (1 + 2 * x + i) * n ≡ (1 + x + i) * (n + k)lem₆ d x {n} {i} {k} eq = begind + (1 + 2 * x + i) * n ≡⟨ cong (λ z → d + z * n) (mid-to-left 1 x i) ⟩d + (x + y) * n ≡⟨ cong (d +_) (*-distribʳ-+ n x y) ⟩d + (x * n + y * n) ≡⟨ +-on-left d _ _ _ eq ⟩y * k + y * n ≡⟨ comm-factor y k n ⟩y * (n + k) ∎where y = 1 + x + ilem₇ : ∀ d y {i} n {k} →d + (1 + y + i) * n ≡ y * k →d + (1 + 2 * y + i) * n ≡ y * (n + k)lem₇ d y {i} n {k} eq = begind + (1 + 2 * y + i) * n ≡⟨ cong (λ z → d + z * n) (mid-to-right 1 y i) ⟩d + (1 + y + i + y) * n ≡⟨ cong (d +_) (*-distribʳ-+ n (1 + y + i) y) ⟩d + ((1 + y + i) * n + y * n) ≡⟨ +-on-left d _ _ _ eq ⟩y * k + y * n ≡⟨ comm-factor y k n ⟩y * (n + k) ∎lem₈ : ∀ {i j k q} x y →1 + y * j ≡ x * i → j * k ≡ q * i →k ≡ (x * k ∸ y * q) * ilem₈ {i} {j} {k} {q} x y eq eq′ =sym (lem₀ (x * k) (y * q) i k lemma)wherelemma = beginx * k * i ≡⟨ *-on-right x k i (*-comm k i) ⟩x * (i * k) ≡⟨ *-on-left x i k (sym eq) ⟩(1 + y * j) * k ≡⟨ +-comm k _ ⟩(y * j) * k + k ≡⟨ cong (_+ k) (*-assoc y j k) ⟩y * (j * k) + k ≡⟨ cong (λ n → y * n + k) eq′ ⟩y * (q * i) + k ≡⟨ cong (_+ k) (*-assoc y q i) ⟨y * q * i + k ∎lem₉ : ∀ {i j k q} x y →1 + x * i ≡ y * j → j * k ≡ q * i →k ≡ (y * q ∸ x * k) * ilem₉ {i} {j} {k} {q} x y eq eq′ =sym (lem₀ (y * q) (x * k) i k lemma)wherelem : ∀ a b c → a * b * c ≡ b * c * alem a b c = begina * b * c ≡⟨ *-assoc a b c ⟩a * (b * c) ≡⟨ *-comm a _ ⟩b * c * a ∎lemma = beginy * q * i ≡⟨ lem y q i ⟩q * i * y ≡⟨ cong (λ n → n * y) eq′ ⟨j * k * y ≡⟨ lem y j k ⟨y * j * k ≡⟨ cong (λ n → n * k) eq ⟨(1 + x * i) * k ≡⟨ +-comm k _ ⟩x * i * k + k ≡⟨ cong (_+ k) (*-on-right x i k (*-comm i k)) ⟩x * (k * i) + k ≡⟨ cong (_+ k) (*-assoc x k i) ⟨x * k * i + k ∎lem₁₀ : ∀ {a′} b c {d} e f → let a = suc a′ ina + b * (c * d * a) ≡ e * (f * d * a) →d ≡ 1lem₁₀ {a′} b c {d} e f eq =m*n≡1⇒n≡1 (e * f ∸ b * c) d(lem₀ (e * f) (b * c) d 1(*-cancelʳ-≡ (e * f * d) (b * c * d + 1) _ (begine * f * d * a ≡⟨ *-assoc₄₃ e f d a ⟩e * (f * d * a) ≡⟨ eq ⟨a + b * (c * d * a) ≡⟨ cong (a +_) (*-assoc₄₃ b c d a) ⟨a + b * c * d * a ≡⟨ +-comm a _ ⟩b * c * d * a + a ≡⟨ cong (b * c * d * a +_) (+-identityʳ a) ⟨b * c * d * a + (a + 0) ≡⟨ *-distribʳ-+ a (b * c * d) 1 ⟨(b * c * d + 1) * a ∎)))where a = suc a′*-assoc₄₃ : ∀ w x y z → w * x * y * z ≡ w * (x * y * z)*-assoc₄₃ w x y z = beginw * x * y * z ≡⟨ cong (_* z) (*-assoc w x y) ⟩w * (x * y) * z ≡⟨ *-assoc w _ z ⟩w * (x * y * z) ∎lem₁₁ : ∀ {i j m n k d} x y →1 + y * j ≡ x * i → i * k ≡ m * d → j * k ≡ n * d →k ≡ (x * m ∸ y * n) * dlem₁₁ {i} {j} {m} {n} {k} {d} x y eq eq₁ eq₂ =sym (lem₀ (x * m) (y * n) d k (beginx * m * d ≡⟨ *-on-right x m d (sym eq₁) ⟩x * (i * k) ≡⟨ *-on-left x i k (sym eq) ⟩(1 + y * j) * k ≡⟨ +-comm k _ ⟩y * j * k + k ≡⟨ cong (_+ k) (*-assoc y j k) ⟩y * (j * k) + k ≡⟨ cong (λ p → y * p + k) eq₂ ⟩y * (n * d) + k ≡⟨ cong (_+ k) (*-assoc y n d) ⟨y * n * d + k ∎))
-------------------------------------------------------------------------- The Agda standard library---- Divisibility------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Divisibility whereopen import Data.Nat.Baseopen import Data.Nat.DivModusing (m≡m%n+[m/n]*n; m%n≡m∸m/n*n; m*n/n≡m; m*n%n≡0; *-/-assoc)open import Data.Nat.Propertiesopen import Function.Base using (_∘′_; _$_; flip)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (0ℓ)open import Relation.Nullary.Decidable as Dec using (yes; no)open import Relation.Nullary.Negation.Core using (contradiction)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Preorder; Poset)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; Antisymmetric; Decidable)import Relation.Binary.Reasoning.Preorder as ≲-Reasoningopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; sym; cong; subst)open import Relation.Binary.Reasoning.Syntaxopen import Relation.Binary.PropositionalEquality.Propertiesusing (isEquivalence; module ≡-Reasoning)privatevariable d m n o p : ℕ-------------------------------------------------------------------------- Definition and derived propertiesopen import Data.Nat.Divisibility.Core public hiding (*-pres-∣)quotient≢0 : (m∣n : m ∣ n) → .{{NonZero n}} → NonZero (quotient m∣n)quotient≢0 m∣n rewrite _∣_.equality m∣n = m*n≢0⇒m≢0 (quotient m∣n)m∣n⇒n≡quotient*m : (m∣n : m ∣ n) → n ≡ (quotient m∣n) * mm∣n⇒n≡quotient*m m∣n = _∣_.equality m∣nm∣n⇒n≡m*quotient : (m∣n : m ∣ n) → n ≡ m * (quotient m∣n)m∣n⇒n≡m*quotient {m = m} m∣n rewrite _∣_.equality m∣n = *-comm (quotient m∣n) mquotient-∣ : (m∣n : m ∣ n) → (quotient m∣n) ∣ nquotient-∣ {m = m} m∣n = divides m (m∣n⇒n≡m*quotient m∣n)quotient>1 : (m∣n : m ∣ n) → m < n → 1 < quotient m∣nquotient>1 {m} {n} m∣n m<n = *-cancelˡ-< m 1 (quotient m∣n) $ begin-strictm * 1 ≡⟨ *-identityʳ m ⟩m <⟨ m<n ⟩n ≡⟨ m∣n⇒n≡m*quotient m∣n ⟩m * quotient m∣n ∎where open ≤-Reasoningquotient-< : (m∣n : m ∣ n) → .{{NonTrivial m}} → .{{NonZero n}} → quotient m∣n < nquotient-< {m} {n} m∣n = begin-strictquotient m∣n <⟨ m<m*n (quotient m∣n) m (nonTrivial⇒n>1 m) ⟩quotient m∣n * m ≡⟨ _∣_.equality m∣n ⟨n ∎where open ≤-Reasoning; instance _ = quotient≢0 m∣n-------------------------------------------------------------------------- Relating _/_ and quotientn/m≡quotient : (m∣n : m ∣ n) .{{_ : NonZero m}} → n / m ≡ quotient m∣nn/m≡quotient {m = m} (divides-refl q) = m*n/n≡m q m-------------------------------------------------------------------------- Relationship with _%_m%n≡0⇒n∣m : ∀ m n .{{_ : NonZero n}} → m % n ≡ 0 → n ∣ mm%n≡0⇒n∣m m n eq = divides (m / n) $ beginm ≡⟨ m≡m%n+[m/n]*n m n ⟩m % n + [m/n]*n ≡⟨ cong (_+ [m/n]*n) eq ⟩[m/n]*n ∎where open ≡-Reasoning; [m/n]*n = m / n * nn∣m⇒m%n≡0 : ∀ m n .{{_ : NonZero n}} → n ∣ m → m % n ≡ 0n∣m⇒m%n≡0 .(q * n) n (divides-refl q) = m*n%n≡0 q nm%n≡0⇔n∣m : ∀ m n .{{_ : NonZero n}} → m % n ≡ 0 ⇔ n ∣ mm%n≡0⇔n∣m m n = mk⇔ (m%n≡0⇒n∣m m n) (n∣m⇒m%n≡0 m n)-------------------------------------------------------------------------- Properties of _∣_ and _≤_∣⇒≤ : .{{_ : NonZero n}} → m ∣ n → m ≤ n∣⇒≤ {n@.(q * m)} {m} (divides-refl q@(suc p)) = m≤m+n m (p * m)>⇒∤ : .{{_ : NonZero n}} → m > n → m ∤ n>⇒∤ {n@(suc _)} n<m@(s<s _) m∣n = contradiction (∣⇒≤ m∣n) (<⇒≱ n<m)-------------------------------------------------------------------------- _∣_ is a partial order-- these could/should inherit from Algebra.Properties.Monoid.Divisibility∣-reflexive : _≡_ ⇒ _∣_∣-reflexive {n} refl = divides 1 (sym (*-identityˡ n))∣-refl : Reflexive _∣_∣-refl = ∣-reflexive refl∣-trans : Transitive _∣_∣-trans (divides-refl p) (divides-refl q) =divides (q * p) (sym (*-assoc q p _))∣-antisym : Antisymmetric _≡_ _∣_∣-antisym {m} {zero} _ q∣p = m∣n⇒n≡m*quotient q∣p∣-antisym {zero} {n} p∣q _ = sym (m∣n⇒n≡m*quotient p∣q)∣-antisym {suc m} {suc n} p∣q q∣p = ≤-antisym (∣⇒≤ p∣q) (∣⇒≤ q∣p)infix 4 _∣?__∣?_ : Decidable _∣_zero ∣? zero = yes (divides-refl 0)zero ∣? suc m = no ((λ()) ∘′ ∣-antisym (divides-refl 0))n@(suc _) ∣? m = Dec.map (m%n≡0⇔n∣m m n) (m % n ≟ 0)∣-isPreorder : IsPreorder _≡_ _∣_∣-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ∣-reflexive; trans = ∣-trans}∣-isPartialOrder : IsPartialOrder _≡_ _∣_∣-isPartialOrder = record{ isPreorder = ∣-isPreorder; antisym = ∣-antisym}∣-preorder : Preorder 0ℓ 0ℓ 0ℓ∣-preorder = record{ isPreorder = ∣-isPreorder}∣-poset : Poset 0ℓ 0ℓ 0ℓ∣-poset = record{ isPartialOrder = ∣-isPartialOrder}-------------------------------------------------------------------------- A reasoning module for the _∣_ relationmodule ∣-Reasoning whereprivate module Base = ≲-Reasoning ∣-preorderopen Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨; step-∼; step-≲)renaming (≲-go to ∣-go)open ∣-syntax _IsRelatedTo_ _IsRelatedTo_ ∣-go public-------------------------------------------------------------------------- Simple properties of _∣_infix 10 _∣0 1∣__∣0 : ∀ n → n ∣ 0n ∣0 = divides-refl 00∣⇒≡0 : 0 ∣ n → n ≡ 00∣⇒≡0 {n} 0∣n = ∣-antisym (n ∣0) 0∣n1∣_ : ∀ n → 1 ∣ n1∣ n = divides n (sym (*-identityʳ n))∣1⇒≡1 : n ∣ 1 → n ≡ 1∣1⇒≡1 {n} n∣1 = ∣-antisym n∣1 (1∣ n)n∣n : n ∣ nn∣n = ∣-refl-------------------------------------------------------------------------- Properties of _∣_ and _+_∣m∣n⇒∣m+n : d ∣ m → d ∣ n → d ∣ m + n∣m∣n⇒∣m+n (divides-refl p) (divides-refl q) =divides (p + q) (sym (*-distribʳ-+ _ p q))∣m+n∣m⇒∣n : d ∣ m + n → d ∣ m → d ∣ n∣m+n∣m⇒∣n {d} {m} {n} (divides p m+n≡p*d) (divides-refl q) =divides (p ∸ q) $ begin-equalityn ≡⟨ m+n∸n≡m n m ⟨n + m ∸ m ≡⟨ cong (_∸ m) (+-comm n m) ⟩m + n ∸ m ≡⟨ cong (_∸ m) m+n≡p*d ⟩p * d ∸ q * d ≡⟨ *-distribʳ-∸ d p q ⟨(p ∸ q) * d ∎where open ∣-Reasoning-------------------------------------------------------------------------- Properties of _∣_ and _*_n∣m*n : ∀ m {n} → n ∣ m * nn∣m*n m = divides m reflm∣m*n : ∀ {m} n → m ∣ m * nm∣m*n n = divides n (*-comm _ n)n∣m*n*o : ∀ m {n} o → n ∣ m * n * on∣m*n*o m o = ∣-trans (n∣m*n m) (m∣m*n o)∣m⇒∣m*n : ∀ n → d ∣ m → d ∣ m * n∣m⇒∣m*n n (divides-refl q) = ∣-trans (n∣m*n q) (m∣m*n n)∣n⇒∣m*n : ∀ m {n} → d ∣ n → d ∣ m * n∣n⇒∣m*n m {n} rewrite *-comm m n = ∣m⇒∣m*n mm*n∣⇒m∣ : ∀ m n → m * n ∣ d → m ∣ dm*n∣⇒m∣ m n (divides-refl q) = ∣n⇒∣m*n q (m∣m*n n)m*n∣⇒n∣ : ∀ m n → m * n ∣ d → n ∣ dm*n∣⇒n∣ m n rewrite *-comm m n = m*n∣⇒m∣ n m*-pres-∣ : o ∣ m → p ∣ n → o * p ∣ m * n*-pres-∣ {o} {m@.(q * o)} {p} {n@.(r * p)} (divides-refl q) (divides-refl r) =divides (q * r) ([m*n]*[o*p]≡[m*o]*[n*p] q o r p)*-monoʳ-∣ : ∀ o → m ∣ n → o * m ∣ o * n*-monoʳ-∣ o = *-pres-∣ (∣-refl {o})*-monoˡ-∣ : ∀ o → m ∣ n → m * o ∣ n * o*-monoˡ-∣ o = flip *-pres-∣ (∣-refl {o})*-cancelˡ-∣ : ∀ o .{{_ : NonZero o}} → o * m ∣ o * n → m ∣ n*-cancelˡ-∣ {m} {n} o o*m∣o*n = divides q $ *-cancelˡ-≡ n (q * m) o $ begin-equalityo * n ≡⟨ m∣n⇒n≡m*quotient o*m∣o*n ⟩o * m * q ≡⟨ *-assoc o m q ⟩o * (m * q) ≡⟨ cong (o *_) (*-comm q m) ⟨o * (q * m) ∎whereopen ∣-Reasoningq = quotient o*m∣o*n*-cancelʳ-∣ : ∀ o .{{_ : NonZero o}} → m * o ∣ n * o → m ∣ n*-cancelʳ-∣ {m} {n} o rewrite *-comm m o | *-comm n o = *-cancelˡ-∣ o-------------------------------------------------------------------------- Properties of _∣_ and _∸_∣m∸n∣n⇒∣m : ∀ d → n ≤ m → d ∣ m ∸ n → d ∣ n → d ∣ m∣m∸n∣n⇒∣m {n} {m} d n≤m (divides p m∸n≡p*d) (divides-refl q) =divides (p + q) $ begin-equalitym ≡⟨ m+[n∸m]≡n n≤m ⟨n + (m ∸ n) ≡⟨ +-comm n (m ∸ n) ⟩m ∸ n + n ≡⟨ cong (_+ n) m∸n≡p*d ⟩p * d + q * d ≡⟨ *-distribʳ-+ d p q ⟨(p + q) * d ∎where open ∣-Reasoning-------------------------------------------------------------------------- Properties of _∣_ and _/_m/n∣m : .{{_ : NonZero n}} → n ∣ m → m / n ∣ mm/n∣m {n} {m} n∣m = beginm / n ≡⟨ n/m≡quotient n∣m ⟩quotient n∣m ∣⟨ quotient-∣ n∣m ⟩m ∎where open ∣-Reasoningm*n∣o⇒m∣o/n : ∀ m n .{{_ : NonZero n}} → m * n ∣ o → m ∣ o / nm*n∣o⇒m∣o/n m n (divides-refl p) = divides p $ begin-equalityp * (m * n) / n ≡⟨ *-/-assoc p (n∣m*n m) ⟩p * ((m * n) / n) ≡⟨ cong (p *_) (m*n/n≡m m n) ⟩p * m ∎where open ∣-Reasoningm*n∣o⇒n∣o/m : ∀ m n .{{_ : NonZero m}} → m * n ∣ o → n ∣ (o / m)m*n∣o⇒n∣o/m m n rewrite *-comm m n = m*n∣o⇒m∣o/n n mm∣n/o⇒m*o∣n : .{{_ : NonZero o}} → o ∣ n → m ∣ n / o → m * o ∣ nm∣n/o⇒m*o∣n {o} {n@.(p * o)} {m} (divides-refl p) m∣p*o/o = beginm * o ∣⟨ *-monoˡ-∣ o (subst (m ∣_) (m*n/n≡m p o) m∣p*o/o) ⟩p * o ∎where open ∣-Reasoningm∣n/o⇒o*m∣n : .{{_ : NonZero o}} → o ∣ n → m ∣ n / o → o * m ∣ nm∣n/o⇒o*m∣n {o} {_} {m} rewrite *-comm o m = m∣n/o⇒m*o∣nm/n∣o⇒m∣o*n : .{{_ : NonZero n}} → n ∣ m → m / n ∣ o → m ∣ o * nm/n∣o⇒m∣o*n {n} {m@.(p * n)} {o} (divides-refl p) p*n/n∣o = beginp * n ∣⟨ *-monoˡ-∣ n (subst (_∣ o) (m*n/n≡m p n) p*n/n∣o) ⟩o * n ∎where open ∣-Reasoningm∣n*o⇒m/n∣o : .{{_ : NonZero n}} → n ∣ m → m ∣ o * n → m / n ∣ om∣n*o⇒m/n∣o {n} {m@.(p * n)} {o} (divides-refl p) pn∣on = beginm / n ≡⟨⟩p * n / n ≡⟨ m*n/n≡m p n ⟩p ∣⟨ *-cancelʳ-∣ n pn∣on ⟩o ∎where open ∣-Reasoning-------------------------------------------------------------------------- Properties of _∣_ and _%_∣n∣m%n⇒∣m : .{{_ : NonZero n}} → d ∣ n → d ∣ m % n → d ∣ m∣n∣m%n⇒∣m {n@.(p * d)} {d} {m} (divides-refl p) (divides q m%n≡qd) =divides (q + (m / n) * p) $ begin-equalitym ≡⟨ m≡m%n+[m/n]*n m n ⟩m % n + (m / n) * n ≡⟨ cong (_+ (m / n) * n) m%n≡qd ⟩q * d + (m / n) * n ≡⟨⟩q * d + (m / n) * (p * d) ≡⟨ cong (q * d +_) (*-assoc (m / n) p d) ⟨q * d + ((m / n) * p) * d ≡⟨ *-distribʳ-+ d q _ ⟨(q + (m / n) * p) * d ∎where open ∣-Reasoning%-presˡ-∣ : .{{_ : NonZero n}} → d ∣ m → d ∣ n → d ∣ m % n%-presˡ-∣ {n} {d} {m@.(p * d)} (divides-refl p) (divides q 1+n≡qd) =divides (p ∸ m / n * q) $ begin-equalitym % n ≡⟨ m%n≡m∸m/n*n m n ⟩m ∸ m / n * n ≡⟨ cong (λ v → m ∸ m / n * v) 1+n≡qd ⟩m ∸ m / n * (q * d) ≡⟨ cong (m ∸_) (*-assoc (m / n) q d) ⟨m ∸ (m / n * q) * d ≡⟨⟩p * d ∸ (m / n * q) * d ≡⟨ *-distribʳ-∸ d p (m / n * q) ⟨(p ∸ m / n * q) * d ∎where open ∣-Reasoning-------------------------------------------------------------------------- Properties of _∣_ and !_m≤n⇒m!∣n! : m ≤ n → m ! ∣ n !m≤n⇒m!∣n! m≤n = help (≤⇒≤′ m≤n)wherehelp : m ≤′ n → m ! ∣ n !help ≤′-refl = ∣-reflhelp {n = n} (≤′-step m≤n) = ∣n⇒∣m*n n (help m≤n)-------------------------------------------------------------------------- Properties of _HasNonTrivialDivisorLessThan_-- Smart constructorhasNonTrivialDivisor-≢ : .{{NonTrivial d}} → .{{NonZero n}} →d ≢ n → d ∣ n → n HasNonTrivialDivisorLessThan nhasNonTrivialDivisor-≢ d≢n d∣n= hasNonTrivialDivisor (≤∧≢⇒< (∣⇒≤ d∣n) d≢n) d∣n-- Monotonicity wrt ∣hasNonTrivialDivisor-∣ : m HasNonTrivialDivisorLessThan n → m ∣ o →o HasNonTrivialDivisorLessThan nhasNonTrivialDivisor-∣ (hasNonTrivialDivisor d<n d∣m) m∣o= hasNonTrivialDivisor d<n (∣-trans d∣m m∣o)-- Monotonicity wrt ≤hasNonTrivialDivisor-≤ : m HasNonTrivialDivisorLessThan n → n ≤ o →m HasNonTrivialDivisorLessThan ohasNonTrivialDivisor-≤ (hasNonTrivialDivisor d<n d∣m) n≤o= hasNonTrivialDivisor (<-≤-trans d<n n≤o) d∣m
-------------------------------------------------------------------------- The Agda standard library---- Core definition of divisibility-------------------------------------------------------------------------- The definition of divisibility is split out from-- `Data.Nat.Divisibility` to avoid a dependency cycle with-- `Data.Nat.DivMod`.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Divisibility.Core whereopen import Data.Nat.Base using (ℕ; _*_; _<_; NonTrivial)open import Data.Nat.Propertiesopen import Relation.Nullary.Negation using (¬_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl)privatevariable m n o p : ℕ-------------------------------------------------------------------------- Main definition---- m ∣ n is inhabited iff m divides n. Some sources, like Hardy and-- Wright's "An Introduction to the Theory of Numbers", require m to-- be non-zero. However, some things become a bit nicer if m is-- allowed to be zero. For instance, _∣_ becomes a partial order, and-- the gcd of 0 and 0 becomes defined.infix 4 _∣_ _∤_record _∣_ (m n : ℕ) : Set whereconstructor dividesfield quotient : ℕequality : n ≡ quotient * m_∤_ : Rel ℕ _m ∤ n = ¬ (m ∣ n)-- Smart constructorpattern divides-refl q = divides q reflopen _∣_ using (quotient) public-------------------------------------------------------------------------- Restricted divisor relation-- Relation for having a non-trivial divisor below a given bound.-- Useful when reasoning about primality.infix 10 _HasNonTrivialDivisorLessThan_record _HasNonTrivialDivisorLessThan_ (m n : ℕ) : Set whereconstructor hasNonTrivialDivisorfield{divisor} : ℕ.{{nontrivial}} : NonTrivial divisordivisor-< : divisor < ndivisor-∣ : divisor ∣ m-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.1*-pres-∣ : o ∣ m → p ∣ n → o * p ∣ m * n*-pres-∣ {o} {m@.(q * o)} {p} {n@.(r * p)} (divides-refl q) (divides-refl r) =divides (q * r) ([m*n]*[o*p]≡[m*o]*[n*p] q o r p){-# WARNING_ON_USAGE *-pres-∣"Warning: *-pres-∣ was deprecated in v2.1.Please use Data.Nat.Divisibility.*-pres-∣ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Natural number division------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.DivMod whereopen import Agda.Builtin.Nat using (div-helper; mod-helper)open import Data.Fin.Base using (Fin; toℕ; fromℕ<)open import Data.Fin.Properties using (nonZeroIndex; toℕ-fromℕ<)open import Data.Nat.Baseopen import Data.Nat.DivMod.Coreopen import Data.Nat.Divisibility.Coreopen import Data.Nat.Inductionopen import Data.Nat.Propertiesopen import Data.Product.Base using (_,_)open import Data.Sum.Base using (inj₁; inj₂)open import Function.Base using (_$_; _∘_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong; cong₂; refl; trans; _≢_; sym)open import Relation.Nullary.Negation using (contradiction)open ≤-Reasoningprivatevariablem n o p : ℕ-------------------------------------------------------------------------- Definitionsopen import Data.Nat.Base publicusing (_%_; _/_)-------------------------------------------------------------------------- Relationship between _%_ and _/_m≡m%n+[m/n]*n : ∀ m n .{{_ : NonZero n}} → m ≡ m % n + (m / n) * nm≡m%n+[m/n]*n m (suc n) = div-mod-lemma 0 0 m nm%n≡m∸m/n*n : ∀ m n .{{_ : NonZero n}} → m % n ≡ m ∸ (m / n) * nm%n≡m∸m/n*n m n = begin-equalitym % n ≡⟨ m+n∸n≡m (m % n) m/n*n ⟨m % n + m/n*n ∸ m/n*n ≡⟨ cong (_∸ m/n*n) (m≡m%n+[m/n]*n m n) ⟨m ∸ m/n*n ∎where m/n*n = (m / n) * n-------------------------------------------------------------------------- Properties of _%_%-congˡ : .{{_ : NonZero o}} → m ≡ n → m % o ≡ n % o%-congˡ refl = refl%-congʳ : .{{_ : NonZero m}} .{{_ : NonZero n}} → m ≡ n →o % m ≡ o % n%-congʳ refl = refln%1≡0 : ∀ n → n % 1 ≡ 0n%1≡0 = a[modₕ]1≡0n%n≡0 : ∀ n .{{_ : NonZero n}} → n % n ≡ 0n%n≡0 (suc n-1) = n[modₕ]n≡0 0 n-1m%n%n≡m%n : ∀ m n .{{_ : NonZero n}} → m % n % n ≡ m % nm%n%n≡m%n m (suc n-1) = modₕ-idem 0 m n-1[m+n]%n≡m%n : ∀ m n .{{_ : NonZero n}} → (m + n) % n ≡ m % n[m+n]%n≡m%n m (suc n-1) = a+n[modₕ]n≡a[modₕ]n 0 m n-1[m+kn]%n≡m%n : ∀ m k n .{{_ : NonZero n}} → (m + k * n) % n ≡ m % n[m+kn]%n≡m%n m zero n = cong (_% n) (+-identityʳ m)[m+kn]%n≡m%n m (suc k) n = begin-equality(m + (n + k * n)) % n ≡⟨ cong (_% n) (+-assoc m n (k * n)) ⟨(m + n + k * n) % n ≡⟨ [m+kn]%n≡m%n (m + n) k n ⟩(m + n) % n ≡⟨ [m+n]%n≡m%n m n ⟩m % n ∎m≤n⇒[n∸m]%m≡n%m : .{{_ : NonZero m}} → m ≤ n →(n ∸ m) % m ≡ n % mm≤n⇒[n∸m]%m≡n%m {m} {n} m≤n = begin-equality(n ∸ m) % m ≡⟨ [m+n]%n≡m%n (n ∸ m) m ⟨(n ∸ m + m) % m ≡⟨ cong (_% m) (m∸n+n≡m m≤n) ⟩n % m ∎m*n≤o⇒[o∸m*n]%n≡o%n : ∀ m {n o} .{{_ : NonZero n}} → m * n ≤ o →(o ∸ m * n) % n ≡ o % nm*n≤o⇒[o∸m*n]%n≡o%n m {n} {o} m*n≤o = begin-equality(o ∸ m * n) % n ≡⟨ [m+kn]%n≡m%n (o ∸ m * n) m n ⟨(o ∸ m * n + m * n) % n ≡⟨ cong (_% n) (m∸n+n≡m m*n≤o) ⟩o % n ∎m*n%n≡0 : ∀ m n .{{_ : NonZero n}} → (m * n) % n ≡ 0m*n%n≡0 m n@(suc _) = [m+kn]%n≡m%n 0 m nm%n<n : ∀ m n .{{_ : NonZero n}} → m % n < nm%n<n m (suc n-1) = s≤s (a[modₕ]n<n 0 m n-1)m%n≤n : ∀ m n .{{_ : NonZero n}} → m % n ≤ nm%n≤n m n = <⇒≤ (m%n<n m n)m%n≤m : ∀ m n .{{_ : NonZero n}} → m % n ≤ mm%n≤m m (suc n-1) = a[modₕ]n≤a 0 m n-1m≤n⇒m%n≡m : m ≤ n → m % suc n ≡ mm≤n⇒m%n≡m {m = m} m≤n with k , refl ← m≤n⇒∃[o]m+o≡n m≤n= a≤n⇒a[modₕ]n≡a 0 (m + k) m km<n⇒m%n≡m : .{{_ : NonZero n}} → m < n → m % n ≡ mm<n⇒m%n≡m {n = suc _} m<n = m≤n⇒m%n≡m (<⇒≤pred m<n)%-pred-≡0 : ∀ {m n} .{{_ : NonZero n}} → (suc m % n) ≡ 0 → (m % n) ≡ n ∸ 1%-pred-≡0 {m} {suc n-1} eq = a+1[modₕ]n≡0⇒a[modₕ]n≡n-1 0 n-1 m eqm<[1+n%d]⇒m≤[n%d] : ∀ {m} n d .{{_ : NonZero d}} → m < suc n % d → m ≤ n % dm<[1+n%d]⇒m≤[n%d] {m} n (suc d-1) = k<1+a[modₕ]n⇒k≤a[modₕ]n 0 m n d-1[1+m%d]≤1+n⇒[m%d]≤n : ∀ m n d .{{_ : NonZero d}} → 0 < suc m % d → suc m % d ≤ suc n → m % d ≤ n[1+m%d]≤1+n⇒[m%d]≤n m n (suc d-1) leq = 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k 0 n m d-1 leq%-distribˡ-+ : ∀ m n d .{{_ : NonZero d}} → (m + n) % d ≡ ((m % d) + (n % d)) % d%-distribˡ-+ m n d@(suc d-1) = begin-equality(m + n) % d ≡⟨ cong (λ v → (v + n) % d) (m≡m%n+[m/n]*n m d) ⟩(m % d + m / d * d + n) % d ≡⟨ cong (_% d) (+-assoc (m % d) _ n) ⟩(m % d + (m / d * d + n)) % d ≡⟨ cong (λ v → (m % d + v) % d) (+-comm _ n) ⟩(m % d + (n + m / d * d)) % d ≡⟨ cong (_% d) (+-assoc (m % d) n _) ⟨(m % d + n + m / d * d) % d ≡⟨ [m+kn]%n≡m%n (m % d + n) (m / d) d ⟩(m % d + n) % d ≡⟨ cong (λ v → (m % d + v) % d) (m≡m%n+[m/n]*n n d) ⟩(m % d + (n % d + (n / d) * d)) % d ≡⟨ cong (_% d) (+-assoc (m % d) (n % d) _) ⟨(m % d + n % d + (n / d) * d) % d ≡⟨ [m+kn]%n≡m%n (m % d + n % d) (n / d) d ⟩(m % d + n % d) % d ∎%-distribˡ-* : ∀ m n d .{{_ : NonZero d}} → (m * n) % d ≡ ((m % d) * (n % d)) % d%-distribˡ-* m n d = begin-equality(m * n) % d ≡⟨ cong (λ h → (h * n) % d) (m≡m%n+[m/n]*n m d) ⟩((m′ + k * d) * n) % d ≡⟨ cong (λ h → ((m′ + k * d) * h) % d) (m≡m%n+[m/n]*n n d) ⟩((m′ + k * d) * (n′ + j * d)) % d ≡⟨ cong (_% d) lemma ⟩(m′ * n′ + (m′ * j + (n′ + j * d) * k) * d) % d ≡⟨ [m+kn]%n≡m%n (m′ * n′) (m′ * j + (n′ + j * d) * k) d ⟩(m′ * n′) % d ≡⟨⟩((m % d) * (n % d)) % d ∎wherem′ = m % dn′ = n % dk = m / dj = n / dlemma : (m′ + k * d) * (n′ + j * d) ≡ m′ * n′ + (m′ * j + (n′ + j * d) * k) * dlemma = begin-equality(m′ + k * d) * (n′ + j * d) ≡⟨ *-distribʳ-+ (n′ + j * d) m′ (k * d) ⟩m′ * (n′ + j * d) + (k * d) * (n′ + j * d) ≡⟨ cong₂ _+_ (*-distribˡ-+ m′ n′ (j * d)) (*-comm (k * d) (n′ + j * d)) ⟩(m′ * n′ + m′ * (j * d)) + (n′ + j * d) * (k * d) ≡⟨ +-assoc (m′ * n′) (m′ * (j * d)) ((n′ + j * d) * (k * d)) ⟩m′ * n′ + (m′ * (j * d) + (n′ + j * d) * (k * d)) ≡⟨ cong (m′ * n′ +_) (cong₂ _+_ (*-assoc m′ j d) (*-assoc (n′ + j * d) k d)) ⟨m′ * n′ + ((m′ * j) * d + ((n′ + j * d) * k) * d) ≡⟨ cong (m′ * n′ +_) (*-distribʳ-+ d (m′ * j) ((n′ + j * d) * k)) ⟨m′ * n′ + (m′ * j + (n′ + j * d) * k) * d ∎%-remove-+ˡ : ∀ {m} n {d} .{{_ : NonZero d}} → d ∣ m → (m + n) % d ≡ n % d%-remove-+ˡ {m@.(p * d)} n {d} (divides-refl p) = begin-equality(m + n) % d ≡⟨⟩(p * d + n) % d ≡⟨ cong (_% d) (+-comm (p * d) n) ⟩(n + p * d) % d ≡⟨ [m+kn]%n≡m%n n p d ⟩n % d ∎%-remove-+ʳ : ∀ m {n d} .{{_ : NonZero d}} → d ∣ n → (m + n) % d ≡ m % d%-remove-+ʳ m {n} rewrite +-comm m n = %-remove-+ˡ {n} m-------------------------------------------------------------------------- Properties of _/_/-congˡ : .{{_ : NonZero o}} → m ≡ n → m / o ≡ n / o/-congˡ refl = refl/-congʳ : .{{_ : NonZero n}} .{{_ : NonZero o}} → n ≡ o → m / n ≡ m / o/-congʳ refl = refl0/n≡0 : ∀ n .{{_ : NonZero n}} → 0 / n ≡ 00/n≡0 (suc _) = refln/1≡n : ∀ n → n / 1 ≡ nn/1≡n n = a[divₕ]1≡a 0 nn/n≡1 : ∀ n .{{_ : NonZero n}} → n / n ≡ 1n/n≡1 (suc n-1) = n[divₕ]n≡1 n-1 n-1m*n/n≡m : ∀ m n .{{_ : NonZero n}} → m * n / n ≡ mm*n/n≡m m (suc n-1) = a*n[divₕ]n≡a 0 m n-1m/n*n≡m : ∀ {m n} .{{_ : NonZero n}} → n ∣ m → m / n * n ≡ mm/n*n≡m {n = n} (divides-refl q) = cong (_* n) (m*n/n≡m q n)m*[n/m]≡n : .{{_ : NonZero m}} → m ∣ n → m * (n / m) ≡ nm*[n/m]≡n {m} m∣n = trans (*-comm m (_ / m)) (m/n*n≡m m∣n)m/n*n≤m : ∀ m n .{{_ : NonZero n}} → (m / n) * n ≤ mm/n*n≤m m n = begin(m / n) * n ≤⟨ m≤m+n ((m / n) * n) (m % n) ⟩(m / n) * n + m % n ≡⟨ +-comm _ (m % n) ⟩m % n + (m / n) * n ≡⟨ m≡m%n+[m/n]*n m n ⟨m ∎m/n≤m : ∀ m n .{{_ : NonZero n}} → (m / n) ≤ mm/n≤m m n = *-cancelʳ-≤ (m / n) m n (begin(m / n) * n ≤⟨ m/n*n≤m m n ⟩m ≤⟨ m≤m*n m n ⟩m * n ∎)m/n<m : ∀ m n .{{_ : NonZero m}} .{{_ : NonZero n}} →1 < n → m / n < mm/n<m m n 1<n = *-cancelʳ-< _ (m / n) m $ begin-strictm / n * n ≤⟨ m/n*n≤m m n ⟩m <⟨ m<m*n m n 1<n ⟩m * n ∎/-mono-≤ : .{{_ : NonZero o}} .{{_ : NonZero p}} →m ≤ n → o ≥ p → m / o ≤ n / p/-mono-≤ m≤n (s≤s o≥p) = divₕ-mono-≤ 0 m≤n o≥p/-monoˡ-≤ : ∀ o .{{_ : NonZero o}} → m ≤ n → m / o ≤ n / o/-monoˡ-≤ o m≤n = /-mono-≤ m≤n (≤-refl {o})/-monoʳ-≤ : ∀ m {n o} .{{_ : NonZero n}} .{{_ : NonZero o}} →n ≥ o → m / n ≤ m / o/-monoʳ-≤ m n≥o = /-mono-≤ ≤-refl n≥o/-cancelʳ-≡ : ∀ {m n o} .{{_ : NonZero o}} →o ∣ m → o ∣ n → m / o ≡ n / o → m ≡ n/-cancelʳ-≡ {m} {n} {o} o∣m o∣n m/o≡n/o = begin-equalitym ≡⟨ m*[n/m]≡n {o} {m} o∣m ⟨o * (m / o) ≡⟨ cong (o *_) m/o≡n/o ⟩o * (n / o) ≡⟨ m*[n/m]≡n {o} {n} o∣n ⟩n ∎m<n⇒m/n≡0 : ∀ {m n} .{{_ : NonZero n}} → m < n → m / n ≡ 0m<n⇒m/n≡0 {m} {suc n-1} (s≤s m≤n) = divₕ-finish n-1 m n-1 m≤nm≥n⇒m/n>0 : ∀ {m n} .{{_ : NonZero n}} → m ≥ n → m / n > 0m≥n⇒m/n>0 {m@(suc _)} {n@(suc _)} m≥n = begin1 ≡⟨ n/n≡1 m ⟨m / m ≤⟨ /-monoʳ-≤ m m≥n ⟩m / n ∎m/n≡0⇒m<n : ∀ {m n} .{{_ : NonZero n}} → m / n ≡ 0 → m < nm/n≡0⇒m<n {m} {n@(suc _)} m/n≡0 with <-≤-connex m n... | inj₁ m<n = m<n... | inj₂ n≤m = contradiction m/n≡0 (≢-nonZero⁻¹ _)where instance _ = >-nonZero (m≥n⇒m/n>0 n≤m)m/n≢0⇒n≤m : ∀ {m n} .{{_ : NonZero n}} → m / n ≢ 0 → n ≤ mm/n≢0⇒n≤m {m} {n@(suc _)} m/n≢0 with <-≤-connex m n... | inj₁ m<n = contradiction (m<n⇒m/n≡0 m<n) m/n≢0... | inj₂ n≤m = n≤m+-distrib-/ : ∀ m n {d} .{{_ : NonZero d}} → m % d + n % d < d →(m + n) / d ≡ m / d + n / d+-distrib-/ m n {suc d-1} leq = +-distrib-divₕ 0 0 m n d-1 leq+-distrib-/-∣ˡ : ∀ {m} n {d} .{{_ : NonZero d}} →d ∣ m → (m + n) / d ≡ m / d + n / d+-distrib-/-∣ˡ {m@.(p * d)} n {d} (divides-refl p) = +-distrib-/ m n $ begin-strictm % d + n % d ≡⟨⟩p * d % d + n % d ≡⟨ cong (_+ n % d) (m*n%n≡0 p d) ⟩n % d <⟨ m%n<n n d ⟩d ∎+-distrib-/-∣ʳ : ∀ m {n} {d} .{{_ : NonZero d}} →d ∣ n → (m + n) / d ≡ m / d + n / d+-distrib-/-∣ʳ m {n@.(p * d)} {d} (divides-refl p) = +-distrib-/ m n $ begin-strictm % d + n % d ≡⟨⟩m % d + p * d % d ≡⟨ cong (m % d +_) (m*n%n≡0 p d) ⟩m % d + 0 ≡⟨ +-identityʳ _ ⟩m % d <⟨ m%n<n m d ⟩d ∎m/n≡1+[m∸n]/n : ∀ {m n} .{{_ : NonZero n}} → m ≥ n → m / n ≡ 1 + ((m ∸ n) / n)m/n≡1+[m∸n]/n {m@(suc m-1)} {n@(suc n-1)} m≥n = begin-equalitym / n ≡⟨⟩div-helper 0 n-1 m n-1 ≡⟨ divₕ-restart n-1 m n-1 m≥n ⟩div-helper 1 n-1 (m ∸ n) n-1 ≡⟨ divₕ-extractAcc 1 n-1 (m ∸ n) n-1 ⟩1 + (div-helper 0 n-1 (m ∸ n) n-1) ≡⟨⟩1 + (m ∸ n) / n ∎[m∸n]/n≡m/n∸1 : ∀ m n .{{_ : NonZero n}} → (m ∸ n) / n ≡ pred (m / n)[m∸n]/n≡m/n∸1 m n with <-≤-connex m n... | inj₁ m<n = begin-equality(m ∸ n) / n ≡⟨ m<n⇒m/n≡0 (≤-<-trans (m∸n≤m m n) m<n) ⟩0 ≡⟨⟩pred 0 ≡⟨ cong pred (m<n⇒m/n≡0 m<n) ⟨pred (m / n) ∎... | inj₂ n≥m = begin-equality(m ∸ n) / n ≡⟨⟩pred (1 + (m ∸ n) / n) ≡⟨ cong pred (m/n≡1+[m∸n]/n n≥m) ⟨pred (m / n) ∎m∣n⇒o%n%m≡o%m : ∀ m n o .{{_ : NonZero m}} .{{_ : NonZero n}} → m ∣ n →o % n % m ≡ o % mm∣n⇒o%n%m≡o%m m n@.(p * m) o (divides-refl p) = begin-equalityo % n % m ≡⟨⟩o % pm % m ≡⟨ %-congˡ (m%n≡m∸m/n*n o pm) ⟩(o ∸ o / pm * pm) % m ≡⟨ cong (λ # → (o ∸ #) % m) (*-assoc (o / pm) p m) ⟨(o ∸ o / pm * p * m) % m ≡⟨ m*n≤o⇒[o∸m*n]%n≡o%n (o / pm * p) lem ⟩o % m ∎wherepm = p * mlem : o / pm * p * m ≤ olem = begino / pm * p * m ≡⟨ *-assoc (o / pm) p m ⟩o / pm * pm ≤⟨ m/n*n≤m o pm ⟩o ∎m*n/m*o≡n/o : ∀ m n o .{{_ : NonZero o}} .{{_ : NonZero (m * o)}} →(m * n) / (m * o) ≡ n / om*n/m*o≡n/o m n o = helper (<-wellFounded n)whereinstance _ = m*n≢0 m ohelper : ∀ {n} → Acc _<_ n → (m * n) / (m * o) ≡ n / ohelper {n} (acc rec) with <-≤-connex n o... | inj₁ n<o = trans (m<n⇒m/n≡0 (*-monoʳ-< m n<o)) (sym (m<n⇒m/n≡0 n<o))where instance _ = m*n≢0⇒m≢0 m... | inj₂ n≥o = begin-equality(m * n) / (m * o) ≡⟨ m/n≡1+[m∸n]/n (*-monoʳ-≤ m n≥o) ⟩1 + (m * n ∸ m * o) / (m * o) ≡⟨ cong (suc ∘ (_/ (m * o))) (*-distribˡ-∸ m n o) ⟨1 + (m * (n ∸ o)) / (m * o) ≡⟨ cong suc (helper (rec n∸o<n)) ⟩1 + (n ∸ o) / o ≡⟨ m/n≡1+[m∸n]/n n≥o ⟨n / o ∎where n∸o<n = ∸-monoʳ-< (n≢0⇒n>0 (≢-nonZero⁻¹ o)) n≥om*n/o*n≡m/o : ∀ m n o .{{_ : NonZero o}} .{{_ : NonZero (o * n)}} →m * n / (o * n) ≡ m / om*n/o*n≡m/o m n o = begin-equalitym * n / (o * n) ≡⟨ /-congˡ (*-comm m n) ⟩n * m / (o * n) ≡⟨ /-congʳ (*-comm o n) ⟩n * m / (n * o) ≡⟨ m*n/m*o≡n/o n m o ⟩m / o ∎where instance_ : NonZero n_ = m*n≢0⇒n≢0 o_ : NonZero (n * o)_ = m*n≢0 n om<n*o⇒m/o<n : ∀ {m n o} .{{_ : NonZero o}} → m < n * o → m / o < nm<n*o⇒m/o<n {m} {1} {o} m<o rewrite *-identityˡ o = begin-strictm / o ≡⟨ m<n⇒m/n≡0 m<o ⟩0 <⟨ z<s ⟩1 ∎m<n*o⇒m/o<n {m} {suc n@(suc _)} {o} m<n*o = pred-cancel-< $ begin-strictpred (m / o) ≡⟨ [m∸n]/n≡m/n∸1 m o ⟨(m ∸ o) / o <⟨ m<n*o⇒m/o<n (m<n+o⇒m∸n<o m o m<n*o) ⟩n ∎where instance _ = m*n≢0 n o[m∸n*o]/o≡m/o∸n : ∀ m n o .{{_ : NonZero o}} → (m ∸ n * o) / o ≡ m / o ∸ n[m∸n*o]/o≡m/o∸n m zero o = refl[m∸n*o]/o≡m/o∸n m (suc n) o = begin-equality(m ∸ (o + n * o)) / o ≡⟨ /-congˡ (∸-+-assoc m o (n * o)) ⟨(m ∸ o ∸ n * o) / o ≡⟨ [m∸n*o]/o≡m/o∸n (m ∸ o) n o ⟩(m ∸ o) / o ∸ n ≡⟨ cong (_∸ n) ([m∸n]/n≡m/n∸1 m o) ⟩m / o ∸ 1 ∸ n ≡⟨ ∸-+-assoc (m / o) 1 n ⟩m / o ∸ suc n ∎m/n/o≡m/[n*o] : ∀ m n o .{{_ : NonZero n}} .{{_ : NonZero o}}.{{_ : NonZero (n * o)}} → m / n / o ≡ m / (n * o)m/n/o≡m/[n*o] m n o = begin-equalitym / n / o ≡⟨ /-congˡ {o = o} (/-congˡ (m≡m%n+[m/n]*n m n*o)) ⟩(m % n*o + m / n*o * n*o) / n / o ≡⟨ /-congˡ (+-distrib-/-∣ʳ (m % n*o) lem₁) ⟩(m % n*o / n + m / n*o * n*o / n) / o ≡⟨ cong (λ # → (m % n*o / n + #) / o) lem₂ ⟩(m % n*o / n + m / n*o * o) / o ≡⟨ +-distrib-/-∣ʳ (m % n*o / n) (divides-refl (m / n*o)) ⟩m % n*o / n / o + m / n*o * o / o ≡⟨ cong (m % n*o / n / o +_) (m*n/n≡m (m / n*o) o) ⟩m % n*o / n / o + m / n*o ≡⟨ cong (_+ m / n*o) (m<n⇒m/n≡0 (m<n*o⇒m/o<n {n = o} lem₃)) ⟩m / n*o ∎wheren*o = n * oo*n = o * nlem₁ : n ∣ m / n*o * n*olem₁ = divides (m / n*o * o) $ begin-equalitym / n*o * n*o ≡⟨ cong (m / n*o *_) (*-comm n o) ⟩m / n*o * o*n ≡⟨ *-assoc (m / n*o) o n ⟨m / n*o * o * n ∎lem₂ : m / n*o * n*o / n ≡ m / n*o * olem₂ = begin-equalitym / n*o * n*o / n ≡⟨ cong (λ # → m / n*o * # / n) (*-comm n o) ⟩m / n*o * o*n / n ≡⟨ /-congˡ (*-assoc (m / n*o) o n) ⟨m / n*o * o * n / n ≡⟨ m*n/n≡m (m / n*o * o) n ⟩m / n*o * o ∎lem₃ : m % n*o < o*nlem₃ = begin-strictm % n*o <⟨ m%n<n m n*o ⟩n*o ≡⟨ *-comm n o ⟩o*n ∎*-/-assoc : ∀ m {n d} .{{_ : NonZero d}} → d ∣ n → m * n / d ≡ m * (n / d)*-/-assoc zero {_} {d} d∣n = 0/n≡0 d*-/-assoc (suc m) {n} {d} d∣n = begin-equality(n + m * n) / d ≡⟨ +-distrib-/-∣ˡ _ d∣n ⟩n / d + (m * n) / d ≡⟨ cong (n / d +_) (*-/-assoc m d∣n) ⟩n / d + m * (n / d) ∎/-*-interchange : .{{_ : NonZero o}} .{{_ : NonZero p}} .{{_ : NonZero (o * p)}} →o ∣ m → p ∣ n → (m * n) / (o * p) ≡ (m / o) * (n / p)/-*-interchange {o} {p} {m@.(q * o)} {n@.(r * p)} (divides-refl q) (divides-refl r)= begin-equality(m * n) / (o * p) ≡⟨⟩q * o * (r * p) / (o * p) ≡⟨ /-congˡ ([m*n]*[o*p]≡[m*o]*[n*p] q o r p) ⟩q * r * (o * p) / (o * p) ≡⟨ m*n/n≡m (q * r) (o * p) ⟩q * r ≡⟨ cong₂ _*_ (m*n/n≡m q o) (m*n/n≡m r p) ⟨(q * o / o) * (r * p / p) ≡⟨⟩(m / o) * (n / p) ∎m*n/m!≡n/[m∸1]! : ∀ m n .{{_ : NonZero m}} →let instance _ = m !≢0 ; instance _ = (pred m) !≢0 in(m * n / m !) ≡ (n / (pred m) !)m*n/m!≡n/[m∸1]! m′@(suc m) n = m*n/m*o≡n/o m′ n (m !)where instance_ = m !≢0_ = m′ !≢0m%[n*o]/o≡m/o%n : ∀ m n o .{{_ : NonZero n}} .{{_ : NonZero o}} →{{_ : NonZero (n * o)}} → m % (n * o) / o ≡ m / o % nm%[n*o]/o≡m/o%n m n o = begin-equalitym % (n * o) / o ≡⟨ /-congˡ (m%n≡m∸m/n*n m (n * o)) ⟩(m ∸ (m / (n * o) * (n * o))) / o ≡⟨ cong (λ # → (m ∸ #) / o) (*-assoc (m / (n * o)) n o) ⟨(m ∸ (m / (n * o) * n * o)) / o ≡⟨ [m∸n*o]/o≡m/o∸n m (m / (n * o) * n) o ⟩m / o ∸ m / (n * o) * n ≡⟨ cong (λ # → m / o ∸ # * n) (/-congʳ (*-comm n o)) ⟩m / o ∸ m / (o * n) * n ≡⟨ cong (λ # → m / o ∸ # * n) (m/n/o≡m/[n*o] m o n ) ⟨m / o ∸ m / o / n * n ≡⟨ m%n≡m∸m/n*n (m / o) n ⟨m / o % n ∎where instance _ = m*n≢0 o nm%n*o≡m*o%[n*o] : ∀ m n o .{{_ : NonZero n}} .{{_ : NonZero (n * o)}} →m % n * o ≡ m * o % (n * o)m%n*o≡m*o%[n*o] m n o = begin-equalitym % n * o ≡⟨ cong (_* o) (m%n≡m∸m/n*n m n) ⟩(m ∸ m / n * n) * o ≡⟨ *-distribʳ-∸ o m (m / n * n) ⟩m * o ∸ m / n * n * o ≡⟨ cong (λ # → m * o ∸ # * n * o) (m*n/o*n≡m/o m o n) ⟨m * o ∸ m * o / (n * o) * n * o ≡⟨ cong (m * o ∸_) (*-assoc (m * o / (n * o)) n o) ⟩m * o ∸ m * o / (n * o) * (n * o) ≡⟨ m%n≡m∸m/n*n (m * o) (n * o) ⟨m * o % (n * o) ∎[m*n+o]%[p*n]≡[m*n]%[p*n]+o : ∀ m {n o} p .{{_ : NonZero (p * n)}} → o < n →(m * n + o) % (p * n) ≡ (m * n) % (p * n) + o[m*n+o]%[p*n]≡[m*n]%[p*n]+o m {n} {o} p@(suc p-1) o<n = begin-equality(mn + o) % pn ≡⟨ %-distribˡ-+ mn o pn ⟩(mn % pn + o % pn) % pn ≡⟨ cong (λ # → (mn % pn + #) % pn) (m<n⇒m%n≡m (m<n⇒m<o*n p o<n)) ⟩(mn % pn + o) % pn ≡⟨ m<n⇒m%n≡m lem₂ ⟩mn % pn + o ∎wheremn = m * npn = p * nlem₁ : mn % pn ≤ p-1 * nlem₁ = beginmn % pn ≡⟨ m%n*o≡m*o%[n*o] m p n ⟨(m % p) * n ≤⟨ *-monoˡ-≤ n (m<1+n⇒m≤n (m%n<n m p)) ⟩p-1 * n ∎lem₂ : mn % pn + o < pnlem₂ = begin-strictmn % pn + o <⟨ +-mono-≤-< lem₁ o<n ⟩p-1 * n + n ≡⟨ +-comm (p-1 * n) n ⟩pn ∎-------------------------------------------------------------------------- A specification of integer division.record DivMod (dividend divisor : ℕ) : Set whereconstructor resultfieldquotient : ℕremainder : Fin divisorproperty : dividend ≡ toℕ remainder + quotient * divisornonZeroDivisor : NonZero divisornonZeroDivisor = nonZeroIndex remainderinfixl 7 _div_ _mod_ _divMod__div_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → ℕ_div_ = _/__mod_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → Fin divisorm mod n = fromℕ< (m%n<n m n)_divMod_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} →DivMod dividend divisorm divMod n = result (m / n) (m mod n) $ begin-equalitym ≡⟨ m≡m%n+[m/n]*n m n ⟩m % n + [m/n]*n ≡⟨ cong (_+ [m/n]*n) (toℕ-fromℕ< [m%n]<n) ⟨toℕ (fromℕ< [m%n]<n) + [m/n]*n ∎where [m/n]*n = m / n * n ; [m%n]<n = m%n<n m n
-------------------------------------------------------------------------- The Agda standard library---- More efficient mod and divMod operations (require the K axiom)------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.Nat.DivMod.WithK whereopen import Data.Nat.Base using (ℕ; NonZero; _+_; _*_)open import Data.Nat.DivMod hiding (_mod_; _divMod_)open import Data.Nat.Properties using (≤⇒≤″)open import Data.Nat.WithK using (≤″-erase)open import Data.Fin.Base using (Fin; toℕ; fromℕ<″)open import Data.Fin.Properties using (toℕ-fromℕ<″)open import Function.Base using (_$_)open import Relation.Binary.PropositionalEquality.Core using (cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Binary.PropositionalEquality.WithK using (≡-erase)open ≡-Reasoninginfixl 7 _mod_ _divMod_-------------------------------------------------------------------------- Certified modulus_mod_ : (dividend divisor : ℕ) → .{{ _ : NonZero divisor }} → Fin divisorm mod n = fromℕ<″ (m % n) (≤″-erase (≤⇒≤″ (m%n<n m n)))-------------------------------------------------------------------------- Returns modulus and division result with correctness proof_divMod_ : (dividend divisor : ℕ) → .{{ NonZero divisor }} →DivMod dividend divisorm divMod n = result (m / n) (m mod n) $ ≡-erase $ beginm ≡⟨ m≡m%n+[m/n]*n m n ⟩m % n + [m/n]*n ≡⟨ cong (_+ [m/n]*n) (toℕ-fromℕ<″ lemma″) ⟨toℕ (fromℕ<″ _ lemma″) + [m/n]*n ∎where [m/n]*n = m / n * n ; lemma″ = ≤″-erase (≤⇒≤″ (m%n<n m n))
-------------------------------------------------------------------------- The Agda standard library---- Core lemmas for division and modulus operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.DivMod.Core whereopen import Agda.Builtin.Nat using ()renaming (div-helper to divₕ; mod-helper to modₕ)open import Data.Nat.Base using (zero; suc; _+_; _*_; _∸_; _≤_; _<_;_≥_; z≤n; s≤s)open import Data.Nat.Propertiesopen import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Product.Base using (_×_; _,_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym; subst; trans)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation using (contradiction)open ≤-Reasoning-------------------------------------------------------------------------- Helper lemmas that have no interpretation for _%_, only for modₕprivatemod-cong₃ : ∀ {c n a₁ a₂ b} → a₁ ≡ a₂ → modₕ c n a₁ b ≡ modₕ c n a₂ bmod-cong₃ refl = reflmodₕ-skipTo0 : ∀ acc n a b → modₕ acc n (b + a) a ≡ modₕ (a + acc) n b 0modₕ-skipTo0 acc n zero b = cong (λ v → modₕ acc n v 0) (+-identityʳ b)modₕ-skipTo0 acc n (suc a) b = begin-equalitymodₕ acc n (b + suc a) (suc a) ≡⟨ mod-cong₃ (+-suc b a) ⟩modₕ acc n (suc b + a) (suc a) ≡⟨⟩modₕ (suc acc) n (b + a) a ≡⟨ modₕ-skipTo0 (suc acc) n a b ⟩modₕ (a + suc acc) n b 0 ≡⟨ cong (λ v → modₕ v n b 0) (+-suc a acc) ⟩modₕ (suc a + acc) n b 0 ∎-------------------------------------------------------------------------- Lemmas for modₕ that also have an interpretation for _%_a[modₕ]1≡0 : ∀ a → modₕ 0 0 a 0 ≡ 0a[modₕ]1≡0 zero = refla[modₕ]1≡0 (suc a) = a[modₕ]1≡0 an[modₕ]n≡0 : ∀ acc v → modₕ acc (acc + v) (suc v) v ≡ 0n[modₕ]n≡0 acc v = modₕ-skipTo0 acc (acc + v) v 1a[modₕ]n<n : ∀ acc d n → modₕ acc (acc + n) d n ≤ acc + na[modₕ]n<n acc zero n = m≤m+n acc na[modₕ]n<n acc (suc d) zero = a[modₕ]n<n zero d (acc + 0)a[modₕ]n<n acc (suc d) (suc n) rewrite +-suc acc n = a[modₕ]n<n (suc acc) d na[modₕ]n≤a : ∀ acc a n → modₕ acc (acc + n) a n ≤ acc + aa[modₕ]n≤a acc zero n = ≤-reflexive (sym (+-identityʳ acc))a[modₕ]n≤a acc (suc a) (suc n) = beginmodₕ acc (acc + suc n) (suc a) (suc n) ≡⟨ cong (λ v → modₕ acc v (suc a) (suc n)) (+-suc acc n) ⟩modₕ acc (suc acc + n) (suc a) (suc n) ≤⟨ a[modₕ]n≤a (suc acc) a n ⟩suc acc + a ≡⟨ sym (+-suc acc a) ⟩acc + suc a ∎a[modₕ]n≤a acc (suc a) zero = beginmodₕ acc (acc + 0) (suc a) 0 ≡⟨ cong (λ v → modₕ acc v (suc a) 0) (+-identityʳ acc) ⟩modₕ acc acc (suc a) 0 ≤⟨ a[modₕ]n≤a 0 a acc ⟩a ≤⟨ n≤1+n a ⟩suc a ≤⟨ m≤n+m (suc a) acc ⟩acc + suc a ∎a≤n⇒a[modₕ]n≡a : ∀ acc n a b → modₕ acc n a (a + b) ≡ acc + aa≤n⇒a[modₕ]n≡a acc n zero b = sym (+-identityʳ acc)a≤n⇒a[modₕ]n≡a acc n (suc a) b = begin-equalitymodₕ (suc acc) n a (a + b) ≡⟨ a≤n⇒a[modₕ]n≡a (suc acc) n a b ⟩suc acc + a ≡⟨ sym (+-suc acc a) ⟩acc + suc a ∎modₕ-idem : ∀ acc a n → modₕ 0 (acc + n) (modₕ acc (acc + n) a n) (acc + n) ≡ modₕ acc (acc + n) a nmodₕ-idem acc zero n = a≤n⇒a[modₕ]n≡a 0 (acc + n) acc nmodₕ-idem acc (suc a) zero rewrite +-identityʳ acc = modₕ-idem 0 a accmodₕ-idem acc (suc a) (suc n) rewrite +-suc acc n = modₕ-idem (suc acc) a na+1[modₕ]n≡0⇒a[modₕ]n≡n-1 : ∀ acc l n → modₕ acc (acc + l) (suc n) l ≡ 0 → modₕ acc (acc + l) n l ≡ acc + la+1[modₕ]n≡0⇒a[modₕ]n≡n-1 acc zero zero eq rewrite +-identityʳ acc = refla+1[modₕ]n≡0⇒a[modₕ]n≡n-1 acc zero (suc n) eq rewrite +-identityʳ acc = a+1[modₕ]n≡0⇒a[modₕ]n≡n-1 0 acc n eqa+1[modₕ]n≡0⇒a[modₕ]n≡n-1 acc (suc l) (suc n) eq rewrite +-suc acc l = a+1[modₕ]n≡0⇒a[modₕ]n≡n-1 (suc acc) l n eqk<1+a[modₕ]n⇒k≤a[modₕ]n : ∀ acc k n l → suc k ≤ modₕ acc (acc + l) (suc n) l → k ≤ modₕ acc (acc + l) n lk<1+a[modₕ]n⇒k≤a[modₕ]n acc k zero (suc l) (s≤s leq) = leqk<1+a[modₕ]n⇒k≤a[modₕ]n acc k (suc n) zero leq rewrite +-identityʳ acc = k<1+a[modₕ]n⇒k≤a[modₕ]n 0 k n acc leqk<1+a[modₕ]n⇒k≤a[modₕ]n acc k (suc n) (suc l) leq rewrite +-suc acc l = k<1+a[modₕ]n⇒k≤a[modₕ]n (suc acc) k n l leq1+a[modₕ]n≤1+k⇒a[modₕ]n≤k : ∀ acc k n l → 0 < modₕ acc (acc + l) (suc n) l →modₕ acc (acc + l) (suc n) l ≤ suc k → modₕ acc (acc + l) n l ≤ k1+a[modₕ]n≤1+k⇒a[modₕ]n≤k acc k zero (suc l) 0<mod (s≤s leq) = leq1+a[modₕ]n≤1+k⇒a[modₕ]n≤k acc k (suc n) zero 0<mod leq rewrite +-identityʳ acc = 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k 0 k n acc 0<mod leq1+a[modₕ]n≤1+k⇒a[modₕ]n≤k acc k (suc n) (suc l) 0<mod leq rewrite +-suc acc l = 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k (suc acc) k n l 0<mod leqa+n[modₕ]n≡a[modₕ]n : ∀ acc a n → modₕ acc (acc + n) (acc + a + suc n) n ≡ modₕ acc (acc + n) a na+n[modₕ]n≡a[modₕ]n acc zero n rewrite +-identityʳ acc = begin-equalitymodₕ acc (acc + n) (acc + suc n) n ≡⟨ mod-cong₃ (+-suc acc n) ⟩modₕ acc (acc + n) (suc acc + n) n ≡⟨ modₕ-skipTo0 acc (acc + n) n (suc acc) ⟩modₕ (acc + n) (acc + n) (suc acc) 0 ≡⟨⟩modₕ 0 (acc + n) acc (acc + n) ≡⟨ a≤n⇒a[modₕ]n≡a 0 (acc + n) acc n ⟩acc ∎a+n[modₕ]n≡a[modₕ]n acc (suc a) zero rewrite +-identityʳ acc = begin-equalitymodₕ acc acc (acc + suc a + 1) 0 ≡⟨ mod-cong₃ (+-comm (acc + suc a) 1) ⟩modₕ acc acc (1 + (acc + suc a)) 0 ≡⟨⟩modₕ 0 acc (acc + suc a) acc ≡⟨ mod-cong₃ (+-comm acc (suc a)) ⟩modₕ 0 acc (suc a + acc) acc ≡⟨ mod-cong₃ (sym (+-suc a acc)) ⟩modₕ 0 acc (a + suc acc) acc ≡⟨ a+n[modₕ]n≡a[modₕ]n 0 a acc ⟩modₕ 0 acc a acc ∎a+n[modₕ]n≡a[modₕ]n acc (suc a) (suc n) rewrite +-suc acc n = begin-equalitymod₁ (acc + suc a + (2 + n)) (suc n) ≡⟨ cong (λ v → mod₁ (v + suc (suc n)) (suc n)) (+-suc acc a) ⟩mod₁ (suc acc + a + (2 + n)) (suc n) ≡⟨⟩mod₂ (acc + a + (2 + n)) n ≡⟨ mod-cong₃ (sym (+-assoc (acc + a) 1 (suc n))) ⟩mod₂ (acc + a + 1 + suc n) n ≡⟨ mod-cong₃ (cong (_+ suc n) (+-comm (acc + a) 1)) ⟩mod₂ (suc acc + a + suc n) n ≡⟨ a+n[modₕ]n≡a[modₕ]n (suc acc) a n ⟩mod₂ a n ∎wheremod₁ = modₕ acc (suc acc + n)mod₂ = modₕ (suc acc) (suc acc + n)-------------------------------------------------------------------------- Helper lemmas that have no interpretation for `_/_`, only for `divₕ`privatediv-cong₃ : ∀ {c n a₁ a₂ b} → a₁ ≡ a₂ → divₕ c n a₁ b ≡ divₕ c n a₂ bdiv-cong₃ refl = reflacc≤divₕ[acc] : ∀ {acc} d n j → acc ≤ divₕ acc d n jacc≤divₕ[acc] {acc} d zero j = ≤-reflacc≤divₕ[acc] {acc} d (suc n) zero = ≤-trans (n≤1+n acc) (acc≤divₕ[acc] d n d)acc≤divₕ[acc] {acc} d (suc n) (suc j) = acc≤divₕ[acc] d n jpattern inj₂′ x = inj₂ (inj₁ x)pattern inj₃ x = inj₂ (inj₂ x)-- This hideous lemma details the conditions needed for two divisions to-- be equal when the two offsets (i.e. the 4ᵗʰ parameters) are different.-- It may be that this triple sum has an elegant simplification to a-- set of inequalities involving the modulus but I can't find it.divₕ-offsetEq : ∀ {acc₁ acc₂} d n j k → j ≤ d → k ≤ d →(acc₁ ≡ acc₂ × j ≤ k × k < modₕ 0 d n d) ⊎(acc₁ ≡ acc₂ × modₕ 0 d n d ≤ j × j ≤ k) ⊎(acc₁ ≡ suc acc₂ × k < modₕ 0 d n d × modₕ 0 d n d ≤ j) →divₕ acc₁ d n j ≡ divₕ acc₂ d n kdivₕ-offsetEq d zero j k j≤d k≤d (inj₁ (refl , _)) = refldivₕ-offsetEq d zero j k j≤d k≤d (inj₂′ (refl , _)) = refldivₕ-offsetEq d zero j k j≤d k≤d (inj₃ (eq , () , _))-- (0 , 0) casesdivₕ-offsetEq d (suc n) zero zero j≤d k≤d (inj₁ (refl , _)) =divₕ-offsetEq d n d d ≤-refl ≤-refl (inj₂′ (refl , a[modₕ]n<n 0 n d , ≤-refl))divₕ-offsetEq d (suc n) zero zero j≤d k≤d (inj₂′ (refl , _)) =divₕ-offsetEq d n d d ≤-refl ≤-refl (inj₂′ (refl , a[modₕ]n<n 0 n d , ≤-refl))divₕ-offsetEq d (suc n) zero zero j≤d k≤d (inj₃ (_ , 0<mod , mod≤0)) =contradiction (<-≤-trans 0<mod mod≤0) λ()-- (0 , suc) casesdivₕ-offsetEq d (suc n) zero (suc k) j≤d k≤d (inj₁ (refl , _ , 1+k<mod)) =divₕ-offsetEq d n d k ≤-refl (<⇒≤ k≤d) (inj₃ (refl , k<1+a[modₕ]n⇒k≤a[modₕ]n 0 (suc k) n d 1+k<mod , a[modₕ]n<n 0 n d))divₕ-offsetEq d (suc n) zero (suc k) j≤d k≤d (inj₂′ (refl , mod≤0 , _)) =divₕ-offsetEq d n d k ≤-refl (<⇒≤ k≤d) (inj₃ (refl , subst (k <_) (sym (a+1[modₕ]n≡0⇒a[modₕ]n≡n-1 0 d n (n≤0⇒n≡0 mod≤0))) k≤d , a[modₕ]n<n 0 n d))divₕ-offsetEq d (suc n) zero (suc k) j≤d k≤d (inj₃ (_ , 1+k<mod , mod≤0)) =contradiction (<-≤-trans 1+k<mod mod≤0) λ()-- (suc , 0) casesdivₕ-offsetEq d (suc n) (suc j) zero j≤d k≤d (inj₁ (_ , () , _))divₕ-offsetEq d (suc n) (suc j) zero j≤d k≤d (inj₂′ (_ , _ , ()))divₕ-offsetEq d (suc n) (suc j) zero j≤d k≤d (inj₃ (eq , 0<mod , mod≤1+j)) =divₕ-offsetEq d n j d (<⇒≤ j≤d) ≤-refl (inj₂′ (eq , 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k 0 j n d 0<mod mod≤1+j , <⇒≤ j≤d))-- (suc , suc) casesdivₕ-offsetEq d (suc n) (suc j) (suc k) j≤d k≤d (inj₁ (eq , s≤s j≤k , 1+k<mod)) =divₕ-offsetEq d n j k (<⇒≤ j≤d) (<⇒≤ k≤d) (inj₁ (eq , j≤k , k<1+a[modₕ]n⇒k≤a[modₕ]n 0 (suc k) n d 1+k<mod))divₕ-offsetEq d (suc n) (suc j) (suc k) j≤d k≤d (inj₂′ (eq , mod≤1+j , (s≤s j≤k))) with modₕ 0 d (suc n) d ≟ 0... | yes mod≡0 = divₕ-offsetEq d n j k (<⇒≤ j≤d) (<⇒≤ k≤d) (inj₁ (eq , j≤k , subst (k <_) (sym (a+1[modₕ]n≡0⇒a[modₕ]n≡n-1 0 d n mod≡0)) k≤d))... | no mod≢0 = divₕ-offsetEq d n j k (<⇒≤ j≤d) (<⇒≤ k≤d) (inj₂′ (eq , 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k 0 j n d (n≢0⇒n>0 mod≢0) mod≤1+j , j≤k))divₕ-offsetEq d (suc n) (suc j) (suc k) j≤d k≤d (inj₃ (eq , k<mod , mod≤1+j)) =divₕ-offsetEq d n j k (<⇒≤ j≤d) (<⇒≤ k≤d) (inj₃ (eq , k<1+a[modₕ]n⇒k≤a[modₕ]n 0 (suc k) n d k<mod , 1+a[modₕ]n≤1+k⇒a[modₕ]n≤k 0 j n d (≤-<-trans z≤n k<mod) mod≤1+j))-------------------------------------------------------------------------- Lemmas for divₕ that also have an interpretation for _/_-- The quotient and remainder are related to the dividend and-- divisor in the right way.div-mod-lemma : ∀ accᵐ accᵈ d n →accᵐ + accᵈ * suc (accᵐ + n) + d ≡modₕ accᵐ (accᵐ + n) d n + divₕ accᵈ (accᵐ + n) d n * suc (accᵐ + n)div-mod-lemma accᵐ accᵈ zero n = +-identityʳ _div-mod-lemma accᵐ accᵈ (suc d) zero rewrite +-identityʳ accᵐ = begin-equalityaccᵐ + accᵈ * suc accᵐ + suc d ≡⟨ +-suc _ d ⟩suc accᵈ * suc accᵐ + d ≡⟨ div-mod-lemma zero (suc accᵈ) d accᵐ ⟩modₕ 0 accᵐ d accᵐ +divₕ (suc accᵈ) accᵐ d accᵐ * suc accᵐ ≡⟨⟩modₕ accᵐ accᵐ (suc d) 0 +divₕ accᵈ accᵐ (suc d) 0 * suc accᵐ ∎div-mod-lemma accᵐ accᵈ (suc d) (suc n) rewrite +-suc accᵐ n = begin-equalityaccᵐ + accᵈ * m + suc d ≡⟨ +-suc _ d ⟩suc (accᵐ + accᵈ * m + d) ≡⟨ div-mod-lemma (suc accᵐ) accᵈ d n ⟩modₕ _ _ d n + divₕ accᵈ _ d n * m ∎wherem = 2 + accᵐ + ndivₕ-restart : ∀ {acc} d n j → j < n → divₕ acc d n j ≡ divₕ (suc acc) d (n ∸ suc j) ddivₕ-restart d (suc n) zero j<n = refldivₕ-restart d (suc n) (suc j) (s≤s j<n) = divₕ-restart d n j j<ndivₕ-extractAcc : ∀ acc d n j → divₕ acc d n j ≡ acc + divₕ 0 d n jdivₕ-extractAcc acc d zero j = sym (+-identityʳ acc)divₕ-extractAcc acc d (suc n) (suc j) = divₕ-extractAcc acc d n jdivₕ-extractAcc acc d (suc n) zero = begin-equalitydivₕ (suc acc) d n d ≡⟨ divₕ-extractAcc (suc acc) d n d ⟩suc acc + divₕ 0 d n d ≡⟨ sym (+-suc acc _) ⟩acc + suc (divₕ 0 d n d) ≡⟨ cong (acc +_) (sym (divₕ-extractAcc 1 d n d)) ⟩acc + divₕ 1 d n d ∎divₕ-finish : ∀ {acc} d n j → j ≥ n → divₕ acc d n j ≡ accdivₕ-finish d zero j j≥n = refldivₕ-finish d (suc n) (suc j) (s≤s j≥n) = divₕ-finish d n j j≥nn[divₕ]n≡1 : ∀ n m → divₕ 0 n (suc m) m ≡ 1n[divₕ]n≡1 n zero = refln[divₕ]n≡1 n (suc m) = n[divₕ]n≡1 n ma[divₕ]1≡a : ∀ acc a → divₕ acc 0 a 0 ≡ acc + aa[divₕ]1≡a acc zero = sym (+-identityʳ acc)a[divₕ]1≡a acc (suc a) = trans (a[divₕ]1≡a (suc acc) a) (sym (+-suc acc a))a*n[divₕ]n≡a : ∀ acc a n → divₕ acc n (a * suc n) n ≡ acc + aa*n[divₕ]n≡a acc zero n = sym (+-identityʳ acc)a*n[divₕ]n≡a acc (suc a) n = begin-equalitydivₕ acc n (suc a * suc n) n ≡⟨ divₕ-restart n (suc a * suc n) n (m≤m+n (suc n) _) ⟩divₕ (suc acc) n (suc a * suc n ∸ suc n) n ≡⟨⟩divₕ (suc acc) n (suc n + a * suc n ∸ suc n) n ≡⟨ div-cong₃ (m+n∸m≡n (suc n) (a * suc n)) ⟩divₕ (suc acc) n (a * suc n) n ≡⟨ a*n[divₕ]n≡a (suc acc) a n ⟩suc acc + a ≡⟨ sym (+-suc acc a) ⟩acc + suc a ∎+-distrib-divₕ : ∀ acc k m n j → modₕ k (k + j) m j + modₕ 0 (k + j) n (k + j) < suc (k + j) →divₕ acc (k + j) (m + n) j ≡ divₕ acc (k + j) m j + divₕ 0 (k + j) n (k + j)+-distrib-divₕ acc k (suc m) n zero leq rewrite +-identityʳ k = +-distrib-divₕ (suc acc) 0 m n k leq+-distrib-divₕ acc k (suc m) n (suc j) leq rewrite +-suc k j = +-distrib-divₕ acc (suc k) m n j leq+-distrib-divₕ acc k zero n j leq = begin-equalitydivₕ acc (k + j) n j ≡⟨ divₕ-extractAcc acc (k + j) n j ⟩acc + divₕ 0 (k + j) n j ≡⟨ cong (acc +_) (divₕ-offsetEq _ n j _ (m≤n+m j k) ≤-refl case) ⟩acc + divₕ 0 (k + j) n (k + j) ∎wherecase = inj₂′ (refl , +-cancelˡ-≤ (suc k) _ _ leq , m≤n+m j k)divₕ-mono-≤ : ∀ {acc} k {m n o p} → m ≤ n → p ≤ o → divₕ acc (k + o) m o ≤ divₕ acc (k + p) n pdivₕ-mono-≤ {acc} k {0} {n} {_} {p} z≤n p≤o = acc≤divₕ[acc] (k + p) n pdivₕ-mono-≤ {acc} k {_} {_} {suc o} {suc p} (s≤s m≤n) (s≤s p≤o)rewrite +-suc k o | +-suc k p = divₕ-mono-≤ (suc k) m≤n p≤odivₕ-mono-≤ {acc} k {suc m} {suc n} {o} {0} (s≤s m≤n) z≤n with o <? suc m... | no o≮1+m rewrite +-identityʳ k = begindivₕ acc (k + o) (suc m) o ≡⟨ divₕ-finish (k + o) (suc m) o (≮⇒≥ o≮1+m) ⟩acc ≤⟨ n≤1+n acc ⟩suc acc ≤⟨ acc≤divₕ[acc] k n k ⟩divₕ (suc acc) k n k ∎... | yes o<1+m rewrite +-identityʳ k = begindivₕ acc (k + o) (suc m) o ≡⟨ divₕ-restart (k + o) (suc m) o o<1+m ⟩divₕ (suc acc) (k + o) (m ∸ o) (k + o) ≤⟨ divₕ-mono-≤ 0 (≤-trans (m∸n≤m m o) m≤n) (m≤m+n k o) ⟩divₕ (suc acc) k n k ∎
-------------------------------------------------------------------------- The Agda standard library---- Coprimality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Coprimality whereopen import Data.Nat.Baseopen import Data.Nat.Divisibilityopen import Data.Nat.GCDopen import Data.Nat.GCD.Lemmasopen import Data.Nat.Primalityopen import Data.Nat.Propertiesopen import Data.Nat.DivModopen import Data.Product.Base as Prodopen import Data.Sum.Base as Sum using (inj₁; inj₂)open import Function.Base using (_∘_)open import Level using (0ℓ)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; refl; trans; cong; subst)open import Relation.Nullary as Nullary using (¬_; contradiction; map′)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Symmetric; Decidable)privatevariable d m n o p : ℕopen ≤-Reasoning-------------------------------------------------------------------------- Definition---- Coprime m n is inhabited iff m and n are coprime (relatively-- prime), i.e. if their only common divisor is 1.Coprime : Rel ℕ 0ℓCoprime m n = ∀ {d} → d ∣ m × d ∣ n → d ≡ 1-------------------------------------------------------------------------- Relationship between GCD and coprimalitycoprime⇒GCD≡1 : Coprime m n → GCD m n 1coprime⇒GCD≡1 {m} {n} coprime = GCD.is (1∣ m , 1∣ n) (∣-reflexive ∘ coprime)GCD≡1⇒coprime : GCD m n 1 → Coprime m nGCD≡1⇒coprime g cd with divides q eq ← GCD.greatest g cd= m*n≡1⇒n≡1 q _ (≡.sym eq)coprime⇒gcd≡1 : Coprime m n → gcd m n ≡ 1coprime⇒gcd≡1 coprime = GCD.unique (gcd-GCD _ _) (coprime⇒GCD≡1 coprime)gcd≡1⇒coprime : gcd m n ≡ 1 → Coprime m ngcd≡1⇒coprime gcd≡1 = GCD≡1⇒coprime (subst (GCD _ _) gcd≡1 (gcd-GCD _ _))coprime-/gcd : ∀ m n .{{_ : NonZero (gcd m n)}} →Coprime (m / gcd m n) (n / gcd m n)coprime-/gcd m n = GCD≡1⇒coprime (GCD-/gcd m n)-------------------------------------------------------------------------- Relational properties of Coprimesym : Symmetric Coprimesym c = c ∘ swapcoprime? : Decidable Coprimecoprime? m n = map′ gcd≡1⇒coprime coprime⇒gcd≡1 (gcd m n ≟ 1)-------------------------------------------------------------------------- Other basic properties-- Everything is coprime to 1.1-coprimeTo : ∀ m → Coprime 1 m1-coprimeTo m = ∣1⇒≡1 ∘ proj₁-- Nothing except for 1 is coprime to 0.0-coprimeTo-m⇒m≡1 : Coprime 0 m → m ≡ 10-coprimeTo-m⇒m≡1 {m} coprime = coprime (m ∣0 , ∣-refl)¬0-coprimeTo-2+ : .{{NonTrivial n}} → ¬ Coprime 0 n¬0-coprimeTo-2+ {n} coprime = contradiction (0-coprimeTo-m⇒m≡1 coprime) (nonTrivial⇒≢1 {n})-- If m and n are coprime, then n + m and n are also coprime.coprime-+ : Coprime m n → Coprime (n + m) ncoprime-+ coprime (d₁ , d₂) = coprime (∣m+n∣m⇒∣n d₁ d₂ , d₂)-- Recomputablerecompute : .(Coprime n d) → Coprime n drecompute {n} {d} coprime = Nullary.recompute (coprime? n d) coprime-------------------------------------------------------------------------- Relationship with Bezout's lemma-- If the "gcd" in Bézout's identity is non-zero, then the "other"-- divisors are coprime.Bézout-coprime : .{{NonZero d}} →Bézout.Identity d (m * d) (n * d) → Coprime m nBézout-coprime {d = suc _} (Bézout.+- x y eq) (divides-refl q₁ , divides-refl q₂) =lem₁₀ y q₂ x q₁ eqBézout-coprime {d = suc _} (Bézout.-+ x y eq) (divides-refl q₁ , divides-refl q₂) =lem₁₀ x q₁ y q₂ eq-- Coprime numbers satisfy Bézout's identity.coprime-Bézout : Coprime m n → Bézout.Identity 1 m ncoprime-Bézout = Bézout.identity ∘ coprime⇒GCD≡1-- If m divides n*o and is coprime to n, then it divides o.coprime-divisor : Coprime m n → m ∣ n * o → m ∣ ocoprime-divisor {o = o} c (divides q eq′) with coprime-Bézout c... | Bézout.+- x y eq = divides (x * o ∸ y * q) (lem₈ x y eq eq′)... | Bézout.-+ x y eq = divides (y * q ∸ x * o) (lem₉ x y eq eq′)-- If d is a common divisor of m*o and n*o, and m and n are coprime,-- then d divides o.coprime-factors : Coprime m n → d ∣ m * o × d ∣ n * o → d ∣ ocoprime-factors c (divides q₁ eq₁ , divides q₂ eq₂) with coprime-Bézout c... | Bézout.+- x y eq = divides (x * q₁ ∸ y * q₂) (lem₁₁ x y eq eq₁ eq₂)... | Bézout.-+ x y eq = divides (y * q₂ ∸ x * q₁) (lem₁₁ y x eq eq₂ eq₁)-------------------------------------------------------------------------- Primality implies coprimality.prime⇒coprime : Prime p → .{{NonZero n}} → n < p → Coprime p nprime⇒coprime p n<p (d∣p , d∣n) with prime⇒irreducible p d∣p... | inj₁ d≡1 = d≡1... | inj₂ d≡p@refl = contradiction n<p (≤⇒≯ (∣⇒≤ d∣n))
-------------------------------------------------------------------------- The Agda standard library---- Combinatorial operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Combinatorics whereopen import Data.Nat.Base using (ℕ; zero; suc; _!; _∸_; z≤n; s≤s; _≤_;_+_; _*_; _<_; s<s; ≢-nonZero)open import Data.Nat.DivMod using (_/_; n/1≡n; /-congˡ; /-congʳ; m*n/n≡m;m/n/o≡m/[n*o]; n/n≡1; +-distrib-/-∣ˡ; m*n/m*o≡n/o)open import Data.Nat.Divisibility using (_∣_; *-monoʳ-∣)open import Data.Nat.Propertiesopen import Relation.Binary.Definitions using (tri>; tri≈; tri<)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; cong; subst)import Data.Nat.Combinatorics.Base as Baseimport Data.Nat.Combinatorics.Specification as Specificationimport Algebra.Properties.CommutativeSemigroup as CommSemigroupPropertiesopen ≤-Reasoningprivatevariablen k : ℕ-------------------------------------------------------------------------- Definitionsopen Base publicusing (_P_; _C_)-------------------------------------------------------------------------- Properties of _P_open Specification publicusing (nPk≡n!/[n∸k]!; k>n⇒nPk≡0; [n∸k]!k!∣n!)nPn≡n! : ∀ n → n P n ≡ n !nPn≡n! n = begin-equalityn P n ≡⟨ nPk≡n!/[n∸k]! (≤-refl {n}) ⟩n ! / (n ∸ n) ! ≡⟨ /-congʳ (cong _! (n∸n≡0 n)) ⟩n ! / 0 ! ≡⟨⟩n ! / 1 ≡⟨ n/1≡n (n !) ⟩n ! ∎where instance_ = (n ∸ n) !≢0nP1≡n : ∀ n → n P 1 ≡ nnP1≡n zero = reflnP1≡n n@(suc n-1) = begin-equalityn P 1 ≡⟨ nPk≡n!/[n∸k]! (s≤s (z≤n {n-1})) ⟩n ! / n-1 ! ≡⟨ m*n/n≡m n (n-1 !) ⟩n ∎where instance_ = n-1 !≢0-------------------------------------------------------------------------- Properties of _C_open Specification publicusing (nCk≡n!/k![n-k]!; k>n⇒nCk≡0)nCk≡nC[n∸k] : k ≤ n → n C k ≡ n C (n ∸ k)nCk≡nC[n∸k] {k} {n} k≤n = begin-equalityn C k ≡⟨ nCk≡n!/k![n-k]! k≤n ⟩n ! / (k ! * (n ∸ k) !) ≡⟨ /-congʳ (*-comm ((n ∸ k) !) (k !)) ⟨n ! / ((n ∸ k) ! * k !) ≡⟨ /-congʳ (cong ((n ∸ k) ! *_) (cong _! (m∸[m∸n]≡n k≤n))) ⟨n ! / ((n ∸ k) ! * (n ∸ (n ∸ k)) !) ≡⟨ nCk≡n!/k![n-k]! (m≤n⇒n∸m≤n k≤n) ⟨n C (n ∸ k) ∎where instance_ = (n ∸ k) !* k !≢0_ = k !* (n ∸ k) !≢0_ = (n ∸ k) !* (n ∸ (n ∸ k)) !≢0nCk≡nPk/k! : k ≤ n → n C k ≡ ((n P k) / k !) {{k !≢0}}nCk≡nPk/k! {k} {n} k≤n = begin-equalityn C k ≡⟨ nCk≡n!/k![n-k]! k≤n ⟩n ! / (k ! * (n ∸ k) !) ≡⟨ /-congʳ (*-comm ((n ∸ k)!) (k !)) ⟨n ! / ((n ∸ k) ! * k !) ≡⟨ m/n/o≡m/[n*o] (n !) ((n ∸ k) !) (k !) ⟨(n ! / (n ∸ k) !) / k ! ≡⟨ /-congˡ (nPk≡n!/[n∸k]! k≤n) ⟨(n P k) / k ! ∎where instance_ = k !≢0_ = (n ∸ k) !≢0_ = (n ∸ k) !* k !≢0_ = k !* (n ∸ k) !≢0nCn≡1 : ∀ n → n C n ≡ 1nCn≡1 n = begin-equalityn C n ≡⟨ nCk≡nPk/k! (≤-refl {n}) ⟩(n P n) / n ! ≡⟨ /-congˡ (nPn≡n! n) ⟩n ! / n ! ≡⟨ n/n≡1 (n !) ⟩1 ∎where instance_ = n !≢0nC1≡n : ∀ n → n C 1 ≡ nnC1≡n zero = reflnC1≡n n@(suc n-1) = begin-equalityn C 1 ≡⟨ nCk≡nPk/k! (s≤s (z≤n {n-1})) ⟩(n P 1) / 1 ! ≡⟨ n/1≡n (n P 1) ⟩n P 1 ≡⟨ nP1≡n n ⟩n ∎-------------------------------------------------------------------------- Arithmetic of (n C k)module _ {n k} (k<n : k < n) whereprivate[n-k] = n ∸ k[n-k-1] = n ∸ suc k[n-k]! = [n-k] ![n-k-1]! = [n-k-1] ![n-k]≡1+[n-k-1] : [n-k] ≡ suc [n-k-1][n-k]≡1+[n-k-1] = +-∸-assoc 1 k<n[n-k]*[n-k-1]!≡[n-k]! : [n-k] * [n-k-1]! ≡ [n-k]![n-k]*[n-k-1]!≡[n-k]! = begin-equality[n-k] * [n-k-1]!≡⟨ cong (_* [n-k-1]!) [n-k]≡1+[n-k-1] ⟩(suc [n-k-1]) * [n-k-1]!≡⟨ cong _! [n-k]≡1+[n-k-1] ⟨[n-k]! ∎privaten! = n !k! = k ![k+1]! = (suc k) !d[k] = k! * [n-k]![k+1]*d[k] = (suc k) * d[k]d[k+1] = [k+1]! * [n-k-1]![n-k]*d[k+1] = [n-k] * d[k+1][n-k]*d[k+1]≡[k+1]*d[k] : [n-k]*d[k+1] ≡ [k+1]*d[k][n-k]*d[k+1]≡[k+1]*d[k] = begin-equality[n-k]*d[k+1]≡⟨ x∙yz≈y∙xz [n-k] [k+1]! [n-k-1]! ⟩[k+1]! * ([n-k] * [n-k-1]!)≡⟨ *-assoc (suc k) k! ([n-k] * [n-k-1]!) ⟩(suc k) * (k! * ([n-k] * [n-k-1]!))≡⟨ cong ((suc k) *_) (cong (k! *_) [n-k]*[n-k-1]!≡[n-k]!) ⟩[k+1]*d[k] ∎where open CommSemigroupProperties *-commutativeSemigroupk![n∸k]!∣n! : ∀ {n k} → k ≤ n → k ! * (n ∸ k) ! ∣ n !k![n∸k]!∣n! {n} {k} k≤n = subst (_∣ n !) (*-comm ((n ∸ k) !) (k !)) ([n∸k]!k!∣n! k≤n)nCk+nC[k+1]≡[n+1]C[k+1] : ∀ n k → n C k + n C (suc k) ≡ suc n C suc knCk+nC[k+1]≡[n+1]C[k+1] n k with <-cmp k n{- case k>n, in which case 1+k>1+n>n -}... | tri> _ _ k>n = begin-equalityn C k + n C (suc k) ≡⟨ cong (_+ (n C (suc k))) (k>n⇒nCk≡0 k>n) ⟩0 + n C (suc k) ≡⟨⟩n C (suc k) ≡⟨ k>n⇒nCk≡0 (m<n⇒m<1+n k>n) ⟩0 ≡⟨ k>n⇒nCk≡0 (s<s k>n) ⟨suc n C suc k ∎{- case k≡n, in which case 1+k≡1+n>n -}... | tri≈ _ k≡n _ rewrite k≡n = begin-equalityn C n + n C (suc n) ≡⟨ cong (n C n +_) (k>n⇒nCk≡0 (n<1+n n)) ⟩n C n + 0 ≡⟨ +-identityʳ (n C n) ⟩n C n ≡⟨ nCn≡1 n ⟩1 ≡⟨ nCn≡1 (suc n) ⟨suc n C suc n ∎{- case k<n, in which case 1+k<1+n and there's arithmetic to perform -}... | tri< k<n _ _ = begin-equalityn C k + n C (suc k)≡⟨ cong (n C k +_) (nCk≡n!/k![n-k]! k<n) ⟩n C k + (n! / d[k+1])≡⟨ cong (n C k +_) (m*n/m*o≡n/o (n ∸ k) n! d[k+1]) ⟨n C k + [n-k]*n!/[n-k]*d[k+1]≡⟨ cong (_+ [n-k]*n!/[n-k]*d[k+1]) (nCk≡n!/k![n-k]! k≤n) ⟩n! / d[k] + _≡⟨ cong (_+ [n-k]*n!/[n-k]*d[k+1]) (m*n/m*o≡n/o (suc k) n! d[k]) ⟨(suc k * n!) / [k+1]*d[k] + _≡⟨ cong (((suc k * n!) / [k+1]*d[k]) +_) (/-congʳ ([n-k]*d[k+1]≡[k+1]*d[k] k<n)) ⟩(suc k * n!) / [k+1]*d[k] + ((n ∸ k) * n! / [k+1]*d[k])≡⟨ +-distrib-/-∣ˡ _ (*-monoʳ-∣ (suc k) (k![n∸k]!∣n! k≤n)) ⟨((suc k) * n! + (n ∸ k) * n!) / [k+1]*d[k]≡⟨ cong (_/ [k+1]*d[k]) (*-distribʳ-+ (n !) (suc k) (n ∸ k)) ⟨((suc k + (n ∸ k)) * n !) / [k+1]*d[k]≡⟨ cong (λ z → z * n ! / [k+1]*d[k]) [k+1]+[n-k]≡[n+1] ⟩((suc n) * n !) / [k+1]*d[k]≡⟨ /-congʳ (*-assoc (suc k) (k !) ((n ∸ k) !)) ⟨((suc n) * n !) / (((suc k) * k !) * (n ∸ k) !)≡⟨⟩suc n ! / (suc k ! * (suc n ∸ suc k) !)≡⟨ nCk≡n!/k![n-k]! [k+1]≤[n+1] ⟨suc n C suc k ∎wherek≤n : k ≤ nk≤n = <⇒≤ k<n[k+1]≤[n+1] : suc k ≤ suc n[k+1]≤[n+1] = s≤s k≤n[k+1]+[n-k]≡[n+1] : (suc k) + (n ∸ k) ≡ suc n[k+1]+[n-k]≡[n+1] = m+[n∸m]≡n {suc k} [k+1]≤[n+1][n-k] = n ∸ k[n-k-1] = n ∸ suc kn! = n !k! = k ![k+1]! = (suc k) ![n-k]! = [n-k] ![n-k-1]! = [n-k-1] !d[k] = k! * [n-k]![k+1]*d[k] = (suc k) * d[k]d[k+1] = [k+1]! * [n-k-1]![n-k]*d[k+1] = [n-k] * d[k+1]n!/[n-k]*d[k+1] = n ! / [n-k]*d[k+1][n-k]*n!/[n-k]*d[k+1] = [n-k] * n! / [n-k]*d[k+1][n-k]*n!/[k+1]*d[k] = [n-k] * n! / [k+1]*d[k]instance[k+1]!*[n-k]!≢0 = (suc k) !* [n-k] !≢0d[k]≢0 = k !* [n-k] !≢0d[k+1]≢0 = (suc k) !* (n ∸ suc k) !≢0[k+1]*d[k]≢0 = m*n≢0 (suc k) d[k][n-k]≢0 = ≢-nonZero (m>n⇒m∸n≢0 k<n)[n-k]*d[k+1]≢0 = m*n≢0 [n-k] d[k+1]
-------------------------------------------------------------------------- The Agda standard library---- The specification for combinatorics operations-------------------------------------------------------------------------- This module should not be imported directly! Please use-- `Data.Nat.Combinatorics` instead.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Combinatorics.Specification whereopen import Data.Bool.Base using (T; true; false)open import Data.Nat.Base using (zero; suc; _≤ᵇ_; _≤_; _!; _∸_; pred;>-nonZero; _*_; NonZero; _+_; s≤s; z≤n; _>_)open import Data.Nat.DivMod using (_/_; n/n≡1; /-congʳ; m*n/m!≡n/[m∸1]!;*-/-assoc; n/1≡n; m/n/o≡m/[n*o]; /-congˡ)open import Data.Nat.Divisibility using (m≤n⇒m!∣n!; _∣_; ∣-refl;∣-reflexive; module ∣-Reasoning; ∣m∣n⇒∣m+n; *-monoʳ-∣; m∣n/o⇒o*m∣n)open import Data.Nat.Propertiesopen import Data.Nat.Combinatorics.Baseopen import Data.Sum.Base using (inj₁; inj₂)open import Relation.Nullary.Decidable using (yes; no; does)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; trans; _≢_; subst; refl; sym; cong; cong₂)import Algebra.Properties.CommutativeSemigroup *-commutativeSemigroup as *-CS-------------------------------------------------------------------------- Preludeprivate≤ᵇ⇒≤′ : ∀ {m n} → (m ≤ᵇ n) ≡ true → m ≤ n≤ᵇ⇒≤′ {m} {n} eq = ≤ᵇ⇒≤ m n (subst T (sym eq) _)-------------------------------------------------------------------------- Properties of _P′_nP′k≡n!/[n∸k]! : ∀ {n k} → k ≤ n → n P′ k ≡ (n ! / (n ∸ k) !) {{(n ∸ k) !≢0}}nP′k≡n!/[n∸k]! {n} {zero} z≤n = sym (n/n≡1 (n !) {{n !≢0}})nP′k≡n!/[n∸k]! {n} {suc k} k<n = begin-equality(n ∸ k) * (n P′ k) ≡⟨ cong ((n ∸ k) *_) (nP′k≡n!/[n∸k]! (<⇒≤ k<n)) ⟩(n ∸ k) * (n ! / (n ∸ k) !) ≡⟨ *-/-assoc (n ∸ k) (m≤n⇒m!∣n! (m∸n≤m n k)) ⟨(((n ∸ k) * n !) / (n ∸ k) !) ≡⟨ m*n/m!≡n/[m∸1]! (n ∸ k) (n !) ⟩(n ! / (pred (n ∸ k) !)) ≡⟨ /-congʳ (cong _! (pred[m∸n]≡m∸[1+n] n k)) ⟩(n ! / (n ∸ suc k) !) ∎whereopen ≤-Reasoninginstance_ = (n ∸ k) !≢0_ = (pred (n ∸ k)) !≢0_ = (n ∸ suc k) !≢0_ = >-nonZero (m<n⇒0<n∸m k<n)nP′k≡n[n∸1P′k∸1] : ∀ n k → .{{NonZero n}} → .{{NonZero k}} →n P′ k ≡ n * (pred n P′ pred k)nP′k≡n[n∸1P′k∸1] n (suc zero) = reflnP′k≡n[n∸1P′k∸1] n@(suc n-1) k@(suc k-1@(suc k-2)) = begin-equalityn P′ k ≡⟨⟩(n ∸ k-1) * (n P′ k-1) ≡⟨ cong ((n ∸ k-1) *_) (nP′k≡n[n∸1P′k∸1] n k-1) ⟩(n ∸ k-1) * (n * (n-1 P′ k-2)) ≡⟨ x∙yz≈y∙xz (n ∸ k-1) n (n-1 P′ k-2) ⟩n * ((n ∸ k-1) * (n-1 P′ k-2)) ≡⟨⟩n * (n-1 P′ k-1) ∎where open ≤-Reasoning; open *-CSP′-rec : ∀ {n k} → k ≤ n → .{{NonZero k}} →n P′ k ≡ k * (pred n P′ pred k) + pred n P′ kP′-rec n@{suc n-1} k@{suc k-1} k≤n = begin-equalityn P′ k ≡⟨ nP′k≡n[n∸1P′k∸1] n k ⟩n * (n-1 P′ k-1) ≡⟨ cong (_* (n-1 P′ k-1)) (m+[n∸m]≡n {k} {n} k≤n) ⟨(k + (n ∸ k)) * (n-1 P′ k-1) ≡⟨ *-distribʳ-+ (n-1 P′ k-1) k (n ∸ k) ⟩k * (n-1 P′ k-1) + (n-1 ∸ k-1) * (n-1 P′ k-1) ≡⟨⟩k * (n-1 P′ k-1) + (n-1 P′ k) ∎where open ≤-ReasoningnP′n≡n! : ∀ n → n P′ n ≡ n !nP′n≡n! n = begin-equalityn P′ n ≡⟨ nP′k≡n!/[n∸k]! (≤-refl {n}) ⟩n ! / (n ∸ n) ! ≡⟨ /-congʳ (cong _! (n∸n≡0 n)) ⟩n ! / 0 ! ≡⟨⟩n ! / 1 ≡⟨ n/1≡n (n !) ⟩n ! ∎where open ≤-Reasoning; instance _ = (n ∸ n) !≢0k!∣nP′k : ∀ {n k} → k ≤ n → k ! ∣ n P′ kk!∣nP′k {n} {zero} k≤n = ∣-reflk!∣nP′k n@{suc n-1} k@{suc k-1} k≤n@(s≤s k-1≤n-1) with k-1 ≟ n-1... | yes refl = ∣-reflexive (sym (nP′n≡n! n))... | no k≢n = begink ! ≡⟨⟩k * k-1 ! ∣⟨ ∣m∣n⇒∣m+n (*-monoʳ-∣ k (k!∣nP′k k-1≤n-1)) ( k!∣nP′k (≤∧≢⇒< k-1≤n-1 k≢n)) ⟩k * (n-1 P′ k-1) + (n-1 P′ k) ≡⟨ P′-rec k≤n ⟨n P′ k ∎where open ∣-Reasoning[n∸k]!k!∣n! : ∀ {n k} → k ≤ n → (n ∸ k) ! * k ! ∣ n ![n∸k]!k!∣n! {n} {k} k≤n = m∣n/o⇒o*m∣n (m≤n⇒m!∣n! (m∸n≤m n k))(subst (k ! ∣_) (nP′k≡n!/[n∸k]! k≤n) (k!∣nP′k k≤n))where instance _ = (n ∸ k) !≢0-------------------------------------------------------------------------- Properties of _P_nPk≡n!/[n∸k]! : ∀ {n k} → k ≤ n → n P k ≡ (n ! / (n ∸ k) !) {{(n ∸ k) !≢0}}nPk≡n!/[n∸k]! {n} {k} k≤n with k ≤ᵇ n in eq... | true = nP′k≡n!/[n∸k]! k≤n... | false = contradiction (≤⇒≤ᵇ k≤n) (subst T eq)k>n⇒nPk≡0 : ∀ {n k} → k > n → n P k ≡ 0k>n⇒nPk≡0 {n} {k} k>n with k ≤ᵇ n in eq... | true = contradiction (≤ᵇ⇒≤′ eq) (<⇒≱ k>n)... | false = refl-------------------------------------------------------------------------- Properties of _C′_nC′k≡n!/k![n-k]! : ∀ {n k} → k ≤ n → n C′ k ≡ (n ! / (k ! * (n ∸ k) !)) {{k !* (n ∸ k) !≢0}}nC′k≡n!/k![n-k]! {n} {k} k≤n = begin-equalityn C′ k ≡⟨⟩(n P′ k) / k ! ≡⟨ /-congˡ (nP′k≡n!/[n∸k]! k≤n) ⟩(n ! / (n ∸ k) !) / k ! ≡⟨ m/n/o≡m/[n*o] (n !) ((n ∸ k) !) (k !) ⟩n ! / ((n ∸ k) ! * k !) ≡⟨ /-congʳ (*-comm ((n ∸ k)!) (k !)) ⟩n ! / (k ! * (n ∸ k) !) ∎whereopen ≤-Reasoninginstance_ = k !≢0_ = (n ∸ k) !≢0_ = (n ∸ k) !* k !≢0_ = k !* (n ∸ k) !≢0C′-sym : ∀ {n k} → k ≤ n → n C′ (n ∸ k) ≡ n C′ kC′-sym {n} {k} k≤n = begin-equalityn C′ (n ∸ k) ≡⟨ nC′k≡n!/k![n-k]! {n} {n ∸ k} (m≤n⇒n∸m≤n k≤n) ⟩n ! / ((n ∸ k) ! * (n ∸ (n ∸ k)) !) ≡⟨ /-congʳ (cong ((n ∸ k) ! *_) (cong _! (m∸[m∸n]≡n k≤n))) ⟩n ! / ((n ∸ k) ! * k !) ≡⟨ /-congʳ (*-comm ((n ∸ k) !) (k !)) ⟩n ! / (k ! * (n ∸ k) !) ≡⟨ nC′k≡n!/k![n-k]! k≤n ⟨n C′ k ∎whereopen ≤-Reasoninginstance_ = (n ∸ k) !* k !≢0_ = k !* (n ∸ k) !≢0_ = (n ∸ k) !* (n ∸ (n ∸ k)) !≢0-------------------------------------------------------------------------- Properties of _C_nCk≡n!/k![n-k]! : ∀ {n k} → k ≤ n →n C k ≡ (n ! / (k ! * (n ∸ k) !)) {{k !* (n ∸ k) !≢0}}nCk≡n!/k![n-k]! {n} {k} k≤n with k ≤ᵇ n in eq2... | false = contradiction (≤⇒≤ᵇ k≤n) (subst T eq2)... | true with ⊓-sel k (n ∸ k)... | inj₁ k⊓[n∸k]≡k rewrite k⊓[n∸k]≡k = nC′k≡n!/k![n-k]! k≤n... | inj₂ k⊓[n∸k]≡n∸k rewrite k⊓[n∸k]≡n∸k = trans (C′-sym k≤n) (nC′k≡n!/k![n-k]! k≤n)k>n⇒nCk≡0 : ∀ {n k} → k > n → n C k ≡ 0k>n⇒nCk≡0 {n} {k} k>n with k ≤ᵇ n in eq... | true = contradiction (≤ᵇ⇒≤′ eq) (<⇒≱ k>n)... | false = refl
-------------------------------------------------------------------------- The Agda standard library---- Combinatorics operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Combinatorics.Base whereopen import Data.Bool.Base using (if_then_else_)open import Data.Nat.Baseopen import Data.Nat.Properties using (_!≢0)-- NOTE: These operators are not implemented as efficiently as they-- could be. See the following link for more details.---- https://math.stackexchange.com/questions/202554/how-do-i-compute-binomial-coefficients-efficiently-------------------------------------------------------------------------- Permutations / falling factorial-- The number of ways, including order, that k objects can be chosen-- from among n objects.-- n P k = n ! / (n ∸ k) !infixl 6.5 _P′_ _P_-- Base definition. Only valid for k ≤ n._P′_ : ℕ → ℕ → ℕn P′ zero = 1n P′ (suc k) = (n ∸ k) * (n P′ k)-- Main definition. Valid for all k as deals with boundary case._P_ : ℕ → ℕ → ℕn P k = if k ≤ᵇ n then n P′ k else 0-------------------------------------------------------------------------- Combinations / binomial coefficient-- The number of ways, disregarding order, that k objects can be chosen-- from among n objects.-- n C k = n ! / (k ! * (n ∸ k) !)infixl 6.5 _C′_ _C_-- Base definition. Only valid for k ≤ n._C′_ : ℕ → ℕ → ℕn C′ k = (n P′ k) / k !where instance _ = k !≢0-- Main definition. Valid for all k.-- Deals with boundary case and exploits symmetry to improve performance._C_ : ℕ → ℕ → ℕn C k = if k ≤ᵇ n then n C′ (k ⊓ (n ∸ k)) else 0
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers represented in binary natively in Agda.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary whereopen import Data.Nat.Binary.Base publicopen import Data.Nat.Binary.Properties public using (_≟_)
-------------------------------------------------------------------------- The Agda standard library---- Subtraction on Bin and some of its properties.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary.Subtraction whereopen import Algebra.Core using (Op₂)open import Algebra.Bundles using (Magma)open import Algebra.Consequences.Propositional using (comm∧distrˡ⇒distrʳ)open import Algebra.Morphism.Consequences using (homomorphic₂-inv)open import Data.Bool.Base using (true; false; if_then_else_)open import Data.Nat as ℕ using (ℕ)open import Data.Nat.Binary.Base using (ℕᵇ; 0ᵇ; 2[1+_]; 1+[2_]; double;pred; toℕ; fromℕ; even<odd; odd<even; _≥_; _>_; _≤_; _<_; _+_; zero; suc; 1ᵇ;_*_)open import Data.Nat.Binary.Propertiesimport Data.Nat.Properties as ℕopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂; ∃)open import Data.Sum.Base using (inj₁; inj₂)open import Data.Vec.Base using ([]; _∷_)open import Function.Base using (_∘_; _$_)open import Level using (0ℓ)open import Relation.Binaryusing (Tri; tri<; tri≈; tri>; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Algebra using (magma)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; sym; trans; subst; _≢_)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Nullary using (Dec; yes; no; does)open import Relation.Nullary.Negation using (contradiction)open import Algebra.Definitions {A = ℕᵇ} _≡_open import Algebra.Properties.CommutativeSemigroup +-commutativeSemigroupusing (xy∙z≈y∙xz; x∙yz≈y∙xz)open import Algebra.Solver.CommutativeMonoid +-0-commutativeMonoidprivatevariablex y : ℕᵇ-------------------------------------------------------------------------- Definitioninfixl 6 _∸__∸_ : Op₂ ℕᵇzero ∸ _ = 0ᵇx ∸ zero = x2[1+ x ] ∸ 2[1+ y ] = double (x ∸ y)1+[2 x ] ∸ 1+[2 y ] = double (x ∸ y)2[1+ x ] ∸ 1+[2 y ] = if does (x <? y) then 0ᵇ else 1+[2 (x ∸ y) ]1+[2 x ] ∸ 2[1+ y ] = if does (x ≤? y) then 0ᵇ else pred (double (x ∸ y))-------------------------------------------------------------------------- Properties of _∸_ and _≡_∸-magma : Magma 0ℓ 0ℓ∸-magma = magma _∸_x∸0≡x : ∀ x → x ∸ 0ᵇ ≡ xx∸0≡x zero = reflx∸0≡x 2[1+ _ ] = reflx∸0≡x 1+[2 _ ] = reflx∸x≡0 : ∀ x → x ∸ x ≡ 0ᵇx∸x≡0 zero = reflx∸x≡0 2[1+ x ] = x≡0⇒double[x]≡0 (x∸x≡0 x)x∸x≡0 1+[2 x ] = x≡0⇒double[x]≡0 (x∸x≡0 x)toℕ-homo-∸ : ∀ x y → toℕ (x ∸ y) ≡ (toℕ x) ℕ.∸ (toℕ y)toℕ-homo-∸ zero zero = refltoℕ-homo-∸ zero 2[1+ y ] = refltoℕ-homo-∸ zero 1+[2 y ] = refltoℕ-homo-∸ 2[1+ x ] zero = refltoℕ-homo-∸ 2[1+ x ] 2[1+ y ] = begintoℕ (double (x ∸ y)) ≡⟨ toℕ-double (x ∸ y) ⟩2 ℕ.* toℕ (x ∸ y) ≡⟨ cong (2 ℕ.*_) (toℕ-homo-∸ x y) ⟩2 ℕ.* (toℕ x ℕ.∸ toℕ y) ≡⟨ ℕ.*-distribˡ-∸ 2 (ℕ.suc (toℕ x)) (ℕ.suc (toℕ y)) ⟩toℕ 2[1+ x ] ℕ.∸ toℕ 2[1+ y ] ∎where open ≡-Reasoningtoℕ-homo-∸ 2[1+ x ] 1+[2 y ] with x <? y... | yes x<y = sym (ℕ.m≤n⇒m∸n≡0 (toℕ-mono-≤ (inj₁ (even<odd x<y))))... | no x≮y = beginℕ.suc (2 ℕ.* toℕ (x ∸ y)) ≡⟨ cong (ℕ.suc ∘ (2 ℕ.*_)) (toℕ-homo-∸ x y) ⟩ℕ.suc (2 ℕ.* (toℕ x ℕ.∸ toℕ y)) ≡⟨ cong ℕ.suc (ℕ.*-distribˡ-∸ 2 (toℕ x) (toℕ y)) ⟩ℕ.suc (2 ℕ.* toℕ x ℕ.∸ 2 ℕ.* toℕ y) ≡⟨ sym (ℕ.+-∸-assoc 1 (ℕ.*-monoʳ-≤ 2 (toℕ-mono-≤ (≮⇒≥ x≮y)))) ⟩ℕ.suc (2 ℕ.* toℕ x) ℕ.∸ 2 ℕ.* toℕ y ≡⟨ sym (cong (ℕ._∸ 2 ℕ.* toℕ y) (ℕ.+-suc (toℕ x) (1 ℕ.* toℕ x))) ⟩2 ℕ.* (ℕ.suc (toℕ x)) ℕ.∸ ℕ.suc (2 ℕ.* toℕ y) ∎where open ≡-Reasoningtoℕ-homo-∸ 1+[2 x ] zero = refltoℕ-homo-∸ 1+[2 x ] 2[1+ y ] with x ≤? y... | yes x≤y = sym (ℕ.m≤n⇒m∸n≡0 (toℕ-mono-≤ (inj₁ (odd<even x≤y))))... | no _ = begintoℕ (pred (double (x ∸ y))) ≡⟨ toℕ-pred (double (x ∸ y)) ⟩ℕ.pred (toℕ (double (x ∸ y))) ≡⟨ cong ℕ.pred (toℕ-double (x ∸ y)) ⟩ℕ.pred (2 ℕ.* toℕ (x ∸ y)) ≡⟨ cong (ℕ.pred ∘ (2 ℕ.*_)) (toℕ-homo-∸ x y) ⟩ℕ.pred (2 ℕ.* (toℕ x ℕ.∸ toℕ y)) ≡⟨ cong ℕ.pred (ℕ.*-distribˡ-∸ 2 (toℕ x) (toℕ y)) ⟩ℕ.pred (2 ℕ.* toℕ x ℕ.∸ 2 ℕ.* toℕ y) ≡⟨ ℕ.pred[m∸n]≡m∸[1+n] (2 ℕ.* toℕ x) (2 ℕ.* toℕ y) ⟩2 ℕ.* toℕ x ℕ.∸ ℕ.suc (2 ℕ.* toℕ y) ≡⟨ sym (cong (2 ℕ.* toℕ x ℕ.∸_) (ℕ.+-suc (toℕ y) (1 ℕ.* toℕ y))) ⟩ℕ.suc (2 ℕ.* toℕ x) ℕ.∸ 2 ℕ.* (ℕ.suc (toℕ y)) ∎where open ≡-Reasoningtoℕ-homo-∸ 1+[2 x ] 1+[2 y ] = begintoℕ (double (x ∸ y)) ≡⟨ toℕ-double (x ∸ y) ⟩2 ℕ.* toℕ (x ∸ y) ≡⟨ cong (2 ℕ.*_) (toℕ-homo-∸ x y) ⟩2 ℕ.* (toℕ x ℕ.∸ toℕ y) ≡⟨ ℕ.*-distribˡ-∸ 2 (toℕ x) (toℕ y) ⟩2 ℕ.* toℕ x ℕ.∸ 2 ℕ.* toℕ y ∎where open ≡-Reasoningfromℕ-homo-∸ : ∀ m n → fromℕ (m ℕ.∸ n) ≡ (fromℕ m) ∸ (fromℕ n)fromℕ-homo-∸ = homomorphic₂-inv ∸-magma ℕ.∸-magma(cong fromℕ) toℕ-inverseᵇ toℕ-homo-∸-------------------------------------------------------------------------- Properties of _∸_ and _≤_/_<_even∸odd-for≥ : x ≥ y → 2[1+ x ] ∸ 1+[2 y ] ≡ 1+[2 (x ∸ y) ]even∸odd-for≥ {x} {y} x≥y with x <? y... | no _ = refl... | yes x<y = contradiction x≥y (<⇒≱ x<y)odd∸even-for> : x > y → 1+[2 x ] ∸ 2[1+ y ] ≡ pred (double (x ∸ y))odd∸even-for> {x} {y} x>y with x ≤? y... | no _ = refl... | yes x≤y = contradiction x>y (≤⇒≯ x≤y)x≤y⇒x∸y≡0 : x ≤ y → x ∸ y ≡ 0ᵇx≤y⇒x∸y≡0 {x} {y} = toℕ-injective ∘ trans (toℕ-homo-∸ x y) ∘ ℕ.m≤n⇒m∸n≡0 ∘ toℕ-mono-≤x∸y≡0⇒x≤y : x ∸ y ≡ 0ᵇ → x ≤ yx∸y≡0⇒x≤y {x} {y} = toℕ-cancel-≤ ∘ ℕ.m∸n≡0⇒m≤n ∘ trans (sym (toℕ-homo-∸ x y)) ∘ cong toℕx<y⇒y∸x>0 : x < y → y ∸ x > 0ᵇx<y⇒y∸x>0 {x} {y} = toℕ-cancel-< ∘ subst (ℕ._> 0) (sym (toℕ-homo-∸ y x)) ∘ ℕ.m<n⇒0<n∸m ∘ toℕ-mono-<-------------------------------------------------------------------------- Properties of _∸_ and _+_[x∸y]+y≡x : x ≥ y → (x ∸ y) + y ≡ x[x∸y]+y≡x {x} {y} x≥y = toℕ-injective (begintoℕ (x ∸ y + y) ≡⟨ toℕ-homo-+ (x ∸ y) y ⟩toℕ (x ∸ y) ℕ.+ toℕ y ≡⟨ cong (ℕ._+ toℕ y) (toℕ-homo-∸ x y) ⟩(toℕ x ℕ.∸ toℕ y) ℕ.+ toℕ y ≡⟨ ℕ.m∸n+n≡m (toℕ-mono-≤ x≥y) ⟩toℕ x ∎)where open ≡-Reasoningx+y∸y≡x : ∀ x y → (x + y) ∸ y ≡ xx+y∸y≡x x y = +-cancelʳ-≡ _ _ x ([x∸y]+y≡x (x≤y+x y x))[x+y]∸x≡y : ∀ x y → (x + y) ∸ x ≡ y[x+y]∸x≡y x y = trans (cong (_∸ x) (+-comm x y)) (x+y∸y≡x y x)x+[y∸x]≡y : x ≤ y → x + (y ∸ x) ≡ yx+[y∸x]≡y {x} {y} x≤y = begin-equalityx + (y ∸ x) ≡⟨ +-comm x _ ⟩(y ∸ x) + x ≡⟨ [x∸y]+y≡x x≤y ⟩y ∎where open ≤-Reasoning∸-+-assoc : ∀ x y z → (x ∸ y) ∸ z ≡ x ∸ (y + z)∸-+-assoc x y z = toℕ-injective $ begintoℕ ((x ∸ y) ∸ z) ≡⟨ toℕ-homo-∸ (x ∸ y) z ⟩toℕ (x ∸ y) ℕ.∸ n ≡⟨ cong (ℕ._∸ n) (toℕ-homo-∸ x y) ⟩(k ℕ.∸ m) ℕ.∸ n ≡⟨ ℕ.∸-+-assoc k m n ⟩k ℕ.∸ (m ℕ.+ n) ≡⟨ cong (k ℕ.∸_) (sym (toℕ-homo-+ y z)) ⟩k ℕ.∸ (toℕ (y + z)) ≡⟨ sym (toℕ-homo-∸ x (y + z)) ⟩toℕ (x ∸ (y + z)) ∎where open ≡-Reasoning; k = toℕ x; m = toℕ y; n = toℕ z+-∸-assoc : ∀ x {y z} → z ≤ y → (x + y) ∸ z ≡ x + (y ∸ z)+-∸-assoc x {y} {z} z≤y = toℕ-injective $ begintoℕ ((x + y) ∸ z) ≡⟨ toℕ-homo-∸ (x + y) z ⟩(toℕ (x + y)) ℕ.∸ n ≡⟨ cong (ℕ._∸ n) (toℕ-homo-+ x y) ⟩(k ℕ.+ m) ℕ.∸ n ≡⟨ ℕ.+-∸-assoc k n≤m ⟩k ℕ.+ (m ℕ.∸ n) ≡⟨ cong (k ℕ.+_) (sym (toℕ-homo-∸ y z)) ⟩k ℕ.+ toℕ (y ∸ z) ≡⟨ sym (toℕ-homo-+ x (y ∸ z)) ⟩toℕ (x + (y ∸ z)) ∎whereopen ≡-Reasoning; k = toℕ x; m = toℕ y; n = toℕ z; n≤m = toℕ-mono-≤ z≤yx+y∸x+z≡y∸z : ∀ x y z → (x + y) ∸ (x + z) ≡ y ∸ zx+y∸x+z≡y∸z x y z = begin-equality(x + y) ∸ (x + z) ≡⟨ sym (∸-+-assoc (x + y) x z) ⟩((x + y) ∸ x) ∸ z ≡⟨ cong (_∸ z) ([x+y]∸x≡y x y) ⟩y ∸ z ∎where open ≤-Reasoningsuc[x]∸suc[y] : ∀ x y → suc x ∸ suc y ≡ x ∸ ysuc[x]∸suc[y] x y = begin-equalitysuc x ∸ suc y ≡⟨ cong₂ _∸_ (suc≗1+ x) (suc≗1+ y) ⟩(1ᵇ + x) ∸ (1ᵇ + y) ≡⟨ x+y∸x+z≡y∸z 1ᵇ x y ⟩x ∸ y ∎where open ≤-Reasoning∸-mono-≤ : _∸_ Preserves₂ _≤_ ⟶ _≥_ ⟶ _≤_∸-mono-≤ {x} {y} {u} {v} x≤y v≤u = toℕ-cancel-≤ (begintoℕ (x ∸ u) ≡⟨ toℕ-homo-∸ x u ⟩toℕ x ℕ.∸ toℕ u ≤⟨ ℕ.∸-mono (toℕ-mono-≤ x≤y) (toℕ-mono-≤ v≤u) ⟩toℕ y ℕ.∸ toℕ v ≡⟨ sym (toℕ-homo-∸ y v) ⟩toℕ (y ∸ v) ∎)where open ℕ.≤-Reasoning∸-monoˡ-≤ : (x : ℕᵇ) → (_∸ x) Preserves _≤_ ⟶ _≤_∸-monoˡ-≤ x y≤z = ∸-mono-≤ y≤z (≤-refl {x})∸-monoʳ-≤ : (x : ℕᵇ) → (x ∸_) Preserves _≥_ ⟶ _≤_∸-monoʳ-≤ x y≥z = ∸-mono-≤ (≤-refl {x}) y≥zx∸y≤x : ∀ x y → x ∸ y ≤ xx∸y≤x x y = beginx ∸ y ≤⟨ ∸-monoʳ-≤ x (0≤x y) ⟩x ∸ 0ᵇ ≡⟨ x∸0≡x x ⟩x ∎where open ≤-Reasoningx∸y<x : {x y : ℕᵇ} → x ≢ 0ᵇ → y ≢ 0ᵇ → x ∸ y < xx∸y<x {x} {y} x≢0 y≢0 = begin-strictx ∸ y ≡⟨ cong₂ _∸_ (sym (suc-pred x≢0)) (sym (suc-pred y≢0)) ⟩suc px ∸ suc py ≡⟨ suc[x]∸suc[y] px py ⟩px ∸ py ≤⟨ x∸y≤x px py ⟩px <⟨ pred[x]<x x≢0 ⟩x ∎where open ≤-Reasoning; px = pred x; py = pred y-------------------------------------------------------------------------- Properties of _∸_ and _*_*-distribˡ-∸ : _*_ DistributesOverˡ _∸_*-distribˡ-∸ x y z = toℕ-injective $ begintoℕ (x * (y ∸ z)) ≡⟨ toℕ-homo-* x (y ∸ z) ⟩k ℕ.* (toℕ (y ∸ z)) ≡⟨ cong (k ℕ.*_) (toℕ-homo-∸ y z) ⟩k ℕ.* (m ℕ.∸ n) ≡⟨ ℕ.*-distribˡ-∸ k m n ⟩(k ℕ.* m) ℕ.∸ (k ℕ.* n) ≡⟨ cong₂ ℕ._∸_ (sym (toℕ-homo-* x y)) (sym (toℕ-homo-* x z)) ⟩toℕ (x * y) ℕ.∸ toℕ (x * z) ≡⟨ sym (toℕ-homo-∸ (x * y) (x * z)) ⟩toℕ ((x * y) ∸ (x * z)) ∎where open ≡-Reasoning; k = toℕ x; m = toℕ y; n = toℕ z*-distribʳ-∸ : _*_ DistributesOverʳ _∸_*-distribʳ-∸ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-∸*-distrib-∸ : _*_ DistributesOver _∸_*-distrib-∸ = *-distribˡ-∸ , *-distribʳ-∸
-------------------------------------------------------------------------- The Agda standard library---- Basic properties of ℕᵇ------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary.Properties whereopen import Algebra.Bundlesopen import Algebra.Morphism.Structuresimport Algebra.Morphism.MonoidMonomorphism as MonoidMonomorphismopen import Algebra.Consequences.Propositional using (comm∧distrˡ⇒distrʳ)open import Data.Bool.Base using (if_then_else_; Bool; true; false)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Nat.Binary.Baseopen import Data.Nat.Base as ℕ using (ℕ; z≤n; s≤s; s<s⁻¹)open import Data.Nat.DivMod using (_%_; _/_; m/n≤m; +-distrib-/-∣ˡ)open import Data.Nat.Divisibility using (∣-refl)import Data.Nat.Properties as ℕopen import Data.Nat.Solver using (module +-*-Solver)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂; ∃)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (_∘_; _$_; id)open import Function.Definitions using (Injective; Surjective;Inverseˡ; Inverseʳ; Inverseᵇ)open import Function.Consequences.Propositionalusing (strictlySurjective⇒surjective; strictlyInverseˡ⇒inverseˡ;strictlyInverseʳ⇒inverseʳ)open import Level using (0ℓ)open import Relation.Binaryopen import Relation.Binary.Consequences using (trans∧irr⇒asym; tri⇒dec<)open import Relation.Binary.Morphismusing (IsRelHomomorphism; IsOrderHomomorphism; IsOrderMonomorphism)import Relation.Binary.Morphism.OrderMonomorphism as OrderMonomorphismopen import Relation.Binary.PropositionalEquality.Algebrausing (magma; isMagma)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; cong; cong₂; sym; _≗_; trans; ≢-sym; subst₂;subst; resp₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence; setoid; decSetoid; module ≡-Reasoning;isEquivalence)open import Relation.Nullary using (¬_; yes; no)import Relation.Nullary.Decidable as Decopen import Relation.Nullary.Negation.Core using (contradiction)open import Algebra.Definitions {A = ℕᵇ} _≡_open import Algebra.Structures {A = ℕᵇ} _≡_import Algebra.Properties.CommutativeSemigroup as CommSemigPropimport Algebra.Properties.CommutativeSemigroup ℕ.+-commutativeSemigroupas ℕ-+-semigroupPropertiesimport Relation.Binary.Construct.StrictToNonStrict _≡_ _<_as StrictToNonStrictopen +-*-Solverprivatevariablex : ℕᵇinfix 4 _<?_ _≟_ _≤?_-------------------------------------------------------------------------- Properties of _≡_------------------------------------------------------------------------2[1+x]≢0 : 2[1+ x ] ≢ 0ᵇ2[1+x]≢0 ()1+[2x]≢0 : 1+[2 x ] ≢ 0ᵇ1+[2x]≢0 ()2[1+_]-injective : Injective _≡_ _≡_ 2[1+_]2[1+_]-injective refl = refl1+[2_]-injective : Injective _≡_ _≡_ 1+[2_]1+[2_]-injective refl = refl_≟_ : DecidableEquality ℕᵇzero ≟ zero = yes reflzero ≟ 2[1+ _ ] = no λ()zero ≟ 1+[2 _ ] = no λ()2[1+ _ ] ≟ zero = no λ()2[1+ x ] ≟ 2[1+ y ] = Dec.map′ (cong 2[1+_]) 2[1+_]-injective (x ≟ y)2[1+ _ ] ≟ 1+[2 _ ] = no λ()1+[2 _ ] ≟ zero = no λ()1+[2 _ ] ≟ 2[1+ _ ] = no λ()1+[2 x ] ≟ 1+[2 y ] = Dec.map′ (cong 1+[2_]) 1+[2_]-injective (x ≟ y)≡-isDecEquivalence : IsDecEquivalence {A = ℕᵇ} _≡_≡-isDecEquivalence = isDecEquivalence _≟_≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid ℕᵇ≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- Properties of toℕ & fromℕ------------------------------------------------------------------------toℕ-double : ∀ x → toℕ (double x) ≡ 2 ℕ.* (toℕ x)toℕ-double zero = refltoℕ-double 1+[2 x ] = cong ((2 ℕ.*_) ∘ ℕ.suc) (toℕ-double x)toℕ-double 2[1+ x ] = cong (2 ℕ.*_) (sym (ℕ.*-distribˡ-+ 2 1 (toℕ x)))toℕ-suc : ∀ x → toℕ (suc x) ≡ ℕ.suc (toℕ x)toℕ-suc zero = refltoℕ-suc 2[1+ x ] = cong (ℕ.suc ∘ (2 ℕ.*_)) (toℕ-suc x)toℕ-suc 1+[2 x ] = ℕ.*-distribˡ-+ 2 1 (toℕ x)toℕ-pred : ∀ x → toℕ (pred x) ≡ ℕ.pred (toℕ x)toℕ-pred zero = refltoℕ-pred 2[1+ x ] = cong ℕ.pred $ sym $ ℕ.*-distribˡ-+ 2 1 (toℕ x)toℕ-pred 1+[2 x ] = toℕ-double xtoℕ-fromℕ' : toℕ ∘ fromℕ' ≗ idtoℕ-fromℕ' 0 = refltoℕ-fromℕ' (ℕ.suc n) = begintoℕ (fromℕ' (ℕ.suc n)) ≡⟨⟩toℕ (suc (fromℕ' n)) ≡⟨ toℕ-suc (fromℕ' n) ⟩ℕ.suc (toℕ (fromℕ' n)) ≡⟨ cong ℕ.suc (toℕ-fromℕ' n) ⟩ℕ.suc n ∎where open ≡-Reasoningfromℕ≡fromℕ' : fromℕ ≗ fromℕ'fromℕ≡fromℕ' n = fromℕ-helper≡fromℕ' n n ℕ.≤-reflwheresplit : ℕᵇ → Maybe Bool × ℕᵇsplit zero = nothing , zerosplit 2[1+ n ] = just false , nsplit 1+[2 n ] = just true , nhead = proj₁ ∘ splittail = proj₂ ∘ splitsplit-injective : Injective _≡_ _≡_ splitsplit-injective {zero} {zero} refl = reflsplit-injective {2[1+ _ ]} {2[1+ _ ]} refl = reflsplit-injective {1+[2 _ ]} {1+[2 _ ]} refl = reflsplit-if : ∀ x xs → split (if x then 1+[2 xs ] else 2[1+ xs ]) ≡ (just x , xs)split-if false xs = reflsplit-if true xs = reflhead-suc : ∀ n → head (suc (suc (suc n))) ≡ head (suc n)head-suc zero = reflhead-suc 2[1+ n ] = reflhead-suc 1+[2 n ] = refltail-suc : ∀ n → suc (tail (suc n)) ≡ tail (suc (suc (suc n)))tail-suc zero = refltail-suc 2[1+ n ] = refltail-suc 1+[2 n ] = reflhead-homo : ∀ n → head (suc (fromℕ' n)) ≡ just (n % 2 ℕ.≡ᵇ 0)head-homo ℕ.zero = reflhead-homo (ℕ.suc ℕ.zero) = reflhead-homo (ℕ.suc (ℕ.suc n)) = trans (head-suc (fromℕ' n)) (head-homo n)open ≡-Reasoningtail-homo : ∀ n → tail (suc (fromℕ' n)) ≡ fromℕ' (n / 2)tail-homo ℕ.zero = refltail-homo (ℕ.suc ℕ.zero) = refltail-homo (ℕ.suc (ℕ.suc n)) = begintail (suc (fromℕ' (ℕ.suc (ℕ.suc n)))) ≡⟨ tail-suc (fromℕ' n) ⟨suc (tail (suc (fromℕ' n))) ≡⟨ cong suc (tail-homo n) ⟩fromℕ' (ℕ.suc (n / 2)) ≡⟨ cong fromℕ' (+-distrib-/-∣ˡ {2} n ∣-refl) ⟨fromℕ' (ℕ.suc (ℕ.suc n) / 2) ∎fromℕ-helper≡fromℕ' : ∀ n w → n ℕ.≤ w → fromℕ.helper n n w ≡ fromℕ' nfromℕ-helper≡fromℕ' ℕ.zero w p = reflfromℕ-helper≡fromℕ' (ℕ.suc n) (ℕ.suc w) (s≤s n≤w) =split-injective (beginsplit (fromℕ.helper n (ℕ.suc n) (ℕ.suc w)) ≡⟨ split-if _ _ ⟩just (n % 2 ℕ.≡ᵇ 0) , fromℕ.helper n (n / 2) w ≡⟨ cong (_ ,_) rec-n/2 ⟩just (n % 2 ℕ.≡ᵇ 0) , fromℕ' (n / 2) ≡⟨ cong₂ _,_ (head-homo n) (tail-homo n) ⟨head (fromℕ' (ℕ.suc n)) , tail (fromℕ' (ℕ.suc n)) ≡⟨⟩split (fromℕ' (ℕ.suc n)) ∎)where rec-n/2 = fromℕ-helper≡fromℕ' (n / 2) w (ℕ.≤-trans (m/n≤m n 2) n≤w)toℕ-fromℕ : toℕ ∘ fromℕ ≗ idtoℕ-fromℕ n rewrite fromℕ≡fromℕ' n = toℕ-fromℕ' ntoℕ-injective : Injective _≡_ _≡_ toℕtoℕ-injective {zero} {zero} _ = refltoℕ-injective {2[1+ x ]} {2[1+ y ]} 2[1+xN]≡2[1+yN] = cong 2[1+_] x≡ywhere1+xN≡1+yN = ℕ.*-cancelˡ-≡ (ℕ.suc _) (ℕ.suc _) 2 2[1+xN]≡2[1+yN]xN≡yN = cong ℕ.pred 1+xN≡1+yNx≡y = toℕ-injective xN≡yNtoℕ-injective {2[1+ x ]} {1+[2 y ]} 2[1+xN]≡1+2yN =contradiction 2[1+xN]≡1+2yN (ℕ.even≢odd (ℕ.suc (toℕ x)) (toℕ y))toℕ-injective {1+[2 x ]} {2[1+ y ]} 1+2xN≡2[1+yN] =contradiction (sym 1+2xN≡2[1+yN]) (ℕ.even≢odd (ℕ.suc (toℕ y)) (toℕ x))toℕ-injective {1+[2 x ]} {1+[2 y ]} 1+2xN≡1+2yN = cong 1+[2_] x≡ywhere2xN≡2yN = cong ℕ.pred 1+2xN≡1+2yNxN≡yN = ℕ.*-cancelˡ-≡ _ _ 2 2xN≡2yNx≡y = toℕ-injective xN≡yNtoℕ-surjective : Surjective _≡_ _≡_ toℕtoℕ-surjective = strictlySurjective⇒surjective (λ n → fromℕ n , toℕ-fromℕ n)toℕ-isRelHomomorphism : IsRelHomomorphism _≡_ _≡_ toℕtoℕ-isRelHomomorphism = record{ cong = cong toℕ}fromℕ-injective : Injective _≡_ _≡_ fromℕfromℕ-injective {x} {y} f[x]≡f[y] = beginx ≡⟨ sym (toℕ-fromℕ x) ⟩toℕ (fromℕ x) ≡⟨ cong toℕ f[x]≡f[y] ⟩toℕ (fromℕ y) ≡⟨ toℕ-fromℕ y ⟩y ∎where open ≡-Reasoningfromℕ-toℕ : fromℕ ∘ toℕ ≗ idfromℕ-toℕ = toℕ-injective ∘ toℕ-fromℕ ∘ toℕtoℕ-inverseˡ : Inverseˡ _≡_ _≡_ toℕ fromℕtoℕ-inverseˡ = strictlyInverseˡ⇒inverseˡ {f⁻¹ = fromℕ} toℕ toℕ-fromℕtoℕ-inverseʳ : Inverseʳ _≡_ _≡_ toℕ fromℕtoℕ-inverseʳ = strictlyInverseʳ⇒inverseʳ toℕ fromℕ-toℕtoℕ-inverseᵇ : Inverseᵇ _≡_ _≡_ toℕ fromℕtoℕ-inverseᵇ = toℕ-inverseˡ , toℕ-inverseʳfromℕ-pred : ∀ n → fromℕ (ℕ.pred n) ≡ pred (fromℕ n)fromℕ-pred n = beginfromℕ (ℕ.pred n) ≡⟨ cong (fromℕ ∘ ℕ.pred) (sym (toℕ-fromℕ n)) ⟩fromℕ (ℕ.pred (toℕ y)) ≡⟨ cong fromℕ (sym (toℕ-pred y)) ⟩fromℕ (toℕ (pred y)) ≡⟨ fromℕ-toℕ (pred y) ⟩pred y ≡⟨ refl ⟩pred (fromℕ n) ∎where open ≡-Reasoning; y = fromℕ nx≡0⇒toℕ[x]≡0 : x ≡ zero → toℕ x ≡ 0x≡0⇒toℕ[x]≡0 {zero} _ = refltoℕ[x]≡0⇒x≡0 : toℕ x ≡ 0 → x ≡ zerotoℕ[x]≡0⇒x≡0 {zero} _ = refl-------------------------------------------------------------------------- Properties of _<_-------------------------------------------------------------------------- Basic propertiesx≮0 : x ≮ zerox≮0 ()x≢0⇒x>0 : x ≢ zero → x > zerox≢0⇒x>0 {zero} 0≢0 = contradiction refl 0≢0x≢0⇒x>0 {2[1+ _ ]} _ = 0<evenx≢0⇒x>0 {1+[2 _ ]} _ = 0<odd1+[2x]<2[1+x] : ∀ x → 1+[2 x ] < 2[1+ x ]1+[2x]<2[1+x] x = odd<even (inj₂ refl)<⇒≢ : _<_ ⇒ _≢_<⇒≢ (even<even x<x) refl = <⇒≢ x<x refl<⇒≢ (odd<odd x<x) refl = <⇒≢ x<x refl>⇒≢ : _>_ ⇒ _≢_>⇒≢ y<x = ≢-sym (<⇒≢ y<x)≡⇒≮ : _≡_ ⇒ _≮_≡⇒≮ x≡y x<y = <⇒≢ x<y x≡y≡⇒≯ : _≡_ ⇒ _≯_≡⇒≯ x≡y x>y = >⇒≢ x>y x≡y<⇒≯ : _<_ ⇒ _≯_<⇒≯ (even<even x<y) (even<even y<x) = <⇒≯ x<y y<x<⇒≯ (even<odd x<y) (odd<even (inj₁ y<x)) = <⇒≯ x<y y<x<⇒≯ (even<odd x<y) (odd<even (inj₂ refl)) = <⇒≢ x<y refl<⇒≯ (odd<even (inj₁ x<y)) (even<odd y<x) = <⇒≯ x<y y<x<⇒≯ (odd<even (inj₂ refl)) (even<odd y<x) = <⇒≢ y<x refl<⇒≯ (odd<odd x<y) (odd<odd y<x) = <⇒≯ x<y y<x>⇒≮ : _>_ ⇒ _≮_>⇒≮ y<x = <⇒≯ y<x<⇒≤ : _<_ ⇒ _≤_<⇒≤ = inj₁-------------------------------------------------------------------------- Properties of _<_ and toℕ & fromℕ.toℕ-mono-< : toℕ Preserves _<_ ⟶ ℕ._<_toℕ-mono-< {zero} {2[1+ _ ]} _ = ℕ.0<1+ntoℕ-mono-< {zero} {1+[2 _ ]} _ = ℕ.0<1+ntoℕ-mono-< {2[1+ x ]} {2[1+ y ]} (even<even x<y) = beginℕ.suc (2 ℕ.* (ℕ.suc xN)) ≤⟨ ℕ.+-monoʳ-≤ 1 (ℕ.*-monoʳ-≤ 2 xN<yN) ⟩ℕ.suc (2 ℕ.* yN) ≤⟨ ℕ.n≤1+n _ ⟩2 ℕ.+ (2 ℕ.* yN) ≡⟨ sym (ℕ.*-distribˡ-+ 2 1 yN) ⟩2 ℕ.* (ℕ.suc yN) ∎where open ℕ.≤-Reasoning; xN = toℕ x; yN = toℕ y; xN<yN = toℕ-mono-< x<ytoℕ-mono-< {2[1+ x ]} {1+[2 y ]} (even<odd x<y) =ℕ.+-monoʳ-≤ 1 (ℕ.*-monoʳ-≤ 2 (toℕ-mono-< x<y))toℕ-mono-< {1+[2 x ]} {2[1+ y ]} (odd<even (inj₁ x<y)) = beginℕ.suc (ℕ.suc (2 ℕ.* xN)) ≡⟨⟩2 ℕ.+ (2 ℕ.* xN) ≡⟨ sym (ℕ.*-distribˡ-+ 2 1 xN) ⟩2 ℕ.* (ℕ.suc xN) ≤⟨ ℕ.*-monoʳ-≤ 2 xN<yN ⟩2 ℕ.* yN ≤⟨ ℕ.*-monoʳ-≤ 2 (ℕ.n≤1+n _) ⟩2 ℕ.* (ℕ.suc yN) ∎where open ℕ.≤-Reasoning; xN = toℕ x; yN = toℕ y; xN<yN = toℕ-mono-< x<ytoℕ-mono-< {1+[2 x ]} {2[1+ .x ]} (odd<even (inj₂ refl)) =ℕ.≤-reflexive (sym (ℕ.*-distribˡ-+ 2 1 (toℕ x)))toℕ-mono-< {1+[2 x ]} {1+[2 y ]} (odd<odd x<y) = ℕ.+-monoʳ-< 1 (ℕ.*-monoʳ-< 2 xN<yN)where xN = toℕ x; yN = toℕ y; xN<yN = toℕ-mono-< x<ytoℕ-cancel-< : ∀ {x y} → toℕ x ℕ.< toℕ y → x < ytoℕ-cancel-< {zero} {2[1+ y ]} x<y = 0<eventoℕ-cancel-< {zero} {1+[2 y ]} x<y = 0<oddtoℕ-cancel-< {2[1+ x ]} {2[1+ y ]} x<y =even<even (toℕ-cancel-< (s<s⁻¹ (ℕ.*-cancelˡ-< 2 _ _ x<y)))toℕ-cancel-< {2[1+ x ]} {1+[2 y ]} x<yrewrite ℕ.*-distribˡ-+ 2 1 (toℕ x) =even<odd (toℕ-cancel-< (ℕ.*-cancelˡ-< 2 _ _ (ℕ.≤-trans (s≤s (ℕ.n≤1+n _)) (s<s⁻¹ x<y))))toℕ-cancel-< {1+[2 x ]} {2[1+ y ]} x<y with toℕ x ℕ.≟ toℕ y... | yes x≡y = odd<even (inj₂ (toℕ-injective x≡y))... | no x≢yrewrite ℕ.+-suc (toℕ y) (toℕ y ℕ.+ 0) =odd<even (inj₁ (toℕ-cancel-< (ℕ.≤∧≢⇒< (ℕ.*-cancelˡ-≤ 2 (ℕ.+-cancelˡ-≤ 2 _ _ x<y)) x≢y)))toℕ-cancel-< {1+[2 x ]} {1+[2 y ]} x<y =odd<odd (toℕ-cancel-< (ℕ.*-cancelˡ-< 2 _ _ (s<s⁻¹ x<y)))fromℕ-cancel-< : ∀ {x y} → fromℕ x < fromℕ y → x ℕ.< yfromℕ-cancel-< = subst₂ ℕ._<_ (toℕ-fromℕ _) (toℕ-fromℕ _) ∘ toℕ-mono-<fromℕ-mono-< : fromℕ Preserves ℕ._<_ ⟶ _<_fromℕ-mono-< = toℕ-cancel-< ∘ subst₂ ℕ._<_ (sym (toℕ-fromℕ _)) (sym (toℕ-fromℕ _))toℕ-isHomomorphism-< : IsOrderHomomorphism _≡_ _≡_ _<_ ℕ._<_ toℕtoℕ-isHomomorphism-< = record{ cong = cong toℕ; mono = toℕ-mono-<}toℕ-isMonomorphism-< : IsOrderMonomorphism _≡_ _≡_ _<_ ℕ._<_ toℕtoℕ-isMonomorphism-< = record{ isOrderHomomorphism = toℕ-isHomomorphism-<; injective = toℕ-injective; cancel = toℕ-cancel-<}-------------------------------------------------------------------------- Relational properties of _<_<-irrefl : Irreflexive _≡_ _<_<-irrefl refl (even<even x<x) = <-irrefl refl x<x<-irrefl refl (odd<odd x<x) = <-irrefl refl x<x<-trans : Transitive _<_<-trans {zero} {_} {2[1+ _ ]} _ _ = 0<even<-trans {zero} {_} {1+[2 _ ]} _ _ = 0<odd<-trans (even<even x<y) (even<even y<z) = even<even (<-trans x<y y<z)<-trans (even<even x<y) (even<odd y<z) = even<odd (<-trans x<y y<z)<-trans (even<odd x<y) (odd<even (inj₁ y<z)) = even<even (<-trans x<y y<z)<-trans (even<odd x<y) (odd<even (inj₂ refl)) = even<even x<y<-trans (even<odd x<y) (odd<odd y<z) = even<odd (<-trans x<y y<z)<-trans (odd<even (inj₁ x<y)) (even<even y<z) = odd<even (inj₁ (<-trans x<y y<z))<-trans (odd<even (inj₂ refl)) (even<even x<z) = odd<even (inj₁ x<z)<-trans (odd<even (inj₁ x<y)) (even<odd y<z) = odd<odd (<-trans x<y y<z)<-trans (odd<even (inj₂ refl)) (even<odd x<z) = odd<odd x<z<-trans (odd<odd x<y) (odd<even (inj₁ y<z)) = odd<even (inj₁ (<-trans x<y y<z))<-trans (odd<odd x<y) (odd<even (inj₂ refl)) = odd<even (inj₁ x<y)<-trans (odd<odd x<y) (odd<odd y<z) = odd<odd (<-trans x<y y<z)<-asym : Asymmetric _<_<-asym {x} {y} = trans∧irr⇒asym refl <-trans <-irrefl {x} {y}-- Should not be implemented via the morphism `toℕ` in order to-- preserve O(log n) time requirement.<-cmp : Trichotomous _≡_ _<_<-cmp zero zero = tri≈ x≮0 refl x≮0<-cmp zero 2[1+ _ ] = tri< 0<even (λ()) x≮0<-cmp zero 1+[2 _ ] = tri< 0<odd (λ()) x≮0<-cmp 2[1+ _ ] zero = tri> (λ()) (λ()) 0<even<-cmp 2[1+ x ] 2[1+ y ] with <-cmp x y... | tri< x<y _ _ = tri< lt (<⇒≢ lt) (<⇒≯ lt) where lt = even<even x<y... | tri≈ _ refl _ = tri≈ (<-irrefl refl) refl (<-irrefl refl)... | tri> _ _ x>y = tri> (>⇒≮ gt) (>⇒≢ gt) gt where gt = even<even x>y<-cmp 2[1+ x ] 1+[2 y ] with <-cmp x y... | tri< x<y _ _ = tri< lt (<⇒≢ lt) (<⇒≯ lt) where lt = even<odd x<y... | tri≈ _ refl _ = tri> (>⇒≮ gt) (>⇒≢ gt) gtwheregt = subst (_< 2[1+ x ]) refl (1+[2x]<2[1+x] x)... | tri> _ _ y<x = tri> (>⇒≮ gt) (>⇒≢ gt) gt where gt = odd<even (inj₁ y<x)<-cmp 1+[2 _ ] zero = tri> (>⇒≮ gt) (>⇒≢ gt) gt where gt = 0<odd<-cmp 1+[2 x ] 2[1+ y ] with <-cmp x y... | tri< x<y _ _ = tri< lt (<⇒≢ lt) (<⇒≯ lt) where lt = odd<even (inj₁ x<y)... | tri≈ _ x≡y _ = tri< lt (<⇒≢ lt) (<⇒≯ lt) where lt = odd<even (inj₂ x≡y)... | tri> _ _ x>y = tri> (>⇒≮ gt) (>⇒≢ gt) gt where gt = even<odd x>y<-cmp 1+[2 x ] 1+[2 y ] with <-cmp x y... | tri< x<y _ _ = tri< lt (<⇒≢ lt) (<⇒≯ lt) where lt = odd<odd x<y... | tri≈ _ refl _ = tri≈ (≡⇒≮ refl) refl (≡⇒≯ refl)... | tri> _ _ x>y = tri> (>⇒≮ gt) (>⇒≢ gt) gt where gt = odd<odd x>y_<?_ : Decidable _<__<?_ = tri⇒dec< <-cmp-------------------------------------------------------------------------- Structures for _<_<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = resp₂ _<_}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}-------------------------------------------------------------------------- Bundles for _<_<-strictPartialOrder : StrictPartialOrder _ _ _<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder _ _ _<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}-------------------------------------------------------------------------- Other properties of _<_x<2[1+x] : ∀ x → x < 2[1+ x ]x<1+[2x] : ∀ x → x < 1+[2 x ]x<2[1+x] zero = 0<evenx<2[1+x] 2[1+ x ] = even<even (x<2[1+x] x)x<2[1+x] 1+[2 x ] = odd<even (inj₁ (x<1+[2x] x))x<1+[2x] zero = 0<oddx<1+[2x] 2[1+ x ] = even<odd (x<2[1+x] x)x<1+[2x] 1+[2 x ] = odd<odd (x<1+[2x] x)-------------------------------------------------------------------------- Properties of _≤_-------------------------------------------------------------------------- Basic properties<⇒≱ : _<_ ⇒ _≱_<⇒≱ x<y (inj₁ y<x) = contradiction y<x (<⇒≯ x<y)<⇒≱ x<y (inj₂ y≡x) = contradiction (sym y≡x) (<⇒≢ x<y)≤⇒≯ : _≤_ ⇒ _≯_≤⇒≯ x≤y x>y = <⇒≱ x>y x≤y≮⇒≥ : _≮_ ⇒ _≥_≮⇒≥ {x} {y} x≮y with <-cmp x y... | tri< lt _ _ = contradiction lt x≮y... | tri≈ _ eq _ = inj₂ (sym eq)... | tri> _ _ y<x = <⇒≤ y<x≰⇒> : _≰_ ⇒ _>_≰⇒> {x} {y} x≰y with <-cmp x y... | tri< lt _ _ = contradiction (<⇒≤ lt) x≰y... | tri≈ _ eq _ = contradiction (inj₂ eq) x≰y... | tri> _ _ x>y = x>y≤∧≢⇒< : ∀ {x y} → x ≤ y → x ≢ y → x < y≤∧≢⇒< (inj₁ x<y) _ = x<y≤∧≢⇒< (inj₂ x≡y) x≢y = contradiction x≡y x≢y0≤x : ∀ x → zero ≤ x0≤x zero = inj₂ refl0≤x 2[1+ _ ] = inj₁ 0<even0≤x 1+[2 x ] = inj₁ 0<oddx≤0⇒x≡0 : x ≤ zero → x ≡ zerox≤0⇒x≡0 (inj₂ x≡0) = x≡0-------------------------------------------------------------------------- Properties of _<_ and toℕ & fromℕ.fromℕ-mono-≤ : fromℕ Preserves ℕ._≤_ ⟶ _≤_fromℕ-mono-≤ m≤n with ℕ.m≤n⇒m<n∨m≡n m≤n... | inj₁ m<n = inj₁ (fromℕ-mono-< m<n)... | inj₂ m≡n = inj₂ (cong fromℕ m≡n)toℕ-mono-≤ : toℕ Preserves _≤_ ⟶ ℕ._≤_toℕ-mono-≤ (inj₁ x<y) = ℕ.<⇒≤ (toℕ-mono-< x<y)toℕ-mono-≤ (inj₂ refl) = ℕ.≤-reflexive refltoℕ-cancel-≤ : ∀ {x y} → toℕ x ℕ.≤ toℕ y → x ≤ ytoℕ-cancel-≤ = subst₂ _≤_ (fromℕ-toℕ _) (fromℕ-toℕ _) ∘ fromℕ-mono-≤fromℕ-cancel-≤ : ∀ {x y} → fromℕ x ≤ fromℕ y → x ℕ.≤ yfromℕ-cancel-≤ = subst₂ ℕ._≤_ (toℕ-fromℕ _) (toℕ-fromℕ _) ∘ toℕ-mono-≤toℕ-isHomomorphism-≤ : IsOrderHomomorphism _≡_ _≡_ _≤_ ℕ._≤_ toℕtoℕ-isHomomorphism-≤ = record{ cong = cong toℕ; mono = toℕ-mono-≤}toℕ-isMonomorphism-≤ : IsOrderMonomorphism _≡_ _≡_ _≤_ ℕ._≤_ toℕtoℕ-isMonomorphism-≤ = record{ isOrderHomomorphism = toℕ-isHomomorphism-≤; injective = toℕ-injective; cancel = toℕ-cancel-≤}-------------------------------------------------------------------------- Relational properties of _≤_≤-refl : Reflexive _≤_≤-refl = inj₂ refl≤-reflexive : _≡_ ⇒ _≤_≤-reflexive {x} {_} refl = ≤-refl {x}≤-trans : Transitive _≤_≤-trans = StrictToNonStrict.trans isEquivalence (resp₂ _<_) <-trans<-≤-trans : ∀ {x y z} → x < y → y ≤ z → x < z<-≤-trans x<y (inj₁ y<z) = <-trans x<y y<z<-≤-trans x<y (inj₂ refl) = x<y≤-<-trans : ∀ {x y z} → x ≤ y → y < z → x < z≤-<-trans (inj₁ x<y) y<z = <-trans x<y y<z≤-<-trans (inj₂ refl) y<z = y<z≤-antisym : Antisymmetric _≡_ _≤_≤-antisym = StrictToNonStrict.antisym isEquivalence <-trans <-irrefl≤-total : Total _≤_≤-total x y with <-cmp x y... | tri< x<y _ _ = inj₁ (<⇒≤ x<y)... | tri≈ _ x≡y _ = inj₁ (≤-reflexive x≡y)... | tri> _ _ y<x = inj₂ (<⇒≤ y<x)-- Should not be implemented via the morphism `toℕ` in order to-- preserve O(log n) time requirement._≤?_ : Decidable _≤_x ≤? y with <-cmp x y... | tri< x<y _ _ = yes (<⇒≤ x<y)... | tri≈ _ x≡y _ = yes (≤-reflexive x≡y)... | tri> _ _ y<x = no (<⇒≱ y<x)-------------------------------------------------------------------------- Structures≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder = record{ isPreorder = ≤-isPreorder}≤-partialOrder : Poset 0ℓ 0ℓ 0ℓ≤-partialOrder = record{ isPartialOrder = ≤-isPartialOrder}≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-totalOrder = record{ isTotalOrder = ≤-isTotalOrder}≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder = record{ isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Equational reasoning for _≤_ and _<_module ≤-Reasoning whereopen import Relation.Binary.Reasoning.Base.Triple≤-isPreorder<-asym<-trans(resp₂ _<_)<⇒≤<-≤-trans≤-<-transpublichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)-------------------------------------------------------------------------- Properties of _<ℕ_------------------------------------------------------------------------<⇒<ℕ : ∀ {x y} → x < y → x <ℕ y<⇒<ℕ x<y = toℕ-mono-< x<y<ℕ⇒< : ∀ {x y} → x <ℕ y → x < y<ℕ⇒< {x} {y} t[x]<t[y] = begin-strictx ≡⟨ sym (fromℕ-toℕ x) ⟩fromℕ (toℕ x) <⟨ fromℕ-mono-< t[x]<t[y] ⟩fromℕ (toℕ y) ≡⟨ fromℕ-toℕ y ⟩y ∎where open ≤-Reasoning-------------------------------------------------------------------------- Properties of _+_-- toℕ/fromℕ are homomorphisms for _+_toℕ-homo-+ : ∀ x y → toℕ (x + y) ≡ toℕ x ℕ.+ toℕ ytoℕ-homo-+ zero _ = refltoℕ-homo-+ 2[1+ x ] zero = cong ℕ.suc (sym (ℕ.+-identityʳ _))toℕ-homo-+ 1+[2 x ] zero = cong ℕ.suc (sym (ℕ.+-identityʳ _))toℕ-homo-+ 2[1+ x ] 2[1+ y ] = begintoℕ (2[1+ x ] + 2[1+ y ]) ≡⟨⟩toℕ 2[1+ (suc (x + y)) ] ≡⟨⟩2 ℕ.* (1 ℕ.+ (toℕ (suc (x + y)))) ≡⟨ cong ((2 ℕ.*_) ∘ ℕ.suc) (toℕ-suc (x + y)) ⟩2 ℕ.* (2 ℕ.+ toℕ (x + y)) ≡⟨ cong ((2 ℕ.*_) ∘ (2 ℕ.+_)) (toℕ-homo-+ x y) ⟩2 ℕ.* (2 ℕ.+ (toℕ x ℕ.+ toℕ y)) ≡⟨ solve 2 (λ m n → con 2 :* (con 2 :+ (m :+ n)) :=con 2 :* (con 1 :+ m) :+ con 2 :* (con 1 :+ n))refl (toℕ x) (toℕ y) ⟩toℕ 2[1+ x ] ℕ.+ toℕ 2[1+ y ] ∎where open ≡-Reasoningtoℕ-homo-+ 2[1+ x ] 1+[2 y ] = begintoℕ (2[1+ x ] + 1+[2 y ]) ≡⟨⟩toℕ (suc 2[1+ (x + y) ]) ≡⟨ toℕ-suc 2[1+ (x + y) ] ⟩ℕ.suc (toℕ 2[1+ (x + y) ]) ≡⟨⟩ℕ.suc (2 ℕ.* (ℕ.suc (toℕ (x + y)))) ≡⟨ cong (λ v → ℕ.suc (2 ℕ.* ℕ.suc v)) (toℕ-homo-+ x y) ⟩ℕ.suc (2 ℕ.* (ℕ.suc (m ℕ.+ n))) ≡⟨ solve 2 (λ m n → con 1 :+ (con 2 :* (con 1 :+ (m :+ n))) :=con 2 :* (con 1 :+ m) :+ (con 1 :+ (con 2 :* n)))refl m n ⟩(2 ℕ.* ℕ.suc m) ℕ.+ (ℕ.suc (2 ℕ.* n)) ≡⟨⟩toℕ 2[1+ x ] ℕ.+ toℕ 1+[2 y ] ∎where open ≡-Reasoning; m = toℕ x; n = toℕ ytoℕ-homo-+ 1+[2 x ] 2[1+ y ] = begintoℕ (1+[2 x ] + 2[1+ y ]) ≡⟨⟩toℕ (suc 2[1+ (x + y) ]) ≡⟨ toℕ-suc 2[1+ (x + y) ] ⟩ℕ.suc (toℕ 2[1+ (x + y) ]) ≡⟨⟩ℕ.suc (2 ℕ.* (ℕ.suc (toℕ (x + y)))) ≡⟨ cong (ℕ.suc ∘ (2 ℕ.*_) ∘ ℕ.suc) (toℕ-homo-+ x y) ⟩ℕ.suc (2 ℕ.* (ℕ.suc (m ℕ.+ n))) ≡⟨ solve 2 (λ m n → con 1 :+ (con 2 :* (con 1 :+ (m :+ n))) :=(con 1 :+ (con 2 :* m)) :+ (con 2 :* (con 1 :+ n)))refl m n ⟩(ℕ.suc (2 ℕ.* m)) ℕ.+ (2 ℕ.* (ℕ.suc n)) ≡⟨⟩toℕ 1+[2 x ] ℕ.+ toℕ 2[1+ y ] ∎where open ≡-Reasoning; m = toℕ x; n = toℕ ytoℕ-homo-+ 1+[2 x ] 1+[2 y ] = begintoℕ (1+[2 x ] + 1+[2 y ]) ≡⟨⟩toℕ (suc 1+[2 (x + y) ]) ≡⟨ toℕ-suc 1+[2 (x + y) ] ⟩ℕ.suc (toℕ 1+[2 (x + y) ]) ≡⟨⟩ℕ.suc (ℕ.suc (2 ℕ.* (toℕ (x + y)))) ≡⟨ cong (ℕ.suc ∘ ℕ.suc ∘ (2 ℕ.*_)) (toℕ-homo-+ x y) ⟩ℕ.suc (ℕ.suc (2 ℕ.* (m ℕ.+ n))) ≡⟨ solve 2 (λ m n → con 1 :+ (con 1 :+ (con 2 :* (m :+ n))) :=(con 1 :+ (con 2 :* m)) :+ (con 1 :+ (con 2 :* n)))refl m n ⟩(ℕ.suc (2 ℕ.* m)) ℕ.+ (ℕ.suc (2 ℕ.* n)) ≡⟨⟩toℕ 1+[2 x ] ℕ.+ toℕ 1+[2 y ] ∎where open ≡-Reasoning; m = toℕ x; n = toℕ ytoℕ-isMagmaHomomorphism-+ : IsMagmaHomomorphism +-rawMagma ℕ.+-rawMagma toℕtoℕ-isMagmaHomomorphism-+ = record{ isRelHomomorphism = toℕ-isRelHomomorphism; homo = toℕ-homo-+}toℕ-isMonoidHomomorphism-+ : IsMonoidHomomorphism +-0-rawMonoid ℕ.+-0-rawMonoid toℕtoℕ-isMonoidHomomorphism-+ = record{ isMagmaHomomorphism = toℕ-isMagmaHomomorphism-+; ε-homo = refl}toℕ-isMonoidMonomorphism-+ : IsMonoidMonomorphism +-0-rawMonoid ℕ.+-0-rawMonoid toℕtoℕ-isMonoidMonomorphism-+ = record{ isMonoidHomomorphism = toℕ-isMonoidHomomorphism-+; injective = toℕ-injective}suc≗1+ : suc ≗ 1ᵇ +_suc≗1+ zero = reflsuc≗1+ 2[1+ _ ] = reflsuc≗1+ 1+[2 _ ] = reflsuc-+ : ∀ x y → suc x + y ≡ suc (x + y)suc-+ zero y = sym (suc≗1+ y)suc-+ 2[1+ x ] zero = reflsuc-+ 1+[2 x ] zero = reflsuc-+ 2[1+ x ] 2[1+ y ] = cong (suc ∘ 2[1+_]) (suc-+ x y)suc-+ 2[1+ x ] 1+[2 y ] = cong (suc ∘ 1+[2_]) (suc-+ x y)suc-+ 1+[2 x ] 2[1+ y ] = reflsuc-+ 1+[2 x ] 1+[2 y ] = refl1+≗suc : (1ᵇ +_) ≗ suc1+≗suc = suc-+ zerofromℕ'-homo-+ : ∀ m n → fromℕ' (m ℕ.+ n) ≡ fromℕ' m + fromℕ' nfromℕ'-homo-+ 0 _ = reflfromℕ'-homo-+ (ℕ.suc m) n = beginfromℕ' ((ℕ.suc m) ℕ.+ n) ≡⟨⟩suc (fromℕ' (m ℕ.+ n)) ≡⟨ cong suc (fromℕ'-homo-+ m n) ⟩suc (a + b) ≡⟨ sym (suc-+ a b) ⟩(suc a) + b ≡⟨⟩(fromℕ' (ℕ.suc m)) + (fromℕ' n) ∎where open ≡-Reasoning; a = fromℕ' m; b = fromℕ' nfromℕ-homo-+ : ∀ m n → fromℕ (m ℕ.+ n) ≡ fromℕ m + fromℕ nfromℕ-homo-+ m n rewrite fromℕ≡fromℕ' (m ℕ.+ n) | fromℕ≡fromℕ' m | fromℕ≡fromℕ' n =fromℕ'-homo-+ m n-------------------------------------------------------------------------- Algebraic properties of _+_-- Mostly proved by using the isomorphism between `ℕ` and `ℕᵇ` provided-- by `toℕ`/`fromℕ`.privatemodule +-Monomorphism = MonoidMonomorphism toℕ-isMonoidMonomorphism-++-assoc : Associative _+_+-assoc = +-Monomorphism.assoc ℕ.+-isMagma ℕ.+-assoc+-comm : Commutative _+_+-comm = +-Monomorphism.comm ℕ.+-isMagma ℕ.+-comm+-identityˡ : LeftIdentity zero _+_+-identityˡ _ = refl+-identityʳ : RightIdentity zero _+_+-identityʳ = +-Monomorphism.identityʳ ℕ.+-isMagma ℕ.+-identityʳ+-identity : Identity zero _+_+-identity = +-identityˡ , +-identityʳ+-cancelˡ-≡ : LeftCancellative _+_+-cancelˡ-≡ = +-Monomorphism.cancelˡ ℕ.+-isMagma ℕ.+-cancelˡ-≡+-cancelʳ-≡ : RightCancellative _+_+-cancelʳ-≡ = +-Monomorphism.cancelʳ ℕ.+-isMagma ℕ.+-cancelʳ-≡-------------------------------------------------------------------------- Structures for _+_+-isMagma : IsMagma _+_+-isMagma = isMagma _+_+-isSemigroup : IsSemigroup _+_+-isSemigroup = +-Monomorphism.isSemigroup ℕ.+-isSemigroup+-isCommutativeSemigroup : IsCommutativeSemigroup _+_+-isCommutativeSemigroup = record{ isSemigroup = +-isSemigroup; comm = +-comm}+-0-isMonoid : IsMonoid _+_ 0ᵇ+-0-isMonoid = +-Monomorphism.isMonoid ℕ.+-0-isMonoid+-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0ᵇ+-0-isCommutativeMonoid = +-Monomorphism.isCommutativeMonoid ℕ.+-0-isCommutativeMonoid-------------------------------------------------------------------------- Bundles for _+_+-magma : Magma 0ℓ 0ℓ+-magma = magma _+_+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ+-commutativeSemigroup = record{ isCommutativeSemigroup = +-isCommutativeSemigroup}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ ε = zero; isMonoid = +-0-isMonoid}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}module Bin+CSemigroup = CommSemigProp +-commutativeSemigroup-------------------------------------------------------------------------- Properties of _+_ and _≤_+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-≤ {x} {x′} {y} {y′} x≤x′ y≤y′ = beginx + y ≡⟨ sym $ cong₂ _+_ (fromℕ-toℕ x) (fromℕ-toℕ y) ⟩fromℕ m + fromℕ n ≡⟨ sym (fromℕ-homo-+ m n) ⟩fromℕ (m ℕ.+ n) ≤⟨ fromℕ-mono-≤ (ℕ.+-mono-≤ m≤m′ n≤n′) ⟩fromℕ (m′ ℕ.+ n′) ≡⟨ fromℕ-homo-+ m′ n′ ⟩fromℕ m′ + fromℕ n′ ≡⟨ cong₂ _+_ (fromℕ-toℕ x′) (fromℕ-toℕ y′) ⟩x′ + y′ ∎whereopen ≤-Reasoningm = toℕ x; m′ = toℕ x′n = toℕ y; n′ = toℕ y′m≤m′ = toℕ-mono-≤ x≤x′; n≤n′ = toℕ-mono-≤ y≤y′+-monoˡ-≤ : ∀ x → (_+ x) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ x y≤z = +-mono-≤ y≤z (≤-refl {x})+-monoʳ-≤ : ∀ x → (x +_) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ x y≤z = +-mono-≤ (≤-refl {x}) y≤z+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-<-≤ {x} {x′} {y} {y′} x<x′ y≤y′ = begin-strictx + y ≡⟨ sym $ cong₂ _+_ (fromℕ-toℕ x) (fromℕ-toℕ y) ⟩fromℕ m + fromℕ n ≡⟨ sym (fromℕ-homo-+ m n) ⟩fromℕ (m ℕ.+ n) <⟨ fromℕ-mono-< (ℕ.+-mono-<-≤ m<m′ n≤n′) ⟩fromℕ (m′ ℕ.+ n′) ≡⟨ fromℕ-homo-+ m′ n′ ⟩fromℕ m′ + fromℕ n′ ≡⟨ cong₂ _+_ (fromℕ-toℕ x′) (fromℕ-toℕ y′) ⟩x′ + y′ ∎whereopen ≤-Reasoningm = toℕ x; n = toℕ ym′ = toℕ x′; n′ = toℕ y′m<m′ = toℕ-mono-< x<x′; n≤n′ = toℕ-mono-≤ y≤y′+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-≤-< {x} {x′} {y} {y′} x≤x′ y<y′ = subst₂ _<_ (+-comm y x) (+-comm y′ x′) y+x<y′+x′wherey+x<y′+x′ = +-mono-<-≤ y<y′ x≤x′+-monoˡ-< : ∀ x → (_+ x) Preserves _<_ ⟶ _<_+-monoˡ-< x y<z = +-mono-<-≤ y<z (≤-refl {x})+-monoʳ-< : ∀ x → (x +_) Preserves _<_ ⟶ _<_+-monoʳ-< x y<z = +-mono-≤-< (≤-refl {x}) y<zx≤y+x : ∀ x y → x ≤ y + xx≤y+x x y = beginx ≡⟨ sym (+-identityˡ x) ⟩0ᵇ + x ≤⟨ +-monoˡ-≤ x (0≤x y) ⟩y + x ∎where open ≤-Reasoningx≤x+y : ∀ x y → x ≤ x + yx≤x+y x y = beginx ≤⟨ x≤y+x x y ⟩y + x ≡⟨ +-comm y x ⟩x + y ∎where open ≤-Reasoningx<x+y : ∀ x {y} → y > 0ᵇ → x < x + yx<x+y x {y} y>0 = begin-strictx ≡⟨ sym (fromℕ-toℕ x) ⟩fromℕ (toℕ x) <⟨ fromℕ-mono-< (ℕ.m<m+n (toℕ x) (toℕ-mono-< y>0)) ⟩fromℕ (toℕ x ℕ.+ toℕ y) ≡⟨ fromℕ-homo-+ (toℕ x) (toℕ y) ⟩fromℕ (toℕ x) + fromℕ (toℕ y) ≡⟨ cong₂ _+_ (fromℕ-toℕ x) (fromℕ-toℕ y) ⟩x + y ∎where open ≤-Reasoningx<x+1 : ∀ x → x < x + 1ᵇx<x+1 x = x<x+y x 0<oddx<1+x : ∀ x → x < 1ᵇ + xx<1+x x rewrite +-comm 1ᵇ x = x<x+1 xx<1⇒x≡0 : x < 1ᵇ → x ≡ zerox<1⇒x≡0 0<odd = refl-------------------------------------------------------------------------- Other propertiesx≢0⇒x+y≢0 : ∀ {x} (y : ℕᵇ) → x ≢ zero → x + y ≢ zerox≢0⇒x+y≢0 {2[1+ _ ]} zero _ = λ()x≢0⇒x+y≢0 {zero} _ 0≢0 = contradiction refl 0≢0-------------------------------------------------------------------------- Properties of _*_-- toℕ/fromℕ are homomorphisms for _*_private 2*ₙ2*ₙ = (2 ℕ.*_) ∘ (2 ℕ.*_)toℕ-homo-* : ∀ x y → toℕ (x * y) ≡ toℕ x ℕ.* toℕ ytoℕ-homo-* x y = aux x y (size x ℕ.+ size y) ℕ.≤-reflwhereaux : (x y : ℕᵇ) → (cnt : ℕ) → (size x ℕ.+ size y ℕ.≤ cnt) → toℕ (x * y) ≡ toℕ x ℕ.* toℕ yaux zero _ _ _ = reflaux 2[1+ x ] zero _ _ = sym (ℕ.*-zeroʳ (toℕ x ℕ.+ (ℕ.suc (toℕ x ℕ.+ 0))))aux 1+[2 x ] zero _ _ = sym (ℕ.*-zeroʳ (toℕ x ℕ.+ (toℕ x ℕ.+ 0)))aux 2[1+ x ] 2[1+ y ] (ℕ.suc cnt) (s≤s |x|+1+|y|≤cnt) = begintoℕ (2[1+ x ] * 2[1+ y ]) ≡⟨⟩toℕ (double 2[1+ (x + (y + xy)) ]) ≡⟨ toℕ-double 2[1+ (x + (y + xy)) ] ⟩2 ℕ.* (toℕ 2[1+ (x + (y + xy)) ]) ≡⟨⟩2*ₙ2*ₙ (ℕ.suc (toℕ (x + (y + xy)))) ≡⟨ cong (2*ₙ2*ₙ ∘ ℕ.suc) (toℕ-homo-+ x (y + xy)) ⟩2*ₙ2*ₙ (ℕ.suc (m ℕ.+ (toℕ (y + xy)))) ≡⟨ cong (2*ₙ2*ₙ ∘ ℕ.suc ∘ (m ℕ.+_)) (toℕ-homo-+ y xy) ⟩2*ₙ2*ₙ (ℕ.suc (m ℕ.+ (n ℕ.+ toℕ xy))) ≡⟨ cong (2*ₙ2*ₙ ∘ ℕ.suc ∘ (m ℕ.+_) ∘ (n ℕ.+_))(aux x y cnt |x|+|y|≤cnt) ⟩2*ₙ2*ₙ (ℕ.suc (m ℕ.+ (n ℕ.+ (m ℕ.* n)))) ≡⟨ solve 2 (λ m n → con 2 :* (con 2 :* (con 1 :+ (m :+ (n :+ m :* n)))) :=(con 2 :* (con 1 :+ m)) :* (con 2 :* (con 1 :+ n)))refl m n ⟩(2 ℕ.* (1 ℕ.+ m)) ℕ.* (2 ℕ.* (1 ℕ.+ n)) ≡⟨⟩toℕ 2[1+ x ] ℕ.* toℕ 2[1+ y ] ∎whereopen ≡-Reasoning; m = toℕ x; n = toℕ y; xy = x * y|x|+|y|≤cnt = ℕ.≤-trans (ℕ.+-monoʳ-≤ (size x) (ℕ.n≤1+n (size y))) |x|+1+|y|≤cntaux 2[1+ x ] 1+[2 y ] (ℕ.suc cnt) (s≤s |x|+1+|y|≤cnt) = begintoℕ (2[1+ x ] * 1+[2 y ]) ≡⟨⟩toℕ (2[1+ (x + y * 2[1+ x ]) ]) ≡⟨⟩2 ℕ.* (ℕ.suc (toℕ (x + y * 2[1+ x ]))) ≡⟨ cong ((2 ℕ.*_) ∘ ℕ.suc) (toℕ-homo-+ x _) ⟩2 ℕ.* (ℕ.suc (m ℕ.+ (toℕ (y * 2[1+ x ])))) ≡⟨ cong ((2 ℕ.*_) ∘ ℕ.suc ∘ (m ℕ.+_))(aux y 2[1+ x ] cnt |y|+1+|x|≤cnt) ⟩2 ℕ.* (1+m ℕ.+ (n ℕ.* (toℕ 2[1+ x ]))) ≡⟨⟩2 ℕ.* (1+m ℕ.+ (n ℕ.* 2[1+m])) ≡⟨ solve 2 (λ m n →con 2 :* ((con 1 :+ m) :+ (n :* (con 2 :* (con 1 :+ m)))) :=(con 2 :* (con 1 :+ m)) :* (con 1 :+ con 2 :* n))refl m n ⟩2[1+m] ℕ.* (ℕ.suc (2 ℕ.* n)) ≡⟨⟩toℕ 2[1+ x ] ℕ.* toℕ 1+[2 y ] ∎whereopen ≡-Reasoning; m = toℕ x; n = toℕ y; 1+m = ℕ.suc m; 2[1+m] = 2 ℕ.* (ℕ.suc m)eq : size x ℕ.+ (ℕ.suc (size y)) ≡ size y ℕ.+ (ℕ.suc (size x))eq = ℕ-+-semigroupProperties.x∙yz≈z∙yx (size x) 1 _|y|+1+|x|≤cnt = subst (ℕ._≤ cnt) eq |x|+1+|y|≤cntaux 1+[2 x ] 2[1+ y ] (ℕ.suc cnt) (s≤s |x|+1+|y|≤cnt) = begintoℕ (1+[2 x ] * 2[1+ y ]) ≡⟨⟩toℕ 2[1+ (y + x * 2[1+ y ]) ] ≡⟨⟩2 ℕ.* (ℕ.suc (toℕ (y + x * 2[1+ y ]))) ≡⟨ cong ((2 ℕ.*_) ∘ ℕ.suc)(toℕ-homo-+ y (x * 2[1+ y ])) ⟩2 ℕ.* (ℕ.suc (n ℕ.+ (toℕ (x * 2[1+ y ])))) ≡⟨ cong ((2 ℕ.*_) ∘ ℕ.suc ∘ (n ℕ.+_))(aux x 2[1+ y ] cnt |x|+1+|y|≤cnt) ⟩2 ℕ.* (1+n ℕ.+ (m ℕ.* toℕ 2[1+ y ])) ≡⟨⟩2 ℕ.* (1+n ℕ.+ (m ℕ.* 2[1+n])) ≡⟨ solve 2 (λ m n →con 2 :* ((con 1 :+ n) :+ (m :* (con 2 :* (con 1 :+ n)))) :=(con 1 :+ (con 2 :* m)) :* (con 2 :* (con 1 :+ n)))refl m n ⟩(ℕ.suc 2m) ℕ.* 2[1+n] ≡⟨⟩toℕ 1+[2 x ] ℕ.* toℕ 2[1+ y ] ∎whereopen ≡-Reasoningm = toℕ x; n = toℕ y; 1+n = ℕ.suc n2m = 2 ℕ.* m; 2[1+n] = 2 ℕ.* (ℕ.suc n)aux 1+[2 x ] 1+[2 y ] (ℕ.suc cnt) (s≤s |x|+1+|y|≤cnt) = begintoℕ (1+[2 x ] * 1+[2 y ]) ≡⟨⟩toℕ 1+[2 (x + y * 1+2x) ] ≡⟨⟩ℕ.suc (2 ℕ.* (toℕ (x + y * 1+2x))) ≡⟨ cong (ℕ.suc ∘ (2 ℕ.*_)) (toℕ-homo-+ x (y * 1+2x)) ⟩ℕ.suc (2 ℕ.* (m ℕ.+ (toℕ (y * 1+2x)))) ≡⟨ cong (ℕ.suc ∘ (2 ℕ.*_) ∘ (m ℕ.+_))(aux y 1+2x cnt |y|+1+|x|≤cnt) ⟩ℕ.suc (2 ℕ.* (m ℕ.+ (n ℕ.* [1+2x]′))) ≡⟨ cong ℕ.suc $ ℕ.*-distribˡ-+ 2 m (n ℕ.* [1+2x]′) ⟩ℕ.suc (2m ℕ.+ (2 ℕ.* (n ℕ.* [1+2x]′))) ≡⟨ cong (ℕ.suc ∘ (2m ℕ.+_)) (sym (ℕ.*-assoc 2 n _)) ⟩(ℕ.suc 2m) ℕ.+ 2n ℕ.* [1+2x]′ ≡⟨⟩[1+2x]′ ℕ.+ 2n ℕ.* [1+2x]′ ≡⟨ cong (ℕ._+ (2n ℕ.* [1+2x]′)) $sym (ℕ.*-identityˡ [1+2x]′) ⟩1 ℕ.* [1+2x]′ ℕ.+ 2n ℕ.* [1+2x]′ ≡⟨ sym (ℕ.*-distribʳ-+ [1+2x]′ 1 2n) ⟩(ℕ.suc 2n) ℕ.* [1+2x]′ ≡⟨ ℕ.*-comm (ℕ.suc 2n) [1+2x]′ ⟩toℕ 1+[2 x ] ℕ.* toℕ 1+[2 y ] ∎whereopen ≡-Reasoningm = toℕ x; n = toℕ y; 2m = 2 ℕ.* m; 2n = 2 ℕ.* n1+2x = 1+[2 x ]; [1+2x]′ = toℕ 1+2xeq : size x ℕ.+ (ℕ.suc (size y)) ≡ size y ℕ.+ (ℕ.suc (size x))eq = ℕ-+-semigroupProperties.x∙yz≈z∙yx (size x) 1 _|y|+1+|x|≤cnt = subst (ℕ._≤ cnt) eq |x|+1+|y|≤cnttoℕ-isMagmaHomomorphism-* : IsMagmaHomomorphism *-rawMagma ℕ.*-rawMagma toℕtoℕ-isMagmaHomomorphism-* = record{ isRelHomomorphism = toℕ-isRelHomomorphism; homo = toℕ-homo-*}toℕ-isMonoidHomomorphism-* : IsMonoidHomomorphism *-1-rawMonoid ℕ.*-1-rawMonoid toℕtoℕ-isMonoidHomomorphism-* = record{ isMagmaHomomorphism = toℕ-isMagmaHomomorphism-*; ε-homo = refl}toℕ-isMonoidMonomorphism-* : IsMonoidMonomorphism *-1-rawMonoid ℕ.*-1-rawMonoid toℕtoℕ-isMonoidMonomorphism-* = record{ isMonoidHomomorphism = toℕ-isMonoidHomomorphism-*; injective = toℕ-injective}fromℕ-homo-* : ∀ m n → fromℕ (m ℕ.* n) ≡ fromℕ m * fromℕ nfromℕ-homo-* m n = beginfromℕ (m ℕ.* n) ≡⟨ cong fromℕ (cong₂ ℕ._*_ m≡aN n≡bN) ⟩fromℕ (toℕ a ℕ.* toℕ b) ≡⟨ cong fromℕ (sym (toℕ-homo-* a b)) ⟩fromℕ (toℕ (a * b)) ≡⟨ fromℕ-toℕ (a * b) ⟩a * b ∎whereopen ≡-Reasoninga = fromℕ m; b = fromℕ nm≡aN = sym (toℕ-fromℕ m); n≡bN = sym (toℕ-fromℕ n)privatemodule *-Monomorphism = MonoidMonomorphism toℕ-isMonoidMonomorphism-*-------------------------------------------------------------------------- Algebraic properties of _*_-- Mostly proved by using the isomorphism between `ℕ` and `ℕᵇ` provided-- by `toℕ`/`fromℕ`.*-assoc : Associative _*_*-assoc = *-Monomorphism.assoc ℕ.*-isMagma ℕ.*-assoc*-comm : Commutative _*_*-comm = *-Monomorphism.comm ℕ.*-isMagma ℕ.*-comm*-identityˡ : LeftIdentity 1ᵇ _*_*-identityˡ = *-Monomorphism.identityˡ ℕ.*-isMagma ℕ.*-identityˡ*-identityʳ : RightIdentity 1ᵇ _*_*-identityʳ x = trans (*-comm x 1ᵇ) (*-identityˡ x)*-identity : Identity 1ᵇ _*_*-identity = (*-identityˡ , *-identityʳ)*-zeroˡ : LeftZero zero _*_*-zeroˡ _ = refl*-zeroʳ : RightZero zero _*_*-zeroʳ zero = refl*-zeroʳ 2[1+ _ ] = refl*-zeroʳ 1+[2 _ ] = refl*-zero : Zero zero _*_*-zero = *-zeroˡ , *-zeroʳ*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distribˡ-+ a b c = begina * (b + c) ≡⟨ sym (fromℕ-toℕ (a * (b + c))) ⟩fromℕ (toℕ (a * (b + c))) ≡⟨ cong fromℕ (toℕ-homo-* a (b + c)) ⟩fromℕ (k ℕ.* (toℕ (b + c))) ≡⟨ cong (fromℕ ∘ (k ℕ.*_)) (toℕ-homo-+ b c) ⟩fromℕ (k ℕ.* (m ℕ.+ n)) ≡⟨ cong fromℕ (ℕ.*-distribˡ-+ k m n) ⟩fromℕ (k ℕ.* m ℕ.+ k ℕ.* n) ≡⟨ cong fromℕ $ sym $cong₂ ℕ._+_ (toℕ-homo-* a b) (toℕ-homo-* a c) ⟩fromℕ (toℕ (a * b) ℕ.+ toℕ (a * c)) ≡⟨ cong fromℕ (sym (toℕ-homo-+ (a * b) (a * c))) ⟩fromℕ (toℕ (a * b + a * c)) ≡⟨ fromℕ-toℕ (a * b + a * c) ⟩a * b + a * c ∎where open ≡-Reasoning; k = toℕ a; m = toℕ b; n = toℕ c*-distribʳ-+ : _*_ DistributesOverʳ _+_*-distribʳ-+ = comm∧distrˡ⇒distrʳ *-comm *-distribˡ-+*-distrib-+ : _*_ DistributesOver _+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+-------------------------------------------------------------------------- Structures*-isMagma : IsMagma _*_*-isMagma = isMagma _*_*-isSemigroup : IsSemigroup _*_*-isSemigroup = *-Monomorphism.isSemigroup ℕ.*-isSemigroup*-1-isMonoid : IsMonoid _*_ 1ᵇ*-1-isMonoid = *-Monomorphism.isMonoid ℕ.*-1-isMonoid*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1ᵇ*-1-isCommutativeMonoid = *-Monomorphism.isCommutativeMonoid ℕ.*-1-isCommutativeMonoid+-*-isSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero _+_ _*_ zero 1ᵇ+-*-isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-0-isCommutativeMonoid; *-cong = cong₂ _*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}+-*-isSemiring : IsSemiring _+_ _*_ zero 1ᵇ+-*-isSemiring = record{ isSemiringWithoutAnnihilatingZero = +-*-isSemiringWithoutAnnihilatingZero; zero = *-zero}+-*-isCommutativeSemiring : IsCommutativeSemiring _+_ _*_ zero 1ᵇ+-*-isCommutativeSemiring = record{ isSemiring = +-*-isSemiring; *-comm = *-comm}-------------------------------------------------------------------------- Bundles*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-semiring : Semiring 0ℓ 0ℓ+-*-semiring = record{ isSemiring = +-*-isSemiring}+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ+-*-commutativeSemiring = record{ isCommutativeSemiring = +-*-isCommutativeSemiring}-------------------------------------------------------------------------- Properties of _*_ and _≤_ & _<_*-mono-≤ : _*_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_*-mono-≤ {x} {u} {y} {v} x≤u y≤v = toℕ-cancel-≤ (begintoℕ (x * y) ≡⟨ toℕ-homo-* x y ⟩toℕ x ℕ.* toℕ y ≤⟨ ℕ.*-mono-≤ (toℕ-mono-≤ x≤u) (toℕ-mono-≤ y≤v) ⟩toℕ u ℕ.* toℕ v ≡⟨ sym (toℕ-homo-* u v) ⟩toℕ (u * v) ∎)where open ℕ.≤-Reasoning*-monoʳ-≤ : ∀ x → (x *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤ x y≤y′ = *-mono-≤ (≤-refl {x}) y≤y′*-monoˡ-≤ : ∀ x → (_* x) Preserves _≤_ ⟶ _≤_*-monoˡ-≤ x y≤y′ = *-mono-≤ y≤y′ (≤-refl {x})*-mono-< : _*_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_*-mono-< {x} {u} {y} {v} x<u y<v = toℕ-cancel-< (begin-stricttoℕ (x * y) ≡⟨ toℕ-homo-* x y ⟩toℕ x ℕ.* toℕ y <⟨ ℕ.*-mono-< (toℕ-mono-< x<u) (toℕ-mono-< y<v) ⟩toℕ u ℕ.* toℕ v ≡⟨ sym (toℕ-homo-* u v) ⟩toℕ (u * v) ∎)where open ℕ.≤-Reasoning*-monoʳ-< : ∀ x → ((1ᵇ + x) *_) Preserves _<_ ⟶ _<_*-monoʳ-< x {y} {z} y<z = begin-strict(1ᵇ + x) * y ≡⟨ *-distribʳ-+ y 1ᵇ x ⟩1ᵇ * y + x * y ≡⟨ cong (_+ x * y) (*-identityˡ y) ⟩y + x * y <⟨ +-mono-<-≤ y<z (*-monoʳ-≤ x (<⇒≤ y<z)) ⟩z + x * z ≡⟨ cong (_+ x * z) (sym (*-identityˡ z)) ⟩1ᵇ * z + x * z ≡⟨ sym (*-distribʳ-+ z 1ᵇ x) ⟩(1ᵇ + x) * z ∎where open ≤-Reasoning*-monoˡ-< : ∀ x → (_* (1ᵇ + x)) Preserves _<_ ⟶ _<_*-monoˡ-< x {y} {z} y<z = begin-stricty * (1ᵇ + x) ≡⟨ *-comm y (1ᵇ + x) ⟩(1ᵇ + x) * y <⟨ *-monoʳ-< x y<z ⟩(1ᵇ + x) * z ≡⟨ *-comm (1ᵇ + x) z ⟩z * (1ᵇ + x) ∎where open ≤-Reasoning-------------------------------------------------------------------------- Other properties of _*_x*y≡0⇒x≡0∨y≡0 : ∀ x {y} → x * y ≡ zero → x ≡ zero ⊎ y ≡ zerox*y≡0⇒x≡0∨y≡0 zero {_} _ = inj₁ reflx*y≡0⇒x≡0∨y≡0 _ {zero} _ = inj₂ reflx≢0∧y≢0⇒x*y≢0 : ∀ {x y} → x ≢ zero → y ≢ zero → x * y ≢ zerox≢0∧y≢0⇒x*y≢0 {x} {_} x≢0 y≢0 xy≡0 with x*y≡0⇒x≡0∨y≡0 x xy≡0... | inj₁ x≡0 = x≢0 x≡0... | inj₂ y≡0 = y≢0 y≡02*x≡x+x : ∀ x → 2ᵇ * x ≡ x + x2*x≡x+x x = begin2ᵇ * x ≡⟨⟩(1ᵇ + 1ᵇ) * x ≡⟨ *-distribʳ-+ x 1ᵇ 1ᵇ ⟩1ᵇ * x + 1ᵇ * x ≡⟨ cong₂ _+_ (*-identityˡ x) (*-identityˡ x) ⟩x + x ∎where open ≡-Reasoning1+-* : ∀ x y → (1ᵇ + x) * y ≡ y + x * y1+-* x y = begin(1ᵇ + x) * y ≡⟨ *-distribʳ-+ y 1ᵇ x ⟩1ᵇ * y + x * y ≡⟨ cong (_+ x * y) (*-identityˡ y) ⟩y + x * y ∎where open ≡-Reasoning*-1+ : ∀ x y → y * (1ᵇ + x) ≡ y + y * x*-1+ x y = beginy * (1ᵇ + x) ≡⟨ *-distribˡ-+ y 1ᵇ x ⟩y * 1ᵇ + y * x ≡⟨ cong (_+ y * x) (*-identityʳ y) ⟩y + y * x ∎where open ≡-Reasoning-------------------------------------------------------------------------- Properties of double------------------------------------------------------------------------double[x]≡0⇒x≡0 : double x ≡ zero → x ≡ zerodouble[x]≡0⇒x≡0 {zero} _ = reflx≡0⇒double[x]≡0 : x ≡ 0ᵇ → double x ≡ 0ᵇx≡0⇒double[x]≡0 = cong doublex≢0⇒double[x]≢0 : x ≢ zero → double x ≢ zerox≢0⇒double[x]≢0 x≢0 = x≢0 ∘ double[x]≡0⇒x≡0double≢1 : double x ≢ 1ᵇdouble≢1 {zero} ()double≗2* : double ≗ 2ᵇ *_double≗2* x = toℕ-injective $ begintoℕ (double x) ≡⟨ toℕ-double x ⟩2 ℕ.* (toℕ x) ≡⟨ sym (toℕ-homo-* 2ᵇ x) ⟩toℕ (2ᵇ * x) ∎where open ≡-Reasoningdouble-*-assoc : ∀ x y → (double x) * y ≡ double (x * y)double-*-assoc x y = begin(double x) * y ≡⟨ cong (_* y) (double≗2* x) ⟩(2ᵇ * x) * y ≡⟨ *-assoc 2ᵇ x y ⟩2ᵇ * (x * y) ≡⟨ sym (double≗2* (x * y)) ⟩double (x * y) ∎where open ≡-Reasoningdouble[x]≡x+x : ∀ x → double x ≡ x + xdouble[x]≡x+x x = trans (double≗2* x) (2*x≡x+x x)double-distrib-+ : ∀ x y → double (x + y) ≡ double x + double ydouble-distrib-+ x y = begindouble (x + y) ≡⟨ double≗2* (x + y) ⟩2ᵇ * (x + y) ≡⟨ *-distribˡ-+ 2ᵇ x y ⟩(2ᵇ * x) + (2ᵇ * y) ≡⟨ sym (cong₂ _+_ (double≗2* x) (double≗2* y)) ⟩double x + double y ∎where open ≡-Reasoningdouble-mono-≤ : double Preserves _≤_ ⟶ _≤_double-mono-≤ {x} {y} x≤y = begindouble x ≡⟨ double≗2* x ⟩2ᵇ * x ≤⟨ *-monoʳ-≤ 2ᵇ x≤y ⟩2ᵇ * y ≡⟨ sym (double≗2* y) ⟩double y ∎where open ≤-Reasoningdouble-mono-< : double Preserves _<_ ⟶ _<_double-mono-< {x} {y} x<y = begin-strictdouble x ≡⟨ double≗2* x ⟩2ᵇ * x <⟨ *-monoʳ-< 1ᵇ x<y ⟩2ᵇ * y ≡⟨ sym (double≗2* y) ⟩double y ∎where open ≤-Reasoningdouble-cancel-≤ : ∀ {x y} → double x ≤ double y → x ≤ ydouble-cancel-≤ {x} {y} 2x≤2y with <-cmp x y... | tri< x<y _ _ = <⇒≤ x<y... | tri≈ _ x≡y _ = ≤-reflexive x≡y... | tri> _ _ x>y = contradiction 2x≤2y (<⇒≱ (double-mono-< x>y))double-cancel-< : ∀ {x y} → double x < double y → x < ydouble-cancel-< {x} {y} 2x<2y with <-cmp x y... | tri< x<y _ _ = x<y... | tri≈ _ refl _ = contradiction 2x<2y (<-irrefl refl)... | tri> _ _ x>y = contradiction (double-mono-< x>y) (<⇒≯ 2x<2y)x<double[x] : ∀ x → x ≢ zero → x < double xx<double[x] x x≢0 = begin-strictx <⟨ x<x+y x (x≢0⇒x>0 x≢0) ⟩x + x ≡⟨ sym (double[x]≡x+x x) ⟩double x ∎where open ≤-Reasoningx≤double[x] : ∀ x → x ≤ double xx≤double[x] x = beginx ≤⟨ x≤x+y x x ⟩x + x ≡⟨ sym (double[x]≡x+x x) ⟩double x ∎where open ≤-Reasoningdouble-suc : ∀ x → double (suc x) ≡ 2ᵇ + double xdouble-suc x = begindouble (suc x) ≡⟨ cong double (suc≗1+ x) ⟩double (1ᵇ + x) ≡⟨ double-distrib-+ 1ᵇ x ⟩2ᵇ + double x ∎where open ≡-Reasoning-------------------------------------------------------------------------- Properties of suc------------------------------------------------------------------------suc≢0 : suc x ≢ zerosuc≢0 {zero} ()suc≢0 {2[1+ _ ]} ()suc≢0 {1+[2 _ ]} ()suc-injective : Injective _≡_ _≡_ sucsuc-injective {zero} {zero} p = reflsuc-injective {zero} {2[1+ y ]} p = contradiction 1+[2 p ]-injective (suc≢0 ∘ sym)suc-injective {2[1+ x ]} {zero} p = contradiction 1+[2 p ]-injective suc≢0suc-injective {2[1+ x ]} {2[1+ y ]} p = cong 2[1+_] (suc-injective 1+[2 p ]-injective)suc-injective {1+[2 x ]} {1+[2 y ]} refl = refl2[1+_]-double-suc : 2[1+_] ≗ double ∘ suc2[1+_]-double-suc zero = refl2[1+_]-double-suc 2[1+ x ] = cong 2[1+_] (2[1+_]-double-suc x)2[1+_]-double-suc 1+[2 x ] = refl1+[2_]-suc-double : 1+[2_] ≗ suc ∘ double1+[2_]-suc-double zero = refl1+[2_]-suc-double 2[1+ x ] = refl1+[2_]-suc-double 1+[2 x ] = begin1+[2 1+[2 x ] ] ≡⟨ cong 1+[2_] (1+[2_]-suc-double x) ⟩1+[2 (suc 2x) ] ≡⟨⟩suc 2[1+ 2x ] ≡⟨ cong suc (2[1+_]-double-suc 2x) ⟩suc (double (suc 2x)) ≡⟨ cong (suc ∘ double) (sym (1+[2_]-suc-double x)) ⟩suc (double 1+[2 x ]) ∎where open ≡-Reasoning; 2x = double xx+suc[y]≡suc[x]+y : ∀ x y → x + suc y ≡ suc x + yx+suc[y]≡suc[x]+y x y = beginx + suc y ≡⟨ +-comm x _ ⟩suc y + x ≡⟨ suc-+ y x ⟩suc (y + x) ≡⟨ cong suc (+-comm y x) ⟩suc (x + y) ≡⟨ sym (suc-+ x y) ⟩suc x + y ∎where open ≡-Reasoning0<suc : ∀ x → zero < suc x0<suc x = x≢0⇒x>0 (suc≢0 {x})x<suc[x] : ∀ x → x < suc xx<suc[x] x = begin-strictx <⟨ x<1+x x ⟩1ᵇ + x ≡⟨ sym (suc≗1+ x) ⟩suc x ∎where open ≤-Reasoningx≤suc[x] : ∀ x → x ≤ suc xx≤suc[x] x = <⇒≤ (x<suc[x] x)x≢suc[x] : ∀ x → x ≢ suc xx≢suc[x] x = <⇒≢ (x<suc[x] x)suc-mono-≤ : suc Preserves _≤_ ⟶ _≤_suc-mono-≤ {x} {y} x≤y = beginsuc x ≡⟨ suc≗1+ x ⟩1ᵇ + x ≤⟨ +-monoʳ-≤ 1ᵇ x≤y ⟩1ᵇ + y ≡⟨ sym (suc≗1+ y) ⟩suc y ∎where open ≤-Reasoningsuc[x]≤y⇒x<y : ∀ {x y} → suc x ≤ y → x < ysuc[x]≤y⇒x<y {x} (inj₁ sx<y) = <-trans (x<suc[x] x) sx<ysuc[x]≤y⇒x<y {x} (inj₂ refl) = x<suc[x] xx<y⇒suc[x]≤y : ∀ {x y} → x < y → suc x ≤ yx<y⇒suc[x]≤y {x} {y} x<y = beginsuc x ≡⟨ sym (fromℕ-toℕ (suc x)) ⟩fromℕ (toℕ (suc x)) ≡⟨ cong fromℕ (toℕ-suc x) ⟩fromℕ (ℕ.suc (toℕ x)) ≤⟨ fromℕ-mono-≤ (toℕ-mono-< x<y) ⟩fromℕ (toℕ y) ≡⟨ fromℕ-toℕ y ⟩y ∎where open ≤-Reasoningsuc-* : ∀ x y → suc x * y ≡ y + x * ysuc-* x y = beginsuc x * y ≡⟨ cong (_* y) (suc≗1+ x) ⟩(1ᵇ + x) * y ≡⟨ 1+-* x y ⟩y + x * y ∎where open ≡-Reasoning*-suc : ∀ x y → x * suc y ≡ x + x * y*-suc x y = beginx * suc y ≡⟨ cong (x *_) (suc≗1+ y) ⟩x * (1ᵇ + y) ≡⟨ *-1+ y x ⟩x + x * y ∎where open ≡-Reasoningx≤suc[y]*x : ∀ x y → x ≤ (suc y) * xx≤suc[y]*x x y = beginx ≤⟨ x≤x+y x (y * x) ⟩x + y * x ≡⟨ sym (suc-* y x) ⟩(suc y) * x ∎where open ≤-Reasoningsuc[x]≤double[x] : ∀ x → x ≢ zero → suc x ≤ double xsuc[x]≤double[x] x = x<y⇒suc[x]≤y {x} {double x} ∘ x<double[x] xsuc[x]<2[1+x] : ∀ x → suc x < 2[1+ x ]suc[x]<2[1+x] x = begin-strictsuc x <⟨ x<double[x] (suc x) suc≢0 ⟩double (suc x) ≡⟨ sym (2[1+_]-double-suc x) ⟩2[1+ x ] ∎where open ≤-Reasoningdouble[x]<1+[2x] : ∀ x → double x < 1+[2 x ]double[x]<1+[2x] x = begin-strictdouble x <⟨ x<suc[x] (double x) ⟩suc (double x) ≡⟨ sym (1+[2_]-suc-double x) ⟩1+[2 x ] ∎where open ≤-Reasoning-------------------------------------------------------------------------- Properties of pred------------------------------------------------------------------------pred-suc : pred ∘ suc ≗ idpred-suc zero = reflpred-suc 2[1+ x ] = sym (2[1+_]-double-suc x)pred-suc 1+[2 x ] = reflsuc-pred : x ≢ zero → suc (pred x) ≡ xsuc-pred {zero} 0≢0 = contradiction refl 0≢0suc-pred {2[1+ _ ]} _ = reflsuc-pred {1+[2 x ]} _ = sym (1+[2_]-suc-double x)pred-mono-≤ : pred Preserves _≤_ ⟶ _≤_pred-mono-≤ {x} {y} x≤y = beginpred x ≡⟨ cong pred (sym (fromℕ-toℕ x)) ⟩pred (fromℕ m) ≡⟨ sym (fromℕ-pred m) ⟩fromℕ (ℕ.pred m) ≤⟨ fromℕ-mono-≤ (ℕ.pred-mono-≤ (toℕ-mono-≤ x≤y)) ⟩fromℕ (ℕ.pred n) ≡⟨ fromℕ-pred n ⟩pred (fromℕ n) ≡⟨ cong pred (fromℕ-toℕ y) ⟩pred y ∎whereopen ≤-Reasoning; m = toℕ x; n = toℕ ypred[x]<x : x ≢ zero → pred x < xpred[x]<x {x} x≢0 = begin-strictpred x <⟨ x<suc[x] (pred x) ⟩suc (pred x) ≡⟨ suc-pred x≢0 ⟩x ∎where open ≤-Reasoningpred[x]+y≡x+pred[y] : ∀ {x y} → x ≢ 0ᵇ → y ≢ 0ᵇ → (pred x) + y ≡ x + pred ypred[x]+y≡x+pred[y] {x} {y} x≢0 y≢0 = beginpx + y ≡⟨ cong (px +_) (sym (suc-pred y≢0)) ⟩px + suc py ≡⟨ cong (px +_) (suc≗1+ py) ⟩px + (1ᵇ + py) ≡⟨ Bin+CSemigroup.x∙yz≈yx∙z px 1ᵇ py ⟩(1ᵇ + px) + py ≡⟨ cong (_+ py) (sym (suc≗1+ px)) ⟩(suc px) + py ≡⟨ cong (_+ py) (suc-pred x≢0) ⟩x + py ∎where open ≡-Reasoning; px = pred x; py = pred y-------------------------------------------------------------------------- Properties of size------------------------------------------------------------------------|x|≡0⇒x≡0 : size x ≡ 0 → x ≡ 0ᵇ|x|≡0⇒x≡0 {zero} refl = refl-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4*-+-isSemiringWithoutAnnihilatingZero = +-*-isSemiringWithoutAnnihilatingZero{-# WARNING_ON_USAGE *-+-isSemiringWithoutAnnihilatingZero"Warning: *-+-isSemiringWithoutAnnihilatingZero was deprecated in v1.4.Please use +-*-isSemiringWithoutAnnihilatingZero instead."#-}*-+-isSemiring = +-*-isSemiring{-# WARNING_ON_USAGE *-+-isSemiring"Warning: *-+-isSemiring was deprecated in v1.4.Please use +-*-isSemiring instead."#-}*-+-isCommutativeSemiring = +-*-isCommutativeSemiring{-# WARNING_ON_USAGE *-+-isCommutativeSemiring"Warning: *-+-isCommutativeSemiring was deprecated in v1.4.Please use +-*-isCommutativeSemiring instead."#-}*-+-semiring = +-*-semiring{-# WARNING_ON_USAGE *-+-semiring"Warning: *-+-semiring was deprecated in v1.4.Please use +-*-semiring instead."#-}*-+-commutativeSemiring = +-*-commutativeSemiring{-# WARNING_ON_USAGE *-+-commutativeSemiring"Warning: *-+-commutativeSemiring was deprecated in v1.4.Please use +-*-commutativeSemiring instead."#-}-- Version 2.0{- issue1858/issue1755: raw bundles have moved to `Data.X.Base` -}open Data.Nat.Binary.Base publicusing (+-rawMagma; +-0-rawMonoid; *-rawMagma; *-1-rawMonoid)
-------------------------------------------------------------------------- The Agda standard library---- Instances for binary natural numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary.Instances whereopen import Data.Nat.Binary.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceℕᵇ-≡-isDecEquivalence = isDecEquivalence _≟_
-------------------------------------------------------------------------- The Agda standard library---- Induction over _<_ for ℕᵇ.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary.Induction whereopen import Data.Nat.Binary.Baseopen import Data.Nat.Binary.Propertiesopen import Data.Nat.Base as ℕ using (ℕ)import Data.Nat.Induction as ℕopen import Induction.WellFounded as WFIimport Relation.Binary.Construct.On as On-------------------------------------------------------------------------- Re-export Acc and accopen WFI public using (Acc; acc)-------------------------------------------------------------------------- _<_ is wellFounded<-wellFounded : WellFounded _<_<-wellFounded = Subrelation.wellFounded <⇒<ℕ(On.wellFounded toℕ ℕ.<-wellFounded)
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers represented in binary.-------------------------------------------------------------------------- This module contains an alternative formulation of ℕ that is-- still reasonably computationally efficient without having to use-- built-in functions.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Binary.Base whereopen import Algebra.Bundles.Raw using (RawMagma; RawMonoid)open import Algebra.Core using (Op₂)open import Data.Bool.Base using (if_then_else_)open import Data.Nat.Base as ℕ using (ℕ)open import Data.Sum.Base using (_⊎_)open import Function.Base using (_on_)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Nullary.Negation using (¬_)-------------------------------------------------------------------------- Definitiondata ℕᵇ : Set wherezero : ℕᵇ2[1+_] : ℕᵇ → ℕᵇ -- n → 2*(1+n) = nonzero even numbers1+[2_] : ℕᵇ → ℕᵇ -- n → 1 + 2*n = odd numbers-------------------------------------------------------------------------- Ordering relationsinfix 4 _<_ _>_ _≤_ _≥_ _≮_ _≯_ _≰_ _≱_data _<_ : Rel ℕᵇ 0ℓ where0<even : ∀ {x} → zero < 2[1+ x ]0<odd : ∀ {x} → zero < 1+[2 x ]even<even : ∀ {x y} → x < y → 2[1+ x ] < 2[1+ y ]even<odd : ∀ {x y} → x < y → 2[1+ x ] < 1+[2 y ]odd<even : ∀ {x y} → x < y ⊎ x ≡ y → 1+[2 x ] < 2[1+ y ]odd<odd : ∀ {x y} → x < y → 1+[2 x ] < 1+[2 y ]-- In these constructors "even" stands for nonzero even._>_ : Rel ℕᵇ 0ℓx > y = y < x_≤_ : Rel ℕᵇ 0ℓx ≤ y = x < y ⊎ x ≡ y_≥_ : Rel ℕᵇ 0ℓx ≥ y = y ≤ x_≮_ : Rel ℕᵇ 0ℓx ≮ y = ¬ (x < y)_≯_ : Rel ℕᵇ 0ℓx ≯ y = ¬ (x > y)_≰_ : Rel ℕᵇ 0ℓx ≰ y = ¬ (x ≤ y)_≱_ : Rel ℕᵇ 0ℓx ≱ y = ¬ (x ≥ y)-------------------------------------------------------------------------- Basic operationsdouble : ℕᵇ → ℕᵇdouble zero = zerodouble 2[1+ x ] = 2[1+ 1+[2 x ] ]double 1+[2 x ] = 2[1+ (double x) ]suc : ℕᵇ → ℕᵇsuc zero = 1+[2 zero ]suc 2[1+ x ] = 1+[2 (suc x) ]suc 1+[2 x ] = 2[1+ x ]pred : ℕᵇ → ℕᵇpred zero = zeropred 2[1+ x ] = 1+[2 x ]pred 1+[2 x ] = double x-------------------------------------------------------------------------- Addition, multiplication and certain related functionsinfixl 6 _+_infixl 7 _*__+_ : Op₂ ℕᵇzero + y = yx + zero = x2[1+ x ] + 2[1+ y ] = 2[1+ suc (x + y) ]2[1+ x ] + 1+[2 y ] = suc 2[1+ (x + y) ]1+[2 x ] + 2[1+ y ] = suc 2[1+ (x + y) ]1+[2 x ] + 1+[2 y ] = suc 1+[2 (x + y) ]_*_ : Op₂ ℕᵇzero * _ = zero_ * zero = zero2[1+ x ] * 2[1+ y ] = double 2[1+ x + (y + x * y) ]2[1+ x ] * 1+[2 y ] = 2[1+ x + y * 2[1+ x ] ]1+[2 x ] * 2[1+ y ] = 2[1+ y + x * 2[1+ y ] ]1+[2 x ] * 1+[2 y ] = 1+[2 x + y * 1+[2 x ] ]-------------------------------------------------------------------------- Conversion between ℕᵇ and ℕtoℕ : ℕᵇ → ℕtoℕ zero = 0toℕ 2[1+ x ] = 2 ℕ.* (ℕ.suc (toℕ x))toℕ 1+[2 x ] = ℕ.suc (2 ℕ.* (toℕ x))fromℕ : ℕ → ℕᵇfromℕ n = helper n nmodule fromℕ wherehelper : ℕ → ℕ → ℕᵇhelper 0 _ = zerohelper (ℕ.suc n) (ℕ.suc w) =if (n ℕ.% 2 ℕ.≡ᵇ 0)then 1+[2 helper (n ℕ./ 2) w ]else 2[1+ helper (n ℕ./ 2) w ]-- Impossible casehelper _ 0 = zero-- An alternative slower definitionfromℕ' : ℕ → ℕᵇfromℕ' 0 = zerofromℕ' (ℕ.suc n) = suc (fromℕ' n)-- An alternative ordering lifted from ℕinfix 4 _<ℕ__<ℕ_ : Rel ℕᵇ 0ℓ_<ℕ_ = ℕ._<_ on toℕ-------------------------------------------------------------------------- Other functions-- Useful in some termination proofs.size : ℕᵇ → ℕsize zero = 0size 2[1+ x ] = ℕ.suc (size x)size 1+[2 x ] = ℕ.suc (size x)-------------------------------------------------------------------------- Constants0ᵇ = zero1ᵇ = suc 0ᵇ2ᵇ = suc 1ᵇ3ᵇ = suc 2ᵇ4ᵇ = suc 3ᵇ5ᵇ = suc 4ᵇ6ᵇ = suc 5ᵇ7ᵇ = suc 6ᵇ8ᵇ = suc 7ᵇ9ᵇ = suc 8ᵇ-------------------------------------------------------------------------- Raw bundles for _+_+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record{ _≈_ = _≡_; _∙_ = _+_}+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record{ _≈_ = _≡_; _∙_ = _+_; ε = 0ᵇ}-------------------------------------------------------------------------- Raw bundles for _*_*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≡_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≡_; _∙_ = _*_; ε = 1ᵇ}
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers, basic types and operations-------------------------------------------------------------------------- See README.Data.Nat for examples of how to use and reason about-- naturals.{-# OPTIONS --cubical-compatible --safe #-}module Data.Nat.Base whereopen import Algebra.Bundles.Raw using (RawMagma; RawMonoid; RawNearSemiring; RawSemiring)open import Algebra.Definitions.RawMagma using (_∣ˡ_; _,_)open import Data.Bool.Base using (Bool; true; false; T; not)open import Data.Parity.Base using (Parity; 0ℙ; 1ℙ)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Unary using (Pred)-------------------------------------------------------------------------- Typesopen import Agda.Builtin.Nat publicusing (zero; suc) renaming (Nat to ℕ)--smart constructorpattern 2+ n = suc (suc n)-------------------------------------------------------------------------- Boolean equality relationopen import Agda.Builtin.Nat publicusing () renaming (_==_ to _≡ᵇ_)-------------------------------------------------------------------------- Boolean ordering relationopen import Agda.Builtin.Nat publicusing () renaming (_<_ to _<ᵇ_)infix 4 _≤ᵇ__≤ᵇ_ : (m n : ℕ) → Boolzero ≤ᵇ n = truesuc m ≤ᵇ n = m <ᵇ n-------------------------------------------------------------------------- Standard ordering relationsinfix 4 _≤_ _<_ _≥_ _>_ _≰_ _≮_ _≱_ _≯_data _≤_ : Rel ℕ 0ℓ wherez≤n : ∀ {n} → zero ≤ ns≤s : ∀ {m n} (m≤n : m ≤ n) → suc m ≤ suc n_<_ : Rel ℕ 0ℓm < n = suc m ≤ n-- Smart constructors of _<_pattern z<s {n} = s≤s (z≤n {n})pattern s<s {m} {n} m<n = s≤s {m} {n} m<npattern sz<ss {n} = s<s (z<s {n})-- Smart destructors of _≤_, _<_s≤s⁻¹ : ∀ {m n} → suc m ≤ suc n → m ≤ ns≤s⁻¹ (s≤s m≤n) = m≤ns<s⁻¹ : ∀ {m n} → suc m < suc n → m < ns<s⁻¹ (s<s m<n) = m<n-------------------------------------------------------------------------- Other derived ordering relations_≥_ : Rel ℕ 0ℓm ≥ n = n ≤ m_>_ : Rel ℕ 0ℓm > n = n < m_≰_ : Rel ℕ 0ℓa ≰ b = ¬ a ≤ b_≮_ : Rel ℕ 0ℓa ≮ b = ¬ a < b_≱_ : Rel ℕ 0ℓa ≱ b = ¬ a ≥ b_≯_ : Rel ℕ 0ℓa ≯ b = ¬ a > b-------------------------------------------------------------------------- Simple predicates-- Defining these predicates in terms of `T` and therefore ultimately-- `⊤` and `⊥` allows Agda to automatically infer them for any natural-- of the correct form. Consequently in many circumstances this-- eliminates the need to explicitly pass a proof when the predicate-- argument is either an implicit or an instance argument. See `_/_`-- and `_%_` further down this file for examples.---- Furthermore, defining these predicates as single-field records-- (rather defining them directly as the type of their field) is-- necessary as the current version of Agda is far better at-- reconstructing meta-variable values for the record parameters.-- A predicate saying that a number is not equal to 0.record NonZero (n : ℕ) : Set wherefieldnonZero : T (not (n ≡ᵇ 0))-- InstancesinstancenonZero : ∀ {n} → NonZero (suc n)nonZero = _-- Constructors≢-nonZero : ∀ {n} → n ≢ 0 → NonZero n≢-nonZero {zero} 0≢0 = contradiction refl 0≢0≢-nonZero {suc n} n≢0 = _>-nonZero : ∀ {n} → n > 0 → NonZero n>-nonZero z<s = _-- Destructors≢-nonZero⁻¹ : ∀ n → .{{NonZero n}} → n ≢ 0≢-nonZero⁻¹ (suc n) ()>-nonZero⁻¹ : ∀ n → .{{NonZero n}} → n > 0>-nonZero⁻¹ (suc n) = z<s-- The property of being a non-zero, non-unitrecord NonTrivial (n : ℕ) : Set wherefieldnonTrivial : T (1 <ᵇ n)-- InstancesinstancenonTrivial : ∀ {n} → NonTrivial (2+ n)nonTrivial = _-- Constructorsn>1⇒nonTrivial : ∀ {n} → n > 1 → NonTrivial nn>1⇒nonTrivial sz<ss = _-- DestructorsnonTrivial⇒nonZero : ∀ n → .{{NonTrivial n}} → NonZero nnonTrivial⇒nonZero (2+ _) = _nonTrivial⇒n>1 : ∀ n → .{{NonTrivial n}} → n > 1nonTrivial⇒n>1 (2+ _) = sz<ssnonTrivial⇒≢1 : ∀ {n} → .{{NonTrivial n}} → n ≢ 1nonTrivial⇒≢1 {{()}} refl-------------------------------------------------------------------------- Raw bundlesopen import Agda.Builtin.Nat publicusing (_+_; _*_) renaming (_-_ to _∸_)+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record{ _≈_ = _≡_; _∙_ = _+_}+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record{ _≈_ = _≡_; _∙_ = _+_; ε = 0}*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record{ _≈_ = _≡_; _∙_ = _*_}*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record{ _≈_ = _≡_; _∙_ = _*_; ε = 1}+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawNearSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0}+-*-rawSemiring : RawSemiring 0ℓ 0ℓ+-*-rawSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0; 1# = 1}-------------------------------------------------------------------------- Arithmeticopen import Agda.Builtin.Natusing (div-helper; mod-helper)pred : ℕ → ℕpred n = n ∸ 1infix 8 _!infixl 7 _⊓_ _⊓′_ _/_ _%_infixl 6 _+⋎_ _⊔_ _⊔′_-- Argument-swapping addition. Used by Data.Vec._⋎_._+⋎_ : ℕ → ℕ → ℕzero +⋎ n = nsuc m +⋎ n = suc (n +⋎ m)-- Max._⊔_ : ℕ → ℕ → ℕzero ⊔ n = nsuc m ⊔ zero = suc msuc m ⊔ suc n = suc (m ⊔ n)-- Max defined in terms of primitive operations.-- This is much faster than `_⊔_` but harder to reason about. For proofs-- involving this function, convert it to `_⊔_` with `Data.Nat.Properties.⊔≡⊔‵`._⊔′_ : ℕ → ℕ → ℕm ⊔′ n with m <ᵇ n... | false = m... | true = n-- Min._⊓_ : ℕ → ℕ → ℕzero ⊓ n = zerosuc m ⊓ zero = zerosuc m ⊓ suc n = suc (m ⊓ n)-- Min defined in terms of primitive operations.-- This is much faster than `_⊓_` but harder to reason about. For proofs-- involving this function, convert it to `_⊓_` wtih `Data.Nat.properties.⊓≡⊓′`._⊓′_ : ℕ → ℕ → ℕm ⊓′ n with m <ᵇ n... | false = n... | true = m-- Parityparity : ℕ → Parityparity 0 = 0ℙparity 1 = 1ℙparity (suc (suc n)) = parity n-- Division by 2, rounded downwards.⌊_/2⌋ : ℕ → ℕ⌊ 0 /2⌋ = 0⌊ 1 /2⌋ = 0⌊ suc (suc n) /2⌋ = suc ⌊ n /2⌋-- Division by 2, rounded upwards.⌈_/2⌉ : ℕ → ℕ⌈ n /2⌉ = ⌊ suc n /2⌋-- Naïve exponentiationinfixr 8 _^__^_ : ℕ → ℕ → ℕx ^ zero = 1x ^ suc n = x * x ^ n-- Distance∣_-_∣ : ℕ → ℕ → ℕ∣ zero - y ∣ = y∣ x - zero ∣ = x∣ suc x - suc y ∣ = ∣ x - y ∣-- Distance in terms of primitive operations.-- This is much faster than `∣_-_∣` but harder to reason about.-- For proofs involving this function, convert it to `∣_-_∣` with-- `Data.Nat.Properties.∣-∣≡∣-∣′`.∣_-_∣′ : ℕ → ℕ → ℕ∣ x - y ∣′ with x <ᵇ y... | false = x ∸ y... | true = y ∸ x-- Division-- Note properties of these are in `Nat.DivMod` not `Nat.Properties`_/_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → ℕm / (suc n) = div-helper 0 n m n-- Remainder/modulus-- Note properties of these are in `Nat.DivMod` not `Nat.Properties`_%_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → ℕm % (suc n) = mod-helper 0 n m n-- Factorial_! : ℕ → ℕzero ! = 1suc n ! = suc n * n !-------------------------------------------------------------------------- Extensionally equivalent alternative definitions of _≤_/_<_ etc.-- _≤′_: this definition is more suitable for well-founded induction-- (see Data.Nat.Induction)infix 4 _≤′_ _<′_ _≥′_ _>′_data _≤′_ (m : ℕ) : ℕ → Set where≤′-refl : m ≤′ m≤′-step : ∀ {n} (m≤′n : m ≤′ n) → m ≤′ suc n_<′_ : Rel ℕ 0ℓm <′ n = suc m ≤′ n-- Smart constructors of _<′_pattern <′-base = ≤′-reflpattern <′-step {n} m<′n = ≤′-step {n} m<′n_≥′_ : Rel ℕ 0ℓm ≥′ n = n ≤′ m_>′_ : Rel ℕ 0ℓm >′ n = n <′ m-- _≤″_: this definition of _≤_ is used for proof-irrelevant ‵DivMod`-- and is a specialised instance of a general algebraic constructioninfix 4 _≤″_ _<″_ _≥″_ _>″__≤″_ : (m n : ℕ) → Set_≤″_ = _∣ˡ_ +-rawMagma_<″_ : Rel ℕ 0ℓm <″ n = suc m ≤″ n_≥″_ : Rel ℕ 0ℓm ≥″ n = n ≤″ m_>″_ : Rel ℕ 0ℓm >″ n = n <″ m-- Smart destructor of _<″_s<″s⁻¹ : ∀ {m n} → suc m <″ suc n → m <″ ns<″s⁻¹ (k , refl) = k , refl-- _≤‴_: this definition is useful for induction with an upper bound.data _≤‴_ : ℕ → ℕ → Set where≤‴-refl : ∀{m} → m ≤‴ m≤‴-step : ∀{m n} → suc m ≤‴ n → m ≤‴ ninfix 4 _≤‴_ _<‴_ _≥‴_ _>‴__<‴_ : Rel ℕ 0ℓm <‴ n = suc m ≤‴ n_≥‴_ : Rel ℕ 0ℓm ≥‴ n = n ≤‴ m_>‴_ : Rel ℕ 0ℓm >‴ n = n <‴ m-------------------------------------------------------------------------- A comparison view. Taken from "View from the left"-- (McBride/McKinna); details may differ.data Ordering : Rel ℕ 0ℓ whereless : ∀ m k → Ordering m (suc (m + k))equal : ∀ m → Ordering m mgreater : ∀ m k → Ordering (suc (m + k)) mcompare : ∀ m n → Ordering m ncompare zero zero = equal zerocompare (suc m) zero = greater zero mcompare zero (suc n) = less zero ncompare (suc m) (suc n) with compare m n... | less m k = less (suc m) k... | equal m = equal (suc m)... | greater n k = greater (suc n) k-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.1-- Smart constructors of _≤″_ and _<″_pattern less-than-or-equal {k} eq = k , eq{-# WARNING_ON_USAGE less-than-or-equal"Warning: less-than-or-equal was deprecated in v2.1. Please match directly on proofs of ≤″ using constructor Algebra.Definitions.RawMagma._∣ˡ_._,_ instead. "#-}pattern ≤″-offset k = k , refl{-# WARNING_ON_USAGE ≤″-offset"Warning: ≤″-offset was deprecated in v2.1. Please match directly on proofs of ≤″ using pattern (_, refl) from Algebra.Definitions.RawMagma._∣ˡ_ instead. "#-}pattern <″-offset k = k , refl{-# WARNING_ON_USAGE <″-offset"Warning: <″-offset was deprecated in v2.1. Please match directly on proofs of ≤″ using pattern (_, refl) from Algebra.Definitions.RawMagma._∣ˡ_ instead. "#-}-- Smart destructors of _<″_s≤″s⁻¹ : ∀ {m n} → suc m ≤″ suc n → m ≤″ ns≤″s⁻¹ (k , refl) = k , refl{-# WARNING_ON_USAGE s≤″s⁻¹"Warning: s≤″s⁻¹ was deprecated in v2.1. Please match directly on proofs of ≤″ using pattern (_, refl) from Algebra.Definitions.RawMagma._∣ˡ_ instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- The Maybe type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe whereopen import Data.Empty using (⊥)open import Data.Unit.Base using (⊤)open import Data.Bool.Base using (T)open import Data.Maybe.Relation.Unary.All using (All)open import Data.Maybe.Relation.Unary.Any using (Any; just)open import Level using (Level)privatevariablea : LevelA : Set a-------------------------------------------------------------------------- The base type and some operationsopen import Data.Maybe.Base public-------------------------------------------------------------------------- Using Any and All to define Is-just and Is-nothingIs-just : Maybe A → Set _Is-just = Any (λ _ → ⊤)Is-nothing : Maybe A → Set _Is-nothing = All (λ _ → ⊥)to-witness : ∀ {m : Maybe A} → Is-just m → Ato-witness (just {x = p} _) = pto-witness-T : ∀ (m : Maybe A) → T (is-just m) → Ato-witness-T (just p) _ = p
-------------------------------------------------------------------------- The Agda standard library---- Maybes where one of the elements satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Relation.Unary.Any whereopen import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Product.Base as Product using (∃; _,_; -,_)open import Function.Base using (id)open import Function.Bundles using (_⇔_; mk⇔)open import Levelopen import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)open import Relation.Unaryopen import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitiondata Any {a p} {A : Set a} (P : Pred A p) : Pred (Maybe A) (a ⊔ p) wherejust : ∀ {x} → P x → Any P (just x)-------------------------------------------------------------------------- Basic operationsmodule _ {a p} {A : Set a} {P : Pred A p} wheredrop-just : ∀ {x} → Any P (just x) → P xdrop-just (just px) = pxjust-equivalence : ∀ {x} → P x ⇔ Any P (just x)just-equivalence = mk⇔ just drop-justmap : ∀ {q} {Q : Pred A q} → P ⊆ Q → Any P ⊆ Any Qmap f (just px) = just (f px)satisfied : ∀ {x} → Any P x → ∃ Psatisfied (just p) = -, p-------------------------------------------------------------------------- (un/)zip(/With)module _ {a p q r} {A : Set a} {P : Pred A p} {Q : Pred A q} {R : Pred A r} wherezipWith : P ∩ Q ⊆ R → Any P ∩ Any Q ⊆ Any RzipWith f (just px , just qx) = just (f (px , qx))unzipWith : P ⊆ Q ∩ R → Any P ⊆ Any Q ∩ Any RunzipWith f (just px) = Product.map just just (f px)module _ {a p q} {A : Set a} {P : Pred A p} {Q : Pred A q} wherezip : Any P ∩ Any Q ⊆ Any (P ∩ Q)zip = zipWith idunzip : Any (P ∩ Q) ⊆ Any P ∩ Any Qunzip = unzipWith id-------------------------------------------------------------------------- Seeing Any as a predicate transformermodule _ {a p} {A : Set a} {P : Pred A p} wheredec : Decidable P → Decidable (Any P)dec P-dec nothing = no λ ()dec P-dec (just x) = Dec.map just-equivalence (P-dec x)irrelevant : Irrelevant P → Irrelevant (Any P)irrelevant P-irrelevant (just p) (just q) = cong just (P-irrelevant p q)satisfiable : Satisfiable P → Satisfiable (Any P)satisfiable P-satisfiable = Product.map just just P-satisfiable
-------------------------------------------------------------------------- The Agda standard library---- Maybes where all the elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Relation.Unary.All whereopen import Effect.Applicativeopen import Effect.Monadopen import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.Any using (Any; just)open import Data.Product.Base as Product using (_,_)open import Function.Base using (id; _∘′_)open import Function.Bundles using (_⇔_; mk⇔)open import Levelopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Unaryopen import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitiondata All {a p} {A : Set a} (P : Pred A p) : Pred (Maybe A) (a ⊔ p) wherejust : ∀ {x} → P x → All P (just x)nothing : All P nothing-------------------------------------------------------------------------- Basic operationsmodule _ {a p} {A : Set a} {P : Pred A p} wheredrop-just : ∀ {x} → All P (just x) → P xdrop-just (just px) = pxjust-equivalence : ∀ {x} → P x ⇔ All P (just x)just-equivalence = mk⇔ just drop-justmap : ∀ {q} {Q : Pred A q} → P ⊆ Q → All P ⊆ All Qmap f (just px) = just (f px)map f nothing = nothingfromAny : Any P ⊆ All PfromAny (just px) = just px-------------------------------------------------------------------------- (un/)zip(/With)module _ {a p q r} {A : Set a} {P : Pred A p} {Q : Pred A q} {R : Pred A r} wherezipWith : P ∩ Q ⊆ R → All P ∩ All Q ⊆ All RzipWith f (just px , just qx) = just (f (px , qx))zipWith f (nothing , nothing) = nothingunzipWith : P ⊆ Q ∩ R → All P ⊆ All Q ∩ All RunzipWith f (just px) = Product.map just just (f px)unzipWith f nothing = nothing , nothingmodule _ {a p q} {A : Set a} {P : Pred A p} {Q : Pred A q} wherezip : All P ∩ All Q ⊆ All (P ∩ Q)zip = zipWith idunzip : All (P ∩ Q) ⊆ All P ∩ All Qunzip = unzipWith id-------------------------------------------------------------------------- Traversable-like functionsmodule _ {a f} p {A : Set a} {P : Pred A (a ⊔ p)} {F}(App : RawApplicative {a ⊔ p} {f} F) whereopen RawApplicative AppsequenceA : All (F ∘′ P) ⊆ F ∘′ All PsequenceA nothing = pure nothingsequenceA (just px) = just <$> pxmapA : ∀ {q} {Q : Pred A q} → (Q ⊆ F ∘′ P) → All Q ⊆ (F ∘′ All P)mapA f = sequenceA ∘′ map fforA : ∀ {q} {Q : Pred A q} {xs} → All Q xs → (Q ⊆ F ∘′ P) → F (All P xs)forA qxs f = mapA f qxsmodule _ {a f} p {A : Set a} {P : Pred A (a ⊔ p)} {M}(Mon : RawMonad {a ⊔ p} {f} M) whereprivate App = RawMonad.rawApplicative MonsequenceM : All (M ∘′ P) ⊆ M ∘′ All PsequenceM = sequenceA p AppmapM : ∀ {q} {Q : Pred A q} → (Q ⊆ M ∘′ P) → All Q ⊆ (M ∘′ All P)mapM = mapA p AppforM : ∀ {q} {Q : Pred A q} {xs} → All Q xs → (Q ⊆ M ∘′ P) → M (All P xs)forM = forA p App-------------------------------------------------------------------------- Seeing All as a predicate transformermodule _ {a p} {A : Set a} {P : Pred A p} wheredec : Decidable P → Decidable (All P)dec P-dec nothing = yes nothingdec P-dec (just x) = Dec.map just-equivalence (P-dec x)universal : Universal P → Universal (All P)universal P-universal (just x) = just (P-universal x)universal P-universal nothing = nothingirrelevant : Irrelevant P → Irrelevant (All P)irrelevant P-irrelevant (just p) (just q) = cong just (P-irrelevant p q)irrelevant P-irrelevant nothing nothing = reflsatisfiable : Satisfiable (All P)satisfiable = nothing , nothing
-------------------------------------------------------------------------- The Agda standard library---- Properties related to All------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Relation.Unary.All.Properties whereopen import Data.Maybe.Baseopen import Data.Maybe.Relation.Unary.All as Allusing (All; nothing; just)open import Data.Maybe.Relation.Binary.Connectedopen import Data.Product.Base using (_×_; _,_)open import Function.Base using (_∘_)open import Levelopen import Relation.Unaryopen import Relation.Binary.Coreprivatevariablea b p q ℓ : LevelA : Set aB : Set bP : Pred A pQ : Pred B q-------------------------------------------------------------------------- Relationship with other combinators------------------------------------------------------------------------All⇒Connectedˡ : ∀ {R : Rel A ℓ} {x y} →All (R x) y → Connected R (just x) yAll⇒Connectedˡ (just x) = just xAll⇒Connectedˡ nothing = just-nothingAll⇒Connectedʳ : ∀ {R : Rel A ℓ} {x y} →All (λ v → R v y) x → Connected R x (just y)All⇒Connectedʳ (just x) = just xAll⇒Connectedʳ nothing = nothing-just-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for maybe operations-------------------------------------------------------------------------- mapmap⁺ : ∀ {f : A → B} {mx} → All (P ∘ f) mx → All P (map f mx)map⁺ (just p) = just pmap⁺ nothing = nothingmap⁻ : ∀ {f : A → B} {mx} → All P (map f mx) → All (P ∘ f) mxmap⁻ {mx = just x} (just px) = just pxmap⁻ {mx = nothing} nothing = nothing-- A variant of All.map.gmap : ∀ {f : A → B} → P ⊆ Q ∘ f → All P ⊆ All Q ∘ map fgmap g = map⁺ ∘ All.map g-------------------------------------------------------------------------- _<∣>_<∣>⁺ : ∀ {mx my} → All P mx → All P my → All P (mx <∣> my)<∣>⁺ (just px) pmy = just px<∣>⁺ nothing pmy = pmy<∣>⁻ : ∀ mx {my} → All P (mx <∣> my) → All P mx<∣>⁻ (just x) pmxy = pmxy<∣>⁻ nothing pmxy = nothing
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of relations to maybes------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Relation.Binary.Pointwise whereopen import Levelopen import Data.Product.Base using (∃; _×_; -,_; _,_)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.Any using (Any; just)open import Function.Bundles using (_⇔_; mk⇔)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid; DecSetoid)open import Relation.Binary.Definitions using (Reflexive; Sym; Trans; Decidable)open import Relation.Binary.Structures using (IsEquivalence; IsDecEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullaryopen import Relation.Unary using (_⊆_)import Relation.Nullary.Decidable as Dec-------------------------------------------------------------------------- Definitiondata Pointwise{a b ℓ} {A : Set a} {B : Set b}(R : REL A B ℓ) : REL (Maybe A) (Maybe B) (a ⊔ b ⊔ ℓ) wherejust : ∀ {x y} → R x y → Pointwise R (just x) (just y)nothing : Pointwise R nothing nothing-------------------------------------------------------------------------- Propertiesmodule _ {a b ℓ} {A : Set a} {B : Set b} {R : REL A B ℓ} wheredrop-just : ∀ {x y} → Pointwise R (just x) (just y) → R x ydrop-just (just p) = pjust-equivalence : ∀ {x y} → R x y ⇔ Pointwise R (just x) (just y)just-equivalence = mk⇔ just drop-justnothing-inv : ∀ {x} → Pointwise R nothing x → x ≡ nothingnothing-inv nothing = ≡.refljust-inv : ∀ {x y} → Pointwise R (just x) y → ∃ λ z → y ≡ just z × R x zjust-inv (just r) = -, ≡.refl , r-------------------------------------------------------------------------- Relational propertiesmodule _ {a r} {A : Set a} {R : Rel A r} whererefl : Reflexive R → Reflexive (Pointwise R)refl R-refl {just _} = just R-reflrefl R-refl {nothing} = nothingreflexive : _≡_ ⇒ R → _≡_ ⇒ Pointwise Rreflexive reflexive ≡.refl = refl (reflexive ≡.refl)module _ {a b r₁ r₂} {A : Set a} {B : Set b}{R : REL A B r₁} {S : REL B A r₂} wheresym : Sym R S → Sym (Pointwise R) (Pointwise S)sym R-sym (just p) = just (R-sym p)sym R-sym nothing = nothingmodule _ {a b c r₁ r₂ r₃} {A : Set a} {B : Set b} {C : Set c}{R : REL A B r₁} {S : REL B C r₂} {T : REL A C r₃} wheretrans : Trans R S T → Trans (Pointwise R) (Pointwise S) (Pointwise T)trans R-trans (just p) (just q) = just (R-trans p q)trans R-trans nothing nothing = nothingmodule _ {a r} {A : Set a} {R : Rel A r} wheredec : Decidable R → Decidable (Pointwise R)dec R-dec (just x) (just y) = Dec.map just-equivalence (R-dec x y)dec R-dec (just x) nothing = no (λ ())dec R-dec nothing (just y) = no (λ ())dec R-dec nothing nothing = yes nothingisEquivalence : IsEquivalence R → IsEquivalence (Pointwise R)isEquivalence R-isEquivalence = record{ refl = refl R.refl; sym = sym R.sym; trans = trans R.trans} where module R = IsEquivalence R-isEquivalenceisDecEquivalence : IsDecEquivalence R → IsDecEquivalence (Pointwise R)isDecEquivalence R-isDecEquivalence = record{ isEquivalence = isEquivalence R.isEquivalence; _≟_ = dec R._≟_} where module R = IsDecEquivalence R-isDecEquivalencepointwise⊆any : ∀ {x} → Pointwise R (just x) ⊆ Any (R x)pointwise⊆any (just Rxy) = just Rxymodule _ {c ℓ} wheresetoid : Setoid c ℓ → Setoid c (c ⊔ ℓ)setoid S = record{ isEquivalence = isEquivalence S.isEquivalence} where module S = Setoid SdecSetoid : DecSetoid c ℓ → DecSetoid c (c ⊔ ℓ)decSetoid S = record{ isDecEquivalence = isDecEquivalence S.isDecEquivalence} where module S = DecSetoid S
-------------------------------------------------------------------------- The Agda standard library---- Lifting a relation such that `nothing` is also related to `just`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Relation.Binary.Connected whereopen import Levelopen import Data.Maybe.Base using (Maybe; just; nothing)open import Function.Bundles using (_⇔_; mk⇔)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Definitions using (Reflexive; Sym; Decidable)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullaryimport Relation.Nullary.Decidable as Decprivatevariablea b ℓ : LevelA : Set aB : Set bR S T : REL A B ℓx y : A-------------------------------------------------------------------------- Definitiondata Connected {A : Set a} {B : Set b} (R : REL A B ℓ): REL (Maybe A) (Maybe B) (a ⊔ b ⊔ ℓ) wherejust : R x y → Connected R (just x) (just y)just-nothing : Connected R (just x) nothingnothing-just : Connected R nothing (just y)nothing : Connected R nothing nothing-------------------------------------------------------------------------- Propertiesdrop-just : Connected R (just x) (just y) → R x ydrop-just (just p) = pjust-equivalence : R x y ⇔ Connected R (just x) (just y)just-equivalence = mk⇔ just drop-just-------------------------------------------------------------------------- Relational propertiesrefl : Reflexive R → Reflexive (Connected R)refl R-refl {just _} = just R-reflrefl R-refl {nothing} = nothingreflexive : _≡_ ⇒ R → _≡_ ⇒ Connected Rreflexive reflexive ≡.refl = refl (reflexive ≡.refl)sym : Sym R S → Sym (Connected R) (Connected S)sym R-sym (just p) = just (R-sym p)sym R-sym nothing-just = just-nothingsym R-sym just-nothing = nothing-justsym R-sym nothing = nothingconnected? : Decidable R → Decidable (Connected R)connected? R? (just x) (just y) = Dec.map just-equivalence (R? x y)connected? R? (just x) nothing = yes just-nothingconnected? R? nothing (just y) = yes nothing-justconnected? R? nothing nothing = yes nothing
-------------------------------------------------------------------------- The Agda standard library---- Maybe-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Properties whereopen import Algebra.Bundles using (Semigroup; Monoid)import Algebra.Structures as Structuresimport Algebra.Definitions as Definitionsopen import Data.Maybe.Base using (Maybe; just; nothing; map; _<∣>_;maybe; maybe′)open import Data.Maybe.Relation.Unary.All using (All; just; nothing)open import Data.Product.Base using (_,_)open import Function.Base using (_∋_; id; _∘_; _∘′_)open import Function.Definitions using (Injective)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; _≗_)open import Relation.Binary.PropositionalEquality.Propertiesusing (isEquivalence)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Decidable using (map′)privatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Equalityjust-injective : ∀ {x y} → (Maybe A ∋ just x) ≡ just y → x ≡ yjust-injective refl = refl≡-dec : DecidableEquality A → DecidableEquality (Maybe A)≡-dec _≟_ nothing nothing = yes refl≡-dec _≟_ (just x) nothing = no λ()≡-dec _≟_ nothing (just y) = no λ()≡-dec _≟_ (just x) (just y) = map′ (cong just) just-injective (x ≟ y)-------------------------------------------------------------------------- mapmap-id : map id ≗ id {A = Maybe A}map-id (just x) = reflmap-id nothing = reflmap-id-local : ∀ {f : A → A} {mx} → All (λ x → f x ≡ x) mx → map f mx ≡ mxmap-id-local (just eq) = cong just eqmap-id-local nothing = reflmap-<∣> : ∀ (f : A → B) mx my →map f (mx <∣> my) ≡ map f mx <∣> map f mymap-<∣> f (just x) my = reflmap-<∣> f nothing my = reflmap-cong : {f g : A → B} → f ≗ g → map f ≗ map gmap-cong f≗g (just x) = cong just (f≗g x)map-cong f≗g nothing = reflmap-cong-local : ∀ {f g : A → B} {mx} →All (λ x → f x ≡ g x) mx → map f mx ≡ map g mxmap-cong-local (just eq) = cong just eqmap-cong-local nothing = reflmap-injective : ∀ {f : A → B} → Injective _≡_ _≡_ f → Injective _≡_ _≡_ (map f)map-injective f-inj {nothing} {nothing} p = reflmap-injective f-inj {just x} {just y} p = cong just (f-inj (just-injective p))map-∘ : {g : B → C} {f : A → B} → map (g ∘ f) ≗ map g ∘ map fmap-∘ (just x) = reflmap-∘ nothing = reflmap-nothing : ∀ {f : A → B} {ma} → ma ≡ nothing → map f ma ≡ nothingmap-nothing refl = reflmap-just : ∀ {f : A → B} {ma a} → ma ≡ just a → map f ma ≡ just (f a)map-just refl = refl-------------------------------------------------------------------------- maybemaybe-map : ∀ {C : Maybe B → Set c}(j : (x : B) → C (just x)) (n : C nothing) (f : A → B) ma →maybe {B = C} j n (map f ma) ≡ maybe {B = C ∘ map f} (j ∘ f) n mamaybe-map j n f (just x) = reflmaybe-map j n f nothing = reflmaybe′-map : ∀ j (n : C) (f : A → B) ma →maybe′ j n (map f ma) ≡ maybe′ (j ∘′ f) n mamaybe′-map = maybe-map-------------------------------------------------------------------------- _<∣>_module _ {A : Set a} whereopen Definitions {A = Maybe A} _≡_<∣>-assoc : Associative _<∣>_<∣>-assoc (just x) y z = refl<∣>-assoc nothing y z = refl<∣>-identityˡ : LeftIdentity nothing _<∣>_<∣>-identityˡ (just x) = refl<∣>-identityˡ nothing = refl<∣>-identityʳ : RightIdentity nothing _<∣>_<∣>-identityʳ (just x) = refl<∣>-identityʳ nothing = refl<∣>-identity : Identity nothing _<∣>_<∣>-identity = <∣>-identityˡ , <∣>-identityʳ<∣>-idem : Idempotent _<∣>_<∣>-idem (just x) = refl<∣>-idem nothing = reflmodule _ (A : Set a) whereopen Structures {A = Maybe A} _≡_<∣>-isMagma : IsMagma _<∣>_<∣>-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _<∣>_}<∣>-isSemigroup : IsSemigroup _<∣>_<∣>-isSemigroup = record{ isMagma = <∣>-isMagma; assoc = <∣>-assoc}<∣>-isMonoid : IsMonoid _<∣>_ nothing<∣>-isMonoid = record{ isSemigroup = <∣>-isSemigroup; identity = <∣>-identity}<∣>-semigroup : Semigroup a a<∣>-semigroup = record{ isSemigroup = <∣>-isSemigroup}<∣>-monoid : Monoid a a<∣>-monoid = record{ isMonoid = <∣>-isMonoid}-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-id₂ = map-id-local{-# WARNING_ON_USAGE map-id₂"Warning: map-id₂ was deprecated in v2.0.Please use map-id-local instead."#-}map-cong₂ = map-cong-local{-# WARNING_ON_USAGE map-id₂"Warning: map-cong₂ was deprecated in v2.0.Please use map-cong-local instead."#-}map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.0.Please use map-∘ instead."#-}map-<∣>-commute = map-<∣>{-# WARNING_ON_USAGE map-<∣>-commute"Warning: map-<∣>-commute was deprecated in v2.0.Please use map-<∣> instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for Maybe------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Instances whereopen import Data.Maybe.Effectfulimport Data.Maybe.Effectful.Transformer as Transinstance-- MaybemaybeFunctor = functormaybeApplicative = applicativemaybeApplicativeZero = applicativeZeromaybeAlternative = alternativemaybeMonad = monadmaybeMonadZero = monadZeromaybeMonadPlus = monadPlus-- MaybeTmaybeTFunctor = λ {f} {g} {M} {{inst}} → Trans.functor {f} {g} {M} instmaybeTApplicative = λ {f} {g} {M} {{inst}} → Trans.applicative {f} {g} {M} instmaybeTMonad = λ {f} {g} {M} {{inst}} → Trans.monad {f} {g} {M} instmaybeTMonadT = λ {f} {g} {M} {{inst}} → Trans.monadT {f} {g} {M} inst
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Maybe------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Effectful whereopen import Levelopen import Data.Maybe.Baseopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Baseprivatevariablea b f g m n : LevelA : Set aB : Set b-------------------------------------------------------------------------- Maybe applicative functorfunctor : RawFunctor {f} Maybefunctor = record{ _<$>_ = map}applicative : RawApplicative {f} Maybeapplicative = record{ rawFunctor = functor; pure = just; _<*>_ = maybe map (const nothing)}empty : RawEmpty {f} Maybeempty = record { empty = nothing }choice : RawChoice {f} Maybechoice = record { _<|>_ = _<∣>_ }applicativeZero : RawApplicativeZero {f} MaybeapplicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}alternative : RawAlternative {f} Maybealternative = record{ rawApplicativeZero = applicativeZero; rawChoice = choice}-------------------------------------------------------------------------- Maybe monadmonad : RawMonad {f} Maybemonad = record{ rawApplicative = applicative; _>>=_ = _>>=_}join : Maybe (Maybe A) → Maybe Ajoin = Join.join monadmonadZero : RawMonadZero {f} MaybemonadZero = record{ rawMonad = monad; rawEmpty = empty}monadPlus : RawMonadPlus {f} MaybemonadPlus {f} = record{ rawMonadZero = monadZero; rawChoice = choice}module TraversableA {F} (App : RawApplicative {f} {g} F) whereopen RawApplicative AppsequenceA : Maybe (F A) → F (Maybe A)sequenceA nothing = pure nothingsequenceA (just x) = just <$> xmapA : (A → F B) → Maybe A → F (Maybe B)mapA f = sequenceA ∘ map fforA : Maybe A → (A → F B) → F (Maybe B)forA = flip mapAmodule TraversableM {M} (Mon : RawMonad {m} {n} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Maybe------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Effectful.Transformer whereopen import Levelopen import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe)open import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadimport Data.Maybe.Effectful as Maybeopen import Function.Baseprivatevariablef g : LevelM : Set f → Set g-------------------------------------------------------------------------- Maybe monad transformerrecord MaybeT (M : Set f → Set g) (A : Set f) : Set g whereconstructor mkMaybeTfield runMaybeT : M (Maybe A)open MaybeT public-------------------------------------------------------------------------- Structurefunctor : RawFunctor M → RawFunctor {f} (MaybeT M)functor M = record{ _<$>_ = λ f → mkMaybeT ∘′ (Maybe.map f <$>_) ∘′ runMaybeT} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative {f} (MaybeT M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkMaybeT ∘′ pure ∘′ just; _<*>_ = λ mf ma → mkMaybeT (Maybe.ap <$> runMaybeT mf <*> runMaybeT ma)} where open RawApplicative Mmonad : RawMonad M → RawMonad {f} (MaybeT M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ ma f → mkMaybeT $ doa ← runMaybeT mamaybe (runMaybeT ∘′ f) (pure nothing) a} where open RawMonad MmonadT : RawMonadT {f} {g} MaybeTmonadT {M = F} M = record{ lift = mkMaybeT ∘′ (just <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Maybe.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Categorical whereopen import Data.Maybe.Effectful public{-# WARNING_ON_IMPORT"Data.Maybe.Categorical was deprecated in v2.0.Use Data.Maybe.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.Maybe.Effectful.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Categorical.Transformer whereopen import Data.Maybe.Effectful.Transformer public{-# WARNING_ON_IMPORT"Data.Maybe.Categorical.Transformer was deprecated in v2.0.Use Data.Maybe.Effectful.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The Maybe type and some operations-------------------------------------------------------------------------- The definitions in this file are reexported by Data.Maybe.{-# OPTIONS --cubical-compatible --safe #-}module Data.Maybe.Base whereopen import Level using (Level; Lift)open import Data.Bool.Base using (Bool; true; false; not)open import Data.Unit.Base using (⊤)open import Data.These.Base using (These; this; that; these)open import Data.Product.Base as Prod using (_×_; _,_)open import Function.Base using (_∘_; id; const)import Relation.Nullary.Decidable.Core as Decprivatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitionopen import Agda.Builtin.Maybe publicusing (Maybe; just; nothing)-------------------------------------------------------------------------- Some operationsboolToMaybe : Bool → Maybe ⊤boolToMaybe true = just _boolToMaybe false = nothingis-just : Maybe A → Boolis-just (just _) = trueis-just nothing = falseis-nothing : Maybe A → Boolis-nothing = not ∘ is-just-- A dependent eliminator.maybe : ∀ {A : Set a} {B : Maybe A → Set b} →((x : A) → B (just x)) → B nothing → (x : Maybe A) → B xmaybe j n (just x) = j xmaybe j n nothing = n-- A non-dependent eliminator.maybe′ : (A → B) → B → Maybe A → Bmaybe′ = maybe-- A defaulting mechanismfromMaybe : A → Maybe A → AfromMaybe = maybe′ id-- A safe variant of "fromJust". If the value is nothing, then the-- return type is the unit type.module _ {a} {A : Set a} whereFrom-just : Maybe A → Set aFrom-just (just _) = AFrom-just nothing = Lift a ⊤from-just : (x : Maybe A) → From-just xfrom-just (just x) = xfrom-just nothing = _-- Functoriality: mapmap : (A → B) → Maybe A → Maybe Bmap f = maybe (just ∘ f) nothing-- Applicative: apap : Maybe (A → B) → Maybe A → Maybe Bap nothing = const nothingap (just f) = map f-- Monad: bindinfixl 1 _>>=__>>=_ : Maybe A → (A → Maybe B) → Maybe Bnothing >>= f = nothingjust a >>= f = f a-- Alternative: <∣>infixr 6 _<∣>__<∣>_ : Maybe A → Maybe A → Maybe Ajust x <∣> my = just xnothing <∣> my = my-- Just when the boolean is truewhen : Bool → A → Maybe Awhen b c = map (const c) (boolToMaybe b)-------------------------------------------------------------------------- Aligning and zippingalignWith : (These A B → C) → Maybe A → Maybe B → Maybe CalignWith f (just a) (just b) = just (f (these a b))alignWith f (just a) nothing = just (f (this a))alignWith f nothing (just b) = just (f (that b))alignWith f nothing nothing = nothingzipWith : (A → B → C) → Maybe A → Maybe B → Maybe CzipWith f (just a) (just b) = just (f a b)zipWith _ _ _ = nothingalign : Maybe A → Maybe B → Maybe (These A B)align = alignWith idzip : Maybe A → Maybe B → Maybe (A × B)zip = zipWith _,_-------------------------------------------------------------------------- Injections.thisM : A → Maybe B → These A BthisM a = maybe′ (these a) (this a)thatM : Maybe A → B → These A BthatM = maybe′ these that-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.1-- decToMaybeopen Dec using (decToMaybe) public
-------------------------------------------------------------------------- The Agda standard library---- Lists-------------------------------------------------------------------------- See README.Data.List for examples of how to use and reason about-- lists.{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for deprecated scansmodule Data.List where-------------------------------------------------------------------------- Types and basic operationsopen import Data.List.Base publichiding (scanr; scanl)open import Data.List.Scans.Base publicusing (scanr; scanl)
-------------------------------------------------------------------------- The Agda standard library---- List Zippers, basic types and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Zipper whereopen import Data.Nat.Baseopen import Data.Maybe.Base as Maybe using (Maybe ; just ; nothing)open import Data.List.Base as List using (List ; [] ; _∷_)open import Function.Base using (_on_; flip)-- Definition-------------------------------------------------------------------------- A List Zipper represents a List together with a particular sub-List-- in focus. The user can attempt to move the focus left or right, with-- a risk of failure if one has already reached the corresponding end.-- To make these operations efficient, the `context` the sub List in-- focus lives in is stored *backwards*. This is made formal by `toList`-- which returns the List a Zipper represents.record Zipper {a} (A : Set a) : Set a whereconstructor mkZipperfield context : List Avalue : List AtoList : List AtoList = List.reverse context List.++ valueopen Zipper public-- Embedding Lists as Zippers without any contextfromList : ∀ {a} {A : Set a} → List A → Zipper AfromList = mkZipper []-- Fundamental operations of a Zipper: Moving around------------------------------------------------------------------------module _ {a} {A : Set a} whereleft : Zipper A → Maybe (Zipper A)left (mkZipper [] val) = nothingleft (mkZipper (x ∷ ctx) val) = just (mkZipper ctx (x ∷ val))right : Zipper A → Maybe (Zipper A)right (mkZipper ctx []) = nothingright (mkZipper ctx (x ∷ val)) = just (mkZipper (x ∷ ctx) val)-- Focus-respecting operations------------------------------------------------------------------------module _ {a} {A : Set a} wherereverse : Zipper A → Zipper Areverse (mkZipper ctx val) = mkZipper val ctx-- If we think of a List [x₁⋯xₘ] split into a List [xₙ₊₁⋯xₘ] in focus-- of another list [x₁⋯xₙ] then there are 4 places (marked {k} here) in-- which we can insert new values: [{1}x₁⋯xₙ{2}][{3}xₙ₊₁⋯xₘ{4}]-- The following 4 functions implement these 4 insertions.-- `xs ˢ++ zp` inserts `xs` on the `s` side of the context of the Zipper `zp`-- `zp ++ˢ xs` insert `xs` on the `s` side of the value in focus of the Zipper `zp`infixr 5 _ˡ++_ _ʳ++_infixl 5 _++ˡ_ _++ʳ_-- {1}_ˡ++_ : List A → Zipper A → Zipper Axs ˡ++ mkZipper ctx val = mkZipper (ctx List.++ List.reverse xs) val-- {2}_ʳ++_ : List A → Zipper A → Zipper Axs ʳ++ mkZipper ctx val = mkZipper (List.reverse xs List.++ ctx) val-- {3}_++ˡ_ : Zipper A → List A → Zipper AmkZipper ctx val ++ˡ xs = mkZipper ctx (xs List.++ val)-- {4}_++ʳ_ : Zipper A → List A → Zipper AmkZipper ctx val ++ʳ xs = mkZipper ctx (val List.++ xs)-- List-like operations------------------------------------------------------------------------module _ {a} {A : Set a} wherelength : Zipper A → ℕlength (mkZipper ctx val) = List.length ctx + List.length valmodule _ {a b} {A : Set a} {B : Set b} wheremap : (A → B) → Zipper A → Zipper Bmap f (mkZipper ctx val) = (mkZipper on List.map f) ctx valfoldr : (A → B → B) → B → Zipper A → Bfoldr c n (mkZipper ctx val) = List.foldl (flip c) (List.foldr c n val) ctx-- Generating all the possible foci of a list------------------------------------------------------------------------module _ {a} {A : Set a} whereallFociIn : List A → List A → List (Zipper A)allFociIn ctx [] = List.[ mkZipper ctx [] ]allFociIn ctx xxs@(x ∷ xs) = mkZipper ctx xxs ∷ allFociIn (x ∷ ctx) xsallFoci : List A → List (Zipper A)allFoci = allFociIn []
-------------------------------------------------------------------------- The Agda standard library---- List Zipper-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Zipper.Properties whereopen import Data.List.Base as List using (List ; [] ; _∷_)open import Data.List.Propertiesopen import Data.List.Zipperusing (Zipper; toList; left; right; mkZipper; reverse; _ˡ++_; _ʳ++_;_++ˡ_; _++ʳ_; map; foldr)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.All using (All; just; nothing)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningopen import Function.Base using (_on_; _$′_; _$_; flip)-- Invariant: Zipper represents a given list------------------------------------------------------------------------module _ {a} {A : Set a} where-- Stability under moving left or righttoList-left-identity : (zp : Zipper A) → All ((_≡_ on toList) zp) (left zp)toList-left-identity (mkZipper [] val) = nothingtoList-left-identity (mkZipper (x ∷ ctx) val) = just $′ beginList.reverse (x ∷ ctx) List.++ val≡⟨ cong (List._++ val) (unfold-reverse x ctx) ⟩(List.reverse ctx List.++ List.[ x ]) List.++ val≡⟨ ++-assoc (List.reverse ctx) List.[ x ] val ⟩toList (mkZipper ctx (x ∷ val))∎toList-right-identity : (zp : Zipper A) → All ((_≡_ on toList) zp) (right zp)toList-right-identity (mkZipper ctx []) = nothingtoList-right-identity (mkZipper ctx (x ∷ val)) = just $′ beginList.reverse ctx List.++ x ∷ val≡⟨ sym (++-assoc (List.reverse ctx) List.[ x ] val) ⟩(List.reverse ctx List.++ List.[ x ]) List.++ val≡⟨ cong (List._++ val) (sym (unfold-reverse x ctx)) ⟩List.reverse (x ∷ ctx) List.++ val∎-- Applying reverse does correspond to reversing the represented listtoList-reverse : (zp : Zipper A) → toList (reverse zp) ≡ List.reverse (toList zp)toList-reverse (mkZipper ctx val) = beginList.reverse val List.++ ctx≡⟨ cong (List.reverse val List.++_) (sym (reverse-involutive ctx)) ⟩List.reverse val List.++ List.reverse (List.reverse ctx)≡⟨ sym (reverse-++ (List.reverse ctx) val) ⟩List.reverse (List.reverse ctx List.++ val)∎-- Properties of the insertion functions-------------------------------------------------------------------------- _ˡ++_ propertiestoList-ˡ++ : ∀ xs (zp : Zipper A) → toList (xs ˡ++ zp) ≡ xs List.++ toList zptoList-ˡ++ xs (mkZipper ctx val) = beginList.reverse (ctx List.++ List.reverse xs) List.++ val≡⟨ cong (List._++ _) (reverse-++ ctx (List.reverse xs)) ⟩(List.reverse (List.reverse xs) List.++ List.reverse ctx) List.++ val≡⟨ ++-assoc (List.reverse (List.reverse xs)) (List.reverse ctx) val ⟩List.reverse (List.reverse xs) List.++ List.reverse ctx List.++ val≡⟨ cong (List._++ _) (reverse-involutive xs) ⟩xs List.++ List.reverse ctx List.++ val∎ˡ++-assoc : ∀ xs ys (zp : Zipper A) → xs ˡ++ (ys ˡ++ zp) ≡ (xs List.++ ys) ˡ++ zpˡ++-assoc xs ys (mkZipper ctx val) = cong (λ ctx → mkZipper ctx val) $ begin(ctx List.++ List.reverse ys) List.++ List.reverse xs≡⟨ ++-assoc ctx _ _ ⟩ctx List.++ List.reverse ys List.++ List.reverse xs≡⟨ cong (ctx List.++_) (sym (reverse-++ xs ys)) ⟩ctx List.++ List.reverse (xs List.++ ys)∎-- _ʳ++_ propertiesʳ++-assoc : ∀ xs ys (zp : Zipper A) → xs ʳ++ (ys ʳ++ zp) ≡ (ys List.++ xs) ʳ++ zpʳ++-assoc xs ys (mkZipper ctx val) = cong (λ ctx → mkZipper ctx val) $ beginList.reverse xs List.++ List.reverse ys List.++ ctx≡⟨ sym (++-assoc (List.reverse xs) (List.reverse ys) ctx) ⟩(List.reverse xs List.++ List.reverse ys) List.++ ctx≡⟨ cong (List._++ ctx) (sym (reverse-++ ys xs)) ⟩List.reverse (ys List.++ xs) List.++ ctx∎-- _++ˡ_ properties++ˡ-assoc : ∀ xs ys (zp : Zipper A) → zp ++ˡ xs ++ˡ ys ≡ zp ++ˡ (ys List.++ xs)++ˡ-assoc xs ys (mkZipper ctx val) = cong (mkZipper ctx) $ sym $ ++-assoc ys xs val-- _++ʳ_ propertiestoList-++ʳ : ∀ (zp : Zipper A) xs → toList (zp ++ʳ xs) ≡ toList zp List.++ xstoList-++ʳ (mkZipper ctx val) xs = beginList.reverse ctx List.++ val List.++ xs≡⟨ sym (++-assoc (List.reverse ctx) val xs) ⟩(List.reverse ctx List.++ val) List.++ xs∎++ʳ-assoc : ∀ xs ys (zp : Zipper A) → zp ++ʳ xs ++ʳ ys ≡ zp ++ʳ (xs List.++ ys)++ʳ-assoc xs ys (mkZipper ctx val) = cong (mkZipper ctx) $ ++-assoc val xs ys-- List-like operations indeed correspond to their counterparts------------------------------------------------------------------------module _ {a b} {A : Set a} {B : Set b} wheretoList-map : ∀ (f : A → B) zp → toList (map f zp) ≡ List.map f (toList zp)toList-map f zp@(mkZipper ctx val) = beginList.reverse (List.map f ctx) List.++ List.map f val≡⟨ cong (List._++ _) (sym (reverse-map f ctx)) ⟩List.map f (List.reverse ctx) List.++ List.map f val≡⟨ sym (map-++ f (List.reverse ctx) val) ⟩List.map f (List.reverse ctx List.++ val)∎toList-foldr : ∀ (c : A → B → B) n zp → foldr c n zp ≡ List.foldr c n (toList zp)toList-foldr c n (mkZipper ctx val) = beginList.foldl (flip c) (List.foldr c n val) ctx≡⟨ sym (reverse-foldr c (List.foldr c n val) ctx) ⟩List.foldr c (List.foldr c n val) (List.reverse ctx)≡⟨ sym (foldr-++ c n (List.reverse ctx) val) ⟩List.foldr c n (List.reverse ctx List.++ val)∎-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0toList-reverse-commute = toList-reverse{-# WARNING_ON_USAGE toList-reverse-commute"Warning: toList-reverse-commute was deprecated in v2.0.Please use toList-reverse instead."#-}toList-ˡ++-commute = toList-ˡ++{-# WARNING_ON_USAGE toList-ˡ++-commute"Warning: toList-ˡ++-commute was deprecated in v2.0.Please use toList-ˡ++ instead."#-}toList-++ʳ-commute = toList-++ʳ{-# WARNING_ON_USAGE toList-++ʳ-commute"Warning: toList-++ʳ-commute was deprecated in v2.0.Please use toList-++ʳ instead."#-}toList-map-commute = toList-map{-# WARNING_ON_USAGE toList-map-commute"Warning: toList-map-commute was deprecated in v2.0.Please use toList-map instead."#-}toList-foldr-commute = toList-foldr{-# WARNING_ON_USAGE toList-foldr-commute"Warning: toList-foldr-commute was deprecated in v2.0.Please use toList-foldr instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Functions and definitions for sorting lists-------------------------------------------------------------------------- See `Data.List.Relation.Unary.Sorted` for the property of a list-- being sorted.{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Base using (List)open import Relation.Binary.Bundles using (DecTotalOrder)module Data.List.Sort{a ℓ₁ ℓ₂} (O : DecTotalOrder a ℓ₁ ℓ₂)whereopen DecTotalOrder O renaming (Carrier to A)-------------------------------------------------------------------------- Re-export core definitionsopen import Data.List.Sort.Base totalOrder publicusing (SortingAlgorithm)-------------------------------------------------------------------------- An instance of a sorting algorithmopen import Data.List.Sort.MergeSort O using (mergeSort)abstractsortingAlgorithm : SortingAlgorithmsortingAlgorithm = mergeSortopen SortingAlgorithm sortingAlgorithm publicusing( sort -- : List A → List A; sort-↭ -- : ∀ xs → sort xs ↭ xs; sort-↗ -- : ∀ xs → Sorted (sort xs))
-------------------------------------------------------------------------- The Agda standard library---- An implementation of merge sort along with proofs of correctness.-------------------------------------------------------------------------- Unless you are need a particular property of MergeSort, you should-- import and use the sorting algorithm from `Data.List.Sort` instead-- of this file.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecTotalOrder)module Data.List.Sort.MergeSort{a ℓ₁ ℓ₂} (O : DecTotalOrder a ℓ₁ ℓ₂) whereopen import Data.Bool.Base using (true; false)open import Data.List.Baseusing (List; []; _∷_; merge; length; map; [_]; concat; _++_)open import Data.List.Properties using (length-partition; ++-assoc; concat-[-])open import Data.List.Relation.Unary.Linked using ([]; [-])import Data.List.Relation.Unary.Sorted.TotalOrder.Properties as Sortedopen import Data.List.Relation.Unary.All as All using (All; []; _∷_)import Data.List.Relation.Unary.All.Properties as Allopen import Data.List.Relation.Binary.Permutation.Propositionalimport Data.List.Relation.Binary.Permutation.Propositional.Properties as Permopen import Data.Maybe.Base using (just)open import Data.Nat.Base using (_<_; _>_; z<s; s<s)open import Data.Nat.Inductionopen import Data.Nat.Properties using (m<n⇒m<1+n)open import Data.Product.Base as Product using (_,_)open import Function.Base using (_∘_)open import Relation.Nullary.Negation.Core using (¬_)open import Relation.Nullary.Decidable.Core using (does)open DecTotalOrder O renaming (Carrier to A)open import Data.List.Sort.Base totalOrderopen import Data.List.Relation.Unary.Sorted.TotalOrder totalOrder hiding (head)open import Relation.Binary.Properties.DecTotalOrder O using (≰⇒≥; ≰-respˡ-≈)open PermutationReasoning-------------------------------------------------------------------------- DefinitionmergePairs : List (List A) → List (List A)mergePairs (xs ∷ ys ∷ yss) = merge _≤?_ xs ys ∷ mergePairs yssmergePairs xss = xssprivatelength-mergePairs : ∀ xs ys yss → let zss = xs ∷ ys ∷ yss inlength (mergePairs zss) < length zsslength-mergePairs _ _ [] = s<s z<slength-mergePairs _ _ (xs ∷ []) = s<s (s<s z<s)length-mergePairs _ _ (xs ∷ ys ∷ yss) = s<s (m<n⇒m<1+n (length-mergePairs xs ys yss))mergeAll : (xss : List (List A)) → Acc _<_ (length xss) → List AmergeAll [] _ = []mergeAll (xs ∷ []) _ = xsmergeAll xss@(xs ∷ ys ∷ yss) (acc rec) = mergeAll(mergePairs xss) (rec (length-mergePairs xs ys yss))sort : List A → List Asort xs = mergeAll (map [_] xs) (<-wellFounded-fast _)-------------------------------------------------------------------------- Permutation propertymergePairs-↭ : ∀ xss → concat (mergePairs xss) ↭ concat xssmergePairs-↭ [] = ↭-reflmergePairs-↭ (xs ∷ []) = ↭-reflmergePairs-↭ (xs ∷ ys ∷ xss) = beginmerge _ xs ys ++ concat (mergePairs xss) ↭⟨ Perm.++⁺ (Perm.merge-↭ _ xs ys) (mergePairs-↭ xss) ⟩(xs ++ ys) ++ concat xss ≡⟨ ++-assoc xs ys (concat xss) ⟩xs ++ ys ++ concat xss ∎mergeAll-↭ : ∀ xss (rec : Acc _<_ (length xss)) → mergeAll xss rec ↭ concat xssmergeAll-↭ [] _ = ↭-reflmergeAll-↭ (xs ∷ []) _ = ↭-sym (Perm.++-identityʳ xs)mergeAll-↭ (xs ∷ ys ∷ xss) (acc rec) = beginmergeAll (mergePairs (xs ∷ ys ∷ xss)) _ ↭⟨ mergeAll-↭ (mergePairs (xs ∷ ys ∷ xss)) _ ⟩concat (mergePairs (xs ∷ ys ∷ xss)) ↭⟨ mergePairs-↭ (xs ∷ ys ∷ xss) ⟩concat (xs ∷ ys ∷ xss) ∎sort-↭ : ∀ xs → sort xs ↭ xssort-↭ xs = beginmergeAll (map [_] xs) _ ↭⟨ mergeAll-↭ (map [_] xs) _ ⟩concat (map [_] xs) ≡⟨ concat-[-] xs ⟩xs ∎-------------------------------------------------------------------------- Sorted propertymergePairs-↗ : ∀ {xss} → All Sorted xss → All Sorted (mergePairs xss)mergePairs-↗ [] = []mergePairs-↗ (xs↗ ∷ []) = xs↗ ∷ []mergePairs-↗ (xs↗ ∷ ys↗ ∷ xss↗) = Sorted.merge⁺ O xs↗ ys↗ ∷ mergePairs-↗ xss↗mergeAll-↗ : ∀ {xss} (rec : Acc _<_ (length xss)) →All Sorted xss → Sorted (mergeAll xss rec)mergeAll-↗ rec [] = []mergeAll-↗ rec (xs↗ ∷ []) = xs↗mergeAll-↗ (acc rec) (xs↗ ∷ ys↗ ∷ xss↗) = mergeAll-↗ _ (mergePairs-↗ (xs↗ ∷ ys↗ ∷ xss↗))sort-↗ : ∀ xs → Sorted (sort xs)sort-↗ xs = mergeAll-↗ _ (All.map⁺ (All.universal (λ _ → [-]) xs))-------------------------------------------------------------------------- AlgorithmmergeSort : SortingAlgorithmmergeSort = record{ sort = sort; sort-↭ = sort-↭; sort-↗ = sort-↗}
-------------------------------------------------------------------------- The Agda standard library---- The core definition of a sorting algorithm------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Base using (List)open import Data.List.Relation.Binary.Permutation.Propositionalopen import Level using (_⊔_)open import Relation.Binary.Bundles using (TotalOrder)module Data.List.Sort.Base{a ℓ₁ ℓ₂} (totalOrder : TotalOrder a ℓ₁ ℓ₂)whereopen TotalOrder totalOrder renaming (Carrier to A)open import Data.List.Relation.Unary.Sorted.TotalOrder totalOrder-------------------------------------------------------------------------- Definition of a sorting algorithmrecord SortingAlgorithm : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldsort : List A → List A-- The output of `sort` is a permutation of the inputsort-↭ : ∀ xs → sort xs ↭ xs-- The output of `sort` is sorted.sort-↗ : ∀ xs → Sorted (sort xs)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- Disabled to prevent warnings from deprecated monoid solver{-# OPTIONS --warn=noUserWarning #-}module Data.List.Solver where{-# WARNING_ON_IMPORT"Data.List.Solver was deprecated in v1.3.Use the new reflective Tactic.MonoidSolver instead."#-}import Algebra.Solver.Monoid as Solveropen import Data.List.Properties using (++-monoid)-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _++_module ++-Solver {a} {A : Set a} =Solver (++-monoid A) renaming (id to nil)
-------------------------------------------------------------------------- The Agda standard library---- Showing lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Show whereopen import Data.List.Base using (List; map)open import Data.String.Base using (String; between; intersperse)open import Function.Base using (_∘_)show : ∀ {a} {A : Set a} → (A → String) → (List A → String)show s = between "[" "]" ∘ intersperse ", " ∘ map s
-------------------------------------------------------------------------- The Agda standard library---- List scans: properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Scans.Properties whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.NonEmpty.Base as List⁺ using (List⁺; _∷_; toList)import Data.List.Properties as Listimport Data.List.NonEmpty.Properties as List⁺open import Data.List.Scans.Baseopen import Function.Base using (_∘_; _$_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; refl; trans; cong; cong₂)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Properties-- scanr⁺ and scanrmodule _ (f : A → B → B) (e : B) whereprivateh = List.foldr f escanr⁺-defn : scanr⁺ f e ≗ List⁺.map h ∘ List⁺.tailsscanr⁺-defn [] = reflscanr⁺-defn (x ∷ xs) = let eq = scanr⁺-defn xsin cong₂ (λ z → f x z ∷_) (cong List⁺.head eq) (cong toList eq)scanr-defn : scanr f e ≗ List.map h ∘ List.tailsscanr-defn xs = cong toList (scanr⁺-defn xs)-- scanl⁺ and scanlmodule _ (f : A → B → A) whereprivateh = List.foldl fscanl⁺-defn : ∀ e → scanl⁺ f e ≗ List⁺.map (h e) ∘ List⁺.initsscanl⁺-defn e [] = reflscanl⁺-defn e (x ∷ xs) = let eq = scanl⁺-defn (f e x) xs incong (e ∷_) $ cong (f e x ∷_) $ trans (cong List⁺.tail eq) (List.map-∘ _)scanl-defn : ∀ e → scanl f e ≗ List.map (h e) ∘ List.initsscanl-defn e xs = cong toList (scanl⁺-defn e xs)
-------------------------------------------------------------------------- The Agda standard library---- List scans: definitions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Scans.Base whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.NonEmpty.Base as List⁺ using (List⁺; _∷_; toList)open import Function.Base using (_∘_)open import Level using (Level)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definitions-- Scanrmodule _ (f : A → B → B) wherescanr⁺ : (e : B) → List A → List⁺ Bscanr⁺ e [] = e ∷ []scanr⁺ e (x ∷ xs) = let y ∷ ys = scanr⁺ e xs in f x y ∷ y ∷ ysscanr : (e : B) → List A → List Bscanr e = toList ∘ scanr⁺ e-- Scanlmodule _ (f : A → B → A) wherescanl⁺ : A → List B → List⁺ Ascanl⁺ e xs = e ∷ go e xswherego : A → List B → List Ago _ [] = []go e (x ∷ xs) = let fex = f e x in fex ∷ go fex xsscanl : A → List B → List Ascanl e = toList ∘ scanl⁺ e
-------------------------------------------------------------------------- The Agda standard library---- Reverse view------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Reverse whereopen import Data.List.Base as L using (List; []; _∷_; _∷ʳ_)open import Data.List.Propertiesusing (unfold-reverse; reverse-involutive)open import Function.Base using (_$_)open import Relation.Binary.PropositionalEquality.Coreusing (subst; sym)-- If you want to traverse a list from the end, then you can use the-- reverse view of it.infixl 5 _∶_∶ʳ_data Reverse {a} {A : Set a} : List A → Set a where[] : Reverse []_∶_∶ʳ_ : ∀ xs (rs : Reverse xs) (x : A) → Reverse (xs ∷ʳ x)module _ {a} {A : Set a} wherereverse : (xs : List A) → Reverse (L.reverse xs)reverse [] = []reverse (x ∷ xs) = cast $ _ ∶ reverse xs ∶ʳ x wherecast = subst Reverse (sym $ unfold-reverse x xs)reverseView : (xs : List A) → Reverse xsreverseView xs = cast $ reverse (L.reverse xs) wherecast = subst Reverse (reverse-involutive xs)
-------------------------------------------------------------------------- The Agda standard library---- Lists made up entirely of unique elements (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Nullary.Negation using (¬_)module Data.List.Relation.Unary.Unique.Setoid {a ℓ} (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- DefinitionprivateDistinct : Rel A ℓDistinct x y = ¬ (x ≈ y)open import Data.List.Relation.Unary.AllPairs.Core Distinct publicrenaming (AllPairs to Unique)open import Data.List.Relation.Unary.AllPairs {R = Distinct} publicusing (head; tail)
-------------------------------------------------------------------------- The Agda standard library---- Properties of unique lists (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Unique.Setoid.Properties whereopen import Data.List.Baseopen import Data.List.Membership.Setoid.Propertiesopen import Data.List.Relation.Binary.Disjoint.Setoidopen import Data.List.Relation.Binary.Disjoint.Setoid.Propertiesopen import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.All.Properties using (All¬⇒¬Any)open import Data.List.Relation.Unary.AllPairs as AllPairs using (AllPairs)open import Data.List.Relation.Unary.Unique.Setoidopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (_×ₛ_)import Data.List.Relation.Unary.AllPairs.Properties as AllPairsopen import Data.Fin.Base using (Fin)open import Data.Nat.Base using (_<_)open import Function.Base using (_∘_; id)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Negation using (contraposition)privatevariablea b c p ℓ ℓ₁ ℓ₂ ℓ₃ : Level-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ (S : Setoid a ℓ₁) (R : Setoid b ℓ₂) whereopen Setoid S renaming (_≈_ to _≈₁_)open Setoid R renaming (_≈_ to _≈₂_)map⁺ : ∀ {f} → (∀ {x y} → f x ≈₂ f y → x ≈₁ y) →∀ {xs} → Unique S xs → Unique R (map f xs)map⁺ inj xs! = AllPairs.map⁺ (AllPairs.map (contraposition inj) xs!)-------------------------------------------------------------------------- ++module _ (S : Setoid a ℓ) where++⁺ : ∀ {xs ys} → Unique S xs → Unique S ys → Disjoint S xs ys → Unique S (xs ++ ys)++⁺ xs! ys! xs#ys = AllPairs.++⁺ xs! ys! (Disjoint⇒AllAll S xs#ys)-------------------------------------------------------------------------- concatmodule _ (S : Setoid a ℓ) whereconcat⁺ : ∀ {xss} → All (Unique S) xss → AllPairs (Disjoint S) xss → Unique S (concat xss)concat⁺ xss! xss# = AllPairs.concat⁺ xss! (AllPairs.map (Disjoint⇒AllAll S) xss#)-------------------------------------------------------------------------- cartesianProductWithmodule _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) (U : Setoid c ℓ₃) whereopen Setoid S using () renaming (_≈_ to _≈₁_)open Setoid T using () renaming (_≈_ to _≈₂_)open Setoid U using () renaming (_≈_ to _≈₃_; sym to sym₃; trans to trans₃)cartesianProductWith⁺ : ∀ {xs ys} f → (∀ {w x y z} → f w y ≈₃ f x z → w ≈₁ x × y ≈₂ z) →Unique S xs → Unique T ys →Unique U (cartesianProductWith f xs ys)cartesianProductWith⁺ {_} {_} f f-inj [] ys! = [] {S = U}cartesianProductWith⁺ {x ∷ xs} {ys} f f-inj (x∉xs ∷ xs!) ys! = ++⁺ U(map⁺ T U (proj₂ ∘ f-inj) ys!)(cartesianProductWith⁺ f f-inj xs! ys!)map#cartesianProductWithwheremap#cartesianProductWith : Disjoint U (map (f x) ys) (cartesianProductWith f xs ys)map#cartesianProductWith (v∈map , v∈com) with∈-map⁻ T U v∈map | ∈-cartesianProductWith⁻ S T U f xs ys v∈com... | (c , _ , v≈fxc) | (a , b , a∈xs , _ , v≈fab) =All¬⇒¬Any x∉xs (∈-resp-≈ S (proj₁ (f-inj (trans₃ (sym₃ v≈fab) v≈fxc))) a∈xs)-------------------------------------------------------------------------- cartesianProductmodule _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) {xs ys} wherecartesianProduct⁺ : Unique S xs → Unique T ys →Unique (S ×ₛ T) (cartesianProduct xs ys)cartesianProduct⁺ = cartesianProductWith⁺ S T (S ×ₛ T) _,_ id-------------------------------------------------------------------------- take & dropmodule _ (S : Setoid a ℓ) wheredrop⁺ : ∀ {xs} n → Unique S xs → Unique S (drop n xs)drop⁺ = AllPairs.drop⁺take⁺ : ∀ {xs} n → Unique S xs → Unique S (take n xs)take⁺ = AllPairs.take⁺-------------------------------------------------------------------------- applyUpTomodule _ (S : Setoid a ℓ) whereopen Setoid SapplyUpTo⁺₁ : ∀ f n → (∀ {i j} → i < j → j < n → f i ≉ f j) →Unique S (applyUpTo f n)applyUpTo⁺₁ = AllPairs.applyUpTo⁺₁applyUpTo⁺₂ : ∀ f n → (∀ i j → f i ≉ f j) →Unique S (applyUpTo f n)applyUpTo⁺₂ = AllPairs.applyUpTo⁺₂-------------------------------------------------------------------------- applyDownFrommodule _ (S : Setoid a ℓ) whereopen Setoid SapplyDownFrom⁺₁ : ∀ f n → (∀ {i j} → j < i → i < n → f i ≉ f j) →Unique S (applyDownFrom f n)applyDownFrom⁺₁ = AllPairs.applyDownFrom⁺₁applyDownFrom⁺₂ : ∀ f n → (∀ i j → f i ≉ f j) →Unique S (applyDownFrom f n)applyDownFrom⁺₂ = AllPairs.applyDownFrom⁺₂-------------------------------------------------------------------------- tabulatemodule _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)tabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → f i ≈ f j → i ≡ j) →Unique S (tabulate f)tabulate⁺ f-inj = AllPairs.tabulate⁺ (_∘ f-inj)-------------------------------------------------------------------------- filtermodule _ (S : Setoid a ℓ) {P : Pred _ p} (P? : Decidable P) wherefilter⁺ : ∀ {xs} → Unique S xs → Unique S (filter P? xs)filter⁺ = AllPairs.filter⁺ P?
-------------------------------------------------------------------------- The Agda standard library---- Lists made up entirely of unique elements (propositional equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Unique.Propositional {a} {A : Set a} whereopen import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Data.List.Relation.Unary.Unique.Setoid as SetoidUnique-------------------------------------------------------------------------- Re-export the contents of setoid uniquenessopen SetoidUnique (setoid A) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of unique lists (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Unique.Propositional.Properties whereopen import Data.List.Base using (map; _++_; concat; cartesianProductWith;cartesianProduct; drop; take; applyUpTo; upTo; applyDownFrom; downFrom;tabulate; allFin; filter)open import Data.List.Relation.Binary.Disjoint.Propositionalusing (Disjoint)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.AllPairs as AllPairs using (AllPairs)open import Data.List.Relation.Unary.Unique.Propositional using (Unique)import Data.List.Relation.Unary.Unique.Setoid.Properties as Setoidopen import Data.Fin.Base using (Fin)open import Data.Nat.Base using (_<_)open import Data.Nat.Properties using (<⇒≢)open import Data.Product.Base using (_×_; _,_)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (≡⇒≡×≡)open import Function.Base using (id; _∘_)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Coreusing (refl; _≡_; _≢_; sym)open import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Negation using (¬_)privatevariablea b c p : Level-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ {A : Set a} {B : Set b} wheremap⁺ : ∀ {f} → (∀ {x y} → f x ≡ f y → x ≡ y) →∀ {xs} → Unique xs → Unique (map f xs)map⁺ = Setoid.map⁺ (setoid A) (setoid B)-------------------------------------------------------------------------- ++module _ {A : Set a} {xs ys} where++⁺ : Unique xs → Unique ys → Disjoint xs ys → Unique (xs ++ ys)++⁺ = Setoid.++⁺ (setoid A)-------------------------------------------------------------------------- concatmodule _ {A : Set a} {xss} whereconcat⁺ : All Unique xss → AllPairs Disjoint xss → Unique (concat xss)concat⁺ = Setoid.concat⁺ (setoid A)-------------------------------------------------------------------------- cartesianProductWithmodule _ {A : Set a} {B : Set b} {C : Set c} {xs ys} wherecartesianProductWith⁺ : ∀ f → (∀ {w x y z} → f w y ≡ f x z → w ≡ x × y ≡ z) →Unique xs → Unique ys →Unique (cartesianProductWith f xs ys)cartesianProductWith⁺ = Setoid.cartesianProductWith⁺ (setoid A) (setoid B) (setoid C)-------------------------------------------------------------------------- cartesianProductmodule _ {A : Set a} {B : Set b} wherecartesianProduct⁺ : ∀ {xs ys} → Unique xs → Unique ys →Unique (cartesianProduct xs ys)cartesianProduct⁺ xs ys = AllPairs.map (_∘ ≡⇒≡×≡)(Setoid.cartesianProduct⁺ (setoid A) (setoid B) xs ys)-------------------------------------------------------------------------- take & dropmodule _ {A : Set a} wheredrop⁺ : ∀ {xs} n → Unique xs → Unique (drop n xs)drop⁺ = Setoid.drop⁺ (setoid A)take⁺ : ∀ {xs} n → Unique xs → Unique (take n xs)take⁺ = Setoid.take⁺ (setoid A)-------------------------------------------------------------------------- applyUpTo & upTomodule _ {A : Set a} whereapplyUpTo⁺₁ : ∀ f n → (∀ {i j} → i < j → j < n → f i ≢ f j) →Unique (applyUpTo f n)applyUpTo⁺₁ = Setoid.applyUpTo⁺₁ (setoid A)applyUpTo⁺₂ : ∀ f n → (∀ i j → f i ≢ f j) →Unique (applyUpTo f n)applyUpTo⁺₂ = Setoid.applyUpTo⁺₂ (setoid A)-------------------------------------------------------------------------- upToupTo⁺ : ∀ n → Unique (upTo n)upTo⁺ n = applyUpTo⁺₁ id n (λ i<j _ → <⇒≢ i<j)-------------------------------------------------------------------------- applyDownFrommodule _ {A : Set a} whereapplyDownFrom⁺₁ : ∀ f n → (∀ {i j} → j < i → i < n → f i ≢ f j) →Unique (applyDownFrom f n)applyDownFrom⁺₁ = Setoid.applyDownFrom⁺₁ (setoid A)applyDownFrom⁺₂ : ∀ f n → (∀ i j → f i ≢ f j) →Unique (applyDownFrom f n)applyDownFrom⁺₂ = Setoid.applyDownFrom⁺₂ (setoid A)-------------------------------------------------------------------------- downFromdownFrom⁺ : ∀ n → Unique (downFrom n)downFrom⁺ n = applyDownFrom⁺₁ id n (λ j<i _ → <⇒≢ j<i ∘ sym)-------------------------------------------------------------------------- tabulatemodule _ {A : Set a} wheretabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → f i ≡ f j → i ≡ j) →Unique (tabulate f)tabulate⁺ = Setoid.tabulate⁺ (setoid A)-------------------------------------------------------------------------- allFinallFin⁺ : ∀ n → Unique (allFin n)allFin⁺ n = tabulate⁺ id-------------------------------------------------------------------------- filtermodule _ {A : Set a} {P : Pred _ p} (P? : Decidable P) wherefilter⁺ : ∀ {xs} → Unique xs → Unique (filter P? xs)filter⁺ = Setoid.filter⁺ (setoid A) P?
-------------------------------------------------------------------------- The Agda standard library---- Lists made up entirely of unique elements (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)import Data.List.Relation.Unary.AllPairs as AllPairsopen import Relation.Unary using (Decidable)open import Relation.Nullary.Decidable using (¬?)module Data.List.Relation.Unary.Unique.DecSetoid{a ℓ} (DS : DecSetoid a ℓ) whereopen DecSetoid DS renaming (setoid to S)-------------------------------------------------------------------------- Re-export setoid definitionopen import Data.List.Relation.Unary.Unique.Setoid S public-------------------------------------------------------------------------- Additional propertiesunique? : Decidable Uniqueunique? = AllPairs.allPairs? (λ x y → ¬? (x ≟ y))
-------------------------------------------------------------------------- The Agda standard library---- Properties of lists made up entirely of decidably unique elements------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Base using ([]; _∷_; deduplicate)import Data.List.Relation.Unary.Unique.DecSetoid as Uniqueopen import Data.List.Relation.Unary.All.Properties using (all-filter)open import Data.List.Relation.Unary.Unique.Setoid.Propertiesopen import Levelopen import Relation.Binary.Bundles using (DecSetoid)module Data.List.Relation.Unary.Unique.DecSetoid.Properties whereprivatevariablea ℓ : Level-------------------------------------------------------------------------- deduplicatemodule _ (DS : DecSetoid a ℓ) whereopen DecSetoid DS renaming (setoid to S)open Unique DSdeduplicate-! : ∀ xs → Unique (deduplicate _≟_ xs)deduplicate-! [] = []deduplicate-! (x ∷ xs) = all-filter _ (deduplicate _≟_ xs) ∷ filter⁺ S _ (deduplicate-! xs)
-------------------------------------------------------------------------- The Agda standard library---- Lists made up entirely of unique elements (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Properties using (decSetoid)module Data.List.Relation.Unary.Unique.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A) where-------------------------------------------------------------------------- Re-export setoid definitionopen import Data.List.Relation.Unary.Unique.DecSetoid (decSetoid _≟_) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of lists made up entirely of decidably unique elements------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Unary.Unique.DecPropositional.Properties{a} {A : Set a} (_≟_ : DecidableEquality A) whereopen import Data.List.Base using (deduplicate)open import Data.List.Relation.Unary.All.Properties using (all-filter)open import Data.List.Relation.Unary.Unique.DecPropositional _≟_import Data.List.Relation.Unary.Unique.DecSetoid.Properties as Setoidopen import Levelopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Re-export propositional propertiesopen import Data.List.Relation.Unary.Unique.Propositional.Properties public-------------------------------------------------------------------------- deduplicatededuplicate-! : ∀ xs → Unique (deduplicate _≟_ xs)deduplicate-! = Setoid.deduplicate-! (decSetoid _≟_)
-------------------------------------------------------------------------- The Agda standard library---- 'Sufficient' lists: a structurally inductive view of lists xs-- as given by xs ≡ non-empty prefix + sufficient suffix---- Useful for termination arguments for function definitions-- which provably consume a non-empty (but otherwise arbitrary) prefix-- *without* having to resort to ancillary WF induction on length etc.-- e.g. lexers, parsers etc.---- Credited by Conor McBride as originally due to James McKinna------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Sufficient whereopen import Level using (Level; _⊔_)open import Data.List.Base using (List; []; _∷_; [_]; _++_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b : LevelA : Set ax : Axs : List A-------------------------------------------------------------------------- Sufficient buildersuffAcc : {A : Set a} (B : List A → Set b) (xs : List A) → Set (a ⊔ b)suffAcc B xs = ∀ {x} {prefix} suffix → xs ≡ x ∷ prefix ++ suffix → B suffix-------------------------------------------------------------------------- Sufficient viewdata Sufficient {A : Set a} : (xs : List A) → Set a whereacc : ∀ {xs} (ih : suffAcc Sufficient xs) → Sufficient xs-------------------------------------------------------------------------- Sufficient properties-- constructorsmodule Constructors where[]⁺ : Sufficient {A = A} [][]⁺ = acc λ _ ()∷⁺ : Sufficient xs → Sufficient (x ∷ xs)∷⁺ {xs = xs} suffices@(acc hyp) = acc λ { _ refl → suf _ refl }wheresuf : ∀ prefix {suffix} → xs ≡ prefix ++ suffix → Sufficient suffixsuf [] refl = sufficessuf (_ ∷ _) {suffix} eq = hyp suffix eq-- destructorsmodule Destructors whereacc-inverse : ∀ ys → Sufficient (x ∷ xs ++ ys) → Sufficient ysacc-inverse ys (acc hyp) = hyp ys refl++⁻ : ∀ xs {ys : List A} → Sufficient (xs ++ ys) → Sufficient ys++⁻ [] suffices = suffices++⁻ (x ∷ xs) {ys} suffices = acc-inverse ys suffices∷⁻ : Sufficient (x ∷ xs) → Sufficient xs∷⁻ {x = x} = ++⁻ [ x ]-------------------------------------------------------------------------- Sufficient view covering propertymodule View whereopen Constructorssufficient : (xs : List A) → Sufficient xssufficient [] = []⁺sufficient (x ∷ xs) = ∷⁺ (sufficient xs)-------------------------------------------------------------------------- Recursion on the sufficient viewmodule _ (B : List A → Set b) (rec : ∀ ys → (ih : suffAcc B ys) → B ys)whereopen ViewsuffRec′ : ∀ {zs} → Sufficient zs → B zssuffRec′ {zs} (acc hyp) = rec zs (λ xs eq → suffRec′ (hyp xs eq))suffRec : ∀ zs → B zssuffRec zs = suffRec′ (sufficient zs)
-------------------------------------------------------------------------- The Agda standard library---- Sorted lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (TotalOrder)module Data.List.Relation.Unary.Sorted.TotalOrder{a ℓ₁ ℓ₂} (totalOrder : TotalOrder a ℓ₁ ℓ₂) whereopen TotalOrder totalOrder renaming (Carrier to A)open import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Unary.Linked as Linked using (Linked)open import Level using (_⊔_)open import Relation.Unary as U using (Pred; _⊆_)open import Relation.Binary.Definitions as B-------------------------------------------------------------------------- DefinitionSorted : Pred (List A) (a ⊔ ℓ₂)Sorted xs = Linked _≤_ xs-------------------------------------------------------------------------- Operationsmodule _ {x y xs} wherehead : Sorted (x ∷ y ∷ xs) → x ≤ yhead = Linked.headtail : Sorted (x ∷ xs) → Sorted xstail = Linked.tail-------------------------------------------------------------------------- Properties of predicates preserved by Sortedsorted? : B.Decidable _≤_ → U.Decidable Sortedsorted? = Linked.linked?irrelevant : B.Irrelevant _≤_ → U.Irrelevant Sortedirrelevant = Linked.irrelevantsatisfiable : U.Satisfiable Sortedsatisfiable = Linked.satisfiable
-------------------------------------------------------------------------- The Agda standard library---- Sorted lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Sorted.TotalOrder.Properties whereopen import Data.List.Baseopen import Data.List.Relation.Unary.All using (All)open import Data.List.Relation.Unary.AllPairs using (AllPairs)open import Data.List.Relation.Unary.Linked as Linkedusing (Linked; []; [-]; _∷_; _∷′_; head′; tail)import Data.List.Relation.Unary.Linked.Properties as Linkedimport Data.List.Relation.Binary.Sublist.Setoid as Sublistimport Data.List.Relation.Binary.Sublist.Setoid.Properties as SublistPropertiesopen import Data.List.Relation.Unary.Sorted.TotalOrder hiding (head)open import Data.Maybe.Base using (just; nothing)open import Data.Maybe.Relation.Binary.Connected using (Connected; just)open import Data.Nat.Base using (ℕ; zero; suc; _<_)open import Level using (Level)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundles using (TotalOrder; DecTotalOrder; Preorder)import Relation.Binary.Properties.TotalOrder as TotalOrderPropertiesopen import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Decidable using (yes; no)privatevariablea b p ℓ₁ ℓ₂ ℓ₃ ℓ₄ : Level-------------------------------------------------------------------------- Relationship to other predicates------------------------------------------------------------------------module _ (O : TotalOrder a ℓ₁ ℓ₂) whereopen TotalOrder OAllPairs⇒Sorted : ∀ {xs} → AllPairs _≤_ xs → Sorted O xsAllPairs⇒Sorted = Linked.AllPairs⇒LinkedSorted⇒AllPairs : ∀ {xs} → Sorted O xs → AllPairs _≤_ xsSorted⇒AllPairs = Linked.Linked⇒AllPairs trans-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ (O₁ : TotalOrder a ℓ₁ ℓ₂) (O₂ : TotalOrder a ℓ₁ ℓ₂) whereprivatemodule O₁ = TotalOrder O₁module O₂ = TotalOrder O₂map⁺ : ∀ {f xs} → f Preserves O₁._≤_ ⟶ O₂._≤_ →Sorted O₁ xs → Sorted O₂ (map f xs)map⁺ pres xs↗ = Linked.map⁺ (Linked.map pres xs↗)map⁻ : ∀ {f xs} → (∀ {x y} → f x O₂.≤ f y → x O₁.≤ y) →Sorted O₂ (map f xs) → Sorted O₁ xsmap⁻ pres fxs↗ = Linked.map pres (Linked.map⁻ fxs↗)-------------------------------------------------------------------------- _++_module _ (O : TotalOrder a ℓ₁ ℓ₂) whereopen TotalOrder O++⁺ : ∀ {xs ys} → Sorted O xs → Connected _≤_ (last xs) (head ys) →Sorted O ys → Sorted O (xs ++ ys)++⁺ = Linked.++⁺-------------------------------------------------------------------------- applyUpTomodule _ (O : TotalOrder a ℓ₁ ℓ₂) whereopen TotalOrder OapplyUpTo⁺₁ : ∀ f n → (∀ {i} → suc i < n → f i ≤ f (suc i)) →Sorted O (applyUpTo f n)applyUpTo⁺₁ = Linked.applyUpTo⁺₁applyUpTo⁺₂ : ∀ f n → (∀ i → f i ≤ f (suc i)) →Sorted O (applyUpTo f n)applyUpTo⁺₂ = Linked.applyUpTo⁺₂-------------------------------------------------------------------------- applyDownFrommodule _ (O : TotalOrder a ℓ₁ ℓ₂) whereopen TotalOrder OapplyDownFrom⁺₁ : ∀ f n → (∀ {i} → suc i < n → f (suc i) ≤ f i) →Sorted O (applyDownFrom f n)applyDownFrom⁺₁ = Linked.applyDownFrom⁺₁applyDownFrom⁺₂ : ∀ f n → (∀ i → f (suc i) ≤ f i) →Sorted O (applyDownFrom f n)applyDownFrom⁺₂ = Linked.applyDownFrom⁺₂-------------------------------------------------------------------------- mergemodule _ (DO : DecTotalOrder a ℓ₁ ℓ₂) whereopen DecTotalOrder DO using (_≤_; _≤?_) renaming (totalOrder to O)open TotalOrderProperties O using (≰⇒≥)privatemerge-con : ∀ {v xs ys} →Connected _≤_ (just v) (head xs) →Connected _≤_ (just v) (head ys) →Connected _≤_ (just v) (head (merge _≤?_ xs ys))merge-con {xs = []} cxs cys = cysmerge-con {xs = x ∷ xs} {[]} cxs cys = cxsmerge-con {xs = x ∷ xs} {y ∷ ys} cxs cys with x ≤? y... | yes x≤y = cxs... | no x≰y = cysmerge⁺ : ∀ {xs ys} → Sorted O xs → Sorted O ys → Sorted O (merge _≤?_ xs ys)merge⁺ {[]} rxs rys = rysmerge⁺ {x ∷ xs} {[]} rxs rys = rxsmerge⁺ {x ∷ xs} {y ∷ ys} rxs ryswith x ≤? y | merge⁺ (Linked.tail rxs) rys| merge⁺ rxs (Linked.tail rys)... | yes x≤y | rec | _ = merge-con (head′ rxs) (just x≤y) ∷′ rec... | no x≰y | _ | rec = merge-con (just (≰⇒≥ x≰y)) (head′ rys) ∷′ rec-- Reexport ⊆-mergeˡʳS = Preorder.Eq.setoid (DecTotalOrder.preorder DO)open Sublist S using (_⊆_)module SP = SublistProperties S⊆-mergeˡ : ∀ xs ys → xs ⊆ merge _≤?_ xs ys⊆-mergeˡ = SP.⊆-mergeˡ _≤?_⊆-mergeʳ : ∀ xs ys → ys ⊆ merge _≤?_ xs ys⊆-mergeʳ = SP.⊆-mergeʳ _≤?_-------------------------------------------------------------------------- filtermodule _ (O : TotalOrder a ℓ₁ ℓ₂) {P : Pred _ p} (P? : Decidable P) whereopen TotalOrder Ofilter⁺ : ∀ {xs} → Sorted O xs → Sorted O (filter P? xs)filter⁺ = Linked.filter⁺ P? trans
-------------------------------------------------------------------------- The Agda standard library---- Lists where every consecutative pair of elements is related.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Linked {a} {A : Set a} whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.Product.Base as Prod using (_,_; _×_; uncurry; <_,_>)open import Data.Maybe.Base using (just)open import Data.Maybe.Relation.Binary.Connectedusing (Connected; just; just-nothing)open import Function.Base using (id; _∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Definitions as Bopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Construct.Intersection renaming (_∩_ to _∩ᵇ_)open import Relation.Binary.PropositionalEquality.Core using (refl; cong₂)open import Relation.Unary as U renaming (_∩_ to _∩ᵘ_) hiding (_⇒_)open import Relation.Nullary.Decidable using (yes; no; map′; _×-dec_)privatevariablep q r ℓ : Level-------------------------------------------------------------------------- Definition-- Linked R xs means that every consecutative pair of elements in xs is-- a member of relation R.infixr 5 _∷_data Linked (R : Rel A ℓ) : List A → Set (a ⊔ ℓ) where[] : Linked R [][-] : ∀ {x} → Linked R (x ∷ [])_∷_ : ∀ {x y xs} → R x y → Linked R (y ∷ xs) → Linked R (x ∷ y ∷ xs)-------------------------------------------------------------------------- Operationsmodule _ {R : Rel A p} wherehead : ∀ {x y xs} → Linked R (x ∷ y ∷ xs) → R x yhead (Rxy ∷ Rxs) = Rxytail : ∀ {x xs} → Linked R (x ∷ xs) → Linked R xstail [-] = []tail (_ ∷ Rxs) = Rxshead′ : ∀ {x xs} → Linked R (x ∷ xs) → Connected R (just x) (List.head xs)head′ [-] = just-nothinghead′ (Rxy ∷ _) = just Rxyinfixr 5 _∷′__∷′_ : ∀ {x xs} →Connected R (just x) (List.head xs) →Linked R xs →Linked R (x ∷ xs)_∷′_ {xs = []} _ _ = [-]_∷′_ {xs = y ∷ xs} (just Rxy) Ryxs = Rxy ∷ Ryxsmodule _ {R : Rel A p} {S : Rel A q} wheremap : R ⇒ S → Linked R ⊆ Linked Smap R⇒S [] = []map R⇒S [-] = [-]map R⇒S (x~xs ∷ pxs) = R⇒S x~xs ∷ map R⇒S pxsmodule _ {P : Rel A p} {Q : Rel A q} {R : Rel A r} wherezipWith : P ∩ᵇ Q ⇒ R → Linked P ∩ᵘ Linked Q ⊆ Linked RzipWith f ([] , []) = []zipWith f ([-] , [-]) = [-]zipWith f (px ∷ pxs , qx ∷ qxs) = f (px , qx) ∷ zipWith f (pxs , qxs)unzipWith : R ⇒ P ∩ᵇ Q → Linked R ⊆ Linked P ∩ᵘ Linked QunzipWith f [] = [] , []unzipWith f [-] = [-] , [-]unzipWith f (rx ∷ rxs) = Prod.zip _∷_ _∷_ (f rx) (unzipWith f rxs)module _ {P : Rel A p} {Q : Rel A q} wherezip : Linked P ∩ᵘ Linked Q ⊆ Linked (P ∩ᵇ Q)zip = zipWith idunzip : Linked (P ∩ᵇ Q) ⊆ Linked P ∩ᵘ Linked Qunzip = unzipWith id-------------------------------------------------------------------------- Properties of predicates preserved by Linkedmodule _ {R : Rel A ℓ} wherelinked? : B.Decidable R → U.Decidable (Linked R)linked? R? [] = yes []linked? R? (x ∷ []) = yes [-]linked? R? (x ∷ y ∷ xs) =map′ (uncurry _∷_) < head , tail > (R? x y ×-dec linked? R? (y ∷ xs))irrelevant : B.Irrelevant R → U.Irrelevant (Linked R)irrelevant irr [] [] = reflirrelevant irr [-] [-] = reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =cong₂ _∷_ (irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : U.Satisfiable (Linked R)satisfiable = [] , []
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Linked------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Linked.Properties whereopen import Data.Bool.Base using (true; false)open import Data.List.Base hiding (any)open import Data.List.Relation.Unary.AllPairs as AllPairsusing (AllPairs; []; _∷_)import Data.List.Relation.Unary.AllPairs.Properties as AllPairsopen import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.List.Relation.Unary.Linked as Linkedusing (Linked; []; [-]; _∷_)open import Data.Nat.Base using (zero; suc; _<_; z<s; s<s)open import Data.Nat.Properties using (≤-refl; m≤n⇒m≤1+n)open import Data.Maybe.Relation.Binary.Connectedusing (Connected; just; nothing; just-nothing; nothing-just)open import Level using (Level)open import Function.Base using (_∘_; flip; _on_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (DecSetoid)open import Relation.Binary.Definitions using (Transitive)open import Relation.Binary.PropositionalEquality.Core using (_≢_)open import Relation.Unary using (Pred; Decidable)open import Relation.Nullary.Decidable using (yes; no; does)privatevariablea b p ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Relationship to other predicates------------------------------------------------------------------------module _ {R : Rel A ℓ} whereAllPairs⇒Linked : ∀ {xs} → AllPairs R xs → Linked R xsAllPairs⇒Linked [] = []AllPairs⇒Linked (px ∷ []) = [-]AllPairs⇒Linked ((px ∷ _) ∷ py ∷ pxs) =px ∷ (AllPairs⇒Linked (py ∷ pxs))module _ {R : Rel A ℓ} (trans : Transitive R) whereLinked⇒All : ∀ {v x xs} → R v x →Linked R (x ∷ xs) → All (R v) (x ∷ xs)Linked⇒All Rvx [-] = Rvx ∷ []Linked⇒All Rvx (Rxy ∷ Rxs) = Rvx ∷ Linked⇒All (trans Rvx Rxy) RxsLinked⇒AllPairs : ∀ {xs} → Linked R xs → AllPairs R xsLinked⇒AllPairs [] = []Linked⇒AllPairs [-] = [] ∷ []Linked⇒AllPairs (Rxy ∷ Rxs) = Linked⇒All Rxy Rxs ∷ Linked⇒AllPairs Rxs-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ {R : Rel A ℓ} {f : B → A} wheremap⁺ : ∀ {xs} → Linked (R on f) xs → Linked R (map f xs)map⁺ [] = []map⁺ [-] = [-]map⁺ (Rxy ∷ Rxs) = Rxy ∷ map⁺ Rxsmap⁻ : ∀ {xs} → Linked R (map f xs) → Linked (R on f) xsmap⁻ {[]} [] = []map⁻ {x ∷ []} [-] = [-]map⁻ {x ∷ y ∷ xs} (Rxy ∷ Rxs) = Rxy ∷ map⁻ Rxs-------------------------------------------------------------------------- _++_module _ {R : Rel A ℓ} where++⁺ : ∀ {xs ys} →Linked R xs →Connected R (last xs) (head ys) →Linked R ys →Linked R (xs ++ ys)++⁺ [] _ Rys = Rys++⁺ [-] _ [] = [-]++⁺ [-] (just Rxy) [-] = Rxy ∷ [-]++⁺ [-] (just Rxy) (Ryz ∷ Rys) = Rxy ∷ Ryz ∷ Rys++⁺ (Rxy ∷ Rxs) Rxsys Rys = Rxy ∷ ++⁺ Rxs Rxsys Rys-------------------------------------------------------------------------- applyUpTomodule _ {R : Rel A ℓ} whereapplyUpTo⁺₁ : ∀ f n → (∀ {i} → suc i < n → R (f i) (f (suc i))) →Linked R (applyUpTo f n)applyUpTo⁺₁ f 0 Rf = []applyUpTo⁺₁ f 1 Rf = [-]applyUpTo⁺₁ f (suc n@(suc _)) Rf =Rf (s<s z<s) ∷ (applyUpTo⁺₁ (f ∘ suc) n (Rf ∘ s<s))applyUpTo⁺₂ : ∀ f n → (∀ i → R (f i) (f (suc i))) →Linked R (applyUpTo f n)applyUpTo⁺₂ f n Rf = applyUpTo⁺₁ f n (λ _ → Rf _)-------------------------------------------------------------------------- applyDownFrommodule _ {R : Rel A ℓ} whereapplyDownFrom⁺₁ : ∀ f n → (∀ {i} → suc i < n → R (f (suc i)) (f i)) →Linked R (applyDownFrom f n)applyDownFrom⁺₁ f 0 Rf = []applyDownFrom⁺₁ f 1 Rf = [-]applyDownFrom⁺₁ f (suc n@(suc _)) Rf =Rf ≤-refl ∷ applyDownFrom⁺₁ f n (Rf ∘ m≤n⇒m≤1+n)applyDownFrom⁺₂ : ∀ f n → (∀ i → R (f (suc i)) (f i)) →Linked R (applyDownFrom f n)applyDownFrom⁺₂ f n Rf = applyDownFrom⁺₁ f n (λ _ → Rf _)-------------------------------------------------------------------------- filtermodule _ {P : Pred A p} (P? : Decidable P){R : Rel A ℓ} (trans : Transitive R)where∷-filter⁺ : ∀ {x xs} → Linked R (x ∷ xs) → Linked R (x ∷ filter P? xs)∷-filter⁺ [-] = [-]∷-filter⁺ {xs = y ∷ _} (r ∷ [-]) with does (P? y)... | false = [-]... | true = r ∷ [-]∷-filter⁺ {x = x} {xs = y ∷ ys} (r ∷ r′ ∷ rs)with does (P? y) | ∷-filter⁺ {xs = ys} | ∷-filter⁺ (r′ ∷ rs)... | false | ihf | _ = ihf (trans r r′ ∷ rs)... | true | _ | iht = r ∷ ihtfilter⁺ : ∀ {xs} → Linked R xs → Linked R (filter P? xs)filter⁺ [] = []filter⁺ {xs = x ∷ []} [-] with does (P? x)... | false = []... | true = [-]filter⁺ {xs = x ∷ _} (r ∷ rs) with does (P? x)... | false = filter⁺ rs... | true = ∷-filter⁺ (r ∷ rs)
-------------------------------------------------------------------------- The Agda standard library---- Property that elements are grouped------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Grouped whereopen import Data.List.Base using (List; []; _∷_; map)open import Data.List.Relation.Unary.All as All using (All; []; _∷_; all?)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Data.Product.Base using (_×_; _,_)open import Relation.Binary.Core using (REL; Rel)open import Relation.Binary.Definitions as Bopen import Relation.Unary as U using (Pred)open import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Decidable as Dec using (yes; ¬?; _⊎-dec_; _×-dec_)open import Level using (Level; _⊔_)privatevariablea ℓ : LevelA : Set ax y : Axs : List A-------------------------------------------------------------------------- Definitioninfixr 5 _∷≉_ _∷≈_data Grouped {A : Set a} (_≈_ : Rel A ℓ) : Pred (List A) (a ⊔ ℓ) where[] : Grouped _≈_ []_∷≉_ : All (λ y → ¬ (x ≈ y)) xs → Grouped _≈_ xs → Grouped _≈_ (x ∷ xs)_∷≈_ : x ≈ y → Grouped _≈_ (y ∷ xs) → Grouped _≈_ (x ∷ y ∷ xs)-------------------------------------------------------------------------- Basic propertiesmodule _ {_≈_ : Rel A ℓ} wheregrouped? : B.Decidable _≈_ → U.Decidable (Grouped _≈_)grouped? _≟_ [] = yes []grouped? _≟_ (x ∷ []) = yes ([] ∷≉ [])grouped? _≟_ (x ∷ y ∷ xs) =Dec.map′ from to ((x ≟ y ⊎-dec all? (λ z → ¬? (x ≟ z)) (y ∷ xs)) ×-dec (grouped? _≟_ (y ∷ xs)))wherefrom : ((x ≈ y) ⊎ All (λ z → ¬ (x ≈ z)) (y ∷ xs)) × Grouped _≈_ (y ∷ xs) → Grouped _≈_ (x ∷ y ∷ xs)from (inj₁ x≈y , grouped[y∷xs]) = x≈y ∷≈ grouped[y∷xs]from (inj₂ all[x≉,y∷xs] , grouped[y∷xs]) = all[x≉,y∷xs] ∷≉ grouped[y∷xs]to : Grouped _≈_ (x ∷ y ∷ xs) → ((x ≈ y) ⊎ All (λ z → ¬ (x ≈ z)) (y ∷ xs)) × Grouped _≈_ (y ∷ xs)to (all[x≉,y∷xs] ∷≉ grouped[y∷xs]) = inj₂ all[x≉,y∷xs] , grouped[y∷xs]to (x≈y ∷≈ grouped[y∷xs]) = inj₁ x≈y , grouped[y∷xs]
-------------------------------------------------------------------------- The Agda standard library---- Property related to Grouped------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Grouped.Properties whereopen import Data.Bool.Base using (true; false)open import Data.List.Base using ([]; [_]; _∷_; map; derun)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)import Data.List.Relation.Unary.All.Properties as Allopen import Data.List.Relation.Unary.AllPairs as AllPairs using (AllPairs; []; _∷_)open import Data.List.Relation.Unary.Groupedopen import Data.Product.Base using (_,_)open import Function.Base using (_∘_; _on_)open import Level using (Level)open import Relation.Binary.Definitions as Bopen import Relation.Binary.Core using (_⇔_; REL; Rel)open import Relation.Unary as U using (Pred)open import Relation.Nullary.Decidable.Core using (does; yes; no)open import Relation.Nullary.Negation.Core using (¬_; contradiction)privatevariablea b c p q : LevelA B C : Set a-------------------------------------------------------------------------- mapmodule _ (P : Rel A p) (Q : Rel B q) wheremap⁺ : ∀ {f xs} → P ⇔ (Q on f) → Grouped P xs → Grouped Q (map f xs)map⁺ P⇔Q [] = []map⁺ P⇔Q@(_ , Q⇒P) (all[¬Px,xs] ∷≉ g[xs]) = All.gmap⁺ (_∘ Q⇒P) all[¬Px,xs] ∷≉ map⁺ P⇔Q g[xs]map⁺ P⇔Q@(P⇒Q , _) (Px₁x₂ ∷≈ g[xs]) = P⇒Q Px₁x₂ ∷≈ map⁺ P⇔Q g[xs]map⁻ : ∀ {f xs} → P ⇔ (Q on f) → Grouped Q (map f xs) → Grouped P xsmap⁻ {xs = []} P⇔Q [] = []map⁻ {xs = _ ∷ []} P⇔Q ([] ∷≉ []) = [] ∷≉ []map⁻ {xs = _ ∷ _ ∷ _} P⇔Q@(P⇒Q , _) (all[¬Qx,xs] ∷≉ g) = All.gmap⁻ (_∘ P⇒Q) all[¬Qx,xs] ∷≉ map⁻ P⇔Q gmap⁻ {xs = _ ∷ _ ∷ _} P⇔Q@(_ , Q⇒P) (Qx₁x₂ ∷≈ g) = Q⇒P Qx₁x₂ ∷≈ map⁻ P⇔Q g-------------------------------------------------------------------------- [_]module _ (P : Rel A p) where[_]⁺ : ∀ x → Grouped P [ x ][_]⁺ x = [] ∷≉ []-------------------------------------------------------------------------- derunmodule _ {P : Rel A p} (P? : B.Decidable P) wheregrouped[xs]⇒unique[derun[xs]] : ∀ xs → Grouped P xs → AllPairs (λ x y → ¬ P x y) (derun P? xs)grouped[xs]⇒unique[derun[xs]] [] [] = []grouped[xs]⇒unique[derun[xs]] (x ∷ []) ([] ∷≉ []) = [] ∷ []grouped[xs]⇒unique[derun[xs]] (x ∷ y ∷ xs) (all[¬Px,y∷xs]@(¬Pxy ∷ _) ∷≉ grouped[y∷xs]) with P? x y... | yes Pxy = contradiction Pxy ¬Pxy... | no _ = All.derun⁺ P? all[¬Px,y∷xs] ∷ grouped[xs]⇒unique[derun[xs]] (y ∷ xs) grouped[y∷xs]grouped[xs]⇒unique[derun[xs]] (x ∷ y ∷ xs) (Pxy ∷≈ grouped[xs]) with P? x y... | yes _ = grouped[xs]⇒unique[derun[xs]] (y ∷ xs) grouped[xs]... | no ¬Pxy = contradiction Pxy ¬Pxy
-------------------------------------------------------------------------- The Agda standard library---- First generalizes the idea that an element is the first in a list to-- satisfy a predicate.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.First {a} {A : Set a} whereopen import Level using (_⊔_)open import Data.Emptyopen import Data.Fin.Base as Fin using (Fin; zero; suc)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.Product.Base using (∃; -,_; _,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Function.Base using (id; _∘′_)open import Relation.Unaryopen import Relation.Nullary-------------------------------------------------------------------------- Basic type.module _ {p q} (P : Pred A p) (Q : Pred A q) whereinfix 1 _++_∷_infixr 5 _∷_data First : Pred (List A) (a ⊔ p ⊔ q) where[_] : ∀ {x xs} → Q x → First (x ∷ xs)_∷_ : ∀ {x xs} → P x → First xs → First (x ∷ xs)data FirstView : Pred (List A) (a ⊔ p ⊔ q) where_++_∷_ : ∀ {xs y} → All P xs → Q y → ∀ ys → FirstView (xs List.++ y ∷ ys)-------------------------------------------------------------------------- mapmodule _ {p q r s} {P : Pred A p} {Q : Pred A q} {R : Pred A r} {S : Pred A s} wheremap : P ⊆ R → Q ⊆ S → First P Q ⊆ First R Smap p⇒r q⇒r [ qx ] = [ q⇒r qx ]map p⇒r q⇒r (px ∷ pqxs) = p⇒r px ∷ map p⇒r q⇒r pqxsmodule _ {p q r} {P : Pred A p} {Q : Pred A q} {R : Pred A r} wheremap₁ : P ⊆ R → First P Q ⊆ First R Qmap₁ p⇒r = map p⇒r idmap₂ : Q ⊆ R → First P Q ⊆ First P Rmap₂ = map idrefine : P ⊆ Q ∪ R → First P Q ⊆ First R Qrefine f [ qx ] = [ qx ]refine f (px ∷ pqxs) with f px... | inj₁ qx = [ qx ]... | inj₂ rx = rx ∷ refine f pqxsmodule _ {p q} {P : Pred A p} {Q : Pred A q} where-------------------------------------------------------------------------- Operationsempty : ¬ First P Q []empty ()tail : ∀ {x xs} → ¬ Q x → First P Q (x ∷ xs) → First P Q xstail ¬qx [ qx ] = ⊥-elim (¬qx qx)tail ¬qx (px ∷ pqxs) = pqxsindex : First P Q ⊆ (Fin ∘′ List.length)index [ qx ] = zeroindex (_ ∷ pqxs) = suc (index pqxs)index-satisfied : ∀ {xs} (pqxs : First P Q xs) → Q (List.lookup xs (index pqxs))index-satisfied [ qx ] = qxindex-satisfied (_ ∷ pqxs) = index-satisfied pqxssatisfied : ∀ {xs} → First P Q xs → ∃ Qsatisfied pqxs = -, index-satisfied pqxssatisfiable : Satisfiable Q → Satisfiable (First P Q)satisfiable (x , qx) = List.[ x ] , [ qx ]-------------------------------------------------------------------------- Decidability resultsfirst : Π[ P ∪ Q ] → Π[ First P Q ∪ All P ]first p⊎q [] = inj₂ []first p⊎q (x ∷ xs) with p⊎q x... | inj₁ px = Sum.map (px ∷_) (px ∷_) (first p⊎q xs)... | inj₂ qx = inj₁ [ qx ]-------------------------------------------------------------------------- Relationship with Anymodule _ {q} {Q : Pred A q} wherefromAny : Any Q ⊆ First U QfromAny (here qx) = [ qx ]fromAny (there any) = _ ∷ fromAny anytoAny : ∀ {p} {P : Pred A p} → First P Q ⊆ Any QtoAny [ qx ] = here qxtoAny (_ ∷ pqxs) = there (toAny pqxs)
-------------------------------------------------------------------------- The Agda standard library---- Properties of First------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.First.Properties whereopen import Data.Fin.Base using (suc)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.Any as Any using (here; there)open import Data.List.Relation.Unary.Firstimport Data.Sum.Base as Sumopen import Function.Base using (_∘′_; _∘_; id)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; refl; _≗_)import Relation.Nullary.Decidable.Core as Decopen import Relation.Nullary.Negation.Core using (contradiction)open import Relation.Unary using (Pred; _⊆_; ∁; Irrelevant; Decidable)-------------------------------------------------------------------------- mapmodule _ {a b p q} {A : Set a} {B : Set b} {P : Pred B p} {Q : Pred B q} wheremap⁺ : {f : A → B} → First (P ∘′ f) (Q ∘′ f) ⊆ First P Q ∘′ List.map fmap⁺ [ qfx ] = [ qfx ]map⁺ (pfxs ∷ pqfxs) = pfxs ∷ map⁺ pqfxsmap⁻ : {f : A → B} → First P Q ∘′ List.map f ⊆ First (P ∘′ f) (Q ∘′ f)map⁻ {f} {x ∷ xs} [ qfx ] = [ qfx ]map⁻ {f} {x ∷ xs} (pfx ∷ pqfxs) = pfx ∷ map⁻ pqfxs-------------------------------------------------------------------------- (++)module _ {a p q} {A : Set a} {P : Pred A p} {Q : Pred A q} where++⁺ : ∀ {xs ys} → All P xs → First P Q ys → First P Q (xs List.++ ys)++⁺ [] pqys = pqys++⁺ (px ∷ pxs) pqys = px ∷ ++⁺ pxs pqys⁺++ : ∀ {xs} → First P Q xs → ∀ ys → First P Q (xs List.++ ys)⁺++ [ qx ] ys = [ qx ]⁺++ (px ∷ pqxs) ys = px ∷ ⁺++ pqxs ys-------------------------------------------------------------------------- Relationship to Allmodule _ {a p q} {A : Set a} {P : Pred A p} {Q : Pred A q} whereAll⇒¬First : P ⊆ ∁ Q → All P ⊆ ∁ (First P Q)All⇒¬First p⇒¬q (px ∷ pxs) [ qx ] = contradiction qx (p⇒¬q px)All⇒¬First p⇒¬q (_ ∷ pxs) (_ ∷ hf) = All⇒¬First p⇒¬q pxs hfFirst⇒¬All : Q ⊆ ∁ P → First P Q ⊆ ∁ (All P)First⇒¬All q⇒¬p [ qx ] (px ∷ pxs) = q⇒¬p qx pxFirst⇒¬All q⇒¬p (_ ∷ pqxs) (_ ∷ pxs) = First⇒¬All q⇒¬p pqxs pxs-------------------------------------------------------------------------- Irrelevanceunique-index : ∀ {xs} → P ⊆ ∁ Q → (f₁ f₂ : First P Q xs) → index f₁ ≡ index f₂unique-index p⇒¬q [ _ ] [ _ ] = reflunique-index p⇒¬q [ qx ] (px ∷ _) = contradiction qx (p⇒¬q px)unique-index p⇒¬q (px ∷ _) [ qx ] = contradiction qx (p⇒¬q px)unique-index p⇒¬q (_ ∷ f₁) (_ ∷ f₂) = ≡.cong suc (unique-index p⇒¬q f₁ f₂)irrelevant : P ⊆ ∁ Q → Irrelevant P → Irrelevant Q → Irrelevant (First P Q)irrelevant p⇒¬q p-irr q-irr [ px ] [ qx ] = ≡.cong [_] (q-irr px qx)irrelevant p⇒¬q p-irr q-irr [ qx ] (px ∷ _) = contradiction qx (p⇒¬q px)irrelevant p⇒¬q p-irr q-irr (px ∷ _) [ qx ] = contradiction qx (p⇒¬q px)irrelevant p⇒¬q p-irr q-irr (px ∷ f) (qx ∷ g) =≡.cong₂ _∷_ (p-irr px qx) (irrelevant p⇒¬q p-irr q-irr f g)-------------------------------------------------------------------------- Decidabilitymodule _ {a p} {A : Set a} {P : Pred A p} wherefirst? : Decidable P → Decidable (First P (∁ P))first? P? = Dec.fromSum∘ Sum.map₂ (All⇒¬First contradiction)∘ first (Dec.toSum ∘ P?)cofirst? : Decidable P → Decidable (First (∁ P) P)cofirst? P? = Dec.fromSum∘ Sum.map₂ (All⇒¬First id)∘ first (Sum.swap ∘ Dec.toSum ∘ P?)-------------------------------------------------------------------------- Conversion to Anymodule _ {a p} {A : Set a} {P : Pred A p} wherefromAny∘toAny≗id : ∀ {xs} → fromAny {Q = P} {x = xs} ∘′ toAny ≗ idfromAny∘toAny≗id [ qx ] = reflfromAny∘toAny≗id (px ∷ pqxs) = ≡.cong (_ ∷_) (fromAny∘toAny≗id pqxs)toAny∘fromAny≗id : ∀ {xs} → toAny {Q = P} ∘′ fromAny {x = xs} ≗ idtoAny∘fromAny≗id (here px) = refltoAny∘fromAny≗id (there v) = ≡.cong there (toAny∘fromAny≗id v)-------------------------------------------------------------------------- Equivalence between the inductive definition and the viewmodule _ {a p q} {A : Set a} {P : Pred A p} {Q : Pred A q} wheretoView : ∀ {as} → First P Q as → FirstView P Q astoView [ qx ] = [] ++ qx ∷ _toView (px ∷ pqxs) with toView pqxs... | pxs ++ qy ∷ ys = (px ∷ pxs) ++ qy ∷ ysfromView : ∀ {as} → FirstView P Q as → First P Q asfromView (pxs ++ qy ∷ ys) = ++⁺ pxs [ qy ]
-------------------------------------------------------------------------- The Agda standard library---- Lists which contain every element of a given type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Base using (List)open import Levelopen import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Unary.Enumerates.Setoid{a ℓ} (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open import Data.List.Membership.Setoid S-------------------------------------------------------------------------- DefinitionIsEnumeration : List A → Set (a ⊔ ℓ)IsEnumeration xs = ∀ x → x ∈ xs
-------------------------------------------------------------------------- The Agda standard library---- Properties of lists which contain every element of a given type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Baseopen import Data.List.Membership.Setoid.Properties as Membershipopen import Data.List.Relation.Unary.Any using (index)open import Data.List.Relation.Unary.Any.Properties using (lookup-index)open import Data.List.Relation.Unary.Enumerates.Setoidopen import Data.Sum.Base using (inj₁; inj₂)open import Data.Sum.Relation.Binary.Pointwiseusing (_⊎ₛ_; inj₁; inj₂)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependentusing (_×ₛ_)open import Function.Base using (_∘_)open import Function.Bundles using (Surjection)open import Function.Definitions using (Surjective)open import Function.Consequences using (strictlySurjective⇒surjective)open import Levelopen import Relation.Binary.Bundles using (Setoid; DecSetoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Properties.Setoid using (respʳ-flip)module Data.List.Relation.Unary.Enumerates.Setoid.Properties whereprivatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- mapmodule _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) (surj : Surjection S T) whereopen Surjection surjmap⁺ : ∀ {xs} → IsEnumeration S xs → IsEnumeration T (map to xs)map⁺ _∈xs y with (x , fx≈y) ← strictlySurjective y =∈-resp-≈ T fx≈y (∈-map⁺ S T cong (x ∈xs))-------------------------------------------------------------------------- _++_module _ (S : Setoid a ℓ₁) where++⁺ˡ : ∀ {xs} ys → IsEnumeration S xs → IsEnumeration S (xs ++ ys)++⁺ˡ _ _∈xs v = Membership.∈-++⁺ˡ S (v ∈xs)++⁺ʳ : ∀ xs {ys} → IsEnumeration S ys → IsEnumeration S (xs ++ ys)++⁺ʳ _ _∈ys v = Membership.∈-++⁺ʳ S _ (v ∈ys)module _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) where++⁺ : ∀ {xs ys} → IsEnumeration S xs → IsEnumeration T ys →IsEnumeration (S ⊎ₛ T) (map inj₁ xs ++ map inj₂ ys)++⁺ _∈xs _ (inj₁ x) = ∈-++⁺ˡ (S ⊎ₛ T) (∈-map⁺ S (S ⊎ₛ T) inj₁ (x ∈xs))++⁺ _ _∈ys (inj₂ y) = ∈-++⁺ʳ (S ⊎ₛ T) _ (∈-map⁺ T (S ⊎ₛ T) inj₂ (y ∈ys))-------------------------------------------------------------------------- cartesianProductmodule _ (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) wherecartesianProduct⁺ : ∀ {xs ys} → IsEnumeration S xs → IsEnumeration T ys →IsEnumeration (S ×ₛ T) (cartesianProduct xs ys)cartesianProduct⁺ _∈xs _∈ys (x , y) = ∈-cartesianProduct⁺ S T (x ∈xs) (y ∈ys)-------------------------------------------------------------------------- deduplicatemodule _ (S? : DecSetoid a ℓ₁) whereopen DecSetoid S? renaming (setoid to S)deduplicate⁺ : ∀ {xs} → IsEnumeration S xs →IsEnumeration S (deduplicate _≟_ xs)deduplicate⁺ = ∈-deduplicate⁺ S _≟_ (respʳ-flip S) ∘_-------------------------------------------------------------------------- lookupmodule _ (S : Setoid a ℓ₁) whereopen Setoid Slookup-surjective : ∀ {xs} → IsEnumeration S xs →Surjective _≡_ _≈_ (lookup xs)lookup-surjective _∈xs = strictlySurjective⇒surjectivetrans (λ { ≡.refl → refl}) (λ y → index (y ∈xs) , sym (lookup-index (y ∈xs)))
-------------------------------------------------------------------------- The Agda standard library---- Lists where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Any whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base as List using (List; []; [_]; _∷_; removeAt)open import Data.Product.Base as Product using (∃; _,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Level using (Level; _⊔_)open import Relation.Nullary.Decidable.Core as Dec using (no; _⊎-dec_)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Unary using (Pred; _⊆_; Decidable; Satisfiable)privatevariablea p q : LevelA : Set aP Q : Pred A px : Axs : List A-------------------------------------------------------------------------- Definition-- Given a predicate P, then Any P xs means that at least one element-- in xs satisfies P. See `Relation.Unary` for an explanation of-- predicates.data Any {A : Set a} (P : Pred A p) : Pred (List A) (a ⊔ p) wherehere : ∀ {x xs} (px : P x) → Any P (x ∷ xs)there : ∀ {x xs} (pxs : Any P xs) → Any P (x ∷ xs)-------------------------------------------------------------------------- Operations on Anyhead : ¬ Any P xs → Any P (x ∷ xs) → P xhead ¬pxs (here px) = pxhead ¬pxs (there pxs) = contradiction pxs ¬pxstail : ¬ P x → Any P (x ∷ xs) → Any P xstail ¬px (here px) = contradiction px ¬pxtail ¬px (there pxs) = pxsmap : P ⊆ Q → Any P ⊆ Any Qmap g (here px) = here (g px)map g (there pxs) = there (map g pxs)-- `index x∈xs` is the list position (zero-based) which `x∈xs` points to.index : Any P xs → Fin (List.length xs)index (here px) = zeroindex (there pxs) = suc (index pxs)lookup : {P : Pred A p} → Any P xs → Alookup {xs = xs} p = List.lookup xs (index p)infixr 5 _∷=__∷=_ : {P : Pred A p} → Any P xs → A → List A_∷=_ {xs = xs} x∈xs v = xs List.[ index x∈xs ]∷= vinfixl 4 _─__─_ : {P : Pred A p} → ∀ xs → Any P xs → List Axs ─ x∈xs = removeAt xs (index x∈xs)-- If any element satisfies P, then P is satisfied.satisfied : Any P xs → ∃ Psatisfied (here px) = _ , pxsatisfied (there pxs) = satisfied pxstoSum : Any P (x ∷ xs) → P x ⊎ Any P xstoSum (here px) = inj₁ pxtoSum (there pxs) = inj₂ pxsfromSum : P x ⊎ Any P xs → Any P (x ∷ xs)fromSum (inj₁ px) = here pxfromSum (inj₂ pxs) = there pxs-------------------------------------------------------------------------- Properties of predicates preserved by Anyany? : Decidable P → Decidable (Any P)any? P? [] = no λ()any? P? (x ∷ xs) = Dec.map′ fromSum toSum (P? x ⊎-dec any? P? xs)satisfiable : Satisfiable P → Satisfiable (Any P)satisfiable (x , Px) = [ x ] , here Px-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4any = any?{-# WARNING_ON_USAGE any"Warning: any was deprecated in v1.4.Please use any? instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Any------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.Any.Properties whereopen import Data.Bool.Base using (Bool; false; true; T)open import Data.Bool.Properties using (T-∨; T-≡)open import Data.Empty using (⊥)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base as List hiding (find)open import Data.List.Effectful as List using (monad)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Membership.Propositionalopen import Data.List.Membership.Propositional.Properties.Coreusing (Any↔; find∘map; map∘find; lose∘find)open import Data.List.Relation.Binary.Pointwiseusing (Pointwise; []; _∷_)open import Data.Nat.Base using (zero; suc; _<_; z<s; s<s; s≤s)open import Data.Nat.Properties using (_≟_; ≤∧≢⇒<; ≤-refl; m<n⇒m<1+n)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.Any as MAny using (just)open import Data.Product.Base as Productusing (_×_; _,_; ∃; ∃₂; proj₁; proj₂)open import Data.Product.Function.NonDependent.Propositionalusing (_×-cong_)import Data.Product.Function.Dependent.Propositional as Σopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Sum.Function.Propositional using (_⊎-cong_)open import Effect.Monad using (RawMonad)open import Function.Base using (_$_; _∘_; flip; const; id; _∘′_)open import Function.Bundlesimport Function.Properties.Inverse as Inverseopen import Function.Related.Propositional as Related using (Kind; Related)open import Level using (Level)open import Relation.Binary.Core using (Rel; REL)open import Relation.Binary.Definitions as Bopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans; cong; cong₂; resp)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Unary as Uusing (Pred; _⟨×⟩_; _⟨→⟩_) renaming (_⊆_ to _⋐_)open import Relation.Nullary.Decidable.Coreusing (¬?; _because_; does; yes; no; decidable-stable)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Reflects using (invert)privateopen module ListMonad {ℓ} = RawMonad (monad {ℓ = ℓ})privatevariablea b c p q r ℓ : LevelA B C : Set aP Q R : Pred A px y : Axs ys : List A-------------------------------------------------------------------------- Equality propertieslift-resp : ∀ {_≈_ : Rel A ℓ} → P Respects _≈_ →(Any P) Respects (Pointwise _≈_)lift-resp resp (x≈y ∷ xs≈ys) (here px) = here (resp x≈y px)lift-resp resp (x≈y ∷ xs≈ys) (there pxs) = there (lift-resp resp xs≈ys pxs)here-injective : ∀ {p q : P x} → here {P = P} {xs = xs} p ≡ here q → p ≡ qhere-injective refl = reflthere-injective : ∀ {p q : Any P xs} → there {x = x} p ≡ there q → p ≡ qthere-injective refl = refl-------------------------------------------------------------------------- Misc¬Any[] : ¬ Any P []¬Any[] ()-------------------------------------------------------------------------- Any is a congruenceAny-cong : ∀ {k : Kind} → (∀ x → Related k (P x) (Q x)) →(∀ {z} → Related k (z ∈ xs) (z ∈ ys)) →Related k (Any P xs) (Any Q ys)Any-cong {P = P} {Q = Q} {xs = xs} {ys} P↔Q xs≈ys =Any P xs ↔⟨ Related.SK-sym Any↔ ⟩(∃ λ x → x ∈ xs × P x) ∼⟨ Σ.cong Inverse.↔-refl (xs≈ys ×-cong P↔Q _) ⟩(∃ λ x → x ∈ ys × Q x) ↔⟨ Any↔ ⟩Any Q ys ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- Any.mapmap-cong : (f g : P ⋐ Q) → (∀ {x} (p : P x) → f p ≡ g p) →(p : Any P xs) → Any.map f p ≡ Any.map g pmap-cong f g hyp (here p) = cong here (hyp p)map-cong f g hyp (there p) = cong there $ map-cong f g hyp pmap-id : ∀ (f : P ⋐ P) → (∀ {x} (p : P x) → f p ≡ p) →(p : Any P xs) → Any.map f p ≡ pmap-id f hyp (here p) = cong here (hyp p)map-id f hyp (there p) = cong there $ map-id f hyp pmap-∘ : ∀ (f : Q ⋐ R) (g : P ⋐ Q) (p : Any P xs) →Any.map (f ∘ g) p ≡ Any.map f (Any.map g p)map-∘ f g (here p) = reflmap-∘ f g (there p) = cong there $ map-∘ f g p-------------------------------------------------------------------------- Any.lookuplookup-result : ∀ (p : Any P xs) → P (Any.lookup p)lookup-result (here px) = pxlookup-result (there p) = lookup-result plookup-index : ∀ (p : Any P xs) → P (lookup xs (Any.index p))lookup-index (here px) = pxlookup-index (there pxs) = lookup-index pxs-------------------------------------------------------------------------- Swapping-- Nested occurrences of Any can sometimes be swapped. See also ×↔.module _ {R : REL A B ℓ} whereswap : Any (λ x → Any (R x) ys) xs → Any (λ y → Any (flip R y) xs) ysswap (here pys) = Any.map here pysswap (there pxys) = Any.map there (swap pxys)swap-there : (any : Any (λ x → Any (R x) ys) xs) →swap (Any.map (there {x = x}) any) ≡ there (swap any)swap-there (here pys) = reflswap-there (there pxys) = cong (Any.map there) (swap-there pxys)module _ {R : REL A B ℓ} whereswap-invol : (any : Any (λ x → Any (R x) ys) xs) →swap (swap any) ≡ anyswap-invol (here (here px)) = reflswap-invol (here (there pys)) =cong (Any.map there) (swap-invol (here pys))swap-invol (there pxys) =trans (swap-there (swap pxys)) (cong there (swap-invol pxys))module _ {R : REL A B ℓ} whereswap↔ : Any (λ x → Any (R x) ys) xs ↔ Any (λ y → Any (flip R y) xs) ysswap↔ = mk↔ₛ′ swap swap swap-invol swap-invol-------------------------------------------------------------------------- Lemmas relating Any to ⊥⊥↔Any⊥ : ⊥ ↔ Any (const ⊥) xs⊥↔Any⊥ = mk↔ₛ′ (λ()) (λ p → from p) (λ p → from p) (λ())wherefrom : Any (const ⊥) xs → Bfrom (there p) = from p⊥↔Any[] : ⊥ ↔ Any P []⊥↔Any[] = mk↔ₛ′ (λ()) (λ()) (λ()) (λ())-------------------------------------------------------------------------- Lemmas relating Any to ⊤-- These introduction and elimination rules are not inverses, though.any⁺ : ∀ (p : A → Bool) → Any (T ∘ p) xs → T (any p xs)any⁺ p (here px) = Equivalence.from T-∨ (inj₁ px)any⁺ p (there {x = x} pxs) with p x... | true = _... | false = any⁺ p pxsany⁻ : ∀ (p : A → Bool) xs → T (any p xs) → Any (T ∘ p) xsany⁻ p (x ∷ xs) px∷xs with p x in eq... | true = here (Equivalence.from T-≡ eq)... | false = there (any⁻ p xs px∷xs)any⇔ : ∀ {p : A → Bool} → Any (T ∘ p) xs ⇔ T (any p xs)any⇔ = mk⇔ (any⁺ _) (any⁻ _ _)-------------------------------------------------------------------------- Sums commute with AnyAny-⊎⁺ : Any P xs ⊎ Any Q xs → Any (λ x → P x ⊎ Q x) xsAny-⊎⁺ = [ Any.map inj₁ , Any.map inj₂ ]′Any-⊎⁻ : Any (λ x → P x ⊎ Q x) xs → Any P xs ⊎ Any Q xsAny-⊎⁻ (here (inj₁ p)) = inj₁ (here p)Any-⊎⁻ (here (inj₂ q)) = inj₂ (here q)Any-⊎⁻ (there p) = Sum.map there there (Any-⊎⁻ p)⊎↔ : (Any P xs ⊎ Any Q xs) ↔ Any (λ x → P x ⊎ Q x) xs⊎↔ {P = P} {Q = Q} = mk↔ₛ′ Any-⊎⁺ Any-⊎⁻ to∘from from∘towherefrom∘to : (p : Any P xs ⊎ Any Q xs) → Any-⊎⁻ (Any-⊎⁺ p) ≡ pfrom∘to (inj₁ (here p)) = reflfrom∘to (inj₁ (there p)) rewrite from∘to (inj₁ p) = reflfrom∘to (inj₂ (here q)) = reflfrom∘to (inj₂ (there q)) rewrite from∘to (inj₂ q) = reflto∘from : (p : Any (λ x → P x ⊎ Q x) xs) → Any-⊎⁺ (Any-⊎⁻ p) ≡ pto∘from (here (inj₁ p)) = reflto∘from (here (inj₂ q)) = reflto∘from (there p) with Any-⊎⁻ p | to∘from p... | inj₁ p | refl = refl... | inj₂ q | refl = refl-------------------------------------------------------------------------- Products "commute" with Any.Any-×⁺ : Any P xs × Any Q ys → Any (λ x → Any (λ y → P x × Q y) ys) xsAny-×⁺ (p , q) = Any.map (λ p → Any.map (λ q → (p , q)) q) pAny-×⁻ : Any (λ x → Any (λ y → P x × Q y) ys) xs →Any P xs × Any Q ysAny-×⁻ pq = let x , x∈xs , pq′ = find pq inlet y , y∈ys , p , q = find pq′ inlose x∈xs p , lose y∈ys q×↔ : ∀ {xs ys} →(Any P xs × Any Q ys) ↔ Any (λ x → Any (λ y → P x × Q y) ys) xs×↔ {P = P} {Q = Q} {xs} {ys} = mk↔ₛ′ Any-×⁺ Any-×⁻ to∘from from∘towhereopen ≡-Reasoningfrom∘to : ∀ pq → Any-×⁻ (Any-×⁺ pq) ≡ pqfrom∘to (p , q) = let x , x∈xs , px = find p inAny-×⁻ (Any-×⁺ (p , q))≡⟨⟩(let (x , x∈xs , pq) = find (Any-×⁺ (p , q))(y , y∈ys , p , q) = find pqin lose x∈xs p , lose y∈ys q)≡⟨ cong (λ • → let (x , x∈xs , pq) = •(y , y∈ys , p , q) = find pqin lose x∈xs p , lose y∈ys q)(find∘map p (λ p → Any.map (p ,_) q)) ⟩(let (x , x∈xs , p) = find p(y , y∈ys , p , q) = find (Any.map (p ,_) q)in lose x∈xs p , lose y∈ys q)≡⟨ cong (λ • → let (x , x∈xs , _) = find p(y , y∈ys , p , q) = •in lose x∈xs p , lose y∈ys q)(find∘map q (px ,_)) ⟩(let (x , x∈xs , p) = find p(y , y∈ys , q) = find qin lose x∈xs p , lose y∈ys q)≡⟨ cong₂ _,_ (lose∘find p) (lose∘find q) ⟩(p , q) ∎to∘from : ∀ pq → Any-×⁺ (Any-×⁻ pq) ≡ pqto∘from pq =let x , x∈xs , pq′ = find pqy , y∈ys , px , qy = find pq′h : P ⋐ λ x → Any (λ y → (P x) × (Q y)) ysh p = Any.map (p ,_) (lose y∈ys qy)helper : h px ≡ pq′helper = beginAny.map (px ,_) (lose y∈ys qy)≡⟨ map-∘ (px ,_) (λ z → resp Q z qy) y∈ys ⟨Any.map (λ z → px , resp Q z qy) y∈ys≡⟨ map∘find pq′ refl ⟩pq′∎in beginAny-×⁺ (Any-×⁻ pq)≡⟨⟩Any.map h (lose x∈xs px)≡⟨ map-∘ h (λ z → resp P z px) x∈xs ⟨Any.map (λ z → Any.map (resp P z px ,_) (lose y∈ys qy)) x∈xs≡⟨ map∘find pq helper ⟩pq∎-------------------------------------------------------------------------- Half-applied product commutes with Any.module _ {_~_ : REL A B r} whereAny-Σ⁺ʳ : (∃ λ x → Any (_~ x) xs) → Any (∃ ∘ _~_) xsAny-Σ⁺ʳ (b , here px) = here (b , px)Any-Σ⁺ʳ (b , there pxs) = there (Any-Σ⁺ʳ (b , pxs))Any-Σ⁻ʳ : Any (∃ ∘ _~_) xs → ∃ λ x → Any (_~ x) xsAny-Σ⁻ʳ (here (b , x)) = b , here xAny-Σ⁻ʳ (there xs) = Product.map₂ there $ Any-Σ⁻ʳ xs-------------------------------------------------------------------------- Invertible introduction (⁺) and elimination (⁻) rules for various-- list functions-------------------------------------------------------------------------------------------------------------------------------------------------- singletonsingleton⁺ : P x → Any P [ x ]singleton⁺ Px = here Pxsingleton⁻ : Any P [ x ] → P xsingleton⁻ (here Px) = Px-------------------------------------------------------------------------- mapmodule _ {f : A → B} wheremap⁺ : Any (P ∘ f) xs → Any P (List.map f xs)map⁺ (here p) = here pmap⁺ (there p) = there $ map⁺ pmap⁻ : Any P (List.map f xs) → Any (P ∘ f) xsmap⁻ {xs = x ∷ xs} (here p) = here pmap⁻ {xs = x ∷ xs} (there p) = there $ map⁻ pmap⁺∘map⁻ : (p : Any P (List.map f xs)) → map⁺ (map⁻ p) ≡ pmap⁺∘map⁻ {xs = x ∷ xs} (here p) = reflmap⁺∘map⁻ {xs = x ∷ xs} (there p) = cong there (map⁺∘map⁻ p)map⁻∘map⁺ : ∀ (P : Pred B p) →(p : Any (P ∘ f) xs) → map⁻ {P = P} (map⁺ p) ≡ pmap⁻∘map⁺ P (here p) = reflmap⁻∘map⁺ P (there p) = cong there (map⁻∘map⁺ P p)map↔ : Any (P ∘ f) xs ↔ Any P (List.map f xs)map↔ = mk↔ₛ′ map⁺ map⁻ map⁺∘map⁻ (map⁻∘map⁺ _)gmap : P ⋐ Q ∘ f → Any P ⋐ Any Q ∘ map fgmap g = map⁺ ∘ Any.map g-------------------------------------------------------------------------- mapMaybemodule _ (f : A → Maybe B) wheremapMaybe⁺ : ∀ xs → Any (MAny.Any P) (map f xs) → Any P (mapMaybe f xs)mapMaybe⁺ (x ∷ xs) ps with f x | ps... | nothing | there pxs = mapMaybe⁺ xs pxs... | just _ | here (just py) = here py... | just _ | there pxs = there (mapMaybe⁺ xs pxs)-------------------------------------------------------------------------- _++_module _ {P : A → Set p} where++⁺ˡ : Any P xs → Any P (xs ++ ys)++⁺ˡ (here p) = here p++⁺ˡ (there p) = there (++⁺ˡ p)++⁺ʳ : ∀ xs {ys} → Any P ys → Any P (xs ++ ys)++⁺ʳ [] p = p++⁺ʳ (x ∷ xs) p = there (++⁺ʳ xs p)++⁻ : ∀ xs {ys} → Any P (xs ++ ys) → Any P xs ⊎ Any P ys++⁻ [] p = inj₂ p++⁻ (x ∷ xs) (here p) = inj₁ (here p)++⁻ (x ∷ xs) (there p) = Sum.map there id (++⁻ xs p)++⁺∘++⁻ : ∀ xs {ys} (p : Any P (xs ++ ys)) → [ ++⁺ˡ , ++⁺ʳ xs ]′ (++⁻ xs p) ≡ p++⁺∘++⁻ [] p = refl++⁺∘++⁻ (x ∷ xs) (here p) = refl++⁺∘++⁻ (x ∷ xs) (there p) with ih ← ++⁺∘++⁻ xs p | ++⁻ xs p... | inj₁ _ = cong there ih... | inj₂ _ = cong there ih++⁻∘++⁺ : ∀ xs {ys} (p : Any P xs ⊎ Any P ys) →++⁻ xs ([ ++⁺ˡ , ++⁺ʳ xs ]′ p) ≡ p++⁻∘++⁺ [] (inj₂ p) = refl++⁻∘++⁺ (x ∷ xs) (inj₁ (here p)) = refl++⁻∘++⁺ (x ∷ xs) {ys} (inj₁ (there p)) rewrite ++⁻∘++⁺ xs {ys} (inj₁ p) = refl++⁻∘++⁺ (x ∷ xs) (inj₂ p) rewrite ++⁻∘++⁺ xs (inj₂ p) = refl++↔ : ∀ {xs ys} → (Any P xs ⊎ Any P ys) ↔ Any P (xs ++ ys)++↔ {xs = xs} = mk↔ₛ′ [ ++⁺ˡ , ++⁺ʳ xs ]′ (++⁻ xs) (++⁺∘++⁻ xs) (++⁻∘++⁺ xs)++-comm : ∀ xs ys → Any P (xs ++ ys) → Any P (ys ++ xs)++-comm xs ys = [ ++⁺ʳ ys , ++⁺ˡ ]′ ∘ ++⁻ xs++-comm∘++-comm : ∀ xs {ys} (p : Any P (xs ++ ys)) →++-comm ys xs (++-comm xs ys p) ≡ p++-comm∘++-comm [] {ys} prewrite ++⁻∘++⁺ ys {ys = []} (inj₁ p) = refl++-comm∘++-comm (x ∷ xs) {ys} (here p)rewrite ++⁻∘++⁺ ys {ys = x ∷ xs} (inj₂ (here p)) = refl++-comm∘++-comm (x ∷ xs) (there p) with ++⁻ xs p | ++-comm∘++-comm xs p++-comm∘++-comm (x ∷ xs) {ys} (there .([ ++⁺ʳ xs , ++⁺ˡ ]′ (++⁻ ys (++⁺ʳ ys p))))| inj₁ p | reflrewrite ++⁻∘++⁺ ys (inj₂ p)| ++⁻∘++⁺ ys (inj₂ $ there {x = x} p) = refl++-comm∘++-comm (x ∷ xs) {ys} (there .([ ++⁺ʳ xs , ++⁺ˡ ]′ (++⁻ ys (++⁺ˡ p))))| inj₂ p | reflrewrite ++⁻∘++⁺ ys {ys = xs} (inj₁ p)| ++⁻∘++⁺ ys {ys = x ∷ xs} (inj₁ p) = refl++↔++ : ∀ xs ys → Any P (xs ++ ys) ↔ Any P (ys ++ xs)++↔++ xs ys = mk↔ₛ′ (++-comm xs ys) (++-comm ys xs)(++-comm∘++-comm ys) (++-comm∘++-comm xs)++-insert : ∀ xs {ys} → P x → Any P (xs ++ [ x ] ++ ys)++-insert xs Px = ++⁺ʳ xs (++⁺ˡ (singleton⁺ Px))-------------------------------------------------------------------------- concatmodule _ {P : A → Set p} whereconcat⁺ : ∀ {xss} → Any (Any P) xss → Any P (concat xss)concat⁺ (here p) = ++⁺ˡ pconcat⁺ (there {x = xs} p) = ++⁺ʳ xs (concat⁺ p)concat⁻ : ∀ xss → Any P (concat xss) → Any (Any P) xssconcat⁻ ([] ∷ xss) p = there $ concat⁻ xss pconcat⁻ ((x ∷ xs) ∷ xss) (here p) = here (here p)concat⁻ ((x ∷ xs) ∷ xss) (there p) with concat⁻ (xs ∷ xss) p... | here p′ = here (there p′)... | there p′ = there p′concat⁻∘++⁺ˡ : ∀ {xs} xss (p : Any P xs) →concat⁻ (xs ∷ xss) (++⁺ˡ p) ≡ here pconcat⁻∘++⁺ˡ xss (here p) = reflconcat⁻∘++⁺ˡ xss (there p) rewrite concat⁻∘++⁺ˡ xss p = reflconcat⁻∘++⁺ʳ : ∀ xs xss (p : Any P (concat xss)) →concat⁻ (xs ∷ xss) (++⁺ʳ xs p) ≡ there (concat⁻ xss p)concat⁻∘++⁺ʳ [] xss p = reflconcat⁻∘++⁺ʳ (x ∷ xs) xss p rewrite concat⁻∘++⁺ʳ xs xss p = reflconcat⁺∘concat⁻ : ∀ xss (p : Any P (concat xss)) →concat⁺ (concat⁻ xss p) ≡ pconcat⁺∘concat⁻ ([] ∷ xss) p = concat⁺∘concat⁻ xss pconcat⁺∘concat⁻ ((x ∷ xs) ∷ xss) (here p) = reflconcat⁺∘concat⁻ ((x ∷ xs) ∷ xss) (there p)with p | concat⁻ (xs ∷ xss) p | concat⁺∘concat⁻ (xs ∷ xss) p... | .(++⁺ˡ p′) | here p′ | refl = refl... | .(++⁺ʳ xs (concat⁺ p′)) | there p′ | refl = reflconcat⁻∘concat⁺ : ∀ {xss} (p : Any (Any P) xss) → concat⁻ xss (concat⁺ p) ≡ pconcat⁻∘concat⁺ (here p) = concat⁻∘++⁺ˡ _ pconcat⁻∘concat⁺ (there {x = xs} {xs = xss} p)rewrite concat⁻∘++⁺ʳ xs xss (concat⁺ p) =cong there $ concat⁻∘concat⁺ pconcat↔ : ∀ {xss} → Any (Any P) xss ↔ Any P (concat xss)concat↔ {xss} = mk↔ₛ′ concat⁺ (concat⁻ xss) (concat⁺∘concat⁻ xss) concat⁻∘concat⁺-------------------------------------------------------------------------- cartesianProductWithmodule _ (f : A → B → C) wherecartesianProductWith⁺ : (∀ {x y} → P x → Q y → R (f x y)) →Any P xs → Any Q ys →Any R (cartesianProductWith f xs ys)cartesianProductWith⁺ pres (here px) qys = ++⁺ˡ (map⁺ (Any.map (pres px) qys))cartesianProductWith⁺ pres (there qxs) qys = ++⁺ʳ _ (cartesianProductWith⁺ pres qxs qys)cartesianProductWith⁻ : (∀ {x y} → R (f x y) → P x × Q y) → ∀ xs ys →Any R (cartesianProductWith f xs ys) →Any P xs × Any Q yscartesianProductWith⁻ resp (x ∷ xs) ys Rxsys with ++⁻ (map (f x) ys) Rxsys... | inj₁ Rfxys = let Rxys = map⁻ Rfxysin here (proj₁ (resp (proj₂ (Any.satisfied Rxys)))) , Any.map (proj₂ ∘ resp) Rxys... | inj₂ Rc = let pxs , qys = cartesianProductWith⁻ resp xs ys Rcin there pxs , qys-------------------------------------------------------------------------- cartesianProductcartesianProduct⁺ : Any P xs → Any Q ys →Any (P ⟨×⟩ Q) (cartesianProduct xs ys)cartesianProduct⁺ = cartesianProductWith⁺ _,_ _,_cartesianProduct⁻ : ∀ xs ys → Any (P ⟨×⟩ Q) (cartesianProduct xs ys) →Any P xs × Any Q yscartesianProduct⁻ = cartesianProductWith⁻ _,_ id-------------------------------------------------------------------------- applyUpToapplyUpTo⁺ : ∀ f {i n} → P (f i) → i < n → Any P (applyUpTo f n)applyUpTo⁺ _ p z<s = here papplyUpTo⁺ f p (s<s i<n@(s≤s _)) =there (applyUpTo⁺ (f ∘ suc) p i<n)applyUpTo⁻ : ∀ f {n} → Any P (applyUpTo f n) →∃ λ i → i < n × P (f i)applyUpTo⁻ f {suc n} (here p) = zero , z<s , papplyUpTo⁻ f {suc n} (there p) =let i , i<n , q = applyUpTo⁻ (f ∘ suc) p in suc i , s<s i<n , q-------------------------------------------------------------------------- applyDownFromapplyDownFrom⁺ : ∀ f {i n} → P (f i) → i < n → Any P (applyDownFrom f n)applyDownFrom⁺ f {i} {suc n} p (s≤s i≤n) with i ≟ n... | yes refl = here p... | no i≢n = there (applyDownFrom⁺ f p (≤∧≢⇒< i≤n i≢n))applyDownFrom⁻ : ∀ f {n} → Any P (applyDownFrom f n) →∃ λ i → i < n × P (f i)applyDownFrom⁻ f {suc n} (here p) = n , ≤-refl , papplyDownFrom⁻ f {suc n} (there p) =let i , i<n , q = applyDownFrom⁻ f p in i , m<n⇒m<1+n i<n , q-------------------------------------------------------------------------- tabulatetabulate⁺ : ∀ {n} {f : Fin n → A} i → P (f i) → Any P (tabulate f)tabulate⁺ zero p = here ptabulate⁺ (suc i) p = there (tabulate⁺ i p)tabulate⁻ : ∀ {n} {f : Fin n → A} → Any P (tabulate f) → ∃ λ i → P (f i)tabulate⁻ {n = suc _} (here p) = zero , ptabulate⁻ {n = suc _} (there p) = Product.map suc id (tabulate⁻ p)-------------------------------------------------------------------------- filtermodule _ (Q? : U.Decidable Q) wherefilter⁺ : (p : Any P xs) → Any P (filter Q? xs) ⊎ ¬ Q (Any.lookup p)filter⁺ {xs = x ∷ _} (here px) with Q? x... | true because _ = inj₁ (here px)... | false because [¬Qx] = inj₂ (invert [¬Qx])filter⁺ {xs = x ∷ _} (there p) with does (Q? x)... | true = Sum.map₁ there (filter⁺ p)... | false = filter⁺ pfilter⁻ : Any P (filter Q? xs) → Any P xsfilter⁻ {xs = x ∷ xs} p with does (Q? x) | p... | true | here px = here px... | true | there pxs = there (filter⁻ pxs)... | false | pxs = there (filter⁻ pxs)-------------------------------------------------------------------------- derun and deduplicatemodule _ {R : Rel A r} (R? : B.Decidable R) whereprivatederun⁺-aux : ∀ x xs → P Respects R → P x → Any P (derun R? (x ∷ xs))derun⁺-aux x [] resp Px = here Pxderun⁺-aux x (y ∷ xs) resp Px with R? x y... | true because [Rxy] = derun⁺-aux y xs resp (resp (invert [Rxy]) Px)... | false because _ = here Pxderun⁺ : P Respects R → Any P xs → Any P (derun R? xs)derun⁺ {xs = x ∷ xs} resp (here px) = derun⁺-aux x xs resp pxderun⁺ {xs = x ∷ y ∷ xs} resp (there pxs) with does (R? x y)... | true = derun⁺ resp pxs... | false = there (derun⁺ resp pxs)deduplicate⁺ : ∀ {xs} → P Respects (flip R) → Any P xs → Any P (deduplicate R? xs)deduplicate⁺ {xs = x ∷ xs} resp (here px) = here pxdeduplicate⁺ {xs = x ∷ xs} resp (there pxs)with filter⁺ (¬? ∘ R? x) (deduplicate⁺ resp pxs)... | inj₁ p = there p... | inj₂ ¬¬q =let q = decidable-stable (R? x (Any.lookup (deduplicate⁺ resp pxs))) ¬¬qin here (resp q (lookup-result (deduplicate⁺ resp pxs)))privatederun⁻-aux : Any P (derun R? (x ∷ xs)) → Any P (x ∷ xs)derun⁻-aux {x = x} {[]} (here px) = here pxderun⁻-aux {x = x} {y ∷ _} p[x∷y∷xs] with does (R? x y) | p[x∷y∷xs]... | true | p[y∷xs] = there (derun⁻-aux p[y∷xs])... | false | here px = here px... | false | there p[y∷xs]! = there (derun⁻-aux p[y∷xs]!)derun⁻ : Any P (derun R? xs) → Any P xsderun⁻ {xs = x ∷ xs} p[x∷xs]! = derun⁻-aux p[x∷xs]!deduplicate⁻ : Any P (deduplicate R? xs) → Any P xsdeduplicate⁻ {xs = x ∷ _} (here px) = here pxdeduplicate⁻ {xs = x ∷ _} (there pxs!) = there (deduplicate⁻ (filter⁻ (¬? ∘ R? x) pxs!))-------------------------------------------------------------------------- mapWith∈.module _ {P : B → Set p} wheremapWith∈⁺ : ∀ {xs : List A} (f : ∀ {x} → x ∈ xs → B) →(∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) →Any P (mapWith∈ xs f)mapWith∈⁺ f (_ , here refl , p) = here pmapWith∈⁺ f (_ , there x∈xs , p) =there $ mapWith∈⁺ (f ∘ there) (_ , x∈xs , p)mapWith∈⁻ : ∀ (xs : List A) (f : ∀ {x} → x ∈ xs → B) →Any P (mapWith∈ xs f) →∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)mapWith∈⁻ (y ∷ xs) f (here p) = (y , here refl , p)mapWith∈⁻ (y ∷ xs) f (there p) =Product.map₂ (Product.map there id) $ mapWith∈⁻ xs (f ∘ there) pmapWith∈↔ : ∀ {xs : List A} {f : ∀ {x} → x ∈ xs → B} →(∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) ↔ Any P (mapWith∈ xs f)mapWith∈↔ = mk↔ₛ′ (mapWith∈⁺ _) (mapWith∈⁻ _ _) (to∘from _ _) (from∘to _)wherefrom∘to : ∀ {xs : List A} (f : ∀ {x} → x ∈ xs → B)(p : ∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) →mapWith∈⁻ xs f (mapWith∈⁺ f p) ≡ pfrom∘to f (_ , here refl , p) = reflfrom∘to f (_ , there x∈xs , p)rewrite from∘to (f ∘ there) (_ , x∈xs , p) = reflto∘from : ∀ (xs : List A) (f : ∀ {x} → x ∈ xs → B)(p : Any P (mapWith∈ xs f)) →mapWith∈⁺ f (mapWith∈⁻ xs f p) ≡ pto∘from (y ∷ xs) f (here p) = reflto∘from (y ∷ xs) f (there p) =cong there $ to∘from xs (f ∘ there) p-------------------------------------------------------------------------- reversereverseAcc⁺ : ∀ acc xs → Any P acc ⊎ Any P xs → Any P (reverseAcc acc xs)reverseAcc⁺ acc [] (inj₁ ps) = psreverseAcc⁺ acc (x ∷ xs) (inj₁ ps) = reverseAcc⁺ (x ∷ acc) xs (inj₁ (there ps))reverseAcc⁺ acc (x ∷ xs) (inj₂ (here px)) = reverseAcc⁺ (x ∷ acc) xs (inj₁ (here px))reverseAcc⁺ acc (x ∷ xs) (inj₂ (there y)) = reverseAcc⁺ (x ∷ acc) xs (inj₂ y)reverseAcc⁻ : ∀ acc xs → Any P (reverseAcc acc xs) → Any P acc ⊎ Any P xsreverseAcc⁻ acc [] ps = inj₁ psreverseAcc⁻ acc (x ∷ xs) ps with reverseAcc⁻ (x ∷ acc) xs ps... | inj₁ (here px) = inj₂ (here px)... | inj₁ (there pxs) = inj₁ pxs... | inj₂ pxs = inj₂ (there pxs)reverse⁺ : Any P xs → Any P (reverse xs)reverse⁺ ps = reverseAcc⁺ [] _ (inj₂ ps)reverse⁻ : Any P (reverse xs) → Any P xsreverse⁻ ps with inj₂ pxs ← reverseAcc⁻ [] _ ps = pxs-------------------------------------------------------------------------- purepure⁺ : P x → Any P (pure x)pure⁺ = herepure⁻ : Any P (pure x) → P xpure⁻ (here p) = ppure⁺∘pure⁻ : (p : Any P (pure x)) → pure⁺ (pure⁻ p) ≡ ppure⁺∘pure⁻ (here p) = reflpure⁻∘pure⁺ : (p : P x) → pure⁻ {P = P} (pure⁺ p) ≡ ppure⁻∘pure⁺ p = reflpure↔ : P x ↔ Any P (pure x)pure↔ {P = P} = mk↔ₛ′ pure⁺ pure⁻ pure⁺∘pure⁻ (pure⁻∘pure⁺ {P = P})-------------------------------------------------------------------------- _∷_∷↔ : (P : Pred A p) → (P x ⊎ Any P xs) ↔ Any P (x ∷ xs)∷↔ {x = x} {xs} P =(P x ⊎ Any P xs) ↔⟨ pure↔ ⊎-cong (Any P xs ∎) ⟩(Any P [ x ] ⊎ Any P xs) ↔⟨ ++↔ ⟩Any P (x ∷ xs) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _>>=_module _ {A B : Set ℓ} {P : B → Set p} {f : A → List B} where>>=↔ : Any (Any P ∘ f) xs ↔ Any P (xs >>= f)>>=↔ {xs = xs} =Any (Any P ∘ f) xs ↔⟨ map↔ ⟩Any (Any P) (List.map f xs) ↔⟨ concat↔ ⟩Any P (xs >>= f) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _⊛_⊛↔ : ∀ {P : B → Set ℓ} {fs : List (A → B)} {xs : List A} →Any (λ f → Any (P ∘ f) xs) fs ↔ Any P (fs ⊛ xs)⊛↔ {P = P} {fs} {xs} =Any (λ f → Any (P ∘ f) xs) fs ↔⟨ Any-cong (λ _ → Any-cong (λ _ → pure↔) (_ ∎)) (_ ∎) ⟩Any (λ f → Any (Any P ∘ pure ∘ f) xs) fs ↔⟨ Any-cong (λ _ → >>=↔ ) (_ ∎) ⟩Any (λ f → Any P (xs >>= pure ∘ f)) fs ↔⟨ >>=↔ ⟩Any P (fs >>= λ f → xs >>= λ x → pure (f x)) ≡⟨ cong (Any P) (List.Applicative.unfold-⊛ fs xs) ⟨Any P (fs ⊛ xs) ∎where open Related.EquationalReasoning-- An alternative introduction rule for _⊛_⊛⁺′ : ∀ {P : Pred A ℓ} {Q : Pred B ℓ} {fs : List (A → B)} {xs} →Any (P ⟨→⟩ Q) fs → Any P xs → Any Q (fs ⊛ xs)⊛⁺′ pq p = Inverse.to ⊛↔ (Any.map (λ pq → Any.map (λ {x} → pq {x}) p) pq)-------------------------------------------------------------------------- _⊗_⊗↔ : {P : A × B → Set ℓ} {xs : List A} {ys : List B} →Any (λ x → Any (λ y → P (x , y)) ys) xs ↔ Any P (xs ⊗ ys)⊗↔ {P = P} {xs} {ys} =Any (λ x → Any (λ y → P (x , y)) ys) xs ↔⟨ pure↔ ⟩Any (λ _,_ → Any (λ x → Any (λ y → P (x , y)) ys) xs) (pure _,_) ↔⟨ ⊛↔ ⟩Any (λ x, → Any (P ∘ x,) ys) (pure _,_ ⊛ xs) ↔⟨ ⊛↔ ⟩Any P (pure _,_ ⊛ xs ⊛ ys) ≡⟨ cong (Any P ∘′ (_⊛ ys)) (List.Applicative.unfold-<$> _,_ xs) ⟨Any P (xs ⊗ ys) ∎where open Related.EquationalReasoning⊗↔′ : {P : A → Set ℓ} {Q : B → Set ℓ} {xs : List A} {ys : List B} →(Any P xs × Any Q ys) ↔ Any (P ⟨×⟩ Q) (xs ⊗ ys)⊗↔′ {P = P} {Q} {xs} {ys} =(Any P xs × Any Q ys) ↔⟨ ×↔ ⟩Any (λ x → Any (λ y → P x × Q y) ys) xs ↔⟨ ⊗↔ ⟩Any (P ⟨×⟩ Q) (xs ⊗ ys) ∎where open Related.EquationalReasoningmap-with-∈⁺ = mapWith∈⁺{-# WARNING_ON_USAGE map-with-∈⁺"Warning: map-with-∈⁺ was deprecated in v2.0.Please use mapWith∈⁺ instead."#-}map-with-∈⁻ = mapWith∈⁻{-# WARNING_ON_USAGE map-with-∈⁻"Warning: map-with-∈⁻ was deprecated in v2.0.Please use mapWith∈⁻ instead."#-}map-with-∈↔ = mapWith∈↔{-# WARNING_ON_USAGE map-with-∈↔"Warning: map-with-∈↔ was deprecated in v2.0.Please use mapWith∈↔ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Lists where every pair of elements are related (symmetrically)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_)module Data.List.Relation.Unary.AllPairs{a ℓ} {A : Set a} {R : Rel A ℓ} whereopen import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.Product.Base as Prod using (_,_; _×_; uncurry; <_,_>)open import Function.Base using (id; _∘_)open import Level using (_⊔_)open import Relation.Binary.Definitions as Bopen import Relation.Binary.Construct.Intersection renaming (_∩_ to _∩ᵇ_)open import Relation.Binary.PropositionalEquality.Core using (refl; cong₂)open import Relation.Unary as U renaming (_∩_ to _∩ᵘ_) hiding (_⇒_)open import Relation.Nullary.Decidable as Dec using (_×-dec_; yes; no)-------------------------------------------------------------------------- Definitionopen import Data.List.Relation.Unary.AllPairs.Core public-------------------------------------------------------------------------- Operationshead : ∀ {x xs} → AllPairs R (x ∷ xs) → All (R x) xshead (px ∷ pxs) = pxtail : ∀ {x xs} → AllPairs R (x ∷ xs) → AllPairs R xstail (px ∷ pxs) = pxsuncons : ∀ {x xs} → AllPairs R (x ∷ xs) → All (R x) xs × AllPairs R xsuncons = < head , tail >module _ {q} {S : Rel A q} wheremap : R ⇒ S → AllPairs R ⊆ AllPairs Smap ~₁⇒~₂ [] = []map ~₁⇒~₂ (x~xs ∷ pxs) = All.map ~₁⇒~₂ x~xs ∷ (map ~₁⇒~₂ pxs)module _ {s t} {S : Rel A s} {T : Rel A t} wherezipWith : R ∩ᵇ S ⇒ T → AllPairs R ∩ᵘ AllPairs S ⊆ AllPairs TzipWith f ([] , []) = []zipWith f (px ∷ pxs , qx ∷ qxs) = All.zipWith f (px , qx) ∷ zipWith f (pxs , qxs)unzipWith : T ⇒ R ∩ᵇ S → AllPairs T ⊆ AllPairs R ∩ᵘ AllPairs SunzipWith f [] = [] , []unzipWith f (rx ∷ rxs) = Prod.zip _∷_ _∷_ (All.unzipWith f rx) (unzipWith f rxs)module _ {s} {S : Rel A s} wherezip : AllPairs R ∩ᵘ AllPairs S ⊆ AllPairs (R ∩ᵇ S)zip = zipWith idunzip : AllPairs (R ∩ᵇ S) ⊆ AllPairs R ∩ᵘ AllPairs Sunzip = unzipWith id-------------------------------------------------------------------------- Properties of predicates preserved by AllPairsallPairs? : B.Decidable R → U.Decidable (AllPairs R)allPairs? R? [] = yes []allPairs? R? (x ∷ xs) =Dec.map′ (uncurry _∷_) uncons (All.all? (R? x) xs ×-dec allPairs? R? xs)irrelevant : B.Irrelevant R → U.Irrelevant (AllPairs R)irrelevant irr [] [] = reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =cong₂ _∷_ (All.irrelevant irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : U.Satisfiable (AllPairs R)satisfiable = [] , []
-------------------------------------------------------------------------- The Agda standard library---- Properties related to AllPairs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.AllPairs.Properties whereopen import Data.List.Base using (List; []; _∷_; map; _++_; concat; take; drop;applyUpTo; applyDownFrom; tabulate; filter; catMaybes)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.All.Properties as All using (Any-catMaybes⁺)open import Data.List.Relation.Unary.AllPairs as AllPairs using (AllPairs; []; _∷_)open import Data.Bool.Base using (true; false)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Maybe.Relation.Binary.Pointwise using (pointwise⊆any; Pointwise)open import Data.Fin.Base as F using (Fin)open import Data.Fin.Properties using (suc-injective; <⇒≢)open import Data.Nat.Base using (zero; suc; _<_; z≤n; s≤s; z<s; s<s)open import Data.Nat.Properties using (≤-refl; m<n⇒m<1+n)open import Function.Base using (_∘_; flip)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (DecSetoid)open import Relation.Binary.PropositionalEquality.Core using (_≢_)open import Relation.Unary using (Pred; Decidable; _⊆_)open import Relation.Nullary.Decidable.Core using (does)privatevariablea b c p ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- mapmodule _ {R : Rel A ℓ} {f : B → A} wheremap⁺ : ∀ {xs} → AllPairs (λ x y → R (f x) (f y)) xs →AllPairs R (map f xs)map⁺ [] = []map⁺ (x∉xs ∷ xs!) = All.map⁺ x∉xs ∷ map⁺ xs!-------------------------------------------------------------------------- ++module _ {R : Rel A ℓ} where++⁺ : ∀ {xs ys} → AllPairs R xs → AllPairs R ys →All (λ x → All (R x) ys) xs → AllPairs R (xs ++ ys)++⁺ [] Rys _ = Rys++⁺ (px ∷ Rxs) Rys (Rxys ∷ Rxsys) = All.++⁺ px Rxys ∷ ++⁺ Rxs Rys Rxsys-------------------------------------------------------------------------- concatmodule _ {R : Rel A ℓ} whereconcat⁺ : ∀ {xss} → All (AllPairs R) xss →AllPairs (λ xs ys → All (λ x → All (R x) ys) xs) xss →AllPairs R (concat xss)concat⁺ [] [] = []concat⁺ (pxs ∷ pxss) (Rxsxss ∷ Rxss) = ++⁺ pxs (concat⁺ pxss Rxss)(All.map All.concat⁺ (All.All-swap Rxsxss))-------------------------------------------------------------------------- take and dropmodule _ {R : Rel A ℓ} wheretake⁺ : ∀ {xs} n → AllPairs R xs → AllPairs R (take n xs)take⁺ zero pxs = []take⁺ (suc n) [] = []take⁺ (suc n) (px ∷ pxs) = All.take⁺ n px ∷ take⁺ n pxsdrop⁺ : ∀ {xs} n → AllPairs R xs → AllPairs R (drop n xs)drop⁺ zero pxs = pxsdrop⁺ (suc n) [] = []drop⁺ (suc n) (_ ∷ pxs) = drop⁺ n pxs-------------------------------------------------------------------------- applyUpTomodule _ {R : Rel A ℓ} whereapplyUpTo⁺₁ : ∀ f n → (∀ {i j} → i < j → j < n → R (f i) (f j)) → AllPairs R (applyUpTo f n)applyUpTo⁺₁ f zero Rf = []applyUpTo⁺₁ f (suc n) Rf =All.applyUpTo⁺₁ _ n (Rf (s≤s z≤n) ∘ s≤s) ∷applyUpTo⁺₁ _ n (λ i≤j j<n → Rf (s≤s i≤j) (s≤s j<n))applyUpTo⁺₂ : ∀ f n → (∀ i j → R (f i) (f j)) → AllPairs R (applyUpTo f n)applyUpTo⁺₂ f n Rf = applyUpTo⁺₁ f n (λ _ _ → Rf _ _)-------------------------------------------------------------------------- applyDownFrommodule _ {R : Rel A ℓ} whereapplyDownFrom⁺₁ : ∀ f n → (∀ {i j} → j < i → i < n → R (f i) (f j)) →AllPairs R (applyDownFrom f n)applyDownFrom⁺₁ f zero Rf = []applyDownFrom⁺₁ f (suc n) Rf =All.applyDownFrom⁺₁ _ n (flip Rf ≤-refl) ∷applyDownFrom⁺₁ f n (λ j<i i<n → Rf j<i (m<n⇒m<1+n i<n))applyDownFrom⁺₂ : ∀ f n → (∀ i j → R (f i) (f j)) → AllPairs R (applyDownFrom f n)applyDownFrom⁺₂ f n Rf = applyDownFrom⁺₁ f n (λ _ _ → Rf _ _)-------------------------------------------------------------------------- tabulatemodule _ {R : Rel A ℓ} wheretabulate⁺-< : ∀ {n} {f : Fin n → A} → (∀ {i j} → i F.< j → R (f i) (f j)) →AllPairs R (tabulate f)tabulate⁺-< {zero} fᵢ~fⱼ = []tabulate⁺-< {suc n} fᵢ~fⱼ =All.tabulate⁺ (λ _ → fᵢ~fⱼ z<s) ∷tabulate⁺-< (fᵢ~fⱼ ∘ s<s)tabulate⁺ : ∀ {n} {f : Fin n → A} → (∀ {i j} → i ≢ j → R (f i) (f j)) →AllPairs R (tabulate f)tabulate⁺ fᵢ~fⱼ = tabulate⁺-< (fᵢ~fⱼ ∘ <⇒≢)-------------------------------------------------------------------------- filtermodule _ {R : Rel A ℓ} {P : Pred A p} (P? : Decidable P) wherefilter⁺ : ∀ {xs} → AllPairs R xs → AllPairs R (filter P? xs)filter⁺ {_} [] = []filter⁺ {x ∷ xs} (x∉xs ∷ xs!) with does (P? x)... | false = filter⁺ xs!... | true = All.filter⁺ P? x∉xs ∷ filter⁺ xs!-------------------------------------------------------------------------- catMaybesmodule _ {R : Rel A ℓ} wherecatMaybes⁺ : {xs : List (Maybe A)} → AllPairs (Pointwise R) xs → AllPairs R (catMaybes xs)catMaybes⁺ {xs = []} [] = []catMaybes⁺ {xs = nothing ∷ _} (x∼xs ∷ pxs) = catMaybes⁺ pxscatMaybes⁺ {xs = just x ∷ xs} (x∼xs ∷ pxs) = Any-catMaybes⁺ (All.map pointwise⊆any x∼xs) ∷ catMaybes⁺ pxs
-------------------------------------------------------------------------- The Agda standard library---- Lists where every pair of elements are related (symmetrically)-------------------------------------------------------------------------- Core modules are not meant to be used directly outside of the-- standard library.-- This module should be removable if and when Agda issue-- https://github.com/agda/agda/issues/3210 is fixed{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)module Data.List.Relation.Unary.AllPairs.Core{a ℓ} {A : Set a} (R : Rel A ℓ) whereopen import Levelopen import Data.List.Baseopen import Data.List.Relation.Unary.All-------------------------------------------------------------------------- Definition-- AllPairs R xs means that every pair of elements (x , y) in xs is a-- member of relation R (as long as x comes before y in the list).infixr 5 _∷_data AllPairs : List A → Set (a ⊔ ℓ) where[] : AllPairs []_∷_ : ∀ {x xs} → All (R x) xs → AllPairs xs → AllPairs (x ∷ xs)
-------------------------------------------------------------------------- The Agda standard library---- Lists where all elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.All whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Membership.Propositional renaming (_∈_ to _∈ₚ_)import Data.List.Membership.Setoid as SetoidMembershipopen import Data.Product.Base as Productusing (∃; -,_; _×_; _,_; proj₁; proj₂; uncurry)open import Data.Sum.Base as Sum using (inj₁; inj₂)open import Effect.Applicativeopen import Effect.Monadopen import Function.Base using (_∘_; _∘′_; id; const)open import Level using (Level; _⊔_)open import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Decopen import Relation.Unary hiding (_∈_)import Relation.Unary.Properties as Unaryopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (_Respects_)open import Relation.Binary.PropositionalEquality.Core as ≡import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b p q r ℓ : LevelA : Set aB : Set bP Q R : Pred A px : Axs : List A-------------------------------------------------------------------------- Definitions-- Given a predicate P, then All P xs means that every element in xs-- satisfies P. See `Relation.Unary` for an explanation of predicates.infixr 5 _∷_data All {A : Set a} (P : Pred A p) : Pred (List A) (a ⊔ p) where[] : All P []_∷_ : ∀ {x xs} (px : P x) (pxs : All P xs) → All P (x ∷ xs)-- All P xs is a finite map from indices x ∈ xs to content P x.-- Relation pxs [ i ]= px states that, in map pxs, key i : x ∈ xs points-- to value px.infix 4 _[_]=_data _[_]=_ {A : Set a} {P : Pred A p} :∀ {x xs} → All P xs → x ∈ₚ xs → P x → Set (a ⊔ p) wherehere : ∀ {x xs} {px : P x} {pxs : All P xs} →px ∷ pxs [ here refl ]= pxthere : ∀ {x xs y} {px : P x} {pxs : All P xs} {py : P y} {i : x ∈ₚ xs} →pxs [ i ]= px →py ∷ pxs [ there i ]= px-- A list is empty if having an element is impossible.Null : Pred (List A) _Null = All ∅-------------------------------------------------------------------------- Operations on Alluncons : All P (x ∷ xs) → P x × All P xsuncons (px ∷ pxs) = px , pxshead : All P (x ∷ xs) → P xhead = proj₁ ∘ unconstail : All P (x ∷ xs) → All P xstail = proj₂ ∘ unconsreduce : (f : ∀ {x} → P x → B) → All P xs → List Breduce f [] = []reduce f (px ∷ pxs) = f px ∷ reduce f pxsconstruct : (f : B → ∃ P) (xs : List B) → ∃ (All P)construct f [] = [] , []construct f (x ∷ xs) = Product.zip _∷_ _∷_ (f x) (construct f xs)fromList : (xs : List (∃ P)) → All P (List.map proj₁ xs)fromList [] = []fromList ((x , p) ∷ xps) = p ∷ fromList xpstoList : All P xs → List (∃ P)toList pxs = reduce (λ {x} px → x , px) pxsmap : P ⊆ Q → All P ⊆ All Qmap g [] = []map g (px ∷ pxs) = g px ∷ map g pxszipWith : P ∩ Q ⊆ R → All P ∩ All Q ⊆ All RzipWith f ([] , []) = []zipWith f (px ∷ pxs , qx ∷ qxs) = f (px , qx) ∷ zipWith f (pxs , qxs)unzipWith : R ⊆ P ∩ Q → All R ⊆ All P ∩ All QunzipWith f [] = [] , []unzipWith f (rx ∷ rxs) = Product.zip _∷_ _∷_ (f rx) (unzipWith f rxs)zip : All P ∩ All Q ⊆ All (P ∩ Q)zip = zipWith idunzip : All (P ∩ Q) ⊆ All P ∩ All Qunzip = unzipWith idmodule _(S : Setoid a ℓ) {P : Pred (Setoid.Carrier S) p} whereopen Setoid S renaming (refl to ≈-refl)open SetoidMembership Stabulateₛ : (∀ {x} → x ∈ xs → P x) → All P xstabulateₛ {[]} hyp = []tabulateₛ {_ ∷ _} hyp = hyp (here ≈-refl) ∷ tabulateₛ (hyp ∘ there)tabulate : (∀ {x} → x ∈ₚ xs → P x) → All P xstabulate = tabulateₛ (≡.setoid _)self : ∀ {xs} → All (const A) xsself = tabulate (λ {x} _ → x)-------------------------------------------------------------------------- (weak) updateAtinfixl 6 _[_]%=_ _[_]≔_updateAt : x ∈ₚ xs → (P x → P x) → All P xs → All P xsupdateAt () f []updateAt (here refl) f (px ∷ pxs) = f px ∷ pxsupdateAt (there i) f (px ∷ pxs) = px ∷ updateAt i f pxs_[_]%=_ : All P xs → x ∈ₚ xs → (P x → P x) → All P xspxs [ i ]%= f = updateAt i f pxs_[_]≔_ : All P xs → x ∈ₚ xs → P x → All P xspxs [ i ]≔ px = pxs [ i ]%= const px-------------------------------------------------------------------------- Traversable-like functionsmodule _ (p : Level) {A : Set a} {P : Pred A (a ⊔ p)}{F : Set (a ⊔ p) → Set (a ⊔ p)}(App : RawApplicative F)whereopen RawApplicative AppsequenceA : All (F ∘′ P) ⊆ F ∘′ All PsequenceA [] = pure []sequenceA (x ∷ xs) = _∷_ <$> x <*> sequenceA xsmapA : ∀ {Q : Pred A q} → (Q ⊆ F ∘′ P) → All Q ⊆ (F ∘′ All P)mapA f = sequenceA ∘′ map fforA : ∀ {Q : Pred A q} → All Q xs → (Q ⊆ F ∘′ P) → F (All P xs)forA qxs f = mapA f qxsmodule _ (p : Level) {A : Set a} {P : Pred A (a ⊔ p)}{M : Set (a ⊔ p) → Set (a ⊔ p)}(Mon : RawMonad M)whereprivate App = RawMonad.rawApplicative MonsequenceM : All (M ∘′ P) ⊆ M ∘′ All PsequenceM = sequenceA p AppmapM : ∀ {Q : Pred A q} → (Q ⊆ M ∘′ P) → All Q ⊆ (M ∘′ All P)mapM = mapA p AppforM : ∀ {Q : Pred A q} → All Q xs → (Q ⊆ M ∘′ P) → M (All P xs)forM = forA p App-------------------------------------------------------------------------- Generalised lookup based on a proof of AnylookupAny : All P xs → (i : Any Q xs) → (P ∩ Q) (Any.lookup i)lookupAny (px ∷ pxs) (here qx) = px , qxlookupAny (px ∷ pxs) (there i) = lookupAny pxs ilookupWith : ∀[ P ⇒ Q ⇒ R ] → All P xs → (i : Any Q xs) → R (Any.lookup i)lookupWith f pxs i = Product.uncurry f (lookupAny pxs i)lookup : All P xs → (∀ {x} → x ∈ₚ xs → P x)lookup pxs = lookupWith (λ { px refl → px }) pxsmodule _(S : Setoid a ℓ) {P : Pred (Setoid.Carrier S) p} whereopen Setoid S renaming (sym to ≈-sym)open SetoidMembership Slookupₛ : P Respects _≈_ → All P xs → (∀ {x} → x ∈ xs → P x)lookupₛ resp pxs = lookupWith (λ py x≈y → resp (≈-sym x≈y) py) pxs-------------------------------------------------------------------------- Properties of predicates preserved by Allall? : Decidable P → Decidable (All P)all? p [] = yes []all? p (x ∷ xs) = Dec.map′ (uncurry _∷_) uncons (p x ×-dec all? p xs)universal : Universal P → Universal (All P)universal u [] = []universal u (x ∷ xs) = u x ∷ universal u xsuniversal-U : Universal (All {A = A} U)universal-U = universal Unary.U-Universalirrelevant : Irrelevant P → Irrelevant (All P)irrelevant irr [] [] = ≡.reflirrelevant irr (px₁ ∷ pxs₁) (px₂ ∷ pxs₂) =≡.cong₂ _∷_ (irr px₁ px₂) (irrelevant irr pxs₁ pxs₂)satisfiable : Satisfiable (All P)satisfiable = [] , []-------------------------------------------------------------------------- Generalised decidability proceduredecide : Π[ P ∪ Q ] → Π[ All P ∪ Any Q ]decide p∪q [] = inj₁ []decide p∪q (x ∷ xs) with p∪q x... | inj₂ qx = inj₂ (here qx)... | inj₁ px = Sum.map (px ∷_) there (decide p∪q xs)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4all = all?{-# WARNING_ON_USAGE all"Warning: all was deprecated in v1.4.Please use all? instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties related to All------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Unary.All.Properties whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Bool.Base using (Bool; T; true; false)open import Data.Bool.Properties using (T-∧)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base as List hiding (lookup; updateAt)open import Data.List.Membership.Propositional using (_∈_; _≢∈_)open import Data.List.Membership.Propositional.Propertiesusing (there-injective-≢∈; ∈-filter⁻)import Data.List.Membership.Setoid as SetoidMembershipimport Data.List.Properties as Listimport Data.List.Relation.Binary.Equality.Setoid as ≋open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Data.List.Relation.Binary.Subset.Propositional using (_⊆_)open import Data.List.Relation.Unary.All as All using( All; []; _∷_; lookup; updateAt; _[_]=_; here; there; Null)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.All as Maybe using (just; nothing; fromAny)open import Data.Maybe.Relation.Unary.Any as Maybe using (just)open import Data.Nat.Base using (zero; suc; s≤s; _<_; z<s; s<s)open import Data.Nat.Properties using (≤-refl; m≤n⇒m≤1+n)open import Data.Product.Base as Product using (_×_; _,_; uncurry; uncurry′)open import Function.Base using (_∘_; _$_; id; case_of_; flip)open import Function.Bundles using (_↠_; mk↠ₛ; _⇔_; mk⇔; _↔_; mk↔ₛ′; Equivalence)open import Level using (Level)open import Relation.Binary.Core using (REL)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.Definitions as Bopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; _≗_)open import Relation.Nullary.Reflects using (invert)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Decidableusing (Dec; does; yes; no; _because_; ¬?; decidable-stable)open import Relation.Unaryusing (Decidable; Pred; Universal; ∁; _∩_; _⟨×⟩_) renaming (_⊆_ to _⋐_)open import Relation.Unary.Properties using (∁?)privatevariablea b c p q r ℓ ℓ₁ ℓ₂ : LevelA : Set aB : Set bC : Set cP : Pred A pQ : Pred B qR : Pred C rx y : Axs ys : List A-------------------------------------------------------------------------- Properties regarding NullNull⇒null : Null xs → T (null xs)Null⇒null [] = _null⇒Null : T (null xs) → Null xsnull⇒Null {xs = [] } _ = []null⇒Null {xs = _ ∷ _} ()-------------------------------------------------------------------------- Properties of the "points-to" relation _[_]=_-- Relation _[_]=_ is deterministic: each index points to a single value.[]=-injective : ∀ {px qx : P x} {pxs : All P xs} {i : x ∈ xs} →pxs [ i ]= px →pxs [ i ]= qx →px ≡ qx[]=-injective here here = refl[]=-injective (there x↦px) (there x↦qx) = []=-injective x↦px x↦qx-- See also Data.List.Relation.Unary.All.Properties.WithK.[]=-irrelevant.-------------------------------------------------------------------------- Lemmas relating Any, All and negation.¬Any⇒All¬ : ∀ xs → ¬ Any P xs → All (¬_ ∘ P) xs¬Any⇒All¬ [] ¬p = []¬Any⇒All¬ (x ∷ xs) ¬p = ¬p ∘ here ∷ ¬Any⇒All¬ xs (¬p ∘ there)All¬⇒¬Any : ∀ {xs} → All (¬_ ∘ P) xs → ¬ Any P xsAll¬⇒¬Any (¬p ∷ _) (here p) = ¬p pAll¬⇒¬Any (_ ∷ ¬p) (there p) = All¬⇒¬Any ¬p p¬All⇒Any¬ : Decidable P → ∀ xs → ¬ All P xs → Any (¬_ ∘ P) xs¬All⇒Any¬ dec [] ¬∀ = contradiction [] ¬∀¬All⇒Any¬ dec (x ∷ xs) ¬∀ with dec x... | true because [p] = there (¬All⇒Any¬ dec xs (¬∀ ∘ _∷_ (invert [p])))... | false because [¬p] = here (invert [¬p])Any¬⇒¬All : ∀ {xs} → Any (¬_ ∘ P) xs → ¬ All P xsAny¬⇒¬All (here ¬p) = ¬p ∘ All.headAny¬⇒¬All (there ¬p) = Any¬⇒¬All ¬p ∘ All.tail¬Any↠All¬ : ∀ {xs} → (¬ Any P xs) ↠ All (¬_ ∘ P) xs¬Any↠All¬ = mk↠ₛ {to = ¬Any⇒All¬ _} (λ y → All¬⇒¬Any y , to∘from y)whereto∘from : ∀ {xs} (¬p : All (¬_ ∘ P) xs) → ¬Any⇒All¬ xs (All¬⇒¬Any ¬p) ≡ ¬pto∘from [] = reflto∘from (¬p ∷ ¬ps) = cong₂ _∷_ refl (to∘from ¬ps)-- If equality of functions were extensional, then the surjection-- could be strengthened to a bijection.from∘to : Extensionality _ _ →∀ xs → (¬p : ¬ Any P xs) → All¬⇒¬Any (¬Any⇒All¬ xs ¬p) ≡ ¬pfrom∘to ext [] ¬p = ext λ ()from∘to ext (x ∷ xs) ¬p = ext λ{ (here p) → refl; (there p) → cong (λ f → f p) $ from∘to ext xs (¬p ∘ there)}Any¬⇔¬All : ∀ {xs} → Decidable P → Any (¬_ ∘ P) xs ⇔ (¬ All P xs)Any¬⇔¬All dec = mk⇔ Any¬⇒¬All (¬All⇒Any¬ dec _)private-- If equality of functions were extensional, then the logical-- equivalence could be strengthened to a surjection.to∘from : Extensionality _ _ → (dec : Decidable P) →(¬∀ : ¬ All P xs) → Any¬⇒¬All (¬All⇒Any¬ dec xs ¬∀) ≡ ¬∀to∘from ext P ¬∀ = ext λ ∀P → contradiction ∀P ¬∀module _ {_~_ : REL A B ℓ} whereAll-swap : ∀ {xs ys} →All (λ x → All (x ~_) ys) xs →All (λ y → All (_~ y) xs) ysAll-swap {ys = []} _ = []All-swap {ys = y ∷ ys} [] = All.universal (λ _ → []) (y ∷ ys)All-swap {ys = y ∷ ys} ((x~y ∷ x~ys) ∷ pxs) =(x~y ∷ (All.map All.head pxs)) ∷All-swap (x~ys ∷ (All.map All.tail pxs))-------------------------------------------------------------------------- Defining properties of lookup and _[_]=_---- pxs [ i ]= px if and only if lookup pxs i = px.-- `i` points to `lookup pxs i` in `pxs`.[]=lookup : (pxs : All P xs) (i : x ∈ xs) →pxs [ i ]= lookup pxs i[]=lookup (px ∷ pxs) (here refl) = here[]=lookup (px ∷ pxs) (there i) = there ([]=lookup pxs i)-- If `i` points to `px` in `pxs`, then `lookup pxs i ≡ px`.[]=⇒lookup : ∀ {px : P x} {pxs : All P xs} {i : x ∈ xs} →pxs [ i ]= px →lookup pxs i ≡ px[]=⇒lookup x↦px = []=-injective ([]=lookup _ _) x↦px-- If `lookup pxs i ≡ px`, then `i` points to `px` in `pxs`.lookup⇒[]= : ∀ {px : P x} (pxs : All P xs) (i : x ∈ xs) →lookup pxs i ≡ px →pxs [ i ]= pxlookup⇒[]= pxs i refl = []=lookup pxs i-------------------------------------------------------------------------- Properties of operations over `All`-------------------------------------------------------------------------- mapmap-cong : ∀ {f : P ⋐ Q} {g : P ⋐ Q} (pxs : All P xs) →(∀ {x} → f {x} ≗ g) → All.map f pxs ≡ All.map g pxsmap-cong [] _ = reflmap-cong (px ∷ pxs) feq = cong₂ _∷_ (feq px) (map-cong pxs feq)map-id : ∀ (pxs : All P xs) → All.map id pxs ≡ pxsmap-id [] = reflmap-id (px ∷ pxs) = cong (px ∷_) (map-id pxs)map-∘ : ∀ {f : P ⋐ Q} {g : Q ⋐ R} (pxs : All P xs) →All.map g (All.map f pxs) ≡ All.map (g ∘ f) pxsmap-∘ [] = reflmap-∘ (px ∷ pxs) = cong (_ ∷_) (map-∘ pxs)lookup-map : ∀ {f : P ⋐ Q} (pxs : All P xs) (i : x ∈ xs) →lookup (All.map f pxs) i ≡ f (lookup pxs i)lookup-map (px ∷ pxs) (here refl) = refllookup-map (px ∷ pxs) (there i) = lookup-map pxs i-------------------------------------------------------------------------- _[_]%=_ / updateAt-- Defining properties of updateAt:-- (+) updateAt actually updates the element at the given index.updateAt-updates : ∀ (i : x ∈ xs) {f : P x → P x} {px : P x} (pxs : All P xs) →pxs [ i ]= px →updateAt i f pxs [ i ]= f pxupdateAt-updates (here refl) (px ∷ pxs) here = hereupdateAt-updates (there i) (px ∷ pxs) (there x↦px) =there (updateAt-updates i pxs x↦px)-- (-) updateAt i does not touch the elements at other indices.updateAt-minimal : ∀ (i : x ∈ xs) (j : y ∈ xs) →∀ {f : P y → P y} {px : P x} (pxs : All P xs) →i ≢∈ j →pxs [ i ]= px →updateAt j f pxs [ i ]= pxupdateAt-minimal (here .refl) (here refl) (px ∷ pxs) i≢j here =contradiction refl (i≢j refl)updateAt-minimal (here .refl) (there j) (px ∷ pxs) i≢j here = hereupdateAt-minimal (there i) (here refl) (px ∷ pxs) i≢j (there val) = there valupdateAt-minimal (there i) (there j) (px ∷ pxs) i≢j (there val) =there (updateAt-minimal i j pxs (there-injective-≢∈ i≢j) val)-- lookup after updateAt reduces.-- For same index this is an easy consequence of updateAt-updates-- using []=↔lookup.lookup∘updateAt : ∀ (pxs : All P xs) (i : x ∈ xs) {f : P x → P x} →lookup (updateAt i f pxs) i ≡ f (lookup pxs i)lookup∘updateAt pxs i =[]=⇒lookup (updateAt-updates i pxs (lookup⇒[]= pxs i refl))-- For different indices it easily follows from updateAt-minimal.lookup∘updateAt′ : ∀ (i : x ∈ xs) (j : y ∈ xs) →∀ {f : P y → P y} {px : P x} (pxs : All P xs) →i ≢∈ j →lookup (updateAt j f pxs) i ≡ lookup pxs ilookup∘updateAt′ i j pxs i≢j =[]=⇒lookup (updateAt-minimal i j pxs i≢j (lookup⇒[]= pxs i refl))-- The other properties are consequences of (+) and (-).-- We spell the most natural properties out.-- Direct inductive proofs are in most cases easier than just using-- the defining properties.-- In the explanations, we make use of shorthand f = g ↾ x-- meaning that f and g agree locally at point x, i.e. f x ≡ g x.-- updateAt (i : x ∈ xs) is a morphism-- from the monoid of endofunctions P x → P x-- to the monoid of endofunctions All P xs → All P xs.-- 1a. local identity: f = id ↾ (lookup pxs i)-- implies updateAt i f = id ↾ pxsupdateAt-id-local : ∀ (i : x ∈ xs) {f : P x → P x} (pxs : All P xs) →f (lookup pxs i) ≡ lookup pxs i →updateAt i f pxs ≡ pxsupdateAt-id-local (here refl)(px ∷ pxs) eq = cong (_∷ pxs) equpdateAt-id-local (there i) (px ∷ pxs) eq = cong (px ∷_) (updateAt-id-local i pxs eq)-- 1b. identity: updateAt i id ≗ idupdateAt-id : ∀ (i : x ∈ xs) (pxs : All P xs) → updateAt i id pxs ≡ pxsupdateAt-id i pxs = updateAt-id-local i pxs refl-- 2a. relative composition: f ∘ g = h ↾ (lookup i pxs)-- implies updateAt i f ∘ updateAt i g = updateAt i h ↾ pxsupdateAt-∘-local : ∀ (i : x ∈ xs) {f g h : P x → P x} (pxs : All P xs) →f (g (lookup pxs i)) ≡ h (lookup pxs i) →updateAt i f (updateAt i g pxs) ≡ updateAt i h pxsupdateAt-∘-local (here refl) (px ∷ pxs) fg=h = cong (_∷ pxs) fg=hupdateAt-∘-local (there i) (px ∷ pxs) fg=h = cong (px ∷_) (updateAt-∘-local i pxs fg=h)-- 2b. composition: updateAt i f ∘ updateAt i g ≗ updateAt i (f ∘ g)updateAt-∘ : ∀ (i : x ∈ xs) {f g : P x → P x} →updateAt {P = P} i f ∘ updateAt i g ≗ updateAt i (f ∘ g)updateAt-∘ i pxs = updateAt-∘-local i pxs refl-- 3. congruence: updateAt i is a congruence wrt. extensional equality.-- 3a. If f = g ↾ (lookup pxs i)-- then updateAt i f = updateAt i g ↾ pxsupdateAt-cong-local : ∀ (i : x ∈ xs) {f g : P x → P x} (pxs : All P xs) →f (lookup pxs i) ≡ g (lookup pxs i) →updateAt i f pxs ≡ updateAt i g pxsupdateAt-cong-local (here refl) (px ∷ pxs) f=g = cong (_∷ pxs) f=gupdateAt-cong-local (there i) (px ∷ pxs) f=g = cong (px ∷_) (updateAt-cong-local i pxs f=g)-- 3b. congruence: f ≗ g → updateAt i f ≗ updateAt i gupdateAt-cong : ∀ (i : x ∈ xs) {f g : P x → P x} →f ≗ g → updateAt {P = P} i f ≗ updateAt i gupdateAt-cong i f≗g pxs = updateAt-cong-local i pxs (f≗g (lookup pxs i))-- The order of updates at different indices i ≢ j does not matter.-- This a consequence of updateAt-updates and updateAt-minimal-- but easier to prove inductively.updateAt-commutes : ∀ (i : x ∈ xs) (j : y ∈ xs) →∀ {f : P x → P x} {g : P y → P y} →i ≢∈ j →updateAt {P = P} i f ∘ updateAt j g ≗ updateAt j g ∘ updateAt i fupdateAt-commutes (here refl) (here refl) i≢j (px ∷ pxs) =contradiction refl (i≢j refl)updateAt-commutes (here refl) (there j) i≢j (px ∷ pxs) = reflupdateAt-commutes (there i) (here refl) i≢j (px ∷ pxs) = reflupdateAt-commutes (there i) (there j) i≢j (px ∷ pxs) =cong (px ∷_) (updateAt-commutes i j (there-injective-≢∈ i≢j) pxs)map-updateAt : ∀ {f : P ⋐ Q} {g : P x → P x} {h : Q x → Q x}(pxs : All P xs) (i : x ∈ xs) →f (g (lookup pxs i)) ≡ h (f (lookup pxs i)) →All.map f (pxs All.[ i ]%= g) ≡ (All.map f pxs) All.[ i ]%= hmap-updateAt (px ∷ pxs) (here refl) = cong (_∷ _)map-updateAt (px ∷ pxs) (there i) feq = cong (_ ∷_) (map-updateAt pxs i feq)-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- singletonsingleton⁻ : All P [ x ] → P xsingleton⁻ (px ∷ []) = px-- headhead⁺ : All P xs → Maybe.All P (head xs)head⁺ [] = nothinghead⁺ (px ∷ _) = just px-- tailtail⁺ : All P xs → Maybe.All (All P) (tail xs)tail⁺ [] = nothingtail⁺ (_ ∷ pxs) = just pxs-- lastlast⁺ : All P xs → Maybe.All P (last xs)last⁺ [] = nothinglast⁺ (px ∷ []) = just pxlast⁺ (px ∷ pxs@(_ ∷ _)) = last⁺ pxs-- unconsuncons⁺ : All P xs → Maybe.All (P ⟨×⟩ All P) (uncons xs)uncons⁺ [] = nothinguncons⁺ (px ∷ pxs) = just (px , pxs)uncons⁻ : Maybe.All (P ⟨×⟩ All P) (uncons xs) → All P xsuncons⁻ {xs = []} nothing = []uncons⁻ {xs = x ∷ xs} (just (px , pxs)) = px ∷ pxs-- mapmap⁺ : ∀ {f : A → B} → All (P ∘ f) xs → All P (map f xs)map⁺ [] = []map⁺ (p ∷ ps) = p ∷ map⁺ psmap⁻ : ∀ {f : A → B} → All P (map f xs) → All (P ∘ f) xsmap⁻ {xs = []} [] = []map⁻ {xs = _ ∷ _} (p ∷ ps) = p ∷ map⁻ ps-- A variant of All.map.gmap⁺ : ∀ {f : A → B} → P ⋐ Q ∘ f → All P ⋐ All Q ∘ map fgmap⁺ g = map⁺ ∘ All.map ggmap⁻ : ∀ {f : A → B} → Q ∘ f ⋐ P → All Q ∘ map f ⋐ All Pgmap⁻ g = All.map g ∘ map⁻-------------------------------------------------------------------------- mapMaybemapMaybe⁺ : ∀ {f : A → Maybe B} →All (Maybe.All P) (map f xs) → All P (mapMaybe f xs)mapMaybe⁺ {xs = []} {f = f} [] = []mapMaybe⁺ {xs = x ∷ xs} {f = f} (px ∷ pxs) with f x... | nothing = mapMaybe⁺ pxs... | just v with just pv ← px = pv ∷ mapMaybe⁺ pxs-------------------------------------------------------------------------- catMaybesAll-catMaybes⁺ : All (Maybe.All P) xs → All P (catMaybes xs)All-catMaybes⁺ [] = []All-catMaybes⁺ (just px ∷ pxs) = px ∷ All-catMaybes⁺ pxsAll-catMaybes⁺ (nothing ∷ pxs) = All-catMaybes⁺ pxsAny-catMaybes⁺ : All (Maybe.Any P) xs → All P (catMaybes xs)Any-catMaybes⁺ = All-catMaybes⁺ ∘ All.map fromAny-------------------------------------------------------------------------- _++_++⁺ : All P xs → All P ys → All P (xs ++ ys)++⁺ [] pys = pys++⁺ (px ∷ pxs) pys = px ∷ ++⁺ pxs pys++⁻ˡ : ∀ xs {ys} → All P (xs ++ ys) → All P xs++⁻ˡ [] p = []++⁻ˡ (x ∷ xs) (px ∷ pxs) = px ∷ (++⁻ˡ _ pxs)++⁻ʳ : ∀ xs {ys} → All P (xs ++ ys) → All P ys++⁻ʳ [] p = p++⁻ʳ (x ∷ xs) (px ∷ pxs) = ++⁻ʳ xs pxs++⁻ : ∀ xs {ys} → All P (xs ++ ys) → All P xs × All P ys++⁻ [] p = [] , p++⁻ (x ∷ xs) (px ∷ pxs) = Product.map (px ∷_) id (++⁻ _ pxs)++↔ : (All P xs × All P ys) ↔ All P (xs ++ ys)++↔ {xs = zs} = mk↔ₛ′ (uncurry ++⁺) (++⁻ zs) (++⁺∘++⁻ zs) ++⁻∘++⁺where++⁺∘++⁻ : ∀ xs (p : All P (xs ++ ys)) → uncurry′ ++⁺ (++⁻ xs p) ≡ p++⁺∘++⁻ [] p = refl++⁺∘++⁻ (x ∷ xs) (px ∷ pxs) = cong (_∷_ px) $ ++⁺∘++⁻ xs pxs++⁻∘++⁺ : ∀ (p : All P xs × All P ys) → ++⁻ xs (uncurry ++⁺ p) ≡ p++⁻∘++⁺ ([] , pys) = refl++⁻∘++⁺ (px ∷ pxs , pys) rewrite ++⁻∘++⁺ (pxs , pys) = refl-------------------------------------------------------------------------- concatconcat⁺ : ∀ {xss} → All (All P) xss → All P (concat xss)concat⁺ [] = []concat⁺ (pxs ∷ pxss) = ++⁺ pxs (concat⁺ pxss)concat⁻ : ∀ {xss} → All P (concat xss) → All (All P) xssconcat⁻ {xss = []} [] = []concat⁻ {xss = xs ∷ xss} pxs = ++⁻ˡ xs pxs ∷ concat⁻ (++⁻ʳ xs pxs)-------------------------------------------------------------------------- snoc∷ʳ⁺ : All P xs → P x → All P (xs ∷ʳ x)∷ʳ⁺ pxs px = ++⁺ pxs (px ∷ [])∷ʳ⁻ : All P (xs ∷ʳ x) → All P xs × P x∷ʳ⁻ pxs = Product.map₂ singleton⁻ $ ++⁻ _ pxs-- unsnocunsnoc⁺ : All P xs → Maybe.All (All P ⟨×⟩ P) (unsnoc xs)unsnoc⁺ {xs = xs} pxs with initLast xsunsnoc⁺ {xs = .[]} pxs | [] = nothingunsnoc⁺ {xs = .(xs ∷ʳ x)} pxs | xs ∷ʳ′ x = just (∷ʳ⁻ pxs)unsnoc⁻ : Maybe.All (All P ⟨×⟩ P) (unsnoc xs) → All P xsunsnoc⁻ {xs = xs} pxs with initLast xsunsnoc⁻ {xs = .[]} nothing | [] = []unsnoc⁻ {xs = .(xs ∷ʳ x)} (just (pxs , px)) | xs ∷ʳ′ x = ∷ʳ⁺ pxs px-------------------------------------------------------------------------- cartesianProductWith and cartesianProductmodule _ (S₁ : Setoid a ℓ₁) (S₂ : Setoid b ℓ₂) whereopen SetoidMembership S₁ using () renaming (_∈_ to _∈₁_)open SetoidMembership S₂ using () renaming (_∈_ to _∈₂_)cartesianProductWith⁺ : ∀ f xs ys →(∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (f x y)) →All P (cartesianProductWith f xs ys)cartesianProductWith⁺ f [] ys pres = []cartesianProductWith⁺ f (x ∷ xs) ys pres = ++⁺(map⁺ (All.tabulateₛ S₂ (pres (here (Setoid.refl S₁)))))(cartesianProductWith⁺ f xs ys (pres ∘ there))cartesianProduct⁺ : ∀ xs ys →(∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (x , y)) →All P (cartesianProduct xs ys)cartesianProduct⁺ = cartesianProductWith⁺ _,_-------------------------------------------------------------------------- take and dropdrop⁺ : ∀ n → All P xs → All P (drop n xs)drop⁺ zero pxs = pxsdrop⁺ (suc n) [] = []drop⁺ (suc n) (px ∷ pxs) = drop⁺ n pxsdropWhile⁺ : (Q? : Decidable Q) → All P xs → All P (dropWhile Q? xs)dropWhile⁺ Q? [] = []dropWhile⁺ {xs = x ∷ xs} Q? (px ∷ pxs) with does (Q? x)... | true = dropWhile⁺ Q? pxs... | false = px ∷ pxsdropWhile⁻ : (P? : Decidable P) → dropWhile P? xs ≡ [] → All P xsdropWhile⁻ {xs = []} P? eq = []dropWhile⁻ {xs = x ∷ xs} P? eq with P? x... | yes px = px ∷ (dropWhile⁻ P? eq)... | no ¬px = case eq of λ ()all-head-dropWhile : (P? : Decidable P) →∀ xs → Maybe.All (∁ P) (head (dropWhile P? xs))all-head-dropWhile P? [] = nothingall-head-dropWhile P? (x ∷ xs) with P? x... | yes px = all-head-dropWhile P? xs... | no ¬px = just ¬pxtake⁺ : ∀ n → All P xs → All P (take n xs)take⁺ zero pxs = []take⁺ (suc n) [] = []take⁺ (suc n) (px ∷ pxs) = px ∷ take⁺ n pxstakeWhile⁺ : (Q? : Decidable Q) → All P xs → All P (takeWhile Q? xs)takeWhile⁺ Q? [] = []takeWhile⁺ {xs = x ∷ xs} Q? (px ∷ pxs) with does (Q? x)... | true = px ∷ takeWhile⁺ Q? pxs... | false = []takeWhile⁻ : (P? : Decidable P) → takeWhile P? xs ≡ xs → All P xstakeWhile⁻ {xs = []} P? eq = []takeWhile⁻ {xs = x ∷ xs} P? eq with P? x... | yes px = px ∷ takeWhile⁻ P? (List.∷-injectiveʳ eq)... | no ¬px = case eq of λ ()all-takeWhile : (P? : Decidable P) → ∀ xs → All P (takeWhile P? xs)all-takeWhile P? [] = []all-takeWhile P? (x ∷ xs) with P? x... | yes px = px ∷ all-takeWhile P? xs... | no ¬px = []-------------------------------------------------------------------------- applyUpToapplyUpTo⁺₁ : ∀ f n → (∀ {i} → i < n → P (f i)) → All P (applyUpTo f n)applyUpTo⁺₁ f zero Pf = []applyUpTo⁺₁ f (suc n) Pf = Pf z<s ∷ applyUpTo⁺₁ (f ∘ suc) n (Pf ∘ s<s)applyUpTo⁺₂ : ∀ f n → (∀ i → P (f i)) → All P (applyUpTo f n)applyUpTo⁺₂ f n Pf = applyUpTo⁺₁ f n (λ _ → Pf _)applyUpTo⁻ : ∀ f n → All P (applyUpTo f n) → ∀ {i} → i < n → P (f i)applyUpTo⁻ f (suc n) (px ∷ _) z<s = pxapplyUpTo⁻ f (suc n) (_ ∷ pxs) (s<s i<n@(s≤s _)) =applyUpTo⁻ (f ∘ suc) n pxs i<n-------------------------------------------------------------------------- upToall-upTo : ∀ n → All (_< n) (upTo n)all-upTo n = applyUpTo⁺₁ id n id-------------------------------------------------------------------------- applyDownFromapplyDownFrom⁺₁ : ∀ f n → (∀ {i} → i < n → P (f i)) → All P (applyDownFrom f n)applyDownFrom⁺₁ f zero Pf = []applyDownFrom⁺₁ f (suc n) Pf = Pf ≤-refl ∷ applyDownFrom⁺₁ f n (Pf ∘ m≤n⇒m≤1+n)applyDownFrom⁺₂ : ∀ f n → (∀ i → P (f i)) → All P (applyDownFrom f n)applyDownFrom⁺₂ f n Pf = applyDownFrom⁺₁ f n (λ _ → Pf _)-------------------------------------------------------------------------- tabulatetabulate⁺ : ∀ {n} {f : Fin n → A} →(∀ i → P (f i)) → All P (tabulate f)tabulate⁺ {n = zero} Pf = []tabulate⁺ {n = suc _} Pf = Pf zero ∷ tabulate⁺ (Pf ∘ suc)tabulate⁻ : ∀ {n} {f : Fin n → A} →All P (tabulate f) → (∀ i → P (f i))tabulate⁻ (px ∷ _) zero = pxtabulate⁻ (_ ∷ pf) (suc i) = tabulate⁻ pf i-------------------------------------------------------------------------- remove─⁺ : ∀ (p : Any P xs) → All Q xs → All Q (xs Any.─ p)─⁺ (here px) (_ ∷ qs) = qs─⁺ (there p) (q ∷ qs) = q ∷ ─⁺ p qs─⁻ : ∀ (p : Any P xs) → Q (Any.lookup p) → All Q (xs Any.─ p) → All Q xs─⁻ (here px) q qs = q ∷ qs─⁻ (there p) q (q′ ∷ qs) = q′ ∷ ─⁻ p q qs-------------------------------------------------------------------------- filtermodule _ (P? : Decidable P) whereall-filter : ∀ xs → All P (filter P? xs)all-filter [] = []all-filter (x ∷ xs) with P? x... | true because [Px] = invert [Px] ∷ all-filter xs... | false because _ = all-filter xsfilter⁺ : All Q xs → All Q (filter P? xs)filter⁺ {xs = _} [] = []filter⁺ {xs = x ∷ _} (Qx ∷ Qxs) with does (P? x)... | false = filter⁺ Qxs... | true = Qx ∷ filter⁺ Qxsfilter⁻ : All Q (filter P? xs) → All Q (filter (¬? ∘ P?) xs) → All Q xsfilter⁻ {xs = []} [] [] = []filter⁻ {xs = x ∷ _} all⁺ all⁻ with P? x | ¬? (P? x)filter⁻ {xs = x ∷ _} all⁺ all⁻ | yes Px | yes ¬Px = contradiction Px ¬Pxfilter⁻ {xs = x ∷ _} (qx ∷ all⁺) all⁻ | yes Px | no ¬¬Px = qx ∷ filter⁻ all⁺ all⁻filter⁻ {xs = x ∷ _} all⁺ (qx ∷ all⁻) | no _ | yes ¬Px = qx ∷ filter⁻ all⁺ all⁻filter⁻ {xs = x ∷ _} all⁺ all⁻ | no ¬Px | no ¬¬Px = contradiction ¬Px ¬¬Px-------------------------------------------------------------------------- partitionmodule _ {P : A → Set p} (P? : Decidable P) wherepartition-All : ∀ xs → (let ys , zs = partition P? xs) →All P ys × All (∁ P) zspartition-All xs rewrite List.partition-defn P? xs =all-filter P? xs , all-filter (∁? P?) xs-------------------------------------------------------------------------- derun and deduplicatemodule _ {R : A → A → Set q} (R? : B.Decidable R) wherederun⁺ : All P xs → All P (derun R? xs)derun⁺ {xs = []} [] = []derun⁺ {xs = x ∷ []} (px ∷ []) = px ∷ []derun⁺ {xs = x ∷ y ∷ xs} (px ∷ all[P,y∷xs]) with does (R? x y)... | false = px ∷ derun⁺ all[P,y∷xs]... | true = derun⁺ all[P,y∷xs]deduplicate⁺ : All P xs → All P (deduplicate R? xs)deduplicate⁺ [] = []deduplicate⁺ (px ∷ pxs) = px ∷ filter⁺ (¬? ∘ R? _) (deduplicate⁺ pxs)derun⁻ : P B.Respects (flip R) → ∀ xs → All P (derun R? xs) → All P xsderun⁻ {P = P} P-resp-R [] [] = []derun⁻ {P = P} P-resp-R (x ∷ xs) all[P,x∷xs] = aux x xs all[P,x∷xs]whereaux : ∀ x xs → All P (derun R? (x ∷ xs)) → All P (x ∷ xs)aux x [] (px ∷ []) = px ∷ []aux x (y ∷ xs) all[P,x∷y∷xs] with R? x yaux x (y ∷ xs) all[P,y∷xs] | yes Rxywith r@(py ∷ _) ← aux y xs all[P,y∷xs] = P-resp-R Rxy py ∷ raux x (y ∷ xs) (px ∷ all[P,y∷xs]) | no _ = px ∷ aux y xs all[P,y∷xs]deduplicate⁻ : P B.Respects R → ∀ xs → All P (deduplicate R? xs) → All P xsdeduplicate⁻ {P = P} resp [] [] = []deduplicate⁻ {P = P} resp (x ∷ xs) (px ∷ pxs!) =px ∷ deduplicate⁻ resp xs (filter⁻ (¬? ∘ R? x) pxs! (All.tabulate aux))whereaux : ∀ {z} → z ∈ filter (¬? ∘ ¬? ∘ R? x) (deduplicate R? xs) → P zaux {z = z} z∈filter = resp (decidable-stable (R? x z)(Product.proj₂ (∈-filter⁻ (¬? ∘ ¬? ∘ R? x) {z} {deduplicate R? xs} z∈filter))) px-------------------------------------------------------------------------- zipWithzipWith⁺ : ∀ (f : A → B → C) → Pointwise (λ x y → P (f x y)) xs ys →All P (zipWith f xs ys)zipWith⁺ f [] = []zipWith⁺ f (Pfxy ∷ Pfxsys) = Pfxy ∷ zipWith⁺ f Pfxsys-------------------------------------------------------------------------- Operations for constructing lists-------------------------------------------------------------------------- fromMaybefromMaybe⁺ : ∀ {mx} → Maybe.All P mx → All P (fromMaybe mx)fromMaybe⁺ (just px) = px ∷ []fromMaybe⁺ nothing = []fromMaybe⁻ : ∀ mx → All P (fromMaybe mx) → Maybe.All P mxfromMaybe⁻ (just x) (px ∷ []) = just pxfromMaybe⁻ nothing p = nothing-------------------------------------------------------------------------- replicatereplicate⁺ : ∀ n → P x → All P (replicate n x)replicate⁺ zero px = []replicate⁺ (suc n) px = px ∷ replicate⁺ n pxreplicate⁻ : ∀ {n} → All P (replicate (suc n) x) → P xreplicate⁻ (px ∷ _) = px-------------------------------------------------------------------------- initsinits⁺ : All P xs → All (All P) (inits xs)inits⁺ [] = [] ∷ []inits⁺ (px ∷ pxs) = [] ∷ gmap⁺ (px ∷_) (inits⁺ pxs)inits⁻ : ∀ xs → All (All P) (inits xs) → All P xsinits⁻ [] pxs = []inits⁻ (x ∷ []) ([] ∷ p[x] ∷ []) = p[x]inits⁻ (x ∷ xs@(_ ∷ _)) ([] ∷ pxs@(p[x] ∷ _)) =singleton⁻ p[x] ∷ inits⁻ xs (All.map (drop⁺ 1) (map⁻ pxs))-------------------------------------------------------------------------- tailstails⁺ : All P xs → All (All P) (tails xs)tails⁺ [] = [] ∷ []tails⁺ pxxs@(_ ∷ pxs) = pxxs ∷ tails⁺ pxstails⁻ : ∀ xs → All (All P) (tails xs) → All P xstails⁻ [] pxs = []tails⁻ (x ∷ xs) (pxxs ∷ _) = pxxs-------------------------------------------------------------------------- allmodule _ (p : A → Bool) whereall⁺ : ∀ xs → T (all p xs) → All (T ∘ p) xsall⁺ [] _ = []all⁺ (x ∷ xs) px∷pxs =let px , pxs = Equivalence.to (T-∧ {p x}) px∷pxsin px ∷ all⁺ xs pxsall⁻ : All (T ∘ p) xs → T (all p xs)all⁻ [] = _all⁻ (px ∷ pxs) = Equivalence.from T-∧ (px , all⁻ pxs)-------------------------------------------------------------------------- All is anti-monotone.anti-mono : xs ⊆ ys → All P ys → All P xsanti-mono xs⊆ys pys = All.tabulate (lookup pys ∘ xs⊆ys)all-anti-mono : ∀ (p : A → Bool) → xs ⊆ ys → T (all p ys) → T (all p xs)all-anti-mono p xs⊆ys = all⁻ p ∘ anti-mono xs⊆ys ∘ all⁺ p _-------------------------------------------------------------------------- Interactions with pointwise equality------------------------------------------------------------------------module _ (S : Setoid c ℓ) whereopen Setoid Sopen ≋ Srespects : P B.Respects _≈_ → (All P) B.Respects _≋_respects p≈ [] [] = []respects p≈ (x≈y ∷ xs≈ys) (px ∷ pxs) = p≈ x≈y px ∷ respects p≈ xs≈ys pxs-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.3Any¬→¬All = Any¬⇒¬All{-# WARNING_ON_USAGE Any¬→¬All"Warning: Any¬→¬All was deprecated in v1.3.Please use Any¬⇒¬All instead."#-}-- Version 2.0updateAt-id-relative = updateAt-id-local{-# WARNING_ON_USAGE updateAt-id-relative"Warning: updateAt-id-relative was deprecated in v2.0.Please use updateAt-id-local instead."#-}updateAt-compose-relative = updateAt-∘-local{-# WARNING_ON_USAGE updateAt-compose-relative"Warning: updateAt-compose-relative was deprecated in v2.0.Please use updateAt-∘-local instead."#-}updateAt-compose = updateAt-∘{-# WARNING_ON_USAGE updateAt-compose"Warning: updateAt-compose was deprecated in v2.0.Please use updateAt-∘ instead."#-}updateAt-cong-relative = updateAt-cong-local{-# WARNING_ON_USAGE updateAt-cong-relative"Warning: updateAt-cong-relative was deprecated in v2.0.Please use updateAt-cong-local instead."#-}gmap = gmap⁺{-# WARNING_ON_USAGE gmap"Warning: gmap was deprecated in v2.0.Please use gmap⁺ instead."#-}-- Version 2.1map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.1.Please use map-∘ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Generalised notion of interleaving two lists into one in an-- order-preserving manner------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Interleaving whereopen import Levelopen import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Data.Product.Base as Product using (∃; ∃₂; _×_; uncurry; _,_; -,_; proj₂)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Baseopen import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)-------------------------------------------------------------------------- Definitionmodule _ {a b c l r} {A : Set a} {B : Set b} {C : Set c}(L : REL A C l) (R : REL B C r) whereinfixr 5 _∷ˡ_ _∷ʳ_data Interleaving : List A → List B → List C → Set (a ⊔ b ⊔ c ⊔ l ⊔ r) where[] : Interleaving [] [] []_∷ˡ_ : ∀ {a c l r cs} → L a c → Interleaving l r cs → Interleaving (a ∷ l) r (c ∷ cs)_∷ʳ_ : ∀ {b c l r cs} → R b c → Interleaving l r cs → Interleaving l (b ∷ r) (c ∷ cs)-------------------------------------------------------------------------- Operationsmodule _ {a b c l r} {A : Set a} {B : Set b} {C : Set c}{L : REL A C l} {R : REL B C r} where-- injectionsleft : ∀ {as cs} → Pointwise L as cs → Interleaving L R as [] csleft [] = []left (l ∷ pw) = l ∷ˡ left pwright : ∀ {bs cs} → Pointwise R bs cs → Interleaving L R [] bs csright [] = []right (r ∷ pw) = r ∷ʳ right pw-- swapswap : ∀ {cs l r} → Interleaving L R l r cs → Interleaving R L r l csswap [] = []swap (l ∷ˡ sp) = l ∷ʳ swap spswap (r ∷ʳ sp) = r ∷ˡ swap sp-- extract the "proper" equality split from the pointwise relationsbreak : ∀ {cs l r} → Interleaving L R l r cs → ∃ $ uncurry $ λ csl csr →Interleaving _≡_ _≡_ csl csr cs × Pointwise L l csl × Pointwise R r csrbreak [] = -, [] , [] , []break (l ∷ˡ sp) = let (_ , eq , pwl , pwr) = break sp in-, refl ∷ˡ eq , l ∷ pwl , pwrbreak (r ∷ʳ sp) = let (_ , eq , pwl , pwr) = break sp in-, refl ∷ʳ eq , pwl , r ∷ pwr-- mapmodule _ {a b c l r p q} {A : Set a} {B : Set b} {C : Set c}{L : REL A C l} {R : REL B C r} {P : REL A C p} {Q : REL B C q} wheremap : ∀ {cs l r} → L ⇒ P → R ⇒ Q → Interleaving L R l r cs → Interleaving P Q l r csmap L⇒P R⇒Q [] = []map L⇒P R⇒Q (l ∷ˡ sp) = L⇒P l ∷ˡ map L⇒P R⇒Q spmap L⇒P R⇒Q (r ∷ʳ sp) = R⇒Q r ∷ʳ map L⇒P R⇒Q spmodule _ {a b c l r p} {A : Set a} {B : Set b} {C : Set c}{L : REL A C l} {R : REL B C r} wheremap₁ : ∀ {P : REL A C p} {as l r} → L ⇒ P →Interleaving L R l r as → Interleaving P R l r asmap₁ L⇒P = map L⇒P idmap₂ : ∀ {P : REL B C p} {as l r} → R ⇒ P →Interleaving L R l r as → Interleaving L P l r asmap₂ = map id-------------------------------------------------------------------------- Special case: The second and third list have the same typemodule _ {a b l r} {A : Set a} {B : Set b} {L : REL A B l} {R : REL A B r} where-- converting back and forth with pointwisesplit : ∀ {as bs} → Pointwise (λ a b → L a b ⊎ R a b) as bs →∃₂ λ asr asl → Interleaving L R asl asr bssplit [] = [] , [] , []split (inj₁ l ∷ pw) = Product.map _ (Product.map _ (l ∷ˡ_)) (split pw)split (inj₂ r ∷ pw) = Product.map _ (Product.map _ (r ∷ʳ_)) (split pw)unsplit : ∀ {l r as} → Interleaving L R l r as →∃ λ bs → Pointwise (λ a b → L a b ⊎ R a b) bs asunsplit [] = -, []unsplit (l ∷ˡ sp) = Product.map _ (inj₁ l ∷_) (unsplit sp)unsplit (r ∷ʳ sp) = Product.map _ (inj₂ r ∷_) (unsplit sp)
-------------------------------------------------------------------------- The Agda standard library---- Interleavings of lists using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Ternary.Interleaving.Setoid {c ℓ} (S : Setoid c ℓ) whereopen import Level using (_⊔_)open import Data.List.Base as List using (List)import Data.List.Relation.Ternary.Interleaving as Generalopen Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- DefinitionInterleaving : List A → List A → List A → Set (c ⊔ ℓ)Interleaving = General.Interleaving _≈_ _≈_-------------------------------------------------------------------------- Re-export the basic combinatorsopen General hiding (Interleaving) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of interleaving using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Ternary.Interleaving.Setoid.Properties{c ℓ} (S : Setoid c ℓ) whereopen import Data.List.Base using (List; []; _∷_; filter; _++_)open import Data.Bool.Base using (true; false)open import Relation.Unary using (Decidable)open import Relation.Nullary.Decidable using (does)open import Relation.Nullary.Decidable using (¬?)open import Function.Base using (_∘_)open import Data.List.Relation.Binary.Equality.Setoid S using (≋-refl)open import Data.List.Relation.Ternary.Interleaving.Setoid Sopen Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Re-exporting existing propertiesopen import Data.List.Relation.Ternary.Interleaving.Properties public-------------------------------------------------------------------------- _++_++-linear : (xs ys : List A) → Interleaving xs ys (xs ++ ys)++-linear xs ys = ++-disjoint (left ≋-refl) (right ≋-refl)-------------------------------------------------------------------------- filtermodule _ {p} {P : A → Set p} (P? : Decidable P) wherefilter⁺ : ∀ xs → Interleaving (filter P? xs) (filter (¬? ∘ P?) xs) xsfilter⁺ [] = []filter⁺ (x ∷ xs) with does (P? x)... | true = refl ∷ˡ filter⁺ xs... | false = refl ∷ʳ filter⁺ xs
-------------------------------------------------------------------------- The Agda standard library---- Interleavings of lists using propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Interleaving.Propositional {a} {A : Set a} whereopen import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.Relation.Binary.Permutation.Propositional as Perm using (_↭_)open import Data.List.Relation.Binary.Permutation.Propositional.Properties using (shift)import Data.List.Relation.Ternary.Interleaving.Setoid as Generalopen import Relation.Binary.PropositionalEquality.Core using (refl)open import Relation.Binary.PropositionalEquality.Properties using (setoid)open Perm.PermutationReasoning-------------------------------------------------------------------------- Re-export the basic combinatorsopen General hiding (Interleaving) public-------------------------------------------------------------------------- DefinitionInterleaving : List A → List A → List A → Set aInterleaving = General.Interleaving (setoid A)pattern consˡ xs = refl ∷ˡ xspattern consʳ xs = refl ∷ʳ xs-------------------------------------------------------------------------- New combinatorstoPermutation : ∀ {l r as} → Interleaving l r as → as ↭ l ++ rtoPermutation [] = Perm.refltoPermutation (consˡ sp) = Perm.prep _ (toPermutation sp)toPermutation {l} {r ∷ rs} {a ∷ as} (consʳ sp) = begina ∷ as ↭⟨ Perm.prep a (toPermutation sp) ⟩a ∷ l ++ rs ↭⟨ Perm.↭-sym (shift a l rs) ⟩l ++ a ∷ rs ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties of interleaving using propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Interleaving.Propositional.Properties{a} {A : Set a} whereimport Data.List.Relation.Ternary.Interleaving.Setoid.Propertiesas SetoidPropertiesopen import Relation.Binary.PropositionalEquality.Properties using (setoid)-------------------------------------------------------------------------- Re-exporting existing propertiesopen SetoidProperties (setoid A) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of general interleavings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Interleaving.Properties whereopen import Data.Nat.Baseopen import Data.Nat.Properties using (+-suc)open import Data.List.Base hiding (_∷ʳ_)open import Data.List.Properties using (reverse-involutive)open import Data.List.Relation.Ternary.Interleaving hiding (map)open import Function.Base using (_$_)open import Relation.Binary.Core using (REL)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoning-------------------------------------------------------------------------- lengthmodule _ {a b c l r} {A : Set a} {B : Set b} {C : Set c}{L : REL A C l} {R : REL B C r} whereinterleave-length : ∀ {as l r} → Interleaving L R l r as →length as ≡ length l + length rinterleave-length [] = reflinterleave-length (l ∷ˡ sp) = cong suc (interleave-length sp)interleave-length {as} {l} {r ∷ rs} (_ ∷ʳ sp) = beginlength as ≡⟨ cong suc (interleave-length sp) ⟩suc (length l + length rs) ≡⟨ sym $ +-suc _ _ ⟩length l + length (r ∷ rs) ∎-------------------------------------------------------------------------- _++_++⁺ : ∀ {as₁ as₂ l₁ l₂ r₁ r₂} →Interleaving L R as₁ l₁ r₁ →Interleaving L R as₂ l₂ r₂ →Interleaving L R (as₁ ++ as₂) (l₁ ++ l₂) (r₁ ++ r₂)++⁺ [] sp₂ = sp₂++⁺ (l ∷ˡ sp₁) sp₂ = l ∷ˡ (++⁺ sp₁ sp₂)++⁺ (r ∷ʳ sp₁) sp₂ = r ∷ʳ (++⁺ sp₁ sp₂)++-disjoint : ∀ {as₁ as₂ l₁ r₂} →Interleaving L R l₁ [] as₁ →Interleaving L R [] r₂ as₂ →Interleaving L R l₁ r₂ (as₁ ++ as₂)++-disjoint [] sp₂ = sp₂++-disjoint (l ∷ˡ sp₁) sp₂ = l ∷ˡ ++-disjoint sp₁ sp₂-------------------------------------------------------------------------- mapmodule _ {a b c d e f l r}{A : Set a} {B : Set b} {C : Set c}{D : Set d} {E : Set e} {F : Set f}{L : REL A C l} {R : REL B C r}(f : E → A) (g : F → B) (h : D → C)wheremap⁺ : ∀ {as l r} →Interleaving (λ x z → L (f x) (h z)) (λ y z → R (g y) (h z)) l r as →Interleaving L R (map f l) (map g r) (map h as)map⁺ [] = []map⁺ (l ∷ˡ sp) = l ∷ˡ map⁺ spmap⁺ (r ∷ʳ sp) = r ∷ʳ map⁺ spmap⁻ : ∀ {as l r} →Interleaving L R (map f l) (map g r) (map h as) →Interleaving (λ x z → L (f x) (h z)) (λ y z → R (g y) (h z)) l r asmap⁻ {[]} {[]} {[]} [] = []map⁻ {_ ∷ _} {[]} {_ ∷ _} (r ∷ʳ sp) = r ∷ʳ map⁻ spmap⁻ {_ ∷ _} {_ ∷ _} {[]} (l ∷ˡ sp) = l ∷ˡ map⁻ spmap⁻ {_ ∷ _} {_ ∷ _} {_ ∷ _} (l ∷ˡ sp) = l ∷ˡ map⁻ spmap⁻ {_ ∷ _} {_ ∷ _} {_ ∷ _} (r ∷ʳ sp) = r ∷ʳ map⁻ sp-------------------------------------------------------------------------- reversemodule _ {a b c l r} {A : Set a} {B : Set b} {C : Set c}{L : REL A C l} {R : REL B C r}wherereverseAcc⁺ : ∀ {as₁ as₂ l₁ l₂ r₁ r₂} →Interleaving L R l₁ r₁ as₁ →Interleaving L R l₂ r₂ as₂ →Interleaving L R (reverseAcc l₁ l₂) (reverseAcc r₁ r₂) (reverseAcc as₁ as₂)reverseAcc⁺ sp₁ [] = sp₁reverseAcc⁺ sp₁ (l ∷ˡ sp₂) = reverseAcc⁺ (l ∷ˡ sp₁) sp₂reverseAcc⁺ sp₁ (r ∷ʳ sp₂) = reverseAcc⁺ (r ∷ʳ sp₁) sp₂ʳ++⁺ : ∀ {as₁ as₂ l₁ l₂ r₁ r₂} →Interleaving L R l₁ r₁ as₁ →Interleaving L R l₂ r₂ as₂ →Interleaving L R (l₁ ʳ++ l₂) (r₁ ʳ++ r₂) (as₁ ʳ++ as₂)ʳ++⁺ sp₁ sp₂ = reverseAcc⁺ sp₂ sp₁reverse⁺ : ∀ {as l r} → Interleaving L R l r as →Interleaving L R (reverse l) (reverse r) (reverse as)reverse⁺ = reverseAcc⁺ []reverse⁻ : ∀ {as l r} → Interleaving L R (reverse l) (reverse r) (reverse as) →Interleaving L R l r asreverse⁻ {as} {l} {r} sp with reverse⁺ sp... | sp′ rewrite reverse-involutive as| reverse-involutive l| reverse-involutive r = sp′
-------------------------------------------------------------------------- The Agda standard library---- Generalised view of appending two lists into one.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Appending {a b c} {A : Set a} {B : Set b} {C : Set c} whereopen import Level using (Level; _⊔_)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Data.Product.Base using (∃₂; _×_; _,_; -,_)open import Relation.Binary.Core using (REL)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)privatevariablel r : LevelL : REL A C lR : REL B C ras : List Abs : List Bcs : List C-------------------------------------------------------------------------- Definitionmodule _ (L : REL A C l) (R : REL B C r) whereinfixr 5 _∷_ []++_data Appending : List A → List B → List C → Set (a ⊔ b ⊔ c ⊔ l ⊔ r) where[]++_ : ∀ {bs cs} → Pointwise R bs cs → Appending [] bs cs_∷_ : ∀ {a as bs c cs} → L a c → Appending as bs cs → Appending (a ∷ as) bs (c ∷ cs)-------------------------------------------------------------------------- Functions manipulating Appendinginfixr 5 _++__++_ : ∀ {cs₁ cs₂ : List C} → Pointwise L as cs₁ → Pointwise R bs cs₂ →Appending L R as bs (cs₁ List.++ cs₂)[] ++ rs = []++ rs(l ∷ ls) ++ rs = l ∷ (ls ++ rs)-- extract the "proper" equality split from the pointwise relationbreak : Appending L R as bs cs → ∃₂ λ cs₁ cs₂ →cs₁ List.++ cs₂ ≡ cs × Pointwise L as cs₁ × Pointwise R bs cs₂break ([]++ rs) = -, -, (refl , [] , rs)break (l ∷ lrs) =let (_ , _ , eq , ls , rs) = break lrs in-, -, (cong (_ ∷_) eq , l ∷ ls , rs)
-------------------------------------------------------------------------- The Agda standard library---- Appending of lists using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Ternary.Appending.Setoid{c ℓ} (S : Setoid c ℓ)whereopen import Level using (_⊔_)open import Data.List.Base as List using (List)import Data.List.Relation.Ternary.Appending as Generalopen Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- DefinitionAppending : List A → List A → List A → Set (c ⊔ ℓ)Appending = General.Appending _≈_ _≈_-------------------------------------------------------------------------- Re-export the basic combinatorsopen General {A = A} {A} {A} publichiding (Appending)
-------------------------------------------------------------------------- The Agda standard library---- Properties of list appending------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Ternary.Appending.Setoid.Properties{c l} (S : Setoid c l)whereopen import Data.List.Base as List using (List; [])import Data.List.Properties as Listopen import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; [])import Data.List.Relation.Ternary.Appending.Properties as Appendingₚopen import Data.Product.Base using (∃-syntax; _×_; _,_)open import Function.Base using (id)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.PropositionalEquality.Core using (refl)open import Relation.Binary.Construct.Composition using (_;_)open Setoid S renaming (Carrier to A)open import Relation.Binary.Properties.Setoid S using (≈;≈⇒≈; ≈⇒≈;≈)open import Data.List.Relation.Ternary.Appending.Setoid Sprivatevariableas bs cs ds : List A-------------------------------------------------------------------------- Re-exporting existing propertiesopen Appendingₚ publicusing (conicalˡ; conicalʳ)-------------------------------------------------------------------------- Proving setoid-specific ones[]++⁻¹ : Appending [] bs cs → Pointwise _≈_ bs cs[]++⁻¹ ([]++ rs) = rs++[]⁻¹ : Appending as [] cs → Pointwise _≈_ as cs++[]⁻¹ {as} {cs} ls with break ls... | cs₁ , cs₂ , refl , pw , []rewrite List.++-identityʳ cs₁= pwrespʳ-≋ : ∀ {cs′} → Appending as bs cs → Pointwise _≈_ cs cs′ →Appending as bs cs′respʳ-≋ = Appendingₚ.respʳ-≋ trans transrespˡ-≋ : ∀ {as′ bs′} → Pointwise _≈_ as′ as → Pointwise _≈_ bs′ bs →Appending as bs cs → Appending as′ bs′ csrespˡ-≋ = Appendingₚ.respˡ-≋ trans transthrough→ :∃[ xs ] Pointwise _≈_ as xs × Appending xs bs cs →∃[ ys ] Appending as bs ys × Pointwise _≈_ ys csthrough→ = Appendingₚ.through→ ≈⇒≈;≈ idthrough← :∃[ ys ] Appending as bs ys × Pointwise _≈_ ys cs →∃[ xs ] Pointwise _≈_ as xs × Appending xs bs csthrough← = Appendingₚ.through← ≈;≈⇒≈ idassoc→ :∃[ xs ] Appending as bs xs × Appending xs cs ds →∃[ ys ] Appending bs cs ys × Appending as ys dsassoc→ = Appendingₚ.assoc→ ≈⇒≈;≈ id ≈;≈⇒≈
-------------------------------------------------------------------------- The Agda standard library---- Appending of lists using propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Appending.Propositional{a} {A : Set a}whereopen import Data.List.Base as List using (List; []; _∷_)open import Data.Product.Base using (_,_)import Data.List.Properties as Listimport Data.List.Relation.Binary.Pointwise as Pw using (≡⇒Pointwise-≡; Pointwise-≡⇒≡)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; trans; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning; setoid)import Data.List.Relation.Ternary.Appending.Setoid (setoid A) as Generalimport Data.List.Relation.Ternary.Appending.Setoid.Properties (setoid A)as Appending-------------------------------------------------------------------------- Re-export the basic combinatorsopen General publichiding (_++_; break)-------------------------------------------------------------------------- Definitioninfixr 5 _++_ _++[]_++_ : (as bs : List A) → Appending as bs (as List.++ bs)as ++ bs = Pw.≡⇒Pointwise-≡ refl General.++ Pw.≡⇒Pointwise-≡ refl_++[] : (as : List A) → Appending as [] asas ++[] = Appending.respʳ-≋ (as ++ []) (Pw.≡⇒Pointwise-≡ (List.++-identityʳ as))break : ∀ {as bs cs} → Appending as bs cs → as List.++ bs ≡ csbreak {as} {bs} {cs} lrs = let (cs₁ , cs₂ , eq , acs , bcs) = General.break lrs in beginas List.++ bs ≡⟨ cong₂ List._++_ (Pw.Pointwise-≡⇒≡ acs) (Pw.Pointwise-≡⇒≡ bcs) ⟩cs₁ List.++ cs₂ ≡⟨ eq ⟩cs ∎ where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Properties of list appending------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Appending.Propositional.Properties {a} {A : Set a} whereopen import Data.List.Base as List using (List; [])import Data.List.Relation.Binary.Pointwise as Pw using (Pointwise-≡⇒≡)open import Data.List.Relation.Binary.Equality.Propositional using (_≋_)open import Data.List.Relation.Ternary.Appending.Propositional {A = A}open import Function.Base using (_∘′_)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (setoid)import Data.List.Relation.Ternary.Appending.Setoid.Properties (setoid A)as Appendingprivatevariableas bs cs : List A-------------------------------------------------------------------------- Re-export existing propertiesopen Appending publichiding ([]++⁻¹; ++[]⁻¹)-------------------------------------------------------------------------- Prove propositional-specific ones[]++⁻¹ : Appending [] bs cs → bs ≡ cs[]++⁻¹ = Pw.Pointwise-≡⇒≡ ∘′ Appending.[]++⁻¹++[]⁻¹ : Appending as [] cs → as ≡ cs++[]⁻¹ = Pw.Pointwise-≡⇒≡ ∘′ Appending.++[]⁻¹
-------------------------------------------------------------------------- The Agda standard library---- Properties of the generalised view of appending two lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Ternary.Appending.Properties whereopen import Data.List.Base using (List; [])open import Data.List.Relation.Ternary.Appendingopen import Data.List.Relation.Binary.Pointwise as Pw using (Pointwise; []; _∷_)open import Data.Product.Base as Product using (∃-syntax; _×_; _,_)open import Function.Base using (id)open import Data.List.Relation.Binary.Pointwise.Base as Pw using (Pointwise; []; _∷_)open import Data.List.Relation.Binary.Pointwise.Properties as Pw using (transitive)open import Level using (Level)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Definitions using (Trans)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Binary.Construct.Composition using (_;_)privatevariablea ℓ l r : LevelA A′ B B′ C C′ D D′ : Set aR S T U V W X Y : REL A B ℓas bs cs ds : List Amodule _ (RST : Trans R S T) (USV : Trans U S V) whererespʳ-≋ : Appending R U as bs cs → Pointwise S cs ds → Appending T V as bs dsrespʳ-≋ ([]++ rs) es = []++ Pw.transitive USV rs esrespʳ-≋ (l ∷ lrs) (e ∷ es) = RST l e ∷ respʳ-≋ lrs esmodule _ {T : REL A B l} (RST : Trans R S T){W : REL A B r} (ERW : Trans U V W)whererespˡ-≋ : ∀ {as′ bs′} → Pointwise R as′ as → Pointwise U bs′ bs →Appending S V as bs cs → Appending T W as′ bs′ csrespˡ-≋ [] esʳ ([]++ rs) = []++ Pw.transitive ERW esʳ rsrespˡ-≋ (eˡ ∷ esˡ) esʳ (l ∷ lrs) = RST eˡ l ∷ respˡ-≋ esˡ esʳ lrsconicalˡ : Appending R S as bs [] → as ≡ []conicalˡ ([]++ rs) = reflconicalʳ : Appending R S as bs [] → bs ≡ []conicalʳ ([]++ []) = reflthrough→ :(R ⇒ (S ; T)) →((U ; V) ⇒ (W ; T)) →∃[ xs ] Pointwise U as xs × Appending V R xs bs cs →∃[ ys ] Appending W S as bs ys × Pointwise T ys csthrough→ f g (_ , [] , []++ rs) =let _ , rs′ , ps′ = Pw.unzip (Pw.map f rs) in_ , []++ rs′ , ps′through→ f g (_ , p ∷ ps , l ∷ lrs) =let _ , l′ , p′ = g (_ , p , l) inProduct.map _ (Product.map (l′ ∷_) (p′ ∷_)) (through→ f g (_ , ps , lrs))through← :((R ; S) ⇒ T) →((U ; S) ⇒ (V ; W)) →∃[ ys ] Appending U R as bs ys × Pointwise S ys cs →∃[ xs ] Pointwise V as xs × Appending W T xs bs csthrough← f g (_ , []++ rs′ , ps′) =_ , [] , []++ (Pw.transitive (λ r′ p′ → f (_ , r′ , p′)) rs′ ps′)through← f g (_ , l′ ∷ lrs′ , p′ ∷ ps′) =let _ , p , l = g (_ , l′ , p′) inProduct.map _ (Product.map (p ∷_) (l ∷_)) (through← f g (_ , lrs′ , ps′))assoc→ :(R ⇒ (S ; T)) →((U ; V) ⇒ (W ; T)) →((Y ; V) ⇒ X) →∃[ xs ] Appending Y U as bs xs × Appending V R xs cs ds →∃[ ys ] Appending W S bs cs ys × Appending X T as ys dsassoc→ f g h (_ , []++ rs , lrs′) =let _ , mss , ss′ = through→ f g (_ , rs , lrs′) in_ , mss , []++ ss′assoc→ f g h (_ , l ∷ lrs , l′ ∷ lrs′) =Product.map₂ (Product.map₂ (h (_ , l , l′) ∷_)) (assoc→ f g h (_ , lrs , lrs′))assoc← :((S ; T) ⇒ R) →((W ; T) ⇒ (U ; V)) →(X ⇒ (Y ; V)) →∃[ ys ] Appending W S bs cs ys × Appending X T as ys ds →∃[ xs ] Appending Y U as bs xs × Appending V R xs cs dsassoc← f g h (_ , mss , []++ ss′) =let _ , rs , lrs′ = through← f g (_ , mss , ss′) in_ , []++ rs , lrs′assoc← f g h (_ , mss , m′ ∷ mss′) =let _ , l , l′ = h m′ inProduct.map _ (Product.map (l ∷_) (l′ ∷_)) (assoc← f g h (_ , mss , mss′))
-------------------------------------------------------------------------- The Agda standard library---- Properties of the homogeneous suffix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Suffix.Homogeneous.Properties whereopen import Levelopen import Function.Base using (_∘′_)open import Relation.Binary.Core using (REL)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder)open import Data.List.Relation.Binary.Pointwise as Pointwise using (Pointwise)open import Data.List.Relation.Binary.Suffix.Heterogeneousopen import Data.List.Relation.Binary.Suffix.Heterogeneous.Propertiesprivatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B sisPreorder : IsPreorder R S → IsPreorder (Pointwise R) (Suffix S)isPreorder po = record{ isEquivalence = Pointwise.isEquivalence PO.isEquivalence; reflexive = fromPointwise ∘′ Pointwise.map PO.reflexive; trans = trans PO.trans} where module PO = IsPreorder poisPartialOrder : IsPartialOrder R S → IsPartialOrder (Pointwise R) (Suffix S)isPartialOrder po = record{ isPreorder = isPreorder PO.isPreorder; antisym = antisym PO.antisym} where module PO = IsPartialOrder poisDecPartialOrder : IsDecPartialOrder R S → IsDecPartialOrder (Pointwise R) (Suffix S)isDecPartialOrder dpo = record{ isPartialOrder = isPartialOrder DPO.isPartialOrder; _≟_ = Pointwise.decidable DPO._≟_; _≤?_ = suffix? DPO._≤?_} where module DPO = IsDecPartialOrder dpo
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the heterogeneous suffix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Suffix.Heterogeneous whereopen import Levelopen import Relation.Binary.Core using (REL; _⇒_)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Binary.Pointwise.Base as Pointwiseusing (Pointwise; []; _∷_)module _ {a b r} {A : Set a} {B : Set b} (R : REL A B r) whereinfixr 5 _++_data Suffix : REL (List A) (List B) (a ⊔ b ⊔ r) wherehere : ∀ {as bs} → Pointwise R as bs → Suffix as bsthere : ∀ {b as bs} → Suffix as bs → Suffix as (b ∷ bs)data SuffixView (as : List A) : List B → Set (a ⊔ b ⊔ r) where_++_ : ∀ cs {ds} → Pointwise R as ds → SuffixView as (cs List.++ ds)module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wheretail : ∀ {a as bs} → Suffix R (a ∷ as) bs → Suffix R as bstail (here (_ ∷ rs)) = there (here rs)tail (there x) = there (tail x)infixr 5 _++ˢ__++ˢ_ : ∀ pre {as bs} → Suffix R as bs → Suffix R as (pre List.++ bs)[] ++ˢ rs = rs(x ∷ xs) ++ˢ rs = there (xs ++ˢ rs)module _ {a b r s} {A : Set a} {B : Set b} {R : REL A B r} {S : REL A B s} wheremap : R ⇒ S → Suffix R ⇒ Suffix Smap R⇒S (here rs) = here (Pointwise.map R⇒S rs)map R⇒S (there suf) = there (map R⇒S suf)module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wheretoView : ∀ {as bs} → Suffix R as bs → SuffixView R as bstoView (here rs) = [] ++ rstoView (there {c} suf) with cs ++ rs ← toView suf = (c ∷ cs) ++ rsfromView : ∀ {as bs} → SuffixView R as bs → Suffix R as bsfromView ([] ++ rs) = here rsfromView ((c ∷ cs) ++ rs) = there (fromView (cs ++ rs))
-------------------------------------------------------------------------- The Agda standard library---- Properties of the heterogeneous suffix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Suffix.Heterogeneous.Properties whereopen import Data.Bool.Base using (true; false)open import Data.List.Base as Listusing (List; []; _∷_; _++_; length; filter; replicate; reverse; reverseAcc)open import Data.List.Relation.Binary.Pointwise as Pwusing (Pointwise; []; _∷_; Pointwise-length)open import Data.List.Relation.Binary.Suffix.Heterogeneous as Suffixusing (Suffix; here; there; tail)open import Data.List.Relation.Binary.Prefix.Heterogeneous as Prefixusing (Prefix)open import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Function.Base using (_$_; flip)open import Relation.Nullary using (Dec; does; ¬_)import Relation.Nullary.Decidable as Decopen import Relation.Unary as U using (Pred)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.Core using (REL; Rel; _⇒_)open import Relation.Binary.Definitions as Busing (Trans; Antisym; Irrelevant)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; sym; cong; subst; subst₂)import Data.List.Properties as Listimport Data.List.Relation.Binary.Prefix.Heterogeneous.Properties as Prefix-------------------------------------------------------------------------- Suffix and Prefix are linked via reversemodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wherefromPrefix : ∀ {as bs} → Prefix R as bs →Suffix R (reverse as) (reverse bs)fromPrefix {as} {bs} p with Prefix._++_ {cs} rs ds ← Prefix.toView p =subst (Suffix R (reverse as))(sym (List.reverse-++ cs ds))(Suffix.fromView (reverse ds Suffix.++ Pw.reverse⁺ rs))fromPrefix-rev : ∀ {as bs} → Prefix R (reverse as) (reverse bs) →Suffix R as bsfromPrefix-rev pre =subst₂ (Suffix R)(List.reverse-involutive _)(List.reverse-involutive _)(fromPrefix pre)toPrefix-rev : ∀ {as bs} → Suffix R as bs →Prefix R (reverse as) (reverse bs)toPrefix-rev {as} {bs} s with Suffix._++_ cs {ds} rs ← Suffix.toView s =subst (Prefix R (reverse as))(sym (List.reverse-++ cs ds))(Prefix.fromView (Pw.reverse⁺ rs Prefix.++ reverse cs))toPrefix : ∀ {as bs} → Suffix R (reverse as) (reverse bs) →Prefix R as bstoPrefix suf =subst₂ (Prefix R)(List.reverse-involutive _)(List.reverse-involutive _)(toPrefix-rev suf)-------------------------------------------------------------------------- lengthmodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wherelength-mono : ∀ {as bs} → Suffix R as bs → length as ≤ length bslength-mono (here rs) = ≤-reflexive (Pointwise-length rs)length-mono (there suf) = m≤n⇒m≤1+n (length-mono suf)S[as][bs]⇒∣as∣≢1+∣bs∣ : ∀ {as bs} → Suffix R as bs →length as ≢ suc (length bs)S[as][bs]⇒∣as∣≢1+∣bs∣ suf eq = <⇒≱ (≤-reflexive (sym eq)) (length-mono suf)-------------------------------------------------------------------------- Pointwise conversionmodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wherefromPointwise : Pointwise R ⇒ Suffix RfromPointwise = heretoPointwise : ∀ {as bs} → length as ≡ length bs →Suffix R as bs → Pointwise R as bstoPointwise eq (here rs) = rstoPointwise eq (there suf) = contradiction eq (S[as][bs]⇒∣as∣≢1+∣bs∣ suf)-------------------------------------------------------------------------- Suffix as a partial ordermodule _ {a b c r s t} {A : Set a} {B : Set b} {C : Set c}{R : REL A B r} {S : REL B C s} {T : REL A C t} wheretrans : Trans R S T → Trans (Suffix R) (Suffix S) (Suffix T)trans rs⇒t (here rs) (here ss) = here (Pw.transitive rs⇒t rs ss)trans rs⇒t (here rs) (there ssuf) = there (trans rs⇒t (here rs) ssuf)trans rs⇒t (there rsuf) ssuf = trans rs⇒t rsuf (tail ssuf)module _ {a b e r s} {A : Set a} {B : Set b}{R : REL A B r} {S : REL B A s} {E : REL A B e} whereantisym : Antisym R S E → Antisym (Suffix R) (Suffix S) (Pointwise E)antisym rs⇒e rsuf ssuf = Pw.antisymmetricrs⇒e(toPointwise eq rsuf)(toPointwise (sym eq) ssuf)where eq = ≤-antisym (length-mono rsuf) (length-mono ssuf)-------------------------------------------------------------------------- _++_module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where++⁺ : ∀ {as bs cs ds} → Suffix R as bs → Pointwise R cs ds →Suffix R (as ++ cs) (bs ++ ds)++⁺ (here rs) rs′ = here (Pw.++⁺ rs rs′)++⁺ (there suf) rs′ = there (++⁺ suf rs′)++⁻ : ∀ {as bs cs ds} → length cs ≡ length ds →Suffix R (as ++ cs) (bs ++ ds) → Pointwise R cs ds++⁻ {_ ∷ _} {_} {_} {_} eq suf = ++⁻ eq (tail suf)++⁻ {[]} {[]} {_} {_} eq suf = toPointwise eq suf++⁻ {[]} {b ∷ bs} {_} {_} eq (there suf) = ++⁻ eq suf++⁻ {[]} {b ∷ bs} {cs} {ds} eq (here rs) = contradiction (sym eq) (<⇒≢ ds<cs)whereopen ≤-Reasoningds<cs : length ds < length csds<cs = begin-strictlength ds ≤⟨ m≤n+m (length ds) (length bs) ⟩length bs + length ds <⟨ ≤-refl ⟩suc (length bs + length ds) ≡⟨ sym $ List.length-++ (b ∷ bs) ⟩length (b ∷ bs ++ ds) ≡⟨ sym $ Pointwise-length rs ⟩length cs ∎-------------------------------------------------------------------------- mapmodule _ {a b c d r} {A : Set a} {B : Set b} {C : Set c} {D : Set d}{R : REL C D r} wheremap⁺ : ∀ {as bs} (f : A → C) (g : B → D) →Suffix (λ a b → R (f a) (g b)) as bs →Suffix R (List.map f as) (List.map g bs)map⁺ f g (here rs) = here (Pw.map⁺ f g rs)map⁺ f g (there suf) = there (map⁺ f g suf)map⁻ : ∀ {as bs} (f : A → C) (g : B → D) →Suffix R (List.map f as) (List.map g bs) →Suffix (λ a b → R (f a) (g b)) as bsmap⁻ {as} {b ∷ bs} f g (here rs) = here (Pw.map⁻ f g rs)map⁻ {as} {b ∷ bs} f g (there suf) = there (map⁻ f g suf)map⁻ {x ∷ as} {[]} f g suf = contradiction (length-mono suf) λ()map⁻ {[]} {[]} f g suf = here []-------------------------------------------------------------------------- filtermodule _ {a b r p q} {A : Set a} {B : Set b} {R : REL A B r}{P : Pred A p} {Q : Pred B q}(P? : U.Decidable P) (Q? : U.Decidable Q)(P⇒Q : ∀ {a b} → R a b → P a → Q b)(Q⇒P : ∀ {a b} → R a b → Q b → P a)wherefilter⁺ : ∀ {as bs} → Suffix R as bs →Suffix R (filter P? as) (filter Q? bs)filter⁺ (here rs) = here (Pw.filter⁺ P? Q? P⇒Q Q⇒P rs)filter⁺ (there {a} suf) with does (Q? a)... | true = there (filter⁺ suf)... | false = filter⁺ suf-------------------------------------------------------------------------- replicatemodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} wherereplicate⁺ : ∀ {m n a b} → m ≤ n → R a b →Suffix R (replicate m a) (replicate n b)replicate⁺ {a = a} {b = b} m≤n r = repl (≤⇒≤′ m≤n)whererepl : ∀ {m n} → m ≤′ n → Suffix R (replicate m a) (replicate n b)repl ≤′-refl = here (Pw.replicate⁺ r _)repl (≤′-step m≤n) = there (repl m≤n)-------------------------------------------------------------------------- Irrelevantmodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} whereirrelevant : Irrelevant R → Irrelevant (Suffix R)irrelevant irr (here rs) (here rs₁) = cong here $ Pw.irrelevant irr rs rs₁irrelevant irr (here rs) (there rsuf) = contradiction (Pointwise-length rs) (S[as][bs]⇒∣as∣≢1+∣bs∣ rsuf)irrelevant irr (there rsuf) (here rs) = contradiction (Pointwise-length rs) (S[as][bs]⇒∣as∣≢1+∣bs∣ rsuf)irrelevant irr (there rsuf) (there rsuf₁) = cong there $ irrelevant irr rsuf rsuf₁-------------------------------------------------------------------------- Decidabilitysuffix? : B.Decidable R → B.Decidable (Suffix R)suffix? R? as bs = Dec.map′ fromPrefix-rev toPrefix-rev$ Prefix.prefix? R? (reverse as) (reverse bs)
-------------------------------------------------------------------------- The Agda standard library---- The extensional sublist relation over setoid equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Subset.Setoid{c ℓ} (S : Setoid c ℓ) whereopen import Data.List.Base using (List)open import Data.List.Membership.Setoid S using (_∈_)open import Function.Base using (flip)open import Level using (_⊔_)open import Relation.Nullary.Negation using (¬_)open Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Definitionsinfix 4 _⊆_ _⊇_ _⊈_ _⊉__⊆_ : Rel (List A) (c ⊔ ℓ)xs ⊆ ys = ∀ {x} → x ∈ xs → x ∈ ys_⊇_ : Rel (List A) (c ⊔ ℓ)_⊇_ = flip _⊆__⊈_ : Rel (List A) (c ⊔ ℓ)xs ⊈ ys = ¬ xs ⊆ ys_⊉_ : Rel (List A) (c ⊔ ℓ)xs ⊉ ys = ¬ xs ⊇ ys
-------------------------------------------------------------------------- The Agda standard library---- Properties of the extensional sublist relation over setoid equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Subset.Setoid.Properties whereopen import Data.Bool.Base using (Bool; true; false)open import Data.List.Base hiding (_∷ʳ_; find)import Data.List.Properties as Listopen import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Relation.Unary.All as All using (All)import Data.List.Membership.Setoid as Membershipimport Data.List.Membership.Setoid.Properties as Membershipₚopen import Data.Nat.Base using (ℕ; s≤s; _≤_)import Data.List.Relation.Binary.Subset.Setoid as Subsetimport Data.List.Relation.Binary.Sublist.Setoid as Sublistimport Data.List.Relation.Binary.Equality.Setoid as Equalityimport Data.List.Relation.Binary.Permutation.Setoid as Permutationimport Data.List.Relation.Binary.Permutation.Setoid.Properties as Permutationₚopen import Data.Product.Base using (_,_)open import Function.Base using (_∘_; _∘₂_; _$_)open import Level using (Level)open import Relation.Nullary using (¬_; does; yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Unary using (Pred; Decidable) renaming (_⊆_ to _⋐_)open import Relation.Binary.Core using (_⇒_; _Preserves_⟶_)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; _Respectsʳ_; _Respectsˡ_; _Respects_)open import Relation.Binary.Bundles using (Setoid; Preorder)open import Relation.Binary.Structures using (IsPreorder)import Relation.Binary.Reasoning.Preorder as ≲-Reasoningopen import Relation.Binary.Reasoning.Syntaxopen Setoid using (Carrier)privatevariablea b p q r ℓ : Level-------------------------------------------------------------------------- Relational properties with _≋_ (pointwise equality)------------------------------------------------------------------------module _ (S : Setoid a ℓ) whereopen Subset Sopen Equality Sopen Membership Sopen Membershipₚ⊆-reflexive : _≋_ ⇒ _⊆_⊆-reflexive xs≋ys = ∈-resp-≋ S xs≋ys⊆-refl : Reflexive _⊆_⊆-refl x∈xs = x∈xs⊆-trans : Transitive _⊆_⊆-trans xs⊆ys ys⊆zs x∈xs = ys⊆zs (xs⊆ys x∈xs)⊆-respʳ-≋ : _⊆_ Respectsʳ _≋_⊆-respʳ-≋ xs≋ys = ∈-resp-≋ S xs≋ys ∘_⊆-respˡ-≋ : _⊆_ Respectsˡ _≋_⊆-respˡ-≋ xs≋ys = _∘ ∈-resp-≋ S (≋-sym xs≋ys)⊆-isPreorder : IsPreorder _≋_ _⊆_⊆-isPreorder = record{ isEquivalence = ≋-isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-preorder : Preorder _ _ _⊆-preorder = record{ isPreorder = ⊆-isPreorder}-------------------------------------------------------------------------- Relational properties with _↭_ (permutations)------------------------------------------------------------------------module _ (S : Setoid a ℓ) whereopen Subset Sopen Permutation Sopen Membership S⊆-reflexive-↭ : _↭_ ⇒ _⊆_⊆-reflexive-↭ xs↭ys = Permutationₚ.∈-resp-↭ S xs↭ys⊆-respʳ-↭ : _⊆_ Respectsʳ _↭_⊆-respʳ-↭ xs↭ys = Permutationₚ.∈-resp-↭ S xs↭ys ∘_⊆-respˡ-↭ : _⊆_ Respectsˡ _↭_⊆-respˡ-↭ xs↭ys = _∘ Permutationₚ.∈-resp-↭ S (↭-sym xs↭ys)⊆-↭-isPreorder : IsPreorder _↭_ _⊆_⊆-↭-isPreorder = record{ isEquivalence = ↭-isEquivalence; reflexive = ⊆-reflexive-↭; trans = ⊆-trans S}⊆-↭-preorder : Preorder _ _ _⊆-↭-preorder = record{ isPreorder = ⊆-↭-isPreorder}-------------------------------------------------------------------------- Reasoning over subsets------------------------------------------------------------------------module ⊆-Reasoning (S : Setoid a ℓ) whereopen Membership S using (_∈_)private module Base = ≲-Reasoning (⊆-preorder S)open Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨; step-≲; step-∼)renaming (≲-go to ⊆-go; ≈-go to ≋-go)open begin-membership-syntax _IsRelatedTo_ _∈_ (λ x → Base.begin x) publicopen ⊆-syntax _IsRelatedTo_ _IsRelatedTo_ ⊆-go publicopen ≋-syntax _IsRelatedTo_ _IsRelatedTo_ ≋-go public-------------------------------------------------------------------------- Relationship with other binary relations------------------------------------------------------------------------module _ (S : Setoid a ℓ) whereopen Setoid Sopen Subset Sopen Sublist S renaming (_⊆_ to _⊑_)Sublist⇒Subset : ∀ {xs ys} → xs ⊑ ys → xs ⊆ ysSublist⇒Subset (x≈y ∷ xs⊑ys) (here v≈x) = here (trans v≈x x≈y)Sublist⇒Subset (x≈y ∷ xs⊑ys) (there v∈xs) = there (Sublist⇒Subset xs⊑ys v∈xs)Sublist⇒Subset (y ∷ʳ xs⊑ys) v∈xs = there (Sublist⇒Subset xs⊑ys v∈xs)-------------------------------------------------------------------------- Relationship with predicates------------------------------------------------------------------------module _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open Subset Sopen Membership SAny-resp-⊆ : ∀ {P : Pred A p} → P Respects _≈_ → (Any P) Respects _⊆_Any-resp-⊆ resp ⊆ pxs with find pxs... | (x , x∈xs , px) = lose resp (⊆ x∈xs) pxAll-resp-⊇ : ∀ {P : Pred A p} → P Respects _≈_ → (All P) Respects _⊇_All-resp-⊇ resp ⊇ pxs = All.tabulateₛ S (All.lookupₛ S resp pxs ∘ ⊇)-------------------------------------------------------------------------- Properties of list functions-------------------------------------------------------------------------- ∷module _ (S : Setoid a ℓ) whereopen Setoid Sopen Subset Sopen Membership Sopen Membershipₚxs⊆x∷xs : ∀ xs x → xs ⊆ x ∷ xsxs⊆x∷xs xs x = there∷⁺ʳ : ∀ {xs ys} x → xs ⊆ ys → x ∷ xs ⊆ x ∷ ys∷⁺ʳ x xs⊆ys (here p) = here p∷⁺ʳ x xs⊆ys (there p) = there (xs⊆ys p)∈-∷⁺ʳ : ∀ {xs ys x} → x ∈ ys → xs ⊆ ys → x ∷ xs ⊆ ys∈-∷⁺ʳ x∈ys _ (here v≈x) = ∈-resp-≈ S (sym v≈x) x∈ys∈-∷⁺ʳ _ xs⊆ys (there x∈xs) = xs⊆ys x∈xs-------------------------------------------------------------------------- ++module _ (S : Setoid a ℓ) whereopen Subset Sopen Membership Sopen Membershipₚxs⊆xs++ys : ∀ xs ys → xs ⊆ xs ++ ysxs⊆xs++ys xs ys = ∈-++⁺ˡ Sxs⊆ys++xs : ∀ xs ys → xs ⊆ ys ++ xsxs⊆ys++xs xs ys = ∈-++⁺ʳ S _++⁺ʳ : ∀ {xs ys} zs → xs ⊆ ys → zs ++ xs ⊆ zs ++ ys++⁺ʳ [] xs⊆ys = xs⊆ys++⁺ʳ (x ∷ zs) xs⊆ys (here p) = here p++⁺ʳ (x ∷ zs) xs⊆ys (there p) = there (++⁺ʳ zs xs⊆ys p)++⁺ˡ : ∀ {xs ys} zs → xs ⊆ ys → xs ++ zs ⊆ ys ++ zs++⁺ˡ {[]} {ys} zs xs⊆ys = xs⊆ys++xs zs ys++⁺ˡ {x ∷ xs} {ys} zs xs⊆ys (here p) = xs⊆xs++ys ys zs (xs⊆ys (here p))++⁺ˡ {x ∷ xs} {ys} zs xs⊆ys (there p) = ++⁺ˡ zs (xs⊆ys ∘ there) p++⁺ : ∀ {ws xs ys zs} → ws ⊆ xs → ys ⊆ zs → ws ++ ys ⊆ xs ++ zs++⁺ ws⊆xs ys⊆zs = ⊆-trans S (++⁺ˡ _ ws⊆xs) (++⁺ʳ _ ys⊆zs)-------------------------------------------------------------------------- mapmodule _ (S : Setoid a ℓ) (R : Setoid b r) whereprivatemodule S = Setoid Smodule R = Setoid Rmodule S⊆ = Subset Smodule R⊆ = Subset Ropen Membershipₚmap⁺ : ∀ {as bs} {f : S.Carrier → R.Carrier} →f Preserves S._≈_ ⟶ R._≈_ →as S⊆.⊆ bs → map f as R⊆.⊆ map f bsmap⁺ {f = f} f-pres as⊆bs v∈f[as] =let x , x∈as , v≈f[x] = ∈-map⁻ S R v∈f[as] in∈-resp-≈ R (R.sym v≈f[x]) (∈-map⁺ S R f-pres (as⊆bs x∈as))-------------------------------------------------------------------------- reversemodule _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open Subset Sreverse-selfAdjoint : ∀ {as bs} → as ⊆ reverse bs → reverse as ⊆ bsreverse-selfAdjoint rs = reverse⁻ ∘ rs ∘ reverse⁻where reverse⁻ = Membershipₚ.reverse⁻ S-- NB. the unit and counit of this adjunction are given by:-- reverse-η : ∀ {xs} → xs ⊆ reverse xs-- reverse-η = Membershipₚ.reverse⁺ S-- reverse-ε : ∀ {xs} → reverse xs ⊆ xs-- reverse-ε = Membershipₚ.reverse⁻ Sreverse⁺ : ∀ {as bs} → as ⊆ bs → reverse as ⊆ reverse bsreverse⁺ {as} {bs} rs = reverse-selfAdjoint $ beginas ⊆⟨ rs ⟩bs ≡⟨ List.reverse-involutive bs ⟨reverse (reverse bs) ∎where open ⊆-Reasoning Sreverse⁻ : ∀ {as bs} → reverse as ⊆ reverse bs → as ⊆ bsreverse⁻ {as} {bs} rs = beginas ≡⟨ List.reverse-involutive as ⟨reverse (reverse as) ⊆⟨ reverse-selfAdjoint rs ⟩bs ∎where open ⊆-Reasoning S-------------------------------------------------------------------------- filtermodule _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open Subset Sopen Membershipₚfilter-⊆ : ∀ {P : Pred A p} (P? : Decidable P) →∀ xs → filter P? xs ⊆ xsfilter-⊆ P? (x ∷ xs) y∈f[x∷xs] with does (P? x)... | false = there (filter-⊆ P? xs y∈f[x∷xs])... | true with y∈f[x∷xs]... | here y≈x = here y≈x... | there y∈f[xs] = there (filter-⊆ P? xs y∈f[xs])-- Should be known as `filter⁺` (no prime) but `filter-⊆` used-- to be called this so for backwards compatability reasons, the-- correct name will have to wait until the deprecated name is-- removed.filter⁺′ : ∀ {P : Pred A p} (P? : Decidable P) → P Respects _≈_ →∀ {Q : Pred A q} (Q? : Decidable Q) → Q Respects _≈_ →P ⋐ Q → ∀ {xs ys} → xs ⊆ ys → filter P? xs ⊆ filter Q? ysfilter⁺′ P? P-resp Q? Q-resp P⋐Q xs⊆ys v∈fxs with ∈-filter⁻ S P? P-resp v∈fxs... | v∈xs , Pv = ∈-filter⁺ S Q? Q-resp (xs⊆ys v∈xs) (P⋐Q Pv)-------------------------------------------------------------------------- applyUpTomodule _ (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open Subset SapplyUpTo⁺ : ∀ (f : ℕ → A) {m n} → m ≤ n → applyUpTo f m ⊆ applyUpTo f napplyUpTo⁺ _ (s≤s m≤n) (here f≡f[0]) = here f≡f[0]applyUpTo⁺ _ (s≤s m≤n) (there v∈xs) = there (applyUpTo⁺ _ m≤n v∈xs)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Version 1.5filter⁺ = filter-⊆{-# WARNING_ON_USAGE filter⁺"Warning: filter⁺ was deprecated in v1.5.Please use filter-⊆ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The sublist relation over propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Subset.Propositional{a} {A : Set a} whereimport Data.List.Relation.Binary.Subset.Setoid as SetoidSubsetopen import Relation.Binary.PropositionalEquality.Properties using (setoid)-------------------------------------------------------------------------- Re-export parameterised definitions from setoid sublistsopen SetoidSubset (setoid A) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of the sublist relation over setoid equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Subset.Propositional.Propertieswhereopen import Data.Bool.Base using (Bool; true; false; T)open import Data.List.Base using (List; map; _∷_; _++_; concat; applyUpTo;any; filter)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Relation.Unary.All using (All)import Data.List.Relation.Unary.Any.Properties as Any hiding (filter⁺)open import Data.List.Effectful using (monad)open import Data.List.Relation.Unary.Any using (Any)open import Data.List.Membership.Propositional using (_∈_; mapWith∈)open import Data.List.Membership.Propositional.Propertiesusing (map-∈↔; concat-∈↔; >>=-∈↔; ⊛-∈↔; ⊗-∈↔)import Data.List.Relation.Binary.Subset.Setoid.Properties as Subsetopen import Data.List.Relation.Binary.Subset.Propositionalusing (_⊆_; _⊇_)open import Data.List.Relation.Binary.Permutation.Propositionalusing (_↭_; ↭-sym; ↭-isEquivalence)import Data.List.Relation.Binary.Permutation.Propositional.Properties as Permutationopen import Data.Nat.Base using (ℕ; _≤_)import Data.Product.Base as Productimport Data.Sum.Base as Sumopen import Effect.Monadopen import Function.Base using (_∘_; _∘′_; id; _$_)open import Function.Bundles using (_↔_; Inverse; Equivalence)open import Level using (Level)open import Relation.Nullary using (¬_; yes; no)open import Relation.Unary using (Decidable; Pred) renaming (_⊆_ to _⋐_)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Preorder)open import Relation.Binary.Definitions hiding (Decidable)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≗_; subst; resp; refl)open import Relation.Binary.PropositionalEquality.Propertiesusing (isEquivalence; setoid; module ≡-Reasoning)open import Relation.Binary.Structures using (IsPreorder)import Relation.Binary.Reasoning.Preorder as ≲-Reasoningprivateopen module ListMonad {ℓ} = RawMonad (monad {ℓ = ℓ})variablea b p q : LevelA : Set aB : Set bws xs ys zs : List A-------------------------------------------------------------------------- Relational properties with _≋_ (pointwise equality)------------------------------------------------------------------------⊆-reflexive : _≡_ {A = List A} ⇒ _⊆_⊆-reflexive refl = id⊆-refl : Reflexive {A = List A} _⊆_⊆-refl x∈xs = x∈xs⊆-trans : Transitive {A = List A} _⊆_⊆-trans xs⊆ys ys⊆zs = ys⊆zs ∘ xs⊆ysmodule _ (A : Set a) where⊆-isPreorder : IsPreorder {A = List A} _≡_ _⊆_⊆-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-preorder : Preorder _ _ _⊆-preorder = record{ isPreorder = ⊆-isPreorder}-------------------------------------------------------------------------- Relational properties with _↭_ (permutation)-------------------------------------------------------------------------- See issue #1354 for why these proofs can't be taken from `Subset`⊆-reflexive-↭ : _↭_ {A = A} ⇒ _⊆_⊆-reflexive-↭ xs↭ys = Permutation.∈-resp-↭ xs↭ys⊆-respʳ-↭ : _⊆_ {A = A} Respectsʳ _↭_⊆-respʳ-↭ xs↭ys = Permutation.∈-resp-↭ xs↭ys ∘_⊆-respˡ-↭ : _⊆_ {A = A} Respectsˡ _↭_⊆-respˡ-↭ xs↭ys = _∘ Permutation.∈-resp-↭ (↭-sym xs↭ys)module _ (A : Set a) where⊆-↭-isPreorder : IsPreorder {A = List A} _↭_ _⊆_⊆-↭-isPreorder = record{ isEquivalence = ↭-isEquivalence; reflexive = ⊆-reflexive-↭; trans = ⊆-trans}⊆-↭-preorder : Preorder _ _ _⊆-↭-preorder = record{ isPreorder = ⊆-↭-isPreorder}-------------------------------------------------------------------------- Reasoning over subsets------------------------------------------------------------------------module ⊆-Reasoning (A : Set a) whereopen Subset.⊆-Reasoning (setoid A) publichiding (step-≋; step-≋˘)-------------------------------------------------------------------------- Properties of _⊆_ and various list predicates------------------------------------------------------------------------Any-resp-⊆ : ∀ {P : Pred A p} → (Any P) Respects _⊆_Any-resp-⊆ = Subset.Any-resp-⊆ (setoid _) (subst _)All-resp-⊇ : ∀ {P : Pred A p} → (All P) Respects _⊇_All-resp-⊇ = Subset.All-resp-⊇ (setoid _) (subst _)-------------------------------------------------------------------------- Properties relating _⊆_ to various list functions-------------------------------------------------------------------------- mapmap⁺ : ∀ (f : A → B) → xs ⊆ ys → map f xs ⊆ map f ysmap⁺ f xs⊆ys =Inverse.to (map-∈↔ f) ∘Product.map₂ (Product.map₁ xs⊆ys) ∘Inverse.from (map-∈↔ f)-------------------------------------------------------------------------- ∷xs⊆x∷xs : ∀ (xs : List A) x → xs ⊆ x ∷ xsxs⊆x∷xs = Subset.xs⊆x∷xs (setoid _)∷⁺ʳ : ∀ x → xs ⊆ ys → x ∷ xs ⊆ x ∷ ys∷⁺ʳ = Subset.∷⁺ʳ (setoid _)∈-∷⁺ʳ : ∀ {x} → x ∈ ys → xs ⊆ ys → x ∷ xs ⊆ ys∈-∷⁺ʳ = Subset.∈-∷⁺ʳ (setoid _)-------------------------------------------------------------------------- _++_xs⊆xs++ys : ∀ (xs ys : List A) → xs ⊆ xs ++ ysxs⊆xs++ys = Subset.xs⊆xs++ys (setoid _)xs⊆ys++xs : ∀ (xs ys : List A) → xs ⊆ ys ++ xsxs⊆ys++xs = Subset.xs⊆ys++xs (setoid _)++⁺ʳ : ∀ zs → xs ⊆ ys → zs ++ xs ⊆ zs ++ ys++⁺ʳ = Subset.++⁺ʳ (setoid _)++⁺ˡ : ∀ zs → xs ⊆ ys → xs ++ zs ⊆ ys ++ zs++⁺ˡ = Subset.++⁺ˡ (setoid _)++⁺ : ws ⊆ xs → ys ⊆ zs → ws ++ ys ⊆ xs ++ zs++⁺ = Subset.++⁺ (setoid _)-------------------------------------------------------------------------- concatmodule _ {xss yss : List (List A)} whereconcat⁺ : xss ⊆ yss → concat xss ⊆ concat yssconcat⁺ xss⊆yss =Inverse.to concat-∈↔ ∘Product.map₂ (Product.map₂ xss⊆yss) ∘Inverse.from concat-∈↔-------------------------------------------------------------------------- applyUpToapplyUpTo⁺ : ∀ (f : ℕ → A) {m n} → m ≤ n → applyUpTo f m ⊆ applyUpTo f napplyUpTo⁺ = Subset.applyUpTo⁺ (setoid _)-------------------------------------------------------------------------- _>>=_module _ {A B : Set a} (f g : A → List B) where>>=⁺ : xs ⊆ ys → (∀ {x} → f x ⊆ g x) → (xs >>= f) ⊆ (ys >>= g)>>=⁺ xs⊆ys f⊆g =Inverse.to >>=-∈↔ ∘Product.map₂ (Product.map xs⊆ys f⊆g) ∘Inverse.from >>=-∈↔-------------------------------------------------------------------------- _⊛_module _ {A B : Set a} {fs gs : List (A → B)} where⊛⁺ : fs ⊆ gs → xs ⊆ ys → (fs ⊛ xs) ⊆ (gs ⊛ ys)⊛⁺ fs⊆gs xs⊆ys =(Inverse.to $ ⊛-∈↔ gs) ∘Product.map₂ (Product.map₂ (Product.map fs⊆gs (Product.map₁ xs⊆ys))) ∘(Inverse.from $ ⊛-∈↔ fs)-------------------------------------------------------------------------- _⊗_module _ {A B : Set a} {ws xs : List A} {ys zs : List B} where⊗⁺ : ws ⊆ xs → ys ⊆ zs → (ws ⊗ ys) ⊆ (xs ⊗ zs)⊗⁺ ws⊆xs ys⊆zs =Inverse.to ⊗-∈↔ ∘Product.map ws⊆xs ys⊆zs ∘Inverse.from ⊗-∈↔-------------------------------------------------------------------------- anymodule _ (p : A → Bool) {xs ys} whereany⁺ : xs ⊆ ys → T (any p xs) → T (any p ys)any⁺ xs⊆ys =Equivalence.to Any.any⇔ ∘Any-resp-⊆ xs⊆ys ∘Equivalence.from Any.any⇔-------------------------------------------------------------------------- mapWith∈module _ {xs : List A} {f : ∀ {x} → x ∈ xs → B}{ys : List A} {g : ∀ {x} → x ∈ ys → B}wheremapWith∈⁺ : (xs⊆ys : xs ⊆ ys) → (∀ {x} → f {x} ≗ g ∘ xs⊆ys) →mapWith∈ xs f ⊆ mapWith∈ ys gmapWith∈⁺ xs⊆ys f≈g {x} =Inverse.to Any.mapWith∈↔ ∘Product.map₂ (Product.map xs⊆ys (λ {x∈xs} x≡fx∈xs → beginx ≡⟨ x≡fx∈xs ⟩f x∈xs ≡⟨ f≈g x∈xs ⟩g (xs⊆ys x∈xs) ∎)) ∘Inverse.from Any.mapWith∈↔where open ≡-Reasoning-------------------------------------------------------------------------- filtermodule _ {P : Pred A p} (P? : Decidable P) wherefilter-⊆ : ∀ xs → filter P? xs ⊆ xsfilter-⊆ = Subset.filter-⊆ (setoid A) P?module _ {Q : Pred A q} (Q? : Decidable Q) wherefilter⁺′ : P ⋐ Q → ∀ {xs ys} → xs ⊆ ys → filter P? xs ⊆ filter Q? ysfilter⁺′ = Subset.filter⁺′ (setoid A) P? (resp P) Q? (resp Q)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Version 1.5mono = Any-resp-⊆{-# WARNING_ON_USAGE mono"Warning: mono was deprecated in v1.5.Please use Any-resp-⊆ instead."#-}map-mono = map⁺{-# WARNING_ON_USAGE map-mono"Warning: map-mono was deprecated in v1.5.Please use map⁺ instead."#-}infix 4 _++-mono__++-mono_ = ++⁺{-# WARNING_ON_USAGE _++-mono_"Warning: _++-mono_ was deprecated in v1.5.Please use ++⁺ instead."#-}concat-mono = concat⁺{-# WARNING_ON_USAGE concat-mono"Warning: concat-mono was deprecated in v1.5.Please use concat⁺ instead."#-}>>=-mono = >>=⁺{-# WARNING_ON_USAGE >>=-mono"Warning: >>=-mono was deprecated in v1.5.Please use >>=⁺ instead."#-}infix 4 _⊛-mono__⊛-mono_ = ⊛⁺{-# WARNING_ON_USAGE _⊛-mono_"Warning: _⊛-mono_ was deprecated in v1.5.Please use ⊛⁺ instead."#-}infix 4 _⊗-mono__⊗-mono_ = ⊗⁺{-# WARNING_ON_USAGE _⊗-mono_"Warning: _⊗-mono_ was deprecated in v1.5.Please use ⊗⁺ instead."#-}any-mono = any⁺{-# WARNING_ON_USAGE any-mono"Warning: any-mono was deprecated in v1.5.Please use any⁺ instead."#-}map-with-∈-mono = mapWith∈⁺{-# WARNING_ON_USAGE map-with-∈-mono"Warning: map-with-∈-mono was deprecated in v1.5.Please use mapWith∈⁺ instead."#-}map-with-∈⁺ = mapWith∈⁺{-# WARNING_ON_USAGE map-with-∈⁺"Warning: map-with-∈⁺ was deprecated in v2.0.Please use mapWith∈⁺ instead."#-}filter⁺ = filter-⊆{-# WARNING_ON_USAGE filter⁺"Warning: filter⁺ was deprecated in v1.5.Please use filter-⊆ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Decidability of the subset relation over setoid equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)module Data.List.Relation.Binary.Subset.DecSetoid {c ℓ} (S : DecSetoid c ℓ) whereopen import Function.Base using (_∘_)open import Data.List.Base using ([]; _∷_)open import Data.List.Relation.Unary.Any using (here; there; map)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary using (yes; no)open DecSetoid Sopen import Data.List.Relation.Binary.Equality.DecSetoid Sopen import Data.List.Membership.DecSetoid S-- Re-export definitionsopen import Data.List.Relation.Binary.Subset.Setoid setoid publicinfix 4 _⊆?__⊆?_ : Decidable _⊆_[] ⊆? _ = yes λ ()(x ∷ xs) ⊆? ys with x ∈? ys... | no x∉ys = no λ xs⊆ys → x∉ys (xs⊆ys (here refl))... | yes x∈ys with xs ⊆? ys... | no xs⊈ys = no λ xs⊆ys → xs⊈ys (xs⊆ys ∘ there)... | yes xs⊆ys = yes λ where (here refl) → map (trans refl) x∈ys(there x∈) → xs⊆ys x∈
-------------------------------------------------------------------------- The Agda standard library---- Decidability of the subset relation over propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Binary.Subset.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A)where-------------------------------------------------------------------------- Re-export core definitions and operationsopen import Data.List.Relation.Binary.Subset.Propositional {A = A} publicopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)open import Data.List.Relation.Binary.Subset.DecSetoid (decSetoid _≟_) publicusing (_⊆?_)
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the sublist relation with respect to a-- setoid. This is a generalisation of what is commonly known as Order-- Preserving Embeddings (OPE).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --postfix-projections #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Sublist.Setoid{c ℓ} (S : Setoid c ℓ) whereopen import Level using (_⊔_)open import Data.List.Base using (List; []; _∷_)import Data.List.Relation.Binary.Equality.Setoid as SetoidEqualityimport Data.List.Relation.Binary.Sublist.Heterogeneous as Heterogeneousimport Data.List.Relation.Binary.Sublist.Heterogeneous.Coreas HeterogeneousCoreimport Data.List.Relation.Binary.Sublist.Heterogeneous.Propertiesas HeterogeneousPropertiesopen import Data.Product.Base using (∃; ∃₂; _×_; _,_; proj₂)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Preorder; Poset)open import Relation.Binary.Structures using (IsPreorder; IsPartialOrder)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary using (¬_; Dec; yes; no)open Setoid S renaming (Carrier to A)open SetoidEquality S-------------------------------------------------------------------------- Definitioninfix 4 _⊆_ _⊇_ _⊂_ _⊃_ _⊈_ _⊉_ _⊄_ _⊅__⊆_ : Rel (List A) (c ⊔ ℓ)_⊆_ = Heterogeneous.Sublist _≈__⊇_ : Rel (List A) (c ⊔ ℓ)xs ⊇ ys = ys ⊆ xs_⊂_ : Rel (List A) (c ⊔ ℓ)xs ⊂ ys = xs ⊆ ys × ¬ (xs ≋ ys)_⊃_ : Rel (List A) (c ⊔ ℓ)xs ⊃ ys = ys ⊂ xs_⊈_ : Rel (List A) (c ⊔ ℓ)xs ⊈ ys = ¬ (xs ⊆ ys)_⊉_ : Rel (List A) (c ⊔ ℓ)xs ⊉ ys = ¬ (xs ⊇ ys)_⊄_ : Rel (List A) (c ⊔ ℓ)xs ⊄ ys = ¬ (xs ⊂ ys)_⊅_ : Rel (List A) (c ⊔ ℓ)xs ⊅ ys = ¬ (xs ⊃ ys)-------------------------------------------------------------------------- Re-export definitions and operations from heterogeneous sublistsopen HeterogeneousCore _≈_ publicusing ([]; _∷_; _∷ʳ_)open Heterogeneous {R = _≈_} publichiding (Sublist; []; _∷_; _∷ʳ_)renaming( toAny to to∈; fromAny to from∈)open Disjoint publicusing ([])open DisjointUnion publicusing ([])-------------------------------------------------------------------------- Relational properties holding for Setoid case⊆-reflexive : _≋_ ⇒ _⊆_⊆-reflexive = HeterogeneousProperties.fromPointwiseopen HeterogeneousProperties.Reflexivity {R = _≈_} refl public using ()renaming (refl to ⊆-refl) -- ⊆-refl : Reflexive _⊆_open HeterogeneousProperties.Transitivity {R = _≈_} {S = _≈_} {T = _≈_} trans public using ()renaming (trans to ⊆-trans) -- ⊆-trans : Transitive _⊆_open HeterogeneousProperties.Antisymmetry {R = _≈_} {S = _≈_} (λ x≈y _ → x≈y) public using ()renaming (antisym to ⊆-antisym) -- ⊆-antisym : Antisymmetric _≋_ _⊆_⊆-isPreorder : IsPreorder _≋_ _⊆_⊆-isPreorder = record{ isEquivalence = ≋-isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-isPartialOrder : IsPartialOrder _≋_ _⊆_⊆-isPartialOrder = record{ isPreorder = ⊆-isPreorder; antisym = ⊆-antisym}⊆-preorder : Preorder c (c ⊔ ℓ) (c ⊔ ℓ)⊆-preorder = record{ isPreorder = ⊆-isPreorder}⊆-poset : Poset c (c ⊔ ℓ) (c ⊔ ℓ)⊆-poset = record{ isPartialOrder = ⊆-isPartialOrder}-------------------------------------------------------------------------- Raw pushout---- The category _⊆_ does not have proper pushouts. For instance consider:---- τᵤ : [] ⊆ (u ∷ [])-- τᵥ : [] ⊆ (v ∷ [])---- Then, there are two unrelated upper bounds (u ∷ v ∷ []) and (v ∷ u ∷ []),-- since _⊆_ does not include permutations.---- Even though there are no unique least upper bounds, we can merge two-- extensions of a list, producing a minimial superlist of both.---- For the example, the left-biased merge would produce the pair:---- τᵤ′ : (u ∷ []) ⊆ (u ∷ v ∷ [])-- τᵥ′ : (v ∷ []) ⊆ (u ∷ v ∷ [])---- We call such a pair a raw pushout. It is then a weak pushout if the-- resulting square commutes, i.e.:---- ⊆-trans τᵤ τᵤ′ ~ ⊆-trans τᵥ τᵥ′---- This requires a notion of equality _~_ on sublist morphisms.---- Further, commutation requires a similar commutation property-- for the underlying equality _≈_, namely---- trans x≈y (sym x≈y) == trans x≈z (sym x≈z)---- for some notion of equality _==_ for equality proofs _≈_.-- Such a property is given e.g. if _≈_ is proof irrelevant-- or forms a groupoid.record RawPushout {xs ys zs : List A} (τ : xs ⊆ ys) (σ : xs ⊆ zs) : Set (c ⊔ ℓ) wherefield{upperBound} : List Aleg₁ : ys ⊆ upperBoundleg₂ : zs ⊆ upperBoundopen RawPushout using (leg₁; leg₂)-------------------------------------------------------------------------- Extending corners of a raw pushout square-- Extending the right upper corner.infixr 5 _∷ʳ₁_ _∷ʳ₂__∷ʳ₁_ : ∀ {xs ys zs : List A} {τ : xs ⊆ ys} {σ : xs ⊆ zs} →(y : A) → RawPushout τ σ → RawPushout (y ∷ʳ τ) σy ∷ʳ₁ rpo = record{ leg₁ = refl ∷ leg₁ rpo; leg₂ = y ∷ʳ leg₂ rpo}-- Extending the left lower corner._∷ʳ₂_ : ∀ {xs ys zs : List A} {τ : xs ⊆ ys} {σ : xs ⊆ zs} →(z : A) → RawPushout τ σ → RawPushout τ (z ∷ʳ σ)z ∷ʳ₂ rpo = record{ leg₁ = z ∷ʳ leg₁ rpo; leg₂ = refl ∷ leg₂ rpo}-- Extending both of these corners with equal elements.∷-rpo : ∀ {x y z : A} {xs ys zs : List A} {τ : xs ⊆ ys} {σ : xs ⊆ zs} →(x≈y : x ≈ y) (x≈z : x ≈ z) → RawPushout τ σ → RawPushout (x≈y ∷ τ) (x≈z ∷ σ)∷-rpo x≈y x≈z rpo = record{ leg₁ = sym x≈y ∷ leg₁ rpo; leg₂ = sym x≈z ∷ leg₂ rpo}-------------------------------------------------------------------------- Left-biased pushout: add elements of left extension first.⊆-pushoutˡ : ∀ {xs ys zs : List A} →(τ : xs ⊆ ys) (σ : xs ⊆ zs) → RawPushout τ σ⊆-pushoutˡ [] σ = record { leg₁ = σ ; leg₂ = ⊆-refl }⊆-pushoutˡ (y ∷ʳ τ) σ = y ∷ʳ₁ ⊆-pushoutˡ τ σ⊆-pushoutˡ τ@(_ ∷ _) (z ∷ʳ σ) = z ∷ʳ₂ ⊆-pushoutˡ τ σ⊆-pushoutˡ (x≈y ∷ τ) (x≈z ∷ σ) = ∷-rpo x≈y x≈z (⊆-pushoutˡ τ σ)-- Join two extensions, returning the upper bound and the diagonal-- of the pushout square.⊆-joinˡ : ∀ {xs ys zs : List A} →(τ : xs ⊆ ys) (σ : xs ⊆ zs) → ∃ λ us → xs ⊆ us⊆-joinˡ τ σ = RawPushout.upperBound rpo , ⊆-trans τ (leg₁ rpo)whererpo = ⊆-pushoutˡ τ σ-------------------------------------------------------------------------- Upper bound of two sublists xs,ys ⊆ zs---- Two sublists τ : xs ⊆ zs and σ : ys ⊆ zs-- can be joined in a unique way if τ and σ are respected.---- For instance, if τ : [x] ⊆ [x,y,x] and σ : [y] ⊆ [x,y,x]-- then the union will be [x,y] or [y,x], depending on whether-- τ picks the first x or the second one.---- NB: If the content of τ and σ were ignored then the union would not-- be unique. Expressing uniqueness would require a notion of equality-- of sublist proofs, which we do not (yet) have for the setoid case-- (however, for the propositional case).record UpperBound {xs ys zs} (τ : xs ⊆ zs) (σ : ys ⊆ zs) : Set (c ⊔ ℓ) wherefield{theUpperBound} : List Asub : theUpperBound ⊆ zsinj₁ : xs ⊆ theUpperBoundinj₂ : ys ⊆ theUpperBoundopen UpperBoundinfixr 5 _∷ₗ-ub_ _∷ᵣ-ub_∷ₙ-ub : ∀ {xs ys zs} {τ : xs ⊆ zs} {σ : ys ⊆ zs} {x} →UpperBound τ σ → UpperBound (x ∷ʳ τ) (x ∷ʳ σ)∷ₙ-ub u = record{ sub = _ ∷ʳ u .sub; inj₁ = u .inj₁; inj₂ = u .inj₂}_∷ₗ-ub_ : ∀ {xs ys zs} {τ : xs ⊆ zs} {σ : ys ⊆ zs} {x y} →(x≈y : x ≈ y) → UpperBound τ σ → UpperBound (x≈y ∷ τ) (y ∷ʳ σ)x≈y ∷ₗ-ub u = record{ sub = refl ∷ u .sub; inj₁ = x≈y ∷ u .inj₁; inj₂ = _ ∷ʳ u .inj₂}_∷ᵣ-ub_ : ∀ {xs ys zs} {τ : xs ⊆ zs} {σ : ys ⊆ zs} {x y} →(x≈y : x ≈ y) → UpperBound τ σ → UpperBound (y ∷ʳ τ) (x≈y ∷ σ)x≈y ∷ᵣ-ub u = record{ sub = refl ∷ u .sub; inj₁ = _ ∷ʳ u .inj₁; inj₂ = x≈y ∷ u .inj₂}_,_∷-ub_ : ∀ {xs ys zs} {τ : xs ⊆ zs} {σ : ys ⊆ zs} {x y z} →(x≈z : x ≈ z) (y≈z : y ≈ z) → UpperBound τ σ → UpperBound (x≈z ∷ τ) (y≈z ∷ σ)x≈z , y≈z ∷-ub u = record{ sub = refl ∷ u .sub; inj₁ = x≈z ∷ u .inj₁; inj₂ = y≈z ∷ u .inj₂}⊆-upper-bound : ∀ {xs ys zs} (τ : xs ⊆ zs) (σ : ys ⊆ zs) → UpperBound τ σ⊆-upper-bound [] [] = record { sub = [] ; inj₁ = [] ; inj₂ = [] }⊆-upper-bound (y ∷ʳ τ) (.y ∷ʳ σ) = ∷ₙ-ub (⊆-upper-bound τ σ)⊆-upper-bound (y ∷ʳ τ) (x≈y ∷ σ) = x≈y ∷ᵣ-ub ⊆-upper-bound τ σ⊆-upper-bound (x≈y ∷ τ) (y ∷ʳ σ) = x≈y ∷ₗ-ub ⊆-upper-bound τ σ⊆-upper-bound (x≈z ∷ τ) (y≈z ∷ σ) = x≈z , y≈z ∷-ub ⊆-upper-bound τ σ-------------------------------------------------------------------------- Disjoint union---- Upper bound of two non-overlapping sublists.⊆-disjoint-union : ∀ {xs ys zs} {τ : xs ⊆ zs} {σ : ys ⊆ zs} →Disjoint τ σ → UpperBound τ σ⊆-disjoint-union {τ = τ} {σ = σ} _ = ⊆-upper-bound τ σ
-------------------------------------------------------------------------- The Agda standard library---- Properties of the setoid sublist relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _⇒_; _Preserves_⟶_)open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Sublist.Setoid.Properties{c ℓ} (S : Setoid c ℓ) whereopen import Data.List.Base hiding (_∷ʳ_)open import Data.List.Relation.Unary.Any using (Any)import Data.Maybe.Relation.Unary.All as Maybeopen import Data.Nat.Base using (ℕ; _≤_; _≥_)import Data.Nat.Properties as ℕopen import Data.Product.Base using (∃; _,_; proj₂)open import Function.Baseopen import Function.Bundles using (_⇔_; _⤖_)open import Levelopen import Relation.Binary.Definitions using () renaming (Decidable to Decidable₂)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; refl; cong; cong₂)open import Relation.Binary.Structures using (IsDecTotalOrder)open import Relation.Unary using (Pred; Decidable; Irrelevant)open import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Decidable using (¬?; yes; no)import Data.List.Relation.Binary.Equality.Setoid as SetoidEqualityimport Data.List.Relation.Binary.Sublist.Setoid as SetoidSublistimport Data.List.Relation.Binary.Sublist.Heterogeneous.Propertiesas HeteroPropertiesimport Data.List.Membership.Setoid as SetoidMembershipopen Setoid S using (_≈_; trans) renaming (Carrier to A; refl to ≈-refl)open SetoidEquality S using (_≋_; ≋-refl)open SetoidSublist S hiding (map)open SetoidMembership S using (_∈_)privatevariablep q r s t : Levela b x y : Aas bs cs ds xs ys : List AP : Pred A pQ : Pred A qm n : ℕ-------------------------------------------------------------------------- Injectivity of constructors------------------------------------------------------------------------module _ where∷-injectiveˡ : ∀ {px qx : x ≈ y} {pxs qxs : xs ⊆ ys} →((x ∷ xs) ⊆ (y ∷ ys) ∋ px ∷ pxs) ≡ (qx ∷ qxs) → px ≡ qx∷-injectiveˡ refl = refl∷-injectiveʳ : ∀ {px qx : x ≈ y} {pxs qxs : xs ⊆ ys} →((x ∷ xs) ⊆ (y ∷ ys) ∋ px ∷ pxs) ≡ (qx ∷ qxs) → pxs ≡ qxs∷-injectiveʳ refl = refl∷ʳ-injective : ∀ {pxs qxs : xs ⊆ ys} → y ∷ʳ pxs ≡ y ∷ʳ qxs → pxs ≡ qxs∷ʳ-injective refl = refl-------------------------------------------------------------------------- Categorical properties------------------------------------------------------------------------module _ (trans-reflˡ : ∀ {x y} (p : x ≈ y) → trans ≈-refl p ≡ p) where⊆-trans-idˡ : (pxs : xs ⊆ ys) → ⊆-trans ⊆-refl pxs ≡ pxs⊆-trans-idˡ [] = refl⊆-trans-idˡ (y ∷ʳ pxs) = cong (y ∷ʳ_) (⊆-trans-idˡ pxs)⊆-trans-idˡ (x ∷ pxs) = cong₂ _∷_ (trans-reflˡ x) (⊆-trans-idˡ pxs)module _ (trans-reflʳ : ∀ {x y} (p : x ≈ y) → trans p ≈-refl ≡ p) where⊆-trans-idʳ : (pxs : xs ⊆ ys) → ⊆-trans pxs ⊆-refl ≡ pxs⊆-trans-idʳ [] = refl⊆-trans-idʳ (y ∷ʳ pxs) = cong (y ∷ʳ_) (⊆-trans-idʳ pxs)⊆-trans-idʳ (x ∷ pxs) = cong₂ _∷_ (trans-reflʳ x) (⊆-trans-idʳ pxs)module _ (≈-assoc : ∀ {w x y z} (p : w ≈ x) (q : x ≈ y) (r : y ≈ z) →trans p (trans q r) ≡ trans (trans p q) r) where⊆-trans-assoc : (ps : as ⊆ bs) (qs : bs ⊆ cs) (rs : cs ⊆ ds) →⊆-trans ps (⊆-trans qs rs) ≡ ⊆-trans (⊆-trans ps qs) rs⊆-trans-assoc ps qs (_ ∷ʳ rs) = cong (_ ∷ʳ_) (⊆-trans-assoc ps qs rs)⊆-trans-assoc ps (_ ∷ʳ qs) (_ ∷ rs) = cong (_ ∷ʳ_) (⊆-trans-assoc ps qs rs)⊆-trans-assoc (_ ∷ʳ ps) (_ ∷ qs) (_ ∷ rs) = cong (_ ∷ʳ_) (⊆-trans-assoc ps qs rs)⊆-trans-assoc (p ∷ ps) (q ∷ qs) (r ∷ rs) = cong₂ _∷_ (≈-assoc p q r) (⊆-trans-assoc ps qs rs)⊆-trans-assoc [] [] [] = refl-------------------------------------------------------------------------- Various functions' outputs are sublists------------------------------------------------------------------------tail-⊆ : ∀ xs → Maybe.All (_⊆ xs) (tail xs)tail-⊆ xs = HeteroProperties.tail-Sublist ⊆-refltake-⊆ : ∀ n xs → take n xs ⊆ xstake-⊆ n xs = HeteroProperties.take-Sublist n ⊆-refldrop-⊆ : ∀ n xs → drop n xs ⊆ xsdrop-⊆ n xs = HeteroProperties.drop-Sublist n ⊆-reflmodule _ (P? : Decidable P) wheretakeWhile-⊆ : ∀ xs → takeWhile P? xs ⊆ xstakeWhile-⊆ xs = HeteroProperties.takeWhile-Sublist P? ⊆-refldropWhile-⊆ : ∀ xs → dropWhile P? xs ⊆ xsdropWhile-⊆ xs = HeteroProperties.dropWhile-Sublist P? ⊆-reflfilter-⊆ : ∀ xs → filter P? xs ⊆ xsfilter-⊆ xs = HeteroProperties.filter-Sublist P? ⊆-reflmodule _ (P? : Decidable P) wheretakeWhile⊆filter : ∀ xs → takeWhile P? xs ⊆ filter P? xstakeWhile⊆filter xs = HeteroProperties.takeWhile-filter P? {xs} ≋-reflfilter⊆dropWhile : ∀ xs → filter P? xs ⊆ dropWhile (¬? ∘ P?) xsfilter⊆dropWhile xs = HeteroProperties.filter-dropWhile P? {xs} ≋-refl-------------------------------------------------------------------------- Various list functions are increasing wrt _⊆_-------------------------------------------------------------------------- We write f⁺ for the proof that `xs ⊆ ys → f xs ⊆ f ys`-- and f⁻ for the one that `f xs ⊆ f ys → xs ⊆ ys`.module _ where∷ˡ⁻ : a ∷ as ⊆ bs → as ⊆ bs∷ˡ⁻ = HeteroProperties.∷ˡ⁻∷ʳ⁻ : ¬ (a ≈ b) → a ∷ as ⊆ b ∷ bs → a ∷ as ⊆ bs∷ʳ⁻ = HeteroProperties.∷ʳ⁻∷⁻ : a ∷ as ⊆ b ∷ bs → as ⊆ bs∷⁻ = HeteroProperties.∷⁻-------------------------------------------------------------------------- mapmodule _ {b ℓ} (R : Setoid b ℓ) whereopen Setoid R using () renaming (Carrier to B; _≈_ to _≈′_)open SetoidSublist R using () renaming (_⊆_ to _⊆′_)map⁺ : ∀ {as bs} {f : A → B} → f Preserves _≈_ ⟶ _≈′_ →as ⊆ bs → map f as ⊆′ map f bsmap⁺ {f = f} f-resp as⊆bs =HeteroProperties.map⁺ f f (SetoidSublist.map S f-resp as⊆bs)-------------------------------------------------------------------------- _++_module _ where++⁺ˡ : ∀ cs → as ⊆ bs → as ⊆ cs ++ bs++⁺ˡ = HeteroProperties.++ˡ++⁺ʳ : ∀ cs → as ⊆ bs → as ⊆ bs ++ cs++⁺ʳ = HeteroProperties.++ʳ++⁺ : as ⊆ bs → cs ⊆ ds → as ++ cs ⊆ bs ++ ds++⁺ = HeteroProperties.++⁺++⁻ : length as ≡ length bs → as ++ cs ⊆ bs ++ ds → cs ⊆ ds++⁻ = HeteroProperties.++⁻-------------------------------------------------------------------------- takemodule _ wheretake⁺ : m ≤ n → take m xs ⊆ take n xstake⁺ m≤n = HeteroProperties.take⁺ m≤n ≋-refl-------------------------------------------------------------------------- dropmodule _ wheredrop⁺ : m ≥ n → xs ⊆ ys → drop m xs ⊆ drop n ysdrop⁺ = HeteroProperties.drop⁺module _ wheredrop⁺-≥ : m ≥ n → drop m xs ⊆ drop n xsdrop⁺-≥ m≥n = drop⁺ m≥n ⊆-reflmodule _ wheredrop⁺-⊆ : ∀ n → xs ⊆ ys → drop n xs ⊆ drop n ysdrop⁺-⊆ n xs⊆ys = drop⁺ {n} ℕ.≤-refl xs⊆ys-------------------------------------------------------------------------- takeWhile / dropWhilemodule _ (P? : Decidable P) (Q? : Decidable Q) wheretakeWhile⁺ : ∀ {xs} → (∀ {a b} → a ≈ b → P a → Q b) →takeWhile P? xs ⊆ takeWhile Q? xstakeWhile⁺ {xs} P⇒Q = HeteroProperties.⊆-takeWhile-Sublist P? Q? {xs} P⇒Q ≋-refldropWhile⁺ : ∀ {xs} → (∀ {a b} → a ≈ b → Q b → P a) →dropWhile P? xs ⊆ dropWhile Q? xsdropWhile⁺ {xs} P⇒Q = HeteroProperties.⊇-dropWhile-Sublist P? Q? {xs} P⇒Q ≋-refl-------------------------------------------------------------------------- filtermodule _ (P? : Decidable P) (Q? : Decidable Q) wherefilter⁺ : (∀ {a b} → a ≈ b → P a → Q b) →as ⊆ bs → filter P? as ⊆ filter Q? bsfilter⁺ = HeteroProperties.⊆-filter-Sublist P? Q?-------------------------------------------------------------------------- reversemodule _ wherereverseAcc⁺ : as ⊆ bs → cs ⊆ ds →reverseAcc cs as ⊆ reverseAcc ds bsreverseAcc⁺ = HeteroProperties.reverseAcc⁺ʳ++⁺ : as ⊆ bs → cs ⊆ ds →as ʳ++ cs ⊆ bs ʳ++ dsʳ++⁺ = reverseAcc⁺reverse⁺ : as ⊆ bs → reverse as ⊆ reverse bsreverse⁺ = HeteroProperties.reverse⁺reverse⁻ : reverse as ⊆ reverse bs → as ⊆ bsreverse⁻ = HeteroProperties.reverse⁻-------------------------------------------------------------------------- mergemodule _ {ℓ′} {_≤_ : Rel A ℓ′} (_≤?_ : Decidable₂ _≤_) where⊆-mergeˡ : ∀ xs ys → xs ⊆ merge _≤?_ xs ys⊆-mergeˡ [] ys = minimum ys⊆-mergeˡ (x ∷ xs) [] = ⊆-refl⊆-mergeˡ (x ∷ xs) (y ∷ ys)with x ≤? y | ⊆-mergeˡ xs (y ∷ ys)| ⊆-mergeˡ (x ∷ xs) ys... | yes x≤y | rec | _ = ≈-refl ∷ rec... | no x≰y | _ | rec = y ∷ʳ rec⊆-mergeʳ : ∀ xs ys → ys ⊆ merge _≤?_ xs ys⊆-mergeʳ [] ys = ⊆-refl⊆-mergeʳ (x ∷ xs) [] = minimum (merge _≤?_ (x ∷ xs) [])⊆-mergeʳ (x ∷ xs) (y ∷ ys)with x ≤? y | ⊆-mergeʳ xs (y ∷ ys)| ⊆-mergeʳ (x ∷ xs) ys... | yes x≤y | rec | _ = x ∷ʳ rec... | no x≰y | _ | rec = ≈-refl ∷ rec-------------------------------------------------------------------------- Inversion lemmas------------------------------------------------------------------------module _ where∷⁻¹ : a ≈ b → as ⊆ bs ⇔ a ∷ as ⊆ b ∷ bs∷⁻¹ = HeteroProperties.∷⁻¹∷ʳ⁻¹ : ¬ (a ≈ b) → a ∷ as ⊆ bs ⇔ a ∷ as ⊆ b ∷ bs∷ʳ⁻¹ = HeteroProperties.∷ʳ⁻¹-------------------------------------------------------------------------- Other------------------------------------------------------------------------module _ wherelength-mono-≤ : as ⊆ bs → length as ≤ length bslength-mono-≤ = HeteroProperties.length-mono-≤-------------------------------------------------------------------------- Conversion to and from list equalityto-≋ : length as ≡ length bs → as ⊆ bs → as ≋ bsto-≋ = HeteroProperties.toPointwise-------------------------------------------------------------------------- Irrelevant special case[]⊆-irrelevant : Irrelevant ([] ⊆_)[]⊆-irrelevant = HeteroProperties.Sublist-[]-irrelevant-------------------------------------------------------------------------- (to/from)∈ is a bijectionmodule _ whereto∈-injective : ∀ {p q : [ x ] ⊆ xs} → to∈ p ≡ to∈ q → p ≡ qto∈-injective = HeteroProperties.toAny-injectivefrom∈-injective : ∀ {p q : x ∈ xs} → from∈ p ≡ from∈ q → p ≡ qfrom∈-injective = HeteroProperties.fromAny-injectiveto∈∘from∈≗id : ∀ (p : x ∈ xs) → to∈ (from∈ p) ≡ pto∈∘from∈≗id = HeteroProperties.toAny∘fromAny≗id[x]⊆xs⤖x∈xs : ([ x ] ⊆ xs) ⤖ (x ∈ xs)[x]⊆xs⤖x∈xs = HeteroProperties.Sublist-[x]-bijection-------------------------------------------------------------------------- Properties of Disjoint(ness) and DisjointUnionopen HeteroProperties.Disjointness {R = _≈_} publicopen HeteroProperties.DisjointnessMonotonicity {R = _≈_} {S = _≈_} {T = _≈_} trans public-- Shrinking one of two disjoint lists preserves disjointness.-- We would have liked to define shrinkDisjointˡ σ = shrinkDisjoint σ ⊆-refl-- but alas, this is only possible for groupoids, not setoids in general.shrinkDisjointˡ : ∀ {xs ys zs us} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} (σ : us ⊆ xs) →Disjoint τ₁ τ₂ →Disjoint (⊆-trans σ τ₁) τ₂-- Not affected by σ:shrinkDisjointˡ σ (y ∷ₙ d) = y ∷ₙ shrinkDisjointˡ σ dshrinkDisjointˡ σ (y≈z ∷ᵣ d) = y≈z ∷ᵣ shrinkDisjointˡ σ d-- In σ: keep x.shrinkDisjointˡ (u≈x ∷ σ) (x≈z ∷ₗ d) = trans u≈x x≈z ∷ₗ shrinkDisjointˡ σ d-- Not in σ: drop x.shrinkDisjointˡ (x ∷ʳ σ) (x≈z ∷ₗ d) = _ ∷ₙ shrinkDisjointˡ σ dshrinkDisjointˡ [] [] = []shrinkDisjointʳ : ∀ {xs ys zs vs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} (σ : vs ⊆ ys) →Disjoint τ₁ τ₂ →Disjoint τ₁ (⊆-trans σ τ₂)-- Not affected by σ:shrinkDisjointʳ σ (y ∷ₙ d) = y ∷ₙ shrinkDisjointʳ σ dshrinkDisjointʳ σ (x≈z ∷ₗ d) = x≈z ∷ₗ shrinkDisjointʳ σ d-- In σ: keep y.shrinkDisjointʳ (v≈y ∷ σ) (y≈z ∷ᵣ d) = trans v≈y y≈z ∷ᵣ shrinkDisjointʳ σ d-- Not in σ: drop y.shrinkDisjointʳ (y ∷ʳ σ) (y≈z ∷ᵣ d) = _ ∷ₙ shrinkDisjointʳ σ dshrinkDisjointʳ [] [] = []
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the sublist relation. This is commonly-- known as Order Preserving Embeddings (OPE).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Propositional{a} {A : Set a} whereopen import Data.List.Base using (List)open import Data.List.Relation.Binary.Equality.Propositional using (≋⇒≡)import Data.List.Relation.Binary.Sublist.Setoid as SetoidSublistopen import Data.List.Relation.Unary.Any using (Any)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Preorder; Poset)open import Relation.Binary.Structures using (IsPreorder; IsPartialOrder)open import Relation.Binary.Definitions using (Antisymmetric)open import Relation.Binary.PropositionalEquality.Coreusing (subst; _≡_; refl)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; isEquivalence)open import Relation.Unary using (Pred)-------------------------------------------------------------------------- Re-export definition and operations from setoid sublistsopen SetoidSublist (setoid A) publichiding(lookup; ⊆-reflexive; ⊆-antisym; ⊆-isPreorder; ⊆-isPartialOrder; ⊆-preorder; ⊆-poset)-------------------------------------------------------------------------- Additional operationsmodule _ {p} {P : Pred A p} wherelookup : ∀ {xs ys} → xs ⊆ ys → Any P xs → Any P yslookup = SetoidSublist.lookup (setoid A) (subst _)-------------------------------------------------------------------------- Relational properties⊆-reflexive : _≡_ ⇒ _⊆_⊆-reflexive refl = ⊆-refl⊆-antisym : Antisymmetric _≡_ _⊆_⊆-antisym xs⊆ys ys⊆xs = ≋⇒≡ (SetoidSublist.⊆-antisym (setoid A) xs⊆ys ys⊆xs)⊆-isPreorder : IsPreorder _≡_ _⊆_⊆-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-isPartialOrder : IsPartialOrder _≡_ _⊆_⊆-isPartialOrder = record{ isPreorder = ⊆-isPreorder; antisym = ⊆-antisym}⊆-preorder : Preorder a a a⊆-preorder = record{ isPreorder = ⊆-isPreorder}⊆-poset : Poset a a a⊆-poset = record{ isPartialOrder = ⊆-isPartialOrder}-------------------------------------------------------------------------- Separating two sublists---- Two possibly overlapping sublists τ : xs ⊆ zs and σ : ys ⊆ zs-- can be turned into disjoint lists τρ : xs ⊆ zs and τρ : ys ⊆ zs′-- by duplicating all entries of zs that occur both in xs and ys,-- resulting in an extension ρ : zs ⊆ zs′ of zs.record Separation {xs ys zs} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) : Set a wherefield{inflation} : List Aseparator₁ : zs ⊆ inflationseparator₂ : zs ⊆ inflationseparated₁ = ⊆-trans τ₁ separator₁separated₂ = ⊆-trans τ₂ separator₂fielddisjoint : Disjoint separated₁ separated₂infixr 5 _∷ₙ-Sep_ _∷ₗ-Sep_ _∷ᵣ-Sep_-- Empty separation[]-Sep : Separation [] [][]-Sep = record { separator₁ = [] ; separator₂ = [] ; disjoint = [] }-- Weaken a separation_∷ₙ-Sep_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →∀ z → Separation τ₁ τ₂ → Separation (z ∷ʳ τ₁) (z ∷ʳ τ₂)z ∷ₙ-Sep record{ separator₁ = ρ₁; separator₂ = ρ₂; disjoint = d } = record{ separator₁ = refl ∷ ρ₁; separator₂ = refl ∷ ρ₂; disjoint = z ∷ₙ d}-- Extend a separation by an element of the first sublist.---- Note: this requires a category law from the underlying equality,-- trans x=z refl = x=z, thus, separation is not available for Sublist.Setoid._∷ₗ-Sep_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →∀ {x z} (x≡z : x ≡ z) → Separation τ₁ τ₂ → Separation (x≡z ∷ τ₁) (z ∷ʳ τ₂)refl ∷ₗ-Sep record{ separator₁ = ρ₁; separator₂ = ρ₂; disjoint = d } = record{ separator₁ = refl ∷ ρ₁; separator₂ = refl ∷ ρ₂; disjoint = refl ∷ₗ d}-- Extend a separation by an element of the second sublist._∷ᵣ-Sep_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →∀ {y z} (y≡z : y ≡ z) → Separation τ₁ τ₂ → Separation (z ∷ʳ τ₁) (y≡z ∷ τ₂)refl ∷ᵣ-Sep record{ separator₁ = ρ₁; separator₂ = ρ₂; disjoint = d } = record{ separator₁ = refl ∷ ρ₁; separator₂ = refl ∷ ρ₂; disjoint = refl ∷ᵣ d}-- Extend a separation by a common element of both sublists.---- Left-biased: the left separator gets the first copy-- of the common element.∷-Sepˡ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →∀ {x y z} (x≡z : x ≡ z) (y≡z : y ≡ z) →Separation τ₁ τ₂ → Separation (x≡z ∷ τ₁) (y≡z ∷ τ₂)∷-Sepˡ refl refl record{ separator₁ = ρ₁; separator₂ = ρ₂; disjoint = d } = record{ separator₁ = _ ∷ʳ refl ∷ ρ₁; separator₂ = refl ∷ _ ∷ʳ ρ₂; disjoint = refl ∷ᵣ (refl ∷ₗ d)}-- Left-biased separation of two sublists. Of common elements,-- the first sublist receives the first copy.separateˡ : ∀ {xs ys zs} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → Separation τ₁ τ₂separateˡ [] [] = []-Sepseparateˡ (z ∷ʳ τ₁) (z ∷ʳ τ₂) = z ∷ₙ-Sep separateˡ τ₁ τ₂separateˡ (z ∷ʳ τ₁) (y≡z ∷ τ₂) = y≡z ∷ᵣ-Sep separateˡ τ₁ τ₂separateˡ (x≡z ∷ τ₁) (z ∷ʳ τ₂) = x≡z ∷ₗ-Sep separateˡ τ₁ τ₂separateˡ (x≡z ∷ τ₁) (y≡z ∷ τ₂) = ∷-Sepˡ x≡z y≡z (separateˡ τ₁ τ₂)
-------------------------------------------------------------------------- The Agda standard library---- Slices in the propositional sublist category.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Propositional.Slice{a} {A : Set a} whereopen import Data.List.Base using (List)open import Data.List.Relation.Binary.Sublist.Propositionalusing (_⊆_; UpperBound; ⊆-trans; ∷ₙ-ub; _∷ʳ_; _∷ₗ-ub_; _∷_; _∷ᵣ-ub_;_,_∷-ub_; ⊆-upper-bound; [])open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong)-------------------------------------------------------------------------- A Union where the triangles commute is a-- Cospan in the slice category (_ ⊆ zs).record IsCospan {xs ys zs : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} (u : UpperBound τ₁ τ₂) : Set a wherefieldtri₁ : ⊆-trans (UpperBound.inj₁ u) (UpperBound.sub u) ≡ τ₁tri₂ : ⊆-trans (UpperBound.inj₂ u) (UpperBound.sub u) ≡ τ₂record Cospan {xs ys zs : List A} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) : Set a wherefieldupperBound : UpperBound τ₁ τ₂isCospan : IsCospan upperBoundopen UpperBound upperBound publicopen IsCospan isCospan publicopen IsCospanopen Cospanmodule _{x : A} {xs ys zs : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs}{u : UpperBound τ₁ τ₂} (c : IsCospan u) whereopen UpperBound uopen IsCospan c∷ₙ-cospan : IsCospan (∷ₙ-ub u)∷ₙ-cospan = record{ tri₁ = cong (x ∷ʳ_) (c .tri₁); tri₂ = cong (x ∷ʳ_) (c .tri₂)}∷ₗ-cospan : IsCospan (refl {x = x} ∷ₗ-ub u)∷ₗ-cospan = record{ tri₁ = cong (refl ∷_) (c .tri₁); tri₂ = cong (x ∷ʳ_) (c .tri₂)}∷ᵣ-cospan : IsCospan (refl {x = x} ∷ᵣ-ub u)∷ᵣ-cospan = record{ tri₁ = cong (x ∷ʳ_) (c .tri₁); tri₂ = cong (refl ∷_) (c .tri₂)}∷-cospan : IsCospan (refl {x = x} , refl {x = x} ∷-ub u)∷-cospan = record{ tri₁ = cong (refl ∷_) (c .tri₁); tri₂ = cong (refl ∷_) (c .tri₂)}⊆-upper-bound-is-cospan : ∀ {xs ys zs : List A} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) →IsCospan (⊆-upper-bound τ₁ τ₂)⊆-upper-bound-is-cospan [] [] = record { tri₁ = refl ; tri₂ = refl }⊆-upper-bound-is-cospan (z ∷ʳ τ₁) (.z ∷ʳ τ₂) = ∷ₙ-cospan (⊆-upper-bound-is-cospan τ₁ τ₂)⊆-upper-bound-is-cospan (z ∷ʳ τ₁) (refl ∷ τ₂) = ∷ᵣ-cospan (⊆-upper-bound-is-cospan τ₁ τ₂)⊆-upper-bound-is-cospan (refl ∷ τ₁) (z ∷ʳ τ₂) = ∷ₗ-cospan (⊆-upper-bound-is-cospan τ₁ τ₂)⊆-upper-bound-is-cospan (refl ∷ τ₁) (refl ∷ τ₂) = ∷-cospan (⊆-upper-bound-is-cospan τ₁ τ₂)⊆-upper-bound-cospan : ∀ {xs ys zs : List A} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) →Cospan τ₁ τ₂⊆-upper-bound-cospan τ₁ τ₂ = record{ upperBound = ⊆-upper-bound τ₁ τ₂; isCospan = ⊆-upper-bound-is-cospan τ₁ τ₂}
-------------------------------------------------------------------------- The Agda standard library---- Sublist-related properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Propositional.Properties{a} {A : Set a} whereopen import Data.List.Base using (List; []; _∷_; map)open import Data.List.Membership.Propositional using (_∈_)open import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Relation.Unary.Any.Propertiesusing (here-injective; there-injective)open import Data.List.Relation.Binary.Sublist.Propositionalhiding (map)import Data.List.Relation.Binary.Sublist.Setoid.Propertiesas SetoidPropertiesopen import Data.Product.Base using (∃; _,_; proj₂)open import Function.Base using (id; _∘_; _∘′_)open import Level using (Level)open import Relation.Binary.Definitions using (_Respects_)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; refl; cong; _≗_; trans)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; subst-injective; trans-reflʳ; trans-assoc)open import Relation.Unary using (Pred)privatevariableb ℓ : LevelB : Set b-------------------------------------------------------------------------- Re-exporting setoid propertiesopen SetoidProperties (setoid A) publichiding (map⁺; ⊆-trans-idˡ; ⊆-trans-idʳ; ⊆-trans-assoc)map⁺ : ∀ {as bs} (f : A → B) → as ⊆ bs → map f as ⊆ map f bsmap⁺ {B = B} f = SetoidProperties.map⁺ (setoid A) (setoid B) (cong f)-------------------------------------------------------------------------- Category laws for _⊆_⊆-trans-idˡ : ∀ {xs ys : List A} {τ : xs ⊆ ys} →⊆-trans ⊆-refl τ ≡ τ⊆-trans-idˡ {τ = τ} = SetoidProperties.⊆-trans-idˡ (setoid A) (λ _ → refl) τ⊆-trans-idʳ : ∀ {xs ys : List A} {τ : xs ⊆ ys} →⊆-trans τ ⊆-refl ≡ τ⊆-trans-idʳ {τ = τ} = SetoidProperties.⊆-trans-idʳ (setoid A) trans-reflʳ τ-- Note: The associativity law is oriented such that rewriting with it-- may trigger reductions of ⊆-trans, which matches first on its-- second argument and then on its first argument.⊆-trans-assoc : ∀ {ws xs ys zs : List A}{τ₁ : ws ⊆ xs} {τ₂ : xs ⊆ ys} {τ₃ : ys ⊆ zs} →⊆-trans τ₁ (⊆-trans τ₂ τ₃) ≡ ⊆-trans (⊆-trans τ₁ τ₂) τ₃⊆-trans-assoc {τ₁ = τ₁} {τ₂ = τ₂} {τ₃ = τ₃} =SetoidProperties.⊆-trans-assoc (setoid A) (λ p _ _ → ≡.sym (trans-assoc p)) τ₁ τ₂ τ₃-------------------------------------------------------------------------- Laws concerning ⊆-trans and ∷ˡ⁻⊆-trans-∷ˡ⁻ᵣ : ∀ {y} {xs ys zs : List A} {τ : xs ⊆ ys} {σ : (y ∷ ys) ⊆ zs} →⊆-trans τ (∷ˡ⁻ σ) ≡ ⊆-trans (y ∷ʳ τ) σ⊆-trans-∷ˡ⁻ᵣ {σ = x ∷ σ} = refl⊆-trans-∷ˡ⁻ᵣ {σ = y ∷ʳ σ} = cong (y ∷ʳ_) ⊆-trans-∷ˡ⁻ᵣ⊆-trans-∷ˡ⁻ₗ : ∀ {x} {xs ys zs : List A} {τ : (x ∷ xs) ⊆ ys} {σ : ys ⊆ zs} →⊆-trans (∷ˡ⁻ τ) σ ≡ ∷ˡ⁻ (⊆-trans τ σ)⊆-trans-∷ˡ⁻ₗ {σ = y ∷ʳ σ} = cong (y ∷ʳ_) ⊆-trans-∷ˡ⁻ₗ⊆-trans-∷ˡ⁻ₗ {τ = y ∷ʳ τ} {σ = refl ∷ σ} = cong (y ∷ʳ_) ⊆-trans-∷ˡ⁻ₗ⊆-trans-∷ˡ⁻ₗ {τ = refl ∷ τ} {σ = refl ∷ σ} = refl⊆-∷ˡ⁻trans-∷ : ∀ {y} {xs ys zs : List A} {τ : xs ⊆ ys} {σ : (y ∷ ys) ⊆ zs} →∷ˡ⁻ (⊆-trans (refl ∷ τ) σ) ≡ ⊆-trans (y ∷ʳ τ) σ⊆-∷ˡ⁻trans-∷ {σ = y ∷ʳ σ} = cong (y ∷ʳ_) ⊆-∷ˡ⁻trans-∷⊆-∷ˡ⁻trans-∷ {σ = refl ∷ σ} = refl-------------------------------------------------------------------------- Relationships to other predicates-- All P is a contravariant functor from _⊆_ to Set.All-resp-⊆ : {P : Pred A ℓ} → (All P) Respects _⊇_All-resp-⊆ [] [] = []All-resp-⊆ (_ ∷ʳ p) (_ ∷ xs) = All-resp-⊆ p xsAll-resp-⊆ (refl ∷ p) (x ∷ xs) = x ∷ All-resp-⊆ p xs-- Any P is a covariant functor from _⊆_ to Set.Any-resp-⊆ : {P : Pred A ℓ} → (Any P) Respects _⊆_Any-resp-⊆ = lookup-------------------------------------------------------------------------- Functor laws for All-resp-⊆-- First functor law: identity.All-resp-⊆-refl : ∀ {P : Pred A ℓ} {xs : List A} →All-resp-⊆ ⊆-refl ≗ id {A = All P xs}All-resp-⊆-refl [] = reflAll-resp-⊆-refl (p ∷ ps) = cong (p ∷_) (All-resp-⊆-refl ps)-- Second functor law: composition.All-resp-⊆-trans : ∀ {P : Pred A ℓ} {xs ys zs} {τ : xs ⊆ ys} (τ′ : ys ⊆ zs) →All-resp-⊆ {P = P} (⊆-trans τ τ′) ≗ All-resp-⊆ τ ∘ All-resp-⊆ τ′All-resp-⊆-trans (_ ∷ʳ τ′) (p ∷ ps) = All-resp-⊆-trans τ′ psAll-resp-⊆-trans {τ = _ ∷ʳ _ } (refl ∷ τ′) (p ∷ ps) = All-resp-⊆-trans τ′ psAll-resp-⊆-trans {τ = refl ∷ _} (refl ∷ τ′) (p ∷ ps) = cong (p ∷_) (All-resp-⊆-trans τ′ ps)All-resp-⊆-trans {τ = [] } ([] ) [] = refl-------------------------------------------------------------------------- Functor laws for Any-resp-⊆ / lookup-- First functor law: identity.Any-resp-⊆-refl : ∀ {P : Pred A ℓ} {xs} →Any-resp-⊆ ⊆-refl ≗ id {A = Any P xs}Any-resp-⊆-refl (here p) = reflAny-resp-⊆-refl (there i) = cong there (Any-resp-⊆-refl i)lookup-⊆-refl = Any-resp-⊆-refl-- Second functor law: composition.Any-resp-⊆-trans : ∀ {P : Pred A ℓ} {xs ys zs} {τ : xs ⊆ ys} (τ′ : ys ⊆ zs) →Any-resp-⊆ {P = P} (⊆-trans τ τ′) ≗ Any-resp-⊆ τ′ ∘ Any-resp-⊆ τAny-resp-⊆-trans (_ ∷ʳ τ′) i = cong there (Any-resp-⊆-trans τ′ i)Any-resp-⊆-trans {τ = _ ∷ʳ _} (_ ∷ τ′) i = cong there (Any-resp-⊆-trans τ′ i)Any-resp-⊆-trans {τ = _ ∷ _} (_ ∷ τ′) (there i) = cong there (Any-resp-⊆-trans τ′ i)Any-resp-⊆-trans {τ = refl ∷ _} (_ ∷ τ′) (here _) = reflAny-resp-⊆-trans {τ = [] } [] ()lookup-⊆-trans = Any-resp-⊆-trans-------------------------------------------------------------------------- The `lookup` function for `xs ⊆ ys` is injective.---- Note: `lookup` can be seen as a strictly increasing reindexing-- function for indices into `xs`, producing indices into `ys`.lookup-injective : ∀ {P : Pred A ℓ} {xs ys} {τ : xs ⊆ ys} {i j : Any P xs} →lookup τ i ≡ lookup τ j → i ≡ jlookup-injective {τ = _ ∷ʳ _} = lookup-injective ∘′ there-injectivelookup-injective {τ = x≡y ∷ _} {here _} {here _} = cong here ∘′ subst-injective x≡y ∘′ here-injective-- Note: instead of using subst-injective, we could match x≡y against refl on the lhs.-- However, this turns the following clause into a non-strict match.lookup-injective {τ = _ ∷ _} {there _} {there _} = cong there ∘′ lookup-injective ∘′ there-injective-------------------------------------------------------------------------- from∈ ∘ to∈ turns a sublist morphism τ : x∷xs ⊆ ys into a morphism-- [x] ⊆ ys. The same morphism is obtained by pre-composing τ with-- the canonial morphism [x] ⊆ x∷xs.---- Note: This lemma does not hold for Sublist.Setoid, but could hold for-- a hypothetical Sublist.Groupoid where trans refl = id.from∈∘to∈ : ∀ {x : A} {xs ys} (τ : x ∷ xs ⊆ ys) →from∈ (to∈ τ) ≡ ⊆-trans (refl ∷ minimum xs) τfrom∈∘to∈ (x≡y ∷ τ) = cong (x≡y ∷_) ([]⊆-irrelevant _ _)from∈∘to∈ (y ∷ʳ τ) = cong (y ∷ʳ_) (from∈∘to∈ τ)from∈∘lookup : ∀{x : A} {xs ys} (τ : xs ⊆ ys) (i : x ∈ xs) →from∈ (lookup τ i) ≡ ⊆-trans (from∈ i) τfrom∈∘lookup (y ∷ʳ τ) i = cong (y ∷ʳ_) (from∈∘lookup τ i)from∈∘lookup (_ ∷ τ) (there i) = cong (_ ∷ʳ_) (from∈∘lookup τ i)from∈∘lookup (refl ∷ τ) (here refl) = cong (refl ∷_) ([]⊆-irrelevant _ _)-------------------------------------------------------------------------- Weak pushout (wpo)-- A raw pushout is a weak pushout if the pushout square commutes.IsWeakPushout : ∀{xs ys zs : List A} {τ : xs ⊆ ys} {σ : xs ⊆ zs} →RawPushout τ σ → Set aIsWeakPushout {τ = τ} {σ = σ} rpo =⊆-trans τ (RawPushout.leg₁ rpo) ≡⊆-trans σ (RawPushout.leg₂ rpo)-- Joining two list extensions with ⊆-pushout produces a weak pushout.⊆-pushoutˡ-is-wpo : ∀{xs ys zs : List A} (τ : xs ⊆ ys) (σ : xs ⊆ zs) →IsWeakPushout (⊆-pushoutˡ τ σ)⊆-pushoutˡ-is-wpo [] σrewrite ⊆-trans-idʳ {τ = σ}= ⊆-trans-idˡ {xs = []}⊆-pushoutˡ-is-wpo (y ∷ʳ τ) σ = cong (y ∷ʳ_) (⊆-pushoutˡ-is-wpo τ σ)⊆-pushoutˡ-is-wpo (x≡y ∷ τ) (z ∷ʳ σ) = cong (z ∷ʳ_) (⊆-pushoutˡ-is-wpo (x≡y ∷ τ) σ)⊆-pushoutˡ-is-wpo (refl ∷ τ) (refl ∷ σ) = cong (refl ∷_) (⊆-pushoutˡ-is-wpo τ σ)-------------------------------------------------------------------------- Properties of disjointness-- From τ₁ ⊎ τ₂ = τ, compute the injection ι₁ such that τ₁ = ⊆-trans ι₁ τ.DisjointUnion-inj₁ : ∀ {xs ys zs xys : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : xys ⊆ zs} →DisjointUnion τ₁ τ₂ τ → ∃ λ (ι₁ : xs ⊆ xys) → ⊆-trans ι₁ τ ≡ τ₁DisjointUnion-inj₁ [] = [] , reflDisjointUnion-inj₁ (y ∷ₙ d) = _ , cong (y ∷ʳ_) (proj₂ (DisjointUnion-inj₁ d))DisjointUnion-inj₁ (x≈y ∷ₗ d) = refl ∷ _ , cong (x≈y ∷_) (proj₂ (DisjointUnion-inj₁ d))DisjointUnion-inj₁ (x≈y ∷ᵣ d) = _ ∷ʳ _ , cong (_ ∷ʳ_) (proj₂ (DisjointUnion-inj₁ d))-- From τ₁ ⊎ τ₂ = τ, compute the injection ι₂ such that τ₂ = ⊆-trans ι₂ τ.DisjointUnion-inj₂ : ∀ {xs ys zs xys : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : xys ⊆ zs} →DisjointUnion τ₁ τ₂ τ → ∃ λ (ι₂ : ys ⊆ xys) → ⊆-trans ι₂ τ ≡ τ₂DisjointUnion-inj₂ [] = [] , reflDisjointUnion-inj₂ (y ∷ₙ d) = _ , cong (y ∷ʳ_) (proj₂ (DisjointUnion-inj₂ d))DisjointUnion-inj₂ (x≈y ∷ᵣ d) = refl ∷ _ , cong (x≈y ∷_) (proj₂ (DisjointUnion-inj₂ d))DisjointUnion-inj₂ (x≈y ∷ₗ d) = _ ∷ʳ _ , cong (_ ∷ʳ_) (proj₂ (DisjointUnion-inj₂ d))-- A sublist σ disjoint to both τ₁ and τ₂ is an equalizer-- for the separators of τ₁ and τ₂.equalize-separators : ∀ {us xs ys zs : List A}{σ : us ⊆ zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} (let s = separateˡ τ₁ τ₂) →Disjoint σ τ₁ → Disjoint σ τ₂ →⊆-trans σ (Separation.separator₁ s) ≡⊆-trans σ (Separation.separator₂ s)equalize-separators [] [] = reflequalize-separators (y ∷ₙ d₁) (.y ∷ₙ d₂) = cong (y ∷ʳ_) (equalize-separators d₁ d₂)equalize-separators (y ∷ₙ d₁) (refl ∷ᵣ d₂) = cong (y ∷ʳ_) (equalize-separators d₁ d₂)equalize-separators (refl ∷ᵣ d₁) (y ∷ₙ d₂) = cong (y ∷ʳ_) (equalize-separators d₁ d₂)equalize-separators {τ₁ = refl ∷ _} {τ₂ = refl ∷ _} -- match here to work around deficiency of Agda's forcing translation(_ ∷ᵣ d₁) (_ ∷ᵣ d₂) = cong (_ ∷ʳ_) (cong (_ ∷ʳ_) (equalize-separators d₁ d₂))equalize-separators (x≈y ∷ₗ d₁) (.x≈y ∷ₗ d₂) = cong (trans x≈y refl ∷_) (equalize-separators d₁ d₂)
-------------------------------------------------------------------------- The Agda standard library---- A larger example for sublists (propositional case):-- Simply-typed lambda terms with globally unique variables-- (both bound and free ones).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Propositional.Example.UniqueBoundVariables (Base : Set) whereopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; cong; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningopen import Data.List.Base using (List; []; _∷_; [_])open import Data.List.Membership.Propositional using (_∈_)open import Data.List.Relation.Unary.All using (Null; [])open import Data.List.Relation.Binary.Sublist.Propositional using( _⊆_; []; _∷_; _∷ʳ_; ⊆-refl; ⊆-trans; minimum; from∈; to∈; lookup; ⊆-pushoutˡ; RawPushout; Disjoint; DisjointUnion; separateˡ; Separation)open import Data.List.Relation.Binary.Sublist.Propositional.Properties using( ∷ˡ⁻; ⊆-trans-assoc; from∈∘to∈; from∈∘lookup; lookup-⊆-trans; ⊆-pushoutˡ-is-wpo; Disjoint→DisjointUnion; DisjointUnion→Disjoint; Disjoint-sym; DisjointUnion-inj₁; DisjointUnion-inj₂; DisjointUnion-[]ʳ; weakenDisjoint; weakenDisjointUnion; shrinkDisjointˡ; disjoint⇒disjoint-to-union; DisjointUnion-fromAny∘toAny-∷ˡ⁻; equalize-separators)open import Data.Product.Base using (_,_; proj₁; proj₂)infixr 8 _⇒_infix 1 _⊢_~_▷_-- Simple types over a set Base of base types.data Ty : Set wherebase : (o : Base) → Ty_⇒_ : (a b : Ty) → Ty-- Typing contexts are lists of types.Cxt = List Tyvariablea b : TyΓ Δ : Cxtx y : a ∈ Γ-- The familiar intrinsically well-typed formulation of STLC-- where a de Bruijn index x is a pointer into the context.module DeBruijn wheredata Tm (Δ : Cxt) : (a : Ty) → Set wherevar : (x : a ∈ Δ) → Tm Δ aabs : (t : Tm (a ∷ Δ) b) → Tm Δ (a ⇒ b)app : (t : Tm Δ (a ⇒ b)) (u : Tm Δ a) → Tm Δ b-- We formalize now intrinsically well-typed STLC with-- named variables that are globally unique, i.e.,-- each variable can be bound at most once.-- List of bound variables of a term.BVars = List TyvariableB : BVarsnoBV : Null B-- There is a single global context Γ of all variables used in the terms.-- Each list of bound variables B is a sublist of Γ.variableβ βₜ βᵤ yβ β\y : B ⊆ Γ-- Named terms are parameterized by a sublist β : B ⊆ Γ of bound variables.-- Variables outside B can occur as free variables in a term.---- * Variables x do not contain any bound variables (Null B).---- * The bound variables of an application (t u) is the disjoint union-- of the bound variables βₜ of t and βᵤ of u.---- * The bound variables β of an abstraction λyt is the disjoint union-- of the single variable y and the bound variables β\y of t.module UniquelyNamed wheredata Tm (β : B ⊆ Γ) : (a : Ty) → Set wherevar : (noBV : Null B)(x : a ∈ Γ)→ Tm β aabs : (y : a ∈ Γ)(y# : DisjointUnion (from∈ y) β\y β)(t : Tm β\y b)→ Tm β (a ⇒ b)app : (t : Tm βₜ (a ⇒ b))(u : Tm βᵤ a)(t#u : DisjointUnion βₜ βᵤ β)→ Tm β bpattern var! x = var [] x-- Bound variables β : B ⊆ Γ can be considered in a larger context Γ′-- obtained by γ : Γ ⊆ Γ′. The embedding β′ : B ⊆ Γ′ is simply the-- composition of β and γ, and terms can be coerced recursively:weakenBV : ∀ {Γ B Γ′} {β : B ⊆ Γ} (γ : Γ ⊆ Γ′) →Tm β a → Tm (⊆-trans β γ) aweakenBV γ (var noBV x) = var noBV (lookup γ x)weakenBV γ (app t u t#u) = app (weakenBV γ t) (weakenBV γ u) (weakenDisjointUnion γ t#u)weakenBV γ (abs y y# t) = abs y′ y′# (weakenBV γ t)wherey′ = lookup γ y-- Typing: y′# : DisjointUnion (from∈ y′) (⊆-trans β\y γ) (⊆-trans β γ)y′# = subst (λ □ → DisjointUnion □ _ _) (sym (from∈∘lookup _ _)) (weakenDisjointUnion γ y#)-- We bring de Bruijn terms into scope as Exp.open DeBruijn renaming (Tm to Exp)open UniquelyNamedvariablet u : Tm β af e : Exp Δ a-- Relating de Bruijn terms and uniquely named terms.---- The judgement δ ⊢ e ~ β ▷ t relates a de Bruijn term e with-- potentially free variables δ : Δ ⊆ Γ to a named term t with exact-- bound variables β : B ⊆ Γ. The intention is to relate exactly the-- terms with the same meaning.---- The judgement will imply the disjointness of Δ and B.variableδ yδ : Δ ⊆ Γdata _⊢_~_▷_ {Γ Δ : Cxt} (δ : Δ ⊆ Γ) : ∀{a} (e : Exp Δ a) {B} (β : B ⊆ Γ) (t : Tm β a) → Set where-- Free de Bruijn index x : a ∈ Δ is related to free variable-- y : a ∈ Γ if δ : Δ ⊆ Γ maps x to y.var : ∀{y} (δx≡y : lookup δ x ≡ y) (δ#β : Disjoint δ β)→ δ ⊢ var x ~ β ▷ var! y-- Unnamed lambda δ ⊢ λ.e is related to named lambda y,β ▷ λy.t-- if body y,δ ⊢ e is related to body β ▷ t.abs : (y#δ : DisjointUnion (from∈ y) δ yδ)→ (y#β : DisjointUnion (from∈ y) β yβ)→ yδ ⊢ e ~ β ▷ t→ δ ⊢ abs e ~ yβ ▷ abs y y#β t-- Application δ ⊢ f e is related to application βₜ,βᵤ ▷ t u-- if function δ ⊢ f is related to βₜ ▷ t-- and argument δ ⊢ e is related to βᵤ ▷ u.app : δ ⊢ f ~ βₜ ▷ t→ δ ⊢ e ~ βᵤ ▷ u→ (t#u : DisjointUnion βₜ βᵤ β)→ δ ⊢ app f e ~ β ▷ app t u t#u-- A dependent substitution lemma for ~.-- Trivial, but needed because term equality t : Tm β a ≡ t′ : Tm β′ a is heterogeneous,-- or, more precisely, indexed by a sublist equality β ≡ β′.subst~ : ∀ {a Δ Γ B} {δ δ′ : Δ ⊆ Γ} {β β′ : B ⊆ Γ}{e : Exp Δ a} {t : Tm β a} {t′ : Tm β′ a}(δ≡δ′ : δ ≡ δ′)(β≡β′ : β ≡ β′)(t≡t′ : subst (λ □ → Tm □ a) β≡β′ t ≡ t′) →δ ⊢ e ~ β ▷ t →δ′ ⊢ e ~ β′ ▷ t′subst~ refl refl refl d = d-- The judgement δ ⊢ e ~ β ▷ t relative to Γ-- can be transported to a bigger context γ : Γ ⊆ Γ′.weaken~ : ∀{a Δ B Γ Γ′} {δ : Δ ⊆ Γ} {β : B ⊆ Γ} {e : Exp Δ a} {t : Tm β a} (γ : Γ ⊆ Γ′)(let δ′ = ⊆-trans δ γ)(let β′ = ⊆-trans β γ)(let t′ = weakenBV γ t) →δ ⊢ e ~ β ▷ t →δ′ ⊢ e ~ β′ ▷ t′weaken~ γ (var refl δ#β) = var (lookup-⊆-trans γ _) (weakenDisjoint γ δ#β)weaken~ γ (abs y#δ y#β d) = abs y′#δ′ y′#β′ (weaken~ γ d)wherey′#δ′ = subst (λ □ → DisjointUnion □ _ _) (sym (from∈∘lookup _ _)) (weakenDisjointUnion γ y#δ)y′#β′ = subst (λ □ → DisjointUnion □ _ _) (sym (from∈∘lookup _ _)) (weakenDisjointUnion γ y#β)weaken~ γ (app dₜ dᵤ t#u) = app (weaken~ γ dₜ) (weaken~ γ dᵤ) (weakenDisjointUnion γ t#u)-- Lemma: If δ ⊢ e ~ β ▷ t, then-- the (potentially) free variables δ of the de Bruijn term e-- are disjoint from the bound variables β of the named term t.disjoint-fv-bv : δ ⊢ e ~ β ▷ t → Disjoint δ βdisjoint-fv-bv (var _ δ#β) = δ#βdisjoint-fv-bv {β = yβ} (abs y⊎δ y⊎β d) = δ#yβwhereδ#y = Disjoint-sym (DisjointUnion→Disjoint y⊎δ)yδ#β = disjoint-fv-bv dδ⊆yδ,eq = DisjointUnion-inj₂ y⊎δδ⊆yδ = proj₁ δ⊆yδ,eqeq = proj₂ δ⊆yδ,eqδ#β = subst (λ □ → Disjoint □ _) eq (shrinkDisjointˡ δ⊆yδ yδ#β)δ#yβ = disjoint⇒disjoint-to-union δ#y δ#β y⊎βdisjoint-fv-bv (app dₜ dᵤ βₜ⊎βᵤ) = disjoint⇒disjoint-to-union δ#βₜ δ#βᵤ βₜ⊎βᵤwhereδ#βₜ = disjoint-fv-bv dₜδ#βᵤ = disjoint-fv-bv dᵤ-- Translating de Bruijn terms to uniquely named terms.---- Given a de Bruijn term Δ ⊢ e : a, we seek to produce a named term-- β ▷ t : a that is related to the de Bruijn term. On the way, we have-- to compute the global context Γ that hosts all free and bound-- variables of t.-- Record (NamedOf e) collects all the outputs of the translation of e.record NamedOf (e : Exp Δ a) : Set whereconstructor mkNamedOffield{glob} : Cxt -- Γemb : Δ ⊆ glob -- δ : Δ ⊆ Γ{bv} : BVars -- Bbound : bv ⊆ glob -- β : B ⊆ Γ{tm} : Tm bound a -- t : Tm β arelate : emb ⊢ e ~ bound ▷ tm -- δ ⊢ e ~ β ▷ t-- The translation.dB→Named : (e : Exp Δ a) → NamedOf e-- For the translation of a variable x : a ∈ Δ, we can pick Γ := Δ and B := [].-- Δ and B are obviously disjoint subsets of Γ.dB→Named (var x) = record{ emb = ⊆-refl -- Γ := Δ; bound = minimum _ -- no bound variables; relate = var refl (DisjointUnion→Disjoint DisjointUnion-[]ʳ)}-- For the translation of an abstraction---- abs (t : Exp (a ∷ Δ) b) : Exp Δ (a ⇒ b)---- we recursively have Γ, B and β : B ⊆ Γ with z,δ : (a ∷ Δ) ⊆ Γ-- and know that B # a∷Δ.---- We keep Γ and produce embedding δ : Δ ⊆ Γ and bound variables z ⊎ β.dB→Named {Δ = Δ} {a = a ⇒ b} (abs e) with dB→Named e... | record{ glob = Γ; emb = zδ; bound = β; relate = d } =record{ glob = Γ; emb = δ̇; bound = proj₁ (proj₂ z⊎β); relate = abs [a]⊆Γ⊎δ (proj₂ (proj₂ z⊎β)) d}where-- Typings:-- zδ : a ∷ Δ ⊆ Γ-- β : bv ⊆ Γzδ#β = disjoint-fv-bv dz : a ∈ Γz = to∈ zδ[a]⊆Γ = from∈ zδ̇ = ∷ˡ⁻ zδ[a]⊆Γ⊎δ = DisjointUnion-fromAny∘toAny-∷ˡ⁻ zδ[a]⊆aΔ : [ a ] ⊆ (a ∷ Δ)[a]⊆aΔ = refl ∷ minimum _eq : ⊆-trans [a]⊆aΔ zδ ≡ [a]⊆Γeq = sym (from∈∘to∈ _)z#β : Disjoint [a]⊆Γ βz#β = subst (λ □ → Disjoint □ β) eq (shrinkDisjointˡ [a]⊆aΔ zδ#β)z⊎β = Disjoint→DisjointUnion z#β-- For the translation of an application (f e) we have by induction-- hypothesis two independent extensions δ₁ : Δ ⊆ Γ₁ and δ₂ : Δ ⊆ Γ₂-- and two bound variable lists β₁ : B₁ ⊆ Γ₁ and β₂ : B₂ ⊆ Γ₂.-- We need to find a common global context Γ such that---- (a) δ : Δ ⊆ Γ and-- (b) the bound variables embed disjointly as β₁″ : B₁ ⊆ Γ and β₂″ : B₂ ⊆ Γ.---- (a) δ is (eventually) found via a weak pushout of δ₁ and δ₂, giving-- ϕ₁ : Γ₁ ⊆ Γ₁₂ and ϕ₂ : Γ₂ ⊆ Γ₁₂.---- (b) The bound variable embeddings---- β₁′ = β₁ϕ₁ : B₁ ⊆ Γ₁₂ and-- β₂′ = β₂ϕ₂ : B₂ ⊆ Γ₁₂ and---- may be overlapping, but we can separate them by enlarging the global-- context to Γ with two embeddings---- γ₁ : Γ₁₂ ⊆ Γ-- γ₂ : Γ₁₂ ⊆ Γ---- such that---- β₁″ = β₁′γ₁ : B₁ ⊆ Γ-- β₂″ = β₂′γ₂ : B₂ ⊆ Γ---- are disjoint. Since Δ is disjoint to both B₁ and B₂ we have equality of---- δ₁ϕ₁γ₁ : Δ ⊆ Γ-- δ₂ϕ₂γ₂ : Δ ⊆ Γ---- Thus, we can return either of them as δ.dB→Named (app f e) with dB→Named f | dB→Named e... | mkNamedOf {Γ₁} δ₁ β₁ {t} d₁ | mkNamedOf {Γ₂} δ₂ β₂ {u} d₂ =mkNamedOf δ̇ β̇ (app d₁″ d₂″ β₁″⊎β₂″)where-- Disjointness of δᵢ and βᵢ from induction hypotheses.δ₁#β₁ = disjoint-fv-bv d₁δ₂#β₂ = disjoint-fv-bv d₂-- join δ₁ and δ₂ via weak pushoutpo = ⊆-pushoutˡ δ₁ δ₂Γ₁₂ = RawPushout.upperBound poϕ₁ = RawPushout.leg₁ poϕ₂ = RawPushout.leg₂ poδ₁′ = ⊆-trans δ₁ ϕ₁δ₂′ = ⊆-trans δ₂ ϕ₂β₁′ = ⊆-trans β₁ ϕ₁β₂′ = ⊆-trans β₂ ϕ₂δ₁′#β₁′ : Disjoint δ₁′ β₁′δ₁′#β₁′ = weakenDisjoint ϕ₁ δ₁#β₁δ₂′#β₂′ : Disjoint δ₂′ β₂′δ₂′#β₂′ = weakenDisjoint ϕ₂ δ₂#β₂δ₁′≡δ₂′ : δ₁′ ≡ δ₂′δ₁′≡δ₂′ = ⊆-pushoutˡ-is-wpo δ₁ δ₂δ₂′#β₁′ : Disjoint δ₂′ β₁′δ₂′#β₁′ = subst (λ □ → Disjoint □ β₁′) δ₁′≡δ₂′ δ₁′#β₁′-- separate β₁ and β₂sep : Separation β₁′ β₂′sep = separateˡ β₁′ β₂′γ₁ = Separation.separator₁ sepγ₂ = Separation.separator₂ sepβ₁″ = Separation.separated₁ sepβ₂″ = Separation.separated₂ sep-- produce their disjoint unionuni = Disjoint→DisjointUnion (Separation.disjoint sep)β̇ = proj₁ (proj₂ uni)β₁″⊎β₂″ : DisjointUnion β₁″ β₂″ β̇β₁″⊎β₂″ = proj₂ (proj₂ uni)ι₁ = DisjointUnion-inj₁ β₁″⊎β₂″ι₂ = DisjointUnion-inj₂ β₁″⊎β₂″-- after separation, the FVs are still disjoint from the BVs.δ₁″ = ⊆-trans δ₂′ γ₁δ₂″ = ⊆-trans δ₂′ γ₂δ₁″≡δ₂″ : δ₁″ ≡ δ₂″δ₁″≡δ₂″ = equalize-separators δ₂′#β₁′ δ₂′#β₂′δ₁″#β₁″ : Disjoint δ₁″ β₁″δ₁″#β₁″ = weakenDisjoint γ₁ δ₂′#β₁′δ₂″#β₂″ : Disjoint δ₂″ β₂″δ₂″#β₂″ = weakenDisjoint γ₂ δ₂′#β₂′δ̇ = δ₂″δ₂″#β₁″ : Disjoint δ₂″ β₁″δ₂″#β₁″ = subst (λ □ → Disjoint □ β₁″) δ₁″≡δ₂″ δ₁″#β₁″δ̇#β̇ : Disjoint δ̇ β̇δ̇#β̇ = disjoint⇒disjoint-to-union δ₂″#β₁″ δ₂″#β₂″ β₁″⊎β₂″-- Combined weakening from Γᵢ to Γγ₁′ = ⊆-trans ϕ₁ γ₁γ₂′ = ⊆-trans ϕ₂ γ₂-- Weakening and converting the first derivation.d₁′ : ⊆-trans δ₁ γ₁′ ⊢ f ~ ⊆-trans β₁ γ₁′ ▷ weakenBV γ₁′ td₁′ = weaken~ γ₁′ d₁δ₁≤δ̇ : ⊆-trans δ₁ γ₁′ ≡ ⊆-trans δ₂′ γ₂δ₁≤δ̇ = begin⊆-trans δ₁ γ₁′ ≡⟨ ⊆-trans-assoc ⟩⊆-trans δ₁′ γ₁ ≡⟨ cong (λ □ → ⊆-trans □ γ₁) δ₁′≡δ₂′ ⟩⊆-trans δ₂′ γ₁ ≡⟨⟩δ₁″ ≡⟨ δ₁″≡δ₂″ ⟩δ₂″ ≡⟨⟩δ̇ ∎β₁≤β₁″ : ⊆-trans β₁ γ₁′ ≡ β₁″β₁≤β₁″ = ⊆-trans-assocd₁″ : δ̇ ⊢ f ~ β₁″ ▷ subst (λ □ → Tm □ _) β₁≤β₁″ (weakenBV γ₁′ t)d₁″ = subst~ δ₁≤δ̇ β₁≤β₁″ refl d₁′-- Weakening and converting the second derivation.d₂′ : ⊆-trans δ₂ γ₂′ ⊢ e ~ ⊆-trans β₂ γ₂′ ▷ weakenBV γ₂′ ud₂′ = weaken~ γ₂′ d₂β₂≤β₂″ : ⊆-trans β₂ γ₂′ ≡ β₂″β₂≤β₂″ = ⊆-trans-assocδ₂≤δ̇ : ⊆-trans δ₂ γ₂′ ≡ δ̇δ₂≤δ̇ = ⊆-trans-assocd₂″ : δ̇ ⊢ e ~ β₂″ ▷ subst (λ □ → Tm □ _) β₂≤β₂″ (weakenBV γ₂′ u)d₂″ = subst~ δ₂≤δ̇ β₂≤β₂″ refl d₂′
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.-- Please use `Data.List.Relation.Binary.Sublist.Propositional.Slice`-- instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Propositional.Disjoint{a} {A : Set a} where{-# WARNING_ON_IMPORT"Data.List.Relation.Binary.Sublist.Propositional.Disjoint was deprecated in v2.1.Use Data.List.Relation.Binary.Sublist.Propositional.Slice instead."#-}open import Data.List.Base using (List)open import Data.List.Relation.Binary.Sublist.Propositional using( _⊆_; _∷_; _∷ʳ_; Disjoint; ⊆-disjoint-union; _∷ₙ_; _∷ₗ_; _∷ᵣ_)import Data.List.Relation.Binary.Sublist.Propositional.Slice as SPSliceopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open SPSlice using (⊆-upper-bound-is-cospan; ⊆-upper-bound-cospan)-- For backward compatibility reexport these:open SPSlice public using ( IsCospan; Cospan )open IsCospanopen Cospanmodule _{x : A} {xs ys zs : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs}(d : Disjoint τ₁ τ₂) (c : IsCospan (⊆-disjoint-union d)) where∷ₙ-cospan : IsCospan (⊆-disjoint-union (x ∷ₙ d))∷ₙ-cospan = record{ tri₁ = cong (x ∷ʳ_) (c .tri₁); tri₂ = cong (x ∷ʳ_) (c .tri₂)}∷ₗ-cospan : IsCospan (⊆-disjoint-union (refl {x = x} ∷ₗ d))∷ₗ-cospan = record{ tri₁ = cong (refl ∷_) (c .tri₁); tri₂ = cong (x ∷ʳ_) (c .tri₂)}∷ᵣ-cospan : IsCospan (⊆-disjoint-union (refl {x = x} ∷ᵣ d))∷ᵣ-cospan = record{ tri₁ = cong (x ∷ʳ_) (c .tri₁); tri₂ = cong (refl ∷_) (c .tri₂)}⊆-disjoint-union-is-cospan : ∀ {xs ys zs : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →(d : Disjoint τ₁ τ₂) → IsCospan (⊆-disjoint-union d)⊆-disjoint-union-is-cospan {τ₁ = τ₁} {τ₂ = τ₂} _ = ⊆-upper-bound-is-cospan τ₁ τ₂⊆-disjoint-union-cospan : ∀ {xs ys zs : List A} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →Disjoint τ₁ τ₂ → Cospan τ₁ τ₂⊆-disjoint-union-cospan {τ₁ = τ₁} {τ₂ = τ₂} _ = ⊆-upper-bound-cospan τ₁ τ₂{-# WARNING_ON_USAGE ⊆-disjoint-union-is-cospan"Warning: ⊆-disjoint-union-is-cospan was deprecated in v2.1.Please use `⊆-upper-bound-is-cospan` from `Data.List.Relation.Binary.Sublist.Propositional.Slice` instead."#-}{-# WARNING_ON_USAGE ⊆-disjoint-union-cospan"Warning: ⊆-disjoint-union-cospan was deprecated in v2.1.Please use `⊆-upper-bound-cospan` from `Data.List.Relation.Binary.Sublist.Propositional.Slice` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the heterogeneous sublist relation-- This is a generalisation of what is commonly known as Order-- Preserving Embeddings (OPE).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.List.Base using (List; []; _∷_; [_])open import Data.List.Relation.Unary.Any using (Any; here; there)open import Level using (_⊔_)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Definitions using (_⟶_Respects_; Min)open import Relation.Unary using (Pred)module Data.List.Relation.Binary.Sublist.Heterogeneous{a b r} {A : Set a} {B : Set b} {R : REL A B r}where-------------------------------------------------------------------------- Re-export core definitionsopen import Data.List.Relation.Binary.Sublist.Heterogeneous.Core public-------------------------------------------------------------------------- Type and basic combinatorsmodule _ {s} {S : REL A B s} wheremap : R ⇒ S → Sublist R ⇒ Sublist Smap f [] = []map f (y ∷ʳ rs) = y ∷ʳ map f rsmap f (r ∷ rs) = f r ∷ map f rsminimum : Min (Sublist R) []minimum [] = []minimum (x ∷ xs) = x ∷ʳ minimum xs-------------------------------------------------------------------------- Conversion to and from Any-- Special case: Sublist R [ a ] bs → Any (R a) bstoAny : ∀ {a as bs} → Sublist R (a ∷ as) bs → Any (R a) bstoAny (y ∷ʳ rs) = there (toAny rs)toAny (r ∷ rs) = here rfromAny : ∀ {a bs} → Any (R a) bs → Sublist R [ a ] bsfromAny (here r) = r ∷ minimum _fromAny (there p) = _ ∷ʳ fromAny p-------------------------------------------------------------------------- Generalised lookup based on a proof of Anymodule _ {p q} {P : Pred A p} {Q : Pred B q} (resp : P ⟶ Q Respects R) wherelookup : ∀ {xs ys} → Sublist R xs ys → Any P xs → Any Q yslookup (y ∷ʳ p) k = there (lookup p k)lookup (rxy ∷ p) (here px) = here (resp rxy px)lookup (rxy ∷ p) (there k) = there (lookup p k)-------------------------------------------------------------------------- Disjoint sublists xs,ys ⊆ zs---- NB: This does not imply that xs and ys partition zs;-- zs may have additional elements.privateinfix 4 _⊆__⊆_ = Sublist Rinfixr 5 _∷ₙ_ _∷ₗ_ _∷ᵣ_data Disjoint : ∀ {xs ys zs} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → Set (a ⊔ b ⊔ r) where[] : Disjoint [] []-- Element y of zs is neither in xs nor in ys:_∷ₙ_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →(y : B) → Disjoint τ₁ τ₂ → Disjoint (y ∷ʳ τ₁) (y ∷ʳ τ₂)-- Element y of zs is in xs as x with x≈y:_∷ₗ_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {x y} →(x≈y : R x y) → Disjoint τ₁ τ₂ → Disjoint (x≈y ∷ τ₁) (y ∷ʳ τ₂)-- Element y of zs is in ys as x with x≈y:_∷ᵣ_ : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {x y} →(x≈y : R x y) → Disjoint τ₁ τ₂ → Disjoint (y ∷ʳ τ₁) (x≈y ∷ τ₂)-------------------------------------------------------------------------- Disjoint union of two sublists xs,ys ⊆ zs---- This is the Cover relation without overlap of Section 6 of-- Conor McBride, Everybody's Got To Be Somewhere,-- MSFP@FSCD 2018: 53-69.data DisjointUnion : ∀ {xs ys zs us} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) (τ : us ⊆ zs) → Set (a ⊔ b ⊔ r) where[] : DisjointUnion [] [] []-- Element y of zs is neither in xs nor in ys: skip._∷ₙ_ : ∀ {xs ys zs us} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : us ⊆ zs} →(y : B) → DisjointUnion τ₁ τ₂ τ → DisjointUnion (y ∷ʳ τ₁) (y ∷ʳ τ₂) (y ∷ʳ τ)-- Element y of zs is in xs as x with x≈y: add to us._∷ₗ_ : ∀ {xs ys zs us} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : us ⊆ zs} {x y} →(x≈y : R x y) → DisjointUnion τ₁ τ₂ τ → DisjointUnion (x≈y ∷ τ₁) (y ∷ʳ τ₂) (x≈y ∷ τ)-- Element y of zs is in ys as x with x≈y: add to us._∷ᵣ_ : ∀ {xs ys zs us} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : us ⊆ zs} {x y} →(x≈y : R x y) → DisjointUnion τ₁ τ₂ τ → DisjointUnion (y ∷ʳ τ₁) (x≈y ∷ τ₂) (x≈y ∷ τ)
-------------------------------------------------------------------------- The Agda standard library---- A solver for proving that one list is a sublist of the other.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Reflexive; Decidable)module Data.List.Relation.Binary.Sublist.Heterogeneous.Solver{a r} {A : Set a} (R : Rel A r)(R-refl : Reflexive R) (R? : Decidable R)where-- Note that we only need the above two constraints to define the-- solver itself. The data structures do not depend on them. However,-- having the whole module parametrised by them means that we can-- instantiate them upon import.open import Level using (_⊔_)open import Data.Fin as Finopen import Data.Maybe.Base as Maybe using (Maybe; nothing; just; From-just; from-just)open import Data.Nat.Base as ℕ using (ℕ)open import Data.Product.Base using (Σ-syntax; _,_)open import Data.Vec.Base as Vec using (Vec ; lookup)open import Data.List.Base using (List; []; _∷_; [_]; _++_)open import Data.List.Properties using (++-assoc; ++-identityʳ)open import Data.List.Relation.Binary.Sublist.Heterogeneoususing (Sublist; minimum; _∷_)open import Data.List.Relation.Binary.Sublist.Heterogeneous.Propertiesopen import Function.Base using (_$_; case_of_)open import Relation.Binary.Consequences using (dec⇒weaklyDec)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≗_; sym; cong; cong₂; subst₂)open import Relation.Binary.PropositionalEquality.Properties as ≡open ≡.≡-Reasoninginfix 4 _⊆I_ _⊆R_ _⊆T_-------------------------------------------------------------------------- Reified list expressions-- Basic building blocks: variables and valuesdata Item (n : ℕ) : Set a wherevar : Fin n → Item nval : A → Item n-- Abstract Syntax Treesinfixr 5 _<>_data TList (n : ℕ) : Set a whereIt : Item n → TList n_<>_ : TList n → TList n → TList n[] : TList n-- Equivalent linearised representationRList : ∀ n → Set aRList n = List (Item n)-- Semantics⟦_⟧I : ∀ {n} → Item n → Vec (List A) n → List A⟦ var k ⟧I ρ = lookup ρ k⟦ val a ⟧I ρ = [ a ]⟦_⟧T : ∀ {n} → TList n → Vec (List A) n → List A⟦ It it ⟧T ρ = ⟦ it ⟧I ρ⟦ t <> u ⟧T ρ = ⟦ t ⟧T ρ ++ ⟦ u ⟧T ρ⟦ [] ⟧T ρ = []⟦_⟧R : ∀ {n} → RList n → Vec (List A) n → List A⟦ [] ⟧R ρ = []⟦ x ∷ xs ⟧R ρ = ⟦ x ⟧I ρ ++ ⟦ xs ⟧R ρ-- Ordersdata _⊆I_ {n} : (d e : Item n) → Set (a ⊔ r) wherevar : ∀ {k l} → k ≡ l → var k ⊆I var lval : ∀ {a b} → R a b → val a ⊆I val b_⊆T_ : ∀ {n} → (d e : TList n) → Set (a ⊔ r)d ⊆T e = ∀ ρ → Sublist R (⟦ d ⟧T ρ) (⟦ e ⟧T ρ)_⊆R_ : ∀ {n} (d e : RList n) → Set (a ⊔ r)d ⊆R e = ∀ ρ → Sublist R (⟦ d ⟧R ρ) (⟦ e ⟧R ρ)-- Flattening in a semantics-respecting manner⟦++⟧R : ∀ {n} xs ys (ρ : Vec (List A) n) → ⟦ xs ++ ys ⟧R ρ ≡ ⟦ xs ⟧R ρ ++ ⟦ ys ⟧R ρ⟦++⟧R [] ys ρ = ≡.refl⟦++⟧R (x ∷ xs) ys ρ = begin⟦ x ⟧I ρ ++ ⟦ xs ++ ys ⟧R ρ≡⟨ cong (⟦ x ⟧I ρ ++_) (⟦++⟧R xs ys ρ) ⟩⟦ x ⟧I ρ ++ ⟦ xs ⟧R ρ ++ ⟦ ys ⟧R ρ≡⟨ sym $ ++-assoc (⟦ x ⟧I ρ) (⟦ xs ⟧R ρ) (⟦ ys ⟧R ρ) ⟩(⟦ x ⟧I ρ ++ ⟦ xs ⟧R ρ) ++ ⟦ ys ⟧R ρ∎flatten : ∀ {n} (t : TList n) → Σ[ r ∈ RList n ] ⟦ r ⟧R ≗ ⟦ t ⟧Tflatten [] = [] , λ _ → ≡.reflflatten (It it) = it ∷ [] , λ ρ → ++-identityʳ (⟦ It it ⟧T ρ)flatten (t <> u) =let (rt , eqt) = flatten t(ru , equ) = flatten uin rt ++ ru , λ ρ → begin⟦ rt ++ ru ⟧R ρ ≡⟨ ⟦++⟧R rt ru ρ ⟩⟦ rt ⟧R ρ ++ ⟦ ru ⟧R ρ ≡⟨ cong₂ _++_ (eqt ρ) (equ ρ) ⟩⟦ t ⟧T ρ ++ ⟦ u ⟧T ρ ≡⟨⟩⟦ t <> u ⟧T ρ ∎-------------------------------------------------------------------------- Solver for the sublist problem-- auxiliary lemmasprivatekeep-it : ∀ {n a b} → a ⊆I b → (xs ys : RList n) → xs ⊆R ys → (a ∷ xs) ⊆R (b ∷ ys)keep-it (var a≡b) xs ys hyp ρ = ++⁺ (reflexive R-refl (cong _ a≡b)) (hyp ρ)keep-it (val rab) xs ys hyp ρ = rab ∷ hyp ρskip-it : ∀ {n} it (d e : RList n) → d ⊆R e → d ⊆R (it ∷ e)skip-it it d ys hyp ρ = ++ˡ (⟦ it ⟧I ρ) (hyp ρ)-- Solver for itemssolveI : ∀ {n} (a b : Item n) → Maybe (a ⊆I b)solveI (var k) (var l) = Maybe.map var $ dec⇒weaklyDec Fin._≟_ k lsolveI (val a) (val b) = Maybe.map val $ dec⇒weaklyDec R? a bsolveI _ _ = nothing-- Solver for linearised expressionssolveR : ∀ {n} (d e : RList n) → Maybe (d ⊆R e)-- trivialsolveR [] e = just (λ ρ → minimum _)solveR d [] = nothing-- actual worksolveR (a ∷ d) (b ∷ e) with solveI a b... | just it = Maybe.map (keep-it it d e) (solveR d e)... | nothing = Maybe.map (skip-it b (a ∷ d) e) (solveR (a ∷ d) e)-- Coming back to ASTs thanks to flattensolveT : ∀ {n} (t u : TList n) → Maybe (t ⊆T u)solveT t u =let (rt , eqt) = flatten t(ru , equ) = flatten uin case solveR rt ru of λ where(just hyp) → just (λ ρ → subst₂ (Sublist R) (eqt ρ) (equ ρ) (hyp ρ))nothing → nothing-- Prover for ASTsprove : ∀ {n} (d e : TList n) → From-just (solveT d e)prove d e = from-just (solveT d e)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the heterogeneous sublist relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Sublist.Heterogeneous.Properties whereopen import Levelopen import Data.Bool.Base using (true; false)open import Data.List.Relation.Unary.All using (Null; []; _∷_)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Base as List hiding (map; _∷ʳ_)import Data.List.Properties as Listopen import Data.List.Relation.Unary.Any.Propertiesusing (here-injective; there-injective)open import Data.List.Relation.Binary.Pointwise as Pw using (Pointwise; []; _∷_)open import Data.List.Relation.Binary.Sublist.Heterogeneousopen import Data.Maybe.Relation.Unary.All as Maybe using (nothing; just)open import Data.Nat.Base using (ℕ; _≤_; _≥_); open ℕ; open _≤_import Data.Nat.Properties as ℕopen import Data.Product.Base using (∃₂; _×_; _,_; <_,_>; proj₂; uncurry)open import Function.Baseopen import Function.Bundles using (_⤖_; _⇔_ ; mk⤖; mk⇔)open import Function.Consequences.Propositional using (strictlySurjective⇒surjective)open import Relation.Nullary.Decidable as Dec using (Dec; does; _because_; yes; no; ¬?)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Nullary.Reflects using (invert)open import Relation.Unary as U using (Pred)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Bundles using (Preorder; Poset; DecPoset)open import Relation.Binary.Definitionsusing (Reflexive; Trans; Antisym; Decidable; Irrelevant; Irreflexive)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea b c d e p q r s t : LevelA : Set aB : Set bC : Set cD : Set dx : Ay : Bas cs xs : List Abs ds ys : List Bass : List (List A)bss : List (List B)m n : ℕ-------------------------------------------------------------------------- Injectivity of constructorsmodule _ {R : REL A B r} where∷-injectiveˡ : {px qx : R x y} {pxs qxs : Sublist R xs ys} →(Sublist R (x ∷ xs) (y ∷ ys) ∋ px ∷ pxs) ≡ (qx ∷ qxs) → px ≡ qx∷-injectiveˡ ≡.refl = ≡.refl∷-injectiveʳ : {px qx : R x y} {pxs qxs : Sublist R xs ys} →(Sublist R (x ∷ xs) (y ∷ ys) ∋ px ∷ pxs) ≡ (qx ∷ qxs) → pxs ≡ qxs∷-injectiveʳ ≡.refl = ≡.refl∷ʳ-injective : {pxs qxs : Sublist R xs ys} →(Sublist R xs (y ∷ ys) ∋ y ∷ʳ pxs) ≡ (y ∷ʳ qxs) → pxs ≡ qxs∷ʳ-injective ≡.refl = ≡.reflmodule _ {R : REL A B r} wherelength-mono-≤ : Sublist R as bs → length as ≤ length bslength-mono-≤ [] = z≤nlength-mono-≤ (y ∷ʳ rs) = ℕ.m≤n⇒m≤1+n (length-mono-≤ rs)length-mono-≤ (r ∷ rs) = s≤s (length-mono-≤ rs)-------------------------------------------------------------------------- Conversion to and from Pointwise (proto-reflexivity)fromPointwise : Pointwise R ⇒ Sublist RfromPointwise [] = []fromPointwise (p ∷ ps) = p ∷ fromPointwise pstoPointwise : length as ≡ length bs →Sublist R as bs → Pointwise R as bstoPointwise {bs = []} eq [] = []toPointwise {bs = b ∷ bs} eq (r ∷ rs) = r ∷ toPointwise (ℕ.suc-injective eq) rstoPointwise {bs = b ∷ bs} eq (b ∷ʳ rs) =contradiction (s≤s (length-mono-≤ rs)) (ℕ.<-irrefl eq)-------------------------------------------------------------------------- Various functions' outputs are sublists-- These lemmas are generalisations of results of the form `f xs ⊆ xs`.-- (where _⊆_ stands for Sublist R). If R is reflexive then we can-- indeed obtain `f xs ⊆ xs` from `xs ⊆ ys → f xs ⊆ ys`. The other-- direction is only true if R is both reflexive and transitive.module _ {R : REL A B r} wheretail-Sublist : Sublist R as bs →Maybe.All (λ as → Sublist R as bs) (tail as)tail-Sublist [] = nothingtail-Sublist (b ∷ʳ ps) = Maybe.map (b ∷ʳ_) (tail-Sublist ps)tail-Sublist (p ∷ ps) = just (_ ∷ʳ ps)take-Sublist : ∀ n → Sublist R as bs → Sublist R (take n as) bstake-Sublist n (y ∷ʳ rs) = y ∷ʳ take-Sublist n rstake-Sublist zero rs = minimum _take-Sublist (suc n) [] = []take-Sublist (suc n) (r ∷ rs) = r ∷ take-Sublist n rsdrop-Sublist : ∀ n → Sublist R ⇒ (Sublist R ∘′ drop n)drop-Sublist n (y ∷ʳ rs) = y ∷ʳ drop-Sublist n rsdrop-Sublist zero rs = rsdrop-Sublist (suc n) [] = []drop-Sublist (suc n) (r ∷ rs) = _ ∷ʳ drop-Sublist n rsmodule _ {R : REL A B r} {P : Pred A p} (P? : U.Decidable P) wheretakeWhile-Sublist : Sublist R as bs → Sublist R (takeWhile P? as) bstakeWhile-Sublist [] = []takeWhile-Sublist (y ∷ʳ rs) = y ∷ʳ takeWhile-Sublist rstakeWhile-Sublist {a ∷ as} (r ∷ rs) with does (P? a)... | true = r ∷ takeWhile-Sublist rs... | false = minimum _dropWhile-Sublist : Sublist R as bs → Sublist R (dropWhile P? as) bsdropWhile-Sublist [] = []dropWhile-Sublist (y ∷ʳ rs) = y ∷ʳ dropWhile-Sublist rsdropWhile-Sublist {a ∷ as} (r ∷ rs) with does (P? a)... | true = _ ∷ʳ dropWhile-Sublist rs... | false = r ∷ rsfilter-Sublist : Sublist R as bs → Sublist R (filter P? as) bsfilter-Sublist [] = []filter-Sublist (y ∷ʳ rs) = y ∷ʳ filter-Sublist rsfilter-Sublist {a ∷ as} (r ∷ rs) with does (P? a)... | true = r ∷ filter-Sublist rs... | false = _ ∷ʳ filter-Sublist rs-------------------------------------------------------------------------- Various functions are increasing wrt _⊆_-- We write f⁺ for the proof that `xs ⊆ ys → f xs ⊆ f ys`-- and f⁻ for the one that `f xs ⊆ f ys → xs ⊆ ys`.module _ {R : REL A B r} where-------------------------------------------------------------------------- _∷_∷ˡ⁻ : Sublist R (x ∷ xs) ys → Sublist R xs ys∷ˡ⁻ (y ∷ʳ rs) = y ∷ʳ ∷ˡ⁻ rs∷ˡ⁻ (r ∷ rs) = _ ∷ʳ rs∷ʳ⁻ : ¬ R x y → Sublist R (x ∷ xs) (y ∷ ys) →Sublist R (x ∷ xs) ys∷ʳ⁻ ¬r (y ∷ʳ rs) = rs∷ʳ⁻ ¬r (r ∷ rs) = contradiction r ¬r∷⁻ : Sublist R (x ∷ xs) (y ∷ ys) → Sublist R xs ys∷⁻ (y ∷ʳ rs) = ∷ˡ⁻ rs∷⁻ (x ∷ rs) = rsmodule _ {R : REL C D r} where-------------------------------------------------------------------------- mapmap⁺ : (f : A → C) (g : B → D) →Sublist (λ a b → R (f a) (g b)) as bs →Sublist R (List.map f as) (List.map g bs)map⁺ f g [] = []map⁺ f g (y ∷ʳ rs) = g y ∷ʳ map⁺ f g rsmap⁺ f g (r ∷ rs) = r ∷ map⁺ f g rsmap⁻ : (f : A → C) (g : B → D) →Sublist R (List.map f as) (List.map g bs) →Sublist (λ a b → R (f a) (g b)) as bsmap⁻ {as = []} {bs} f g rs = minimum _map⁻ {as = a ∷ as} {b ∷ bs} f g (_ ∷ʳ rs) = b ∷ʳ map⁻ f g rsmap⁻ {as = a ∷ as} {b ∷ bs} f g (r ∷ rs) = r ∷ map⁻ f g rsmodule _ {R : REL A B r} where-------------------------------------------------------------------------- _++_++⁺ : Sublist R as bs → Sublist R cs ds →Sublist R (as ++ cs) (bs ++ ds)++⁺ [] cds = cds++⁺ (y ∷ʳ abs) cds = y ∷ʳ ++⁺ abs cds++⁺ (ab ∷ abs) cds = ab ∷ ++⁺ abs cds++⁻ : length as ≡ length bs →Sublist R (as ++ cs) (bs ++ ds) → Sublist R cs ds++⁻ {as = []} {[]} eq rs = rs++⁻ {as = a ∷ as} {b ∷ bs} eq rs = ++⁻ (ℕ.suc-injective eq) (∷⁻ rs)++ˡ : (cs : List B) → Sublist R as bs → Sublist R as (cs ++ bs)++ˡ zs = ++⁺ (minimum zs)++ʳ : (cs : List B) → Sublist R as bs → Sublist R as (bs ++ cs)++ʳ cs [] = minimum cs++ʳ cs (y ∷ʳ rs) = y ∷ʳ ++ʳ cs rs++ʳ cs (r ∷ rs) = r ∷ ++ʳ cs rs-------------------------------------------------------------------------- concatconcat⁺ : Sublist (Sublist R) ass bss →Sublist R (concat ass) (concat bss)concat⁺ [] = []concat⁺ (y ∷ʳ rss) = ++ˡ y (concat⁺ rss)concat⁺ (rs ∷ rss) = ++⁺ rs (concat⁺ rss)-------------------------------------------------------------------------- take / droptake⁺ : m ≤ n → Pointwise R as bs →Sublist R (take m as) (take n bs)take⁺ z≤n ps = minimum _take⁺ (s≤s m≤n) [] = []take⁺ (s≤s m≤n) (p ∷ ps) = p ∷ take⁺ m≤n psdrop⁺ : m ≥ n → Sublist R as bs →Sublist R (drop m as) (drop n bs)drop⁺ (z≤n {m}) rs = drop-Sublist m rsdrop⁺ (s≤s m≥n) [] = []drop⁺ (s≤s m≥n) (y ∷ʳ rs) = drop⁺ (ℕ.m≤n⇒m≤1+n m≥n) rsdrop⁺ (s≤s m≥n) (r ∷ rs) = drop⁺ m≥n rsdrop⁺-≥ : m ≥ n → Pointwise R as bs →Sublist R (drop m as) (drop n bs)drop⁺-≥ m≥n pw = drop⁺ m≥n (fromPointwise pw)drop⁺-⊆ : ∀ m → Sublist R as bs →Sublist R (drop m as) (drop m bs)drop⁺-⊆ m = drop⁺ (ℕ.≤-refl {m})module _ {R : REL A B r} {P : Pred A p} {Q : Pred B q}(P? : U.Decidable P) (Q? : U.Decidable Q) where⊆-takeWhile-Sublist : (∀ {a b} → R a b → P a → Q b) →Pointwise R as bs →Sublist R (takeWhile P? as) (takeWhile Q? bs)⊆-takeWhile-Sublist rp⇒q [] = []⊆-takeWhile-Sublist {a ∷ as} {b ∷ bs} rp⇒q (p ∷ ps) with P? a | Q? b... | false because _ | _ = minimum _... | true because _ | true because _ = p ∷ ⊆-takeWhile-Sublist rp⇒q ps... | yes pa | no ¬qb = contradiction (rp⇒q p pa) ¬qb⊇-dropWhile-Sublist : (∀ {a b} → R a b → Q b → P a) →Pointwise R as bs →Sublist R (dropWhile P? as) (dropWhile Q? bs)⊇-dropWhile-Sublist rq⇒p [] = []⊇-dropWhile-Sublist {a ∷ as} {b ∷ bs} rq⇒p (p ∷ ps) with P? a | Q? b... | true because _ | true because _ = ⊇-dropWhile-Sublist rq⇒p ps... | true because _ | false because _ =b ∷ʳ dropWhile-Sublist P? (fromPointwise ps)... | false because _ | false because _ = p ∷ fromPointwise ps... | no ¬pa | yes qb = contradiction (rq⇒p p qb) ¬pa⊆-filter-Sublist : (∀ {a b} → R a b → P a → Q b) →Sublist R as bs → Sublist R (filter P? as) (filter Q? bs)⊆-filter-Sublist rp⇒q [] = []⊆-filter-Sublist rp⇒q (y ∷ʳ rs) with does (Q? y)... | true = y ∷ʳ ⊆-filter-Sublist rp⇒q rs... | false = ⊆-filter-Sublist rp⇒q rs⊆-filter-Sublist {a ∷ as} {b ∷ bs} rp⇒q (r ∷ rs) with P? a | Q? b... | true because _ | true because _ = r ∷ ⊆-filter-Sublist rp⇒q rs... | false because _ | true because _ = _ ∷ʳ ⊆-filter-Sublist rp⇒q rs... | false because _ | false because _ = ⊆-filter-Sublist rp⇒q rs... | yes pa | no ¬qb = contradiction (rp⇒q r pa) ¬qbmodule _ {R : Rel A r} {P : Pred A p} (P? : U.Decidable P) wheretakeWhile-filter : Pointwise R as as →Sublist R (takeWhile P? as) (filter P? as)takeWhile-filter [] = []takeWhile-filter {a ∷ as} (p ∷ ps) with does (P? a)... | true = p ∷ takeWhile-filter ps... | false = minimum _filter-dropWhile : Pointwise R as as →Sublist R (filter P? as) (dropWhile (¬? ∘ P?) as)filter-dropWhile [] = []filter-dropWhile {a ∷ as} (p ∷ ps) with does (P? a)... | true = p ∷ filter-Sublist P? (fromPointwise ps)... | false = filter-dropWhile ps-------------------------------------------------------------------------- reversemodule _ {R : REL A B r} wherereverseAcc⁺ : Sublist R as bs → Sublist R cs ds →Sublist R (reverseAcc cs as) (reverseAcc ds bs)reverseAcc⁺ [] cds = cdsreverseAcc⁺ (y ∷ʳ abs) cds = reverseAcc⁺ abs (y ∷ʳ cds)reverseAcc⁺ (r ∷ abs) cds = reverseAcc⁺ abs (r ∷ cds)ʳ++⁺ : Sublist R as bs → Sublist R cs ds →Sublist R (as ʳ++ cs) (bs ʳ++ ds)ʳ++⁺ = reverseAcc⁺reverse⁺ : Sublist R as bs → Sublist R (reverse as) (reverse bs)reverse⁺ rs = reverseAcc⁺ rs []reverse⁻ : Sublist R (reverse as) (reverse bs) → Sublist R as bsreverse⁻ {as = as} {bs = bs} p = cast (reverse⁺ p) wherecast = ≡.subst₂ (Sublist R) (List.reverse-involutive as) (List.reverse-involutive bs)-------------------------------------------------------------------------- Inversion lemmasmodule _ {R : REL A B r} where∷⁻¹ : R x y → Sublist R xs ys ⇔ Sublist R (x ∷ xs) (y ∷ ys)∷⁻¹ r = mk⇔ (r ∷_) ∷⁻∷ʳ⁻¹ : ¬ R x y → Sublist R (x ∷ xs) ys ⇔ Sublist R (x ∷ xs) (y ∷ ys)∷ʳ⁻¹ ¬r = mk⇔ (_ ∷ʳ_) (∷ʳ⁻ ¬r)-------------------------------------------------------------------------- Irrelevant special casemodule _ {R : REL A B r} whereSublist-[]-irrelevant : U.Irrelevant (Sublist R [])Sublist-[]-irrelevant [] [] = ≡.reflSublist-[]-irrelevant (y ∷ʳ p) (.y ∷ʳ q) = ≡.cong (y ∷ʳ_) (Sublist-[]-irrelevant p q)-------------------------------------------------------------------------- (to/from)Any is a bijectiontoAny-injective :{p q : Sublist R [ x ] xs} → toAny p ≡ toAny q → p ≡ qtoAny-injective {p = y ∷ʳ p} {y ∷ʳ q} =≡.cong (y ∷ʳ_) ∘′ toAny-injective ∘′ there-injectivetoAny-injective {p = _ ∷ p} {_ ∷ q} =≡.cong₂ (flip _∷_) (Sublist-[]-irrelevant p q) ∘′ here-injectivefromAny-injective : {p q : Any (R x) xs} →fromAny {R = R} p ≡ fromAny q → p ≡ qfromAny-injective {p = here px} {here qx} = ≡.cong here ∘′ ∷-injectiveˡfromAny-injective {p = there p} {there q} =≡.cong there ∘′ fromAny-injective ∘′ ∷ʳ-injectivetoAny∘fromAny≗id : (p : Any (R x) xs) → toAny (fromAny {R = R} p) ≡ ptoAny∘fromAny≗id (here px) = ≡.refltoAny∘fromAny≗id (there p) = ≡.cong there (toAny∘fromAny≗id p)Sublist-[x]-bijection : (Sublist R [ x ] xs) ⤖ (Any (R x) xs)Sublist-[x]-bijection = mk⤖ (toAny-injective , strictlySurjective⇒surjective < fromAny , toAny∘fromAny≗id >)-------------------------------------------------------------------------- Relational propertiesmodule Reflexivity{R : Rel A r}(R-refl : Reflexive R) wherereflexive : _≡_ ⇒ Sublist Rreflexive ≡.refl = fromPointwise (Pw.refl R-refl)refl : Reflexive (Sublist R)refl = reflexive ≡.reflopen Reflexivity publicmodule Transitivity{R : REL A B r} {S : REL B C s} {T : REL A C t}(rs⇒t : Trans R S T) wheretrans : Trans (Sublist R) (Sublist S) (Sublist T)trans rs (y ∷ʳ ss) = y ∷ʳ trans rs sstrans (y ∷ʳ rs) (s ∷ ss) = _ ∷ʳ trans rs sstrans (r ∷ rs) (s ∷ ss) = rs⇒t r s ∷ trans rs sstrans [] [] = []open Transitivity publicmodule Antisymmetry{R : REL A B r} {S : REL B A s} {E : REL A B e}(rs⇒e : Antisym R S E) whereopen ℕ.≤-Reasoningantisym : Antisym (Sublist R) (Sublist S) (Pointwise E)antisym [] [] = []antisym (r ∷ rs) (s ∷ ss) = rs⇒e r s ∷ antisym rs ss-- impossible casesantisym (_∷ʳ_ {xs} {ys₁} y rs) (_∷ʳ_ {ys₂} {zs} z ss) =contradiction (beginlength (y ∷ ys₁) ≤⟨ length-mono-≤ ss ⟩length zs ≤⟨ ℕ.n≤1+n (length zs) ⟩length (z ∷ zs) ≤⟨ length-mono-≤ rs ⟩length ys₁ ∎) $ ℕ.<-irrefl ≡.reflantisym (_∷ʳ_ {xs} {ys₁} y rs) (_∷_ {y} {ys₂} {z} {zs} s ss) =contradiction (beginlength (z ∷ zs) ≤⟨ length-mono-≤ rs ⟩length ys₁ ≤⟨ length-mono-≤ ss ⟩length zs ∎) $ ℕ.<-irrefl ≡.reflantisym (_∷_ {x} {xs} {y} {ys₁} r rs) (_∷ʳ_ {ys₂} {zs} z ss) =contradiction (beginlength (y ∷ ys₁) ≤⟨ length-mono-≤ ss ⟩length xs ≤⟨ length-mono-≤ rs ⟩length ys₁ ∎) $ ℕ.<-irrefl ≡.reflopen Antisymmetry publicmodule _ {R : REL A B r} (R? : Decidable R) wheresublist? : Decidable (Sublist R)sublist? [] ys = yes (minimum ys)sublist? (x ∷ xs) [] = no λ ()sublist? (x ∷ xs) (y ∷ ys) with R? x y... | true because [r] =Dec.map (∷⁻¹ (invert [r])) (sublist? xs ys)... | false because [¬r] =Dec.map (∷ʳ⁻¹ (invert [¬r])) (sublist? (x ∷ xs) ys)module _ {E : Rel A e} {R : Rel A r} whereisPreorder : IsPreorder E R → IsPreorder (Pointwise E) (Sublist R)isPreorder ER-isPreorder = record{ isEquivalence = Pw.isEquivalence ER.isEquivalence; reflexive = fromPointwise ∘ Pw.map ER.reflexive; trans = trans ER.trans} where module ER = IsPreorder ER-isPreorderisPartialOrder : IsPartialOrder E R → IsPartialOrder (Pointwise E) (Sublist R)isPartialOrder ER-isPartialOrder = record{ isPreorder = isPreorder ER.isPreorder; antisym = antisym ER.antisym} where module ER = IsPartialOrder ER-isPartialOrderisDecPartialOrder : IsDecPartialOrder E R →IsDecPartialOrder (Pointwise E) (Sublist R)isDecPartialOrder ER-isDecPartialOrder = record{ isPartialOrder = isPartialOrder ER.isPartialOrder; _≟_ = Pw.decidable ER._≟_; _≤?_ = sublist? ER._≤?_} where module ER = IsDecPartialOrder ER-isDecPartialOrderpreorder : Preorder a e r → Preorder _ _ _preorder ER-preorder = record{ isPreorder = isPreorder ER.isPreorder} where module ER = Preorder ER-preorderposet : Poset a e r → Poset _ _ _poset ER-poset = record{ isPartialOrder = isPartialOrder ER.isPartialOrder} where module ER = Poset ER-posetdecPoset : DecPoset a e r → DecPoset _ _ _decPoset ER-poset = record{ isDecPartialOrder = isDecPartialOrder ER.isDecPartialOrder} where module ER = DecPoset ER-poset-------------------------------------------------------------------------- Properties of disjoint sublistsmodule Disjointness {a b r} {A : Set a} {B : Set b} {R : REL A B r} whereprivateinfix 4 _⊆__⊆_ = Sublist R-- Forgetting the unionDisjointUnion→Disjoint : ∀ {xs ys zs us} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : us ⊆ zs} →DisjointUnion τ₁ τ₂ τ → Disjoint τ₁ τ₂DisjointUnion→Disjoint [] = []DisjointUnion→Disjoint (y ∷ₙ u) = y ∷ₙ DisjointUnion→Disjoint uDisjointUnion→Disjoint (x≈y ∷ₗ u) = x≈y ∷ₗ DisjointUnion→Disjoint uDisjointUnion→Disjoint (x≈y ∷ᵣ u) = x≈y ∷ᵣ DisjointUnion→Disjoint u-- Reconstructing the unionDisjoint→DisjointUnion : ∀ {xs ys zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →Disjoint τ₁ τ₂ → ∃₂ λ us (τ : us ⊆ zs) → DisjointUnion τ₁ τ₂ τDisjoint→DisjointUnion [] = _ , _ , []Disjoint→DisjointUnion (y ∷ₙ u) = _ , _ , y ∷ₙ proj₂ (proj₂ (Disjoint→DisjointUnion u))Disjoint→DisjointUnion (x≈y ∷ₗ u) = _ , _ , x≈y ∷ₗ proj₂ (proj₂ (Disjoint→DisjointUnion u))Disjoint→DisjointUnion (x≈y ∷ᵣ u) = _ , _ , x≈y ∷ᵣ proj₂ (proj₂ (Disjoint→DisjointUnion u))-- Disjoint is decidable⊆-disjoint? : ∀ {xs ys zs} (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → Dec (Disjoint τ₁ τ₂)⊆-disjoint? [] [] = yes []-- Present in both sublists: not disjoint.⊆-disjoint? (x≈z ∷ τ₁) (y≈z ∷ τ₂) = no λ()-- Present in either sublist: ok.⊆-disjoint? (y ∷ʳ τ₁) (x≈y ∷ τ₂) =Dec.map′ (x≈y ∷ᵣ_) (λ{ (_ ∷ᵣ d) → d }) (⊆-disjoint? τ₁ τ₂)⊆-disjoint? (x≈y ∷ τ₁) (y ∷ʳ τ₂) =Dec.map′ (x≈y ∷ₗ_) (λ{ (_ ∷ₗ d) → d }) (⊆-disjoint? τ₁ τ₂)-- Present in neither sublist: ok.⊆-disjoint? (y ∷ʳ τ₁) (.y ∷ʳ τ₂) =Dec.map′ (y ∷ₙ_) (λ{ (_ ∷ₙ d) → d }) (⊆-disjoint? τ₁ τ₂)-- Disjoint is proof-irrelevantDisjoint-irrelevant : ∀{xs ys zs} → Irrelevant (Disjoint {R = R} {xs} {ys} {zs})Disjoint-irrelevant [] [] = ≡.reflDisjoint-irrelevant (y ∷ₙ d₁) (.y ∷ₙ d₂) = ≡.cong (y ∷ₙ_) (Disjoint-irrelevant d₁ d₂)Disjoint-irrelevant (x≈y ∷ₗ d₁) (.x≈y ∷ₗ d₂) = ≡.cong (x≈y ∷ₗ_) (Disjoint-irrelevant d₁ d₂)Disjoint-irrelevant (x≈y ∷ᵣ d₁) (.x≈y ∷ᵣ d₂) = ≡.cong (x≈y ∷ᵣ_) (Disjoint-irrelevant d₁ d₂)-- Note: DisjointUnion is not proof-irrelevant unless the underlying relation R is.-- The proof is not entirely trivial, thus, we leave it for future work:---- DisjointUnion-irrelevant : Irrelevant R →-- ∀{xs ys us zs} {τ : us ⊆ zs} →-- Irrelevant (λ (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → DisjointUnion τ₁ τ₂ τ)-- IrreflexivityDisjoint-irrefl′ : ∀{xs ys} {τ : xs ⊆ ys} → Disjoint τ τ → Null xsDisjoint-irrefl′ [] = []Disjoint-irrefl′ (y ∷ₙ d) = Disjoint-irrefl′ dDisjoint-irrefl : ∀{x xs ys} → Irreflexive {A = x ∷ xs ⊆ ys } _≡_ DisjointDisjoint-irrefl ≡.refl x with Disjoint-irrefl′ x... | () ∷ _-- SymmetryDisjointUnion-sym : ∀ {xs ys xys} {zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} {τ : xys ⊆ zs} →DisjointUnion τ₁ τ₂ τ → DisjointUnion τ₂ τ₁ τDisjointUnion-sym [] = []DisjointUnion-sym (y ∷ₙ d) = y ∷ₙ DisjointUnion-sym dDisjointUnion-sym (x≈y ∷ₗ d) = x≈y ∷ᵣ DisjointUnion-sym dDisjointUnion-sym (x≈y ∷ᵣ d) = x≈y ∷ₗ DisjointUnion-sym dDisjoint-sym : ∀ {xs ys} {zs} {τ₁ : xs ⊆ zs} {τ₂ : ys ⊆ zs} →Disjoint τ₁ τ₂ → Disjoint τ₂ τ₁Disjoint-sym [] = []Disjoint-sym (y ∷ₙ d) = y ∷ₙ Disjoint-sym dDisjoint-sym (x≈y ∷ₗ d) = x≈y ∷ᵣ Disjoint-sym dDisjoint-sym (x≈y ∷ᵣ d) = x≈y ∷ₗ Disjoint-sym d-- Empty sublistDisjointUnion-[]ˡ : ∀{xs ys} {ε : [] ⊆ ys} {τ : xs ⊆ ys} → DisjointUnion ε τ τDisjointUnion-[]ˡ {ε = []} {τ = []} = []DisjointUnion-[]ˡ {ε = y ∷ʳ ε} {τ = y ∷ʳ τ} = y ∷ₙ DisjointUnion-[]ˡDisjointUnion-[]ˡ {ε = y ∷ʳ ε} {τ = x≈y ∷ τ} = x≈y ∷ᵣ DisjointUnion-[]ˡDisjointUnion-[]ʳ : ∀{xs ys} {ε : [] ⊆ ys} {τ : xs ⊆ ys} → DisjointUnion τ ε τDisjointUnion-[]ʳ {ε = []} {τ = []} = []DisjointUnion-[]ʳ {ε = y ∷ʳ ε} {τ = y ∷ʳ τ} = y ∷ₙ DisjointUnion-[]ʳDisjointUnion-[]ʳ {ε = y ∷ʳ ε} {τ = x≈y ∷ τ} = x≈y ∷ₗ DisjointUnion-[]ʳ-- A sublist τ : x∷xs ⊆ ys can be split into two disjoint sublists-- [x] ⊆ ys (canonical choice) and (∷ˡ⁻ τ) : xs ⊆ ys.DisjointUnion-fromAny∘toAny-∷ˡ⁻ : ∀ {x xs ys} (τ : (x ∷ xs) ⊆ ys) → DisjointUnion (fromAny (toAny τ)) (∷ˡ⁻ τ) τDisjointUnion-fromAny∘toAny-∷ˡ⁻ (y ∷ʳ τ) = y ∷ₙ DisjointUnion-fromAny∘toAny-∷ˡ⁻ τDisjointUnion-fromAny∘toAny-∷ˡ⁻ (xRy ∷ τ) = xRy ∷ₗ DisjointUnion-[]ˡ-- Disjoint union of three mutually disjoint lists.---- τᵢⱼ denotes the disjoint union of τᵢ and τⱼ: DisjointUnion τᵢ τⱼ τᵢⱼrecord DisjointUnion³{xs ys zs ts} (τ₁ : xs ⊆ ts) (τ₂ : ys ⊆ ts) (τ₃ : zs ⊆ ts){xys xzs yzs} (τ₁₂ : xys ⊆ ts) (τ₁₃ : xzs ⊆ ts) (τ₂₃ : yzs ⊆ ts) : Set (a ⊔ b ⊔ r) wherefield{union³} : List Asub³ : union³ ⊆ tsjoin₁ : DisjointUnion τ₁ τ₂₃ sub³join₂ : DisjointUnion τ₂ τ₁₃ sub³join₃ : DisjointUnion τ₃ τ₁₂ sub³infixr 5 _∷ʳ-DisjointUnion³_ _∷₁-DisjointUnion³_ _∷₂-DisjointUnion³_ _∷₃-DisjointUnion³_-- Weakening the target list ts of a disjoint union._∷ʳ-DisjointUnion³_ :∀ {xs ys zs ts} {τ₁ : xs ⊆ ts} {τ₂ : ys ⊆ ts} {τ₃ : zs ⊆ ts} →∀ {xys xzs yzs} {τ₁₂ : xys ⊆ ts} {τ₁₃ : xzs ⊆ ts} {τ₂₃ : yzs ⊆ ts} →∀ y →DisjointUnion³ τ₁ τ₂ τ₃ τ₁₂ τ₁₃ τ₂₃ →DisjointUnion³ (y ∷ʳ τ₁) (y ∷ʳ τ₂) (y ∷ʳ τ₃) (y ∷ʳ τ₁₂) (y ∷ʳ τ₁₃) (y ∷ʳ τ₂₃)y ∷ʳ-DisjointUnion³ record{ sub³ = σ ; join₁ = d₁ ; join₂ = d₂ ; join₃ = d₃ } = record{ sub³ = y ∷ʳ σ; join₁ = y ∷ₙ d₁; join₂ = y ∷ₙ d₂; join₃ = y ∷ₙ d₃}-- Adding an element to the first list._∷₁-DisjointUnion³_ :∀ {xs ys zs ts} {τ₁ : xs ⊆ ts} {τ₂ : ys ⊆ ts} {τ₃ : zs ⊆ ts} →∀ {xys xzs yzs} {τ₁₂ : xys ⊆ ts} {τ₁₃ : xzs ⊆ ts} {τ₂₃ : yzs ⊆ ts} →∀ {x y} (xRy : R x y) →DisjointUnion³ τ₁ τ₂ τ₃ τ₁₂ τ₁₃ τ₂₃ →DisjointUnion³ (xRy ∷ τ₁) (y ∷ʳ τ₂) (y ∷ʳ τ₃) (xRy ∷ τ₁₂) (xRy ∷ τ₁₃) (y ∷ʳ τ₂₃)xRy ∷₁-DisjointUnion³ record{ sub³ = σ ; join₁ = d₁ ; join₂ = d₂ ; join₃ = d₃ } = record{ sub³ = xRy ∷ σ; join₁ = xRy ∷ₗ d₁; join₂ = xRy ∷ᵣ d₂; join₃ = xRy ∷ᵣ d₃}-- Adding an element to the second list._∷₂-DisjointUnion³_ :∀ {xs ys zs ts} {τ₁ : xs ⊆ ts} {τ₂ : ys ⊆ ts} {τ₃ : zs ⊆ ts} →∀ {xys xzs yzs} {τ₁₂ : xys ⊆ ts} {τ₁₃ : xzs ⊆ ts} {τ₂₃ : yzs ⊆ ts} →∀ {x y} (xRy : R x y) →DisjointUnion³ τ₁ τ₂ τ₃ τ₁₂ τ₁₃ τ₂₃ →DisjointUnion³ (y ∷ʳ τ₁) (xRy ∷ τ₂) (y ∷ʳ τ₃) (xRy ∷ τ₁₂) (y ∷ʳ τ₁₃) (xRy ∷ τ₂₃)xRy ∷₂-DisjointUnion³ record{ sub³ = σ ; join₁ = d₁ ; join₂ = d₂ ; join₃ = d₃ } = record{ sub³ = xRy ∷ σ; join₁ = xRy ∷ᵣ d₁; join₂ = xRy ∷ₗ d₂; join₃ = xRy ∷ᵣ d₃}-- Adding an element to the third list._∷₃-DisjointUnion³_ :∀ {xs ys zs ts} {τ₁ : xs ⊆ ts} {τ₂ : ys ⊆ ts} {τ₃ : zs ⊆ ts} →∀ {xys xzs yzs} {τ₁₂ : xys ⊆ ts} {τ₁₃ : xzs ⊆ ts} {τ₂₃ : yzs ⊆ ts} →∀ {x y} (xRy : R x y) →DisjointUnion³ τ₁ τ₂ τ₃ τ₁₂ τ₁₃ τ₂₃ →DisjointUnion³ (y ∷ʳ τ₁) (y ∷ʳ τ₂) (xRy ∷ τ₃) (y ∷ʳ τ₁₂) (xRy ∷ τ₁₃) (xRy ∷ τ₂₃)xRy ∷₃-DisjointUnion³ record{ sub³ = σ ; join₁ = d₁ ; join₂ = d₂ ; join₃ = d₃ } = record{ sub³ = xRy ∷ σ; join₁ = xRy ∷ᵣ d₁; join₂ = xRy ∷ᵣ d₂; join₃ = xRy ∷ₗ d₃}-- Computing the disjoint union of three disjoint lists.disjointUnion³ : ∀{xs ys zs ts} {τ₁ : xs ⊆ ts} {τ₂ : ys ⊆ ts} {τ₃ : zs ⊆ ts}{xys xzs yzs} {τ₁₂ : xys ⊆ ts} {τ₁₃ : xzs ⊆ ts} {τ₂₃ : yzs ⊆ ts} →DisjointUnion τ₁ τ₂ τ₁₂ →DisjointUnion τ₁ τ₃ τ₁₃ →DisjointUnion τ₂ τ₃ τ₂₃ →DisjointUnion³ τ₁ τ₂ τ₃ τ₁₂ τ₁₃ τ₂₃disjointUnion³ [] [] [] = record { sub³ = [] ; join₁ = [] ; join₂ = [] ; join₃ = [] }disjointUnion³ (y ∷ₙ d₁₂) (.y ∷ₙ d₁₃) (.y ∷ₙ d₂₃) = y ∷ʳ-DisjointUnion³ disjointUnion³ d₁₂ d₁₃ d₂₃disjointUnion³ (y ∷ₙ d₁₂) (xRy ∷ᵣ d₁₃) (.xRy ∷ᵣ d₂₃) = xRy ∷₃-DisjointUnion³ disjointUnion³ d₁₂ d₁₃ d₂₃disjointUnion³ (xRy ∷ᵣ d₁₂) (y ∷ₙ d₁₃) (.xRy ∷ₗ d₂₃) = xRy ∷₂-DisjointUnion³ disjointUnion³ d₁₂ d₁₃ d₂₃disjointUnion³ (xRy ∷ₗ d₁₂) (.xRy ∷ₗ d₁₃) (y ∷ₙ d₂₃) = xRy ∷₁-DisjointUnion³ disjointUnion³ d₁₂ d₁₃ d₂₃disjointUnion³ (xRy ∷ᵣ d₁₂) (xRy′ ∷ᵣ d₁₃) ()-- If a sublist τ is disjoint to two lists σ₁ and σ₂,-- then also to their disjoint union σ.disjoint⇒disjoint-to-union : ∀{xs ys zs yzs ts}{τ : xs ⊆ ts} {σ₁ : ys ⊆ ts} {σ₂ : zs ⊆ ts} {σ : yzs ⊆ ts} →Disjoint τ σ₁ → Disjoint τ σ₂ → DisjointUnion σ₁ σ₂ σ → Disjoint τ σdisjoint⇒disjoint-to-union d₁ d₂ u = let_ , _ , u₁ = Disjoint→DisjointUnion d₁_ , _ , u₂ = Disjoint→DisjointUnion d₂in DisjointUnion→Disjoint (DisjointUnion³.join₁ (disjointUnion³ u₁ u₂ u))open Disjointness public-- Monotonicity of disjointness.module DisjointnessMonotonicity{R : REL A B r} {S : REL B C s} {T : REL A C t}(rs⇒t : Trans R S T) where-- We can enlarge and convert the target list of a disjoint union.weakenDisjointUnion : ∀ {xs ys xys zs ws}{τ₁ : Sublist R xs zs}{τ₂ : Sublist R ys zs}{τ : Sublist R xys zs} (σ : Sublist S zs ws) →DisjointUnion τ₁ τ₂ τ →DisjointUnion (trans rs⇒t τ₁ σ) (trans rs⇒t τ₂ σ) (trans rs⇒t τ σ)weakenDisjointUnion [] [] = []weakenDisjointUnion (w ∷ʳ σ) d = w ∷ₙ weakenDisjointUnion σ dweakenDisjointUnion (_ ∷ σ) (y ∷ₙ d) = _ ∷ₙ weakenDisjointUnion σ dweakenDisjointUnion (zSw ∷ σ) (xRz ∷ₗ d) = rs⇒t xRz zSw ∷ₗ weakenDisjointUnion σ dweakenDisjointUnion (zSw ∷ σ) (yRz ∷ᵣ d) = rs⇒t yRz zSw ∷ᵣ weakenDisjointUnion σ dweakenDisjoint : ∀ {xs ys zs ws}{τ₁ : Sublist R xs zs}{τ₂ : Sublist R ys zs} (σ : Sublist S zs ws) →Disjoint τ₁ τ₂ →Disjoint (trans rs⇒t τ₁ σ) (trans rs⇒t τ₂ σ)weakenDisjoint [] [] = []weakenDisjoint (w ∷ʳ σ) d = w ∷ₙ weakenDisjoint σ dweakenDisjoint (_ ∷ σ) (y ∷ₙ d) = _ ∷ₙ weakenDisjoint σ dweakenDisjoint (zSw ∷ σ) (xRz ∷ₗ d) = rs⇒t xRz zSw ∷ₗ weakenDisjoint σ dweakenDisjoint (zSw ∷ σ) (yRz ∷ᵣ d) = rs⇒t yRz zSw ∷ᵣ weakenDisjoint σ d-- Lists remain disjoint when elements are removed.shrinkDisjoint : ∀ {us vs xs ys zs}(σ₁ : Sublist R us xs) {τ₁ : Sublist S xs zs}(σ₂ : Sublist R vs ys) {τ₂ : Sublist S ys zs} →Disjoint τ₁ τ₂ →Disjoint (trans rs⇒t σ₁ τ₁) (trans rs⇒t σ₂ τ₂)shrinkDisjoint σ₁ σ₂ (y ∷ₙ d) = y ∷ₙ shrinkDisjoint σ₁ σ₂ dshrinkDisjoint (x ∷ʳ σ₁) σ₂ (xSz ∷ₗ d) = _ ∷ₙ shrinkDisjoint σ₁ σ₂ dshrinkDisjoint (uRx ∷ σ₁) σ₂ (xSz ∷ₗ d) = rs⇒t uRx xSz ∷ₗ shrinkDisjoint σ₁ σ₂ dshrinkDisjoint σ₁ (y ∷ʳ σ₂) (ySz ∷ᵣ d) = _ ∷ₙ shrinkDisjoint σ₁ σ₂ dshrinkDisjoint σ₁ (vRy ∷ σ₂) (ySz ∷ᵣ d) = rs⇒t vRy ySz ∷ᵣ shrinkDisjoint σ₁ σ₂ dshrinkDisjoint [] [] [] = []open DisjointnessMonotonicity public
-------------------------------------------------------------------------- The Agda standard library---- This file contains some core definitions which are re-exported by-- Data.List.Relation.Binary.Sublist.Heterogeneous.-------------------------------------------------------------------------- This module has R as explicit parameter, in contrast to the implicit-- parameter R of the main module Sublist.Heterogeneous.-- Parameterized data modules (https://github.com/agda/agda/issues/3210)-- may simplify this setup, making this module obsolete.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (REL)module Data.List.Relation.Binary.Sublist.Heterogeneous.Core{a b r} {A : Set a} {B : Set b} (R : REL A B r)whereopen import Level using (_⊔_)open import Data.List.Base using (List; []; _∷_)infixr 5 _∷_ _∷ʳ_data Sublist : REL (List A) (List B) (a ⊔ b ⊔ r) where[] : Sublist [] []_∷ʳ_ : ∀ {xs ys} → ∀ y → Sublist xs ys → Sublist xs (y ∷ ys)_∷_ : ∀ {x xs y ys} → R x y → Sublist xs ys → Sublist (x ∷ xs) (y ∷ ys)
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the sublist relation with respect to a-- setoid which is decidable. This is a generalisation of what is-- commonly known as Order Preserving Embeddings (OPE).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid; DecPoset)open import Relation.Binary.Structuresusing (IsDecPartialOrder)open import Relation.Binary.Definitions using (Decidable)module Data.List.Relation.Binary.Sublist.DecSetoid{c ℓ} (S : DecSetoid c ℓ) whereimport Data.List.Relation.Binary.Equality.DecSetoid as DecSetoidEqualityimport Data.List.Relation.Binary.Sublist.Setoid as SetoidSublistimport Data.List.Relation.Binary.Sublist.Heterogeneous.Propertiesas HeterogeneousPropertiesopen import Level using (_⊔_)open DecSetoid Sopen DecSetoidEquality Sinfix 4 _⊆?_-------------------------------------------------------------------------- Re-export core definitionsopen SetoidSublist setoid public-------------------------------------------------------------------------- Additional relational properties_⊆?_ : Decidable _⊆__⊆?_ = HeterogeneousProperties.sublist? _≟_⊆-isDecPartialOrder : IsDecPartialOrder _≋_ _⊆_⊆-isDecPartialOrder = record{ isPartialOrder = ⊆-isPartialOrder; _≟_ = _≋?_; _≤?_ = _⊆?_}⊆-decPoset : DecPoset c (c ⊔ ℓ) (c ⊔ ℓ)⊆-decPoset = record{ isDecPartialOrder = ⊆-isDecPartialOrder}
-------------------------------------------------------------------------- The Agda standard library---- A solver for proving that one list is a sublist of the other.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)module Data.List.Relation.Binary.Sublist.DecSetoid.Solver {c ℓ} (S : DecSetoid c ℓ) whereopen DecSetoid Sopen import Data.List.Relation.Binary.Sublist.Heterogeneous.Solver _≈_ refl _≟_using (Item; module Item; TList; module TList; prove) public
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the sublist relation for types which have-- a decidable equality. This is commonly known as Order Preserving-- Embeddings (OPE).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Binary.Sublist.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A)whereopen import Data.List.Relation.Binary.Equality.DecPropositional _≟_using (_≡?_)import Data.List.Relation.Binary.Sublist.DecSetoid as DecSetoidSublistimport Data.List.Relation.Binary.Sublist.Propositional as PropositionalSublistopen import Relation.Binary.Bundles using (DecPoset)open import Relation.Binary.Structures using (IsDecPartialOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Re-export core definitions and operationsopen PropositionalSublist {A = A} publicopen DecSetoidSublist (decSetoid _≟_) using (_⊆?_) public-------------------------------------------------------------------------- Additional relational properties⊆-isDecPartialOrder : IsDecPartialOrder _≡_ _⊆_⊆-isDecPartialOrder = record{ isPartialOrder = ⊆-isPartialOrder; _≟_ = _≡?_; _≤?_ = _⊆?_}⊆-decPoset : DecPoset a a a⊆-decPoset = record{ isDecPartialOrder = ⊆-isDecPartialOrder}
-------------------------------------------------------------------------- The Agda standard library---- A solver for proving that one list is a sublist of the other for-- types which enjoy decidable equalities.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Binary.Sublist.DecPropositional.Solver{a} {A : Set a} (_≟_ : DecidableEquality A)whereopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)open import Data.List.Relation.Binary.Sublist.DecSetoid.Solver (decSetoid _≟_) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of the homogeneous prefix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Prefix.Homogeneous.Properties whereopen import Levelopen import Function.Base using (_∘′_)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder)open import Data.List.Relation.Binary.Pointwise as Pointwise using (Pointwise)open import Data.List.Relation.Binary.Prefix.Heterogeneousopen import Data.List.Relation.Binary.Prefix.Heterogeneous.Propertiesprivatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B sisPreorder : IsPreorder R S → IsPreorder (Pointwise R) (Prefix S)isPreorder po = record{ isEquivalence = Pointwise.isEquivalence PO.isEquivalence; reflexive = fromPointwise ∘′ Pointwise.map PO.reflexive; trans = trans PO.trans} where module PO = IsPreorder poisPartialOrder : IsPartialOrder R S → IsPartialOrder (Pointwise R) (Prefix S)isPartialOrder po = record{ isPreorder = isPreorder PO.isPreorder; antisym = antisym PO.antisym} where module PO = IsPartialOrder poisDecPartialOrder : IsDecPartialOrder R S → IsDecPartialOrder (Pointwise R) (Prefix S)isDecPartialOrder dpo = record{ isPartialOrder = isPartialOrder DPO.isPartialOrder; _≟_ = Pointwise.decidable DPO._≟_; _≤?_ = prefix? DPO._≤?_} where module DPO = IsDecPartialOrder dpo
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the heterogeneous prefix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Prefix.Heterogeneous whereopen import Levelopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.Relation.Binary.Pointwiseusing (Pointwise; []; _∷_)open import Data.Product.Base using (∃; _×_; _,_; uncurry)open import Relation.Binary.Core using (REL; _⇒_)module _ {a b r} {A : Set a} {B : Set b} (R : REL A B r) whereinfixr 5 _∷_ _++_data Prefix : REL (List A) (List B) (a ⊔ b ⊔ r) where[] : ∀ {bs} → Prefix [] bs_∷_ : ∀ {a b as bs} → R a b → Prefix as bs → Prefix (a ∷ as) (b ∷ bs)data PrefixView (as : List A) : List B → Set (a ⊔ b ⊔ r) where_++_ : ∀ {cs} → Pointwise R as cs → ∀ ds → PrefixView as (cs List.++ ds)module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} {a b as bs} wherehead : Prefix R (a ∷ as) (b ∷ bs) → R a bhead (r ∷ rs) = rtail : Prefix R (a ∷ as) (b ∷ bs) → Prefix R as bstail (r ∷ rs) = rsuncons : Prefix R (a ∷ as) (b ∷ bs) → R a b × Prefix R as bsuncons (r ∷ rs) = r , rsmodule _ {a b r s} {A : Set a} {B : Set b} {R : REL A B r} {S : REL A B s} wheremap : R ⇒ S → Prefix R ⇒ Prefix Smap R⇒S [] = []map R⇒S (r ∷ rs) = R⇒S r ∷ map R⇒S rsmodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} whereinfixr 5 _++ᵖ__++ᵖ_ : ∀ {as bs} → Prefix R as bs → ∀ suf → Prefix R as (bs List.++ suf)[] ++ᵖ suf = [](r ∷ rs) ++ᵖ suf = r ∷ (rs ++ᵖ suf)toView : ∀ {as bs} → Prefix R as bs → PrefixView R as bstoView [] = [] ++ _toView (r ∷ rs) with rs′ ++ ds ← toView rs = (r ∷ rs′) ++ dsfromView : ∀ {as bs} → PrefixView R as bs → Prefix R as bsfromView ([] ++ ds) = []fromView ((r ∷ rs) ++ ds) = r ∷ fromView (rs ++ ds)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the heterogeneous prefix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Prefix.Heterogeneous.Properties whereopen import Levelopen import Data.Bool.Base using (true; false)open import Data.Emptyopen import Data.List.Relation.Unary.All as All using (All; []; _∷_)import Data.List.Relation.Unary.All.Properties as Allopen import Data.List.Base as List hiding (map; uncons)open import Data.List.Membership.Propositional.Properties using ([]∈inits)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Data.List.Relation.Binary.Prefix.Heterogeneous as Prefix hiding (PrefixView; _++_)open import Data.Nat.Base using (ℕ; zero; suc; _≤_; z≤n; s≤s)open import Data.Nat.Properties using (suc-injective)open import Data.Product.Base as Product using (_×_; _,_; proj₁; proj₂; uncurry)open import Function.Baseopen import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Decidable as Dec using (_×-dec_; yes; no; _because_)open import Relation.Unary as U using (Pred)open import Relation.Binary.Core using (Rel; REL; _⇒_)open import Relation.Binary.Definitionsusing (Trans; Antisym; Irrelevant; Decidable)open import Relation.Binary.PropositionalEquality.Core using (_≡_; _≢_; refl; cong₂)privatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B s-------------------------------------------------------------------------- First as a decidable partial order (once made homogeneous)fromPointwise : Pointwise R ⇒ Prefix RfromPointwise [] = []fromPointwise (r ∷ rs) = r ∷ fromPointwise rstoPointwise : ∀ {as bs} → length as ≡ length bs →Prefix R as bs → Pointwise R as bstoPointwise {bs = []} eq [] = []toPointwise eq (r ∷ rs) = r ∷ toPointwise (suc-injective eq) rsmodule _ {a b c r s t} {A : Set a} {B : Set b} {C : Set c}{R : REL A B r} {S : REL B C s} {T : REL A C t} wheretrans : Trans R S T → Trans (Prefix R) (Prefix S) (Prefix T)trans rs⇒t [] ss = []trans rs⇒t (r ∷ rs) (s ∷ ss) = rs⇒t r s ∷ trans rs⇒t rs ssmodule _ {a b r s e} {A : Set a} {B : Set b}{R : REL A B r} {S : REL B A s} {E : REL A B e} whereantisym : Antisym R S E → Antisym (Prefix R) (Prefix S) (Pointwise E)antisym rs⇒e [] [] = []antisym rs⇒e (r ∷ rs) (s ∷ ss) = rs⇒e r s ∷ antisym rs⇒e rs ss-------------------------------------------------------------------------- lengthlength-mono : ∀ {as bs} → Prefix R as bs → length as ≤ length bslength-mono [] = z≤nlength-mono (r ∷ rs) = s≤s (length-mono rs)-------------------------------------------------------------------------- _++_++⁺ : ∀ {as bs cs ds} → Pointwise R as bs →Prefix R cs ds → Prefix R (as ++ cs) (bs ++ ds)++⁺ [] cs⊆ds = cs⊆ds++⁺ (r ∷ rs) cs⊆ds = r ∷ (++⁺ rs cs⊆ds)++⁻ : ∀ {as bs cs ds} → length as ≡ length bs →Prefix R (as ++ cs) (bs ++ ds) → Prefix R cs ds++⁻ {as = []} {[]} eq rs = rs++⁻ {as = _ ∷ _} {_ ∷ _} eq (_ ∷ rs) = ++⁻ (suc-injective eq) rs-------------------------------------------------------------------------- mapmodule _ {a b c d r} {A : Set a} {B : Set b} {C : Set c} {D : Set d}{R : REL C D r} wheremap⁺ : ∀ {as bs} (f : A → C) (g : B → D) →Prefix (λ a b → R (f a) (g b)) as bs →Prefix R (List.map f as) (List.map g bs)map⁺ f g [] = []map⁺ f g (r ∷ rs) = r ∷ map⁺ f g rsmap⁻ : ∀ {as bs} (f : A → C) (g : B → D) →Prefix R (List.map f as) (List.map g bs) →Prefix (λ a b → R (f a) (g b)) as bsmap⁻ {[]} {bs} f g rs = []map⁻ {a ∷ as} {b ∷ bs} f g (r ∷ rs) = r ∷ map⁻ f g rs-------------------------------------------------------------------------- filtermodule _ {p q} {P : Pred A p} {Q : Pred B q} (P? : U.Decidable P) (Q? : U.Decidable Q)(P⇒Q : ∀ {a b} → R a b → P a → Q b) (Q⇒P : ∀ {a b} → R a b → Q b → P a)wherefilter⁺ : ∀ {as bs} → Prefix R as bs → Prefix R (filter P? as) (filter Q? bs)filter⁺ [] = []filter⁺ {a ∷ as} {b ∷ bs} (r ∷ rs) with P? a | Q? b... | true because _ | true because _ = r ∷ filter⁺ rs... | yes pa | no ¬qb = ⊥-elim (¬qb (P⇒Q r pa))... | no ¬pa | yes qb = ⊥-elim (¬pa (Q⇒P r qb))... | false because _ | false because _ = filter⁺ rs-------------------------------------------------------------------------- taketake⁺ : ∀ {as bs} n → Prefix R as bs →Prefix R (take n as) (take n bs)take⁺ zero rs = []take⁺ (suc n) [] = []take⁺ (suc n) (r ∷ rs) = r ∷ take⁺ n rstake⁻ : ∀ {as bs} n →Prefix R (take n as) (take n bs) →Prefix R (drop n as) (drop n bs) →Prefix R as bstake⁻ zero hds tls = tlstake⁻ {as = []} (suc n) hds tls = []take⁻ {as = a ∷ as} {b ∷ bs} (suc n) (r ∷ hds) tls = r ∷ take⁻ n hds tls-------------------------------------------------------------------------- dropdrop⁺ : ∀ {as bs} n → Prefix R as bs → Prefix R (drop n as) (drop n bs)drop⁺ zero rs = rsdrop⁺ (suc n) [] = []drop⁺ (suc n) (r ∷ rs) = drop⁺ n rsdrop⁻ : ∀ {as bs} n → Pointwise R (take n as) (take n bs) →Prefix R (drop n as) (drop n bs) → Prefix R as bsdrop⁻ zero hds tls = tlsdrop⁻ {as = []} (suc n) hds tls = []drop⁻ {as = _ ∷ _} {_ ∷ _} (suc n) (r ∷ hds) tls = r ∷ (drop⁻ n hds tls)-------------------------------------------------------------------------- replicatereplicate⁺ : ∀ {m n a b} → m ≤ n → R a b →Prefix R (replicate m a) (replicate n b)replicate⁺ z≤n r = []replicate⁺ (s≤s m≤n) r = r ∷ replicate⁺ m≤n rreplicate⁻ : ∀ {m n a b} → m ≢ 0 →Prefix R (replicate m a) (replicate n b) → R a breplicate⁻ {m = zero} {n} m≢0 r = ⊥-elim (m≢0 refl)replicate⁻ {m = suc m} {suc n} m≢0 rs = Prefix.head rs-------------------------------------------------------------------------- initsmodule _ {a r} {A : Set a} {R : Rel A r} whereinits⁺ : ∀ {as} → Pointwise R as as → All (flip (Prefix R) as) (inits as)inits⁺ [] = [] ∷ []inits⁺ (r ∷ rs) = [] ∷ All.map⁺ (All.map (r ∷_) (inits⁺ rs))inits⁻ : ∀ {as} → All (flip (Prefix R) as) (inits as) → Pointwise R as asinits⁻ {as = []} rs = []inits⁻ {as = a ∷ as} (r ∷ rs) =let (hd , tls) = All.unzip (All.map uncons (All.map⁻ rs)) inAll.lookup hd ([]∈inits as) ∷ inits⁻ tls-------------------------------------------------------------------------- zip(With)module _ {a b c} {A : Set a} {B : Set b} {C : Set c}{d e f} {D : Set d} {E : Set e} {F : Set f}{r s t} {R : REL A D r} {S : REL B E s} {T : REL C F t} wherezipWith⁺ : ∀ {as bs ds es} {f : A → B → C} {g : D → E → F} →(∀ {a b c d} → R a c → S b d → T (f a b) (g c d)) →Prefix R as ds → Prefix S bs es →Prefix T (zipWith f as bs) (zipWith g ds es)zipWith⁺ f [] ss = []zipWith⁺ f (r ∷ rs) [] = []zipWith⁺ f (r ∷ rs) (s ∷ ss) = f r s ∷ zipWith⁺ f rs ssmodule _ {a b c d} {A : Set a} {B : Set b} {C : Set c} {D : Set d}{r s} {R : REL A C r} {S : REL B D s} whereprivateR×S : REL (A × B) (C × D) _R×S (a , b) (c , d) = R a c × S b dzip⁺ : ∀ {as bs cs ds} → Prefix R as cs → Prefix S bs ds →Prefix R×S (zip as bs) (zip cs ds)zip⁺ = zipWith⁺ _,_-------------------------------------------------------------------------- Irrelevancemodule _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} whereirrelevant : Irrelevant R → Irrelevant (Prefix R)irrelevant R-irr [] [] = reflirrelevant R-irr (r ∷ rs) (r′ ∷ rs′) =cong₂ _∷_ (R-irr r r′) (irrelevant R-irr rs rs′)-------------------------------------------------------------------------- Decidabilityprefix? : Decidable R → Decidable (Prefix R)prefix? R? [] bs = yes []prefix? R? (a ∷ as) [] = no (λ ())prefix? R? (a ∷ as) (b ∷ bs) = Dec.map′ (uncurry _∷_) uncons$ R? a b ×-dec prefix? R? as bs
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of relations to lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Pointwise whereopen import Algebra.Core using (Op₂)open import Function.Baseopen import Function.Bundles using (Inverse)open import Data.Bool.Base using (true; false)open import Data.Product.Base hiding (map)open import Data.List.Base as List hiding (map; head; tail; uncons)open import Data.List.Properties using (≡-dec; length-++)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.AllPairs using (AllPairs; []; _∷_)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.Fin.Base using (Fin; toℕ; cast) renaming (zero to fzero; suc to fsuc)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Nat.Propertiesopen import Levelopen import Relation.Nullary hiding (Irrelevant)import Relation.Nullary.Decidable as Dec using (map′)open import Relation.Unary as U using (Pred)open import Relation.Binary.Core renaming (Rel to Rel₂)open import Relation.Binary.Definitions using (_Respects_; _Respects₂_)open import Relation.Binary.Bundles using (Setoid; DecSetoid; Preorder; Poset)open import Relation.Binary.Structures using (IsEquivalence; IsDecEquivalence; IsPartialOrder; IsPreorder)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b c d p q ℓ ℓ₁ ℓ₂ : LevelA B C D : Set dx y z : Aws xs ys zs : List AR S T : REL A B ℓ-------------------------------------------------------------------------- Re-exporting the definition and basic operations------------------------------------------------------------------------open import Data.List.Relation.Binary.Pointwise.Base publicopen import Data.List.Relation.Binary.Pointwise.Properties public-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence R → IsEquivalence (Pointwise R)isEquivalence eq = record{ refl = refl Eq.refl; sym = symmetric Eq.sym; trans = transitive Eq.trans} where module Eq = IsEquivalence eqisDecEquivalence : IsDecEquivalence R → IsDecEquivalence (Pointwise R)isDecEquivalence eq = record{ isEquivalence = isEquivalence DE.isEquivalence; _≟_ = decidable DE._≟_} where module DE = IsDecEquivalence eqisPreorder : IsPreorder R S → IsPreorder (Pointwise R) (Pointwise S)isPreorder pre = record{ isEquivalence = isEquivalence Pre.isEquivalence; reflexive = reflexive Pre.reflexive; trans = transitive Pre.trans} where module Pre = IsPreorder preisPartialOrder : IsPartialOrder R S →IsPartialOrder (Pointwise R) (Pointwise S)isPartialOrder po = record{ isPreorder = isPreorder PO.isPreorder; antisym = antisymmetric PO.antisym} where module PO = IsPartialOrder po-------------------------------------------------------------------------- Bundlessetoid : Setoid a ℓ → Setoid a (a ⊔ ℓ)setoid s = record{ isEquivalence = isEquivalence (Setoid.isEquivalence s)}decSetoid : DecSetoid a ℓ → DecSetoid a (a ⊔ ℓ)decSetoid d = record{ isDecEquivalence = isDecEquivalence (DecSetoid.isDecEquivalence d)}preorder : Preorder a ℓ₁ ℓ₂ → Preorder _ _ _preorder p = record{ isPreorder = isPreorder (Preorder.isPreorder p)}poset : Poset a ℓ₁ ℓ₂ → Poset _ _ _poset p = record{ isPartialOrder = isPartialOrder (Poset.isPartialOrder p)}-------------------------------------------------------------------------- Relationships to other list predicates------------------------------------------------------------------------All-resp-Pointwise : ∀ {P : Pred A p} → P Respects R →(All P) Respects (Pointwise R)All-resp-Pointwise resp [] [] = []All-resp-Pointwise resp (x∼y ∷ xs) (px ∷ pxs) =resp x∼y px ∷ All-resp-Pointwise resp xs pxsAny-resp-Pointwise : ∀ {P : Pred A p} → P Respects R →(Any P) Respects (Pointwise R)Any-resp-Pointwise resp (x∼y ∷ xs) (here px) = here (resp x∼y px)Any-resp-Pointwise resp (x∼y ∷ xs) (there pxs) =there (Any-resp-Pointwise resp xs pxs)AllPairs-resp-Pointwise : R Respects₂ S →(AllPairs R) Respects (Pointwise S)AllPairs-resp-Pointwise _ [] [] = []AllPairs-resp-Pointwise resp@(respₗ , respᵣ) (x∼y ∷ xs) (px ∷ pxs) =All-resp-Pointwise respₗ xs (All.map (respᵣ x∼y) px) ∷(AllPairs-resp-Pointwise resp xs pxs)-------------------------------------------------------------------------- Relationship to functions over lists-------------------------------------------------------------------------- lengthPointwise-length : Pointwise R xs ys → length xs ≡ length ysPointwise-length [] = ≡.reflPointwise-length (x∼y ∷ xs∼ys) = ≡.cong ℕ.suc (Pointwise-length xs∼ys)-------------------------------------------------------------------------- tabulatetabulate⁺ : ∀ {n} {f : Fin n → A} {g : Fin n → B} →(∀ i → R (f i) (g i)) → Pointwise R (tabulate f) (tabulate g)tabulate⁺ {n = zero} f∼g = []tabulate⁺ {n = suc n} f∼g = f∼g fzero ∷ tabulate⁺ (f∼g ∘ fsuc)tabulate⁻ : ∀ {n} {f : Fin n → A} {g : Fin n → B} →Pointwise R (tabulate f) (tabulate g) → (∀ i → R (f i) (g i))tabulate⁻ {n = suc n} (x∼y ∷ xs∼ys) fzero = x∼ytabulate⁻ {n = suc n} (x∼y ∷ xs∼ys) (fsuc i) = tabulate⁻ xs∼ys i-------------------------------------------------------------------------- _++_++⁺ : Pointwise R ws xs → Pointwise R ys zs →Pointwise R (ws ++ ys) (xs ++ zs)++⁺ [] ys∼zs = ys∼zs++⁺ (w∼x ∷ ws∼xs) ys∼zs = w∼x ∷ ++⁺ ws∼xs ys∼zs++-cancelˡ : ∀ xs → Pointwise R (xs ++ ys) (xs ++ zs) → Pointwise R ys zs++-cancelˡ [] ys∼zs = ys∼zs++-cancelˡ (x ∷ xs) (_ ∷ xs++ys∼xs++zs) = ++-cancelˡ xs xs++ys∼xs++zs++-cancelʳ : ∀ ys zs → Pointwise R (ys ++ xs) (zs ++ xs) → Pointwise R ys zs++-cancelʳ [] [] _ = []++-cancelʳ (y ∷ ys) (z ∷ zs) (y∼z ∷ ys∼zs) = y∼z ∷ (++-cancelʳ ys zs ys∼zs)-- Impossible cases++-cancelʳ {xs = xs} [] (z ∷ zs) eq =contradiction (≡.trans (Pointwise-length eq) (length-++ (z ∷ zs))) (m≢1+n+m (length xs))++-cancelʳ {xs = xs} (y ∷ ys) [] eq =contradiction (≡.trans (≡.sym (length-++ (y ∷ ys))) (Pointwise-length eq)) (m≢1+n+m (length xs) ∘ ≡.sym)-------------------------------------------------------------------------- concatconcat⁺ : ∀ {xss yss} → Pointwise (Pointwise R) xss yss →Pointwise R (concat xss) (concat yss)concat⁺ [] = []concat⁺ (xs∼ys ∷ xss∼yss) = ++⁺ xs∼ys (concat⁺ xss∼yss)-------------------------------------------------------------------------- reversereverseAcc⁺ : Pointwise R ws xs → Pointwise R ys zs →Pointwise R (reverseAcc ws ys) (reverseAcc xs zs)reverseAcc⁺ rs′ [] = rs′reverseAcc⁺ rs′ (r ∷ rs) = reverseAcc⁺ (r ∷ rs′) rsʳ++⁺ : Pointwise R ws xs → Pointwise R ys zs →Pointwise R (ws ʳ++ ys) (xs ʳ++ zs)ʳ++⁺ rs rs′ = reverseAcc⁺ rs′ rsreverse⁺ : Pointwise R xs ys → Pointwise R (reverse xs) (reverse ys)reverse⁺ = reverseAcc⁺ []-------------------------------------------------------------------------- mapmap⁺ : ∀ (f : A → C) (g : B → D) →Pointwise (λ a b → R (f a) (g b)) xs ys →Pointwise R (List.map f xs) (List.map g ys)map⁺ f g [] = []map⁺ f g (r ∷ rs) = r ∷ map⁺ f g rsmap⁻ : ∀ (f : A → C) (g : B → D) →Pointwise R (List.map f xs) (List.map g ys) →Pointwise (λ a b → R (f a) (g b)) xs ysmap⁻ {xs = []} {[]} f g [] = []map⁻ {xs = _ ∷ _} {_ ∷ _} f g (r ∷ rs) = r ∷ map⁻ f g rs-------------------------------------------------------------------------- foldrfoldr⁺ : ∀ {_•_ : Op₂ A} {_◦_ : Op₂ B} →(∀ {w x y z} → R w x → R y z → R (w • y) (x ◦ z)) →∀ {e f} → R e f → Pointwise R xs ys →R (foldr _•_ e xs) (foldr _◦_ f ys)foldr⁺ _ e~f [] = e~ffoldr⁺ pres e~f (x~y ∷ xs~ys) = pres x~y (foldr⁺ pres e~f xs~ys)-------------------------------------------------------------------------- filtermodule _ {P : Pred A p} {Q : Pred B q}(P? : U.Decidable P) (Q? : U.Decidable Q)(P⇒Q : ∀ {a b} → R a b → P a → Q b)(Q⇒P : ∀ {a b} → R a b → Q b → P a)wherefilter⁺ : Pointwise R xs ys →Pointwise R (filter P? xs) (filter Q? ys)filter⁺ [] = []filter⁺ {x ∷ _} {y ∷ _} (r ∷ rs) with P? x | Q? y... | true because _ | true because _ = r ∷ filter⁺ rs... | false because _ | false because _ = filter⁺ rs... | yes p | no ¬q = contradiction (P⇒Q r p) ¬q... | no ¬p | yes q = contradiction (Q⇒P r q) ¬p-------------------------------------------------------------------------- replicatereplicate⁺ : R x y → ∀ n → Pointwise R (replicate n x) (replicate n y)replicate⁺ r 0 = []replicate⁺ r (suc n) = r ∷ replicate⁺ r n-------------------------------------------------------------------------- lookuplookup⁻ : length xs ≡ length ys →(∀ {i j} → toℕ i ≡ toℕ j → R (lookup xs i) (lookup ys j)) →Pointwise R xs yslookup⁻ {xs = []} {ys = []} _ _ = []lookup⁻ {xs = _ ∷ _} {ys = _ ∷ _} |xs|≡|ys| eq = eq {fzero} ≡.refl ∷lookup⁻ (suc-injective |xs|≡|ys|) (eq ∘ ≡.cong ℕ.suc)lookup⁺ : ∀ (Rxys : Pointwise R xs ys) →∀ i → (let j = cast (Pointwise-length Rxys) i) →R (lookup xs i) (lookup ys j)lookup⁺ (Rxy ∷ _) fzero = Rxylookup⁺ (_ ∷ Rxys) (fsuc i) = lookup⁺ Rxys i-------------------------------------------------------------------------- Properties of propositional pointwise------------------------------------------------------------------------Pointwise-≡⇒≡ : Pointwise {A = A} _≡_ ⇒ _≡_Pointwise-≡⇒≡ [] = ≡.reflPointwise-≡⇒≡ (≡.refl ∷ xs∼ys) with Pointwise-≡⇒≡ xs∼ys... | ≡.refl = ≡.refl≡⇒Pointwise-≡ : _≡_ ⇒ Pointwise {A = A} _≡_≡⇒Pointwise-≡ ≡.refl = refl ≡.reflPointwise-≡↔≡ : Inverse (setoid (≡.setoid A)) (≡.setoid (List A))Pointwise-≡↔≡ = record{ to = id; from = id; to-cong = Pointwise-≡⇒≡; from-cong = ≡⇒Pointwise-≡; inverse = Pointwise-≡⇒≡ , ≡⇒Pointwise-≡}
-------------------------------------------------------------------------- The Agda standard library---- Properties of pointwise lifting of relations to lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Pointwise.Properties whereopen import Data.Product.Base using (_,_; uncurry)open import Data.List.Base using (List; []; _∷_)open import Levelopen import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Definitionsimport Relation.Binary.PropositionalEquality.Core as ≡open import Relation.Nullary using (yes; no; _×-dec_)import Relation.Nullary.Decidable as Decopen import Data.List.Relation.Binary.Pointwise.Baseprivatevariablea b ℓ : LevelA : Set aB : Set bR S T : REL A B ℓ-------------------------------------------------------------------------- Relational properties------------------------------------------------------------------------reflexive : R ⇒ S → Pointwise R ⇒ Pointwise Sreflexive = maprefl : Reflexive R → Reflexive (Pointwise R)refl rfl {[]} = []refl rfl {x ∷ xs} = rfl ∷ refl rflsymmetric : Sym R S → Sym (Pointwise R) (Pointwise S)symmetric sym [] = []symmetric sym (x∼y ∷ xs∼ys) = sym x∼y ∷ symmetric sym xs∼ystransitive : Trans R S T →Trans (Pointwise R) (Pointwise S) (Pointwise T)transitive trans [] [] = []transitive trans (x∼y ∷ xs∼ys) (y∼z ∷ ys∼zs) =trans x∼y y∼z ∷ transitive trans xs∼ys ys∼zsantisymmetric : Antisym R S T →Antisym (Pointwise R) (Pointwise S) (Pointwise T)antisymmetric antisym [] [] = []antisymmetric antisym (x∼y ∷ xs∼ys) (y∼x ∷ ys∼xs) =antisym x∼y y∼x ∷ antisymmetric antisym xs∼ys ys∼xsrespʳ : R Respectsʳ S → (Pointwise R) Respectsʳ (Pointwise S)respʳ resp [] [] = []respʳ resp (x≈y ∷ xs≈ys) (z∼x ∷ zs∼xs) = resp x≈y z∼x ∷ respʳ resp xs≈ys zs∼xsrespˡ : R Respectsˡ S → (Pointwise R) Respectsˡ (Pointwise S)respˡ resp [] [] = []respˡ resp (x≈y ∷ xs≈ys) (x∼z ∷ xs∼zs) = resp x≈y x∼z ∷ respˡ resp xs≈ys xs∼zsrespects₂ : R Respects₂ S → (Pointwise R) Respects₂ (Pointwise S)respects₂ (rʳ , rˡ) = respʳ rʳ , respˡ rˡdecidable : Decidable R → Decidable (Pointwise R)decidable _ [] [] = yes []decidable _ [] (y ∷ ys) = no λ()decidable _ (x ∷ xs) [] = no λ()decidable R? (x ∷ xs) (y ∷ ys) = Dec.map′ (uncurry _∷_) uncons(R? x y ×-dec decidable R? xs ys)irrelevant : Irrelevant R → Irrelevant (Pointwise R)irrelevant irr [] [] = ≡.reflirrelevant irr (r ∷ rs) (r₁ ∷ rs₁) =≡.cong₂ _∷_ (irr r r₁) (irrelevant irr rs rs₁)
-------------------------------------------------------------------------- The Agda standard library---- Pointwise lifting of relations to lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Pointwise.Base whereopen import Data.Product.Base as Product using (_×_; _,_; <_,_>; ∃-syntax)open import Data.List.Base using (List; []; _∷_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Construct.Composition using (_;_)privatevariablea b c ℓ : LevelA B : Set ax y : Axs ys : List AR S : REL A B ℓ-------------------------------------------------------------------------- Definition------------------------------------------------------------------------infixr 5 _∷_data Pointwise {A : Set a} {B : Set b} (R : REL A B ℓ): List A → List B → Set (a ⊔ b ⊔ ℓ) where[] : Pointwise R [] []_∷_ : (x∼y : R x y) (xs∼ys : Pointwise R xs ys) →Pointwise R (x ∷ xs) (y ∷ ys)-------------------------------------------------------------------------- Operations------------------------------------------------------------------------head : Pointwise R (x ∷ xs) (y ∷ ys) → R x yhead (x∼y ∷ xs∼ys) = x∼ytail : Pointwise R (x ∷ xs) (y ∷ ys) → Pointwise R xs ystail (x∼y ∷ xs∼ys) = xs∼ysuncons : Pointwise R (x ∷ xs) (y ∷ ys) → R x y × Pointwise R xs ysuncons = < head , tail >rec : ∀ (P : ∀ {xs ys} → Pointwise R xs ys → Set c) →(∀ {x y xs ys} {Rxsys : Pointwise R xs ys} →(Rxy : R x y) → P Rxsys → P (Rxy ∷ Rxsys)) →P [] →∀ {xs ys} (Rxsys : Pointwise R xs ys) → P Rxsysrec P c n [] = nrec P c n (Rxy ∷ Rxsys) = c Rxy (rec P c n Rxsys)map : R ⇒ S → Pointwise R ⇒ Pointwise Smap R⇒S [] = []map R⇒S (Rxy ∷ Rxsys) = R⇒S Rxy ∷ map R⇒S Rxsysunzip : Pointwise (R ; S) ⇒ (Pointwise R ; Pointwise S)unzip [] = [] , [] , []unzip ((y , r , s) ∷ xs∼ys) =Product.map (y ∷_) (Product.map (r ∷_) (s ∷_)) (unzip xs∼ys)
-------------------------------------------------------------------------- The Agda standard library---- A definition for the permutation relation using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Function.Base using (_∘′_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.Reasoning.Syntaxmodule Data.List.Relation.Binary.Permutation.Setoid{a ℓ} (S : Setoid a ℓ) whereopen import Data.List.Base using (List; _∷_)import Data.List.Relation.Binary.Permutation.Homogeneous as Homogeneousimport Data.List.Relation.Binary.Pointwise.Properties as Pointwise using (refl)open import Data.List.Relation.Binary.Equality.Setoid Sopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Level using (_⊔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatemodule Eq = Setoid Sopen Eq using (_≈_) renaming (Carrier to A)-------------------------------------------------------------------------- Definitionopen Homogeneous publicusing (refl; prep; swap; trans)infix 3 _↭__↭_ : Rel (List A) (a ⊔ ℓ)_↭_ = Homogeneous.Permutation _≈_-------------------------------------------------------------------------- Constructor aliases-- These provide aliases for `swap` and `prep` when the elements being-- swapped or prepended are propositionally equal↭-prep : ∀ x {xs ys} → xs ↭ ys → x ∷ xs ↭ x ∷ ys↭-prep x xs↭ys = prep Eq.refl xs↭ys↭-swap : ∀ x y {xs ys} → xs ↭ ys → x ∷ y ∷ xs ↭ y ∷ x ∷ ys↭-swap x y xs↭ys = swap Eq.refl Eq.refl xs↭ys-------------------------------------------------------------------------- Functions over permutationssteps : ∀ {xs ys} → xs ↭ ys → ℕsteps (refl _) = 1steps (prep _ xs↭ys) = suc (steps xs↭ys)steps (swap _ _ xs↭ys) = suc (steps xs↭ys)steps (trans xs↭ys ys↭zs) = steps xs↭ys + steps ys↭zs-------------------------------------------------------------------------- _↭_ is an equivalence↭-reflexive : _≡_ ⇒ _↭_↭-reflexive refl = refl (Pointwise.refl Eq.refl)↭-refl : Reflexive _↭_↭-refl = ↭-reflexive refl↭-sym : Symmetric _↭_↭-sym = Homogeneous.sym Eq.sym↭-trans : Transitive _↭_↭-trans = trans↭-isEquivalence : IsEquivalence _↭_↭-isEquivalence = Homogeneous.isEquivalence Eq.refl Eq.sym↭-setoid : Setoid _ _↭-setoid = Homogeneous.setoid {R = _≈_} Eq.refl Eq.sym-------------------------------------------------------------------------- A reasoning API to chain permutation proofsmodule PermutationReasoning whereprivate module Base = ≈-Reasoning ↭-setoidopen Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)renaming (≈-go to ↭-go)open ↭-syntax _IsRelatedTo_ _IsRelatedTo_ ↭-go ↭-sym publicopen ≋-syntax _IsRelatedTo_ _IsRelatedTo_ (↭-go ∘′ refl) ≋-sym public-- Some extra combinators that allow us to skip certain elementsinfixr 2 step-swap step-prep-- Skip reasoning on the first elementstep-prep : ∀ x xs {ys zs : List A} → (x ∷ ys) IsRelatedTo zs →xs ↭ ys → (x ∷ xs) IsRelatedTo zsstep-prep x xs rel xs↭ys = relTo (trans (prep Eq.refl xs↭ys) (begin rel))-- Skip reasoning about the first two elementsstep-swap : ∀ x y xs {ys zs : List A} → (y ∷ x ∷ ys) IsRelatedTo zs →xs ↭ ys → (x ∷ y ∷ xs) IsRelatedTo zsstep-swap x y xs rel xs↭ys = relTo (trans (swap Eq.refl Eq.refl xs↭ys) (begin rel))syntax step-prep x xs y↭z x↭y = x ∷ xs <⟨ x↭y ⟩ y↭zsyntax step-swap x y xs y↭z x↭y = x ∷ y ∷ xs <<⟨ x↭y ⟩ y↭z
-------------------------------------------------------------------------- The Agda standard library---- Properties of permutations using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coreusing (Rel; _⇒_; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions as B hiding (Decidable)module Data.List.Relation.Binary.Permutation.Setoid.Properties{a ℓ} (S : Setoid a ℓ)whereopen import Algebraimport Algebra.Properties.CommutativeMonoid as ACMopen import Data.Bool.Base using (true; false)open import Data.List.Base as List hiding (head; tail)open import Data.List.Relation.Binary.Pointwise as Pointwiseusing (Pointwise; head; tail)import Data.List.Relation.Binary.Equality.Setoid as Equalityimport Data.List.Relation.Binary.Permutation.Setoid as Permutationopen import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Relation.Unary.All as All using (All; []; _∷_)open import Data.List.Relation.Unary.AllPairs using (AllPairs; []; _∷_)import Data.List.Relation.Unary.Unique.Setoid as Uniqueimport Data.List.Membership.Setoid as Membershipopen import Data.List.Membership.Setoid.Properties using (∈-∃++; ∈-insert)import Data.List.Properties as Lₚopen import Data.Nat.Base using (ℕ; suc; _<_; z<s; _+_)open import Data.Nat.Inductionopen import Data.Nat.Propertiesopen import Data.Product.Base using (_,_; _×_; ∃; ∃₂; proj₁; proj₂)open import Function.Base using (_∘_; _⟨_⟩_; flip)open import Level using (Level; _⊔_)open import Relation.Unary using (Pred; Decidable)import Relation.Binary.Reasoning.Setoid as RelSetoidopen import Relation.Binary.Properties.Setoid S using (≉-resp₂)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_ ; refl; sym; cong; cong₂; subst; _≢_)open import Relation.Nullary.Decidable using (yes; no; does)open import Relation.Nullary.Negation using (contradiction)privatevariableb p r : Levelopen Setoid S using (_≈_) renaming (Carrier to A; refl to ≈-refl; sym to ≈-sym; trans to ≈-trans)open Permutation Sopen Membership Sopen Unique S using (Unique)open module ≋ = Equality Susing (_≋_; []; _∷_; ≋-refl; ≋-sym; ≋-trans; All-resp-≋; Any-resp-≋; AllPairs-resp-≋)open PermutationReasoning-------------------------------------------------------------------------- Relationships to other predicates------------------------------------------------------------------------All-resp-↭ : ∀ {P : Pred A p} → P Respects _≈_ → (All P) Respects _↭_All-resp-↭ resp (refl xs≋ys) pxs = All-resp-≋ resp xs≋ys pxsAll-resp-↭ resp (prep x≈y p) (px ∷ pxs) = resp x≈y px ∷ All-resp-↭ resp p pxsAll-resp-↭ resp (swap ≈₁ ≈₂ p) (px ∷ py ∷ pxs) = resp ≈₂ py ∷ resp ≈₁ px ∷ All-resp-↭ resp p pxsAll-resp-↭ resp (trans p₁ p₂) pxs = All-resp-↭ resp p₂ (All-resp-↭ resp p₁ pxs)Any-resp-↭ : ∀ {P : Pred A p} → P Respects _≈_ → (Any P) Respects _↭_Any-resp-↭ resp (refl xs≋ys) pxs = Any-resp-≋ resp xs≋ys pxsAny-resp-↭ resp (prep x≈y p) (here px) = here (resp x≈y px)Any-resp-↭ resp (prep x≈y p) (there pxs) = there (Any-resp-↭ resp p pxs)Any-resp-↭ resp (swap x y p) (here px) = there (here (resp x px))Any-resp-↭ resp (swap x y p) (there (here px)) = here (resp y px)Any-resp-↭ resp (swap x y p) (there (there pxs)) = there (there (Any-resp-↭ resp p pxs))Any-resp-↭ resp (trans p₁ p₂) pxs = Any-resp-↭ resp p₂ (Any-resp-↭ resp p₁ pxs)AllPairs-resp-↭ : ∀ {R : Rel A r} → Symmetric R → R Respects₂ _≈_ → (AllPairs R) Respects _↭_AllPairs-resp-↭ sym resp (refl xs≋ys) pxs = AllPairs-resp-≋ resp xs≋ys pxsAllPairs-resp-↭ sym resp (prep x≈y p) (∼ ∷ pxs) =All-resp-↭ (proj₁ resp) p (All.map (proj₂ resp x≈y) ∼) ∷AllPairs-resp-↭ sym resp p pxsAllPairs-resp-↭ sym resp@(rʳ , rˡ) (swap eq₁ eq₂ p) ((∼₁ ∷ ∼₂) ∷ ∼₃ ∷ pxs) =(sym (rʳ eq₂ (rˡ eq₁ ∼₁)) ∷ All-resp-↭ rʳ p (All.map (rˡ eq₂) ∼₃)) ∷All-resp-↭ rʳ p (All.map (rˡ eq₁) ∼₂) ∷AllPairs-resp-↭ sym resp p pxsAllPairs-resp-↭ sym resp (trans p₁ p₂) pxs =AllPairs-resp-↭ sym resp p₂ (AllPairs-resp-↭ sym resp p₁ pxs)∈-resp-↭ : ∀ {x} → (x ∈_) Respects _↭_∈-resp-↭ = Any-resp-↭ (flip ≈-trans)Unique-resp-↭ : Unique Respects _↭_Unique-resp-↭ = AllPairs-resp-↭ (_∘ ≈-sym) ≉-resp₂-------------------------------------------------------------------------- Relationships to other relations------------------------------------------------------------------------≋⇒↭ : _≋_ ⇒ _↭_≋⇒↭ = refl↭-respʳ-≋ : _↭_ Respectsʳ _≋_↭-respʳ-≋ xs≋ys (refl zs≋xs) = refl (≋-trans zs≋xs xs≋ys)↭-respʳ-≋ (x≈y ∷ xs≋ys) (prep eq zs↭xs) = prep (≈-trans eq x≈y) (↭-respʳ-≋ xs≋ys zs↭xs)↭-respʳ-≋ (x≈y ∷ w≈z ∷ xs≋ys) (swap eq₁ eq₂ zs↭xs) = swap (≈-trans eq₁ w≈z) (≈-trans eq₂ x≈y) (↭-respʳ-≋ xs≋ys zs↭xs)↭-respʳ-≋ xs≋ys (trans ws↭zs zs↭xs) = trans ws↭zs (↭-respʳ-≋ xs≋ys zs↭xs)↭-respˡ-≋ : _↭_ Respectsˡ _≋_↭-respˡ-≋ xs≋ys (refl ys≋zs) = refl (≋-trans (≋-sym xs≋ys) ys≋zs)↭-respˡ-≋ (x≈y ∷ xs≋ys) (prep eq zs↭xs) = prep (≈-trans (≈-sym x≈y) eq) (↭-respˡ-≋ xs≋ys zs↭xs)↭-respˡ-≋ (x≈y ∷ w≈z ∷ xs≋ys) (swap eq₁ eq₂ zs↭xs) = swap (≈-trans (≈-sym x≈y) eq₁) (≈-trans (≈-sym w≈z) eq₂) (↭-respˡ-≋ xs≋ys zs↭xs)↭-respˡ-≋ xs≋ys (trans ws↭zs zs↭xs) = trans (↭-respˡ-≋ xs≋ys ws↭zs) zs↭xs-------------------------------------------------------------------------- Properties of steps------------------------------------------------------------------------0<steps : ∀ {xs ys} (xs↭ys : xs ↭ ys) → 0 < steps xs↭ys0<steps (refl _) = z<s0<steps (prep eq xs↭ys) = m<n⇒m<1+n (0<steps xs↭ys)0<steps (swap eq₁ eq₂ xs↭ys) = m<n⇒m<1+n (0<steps xs↭ys)0<steps (trans xs↭ys xs↭ys₁) =<-≤-trans (0<steps xs↭ys) (m≤m+n (steps xs↭ys) (steps xs↭ys₁))steps-respˡ : ∀ {xs ys zs} (ys≋xs : ys ≋ xs) (ys↭zs : ys ↭ zs) →steps (↭-respˡ-≋ ys≋xs ys↭zs) ≡ steps ys↭zssteps-respˡ _ (refl _) = reflsteps-respˡ (_ ∷ ys≋xs) (prep _ ys↭zs) = cong suc (steps-respˡ ys≋xs ys↭zs)steps-respˡ (_ ∷ _ ∷ ys≋xs) (swap _ _ ys↭zs) = cong suc (steps-respˡ ys≋xs ys↭zs)steps-respˡ ys≋xs (trans ys↭ws ws↭zs) = cong (_+ steps ws↭zs) (steps-respˡ ys≋xs ys↭ws)steps-respʳ : ∀ {xs ys zs} (xs≋ys : xs ≋ ys) (zs↭xs : zs ↭ xs) →steps (↭-respʳ-≋ xs≋ys zs↭xs) ≡ steps zs↭xssteps-respʳ _ (refl _) = reflsteps-respʳ (_ ∷ ys≋xs) (prep _ ys↭zs) = cong suc (steps-respʳ ys≋xs ys↭zs)steps-respʳ (_ ∷ _ ∷ ys≋xs) (swap _ _ ys↭zs) = cong suc (steps-respʳ ys≋xs ys↭zs)steps-respʳ ys≋xs (trans ys↭ws ws↭zs) = cong (steps ys↭ws +_) (steps-respʳ ys≋xs ws↭zs)-------------------------------------------------------------------------- Properties of list functions-------------------------------------------------------------------------------------------------------------------------------------------------- mapmodule _ {ℓ} (T : Setoid b ℓ) whereopen Setoid T using () renaming (_≈_ to _≈′_)open Permutation T using () renaming (_↭_ to _↭′_)map⁺ : ∀ {f} → f Preserves _≈_ ⟶ _≈′_ →∀ {xs ys} → xs ↭ ys → map f xs ↭′ map f ysmap⁺ pres (refl xs≋ys) = refl (Pointwise.map⁺ _ _ (Pointwise.map pres xs≋ys))map⁺ pres (prep x p) = prep (pres x) (map⁺ pres p)map⁺ pres (swap x y p) = swap (pres x) (pres y) (map⁺ pres p)map⁺ pres (trans p₁ p₂) = trans (map⁺ pres p₁) (map⁺ pres p₂)-------------------------------------------------------------------------- _++_shift : ∀ {v w} → v ≈ w → (xs ys : List A) → xs ++ [ v ] ++ ys ↭ w ∷ xs ++ ysshift {v} {w} v≈w [] ys = prep v≈w ↭-reflshift {v} {w} v≈w (x ∷ xs) ys = beginx ∷ (xs ++ [ v ] ++ ys) <⟨ shift v≈w xs ys ⟩x ∷ w ∷ xs ++ ys <<⟨ ↭-refl ⟩w ∷ x ∷ xs ++ ys ∎↭-shift : ∀ {v} (xs ys : List A) → xs ++ [ v ] ++ ys ↭ v ∷ xs ++ ys↭-shift = shift ≈-refl++⁺ˡ : ∀ xs {ys zs : List A} → ys ↭ zs → xs ++ ys ↭ xs ++ zs++⁺ˡ [] ys↭zs = ys↭zs++⁺ˡ (x ∷ xs) ys↭zs = ↭-prep _ (++⁺ˡ xs ys↭zs)++⁺ʳ : ∀ {xs ys : List A} zs → xs ↭ ys → xs ++ zs ↭ ys ++ zs++⁺ʳ zs (refl xs≋ys) = refl (Pointwise.++⁺ xs≋ys ≋-refl)++⁺ʳ zs (prep x ↭) = prep x (++⁺ʳ zs ↭)++⁺ʳ zs (swap x y ↭) = swap x y (++⁺ʳ zs ↭)++⁺ʳ zs (trans ↭₁ ↭₂) = trans (++⁺ʳ zs ↭₁) (++⁺ʳ zs ↭₂)++⁺ : _++_ Preserves₂ _↭_ ⟶ _↭_ ⟶ _↭_++⁺ ws↭xs ys↭zs = trans (++⁺ʳ _ ws↭xs) (++⁺ˡ _ ys↭zs)-- Algebraic properties++-identityˡ : LeftIdentity _↭_ [] _++_++-identityˡ xs = ↭-refl++-identityʳ : RightIdentity _↭_ [] _++_++-identityʳ xs = ↭-reflexive (Lₚ.++-identityʳ xs)++-identity : Identity _↭_ [] _++_++-identity = ++-identityˡ , ++-identityʳ++-assoc : Associative _↭_ _++_++-assoc xs ys zs = ↭-reflexive (Lₚ.++-assoc xs ys zs)++-comm : Commutative _↭_ _++_++-comm [] ys = ↭-sym (++-identityʳ ys)++-comm (x ∷ xs) ys = beginx ∷ xs ++ ys <⟨ ++-comm xs ys ⟩x ∷ ys ++ xs ↭⟨ ↭-shift ys xs ⟨ys ++ (x ∷ xs) ∎-- Structures++-isMagma : IsMagma _↭_ _++_++-isMagma = record{ isEquivalence = ↭-isEquivalence; ∙-cong = ++⁺}++-isSemigroup : IsSemigroup _↭_ _++_++-isSemigroup = record{ isMagma = ++-isMagma; assoc = ++-assoc}++-isMonoid : IsMonoid _↭_ _++_ []++-isMonoid = record{ isSemigroup = ++-isSemigroup; identity = ++-identity}++-isCommutativeMonoid : IsCommutativeMonoid _↭_ _++_ []++-isCommutativeMonoid = record{ isMonoid = ++-isMonoid; comm = ++-comm}-- Bundles++-magma : Magma a (a ⊔ ℓ)++-magma = record{ isMagma = ++-isMagma}++-semigroup : Semigroup a (a ⊔ ℓ)++-semigroup = record{ isSemigroup = ++-isSemigroup}++-monoid : Monoid a (a ⊔ ℓ)++-monoid = record{ isMonoid = ++-isMonoid}++-commutativeMonoid : CommutativeMonoid a (a ⊔ ℓ)++-commutativeMonoid = record{ isCommutativeMonoid = ++-isCommutativeMonoid}-- Some other useful lemmaszoom : ∀ h {t xs ys : List A} → xs ↭ ys → h ++ xs ++ t ↭ h ++ ys ++ tzoom h {t} = ++⁺ˡ h ∘ ++⁺ʳ tinject : ∀ (v : A) {ws xs ys zs} → ws ↭ ys → xs ↭ zs →ws ++ [ v ] ++ xs ↭ ys ++ [ v ] ++ zsinject v ws↭ys xs↭zs = trans (++⁺ˡ _ (↭-prep _ xs↭zs)) (++⁺ʳ _ ws↭ys)shifts : ∀ xs ys {zs : List A} → xs ++ ys ++ zs ↭ ys ++ xs ++ zsshifts xs ys {zs} = beginxs ++ ys ++ zs ↭⟨ ++-assoc xs ys zs ⟨(xs ++ ys) ++ zs ↭⟨ ++⁺ʳ zs (++-comm xs ys) ⟩(ys ++ xs) ++ zs ↭⟨ ++-assoc ys xs zs ⟩ys ++ xs ++ zs ∎dropMiddleElement-≋ : ∀ {x} ws xs {ys} {zs} →ws ++ [ x ] ++ ys ≋ xs ++ [ x ] ++ zs →ws ++ ys ↭ xs ++ zsdropMiddleElement-≋ [] [] (_ ∷ eq) = ≋⇒↭ eqdropMiddleElement-≋ [] (x ∷ xs) (w≈v ∷ eq) = ↭-respˡ-≋ (≋-sym eq) (shift w≈v xs _)dropMiddleElement-≋ (w ∷ ws) [] (w≈x ∷ eq) = ↭-respʳ-≋ eq (↭-sym (shift (≈-sym w≈x) ws _))dropMiddleElement-≋ (w ∷ ws) (x ∷ xs) (w≈x ∷ eq) = prep w≈x (dropMiddleElement-≋ ws xs eq)dropMiddleElement : ∀ {v} ws xs {ys zs} →ws ++ [ v ] ++ ys ↭ xs ++ [ v ] ++ zs →ws ++ ys ↭ xs ++ zsdropMiddleElement {v} ws xs {ys} {zs} p = helper p ws xs ≋-refl ≋-reflwherelemma : ∀ {w x y z} → w ≈ x → x ≈ y → z ≈ y → w ≈ zlemma w≈x x≈y z≈y = ≈-trans (≈-trans w≈x x≈y) (≈-sym z≈y)open PermutationReasoning-- The l′ & l″ could be eliminated at the cost of making the `trans` case-- much more difficult to prove. At the very least would require using `Acc`.helper : ∀ {l′ l″ : List A} → l′ ↭ l″ →∀ ws xs {ys zs : List A} →ws ++ [ v ] ++ ys ≋ l′ →xs ++ [ v ] ++ zs ≋ l″ →ws ++ ys ↭ xs ++ zshelper {as} {bs} (refl eq3) ws xs {ys} {zs} eq1 eq2 =dropMiddleElement-≋ ws xs (≋-trans (≋-trans eq1 eq3) (≋-sym eq2))helper {_ ∷ as} {_ ∷ bs} (prep _ as↭bs) [] [] {ys} {zs} (_ ∷ ys≋as) (_ ∷ zs≋bs) = beginys ≋⟨ ys≋as ⟩as ↭⟨ as↭bs ⟩bs ≋⟨ zs≋bs ⟨zs ∎helper {_ ∷ as} {_ ∷ bs} (prep a≈b as↭bs) [] (x ∷ xs) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginys ≋⟨ ≋₁ ⟩as ↭⟨ as↭bs ⟩bs ≋⟨ ≋₂ ⟨xs ++ v ∷ zs ↭⟨ shift (lemma ≈₁ a≈b ≈₂) xs zs ⟩x ∷ xs ++ zs ∎helper {_ ∷ as} {_ ∷ bs} (prep v≈w p) (w ∷ ws) [] {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginw ∷ ws ++ ys ↭⟨ ↭-sym (shift (lemma ≈₂ (≈-sym v≈w) ≈₁) ws ys) ⟩ws ++ v ∷ ys ≋⟨ ≋₁ ⟩as ↭⟨ p ⟩bs ≋⟨ ≋₂ ⟨zs ∎helper {_ ∷ as} {_ ∷ bs} (prep w≈x p) (w ∷ ws) (x ∷ xs) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginw ∷ ws ++ ys ↭⟨ prep (lemma ≈₁ w≈x ≈₂) (helper p ws xs ≋₁ ≋₂) ⟩x ∷ xs ++ zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap v≈x y≈v p) [] [] {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginys ≋⟨ ≋₁ ⟩a ∷ as ↭⟨ prep (≈-trans (≈-trans (≈-trans y≈v (≈-sym ≈₂)) ≈₁) v≈x) p ⟩b ∷ bs ≋⟨ ≋₂ ⟨zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap v≈w y≈w p) [] (x ∷ []) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginys ≋⟨ ≋₁ ⟩a ∷ as ↭⟨ prep y≈w p ⟩_ ∷ bs ≋⟨ ≈₂ ∷ tail ≋₂ ⟨x ∷ zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap v≈w y≈x p) [] (x ∷ w ∷ xs) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginys ≋⟨ ≋₁ ⟩a ∷ as ↭⟨ prep y≈x p ⟩_ ∷ bs ≋⟨ ≋-sym (≈₂ ∷ tail ≋₂) ⟩x ∷ xs ++ v ∷ zs ↭⟨ prep ≈-refl (shift (lemma ≈₁ v≈w (head ≋₂)) xs zs) ⟩x ∷ w ∷ xs ++ zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap w≈x _ p) (w ∷ []) [] {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginw ∷ ys ≋⟨ ≈₁ ∷ tail (≋₁) ⟩_ ∷ as ↭⟨ prep w≈x p ⟩b ∷ bs ≋⟨ ≋-sym ≋₂ ⟩zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap w≈y x≈v p) (w ∷ x ∷ ws) [] {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginw ∷ x ∷ ws ++ ys ↭⟨ prep ≈-refl (↭-sym (shift (lemma ≈₂ (≈-sym x≈v) (head ≋₁)) ws ys)) ⟩w ∷ ws ++ v ∷ ys ≋⟨ ≈₁ ∷ tail ≋₁ ⟩_ ∷ as ↭⟨ prep w≈y p ⟩b ∷ bs ≋⟨ ≋-sym ≋₂ ⟩zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap x≈v v≈y p) (x ∷ []) (y ∷ []) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginx ∷ ys ≋⟨ ≈₁ ∷ tail ≋₁ ⟩_ ∷ as ↭⟨ prep (≈-trans x≈v (≈-trans (≈-sym (head ≋₂)) (≈-trans (head ≋₁) v≈y))) p ⟩_ ∷ bs ≋⟨ ≋-sym (≈₂ ∷ tail ≋₂) ⟩y ∷ zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap y≈w v≈z p) (y ∷ []) (z ∷ w ∷ xs) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginy ∷ ys ≋⟨ ≈₁ ∷ tail ≋₁ ⟩_ ∷ as ↭⟨ prep y≈w p ⟩_ ∷ bs ≋⟨ ≋-sym ≋₂ ⟩w ∷ xs ++ v ∷ zs ↭⟨ ↭-prep w (↭-shift xs zs) ⟩w ∷ v ∷ xs ++ zs ↭⟨ swap ≈-refl (lemma (head ≋₁) v≈z ≈₂) ↭-refl ⟩z ∷ w ∷ xs ++ zs ∎helper {_ ∷ a ∷ as} {_ ∷ b ∷ bs} (swap y≈v w≈z p) (y ∷ w ∷ ws) (z ∷ []) {ys} {zs} (≈₁ ∷ ≋₁) (≈₂ ∷ ≋₂) = beginy ∷ w ∷ ws ++ ys ↭⟨ swap (lemma ≈₁ y≈v (head ≋₂)) ≈-refl ↭-refl ⟩w ∷ v ∷ ws ++ ys ↭⟨ ↭-prep w (↭-sym (↭-shift ws ys)) ⟩w ∷ ws ++ v ∷ ys ≋⟨ ≋₁ ⟩_ ∷ as ↭⟨ prep w≈z p ⟩_ ∷ bs ≋⟨ ≋-sym (≈₂ ∷ tail ≋₂) ⟩z ∷ zs ∎helper (swap x≈z y≈w p) (x ∷ y ∷ ws) (w ∷ z ∷ xs) {ys} {zs} (≈₁ ∷ ≈₃ ∷ ≋₁) (≈₂ ∷ ≈₄ ∷ ≋₂) = beginx ∷ y ∷ ws ++ ys ↭⟨ swap (lemma ≈₁ x≈z ≈₄) (lemma ≈₃ y≈w ≈₂) (helper p ws xs ≋₁ ≋₂) ⟩w ∷ z ∷ xs ++ zs ∎helper {as} {bs} (trans p₁ p₂) ws xs eq1 eq2with ∈-∃++ S (∈-resp-↭ (↭-respˡ-≋ (≋-sym eq1) p₁) (∈-insert S ws ≈-refl))... | (h , t , w , v≈w , eq) = trans(helper p₁ ws h eq1 (≋-trans (≋.++⁺ ≋-refl (v≈w ∷ ≋-refl)) (≋-sym eq)))(helper p₂ h xs (≋-trans (≋.++⁺ ≋-refl (v≈w ∷ ≋-refl)) (≋-sym eq)) eq2)dropMiddle : ∀ {vs} ws xs {ys zs} →ws ++ vs ++ ys ↭ xs ++ vs ++ zs →ws ++ ys ↭ xs ++ zsdropMiddle {[]} ws xs p = pdropMiddle {v ∷ vs} ws xs p = dropMiddle ws xs (dropMiddleElement ws xs p)split : ∀ (v : A) as bs {xs} → xs ↭ as ++ [ v ] ++ bs → ∃₂ λ ps qs → xs ≋ ps ++ [ v ] ++ qssplit v as bs p = helper as bs p (<-wellFounded (steps p))wherehelper : ∀ as bs {xs} (p : xs ↭ as ++ [ v ] ++ bs) → Acc _<_ (steps p) →∃₂ λ ps qs → xs ≋ ps ++ [ v ] ++ qshelper [] bs (refl eq) _ = [] , bs , eqhelper (a ∷ []) bs (refl eq) _ = [ a ] , bs , eqhelper (a ∷ b ∷ as) bs (refl eq) _ = a ∷ b ∷ as , bs , eqhelper [] bs (prep v≈x _) _ = [] , _ , v≈x ∷ ≋-reflhelper (a ∷ as) bs (prep eq as↭xs) (acc rec) with helper as bs as↭xs (rec ≤-refl)... | (ps , qs , eq₂) = a ∷ ps , qs , eq ∷ eq₂helper [] (b ∷ bs) (swap x≈b y≈v _) _ = [ b ] , _ , x≈b ∷ y≈v ∷ ≋-reflhelper (a ∷ []) bs (swap x≈v y≈a ↭) _ = [] , a ∷ _ , x≈v ∷ y≈a ∷ ≋-reflhelper (a ∷ b ∷ as) bs (swap x≈b y≈a as↭xs) (acc rec) with helper as bs as↭xs (rec ≤-refl)... | (ps , qs , eq) = b ∷ a ∷ ps , qs , x≈b ∷ y≈a ∷ eqhelper as bs (trans ↭₁ ↭₂) (acc rec) with helper as bs ↭₂ (rec (m<n+m (steps ↭₂) (0<steps ↭₁)))... | (ps , qs , eq) = helper ps qs (↭-respʳ-≋ eq ↭₁)(rec (subst (_< _) (sym (steps-respʳ eq ↭₁)) (m<m+n (steps ↭₁) (0<steps ↭₂))))-------------------------------------------------------------------------- filtermodule _ {p} {P : Pred A p} (P? : Decidable P) (P≈ : P Respects _≈_) wherefilter⁺ : ∀ {xs ys : List A} → xs ↭ ys → filter P? xs ↭ filter P? ysfilter⁺ (refl xs≋ys) = refl (≋.filter⁺ P? P≈ xs≋ys)filter⁺ (trans xs↭zs zs↭ys) = trans (filter⁺ xs↭zs) (filter⁺ zs↭ys)filter⁺ {x ∷ xs} {y ∷ ys} (prep x≈y xs↭ys) with P? x | P? y... | yes _ | yes _ = prep x≈y (filter⁺ xs↭ys)... | yes Px | no ¬Py = contradiction (P≈ x≈y Px) ¬Py... | no ¬Px | yes Py = contradiction (P≈ (≈-sym x≈y) Py) ¬Px... | no _ | no _ = filter⁺ xs↭ysfilter⁺ {x ∷ w ∷ xs} {y ∷ z ∷ ys} (swap x≈z w≈y xs↭ys) with P? x | P? yfilter⁺ {x ∷ w ∷ xs} {y ∷ z ∷ ys} (swap x≈z w≈y xs↭ys) | no ¬Px | no ¬Pywith P? z | P? w... | _ | yes Pw = contradiction (P≈ w≈y Pw) ¬Py... | yes Pz | _ = contradiction (P≈ (≈-sym x≈z) Pz) ¬Px... | no _ | no _ = filter⁺ xs↭ysfilter⁺ {x ∷ w ∷ xs} {y ∷ z ∷ ys} (swap x≈z w≈y xs↭ys) | no ¬Px | yes Pywith P? z | P? w... | _ | no ¬Pw = contradiction (P≈ (≈-sym w≈y) Py) ¬Pw... | yes Pz | _ = contradiction (P≈ (≈-sym x≈z) Pz) ¬Px... | no _ | yes _ = prep w≈y (filter⁺ xs↭ys)filter⁺ {x ∷ w ∷ xs} {y ∷ z ∷ ys} (swap x≈z w≈y xs↭ys) | yes Px | no ¬Pywith P? z | P? w... | no ¬Pz | _ = contradiction (P≈ x≈z Px) ¬Pz... | _ | yes Pw = contradiction (P≈ w≈y Pw) ¬Py... | yes _ | no _ = prep x≈z (filter⁺ xs↭ys)filter⁺ {x ∷ w ∷ xs} {y ∷ z ∷ ys} (swap x≈z w≈y xs↭ys) | yes Px | yes Pywith P? z | P? w... | no ¬Pz | _ = contradiction (P≈ x≈z Px) ¬Pz... | _ | no ¬Pw = contradiction (P≈ (≈-sym w≈y) Py) ¬Pw... | yes _ | yes _ = swap x≈z w≈y (filter⁺ xs↭ys)-------------------------------------------------------------------------- partitionmodule _ {p} {P : Pred A p} (P? : Decidable P) wherepartition-↭ : ∀ xs → (let ys , zs = partition P? xs) → xs ↭ ys ++ zspartition-↭ [] = ↭-reflpartition-↭ (x ∷ xs) with does (P? x)... | true = ↭-prep x (partition-↭ xs)... | false = ↭-trans (↭-prep x (partition-↭ xs)) (↭-sym (↭-shift _ _))where open PermutationReasoning-------------------------------------------------------------------------- mergemodule _ {ℓ} {R : Rel A ℓ} (R? : B.Decidable R) wheremerge-↭ : ∀ xs ys → merge R? xs ys ↭ xs ++ ysmerge-↭ [] [] = ↭-reflmerge-↭ [] (y ∷ ys) = ↭-reflmerge-↭ (x ∷ xs) [] = ↭-sym (++-identityʳ (x ∷ xs))merge-↭ (x ∷ xs) (y ∷ ys)with does (R? x y) | merge-↭ xs (y ∷ ys) | merge-↭ (x ∷ xs) ys... | true | rec | _ = ↭-prep x rec... | false | _ | rec = beginy ∷ merge R? (x ∷ xs) ys <⟨ rec ⟩y ∷ x ∷ xs ++ ys ↭⟨ ↭-shift (x ∷ xs) ys ⟨(x ∷ xs) ++ y ∷ ys ≡⟨ Lₚ.++-assoc [ x ] xs (y ∷ ys) ⟨x ∷ xs ++ y ∷ ys ∎where open PermutationReasoning-------------------------------------------------------------------------- _∷ʳ_∷↭∷ʳ : ∀ (x : A) xs → x ∷ xs ↭ xs ∷ʳ x∷↭∷ʳ x xs = ↭-sym (beginxs ++ [ x ] ↭⟨ ↭-shift xs [] ⟩x ∷ xs ++ [] ≡⟨ Lₚ.++-identityʳ _ ⟩x ∷ xs ∎)where open PermutationReasoning-------------------------------------------------------------------------- ʳ++++↭ʳ++ : ∀ (xs ys : List A) → xs ++ ys ↭ xs ʳ++ ys++↭ʳ++ [] ys = ↭-refl++↭ʳ++ (x ∷ xs) ys = ↭-trans (↭-sym (↭-shift xs ys)) (++↭ʳ++ xs (x ∷ ys))-------------------------------------------------------------------------- foldr of Commutative Monoidmodule _ {_∙_ : Op₂ A} {ε : A} (isCmonoid : IsCommutativeMonoid _≈_ _∙_ ε) whereopen module CM = IsCommutativeMonoid isCmonoidprivatemodule S = RelSetoid setoidcmonoid : CommutativeMonoid _ _cmonoid = record { isCommutativeMonoid = isCmonoid }open ACM cmonoidfoldr-commMonoid : ∀ {xs ys} → xs ↭ ys → foldr _∙_ ε xs ≈ foldr _∙_ ε ysfoldr-commMonoid (refl []) = CM.reflfoldr-commMonoid (refl (x≈y ∷ xs≈ys)) = ∙-cong x≈y (foldr-commMonoid (Permutation.refl xs≈ys))foldr-commMonoid (prep x≈y xs↭ys) = ∙-cong x≈y (foldr-commMonoid xs↭ys)foldr-commMonoid (swap {xs} {ys} {x} {y} {x′} {y′} x≈x′ y≈y′ xs↭ys) = S.beginx ∙ (y ∙ foldr _∙_ ε xs) S.≈⟨ ∙-congˡ (∙-congˡ (foldr-commMonoid xs↭ys)) ⟩x ∙ (y ∙ foldr _∙_ ε ys) S.≈⟨ assoc x y (foldr _∙_ ε ys) ⟨(x ∙ y) ∙ foldr _∙_ ε ys S.≈⟨ ∙-congʳ (comm x y) ⟩(y ∙ x) ∙ foldr _∙_ ε ys S.≈⟨ ∙-congʳ (∙-cong y≈y′ x≈x′) ⟩(y′ ∙ x′) ∙ foldr _∙_ ε ys S.≈⟨ assoc y′ x′ (foldr _∙_ ε ys) ⟩y′ ∙ (x′ ∙ foldr _∙_ ε ys) S.∎foldr-commMonoid (trans xs↭ys ys↭zs) = CM.trans (foldr-commMonoid xs↭ys) (foldr-commMonoid ys↭zs)
-------------------------------------------------------------------------- The Agda standard library---- Properties of permutations using setoid equality (on Maybe elements)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Permutation.Setoid.Properties.Maybe whereopen import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundles using (Setoid)open import Level using (Level)open import Function.Base using (_∘_; _$_)open import Data.List.Base using (catMaybes; mapMaybe)open import Data.List.Relation.Binary.Pointwise using (Pointwise; []; _∷_)import Data.List.Relation.Binary.Permutation.Setoid as Permutationopen import Data.List.Relation.Binary.Permutation.Setoid.Propertiesopen import Data.Maybe using (Maybe; nothing; just)open import Data.Maybe.Relation.Binary.Pointwise using (nothing; just)renaming (setoid to setoidᴹ)privatevariablea b ℓ ℓ′ : Level-------------------------------------------------------------------------- catMaybesmodule _ (sᴬ : Setoid a ℓ) whereopen Setoid sᴬ using (_≈_)open Permutation sᴬprivate sᴹ = setoidᴹ sᴬopen Setoid sᴹ using () renaming (_≈_ to _≈ᴹ_)open Permutation sᴹ using () renaming (_↭_ to _↭ᴹ_)catMaybes-↭ : ∀ {xs ys} → xs ↭ᴹ ys → catMaybes xs ↭ catMaybes yscatMaybes-↭ (refl p) = refl (pointwise p)wherepointwise : ∀ {xs ys} → Pointwise _≈ᴹ_ xs ys →Pointwise _≈_ (catMaybes xs) (catMaybes ys)pointwise [] = []pointwise (just p ∷ ps) = p ∷ pointwise pspointwise (nothing ∷ ps) = pointwise pscatMaybes-↭ (trans xs↭ ↭ys) = trans (catMaybes-↭ xs↭) (catMaybes-↭ ↭ys)catMaybes-↭ (prep nothing xs↭) = catMaybes-↭ xs↭catMaybes-↭ (prep (just x~y) xs↭) = prep x~y $ catMaybes-↭ xs↭catMaybes-↭ (swap nothing nothing xs↭) = catMaybes-↭ xs↭catMaybes-↭ (swap nothing (just y) xs↭) = prep y $ catMaybes-↭ xs↭catMaybes-↭ (swap (just x) nothing xs↭) = prep x $ catMaybes-↭ xs↭catMaybes-↭ (swap (just x) (just y) xs↭) = swap x y $ catMaybes-↭ xs↭-------------------------------------------------------------------------- mapMaybemodule _ (sᴬ : Setoid a ℓ) (sᴮ : Setoid b ℓ′) whereopen Setoid sᴬ using () renaming (_≈_ to _≈ᴬ_)open Permutation sᴬ using () renaming (_↭_ to _↭ᴬ_)open Permutation sᴮ using () renaming (_↭_ to _↭ᴮ_)private sᴹᴮ = setoidᴹ sᴮopen Setoid sᴹᴮ using () renaming (_≈_ to _≈ᴹᴮ_)mapMaybe-↭ : ∀ {f} → f Preserves _≈ᴬ_ ⟶ _≈ᴹᴮ_ →∀ {xs ys} → xs ↭ᴬ ys → mapMaybe f xs ↭ᴮ mapMaybe f ysmapMaybe-↭ pres = catMaybes-↭ sᴮ ∘ map⁺ sᴬ sᴹᴮ pres
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition for the permutation relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Permutation.Propositional{a} {A : Set a} whereopen import Data.List.Base using (List; []; _∷_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Transitive)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)import Relation.Binary.Reasoning.Setoid as EqReasoningopen import Relation.Binary.Reasoning.Syntax-------------------------------------------------------------------------- An inductive definition of permutation-- Note that one would expect that this would be defined in terms of-- `Permutation.Setoid`. This is not currently the case as it involves-- adding in a bunch of trivial `_≡_` proofs to the constructors which-- a) adds noise and b) prevents easy access to the variables `x`, `y`.-- This may be changed in future when a better solution is found.infix 3 _↭_data _↭_ : Rel (List A) a whererefl : ∀ {xs} → xs ↭ xsprep : ∀ {xs ys} x → xs ↭ ys → x ∷ xs ↭ x ∷ ysswap : ∀ {xs ys} x y → xs ↭ ys → x ∷ y ∷ xs ↭ y ∷ x ∷ ystrans : ∀ {xs ys zs} → xs ↭ ys → ys ↭ zs → xs ↭ zs-------------------------------------------------------------------------- _↭_ is an equivalence↭-reflexive : _≡_ ⇒ _↭_↭-reflexive refl = refl↭-refl : Reflexive _↭_↭-refl = refl↭-sym : ∀ {xs ys} → xs ↭ ys → ys ↭ xs↭-sym refl = refl↭-sym (prep x xs↭ys) = prep x (↭-sym xs↭ys)↭-sym (swap x y xs↭ys) = swap y x (↭-sym xs↭ys)↭-sym (trans xs↭ys ys↭zs) = trans (↭-sym ys↭zs) (↭-sym xs↭ys)-- A smart version of trans that avoids unnecessary `refl`s (see #1113).↭-trans : Transitive _↭_↭-trans refl ρ₂ = ρ₂↭-trans ρ₁ refl = ρ₁↭-trans ρ₁ ρ₂ = trans ρ₁ ρ₂↭-isEquivalence : IsEquivalence _↭_↭-isEquivalence = record{ refl = refl; sym = ↭-sym; trans = ↭-trans}↭-setoid : Setoid _ _↭-setoid = record{ isEquivalence = ↭-isEquivalence}-------------------------------------------------------------------------- A reasoning API to chain permutation proofs and allow "zooming in"-- to localised reasoning.module PermutationReasoning whereprivate module Base = EqReasoning ↭-setoidopen Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)renaming (≈-go to ↭-go)open ↭-syntax _IsRelatedTo_ _IsRelatedTo_ ↭-go ↭-sym public-- Some extra combinators that allow us to skip certain elementsinfixr 2 step-swap step-prep-- Skip reasoning on the first elementstep-prep : ∀ x xs {ys zs : List A} → (x ∷ ys) IsRelatedTo zs →xs ↭ ys → (x ∷ xs) IsRelatedTo zsstep-prep x xs rel xs↭ys = relTo (trans (prep x xs↭ys) (begin rel))-- Skip reasoning about the first two elementsstep-swap : ∀ x y xs {ys zs : List A} → (y ∷ x ∷ ys) IsRelatedTo zs →xs ↭ ys → (x ∷ y ∷ xs) IsRelatedTo zsstep-swap x y xs rel xs↭ys = relTo (trans (swap x y xs↭ys) (begin rel))syntax step-prep x xs y↭z x↭y = x ∷ xs <⟨ x↭y ⟩ y↭zsyntax step-swap x y xs y↭z x↭y = x ∷ y ∷ xs <<⟨ x↭y ⟩ y↭z
-------------------------------------------------------------------------- The Agda standard library---- Properties of permutation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Permutation.Propositional.Properties whereopen import Algebra.Bundlesopen import Algebra.Definitionsopen import Algebra.Structuresopen import Data.Bool.Base using (Bool; true; false)open import Data.Nat.Base using (suc; _*_)open import Data.Nat.Properties using (*-assoc; *-comm)open import Data.Product.Base using (-,_; proj₂)open import Data.List.Base as Listopen import Data.List.Relation.Binary.Permutation.Propositionalopen import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.List.Membership.Propositionalopen import Data.List.Membership.Propositional.Propertiesimport Data.List.Properties as Lₚopen import Data.Product.Base using (_,_; _×_; ∃; ∃₂)open import Data.Maybe.Base using (Maybe; just; nothing)open import Function.Base using (_∘_; _⟨_⟩_; _$_)open import Level using (Level)open import Relation.Unary using (Pred)open import Relation.Binary.Core using (Rel; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.Definitions using (_Respects_; Decidable)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_ ; refl ; cong; cong₂; _≢_)open import Relation.Binary.PropositionalEquality.Properties using (module ≡-Reasoning)open import Relation.Nullaryprivatevariablea b p : LevelA : Set aB : Set bxs ys : List A-------------------------------------------------------------------------- Permutations of empty and singleton lists↭-empty-inv : ∀ {xs : List A} → xs ↭ [] → xs ≡ []↭-empty-inv refl = refl↭-empty-inv (trans p q) with refl ← ↭-empty-inv q = ↭-empty-inv p¬x∷xs↭[] : ∀ {x} {xs : List A} → ¬ ((x ∷ xs) ↭ [])¬x∷xs↭[] (trans s₁ s₂) with ↭-empty-inv s₂... | refl = ¬x∷xs↭[] s₁↭-singleton-inv : ∀ {x} {xs : List A} → xs ↭ [ x ] → xs ≡ [ x ]↭-singleton-inv refl = refl↭-singleton-inv (prep _ ρ) with refl ← ↭-empty-inv ρ = refl↭-singleton-inv (trans ρ₁ ρ₂) with refl ← ↭-singleton-inv ρ₂ = ↭-singleton-inv ρ₁-------------------------------------------------------------------------- sym↭-sym-involutive : ∀ {xs ys : List A} (p : xs ↭ ys) → ↭-sym (↭-sym p) ≡ p↭-sym-involutive refl = refl↭-sym-involutive (prep x ↭) = cong (prep x) (↭-sym-involutive ↭)↭-sym-involutive (swap x y ↭) = cong (swap x y) (↭-sym-involutive ↭)↭-sym-involutive (trans ↭₁ ↭₂) =cong₂ trans (↭-sym-involutive ↭₁) (↭-sym-involutive ↭₂)-------------------------------------------------------------------------- Relationships to other predicatesAll-resp-↭ : ∀ {P : Pred A p} → (All P) Respects _↭_All-resp-↭ refl wit = witAll-resp-↭ (prep x p) (px ∷ wit) = px ∷ All-resp-↭ p witAll-resp-↭ (swap x y p) (px ∷ py ∷ wit) = py ∷ px ∷ All-resp-↭ p witAll-resp-↭ (trans p₁ p₂) wit = All-resp-↭ p₂ (All-resp-↭ p₁ wit)Any-resp-↭ : ∀ {P : Pred A p} → (Any P) Respects _↭_Any-resp-↭ refl wit = witAny-resp-↭ (prep x p) (here px) = here pxAny-resp-↭ (prep x p) (there wit) = there (Any-resp-↭ p wit)Any-resp-↭ (swap x y p) (here px) = there (here px)Any-resp-↭ (swap x y p) (there (here px)) = here pxAny-resp-↭ (swap x y p) (there (there wit)) = there (there (Any-resp-↭ p wit))Any-resp-↭ (trans p p₁) wit = Any-resp-↭ p₁ (Any-resp-↭ p wit)∈-resp-↭ : ∀ {x : A} → (x ∈_) Respects _↭_∈-resp-↭ = Any-resp-↭Any-resp-[σ⁻¹∘σ] : {xs ys : List A} {P : Pred A p} →(σ : xs ↭ ys) →(ix : Any P xs) →Any-resp-↭ (trans σ (↭-sym σ)) ix ≡ ixAny-resp-[σ⁻¹∘σ] refl ix = reflAny-resp-[σ⁻¹∘σ] (prep _ _) (here _) = reflAny-resp-[σ⁻¹∘σ] (swap _ _ _) (here _) = reflAny-resp-[σ⁻¹∘σ] (swap _ _ _) (there (here _)) = reflAny-resp-[σ⁻¹∘σ] (trans σ₁ σ₂) ixrewrite Any-resp-[σ⁻¹∘σ] σ₂ (Any-resp-↭ σ₁ ix)rewrite Any-resp-[σ⁻¹∘σ] σ₁ ix= reflAny-resp-[σ⁻¹∘σ] (prep _ σ) (there ix)rewrite Any-resp-[σ⁻¹∘σ] σ ix= reflAny-resp-[σ⁻¹∘σ] (swap _ _ σ) (there (there ix))rewrite Any-resp-[σ⁻¹∘σ] σ ix= refl∈-resp-[σ⁻¹∘σ] : {xs ys : List A} {x : A} →(σ : xs ↭ ys) →(ix : x ∈ xs) →∈-resp-↭ (trans σ (↭-sym σ)) ix ≡ ix∈-resp-[σ⁻¹∘σ] = Any-resp-[σ⁻¹∘σ]-------------------------------------------------------------------------- mapmodule _ (f : A → B) wheremap⁺ : ∀ {xs ys} → xs ↭ ys → map f xs ↭ map f ysmap⁺ refl = reflmap⁺ (prep x p) = prep _ (map⁺ p)map⁺ (swap x y p) = swap _ _ (map⁺ p)map⁺ (trans p₁ p₂) = trans (map⁺ p₁) (map⁺ p₂)-- permutations preserve 'being a mapped list'↭-map-inv : ∀ {xs ys} → map f xs ↭ ys → ∃ λ ys′ → ys ≡ map f ys′ × xs ↭ ys′↭-map-inv {[]} ρ = -, ↭-empty-inv (↭-sym ρ) , ↭-refl↭-map-inv {x ∷ []} ρ = -, ↭-singleton-inv (↭-sym ρ) , ↭-refl↭-map-inv {_ ∷ _ ∷ _} refl = -, refl , ↭-refl↭-map-inv {_ ∷ _ ∷ _} (prep _ ρ) with _ , refl , ρ′ ← ↭-map-inv ρ = -, refl , prep _ ρ′↭-map-inv {_ ∷ _ ∷ _} (swap _ _ ρ) with _ , refl , ρ′ ← ↭-map-inv ρ = -, refl , swap _ _ ρ′↭-map-inv {_ ∷ _ ∷ _} (trans ρ₁ ρ₂) with _ , refl , ρ₃ ← ↭-map-inv ρ₁with _ , refl , ρ₄ ← ↭-map-inv ρ₂ = -, refl , trans ρ₃ ρ₄-------------------------------------------------------------------------- length↭-length : ∀ {xs ys : List A} → xs ↭ ys → length xs ≡ length ys↭-length refl = refl↭-length (prep x lr) = cong suc (↭-length lr)↭-length (swap x y lr) = cong (suc ∘ suc) (↭-length lr)↭-length (trans lr₁ lr₂) = ≡.trans (↭-length lr₁) (↭-length lr₂)-------------------------------------------------------------------------- _++_++⁺ˡ : ∀ xs {ys zs : List A} → ys ↭ zs → xs ++ ys ↭ xs ++ zs++⁺ˡ [] ys↭zs = ys↭zs++⁺ˡ (x ∷ xs) ys↭zs = prep x (++⁺ˡ xs ys↭zs)++⁺ʳ : ∀ {xs ys : List A} zs → xs ↭ ys → xs ++ zs ↭ ys ++ zs++⁺ʳ zs refl = refl++⁺ʳ zs (prep x ↭) = prep x (++⁺ʳ zs ↭)++⁺ʳ zs (swap x y ↭) = swap x y (++⁺ʳ zs ↭)++⁺ʳ zs (trans ↭₁ ↭₂) = trans (++⁺ʳ zs ↭₁) (++⁺ʳ zs ↭₂)++⁺ : _++_ {A = A} Preserves₂ _↭_ ⟶ _↭_ ⟶ _↭_++⁺ ws↭xs ys↭zs = trans (++⁺ʳ _ ws↭xs) (++⁺ˡ _ ys↭zs)-- Some useful lemmaszoom : ∀ h {t xs ys : List A} → xs ↭ ys → h ++ xs ++ t ↭ h ++ ys ++ tzoom h {t} = ++⁺ˡ h ∘ ++⁺ʳ tinject : ∀ (v : A) {ws xs ys zs} → ws ↭ ys → xs ↭ zs →ws ++ [ v ] ++ xs ↭ ys ++ [ v ] ++ zsinject v ws↭ys xs↭zs = trans (++⁺ˡ _ (prep v xs↭zs)) (++⁺ʳ _ ws↭ys)shift : ∀ v (xs ys : List A) → xs ++ [ v ] ++ ys ↭ v ∷ xs ++ ysshift v [] ys = reflshift v (x ∷ xs) ys = beginx ∷ (xs ++ [ v ] ++ ys) <⟨ shift v xs ys ⟩x ∷ v ∷ xs ++ ys <<⟨ refl ⟩v ∷ x ∷ xs ++ ys ∎where open PermutationReasoningdrop-mid-≡ : ∀ {x : A} ws xs {ys} {zs} →ws ++ [ x ] ++ ys ≡ xs ++ [ x ] ++ zs →ws ++ ys ↭ xs ++ zsdrop-mid-≡ [] [] eq with cong tail eqdrop-mid-≡ [] [] eq | refl = refldrop-mid-≡ [] (x ∷ xs) refl = shift _ xs _drop-mid-≡ (w ∷ ws) [] refl = ↭-sym (shift _ ws _)drop-mid-≡ (w ∷ ws) (x ∷ xs) eq with Lₚ.∷-injective eq... | refl , eq′ = prep w (drop-mid-≡ ws xs eq′)drop-mid : ∀ {x : A} ws xs {ys zs} →ws ++ [ x ] ++ ys ↭ xs ++ [ x ] ++ zs →ws ++ ys ↭ xs ++ zsdrop-mid {A = A} {x} ws xs p = drop-mid′ p ws xs refl reflwheredrop-mid′ : ∀ {l′ l″ : List A} → l′ ↭ l″ →∀ ws xs {ys zs} →ws ++ [ x ] ++ ys ≡ l′ →xs ++ [ x ] ++ zs ≡ l″ →ws ++ ys ↭ xs ++ zsdrop-mid′ refl ws xs refl eq = drop-mid-≡ ws xs (≡.sym eq)drop-mid′ (prep x p) [] [] refl eq with cong tail eqdrop-mid′ (prep x p) [] [] refl eq | refl = pdrop-mid′ (prep x p) [] (x ∷ xs) refl refl = trans p (shift _ _ _)drop-mid′ (prep x p) (w ∷ ws) [] refl refl = trans (↭-sym (shift _ _ _)) pdrop-mid′ (prep x p) (w ∷ ws) (x ∷ xs) refl refl = prep _ (drop-mid′ p ws xs refl refl)drop-mid′ (swap y z p) [] [] refl refl = prep _ pdrop-mid′ (swap y z p) [] (x ∷ []) refl eq with cong {B = List _}(λ { (x ∷ _ ∷ xs) → x ∷ xs; _ → []})eqdrop-mid′ (swap y z p) [] (x ∷ []) refl eq | refl = prep _ pdrop-mid′ (swap y z p) [] (x ∷ _ ∷ xs) refl refl = prep _ (trans p (shift _ _ _))drop-mid′ (swap y z p) (w ∷ []) [] refl eq with cong tail eqdrop-mid′ (swap y z p) (w ∷ []) [] refl eq | refl = prep _ pdrop-mid′ (swap y z p) (w ∷ x ∷ ws) [] refl refl = prep _ (trans (↭-sym (shift _ _ _)) p)drop-mid′ (swap y y p) (y ∷ []) (y ∷ []) refl refl = prep _ pdrop-mid′ (swap y z p) (y ∷ []) (z ∷ y ∷ xs) refl refl = begin_ ∷ _ <⟨ p ⟩_ ∷ (xs ++ _ ∷ _) <⟨ shift _ _ _ ⟩_ ∷ _ ∷ xs ++ _ <<⟨ refl ⟩_ ∷ _ ∷ xs ++ _ ∎where open PermutationReasoningdrop-mid′ (swap y z p) (y ∷ z ∷ ws) (z ∷ []) refl refl = begin_ ∷ _ ∷ ws ++ _ <<⟨ refl ⟩_ ∷ (_ ∷ ws ++ _) <⟨ ↭-sym (shift _ _ _) ⟩_ ∷ (ws ++ _ ∷ _) <⟨ p ⟩_ ∷ _ ∎where open PermutationReasoningdrop-mid′ (swap y z p) (y ∷ z ∷ ws) (z ∷ y ∷ xs) refl refl = swap y z (drop-mid′ p _ _ refl refl)drop-mid′ (trans p₁ p₂) ws xs refl refl with ∈-∃++ (∈-resp-↭ p₁ (∈-insert ws))... | (h , t , refl) = trans (drop-mid′ p₁ ws h refl refl) (drop-mid′ p₂ h xs refl refl)-- Algebraic properties++-identityˡ : LeftIdentity {A = List A} _↭_ [] _++_++-identityˡ xs = refl++-identityʳ : RightIdentity {A = List A} _↭_ [] _++_++-identityʳ xs = ↭-reflexive (Lₚ.++-identityʳ xs)++-identity : Identity {A = List A} _↭_ [] _++_++-identity = ++-identityˡ , ++-identityʳ++-assoc : Associative {A = List A} _↭_ _++_++-assoc xs ys zs = ↭-reflexive (Lₚ.++-assoc xs ys zs)++-comm : Commutative {A = List A} _↭_ _++_++-comm [] ys = ↭-sym (++-identityʳ ys)++-comm (x ∷ xs) ys = beginx ∷ xs ++ ys <⟨ ++-comm xs ys ⟩x ∷ ys ++ xs ↭⟨ shift x ys xs ⟨ys ++ (x ∷ xs) ∎where open PermutationReasoning++-isMagma : IsMagma {A = List A} _↭_ _++_++-isMagma = record{ isEquivalence = ↭-isEquivalence; ∙-cong = ++⁺}++-isSemigroup : IsSemigroup {A = List A} _↭_ _++_++-isSemigroup = record{ isMagma = ++-isMagma; assoc = ++-assoc}++-isMonoid : IsMonoid {A = List A} _↭_ _++_ []++-isMonoid = record{ isSemigroup = ++-isSemigroup; identity = ++-identity}++-isCommutativeMonoid : IsCommutativeMonoid {A = List A} _↭_ _++_ []++-isCommutativeMonoid = record{ isMonoid = ++-isMonoid; comm = ++-comm}module _ {a} {A : Set a} where++-magma : Magma _ _++-magma = record{ isMagma = ++-isMagma {A = A}}++-semigroup : Semigroup a _++-semigroup = record{ isSemigroup = ++-isSemigroup {A = A}}++-monoid : Monoid a _++-monoid = record{ isMonoid = ++-isMonoid {A = A}}++-commutativeMonoid : CommutativeMonoid _ _++-commutativeMonoid = record{ isCommutativeMonoid = ++-isCommutativeMonoid {A = A}}-- Another useful lemmashifts : ∀ xs ys {zs : List A} → xs ++ ys ++ zs ↭ ys ++ xs ++ zsshifts xs ys {zs} = beginxs ++ ys ++ zs ↭⟨ ++-assoc xs ys zs ⟨(xs ++ ys) ++ zs ↭⟨ ++⁺ʳ zs (++-comm xs ys) ⟩(ys ++ xs) ++ zs ↭⟨ ++-assoc ys xs zs ⟩ys ++ xs ++ zs ∎where open PermutationReasoning-------------------------------------------------------------------------- _∷_drop-∷ : ∀ {x : A} {xs ys} → x ∷ xs ↭ x ∷ ys → xs ↭ ysdrop-∷ = drop-mid [] []-------------------------------------------------------------------------- _∷ʳ_∷↭∷ʳ : ∀ (x : A) xs → x ∷ xs ↭ xs ∷ʳ x∷↭∷ʳ x xs = ↭-sym (beginxs ++ [ x ] ↭⟨ shift x xs [] ⟩x ∷ xs ++ [] ≡⟨ Lₚ.++-identityʳ _ ⟩x ∷ xs ∎)where open PermutationReasoning-------------------------------------------------------------------------- ʳ++++↭ʳ++ : ∀ (xs ys : List A) → xs ++ ys ↭ xs ʳ++ ys++↭ʳ++ [] ys = ↭-refl++↭ʳ++ (x ∷ xs) ys = ↭-trans (↭-sym (shift x xs ys)) (++↭ʳ++ xs (x ∷ ys))-------------------------------------------------------------------------- reverse↭-reverse : (xs : List A) → reverse xs ↭ xs↭-reverse [] = ↭-refl↭-reverse (x ∷ xs) = beginreverse (x ∷ xs) ≡⟨ Lₚ.unfold-reverse x xs ⟩reverse xs ∷ʳ x ↭⟨ ∷↭∷ʳ x (reverse xs) ⟨x ∷ reverse xs ↭⟨ prep x (↭-reverse xs) ⟩x ∷ xs ∎where open PermutationReasoning-------------------------------------------------------------------------- mergemodule _ {ℓ} {R : Rel A ℓ} (R? : Decidable R) wheremerge-↭ : ∀ xs ys → merge R? xs ys ↭ xs ++ ysmerge-↭ [] [] = ↭-reflmerge-↭ [] (y ∷ ys) = ↭-reflmerge-↭ (x ∷ xs) [] = ↭-sym (++-identityʳ (x ∷ xs))merge-↭ (x ∷ xs) (y ∷ ys)with does (R? x y) | merge-↭ xs (y ∷ ys) | merge-↭ (x ∷ xs) ys... | true | rec | _ = prep x rec... | false | _ | rec = beginy ∷ merge R? (x ∷ xs) ys <⟨ rec ⟩y ∷ x ∷ xs ++ ys ↭⟨ shift y (x ∷ xs) ys ⟨(x ∷ xs) ++ y ∷ ys ≡⟨ Lₚ.++-assoc [ x ] xs (y ∷ ys) ⟨x ∷ xs ++ y ∷ ys ∎where open PermutationReasoning-------------------------------------------------------------------------- productproduct-↭ : product Preserves _↭_ ⟶ _≡_product-↭ refl = reflproduct-↭ (prep x r) = cong (x *_) (product-↭ r)product-↭ (trans r s) = ≡.trans (product-↭ r) (product-↭ s)product-↭ (swap {xs} {ys} x y r) = beginx * (y * product xs) ≡˘⟨ *-assoc x y (product xs) ⟩(x * y) * product xs ≡⟨ cong₂ _*_ (*-comm x y) (product-↭ r) ⟩(y * x) * product ys ≡⟨ *-assoc y x (product ys) ⟩y * (x * product ys) ∎where open ≡-Reasoning-------------------------------------------------------------------------- catMaybescatMaybes-↭ : xs ↭ ys → catMaybes xs ↭ catMaybes yscatMaybes-↭ refl = reflcatMaybes-↭ (trans xs↭ ↭ys) = trans (catMaybes-↭ xs↭) (catMaybes-↭ ↭ys)catMaybes-↭ (prep nothing xs↭) = catMaybes-↭ xs↭catMaybes-↭ (prep (just x) xs↭) = prep x $ catMaybes-↭ xs↭catMaybes-↭ (swap nothing nothing xs↭) = catMaybes-↭ xs↭catMaybes-↭ (swap nothing (just y) xs↭) = prep y $ catMaybes-↭ xs↭catMaybes-↭ (swap (just x) nothing xs↭) = prep x $ catMaybes-↭ xs↭catMaybes-↭ (swap (just x) (just y) xs↭) = swap x y $ catMaybes-↭ xs↭-------------------------------------------------------------------------- mapMaybemapMaybe-↭ : (f : A → Maybe B) → xs ↭ ys → mapMaybe f xs ↭ mapMaybe f ysmapMaybe-↭ f = catMaybes-↭ ∘ map⁺ f
-------------------------------------------------------------------------- The Agda standard library---- A definition for the permutation relation using setoid equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Permutation.Homogeneous whereopen import Data.List.Base using (List; _∷_)open import Data.List.Relation.Binary.Pointwise.Base as Pointwiseusing (Pointwise)open import Data.List.Relation.Binary.Pointwise.Properties as Pointwiseusing (symmetric)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitions using (Reflexive; Symmetric)privatevariablea r s : LevelA : Set adata Permutation {A : Set a} (R : Rel A r) : Rel (List A) (a ⊔ r) whererefl : ∀ {xs ys} → Pointwise R xs ys → Permutation R xs ysprep : ∀ {xs ys x y} (eq : R x y) → Permutation R xs ys → Permutation R (x ∷ xs) (y ∷ ys)swap : ∀ {xs ys x y x′ y′} (eq₁ : R x x′) (eq₂ : R y y′) → Permutation R xs ys → Permutation R (x ∷ y ∷ xs) (y′ ∷ x′ ∷ ys)trans : ∀ {xs ys zs} → Permutation R xs ys → Permutation R ys zs → Permutation R xs zs-------------------------------------------------------------------------- The Permutation relation is an equivalencemodule _ {R : Rel A r} wheresym : Symmetric R → Symmetric (Permutation R)sym R-sym (refl xs∼ys) = refl (Pointwise.symmetric R-sym xs∼ys)sym R-sym (prep x∼x′ xs↭ys) = prep (R-sym x∼x′) (sym R-sym xs↭ys)sym R-sym (swap x∼x′ y∼y′ xs↭ys) = swap (R-sym y∼y′) (R-sym x∼x′) (sym R-sym xs↭ys)sym R-sym (trans xs↭ys ys↭zs) = trans (sym R-sym ys↭zs) (sym R-sym xs↭ys)isEquivalence : Reflexive R → Symmetric R → IsEquivalence (Permutation R)isEquivalence R-refl R-sym = record{ refl = refl (Pointwise.refl R-refl); sym = sym R-sym; trans = trans}setoid : Reflexive R → Symmetric R → Setoid _ _setoid R-refl R-sym = record{ isEquivalence = isEquivalence R-refl R-sym}map : ∀ {R : Rel A r} {S : Rel A s} →(R ⇒ S) → (Permutation R ⇒ Permutation S)map R⇒S (refl xs∼ys) = refl (Pointwise.map R⇒S xs∼ys)map R⇒S (prep e xs∼ys) = prep (R⇒S e) (map R⇒S xs∼ys)map R⇒S (swap e₁ e₂ xs∼ys) = swap (R⇒S e₁) (R⇒S e₂) (map R⇒S xs∼ys)map R⇒S (trans xs∼ys ys∼zs) = trans (map R⇒S xs∼ys) (map R⇒S ys∼zs)
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Lex whereopen import Data.Empty using (⊥; ⊥-elim)open import Data.Unit.Base using (⊤; tt)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂; uncurry)open import Data.List.Base using (List; []; _∷_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Function.Base using (_∘_; flip; id)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (_⊔_)open import Relation.Nullary.Negation using (¬_)open import Relation.Nullary.Decidable as Decusing (Dec; yes; no; _×-dec_; _⊎-dec_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Symmetric; Transitive; Irreflexive; Asymmetric; Antisymmetric; Decidable; _Respects₂_; _Respects_)open import Data.List.Relation.Binary.Pointwise.Baseusing (Pointwise; []; _∷_; head; tail)-------------------------------------------------------------------------- Re-exporting the core definitions and propertiesopen import Data.List.Relation.Binary.Lex.Core public-------------------------------------------------------------------------- Propertiesmodule _ {a ℓ₁ ℓ₂} {A : Set a} {P : Set}{_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex P _≈_ _≺_¬≤-this : ∀ {x y xs ys} → ¬ (x ≈ y) → ¬ (x ≺ y) →¬ (x ∷ xs) < (y ∷ ys)¬≤-this x≉y x≮y (this x≺y) = x≮y x≺y¬≤-this x≉y x≮y (next x≈y xs<ys) = x≉y x≈y¬≤-next : ∀ {x y xs ys} → ¬ x ≺ y → ¬ xs < ys →¬ (x ∷ xs) < (y ∷ ys)¬≤-next x≮y xs≮ys (this x≺y) = x≮y x≺y¬≤-next x≮y xs≮ys (next _ xs<ys) = xs≮ys xs<ysantisymmetric : Symmetric _≈_ → Irreflexive _≈_ _≺_ →Asymmetric _≺_ → Antisymmetric _≋_ _<_antisymmetric sym ir asym = aswhereas : Antisymmetric _≋_ _<_as (base _) (base _) = []as (this x≺y) (this y≺x) = ⊥-elim (asym x≺y y≺x)as (this x≺y) (next y≈x ys<xs) = ⊥-elim (ir (sym y≈x) x≺y)as (next x≈y xs<ys) (this y≺x) = ⊥-elim (ir (sym x≈y) y≺x)as (next x≈y xs<ys) (next y≈x ys<xs) = x≈y ∷ as xs<ys ys<xstoSum : ∀ {x y xs ys} → (x ∷ xs) < (y ∷ ys) → (x ≺ y ⊎ (x ≈ y × xs < ys))toSum (this x≺y) = inj₁ x≺ytoSum (next x≈y xs<ys) = inj₂ (x≈y , xs<ys)transitive : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ →Transitive _<_transitive eq resp tr = transwheretrans : Transitive (Lex P _≈_ _≺_)trans (base p) (base _) = base ptrans (base y) halt = halttrans halt (this y≺z) = halttrans halt (next y≈z ys<zs) = halttrans (this x≺y) (this y≺z) = this (tr x≺y y≺z)trans (this x≺y) (next y≈z ys<zs) = this (proj₁ resp y≈z x≺y)trans (next x≈y xs<ys) (this y≺z) =this (proj₂ resp (IsEquivalence.sym eq x≈y) y≺z)trans (next x≈y xs<ys) (next y≈z ys<zs) =next (IsEquivalence.trans eq x≈y y≈z) (trans xs<ys ys<zs)respects₂ : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → _<_ Respects₂ _≋_respects₂ eq (resp₁ , resp₂) = resp¹ , resp²whereopen IsEquivalence eq using (sym; trans)resp¹ : ∀ {xs} → Lex P _≈_ _≺_ xs Respects _≋_resp¹ [] xs<[] = xs<[]resp¹ (_ ∷ _) halt = haltresp¹ (x≈y ∷ _) (this z≺x) = this (resp₁ x≈y z≺x)resp¹ (x≈y ∷ xs≋ys) (next z≈x zs<xs) =next (trans z≈x x≈y) (resp¹ xs≋ys zs<xs)resp² : ∀ {ys} → flip (Lex P _≈_ _≺_) ys Respects _≋_resp² [] []<ys = []<ysresp² (x≈z ∷ _) (this x≺y) = this (resp₂ x≈z x≺y)resp² (x≈z ∷ xs≋zs) (next x≈y xs<ys) =next (trans (sym x≈z) x≈y) (resp² xs≋zs xs<ys)[]<[]-⇔ : P ⇔ [] < [][]<[]-⇔ = mk⇔ base (λ { (base p) → p })∷<∷-⇔ : ∀ {x y xs ys} → (x ≺ y ⊎ (x ≈ y × xs < ys)) ⇔ (x ∷ xs) < (y ∷ ys)∷<∷-⇔ = mk⇔ [ this , uncurry next ] toSummodule _ (dec-P : Dec P) (dec-≈ : Decidable _≈_) (dec-≺ : Decidable _≺_)wheredecidable : Decidable _<_decidable [] [] = Dec.map []<[]-⇔ dec-Pdecidable [] (y ∷ ys) = yes haltdecidable (x ∷ xs) [] = no λ()decidable (x ∷ xs) (y ∷ ys) =Dec.map ∷<∷-⇔ (dec-≺ x y ⊎-dec (dec-≈ x y ×-dec decidable xs ys))
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of lists-------------------------------------------------------------------------- The definitions of lexicographic ordering used here are suitable if-- the argument order is a strict partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Lex.Strict whereopen import Data.Empty using (⊥)open import Data.Unit.Base using (⊤; tt)open import Function.Base using (_∘_; id)open import Data.Product.Base using (_,_)open import Data.Sum.Base using (inj₁; inj₂)open import Data.List.Base using (List; []; _∷_)open import Level using (_⊔_)open import Relation.Nullary using (yes; no; ¬_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (StrictPartialOrder; StrictTotalOrder; Preorder; Poset; DecPoset; DecTotalOrder)open import Relation.Binary.Structuresusing (IsEquivalence; IsStrictPartialOrder; IsStrictTotalOrder; IsPreorder; IsPartialOrder; IsDecPartialOrder; IsTotalOrder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Irreflexive; Symmetric; _Respects₂_; Total; Asymmetric; Antisymmetric; Transitive; Trichotomous; Decidable; tri≈; tri<; tri>)open import Relation.Binary.Consequencesopen import Data.List.Relation.Binary.Pointwise as Pointwiseusing (Pointwise; []; _∷_; head; tail)import Data.List.Relation.Binary.Lex as Core-------------------------------------------------------------------------- Re-exporting core definitionsopen Core publicusing (Lex-<; Lex-≤; base; halt; this; next; ¬≤-this; ¬≤-next)-------------------------------------------------------------------------- Strict lexicographic ordering.module _ {a ℓ₁ ℓ₂} {A : Set a} where-- Propertiesmodule _ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≺_xs≮[] : ∀ {xs} → ¬ xs < []xs≮[] (base ())¬[]<[] : ¬ [] < []¬[]<[] = xs≮[]<-irreflexive : Irreflexive _≈_ _≺_ → Irreflexive _≋_ _<_<-irreflexive irr (x≈y ∷ xs≋ys) (this x<y) = irr x≈y x<y<-irreflexive irr (x≈y ∷ xs≋ys) (next _ xs⊴ys) =<-irreflexive irr xs≋ys xs⊴ys<-asymmetric : Symmetric _≈_ → _≺_ Respects₂ _≈_ → Asymmetric _≺_ →Asymmetric _<_<-asymmetric sym resp as = asymwhereirrefl : Irreflexive _≈_ _≺_irrefl = asym⇒irr resp sym asasym : Asymmetric _<_asym (base bot) _ = botasym (this x<y) (this y<x) = as x<y y<xasym (this x<y) (next y≈x ys⊴xs) = irrefl (sym y≈x) x<yasym (next x≈y xs⊴ys) (this y<x) = irrefl (sym x≈y) y<xasym (next x≈y xs⊴ys) (next y≈x ys⊴xs) = asym xs⊴ys ys⊴xs<-antisymmetric : Symmetric _≈_ → Irreflexive _≈_ _≺_ →Asymmetric _≺_ → Antisymmetric _≋_ _<_<-antisymmetric = Core.antisymmetric<-transitive : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ →Transitive _≺_ → Transitive _<_<-transitive = Core.transitive<-compare : Symmetric _≈_ → Trichotomous _≈_ _≺_ →Trichotomous _≋_ _<_<-compare sym tri [] [] = tri≈ ¬[]<[] [] ¬[]<[]<-compare sym tri [] (y ∷ ys) = tri< halt (λ()) (λ())<-compare sym tri (x ∷ xs) [] = tri> (λ()) (λ()) halt<-compare sym tri (x ∷ xs) (y ∷ ys) with tri x y... | tri< x<y x≉y y≮x =tri< (this x<y) (x≉y ∘ head) (¬≤-this (x≉y ∘ sym) y≮x)... | tri> x≮y x≉y y<x =tri> (¬≤-this x≉y x≮y) (x≉y ∘ head) (this y<x)... | tri≈ x≮y x≈y y≮x with <-compare sym tri xs ys... | tri< xs<ys xs≉ys ys≮xs =tri< (next x≈y xs<ys) (xs≉ys ∘ tail) (¬≤-next y≮x ys≮xs)... | tri≈ xs≮ys xs≈ys ys≮xs =tri≈ (¬≤-next x≮y xs≮ys) (x≈y ∷ xs≈ys) (¬≤-next y≮x ys≮xs)... | tri> xs≮ys xs≉ys ys<xs =tri> (¬≤-next x≮y xs≮ys) (xs≉ys ∘ tail) (next (sym x≈y) ys<xs)<-decidable : Decidable _≈_ → Decidable _≺_ → Decidable _<_<-decidable = Core.decidable (no id)<-respects₂ : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ →_<_ Respects₂ _≋_<-respects₂ = Core.respects₂<-isStrictPartialOrder : IsStrictPartialOrder _≈_ _≺_ →IsStrictPartialOrder _≋_ _<_<-isStrictPartialOrder spo = record{ isEquivalence = Pointwise.isEquivalence isEquivalence; irrefl = <-irreflexive irrefl; trans = Core.transitive isEquivalence <-resp-≈ trans; <-resp-≈ = Core.respects₂ isEquivalence <-resp-≈} where open IsStrictPartialOrder spo<-isStrictTotalOrder : IsStrictTotalOrder _≈_ _≺_ →IsStrictTotalOrder _≋_ _<_<-isStrictTotalOrder sto = record{ isStrictPartialOrder = <-isStrictPartialOrder isStrictPartialOrder; compare = <-compare Eq.sym compare} where open IsStrictTotalOrder sto<-strictPartialOrder : ∀ {a ℓ₁ ℓ₂} → StrictPartialOrder a ℓ₁ ℓ₂ →StrictPartialOrder _ _ _<-strictPartialOrder spo = record{ isStrictPartialOrder = <-isStrictPartialOrder isStrictPartialOrder} where open StrictPartialOrder spo<-strictTotalOrder : ∀ {a ℓ₁ ℓ₂} → StrictTotalOrder a ℓ₁ ℓ₂ →StrictTotalOrder _ _ _<-strictTotalOrder sto = record{ isStrictTotalOrder = <-isStrictTotalOrder isStrictTotalOrder} where open StrictTotalOrder sto-------------------------------------------------------------------------- Non-strict lexicographic ordering.module _ {a ℓ₁ ℓ₂} {A : Set a} where-- Properties≤-reflexive : (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) →Pointwise _≈_ ⇒ Lex-≤ _≈_ _≺_≤-reflexive _≈_ _≺_ [] = base tt≤-reflexive _≈_ _≺_ (x≈y ∷ xs≈ys) =next x≈y (≤-reflexive _≈_ _≺_ xs≈ys)module _ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__≤_ = Lex-≤ _≈_ _≺_≤-antisymmetric : Symmetric _≈_ → Irreflexive _≈_ _≺_ →Asymmetric _≺_ → Antisymmetric _≋_ _≤_≤-antisymmetric = Core.antisymmetric≤-transitive : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ →Transitive _≺_ → Transitive _≤_≤-transitive = Core.transitive-- Note that trichotomy is an unnecessarily strong precondition for-- the following lemma.≤-total : Symmetric _≈_ → Trichotomous _≈_ _≺_ → Total _≤_≤-total _ _ [] [] = inj₁ (base tt)≤-total _ _ [] (x ∷ xs) = inj₁ halt≤-total _ _ (x ∷ xs) [] = inj₂ halt≤-total sym tri (x ∷ xs) (y ∷ ys) with tri x y... | tri< x<y _ _ = inj₁ (this x<y)... | tri> _ _ y<x = inj₂ (this y<x)... | tri≈ _ x≈y _ with ≤-total sym tri xs ys... | inj₁ xs≲ys = inj₁ (next x≈y xs≲ys)... | inj₂ ys≲xs = inj₂ (next (sym x≈y) ys≲xs)≤-decidable : Decidable _≈_ → Decidable _≺_ → Decidable _≤_≤-decidable = Core.decidable (yes tt)≤-respects₂ : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ →_≤_ Respects₂ _≋_≤-respects₂ = Core.respects₂≤-isPreorder : IsEquivalence _≈_ → Transitive _≺_ →_≺_ Respects₂ _≈_ → IsPreorder _≋_ _≤_≤-isPreorder eq tr resp = record{ isEquivalence = Pointwise.isEquivalence eq; reflexive = ≤-reflexive _≈_ _≺_; trans = Core.transitive eq resp tr}≤-isPartialOrder : IsStrictPartialOrder _≈_ _≺_ →IsPartialOrder _≋_ _≤_≤-isPartialOrder spo = record{ isPreorder = ≤-isPreorder isEquivalence trans <-resp-≈; antisym = Core.antisymmetric Eq.sym irrefl asym}where open IsStrictPartialOrder spo≤-isDecPartialOrder : IsStrictTotalOrder _≈_ _≺_ →IsDecPartialOrder _≋_ _≤_≤-isDecPartialOrder sto = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder; _≟_ = Pointwise.decidable _≟_; _≤?_ = ≤-decidable _≟_ _<?_} where open IsStrictTotalOrder sto≤-isTotalOrder : IsStrictTotalOrder _≈_ _≺_ → IsTotalOrder _≋_ _≤_≤-isTotalOrder sto = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder; total = ≤-total Eq.sym compare}where open IsStrictTotalOrder sto≤-isDecTotalOrder : IsStrictTotalOrder _≈_ _≺_ →IsDecTotalOrder _≋_ _≤_≤-isDecTotalOrder sto = record{ isTotalOrder = ≤-isTotalOrder sto; _≟_ = Pointwise.decidable _≟_; _≤?_ = ≤-decidable _≟_ _<?_}where open IsStrictTotalOrder sto≤-preorder : ∀ {a ℓ₁ ℓ₂} → Preorder a ℓ₁ ℓ₂ → Preorder _ _ _≤-preorder pre = record{ isPreorder = ≤-isPreorder isEquivalence trans ∼-resp-≈} where open Preorder pre≤-partialOrder : ∀ {a ℓ₁ ℓ₂} → StrictPartialOrder a ℓ₁ ℓ₂ → Poset _ _ _≤-partialOrder spo = record{ isPartialOrder = ≤-isPartialOrder isStrictPartialOrder} where open StrictPartialOrder spo≤-decPoset : ∀ {a ℓ₁ ℓ₂} → StrictTotalOrder a ℓ₁ ℓ₂ →DecPoset _ _ _≤-decPoset sto = record{ isDecPartialOrder = ≤-isDecPartialOrder isStrictTotalOrder} where open StrictTotalOrder sto≤-decTotalOrder : ∀ {a ℓ₁ ℓ₂} → StrictTotalOrder a ℓ₁ ℓ₂ →DecTotalOrder _ _ _≤-decTotalOrder sto = record{ isDecTotalOrder = ≤-isDecTotalOrder isStrictTotalOrder} where open StrictTotalOrder sto
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of lists-------------------------------------------------------------------------- The definitions of lexicographic orderings used here is suitable if-- the argument order is a (non-strict) partial order.{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Lex.NonStrict whereopen import Data.Empty using (⊥)open import Function.Baseopen import Data.Unit.Base using (⊤; tt)open import Data.List.Baseopen import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; [])import Data.List.Relation.Binary.Lex.Strict as Strictopen import Levelopen import Relation.Nullaryopen import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundlesusing (Poset; StrictPartialOrder; DecTotalOrder; StrictTotalOrder; Preorder)open import Relation.Binary.Structuresusing (IsEquivalence; IsPartialOrder; IsStrictPartialOrder; IsTotalOrder; IsStrictTotalOrder; IsPreorder; IsDecTotalOrder)open import Relation.Binary.Definitionsusing (Irreflexive; _Respects₂_; Antisymmetric; Asymmetric; Symmetric; Transitive; Decidable; Total; Trichotomous)import Relation.Binary.Construct.NonStrictToStrict as Convimport Data.List.Relation.Binary.Lex as Core-------------------------------------------------------------------------- Publically re-export definitions from Coreopen Core publicusing (base; halt; this; next; ¬≤-this; ¬≤-next)-------------------------------------------------------------------------- Strict lexicographic ordering.module _ {a ℓ₁ ℓ₂} {A : Set a} whereLex-< : (_≈_ : Rel A ℓ₁) (_≼_ : Rel A ℓ₂) → Rel (List A) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-< _≈_ _≼_ = Core.Lex ⊥ _≈_ (Conv._<_ _≈_ _≼_)-- Propertiesmodule _ {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__<_ = Lex-< _≈_ _≼_<-irreflexive : Irreflexive _≋_ _<_<-irreflexive = Strict.<-irreflexive (Conv.<-irrefl _≈_ _≼_)<-asymmetric : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ →Antisymmetric _≈_ _≼_ → Asymmetric _<_<-asymmetric eq resp antisym =Strict.<-asymmetric sym (Conv.<-resp-≈ _ _ eq resp)(Conv.<-asym _≈_ _ antisym)where open IsEquivalence eq<-antisymmetric : Symmetric _≈_ → Antisymmetric _≈_ _≼_ →Antisymmetric _≋_ _<_<-antisymmetric sym antisym =Core.antisymmetric sym(Conv.<-irrefl _≈_ _≼_)(Conv.<-asym _ _≼_ antisym)<-transitive : IsPartialOrder _≈_ _≼_ → Transitive _<_<-transitive po =Core.transitive isEquivalence(Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)(Conv.<-trans _ _≼_ po)where open IsPartialOrder po<-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ → _<_ Respects₂ _≋_<-resp₂ eq resp = Core.respects₂ eq (Conv.<-resp-≈ _ _ eq resp)<-compare : Symmetric _≈_ → Decidable _≈_ → Antisymmetric _≈_ _≼_ →Total _≼_ → Trichotomous _≋_ _<_<-compare sym _≟_ antisym tot =Strict.<-compare sym (Conv.<-trichotomous _ _ sym _≟_ antisym tot)<-decidable : Decidable _≈_ → Decidable _≼_ → Decidable _<_<-decidable _≟_ _≼?_ =Core.decidable (no id) _≟_ (Conv.<-decidable _ _ _≟_ _≼?_)<-isStrictPartialOrder : IsPartialOrder _≈_ _≼_ →IsStrictPartialOrder _≋_ _<_<-isStrictPartialOrder po =Strict.<-isStrictPartialOrder(Conv.<-isStrictPartialOrder _ _ po)<-isStrictTotalOrder : Decidable _≈_ → IsTotalOrder _≈_ _≼_ →IsStrictTotalOrder _≋_ _<_<-isStrictTotalOrder dec tot =Strict.<-isStrictTotalOrder(Conv.<-isStrictTotalOrder₁ _ _ dec tot)<-strictPartialOrder : ∀ {a ℓ₁ ℓ₂} → Poset a ℓ₁ ℓ₂ →StrictPartialOrder _ _ _<-strictPartialOrder po = record{ isStrictPartialOrder = <-isStrictPartialOrder isPartialOrder} where open Poset po<-strictTotalOrder : ∀ {a ℓ₁ ℓ₂} → DecTotalOrder a ℓ₁ ℓ₂ →StrictTotalOrder _ _ _<-strictTotalOrder dtot = record{ isStrictTotalOrder = <-isStrictTotalOrder _≟_ isTotalOrder} where open DecTotalOrder dtot-------------------------------------------------------------------------- Non-strict lexicographic ordering.module _ {a ℓ₁ ℓ₂} {A : Set a} whereLex-≤ : (_≈_ : Rel A ℓ₁) (_≼_ : Rel A ℓ₂) → Rel (List A) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-≤ _≈_ _≼_ = Core.Lex ⊤ _≈_ (Conv._<_ _≈_ _≼_)≤-reflexive : ∀ _≈_ _≼_ → Pointwise _≈_ ⇒ Lex-≤ _≈_ _≼_≤-reflexive _≈_ _≼_ = Strict.≤-reflexive _≈_ (Conv._<_ _≈_ _≼_)-- Propertiesmodule _ {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂} whereprivate_≋_ = Pointwise _≈__≤_ = Lex-≤ _≈_ _≼_≤-antisymmetric : Symmetric _≈_ → Antisymmetric _≈_ _≼_ →Antisymmetric _≋_ _≤_≤-antisymmetric sym antisym =Core.antisymmetric sym(Conv.<-irrefl _≈_ _≼_)(Conv.<-asym _ _≼_ antisym)≤-transitive : IsPartialOrder _≈_ _≼_ → Transitive _≤_≤-transitive po =Core.transitive isEquivalence(Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)(Conv.<-trans _ _≼_ po)where open IsPartialOrder po≤-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ → _≤_ Respects₂ _≋_≤-resp₂ eq resp = Core.respects₂ eq (Conv.<-resp-≈ _ _ eq resp)≤-decidable : Decidable _≈_ → Decidable _≼_ → Decidable _≤_≤-decidable _≟_ _≼?_ =Core.decidable (yes tt) _≟_ (Conv.<-decidable _ _ _≟_ _≼?_)≤-total : Symmetric _≈_ → Decidable _≈_ → Antisymmetric _≈_ _≼_ →Total _≼_ → Total _≤_≤-total sym dec-≈ antisym tot =Strict.≤-total sym (Conv.<-trichotomous _ _ sym dec-≈ antisym tot)≤-isPreorder : IsPartialOrder _≈_ _≼_ → IsPreorder _≋_ _≤_≤-isPreorder po =Strict.≤-isPreorderisEquivalence (Conv.<-trans _ _ po)(Conv.<-resp-≈ _ _ isEquivalence ≤-resp-≈)where open IsPartialOrder po≤-isPartialOrder : IsPartialOrder _≈_ _≼_ → IsPartialOrder _≋_ _≤_≤-isPartialOrder po =Strict.≤-isPartialOrder(Conv.<-isStrictPartialOrder _ _ po)≤-isTotalOrder : Decidable _≈_ → IsTotalOrder _≈_ _≼_ →IsTotalOrder _≋_ _≤_≤-isTotalOrder dec tot =Strict.≤-isTotalOrder(Conv.<-isStrictTotalOrder₁ _ _ dec tot)≤-isDecTotalOrder : IsDecTotalOrder _≈_ _≼_ →IsDecTotalOrder _≋_ _≤_≤-isDecTotalOrder dtot =Strict.≤-isDecTotalOrder(Conv.<-isStrictTotalOrder₂ _ _ dtot)≤-preorder : ∀ {a ℓ₁ ℓ₂} → Poset a ℓ₁ ℓ₂ → Preorder _ _ _≤-preorder po = record{ isPreorder = ≤-isPreorder isPartialOrder} where open Poset po≤-partialOrder : ∀ {a ℓ₁ ℓ₂} → Poset a ℓ₁ ℓ₂ → Poset _ _ _≤-partialOrder po = record{ isPartialOrder = ≤-isPartialOrder isPartialOrder} where open Poset po≤-decTotalOrder : ∀ {a ℓ₁ ℓ₂} → DecTotalOrder a ℓ₁ ℓ₂ →DecTotalOrder _ _ _≤-decTotalOrder dtot = record{ isDecTotalOrder = ≤-isDecTotalOrder isDecTotalOrder} where open DecTotalOrder dtot
-------------------------------------------------------------------------- The Agda standard library---- Lexicographic ordering of lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Lex.Core whereopen import Data.Empty using (⊥; ⊥-elim)open import Data.Unit.Base using (⊤; tt)open import Data.Product.Base using (_×_; _,_; proj₁; proj₂; uncurry)open import Data.List.Base using (List; []; _∷_)open import Function.Base using (_∘_; flip; id)open import Level using (Level; _⊔_)open import Relation.Nullary.Negation using (¬_)open import Relation.Binary.Core using (Rel)open import Data.List.Relation.Binary.Pointwise.Baseusing (Pointwise; []; _∷_; head; tail)privatevariablea ℓ₁ ℓ₂ : Level-- The lexicographic ordering itself can be either strict or non-strict,-- depending on whether type P is inhabited.data Lex {A : Set a} (P : Set)(_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) :Rel (List A) (a ⊔ ℓ₁ ⊔ ℓ₂) wherebase : P → Lex P _≈_ _≺_ [] []halt : ∀ {y ys} → Lex P _≈_ _≺_ [] (y ∷ ys)this : ∀ {x xs y ys} (x≺y : x ≺ y) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys)next : ∀ {x xs y ys} (x≈y : x ≈ y)(xs<ys : Lex P _≈_ _≺_ xs ys) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys)-------------------------------------------------------------------------- Lexicographic orderings, using a strict ordering as the baseLex-< : {A : Set a} (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) →Rel (List A) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-< = Lex ⊥Lex-≤ : {A : Set a} (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) →Rel (List A) (a ⊔ ℓ₁ ⊔ ℓ₂)Lex-≤ = Lex ⊤
-------------------------------------------------------------------------- The Agda standard library---- Properties of the homogeneous infix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Infix.Homogeneous.Properties whereopen import Levelopen import Function.Base using (_∘′_)open import Relation.Binary.Core using (REL)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsDecPartialOrder)open import Data.List.Relation.Binary.Pointwise as Pointwise using (Pointwise)open import Data.List.Relation.Binary.Infix.Heterogeneousopen import Data.List.Relation.Binary.Infix.Heterogeneous.Propertiesprivatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B sisPreorder : IsPreorder R S → IsPreorder (Pointwise R) (Infix S)isPreorder po = record{ isEquivalence = Pointwise.isEquivalence PO.isEquivalence; reflexive = fromPointwise ∘′ Pointwise.map PO.reflexive; trans = trans PO.trans} where module PO = IsPreorder poisPartialOrder : IsPartialOrder R S → IsPartialOrder (Pointwise R) (Infix S)isPartialOrder po = record{ isPreorder = isPreorder PO.isPreorder; antisym = antisym PO.antisym} where module PO = IsPartialOrder poisDecPartialOrder : IsDecPartialOrder R S → IsDecPartialOrder (Pointwise R) (Infix S)isDecPartialOrder dpo = record{ isPartialOrder = isPartialOrder DPO.isPartialOrder; _≟_ = Pointwise.decidable DPO._≟_; _≤?_ = infix? DPO._≤?_} where module DPO = IsDecPartialOrder dpo
-------------------------------------------------------------------------- The Agda standard library---- An inductive definition of the heterogeneous infix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Infix.Heterogeneous whereopen import Levelopen import Relation.Binary.Core using (REL; _⇒_)open import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.Relation.Binary.Pointwiseusing (Pointwise)open import Data.List.Relation.Binary.Prefix.Heterogeneousas Prefix using (Prefix; []; _∷_; _++ᵖ_)privatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B smodule _ {A : Set a} {B : Set b} (R : REL A B r) wheredata Infix : REL (List A) (List B) (a ⊔ b ⊔ r) wherehere : ∀ {as bs} → Prefix R as bs → Infix as bsthere : ∀ {b as bs} → Infix as bs → Infix as (b ∷ bs)data View (as : List A) : List B → Set (a ⊔ b ⊔ r) whereMkView : ∀ pref {inf} → Pointwise R as inf → ∀ suff →View as (pref List.++ inf List.++ suff)infixr 5 _++ⁱ_ _ⁱ++__++ⁱ_ : ∀ xs {as bs} → Infix R as bs → Infix R as (xs ++ bs)[] ++ⁱ rs = rs(x ∷ xs) ++ⁱ rs = there (xs ++ⁱ rs)_ⁱ++_ : ∀ {as bs} → Infix R as bs → ∀ xs → Infix R as (bs ++ xs)here rs ⁱ++ xs = here (rs ++ᵖ xs)there rs ⁱ++ xs = there (rs ⁱ++ xs)map : R ⇒ S → Infix R ⇒ Infix Smap R⇒S (here pref) = here (Prefix.map R⇒S pref)map R⇒S (there inf) = there (map R⇒S inf)toView : ∀ {as bs} → Infix R as bs → View R as bstoView (here p) with inf Prefix.++ suff ← Prefix.toView p = MkView [] inf sufftoView (there p) with MkView pref inf suff ← toView p = MkView (_ ∷ pref) inf sufffromView : ∀ {as bs} → View R as bs → Infix R as bsfromView (MkView [] inf suff) = here (Prefix.fromView (inf Prefix.++ suff))fromView (MkView (a ∷ pref) inf suff) = there (fromView (MkView pref inf suff))
-------------------------------------------------------------------------- The Agda standard library---- Properties of the heterogeneous infix relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Infix.Heterogeneous.Properties whereopen import Levelopen import Data.Bool.Base using (true; false)open import Data.Empty using (⊥-elim)open import Data.List.Base as List using (List; []; _∷_; length; map; filter; replicate)open import Data.Nat.Base using (zero; suc; _≤_)import Data.Nat.Properties as ℕopen import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (case_of_; _$′_)open import Relation.Nullary.Decidable using (yes; no; does; map′; _⊎-dec_)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Unary as U using (Pred)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Definitions using (Decidable; Trans; Antisym)open import Relation.Binary.PropositionalEquality.Core using (_≢_; refl; cong)open import Data.List.Relation.Binary.Pointwise.Base as Pointwise using (Pointwise)open import Data.List.Relation.Binary.Infix.Heterogeneousopen import Data.List.Relation.Binary.Prefix.Heterogeneousas Prefix using (Prefix; []; _∷_)import Data.List.Relation.Binary.Prefix.Heterogeneous.Properties as Prefixopen import Data.List.Relation.Binary.Suffix.Heterogeneousas Suffix using (Suffix; here; there)privatevariablea b r s : LevelA : Set aB : Set bR : REL A B rS : REL A B s-------------------------------------------------------------------------- Conversion functionsfromPointwise : ∀ {as bs} → Pointwise R as bs → Infix R as bsfromPointwise pw = here (Prefix.fromPointwise pw)fromSuffix : ∀ {as bs} → Suffix R as bs → Infix R as bsfromSuffix (here pw) = fromPointwise pwfromSuffix (there p) = there (fromSuffix p)module _ {c t} {C : Set c} {T : REL A C t} wherefromPrefixSuffix : Trans R S T → Trans (Prefix R) (Suffix S) (Infix T)fromPrefixSuffix tr p (here q) = here (Prefix.trans tr p (Prefix.fromPointwise q))fromPrefixSuffix tr p (there q) = there (fromPrefixSuffix tr p q)fromSuffixPrefix : Trans R S T → Trans (Suffix R) (Prefix S) (Infix T)fromSuffixPrefix tr (here p) q = here (Prefix.trans tr (Prefix.fromPointwise p) q)fromSuffixPrefix tr (there p) (_ ∷ q) = there (fromSuffixPrefix tr p q)∷⁻ : ∀ {as b bs} → Infix R as (b ∷ bs) → Prefix R as (b ∷ bs) ⊎ Infix R as bs∷⁻ (here pref) = inj₁ pref∷⁻ (there inf) = inj₂ inf-------------------------------------------------------------------------- lengthlength-mono : ∀ {as bs} → Infix R as bs → length as ≤ length bslength-mono (here pref) = Prefix.length-mono preflength-mono (there p) = ℕ.m≤n⇒m≤1+n (length-mono p)-------------------------------------------------------------------------- As an ordermodule _ {c t} {C : Set c} {T : REL A C t} wherePrefix-Infix-trans : Trans R S T → Trans (Prefix R) (Infix S) (Infix T)Prefix-Infix-trans tr p (here q) = here (Prefix.trans tr p q)Prefix-Infix-trans tr p (there q) = there (Prefix-Infix-trans tr p q)Infix-Prefix-trans : Trans R S T → Trans (Infix R) (Prefix S) (Infix T)Infix-Prefix-trans tr (here p) q = here (Prefix.trans tr p q)Infix-Prefix-trans tr (there p) (_ ∷ q) = there (Infix-Prefix-trans tr p q)Suffix-Infix-trans : Trans R S T → Trans (Suffix R) (Infix S) (Infix T)Suffix-Infix-trans tr p (here q) = fromSuffixPrefix tr p qSuffix-Infix-trans tr p (there q) = there (Suffix-Infix-trans tr p q)Infix-Suffix-trans : Trans R S T → Trans (Infix R) (Suffix S) (Infix T)Infix-Suffix-trans tr p (here q) = Infix-Prefix-trans tr p (Prefix.fromPointwise q)Infix-Suffix-trans tr p (there q) = there (Infix-Suffix-trans tr p q)trans : Trans R S T → Trans (Infix R) (Infix S) (Infix T)trans tr p (here q) = Infix-Prefix-trans tr p qtrans tr p (there q) = there (trans tr p q)antisym : Antisym R S T → Antisym (Infix R) (Infix S) (Pointwise T)antisym asym (here p) (here q) = Prefix.antisym asym p qantisym asym {i = a ∷ as} {j = bs} p@(here _) (there q)= ⊥-elim $′ ℕ.<-irrefl refl $′ begin-strictlength as <⟨ length-mono p ⟩length bs ≤⟨ length-mono q ⟩length as ∎ where open ℕ.≤-Reasoningantisym asym {i = as} {j = b ∷ bs} (there p) q@(here _)= ⊥-elim $′ ℕ.<-irrefl refl $′ begin-strictlength bs <⟨ length-mono q ⟩length as ≤⟨ length-mono p ⟩length bs ∎ where open ℕ.≤-Reasoningantisym asym {i = a ∷ as} {j = b ∷ bs} (there p) (there q)= ⊥-elim $′ ℕ.<-irrefl refl $′ begin-strictlength as <⟨ length-mono p ⟩length bs <⟨ length-mono q ⟩length as ∎ where open ℕ.≤-Reasoning-------------------------------------------------------------------------- mapmodule _ {c d r} {C : Set c} {D : Set d} {R : REL C D r} wheremap⁺ : ∀ {as bs} (f : A → C) (g : B → D) →Infix (λ a b → R (f a) (g b)) as bs →Infix R (List.map f as) (List.map g bs)map⁺ f g (here p) = here (Prefix.map⁺ f g p)map⁺ f g (there p) = there (map⁺ f g p)map⁻ : ∀ {as bs} (f : A → C) (g : B → D) →Infix R (List.map f as) (List.map g bs) →Infix (λ a b → R (f a) (g b)) as bsmap⁻ {bs = []} f g (here p) = here (Prefix.map⁻ f g p)map⁻ {bs = b ∷ bs} f g (here p) = here (Prefix.map⁻ f g p)map⁻ {bs = b ∷ bs} f g (there p) = there (map⁻ f g p)-------------------------------------------------------------------------- filtermodule _ {p q} {P : Pred A p} {Q : Pred B q} (P? : U.Decidable P) (Q? : U.Decidable Q)(P⇒Q : ∀ {a b} → P a → Q b) (Q⇒P : ∀ {a b} → Q b → P a)wherefilter⁺ : ∀ {as bs} → Infix R as bs → Infix R (filter P? as) (filter Q? bs)filter⁺ (here p) = here (Prefix.filter⁺ P? Q? (λ _ → P⇒Q) (λ _ → Q⇒P) p)filter⁺ {bs = b ∷ bs} (there p) with does (Q? b)... | true = there (filter⁺ p)... | false = filter⁺ p-------------------------------------------------------------------------- replicatereplicate⁺ : ∀ {m n a b} → m ≤ n → R a b →Infix R (replicate m a) (replicate n b)replicate⁺ m≤n r = here (Prefix.replicate⁺ m≤n r)replicate⁻ : ∀ {m n a b} → m ≢ 0 →Infix R (replicate m a) (replicate n b) → R a breplicate⁻ {m = m} {n = zero} m≢0 (here p) = Prefix.replicate⁻ m≢0 preplicate⁻ {m = m} {n = suc n} m≢0 (here p) = Prefix.replicate⁻ m≢0 preplicate⁻ {m = m} {n = suc n} m≢0 (there p) = replicate⁻ m≢0 p-------------------------------------------------------------------------- decidabilityinfix? : Decidable R → Decidable (Infix R)infix? R? [] [] = yes (here [])infix? R? (a ∷ as) [] = no (λ where (here ()))infix? R? as bbs@(_ ∷ bs) =map′ [ here , there ]′ ∷⁻(Prefix.prefix? R? as bbs ⊎-dec infix? R? as bs)
-------------------------------------------------------------------------- The Agda standard library---- Pointwise equality over lists parameterised by a setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Equality.Setoid {a ℓ} (S : Setoid a ℓ) whereopen import Algebra.Core using (Op₂)open import Data.Fin.Base using (Fin)open import Data.List.Base using (List; length; map; foldr; _++_; concat;tabulate; filter; _ʳ++_; reverse)open import Data.List.Relation.Binary.Pointwise as PW using (Pointwise)open import Data.List.Relation.Unary.Unique.Setoid S using (Unique)open import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (_⇒_; _Preserves_⟶_) renaming (Rel to Rel₂)open import Relation.Binary.Definitions using (Transitive; Symmetric; Reflexive; _Respects_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Properties.Setoid S using (≉-resp₂)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Unary as U using (Pred)open Setoid S renaming (Carrier to A)privatevariablep q : Level-------------------------------------------------------------------------- Definition of equality------------------------------------------------------------------------infix 4 _≋__≋_ : Rel₂ (List A) (a ⊔ ℓ)_≋_ = Pointwise _≈_open PW publicusing ([]; _∷_)-------------------------------------------------------------------------- Relational properties------------------------------------------------------------------------≋-refl : Reflexive _≋_≋-refl = PW.refl refl≋-reflexive : _≡_ ⇒ _≋_≋-reflexive ≡.refl = ≋-refl≋-sym : Symmetric _≋_≋-sym = PW.symmetric sym≋-trans : Transitive _≋_≋-trans = PW.transitive trans≋-isEquivalence : IsEquivalence _≋_≋-isEquivalence = PW.isEquivalence isEquivalence≋-setoid : Setoid _ _≋-setoid = PW.setoid S-------------------------------------------------------------------------- Relationships to predicates------------------------------------------------------------------------open PW publicusing () renaming( Any-resp-Pointwise to Any-resp-≋; All-resp-Pointwise to All-resp-≋; AllPairs-resp-Pointwise to AllPairs-resp-≋)Unique-resp-≋ : Unique Respects _≋_Unique-resp-≋ = AllPairs-resp-≋ ≉-resp₂-------------------------------------------------------------------------- List operations-------------------------------------------------------------------------------------------------------------------------------------------------- length≋-length : ∀ {xs ys} → xs ≋ ys → length xs ≡ length ys≋-length = PW.Pointwise-length-------------------------------------------------------------------------- mapmodule _ {b ℓ₂} (T : Setoid b ℓ₂) whereopen Setoid T using () renaming (_≈_ to _≈′_)private_≋′_ = Pointwise _≈′_map⁺ : ∀ {f} → f Preserves _≈_ ⟶ _≈′_ →∀ {xs ys} → xs ≋ ys → map f xs ≋′ map f ysmap⁺ {f} pres xs≋ys = PW.map⁺ f f (PW.map pres xs≋ys)-------------------------------------------------------------------------- foldrfoldr⁺ : ∀ {_•_ : Op₂ A} {_◦_ : Op₂ A} →(∀ {w x y z} → w ≈ x → y ≈ z → (w • y) ≈ (x ◦ z)) →∀ {xs ys e f} → e ≈ f → xs ≋ ys →foldr _•_ e xs ≈ foldr _◦_ f ysfoldr⁺ ∙⇔◦ e≈f xs≋ys = PW.foldr⁺ ∙⇔◦ e≈f xs≋ys-------------------------------------------------------------------------- _++_++⁺ : ∀ {ws xs ys zs} → ws ≋ xs → ys ≋ zs → ws ++ ys ≋ xs ++ zs++⁺ = PW.++⁺++-cancelˡ : ∀ xs {ys zs} → xs ++ ys ≋ xs ++ zs → ys ≋ zs++-cancelˡ xs = PW.++-cancelˡ xs++-cancelʳ : ∀ {xs} ys zs → ys ++ xs ≋ zs ++ xs → ys ≋ zs++-cancelʳ = PW.++-cancelʳ-------------------------------------------------------------------------- concatconcat⁺ : ∀ {xss yss} → Pointwise _≋_ xss yss → concat xss ≋ concat yssconcat⁺ = PW.concat⁺-------------------------------------------------------------------------- tabulatemodule _ {n} {f g : Fin n → A}wheretabulate⁺ : (∀ i → f i ≈ g i) → tabulate f ≋ tabulate gtabulate⁺ = PW.tabulate⁺tabulate⁻ : tabulate f ≋ tabulate g → (∀ i → f i ≈ g i)tabulate⁻ = PW.tabulate⁻-------------------------------------------------------------------------- filtermodule _ {P : Pred A p} (P? : U.Decidable P) (resp : P Respects _≈_)wherefilter⁺ : ∀ {xs ys} → xs ≋ ys → filter P? xs ≋ filter P? ysfilter⁺ xs≋ys = PW.filter⁺ P? P? resp (resp ∘ sym) xs≋ys-------------------------------------------------------------------------- reverseʳ++⁺ : ∀{xs xs′ ys ys′} → xs ≋ xs′ → ys ≋ ys′ → xs ʳ++ ys ≋ xs′ ʳ++ ys′ʳ++⁺ = PW.ʳ++⁺reverse⁺ : ∀ {xs ys} → xs ≋ ys → reverse xs ≋ reverse ysreverse⁺ = PW.reverse⁺
-------------------------------------------------------------------------- The Agda standard library---- Properties of List modulo ≋------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Equality.Setoid.Properties{c ℓ} (S : Setoid c ℓ)whereopen import Algebra.Bundles using (Magma; Semigroup; Monoid)import Algebra.Structures as Structuresopen import Data.List.Base using (List; []; _++_)import Data.List.Properties as Listimport Data.List.Relation.Binary.Equality.Setoid as ≋open import Data.Product.Base using (_,_)open import Function.Base using (_∘_)open import Level using (_⊔_)open ≋ S using (_≋_; ≋-refl; ≋-reflexive; ≋-isEquivalence; ++⁺)open Structures _≋_ using (IsMagma; IsSemigroup; IsMonoid)-------------------------------------------------------------------------- The []-++-Monoid-- StructuresisMagma : IsMagma _++_isMagma = record{ isEquivalence = ≋-isEquivalence; ∙-cong = ++⁺}isSemigroup : IsSemigroup _++_isSemigroup = record{ isMagma = isMagma; assoc = λ xs ys zs → ≋-reflexive (List.++-assoc xs ys zs)}isMonoid : IsMonoid _++_ []isMonoid = record{ isSemigroup = isSemigroup; identity = (λ _ → ≋-refl) , ≋-reflexive ∘ List.++-identityʳ}-- Bundlesmagma : Magma c (c ⊔ ℓ)magma = record { isMagma = isMagma }semigroup : Semigroup c (c ⊔ ℓ)semigroup = record { isSemigroup = isSemigroup }monoid : Monoid c (c ⊔ ℓ)monoid = record { isMonoid = isMonoid }
-------------------------------------------------------------------------- The Agda standard library---- Pointwise equality over lists using propositional equality-------------------------------------------------------------------------- Note think carefully about using this module as pointwise-- propositional equality can usually be replaced with propositional-- equality.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (_⇒_)module Data.List.Relation.Binary.Equality.Propositional {a} {A : Set a} whereopen import Data.List.Baseimport Data.List.Relation.Binary.Equality.Setoid as SetoidEqualityopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)import Relation.Binary.PropositionalEquality.Properties as ≡-------------------------------------------------------------------------- Re-export everything from setoid equalityopen SetoidEquality (≡.setoid A) public-------------------------------------------------------------------------- ≋ is propositional≋⇒≡ : _≋_ ⇒ _≡_≋⇒≡ [] = refl≋⇒≡ (refl ∷ xs≈ys) = cong (_ ∷_) (≋⇒≡ xs≈ys)≡⇒≋ : _≡_ ⇒ _≋_≡⇒≋ refl = ≋-refl
-------------------------------------------------------------------------- The Agda standard library---- Pointwise decidable equality over lists parameterised by a setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)open import Relation.Binary.Structures using (IsDecEquivalence)open import Relation.Binary.Definitions using (Decidable)module Data.List.Relation.Binary.Equality.DecSetoid{a ℓ} (DS : DecSetoid a ℓ) whereimport Data.List.Relation.Binary.Equality.Setoid as SetoidEqualityimport Data.List.Relation.Binary.Pointwise as PWopen import Levelopen import Relation.Binary.Definitions using (Decidable)open DecSetoid DS-------------------------------------------------------------------------- Make all definitions from setoid equality availableopen SetoidEquality setoid public-------------------------------------------------------------------------- Additional propertiesinfix 4 _≋?__≋?_ : Decidable _≋__≋?_ = PW.decidable _≟_≋-isDecEquivalence : IsDecEquivalence _≋_≋-isDecEquivalence = PW.isDecEquivalence isDecEquivalence≋-decSetoid : DecSetoid a (a ⊔ ℓ)≋-decSetoid = PW.decSetoid DS
-------------------------------------------------------------------------- The Agda standard library---- Decidable pointwise equality over lists using propositional equality-------------------------------------------------------------------------- Note think carefully about using this module as pointwise-- propositional equality can usually be replaced with propositional-- equality.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Binary.Equality.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A) whereopen import Data.List.Base using (List)open import Data.List.Properties using (≡-dec)import Data.List.Relation.Binary.Equality.Propositional as PropositionalEqimport Data.List.Relation.Binary.Equality.DecSetoid as DecSetoidEqopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Publically re-export everything from decSetoid and propositional-- equalityopen PropositionalEq publicopen DecSetoidEq (decSetoid _≟_) publicusing (_≋?_; ≋-isDecEquivalence; ≋-decSetoid)-------------------------------------------------------------------------- Additional proofsinfix 4 _≡?__≡?_ : DecidableEquality (List A)_≡?_ = ≡-dec _≟_
-------------------------------------------------------------------------- The Agda standard library---- Pairs of lists that share no common elements (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.List.Relation.Binary.Disjoint.Setoid {c ℓ} (S : Setoid c ℓ) whereopen import Level using (_⊔_)open import Relation.Nullary.Negation using (¬_)open import Function.Base using (_∘_)open import Data.List.Base using (List; []; [_]; _∷_)open import Data.List.Relation.Unary.Any using (here; there)open import Data.Product.Base using (_×_; _,_)open Setoid S renaming (Carrier to A)open import Data.List.Membership.Setoid S using (_∈_; _∉_)-------------------------------------------------------------------------- DefinitionDisjoint : Rel (List A) (ℓ ⊔ c)Disjoint xs ys = ∀ {v} → ¬ (v ∈ xs × v ∈ ys)-------------------------------------------------------------------------- Operationscontractₗ : ∀ {x xs ys} → Disjoint (x ∷ xs) ys → Disjoint xs yscontractₗ x∷xs∩ys=∅ (v∈xs , v∈ys) = x∷xs∩ys=∅ (there v∈xs , v∈ys)contractᵣ : ∀ {xs y ys} → Disjoint xs (y ∷ ys) → Disjoint xs yscontractᵣ xs#y∷ys (v∈xs , v∈ys) = xs#y∷ys (v∈xs , there v∈ys)
-------------------------------------------------------------------------- The Agda standard library---- Properties of disjoint lists (setoid equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Disjoint.Setoid.Properties whereopen import Data.List.Baseopen import Data.List.Relation.Binary.Disjoint.Setoidimport Data.List.Relation.Unary.Any as Anyopen import Data.List.Relation.Unary.All as Allopen import Data.List.Relation.Unary.All.Properties using (¬Any⇒All¬)open import Data.List.Relation.Unary.Any.Properties using (++⁻)open import Data.Product.Base using (_,_)open import Data.Sum.Base using (inj₁; inj₂)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Symmetric)open import Relation.Nullary.Negation using (¬_)-------------------------------------------------------------------------- Relational properties------------------------------------------------------------------------module _ {c ℓ} (S : Setoid c ℓ) wheresym : Symmetric (Disjoint S)sym xs#ys (v∈ys , v∈xs) = xs#ys (v∈xs , v∈ys)-------------------------------------------------------------------------- Relationship with other predicates------------------------------------------------------------------------module _ {c ℓ} (S : Setoid c ℓ) whereopen Setoid SDisjoint⇒AllAll : ∀ {xs ys} → Disjoint S xs ys →All (λ x → All (λ y → ¬ x ≈ y) ys) xsDisjoint⇒AllAll xs#ys = All.map (¬Any⇒All¬ _)(All.tabulate (λ v∈xs v∈ys → xs#ys (Any.map reflexive v∈xs , v∈ys)))-------------------------------------------------------------------------- Introduction (⁺) and elimination (⁻) rules for list operations-------------------------------------------------------------------------- concatmodule _ {c ℓ} (S : Setoid c ℓ) whereconcat⁺ʳ : ∀ {vs xss} → All (Disjoint S vs) xss → Disjoint S vs (concat xss)concat⁺ʳ {xss = xs ∷ xss} (vs#xs ∷ vs#xss) (v∈vs , v∈xs++concatxss)with ++⁻ xs v∈xs++concatxss... | inj₁ v∈xs = vs#xs (v∈vs , v∈xs)... | inj₂ v∈xss = concat⁺ʳ vs#xss (v∈vs , v∈xss)
-------------------------------------------------------------------------- The Agda standard library---- Pairs of lists that share no common elements (propositional equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.Disjoint.Propositional{a} {A : Set a} whereopen import Relation.Binary.PropositionalEquality.Properties using (setoid)open import Data.List.Relation.Binary.Disjoint.Setoid as DisjointUnique-------------------------------------------------------------------------- Re-export the contents of setoid uniquenessopen DisjointUnique (setoid A) public
-------------------------------------------------------------------------- The Agda standard library---- Decidability of the disjoint relation over setoid equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)module Data.List.Relation.Binary.Disjoint.DecSetoid {c ℓ} (S : DecSetoid c ℓ) whereopen import Data.Product.Base using (_,_)open import Data.List.Relation.Unary.Any using (map)open import Data.List.Relation.Unary.All using (all?; lookupₛ)open import Data.List.Relation.Unary.All.Properties using (¬All⇒Any¬)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary using (yes; no; decidable-stable)open DecSetoid Sopen import Data.List.Relation.Binary.Equality.DecSetoid Sopen import Data.List.Relation.Binary.Disjoint.Setoid setoid publicopen import Data.List.Membership.DecSetoid Sdisjoint? : Decidable Disjointdisjoint? xs ys with all? (_∉? ys) xs... | yes xs♯ys = yes λ (v∈ , v∈′) →lookupₛ setoid (λ x≈y ∉ys ∈ys → ∉ys (map (trans x≈y) ∈ys)) xs♯ys v∈ v∈′... | no ¬xs♯ys = let (x , x∈ , ¬∉ys) = find (¬All⇒Any¬ (_∉? _) _ ¬xs♯ys) inno λ p → p (x∈ , decidable-stable (_ ∈? _) ¬∉ys)
-------------------------------------------------------------------------- The Agda standard library---- Decidability of the disjoint relation over propositional equality.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Relation.Binary.Disjoint.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A)where-------------------------------------------------------------------------- Re-export core definitions and operationsopen import Data.List.Relation.Binary.Disjoint.Propositional {A = A} publicopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)open import Data.List.Relation.Binary.Disjoint.DecSetoid (decSetoid _≟_) publicusing (disjoint?)
-------------------------------------------------------------------------- The Agda standard library---- Bag and set equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Relation.Binary.BagAndSetEquality whereopen import Algebra.Bundles using (CommutativeMonoid)open import Algebra.Definitions using (Idempotent)open import Algebra.Structures.Biased using (isCommutativeMonoidˡ)open import Effect.Monad using (RawMonad)open import Data.Empty using (⊥; ⊥-elim)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Baseusing (List; []; _∷_; map; _++_; concat; [_]; lookup; length)open import Data.List.Effectful using (monad; module Applicative; module MonadProperties)import Data.List.Properties as Listopen import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.List.Relation.Unary.Any.Propertiesusing (∷↔; map↔; Any-cong; ++↔; concat↔; >>=↔; ++↔++; ⊎↔; ⊥↔Any[])open import Data.List.Membership.Propositional using (_∈_)open import Data.List.Membership.Propositional.Propertiesusing (∈-∃++)open import Data.List.Relation.Binary.Subset.Propositional.Propertiesusing (⊆-preorder)open import Data.List.Relation.Binary.Permutation.Propositionalusing (_↭_; ↭-sym; refl; module PermutationReasoning)open import Data.List.Relation.Binary.Permutation.Propositional.Propertiesusing (∈-resp-↭; ∈-resp-[σ⁻¹∘σ]; ↭-sym-involutive; shift; ++-comm)open import Data.Product.Base as Product using (∃; _,_; proj₁; proj₂; _×_)import Data.Product.Function.Dependent.Propositional as Σopen import Data.Sum.Base as Sum using (_⊎_; [_,_]′; inj₁; inj₂)open import Data.Sum.Properties using (inj₂-injective; inj₁-injective)open import Data.Sum.Function.Propositional using (_⊎-cong_)open import Data.Unit.Polymorphic.Base using (⊤)open import Function.Base using (_∘_; _$_; id; _⟨_⟩_; case_of_)open import Function.Bundles using (_↔_; Inverse; Equivalence; mk↔ₛ′; mk⇔)open import Function.Related.Propositional as Relatedusing (↔⇒; ⌊_⌋; ⌊_⌋→; ⇒→; K-refl; SK-sym)open import Function.Related.TypeIsomorphisms using (×-identityʳ; ∃∃↔∃∃)open import Function.Properties.Inverse using (↔-sym; ↔-trans; to-from)open import Level using (Level)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Definitions using (Trans)open import Relation.Binary.Bundles using (Preorder; Setoid)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Relation.Binary.Reasoning.Preorder as ≲-Reasoningopen import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; _≗_; refl)open import Relation.Binary.PropositionalEquality.Properties as ≡using (module ≡-Reasoning)open import Relation.Binary.Reasoning.Syntaxopen import Relation.Nullary.Negation.Core using (¬_)privatevariablea b : LevelA B : Set ax y : Aws xs ys zs : List A-------------------------------------------------------------------------- Definitionsopen Related public using (Kind; SymmetricKind) renaming( implication to subset; reverseImplication to superset; equivalence to set; injection to subbag; reverseInjection to superbag; bijection to bag)[_]-Order : Kind → Set a → Preorder _ _ _[ k ]-Order A = Related.InducedPreorder₂ {A = A} k _∈_[_]-Equality : SymmetricKind → Set a → Setoid _ _[ k ]-Equality A = Related.InducedEquivalence₂ {A = A} k _∈_infix 4 _∼[_]__∼[_]_ : ∀ {a} {A : Set a} → List A → Kind → List A → Set __∼[_]_ {A = A} xs k ys = Preorder._≲_ ([ k ]-Order A) xs ysprivatemodule Eq {k a} {A : Set a} = Setoid ([ k ]-Equality A)module Ord {k a} {A : Set a} = Preorder ([ k ]-Order A)open module ListMonad {ℓ} = RawMonad (monad {ℓ = ℓ})module MP = MonadProperties-------------------------------------------------------------------------- Bag equality implies the other relations.bag-=⇒ : ∀ {k} → xs ∼[ bag ] ys → xs ∼[ k ] ysbag-=⇒ xs≈ys = ↔⇒ xs≈ys-------------------------------------------------------------------------- "Equational" reasoning for _⊆_ along with an additional relatednessmodule ⊆-Reasoning {A : Set a} whereprivate module Base = ≲-Reasoning (⊆-preorder A)open Base publichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨; step-∼; step-≲)renaming (≲-go to ⊆-go)open begin-membership-syntax _IsRelatedTo_ _∈_ (λ x → begin x) publicopen ⊆-syntax _IsRelatedTo_ _IsRelatedTo_ ⊆-go publicmodule _ {k : Related.ForwardKind} where∼-go : Trans _∼[ ⌊ k ⌋→ ]_ _IsRelatedTo_ _IsRelatedTo_∼-go eq = ⊆-go (⇒→ eq)open ∼-syntax _IsRelatedTo_ _IsRelatedTo_ ∼-go public-------------------------------------------------------------------------- Congruence lemmas-------------------------------------------------------------------------- _∷_module _ {k} {x y : A} {xs ys} where∷-cong : x ≡ y → xs ∼[ k ] ys → x ∷ xs ∼[ k ] y ∷ ys∷-cong refl xs≈ys {y} = beginy ∈ x ∷ xs ↔⟨ SK-sym $ ∷↔ (y ≡_) ⟩(y ≡ x ⊎ y ∈ xs) ∼⟨ K-refl ⊎-cong xs≈ys ⟩(y ≡ x ⊎ y ∈ ys) ↔⟨ ∷↔ (y ≡_) ⟩y ∈ x ∷ ys ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- mapmodule _ {k} {f g : A → B} {xs ys} wheremap-cong : f ≗ g → xs ∼[ k ] ys → map f xs ∼[ k ] map g ysmap-cong f≗g xs≈ys {x} = beginx ∈ map f xs ↔⟨ SK-sym $ map↔ ⟩Any (λ y → x ≡ f y) xs ∼⟨ Any-cong (↔⇒ ∘ helper) xs≈ys ⟩Any (λ y → x ≡ g y) ys ↔⟨ map↔ ⟩x ∈ map g ys ∎whereopen Related.EquationalReasoninghelper : ∀ y → x ≡ f y ↔ x ≡ g yhelper y = mk↔ₛ′(λ x≡fy → ≡.trans x≡fy ( f≗g y))(λ x≡gy → ≡.trans x≡gy (≡.sym $ f≗g y))(λ { ≡.refl → ≡.trans-symˡ (f≗g y) })λ { ≡.refl → ≡.trans-symʳ (f≗g y) }-------------------------------------------------------------------------- _++_module _ {k} {xs₁ xs₂ ys₁ ys₂ : List A} where++-cong : xs₁ ∼[ k ] xs₂ → ys₁ ∼[ k ] ys₂ →xs₁ ++ ys₁ ∼[ k ] xs₂ ++ ys₂++-cong xs₁≈xs₂ ys₁≈ys₂ {x} = beginx ∈ xs₁ ++ ys₁ ↔⟨ SK-sym $ ++↔ ⟩(x ∈ xs₁ ⊎ x ∈ ys₁) ∼⟨ xs₁≈xs₂ ⊎-cong ys₁≈ys₂ ⟩(x ∈ xs₂ ⊎ x ∈ ys₂) ↔⟨ ++↔ ⟩x ∈ xs₂ ++ ys₂ ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- concatmodule _ {k} {xss yss : List (List A)} whereconcat-cong : xss ∼[ k ] yss → concat xss ∼[ k ] concat yssconcat-cong xss≈yss {x} = beginx ∈ concat xss ↔⟨ SK-sym concat↔ ⟩Any (Any (x ≡_)) xss ∼⟨ Any-cong (λ _ → _ ∎) xss≈yss ⟩Any (Any (x ≡_)) yss ↔⟨ concat↔ ⟩x ∈ concat yss ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _>>=_module _ {k} {A B : Set a} {xs ys} {f g : A → List B} where>>=-cong : xs ∼[ k ] ys → (∀ x → f x ∼[ k ] g x) →(xs >>= f) ∼[ k ] (ys >>= g)>>=-cong xs≈ys f≈g {x} = beginx ∈ (xs >>= f) ↔⟨ SK-sym >>=↔ ⟩Any (λ y → x ∈ f y) xs ∼⟨ Any-cong (λ x → f≈g x) xs≈ys ⟩Any (λ y → x ∈ g y) ys ↔⟨ >>=↔ ⟩x ∈ (ys >>= g) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _⊛_module _ {k} {A B : Set a} {fs gs : List (A → B)} {xs ys} where⊛-cong : fs ∼[ k ] gs → xs ∼[ k ] ys → (fs ⊛ xs) ∼[ k ] (gs ⊛ ys)⊛-cong fs≈gs xs≈ys {x} = beginx ∈ (fs ⊛ xs)≡⟨ ≡.cong (x ∈_) (Applicative.unfold-⊛ fs xs) ⟩x ∈ (fs >>= λ f → xs >>= λ x → pure (f x))∼⟨ >>=-cong fs≈gs (λ f → >>=-cong xs≈ys λ x → K-refl) ⟩x ∈ (gs >>= λ g → ys >>= λ y → pure (g y))≡⟨ ≡.cong (x ∈_) (Applicative.unfold-⊛ gs ys) ⟨x ∈ (gs ⊛ ys) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _⊗_module _ {ℓ k} {A B : Set ℓ} {xs₁ xs₂ : List A} {ys₁ ys₂ : List B} where⊗-cong : xs₁ ∼[ k ] xs₂ → ys₁ ∼[ k ] ys₂ →(xs₁ ⊗ ys₁) ∼[ k ] (xs₂ ⊗ ys₂)⊗-cong xs₁≈xs₂ ys₁≈ys₂ =⊛-cong (map-cong (λ _ → refl) xs₁≈xs₂) ys₁≈ys₂-------------------------------------------------------------------------- Other properties-- _++_ and [] form a commutative monoid, with either bag or set-- equality as the underlying equality.commutativeMonoid : SymmetricKind → Set a → CommutativeMonoid _ _commutativeMonoid {a} k A = record{ Carrier = List A; _≈_ = _∼[ ⌊ k ⌋ ]_; _∙_ = _++_; ε = []; isCommutativeMonoid = isCommutativeMonoidˡ record{ isSemigroup = record{ isMagma = record{ isEquivalence = Eq.isEquivalence; ∙-cong = ++-cong}; assoc = λ xs ys zs →Eq.reflexive (List.++-assoc xs ys zs)}; identityˡ = λ xs → K-refl; comm = λ xs ys → ↔⇒ (++↔++ xs ys)}}where open Related.EquationalReasoning-- The only list which is bag or set equal to the empty list (or a-- subset or subbag of the list) is the empty list itself.empty-unique : ∀ {k} → xs ∼[ ⌊ k ⌋→ ] [] → xs ≡ []empty-unique {xs = []} _ = reflempty-unique {xs = _ ∷ _} ∷∼[] with () ← ⇒→ ∷∼[] (here refl)-- _++_ is idempotent (under set equality).++-idempotent : Idempotent {A = List A} _∼[ set ]_ _++_++-idempotent xs {x} =x ∈ xs ++ xs∼⟨ mk⇔ ([ id , id ]′ ∘ (Inverse.from $ ++↔)) (Inverse.to ++↔ ∘ inj₁) ⟩x ∈ xs ∎where open Related.EquationalReasoning-- The list monad's bind distributes from the left over _++_.>>=-left-distributive :∀ (xs : List A) {f g : A → List B} →(xs >>= λ x → f x ++ g x) ∼[ bag ] (xs >>= f) ++ (xs >>= g)>>=-left-distributive {ℓ} xs {f} {g} {y} =y ∈ (xs >>= λ x → f x ++ g x) ↔⟨ SK-sym $ >>=↔ ⟩Any (λ x → y ∈ f x ++ g x) xs ↔⟨ SK-sym (Any-cong (λ _ → ++↔) (_ ∎)) ⟩Any (λ x → y ∈ f x ⊎ y ∈ g x) xs ↔⟨ SK-sym $ ⊎↔ ⟩(Any (λ x → y ∈ f x) xs ⊎ Any (λ x → y ∈ g x) xs) ↔⟨ >>=↔ ⟨ _⊎-cong_ ⟩ >>=↔ ⟩(y ∈ (xs >>= f) ⊎ y ∈ (xs >>= g)) ↔⟨ ++↔ ⟩y ∈ (xs >>= f) ++ (xs >>= g) ∎where open Related.EquationalReasoning-- The same applies to _⊛_.⊛-left-distributive :∀ (fs : List (A → B)) xs₁ xs₂ →(fs ⊛ (xs₁ ++ xs₂)) ∼[ bag ] (fs ⊛ xs₁) ++ (fs ⊛ xs₂)⊛-left-distributive {B = B} fs xs₁ xs₂ = beginfs ⊛ (xs₁ ++ xs₂) ≡⟨ Applicative.unfold-⊛ fs (xs₁ ++ xs₂) ⟩(fs >>= λ f → xs₁ ++ xs₂ >>= pure ∘ f) ≡⟨ (MP.cong (refl {x = fs}) λ f →MP.right-distributive xs₁ xs₂ (pure ∘ f)) ⟩(fs >>= λ f → (xs₁ >>= pure ∘ f) ++(xs₂ >>= pure ∘ f)) ≈⟨ >>=-left-distributive fs ⟩(fs >>= λ f → xs₁ >>= pure ∘ f) ++(fs >>= λ f → xs₂ >>= pure ∘ f) ≡⟨ ≡.cong₂ _++_ (Applicative.unfold-⊛ fs xs₁) (Applicative.unfold-⊛ fs xs₂) ⟨(fs ⊛ xs₁) ++ (fs ⊛ xs₂) ∎where open ≈-Reasoning ([ bag ]-Equality B)private-- If x ∷ xs is set equal to x ∷ ys, then xs and ys are not-- necessarily set equal.¬-drop-cons : ∀ {x : A} →¬ (∀ {xs ys} → x ∷ xs ∼[ set ] x ∷ ys → xs ∼[ set ] ys)¬-drop-cons {x = x} drop-cons with Equivalence.to x∼[] (here refl)wherex,x≈x : (x ∷ x ∷ []) ∼[ set ] [ x ]x,x≈x = ++-idempotent [ x ]x∼[] : [ x ] ∼[ set ] []x∼[] = drop-cons x,x≈x... | ()-- However, the corresponding property does hold for bag equality.drop-cons : ∀ {x : A} {xs ys} → x ∷ xs ∼[ bag ] x ∷ ys → xs ∼[ bag ] ysdrop-cons {x = x} {xs} {ys} x∷xs≈x∷ys =⊎-left-cancellative(∼→⊎↔⊎ x∷xs≈x∷ys)(lemma x∷xs≈x∷ys)(lemma (SK-sym x∷xs≈x∷ys))where-- TODO: Some of the code below could perhaps be exposed to users.-- List membership can be expressed as "there is an index which-- points to the element".∈-index : ∀ {z} (xs : List A) → z ∈ xs ↔ ∃ λ i → z ≡ lookup xs i∈-index {z = z} [] =z ∈ [] ↔⟨ SK-sym ⊥↔Any[] ⟩⊥ ↔⟨ mk↔ₛ′ (λ ()) (λ { (() , _) }) (λ { (() , _) }) (λ ()) ⟩(∃ λ (i : Fin 0) → z ≡ lookup [] i) ∎whereopen Related.EquationalReasoning∈-index {z = z} (x ∷ xs) =z ∈ x ∷ xs ↔⟨ SK-sym (∷↔ _) ⟩(z ≡ x ⊎ z ∈ xs) ↔⟨ K-refl ⊎-cong ∈-index xs ⟩(z ≡ x ⊎ ∃ λ i → z ≡ lookup xs i) ↔⟨ mk↔ₛ′ (λ { (inj₁ p) → zero , p; (inj₂ (i , p)) → suc i , p })(λ { (zero , p) → inj₁ p; (suc i , p) → inj₂ (i , p) })(λ { (zero , _) → refl; (suc _ , _) → refl })(λ { (inj₁ _) → refl; (inj₂ _) → refl }) ⟩(∃ λ i → z ≡ lookup (x ∷ xs) i) ∎whereopen Related.EquationalReasoning-- The index which points to the element.index-of : ∀ {a} {A : Set a} {z} {xs : List A} →z ∈ xs → Fin (length xs)index-of = proj₁ ∘ (Inverse.to (∈-index _))-- The type ∃ λ z → z ∈ xs is isomorphic to Fin n, where n is the-- length of xs.---- Thierry Coquand pointed out that (a variant of) this statement is-- a generalisation of the fact that singletons are contractible.Fin-length : ∀ {a} {A : Set a}(xs : List A) → (∃ λ z → z ∈ xs) ↔ Fin (length xs)Fin-length xs =(∃ λ z → z ∈ xs) ↔⟨ Σ.cong K-refl (∈-index xs) ⟩(∃ λ z → ∃ λ i → z ≡ lookup xs i) ↔⟨ ∃∃↔∃∃ _ ⟩(∃ λ i → ∃ λ z → z ≡ lookup xs i) ↔⟨ Σ.cong K-refl (mk↔ₛ′ _ (λ _ → _ , refl) (λ _ → refl) (λ { (_ , refl) → refl })) ⟩(Fin (length xs) × ⊤) ↔⟨ ×-identityʳ _ _ ⟩Fin (length xs) ∎whereopen Related.EquationalReasoning-- From this lemma we get that lists which are bag equivalent have-- related lengths.Fin-length-cong : ∀ {a} {A : Set a} {xs ys : List A} →xs ∼[ bag ] ys → Fin (length xs) ↔ Fin (length ys)Fin-length-cong {xs = xs} {ys} xs≈ys =Fin (length xs) ↔⟨ SK-sym $ Fin-length xs ⟩∃ (λ z → z ∈ xs) ↔⟨ Σ.cong K-refl xs≈ys ⟩∃ (λ z → z ∈ ys) ↔⟨ Fin-length ys ⟩Fin (length ys) ∎whereopen Related.EquationalReasoning-- The index-of function commutes with applications of certain-- inverses.index-of-commutes :∀ {a} {A : Set a} {z : A} {xs ys} →(xs≈ys : xs ∼[ bag ] ys) (p : z ∈ xs) →index-of (Inverse.to xs≈ys p) ≡Inverse.to (Fin-length-cong xs≈ys) (index-of p)index-of-commutes {z = z} {xs} {ys} xs≈ys p =index-of (to xs≈ys p) ≡⟨ lemma z p ⟩index-of (to xs≈ys (proj₂(from (Fin-length xs) (to (Fin-length xs) (z , p))))) ≡⟨⟩index-of (proj₂ (Product.map₂ (to xs≈ys)(from (Fin-length xs) (to (Fin-length xs) (z , p))))) ≡⟨⟩to (Fin-length ys) (Product.map₂ (to xs≈ys)(from (Fin-length xs) (index-of p))) ≡⟨⟩to (Fin-length-cong xs≈ys) (index-of p) ∎whereopen ≡-Reasoningopen Inverselemma :∀ z p →index-of (to xs≈ys p) ≡index-of (to xs≈ys (proj₂(from (Fin-length xs) (to (Fin-length xs) (z , p)))))lemma z p with to (Fin-length xs) (z , p)| strictlyInverseʳ (Fin-length xs) (z , p)lemma .(lookup xs i) .(from (∈-index xs) (i , refl)) | i | refl =refl-- Bag equivalence isomorphisms preserve index equality. Note that-- this means that, even if the underlying equality is proof-- relevant, a bag equivalence isomorphism cannot map two distinct-- proofs, that point to the same position, to different positions.index-equality-preserved :∀ {a} {A : Set a} {z : A} {xs ys} {p q : z ∈ xs}(xs≈ys : xs ∼[ bag ] ys) →index-of p ≡ index-of q →index-of (Inverse.to xs≈ys p) ≡index-of (Inverse.to xs≈ys q)index-equality-preserved {p = p} {q} xs≈ys eq =index-of (Inverse.to xs≈ys p) ≡⟨ index-of-commutes xs≈ys p ⟩Inverse.to (Fin-length-cong xs≈ys) (index-of p) ≡⟨ ≡.cong (Inverse.to (Fin-length-cong xs≈ys)) eq ⟩Inverse.to (Fin-length-cong xs≈ys) (index-of q) ≡⟨ ≡.sym $ index-of-commutes xs≈ys q ⟩index-of (Inverse.to xs≈ys q) ∎whereopen ≡-Reasoning-- The old inspect idiom.inspect : ∀ {a} {A : Set a} (x : A) → ∃ (x ≡_)inspect x = x , refl-- A function is "well-behaved" if any "left" element which is the-- image of a "right" element is in turn not mapped to another-- "left" element.Well-behaved : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} →(A ⊎ B → A ⊎ C) → Set _Well-behaved f =∀ {b a a′} → f (inj₂ b) ≡ inj₁ a → f (inj₁ a) ≢ inj₁ a′-- The type constructor _⊎_ is left cancellative for certain-- well-behaved inverses.⊎-left-cancellative :∀ {a b c} {A : Set a} {B : Set b} {C : Set c}(f : (A ⊎ B) ↔ (A ⊎ C)) →Well-behaved (Inverse.to f) →Well-behaved (Inverse.from f) →B ↔ C⊎-left-cancellative {A = A} = λ inv to-hyp from-hyp → mk↔ₛ′(g (to inv) to-hyp)(g (from inv) from-hyp)(g∘g (SK-sym inv) from-hyp to-hyp)(g∘g inv to-hyp from-hyp)whereopen Inversemodule _{a b c} {A : Set a} {B : Set b} {C : Set c}(f : A ⊎ B → A ⊎ C)(hyp : Well-behaved f)wheremutualg : B → Cg b = g′ (inspect (f (inj₂ b)))g′ : ∀ {b} → ∃ (f (inj₂ b) ≡_) → Cg′ (inj₂ c , _) = cg′ (inj₁ a , eq) = g″ eq (inspect (f (inj₁ a)))g″ : ∀ {a b} →f (inj₂ b) ≡ inj₁ a → ∃ (f (inj₁ a) ≡_) → Cg″ _ (inj₂ c , _) = cg″ eq₁ (inj₁ _ , eq₂) = ⊥-elim $ hyp eq₁ eq₂g∘g : ∀ {b c} {B : Set b} {C : Set c}(f : (A ⊎ B) ↔ (A ⊎ C)) →(to-hyp : Well-behaved (to f)) →(from-hyp : Well-behaved (from f)) →∀ b → g (from f) from-hyp (g (to f) to-hyp b) ≡ bg∘g f to-hyp from-hyp b = g∘g′whereopen ≡-Reasoningg∘g′ : g (from f) from-hyp (g (to f) to-hyp b) ≡ bg∘g′ with inspect (to f (inj₂ b))g∘g′ | inj₂ c , eq₁ with inspect (from f (inj₂ c))... | inj₂ b′ , eq₂ = inj₂-injective (inj₂ b′ ≡⟨ ≡.sym eq₂ ⟩from f (inj₂ c) ≡⟨ to-from f eq₁ ⟩inj₂ b ∎)... | inj₁ a , eq₂ withinj₁ a ≡⟨ ≡.sym eq₂ ⟩from f (inj₂ c) ≡⟨ to-from f eq₁ ⟩inj₂ b ∎... | ()g∘g′ | inj₁ a , eq₁ with inspect (to f (inj₁ a))g∘g′ | inj₁ a , eq₁ | inj₁ a′ , eq₂ = ⊥-elim $ to-hyp eq₁ eq₂g∘g′ | inj₁ a , eq₁ | inj₂ c , eq₂ with inspect (from f (inj₂ c))g∘g′ | inj₁ a , eq₁ | inj₂ c , eq₂ | inj₂ b′ , eq₃ withinj₁ a ≡⟨ ≡.sym (to-from f eq₂) ⟩from f (inj₂ c) ≡⟨ eq₃ ⟩inj₂ b′ ∎... | ()g∘g′ | inj₁ a , eq₁ | inj₂ c , eq₂ | inj₁ a′ , eq₃ with inspect (from f $ inj₁ a′)g∘g′ | inj₁ a , eq₁ | inj₂ c , eq₂ | inj₁ a′ , eq₃ | inj₁ a″ , eq₄ = ⊥-elim $ from-hyp eq₃ eq₄g∘g′ | inj₁ a , eq₁ | inj₂ c , eq₂ | inj₁ a′ , eq₃ | inj₂ b′ , eq₄ = inj₂-injective (let lemma =inj₁ a′ ≡⟨ ≡.sym eq₃ ⟩from f (inj₂ c) ≡⟨ to-from f eq₂ ⟩inj₁ a ∎ininj₂ b′ ≡⟨ ≡.sym eq₄ ⟩from f (inj₁ a′) ≡⟨ ≡.cong (from f ∘ inj₁) $ inj₁-injective lemma ⟩from f (inj₁ a) ≡⟨ to-from f eq₁ ⟩inj₂ b ∎)-- Some final lemmas.∼→⊎↔⊎ :∀ {x : A} {xs ys} →x ∷ xs ∼[ bag ] x ∷ ys →∀ {z} → (z ≡ x ⊎ z ∈ xs) ↔ (z ≡ x ⊎ z ∈ ys)∼→⊎↔⊎ {x = x} {xs} {ys} x∷xs≈x∷ys {z} =(z ≡ x ⊎ z ∈ xs) ↔⟨ ∷↔ _ ⟩z ∈ x ∷ xs ↔⟨ x∷xs≈x∷ys ⟩z ∈ x ∷ ys ↔⟨ SK-sym (∷↔ _) ⟩(z ≡ x ⊎ z ∈ ys) ∎whereopen Related.EquationalReasoninglemma : ∀ {xs ys} (inv : x ∷ xs ∼[ bag ] x ∷ ys) {z} →Well-behaved (Inverse.to (∼→⊎↔⊎ inv {z}))lemma {xs} inv {b = z∈xs} {a = p} {a′ = q} hyp₁ hyp₂ = case contra of λ ()whereopen Inverseopen ≡-Reasoningcontra : zero ≡ suc (index-of {xs = xs} z∈xs)contra = beginzero≡⟨⟩index-of {xs = x ∷ xs} (here p)≡⟨⟩index-of {xs = x ∷ xs} (to (∷↔ _) $ inj₁ p)≡⟨ ≡.cong (index-of ∘ (to (∷↔ (_ ≡_)))) $ to-from (∼→⊎↔⊎ inv) {x = inj₁ p} hyp₂ ⟨index-of {xs = x ∷ xs} (to (∷↔ _) $ (from (∼→⊎↔⊎ inv) $ inj₁ q))≡⟨ ≡.cong index-of $ strictlyInverseˡ (∷↔ _) (from inv (here q)) ⟩index-of {xs = x ∷ xs} (to (SK-sym inv) $ here q)≡⟨ index-equality-preserved (SK-sym inv) refl ⟩index-of {xs = x ∷ xs} (to (SK-sym inv) $ here p)≡⟨ ≡.cong index-of $ strictlyInverseˡ (∷↔ _) (from inv (here p)) ⟨index-of {xs = x ∷ xs} (to (∷↔ _) (from (∼→⊎↔⊎ inv) $ inj₁ p))≡⟨ ≡.cong (index-of ∘ (to (∷↔ (_ ≡_)))) $ to-from (∼→⊎↔⊎ inv) {x = inj₂ z∈xs} hyp₁ ⟩index-of {xs = x ∷ xs} (to (∷↔ _) $ inj₂ z∈xs)≡⟨⟩index-of {xs = x ∷ xs} (there z∈xs)≡⟨⟩suc (index-of {xs = xs} z∈xs)∎-------------------------------------------------------------------------- Relationships to other relations↭⇒∼bag : _↭_ {A = A} ⇒ _∼[ bag ]_↭⇒∼bag xs↭ys {v} = mk↔ₛ′ (to xs↭ys) (from xs↭ys) (to∘from xs↭ys) (from∘to xs↭ys)whereto : ∀ {xs ys} → xs ↭ ys → v ∈ xs → v ∈ ysto xs↭ys = ∈-resp-↭ xs↭ysfrom : ∀ {xs ys} → xs ↭ ys → v ∈ ys → v ∈ xsfrom xs↭ys = ∈-resp-↭ (↭-sym xs↭ys)from∘to : ∀ {xs ys} (p : xs ↭ ys) (q : v ∈ xs) → from p (to p q) ≡ qfrom∘to = ∈-resp-[σ⁻¹∘σ]to∘from : ∀ {xs ys} (p : xs ↭ ys) (q : v ∈ ys) → to p (from p q) ≡ qto∘from p with res ← from∘to (↭-sym p) rewrite ↭-sym-involutive p = res∼bag⇒↭ : _∼[ bag ]_ ⇒ _↭_ {A = A}∼bag⇒↭ {A = A} {[]} eq with refl ← empty-unique (↔-sym eq) = refl∼bag⇒↭ {A = A} {x ∷ xs} eqwith zs₁ , zs₂ , p ← ∈-∃++ (Inverse.to (eq {x}) (here ≡.refl)) rewrite p = beginx ∷ xs <⟨ ∼bag⇒↭ (drop-cons (↔-trans eq (comm zs₁ (x ∷ zs₂)))) ⟩x ∷ (zs₂ ++ zs₁) <⟨ ++-comm zs₂ zs₁ ⟩x ∷ (zs₁ ++ zs₂) ↭⟨ shift x zs₁ zs₂ ⟨zs₁ ++ x ∷ zs₂ ∎whereopen CommutativeMonoid (commutativeMonoid bag A)open PermutationReasoning
-------------------------------------------------------------------------- The Agda standard library---- Reflection utilities for List------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Reflection whereopen import Data.List.Baseopen import Reflection.AST.Termopen import Reflection.AST.Argument-------------------------------------------------------------------------- Type`List : Term → Term`List `A = def (quote List) (1 ⋯⟅∷⟆ `A ⟨∷⟩ [])-------------------------------------------------------------------------- Constructors`[] : Term`[] = con (quote List.[]) (2 ⋯⟅∷⟆ [])infixr 5 _`∷__`∷_ : Term → Term → Termx `∷ xs = con (quote List._∷_) (2 ⋯⟅∷⟆ x ⟨∷⟩ xs ⟨∷⟩ [])-------------------------------------------------------------------------- Patterns-- Can't be used on the RHS as the omitted args aren't inferablepattern `[]` = con (quote List.[]) _pattern _`∷`_ x xs = con (quote List._∷_) (_ ∷ _ ∷ x ⟨∷⟩ xs ⟨∷⟩ _)
-------------------------------------------------------------------------- The Agda standard library---- List-related properties-------------------------------------------------------------------------- Note that the lemmas below could be generalised to work with other-- equalities than _≡_.{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for deprecated scansmodule Data.List.Properties whereopen import Algebra.Bundlesopen import Algebra.Consequences.Propositionalusing (selfInverse⇒involutive; selfInverse⇒injective)open import Algebra.Definitions as AlgebraicDefinitions using (SelfInverse; Involutive)open import Algebra.Morphism.Structures using (IsMagmaHomomorphism; IsMonoidHomomorphism)import Algebra.Structures as AlgebraicStructuresopen import Data.Bool.Base using (Bool; false; true; not; if_then_else_)open import Data.Fin.Base using (Fin; zero; suc; cast; toℕ)open import Data.List.Base as Listopen import Data.List.Membership.Propositional using (_∈_)open import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.List.Relation.Unary.Any using (Any; here; there)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)open import Data.Maybe.Relation.Unary.Any using (just) renaming (Any to MAny)open import Data.Nat.Baseopen import Data.Nat.Divisibility using (_∣_; divides; ∣n⇒∣m*n)open import Data.Nat.Propertiesopen import Data.Product.Base as Productusing (_×_; _,_; uncurry; uncurry′; proj₁; proj₂; <_,_>)import Data.Product.Relation.Unary.All as Product using (All)open import Data.Sum using (_⊎_; inj₁; inj₂; isInj₁; isInj₂)open import Data.These.Base as These using (These; this; that; these)open import Data.Fin.Properties using (toℕ-cast)open import Function.Base using (id; _∘_; _∘′_; _∋_; _-⟨_∣; ∣_⟩-_; _$_; const; flip)open import Function.Definitions using (Injective)open import Level using (Level)open import Relation.Binary.Definitions as B using (DecidableEquality)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen import Relation.Binary.PropositionalEquality.Core as ≡open import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Binary.Core using (Rel)open import Relation.Nullary.Reflects using (invert)open import Relation.Nullary using (¬_; Dec; does; _because_; yes; no; contradiction)open import Relation.Nullary.Decidable as Decidable using (isYes; map′; ⌊_⌋; ¬?; _×-dec_)open import Relation.Unary using (Pred; Decidable; ∁)open import Relation.Unary.Properties using (∁?)import Data.Nat.GeneralisedArithmetic as ℕopen ≡-Reasoningprivatevariablea b c d e p ℓ : LevelA : Set aB : Set bC : Set cD : Set dE : Set ex y z w : Axs ys zs ws : List A-------------------------------------------------------------------------- _∷_∷-injective : x ∷ xs ≡ y List.∷ ys → x ≡ y × xs ≡ ys∷-injective refl = refl , refl∷-injectiveˡ : x ∷ xs ≡ y List.∷ ys → x ≡ y∷-injectiveˡ refl = refl∷-injectiveʳ : x ∷ xs ≡ y List.∷ ys → xs ≡ ys∷-injectiveʳ refl = refl∷-dec : Dec (x ≡ y) → Dec (xs ≡ ys) → Dec (x ∷ xs ≡ y List.∷ ys)∷-dec x≟y xs≟ys = Decidable.map′ (uncurry (cong₂ _∷_)) ∷-injective (x≟y ×-dec xs≟ys)≡-dec : DecidableEquality A → DecidableEquality (List A)≡-dec _≟_ [] [] = yes refl≡-dec _≟_ (x ∷ xs) [] = no λ()≡-dec _≟_ [] (y ∷ ys) = no λ()≡-dec _≟_ (x ∷ xs) (y ∷ ys) = ∷-dec (x ≟ y) (≡-dec _≟_ xs ys)-------------------------------------------------------------------------- mapmap-id : map id ≗ id {A = List A}map-id [] = reflmap-id (x ∷ xs) = cong (x ∷_) (map-id xs)map-id-local : ∀ {f : A → A} {xs} → All (λ x → f x ≡ x) xs → map f xs ≡ xsmap-id-local [] = reflmap-id-local (fx≡x ∷ pxs) = cong₂ _∷_ fx≡x (map-id-local pxs)map-++ : ∀ (f : A → B) xs ys →map f (xs ++ ys) ≡ map f xs ++ map f ysmap-++ f [] ys = reflmap-++ f (x ∷ xs) ys = cong (f x ∷_) (map-++ f xs ys)map-cong : ∀ {f g : A → B} → f ≗ g → map f ≗ map gmap-cong f≗g [] = reflmap-cong f≗g (x ∷ xs) = cong₂ _∷_ (f≗g x) (map-cong f≗g xs)map-cong-local : ∀ {f g : A → B} {xs} →All (λ x → f x ≡ g x) xs → map f xs ≡ map g xsmap-cong-local [] = reflmap-cong-local (fx≡gx ∷ fxs≡gxs) = cong₂ _∷_ fx≡gx (map-cong-local fxs≡gxs)length-map : ∀ (f : A → B) xs → length (map f xs) ≡ length xslength-map f [] = refllength-map f (x ∷ xs) = cong suc (length-map f xs)map-∘ : {g : B → C} {f : A → B} → map (g ∘ f) ≗ map g ∘ map fmap-∘ [] = reflmap-∘ (x ∷ xs) = cong (_ ∷_) (map-∘ xs)map-injective : ∀ {f : A → B} → Injective _≡_ _≡_ f → Injective _≡_ _≡_ (map f)map-injective finj {[]} {[]} eq = reflmap-injective finj {x ∷ xs} {y ∷ ys} eq =let fx≡fy , fxs≡fys = ∷-injective eq incong₂ _∷_ (finj fx≡fy) (map-injective finj fxs≡fys)-------------------------------------------------------------------------- _++_length-++ : ∀ (xs : List A) {ys} →length (xs ++ ys) ≡ length xs + length yslength-++ [] = refllength-++ (x ∷ xs) = cong suc (length-++ xs)module _ {A : Set a} whereopen AlgebraicDefinitions {A = List A} _≡_open AlgebraicStructures {A = List A} _≡_++-assoc : Associative _++_++-assoc [] ys zs = refl++-assoc (x ∷ xs) ys zs = cong (x ∷_) (++-assoc xs ys zs)++-identityˡ : LeftIdentity [] _++_++-identityˡ xs = refl++-identityʳ : RightIdentity [] _++_++-identityʳ [] = refl++-identityʳ (x ∷ xs) = cong (x ∷_) (++-identityʳ xs)++-identity : Identity [] _++_++-identity = ++-identityˡ , ++-identityʳ++-identityʳ-unique : ∀ (xs : List A) {ys} → xs ≡ xs ++ ys → ys ≡ []++-identityʳ-unique [] refl = refl++-identityʳ-unique (x ∷ xs) eq =++-identityʳ-unique xs (∷-injectiveʳ eq)++-identityˡ-unique : ∀ {xs} (ys : List A) → xs ≡ ys ++ xs → ys ≡ []++-identityˡ-unique [] _ = refl++-identityˡ-unique {xs = x ∷ xs} (y ∷ ys) eqwith ++-identityˡ-unique (ys ++ [ x ]) (beginxs ≡⟨ ∷-injectiveʳ eq ⟩ys ++ x ∷ xs ≡⟨ ++-assoc ys [ x ] xs ⟨(ys ++ [ x ]) ++ xs ∎)++-identityˡ-unique {xs = x ∷ xs} (y ∷ [] ) eq | ()++-identityˡ-unique {xs = x ∷ xs} (y ∷ _ ∷ _) eq | ()++-cancelˡ : LeftCancellative _++_++-cancelˡ [] _ _ ys≡zs = ys≡zs++-cancelˡ (x ∷ xs) _ _ x∷xs++ys≡x∷xs++zs = ++-cancelˡ xs _ _ (∷-injectiveʳ x∷xs++ys≡x∷xs++zs)++-cancelʳ : RightCancellative _++_++-cancelʳ _ [] [] _ = refl++-cancelʳ xs [] (z ∷ zs) eq =contradiction (trans (cong length eq) (length-++ (z ∷ zs))) (m≢1+n+m (length xs))++-cancelʳ xs (y ∷ ys) [] eq =contradiction (trans (sym (length-++ (y ∷ ys))) (cong length eq)) (m≢1+n+m (length xs) ∘ sym)++-cancelʳ _ (y ∷ ys) (z ∷ zs) eq =cong₂ _∷_ (∷-injectiveˡ eq) (++-cancelʳ _ ys zs (∷-injectiveʳ eq))++-cancel : Cancellative _++_++-cancel = ++-cancelˡ , ++-cancelʳ++-conicalˡ : ∀ (xs ys : List A) → xs ++ ys ≡ [] → xs ≡ []++-conicalˡ [] _ refl = refl++-conicalʳ : ∀ (xs ys : List A) → xs ++ ys ≡ [] → ys ≡ []++-conicalʳ [] _ refl = refl++-conical : Conical [] _++_++-conical = ++-conicalˡ , ++-conicalʳ++-isMagma : IsMagma _++_++-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _++_}++-isSemigroup : IsSemigroup _++_++-isSemigroup = record{ isMagma = ++-isMagma; assoc = ++-assoc}++-isMonoid : IsMonoid _++_ []++-isMonoid = record{ isSemigroup = ++-isSemigroup; identity = ++-identity}module _ (A : Set a) where++-semigroup : Semigroup a a++-semigroup = record{ Carrier = List A; isSemigroup = ++-isSemigroup}++-monoid : Monoid a a++-monoid = record{ Carrier = List A; isMonoid = ++-isMonoid}module _ (A : Set a) wherelength-isMagmaHomomorphism : IsMagmaHomomorphism (++-rawMagma A) +-rawMagma lengthlength-isMagmaHomomorphism = record{ isRelHomomorphism = record{ cong = cong length}; homo = λ xs ys → length-++ xs {ys}}length-isMonoidHomomorphism : IsMonoidHomomorphism (++-[]-rawMonoid A) +-0-rawMonoid lengthlength-isMonoidHomomorphism = record{ isMagmaHomomorphism = length-isMagmaHomomorphism; ε-homo = refl}-------------------------------------------------------------------------- cartesianProductWithmodule _ (f : A → B → C) whereprivateprod = cartesianProductWith fcartesianProductWith-zeroˡ : ∀ ys → prod [] ys ≡ []cartesianProductWith-zeroˡ _ = reflcartesianProductWith-zeroʳ : ∀ xs → prod xs [] ≡ []cartesianProductWith-zeroʳ [] = reflcartesianProductWith-zeroʳ (x ∷ xs) = cartesianProductWith-zeroʳ xscartesianProductWith-distribʳ-++ : ∀ xs ys zs → prod (xs ++ ys) zs ≡ prod xs zs ++ prod ys zscartesianProductWith-distribʳ-++ [] ys zs = reflcartesianProductWith-distribʳ-++ (x ∷ xs) ys zs = beginprod (x ∷ xs ++ ys) zs ≡⟨⟩map (f x) zs ++ prod (xs ++ ys) zs ≡⟨ cong (map (f x) zs ++_) (cartesianProductWith-distribʳ-++ xs ys zs) ⟩map (f x) zs ++ prod xs zs ++ prod ys zs ≡⟨ ++-assoc (map (f x) zs) (prod xs zs) (prod ys zs) ⟨(map (f x) zs ++ prod xs zs) ++ prod ys zs ≡⟨⟩prod (x ∷ xs) zs ++ prod ys zs ∎-------------------------------------------------------------------------- alignWithmodule _ {f g : These A B → C} wherealignWith-cong : f ≗ g → ∀ as → alignWith f as ≗ alignWith g asalignWith-cong f≗g [] bs = map-cong (f≗g ∘ that) bsalignWith-cong f≗g as@(_ ∷ _) [] = map-cong (f≗g ∘ this) asalignWith-cong f≗g (a ∷ as) (b ∷ bs) =cong₂ _∷_ (f≗g (these a b)) (alignWith-cong f≗g as bs)module _ {f : These A B → C} wherelength-alignWith : ∀ xs ys →length (alignWith f xs ys) ≡ length xs ⊔ length yslength-alignWith [] ys = length-map (f ∘′ that) yslength-alignWith xs@(_ ∷ _) [] = length-map (f ∘′ this) xslength-alignWith (x ∷ xs) (y ∷ ys) = cong suc (length-alignWith xs ys)alignWith-map : (g : D → A) (h : E → B) →∀ xs ys → alignWith f (map g xs) (map h ys) ≡alignWith (f ∘′ These.map g h) xs ysalignWith-map g h [] ys = sym (map-∘ ys)alignWith-map g h xs@(_ ∷ _) [] = sym (map-∘ xs)alignWith-map g h (x ∷ xs) (y ∷ ys) =cong₂ _∷_ refl (alignWith-map g h xs ys)map-alignWith : ∀ (g : C → D) → ∀ xs ys →map g (alignWith f xs ys) ≡alignWith (g ∘′ f) xs ysmap-alignWith g [] ys = sym (map-∘ ys)map-alignWith g xs@(_ ∷ _) [] = sym (map-∘ xs)map-alignWith g (x ∷ xs) (y ∷ ys) =cong₂ _∷_ refl (map-alignWith g xs ys)alignWith-flip : ∀ xs ys →alignWith f xs ys ≡ alignWith (f ∘ These.swap) ys xsalignWith-flip [] [] = reflalignWith-flip [] (y ∷ ys) = reflalignWith-flip (x ∷ xs) [] = reflalignWith-flip (x ∷ xs) (y ∷ ys) = cong (_ ∷_) (alignWith-flip xs ys)module _ {f : These A A → B} wherealignWith-comm : f ∘ These.swap ≗ f →∀ xs ys → alignWith f xs ys ≡ alignWith f ys xsalignWith-comm f-comm xs ys = beginalignWith f xs ys ≡⟨ alignWith-flip xs ys ⟩alignWith (f ∘ These.swap) ys xs ≡⟨ alignWith-cong f-comm ys xs ⟩alignWith f ys xs ∎-------------------------------------------------------------------------- alignalign-map : ∀ (f : A → B) (g : C → D) →∀ xs ys → align (map f xs) (map g ys) ≡map (These.map f g) (align xs ys)align-map f g xs ys = beginalign (map f xs) (map g ys) ≡⟨ alignWith-map f g xs ys ⟩alignWith (These.map f g) xs ys ≡⟨ sym (map-alignWith (These.map f g) xs ys) ⟩map (These.map f g) (align xs ys) ∎align-flip : ∀ (xs : List A) (ys : List B) →align xs ys ≡ map These.swap (align ys xs)align-flip xs ys = beginalign xs ys ≡⟨ alignWith-flip xs ys ⟩alignWith These.swap ys xs ≡⟨ sym (map-alignWith These.swap ys xs) ⟩map These.swap (align ys xs) ∎-------------------------------------------------------------------------- zipWithmodule _ {f g : A → B → C} wherezipWith-cong : (∀ a b → f a b ≡ g a b) → ∀ as → zipWith f as ≗ zipWith g aszipWith-cong f≗g [] bs = reflzipWith-cong f≗g as@(_ ∷ _) [] = reflzipWith-cong f≗g (a ∷ as) (b ∷ bs) =cong₂ _∷_ (f≗g a b) (zipWith-cong f≗g as bs)module _ (f : A → B → C) wherezipWith-zeroˡ : ∀ xs → zipWith f [] xs ≡ []zipWith-zeroˡ [] = reflzipWith-zeroˡ (x ∷ xs) = reflzipWith-zeroʳ : ∀ xs → zipWith f xs [] ≡ []zipWith-zeroʳ [] = reflzipWith-zeroʳ (x ∷ xs) = refllength-zipWith : ∀ xs ys →length (zipWith f xs ys) ≡ length xs ⊓ length yslength-zipWith [] [] = refllength-zipWith [] (y ∷ ys) = refllength-zipWith (x ∷ xs) [] = refllength-zipWith (x ∷ xs) (y ∷ ys) = cong suc (length-zipWith xs ys)zipWith-map : ∀ (g : D → A) (h : E → B) →∀ xs ys → zipWith f (map g xs) (map h ys) ≡zipWith (λ x y → f (g x) (h y)) xs yszipWith-map g h [] [] = reflzipWith-map g h [] (y ∷ ys) = reflzipWith-map g h (x ∷ xs) [] = reflzipWith-map g h (x ∷ xs) (y ∷ ys) =cong₂ _∷_ refl (zipWith-map g h xs ys)map-zipWith : ∀ (g : C → D) → ∀ xs ys →map g (zipWith f xs ys) ≡zipWith (λ x y → g (f x y)) xs ysmap-zipWith g [] [] = reflmap-zipWith g [] (y ∷ ys) = reflmap-zipWith g (x ∷ xs) [] = reflmap-zipWith g (x ∷ xs) (y ∷ ys) =cong₂ _∷_ refl (map-zipWith g xs ys)zipWith-flip : ∀ xs ys → zipWith f xs ys ≡ zipWith (flip f) ys xszipWith-flip [] [] = reflzipWith-flip [] (x ∷ ys) = reflzipWith-flip (x ∷ xs) [] = reflzipWith-flip (x ∷ xs) (y ∷ ys) = cong (f x y ∷_) (zipWith-flip xs ys)module _ (f : A → A → B) wherezipWith-comm : (∀ x y → f x y ≡ f y x) →∀ xs ys → zipWith f xs ys ≡ zipWith f ys xszipWith-comm f-comm xs ys = beginzipWith f xs ys ≡⟨ zipWith-flip f xs ys ⟩zipWith (flip f) ys xs ≡⟨ zipWith-cong (flip f-comm) ys xs ⟩zipWith f ys xs ∎-------------------------------------------------------------------------- zipzip-map : ∀ (f : A → B) (g : C → D) →∀ xs ys → zip (map f xs) (map g ys) ≡map (Product.map f g) (zip xs ys)zip-map f g xs ys = beginzip (map f xs) (map g ys) ≡⟨ zipWith-map _,_ f g xs ys ⟩zipWith (λ x y → f x , g y) xs ys ≡⟨ sym (map-zipWith _,_ (Product.map f g) xs ys) ⟩map (Product.map f g) (zip xs ys) ∎zip-flip : ∀ (xs : List A) (ys : List B) →zip xs ys ≡ map Product.swap (zip ys xs)zip-flip xs ys = beginzip xs ys ≡⟨ zipWith-flip _,_ xs ys ⟩zipWith (flip _,_) ys xs ≡⟨ sym (map-zipWith _,_ Product.swap ys xs) ⟩map Product.swap (zip ys xs) ∎-------------------------------------------------------------------------- unalignWithunalignWith-this : unalignWith ((A → These A B) ∋ this) ≗ (_, [])unalignWith-this [] = reflunalignWith-this (a ∷ as) = cong (Product.map₁ (a ∷_)) (unalignWith-this as)unalignWith-that : unalignWith ((B → These A B) ∋ that) ≗ ([] ,_)unalignWith-that [] = reflunalignWith-that (b ∷ bs) = cong (Product.map₂ (b ∷_)) (unalignWith-that bs)module _ {f g : C → These A B} whereunalignWith-cong : f ≗ g → unalignWith f ≗ unalignWith gunalignWith-cong f≗g [] = reflunalignWith-cong f≗g (c ∷ cs) with f c | g c | f≗g c... | this a | ._ | refl = cong (Product.map₁ (a ∷_)) (unalignWith-cong f≗g cs)... | that b | ._ | refl = cong (Product.map₂ (b ∷_)) (unalignWith-cong f≗g cs)... | these a b | ._ | refl = cong (Product.map (a ∷_) (b ∷_)) (unalignWith-cong f≗g cs)module _ (f : C → These A B) whereunalignWith-map : (g : D → C) → ∀ ds →unalignWith f (map g ds) ≡ unalignWith (f ∘′ g) dsunalignWith-map g [] = reflunalignWith-map g (d ∷ ds) with f (g d)... | this a = cong (Product.map₁ (a ∷_)) (unalignWith-map g ds)... | that b = cong (Product.map₂ (b ∷_)) (unalignWith-map g ds)... | these a b = cong (Product.map (a ∷_) (b ∷_)) (unalignWith-map g ds)map-unalignWith : (g : A → D) (h : B → E) →Product.map (map g) (map h) ∘′ unalignWith f ≗ unalignWith (These.map g h ∘′ f)map-unalignWith g h [] = reflmap-unalignWith g h (c ∷ cs) with f c... | this a = cong (Product.map₁ (g a ∷_)) (map-unalignWith g h cs)... | that b = cong (Product.map₂ (h b ∷_)) (map-unalignWith g h cs)... | these a b = cong (Product.map (g a ∷_) (h b ∷_)) (map-unalignWith g h cs)unalignWith-alignWith : (g : These A B → C) → f ∘′ g ≗ id → ∀ as bs →unalignWith f (alignWith g as bs) ≡ (as , bs)unalignWith-alignWith g g∘f≗id [] bs = beginunalignWith f (map (g ∘′ that) bs) ≡⟨ unalignWith-map (g ∘′ that) bs ⟩unalignWith (f ∘′ g ∘′ that) bs ≡⟨ unalignWith-cong (g∘f≗id ∘ that) bs ⟩unalignWith that bs ≡⟨ unalignWith-that bs ⟩[] , bs ∎unalignWith-alignWith g g∘f≗id as@(_ ∷ _) [] = beginunalignWith f (map (g ∘′ this) as) ≡⟨ unalignWith-map (g ∘′ this) as ⟩unalignWith (f ∘′ g ∘′ this) as ≡⟨ unalignWith-cong (g∘f≗id ∘ this) as ⟩unalignWith this as ≡⟨ unalignWith-this as ⟩as , [] ∎unalignWith-alignWith g g∘f≗id (a ∷ as) (b ∷ bs)rewrite g∘f≗id (these a b) =cong (Product.map (a ∷_) (b ∷_)) (unalignWith-alignWith g g∘f≗id as bs)-------------------------------------------------------------------------- unzipWithmodule _ {f g : A → B × C} whereunzipWith-cong : f ≗ g → unzipWith f ≗ unzipWith gunzipWith-cong f≗g [] = reflunzipWith-cong f≗g (x ∷ xs) =cong₂ (Product.zip _∷_ _∷_) (f≗g x) (unzipWith-cong f≗g xs)module _ (f : A → B × C) wherelength-unzipWith₁ : ∀ xys →length (proj₁ (unzipWith f xys)) ≡ length xyslength-unzipWith₁ [] = refllength-unzipWith₁ (x ∷ xys) = cong suc (length-unzipWith₁ xys)length-unzipWith₂ : ∀ xys →length (proj₂ (unzipWith f xys)) ≡ length xyslength-unzipWith₂ [] = refllength-unzipWith₂ (x ∷ xys) = cong suc (length-unzipWith₂ xys)zipWith-unzipWith : (g : B → C → A) → uncurry′ g ∘ f ≗ id →uncurry′ (zipWith g) ∘ (unzipWith f) ≗ idzipWith-unzipWith g g∘f≗id [] = reflzipWith-unzipWith g g∘f≗id (x ∷ xs) =cong₂ _∷_ (g∘f≗id x) (zipWith-unzipWith g g∘f≗id xs)unzipWith-zipWith : (g : B → C → A) → f ∘ uncurry′ g ≗ id →∀ xs ys → length xs ≡ length ys →unzipWith f (zipWith g xs ys) ≡ (xs , ys)unzipWith-zipWith g f∘g≗id [] [] l≡l = reflunzipWith-zipWith g f∘g≗id (x ∷ xs) (y ∷ ys) l≡l =cong₂ (Product.zip _∷_ _∷_) (f∘g≗id (x , y))(unzipWith-zipWith g f∘g≗id xs ys (suc-injective l≡l))unzipWith-map : (g : D → A) → unzipWith f ∘ map g ≗ unzipWith (f ∘ g)unzipWith-map g [] = reflunzipWith-map g (x ∷ xs) =cong (Product.zip _∷_ _∷_ (f (g x))) (unzipWith-map g xs)map-unzipWith : (g : B → D) (h : C → E) →Product.map (map g) (map h) ∘ unzipWith f ≗unzipWith (Product.map g h ∘ f)map-unzipWith g h [] = reflmap-unzipWith g h (x ∷ xs) =cong (Product.zip _∷_ _∷_ _) (map-unzipWith g h xs)unzipWith-swap : unzipWith (Product.swap ∘ f) ≗Product.swap ∘ unzipWith funzipWith-swap [] = reflunzipWith-swap (x ∷ xs) =cong (Product.zip _∷_ _∷_ _) (unzipWith-swap xs)unzipWith-++ : ∀ xs ys →unzipWith f (xs ++ ys) ≡Product.zip _++_ _++_ (unzipWith f xs) (unzipWith f ys)unzipWith-++ [] ys = reflunzipWith-++ (x ∷ xs) ys =cong (Product.zip _∷_ _∷_ (f x)) (unzipWith-++ xs ys)-------------------------------------------------------------------------- unzipunzip-map : ∀ (f : A → B) (g : C → D) →unzip ∘ map (Product.map f g) ≗Product.map (map f) (map g) ∘ unzipunzip-map f g xs = beginunzip (map (Product.map f g) xs) ≡⟨ unzipWith-map id (Product.map f g) xs ⟩unzipWith (Product.map f g) xs ≡⟨ sym (map-unzipWith id f g xs) ⟩Product.map (map f) (map g) (unzip xs) ∎unzip-swap : unzip ∘ map Product.swap ≗ Product.swap ∘ unzip {A = A} {B = B}unzip-swap xs = beginunzip (map Product.swap xs) ≡⟨ unzipWith-map id Product.swap xs ⟩unzipWith Product.swap xs ≡⟨ unzipWith-swap id xs ⟩Product.swap (unzip xs) ∎zip-unzip : uncurry′ zip ∘ unzip ≗ id {A = List (A × B)}zip-unzip = zipWith-unzipWith id _,_ λ _ → reflunzip-zip : ∀ (xs : List A) (ys : List B) →length xs ≡ length ys → unzip (zip xs ys) ≡ (xs , ys)unzip-zip = unzipWith-zipWith id _,_ λ _ → refl-------------------------------------------------------------------------- foldrfoldr-universal : ∀ (h : List A → B) f e → (h [] ≡ e) →(∀ x xs → h (x ∷ xs) ≡ f x (h xs)) →h ≗ foldr f efoldr-universal h f e base step [] = basefoldr-universal h f e base step (x ∷ xs) = beginh (x ∷ xs) ≡⟨ step x xs ⟩f x (h xs) ≡⟨ cong (f x) (foldr-universal h f e base step xs) ⟩f x (foldr f e xs) ∎foldr-cong : ∀ {f g : A → B → B} {d e : B} →(∀ x y → f x y ≡ g x y) → d ≡ e →foldr f d ≗ foldr g efoldr-cong f≗g refl [] = reflfoldr-cong f≗g d≡e (x ∷ xs) rewrite foldr-cong f≗g d≡e xs = f≗g x _foldr-fusion : ∀ (h : B → C) {f : A → B → B} {g : A → C → C} (e : B) →(∀ x y → h (f x y) ≡ g x (h y)) →h ∘ foldr f e ≗ foldr g (h e)foldr-fusion h {f} {g} e fuse =foldr-universal (h ∘ foldr f e) g (h e) refl(λ x xs → fuse x (foldr f e xs))id-is-foldr : id {A = List A} ≗ foldr _∷_ []id-is-foldr = foldr-universal id _∷_ [] refl (λ _ _ → refl)++-is-foldr : (xs ys : List A) → xs ++ ys ≡ foldr _∷_ ys xs++-is-foldr xs ys = beginxs ++ ys ≡⟨ cong (_++ ys) (id-is-foldr xs) ⟩foldr _∷_ [] xs ++ ys ≡⟨ foldr-fusion (_++ ys) [] (λ _ _ → refl) xs ⟩foldr _∷_ ([] ++ ys) xs ≡⟨⟩foldr _∷_ ys xs ∎foldr-++ : ∀ (f : A → B → B) x ys zs →foldr f x (ys ++ zs) ≡ foldr f (foldr f x zs) ysfoldr-++ f x [] zs = reflfoldr-++ f x (y ∷ ys) zs = cong (f y) (foldr-++ f x ys zs)map-is-foldr : {f : A → B} → map f ≗ foldr (λ x ys → f x ∷ ys) []map-is-foldr {f = f} xs = beginmap f xs ≡⟨ cong (map f) (id-is-foldr xs) ⟩map f (foldr _∷_ [] xs) ≡⟨ foldr-fusion (map f) [] (λ _ _ → refl) xs ⟩foldr (λ x ys → f x ∷ ys) [] xs ∎foldr-∷ʳ : ∀ (f : A → B → B) x y ys →foldr f x (ys ∷ʳ y) ≡ foldr f (f y x) ysfoldr-∷ʳ f x y [] = reflfoldr-∷ʳ f x y (z ∷ ys) = cong (f z) (foldr-∷ʳ f x y ys)foldr-map : ∀ (f : A → B → B) (g : C → A) x xs → foldr f x (map g xs) ≡ foldr (g -⟨ f ∣) x xsfoldr-map f g x [] = reflfoldr-map f g x (y ∷ xs) = cong (f (g y)) (foldr-map f g x xs)-- Interaction with predicatesmodule _ {P : Pred A p} {f : A → A → A} wherefoldr-forcesᵇ : (∀ x y → P (f x y) → P x × P y) →∀ e xs → P (foldr f e xs) → All P xsfoldr-forcesᵇ _ _ [] _ = []foldr-forcesᵇ forces _ (x ∷ xs) Pfold =let px , pfxs = forces _ _ Pfold in px ∷ foldr-forcesᵇ forces _ xs pfxsfoldr-preservesᵇ : (∀ {x y} → P x → P y → P (f x y)) →∀ {e xs} → P e → All P xs → P (foldr f e xs)foldr-preservesᵇ _ Pe [] = Pefoldr-preservesᵇ pres Pe (px ∷ pxs) = pres px (foldr-preservesᵇ pres Pe pxs)foldr-preservesʳ : (∀ x {y} → P y → P (f x y)) →∀ {e} → P e → ∀ xs → P (foldr f e xs)foldr-preservesʳ pres Pe [] = Pefoldr-preservesʳ pres Pe (_ ∷ xs) = pres _ (foldr-preservesʳ pres Pe xs)foldr-preservesᵒ : (∀ x y → P x ⊎ P y → P (f x y)) →∀ e xs → P e ⊎ Any P xs → P (foldr f e xs)foldr-preservesᵒ pres e [] (inj₁ Pe) = Pefoldr-preservesᵒ pres e (x ∷ xs) (inj₁ Pe) =pres _ _ (inj₂ (foldr-preservesᵒ pres e xs (inj₁ Pe)))foldr-preservesᵒ pres e (x ∷ xs) (inj₂ (here px)) = pres _ _ (inj₁ px)foldr-preservesᵒ pres e (x ∷ xs) (inj₂ (there pxs)) =pres _ _ (inj₂ (foldr-preservesᵒ pres e xs (inj₂ pxs)))-------------------------------------------------------------------------- foldlfoldl-cong : ∀ {f g : B → A → B} → (∀ x y → f x y ≡ g x y) →∀ x → foldl f x ≗ foldl g xfoldl-cong f≗g x [] = reflfoldl-cong f≗g x (y ∷ xs) rewrite f≗g x y = foldl-cong f≗g _ xsfoldl-++ : ∀ (f : A → B → A) x ys zs →foldl f x (ys ++ zs) ≡ foldl f (foldl f x ys) zsfoldl-++ f x [] zs = reflfoldl-++ f x (y ∷ ys) zs = foldl-++ f (f x y) ys zsfoldl-∷ʳ : ∀ (f : A → B → A) x y ys →foldl f x (ys ∷ʳ y) ≡ f (foldl f x ys) yfoldl-∷ʳ f x y [] = reflfoldl-∷ʳ f x y (z ∷ ys) = foldl-∷ʳ f (f x z) y ysfoldl-map : ∀ (f : A → B → A) (g : C → B) x xs → foldl f x (map g xs) ≡ foldl (∣ f ⟩- g) x xsfoldl-map f g x [] = reflfoldl-map f g x (y ∷ xs) = foldl-map f g (f x (g y)) xs-------------------------------------------------------------------------- concatconcat-map : ∀ {f : A → B} → concat ∘ map (map f) ≗ map f ∘ concatconcat-map {f = f} xss = beginconcat (map (map f) xss) ≡⟨ cong concat (map-is-foldr xss) ⟩concat (foldr (λ xs → map f xs ∷_) [] xss) ≡⟨ foldr-fusion concat [] (λ _ _ → refl) xss ⟩foldr (λ ys → map f ys ++_) [] xss ≡⟨ sym (foldr-fusion (map f) [] (map-++ f) xss) ⟩map f (concat xss) ∎concat-++ : (xss yss : List (List A)) → concat xss ++ concat yss ≡ concat (xss ++ yss)concat-++ [] yss = reflconcat-++ ([] ∷ xss) yss = concat-++ xss yssconcat-++ ((x ∷ xs) ∷ xss) yss = cong (x ∷_) (concat-++ (xs ∷ xss) yss)concat-concat : concat {A = A} ∘ map concat ≗ concat ∘ concatconcat-concat [] = reflconcat-concat (xss ∷ xsss) = beginconcat (map concat (xss ∷ xsss)) ≡⟨ cong (concat xss ++_) (concat-concat xsss) ⟩concat xss ++ concat (concat xsss) ≡⟨ concat-++ xss (concat xsss) ⟩concat (concat (xss ∷ xsss)) ∎concat-[-] : concat {A = A} ∘ map [_] ≗ idconcat-[-] [] = reflconcat-[-] (x ∷ xs) = cong (x ∷_) (concat-[-] xs)-------------------------------------------------------------------------- concatMapconcatMap-cong : ∀ {f g : A → List B} → f ≗ g → concatMap f ≗ concatMap gconcatMap-cong eq xs = cong concat (map-cong eq xs)concatMap-pure : concatMap {A = A} [_] ≗ idconcatMap-pure = concat-[-]concatMap-map : (g : B → List C) → (f : A → B) → (xs : List A) →concatMap g (map f xs) ≡ concatMap (g ∘′ f) xsconcatMap-map g f xs= cong concat{x = map g (map f xs)}{y = map (g ∘′ f) xs}(sym $ map-∘ xs)map-concatMap : (f : B → C) (g : A → List B) →map f ∘′ concatMap g ≗ concatMap (map f ∘′ g)map-concatMap f g xs = beginmap f (concatMap g xs)≡⟨⟩map f (concat (map g xs))≡⟨ concat-map (map g xs) ⟨concat (map (map f) (map g xs))≡⟨ cong concat{x = map (map f) (map g xs)}{y = map (map f ∘′ g) xs}(sym $ map-∘ xs) ⟩concat (map (map f ∘′ g) xs)≡⟨⟩concatMap (map f ∘′ g) xs∎-------------------------------------------------------------------------- catMaybescatMaybes-concatMap : catMaybes {A = A} ≗ concatMap fromMaybecatMaybes-concatMap [] = reflcatMaybes-concatMap (just x ∷ xs) = cong (x ∷_) $ catMaybes-concatMap xscatMaybes-concatMap (nothing ∷ xs) = catMaybes-concatMap xslength-catMaybes : ∀ xs → length (catMaybes {A = A} xs) ≤ length xslength-catMaybes [] = ≤-refllength-catMaybes (just _ ∷ xs) = s≤s $ length-catMaybes xslength-catMaybes (nothing ∷ xs) = m≤n⇒m≤1+n $ length-catMaybes xscatMaybes-++ : (xs ys : List (Maybe A)) →catMaybes (xs ++ ys) ≡ catMaybes xs ++ catMaybes yscatMaybes-++ [] _ = reflcatMaybes-++ (just x ∷ xs) ys = cong (x ∷_) $ catMaybes-++ xs yscatMaybes-++ (nothing ∷ xs) ys = catMaybes-++ xs ysmap-catMaybes : (f : A → B) → map f ∘ catMaybes ≗ catMaybes ∘ map (Maybe.map f)map-catMaybes _ [] = reflmap-catMaybes f (just x ∷ xs) = cong (f x ∷_) $ map-catMaybes f xsmap-catMaybes f (nothing ∷ xs) = map-catMaybes f xsAny-catMaybes⁺ : ∀ {P : Pred A ℓ} {xs : List (Maybe A)} →Any (MAny P) xs → Any P (catMaybes xs)Any-catMaybes⁺ {xs = nothing ∷ xs} (there x∈) = Any-catMaybes⁺ x∈Any-catMaybes⁺ {xs = just x ∷ xs} (here (just px)) = here pxAny-catMaybes⁺ {xs = just x ∷ xs} (there x∈) = there $ Any-catMaybes⁺ x∈-------------------------------------------------------------------------- mapMaybemapMaybe-cong : {f g : A → Maybe B} → f ≗ g → mapMaybe f ≗ mapMaybe gmapMaybe-cong f≗g = cong catMaybes ∘ map-cong f≗gmapMaybe-just : (xs : List A) → mapMaybe just xs ≡ xsmapMaybe-just [] = reflmapMaybe-just (x ∷ xs) = cong (x ∷_) (mapMaybe-just xs)mapMaybe-nothing : (xs : List A) →mapMaybe {B = B} (λ _ → nothing) xs ≡ []mapMaybe-nothing [] = reflmapMaybe-nothing (x ∷ xs) = mapMaybe-nothing xsmodule _ (f : A → Maybe B) wheremapMaybe-concatMap : mapMaybe f ≗ concatMap (fromMaybe ∘ f)mapMaybe-concatMap xs = begincatMaybes (map f xs) ≡⟨ catMaybes-concatMap (map f xs) ⟩concatMap fromMaybe (map f xs) ≡⟨ concatMap-map fromMaybe f xs ⟩concatMap (fromMaybe ∘ f) xs ∎length-mapMaybe : ∀ xs → length (mapMaybe f xs) ≤ length xslength-mapMaybe xs = ≤-beginlength (mapMaybe f xs) ≤⟨ length-catMaybes (map f xs) ⟩length (map f xs) ≤⟨ ≤-reflexive (length-map f xs) ⟩length xs ≤-∎where open ≤-Reasoning renaming (begin_ to ≤-begin_; _∎ to _≤-∎)mapMaybe-++ : ∀ xs ys →mapMaybe f (xs ++ ys) ≡ mapMaybe f xs ++ mapMaybe f ysmapMaybe-++ xs ys = begincatMaybes (map f (xs ++ ys)) ≡⟨ cong catMaybes (map-++ f xs ys) ⟩catMaybes (map f xs ++ map f ys) ≡⟨ catMaybes-++ (map f xs) (map f ys) ⟩mapMaybe f xs ++ mapMaybe f ys ∎module _ (f : B → Maybe C) (g : A → B) wheremapMaybe-map : mapMaybe f ∘ map g ≗ mapMaybe (f ∘ g)mapMaybe-map = cong catMaybes ∘ sym ∘ map-∘module _ (g : B → C) (f : A → Maybe B) wheremap-mapMaybe : map g ∘ mapMaybe f ≗ mapMaybe (Maybe.map g ∘ f)map-mapMaybe xs = beginmap g (catMaybes (map f xs)) ≡⟨ map-catMaybes g (map f xs) ⟩mapMaybe (Maybe.map g) (map f xs) ≡⟨ mapMaybe-map _ f xs ⟩mapMaybe (Maybe.map g ∘ f) xs ∎-- embedding-projection pairsmodule _ {proj : B → Maybe A} {emb : A → B} wheremapMaybe-map-retract : proj ∘ emb ≗ just → mapMaybe proj ∘ map emb ≗ idmapMaybe-map-retract retract xs = beginmapMaybe proj (map emb xs) ≡⟨ mapMaybe-map _ _ xs ⟩mapMaybe (proj ∘ emb) xs ≡⟨ mapMaybe-cong retract xs ⟩mapMaybe just xs ≡⟨ mapMaybe-just _ ⟩xs ∎module _ {proj : C → Maybe B} {emb : A → C} wheremapMaybe-map-none : proj ∘ emb ≗ const nothing → mapMaybe proj ∘ map emb ≗ const []mapMaybe-map-none retract xs = beginmapMaybe proj (map emb xs) ≡⟨ mapMaybe-map _ _ xs ⟩mapMaybe (proj ∘ emb) xs ≡⟨ mapMaybe-cong retract xs ⟩mapMaybe (const nothing) xs ≡⟨ mapMaybe-nothing xs ⟩[] ∎-- embedding-projection pairs on sumsmapMaybeIsInj₁∘mapInj₁ : (xs : List A) → mapMaybe (isInj₁ {B = B}) (map inj₁ xs) ≡ xsmapMaybeIsInj₁∘mapInj₁ = mapMaybe-map-retract λ _ → reflmapMaybeIsInj₁∘mapInj₂ : (xs : List B) → mapMaybe (isInj₁ {A = A}) (map inj₂ xs) ≡ []mapMaybeIsInj₁∘mapInj₂ = mapMaybe-map-none λ _ → reflmapMaybeIsInj₂∘mapInj₂ : (xs : List B) → mapMaybe (isInj₂ {A = A}) (map inj₂ xs) ≡ xsmapMaybeIsInj₂∘mapInj₂ = mapMaybe-map-retract λ _ → reflmapMaybeIsInj₂∘mapInj₁ : (xs : List A) → mapMaybe (isInj₂ {B = B}) (map inj₁ xs) ≡ []mapMaybeIsInj₂∘mapInj₁ = mapMaybe-map-none λ _ → refl-------------------------------------------------------------------------- sumsum-++ : ∀ xs ys → sum (xs ++ ys) ≡ sum xs + sum yssum-++ [] ys = reflsum-++ (x ∷ xs) ys = beginx + sum (xs ++ ys) ≡⟨ cong (x +_) (sum-++ xs ys) ⟩x + (sum xs + sum ys) ≡⟨ sym (+-assoc x _ _) ⟩(x + sum xs) + sum ys ∎-------------------------------------------------------------------------- product∈⇒∣product : ∀ {n ns} → n ∈ ns → n ∣ product ns∈⇒∣product {n} {n ∷ ns} (here refl) = divides (product ns) (*-comm n (product ns))∈⇒∣product {n} {m ∷ ns} (there n∈ns) = ∣n⇒∣m*n m (∈⇒∣product n∈ns)-------------------------------------------------------------------------- applyUpTolength-applyUpTo : ∀ (f : ℕ → A) n → length (applyUpTo f n) ≡ nlength-applyUpTo f zero = refllength-applyUpTo f (suc n) = cong suc (length-applyUpTo (f ∘ suc) n)lookup-applyUpTo : ∀ (f : ℕ → A) n i → lookup (applyUpTo f n) i ≡ f (toℕ i)lookup-applyUpTo f (suc n) zero = refllookup-applyUpTo f (suc n) (suc i) = lookup-applyUpTo (f ∘ suc) n iapplyUpTo-∷ʳ : ∀ (f : ℕ → A) n → applyUpTo f n ∷ʳ f n ≡ applyUpTo f (suc n)applyUpTo-∷ʳ f zero = reflapplyUpTo-∷ʳ f (suc n) = cong (f 0 ∷_) (applyUpTo-∷ʳ (f ∘ suc) n)-------------------------------------------------------------------------- applyDownFrommodule _ (f : ℕ → A) wherelength-applyDownFrom : ∀ n → length (applyDownFrom f n) ≡ nlength-applyDownFrom zero = refllength-applyDownFrom (suc n) = cong suc (length-applyDownFrom n)lookup-applyDownFrom : ∀ n i → lookup (applyDownFrom f n) i ≡ f (n ∸ (suc (toℕ i)))lookup-applyDownFrom (suc n) zero = refllookup-applyDownFrom (suc n) (suc i) = lookup-applyDownFrom n iapplyDownFrom-∷ʳ : ∀ n → applyDownFrom (f ∘ suc) n ∷ʳ f 0 ≡ applyDownFrom f (suc n)applyDownFrom-∷ʳ zero = reflapplyDownFrom-∷ʳ (suc n) = cong (f (suc n) ∷_) (applyDownFrom-∷ʳ n)-------------------------------------------------------------------------- upTolength-upTo : ∀ n → length (upTo n) ≡ nlength-upTo = length-applyUpTo idlookup-upTo : ∀ n i → lookup (upTo n) i ≡ toℕ ilookup-upTo = lookup-applyUpTo idupTo-∷ʳ : ∀ n → upTo n ∷ʳ n ≡ upTo (suc n)upTo-∷ʳ = applyUpTo-∷ʳ id-------------------------------------------------------------------------- downFromlength-downFrom : ∀ n → length (downFrom n) ≡ nlength-downFrom = length-applyDownFrom idlookup-downFrom : ∀ n i → lookup (downFrom n) i ≡ n ∸ (suc (toℕ i))lookup-downFrom = lookup-applyDownFrom iddownFrom-∷ʳ : ∀ n → applyDownFrom suc n ∷ʳ 0 ≡ downFrom (suc n)downFrom-∷ʳ = applyDownFrom-∷ʳ id-------------------------------------------------------------------------- tabulatetabulate-cong : ∀ {n} {f g : Fin n → A} →f ≗ g → tabulate f ≡ tabulate gtabulate-cong {n = zero} p = refltabulate-cong {n = suc n} p = cong₂ _∷_ (p zero) (tabulate-cong (p ∘ suc))tabulate-lookup : ∀ (xs : List A) → tabulate (lookup xs) ≡ xstabulate-lookup [] = refltabulate-lookup (x ∷ xs) = cong (_ ∷_) (tabulate-lookup xs)length-tabulate : ∀ {n} → (f : Fin n → A) →length (tabulate f) ≡ nlength-tabulate {n = zero} f = refllength-tabulate {n = suc n} f = cong suc (length-tabulate (λ z → f (suc z)))lookup-tabulate : ∀ {n} → (f : Fin n → A) →∀ i → let i′ = cast (sym (length-tabulate f)) iin lookup (tabulate f) i′ ≡ f ilookup-tabulate f zero = refllookup-tabulate f (suc i) = lookup-tabulate (f ∘ suc) imap-tabulate : ∀ {n} (g : Fin n → A) (f : A → B) →map f (tabulate g) ≡ tabulate (f ∘ g)map-tabulate {n = zero} g f = reflmap-tabulate {n = suc n} g f = cong (_ ∷_) (map-tabulate (g ∘ suc) f)-------------------------------------------------------------------------- _[_]%=_length-%= : ∀ xs k (f : A → A) → length (xs [ k ]%= f) ≡ length xslength-%= (x ∷ xs) zero f = refllength-%= (x ∷ xs) (suc k) f = cong suc (length-%= xs k f)-------------------------------------------------------------------------- _[_]∷=_length-∷= : ∀ xs k (v : A) → length (xs [ k ]∷= v) ≡ length xslength-∷= xs k v = length-%= xs k (const v)map-∷= : ∀ xs k (v : A) (f : A → B) →let eq = sym (length-map f xs) inmap f (xs [ k ]∷= v) ≡ map f xs [ cast eq k ]∷= f vmap-∷= (x ∷ xs) zero v f = reflmap-∷= (x ∷ xs) (suc k) v f = cong (f x ∷_) (map-∷= xs k v f)-------------------------------------------------------------------------- insertAtlength-insertAt : ∀ (xs : List A) (i : Fin (suc (length xs))) v →length (insertAt xs i v) ≡ suc (length xs)length-insertAt xs zero v = refllength-insertAt (x ∷ xs) (suc i) v = cong suc (length-insertAt xs i v)-------------------------------------------------------------------------- removeAtlength-removeAt : ∀ (xs : List A) k → length (removeAt xs k) ≡ pred (length xs)length-removeAt (x ∷ xs) zero = refllength-removeAt (x ∷ xs@(_ ∷ _)) (suc k) = cong suc (length-removeAt xs k)length-removeAt′ : ∀ (xs : List A) k → length xs ≡ suc (length (removeAt xs k))length-removeAt′ xs@(_ ∷ _) k rewrite length-removeAt xs k = reflmap-removeAt : ∀ xs k (f : A → B) →let eq = sym (length-map f xs) inmap f (removeAt xs k) ≡ removeAt (map f xs) (cast eq k)map-removeAt (x ∷ xs) zero f = reflmap-removeAt (x ∷ xs) (suc k) f = cong (f x ∷_) (map-removeAt xs k f)-------------------------------------------------------------------------- insertAt and removeAtremoveAt-insertAt : ∀ (xs : List A) (i : Fin (suc (length xs))) v →removeAt (insertAt xs i v) ((cast (sym (length-insertAt xs i v)) i)) ≡ xsremoveAt-insertAt xs zero v = reflremoveAt-insertAt (x ∷ xs) (suc i) v = cong (_ ∷_) (removeAt-insertAt xs i v)insertAt-removeAt : (xs : List A) (i : Fin (length xs)) →insertAt (removeAt xs i) (cast (length-removeAt′ xs i) i) (lookup xs i) ≡ xsinsertAt-removeAt (x ∷ xs) zero = reflinsertAt-removeAt (x ∷ xs) (suc i) = cong (x ∷_) (insertAt-removeAt xs i)-------------------------------------------------------------------------- takelength-take : ∀ n (xs : List A) → length (take n xs) ≡ n ⊓ (length xs)length-take zero xs = refllength-take (suc n) [] = refllength-take (suc n) (x ∷ xs) = cong suc (length-take n xs)-- Take commutes with map.take-map : ∀ {f : A → B} (n : ℕ) xs → take n (map f xs) ≡ map f (take n xs)take-map zero xs = refltake-map (suc s) [] = refltake-map (suc s) (a ∷ xs) = cong (_ ∷_) (take-map s xs)take-suc : (xs : List A) (i : Fin (length xs)) → let m = toℕ i intake (suc m) xs ≡ take m xs ∷ʳ lookup xs itake-suc (x ∷ xs) zero = refltake-suc (x ∷ xs) (suc i) = cong (x ∷_) (take-suc xs i)take-suc-tabulate : ∀ {n} (f : Fin n → A) (i : Fin n) → let m = toℕ i intake (suc m) (tabulate f) ≡ take m (tabulate f) ∷ʳ f itake-suc-tabulate f i rewrite sym (toℕ-cast (sym (length-tabulate f)) i) | sym (lookup-tabulate f i)= take-suc (tabulate f) (cast _ i)-- If you take at least as many elements from a list as it has, you get-- the whole list.take-all : (n : ℕ) (xs : List A) → n ≥ length xs → take n xs ≡ xstake-all zero [] _ = refltake-all (suc _) [] _ = refltake-all (suc n) (x ∷ xs) (s≤s pf) = cong (x ∷_) (take-all n xs pf)-- Taking from an empty list does nothing.take-[] : ∀ m → take {A = A} m [] ≡ []take-[] zero = refltake-[] (suc m) = refl-- Taking twice takes the minimum of both counts.take-take : ∀ n m (xs : List A) → take n (take m xs) ≡ take (n ⊓ m) xstake-take zero m xs = refltake-take (suc n) zero xs = refltake-take (suc n) (suc m) [] = refltake-take (suc n) (suc m) (x ∷ xs) = cong (x ∷_) (take-take n m xs)-- Dropping m elements and then taking n is the same as-- taking n + m elements and then dropping m.take-drop : ∀ n m (xs : List A) →take n (drop m xs) ≡ drop m (take (m + n) xs)take-drop n zero xs = refltake-drop n (suc m) [] = take-[] ntake-drop n (suc m) (x ∷ xs) = take-drop n m xs-------------------------------------------------------------------------- droplength-drop : ∀ n (xs : List A) → length (drop n xs) ≡ length xs ∸ nlength-drop zero xs = refllength-drop (suc n) [] = refllength-drop (suc n) (x ∷ xs) = length-drop n xs-- Drop commutes with map.drop-map : ∀ {f : A → B} (n : ℕ) xs → drop n (map f xs) ≡ map f (drop n xs)drop-map zero xs = refldrop-map (suc n) [] = refldrop-map (suc n) (a ∷ xs) = drop-map n xs-- Dropping from an empty list does nothing.drop-[] : ∀ m → drop {A = A} m [] ≡ []drop-[] zero = refldrop-[] (suc m) = refltake++drop≡id : ∀ n (xs : List A) → take n xs ++ drop n xs ≡ xstake++drop≡id zero xs = refltake++drop≡id (suc n) [] = refltake++drop≡id (suc n) (x ∷ xs) = cong (x ∷_) (take++drop≡id n xs)drop-take-suc : (xs : List A) (i : Fin (length xs)) → let m = toℕ i indrop m (take (suc m) xs) ≡ [ lookup xs i ]drop-take-suc (x ∷ xs) zero = refldrop-take-suc (x ∷ xs) (suc i) = drop-take-suc xs idrop-take-suc-tabulate : ∀ {n} (f : Fin n → A) (i : Fin n) → let m = toℕ i indrop m (take (suc m) (tabulate f)) ≡ [ f i ]drop-take-suc-tabulate f i rewrite sym (toℕ-cast (sym (length-tabulate f)) i) | sym (lookup-tabulate f i)= drop-take-suc (tabulate f) (cast _ i)-- Dropping m elements and then n elements is same as dropping m+n elementsdrop-drop : (m n : ℕ) → (xs : List A) → drop n (drop m xs) ≡ drop (m + n) xsdrop-drop zero n xs = refldrop-drop (suc m) n [] = drop-[] ndrop-drop (suc m) n (x ∷ xs) = drop-drop m n xsdrop-all : (n : ℕ) (xs : List A) → n ≥ length xs → drop n xs ≡ []drop-all n [] _ = drop-[] ndrop-all (suc n) (x ∷ xs) p = drop-all n xs (s≤s⁻¹ p)-------------------------------------------------------------------------- replicatelength-replicate : ∀ n {x : A} → length (replicate n x) ≡ nlength-replicate zero = refllength-replicate (suc n) = cong suc (length-replicate n)lookup-replicate : ∀ n (x : A) (i : Fin n) →lookup (replicate n x) (cast (sym (length-replicate n)) i) ≡ xlookup-replicate (suc n) x zero = refllookup-replicate (suc n) x (suc i) = lookup-replicate n x imap-replicate : ∀ (f : A → B) n (x : A) →map f (replicate n x) ≡ replicate n (f x)map-replicate f zero x = reflmap-replicate f (suc n) x = cong (_ ∷_) (map-replicate f n x)zipWith-replicate : ∀ n (_⊕_ : A → B → C) (x : A) (y : B) →zipWith _⊕_ (replicate n x) (replicate n y) ≡ replicate n (x ⊕ y)zipWith-replicate zero _⊕_ x y = reflzipWith-replicate (suc n) _⊕_ x y = cong (x ⊕ y ∷_) (zipWith-replicate n _⊕_ x y)-------------------------------------------------------------------------- iteratelength-iterate : ∀ f (x : A) n → length (iterate f x n) ≡ nlength-iterate f x zero = refllength-iterate f x (suc n) = cong suc (length-iterate f (f x) n)iterate-id : ∀ (x : A) n → iterate id x n ≡ replicate n xiterate-id x zero = refliterate-id x (suc n) = cong (_ ∷_) (iterate-id x n)lookup-iterate : ∀ f (x : A) n (i : Fin n) →lookup (iterate f x n) (cast (sym (length-iterate f x n)) i) ≡ ℕ.iterate f x (toℕ i)lookup-iterate f x (suc n) zero = refllookup-iterate f x (suc n) (suc i) = lookup-iterate f (f x) n i-------------------------------------------------------------------------- splitAtsplitAt-defn : ∀ n → splitAt {A = A} n ≗ < take n , drop n >splitAt-defn zero xs = reflsplitAt-defn (suc n) [] = reflsplitAt-defn (suc n) (x ∷ xs) = cong (Product.map (x ∷_) id) (splitAt-defn n xs)module _ (f : A → B) wheresplitAt-map : ∀ n → splitAt n ∘ map f ≗Product.map (map f) (map f) ∘ splitAt nsplitAt-map zero xs = reflsplitAt-map (suc n) [] = reflsplitAt-map (suc n) (x ∷ xs) =cong (Product.map₁ (f x ∷_)) (splitAt-map n xs)-------------------------------------------------------------------------- takeWhile, dropWhile, and spanmodule _ {P : Pred A p} (P? : Decidable P) wheretakeWhile++dropWhile : ∀ xs → takeWhile P? xs ++ dropWhile P? xs ≡ xstakeWhile++dropWhile [] = refltakeWhile++dropWhile (x ∷ xs) with does (P? x)... | true = cong (x ∷_) (takeWhile++dropWhile xs)... | false = reflspan-defn : span P? ≗ < takeWhile P? , dropWhile P? >span-defn [] = reflspan-defn (x ∷ xs) with does (P? x)... | true = cong (Product.map (x ∷_) id) (span-defn xs)... | false = refl-------------------------------------------------------------------------- filtermodule _ {P : Pred A p} (P? : Decidable P) wherelength-filter : ∀ xs → length (filter P? xs) ≤ length xslength-filter [] = z≤nlength-filter (x ∷ xs) with ih ← length-filter xs | does (P? x)... | false = m≤n⇒m≤1+n ih... | true = s≤s ihfilter-all : ∀ {xs} → All P xs → filter P? xs ≡ xsfilter-all {[]} [] = reflfilter-all {x ∷ xs} (px ∷ pxs) with P? x... | no ¬px = contradiction px ¬px... | true because _ = cong (x ∷_) (filter-all pxs)filter-notAll : ∀ xs → Any (∁ P) xs → length (filter P? xs) < length xsfilter-notAll (x ∷ xs) (here ¬px) with P? x... | false because _ = s≤s (length-filter xs)... | yes px = contradiction px ¬pxfilter-notAll (x ∷ xs) (there any) with ih ← filter-notAll xs any | does (P? x)... | false = m≤n⇒m≤1+n ih... | true = s≤s ihfilter-some : ∀ {xs} → Any P xs → 0 < length (filter P? xs)filter-some {x ∷ xs} (here px) with P? x... | true because _ = z<s... | no ¬px = contradiction px ¬pxfilter-some {x ∷ xs} (there pxs) with does (P? x)... | true = m≤n⇒m≤1+n (filter-some pxs)... | false = filter-some pxsfilter-none : ∀ {xs} → All (∁ P) xs → filter P? xs ≡ []filter-none {[]} [] = reflfilter-none {x ∷ xs} (¬px ∷ ¬pxs) with P? x... | false because _ = filter-none ¬pxs... | yes px = contradiction px ¬pxfilter-complete : ∀ {xs} → length (filter P? xs) ≡ length xs →filter P? xs ≡ xsfilter-complete {[]} eq = reflfilter-complete {x ∷ xs} eq with does (P? x)... | false = contradiction eq (<⇒≢ (s≤s (length-filter xs)))... | true = cong (x ∷_) (filter-complete (suc-injective eq))filter-accept : ∀ {x xs} → P x → filter P? (x ∷ xs) ≡ x ∷ (filter P? xs)filter-accept {x} Px with P? x... | true because _ = refl... | no ¬Px = contradiction Px ¬Pxfilter-reject : ∀ {x xs} → ¬ P x → filter P? (x ∷ xs) ≡ filter P? xsfilter-reject {x} ¬Px with P? x... | yes Px = contradiction Px ¬Px... | false because _ = reflfilter-idem : filter P? ∘ filter P? ≗ filter P?filter-idem [] = reflfilter-idem (x ∷ xs) with does (P? x) in eq... | false = filter-idem xs... | true rewrite eq = cong (x ∷_) (filter-idem xs)filter-++ : ∀ xs ys → filter P? (xs ++ ys) ≡ filter P? xs ++ filter P? ysfilter-++ [] ys = reflfilter-++ (x ∷ xs) ys with ih ← filter-++ xs ys | does (P? x)... | true = cong (x ∷_) ih... | false = ih-------------------------------------------------------------------------- derun and deduplicatemodule _ {R : Rel A p} (R? : B.Decidable R) wherelength-derun : ∀ xs → length (derun R? xs) ≤ length xslength-derun [] = ≤-refllength-derun (x ∷ []) = ≤-refllength-derun (x ∷ y ∷ xs) with ih ← length-derun (y ∷ xs) | does (R? x y)... | true = m≤n⇒m≤1+n ih... | false = s≤s ihlength-deduplicate : ∀ xs → length (deduplicate R? xs) ≤ length xslength-deduplicate [] = z≤nlength-deduplicate (x ∷ xs) = ≤-begin1 + length (filter (¬? ∘ R? x) r) ≤⟨ s≤s (length-filter (¬? ∘ R? x) r) ⟩1 + length r ≤⟨ s≤s (length-deduplicate xs) ⟩1 + length xs ≤-∎whereopen ≤-Reasoning renaming (begin_ to ≤-begin_; _∎ to _≤-∎)r = deduplicate R? xsderun-reject : ∀ {x y} xs → R x y → derun R? (x ∷ y ∷ xs) ≡ derun R? (y ∷ xs)derun-reject {x} {y} xs Rxy with R? x y... | yes _ = refl... | no ¬Rxy = contradiction Rxy ¬Rxyderun-accept : ∀ {x y} xs → ¬ R x y → derun R? (x ∷ y ∷ xs) ≡ x ∷ derun R? (y ∷ xs)derun-accept {x} {y} xs ¬Rxy with R? x y... | yes Rxy = contradiction Rxy ¬Rxy... | no _ = refl-------------------------------------------------------------------------- partitionmodule _ {P : Pred A p} (P? : Decidable P) wherepartition-defn : partition P? ≗ < filter P? , filter (∁? P?) >partition-defn [] = reflpartition-defn (x ∷ xs) with ih ← partition-defn xs | does (P? x)... | true = cong (Product.map (x ∷_) id) ih... | false = cong (Product.map id (x ∷_)) ihlength-partition : ∀ xs → (let (ys , zs) = partition P? xs) →length ys ≤ length xs × length zs ≤ length xslength-partition [] = z≤n , z≤nlength-partition (x ∷ xs) with ih ← length-partition xs | does (P? x)... | true = Product.map s≤s m≤n⇒m≤1+n ih... | false = Product.map m≤n⇒m≤1+n s≤s ih-------------------------------------------------------------------------- _ʳ++_ʳ++-defn : ∀ (xs : List A) {ys} → xs ʳ++ ys ≡ reverse xs ++ ysʳ++-defn [] = reflʳ++-defn (x ∷ xs) {ys} = begin(x ∷ xs) ʳ++ ys ≡⟨⟩xs ʳ++ x ∷ ys ≡⟨⟩xs ʳ++ [ x ] ++ ys ≡⟨ ʳ++-defn xs ⟩reverse xs ++ [ x ] ++ ys ≡⟨ sym (++-assoc (reverse xs) _ _) ⟩(reverse xs ++ [ x ]) ++ ys ≡⟨ cong (_++ ys) (sym (ʳ++-defn xs)) ⟩(xs ʳ++ [ x ]) ++ ys ≡⟨⟩reverse (x ∷ xs) ++ ys ∎-- Reverse-append of append is reverse-append after reverse-append.++-ʳ++ : ∀ (xs {ys zs} : List A) → (xs ++ ys) ʳ++ zs ≡ ys ʳ++ xs ʳ++ zs++-ʳ++ [] = refl++-ʳ++ (x ∷ xs) {ys} {zs} = begin(x ∷ xs ++ ys) ʳ++ zs ≡⟨⟩(xs ++ ys) ʳ++ x ∷ zs ≡⟨ ++-ʳ++ xs ⟩ys ʳ++ xs ʳ++ x ∷ zs ≡⟨⟩ys ʳ++ (x ∷ xs) ʳ++ zs ∎-- Reverse-append of reverse-append is commuted reverse-append after append.ʳ++-ʳ++ : ∀ (xs {ys zs} : List A) → (xs ʳ++ ys) ʳ++ zs ≡ ys ʳ++ xs ++ zsʳ++-ʳ++ [] = reflʳ++-ʳ++ (x ∷ xs) {ys} {zs} = begin((x ∷ xs) ʳ++ ys) ʳ++ zs ≡⟨⟩(xs ʳ++ x ∷ ys) ʳ++ zs ≡⟨ ʳ++-ʳ++ xs ⟩(x ∷ ys) ʳ++ xs ++ zs ≡⟨⟩ys ʳ++ (x ∷ xs) ++ zs ∎-- Length of reverse-appendlength-ʳ++ : ∀ (xs {ys} : List A) →length (xs ʳ++ ys) ≡ length xs + length yslength-ʳ++ [] = refllength-ʳ++ (x ∷ xs) {ys} = beginlength ((x ∷ xs) ʳ++ ys) ≡⟨⟩length (xs ʳ++ x ∷ ys) ≡⟨ length-ʳ++ xs ⟩length xs + length (x ∷ ys) ≡⟨ +-suc _ _ ⟩length (x ∷ xs) + length ys ∎-- map distributes over reverse-append.map-ʳ++ : (f : A → B) (xs {ys} : List A) →map f (xs ʳ++ ys) ≡ map f xs ʳ++ map f ysmap-ʳ++ f [] = reflmap-ʳ++ f (x ∷ xs) {ys} = beginmap f ((x ∷ xs) ʳ++ ys) ≡⟨⟩map f (xs ʳ++ x ∷ ys) ≡⟨ map-ʳ++ f xs ⟩map f xs ʳ++ map f (x ∷ ys) ≡⟨⟩map f xs ʳ++ f x ∷ map f ys ≡⟨⟩(f x ∷ map f xs) ʳ++ map f ys ≡⟨⟩map f (x ∷ xs) ʳ++ map f ys ∎-- A foldr after a reverse is a foldl.foldr-ʳ++ : ∀ (f : A → B → B) b xs {ys} →foldr f b (xs ʳ++ ys) ≡ foldl (flip f) (foldr f b ys) xsfoldr-ʳ++ f b [] {_} = reflfoldr-ʳ++ f b (x ∷ xs) {ys} = beginfoldr f b ((x ∷ xs) ʳ++ ys) ≡⟨⟩foldr f b (xs ʳ++ x ∷ ys) ≡⟨ foldr-ʳ++ f b xs ⟩foldl (flip f) (foldr f b (x ∷ ys)) xs ≡⟨⟩foldl (flip f) (f x (foldr f b ys)) xs ≡⟨⟩foldl (flip f) (foldr f b ys) (x ∷ xs) ∎-- A foldl after a reverse is a foldr.foldl-ʳ++ : ∀ (f : B → A → B) b xs {ys} →foldl f b (xs ʳ++ ys) ≡ foldl f (foldr (flip f) b xs) ysfoldl-ʳ++ f b [] {_} = reflfoldl-ʳ++ f b (x ∷ xs) {ys} = beginfoldl f b ((x ∷ xs) ʳ++ ys) ≡⟨⟩foldl f b (xs ʳ++ x ∷ ys) ≡⟨ foldl-ʳ++ f b xs ⟩foldl f (foldr (flip f) b xs) (x ∷ ys) ≡⟨⟩foldl f (f (foldr (flip f) b xs) x) ys ≡⟨⟩foldl f (foldr (flip f) b (x ∷ xs)) ys ∎-------------------------------------------------------------------------- reverse-- reverse of cons is snoc of reverse.unfold-reverse : ∀ (x : A) xs → reverse (x ∷ xs) ≡ reverse xs ∷ʳ xunfold-reverse x xs = ʳ++-defn xs-- reverse is an anti-homomorphism with respect to append.reverse-++ : (xs ys : List A) →reverse (xs ++ ys) ≡ reverse ys ++ reverse xsreverse-++ xs ys = beginreverse (xs ++ ys) ≡⟨⟩(xs ++ ys) ʳ++ [] ≡⟨ ++-ʳ++ xs ⟩ys ʳ++ xs ʳ++ [] ≡⟨⟩ys ʳ++ reverse xs ≡⟨ ʳ++-defn ys ⟩reverse ys ++ reverse xs ∎-- reverse is self-inverse.reverse-selfInverse : SelfInverse {A = List A} _≡_ reversereverse-selfInverse {x = xs} {y = ys} xs⁻¹≈ys = beginreverse ys ≡⟨⟩ys ʳ++ [] ≡⟨ cong (_ʳ++ []) xs⁻¹≈ys ⟨reverse xs ʳ++ [] ≡⟨⟩(xs ʳ++ []) ʳ++ [] ≡⟨ ʳ++-ʳ++ xs ⟩[] ʳ++ xs ++ [] ≡⟨⟩xs ++ [] ≡⟨ ++-identityʳ xs ⟩xs ∎-- reverse is involutive.reverse-involutive : Involutive {A = List A} _≡_ reversereverse-involutive = selfInverse⇒involutive reverse-selfInverse-- reverse is injective.reverse-injective : Injective {A = List A} _≡_ _≡_ reversereverse-injective = selfInverse⇒injective reverse-selfInverse-- reverse preserves length.length-reverse : ∀ (xs : List A) → length (reverse xs) ≡ length xslength-reverse xs = beginlength (reverse xs) ≡⟨⟩length (xs ʳ++ []) ≡⟨ length-ʳ++ xs ⟩length xs + 0 ≡⟨ +-identityʳ _ ⟩length xs ∎reverse-map : (f : A → B) → map f ∘ reverse ≗ reverse ∘ map freverse-map f xs = beginmap f (reverse xs) ≡⟨⟩map f (xs ʳ++ []) ≡⟨ map-ʳ++ f xs ⟩map f xs ʳ++ [] ≡⟨⟩reverse (map f xs) ∎reverse-foldr : ∀ (f : A → B → B) b →foldr f b ∘ reverse ≗ foldl (flip f) breverse-foldr f b xs = foldr-ʳ++ f b xsreverse-foldl : ∀ (f : B → A → B) b xs →foldl f b (reverse xs) ≡ foldr (flip f) b xsreverse-foldl f b xs = foldl-ʳ++ f b xs-------------------------------------------------------------------------- reverse, applyUpTo, and applyDownFromreverse-applyUpTo : ∀ (f : ℕ → A) n → reverse (applyUpTo f n) ≡ applyDownFrom f nreverse-applyUpTo f zero = reflreverse-applyUpTo f (suc n) = beginreverse (f 0 ∷ applyUpTo (f ∘ suc) n) ≡⟨ reverse-++ [ f 0 ] (applyUpTo (f ∘ suc) n) ⟩reverse (applyUpTo (f ∘ suc) n) ∷ʳ f 0 ≡⟨ cong (_∷ʳ f 0) (reverse-applyUpTo (f ∘ suc) n) ⟩applyDownFrom (f ∘ suc) n ∷ʳ f 0 ≡⟨ applyDownFrom-∷ʳ f n ⟩applyDownFrom f (suc n) ∎reverse-upTo : ∀ n → reverse (upTo n) ≡ downFrom nreverse-upTo = reverse-applyUpTo idreverse-applyDownFrom : ∀ (f : ℕ → A) n → reverse (applyDownFrom f n) ≡ applyUpTo f nreverse-applyDownFrom f zero = reflreverse-applyDownFrom f (suc n) = beginreverse (f n ∷ applyDownFrom f n) ≡⟨ reverse-++ [ f n ] (applyDownFrom f n) ⟩reverse (applyDownFrom f n) ∷ʳ f n ≡⟨ cong (_∷ʳ f n) (reverse-applyDownFrom f n) ⟩applyUpTo f n ∷ʳ f n ≡⟨ applyUpTo-∷ʳ f n ⟩applyUpTo f (suc n) ∎reverse-downFrom : ∀ n → reverse (downFrom n) ≡ upTo nreverse-downFrom = reverse-applyDownFrom id-------------------------------------------------------------------------- _∷ʳ_∷ʳ-injective : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y∷ʳ-injective [] [] refl = refl , refl∷ʳ-injective (x ∷ xs) (y ∷ ys) eq with refl , eq′ ← ∷-injective eq= Product.map (cong (x ∷_)) id (∷ʳ-injective xs ys eq′)∷ʳ-injective [] (_ ∷ _ ∷ _) ()∷ʳ-injective (_ ∷ _ ∷ _) [] ()∷ʳ-injectiveˡ : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys∷ʳ-injectiveˡ xs ys eq = proj₁ (∷ʳ-injective xs ys eq)∷ʳ-injectiveʳ : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y∷ʳ-injectiveʳ xs ys eq = proj₂ (∷ʳ-injective xs ys eq)∷ʳ-++ : ∀ xs (a : A) ys → xs ∷ʳ a ++ ys ≡ xs ++ a ∷ ys∷ʳ-++ xs a ys = ++-assoc xs [ a ] ys-------------------------------------------------------------------------- unconsmodule _ (f : A → B) where-- 'commute' List.uncons and List.map to obtain a Maybe.map and List.uncons.uncons-map : uncons ∘ map f ≗ Maybe.map (Product.map f (map f)) ∘ unconsuncons-map [] = refluncons-map (x ∷ xs) = refl-------------------------------------------------------------------------- headmodule _ {f : A → B} where-- 'commute' List.head and List.map to obtain a Maybe.map and List.head.head-map : head ∘ map f ≗ Maybe.map f ∘ headhead-map [] = reflhead-map (_ ∷ _) = refl-------------------------------------------------------------------------- lastmodule _ (f : A → B) where-- 'commute' List.last and List.map to obtain a Maybe.map and List.last.last-map : last ∘ map f ≗ Maybe.map f ∘ lastlast-map [] = refllast-map (x ∷ []) = refllast-map (x ∷ xs@(_ ∷ _)) = last-map xs-------------------------------------------------------------------------- tailmodule _ (f : A → B) where-- 'commute' List.tail and List.map to obtain a Maybe.map and List.tail.tail-map : tail ∘ map f ≗ Maybe.map (map f) ∘ tailtail-map [] = refltail-map (x ∷ xs) = refl-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-id₂ = map-id-local{-# WARNING_ON_USAGE map-id₂"Warning: map-id₂ was deprecated in v2.0.Please use map-id-local instead."#-}map-cong₂ = map-cong-local{-# WARNING_ON_USAGE map-id₂"Warning: map-cong₂ was deprecated in v2.0.Please use map-cong-local instead."#-}map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.0.Please use map-∘ instead."#-}map-++-commute = map-++{-# WARNING_ON_USAGE map-++-commute"Warning: map-++-commute was deprecated in v2.0.Please use map-++ instead."#-}sum-++-commute = sum-++{-# WARNING_ON_USAGE sum-++-commute"Warning: map-++-commute was deprecated in v2.0.Please use map-++ instead."#-}reverse-map-commute = reverse-map{-# WARNING_ON_USAGE reverse-map-commute"Warning: reverse-map-commute was deprecated in v2.0.Please use reverse-map instead."#-}reverse-++-commute = reverse-++{-# WARNING_ON_USAGE reverse-++-commute"Warning: reverse-++-commute was deprecated in v2.0.Please use reverse-++ instead."#-}zipWith-identityˡ = zipWith-zeroˡ{-# WARNING_ON_USAGE zipWith-identityˡ"Warning: zipWith-identityˡ was deprecated in v2.0.Please use zipWith-zeroˡ instead."#-}zipWith-identityʳ = zipWith-zeroʳ{-# WARNING_ON_USAGE zipWith-identityʳ"Warning: zipWith-identityʳ was deprecated in v2.0.Please use zipWith-zeroʳ instead."#-}ʳ++-++ = ++-ʳ++{-# WARNING_ON_USAGE ʳ++-++"Warning: ʳ++-++ was deprecated in v2.0.Please use ++-ʳ++ instead."#-}take++drop = take++drop≡id{-# WARNING_ON_USAGE take++drop"Warning: take++drop was deprecated in v2.0.Please use take++drop≡id instead."#-}length-─ = length-removeAt{-# WARNING_ON_USAGE length-─"Warning: length-─ was deprecated in v2.0.Please use length-removeAt instead."#-}map-─ = map-removeAt{-# WARNING_ON_USAGE map-─"Warning: map-─ was deprecated in v2.0.Please use map-removeAt instead."#-}-- Version 2.1scanr-defn : ∀ (f : A → B → B) (e : B) →scanr f e ≗ map (foldr f e) ∘ tailsscanr-defn f e [] = reflscanr-defn f e (x ∷ []) = reflscanr-defn f e (x ∷ xs@(_ ∷ _))with eq ← scanr-defn f e xswith ys@(_ ∷ _) ← scanr f e xs= cong₂ (λ z → f x z ∷_) (∷-injectiveˡ eq) eq{-# WARNING_ON_USAGE scanr-defn"Warning: scanr-defn was deprecated in v2.1.Please use Data.List.Scans.Properties.scanr-defn instead."#-}scanl-defn : ∀ (f : A → B → A) (e : A) →scanl f e ≗ map (foldl f e) ∘ initsscanl-defn f e [] = reflscanl-defn f e (x ∷ xs) = cong (e ∷_) (beginscanl f (f e x) xs≡⟨ scanl-defn f (f e x) xs ⟩map (foldl f (f e x)) (inits xs)≡⟨ refl ⟩map (foldl f e ∘ (x ∷_)) (inits xs)≡⟨ map-∘ (inits xs) ⟩map (foldl f e) (map (x ∷_) (inits xs))∎){-# WARNING_ON_USAGE scanl-defn"Warning: scanl-defn was deprecated in v2.1.Please use Data.List.Scans.Properties.scanl-defn instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Non-empty lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty whereopen import Level using (Level)open import Data.List.Base as List using (List)-------------------------------------------------------------------------- Re-export basic type and operationsopen import Data.List.NonEmpty.Base public-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.privatevariablea : LevelA : Set a-- Version 1.4infixl 5 _∷ʳ'__∷ʳ'_ : (xs : List A) (x : A) → SnocView (xs ∷ʳ x)_∷ʳ'_ = SnocView._∷ʳ′_{-# WARNING_ON_USAGE _∷ʳ'_"Warning: _∷ʳ'_ (ending in an apostrophe) was deprecated in v1.4.Please use _∷ʳ′_ (ending in a prime) instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Non-empty lists where all elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Relation.Unary.All whereimport Data.List.Relation.Unary.All as Listopen import Data.List.Relation.Unary.All using ([]; _∷_)open import Data.List.Base using ([]; _∷_)open import Data.List.NonEmpty.Base using (List⁺; _∷_; toList)open import Levelopen import Relation.Unary using (Pred)privatevariablea p : LevelA : Set aP : Pred A p-------------------------------------------------------------------------- Definition-- Given a predicate P, then All P xs means that every element in xs-- satisfies P. See `Relation.Unary` for an explanation of predicates.infixr 5 _∷_data All {A : Set a} (P : Pred A p) : Pred (List⁺ A) (a ⊔ p) where_∷_ : ∀ {x xs} (px : P x) (pxs : List.All P xs) → All P (x ∷ xs)-------------------------------------------------------------------------- FunctionstoList⁺ : ∀ {xs : List⁺ A} → All P xs → List.All P (toList xs)toList⁺ (px ∷ pxs) = px ∷ pxs
-------------------------------------------------------------------------- The Agda standard library---- Properties of non-empty lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Properties whereopen import Effect.Monad using (RawMonad)open import Data.Nat.Base using (suc; _+_)open import Data.Nat.Properties using (suc-injective)open import Data.Maybe.Properties using (just-injective)open import Data.Bool.Base using (Bool; true; false)open import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.List.Effectful using () renaming (monad to listMonad)open import Data.List.NonEmpty.Effectful using () renaming (monad to list⁺Monad)open import Data.List.NonEmptyusing (List⁺; _∷_; tail; head; toList; _⁺++_; _⁺++⁺_; _++⁺_; length; fromList;drop+; map; inits; tails; groupSeqs; ungroupSeqs)open import Data.List.NonEmpty.Relation.Unary.All using (All; toList⁺; _∷_)open import Data.List.Relation.Unary.All using ([]; _∷_) renaming (All to ListAll)import Data.List.Properties as Listopen import Data.Sum.Base using (inj₁; inj₂)open import Data.Sum.Relation.Unary.All using (inj₁; inj₂)import Data.Sum.Relation.Unary.All as Sum using (All; inj₁; inj₂)open import Level using (Level)open import Function.Base using (_∘_; _$_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; _≗_)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Unary using (Pred; Decidable; ∁)open import Relation.Nullary using (¬_; does; yes; no)open ≡-Reasoningprivatevariablea p : LevelA B C : Set aopen module LMo {a} = RawMonad {f = a} listMonadusing () renaming (_>>=_ to _⋆>>=_)open module L⁺Mo {a} = RawMonad {f = a} list⁺Monad-------------------------------------------------------------------------- toListη : ∀ (xs : List⁺ A) → head xs ∷ tail xs ≡ toList xsη _ = refltoList-fromList : ∀ x (xs : List A) → x ∷ xs ≡ toList (x ∷ xs)toList-fromList _ _ = refltoList-⁺++ : ∀ (xs : List⁺ A) ys → toList xs ++ ys ≡ toList (xs ⁺++ ys)toList-⁺++ _ _ = refltoList-⁺++⁺ : ∀ (xs ys : List⁺ A) →toList xs ++ toList ys ≡ toList (xs ⁺++⁺ ys)toList-⁺++⁺ _ _ = refltoList->>= : ∀ (f : A → List⁺ B) (xs : List⁺ A) →(toList xs ⋆>>= toList ∘ f) ≡ toList (xs >>= f)toList->>= f (x ∷ xs) = beginList.concat (List.map (toList ∘ f) (x ∷ xs))≡⟨ cong List.concat $ List.map-∘ {g = toList} (x ∷ xs) ⟩List.concat (List.map toList (List.map f (x ∷ xs)))∎-------------------------------------------------------------------------- _++⁺_length-++⁺ : (xs : List A) (ys : List⁺ A) →length (xs ++⁺ ys) ≡ List.length xs + length yslength-++⁺ [] ys = refllength-++⁺ (x ∷ xs) ys rewrite length-++⁺ xs ys = refllength-++⁺-tail : (xs : List A) (ys : List⁺ A) →length (xs ++⁺ ys) ≡ suc (List.length xs + List.length (List⁺.tail ys))length-++⁺-tail [] ys = refllength-++⁺-tail (x ∷ xs) ys rewrite length-++⁺-tail xs ys = refl++-++⁺ : (xs : List A) → ∀ {ys zs} → (xs ++ ys) ++⁺ zs ≡ xs ++⁺ ys ++⁺ zs++-++⁺ [] = refl++-++⁺ (x ∷ l) = cong (x ∷_) (cong toList (++-++⁺ l))++⁺-cancelˡ′ : ∀ xs ys {zs zs′ : List⁺ A} →xs ++⁺ zs ≡ ys ++⁺ zs′ →List.length xs ≡ List.length ys → zs ≡ zs′++⁺-cancelˡ′ [] [] eq eqxs = eq++⁺-cancelˡ′ (x ∷ xs) (y ∷ ys) eq eql = ++⁺-cancelˡ′ xs ys(just-injective (cong fromList (cong List⁺.tail eq)))(suc-injective eql)++⁺-cancelˡ : ∀ xs {ys zs : List⁺ A} → xs ++⁺ ys ≡ xs ++⁺ zs → ys ≡ zs++⁺-cancelˡ xs eq = ++⁺-cancelˡ′ xs xs eq refldrop-+-++⁺ : ∀ (xs : List A) ys → drop+ (List.length xs) (xs ++⁺ ys) ≡ ysdrop-+-++⁺ [] ys = refldrop-+-++⁺ (x ∷ xs) ys = drop-+-++⁺ xs ysmap-++⁺ : ∀ (f : A → B) xs ys →map f (xs ++⁺ ys) ≡ List.map f xs ++⁺ map f ysmap-++⁺ f [] ys = reflmap-++⁺ f (x ∷ xs) ys = cong (λ zs → f x ∷ toList zs) (map-++⁺ f xs ys)-------------------------------------------------------------------------- maplength-map : ∀ (f : A → B) xs → length (map f xs) ≡ length xslength-map f (_ ∷ xs) = cong suc (List.length-map f xs)map-cong : ∀ {f g : A → B} → f ≗ g → map f ≗ map gmap-cong f≗g (x ∷ xs) = cong₂ _∷_ (f≗g x) (List.map-cong f≗g xs)map-∘ : {g : B → C} {f : A → B} → map (g ∘ f) ≗ map g ∘ map fmap-∘ (x ∷ xs) = cong (_ ∷_) (List.map-∘ xs)-------------------------------------------------------------------------- initstoList-inits : toList ∘ inits ≗ List.inits {A = A}toList-inits _ = refl-------------------------------------------------------------------------- tailstoList-tails : toList ∘ tails ≗ List.tails {A = A}toList-tails _ = refl-------------------------------------------------------------------------- groupSeqs-- Groups all contiguous elements for which the predicate returns the-- same result into lists.module _ {P : Pred A p} (P? : Decidable P) wheregroupSeqs-groups : ∀ xs → ListAll (Sum.All (All P) (All (∁ P))) (groupSeqs P? xs)groupSeqs-groups [] = []groupSeqs-groups (x ∷ xs) with P? x | groupSeqs P? xs | groupSeqs-groups xs... | yes px | [] | hyp = inj₁ (px ∷ []) ∷ hyp... | yes px | inj₁ xs′ ∷ xss | inj₁ pxs ∷ pxss = inj₁ (px ∷ toList⁺ pxs) ∷ pxss... | yes px | inj₂ xs′ ∷ xss | inj₂ pxs ∷ pxss = inj₁ (px ∷ []) ∷ inj₂ pxs ∷ pxss... | no ¬px | [] | hyp = inj₂ (¬px ∷ []) ∷ hyp... | no ¬px | inj₂ xs′ ∷ xss | inj₂ pxs ∷ pxss = inj₂ (¬px ∷ toList⁺ pxs) ∷ pxss... | no ¬px | inj₁ xs′ ∷ xss | inj₁ pxs ∷ pxss = inj₂ (¬px ∷ []) ∷ inj₁ pxs ∷ pxssungroupSeqs-groupSeqs : ∀ xs → ungroupSeqs (groupSeqs P? xs) ≡ xsungroupSeqs-groupSeqs [] = reflungroupSeqs-groupSeqs (x ∷ xs)with does (P? x) | groupSeqs P? xs | ungroupSeqs-groupSeqs xs... | true | [] | hyp = cong (x ∷_) hyp... | true | inj₁ _ ∷ _ | hyp = cong (x ∷_) hyp... | true | inj₂ _ ∷ _ | hyp = cong (x ∷_) hyp... | false | [] | hyp = cong (x ∷_) hyp... | false | inj₁ _ ∷ _ | hyp = cong (x ∷_) hyp... | false | inj₂ _ ∷ _ | hyp = cong (x ∷_) hyp-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.0.Please use map-∘ instead."#-}map-++⁺-commute = map-++⁺{-# WARNING_ON_USAGE map-++⁺-commute"Warning: map-++⁺-commute was deprecated in v2.0.Please use map-++⁺ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for List⁺------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Instances whereopen import Data.List.NonEmpty.Effectfulimport Data.List.NonEmpty.Effectful.Transformer as Transinstance-- List⁺ instancesnonEmptyListFunctor = functornonEmptyListApplicative = applicativenonEmptyListMonad = monadnonEmptyListComonad = comonad-- List⁺T instancesnonEmptyListTFunctor = λ {f} {g} {M} {{inst}} → Trans.functor {f} {g} {M} instnonEmptyListTApplicative = λ {f} {g} {M} {{inst}} → Trans.applicative {f} {g} {M} instnonEmptyListTMonad = λ {f} {g} {M} {{inst}} → Trans.monad {f} {g} {M} instnonEmptyListTMonadT = λ {f} {g} {M} {{inst}} → Trans.monadT {f} {g} {M} inst
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of List⁺------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Effectful whereopen import Agda.Builtin.Listimport Data.List.Effectful as Listopen import Data.List.NonEmpty.Baseopen import Data.Product.Base using (uncurry)open import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Effect.Comonadopen import Function.Base using (flip; _∘′_; _∘_)-------------------------------------------------------------------------- List⁺ applicative functorfunctor : ∀ {f} → RawFunctor {f} List⁺functor = record{ _<$>_ = map}applicative : ∀ {f} → RawApplicative {f} List⁺applicative = record{ rawFunctor = functor; pure = [_]; _<*>_ = ap}-------------------------------------------------------------------------- List⁺ monadmonad : ∀ {f} → RawMonad {f} List⁺monad = record{ rawApplicative = applicative; _>>=_ = flip concatMap}-------------------------------------------------------------------------- List⁺ comonadcomonad : ∀ {f} → RawComonad {f} List⁺comonad = record{ extract = head; extend = λ f → uncurry (extend f) ∘′ uncons} whereextend : ∀ {A B} → (List⁺ A → B) → A → List A → List⁺ Bextend f x xs@[] = f (x ∷ xs) ∷ []extend f x xs@(y ∷ ys) = f (x ∷ xs) ∷⁺ extend f y ys-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {f g F} (App : RawApplicative {f} {g} F) whereopen RawApplicative AppsequenceA : ∀ {A} → List⁺ (F A) → F (List⁺ A)sequenceA (x ∷ xs) = _∷_ <$> x ⊛ List.TraversableA.sequenceA App xsmapA : ∀ {a} {A : Set a} {B} → (A → F B) → List⁺ A → F (List⁺ B)mapA f = sequenceA ∘ map fforA : ∀ {a} {A : Set a} {B} → List⁺ A → (A → F B) → F (List⁺ B)forA = flip mapAmodule TraversableM {m n M} (Mon : RawMonad {m} {n} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of List------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Effectful.Transformer whereopen import Data.List.NonEmpty.Base as List⁺ using (List⁺; _∷_)open import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Baseopen import Level using (Level)import Data.List.NonEmpty.Effectful as List⁺privatevariablef g : LevelM : Set f → Set g-------------------------------------------------------------------------- List⁺ monad transformerrecord List⁺T (M : Set f → Set g) (A : Set f) : Set g whereconstructor mkList⁺Tfield runList⁺T : M (List⁺ A)open List⁺T publicfunctor : RawFunctor M → RawFunctor {f} (List⁺T M)functor M = record{ _<$>_ = λ f → mkList⁺T ∘′ (List⁺.map f <$>_) ∘′ runList⁺T} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative {f} (List⁺T M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkList⁺T ∘′ pure ∘′ List⁺.[_]; _<*>_ = λ mf ma → mkList⁺T (List⁺.ap <$> runList⁺T mf <*> runList⁺T ma)} where open RawApplicative Mmonad : RawMonad M → RawMonad (List⁺T M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ mas f → mkList⁺T $ doas ← runList⁺T masList⁺.concat <$> mapM (runList⁺T ∘′ f) as} where open RawMonad M; open List⁺.TraversableM MmonadT : RawMonadT {f} {g} List⁺TmonadT M = record{ lift = mkList⁺T ∘′ (List⁺.[_] <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.List.NonEmpty.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Categorical whereopen import Data.List.NonEmpty.Effectful public{-# WARNING_ON_IMPORT"Data.List.NonEmpty.Categorical was deprecated in v2.0.Use Data.List.NonEmpty.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.List.NonEmpty.Effectful.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Categorical.Transformer whereopen import Data.List.NonEmpty.Effectful.Transformer public{-# WARNING_ON_IMPORT"Data.List.NonEmpty.Categorical.Transformer was deprecated in v2.0.Use Data.List.NonEmpty.Effectful.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Non-empty lists: base type and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.NonEmpty.Base whereopen import Level using (Level)open import Data.Bool.Base using (Bool; false; true)open import Data.List.Base as List using (List; []; _∷_)open import Data.Maybe.Base using (Maybe ; nothing; just)open import Data.Nat.Base as ℕopen import Data.Product.Base as Prod using (∃; _×_; proj₁; proj₂; _,_; -,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Data.These.Base as These using (These; this; that; these)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Function.Baseopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl)open import Relation.Unary using (Pred; Decidable; U; ∅)open import Relation.Unary.Properties using (U?; ∅?)open import Relation.Nullary.Decidable using (does)privatevariablea p : LevelA B C : Set a-------------------------------------------------------------------------- Definitioninfixr 5 _∷_record List⁺ (A : Set a) : Set a whereconstructor _∷_fieldhead : Atail : List Aopen List⁺ public-------------------------------------------------------------------------- Basic combinatorsuncons : List⁺ A → A × List Auncons (hd ∷ tl) = hd , tl[_] : A → List⁺ A[ x ] = x ∷ []infixr 5 _∷⁺__∷⁺_ : A → List⁺ A → List⁺ Ax ∷⁺ y ∷ xs = x ∷ y ∷ xslength : List⁺ A → ℕlength (x ∷ xs) = suc (List.length xs)-------------------------------------------------------------------------- ConversiontoList : List⁺ A → List AtoList (x ∷ xs) = x ∷ xsfromList : List A → Maybe (List⁺ A)fromList [] = nothingfromList (x ∷ xs) = just (x ∷ xs)fromVec : ∀ {n} → Vec A (suc n) → List⁺ AfromVec (x ∷ xs) = x ∷ Vec.toList xstoVec : (xs : List⁺ A) → Vec A (length xs)toVec (x ∷ xs) = x ∷ Vec.fromList xslift : (∀ {m} → Vec A (suc m) → ∃ λ n → Vec B (suc n)) →List⁺ A → List⁺ Blift f xs = fromVec (proj₂ (f (toVec xs)))-------------------------------------------------------------------------- Other operationsmap : (A → B) → List⁺ A → List⁺ Bmap f (x ∷ xs) = (f x ∷ List.map f xs)replicate : ∀ n → n ≢ 0 → A → List⁺ Areplicate n n≢0 a = a ∷ List.replicate (pred n) a-- when dropping more than the size of the length of the list, the-- last element remainsdrop+ : ℕ → List⁺ A → List⁺ Adrop+ zero xs = xsdrop+ (suc n) (x ∷ []) = x ∷ []drop+ (suc n) (x ∷ y ∷ xs) = drop+ n (y ∷ xs)-- Right fold. Note that s is only applied to the last element (see-- the examples below).foldr : (A → B → B) → (A → B) → List⁺ A → Bfoldr {A = A} {B = B} c s (x ∷ xs) = foldr′ x xswherefoldr′ : A → List A → Bfoldr′ x [] = s xfoldr′ x (y ∷ xs) = c x (foldr′ y xs)-- Right fold.foldr₁ : (A → A → A) → List⁺ A → Afoldr₁ f = foldr f id-- Left fold. Note that s is only applied to the first element (see-- the examples below).foldl : (B → A → B) → (A → B) → List⁺ A → Bfoldl c s (x ∷ xs) = List.foldl c (s x) xs-- Left fold.foldl₁ : (A → A → A) → List⁺ A → Afoldl₁ f = foldl f id-- Append (several variants).infixr 5 _⁺++⁺_ _++⁺_ _⁺++__⁺++⁺_ : List⁺ A → List⁺ A → List⁺ A(x ∷ xs) ⁺++⁺ (y ∷ ys) = x ∷ (xs List.++ y ∷ ys)_⁺++_ : List⁺ A → List A → List⁺ A(x ∷ xs) ⁺++ ys = x ∷ (xs List.++ ys)_++⁺_ : List A → List⁺ A → List⁺ Axs ++⁺ ys = List.foldr _∷⁺_ ys xsconcat : List⁺ (List⁺ A) → List⁺ Aconcat (xs ∷ xss) = xs ⁺++ List.concat (List.map toList xss)concatMap : (A → List⁺ B) → List⁺ A → List⁺ BconcatMap f = concat ∘′ map fap : List⁺ (A → B) → List⁺ A → List⁺ Bap fs as = concatMap (λ f → map f as) fs-- Initsinits : List A → List⁺ (List A)inits xs = [] ∷ List.Inits.tail xs-- Tailstails : List A → List⁺ (List A)tails xs = xs ∷ List.Tails.tail xs-- Reversereverse : List⁺ A → List⁺ Areverse = lift (-,_ ∘′ Vec.reverse)-- Align and ZipalignWith : (These A B → C) → List⁺ A → List⁺ B → List⁺ CalignWith f (a ∷ as) (b ∷ bs) = f (these a b) ∷ List.alignWith f as bszipWith : (A → B → C) → List⁺ A → List⁺ B → List⁺ CzipWith f (a ∷ as) (b ∷ bs) = f a b ∷ List.zipWith f as bsunalignWith : (A → These B C) → List⁺ A → These (List⁺ B) (List⁺ C)unalignWith f = foldr (These.alignWith mcons mcons ∘′ f)(These.map [_] [_] ∘′ f)where mcons : ∀ {e} {E : Set e} → These E (List⁺ E) → List⁺ Emcons = These.fold [_] id _∷⁺_unzipWith : (A → B × C) → List⁺ A → List⁺ B × List⁺ CunzipWith f (a ∷ as) = Prod.zip _∷_ _∷_ (f a) (List.unzipWith f as)align : List⁺ A → List⁺ B → List⁺ (These A B)align = alignWith idzip : List⁺ A → List⁺ B → List⁺ (A × B)zip = zipWith _,_unalign : List⁺ (These A B) → These (List⁺ A) (List⁺ B)unalign = unalignWith idunzip : List⁺ (A × B) → List⁺ A × List⁺ Bunzip = unzipWith id-- Snoc.infixl 5 _∷ʳ_ _⁺∷ʳ__∷ʳ_ : List A → A → List⁺ A[] ∷ʳ y = [ y ](x ∷ xs) ∷ʳ y = x ∷ (xs List.∷ʳ y)_⁺∷ʳ_ : List⁺ A → A → List⁺ Axs ⁺∷ʳ x = toList xs ∷ʳ x-- A snoc-view of non-empty lists.infixl 5 _∷ʳ′_data SnocView {A : Set a} : List⁺ A → Set a where_∷ʳ′_ : (xs : List A) (x : A) → SnocView (xs ∷ʳ x)snocView : (xs : List⁺ A) → SnocView xssnocView (x ∷ xs) with List.initLast xssnocView (x ∷ .[]) | [] = [] ∷ʳ′ xsnocView (x ∷ .(xs List.∷ʳ y)) | xs List.∷ʳ′ y = (x ∷ xs) ∷ʳ′ y-- The last element in the list.privatelast′ : ∀ {l} → SnocView {A = A} l → Alast′ (_ ∷ʳ′ y) = ylast : List⁺ A → Alast = last′ ∘ snocView-- Groups all contiguous elements for which the predicate returns the-- same result into lists. The left sums are the ones for which the-- predicate holds, the right ones are the ones for which it doesn't.groupSeqsᵇ : (A → Bool) → List A → List (List⁺ A ⊎ List⁺ A)groupSeqsᵇ p [] = []groupSeqsᵇ p (x ∷ xs) with p x | groupSeqsᵇ p xs... | true | inj₁ xs′ ∷ xss = inj₁ (x ∷⁺ xs′) ∷ xss... | true | xss = inj₁ [ x ] ∷ xss... | false | inj₂ xs′ ∷ xss = inj₂ (x ∷⁺ xs′) ∷ xss... | false | xss = inj₂ [ x ] ∷ xss-- Groups all contiguous elements /not/ satisfying the predicate into-- lists. Elements satisfying the predicate are dropped.wordsByᵇ : (A → Bool) → List A → List (List⁺ A)wordsByᵇ p = List.mapMaybe Sum.[ const nothing , just ] ∘ groupSeqsᵇ pgroupSeqs : {P : Pred A p} → Decidable P → List A → List (List⁺ A ⊎ List⁺ A)groupSeqs P? = groupSeqsᵇ (does ∘ P?)wordsBy : {P : Pred A p} → Decidable P → List A → List (List⁺ A)wordsBy P? = wordsByᵇ (does ∘ P?)-- Inverse operation for groupSequences.ungroupSeqs : List (List⁺ A ⊎ List⁺ A) → List AungroupSeqs = List.concat ∘ List.map Sum.[ toList , toList ]-------------------------------------------------------------------------- Examples-- Note that these examples are simple unit tests, because the type-- checker verifies them.privatemodule Examples {A B : Set}(_⊕_ : A → B → B)(_⊗_ : B → A → B)(_⊙_ : A → A → A)(f : A → B)(a b c : A)wherehd : head (a ∷⁺ b ∷⁺ [ c ]) ≡ ahd = refltl : tail (a ∷⁺ b ∷⁺ [ c ]) ≡ b ∷ c ∷ []tl = reflmp : map f (a ∷⁺ b ∷⁺ [ c ]) ≡ f a ∷⁺ f b ∷⁺ [ f c ]mp = reflright : foldr _⊕_ f (a ∷⁺ b ∷⁺ [ c ]) ≡ (a ⊕ (b ⊕ f c))right = reflright₁ : foldr₁ _⊙_ (a ∷⁺ b ∷⁺ [ c ]) ≡ (a ⊙ (b ⊙ c))right₁ = reflleft : foldl _⊗_ f (a ∷⁺ b ∷⁺ [ c ]) ≡ ((f a ⊗ b) ⊗ c)left = reflleft₁ : foldl₁ _⊙_ (a ∷⁺ b ∷⁺ [ c ]) ≡ ((a ⊙ b) ⊙ c)left₁ = refl⁺app⁺ : (a ∷⁺ b ∷⁺ [ c ]) ⁺++⁺ (b ∷⁺ [ c ]) ≡a ∷⁺ b ∷⁺ c ∷⁺ b ∷⁺ [ c ]⁺app⁺ = refl⁺app : (a ∷⁺ b ∷⁺ [ c ]) ⁺++ (b ∷ c ∷ []) ≡a ∷⁺ b ∷⁺ c ∷⁺ b ∷⁺ [ c ]⁺app = reflapp⁺ : (a ∷ b ∷ c ∷ []) ++⁺ (b ∷⁺ [ c ]) ≡a ∷⁺ b ∷⁺ c ∷⁺ b ∷⁺ [ c ]app⁺ = reflconc : concat ((a ∷⁺ b ∷⁺ [ c ]) ∷⁺ [ b ∷⁺ [ c ] ]) ≡a ∷⁺ b ∷⁺ c ∷⁺ b ∷⁺ [ c ]conc = reflrev : reverse (a ∷⁺ b ∷⁺ [ c ]) ≡ c ∷⁺ b ∷⁺ [ a ]rev = reflsnoc : (a ∷ b ∷ c ∷ []) ∷ʳ a ≡ a ∷⁺ b ∷⁺ c ∷⁺ [ a ]snoc = reflsnoc⁺ : (a ∷⁺ b ∷⁺ [ c ]) ⁺∷ʳ a ≡ a ∷⁺ b ∷⁺ c ∷⁺ [ a ]snoc⁺ = reflgroupSeqs-true : groupSeqs U? (a ∷ b ∷ c ∷ []) ≡inj₁ (a ∷⁺ b ∷⁺ [ c ]) ∷ []groupSeqs-true = reflgroupSeqs-false : groupSeqs ∅? (a ∷ b ∷ c ∷ []) ≡inj₂ (a ∷⁺ b ∷⁺ [ c ]) ∷ []groupSeqs-false = reflgroupSeqs-≡1 : groupSeqsᵇ (ℕ._≡ᵇ 1) (1 ∷ 2 ∷ 3 ∷ 1 ∷ 1 ∷ 2 ∷ 1 ∷ []) ≡inj₁ [ 1 ] ∷inj₂ (2 ∷⁺ [ 3 ]) ∷inj₁ (1 ∷⁺ [ 1 ]) ∷inj₂ [ 2 ] ∷inj₁ [ 1 ] ∷[]groupSeqs-≡1 = reflwordsBy-true : wordsByᵇ (const true) (a ∷ b ∷ c ∷ []) ≡ []wordsBy-true = reflwordsBy-false : wordsByᵇ (const false) (a ∷ b ∷ c ∷ []) ≡(a ∷⁺ b ∷⁺ [ c ]) ∷ []wordsBy-false = reflwordsBy-≡1 : wordsByᵇ (ℕ._≡ᵇ 1) (1 ∷ 2 ∷ 3 ∷ 1 ∷ 1 ∷ 2 ∷ 1 ∷ []) ≡(2 ∷⁺ [ 3 ]) ∷[ 2 ] ∷[]wordsBy-≡1 = refl
-------------------------------------------------------------------------- The Agda standard library---- Nondependent N-ary functions manipulating lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Nary.NonDependent whereopen import Data.Nat.Base using (zero; suc)open import Data.List.Base as List using (List; []; _∷_)open import Data.Product.Base as Product using (_,_)open import Data.Product.Nary.NonDependent using (Product)open import Function.Base using ()open import Function.Nary.NonDependent.Base-------------------------------------------------------------------------- n-ary smart constructorsnilₙ : ∀ n {ls} {as : Sets n ls} → Product n (List <$> as)nilₙ 0 = _nilₙ 1 = []nilₙ (suc n@(suc _)) = [] , nilₙ nconsₙ : ∀ n {ls} {as : Sets n ls} →Product n as → Product n (List <$> as) → Product n (List <$> as)consₙ 0 _ _ = _consₙ 1 a as = a ∷ asconsₙ (suc n@(suc _)) (a , xs) (as , xss) = a ∷ as , consₙ n xs xss-------------------------------------------------------------------------- n-ary zipWith-like operationszipWith : ∀ n {ls} {as : Sets n ls} {r} {R : Set r} →Arrows n as R → Arrows n (List <$> as) (List R)zipWith 0 f = []zipWith 1 f xs = List.map f xszipWith (suc n@(suc _)) f xs ys =zipWith n (Product.uncurry f) (List.zipWith _,_ xs ys)unzipWith : ∀ n {ls} {as : Sets n ls} {a} {A : Set a} →(A → Product n as) → (List A → Product n (List <$> as))unzipWith n f [] = nilₙ nunzipWith n f (a ∷ as) = consₙ n (f a) (unzipWith n f as)
-------------------------------------------------------------------------- The Agda standard library---- List membership and some related definitions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.List.Membership.Setoid {c ℓ} (S : Setoid c ℓ) whereopen import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Unary.Any as Anyusing (Any; map; here; there)open import Data.Product.Base as Product using (∃; _×_; _,_)open import Function.Base using (_∘_; flip; const)open import Relation.Binary.Definitions using (_Respects_)open import Relation.Nullary.Negation using (¬_)open import Relation.Unary using (Pred)open Setoid S renaming (Carrier to A)-------------------------------------------------------------------------- Definitionsinfix 4 _∈_ _∉__∈_ : A → List A → Set _x ∈ xs = Any (x ≈_) xs_∉_ : A → List A → Set _x ∉ xs = ¬ x ∈ xs-------------------------------------------------------------------------- Operations_∷=_ = Any._∷=_ {A = A}_─_ = Any._─_ {A = A}mapWith∈ : ∀ {b} {B : Set b}(xs : List A) → (∀ {x} → x ∈ xs → B) → List BmapWith∈ [] f = []mapWith∈ (x ∷ xs) f = f (here refl) ∷ mapWith∈ xs (f ∘ there)-------------------------------------------------------------------------- Finding and losing witnessesmodule _ {p} {P : Pred A p} wherefind : ∀ {xs} → Any P xs → ∃ λ x → x ∈ xs × P xfind (here px) = _ , here refl , pxfind (there pxs) = let x , x∈xs , px = find pxs in x , there x∈xs , pxlose : P Respects _≈_ → ∀ {x xs} → x ∈ xs → P x → Any P xslose resp x∈xs px = map (flip resp px) x∈xs
-------------------------------------------------------------------------- The Agda standard library---- Properties related to setoid list membership------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Membership.Setoid.Properties whereopen import Algebra using (Op₂; Selective)open import Data.Bool.Base using (true; false)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Fin.Properties using (suc-injective)open import Data.List.Base hiding (find)import Data.List.Membership.Setoid as Membershipimport Data.List.Relation.Binary.Equality.Setoid as Equalityopen import Data.List.Relation.Unary.All as All using (All)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)import Data.List.Relation.Unary.Any.Properties as Anyimport Data.List.Relation.Unary.Unique.Setoid as Uniqueopen import Data.Nat.Base using (suc; z<s; _<_)open import Data.Product.Base as Product using (∃; _×_; _,_ ; ∃₂)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (_×ₛ_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (_$_; flip; _∘_; _∘′_; id)open import Function.Bundles using (_↔_)open import Level using (Level)open import Relation.Binary.Core using (Rel; _Preserves₂_⟶_⟶_; _Preserves_⟶_)open import Relation.Binary.Definitions as Binary hiding (Decidable)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary.Decidable using (does; _because_; yes; no)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Nullary.Reflects using (invert)open import Relation.Unary as Unary using (Decidable; Pred)open Setoid using (Carrier)privatevariablec c₁ c₂ c₃ p ℓ ℓ₁ ℓ₂ ℓ₃ : Level-------------------------------------------------------------------------- Equality propertiesmodule _ (S : Setoid c ℓ) whereopen Setoid Sopen Equality Sopen Membership S-- _∈_ respects the underlying equality∈-resp-≈ : ∀ {xs} → (_∈ xs) Respects _≈_∈-resp-≈ x≈y x∈xs = Any.map (trans (sym x≈y)) x∈xs∉-resp-≈ : ∀ {xs} → (_∉ xs) Respects _≈_∉-resp-≈ v≈w v∉xs w∈xs = v∉xs (∈-resp-≈ (sym v≈w) w∈xs)∈-resp-≋ : ∀ {x} → (x ∈_) Respects _≋_∈-resp-≋ = Any.lift-resp (flip trans)∉-resp-≋ : ∀ {x} → (x ∉_) Respects _≋_∉-resp-≋ xs≋ys v∉xs v∈ys = v∉xs (∈-resp-≋ (≋-sym xs≋ys) v∈ys)-- index is injective in its first argument.index-injective : ∀ {x₁ x₂ xs} (x₁∈xs : x₁ ∈ xs) (x₂∈xs : x₂ ∈ xs) →Any.index x₁∈xs ≡ Any.index x₂∈xs → x₁ ≈ x₂index-injective (here x₁≈x) (here x₂≈x) _ = trans x₁≈x (sym x₂≈x)index-injective (there x₁∈xs) (there x₂∈xs) eq = index-injective x₁∈xs x₂∈xs (suc-injective eq)-------------------------------------------------------------------------- Irrelevancemodule _ (S : Setoid c ℓ) whereopen Setoid Sopen Unique Sopen Membership Sprivate∉×∈⇒≉ : ∀ {x y xs} → All (y ≉_) xs → x ∈ xs → x ≉ y∉×∈⇒≉ = All.lookupWith λ y≉z x≈z x≈y → y≉z (trans (sym x≈y) x≈z)unique⇒irrelevant : Binary.Irrelevant _≈_ → ∀ {xs} → Unique xs → Unary.Irrelevant (_∈ xs)unique⇒irrelevant ≈-irr _ (here p) (here q) =≡.cong here (≈-irr p q)unique⇒irrelevant ≈-irr (_ ∷ u) (there p) (there q) =≡.cong there (unique⇒irrelevant ≈-irr u p q)unique⇒irrelevant ≈-irr (≉s ∷ _) (here p) (there q) =contradiction p (∉×∈⇒≉ ≉s q)unique⇒irrelevant ≈-irr (≉s ∷ _) (there p) (here q) =contradiction q (∉×∈⇒≉ ≉s p)-------------------------------------------------------------------------- mapWith∈module _ (S₁ : Setoid c₁ ℓ₁) (S₂ : Setoid c₂ ℓ₂) whereopen Setoid S₁ renaming (Carrier to A₁; _≈_ to _≈₁_; refl to refl₁)open Setoid S₂ renaming (Carrier to A₂; _≈_ to _≈₂_; refl to refl₂)open Equality S₁ using ([]; _∷_) renaming (_≋_ to _≋₁_)open Equality S₂ using () renaming (_≋_ to _≋₂_)open Membership S₁mapWith∈-cong : ∀ {xs ys} → xs ≋₁ ys →(f : ∀ {x} → x ∈ xs → A₂) →(g : ∀ {y} → y ∈ ys → A₂) →(∀ {x y} → x ≈₁ y → (x∈xs : x ∈ xs) (y∈ys : y ∈ ys) →f x∈xs ≈₂ g y∈ys) →mapWith∈ xs f ≋₂ mapWith∈ ys gmapWith∈-cong [] f g cong = []mapWith∈-cong (x≈y ∷ xs≋ys) f g cong =cong x≈y (here refl₁) (here refl₁) ∷mapWith∈-cong xs≋ys (f ∘ there) (g ∘ there)(λ x≈y x∈xs y∈ys → cong x≈y (there x∈xs) (there y∈ys))mapWith∈≗map : ∀ f xs → mapWith∈ xs (λ {x} _ → f x) ≋₂ map f xsmapWith∈≗map f [] = []mapWith∈≗map f (x ∷ xs) = refl₂ ∷ mapWith∈≗map f xsmodule _ (S : Setoid c ℓ) whereopen Setoid Sopen Membership Slength-mapWith∈ : ∀ {a} {A : Set a} xs {f : ∀ {x} → x ∈ xs → A} →length (mapWith∈ xs f) ≡ length xslength-mapWith∈ [] = ≡.refllength-mapWith∈ (x ∷ xs) = ≡.cong suc (length-mapWith∈ xs)mapWith∈-id : ∀ xs → mapWith∈ xs (λ {x} _ → x) ≡ xsmapWith∈-id [] = ≡.reflmapWith∈-id (x ∷ xs) = ≡.cong (x ∷_) (mapWith∈-id xs)map-mapWith∈ : ∀ {a b} {A : Set a} {B : Set b} →∀ xs (f : ∀ {x} → x ∈ xs → A) (g : A → B) →map g (mapWith∈ xs f) ≡ mapWith∈ xs (g ∘′ f)map-mapWith∈ [] f g = ≡.reflmap-mapWith∈ (x ∷ xs) f g = ≡.cong (_ ∷_) (map-mapWith∈ xs (f ∘ there) g)-------------------------------------------------------------------------- mapmodule _ (S₁ : Setoid c₁ ℓ₁) (S₂ : Setoid c₂ ℓ₂) whereopen Setoid S₁ renaming (_≈_ to _≈₁_)open Setoid S₂ renaming (_≈_ to _≈₂_)private module M₁ = Membership S₁; open M₁ using (find) renaming (_∈_ to _∈₁_)private module M₂ = Membership S₂; open M₂ using () renaming (_∈_ to _∈₂_)∈-map⁺ : ∀ {f} → f Preserves _≈₁_ ⟶ _≈₂_ →∀ {v xs} → v ∈₁ xs → f v ∈₂ map f xs∈-map⁺ pres x∈xs = Any.map⁺ (Any.map pres x∈xs)∈-map⁻ : ∀ {v xs f} → v ∈₂ map f xs →∃ λ x → x ∈₁ xs × v ≈₂ f x∈-map⁻ x∈map = find (Any.map⁻ x∈map)map-∷= : ∀ {f} (pres : f Preserves _≈₁_ ⟶ _≈₂_) →∀ {xs x v} → (x∈xs : x ∈₁ xs) →map f (x∈xs M₁.∷= v) ≡ ∈-map⁺ pres x∈xs M₂.∷= f vmap-∷= pres (here x≈y) = ≡.reflmap-∷= pres (there x∈xs) = ≡.cong (_ ∷_) (map-∷= pres x∈xs)-------------------------------------------------------------------------- _++_module _ (S : Setoid c ℓ) whereopen Membership S using (_∈_)open Setoid Sopen Equality S using (_≋_; _∷_; ≋-refl)∈-++⁺ˡ : ∀ {v xs ys} → v ∈ xs → v ∈ xs ++ ys∈-++⁺ˡ = Any.++⁺ˡ∈-++⁺ʳ : ∀ {v} xs {ys} → v ∈ ys → v ∈ xs ++ ys∈-++⁺ʳ = Any.++⁺ʳ∈-++⁻ : ∀ {v} xs {ys} → v ∈ xs ++ ys → (v ∈ xs) ⊎ (v ∈ ys)∈-++⁻ = Any.++⁻∈-++⁺∘++⁻ : ∀ {v} xs {ys} (p : v ∈ xs ++ ys) →[ ∈-++⁺ˡ , ∈-++⁺ʳ xs ]′ (∈-++⁻ xs p) ≡ p∈-++⁺∘++⁻ = Any.++⁺∘++⁻∈-++⁻∘++⁺ : ∀ {v} xs {ys} (p : v ∈ xs ⊎ v ∈ ys) →∈-++⁻ xs ([ ∈-++⁺ˡ , ∈-++⁺ʳ xs ]′ p) ≡ p∈-++⁻∘++⁺ = Any.++⁻∘++⁺∈-++↔ : ∀ {v xs ys} → (v ∈ xs ⊎ v ∈ ys) ↔ v ∈ xs ++ ys∈-++↔ = Any.++↔∈-++-comm : ∀ {v} xs ys → v ∈ xs ++ ys → v ∈ ys ++ xs∈-++-comm = Any.++-comm∈-++-comm∘++-comm : ∀ {v} xs {ys} (p : v ∈ xs ++ ys) →∈-++-comm ys xs (∈-++-comm xs ys p) ≡ p∈-++-comm∘++-comm = Any.++-comm∘++-comm∈-++↔++ : ∀ {v} xs ys → v ∈ xs ++ ys ↔ v ∈ ys ++ xs∈-++↔++ = Any.++↔++∈-insert : ∀ xs {ys v w} → v ≈ w → v ∈ xs ++ [ w ] ++ ys∈-insert xs = Any.++-insert xs∈-∃++ : ∀ {v xs} → v ∈ xs → ∃₂ λ ys zs → ∃ λ w →v ≈ w × xs ≋ ys ++ [ w ] ++ zs∈-∃++ (here px) = [] , _ , _ , px , ≋-refl∈-∃++ (there {d} v∈xs) =let hs , _ , _ , v≈v′ , eq = ∈-∃++ v∈xsin d ∷ hs , _ , _ , v≈v′ , refl ∷ eq-------------------------------------------------------------------------- concatmodule _ (S : Setoid c ℓ) whereopen Setoid S using (_≈_)open Membership S using (_∈_)open Equality S using (≋-setoid)open Membership ≋-setoid using (find) renaming (_∈_ to _∈ₗ_)∈-concat⁺ : ∀ {v xss} → Any (v ∈_) xss → v ∈ concat xss∈-concat⁺ = Any.concat⁺∈-concat⁻ : ∀ {v} xss → v ∈ concat xss → Any (v ∈_) xss∈-concat⁻ = Any.concat⁻∈-concat⁺′ : ∀ {v vs xss} → v ∈ vs → vs ∈ₗ xss → v ∈ concat xss∈-concat⁺′ v∈vs = ∈-concat⁺ ∘ Any.map (flip (∈-resp-≋ S) v∈vs)∈-concat⁻′ : ∀ {v} xss → v ∈ concat xss → ∃ λ xs → v ∈ xs × xs ∈ₗ xss∈-concat⁻′ xss v∈c[xss] =let xs , xs∈xss , v∈xs = find (∈-concat⁻ xss v∈c[xss]) in xs , v∈xs , xs∈xss-------------------------------------------------------------------------- reversemodule _ (S : Setoid c ℓ) whereopen Membership S using (_∈_)reverse⁺ : ∀ {x xs} → x ∈ xs → x ∈ reverse xsreverse⁺ = Any.reverse⁺reverse⁻ : ∀ {x xs} → x ∈ reverse xs → x ∈ xsreverse⁻ = Any.reverse⁻-------------------------------------------------------------------------- cartesianProductWithmodule _ (S₁ : Setoid c₁ ℓ₁) (S₂ : Setoid c₂ ℓ₂) (S₃ : Setoid c₃ ℓ₃) whereopen Setoid S₁ renaming (_≈_ to _≈₁_; refl to refl₁)open Setoid S₂ renaming (_≈_ to _≈₂_)open Setoid S₃ renaming (_≈_ to _≈₃_)open Membership S₁ renaming (_∈_ to _∈₁_)open Membership S₂ renaming (_∈_ to _∈₂_)open Membership S₃ renaming (_∈_ to _∈₃_)∈-cartesianProductWith⁺ : ∀ {f} → f Preserves₂ _≈₁_ ⟶ _≈₂_ ⟶ _≈₃_ →∀ {xs ys a b} → a ∈₁ xs → b ∈₂ ys →f a b ∈₃ cartesianProductWith f xs ys∈-cartesianProductWith⁺ pres = Any.cartesianProductWith⁺ _ pres∈-cartesianProductWith⁻ : ∀ f xs ys {v} → v ∈₃ cartesianProductWith f xs ys →∃₂ λ a b → a ∈₁ xs × b ∈₂ ys × v ≈₃ f a b∈-cartesianProductWith⁻ f (x ∷ xs) ys v∈c with ∈-++⁻ S₃ (map (f x) ys) v∈c... | inj₁ v∈map =let b , b∈ys , v≈fxb = ∈-map⁻ S₂ S₃ v∈mapin x , b , here refl₁ , b∈ys , v≈fxb... | inj₂ v∈com =let a , b , a∈xs , b∈ys , v≈fab = ∈-cartesianProductWith⁻ f xs ys v∈comin a , b , there a∈xs , b∈ys , v≈fab-------------------------------------------------------------------------- cartesianProductmodule _ (S₁ : Setoid c₁ ℓ₁) (S₂ : Setoid c₂ ℓ₂) whereopen Setoid S₁ renaming (Carrier to A)open Setoid S₂ renaming (Carrier to B)open Membership S₁ renaming (_∈_ to _∈₁_)open Membership S₂ renaming (_∈_ to _∈₂_)open Membership (S₁ ×ₛ S₂) renaming (_∈_ to _∈₁₂_)∈-cartesianProduct⁺ : ∀ {x y xs ys} → x ∈₁ xs → y ∈₂ ys →(x , y) ∈₁₂ cartesianProduct xs ys∈-cartesianProduct⁺ = Any.cartesianProduct⁺∈-cartesianProduct⁻ : ∀ xs ys {xy@(x , y) : A × B} →xy ∈₁₂ cartesianProduct xs ys →x ∈₁ xs × y ∈₂ ys∈-cartesianProduct⁻ xs ys = Any.cartesianProduct⁻ xs ys-------------------------------------------------------------------------- applyUpTomodule _ (S : Setoid c ℓ) whereopen Setoid S using (_≈_; refl)open Membership S using (_∈_)∈-applyUpTo⁺ : ∀ f {i n} → i < n → f i ∈ applyUpTo f n∈-applyUpTo⁺ f = Any.applyUpTo⁺ f refl∈-applyUpTo⁻ : ∀ {v} f {n} → v ∈ applyUpTo f n →∃ λ i → i < n × v ≈ f i∈-applyUpTo⁻ = Any.applyUpTo⁻-------------------------------------------------------------------------- applyDownFrom∈-applyDownFrom⁺ : ∀ f {i n} → i < n → f i ∈ applyDownFrom f n∈-applyDownFrom⁺ f = Any.applyDownFrom⁺ f refl∈-applyDownFrom⁻ : ∀ {v} f {n} → v ∈ applyDownFrom f n →∃ λ i → i < n × v ≈ f i∈-applyDownFrom⁻ = Any.applyDownFrom⁻-------------------------------------------------------------------------- tabulatemodule _ (S : Setoid c ℓ) whereopen Setoid S using (_≈_; refl) renaming (Carrier to A)open Membership S using (_∈_)∈-tabulate⁺ : ∀ {n} {f : Fin n → A} i → f i ∈ tabulate f∈-tabulate⁺ i = Any.tabulate⁺ i refl∈-tabulate⁻ : ∀ {n} {f : Fin n → A} {v} →v ∈ tabulate f → ∃ λ i → v ≈ f i∈-tabulate⁻ = Any.tabulate⁻-------------------------------------------------------------------------- filtermodule _ (S : Setoid c ℓ) {P : Pred (Carrier S) p}(P? : Decidable P) (resp : P Respects (Setoid._≈_ S)) whereopen Setoid S using (_≈_; sym)open Membership S using (_∈_)∈-filter⁺ : ∀ {v xs} → v ∈ xs → P v → v ∈ filter P? xs∈-filter⁺ {xs = x ∷ _} (here v≈x) Pv with P? x... | true because _ = here v≈x... | false because [¬Px] = contradiction (resp v≈x Pv) (invert [¬Px])∈-filter⁺ {xs = x ∷ _} (there v∈xs) Pv with does (P? x)... | true = there (∈-filter⁺ v∈xs Pv)... | false = ∈-filter⁺ v∈xs Pv∈-filter⁻ : ∀ {v xs} → v ∈ filter P? xs → v ∈ xs × P v∈-filter⁻ {xs = x ∷ xs} v∈f[x∷xs] with P? x... | false because _ = Product.map there id (∈-filter⁻ v∈f[x∷xs])... | true because [Px] with v∈f[x∷xs]... | here v≈x = here v≈x , resp (sym v≈x) (invert [Px])... | there v∈fxs = Product.map there id (∈-filter⁻ v∈fxs)-------------------------------------------------------------------------- derun and deduplicatemodule _ (S : Setoid c ℓ) {R : Rel (Carrier S) ℓ₂} (R? : Binary.Decidable R) whereopen Setoid S using (_≈_)open Membership S using (_∈_)∈-derun⁺ : _≈_ Respectsʳ R → ∀ {xs z} → z ∈ xs → z ∈ derun R? xs∈-derun⁺ ≈-resp-R z∈xs = Any.derun⁺ R? ≈-resp-R z∈xs∈-deduplicate⁺ : _≈_ Respectsʳ (flip R) → ∀ {xs z} →z ∈ xs → z ∈ deduplicate R? xs∈-deduplicate⁺ ≈-resp-R z∈xs = Any.deduplicate⁺ R? ≈-resp-R z∈xs∈-derun⁻ : ∀ xs {z} → z ∈ derun R? xs → z ∈ xs∈-derun⁻ xs z∈derun[R,xs] = Any.derun⁻ R? z∈derun[R,xs]∈-deduplicate⁻ : ∀ xs {z} → z ∈ deduplicate R? xs → z ∈ xs∈-deduplicate⁻ xs z∈dedup[R,xs] = Any.deduplicate⁻ R? z∈dedup[R,xs]-------------------------------------------------------------------------- lengthmodule _ (S : Setoid c ℓ) whereopen Membership S using (_∈_)∈-length : ∀ {x xs} → x ∈ xs → 0 < length xs∈-length (here px) = z<s∈-length (there x∈xs) = z<s-------------------------------------------------------------------------- lookupmodule _ (S : Setoid c ℓ) whereopen Setoid S using (refl)open Membership S using (_∈_)∈-lookup : ∀ xs i → lookup xs i ∈ xs∈-lookup (x ∷ xs) zero = here refl∈-lookup (x ∷ xs) (suc i) = there (∈-lookup xs i)-------------------------------------------------------------------------- foldrmodule _ (S : Setoid c ℓ) {_•_ : Op₂ (Carrier S)} whereopen Setoid S using (_≈_; refl; sym; trans)open Membership S using (_∈_)foldr-selective : Selective _≈_ _•_ → ∀ e xs →(foldr _•_ e xs ≈ e) ⊎ (foldr _•_ e xs ∈ xs)foldr-selective •-sel i [] = inj₁ reflfoldr-selective •-sel i (x ∷ xs) with •-sel x (foldr _•_ i xs)... | inj₁ x•f≈x = inj₂ (here x•f≈x)... | inj₂ x•f≈f with foldr-selective •-sel i xs... | inj₁ f≈i = inj₁ (trans x•f≈f f≈i)... | inj₂ f∈xs = inj₂ (∈-resp-≈ S (sym x•f≈f) (there f∈xs))-------------------------------------------------------------------------- _∷=_module _ (S : Setoid c ℓ) whereopen Setoid Sopen Membership S∈-∷=⁺-updated : ∀ {xs x v} (x∈xs : x ∈ xs) → v ∈ (x∈xs ∷= v)∈-∷=⁺-updated (here px) = here refl∈-∷=⁺-updated (there pxs) = there (∈-∷=⁺-updated pxs)∈-∷=⁺-untouched : ∀ {xs x y v} (x∈xs : x ∈ xs) → (¬ x ≈ y) → y ∈ xs → y ∈ (x∈xs ∷= v)∈-∷=⁺-untouched (here x≈z) x≉y (here y≈z) = contradiction (trans x≈z (sym y≈z)) x≉y∈-∷=⁺-untouched (here x≈z) x≉y (there y∈xs) = there y∈xs∈-∷=⁺-untouched (there x∈xs) x≉y (here y≈z) = here y≈z∈-∷=⁺-untouched (there x∈xs) x≉y (there y∈xs) = there (∈-∷=⁺-untouched x∈xs x≉y y∈xs)∈-∷=⁻ : ∀ {xs x y v} (x∈xs : x ∈ xs) → (¬ y ≈ v) → y ∈ (x∈xs ∷= v) → y ∈ xs∈-∷=⁻ (here x≈z) y≉v (here y≈v) = contradiction y≈v y≉v∈-∷=⁻ (here x≈z) y≉v (there y∈) = there y∈∈-∷=⁻ (there x∈xs) y≉v (here y≈z) = here y≈z∈-∷=⁻ (there x∈xs) y≉v (there y∈) = there (∈-∷=⁻ x∈xs y≉v y∈)
-------------------------------------------------------------------------- The Agda standard library---- Data.List.Any.Membership instantiated with propositional equality,-- along with some additional definitions.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Membership.Propositional {a} {A : Set a} whereopen import Data.List.Relation.Unary.Any using (Any)open import Relation.Binary.PropositionalEquality.Core using (_≡_; _≢_; resp; subst)open import Relation.Binary.PropositionalEquality.Properties using (setoid)import Data.List.Membership.Setoid as SetoidMembership-------------------------------------------------------------------------- Re-export contents of setoid membershipopen SetoidMembership (setoid A) public hiding (lose)-------------------------------------------------------------------------- Different membersinfix 4 _≢∈__≢∈_ : ∀ {x y : A} {xs} → x ∈ xs → y ∈ xs → Set __≢∈_ x∈xs y∈xs = ∀ x≡y → subst (_∈ _) x≡y x∈xs ≢ y∈xs-------------------------------------------------------------------------- Other operationslose : ∀ {p} {P : A → Set p} {x xs} → x ∈ xs → P x → Any P xslose = SetoidMembership.lose (setoid A) (resp _)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to propositional list membership------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Membership.Propositional.Properties whereopen import Algebra.Core using (Op₂)open import Algebra.Definitions using (Selective)open import Data.Fin.Base using (Fin)open import Data.List.Base as Listopen import Data.List.Effectful using (monad)open import Data.List.Membership.Propositionalusing (_∈_; _∉_; mapWith∈; _≢∈_)import Data.List.Membership.Setoid.Properties as Membershipopen import Data.List.Relation.Binary.Equality.Propositionalusing (_≋_; ≡⇒≋; ≋⇒≡)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Relation.Unary.Any.Propertiesusing (map↔; concat↔; >>=↔; ⊛↔; Any-cong; ⊗↔′; ¬Any[])open import Data.Nat.Base using (ℕ; suc; s≤s; _≤_; _<_; _≰_)open import Data.Nat.Propertiesusing (suc-injective; m≤n⇒m≤1+n; _≤?_; <⇒≢; ≰⇒>)open import Data.Product.Base using (∃; ∃₂; _×_; _,_)open import Data.Product.Properties using (×-≡,≡↔≡)open import Data.Product.Function.NonDependent.Propositional using (_×-cong_)import Data.Product.Function.Dependent.Propositional as Σopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Effect.Monad using (RawMonad)open import Function.Base using (_∘_; _∘′_; _$_; id; flip; _⟨_⟩_)open import Function.Definitions using (Injective)import Function.Related.Propositional as Relatedopen import Function.Bundles using (_↔_; _↣_; Injection)open import Function.Related.TypeIsomorphisms using (×-comm; ∃∃↔∃∃)open import Function.Construct.Identity using (↔-id)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions as Binary hiding (Decidable)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; refl; sym; trans; cong; cong₂; resp; _≗_)open import Relation.Binary.PropositionalEquality.Properties as ≡ using (setoid)import Relation.Binary.Properties.DecTotalOrder as DTOPropertiesopen import Relation.Nullary.Decidable.Coreusing (Dec; yes; no; ¬¬-excluded-middle)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Reflects using (invert)open import Relation.Unary using (_⟨×⟩_; Decidable)privateopen module ListMonad {ℓ} = RawMonad (monad {ℓ = ℓ})variableℓ : LevelA B C : Set ℓ-------------------------------------------------------------------------- Publicly re-export properties from Coreopen import Data.List.Membership.Propositional.Properties.Core public-------------------------------------------------------------------------- Equality∈-resp-≋ : ∀ {x : A} → (x ∈_) Respects _≋_∈-resp-≋ = Membership.∈-resp-≋ (≡.setoid _)∉-resp-≋ : ∀ {x : A} → (x ∉_) Respects _≋_∉-resp-≋ = Membership.∉-resp-≋ (≡.setoid _)-------------------------------------------------------------------------- mapWith∈mapWith∈-cong : ∀ (xs : List A) → (f g : ∀ {x} → x ∈ xs → B) →(∀ {x} → (x∈xs : x ∈ xs) → f x∈xs ≡ g x∈xs) →mapWith∈ xs f ≡ mapWith∈ xs gmapWith∈-cong [] f g cong = reflmapWith∈-cong (x ∷ xs) f g cong = cong₂ _∷_ (cong (here refl))(mapWith∈-cong xs (f ∘ there) (g ∘ there) (cong ∘ there))mapWith∈≗map : ∀ (f : A → B) xs → mapWith∈ xs (λ {x} _ → f x) ≡ map f xsmapWith∈≗map f xs =≋⇒≡ (Membership.mapWith∈≗map (≡.setoid _) (≡.setoid _) f xs)mapWith∈-id : (xs : List A) → mapWith∈ xs (λ {x} _ → x) ≡ xsmapWith∈-id = Membership.mapWith∈-id (≡.setoid _)map-mapWith∈ : (xs : List A) (f : ∀ {x} → x ∈ xs → B) (g : B → C) →map g (mapWith∈ xs f) ≡ mapWith∈ xs (g ∘′ f)map-mapWith∈ = Membership.map-mapWith∈ (≡.setoid _)-------------------------------------------------------------------------- mapmodule _ (f : A → B) where∈-map⁺ : ∀ {x xs} → x ∈ xs → f x ∈ map f xs∈-map⁺ = Membership.∈-map⁺ (≡.setoid A) (≡.setoid B) (cong f)∈-map⁻ : ∀ {y xs} → y ∈ map f xs → ∃ λ x → x ∈ xs × y ≡ f x∈-map⁻ = Membership.∈-map⁻ (≡.setoid A) (≡.setoid B)map-∈↔ : ∀ {y xs} → (∃ λ x → x ∈ xs × y ≡ f x) ↔ y ∈ map f xsmap-∈↔ {y} {xs} =(∃ λ x → x ∈ xs × y ≡ f x) ↔⟨ Any↔ ⟩Any (λ x → y ≡ f x) xs ↔⟨ map↔ ⟩y ∈ List.map f xs ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _++_module _ {v : A} where∈-++⁺ˡ : ∀ {xs ys} → v ∈ xs → v ∈ xs ++ ys∈-++⁺ˡ = Membership.∈-++⁺ˡ (≡.setoid A)∈-++⁺ʳ : ∀ xs {ys} → v ∈ ys → v ∈ xs ++ ys∈-++⁺ʳ = Membership.∈-++⁺ʳ (≡.setoid A)∈-++⁻ : ∀ xs {ys} → v ∈ xs ++ ys → (v ∈ xs) ⊎ (v ∈ ys)∈-++⁻ = Membership.∈-++⁻ (≡.setoid A)∈-insert : ∀ xs {ys} → v ∈ xs ++ [ v ] ++ ys∈-insert xs = Membership.∈-insert (≡.setoid A) xs refl∈-∃++ : ∀ {xs} → v ∈ xs → ∃₂ λ ys zs → xs ≡ ys ++ [ v ] ++ zs∈-∃++ v∈xswith ys , zs , _ , refl , eq ← Membership.∈-∃++ (≡.setoid A) v∈xs= ys , zs , ≋⇒≡ eq-------------------------------------------------------------------------- concatmodule _ {v : A} where∈-concat⁺ : ∀ {xss} → Any (v ∈_) xss → v ∈ concat xss∈-concat⁺ = Membership.∈-concat⁺ (≡.setoid A)∈-concat⁻ : ∀ xss → v ∈ concat xss → Any (v ∈_) xss∈-concat⁻ = Membership.∈-concat⁻ (≡.setoid A)∈-concat⁺′ : ∀ {vs xss} → v ∈ vs → vs ∈ xss → v ∈ concat xss∈-concat⁺′ v∈vs vs∈xss =Membership.∈-concat⁺′ (≡.setoid A) v∈vs (Any.map ≡⇒≋ vs∈xss)∈-concat⁻′ : ∀ xss → v ∈ concat xss → ∃ λ xs → v ∈ xs × xs ∈ xss∈-concat⁻′ xss v∈c =let xs , v∈xs , xs∈xss = Membership.∈-concat⁻′ (≡.setoid A) xss v∈cin xs , v∈xs , Any.map ≋⇒≡ xs∈xssconcat-∈↔ : ∀ {xss : List (List A)} →(∃ λ xs → v ∈ xs × xs ∈ xss) ↔ v ∈ concat xssconcat-∈↔ {xss} =(∃ λ xs → v ∈ xs × xs ∈ xss) ↔⟨ Σ.cong (↔-id _) $ ×-comm _ _ ⟩(∃ λ xs → xs ∈ xss × v ∈ xs) ↔⟨ Any↔ ⟩Any (Any (v ≡_)) xss ↔⟨ concat↔ ⟩v ∈ concat xss ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- cartesianProductWithmodule _ (f : A → B → C) where∈-cartesianProductWith⁺ : ∀ {xs ys a b} → a ∈ xs → b ∈ ys →f a b ∈ cartesianProductWith f xs ys∈-cartesianProductWith⁺ = Membership.∈-cartesianProductWith⁺(≡.setoid A) (≡.setoid B) (≡.setoid C) (cong₂ f)∈-cartesianProductWith⁻ : ∀ xs ys {v} → v ∈ cartesianProductWith f xs ys →∃₂ λ a b → a ∈ xs × b ∈ ys × v ≡ f a b∈-cartesianProductWith⁻ = Membership.∈-cartesianProductWith⁻(≡.setoid A) (≡.setoid B) (≡.setoid C) f-------------------------------------------------------------------------- cartesianProduct∈-cartesianProduct⁺ : ∀ {x : A} {y : B} {xs ys} → x ∈ xs → y ∈ ys →(x , y) ∈ cartesianProduct xs ys∈-cartesianProduct⁺ = ∈-cartesianProductWith⁺ _,_∈-cartesianProduct⁻ : ∀ xs ys {xy@(x , y) : A × B} →xy ∈ cartesianProduct xs ys → x ∈ xs × y ∈ ys∈-cartesianProduct⁻ xs ys xy∈p[xs,ys]with _ , _ , x∈xs , y∈ys , refl ← ∈-cartesianProductWith⁻ _,_ xs ys xy∈p[xs,ys]= x∈xs , y∈ys-------------------------------------------------------------------------- applyUpTomodule _ (f : ℕ → A) where∈-applyUpTo⁺ : ∀ {i n} → i < n → f i ∈ applyUpTo f n∈-applyUpTo⁺ = Membership.∈-applyUpTo⁺ (≡.setoid _) f∈-applyUpTo⁻ : ∀ {v n} → v ∈ applyUpTo f n →∃ λ i → i < n × v ≡ f i∈-applyUpTo⁻ = Membership.∈-applyUpTo⁻ (≡.setoid _) f-------------------------------------------------------------------------- upTo∈-upTo⁺ : ∀ {n i} → i < n → i ∈ upTo n∈-upTo⁺ = ∈-applyUpTo⁺ id∈-upTo⁻ : ∀ {n i} → i ∈ upTo n → i < n∈-upTo⁻ p with _ , i<n , refl ← ∈-applyUpTo⁻ id p = i<n-------------------------------------------------------------------------- applyDownFrommodule _ (f : ℕ → A) where∈-applyDownFrom⁺ : ∀ {i n} → i < n → f i ∈ applyDownFrom f n∈-applyDownFrom⁺ = Membership.∈-applyDownFrom⁺ (≡.setoid _) f∈-applyDownFrom⁻ : ∀ {v n} → v ∈ applyDownFrom f n →∃ λ i → i < n × v ≡ f i∈-applyDownFrom⁻ = Membership.∈-applyDownFrom⁻ (≡.setoid _) f-------------------------------------------------------------------------- downFrom∈-downFrom⁺ : ∀ {n i} → i < n → i ∈ downFrom n∈-downFrom⁺ i<n = ∈-applyDownFrom⁺ id i<n∈-downFrom⁻ : ∀ {n i} → i ∈ downFrom n → i < n∈-downFrom⁻ p with _ , i<n , refl ← ∈-applyDownFrom⁻ id p = i<n-------------------------------------------------------------------------- tabulatemodule _ {n} {f : Fin n → A} where∈-tabulate⁺ : ∀ i → f i ∈ tabulate f∈-tabulate⁺ = Membership.∈-tabulate⁺ (≡.setoid _)∈-tabulate⁻ : ∀ {v} → v ∈ tabulate f → ∃ λ i → v ≡ f i∈-tabulate⁻ = Membership.∈-tabulate⁻ (≡.setoid _)-------------------------------------------------------------------------- filtermodule _ {p} {P : A → Set p} (P? : Decidable P) where∈-filter⁺ : ∀ {x xs} → x ∈ xs → P x → x ∈ filter P? xs∈-filter⁺ = Membership.∈-filter⁺ (≡.setoid A) P? (≡.resp P)∈-filter⁻ : ∀ {v xs} → v ∈ filter P? xs → v ∈ xs × P v∈-filter⁻ = Membership.∈-filter⁻ (≡.setoid A) P? (≡.resp P)-------------------------------------------------------------------------- derun and deduplicatemodule _ {r} {R : Rel A r} (R? : Binary.Decidable R) where∈-derun⁻ : ∀ xs {z} → z ∈ derun R? xs → z ∈ xs∈-derun⁻ xs z∈derun[R,xs] = Membership.∈-derun⁻ (≡.setoid A) R? xs z∈derun[R,xs]∈-deduplicate⁻ : ∀ xs {z} → z ∈ deduplicate R? xs → z ∈ xs∈-deduplicate⁻ xs z∈dedup[R,xs] = Membership.∈-deduplicate⁻ (≡.setoid A) R? xs z∈dedup[R,xs]module _ (_≈?_ : DecidableEquality A) where∈-derun⁺ : ∀ {xs z} → z ∈ xs → z ∈ derun _≈?_ xs∈-derun⁺ z∈xs = Membership.∈-derun⁺ (≡.setoid A) _≈?_ (flip trans) z∈xs∈-deduplicate⁺ : ∀ {xs z} → z ∈ xs → z ∈ deduplicate _≈?_ xs∈-deduplicate⁺ z∈xs = Membership.∈-deduplicate⁺ (≡.setoid A) _≈?_ (λ c≡b a≡b → trans a≡b (sym c≡b)) z∈xs-------------------------------------------------------------------------- _>>=_>>=-∈↔ : ∀ {xs} {f : A → List B} {y} →(∃ λ x → x ∈ xs × y ∈ f x) ↔ y ∈ (xs >>= f)>>=-∈↔ {xs = xs} {f} {y} =(∃ λ x → x ∈ xs × y ∈ f x) ↔⟨ Any↔ ⟩Any (Any (y ≡_) ∘ f) xs ↔⟨ >>=↔ ⟩y ∈ (xs >>= f) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _⊛_⊛-∈↔ : ∀ (fs : List (A → B)) {xs y} →(∃₂ λ f x → f ∈ fs × x ∈ xs × y ≡ f x) ↔ y ∈ (fs ⊛ xs)⊛-∈↔ fs {xs} {y} =(∃₂ λ f x → f ∈ fs × x ∈ xs × y ≡ f x) ↔⟨ Σ.cong (↔-id _) (∃∃↔∃∃ _) ⟩(∃ λ f → f ∈ fs × ∃ λ x → x ∈ xs × y ≡ f x) ↔⟨ Σ.cong (↔-id _) (↔-id _ ⟨ _×-cong_ ⟩ Any↔) ⟩(∃ λ f → f ∈ fs × Any (_≡_ y ∘ f) xs) ↔⟨ Any↔ ⟩Any (λ f → Any (_≡_ y ∘ f) xs) fs ↔⟨ ⊛↔ ⟩y ∈ (fs ⊛ xs) ∎where open Related.EquationalReasoning-------------------------------------------------------------------------- _⊗_⊗-∈↔ : ∀ {xs ys} {x : A} {y : B} →(x ∈ xs × y ∈ ys) ↔ (x , y) ∈ (xs ⊗ ys)⊗-∈↔ {xs = xs} {ys} {x} {y} =(x ∈ xs × y ∈ ys) ↔⟨ ⊗↔′ ⟩Any (x ≡_ ⟨×⟩ y ≡_) (xs ⊗ ys) ↔⟨ Any-cong (λ _ → ×-≡,≡↔≡) (↔-id _) ⟩(x , y) ∈ (xs ⊗ ys) ∎whereopen Related.EquationalReasoning-------------------------------------------------------------------------- length∈-length : ∀ {x : A} {xs} → x ∈ xs → 0 < length xs∈-length = Membership.∈-length (≡.setoid _)-------------------------------------------------------------------------- lookup∈-lookup : ∀ {xs : List A} i → lookup xs i ∈ xs∈-lookup {xs = xs} i = Membership.∈-lookup (≡.setoid _) xs i-------------------------------------------------------------------------- foldrmodule _ {_•_ : Op₂ A} wherefoldr-selective : Selective _≡_ _•_ → ∀ e xs →(foldr _•_ e xs ≡ e) ⊎ (foldr _•_ e xs ∈ xs)foldr-selective = Membership.foldr-selective (≡.setoid A)-------------------------------------------------------------------------- allFin∈-allFin : ∀ {n} (k : Fin n) → k ∈ allFin n∈-allFin = ∈-tabulate⁺-------------------------------------------------------------------------- inits[]∈inits : ∀ {a} {A : Set a} (as : List A) → [] ∈ inits as[]∈inits _ = here refl-------------------------------------------------------------------------- Other properties-- Only a finite number of distinct elements can be members of a-- given list.finite : (inj : ℕ ↣ A) → ∀ xs → ¬ (∀ i → Injection.to inj i ∈ xs)finite inj [] fᵢ∈[] = ¬Any[] (fᵢ∈[] 0)finite inj (x ∷ xs) fᵢ∈x∷xs = ¬¬-excluded-middle helperwhereopen Injection inj renaming (injective to f-inj)f : ℕ → _f = tonot-x : ∀ {i} → f i ≢ x → f i ∈ xsnot-x {i} fᵢ≢x with fᵢ∈x∷xs i... | here fᵢ≡x = contradiction fᵢ≡x fᵢ≢x... | there fᵢ∈xs = fᵢ∈xshelper : ¬ Dec (∃ λ i → f i ≡ x)helper (no fᵢ≢x) = finite inj xs (λ i → not-x (fᵢ≢x ∘ _,_ i))helper (yes (i , fᵢ≡x)) = finite f′-inj xs f′ⱼ∈xswheref′ : ℕ → _f′ j with i ≤? j... | yes _ = f (suc j)... | no _ = f j∈-if-not-i : ∀ {j} → i ≢ j → f j ∈ xs∈-if-not-i i≢j = not-x (i≢j ∘ f-inj ∘ trans fᵢ≡x ∘ sym)lemma : ∀ {k j} → i ≤ j → i ≰ k → suc j ≢ klemma i≤j i≰1+j refl = i≰1+j (m≤n⇒m≤1+n i≤j)f′ⱼ∈xs : ∀ j → f′ j ∈ xsf′ⱼ∈xs j with i ≤? j... | yes i≤j = ∈-if-not-i (<⇒≢ (s≤s i≤j))... | no i≰j = ∈-if-not-i (<⇒≢ (≰⇒> i≰j) ∘ sym)f′-injective′ : Injective _≡_ _≡_ f′f′-injective′ {j} {k} eq with i ≤? j | i ≤? k... | yes i≤j | yes i≤k = suc-injective (f-inj eq)... | yes i≤j | no i≰k = contradiction (f-inj eq) (lemma i≤j i≰k)... | no i≰j | yes i≤k = contradiction (f-inj eq) (lemma i≤k i≰j ∘ sym)... | no i≰j | no i≰k = f-inj eqf′-inj : ℕ ↣ _f′-inj = record{ to = f′; cong = ≡.cong f′; injective = f′-injective′}-------------------------------------------------------------------------- Different membersthere-injective-≢∈ : ∀ {xs} {x y z : A} {x∈xs : x ∈ xs} {y∈xs : y ∈ xs} →there {x = z} x∈xs ≢∈ there y∈xs →x∈xs ≢∈ y∈xsthere-injective-≢∈ neq refl eq = neq refl (≡.cong there eq)
-------------------------------------------------------------------------- The Agda standard library---- Properties related to propositional list membership, that rely on-- the K rule------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Data.List.Membership.Propositional.Properties.WithK whereopen import Data.List.Baseopen import Data.List.Relation.Unary.Unique.Propositionalopen import Data.List.Membership.Propositionalimport Data.List.Membership.Setoid.Properties as Membershipopen import Relation.Unary using (Irrelevant)open import Relation.Binary.PropositionalEquality.Properties as ≡open import Relation.Binary.PropositionalEquality.WithK-------------------------------------------------------------------------- Irrelevanceunique⇒irrelevant : ∀ {a} {A : Set a} {xs : List A} →Unique xs → Irrelevant (_∈ xs)unique⇒irrelevant = Membership.unique⇒irrelevant (≡.setoid _) ≡-irrelevant
-------------------------------------------------------------------------- The Agda standard library---- Core properties related to propositional list membership.-------------------------------------------------------------------------- This file is needed to break the cyclic dependency with the proof-- `Any-cong` in `Data.List.Relation.Unary.Any.Properties` which relies-- on `Any↔` defined in this file.{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Membership.Propositional.Properties.Core whereopen import Data.List.Base using (List)open import Data.List.Membership.Propositionalopen import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.Product.Base as Product using (_,_; ∃; _×_)open import Function.Base using (flip; id; _∘_)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; resp)open import Relation.Unary using (Pred; _⊆_)privatevariablea p q : LevelA : Set ax : Axs : List A-------------------------------------------------------------------------- find satisfies a simple equality when the predicate is a-- propositional equality.find-∈ : (x∈xs : x ∈ xs) → find x∈xs ≡ (x , x∈xs , refl)find-∈ (here refl) = reflfind-∈ (there x∈xs) rewrite find-∈ x∈xs = refl-------------------------------------------------------------------------- Lemmas relating map and find.module _ {P : Pred A p} wheremap∘find : (p : Any P xs) → let x , x∈xs , px = find p in{f : (x ≡_) ⊆ P} → f refl ≡ px →Any.map f x∈xs ≡ pmap∘find (here p) hyp = cong here hypmap∘find (there p) hyp = cong there (map∘find p hyp)find∘map : ∀ {Q : Pred A q} {xs} (p : Any P xs) (f : P ⊆ Q) →let x , x∈xs , px = find p infind (Any.map f p) ≡ (x , x∈xs , f px)find∘map (here p) f = reflfind∘map (there p) f rewrite find∘map p f = refl-------------------------------------------------------------------------- Any can be expressed using _∈_module _ {P : Pred A p} where∃∈-Any : (∃ λ x → x ∈ xs × P x) → Any P xs∃∈-Any (x , x∈xs , px) = lose {P = P} x∈xs px∃∈-Any∘find : (p : Any P xs) → ∃∈-Any (find p) ≡ p∃∈-Any∘find p = map∘find p reflfind∘∃∈-Any : (p : ∃ λ x → x ∈ xs × P x) → find (∃∈-Any p) ≡ pfind∘∃∈-Any p@(x , x∈xs , px)rewrite find∘map x∈xs (flip (resp P) px) | find-∈ x∈xs = reflAny↔ : (∃ λ x → x ∈ xs × P x) ↔ Any P xsAny↔ = mk↔ₛ′ ∃∈-Any find ∃∈-Any∘find find∘∃∈-Any-------------------------------------------------------------------------- Hence, find and lose are inverses (more or less).lose∘find : ∀ {P : Pred A p} {xs} (p : Any P xs) → ∃∈-Any (find p) ≡ plose∘find = ∃∈-Any∘findfind∘lose : ∀ (P : Pred A p) {x xs}(x∈xs : x ∈ xs) (px : P x) →find (lose {P = P} x∈xs px) ≡ (x , x∈xs , px)find∘lose P {x} x∈xs px = find∘∃∈-Any (x , x∈xs , px)
-------------------------------------------------------------------------- The Agda standard library---- Decidable setoid membership over lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (DecSetoid)module Data.List.Membership.DecSetoid {a ℓ} (DS : DecSetoid a ℓ) whereopen import Data.List.Relation.Unary.Any using (any?)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary.Decidable using (¬?)open DecSetoid DS-------------------------------------------------------------------------- Re-export contents of propositional membershipopen import Data.List.Membership.Setoid (DecSetoid.setoid DS) public-------------------------------------------------------------------------- Other operationsinfix 4 _∈?_ _∉?__∈?_ : Decidable _∈_x ∈? xs = any? (x ≟_) xs_∉?_ : Decidable _∉_x ∉? xs = ¬? (x ∈? xs)
-------------------------------------------------------------------------- The Agda standard library---- Decidable propositional membership over lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (DecidableEquality)module Data.List.Membership.DecPropositional{a} {A : Set a} (_≟_ : DecidableEquality A) whereopen import Relation.Binary.PropositionalEquality.Properties using (decSetoid)open import Relation.Binary.PropositionalEquality.Properties using (decSetoid)-------------------------------------------------------------------------- Re-export contents of propositional membershipopen import Data.List.Membership.Propositional {A = A} publicopen import Data.List.Membership.DecSetoid (decSetoid _≟_) publicusing (_∈?_; _∉?_)
-------------------------------------------------------------------------- The Agda standard library---- List Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Literals whereopen import Agda.Builtin.FromString using (IsString)open import Data.Unit.Base using (⊤)open import Agda.Builtin.Char using (Char)open import Agda.Builtin.List using (List)open import Data.String.Base using (toList)isString : IsString (List Char)isString = record{ Constraint = λ _ → ⊤; fromString = λ s → toList s}
-------------------------------------------------------------------------- The Agda standard library---- An alternative definition of mutually-defined lists and non-empty-- lists, using the Kleene star and plus.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Kleene where-------------------------------------------------------------------------- Types and basic operationsopen import Data.List.Kleene.Base public
-------------------------------------------------------------------------- The Agda standard library---- Lists, based on the Kleene star and plus, basic types and operations.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Kleene.Base whereopen import Data.Product.Base as Productusing (_×_; _,_; map₂; map₁; proj₁; proj₂)open import Data.Nat.Base as ℕ using (ℕ; suc; zero)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe′)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Level using (Level)open import Algebra.Core using (Op₂)open import Function.Baseprivatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Definitions---- These lists are exactly equivalent to normal lists, except the "cons"-- case is split into its own data type. This lets us write all the same-- functions as before, but it has 2 advantages:---- * Some functions are easier to express on the non-empty type. Head,-- for instance, has a natural safe implementation. Having the-- non-empty type be defined mutually with the normal type makes the-- use of this non-empty type occasionally more ergonomic.-- * It can make some proofs easier. By using the non-empty type where-- possible, we can avoid an extra pattern match, which can really-- simplify certain proofs.infixr 5 _&_ ∹_infixl 4 _+ _*record _+ {a} (A : Set a) : Set adata _* {a} (A : Set a) : Set a-- Non-Empty Listsrecord _+ A whereinductiveconstructor _&_fieldhead : Atail : A *-- Possibly Empty Listsdata _* A where[] : A *∹_ : A + → A *open _+ public-------------------------------------------------------------------------- Unconsuncons : A * → Maybe (A +)uncons [] = nothinguncons (∹ xs) = just xs-------------------------------------------------------------------------- FoldMapfoldMap+ : Op₂ B → (A → B) → A + → BfoldMap+ _∙_ f (x & []) = f xfoldMap+ _∙_ f (x & ∹ xs) = f x ∙ foldMap+ _∙_ f xsfoldMap* : Op₂ B → B → (A → B) → A * → BfoldMap* _∙_ ε f [] = εfoldMap* _∙_ ε f (∹ xs) = foldMap+ _∙_ f xs-------------------------------------------------------------------------- Foldsmodule _ (f : A → B → B) (b : B) wherefoldr+ : A + → Bfoldr* : A * → Bfoldr+ (x & xs) = f x (foldr* xs)foldr* [] = bfoldr* (∹ xs) = foldr+ xsmodule _ (f : B → A → B) wherefoldl+ : B → A + → Bfoldl* : B → A * → Bfoldl+ b (x & xs) = foldl* (f b x) xsfoldl* b [] = bfoldl* b (∹ xs) = foldl+ b xs-------------------------------------------------------------------------- Concatenationmodule Concat whereinfixr 4 _++++_ _+++*_ _*+++_ _*++*__++++_ : A + → A + → A +_+++*_ : A + → A * → A +_*+++_ : A * → A + → A +_*++*_ : A * → A * → A *head (xs +++* ys) = head xstail (xs +++* ys) = tail xs *++* ysxs *++* ys = foldr* (λ x zs → ∹ x & zs) ys xsxs ++++ ys = foldr+ (λ x zs → x & ∹ zs) ys xs[] *+++ ys = ys(∹ xs) *+++ ys = xs ++++ ysopen Concat public using () renaming (_++++_ to _+++_; _*++*_ to _++*_)-------------------------------------------------------------------------- Mappingmodule _ (f : A → B) wheremap+ : A + → B +map* : A * → B *head (map+ xs) = f (head xs)tail (map+ xs) = map* (tail xs)map* [] = []map* (∹ xs) = ∹ map+ xsmodule _ (f : A → Maybe B) wheremapMaybe+ : A + → B *mapMaybe* : A * → B *mapMaybe+ (x & xs) = maybe′ (λ y z → ∹ y & z) id (f x) $ mapMaybe* xsmapMaybe* [] = []mapMaybe* (∹ xs) = mapMaybe+ xs-------------------------------------------------------------------------- Applicative Operationspure+ : A → A +head (pure+ x) = xtail (pure+ x) = []pure* : A → A *pure* x = ∹ pure+ xmodule Apply where_*<*>*_ : (A → B) * → A * → B *_+<*>*_ : (A → B) + → A * → B *_*<*>+_ : (A → B) * → A + → B *_+<*>+_ : (A → B) + → A + → B +[] *<*>* xs = [](∹ fs) *<*>* xs = fs +<*>* xsfs +<*>* xs = map* (head fs) xs ++* (tail fs *<*>* xs)[] *<*>+ xs = [](∹ fs) *<*>+ xs = ∹ fs +<*>+ xsfs +<*>+ xs = map+ (head fs) xs Concat.+++* (tail fs *<*>+ xs)open Apply public using () renaming (_*<*>*_ to _<*>*_; _+<*>+_ to _<*>+_)-------------------------------------------------------------------------- Monadic Operationsmodule Bind where_+>>=+_ : A + → (A → B +) → B +_+>>=*_ : A + → (A → B *) → B *_*>>=+_ : A * → (A → B +) → B *_*>>=*_ : A * → (A → B *) → B *(x & xs) +>>=+ k = k x Concat.+++* (xs *>>=+ k)(x & xs) +>>=* k = k x Concat.*++* (xs *>>=* k)[] *>>=* k = [](∹ xs) *>>=* k = xs +>>=* k[] *>>=+ k = [](∹ xs) *>>=+ k = ∹ xs +>>=+ kopen Bind public using () renaming (_*>>=*_ to _>>=*_; _+>>=+_ to _>>=+_)-------------------------------------------------------------------------- Scansmodule Scanr (f : A → B → B) (b : B) wherecons : A → B + → B +head (cons x xs) = f x (head xs)tail (cons x xs) = ∹ xsscanr+ : A + → B +scanr* : A * → B +scanr* = foldr* cons (b & [])scanr+ = foldr+ cons (b & [])open Scanr public using (scanr+; scanr*)module _ (f : B → A → B) wherescanl* : B → A * → B +head (scanl* b xs) = btail (scanl* b []) = []tail (scanl* b (∹ xs)) = ∹ scanl* (f b (head xs)) (tail xs)scanl+ : B → A + → B +head (scanl+ b xs) = btail (scanl+ b xs) = ∹ scanl* (f b (head xs)) (tail xs)scanl₁ : B → A + → B +scanl₁ b xs = scanl* (f b (head xs)) (tail xs)-------------------------------------------------------------------------- Accumulating mapsmodule _ (f : B → A → (B × C)) wheremapAccumˡ* : B → A * → (B × C *)mapAccumˡ+ : B → A + → (B × C +)mapAccumˡ* b [] = b , []mapAccumˡ* b (∹ xs) = map₂ ∹_ (mapAccumˡ+ b xs)mapAccumˡ+ b (x & xs) =let y , ys = f b xz , zs = mapAccumˡ* y xsin z , ys & zsmodule _ (f : A → B → (C × B)) (b : B) wheremapAccumʳ* : A * → (C * × B)mapAccumʳ+ : A + → (C + × B)mapAccumʳ* [] = [] , bmapAccumʳ* (∹ xs) = map₁ ∹_ (mapAccumʳ+ xs)mapAccumʳ+ (x & xs) =let ys , y = mapAccumʳ* xszs , z = f x yin zs & ys , z-------------------------------------------------------------------------- Non-Empty Foldslast : A + → Alast (x & []) = xlast (_ & ∹ xs) = last xsmodule _ (f : A → A → A) wherefoldr₁ : A + → Afoldr₁ (x & []) = xfoldr₁ (x & ∹ xs) = f x (foldr₁ xs)foldl₁ : A + → Afoldl₁ (x & xs) = foldl* f x xsmodule _ (f : A → Maybe B → B) wherefoldrMaybe* : A * → Maybe BfoldrMaybe+ : A + → BfoldrMaybe* [] = nothingfoldrMaybe* (∹ xs) = just (foldrMaybe+ xs)foldrMaybe+ (x & xs) = f x (foldrMaybe* xs)-------------------------------------------------------------------------- Indexinginfix 4 _[_]* _[_]+_[_]* : A * → ℕ → Maybe A_[_]+ : A + → ℕ → Maybe A[] [ _ ]* = nothing(∹ xs) [ i ]* = xs [ i ]+xs [ zero ]+ = just (head xs)xs [ suc i ]+ = tail xs [ i ]*applyUpTo* : (ℕ → A) → ℕ → A *applyUpTo+ : (ℕ → A) → ℕ → A +applyUpTo* f zero = []applyUpTo* f (suc n) = ∹ applyUpTo+ f nhead (applyUpTo+ f n) = f zerotail (applyUpTo+ f n) = applyUpTo* (f ∘ suc) nupTo* : ℕ → ℕ *upTo* = applyUpTo* idupTo+ : ℕ → ℕ +upTo+ = applyUpTo+ id-------------------------------------------------------------------------- Manipulationmodule ZipWith (f : A → B → C) where+zipWith+ : A + → B + → C +*zipWith+ : A * → B + → C *+zipWith* : A + → B * → C **zipWith* : A * → B * → C *head (+zipWith+ xs ys) = f (head xs) (head ys)tail (+zipWith+ xs ys) = *zipWith* (tail xs) (tail ys)*zipWith+ [] ys = []*zipWith+ (∹ xs) ys = ∹ +zipWith+ xs ys+zipWith* xs [] = []+zipWith* xs (∹ ys) = ∹ +zipWith+ xs ys*zipWith* [] ys = []*zipWith* (∹ xs) ys = +zipWith* xs ysopen ZipWith public renaming (+zipWith+ to zipWith+; *zipWith* to zipWith*)module Unzip (f : A → B × C) wherecons : B × C → B * × C * → B + × C +cons = Product.zip′ _&_ _&_unzipWith* : A * → B * × C *unzipWith+ : A + → B + × C +unzipWith* = foldr* (λ x xs → Product.map ∹_ ∹_ (cons (f x) xs)) ([] , [])unzipWith+ xs = cons (f (head xs)) (unzipWith* (tail xs))open Unzip using (unzipWith+; unzipWith*) publicmodule Partition (f : A → B ⊎ C) wherecons : B ⊎ C → B * × C * → B * × C *proj₁ (cons (inj₁ x) xs) = ∹ x & proj₁ xsproj₂ (cons (inj₁ x) xs) = proj₂ xsproj₂ (cons (inj₂ x) xs) = ∹ x & proj₂ xsproj₁ (cons (inj₂ x) xs) = proj₁ xspartitionSumsWith* : A * → B * × C *partitionSumsWith+ : A + → B * × C *partitionSumsWith* = foldr* (cons ∘ f) ([] , [])partitionSumsWith+ = foldr+ (cons ∘ f) ([] , [])open Partition using (partitionSumsWith+; partitionSumsWith*) publictails* : A * → (A +) *tails+ : A + → (A +) +head (tails+ xs) = xstail (tails+ xs) = tails* (tail xs)tails* [] = []tails* (∹ xs) = ∹ tails+ xsreverse* : A * → A *reverse* = foldl* (λ xs x → ∹ x & xs) []reverse+ : A + → A +reverse+ (x & xs) = foldl* (λ ys y → y & ∹ ys) (x & []) xs
-------------------------------------------------------------------------- The Agda standard library---- A different interface to the Kleene lists, designed to mimic-- Data.List.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Kleene.AsList whereopen import Level as Level using (Level)privatevariablea b c : LevelA : Set aB : Set bC : Set cimport Data.List.Kleene.Base as Kleene-------------------------------------------------------------------------- Here we import half of the functions from Data.KleeneList: the half-- for possibly-empty lists.open import Data.List.Kleene.Base publicusing ([])renaming( _* to List; foldr* to foldr; foldl* to foldl; _++*_ to _++_; map* to map; mapMaybe* to mapMaybe; pure* to pure; _<*>*_ to _<*>_; _>>=*_ to _>>=_; mapAccumˡ* to mapAccumˡ; mapAccumʳ* to mapAccumʳ; _[_]* to _[_]; applyUpTo* to applyUpTo; upTo* to upTo; zipWith* to zipWith; unzipWith* to unzipWith; partitionSumsWith* to partitionSumsWith; reverse* to reverse)-------------------------------------------------------------------------- A pattern which mimics Data.List._∷_infixr 5 _∷_pattern _∷_ x xs = Kleene.∹ x Kleene.& xs-------------------------------------------------------------------------- The following functions change the type of the list (from ⁺ to * or-- vice versa) in Data.KleeneList, so we reimplement them here to keep-- the type the same.scanr : (A → B → B) → B → List A → List Bscanr f b xs = Kleene.∹ Kleene.scanr* f b xsscanl : (B → A → B) → B → List A → List Bscanl f b xs = Kleene.∹ Kleene.scanl* f b xstails : List A → List (List A)tails xs = foldr (λ x xs → (Kleene.∹ x) ∷ xs) ([] ∷ []) (Kleene.tails* xs)
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for List------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Instances whereopen import Data.List.Baseopen import Data.List.Effectfulimport Data.List.Effectful.Transformer as Transopen import Data.List.Propertiesusing (≡-dec)open import Data.List.Relation.Binary.Pointwiseusing (Pointwise)open import Data.List.Relation.Binary.Lex.NonStrictusing (Lex-≤; ≤-isDecTotalOrder)open import Levelopen import Relation.Binary.Coreopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)open import Relation.Binary.TypeClassesprivatevariablea ℓ₁ ℓ₂ : LevelA : Set ainstance-- ListlistFunctor = functorlistApplicative = applicativelistApplicativeZero = applicativeZerolistAlternative = alternativelistMonad = monadlistMonadZero = monadZerolistMonadPlus = monadPlus-- ListTlistTFunctor = λ {f} {g} {M} {{inst}} → Trans.functor {f} {g} {M} instlistTApplicative = λ {f} {g} {M} {{inst}} → Trans.applicative {f} {g} {M} instlistTMonad = λ {f} {g} {M} {{inst}} → Trans.monad {f} {g} {M} instlistTMonadT = λ {f} {g} {M} {{inst}} → Trans.monadT {f} {g} {M} instList-≡-isDecEquivalence : {{IsDecEquivalence {A = A} _≡_}} → IsDecEquivalence {A = List A} _≡_List-≡-isDecEquivalence = isDecEquivalence (≡-dec _≟_)List-Lex-≤-isDecTotalOrder : {_≈_ : Rel A ℓ₁} {_≼_ : Rel A ℓ₂}→ {{IsDecTotalOrder _≈_ _≼_}}→ IsDecTotalOrder (Pointwise _≈_) (Lex-≤ _≈_ _≼_)List-Lex-≤-isDecTotalOrder {{≼-isDecTotalOrder}} = ≤-isDecTotalOrder ≼-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Fresh lists, a proof relevant variant of Catarina Coquand's contexts-- in "A Formalised Proof of the Soundness and Completeness of a Simply-- Typed Lambda-Calculus with Explicit Substitutions"-------------------------------------------------------------------------- See README.Data.List.Fresh and README.Data.Trie.NonDependent for-- examples of how to use fresh lists.{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh whereopen import Level using (Level; _⊔_)open import Data.Bool.Base using (true; false; if_then_else_)open import Data.Unit.Polymorphic.Base using (⊤)open import Data.Product.Base using (∃; _×_; _,_; -,_; proj₁; proj₂)open import Data.List.Relation.Unary.All using (All; []; _∷_)open import Data.List.Relation.Unary.AllPairs using (AllPairs; []; _∷_)open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)open import Data.Nat.Base using (ℕ; zero; suc)open import Function.Base using (_∘′_; flip; id; _on_)open import Relation.Nullary using (does)open import Relation.Unary as U using (Pred)open import Relation.Binary.Core using (Rel)import Relation.Binary.Definitions as Bopen import Relation.Naryprivatevariablea b p r s : LevelA : Set aB : Set b-------------------------------------------------------------------------- Basic type-- If we pick an R such that (R a b) means that a is different from b-- then we have a list of distinct values.module _ {a} (A : Set a) (R : Rel A r) wheredata List# : Set (a ⊔ r)fresh : (a : A) (as : List#) → Set rdata List# where[] : List#cons : (a : A) (as : List#) → fresh a as → List#-- Whenever R can be reconstructed by η-expansion (e.g. because it is-- the erasure ⌊_⌋ of a decidable predicate, cf. Relation.Nary) or we-- do not care about the proof, it is convenient to get back list syntax.-- We use a different symbol to avoid conflict when importing both-- Data.List and Data.List.Fresh.infixr 5 _∷#_pattern _∷#_ x xs = cons x xs _fresh a [] = ⊤fresh a (x ∷# xs) = R a x × fresh a xs-- Convenient notation for freshness making A and R implicit parametersinfix 5 _#__#_ : {R : Rel A r} (a : A) (as : List# A R) → Set r_#_ = fresh _ _-------------------------------------------------------------------------- Operations for modifying fresh listsmodule _ {R : Rel A r} {S : Rel B s} (f : A → B) (R⇒S : ∀[ R ⇒ (S on f) ]) wheremap : List# A R → List# B Smap-# : ∀ {a} as → a # as → f a # map asmap [] = []map (cons a as ps) = cons (f a) (map as) (map-# as ps)map-# [] _ = _map-# (a ∷# as) (p , ps) = R⇒S p , map-# as psmodule _ {R : Rel B r} (f : A → B) wheremap₁ : List# A (R on f) → List# B Rmap₁ = map f idmodule _ {R : Rel A r} {S : Rel A s} (R⇒S : ∀[ R ⇒ S ]) wheremap₂ : List# A R → List# A Smap₂ = map id R⇒S-------------------------------------------------------------------------- Viewsdata Empty {A : Set a} {R : Rel A r} : List# A R → Set (a ⊔ r) where[] : Empty []data NonEmpty {A : Set a} {R : Rel A r} : List# A R → Set (a ⊔ r) wherecons : ∀ x xs pr → NonEmpty (cons x xs pr)-------------------------------------------------------------------------- Operations for reducing fresh listslength : {R : Rel A r} → List# A R → ℕlength [] = 0length (_ ∷# xs) = suc (length xs)-------------------------------------------------------------------------- Operations for constructing fresh listspattern [_] a = a ∷# []fromMaybe : {R : Rel A r} → Maybe A → List# A RfromMaybe nothing = []fromMaybe (just a) = [ a ]module _ {R : Rel A r} (R-refl : B.Reflexive R) wherereplicate : ℕ → A → List# A Rreplicate-# : (n : ℕ) (a : A) → a # replicate n areplicate zero a = []replicate (suc n) a = cons a (replicate n a) (replicate-# n a)replicate-# zero a = _replicate-# (suc n) a = R-refl , replicate-# n a-------------------------------------------------------------------------- Operations for deconstructing fresh listsuncons : {R : Rel A r} → List# A R → Maybe (A × List# A R)uncons [] = nothinguncons (a ∷# as) = just (a , as)head : {R : Rel A r} → List# A R → Maybe Ahead = Maybe.map proj₁ ∘′ unconstail : {R : Rel A r} → List# A R → Maybe (List# A R)tail = Maybe.map proj₂ ∘′ unconstake : {R : Rel A r} → ℕ → List# A R → List# A Rtake-# : {R : Rel A r} → ∀ n a (as : List# A R) → a # as → a # take n astake zero xs = []take (suc n) [] = []take (suc n) (cons a as ps) = cons a (take n as) (take-# n a as ps)take-# zero a xs _ = _take-# (suc n) a [] ps = _take-# (suc n) a (x ∷# xs) (p , ps) = p , take-# n a xs psdrop : {R : Rel A r} → ℕ → List# A R → List# A Rdrop zero as = asdrop (suc n) [] = []drop (suc n) (a ∷# as) = drop n asmodule _ {P : Pred A p} (P? : U.Decidable P) wheretakeWhile : {R : Rel A r} → List# A R → List# A RtakeWhile-# : ∀ {R : Rel A r} a (as : List# A R) → a # as → a # takeWhile astakeWhile [] = []takeWhile (cons a as ps) =if does (P? a) then cons a (takeWhile as) (takeWhile-# a as ps) else []-- this 'with' is needed to cause reduction in the type of 'takeWhile (a ∷# as)'takeWhile-# a [] _ = _takeWhile-# a (x ∷# xs) (p , ps) with does (P? x)... | true = p , takeWhile-# a xs ps... | false = _dropWhile : {R : Rel A r} → List# A R → List# A RdropWhile [] = []dropWhile aas@(a ∷# as) = if does (P? a) then dropWhile as else aasfilter : {R : Rel A r} → List# A R → List# A Rfilter-# : ∀ {R : Rel A r} a (as : List# A R) → a # as → a # filter asfilter [] = []filter (cons a as ps) =let l = filter as inif does (P? a) then cons a l (filter-# a as ps) else l-- this 'with' is needed to cause reduction in the type of 'filter-# a (x ∷# xs)'filter-# a [] _ = _filter-# a (x ∷# xs) (p , ps) with does (P? x)... | true = p , filter-# a xs ps... | false = filter-# a xs ps-------------------------------------------------------------------------- Relationship to List and AllPairstoList : {R : Rel A r} → List# A R → ∃ (AllPairs R)toAll : ∀ {R : Rel A r} {a} as → fresh A R a as → All (R a) (proj₁ (toList as))toList [] = -, []toList (cons x xs ps) = -, toAll xs ps ∷ proj₂ (toList xs)toAll [] ps = []toAll (a ∷# as) (p , ps) = p ∷ toAll as psfromList : ∀ {R : Rel A r} {xs} → AllPairs R xs → List# A RfromList-# : ∀ {R : Rel A r} {x xs} (ps : AllPairs R xs) →All (R x) xs → x # fromList psfromList [] = []fromList (r ∷ rs) = cons _ (fromList rs) (fromList-# rs r)fromList-# [] _ = _fromList-# (p ∷ ps) (r ∷ rs) = r , fromList-# ps rs
-------------------------------------------------------------------------- The Agda standard library---- Any predicate transformer for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.Relation.Unary.Any whereopen import Level using (Level; _⊔_; Lift)open import Data.Product.Base using (∃; _,_; -,_)open import Data.Sum.Base using (_⊎_; [_,_]′; inj₁; inj₂)open import Function.Bundles using (_⇔_; mk⇔)open import Relation.Nullary.Negation using (¬_; contradiction)open import Relation.Nullary.Decidable as Dec using (Dec; no; _⊎-dec_)open import Relation.Unary as Uopen import Relation.Binary.Core using (Rel)open import Data.List.Fresh using (List#; []; cons; _∷#_; _#_)privatevariablea p q r : LevelA : Set amodule _ {A : Set a} {R : Rel A r} (P : Pred A p) wheredata Any : List# A R → Set (p ⊔ a ⊔ r) wherehere : ∀ {x xs pr} → P x → Any (cons x xs pr)there : ∀ {x xs pr} → Any xs → Any (cons x xs pr)module _ {R : Rel A r} {P : Pred A p} {x} {xs : List# A R} {pr} wherehead : ¬ Any P xs → Any P (cons x xs pr) → P xhead ¬tail (here p) = phead ¬tail (there ps) = contradiction ps ¬tailtail : ¬ P x → Any P (cons x xs pr) → Any P xstail ¬head (here p) = contradiction p ¬headtail ¬head (there ps) = pstoSum : Any P (cons x xs pr) → P x ⊎ Any P xstoSum (here p) = inj₁ ptoSum (there ps) = inj₂ psfromSum : P x ⊎ Any P xs → Any P (cons x xs pr)fromSum = [ here , there ]′⊎⇔Any : (P x ⊎ Any P xs) ⇔ Any P (cons x xs pr)⊎⇔Any = mk⇔ fromSum toSummodule _ {R : Rel A r} {P : Pred A p} {Q : Pred A q} wheremap : {xs : List# A R} → ∀[ P ⇒ Q ] → Any P xs → Any Q xsmap p⇒q (here p) = here (p⇒q p)map p⇒q (there p) = there (map p⇒q p)module _ {R : Rel A r} {P : Pred A p} wherewitness : {xs : List# A R} → Any P xs → ∃ Pwitness (here p) = -, pwitness (there ps) = witness psremove : (xs : List# A R) → Any P xs → List# A Rremove-# : ∀ {x} {xs : List# A R} p → x # xs → x # (remove xs p)remove (_ ∷# xs) (here _) = xsremove (cons x xs pr) (there k) = cons x (remove xs k) (remove-# k pr)remove-# (here x) (p , ps) = psremove-# (there k) (p , ps) = p , remove-# k psinfixl 4 _─__─_ = removemodule _ {R : Rel A r} {P : Pred A p} (P? : Decidable P) whereany? : (xs : List# A R) → Dec (Any P xs)any? [] = no (λ ())any? (x ∷# xs) = Dec.map ⊎⇔Any (P? x ⊎-dec any? xs)
-------------------------------------------------------------------------- The Agda standard library---- Properties of Any predicate transformer for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.Relation.Unary.Any.Properties whereopen import Level using (Level; _⊔_; Lift)open import Data.Bool.Base using (true; false)open import Data.Emptyopen import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (_,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Function.Base using (_∘′_)open import Relation.Nullary.Reflects using (invert)open import Relation.Nullaryopen import Relation.Unary as U using (Pred)open import Relation.Binary.Core using (Rel)open import Relation.Naryopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Data.List.Freshopen import Data.List.Fresh.Relation.Unary.Allopen import Data.List.Fresh.Relation.Unary.Anyprivatevariablea b p q r s : LevelA : Set aB : Set b-------------------------------------------------------------------------- NonEmptymodule _ {R : Rel A r} {P : Pred A p} whereAny⇒NonEmpty : {xs : List# A R} → Any P xs → NonEmpty xsAny⇒NonEmpty {xs = cons x xs pr} p = cons x xs pr-------------------------------------------------------------------------- Correspondence between Any and Allmodule _ {R : Rel A r} {P : Pred A p} {Q : Pred A q} (P⇒¬Q : ∀[ P ⇒ ∁ Q ]) whereAny⇒¬All : {xs : List# A R} → Any P xs → ¬ (All Q xs)Any⇒¬All (here p) (q ∷ _) = P⇒¬Q p qAny⇒¬All (there ps) (_ ∷ qs) = Any⇒¬All ps qsAll⇒¬Any : {xs : List# A R} → All P xs → ¬ (Any Q xs)All⇒¬Any (p ∷ _) (here q) = P⇒¬Q p qAll⇒¬Any (_ ∷ ps) (there qs) = All⇒¬Any ps qsmodule _ {R : Rel A r} {P : Pred A p} {Q : Pred A q} (P? : Decidable P) where¬All⇒Any : {xs : List# A R} → ¬ (All P xs) → Any (∁ P) xs¬All⇒Any {xs = []} ¬ps = ⊥-elim (¬ps [])¬All⇒Any {xs = x ∷# xs} ¬ps with P? x... | true because [p] = there (¬All⇒Any (¬ps ∘′ (invert [p] ∷_)))... | false because [¬p] = here (invert [¬p])¬Any⇒All : {xs : List# A R} → ¬ (Any P xs) → All (∁ P) xs¬Any⇒All {xs = []} ¬ps = []¬Any⇒All {xs = x ∷# xs} ¬ps with P? x... | true because [p] = ⊥-elim (¬ps (here (invert [p])))... | false because [¬p] = invert [¬p] ∷ ¬Any⇒All (¬ps ∘′ there)-------------------------------------------------------------------------- removemodule _ {R : Rel A r} {P : Pred A p} wherelength-remove : {xs : List# A R} (k : Any P xs) →length xs ≡ suc (length (xs ─ k))length-remove (here _) = refllength-remove (there p) = cong suc (length-remove p)-------------------------------------------------------------------------- appendmodule _ {R : Rel A r} {P : Pred A p} whereappend⁺ˡ : {xs ys : List# A R} {ps : All (_# ys) xs} →Any P xs → Any P (append xs ys ps)append⁺ˡ (here px) = here pxappend⁺ˡ (there p) = there (append⁺ˡ p)append⁺ʳ : {xs ys : List# A R} {ps : All (_# ys) xs} →Any P ys → Any P (append xs ys ps)append⁺ʳ {xs = []} p = pappend⁺ʳ {xs = x ∷# xs} p = there (append⁺ʳ p)append⁻ : ∀ xs {ys : List# A R} {ps : All (_# ys) xs} →Any P (append xs ys ps) → Any P xs ⊎ Any P ysappend⁻ [] p = inj₂ pappend⁻ (x ∷# xs) (here px) = inj₁ (here px)append⁻ (x ∷# xs) (there p) = Sum.map₁ there (append⁻ xs p)
-------------------------------------------------------------------------- The Agda standard library---- All predicate transformer for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.Relation.Unary.All whereopen import Level using (Level; _⊔_; Lift)open import Data.Product.Base using (_×_; _,_; proj₁; uncurry)open import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_]′)open import Function.Base using (_∘_; _$_)open import Relation.Nullary.Decidable as Dec using (Dec; yes; no; _×-dec_)open import Relation.Unary as Uopen import Relation.Binary.Core using (Rel)open import Data.List.Fresh using (List#; []; cons; _∷#_; _#_)open import Data.List.Fresh.Relation.Unary.Any as Any using (Any; here; there)privatevariablea p q r : LevelA : Set amodule _ {A : Set a} {R : Rel A r} (P : Pred A p) whereinfixr 5 _∷_data All : List# A R → Set (p ⊔ a ⊔ r) where[] : All []_∷_ : ∀ {x xs pr} → P x → All xs → All (cons x xs pr)module _ {R : Rel A r} {P : Pred A p} whereuncons : ∀ {x} {xs : List# A R} {pr} →All P (cons x xs pr) → P x × All P xsuncons (p ∷ ps) = p , psmodule _ {R : Rel A r} whereappend : (xs ys : List# A R) → All (_# ys) xs → List# A Rappend-# : ∀ {x} xs ys {ps} → x # xs → x # ys → x # append xs ys psappend [] ys _ = ysappend (cons x xs pr) ys ps =let (p , ps) = uncons ps incons x (append xs ys ps) (append-# xs ys pr p)append-# [] ys x#xs x#ys = x#ysappend-# (cons x xs pr) ys (r , x#xs) x#ys = r , append-# xs ys x#xs x#ysmodule _ {R : Rel A r} {P : Pred A p} {Q : Pred A q} wheremap : ∀ {xs : List# A R} → ∀[ P ⇒ Q ] → All P xs → All Q xsmap p⇒q [] = []map p⇒q (p ∷ ps) = p⇒q p ∷ map p⇒q pslookup : ∀ {xs : List# A R} → All Q xs → (ps : Any P xs) →Q (proj₁ (Any.witness ps))lookup (q ∷ _) (here _) = qlookup (_ ∷ qs) (there k) = lookup qs kmodule _ {R : Rel A r} {P : Pred A p} (P? : Decidable P) whereall? : (xs : List# A R) → Dec (All P xs)all? [] = yes []all? (x ∷# xs) = Dec.map′ (uncurry _∷_) uncons (P? x ×-dec all? xs)-------------------------------------------------------------------------- Generalised decidability proceduremodule _ {R : Rel A r} {P : Pred A p} {Q : Pred A q} wheredecide : Π[ P ∪ Q ] → Π[ All {R = R} P ∪ Any Q ]decide p∪q [] = inj₁ []decide p∪q (x ∷# xs) =[ (λ px → Sum.map (px ∷_) there (decide p∪q xs)), inj₂ ∘ here]′ $ p∪q x
-------------------------------------------------------------------------- The Agda standard library---- Properties of All predicate transformer for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.Relation.Unary.All.Properties whereopen import Level using (Level; _⊔_; Lift)open import Data.Emptyopen import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (_,_)open import Function.Base using (_∘′_)open import Relation.Nullaryopen import Relation.Unary as Uopen import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Data.List.Fresh using (List#; []; cons; _∷#_; _#_)open import Data.List.Fresh.Relation.Unary.Allprivatevariablea p r : LevelA : Set amodule _ {R : Rel A r} wherefromAll : ∀ {x} {xs : List# A R} → All (R x) xs → x # xsfromAll [] = _fromAll (p ∷ ps) = p , fromAll pstoAll : ∀ {x} {xs : List# A R} → x # xs → All (R x) xstoAll {xs = []} _ = []toAll {xs = a ∷# as} (p , ps) = p ∷ toAll psmodule _ {R : Rel A r} {P : Pred A p} whereappend⁺ : {xs ys : List# A R} {ps : All (_# ys) xs} →All P xs → All P ys → All P (append xs ys ps)append⁺ [] pys = pysappend⁺ (px ∷ pxs) pys = px ∷ append⁺ pxs pys
-------------------------------------------------------------------------- The Agda standard library---- Properties of fresh lists and functions acting on them------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.Properties whereopen import Level using (Level; _⊔_)open import Data.Product.Base using (_,_)open import Relation.Nullaryopen import Relation.Unary as U using (Pred)import Relation.Binary.Definitions as Bopen import Relation.Binary.Core using (Rel)open import Data.List.Freshprivatevariablea b e p r : LevelA : Set aB : Set b-------------------------------------------------------------------------- Fresh congruencemodule _ {R : Rel A r} {_≈_ : Rel A e} (R≈ : R B.Respectsˡ _≈_) wherefresh-respectsˡ : ∀ {x y} {xs : List# A R} → x ≈ y → x # xs → y # xsfresh-respectsˡ {xs = []} x≈y x#xs = _fresh-respectsˡ {xs = x ∷# xs} x≈y (r , x#xs) =R≈ x≈y r , fresh-respectsˡ x≈y x#xs-------------------------------------------------------------------------- Empty and NotEmptyEmpty⇒¬NonEmpty : {R : Rel A r} {xs : List# A R} → Empty xs → ¬ (NonEmpty xs)Empty⇒¬NonEmpty [] ()NonEmpty⇒¬Empty : {R : Rel A r} {xs : List# A R} → NonEmpty xs → ¬ (Empty xs)NonEmpty⇒¬Empty () []empty? : {R : Rel A r} (xs : List# A R) → Dec (Empty xs)empty? [] = yes []empty? (_ ∷# _) = no (λ ())nonEmpty? : {R : Rel A r} (xs : List# A R) → Dec (NonEmpty xs)nonEmpty? [] = no (λ ())nonEmpty? (cons x xs pr) = yes (cons x xs pr)
-------------------------------------------------------------------------- The Agda standard library---- A non-empty fresh list------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Fresh.NonEmpty whereopen import Level using (Level; _⊔_)open import Data.List.Fresh as List# using (List#; []; cons; fresh)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Nat.Base using (ℕ; suc)open import Data.Product.Base using (_×_; _,_)open import Relation.Binary.Core using (Rel)privatevariablea r : LevelA : Set aR : Rel A r-------------------------------------------------------------------------- Definitioninfixr 5 _∷#⁺_record List#⁺ (A : Set a) (R : Rel A r) : Set (a ⊔ r) whereconstructor _∷#⁺_fieldhead : Atail : List# A R{rel} : fresh A R head tailopen List#⁺-------------------------------------------------------------------------- Operationsuncons : List#⁺ A R → A × List# A Runcons (x ∷#⁺ xs) = x , xs[_] : A → List#⁺ A R[ x ] = x ∷#⁺ []length : List#⁺ A R → ℕlength (x ∷#⁺ xs) = suc (List#.length xs)-- ConversiontoList# : List#⁺ A R → List# A RtoList# l = cons (l .head) (l .tail) (l .rel)fromList# : List# A R → Maybe (List#⁺ A R)fromList# [] = nothingfromList# (cons a as ps) = just (record { head = a ; tail = as ; rel = ps })
-------------------------------------------------------------------------- The Agda standard library---- Membership predicate for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.List.Fresh.Membership.Setoid {c ℓ} (S : Setoid c ℓ) whereopen import Level using (Level; _⊔_)open import Data.List.Freshopen import Data.List.Fresh.Relation.Unary.Any as Any using (Any)open import Relation.Nullaryopen Setoid S renaming (Carrier to A)infix 4 _∈_ _∉_privatevariabler : Level_∈_ : {R : Rel A r} → A → List# A R → Set _x ∈ xs = Any (x ≈_) xs_∉_ : {R : Rel A r} → A → List# A R → Set _x ∉ xs = ¬ (x ∈ xs)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the membership predicate for fresh lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)module Data.List.Fresh.Membership.Setoid.Properties {c ℓ} (S : Setoid c ℓ) whereopen import Level using (Level; _⊔_)open import Data.Emptyopen import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Data.Product.Base using (∃; _×_; _,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; fromInj₂)open import Function.Base using (id; _∘′_; _$_)open import Relation.Nullaryopen import Relation.Unary as Unary using (Pred)import Relation.Binary.Definitions as Binaryimport Relation.Binary.PropositionalEquality.Core as ≡open import Relation.Naryopen import Data.List.Freshopen import Data.List.Fresh.Propertiesopen import Data.List.Fresh.Membership.Setoid Sopen import Data.List.Fresh.Relation.Unary.Any using (Any; here; there; _─_)import Data.List.Fresh.Relation.Unary.Any.Properties as List#open Setoid S renaming (Carrier to A)privatevariablep r : Level-------------------------------------------------------------------------- transportmodule _ {R : Rel A r} where≈-subst-∈ : ∀ {x y} {xs : List# A R} → x ≈ y → x ∈ xs → y ∈ xs≈-subst-∈ x≈y (here x≈x′) = here (trans (sym x≈y) x≈x′)≈-subst-∈ x≈y (there x∈xs) = there (≈-subst-∈ x≈y x∈xs)-------------------------------------------------------------------------- relationship to freshmodule _ {R : Rel A r} (R⇒≉ : ∀[ R ⇒ _≉_ ]) wherefresh⇒∉ : ∀ {x} {xs : List# A R} → x # xs → x ∉ xsfresh⇒∉ (r , _) (here x≈y) = R⇒≉ r x≈yfresh⇒∉ (_ , x#xs) (there x∈xs) = fresh⇒∉ x#xs x∈xs-------------------------------------------------------------------------- disjointnessmodule _ {R : Rel A r} wheredistinct : ∀ {x y} {xs : List# A R} → x ∈ xs → y ∉ xs → x ≉ ydistinct x∈xs y∉xs x≈y = y∉xs (≈-subst-∈ x≈y x∈xs)-------------------------------------------------------------------------- removemodule _ {R : Rel A r} whereremove-inv : ∀ {x y} {xs : List# A R} (x∈xs : x ∈ xs) →y ∈ xs → x ≈ y ⊎ y ∈ (xs ─ x∈xs)remove-inv (here x≈z) (here y≈z) = inj₁ (trans x≈z (sym y≈z))remove-inv (here _) (there y∈xs) = inj₂ y∈xsremove-inv (there _) (here y≈z) = inj₂ (here y≈z)remove-inv (there x∈xs) (there y∈xs) = Sum.map₂ there (remove-inv x∈xs y∈xs)∈-remove : ∀ {x y} {xs : List# A R} (x∈xs : x ∈ xs) → y ∈ xs → x ≉ y → y ∈ (xs ─ x∈xs)∈-remove x∈xs y∈xs x≉y = fromInj₂ (⊥-elim ∘′ x≉y) (remove-inv x∈xs y∈xs)module _ {R : Rel A r} (R⇒≉ : ∀[ R ⇒ _≉_ ]) (≉⇒R : ∀[ _≉_ ⇒ R ]) whereprivateR≈ : R Binary.Respectsˡ _≈_R≈ x≈y Rxz = ≉⇒R (R⇒≉ Rxz ∘′ trans x≈y)fresh-remove : ∀ {x} {xs : List# A R} (x∈xs : x ∈ xs) → x # (xs ─ x∈xs)fresh-remove {xs = cons x xs pr} (here x≈y) = fresh-respectsˡ R≈ (sym x≈y) prfresh-remove {xs = cons x xs pr} (there x∈xs) =≉⇒R (distinct x∈xs (fresh⇒∉ R⇒≉ pr)) , fresh-remove x∈xs∉-remove : ∀ {x} {xs : List# A R} (x∈xs : x ∈ xs) → x ∉ (xs ─ x∈xs)∉-remove x∈xs = fresh⇒∉ R⇒≉ (fresh-remove x∈xs)-------------------------------------------------------------------------- injectionmodule _ {R : Rel A r} (R⇒≉ : ∀[ R ⇒ _≉_ ]) whereinjection : ∀ {xs ys : List# A R} (inj : ∀ {x} → x ∈ xs → x ∈ ys) →length xs ≤ length ysinjection {[]} {ys} inj = z≤ninjection {xxs@(cons x xs pr)} {ys} inj = beginlength xxs ≤⟨ s≤s (injection step) ⟩suc (length (ys ─ x∈ys)) ≡⟨ ≡.sym (List#.length-remove x∈ys) ⟩length ys ∎whereopen ≤-Reasoningx∉xs : x ∉ xsx∉xs = fresh⇒∉ R⇒≉ prx∈ys : x ∈ ysx∈ys = inj (here refl)step : ∀ {y} → y ∈ xs → y ∈ (ys ─ x∈ys)step {y} y∈xs = ∈-remove x∈ys (inj (there y∈xs)) (distinct y∈xs x∉xs ∘′ sym)strict-injection : ∀ {xs ys : List# A R} (inj : ∀ {x} → x ∈ xs → x ∈ ys) →(∃ λ x → x ∈ ys × x ∉ xs) → length xs < length ysstrict-injection {xs} {ys} inj (x , x∈ys , x∉xs) = beginsuc (length xs) ≤⟨ s≤s (injection step) ⟩suc (length (ys ─ x∈ys)) ≡⟨ ≡.sym (List#.length-remove x∈ys) ⟩length ys ∎whereopen ≤-Reasoningstep : ∀ {y} → y ∈ xs → y ∈ (ys ─ x∈ys)step {y} y∈xs = fromInj₂ (λ x≈y → ⊥-elim (x∉xs (≈-subst-∈ (sym x≈y) y∈xs)))$ remove-inv x∈ys (inj y∈xs)-------------------------------------------------------------------------- proof irrelevancemodule _ {R : Rel A r} (R⇒≉ : ∀[ R ⇒ _≉_ ]) (≈-irrelevant : Binary.Irrelevant _≈_) where∈-irrelevant : ∀ {x} {xs : List# A R} → Irrelevant (x ∈ xs)-- positive cases∈-irrelevant (here x≈y₁) (here x≈y₂) = ≡.cong here (≈-irrelevant x≈y₁ x≈y₂)∈-irrelevant (there x∈xs₁) (there x∈xs₂) = ≡.cong there (∈-irrelevant x∈xs₁ x∈xs₂)-- absurd cases∈-irrelevant {xs = cons x xs pr} (here x≈y) (there x∈xs₂) =⊥-elim (distinct x∈xs₂ (fresh⇒∉ R⇒≉ pr) x≈y)∈-irrelevant {xs = cons x xs pr} (there x∈xs₁) (here x≈y) =⊥-elim (distinct x∈xs₁ (fresh⇒∉ R⇒≉ pr) x≈y)
-------------------------------------------------------------------------- The Agda standard library---- Finding the maximum/minimum values in a list------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (TotalOrder; Setoid)module Data.List.Extrema{b ℓ₁ ℓ₂} (totalOrder : TotalOrder b ℓ₁ ℓ₂) whereimport Algebra.Construct.NaturalChoice.Min as Minimport Algebra.Construct.NaturalChoice.Max as Maxopen import Data.List.Base using (List; foldr)open import Data.List.Relation.Unary.Any as Any using (Any; here; there)open import Data.List.Relation.Unary.All using (All; []; _∷_; lookup; map; tabulate)open import Data.List.Membership.Propositional using (_∈_; lose)open import Data.List.Membership.Propositional.Propertiesusing (foldr-selective)open import Data.List.Relation.Binary.Subset.Propositional using (_⊆_; _⊇_)open import Data.List.Propertiesopen import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Function.Base using (id; flip; _on_; _∘_)open import Level using (Level)open import Relation.Unary using (Pred)import Relation.Binary.Construct.NonStrictToStrict as NonStrictToStrictopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; sym; subst) renaming (refl to ≡-refl)import Relation.Binary.Construct.On as On-------------------------------------------------------------------------- Setupopen TotalOrder totalOrder renaming (Carrier to B)open NonStrictToStrict _≈_ _≤_ using (_<_)open import Data.List.Extrema.Core totalOrderrenaming (⊓ᴸ to ⊓-lift; ⊔ᴸ to ⊔-lift)privatevariablea p : LevelA : Set a-------------------------------------------------------------------------- Functionsargmin : (A → B) → A → List A → Aargmin f = foldr (⊓-lift f)argmax : (A → B) → A → List A → Aargmax f = foldr (⊔-lift f)min : B → List B → Bmin = argmin idmax : B → List B → Bmax = argmax id-------------------------------------------------------------------------- Properties of argminmodule _ {f : A → B} wheref[argmin]≤v⁺ : ∀ {v} ⊤ xs → (f ⊤ ≤ v) ⊎ (Any (λ x → f x ≤ v) xs) →f (argmin f ⊤ xs) ≤ vf[argmin]≤v⁺ = foldr-preservesᵒ (⊓ᴸ-presᵒ-≤v f)f[argmin]<v⁺ : ∀ {v} ⊤ xs → (f ⊤ < v) ⊎ (Any (λ x → f x < v) xs) →f (argmin f ⊤ xs) < vf[argmin]<v⁺ = foldr-preservesᵒ (⊓ᴸ-presᵒ-<v f)v≤f[argmin]⁺ : ∀ {v ⊤ xs} → v ≤ f ⊤ → All (λ x → v ≤ f x) xs →v ≤ f (argmin f ⊤ xs)v≤f[argmin]⁺ = foldr-preservesᵇ (⊓ᴸ-presᵇ-v≤ f)v<f[argmin]⁺ : ∀ {v ⊤ xs} → v < f ⊤ → All (λ x → v < f x) xs →v < f (argmin f ⊤ xs)v<f[argmin]⁺ = foldr-preservesᵇ (⊓ᴸ-presᵇ-v< f)f[argmin]≤f[⊤] : ∀ ⊤ xs → f (argmin f ⊤ xs) ≤ f ⊤f[argmin]≤f[⊤] ⊤ xs = f[argmin]≤v⁺ ⊤ xs (inj₁ refl)f[argmin]≤f[xs] : ∀ ⊤ xs → All (λ x → f (argmin f ⊤ xs) ≤ f x) xsf[argmin]≤f[xs] ⊤ xs = foldr-forcesᵇ (⊓ᴸ-forcesᵇ-v≤ f) ⊤ xs reflf[argmin]≈f[v]⁺ : ∀ {v ⊤ xs} → v ∈ xs → All (λ x → f v ≤ f x) xs → f v ≤ f ⊤ →f (argmin f ⊤ xs) ≈ f vf[argmin]≈f[v]⁺ v∈xs fv≤fxs fv≤f⊤ = antisym(f[argmin]≤v⁺ _ _ (inj₂ (lose v∈xs refl)))(v≤f[argmin]⁺ fv≤f⊤ fv≤fxs)argmin[xs]≤argmin[ys]⁺ : ∀ {f g : A → B} ⊤₁ {⊤₂} xs {ys : List A} →(f ⊤₁ ≤ g ⊤₂) ⊎ Any (λ x → f x ≤ g ⊤₂) xs →All (λ y → (f ⊤₁ ≤ g y) ⊎ Any (λ x → f x ≤ g y) xs) ys →f (argmin f ⊤₁ xs) ≤ g (argmin g ⊤₂ ys)argmin[xs]≤argmin[ys]⁺ ⊤₁ xs xs≤⊤₂ xs≤ys =v≤f[argmin]⁺ (f[argmin]≤v⁺ ⊤₁ _ xs≤⊤₂) (map (f[argmin]≤v⁺ ⊤₁ xs) xs≤ys)argmin[xs]<argmin[ys]⁺ : ∀ {f g : A → B} ⊤₁ {⊤₂} xs {ys : List A} →(f ⊤₁ < g ⊤₂) ⊎ Any (λ x → f x < g ⊤₂) xs →All (λ y → (f ⊤₁ < g y) ⊎ Any (λ x → f x < g y) xs) ys →f (argmin f ⊤₁ xs) < g (argmin g ⊤₂ ys)argmin[xs]<argmin[ys]⁺ ⊤₁ xs xs<⊤₂ xs<ys =v<f[argmin]⁺ (f[argmin]<v⁺ ⊤₁ _ xs<⊤₂) (map (f[argmin]<v⁺ ⊤₁ xs) xs<ys)argmin-sel : ∀ (f : A → B) ⊤ xs → (argmin f ⊤ xs ≡ ⊤) ⊎ (argmin f ⊤ xs ∈ xs)argmin-sel f = foldr-selective (⊓ᴸ-sel f)argmin-all : ∀ (f : A → B) {⊤ xs} {P : Pred A p} →P ⊤ → All P xs → P (argmin f ⊤ xs)argmin-all f {⊤} {xs} {P = P} p⊤ pxs with argmin-sel f ⊤ xs... | inj₁ argmin≡⊤ = subst P (sym argmin≡⊤) p⊤... | inj₂ argmin∈xs = lookup pxs argmin∈xs-------------------------------------------------------------------------- Properties of argmaxmodule _ {f : A → B} wherev≤f[argmax]⁺ : ∀ {v} ⊥ xs → (v ≤ f ⊥) ⊎ (Any (λ x → v ≤ f x) xs) →v ≤ f (argmax f ⊥ xs)v≤f[argmax]⁺ = foldr-preservesᵒ (⊔ᴸ-presᵒ-v≤ f)v<f[argmax]⁺ : ∀ {v} ⊥ xs → (v < f ⊥) ⊎ (Any (λ x → v < f x) xs) →v < f (argmax f ⊥ xs)v<f[argmax]⁺ = foldr-preservesᵒ (⊔ᴸ-presᵒ-v< f)f[argmax]≤v⁺ : ∀ {v ⊥ xs} → f ⊥ ≤ v → All (λ x → f x ≤ v) xs →f (argmax f ⊥ xs) ≤ vf[argmax]≤v⁺ = foldr-preservesᵇ (⊔ᴸ-presᵇ-≤v f)f[argmax]<v⁺ : ∀ {v ⊥ xs} → f ⊥ < v → All (λ x → f x < v) xs →f (argmax f ⊥ xs) < vf[argmax]<v⁺ = foldr-preservesᵇ (⊔ᴸ-presᵇ-<v f)f[⊥]≤f[argmax] : ∀ ⊥ xs → f ⊥ ≤ f (argmax f ⊥ xs)f[⊥]≤f[argmax] ⊥ xs = v≤f[argmax]⁺ ⊥ xs (inj₁ refl)f[xs]≤f[argmax] : ∀ ⊥ xs → All (λ x → f x ≤ f (argmax f ⊥ xs)) xsf[xs]≤f[argmax] ⊥ xs = foldr-forcesᵇ (⊔ᴸ-forcesᵇ-≤v f) ⊥ xs reflf[argmax]≈f[v]⁺ : ∀ {v ⊥ xs} → v ∈ xs → All (λ x → f x ≤ f v) xs → f ⊥ ≤ f v →f (argmax f ⊥ xs) ≈ f vf[argmax]≈f[v]⁺ v∈xs fxs≤fv f⊥≤fv = antisym(f[argmax]≤v⁺ f⊥≤fv fxs≤fv)(v≤f[argmax]⁺ _ _ (inj₂ (lose v∈xs refl)))argmax[xs]≤argmax[ys]⁺ : ∀ {f g : A → B} {⊥₁} ⊥₂ {xs : List A} ys →(f ⊥₁ ≤ g ⊥₂) ⊎ Any (λ y → f ⊥₁ ≤ g y) ys →All (λ x → (f x ≤ g ⊥₂) ⊎ Any (λ y → f x ≤ g y) ys) xs →f (argmax f ⊥₁ xs) ≤ g (argmax g ⊥₂ ys)argmax[xs]≤argmax[ys]⁺ ⊥₂ ys ⊥₁≤ys xs≤ys =f[argmax]≤v⁺ (v≤f[argmax]⁺ ⊥₂ _ ⊥₁≤ys) (map (v≤f[argmax]⁺ ⊥₂ ys) xs≤ys)argmax[xs]<argmax[ys]⁺ : ∀ {f g : A → B} {⊥₁} ⊥₂ {xs : List A} ys →(f ⊥₁ < g ⊥₂) ⊎ Any (λ y → f ⊥₁ < g y) ys →All (λ x → (f x < g ⊥₂) ⊎ Any (λ y → f x < g y) ys) xs →f (argmax f ⊥₁ xs) < g (argmax g ⊥₂ ys)argmax[xs]<argmax[ys]⁺ ⊥₂ ys ⊥₁<ys xs<ys =f[argmax]<v⁺ (v<f[argmax]⁺ ⊥₂ _ ⊥₁<ys) (map (v<f[argmax]⁺ ⊥₂ ys) xs<ys)argmax-sel : ∀ (f : A → B) ⊥ xs → (argmax f ⊥ xs ≡ ⊥) ⊎ (argmax f ⊥ xs ∈ xs)argmax-sel f = foldr-selective (⊔ᴸ-sel f)argmax-all : ∀ (f : A → B) {P : Pred A p} {⊥ xs} →P ⊥ → All P xs → P (argmax f ⊥ xs)argmax-all f {P = P} {⊥} {xs} p⊥ pxs with argmax-sel f ⊥ xs... | inj₁ argmax≡⊥ = subst P (sym argmax≡⊥) p⊥... | inj₂ argmax∈xs = lookup pxs argmax∈xs-------------------------------------------------------------------------- Properties of minmin≤v⁺ : ∀ {v} ⊤ xs → ⊤ ≤ v ⊎ Any (_≤ v) xs → min ⊤ xs ≤ vmin≤v⁺ = f[argmin]≤v⁺min<v⁺ : ∀ {v} ⊤ xs → ⊤ < v ⊎ Any (_< v) xs → min ⊤ xs < vmin<v⁺ = f[argmin]<v⁺v≤min⁺ : ∀ {v ⊤ xs} → v ≤ ⊤ → All (v ≤_) xs → v ≤ min ⊤ xsv≤min⁺ = v≤f[argmin]⁺v<min⁺ : ∀ {v ⊤ xs} → v < ⊤ → All (v <_) xs → v < min ⊤ xsv<min⁺ = v<f[argmin]⁺min≤⊤ : ∀ ⊤ xs → min ⊤ xs ≤ ⊤min≤⊤ = f[argmin]≤f[⊤]min≤xs : ∀ ⊥ xs → All (min ⊥ xs ≤_) xsmin≤xs = f[argmin]≤f[xs]min≈v⁺ : ∀ {v ⊤ xs} → v ∈ xs → All (v ≤_) xs → v ≤ ⊤ → min ⊤ xs ≈ vmin≈v⁺ = f[argmin]≈f[v]⁺min[xs]≤min[ys]⁺ : ∀ ⊤₁ {⊤₂} xs {ys} → (⊤₁ ≤ ⊤₂) ⊎ Any (_≤ ⊤₂) xs →All (λ y → (⊤₁ ≤ y) ⊎ Any (λ x → x ≤ y) xs) ys →min ⊤₁ xs ≤ min ⊤₂ ysmin[xs]≤min[ys]⁺ = argmin[xs]≤argmin[ys]⁺min[xs]<min[ys]⁺ : ∀ ⊤₁ {⊤₂} xs {ys} → (⊤₁ < ⊤₂) ⊎ Any (_< ⊤₂) xs →All (λ y → (⊤₁ < y) ⊎ Any (λ x → x < y) xs) ys →min ⊤₁ xs < min ⊤₂ ysmin[xs]<min[ys]⁺ = argmin[xs]<argmin[ys]⁺min-mono-⊆ : ∀ {⊥₁ ⊥₂ xs ys} → ⊥₁ ≤ ⊥₂ → xs ⊇ ys → min ⊥₁ xs ≤ min ⊥₂ ysmin-mono-⊆ ⊥₁≤⊥₂ ys⊆xs = min[xs]≤min[ys]⁺ _ _ (inj₁ ⊥₁≤⊥₂)(tabulate (inj₂ ∘ Any.map (λ {≡-refl → refl}) ∘ ys⊆xs))-------------------------------------------------------------------------- Properties of maxmax≤v⁺ : ∀ {v ⊥ xs} → ⊥ ≤ v → All (_≤ v) xs → max ⊥ xs ≤ vmax≤v⁺ = f[argmax]≤v⁺max<v⁺ : ∀ {v ⊥ xs} → ⊥ < v → All (_< v) xs → max ⊥ xs < vmax<v⁺ = f[argmax]<v⁺v≤max⁺ : ∀ {v} ⊥ xs → v ≤ ⊥ ⊎ Any (v ≤_) xs → v ≤ max ⊥ xsv≤max⁺ = v≤f[argmax]⁺v<max⁺ : ∀ {v} ⊥ xs → v < ⊥ ⊎ Any (v <_) xs → v < max ⊥ xsv<max⁺ = v<f[argmax]⁺⊥≤max : ∀ ⊥ xs → ⊥ ≤ max ⊥ xs⊥≤max = f[⊥]≤f[argmax]xs≤max : ∀ ⊥ xs → All (_≤ max ⊥ xs) xsxs≤max = f[xs]≤f[argmax]max≈v⁺ : ∀ {v ⊤ xs} → v ∈ xs → All (_≤ v) xs → ⊤ ≤ v → max ⊤ xs ≈ vmax≈v⁺ = f[argmax]≈f[v]⁺max[xs]≤max[ys]⁺ : ∀ {⊥₁} ⊥₂ {xs} ys → ⊥₁ ≤ ⊥₂ ⊎ Any (⊥₁ ≤_) ys →All (λ x → x ≤ ⊥₂ ⊎ Any (x ≤_) ys) xs →max ⊥₁ xs ≤ max ⊥₂ ysmax[xs]≤max[ys]⁺ = argmax[xs]≤argmax[ys]⁺max[xs]<max[ys]⁺ : ∀ {⊥₁} ⊥₂ {xs} ys → ⊥₁ < ⊥₂ ⊎ Any (⊥₁ <_) ys →All (λ x → x < ⊥₂ ⊎ Any (x <_) ys) xs →max ⊥₁ xs < max ⊥₂ ysmax[xs]<max[ys]⁺ = argmax[xs]<argmax[ys]⁺max-mono-⊆ : ∀ {⊥₁ ⊥₂ xs ys} → ⊥₁ ≤ ⊥₂ → xs ⊆ ys → max ⊥₁ xs ≤ max ⊥₂ ysmax-mono-⊆ ⊥₁≤⊥₂ xs⊆ys = max[xs]≤max[ys]⁺ _ _ (inj₁ ⊥₁≤⊥₂)(tabulate (inj₂ ∘ Any.map (λ {≡-refl → refl}) ∘ xs⊆ys))
-------------------------------------------------------------------------- The Agda standard library---- Finding the maximum/minimum values in a list, specialised for Nat------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- This specialised module is needed as `m < n` for Nat is not-- implemented as `m ≤ n × m ≢ n`.module Data.List.Extrema.Nat whereopen import Data.Nat.Base using (ℕ; _≤_; _<_)open import Data.Nat.Properties as ℕ using (≤∧≢⇒<; <⇒≤; <⇒≢)open import Data.Sum.Base as Sum using (_⊎_)open import Data.List.Base using (List)import Data.List.Extremaopen import Data.List.Relation.Unary.Any as Any using (Any)open import Data.List.Relation.Unary.All as All using (All)open import Data.Product.Base using (_×_; _,_; uncurry′)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≢_)privatevariablea : LevelA : Set a<⇒<× : ∀ {x y} → x < y → x ≤ y × x ≢ y<⇒<× x<y = <⇒≤ x<y , <⇒≢ x<y<×⇒< : ∀ {x y} → x ≤ y × x ≢ y → x < y<×⇒< (x≤y , x≢y) = ≤∧≢⇒< x≤y x≢ymodule Extrema = Data.List.Extrema ℕ.≤-totalOrder-------------------------------------------------------------------------- Re-export the contents of Extremaopen Extrema publichiding( f[argmin]<v⁺; v<f[argmin]⁺; argmin[xs]<argmin[ys]⁺; f[argmax]<v⁺; v<f[argmax]⁺; argmax[xs]<argmax[ys]⁺; min<v⁺; v<min⁺; min[xs]<min[ys]⁺; max<v⁺; v<max⁺; max[xs]<max[ys]⁺)-------------------------------------------------------------------------- New versions of the proofs involving _<_-- Argminf[argmin]<v⁺ : ∀ {f : A → ℕ} {v} ⊤ xs →(f ⊤ < v) ⊎ (Any (λ x → f x < v) xs) →f (argmin f ⊤ xs) < vf[argmin]<v⁺ ⊤ xs arg =<×⇒< (Extrema.f[argmin]<v⁺ ⊤ xs (Sum.map <⇒<× (Any.map <⇒<×) arg))v<f[argmin]⁺ : ∀ {f : A → ℕ} {v ⊤ xs} →v < f ⊤ → All (λ x → v < f x) xs →v < f (argmin f ⊤ xs)v<f[argmin]⁺ {v} v<f⊤ v<fxs =<×⇒< (Extrema.v<f[argmin]⁺ (<⇒<× v<f⊤) (All.map <⇒<× v<fxs))argmin[xs]<argmin[ys]⁺ : ∀ {f g : A → ℕ} ⊤₁ {⊤₂} xs {ys} →(f ⊤₁ < g ⊤₂) ⊎ Any (λ x → f x < g ⊤₂) xs →All (λ y → (f ⊤₁ < g y) ⊎ Any (λ x → f x < g y) xs) ys →f (argmin f ⊤₁ xs) < g (argmin g ⊤₂ ys)argmin[xs]<argmin[ys]⁺ ⊤₁ xs xs<⊤₂ xs<ys =v<f[argmin]⁺ (f[argmin]<v⁺ ⊤₁ _ xs<⊤₂) (All.map (f[argmin]<v⁺ ⊤₁ xs) xs<ys)-- Argmaxv<f[argmax]⁺ : ∀ {f : A → ℕ} {v} ⊥ xs → (v < f ⊥) ⊎ (Any (λ x → v < f x) xs) →v < f (argmax f ⊥ xs)v<f[argmax]⁺ ⊥ xs leq = <×⇒< (Extrema.v<f[argmax]⁺ ⊥ xs (Sum.map <⇒<× (Any.map <⇒<×) leq))f[argmax]<v⁺ : ∀ {f : A → ℕ} {v ⊥ xs} → f ⊥ < v → All (λ x → f x < v) xs →f (argmax f ⊥ xs) < vf[argmax]<v⁺ ⊥<v xs<v = <×⇒< (Extrema.f[argmax]<v⁺ (<⇒<× ⊥<v) (All.map <⇒<× xs<v))argmax[xs]<argmax[ys]⁺ : ∀ {f g : A → ℕ} {⊥₁} ⊥₂ {xs} ys →(f ⊥₁ < g ⊥₂) ⊎ Any (λ y → f ⊥₁ < g y) ys →All (λ x → (f x < g ⊥₂) ⊎ Any (λ y → f x < g y) ys) xs →f (argmax f ⊥₁ xs) < g (argmax g ⊥₂ ys)argmax[xs]<argmax[ys]⁺ ⊥₂ ys ⊥₁<ys xs<ys =f[argmax]<v⁺ (v<f[argmax]⁺ ⊥₂ _ ⊥₁<ys) (All.map (v<f[argmax]⁺ ⊥₂ ys) xs<ys)-- Minmin<v⁺ : ∀ {v} ⊤ xs → ⊤ < v ⊎ Any (_< v) xs → min ⊤ xs < vmin<v⁺ = f[argmin]<v⁺v<min⁺ : ∀ {v ⊤ xs} → v < ⊤ → All (v <_) xs → v < min ⊤ xsv<min⁺ = v<f[argmin]⁺min[xs]<min[ys]⁺ : ∀ ⊤₁ {⊤₂} xs {ys} → (⊤₁ < ⊤₂) ⊎ Any (_< ⊤₂) xs →All (λ y → (⊤₁ < y) ⊎ Any (λ x → x < y) xs) ys →min ⊤₁ xs < min ⊤₂ ysmin[xs]<min[ys]⁺ = argmin[xs]<argmin[ys]⁺-- Maxmax<v⁺ : ∀ {v ⊥ xs} → ⊥ < v → All (_< v) xs → max ⊥ xs < vmax<v⁺ = f[argmax]<v⁺v<max⁺ : ∀ {v} ⊥ xs → v < ⊥ ⊎ Any (v <_) xs → v < max ⊥ xsv<max⁺ = v<f[argmax]⁺max[xs]<max[ys]⁺ : ∀ {⊥₁} ⊥₂ {xs} ys → ⊥₁ < ⊥₂ ⊎ Any (⊥₁ <_) ys →All (λ x → x < ⊥₂ ⊎ Any (x <_) ys) xs →max ⊥₁ xs < max ⊥₂ ysmax[xs]<max[ys]⁺ = argmax[xs]<argmax[ys]⁺
-------------------------------------------------------------------------- The Agda standard library---- Core lemmas needed to make list argmin/max functions work------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Definitions using (Trans)open import Relation.Binary.Bundles using (TotalOrder; Setoid)module Data.List.Extrema.Core{b ℓ₁ ℓ₂} (totalOrder : TotalOrder b ℓ₁ ℓ₂) whereopen import Algebra.Coreopen import Algebra.Definitionsimport Algebra.Construct.NaturalChoice.Min as Minimport Algebra.Construct.NaturalChoice.Max as Maxopen import Data.Product.Base using (_×_; _,_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Algebra.Construct.LiftedChoiceopen TotalOrder totalOrder renaming (Carrier to B)open import Relation.Binary.Construct.NonStrictToStrict _≈_ _≤_using (_<_; <-≤-trans; ≤-<-trans)-------------------------------------------------------------------------- Setup-- open NonStrictToStrict totalOrder using (_<_; ≤-<-trans; <-≤-trans)open Max totalOrderopen Min totalOrderprivatevariablea : LevelA : Set a<-transʳ : Trans _≤_ _<_ _<_<-transʳ = ≤-<-trans trans antisym ≤-respˡ-≈<-transˡ : Trans _<_ _≤_ _<_<-transˡ = <-≤-trans Eq.sym trans antisym ≤-respʳ-≈module _ (f : A → B) wherelemma₁ : ∀ {x y v} → f x ≤ v → f x ⊓ f y ≈ f y → f y ≤ vlemma₁ fx≤v fx⊓fy≈fy = trans (x⊓y≈y⇒y≤x fx⊓fy≈fy) fx≤vlemma₂ : ∀ {x y v} → f y ≤ v → f x ⊓ f y ≈ f x → f x ≤ vlemma₂ fy≤v fx⊓fy≈fx = trans (x⊓y≈x⇒x≤y fx⊓fy≈fx) fy≤vlemma₃ : ∀ {x y v} → f x < v → f x ⊓ f y ≈ f y → f y < vlemma₃ fx<v fx⊓fy≈fy = <-transʳ (x⊓y≈y⇒y≤x fx⊓fy≈fy) fx<vlemma₄ : ∀ {x y v} → f y < v → f x ⊓ f y ≈ f x → f x < vlemma₄ fx<v fx⊓fy≈fy = <-transʳ (x⊓y≈x⇒x≤y fx⊓fy≈fy) fx<v-------------------------------------------------------------------------- Definition of lifted max and min⊓ᴸ : (A → B) → Op₂ A⊓ᴸ = Lift _≈_ _⊓_ ⊓-sel⊔ᴸ : (A → B) → Op₂ A⊔ᴸ = Lift _≈_ _⊔_ ⊔-sel-------------------------------------------------------------------------- Properties of ⊓ᴸ⊓ᴸ-sel : ∀ f → Selective {A = A} _≡_ (⊓ᴸ f)⊓ᴸ-sel f = sel-≡ ⊓-isSelectiveMagma f⊓ᴸ-presᵒ-≤v : ∀ f {v} (x y : A) → f x ≤ v ⊎ f y ≤ v → f (⊓ᴸ f x y) ≤ v⊓ᴸ-presᵒ-≤v f = preservesᵒ ⊓-isSelectiveMagma f (lemma₁ f) (lemma₂ f)⊓ᴸ-presᵒ-<v : ∀ f {v} (x y : A) → f x < v ⊎ f y < v → f (⊓ᴸ f x y) < v⊓ᴸ-presᵒ-<v f = preservesᵒ ⊓-isSelectiveMagma f (lemma₃ f) (lemma₄ f)⊓ᴸ-presᵇ-v≤ : ∀ f {v} {x y : A} → v ≤ f x → v ≤ f y → v ≤ f (⊓ᴸ f x y)⊓ᴸ-presᵇ-v≤ f {v} = preservesᵇ ⊓-isSelectiveMagma {P = λ x → v ≤ f x} f⊓ᴸ-presᵇ-v< : ∀ f {v} {x y : A} → v < f x → v < f y → v < f (⊓ᴸ f x y)⊓ᴸ-presᵇ-v< f {v} = preservesᵇ ⊓-isSelectiveMagma {P = λ x → v < f x} f⊓ᴸ-forcesᵇ-v≤ : ∀ f {v} (x y : A) → v ≤ f (⊓ᴸ f x y) → v ≤ f x × v ≤ f y⊓ᴸ-forcesᵇ-v≤ f {v} = forcesᵇ ⊓-isSelectiveMagma f(λ v≤fx fx⊓fy≈fx → trans v≤fx (x⊓y≈x⇒x≤y fx⊓fy≈fx))(λ v≤fy fx⊓fy≈fy → trans v≤fy (x⊓y≈y⇒y≤x fx⊓fy≈fy))-------------------------------------------------------------------------- Properties of ⊔ᴸ⊔ᴸ-sel : ∀ f → Selective {A = A} _≡_ (⊔ᴸ f)⊔ᴸ-sel f = sel-≡ ⊔-isSelectiveMagma f⊔ᴸ-presᵒ-v≤ : ∀ f {v} (x y : A) → v ≤ f x ⊎ v ≤ f y → v ≤ f (⊔ᴸ f x y)⊔ᴸ-presᵒ-v≤ f {v} = preservesᵒ ⊔-isSelectiveMagma f(λ v≤fx fx⊔fy≈fy → trans v≤fx (x⊔y≈y⇒x≤y fx⊔fy≈fy))(λ v≤fy fx⊔fy≈fx → trans v≤fy (x⊔y≈x⇒y≤x fx⊔fy≈fx))⊔ᴸ-presᵒ-v< : ∀ f {v} (x y : A) → v < f x ⊎ v < f y → v < f (⊔ᴸ f x y)⊔ᴸ-presᵒ-v< f {v} = preservesᵒ ⊔-isSelectiveMagma f(λ v<fx fx⊔fy≈fy → <-transˡ v<fx (x⊔y≈y⇒x≤y fx⊔fy≈fy))(λ v<fy fx⊔fy≈fx → <-transˡ v<fy (x⊔y≈x⇒y≤x fx⊔fy≈fx))⊔ᴸ-presᵇ-≤v : ∀ f {v} {x y : A} → f x ≤ v → f y ≤ v → f (⊔ᴸ f x y) ≤ v⊔ᴸ-presᵇ-≤v f {v} = preservesᵇ ⊔-isSelectiveMagma {P = λ x → f x ≤ v} f⊔ᴸ-presᵇ-<v : ∀ f {v} {x y : A} → f x < v → f y < v → f (⊔ᴸ f x y) < v⊔ᴸ-presᵇ-<v f {v} = preservesᵇ ⊔-isSelectiveMagma {P = λ x → f x < v} f⊔ᴸ-forcesᵇ-≤v : ∀ f {v} (x y : A) → f (⊔ᴸ f x y) ≤ v → f x ≤ v × f y ≤ v⊔ᴸ-forcesᵇ-≤v f {v} = forcesᵇ ⊔-isSelectiveMagma f(λ fx≤v fx⊔fy≈fx → trans (x⊔y≈x⇒y≤x fx⊔fy≈fx) fx≤v)(λ fy≤v fx⊔fy≈fy → trans (x⊔y≈y⇒x≤y fx⊔fy≈fy) fy≤v)
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of List------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Effectful whereopen import Data.Bool.Base using (false; true)open import Data.List.Baseusing (List; map; [_]; ap; []; _∷_; _++_; concat; concatMap)open import Data.List.Propertiesusing (++-identityʳ; ++-assoc; map-cong; concatMap-cong; map-concatMap;concatMap-pure)open import Effect.Choice using (RawChoice)open import Effect.Empty using (RawEmpty)open import Effect.Functor using (RawFunctor)open import Effect.Applicativeusing (RawApplicative; RawApplicativeZero; RawAlternative)open import Effect.Monadusing (RawMonad; module Join; RawMonadZero; RawMonadPlus)open import Function.Base using (flip; _∘_; const; _$_; id; _∘′_; _$′_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; _≗_; refl)open import Relation.Binary.PropositionalEquality.Properties as ≡open ≡.≡-Reasoningprivatevariableℓ : LevelA : Set ℓ-------------------------------------------------------------------------- List applicative functorfunctor : RawFunctor {ℓ} Listfunctor = record { _<$>_ = map }applicative : RawApplicative {ℓ} Listapplicative = record{ rawFunctor = functor; pure = [_]; _<*>_ = ap}empty : RawEmpty {ℓ} Listempty = record { empty = [] }choice : RawChoice {ℓ} Listchoice = record { _<|>_ = _++_ }applicativeZero : RawApplicativeZero {ℓ} ListapplicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}alternative : RawAlternative {ℓ} Listalternative = record{ rawApplicativeZero = applicativeZero; rawChoice = choice}-------------------------------------------------------------------------- List monadmonad : ∀ {ℓ} → RawMonad {ℓ} Listmonad = record{ rawApplicative = applicative; _>>=_ = flip concatMap}join : List (List A) → List Ajoin = Join.join monadmonadZero : ∀ {ℓ} → RawMonadZero {ℓ} ListmonadZero = record{ rawMonad = monad; rawEmpty = empty}monadPlus : ∀ {ℓ} → RawMonadPlus {ℓ} ListmonadPlus = record{ rawMonadZero = monadZero; rawChoice = choice}-------------------------------------------------------------------------- Get access to other monadic functionsmodule TraversableA {f g F} (App : RawApplicative {f} {g} F) whereopen RawApplicative AppsequenceA : ∀ {A} → List (F A) → F (List A)sequenceA [] = pure []sequenceA (x ∷ xs) = _∷_ <$> x <*> sequenceA xsmapA : ∀ {a} {A : Set a} {B} → (A → F B) → List A → F (List B)mapA f = sequenceA ∘ map fforA : ∀ {a} {A : Set a} {B} → List A → (A → F B) → F (List B)forA = flip mapAmodule TraversableM {m n M} (Mon : RawMonad {m} {n} M) whereopen RawMonad Monopen TraversableA rawApplicative publicrenaming( sequenceA to sequenceM; mapA to mapM; forA to forM)-------------------------------------------------------------------------- The list monad.privateopen module LMP {ℓ} = RawMonadPlus (monadPlus {ℓ = ℓ})module MonadProperties whereleft-identity : ∀ {ℓ} {A B : Set ℓ} (x : A) (f : A → List B) →(pure x >>= f) ≡ f xleft-identity x f = ++-identityʳ (f x)right-identity : ∀ {ℓ} {A : Set ℓ} (xs : List A) →(xs >>= pure) ≡ xsright-identity [] = reflright-identity (x ∷ xs) = ≡.cong (x ∷_) (right-identity xs)left-zero : ∀ {ℓ} {A B : Set ℓ} (f : A → List B) → (∅ >>= f) ≡ ∅left-zero f = reflright-zero : ∀ {ℓ} {A B : Set ℓ} (xs : List A) →(xs >>= const ∅) ≡ ∅ {A = B}right-zero [] = reflright-zero (x ∷ xs) = right-zero xsprivatenot-left-distributive :let xs = true ∷ false ∷ []; f = pure; g = pure in(xs >>= λ x → f x ∣ g x) ≢ ((xs >>= f) ∣ (xs >>= g))not-left-distributive ()right-distributive : ∀ {ℓ} {A B : Set ℓ}(xs ys : List A) (f : A → List B) →(xs ∣ ys >>= f) ≡ ((xs >>= f) ∣ (ys >>= f))right-distributive [] ys f = reflright-distributive (x ∷ xs) ys f = beginf x ∣ (xs ∣ ys >>= f) ≡⟨ ≡.cong (f x ∣_) $ right-distributive xs ys f ⟩f x ∣ ((xs >>= f) ∣ (ys >>= f)) ≡⟨ ≡.sym $ ++-assoc (f x) _ _ ⟩((f x ∣ (xs >>= f)) ∣ (ys >>= f)) ∎associative : ∀ {ℓ} {A B C : Set ℓ}(xs : List A) (f : A → List B) (g : B → List C) →(xs >>= λ x → f x >>= g) ≡ (xs >>= f >>= g)associative [] f g = reflassociative (x ∷ xs) f g = begin(f x >>= g) ∣ (xs >>= λ x → f x >>= g) ≡⟨ ≡.cong ((f x >>= g) ∣_) $ associative xs f g ⟩(f x >>= g) ∣ (xs >>= f >>= g) ≡⟨ ≡.sym $ right-distributive (f x) (xs >>= f) g ⟩(f x ∣ (xs >>= f) >>= g) ∎cong : ∀ {ℓ} {A B : Set ℓ} {xs₁ xs₂} {f₁ f₂ : A → List B} →xs₁ ≡ xs₂ → f₁ ≗ f₂ → (xs₁ >>= f₁) ≡ (xs₂ >>= f₂)cong {xs₁ = xs} refl f₁≗f₂ = ≡.cong concat (map-cong f₁≗f₂ xs)-------------------------------------------------------------------------- The applicative functor derived from the list monad.-- Note that these proofs (almost) show that RawIMonad.rawIApplicative-- is correctly defined. The proofs can be reused if proof components-- are ever added to RawIMonad and RawIApplicative.module Applicative whereprivatemodule MP = MonadProperties-- A variant of flip map.pam : ∀ {ℓ} {A B : Set ℓ} → List A → (A → B) → List Bpam xs f = xs >>= pure ∘ f-- ∅ is a left zero for _⊛_.left-zero : ∀ {ℓ} {A B : Set ℓ} → (xs : List A) → (∅ ⊛ xs) ≡ ∅ {A = B}left-zero xs = begin∅ ⊛ xs ≡⟨⟩(∅ >>= pam xs) ≡⟨ MonadProperties.left-zero (pam xs) ⟩∅ ∎-- ∅ is a right zero for _⊛_.right-zero : ∀ {ℓ} {A B : Set ℓ} → (fs : List (A → B)) → (fs ⊛ ∅) ≡ ∅right-zero {ℓ} fs = beginfs ⊛ ∅ ≡⟨⟩(fs >>= pam ∅) ≡⟨ (MP.cong (refl {x = fs}) λ f →MP.left-zero (pure ∘ f)) ⟩(fs >>= λ _ → ∅) ≡⟨ MP.right-zero fs ⟩∅ ∎unfold-<$> : ∀ {ℓ} {A B : Set ℓ} → (f : A → B) (as : List A) →(f <$> as) ≡ (pure f ⊛ as)unfold-<$> f as = ≡.sym (++-identityʳ (f <$> as))-- _⊛_ unfolds to binds.unfold-⊛ : ∀ {ℓ} {A B : Set ℓ} → (fs : List (A → B)) (as : List A) →(fs ⊛ as) ≡ (fs >>= pam as)unfold-⊛ fs as = beginfs ⊛ as≡⟨ concatMap-cong (λ f → ≡.cong (map f) (concatMap-pure as)) fs ⟨concatMap (λ f → map f (concatMap pure as)) fs≡⟨ concatMap-cong (λ f → map-concatMap f pure as) fs ⟩concatMap (λ f → concatMap (λ x → pure (f x)) as) fs≡⟨⟩(fs >>= pam as)∎-- _⊛_ distributes over _∣_ from the right.right-distributive : ∀ {ℓ} {A B : Set ℓ} (fs₁ fs₂ : List (A → B)) xs →((fs₁ ∣ fs₂) ⊛ xs) ≡ (fs₁ ⊛ xs ∣ fs₂ ⊛ xs)right-distributive fs₁ fs₂ xs = begin(fs₁ ∣ fs₂) ⊛ xs ≡⟨ unfold-⊛ (fs₁ ∣ fs₂) xs ⟩(fs₁ ∣ fs₂ >>= pam xs) ≡⟨ MonadProperties.right-distributive fs₁ fs₂ (pam xs) ⟩(fs₁ >>= pam xs) ∣ (fs₂ >>= pam xs) ≡⟨ ≡.cong₂ _∣_ (unfold-⊛ fs₁ xs) (unfold-⊛ fs₂ xs) ⟨(fs₁ ⊛ xs ∣ fs₂ ⊛ xs) ∎-- _⊛_ does not distribute over _∣_ from the left.privatenot-left-distributive :let fs = id ∷ id ∷ []; xs₁ = true ∷ []; xs₂ = true ∷ false ∷ [] in(fs ⊛ (xs₁ ∣ xs₂)) ≢ (fs ⊛ xs₁ ∣ fs ⊛ xs₂)not-left-distributive ()-- Applicative functor laws.identity : ∀ {a} {A : Set a} (xs : List A) → (pure id ⊛ xs) ≡ xsidentity xs = beginpure id ⊛ xs ≡⟨ unfold-⊛ (pure id) xs ⟩(pure id >>= pam xs) ≡⟨ MonadProperties.left-identity id (pam xs) ⟩(xs >>= pure) ≡⟨ MonadProperties.right-identity xs ⟩xs ∎privatepam-lemma : ∀ {ℓ} {A B C : Set ℓ}(xs : List A) (f : A → B) (fs : B → List C) →(pam xs f >>= fs) ≡ (xs >>= λ x → fs (f x))pam-lemma xs f fs = begin(pam xs f >>= fs) ≡⟨ MP.associative xs (pure ∘ f) fs ⟨(xs >>= λ x → pure (f x) >>= fs) ≡⟨ MP.cong (refl {x = xs}) (λ x → MP.left-identity (f x) fs) ⟩(xs >>= λ x → fs (f x)) ∎composition : ∀ {ℓ} {A B C : Set ℓ}(fs : List (B → C)) (gs : List (A → B)) xs →(pure _∘′_ ⊛ fs ⊛ gs ⊛ xs) ≡ (fs ⊛ (gs ⊛ xs))composition {ℓ} fs gs xs = beginpure _∘′_ ⊛ fs ⊛ gs ⊛ xs≡⟨ unfold-⊛ (pure _∘′_ ⊛ fs ⊛ gs) xs ⟩(pure _∘′_ ⊛ fs ⊛ gs >>= pam xs)≡⟨ ≡.cong (_>>= pam xs) (unfold-⊛ (pure _∘′_ ⊛ fs) gs) ⟩(pure _∘′_ ⊛ fs >>= pam gs >>= pam xs)≡⟨ ≡.cong (λ h → h >>= pam gs >>= pam xs) (unfold-⊛ (pure _∘′_) fs) ⟩(pure _∘′_ >>= pam fs >>= pam gs >>= pam xs)≡⟨ MP.cong (MP.cong (MP.left-identity _∘′_ (pam fs))(λ f → refl {x = pam gs f}))(λ fg → refl {x = pam xs fg}) ⟩(pam fs _∘′_ >>= pam gs >>= pam xs)≡⟨ MP.cong (pam-lemma fs _∘′_ (pam gs)) (λ _ → refl) ⟩((fs >>= λ f → pam gs (f ∘′_)) >>= pam xs)≡⟨ MP.associative fs (λ f → pam gs (_∘′_ f)) (pam xs) ⟨(fs >>= λ f → pam gs (f ∘′_) >>= pam xs)≡⟨ MP.cong (refl {x = fs}) (λ f → pam-lemma gs (f ∘′_) (pam xs)) ⟩(fs >>= λ f → gs >>= λ g → pam xs (f ∘′ g))≡⟨ (MP.cong (refl {x = fs}) λ f →MP.cong (refl {x = gs}) λ g →≡.sym $ pam-lemma xs g (pure ∘ f)) ⟩(fs >>= λ f → gs >>= λ g → pam (pam xs g) f)≡⟨ MP.cong (refl {x = fs}) (λ f → MP.associative gs (pam xs) (pure ∘ f)) ⟩(fs >>= pam (gs >>= pam xs))≡⟨ unfold-⊛ fs (gs >>= pam xs) ⟨fs ⊛ (gs >>= pam xs)≡⟨ ≡.cong (fs ⊛_) (unfold-⊛ gs xs) ⟨fs ⊛ (gs ⊛ xs)∎homomorphism : ∀ {ℓ} {A B : Set ℓ} (f : A → B) x →(pure f ⊛ pure x) ≡ pure (f x)homomorphism f x = beginpure f ⊛ pure x ≡⟨⟩(pure f >>= pam (pure x)) ≡⟨ MP.left-identity f (pam (pure x)) ⟩pam (pure x) f ≡⟨ MP.left-identity x (pure ∘ f) ⟩pure (f x) ∎interchange : ∀ {ℓ} {A B : Set ℓ} (fs : List (A → B)) {x} →(fs ⊛ pure x) ≡ (pure (_$′ x) ⊛ fs)interchange fs {x} = beginfs ⊛ pure x ≡⟨⟩(fs >>= pam (pure x)) ≡⟨ (MP.cong (refl {x = fs}) λ f →MP.left-identity x (pure ∘ f)) ⟩(fs >>= λ f → pure (f x)) ≡⟨⟩(pam fs (_$′ x)) ≡⟨ ≡.sym $ MP.left-identity (_$′ x) (pam fs) ⟩(pure (_$′ x) >>= pam fs) ≡⟨ unfold-⊛ (pure (_$′ x)) fs ⟨pure (_$′ x) ⊛ fs ∎
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of List------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Effectful.Transformer whereopen import Data.List.Base as List using (List; []; _∷_)open import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Function.Baseopen import Levelimport Data.List.Effectful as Listprivatevariablef g : LevelM : Set f → Set g-------------------------------------------------------------------------- List monad transformerrecord ListT (M : Set f → Set g) (A : Set f) : Set g whereconstructor mkListTfield runListT : M (List A)open ListT publicfunctor : RawFunctor M → RawFunctor {f} (ListT M)functor M = record{ _<$>_ = λ f → mkListT ∘′ (List.map f <$>_) ∘′ runListT} where open RawFunctor Mapplicative : RawApplicative M → RawApplicative {f} (ListT M)applicative M = record{ rawFunctor = functor rawFunctor; pure = mkListT ∘′ pure ∘′ List.[_]; _<*>_ = λ mf ma → mkListT (List.ap <$> runListT mf <*> runListT ma)} where open RawApplicative Mmonad : RawMonad M → RawMonad (ListT M)monad M = record{ rawApplicative = applicative rawApplicative; _>>=_ = λ mas f → mkListT $ doas ← runListT masList.concat <$> mapM (runListT ∘′ f) as} where open RawMonad M; open List.TraversableM MmonadT : RawMonadT {f} {g} ListTmonadT M = record{ lift = mkListT ∘′ (List.[_] <$>_); rawMonad = monad M} where open RawMonad M
-------------------------------------------------------------------------- The Agda standard library---- A data structure which keeps track of an upper bound on the number-- of elements /not/ in a given list------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (0ℓ)open import Relation.Binary.Bundles using (DecSetoid)module Data.List.Countdown (D : DecSetoid 0ℓ 0ℓ) whereopen import Data.Emptyopen import Data.Fin.Base using (Fin; zero; suc; punchOut)open import Data.Fin.Propertiesusing (suc-injective; punchOut-injective)open import Function.Baseopen import Function.Bundlesusing (Injection; module Injection)open import Data.Bool.Base using (true; false)open import Data.List.Base hiding (lookup)open import Data.List.Relation.Unary.Any as Any using (here; there)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Product.Base using (∃; _,_; _×_)open import Data.Sum.Baseopen import Data.Sum.Propertiesopen import Relation.Nullary.Reflects using (invert)open import Relation.Nullaryopen import Relation.Nullary.Decidable using (dec-true; dec-false)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; refl; cong)import Relation.Binary.PropositionalEquality.Properties as ≡open ≡.≡-Reasoningprivateopen module D = DecSetoid Dhiding (refl) renaming (Carrier to Elem)open import Data.List.Membership.Setoid D.setoid-------------------------------------------------------------------------- Helper functionsprivate-- The /first/ occurrence of x in xs.first-occurrence : ∀ {xs} x → x ∈ xs → x ∈ xsfirst-occurrence x (here x≈y) = here x≈yfirst-occurrence x (there {x = y} x∈xs) with x ≟ y... | true because [x≈y] = here (invert [x≈y])... | false because _ = there $ first-occurrence x x∈xs-- The index of the first occurrence of x in xs.first-index : ∀ {xs} x → x ∈ xs → Fin (length xs)first-index x x∈xs = Any.index $ first-occurrence x x∈xs-- first-index preserves equality of its first argument.first-index-cong : ∀ {x₁ x₂ xs} (x₁∈xs : x₁ ∈ xs) (x₂∈xs : x₂ ∈ xs) →x₁ ≈ x₂ → first-index x₁ x₁∈xs ≡ first-index x₂ x₂∈xsfirst-index-cong {x₁} {x₂} x₁∈xs x₂∈xs x₁≈x₂ = helper x₁∈xs x₂∈xswherehelper : ∀ {xs} (x₁∈xs : x₁ ∈ xs) (x₂∈xs : x₂ ∈ xs) →first-index x₁ x₁∈xs ≡ first-index x₂ x₂∈xshelper (here x₁≈x) (here x₂≈x) = reflhelper (here x₁≈x) (there {x = x} x₂∈xs)with x₂ ≟ x | dec-true (x₂ ≟ x) (trans (sym x₁≈x₂) x₁≈x)... | _ | refl = reflhelper (there {x = x} x₁∈xs) (here x₂≈x)with x₁ ≟ x | dec-true (x₁ ≟ x) (trans x₁≈x₂ x₂≈x)... | _ | refl = reflhelper (there {x = x} x₁∈xs) (there x₂∈xs) with x₁ ≟ x | x₂ ≟ x... | true because _ | true because _ = refl... | false because _ | false because _ = cong suc $ helper x₁∈xs x₂∈xs... | yes x₁≈x | no x₂≉x = ⊥-elim (x₂≉x (trans (sym x₁≈x₂) x₁≈x))... | no x₁≉x | yes x₂≈x = ⊥-elim (x₁≉x (trans x₁≈x₂ x₂≈x))-- first-index is injective in its first argument.first-index-injective: ∀ {x₁ x₂ xs} (x₁∈xs : x₁ ∈ xs) (x₂∈xs : x₂ ∈ xs) →first-index x₁ x₁∈xs ≡ first-index x₂ x₂∈xs → x₁ ≈ x₂first-index-injective {x₁} {x₂} = helperwherehelper : ∀ {xs} (x₁∈xs : x₁ ∈ xs) (x₂∈xs : x₂ ∈ xs) →first-index x₁ x₁∈xs ≡ first-index x₂ x₂∈xs → x₁ ≈ x₂helper (here x₁≈x) (here x₂≈x) _ = trans x₁≈x (sym x₂≈x)helper (here x₁≈x) (there {x = x} x₂∈xs) _ with x₂ ≟ xhelper (here x₁≈x) (there {x = x} x₂∈xs) _ | yes x₂≈x = trans x₁≈x (sym x₂≈x)helper (here x₁≈x) (there {x = x} x₂∈xs) () | no x₂≉xhelper (there {x = x} x₁∈xs) (here x₂≈x) _ with x₁ ≟ xhelper (there {x = x} x₁∈xs) (here x₂≈x) _ | yes x₁≈x = trans x₁≈x (sym x₂≈x)helper (there {x = x} x₁∈xs) (here x₂≈x) () | no x₁≉xhelper (there {x = x} x₁∈xs) (there x₂∈xs) _ with x₁ ≟ x | x₂ ≟ xhelper (there {x = x} x₁∈xs) (there x₂∈xs) _ | yes x₁≈x | yes x₂≈x = trans x₁≈x (sym x₂≈x)helper (there {x = x} x₁∈xs) (there x₂∈xs) () | yes x₁≈x | no x₂≉xhelper (there {x = x} x₁∈xs) (there x₂∈xs) () | no x₁≉x | yes x₂≈xhelper (there {x = x} x₁∈xs) (there x₂∈xs) eq | no x₁≉x | no x₂≉x =helper x₁∈xs x₂∈xs (suc-injective eq)-------------------------------------------------------------------------- The countdown data structure-- If counted ⊕ n is inhabited then there are at most n values of type-- Elem which are not members of counted (up to _≈_). You can read the-- symbol _⊕_ as partitioning Elem into two parts: counted and-- uncounted.infix 4 _⊕_record _⊕_ (counted : List Elem) (n : ℕ) : Set wherefield-- An element can be of two kinds:-- ⑴ It is provably in counted.-- ⑵ It is one of at most n elements which may or may not be in-- counted. The "at most n" part is guaranteed by the field-- "injective".kind : ∀ x → x ∈ counted ⊎ Fin ninjective : ∀ {x y i} → kind x ≡ inj₂ i → kind y ≡ inj₂ i → x ≈ y-- A countdown can be initialised by proving that Elem is finite.empty : ∀ {n} → Injection D.setoid (≡.setoid (Fin n)) → [] ⊕ nempty inj =record { kind = inj₂ ∘ to; injective = λ {x} {y} {i} eq₁ eq₂ → injective (beginto x ≡⟨ inj₂-injective eq₁ ⟩i ≡⟨ ≡.sym $ inj₂-injective eq₂ ⟩to y ∎)}where open Injection inj-- A countdown can also be initialised by proving that Elem is finite.emptyFromList : (counted : List Elem) → (∀ x → x ∈ counted) →[] ⊕ length countedemptyFromList counted complete = empty record{ to = λ x → first-index x (complete x); cong = first-index-cong (complete _) (complete _); injective = first-index-injective (complete _) (complete _)}-- Finds out if an element has been counted yet.lookup : ∀ {counted n} → counted ⊕ n → ∀ x → Dec (x ∈ counted)lookup {counted} _ x = Any.any? (_≟_ x) counted-- When no element remains to be counted all elements have been-- counted.lookup! : ∀ {counted} → counted ⊕ zero → ∀ x → x ∈ countedlookup! counted⊕0 x with _⊕_.kind counted⊕0 x... | inj₁ x∈counted = x∈counted... | inj₂ ()private-- A variant of lookup!.lookup‼ : ∀ {m counted} →counted ⊕ m → ∀ x → x ∉ counted → ∃ λ n → m ≡ suc nlookup‼ {suc m} counted⊕n x x∉counted = (m , refl)lookup‼ {zero} counted⊕n x x∉counted =⊥-elim (x∉counted $ lookup! counted⊕n x)-- Counts a previously uncounted element.insert : ∀ {counted n} →counted ⊕ suc n → ∀ x → x ∉ counted → x ∷ counted ⊕ ninsert {counted} {n} counted⊕1+n x x∉counted =record { kind = kind′; injective = inj }whereopen _⊕_ counted⊕1+nhelper : ∀ x y i {j} →kind x ≡ inj₂ i → kind y ≡ inj₂ j → i ≡ j → x ≈ yhelper _ _ _ eq₁ eq₂ refl = injective eq₁ eq₂kind′ : ∀ y → y ∈ x ∷ counted ⊎ Fin nkind′ y with y ≟ x | kind x | kind y | helper x ykind′ y | yes y≈x | _ | _ | _ = inj₁ (here y≈x)kind′ y | _ | inj₁ x∈counted | _ | _ = ⊥-elim (x∉counted x∈counted)kind′ y | _ | _ | inj₁ y∈counted | _ = inj₁ (there y∈counted)kind′ y | no y≉x | inj₂ i | inj₂ j | hlp =inj₂ (punchOut (y≉x ∘ sym ∘ hlp _ refl refl))inj : ∀ {y z i} → kind′ y ≡ inj₂ i → kind′ z ≡ inj₂ i → y ≈ zinj {y} {z} eq₁ eq₂ with y ≟ x | z ≟ x | kind x | kind y | kind z| helper x y | helper x z | helper y zinj () _ | yes _ | _ | _ | _ | _ | _ | _ | _inj _ () | _ | yes _ | _ | _ | _ | _ | _ | _inj _ _ | no _ | no _ | inj₁ x∈counted | _ | _ | _ | _ | _ = ⊥-elim (x∉counted x∈counted)inj () _ | no _ | no _ | inj₂ _ | inj₁ _ | _ | _ | _ | _inj _ () | no _ | no _ | inj₂ _ | _ | inj₁ _ | _ | _ | _inj eq₁ eq₂ | no _ | no _ | inj₂ i | inj₂ _ | inj₂ _ | _ | _ | hlp =hlp _ refl refl $punchOut-injective {i = i} _ _ $(≡.trans (inj₂-injective eq₁) (≡.sym (inj₂-injective eq₂)))-- Counts an element if it has not already been counted.lookupOrInsert : ∀ {counted m} →counted ⊕ m →∀ x → x ∈ counted ⊎∃ λ n → m ≡ suc n × x ∷ counted ⊕ nlookupOrInsert counted⊕n x with lookup counted⊕n x... | yes x∈counted = inj₁ x∈counted... | no x∉counted with lookup‼ counted⊕n x x∉counted... | (n , refl) = inj₂ (n , refl , insert counted⊕n x x∉counted)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.List.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Categorical whereopen import Data.List.Effectful public{-# WARNING_ON_IMPORT"Data.List.Categorical was deprecated in v2.0.Use Data.List.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Data.List.Effectful.Transformer` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Categorical.Transformer whereopen import Data.List.Effectful.Transformer public{-# WARNING_ON_IMPORT"Data.List.Categorical.Transformer was deprecated in v2.0.Use Data.List.Effectful.Transformer instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Lists, basic types and operations-------------------------------------------------------------------------- See README.Data.List for examples of how to use and reason about-- lists.{-# OPTIONS --cubical-compatible --safe #-}module Data.List.Base whereopen import Algebra.Bundles.Raw using (RawMagma; RawMonoid)open import Data.Bool.Base as Boolusing (Bool; false; true; not; _∧_; _∨_; if_then_else_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Maybe.Base as Maybe using (Maybe; nothing; just; maybe′)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _+_; _*_ ; _≤_ ; s≤s)open import Data.Product.Base as Product using (_×_; _,_; map₁; map₂′)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Data.These.Base as These using (These; this; that; these)open import Function.Baseusing (id; _∘_ ; _∘′_; _∘₂_; _$_; const; flip)open import Level using (Level)open import Relation.Unary using (Pred; Decidable)open import Relation.Binary.Core using (Rel)import Relation.Binary.Definitions as Bopen import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Relation.Nullary.Decidable.Core using (T?; does; ¬?)privatevariablea b c p ℓ : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Typesopen import Agda.Builtin.List publicusing (List; []; _∷_)-------------------------------------------------------------------------- Operations for transforming listsmap : (A → B) → List A → List Bmap f [] = []map f (x ∷ xs) = f x ∷ map f xsinfixr 5 _++__++_ : List A → List A → List A[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ (xs ++ ys)intersperse : A → List A → List Aintersperse x [] = []intersperse x (y ∷ []) = y ∷ []intersperse x (y ∷ ys) = y ∷ x ∷ intersperse x ysintercalate : List A → List (List A) → List Aintercalate xs [] = []intercalate xs (ys ∷ []) = ysintercalate xs (ys ∷ yss) = ys ++ xs ++ intercalate xs ysscartesianProductWith : (A → B → C) → List A → List B → List CcartesianProductWith f [] _ = []cartesianProductWith f (x ∷ xs) ys = map (f x) ys ++ cartesianProductWith f xs yscartesianProduct : List A → List B → List (A × B)cartesianProduct = cartesianProductWith _,_-------------------------------------------------------------------------- Aligning and zippingalignWith : (These A B → C) → List A → List B → List CalignWith f [] bs = map (f ∘′ that) bsalignWith f as [] = map (f ∘′ this) asalignWith f (a ∷ as) (b ∷ bs) = f (these a b) ∷ alignWith f as bszipWith : (A → B → C) → List A → List B → List CzipWith f (x ∷ xs) (y ∷ ys) = f x y ∷ zipWith f xs yszipWith f _ _ = []unalignWith : (A → These B C) → List A → List B × List CunalignWith f [] = [] , []unalignWith f (a ∷ as) with f a... | this b = Product.map₁ (b ∷_) (unalignWith f as)... | that c = Product.map₂ (c ∷_) (unalignWith f as)... | these b c = Product.map (b ∷_) (c ∷_) (unalignWith f as)unzipWith : (A → B × C) → List A → List B × List CunzipWith f [] = [] , []unzipWith f (xy ∷ xys) = Product.zip _∷_ _∷_ (f xy) (unzipWith f xys)partitionSumsWith : (A → B ⊎ C) → List A → List B × List CpartitionSumsWith f = unalignWith (These.fromSum ∘′ f)align : List A → List B → List (These A B)align = alignWith idzip : List A → List B → List (A × B)zip = zipWith (_,_)unalign : List (These A B) → List A × List Bunalign = unalignWith idunzip : List (A × B) → List A × List Bunzip = unzipWith idpartitionSums : List (A ⊎ B) → List A × List BpartitionSums = partitionSumsWith idmerge : {R : Rel A ℓ} → B.Decidable R → List A → List A → List Amerge R? [] ys = ysmerge R? xs [] = xsmerge R? x∷xs@(x ∷ xs) y∷ys@(y ∷ ys) = if does (R? x y)then x ∷ merge R? xs y∷yselse y ∷ merge R? x∷xs ys-------------------------------------------------------------------------- Operations for reducing listsfoldr : (A → B → B) → B → List A → Bfoldr c n [] = nfoldr c n (x ∷ xs) = c x (foldr c n xs)foldl : (A → B → A) → A → List B → Afoldl c n [] = nfoldl c n (x ∷ xs) = foldl c (c n x) xsconcat : List (List A) → List Aconcat = foldr _++_ []concatMap : (A → List B) → List A → List BconcatMap f = concat ∘ map fap : List (A → B) → List A → List Bap fs as = concatMap (flip map as) fscatMaybes : List (Maybe A) → List AcatMaybes = foldr (maybe′ _∷_ id) []mapMaybe : (A → Maybe B) → List A → List BmapMaybe p = catMaybes ∘ map pnull : List A → Boolnull [] = truenull (x ∷ xs) = falseand : List Bool → Booland = foldr _∧_ trueor : List Bool → Boolor = foldr _∨_ falseany : (A → Bool) → List A → Boolany p = or ∘ map pall : (A → Bool) → List A → Boolall p = and ∘ map psum : List ℕ → ℕsum = foldr _+_ 0product : List ℕ → ℕproduct = foldr _*_ 1length : List A → ℕlength = foldr (const suc) 0-------------------------------------------------------------------------- Operations for constructing lists[_] : A → List A[ x ] = x ∷ []fromMaybe : Maybe A → List AfromMaybe (just x) = [ x ]fromMaybe nothing = []replicate : ℕ → A → List Areplicate zero x = []replicate (suc n) x = x ∷ replicate n xiterate : (A → A) → A → ℕ → List Aiterate f e zero = []iterate f e (suc n) = e ∷ iterate f (f e) ninits : List A → List (List A)inits {A = A} = λ xs → [] ∷ tail xsmodule Inits wheretail : List A → List (List A)tail [] = []tail (x ∷ xs) = [ x ] ∷ map (x ∷_) (tail xs)tails : List A → List (List A)tails {A = A} = λ xs → xs ∷ tail xsmodule Tails wheretail : List A → List (List A)tail [] = []tail (_ ∷ xs) = xs ∷ tail xsinsertAt : (xs : List A) → Fin (suc (length xs)) → A → List AinsertAt xs zero v = v ∷ xsinsertAt (x ∷ xs) (suc i) v = x ∷ insertAt xs i vupdateAt : (xs : List A) → Fin (length xs) → (A → A) → List AupdateAt (x ∷ xs) zero f = f x ∷ xsupdateAt (x ∷ xs) (suc i) f = x ∷ updateAt xs i f-- TabulationapplyUpTo : (ℕ → A) → ℕ → List AapplyUpTo f zero = []applyUpTo f (suc n) = f zero ∷ applyUpTo (f ∘ suc) napplyDownFrom : (ℕ → A) → ℕ → List AapplyDownFrom f zero = []applyDownFrom f (suc n) = f n ∷ applyDownFrom f ntabulate : ∀ {n} (f : Fin n → A) → List Atabulate {n = zero} f = []tabulate {n = suc n} f = f zero ∷ tabulate (f ∘ suc)lookup : ∀ (xs : List A) → Fin (length xs) → Alookup (x ∷ xs) zero = xlookup (x ∷ xs) (suc i) = lookup xs i-- NumericalupTo : ℕ → List ℕupTo = applyUpTo iddownFrom : ℕ → List ℕdownFrom = applyDownFrom idallFin : ∀ n → List (Fin n)allFin n = tabulate idunfold : ∀ (P : ℕ → Set b)(f : ∀ {n} → P (suc n) → Maybe (A × P n)) →∀ {n} → P n → List Aunfold P f {n = zero} s = []unfold P f {n = suc n} s = maybe′ (λ (x , s′) → x ∷ unfold P f s′) [] (f s)-------------------------------------------------------------------------- Operations for reversing listsreverseAcc : List A → List A → List AreverseAcc = foldl (flip _∷_)reverse : List A → List Areverse = reverseAcc []-- "Reverse append" xs ʳ++ ys = reverse xs ++ ysinfixr 5 _ʳ++__ʳ++_ : List A → List A → List A_ʳ++_ = flip reverseAcc-- Snoc: Cons, but from the right.infixl 6 _∷ʳ__∷ʳ_ : List A → A → List Axs ∷ʳ x = xs ++ [ x ]-- Backwards initialisationinfixl 5 _∷ʳ′_data InitLast {A : Set a} : List A → Set a where[] : InitLast []_∷ʳ′_ : (xs : List A) (x : A) → InitLast (xs ∷ʳ x)initLast : (xs : List A) → InitLast xsinitLast [] = []initLast (x ∷ xs) with initLast xs... | [] = [] ∷ʳ′ x... | ys ∷ʳ′ y = (x ∷ ys) ∷ʳ′ y-- uncons, but from the rightunsnoc : List A → Maybe (List A × A)unsnoc as with initLast as... | [] = nothing... | xs ∷ʳ′ x = just (xs , x)-------------------------------------------------------------------------- Operations for deconstructing lists-- Note that although the following three combinators can be useful for-- programming, when proving it is often a better idea to manually-- destruct a list argument as each branch of the pattern-matching will-- have a refined type.uncons : List A → Maybe (A × List A)uncons [] = nothinguncons (x ∷ xs) = just (x , xs)head : List A → Maybe Ahead [] = nothinghead (x ∷ _) = just xtail : List A → Maybe (List A)tail [] = nothingtail (_ ∷ xs) = just xslast : List A → Maybe Alast [] = nothinglast (x ∷ []) = just xlast (_ ∷ xs) = last xstake : ℕ → List A → List Atake zero xs = []take (suc n) [] = []take (suc n) (x ∷ xs) = x ∷ take n xsdrop : ℕ → List A → List Adrop zero xs = xsdrop (suc n) [] = []drop (suc n) (x ∷ xs) = drop n xssplitAt : ℕ → List A → List A × List AsplitAt zero xs = ([] , xs)splitAt (suc n) [] = ([] , [])splitAt (suc n) (x ∷ xs) = Product.map₁ (x ∷_) (splitAt n xs)removeAt : (xs : List A) → Fin (length xs) → List AremoveAt (x ∷ xs) zero = xsremoveAt (x ∷ xs) (suc i) = x ∷ removeAt xs i-------------------------------------------------------------------------- Operations for filtering lists-- The following are a variety of functions that can be used to-- construct sublists using a predicate.---- Each function has two forms. The first main variant uses a-- proof-relevant decidable predicate, while the second variant uses-- a irrelevant boolean predicate and are suffixed with a `ᵇ` character,-- typed as \^b.---- The decidable versions have several advantages: 1) easier to prove-- properties, 2) better meta-variable inference and 3) most of the rest-- of the library is set-up to work with decidable predicates. However,-- in rare cases the boolean versions can be useful, mainly when one-- wants to minimise dependencies.---- In summary, in most cases you probably want to use the decidable-- versions over the boolean versions, e.g. use `takeWhile (_≤? 10) xs`-- rather than `takeWhileᵇ (_≤ᵇ 10) xs`.takeWhile : ∀ {P : Pred A p} → Decidable P → List A → List AtakeWhile P? [] = []takeWhile P? (x ∷ xs) with does (P? x)... | true = x ∷ takeWhile P? xs... | false = []takeWhileᵇ : (A → Bool) → List A → List AtakeWhileᵇ p = takeWhile (T? ∘ p)dropWhile : ∀ {P : Pred A p} → Decidable P → List A → List AdropWhile P? [] = []dropWhile P? (x ∷ xs) with does (P? x)... | true = dropWhile P? xs... | false = x ∷ xsdropWhileᵇ : (A → Bool) → List A → List AdropWhileᵇ p = dropWhile (T? ∘ p)filter : ∀ {P : Pred A p} → Decidable P → List A → List Afilter P? [] = []filter P? (x ∷ xs) with does (P? x)... | false = filter P? xs... | true = x ∷ filter P? xsfilterᵇ : (A → Bool) → List A → List Afilterᵇ p = filter (T? ∘ p)partition : ∀ {P : Pred A p} → Decidable P → List A → (List A × List A)partition P? [] = ([] , [])partition P? (x ∷ xs) with does (P? x) | partition P? xs... | true | (ys , zs) = (x ∷ ys , zs)... | false | (ys , zs) = (ys , x ∷ zs)partitionᵇ : (A → Bool) → List A → List A × List Apartitionᵇ p = partition (T? ∘ p)span : ∀ {P : Pred A p} → Decidable P → List A → (List A × List A)span P? [] = ([] , [])span P? ys@(x ∷ xs) with does (P? x)... | true = Product.map (x ∷_) id (span P? xs)... | false = ([] , ys)spanᵇ : (A → Bool) → List A → List A × List Aspanᵇ p = span (T? ∘ p)break : ∀ {P : Pred A p} → Decidable P → List A → (List A × List A)break P? = span (¬? ∘ P?)breakᵇ : (A → Bool) → List A → List A × List Abreakᵇ p = break (T? ∘ p)-- The predicate `P` represents the notion of newline character for the-- type `A`. It is used to split the input list into a list of lines.-- Some lines may be empty if the input contains at least two-- consecutive newline characters.linesBy : ∀ {P : Pred A p} → Decidable P → List A → List (List A)linesBy {A = A} P? = go nothing wherego : Maybe (List A) → List A → List (List A)go acc [] = maybe′ ([_] ∘′ reverse) [] accgo acc (c ∷ cs) = if does (P? c)then reverse acc′ ∷ go nothing cselse go (just (c ∷ acc′)) cswhere acc′ = Maybe.fromMaybe [] acclinesByᵇ : (A → Bool) → List A → List (List A)linesByᵇ p = linesBy (T? ∘ p)-- The predicate `P` represents the notion of space character for the-- type `A`. It is used to split the input list into a list of words.-- All the words are non empty and the output does not contain any space-- characters.wordsBy : ∀ {P : Pred A p} → Decidable P → List A → List (List A)wordsBy {A = A} P? = go [] wherecons : List A → List (List A) → List (List A)cons [] ass = asscons as ass = reverse as ∷ assgo : List A → List A → List (List A)go acc [] = cons acc []go acc (c ∷ cs) = if does (P? c)then cons acc (go [] cs)else go (c ∷ acc) cswordsByᵇ : (A → Bool) → List A → List (List A)wordsByᵇ p = wordsBy (T? ∘ p)derun : ∀ {R : Rel A p} → B.Decidable R → List A → List Aderun R? [] = []derun R? (x ∷ []) = x ∷ []derun R? (x ∷ xs@(y ∷ _)) with does (R? x y) | derun R? xs... | true | ys = ys... | false | ys = x ∷ ysderunᵇ : (A → A → Bool) → List A → List Aderunᵇ r = derun (T? ∘₂ r)deduplicate : ∀ {R : Rel A p} → B.Decidable R → List A → List Adeduplicate R? [] = []deduplicate R? (x ∷ xs) = x ∷ filter (¬? ∘ R? x) (deduplicate R? xs)deduplicateᵇ : (A → A → Bool) → List A → List Adeduplicateᵇ r = deduplicate (T? ∘₂ r)-- Finds the first element satisfying the boolean predicatefind : ∀ {P : Pred A p} → Decidable P → List A → Maybe Afind P? [] = nothingfind P? (x ∷ xs) = if does (P? x) then just x else find P? xsfindᵇ : (A → Bool) → List A → Maybe Afindᵇ p = find (T? ∘ p)-- Finds the index of the first element satisfying the boolean predicatefindIndex : ∀ {P : Pred A p} → Decidable P → (xs : List A) → Maybe $ Fin (length xs)findIndex P? [] = nothingfindIndex P? (x ∷ xs) = if does (P? x)then just zeroelse Maybe.map suc (findIndex P? xs)findIndexᵇ : (A → Bool) → (xs : List A) → Maybe $ Fin (length xs)findIndexᵇ p = findIndex (T? ∘ p)-- Finds indices of all the elements satisfying the boolean predicatefindIndices : ∀ {P : Pred A p} → Decidable P → (xs : List A) → List $ Fin (length xs)findIndices P? [] = []findIndices P? (x ∷ xs) = if does (P? x)then zero ∷ indiceselse indiceswhere indices = map suc (findIndices P? xs)findIndicesᵇ : (A → Bool) → (xs : List A) → List $ Fin (length xs)findIndicesᵇ p = findIndices (T? ∘ p)-------------------------------------------------------------------------- Actions on single elementsinfixl 5 _[_]%=_ _[_]∷=_-- xs [ i ]%= f modifies the i-th element of xs according to f_[_]%=_ : (xs : List A) → Fin (length xs) → (A → A) → List Axs [ i ]%= f = updateAt xs i f-- xs [ i ]≔ y overwrites the i-th element of xs with y_[_]∷=_ : (xs : List A) → Fin (length xs) → A → List Axs [ k ]∷= v = xs [ k ]%= const v-------------------------------------------------------------------------- Conditional versions of cons and snocinfixr 5 _?∷__?∷_ : Maybe A → List A → List A_?∷_ = maybe′ _∷_ idinfixl 6 _∷ʳ?__∷ʳ?_ : List A → Maybe A → List Axs ∷ʳ? x = maybe′ (xs ∷ʳ_) xs x-------------------------------------------------------------------------- Raw algebraic bundlesmodule _ (A : Set a) where++-rawMagma : RawMagma a _++-rawMagma = record{ Carrier = List A; _≈_ = _≡_; _∙_ = _++_}++-[]-rawMonoid : RawMonoid a _++-[]-rawMonoid = record{ Carrier = List A; _≈_ = _≡_; _∙_ = _++_; ε = []}-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4infixl 5 _∷ʳ'__∷ʳ'_ : (xs : List A) (x : A) → InitLast (xs ∷ʳ x)_∷ʳ'_ = InitLast._∷ʳ′_{-# WARNING_ON_USAGE _∷ʳ'_"Warning: _∷ʳ'_ (ending in an apostrophe) was deprecated in v1.4.Please use _∷ʳ′_ (ending in a prime) instead."#-}-- Version 2.0infixl 5 _─__─_ = removeAt{-# WARNING_ON_USAGE _─_"Warning: _─_ was deprecated in v2.0.Please use removeAt instead."#-}-- Version 2.1scanr : (A → B → B) → B → List A → List Bscanr f e [] = e ∷ []scanr f e (x ∷ xs) with scanr f e xs... | [] = [] -- dead branch... | ys@(y ∷ _) = f x y ∷ ys{-# WARNING_ON_USAGE scanr"Warning: scanr was deprecated in v2.1.Please use Data.List.Scans.Base.scanr instead."#-}scanl : (A → B → A) → A → List B → List Ascanl f e [] = e ∷ []scanl f e (x ∷ xs) = e ∷ scanl f (f e x) xs{-# WARNING_ON_USAGE scanl"Warning: scanl was deprecated in v2.1.Please use Data.List.Scans.Base.scanl instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Wrapper for the proof irrelevance modality---- This allows us to store proof irrelevant witnesses in a record and-- use projections to manipulate them without having to turn on the-- unsafe option --irrelevant-projections.-- Cf. Data.Refinement for a use case------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Irrelevant whereopen import Level using (Level)privatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Typerecord Irrelevant (A : Set a) : Set a whereconstructor [_]field .irrelevant : Aopen Irrelevant public-------------------------------------------------------------------------- Algebraic structure: Functor, Appplicative and Monad-likemap : (A → B) → Irrelevant A → Irrelevant Bmap f [ a ] = [ f a ]pure : A → Irrelevant Apure x = [ x ]infixl 4 _<*>__<*>_ : Irrelevant (A → B) → Irrelevant A → Irrelevant B[ f ] <*> [ a ] = [ f a ]infixl 1 _>>=__>>=_ : Irrelevant A → (.A → Irrelevant B) → Irrelevant B[ a ] >>= f = f a-------------------------------------------------------------------------- Other functionszipWith : (A → B → C) → Irrelevant A → Irrelevant B → Irrelevant CzipWith f a b = ⦇ f a b ⦈
-------------------------------------------------------------------------- The Agda standard library---- Integers-------------------------------------------------------------------------- See README.Data.Integer for examples of how to use and reason about-- integers.{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer where-------------------------------------------------------------------------- Re-export basic definition, operations and queriesopen import Data.Integer.Base publicopen import Data.Integer.Properties publicusing (_≟_; _≤?_; _<?_)-------------------------------------------------------------------------- Deprecated-- Version 0.17open import Data.Integer.Properties publicusing (◃-cong; drop‿+≤+; drop‿-≤-)renaming (◃-inverse to ◃-left-inverse)-- Version 1.5-- Showimport Data.Nat.Show as ℕ using (show)open import Data.Sign.Base as Sign using (Sign)open import Data.String.Base using (String; _++_)show : ℤ → Stringshow i = showSign (sign i) ++ ℕ.show ∣ i ∣whereshowSign : Sign → StringshowSign Sign.- = "-"showSign Sign.+ = ""{-# WARNING_ON_USAGE show"Warning: show was deprecated in v1.5.Please use Data.Integer.Show's show instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over integers-------------------------------------------------------------------------- See README.Tactic.RingSolver for examples of how to use this solver{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Tactic.RingSolver whereopen import Agda.Builtin.Reflectionopen import Data.Maybe.Base using (just; nothing)open import Data.Integer.Base using (+0)open import Data.Integer.Properties using (+-*-commutativeRing)open import Level using (0ℓ)open import Data.Unit.Base using (⊤)open import Relation.Binary.PropositionalEquality.Core using (refl)import Tactic.RingSolver as Solverimport Tactic.RingSolver.Core.AlmostCommutativeRing as ACR-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_ring : ACR.AlmostCommutativeRing 0ℓ 0ℓring = ACR.fromCommutativeRing +-*-commutativeRingλ { +0 → just refl; _ → nothing }macrosolve-∀ : Term → TC ⊤solve-∀ = Solver.solve-∀-macro (quote ring)macrosolve : Term → Term → TC ⊤solve n = Solver.solve-macro n (quote ring)
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over integers-------------------------------------------------------------------------- See README.Data.Integer for examples of how to use this solver{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Solver whereimport Algebra.Solver.Ring.Simple as Solverimport Algebra.Solver.Ring.AlmostCommutativeRing as ACRopen import Data.Integer.Properties using (_≟_; +-*-commutativeRing)-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _+_ and _*_module +-*-Solver =Solver (ACR.fromCommutativeRing +-*-commutativeRing) _≟_
-------------------------------------------------------------------------- The Agda standard library---- Showing integers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Show whereopen import Data.Integer.Base using (ℤ; +_; -[1+_])open import Data.Nat.Base using (suc)open import Data.Nat.Show using () renaming (show to showℕ)open import Data.String.Base using (String; _++_)-------------------------------------------------------------------------- Show-- Decimal notation-- Time complexity is O(log₁₀(n))show : ℤ → Stringshow (+ n) = showℕ nshow -[1+ n ] = "-" ++ showℕ (suc n)
-------------------------------------------------------------------------- The Agda standard library---- Some properties about integers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Properties whereopen import Algebra.Bundlesimport Algebra.Morphism as Morphismopen import Algebra.Construct.NaturalChoice.Baseimport Algebra.Construct.NaturalChoice.MinMaxOp as MinMaxOpimport Algebra.Lattice.Construct.NaturalChoice.MinMaxOp as LatticeMinMaxOpimport Algebra.Properties.AbelianGroupopen import Data.Bool.Base using (T; true; false)open import Data.Integer.Base renaming (suc to sucℤ)open import Data.Integer.Properties.NatLemmasopen import Data.Nat.Base as ℕusing (ℕ; suc; zero; _∸_; s≤s; z≤n; s<s; z<s; s≤s⁻¹; s<s⁻¹)hiding (module ℕ)import Data.Nat.Properties as ℕopen import Data.Product.Base using (proj₁; proj₂; _,_; _×_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Sign.Base as Sign using (Sign)import Data.Sign.Properties as Signopen import Function.Base using (_∘_; _$_; id)open import Level using (0ℓ)open import Relation.Binary.Core using (_⇒_; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.Bundles using(Setoid; DecSetoid; Preorder; TotalPreorder; Poset; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsPreorder; IsTotalPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Definitionsusing (DecidableEquality; Reflexive; Transitive; Antisymmetric; Total; Decidable; Irrelevant; Irreflexive; Asymmetric; LeftTrans; RightTrans; Trichotomous; tri≈; tri<; tri>)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; sym; _≢_; subst; resp₂; trans)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning; setoid; decSetoid; isEquivalence)open import Relation.Nullary.Decidable.Core using (yes; no)import Relation.Nullary.Reflects as Reflectsopen import Relation.Nullary.Negation.Core using (¬_; contradiction)import Relation.Nullary.Decidable as Decopen import Algebra.Definitions {A = ℤ} _≡_open import Algebra.Consequences.Propositionalopen import Algebra.Structures {A = ℤ} _≡_module ℤtoℕ = Morphism.Definitions ℤ ℕ _≡_module ℕtoℤ = Morphism.Definitions ℕ ℤ _≡_privatevariablem n o : ℕi j k : ℤs t : Sign-------------------------------------------------------------------------- Equality------------------------------------------------------------------------+-injective : + m ≡ + n → m ≡ n+-injective refl = refl-[1+-injective : -[1+ m ] ≡ -[1+ n ] → m ≡ n-[1+-injective refl = refl+[1+-injective : +[1+ m ] ≡ +[1+ n ] → m ≡ n+[1+-injective refl = reflinfix 4 _≟__≟_ : DecidableEquality ℤ+ m ≟ + n = Dec.map′ (cong (+_)) +-injective (m ℕ.≟ n)+ m ≟ -[1+ n ] = no λ()-[1+ m ] ≟ + n = no λ()-[1+ m ] ≟ -[1+ n ] = Dec.map′ (cong -[1+_]) -[1+-injective (m ℕ.≟ n)≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid ℤ≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- Properties of _≤_------------------------------------------------------------------------drop‿+≤+ : + m ≤ + n → m ℕ.≤ ndrop‿+≤+ (+≤+ m≤n) = m≤ndrop‿-≤- : -[1+ m ] ≤ -[1+ n ] → n ℕ.≤ mdrop‿-≤- (-≤- n≤m) = n≤m-------------------------------------------------------------------------- Relational properties≤-reflexive : _≡_ ⇒ _≤_≤-reflexive { -[1+ n ]} refl = -≤- ℕ.≤-refl≤-reflexive {+ n} refl = +≤+ ℕ.≤-refl≤-refl : Reflexive _≤_≤-refl = ≤-reflexive refl≤-trans : Transitive _≤_≤-trans -≤+ (+≤+ n≤m) = -≤+≤-trans (-≤- n≤m) -≤+ = -≤+≤-trans (-≤- n≤m) (-≤- k≤n) = -≤- (ℕ.≤-trans k≤n n≤m)≤-trans (+≤+ m≤n) (+≤+ n≤k) = +≤+ (ℕ.≤-trans m≤n n≤k)≤-antisym : Antisymmetric _≡_ _≤_≤-antisym (-≤- n≤m) (-≤- m≤n) = cong -[1+_] $ ℕ.≤-antisym m≤n n≤m≤-antisym (+≤+ m≤n) (+≤+ n≤m) = cong (+_) $ ℕ.≤-antisym m≤n n≤m≤-total : Total _≤_≤-total (-[1+ m ]) (-[1+ n ]) = Sum.map -≤- -≤- (ℕ.≤-total n m)≤-total (-[1+ m ]) (+ n ) = inj₁ -≤+≤-total (+ m ) (-[1+ n ]) = inj₂ -≤+≤-total (+ m ) (+ n ) = Sum.map +≤+ +≤+ (ℕ.≤-total m n)infix 4 _≤?__≤?_ : Decidable _≤_-[1+ m ] ≤? -[1+ n ] = Dec.map′ -≤- drop‿-≤- (n ℕ.≤? m)-[1+ m ] ≤? + n = yes -≤++ m ≤? -[1+ n ] = no λ ()+ m ≤? + n = Dec.map′ +≤+ drop‿+≤+ (m ℕ.≤? n)≤-irrelevant : Irrelevant _≤_≤-irrelevant -≤+ -≤+ = refl≤-irrelevant (-≤- n≤m₁) (-≤- n≤m₂) = cong -≤- (ℕ.≤-irrelevant n≤m₁ n≤m₂)≤-irrelevant (+≤+ n≤m₁) (+≤+ n≤m₂) = cong +≤+ (ℕ.≤-irrelevant n≤m₁ n≤m₂)-------------------------------------------------------------------------- Structures≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-isTotalPreorder = record{ isPreorder = ≤-isPreorder; total = ≤-total}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder = record{ isPreorder = ≤-isPreorder}≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder = record{ isTotalPreorder = ≤-isTotalPreorder}≤-poset : Poset 0ℓ 0ℓ 0ℓ≤-poset = record{ isPartialOrder = ≤-isPartialOrder}≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-totalOrder = record{ isTotalOrder = ≤-isTotalOrder}≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder = record{ isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Properties of _≤ᵇ_------------------------------------------------------------------------≤ᵇ⇒≤ : T (i ≤ᵇ j) → i ≤ j≤ᵇ⇒≤ {+ _} {+ _} i≤j = +≤+ (ℕ.≤ᵇ⇒≤ _ _ i≤j)≤ᵇ⇒≤ { -[1+ _ ]} {+ _} i≤j = -≤+≤ᵇ⇒≤ { -[1+ _ ]} { -[1+ _ ]} i≤j = -≤- (ℕ.≤ᵇ⇒≤ _ _ i≤j)≤⇒≤ᵇ : i ≤ j → T (i ≤ᵇ j)≤⇒≤ᵇ (-≤- n≤m) = ℕ.≤⇒≤ᵇ n≤m≤⇒≤ᵇ -≤+ = _≤⇒≤ᵇ (+≤+ m≤n) = ℕ.≤⇒≤ᵇ m≤n-------------------------------------------------------------------------- Properties _<_------------------------------------------------------------------------drop‿+<+ : + m < + n → m ℕ.< ndrop‿+<+ (+<+ m<n) = m<ndrop‿-<- : -[1+ m ] < -[1+ n ] → n ℕ.< mdrop‿-<- (-<- n<m) = n<m+≮0 : + n ≮ +0+≮0 (+<+ ())+≮- : + m ≮ -[1+ n ]+≮- ()-------------------------------------------------------------------------- Relationship between other operators<⇒≤ : _<_ ⇒ _≤_<⇒≤ (-<- i<j) = -≤- (ℕ.<⇒≤ i<j)<⇒≤ -<+ = -≤+<⇒≤ (+<+ i<j) = +≤+ (ℕ.<⇒≤ i<j)<⇒≢ : _<_ ⇒ _≢_<⇒≢ (-<- n<m) refl = ℕ.<⇒≢ n<m refl<⇒≢ (+<+ m<n) refl = ℕ.<⇒≢ m<n refl<⇒≱ : _<_ ⇒ _≱_<⇒≱ (-<- n<m) = ℕ.<⇒≱ n<m ∘ drop‿-≤-<⇒≱ (+<+ m<n) = ℕ.<⇒≱ m<n ∘ drop‿+≤+≤⇒≯ : _≤_ ⇒ _≯_≤⇒≯ (-≤- n≤m) (-<- n<m) = ℕ.≤⇒≯ n≤m n<m≤⇒≯ -≤+ = +≮-≤⇒≯ (+≤+ m≤n) (+<+ m<n) = ℕ.≤⇒≯ m≤n m<n≰⇒> : _≰_ ⇒ _>_≰⇒> {+ n} {+_ n₁} i≰j = +<+ (ℕ.≰⇒> (i≰j ∘ +≤+))≰⇒> {+ n} { -[1+_] n₁} i≰j = -<+≰⇒> { -[1+_] n} {+_ n₁} i≰j = contradiction -≤+ i≰j≰⇒> { -[1+_] n} { -[1+_] n₁} i≰j = -<- (ℕ.≰⇒> (i≰j ∘ -≤-))≮⇒≥ : _≮_ ⇒ _≥_≮⇒≥ {+ i} {+ j} i≮j = +≤+ (ℕ.≮⇒≥ (i≮j ∘ +<+))≮⇒≥ {+ i} { -[1+_] j} i≮j = -≤+≮⇒≥ { -[1+_] i} {+ j} i≮j = contradiction -<+ i≮j≮⇒≥ { -[1+_] i} { -[1+_] j} i≮j = -≤- (ℕ.≮⇒≥ (i≮j ∘ -<-))>⇒≰ : _>_ ⇒ _≰_>⇒≰ = <⇒≱≤∧≢⇒< : i ≤ j → i ≢ j → i < j≤∧≢⇒< (-≤- m≤n) i≢j = -<- (ℕ.≤∧≢⇒< m≤n (i≢j ∘ cong -[1+_] ∘ sym))≤∧≢⇒< -≤+ i≢j = -<+≤∧≢⇒< (+≤+ n≤m) i≢j = +<+ (ℕ.≤∧≢⇒< n≤m (i≢j ∘ cong (+_)))≤∧≮⇒≡ : i ≤ j → i ≮ j → i ≡ j≤∧≮⇒≡ i≤j i≮j = ≤-antisym i≤j (≮⇒≥ i≮j)-------------------------------------------------------------------------- Relational properties<-irrefl : Irreflexive _≡_ _<_<-irrefl { -[1+ n ]} refl = ℕ.<-irrefl refl ∘ drop‿-<-<-irrefl { +0} refl (+<+ ())<-irrefl { +[1+ n ]} refl = ℕ.<-irrefl refl ∘ drop‿+<+<-asym : Asymmetric _<_<-asym (-<- n<m) = ℕ.<-asym n<m ∘ drop‿-<-<-asym (+<+ m<n) = ℕ.<-asym m<n ∘ drop‿+<+≤-<-trans : LeftTrans _≤_ _<_≤-<-trans (-≤- n≤m) (-<- o<n) = -<- (ℕ.<-≤-trans o<n n≤m)≤-<-trans (-≤- n≤m) -<+ = -<+≤-<-trans -≤+ (+<+ m<o) = -<+≤-<-trans (+≤+ m≤n) (+<+ n<o) = +<+ (ℕ.≤-<-trans m≤n n<o)<-≤-trans : RightTrans _<_ _≤_<-≤-trans (-<- n<m) (-≤- o≤n) = -<- (ℕ.≤-<-trans o≤n n<m)<-≤-trans (-<- n<m) -≤+ = -<+<-≤-trans -<+ (+≤+ m≤n) = -<+<-≤-trans (+<+ m<n) (+≤+ n≤o) = +<+ (ℕ.<-≤-trans m<n n≤o)<-trans : Transitive _<_<-trans m<n n<p = ≤-<-trans (<⇒≤ m<n) n<p<-cmp : Trichotomous _≡_ _<_<-cmp +0 +0 = tri≈ +≮0 refl +≮0<-cmp +0 +[1+ n ] = tri< (+<+ z<s) (λ()) +≮0<-cmp +[1+ n ] +0 = tri> +≮0 (λ()) (+<+ z<s)<-cmp (+ m) -[1+ n ] = tri> +≮- (λ()) -<+<-cmp -[1+ m ] (+ n) = tri< -<+ (λ()) +≮-<-cmp -[1+ m ] -[1+ n ] with ℕ.<-cmp m n... | tri< m<n m≢n n≯m = tri> (n≯m ∘ drop‿-<-) (m≢n ∘ -[1+-injective) (-<- m<n)... | tri≈ m≮n m≡n n≯m = tri≈ (n≯m ∘ drop‿-<-) (cong -[1+_] m≡n) (m≮n ∘ drop‿-<-)... | tri> m≮n m≢n n>m = tri< (-<- n>m) (m≢n ∘ -[1+-injective) (m≮n ∘ drop‿-<-)<-cmp +[1+ m ] +[1+ n ] with ℕ.<-cmp m n... | tri< m<n m≢n n≯m = tri< (+<+ (s<s m<n)) (m≢n ∘ +[1+-injective) (n≯m ∘ s<s⁻¹ ∘ drop‿+<+)... | tri≈ m≮n m≡n n≯m = tri≈ (m≮n ∘ s<s⁻¹ ∘ drop‿+<+) (cong (+_ ∘ suc) m≡n) (n≯m ∘ s<s⁻¹ ∘ drop‿+<+)... | tri> m≮n m≢n n>m = tri> (m≮n ∘ s<s⁻¹ ∘ drop‿+<+) (m≢n ∘ +[1+-injective) (+<+ (s<s n>m))infix 4 _<?__<?_ : Decidable _<_-[1+ m ] <? -[1+ n ] = Dec.map′ -<- drop‿-<- (n ℕ.<? m)-[1+ m ] <? + n = yes -<++ m <? -[1+ n ] = no λ()+ m <? + n = Dec.map′ +<+ drop‿+<+ (m ℕ.<? n)<-irrelevant : Irrelevant _<_<-irrelevant (-<- n<m₁) (-<- n<m₂) = cong -<- (ℕ.<-irrelevant n<m₁ n<m₂)<-irrelevant -<+ -<+ = refl<-irrelevant (+<+ m<n₁) (+<+ m<n₂) = cong +<+ (ℕ.<-irrelevant m<n₁ m<n₂)-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = subst (_ <_) , subst (_< _)}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}-------------------------------------------------------------------------- Bundles<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}-------------------------------------------------------------------------- Other properties of _<_i≮i : i ≮ ii≮i = <-irrefl refl>-irrefl : Irreflexive _≡_ _>_>-irrefl = <-irrefl ∘ sym-------------------------------------------------------------------------- A specialised module for reasoning about the _≤_ and _<_ relations------------------------------------------------------------------------module ≤-Reasoning whereopen import Relation.Binary.Reasoning.Base.Triple≤-isPreorder<-asym<-trans(resp₂ _<_)<⇒≤<-≤-trans≤-<-transpublichiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)-------------------------------------------------------------------------- Properties of Positive/NonPositive/Negative/NonNegative and _≤_/_<_positive⁻¹ : ∀ i → .{{Positive i}} → i > 0ℤpositive⁻¹ +[1+ n ] = +<+ z<snegative⁻¹ : ∀ i → .{{Negative i}} → i < 0ℤnegative⁻¹ -[1+ n ] = -<+nonPositive⁻¹ : ∀ i → .{{NonPositive i}} → i ≤ 0ℤnonPositive⁻¹ +0 = +≤+ z≤nnonPositive⁻¹ -[1+ n ] = -≤+nonNegative⁻¹ : ∀ i → .{{NonNegative i}} → i ≥ 0ℤnonNegative⁻¹ (+ n) = +≤+ z≤nnegative<positive : ∀ i j → .{{Negative i}} → .{{Positive j}} → i < jnegative<positive i j = <-trans (negative⁻¹ i) (positive⁻¹ j)-------------------------------------------------------------------------- Properties of -_------------------------------------------------------------------------neg-involutive : ∀ i → - - i ≡ ineg-involutive -[1+ n ] = reflneg-involutive +0 = reflneg-involutive +[1+ n ] = reflneg-injective : - i ≡ - j → i ≡ jneg-injective {i} {j} -i≡-j = begini ≡⟨ neg-involutive i ⟨- - i ≡⟨ cong -_ -i≡-j ⟩- - j ≡⟨ neg-involutive j ⟩j ∎ where open ≡-Reasoningneg-≤-pos : ∀ {m n} → - (+ m) ≤ + nneg-≤-pos {zero} = +≤+ z≤nneg-≤-pos {suc m} = -≤+neg-mono-≤ : -_ Preserves _≤_ ⟶ _≥_neg-mono-≤ -≤+ = neg-≤-posneg-mono-≤ (-≤- n≤m) = +≤+ (s≤s n≤m)neg-mono-≤ (+≤+ z≤n) = neg-≤-posneg-mono-≤ (+≤+ (s≤s m≤n)) = -≤- m≤nneg-cancel-≤ : - i ≤ - j → i ≥ jneg-cancel-≤ { +[1+ m ]} { +[1+ n ]} (-≤- n≤m) = +≤+ (s≤s n≤m)neg-cancel-≤ { +[1+ m ]} { +0} -≤+ = +≤+ z≤nneg-cancel-≤ { +[1+ m ]} { -[1+ n ]} -≤+ = -≤+neg-cancel-≤ { +0} { +0} _ = +≤+ z≤nneg-cancel-≤ { +0} { -[1+ n ]} _ = -≤+neg-cancel-≤ { -[1+ m ]} { +0} (+≤+ ())neg-cancel-≤ { -[1+ m ]} { -[1+ n ]} (+≤+ (s≤s m≤n)) = -≤- m≤nneg-mono-< : -_ Preserves _<_ ⟶ _>_neg-mono-< { -[1+ _ ]} { -[1+ _ ]} (-<- n<m) = +<+ (s<s n<m)neg-mono-< { -[1+ _ ]} { +0} -<+ = +<+ z<sneg-mono-< { -[1+ _ ]} { +[1+ n ]} -<+ = -<+neg-mono-< { +0} { +[1+ n ]} (+<+ _) = -<+neg-mono-< { +[1+ m ]} { +[1+ n ]} (+<+ m<n) = -<- (s<s⁻¹ m<n)neg-cancel-< : - i < - j → i > jneg-cancel-< { +[1+ m ]} { +[1+ n ]} (-<- n<m) = +<+ (s<s n<m)neg-cancel-< { +[1+ m ]} { +0} -<+ = +<+ z<sneg-cancel-< { +[1+ m ]} { -[1+ n ]} -<+ = -<+neg-cancel-< { +0} { +0} (+<+ ())neg-cancel-< { +0} { -[1+ n ]} _ = -<+neg-cancel-< { -[1+ m ]} { +0} (+<+ ())neg-cancel-< { -[1+ m ]} { -[1+ n ]} (+<+ m<n) = -<- (s<s⁻¹ m<n)-------------------------------------------------------------------------- Properties of ∣_∣------------------------------------------------------------------------∣i∣≡0⇒i≡0 : ∣ i ∣ ≡ 0 → i ≡ + 0∣i∣≡0⇒i≡0 {+0} refl = refl∣-i∣≡∣i∣ : ∀ i → ∣ - i ∣ ≡ ∣ i ∣∣-i∣≡∣i∣ -[1+ n ] = refl∣-i∣≡∣i∣ +0 = refl∣-i∣≡∣i∣ +[1+ n ] = refl0≤i⇒+∣i∣≡i : 0ℤ ≤ i → + ∣ i ∣ ≡ i0≤i⇒+∣i∣≡i (+≤+ _) = refl+∣i∣≡i⇒0≤i : + ∣ i ∣ ≡ i → 0ℤ ≤ i+∣i∣≡i⇒0≤i {+ n} _ = +≤+ z≤n+∣i∣≡i⊎+∣i∣≡-i : ∀ i → + ∣ i ∣ ≡ i ⊎ + ∣ i ∣ ≡ - i+∣i∣≡i⊎+∣i∣≡-i (+ n) = inj₁ refl+∣i∣≡i⊎+∣i∣≡-i (-[1+ n ]) = inj₂ refl∣m⊝n∣≤m⊔n : ∀ m n → ∣ m ⊖ n ∣ ℕ.≤ m ℕ.⊔ n∣m⊝n∣≤m⊔n m n with m ℕ.<ᵇ n... | true = begin∣ - + (n ℕ.∸ m) ∣ ≡⟨ ∣-i∣≡∣i∣ (+ (n ℕ.∸ m)) ⟩∣ + (n ℕ.∸ m) ∣ ≡⟨⟩n ℕ.∸ m ≤⟨ ℕ.m∸n≤m n m ⟩n ≤⟨ ℕ.m≤n⊔m m n ⟩m ℕ.⊔ n ∎where open ℕ.≤-Reasoning... | false = begin∣ + (m ℕ.∸ n) ∣ ≡⟨⟩m ℕ.∸ n ≤⟨ ℕ.m∸n≤m m n ⟩m ≤⟨ ℕ.m≤m⊔n m n ⟩m ℕ.⊔ n ∎where open ℕ.≤-Reasoning∣i+j∣≤∣i∣+∣j∣ : ∀ i j → ∣ i + j ∣ ℕ.≤ ∣ i ∣ ℕ.+ ∣ j ∣∣i+j∣≤∣i∣+∣j∣ +[1+ m ] (+ n) = ℕ.≤-refl∣i+j∣≤∣i∣+∣j∣ +0 (+ n) = ℕ.≤-refl∣i+j∣≤∣i∣+∣j∣ +0 -[1+ n ] = ℕ.≤-refl∣i+j∣≤∣i∣+∣j∣ -[1+ m ] -[1+ n ] rewrite ℕ.+-suc (suc m) n = ℕ.≤-refl∣i+j∣≤∣i∣+∣j∣ +[1+ m ] -[1+ n ] = begin∣ suc m ⊖ suc n ∣ ≤⟨ ∣m⊝n∣≤m⊔n (suc m) (suc n) ⟩suc m ℕ.⊔ suc n ≤⟨ ℕ.m⊔n≤m+n (suc m) (suc n) ⟩suc m ℕ.+ suc n ∎where open ℕ.≤-Reasoning∣i+j∣≤∣i∣+∣j∣ -[1+ m ] (+ n) = begin∣ n ⊖ suc m ∣ ≤⟨ ∣m⊝n∣≤m⊔n n (suc m) ⟩n ℕ.⊔ suc m ≤⟨ ℕ.m⊔n≤m+n n (suc m) ⟩n ℕ.+ suc m ≡⟨ ℕ.+-comm n (suc m) ⟩suc m ℕ.+ n ∎where open ℕ.≤-Reasoning∣i-j∣≤∣i∣+∣j∣ : ∀ i j → ∣ i - j ∣ ℕ.≤ ∣ i ∣ ℕ.+ ∣ j ∣∣i-j∣≤∣i∣+∣j∣ i j = begin∣ i - j ∣ ≤⟨ ∣i+j∣≤∣i∣+∣j∣ i (- j) ⟩∣ i ∣ ℕ.+ ∣ - j ∣ ≡⟨ cong (∣ i ∣ ℕ.+_) (∣-i∣≡∣i∣ j) ⟩∣ i ∣ ℕ.+ ∣ j ∣ ∎where open ℕ.≤-Reasoning-------------------------------------------------------------------------- Properties of sign and _◃_◃-nonZero : ∀ s n .{{_ : ℕ.NonZero n}} → NonZero (s ◃ n)◃-nonZero Sign.- (ℕ.suc _) = _◃-nonZero Sign.+ (ℕ.suc _) = _◃-inverse : ∀ i → sign i ◃ ∣ i ∣ ≡ i◃-inverse -[1+ n ] = refl◃-inverse +0 = refl◃-inverse +[1+ n ] = refl◃-cong : sign i ≡ sign j → ∣ i ∣ ≡ ∣ j ∣ → i ≡ j◃-cong {+ m} {+ n } ≡-sign refl = refl◃-cong { -[1+ m ]} { -[1+ n ]} ≡-sign refl = refl+◃n≡+n : ∀ n → Sign.+ ◃ n ≡ + n+◃n≡+n zero = refl+◃n≡+n (suc _) = refl-◃n≡-n : ∀ n → Sign.- ◃ n ≡ - + n-◃n≡-n zero = refl-◃n≡-n (suc _) = reflsign-◃ : ∀ s n .{{_ : ℕ.NonZero n}} → sign (s ◃ n) ≡ ssign-◃ Sign.- (suc _) = reflsign-◃ Sign.+ (suc _) = reflabs-◃ : ∀ s n → ∣ s ◃ n ∣ ≡ nabs-◃ _ zero = reflabs-◃ Sign.- (suc n) = reflabs-◃ Sign.+ (suc n) = reflsignᵢ◃∣i∣≡i : ∀ i → sign i ◃ ∣ i ∣ ≡ isignᵢ◃∣i∣≡i (+ n) = +◃n≡+n nsignᵢ◃∣i∣≡i -[1+ n ] = reflsign-cong : .{{_ : ℕ.NonZero m}} .{{_ : ℕ.NonZero n}} →s ◃ m ≡ t ◃ n → s ≡ tsign-cong {n@(suc _)} {m@(suc _)} {s} {t} eq = begins ≡⟨ sign-◃ s n ⟨sign (s ◃ n) ≡⟨ cong sign eq ⟩sign (t ◃ m) ≡⟨ sign-◃ t m ⟩t ∎ where open ≡-Reasoningsign-cong′ : s ◃ m ≡ t ◃ n → s ≡ t ⊎ (m ≡ 0 × n ≡ 0)sign-cong′ {s} {zero} {t} {zero} eq = inj₂ (refl , refl)sign-cong′ {s} {zero} {Sign.- } {suc n} ()sign-cong′ {s} {zero} {Sign.+ } {suc n} ()sign-cong′ {Sign.- } {suc m} {t} {zero} ()sign-cong′ {Sign.+ } {suc m} {t} {zero} ()sign-cong′ {s} {suc m} {t} {suc n} eq = inj₁ (sign-cong eq)abs-cong : s ◃ m ≡ t ◃ n → m ≡ nabs-cong {s} {m} {t} {n} eq = beginm ≡⟨ abs-◃ s m ⟨∣ s ◃ m ∣ ≡⟨ cong ∣_∣ eq ⟩∣ t ◃ n ∣ ≡⟨ abs-◃ t n ⟩n ∎ where open ≡-Reasoning∣s◃m∣*∣t◃n∣≡m*n : ∀ s t m n → ∣ s ◃ m ∣ ℕ.* ∣ t ◃ n ∣ ≡ m ℕ.* n∣s◃m∣*∣t◃n∣≡m*n s t m n = cong₂ ℕ._*_ (abs-◃ s m) (abs-◃ t n)+◃-mono-< : m ℕ.< n → Sign.+ ◃ m < Sign.+ ◃ n+◃-mono-< {zero} {suc n} m<n = +<+ m<n+◃-mono-< {suc m} {suc n} m<n = +<+ m<n+◃-cancel-< : Sign.+ ◃ m < Sign.+ ◃ n → m ℕ.< n+◃-cancel-< {zero} {zero} (+<+ ())+◃-cancel-< {suc m} {zero} (+<+ ())+◃-cancel-< {zero} {suc n} (+<+ m<n) = m<n+◃-cancel-< {suc m} {suc n} (+<+ m<n) = m<nneg◃-cancel-< : Sign.- ◃ m < Sign.- ◃ n → n ℕ.< mneg◃-cancel-< {zero} {zero} (+<+ ())neg◃-cancel-< {suc m} {zero} -<+ = z<sneg◃-cancel-< {suc m} {suc n} (-<- n<m) = s<s n<m-◃<+◃ : ∀ m n .{{_ : ℕ.NonZero m}} → Sign.- ◃ m < Sign.+ ◃ n-◃<+◃ (suc _) zero = -<+-◃<+◃ (suc _) (suc _) = -<++◃≮-◃ : Sign.+ ◃ m ≮ Sign.- ◃ n+◃≮-◃ {zero} {zero} (+<+ ())+◃≮-◃ {suc m} {zero} (+<+ ())-------------------------------------------------------------------------- Properties of _⊖_------------------------------------------------------------------------n⊖n≡0 : ∀ n → n ⊖ n ≡ 0ℤn⊖n≡0 n with n ℕ.<ᵇ n in leq... | true = cong (-_ ∘ +_) (ℕ.n∸n≡0 n) -- this is actually impossible!... | false = cong +_ (ℕ.n∸n≡0 n)[1+m]⊖[1+n]≡m⊖n : ∀ m n → suc m ⊖ suc n ≡ m ⊖ n[1+m]⊖[1+n]≡m⊖n m n with m ℕ.<ᵇ n... | true = refl... | false = refl⊖-swap : ∀ m n → m ⊖ n ≡ - (n ⊖ m)⊖-swap zero zero = refl⊖-swap zero (suc m) = refl⊖-swap (suc m) zero = refl⊖-swap (suc m) (suc n) = beginsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n ≡⟨ ⊖-swap m n ⟩- (n ⊖ m) ≡⟨ cong -_ ([1+m]⊖[1+n]≡m⊖n n m) ⟨- (suc n ⊖ suc m) ∎ where open ≡-Reasoning⊖-≥ : m ℕ.≥ n → m ⊖ n ≡ + (m ∸ n)⊖-≥ {m} {n} p with m ℕ.<ᵇ n | Reflects.invert (ℕ.<ᵇ-reflects-< m n)... | true | q = contradiction (ℕ.≤-<-trans p q) (ℕ.<-irrefl refl)... | false | q = refl≤-⊖ : m ℕ.≤ n → n ⊖ m ≡ + (n ∸ m)≤-⊖ (z≤n {n}) = refl≤-⊖ (s≤s {m} {n} p) = beginsuc n ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟩n ⊖ m ≡⟨ ≤-⊖ p ⟩+ (n ∸ m) ≡⟨⟩+ (suc n ∸ suc m) ∎ where open ≡-Reasoning⊖-≤ : m ℕ.≤ n → m ⊖ n ≡ - + (n ∸ m)⊖-≤ {m} {n} p with m ℕ.<ᵇ n | Reflects.invert (ℕ.<ᵇ-reflects-< m n)... | true | q = refl... | false | q rewrite ℕ.≤-antisym p (ℕ.≮⇒≥ q) | ℕ.n∸n≡0 n = refl⊖-< : m ℕ.< n → m ⊖ n ≡ - + (n ∸ m)⊖-< = ⊖-≤ ∘ ℕ.<⇒≤⊖-≰ : n ℕ.≰ m → m ⊖ n ≡ - + (n ∸ m)⊖-≰ = ⊖-< ∘ ℕ.≰⇒>∣⊖∣-≤ : m ℕ.≤ n → ∣ m ⊖ n ∣ ≡ n ∸ m∣⊖∣-≤ {m} {n} p = begin∣ m ⊖ n ∣ ≡⟨ cong ∣_∣ (⊖-≤ p) ⟩∣ - (+ (n ∸ m)) ∣ ≡⟨ ∣-i∣≡∣i∣ (+ (n ∸ m)) ⟩∣ + (n ∸ m) ∣ ≡⟨⟩n ∸ m ∎ where open ≡-Reasoning∣⊖∣-< : m ℕ.< n → ∣ m ⊖ n ∣ ≡ n ∸ m∣⊖∣-< {m} {n} p = begin∣ m ⊖ n ∣ ≡⟨ cong ∣_∣ (⊖-< p) ⟩∣ - (+ (n ∸ m)) ∣ ≡⟨ ∣-i∣≡∣i∣ (+ (n ∸ m)) ⟩∣ + (n ∸ m) ∣ ≡⟨⟩n ∸ m ∎ where open ≡-Reasoning∣⊖∣-≰ : n ℕ.≰ m → ∣ m ⊖ n ∣ ≡ n ∸ m∣⊖∣-≰ = ∣⊖∣-< ∘ ℕ.≰⇒>-m+n≡n⊖m : ∀ m n → - (+ m) + + n ≡ n ⊖ m-m+n≡n⊖m zero n = refl-m+n≡n⊖m (suc m) n = reflm-n≡m⊖n : ∀ m n → + m + (- + n) ≡ m ⊖ nm-n≡m⊖n zero zero = reflm-n≡m⊖n zero (suc n) = reflm-n≡m⊖n (suc m) zero = cong +[1+_] (ℕ.+-identityʳ m)m-n≡m⊖n (suc m) (suc n) = refl-[n⊖m]≡-m+n : ∀ m n → - (m ⊖ n) ≡ (- (+ m)) + (+ n)-[n⊖m]≡-m+n m n with m ℕ.<ᵇ n | Reflects.invert (ℕ.<ᵇ-reflects-< m n)... | true | p = begin- (- (+ (n ∸ m))) ≡⟨ neg-involutive (+ (n ∸ m)) ⟩+ (n ∸ m) ≡⟨ ⊖-≥ (ℕ.≤-trans (ℕ.m≤n+m m 1) p) ⟨n ⊖ m ≡⟨ -m+n≡n⊖m m n ⟨- (+ m) + + n ∎ where open ≡-Reasoning... | false | p = begin- (+ (m ∸ n)) ≡⟨ ⊖-≤ (ℕ.≮⇒≥ p) ⟨n ⊖ m ≡⟨ -m+n≡n⊖m m n ⟨- (+ m) + + n ∎ where open ≡-Reasoning∣m⊖n∣≡∣n⊖m∣ : ∀ m n → ∣ m ⊖ n ∣ ≡ ∣ n ⊖ m ∣∣m⊖n∣≡∣n⊖m∣ m n = begin∣ m ⊖ n ∣ ≡⟨ cong ∣_∣ (⊖-swap m n) ⟩∣ - (n ⊖ m) ∣ ≡⟨ ∣-i∣≡∣i∣ (n ⊖ m) ⟩∣ n ⊖ m ∣ ∎ where open ≡-Reasoning+-cancelˡ-⊖ : ∀ m n o → (m ℕ.+ n) ⊖ (m ℕ.+ o) ≡ n ⊖ o+-cancelˡ-⊖ zero n o = refl+-cancelˡ-⊖ (suc m) n o = beginsuc (m ℕ.+ n) ⊖ suc (m ℕ.+ o) ≡⟨ [1+m]⊖[1+n]≡m⊖n (m ℕ.+ n) (m ℕ.+ o) ⟩m ℕ.+ n ⊖ (m ℕ.+ o) ≡⟨ +-cancelˡ-⊖ m n o ⟩n ⊖ o ∎ where open ≡-Reasoningm⊖n≤m : ∀ m n → m ⊖ n ≤ + mm⊖n≤m m zero = ≤-reflm⊖n≤m zero (suc n) = -≤+m⊖n≤m (suc m) (suc n) = beginsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n ≤⟨ m⊖n≤m m n ⟩+ m ≤⟨ +≤+ (ℕ.n≤1+n m) ⟩+[1+ m ] ∎ where open ≤-Reasoningm⊖n<1+m : ∀ m n → m ⊖ n < +[1+ m ]m⊖n<1+m m n = ≤-<-trans (m⊖n≤m m n) (+<+ (ℕ.m<n+m m z<s))m⊖1+n<m : ∀ m n .{{_ : ℕ.NonZero n}} → m ⊖ n < + mm⊖1+n<m zero (suc n) = -<+m⊖1+n<m (suc m) (suc n) = begin-strictsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n <⟨ m⊖n<1+m m n ⟩+[1+ m ] ∎ where open ≤-Reasoning-1+m<n⊖m : ∀ m n → -[1+ m ] < n ⊖ m-1+m<n⊖m zero n = -<+-1+m<n⊖m (suc m) zero = -<- ℕ.≤-refl-1+m<n⊖m (suc m) (suc n) = begin-strict-[1+ suc m ] <⟨ -<- ℕ.≤-refl ⟩-[1+ m ] <⟨ -1+m<n⊖m m n ⟩n ⊖ m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟨suc n ⊖ suc m ∎ where open ≤-Reasoning-[1+m]≤n⊖m+1 : ∀ m n → -[1+ m ] ≤ n ⊖ suc m-[1+m]≤n⊖m+1 m zero = ≤-refl-[1+m]≤n⊖m+1 m (suc n) = begin-[1+ m ] ≤⟨ <⇒≤ (-1+m<n⊖m m n) ⟩n ⊖ m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟨suc n ⊖ suc m ∎ where open ≤-Reasoning-1+m≤n⊖m : ∀ m n → -[1+ m ] ≤ n ⊖ m-1+m≤n⊖m m n = <⇒≤ (-1+m<n⊖m m n)0⊖m≤+ : ∀ m {n} → 0 ⊖ m ≤ + n0⊖m≤+ zero = +≤+ z≤n0⊖m≤+ (suc m) = -≤+sign-⊖-< : m ℕ.< n → sign (m ⊖ n) ≡ Sign.-sign-⊖-< {zero} (ℕ.z<s) = reflsign-⊖-< {suc m} {suc n} (ℕ.s<s m<n) = beginsign (suc m ⊖ suc n) ≡⟨ cong sign ([1+m]⊖[1+n]≡m⊖n m n) ⟩sign (m ⊖ n) ≡⟨ sign-⊖-< m<n ⟩Sign.- ∎ where open ≡-Reasoningsign-⊖-≰ : n ℕ.≰ m → sign (m ⊖ n) ≡ Sign.-sign-⊖-≰ = sign-⊖-< ∘ ℕ.≰⇒>⊖-monoʳ-≥-≤ : ∀ n → (n ⊖_) Preserves ℕ._≥_ ⟶ _≤_⊖-monoʳ-≥-≤ zero {m} z≤n = 0⊖m≤+ m⊖-monoʳ-≥-≤ zero {_} (s≤s m≤n) = -≤- m≤n⊖-monoʳ-≥-≤ (suc n) {zero} z≤n = ≤-refl⊖-monoʳ-≥-≤ (suc n) {suc m} z≤n = beginsuc n ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟩n ⊖ m <⟨ m⊖n<1+m n m ⟩+[1+ n ] ∎ where open ≤-Reasoning⊖-monoʳ-≥-≤ (suc n) {suc m} {suc o} (s≤s m≤o) = beginsuc n ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟩n ⊖ m ≤⟨ ⊖-monoʳ-≥-≤ n m≤o ⟩n ⊖ o ≡⟨ [1+m]⊖[1+n]≡m⊖n n o ⟨suc n ⊖ suc o ∎ where open ≤-Reasoning⊖-monoˡ-≤ : ∀ n → (_⊖ n) Preserves ℕ._≤_ ⟶ _≤_⊖-monoˡ-≤ zero {_} {_} m≤o = +≤+ m≤o⊖-monoˡ-≤ (suc n) {_} {0} z≤n = ≤-refl⊖-monoˡ-≤ (suc n) {_} {suc o} z≤n = beginzero ⊖ suc n ≤⟨ ⊖-monoʳ-≥-≤ 0 (ℕ.n≤1+n n) ⟩zero ⊖ n ≤⟨ ⊖-monoˡ-≤ n z≤n ⟩o ⊖ n ≡⟨ [1+m]⊖[1+n]≡m⊖n o n ⟨suc o ⊖ suc n ∎ where open ≤-Reasoning⊖-monoˡ-≤ (suc n) {suc m} {suc o} (s≤s m≤o) = beginsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n ≤⟨ ⊖-monoˡ-≤ n m≤o ⟩o ⊖ n ≡⟨ [1+m]⊖[1+n]≡m⊖n o n ⟨suc o ⊖ suc n ∎ where open ≤-Reasoning⊖-monoʳ->-< : ∀ p → (p ⊖_) Preserves ℕ._>_ ⟶ _<_⊖-monoʳ->-< zero {_} z<s = -<+⊖-monoʳ->-< zero {_} (s<s m<n@(s≤s _)) = -<- m<n⊖-monoʳ->-< (suc p) {suc m} z<s = begin-strictsuc p ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n p m ⟩p ⊖ m <⟨ m⊖n<1+m p m ⟩+[1+ p ] ∎ where open ≤-Reasoning⊖-monoʳ->-< (suc p) {suc m} {suc n} (s<s m<n@(s≤s _)) = begin-strictsuc p ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n p m ⟩p ⊖ m <⟨ ⊖-monoʳ->-< p m<n ⟩p ⊖ n ≡⟨ [1+m]⊖[1+n]≡m⊖n p n ⟨suc p ⊖ suc n ∎ where open ≤-Reasoning⊖-monoˡ-< : ∀ n → (_⊖ n) Preserves ℕ._<_ ⟶ _<_⊖-monoˡ-< zero m<o = +<+ m<o⊖-monoˡ-< (suc n) {_} {suc o} z<s = begin-strict-[1+ n ] <⟨ -1+m<n⊖m n _ ⟩o ⊖ n ≡⟨ [1+m]⊖[1+n]≡m⊖n o n ⟨suc o ⊖ suc n ∎ where open ≤-Reasoning⊖-monoˡ-< (suc n) {suc m} {suc (suc o)} (s<s m<o@(s≤s _)) = begin-strictsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n <⟨ ⊖-monoˡ-< n m<o ⟩suc o ⊖ n ≡⟨ [1+m]⊖[1+n]≡m⊖n (suc o) n ⟨suc (suc o) ⊖ suc n ∎ where open ≤-Reasoning-------------------------------------------------------------------------- Properties of _+_-------------------------------------------------------------------------------------------------------------------------------------------------- Algebraic properties of _+_+-comm : Commutative _+_+-comm -[1+ m ] -[1+ n ] = cong (-[1+_] ∘ suc) (ℕ.+-comm m n)+-comm (+ m) (+ n) = cong +_ (ℕ.+-comm m n)+-comm -[1+ _ ] (+ _) = refl+-comm (+ _) -[1+ _ ] = refl+-identityˡ : LeftIdentity +0 _+_+-identityˡ -[1+ _ ] = refl+-identityˡ (+ _) = refl+-identityʳ : RightIdentity +0 _+_+-identityʳ = comm∧idˡ⇒idʳ +-comm +-identityˡ+-identity : Identity +0 _+_+-identity = +-identityˡ , +-identityʳdistribˡ-⊖-+-pos : ∀ m n o → n ⊖ o + + m ≡ n ℕ.+ m ⊖ odistribˡ-⊖-+-pos _ zero zero = refldistribˡ-⊖-+-pos _ zero (suc _) = refldistribˡ-⊖-+-pos _ (suc _) zero = refldistribˡ-⊖-+-pos m (suc n) (suc o) = beginsuc n ⊖ suc o + + m ≡⟨ cong (_+ + m) ([1+m]⊖[1+n]≡m⊖n n o) ⟩n ⊖ o + + m ≡⟨ distribˡ-⊖-+-pos m n o ⟩n ℕ.+ m ⊖ o ≡⟨ [1+m]⊖[1+n]≡m⊖n (n ℕ.+ m) o ⟨suc (n ℕ.+ m) ⊖ suc o ∎ where open ≡-Reasoningdistribˡ-⊖-+-neg : ∀ m n o → n ⊖ o + -[1+ m ] ≡ n ⊖ (suc o ℕ.+ m)distribˡ-⊖-+-neg _ zero zero = refldistribˡ-⊖-+-neg _ zero (suc _) = refldistribˡ-⊖-+-neg _ (suc _) zero = refldistribˡ-⊖-+-neg m (suc n) (suc o) = beginsuc n ⊖ suc o + -[1+ m ] ≡⟨ cong (_+ -[1+ m ]) ([1+m]⊖[1+n]≡m⊖n n o) ⟩n ⊖ o + -[1+ m ] ≡⟨ distribˡ-⊖-+-neg m n o ⟩n ⊖ (suc o ℕ.+ m) ≡⟨ [1+m]⊖[1+n]≡m⊖n n (suc o ℕ.+ m) ⟨suc n ⊖ (suc (suc o) ℕ.+ m) ∎ where open ≡-Reasoningdistribʳ-⊖-+-pos : ∀ m n o → + m + (n ⊖ o) ≡ m ℕ.+ n ⊖ odistribʳ-⊖-+-pos m n o = begin+ m + (n ⊖ o) ≡⟨ +-comm (+ m) (n ⊖ o) ⟩(n ⊖ o) + + m ≡⟨ distribˡ-⊖-+-pos m n o ⟩n ℕ.+ m ⊖ o ≡⟨ cong (_⊖ o) (ℕ.+-comm n m) ⟩m ℕ.+ n ⊖ o ∎ where open ≡-Reasoningdistribʳ-⊖-+-neg : ∀ m n o → -[1+ m ] + (n ⊖ o) ≡ n ⊖ (suc m ℕ.+ o)distribʳ-⊖-+-neg m n o = begin-[1+ m ] + (n ⊖ o) ≡⟨ +-comm -[1+ m ] (n ⊖ o) ⟩(n ⊖ o) + -[1+ m ] ≡⟨ distribˡ-⊖-+-neg m n o ⟩n ⊖ suc (o ℕ.+ m) ≡⟨ cong (λ x → n ⊖ suc x) (ℕ.+-comm o m) ⟩n ⊖ suc (m ℕ.+ o) ∎ where open ≡-Reasoning+-assoc : Associative _+_+-assoc +0 j k rewrite +-identityˡ j | +-identityˡ (j + k) = refl+-assoc i +0 k rewrite +-identityʳ i | +-identityˡ k = refl+-assoc i j +0 rewrite +-identityʳ (i + j) | +-identityʳ j = refl+-assoc -[1+ m ] -[1+ n ] +[1+ o ] = beginsuc o ⊖ suc (suc (m ℕ.+ n)) ≡⟨ [1+m]⊖[1+n]≡m⊖n o (suc m ℕ.+ n) ⟩o ⊖ (suc m ℕ.+ n) ≡⟨ distribʳ-⊖-+-neg m o n ⟨-[1+ m ] + (o ⊖ n) ≡⟨ cong (λ z → -[1+ m ] + z) ([1+m]⊖[1+n]≡m⊖n o n) ⟨-[1+ m ] + (suc o ⊖ suc n) ∎ where open ≡-Reasoning+-assoc -[1+ m ] +[1+ n ] +[1+ o ] = beginsuc n ⊖ suc m + +[1+ o ] ≡⟨ cong (_+ +[1+ o ]) ([1+m]⊖[1+n]≡m⊖n n m) ⟩(n ⊖ m) + +[1+ o ] ≡⟨ distribˡ-⊖-+-pos (suc o) n m ⟩n ℕ.+ suc o ⊖ m ≡⟨ [1+m]⊖[1+n]≡m⊖n (n ℕ.+ suc o) m ⟨suc (n ℕ.+ suc o) ⊖ suc m ∎ where open ≡-Reasoning+-assoc +[1+ m ] -[1+ n ] -[1+ o ] = begin(suc m ⊖ suc n) + -[1+ o ] ≡⟨ cong (_+ -[1+ o ]) ([1+m]⊖[1+n]≡m⊖n m n) ⟩(m ⊖ n) + -[1+ o ] ≡⟨ distribˡ-⊖-+-neg o m n ⟩m ⊖ suc (n ℕ.+ o) ≡⟨ [1+m]⊖[1+n]≡m⊖n m (suc n ℕ.+ o) ⟨suc m ⊖ suc (suc (n ℕ.+ o)) ∎ where open ≡-Reasoning+-assoc +[1+ m ] -[1+ n ] +[1+ o ]rewrite [1+m]⊖[1+n]≡m⊖n m n| [1+m]⊖[1+n]≡m⊖n o n| distribˡ-⊖-+-pos (suc o) m n| distribʳ-⊖-+-pos (suc m) o n| sym (ℕ.+-assoc m 1 o)| ℕ.+-comm m 1= refl+-assoc +[1+ m ] +[1+ n ] -[1+ o ]rewrite [1+m]⊖[1+n]≡m⊖n n o| [1+m]⊖[1+n]≡m⊖n (m ℕ.+ suc n) o| distribʳ-⊖-+-pos (suc m) n o| sym (ℕ.+-assoc m 1 n)| ℕ.+-comm m 1= refl+-assoc -[1+ m ] -[1+ n ] -[1+ o ]rewrite sym (ℕ.+-assoc m 1 (n ℕ.+ o))| ℕ.+-comm m 1| ℕ.+-assoc m n o= refl+-assoc -[1+ m ] +[1+ n ] -[1+ o ]rewrite [1+m]⊖[1+n]≡m⊖n n m| [1+m]⊖[1+n]≡m⊖n n o| distribʳ-⊖-+-neg m n o| distribˡ-⊖-+-neg o n m= refl+-assoc +[1+ m ] +[1+ n ] +[1+ o ]rewrite ℕ.+-assoc (suc m) (suc n) (suc o)= refl+-inverseˡ : LeftInverse +0 -_ _+_+-inverseˡ -[1+ n ] = n⊖n≡0 (suc n)+-inverseˡ +0 = refl+-inverseˡ +[1+ n ] = n⊖n≡0 (suc n)+-inverseʳ : RightInverse +0 -_ _+_+-inverseʳ = comm∧invˡ⇒invʳ +-comm +-inverseˡ+-inverse : Inverse +0 -_ _+_+-inverse = +-inverseˡ , +-inverseʳ-------------------------------------------------------------------------- Structures+-isMagma : IsMagma _+_+-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _+_}+-isSemigroup : IsSemigroup _+_+-isSemigroup = record{ isMagma = +-isMagma; assoc = +-assoc}+-isCommutativeSemigroup : IsCommutativeSemigroup _+_+-isCommutativeSemigroup = record{ isSemigroup = +-isSemigroup; comm = +-comm}+-0-isMonoid : IsMonoid _+_ +0+-0-isMonoid = record{ isSemigroup = +-isSemigroup; identity = +-identity}+-0-isCommutativeMonoid : IsCommutativeMonoid _+_ +0+-0-isCommutativeMonoid = record{ isMonoid = +-0-isMonoid; comm = +-comm}+-0-isGroup : IsGroup _+_ +0 (-_)+-0-isGroup = record{ isMonoid = +-0-isMonoid; inverse = +-inverse; ⁻¹-cong = cong (-_)}+-0-isAbelianGroup : IsAbelianGroup _+_ +0 (-_)+-0-isAbelianGroup = record{ isGroup = +-0-isGroup; comm = +-comm}-------------------------------------------------------------------------- Bundles+-magma : Magma 0ℓ 0ℓ+-magma = record{ isMagma = +-isMagma}+-semigroup : Semigroup 0ℓ 0ℓ+-semigroup = record{ isSemigroup = +-isSemigroup}+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ+-commutativeSemigroup = record{ isCommutativeSemigroup = +-isCommutativeSemigroup}+-0-monoid : Monoid 0ℓ 0ℓ+-0-monoid = record{ isMonoid = +-0-isMonoid}+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-0-commutativeMonoid = record{ isCommutativeMonoid = +-0-isCommutativeMonoid}+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ+-0-abelianGroup = record{ isAbelianGroup = +-0-isAbelianGroup}-------------------------------------------------------------------------- Properties of _+_ and +_/-_.pos-+ : ℕtoℤ.Homomorphic₂ +_ ℕ._+_ _+_pos-+ zero n = reflpos-+ (suc m) n = cong sucℤ (pos-+ m n)neg-distrib-+ : ∀ i j → - (i + j) ≡ (- i) + (- j)neg-distrib-+ +0 +0 = reflneg-distrib-+ +0 +[1+ n ] = reflneg-distrib-+ +[1+ m ] +0 = cong -[1+_] (ℕ.+-identityʳ m)neg-distrib-+ +[1+ m ] +[1+ n ] = cong -[1+_] (ℕ.+-suc m n)neg-distrib-+ -[1+ m ] -[1+ n ] = cong +[1+_] (sym (ℕ.+-suc m n))neg-distrib-+ (+ m) -[1+ n ] = -[n⊖m]≡-m+n m (suc n)neg-distrib-+ -[1+ m ] (+ n) =trans (-[n⊖m]≡-m+n n (suc m)) (+-comm (- + n) (+ suc m))◃-distrib-+ : ∀ s m n → s ◃ (m ℕ.+ n) ≡ (s ◃ m) + (s ◃ n)◃-distrib-+ Sign.- m n = beginSign.- ◃ (m ℕ.+ n) ≡⟨ -◃n≡-n (m ℕ.+ n) ⟩- (+ (m ℕ.+ n)) ≡⟨⟩- ((+ m) + (+ n)) ≡⟨ neg-distrib-+ (+ m) (+ n) ⟩(- (+ m)) + (- (+ n)) ≡⟨ sym (cong₂ _+_ (-◃n≡-n m) (-◃n≡-n n)) ⟩(Sign.- ◃ m) + (Sign.- ◃ n) ∎ where open ≡-Reasoning◃-distrib-+ Sign.+ m n = beginSign.+ ◃ (m ℕ.+ n) ≡⟨ +◃n≡+n (m ℕ.+ n) ⟩+ (m ℕ.+ n) ≡⟨⟩(+ m) + (+ n) ≡⟨ sym (cong₂ _+_ (+◃n≡+n m) (+◃n≡+n n)) ⟩(Sign.+ ◃ m) + (Sign.+ ◃ n) ∎ where open ≡-Reasoning-------------------------------------------------------------------------- Properties of _+_ and _≤_+-monoʳ-≤ : ∀ n → (_+_ n) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ (+ n) {_} (-≤- o≤m) = ⊖-monoʳ-≥-≤ n (s≤s o≤m)+-monoʳ-≤ (+ n) { -[1+ m ]} -≤+ = ≤-trans (m⊖n≤m n (suc m)) (+≤+ (ℕ.m≤m+n n _))+-monoʳ-≤ (+ n) {_} (+≤+ m≤o) = +≤+ (ℕ.+-monoʳ-≤ n m≤o)+-monoʳ-≤ -[1+ n ] {_} {_} (-≤- n≤m) = -≤- (ℕ.+-monoʳ-≤ (suc n) n≤m)+-monoʳ-≤ -[1+ n ] {_} {+ m} -≤+ = ≤-trans (-≤- (ℕ.m≤m+n (suc n) _)) (-1+m≤n⊖m (suc n) m)+-monoʳ-≤ -[1+ n ] {_} {_} (+≤+ m≤n) = ⊖-monoˡ-≤ (suc n) m≤n+-monoˡ-≤ : ∀ n → (_+ n) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ n {i} {j} rewrite +-comm i n | +-comm j n = +-monoʳ-≤ n+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-≤ {m} {n} {i} {j} m≤n i≤j = beginm + i ≤⟨ +-monoˡ-≤ i m≤n ⟩n + i ≤⟨ +-monoʳ-≤ n i≤j ⟩n + j ∎where open ≤-Reasoningi≤j⇒i≤k+j : ∀ k .{{_ : NonNegative k}} → i ≤ j → i ≤ k + ji≤j⇒i≤k+j (+ n) i≤j = subst (_≤ _) (+-identityˡ _) (+-mono-≤ (+≤+ z≤n) i≤j)i≤j+i : ∀ i j .{{_ : NonNegative j}} → i ≤ j + ii≤j+i i j = i≤j⇒i≤k+j j ≤-refli≤i+j : ∀ i j .{{_ : NonNegative j}} → i ≤ i + ji≤i+j i j rewrite +-comm i j = i≤j+i i j-------------------------------------------------------------------------- Properties of _+_ and _<_+-monoʳ-< : ∀ i → (_+_ i) Preserves _<_ ⟶ _<_+-monoʳ-< (+ n) {_} {_} (-<- o<m) = ⊖-monoʳ->-< n (s<s o<m)+-monoʳ-< (+ n) {_} {_} -<+ = <-≤-trans (m⊖1+n<m n _) (+≤+ (ℕ.m≤m+n n _))+-monoʳ-< (+ n) {_} {_} (+<+ m<o) = +<+ (ℕ.+-monoʳ-< n m<o)+-monoʳ-< -[1+ n ] {_} {_} (-<- o<m) = -<- (ℕ.+-monoʳ-< (suc n) o<m)+-monoʳ-< -[1+ n ] {_} {+ o} -<+ = <-≤-trans (-<- (ℕ.m≤m+n (suc n) _)) (-[1+m]≤n⊖m+1 n o)+-monoʳ-< -[1+ n ] {_} {_} (+<+ m<o) = ⊖-monoˡ-< (suc n) m<o+-monoˡ-< : ∀ i → (_+ i) Preserves _<_ ⟶ _<_+-monoˡ-< i {j} {k} rewrite +-comm j i | +-comm k i = +-monoʳ-< i+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-mono-< {i} {j} {k} {l} i<j k<l = begin-stricti + k <⟨ +-monoˡ-< k i<j ⟩j + k <⟨ +-monoʳ-< j k<l ⟩j + l ∎where open ≤-Reasoning+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-≤-< {i} {j} {k} i≤j j<k = ≤-<-trans (+-monoˡ-≤ k i≤j) (+-monoʳ-< j j<k)+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-<-≤ {i} {j} {k} i<j j≤k = <-≤-trans (+-monoˡ-< k i<j) (+-monoʳ-≤ j j≤k)-------------------------------------------------------------------------- Properties of _-_------------------------------------------------------------------------neg-minus-pos : ∀ m n → -[1+ m ] - (+ n) ≡ -[1+ (n ℕ.+ m) ]neg-minus-pos m zero = reflneg-minus-pos zero (suc n) = cong (-[1+_] ∘ suc) (sym (ℕ.+-identityʳ n))neg-minus-pos (suc m) (suc n) = cong (-[1+_] ∘ suc) (ℕ.+-comm (suc m) n)+-minus-telescope : ∀ i j k → (i - j) + (j - k) ≡ i - k+-minus-telescope i j k = begin(i - j) + (j - k) ≡⟨ +-assoc i (- j) (j - k) ⟩i + (- j + (j - k)) ≡⟨ cong (λ v → i + v) (+-assoc (- j) j _) ⟨i + ((- j + j) - k) ≡⟨ +-assoc i (- j + j) (- k) ⟨i + (- j + j) - k ≡⟨ cong (λ a → i + a - k) (+-inverseˡ j) ⟩i + 0ℤ - k ≡⟨ cong (_- k) (+-identityʳ i) ⟩i - k ∎ where open ≡-Reasoning[+m]-[+n]≡m⊖n : ∀ m n → (+ m) - (+ n) ≡ m ⊖ n[+m]-[+n]≡m⊖n zero zero = refl[+m]-[+n]≡m⊖n zero (suc n) = refl[+m]-[+n]≡m⊖n (suc m) zero = cong +[1+_] (ℕ.+-identityʳ m)[+m]-[+n]≡m⊖n (suc m) (suc n) = refl∣i-j∣≡∣j-i∣ : ∀ i j → ∣ i - j ∣ ≡ ∣ j - i ∣∣i-j∣≡∣j-i∣ -[1+ m ] -[1+ n ] = ∣m⊖n∣≡∣n⊖m∣ (suc n) (suc m)∣i-j∣≡∣j-i∣ -[1+ m ] (+ n) = begin∣ -[1+ m ] - (+ n) ∣ ≡⟨ cong ∣_∣ (neg-minus-pos m n) ⟩suc (n ℕ.+ m) ≡⟨ ℕ.+-suc n m ⟨n ℕ.+ suc m ∎ where open ≡-Reasoning∣i-j∣≡∣j-i∣ (+ m) -[1+ n ] = beginm ℕ.+ suc n ≡⟨ ℕ.+-suc m n ⟩suc (m ℕ.+ n) ≡⟨ cong ∣_∣ (neg-minus-pos n m) ⟨∣ -[1+ n ] + - + m ∣ ∎ where open ≡-Reasoning∣i-j∣≡∣j-i∣ (+ m) (+ n) = begin∣ + m - + n ∣ ≡⟨ cong ∣_∣ ([+m]-[+n]≡m⊖n m n) ⟩∣ m ⊖ n ∣ ≡⟨ ∣m⊖n∣≡∣n⊖m∣ m n ⟩∣ n ⊖ m ∣ ≡⟨ cong ∣_∣ ([+m]-[+n]≡m⊖n n m) ⟨∣ + n - + m ∣ ∎ where open ≡-Reasoning∣-∣-≤ : i ≤ j → + ∣ i - j ∣ ≡ j - i∣-∣-≤ (-≤- {m} {n} n≤m) = begin+ ∣ -[1+ m ] + +[1+ n ] ∣ ≡⟨ cong (λ j → + ∣ j ∣) ([1+m]⊖[1+n]≡m⊖n n m) ⟩+ ∣ n ⊖ m ∣ ≡⟨ cong +_ (∣⊖∣-≤ n≤m) ⟩+ ( m ∸ n ) ≡⟨ sym (≤-⊖ n≤m) ⟩m ⊖ n ≡⟨ sym ([1+m]⊖[1+n]≡m⊖n m n) ⟩suc m ⊖ suc n ∎ where open ≡-Reasoning∣-∣-≤ (-≤+ {m} {zero}) = refl∣-∣-≤ (-≤+ {m} {suc n}) = begin+ ∣ -[1+ m ] - + suc n ∣ ≡⟨⟩+ suc (suc m ℕ.+ n) ≡⟨ cong (λ n → + suc n) (ℕ.+-comm (suc m) n) ⟩+ (suc n ℕ.+ suc m) ≡⟨⟩+ suc n - -[1+ m ] ∎ where open ≡-Reasoning∣-∣-≤ (+≤+ {m} {n} m≤n) = begin+ ∣ + m - + n ∣ ≡⟨ cong (λ j → + ∣ j ∣) (m-n≡m⊖n m n) ⟩+ ∣ m ⊖ n ∣ ≡⟨ cong +_ ( ∣⊖∣-≤ m≤n ) ⟩+ (n ∸ m) ≡⟨ sym (≤-⊖ m≤n) ⟩n ⊖ m ≡⟨ sym (m-n≡m⊖n n m) ⟩+ n - + m ∎ where open ≡-Reasoningi≡j⇒i-j≡0 : i ≡ j → i - j ≡ 0ℤi≡j⇒i-j≡0 {i} refl = +-inverseʳ ii-j≡0⇒i≡j : ∀ i j → i - j ≡ 0ℤ → i ≡ ji-j≡0⇒i≡j i j i-j≡0 = begini ≡⟨ +-identityʳ i ⟨i + 0ℤ ≡⟨ cong (_+_ i) (+-inverseˡ j) ⟨i + (- j + j) ≡⟨ +-assoc i (- j) j ⟨(i - j) + j ≡⟨ cong (_+ j) i-j≡0 ⟩0ℤ + j ≡⟨ +-identityˡ j ⟩j ∎ where open ≡-Reasoningi≤j⇒i-k≤j : ∀ k .{{_ : NonNegative k}} → i ≤ j → i - k ≤ ji≤j⇒i-k≤j {i} +0 i≤j rewrite +-identityʳ i = i≤ji≤j⇒i-k≤j {+ m} +[1+ n ] i≤j = ≤-trans (m⊖n≤m m (suc n)) i≤ji≤j⇒i-k≤j { -[1+ m ]} +[1+ n ] i≤j = ≤-trans (-≤- (ℕ.≤-trans (ℕ.m≤m+n m n) (ℕ.n≤1+n _))) i≤ji-j≤i : ∀ i j .{{_ : NonNegative j}} → i - j ≤ ii-j≤i i j = i≤j⇒i-k≤j j ≤-refli≤j⇒i-j≤0 : i ≤ j → i - j ≤ 0ℤi≤j⇒i-j≤0 {_} {j} -≤+ = i≤j⇒i-k≤j j -≤+i≤j⇒i-j≤0 { -[1+ m ]} { -[1+ n ]} (-≤- n≤m) = beginsuc n ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n n m ⟩n ⊖ m ≤⟨ ⊖-monoʳ-≥-≤ n n≤m ⟩n ⊖ n ≡⟨ n⊖n≡0 n ⟩0ℤ ∎ where open ≤-Reasoningi≤j⇒i-j≤0 {_} {+0} (+≤+ z≤n) = +≤+ z≤ni≤j⇒i-j≤0 {_} {+[1+ n ]} (+≤+ z≤n) = -≤+i≤j⇒i-j≤0 {+[1+ m ]} {+[1+ n ]} (+≤+ (s≤s m≤n)) = beginsuc m ⊖ suc n ≡⟨ [1+m]⊖[1+n]≡m⊖n m n ⟩m ⊖ n ≤⟨ ⊖-monoʳ-≥-≤ m m≤n ⟩m ⊖ m ≡⟨ n⊖n≡0 m ⟩0ℤ ∎ where open ≤-Reasoningi-j≤0⇒i≤j : i - j ≤ 0ℤ → i ≤ ji-j≤0⇒i≤j {i} {j} i-j≤0 = begini ≡⟨ +-identityʳ i ⟨i + 0ℤ ≡⟨ cong (_+_ i) (+-inverseˡ j) ⟨i + (- j + j) ≡⟨ +-assoc i (- j) j ⟨(i - j) + j ≤⟨ +-monoˡ-≤ j i-j≤0 ⟩0ℤ + j ≡⟨ +-identityˡ j ⟩j ∎where open ≤-Reasoningi≤j⇒0≤j-i : i ≤ j → 0ℤ ≤ j - ii≤j⇒0≤j-i {i} {j} i≤j = begin0ℤ ≡⟨ +-inverseʳ i ⟨i - i ≤⟨ +-monoˡ-≤ (- i) i≤j ⟩j - i ∎where open ≤-Reasoning0≤i-j⇒j≤i : 0ℤ ≤ i - j → j ≤ i0≤i-j⇒j≤i {i} {j} 0≤i-j = beginj ≡⟨ +-identityˡ j ⟨0ℤ + j ≤⟨ +-monoˡ-≤ j 0≤i-j ⟩i - j + j ≡⟨ +-assoc i (- j) j ⟩i + (- j + j) ≡⟨ cong (_+_ i) (+-inverseˡ j) ⟩i + 0ℤ ≡⟨ +-identityʳ i ⟩i ∎where open ≤-Reasoning-------------------------------------------------------------------------- Properties of suc------------------------------------------------------------------------i≤j⇒i≤1+j : i ≤ j → i ≤ sucℤ ji≤j⇒i≤1+j = i≤j⇒i≤k+j (+ 1)i≤suc[i] : ∀ i → i ≤ sucℤ ii≤suc[i] i = i≤j+i i (+ 1)suc-+ : ∀ m n → +[1+ m ] + n ≡ sucℤ (+ m + n)suc-+ m (+ n) = reflsuc-+ m (-[1+ n ]) = sym (distribʳ-⊖-+-pos 1 m (suc n))i≢suc[i] : i ≢ sucℤ ii≢suc[i] {+ _} ()i≢suc[i] { -[1+ 0 ]} ()i≢suc[i] { -[1+ suc n ]} ()1-[1+n]≡-n : ∀ n → sucℤ -[1+ n ] ≡ - (+ n)1-[1+n]≡-n zero = refl1-[1+n]≡-n (suc n) = reflsuc-mono : sucℤ Preserves _≤_ ⟶ _≤_suc-mono (-≤+ {m} {n}) = begin1 ⊖ suc m ≡⟨ [1+m]⊖[1+n]≡m⊖n 0 m ⟩0 ⊖ m ≤⟨ 0⊖m≤+ m ⟩sucℤ (+ n) ∎ where open ≤-Reasoningsuc-mono (-≤- n≤m) = ⊖-monoʳ-≥-≤ 1 (s≤s n≤m)suc-mono (+≤+ m≤n) = +≤+ (s≤s m≤n)suc[i]≤j⇒i<j : sucℤ i ≤ j → i < jsuc[i]≤j⇒i<j {+ i} {+ _} (+≤+ i≤j) = +<+ i≤jsuc[i]≤j⇒i<j { -[1+ 0 ]} {+ j} p = -<+suc[i]≤j⇒i<j { -[1+ suc i ]} {+ j} -≤+ = -<+suc[i]≤j⇒i<j { -[1+ suc i ]} { -[1+ j ]} (-≤- j≤i) = -<- (s≤s j≤i)i<j⇒suc[i]≤j : i < j → sucℤ i ≤ ji<j⇒suc[i]≤j {+ _} {+ _} (+<+ i<j) = +≤+ i<ji<j⇒suc[i]≤j { -[1+ 0 ]} {+ _} -<+ = +≤+ z≤ni<j⇒suc[i]≤j { -[1+ suc i ]} { -[1+ _ ]} (-<- j<i) = -≤- (s≤s⁻¹ j<i)i<j⇒suc[i]≤j { -[1+ suc i ]} {+ _} -<+ = -≤+-------------------------------------------------------------------------- Properties of pred------------------------------------------------------------------------suc-pred : ∀ i → sucℤ (pred i) ≡ isuc-pred i = beginsucℤ (pred i) ≡⟨ +-assoc 1ℤ -1ℤ i ⟨0ℤ + i ≡⟨ +-identityˡ i ⟩i ∎ where open ≡-Reasoningpred-suc : ∀ i → pred (sucℤ i) ≡ ipred-suc i = beginpred (sucℤ i) ≡⟨ +-assoc -1ℤ 1ℤ i ⟨0ℤ + i ≡⟨ +-identityˡ i ⟩i ∎ where open ≡-Reasoning+-pred : ∀ i j → i + pred j ≡ pred (i + j)+-pred i j = begini + (-1ℤ + j) ≡⟨ +-assoc i -1ℤ j ⟨i + -1ℤ + j ≡⟨ cong (_+ j) (+-comm i -1ℤ) ⟩-1ℤ + i + j ≡⟨ +-assoc -1ℤ i j ⟩-1ℤ + (i + j) ∎ where open ≡-Reasoningpred-+ : ∀ i j → pred i + j ≡ pred (i + j)pred-+ i j = beginpred i + j ≡⟨ +-comm (pred i) j ⟩j + pred i ≡⟨ +-pred j i ⟩pred (j + i) ≡⟨ cong pred (+-comm j i) ⟩pred (i + j) ∎ where open ≡-Reasoningneg-suc : ∀ m → -[1+ m ] ≡ pred (- + m)neg-suc zero = reflneg-suc (suc m) = reflminus-suc : ∀ m n → m - +[1+ n ] ≡ pred (m - + n)minus-suc m n = beginm + - +[1+ n ] ≡⟨ cong (_+_ m) (neg-suc n) ⟩m + pred (- (+ n)) ≡⟨ +-pred m (- + n) ⟩pred (m - + n) ∎ where open ≡-Reasoningi≤pred[j]⇒i<j : i ≤ pred j → i < ji≤pred[j]⇒i<j {_} { + n} leq = ≤-<-trans leq (m⊖1+n<m n 1)i≤pred[j]⇒i<j {_} { -[1+ n ]} leq = ≤-<-trans leq (-<- ℕ.≤-refl)i<j⇒i≤pred[j] : i < j → i ≤ pred ji<j⇒i≤pred[j] {_} { +0} -<+ = -≤- z≤ni<j⇒i≤pred[j] {_} { +[1+ n ]} -<+ = -≤+i<j⇒i≤pred[j] {_} { +[1+ n ]} (+<+ m<n) = +≤+ (s≤s⁻¹ m<n)i<j⇒i≤pred[j] {_} { -[1+ n ]} (-<- n<m) = -≤- n<mi≤j⇒pred[i]≤j : i ≤ j → pred i ≤ ji≤j⇒pred[i]≤j -≤+ = -≤+i≤j⇒pred[i]≤j (-≤- n≤m) = -≤- (ℕ.m≤n⇒m≤1+n n≤m)i≤j⇒pred[i]≤j (+≤+ z≤n) = -≤+i≤j⇒pred[i]≤j (+≤+ (s≤s m≤n)) = +≤+ (ℕ.m≤n⇒m≤1+n m≤n)pred-mono : pred Preserves _≤_ ⟶ _≤_pred-mono (-≤+ {n = 0}) = -≤- z≤npred-mono (-≤+ {n = suc n}) = -≤+pred-mono (-≤- n≤m) = -≤- (s≤s n≤m)pred-mono (+≤+ m≤n) = ⊖-monoˡ-≤ 1 m≤n-------------------------------------------------------------------------- Properties of _*_-------------------------------------------------------------------------- Algebraic properties*-comm : Commutative _*_*-comm -[1+ m ] -[1+ n ] rewrite ℕ.*-comm (suc m) (suc n) = refl*-comm -[1+ m ] (+ n) rewrite ℕ.*-comm (suc m) n = refl*-comm (+ m) -[1+ n ] rewrite ℕ.*-comm m (suc n) = refl*-comm (+ m) (+ n) rewrite ℕ.*-comm m n = refl*-identityˡ : LeftIdentity 1ℤ _*_*-identityˡ -[1+ n ] rewrite ℕ.+-identityʳ n = refl*-identityˡ +0 = refl*-identityˡ +[1+ n ] rewrite ℕ.+-identityʳ n = refl*-identityʳ : RightIdentity 1ℤ _*_*-identityʳ = comm∧idˡ⇒idʳ *-comm *-identityˡ*-identity : Identity 1ℤ _*_*-identity = *-identityˡ , *-identityʳ*-zeroˡ : LeftZero 0ℤ _*_*-zeroˡ _ = refl*-zeroʳ : RightZero 0ℤ _*_*-zeroʳ = comm∧zeˡ⇒zeʳ *-comm *-zeroˡ*-zero : Zero 0ℤ _*_*-zero = *-zeroˡ , *-zeroʳ*-assoc : Associative _*_*-assoc +0 _ _ = refl*-assoc i +0 _ rewrite ℕ.*-zeroʳ ∣ i ∣ = refl*-assoc i j +0 rewriteℕ.*-zeroʳ ∣ j ∣| ℕ.*-zeroʳ ∣ i ∣| ℕ.*-zeroʳ ∣ sign i Sign.* sign j ◃ ∣ i ∣ ℕ.* ∣ j ∣ ∣= refl*-assoc -[1+ m ] -[1+ n ] +[1+ o ] = cong (+_ ∘ suc) (inner-assoc m n o)*-assoc -[1+ m ] +[1+ n ] -[1+ o ] = cong (+_ ∘ suc) (inner-assoc m n o)*-assoc +[1+ m ] +[1+ n ] +[1+ o ] = cong (+_ ∘ suc) (inner-assoc m n o)*-assoc +[1+ m ] -[1+ n ] -[1+ o ] = cong (+_ ∘ suc) (inner-assoc m n o)*-assoc -[1+ m ] -[1+ n ] -[1+ o ] = cong -[1+_] (inner-assoc m n o)*-assoc -[1+ m ] +[1+ n ] +[1+ o ] = cong -[1+_] (inner-assoc m n o)*-assoc +[1+ m ] -[1+ n ] +[1+ o ] = cong -[1+_] (inner-assoc m n o)*-assoc +[1+ m ] +[1+ n ] -[1+ o ] = cong -[1+_] (inner-assoc m n o)private-- lemma used to prove distributivity.distrib-lemma : ∀ m n o → (o ⊖ n) * -[1+ m ] ≡ m ℕ.+ n ℕ.* suc m ⊖ (m ℕ.+ o ℕ.* suc m)distrib-lemma m n orewrite +-cancelˡ-⊖ m (n ℕ.* suc m) (o ℕ.* suc m)| ⊖-swap (n ℕ.* suc m) (o ℕ.* suc m)with n ℕ.≤? o... | yes n≤orewrite ⊖-≥ n≤o| ⊖-≥ (ℕ.*-mono-≤ n≤o (ℕ.≤-refl {x = suc m}))| -◃n≡-n ((o ∸ n) ℕ.* suc m)| ℕ.*-distribʳ-∸ (suc m) o n= refl... | no n≰orewrite sign-⊖-≰ n≰o| ∣⊖∣-≰ n≰o| +◃n≡+n ((n ∸ o) ℕ.* suc m)| ⊖-≰ (n≰o ∘ ℕ.*-cancelʳ-≤ n o (suc m))| neg-involutive (+ (n ℕ.* suc m ∸ o ℕ.* suc m))| ℕ.*-distribʳ-∸ (suc m) n o= refl*-distribʳ-+ : _*_ DistributesOverʳ _+_*-distribʳ-+ +0 y zrewrite ℕ.*-zeroʳ ∣ y ∣| ℕ.*-zeroʳ ∣ z ∣| ℕ.*-zeroʳ ∣ y + z ∣= refl*-distribʳ-+ x +0 zrewrite +-identityˡ z| +-identityˡ (sign z Sign.* sign x ◃ ∣ z ∣ ℕ.* ∣ x ∣)= refl*-distribʳ-+ x y +0rewrite +-identityʳ y| +-identityʳ (sign y Sign.* sign x ◃ ∣ y ∣ ℕ.* ∣ x ∣)= refl*-distribʳ-+ -[1+ m ] -[1+ n ] -[1+ o ] = cong (+_) $ assoc₁ m n o*-distribʳ-+ +[1+ m ] +[1+ n ] +[1+ o ] = cong +[1+_] $ ℕ.suc-injective (assoc₂ m n o)*-distribʳ-+ -[1+ m ] +[1+ n ] +[1+ o ] = cong -[1+_] $ assoc₃ m n o*-distribʳ-+ +[1+ m ] -[1+ n ] -[1+ o ] = cong -[1+_] $ assoc₄ m n o*-distribʳ-+ -[1+ m ] -[1+ n ] +[1+ o ] = begin(suc o ⊖ suc n) * -[1+ m ] ≡⟨ cong (_* -[1+ m ]) ([1+m]⊖[1+n]≡m⊖n o n) ⟩(o ⊖ n) * -[1+ m ] ≡⟨ distrib-lemma m n o ⟩m ℕ.+ n ℕ.* suc m ⊖ (m ℕ.+ o ℕ.* suc m) ≡⟨ [1+m]⊖[1+n]≡m⊖n (m ℕ.+ n ℕ.* suc m) (m ℕ.+ o ℕ.* suc m) ⟨-[1+ n ] * -[1+ m ] + +[1+ o ] * -[1+ m ] ∎ where open ≡-Reasoning*-distribʳ-+ -[1+ m ] +[1+ n ] -[1+ o ] = begin(+[1+ n ] + -[1+ o ]) * -[1+ m ] ≡⟨ cong (_* -[1+ m ]) ([1+m]⊖[1+n]≡m⊖n n o) ⟩(n ⊖ o) * -[1+ m ] ≡⟨ distrib-lemma m o n ⟩m ℕ.+ o ℕ.* suc m ⊖ (m ℕ.+ n ℕ.* suc m) ≡⟨ [1+m]⊖[1+n]≡m⊖n (m ℕ.+ o ℕ.* suc m) (m ℕ.+ n ℕ.* suc m) ⟨+[1+ n ] * -[1+ m ] + -[1+ o ] * -[1+ m ] ∎ where open ≡-Reasoning*-distribʳ-+ +[1+ m ] -[1+ n ] +[1+ o ] with n ℕ.≤? o... | yes n≤orewrite [1+m]⊖[1+n]≡m⊖n o n| [1+m]⊖[1+n]≡m⊖n (m ℕ.+ o ℕ.* suc m) (m ℕ.+ n ℕ.* suc m)| +-cancelˡ-⊖ m (o ℕ.* suc m) (n ℕ.* suc m)| ⊖-≥ n≤o| +-comm (- (+ (m ℕ.+ n ℕ.* suc m))) (+ (m ℕ.+ o ℕ.* suc m))| ⊖-≥ (ℕ.*-mono-≤ n≤o (ℕ.≤-refl {x = suc m}))| ℕ.*-distribʳ-∸ (suc m) o n| +◃n≡+n (o ℕ.* suc m ∸ n ℕ.* suc m)= refl... | no n≰orewrite [1+m]⊖[1+n]≡m⊖n o n| [1+m]⊖[1+n]≡m⊖n (m ℕ.+ o ℕ.* suc m) (m ℕ.+ n ℕ.* suc m)| +-cancelˡ-⊖ m (o ℕ.* suc m) (n ℕ.* suc m)| sign-⊖-≰ n≰o| ∣⊖∣-≰ n≰o| -◃n≡-n ((n ∸ o) ℕ.* suc m)| ⊖-≰ (n≰o ∘ ℕ.*-cancelʳ-≤ n o (suc m))| ℕ.*-distribʳ-∸ (suc m) n o= refl*-distribʳ-+ +[1+ o ] +[1+ m ] -[1+ n ] with n ℕ.≤? m... | yes n≤mrewrite [1+m]⊖[1+n]≡m⊖n m n| [1+m]⊖[1+n]≡m⊖n (o ℕ.+ m ℕ.* suc o) (o ℕ.+ n ℕ.* suc o)| +-cancelˡ-⊖ o (m ℕ.* suc o) (n ℕ.* suc o)| ⊖-≥ n≤m| ⊖-≥ (ℕ.*-mono-≤ n≤m (ℕ.≤-refl {x = suc o}))| +◃n≡+n ((m ∸ n) ℕ.* suc o)| ℕ.*-distribʳ-∸ (suc o) m n= refl... | no n≰mrewrite [1+m]⊖[1+n]≡m⊖n m n| [1+m]⊖[1+n]≡m⊖n (o ℕ.+ m ℕ.* suc o) (o ℕ.+ n ℕ.* suc o)| +-cancelˡ-⊖ o (m ℕ.* suc o) (n ℕ.* suc o)| sign-⊖-≰ n≰m| ∣⊖∣-≰ n≰m| ⊖-≰ (n≰m ∘ ℕ.*-cancelʳ-≤ n m (suc o))| -◃n≡-n ((n ∸ m) ℕ.* suc o)| ℕ.*-distribʳ-∸ (suc o) n m= refl*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distribˡ-+ = comm∧distrʳ⇒distrˡ *-comm *-distribʳ-+*-distrib-+ : _*_ DistributesOver _+_*-distrib-+ = *-distribˡ-+ , *-distribʳ-+-------------------------------------------------------------------------- Structures*-isMagma : IsMagma _*_*-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _*_}*-isSemigroup : IsSemigroup _*_*-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-isCommutativeSemigroup : IsCommutativeSemigroup _*_*-isCommutativeSemigroup = record{ isSemigroup = *-isSemigroup; comm = *-comm}*-1-isMonoid : IsMonoid _*_ 1ℤ*-1-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1ℤ*-1-isCommutativeMonoid = record{ isMonoid = *-1-isMonoid; comm = *-comm}+-*-isSemiring : IsSemiring _+_ _*_ 0ℤ 1ℤ+-*-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-0-isCommutativeMonoid; *-cong = cong₂ _*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}; zero = *-zero}+-*-isCommutativeSemiring : IsCommutativeSemiring _+_ _*_ 0ℤ 1ℤ+-*-isCommutativeSemiring = record{ isSemiring = +-*-isSemiring; *-comm = *-comm}+-*-isRing : IsRing _+_ _*_ -_ 0ℤ 1ℤ+-*-isRing = record{ +-isAbelianGroup = +-0-isAbelianGroup; *-cong = cong₂ _*_; *-assoc = *-assoc; *-identity = *-identity; distrib = *-distrib-+}+-*-isCommutativeRing : IsCommutativeRing _+_ _*_ -_ 0ℤ 1ℤ+-*-isCommutativeRing = record{ isRing = +-*-isRing; *-comm = *-comm}-------------------------------------------------------------------------- Bundles*-magma : Magma 0ℓ 0ℓ*-magma = record{ isMagma = *-isMagma}*-semigroup : Semigroup 0ℓ 0ℓ*-semigroup = record{ isSemigroup = *-isSemigroup}*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeSemigroup = record{ isCommutativeSemigroup = *-isCommutativeSemigroup}*-1-monoid : Monoid 0ℓ 0ℓ*-1-monoid = record{ isMonoid = *-1-isMonoid}*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-1-commutativeMonoid = record{ isCommutativeMonoid = *-1-isCommutativeMonoid}+-*-semiring : Semiring 0ℓ 0ℓ+-*-semiring = record{ isSemiring = +-*-isSemiring}+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ+-*-commutativeSemiring = record{ isCommutativeSemiring = +-*-isCommutativeSemiring}+-*-ring : Ring 0ℓ 0ℓ+-*-ring = record{ isRing = +-*-isRing}+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ+-*-commutativeRing = record{ isCommutativeRing = +-*-isCommutativeRing}-------------------------------------------------------------------------- Other properties of _*_ and _≡_abs-* : ℤtoℕ.Homomorphic₂ ∣_∣ _*_ ℕ._*_abs-* i j = abs-◃ _ _sign-* : ∀ i j → .{{NonZero (i * j)}} → sign (i * j) ≡ sign i Sign.* sign jsign-* i j rewrite abs-* i j = sign-◃ (sign i Sign.* sign j) (∣ i ∣ ℕ.* ∣ j ∣)*-cancelʳ-≡ : ∀ i j k .{{_ : NonZero k}} → i * k ≡ j * k → i ≡ j*-cancelʳ-≡ i j k eq with sign-cong′ eq... | inj₁ s[ik]≡s[jk] = ◃-cong(Sign.*-cancelʳ-≡ (sign k) (sign i) (sign j) s[ik]≡s[jk])(ℕ.*-cancelʳ-≡ ∣ i ∣ ∣ j ∣ _ (abs-cong eq))... | inj₂ (∣ik∣≡0 , ∣jk∣≡0) = trans(∣i∣≡0⇒i≡0 (ℕ.m*n≡0⇒m≡0 _ _ ∣ik∣≡0))(sym (∣i∣≡0⇒i≡0 (ℕ.m*n≡0⇒m≡0 _ _ ∣jk∣≡0)))*-cancelˡ-≡ : ∀ i j k .{{_ : NonZero i}} → i * j ≡ i * k → j ≡ k*-cancelˡ-≡ i j k rewrite *-comm i j | *-comm i k = *-cancelʳ-≡ j k isuc-* : ∀ i j → sucℤ i * j ≡ j + i * jsuc-* i j = beginsucℤ i * j ≡⟨ *-distribʳ-+ j (+ 1) i ⟩+ 1 * j + i * j ≡⟨ cong (_+ i * j) (*-identityˡ j) ⟩j + i * j ∎where open ≡-Reasoning*-suc : ∀ i j → i * sucℤ j ≡ i + i * j*-suc i j = begini * sucℤ j ≡⟨ *-comm i _ ⟩sucℤ j * i ≡⟨ suc-* j i ⟩i + j * i ≡⟨ cong (λ v → i + v) (*-comm j i) ⟩i + i * j ∎where open ≡-Reasoning-1*i≡-i : ∀ i → -1ℤ * i ≡ - i-1*i≡-i -[1+ n ] = cong +[1+_] (ℕ.+-identityʳ n)-1*i≡-i +0 = refl-1*i≡-i +[1+ n ] = cong -[1+_] (ℕ.+-identityʳ n)i*j≡0⇒i≡0∨j≡0 : ∀ i {j} → i * j ≡ 0ℤ → i ≡ 0ℤ ⊎ j ≡ 0ℤi*j≡0⇒i≡0∨j≡0 i p with ℕ.m*n≡0⇒m≡0∨n≡0 ∣ i ∣ (abs-cong {t = Sign.+} p)... | inj₁ ∣i∣≡0 = inj₁ (∣i∣≡0⇒i≡0 ∣i∣≡0)... | inj₂ ∣j∣≡0 = inj₂ (∣i∣≡0⇒i≡0 ∣j∣≡0)i*j≢0 : ∀ i j .{{_ : NonZero i}} .{{_ : NonZero j}} → NonZero (i * j)i*j≢0 i j rewrite abs-* i j = ℕ.m*n≢0 ∣ i ∣ ∣ j ∣-------------------------------------------------------------------------- Properties of _^_------------------------------------------------------------------------^-identityʳ : ∀ i → i ^ 1 ≡ i^-identityʳ = *-identityʳ^-zeroˡ : ∀ n → 1ℤ ^ n ≡ 1ℤ^-zeroˡ zero = refl^-zeroˡ (suc n) = begin1ℤ ^ suc n ≡⟨⟩1ℤ * (1ℤ ^ n) ≡⟨ *-identityˡ (1ℤ ^ n) ⟩1ℤ ^ n ≡⟨ ^-zeroˡ n ⟩1ℤ ∎where open ≡-Reasoning^-distribˡ-+-* : ∀ i m n → i ^ (m ℕ.+ n) ≡ i ^ m * i ^ n^-distribˡ-+-* i zero n = sym (*-identityˡ (i ^ n))^-distribˡ-+-* i (suc m) n = begini * (i ^ (m ℕ.+ n)) ≡⟨ cong (i *_) (^-distribˡ-+-* i m n) ⟩i * ((i ^ m) * (i ^ n)) ≡⟨ sym (*-assoc i _ _) ⟩(i * (i ^ m)) * (i ^ n) ∎where open ≡-Reasoning^-isMagmaHomomorphism : ∀ i → Morphism.IsMagmaHomomorphism ℕ.+-rawMagma *-rawMagma (i ^_)^-isMagmaHomomorphism i = record{ isRelHomomorphism = record { cong = cong (i ^_) }; homo = ^-distribˡ-+-* i}^-isMonoidHomomorphism : ∀ i → Morphism.IsMonoidHomomorphism ℕ.+-0-rawMonoid *-1-rawMonoid (i ^_)^-isMonoidHomomorphism i = record{ isMagmaHomomorphism = ^-isMagmaHomomorphism i; ε-homo = refl}^-*-assoc : ∀ i m n → (i ^ m) ^ n ≡ i ^ (m ℕ.* n)^-*-assoc i m zero = cong (i ^_) (sym $ ℕ.*-zeroʳ m)^-*-assoc i m (suc n) = begin(i ^ m) * ((i ^ m) ^ n) ≡⟨ cong ((i ^ m) *_) (^-*-assoc i m n) ⟩(i ^ m) * (i ^ (m ℕ.* n)) ≡⟨ sym (^-distribˡ-+-* i m (m ℕ.* n)) ⟩i ^ (m ℕ.+ m ℕ.* n) ≡⟨ cong (i ^_) (sym (ℕ.*-suc m n)) ⟩i ^ (m ℕ.* suc n) ∎where open ≡-Reasoningi^n≡0⇒i≡0 : ∀ i n → i ^ n ≡ 0ℤ → i ≡ 0ℤi^n≡0⇒i≡0 i (suc n) eq = [ id , i^n≡0⇒i≡0 i n ]′ (i*j≡0⇒i≡0∨j≡0 i eq)-------------------------------------------------------------------------- Properties of _*_ and +_/-_pos-* : ℕtoℤ.Homomorphic₂ +_ ℕ._*_ _*_pos-* zero n = reflpos-* (suc m) zero = pos-* m zeropos-* (suc m) (suc n) = reflneg-distribˡ-* : ∀ i j → - (i * j) ≡ (- i) * jneg-distribˡ-* i j = begin- (i * j) ≡⟨ -1*i≡-i (i * j) ⟨-1ℤ * (i * j) ≡⟨ *-assoc -1ℤ i j ⟨-1ℤ * i * j ≡⟨ cong (_* j) (-1*i≡-i i) ⟩- i * j ∎ where open ≡-Reasoningneg-distribʳ-* : ∀ i j → - (i * j) ≡ i * (- j)neg-distribʳ-* i j = begin- (i * j) ≡⟨ cong -_ (*-comm i j) ⟩- (j * i) ≡⟨ neg-distribˡ-* j i ⟩- j * i ≡⟨ *-comm (- j) i ⟩i * (- j) ∎ where open ≡-Reasoning-------------------------------------------------------------------------- Properties of _*_ and _◃_◃-distrib-* : ∀ s t m n → (s Sign.* t) ◃ (m ℕ.* n) ≡ (s ◃ m) * (t ◃ n)◃-distrib-* s t zero zero = refl◃-distrib-* s t zero (suc n) = refl◃-distrib-* s t (suc m) zero =trans(cong₂ _◃_ (Sign.*-comm s t) (ℕ.*-comm m 0))(*-comm (t ◃ zero) (s ◃ suc m))◃-distrib-* s t (suc m) (suc n) =sym (cong₂ _◃_(cong₂ Sign._*_ (sign-◃ s (suc m)) (sign-◃ t (suc n)))(∣s◃m∣*∣t◃n∣≡m*n s t (suc m) (suc n)))-------------------------------------------------------------------------- Properties of _*_ and _≤_*-cancelʳ-≤-pos : ∀ i j k .{{_ : Positive k}} → i * k ≤ j * k → i ≤ j*-cancelʳ-≤-pos -[1+ m ] -[1+ n ] +[1+ o ] (-≤- n≤m) =-≤- (s≤s⁻¹ (ℕ.*-cancelʳ-≤ (suc n) (suc m) (suc o) (s≤s n≤m)))*-cancelʳ-≤-pos -[1+ _ ] (+ _) +[1+ o ] _ = -≤+*-cancelʳ-≤-pos +0 +0 +[1+ o ] _ = +≤+ z≤n*-cancelʳ-≤-pos +0 +[1+ _ ] +[1+ o ] _ = +≤+ z≤n*-cancelʳ-≤-pos +[1+ _ ] +0 +[1+ o ] (+≤+ ())*-cancelʳ-≤-pos +[1+ m ] +[1+ n ] +[1+ o ] (+≤+ m≤n) =+≤+ (ℕ.*-cancelʳ-≤ (suc m) (suc n) (suc o) m≤n)*-cancelˡ-≤-pos : ∀ i j k .{{_ : Positive k}} → k * i ≤ k * j → i ≤ j*-cancelˡ-≤-pos i j k rewrite *-comm k i | *-comm k j = *-cancelʳ-≤-pos i j k*-monoʳ-≤-nonNeg : ∀ i .{{_ : NonNegative i}} → (_* i) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonNeg +0 {i} {j} i≤j rewrite *-zeroʳ i | *-zeroʳ j = +≤+ z≤n*-monoʳ-≤-nonNeg +[1+ n ] (-≤+ {n = 0}) = -≤+*-monoʳ-≤-nonNeg +[1+ n ] (-≤+ {n = suc _}) = -≤+*-monoʳ-≤-nonNeg +[1+ n ] (-≤- n≤m) = -≤- (s≤s⁻¹ (ℕ.*-mono-≤ (s≤s n≤m) (ℕ.≤-refl {x = suc n})))*-monoʳ-≤-nonNeg +[1+ n ] {+0} {+0} (+≤+ m≤n) = +≤+ m≤n*-monoʳ-≤-nonNeg +[1+ n ] {+0} {+[1+ _ ]} (+≤+ m≤n) = +≤+ z≤n*-monoʳ-≤-nonNeg +[1+ n ] {+[1+ _ ]} {+[1+ _ ]} (+≤+ m≤n) = +≤+ (ℕ.*-monoˡ-≤ (suc n) m≤n)*-monoˡ-≤-nonNeg : ∀ i .{{_ : NonNegative i}} → (i *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg i {j} {k} rewrite *-comm i j | *-comm i k = *-monoʳ-≤-nonNeg i*-cancelˡ-≤-neg : ∀ i j k .{{_ : Negative i}} → i * j ≤ i * k → j ≥ k*-cancelˡ-≤-neg i@(-[1+ _ ]) j k ij≤ik = neg-cancel-≤ (*-cancelˡ-≤-pos (- j) (- k) (- i) (begin- i * - j ≡⟨ neg-distribʳ-* (- i) j ⟨-(- i * j) ≡⟨ neg-distribˡ-* (- i) j ⟩i * j ≤⟨ ij≤ik ⟩i * k ≡⟨ neg-distribˡ-* (- i) k ⟨-(- i * k) ≡⟨ neg-distribʳ-* (- i) k ⟩- i * - k ∎))where open ≤-Reasoning*-cancelʳ-≤-neg : ∀ i j k .{{_ : Negative k}} → i * k ≤ j * k → i ≥ j*-cancelʳ-≤-neg i j k rewrite *-comm i k | *-comm j k = *-cancelˡ-≤-neg k i j*-monoˡ-≤-nonPos : ∀ i .{{_ : NonPositive i}} → (i *_) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-nonPos +0 {j} {k} j≤k = +≤+ z≤n*-monoˡ-≤-nonPos i@(-[1+ m ]) {j} {k} j≤k = begini * k ≡⟨ neg-distribˡ-* (- i) k ⟨-(- i * k) ≡⟨ neg-distribʳ-* (- i) k ⟩- i * - k ≤⟨ *-monoˡ-≤-nonNeg (- i) (neg-mono-≤ j≤k) ⟩- i * - j ≡⟨ neg-distribʳ-* (- i) j ⟨-(- i * j) ≡⟨ neg-distribˡ-* (- i) j ⟩i * j ∎where open ≤-Reasoning*-monoʳ-≤-nonPos : ∀ i .{{_ : NonPositive i}} → (_* i) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos i {j} {k} rewrite *-comm k i | *-comm j i = *-monoˡ-≤-nonPos i-------------------------------------------------------------------------- Properties of _*_ and _<_*-monoˡ-<-pos : ∀ i .{{_ : Positive i}} → (i *_) Preserves _<_ ⟶ _<_*-monoˡ-<-pos +[1+ n ] {+ m} {+ o} (+<+ m<o) = +◃-mono-< (ℕ.+-mono-<-≤ m<o (ℕ.*-monoʳ-≤ n (ℕ.<⇒≤ m<o)))*-monoˡ-<-pos +[1+ n ] { -[1+ m ]} {+ o} leq = -◃<+◃ _ (suc n ℕ.* o)*-monoˡ-<-pos +[1+ n ] { -[1+ m ]} { -[1+ o ]} (-<- o<m) = -<- (ℕ.+-mono-<-≤ o<m (ℕ.*-monoʳ-≤ n (ℕ.<⇒≤ (s≤s o<m))))*-monoʳ-<-pos : ∀ i .{{_ : Positive i}} → (_* i) Preserves _<_ ⟶ _<_*-monoʳ-<-pos i {j} {k} rewrite *-comm j i | *-comm k i = *-monoˡ-<-pos i*-cancelˡ-<-nonNeg : ∀ k .{{_ : NonNegative k}} → k * i < k * j → i < j*-cancelˡ-<-nonNeg {+ i} {+ j} (+ n) leq = +<+ (ℕ.*-cancelˡ-< n _ _ (+◃-cancel-< leq))*-cancelˡ-<-nonNeg {+ i} { -[1+ j ]} (+ n) leq = contradiction leq +◃≮-◃*-cancelˡ-<-nonNeg { -[1+ i ]} {+ j} (+ n)leq = -<+*-cancelˡ-<-nonNeg { -[1+ i ]} { -[1+ j ]} (+ n) leq = -<- (s<s⁻¹ (ℕ.*-cancelˡ-< n _ _ (neg◃-cancel-< leq)))*-cancelʳ-<-nonNeg : ∀ k .{{_ : NonNegative k}} → i * k < j * k → i < j*-cancelʳ-<-nonNeg {i} {j} k rewrite *-comm i k | *-comm j k = *-cancelˡ-<-nonNeg k*-monoˡ-<-neg : ∀ i .{{_ : Negative i}} → (i *_) Preserves _<_ ⟶ _>_*-monoˡ-<-neg i@(-[1+ _ ]) {j} {k} j<k = begin-stricti * k ≡⟨ neg-distribˡ-* (- i) k ⟨-(- i * k) ≡⟨ neg-distribʳ-* (- i) k ⟩- i * - k <⟨ *-monoˡ-<-pos (- i) (neg-mono-< j<k) ⟩- i * - j ≡⟨ neg-distribʳ-* (- i) j ⟨- (- i * j) ≡⟨ neg-distribˡ-* (- i) j ⟩i * j ∎where open ≤-Reasoning*-monoʳ-<-neg : ∀ i .{{_ : Negative i}} → (_* i) Preserves _<_ ⟶ _>_*-monoʳ-<-neg i {j} {k} rewrite *-comm k i | *-comm j i = *-monoˡ-<-neg i*-cancelˡ-<-nonPos : ∀ k .{{_ : NonPositive k}} → k * i < k * j → i > j*-cancelˡ-<-nonPos {i} {j} +0 (+<+ ())*-cancelˡ-<-nonPos {i} {j} k@(-[1+ _ ]) ki<kj = neg-cancel-< (*-cancelˡ-<-nonNeg (- k) (begin-strict- k * - i ≡⟨ neg-distribʳ-* (- k) i ⟨-(- k * i) ≡⟨ neg-distribˡ-* (- k) i ⟩k * i <⟨ ki<kj ⟩k * j ≡⟨ neg-distribˡ-* (- k) j ⟨-(- k * j) ≡⟨ neg-distribʳ-* (- k) j ⟩- k * - j ∎))where open ≤-Reasoning*-cancelʳ-<-nonPos : ∀ k .{{_ : NonPositive k}} → i * k < j * k → i > j*-cancelʳ-<-nonPos {i} {j} k rewrite *-comm i k | *-comm j k = *-cancelˡ-<-nonPos k*-cancelˡ-<-neg : ∀ n → -[1+ n ] * i < -[1+ n ] * j → i > j*-cancelˡ-<-neg {i} {j} n = *-cancelˡ-<-nonPos -[1+ n ]*-cancelʳ-<-neg : ∀ n → i * -[1+ n ] < j * -[1+ n ] → i > j*-cancelʳ-<-neg {i} {j} n = *-cancelʳ-<-nonPos -[1+ n ]-------------------------------------------------------------------------- Properties of _*_ and ∣_∣∣i*j∣≡∣i∣*∣j∣ : ∀ i j → ∣ i * j ∣ ≡ ∣ i ∣ ℕ.* ∣ j ∣∣i*j∣≡∣i∣*∣j∣ = abs-*-------------------------------------------------------------------------- Properties of _⊓_ and _⊔_-------------------------------------------------------------------------- Basic specification in terms of _≤_i≤j⇒i⊓j≡i : i ≤ j → i ⊓ j ≡ ii≤j⇒i⊓j≡i (-≤- i≥j) = cong -[1+_] (ℕ.m≥n⇒m⊔n≡m i≥j)i≤j⇒i⊓j≡i -≤+ = refli≤j⇒i⊓j≡i (+≤+ i≤j) = cong +_ (ℕ.m≤n⇒m⊓n≡m i≤j)i≥j⇒i⊓j≡j : i ≥ j → i ⊓ j ≡ ji≥j⇒i⊓j≡j (-≤- i≥j) = cong -[1+_] (ℕ.m≤n⇒m⊔n≡n i≥j)i≥j⇒i⊓j≡j -≤+ = refli≥j⇒i⊓j≡j (+≤+ i≤j) = cong +_ (ℕ.m≥n⇒m⊓n≡n i≤j)i≤j⇒i⊔j≡j : i ≤ j → i ⊔ j ≡ ji≤j⇒i⊔j≡j (-≤- i≥j) = cong -[1+_] (ℕ.m≥n⇒m⊓n≡n i≥j)i≤j⇒i⊔j≡j -≤+ = refli≤j⇒i⊔j≡j (+≤+ i≤j) = cong +_ (ℕ.m≤n⇒m⊔n≡n i≤j)i≥j⇒i⊔j≡i : i ≥ j → i ⊔ j ≡ ii≥j⇒i⊔j≡i (-≤- i≥j) = cong -[1+_] (ℕ.m≤n⇒m⊓n≡m i≥j)i≥j⇒i⊔j≡i -≤+ = refli≥j⇒i⊔j≡i (+≤+ i≤j) = cong +_ (ℕ.m≥n⇒m⊔n≡m i≤j)⊓-operator : MinOperator ≤-totalPreorder⊓-operator = record{ x≤y⇒x⊓y≈x = i≤j⇒i⊓j≡i; x≥y⇒x⊓y≈y = i≥j⇒i⊓j≡j}⊔-operator : MaxOperator ≤-totalPreorder⊔-operator = record{ x≤y⇒x⊔y≈y = i≤j⇒i⊔j≡j; x≥y⇒x⊔y≈x = i≥j⇒i⊔j≡i}-------------------------------------------------------------------------- Automatically derived properties of _⊓_ and _⊔_privatemodule ⊓-⊔-properties = MinMaxOp ⊓-operator ⊔-operatormodule ⊓-⊔-latticeProperties = LatticeMinMaxOp ⊓-operator ⊔-operatoropen ⊓-⊔-properties publicusing( ⊓-idem -- : Idempotent _⊓_; ⊓-sel -- : Selective _⊓_; ⊓-assoc -- : Associative _⊓_; ⊓-comm -- : Commutative _⊓_; ⊔-idem -- : Idempotent _⊔_; ⊔-sel -- : Selective _⊔_; ⊔-assoc -- : Associative _⊔_; ⊔-comm -- : Commutative _⊔_; ⊓-distribˡ-⊔ -- : _⊓_ DistributesOverˡ _⊔_; ⊓-distribʳ-⊔ -- : _⊓_ DistributesOverʳ _⊔_; ⊓-distrib-⊔ -- : _⊓_ DistributesOver _⊔_; ⊔-distribˡ-⊓ -- : _⊔_ DistributesOverˡ _⊓_; ⊔-distribʳ-⊓ -- : _⊔_ DistributesOverʳ _⊓_; ⊔-distrib-⊓ -- : _⊔_ DistributesOver _⊓_; ⊓-absorbs-⊔ -- : _⊓_ Absorbs _⊔_; ⊔-absorbs-⊓ -- : _⊔_ Absorbs _⊓_; ⊔-⊓-absorptive -- : Absorptive _⊔_ _⊓_; ⊓-⊔-absorptive -- : Absorptive _⊓_ _⊔_; ⊓-isMagma -- : IsMagma _⊓_; ⊓-isSemigroup -- : IsSemigroup _⊓_; ⊓-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊓_; ⊓-isBand -- : IsBand _⊓_; ⊓-isSelectiveMagma -- : IsSelectiveMagma _⊓_; ⊔-isMagma -- : IsMagma _⊔_; ⊔-isSemigroup -- : IsSemigroup _⊔_; ⊔-isCommutativeSemigroup -- : IsCommutativeSemigroup _⊔_; ⊔-isBand -- : IsBand _⊔_; ⊔-isSelectiveMagma -- : IsSelectiveMagma _⊔_; ⊓-magma -- : Magma _ _; ⊓-semigroup -- : Semigroup _ _; ⊓-band -- : Band _ _; ⊓-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊓-selectiveMagma -- : SelectiveMagma _ _; ⊔-magma -- : Magma _ _; ⊔-semigroup -- : Semigroup _ _; ⊔-band -- : Band _ _; ⊔-commutativeSemigroup -- : CommutativeSemigroup _ _; ⊔-selectiveMagma -- : SelectiveMagma _ _; ⊓-glb -- : ∀ {m n o} → m ≥ o → n ≥ o → m ⊓ n ≥ o; ⊓-triangulate -- : ∀ m n o → m ⊓ n ⊓ o ≡ (m ⊓ n) ⊓ (n ⊓ o); ⊓-mono-≤ -- : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊓-monoˡ-≤ -- : ∀ n → (_⊓ n) Preserves _≤_ ⟶ _≤_; ⊓-monoʳ-≤ -- : ∀ n → (n ⊓_) Preserves _≤_ ⟶ _≤_; ⊔-lub -- : ∀ {m n o} → m ≤ o → n ≤ o → m ⊔ n ≤ o; ⊔-triangulate -- : ∀ m n o → m ⊔ n ⊔ o ≡ (m ⊔ n) ⊔ (n ⊔ o); ⊔-mono-≤ -- : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_; ⊔-monoˡ-≤ -- : ∀ n → (_⊔ n) Preserves _≤_ ⟶ _≤_; ⊔-monoʳ-≤ -- : ∀ n → (n ⊔_) Preserves _≤_ ⟶ _≤_)renaming( x⊓y≈y⇒y≤x to i⊓j≡j⇒j≤i -- : ∀ {i j} → i ⊓ j ≡ j → j ≤ i; x⊓y≈x⇒x≤y to i⊓j≡i⇒i≤j -- : ∀ {i j} → i ⊓ j ≡ i → i ≤ j; x⊓y≤x to i⊓j≤i -- : ∀ i j → i ⊓ j ≤ i; x⊓y≤y to i⊓j≤j -- : ∀ i j → i ⊓ j ≤ j; x≤y⇒x⊓z≤y to i≤j⇒i⊓k≤j -- : ∀ {i j} k → i ≤ j → i ⊓ k ≤ j; x≤y⇒z⊓x≤y to i≤j⇒k⊓i≤j -- : ∀ {i j} k → i ≤ j → k ⊓ i ≤ j; x≤y⊓z⇒x≤y to i≤j⊓k⇒i≤j -- : ∀ {i} j k → i ≤ j ⊓ k → i ≤ j; x≤y⊓z⇒x≤z to i≤j⊓k⇒i≤k -- : ∀ {i} j k → i ≤ j ⊓ k → i ≤ k; x⊔y≈y⇒x≤y to i⊔j≡j⇒i≤j -- : ∀ {i j} → i ⊔ j ≡ j → i ≤ j; x⊔y≈x⇒y≤x to i⊔j≡i⇒j≤i -- : ∀ {i j} → i ⊔ j ≡ i → j ≤ i; x≤x⊔y to i≤i⊔j -- : ∀ i j → i ≤ i ⊔ j; x≤y⊔x to i≤j⊔i -- : ∀ i j → i ≤ j ⊔ i; x≤y⇒x≤y⊔z to i≤j⇒i≤j⊔k -- : ∀ {i j} k → i ≤ j → i ≤ j ⊔ k; x≤y⇒x≤z⊔y to i≤j⇒i≤k⊔j -- : ∀ {i j} k → i ≤ j → i ≤ k ⊔ j; x⊔y≤z⇒x≤z to i⊔j≤k⇒i≤k -- : ∀ i j {k} → i ⊔ j ≤ k → i ≤ k; x⊔y≤z⇒y≤z to i⊔j≤k⇒j≤k -- : ∀ i j {k} → i ⊔ j ≤ k → j ≤ k; x⊓y≤x⊔y to i⊓j≤i⊔j -- : ∀ i j → i ⊓ j ≤ i ⊔ j)open ⊓-⊔-latticeProperties publicusing( ⊓-isSemilattice -- : IsSemilattice _⊓_; ⊔-isSemilattice -- : IsSemilattice _⊔_; ⊔-⊓-isLattice -- : IsLattice _⊔_ _⊓_; ⊓-⊔-isLattice -- : IsLattice _⊓_ _⊔_; ⊔-⊓-isDistributiveLattice -- : IsDistributiveLattice _⊔_ _⊓_; ⊓-⊔-isDistributiveLattice -- : IsDistributiveLattice _⊓_ _⊔_; ⊓-semilattice -- : Semilattice _ _; ⊔-semilattice -- : Semilattice _ _; ⊔-⊓-lattice -- : Lattice _ _; ⊓-⊔-lattice -- : Lattice _ _; ⊔-⊓-distributiveLattice -- : DistributiveLattice _ _; ⊓-⊔-distributiveLattice -- : DistributiveLattice _ _)-------------------------------------------------------------------------- Other properties of _⊓_ and _⊔_mono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ i j → f (i ⊔ j) ≡ f i ⊔ f jmono-≤-distrib-⊔ {f} = ⊓-⊔-properties.mono-≤-distrib-⊔ (cong f)mono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≤_ →∀ i j → f (i ⊓ j) ≡ f i ⊓ f jmono-≤-distrib-⊓ {f} = ⊓-⊔-properties.mono-≤-distrib-⊓ (cong f)antimono-≤-distrib-⊓ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ i j → f (i ⊓ j) ≡ f i ⊔ f jantimono-≤-distrib-⊓ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊓ (cong f)antimono-≤-distrib-⊔ : ∀ {f} → f Preserves _≤_ ⟶ _≥_ →∀ i j → f (i ⊔ j) ≡ f i ⊓ f jantimono-≤-distrib-⊔ {f} = ⊓-⊔-properties.antimono-≤-distrib-⊔ (cong f)mono-<-distrib-⊓ : ∀ f → f Preserves _<_ ⟶ _<_ → ∀ i j → f (i ⊓ j) ≡ f i ⊓ f jmono-<-distrib-⊓ f f-mono-< i j with <-cmp i j... | tri< i<j _ _ = trans (cong f (i≤j⇒i⊓j≡i (<⇒≤ i<j))) (sym (i≤j⇒i⊓j≡i (<⇒≤ (f-mono-< i<j))))... | tri≈ _ refl _ = trans (cong f (i≤j⇒i⊓j≡i ≤-refl)) (sym (i≤j⇒i⊓j≡i ≤-refl))... | tri> _ _ i>j = trans (cong f (i≥j⇒i⊓j≡j (<⇒≤ i>j))) (sym (i≥j⇒i⊓j≡j (<⇒≤ (f-mono-< i>j))))mono-<-distrib-⊔ : ∀ f → f Preserves _<_ ⟶ _<_ → ∀ i j → f (i ⊔ j) ≡ f i ⊔ f jmono-<-distrib-⊔ f f-mono-< i j with <-cmp i j... | tri< i<j _ _ = trans (cong f (i≤j⇒i⊔j≡j (<⇒≤ i<j))) (sym (i≤j⇒i⊔j≡j (<⇒≤ (f-mono-< i<j))))... | tri≈ _ refl _ = trans (cong f (i≤j⇒i⊔j≡j ≤-refl)) (sym (i≤j⇒i⊔j≡j ≤-refl))... | tri> _ _ i>j = trans (cong f (i≥j⇒i⊔j≡i (<⇒≤ i>j))) (sym (i≥j⇒i⊔j≡i (<⇒≤ (f-mono-< i>j))))antimono-<-distrib-⊔ : ∀ f → f Preserves _<_ ⟶ _>_ → ∀ i j → f (i ⊔ j) ≡ f i ⊓ f jantimono-<-distrib-⊔ f f-mono-< i j with <-cmp i j... | tri< i<j _ _ = trans (cong f (i≤j⇒i⊔j≡j (<⇒≤ i<j))) (sym (i≥j⇒i⊓j≡j (<⇒≤ (f-mono-< i<j))))... | tri≈ _ refl _ = trans (cong f (i≤j⇒i⊔j≡j ≤-refl)) (sym (i≥j⇒i⊓j≡j ≤-refl))... | tri> _ _ i>j = trans (cong f (i≥j⇒i⊔j≡i (<⇒≤ i>j))) (sym (i≤j⇒i⊓j≡i (<⇒≤ (f-mono-< i>j))))antimono-<-distrib-⊓ : ∀ f → f Preserves _<_ ⟶ _>_ → ∀ i j → f (i ⊓ j) ≡ f i ⊔ f jantimono-<-distrib-⊓ f f-mono-< i j with <-cmp i j... | tri< i<j _ _ = trans (cong f (i≤j⇒i⊓j≡i (<⇒≤ i<j))) (sym (i≥j⇒i⊔j≡i (<⇒≤ (f-mono-< i<j))))... | tri≈ _ refl _ = trans (cong f (i≤j⇒i⊓j≡i ≤-refl)) (sym (i≥j⇒i⊔j≡i ≤-refl))... | tri> _ _ i>j = trans (cong f (i≥j⇒i⊓j≡j (<⇒≤ i>j))) (sym (i≤j⇒i⊔j≡j (<⇒≤ (f-mono-< i>j))))-------------------------------------------------------------------------- Other properties of _⊓_, _⊔_ and -_neg-distrib-⊔-⊓ : ∀ i j → - (i ⊔ j) ≡ - i ⊓ - jneg-distrib-⊔-⊓ = antimono-<-distrib-⊔ -_ neg-mono-<neg-distrib-⊓-⊔ : ∀ i j → - (i ⊓ j) ≡ - i ⊔ - jneg-distrib-⊓-⊔ = antimono-<-distrib-⊓ -_ neg-mono-<-------------------------------------------------------------------------- Other properties of _⊓_, _⊔_ and _*_*-distribˡ-⊓-nonNeg : ∀ i j k .{{_ : NonNegative i}} →i * (j ⊓ k) ≡ (i * j) ⊓ (i * k)*-distribˡ-⊓-nonNeg i j k = mono-≤-distrib-⊓ (*-monoˡ-≤-nonNeg i) j k*-distribʳ-⊓-nonNeg : ∀ i j k .{{_ : NonNegative i}} →(j ⊓ k) * i ≡ (j * i) ⊓ (k * i)*-distribʳ-⊓-nonNeg i j k = mono-≤-distrib-⊓ (*-monoʳ-≤-nonNeg i) j k*-distribˡ-⊓-nonPos : ∀ i j k .{{_ : NonPositive i}} →i * (j ⊓ k) ≡ (i * j) ⊔ (i * k)*-distribˡ-⊓-nonPos i j k = antimono-≤-distrib-⊓ (*-monoˡ-≤-nonPos i) j k*-distribʳ-⊓-nonPos : ∀ i j k .{{_ : NonPositive i}} →(j ⊓ k) * i ≡ (j * i) ⊔ (k * i)*-distribʳ-⊓-nonPos i j k = antimono-≤-distrib-⊓ (*-monoʳ-≤-nonPos i) j k*-distribˡ-⊔-nonNeg : ∀ i j k .{{_ : NonNegative i}} →i * (j ⊔ k) ≡ (i * j) ⊔ (i * k)*-distribˡ-⊔-nonNeg i j k = mono-≤-distrib-⊔ (*-monoˡ-≤-nonNeg i) j k*-distribʳ-⊔-nonNeg : ∀ i j k .{{_ : NonNegative i}} →(j ⊔ k) * i ≡ (j * i) ⊔ (k * i)*-distribʳ-⊔-nonNeg i j k = mono-≤-distrib-⊔ (*-monoʳ-≤-nonNeg i) j k*-distribˡ-⊔-nonPos : ∀ i j k .{{_ : NonPositive i}} →i * (j ⊔ k) ≡ (i * j) ⊓ (i * k)*-distribˡ-⊔-nonPos i j k = antimono-≤-distrib-⊔ (*-monoˡ-≤-nonPos i) j k*-distribʳ-⊔-nonPos : ∀ i j k .{{_ : NonPositive i}} →(j ⊔ k) * i ≡ (j * i) ⊓ (k * i)*-distribʳ-⊔-nonPos i j k = antimono-≤-distrib-⊔ (*-monoʳ-≤-nonPos i) j k-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.5neg-mono-<-> = neg-mono-<{-# WARNING_ON_USAGE neg-mono-<->"Warning: neg-mono-<-> was deprecated in v1.5.Please use neg-mono-< instead."#-}neg-mono-≤-≥ = neg-mono-≤{-# WARNING_ON_USAGE neg-mono-≤-≥"Warning: neg-mono-≤-≥ was deprecated in v1.5.Please use neg-mono-≤ instead."#-}*-monoʳ-≤-non-neg = *-monoʳ-≤-nonNeg{-# WARNING_ON_USAGE *-monoʳ-≤-non-neg"Warning: *-monoʳ-≤-non-neg was deprecated in v1.5.Please use *-monoʳ-≤-nonNeg instead."#-}*-monoˡ-≤-non-neg = *-monoˡ-≤-nonNeg{-# WARNING_ON_USAGE *-monoˡ-≤-non-neg"Warning: *-monoˡ-≤-non-neg deprecated in v1.5.Please use *-monoˡ-≤-nonNeg instead."#-}*-cancelˡ-<-non-neg = *-cancelˡ-<-nonNeg{-# WARNING_ON_USAGE *-cancelˡ-<-non-neg"Warning: *-cancelˡ-<-non-neg was deprecated in v1.5.Please use *-cancelˡ-<-nonNeg instead."#-}*-cancelʳ-<-non-neg = *-cancelʳ-<-nonNeg{-# WARNING_ON_USAGE *-cancelʳ-<-non-neg"Warning: *-cancelʳ-<-non-neg was deprecated in v1.5.Please use *-cancelʳ-<-nonNeg instead."#-}-- Version 1.6m≤n⇒m⊓n≡m = i≤j⇒i⊓j≡i{-# WARNING_ON_USAGE m≤n⇒m⊓n≡m"Warning: m≤n⇒m⊓n≡m was deprecated in v1.6Please use i≤j⇒i⊓j≡i instead."#-}m⊓n≡m⇒m≤n = i⊓j≡i⇒i≤j{-# WARNING_ON_USAGE m⊓n≡m⇒m≤n"Warning: m≤n⇒m⊓n≡m was deprecated in v1.6Please use i⊓j≡i⇒i≤j instead."#-}m≥n⇒m⊓n≡n = i≥j⇒i⊓j≡j{-# WARNING_ON_USAGE m≥n⇒m⊓n≡n"Warning: m≥n⇒m⊓n≡n was deprecated in v1.6Please use i≥j⇒i⊓j≡j instead."#-}m⊓n≡n⇒m≥n = i⊓j≡j⇒j≤i{-# WARNING_ON_USAGE m⊓n≡n⇒m≥n"Warning: m⊓n≡n⇒m≥n was deprecated in v1.6Please use i⊓j≡j⇒j≤i instead."#-}m⊓n≤n = i⊓j≤j{-# WARNING_ON_USAGE m⊓n≤n"Warning: m⊓n≤n was deprecated in v1.6Please use i⊓j≤j instead."#-}m⊓n≤m = i⊓j≤i{-# WARNING_ON_USAGE m⊓n≤m"Warning: m⊓n≤m was deprecated in v1.6Please use i⊓j≤i instead."#-}m≤n⇒m⊔n≡n = i≤j⇒i⊔j≡j{-# WARNING_ON_USAGE m≤n⇒m⊔n≡n"Warning: m≤n⇒m⊔n≡n was deprecated in v1.6Please use i≤j⇒i⊔j≡j instead."#-}m⊔n≡n⇒m≤n = i⊔j≡j⇒i≤j{-# WARNING_ON_USAGE m⊔n≡n⇒m≤n"Warning: m⊔n≡n⇒m≤n was deprecated in v1.6Please use i⊔j≡j⇒i≤j instead."#-}m≥n⇒m⊔n≡m = i≥j⇒i⊔j≡i{-# WARNING_ON_USAGE m≥n⇒m⊔n≡m"Warning: m≥n⇒m⊔n≡m was deprecated in v1.6Please use i≥j⇒i⊔j≡i instead."#-}m⊔n≡m⇒m≥n = i⊔j≡i⇒j≤i{-# WARNING_ON_USAGE m⊔n≡m⇒m≥n"Warning: m⊔n≡m⇒m≥n was deprecated in v1.6Please use i⊔j≡i⇒j≤i instead."#-}m≤m⊔n = i≤i⊔j{-# WARNING_ON_USAGE m≤m⊔n"Warning: m≤m⊔n was deprecated in v1.6Please use i≤i⊔j instead."#-}n≤m⊔n = i≤j⊔i{-# WARNING_ON_USAGE n≤m⊔n"Warning: n≤m⊔n was deprecated in v1.6Please use i≤j⊔i instead."#-}-- Version 2.0+-pos-monoʳ-≤ : ∀ n → (_+_ (+ n)) Preserves _≤_ ⟶ _≤_+-pos-monoʳ-≤ n {_} (-≤- o≤m) = ⊖-monoʳ-≥-≤ n (s≤s o≤m)+-pos-monoʳ-≤ n { -[1+ m ]} -≤+ = ≤-trans (m⊖n≤m n (suc m)) (+≤+ (ℕ.m≤m+n n _))+-pos-monoʳ-≤ n {_} (+≤+ m≤o) = +≤+ (ℕ.+-monoʳ-≤ n m≤o){-# WARNING_ON_USAGE +-pos-monoʳ-≤"Warning: +-pos-monoʳ-≤ was deprecated in v2.0Please use +-monoʳ-≤ instead."#-}+-neg-monoʳ-≤ : ∀ n → (_+_ (-[1+ n ])) Preserves _≤_ ⟶ _≤_+-neg-monoʳ-≤ n {_} {_} (-≤- n≤m) = -≤- (ℕ.+-monoʳ-≤ (suc n) n≤m)+-neg-monoʳ-≤ n {_} {+ m} -≤+ = ≤-trans (-≤- (ℕ.m≤m+n (suc n) _)) (-1+m≤n⊖m (suc n) m)+-neg-monoʳ-≤ n {_} {_} (+≤+ m≤n) = ⊖-monoˡ-≤ (suc n) m≤n{-# WARNING_ON_USAGE +-neg-monoʳ-≤"Warning: +-neg-monoʳ-≤ was deprecated in v2.0Please use +-monoʳ-≤ instead."#-}n≮n = i≮i{-# WARNING_ON_USAGE n≮n"Warning: n≮n was deprecated in v2.0Please use i≮i instead."#-}∣n∣≡0⇒n≡0 = ∣i∣≡0⇒i≡0{-# WARNING_ON_USAGE ∣n∣≡0⇒n≡0"Warning: ∣n∣≡0⇒n≡0 was deprecated in v2.0Please use ∣i∣≡0⇒i≡0 instead."#-}∣-n∣≡∣n∣ = ∣-i∣≡∣i∣{-# WARNING_ON_USAGE ∣-n∣≡∣n∣"Warning: ∣-n∣≡∣n∣ was deprecated in v2.0Please use ∣-i∣≡∣i∣ instead."#-}0≤n⇒+∣n∣≡n = 0≤i⇒+∣i∣≡i{-# WARNING_ON_USAGE 0≤n⇒+∣n∣≡n"Warning: 0≤n⇒+∣n∣≡n was deprecated in v2.0Please use 0≤i⇒+∣i∣≡i instead."#-}+∣n∣≡n⇒0≤n = +∣i∣≡i⇒0≤i{-# WARNING_ON_USAGE +∣n∣≡n⇒0≤n"Warning: +∣n∣≡n⇒0≤n was deprecated in v2.0Please use +∣i∣≡i⇒0≤i instead."#-}+∣n∣≡n⊎+∣n∣≡-n = +∣i∣≡i⊎+∣i∣≡-i{-# WARNING_ON_USAGE +∣n∣≡n⊎+∣n∣≡-n"Warning: +∣n∣≡n⊎+∣n∣≡-n was deprecated in v2.0Please use +∣i∣≡i⊎+∣i∣≡-i instead."#-}∣m+n∣≤∣m∣+∣n∣ = ∣i+j∣≤∣i∣+∣j∣{-# WARNING_ON_USAGE ∣m+n∣≤∣m∣+∣n∣"Warning: ∣m+n∣≤∣m∣+∣n∣ was deprecated in v2.0Please use ∣i+j∣≤∣i∣+∣j∣ instead."#-}∣m-n∣≤∣m∣+∣n∣ = ∣i-j∣≤∣i∣+∣j∣{-# WARNING_ON_USAGE ∣m-n∣≤∣m∣+∣n∣"Warning: ∣m-n∣≤∣m∣+∣n∣ was deprecated in v2.0Please use ∣i-j∣≤∣i∣+∣j∣ instead."#-}signₙ◃∣n∣≡n = signᵢ◃∣i∣≡i{-# WARNING_ON_USAGE signₙ◃∣n∣≡n"Warning: signₙ◃∣n∣≡n was deprecated in v2.0Please use signᵢ◃∣i∣≡i instead."#-}◃-≡ = ◃-cong{-# WARNING_ON_USAGE ◃-≡"Warning: ◃-≡ was deprecated in v2.0Please use ◃-cong instead."#-}∣m-n∣≡∣n-m∣ = ∣i-j∣≡∣j-i∣{-# WARNING_ON_USAGE ∣m-n∣≡∣n-m∣"Warning: ∣m-n∣≡∣n-m∣ was deprecated in v2.0Please use ∣i-j∣≡∣j-i∣ instead."#-}m≡n⇒m-n≡0 = i≡j⇒i-j≡0{-# WARNING_ON_USAGE m≡n⇒m-n≡0"Warning: m≡n⇒m-n≡0 was deprecated in v2.0Please use i≡j⇒i-j≡0 instead."#-}m-n≡0⇒m≡n = i-j≡0⇒i≡j{-# WARNING_ON_USAGE m-n≡0⇒m≡n"Warning: m-n≡0⇒m≡n was deprecated in v2.0Please use i-j≡0⇒i≡j instead."#-}≤-steps = i≤j⇒i≤k+j{-# WARNING_ON_USAGE ≤-steps"Warning: ≤-steps was deprecated in v2.0Please use i≤j⇒i≤k+j instead."#-}≤-steps-neg = i≤j⇒i-k≤j{-# WARNING_ON_USAGE ≤-steps-neg"Warning: ≤-steps-neg was deprecated in v2.0Please use i≤j⇒i-k≤j instead."#-}≤-step = i≤j⇒i≤1+j{-# WARNING_ON_USAGE ≤-step"Warning: ≤-step was deprecated in v2.0Please use i≤j⇒i≤1+j instead."#-}≤-step-neg = i≤j⇒pred[i]≤j{-# WARNING_ON_USAGE ≤-step-neg"Warning: ≤-step-neg was deprecated in v2.0Please use i≤j⇒pred[i]≤j instead."#-}m≤n⇒m-n≤0 = i≤j⇒i-j≤0{-# WARNING_ON_USAGE m≤n⇒m-n≤0"Warning: m≤n⇒m-n≤0 was deprecated in v2.0Please use i≤j⇒i-j≤0 instead."#-}m-n≤0⇒m≤n = i-j≤0⇒i≤j{-# WARNING_ON_USAGE m-n≤0⇒m≤n"Warning: m-n≤0⇒m≤n was deprecated in v2.0Please use i-j≤0⇒i≤j instead."#-}m≤n⇒0≤n-m = i≤j⇒0≤j-i{-# WARNING_ON_USAGE m≤n⇒0≤n-m"Warning: m≤n⇒0≤n-m was deprecated in v2.0Please use i≤j⇒0≤j-i instead."#-}0≤n-m⇒m≤n = 0≤i-j⇒j≤i{-# WARNING_ON_USAGE 0≤n-m⇒m≤n"Warning: 0≤n-m⇒m≤n was deprecated in v2.0Please use 0≤i-j⇒j≤i instead."#-}n≤1+n = i≤suc[i]{-# WARNING_ON_USAGE n≤1+n"Warning: n≤1+n was deprecated in v2.0Please use i≤suc[i] instead."#-}n≢1+n = i≢suc[i]{-# WARNING_ON_USAGE n≢1+n"Warning: n≢1+n was deprecated in v2.0Please use i≢suc[i] instead."#-}m≤pred[n]⇒m<n = i≤pred[j]⇒i<j{-# WARNING_ON_USAGE m≤pred[n]⇒m<n"Warning: m≤pred[n]⇒m<n was deprecated in v2.0Please use i≤pred[j]⇒i<j instead."#-}m<n⇒m≤pred[n] = i<j⇒i≤pred[j]{-# WARNING_ON_USAGE m<n⇒m≤pred[n]"Warning: m<n⇒m≤pred[n] was deprecated in v2.0Please use i<j⇒i≤pred[j] instead."#-}-1*n≡-n = -1*i≡-i{-# WARNING_ON_USAGE -1*n≡-n"Warning: -1*n≡-n was deprecated in v2.0Please use -1*i≡-i instead."#-}m*n≡0⇒m≡0∨n≡0 = i*j≡0⇒i≡0∨j≡0{-# WARNING_ON_USAGE m*n≡0⇒m≡0∨n≡0"Warning: m*n≡0⇒m≡0∨n≡0 was deprecated in v2.0Please use i*j≡0⇒i≡0∨j≡0 instead."#-}∣m*n∣≡∣m∣*∣n∣ = ∣i*j∣≡∣i∣*∣j∣{-# WARNING_ON_USAGE ∣m*n∣≡∣m∣*∣n∣"Warning: ∣m*n∣≡∣m∣*∣n∣ was deprecated in v2.0Please use ∣i*j∣≡∣i∣*∣j∣ instead."#-}n≤m+n : ∀ n → i ≤ + n + in≤m+n {i} n = i≤j+i i (+ n){-# WARNING_ON_USAGE n≤m+n"Warning: n≤m+n was deprecated in v2.0Please use i≤j+i instead. Note the change of form of the explicit arguments."#-}m≤m+n : ∀ n → i ≤ i + + nm≤m+n {i} n = i≤i+j i (+ n){-# WARNING_ON_USAGE m≤m+n"Warning: m≤m+n was deprecated in v2.0Please use i≤i+j instead. Note the change of form of the explicit arguments."#-}m-n≤m : ∀ i n → i - + n ≤ im-n≤m i n = i-j≤i i (+ n){-# WARNING_ON_USAGE m-n≤m"Warning: m-n≤m was deprecated in v2.0Please use i-j≤i instead. Note the change of form of the explicit arguments."#-}*-monoʳ-≤-pos : ∀ n → (_* + suc n) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-pos n = *-monoʳ-≤-nonNeg +[1+ n ]{-# WARNING_ON_USAGE *-monoʳ-≤-pos"Warning: *-monoʳ-≤-pos was deprecated in v2.0Please use *-monoʳ-≤-nonNeg instead."#-}*-monoˡ-≤-pos : ∀ n → (+ suc n *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-pos n = *-monoˡ-≤-nonNeg +[1+ n ]{-# WARNING_ON_USAGE *-monoˡ-≤-pos"Warning: *-monoˡ-≤-pos was deprecated in v2.0Please use *-monoˡ-≤-nonNeg instead."#-}*-monoˡ-≤-neg : ∀ m → (-[1+ m ] *_) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg m = *-monoˡ-≤-nonPos -[1+ m ]{-# WARNING_ON_USAGE *-monoˡ-≤-neg"Warning: *-monoˡ-≤-neg was deprecated in v2.0Please use *-monoˡ-≤-nonPos instead."#-}*-monoʳ-≤-neg : ∀ m → (_* -[1+ m ]) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-neg m = *-monoʳ-≤-nonPos -[1+ m ]{-# WARNING_ON_USAGE *-monoʳ-≤-neg"Warning: *-monoʳ-≤-neg was deprecated in v2.0Please use *-monoʳ-≤-nonPos instead."#-}pos-+-commute : ℕtoℤ.Homomorphic₂ +_ ℕ._+_ _+_pos-+-commute = pos-+{-# WARNING_ON_USAGE pos-+-commute"Warning: pos-+-commute was deprecated in v2.0Please use pos-+ instead."#-}abs-*-commute : ℤtoℕ.Homomorphic₂ ∣_∣ _*_ ℕ._*_abs-*-commute = abs-*{-# WARNING_ON_USAGE abs-*-commute"Warning: abs-*-commute was deprecated in v2.0Please use abs-* instead."#-}pos-distrib-* : ∀ m n → (+ m) * (+ n) ≡ + (m ℕ.* n)pos-distrib-* m n = sym (pos-* m n){-# WARNING_ON_USAGE pos-distrib-*"Warning: pos-distrib-* was deprecated in v2.0Please use pos-* instead."#-}+-isAbelianGroup = +-0-isAbelianGroup{-# WARNING_ON_USAGE +-isAbelianGroup"Warning: +-isAbelianGroup was deprecated in v2.0Please use +-0-isAbelianGroup instead."#-}{- issue1844/issue1755: raw bundles have moved to `Data.X.Base` -}open Data.Integer.Base publicusing (*-rawMagma; *-1-rawMonoid)
-------------------------------------------------------------------------- The Agda standard library---- Some extra lemmas about natural numbers only needed for-- Data.Integer.Properties (for distributivity)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Properties.NatLemmas whereopen import Data.Nat.Base using (ℕ; _+_; _*_; suc)open import Data.Nat.Propertiesusing (*-distribʳ-+; *-assoc; +-assoc; +-comm; +-suc)open import Function.Base using (_∘_)open import Relation.Binary.PropositionalEqualityusing (_≡_; cong; cong₂; sym; module ≡-Reasoning)open ≡-Reasoninginner-assoc : ∀ m n o → o + (n + m * suc n) * suc o≡ o + n * suc o + m * suc (o + n * suc o)inner-assoc m n o = begino + (n + m * suc n) * suc o ≡⟨ cong (o +_) (begin(n + m * suc n) * suc o ≡⟨ *-distribʳ-+ (suc o) n (m * suc n) ⟩n * suc o + m * suc n * suc o ≡⟨ cong (n * suc o +_) (*-assoc m (suc n) (suc o)) ⟩n * suc o + m * suc (o + n * suc o) ∎) ⟩o + (n * suc o + m * suc (o + n * suc o)) ≡⟨ +-assoc o _ _ ⟨o + n * suc o + m * suc (o + n * suc o) ∎privateassoc-comm : ∀ a b c d → a + b + c + d ≡ (a + c) + (b + d)assoc-comm a b c d = begina + b + c + d ≡⟨ cong (_+ d) (+-assoc a b c) ⟩a + (b + c) + d ≡⟨ cong (λ z → a + z + d) (+-comm b c) ⟩a + (c + b) + d ≡⟨ cong (_+ d) (+-assoc a c b) ⟨(a + c) + b + d ≡⟨ +-assoc (a + c) b d ⟩(a + c) + (b + d) ∎assoc-comm′ : ∀ a b c d → a + (b + (c + d)) ≡ a + c + (b + d)assoc-comm′ a b c d = begina + (b + (c + d)) ≡⟨ cong (a +_) (+-assoc b c d) ⟨a + (b + c + d) ≡⟨ cong (λ z → a + (z + d)) (+-comm b c) ⟩a + (c + b + d) ≡⟨ cong (a +_) (+-assoc c b d) ⟩a + (c + (b + d)) ≡⟨ +-assoc a c _ ⟨a + c + (b + d) ∎assoc₁ : ∀ m n o → (2 + n + o) * (1 + m) ≡ (1 + n) * (1 + m) + (1 + o) * (1 + m)assoc₁ m n o = begin(2 + n + o) * (1 + m) ≡⟨ cong (_* (1 + m)) (assoc-comm 1 1 n o) ⟩((1 + n) + (1 + o)) * (1 + m) ≡⟨ *-distribʳ-+ (1 + m) (1 + n) (1 + o) ⟩(1 + n) * (1 + m) + (1 + o) * (1 + m) ∎assoc₂ : ∀ m n o → (1 + n + (1 + o)) * (1 + m) ≡ (1 + n) * (1 + m) + (1 + o) * (1 + m)assoc₂ m n o = *-distribʳ-+ (1 + m) (1 + n) (1 + o)assoc₃ : ∀ m n o → m + (n + (1 + o)) * (1 + m) ≡ (1 + n) * (1 + m) + (m + o * (1 + m))assoc₃ m n o = beginm + (n + (1 + o)) * (1 + m) ≡⟨ cong (m +_) (*-distribʳ-+ (1 + m) n (1 + o)) ⟩m + (n * (1 + m) + (1 + o) * (1 + m)) ≡⟨ +-assoc m _ _ ⟨(m + n * (1 + m)) + (1 + o) * (1 + m) ≡⟨ +-suc _ _ ⟩(1 + n) * (1 + m) + (m + o * (1 + m)) ∎assoc₄ : ∀ m n o → m + (1 + m + (n + o) * (1 + m)) ≡ (1 + n) * (1 + m) + (m + o * (1 + m))assoc₄ m n o = beginm + (1 + m + (n + o) * (1 + m)) ≡⟨ +-suc _ _ ⟩1 + m + (m + (n + o) * (1 + m)) ≡⟨ cong (λ z → suc (m + (m + z))) (*-distribʳ-+ (suc m) n o) ⟩1 + m + (m + (n * (1 + m) + o * (1 + m))) ≡⟨ cong suc (assoc-comm′ m m _ _) ⟩(1 + n) * (1 + m) + (m + o * (1 + m)) ∎
-------------------------------------------------------------------------- The Agda standard library---- Integer Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Agda.Builtin.FromNeg using (Negative)open import Data.Unit.Base using (⊤)open import Data.Integer.Base using (ℤ; -_; +_)number : Number ℤnumber = record{ Constraint = λ _ → ⊤; fromNat = λ n → + n}negative : Negative ℤnegative = record{ Constraint = λ _ → ⊤; fromNeg = λ n → - (+ n)}
-------------------------------------------------------------------------- The Agda standard library---- Least Common Multiple for integers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.LCM whereopen import Data.Integer.Baseopen import Data.Integer.Divisibilityopen import Data.Integer.GCDimport Data.Nat.LCM as ℕopen import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)-------------------------------------------------------------------------- Definition------------------------------------------------------------------------lcm : ℤ → ℤ → ℤlcm i j = + ℕ.lcm ∣ i ∣ ∣ j ∣-------------------------------------------------------------------------- Properties------------------------------------------------------------------------i∣lcm[i,j] : ∀ i j → i ∣ lcm i ji∣lcm[i,j] i j = ℕ.m∣lcm[m,n] ∣ i ∣ ∣ j ∣j∣lcm[i,j] : ∀ i j → j ∣ lcm i jj∣lcm[i,j] i j = ℕ.n∣lcm[m,n] ∣ i ∣ ∣ j ∣lcm-least : ∀ {i j c} → i ∣ c → j ∣ c → lcm i j ∣ clcm-least c∣i c∣j = ℕ.lcm-least c∣i c∣jlcm[0,i]≡0 : ∀ i → lcm 0ℤ i ≡ 0ℤlcm[0,i]≡0 i = cong (+_) (ℕ.lcm[0,n]≡0 ∣ i ∣)lcm[i,0]≡0 : ∀ i → lcm i 0ℤ ≡ 0ℤlcm[i,0]≡0 i = cong (+_) (ℕ.lcm[n,0]≡0 ∣ i ∣)lcm-comm : ∀ i j → lcm i j ≡ lcm j ilcm-comm i j = cong (+_) (ℕ.lcm-comm ∣ i ∣ ∣ j ∣)
-------------------------------------------------------------------------- The Agda standard library---- Instances for integers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Instances whereopen import Data.Integer.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceℤ-≡-isDecEquivalence = isDecEquivalence _≟_ℤ-≤-isDecTotalOrder = ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Greatest Common Divisor for integers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.GCD whereopen import Data.Integer.Baseopen import Data.Integer.Divisibilityopen import Data.Integer.Propertiesimport Data.Nat.GCD as ℕopen import Data.Product.Base using (_,_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)open import Algebra.Definitions {A = ℤ} _≡_ as Algebrausing (Associative; Commutative; LeftIdentity; RightIdentity; LeftZero; RightZero; Zero)-------------------------------------------------------------------------- Definition------------------------------------------------------------------------gcd : ℤ → ℤ → ℤgcd i j = + ℕ.gcd ∣ i ∣ ∣ j ∣-------------------------------------------------------------------------- Properties------------------------------------------------------------------------gcd[i,j]∣i : ∀ i j → gcd i j ∣ igcd[i,j]∣i i j = ℕ.gcd[m,n]∣m ∣ i ∣ ∣ j ∣gcd[i,j]∣j : ∀ i j → gcd i j ∣ jgcd[i,j]∣j i j = ℕ.gcd[m,n]∣n ∣ i ∣ ∣ j ∣gcd-greatest : ∀ {i j c} → c ∣ i → c ∣ j → c ∣ gcd i jgcd-greatest c∣i c∣j = ℕ.gcd-greatest c∣i c∣jgcd[0,0]≡0 : gcd 0ℤ 0ℤ ≡ 0ℤgcd[0,0]≡0 = cong (+_) ℕ.gcd[0,0]≡0gcd[i,j]≡0⇒i≡0 : ∀ i j → gcd i j ≡ 0ℤ → i ≡ 0ℤgcd[i,j]≡0⇒i≡0 i j eq = ∣i∣≡0⇒i≡0 (ℕ.gcd[m,n]≡0⇒m≡0 (+-injective eq))gcd[i,j]≡0⇒j≡0 : ∀ {i j} → gcd i j ≡ 0ℤ → j ≡ 0ℤgcd[i,j]≡0⇒j≡0 {i} eq = ∣i∣≡0⇒i≡0 (ℕ.gcd[m,n]≡0⇒n≡0 ∣ i ∣ (+-injective eq))gcd-comm : Commutative gcdgcd-comm i j = cong (+_) (ℕ.gcd-comm ∣ i ∣ ∣ j ∣)gcd-assoc : Associative gcdgcd-assoc i j k = cong (+_) (ℕ.gcd-assoc ∣ i ∣ ∣ j ∣ (∣ k ∣))gcd-zeroˡ : LeftZero 1ℤ gcdgcd-zeroˡ i = cong (+_) (ℕ.gcd-zeroˡ ∣ i ∣)gcd-zeroʳ : RightZero 1ℤ gcdgcd-zeroʳ i = cong (+_) (ℕ.gcd-zeroʳ ∣ i ∣)gcd-zero : Zero 1ℤ gcdgcd-zero = gcd-zeroˡ , gcd-zeroʳ
------------------------------------------------------------------------- The Agda standard library---- Unsigned divisibility-------------------------------------------------------------------------- For signed divisibility see `Data.Integer.Divisibility.Signed`{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Divisibility whereopen import Function.Base using (_on_; _$_)open import Data.Integer.Baseopen import Data.Integer.Propertiesimport Data.Nat.Base as ℕimport Data.Nat.Divisibility as ℕopen import Levelopen import Relation.Binary.Core using (Rel; _Preserves_⟶_)-------------------------------------------------------------------------- Divisibilityinfix 4 _∣__∣_ : Rel ℤ 0ℓ_∣_ = ℕ._∣_ on ∣_∣pattern divides k eq = ℕ.divides k eq-------------------------------------------------------------------------- Properties of divisibility*-monoʳ-∣ : ∀ k → (k *_) Preserves _∣_ ⟶ _∣_*-monoʳ-∣ k {i} {j} i∣j = begin∣ k * i ∣ ≡⟨ abs-* k i ⟩∣ k ∣ ℕ.* ∣ i ∣ ∣⟨ ℕ.*-monoʳ-∣ ∣ k ∣ i∣j ⟩∣ k ∣ ℕ.* ∣ j ∣ ≡⟨ abs-* k j ⟨∣ k * j ∣ ∎where open ℕ.∣-Reasoning*-monoˡ-∣ : ∀ k → (_* k) Preserves _∣_ ⟶ _∣_*-monoˡ-∣ k {i} {j} rewrite *-comm i k | *-comm j k = *-monoʳ-∣ k*-cancelˡ-∣ : ∀ k {i j} .{{_ : NonZero k}} → k * i ∣ k * j → i ∣ j*-cancelˡ-∣ k {i} {j} k*i∣k*j = ℕ.*-cancelˡ-∣ ∣ k ∣ $ begin∣ k ∣ ℕ.* ∣ i ∣ ≡⟨ abs-* k i ⟨∣ k * i ∣ ∣⟨ k*i∣k*j ⟩∣ k * j ∣ ≡⟨ abs-* k j ⟩∣ k ∣ ℕ.* ∣ j ∣ ∎where open ℕ.∣-Reasoning*-cancelʳ-∣ : ∀ k {i j} .{{_ : NonZero k}} → i * k ∣ j * k → i ∣ j*-cancelʳ-∣ k {i} {j} rewrite *-comm i k | *-comm j k = *-cancelˡ-∣ k
-------------------------------------------------------------------------- The Agda standard library---- Alternative definition of divisibility without using modulus.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Divisibility.Signed whereopen import Function.Base using (_⟨_⟩_; _$_; _$′_; _∘_; _∘′_)open import Data.Integer.Base using (ℤ; _*_; +0; sign; _◃_; ≢-nonZero;∣_∣; 0ℤ; +_; _+_; _-_; -_; NonZero)open import Data.Integer.Propertiesimport Data.Integer.Divisibility as Unsignedimport Data.Nat.Base as ℕimport Data.Nat.Divisibility as ℕimport Data.Nat.Coprimality as ℕimport Data.Nat.Properties as ℕimport Data.Sign.Base as Signimport Data.Sign.Properties as Signopen import Relation.Binary.Core using (_⇒_; _Preserves_⟶_)open import Relation.Binary.Bundles using (Preorder)open import Relation.Binary.Structures using (IsPreorder)open import Relation.Binary.Definitionsusing (Reflexive; Transitive; Decidable)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; trans; sym; cong; refl)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning; isEquivalence)import Relation.Binary.Reasoning.Preorder as ≲-Reasoningopen import Relation.Nullary.Decidable as Dec using (yes; no)open import Relation.Binary.Reasoning.Syntax-------------------------------------------------------------------------- Typeinfix 4 _∣_record _∣_ (k z : ℤ) : Set whereconstructor dividesfield quotient : ℤequality : z ≡ quotient * kopen _∣_ using (quotient) public-------------------------------------------------------------------------- Conversion between signed and unsigned divisibility∣ᵤ⇒∣ : ∀ {k i} → k Unsigned.∣ i → k ∣ i∣ᵤ⇒∣ {k} {i} (Unsigned.divides 0 eq) = divides +0 (∣i∣≡0⇒i≡0 eq)∣ᵤ⇒∣ {k} {i} (Unsigned.divides q@(ℕ.suc _) eq) with k ≟ +0... | yes refl = divides +0 (∣i∣≡0⇒i≡0 (trans eq (ℕ.*-zeroʳ q)))... | no neq = divides s[i*k]◃q (◃-cong sign-eq abs-eq)wheres[i*k] = sign i Sign.* sign ks[i*k]◃q = s[i*k] ◃ qinstance_ = ≢-nonZero neq_ = ◃-nonZero s[i*k] q_ = i*j≢0 s[i*k]◃q ksign-eq : sign i ≡ sign (s[i*k]◃q * k)sign-eq = sym $ beginsign (s[i*k]◃q * k) ≡⟨ sign-* s[i*k]◃q k ⟩sign s[i*k]◃q Sign.* sign k ≡⟨ cong (Sign._* _) (sign-◃ s[i*k] q) ⟩s[i*k] Sign.* sign k ≡⟨ Sign.*-assoc (sign i) (sign k) (sign k) ⟩sign i Sign.* (sign k Sign.* sign k) ≡⟨ cong (sign i Sign.*_) (Sign.s*s≡+ (sign k)) ⟩sign i Sign.* Sign.+ ≡⟨ Sign.*-identityʳ (sign i) ⟩sign i ∎where open ≡-Reasoningabs-eq : ∣ i ∣ ≡ ∣ s[i*k]◃q * k ∣abs-eq = sym $ begin∣ s[i*k]◃q * k ∣ ≡⟨ abs-* s[i*k]◃q k ⟩∣ s[i*k]◃q ∣ ℕ.* ∣ k ∣ ≡⟨ cong (ℕ._* ∣ k ∣) (abs-◃ s[i*k] q) ⟩q ℕ.* ∣ k ∣ ≡⟨ eq ⟨∣ i ∣ ∎where open ≡-Reasoning∣⇒∣ᵤ : ∀ {k i} → k ∣ i → k Unsigned.∣ i∣⇒∣ᵤ {k} {i} (divides q eq) = Unsigned.divides ∣ q ∣ $′ begin∣ i ∣ ≡⟨ cong ∣_∣ eq ⟩∣ q * k ∣ ≡⟨ abs-* q k ⟩∣ q ∣ ℕ.* ∣ k ∣ ∎where open ≡-Reasoning-------------------------------------------------------------------------- _∣_ is a preorder∣-refl : Reflexive _∣_∣-refl = ∣ᵤ⇒∣ ℕ.∣-refl∣-reflexive : _≡_ ⇒ _∣_∣-reflexive refl = ∣-refl∣-trans : Transitive _∣_∣-trans i∣j j∣k = ∣ᵤ⇒∣ (ℕ.∣-trans (∣⇒∣ᵤ i∣j) (∣⇒∣ᵤ j∣k))∣-isPreorder : IsPreorder _≡_ _∣_∣-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ∣-reflexive; trans = ∣-trans}∣-preorder : Preorder _ _ _∣-preorder = record { isPreorder = ∣-isPreorder }-------------------------------------------------------------------------- Divisibility reasoningmodule ∣-Reasoning whereprivate module Base = ≲-Reasoning ∣-preorderopen Base publichiding (step-≲; step-∼; step-≈; step-≈˘)renaming (≲-go to ∣-go)open ∣-syntax _IsRelatedTo_ _IsRelatedTo_ ∣-go public-------------------------------------------------------------------------- Other properties of _∣_infix 4 _∣?__∣?_ : Decidable _∣_k ∣? m = Dec.map′ ∣ᵤ⇒∣ ∣⇒∣ᵤ (∣ k ∣ ℕ.∣? ∣ m ∣)0∣⇒≡0 : ∀ {m} → 0ℤ ∣ m → m ≡ 0ℤ0∣⇒≡0 0|m = ∣i∣≡0⇒i≡0 (ℕ.0∣⇒≡0 (∣⇒∣ᵤ 0|m))m∣∣m∣ : ∀ {m} → m ∣ (+ ∣ m ∣)m∣∣m∣ = ∣ᵤ⇒∣ ℕ.∣-refl∣m∣∣m : ∀ {m} → (+ ∣ m ∣) ∣ m∣m∣∣m = ∣ᵤ⇒∣ ℕ.∣-refl∣m∣n⇒∣m+n : ∀ {i m n} → i ∣ m → i ∣ n → i ∣ m + n∣m∣n⇒∣m+n (divides q refl) (divides p refl) =divides (q + p) (sym (*-distribʳ-+ _ q p))∣m⇒∣-m : ∀ {i m} → i ∣ m → i ∣ - m∣m⇒∣-m {i} {m} i∣m = ∣ᵤ⇒∣ $′ begin∣ i ∣ ∣⟨ ∣⇒∣ᵤ i∣m ⟩∣ m ∣ ≡⟨ ∣-i∣≡∣i∣ m ⟨∣ - m ∣ ∎where open ℕ.∣-Reasoning∣m∣n⇒∣m-n : ∀ {i m n} → i ∣ m → i ∣ n → i ∣ m - n∣m∣n⇒∣m-n i∣m i∣n = ∣m∣n⇒∣m+n i∣m (∣m⇒∣-m i∣n)∣m+n∣m⇒∣n : ∀ {i m n} → i ∣ m + n → i ∣ m → i ∣ n∣m+n∣m⇒∣n {i} {m} {n} i∣m+n i∣m = begini ∣⟨ ∣m∣n⇒∣m-n i∣m+n i∣m ⟩m + n - m ≡⟨ +-comm (m + n) (- m) ⟩- m + (m + n) ≡⟨ +-assoc (- m) m n ⟨- m + m + n ≡⟨ cong (_+ n) (+-inverseˡ m) ⟩+ 0 + n ≡⟨ +-identityˡ n ⟩n ∎where open ∣-Reasoning∣m+n∣n⇒∣m : ∀ {i m n} → i ∣ m + n → i ∣ n → i ∣ m∣m+n∣n⇒∣m {m = m} {n} i|m+n i|n rewrite +-comm m n = ∣m+n∣m⇒∣n i|m+n i|n∣n⇒∣m*n : ∀ {i} m {n} → i ∣ n → i ∣ m * n∣n⇒∣m*n {i} m {n} (divides q eq) = divides (m * q) $′ beginm * n ≡⟨ cong (m *_) eq ⟩m * (q * i) ≡⟨ *-assoc m q i ⟨m * q * i ∎where open ≡-Reasoning∣m⇒∣m*n : ∀ {i m} n → i ∣ m → i ∣ m * n∣m⇒∣m*n {m = m} n i|m rewrite *-comm m n = ∣n⇒∣m*n n i|m*-monoʳ-∣ : ∀ k → (k *_) Preserves _∣_ ⟶ _∣_*-monoʳ-∣ k = ∣ᵤ⇒∣ ∘ Unsigned.*-monoʳ-∣ k ∘ ∣⇒∣ᵤ*-monoˡ-∣ : ∀ k → (_* k) Preserves _∣_ ⟶ _∣_*-monoˡ-∣ k {i} {j} = ∣ᵤ⇒∣ ∘ Unsigned.*-monoˡ-∣ k {i} {j} ∘ ∣⇒∣ᵤ*-cancelˡ-∣ : ∀ k {i j} .{{_ : NonZero k}} → k * i ∣ k * j → i ∣ j*-cancelˡ-∣ k = ∣ᵤ⇒∣ ∘ Unsigned.*-cancelˡ-∣ k ∘ ∣⇒∣ᵤ*-cancelʳ-∣ : ∀ k {i j} .{{_ : NonZero k}} → i * k ∣ j * k → i ∣ j*-cancelʳ-∣ k {i} {j} = ∣ᵤ⇒∣ ∘′ Unsigned.*-cancelʳ-∣ k {i} {j} ∘′ ∣⇒∣ᵤ
-------------------------------------------------------------------------- The Agda standard library---- Integer division------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.DivMod whereopen import Data.Integer.Base using (+_; -[1+_]; +[1+_]; NonZero; _%_; ∣_∣;_%ℕ_; _/ℕ_; _+_; _*_; -_; _-_; pred; -1ℤ; 0ℤ; _⊖_; _≤_; _<_; +≤+; suc;+<+)open import Data.Integer.Propertiesopen import Data.Nat.Base as ℕ using (ℕ; z≤n; s≤s; z<s; s<s)import Data.Nat.Properties as ℕimport Data.Nat.DivMod as ℕopen import Function.Base using (_∘′_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong; sym; subst)open ≤-Reasoning-------------------------------------------------------------------------- Definitionopen import Data.Integer.Base publicusing (_/ℕ_; _/_; _%ℕ_; _%_)-------------------------------------------------------------------------- Propertiesn%ℕd<d : ∀ n d .{{_ : ℕ.NonZero d}} → n %ℕ d ℕ.< dn%ℕd<d (+ n) d = ℕ.m%n<n n dn%ℕd<d -[1+ n ] d@(ℕ.suc _) with ℕ.suc n ℕ.% d... | ℕ.zero = z<s... | ℕ.suc r = s<s (ℕ.m∸n≤m _ r)n%d<d : ∀ n d .{{_ : NonZero d}} → n % d ℕ.< ∣ d ∣n%d<d n (+ d) = n%ℕd<d n dn%d<d n -[1+ d ] = n%ℕd<d n (ℕ.suc d)a≡a%ℕn+[a/ℕn]*n : ∀ n d .{{_ : ℕ.NonZero d}} → n ≡ + (n %ℕ d) + (n /ℕ d) * + da≡a%ℕn+[a/ℕn]*n (+ n) d = let q = n ℕ./ d; r = n ℕ.% d in begin-equality+ n ≡⟨ cong +_ (ℕ.m≡m%n+[m/n]*n n d) ⟩+ (r ℕ.+ q ℕ.* d) ≡⟨ pos-+ r (q ℕ.* d) ⟩+ r + + (q ℕ.* d) ≡⟨ cong (_+_ (+ r)) (pos-* q d) ⟩+ r + + q * + d ∎a≡a%ℕn+[a/ℕn]*n n@(-[1+ _ ]) d with ∣ n ∣ ℕ.% d in eq... | ℕ.zero = begin-equalityn ≡⟨ cong (-_ ∘′ +_) (ℕ.m≡m%n+[m/n]*n ∣n∣ d) ⟩- + (r ℕ.+ q ℕ.* d) ≡⟨ cong (-_ ∘′ +_) (cong (ℕ._+ q ℕ.* d) eq) ⟩- + (q ℕ.* d) ≡⟨ cong -_ (pos-* q d) ⟩- (+ q * + d) ≡⟨ neg-distribˡ-* (+ q) (+ d) ⟩- (+ q) * + d ≡⟨ sym (+-identityˡ (- (+ q) * + d)) ⟩+ 0 + - (+ q) * + d ∎where ∣n∣ = ∣ n ∣; q = ∣n∣ ℕ./ d; r = ∣n∣ ℕ.% d... | r@(ℕ.suc _) = begin-equalitylet ∣n∣ = ∣ n ∣; q = ∣n∣ ℕ./ d; r′ = ∣n∣ ℕ.% d inn ≡⟨ cong (-_ ∘′ +_) (ℕ.m≡m%n+[m/n]*n ∣n∣ d) ⟩- + (r′ ℕ.+ q ℕ.* d) ≡⟨ cong (-_ ∘′ +_) (cong (ℕ._+ q ℕ.* d) eq) ⟩- + (r ℕ.+ q ℕ.* d) ≡⟨ cong -_ (pos-+ r (q ℕ.* d)) ⟩- (+ r + + (q ℕ.* d)) ≡⟨ neg-distrib-+ (+ r) (+ (q ℕ.* d)) ⟩- + r - + (q ℕ.* d) ≡⟨ cong (_-_ (- + r)) (pos-* q d) ⟩- + r - (+ q * + d) ≡⟨⟩- + r - pred +[1+ q ] * + d ≡⟨ cong (_-_ (- + r)) (*-distribʳ-+ (+ d) -1ℤ +[1+ q ]) ⟩- + r - (-1ℤ * + d + (+[1+ q ] * + d)) ≡⟨ cong (λ v → - + r - (v + (+[1+ q ] * + d))) (-1*i≡-i (+ d)) ⟩- + r - (- + d + (+[1+ q ] * + d)) ≡⟨ cong (_+_ (- + r)) (neg-distrib-+ (- + d) (+[1+ q ] * + d)) ⟩- + r + (- - + d + - (+[1+ q ] * + d)) ≡⟨ cong (λ v → - + r + (v + - (+[1+ q ] * + d))) (neg-involutive (+ d)) ⟩- + r + (+ d + - (+[1+ q ] * + d)) ≡⟨ cong (λ v → - + r + (+ d + v)) (neg-distribˡ-* +[1+ q ] (+ d)) ⟩- + r + (+ d + (-[1+ q ] * + d)) ≡⟨ sym (+-assoc (- + r) (+ d) (-[1+ q ] * + d)) ⟩- + r + + d + (-[1+ q ] * + d) ≡⟨ cong (_+ -[1+ q ] * + d) (-m+n≡n⊖m r d) ⟩d ⊖ r + (-[1+ q ] * + d) ≡⟨ cong (_+ -[1+ q ] * + d) (⊖-≥ (subst (ℕ._≤ d) eq (ℕ.m%n≤n ∣n∣ d))) ⟩+ (d ℕ.∸ r) + (-[1+ q ] * + d) ∎[n/ℕd]*d≤n : ∀ n d .{{_ : ℕ.NonZero d}} → (n /ℕ d) * + d ≤ n[n/ℕd]*d≤n n d = let q = n /ℕ d; r = n %ℕ d in beginq * + d ≤⟨ i≤j+i _ (+ r) ⟩+ r + q * + d ≡⟨ a≡a%ℕn+[a/ℕn]*n n d ⟨n ∎div-pos-is-/ℕ : ∀ n d .{{_ : ℕ.NonZero d}} →n / (+ d) ≡ n /ℕ ddiv-pos-is-/ℕ n (ℕ.suc d) = *-identityˡ (n /ℕ ℕ.suc d)div-neg-is-neg-/ℕ : ∀ n d .{{_ : ℕ.NonZero d}} .{{_ : NonZero (- + d)}} →n / (- + d) ≡ - (n /ℕ d)div-neg-is-neg-/ℕ n (ℕ.suc d) = -1*i≡-i (n /ℕ ℕ.suc d)0≤n⇒0≤n/ℕd : ∀ n d .{{_ : ℕ.NonZero d}} → 0ℤ ≤ n → 0ℤ ≤ (n /ℕ d)0≤n⇒0≤n/ℕd (+ n) d (+≤+ m≤n) = +≤+ z≤n0≤n⇒0≤n/d : ∀ n d .{{_ : NonZero d}} → 0ℤ ≤ n → 0ℤ ≤ d → 0ℤ ≤ (n / d)0≤n⇒0≤n/d n (+ d) {{d≢0}} 0≤n (+≤+ 0≤d)rewrite div-pos-is-/ℕ n d {{d≢0}}= 0≤n⇒0≤n/ℕd n d 0≤n[n/d]*d≤n : ∀ n d .{{_ : NonZero d}} → (n / d) * d ≤ n[n/d]*d≤n n (+ d) = beginn / + d * + d ≡⟨ cong (_* (+ d)) (div-pos-is-/ℕ n d) ⟩n /ℕ d * + d ≤⟨ [n/ℕd]*d≤n n d ⟩n ∎[n/d]*d≤n n d@(-[1+ _ ]) = begin let ∣d∣ = ∣ d ∣ inn / d * d ≡⟨ cong (_* d) (div-neg-is-neg-/ℕ n ∣d∣) ⟩- (n /ℕ ∣d∣) * d ≡⟨ sym (neg-distribˡ-* (n /ℕ ∣d∣) d) ⟩- (n /ℕ ∣d∣ * d) ≡⟨ neg-distribʳ-* (n /ℕ ∣d∣) d ⟩n /ℕ ∣d∣ * + ∣d∣ ≤⟨ [n/ℕd]*d≤n n ∣d∣ ⟩n ∎n<s[n/ℕd]*d : ∀ n d .{{_ : ℕ.NonZero d}} → n < suc (n /ℕ d) * + dn<s[n/ℕd]*d n d = begin-strictn ≡⟨ a≡a%ℕn+[a/ℕn]*n n d ⟩+ r + q * + d <⟨ +-monoˡ-< (q * + d) (+<+ (n%ℕd<d n d)) ⟩+ d + q * + d ≡⟨ sym (suc-* q (+ d)) ⟩suc (n /ℕ d) * + d ∎where q = n /ℕ d; r = n %ℕ da≡a%n+[a/n]*n : ∀ a n .{{_ : NonZero n}} → a ≡ + (a % n) + (a / n) * na≡a%n+[a/n]*n n d@(+ _) = begin-equalitylet ∣d∣ = ∣ d ∣; r = n % d; q = n /ℕ ∣d∣ inn ≡⟨ a≡a%ℕn+[a/ℕn]*n n ∣d∣ ⟩+ r + (q * + ∣d∣) ≡⟨ cong (λ p → + r + p * d) (sym (div-pos-is-/ℕ n ∣d∣)) ⟩+ r + n / d * d ∎a≡a%n+[a/n]*n n d@(-[1+ _ ]) = begin-equalitylet ∣d∣ = ∣ d ∣; r = n % d; q = n /ℕ ∣d∣ inn ≡⟨ a≡a%ℕn+[a/ℕn]*n n ∣d∣ ⟩+ r + q * + ∣d∣ ≡⟨⟩+ r + q * - d ≡⟨ cong (_+_ (+ r)) (sym (neg-distribʳ-* q d)) ⟩+ r + - (q * d) ≡⟨ cong (_+_ (+ r)) (neg-distribˡ-* q d) ⟩+ r + - q * d ≡⟨ cong (_+_ (+ r) ∘′ (_* d)) (sym (-1*i≡-i q)) ⟩+ r + n / d * d ∎-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infixl 7 _divℕ_ _div_ _modℕ_ _mod__divℕ_ = _/ℕ_{-# WARNING_ON_USAGE _divℕ_"Warning: _divℕ_ was deprecated in v2.0.Please use _/ℕ_ instead."#-}_div_ = _/_{-# WARNING_ON_USAGE _div_"Warning: _div_ was deprecated in v2.0.Please use _/_ instead."#-}_modℕ_ = _%ℕ_{-# WARNING_ON_USAGE _modℕ_"Warning: _modℕ_ was deprecated in v2.0.Please use _%ℕ_ instead."#-}_mod_ = _%_{-# WARNING_ON_USAGE _mod_"Warning: _mod_ was deprecated in v2.0.Please use _%_ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Coprimality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Coprimality whereopen import Data.Integer.Baseopen import Data.Integer.Divisibilityopen import Data.Integer.Propertiesimport Data.Nat.Coprimality as ℕimport Data.Nat.Divisibility as ℕopen import Function.Base using (_on_)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable; Symmetric)open import Relation.Binary.PropositionalEquality.Core using (subst)-------------------------------------------------------------------------- DefinitionCoprime : Rel ℤ 0ℓCoprime = ℕ.Coprime on ∣_∣-------------------------------------------------------------------------- Properties of coprimalitysym : Symmetric Coprimesym = ℕ.symcoprime? : Decidable Coprimecoprime? x y = ℕ.coprime? ∣ x ∣ ∣ y ∣coprime-divisor : ∀ i j k → Coprime i j → i ∣ j * k → i ∣ kcoprime-divisor i j k c eq =ℕ.coprime-divisor c (subst (∣ i ∣ ℕ.∣_ ) (abs-* j k) eq)
-------------------------------------------------------------------------- The Agda standard library---- Integers, basic types and operations-------------------------------------------------------------------------- See README.Data.Integer for examples of how to use and reason about-- integers.{-# OPTIONS --cubical-compatible --safe #-}module Data.Integer.Base whereopen import Algebra.Bundles.Rawusing (RawMagma; RawMonoid; RawGroup; RawNearSemiring; RawSemiring; RawRing)open import Data.Bool.Base using (Bool; T; true; false)open import Data.Nat.Base as ℕ using (ℕ; z≤n; s≤s) hiding (module ℕ)open import Data.Sign.Base as Sign using (Sign)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Unary using (Pred)infix 8 -_infixr 8 _^_infixl 7 _*_ _⊓_ _/ℕ_ _/_ _%ℕ_ _%_infixl 6 _+_ _-_ _⊖_ _⊔_infix 4 _≤_ _≥_ _<_ _>_ _≰_ _≱_ _≮_ _≯_infix 4 _≤ᵇ_-------------------------------------------------------------------------- Typesopen import Agda.Builtin.Int publicusing ()renaming( Int to ℤ; pos to +_ -- "+ n" stands for "n"; negsuc to -[1+_] -- "-[1+ n ]" stands for "- (1 + n)")-- Some additional patterns that provide symmetry around 0pattern +0 = + 0pattern +[1+_] n = + (ℕ.suc n)-------------------------------------------------------------------------- Constants0ℤ : ℤ0ℤ = +0-1ℤ : ℤ-1ℤ = -[1+ 0 ]1ℤ : ℤ1ℤ = +[1+ 0 ]-------------------------------------------------------------------------- Conversion-- Absolute value.∣_∣ : ℤ → ℕ∣ + n ∣ = n∣ -[1+ n ] ∣ = ℕ.suc n-- Gives the sign. For zero the sign is arbitrarily chosen to be +.sign : ℤ → Signsign (+ _) = Sign.+sign -[1+ _ ] = Sign.--------------------------------------------------------------------------- Orderingdata _≤_ : ℤ → ℤ → Set where-≤- : ∀ {m n} → (n≤m : n ℕ.≤ m) → -[1+ m ] ≤ -[1+ n ]-≤+ : ∀ {m n} → -[1+ m ] ≤ + n+≤+ : ∀ {m n} → (m≤n : m ℕ.≤ n) → + m ≤ + ndata _<_ : ℤ → ℤ → Set where-<- : ∀ {m n} → (n<m : n ℕ.< m) → -[1+ m ] < -[1+ n ]-<+ : ∀ {m n} → -[1+ m ] < + n+<+ : ∀ {m n} → (m<n : m ℕ.< n) → + m < + n_≥_ : Rel ℤ 0ℓx ≥ y = y ≤ x_>_ : Rel ℤ 0ℓx > y = y < x_≰_ : Rel ℤ 0ℓx ≰ y = ¬ (x ≤ y)_≱_ : Rel ℤ 0ℓx ≱ y = ¬ (x ≥ y)_≮_ : Rel ℤ 0ℓx ≮ y = ¬ (x < y)_≯_ : Rel ℤ 0ℓx ≯ y = ¬ (x > y)-------------------------------------------------------------------------- Boolean ordering-- A boolean version._≤ᵇ_ : ℤ → ℤ → Bool-[1+ m ] ≤ᵇ -[1+ n ] = n ℕ.≤ᵇ m(+ m) ≤ᵇ -[1+ n ] = false-[1+ m ] ≤ᵇ (+ n) = true(+ m) ≤ᵇ (+ n) = m ℕ.≤ᵇ n-------------------------------------------------------------------------- Simple predicates-- See `Data.Nat.Base` for a discussion on the design of these.NonZero : Pred ℤ 0ℓNonZero i = ℕ.NonZero ∣ i ∣record Positive (i : ℤ) : Set wherefieldpos : T (1ℤ ≤ᵇ i)record NonNegative (i : ℤ) : Set wherefieldnonNeg : T (0ℤ ≤ᵇ i)record NonPositive (i : ℤ) : Set wherefieldnonPos : T (i ≤ᵇ 0ℤ)record Negative (i : ℤ) : Set wherefieldneg : T (i ≤ᵇ -1ℤ)-- Instancesopen ℕ publicusing (nonZero)instancepos : ∀ {n} → Positive +[1+ n ]pos = _nonNeg : ∀ {n} → NonNegative (+ n)nonNeg = _nonPos0 : NonPositive 0ℤnonPos0 = _nonPos : ∀ {n} → NonPositive -[1+ n ]nonPos = _neg : ∀ {n} → Negative -[1+ n ]neg = _-- Constructors≢-nonZero : ∀ {i} → i ≢ 0ℤ → NonZero i≢-nonZero { +[1+ n ]} _ = _≢-nonZero { +0} 0≢0 = contradiction refl 0≢0≢-nonZero { -[1+ n ]} _ = _>-nonZero : ∀ {i} → i > 0ℤ → NonZero i>-nonZero (+<+ (s≤s m<n)) = _<-nonZero : ∀ {i} → i < 0ℤ → NonZero i<-nonZero -<+ = _positive : ∀ {i} → i > 0ℤ → Positive ipositive (+<+ (s≤s m<n)) = _negative : ∀ {i} → i < 0ℤ → Negative inegative -<+ = _nonPositive : ∀ {i} → i ≤ 0ℤ → NonPositive inonPositive -≤+ = _nonPositive (+≤+ z≤n) = _nonNegative : ∀ {i} → i ≥ 0ℤ → NonNegative inonNegative {+0} _ = _nonNegative {+[1+ n ]} _ = _-------------------------------------------------------------------------- A view of integers as sign + absolute valueinfix 5 _◂_ _◃__◃_ : Sign → ℕ → ℤ_ ◃ ℕ.zero = +0Sign.+ ◃ n = + nSign.- ◃ ℕ.suc n = -[1+ n ]data SignAbs : ℤ → Set where_◂_ : (s : Sign) (n : ℕ) → SignAbs (s ◃ n)signAbs : ∀ i → SignAbs isignAbs -[1+ n ] = Sign.- ◂ ℕ.suc nsignAbs +0 = Sign.+ ◂ ℕ.zerosignAbs +[1+ n ] = Sign.+ ◂ ℕ.suc n-------------------------------------------------------------------------- Arithmetic-- Negation.-_ : ℤ → ℤ- -[1+ n ] = +[1+ n ]- +0 = +0- +[1+ n ] = -[1+ n ]-- Subtraction of natural numbers.-- We define it using _<ᵇ_ and _∸_ rather than inductively so that it-- is backed by builtin operations. This makes it much faster._⊖_ : ℕ → ℕ → ℤm ⊖ n with m ℕ.<ᵇ n... | true = - + (n ℕ.∸ m)... | false = + (m ℕ.∸ n)-- Addition._+_ : ℤ → ℤ → ℤ-[1+ m ] + -[1+ n ] = -[1+ ℕ.suc (m ℕ.+ n) ]-[1+ m ] + + n = n ⊖ ℕ.suc m+ m + -[1+ n ] = m ⊖ ℕ.suc n+ m + + n = + (m ℕ.+ n)-- Subtraction._-_ : ℤ → ℤ → ℤi - j = i + (- j)-- Successor.suc : ℤ → ℤsuc i = 1ℤ + i-- Predecessor.pred : ℤ → ℤpred i = -1ℤ + i-- Multiplication._*_ : ℤ → ℤ → ℤi * j = sign i Sign.* sign j ◃ ∣ i ∣ ℕ.* ∣ j ∣-- Naïve exponentiation._^_ : ℤ → ℕ → ℤi ^ ℕ.zero = 1ℤi ^ (ℕ.suc m) = i * i ^ m-- Maximum._⊔_ : ℤ → ℤ → ℤ-[1+ m ] ⊔ -[1+ n ] = -[1+ ℕ._⊓_ m n ]-[1+ m ] ⊔ + n = + n+ m ⊔ -[1+ n ] = + m+ m ⊔ + n = + (ℕ._⊔_ m n)-- Minimum._⊓_ : ℤ → ℤ → ℤ-[1+ m ] ⊓ -[1+ n ] = -[1+ m ℕ.⊔ n ]-[1+ m ] ⊓ + n = -[1+ m ]+ m ⊓ -[1+ n ] = -[1+ n ]+ m ⊓ + n = + (m ℕ.⊓ n)-- Division by a natural_/ℕ_ : (dividend : ℤ) (divisor : ℕ) .{{_ : ℕ.NonZero divisor}} → ℤ(+ n /ℕ d) = + (n ℕ./ d)(-[1+ n ] /ℕ d) with ℕ.suc n ℕ.% d... | ℕ.zero = - (+ (ℕ.suc n ℕ./ d))... | ℕ.suc r = -[1+ (ℕ.suc n ℕ./ d) ]-- Division_/_ : (dividend divisor : ℤ) .{{_ : NonZero divisor}} → ℤi / j = (sign j ◃ 1) * (i /ℕ ∣ j ∣)-- Modulus by a natural_%ℕ_ : (dividend : ℤ) (divisor : ℕ) .{{_ : ℕ.NonZero divisor}} → ℕ(+ n %ℕ d) = n ℕ.% d(-[1+ n ] %ℕ d) with ℕ.suc n ℕ.% d... | ℕ.zero = 0... | r@(ℕ.suc _) = d ℕ.∸ r-- Modulus_%_ : (dividend divisor : ℤ) .{{_ : NonZero divisor}} → ℕi % j = i %ℕ ∣ j ∣-------------------------------------------------------------------------- Bundles+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMagma = record { _≈_ = _≡_ ; _∙_ = _+_ }+-0-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawMonoid = record { _≈_ = _≡_ ; _∙_ = _+_ ; ε = 0ℤ }+-0-rawGroup : RawGroup 0ℓ 0ℓ+-0-rawGroup = record { _≈_ = _≡_ ; _∙_ = _+_ ; _⁻¹ = -_; ε = 0ℤ }*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma = record { _≈_ = _≡_ ; _∙_ = _*_ }*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid = record { _≈_ = _≡_ ; _∙_ = _*_ ; ε = 1ℤ }+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawNearSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℤ}+-*-rawSemiring : RawSemiring 0ℓ 0ℓ+-*-rawSemiring = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; 0# = 0ℤ; 1# = 1ℤ}+-*-rawRing : RawRing 0ℓ 0ℓ+-*-rawRing = record{ Carrier = _; _≈_ = _≡_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0ℤ; 1# = 1ℤ}
-------------------------------------------------------------------------- The Agda standard library---- Directed acyclic multigraphs-------------------------------------------------------------------------- A representation of DAGs, based on the idea underlying Martin-- Erwig's FGL. Note that this representation does not aim to be-- efficient.{-# OPTIONS --cubical-compatible --safe #-}module Data.Graph.Acyclic whereopen import Level using (_⊔_)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _<′_)open import Data.Nat.Induction using (<′-rec; <′-Rec)import Data.Nat.Properties as ℕopen import Data.Fin as Finusing (Fin; Fin′; zero; suc; #_; toℕ; _≟_; opposite) renaming (_ℕ-ℕ_ to _-_)import Data.Fin.Properties as Finopen import Data.Product.Base as Prod using (∃; _×_; _,_)open import Data.Maybe.Base as Maybe using (Maybe)open import Data.Empty using (⊥)open import Data.Unit.Base using (⊤; tt)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.List.Base as List using (List; []; _∷_)open import Function.Base using (_$_; _∘′_; _∘_; id)open import Relation.Binary.Consequences using (dec⇒weaklyDec)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)-------------------------------------------------------------------------- A lemmaprivatelemma : ∀ n (i : Fin n) → n - suc i <′ nlemma (suc n) i = ℕ.≤⇒≤′ $ ℕ.s≤s $ Fin.nℕ-ℕi≤n n i-------------------------------------------------------------------------- Node contextsrecord Context {ℓ e} (Node : Set ℓ) (Edge : Set e) (n : ℕ) : Set (ℓ ⊔ e) whereconstructor contextfieldlabel : Nodesuccessors : List (Edge × Fin n)open Context public-- Map for contexts.module _ {ℓ₁ e₁} {N₁ : Set ℓ₁} {E₁ : Set e₁}{ℓ₂ e₂} {N₂ : Set ℓ₂} {E₂ : Set e₂} wherecmap : ∀ {n} → (N₁ → N₂) → (List (E₁ × Fin n) → List (E₂ × Fin n)) →Context N₁ E₁ n → Context N₂ E₂ ncmap f g c = context (f (label c)) (g (successors c))-------------------------------------------------------------------------- Graphsinfixr 3 _&_-- The DAGs are indexed on the number of nodes.data Graph {ℓ e} (Node : Set ℓ) (Edge : Set e) : ℕ → Set (ℓ ⊔ e) where∅ : Graph Node Edge 0_&_ : ∀ {n} (c : Context Node Edge n) (g : Graph Node Edge n) →Graph Node Edge (suc n)privateexample : Graph ℕ ℕ 5example = context 0 [] &context 1 ((10 , # 1) ∷ (11 , # 1) ∷ []) &context 2 ((12 , # 0) ∷ []) &context 3 [] &context 4 [] &∅-------------------------------------------------------------------------- Higher-order functionsmodule _ {ℓ e} {N : Set ℓ} {E : Set e} {t} where-- "Fold right".foldr : (T : ℕ → Set t) →(∀ {n} → Context N E n → T n → T (suc n)) →T 0 →∀ {m} → Graph N E m → T mfoldr T _∙_ x ∅ = xfoldr T _∙_ x (c & g) = c ∙ foldr T _∙_ x g-- "Fold left".foldl : ∀ {n} (T : ℕ → Set t) →((i : Fin n) → T (toℕ i) → Context N E (n - suc i) →T (suc (toℕ i))) →T 0 →Graph N E n → T nfoldl T f x ∅ = xfoldl T f x (c & g) = foldl (T ∘′ suc) (f ∘ suc) (f zero x c) gmodule _ {ℓ₁ e₁} {N₁ : Set ℓ₁} {E₁ : Set e₁}{ℓ₂ e₂} {N₂ : Set ℓ₂} {E₂ : Set e₂} where-- Maps over node contexts.map : (∀ {n} → Context N₁ E₁ n → Context N₂ E₂ n) →∀ {n} → Graph N₁ E₁ n → Graph N₂ E₂ nmap f = foldr _ (λ c → f c &_) ∅-- Maps over node labels.nmap : ∀ {ℓ₁ ℓ₂ e} {N₁ : Set ℓ₁} {N₂ : Set ℓ₂} {E : Set e} →∀ {n} → (N₁ → N₂) → Graph N₁ E n → Graph N₂ E nnmap f = map (cmap f id)-- Maps over edge labels.emap : ∀ {ℓ e₁ e₂} {N : Set ℓ} {E₁ : Set e₁} {E₂ : Set e₂} →∀ {n} → (E₁ → E₂) → Graph N E₁ n → Graph N E₂ nemap f = map (cmap id (List.map (Prod.map f id)))-- Zips two graphs with the same number of nodes. Note that one of the-- graphs has a type which restricts it to be completely disconnected.zipWith : ∀ {ℓ₁ ℓ₂ ℓ e} {N₁ : Set ℓ₁} {N₂ : Set ℓ₂} {N : Set ℓ} {E : Set e} →∀ {n} → (N₁ → N₂ → N) → Graph N₁ ⊥ n → Graph N₂ E n → Graph N E nzipWith _∙_ ∅ ∅ = ∅zipWith _∙_ (c₁ & g₁) (c₂ & g₂) =context (label c₁ ∙ label c₂) (successors c₂) & zipWith _∙_ g₁ g₂-------------------------------------------------------------------------- Specific graphs-- A completeley disconnected graph.disconnected : ∀ n → Graph ⊤ ⊥ ndisconnected zero = ∅disconnected (suc n) = context tt [] & disconnected n-- A complete graph.complete : ∀ n → Graph ⊤ ⊤ ncomplete zero = ∅complete (suc n) =context tt (List.map (tt ,_) $ Vec.toList (Vec.allFin n)) &complete n-------------------------------------------------------------------------- Queriesmodule _ {ℓ e} {N : Set ℓ} {E : Set e} where-- The top-most context.head : ∀ {n} → Graph N E (suc n) → Context N E nhead (c & g) = c-- The remaining graph.tail : ∀ {n} → Graph N E (suc n) → Graph N E ntail (c & g) = g-- Finds the context and remaining graph corresponding to a given node-- index.infix 4 _[_]_[_] : ∀ {n} → Graph N E n → (i : Fin n) → Graph N E (suc (n - suc i))(c & g) [ zero ] = c & g(c & g) [ suc i ] = g [ i ]-- The nodes of the graph (node number relative to "topmost" node ×-- node label).nodes : ∀ {n} → Graph N E n → Vec (Fin n × N) nnodes = Vec.zip (Vec.allFin _) ∘foldr (Vec N) (λ c → label c ∷_) []privatetest-nodes : nodes example ≡ (# 0 , 0) ∷ (# 1 , 1) ∷ (# 2 , 2) ∷(# 3 , 3) ∷ (# 4 , 4) ∷ []test-nodes = reflmodule _ {ℓ e} {N : Set ℓ} {E : Set e} where-- Topological sort. Gives a vector where earlier nodes are never-- successors of later nodes.topSort : ∀ {n} → Graph N E n → Vec (Fin n × N) ntopSort = nodes-- The edges of the graph (predecessor × edge label × successor).---- The predecessor is a node number relative to the "topmost" node in-- the graph, and the successor is a node number relative to the-- predecessor.edges : ∀ {n} → Graph N E n → List (∃ λ i → E × Fin (n - suc i))edges {n} =foldl (λ _ → List (∃ λ i → E × Fin (n - suc i)))(λ i es c → es List.++ List.map (i ,_) (successors c))[]privatetest-edges : edges example ≡ (# 1 , 10 , # 1) ∷ (# 1 , 11 , # 1) ∷(# 2 , 12 , # 0) ∷ []test-edges = refl-- The successors of a given node i (edge label × node number relative-- to i).sucs : ∀ {ℓ e} {N : Set ℓ} {E : Set e} →∀ {n} → Graph N E n → (i : Fin n) → List (E × Fin (n - suc i))sucs g i = successors $ head (g [ i ])privatetest-sucs : sucs example (# 1) ≡ (10 , # 1) ∷ (11 , # 1) ∷ []test-sucs = refl-- The predecessors of a given node i (node number relative to i ×-- edge label).preds : ∀ {ℓ e} {N : Set ℓ} {E : Set e} →∀ {n} → Graph N E n → (i : Fin n) → List (Fin′ i × E)preds g zero = []preds (c & g) (suc i) =List._++_ (List.mapMaybe (p i) $ successors c)(List.map (Prod.map suc id) $ preds g i)wherep : ∀ {e} {E : Set e} {n} (i : Fin n) → E × Fin n → Maybe (Fin′ (suc i) × E)p i (e , j) = Maybe.map (λ{ refl → zero , e }) (dec⇒weaklyDec _≟_ i j)privatetest-preds : preds example (# 3) ≡(# 1 , 10) ∷ (# 1 , 11) ∷ (# 2 , 12) ∷ []test-preds = refl-------------------------------------------------------------------------- Operations-- Weakens a node label.weaken : ∀ {n} {i : Fin n} → Fin (n - suc i) → Fin nweaken {n} {i} j = Fin.inject≤ j (Fin.nℕ-ℕi≤n n (suc i))-- Labels each node with its node number.number : ∀ {ℓ e} {N : Set ℓ} {E : Set e} →∀ {n} → Graph N E n → Graph (Fin n × N) E nnumber {N = N} {E} =foldr (λ n → Graph (Fin n × N) E n)(λ c g → cmap (zero ,_) id c & nmap (Prod.map suc id) g)∅privatetest-number : number example ≡(context (# 0 , 0) [] &context (# 1 , 1) ((10 , # 1) ∷ (11 , # 1) ∷ []) &context (# 2 , 2) ((12 , # 0) ∷ []) &context (# 3 , 3) [] &context (# 4 , 4) [] &∅)test-number = refl-- Reverses all the edges in the graph.reverse : ∀ {ℓ e} {N : Set ℓ} {E : Set e} →∀ {n} → Graph N E n → Graph N E nreverse {N = N} {E} g =foldl (Graph N E)(λ i g′ c →context (label c)(List.map (Prod.swap ∘ Prod.map opposite id) $preds g i)& g′)∅ gprivatetest-reverse : reverse (reverse example) ≡ exampletest-reverse = refl-------------------------------------------------------------------------- Views-- Expands the subgraph induced by a given node into a tree (thus-- losing all sharing).data Tree {ℓ e} (N : Set ℓ) (E : Set e) : Set (ℓ ⊔ e) wherenode : (label : N) (successors : List (E × Tree N E)) → Tree N Emodule _ {ℓ e} {N : Set ℓ} {E : Set e} wheretoTree : ∀ {n} → Graph N E n → Fin n → Tree N EtoTree g i = <′-rec Pred expand _ (g [ i ])wherePred = λ n → Graph N E (suc n) → Tree N Eexpand : (n : ℕ) → <′-Rec Pred n → Pred nexpand n rec (c & g) =node (label c)(List.map(Prod.map id (λ i → rec (lemma n i) (g [ i ])))(successors c))-- Performs the toTree expansion once for each node.toForest : ∀ {n} → Graph N E n → Vec (Tree N E) ntoForest g = Vec.map (toTree g) (Vec.allFin _)privatetest-toForest : toForest example ≡let n3 = node 3 [] innode 0 [] ∷node 1 ((10 , n3) ∷ (11 , n3) ∷ []) ∷node 2 ((12 , n3) ∷ []) ∷node 3 [] ∷node 4 [] ∷[]test-toForest = refl
-------------------------------------------------------------------------- The Agda standard library---- Floating point numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Float where-------------------------------------------------------------------------- Re-export base definitions and decidability of equalityopen import Data.Float.Base publicopen import Data.Float.Properties using (_≈?_; _≟_) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on floats------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Float.Properties whereopen import Data.Bool.Base as Bool using (Bool)open import Data.Float.Baseimport Data.Maybe.Base as Maybeimport Data.Maybe.Properties as Maybeimport Data.Nat.Properties as ℕimport Data.Word64.Base as Word64import Data.Word64.Properties as Word64open import Function.Base using (_∘_)open import Relation.Nullary.Decidable as RN using (map′)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Setoid; DecSetoid)open import Relation.Binary.Structuresusing (IsEquivalence; IsDecEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Substitutive; Decidable; DecidableEquality)import Relation.Binary.Construct.On as Onopen import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; sym; trans; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid; decSetoid)-------------------------------------------------------------------------- Primitive propertiesopen import Agda.Builtin.Float.Propertiesrenaming (primFloatToWord64Injective to toWord64-injective)public-------------------------------------------------------------------------- Properties of _≈_≈⇒≡ : _≈_ ⇒ _≡_≈⇒≡ eq = toWord64-injective _ _ (Maybe.map-injective Word64.≈⇒≡ eq)≈-reflexive : _≡_ ⇒ _≈_≈-reflexive eq = cong (Maybe.map Word64.toℕ ∘ toWord64) eq≈-refl : Reflexive _≈_≈-refl = refl≈-sym : Symmetric _≈_≈-sym = sym≈-trans : Transitive _≈_≈-trans = trans≈-subst : ∀ {ℓ} → Substitutive _≈_ ℓ≈-subst P x≈y p = subst P (≈⇒≡ x≈y) pinfix 4 _≈?__≈?_ : Decidable _≈__≈?_ = On.decidable (Maybe.map Word64.toℕ ∘ toWord64) _≡_ (Maybe.≡-dec ℕ._≟_)≈-isEquivalence : IsEquivalence _≈_≈-isEquivalence = record{ refl = λ {i} → ≈-refl {i}; sym = λ {i j} → ≈-sym {i} {j}; trans = λ {i j k} → ≈-trans {i} {j} {k}}≈-setoid : Setoid _ _≈-setoid = record{ isEquivalence = ≈-isEquivalence}≈-isDecEquivalence : IsDecEquivalence _≈_≈-isDecEquivalence = record{ isEquivalence = ≈-isEquivalence; _≟_ = _≈?_}≈-decSetoid : DecSetoid _ _≈-decSetoid = record{ isDecEquivalence = ≈-isDecEquivalence}-------------------------------------------------------------------------- Properties of _≡_infix 4 _≟__≟_ : DecidableEquality Floatx ≟ y = map′ ≈⇒≡ ≈-reflexive (x ≈? y)≡-setoid : Setoid _ _≡-setoid = setoid Float≡-decSetoid : DecSetoid _ _≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- DEPRECATIONStoWord-injective = toWord64-injective{-# WARNING_ON_USAGE toWord-injective"Warning: toWord-injective was deprecated in v2.1.Please use toWord64-injective instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Instances for floating point numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Float.Instances whereopen import Data.Float.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceFloat-≡-isDecEquivalence = isDecEquivalence _≟_
-------------------------------------------------------------------------- The Agda standard library---- Floats: basic types and operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Float.Base whereopen import Data.Bool.Base using (T)import Data.Word64.Base as Word64import Data.Maybe.Base as Maybeopen import Function.Base using (_on_; _∘_)open import Agda.Builtin.Equalityopen import Relation.Binary.Core using (Rel)-------------------------------------------------------------------------- Re-export built-ins publicallyopen import Agda.Builtin.Float publicusing (Float)renaming-- Relations( primFloatInequality to infix 4 _≤ᵇ_; primFloatEquality to infix 4 _≡ᵇ_; primFloatLess to infix 4 _<ᵇ_; primFloatIsInfinite to isInfinite; primFloatIsNaN to isNaN; primFloatIsNegativeZero to isNegativeZero; primFloatIsSafeInteger to isSafeInteger-- Conversions; primFloatToWord64 to toWord64; primNatToFloat to fromℕ; primIntToFloat to fromℤ; primFloatRound to round; primFloatFloor to ⌊_⌋; primFloatCeiling to ⌈_⌉; primFloatToRatio to toRatio; primRatioToFloat to fromRatio; primFloatDecode to decode; primFloatEncode to encode; primShowFloat to show-- Operations; primFloatPlus to infixl 6 _+_; primFloatMinus to infixl 6 _-_; primFloatTimes to infixl 7 _*_; primFloatDiv to infixl 7 _÷_; primFloatPow to infixl 8 _**_; primFloatNegate to infixr 9 -_; primFloatSqrt to sqrt; primFloatExp to infixr 9 e^_; primFloatLog to log; primFloatSin to sin; primFloatCos to cos; primFloatTan to tan; primFloatASin to asin; primFloatACos to acos; primFloatATan to atan; primFloatATan2 to atan2; primFloatSinh to sinh; primFloatCosh to cosh; primFloatTanh to tanh; primFloatASinh to asinh; primFloatACosh to acosh; primFloatATanh to atanh)infix 4 _≈__≈_ : Rel Float __≈_ = _≡_ on Maybe.map Word64.toℕ ∘ toWord64infix 4 _≤__≤_ : Rel Float _x ≤ y = T (x ≤ᵇ y)-------------------------------------------------------------------------- DEPRECATIONStoWord = toWord64{-# WARNING_ON_USAGE toWord"Warning: toWord was deprecated in v2.1.Please use toWord64 instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Finite sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin whereopen import Relation.Nullary.Decidable.Coreimport Data.Nat.Properties as ℕ-------------------------------------------------------------------------- Publicly re-export the contents of the base moduleopen import Data.Fin.Base public-------------------------------------------------------------------------- Publicly re-export queriesopen import Data.Fin.Properties publicusing (_≟_; _≤?_; _<?_)-- # m = "m".infix 10 #_#_ : ∀ m {n} {m<n : True (m ℕ.<? n)} → Fin n#_ _ {m<n = m<n} = fromℕ< (toWitness m<n)
-------------------------------------------------------------------------- The Agda standard library---- Substitutions-------------------------------------------------------------------------- Uses a variant of Conor McBride's technique from his paper-- "Type-Preserving Renaming and Substitution".-- See README.Data.Fin.Substitution.UntypedLambda for an example-- of how this module can be used: a definition of substitution for-- the untyped λ-calculus.{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Substitution whereopen import Data.Nat.Base hiding (_⊔_; _/_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Vec.Baseopen import Function.Base as Fun using (flip)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveas Star using (Star; ε; _◅_)open import Level using (Level; _⊔_; 0ℓ)open import Relation.Unary using (Pred)privatevariableℓ ℓ₁ ℓ₂ : Levelk m n o : ℕ-------------------------------------------------------------------------- General functionality-- A Sub T m n is a substitution which, when applied to something with-- at most m variables, yields something with at most n variables.Sub : Pred ℕ ℓ → ℕ → ℕ → Set ℓSub T m n = Vec (T n) m-- A /reversed/ sequence of matching substitutions.Subs : Pred ℕ ℓ → ℕ → ℕ → Set ℓSubs T = flip (Star (flip (Sub T)))-- Some simple substitutions.record Simple (T : Pred ℕ ℓ) : Set ℓ whereinfix 10 _↑infixl 10 _↑⋆_ _↑✶_fieldvar : ∀ {n} → Fin n → T n -- Takes variables to Ts.weaken : ∀ {n} → T n → T (suc n) -- Weakens Ts.-- Lifting._↑ : Sub T m n → Sub T (suc m) (suc n)ρ ↑ = var zero ∷ map weaken ρ_↑⋆_ : Sub T m n → ∀ k → Sub T (k + m) (k + n)ρ ↑⋆ zero = ρρ ↑⋆ suc k = (ρ ↑⋆ k) ↑_↑✶_ : Subs T m n → ∀ k → Subs T (k + m) (k + n)ρs ↑✶ k = Star.gmap (_+_ k) (λ ρ → ρ ↑⋆ k) ρs-- The identity substitution.id : Sub T n nid {zero} = []id {suc n} = id ↑-- Weakening.wk⋆ : ∀ k → Sub T n (k + n)wk⋆ zero = idwk⋆ (suc k) = map weaken (wk⋆ k)wk : Sub T n (suc n)wk = wk⋆ 1-- A substitution which only replaces the first variable.sub : T n → Sub T (suc n) nsub t = t ∷ id-- Application of substitutions.record Application (T₁ : Pred ℕ ℓ₁) (T₂ : Pred ℕ ℓ₂) : Set (ℓ₁ ⊔ ℓ₂) whereinfixl 8 _/_ _/✶_infixl 9 _⊙_-- Post-application of substitutions to things.field _/_ : ∀ {m n} → T₁ m → Sub T₂ m n → T₁ n-- Reverse composition. (Fits well with post-application.)_⊙_ : Sub T₁ m n → Sub T₂ n o → Sub T₁ m oρ₁ ⊙ ρ₂ = map (_/ ρ₂) ρ₁-- Application of multiple substitutions._/✶_ : T₁ m → Subs T₂ m n → T₁ n_/✶_ = Star.gfold Fun.id _ (flip _/_) {k = zero}-- A combination of the two records above.record Subst (T : Pred ℕ ℓ) : Set ℓ wherefieldsimple : Simple Tapplication : Application T Topen Simple simple publicopen Application application public-- Composition of multiple substitutions.⨀ : Subs T m n → Sub T m n⨀ ε = id⨀ (ρ ◅ ε) = ρ -- Convenient optimisation; simplifies some proofs.⨀ (ρ ◅ ρs) = ⨀ ρs ⊙ ρ-------------------------------------------------------------------------- Instantiations and code for facilitating instantiations-- Liftings from T₁ to T₂.record Lift (T₁ : Pred ℕ ℓ₁) (T₂ : Pred ℕ ℓ₂) : Set (ℓ₁ ⊔ ℓ₂) wherefieldsimple : Simple T₁lift : ∀ {n} → T₁ n → T₂ nopen Simple simple public-- Variable substitutions (renamings).module VarSubst wheresubst : Subst Finsubst = record{ simple = record { var = Fun.id; weaken = suc }; application = record { _/_ = flip lookup }}open Subst subst public-- "Term" substitutions.record TermSubst (T : Pred ℕ 0ℓ) : Set₁ wherefieldvar : ∀ {n} → Fin n → T napp : ∀ {T′ : Pred ℕ 0ℓ} → Lift T′ T → ∀ {m n} → T m → Sub T′ m n → T nmodule Lifted {T′ : Pred ℕ 0ℓ} (lift : Lift T′ T) whereapplication : Application T T′application = record { _/_ = app lift }open Lift lift publicopen Application application publicvarLift : Lift Fin TvarLift = record { simple = VarSubst.simple; lift = var }infixl 8 _/Var__/Var_ : T m → Sub Fin m n → T n_/Var_ = app varLiftsimple : Simple Tsimple = record{ var = var; weaken = λ t → t /Var VarSubst.wk}termLift : Lift T TtermLift = record { simple = simple; lift = Fun.id }subst : Subst Tsubst = record{ simple = simple; application = Lifted.application termLift}open Subst subst public hiding (var; simple)
-------------------------------------------------------------------------- The Agda standard library---- Application of substitutions to lists, along with various lemmas-------------------------------------------------------------------------- This module illustrates how Data.Fin.Substitution.Lemmas.AppLemmas-- can be used.{-# OPTIONS --cubical-compatible --safe #-}open import Data.Fin.Substitution.Lemmas using (Lemmas₄; AppLemmas)open import Data.Nat.Base using (ℕ)module Data.Fin.Substitution.List {ℓ} {T : ℕ → Set ℓ} (lemmas₄ : Lemmas₄ T) whereopen import Data.List.Base using (List; map)open import Data.List.Properties using (map-id; map-cong; map-∘)open import Data.Fin.Substitution using (Sub)import Function.Base as Funopen import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablem n : ℕListT : ℕ → Set ℓListT = List Fun.∘ Topen module L = Lemmas₄ lemmas₄ using (_/_; id; _⊙_)-------------------------------------------------------------------------- Listwise application of a substitution, plus lemmas about itinfixl 8 _//__//_ : ListT m → Sub T m n → ListT nts // ρ = map (λ σ → σ / ρ) tsappLemmas : AppLemmas ListT TappLemmas = record{ application = record { _/_ = _//_ }; lemmas₄ = lemmas₄; id-vanishes = λ ts → begints // id ≡⟨ map-cong L.id-vanishes ts ⟩map Fun.id ts ≡⟨ map-id ts ⟩ts ∎; /-⊙ = λ {_ _ _ ρ₁ ρ₂} ts → begints // ρ₁ ⊙ ρ₂ ≡⟨ map-cong L./-⊙ ts ⟩map (λ σ → σ / ρ₁ / ρ₂) ts ≡⟨ map-∘ ts ⟩ts // ρ₁ // ρ₂ ∎} where open ≡-Reasoningopen AppLemmas appLemmas publichiding (_/_) renaming (_/✶_ to _//✶_)
-------------------------------------------------------------------------- The Agda standard library---- Substitution lemmas------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Substitution.Lemmas whereopen import Data.Fin.Substitutionopen import Data.Nat.Base using (ℕ; zero; suc; _+_)open import Data.Fin.Base using (Fin; zero; suc; lift)open import Data.Vec.Base using (lookup; []; _∷_; map)import Data.Vec.Properties as Vecopen import Function.Base as Fun using (_∘_; _$_; flip)open import Level using (Level; _⊔_)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; refl; sym; cong; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (Star; ε; _◅_; _▻_)open ≡-Reasoningopen import Relation.Unary using (Pred)privatevariableℓ ℓ₁ ℓ₂ : Levelm n o p : ℕ-------------------------------------------------------------------------- A lemma which does not refer to any substitutions.lift-commutes : ∀ k j (x : Fin (j + (k + n))) →lift j suc (lift j (lift k suc) x) ≡lift j (lift (suc k) suc) (lift j suc x)lift-commutes k zero x = refllift-commutes k (suc j) zero = refllift-commutes k (suc j) (suc x) = cong suc (lift-commutes k j x)-------------------------------------------------------------------------- The modules below prove a number of substitution lemmas, on the-- assumption that the underlying substitution machinery satisfies-- certain properties.record Lemmas₀ (T : Pred ℕ ℓ) : Set ℓ wherefield simple : Simple Topen Simple simpleextensionality : {ρ₁ ρ₂ : Sub T m n} →(∀ x → lookup ρ₁ x ≡ lookup ρ₂ x) → ρ₁ ≡ ρ₂extensionality {ρ₁ = []} {[]} hyp = reflextensionality {ρ₁ = t₁ ∷ ρ₁} { t₂ ∷ ρ₂} hyp with hyp zeroextensionality {ρ₁ = t₁ ∷ ρ₁} {.t₁ ∷ ρ₂} hyp | refl =cong (_∷_ t₁) (extensionality (hyp ∘ suc))id-↑⋆ : ∀ {n} k → id ↑⋆ k ≡ id {k + n}id-↑⋆ zero = reflid-↑⋆ (suc k) = begin(id ↑⋆ k) ↑ ≡⟨ cong _↑ (id-↑⋆ k) ⟩id ↑ ∎lookup-map-weaken-↑⋆ : ∀ k x {ρ : Sub T m n} →lookup (map weaken ρ ↑⋆ k) x ≡lookup ((ρ ↑) ↑⋆ k) (lift k suc x)lookup-map-weaken-↑⋆ zero x = refllookup-map-weaken-↑⋆ (suc k) zero = refllookup-map-weaken-↑⋆ (suc k) (suc x) {ρ} = beginlookup (map weaken (map weaken ρ ↑⋆ k)) x ≡⟨ Vec.lookup-map x weaken (map weaken ρ ↑⋆ k) ⟩weaken (lookup (map weaken ρ ↑⋆ k) x) ≡⟨ cong weaken (lookup-map-weaken-↑⋆ k x) ⟩weaken (lookup ((ρ ↑) ↑⋆ k) (lift k suc x)) ≡⟨ sym $ Vec.lookup-map (lift k suc x) weaken ((ρ ↑) ↑⋆ k) ⟩lookup (map weaken ((ρ ↑) ↑⋆ k)) (lift k suc x) ∎record Lemmas₁ (T : Pred ℕ ℓ) : Set ℓ wherefield lemmas₀ : Lemmas₀ Topen Lemmas₀ lemmas₀open Simple simplefield weaken-var : ∀ {n} {x : Fin n} → weaken (var x) ≡ var (suc x)lookup-map-weaken : ∀ x {y} {ρ : Sub T m n} →lookup ρ x ≡ var y →lookup (map weaken ρ) x ≡ var (suc y)lookup-map-weaken x {y} {ρ} hyp = beginlookup (map weaken ρ) x ≡⟨ Vec.lookup-map x weaken ρ ⟩weaken (lookup ρ x) ≡⟨ cong weaken hyp ⟩weaken (var y) ≡⟨ weaken-var ⟩var (suc y) ∎mutuallookup-id : (x : Fin n) → lookup id x ≡ var xlookup-id zero = refllookup-id (suc x) = lookup-wk xlookup-wk : (x : Fin n) → lookup wk x ≡ var (suc x)lookup-wk x = lookup-map-weaken x {ρ = id} (lookup-id x)lookup-↑⋆ : (f : Fin m → Fin n) {ρ : Sub T m n} →(∀ x → lookup ρ x ≡ var (f x)) →∀ k x → lookup (ρ ↑⋆ k) x ≡ var (lift k f x)lookup-↑⋆ f hyp zero x = hyp xlookup-↑⋆ f hyp (suc k) zero = refllookup-↑⋆ f {ρ = ρ} hyp (suc k) (suc x) =lookup-map-weaken x {ρ = ρ ↑⋆ k} (lookup-↑⋆ f hyp k x)lookup-lift-↑⋆ : (f : Fin n → Fin m) {ρ : Sub T m n} →(∀ x → lookup ρ (f x) ≡ var x) →∀ k x → lookup (ρ ↑⋆ k) (lift k f x) ≡ var xlookup-lift-↑⋆ f hyp zero x = hyp xlookup-lift-↑⋆ f hyp (suc k) zero = refllookup-lift-↑⋆ f {ρ = ρ} hyp (suc k) (suc x) =lookup-map-weaken (lift k f x) {ρ = ρ ↑⋆ k} (lookup-lift-↑⋆ f hyp k x)lookup-wk-↑⋆ : ∀ k (x : Fin (k + n)) →lookup (wk ↑⋆ k) x ≡ var (lift k suc x)lookup-wk-↑⋆ = lookup-↑⋆ suc lookup-wklookup-wk-↑⋆-↑⋆ : ∀ k j (x : Fin (j + (k + n))) →lookup (wk ↑⋆ k ↑⋆ j) x ≡var (lift j (lift k suc) x)lookup-wk-↑⋆-↑⋆ k = lookup-↑⋆ (lift k suc) (lookup-wk-↑⋆ k)lookup-sub-↑⋆ : ∀ {t} k (x : Fin (k + n)) →lookup (sub t ↑⋆ k) (lift k suc x) ≡ var xlookup-sub-↑⋆ = lookup-lift-↑⋆ suc lookup-idopen Lemmas₀ lemmas₀ publicrecord Lemmas₂ (T : Pred ℕ ℓ) : Set ℓ wherefieldlemmas₁ : Lemmas₁ Tapplication : Application T Topen Lemmas₁ lemmas₁subst : Subst Tsubst = record { simple = simple; application = application }open Subst substfield var-/ : ∀ {m n x} {ρ : Sub T m n} → var x / ρ ≡ lookup ρ xsuc-/-sub : ∀ {x} {t : T n} → var (suc x) / sub t ≡ var xsuc-/-sub {x = x} {t} = beginvar (suc x) / sub t ≡⟨ var-/ ⟩lookup (sub t) (suc x) ≡⟨ refl ⟩lookup id x ≡⟨ lookup-id x ⟩var x ∎lookup-⊙ : ∀ x {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} →lookup (ρ₁ ⊙ ρ₂) x ≡ lookup ρ₁ x / ρ₂lookup-⊙ x {ρ₁} {ρ₂} = Vec.lookup-map x (λ t → t / ρ₂) ρ₁lookup-⨀ : ∀ x (ρs : Subs T m n) →lookup (⨀ ρs) x ≡ var x /✶ ρslookup-⨀ x ε = lookup-id xlookup-⨀ x (ρ ◅ ε) = sym var-/lookup-⨀ x (ρ ◅ (ρ′ ◅ ρs′)) = beginlookup (⨀ (ρ ◅ ρs)) x ≡⟨ refl ⟩lookup (⨀ ρs ⊙ ρ) x ≡⟨ lookup-⊙ x {ρ₁ = ⨀ (ρ′ ◅ ρs′)} ⟩lookup (⨀ ρs) x / ρ ≡⟨ cong₂ _/_ (lookup-⨀ x (ρ′ ◅ ρs′)) refl ⟩var x /✶ ρs / ρ ∎where ρs = ρ′ ◅ ρs′id-⊙ : {ρ : Sub T m n} → id ⊙ ρ ≡ ρid-⊙ {ρ = ρ} = extensionality λ x → beginlookup (id ⊙ ρ) x ≡⟨ lookup-⊙ x {ρ₁ = id} ⟩lookup id x / ρ ≡⟨ cong₂ _/_ (lookup-id x) refl ⟩var x / ρ ≡⟨ var-/ ⟩lookup ρ x ∎lookup-wk-↑⋆-⊙ : ∀ k {x} {ρ : Sub T (k + suc m) n} →lookup (wk ↑⋆ k ⊙ ρ) x ≡ lookup ρ (lift k suc x)lookup-wk-↑⋆-⊙ k {x} {ρ} = beginlookup (wk ↑⋆ k ⊙ ρ) x ≡⟨ lookup-⊙ x {ρ₁ = wk ↑⋆ k} ⟩lookup (wk ↑⋆ k) x / ρ ≡⟨ cong₂ _/_ (lookup-wk-↑⋆ k x) refl ⟩var (lift k suc x) / ρ ≡⟨ var-/ ⟩lookup ρ (lift k suc x) ∎wk-⊙-sub′ : ∀ {t : T n} k → wk ↑⋆ k ⊙ sub t ↑⋆ k ≡ idwk-⊙-sub′ {t = t} k = extensionality λ x → beginlookup (wk ↑⋆ k ⊙ sub t ↑⋆ k) x ≡⟨ lookup-wk-↑⋆-⊙ k ⟩lookup (sub t ↑⋆ k) (lift k suc x) ≡⟨ lookup-sub-↑⋆ k x ⟩var x ≡⟨ sym (lookup-id x) ⟩lookup id x ∎wk-⊙-sub : {t : T n} → wk ⊙ sub t ≡ idwk-⊙-sub = wk-⊙-sub′ zerovar-/-wk-↑⋆ : ∀ {n} k (x : Fin (k + n)) →var x / wk ↑⋆ k ≡ var (lift k suc x)var-/-wk-↑⋆ k x = beginvar x / wk ↑⋆ k ≡⟨ var-/ ⟩lookup (wk ↑⋆ k) x ≡⟨ lookup-wk-↑⋆ k x ⟩var (lift k suc x) ∎wk-↑⋆-⊙-wk : ∀ k j →wk {n} ↑⋆ k ↑⋆ j ⊙ wk ↑⋆ j ≡wk ↑⋆ j ⊙ wk ↑⋆ suc k ↑⋆ jwk-↑⋆-⊙-wk k j = extensionality λ x → beginlookup (wk ↑⋆ k ↑⋆ j ⊙ wk ↑⋆ j) x ≡⟨ lookup-⊙ x {ρ₁ = wk ↑⋆ k ↑⋆ j} ⟩lookup (wk ↑⋆ k ↑⋆ j) x / wk ↑⋆ j ≡⟨ cong₂ _/_ (lookup-wk-↑⋆-↑⋆ k j x) refl ⟩var (lift j (lift k suc) x) / wk ↑⋆ j ≡⟨ var-/-wk-↑⋆ j (lift j (lift k suc) x) ⟩var (lift j suc (lift j (lift k suc) x)) ≡⟨ cong var (lift-commutes k j x) ⟩var (lift j (lift (suc k) suc) (lift j suc x)) ≡⟨ sym (lookup-wk-↑⋆-↑⋆ (suc k) j (lift j suc x)) ⟩lookup (wk ↑⋆ suc k ↑⋆ j) (lift j suc x) ≡⟨ sym var-/ ⟩var (lift j suc x) / wk ↑⋆ suc k ↑⋆ j ≡⟨ cong₂ _/_ (sym (lookup-wk-↑⋆ j x)) refl ⟩lookup (wk ↑⋆ j) x / wk ↑⋆ suc k ↑⋆ j ≡⟨ sym (lookup-⊙ x {ρ₁ = wk ↑⋆ j}) ⟩lookup (wk ↑⋆ j ⊙ wk ↑⋆ suc k ↑⋆ j) x ∎open Subst subst public hiding (simple; application)open Lemmas₁ lemmas₁ publicrecord Lemmas₃ (T : Pred ℕ ℓ) : Set ℓ wherefield lemmas₂ : Lemmas₂ Topen Lemmas₂ lemmas₂field/✶-↑✶ : ∀ {m n} (ρs₁ ρs₂ : Subs T m n) →(∀ k x → var x /✶ ρs₁ ↑✶ k ≡ var x /✶ ρs₂ ↑✶ k) →∀ k t → t /✶ ρs₁ ↑✶ k ≡ t /✶ ρs₂ ↑✶ k/✶-↑✶′ : (ρs₁ ρs₂ : Subs T m n) →(∀ k → ⨀ (ρs₁ ↑✶ k) ≡ ⨀ (ρs₂ ↑✶ k)) →∀ k t → t /✶ ρs₁ ↑✶ k ≡ t /✶ ρs₂ ↑✶ k/✶-↑✶′ ρs₁ ρs₂ hyp = /✶-↑✶ ρs₁ ρs₂ (λ k x → beginvar x /✶ ρs₁ ↑✶ k ≡⟨ sym (lookup-⨀ x (ρs₁ ↑✶ k)) ⟩lookup (⨀ (ρs₁ ↑✶ k)) x ≡⟨ cong (flip lookup x) (hyp k) ⟩lookup (⨀ (ρs₂ ↑✶ k)) x ≡⟨ lookup-⨀ x (ρs₂ ↑✶ k) ⟩var x /✶ ρs₂ ↑✶ k ∎)id-vanishes : (t : T n) → t / id ≡ tid-vanishes = /✶-↑✶′ (ε ▻ id) ε id-↑⋆ zero⊙-id : {ρ : Sub T m n} → ρ ⊙ id ≡ ρ⊙-id {ρ = ρ} = beginmap (λ t → t / id) ρ ≡⟨ Vec.map-cong id-vanishes ρ ⟩map Fun.id ρ ≡⟨ Vec.map-id ρ ⟩ρ ∎open Lemmas₂ lemmas₂ public hiding (wk-⊙-sub′)record Lemmas₄ (T : Pred ℕ ℓ) : Set ℓ wherefield lemmas₃ : Lemmas₃ Topen Lemmas₃ lemmas₃field /-wk : ∀ {n} {t : T n} → t / wk ≡ weaken tprivate↑-distrib′ : {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} →(∀ t → t / ρ₂ / wk ≡ t / wk / ρ₂ ↑) →(ρ₁ ⊙ ρ₂) ↑ ≡ ρ₁ ↑ ⊙ ρ₂ ↑↑-distrib′ {ρ₁ = ρ₁} {ρ₂} hyp = begin(ρ₁ ⊙ ρ₂) ↑ ≡⟨ refl ⟩var zero ∷ map weaken (ρ₁ ⊙ ρ₂) ≡⟨ cong₂ _∷_ (sym var-/) lemma ⟩var zero / ρ₂ ↑ ∷ map weaken ρ₁ ⊙ ρ₂ ↑ ≡⟨ refl ⟩ρ₁ ↑ ⊙ ρ₂ ↑ ∎wherelemma = beginmap weaken (map (λ t → t / ρ₂) ρ₁) ≡⟨ sym (Vec.map-∘ _ _ _) ⟩map (λ t → weaken (t / ρ₂)) ρ₁ ≡⟨ Vec.map-cong (λ t → beginweaken (t / ρ₂) ≡⟨ sym /-wk ⟩t / ρ₂ / wk ≡⟨ hyp t ⟩t / wk / ρ₂ ↑ ≡⟨ cong₂ _/_ /-wk refl ⟩weaken t / ρ₂ ↑ ∎) ρ₁ ⟩map (λ t → weaken t / ρ₂ ↑) ρ₁ ≡⟨ Vec.map-∘ _ _ _ ⟩map (λ t → t / ρ₂ ↑) (map weaken ρ₁) ∎↑⋆-distrib′ : {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} →(∀ k t → t / ρ₂ ↑⋆ k / wk ≡ t / wk / ρ₂ ↑⋆ suc k) →∀ k → (ρ₁ ⊙ ρ₂) ↑⋆ k ≡ ρ₁ ↑⋆ k ⊙ ρ₂ ↑⋆ k↑⋆-distrib′ hyp zero = refl↑⋆-distrib′ {ρ₁ = ρ₁} {ρ₂} hyp (suc k) = begin(ρ₁ ⊙ ρ₂) ↑⋆ suc k ≡⟨ cong _↑ (↑⋆-distrib′ hyp k) ⟩(ρ₁ ↑⋆ k ⊙ ρ₂ ↑⋆ k) ↑ ≡⟨ ↑-distrib′ (hyp k) ⟩ρ₁ ↑⋆ suc k ⊙ ρ₂ ↑⋆ suc k ∎map-weaken : {ρ : Sub T m n} → map weaken ρ ≡ ρ ⊙ wkmap-weaken {ρ = ρ} = beginmap weaken ρ ≡⟨ Vec.map-cong (λ _ → sym /-wk) ρ ⟩map (λ t → t / wk) ρ ≡⟨ refl ⟩ρ ⊙ wk ∎private⊙-wk′ : ∀ {ρ : Sub T m n} k →ρ ↑⋆ k ⊙ wk ↑⋆ k ≡ wk ↑⋆ k ⊙ ρ ↑ ↑⋆ k⊙-wk′ {ρ = ρ} k = sym (beginwk ↑⋆ k ⊙ ρ ↑ ↑⋆ k ≡⟨ lemma ⟩map weaken ρ ↑⋆ k ≡⟨ cong (λ ρ′ → ρ′ ↑⋆ k) map-weaken ⟩(ρ ⊙ wk) ↑⋆ k ≡⟨ ↑⋆-distrib′ (λ k t →/✶-↑✶′ (ε ▻ wk ↑⋆ k ▻ wk) (ε ▻ wk ▻ wk ↑⋆ suc k)(wk-↑⋆-⊙-wk k) zero t) k ⟩ρ ↑⋆ k ⊙ wk ↑⋆ k ∎)wherelemma = extensionality λ x → beginlookup (wk ↑⋆ k ⊙ ρ ↑ ↑⋆ k) x ≡⟨ lookup-wk-↑⋆-⊙ k ⟩lookup (ρ ↑ ↑⋆ k) (lift k suc x) ≡⟨ sym (lookup-map-weaken-↑⋆ k x) ⟩lookup (map weaken ρ ↑⋆ k) x ∎⊙-wk : {ρ : Sub T m n} → ρ ⊙ wk ≡ wk ⊙ ρ ↑⊙-wk = ⊙-wk′ zerowk-commutes : ∀ {ρ : Sub T m n} t →t / ρ / wk ≡ t / wk / ρ ↑wk-commutes {ρ = ρ} = /✶-↑✶′ (ε ▻ ρ ▻ wk) (ε ▻ wk ▻ ρ ↑) ⊙-wk′ zero↑⋆-distrib : {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} →∀ k → (ρ₁ ⊙ ρ₂) ↑⋆ k ≡ ρ₁ ↑⋆ k ⊙ ρ₂ ↑⋆ k↑⋆-distrib = ↑⋆-distrib′ (λ _ → wk-commutes)/-⊙ : ∀ {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} t →t / ρ₁ ⊙ ρ₂ ≡ t / ρ₁ / ρ₂/-⊙ {ρ₁ = ρ₁} {ρ₂} t =/✶-↑✶′ (ε ▻ ρ₁ ⊙ ρ₂) (ε ▻ ρ₁ ▻ ρ₂) ↑⋆-distrib zero t⊙-assoc : {ρ₁ : Sub T m n} {ρ₂ : Sub T n o} {ρ₃ : Sub T o p} →ρ₁ ⊙ (ρ₂ ⊙ ρ₃) ≡ (ρ₁ ⊙ ρ₂) ⊙ ρ₃⊙-assoc {ρ₁ = ρ₁} {ρ₂} {ρ₃} = beginmap (λ t → t / ρ₂ ⊙ ρ₃) ρ₁ ≡⟨ Vec.map-cong /-⊙ ρ₁ ⟩map (λ t → t / ρ₂ / ρ₃) ρ₁ ≡⟨ Vec.map-∘ _ _ _ ⟩map (λ t → t / ρ₃) (map (λ t → t / ρ₂) ρ₁) ∎map-weaken-⊙-sub : ∀ {ρ : Sub T m n} {t} → map weaken ρ ⊙ sub t ≡ ρmap-weaken-⊙-sub {ρ = ρ} {t} = beginmap weaken ρ ⊙ sub t ≡⟨ cong₂ _⊙_ map-weaken refl ⟩ρ ⊙ wk ⊙ sub t ≡⟨ sym ⊙-assoc ⟩ρ ⊙ (wk ⊙ sub t) ≡⟨ cong (_⊙_ ρ) wk-⊙-sub ⟩ρ ⊙ id ≡⟨ ⊙-id ⟩ρ ∎sub-⊙ : ∀ {ρ : Sub T m n} t → sub t ⊙ ρ ≡ ρ ↑ ⊙ sub (t / ρ)sub-⊙ {ρ = ρ} t = beginsub t ⊙ ρ ≡⟨ refl ⟩t / ρ ∷ id ⊙ ρ ≡⟨ cong (_∷_ (t / ρ)) id-⊙ ⟩t / ρ ∷ ρ ≡⟨ cong (_∷_ (t / ρ)) (sym map-weaken-⊙-sub) ⟩t / ρ ∷ map weaken ρ ⊙ sub (t / ρ) ≡⟨ cong₂ _∷_ (sym var-/) refl ⟩ρ ↑ ⊙ sub (t / ρ) ∎suc-/-↑ : ∀ {ρ : Sub T m n} x →var (suc x) / ρ ↑ ≡ var x / ρ / wksuc-/-↑ {ρ = ρ} x = beginvar (suc x) / ρ ↑ ≡⟨ var-/ ⟩lookup (map weaken ρ) x ≡⟨ cong (flip lookup x) (map-weaken {ρ = ρ}) ⟩lookup (ρ ⊙ wk) x ≡⟨ lookup-⊙ x {ρ₁ = ρ} ⟩lookup ρ x / wk ≡⟨ cong₂ _/_ (sym var-/) refl ⟩var x / ρ / wk ∎weaken-↑ : ∀ t {ρ : Sub T m n} → weaken t / (ρ ↑) ≡ weaken (t / ρ)weaken-↑ t {ρ} = beginweaken t / (ρ ↑) ≡⟨ cong (_/ ρ ↑) (sym /-wk) ⟩t / wk / ρ ↑ ≡⟨ sym (wk-commutes t) ⟩t / ρ / wk ≡⟨ /-wk ⟩weaken (t / ρ) ∎open Lemmas₃ lemmas₃ publichiding (/✶-↑✶; /✶-↑✶′; wk-↑⋆-⊙-wk;lookup-wk-↑⋆-⊙; lookup-map-weaken-↑⋆)-------------------------------------------------------------------------- For an example of how AppLemmas can be used, see-- Data.Fin.Substitution.List.record AppLemmas (T₁ : Pred ℕ ℓ₁) (T₂ : Pred ℕ ℓ₂) : Set (ℓ₁ ⊔ ℓ₂) wherefieldapplication : Application T₁ T₂lemmas₄ : Lemmas₄ T₂open Application application using (_/_; _/✶_)open Lemmas₄ lemmas₄using (id; _⊙_; wk; weaken; sub; _↑; ⨀; /-wk) renaming (_/_ to _⊘_)fieldid-vanishes : ∀ {n} (t : T₁ n) → t / id ≡ t/-⊙ : ∀ {m n k} {ρ₁ : Sub T₂ m n} {ρ₂ : Sub T₂ n k} t →t / ρ₁ ⊙ ρ₂ ≡ t / ρ₁ / ρ₂private module L₄ = Lemmas₄ lemmas₄/-⨀ : ∀ t (ρs : Subs T₂ m n) → t / ⨀ ρs ≡ t /✶ ρs/-⨀ t ε = id-vanishes t/-⨀ t (ρ ◅ ε) = refl/-⨀ t (ρ ◅ (ρ′ ◅ ρs′)) = begint / ⨀ ρs ⊙ ρ ≡⟨ /-⊙ t ⟩t / ⨀ ρs / ρ ≡⟨ cong₂ _/_ (/-⨀ t (ρ′ ◅ ρs′)) refl ⟩t /✶ ρs / ρ ∎where ρs = ρ′ ◅ ρs′⨀→/✶ : (ρs₁ ρs₂ : Subs T₂ m n) →⨀ ρs₁ ≡ ⨀ ρs₂ → ∀ t → t /✶ ρs₁ ≡ t /✶ ρs₂⨀→/✶ ρs₁ ρs₂ hyp t = begint /✶ ρs₁ ≡⟨ sym (/-⨀ t ρs₁) ⟩t / ⨀ ρs₁ ≡⟨ cong (_/_ t) hyp ⟩t / ⨀ ρs₂ ≡⟨ /-⨀ t ρs₂ ⟩t /✶ ρs₂ ∎wk-commutes : ∀ {ρ : Sub T₂ m n} t →t / ρ / wk ≡ t / wk / ρ ↑wk-commutes {ρ = ρ} = ⨀→/✶ (ε ▻ ρ ▻ wk) (ε ▻ wk ▻ ρ ↑) L₄.⊙-wksub-commutes : ∀ {t′} {ρ : Sub T₂ m n} t →t / sub t′ / ρ ≡ t / ρ ↑ / sub (t′ ⊘ ρ)sub-commutes {t′ = t′} {ρ} =⨀→/✶ (ε ▻ sub t′ ▻ ρ) (ε ▻ ρ ↑ ▻ sub (t′ ⊘ ρ)) (L₄.sub-⊙ t′)wk-sub-vanishes : ∀ {t′} (t : T₁ n) → t / wk / sub t′ ≡ twk-sub-vanishes {t′ = t′} = ⨀→/✶ (ε ▻ wk ▻ sub t′) ε L₄.wk-⊙-sub/-weaken : ∀ {ρ : Sub T₂ m n} t → t / map weaken ρ ≡ t / ρ / wk/-weaken {ρ = ρ} = ⨀→/✶ (ε ▻ map weaken ρ) (ε ▻ ρ ▻ wk) L₄.map-weakenopen Application application publicopen L₄ publichiding (application; _⊙_; _/_; _/✶_;id-vanishes; /-⊙; wk-commutes)record Lemmas₅ {ℓ} (T : Pred ℕ ℓ) : Set ℓ wherefield lemmas₄ : Lemmas₄ Tprivate module L₄ = Lemmas₄ lemmas₄appLemmas : AppLemmas T TappLemmas = record{ application = L₄.application; lemmas₄ = lemmas₄; id-vanishes = L₄.id-vanishes; /-⊙ = L₄./-⊙}open AppLemmas appLemmas public hiding (lemmas₄)-------------------------------------------------------------------------- Instantiations and code for facilitating instantiations-- Lemmas about variable substitutions (renamings).module VarLemmas whereopen VarSubstlemmas₃ : Lemmas₃ Finlemmas₃ = record{ lemmas₂ = record{ lemmas₁ = record{ lemmas₀ = record{ simple = simple}; weaken-var = refl}; application = application; var-/ = refl}; /✶-↑✶ = λ _ _ hyp → hyp}private module L₃ = Lemmas₃ lemmas₃lemmas₅ : Lemmas₅ Finlemmas₅ = record{ lemmas₄ = record{ lemmas₃ = lemmas₃; /-wk = L₃.lookup-wk _}}open Lemmas₅ lemmas₅ public hiding (lemmas₃)-- Lemmas about "term" substitutions.record TermLemmas (T : ℕ → Set) : Set₁ wherefieldtermSubst : TermSubst Topen TermSubst termSubstprivate module T = TermSubst termSubstfieldapp-var : ∀ {T′} {lift : Lift T′ T} {m n x} {ρ : Sub T′ m n} →app lift (var x) ρ ≡ Lift.lift lift (lookup ρ x)/✶-↑✶ : ∀ {T₁ T₂} {lift₁ : Lift T₁ T} {lift₂ : Lift T₂ T} →let open Lifted lift₁using () renaming (_↑✶_ to _↑✶₁_; _/✶_ to _/✶₁_)open Lifted lift₂using () renaming (_↑✶_ to _↑✶₂_; _/✶_ to _/✶₂_)in∀ {m n} (ρs₁ : Subs T₁ m n) (ρs₂ : Subs T₂ m n) →(∀ k x → var x /✶₁ ρs₁ ↑✶₁ k ≡ var x /✶₂ ρs₂ ↑✶₂ k) →∀ k t → t /✶₁ ρs₁ ↑✶₁ k ≡ t /✶₂ ρs₂ ↑✶₂ kprivate module V = VarLemmaslemmas₃ : Lemmas₃ Tlemmas₃ = record{ lemmas₂ = record{ lemmas₁ = record{ lemmas₀ = record{ simple = simple}; weaken-var = λ {_ x} → beginvar x /Var V.wk ≡⟨ app-var ⟩var (lookup V.wk x) ≡⟨ cong var (V.lookup-wk x) ⟩var (suc x) ∎}; application = Subst.application subst; var-/ = app-var}; /✶-↑✶ = /✶-↑✶}private module L₃ = Lemmas₃ lemmas₃lemmas₅ : Lemmas₅ Tlemmas₅ = record{ lemmas₄ = record{ lemmas₃ = lemmas₃; /-wk = λ {_ t} → begint / wk ≡⟨ /✶-↑✶ (ε ▻ wk) (ε ▻ V.wk)(λ k x → beginvar x / wk ↑⋆ k ≡⟨ L₃.var-/-wk-↑⋆ k x ⟩var (lift k suc x) ≡⟨ cong var (sym (V.var-/-wk-↑⋆ k x)) ⟩var (lookup (V._↑⋆_ V.wk k) x) ≡⟨ sym app-var ⟩var x /Var V._↑⋆_ V.wk k ∎)zero t ⟩t /Var V.wk ≡⟨⟩weaken t ∎}}open Lemmas₅ lemmas₅ public hiding (lemmas₃)wk-⊙-∷ : (t : T n) (ρ : Sub T m n) → (T.wk T.⊙ (t ∷ ρ)) ≡ ρwk-⊙-∷ t ρ = extensionality λ x → beginlookup (T.wk T.⊙ (t ∷ ρ)) x ≡⟨ L₃.lookup-wk-↑⋆-⊙ 0 {ρ = t ∷ ρ} ⟩lookup ρ x ∎weaken-∷ : (t₁ : T m) {t₂ : T n} {ρ : Sub T m n} →T.weaken t₁ T./ (t₂ ∷ ρ) ≡ t₁ T./ ρweaken-∷ t₁ {t₂} {ρ} = beginT.weaken t₁ T./ (t₂ ∷ ρ) ≡⟨ cong (T._/ (t₂ ∷ ρ)) (sym /-wk) ⟩(t₁ T./ T.wk) T./ (t₂ ∷ ρ) ≡⟨ ⨀→/✶ ((t₂ ∷ ρ) ◅ T.wk ◅ ε) (ρ ◅ ε) (wk-⊙-∷ t₂ ρ) t₁ ⟩t₁ T./ ρ ∎weaken-sub : (t₁ : T n) {t₂ : T n} → T.weaken t₁ T./ (T.sub t₂) ≡ t₁weaken-sub t₁ {t₂} = beginT.weaken t₁ T./ (T.sub t₂) ≡⟨ weaken-∷ t₁ ⟩t₁ T./ T.id ≡⟨ id-vanishes t₁ ⟩t₁ ∎-- Lemmas relating renamings to substitutions.map-var≡ : {ρ₁ : Sub Fin m n} {ρ₂ : Sub T m n} {f : Fin m → Fin n} →(∀ x → lookup ρ₁ x ≡ f x) →(∀ x → lookup ρ₂ x ≡ T.var (f x)) →map T.var ρ₁ ≡ ρ₂map-var≡ {ρ₁ = ρ₁} {ρ₂ = ρ₂} {f = f} hyp₁ hyp₂ = extensionality λ x →lookup (map T.var ρ₁) x ≡⟨ Vec.lookup-map x _ ρ₁ ⟩T.var (lookup ρ₁ x) ≡⟨ cong T.var $ hyp₁ x ⟩T.var (f x) ≡⟨ sym $ hyp₂ x ⟩lookup ρ₂ x ∎wk≡wk : map T.var VarSubst.wk ≡ T.wk {n = n}wk≡wk = map-var≡ VarLemmas.lookup-wk lookup-wkid≡id : map T.var VarSubst.id ≡ T.id {n = n}id≡id = map-var≡ VarLemmas.lookup-id lookup-idsub≡sub : {x : Fin n} → map T.var (VarSubst.sub x) ≡ T.sub (T.var x)sub≡sub = cong (_ ∷_) id≡id↑≡↑ : {ρ : Sub Fin m n} → map T.var (ρ VarSubst.↑) ≡ map T.var ρ T.↑↑≡↑ {ρ = ρ} = map-var≡(VarLemmas.lookup-↑⋆ (lookup ρ) (λ _ → refl) 1)(lookup-↑⋆ (lookup ρ) (λ _ → Vec.lookup-map _ _ ρ) 1)/Var≡/ : ∀ {ρ : Sub Fin m n} {t} → t /Var ρ ≡ t T./ map T.var ρ/Var≡/ {ρ = ρ} {t = t} =/✶-↑✶ (ε ▻ ρ) (ε ▻ map T.var ρ)(λ k x →T.var x /Var ρ VarSubst.↑⋆ k ≡⟨ app-var ⟩T.var (lookup (ρ VarSubst.↑⋆ k) x) ≡⟨ cong T.var $ VarLemmas.lookup-↑⋆ _ (λ _ → refl) k _ ⟩T.var (lift k (VarSubst._/ ρ) x) ≡⟨ sym $ lookup-↑⋆ _ (λ _ → Vec.lookup-map _ _ ρ) k _ ⟩lookup (map T.var ρ T.↑⋆ k) x ≡⟨ sym app-var ⟩T.var x T./ map T.var ρ T.↑⋆ k ∎)zero tsub-renaming-commutes : ∀ {t x} {ρ : Sub T m n} →t /Var VarSubst.sub x T./ ρ ≡ t T./ ρ T.↑ T./ T.sub (lookup ρ x)sub-renaming-commutes {t = t} {x = x} {ρ = ρ} =t /Var VarSubst.sub x T./ ρ ≡⟨ cong (T._/ ρ) /Var≡/ ⟩t T./ map T.var (VarSubst.sub x) T./ ρ ≡⟨ cong (λ ρ′ → t T./ ρ′ T./ ρ) sub≡sub ⟩t T./ T.sub (T.var x) T./ ρ ≡⟨ sub-commutes _ ⟩t T./ ρ T.↑ T./ T.sub (T.var x T./ ρ) ≡⟨ cong (λ t′ → t T./ ρ T.↑ T./ T.sub t′) app-var ⟩t T./ ρ T.↑ T./ T.sub (lookup ρ x) ∎sub-commutes-with-renaming : ∀ {t t′} {ρ : Sub Fin m n} →t T./ T.sub t′ /Var ρ ≡ t /Var ρ VarSubst.↑ T./ T.sub (t′ /Var ρ)sub-commutes-with-renaming {t = t} {t′ = t′} {ρ = ρ} =t T./ T.sub t′ /Var ρ ≡⟨ /Var≡/ ⟩t T./ T.sub t′ T./ map T.var ρ ≡⟨ sub-commutes _ ⟩t T./ map T.var ρ T.↑ T./ T.sub (t′ T./ map T.var ρ) ≡⟨ sym $ cong (λ ρ′ → t T./ ρ′ T./ T.sub (t′ T./ map T.var ρ)) ↑≡↑ ⟩t T./ map T.var (ρ VarSubst.↑) T./ T.sub (t′ T./ map T.var ρ) ≡⟨ sym $ cong₂ (λ t ρ → t T./ T.sub ρ) /Var≡/ /Var≡/ ⟩t /Var ρ VarSubst.↑ T./ T.sub (t′ /Var ρ) ∎
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please see-- `README.Data.Nat.Fin.Substitution.UntypedLambda` instead.--------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Substitution.Example where{-# WARNING_ON_IMPORT"Data.Fin.Substitution.Example was deprecated in v2.0.Please see README.Data.Fin.Substitution.UntypedLambda instead."#-}open import Data.Fin.Substitutionopen import Data.Fin.Substitution.Lemmasopen import Data.Nat.Base hiding (_/_)open import Data.Fin.Base using (Fin)open import Data.Vec.Baseopen import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; cong₂; module ≡-Reasoning)open ≡-Reasoningopen import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (Star; ε; _◅_)-- A representation of the untyped λ-calculus. Uses de Bruijn indices.infixl 9 _·_data Tm (n : ℕ) : Set wherevar : (x : Fin n) → Tm nƛ : (t : Tm (suc n)) → Tm n_·_ : (t₁ t₂ : Tm n) → Tm n-- Code for applying substitutions.module TmApp {ℓ} {T : ℕ → Set ℓ} (l : Lift T Tm) whereopen Lift l hiding (var)-- Applies a substitution to a term.infix 8 _/__/_ : ∀ {m n} → Tm m → Sub T m n → Tm nvar x / ρ = lift (lookup ρ x)ƛ t / ρ = ƛ (t / ρ ↑)t₁ · t₂ / ρ = (t₁ / ρ) · (t₂ / ρ)open Application (record { _/_ = _/_ }) using (_/✶_)-- Some lemmas about _/_.ƛ-/✶-↑✶ : ∀ k {m n t} (ρs : Subs T m n) →ƛ t /✶ ρs ↑✶ k ≡ ƛ (t /✶ ρs ↑✶ suc k)ƛ-/✶-↑✶ k ε = reflƛ-/✶-↑✶ k (ρ ◅ ρs) = cong₂ _/_ (ƛ-/✶-↑✶ k ρs) refl·-/✶-↑✶ : ∀ k {m n t₁ t₂} (ρs : Subs T m n) →t₁ · t₂ /✶ ρs ↑✶ k ≡ (t₁ /✶ ρs ↑✶ k) · (t₂ /✶ ρs ↑✶ k)·-/✶-↑✶ k ε = refl·-/✶-↑✶ k (ρ ◅ ρs) = cong₂ _/_ (·-/✶-↑✶ k ρs) refltmSubst : TermSubst TmtmSubst = record { var = var; app = TmApp._/_ }open TermSubst tmSubst hiding (var)-- Substitution lemmas.tmLemmas : TermLemmas TmtmLemmas = record{ termSubst = tmSubst; app-var = refl; /✶-↑✶ = Lemma./✶-↑✶}wheremodule Lemma {T₁ T₂} {lift₁ : Lift T₁ Tm} {lift₂ : Lift T₂ Tm} whereopen Lifted lift₁ using () renaming (_↑✶_ to _↑✶₁_; _/✶_ to _/✶₁_)open Lifted lift₂ using () renaming (_↑✶_ to _↑✶₂_; _/✶_ to _/✶₂_)/✶-↑✶ : ∀ {m n} (ρs₁ : Subs T₁ m n) (ρs₂ : Subs T₂ m n) →(∀ k x → var x /✶₁ ρs₁ ↑✶₁ k ≡ var x /✶₂ ρs₂ ↑✶₂ k) →∀ k t → t /✶₁ ρs₁ ↑✶₁ k ≡ t /✶₂ ρs₂ ↑✶₂ k/✶-↑✶ ρs₁ ρs₂ hyp k (var x) = hyp k x/✶-↑✶ ρs₁ ρs₂ hyp k (ƛ t) = beginƛ t /✶₁ ρs₁ ↑✶₁ k ≡⟨ TmApp.ƛ-/✶-↑✶ _ k ρs₁ ⟩ƛ (t /✶₁ ρs₁ ↑✶₁ suc k) ≡⟨ cong ƛ (/✶-↑✶ ρs₁ ρs₂ hyp (suc k) t) ⟩ƛ (t /✶₂ ρs₂ ↑✶₂ suc k) ≡⟨ sym (TmApp.ƛ-/✶-↑✶ _ k ρs₂) ⟩ƛ t /✶₂ ρs₂ ↑✶₂ k ∎/✶-↑✶ ρs₁ ρs₂ hyp k (t₁ · t₂) = begint₁ · t₂ /✶₁ ρs₁ ↑✶₁ k ≡⟨ TmApp.·-/✶-↑✶ _ k ρs₁ ⟩(t₁ /✶₁ ρs₁ ↑✶₁ k) · (t₂ /✶₁ ρs₁ ↑✶₁ k) ≡⟨ cong₂ _·_ (/✶-↑✶ ρs₁ ρs₂ hyp k t₁)(/✶-↑✶ ρs₁ ρs₂ hyp k t₂) ⟩(t₁ /✶₂ ρs₂ ↑✶₂ k) · (t₂ /✶₂ ρs₂ ↑✶₂ k) ≡⟨ sym (TmApp.·-/✶-↑✶ _ k ρs₂) ⟩t₁ · t₂ /✶₂ ρs₂ ↑✶₂ k ∎open TermLemmas tmLemmas public hiding (var)
-------------------------------------------------------------------------- The Agda standard library---- Subsets of finite sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Subset whereopen import Algebra.Core using (Op₁; Op₂)open import Data.Bool using (not; _∧_; _∨_; _≟_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.List.Base using (List; foldr; foldl)open import Data.Nat.Base using (ℕ)open import Data.Product.Base using (∃; _×_)open import Data.Vec.Base hiding (foldr; foldl)open import Relation.Nullaryprivatevariablen : ℕ-------------------------------------------------------------------------- Definitions-- Partitions a finite set into two parts, the inside and the outside.-- Note that it would be great to shorten these to `in` and `out` but-- `in` is a keyword (e.g. let ... in ...)-- Sides.open import Data.Bool.Base publicusing () renaming (Bool to Side; true to inside; false to outside)-- SubsetSubset : ℕ → SetSubset = Vec Side-------------------------------------------------------------------------- Special subsets-- The empty subset⊥ : Subset n⊥ = replicate _ outside-- The full subset⊤ : Subset n⊤ = replicate _ inside-- A singleton subset, containing just the given element.⁅_⁆ : Fin n → Subset n⁅ zero ⁆ = inside ∷ ⊥⁅ suc i ⁆ = outside ∷ ⁅ i ⁆-------------------------------------------------------------------------- Membership and subset predicatesinfix 4 _∈_ _∉_ _⊆_ _⊈_ _⊂_ _⊄__∈_ : Fin n → Subset n → Setx ∈ p = p [ x ]= inside_∉_ : Fin n → Subset n → Setx ∉ p = ¬ (x ∈ p)_⊆_ : Subset n → Subset n → Setp ⊆ q = ∀ {x} → x ∈ p → x ∈ q_⊈_ : Subset n → Subset n → Setp ⊈ q = ¬ (p ⊆ q)_⊂_ : Subset n → Subset n → Setp ⊂ q = p ⊆ q × ∃ (λ x → x ∈ q × x ∉ p)_⊄_ : Subset n → Subset n → Setp ⊄ q = ¬ (p ⊂ q)-------------------------------------------------------------------------- Set operationsinfixr 7 _∩_infixr 6 _∪_infixl 5 _─_ _-_-- Complement∁ : Op₁ (Subset n)∁ p = map not p-- Intersection_∩_ : Op₂ (Subset n)p ∩ q = zipWith _∧_ p q-- Union_∪_ : Op₂ (Subset n)p ∪ q = zipWith _∨_ p q-- Difference_─_ : Op₂ (Subset n)p ─ q = zipWith diff p qwherediff : Side → Side → Sidediff x inside = outsidediff x outside = x-- N-ary union⋃ : List (Subset n) → Subset n⋃ = foldr _∪_ ⊥-- N-ary intersection⋂ : List (Subset n) → Subset n⋂ = foldr _∩_ ⊤-- Element removal_-_ : Subset n → Fin n → Subset np - x = p ─ ⁅ x ⁆-- Size∣_∣ : Subset n → ℕ∣ p ∣ = count (_≟ inside) p-------------------------------------------------------------------------- PropertiesNonempty : ∀ (p : Subset n) → SetNonempty p = ∃ λ f → f ∈ pEmpty : ∀ (p : Subset n) → SetEmpty p = ¬ Nonempty pLift : ∀ {ℓ} → (Fin n → Set ℓ) → (Subset n → Set ℓ)Lift P p = ∀ {x} → x ∈ p → P x
-------------------------------------------------------------------------- The Agda standard library---- Some properties about subsets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Subset.Properties whereimport Algebra.Definitions as AlgebraicDefinitionsimport Algebra.Structures as AlgebraicStructuresimport Algebra.Lattice.Structures as AlgebraicLatticeStructuresopen import Algebra.Bundles using (Magma; Semigroup; Monoid; Band;CommutativeMonoid; IdempotentCommutativeMonoid)open import Algebra.Lattice.Bundles using (Semilattice; Lattice;DistributiveLattice; BooleanAlgebra)import Algebra.Lattice.Properties.Lattice as Limport Algebra.Lattice.Properties.DistributiveLattice as DLimport Algebra.Lattice.Properties.BooleanAlgebra as BAopen import Data.Bool.Base using (not)open import Data.Bool.Propertiesopen import Data.Fin.Base using (Fin; suc; zero)open import Data.Fin.Subsetopen import Data.Fin.Properties using (any?; decFinSubset)open import Data.Nat.Base hiding (∣_-_∣)import Data.Nat.Properties as ℕopen import Data.Product as Product using (∃; ∄; _×_; _,_; proj₁)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Vec.Base using (Vec; []; _∷_; here; there)open import Data.Vec.Propertiesopen import Function.Base using (_∘_; const; id; case_of_)open import Function.Bundles using (_⇔_; mk⇔)open import Level using (Level)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsStrictPartialOrder; IsDecStrictPartialOrder)open import Relation.Binary.Bundlesusing (Preorder; Poset; StrictPartialOrder; DecStrictPartialOrder)open import Relation.Binary.Definitions as B hiding (Decidable; Empty)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong; cong₂; subst; _≢_; sym)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning; isEquivalence)open import Relation.Nullary.Decidable as Dec using (Dec; yes; no; _⊎-dec_)open import Relation.Nullary.Negation using (contradiction)open import Relation.Unary using (Pred; Decidable; Satisfiable)privatevariableℓ : Leveln : ℕs t : Sidex y : Fin np q : Subset n-------------------------------------------------------------------------- Constructor manglingdrop-there : suc x ∈ s ∷ p → x ∈ pdrop-there (there x∈p) = x∈pdrop-not-there : suc x ∉ s ∷ p → x ∉ pdrop-not-there x∉sp x∈p = contradiction (there x∈p) x∉spdrop-∷-⊆ : s ∷ p ⊆ t ∷ q → p ⊆ qdrop-∷-⊆ sp⊆tq x∈p = drop-there (sp⊆tq (there x∈p))drop-∷-⊂ : s ∷ p ⊂ s ∷ q → p ⊂ qdrop-∷-⊂ {s = inside} (_ , zero , _ , x∉sp) = contradiction here x∉spdrop-∷-⊂ {s} (sp⊆sq , suc x , there x∈q , x∉sp) = drop-∷-⊆ sp⊆sq , x , x∈q , drop-not-there x∉spout⊆ : p ⊆ q → outside ∷ p ⊆ s ∷ qout⊆ p⊆q (there ∈p) = there (p⊆q ∈p)out⊆-⇔ : p ⊆ q ⇔ outside ∷ p ⊆ s ∷ qout⊆-⇔ = mk⇔ out⊆ drop-∷-⊆in⊆in : p ⊆ q → inside ∷ p ⊆ inside ∷ qin⊆in p⊆q here = herein⊆in p⊆q (there ∈p) = there (p⊆q ∈p)in⊆in-⇔ : p ⊆ q ⇔ inside ∷ p ⊆ inside ∷ qin⊆in-⇔ = mk⇔ in⊆in drop-∷-⊆s⊆s : p ⊆ q → s ∷ p ⊆ s ∷ qs⊆s p⊆q here = heres⊆s p⊆q (there ∈p) = there (p⊆q ∈p)s⊂s : p ⊂ q → s ∷ p ⊂ s ∷ qs⊂s (p⊆q , v , v∈p , v∉q) = s⊆s p⊆q , suc v , there v∈p , v∉q ∘ drop-thereout⊂ : p ⊂ q → outside ∷ p ⊂ s ∷ qout⊂ (p⊆q , x , x∈q , x∉p) = out⊆ p⊆q , suc x , there x∈q , x∉p ∘ drop-therein⊂in : p ⊂ q → inside ∷ p ⊂ inside ∷ qin⊂in = s⊂sout⊂in : p ⊆ q → outside ∷ p ⊂ inside ∷ qout⊂in p⊆q = out⊆ p⊆q , zero , here , λ ()out⊂in-⇔ : p ⊆ q ⇔ outside ∷ p ⊂ inside ∷ qout⊂in-⇔ = mk⇔ out⊂in (drop-∷-⊆ ∘ proj₁)out⊂out-⇔ : p ⊂ q ⇔ outside ∷ p ⊂ outside ∷ qout⊂out-⇔ = mk⇔ out⊂ drop-∷-⊂in⊂in-⇔ : p ⊂ q ⇔ inside ∷ p ⊂ inside ∷ qin⊂in-⇔ = mk⇔ in⊂in drop-∷-⊂-------------------------------------------------------------------------- _∈_infix 4 _∈?__∈?_ : ∀ x (p : Subset n) → Dec (x ∈ p)zero ∈? inside ∷ p = yes herezero ∈? outside ∷ p = no λ()suc n ∈? s ∷ p = Dec.map′ there drop-there (n ∈? p)-------------------------------------------------------------------------- Emptydrop-∷-Empty : Empty (s ∷ p) → Empty pdrop-∷-Empty ¬∃∈ (x , x∈p) = ¬∃∈ (suc x , there x∈p)Empty-unique : Empty p → p ≡ ⊥Empty-unique {p = []} ¬∃∈ = reflEmpty-unique {p = inside ∷ p} ¬∃∈ = contradiction (zero , here) ¬∃∈Empty-unique {p = outside ∷ p} ¬∃∈ =cong (outside ∷_) (Empty-unique (drop-∷-Empty ¬∃∈))nonempty? : Decidable {A = Subset n} Nonemptynonempty? p = any? (_∈? p)-------------------------------------------------------------------------- ∣_∣∣p∣≤n : ∀ (p : Subset n) → ∣ p ∣ ≤ n∣p∣≤n = count≤n (_≟ inside)∣p∣≤∣x∷p∣ : ∀ x (p : Subset n) → ∣ p ∣ ≤ ∣ x ∷ p ∣∣p∣≤∣x∷p∣ outside p = ℕ.≤-refl∣p∣≤∣x∷p∣ inside p = ℕ.n≤1+n ∣ p ∣-------------------------------------------------------------------------- ⊥∉⊥ : x ∉ ⊥∉⊥ (there p) = ∉⊥ p⊥⊆ : ⊥ ⊆ p⊥⊆ x∈⊥ = contradiction x∈⊥ ∉⊥∣⊥∣≡0 : ∀ n → ∣ ⊥ {n = n} ∣ ≡ 0∣⊥∣≡0 zero = refl∣⊥∣≡0 (suc n) = ∣⊥∣≡0 n-------------------------------------------------------------------------- ⊤∈⊤ : x ∈ ⊤∈⊤ {x = zero} = here∈⊤ {x = suc x} = there ∈⊤⊆⊤ : p ⊆ ⊤⊆⊤ = const ∈⊤∣⊤∣≡n : ∀ n → ∣ ⊤ {n} ∣ ≡ n∣⊤∣≡n zero = refl∣⊤∣≡n (suc n) = cong suc (∣⊤∣≡n n)∣p∣≡n⇒p≡⊤ : ∣ p ∣ ≡ n → p ≡ ⊤ {n}∣p∣≡n⇒p≡⊤ {p = []} _ = refl∣p∣≡n⇒p≡⊤ {p = outside ∷ p} |p|≡n = contradiction |p|≡n (ℕ.<⇒≢ (s≤s (∣p∣≤n p)))∣p∣≡n⇒p≡⊤ {p = inside ∷ p} |p|≡n = cong (inside ∷_) (∣p∣≡n⇒p≡⊤ (ℕ.suc-injective |p|≡n))-------------------------------------------------------------------------- ⁅_⁆x∈⁅x⁆ : ∀ (x : Fin n) → x ∈ ⁅ x ⁆x∈⁅x⁆ zero = herex∈⁅x⁆ (suc x) = there (x∈⁅x⁆ x)x∈⁅y⁆⇒x≡y : ∀ {x} (y : Fin n) → x ∈ ⁅ y ⁆ → x ≡ yx∈⁅y⁆⇒x≡y zero here = reflx∈⁅y⁆⇒x≡y zero (there p) = contradiction p ∉⊥x∈⁅y⁆⇒x≡y (suc y) (there p) = cong suc (x∈⁅y⁆⇒x≡y y p)x∈⁅y⁆⇔x≡y : x ∈ ⁅ y ⁆ ⇔ x ≡ yx∈⁅y⁆⇔x≡y {x = x} {y = y} = mk⇔(x∈⁅y⁆⇒x≡y y)(λ x≡y → subst (λ y → x ∈ ⁅ y ⁆) x≡y (x∈⁅x⁆ x))x≢y⇒x∉⁅y⁆ : x ≢ y → x ∉ ⁅ y ⁆x≢y⇒x∉⁅y⁆ x≢y = x≢y ∘ x∈⁅y⁆⇒x≡y _x∉⁅y⁆⇒x≢y : x ∉ ⁅ y ⁆ → x ≢ yx∉⁅y⁆⇒x≢y x∉⁅x⁆ refl = x∉⁅x⁆ (x∈⁅x⁆ _)∣⁅x⁆∣≡1 : ∀ (i : Fin n) → ∣ ⁅ i ⁆ ∣ ≡ 1∣⁅x⁆∣≡1 {suc n} zero = cong suc (∣⊥∣≡0 n)∣⁅x⁆∣≡1 {_} (suc i) = ∣⁅x⁆∣≡1 i-------------------------------------------------------------------------- _⊆_⊆-refl : Reflexive {A = Subset n} _⊆_⊆-refl = id⊆-reflexive : _≡_ {A = Subset n} ⇒ _⊆_⊆-reflexive refl = ⊆-refl⊆-trans : Transitive {A = Subset n} _⊆_⊆-trans p⊆q q⊆r x∈p = q⊆r (p⊆q x∈p)⊆-antisym : Antisymmetric {A = Subset n} _≡_ _⊆_⊆-antisym {i = []} {[]} p⊆q q⊆p = refl⊆-antisym {i = x ∷ xs} {y ∷ ys} p⊆q q⊆p with x | y... | inside | inside = cong₂ _∷_ refl (⊆-antisym (drop-∷-⊆ p⊆q) (drop-∷-⊆ q⊆p))... | inside | outside = contradiction (p⊆q here) λ()... | outside | inside = contradiction (q⊆p here) λ()... | outside | outside = cong₂ _∷_ refl (⊆-antisym (drop-∷-⊆ p⊆q) (drop-∷-⊆ q⊆p))⊆-min : Minimum {A = Subset n} _⊆_ ⊥⊆-min p = ⊥⊆⊆-max : Maximum {A = Subset n} _⊆_ ⊤⊆-max p = ⊆⊤infix 4 _⊆?__⊆?_ : B.Decidable {A = Subset n} _⊆_[] ⊆? [] = yes idoutside ∷ p ⊆? y ∷ q = Dec.map out⊆-⇔ (p ⊆? q)inside ∷ p ⊆? outside ∷ q = no (λ p⊆q → case (p⊆q here) of λ())inside ∷ p ⊆? inside ∷ q = Dec.map in⊆in-⇔ (p ⊆? q)module _ (n : ℕ) where⊆-isPreorder : IsPreorder {A = Subset n} _≡_ _⊆_⊆-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ⊆-reflexive; trans = ⊆-trans}⊆-isPartialOrder : IsPartialOrder {A = Subset n} _≡_ _⊆_⊆-isPartialOrder = record{ isPreorder = ⊆-isPreorder; antisym = ⊆-antisym}⊆-preorder : Preorder _ _ _⊆-preorder = record{ isPreorder = ⊆-isPreorder}⊆-poset : Poset _ _ _⊆-poset = record{ isPartialOrder = ⊆-isPartialOrder}p⊆q⇒∣p∣≤∣q∣ : p ⊆ q → ∣ p ∣ ≤ ∣ q ∣p⊆q⇒∣p∣≤∣q∣ {p = []} {[]} p⊆q = z≤np⊆q⇒∣p∣≤∣q∣ {p = outside ∷ p} {outside ∷ q} p⊆q = p⊆q⇒∣p∣≤∣q∣ (drop-∷-⊆ p⊆q)p⊆q⇒∣p∣≤∣q∣ {p = outside ∷ p} {inside ∷ q} p⊆q = ℕ.m≤n⇒m≤1+n (p⊆q⇒∣p∣≤∣q∣ (drop-∷-⊆ p⊆q))p⊆q⇒∣p∣≤∣q∣ {p = inside ∷ p} {outside ∷ q} p⊆q = contradiction (p⊆q here) λ()p⊆q⇒∣p∣≤∣q∣ {p = inside ∷ p} {inside ∷ q} p⊆q = s≤s (p⊆q⇒∣p∣≤∣q∣ (drop-∷-⊆ p⊆q))-------------------------------------------------------------------------- _⊂_p⊂q⇒p⊆q : p ⊂ q → p ⊆ qp⊂q⇒p⊆q = proj₁⊂-trans : Transitive {A = Subset n} _⊂_⊂-trans (p⊆q , x , x∈q , x∉p) (q⊆r , _ , _ , _) = ⊆-trans p⊆q q⊆r , x , q⊆r x∈q , x∉p⊂-⊆-trans : Trans {A = Subset n} _⊂_ _⊆_ _⊂_⊂-⊆-trans (p⊆q , x , x∈q , x∉p) q⊆r = ⊆-trans p⊆q q⊆r , x , q⊆r x∈q , x∉p⊆-⊂-trans : Trans {A = Subset n} _⊆_ _⊂_ _⊂_⊆-⊂-trans p⊆q (q⊆r , x , x∈r , x∉q) = ⊆-trans p⊆q q⊆r , x , x∈r , x∉q ∘ p⊆q⊂-irref : Irreflexive {A = Subset n} _≡_ _⊂_⊂-irref refl (_ , x , x∈p , x∉q) = contradiction x∈p x∉q⊂-antisym : Antisymmetric {A = Subset n} _≡_ _⊂_⊂-antisym (p⊆q , _) (q⊆p , _) = ⊆-antisym p⊆q q⊆p⊂-asymmetric : Asymmetric {A = Subset n} _⊂_⊂-asymmetric (p⊆q , _) (_ , x , x∈p , x∉q) = contradiction (p⊆q x∈p) x∉qinfix 4 _⊂?__⊂?_ : B.Decidable {A = Subset n} _⊂_[] ⊂? [] = no λ ()outside ∷ p ⊂? outside ∷ q = Dec.map out⊂out-⇔ (p ⊂? q)outside ∷ p ⊂? inside ∷ q = Dec.map out⊂in-⇔ (p ⊆? q)inside ∷ p ⊂? outside ∷ q = no (λ {(p⊆q , _) → case (p⊆q here) of λ ()})inside ∷ p ⊂? inside ∷ q = Dec.map in⊂in-⇔ (p ⊂? q)module _ (n : ℕ) where⊂-isStrictPartialOrder : IsStrictPartialOrder {A = Subset n} _≡_ _⊂_⊂-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = ⊂-irref; trans = ⊂-trans; <-resp-≈ = (λ {refl → id}) , (λ {refl → id})}⊂-isDecStrictPartialOrder : IsDecStrictPartialOrder {A = Subset n} _≡_ _⊂_⊂-isDecStrictPartialOrder = record{ isStrictPartialOrder = ⊂-isStrictPartialOrder; _≟_ = ≡-dec _≟_; _<?_ = _⊂?_}⊂-strictPartialOrder : StrictPartialOrder _ _ _⊂-strictPartialOrder = record{ isStrictPartialOrder = ⊂-isStrictPartialOrder}⊂-decStrictPartialOrder : DecStrictPartialOrder _ _ _⊂-decStrictPartialOrder = record{ isDecStrictPartialOrder = ⊂-isDecStrictPartialOrder}p⊂q⇒∣p∣<∣q∣ : p ⊂ q → ∣ p ∣ < ∣ q ∣p⊂q⇒∣p∣<∣q∣ {p = outside ∷ p} {outside ∷ q} op⊂oq@(_ , _ , _ , _) = p⊂q⇒∣p∣<∣q∣ (drop-∷-⊂ op⊂oq)p⊂q⇒∣p∣<∣q∣ {p = outside ∷ p} {inside ∷ q} (op⊆iq , _ , _ , _) = s≤s (p⊆q⇒∣p∣≤∣q∣ (drop-∷-⊆ op⊆iq))p⊂q⇒∣p∣<∣q∣ {p = inside ∷ p} {outside ∷ q} (ip⊆oq , _ , _ , _) = contradiction (ip⊆oq here) λ()p⊂q⇒∣p∣<∣q∣ {p = inside ∷ p} {inside ∷ q} (_ , zero , _ , x∉ip) = contradiction here x∉ipp⊂q⇒∣p∣<∣q∣ {p = inside ∷ p} {inside ∷ q} ip⊂iq@(_ , suc x , _ , _) = s≤s (p⊂q⇒∣p∣<∣q∣ (drop-∷-⊂ ip⊂iq))-------------------------------------------------------------------------- ∁x∈p⇒x∉∁p : x ∈ p → x ∉ ∁ px∈p⇒x∉∁p (there x∈p) (there x∈∁p) = x∈p⇒x∉∁p x∈p x∈∁px∈∁p⇒x∉p : x ∈ ∁ p → x ∉ px∈∁p⇒x∉p (there x∈∁p) (there x∈p) = x∈∁p⇒x∉p x∈∁p x∈px∉∁p⇒x∈p : x ∉ ∁ p → x ∈ px∉∁p⇒x∈p {x = zero} {outside ∷ p} x∉∁p = contradiction here x∉∁px∉∁p⇒x∈p {x = zero} {inside ∷ p} x∉∁p = herex∉∁p⇒x∈p {x = suc x} {_ ∷ p} x∉∁p = there (x∉∁p⇒x∈p (x∉∁p ∘ there))x∉p⇒x∈∁p : x ∉ p → x ∈ ∁ px∉p⇒x∈∁p {x = zero} {outside ∷ p} x∉p = herex∉p⇒x∈∁p {x = zero} {inside ∷ p} x∉p = contradiction here x∉px∉p⇒x∈∁p {x = suc x} {_ ∷ p} x∉p = there (x∉p⇒x∈∁p (x∉p ∘ there))p∪∁p≡⊤ : ∀ (p : Subset n) → p ∪ ∁ p ≡ ⊤p∪∁p≡⊤ [] = reflp∪∁p≡⊤ (outside ∷ p) = cong (inside ∷_) (p∪∁p≡⊤ p)p∪∁p≡⊤ (inside ∷ p) = cong (inside ∷_) (p∪∁p≡⊤ p)∣∁p∣≡n∸∣p∣ : ∀ (p : Subset n) → ∣ ∁ p ∣ ≡ n ∸ ∣ p ∣∣∁p∣≡n∸∣p∣ [] = refl∣∁p∣≡n∸∣p∣ (inside ∷ p) = ∣∁p∣≡n∸∣p∣ p∣∁p∣≡n∸∣p∣ (outside ∷ p) = beginsuc ∣ ∁ p ∣ ≡⟨ cong suc (∣∁p∣≡n∸∣p∣ p) ⟩suc (_ ∸ ∣ p ∣) ≡⟨ sym (ℕ.+-∸-assoc 1 (∣p∣≤n p)) ⟩suc _ ∸ ∣ p ∣ ∎where open ≡-Reasoning-------------------------------------------------------------------------- _∩_module _ {n : ℕ} whereopen AlgebraicDefinitions {A = Subset n} _≡_∩-assoc : Associative _∩_∩-assoc = zipWith-assoc ∧-assoc∩-comm : Commutative _∩_∩-comm = zipWith-comm ∧-comm∩-idem : Idempotent _∩_∩-idem = zipWith-idem ∧-idem∩-identityˡ : LeftIdentity ⊤ _∩_∩-identityˡ = zipWith-identityˡ ∧-identityˡ∩-identityʳ : RightIdentity ⊤ _∩_∩-identityʳ = zipWith-identityʳ ∧-identityʳ∩-identity : Identity ⊤ _∩_∩-identity = ∩-identityˡ , ∩-identityʳ∩-zeroˡ : LeftZero ⊥ _∩_∩-zeroˡ = zipWith-zeroˡ ∧-zeroˡ∩-zeroʳ : RightZero ⊥ _∩_∩-zeroʳ = zipWith-zeroʳ ∧-zeroʳ∩-zero : Zero ⊥ _∩_∩-zero = ∩-zeroˡ , ∩-zeroʳ∩-inverseˡ : LeftInverse ⊥ ∁ _∩_∩-inverseˡ = zipWith-inverseˡ ∧-inverseˡ∩-inverseʳ : RightInverse ⊥ ∁ _∩_∩-inverseʳ = zipWith-inverseʳ ∧-inverseʳ∩-inverse : Inverse ⊥ ∁ _∩_∩-inverse = ∩-inverseˡ , ∩-inverseʳmodule _ (n : ℕ) whereopen AlgebraicStructures {A = Subset n} _≡_open AlgebraicLatticeStructures {A = Subset n} _≡_∩-isMagma : IsMagma _∩_∩-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _∩_}∩-isSemigroup : IsSemigroup _∩_∩-isSemigroup = record{ isMagma = ∩-isMagma; assoc = ∩-assoc}∩-isBand : IsBand _∩_∩-isBand = record{ isSemigroup = ∩-isSemigroup; idem = ∩-idem}∩-isSemilattice : IsSemilattice _∩_∩-isSemilattice = record{ isBand = ∩-isBand; comm = ∩-comm}∩-isMonoid : IsMonoid _∩_ ⊤∩-isMonoid = record{ isSemigroup = ∩-isSemigroup; identity = ∩-identity}∩-isCommutativeMonoid : IsCommutativeMonoid _∩_ ⊤∩-isCommutativeMonoid = record{ isMonoid = ∩-isMonoid; comm = ∩-comm}∩-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∩_ ⊤∩-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∩-isCommutativeMonoid; idem = ∩-idem}∩-magma : Magma _ _∩-magma = record{ isMagma = ∩-isMagma}∩-semigroup : Semigroup _ _∩-semigroup = record{ isSemigroup = ∩-isSemigroup}∩-band : Band _ _∩-band = record{ isBand = ∩-isBand}∩-semilattice : Semilattice _ _∩-semilattice = record{ isSemilattice = ∩-isSemilattice}∩-monoid : Monoid _ _∩-monoid = record{ isMonoid = ∩-isMonoid}∩-commutativeMonoid : CommutativeMonoid _ _∩-commutativeMonoid = record{ isCommutativeMonoid = ∩-isCommutativeMonoid}∩-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∩-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∩-isIdempotentCommutativeMonoid}p∩q⊆p : ∀ (p q : Subset n) → p ∩ q ⊆ pp∩q⊆p [] [] x∈p∩q = x∈p∩qp∩q⊆p (inside ∷ p) (inside ∷ q) here = herep∩q⊆p (inside ∷ p) (_ ∷ q) (there ∈p∩q) = there (p∩q⊆p p q ∈p∩q)p∩q⊆p (outside ∷ p) (_ ∷ q) (there ∈p∩q) = there (p∩q⊆p p q ∈p∩q)p∩q⊆q : ∀ (p q : Subset n) → p ∩ q ⊆ qp∩q⊆q p q rewrite ∩-comm p q = p∩q⊆p q px∈p∩q⁺ : x ∈ p × x ∈ q → x ∈ p ∩ qx∈p∩q⁺ (here , here) = herex∈p∩q⁺ (there x∈p , there x∈q) = there (x∈p∩q⁺ (x∈p , x∈q))x∈p∩q⁻ : ∀ (p q : Subset n) → x ∈ p ∩ q → x ∈ p × x ∈ qx∈p∩q⁻ (inside ∷ p) (inside ∷ q) here = here , herex∈p∩q⁻ (s ∷ p) (t ∷ q) (there x∈p∩q) =Product.map there there (x∈p∩q⁻ p q x∈p∩q)∩⇔× : x ∈ p ∩ q ⇔ (x ∈ p × x ∈ q)∩⇔× = mk⇔ (x∈p∩q⁻ _ _) x∈p∩q⁺∣p∩q∣≤∣p∣ : ∀ (p q : Subset n) → ∣ p ∩ q ∣ ≤ ∣ p ∣∣p∩q∣≤∣p∣ p q = p⊆q⇒∣p∣≤∣q∣ (p∩q⊆p p q)∣p∩q∣≤∣q∣ : ∀ (p q : Subset n) → ∣ p ∩ q ∣ ≤ ∣ q ∣∣p∩q∣≤∣q∣ p q = p⊆q⇒∣p∣≤∣q∣ (p∩q⊆q p q)∣p∩q∣≤∣p∣⊓∣q∣ : ∀ (p q : Subset n) → ∣ p ∩ q ∣ ≤ ∣ p ∣ ⊓ ∣ q ∣∣p∩q∣≤∣p∣⊓∣q∣ p q = ℕ.⊓-glb (∣p∩q∣≤∣p∣ p q) (∣p∩q∣≤∣q∣ p q)-------------------------------------------------------------------------- _∪_module _ {n : ℕ} whereopen AlgebraicDefinitions {A = Subset n} _≡_∪-assoc : Associative _∪_∪-assoc = zipWith-assoc ∨-assoc∪-comm : Commutative _∪_∪-comm = zipWith-comm ∨-comm∪-idem : Idempotent _∪_∪-idem = zipWith-idem ∨-idem∪-identityˡ : LeftIdentity ⊥ _∪_∪-identityˡ = zipWith-identityˡ ∨-identityˡ∪-identityʳ : RightIdentity ⊥ _∪_∪-identityʳ = zipWith-identityʳ ∨-identityʳ∪-identity : Identity ⊥ _∪_∪-identity = ∪-identityˡ , ∪-identityʳ∪-zeroˡ : LeftZero ⊤ _∪_∪-zeroˡ = zipWith-zeroˡ ∨-zeroˡ∪-zeroʳ : RightZero ⊤ _∪_∪-zeroʳ = zipWith-zeroʳ ∨-zeroʳ∪-zero : Zero ⊤ _∪_∪-zero = ∪-zeroˡ , ∪-zeroʳ∪-inverseˡ : LeftInverse ⊤ ∁ _∪_∪-inverseˡ = zipWith-inverseˡ ∨-inverseˡ∪-inverseʳ : RightInverse ⊤ ∁ _∪_∪-inverseʳ = zipWith-inverseʳ ∨-inverseʳ∪-inverse : Inverse ⊤ ∁ _∪_∪-inverse = ∪-inverseˡ , ∪-inverseʳ∪-distribˡ-∩ : _∪_ DistributesOverˡ _∩_∪-distribˡ-∩ = zipWith-distribˡ ∨-distribˡ-∧∪-distribʳ-∩ : _∪_ DistributesOverʳ _∩_∪-distribʳ-∩ = zipWith-distribʳ ∨-distribʳ-∧∪-distrib-∩ : _∪_ DistributesOver _∩_∪-distrib-∩ = ∪-distribˡ-∩ , ∪-distribʳ-∩∩-distribˡ-∪ : _∩_ DistributesOverˡ _∪_∩-distribˡ-∪ = zipWith-distribˡ ∧-distribˡ-∨∩-distribʳ-∪ : _∩_ DistributesOverʳ _∪_∩-distribʳ-∪ = zipWith-distribʳ ∧-distribʳ-∨∩-distrib-∪ : _∩_ DistributesOver _∪_∩-distrib-∪ = ∩-distribˡ-∪ , ∩-distribʳ-∪∪-abs-∩ : _∪_ Absorbs _∩_∪-abs-∩ = zipWith-absorbs ∨-abs-∧∩-abs-∪ : _∩_ Absorbs _∪_∩-abs-∪ = zipWith-absorbs ∧-abs-∨module _ (n : ℕ) whereopen AlgebraicStructures {A = Subset n} _≡_open AlgebraicLatticeStructures {A = Subset n} _≡_∪-isMagma : IsMagma _∪_∪-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _∪_}∪-magma : Magma _ _∪-magma = record{ isMagma = ∪-isMagma}∪-isSemigroup : IsSemigroup _∪_∪-isSemigroup = record{ isMagma = ∪-isMagma; assoc = ∪-assoc}∪-semigroup : Semigroup _ _∪-semigroup = record{ isSemigroup = ∪-isSemigroup}∪-isBand : IsBand _∪_∪-isBand = record{ isSemigroup = ∪-isSemigroup; idem = ∪-idem}∪-band : Band _ _∪-band = record{ isBand = ∪-isBand}∪-isSemilattice : IsSemilattice _∪_∪-isSemilattice = record{ isBand = ∪-isBand; comm = ∪-comm}∪-semilattice : Semilattice _ _∪-semilattice = record{ isSemilattice = ∪-isSemilattice}∪-isMonoid : IsMonoid _∪_ ⊥∪-isMonoid = record{ isSemigroup = ∪-isSemigroup; identity = ∪-identity}∪-monoid : Monoid _ _∪-monoid = record{ isMonoid = ∪-isMonoid}∪-isCommutativeMonoid : IsCommutativeMonoid _∪_ ⊥∪-isCommutativeMonoid = record{ isMonoid = ∪-isMonoid; comm = ∪-comm}∪-commutativeMonoid : CommutativeMonoid _ _∪-commutativeMonoid = record{ isCommutativeMonoid = ∪-isCommutativeMonoid}∪-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∪_ ⊥∪-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∪-isCommutativeMonoid; idem = ∪-idem}∪-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∪-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∪-isIdempotentCommutativeMonoid}∪-∩-isLattice : IsLattice _∪_ _∩_∪-∩-isLattice = record{ isEquivalence = isEquivalence; ∨-comm = ∪-comm; ∨-assoc = ∪-assoc; ∨-cong = cong₂ _∪_; ∧-comm = ∩-comm; ∧-assoc = ∩-assoc; ∧-cong = cong₂ _∩_; absorptive = ∪-abs-∩ , ∩-abs-∪}∪-∩-lattice : Lattice _ _∪-∩-lattice = record{ isLattice = ∪-∩-isLattice}∪-∩-isDistributiveLattice : IsDistributiveLattice _∪_ _∩_∪-∩-isDistributiveLattice = record{ isLattice = ∪-∩-isLattice; ∨-distrib-∧ = ∪-distrib-∩; ∧-distrib-∨ = ∩-distrib-∪}∪-∩-distributiveLattice : DistributiveLattice _ _∪-∩-distributiveLattice = record{ isDistributiveLattice = ∪-∩-isDistributiveLattice}∪-∩-isBooleanAlgebra : IsBooleanAlgebra _∪_ _∩_ ∁ ⊤ ⊥∪-∩-isBooleanAlgebra = record{ isDistributiveLattice = ∪-∩-isDistributiveLattice; ∨-complement = ∪-inverse; ∧-complement = ∩-inverse; ¬-cong = cong ∁}∪-∩-booleanAlgebra : BooleanAlgebra _ _∪-∩-booleanAlgebra = record{ isBooleanAlgebra = ∪-∩-isBooleanAlgebra}∩-∪-isLattice : IsLattice _∩_ _∪_∩-∪-isLattice = L.∧-∨-isLattice ∪-∩-lattice∩-∪-lattice : Lattice _ _∩-∪-lattice = L.∧-∨-lattice ∪-∩-lattice∩-∪-isDistributiveLattice : IsDistributiveLattice _∩_ _∪_∩-∪-isDistributiveLattice = DL.∧-∨-isDistributiveLattice ∪-∩-distributiveLattice∩-∪-distributiveLattice : DistributiveLattice _ _∩-∪-distributiveLattice = DL.∧-∨-distributiveLattice ∪-∩-distributiveLattice∩-∪-isBooleanAlgebra : IsBooleanAlgebra _∩_ _∪_ ∁ ⊥ ⊤∩-∪-isBooleanAlgebra = BA.∧-∨-isBooleanAlgebra ∪-∩-booleanAlgebra∩-∪-booleanAlgebra : BooleanAlgebra _ _∩-∪-booleanAlgebra = BA.∧-∨-booleanAlgebra ∪-∩-booleanAlgebrap⊆p∪q : ∀ (q : Subset n) → p ⊆ p ∪ qp⊆p∪q (s ∷ q) here = herep⊆p∪q (s ∷ q) (there x∈p) = there (p⊆p∪q q x∈p)q⊆p∪q : ∀ (p q : Subset n) → q ⊆ p ∪ qq⊆p∪q p q rewrite ∪-comm p q = p⊆p∪q px∈p∪q⁻ : ∀ (p q : Subset n) → x ∈ p ∪ q → x ∈ p ⊎ x ∈ qx∈p∪q⁻ (inside ∷ p) (t ∷ q) here = inj₁ herex∈p∪q⁻ (outside ∷ p) (inside ∷ q) here = inj₂ herex∈p∪q⁻ (s ∷ p) (t ∷ q) (there x∈p∪q) =Sum.map there there (x∈p∪q⁻ p q x∈p∪q)x∈p∪q⁺ : x ∈ p ⊎ x ∈ q → x ∈ p ∪ qx∈p∪q⁺ (inj₁ x∈p) = p⊆p∪q _ x∈px∈p∪q⁺ (inj₂ x∈q) = q⊆p∪q _ _ x∈q∪⇔⊎ : x ∈ p ∪ q ⇔ (x ∈ p ⊎ x ∈ q)∪⇔⊎ = mk⇔ (x∈p∪q⁻ _ _) x∈p∪q⁺∣p∣≤∣p∪q∣ : ∀ (p q : Subset n) → ∣ p ∣ ≤ ∣ p ∪ q ∣∣p∣≤∣p∪q∣ p q = p⊆q⇒∣p∣≤∣q∣ (p⊆p∪q {p = p} q)∣q∣≤∣p∪q∣ : ∀ (p q : Subset n) → ∣ q ∣ ≤ ∣ p ∪ q ∣∣q∣≤∣p∪q∣ p q = p⊆q⇒∣p∣≤∣q∣ (q⊆p∪q p q)∣p∣⊔∣q∣≤∣p∪q∣ : ∀ (p q : Subset n) → ∣ p ∣ ⊔ ∣ q ∣ ≤ ∣ p ∪ q ∣∣p∣⊔∣q∣≤∣p∪q∣ p q = ℕ.⊔-lub (∣p∣≤∣p∪q∣ p q) (∣q∣≤∣p∪q∣ p q)-------------------------------------------------------------------------- Properties of _─_p─⊥≡p : ∀ (p : Subset n) → p ─ ⊥ ≡ pp─⊥≡p [] = reflp─⊥≡p (x ∷ p) = cong (x ∷_) (p─⊥≡p p)p─⊤≡⊥ : ∀ (p : Subset n) → p ─ ⊤ ≡ ⊥p─⊤≡⊥ [] = reflp─⊤≡⊥ (x ∷ p) = cong (outside ∷_) (p─⊤≡⊥ p)p─q─r≡p─q∪r : ∀ (p q r : Subset n) → p ─ q ─ r ≡ p ─ (q ∪ r)p─q─r≡p─q∪r [] [] [] = reflp─q─r≡p─q∪r (x ∷ p) (outside ∷ q) (outside ∷ r) = cong (x ∷_) (p─q─r≡p─q∪r p q r)p─q─r≡p─q∪r (x ∷ p) (inside ∷ q) (outside ∷ r) = cong (outside ∷_) (p─q─r≡p─q∪r p q r)p─q─r≡p─q∪r (x ∷ p) (outside ∷ q) (inside ∷ r) = cong (outside ∷_) (p─q─r≡p─q∪r p q r)p─q─r≡p─q∪r (x ∷ p) (inside ∷ q) (inside ∷ r) = cong (outside ∷_) (p─q─r≡p─q∪r p q r)p─q─q≡p─q : ∀ (p q : Subset n) → p ─ q ─ q ≡ p ─ qp─q─q≡p─q p q = beginp ─ q ─ q ≡⟨ p─q─r≡p─q∪r p q q ⟩p ─ q ∪ q ≡⟨ cong (p ─_) (∪-idem q) ⟩p ─ q ∎where open ≡-Reasoningp─q─r≡p─r─q : ∀ (p q r : Subset n) → p ─ q ─ r ≡ p ─ r ─ qp─q─r≡p─r─q p q r = begin(p ─ q) ─ r ≡⟨ p─q─r≡p─q∪r p q r ⟩p ─ (q ∪ r) ≡⟨ cong (p ─_) (∪-comm q r) ⟩p ─ (r ∪ q) ≡⟨ p─q─r≡p─q∪r p r q ⟨(p ─ r) ─ q ∎where open ≡-Reasoningx∈p∧x∉q⇒x∈p─q : x ∈ p → x ∉ q → x ∈ p ─ qx∈p∧x∉q⇒x∈p─q {q = outside ∷ q} here i∉q = herex∈p∧x∉q⇒x∈p─q {q = inside ∷ q} here i∉q = contradiction here i∉qx∈p∧x∉q⇒x∈p─q {q = outside ∷ q} (there i∈p) i∉q = there (x∈p∧x∉q⇒x∈p─q i∈p (i∉q ∘ there))x∈p∧x∉q⇒x∈p─q {q = inside ∷ q} (there i∈p) i∉q = there (x∈p∧x∉q⇒x∈p─q i∈p (i∉q ∘ there))p─q⊆p : ∀ (p q : Subset n) → p ─ q ⊆ pp─q⊆p (inside ∷ p) (outside ∷ q) here = herep─q⊆p (inside ∷ p) (outside ∷ q) (there x∈p) = there (p─q⊆p p q x∈p)p─q⊆p (outside ∷ p) (outside ∷ q) (there x∈p) = there (p─q⊆p p q x∈p)p─q⊆p (_ ∷ p) (inside ∷ q) (there x∈p) = there (p─q⊆p p q x∈p)p∩q≢∅⇒p─q⊂p : ∀ (p q : Subset n) → Nonempty (p ∩ q) → p ─ q ⊂ pp∩q≢∅⇒p─q⊂p (inside ∷ p) (inside ∷ q) (zero , here) = out⊂in (p─q⊆p p q)p∩q≢∅⇒p─q⊂p (x ∷ p) (inside ∷ q) (suc i , there i∈p∩q) = out⊂ (p∩q≢∅⇒p─q⊂p p q (i , i∈p∩q))p∩q≢∅⇒p─q⊂p (outside ∷ p) (outside ∷ q) (suc i , there i∈p∩q) = out⊂ (p∩q≢∅⇒p─q⊂p p q (i , i∈p∩q))p∩q≢∅⇒p─q⊂p (inside ∷ p) (outside ∷ q) (suc i , there i∈p∩q) = s⊂s (p∩q≢∅⇒p─q⊂p p q (i , i∈p∩q))∣p─q∣≤∣p∣ : ∀ (p q : Subset n) → ∣ p ─ q ∣ ≤ ∣ p ∣∣p─q∣≤∣p∣ p q = p⊆q⇒∣p∣≤∣q∣ (p─q⊆p p q)p∩q≢∅⇒∣p─q∣<∣p∣ : ∀ (p q : Subset n) → Nonempty (p ∩ q) → ∣ p ─ q ∣ < ∣ p ∣p∩q≢∅⇒∣p─q∣<∣p∣ p q ne = p⊂q⇒∣p∣<∣q∣ (p∩q≢∅⇒p─q⊂p p q ne)-------------------------------------------------------------------------- Properties of _-_x∈p∧x≢y⇒x∈p-y : x ∈ p → x ≢ y → x ∈ p - yx∈p∧x≢y⇒x∈p-y x∈p x≢y = x∈p∧x∉q⇒x∈p─q x∈p (x≢y⇒x∉⁅y⁆ x≢y)p─x─y≡p─y─x : ∀ (p : Subset n) x y → p - x - y ≡ p - y - xp─x─y≡p─y─x p x y = p─q─r≡p─r─q p ⁅ x ⁆ ⁅ y ⁆x∈p⇒p-x⊂p : x ∈ p → p - x ⊂ px∈p⇒p-x⊂p {n} {x} {p} x∈p = p∩q≢∅⇒p─q⊂p p ⁅ x ⁆ (x , x∈p∩q⁺ (x∈p , x∈⁅x⁆ x))x∈p⇒∣p-x∣<∣p∣ : x ∈ p → ∣ p - x ∣ < ∣ p ∣x∈p⇒∣p-x∣<∣p∣ x∈p = p⊂q⇒∣p∣<∣q∣ (x∈p⇒p-x⊂p x∈p)-------------------------------------------------------------------------- LiftLift? : ∀ {P : Pred (Fin n) ℓ} → Decidable P → Decidable (Lift P)Lift? P? p = decFinSubset (_∈? p) (λ {x} _ → P? x)-------------------------------------------------------------------------- Othermodule _ {P : Pred (Subset 0) ℓ} where∃-Subset-zero : ∃⟨ P ⟩ → P []∃-Subset-zero ([] , P[]) = P[]∃-Subset-[]-⇔ : P [] ⇔ ∃⟨ P ⟩∃-Subset-[]-⇔ = mk⇔ ([] ,_) ∃-Subset-zeromodule _ {P : Pred (Subset (suc n)) ℓ} where∃-Subset-suc : ∃⟨ P ⟩ → ∃⟨ P ∘ (inside ∷_) ⟩ ⊎ ∃⟨ P ∘ (outside ∷_) ⟩∃-Subset-suc (outside ∷ p , Pop) = inj₂ (p , Pop)∃-Subset-suc ( inside ∷ p , Pip) = inj₁ (p , Pip)∃-Subset-∷-⇔ : (∃⟨ P ∘ (inside ∷_) ⟩ ⊎ ∃⟨ P ∘ (outside ∷_) ⟩) ⇔ ∃⟨ P ⟩∃-Subset-∷-⇔ = mk⇔[ Product.map _ id , Product.map _ id ]′∃-Subset-sucanySubset? : ∀ {P : Pred (Subset n) ℓ} → Decidable P → Dec ∃⟨ P ⟩anySubset? {n = zero} P? = Dec.map ∃-Subset-[]-⇔ (P? [])anySubset? {n = suc n} P? = Dec.map ∃-Subset-∷-⇔(anySubset? (P? ∘ (inside ∷_)) ⊎-dec anySubset? (P? ∘ (outside ∷_)))-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.3p⊆q⇒∣p∣<∣q∣ = p⊆q⇒∣p∣≤∣q∣{-# WARNING_ON_USAGE p⊆q⇒∣p∣<∣q∣"Warning: p⊆q⇒∣p∣<∣q∣ was deprecated in v1.3.Please use p⊆q⇒∣p∣≤∣q∣ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Induction over Subset------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Subset.Induction whereopen import Data.Nat.Base using (ℕ)open import Data.Nat.Induction using (<-wellFounded)open import Data.Fin.Subset using (Subset; _⊂_; ∣_∣)open import Data.Fin.Subset.Propertiesopen import Inductionopen import Induction.WellFounded as WFopen import Level using (Level)import Relation.Binary.Construct.On as Onprivatevariableℓ : Leveln : ℕ-------------------------------------------------------------------------- Re-export accessabilityopen WF public using (Acc; acc)-------------------------------------------------------------------------- Complete induction based on _⊂_⊂-Rec : RecStruct (Subset n) ℓ ℓ⊂-Rec = WfRec _⊂_⊂-wellFounded : WellFounded {A = Subset n} _⊂_⊂-wellFounded = Subrelation.wellFounded p⊂q⇒∣p∣<∣q∣(On.wellFounded ∣_∣ <-wellFounded)
-------------------------------------------------------------------------- The Agda standard library---- Showing finite numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Show whereopen import Data.Fin.Base using (Fin; toℕ; fromℕ<)open import Data.Maybe.Base using (Maybe; nothing; just; _>>=_)open import Data.Nat as ℕ using (ℕ; _≤?_; _<?_)import Data.Nat.Show as ℕ using (show; readMaybe)open import Data.String.Base using (String)open import Function.Baseopen import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Decidable using (True)show : ∀ {n} → Fin n → Stringshow = ℕ.show ∘′ toℕreadMaybe : ∀ {n} base {base≤16 : True (base ≤? 16)} → String → Maybe (Fin n)readMaybe {n} base {pr} str = donat ← ℕ.readMaybe base {pr} strcase nat <? n of λ where(yes pr) → just (fromℕ< pr)(no ¬pr) → nothing
-------------------------------------------------------------------------- The Agda standard library---- The 'top' view of Fin.---- This is an example of a view of (elements of) a datatype,-- here i : Fin (suc n), which exhibits every such i as-- * either, i = fromℕ n-- * or, i = inject₁ j for a unique j : Fin n------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Relation.Unary.Top whereopen import Data.Nat.Base using (ℕ; zero; suc)open import Data.Fin.Base using (Fin; zero; suc; fromℕ; inject₁)open import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablen : ℕi : Fin n-------------------------------------------------------------------------- The View, considered as a unary relation on Fin n-- NB `Data.Fin.Properties.fromℕ≢inject₁` establishes that the following-- inductively defined family on `Fin n` has constructors which target-- *disjoint* instances of the family (moreover at indices `n = suc _`);-- hence the interpretations of the View constructors will also be disjoint.data View : (i : Fin n) → Set where‵fromℕ : View (fromℕ n)‵inj₁ : View i → View (inject₁ i)pattern ‵inject₁ i = ‵inj₁ {i = i} _-- The view covering function, witnessing soundness of the viewview : (i : Fin n) → View iview zero = view-zero whereview-zero : View (zero {n})view-zero {n = zero} = ‵fromℕview-zero {n = suc _} = ‵inj₁ view-zeroview (suc i) with view i... | ‵fromℕ = ‵fromℕ... | ‵inject₁ i = ‵inj₁ (view (suc i))-- Interpretation of the view constructors⟦_⟧ : {i : Fin n} → View i → Fin n⟦ ‵fromℕ ⟧ = fromℕ _⟦ ‵inject₁ i ⟧ = inject₁ i-- Completeness of the viewview-complete : (v : View i) → ⟦ v ⟧ ≡ iview-complete ‵fromℕ = reflview-complete (‵inj₁ _) = refl-- 'Computational' behaviour of the covering functionview-fromℕ : ∀ n → view (fromℕ n) ≡ ‵fromℕview-fromℕ zero = reflview-fromℕ (suc n) rewrite view-fromℕ n = reflview-inject₁ : (i : Fin n) → view (inject₁ i) ≡ ‵inj₁ (view i)view-inject₁ zero = reflview-inject₁ (suc i) rewrite view-inject₁ i = refl-- Uniqueness of the viewview-unique : (v : View i) → view i ≡ vview-unique ‵fromℕ = view-fromℕ _view-unique (‵inj₁ {i = i} v) = beginview (inject₁ i) ≡⟨ view-inject₁ i ⟩‵inj₁ (view i) ≡⟨ cong ‵inj₁ (view-unique v) ⟩‵inj₁ v ∎ where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Reflection utilities for Fin------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Reflection whereopen import Data.Nat.Base as ℕ hiding (module ℕ)open import Data.Fin.Base as Fin hiding (module Fin)open import Data.List.Baseopen import Reflection.AST.Termopen import Reflection.AST.Argument-------------------------------------------------------------------------- TermtoTerm : ∀ {n} → Fin n → TermtoTerm zero = con (quote Fin.zero) (1 ⋯⟅∷⟆ [])toTerm (suc i) = con (quote Fin.suc) (1 ⋯⟅∷⟆ toTerm i ⟨∷⟩ [])
-------------------------------------------------------------------------- The Agda standard library---- Properties related to Fin, and operations making use of these-- properties (or other properties not available in Data.Fin)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for deprecated _≺_ and _≻toℕ_ (issue #1726)module Data.Fin.Properties whereopen import Axiom.Extensionality.Propositionalopen import Algebra.Definitions using (Involutive)open import Effect.Applicative using (RawApplicative)open import Effect.Functor using (RawFunctor)open import Data.Bool.Base using (Bool; true; false; not; _∧_; _∨_)open import Data.Empty using (⊥; ⊥-elim)open import Data.Fin.Baseopen import Data.Fin.Patternsopen import Data.Nat.Base as ℕusing (ℕ; zero; suc; s≤s; z≤n; z<s; s<s; s<s⁻¹; _∸_; _^_)import Data.Nat.Properties as ℕopen import Data.Unit.Base using (⊤; tt)open import Data.Product.Base as Productusing (∃; ∃₂; _×_; _,_; map; proj₁; proj₂; uncurry; <_,_>)open import Data.Product.Properties using (,-injective)open import Data.Product.Algebra using (×-cong)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]; [_,_]′)open import Data.Sum.Properties using ([,]-map; [,]-∘)open import Function.Base using (_∘_; id; _$_; flip)open import Function.Bundles using (Injection; _↣_; _⇔_; _↔_; mk⇔; mk↔ₛ′)open import Function.Definitions using (Injective; Surjective)open import Function.Consequences.Propositional using (contraInjective)open import Function.Construct.Composition as Comp hiding (injective)open import Level using (Level)open import Relation.Binary.Definitions as B hiding (Decidable)open import Relation.Binary.Core using (_⇒_; _Preserves_⟶_)open import Relation.Binary.Bundlesusing (Preorder; Setoid; DecSetoid; Poset; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder)open import Relation.Binary.Structuresusing (IsDecEquivalence; IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; refl; sym; trans; cong; cong₂; subst; _≗_)open import Relation.Binary.PropositionalEquality.Properties as ≡using (module ≡-Reasoning)open import Relation.Nullary.Decidable as Decusing (Dec; _because_; yes; no; _×-dec_; _⊎-dec_; map′)open import Relation.Nullary.Negation.Core using (¬_; contradiction)open import Relation.Nullary.Reflects using (Reflects; invert)open import Relation.Unary as Uusing (U; Pred; Decidable; _⊆_; Satisfiable; Universal)open import Relation.Unary.Properties using (U?)privatevariablea : LevelA : Set am n o : ℕi j : Fin n-------------------------------------------------------------------------- Fin------------------------------------------------------------------------¬Fin0 : ¬ Fin 0¬Fin0 ()nonZeroIndex : Fin n → ℕ.NonZero nnonZeroIndex {n = suc _} _ = _-------------------------------------------------------------------------- Bundles0↔⊥ : Fin 0 ↔ ⊥0↔⊥ = mk↔ₛ′ ¬Fin0 (λ ()) (λ ()) (λ ())1↔⊤ : Fin 1 ↔ ⊤1↔⊤ = mk↔ₛ′ (λ { 0F → tt }) (λ { tt → 0F }) (λ { tt → refl }) λ { 0F → refl }2↔Bool : Fin 2 ↔ Bool2↔Bool = mk↔ₛ′ (λ { 0F → false; 1F → true }) (λ { false → 0F ; true → 1F })(λ { false → refl ; true → refl }) (λ { 0F → refl ; 1F → refl })-------------------------------------------------------------------------- Properties of _≡_------------------------------------------------------------------------0≢1+n : zero ≢ Fin.suc i0≢1+n ()suc-injective : Fin.suc i ≡ suc j → i ≡ jsuc-injective refl = reflinfix 4 _≟__≟_ : DecidableEquality (Fin n)zero ≟ zero = yes reflzero ≟ suc y = no λ()suc x ≟ zero = no λ()suc x ≟ suc y = map′ (cong suc) suc-injective (x ≟ y)-------------------------------------------------------------------------- Structures≡-isDecEquivalence : IsDecEquivalence {A = Fin n} _≡_≡-isDecEquivalence = record{ isEquivalence = ≡.isEquivalence; _≟_ = _≟_}-------------------------------------------------------------------------- Bundles≡-preorder : ℕ → Preorder _ _ _≡-preorder n = ≡.preorder (Fin n)≡-setoid : ℕ → Setoid _ _≡-setoid n = ≡.setoid (Fin n)≡-decSetoid : ℕ → DecSetoid _ _≡-decSetoid n = record{ isDecEquivalence = ≡-isDecEquivalence {n}}-------------------------------------------------------------------------- toℕ------------------------------------------------------------------------toℕ-injective : toℕ i ≡ toℕ j → i ≡ jtoℕ-injective {zero} {} {} _toℕ-injective {suc n} {zero} {zero} eq = refltoℕ-injective {suc n} {suc i} {suc j} eq =cong suc (toℕ-injective (cong ℕ.pred eq))toℕ-strengthen : ∀ (i : Fin n) → toℕ (strengthen i) ≡ toℕ itoℕ-strengthen zero = refltoℕ-strengthen (suc i) = cong suc (toℕ-strengthen i)-------------------------------------------------------------------------- toℕ-↑ˡ: "i" ↑ˡ n = "i" in Fin (m + n)------------------------------------------------------------------------toℕ-↑ˡ : ∀ (i : Fin m) n → toℕ (i ↑ˡ n) ≡ toℕ itoℕ-↑ˡ zero n = refltoℕ-↑ˡ (suc i) n = cong suc (toℕ-↑ˡ i n)↑ˡ-injective : ∀ n (i j : Fin m) → i ↑ˡ n ≡ j ↑ˡ n → i ≡ j↑ˡ-injective n zero zero refl = refl↑ˡ-injective n (suc i) (suc j) eq =cong suc (↑ˡ-injective n i j (suc-injective eq))-------------------------------------------------------------------------- toℕ-↑ʳ: n ↑ʳ "i" = "n + i" in Fin (n + m)------------------------------------------------------------------------toℕ-↑ʳ : ∀ n (i : Fin m) → toℕ (n ↑ʳ i) ≡ n ℕ.+ toℕ itoℕ-↑ʳ zero i = refltoℕ-↑ʳ (suc n) i = cong suc (toℕ-↑ʳ n i)↑ʳ-injective : ∀ n (i j : Fin m) → n ↑ʳ i ≡ n ↑ʳ j → i ≡ j↑ʳ-injective zero i i refl = refl↑ʳ-injective (suc n) i j eq = ↑ʳ-injective n i j (suc-injective eq)-------------------------------------------------------------------------- toℕ and the ordering relations------------------------------------------------------------------------toℕ<n : ∀ (i : Fin n) → toℕ i ℕ.< ntoℕ<n {n = suc _} zero = z<stoℕ<n {n = suc _} (suc i) = s<s (toℕ<n i)toℕ≤pred[n] : ∀ (i : Fin n) → toℕ i ℕ.≤ ℕ.pred ntoℕ≤pred[n] zero = z≤ntoℕ≤pred[n] (suc {n = suc n} i) = s≤s (toℕ≤pred[n] i)toℕ≤n : ∀ (i : Fin n) → toℕ i ℕ.≤ ntoℕ≤n {suc n} i = ℕ.m≤n⇒m≤1+n (toℕ≤pred[n] i)-- A simpler implementation of toℕ≤pred[n],-- however, with a different reduction behavior.-- If no one needs the reduction behavior of toℕ≤pred[n],-- it can be removed in favor of toℕ≤pred[n]′.toℕ≤pred[n]′ : ∀ (i : Fin n) → toℕ i ℕ.≤ ℕ.pred ntoℕ≤pred[n]′ i = ℕ.<⇒≤pred (toℕ<n i)toℕ-mono-< : i < j → toℕ i ℕ.< toℕ jtoℕ-mono-< i<j = i<jtoℕ-mono-≤ : i ≤ j → toℕ i ℕ.≤ toℕ jtoℕ-mono-≤ i≤j = i≤jtoℕ-cancel-≤ : toℕ i ℕ.≤ toℕ j → i ≤ jtoℕ-cancel-≤ i≤j = i≤jtoℕ-cancel-< : toℕ i ℕ.< toℕ j → i < jtoℕ-cancel-< i<j = i<j-------------------------------------------------------------------------- fromℕ------------------------------------------------------------------------toℕ-fromℕ : ∀ n → toℕ (fromℕ n) ≡ ntoℕ-fromℕ zero = refltoℕ-fromℕ (suc n) = cong suc (toℕ-fromℕ n)fromℕ-toℕ : ∀ (i : Fin n) → fromℕ (toℕ i) ≡ strengthen ifromℕ-toℕ zero = reflfromℕ-toℕ (suc i) = cong suc (fromℕ-toℕ i)≤fromℕ : ∀ (i : Fin (suc n)) → i ≤ fromℕ n≤fromℕ {n = n} i rewrite toℕ-fromℕ n = ℕ.s≤s⁻¹ (toℕ<n i)-------------------------------------------------------------------------- fromℕ<------------------------------------------------------------------------fromℕ<-toℕ : ∀ (i : Fin n) .(i<n : toℕ i ℕ.< n) → fromℕ< i<n ≡ ifromℕ<-toℕ zero _ = reflfromℕ<-toℕ (suc i) i<n = cong suc (fromℕ<-toℕ i (ℕ.s<s⁻¹ i<n))toℕ-fromℕ< : ∀ .(m<n : m ℕ.< n) → toℕ (fromℕ< m<n) ≡ mtoℕ-fromℕ< {m = zero} {n = suc _} _ = refltoℕ-fromℕ< {m = suc m} {n = suc _} m<n = cong suc (toℕ-fromℕ< (ℕ.s<s⁻¹ m<n))-- fromℕ is a special case of fromℕ<.fromℕ-def : ∀ n → fromℕ n ≡ fromℕ< ℕ.≤-reflfromℕ-def zero = reflfromℕ-def (suc n) = cong suc (fromℕ-def n)fromℕ<-cong : ∀ m n {o} → m ≡ n → .(m<o : m ℕ.< o) .(n<o : n ℕ.< o) →fromℕ< m<o ≡ fromℕ< n<ofromℕ<-cong 0 0 _ _ _ = reflfromℕ<-cong (suc _) (suc _) {o = suc _} r m<n n<o= cong suc (fromℕ<-cong _ _ (ℕ.suc-injective r) (ℕ.s<s⁻¹ m<n) (ℕ.s<s⁻¹ n<o))fromℕ<-injective : ∀ m n {o} → .(m<o : m ℕ.< o) .(n<o : n ℕ.< o) →fromℕ< m<o ≡ fromℕ< n<o → m ≡ nfromℕ<-injective 0 0 _ _ _ = reflfromℕ<-injective 0 (suc _) {o = suc _} _ _ ()fromℕ<-injective (suc _) (suc _) {o = suc _} m<n n<o r= cong suc (fromℕ<-injective _ _ (ℕ.s<s⁻¹ m<n) (ℕ.s<s⁻¹ n<o) (suc-injective r))-------------------------------------------------------------------------- fromℕ<″------------------------------------------------------------------------fromℕ<≡fromℕ<″ : ∀ (m<n : m ℕ.< n) (m<″n : m ℕ.<″ n) →fromℕ< m<n ≡ fromℕ<″ m m<″nfromℕ<≡fromℕ<″ {m = zero} {n = suc _} _ _ = reflfromℕ<≡fromℕ<″ {m = suc m} {n = suc _} m<n m<″n= cong suc (fromℕ<≡fromℕ<″ (ℕ.s<s⁻¹ m<n) (ℕ.s<″s⁻¹ m<″n))toℕ-fromℕ<″ : ∀ (m<n : m ℕ.<″ n) → toℕ (fromℕ<″ m m<n) ≡ mtoℕ-fromℕ<″ {m} {n} m<n = begintoℕ (fromℕ<″ m m<n) ≡⟨ cong toℕ (sym (fromℕ<≡fromℕ<″ (ℕ.≤″⇒≤ m<n) m<n)) ⟩toℕ (fromℕ< _) ≡⟨ toℕ-fromℕ< (ℕ.≤″⇒≤ m<n) ⟩m ∎where open ≡-Reasoning-------------------------------------------------------------------------- Properties of cast------------------------------------------------------------------------toℕ-cast : ∀ .(eq : m ≡ n) (k : Fin m) → toℕ (cast eq k) ≡ toℕ ktoℕ-cast {n = suc n} eq zero = refltoℕ-cast {n = suc n} eq (suc k) = cong suc (toℕ-cast (cong ℕ.pred eq) k)cast-is-id : .(eq : m ≡ m) (k : Fin m) → cast eq k ≡ kcast-is-id eq zero = reflcast-is-id eq (suc k) = cong suc (cast-is-id (ℕ.suc-injective eq) k)subst-is-cast : (eq : m ≡ n) (k : Fin m) → subst Fin eq k ≡ cast eq ksubst-is-cast refl k = sym (cast-is-id refl k)cast-trans : .(eq₁ : m ≡ n) .(eq₂ : n ≡ o) (k : Fin m) →cast eq₂ (cast eq₁ k) ≡ cast (trans eq₁ eq₂) kcast-trans {m = suc _} {n = suc _} {o = suc _} eq₁ eq₂ zero = reflcast-trans {m = suc _} {n = suc _} {o = suc _} eq₁ eq₂ (suc k) =cong suc (cast-trans (ℕ.suc-injective eq₁) (ℕ.suc-injective eq₂) k)-------------------------------------------------------------------------- Properties of _≤_-------------------------------------------------------------------------- Relational properties≤-reflexive : _≡_ ⇒ (_≤_ {n})≤-reflexive refl = ℕ.≤-refl≤-refl : Reflexive (_≤_ {n})≤-refl = ≤-reflexive refl≤-trans : Transitive (_≤_ {n})≤-trans = ℕ.≤-trans≤-antisym : Antisymmetric _≡_ (_≤_ {n})≤-antisym x≤y y≤x = toℕ-injective (ℕ.≤-antisym x≤y y≤x)≤-total : Total (_≤_ {n})≤-total x y = ℕ.≤-total (toℕ x) (toℕ y)≤-irrelevant : Irrelevant (_≤_ {m} {n})≤-irrelevant = ℕ.≤-irrelevantinfix 4 _≤?_ _<?__≤?_ : B.Decidable (_≤_ {m} {n})a ≤? b = toℕ a ℕ.≤? toℕ b_<?_ : B.Decidable (_<_ {m} {n})m <? n = suc (toℕ m) ℕ.≤? toℕ n-------------------------------------------------------------------------- Structures≤-isPreorder : IsPreorder {A = Fin n} _≡_ _≤_≤-isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isPartialOrder : IsPartialOrder {A = Fin n} _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder {A = Fin n} _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder {A = Fin n} _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-------------------------------------------------------------------------- Bundles≤-preorder : ℕ → Preorder _ _ _≤-preorder n = record{ isPreorder = ≤-isPreorder {n}}≤-poset : ℕ → Poset _ _ _≤-poset n = record{ isPartialOrder = ≤-isPartialOrder {n}}≤-totalOrder : ℕ → TotalOrder _ _ _≤-totalOrder n = record{ isTotalOrder = ≤-isTotalOrder {n}}≤-decTotalOrder : ℕ → DecTotalOrder _ _ _≤-decTotalOrder n = record{ isDecTotalOrder = ≤-isDecTotalOrder {n}}-------------------------------------------------------------------------- Properties of _<_-------------------------------------------------------------------------- Relational properties<-irrefl : Irreflexive _≡_ (_<_ {n})<-irrefl refl = ℕ.<-irrefl refl<-asym : Asymmetric (_<_ {n})<-asym = ℕ.<-asym<-trans : Transitive (_<_ {n})<-trans = ℕ.<-trans<-cmp : Trichotomous _≡_ (_<_ {n})<-cmp zero zero = tri≈ (λ()) refl (λ())<-cmp zero (suc j) = tri< z<s (λ()) (λ())<-cmp (suc i) zero = tri> (λ()) (λ()) z<s<-cmp (suc i) (suc j) with <-cmp i j... | tri< i<j i≢j j≮i = tri< (s<s i<j) (i≢j ∘ suc-injective) (j≮i ∘ s<s⁻¹)... | tri> i≮j i≢j j<i = tri> (i≮j ∘ s<s⁻¹) (i≢j ∘ suc-injective) (s<s j<i)... | tri≈ i≮j i≡j j≮i = tri≈ (i≮j ∘ s<s⁻¹) (cong suc i≡j) (j≮i ∘ s<s⁻¹)<-respˡ-≡ : (_<_ {m} {n}) Respectsˡ _≡_<-respˡ-≡ refl x≤y = x≤y<-respʳ-≡ : (_<_ {m} {n}) Respectsʳ _≡_<-respʳ-≡ refl x≤y = x≤y<-resp₂-≡ : (_<_ {n}) Respects₂ _≡_<-resp₂-≡ = <-respʳ-≡ , <-respˡ-≡<-irrelevant : Irrelevant (_<_ {m} {n})<-irrelevant = ℕ.<-irrelevant-------------------------------------------------------------------------- Structures<-isStrictPartialOrder : IsStrictPartialOrder {A = Fin n} _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = ≡.isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = <-resp₂-≡}<-isStrictTotalOrder : IsStrictTotalOrder {A = Fin n} _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}-------------------------------------------------------------------------- Bundles<-strictPartialOrder : ℕ → StrictPartialOrder _ _ _<-strictPartialOrder n = record{ isStrictPartialOrder = <-isStrictPartialOrder {n}}<-strictTotalOrder : ℕ → StrictTotalOrder _ _ _<-strictTotalOrder n = record{ isStrictTotalOrder = <-isStrictTotalOrder {n}}-------------------------------------------------------------------------- Other propertiesi<1+i : ∀ (i : Fin n) → i < suc ii<1+i = ℕ.n<1+n ∘ toℕ<⇒≢ : i < j → i ≢ j<⇒≢ i<i refl = ℕ.n≮n _ i<i≤∧≢⇒< : i ≤ j → i ≢ j → i < j≤∧≢⇒< {i = zero} {zero} _ 0≢0 = contradiction refl 0≢0≤∧≢⇒< {i = zero} {suc j} _ _ = z<s≤∧≢⇒< {i = suc i} {suc j} 1+i≤1+j 1+i≢1+j =s<s (≤∧≢⇒< (ℕ.s≤s⁻¹ 1+i≤1+j) (1+i≢1+j ∘ (cong suc)))-------------------------------------------------------------------------- inject------------------------------------------------------------------------toℕ-inject : ∀ {i : Fin n} (j : Fin′ i) → toℕ (inject j) ≡ toℕ jtoℕ-inject {i = suc i} zero = refltoℕ-inject {i = suc i} (suc j) = cong suc (toℕ-inject j)-------------------------------------------------------------------------- inject₁------------------------------------------------------------------------fromℕ≢inject₁ : fromℕ n ≢ inject₁ ifromℕ≢inject₁ {i = suc i} eq = fromℕ≢inject₁ {i = i} (suc-injective eq)inject₁-injective : inject₁ i ≡ inject₁ j → i ≡ jinject₁-injective {i = zero} {zero} i≡j = reflinject₁-injective {i = suc i} {suc j} i≡j =cong suc (inject₁-injective (suc-injective i≡j))toℕ-inject₁ : ∀ (i : Fin n) → toℕ (inject₁ i) ≡ toℕ itoℕ-inject₁ zero = refltoℕ-inject₁ (suc i) = cong suc (toℕ-inject₁ i)toℕ-inject₁-≢ : ∀ (i : Fin n) → n ≢ toℕ (inject₁ i)toℕ-inject₁-≢ (suc i) = toℕ-inject₁-≢ i ∘ ℕ.suc-injectiveinject₁ℕ< : ∀ (i : Fin n) → toℕ (inject₁ i) ℕ.< ninject₁ℕ< i rewrite toℕ-inject₁ i = toℕ<n iinject₁ℕ≤ : ∀ (i : Fin n) → toℕ (inject₁ i) ℕ.≤ ninject₁ℕ≤ = ℕ.<⇒≤ ∘ inject₁ℕ<≤̄⇒inject₁< : i ≤ j → inject₁ i < suc j≤̄⇒inject₁< {i = i} i≤j rewrite sym (toℕ-inject₁ i) = s<s i≤jℕ<⇒inject₁< : ∀ {i : Fin (ℕ.suc n)} {j : Fin n} → j < i → inject₁ j < iℕ<⇒inject₁< {i = suc i} j≤i = ≤̄⇒inject₁< (ℕ.s≤s⁻¹ j≤i)i≤inject₁[j]⇒i≤1+j : i ≤ inject₁ j → i ≤ suc ji≤inject₁[j]⇒i≤1+j {i = zero} _ = z≤ni≤inject₁[j]⇒i≤1+j {i = suc i} {j = suc j} i≤j = s≤s (ℕ.m≤n⇒m≤1+n (subst (toℕ i ℕ.≤_) (toℕ-inject₁ j) (ℕ.s≤s⁻¹ i≤j)))-------------------------------------------------------------------------- lower₁------------------------------------------------------------------------toℕ-lower₁ : ∀ i (p : n ≢ toℕ i) → toℕ (lower₁ i p) ≡ toℕ itoℕ-lower₁ {ℕ.zero} zero p = contradiction refl ptoℕ-lower₁ {ℕ.suc m} zero p = refltoℕ-lower₁ {ℕ.suc m} (suc i) p = cong ℕ.suc (toℕ-lower₁ i (p ∘ cong ℕ.suc))lower₁-injective : ∀ {n≢i : n ≢ toℕ i} {n≢j : n ≢ toℕ j} →lower₁ i n≢i ≡ lower₁ j n≢j → i ≡ jlower₁-injective {zero} {zero} {_} {n≢i} {_} _ = contradiction refl n≢ilower₁-injective {zero} {_} {zero} {_} {n≢j} _ = contradiction refl n≢jlower₁-injective {suc n} {zero} {zero} {_} {_} refl = refllower₁-injective {suc n} {suc i} {suc j} {n≢i} {n≢j} eq =cong suc (lower₁-injective (suc-injective eq))-------------------------------------------------------------------------- inject₁ and lower₁inject₁-lower₁ : ∀ (i : Fin (suc n)) (n≢i : n ≢ toℕ i) →inject₁ (lower₁ i n≢i) ≡ iinject₁-lower₁ {zero} zero 0≢0 = contradiction refl 0≢0inject₁-lower₁ {suc n} zero _ = reflinject₁-lower₁ {suc n} (suc i) n+1≢i+1 =cong suc (inject₁-lower₁ i (n+1≢i+1 ∘ cong suc))lower₁-inject₁′ : ∀ (i : Fin n) (n≢i : n ≢ toℕ (inject₁ i)) →lower₁ (inject₁ i) n≢i ≡ ilower₁-inject₁′ zero _ = refllower₁-inject₁′ (suc i) n+1≢i+1 =cong suc (lower₁-inject₁′ i (n+1≢i+1 ∘ cong suc))lower₁-inject₁ : ∀ (i : Fin n) →lower₁ (inject₁ i) (toℕ-inject₁-≢ i) ≡ ilower₁-inject₁ i = lower₁-inject₁′ i (toℕ-inject₁-≢ i)lower₁-irrelevant : ∀ (i : Fin (suc n)) (n≢i₁ n≢i₂ : n ≢ toℕ i) →lower₁ i n≢i₁ ≡ lower₁ i n≢i₂lower₁-irrelevant {zero} zero 0≢0 _ = contradiction refl 0≢0lower₁-irrelevant {suc n} zero _ _ = refllower₁-irrelevant {suc n} (suc i) _ _ =cong suc (lower₁-irrelevant i _ _)inject₁≡⇒lower₁≡ : ∀ {i : Fin n} {j : Fin (ℕ.suc n)} →(n≢j : n ≢ toℕ j) → inject₁ i ≡ j → lower₁ j n≢j ≡ iinject₁≡⇒lower₁≡ n≢j i≡j = inject₁-injective (trans (inject₁-lower₁ _ n≢j) (sym i≡j))-------------------------------------------------------------------------- inject≤------------------------------------------------------------------------toℕ-inject≤ : ∀ i .(m≤n : m ℕ.≤ n) → toℕ (inject≤ i m≤n) ≡ toℕ itoℕ-inject≤ {_} {suc n} zero _ = refltoℕ-inject≤ {_} {suc n} (suc i) _ = cong suc (toℕ-inject≤ i _)inject≤-refl : ∀ i .(n≤n : n ℕ.≤ n) → inject≤ i n≤n ≡ iinject≤-refl {suc n} zero _ = reflinject≤-refl {suc n} (suc i) _ = cong suc (inject≤-refl i _)inject≤-idempotent : ∀ (i : Fin m).(m≤n : m ℕ.≤ n) .(n≤o : n ℕ.≤ o) .(m≤o : m ℕ.≤ o) →inject≤ (inject≤ i m≤n) n≤o ≡ inject≤ i m≤oinject≤-idempotent {_} {suc n} {suc o} zero _ _ _ = reflinject≤-idempotent {_} {suc n} {suc o} (suc i) _ _ _ =cong suc (inject≤-idempotent i _ _ _)inject≤-trans : ∀ (i : Fin m) .(m≤n : m ℕ.≤ n) .(n≤o : n ℕ.≤ o) →inject≤ (inject≤ i m≤n) n≤o ≡ inject≤ i (ℕ.≤-trans m≤n n≤o)inject≤-trans i _ _ = inject≤-idempotent i _ _ _inject≤-injective : ∀ .(m≤n m≤n′ : m ℕ.≤ n) i j →inject≤ i m≤n ≡ inject≤ j m≤n′ → i ≡ jinject≤-injective {n = suc _} _ _ zero zero eq = reflinject≤-injective {n = suc _} _ _ (suc i) (suc j) eq =cong suc (inject≤-injective _ _ i j (suc-injective eq))inject≤-irrelevant : ∀ .(m≤n m≤n′ : m ℕ.≤ n) i →inject≤ i m≤n ≡ inject≤ i m≤n′inject≤-irrelevant _ _ i = refl-------------------------------------------------------------------------- pred------------------------------------------------------------------------pred< : ∀ (i : Fin (suc n)) → i ≢ zero → pred i < ipred< zero i≢0 = contradiction refl i≢0pred< (suc i) _ = ≤̄⇒inject₁< ℕ.≤-refl-------------------------------------------------------------------------- splitAt-------------------------------------------------------------------------- Fin (m + n) ↔ Fin m ⊎ Fin nsplitAt-↑ˡ : ∀ m i n → splitAt m (i ↑ˡ n) ≡ inj₁ isplitAt-↑ˡ (suc m) zero n = reflsplitAt-↑ˡ (suc m) (suc i) n rewrite splitAt-↑ˡ m i n = reflsplitAt⁻¹-↑ˡ : ∀ {m} {n} {i} {j} → splitAt m {n} i ≡ inj₁ j → j ↑ˡ n ≡ isplitAt⁻¹-↑ˡ {suc m} {n} {0F} {.0F} refl = reflsplitAt⁻¹-↑ˡ {suc m} {n} {suc i} {j} eqwith inj₁ k ← splitAt m i in splitAt[m][i]≡inj₁[j]with refl ← eq= cong suc (splitAt⁻¹-↑ˡ {i = i} {j = k} splitAt[m][i]≡inj₁[j])splitAt-↑ʳ : ∀ m n i → splitAt m (m ↑ʳ i) ≡ inj₂ {B = Fin n} isplitAt-↑ʳ zero n i = reflsplitAt-↑ʳ (suc m) n i rewrite splitAt-↑ʳ m n i = reflsplitAt⁻¹-↑ʳ : ∀ {m} {n} {i} {j} → splitAt m {n} i ≡ inj₂ j → m ↑ʳ j ≡ isplitAt⁻¹-↑ʳ {zero} {n} {i} {j} refl = reflsplitAt⁻¹-↑ʳ {suc m} {n} {suc i} {j} eqwith inj₂ k ← splitAt m i in splitAt[m][i]≡inj₂[k]with refl ← eq= cong suc (splitAt⁻¹-↑ʳ {i = i} {j = k} splitAt[m][i]≡inj₂[k])splitAt-join : ∀ m n i → splitAt m (join m n i) ≡ isplitAt-join m n (inj₁ x) = splitAt-↑ˡ m x nsplitAt-join m n (inj₂ y) = splitAt-↑ʳ m n yjoin-splitAt : ∀ m n i → join m n (splitAt m i) ≡ ijoin-splitAt zero n i = refljoin-splitAt (suc m) n zero = refljoin-splitAt (suc m) n (suc i) = begin[ _↑ˡ n , (suc m) ↑ʳ_ ]′ (splitAt (suc m) (suc i)) ≡⟨ [,]-map (splitAt m i) ⟩[ suc ∘ (_↑ˡ n) , suc ∘ (m ↑ʳ_) ]′ (splitAt m i) ≡⟨ [,]-∘ suc (splitAt m i) ⟨suc ([ _↑ˡ n , m ↑ʳ_ ]′ (splitAt m i)) ≡⟨ cong suc (join-splitAt m n i) ⟩suc i ∎where open ≡-Reasoning-- splitAt "m" "i" ≡ inj₁ "i" if i < msplitAt-< : ∀ m {n} (i : Fin (m ℕ.+ n)) .(i<m : toℕ i ℕ.< m) →splitAt m i ≡ inj₁ (fromℕ< i<m)splitAt-< (suc m) zero _ = reflsplitAt-< (suc m) (suc i) i<m = cong (Sum.map suc id) (splitAt-< m i (ℕ.s<s⁻¹ i<m))-- splitAt "m" "i" ≡ inj₂ "i - m" if i ≥ msplitAt-≥ : ∀ m {n} (i : Fin (m ℕ.+ n)) .(i≥m : toℕ i ℕ.≥ m) →splitAt m i ≡ inj₂ (reduce≥ i i≥m)splitAt-≥ zero i _ = reflsplitAt-≥ (suc m) (suc i) i≥m = cong (Sum.map suc id) (splitAt-≥ m i (ℕ.s≤s⁻¹ i≥m))-------------------------------------------------------------------------- Bundles+↔⊎ : Fin (m ℕ.+ n) ↔ (Fin m ⊎ Fin n)+↔⊎ {m} {n} = mk↔ₛ′ (splitAt m {n}) (join m n) (splitAt-join m n) (join-splitAt m n)-------------------------------------------------------------------------- remQuot-------------------------------------------------------------------------- Fin (m * n) ↔ Fin m × Fin nremQuot-combine : ∀ {n k} (i : Fin n) j → remQuot k (combine i j) ≡ (i , j)remQuot-combine {suc n} {k} zero j rewrite splitAt-↑ˡ k j (n ℕ.* k) = reflremQuot-combine {suc n} {k} (suc i) j rewrite splitAt-↑ʳ k (n ℕ.* k) (combine i j) =cong (Product.map₁ suc) (remQuot-combine i j)combine-remQuot : ∀ {n} k (i : Fin (n ℕ.* k)) → uncurry combine (remQuot {n} k i) ≡ icombine-remQuot {suc n} k i with splitAt k i in eq... | inj₁ j = beginjoin k (n ℕ.* k) (inj₁ j) ≡⟨ cong (join k (n ℕ.* k)) eq ⟨join k (n ℕ.* k) (splitAt k i) ≡⟨ join-splitAt k (n ℕ.* k) i ⟩i ∎where open ≡-Reasoning... | inj₂ j = begink ↑ʳ (uncurry combine (remQuot {n} k j)) ≡⟨ cong (k ↑ʳ_) (combine-remQuot {n} k j) ⟩join k (n ℕ.* k) (inj₂ j) ≡⟨ cong (join k (n ℕ.* k)) eq ⟨join k (n ℕ.* k) (splitAt k i) ≡⟨ join-splitAt k (n ℕ.* k) i ⟩i ∎where open ≡-Reasoningtoℕ-combine : ∀ (i : Fin m) (j : Fin n) → toℕ (combine i j) ≡ n ℕ.* toℕ i ℕ.+ toℕ jtoℕ-combine {suc m} {n} i@0F j = begintoℕ (combine i j) ≡⟨⟩toℕ (j ↑ˡ (m ℕ.* n)) ≡⟨ toℕ-↑ˡ j (m ℕ.* n) ⟩toℕ j ≡⟨⟩0 ℕ.+ toℕ j ≡⟨ cong (ℕ._+ toℕ j) (ℕ.*-zeroʳ n) ⟨n ℕ.* toℕ i ℕ.+ toℕ j ∎where open ≡-Reasoningtoℕ-combine {suc m} {n} (suc i) j = begintoℕ (combine (suc i) j) ≡⟨⟩toℕ (n ↑ʳ combine i j) ≡⟨ toℕ-↑ʳ n (combine i j) ⟩n ℕ.+ toℕ (combine i j) ≡⟨ cong (n ℕ.+_) (toℕ-combine i j) ⟩n ℕ.+ (n ℕ.* toℕ i ℕ.+ toℕ j) ≡⟨ ℕ.+-assoc n _ (toℕ j) ⟨n ℕ.+ n ℕ.* toℕ i ℕ.+ toℕ j ≡⟨ cong (λ z → z ℕ.+ n ℕ.* toℕ i ℕ.+ toℕ j) (ℕ.*-identityʳ n) ⟨n ℕ.* 1 ℕ.+ n ℕ.* toℕ i ℕ.+ toℕ j ≡⟨ cong (ℕ._+ toℕ j) (ℕ.*-distribˡ-+ n 1 (toℕ i) ) ⟨n ℕ.* toℕ (suc i) ℕ.+ toℕ j ∎where open ≡-Reasoningcombine-monoˡ-< : ∀ {i j : Fin m} (k l : Fin n) →i < j → combine i k < combine j lcombine-monoˡ-< {m} {n} {i} {j} k l i<j = begin-stricttoℕ (combine i k) ≡⟨ toℕ-combine i k ⟩n ℕ.* toℕ i ℕ.+ toℕ k <⟨ ℕ.+-monoʳ-< (n ℕ.* toℕ i) (toℕ<n k) ⟩n ℕ.* toℕ i ℕ.+ n ≡⟨ ℕ.+-comm _ n ⟩n ℕ.+ n ℕ.* toℕ i ≡⟨ cong (n ℕ.+_) (ℕ.*-comm n _) ⟩n ℕ.+ toℕ i ℕ.* n ≡⟨ ℕ.*-comm (suc (toℕ i)) n ⟩n ℕ.* suc (toℕ i) ≤⟨ ℕ.*-monoʳ-≤ n (toℕ-mono-< i<j) ⟩n ℕ.* toℕ j ≤⟨ ℕ.m≤m+n (n ℕ.* toℕ j) (toℕ l) ⟩n ℕ.* toℕ j ℕ.+ toℕ l ≡⟨ toℕ-combine j l ⟨toℕ (combine j l) ∎where open ℕ.≤-Reasoningcombine-injectiveˡ : ∀ (i : Fin m) (j : Fin n) (k : Fin m) (l : Fin n) →combine i j ≡ combine k l → i ≡ kcombine-injectiveˡ i j k l cᵢⱼ≡cₖₗ with <-cmp i k... | tri< i<k _ _ = contradiction cᵢⱼ≡cₖₗ (<⇒≢ (combine-monoˡ-< j l i<k))... | tri≈ _ i≡k _ = i≡k... | tri> _ _ i>k = contradiction (sym cᵢⱼ≡cₖₗ) (<⇒≢ (combine-monoˡ-< l j i>k))combine-injectiveʳ : ∀ (i : Fin m) (j : Fin n) (k : Fin m) (l : Fin n) →combine i j ≡ combine k l → j ≡ lcombine-injectiveʳ {m} {n} i j k l cᵢⱼ≡cₖₗwith refl ← combine-injectiveˡ i j k l cᵢⱼ≡cₖₗ= toℕ-injective (ℕ.+-cancelˡ-≡ (n ℕ.* toℕ i) _ _ (beginn ℕ.* toℕ i ℕ.+ toℕ j ≡⟨ toℕ-combine i j ⟨toℕ (combine i j) ≡⟨ cong toℕ cᵢⱼ≡cₖₗ ⟩toℕ (combine i l) ≡⟨ toℕ-combine i l ⟩n ℕ.* toℕ i ℕ.+ toℕ l ∎))where open ≡-Reasoningcombine-injective : ∀ (i : Fin m) (j : Fin n) (k : Fin m) (l : Fin n) →combine i j ≡ combine k l → i ≡ k × j ≡ lcombine-injective i j k l cᵢⱼ≡cₖₗ =combine-injectiveˡ i j k l cᵢⱼ≡cₖₗ ,combine-injectiveʳ i j k l cᵢⱼ≡cₖₗcombine-surjective : ∀ (i : Fin (m ℕ.* n)) → ∃₂ λ j k → combine j k ≡ icombine-surjective {m} {n} i with j , k ← remQuot {m} n i in eq= j , k , (begincombine j k ≡⟨ uncurry (cong₂ combine) (,-injective eq) ⟨uncurry combine (remQuot {m} n i) ≡⟨ combine-remQuot {m} n i ⟩i ∎)where open ≡-Reasoning-------------------------------------------------------------------------- Bundles*↔× : Fin (m ℕ.* n) ↔ (Fin m × Fin n)*↔× {m} {n} = mk↔ₛ′ (remQuot {m} n) (uncurry combine)(uncurry remQuot-combine)(combine-remQuot {m} n)-------------------------------------------------------------------------- fin→fun------------------------------------------------------------------------funToFin-finToFin : funToFin {m} {n} ∘ finToFun ≗ idfunToFin-finToFin {zero} {n} zero = reflfunToFin-finToFin {suc m} {n} k =begincombine (finToFun {n} {suc m} k zero) (funToFin (finToFun {n} {suc m} k ∘ suc))≡⟨⟩combine (quotient {n} (n ^ m) k)(funToFin (finToFun {n} {m} (remainder {n} (n ^ m) k)))≡⟨ cong (combine (quotient {n} (n ^ m) k))(funToFin-finToFin {m} (remainder {n} (n ^ m) k)) ⟩combine (quotient {n} (n ^ m) k) (remainder {n} (n ^ m) k)≡⟨⟩uncurry combine (remQuot {n} (n ^ m) k)≡⟨ combine-remQuot {n = n} (n ^ m) k ⟩k∎ where open ≡-ReasoningfinToFun-funToFin : (f : Fin m → Fin n) → finToFun (funToFin f) ≗ ffinToFun-funToFin {suc m} {n} f zero =beginquotient (n ^ m) (combine (f zero) (funToFin (f ∘ suc)))≡⟨ cong proj₁ (remQuot-combine _ _) ⟩proj₁ (f zero , funToFin (f ∘ suc))≡⟨⟩f zero∎ where open ≡-ReasoningfinToFun-funToFin {suc m} {n} f (suc i) =beginfinToFun (remainder {n} (n ^ m) (combine (f zero) (funToFin (f ∘ suc)))) i≡⟨ cong (λ rq → finToFun (proj₂ rq) i) (remQuot-combine {n} _ _) ⟩finToFun (proj₂ (f zero , funToFin (f ∘ suc))) i≡⟨⟩finToFun (funToFin (f ∘ suc)) i≡⟨ finToFun-funToFin (f ∘ suc) i ⟩(f ∘ suc) i≡⟨⟩f (suc i)∎ where open ≡-Reasoning-------------------------------------------------------------------------- Bundles^↔→ : Extensionality _ _ → Fin (m ^ n) ↔ (Fin n → Fin m)^↔→ {m} {n} ext = mk↔ₛ′ finToFun funToFin(ext ∘ finToFun-funToFin)(funToFin-finToFin {n} {m})-------------------------------------------------------------------------- lift------------------------------------------------------------------------lift-injective : ∀ (f : Fin m → Fin n) → Injective _≡_ _≡_ f →∀ k → Injective _≡_ _≡_ (lift k f)lift-injective f inj zero {_} {_} eq = inj eqlift-injective f inj (suc k) {zero} {zero} eq = refllift-injective f inj (suc k) {suc _} {suc _} eq =cong suc (lift-injective f inj k (suc-injective eq))-------------------------------------------------------------------------- pred------------------------------------------------------------------------<⇒≤pred : i < j → i ≤ pred j<⇒≤pred {i = zero} {j = suc j} z<s = z≤n<⇒≤pred {i = suc i} {j = suc j} (s<s i<j) rewrite toℕ-inject₁ j = i<j-------------------------------------------------------------------------- _ℕ-_------------------------------------------------------------------------toℕ‿ℕ- : ∀ n i → toℕ (n ℕ- i) ≡ n ∸ toℕ itoℕ‿ℕ- n zero = toℕ-fromℕ ntoℕ‿ℕ- (suc n) (suc i) = toℕ‿ℕ- n i-------------------------------------------------------------------------- _ℕ-ℕ_------------------------------------------------------------------------ℕ-ℕ≡toℕ‿ℕ- : ∀ n i → n ℕ-ℕ i ≡ toℕ (n ℕ- i)ℕ-ℕ≡toℕ‿ℕ- n zero = sym (toℕ-fromℕ n)ℕ-ℕ≡toℕ‿ℕ- (suc n) (suc i) = ℕ-ℕ≡toℕ‿ℕ- n inℕ-ℕi≤n : ∀ n i → n ℕ-ℕ i ℕ.≤ nnℕ-ℕi≤n n zero = ℕ.≤-reflnℕ-ℕi≤n (suc n) (suc i) = beginn ℕ-ℕ i ≤⟨ nℕ-ℕi≤n n i ⟩n ≤⟨ ℕ.n≤1+n n ⟩suc n ∎where open ℕ.≤-Reasoning-------------------------------------------------------------------------- punchIn------------------------------------------------------------------------punchIn-injective : ∀ i (j k : Fin n) →punchIn i j ≡ punchIn i k → j ≡ kpunchIn-injective zero _ _ refl = reflpunchIn-injective (suc i) zero zero _ = reflpunchIn-injective (suc i) (suc j) (suc k) ↑j+1≡↑k+1 =cong suc (punchIn-injective i j k (suc-injective ↑j+1≡↑k+1))punchInᵢ≢i : ∀ i (j : Fin n) → punchIn i j ≢ ipunchInᵢ≢i (suc i) (suc j) = punchInᵢ≢i i j ∘ suc-injective-------------------------------------------------------------------------- punchOut-------------------------------------------------------------------------- A version of 'cong' for 'punchOut' in which the inequality argument-- can be changed out arbitrarily (reflecting the proof-irrelevance of-- that argument).punchOut-cong : ∀ (i : Fin (suc n)) {j k} {i≢j : i ≢ j} {i≢k : i ≢ k} →j ≡ k → punchOut i≢j ≡ punchOut i≢kpunchOut-cong {_} zero {zero} {i≢j = 0≢0} = contradiction refl 0≢0punchOut-cong {_} zero {suc j} {zero} {i≢k = 0≢0} = contradiction refl 0≢0punchOut-cong {_} zero {suc j} {suc k} = suc-injectivepunchOut-cong {suc n} (suc i) {zero} {zero} _ = reflpunchOut-cong {suc n} (suc i) {suc j} {suc k} = cong suc ∘ punchOut-cong i ∘ suc-injective-- An alternative to 'punchOut-cong' in the which the new inequality-- argument is specific. Useful for enabling the omission of that-- argument during equational reasoning.punchOut-cong′ : ∀ (i : Fin (suc n)) {j k} {p : i ≢ j} (q : j ≡ k) →punchOut p ≡ punchOut (p ∘ sym ∘ trans q ∘ sym)punchOut-cong′ i q = punchOut-cong i qpunchOut-injective : ∀ {i j k : Fin (suc n)}(i≢j : i ≢ j) (i≢k : i ≢ k) →punchOut i≢j ≡ punchOut i≢k → j ≡ kpunchOut-injective {_} {zero} {zero} {_} 0≢0 _ _ = contradiction refl 0≢0punchOut-injective {_} {zero} {_} {zero} _ 0≢0 _ = contradiction refl 0≢0punchOut-injective {_} {zero} {suc j} {suc k} _ _ pⱼ≡pₖ = cong suc pⱼ≡pₖpunchOut-injective {suc n} {suc i} {zero} {zero} _ _ _ = reflpunchOut-injective {suc n} {suc i} {suc j} {suc k} i≢j i≢k pⱼ≡pₖ =cong suc (punchOut-injective (i≢j ∘ cong suc) (i≢k ∘ cong suc) (suc-injective pⱼ≡pₖ))punchIn-punchOut : ∀ {i j : Fin (suc n)} (i≢j : i ≢ j) →punchIn i (punchOut i≢j) ≡ jpunchIn-punchOut {_} {zero} {zero} 0≢0 = contradiction refl 0≢0punchIn-punchOut {_} {zero} {suc j} _ = reflpunchIn-punchOut {suc m} {suc i} {zero} i≢j = reflpunchIn-punchOut {suc m} {suc i} {suc j} i≢j =cong suc (punchIn-punchOut (i≢j ∘ cong suc))punchOut-punchIn : ∀ i {j : Fin n} → punchOut {i = i} {j = punchIn i j} (punchInᵢ≢i i j ∘ sym) ≡ jpunchOut-punchIn zero {j} = reflpunchOut-punchIn (suc i) {zero} = reflpunchOut-punchIn (suc i) {suc j} = cong suc (beginpunchOut (punchInᵢ≢i i j ∘ suc-injective ∘ sym ∘ cong suc) ≡⟨ punchOut-cong i refl ⟩punchOut (punchInᵢ≢i i j ∘ sym) ≡⟨ punchOut-punchIn i ⟩j ∎)where open ≡-Reasoning-------------------------------------------------------------------------- pinch------------------------------------------------------------------------pinch-surjective : ∀ (i : Fin n) → Surjective _≡_ _≡_ (pinch i)pinch-surjective _ zero = zero , λ { refl → refl }pinch-surjective zero (suc j) = suc (suc j) , λ { refl → refl }pinch-surjective (suc i) (suc j) = map suc (λ {f refl → cong suc (f refl)}) (pinch-surjective i j)pinch-mono-≤ : ∀ (i : Fin n) → (pinch i) Preserves _≤_ ⟶ _≤_pinch-mono-≤ 0F {0F} {k} 0≤n = z≤npinch-mono-≤ 0F {suc j} {suc k} j≤k = ℕ.s≤s⁻¹ j≤kpinch-mono-≤ (suc i) {0F} {k} 0≤n = z≤npinch-mono-≤ (suc i) {suc j} {suc k} j≤k = s≤s (pinch-mono-≤ i (ℕ.s≤s⁻¹ j≤k))pinch-injective : ∀ {i : Fin n} {j k : Fin (ℕ.suc n)} →suc i ≢ j → suc i ≢ k → pinch i j ≡ pinch i k → j ≡ kpinch-injective {i = i} {zero} {zero} _ _ _ = reflpinch-injective {i = zero} {zero} {suc k} _ 1+i≢k eq =contradiction (cong suc eq) 1+i≢kpinch-injective {i = zero} {suc j} {zero} 1+i≢j _ eq =contradiction (cong suc (sym eq)) 1+i≢jpinch-injective {i = zero} {suc j} {suc k} _ _ eq =cong suc eqpinch-injective {i = suc i} {suc j} {suc k} 1+i≢j 1+i≢k eq =cong suc(pinch-injective (1+i≢j ∘ cong suc) (1+i≢k ∘ cong suc)(suc-injective eq))-------------------------------------------------------------------------- Quantification------------------------------------------------------------------------module _ {p} {P : Pred (Fin (suc n)) p} where∀-cons : P zero → Π[ P ∘ suc ] → Π[ P ]∀-cons z s zero = z∀-cons z s (suc i) = s i∀-cons-⇔ : (P zero × Π[ P ∘ suc ]) ⇔ Π[ P ]∀-cons-⇔ = mk⇔ (uncurry ∀-cons) < _$ zero , _∘ suc >∃-here : P zero → ∃⟨ P ⟩∃-here = zero ,_∃-there : ∃⟨ P ∘ suc ⟩ → ∃⟨ P ⟩∃-there = map suc id∃-toSum : ∃⟨ P ⟩ → P zero ⊎ ∃⟨ P ∘ suc ⟩∃-toSum ( zero , P₀ ) = inj₁ P₀∃-toSum (suc f , P₁₊) = inj₂ (f , P₁₊)⊎⇔∃ : (P zero ⊎ ∃⟨ P ∘ suc ⟩) ⇔ ∃⟨ P ⟩⊎⇔∃ = mk⇔ [ ∃-here , ∃-there ] ∃-toSumdecFinSubset : ∀ {p q} {P : Pred (Fin n) p} {Q : Pred (Fin n) q} →Decidable Q → (∀ {i} → Q i → Dec (P i)) → Dec (Q ⊆ P)decFinSubset {zero} {_} {_} Q? P? = yes λ {}decFinSubset {suc n} {P = P} {Q} Q? P?with Q? zero | ∀-cons {P = λ x → Q x → P x}... | false because [¬Q0] | cons =map′ (λ f {x} → cons (⊥-elim ∘ invert [¬Q0]) (λ x → f {x}) x)(λ f {x} → f {suc x})(decFinSubset (Q? ∘ suc) P?)... | true because [Q0] | cons =map′ (uncurry λ P0 rec {x} → cons (λ _ → P0) (λ x → rec {x}) x)< _$ invert [Q0] , (λ f {x} → f {suc x}) >(P? (invert [Q0]) ×-dec decFinSubset (Q? ∘ suc) P?)any? : ∀ {p} {P : Pred (Fin n) p} → Decidable P → Dec (∃ P)any? {zero} {P = _} P? = no λ { (() , _) }any? {suc n} {P = P} P? = Dec.map ⊎⇔∃ (P? zero ⊎-dec any? (P? ∘ suc))all? : ∀ {p} {P : Pred (Fin n) p} → Decidable P → Dec (∀ f → P f)all? P? = map′ (λ ∀p f → ∀p tt) (λ ∀p {x} _ → ∀p x)(decFinSubset U? (λ {f} _ → P? f))private-- A nice computational property of `all?`:-- The boolean component of the result is exactly the-- obvious fold of boolean tests (`foldr _∧_ true`).note : ∀ {p} {P : Pred (Fin 3) p} (P? : Decidable P) →∃ λ z → Dec.does (all? P?) ≡ znote P? = Dec.does (P? 0F) ∧ Dec.does (P? 1F) ∧ Dec.does (P? 2F) ∧ true, refl-- If a decidable predicate P over a finite set is sometimes false,-- then we can find the smallest value for which this is the case.¬∀⟶∃¬-smallest : ∀ n {p} (P : Pred (Fin n) p) → Decidable P →¬ (∀ i → P i) → ∃ λ i → ¬ P i × ((j : Fin′ i) → P (inject j))¬∀⟶∃¬-smallest zero P P? ¬∀P = contradiction (λ()) ¬∀P¬∀⟶∃¬-smallest (suc n) P P? ¬∀P with P? zero... | false because [¬P₀] = (zero , invert [¬P₀] , λ ())... | true because [P₀] = map suc (map id (∀-cons (invert [P₀])))(¬∀⟶∃¬-smallest n (P ∘ suc) (P? ∘ suc) (¬∀P ∘ (∀-cons (invert [P₀]))))-- When P is a decidable predicate over a finite set the following-- lemma can be proved.¬∀⟶∃¬ : ∀ n {p} (P : Pred (Fin n) p) → Decidable P →¬ (∀ i → P i) → (∃ λ i → ¬ P i)¬∀⟶∃¬ n P P? ¬P = map id proj₁ (¬∀⟶∃¬-smallest n P P? ¬P)-------------------------------------------------------------------------- Properties of functions to and from Fin-------------------------------------------------------------------------- The pigeonhole principle.pigeonhole : m ℕ.< n → (f : Fin n → Fin m) → ∃₂ λ i j → i < j × f i ≡ f jpigeonhole z<s f = contradiction (f zero) λ()pigeonhole (s<s m<n@(s≤s _)) f with any? (λ k → f zero ≟ f (suc k))... | yes (j , f₀≡fⱼ) = zero , suc j , z<s , f₀≡fⱼ... | no f₀≢fₖwith i , j , i<j , fᵢ≡fⱼ ← pigeonhole m<n (λ j → punchOut (f₀≢fₖ ∘ (j ,_ )))= suc i , suc j , s<s i<j , punchOut-injective (f₀≢fₖ ∘ (i ,_)) _ fᵢ≡fⱼinjective⇒≤ : ∀ {f : Fin m → Fin n} → Injective _≡_ _≡_ f → m ℕ.≤ ninjective⇒≤ {zero} {_} {f} _ = z≤ninjective⇒≤ {suc _} {zero} {f} _ = contradiction (f zero) ¬Fin0injective⇒≤ {suc _} {suc _} {f} inj = s≤s (injective⇒≤ (λ eq →suc-injective (inj (punchOut-injective(contraInjective inj 0≢1+n)(contraInjective inj 0≢1+n) eq))))<⇒notInjective : ∀ {f : Fin m → Fin n} → n ℕ.< m → ¬ (Injective _≡_ _≡_ f)<⇒notInjective n<m inj = ℕ.≤⇒≯ (injective⇒≤ inj) n<mℕ→Fin-notInjective : ∀ (f : ℕ → Fin n) → ¬ (Injective _≡_ _≡_ f)ℕ→Fin-notInjective f inj = ℕ.<-irrefl refl(injective⇒≤ (Comp.injective _≡_ _≡_ _≡_ toℕ-injective inj))-- Cantor-Schröder-Bernstein for finite setscantor-schröder-bernstein : ∀ {f : Fin m → Fin n} {g : Fin n → Fin m} →Injective _≡_ _≡_ f → Injective _≡_ _≡_ g →m ≡ ncantor-schröder-bernstein f-inj g-inj = ℕ.≤-antisym(injective⇒≤ f-inj) (injective⇒≤ g-inj)-------------------------------------------------------------------------- Effectful------------------------------------------------------------------------module _ {f} {F : Set f → Set f} (RA : RawApplicative F) whereopen RawApplicative RAsequence : ∀ {n} {P : Pred (Fin n) f} →(∀ i → F (P i)) → F (∀ i → P i)sequence {zero} ∀iPi = pure λ()sequence {suc n} ∀iPi = ∀-cons <$> ∀iPi zero <*> sequence (∀iPi ∘ suc)module _ {f} {F : Set f → Set f} (RF : RawFunctor F) whereopen RawFunctor RFsequence⁻¹ : ∀ {A : Set f} {P : Pred A f} →F (∀ i → P i) → (∀ i → F (P i))sequence⁻¹ F∀iPi i = (λ f → f i) <$> F∀iPi-------------------------------------------------------------------------- If there is an injection from a type A to a finite set, then the type-- has decidable equality.module _ {ℓ} {S : Setoid a ℓ} (inj : Injection S (≡-setoid n)) whereopen Setoid Sinj⇒≟ : B.Decidable _≈_inj⇒≟ = Dec.via-injection inj _≟_inj⇒decSetoid : DecSetoid a ℓinj⇒decSetoid = record{ isDecEquivalence = record{ isEquivalence = isEquivalence; _≟_ = inj⇒≟}}-------------------------------------------------------------------------- Opposite------------------------------------------------------------------------opposite-prop : ∀ (i : Fin n) → toℕ (opposite i) ≡ n ∸ suc (toℕ i)opposite-prop {suc n} zero = toℕ-fromℕ nopposite-prop {suc n} (suc i) = begintoℕ (inject₁ (opposite i)) ≡⟨ toℕ-inject₁ (opposite i) ⟩toℕ (opposite i) ≡⟨ opposite-prop i ⟩n ∸ suc (toℕ i) ∎where open ≡-Reasoningopposite-involutive : Involutive {A = Fin n} _≡_ oppositeopposite-involutive {suc n} i = toℕ-injective (begintoℕ (opposite (opposite i)) ≡⟨ opposite-prop (opposite i) ⟩n ∸ (toℕ (opposite i)) ≡⟨ cong (n ∸_) (opposite-prop i) ⟩n ∸ (n ∸ (toℕ i)) ≡⟨ ℕ.m∸[m∸n]≡n (toℕ≤pred[n] i) ⟩toℕ i ∎)where open ≡-Reasoningopposite-suc : ∀ (i : Fin n) → toℕ (opposite (suc i)) ≡ toℕ (opposite i)opposite-suc {n} i = begintoℕ (opposite (suc i)) ≡⟨ opposite-prop (suc i) ⟩suc n ∸ suc (toℕ (suc i)) ≡⟨⟩n ∸ toℕ (suc i) ≡⟨⟩n ∸ suc (toℕ i) ≡⟨ opposite-prop i ⟨toℕ (opposite i) ∎where open ≡-Reasoning-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.5inject+-raise-splitAt = join-splitAt{-# WARNING_ON_USAGE inject+-raise-splitAt"Warning: inject+-raise-splitAt was deprecated in v1.5.Please use join-splitAt instead."#-}-- Version 2.0toℕ-raise = toℕ-↑ʳ{-# WARNING_ON_USAGE toℕ-raise"Warning: toℕ-raise was deprecated in v2.0.Please use toℕ-↑ʳ instead."#-}toℕ-inject+ : ∀ {m} n (i : Fin m) → toℕ i ≡ toℕ (i ↑ˡ n)toℕ-inject+ n i = sym (toℕ-↑ˡ i n){-# WARNING_ON_USAGE toℕ-inject+"Warning: toℕ-inject+ was deprecated in v2.0.Please use toℕ-↑ˡ instead.NB argument order has been flipped:the left-hand argument is the Fin mthe right-hand is the Nat index increment."#-}splitAt-inject+ : ∀ m n i → splitAt m (i ↑ˡ n) ≡ inj₁ isplitAt-inject+ m n i = splitAt-↑ˡ m i n{-# WARNING_ON_USAGE splitAt-inject+"Warning: splitAt-inject+ was deprecated in v2.0.Please use splitAt-↑ˡ instead.NB argument order has been flipped."#-}splitAt-raise : ∀ m n i → splitAt m (m ↑ʳ i) ≡ inj₂ {B = Fin n} isplitAt-raise = splitAt-↑ʳ{-# WARNING_ON_USAGE splitAt-raise"Warning: splitAt-raise was deprecated in v2.0.Please use splitAt-↑ʳ instead."#-}Fin0↔⊥ : Fin 0 ↔ ⊥Fin0↔⊥ = 0↔⊥{-# WARNING_ON_USAGE Fin0↔⊥"Warning: Fin0↔⊥ was deprecated in v2.0.Please use 0↔⊥ instead."#-}eq? : A ↣ Fin n → DecidableEquality Aeq? = inj⇒≟{-# WARNING_ON_USAGE eq?"Warning: eq? was deprecated in v2.0.Please use inj⇒≟ instead."#-}privatez≺s : ∀ {n} → zero ≺ suc nz≺s = _ ≻toℕ zeros≺s : ∀ {m n} → m ≺ n → suc m ≺ suc ns≺s (n ≻toℕ i) = (suc n) ≻toℕ (suc i)<⇒≺ : ℕ._<_ ⇒ _≺_<⇒≺ {zero} z<s = z≺s<⇒≺ {suc m} (s<s lt) = s≺s (<⇒≺ lt)≺⇒< : _≺_ ⇒ ℕ._<_≺⇒< (n ≻toℕ i) = toℕ<n i≺⇒<′ : _≺_ ⇒ ℕ._<′_≺⇒<′ lt = ℕ.<⇒<′ (≺⇒< lt){-# WARNING_ON_USAGE ≺⇒<′"Warning: ≺⇒<′ was deprecated in v2.0.Please use <⇒<′ instead."#-}<′⇒≺ : ℕ._<′_ ⇒ _≺_<′⇒≺ lt = <⇒≺ (ℕ.<′⇒< lt){-# WARNING_ON_USAGE <′⇒≺"Warning: <′⇒≺ was deprecated in v2.0.Please use <′⇒< instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bijections on finite sets (i.e. permutations).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Permutation whereopen import Data.Bool.Base using (true; false)open import Data.Fin.Base using (Fin; suc; opposite; punchIn; punchOut)open import Data.Fin.Patterns using (0F)open import Data.Fin.Properties using (punchInᵢ≢i; punchOut-punchIn;punchOut-cong; punchOut-cong′; punchIn-punchOut; _≟_; ¬Fin0)import Data.Fin.Permutation.Components as PCopen import Data.Nat.Base using (ℕ; suc; zero)open import Data.Product.Base using (_,_; proj₂)open import Function.Bundles using (_↔_; Injection; Inverse; mk↔ₛ′)open import Function.Construct.Composition using (_↔-∘_)open import Function.Construct.Identity using (↔-id)open import Function.Construct.Symmetry using (↔-sym)open import Function.Definitions using (StrictlyInverseˡ; StrictlyInverseʳ)open import Function.Properties.Inverse using (↔⇒↣)open import Function.Base using (_∘_)open import Level using (0ℓ)open import Relation.Binary.Core using (Rel)open import Relation.Nullary using (does; ¬_; yes; no)open import Relation.Nullary.Decidable using (dec-yes; dec-no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; _≢_; refl; sym; trans; subst; cong; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablem n o : ℕ-------------------------------------------------------------------------- Types-- A bijection between finite sets of potentially different sizes.-- There only exist inhabitants of this type if in fact m = n, however-- it is often easier to prove the existence of a bijection without-- first proving that the sets have the same size. Indeed such a-- bijection is a useful way to prove that the sets are in fact the same-- size. See '↔-≡' below.Permutation : ℕ → ℕ → SetPermutation m n = Fin m ↔ Fin nPermutation′ : ℕ → SetPermutation′ n = Permutation n n-------------------------------------------------------------------------- Helper functionspermutation : ∀ (f : Fin m → Fin n) (g : Fin n → Fin m) →StrictlyInverseˡ _≡_ f g → StrictlyInverseʳ _≡_ f g → Permutation m npermutation = mk↔ₛ′infixl 5 _⟨$⟩ʳ_ _⟨$⟩ˡ__⟨$⟩ʳ_ : Permutation m n → Fin m → Fin n_⟨$⟩ʳ_ = Inverse.to_⟨$⟩ˡ_ : Permutation m n → Fin n → Fin m_⟨$⟩ˡ_ = Inverse.frominverseˡ : ∀ (π : Permutation m n) {i} → π ⟨$⟩ˡ (π ⟨$⟩ʳ i) ≡ iinverseˡ π = Inverse.inverseʳ π reflinverseʳ : ∀ (π : Permutation m n) {i} → π ⟨$⟩ʳ (π ⟨$⟩ˡ i) ≡ iinverseʳ π = Inverse.inverseˡ π refl-------------------------------------------------------------------------- Equalityinfix 6 _≈__≈_ : Rel (Permutation m n) 0ℓπ ≈ ρ = ∀ i → π ⟨$⟩ʳ i ≡ ρ ⟨$⟩ʳ i-------------------------------------------------------------------------- Example permutations-- Identityid : Permutation′ nid = ↔-id _-- Transpose two indicestranspose : Fin n → Fin n → Permutation′ ntranspose i j = permutation (PC.transpose i j) (PC.transpose j i) (λ _ → PC.transpose-inverse _ _) (λ _ → PC.transpose-inverse _ _)-- Reverse the order of indicesreverse : Permutation′ nreverse = permutation opposite opposite PC.reverse-involutive PC.reverse-involutive-------------------------------------------------------------------------- Operations-- Compositioninfixr 9 _∘ₚ__∘ₚ_ : Permutation m n → Permutation n o → Permutation m oπ₁ ∘ₚ π₂ = π₂ ↔-∘ π₁-- Flipflip : Permutation m n → Permutation n mflip = ↔-sym-- Element removal---- `remove k [0 ↦ i₀, …, k ↦ iₖ, …, n ↦ iₙ]` yields---- [0 ↦ i₀, …, k-1 ↦ iₖ₋₁, k ↦ iₖ₊₁, k+1 ↦ iₖ₊₂, …, n-1 ↦ iₙ]remove : Fin (suc m) → Permutation (suc m) (suc n) → Permutation m nremove {m} {n} i π = permutation to from inverseˡ′ inverseʳ′whereπʳ = π ⟨$⟩ʳ_πˡ = π ⟨$⟩ˡ_permute-≢ : ∀ {i j} → i ≢ j → πʳ i ≢ πʳ jpermute-≢ p = p ∘ Injection.injective (↔⇒↣ π)to-punchOut : ∀ {j : Fin m} → πʳ i ≢ πʳ (punchIn i j)to-punchOut = permute-≢ (punchInᵢ≢i _ _ ∘ sym)from-punchOut : ∀ {j : Fin n} → i ≢ πˡ (punchIn (πʳ i) j)from-punchOut {j} p = punchInᵢ≢i (πʳ i) j (sym (beginπʳ i ≡⟨ cong πʳ p ⟩πʳ (πˡ (punchIn (πʳ i) j)) ≡⟨ inverseʳ π ⟩punchIn (πʳ i) j ∎))to : Fin m → Fin nto j = punchOut (to-punchOut {j})from : Fin n → Fin mfrom j = punchOut {j = πˡ (punchIn (πʳ i) j)} from-punchOutinverseʳ′ : StrictlyInverseʳ _≡_ to frominverseʳ′ j = beginfrom (to j) ≡⟨⟩punchOut {i = i} {πˡ (punchIn (πʳ i) (punchOut to-punchOut))} _ ≡⟨ punchOut-cong′ i (cong πˡ (punchIn-punchOut _)) ⟩punchOut {i = i} {πˡ (πʳ (punchIn i j))} _ ≡⟨ punchOut-cong i (inverseˡ π) ⟩punchOut {i = i} {punchIn i j} _ ≡⟨ punchOut-punchIn i ⟩j ∎inverseˡ′ : StrictlyInverseˡ _≡_ to frominverseˡ′ j = beginto (from j) ≡⟨⟩punchOut {i = πʳ i} {πʳ (punchIn i (punchOut from-punchOut))} _ ≡⟨ punchOut-cong′ (πʳ i) (cong πʳ (punchIn-punchOut _)) ⟩punchOut {i = πʳ i} {πʳ (πˡ (punchIn (πʳ i) j))} _ ≡⟨ punchOut-cong (πʳ i) (inverseʳ π) ⟩punchOut {i = πʳ i} {punchIn (πʳ i) j} _ ≡⟨ punchOut-punchIn (πʳ i) ⟩j ∎-- lift: takes a permutation m → n and creates a permutation (suc m) → (suc n)-- by mapping 0 to 0 and applying the input permutation to everything elselift₀ : Permutation m n → Permutation (suc m) (suc n)lift₀ {m} {n} π = permutation to from inverseˡ′ inverseʳ′whereto : Fin (suc m) → Fin (suc n)to 0F = 0Fto (suc i) = suc (π ⟨$⟩ʳ i)from : Fin (suc n) → Fin (suc m)from 0F = 0Ffrom (suc i) = suc (π ⟨$⟩ˡ i)inverseʳ′ : StrictlyInverseʳ _≡_ to frominverseʳ′ 0F = reflinverseʳ′ (suc j) = cong suc (inverseˡ π)inverseˡ′ : StrictlyInverseˡ _≡_ to frominverseˡ′ 0F = reflinverseˡ′ (suc j) = cong suc (inverseʳ π)-- insert i j π is the permutation that maps i to j and otherwise looks like π-- it's roughly an inverse of removeinsert : ∀ {m n} → Fin (suc m) → Fin (suc n) → Permutation m n → Permutation (suc m) (suc n)insert {m} {n} i j π = permutation to from inverseˡ′ inverseʳ′whereto : Fin (suc m) → Fin (suc n)to k with i ≟ k... | yes i≡k = j... | no i≢k = punchIn j (π ⟨$⟩ʳ punchOut i≢k)from : Fin (suc n) → Fin (suc m)from k with j ≟ k... | yes j≡k = i... | no j≢k = punchIn i (π ⟨$⟩ˡ punchOut j≢k)inverseʳ′ : StrictlyInverseʳ _≡_ to frominverseʳ′ k with i ≟ k... | yes i≡k rewrite proj₂ (dec-yes (j ≟ j) refl) = i≡k... | no i≢kwith j≢punchInⱼπʳpunchOuti≢k ← punchInᵢ≢i j (π ⟨$⟩ʳ punchOut i≢k) ∘ symrewrite dec-no (j ≟ punchIn j (π ⟨$⟩ʳ punchOut i≢k)) j≢punchInⱼπʳpunchOuti≢k= beginpunchIn i (π ⟨$⟩ˡ punchOut j≢punchInⱼπʳpunchOuti≢k) ≡⟨ cong (λ l → punchIn i (π ⟨$⟩ˡ l)) (punchOut-cong j refl) ⟩punchIn i (π ⟨$⟩ˡ punchOut (punchInᵢ≢i j (π ⟨$⟩ʳ punchOut i≢k) ∘ sym)) ≡⟨ cong (λ l → punchIn i (π ⟨$⟩ˡ l)) (punchOut-punchIn j) ⟩punchIn i (π ⟨$⟩ˡ (π ⟨$⟩ʳ punchOut i≢k)) ≡⟨ cong (punchIn i) (inverseˡ π) ⟩punchIn i (punchOut i≢k) ≡⟨ punchIn-punchOut i≢k ⟩k ∎inverseˡ′ : StrictlyInverseˡ _≡_ to frominverseˡ′ k with j ≟ k... | yes j≡k rewrite proj₂ (dec-yes (i ≟ i) refl) = j≡k... | no j≢kwith i≢punchInᵢπˡpunchOutj≢k ← punchInᵢ≢i i (π ⟨$⟩ˡ punchOut j≢k) ∘ symrewrite dec-no (i ≟ punchIn i (π ⟨$⟩ˡ punchOut j≢k)) i≢punchInᵢπˡpunchOutj≢k= beginpunchIn j (π ⟨$⟩ʳ punchOut i≢punchInᵢπˡpunchOutj≢k) ≡⟨ cong (λ l → punchIn j (π ⟨$⟩ʳ l)) (punchOut-cong i refl) ⟩punchIn j (π ⟨$⟩ʳ punchOut (punchInᵢ≢i i (π ⟨$⟩ˡ punchOut j≢k) ∘ sym)) ≡⟨ cong (λ l → punchIn j (π ⟨$⟩ʳ l)) (punchOut-punchIn i) ⟩punchIn j (π ⟨$⟩ʳ (π ⟨$⟩ˡ punchOut j≢k)) ≡⟨ cong (punchIn j) (inverseʳ π) ⟩punchIn j (punchOut j≢k) ≡⟨ punchIn-punchOut j≢k ⟩k ∎-------------------------------------------------------------------------- Other propertiesmodule _ (π : Permutation (suc m) (suc n)) whereprivateπʳ = π ⟨$⟩ʳ_πˡ = π ⟨$⟩ˡ_punchIn-permute : ∀ i j → πʳ (punchIn i j) ≡ punchIn (πʳ i) (remove i π ⟨$⟩ʳ j)punchIn-permute i j = sym (punchIn-punchOut _)punchIn-permute′ : ∀ i j → πʳ (punchIn (πˡ i) j) ≡ punchIn i (remove (πˡ i) π ⟨$⟩ʳ j)punchIn-permute′ i j = beginπʳ (punchIn (πˡ i) j) ≡⟨ punchIn-permute _ _ ⟩punchIn (πʳ (πˡ i)) (remove (πˡ i) π ⟨$⟩ʳ j) ≡⟨ cong₂ punchIn (inverseʳ π) refl ⟩punchIn i (remove (πˡ i) π ⟨$⟩ʳ j) ∎lift₀-remove : πʳ 0F ≡ 0F → lift₀ (remove 0F π) ≈ πlift₀-remove p 0F = sym plift₀-remove p (suc i) = punchOut-zero (πʳ (suc i)) pwherepunchOut-zero : ∀ {i} (j : Fin (suc n)) {neq} → i ≡ 0F → suc (punchOut {i = i} {j} neq) ≡ jpunchOut-zero 0F {neq} p = contradiction p neqpunchOut-zero (suc j) refl = refl↔⇒≡ : Permutation m n → m ≡ n↔⇒≡ {zero} {zero} π = refl↔⇒≡ {zero} {suc n} π = contradiction (π ⟨$⟩ˡ 0F) ¬Fin0↔⇒≡ {suc m} {zero} π = contradiction (π ⟨$⟩ʳ 0F) ¬Fin0↔⇒≡ {suc m} {suc n} π = cong suc (↔⇒≡ (remove 0F π))fromPermutation : Permutation m n → Permutation′ mfromPermutation π = subst (Permutation _) (sym (↔⇒≡ π)) πrefute : m ≢ n → ¬ Permutation m nrefute m≢n π = contradiction (↔⇒≡ π) m≢nlift₀-id : (i : Fin (suc n)) → lift₀ id ⟨$⟩ʳ i ≡ ilift₀-id 0F = refllift₀-id (suc i) = refllift₀-comp : ∀ (π : Permutation m n) (ρ : Permutation n o) →lift₀ π ∘ₚ lift₀ ρ ≈ lift₀ (π ∘ₚ ρ)lift₀-comp π ρ 0F = refllift₀-comp π ρ (suc i) = refllift₀-cong : ∀ (π ρ : Permutation m n) → π ≈ ρ → lift₀ π ≈ lift₀ ρlift₀-cong π ρ f 0F = refllift₀-cong π ρ f (suc i) = cong suc (f i)lift₀-transpose : ∀ (i j : Fin n) → transpose (suc i) (suc j) ≈ lift₀ (transpose i j)lift₀-transpose i j 0F = refllift₀-transpose i j (suc k) with does (k ≟ i)... | true = refl... | false with does (k ≟ j)... | false = refl... | true = reflinsert-punchIn : ∀ i j (π : Permutation m n) k → insert i j π ⟨$⟩ʳ punchIn i k ≡ punchIn j (π ⟨$⟩ʳ k)insert-punchIn i j π k with i ≟ punchIn i k... | yes i≡punchInᵢk = contradiction (sym i≡punchInᵢk) (punchInᵢ≢i i k)... | no i≢punchInᵢk = beginpunchIn j (π ⟨$⟩ʳ punchOut i≢punchInᵢk) ≡⟨ cong (λ l → punchIn j (π ⟨$⟩ʳ l)) (punchOut-cong i refl) ⟩punchIn j (π ⟨$⟩ʳ punchOut (punchInᵢ≢i i k ∘ sym)) ≡⟨ cong (λ l → punchIn j (π ⟨$⟩ʳ l)) (punchOut-punchIn i) ⟩punchIn j (π ⟨$⟩ʳ k) ∎insert-remove : ∀ i (π : Permutation (suc m) (suc n)) → insert i (π ⟨$⟩ʳ i) (remove i π) ≈ πinsert-remove {m = m} {n = n} i π j with i ≟ j... | yes i≡j = cong (π ⟨$⟩ʳ_) i≡j... | no i≢j = beginpunchIn (π ⟨$⟩ʳ i) (punchOut (punchInᵢ≢i i (punchOut i≢j) ∘ sym ∘ Injection.injective (↔⇒↣ π))) ≡⟨ punchIn-punchOut _ ⟩π ⟨$⟩ʳ punchIn i (punchOut i≢j) ≡⟨ cong (π ⟨$⟩ʳ_) (punchIn-punchOut i≢j) ⟩π ⟨$⟩ʳ j ∎remove-insert : ∀ i j (π : Permutation m n) → remove i (insert i j π) ≈ πremove-insert i j π k with i ≟ i... | no i≢i = contradiction refl i≢i... | yes _ = beginpunchOut {i = j} _≡⟨ punchOut-cong j (insert-punchIn i j π k) ⟩punchOut {i = j} (punchInᵢ≢i j (π ⟨$⟩ʳ k) ∘ sym)≡⟨ punchOut-punchIn j ⟩π ⟨$⟩ʳ k∎
-------------------------------------------------------------------------- The Agda standard library---- Decomposition of permutations into a list of transpositions.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Permutation.Transposition.List whereopen import Data.Fin.Base using (Fin; suc)open import Data.Fin.Patterns using (0F)open import Data.Fin.Permutation as P hiding (lift₀)import Data.Fin.Permutation.Components as PCopen import Data.List.Base using (List; []; _∷_; map)open import Data.Nat.Base using (ℕ; suc; zero)open import Data.Product.Base using (_×_; _,_)open import Function.Base using (_∘_)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; sym; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open ≡-Reasoningprivatevariablen : ℕ-------------------------------------------------------------------------- Definition-- This decomposition is not a unique representation of the original-- permutation but can be used to simply proofs about permutations (by-- instead inducting on the list of transpositions).TranspositionList : ℕ → SetTranspositionList n = List (Fin n × Fin n)-------------------------------------------------------------------------- Operations on transposition listslift₀ : TranspositionList n → TranspositionList (suc n)lift₀ xs = map (λ (i , j) → (suc i , suc j)) xseval : TranspositionList n → Permutation′ neval [] = ideval ((i , j) ∷ xs) = transpose i j ∘ₚ eval xsdecompose : Permutation′ n → TranspositionList ndecompose {zero} π = []decompose {suc n} π = (π ⟨$⟩ˡ 0F , 0F) ∷ lift₀ (decompose (remove 0F ((transpose 0F (π ⟨$⟩ˡ 0F)) ∘ₚ π)))-------------------------------------------------------------------------- Propertieseval-lift : ∀ (xs : TranspositionList n) → eval (lift₀ xs) ≈ P.lift₀ (eval xs)eval-lift [] = sym ∘ lift₀-ideval-lift ((i , j) ∷ xs) k = begintranspose (suc i) (suc j) ∘ₚ eval (lift₀ xs) ⟨$⟩ʳ k ≡⟨ cong (eval (lift₀ xs) ⟨$⟩ʳ_) (lift₀-transpose i j k) ⟩P.lift₀ (transpose i j) ∘ₚ eval (lift₀ xs) ⟨$⟩ʳ k ≡⟨ eval-lift xs (P.lift₀ (transpose i j) ⟨$⟩ʳ k) ⟩P.lift₀ (eval xs) ⟨$⟩ʳ (P.lift₀ (transpose i j) ⟨$⟩ʳ k) ≡⟨ lift₀-comp (transpose i j) (eval xs) k ⟩P.lift₀ (transpose i j ∘ₚ eval xs) ⟨$⟩ʳ k ∎eval-decompose : ∀ (π : Permutation′ n) → eval (decompose π) ≈ πeval-decompose {suc n} π i = begintπ0 ∘ₚ eval (lift₀ (decompose (remove 0F (t0π ∘ₚ π)))) ⟨$⟩ʳ i ≡⟨ eval-lift (decompose (remove 0F (t0π ∘ₚ π))) (tπ0 ⟨$⟩ʳ i) ⟩tπ0 ∘ₚ P.lift₀ (eval (decompose (remove 0F (t0π ∘ₚ π)))) ⟨$⟩ʳ i ≡⟨ lift₀-cong _ _ (eval-decompose _) (tπ0 ⟨$⟩ʳ i) ⟩tπ0 ∘ₚ P.lift₀ (remove 0F (t0π ∘ₚ π)) ⟨$⟩ʳ i ≡⟨ lift₀-remove (t0π ∘ₚ π) (inverseʳ π) (tπ0 ⟨$⟩ʳ i) ⟩tπ0 ∘ₚ t0π ∘ₚ π ⟨$⟩ʳ i ≡⟨ cong (π ⟨$⟩ʳ_) (PC.transpose-inverse 0F (π ⟨$⟩ˡ 0F)) ⟩π ⟨$⟩ʳ i ∎wheretπ0 = transpose (π ⟨$⟩ˡ 0F) 0Ft0π = transpose 0F (π ⟨$⟩ˡ 0F)
-------------------------------------------------------------------------- The Agda standard library---- Component functions of permutations found in `Data.Fin.Permutation`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Permutation.Components whereopen import Data.Bool.Base using (Bool; true; false)open import Data.Fin.Base using (Fin; suc; opposite; toℕ)open import Data.Fin.Propertiesusing (_≟_; opposite-prop; opposite-involutive; opposite-suc)open import Data.Nat.Base as ℕ using (zero; suc; _∸_)open import Data.Product.Base using (proj₂)open import Function.Base using (_∘_)open import Relation.Nullary.Reflects using (invert)open import Relation.Nullary using (does; _because_; yes; no)open import Relation.Nullary.Decidable using (dec-true; dec-false)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; trans)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)open import Algebra.Definitions using (Involutive)open ≡-Reasoning-------------------------------------------------------------------------- Functions-------------------------------------------------------------------------- 'tranpose i j' swaps the places of 'i' and 'j'.transpose : ∀ {n} → Fin n → Fin n → Fin n → Fin ntranspose i j k with does (k ≟ i)... | true = j... | false with does (k ≟ j)... | true = i... | false = k-------------------------------------------------------------------------- Properties------------------------------------------------------------------------transpose-inverse : ∀ {n} (i j : Fin n) {k} →transpose i j (transpose j i k) ≡ ktranspose-inverse i j {k} with k ≟ j... | true because [k≡j] rewrite dec-true (i ≟ i) refl = sym (invert [k≡j])... | false because [k≢j] with k ≟ i... | true because [k≡i]rewrite dec-false (j ≟ i) (invert [k≢j] ∘ trans (invert [k≡i]) ∘ sym)| dec-true (j ≟ j) refl= sym (invert [k≡i])... | false because [k≢i] rewrite dec-false (k ≟ i) (invert [k≢i])| dec-false (k ≟ j) (invert [k≢j]) = refl-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0reverse = opposite{-# WARNING_ON_USAGE reverse"Warning: reverse was deprecated in v2.0.Please use opposite from Data.Fin.Base instead."#-}reverse-prop = opposite-prop{-# WARNING_ON_USAGE reverse"Warning: reverse-prop was deprecated in v2.0.Please use opposite-prop from Data.Fin.Properties instead."#-}reverse-involutive = opposite-involutive{-# WARNING_ON_USAGE reverse"Warning: reverse-involutive was deprecated in v2.0.Please use opposite-involutive from Data.Fin.Properties instead."#-}reverse-suc : ∀ {n} {i : Fin n} → toℕ (opposite (suc i)) ≡ toℕ (opposite i)reverse-suc {i = i} = opposite-suc i{-# WARNING_ON_USAGE reverse"Warning: reverse-suc was deprecated in v2.0.Please use opposite-suc from Data.Fin.Properties instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Patterns for Fin------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Patterns whereopen import Data.Fin.Base-------------------------------------------------------------------------- Constantspattern 0F = zeropattern 1F = suc 0Fpattern 2F = suc 1Fpattern 3F = suc 2Fpattern 4F = suc 3Fpattern 5F = suc 4Fpattern 6F = suc 5Fpattern 7F = suc 6Fpattern 8F = suc 7Fpattern 9F = suc 8F
-------------------------------------------------------------------------- The Agda standard library---- Fin Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Literals whereopen import Agda.Builtin.FromNatopen import Data.Nat using (suc; _≤?_)open import Data.Fin using (Fin ; #_)open import Relation.Nullary.Decidable using (True)number : ∀ n → Number (Fin n)number n = record{ Constraint = λ m → True (suc m ≤? n); fromNat = λ m {{pr}} → (# m) {n} {pr}}
-------------------------------------------------------------------------- The Agda standard library---- Instances for finite sets------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Instances whereopen import Data.Fin.Baseopen import Data.Fin.PropertiesinstanceFin-≡-isDecEquivalence = ≡-isDecEquivalenceFin-≤-isDecTotalOrder = ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- Induction over Fin------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}{-# OPTIONS --warn=noUserWarning #-} -- for deprecated _≺_ (issue #1726)module Data.Fin.Induction whereopen import Data.Fin.Base using (Fin; zero; suc; _<_; toℕ; inject₁;_≥_; _>_; fromℕ; _≺_)open import Data.Fin.Properties using (toℕ-inject₁; ≤-refl; <-cmp;toℕ≤n; toℕ-injective; toℕ-fromℕ; toℕ-lower₁; inject₁-lower₁;pigeonhole; ≺⇒<′)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _∸_; s≤s)open import Data.Nat.Properties using (n<1+n; ≤⇒≯)import Data.Nat.Induction as ℕimport Data.Nat.Properties as ℕopen import Data.Product.Base using (_,_)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Relation.Unary.Linked as Linked using (Linked; [-]; _∷_)import Data.Vec.Relation.Unary.Linked.Properties as Linkedopen import Function.Base using (flip; _$_)open import Induction using (RecStruct)open import Induction.WellFounded as WF using (WellFounded; WfRec;module Subrelation)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (StrictPartialOrder)open import Relation.Binary.Structures using (IsPartialOrder; IsStrictPartialOrder)open import Relation.Binary.Definitions using (Decidable)import Relation.Binary.Construct.Flip.EqAndOrd as EqAndOrdimport Relation.Binary.Construct.Flip.Ord as Ordimport Relation.Binary.Construct.NonStrictToStrict as ToStrictimport Relation.Binary.Construct.On as Onopen import Relation.Binary.Definitions using (Tri; tri<; tri≈; tri>)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; sym; subst; trans; cong)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation using (contradiction)open import Relation.Unary using (Pred)privatevariableℓ : Leveln : ℕ-------------------------------------------------------------------------- Re-export accessabilityopen WF public using (Acc; acc)-------------------------------------------------------------------------- Induction over _<_<-wellFounded : WellFounded {A = Fin n} _<_<-wellFounded = On.wellFounded toℕ ℕ.<-wellFounded<-weakInduction-startingFrom : ∀ (P : Pred (Fin (suc n)) ℓ) →∀ {i} → P i →(∀ j → P (inject₁ j) → P (suc j)) →∀ {j} → j ≥ i → P j<-weakInduction-startingFrom P {i} Pi Pᵢ⇒Pᵢ₊₁ {j} j≥i = induct (<-wellFounded _) (<-cmp i j) j≥iwhereinduct : ∀ {j} → Acc _<_ j → Tri (i < j) (i ≡ j) (i > j) → j ≥ i → P jinduct (acc rs) (tri≈ _ refl _) i≤j = Piinduct (acc rs) (tri> _ _ i>sj) i≤j with () ← ≤⇒≯ i≤j i>sjinduct {suc j} (acc rs) (tri< (s≤s i≤j) _ _) _ = Pᵢ⇒Pᵢ₊₁ j P[1+j]wheretoℕj≡toℕinjJ = sym $ toℕ-inject₁ jP[1+j] = induct (rs (s≤s (subst (ℕ._≤ toℕ j) toℕj≡toℕinjJ ≤-refl)))(<-cmp i $ inject₁ j) (subst (toℕ i ℕ.≤_) toℕj≡toℕinjJ i≤j)<-weakInduction : (P : Pred (Fin (suc n)) ℓ) →P zero →(∀ i → P (inject₁ i) → P (suc i)) →∀ i → P i<-weakInduction P P₀ Pᵢ⇒Pᵢ₊₁ i = <-weakInduction-startingFrom P P₀ Pᵢ⇒Pᵢ₊₁ ℕ.z≤n-------------------------------------------------------------------------- Induction over _>_privateacc-map : ∀ {x : Fin n} → Acc ℕ._<_ (n ∸ toℕ x) → Acc _>_ xacc-map (acc rs) = acc λ y>x → acc-map (rs (ℕ.∸-monoʳ-< y>x (toℕ≤n _)))>-wellFounded : WellFounded {A = Fin n} _>_>-wellFounded {n} x = acc-map (ℕ.<-wellFounded (n ∸ toℕ x))>-weakInduction : (P : Pred (Fin (suc n)) ℓ) →P (fromℕ n) →(∀ i → P (suc i) → P (inject₁ i)) →∀ i → P i>-weakInduction {n = n} P Pₙ Pᵢ₊₁⇒Pᵢ i = induct (>-wellFounded i)whereinduct : ∀ {i} → Acc _>_ i → P iinduct {i} (acc rec) with n ℕ.≟ toℕ i... | yes n≡i = subst P (toℕ-injective (trans (toℕ-fromℕ n) n≡i)) Pₙ... | no n≢i = subst P (inject₁-lower₁ i n≢i) (Pᵢ₊₁⇒Pᵢ _ Pᵢ₊₁)where Pᵢ₊₁ = induct (rec (ℕ.≤-reflexive (cong suc (sym (toℕ-lower₁ i n≢i)))))-------------------------------------------------------------------------- Well-foundedness of other (strict) partial orders on Finmodule _ {_≈_ : Rel (Fin n) ℓ} where-- Every (strict) partial order over `Fin n' is well-founded.-- Intuition: there cannot be any infinite descending chains simply-- because Fin n has only finitely many inhabitants. Thus any chain-- of length > n must have a cycle (which is forbidden by-- irreflexivity).spo-wellFounded : ∀ {r} {_⊏_ : Rel (Fin n) r} →IsStrictPartialOrder _≈_ _⊏_ → WellFounded _⊏_spo-wellFounded {_} {_⊏_} isSPO i = go n pigeon wheremodule ⊏ = IsStrictPartialOrder isSPOgo : ∀ m {i} →({xs : Vec (Fin n) m} → Linked (flip _⊏_) (i ∷ xs) → WellFounded _⊏_) →Acc _⊏_ igo zero k = k [-] _go (suc m) k = acc λ j⊏i → go m λ i∷xs↑ → k (j⊏i ∷ i∷xs↑)pigeon : {xs : Vec (Fin n) n} → Linked (flip _⊏_) (i ∷ xs) → WellFounded _⊏_pigeon {xs} i∷xs↑ =let (i₁ , i₂ , i₁<i₂ , xs[i₁]≡xs[i₂]) = pigeonhole (n<1+n n) (Vec.lookup (i ∷ xs)) inlet xs[i₁]⊏xs[i₂] = Linked.lookup⁺ (Ord.transitive _⊏_ ⊏.trans) i∷xs↑ i₁<i₂ inlet xs[i₁]⊏xs[i₁] = ⊏.<-respʳ-≈ (⊏.Eq.reflexive xs[i₁]≡xs[i₂]) xs[i₁]⊏xs[i₂] incontradiction xs[i₁]⊏xs[i₁] (⊏.irrefl ⊏.Eq.refl)po-wellFounded : ∀ {r} {_⊑_ : Rel (Fin n) r} →IsPartialOrder _≈_ _⊑_ → WellFounded (ToStrict._<_ _≈_ _⊑_)po-wellFounded isPO =spo-wellFounded (ToStrict.<-isStrictPartialOrder _≈_ _ isPO)-- The inverse order is also well-founded, i.e. every (strict)-- partial order is also Noetherian.spo-noetherian : ∀ {r} {_⊏_ : Rel (Fin n) r} →IsStrictPartialOrder _≈_ _⊏_ → WellFounded (flip _⊏_)spo-noetherian isSPO = spo-wellFounded (EqAndOrd.isStrictPartialOrder isSPO)po-noetherian : ∀ {r} {_⊑_ : Rel (Fin n) r} → IsPartialOrder _≈_ _⊑_ →WellFounded (flip (ToStrict._<_ _≈_ _⊑_))po-noetherian isPO =spo-noetherian (ToStrict.<-isStrictPartialOrder _≈_ _ isPO)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0≺-Rec : RecStruct ℕ ℓ ℓ≺-Rec = WfRec _≺_≺-wellFounded : WellFounded _≺_≺-wellFounded = Subrelation.wellFounded ≺⇒<′ ℕ.<′-wellFoundedmodule _ {ℓ} whereopen WF.All ≺-wellFounded ℓ publicrenaming( wfRecBuilder to ≺-recBuilder; wfRec to ≺-rec)hiding (wfRec-builder){-# WARNING_ON_USAGE ≺-Rec"Warning: ≺-Rec was deprecated in v2.0.Please use <-Rec instead."#-}{-# WARNING_ON_USAGE ≺-wellFounded"Warning: ≺-wellFounded was deprecated in v2.0.Please use <-wellFounded instead."#-}{-# WARNING_ON_USAGE ≺-recBuilder"Warning: ≺-recBuilder was deprecated in v2.0.Please use <-recBuilder instead."#-}{-# WARNING_ON_USAGE ≺-rec"Warning: ≺-rec was deprecated in v2.0.Please use <-rec instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Finite sets-------------------------------------------------------------------------- Note that elements of Fin n can be seen as natural numbers in the-- set {m | m < n}. The notation "m" in comments below refers to this-- natural number view.{-# OPTIONS --cubical-compatible --safe #-}module Data.Fin.Base whereopen import Data.Bool.Base using (Bool; T)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Data.Product.Base as Product using (_×_; _,_; proj₁; proj₂)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Function.Base using (id; _∘_; _on_; flip; _$_)open import Level using (0ℓ)open import Relation.Binary.Coreopen import Relation.Binary.PropositionalEquality.Core using (_≡_; _≢_; refl; cong)open import Relation.Binary.Indexed.Heterogeneous.Core using (IRel)open import Relation.Nullary.Negation.Core using (contradiction)privatevariablem n : ℕ-------------------------------------------------------------------------- Types-- Fin n is a type with n elements.data Fin : ℕ → Set wherezero : Fin (suc n)suc : (i : Fin n) → Fin (suc n)-- A conversion: toℕ "i" = i.toℕ : Fin n → ℕtoℕ zero = 0toℕ (suc i) = suc (toℕ i)-- A Fin-indexed variant of Fin.Fin′ : Fin n → SetFin′ i = Fin (toℕ i)-------------------------------------------------------------------------- A cast that actually computes on constructors (as opposed to subst)cast : .(m ≡ n) → Fin m → Fin ncast {zero} {zero} eq k = kcast {suc m} {suc n} eq zero = zerocast {suc m} {suc n} eq (suc k) = suc (cast (cong ℕ.pred eq) k)-------------------------------------------------------------------------- Conversions-- toℕ is defined above.-- fromℕ n = "n".fromℕ : (n : ℕ) → Fin (suc n)fromℕ zero = zerofromℕ (suc n) = suc (fromℕ n)-- fromℕ< {m} _ = "m".fromℕ< : .(m ℕ.< n) → Fin nfromℕ< {zero} {suc _} _ = zerofromℕ< {suc m} {suc _} m<n = suc (fromℕ< (ℕ.s<s⁻¹ m<n))-- fromℕ<″ m _ = "m".fromℕ<″ : ∀ m {n} → .(m ℕ.<″ n) → Fin nfromℕ<″ zero {suc _} _ = zerofromℕ<″ (suc m) {suc _} m<″n = suc (fromℕ<″ m (ℕ.s<″s⁻¹ m<″n))-- canonical liftings of i:Fin m to larger index-- injection on the left: "i" ↑ˡ n = "i" in Fin (m + n)infixl 5 _↑ˡ__↑ˡ_ : ∀ {m} → Fin m → ∀ n → Fin (m ℕ.+ n)zero ↑ˡ n = zero(suc i) ↑ˡ n = suc (i ↑ˡ n)-- injection on the right: n ↑ʳ "i" = "n + i" in Fin (n + m)infixr 5 _↑ʳ__↑ʳ_ : ∀ {m} n → Fin m → Fin (n ℕ.+ m)zero ↑ʳ i = i(suc n) ↑ʳ i = suc (n ↑ʳ i)-- reduce≥ "m + i" _ = "i".reduce≥ : ∀ (i : Fin (m ℕ.+ n)) → .(m ℕ.≤ toℕ i) → Fin nreduce≥ {zero} i _ = ireduce≥ {suc _} (suc i) m≤i = reduce≥ i (ℕ.s≤s⁻¹ m≤i)-- inject⋆ m "i" = "i".inject : ∀ {i : Fin n} → Fin′ i → Fin ninject {i = suc i} zero = zeroinject {i = suc i} (suc j) = suc (inject j)inject! : ∀ {i : Fin (suc n)} → Fin′ i → Fin ninject! {n = suc _} {i = suc _} zero = zeroinject! {n = suc _} {i = suc _} (suc j) = suc (inject! j)inject₁ : Fin n → Fin (suc n)inject₁ zero = zeroinject₁ (suc i) = suc (inject₁ i)inject≤ : Fin m → .(m ℕ.≤ n) → Fin ninject≤ {n = suc _} zero _ = zeroinject≤ {n = suc _} (suc i) m≤n = suc (inject≤ i (ℕ.s≤s⁻¹ m≤n))-- lower₁ "i" _ = "i".lower₁ : ∀ (i : Fin (suc n)) → n ≢ toℕ i → Fin nlower₁ {zero} zero ne = contradiction refl nelower₁ {suc n} zero _ = zerolower₁ {suc n} (suc i) ne = suc (lower₁ i (ne ∘ cong suc))-- A strengthening injection into the minimal Fin fibre.strengthen : ∀ (i : Fin n) → Fin′ (suc i)strengthen zero = zerostrengthen (suc i) = suc (strengthen i)-- splitAt m "i" = inj₁ "i" if i < m-- inj₂ "i - m" if i ≥ m-- This is dual to splitAt from Data.Vec.splitAt : ∀ m {n} → Fin (m ℕ.+ n) → Fin m ⊎ Fin nsplitAt zero i = inj₂ isplitAt (suc m) zero = inj₁ zerosplitAt (suc m) (suc i) = Sum.map₁ suc (splitAt m i)-- inverse of above functionjoin : ∀ m n → Fin m ⊎ Fin n → Fin (m ℕ.+ n)join m n = [ _↑ˡ n , m ↑ʳ_ ]′-- quotRem k "i" = "i % k" , "i / k"-- This is dual to group from Data.Vec.quotRem : ∀ n → Fin (m ℕ.* n) → Fin n × Fin mquotRem {suc m} n i =[ (_, zero), Product.map₂ suc ∘ quotRem {m} n]′ $ splitAt n i-- a variant of quotRem the type of whose result matches the order of multiplicationremQuot : ∀ n → Fin (m ℕ.* n) → Fin m × Fin nremQuot i = Product.swap ∘ quotRem iquotient : ∀ n → Fin (m ℕ.* n) → Fin mquotient n = proj₁ ∘ remQuot nremainder : ∀ n → Fin (m ℕ.* n) → Fin nremainder {m} n = proj₂ ∘ remQuot {m} n-- inverse of remQuotcombine : Fin m → Fin n → Fin (m ℕ.* n)combine {suc m} {n} zero j = j ↑ˡ (m ℕ.* n)combine {suc m} {n} (suc i) j = n ↑ʳ (combine i j)-- Next in progression after splitAt and remQuotfinToFun : Fin (m ℕ.^ n) → (Fin n → Fin m)finToFun {m} {suc n} i zero = quotient (m ℕ.^ n) ifinToFun {m} {suc n} i (suc j) = finToFun (remainder {m} (m ℕ.^ n) i) j-- inverse of above functionfunToFin : (Fin m → Fin n) → Fin (n ℕ.^ m)funToFin {zero} f = zerofunToFin {suc m} f = combine (f zero) (funToFin (f ∘ suc))-------------------------------------------------------------------------- Operations-- Folds.fold : ∀ {t} (T : ℕ → Set t) {m} →(∀ {n} → T n → T (suc n)) →(∀ {n} → T (suc n)) →Fin m → T mfold T f x zero = xfold T f x (suc i) = f (fold T f x i)fold′ : ∀ {n t} (T : Fin (suc n) → Set t) →(∀ i → T (inject₁ i) → T (suc i)) →T zero →∀ i → T ifold′ T f x zero = xfold′ {n = suc n} T f x (suc i) =f i (fold′ (T ∘ inject₁) (f ∘ inject₁) x i)-- Lifts functions.lift : ∀ k → (Fin m → Fin n) → Fin (k ℕ.+ m) → Fin (k ℕ.+ n)lift zero f i = f ilift (suc k) f zero = zerolift (suc k) f (suc i) = suc (lift k f i)-- "i" + "j" = "i + j".infixl 6 _+__+_ : ∀ (i : Fin m) (j : Fin n) → Fin (toℕ i ℕ.+ n)zero + j = jsuc i + j = suc (i + j)-- "i" - "j" = "i ∸ j".infixl 6 _-__-_ : ∀ (i : Fin n) (j : Fin′ (suc i)) → Fin (n ℕ.∸ toℕ j)i - zero = isuc i - suc j = i - j-- m ℕ- "i" = "m ∸ i".infixl 6 _ℕ-__ℕ-_ : (n : ℕ) (j : Fin (suc n)) → Fin (suc n ℕ.∸ toℕ j)n ℕ- zero = fromℕ nsuc n ℕ- suc i = n ℕ- i-- m ℕ-ℕ "i" = m ∸ i.infixl 6 _ℕ-ℕ__ℕ-ℕ_ : (n : ℕ) → Fin (suc n) → ℕn ℕ-ℕ zero = nsuc n ℕ-ℕ suc i = n ℕ-ℕ i-- pred "i" = "pred i".pred : Fin n → Fin npred zero = zeropred (suc i) = inject₁ i-- opposite "i" = "n - i" (i.e. the additive inverse).opposite : Fin n → Fin nopposite {suc n} zero = fromℕ nopposite {suc n} (suc i) = inject₁ (opposite i)-- The function f(i,j) = if j>i then j-1 else j-- This is a variant of the thick function from Conor-- McBride's "First-order unification by structural recursion".punchOut : ∀ {i j : Fin (suc n)} → i ≢ j → Fin npunchOut {_} {zero} {zero} i≢j = contradiction refl i≢jpunchOut {_} {zero} {suc j} _ = jpunchOut {suc _} {suc i} {zero} _ = zeropunchOut {suc _} {suc i} {suc j} i≢j = suc (punchOut (i≢j ∘ cong suc))-- The function f(i,j) = if j≥i then j+1 else jpunchIn : Fin (suc n) → Fin n → Fin (suc n)punchIn zero j = suc jpunchIn (suc i) zero = zeropunchIn (suc i) (suc j) = suc (punchIn i j)-- The function f(i,j) such that f(i,j) = if j≤i then j else j-1pinch : Fin n → Fin (suc n) → Fin npinch {suc n} _ zero = zeropinch {suc n} zero (suc j) = jpinch {suc n} (suc i) (suc j) = suc (pinch i j)-------------------------------------------------------------------------- Order relationsinfix 4 _≤_ _≥_ _<_ _>__≤_ : IRel Fin 0ℓi ≤ j = toℕ i ℕ.≤ toℕ j_≥_ : IRel Fin 0ℓi ≥ j = toℕ i ℕ.≥ toℕ j_<_ : IRel Fin 0ℓi < j = toℕ i ℕ.< toℕ j_>_ : IRel Fin 0ℓi > j = toℕ i ℕ.> toℕ j-------------------------------------------------------------------------- An ordering view.data Ordering {n : ℕ} : Fin n → Fin n → Set whereless : ∀ greatest (least : Fin′ greatest) →Ordering (inject least) greatestequal : ∀ i → Ordering i igreater : ∀ greatest (least : Fin′ greatest) →Ordering greatest (inject least)compare : ∀ (i j : Fin n) → Ordering i jcompare zero zero = equal zerocompare zero (suc j) = less (suc j) zerocompare (suc i) zero = greater (suc i) zerocompare (suc i) (suc j) with compare i j... | less greatest least = less (suc greatest) (suc least)... | greater greatest least = greater (suc greatest) (suc least)... | equal i = equal (suc i)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0raise = _↑ʳ_{-# WARNING_ON_USAGE raise"Warning: raise was deprecated in v2.0.Please use _↑ʳ_ instead."#-}inject+ : ∀ {m} n → Fin m → Fin (m ℕ.+ n)inject+ n i = i ↑ˡ n{-# WARNING_ON_USAGE inject+"Warning: inject+ was deprecated in v2.0.Please use _↑ˡ_ instead.NB argument order has been flipped:the left-hand argument is the Fin mthe right-hand is the Nat index increment."#-}data _≺_ : ℕ → ℕ → Set where_≻toℕ_ : ∀ n (i : Fin n) → toℕ i ≺ n{-# WARNING_ON_USAGE _≺_"Warning: _≺_ was deprecated in v2.0.Please use equivalent relation _<_ instead."#-}{-# WARNING_ON_USAGE _≻toℕ_"Warning: _≻toℕ_ was deprecated in v2.0.Please use toℕ<n from Data.Fin.Properties instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Erased where{-# WARNING_ON_IMPORT"Data.Erased was deprecated in v2.0.Use Data.Irrelevant instead."#-}open import Data.Irrelevant publicusing ([_]; map; pure; _<*>_; _>>=_; zipWith)renaming( Irrelevant to Erased; irrelevant to erased)
-------------------------------------------------------------------------- The Agda standard library---- Empty type, judgementally proof irrelevant, Level-monomorphic------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Empty whereopen import Data.Irrelevant using (Irrelevant)-------------------------------------------------------------------------- Definition-- Note that by default the empty type is not universe polymorphic as it-- often results in unsolved metas. See `Data.Empty.Polymorphic` for a-- universe polymorphic variant.privatedata Empty : Set where-- ⊥ is defined via Data.Irrelevant (a record with a single irrelevant-- field) so that Agda can judgementally declare that all proofs of ⊥-- are equal to each other. In particular this means that all functions-- returning a proof of ⊥ are equal.⊥ : Set⊥ = Irrelevant Empty{-# DISPLAY Irrelevant Empty = ⊥ #-}-------------------------------------------------------------------------- Functions⊥-elim : ∀ {w} {Whatever : Set w} → ⊥ → Whatever⊥-elim ()⊥-elim-irr : ∀ {w} {Whatever : Set w} → .⊥ → Whatever⊥-elim-irr ()
-------------------------------------------------------------------------- The Agda standard library---- Level polymorphic Empty type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Empty.Polymorphic whereimport Data.Empty as Emptyopen import Level⊥ : {ℓ : Level} → Set ℓ⊥ {ℓ} = Lift ℓ Empty.⊥-- make ⊥-elim dependent too, as it does seem useful⊥-elim : ∀ {w ℓ} {Whatever : ⊥ {ℓ} → Set w} → (witness : ⊥ {ℓ}) → Whatever witness⊥-elim ()
-------------------------------------------------------------------------- The Agda standard library---- An irrelevant version of ⊥-elim------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Empty.Irrelevant whereopen import Data.Empty hiding (⊥-elim)⊥-elim : ∀ {w} {Whatever : Set w} → .⊥ → Whatever⊥-elim ()
-------------------------------------------------------------------------- The Agda standard library---- Digits and digit expansions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Digit whereopen import Data.Nat.Baseusing (ℕ; zero; suc; _<_; _/_; _%_; sz<ss; _+_; _*_; 2+; _≤′_)open import Data.Nat.Propertiesusing (_≤?_; _<?_; ≤⇒≤′; module ≤-Reasoning; m≤m+n; +-comm; +-assoc;*-distribˡ-+; *-identityʳ)open import Data.Fin.Base as Fin using (Fin; zero; suc; toℕ)open import Data.Bool.Base using (Bool; true; false)open import Data.Char.Base using (Char)open import Data.List.Base using (List; replicate; [_]; _∷_; [])open import Data.Product.Base using (∃; _,_)open import Data.Vec.Base as Vec using (Vec; _∷_; [])open import Data.Nat.DivMod using (m/n<m; _divMod_; result)open import Data.Nat.Inductionusing (Acc; acc; <-wellFounded-fast; <′-Rec; <′-rec)open import Function.Base using (_$_)open import Relation.Nullary.Decidable using (True; does; toWitness)open import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; cong₂; module ≡-Reasoning)-------------------------------------------------------------------------- Digits-- Digit b is the type of digits in base b.Digit : ℕ → SetDigit b = Fin b-- Some specific digit kinds.Decimal = Digit 10Bit = Digit 2-- Some named digits.0b : Bit0b = zero1b : Bit1b = suc zero-------------------------------------------------------------------------- Converting between `ℕ` and `expansions of ℕ`toNatDigits : (base : ℕ) {base≤16 : True (1 ≤? base)} → ℕ → List ℕtoNatDigits base@(suc zero) n = replicate n 1toNatDigits base@(suc (suc _)) n = aux (<-wellFounded-fast n) []whereaux : {n : ℕ} → Acc _<_ n → List ℕ → List ℕaux {zero} _ xs = (0 ∷ xs)aux {n@(suc _)} (acc wf) xs with does (0 <? n / base)... | false = (n % base) ∷ xs -- Could this more simply be n ∷ xs here?... | true = aux (wf (m/n<m n base sz<ss)) ((n % base) ∷ xs)-------------------------------------------------------------------------- Converting between `ℕ` and expansions of `Digit base`Expansion : ℕ → SetExpansion base = List (Digit base)-- fromDigits takes a digit expansion of a natural number, starting-- with the _least_ significant digit, and returns the corresponding-- natural number.fromDigits : ∀ {base} → Expansion base → ℕfromDigits [] = 0fromDigits {base} (d ∷ ds) = toℕ d + fromDigits ds * base-- toDigits b n yields the digits of n, in base b, starting with the-- _least_ significant digit.---- Note that the list of digits is always non-empty.toDigits : (base : ℕ) {base≥2 : True (2 ≤? base)} (n : ℕ) →∃ λ (ds : Expansion base) → fromDigits ds ≡ ntoDigits base@(suc (suc k)) n = <′-rec Pred helper nwherePred = λ n → ∃ λ ds → fromDigits ds ≡ ncons : ∀ {m} (r : Digit base) → Pred m → Pred (toℕ r + m * base)cons r (ds , eq) = (r ∷ ds , cong (λ i → toℕ r + i * base) eq)lem′ : ∀ x k → x + x + (k + x * k) ≡ k + x * 2+ klem′ x k = beginx + x + (k + x * k) ≡⟨ +-assoc (x + x) k _ ⟨x + x + k + x * k ≡⟨ cong (_+ x * k) (+-comm _ k) ⟩k + (x + x) + x * k ≡⟨ +-assoc k (x + x) _ ⟩k + ((x + x) + x * k) ≡⟨ cong (k +_) (begin(x + x) + x * k ≡⟨ +-assoc x x _ ⟩x + (x + x * k) ≡⟨ cong (x +_) (cong (_+ x * k) (*-identityʳ x)) ⟨x + (x * 1 + x * k) ≡⟨ cong₂ _+_ (*-identityʳ x) (*-distribˡ-+ x 1 k ) ⟨x * 1 + (x * suc k) ≡⟨ *-distribˡ-+ x 1 (1 + k) ⟨x * 2+ k ∎) ⟩k + x * 2+ k ∎where open ≡-Reasoninglem : ∀ x k r → 2 + x ≤′ r + (1 + x) * (2 + k)lem x k r = ≤⇒≤′ $ begin2 + x ≤⟨ m≤m+n _ _ ⟩2 + x + (x + (1 + x) * k + r) ≡⟨ cong ((2 + x) +_) (+-comm _ r) ⟩2 + x + (r + (x + (1 + x) * k)) ≡⟨ +-assoc (2 + x) r _ ⟨2 + x + r + (x + (1 + x) * k) ≡⟨ cong (_+ (x + (1 + x) * k)) (+-comm (2 + x) r) ⟩r + (2 + x) + (x + (1 + x) * k) ≡⟨ +-assoc r (2 + x) _ ⟩r + ((2 + x) + (x + (1 + x) * k)) ≡⟨ cong (r +_) (cong 2+ (+-assoc x x _)) ⟨r + (2 + (x + x + (1 + x) * k)) ≡⟨ cong (λ z → r + (2+ z)) (lem′ x k) ⟩r + (2 + (k + x * (2 + k))) ≡⟨⟩r + (1 + x) * (2 + k) ∎where open ≤-Reasoninghelper : ∀ n → <′-Rec Pred n → Pred nhelper n rec with n divMod base... | result zero r eq = ([ r ] , sym eq)... | result (suc x) r refl = cons r (rec (lem x k (toℕ r)))-------------------------------------------------------------------------- Showing digits-- The characters used to show the first 16 digits.digitChars : Vec Char 16digitChars ='0' ∷ '1' ∷ '2' ∷ '3' ∷ '4' ∷ '5' ∷ '6' ∷ '7' ∷ '8' ∷ '9' ∷'a' ∷ 'b' ∷ 'c' ∷ 'd' ∷ 'e' ∷ 'f' ∷ []-- showDigit shows digits in base ≤ 16.showDigit : ∀ {base} {base≤16 : True (base ≤? 16)} → Digit base → CharshowDigit {base≤16 = base≤16} d =Vec.lookup digitChars (Fin.inject≤ d (toWitness base≤16))
-------------------------------------------------------------------------- The Agda standard library---- Properties of digits and digit expansions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Digitimport Data.Char.Properties as Charopen import Data.Nat.Base using (ℕ)open import Data.Nat.Properties using (_≤?_)open import Data.Fin.Properties using (inject≤-injective)open import Data.Product.Base using (_,_; proj₁)open import Data.Vec.Relation.Unary.Unique.Propositional using (Unique)import Data.Vec.Relation.Unary.Unique.Propositional.Properties as Uniqueopen import Data.Vec.Relation.Unary.AllPairs using (allPairs?)open import Relation.Nullary.Decidable.Core using (True; from-yes; ¬?)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Function.Base using (_∘_)module Data.Digit.Properties wheredigitCharsUnique : Unique digitCharsdigitCharsUnique = from-yes (allPairs? (λ x y → ¬? (x Char.≟ y)) digitChars)module _ (base : ℕ) wheremodule _ {base≥2 base≥2′ : True (2 ≤? base)} wheretoDigits-injective : ∀ n m → proj₁ (toDigits base {base≥2} n) ≡ proj₁ (toDigits base {base≥2′} m) → n ≡ mtoDigits-injective n m eq with toDigits base {base≥2} n | toDigits base {base≥2′} mtoDigits-injective ._ ._ refl | _ , refl | ._ , refl = reflmodule _ {base≤16 base≤16′ : True (base ≤? 16)} whereshowDigit-injective : (n m : Digit base) → showDigit {base} {base≤16} n ≡ showDigit {base} {base≤16′} m → n ≡ mshowDigit-injective n m = inject≤-injective _ _ n m ∘ Unique.lookup-injective digitCharsUnique _ _
-------------------------------------------------------------------------- The Agda standard library---- Vectors with fast append------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.DifferenceVec whereopen import Data.DifferenceNatopen import Data.Vec.Base as Vec using (Vec)open import Function.Base using (_⟨_⟩_)import Data.Nat.Base as ℕinfixr 5 _∷_ _++_DiffVec : ∀ {ℓ} → Set ℓ → Diffℕ → Set ℓDiffVec A m = ∀ {n} → Vec A n → Vec A (m n)[] : ∀ {a} {A : Set a} → DiffVec A 0#[] = λ k → k_∷_ : ∀ {a} {A : Set a} {n} → A → DiffVec A n → DiffVec A (suc n)x ∷ xs = λ k → Vec._∷_ x (xs k)[_] : ∀ {a} {A : Set a} → A → DiffVec A 1#[ x ] = x ∷ []_++_ : ∀ {a} {A : Set a} {m n} →DiffVec A m → DiffVec A n → DiffVec A (m + n)xs ++ ys = λ k → xs (ys k)toVec : ∀ {a} {A : Set a} {n} → DiffVec A n → Vec A (toℕ n)toVec xs = xs Vec.[]-- fromVec xs is linear in the length of xs.fromVec : ∀ {a} {A : Set a} {n} → Vec A n → DiffVec A (fromℕ n)fromVec xs = λ k → xs ⟨ Vec._++_ ⟩ khead : ∀ {a} {A : Set a} {n} → DiffVec A (suc n) → Ahead xs = Vec.head (toVec xs)tail : ∀ {a} {A : Set a} {n} → DiffVec A (suc n) → DiffVec A ntail xs = λ k → Vec.tail (xs k)take : ∀ {a} {A : Set a} m {n} →DiffVec A (fromℕ m + n) → DiffVec A (fromℕ m)take ℕ.zero xs = []take (ℕ.suc m) xs = head xs ∷ take m (tail xs)drop : ∀ {a} {A : Set a} m {n} →DiffVec A (fromℕ m + n) → DiffVec A ndrop ℕ.zero xs = xsdrop (ℕ.suc m) xs = drop m (tail xs)
-------------------------------------------------------------------------- The Agda standard library---- Natural numbers with fast addition (for use together with-- DifferenceVec)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.DifferenceNat whereopen import Data.Nat.Base as ℕ using (ℕ)open import Function.Base using (_⟨_⟩_)infixl 6 _+_Diffℕ : SetDiffℕ = ℕ → ℕ0# : Diffℕ0# = λ k → ksuc : Diffℕ → Diffℕsuc n = λ k → ℕ.suc (n k)1# : Diffℕ1# = suc 0#_+_ : Diffℕ → Diffℕ → Diffℕm + n = λ k → m (n k)toℕ : Diffℕ → ℕtoℕ n = n 0-- fromℕ n is linear in the size of n.fromℕ : ℕ → Diffℕfromℕ n = λ k → n ⟨ ℕ._+_ ⟩ k
-------------------------------------------------------------------------- The Agda standard library---- Lists with fast append------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.DifferenceList whereopen import Level using (Level)open import Data.List.Base as List using (List)open import Function.Base using (_⟨_⟩_)open import Data.Nat.Baseprivatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Type definition and list function liftingDiffList : Set a → Set aDiffList A = List A → List Alift : (List A → List A) → (DiffList A → DiffList A)lift f xs = λ k → f (xs k)-------------------------------------------------------------------------- Building difference listsinfixr 5 _∷_ _++_[] : DiffList A[] = λ k → k_∷_ : A → DiffList A → DiffList A_∷_ x = lift (x List.∷_)[_] : A → DiffList A[ x ] = x ∷ []_++_ : DiffList A → DiffList A → DiffList Axs ++ ys = λ k → xs (ys k)infixl 6 _∷ʳ__∷ʳ_ : DiffList A → A → DiffList Axs ∷ʳ x = λ k → xs (x List.∷ k)-------------------------------------------------------------------------- Conversion back and forth with ListtoList : DiffList A → List AtoList xs = xs List.[]-- fromList xs is linear in the length of xs.fromList : List A → DiffList AfromList xs = λ k → xs ⟨ List._++_ ⟩ k-------------------------------------------------------------------------- Transforming difference lists-- It is OK to use List._++_ here, since map is linear in the length of-- the list anyway.map : (A → B) → DiffList A → DiffList Bmap f xs = λ k → List.map f (toList xs) ⟨ List._++_ ⟩ k-- concat is linear in the length of the outer list.concat : DiffList (DiffList A) → DiffList Aconcat xs = concat′ (toList xs)whereconcat′ : List (DiffList A) → DiffList Aconcat′ = List.foldr _++_ []take : ℕ → DiffList A → DiffList Atake n = lift (List.take n)drop : ℕ → DiffList A → DiffList Adrop n = lift (List.drop n)
-------------------------------------------------------------------------- The Agda standard library---- A way to specify that a function's argument takes a default value-- if the argument is not passed explicitly.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Default where-- An argument of type `WithDefault {a} {A} x` is an argument of type-- `A` that happens to default to `x` if no other value is specified-- (as long as the `default` instance is in scope)infixl 0 _!record WithDefault {a} {A : Set a} (x : A) : Set a whereconstructor _!field value : Aopen WithDefault publicinstancedefault : ∀ {a} {A : Set a} {x : A} → WithDefault xdefault {x = x} .value = x-- See README.Data.Default for an example
-------------------------------------------------------------------------- The Agda standard library---- Containers, based on the work of Abbott and others------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level; _⊔_)open import Data.W using (W)module Data.Container where-------------------------------------------------------------------------- Re-exporting content to maintain backwards compatibilityopen import Data.Container.Core publicopen import Data.Container.Relation.Unary.Anyusing (◇) renaming (map to ◇-map) publicopen import Data.Container.Relation.Unary.Allusing (□) renaming (map to □-map) publicopen import Data.Container.Membershipusing (_∈_) publicopen import Data.Container.Relation.Binary.Pointwiseusing () renaming (Pointwise to Eq) publicopen import Data.Container.Relation.Binary.Pointwise.Propertiesusing (refl; sym; trans) publicopen import Data.Container.Relation.Binary.Equality.Setoidusing (isEquivalence; setoid) publicopen import Data.Container.Propertiesusing () renaming (map-identity to identity; map-compose to composition) publicopen import Data.Container.Related publicmodule Morphism whereopen import Data.Container.Morphism.Propertiesusing (Natural; NT; natural; complete; id-correct; ∘-correct) publicopen import Data.Container.Morphismusing (id; _∘_) publicprivatevariables p : Level-- The least fixpoint of a container.μ : Container s p → Set (s ⊔ p)μ = W-- The greatest fixpoint of a container can be found-- in `Data.Container.Fixpoints.Guarded` as it relies-- on the `guardedness` flag.-- You can find sized alternatives in `Data.Container.Fixpoints.Sized`-- as they rely on the unsafe flag `--sized-types`.
-------------------------------------------------------------------------- The Agda standard library---- Any (◇) for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Relation.Unary.Any whereopen import Level using (_⊔_)open import Relation.Unary using (Pred; _⊆_)open import Data.Product.Base using (_,_; proj₂; ∃)open import Function.Base using (_∘′_; id)open import Data.Container.Core hiding (map)import Data.Container.Morphism as Mrecord ◇ {s p} (C : Container s p) {x ℓ} {X : Set x}(P : Pred X ℓ) (cx : ⟦ C ⟧ X) : Set (p ⊔ ℓ) whereconstructor anyfield proof : ∃ λ p → P (proj₂ cx p)module _ {s₁ p₁ s₂ p₂} {C : Container s₁ p₁} {D : Container s₂ p₂}{x ℓ ℓ′} {X : Set x} {P : Pred X ℓ} {Q : Pred X ℓ′}wheremap : (f : C ⇒ D) → P ⊆ Q → ◇ D P ∘′ ⟪ f ⟫ ⊆ ◇ C Qmap f P⊆Q (any (p , P)) .◇.proof = f .position p , P⊆Q Pmodule _ {s₁ p₁ s₂ p₂} {C : Container s₁ p₁} {D : Container s₂ p₂}{x ℓ} {X : Set x} {P : Pred X ℓ}wheremap₁ : (f : C ⇒ D) → ◇ D P ∘′ ⟪ f ⟫ ⊆ ◇ C Pmap₁ f = map f idmodule _ {s p} {C : Container s p}{x ℓ ℓ′} {X : Set x} {P : Pred X ℓ} {Q : Pred X ℓ′}wheremap₂ : P ⊆ Q → ◇ C P ⊆ ◇ C Qmap₂ = map (M.id C)
-------------------------------------------------------------------------- The Agda standard library---- Propertiers of any for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Relation.Unary.Any.Properties whereopen import Algebra.Bundles using (CommutativeSemiring)open import Data.Product.Base using (∃; _×_; ∃₂; _,_; proj₂)open import Data.Product.Properties using (Σ-≡,≡→≡)open import Data.Product.Function.NonDependent.Propositional using (_×-cong_)import Data.Product.Function.Dependent.Propositional as Σopen import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Function.Base using (_∘_; _∘′_; id; flip; _$_)open import Function.Bundles using (_↔_; mk↔ₛ′; Inverse)open import Function.Properties.Inverse using (↔-refl)open import Function.Properties.Inverse.HalfAdjointEquivalence using (_≃_; ↔⇒≃)open import Function.Related.Propositional as Related using (Related; SK-sym)open import Function.Related.TypeIsomorphismsusing (×-⊎-commutativeSemiring; ∃∃↔∃∃; Σ-assoc; ×-comm)open import Level using (Level; _⊔_)open import Relation.Unary using (Pred ; _∪_ ; _∩_)open import Relation.Binary.Core using (REL)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≗_; refl)open import Relation.Binary.PropositionalEquality.Properties as ≡privatemodule ×⊎ {k ℓ} = CommutativeSemiring (×-⊎-commutativeSemiring k ℓ)open import Data.Container.Coreimport Data.Container.Combinator as Copen import Data.Container.Combinator.Propertiesopen import Data.Container.Relatedopen import Data.Container.Relation.Unary.Any as Any using (◇; any)open import Data.Container.Membershipmodule _ {s p} (C : Container s p) {x} {X : Set x} {ℓ} {P : Pred X ℓ} where-- ◇ can be unwrapped to reveal the Σ type↔Σ : ∀ {xs : ⟦ C ⟧ X} → ◇ C P xs ↔ ∃ λ p → P (proj₂ xs p)↔Σ {xs} = mk↔ₛ′ ◇.proof any (λ _ → refl) (λ _ → refl)-- ◇ can be expressed using _∈_.↔∈ : ∀ {xs : ⟦ C ⟧ X} → ◇ C P xs ↔ (∃ λ x → x ∈ xs × P x)↔∈ {xs} = mk↔ₛ′ to from to∘from (λ _ → refl) whereto : ◇ C P xs → ∃ λ x → x ∈ xs × P xto (any (p , Px)) = (proj₂ xs p , (any (p , refl)) , Px)from : (∃ λ x → x ∈ xs × P x) → ◇ C P xsfrom (.(proj₂ xs p) , (any (p , refl)) , Px) = any (p , Px)to∘from : to ∘ from ≗ idto∘from (.(proj₂ xs p) , any (p , refl) , Px) = reflmodule _ {s p} {C : Container s p} {x} {X : Set x}{ℓ₁ ℓ₂} {P₁ : Pred X ℓ₁} {P₂ : Pred X ℓ₂} where-- ◇ is a congruence for bag and set equality and related preorders.cong : ∀ {k} {xs₁ xs₂ : ⟦ C ⟧ X} →(∀ x → Related k (P₁ x) (P₂ x)) → xs₁ ≲[ k ] xs₂ →Related k (◇ C P₁ xs₁) (◇ C P₂ xs₂)cong {k} {xs₁} {xs₂} P₁↔P₂ xs₁≈xs₂ =◇ C P₁ xs₁ ↔⟨ ↔∈ C ⟩(∃ λ x → x ∈ xs₁ × P₁ x) ∼⟨ Σ.cong ↔-refl (xs₁≈xs₂ ×-cong P₁↔P₂ _) ⟩(∃ λ x → x ∈ xs₂ × P₂ x) ↔⟨ SK-sym (↔∈ C) ⟩◇ C P₂ xs₂ ∎where open Related.EquationalReasoning-- Nested occurrences of ◇ can sometimes be swapped.module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}{x y} {X : Set x} {Y : Set y} {r} {P : REL X Y r} whereswap : {xs : ⟦ C₁ ⟧ X} {ys : ⟦ C₂ ⟧ Y} →let ◈ : ∀ {s p} {C : Container s p} {x} {X : Set x} {ℓ} → ⟦ C ⟧ X → Pred X ℓ → Set (p ⊔ ℓ)◈ = λ {_} {_} → flip (◇ _) in◈ xs (◈ ys ∘ P) ↔ ◈ ys (◈ xs ∘ flip P)swap {xs} {ys} =◇ _ (λ x → ◇ _ (P x) ys) xs ↔⟨ ↔∈ C₁ ⟩(∃ λ x → x ∈ xs × ◇ _ (P x) ys) ↔⟨ Σ.cong ↔-refl $ Σ.cong ↔-refl $ ↔∈ C₂ ⟩(∃ λ x → x ∈ xs × ∃ λ y → y ∈ ys × P x y) ↔⟨ Σ.cong ↔-refl (λ {x} → ∃∃↔∃∃ (λ _ y → y ∈ ys × P x y)) ⟩(∃₂ λ x y → x ∈ xs × y ∈ ys × P x y) ↔⟨ ∃∃↔∃∃ (λ x y → x ∈ xs × y ∈ ys × P x y) ⟩(∃₂ λ y x → x ∈ xs × y ∈ ys × P x y) ↔⟨ Σ.cong ↔-refl (λ {y} → Σ.cong ↔-refl (λ {x} →(x ∈ xs × y ∈ ys × P x y) ↔⟨ SK-sym Σ-assoc ⟩((x ∈ xs × y ∈ ys) × P x y) ↔⟨ Σ.cong (×-comm _ _) ↔-refl ⟩((y ∈ ys × x ∈ xs) × P x y) ↔⟨ Σ-assoc ⟩(y ∈ ys × x ∈ xs × P x y) ∎)) ⟩(∃₂ λ y x → y ∈ ys × x ∈ xs × P x y) ↔⟨ Σ.cong ↔-refl (λ {y} → ∃∃↔∃∃ {B = y ∈ ys} (λ x _ → x ∈ xs × P x y)) ⟩(∃ λ y → y ∈ ys × ∃ λ x → x ∈ xs × P x y) ↔⟨ Σ.cong ↔-refl (Σ.cong ↔-refl (SK-sym (↔∈ C₁))) ⟩(∃ λ y → y ∈ ys × ◇ _ (flip P y) xs) ↔⟨ SK-sym (↔∈ C₂) ⟩◇ _ (λ y → ◇ _ (flip P y) xs) ys ∎where open Related.EquationalReasoning-- Nested occurrences of ◇ can sometimes be flattened.module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}{x} {X : Set x} {ℓ} (P : Pred X ℓ) whereflatten : ∀ (xss : ⟦ C₁ ⟧ (⟦ C₂ ⟧ X)) →◇ C₁ (◇ C₂ P) xss ↔◇ (C₁ C.∘ C₂) P (Inverse.from (Composition.correct C₁ C₂) xss)flatten xss = mk↔ₛ′ t f (λ _ → refl) (λ _ → refl) where◇₁ = ◇ C₁; ◇₂ = ◇ C₂; ◇₁₂ = ◇ (C₁ C.∘ C₂)open Inverset : ◇₁ (◇₂ P) xss → ◇₁₂ P (from (Composition.correct C₁ C₂) xss)t (any (p₁ , (any (p₂ , p)))) = any (any (p₁ , p₂) , p)f : ◇₁₂ P (from (Composition.correct C₁ C₂) xss) → ◇₁ (◇₂ P) xssf (any (any (p₁ , p₂) , p)) = any (p₁ , any (p₂ , p))-- Sums commute with ◇ (for a fixed instance of a given container).module _ {s p} {C : Container s p} {x} {X : Set x}{ℓ ℓ′} {P : Pred X ℓ} {Q : Pred X ℓ′} where◇⊎↔⊎◇ : ∀ {xs : ⟦ C ⟧ X} → ◇ C (P ∪ Q) xs ↔ (◇ C P xs ⊎ ◇ C Q xs)◇⊎↔⊎◇ {xs} = mk↔ₛ′ to from to∘from from∘towhereto : ◇ C (λ x → P x ⊎ Q x) xs → ◇ C P xs ⊎ ◇ C Q xsto (any (pos , inj₁ p)) = inj₁ (any (pos , p))to (any (pos , inj₂ q)) = inj₂ (any (pos , q))from : ◇ C P xs ⊎ ◇ C Q xs → ◇ C (λ x → P x ⊎ Q x) xsfrom = [ Any.map₂ inj₁ , Any.map₂ inj₂ ]from∘to : from ∘ to ≗ idfrom∘to (any (pos , inj₁ p)) = reflfrom∘to (any (pos , inj₂ q)) = reflto∘from : to ∘ from ≗ idto∘from = [ (λ _ → refl) , (λ _ → refl) ]-- Products "commute" with ◇.module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}{x y} {X : Set x} {Y : Set y} {ℓ ℓ′} {P : Pred X ℓ} {Q : Pred Y ℓ′} where×◇↔◇◇× : ∀ {xs : ⟦ C₁ ⟧ X} {ys : ⟦ C₂ ⟧ Y} →◇ C₁ (λ x → ◇ C₂ (λ y → P x × Q y) ys) xs ↔ (◇ C₁ P xs × ◇ C₂ Q ys)×◇↔◇◇× {xs} {ys} = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)where◇₁ = ◇ C₁; ◇₂ = ◇ C₂to : ◇₁ (λ x → ◇₂ (λ y → P x × Q y) ys) xs → ◇₁ P xs × ◇₂ Q ysto (any (p₁ , any (p₂ , p , q))) = (any (p₁ , p) , any (p₂ , q))from : ◇₁ P xs × ◇₂ Q ys → ◇₁ (λ x → ◇₂ (λ y → P x × Q y) ys) xsfrom (any (p₁ , p) , any (p₂ , q)) = any (p₁ , any (p₂ , p , q))-- map can be absorbed by the predicate.module _ {s p} (C : Container s p) {x y} {X : Set x} {Y : Set y}{ℓ} (P : Pred Y ℓ) wheremap↔∘ : ∀ {xs : ⟦ C ⟧ X} (f : X → Y) → ◇ C P (map f xs) ↔ ◇ C (P ∘′ f) xsmap↔∘ {xs} f =◇ C P (map f xs) ↔⟨ ↔Σ C ⟩∃ (P ∘′ proj₂ (map f xs)) ≡⟨⟩∃ (P ∘′ f ∘′ proj₂ xs) ↔⟨ SK-sym (↔Σ C) ⟩◇ C (P ∘′ f) xs ∎where open Related.EquationalReasoning-- Membership in a mapped container can be expressed without reference-- to map.module _ {s p} (C : Container s p) {x y} {X : Set x} {Y : Set y}{ℓ} (P : Pred Y ℓ) where∈map↔∈×≡ : ∀ {f : X → Y} {xs : ⟦ C ⟧ X} {y} →y ∈ map f xs ↔ (∃ λ x → x ∈ xs × y ≡ f x)∈map↔∈×≡ {f = f} {xs} {y} =y ∈ map f xs ↔⟨ map↔∘ C (y ≡_) f ⟩◇ C (λ x → y ≡ f x) xs ↔⟨ ↔∈ C ⟩∃ (λ x → x ∈ xs × y ≡ f x) ∎where open Related.EquationalReasoning-- map is a congruence for bag and set equality and related preorders.module _ {s p} (C : Container s p) {x y} {X : Set x} {Y : Set y}{ℓ} (P : Pred Y ℓ) wheremap-cong : ∀ {k} {f₁ f₂ : X → Y} {xs₁ xs₂ : ⟦ C ⟧ X} →f₁ ≗ f₂ → xs₁ ≲[ k ] xs₂ →map f₁ xs₁ ≲[ k ] map f₂ xs₂map-cong {f₁ = f₁} {f₂} {xs₁} {xs₂} f₁≗f₂ xs₁≈xs₂ {x} =x ∈ map f₁ xs₁ ↔⟨ map↔∘ C (_≡_ x) f₁ ⟩◇ C (λ y → x ≡ f₁ y) xs₁ ∼⟨ cong (Related.↔⇒ ∘ helper) xs₁≈xs₂ ⟩◇ C (λ y → x ≡ f₂ y) xs₂ ↔⟨ SK-sym (map↔∘ C (_≡_ x) f₂) ⟩x ∈ map f₂ xs₂ ∎whereopen Related.EquationalReasoninghelper : ∀ y → (x ≡ f₁ y) ↔ (x ≡ f₂ y)helper y rewrite f₁≗f₂ y = ↔-refl-- Uses of linear morphisms can be removed.module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}{x} {X : Set x} {ℓ} (P : Pred X ℓ) whereremove-linear : ∀ {xs : ⟦ C₁ ⟧ X} (m : C₁ ⊸ C₂) → ◇ C₂ P (⟪ m ⟫⊸ xs) ↔ ◇ C₁ P xsremove-linear {xs} m = mk↔ₛ′ t f t∘f f∘twhereopen _≃_open ≡.≡-Reasoningposition⊸m : ∀ {s} → Position C₂ (shape⊸ m s) ≃ Position C₁ sposition⊸m = ↔⇒≃ (position⊸ m)◇₁ = ◇ C₁; ◇₂ = ◇ C₂t : ◇₂ P (⟪ m ⟫⊸ xs) → ◇₁ P xst = Any.map₁ (_⊸_.morphism m)f : ◇₁ P xs → ◇₂ P (⟪ m ⟫⊸ xs)f (any (x , p)) =any $ from position⊸m x, ≡.subst (P ∘′ proj₂ xs) (≡.sym (right-inverse-of position⊸m _)) pf∘t : f ∘ t ≗ idf∘t (any (p₂ , p)) = ≡.cong any $ Σ-≡,≡→≡( left-inverse-of position⊸m p₂, (≡.subst (P ∘ proj₂ xs ∘ to position⊸m)(left-inverse-of position⊸m p₂)(≡.subst (P ∘ proj₂ xs)(≡.sym (right-inverse-of position⊸m(to position⊸m p₂)))p) ≡⟨ ≡.subst-∘ (left-inverse-of position⊸m _) ⟩≡.subst (P ∘ proj₂ xs)(≡.cong (to position⊸m)(left-inverse-of position⊸m p₂))(≡.subst (P ∘ proj₂ xs)(≡.sym (right-inverse-of position⊸m(to position⊸m p₂)))p) ≡⟨ ≡.cong (λ eq → ≡.subst (P ∘ proj₂ xs) eq(≡.subst (P ∘ proj₂ xs)(≡.sym (right-inverse-of position⊸m _)) _))(_≃_.left-right position⊸m _) ⟩≡.subst (P ∘ proj₂ xs)(right-inverse-of position⊸m(to position⊸m p₂))(≡.subst (P ∘ proj₂ xs)(≡.sym (right-inverse-of position⊸m(to position⊸m p₂)))p) ≡⟨ ≡.subst-subst (≡.sym (right-inverse-of position⊸m _)) ⟩≡.subst (P ∘ proj₂ xs)(≡.trans(≡.sym (right-inverse-of position⊸m(to position⊸m p₂)))(right-inverse-of position⊸m(to position⊸m p₂)))p ≡⟨ ≡.cong (λ eq → ≡.subst (P ∘ proj₂ xs) eq p)(≡.trans-symˡ (right-inverse-of position⊸m _)) ⟩≡.subst (P ∘ proj₂ xs) ≡.refl p ≡⟨⟩p ∎))t∘f : t ∘ f ≗ idt∘f (any (p₁ , p)) = ≡.cong any $ Σ-≡,≡→≡( right-inverse-of position⊸m p₁, (≡.subst (P ∘ proj₂ xs)(right-inverse-of position⊸m p₁)(≡.subst (P ∘ proj₂ xs)(≡.sym (right-inverse-of position⊸m p₁))p) ≡⟨ ≡.subst-subst (≡.sym (right-inverse-of position⊸m _)) ⟩≡.subst (P ∘ proj₂ xs)(≡.trans(≡.sym (right-inverse-of position⊸m p₁))(right-inverse-of position⊸m p₁))p ≡⟨ ≡.cong (λ eq → ≡.subst (P ∘ proj₂ xs) eq p)(≡.trans-symˡ (right-inverse-of position⊸m _)) ⟩≡.subst (P ∘ proj₂ xs) ≡.refl p ≡⟨⟩p ∎))-- Linear endomorphisms are identity functions if bag equality is used.module _ {s p} {C : Container s p} {x} {X : Set x} wherelinear-identity : ∀ {xs : ⟦ C ⟧ X} (m : C ⊸ C) → ⟪ m ⟫⊸ xs ≲[ bag ] xslinear-identity {xs} m {x} =x ∈ ⟪ m ⟫⊸ xs ↔⟨ remove-linear (_≡_ x) m ⟩x ∈ xs ∎where open Related.EquationalReasoning-- If join can be expressed using a linear morphism (in a certain-- way), then it can be absorbed by the predicate.module _ {s₁ s₂ s₃ p₁ p₂ p₃}{C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} {C₃ : Container s₃ p₃}{x} {X : Set x} {ℓ} (P : Pred X ℓ) wherejoin↔◇ : (join′ : (C₁ C.∘ C₂) ⊸ C₃) (xss : ⟦ C₁ ⟧ (⟦ C₂ ⟧ X)) →let join : ∀ {X} → ⟦ C₁ ⟧ (⟦ C₂ ⟧ X) → ⟦ C₃ ⟧ Xjoin = λ {_} → ⟪ join′ ⟫⊸ ∘(Inverse.from (Composition.correct C₁ C₂)) in◇ C₃ P (join xss) ↔ ◇ C₁ (◇ C₂ P) xssjoin↔◇ join xss =◇ C₃ P (⟪ join ⟫⊸ xss′) ↔⟨ remove-linear P join ⟩◇ (C₁ C.∘ C₂) P xss′ ↔⟨ SK-sym $ flatten P xss ⟩◇ C₁ (◇ C₂ P) xss ∎whereopen Related.EquationalReasoningxss′ = Inverse.from (Composition.correct C₁ C₂) xss
-------------------------------------------------------------------------- The Agda standard library---- All (□) for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Relation.Unary.All whereopen import Level using (_⊔_)open import Relation.Unary using (Pred; _⊆_)open import Data.Product.Base using (_,_; proj₁; proj₂; ∃)open import Function.Base using (_∘′_; id)open import Data.Container.Core hiding (map)import Data.Container.Morphism as Mrecord □ {s p} (C : Container s p) {x ℓ} {X : Set x}(P : Pred X ℓ) (cx : ⟦ C ⟧ X) : Set (p ⊔ ℓ) whereconstructor allfield proof : ∀ p → P (proj₂ cx p)module _ {s₁ p₁ s₂ p₂} {C : Container s₁ p₁} {D : Container s₂ p₂}{x ℓ ℓ′} {X : Set x} {P : Pred X ℓ} {Q : Pred X ℓ′}wheremap : (f : C ⇒ D) → P ⊆ Q → □ C P ⊆ □ D Q ∘′ ⟪ f ⟫map f P⊆Q (all prf) .□.proof p = P⊆Q (prf (f .position p))module _ {s₁ p₁ s₂ p₂} {C : Container s₁ p₁} {D : Container s₂ p₂}{x ℓ} {X : Set x} {P : Pred X ℓ}wheremap₁ : (f : C ⇒ D) → □ C P ⊆ □ D P ∘′ ⟪ f ⟫map₁ f = map f idmodule _ {s p} {C : Container s p}{x ℓ ℓ′} {X : Set x} {P : Pred X ℓ} {Q : Pred X ℓ′}wheremap₂ : P ⊆ Q → □ C P ⊆ □ C Qmap₂ = map (M.id C)
-------------------------------------------------------------------------- The Agda standard library---- Pointwise equality for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Relation.Binary.Pointwise whereopen import Data.Product.Base using (_,_; Σ-syntax; -,_; proj₁; proj₂)open import Function.Base using (_∘_)open import Level using (_⊔_)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; subst)open import Data.Container.Core using (Container; ⟦_⟧)-- Equality, parametrised on an underlying relation.module _ {s p} (C : Container s p) whererecord Pointwise {x y e} {X : Set x} {Y : Set y} (R : REL X Y e)(cx : ⟦ C ⟧ X) (cy : ⟦ C ⟧ Y) : Set (s ⊔ p ⊔ e) whereconstructor _,_field shape : proj₁ cx ≡ proj₁ cyposition : ∀ p → R (proj₂ cx p) (proj₂ cy (subst _ shape p))infixr 4 _,_module _ {s p} {C : Container s p} {x y} {X : Set x} {Y : Set y}{ℓ ℓ′} {R : REL X Y ℓ} {R′ : REL X Y ℓ′}wheremap : R ⇒ R′ → Pointwise C R ⇒ Pointwise C R′map R⇒R′ (s , f) = s , R⇒R′ ∘ f
-------------------------------------------------------------------------- The Agda standard library---- Properties of pointwise equality for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Relation.Binary.Pointwise.Properties whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Container.Core using (Container; ⟦_⟧)open import Data.Container.Relation.Binary.Pointwiseusing (Pointwise; _,_)open import Data.Product.Base using (_,_; Σ-syntax; -,_)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; subst; cong)module _ {s p x r} {X : Set x} (C : Container s p) (R : Rel X r) whererefl : Reflexive R → Reflexive (Pointwise C R)refl R-refl = ≡.refl , λ p → R-reflsym : Symmetric R → Symmetric (Pointwise C R)sym R-sym (≡.refl , f) = ≡.refl , λ p → R-sym (f p)trans : Transitive R → Transitive (Pointwise C R)trans R-trans (≡.refl , f) (≡.refl , g) = ≡.refl , λ p → R-trans (f p) (g p)private-- Note that, if propositional equality were extensional, then-- Eq _≡_ and _≡_ would coincide.Eq⇒≡ : ∀ {s p x} {C : Container s p} {X : Set x} {xs ys : ⟦ C ⟧ X} →Extensionality p x → Pointwise C _≡_ xs ys → xs ≡ ysEq⇒≡ ext (≡.refl , f≈f′) = cong -,_ (ext f≈f′)
-------------------------------------------------------------------------- The Agda standard library---- Equality over container extensions parametrised by some setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.Container.Relation.Binary.Equality.Setoid {c e} (S : Setoid c e) whereopen import Level using (_⊔_; suc)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Data.Container.Coreopen import Data.Container.Relation.Binary.Pointwiseimport Data.Container.Relation.Binary.Pointwise.Properties as Pwprivatemodule S = Setoid Sopen S using (_≈_) renaming (Carrier to X)-------------------------------------------------------------------------- Definition of equalitymodule _ {s p} (C : Container s p) whereEq : Rel (⟦ C ⟧ X) (e ⊔ s ⊔ p)Eq = Pointwise C _≈_-------------------------------------------------------------------------- Relational propertiesrefl : Reflexive Eqrefl = Pw.refl C _ S.reflsym : Symmetric Eqsym = Pw.sym C _ S.symtrans : Transitive Eqtrans = Pw.trans C _ S.transisEquivalence : IsEquivalence EqisEquivalence = record{ refl = refl; sym = sym; trans = trans}setoid : Setoid (s ⊔ p ⊔ c) (s ⊔ p ⊔ e)setoid = record{ isEquivalence = isEquivalence}
-------------------------------------------------------------------------- The Agda standard library---- Several kinds of "relatedness" for containers such as equivalences,-- surjections and bijections------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Related whereopen import Level using (_⊔_)open import Data.Container.Coreimport Function.Related.Propositional as Relatedopen import Relation.Binary.Bundles using (Preorder; Setoid)open import Data.Container.Membershipopen Related publicusing (Kind; SymmetricKind)renaming ( implication to subset; reverseImplication to superset; equivalence to set; injection to subbag; reverseInjection to superbag; bijection to bag)[_]-Order : ∀ {s p ℓ} → Kind → Container s p → Set ℓ →Preorder (s ⊔ p ⊔ ℓ) (s ⊔ p ⊔ ℓ) (p ⊔ ℓ)[ k ]-Order C X = Related.InducedPreorder₂ k (_∈_ {C = C} {X = X})[_]-Equality : ∀ {s p ℓ} → SymmetricKind → Container s p → Set ℓ →Setoid (s ⊔ p ⊔ ℓ) (p ⊔ ℓ)[ k ]-Equality C X = Related.InducedEquivalence₂ k (_∈_ {C = C} {X = X})infix 4 _≲[_]__≲[_]_ : ∀ {s p x} {C : Container s p} {X : Set x} →⟦ C ⟧ X → Kind → ⟦ C ⟧ X → Set (p ⊔ x)_≲[_]_ {C = C} {X} xs k ys = Preorder._≲_ ([ k ]-Order C X) xs ys-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0infix 4 _∼[_]__∼[_]_ = _≲[_]_{-# WARNING_ON_USAGE _∼[_]_"Warning: _∼[_]_ was deprecated in v2.0. Please use _≲[_]_ instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Properties whereimport Function.Base as Fopen import Relation.Binary.Bundles using (Setoid)open import Data.Container.Coreopen import Data.Container.Relation.Binary.Equality.Setoidmodule _ {s p} {C : Container s p} wheremap-identity : ∀ {x e} (X : Setoid x e) xs →Eq X C (map F.id xs) xsmap-identity X xs = refl X Cmap-compose : ∀ {x y z e} {X : Set x} {Y : Set y} (Z : Setoid z e) g (f : X → Y) xs →Eq Z C (map g (map f xs)) (map (g F.∘′ f) xs)map-compose Z g f xs = refl Z C
-------------------------------------------------------------------------- The Agda standard library---- Container Morphisms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Morphism whereopen import Data.Container.Coreimport Function.Base as Fmodule _ {s p} (C : Container s p) whereid : C ⇒ Cid .shape = F.idid .position = F.idmodule _ {s₁ s₂ s₃ p₁ p₂ p₃}{C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} {C₃ : Container s₃ p₃}whereinfixr 9 _∘__∘_ : C₂ ⇒ C₃ → C₁ ⇒ C₂ → C₁ ⇒ C₃(f ∘ g) .shape = shape f F.∘′ shape g(f ∘ g) .position = position g F.∘′ position f
-------------------------------------------------------------------------- The Agda standard library---- Propertiers of any for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Morphism.Properties whereopen import Level using (_⊔_; suc)open import Function.Base as F using (_$_)open import Data.Product.Base using (∃; proj₁; proj₂; _,_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; _≗_)open import Data.Container.Coreopen import Data.Container.Morphismopen import Data.Container.Relation.Binary.Equality.Setoid-- Identitymodule _ {s p} (C : Container s p) whereid-correct : ∀ {x} {X : Set x} → ⟪ id C ⟫ {X = X} ≗ F.idid-correct x = ≡.refl-- Composition.module _ {s₁ s₂ s₃ p₁ p₂ p₃}{C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} {C₃ : Container s₃ p₃}where∘-correct : (f : C₂ ⇒ C₃) (g : C₁ ⇒ C₂) → ∀ {x} {X : Set x} →⟪ f ∘ g ⟫ {X = X} ≗ (⟪ f ⟫ F.∘ ⟪ g ⟫)∘-correct f g xs = ≡.reflmodule _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} where-- Naturality.Natural : ∀ x e → (∀ {X : Set x} → ⟦ C₁ ⟧ X → ⟦ C₂ ⟧ X) →Set (s₁ ⊔ s₂ ⊔ p₁ ⊔ p₂ ⊔ suc (x ⊔ e))Natural x e m =∀ {X : Set x} (Y : Setoid x e) → let module Y = Setoid Y in(f : X → Y.Carrier) (xs : ⟦ C₁ ⟧ X) →Eq Y C₂ (m $ map f xs) (map f $ m xs)-- Container morphisms are natural.natural : ∀ (m : C₁ ⇒ C₂) x e → Natural x e ⟪ m ⟫natural m x e Y f xs = refl Y C₂module _ {s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂) where-- Natural transformations.NT : ∀ x e → Set (s₁ ⊔ s₂ ⊔ p₁ ⊔ p₂ ⊔ suc (x ⊔ e))NT x e = ∃ λ (m : ∀ {X : Set x} → ⟦ C₁ ⟧ X → ⟦ C₂ ⟧ X) → Natural x e mmodule _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} where-- All natural functions of the right type are container morphisms.complete : ∀ {e} → (nt : NT C₁ C₂ p₁ e) →∃ λ m → (X : Setoid p₁ e) → let module X = Setoid X in∀ xs → Eq X C₂ (proj₁ nt xs) (⟪ m ⟫ xs)complete (nt , nat) =(m , λ X xs → nat X (proj₂ xs) (proj₁ xs , F.id)) wherem : C₁ ⇒ C₂m .shape = λ s → proj₁ (nt (s , F.id))m .position = proj₂ (nt (_ , F.id))
-------------------------------------------------------------------------- The Agda standard library---- Membership for containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Membership whereopen import Level using (_⊔_)open import Relation.Unary using (Pred)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Data.Container.Core using (Container; ⟦_⟧)open import Data.Container.Relation.Unary.Any using (◇)module _ {s p} {C : Container s p} {x} {X : Set x} whereinfix 4 _∈__∈_ : X → Pred (⟦ C ⟧ X) (p ⊔ x)x ∈ xs = ◇ C (_≡_ x) xs
-------------------------------------------------------------------------- The Agda standard library---- Indexed containers aka interaction structures aka polynomial-- functors. The notation and presentation here is closest to that of-- Hancock and Hyvernat in "Programming interfaces and basic topology"-- (2006/9).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed whereopen import Level using (Level; zero; _⊔_)open import Data.Product.Base as Prod hiding (map)open import Data.W.Indexed using (W)open import Function.Base renaming (id to ⟨id⟩; _∘_ to _⟨∘⟩_)open import Function.Bundles using (_↔_; Inverse)open import Relation.Unary using (Pred; _⊆_)open import Relation.Binary.Core using (Rel; REL)open import Relation.Binary.PropositionalEquality.Core using (_≡_; _≗_; refl; trans; subst)-------------------------------------------------------------------------- The type and its semantics ("extension").open import Data.Container.Indexed.Core publicopen Container public-- Abbreviation for the commonly used level one version of indexed-- containers.infix 5 _▷__▷_ : Set → Set → Set₁I ▷ O = Container I O zero zero-- The least and greatest fixpoint.μ : ∀ {o c r} {O : Set o} → Container O O c r → Pred O _μ = W-- An equivalence relation is defined in Data.Container.Indexed.WithK.-------------------------------------------------------------------------- Functoriality-- Indexed containers are functors.map : ∀ {i o c r ℓ₁ ℓ₂} {I : Set i} {O : Set o}(C : Container I O c r) {X : Pred I ℓ₁} {Y : Pred I ℓ₂} →X ⊆ Y → ⟦ C ⟧ X ⊆ ⟦ C ⟧ Ymap _ f = Prod.map ⟨id⟩ (λ g → f ⟨∘⟩ g)-- Some properties are proved in Data.Container.Indexed.WithK.-------------------------------------------------------------------------- Container morphismsmodule _ {i₁ i₂ o₁ o₂}{I₁ : Set i₁} {I₂ : Set i₂} {O₁ : Set o₁} {O₂ : Set o₂} where-- General container morphism.record ContainerMorphism {c₁ c₂ r₁ r₂ ℓ₁ ℓ₂}(C₁ : Container I₁ O₁ c₁ r₁) (C₂ : Container I₂ O₂ c₂ r₂)(f : I₁ → I₂) (g : O₁ → O₂)(_∼_ : Rel I₂ ℓ₁) (_≈_ : REL (Set r₂) (Set r₁) ℓ₂)(_·_ : ∀ {A B} → A ≈ B → A → B) :Set (i₁ ⊔ i₂ ⊔ o₁ ⊔ o₂ ⊔ c₁ ⊔ c₂ ⊔ r₁ ⊔ r₂ ⊔ ℓ₁ ⊔ ℓ₂) wherefieldcommand : Command C₁ ⊆ Command C₂ ⟨∘⟩ gresponse : ∀ {o} {c₁ : Command C₁ o} →Response C₂ (command c₁) ≈ Response C₁ c₁coherent : ∀ {o} {c₁ : Command C₁ o} {r₂ : Response C₂ (command c₁)} →f (next C₁ c₁ (response · r₂)) ∼ next C₂ (command c₁) r₂open ContainerMorphism public-- Plain container morphism._⇒[_/_]_ : ∀ {c₁ c₂ r₁ r₂} →Container I₁ O₁ c₁ r₁ → (I₁ → I₂) → (O₁ → O₂) →Container I₂ O₂ c₂ r₂ → Set _C₁ ⇒[ f / g ] C₂ = ContainerMorphism C₁ C₂ f g _≡_ (λ R₂ R₁ → R₂ → R₁) _$_-- Linear container morphism._⊸[_/_]_ : ∀ {c₁ c₂ r₁ r₂} →Container I₁ O₁ c₁ r₁ → (I₁ → I₂) → (O₁ → O₂) →Container I₂ O₂ c₂ r₂ → Set _C₁ ⊸[ f / g ] C₂ = ContainerMorphism C₁ C₂ f g _≡_ _↔_(λ r₂↔r₁ r₂ → Inverse.to r₂↔r₁ r₂)-- Cartesian container morphism._⇒C[_/_]_ : ∀ {c₁ c₂ r} →Container I₁ O₁ c₁ r → (I₁ → I₂) → (O₁ → O₂) →Container I₂ O₂ c₂ r → Set _C₁ ⇒C[ f / g ] C₂ = ContainerMorphism C₁ C₂ f g _≡_ (λ R₂ R₁ → R₂ ≡ R₁)(λ r₂≡r₁ r₂ → subst ⟨id⟩ r₂≡r₁ r₂)-- Degenerate cases where no reindexing is performed.module _ {i o c r} {I : Set i} {O : Set o} whereinfixr 8 _⇒_ _⊸_ _⇒C__⇒_ : Rel (Container I O c r) _C₁ ⇒ C₂ = C₁ ⇒[ ⟨id⟩ / ⟨id⟩ ] C₂_⊸_ : Rel (Container I O c r) _C₁ ⊸ C₂ = C₁ ⊸[ ⟨id⟩ / ⟨id⟩ ] C₂_⇒C_ : Rel (Container I O c r) _C₁ ⇒C C₂ = C₁ ⇒C[ ⟨id⟩ / ⟨id⟩ ] C₂-------------------------------------------------------------------------- Plain morphisms-- Interpretation of _⇒_.⟪_⟫ : ∀ {i o c r ℓ} {I : Set i} {O : Set o} {C₁ C₂ : Container I O c r} →C₁ ⇒ C₂ → (X : Pred I ℓ) → ⟦ C₁ ⟧ X ⊆ ⟦ C₂ ⟧ X⟪ m ⟫ X (c , k) = command m c , λ r₂ →subst X (coherent m) (k (response m r₂))module PlainMorphism {i o c r} {I : Set i} {O : Set o} where-- Identity.id : (C : Container I O c r) → C ⇒ Cid _ = record{ command = ⟨id⟩; response = ⟨id⟩; coherent = refl}-- Composition.infixr 9 _∘__∘_ : {C₁ C₂ C₃ : Container I O c r} →C₂ ⇒ C₃ → C₁ ⇒ C₂ → C₁ ⇒ C₃f ∘ g = record{ command = command f ⟨∘⟩ command g; response = response g ⟨∘⟩ response f; coherent = coherent g ⟨ trans ⟩ coherent f}-- Identity commutes with ⟪_⟫.id-correct : ∀ {ℓ} {C : Container I O c r} → ∀ {X : Pred I ℓ} {o} →⟪ id C ⟫ X {o} ≗ ⟨id⟩id-correct _ = refl-- More properties are proved in Data.Container.Indexed.WithK.-------------------------------------------------------------------------- Linear container morphismsmodule LinearMorphism{i o c r} {I : Set i} {O : Set o} {C₁ C₂ : Container I O c r}(m : C₁ ⊸ C₂)wheremorphism : C₁ ⇒ C₂morphism = record{ command = command m; response = Inverse.to (response m); coherent = coherent m}⟪_⟫⊸ : ∀ {ℓ} (X : Pred I ℓ) → ⟦ C₁ ⟧ X ⊆ ⟦ C₂ ⟧ X⟪_⟫⊸ = ⟪ morphism ⟫open LinearMorphism public using (⟪_⟫⊸)-------------------------------------------------------------------------- Cartesian morphismsmodule CartesianMorphism{i o c r} {I : Set i} {O : Set o} {C₁ C₂ : Container I O c r}(m : C₁ ⇒C C₂)wheremorphism : C₁ ⇒ C₂morphism = record{ command = command m; response = subst ⟨id⟩ (response m); coherent = coherent m}⟪_⟫C : ∀ {ℓ} (X : Pred I ℓ) → ⟦ C₁ ⟧ X ⊆ ⟦ C₂ ⟧ X⟪_⟫C = ⟪ morphism ⟫open CartesianMorphism public using (⟪_⟫C)-------------------------------------------------------------------------- All and any-- □ and ◇ are defined in the core module.module _ {i o c r ℓ₁ ℓ₂} {I : Set i} {O : Set o} (C : Container I O c r){X : Pred I ℓ₁} {P Q : Pred (Σ I X) ℓ₂} where-- All.□-map : P ⊆ Q → □ C P ⊆ □ C Q□-map P⊆Q = _⟨∘⟩_ P⊆Q-- Any.◇-map : P ⊆ Q → ◇ C P ⊆ ◇ C Q◇-map P⊆Q = Prod.map ⟨id⟩ P⊆Q-- Membership is defined in Data.Container.Indexed.WithK.
-------------------------------------------------------------------------- The Agda standard library---- Some code related to indexed containers that uses heterogeneous-- equality-------------------------------------------------------------------------- The notation and presentation here is perhaps close to those used-- by Hancock and Hyvernat in "Programming interfaces and basic-- topology" (2006).{-# OPTIONS --with-K --safe #-}module Data.Container.Indexed.WithK whereopen import Axiom.Extensionality.Heterogeneous using (Extensionality)open import Data.Container.Indexed hiding (module PlainMorphism)open import Data.Product.Baseusing (_,_; -,_; _×_; ∃; proj₁; proj₂; Σ-syntax)open import Function.Base renaming (id to ⟨id⟩; _∘_ to _⟨∘⟩_)open import Levelopen import Relation.Unary using (Pred; _⊆_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; refl)open import Relation.Binary.HeterogeneousEquality as ≅ using (_≅_; refl)open import Relation.Binary.Indexed.Heterogeneous-------------------------------------------------------------------------- Equality, parametrised on an underlying relation.Eq : ∀ {i o c r ℓ} {I : Set i} {O : Set o} (C : Container I O c r)(X Y : Pred I ℓ) → IREL X Y ℓ → IREL (⟦ C ⟧ X) (⟦ C ⟧ Y) _Eq C _ _ _≈_ {o₁} {o₂} (c , k) (c′ , k′) =o₁ ≡ o₂ × c ≅ c′ × (∀ r r′ → r ≅ r′ → k r ≈ k′ r′)private-- Note that, if propositional equality were extensional, then Eq _≅_-- and _≅_ would coincide.Eq⇒≅ : ∀ {i o c r ℓ} {I : Set i} {O : Set o}{C : Container I O c r} {X : Pred I ℓ} {o₁ o₂ : O}{xs : ⟦ C ⟧ X o₁} {ys : ⟦ C ⟧ X o₂} → Extensionality r ℓ →Eq C X X (λ x₁ x₂ → x₁ ≅ x₂) xs ys → xs ≅ ysEq⇒≅ {xs = c , k} {.c , k′} ext (refl , refl , k≈k′) =≅.cong (_,_ c) (ext (λ _ → refl) (λ r → k≈k′ r r refl))setoid : ∀ {i o c r s} {I : Set i} {O : Set o} →Container I O c r → IndexedSetoid I s _ → IndexedSetoid O _ _setoid C X = record{ Carrier = ⟦ C ⟧ X.Carrier; _≈_ = _≈_; isEquivalence = record{ refl = refl , refl , λ { r .r refl → X.refl }; sym = sym; trans = λ { {_} {i = xs} {ys} {zs} → trans {_} {i = xs} {ys} {zs} }}}wheremodule X = IndexedSetoid X_≈_ : IRel (⟦ C ⟧ X.Carrier) __≈_ = Eq C X.Carrier X.Carrier X._≈_sym : Symmetric (⟦ C ⟧ X.Carrier) _≈_sym {_} {._} {_ , _} {._ , _} (refl , refl , k) =refl , refl , λ { r .r refl → X.sym (k r r refl) }trans : Transitive (⟦ C ⟧ X.Carrier) _≈_trans {._} {_} {._} {_ , _} {._ , _} {._ , _}(refl , refl , k) (refl , refl , k′) =refl , refl , λ { r .r refl → X.trans (k r r refl) (k′ r r refl) }-------------------------------------------------------------------------- Functorialitymodule Map whereidentity : ∀ {i o c r s} {I : Set i} {O : Set o} (C : Container I O c r)(X : IndexedSetoid I s _) → let module X = IndexedSetoid X in∀ {o} {xs : ⟦ C ⟧ X.Carrier o} → Eq C X.Carrier X.CarrierX._≈_ xs (map C {X.Carrier} ⟨id⟩ xs)identity C X = IndexedSetoid.refl (setoid C X)composition : ∀ {i o c r s ℓ₁ ℓ₂} {I : Set i} {O : Set o}(C : Container I O c r) {X : Pred I ℓ₁} {Y : Pred I ℓ₂}(Z : IndexedSetoid I s _) → let module Z = IndexedSetoid Z in{f : Y ⊆ Z.Carrier} {g : X ⊆ Y} {o : O} {xs : ⟦ C ⟧ X o} →Eq C Z.Carrier Z.Carrier Z._≈_(map C {Y} f (map C {X} g xs))(map C {X} (f ⟨∘⟩ g) xs)composition C Z = IndexedSetoid.refl (setoid C Z)-------------------------------------------------------------------------- Plain morphismsmodule PlainMorphism {i o c r} {I : Set i} {O : Set o} whereopen Data.Container.Indexed.PlainMorphism-- Naturality.Natural : ∀ {ℓ} {C₁ C₂ : Container I O c r} →((X : Pred I ℓ) → ⟦ C₁ ⟧ X ⊆ ⟦ C₂ ⟧ X) → Set _Natural {C₁ = C₁} {C₂} m =∀ {X} Y → let module Y = IndexedSetoid Y in (f : X ⊆ Y.Carrier) →∀ {o} (xs : ⟦ C₁ ⟧ X o) →Eq C₂ Y.Carrier Y.Carrier Y._≈_(m Y.Carrier $ map C₁ {X} f xs) (map C₂ {X} f $ m X xs)-- Natural transformations.NT : ∀ {ℓ} (C₁ C₂ : Container I O c r) → Set _NT {ℓ} C₁ C₂ = ∃ λ (m : (X : Pred I ℓ) → ⟦ C₁ ⟧ X ⊆ ⟦ C₂ ⟧ X) →Natural m-- Container morphisms are natural.natural : ∀ {ℓ} (C₁ C₂ : Container I O c r) (m : C₁ ⇒ C₂) → Natural {ℓ} ⟪ m ⟫natural _ _ m {X} Y f _ = refl , refl , λ { r .r refl → lemma (coherent m) }wheremodule Y = IndexedSetoid Ylemma : ∀ {i j} (eq : i ≡ j) {x} →≡.subst Y.Carrier eq (f x) Y.≈ f (≡.subst X eq x)lemma refl = Y.refl-- In fact, all natural functions of the right type are container-- morphisms.complete : ∀ {C₁ C₂ : Container I O c r} (nt : NT C₁ C₂) →∃ λ m → (X : IndexedSetoid I _ _) →let module X = IndexedSetoid X in∀ {o} (xs : ⟦ C₁ ⟧ X.Carrier o) →Eq C₂ X.Carrier X.Carrier X._≈_(proj₁ nt X.Carrier xs) (⟪ m ⟫ X.Carrier {o} xs)complete {C₁} {C₂} (nt , nat) = m , (λ X xs → nat X(λ { (r , eq) → ≡.subst (IndexedSetoid.Carrier X) eq (proj₂ xs r) })(proj₁ xs , (λ r → r , refl)))wherem : C₁ ⇒ C₂m = record{ command = λ c₁ → proj₁ (lemma c₁); response = λ {_} {c₁} r₂ → proj₁ (proj₂ (lemma c₁) r₂); coherent = λ {_} {c₁} {r₂} → proj₂ (proj₂ (lemma c₁) r₂)}wherelemma : ∀ {o} (c₁ : Command C₁ o) → Σ[ c₂ ∈ Command C₂ o ]((r₂ : Response C₂ c₂) → Σ[ r₁ ∈ Response C₁ c₁ ]next C₁ c₁ r₁ ≡ next C₂ c₂ r₂)lemma c₁ = nt (λ i → Σ[ r₁ ∈ Response C₁ c₁ ] next C₁ c₁ r₁ ≡ i)(c₁ , λ r₁ → r₁ , refl)-- Composition commutes with ⟪_⟫.∘-correct : {C₁ C₂ C₃ : Container I O c r}(f : C₂ ⇒ C₃) (g : C₁ ⇒ C₂) (X : IndexedSetoid I (c ⊔ r) _) →let module X = IndexedSetoid X in∀ {o} {xs : ⟦ C₁ ⟧ X.Carrier o} →Eq C₃ X.Carrier X.Carrier X._≈_(⟪ f ∘ g ⟫ X.Carrier xs)(⟪ f ⟫ X.Carrier (⟪ g ⟫ X.Carrier xs))∘-correct f g X = refl , refl , λ { r .r refl → lemma (coherent g)(coherent f) }wheremodule X = IndexedSetoid Xlemma : ∀ {i j k} (eq₁ : i ≡ j) (eq₂ : j ≡ k) {x} →≡.subst X.Carrier (≡.trans eq₁ eq₂) xX.≈≡.subst X.Carrier eq₂ (≡.subst X.Carrier eq₁ x)lemma refl refl = X.refl-------------------------------------------------------------------------- All and any-- Membership.infix 4 _∈__∈_ : ∀ {i o c r ℓ} {I : Set i} {O : Set o}{C : Container I O c r} {X : Pred I (i ⊔ ℓ)} → IREL X (⟦ C ⟧ X) __∈_ {C = C} {X} x xs = ◇ C {X = X} ((x ≅_) ⟨∘⟩ proj₂) (-, xs)
-------------------------------------------------------------------------- The Agda standard library---- Pointwise equality for indexed containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed.Relation.Binary.Pointwise whereopen import Data.Product.Base using (_,_; Σ-syntax)open import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Binary using (REL; _⇒_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Data.Container.Indexed.Core using (Container; Subtrees; ⟦_⟧)private variableℓᵉ ℓᵉ′ ℓᵖ ℓˢ ℓˣ ℓʸ : LevelI O : Set _-------------------------------------------------------------------------- Equality, parametrised on an underlying relation.-- Since ⟦_⟧ is a Σ-type, not a record, I'd say Pointwise should also be-- a Σ-type, not a record. Maybe we need to update module-- `Data.Container.Relation.Binary.Pointwise` accordingly...---- record Pointwise : Set (ℓˢ ⊔ ℓᵖ ⊔ ℓᵉ) where-- constructor _,_-- field shape : c ≡ c'-- position : Eqs shape xs ysmodule _ (C : Container I O ℓˢ ℓᵖ){X : I → Set ℓˣ} {Y : I → Set ℓʸ} (R : (i : I) → REL (X i) (Y i) ℓᵉ)(o : O)((c , xs) : ⟦ C ⟧ X o)((c' , ys) : ⟦ C ⟧ Y o)whereopen Container CEqs : c ≡ c' → Subtrees C X o c → Subtrees C Y o c' → Set _Eqs refl xs ys = (r : Response c) → R (next c r) (xs r) (ys r)Pointwise = Σ[ eq ∈ c ≡ c' ] Eqs eq xs ys-------------------------------------------------------------------------- Operationsmodule _ {C : Container I O ℓˢ ℓᵖ}{X : I → Set ℓˣ} {Y : I → Set ℓʸ}{R : (i : I) → REL (X i) (Y i) ℓᵉ}{R′ : (i : I) → REL (X i) (Y i) ℓᵉ′}wheremap : (R⇒R′ : ∀ i → R i ⇒ R′ i) {o : O} → Pointwise C R o ⇒ Pointwise C R′ omap R⇒R′ (refl , f) = refl , R⇒R′ _ ∘ f
-------------------------------------------------------------------------- The Agda standard library---- Properties of pointwise equality for indexed containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed.Relation.Binary.Pointwise.Properties whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Container.Indexed.Core using (Container; ⟦_⟧)open import Data.Container.Indexed.Relation.Binary.Pointwiseusing (Pointwise)open import Data.Product.Base using (_,_; Σ-syntax; -,_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; subst; cong)private variableℓᵉ ℓᵖ ℓˢ ℓˣ : LevelI O : Set _module _(C : Container I O ℓˢ ℓᵖ) {X : I → Set ℓˣ}(R : (i : I) → Rel (X i) ℓᵉ){o : O}whererefl : (∀ i → Reflexive (R i)) → Reflexive (Pointwise C R o)refl R-refl = ≡.refl , λ p → R-refl _sym : (∀ i → Symmetric (R i)) → Symmetric (Pointwise C R o)sym R-sym (≡.refl , f) = ≡.refl , λ p → R-sym _ (f p)trans : (∀ i → Transitive (R i)) → Transitive (Pointwise C R o)trans R-trans (≡.refl , f) (≡.refl , g) = ≡.refl , λ p → R-trans _ (f p) (g p)-- If propositional equality is extensional, then `Eq _≡_` and `_≡_` coincide.Eq⇒≡ : {C : Container I O ℓˢ ℓᵖ} {X : I → Set ℓˣ} {R : (i : I) → Rel (X i) ℓᵉ}{o : O} {xs ys : ⟦ C ⟧ X o} →Extensionality ℓᵖ ℓˣ →Pointwise C (λ (i : I) → _≡_ {A = X i}) o xs ys →xs ≡ ysEq⇒≡ ext (≡.refl , f≈f′) = cong -,_ (ext f≈f′)
-------------------------------------------------------------------------- The Agda standard library---- Equality over indexed container extensions parametrised by a setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary using (Setoid)module Data.Container.Indexed.Relation.Binary.Equality.Setoid{ℓⁱ ℓᶜ ℓᵉ} {I : Set ℓⁱ} (S : I → Setoid ℓᶜ ℓᵉ)whereopen import Functionopen import Level using (Level; _⊔_; suc)open import Relation.Binaryopen import Data.Container.Indexed.Coreopen import Data.Container.Indexed.Relation.Binary.Pointwiseimport Data.Container.Indexed.Relation.Binary.Pointwise.Propertiesas Pointwiseopen Setoid using (Carrier; _≈_)private variableℓˢ ℓᵖ : LevelO : Set _-------------------------------------------------------------------------- Definition of equalitymodule _ (C : Container I O ℓˢ ℓᵖ) (o : O) whereEq : Rel (⟦ C ⟧ (Carrier ∘ S) o) (ℓᵉ ⊔ ℓˢ ⊔ ℓᵖ)Eq = Pointwise C (_≈_ ∘ S) o-------------------------------------------------------------------------- Relational propertiesrefl : Reflexive Eqrefl = Pointwise.refl C _ (Setoid.refl ∘ S)sym : Symmetric Eqsym = Pointwise.sym C _ (Setoid.sym ∘ S)trans : Transitive Eqtrans = Pointwise.trans C _ (Setoid.trans ∘ S)isEquivalence : IsEquivalence EqisEquivalence = record{ refl = refl; sym = sym; trans = trans}setoid : Setoid (ℓˢ ⊔ ℓᵖ ⊔ ℓᶜ) (ℓˢ ⊔ ℓᵖ ⊔ ℓᵉ)setoid = record{ isEquivalence = isEquivalence}
-------------------------------------------------------------------------- The Agda standard library---- The free monad construction on indexed containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed.FreeMonad whereopen import Levelopen import Function.Base hiding (const)open import Effect.Monad.Predicateopen import Data.Container.Indexedopen import Data.Container.Indexed.Combinator hiding (id; _∘_)open import Data.Emptyopen import Data.Sum.Base using (inj₁; inj₂)open import Data.Product.Base using (_,_)open import Data.W.Indexedopen import Relation.Unaryopen import Relation.Unary.PredicateTransformeropen import Relation.Binary.PropositionalEquality.Core using (refl)------------------------------------------------------------------------infixl 9 _⋆C_infix 9 _⋆__⋆C_ : ∀ {i o c r} {I : Set i} {O : Set o} →Container I O c r → Pred O c → Container I O _ _C ⋆C X = const X ⊎′ C_⋆_ : ∀ {ℓ} {O : Set ℓ} → Container O O ℓ ℓ → Pt O ℓC ⋆ X = μ (C ⋆C X)pattern returnP x = (inj₁ x , _)pattern doP c k = (inj₂ c , k)inn : ∀ {ℓ} {O : Set ℓ} {C : Container O O ℓ ℓ} {X} →⟦ C ⟧ (C ⋆ X) ⊆ C ⋆ Xinn (c , k) = sup (doP c k)rawPMonad : ∀ {ℓ} {O : Set ℓ} {C : Container O O ℓ ℓ} →RawPMonad {ℓ = ℓ} (_⋆_ C)rawPMonad {C = C} = record{ return? = return; _=<?_ = _=<<_}wherereturn : ∀ {X} → X ⊆ C ⋆ Xreturn x = sup (inj₁ x , ⊥-elim ∘ lower)_=<<_ : ∀ {X Y} → X ⊆ C ⋆ Y → C ⋆ X ⊆ C ⋆ Yf =<< sup (returnP x) = f xf =<< sup (doP c k) = inn (c , λ r → f =<< k r)leaf : ∀ {ℓ} {O : Set ℓ} {C : Container O O ℓ ℓ} {X : Pred O ℓ} →⟦ C ⟧ X ⊆ C ⋆ Xleaf (c , k) = inn (c , return? ∘ k)whereopen RawPMonad rawPMonadgeneric : ∀ {ℓ} {O : Set ℓ} {C : Container O O ℓ ℓ} {o}(c : Command C o) →o ∈ C ⋆ (⋃[ r ∶ Response C c ] { next C c r })generic c = inn (c , λ r → return? (r , refl))whereopen RawPMonad rawPMonad
-------------------------------------------------------------------------- The Agda standard library---- Greatest fixpoint for indexed containers - using guardedness------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Data.Container.Indexed.Fixpoints.Guarded whereopen import Level using (Level; _⊔_)open import Codata.Musical.M.Indexed using (M)open import Data.Container.Indexed using (Container)open import Relation.Unary using (Pred)privatevariableo c r : LevelO : Set o-- The least fixpoint can be found in `Data.Container`open Data.Container.Indexed publicusing (μ)-- This lives in its own module due to its use of guardedness.ν : Container O O c r → Pred O _ν = M
-------------------------------------------------------------------------- The Agda standard library---- Indexed containers core------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed.Core whereopen import Levelopen import Data.Product.Base using (Σ; Σ-syntax; _,_; ∃)open import Relation.Unaryprivate variablei o c r ℓ ℓ′ : LevelI : Set iO : Set o-------------------------------------------------------------------------- Definitioninfix 5 _◃_/_record Container (I : Set i) (O : Set o) c r : Set (i ⊔ o ⊔ suc c ⊔ suc r) whereconstructor _◃_/_fieldCommand : (o : O) → Set cResponse : ∀ {o} → Command o → Set rnext : ∀ {o} (c : Command o) → Response c → I-------------------------------------------------------------------------- The semantics ("extension") of an indexed container.module _ (C : Container I O c r) (X : Pred I ℓ) whereopen Container CSubtrees : ∀ o → Command o → Set _Subtrees o c = (r : Response c) → X (next c r)⟦_⟧ : Pred O _⟦_⟧ o = Σ (Command o) (Subtrees o)-------------------------------------------------------------------------- All and anymodule _ (C : Container I O c r) {X : Pred I ℓ} where-- All.□ : Pred (Σ I X) ℓ′ → Pred (Σ O (⟦ C ⟧ X)) _□ P (_ , _ , k) = ∀ r → P (_ , k r)-- Any.◇ : Pred (Σ I X) ℓ′ → Pred (Σ O (⟦ C ⟧ X)) _◇ P (_ , _ , k) = ∃ λ r → P (_ , k r)
-------------------------------------------------------------------------- The Agda standard library---- Indexed container combinators------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Indexed.Combinator whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Container.Indexed using (Container; _◃_/_; ⟦_⟧;Command; Response; ◇; next)open import Data.Empty.Polymorphic using (⊥; ⊥-elim)open import Data.Unit.Polymorphic.Base using (⊤)open import Data.Product.Base as Prod hiding (Σ) renaming (_×_ to _⟨×⟩_)open import Data.Sum.Base renaming (_⊎_ to _⟨⊎⟩_)open import Data.Sum.Relation.Unary.All as All using (All)open import Function.Base as F hiding (id; const) renaming (_∘_ to _⟨∘⟩_)open import Function.Bundles using (mk↔ₛ′)open import Function.Indexed.Bundles using (_↔ᵢ_)open import Level using (Level; _⊔_)open import Relation.Unary using (Pred; _⊆_; _∪_; _∩_; ⋃; ⋂)renaming (_⟨×⟩_ to _⟪×⟫_; _⟨⊙⟩_ to _⟪⊙⟫_; _⟨⊎⟩_ to _⟪⊎⟫_)open import Relation.Binary.PropositionalEquality.Coreusing (_≗_; refl; cong)privatevariableℓ ℓ₁ ℓ₂ i j k o c c₁ c₂ r r₁ r₂ x z : LevelI J K O X Z : Set _-------------------------------------------------------------------------- Combinators-- Identity.id : Container O O c rid = F.const ⊤ ◃ F.const ⊤ / (λ {o} _ _ → o)-- Constant.const : Pred O c → Container I O c rconst X = X ◃ F.const ⊥ / F.const ⊥-elim-- Composition.infixr 9 _∘__∘_ : Container J K c₁ r₁ → Container I J c₂ r₂ → Container I K _ _C₁ ∘ C₂ = C ◃ R / nwhereC : ∀ k → Set _C = ⟦ C₁ ⟧ (Command C₂)R : ∀ {k} → ⟦ C₁ ⟧ (Command C₂) k → Set _R (c , k) = ◇ C₁ {X = Command C₂} (Response C₂ ⟨∘⟩ proj₂) (_ , c , k)n : ∀ {k} (c : ⟦ C₁ ⟧ (Command C₂) k) → R c → _n (_ , f) (r₁ , r₂) = next C₂ (f r₁) r₂-- Duality._^⊥ : Container I O c r → Container I O (c ⊔ r) c(C ^⊥) .Command o = (c : C .Command o) → C .Response c(C ^⊥) .Response {o} _ = C .Command o(C ^⊥) .next f c = C .next c (f c)-- Strength.infixl 3 _⋊__⋊_ : Container I O c r → (Z : Set z) → Container (I ⟨×⟩ Z) (O ⟨×⟩ Z) c r(C ⋊ Z) .Command (o , z) = C .Command o(C ⋊ Z) .Response = C .Response(C ⋊ Z) .next {o , z} c r = C .next c r , zinfixr 3 _⋉__⋉_ : (Z : Set z) → Container I O c r → Container (Z ⟨×⟩ I) (Z ⟨×⟩ O) c r(Z ⋉ C) .Command (z , o) = C .Command o(Z ⋉ C) .Response = C .Response(Z ⋉ C) .next {z , o} c r = z , C .next c r-- Product. (Note that, up to isomorphism, and ignoring universe level-- issues, this is a special case of indexed product.)infixr 2 _×__×_ : Container I O c₁ r₁ → Container I O c₂ r₂ → Container I O _ _(C₁ ◃ R₁ / n₁) × (C₂ ◃ R₂ / n₂) = record{ Command = C₁ ∩ C₂; Response = R₁ ⟪⊙⟫ R₂; next = λ { (c₁ , c₂) → [ n₁ c₁ , n₂ c₂ ] }}-- Indexed product.Π : (X → Container I O c r) → Container I O _ _Π {X = X} C = record{ Command = ⋂ X (Command ⟨∘⟩ C); Response = ⋃[ x ∶ X ] λ c → Response (C x) (c x); next = λ { c (x , r) → next (C x) (c x) r }}-- Sum. (Note that, up to isomorphism, and ignoring universe level-- issues, this is a special case of indexed sum.)infixr 1 _⊎_ _⊎′__⊎_ : Container I O c₁ r₁ → Container I O c₂ r₂ → Container I O _ _(C₁ ⊎ C₂) .Command = C₁ .Command ∪ C₂ .Command(C₁ ⊎ C₂) .Response = All (C₁ .Response) (C₂ .Response)(C₁ ⊎ C₂) .next = All.[ C₁ .next , C₂ .next ]-- A simplified version for responses at the same level r:_⊎′_ : Container I O c₁ r → Container I O c₂ r → Container I O _ r(C₁ ◃ R₁ / n₁) ⊎′ (C₂ ◃ R₂ / n₂) = record{ Command = C₁ ∪ C₂; Response = [ R₁ , R₂ ]; next = [ n₁ , n₂ ]}-- Indexed sum.Σ : (X → Container I O c r) → Container I O _ rΣ {X = X} C = record{ Command = ⋃ X (Command ⟨∘⟩ C); Response = λ { (x , c) → Response (C x) c }; next = λ { (x , c) r → next (C x) c r }}-- Constant exponentiation. (Note that this is a special case of-- indexed product.)infix 0 const[_]⟶_const[_]⟶_ : (X : Set ℓ) → Container I O c r → Container I O _ _const[ X ]⟶ C = Π {X = X} (F.const C)-------------------------------------------------------------------------- Correctness proofsmodule Identity wherecorrect : {X : Pred O ℓ} → ⟦ id {c = c}{r} ⟧ X ↔ᵢ F.id Xcorrect {X = X} = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)whereto : ∀ {x} → ⟦ id ⟧ X x → F.id X xto xs = proj₂ xs _from : ∀ {x} → F.id X x → ⟦ id ⟧ X xfrom x = (_ , λ _ → x)module Constant (ext : ∀ {ℓ} → Extensionality ℓ ℓ) wherecorrect : (X : Pred O ℓ₁) {Y : Pred O ℓ₂} → ⟦ const X ⟧ Y ↔ᵢ F.const X Ycorrect X {Y} = mk↔ₛ′ to from (λ _ → refl) to∘fromwhereto : ⟦ const X ⟧ Y ⊆ Xto = proj₁from : X ⊆ ⟦ const X ⟧ Yfrom = < F.id , F.const ⊥-elim >to∘from : _to∘from xs = cong (proj₁ xs ,_) (ext ⊥-elim)module Duality wherecorrect : (C : Container I O c r) (X : Pred I ℓ) →⟦ C ^⊥ ⟧ X ↔ᵢ (λ o → (c : Command C o) → ∃ λ r → X (next C c r))correct C X = mk↔ₛ′ (λ { (f , g) → < f , g > }) (λ f → proj₁ ⟨∘⟩ f , proj₂ ⟨∘⟩ f)(λ _ → refl) (λ _ → refl)module Composition wherecorrect : (C₁ : Container J K c r) (C₂ : Container I J c r) →{X : Pred I ℓ} → ⟦ C₁ ∘ C₂ ⟧ X ↔ᵢ (⟦ C₁ ⟧ ⟨∘⟩ ⟦ C₂ ⟧) Xcorrect C₁ C₂ {X} = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)whereto : ⟦ C₁ ∘ C₂ ⟧ X ⊆ ⟦ C₁ ⟧ (⟦ C₂ ⟧ X)to ((c , f) , g) = (c , < f , curry g >)from : ⟦ C₁ ⟧ (⟦ C₂ ⟧ X) ⊆ ⟦ C₁ ∘ C₂ ⟧ Xfrom (c , f) = ((c , proj₁ ⟨∘⟩ f) , uncurry (proj₂ ⟨∘⟩ f))module Product (ext : ∀ {ℓ} → Extensionality ℓ ℓ) wherecorrect : (C₁ C₂ : Container I O c r) {X : Pred I _} →⟦ C₁ × C₂ ⟧ X ↔ᵢ (⟦ C₁ ⟧ X ∩ ⟦ C₂ ⟧ X)correct C₁ C₂ {X} = mk↔ₛ′ to from (λ _ → refl) from∘towhereto : ⟦ C₁ × C₂ ⟧ X ⊆ ⟦ C₁ ⟧ X ∩ ⟦ C₂ ⟧ Xto ((c₁ , c₂) , k) = ((c₁ , k ⟨∘⟩ inj₁) , (c₂ , k ⟨∘⟩ inj₂))from : ⟦ C₁ ⟧ X ∩ ⟦ C₂ ⟧ X ⊆ ⟦ C₁ × C₂ ⟧ Xfrom ((c₁ , k₁) , (c₂ , k₂)) = ((c₁ , c₂) , [ k₁ , k₂ ])from∘to : from ⟨∘⟩ to ≗ F.idfrom∘to (c , _) =cong (c ,_) (ext [ (λ _ → refl) , (λ _ → refl) ])module IndexedProduct wherecorrect : (C : X → Container I O c r) {Y : Pred I ℓ} →⟦ Π C ⟧ Y ↔ᵢ ⋂[ x ∶ X ] ⟦ C x ⟧ Ycorrect {X = X} C {Y} = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)whereto : ⟦ Π C ⟧ Y ⊆ ⋂[ x ∶ X ] ⟦ C x ⟧ Yto (c , k) = λ x → (c x , λ r → k (x , r))from : ⋂[ x ∶ X ] ⟦ C x ⟧ Y ⊆ ⟦ Π C ⟧ Yfrom f = (proj₁ ⟨∘⟩ f , uncurry (proj₂ ⟨∘⟩ f))module Sum (ext : ∀ {ℓ₁ ℓ₂} → Extensionality ℓ₁ ℓ₂) wherecorrect : (C₁ C₂ : Container I O c r) {X : Pred I ℓ} →⟦ C₁ ⊎ C₂ ⟧ X ↔ᵢ (⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ X)correct C₁ C₂ {X} = mk↔ₛ′ to from to∘from from∘towhereto : ⟦ C₁ ⊎ C₂ ⟧ X ⊆ ⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ Xto (inj₁ c₁ , k) = inj₁ (c₁ , λ r → k (All.inj₁ r))to (inj₂ c₂ , k) = inj₂ (c₂ , λ r → k (All.inj₂ r))from : ⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ X ⊆ ⟦ C₁ ⊎ C₂ ⟧ Xfrom (inj₁ (c , f)) = inj₁ c , λ{ (All.inj₁ r) → f r}from (inj₂ (c , f)) = inj₂ c , λ{ (All.inj₂ r) → f r}from∘to : from ⟨∘⟩ to ≗ F.idfrom∘to (inj₁ _ , _) = cong (inj₁ _ ,_) (ext λ{ (All.inj₁ r) → refl})from∘to (inj₂ _ , _) = cong (inj₂ _ ,_) (ext λ{ (All.inj₂ r) → refl})to∘from : to ⟨∘⟩ from ≗ F.idto∘from = [ (λ _ → refl) , (λ _ → refl) ]module Sum′ wherecorrect : (C₁ C₂ : Container I O c r) {X : Pred I ℓ} →⟦ C₁ ⊎′ C₂ ⟧ X ↔ᵢ (⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ X)correct C₁ C₂ {X} = mk↔ₛ′ to from to∘from from∘towhereto : ⟦ C₁ ⊎′ C₂ ⟧ X ⊆ ⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ Xto (inj₁ c₁ , k) = inj₁ (c₁ , k)to (inj₂ c₂ , k) = inj₂ (c₂ , k)from : ⟦ C₁ ⟧ X ∪ ⟦ C₂ ⟧ X ⊆ ⟦ C₁ ⊎′ C₂ ⟧ Xfrom = [ Prod.map inj₁ F.id , Prod.map inj₂ F.id ]from∘to : from ⟨∘⟩ to ≗ F.idfrom∘to (inj₁ _ , _) = reflfrom∘to (inj₂ _ , _) = reflto∘from : to ⟨∘⟩ from ≗ F.idto∘from = [ (λ _ → refl) , (λ _ → refl) ]module IndexedSum wherecorrect : (C : X → Container I O c r) {Y : Pred I ℓ} →⟦ Σ C ⟧ Y ↔ᵢ ⋃[ x ∶ X ] ⟦ C x ⟧ Ycorrect {X = X} C {Y} = mk↔ₛ′ to from (λ _ → refl) (λ _ → refl)whereto : ⟦ Σ C ⟧ Y ⊆ ⋃[ x ∶ X ] ⟦ C x ⟧ Yto ((x , c) , k) = (x , (c , k))from : ⋃[ x ∶ X ] ⟦ C x ⟧ Y ⊆ ⟦ Σ C ⟧ Yfrom (x , (c , k)) = ((x , c) , k)module ConstantExponentiation wherecorrect : (C : Container I O c r) {Y : Pred I ℓ} →⟦ const[ X ]⟶ C ⟧ Y ↔ᵢ (⋂ X (F.const (⟦ C ⟧ Y)))correct C {Y} = IndexedProduct.correct (F.const C) {Y}
-------------------------------------------------------------------------- The Agda standard library---- The free monad construction on containers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.FreeMonad whereopen import Level using (Level; _⊔_)open import Data.Sum.Base using (inj₁; inj₂ ; [_,_]′)open import Data.Product.Base using (_,_; -,_)open import Data.Container using (Container; ⟦_⟧; μ)open import Data.Container.Relation.Unary.All using (□; all)open import Data.Container.Combinator using (const; _⊎_)open import Data.W as W using (sup)open import Effect.Functor using (RawFunctor)open import Effect.Applicative using (RawApplicative)open import Effect.Monad using (RawMonad)open import Function.Base as Function using (_$_; _∘_)privatevariablex y s p ℓ : LevelC : Container s pX : Set xY : Set yinfixl 1 _⋆C_infix 1 _⋆_-------------------------------------------------------------------------- The free monad construction over a container and a set is, in-- universal algebra terminology, also known as the term algebra over a-- signature (a container) and a set (of variable symbols). The return-- of the free monad corresponds to variables and the bind operator-- corresponds to (parallel) substitution.-- A useful intuition is to think of containers describing single-- operations and the free monad construction over a container and a set-- describing a tree of operations as nodes and elements of the set as-- leaves. If one starts at the root, then any path will pass finitely-- many nodes (operations described by the container) and eventually end-- up in a leaf (element of the set) -- hence the Kleene star notation-- (the type can be read as a regular expression).-------------------------------------------------------------------------- Type definition-- The free monad can be defined as the least fixpoint `μ (C ⋆C X)`_⋆C_ : ∀ {x s p} → Container s p → Set x → Container (s ⊔ x) pC ⋆C X = const X ⊎ C-- However Agda's positivity checker is currently too weak to observe-- that `X` is used in a strictly positive manner in `μ (C ⋆C X)` as-- demonstrated in #693.-- So we provide instead an inductive definition that we prove to be-- equivalent to the μ-based one.data _⋆_ (C : Container s p) (X : Set x) : Set (x ⊔ s ⊔ p) wherepure : X → C ⋆ Ximpure : ⟦ C ⟧ (C ⋆ X) → C ⋆ X-------------------------------------------------------------------------- Equivalent types-- We can prove that `C ⋆ X` is equivalent to one layer of `C ⋆C X` with-- subterms of tyep `C ⋆ X`.inj : {X : Set x} → ⟦ C ⋆C X ⟧ (C ⋆ X) → C ⋆ Xinj (inj₁ x , _) = pure xinj (inj₂ c , r) = impure (c , r)out : {X : Set x} → C ⋆ X → ⟦ C ⋆C X ⟧ (C ⋆ X)out (pure x) = inj₁ x , λ ()out (impure (c , r)) = inj₂ c , r-- We can fully convert back and forth between `C ⋆ X` and `μ (C ⋆C X)`.toμ : C ⋆ X → μ (C ⋆C X)toμ (pure x) = sup (inj₁ x , λ ())toμ (impure (c , r)) = sup (inj₂ c , toμ ∘ r)fromμ : μ (C ⋆C X) → C ⋆ Xfromμ = W.foldr inj-- We can recover an induction principle similar to the one given in `Data.W`.-- We curry these ones by distinguishing the pure vs. impure casemodule _ (P : C ⋆ X → Set ℓ)(algP : ∀ x → P (pure x))(algI : ∀ {t} → □ C P t → P (impure t)) whereinduction : (t : C ⋆ X) → P tinduction (pure x) = algP xinduction (impure (c , r)) = algI $ all (induction ∘ r)module _ {P : Set ℓ}(algP : X → P)(algI : ⟦ C ⟧ P → P) wherefoldr : C ⋆ X → Pfoldr = induction (Function.const P) algP (algI ∘ -,_ ∘ □.proof)infixr -1 _<$>_ _<*>_infixl 1 _>>=__<$>_ : (X → Y) → C ⋆ X → C ⋆ Yf <$> t = foldr (pure ∘ f) impure t_<*>_ : C ⋆ (X → Y) → C ⋆ X → C ⋆ Ypure f <*> t = f <$> timpure (c , r) <*> t = impure (c , λ v → r v <*> t)_>>=_ : C ⋆ X → (X → C ⋆ Y) → C ⋆ Ypure x >>= f = f ximpure (c , r) >>= f = impure (c , λ v → r v >>= f)-------------------------------------------------------------------------- Structurefunctor : RawFunctor (_⋆_ {x = x} C)functor = record { _<$>_ = _<$>_ }applicative : {C : Container s p} → RawApplicative (_⋆_ {x = x ⊔ s ⊔ p} C)applicative = record{ rawFunctor = functor; pure = pure; _<*>_ = _<*>_ }monad : {C : Container s p} → RawMonad (_⋆_ {x = x ⊔ s ⊔ p} C)monad {x = x} = record{ rawApplicative = applicative {x = x}; _>>=_ = _>>=_}-------------------------------------------------------------------------- DEPRECATIONSrawFunctor = functor{-# WARNING_ON_USAGE rawFunctor"Warning: all rawFunctor deprecated in v2.0.Please use functor instead."#-}rawApplicative = applicative{-# WARNING_ON_USAGE rawApplicative"Warning: rawApplicative was deprecated in v2.0.Please use applicative instead."#-}rawMonad = monad{-# WARNING_ON_USAGE rawMonad"Warning: rawMonad was deprecated in v2.0.Please use monad instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Sized fixpoints of containers, based on the work of Abbott and others------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Data.Container.Fixpoints.Sized whereopen import Level using (Level; _⊔_)open import Size using (Size)open import Codata.Sized.M using (M)open import Data.W.Sized using (W)open import Data.Container hiding (μ) publicprivatevariables p : Level-- The sized least and greatest fixpoints of a container.μ : Container s p → Size → Set (s ⊔ p)μ = Wν : Container s p → Size → Set (s ⊔ p)ν = M
-------------------------------------------------------------------------- The Agda standard library---- Fixpoints for containers - using guardedness------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Data.Container.Fixpoints.Guarded whereopen import Level using (Level; _⊔_)open import Codata.Musical.M using (M)open import Data.Container using (Container)privatevariables p : Level-- The least fixpoint can be found in `Data.Container`open Data.Container publicusing (μ)-- This lives in its own module due to its use of guardedness.ν : Container s p → Set (s ⊔ p)ν C = M C
-------------------------------------------------------------------------- The Agda standard library---- Containers core------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Core whereopen import Level using (Level; _⊔_; suc)open import Data.Product.Base as Product using (Σ-syntax)open import Function.Base using (_∘_; _∘′_)open import Function.Bundles using (Inverse; _↔_)open import Relation.Unary using (Pred; _⊆_)-- Definition of Containersinfix 5 _▷_record Container (s p : Level) : Set (suc (s ⊔ p)) whereconstructor _▷_fieldShape : Set sPosition : Shape → Set popen Container public-- The semantics ("extension") of a container.⟦_⟧ : ∀ {s p ℓ} → Container s p → Set ℓ → Set (s ⊔ p ⊔ ℓ)⟦ S ▷ P ⟧ X = Σ[ s ∈ S ] (P s → X)-- The extension is a functormap : ∀ {s p x y} {C : Container s p} {X : Set x} {Y : Set y} →(X → Y) → ⟦ C ⟧ X → ⟦ C ⟧ Ymap f = Product.map₂ (f ∘_)-- Representation of container morphisms.infixr 8 _⇒_ _⊸_record _⇒_ {s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂): Set (s₁ ⊔ s₂ ⊔ p₁ ⊔ p₂) whereconstructor _▷_fieldshape : Shape C₁ → Shape C₂position : ∀ {s} → Position C₂ (shape s) → Position C₁ s⟪_⟫ : ∀ {x} {X : Set x} → ⟦ C₁ ⟧ X → ⟦ C₂ ⟧ X⟪_⟫ = Product.map shape (_∘′ position)open _⇒_ public-- Linear container morphismsrecord _⊸_ {s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂): Set (s₁ ⊔ s₂ ⊔ p₁ ⊔ p₂) wherefieldshape⊸ : Shape C₁ → Shape C₂position⊸ : ∀ {s} → Position C₂ (shape⊸ s) ↔ Position C₁ smorphism : C₁ ⇒ C₂morphism = record{ shape = shape⊸; position = Inverse.to position⊸}⟪_⟫⊸ : ∀ {x} {X : Set x} → ⟦ C₁ ⟧ X → ⟦ C₂ ⟧ X⟪_⟫⊸ = ⟪ morphism ⟫open _⊸_ public using (shape⊸; position⊸; ⟪_⟫⊸)
-------------------------------------------------------------------------- The Agda standard library---- Container combinators------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Combinator whereopen import Level using (Level; _⊔_; lower)open import Data.Empty.Polymorphic using (⊥; ⊥-elim)open import Data.Product.Base as Product using (_,_; <_,_>; proj₁; proj₂; ∃)open import Data.Sum.Base as Sum using ([_,_]′)open import Data.Unit.Polymorphic.Base using (⊤)import Function.Base as Fopen import Data.Container.Coreopen import Data.Container.Relation.Unary.Any-------------------------------------------------------------------------- Combinatorsmodule _ {s p : Level} where-- Identity.id : Container s pid .Shape = ⊤id .Position = F.const ⊤to-id : ∀ {a} {A : Set a} → F.id A → ⟦ id ⟧ Ato-id x = (_ , λ _ → x)from-id : ∀ {a} {A : Set a} → ⟦ id ⟧ A → F.id Afrom-id xs = proj₂ xs _-- Constant.const : Set s → Container s pconst A .Shape = Aconst A .Position = F.const ⊥to-const : ∀ {b} (A : Set s) {B : Set b} → A → ⟦ const A ⟧ Bto-const _ = _, ⊥-elim {Whatever = F.const _}from-const : ∀ {b} (A : Set s) {B : Set b} → ⟦ const A ⟧ B → Afrom-const _ = proj₁module _ {s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂) where-- Composition.infixr 9 _∘__∘_ : Container (s₁ ⊔ s₂ ⊔ p₁) (p₁ ⊔ p₂)_∘_ .Shape = ⟦ C₁ ⟧ (Shape C₂)_∘_ .Position = ◇ C₁ (Position C₂)to-∘ : ∀ {a} {A : Set a} → ⟦ C₁ ⟧ (⟦ C₂ ⟧ A) → ⟦ _∘_ ⟧ Ato-∘ (s , f) = ((s , proj₁ F.∘ f) , Product.uncurry (proj₂ F.∘ f) F.∘′ ◇.proof)from-∘ : ∀ {a} {A : Set a} → ⟦ _∘_ ⟧ A → ⟦ C₁ ⟧ (⟦ C₂ ⟧ A)from-∘ ((s , f) , g) = (s , < f , Product.curry (g F.∘′ any) >)-- Product. (Note that, up to isomorphism, this is a special case of-- indexed product.)infixr 2 _×__×_ : Container (s₁ ⊔ s₂) (p₁ ⊔ p₂)_×_ .Shape = Shape C₁ Product.× Shape C₂_×_ .Position = Product.uncurry λ s₁ s₂ → (Position C₁ s₁) Sum.⊎ (Position C₂ s₂)to-× : ∀ {a} {A : Set a} → ⟦ C₁ ⟧ A Product.× ⟦ C₂ ⟧ A → ⟦ _×_ ⟧ Ato-× ((s₁ , f₁) , (s₂ , f₂)) = ((s₁ , s₂) , [ f₁ , f₂ ]′)from-× : ∀ {a} {A : Set a} → ⟦ _×_ ⟧ A → ⟦ C₁ ⟧ A Product.× ⟦ C₂ ⟧ Afrom-× ((s₁ , s₂) , f) = ((s₁ , f F.∘ Sum.inj₁) , (s₂ , f F.∘ Sum.inj₂))-- Indexed product.module _ {i s p} (I : Set i) (Cᵢ : I → Container s p) whereΠ : Container (i ⊔ s) (i ⊔ p)Π .Shape = ∀ i → Shape (Cᵢ i)Π .Position = λ s → ∃ λ i → Position (Cᵢ i) (s i)to-Π : ∀ {a} {A : Set a} → (∀ i → ⟦ Cᵢ i ⟧ A) → ⟦ Π ⟧ Ato-Π f = (proj₁ F.∘ f , Product.uncurry (proj₂ F.∘ f))from-Π : ∀ {a} {A : Set a} → ⟦ Π ⟧ A → ∀ i → ⟦ Cᵢ i ⟧ Afrom-Π (s , f) = λ i → (s i , λ p → f (i , p))-- Constant exponentiation. (Note that this is a special case of-- indexed product.)infix 0 const[_]⟶_const[_]⟶_ : ∀ {i s p} → Set i → Container s p → Container (i ⊔ s) (i ⊔ p)const[ A ]⟶ C = Π A (F.const C)-- Sum. (Note that, up to isomorphism, this is a special case of-- indexed sum.)module _ {s₁ s₂ p} (C₁ : Container s₁ p) (C₂ : Container s₂ p) whereinfixr 1 _⊎__⊎_ : Container (s₁ ⊔ s₂) p_⊎_ .Shape = (Shape C₁ Sum.⊎ Shape C₂)_⊎_ .Position = [ Position C₁ , Position C₂ ]′to-⊎ : ∀ {a} {A : Set a} → ⟦ C₁ ⟧ A Sum.⊎ ⟦ C₂ ⟧ A → ⟦ _⊎_ ⟧ Ato-⊎ = [ Product.map Sum.inj₁ F.id , Product.map Sum.inj₂ F.id ]′from-⊎ : ∀ {a} {A : Set a} → ⟦ _⊎_ ⟧ A → ⟦ C₁ ⟧ A Sum.⊎ ⟦ C₂ ⟧ Afrom-⊎ (Sum.inj₁ s₁ , f) = Sum.inj₁ (s₁ , f)from-⊎ (Sum.inj₂ s₂ , f) = Sum.inj₂ (s₂ , f)-- Indexed sum.module _ {i s p} (I : Set i) (C : I → Container s p) whereΣ : Container (i ⊔ s) pΣ .Shape = ∃ λ i → Shape (C i)Σ .Position = λ s → Position (C (proj₁ s)) (proj₂ s)to-Σ : ∀ {a} {A : Set a} → (∃ λ i → ⟦ C i ⟧ A) → ⟦ Σ ⟧ Ato-Σ (i , (s , f)) = ((i , s) , f)from-Σ : ∀ {a} {A : Set a} → ⟦ Σ ⟧ A → ∃ λ i → ⟦ C i ⟧ Afrom-Σ ((i , s) , f) = (i , (s , f))
-------------------------------------------------------------------------- The Agda standard library---- Correctness proofs for container combinators------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Combinator.Properties whereopen import Axiom.Extensionality.Propositional using (Extensionality)open import Data.Container.Core using (Container; ⟦_⟧)open import Data.Container.Combinatoropen import Data.Empty using (⊥-elim)open import Data.Product.Base as P using (∃; _,_; proj₁; proj₂; <_,_>; uncurry; curry)open import Data.Sum.Base as S using (inj₁; inj₂; [_,_]′; [_,_])open import Function.Base as F using (_∘′_)open import Function.Bundles using (_↔_; mk↔ₛ′)open import Level using (_⊔_; lower)open import Relation.Binary.PropositionalEquality.Core using (_≡_; _≗_; refl; cong)-- I have proved some of the correctness statements under the-- assumption of functional extensionality. I could have reformulated-- the statements using suitable setoids, but I could not be bothered.module Identity wherecorrect : ∀ {s p x} {X : Set x} → ⟦ id {s} {p} ⟧ X ↔ F.id Xcorrect {X = X} = mk↔ₛ′ from-id to-id (λ _ → refl) (λ _ → refl)module Constant (ext : ∀ {ℓ ℓ′} → Extensionality ℓ ℓ′) wherecorrect : ∀ {x p y} (X : Set x) {Y : Set y} → ⟦ const {x} {p ⊔ y} X ⟧ Y ↔ F.const X Ycorrect {x} {y} X {Y} = mk↔ₛ′ (from-const X) (to-const X) (λ _ → refl) from∘towherefrom∘to : (x : ⟦ const X ⟧ Y) → to-const X (proj₁ x) ≡ xfrom∘to xs = cong (proj₁ xs ,_) (ext (λ x → ⊥-elim (lower x)))module Composition {s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂) wherecorrect : ∀ {x} {X : Set x} → ⟦ C₁ ∘ C₂ ⟧ X ↔ (⟦ C₁ ⟧ F.∘ ⟦ C₂ ⟧) Xcorrect {X = X} = mk↔ₛ′ (from-∘ C₁ C₂) (to-∘ C₁ C₂) (λ _ → refl) (λ _ → refl)module Product (ext : ∀ {ℓ ℓ′} → Extensionality ℓ ℓ′){s₁ s₂ p₁ p₂} (C₁ : Container s₁ p₁) (C₂ : Container s₂ p₂) wherecorrect : ∀ {x} {X : Set x} → ⟦ C₁ × C₂ ⟧ X ↔ (⟦ C₁ ⟧ X P.× ⟦ C₂ ⟧ X)correct {X = X} = mk↔ₛ′ (from-× C₁ C₂) (to-× C₁ C₂) (λ _ → refl) from∘towherefrom∘to : (to-× C₁ C₂) F.∘ (from-× C₁ C₂) ≗ F.idfrom∘to (s , f) =cong (s ,_) (ext [ (λ _ → refl) , (λ _ → refl) ])module IndexedProduct {i s p} {I : Set i} (Cᵢ : I → Container s p) wherecorrect : ∀ {x} {X : Set x} → ⟦ Π I Cᵢ ⟧ X ↔ (∀ i → ⟦ Cᵢ i ⟧ X)correct {X = X} = mk↔ₛ′ (from-Π I Cᵢ) (to-Π I Cᵢ) (λ _ → refl) (λ _ → refl)module Sum {s₁ s₂ p} (C₁ : Container s₁ p) (C₂ : Container s₂ p) wherecorrect : ∀ {x} {X : Set x} → ⟦ C₁ ⊎ C₂ ⟧ X ↔ (⟦ C₁ ⟧ X S.⊎ ⟦ C₂ ⟧ X)correct {X = X} = mk↔ₛ′ (from-⊎ C₁ C₂) (to-⊎ C₁ C₂) to∘from from∘towherefrom∘to : (to-⊎ C₁ C₂) F.∘ (from-⊎ C₁ C₂) ≗ F.idfrom∘to (inj₁ s₁ , f) = reflfrom∘to (inj₂ s₂ , f) = reflto∘from : (from-⊎ C₁ C₂) F.∘ (to-⊎ C₁ C₂) ≗ F.idto∘from = [ (λ _ → refl) , (λ _ → refl) ]module IndexedSum {i s p} {I : Set i} (C : I → Container s p) wherecorrect : ∀ {x} {X : Set x} → ⟦ Σ I C ⟧ X ↔ (∃ λ i → ⟦ C i ⟧ X)correct {X = X} = mk↔ₛ′ (from-Σ I C) (to-Σ I C) (λ _ → refl) (λ _ → refl)module ConstantExponentiation {i s p} {I : Set i} (C : Container s p) wherecorrect : ∀ {x} {X : Set x} → ⟦ const[ I ]⟶ C ⟧ X ↔ (I → ⟦ C ⟧ X)correct = IndexedProduct.correct (F.const C)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- Data.Container.Relation.Unary.Any directly.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Container.Any whereopen import Data.Container.Relation.Unary.Any publicopen import Data.Container.Relation.Unary.Any.Properties public
-------------------------------------------------------------------------- The Agda standard library---- Characters------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Char where-------------------------------------------------------------------------- Re-export base definitions and decidability of equalityopen import Data.Char.Base publicopen import Data.Char.Propertiesusing (_≈?_; _≟_; _<?_; _≤?_; _==_) public
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on characters------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Char.Properties whereopen import Data.Bool.Base using (Bool)open import Data.Char.Baseimport Data.Nat.Base as ℕimport Data.Nat.Properties as ℕopen import Data.Product.Base using (_,_)open import Function.Baseopen import Relation.Nullary using (¬_; yes; no)open import Relation.Nullary.Decidable using (map′; isYes)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; StrictPartialOrder; StrictTotalOrder; Preorder; Poset; DecPoset)open import Relation.Binary.Structuresusing (IsDecEquivalence; IsStrictPartialOrder; IsStrictTotalOrder; IsPreorder; IsPartialOrder; IsDecPartialOrder; IsEquivalence)open import Relation.Binary.Definitionsusing (Decidable; DecidableEquality; Trichotomous; Irreflexive; Transitive; Asymmetric; Antisymmetric; Symmetric; Substitutive; Reflexive; tri<; tri≈; tri>)import Relation.Binary.Construct.On as Onimport Relation.Binary.Construct.Subst.Equality as Substimport Relation.Binary.Construct.Closure.Reflexive as Reflimport Relation.Binary.Construct.Closure.Reflexive.Properties as Reflopen import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; refl; cong; sym; trans; subst)import Relation.Binary.PropositionalEquality.Properties as ≡-------------------------------------------------------------------------- Primitive propertiesopen import Agda.Builtin.Char.Propertiesrenaming ( primCharToNatInjective to toℕ-injective)public-------------------------------------------------------------------------- Properties of _≈_≈⇒≡ : _≈_ ⇒ _≡_≈⇒≡ = toℕ-injective _ _≉⇒≢ : _≉_ ⇒ _≢_≉⇒≢ p refl = p refl≈-reflexive : _≡_ ⇒ _≈_≈-reflexive = cong toℕ-------------------------------------------------------------------------- Properties of _≡_infix 4 _≟__≟_ : DecidableEquality Charx ≟ y = map′ ≈⇒≡ ≈-reflexive (toℕ x ℕ.≟ toℕ y)setoid : Setoid _ _setoid = ≡.setoid ChardecSetoid : DecSetoid _ _decSetoid = ≡.decSetoid _≟_isDecEquivalence : IsDecEquivalence _≡_isDecEquivalence = ≡.isDecEquivalence _≟_-------------------------------------------------------------------------- Boolean equality test.---- Why is the definition _==_ = primCharEquality not used? One reason-- is that the present definition can sometimes improve type-- inference, at least with the version of Agda that is current at the-- time of writing: see unit-test below.infix 4 _==__==_ : Char → Char → Boolc₁ == c₂ = isYes (c₁ ≟ c₂)private-- The following unit test does not type-check (at the time of-- writing) if _==_ is replaced by primCharEquality.data P : (Char → Bool) → Set whereMkP : (c : Char) → P (c ==_)unit-test : P ('x' ==_)unit-test = MkP _-------------------------------------------------------------------------- Properties of _<_infix 4 _<?__<?_ : Decidable _<__<?_ = On.decidable toℕ ℕ._<_ ℕ._<?_<-cmp : Trichotomous _≡_ _<_<-cmp c d with ℕ.<-cmp (toℕ c) (toℕ d)... | tri< lt ¬eq ¬gt = tri< lt (≉⇒≢ ¬eq) ¬gt... | tri≈ ¬lt eq ¬gt = tri≈ ¬lt (≈⇒≡ eq) ¬gt... | tri> ¬lt ¬eq gt = tri> ¬lt (≉⇒≢ ¬eq) gt<-irrefl : Irreflexive _≡_ _<_<-irrefl = ℕ.<-irrefl ∘′ cong toℕ<-trans : Transitive _<_<-trans {c} {d} {e} = On.transitive toℕ ℕ._<_ ℕ.<-trans {c} {d} {e}<-asym : Asymmetric _<_<-asym {c} {d} = On.asymmetric toℕ ℕ._<_ ℕ.<-asym {c} {d}<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = ≡.isEquivalence; irrefl = <-irrefl; trans = λ {a} {b} {c} → <-trans {a} {b} {c}; <-resp-≈ = (λ {c} → ≡.subst (c <_)), (λ {c} → ≡.subst (_< c))}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}<-strictPartialOrder : StrictPartialOrder _ _ _<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder _ _ _<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}-------------------------------------------------------------------------- Properties of _≤_infix 4 _≤?__≤?_ : Decidable _≤__≤?_ = Refl.decidable <-cmp≤-reflexive : _≡_ ⇒ _≤_≤-reflexive = Refl.reflexive≤-trans : Transitive _≤_≤-trans = Refl.trans (λ {a} {b} {c} → <-trans {a} {b} {c})≤-antisym : Antisymmetric _≡_ _≤_≤-antisym = Refl.antisym _≡_ refl ℕ.<-asym≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = ≡.isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isDecPartialOrder : IsDecPartialOrder _≡_ _≤_≤-isDecPartialOrder = record{ isPartialOrder = ≤-isPartialOrder; _≟_ = _≟_; _≤?_ = _≤?_}≤-preorder : Preorder _ _ _≤-preorder = record { isPreorder = ≤-isPreorder }≤-poset : Poset _ _ _≤-poset = record { isPartialOrder = ≤-isPartialOrder }≤-decPoset : DecPoset _ _ _≤-decPoset = record { isDecPartialOrder = ≤-isDecPartialOrder }-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.5≈-refl : Reflexive _≈_≈-refl = refl{-# WARNING_ON_USAGE ≈-refl"Warning: ≈-refl was deprecated in v1.5.Please use Propositional Equality's refl instead."#-}≈-sym : Symmetric _≈_≈-sym = sym{-# WARNING_ON_USAGE ≈-sym"Warning: ≈-sym was deprecated in v1.5.Please use Propositional Equality's sym instead."#-}≈-trans : Transitive _≈_≈-trans = trans{-# WARNING_ON_USAGE ≈-trans"Warning: ≈-trans was deprecated in v1.5.Please use Propositional Equality's trans instead."#-}≈-subst : ∀ {ℓ} → Substitutive _≈_ ℓ≈-subst P x≈y p = subst P (≈⇒≡ x≈y) p{-# WARNING_ON_USAGE ≈-subst"Warning: ≈-subst was deprecated in v1.5.Please use Propositional Equality's subst instead."#-}infix 4 _≈?__≈?_ : Decidable _≈_x ≈? y = toℕ x ℕ.≟ toℕ y≈-isEquivalence : IsEquivalence _≈_≈-isEquivalence = record{ refl = refl; sym = sym; trans = trans}≈-setoid : Setoid _ _≈-setoid = record{ isEquivalence = ≈-isEquivalence}≈-isDecEquivalence : IsDecEquivalence _≈_≈-isDecEquivalence = record{ isEquivalence = ≈-isEquivalence; _≟_ = _≈?_}≈-decSetoid : DecSetoid _ _≈-decSetoid = record{ isDecEquivalence = ≈-isDecEquivalence}{-# WARNING_ON_USAGE _≈?_"Warning: _≈?_ was deprecated in v1.5.Please use _≟_ instead."#-}{-# WARNING_ON_USAGE ≈-isEquivalence"Warning: ≈-isEquivalence was deprecated in v1.5.Please use Propositional Equality's isEquivalence instead."#-}{-# WARNING_ON_USAGE ≈-setoid"Warning: ≈-setoid was deprecated in v1.5.Please use Propositional Equality's setoid instead."#-}{-# WARNING_ON_USAGE ≈-isDecEquivalence"Warning: ≈-isDecEquivalence was deprecated in v1.5.Please use Propositional Equality's isDecEquivalence instead."#-}{-# WARNING_ON_USAGE ≈-decSetoid"Warning: ≈-decSetoid was deprecated in v1.5.Please use Propositional Equality's decSetoid instead."#-}≡-setoid : Setoid _ _≡-setoid = setoid{-# WARNING_ON_USAGE ≡-setoid"Warning: ≡-setoid was deprecated in v1.5.Please use setoid instead."#-}≡-decSetoid : DecSetoid _ _≡-decSetoid = decSetoid{-# WARNING_ON_USAGE ≡-decSetoid"Warning: ≡-decSetoid was deprecated in v1.5.Please use decSetoid instead."#-}<-isStrictPartialOrder-≈ : IsStrictPartialOrder _≈_ _<_<-isStrictPartialOrder-≈ = On.isStrictPartialOrder toℕ ℕ.<-isStrictPartialOrder{-# WARNING_ON_USAGE <-isStrictPartialOrder-≈"Warning: <-isStrictPartialOrder-≈ was deprecated in v1.5.Please use <-isStrictPartialOrder instead."#-}<-isStrictTotalOrder-≈ : IsStrictTotalOrder _≈_ _<_<-isStrictTotalOrder-≈ = On.isStrictTotalOrder toℕ ℕ.<-isStrictTotalOrder{-# WARNING_ON_USAGE <-isStrictTotalOrder-≈"Warning: <-isStrictTotalOrder-≈ was deprecated in v1.5.Please use <-isStrictTotalOrder instead."#-}<-strictPartialOrder-≈ : StrictPartialOrder _ _ _<-strictPartialOrder-≈ = On.strictPartialOrder ℕ.<-strictPartialOrder toℕ{-# WARNING_ON_USAGE <-strictPartialOrder-≈"Warning: <-strictPartialOrder-≈ was deprecated in v1.5.Please use <-strictPartialOrder instead."#-}<-strictTotalOrder-≈ : StrictTotalOrder _ _ _<-strictTotalOrder-≈ = On.strictTotalOrder ℕ.<-strictTotalOrder toℕ{-# WARNING_ON_USAGE <-strictTotalOrder-≈"Warning: <-strictTotalOrder-≈ was deprecated in v1.5.Please use <-strictTotalOrder instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Instances for characters------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Char.Instances whereopen import Data.Char.PropertiesinstanceChar-≡-isDecEquivalence = isDecEquivalence
-------------------------------------------------------------------------- The Agda standard library---- Basic definitions for Characters------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Char.Base whereopen import Level using (zero)import Data.Nat.Base as ℕopen import Data.Bool.Base using (Bool)open import Function.Base using (_on_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.Construct.Closure.Reflexive-------------------------------------------------------------------------- Re-export the type, and renamed primitivesopen import Agda.Builtin.Char public using ( Char )renaming-- testing( primIsLower to isLower; primIsDigit to isDigit; primIsAlpha to isAlpha; primIsSpace to isSpace; primIsAscii to isAscii; primIsLatin1 to isLatin1; primIsPrint to isPrint; primIsHexDigit to isHexDigit-- transforming; primToUpper to toUpper; primToLower to toLower-- converting; primCharToNat to toℕ; primNatToChar to fromℕ)open import Agda.Builtin.String public using ()renaming ( primShowChar to show )infix 4 _≈_ _≉__≈_ : Rel Char zero_≈_ = _≡_ on toℕ_≉_ : Rel Char zero_≉_ = _≢_ on toℕinfix 4 _≈ᵇ__≈ᵇ_ : (c d : Char) → Boolc ≈ᵇ d = toℕ c ℕ.≡ᵇ toℕ dinfix 4 _<__<_ : Rel Char zero_<_ = ℕ._<_ on toℕinfix 4 _≤__≤_ : Rel Char zero_≤_ = ReflClosure _<_
-------------------------------------------------------------------------- The Agda standard library---- Primitive bytestrings: simple bindings to Haskell types and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Bytestring.Primitive whereopen import Agda.Builtin.Nat using (Nat)open import Agda.Builtin.String using (String)open import Agda.Builtin.Word using (Word64)open import Data.Word8.Primitive using (Word8)-- NB: the bytestring package uses `Int` as the indexing type which-- Haskell's base specifies as:---- > A fixed-precision integer type with at least the range-- > [-2^29 .. 2^29-1]. The exact range for a given implementation-- > can be determined by using minBound and maxBound from the-- > Bounded class.---- There is no ergonomic way to encode that in a type-safe manner.-- For now we use `Word64` with the understanding that using indices-- greater than 2^29-1 may lead to undefined behaviours...postulateBytestring : Setindex : Bytestring → Word64 → Word8length : Bytestring → Nattake : Word64 → Bytestring → Bytestringdrop : Word64 → Bytestring → Bytestringshow : Bytestring → String{-# FOREIGN GHC import qualified Data.ByteString as B #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# COMPILE GHC Bytestring = type B.ByteString #-}{-# COMPILE GHC index = \ buf idx -> B.index buf (fromIntegral idx) #-}{-# COMPILE GHC length = \ buf -> fromIntegral (B.length buf) #-}{-# COMPILE GHC take = B.take . fromIntegral #-}{-# COMPILE GHC drop = B.drop . fromIntegral #-}{-# COMPILE GHC show = T.pack . Prelude.show #-}
-------------------------------------------------------------------------- The Agda standard library---- Bytestrings: IO operations------------------------------------------------------------------------{-# OPTIONS --guardedness --cubical-compatible #-}module Data.Bytestring.IO whereopen import Agda.Builtin.Stringopen import IO using (IO; lift)open import Data.Bytestring.Base using (Bytestring)open import Data.Unit.Base using (⊤)import Data.Bytestring.IO.Primitive as PrimreadFile : String → IO BytestringreadFile fp = lift (Prim.readFile fp)writeFile : String → Bytestring → IO ⊤writeFile fp str = lift (Prim.writeFile fp str)
-------------------------------------------------------------------------- The Agda standard library---- Primitive Bytestrings: IO operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Bytestring.IO.Primitive whereopen import Agda.Builtin.String using (String)open import Agda.Builtin.Unit using (⊤)open import IO.Primitive.Core using (IO)open import Data.Bytestring.PrimitivepostulatereadFile : String → IO BytestringwriteFile : String → Bytestring → IO ⊤{-# FOREIGN GHC import qualified Data.Text as T #-}{-# FOREIGN GHC import Data.ByteString #-}{-# COMPILE GHC readFile = Data.ByteString.readFile . T.unpack #-}{-# COMPILE GHC writeFile = Data.ByteString.writeFile . T.unpack #-}
-------------------------------------------------------------------------- The Agda standard library---- Primitive Bytestrings: builder type and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Bytestring.Builder.Primitive whereopen import Agda.Builtin.Natopen import Agda.Builtin.Stringopen import Data.Word8.Primitiveopen import Data.Bytestring.Primitive using (Bytestring)infixr 6 _<>_postulate-- Builder and executionBuilder : SettoBytestring : Builder → Bytestring-- Assembling a builderbytestring : Bytestring → Builderword8 : Word8 → Builderempty : Builder_<>_ : Builder → Builder → Builder{-# FOREIGN GHC import qualified Data.ByteString.Builder as Builder #-}{-# FOREIGN GHC import qualified Data.ByteString.Lazy as Lazy #-}{-# FOREIGN GHC import qualified Data.Text as T #-}{-# COMPILE GHC Builder = type Builder.Builder #-}{-# COMPILE GHC toBytestring = Lazy.toStrict . Builder.toLazyByteString #-}{-# COMPILE GHC bytestring = Builder.byteString #-}{-# COMPILE GHC word8 = Builder.word8 #-}{-# COMPILE GHC empty = mempty #-}{-# COMPILE GHC _<>_ = mappend #-}
-------------------------------------------------------------------------- The Agda standard library---- Bytestrings: builder type and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Bytestring.Builder.Base whereopen import Data.Nat.Base using (ℕ; zero; suc; _/_; _%_; _^_)open import Data.Word8.Base as Word8 using (Word8)open import Data.Word64.Base as Word64 using (Word64)open import Function.Base using (_∘′_)-------------------------------------------------------------------------------- Re-export type and operationsopen import Data.Bytestring.Builder.Primitive as Prim publicusing ( Builder; toBytestring; bytestring; word8; empty; _<>_)-------------------------------------------------------------------------------- High-level combinatorsmodule List whereopen import Data.List.Base as List using (List)concat : List Builder → Builderconcat = List.foldr _<>_ emptymodule Vec whereopen import Data.Vec.Base as Vec using (Vec)concat : ∀ {n} → Vec Builder n → Builderconcat = Vec.foldr′ _<>_ emptyopen Vec-------------------------------------------------------------------------------- Generic word-specific combinatorsopen import Data.Vec.Base as Vec using (Vec; []; _∷_)wordN : ∀ {n} → Vec Word8 n → BuilderwordN = concat ∘′ Vec.map word8toWord8sLE : ∀ {w} {W : Set w} (n : ℕ) (toℕ : W → ℕ) → W → Vec Word8 ntoWord8sLE n toℕ w = loop (toℕ w) n whereloop : ℕ → (n : ℕ) → Vec Word8 nloop acc 0 = []loop acc 1 = Word8.fromℕ acc ∷ []loop acc (suc n) = Word8.fromℕ (acc % 2 ^ 8) ∷ loop (acc / 2 ^ 8) ntoWord8sBE : ∀ {w} {W : Set w} (n : ℕ) (toℕ : W → ℕ) → W → Vec Word8 ntoWord8sBE n toℕ w = Vec.reverse (toWord8sLE n toℕ w)-------------------------------------------------------------------------------- Builders for Word64word64LE : Word64 → Builderword64LE w = wordN (toWord8sLE 8 Word64.toℕ w)word64BE : Word64 → Builderword64BE w = wordN (toWord8sBE 8 Word64.toℕ w)
-------------------------------------------------------------------------- The Agda standard library---- Bytestrings: simple types and functions-- Note that these functions do not perform bound checks.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module Data.Bytestring.Base whereopen import Data.Nat.Base using (ℕ; _+_; _*_; _^_)open import Agda.Builtin.String using (String)import Data.Fin.Base as Finopen import Data.Vec.Base as Vec using (Vec)open import Data.Word8.Base as Word8 using (Word8)open import Data.Word64.Base as Word64 using (Word64)open import Function.Base using (const; _$_)-------------------------------------------------------------------------------- Re-export type and operationsopen import Data.Bytestring.Primitive as Prim publicusing ( Bytestring; length; take; drop; show)renaming (index to getWord8)-------------------------------------------------------------------------------- Operationsslice : Word64 → Word64 → Bytestring → Bytestringslice start chunk buf = take chunk (drop start buf)-------------------------------------------------------------------------------- Generic combinators for fixed-size encodingsgetWord8s : (n : ℕ) → Bytestring → Word64 → Vec Word8 ngetWord8s n buf idx= let idx = Word64.toℕ idx inVec.map (λ k → getWord8 buf (Word64.fromℕ (idx + Fin.toℕ k)))$ Vec.allFin n-- Little endian representation:-- Low place values firstfromWord8sLE : ∀ {n w} {W : Set w} → (fromℕ : ℕ → W) → Vec Word8 n → WfromWord8sLE f ws = f (Vec.foldr′ (λ w acc → Word8.toℕ w + acc * (2 ^ 8)) 0 ws)-- Big endian representation-- Big place values firstfromWord8sBE : ∀ {n w} {W : Set w} → (fromℕ : ℕ → W) → Vec Word8 n → WfromWord8sBE f ws = f (Vec.foldl′ (λ acc w → acc * (2 ^ 8) + Word8.toℕ w) 0 ws)-------------------------------------------------------------------------------- Decoding to a vector of bytestoWord8s : (b : Bytestring) → Vec Word8 (length b)toWord8s b = getWord8s _ b (Word64.fromℕ 0)-------------------------------------------------------------------------------- Getting Word64getWord64LE : Bytestring → Word64 → Word64getWord64LE buf idx= fromWord8sLE Word64.fromℕ (getWord8s 8 buf idx)getWord64BE : Bytestring → Word64 → Word64getWord64BE buf idx= fromWord8sBE Word64.fromℕ (getWord8s 8 buf idx)
-------------------------------------------------------------------------- The Agda standard library---- Booleans------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool where-------------------------------------------------------------------------- The boolean type and some operationsopen import Data.Bool.Base public-------------------------------------------------------------------------- Publicly re-export queriesopen import Data.Bool.Properties publicusing (T?; _≟_; _≤?_; _<?_)
-------------------------------------------------------------------------- The Agda standard library---- Automatic solvers for equations over booleans-------------------------------------------------------------------------- See README.Data.Nat for examples of how to use similar solvers{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool.Solver whereimport Algebra.Solver.Ring.Simple as Solverimport Algebra.Solver.Ring.AlmostCommutativeRing as ACRopen import Data.Bool.Properties-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _∨_ and _∧_module ∨-∧-Solver =Solver (ACR.fromCommutativeSemiring ∨-∧-commutativeSemiring) _≟_-------------------------------------------------------------------------- A module for automatically solving propositional equivalences-- containing _xor_ and _∧_module xor-∧-Solver =Solver (ACR.fromCommutativeRing xor-∧-commutativeRing) _≟_
-------------------------------------------------------------------------- The Agda standard library---- Showing booleans------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool.Show whereopen import Data.Bool.Base using (Bool; false; true)open import Data.Char.Base using (Char)open import Data.String.Base using (String)show : Bool → Stringshow true = "true"show false = "false"showBit : Bool → CharshowBit true = '1'showBit false = '0'
-------------------------------------------------------------------------- The Agda standard library---- A bunch of properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool.Properties whereopen import Algebra.Bundlesopen import Algebra.Lattice.Bundlesimport Algebra.Lattice.Properties.BooleanAlgebra as BooleanAlgebraPropertiesopen import Data.Bool.Baseopen import Data.Emptyopen import Data.Product.Base using (_×_; _,_; proj₁; proj₂)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])open import Function.Base using (_⟨_⟩_; const; id)open import Function.Bundles hiding (LeftInverse; RightInverse; Inverse)open import Induction.WellFounded using (WellFounded; Acc; acc)open import Level using (Level; 0ℓ)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Structuresusing (IsPreorder; IsPartialOrder; IsTotalOrder; IsDecTotalOrder; IsStrictPartialOrder; IsStrictTotalOrder)open import Relation.Binary.Bundlesusing (Setoid; DecSetoid; Poset; Preorder; TotalOrder; DecTotalOrder; StrictPartialOrder; StrictTotalOrder)open import Relation.Binary.Definitionsusing (Decidable; DecidableEquality; Reflexive; Transitive; Antisymmetric; Minimum; Maximum; Total; Irrelevant; Irreflexive; Asymmetric; Trans; Trichotomous; tri≈; tri<; tri>; _Respects₂_)open import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesopen import Relation.Nullary.Decidable.Core using (True; yes; no; fromWitness)import Relation.Unary as Uopen import Algebra.Definitions {A = Bool} _≡_open import Algebra.Structures {A = Bool} _≡_open import Algebra.Lattice.Structures {A = Bool} _≡_open ≡-Reasoningprivatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- Properties of _≡_infix 4 _≟__≟_ : DecidableEquality Booltrue ≟ true = yes reflfalse ≟ false = yes refltrue ≟ false = no λ()false ≟ true = no λ()≡-setoid : Setoid 0ℓ 0ℓ≡-setoid = setoid Bool≡-decSetoid : DecSetoid 0ℓ 0ℓ≡-decSetoid = decSetoid _≟_-------------------------------------------------------------------------- Properties of _≤_-- Relational properties≤-reflexive : _≡_ ⇒ _≤_≤-reflexive refl = b≤b≤-refl : Reflexive _≤_≤-refl = ≤-reflexive refl≤-trans : Transitive _≤_≤-trans b≤b p = p≤-trans f≤t b≤b = f≤t≤-antisym : Antisymmetric _≡_ _≤_≤-antisym b≤b _ = refl≤-minimum : Minimum _≤_ false≤-minimum false = b≤b≤-minimum true = f≤t≤-maximum : Maximum _≤_ true≤-maximum false = f≤t≤-maximum true = b≤b≤-total : Total _≤_≤-total false b = inj₁ (≤-minimum b)≤-total true b = inj₂ (≤-maximum b)infix 4 _≤?__≤?_ : Decidable _≤_false ≤? b = yes (≤-minimum b)true ≤? false = no λ ()true ≤? true = yes b≤b≤-irrelevant : Irrelevant _≤_≤-irrelevant {_} f≤t f≤t = refl≤-irrelevant {false} b≤b b≤b = refl≤-irrelevant {true} b≤b b≤b = refl-- Structures≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isPartialOrder = record{ isPreorder = ≤-isPreorder; antisym = ≤-antisym}≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isTotalOrder = record{ isPartialOrder = ≤-isPartialOrder; total = ≤-total}≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-isDecTotalOrder = record{ isTotalOrder = ≤-isTotalOrder; _≟_ = _≟_; _≤?_ = _≤?_}-- Bundles≤-poset : Poset 0ℓ 0ℓ 0ℓ≤-poset = record{ isPartialOrder = ≤-isPartialOrder}≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder = record{ isPreorder = ≤-isPreorder}≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-totalOrder = record{ isTotalOrder = ≤-isTotalOrder}≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder = record{ isDecTotalOrder = ≤-isDecTotalOrder}-------------------------------------------------------------------------- Properties of _<_-- Relational properties<-irrefl : Irreflexive _≡_ _<_<-irrefl refl ()<-asym : Asymmetric _<_<-asym f<t ()<-trans : Transitive _<_<-trans f<t ()<-transʳ : Trans _≤_ _<_ _<_<-transʳ b≤b f<t = f<t<-transˡ : Trans _<_ _≤_ _<_<-transˡ f<t b≤b = f<t<-cmp : Trichotomous _≡_ _<_<-cmp false false = tri≈ (λ()) refl (λ())<-cmp false true = tri< f<t (λ()) (λ())<-cmp true false = tri> (λ()) (λ()) f<t<-cmp true true = tri≈ (λ()) refl (λ())infix 4 _<?__<?_ : Decidable _<_false <? false = no (λ())false <? true = yes f<ttrue <? _ = no (λ())<-resp₂-≡ : _<_ Respects₂ _≡_<-resp₂-≡ = subst (_ <_) , subst (_< _)<-irrelevant : Irrelevant _<_<-irrelevant f<t f<t = refl<-wellFounded : WellFounded _<_<-wellFounded _ = acc <-accwhere<-acc : ∀ {x y} → y < x → Acc _<_ y<-acc f<t = acc λ ()-- Structures<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictPartialOrder = record{ isEquivalence = isEquivalence; irrefl = <-irrefl; trans = <-trans; <-resp-≈ = <-resp₂-≡}<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}-- Bundles<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictPartialOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder}<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder = record{ isStrictTotalOrder = <-isStrictTotalOrder}-------------------------------------------------------------------------- Properties of _∨_∨-assoc : Associative _∨_∨-assoc true y z = refl∨-assoc false y z = refl∨-comm : Commutative _∨_∨-comm true true = refl∨-comm true false = refl∨-comm false true = refl∨-comm false false = refl∨-identityˡ : LeftIdentity false _∨_∨-identityˡ _ = refl∨-identityʳ : RightIdentity false _∨_∨-identityʳ false = refl∨-identityʳ true = refl∨-identity : Identity false _∨_∨-identity = ∨-identityˡ , ∨-identityʳ∨-zeroˡ : LeftZero true _∨_∨-zeroˡ _ = refl∨-zeroʳ : RightZero true _∨_∨-zeroʳ false = refl∨-zeroʳ true = refl∨-zero : Zero true _∨_∨-zero = ∨-zeroˡ , ∨-zeroʳ∨-inverseˡ : LeftInverse true not _∨_∨-inverseˡ false = refl∨-inverseˡ true = refl∨-inverseʳ : RightInverse true not _∨_∨-inverseʳ x = ∨-comm x (not x) ⟨ trans ⟩ ∨-inverseˡ x∨-inverse : Inverse true not _∨_∨-inverse = ∨-inverseˡ , ∨-inverseʳ∨-idem : Idempotent _∨_∨-idem false = refl∨-idem true = refl∨-sel : Selective _∨_∨-sel false y = inj₂ refl∨-sel true y = inj₁ refl∨-conicalˡ : LeftConical false _∨_∨-conicalˡ false false _ = refl∨-conicalʳ : RightConical false _∨_∨-conicalʳ false false _ = refl∨-conical : Conical false _∨_∨-conical = ∨-conicalˡ , ∨-conicalʳ∨-isMagma : IsMagma _∨_∨-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _∨_}∨-magma : Magma 0ℓ 0ℓ∨-magma = record{ isMagma = ∨-isMagma}∨-isSemigroup : IsSemigroup _∨_∨-isSemigroup = record{ isMagma = ∨-isMagma; assoc = ∨-assoc}∨-semigroup : Semigroup 0ℓ 0ℓ∨-semigroup = record{ isSemigroup = ∨-isSemigroup}∨-isBand : IsBand _∨_∨-isBand = record{ isSemigroup = ∨-isSemigroup; idem = ∨-idem}∨-band : Band 0ℓ 0ℓ∨-band = record{ isBand = ∨-isBand}∨-isSemilattice : IsSemilattice _∨_∨-isSemilattice = record{ isBand = ∨-isBand; comm = ∨-comm}∨-semilattice : Semilattice 0ℓ 0ℓ∨-semilattice = record{ isSemilattice = ∨-isSemilattice}∨-isMonoid : IsMonoid _∨_ false∨-isMonoid = record{ isSemigroup = ∨-isSemigroup; identity = ∨-identity}∨-isCommutativeMonoid : IsCommutativeMonoid _∨_ false∨-isCommutativeMonoid = record{ isMonoid = ∨-isMonoid; comm = ∨-comm}∨-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ∨-commutativeMonoid = record{ isCommutativeMonoid = ∨-isCommutativeMonoid}∨-isIdempotentCommutativeMonoid :IsIdempotentCommutativeMonoid _∨_ false∨-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∨-isCommutativeMonoid; idem = ∨-idem}∨-idempotentCommutativeMonoid : IdempotentCommutativeMonoid 0ℓ 0ℓ∨-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∨-isIdempotentCommutativeMonoid}-------------------------------------------------------------------------- Properties of _∧_∧-assoc : Associative _∧_∧-assoc true y z = refl∧-assoc false y z = refl∧-comm : Commutative _∧_∧-comm true true = refl∧-comm true false = refl∧-comm false true = refl∧-comm false false = refl∧-identityˡ : LeftIdentity true _∧_∧-identityˡ _ = refl∧-identityʳ : RightIdentity true _∧_∧-identityʳ false = refl∧-identityʳ true = refl∧-identity : Identity true _∧_∧-identity = ∧-identityˡ , ∧-identityʳ∧-zeroˡ : LeftZero false _∧_∧-zeroˡ _ = refl∧-zeroʳ : RightZero false _∧_∧-zeroʳ false = refl∧-zeroʳ true = refl∧-zero : Zero false _∧_∧-zero = ∧-zeroˡ , ∧-zeroʳ∧-inverseˡ : LeftInverse false not _∧_∧-inverseˡ false = refl∧-inverseˡ true = refl∧-inverseʳ : RightInverse false not _∧_∧-inverseʳ x = ∧-comm x (not x) ⟨ trans ⟩ ∧-inverseˡ x∧-inverse : Inverse false not _∧_∧-inverse = ∧-inverseˡ , ∧-inverseʳ∧-idem : Idempotent _∧_∧-idem false = refl∧-idem true = refl∧-sel : Selective _∧_∧-sel false y = inj₁ refl∧-sel true y = inj₂ refl∧-conicalˡ : LeftConical true _∧_∧-conicalˡ true true _ = refl∧-conicalʳ : RightConical true _∧_∧-conicalʳ true true _ = refl∧-conical : Conical true _∧_∧-conical = ∧-conicalˡ , ∧-conicalʳ∧-distribˡ-∨ : _∧_ DistributesOverˡ _∨_∧-distribˡ-∨ true y z = refl∧-distribˡ-∨ false y z = refl∧-distribʳ-∨ : _∧_ DistributesOverʳ _∨_∧-distribʳ-∨ x y z = begin(y ∨ z) ∧ x ≡⟨ ∧-comm (y ∨ z) x ⟩x ∧ (y ∨ z) ≡⟨ ∧-distribˡ-∨ x y z ⟩x ∧ y ∨ x ∧ z ≡⟨ cong₂ _∨_ (∧-comm x y) (∧-comm x z) ⟩y ∧ x ∨ z ∧ x ∎∧-distrib-∨ : _∧_ DistributesOver _∨_∧-distrib-∨ = ∧-distribˡ-∨ , ∧-distribʳ-∨∨-distribˡ-∧ : _∨_ DistributesOverˡ _∧_∨-distribˡ-∧ true y z = refl∨-distribˡ-∧ false y z = refl∨-distribʳ-∧ : _∨_ DistributesOverʳ _∧_∨-distribʳ-∧ x y z = begin(y ∧ z) ∨ x ≡⟨ ∨-comm (y ∧ z) x ⟩x ∨ (y ∧ z) ≡⟨ ∨-distribˡ-∧ x y z ⟩(x ∨ y) ∧ (x ∨ z) ≡⟨ cong₂ _∧_ (∨-comm x y) (∨-comm x z) ⟩(y ∨ x) ∧ (z ∨ x) ∎∨-distrib-∧ : _∨_ DistributesOver _∧_∨-distrib-∧ = ∨-distribˡ-∧ , ∨-distribʳ-∧∧-abs-∨ : _∧_ Absorbs _∨_∧-abs-∨ true y = refl∧-abs-∨ false y = refl∨-abs-∧ : _∨_ Absorbs _∧_∨-abs-∧ true y = refl∨-abs-∧ false y = refl∨-∧-absorptive : Absorptive _∨_ _∧_∨-∧-absorptive = ∨-abs-∧ , ∧-abs-∨∧-isMagma : IsMagma _∧_∧-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = cong₂ _∧_}∧-magma : Magma 0ℓ 0ℓ∧-magma = record{ isMagma = ∧-isMagma}∧-isSemigroup : IsSemigroup _∧_∧-isSemigroup = record{ isMagma = ∧-isMagma; assoc = ∧-assoc}∧-semigroup : Semigroup 0ℓ 0ℓ∧-semigroup = record{ isSemigroup = ∧-isSemigroup}∧-isBand : IsBand _∧_∧-isBand = record{ isSemigroup = ∧-isSemigroup; idem = ∧-idem}∧-band : Band 0ℓ 0ℓ∧-band = record{ isBand = ∧-isBand}∧-isSemilattice : IsSemilattice _∧_∧-isSemilattice = record{ isBand = ∧-isBand; comm = ∧-comm}∧-semilattice : Semilattice 0ℓ 0ℓ∧-semilattice = record{ isSemilattice = ∧-isSemilattice}∧-isMonoid : IsMonoid _∧_ true∧-isMonoid = record{ isSemigroup = ∧-isSemigroup; identity = ∧-identity}∧-isCommutativeMonoid : IsCommutativeMonoid _∧_ true∧-isCommutativeMonoid = record{ isMonoid = ∧-isMonoid; comm = ∧-comm}∧-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ∧-commutativeMonoid = record{ isCommutativeMonoid = ∧-isCommutativeMonoid}∧-isIdempotentCommutativeMonoid :IsIdempotentCommutativeMonoid _∧_ true∧-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = ∧-isCommutativeMonoid; idem = ∧-idem}∧-idempotentCommutativeMonoid : IdempotentCommutativeMonoid 0ℓ 0ℓ∧-idempotentCommutativeMonoid = record{ isIdempotentCommutativeMonoid = ∧-isIdempotentCommutativeMonoid}∨-∧-isSemiring : IsSemiring _∨_ _∧_ false true∨-∧-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∨-isCommutativeMonoid; *-cong = cong₂ _∧_; *-assoc = ∧-assoc; *-identity = ∧-identity; distrib = ∧-distrib-∨}; zero = ∧-zero}∨-∧-isCommutativeSemiring: IsCommutativeSemiring _∨_ _∧_ false true∨-∧-isCommutativeSemiring = record{ isSemiring = ∨-∧-isSemiring; *-comm = ∧-comm}∨-∧-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ∨-∧-commutativeSemiring = record{ _+_ = _∨_; _*_ = _∧_; 0# = false; 1# = true; isCommutativeSemiring = ∨-∧-isCommutativeSemiring}∧-∨-isSemiring : IsSemiring _∧_ _∨_ true false∧-∨-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∧-isCommutativeMonoid; *-cong = cong₂ _∨_; *-assoc = ∨-assoc; *-identity = ∨-identity; distrib = ∨-distrib-∧}; zero = ∨-zero}∧-∨-isCommutativeSemiring: IsCommutativeSemiring _∧_ _∨_ true false∧-∨-isCommutativeSemiring = record{ isSemiring = ∧-∨-isSemiring; *-comm = ∨-comm}∧-∨-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ∧-∨-commutativeSemiring = record{ _+_ = _∧_; _*_ = _∨_; 0# = true; 1# = false; isCommutativeSemiring = ∧-∨-isCommutativeSemiring}∨-∧-isLattice : IsLattice _∨_ _∧_∨-∧-isLattice = record{ isEquivalence = isEquivalence; ∨-comm = ∨-comm; ∨-assoc = ∨-assoc; ∨-cong = cong₂ _∨_; ∧-comm = ∧-comm; ∧-assoc = ∧-assoc; ∧-cong = cong₂ _∧_; absorptive = ∨-∧-absorptive}∨-∧-lattice : Lattice 0ℓ 0ℓ∨-∧-lattice = record{ isLattice = ∨-∧-isLattice}∨-∧-isDistributiveLattice : IsDistributiveLattice _∨_ _∧_∨-∧-isDistributiveLattice = record{ isLattice = ∨-∧-isLattice; ∨-distrib-∧ = ∨-distrib-∧; ∧-distrib-∨ = ∧-distrib-∨}∨-∧-distributiveLattice : DistributiveLattice 0ℓ 0ℓ∨-∧-distributiveLattice = record{ isDistributiveLattice = ∨-∧-isDistributiveLattice}∨-∧-isBooleanAlgebra : IsBooleanAlgebra _∨_ _∧_ not true false∨-∧-isBooleanAlgebra = record{ isDistributiveLattice = ∨-∧-isDistributiveLattice; ∨-complement = ∨-inverse; ∧-complement = ∧-inverse; ¬-cong = cong not}∨-∧-booleanAlgebra : BooleanAlgebra 0ℓ 0ℓ∨-∧-booleanAlgebra = record{ isBooleanAlgebra = ∨-∧-isBooleanAlgebra}-------------------------------------------------------------------------- Properties of notnot-involutive : Involutive notnot-involutive true = reflnot-involutive false = reflnot-injective : ∀ {x y} → not x ≡ not y → x ≡ ynot-injective {false} {false} nx≢ny = reflnot-injective {true} {true} nx≢ny = reflnot-¬ : ∀ {x y} → x ≡ y → x ≢ not ynot-¬ {true} refl ()not-¬ {false} refl ()¬-not : ∀ {x y} → x ≢ y → x ≡ not y¬-not {true} {true} x≢y = ⊥-elim (x≢y refl)¬-not {true} {false} _ = refl¬-not {false} {true} _ = refl¬-not {false} {false} x≢y = ⊥-elim (x≢y refl)-------------------------------------------------------------------------- Properties of _xor_xor-is-ok : ∀ x y → x xor y ≡ (x ∨ y) ∧ not (x ∧ y)xor-is-ok true y = reflxor-is-ok false y = sym (∧-identityʳ _)true-xor : ∀ x → true xor x ≡ not xtrue-xor false = refltrue-xor true = reflxor-same : ∀ x → x xor x ≡ falsexor-same false = reflxor-same true = reflnot-distribˡ-xor : ∀ x y → not (x xor y) ≡ (not x) xor ynot-distribˡ-xor false y = reflnot-distribˡ-xor true y = not-involutive _not-distribʳ-xor : ∀ x y → not (x xor y) ≡ x xor (not y)not-distribʳ-xor false y = reflnot-distribʳ-xor true y = reflxor-assoc : Associative _xor_xor-assoc true y z = sym (not-distribˡ-xor y z)xor-assoc false y z = reflxor-comm : Commutative _xor_xor-comm false false = reflxor-comm false true = reflxor-comm true false = reflxor-comm true true = reflxor-identityˡ : LeftIdentity false _xor_xor-identityˡ _ = reflxor-identityʳ : RightIdentity false _xor_xor-identityʳ false = reflxor-identityʳ true = reflxor-identity : Identity false _xor_xor-identity = xor-identityˡ , xor-identityʳxor-inverseˡ : LeftInverse true not _xor_xor-inverseˡ false = reflxor-inverseˡ true = reflxor-inverseʳ : RightInverse true not _xor_xor-inverseʳ x = xor-comm x (not x) ⟨ trans ⟩ xor-inverseˡ xxor-inverse : Inverse true not _xor_xor-inverse = xor-inverseˡ , xor-inverseʳ∧-distribˡ-xor : _∧_ DistributesOverˡ _xor_∧-distribˡ-xor false y z = refl∧-distribˡ-xor true y z = refl∧-distribʳ-xor : _∧_ DistributesOverʳ _xor_∧-distribʳ-xor x false z = refl∧-distribʳ-xor x true false = sym (xor-identityʳ x)∧-distribʳ-xor x true true = sym (xor-same x)∧-distrib-xor : _∧_ DistributesOver _xor_∧-distrib-xor = ∧-distribˡ-xor , ∧-distribʳ-xorxor-annihilates-not : ∀ x y → (not x) xor (not y) ≡ x xor yxor-annihilates-not false y = not-involutive _xor-annihilates-not true y = reflxor-∧-commutativeRing : CommutativeRing 0ℓ 0ℓxor-∧-commutativeRing = ⊕-∧-commutativeRingwhereopen BooleanAlgebraProperties ∨-∧-booleanAlgebraopen XorRing _xor_ xor-is-ok-------------------------------------------------------------------------- Properties of if_then_else_if-float : ∀ (f : A → B) b {x y} →f (if b then x else y) ≡ (if b then f x else f y)if-float _ true = reflif-float _ false = refl-------------------------------------------------------------------------- Properties of Topen Relation.Nullary.Decidable.Core public using (T?)T-≡ : ∀ {x} → T x ⇔ x ≡ trueT-≡ {false} = mk⇔ (λ ()) (λ ())T-≡ {true} = mk⇔ (const refl) (const _)T-not-≡ : ∀ {x} → T (not x) ⇔ x ≡ falseT-not-≡ {false} = mk⇔ (const refl) (const _)T-not-≡ {true} = mk⇔ (λ ()) (λ ())T-∧ : ∀ {x y} → T (x ∧ y) ⇔ (T x × T y)T-∧ {true} {true} = mk⇔ (const (_ , _)) (const _)T-∧ {true} {false} = mk⇔ (λ ()) proj₂T-∧ {false} {_} = mk⇔ (λ ()) proj₁T-∨ : ∀ {x y} → T (x ∨ y) ⇔ (T x ⊎ T y)T-∨ {true} {_} = mk⇔ inj₁ (const _)T-∨ {false} {true} = mk⇔ inj₂ (const _)T-∨ {false} {false} = mk⇔ inj₁ [ id , id ]T-irrelevant : U.Irrelevant TT-irrelevant {true} _ _ = reflT?-diag : ∀ b → T b → True (T? b)T?-diag b = fromWitness-------------------------------------------------------------------------- Miscellaneous other properties⇔→≡ : {x y z : Bool} → x ≡ z ⇔ y ≡ z → x ≡ y⇔→≡ {true } {true } hyp = refl⇔→≡ {true } {false} {true } hyp = sym (Equivalence.to hyp refl)⇔→≡ {true } {false} {false} hyp = Equivalence.from hyp refl⇔→≡ {false} {true } {true } hyp = Equivalence.from hyp refl⇔→≡ {false} {true } {false} hyp = sym (Equivalence.to hyp refl)⇔→≡ {false} {false} hyp = refl-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0push-function-into-if = if-float{-# WARNING_ON_USAGE push-function-into-if"Warning: push-function-into-if was deprecated in v2.0.Please use if-float instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Instances for booleans------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool.Instances whereopen import Data.Bool.Propertiesopen import Relation.Binary.PropositionalEquality.Propertiesusing (isDecEquivalence)instanceBool-≡-isDecEquivalence = isDecEquivalence _≟_Bool-≤-isDecTotalOrder = ≤-isDecTotalOrder
-------------------------------------------------------------------------- The Agda standard library---- The type for booleans and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.Bool.Base whereopen import Data.Unit.Base using (⊤)open import Data.Emptyopen import Level using (Level)privatevariablea : LevelA : Set a-------------------------------------------------------------------------- The boolean typeopen import Agda.Builtin.Bool public-------------------------------------------------------------------------- Relationsinfix 4 _≤_ _<_data _≤_ : Bool → Bool → Set wheref≤t : false ≤ trueb≤b : ∀ {b} → b ≤ bdata _<_ : Bool → Bool → Set wheref<t : false < true-------------------------------------------------------------------------- Boolean operationsinfixr 6 _∧_infixr 5 _∨_ _xor_not : Bool → Boolnot true = falsenot false = true_∧_ : Bool → Bool → Booltrue ∧ b = bfalse ∧ b = false_∨_ : Bool → Bool → Booltrue ∨ b = truefalse ∨ b = b_xor_ : Bool → Bool → Booltrue xor b = not bfalse xor b = b-------------------------------------------------------------------------- Conversion to Set-- A function mapping true to an inhabited type and false to an empty-- type.T : Bool → SetT true = ⊤T false = ⊥-------------------------------------------------------------------------- Other operationsinfix 0 if_then_else_if_then_else_ : Bool → A → A → Aif true then t else f = tif false then t else f = f
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Data.AVL was deprecated in v1.4.Use Data.Tree.AVL instead."#-}open import Data.Tree.AVL strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (Setoid)module Data.AVL.Value {a ℓ} (S : Setoid a ℓ) where{-# WARNING_ON_IMPORT"Data.AVL.Value was deprecated in v1.4.Use Data.Tree.AVL.Value instead."#-}open import Data.Tree.AVL.Value S public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL.Sets{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Data.AVL.Sets was deprecated in v1.4.Use Data.Tree.AVL.Sets instead."#-}open import Data.Tree.AVL.Sets strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL.NonEmpty{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂) where{-# WARNING_ON_IMPORT"Data.AVL.NonEmpty was deprecated in v1.4.Use Data.Tree.AVL.NonEmpty instead."#-}open import Data.Tree.AVL.NonEmpty strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.Bundles using (StrictTotalOrder)open import Relation.Binary.PropositionalEquality using (_≡_; refl; subst)module Data.AVL.NonEmpty.Propositional{k r} {Key : Set k} {_<_ : Rel Key r}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) where{-# WARNING_ON_IMPORT"Data.AVL.NonEmpty.Propositional was deprecated in v1.4.Use Data.Tree.AVL.NonEmpty.Propositonal instead."#-}open import Data.Tree.AVL.NonEmpty.Propositional isStrictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL.Map{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Data.AVL.Map was deprecated in v1.4.Use Data.Tree.AVL.Map instead."#-}open import Data.Tree.AVL.Map strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL.Key{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Data.AVL.Key was deprecated in v1.4.Use Data.Tree.AVL.Key instead."#-}open import Data.Tree.AVL.Key strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base using (∃)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong; subst)import Data.Tree.AVL.Valuemodule Data.AVL.IndexedMap{i k v ℓ}{Index : Set i} {Key : Index → Set k} (Value : Index → Set v){_<_ : Rel (∃ Key) ℓ}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_)where{-# WARNING_ON_IMPORT"Data.AVL.IndexedMap was deprecated in v1.4.Use Data.Tree.AVL.IndexedMap instead."#-}open import Data.Tree.AVL.IndexedMap Value isStrictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (StrictTotalOrder)module Data.AVL.Indexed{a ℓ₁ ℓ₂} (strictTotalOrder : StrictTotalOrder a ℓ₁ ℓ₂) where{-# WARNING_ON_IMPORT"Data.AVL.Indexed was deprecated in v1.4.Use Data.Tree.AVL.Indexed instead."#-}open import Data.Tree.AVL.Indexed strictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsStrictTotalOrder)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; subst)module Data.AVL.Indexed.WithK{k r} (Key : Set k) {_<_ : Rel Key r}(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) where{-# WARNING_ON_IMPORT"Data.AVL.Indexed.WithK was deprecated in v1.4.Use Data.Tree.AVL.Indexed.WithK instead."#-}open import Data.Tree.AVL.Indexed.WithK Key isStrictTotalOrder public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Data.AVL.Height where{-# WARNING_ON_IMPORT"Data.AVL.Height was deprecated in v1.4.Use Data.Tree.AVL.Height instead."#-}open import Data.Tree.AVL.Height public
-------------------------------------------------------------------------- The Agda standard library---- The Thunk wrappers for sized codata, copredicates and corelations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Thunk whereopen import Sizeopen import Relation.Unary.Sized-------------------------------------------------------------------------- Basic types.record Thunk {ℓ} (F : SizedSet ℓ) (i : Size) : Set ℓ wherecoinductivefield force : {j : Size< i} → F jopen Thunk publicThunk^P : ∀ {f p} {F : SizedSet f} (P : Size → F ∞ → Set p)(i : Size) (tf : Thunk F ∞) → Set pThunk^P P i tf = Thunk (λ i → P i (tf .force)) iThunk^R : ∀ {f g r} {F : SizedSet f} {G : SizedSet g}(R : Size → F ∞ → G ∞ → Set r)(i : Size) (tf : Thunk F ∞) (tg : Thunk G ∞) → Set rThunk^R R i tf tg = Thunk (λ i → R i (tf .force) (tg .force)) i-------------------------------------------------------------------------- SyntaxThunk-syntax : ∀ {ℓ} → SizedSet ℓ → Size → Set ℓThunk-syntax = Thunksyntax Thunk-syntax (λ j → e) i = Thunk[ j < i ] e-------------------------------------------------------------------------- Basic functions.-- Thunk is a functormodule _ {p q} {P : SizedSet p} {Q : SizedSet q} wheremap : ∀[ P ⇒ Q ] → ∀[ Thunk P ⇒ Thunk Q ]map f p .force = f (p .force)-- Thunk is a comonadmodule _ {p} {P : SizedSet p} whereextract : ∀[ Thunk P ] → P ∞extract p = p .forceduplicate : ∀[ Thunk P ⇒ Thunk (Thunk P) ]duplicate p .force .force = p .forcemodule _ {p q} {P : SizedSet p} {Q : SizedSet q} whereinfixl 1 _<*>__<*>_ : ∀[ Thunk (P ⇒ Q) ⇒ Thunk P ⇒ Thunk Q ](f <*> p) .force = f .force (p .force)-- We can take cofixpoints of functions only making Thunk'd recursive callsmodule _ {p} (P : SizedSet p) wherecofix : ∀[ Thunk P ⇒ P ] → ∀[ P ]cofix f = f λ where .force → cofix f
-------------------------------------------------------------------------- The Agda standard library---- The Stream type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream whereopen import Sizeopen import Codata.Sized.Thunk as Thunk using (Thunk; force)open import Data.Nat.Baseopen import Data.List.Base using (List; []; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_; _∷⁺_)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.Product.Base as P using (Σ; _×_; _,_; <_,_>; proj₁; proj₂)open import Function.Base using (id; _∘_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b c : LevelA : Set aB : Set bC : Set ci : Size-------------------------------------------------------------------------- Typedata Stream (A : Set a) (i : Size) : Set a where_∷_ : A → Thunk (Stream A) i → Stream A iinfixr 5 _∷_-------------------------------------------------------------------------- Creating streamsrepeat : A → Stream A irepeat a = a ∷ λ where .force → repeat ainfixr 5 _++_ _⁺++__++_ : List A → Stream A i → Stream A i[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ λ where .force → xs ++ ysunfold : (A → A × B) → A → Stream B iunfold next seed =let (seed′ , b) = next seed inb ∷ λ where .force → unfold next seed′iterate : (A → A) → A → Stream A ∞iterate f = unfold < f , id >nats : Stream ℕ ∞nats = iterate suc zero-------------------------------------------------------------------------- Looking at streamshead : Stream A i → Ahead (x ∷ xs) = xtail : {j : Size< i} → Stream A i → Stream A jtail (x ∷ xs) = xs .forcelookup : Stream A ∞ → ℕ → Alookup xs zero = head xslookup xs (suc k) = lookup (tail xs) k-------------------------------------------------------------------------- Transforming streamsmap : (A → B) → Stream A i → Stream B imap f (x ∷ xs) = f x ∷ λ where .force → map f (xs .force)ap : Stream (A → B) i → Stream A i → Stream B iap (f ∷ fs) (x ∷ xs) = f x ∷ λ where .force → ap (fs .force) (xs .force)scanl : (B → A → B) → B → Stream A i → Stream B iscanl c n (x ∷ xs) = n ∷ λ where .force → scanl c (c n x) (xs .force)zipWith : (A → B → C) → Stream A i → Stream B i → Stream C izipWith f (a ∷ as) (b ∷ bs) = f a b ∷ λ where .force → zipWith f (as .force) (bs .force)-------------------------------------------------------------------------- List⁺-related functions_⁺++_ : List⁺ A → Thunk (Stream A) i → Stream A i(x ∷ xs) ⁺++ ys = x ∷ λ where .force → xs ++ ys .forcecycle : List⁺ A → Stream A icycle xs = xs ⁺++ λ where .force → cycle xsconcat : Stream (List⁺ A) i → Stream A iconcat (xs ∷ xss) = xs ⁺++ λ where .force → concat (xss .force)-------------------------------------------------------------------------- ChunkingsplitAt : (n : ℕ) → Stream A ∞ → Vec A n × Stream A ∞splitAt zero xs = [] , xssplitAt (suc n) (x ∷ xs) = P.map₁ (x ∷_) (splitAt n (xs .force))take : (n : ℕ) → Stream A ∞ → Vec A ntake n xs = proj₁ (splitAt n xs)drop : ℕ → Stream A ∞ → Stream A ∞drop n xs = proj₂ (splitAt n xs)chunksOf : (n : ℕ) → Stream A ∞ → Stream (Vec A n) ∞chunksOf n = chunksOfAcc n id module ChunksOf wherechunksOfAcc : ∀ k (acc : Vec A k → Vec A n) →Stream A ∞ → Stream (Vec A n) ichunksOfAcc zero acc xs = acc [] ∷ λ where .force → chunksOfAcc n id xschunksOfAcc (suc k) acc (x ∷ xs) = chunksOfAcc k (acc ∘ (x ∷_)) (xs .force)-------------------------------------------------------------------------- Interleaving streams-- The most basic of interleaving strategies is to take two streams and-- alternate between emitting values from one and the other.interleave : Stream A i → Thunk (Stream A) i → Stream A iinterleave (x ∷ xs) ys = x ∷ λ where .force → interleave (ys .force) xs-- This interleaving strategy can be generalised to an arbitrary-- non-empty list of streamsinterleave⁺ : List⁺ (Stream A i) → Stream A iinterleave⁺ xss =List⁺.map head xss⁺++ λ where .force → interleave⁺ (List⁺.map tail xss)-- To generalise this further to a stream of streams however we have to-- adopt a different strategy: if we were to start with *all* the heads-- then we would never reach any of the second elements in the streams.-- Here we use Cantor's zig zag function to explore the plane defined by-- the function `(i,j) ↦ lookup (lookup xss i) j‵ mapping coordinates to-- values in a way that guarantees that any point is reached in a finite-- amount of time. The definition is taken from the paper:-- Applications of Applicative Proof Search by Liam O'Connorcantor : Stream (Stream A ∞) ∞ → Stream A ∞cantor (l ∷ ls) = zig (l ∷ []) (ls .force) module Cantor wherezig : List⁺ (Stream A ∞) → Stream (Stream A ∞) ∞ → Stream A izag : List⁺ A → List⁺ (Stream A ∞) → Stream (Stream A ∞) ∞ → Stream A izig xss = zag (List⁺.map head xss) (List⁺.map tail xss)zag (x ∷ []) zs (l ∷ ls) = x ∷ λ where .force → zig (l ∷⁺ zs) (ls .force)zag (x ∷ (y ∷ xs)) zs ls = x ∷ λ where .force → zag (y ∷ xs) zs ls-- We can use the Cantor zig zag function to define a form of `bind'-- that reaches any point of the plane in a finite amount of time.plane : {B : A → Set b} → Stream A ∞ → ((a : A) → Stream (B a) ∞) →Stream (Σ A B) ∞plane as bs = cantor (map (λ a → map (a ,_) (bs a)) as)-- Here is the beginning of the path we are following:_ : take 21 (plane nats (λ _ → nats))≡ (0 , 0)∷ (1 , 0) ∷ (0 , 1)∷ (2 , 0) ∷ (1 , 1) ∷ (0 , 2)∷ (3 , 0) ∷ (2 , 1) ∷ (1 , 2) ∷ (0 , 3)∷ (4 , 0) ∷ (3 , 1) ∷ (2 , 2) ∷ (1 , 3) ∷ (0 , 4)∷ (5 , 0) ∷ (4 , 1) ∷ (3 , 2) ∷ (2 , 3) ∷ (1 , 4) ∷ (0 , 5)∷ []_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on the Stream type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream.Properties whereopen import Level using (Level)open import Sizeopen import Codata.Sized.Thunk as Thunk using (Thunk; force)open import Codata.Sized.Streamopen import Codata.Sized.Stream.Bisimilarityopen import Data.Nat.Baseopen import Data.Nat.GeneralisedArithmetic using (fold; fold-pull)open import Data.List.Base as List using ([]; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)import Data.List.Relation.Binary.Equality.Propositional as ≋open import Data.Product.Base as Product using (_,_)open import Data.Vec.Base as Vec using (_∷_)open import Function.Base using (id; _$_; _∘′_; const)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_; _≢_)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablea b c : LevelA : Set aB : Set bC : Set ci : Size-------------------------------------------------------------------------- repeatlookup-repeat-identity : (n : ℕ) (a : A) → lookup (repeat a) n ≡ alookup-repeat-identity zero a = ≡.refllookup-repeat-identity (suc n) a = lookup-repeat-identity n atake-repeat-identity : (n : ℕ) (a : A) → take n (repeat a) ≡ Vec.replicate n atake-repeat-identity zero a = ≡.refltake-repeat-identity (suc n) a = ≡.cong (a Vec.∷_) (take-repeat-identity n a)splitAt-repeat-identity : (n : ℕ) (a : A) → splitAt n (repeat a) ≡ (Vec.replicate n a , repeat a)splitAt-repeat-identity zero a = ≡.reflsplitAt-repeat-identity (suc n) a = ≡.cong (Product.map₁ (a ∷_)) (splitAt-repeat-identity n a)replicate-repeat : ∀ {i} (n : ℕ) (a : A) → i ⊢ List.replicate n a ++ repeat a ≈ repeat areplicate-repeat zero a = reflreplicate-repeat (suc n) a = ≡.refl ∷ λ where .force → replicate-repeat n acycle-replicate : ∀ {i} (n : ℕ) (n≢0 : n ≢ 0) (a : A) → i ⊢ cycle (List⁺.replicate n n≢0 a) ≈ repeat acycle-replicate {i} n n≢0 a = let as = List⁺.replicate n n≢0 a in begincycle as ≡⟨⟩as ⁺++ _ ≈⟨ ⁺++⁺ ≋.≋-refl (λ where .force → cycle-replicate n n≢0 a) ⟩as ⁺++ (λ where .force → repeat a) ≈⟨ ≡.refl ∷ (λ where .force → replicate-repeat (pred n) a) ⟩repeat a ∎ where open ≈-Reasoningmodule _ {a b} {A : Set a} {B : Set b} wheremap-repeat : ∀ (f : A → B) a {i} → i ⊢ map f (repeat a) ≈ repeat (f a)map-repeat f a = ≡.refl ∷ λ where .force → map-repeat f aap-repeat : ∀ (f : A → B) a {i} → i ⊢ ap (repeat f) (repeat a) ≈ repeat (f a)ap-repeat f a = ≡.refl ∷ λ where .force → ap-repeat f aap-repeatˡ : ∀ (f : A → B) as {i} → i ⊢ ap (repeat f) as ≈ map f asap-repeatˡ f (a ∷ as) = ≡.refl ∷ λ where .force → ap-repeatˡ f (as .force)ap-repeatʳ : ∀ (fs : Stream (A → B) ∞) (a : A) {i} → i ⊢ ap fs (repeat a) ≈ map (_$ a) fsap-repeatʳ (f ∷ fs) a = ≡.refl ∷ λ where .force → ap-repeatʳ (fs .force) amap-++ : ∀ {i} (f : A → B) as xs → i ⊢ map f (as ++ xs) ≈ List.map f as ++ map f xsmap-++ f [] xs = reflmap-++ f (a ∷ as) xs = ≡.refl ∷ λ where .force → map-++ f as xsmap-⁺++ : ∀ {i} (f : A → B) as xs → i ⊢ map f (as ⁺++ xs) ≈ List⁺.map f as ⁺++ Thunk.map (map f) xsmap-⁺++ f (a ∷ as) xs = ≡.refl ∷ (λ where .force → map-++ f as (xs .force))map-cycle : ∀ {i} (f : A → B) as → i ⊢ map f (cycle as) ≈ cycle (List⁺.map f as)map-cycle f as = beginmap f (cycle as) ≈⟨ map-⁺++ f as _ ⟩List⁺.map f as ⁺++ _ ≈⟨ ⁺++⁺ ≋.≋-refl (λ where .force → map-cycle f as) ⟩cycle (List⁺.map f as) ∎ where open ≈-Reasoning-------------------------------------------------------------------------- Functor lawsmap-id : ∀ (as : Stream A ∞) → i ⊢ map id as ≈ asmap-id (a ∷ as) = ≡.refl ∷ λ where .force → map-id (as .force)map-∘ : ∀ (f : A → B) (g : B → C) as → i ⊢ map g (map f as) ≈ map (g ∘′ f) asmap-∘ f g (a ∷ as) = ≡.refl ∷ λ where .force → map-∘ f g (as .force)-------------------------------------------------------------------------- splitAtsplitAt-map : ∀ n (f : A → B) xs →splitAt n (map f xs) ≡ Product.map (Vec.map f) (map f) (splitAt n xs)splitAt-map zero f xs = ≡.reflsplitAt-map (suc n) f (x ∷ xs) =≡.cong (Product.map₁ (f x Vec.∷_)) (splitAt-map n f (xs .force))-------------------------------------------------------------------------- iteratelookup-iterate-identity : ∀ n f (a : A) → lookup (iterate f a) n ≡ fold a f nlookup-iterate-identity zero f a = ≡.refllookup-iterate-identity (suc n) f a = beginlookup (iterate f a) (suc n) ≡⟨⟩lookup (iterate f (f a)) n ≡⟨ lookup-iterate-identity n f (f a) ⟩fold (f a) f n ≡⟨ fold-pull a f (const ∘′ f) (f a) ≡.refl (λ _ → ≡.refl) n ⟩f (fold a f n) ≡⟨⟩fold a f (suc n) ∎ where open ≡-Reasoning-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-identity = map-id{-# WARNING_ON_USAGE map-identity"Warning: map-identity was deprecated in v2.0.Please use map-id instead."#-}map-map-fusion = map-∘{-# WARNING_ON_USAGE map-map-fusion"Warning: map-map-fusion was deprecated in v2.0.Please use map-∘ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for Stream------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream.Instances whereopen import Codata.Sized.Stream.EffectfulinstancestreamFunctor = functorstreamApplicative = applicativestreamComonad = comonad
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Stream------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream.Effectful whereopen import Data.Product.Base using (<_,_>)open import Codata.Sized.Streamopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Comonadopen import Function.Basefunctor : ∀ {ℓ i} → RawFunctor {ℓ} (λ A → Stream A i)functor = record { _<$>_ = λ f → map f }applicative : ∀ {ℓ i} → RawApplicative {ℓ} (λ A → Stream A i)applicative = record{ rawFunctor = functor; pure = repeat; _<*>_ = ap}comonad : ∀ {ℓ} → RawComonad {ℓ} (λ A → Stream A _)comonad = record{ extract = head; extend = unfold ∘′ < tail ,_>}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Codata.Sized.Stream.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream.Categorical whereopen import Codata.Sized.Stream.Effectful public{-# WARNING_ON_IMPORT"Codata.Sized.Stream.Categorical was deprecated in v2.0.Use Codata.Sized.Stream.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for Streams------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Stream.Bisimilarity whereopen import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Streamopen import Levelopen import Data.List.NonEmpty as List⁺ using (_∷_)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Relation.Binary.Core using (Rel; REL)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Sym; Trans)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b c p q r : LevelA : Set aB : Set bC : Set ci : Sizedata Bisim {A : Set a} {B : Set b} (R : REL A B r) i :REL (Stream A ∞) (Stream B ∞) (a ⊔ b ⊔ r) where_∷_ : ∀ {x y xs ys} → R x y → Thunk^R (Bisim R) i xs ys →Bisim R i (x ∷ xs) (y ∷ ys)infixr 5 _∷_module _ {R : Rel A r} wherereflexive : Reflexive R → Reflexive (Bisim R i)reflexive refl^R {r ∷ rs} = refl^R ∷ λ where .force → reflexive refl^Rmodule _ {P : REL A B p} {Q : REL B A q} wheresymmetric : Sym P Q → Sym (Bisim P i) (Bisim Q i)symmetric sym^PQ (p ∷ ps) = sym^PQ p ∷ λ where .force → symmetric sym^PQ (ps .force)module _ {P : REL A B p} {Q : REL B C q} {R : REL A C r} wheretransitive : Trans P Q R → Trans (Bisim P i) (Bisim Q i) (Bisim R i)transitive trans^PQR (p ∷ ps) (q ∷ qs) =trans^PQR p q ∷ λ where .force → transitive trans^PQR (ps .force) (qs .force)isEquivalence : {R : Rel A r} → IsEquivalence R → IsEquivalence (Bisim R i)isEquivalence equiv^R = record{ refl = reflexive equiv^R.refl; sym = symmetric equiv^R.sym; trans = transitive equiv^R.trans} where module equiv^R = IsEquivalence equiv^Rsetoid : Setoid a r → Size → Setoid a (a ⊔ r)setoid S i = record{ isEquivalence = isEquivalence {i = i} (Setoid.isEquivalence S)}module _ {R : REL A B r} where++⁺ : ∀ {as bs xs ys} → Pointwise R as bs →Bisim R i xs ys → Bisim R i (as ++ xs) (bs ++ ys)++⁺ [] rs = rs++⁺ (r ∷ pw) rs = r ∷ λ where .force → ++⁺ pw rs⁺++⁺ : ∀ {as bs xs ys} → Pointwise R (List⁺.toList as) (List⁺.toList bs) →Thunk^R (Bisim R) i xs ys → Bisim R i (as ⁺++ xs) (bs ⁺++ ys)⁺++⁺ (r ∷ pw) rs = r ∷ λ where .force → ++⁺ pw (rs .force)-------------------------------------------------------------------------- Pointwise Equality as a Bisimilaritymodule _ {A : Set a} whereinfix 1 _⊢_≈__⊢_≈_ : ∀ i → Stream A ∞ → Stream A ∞ → Set a_⊢_≈_ = Bisim _≡_refl : ∀ {i} → Reflexive (i ⊢_≈_)refl = reflexive ≡.reflsym : ∀ {i} → Symmetric (i ⊢_≈_)sym = symmetric ≡.symtrans : ∀ {i} → Transitive (i ⊢_≈_)trans = transitive ≡.transmodule ≈-Reasoning {a} {A : Set a} {i} whereopen import Relation.Binary.Reasoning.Setoid (setoid (≡.setoid A) i) public
-------------------------------------------------------------------------- The Agda standard library---- M-types (the dual of W-types)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.M whereopen import Sizeopen import Levelopen import Codata.Sized.Thunk using (Thunk; force)open import Data.Product.Base hiding (map)open import Data.Container.Core as C hiding (map)data M {s p} (C : Container s p) (i : Size) : Set (s ⊔ p) whereinf : ⟦ C ⟧ (Thunk (M C) i) → M C imodule _ {s p} {C : Container s p} wherehead : ∀ {i} → M C i → Shape Chead (inf (x , f)) = xtail : (x : M C ∞) → Position C (head x) → M C ∞tail (inf (x , f)) = λ p → f p .force-- mapmodule _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}(m : C₁ ⇒ C₂) wheremap : ∀ {i} → M C₁ i → M C₂ imap (inf t) = inf (⟪ m ⟫ (C.map (λ t → λ where .force → map (t .force)) t))-- unfoldmodule _ {s p ℓ} {C : Container s p} (open Container C){S : Set ℓ} (alg : S → ⟦ C ⟧ S) whereunfold : S → ∀ {i} → M C iunfold seed = let (x , next) = alg seed ininf (x , λ p → λ where .force → unfold (next p))
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on M-types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.M.Properties whereopen import Levelopen import Sizeopen import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Mopen import Codata.Sized.M.Bisimilarityopen import Data.Container.Core as C hiding (map)import Data.Container.Morphism as Mpopen import Data.Product.Base as Product using (_,_)open import Data.Product.Properties hiding (map-cong)open import Function.Base using (_$′_; _∘′_)import Relation.Binary.PropositionalEquality.Core as ≡import Relation.Binary.PropositionalEquality.Properties as ≡open import Data.Container.Relation.Binary.Pointwise using (_,_)import Data.Container.Relation.Binary.Equality.Setoid as EqSetoidprivate module Eq {a} (A : Set a) = EqSetoid (≡.setoid A)open Eq using (Eq)module _ {s p} {C : Container s p} wheremap-id : ∀ {i} c → Bisim C i (map (Mp.id C) c) cmap-id (inf (s , f)) = inf (≡.refl , λ where p .force → map-id (f p .force))module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂} wheremap-cong : ∀ {i} {f g : C₁ ⇒ C₂} →(∀ {X} t → Eq X C₂ (⟪ f ⟫ t) (⟪ g ⟫ t)) →∀ c₁ → Bisim C₂ i (map f c₁) (map g c₁)map-cong {f = f} {g} f≗g (inf t@(s , n)) with f≗g t... | eqs , eqf = inf (eqs , λ wherep .force {j} → ≡.subst (λ t → Bisim C₂ j (map f (n (position f p) .force))(map g (t .force)))(eqf p)(map-cong f≗g (n (position f p) .force)))module _ {s₁ s₂ s₃ p₁ p₂ p₃} {C₁ : Container s₁ p₁}{C₂ : Container s₂ p₂} {C₃ : Container s₃ p₃} wheremap-∘ : ∀ {i} {g : C₂ ⇒ C₃} {f : C₁ ⇒ C₂} c₁ →Bisim C₃ i (map (g Mp.∘ f) c₁) (map g $′ map f c₁)map-∘ (inf (s , f)) = inf (≡.refl , λ where p .force → map-∘ (f _ .force))module _ {s₁ s₂ p₁ p₂ s} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}{S : Set s} {alg : S → ⟦ C₁ ⟧ S} {f : C₁ ⇒ C₂} wheremap-unfold : ∀ {i} s → Bisim C₂ i (map f (unfold alg s))(unfold (⟪ f ⟫ ∘′ alg) s)map-unfold s = inf (≡.refl , λ where p .force → map-unfold _)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-compose = map-∘{-# WARNING_ON_USAGE map-compose"Warning: map-compose was deprecated in v2.0.Please use map-∘ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for M-types------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.M.Bisimilarity whereopen import Levelopen import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Mopen import Data.Container.Coreopen import Data.Container.Relation.Binary.Pointwise using (Pointwise; _,_)open import Data.Product.Base using (_,_)open import Function.Base using (_∋_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)import Relation.Binary.PropositionalEquality.Core as ≡data Bisim {s p} (C : Container s p) (i : Size) : Rel (M C ∞) (s ⊔ p) whereinf : ∀ {t u} → Pointwise C (Thunk^R (Bisim C) i) t u → Bisim C i (inf t) (inf u)module _ {s p} {C : Container s p} where-- unfortunately the proofs are a lot nicer if we do not use the-- combinators C.refl, C.sym and C.transrefl : ∀ {i} → Reflexive (Bisim C i)refl {x = inf t} = inf (≡.refl , λ where p .force → refl)sym : ∀ {i} → Symmetric (Bisim C i)sym (inf (≡.refl , f)) = inf (≡.refl , λ where p .force → sym (f p .force))trans : ∀ {i} → Transitive (Bisim C i)trans (inf (≡.refl , f)) (inf (≡.refl , g)) =inf (≡.refl , λ where p .force → trans (f p .force) (g p .force))isEquivalence : ∀ {i} → IsEquivalence (Bisim C i)isEquivalence = record{ refl = refl; sym = sym; trans = trans}setoid : {i : Size} → Setoid (s ⊔ p) (s ⊔ p)setoid {i} = record{ isEquivalence = isEquivalence {i}}
-------------------------------------------------------------------------- The Agda standard library---- The Delay type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Delay whereopen import Sizeopen import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conat using (Conat; zero; suc; Finite)open import Data.Emptyopen import Relation.Nullaryopen import Data.Nat.Baseopen import Data.Maybe.Base hiding (map ; fromMaybe ; zipWith ; alignWith ; zip ; align)open import Data.Product.Base hiding (map ; zip)open import Data.Sum.Base hiding (map)open import Data.These.Base using (These; this; that; these)open import Function.Base using (id)-------------------------------------------------------------------------- Definitiondata Delay {ℓ} (A : Set ℓ) (i : Size) : Set ℓ wherenow : A → Delay A ilater : Thunk (Delay A) i → Delay A imodule _ {ℓ} {A : Set ℓ} wherelength : ∀ {i} → Delay A i → Conat ilength (now _) = zerolength (later d) = suc λ where .force → length (d .force)never : ∀ {i} → Delay A inever = later λ where .force → neverfromMaybe : Maybe A → Delay A ∞fromMaybe = maybe now neverrunFor : ℕ → Delay A ∞ → Maybe ArunFor zero d = nothingrunFor (suc n) (now a) = just arunFor (suc n) (later d) = runFor n (d .force)module _ {ℓ ℓ′} {A : Set ℓ} {B : Set ℓ′} wheremap : (A → B) → ∀ {i} → Delay A i → Delay B imap f (now a) = now (f a)map f (later d) = later λ where .force → map f (d .force)bind : ∀ {i} → Delay A i → (A → Delay B i) → Delay B ibind (now a) f = f abind (later d) f = later λ where .force → bind (d .force) funfold : (A → A ⊎ B) → A → ∀ {i} → Delay B iunfold next seed with next seed... | inj₁ seed′ = later λ where .force → unfold next seed′... | inj₂ b = now bmodule _ {a b c} {A : Set a} {B : Set b} {C : Set c} wherezipWith : (A → B → C) → ∀ {i} → Delay A i → Delay B i → Delay C izipWith f (now a) d = map (f a) dzipWith f d (now b) = map (λ a → f a b) dzipWith f (later a) (later b) = later λ where .force → zipWith f (a .force) (b .force)alignWith : (These A B → C) → ∀ {i} → Delay A i → Delay B i → Delay C ialignWith f (now a) (now b) = now (f (these a b))alignWith f (now a) (later _) = now (f (this a))alignWith f (later _) (now b) = now (f (that b))alignWith f (later a) (later b) = later λ where.force → alignWith f (a .force) (b .force)module _ {a b} {A : Set a} {B : Set b} wherezip : ∀ {i} → Delay A i → Delay B i → Delay (A × B) izip = zipWith _,_align : ∀ {i} → Delay A i → Delay B i → Delay (These A B) ialign = alignWith id-------------------------------------------------------------------------- Finite Delaysmodule _ {ℓ} {A : Set ℓ} whereinfix 3 _⇓data _⇓ : Delay A ∞ → Set ℓ wherenow : ∀ a → now a ⇓later : ∀ {d} → d .force ⇓ → later d ⇓extract : ∀ {d} → d ⇓ → Aextract (now a) = aextract (later d) = extract d¬never⇓ : ¬ (never ⇓)¬never⇓ (later p) = ¬never⇓ plength-⇓ : ∀ {d} → d ⇓ → Finite (length d)length-⇓ (now a) = zerolength-⇓ (later d⇓) = suc (length-⇓ d⇓)module _ {ℓ ℓ′} {A : Set ℓ} {B : Set ℓ′} wheremap-⇓ : ∀ (f : A → B) {d} → d ⇓ → map f d ⇓map-⇓ f (now a) = now (f a)map-⇓ f (later d) = later (map-⇓ f d)bind-⇓ : ∀ {m} (m⇓ : m ⇓) {f : A → Delay B ∞} → f (extract m⇓) ⇓ → bind m f ⇓bind-⇓ (now a) fa⇓ = fa⇓bind-⇓ (later p) fa⇓ = later (bind-⇓ p fa⇓)
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on the Delay type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Delay.Properties whereopen import Sizeimport Data.Sum.Base as Sumimport Data.Nat.Base as ℕopen import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conatopen import Codata.Sized.Conat.Bisimilarity as Coℕ using (zero ; suc)open import Codata.Sized.Delayopen import Codata.Sized.Delay.Bisimilarityopen import Function.Base using (id; _∘′_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)module _ {a} {A : Set a} wherelength-never : ∀ {i} → i Coℕ.⊢ length (never {A = A}) ≈ infinitylength-never = suc λ where .force → length-nevermodule _ {a b} {A : Set a} {B : Set b} wherelength-map : ∀ (f : A → B) da {i} → i Coℕ.⊢ length (map f da) ≈ length dalength-map f (now a) = zerolength-map f (later da) = suc λ where .force → length-map f (da .force)module _ {a b c} {A : Set a} {B : Set b} {C : Set c} wherelength-zipWith : ∀ (f : A → B → C) da db {i} →i Coℕ.⊢ length (zipWith f da db) ≈ length da ⊔ length dblength-zipWith f (now a) db = length-map (f a) dblength-zipWith f da@(later _) (now b) = length-map (λ a → f a b) dalength-zipWith f (later da) (later db) =suc λ where .force → length-zipWith f (da .force) (db .force)map-id : ∀ da {i} → i ⊢ map (id {A = A}) da ≈ damap-id (now a) = now ≡.reflmap-id (later da) = later λ where .force → map-id (da .force)map-∘ : ∀ (f : A → B) (g : B → C) da {i} →i ⊢ map g (map f da) ≈ map (g ∘′ f) damap-∘ f g (now a) = now ≡.reflmap-∘ f g (later da) = later λ where .force → map-∘ f g (da .force)map-unfold : ∀ (f : B → C) n (s : A) {i} →i ⊢ map f (unfold n s) ≈ unfold (Sum.map id f ∘′ n) smap-unfold f n s with n s... | Sum.inj₁ s′ = later λ where .force → map-unfold f n s′... | Sum.inj₂ b = now ≡.refl-------------------------------------------------------------------------- ⇓⇓-unique : ∀ {a} {A : Set a} →{d : Delay A ∞} →(d⇓₁ : d ⇓) → (d⇓₂ : d ⇓) →d⇓₁ ≡ d⇓₂⇓-unique {d = now s} (now s) (now s) = ≡.refl⇓-unique {d = later d'} (later l) (later r) =≡.cong later (⇓-unique {d = force d'} l r)module _ {a} {A B : Set a} wherebind̅₁ : (d : Delay A ∞) {f : A → Delay B ∞} → bind d f ⇓ → d ⇓bind̅₁ (now s) _ = now sbind̅₁ (later s) (later x) =later (bind̅₁ (force s) x)bind̅₂ : (d : Delay A ∞) {f : A → Delay B ∞} →(bind⇓ : bind d f ⇓) →f (extract (bind̅₁ d bind⇓)) ⇓bind̅₂ (now s) foo = foobind̅₂ (later s) {f} (later foo) =bind̅₂ (force s) foo-- The extracted value of a bind is equivalent to the extracted value-- of its second elementextract-bind-⇓ : {d : Delay A Size.∞} → {f : A → Delay B Size.∞} →(d⇓ : d ⇓) → (f⇓ : f (extract d⇓) ⇓) →extract (bind-⇓ d⇓ {f} f⇓) ≡ extract f⇓extract-bind-⇓ (now a) f⇓ = ≡.reflextract-bind-⇓ (later t) f⇓ = extract-bind-⇓ t f⇓-- If the right element of a bind returns a certain value so does the-- entire bindextract-bind̅₂-bind⇓ :(d : Delay A ∞) {f : A → Delay B ∞} →(bind⇓ : bind d f ⇓) →extract (bind̅₂ d bind⇓) ≡ extract bind⇓extract-bind̅₂-bind⇓ (now s) bind⇓ = ≡.reflextract-bind̅₂-bind⇓ (later s) (later bind⇓) =extract-bind̅₂-bind⇓ (force s) bind⇓-- Proof that the length of a bind-⇓ is equal to the sum of the length-- of its components.bind⇓-length :{d : Delay A ∞} {f : A → Delay B ∞} →(bind⇓ : bind d f ⇓) →(d⇓ : d ⇓) → (f⇓ : f (extract d⇓) ⇓) →toℕ (length-⇓ bind⇓) ≡ toℕ (length-⇓ d⇓) ℕ.+ toℕ (length-⇓ f⇓)bind⇓-length {f = f} bind⇓ d⇓@(now s') f⇓ =≡.cong (toℕ ∘′ length-⇓) (⇓-unique bind⇓ f⇓)bind⇓-length {d = d@(later dt)} {f = f} bind⇓@(later bind'⇓) d⇓@(later r) f⇓ =≡.cong ℕ.suc (bind⇓-length bind'⇓ r f⇓)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-identity = map-id{-# WARNING_ON_USAGE map-identity"Warning: map-identity was deprecated in v2.0.Please use map-id instead."#-}map-map-fusion = map-∘{-# WARNING_ON_USAGE map-map-fusion"Warning: map-map-fusion was deprecated in v2.0.Please use map-∘ instead."#-}map-unfold-fusion = map-unfold{-# WARNING_ON_USAGE map-unfold-fusion"Warning: map-unfold-fusion was deprecated in v2.0.Please use map-unfold instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Delay------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Delay.Effectful whereopen import Codata.Sized.Delayopen import Function.Base using (id)open import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativeopen import Effect.Monadopen import Data.These using (leftMost)functor : ∀ {i ℓ} → RawFunctor {ℓ} (λ A → Delay A i)functor = record { _<$>_ = λ f → map f }module Sequential whereapplicative : ∀ {i ℓ} → RawApplicative {ℓ} (λ A → Delay A i)applicative = record{ rawFunctor = functor; pure = now; _<*>_ = λ df da → bind df (λ f → map f da)}empty : ∀ {i ℓ} → RawEmpty {ℓ} (λ A → Delay A i)empty = record { empty = never }applicativeZero : ∀ {i ℓ} → RawApplicativeZero {ℓ} (λ A → Delay A i)applicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}monad : ∀ {i ℓ} → RawMonad {ℓ} (λ A → Delay A i)monad = record{ rawApplicative = applicative; _>>=_ = bind}monadZero : ∀ {i ℓ} → RawMonadZero {ℓ} (λ A → Delay A i)monadZero = record{ rawMonad = monad; rawEmpty = empty}module Zippy whereapplicative : ∀ {i ℓ} → RawApplicative {ℓ} (λ A → Delay A i)applicative = record{ rawFunctor = functor; pure = now; _<*>_ = zipWith id}empty : ∀ {i ℓ} → RawEmpty {ℓ} (λ A → Delay A i)empty = record { empty = never }applicativeZero : ∀ {i ℓ} → RawApplicativeZero {ℓ} (λ A → Delay A i)applicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}choice : ∀ {i ℓ} → RawChoice {ℓ} (λ A → Delay A i)choice = record { _<|>_ = alignWith leftMost }alternative : ∀ {i ℓ} → RawAlternative {ℓ} (λ A → Delay A i)alternative = record{ rawApplicativeZero = applicativeZero; rawChoice = choice}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Codata.Sized.Delay.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Delay.Categorical whereopen import Codata.Sized.Delay.Effectful public{-# WARNING_ON_IMPORT"Codata.Sized.Delay.Categorical was deprecated in v2.0.Use Codata.Sized.Delay.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for the Delay type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Delay.Bisimilarity whereopen import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Delayopen import Levelopen import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Sym; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)data Bisim {a b r} {A : Set a} {B : Set b} (R : A → B → Set r) i :(xs : Delay A ∞) (ys : Delay B ∞) → Set (a ⊔ b ⊔ r) wherenow : ∀ {x y} → R x y → Bisim R i (now x) (now y)later : ∀ {xs ys} → Thunk^R (Bisim R) i xs ys → Bisim R i (later xs) (later ys)module _ {a r} {A : Set a} {R : A → A → Set r} wherereflexive : Reflexive R → ∀ {i} → Reflexive (Bisim R i)reflexive refl^R {i} {now r} = now refl^Rreflexive refl^R {i} {later rs} = later λ where .force → reflexive refl^Rmodule _ {a b} {A : Set a} {B : Set b}{r} {P : A → B → Set r} {Q : B → A → Set r} wheresymmetric : Sym P Q → ∀ {i} → Sym (Bisim P i) (Bisim Q i)symmetric sym^PQ (now p) = now (sym^PQ p)symmetric sym^PQ (later ps) = later λ where .force → symmetric sym^PQ (ps .force)module _ {a b c} {A : Set a} {B : Set b} {C : Set c}{r} {P : A → B → Set r} {Q : B → C → Set r} {R : A → C → Set r} wheretransitive : Trans P Q R → ∀ {i} → Trans (Bisim P i) (Bisim Q i) (Bisim R i)transitive trans^PQR (now p) (now q) = now (trans^PQR p q)transitive trans^PQR (later ps) (later qs) =later λ where .force → transitive trans^PQR (ps .force) (qs .force)-- Pointwise Equality as a Bisimilarity------------------------------------------------------------------------module _ {ℓ} {A : Set ℓ} whereinfix 1 _⊢_≈__⊢_≈_ : ∀ i → Delay A ∞ → Delay A ∞ → Set ℓ_⊢_≈_ = Bisim _≡_refl : ∀ {i} → Reflexive (i ⊢_≈_)refl = reflexive ≡.reflsym : ∀ {i} → Symmetric (i ⊢_≈_)sym = symmetric ≡.symtrans : ∀ {i} → Transitive (i ⊢_≈_)trans = transitive ≡.trans
-------------------------------------------------------------------------- The Agda standard library---- The Cowriter type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Cowriter whereopen import Sizeopen import Level as L using (Level)open import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conatopen import Codata.Sized.Delay using (Delay; later; now)open import Codata.Sized.Stream as Stream using (Stream; _∷_)open import Data.Unit.Baseopen import Data.List.Base using (List; []; _∷_)open import Data.List.NonEmpty.Base using (List⁺; _∷_)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Data.Product.Base as Product using (_×_; _,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.Vec.Bounded.Base as Vec≤ using (Vec≤; _,_)open import Function.Base using (_$_; _∘′_; id)privatevariablea b w x : LevelA : Set aB : Set bW : Set wX : Set x-------------------------------------------------------------------------- Definitiondata Cowriter (W : Set w) (A : Set a) (i : Size) : Set (a L.⊔ w) where[_] : A → Cowriter W A i_∷_ : W → Thunk (Cowriter W A) i → Cowriter W A iinfixr 5 _∷_-------------------------------------------------------------------------- Relationship to Delay.fromDelay : ∀ {i} → Delay A i → Cowriter ⊤ A ifromDelay (now a) = [ a ]fromDelay (later da) = _ ∷ λ where .force → fromDelay (da .force)toDelay : ∀ {i} → Cowriter W A i → Delay A itoDelay [ a ] = now atoDelay (_ ∷ ca) = later λ where .force → toDelay (ca .force)-------------------------------------------------------------------------- Basic functions.fromStream : ∀ {i} → Stream W i → Cowriter W A ifromStream (w ∷ ws) = w ∷ λ where .force → fromStream (ws .force)repeat : W → Cowriter W A ∞repeat = fromStream ∘′ Stream.repeatlength : ∀ {i} → Cowriter W A i → Conat ilength [ _ ] = zerolength (w ∷ cw) = suc λ where .force → length (cw .force)splitAt : ∀ (n : ℕ) → Cowriter W A ∞ → (Vec W n × Cowriter W A ∞) ⊎ (Vec≤ W n × A)splitAt zero cw = inj₁ ([] , cw)splitAt (suc n) [ a ] = inj₂ (Vec≤.[] , a)splitAt (suc n) (w ∷ cw) = Sum.map (Product.map₁ (w ∷_)) (Product.map₁ (w Vec≤.∷_))$ splitAt n (cw .force)take : ∀ (n : ℕ) → Cowriter W A ∞ → Vec W n ⊎ (Vec≤ W n × A)take n = Sum.map₁ Product.proj₁ ∘′ splitAt ninfixr 5 _++_ _⁺++__++_ : ∀ {i} → List W → Cowriter W A i → Cowriter W A i[] ++ ca = ca(w ∷ ws) ++ ca = w ∷ λ where .force → ws ++ ca_⁺++_ : ∀ {i} → List⁺ W → Thunk (Cowriter W A) i → Cowriter W A i(w ∷ ws) ⁺++ ca = w ∷ λ where .force → ws ++ ca .forceconcat : ∀ {i} → Cowriter (List⁺ W) A i → Cowriter W A iconcat [ a ] = [ a ]concat (w ∷ ca) = w ⁺++ λ where .force → concat (ca .force)-------------------------------------------------------------------------- Functor, Applicative and Monadmap : ∀ {i} → (W → X) → (A → B) → Cowriter W A i → Cowriter X B imap f g [ a ] = [ g a ]map f g (w ∷ cw) = f w ∷ λ where .force → map f g (cw .force)map₁ : ∀ {i} → (W → X) → Cowriter W A i → Cowriter X A imap₁ f = map f idmap₂ : ∀ {i} → (A → X) → Cowriter W A i → Cowriter W X imap₂ = map idap : ∀ {i} → Cowriter W (A → X) i → Cowriter W A i → Cowriter W X iap [ f ] ca = map₂ f caap (w ∷ cf) ca = w ∷ λ where .force → ap (cf .force) cainfixl 1 _>>=__>>=_ : ∀ {i} → Cowriter W A i → (A → Cowriter W X i) → Cowriter W X i[ a ] >>= f = f a(w ∷ ca) >>= f = w ∷ λ where .force → ca .force >>= f-------------------------------------------------------------------------- Construction.unfold : ∀ {i} → (X → (W × X) ⊎ A) → X → Cowriter W A iunfold next seed =Sum.[ (λ where (w , seed′) → w ∷ λ where .force → unfold next seed′), [_]] (next seed)
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for Cowriter------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Cowriter.Bisimilarity whereopen import Level using (Level; _⊔_)open import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Cowriteropen import Relation.Binary.Core using (REL; Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Sym; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b c p q pq r s rs v w x : LevelA : Set aB : Set bC : Set cV : Set vW : Set wX : Set xi : Sizedata Bisim {V : Set v} {W : Set w} {A : Set a} {B : Set b}(R : REL V W r) (S : REL A B s) (i : Size) :REL (Cowriter V A ∞) (Cowriter W B ∞) (r ⊔ s ⊔ v ⊔ w ⊔ a ⊔ b) where[_] : ∀ {a b} → S a b → Bisim R S i [ a ] [ b ]_∷_ : ∀ {x y xs ys} → R x y → Thunk^R (Bisim R S) i xs ys →Bisim R S i (x ∷ xs) (y ∷ ys)infixr 5 _∷_module _ {R : Rel W r} {S : Rel A s}(refl^R : Reflexive R) (refl^S : Reflexive S) wherereflexive : Reflexive (Bisim R S i)reflexive {x = [ a ]} = [ refl^S ]reflexive {x = w ∷ ws} = refl^R ∷ λ where .force → reflexivemodule _ {R : REL V W r} {S : REL W V s} {P : REL A B p} {Q : REL B A q}(sym^RS : Sym R S) (sym^PQ : Sym P Q) wheresymmetric : Sym (Bisim R P i) (Bisim S Q i)symmetric [ a ] = [ sym^PQ a ]symmetric (p ∷ ps) = sym^RS p ∷ λ where .force → symmetric (ps .force)module _ {R : REL V W r} {S : REL W X s} {RS : REL V X rs}{P : REL A B p} {Q : REL B C q} {PQ : REL A C pq}(trans^RS : Trans R S RS) (trans^PQ : Trans P Q PQ) wheretransitive : Trans (Bisim R P i) (Bisim S Q i) (Bisim RS PQ i)transitive [ p ] [ q ] = [ trans^PQ p q ]transitive (p ∷ ps) (q ∷ qs) =trans^RS p q ∷ λ where .force → transitive (ps .force) (qs .force)-- Pointwise Equality as a Bisimilarity------------------------------------------------------------------------module _ {W : Set w} {A : Set a} whereinfix 1 _⊢_≈__⊢_≈_ : ∀ i → Cowriter W A ∞ → Cowriter W A ∞ → Set (a ⊔ w)_⊢_≈_ = Bisim _≡_ _≡_refl : Reflexive (i ⊢_≈_)refl = reflexive ≡.refl ≡.reflfromEq : ∀ {as bs} → as ≡ bs → i ⊢ as ≈ bsfromEq ≡.refl = reflsym : Symmetric (i ⊢_≈_)sym = symmetric ≡.sym ≡.symtrans : Transitive (i ⊢_≈_)trans = transitive ≡.trans ≡.transmodule _ {R : Rel W r} {S : Rel A s}(equiv^R : IsEquivalence R) (equiv^S : IsEquivalence S) whereprivatemodule equiv^R = IsEquivalence equiv^Rmodule equiv^S = IsEquivalence equiv^SisEquivalence : IsEquivalence (Bisim R S i)isEquivalence = record{ refl = reflexive equiv^R.refl equiv^S.refl; sym = symmetric equiv^R.sym equiv^S.sym; trans = transitive equiv^R.trans equiv^S.trans}setoid : Setoid w r → Setoid a s → Size → Setoid (w ⊔ a) (w ⊔ a ⊔ r ⊔ s)setoid R S i = record{ isEquivalence = isEquivalence (Setoid.isEquivalence R)(Setoid.isEquivalence S) {i = i}}module ≈-Reasoning {W : Set w} {A : Set a} {i} whereopen import Relation.Binary.Reasoning.Setoid(setoid (≡.setoid W) (≡.setoid A) i) public
-------------------------------------------------------------------------- The Agda standard library---- The Covec type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec whereopen import Sizeopen import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conat as Conatopen import Codata.Sized.Conat.Bisimilarityopen import Codata.Sized.Conat.Propertiesopen import Codata.Sized.Cofin as Cofin using (Cofin; zero; suc)open import Codata.Sized.Colist as Colist using (Colist ; [] ; _∷_)open import Codata.Sized.Stream as Stream using (Stream ; _∷_)open import Level using (Level)privatevariablea b : LevelA : Set aB : Set bdata Covec (A : Set a) (i : Size) : Conat ∞ → Set a where[] : Covec A i zero_∷_ : ∀ {n} → A → Thunk (λ i → Covec A i (n .force)) i → Covec A i (suc n)infixr 5 _∷_head : ∀ {n i} → Covec A i (suc n) → Ahead (x ∷ _) = xtail : ∀ {n} → Covec A ∞ (suc n) → Covec A ∞ (n .force)tail (_ ∷ xs) = xs .forcelookup : ∀ {n} → Covec A ∞ n → Cofin n → Alookup as zero = head aslookup as (suc k) = lookup (tail as) kreplicate : ∀ {i} → (n : Conat ∞) → A → Covec A i nreplicate zero a = []replicate (suc n) a = a ∷ λ where .force → replicate (n .force) acotake : ∀ {i} → (n : Conat ∞) → Stream A i → Covec A i ncotake zero xs = []cotake (suc n) (x ∷ xs) = x ∷ λ where .force → cotake (n .force) (xs .force)infixr 5 _++__++_ : ∀ {i m n} → Covec A i m → Covec A i n → Covec A i (m + n)[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ λ where .force → xs .force ++ ysfromColist : ∀ {i} → (xs : Colist A ∞) → Covec A i (Colist.length xs)fromColist [] = []fromColist (x ∷ xs) = x ∷ λ where .force → fromColist (xs .force)toColist : ∀ {i n} → Covec A i n → Colist A itoColist [] = []toColist (x ∷ xs) = x ∷ λ where .force → toColist (xs .force)fromStream : ∀ {i} → Stream A i → Covec A i infinityfromStream = cotake infinitycast : ∀ {i} {m n} → i ⊢ m ≈ n → Covec A i m → Covec A i ncast zero [] = []cast (suc eq) (a ∷ as) = a ∷ λ where .force → cast (eq .force) (as .force)module _ {a b} {A : Set a} {B : Set b} wheremap : ∀ {i n} (f : A → B) → Covec A i n → Covec B i nmap f [] = []map f (a ∷ as) = f a ∷ λ where .force → map f (as .force)ap : ∀ {i n} → Covec (A → B) i n → Covec A i n → Covec B i nap [] [] = []ap (f ∷ fs) (a ∷ as) = (f a) ∷ λ where .force → ap (fs .force) (as .force)scanl : ∀ {i n} → (B → A → B) → B → Covec A i n → Covec B i (1 ℕ+ n)scanl c n [] = n ∷ λ where .force → []scanl c n (a ∷ as) = n ∷ λ where.force → cast (suc λ where .force → 0ℕ+-identity)(scanl c (c n a) (as .force))module _ {a b c} {A : Set a} {B : Set b} {C : Set c} wherezipWith : ∀ {i n} → (A → B → C) → Covec A i n → Covec B i n → Covec C i nzipWith f [] [] = []zipWith f (a ∷ as) (b ∷ bs) =f a b ∷ λ where .force → zipWith f (as .force) (bs .force)
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on the Covec type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec.Properties whereopen import Sizeopen import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conatopen import Codata.Sized.Covecopen import Codata.Sized.Covec.Bisimilarityopen import Function.Base using (id; _∘_)open import Relation.Binary.PropositionalEquality.Core as ≡-- Functor lawsmodule _ {a} {A : Set a} wheremap-id : ∀ {m} (as : Covec A ∞ m) {i} → i , m ⊢ map id as ≈ asmap-id [] = []map-id (a ∷ as) = ≡.refl ∷ λ where .force → map-id (as .force)module _ {a b c} {A : Set a} {B : Set b} {C : Set c} wheremap-∘ : ∀ (f : A → B) (g : B → C) {m} as {i} → i , m ⊢ map g (map f as) ≈ map (g ∘ f) asmap-∘ f g [] = []map-∘ f g (a ∷ as) = ≡.refl ∷ λ where .force → map-∘ f g (as .force)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-identity = map-id{-# WARNING_ON_USAGE map-identity"Warning: map-identity was deprecated in v2.0.Please use map-id instead."#-}map-map-fusion = map-∘{-# WARNING_ON_USAGE map-map-fusion"Warning: map-map-fusion was deprecated in v2.0.Please use map-∘ instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Typeclass instances for Covec------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec.Instances whereopen import Codata.Sized.Covec.EffectfulinstancecovecFunctor = functorcovecApplicative = applicative
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Covec------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec.Effectful whereopen import Codata.Sized.Conatopen import Codata.Sized.Covecopen import Effect.Functoropen import Effect.Applicativefunctor : ∀ {ℓ i n} → RawFunctor {ℓ} (λ A → Covec A n i)functor = record { _<$>_ = map }applicative : ∀ {ℓ i n} → RawApplicative {ℓ} (λ A → Covec A n i)applicative = record{ rawFunctor = functor; pure = replicate _; _<*>_ = ap}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Codata.Sized.Covec.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec.Categorical whereopen import Codata.Sized.Covec.Effectful public{-# WARNING_ON_IMPORT"Codata.Sized.Covec.Categorical was deprecated in v2.0.Use Codata.Sized.Covec.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for Covecs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Covec.Bisimilarity whereopen import Level using (_⊔_)open import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Conat hiding (_⊔_)open import Codata.Sized.Covecopen import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Sym; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)data Bisim {a b r} {A : Set a} {B : Set b} (R : A → B → Set r) (i : Size) :∀ m n (xs : Covec A ∞ m) (ys : Covec B ∞ n) → Set (r ⊔ a ⊔ b) where[] : Bisim R i zero zero [] []_∷_ : ∀ {x y m n xs ys} → R x y → Thunk^R (λ i → Bisim R i (m .force) (n .force)) i xs ys →Bisim R i (suc m) (suc n) (x ∷ xs) (y ∷ ys)infixr 5 _∷_module _ {a r} {A : Set a} {R : A → A → Set r} wherereflexive : Reflexive R → ∀ {i m} → Reflexive (Bisim R i m m)reflexive refl^R {i} {m} {[]} = []reflexive refl^R {i} {m} {r ∷ rs} = refl^R ∷ λ where .force → reflexive refl^Rmodule _ {a b} {A : Set a} {B : Set b}{r} {P : A → B → Set r} {Q : B → A → Set r} wheresymmetric : Sym P Q → ∀ {i m n} → Sym (Bisim P i m n) (Bisim Q i n m)symmetric sym^PQ [] = []symmetric sym^PQ (p ∷ ps) = sym^PQ p ∷ λ where .force → symmetric sym^PQ (ps .force)module _ {a b c} {A : Set a} {B : Set b} {C : Set c}{r} {P : A → B → Set r} {Q : B → C → Set r} {R : A → C → Set r} wheretransitive : Trans P Q R → ∀ {i m n p} → Trans (Bisim P i m n) (Bisim Q i n p) (Bisim R i m p)transitive trans^PQR [] [] = []transitive trans^PQR (p ∷ ps) (q ∷ qs) =trans^PQR p q ∷ λ where .force → transitive trans^PQR (ps .force) (qs .force)-- Pointwise Equality as a Bisimilarity------------------------------------------------------------------------module _ {ℓ} {A : Set ℓ} whereinfix 1 _,_⊢_≈__,_⊢_≈_ : ∀ i m → Covec A ∞ m → Covec A ∞ m → Set ℓ_,_⊢_≈_ i m = Bisim _≡_ i m mrefl : ∀ {i m} → Reflexive (i , m ⊢_≈_)refl = reflexive ≡.reflsym : ∀ {i m} → Symmetric (i , m ⊢_≈_)sym = symmetric ≡.symtrans : ∀ {i m} → Transitive (i , m ⊢_≈_)trans = transitive ≡.trans
-------------------------------------------------------------------------- The Agda standard library---- The Conat type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Conat whereopen import Sizeopen import Codata.Sized.Thunkopen import Data.Nat.Base using (ℕ ; zero ; suc)open import Relation.Nullary-------------------------------------------------------------------------- Definition and first valuesdata Conat (i : Size) : Set wherezero : Conat isuc : Thunk Conat i → Conat iinfinity : ∀ {i} → Conat iinfinity = suc λ where .force → infinityfromℕ : ℕ → Conat ∞fromℕ zero = zerofromℕ (suc n) = suc λ where .force → fromℕ n-------------------------------------------------------------------------- Arithmetic operationspred : ∀ {i} {j : Size< i} → Conat i → Conat jpred zero = zeropred (suc n) = n .forceinfixl 6 _∸_ _+_ _ℕ+_ _+ℕ_infixl 7 _*__∸_ : Conat ∞ → ℕ → Conat ∞m ∸ zero = mm ∸ suc n = pred m ∸ n_ℕ+_ : ℕ → ∀ {i} → Conat i → Conat izero ℕ+ n = nsuc m ℕ+ n = suc λ where .force → m ℕ+ n_+ℕ_ : ∀ {i} → Conat i → ℕ → Conat izero +ℕ n = fromℕ nsuc m +ℕ n = suc λ where .force → (m .force) +ℕ n_+_ : ∀ {i} → Conat i → Conat i → Conat izero + n = nsuc m + n = suc λ where .force → (m .force) + n_*_ : ∀ {i} → Conat i → Conat i → Conat im * zero = zerozero * n = zerosuc m * suc n = suc λ where .force → n .force + (m .force * suc n)-- Max and Mininfixl 6 _⊔_infixl 7 _⊓__⊔_ : ∀ {i} → Conat i → Conat i → Conat izero ⊔ n = nm ⊔ zero = msuc m ⊔ suc n = suc λ where .force → m .force ⊔ n .force_⊓_ : ∀ {i} → Conat i → Conat i → Conat izero ⊓ n = zerom ⊓ zero = zerosuc m ⊓ suc n = suc λ where .force → m .force ⊓ n .force-------------------------------------------------------------------------- Finitenessdata Finite : Conat ∞ → Set wherezero : Finite zerosuc : ∀ {n} → Finite (n .force) → Finite (suc n)toℕ : ∀ {n} → Finite n → ℕtoℕ zero = zerotoℕ (suc n) = suc (toℕ n)¬Finite∞ : ¬ (Finite infinity)¬Finite∞ (suc p) = ¬Finite∞ p-------------------------------------------------------------------------- Order wrt to Natinfix 4 _ℕ<_ _ℕ≤infinity _ℕ≤_data _ℕ≤_ : ℕ → Conat ∞ → Set wherezℕ≤n : ∀ {n} → zero ℕ≤ nsℕ≤s : ∀ {k n} → k ℕ≤ n .force → suc k ℕ≤ suc n_ℕ<_ : ℕ → Conat ∞ → Setk ℕ< n = suc k ℕ≤ n_ℕ≤infinity : ∀ k → k ℕ≤ infinityzero ℕ≤infinity = zℕ≤nsuc k ℕ≤infinity = sℕ≤s (k ℕ≤infinity)
-------------------------------------------------------------------------- The Agda standard library---- Properties for Conats------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Conat.Properties whereopen import Sizeopen import Data.Nat.Base using (ℕ; zero; suc)open import Codata.Sized.Thunkopen import Codata.Sized.Conatopen import Codata.Sized.Conat.Bisimilarityopen import Function.Base using (_∋_)open import Relation.Nullaryopen import Relation.Nullary.Decidable using (map′)open import Relation.Binary.Definitions using (Decidable)privatevariablei : Size0∸m≈0 : ∀ m → i ⊢ zero ∸ m ≈ zero0∸m≈0 zero = refl0∸m≈0 (suc m) = 0∸m≈0 msℕ≤s⁻¹ : ∀ {m n} → suc m ℕ≤ suc n → m ℕ≤ n .forcesℕ≤s⁻¹ (sℕ≤s p) = pinfix 4 _ℕ≤?__ℕ≤?_ : Decidable _ℕ≤_zero ℕ≤? n = yes zℕ≤nsuc m ℕ≤? zero = no (λ ())suc m ℕ≤? suc n = map′ sℕ≤s sℕ≤s⁻¹ (m ℕ≤? n .force)0ℕ+-identity : ∀ {n} → i ⊢ 0 ℕ+ n ≈ n0ℕ+-identity = refl+ℕ0-identity : ∀ {n} → i ⊢ n +ℕ 0 ≈ n+ℕ0-identity {n = zero} = zero+ℕ0-identity {n = suc n} = suc λ where .force → +ℕ0-identity
-------------------------------------------------------------------------- The Agda standard library---- Conat Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Conat.Literals whereopen import Agda.Builtin.FromNat using (Number)open import Data.Unit.Base using (⊤)open import Codata.Sized.Conat using (Conat; fromℕ)number : ∀ {i} → Number (Conat i)number = record{ Constraint = λ _ → ⊤; fromNat = λ n → fromℕ n}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for Conats------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Conat.Bisimilarity whereopen import Level using (0ℓ)open import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Conatopen import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)infix 1 _⊢_≈_data _⊢_≈_ i : (m n : Conat ∞) → Set wherezero : i ⊢ zero ≈ zerosuc : ∀ {m n} → Thunk^R _⊢_≈_ i m n → i ⊢ suc m ≈ suc nrefl : ∀ {i m} → i ⊢ m ≈ mrefl {m = zero} = zerorefl {m = suc m} = suc λ where .force → reflsym : ∀ {i m n} → i ⊢ m ≈ n → i ⊢ n ≈ msym zero = zerosym (suc eq) = suc λ where .force → sym (eq .force)trans : ∀ {i m n p} → i ⊢ m ≈ n → i ⊢ n ≈ p → i ⊢ m ≈ ptrans zero zero = zerotrans (suc eq₁) (suc eq₂) = suc λ where .force → trans (eq₁ .force) (eq₂ .force)isEquivalence : ∀ {i} → IsEquivalence (i ⊢_≈_)isEquivalence = record{ refl = refl; sym = sym; trans = trans}setoid : Size → Setoid 0ℓ 0ℓsetoid i = record{ isEquivalence = isEquivalence {i = i}}module ≈-Reasoning {i} whereopen import Relation.Binary.Reasoning.Setoid (setoid i) publicinfix 1 _⊢_≲_data _⊢_≲_ i : (m n : Conat ∞) → Set wherez≲n : ∀ {n} → i ⊢ zero ≲ ns≲s : ∀ {m n} → Thunk^R _⊢_≲_ i m n → i ⊢ suc m ≲ suc n≈⇒≲ : ∀ {i m n} → i ⊢ m ≈ n → i ⊢ m ≲ n≈⇒≲ zero = z≲n≈⇒≲ (suc eq) = s≲s λ where .force → ≈⇒≲ (eq .force)≲-refl : ∀ {i m} → i ⊢ m ≲ m≲-refl = ≈⇒≲ refl≲-antisym : ∀ {i m n} → i ⊢ m ≲ n → i ⊢ n ≲ m → i ⊢ m ≈ n≲-antisym z≲n z≲n = zero≲-antisym (s≲s le) (s≲s ge) = suc λ where .force → ≲-antisym (le .force) (ge .force)≲-trans : ∀ {i m n p} → i ⊢ m ≲ n → i ⊢ n ≲ p → i ⊢ m ≲ p≲-trans z≲n _ = z≲n≲-trans (s≲s le₁) (s≲s le₂) = s≲s λ where .force → ≲-trans (le₁ .force) (le₂ .force)
-------------------------------------------------------------------------- The Agda standard library---- The Colist type and some operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Colist whereopen import Level using (Level)open import Sizeopen import Data.Unit.Baseopen import Data.Nat.Baseopen import Data.Product.Base using (_×_ ; _,_)open import Data.These.Base using (These; this; that; these)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.List.Base using (List; []; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Data.Vec.Bounded.Base as Vec≤ using (Vec≤)open import Function.Base using (_$′_; _∘′_; id; _∘_)open import Codata.Sized.Thunk using (Thunk; force)open import Codata.Sized.Conat as Conat using (Conat ; zero ; suc)open import Codata.Sized.Cowriter as CW using (Cowriter; _∷_)open import Codata.Sized.Delay as Delay using (Delay ; now ; later)open import Codata.Sized.Stream using (Stream ; _∷_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b c w : Leveli : SizeA : Set aB : Set bC : Set cW : Set wdata Colist (A : Set a) (i : Size) : Set a where[] : Colist A i_∷_ : A → Thunk (Colist A) i → Colist A iinfixr 5 _∷_-------------------------------------------------------------------------- Relationship to Cowriter.fromCowriter : Cowriter W A i → Colist W ifromCowriter CW.[ _ ] = []fromCowriter (w ∷ ca) = w ∷ λ where .force → fromCowriter (ca .force)toCowriter : Colist A i → Cowriter A ⊤ itoCowriter [] = CW.[ _ ]toCowriter (a ∷ as) = a ∷ λ where .force → toCowriter (as .force)-------------------------------------------------------------------------- Basic functions.[_] : A → Colist A ∞[ a ] = a ∷ λ where .force → []length : Colist A i → Conat ilength [] = zerolength (x ∷ xs) = suc λ where .force → length (xs .force)replicate : Conat i → A → Colist A ireplicate zero a = []replicate (suc n) a = a ∷ λ where .force → replicate (n .force) ainfixr 5 _++_ _⁺++__++_ : Colist A i → Colist A i → Colist A i[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ λ where .force → xs .force ++ yslookup : Colist A ∞ → ℕ → Maybe Alookup [] _ = nothinglookup (a ∷ as) zero = just alookup (a ∷ as) (suc n) = lookup (as .force) ncolookup : Colist A i → Conat i → Delay (Maybe A) icolookup [] _ = now nothingcolookup (a ∷ as) zero = now (just a)colookup (a ∷ as) (suc n) =later λ where .force → colookup (as .force) (n .force)take : (n : ℕ) → Colist A ∞ → Vec≤ A ntake zero xs = Vec≤.[]take n [] = Vec≤.[]take (suc n) (x ∷ xs) = x Vec≤.∷ take n (xs .force)cotake : Conat i → Stream A i → Colist A icotake zero xs = []cotake (suc n) (x ∷ xs) = x ∷ λ where .force → cotake (n .force) (xs .force)drop : ℕ → Colist A ∞ → Colist A ∞drop zero xs = xsdrop (suc n) [] = []drop (suc n) (x ∷ xs) = drop n (xs .force)fromList : List A → Colist A ∞fromList [] = []fromList (x ∷ xs) = x ∷ λ where .force → fromList xsfromList⁺ : List⁺ A → Colist A ∞fromList⁺ = fromList ∘′ List⁺.toList_⁺++_ : List⁺ A → Thunk (Colist A) i → Colist A i(x ∷ xs) ⁺++ ys = x ∷ λ where .force → fromList xs ++ ys .forceconcat : Colist (List⁺ A) i → Colist A iconcat [] = []concat (as ∷ ass) = as ⁺++ λ where .force → concat (ass .force)fromStream : Stream A i → Colist A ifromStream = cotake Conat.infinitymodule ChunksOf (n : ℕ) wherechunksOf : Colist A ∞ → Cowriter (Vec A n) (Vec≤ A n) ichunksOfAcc : ∀ m →-- We have two continuations but we are only ever going to use one.-- If we had linear types, we'd write the type using the & conjunction here.(k≤ : Vec≤ A m → Vec≤ A n) →(k≡ : Vec A m → Vec A n) →-- Finally we chop up the input stream.Colist A ∞ → Cowriter (Vec A n) (Vec≤ A n) ichunksOf = chunksOfAcc n id idchunksOfAcc zero k≤ k≡ as = k≡ [] ∷ λ where .force → chunksOf aschunksOfAcc (suc k) k≤ k≡ [] = CW.[ k≤ Vec≤.[] ]chunksOfAcc (suc k) k≤ k≡ (a ∷ as) =chunksOfAcc k (k≤ ∘ (a Vec≤.∷_)) (k≡ ∘ (a ∷_)) (as .force)open ChunksOf using (chunksOf) public-- Test to make sure that the values are kept in the same order_ : chunksOf 3 (fromList (1 ∷ 2 ∷ 3 ∷ 4 ∷ []))≡ (1 ∷ 2 ∷ 3 ∷ []) ∷ __ = reflmap : (A → B) → Colist A i → Colist B imap f [] = []map f (a ∷ as) = f a ∷ λ where .force → map f (as .force)unfold : (A → Maybe (A × B)) → A → Colist B iunfold next seed with next seed... | nothing = []... | just (seed′ , b) = b ∷ λ where .force → unfold next seed′scanl : (B → A → B) → B → Colist A i → Colist B iscanl c n [] = n ∷ λ where .force → []scanl c n (a ∷ as) = n ∷ λ where .force → scanl c (c n a) (as .force)alignWith : (These A B → C) → Colist A i → Colist B i → Colist C ialignWith f [] bs = map (f ∘′ that) bsalignWith f as@(_ ∷ _) [] = map (f ∘′ this) asalignWith f (a ∷ as) (b ∷ bs) =f (these a b) ∷ λ where .force → alignWith f (as .force) (bs .force)zipWith : (A → B → C) → Colist A i → Colist B i → Colist C izipWith f [] bs = []zipWith f as [] = []zipWith f (a ∷ as) (b ∷ bs) =f a b ∷ λ where .force → zipWith f (as .force) (bs .force)align : Colist A i → Colist B i → Colist (These A B) ialign = alignWith idzip : Colist A i → Colist B i → Colist (A × B) izip = zipWith _,_ap : Colist (A → B) i → Colist A i → Colist B iap = zipWith _$′_
-------------------------------------------------------------------------- The Agda standard library---- Properties of operations on the Colist type------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Colist.Properties whereopen import Level using (Level)open import Sizeopen import Codata.Sized.Thunk as Thunk using (Thunk; force)open import Codata.Sized.Colistopen import Codata.Sized.Colist.Bisimilarityopen import Codata.Sized.Conatopen import Codata.Sized.Conat.Bisimilarity as Conat using (zero; suc)import Codata.Sized.Conat.Properties as Conatopen import Codata.Sized.Cowriter as Cowriter using ([_]; _∷_)open import Codata.Sized.Cowriter.Bisimilarity as Cowriter using ([_]; _∷_)open import Codata.Sized.Stream as Stream using (Stream; _∷_)open import Data.Vec.Bounded as Vec≤ using (Vec≤)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)import Data.List.Scans.Base as Scansopen import Data.List.Relation.Binary.Equality.Propositional using (≋-refl)open import Data.Maybe.Base as Maybe using (Maybe; nothing; just)import Data.Maybe.Properties as Maybeopen import Data.Maybe.Relation.Unary.All using (All; nothing; just)open import Data.Nat.Base as ℕ using (zero; suc; z≤n; s≤s)open import Data.Product.Base as Product using (_×_; _,_; uncurry)open import Data.These.Base as These using (These; this; that; these)open import Data.Vec.Base as Vec using (Vec; []; _∷_)open import Function.Baseopen import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea b c d : LevelA : Set aB : Set bC : Set cD : Set di : Size-------------------------------------------------------------------------- Functor lawsmap-id : ∀ (as : Colist A ∞) → i ⊢ map id as ≈ asmap-id [] = []map-id (a ∷ as) = ≡.refl ∷ λ where .force → map-id (as .force)map-∘ : ∀ (f : A → B) (g : B → C) as {i} →i ⊢ map g (map f as) ≈ map (g ∘ f) asmap-∘ f g [] = []map-∘ f g (a ∷ as) =≡.refl ∷ λ where .force → map-∘ f g (as .force)-------------------------------------------------------------------------- Relation to CowriterfromCowriter∘toCowriter≗id : ∀ (as : Colist A ∞) →i ⊢ fromCowriter (toCowriter as) ≈ asfromCowriter∘toCowriter≗id [] = []fromCowriter∘toCowriter≗id (a ∷ as) =≡.refl ∷ λ where .force → fromCowriter∘toCowriter≗id (as .force)-------------------------------------------------------------------------- Properties of lengthlength-∷ : ∀ (a : A) as → i Conat.⊢ length (a ∷ as) ≈ 1 ℕ+ length (as .force)length-∷ a as = suc (λ where .force → Conat.refl)length-replicate : ∀ n (a : A) → i Conat.⊢ length (replicate n a) ≈ nlength-replicate zero a = zerolength-replicate (suc n) a = suc λ where .force → length-replicate (n .force) alength-++ : (as bs : Colist A ∞) →i Conat.⊢ length (as ++ bs) ≈ length as + length bslength-++ [] bs = Conat.refllength-++ (a ∷ as) bs = suc λ where .force → length-++ (as .force) bslength-map : ∀ (f : A → B) as → i Conat.⊢ length (map f as) ≈ length aslength-map f [] = zerolength-map f (a ∷ as) = suc λ where .force → length-map f (as .force)-------------------------------------------------------------------------- Properties of replicatereplicate-+ : ∀ m n (a : A) →i ⊢ replicate (m + n) a ≈ replicate m a ++ replicate n areplicate-+ zero n a = reflreplicate-+ (suc m) n a = ≡.refl ∷ λ where .force → replicate-+ (m .force) n amap-replicate : ∀ (f : A → B) n a →i ⊢ map f (replicate n a) ≈ replicate n (f a)map-replicate f zero a = []map-replicate f (suc n) a =≡.refl ∷ λ where .force → map-replicate f (n .force) alookup-replicate : ∀ k n (a : A) → All (a ≡_) (lookup (replicate n a) k)lookup-replicate k zero a = nothinglookup-replicate zero (suc n) a = just ≡.refllookup-replicate (suc k) (suc n) a = lookup-replicate k (n .force) a-------------------------------------------------------------------------- Properties of unfoldmap-unfold : ∀ (f : B → C) (alg : A → Maybe (A × B)) a →i ⊢ map f (unfold alg a) ≈ unfold (Maybe.map (Product.map₂ f) ∘ alg) amap-unfold f alg a with alg a... | nothing = []... | just (a′ , b) = ≡.refl ∷ λ where .force → map-unfold f alg a′module _ {alg : A → Maybe (A × B)} {a} whereunfold-nothing : alg a ≡ nothing → unfold alg a ≡ []unfold-nothing eq with alg a... | nothing = ≡.reflunfold-just : ∀ {a′ b} → alg a ≡ just (a′ , b) →i ⊢ unfold alg a ≈ b ∷ λ where .force → unfold alg a′unfold-just eq with alg aunfold-just ≡.refl | just (a′ , b) = ≡.refl ∷ λ where .force → refl-------------------------------------------------------------------------- Properties of scanllength-scanl : ∀ (c : B → A → B) n as →i Conat.⊢ length (scanl c n as) ≈ 1 ℕ+ length aslength-scanl c n [] = suc λ where .force → zerolength-scanl c n (a ∷ as) = suc λ { .force → beginlength (scanl c (c n a) (as .force))≈⟨ length-scanl c (c n a) (as .force) ⟩1 ℕ+ length (as .force)≈⟨ length-∷ a as ⟨length (a ∷ as) ∎ } where open Conat.≈-Reasoningmodule _ (cons : C → B → C) (alg : A → Maybe (A × B)) whereprivatealg′ : (A × C) → Maybe ((A × C) × C)alg′ (a , c) = Maybe.map (uncurry step) (alg a) wherestep = λ a′ b → let b′ = cons c b in (a′ , b′) , b′scanl-unfold : ∀ nil a → i ⊢ scanl cons nil (unfold alg a)≈ nil ∷ (λ where .force → unfold alg′ (a , nil))scanl-unfold nil a with alg a in eq... | nothing = ≡.refl ∷ λ { .force →sym (fromEq (unfold-nothing (Maybe.map-nothing eq))) }... | just (a′ , b) = ≡.refl ∷ λ { .force → beginscanl cons (cons nil b) (unfold alg a′)≈⟨ scanl-unfold (cons nil b) a′ ⟩(cons nil b ∷ _)≈⟨ ≡.refl ∷ (λ where .force → refl) ⟩(cons nil b ∷ _)≈⟨ unfold-just (Maybe.map-just eq) ⟨unfold alg′ (a , nil) ∎ } where open ≈-Reasoning-------------------------------------------------------------------------- Properties of alignwithmap-alignWith : ∀ (f : C → D) (al : These A B → C) as bs →i ⊢ map f (alignWith al as bs) ≈ alignWith (f ∘ al) as bsmap-alignWith f al [] bs = map-∘ (al ∘′ that) f bsmap-alignWith f al as@(_ ∷ _) [] = map-∘ (al ∘′ this) f asmap-alignWith f al (a ∷ as) (b ∷ bs) =≡.refl ∷ λ where .force → map-alignWith f al (as .force) (bs .force)length-alignWith : ∀ (al : These A B → C) as bs →i Conat.⊢ length (alignWith al as bs) ≈ length as ⊔ length bslength-alignWith al [] bs = length-map (al ∘ that) bslength-alignWith al as@(_ ∷ _) [] = length-map (al ∘ this) aslength-alignWith al (a ∷ as) (b ∷ bs) =suc λ where .force → length-alignWith al (as .force) (bs .force)-------------------------------------------------------------------------- Properties of zipwithmap-zipWith : ∀ (f : C → D) (zp : A → B → C) as bs →i ⊢ map f (zipWith zp as bs) ≈ zipWith (λ a → f ∘ zp a) as bsmap-zipWith f zp [] _ = []map-zipWith f zp (_ ∷ _) [] = []map-zipWith f zp (a ∷ as) (b ∷ bs) =≡.refl ∷ λ where .force → map-zipWith f zp (as .force) (bs .force)length-zipWith : ∀ (zp : A → B → C) as bs →i Conat.⊢ length (zipWith zp as bs) ≈ length as ⊓ length bslength-zipWith zp [] bs = zerolength-zipWith zp as@(_ ∷ _) [] = zerolength-zipWith zp (a ∷ as) (b ∷ bs) =suc λ where .force → length-zipWith zp (as .force) (bs .force)-------------------------------------------------------------------------- Properties of dropdrop-nil : ∀ m → i ⊢ drop {A = A} m [] ≈ []drop-nil zero = []drop-nil (suc m) = []drop-drop : ∀ m n (as : Colist A ∞) →i ⊢ drop n (drop m as) ≈ drop (m ℕ.+ n) asdrop-drop zero n as = refldrop-drop (suc m) n [] = drop-nil ndrop-drop (suc m) n (a ∷ as) = drop-drop m n (as .force)map-drop : ∀ (f : A → B) m as → i ⊢ map f (drop m as) ≈ drop m (map f as)map-drop f zero as = reflmap-drop f (suc m) [] = []map-drop f (suc m) (a ∷ as) = map-drop f m (as .force)length-drop : ∀ m (as : Colist A ∞) → i Conat.⊢ length (drop m as) ≈ length as ∸ mlength-drop zero as = Conat.refllength-drop (suc m) [] = Conat.sym (Conat.0∸m≈0 m)length-drop (suc m) (a ∷ as) = length-drop m (as .force)drop-fromList-++-identity : ∀ (as : List A) bs →drop (List.length as) (fromList as ++ bs) ≡ bsdrop-fromList-++-identity [] bs = ≡.refldrop-fromList-++-identity (a ∷ as) bs = drop-fromList-++-identity as bsdrop-fromList-++-≤ : ∀ (as : List A) bs {m} → m ℕ.≤ List.length as →drop m (fromList as ++ bs) ≡ fromList (List.drop m as) ++ bsdrop-fromList-++-≤ [] bs z≤n = ≡.refldrop-fromList-++-≤ (a ∷ as) bs z≤n = ≡.refldrop-fromList-++-≤ (a ∷ as) bs (s≤s p) = drop-fromList-++-≤ as bs pdrop-fromList-++-≥ : ∀ (as : List A) bs {m} → m ℕ.≥ List.length as →drop m (fromList as ++ bs) ≡ drop (m ℕ.∸ List.length as) bsdrop-fromList-++-≥ [] bs z≤n = ≡.refldrop-fromList-++-≥ (a ∷ as) bs (s≤s p) = drop-fromList-++-≥ as bs pdrop-⁺++-identity : ∀ (as : List⁺ A) bs →drop (List⁺.length as) (as ⁺++ bs) ≡ bs .forcedrop-⁺++-identity (a ∷ as) bs = drop-fromList-++-identity as (bs .force)-------------------------------------------------------------------------- Properties of cotakelength-cotake : ∀ n (as : Stream A ∞) → i Conat.⊢ length (cotake n as) ≈ nlength-cotake zero as = zerolength-cotake (suc n) (a ∷ as) =suc λ where .force → length-cotake (n .force) (as .force)map-cotake : ∀ (f : A → B) n as →i ⊢ map f (cotake n as) ≈ cotake n (Stream.map f as)map-cotake f zero as = []map-cotake f (suc n) (a ∷ as) =≡.refl ∷ λ where .force → map-cotake f (n .force) (as .force)-------------------------------------------------------------------------- Properties of chunksOfmodule Map-ChunksOf (f : A → B) n whereopen ChunksOf n using (chunksOfAcc)map-chunksOf : ∀ as →i Cowriter.⊢ Cowriter.map (Vec.map f) (Vec≤.map f) (chunksOf n as)≈ chunksOf n (map f as)map-chunksOfAcc : ∀ m as {k≤ k≡ k≤′ k≡′} →(∀ vs → Vec≤.map f (k≤ vs) ≡ k≤′ (Vec≤.map f vs)) →(∀ vs → Vec.map f (k≡ vs) ≡ k≡′ (Vec.map f vs)) →i Cowriter.⊢ Cowriter.map (Vec.map f) (Vec≤.map f)(chunksOfAcc m k≤ k≡ as)≈ chunksOfAcc m k≤′ k≡′ (map f as)map-chunksOf as = map-chunksOfAcc n as (λ vs → ≡.refl) (λ vs → ≡.refl)map-chunksOfAcc zero as eq-≤ eq-≡ =eq-≡ [] ∷ λ where .force → map-chunksOf asmap-chunksOfAcc (suc m) [] eq-≤ eq-≡ = Cowriter.[ eq-≤ Vec≤.[] ]map-chunksOfAcc (suc m) (a ∷ as) eq-≤ eq-≡ =map-chunksOfAcc m (as .force) (eq-≤ ∘ (a Vec≤.∷_)) (eq-≡ ∘ (a Vec.∷_))open Map-ChunksOf using (map-chunksOf) public-------------------------------------------------------------------------- Properties of fromListfromList-++ : (as bs : List A) →i ⊢ fromList (as List.++ bs) ≈ fromList as ++ fromList bsfromList-++ [] bs = reflfromList-++ (a ∷ as) bs = ≡.refl ∷ λ where .force → fromList-++ as bsfromList-scanl : ∀ (c : B → A → B) n as →i ⊢ fromList (Scans.scanl c n as) ≈ scanl c n (fromList as)fromList-scanl c n [] = ≡.refl ∷ λ where .force → reflfromList-scanl c n (a ∷ as) =≡.refl ∷ λ where .force → fromList-scanl c (c n a) asmap-fromList : ∀ (f : A → B) as →i ⊢ map f (fromList as) ≈ fromList (List.map f as)map-fromList f [] = []map-fromList f (a ∷ as) = ≡.refl ∷ λ where .force → map-fromList f aslength-fromList : (as : List A) →i Conat.⊢ length (fromList as) ≈ fromℕ (List.length as)length-fromList [] = zerolength-fromList (a ∷ as) = suc (λ where .force → length-fromList as)-------------------------------------------------------------------------- Properties of fromStreamfromStream-++ : ∀ (as : List A) bs →i ⊢ fromStream (as Stream.++ bs) ≈ fromList as ++ fromStream bsfromStream-++ [] bs = reflfromStream-++ (a ∷ as) bs = ≡.refl ∷ λ where .force → fromStream-++ as bsfromStream-⁺++ : ∀ (as : List⁺ A) bs →i ⊢ fromStream (as Stream.⁺++ bs)≈ fromList⁺ as ++ fromStream (bs .force)fromStream-⁺++ (a ∷ as) bs =≡.refl ∷ λ where .force → fromStream-++ as (bs .force)fromStream-concat : (ass : Stream (List⁺ A) ∞) →i ⊢ concat (fromStream ass) ≈ fromStream (Stream.concat ass)fromStream-concat (as@(a ∷ _) ∷ ass) = beginconcat (fromStream (as ∷ ass))≈⟨ ≡.refl ∷ (λ { .force → ++⁺ ≋-refl (fromStream-concat (ass .force))}) ⟩a ∷ _≈⟨ sym (fromStream-⁺++ as _) ⟩fromStream (Stream.concat (as ∷ ass)) ∎ where open ≈-ReasoningfromStream-scanl : ∀ (c : B → A → B) n as →i ⊢ scanl c n (fromStream as)≈ fromStream (Stream.scanl c n as)fromStream-scanl c n (a ∷ as) =≡.refl ∷ λ where .force → fromStream-scanl c (c n a) (as .force)map-fromStream : ∀ (f : A → B) as →i ⊢ map f (fromStream as) ≈ fromStream (Stream.map f as)map-fromStream f (a ∷ as) =≡.refl ∷ λ where .force → map-fromStream f (as .force)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-identity = map-id{-# WARNING_ON_USAGE map-identity"Warning: map-identity was deprecated in v2.0.Please use map-id instead."#-}map-map-fusion = map-∘{-# WARNING_ON_USAGE map-map-fusion"Warning: map-map-fusion was deprecated in v2.0.Please use map-∘ instead."#-}drop-drop-fusion = drop-drop{-# WARNING_ON_USAGE drop-drop-fusion"Warning: drop-drop-fusion was deprecated in v2.0.Please use drop-drop instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- An effectful view of Colist------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Colist.Effectful whereopen import Codata.Sized.Conat using (infinity)open import Codata.Sized.Colistopen import Effect.Choiceopen import Effect.Emptyopen import Effect.Functoropen import Effect.Applicativefunctor : ∀ {ℓ i} → RawFunctor {ℓ} (λ A → Colist A i)functor = record { _<$>_ = map }applicative : ∀ {ℓ i} → RawApplicative {ℓ} (λ A → Colist A i)applicative = record{ rawFunctor = functor; pure = replicate infinity; _<*>_ = ap}empty : ∀ {ℓ i} → RawEmpty {ℓ} (λ A → Colist A i)empty = record { empty = [] }choice : ∀ {ℓ i} → RawChoice {ℓ} (λ A → Colist A i)choice = record { _<|>_ = _++_ }applicativeZero : ∀ {ℓ i} → RawApplicativeZero {ℓ} (λ A → Colist A i)applicativeZero = record{ rawApplicative = applicative; rawEmpty = empty}alternative : ∀ {ℓ i} → RawAlternative {ℓ} (λ A → Colist A i)alternative = record{ rawApplicativeZero = applicativeZero; rawChoice = choice}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Codata.Sized.Colist.Effectful` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Colist.Categorical whereopen import Codata.Sized.Colist.Effectful public{-# WARNING_ON_IMPORT"Codata.Sized.Colist.Categorical was deprecated in v2.0.Use Codata.Sized.Colist.Effectful instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Bisimilarity for Colists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Colist.Bisimilarity whereopen import Level using (Level; _⊔_)open import Sizeopen import Codata.Sized.Thunkopen import Codata.Sized.Colistopen import Data.List.Base using (List; []; _∷_)open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)open import Relation.Binary.Core using (REL; Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Sym; Trans)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea b c p q r : LevelA : Set aB : Set bC : Set ci : Sizedata Bisim {A : Set a} {B : Set b} (R : REL A B r) (i : Size) :REL (Colist A ∞) (Colist B ∞) (r ⊔ a ⊔ b) where[] : Bisim R i [] []_∷_ : ∀ {x y xs ys} → R x y → Thunk^R (Bisim R) i xs ys →Bisim R i (x ∷ xs) (y ∷ ys)infixr 5 _∷_module _ {R : Rel A r} wherereflexive : Reflexive R → Reflexive (Bisim R i)reflexive refl^R {[]} = []reflexive refl^R {r ∷ rs} = refl^R ∷ λ where .force → reflexive refl^Rmodule _ {P : REL A B p} {Q : REL B A q} wheresymmetric : Sym P Q → Sym (Bisim P i) (Bisim Q i)symmetric sym^PQ [] = []symmetric sym^PQ (p ∷ ps) = sym^PQ p ∷ λ where .force → symmetric sym^PQ (ps .force)module _ {P : REL A B p} {Q : REL B C q} {R : REL A C r} wheretransitive : Trans P Q R → Trans (Bisim P i) (Bisim Q i) (Bisim R i)transitive trans^PQR [] [] = []transitive trans^PQR (p ∷ ps) (q ∷ qs) =trans^PQR p q ∷ λ where .force → transitive trans^PQR (ps .force) (qs .force)-------------------------------------------------------------------------- Congruence rulesmodule _ {R : REL A B r} where++⁺ : ∀ {as bs xs ys} → Pointwise R as bs →Bisim R i xs ys → Bisim R i (fromList as ++ xs) (fromList bs ++ ys)++⁺ [] rs = rs++⁺ (r ∷ pw) rs = r ∷ λ where .force → ++⁺ pw rs⁺++⁺ : ∀ {as bs xs ys} → Pointwise R (List⁺.toList as) (List⁺.toList bs) →Thunk^R (Bisim R) i xs ys → Bisim R i (as ⁺++ xs) (bs ⁺++ ys)⁺++⁺ (r ∷ pw) rs = r ∷ λ where .force → ++⁺ pw (rs .force)-------------------------------------------------------------------------- Pointwise Equality as a Bisimilaritymodule _ {A : Set a} whereinfix 1 _⊢_≈__⊢_≈_ : ∀ i → Colist A ∞ → Colist A ∞ → Set a_⊢_≈_ = Bisim _≡_refl : Reflexive (i ⊢_≈_)refl = reflexive ≡.reflfromEq : ∀ {as bs} → as ≡ bs → i ⊢ as ≈ bsfromEq ≡.refl = reflsym : Symmetric (i ⊢_≈_)sym = symmetric ≡.symtrans : Transitive (i ⊢_≈_)trans = transitive ≡.transisEquivalence : {R : Rel A r} → IsEquivalence R → IsEquivalence (Bisim R i)isEquivalence equiv^R = record{ refl = reflexive equiv^R.refl; sym = symmetric equiv^R.sym; trans = transitive equiv^R.trans} where module equiv^R = IsEquivalence equiv^Rsetoid : Setoid a r → Size → Setoid a (a ⊔ r)setoid S i = record{ isEquivalence = isEquivalence {i = i} (Setoid.isEquivalence S)}module ≈-Reasoning {a} {A : Set a} {i} whereopen import Relation.Binary.Reasoning.Setoid (setoid (≡.setoid A) i) public
-------------------------------------------------------------------------- The Agda standard library---- "Finite" sets indexed on coinductive "natural" numbers------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Cofin whereopen import Size using (∞)open import Codata.Sized.Thunk using (force)open import Codata.Sized.Conat as Conatusing (Conat; zero; suc; infinity; _ℕ<_; sℕ≤s; _ℕ≤infinity)open import Codata.Sized.Conat.Bisimilarity as Bisim using (_⊢_≲_ ; s≲s)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Fin.Base using (Fin; zero; suc)open import Function.Base using (_∋_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)-------------------------------------------------------------------------- The type-- Note that `Cofin infinity` is /not/ finite. Note also that this is-- not a coinductive type, but it is indexed on a coinductive type.data Cofin : Conat ∞ → Set wherezero : ∀ {n} → Cofin (suc n)suc : ∀ {n} → Cofin (n .force) → Cofin (suc n)suc-injective : ∀ {n} {p q : Cofin (n .force)} →(Cofin (suc n) ∋ suc p) ≡ suc q → p ≡ qsuc-injective refl = refl-------------------------------------------------------------------------- Some operationsfromℕ< : ∀ {n k} → k ℕ< n → Cofin nfromℕ< {zero} ()fromℕ< {suc n} {zero} (sℕ≤s p) = zerofromℕ< {suc n} {suc k} (sℕ≤s p) = suc (fromℕ< p)fromℕ : ℕ → Cofin infinityfromℕ k = fromℕ< (suc k ℕ≤infinity)toℕ : ∀ {n} → Cofin n → ℕtoℕ zero = zerotoℕ (suc i) = suc (toℕ i)fromFin : ∀ {n} → Fin n → Cofin (Conat.fromℕ n)fromFin zero = zerofromFin (suc i) = suc (fromFin i)toFin : ∀ n → Cofin (Conat.fromℕ n) → Fin ntoFin zero ()toFin (suc n) zero = zerotoFin (suc n) (suc i) = suc (toFin n i)
-------------------------------------------------------------------------- The Agda standard library---- Conat Literals------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module Codata.Sized.Cofin.Literals whereopen import Data.Nat.Baseopen import Agda.Builtin.FromNatopen import Codata.Sized.Conatopen import Codata.Sized.Conat.Propertiesopen import Codata.Sized.Cofinopen import Relation.Nullary.Decidablenumber : ∀ n → Number (Cofin n)number n = record{ Constraint = λ k → True (suc k ℕ≤? n); fromNat = λ n {{p}} → fromℕ< (toWitness p)}
-------------------------------------------------------------------------- The Agda standard library---- Streams------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Stream whereopen import Level using (Level)open import Codata.Musical.Notationopen import Codata.Musical.Colist using (Colist; []; _∷_)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.Nat.Base using (ℕ; zero; suc)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- The typeinfixr 5 _∷_data Stream (A : Set a) : Set a where_∷_ : (x : A) (xs : ∞ (Stream A)) → Stream A{-# FOREIGN GHCdata AgdaStream a = Cons a (MAlonzo.RTE.Inf (AgdaStream a))type AgdaStream' l a = AgdaStream a#-}{-# COMPILE GHC Stream = data AgdaStream' (Cons) #-}-------------------------------------------------------------------------- Some operationshead : Stream A → Ahead (x ∷ xs) = xtail : Stream A → Stream Atail (x ∷ xs) = ♭ xsmap : (A → B) → Stream A → Stream Bmap f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)zipWith : (A → B → C) → Stream A → Stream B → Stream CzipWith _∙_ (x ∷ xs) (y ∷ ys) = (x ∙ y) ∷ ♯ zipWith _∙_ (♭ xs) (♭ ys)take : ∀ n → Stream A → Vec A ntake zero xs = []take (suc n) (x ∷ xs) = x ∷ take n (♭ xs)drop : ℕ → Stream A → Stream Adrop zero xs = xsdrop (suc n) (x ∷ xs) = drop n (♭ xs)repeat : A → Stream Arepeat x = x ∷ ♯ repeat xiterate : (A → A) → A → Stream Aiterate f x = x ∷ ♯ iterate f (f x)-- Interleaves the two streams.infixr 5 _⋎__⋎_ : Stream A → Stream A → Stream A(x ∷ xs) ⋎ ys = x ∷ ♯ (ys ⋎ ♭ xs)mutual-- Takes every other element from the stream, starting with the-- first one.evens : Stream A → Stream Aevens (x ∷ xs) = x ∷ ♯ odds (♭ xs)-- Takes every other element from the stream, starting with the-- second one.odds : Stream A → Stream Aodds (x ∷ xs) = evens (♭ xs)toColist : Stream A → Colist AtoColist (x ∷ xs) = x ∷ ♯ toColist (♭ xs)lookup : Stream A → ℕ → Alookup (x ∷ xs) zero = xlookup (x ∷ xs) (suc n) = lookup (♭ xs) ninfixr 5 _++__++_ : ∀ {a} {A : Set a} → Colist A → Stream A → Stream A[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)-------------------------------------------------------------------------- Equality and other relations-- xs ≈ ys means that xs and ys are equal.infix 4 _≈_data _≈_ {A : Set a} : Stream A → Stream A → Set a where_∷_ : ∀ {x y xs ys}(x≡ : x ≡ y) (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ y ∷ ys-- x ∈ xs means that x is a member of xs.infix 4 _∈_data _∈_ {A : Set a} : A → Stream A → Set a wherehere : ∀ {x xs} → x ∈ x ∷ xsthere : ∀ {x y xs} (x∈xs : x ∈ ♭ xs) → x ∈ y ∷ xs-- xs ⊑ ys means that xs is a prefix of ys.infix 4 _⊑_data _⊑_ {A : Set a} : Colist A → Stream A → Set a where[] : ∀ {ys} → [] ⊑ ys_∷_ : ∀ x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) → x ∷ xs ⊑ x ∷ ys-------------------------------------------------------------------------- Some proofssetoid : ∀ {a} → Set a → Setoid _ _setoid A = record{ Carrier = Stream A; _≈_ = _≈_ {A = A}; isEquivalence = record{ refl = refl; sym = sym; trans = trans}}whererefl : Reflexive _≈_refl {_ ∷ _} = ≡.refl ∷ ♯ reflsym : Symmetric _≈_sym (x≡ ∷ xs≈) = ≡.sym x≡ ∷ ♯ sym (♭ xs≈)trans : Transitive _≈_trans (x≡ ∷ xs≈) (y≡ ∷ ys≈) = ≡.trans x≡ y≡ ∷ ♯ trans (♭ xs≈) (♭ ys≈)head-cong : {xs ys : Stream A} → xs ≈ ys → head xs ≡ head yshead-cong (x≡ ∷ _) = x≡tail-cong : {xs ys : Stream A} → xs ≈ ys → tail xs ≈ tail ystail-cong (_ ∷ xs≈) = ♭ xs≈map-cong : ∀ (f : A → B) {xs ys} →xs ≈ ys → map f xs ≈ map f ysmap-cong f (x≡ ∷ xs≈) = ≡.cong f x≡ ∷ ♯ map-cong f (♭ xs≈)zipWith-cong : ∀ (_∙_ : A → B → C) {xs xs′ ys ys′} →xs ≈ xs′ → ys ≈ ys′ →zipWith _∙_ xs ys ≈ zipWith _∙_ xs′ ys′zipWith-cong _∙_ (x≡ ∷ xs≈) (y≡ ∷ ys≈) =≡.cong₂ _∙_ x≡ y≡ ∷ ♯ zipWith-cong _∙_ (♭ xs≈) (♭ ys≈)infixr 5 _⋎-cong__⋎-cong_ : {xs xs′ ys ys′ : Stream A} →xs ≈ xs′ → ys ≈ ys′ → xs ⋎ ys ≈ xs′ ⋎ ys′(x ∷ xs≈) ⋎-cong ys≈ = x ∷ ♯ (ys≈ ⋎-cong ♭ xs≈)
-------------------------------------------------------------------------- The Agda standard library---- Basic types related to coinduction------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Codata.Musical.Notation whereopen import Agda.Builtin.Coinduction public
-------------------------------------------------------------------------- The Agda standard library---- M-types (the dual of W-types)------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Musical.M whereopen import Codata.Musical.Notationopen import Levelopen import Data.Product.Base hiding (map)open import Data.Container.Core as C hiding (map)-- The family of M-types.data M {s p} (C : Container s p) : Set (s ⊔ p) whereinf : ⟦ C ⟧ (∞ (M C)) → M C-- Projections.module _ {s p} (C : Container s p) wherehead : M C → Shape Chead (inf (x , _)) = xtail : (x : M C) → Position C (head x) → M Ctail (inf (x , f)) b = ♭ (f b)-- mapmodule _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}(m : C₁ ⇒ C₂) wheremap : M C₁ → M C₂map (inf (x , f)) = inf (shape m x , λ p → ♯ map (♭ (f (position m p))))-- unfoldmodule _ {s p ℓ} {C : Container s p} (open Container C){S : Set ℓ} (alg : S → ⟦ C ⟧ S) whereunfold : S → M Cunfold seed = let (x , f) = alg seed ininf (x , λ p → ♯ unfold (f p))
-------------------------------------------------------------------------- The Agda standard library---- Indexed M-types (the dual of indexed W-types aka Petersson-Synek-- trees).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Codata.Musical.M.Indexed whereopen import Levelopen import Codata.Musical.Notationopen import Data.Product.Base using (_,_; proj₁; proj₂)open import Data.Container.Indexed.Coreopen import Function.Base using (_∘_)open import Relation.Unary-- The family of indexed M-types.module _ {ℓ c r} {O : Set ℓ} (C : Container O O c r) wheredata M (o : O) : Set (ℓ ⊔ c ⊔ r) whereinf : ⟦ C ⟧ (∞ ∘ M) o → M oopen Container C-- Projections.head : M ⊆ Commandhead (inf (c , _)) = ctail : ∀ {o} (m : M o) (r : Response (head m)) → M (next (head m) r)tail (inf (_ , k)) r = ♭ (k r)force : M ⊆ ⟦ C ⟧ Mforce (inf (c , k)) = c , λ r → ♭ (k r)-- Coiteration.coit : ∀ {ℓ} {X : Pred O ℓ} → X ⊆ ⟦ C ⟧ X → X ⊆ Mcoit ψ x = inf (proj₁ cs , λ r → ♯ coit ψ (proj₂ cs r))wherecs = ψ x
-------------------------------------------------------------------------- The Agda standard library---- Coinductive vectors------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Covec whereopen import Codata.Musical.Notationopen import Codata.Musical.Conat as Coℕ using (Coℕ; zero; suc; _+_)open import Codata.Musical.Cofin using (Cofin; zero; suc)open import Codata.Musical.Colist as Colist using (Colist; []; _∷_)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.Product.Base using (_,_)open import Function.Base using (_∋_)open import Level using (Level)open import Relation.Binary.Core using (_⇒_; _=[_]⇒_)open import Relation.Binary.Bundles using (Setoid; Poset)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive; Antisymmetric)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- The typeinfixr 5 _∷_data Covec (A : Set a) : Coℕ → Set a where[] : Covec A zero_∷_ : ∀ {n} (x : A) (xs : ∞ (Covec A (♭ n))) → Covec A (suc n)∷-injectiveˡ : ∀ {a b} {n} {as bs} → (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → a ≡ b∷-injectiveˡ ≡.refl = ≡.refl∷-injectiveʳ : ∀ {a b} {n} {as bs} → (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → as ≡ bs∷-injectiveʳ ≡.refl = ≡.refl-------------------------------------------------------------------------- Some operationsmap : ∀ {n} → (A → B) → Covec A n → Covec B nmap f [] = []map f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)fromVec : ∀ {n} → Vec A n → Covec A (Coℕ.fromℕ n)fromVec [] = []fromVec (x ∷ xs) = x ∷ ♯ fromVec xsfromColist : (xs : Colist A) → Covec A (Colist.length xs)fromColist [] = []fromColist (x ∷ xs) = x ∷ ♯ fromColist (♭ xs)take : ∀ m {n} → Covec A (m + n) → Covec A mtake zero xs = []take (suc n) (x ∷ xs) = x ∷ ♯ take (♭ n) (♭ xs)drop : ∀ m {n} → Covec A (Coℕ.fromℕ m + n) → Covec A ndrop zero xs = xsdrop (suc n) (x ∷ xs) = drop n (♭ xs)replicate : ∀ n → A → Covec A nreplicate zero x = []replicate (suc n) x = x ∷ ♯ replicate (♭ n) xlookup : ∀ {n} → Covec A n → Cofin n → Alookup (x ∷ xs) zero = xlookup (x ∷ xs) (suc n) = lookup (♭ xs) ninfixr 5 _++__++_ : ∀ {m n} → Covec A m → Covec A n → Covec A (m + n)[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)[_] : A → Covec A (suc (♯ zero))[ x ] = x ∷ ♯ []-------------------------------------------------------------------------- Equality and other relations-- xs ≈ ys means that xs and ys are equal.infix 4 _≈_data _≈_ {A : Set a} : ∀ {n} (xs ys : Covec A n) → Set a where[] : [] ≈ []_∷_ : ∀ {n} x {xs ys}(xs≈ : ∞ (♭ xs ≈ ♭ ys)) → _≈_ {n = suc n} (x ∷ xs) (x ∷ ys)-- x ∈ xs means that x is a member of xs.infix 4 _∈_data _∈_ {A : Set a} : ∀ {n} → A → Covec A n → Set a wherehere : ∀ {n x } {xs} → _∈_ {n = suc n} x (x ∷ xs)there : ∀ {n x y} {xs} (x∈xs : x ∈ ♭ xs) → _∈_ {n = suc n} x (y ∷ xs)-- xs ⊑ ys means that xs is a prefix of ys.infix 4 _⊑_data _⊑_ {A : Set a} : ∀ {m n} → Covec A m → Covec A n → Set a where[] : ∀ {n} {ys : Covec A n} → [] ⊑ ys_∷_ : ∀ {m n} x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) →_⊑_ {m = suc m} {suc n} (x ∷ xs) (x ∷ ys)-------------------------------------------------------------------------- Some proofssetoid : ∀ {a} → Set a → Coℕ → Setoid _ _setoid A n = record{ Carrier = Covec A n; _≈_ = _≈_; isEquivalence = record{ refl = refl; sym = sym; trans = trans}}whererefl : ∀ {n} → Reflexive (_≈_ {n = n})refl {x = []} = []refl {x = x ∷ xs} = x ∷ ♯ reflsym : ∀ {n} → Symmetric (_≈_ {A = A} {n})sym [] = []sym (x ∷ xs≈) = x ∷ ♯ sym (♭ xs≈)trans : ∀ {n} → Transitive (_≈_ {A = A} {n})trans [] [] = []trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)poset : ∀ {a} → Set a → Coℕ → Poset _ _ _poset A n = record{ Carrier = Covec A n; _≈_ = _≈_; _≤_ = _⊑_; isPartialOrder = record{ isPreorder = record{ isEquivalence = Setoid.isEquivalence (setoid A n); reflexive = reflexive; trans = trans}; antisym = antisym}}wherereflexive : ∀ {n} → _≈_ {n = n} ⇒ _⊑_reflexive [] = []reflexive (x ∷ xs≈) = x ∷ ♯ reflexive (♭ xs≈)trans : ∀ {n} → Transitive (_⊑_ {n = n})trans [] _ = []trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)tail : ∀ {n x y xs ys} →_∷_ {n = n} x xs ⊑ _∷_ {n = n} y ys → ♭ xs ⊑ ♭ ystail (_ ∷ p) = ♭ pantisym : ∀ {n} → Antisymmetric (_≈_ {n = n}) _⊑_antisym [] [] = []antisym (x ∷ p₁) p₂ = x ∷ ♯ antisym (♭ p₁) (tail p₂)map-cong : ∀ {n} (f : A → B) → _≈_ {n = n} =[ map f ]⇒ _≈_map-cong f [] = []map-cong f (x ∷ xs≈) = f x ∷ ♯ map-cong f (♭ xs≈)take-⊑ : ∀ m {n} (xs : Covec A (m + n)) → take m xs ⊑ xstake-⊑ zero xs = []take-⊑ (suc n) (x ∷ xs) = x ∷ ♯ take-⊑ (♭ n) (♭ xs)
-------------------------------------------------------------------------- The Agda standard library---- Costrings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Costring whereopen import Codata.Musical.Colist.Base as Colist using (Colist)open import Data.Char.Base using (Char)open import Data.String.Base as String using (String)open import Function.Base using (_∘_)-- Possibly infinite strings.Costring : SetCostring = Colist Char-- MethodstoCostring : String → CostringtoCostring = Colist.fromList ∘ String.toList
-------------------------------------------------------------------------- The Agda standard library---- Conversion between coinductive data structures using "musical"-- coinduction and the ones using sized types.---- Warning: the combination of --sized-types and --guardedness is-- known to be unsound, so use these conversions at your own risk.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types --guardedness #-}module Codata.Musical.Conversion whereopen import Level using (Level)import Codata.Sized.Cofin as Sizedimport Codata.Sized.Colist as Sizedimport Codata.Sized.Conat as Sizedimport Codata.Sized.Covec as Sizedimport Codata.Sized.M as Sizedimport Codata.Sized.Stream as Sizedopen import Codata.Sized.Thunkopen import Codata.Musical.Cofin hiding (module Cofin)open import Codata.Musical.Colist hiding (module Colist)open import Codata.Musical.Conatopen import Codata.Musical.Covec hiding (module Covec)open import Codata.Musical.M hiding (module M)open import Codata.Musical.Notationopen import Codata.Musical.Stream hiding (module Stream)open import Data.Product.Base using (_,_)open import Data.Container.Core as C using (Container)import Sizeprivatevariablea : LevelA : Set amodule Colist wherefromMusical : ∀ {i} → Colist A → Sized.Colist A ifromMusical [] = Sized.[]fromMusical (x ∷ xs) = x Sized.∷ λ where .force → fromMusical (♭ xs)toMusical : Sized.Colist A Size.∞ → Colist AtoMusical Sized.[] = []toMusical (x Sized.∷ xs) = x ∷ ♯ toMusical (xs .force)module Conat wherefromMusical : ∀ {i} → Coℕ → Sized.Conat ifromMusical zero = Sized.zerofromMusical (suc n) = Sized.suc λ where .force → fromMusical (♭ n)toMusical : Sized.Conat Size.∞ → CoℕtoMusical Sized.zero = zerotoMusical (Sized.suc n) = suc (♯ toMusical (n .force))module Cofin wherefromMusical : ∀ {n} → Cofin n → Sized.Cofin (Conat.fromMusical n)fromMusical zero = Sized.zerofromMusical (suc n) = Sized.suc (fromMusical n)toMusical : ∀ {n} → Sized.Cofin n → Cofin (Conat.toMusical n)toMusical Sized.zero = zerotoMusical (Sized.suc n) = suc (toMusical n)module Covec wherefromMusical : ∀ {i n} → Covec A n → Sized.Covec A i (Conat.fromMusical n)fromMusical [] = Sized.[]fromMusical (x ∷ xs) = x Sized.∷ λ where .force → fromMusical (♭ xs)toMusical : ∀ {n} → Sized.Covec A Size.∞ n → Covec A (Conat.toMusical n)toMusical Sized.[] = []toMusical (x Sized.∷ xs) = x ∷ ♯ toMusical (xs .force)module M {s p} {C : Container s p} wherefromMusical : ∀ {i} → M C → Sized.M C ifromMusical (inf t) = Sized.M.inf (C.map rec t) whererec = λ x → λ where .force → fromMusical (♭ x)toMusical : Sized.M C Size.∞ → M CtoMusical (Sized.M.inf (s , f)) = inf (s , λ p → ♯ toMusical (f p .force))module Stream wherefromMusical : ∀ {i} → Stream A → Sized.Stream A ifromMusical (x ∷ xs) = x Sized.∷ λ where .force → fromMusical (♭ xs)toMusical : Sized.Stream A Size.∞ → Stream AtoMusical (x Sized.∷ xs) = x ∷ ♯ toMusical (xs .force)
-------------------------------------------------------------------------- The Agda standard library---- Coinductive "natural" numbers------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Musical.Conat whereopen import Codata.Musical.Notationopen import Data.Nat.Base using (ℕ; zero; suc)open import Function.Base using (_∋_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)-------------------------------------------------------------------------- Re-exporting the type and basic operationsopen import Codata.Musical.Conat.Base public-------------------------------------------------------------------------- Some propertiesmodule Coℕ-injective wheresuc-injective : ∀ {m n} → (Coℕ ∋ suc m) ≡ suc n → m ≡ nsuc-injective ≡.refl = ≡.reflfromℕ-injective : ∀ {m n} → fromℕ m ≡ fromℕ n → m ≡ nfromℕ-injective {zero} {zero} eq = ≡.reflfromℕ-injective {suc m} {suc n} eq = ≡.cong suc (fromℕ-injective (≡.cong pred eq))-------------------------------------------------------------------------- Equalityinfix 4 _≈_data _≈_ : Coℕ → Coℕ → Set wherezero : zero ≈ zerosuc : ∀ {m n} (m≈n : ∞ (♭ m ≈ ♭ n)) → suc m ≈ suc nmodule ≈-injective wheresuc-injective : ∀ {m n p q} → (suc m ≈ suc n ∋ suc p) ≡ suc q → p ≡ qsuc-injective ≡.refl = ≡.reflsetoid : Setoid _ _setoid = record{ Carrier = Coℕ; _≈_ = _≈_; isEquivalence = record{ refl = refl; sym = sym; trans = trans}}whererefl : Reflexive _≈_refl {zero} = zerorefl {suc n} = suc (♯ refl)sym : Symmetric _≈_sym zero = zerosym (suc m≈n) = suc (♯ sym (♭ m≈n))trans : Transitive _≈_trans zero zero = zerotrans (suc m≈n) (suc n≈k) = suc (♯ trans (♭ m≈n) (♭ n≈k))
-------------------------------------------------------------------------- The Agda standard library---- Coinductive "natural" numbers: base type and operations------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Musical.Conat.Base whereopen import Codata.Musical.Notationopen import Data.Nat.Base using (ℕ; zero; suc)open import Function.Base using (_∋_)-------------------------------------------------------------------------- The typedata Coℕ : Set wherezero : Coℕsuc : (n : ∞ Coℕ) → Coℕ-------------------------------------------------------------------------- Constant∞ℕ : Coℕ∞ℕ = suc (♯ ∞ℕ)-------------------------------------------------------------------------- Some operationspred : Coℕ → Coℕpred zero = zeropred (suc n) = ♭ nfromℕ : ℕ → Coℕfromℕ zero = zerofromℕ (suc n) = suc (♯ fromℕ n)infixl 6 _+__+_ : Coℕ → Coℕ → Coℕzero + n = nsuc m + n = suc (♯ (♭ m + n))
-------------------------------------------------------------------------- The Agda standard library---- Coinductive lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist whereopen import Level using (Level)open import Effect.Monadopen import Codata.Musical.Notationopen import Codata.Musical.Conat using (Coℕ; zero; suc)import Codata.Musical.Colist.Propertiesimport Codata.Musical.Colist.Relation.Unary.All.Propertiesopen import Data.Bool.Base using (Bool; true; false)open import Data.Empty using (⊥)open import Data.Maybe using (Maybe; nothing; just; Is-just)open import Data.Maybe.Relation.Unary.Any using (just)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.List.Base using (List; []; _∷_)open import Data.List.NonEmpty using (List⁺; _∷_)open import Data.Product.Base as Product using (∃; _×_; _,_)open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]′)open import Data.Vec.Bounded as Vec≤ using (Vec≤)open import Function.Baseopen import Function.Bundlesopen import Level using (_⊔_)open import Relation.Binary.Core using (Rel; _⇒_)open import Relation.Binary.Bundles using (Poset; Setoid; Preorder)open import Relation.Binary.Definitions using (Transitive; Antisymmetric)import Relation.Binary.Construct.FromRel as Indimport Relation.Binary.Reasoning.Preorder as ≲-Reasoningimport Relation.Binary.Reasoning.PartialOrder as ≤-Reasoningopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Binary.Reasoning.Syntaxopen import Relation.Nullary.Reflects using (invert)open import Relation.Nullaryopen import Relation.Nullary.Negationopen import Relation.Nullary.Decidable using (¬¬-excluded-middle)open import Relation.Unary using (Pred)privatevariablea b p : LevelA : Set aB : Set bP : Pred A p-------------------------------------------------------------------------- Re-export type and basic definitionsopen import Codata.Musical.Colist.Base publicmodule Colist-injective = Codata.Musical.Colist.Propertiesopen import Codata.Musical.Colist.Bisimilarity publicopen import Codata.Musical.Colist.Relation.Unary.All publicmodule All-injective = Codata.Musical.Colist.Relation.Unary.All.Propertiesopen import Codata.Musical.Colist.Relation.Unary.Any publicopen import Codata.Musical.Colist.Relation.Unary.Any.Properties public-------------------------------------------------------------------------- More operationstake : ∀ {a} {A : Set a} (n : ℕ) → Colist A → Vec≤ A ntake zero xs = Vec≤.[]take (suc n) [] = Vec≤.[]take (suc n) (x ∷ xs) = x Vec≤.∷ take n (♭ xs)module ¬¬Monad {a} whereopen RawMonad (¬¬-Monad {a}) publicopen ¬¬Monad -- we don't want the RawMonad content to be opened publicly-------------------------------------------------------------------------- Memberships, subsets, prefixes-- x ∈ xs means that x is a member of xs.infix 4 _∈__∈_ : {A : Set a} → A → Colist A → Set ax ∈ xs = Any (_≡_ x) xs-- xs ⊆ ys means that xs is a subset of ys.infix 4 _⊆__⊆_ : {A : Set a} → Rel (Colist A) axs ⊆ ys = ∀ {x} → x ∈ xs → x ∈ ys-- xs ⊑ ys means that xs is a prefix of ys.infix 4 _⊑_data _⊑_ {A : Set a} : Rel (Colist A) a where[] : ∀ {ys} → [] ⊑ ys_∷_ : ∀ x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) → x ∷ xs ⊑ x ∷ ys-- Any can be expressed using _∈_ (and vice versa).Any-∈ : ∀ {xs} → Any P xs ↔ ∃ λ x → x ∈ xs × P xAny-∈ {P = P} = mk↔ₛ′to(λ { (x , x∈xs , p) → from x∈xs p })(λ { (x , x∈xs , p) → to∘from x∈xs p })from∘towhereto : ∀ {xs} → Any P xs → ∃ λ x → x ∈ xs × P xto (here p) = _ , here refl , pto (there p) = Product.map id (Product.map there id) (to p)from : ∀ {x xs} → x ∈ xs → P x → Any P xsfrom (here refl) p = here pfrom (there x∈xs) p = there (from x∈xs p)to∘from : ∀ {x xs} (x∈xs : x ∈ xs) (p : P x) →to (from x∈xs p) ≡ (x , x∈xs , p)to∘from (here refl) p = reflto∘from (there x∈xs) p =cong (Product.map id (Product.map there id)) (to∘from x∈xs p)from∘to : ∀ {xs} (p : Any P xs) →let (x , x∈xs , px) = to p in from x∈xs px ≡ pfrom∘to (here _) = reflfrom∘to (there p) = cong there (from∘to p)-- Prefixes are subsets.⊑⇒⊆ : _⊑_ {A = A} ⇒ _⊆_⊑⇒⊆ (x ∷ xs⊑ys) (here ≡x) = here ≡x⊑⇒⊆ (_ ∷ xs⊑ys) (there x∈xs) = there (⊑⇒⊆ (♭ xs⊑ys) x∈xs)-- The prefix relation forms a poset.⊑-Poset : ∀ {ℓ} → Set ℓ → Poset _ _ _⊑-Poset A = record{ Carrier = Colist A; _≈_ = _≈_; _≤_ = _⊑_; isPartialOrder = record{ isPreorder = record{ isEquivalence = Setoid.isEquivalence (setoid A); reflexive = reflexive; trans = trans}; antisym = antisym}}wherereflexive : _≈_ ⇒ _⊑_reflexive [] = []reflexive (x ∷ xs≈) = x ∷ ♯ reflexive (♭ xs≈)trans : Transitive _⊑_trans [] _ = []trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)tail : ∀ {x xs y ys} → x ∷ xs ⊑ y ∷ ys → ♭ xs ⊑ ♭ ystail (_ ∷ p) = ♭ pantisym : Antisymmetric _≈_ _⊑_antisym [] [] = []antisym (x ∷ p₁) p₂ = x ∷ ♯ antisym (♭ p₁) (tail p₂)module ⊑-Reasoning {a} {A : Set a} whereprivate module Base = ≤-Reasoning (⊑-Poset A)open Base public hiding (step-<; step-≤)open ⊑-syntax _IsRelatedTo_ _IsRelatedTo_ Base.≤-go publicopen ⊏-syntax _IsRelatedTo_ _IsRelatedTo_ Base.<-go public-- The subset relation forms a preorder.⊆-Preorder : ∀ {ℓ} → Set ℓ → Preorder _ _ _⊆-Preorder A = Ind.preorder (setoid A) _∈_(λ xs≈ys → ⊑⇒⊆ (⊑A.reflexive xs≈ys))where module ⊑A = Poset (⊑-Poset A)-- Example uses:---- x∈zs : x ∈ zs-- x∈zs =-- x ∈⟨ x∈xs ⟩-- xs ⊆⟨ xs⊆ys ⟩-- ys ≡⟨ ys≡zs ⟩-- zs ∎module ⊆-Reasoning {A : Set a} whereprivate module Base = ≲-Reasoning (⊆-Preorder A)open Base publichiding (step-≲; step-∼)renaming (≲-go to ⊆-go)open begin-membership-syntax _IsRelatedTo_ _∈_ (λ x → begin x)open ⊆-syntax _IsRelatedTo_ _IsRelatedTo_ ⊆-go public-- take returns a prefix.take-⊑ : ∀ n (xs : Colist A) →let toColist = fromList {a} ∘ Vec≤.toList intoColist (take n xs) ⊑ xstake-⊑ zero xs = []take-⊑ (suc n) [] = []take-⊑ (suc n) (x ∷ xs) = x ∷ ♯ take-⊑ n (♭ xs)-------------------------------------------------------------------------- Finiteness and infiniteness-- Finite xs means that xs has finite length.data Finite {A : Set a} : Colist A → Set a where[] : Finite []_∷_ : ∀ x {xs} (fin : Finite (♭ xs)) → Finite (x ∷ xs)infixr 5 _∷_module Finite-injective where∷-injective : ∀ {x : A} {xs p q} → (Finite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q∷-injective refl = refl-- Infinite xs means that xs has infinite length.data Infinite {A : Set a} : Colist A → Set a where_∷_ : ∀ x {xs} (inf : ∞ (Infinite (♭ xs))) → Infinite (x ∷ xs)module Infinite-injective where∷-injective : ∀ {x : A} {xs p q} → (Infinite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q∷-injective refl = refl-- Colists which are not finite are infinite.not-finite-is-infinite :(xs : Colist A) → ¬ Finite xs → Infinite xsnot-finite-is-infinite [] hyp = contradiction [] hypnot-finite-is-infinite (x ∷ xs) hyp =x ∷ ♯ not-finite-is-infinite (♭ xs) (hyp ∘ _∷_ x)-- Colists are either finite or infinite (classically).finite-or-infinite :(xs : Colist A) → ¬ ¬ (Finite xs ⊎ Infinite xs)finite-or-infinite xs = helper <$> ¬¬-excluded-middlewherehelper : Dec (Finite xs) → Finite xs ⊎ Infinite xshelper ( true because [fin]) = inj₁ (invert [fin])helper (false because [¬fin]) =inj₂ $ not-finite-is-infinite xs (invert [¬fin])-- Colists are not both finite and infinite.not-finite-and-infinite :∀ {xs : Colist A} → Finite xs → Infinite xs → ⊥not-finite-and-infinite (x ∷ fin) (.x ∷ inf) =not-finite-and-infinite fin (♭ inf)
-------------------------------------------------------------------------- The Agda standard library---- Coinductive lists where at least one element satisfies a predicate------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Relation.Unary.Any whereopen import Codata.Musical.Colist.Baseopen import Codata.Musical.Notationopen import Data.Nat.Base using (ℕ; zero; suc)open import Function.Base using (_∋_)open import Level using (Level; _⊔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Unary using (Pred)privatevariablea b p : LevelA : Set aB : Set bP : Pred A pdata Any {A : Set a} (P : Pred A p) : Pred (Colist A) (a ⊔ p) wherehere : ∀ {x xs} (px : P x) → Any P (x ∷ xs)there : ∀ {x xs} (pxs : Any P (♭ xs)) → Any P (x ∷ xs)index : ∀ {xs} → Any P xs → ℕindex (here px) = zeroindex (there p) = suc (index p)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the Any predicate on colists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Relation.Unary.Any.Properties whereopen import Codata.Musical.Colist.Baseopen import Codata.Musical.Colist.Bisimilarityopen import Codata.Musical.Colist.Relation.Unary.Anyopen import Codata.Musical.Notationopen import Data.Maybe using (Is-just)open import Data.Maybe.Relation.Unary.Any using (just)open import Data.Nat.Base using (suc; _≥′_; ≤′-refl; ≤′-step)open import Data.Nat.Properties using (s≤′s)open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′; [_,_])open import Function.Base using (_∋_; _∘_)open import Function.Bundlesopen import Level using (Level; _⊔_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; refl; cong)open import Relation.Unary using (Pred)privatevariablea b p q : LevelA : Set aB : Set bP : Pred A pQ : Pred A q-------------------------------------------------------------------------- Equality propertieshere-injective : ∀ {x xs p q} → (Any P (x ∷ xs) ∋ here p) ≡ here q → p ≡ qhere-injective refl = reflthere-injective : ∀ {x xs p q} → (Any P (x ∷ xs) ∋ there p) ≡ there q → p ≡ qthere-injective refl = reflAny-resp : ∀ {a p q} {A : Set a} {P : A → Set p} {Q : A → Set q}{xs ys} → (∀ {x} → P x → Q x) → xs ≈ ys →Any P xs → Any Q ysAny-resp f (x ∷ xs≈) (here px) = here (f px)Any-resp f (x ∷ xs≈) (there p) = there (Any-resp f (♭ xs≈) p)-- Any maps pointwise isomorphic predicates and equal colists to-- isomorphic types.Any-cong : ∀ {a p q} {A : Set a} {P : A → Set p} {Q : A → Set q}{xs ys} → (∀ {i} → P i ↔ Q i) → xs ≈ ys → Any P xs ↔ Any Q ysAny-cong {A = A} {P} {Q} {xs} {ys} P↔Q xs≈ys =mk↔ₛ′ (to xs≈ys) (from xs≈ys) (to∘from _) (from∘to _)whereopen Setoid (setoid _) using (sym)to : ∀ {xs ys} → xs ≈ ys → Any P xs → Any Q ysto xs≈ys = Any-resp (Inverse.to P↔Q) xs≈ysfrom : ∀ {xs ys} → xs ≈ ys → Any Q ys → Any P xsfrom xs≈ys = Any-resp (Inverse.from P↔Q) (sym xs≈ys)to∘from : ∀ {xs ys} (xs≈ys : xs ≈ ys) (q : Any Q ys) →to xs≈ys (from xs≈ys q) ≡ qto∘from (x ∷ xs≈) (there q) = cong there (to∘from (♭ xs≈) q)to∘from (x ∷ xs≈) (here qx) =cong here (Inverse.strictlyInverseˡ P↔Q qx)from∘to : ∀ {xs ys} (xs≈ys : xs ≈ ys) (p : Any P xs) →from xs≈ys (to xs≈ys p) ≡ pfrom∘to (x ∷ xs≈) (there p) = cong there (from∘to (♭ xs≈) p)from∘to (x ∷ xs≈) (here px) =cong here (Inverse.strictlyInverseʳ P↔Q px)-------------------------------------------------------------------------- mapmodule _ {f : A → B} wheremap⁻ : ∀ {xs} → Any P (map f xs) → Any (P ∘ f) xsmap⁻ {xs = x ∷ xs} (here px) = here pxmap⁻ {xs = x ∷ xs} (there p) = there (map⁻ p)map⁺ : ∀ {xs} → Any (P ∘ f) xs → Any P (map f xs)map⁺ (here px) = here pxmap⁺ (there p) = there (map⁺ p)Any-map : ∀ {xs} → Any P (map f xs) ↔ Any (P ∘ f) xsAny-map {xs = xs} = mk↔ₛ′ map⁻ map⁺ to∘from from∘towherefrom∘to : ∀ {xs} (p : Any P (map f xs)) → map⁺ (map⁻ p) ≡ pfrom∘to {xs = x ∷ xs} (here px) = reflfrom∘to {xs = x ∷ xs} (there p) = cong there (from∘to p)to∘from : ∀ {xs} (p : Any (P ∘ f) xs) → map⁻ {P = P} (map⁺ p) ≡ pto∘from (here px) = reflto∘from (there p) = cong there (to∘from p)-------------------------------------------------------------------------- _⋎_⋎⁻ : ∀ xs {ys} → Any P (xs ⋎ ys) → Any P xs ⊎ Any P ys⋎⁻ [] p = inj₂ p⋎⁻ (x ∷ xs) (here px) = inj₁ (here px)⋎⁻ (x ∷ xs) (there p) = [ inj₂ , inj₁ ∘ there ]′ (⋎⁻ _ p)mutual⋎⁺₁ : ∀ {xs ys} → Any P xs → Any P (xs ⋎ ys)⋎⁺₁ (here px) = here px⋎⁺₁ {ys = ys} (there p) = there (⋎⁺₂ ys p)⋎⁺₂ : ∀ xs {ys} → Any P ys → Any P (xs ⋎ ys)⋎⁺₂ [] p = p⋎⁺₂ (x ∷ xs) p = there (⋎⁺₁ p)⋎⁺ : ∀ xs {ys} → Any P xs ⊎ Any P ys → Any P (xs ⋎ ys)⋎⁺ xs = [ ⋎⁺₁ , ⋎⁺₂ xs ]Any-⋎ : ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} →Any P (xs ⋎ ys) ↔ (Any P xs ⊎ Any P ys)Any-⋎ {P = P} xs = mk↔ₛ′ (⋎⁻ xs) (⋎⁺ xs) (to∘from xs) (from∘to xs)wherefrom∘to : ∀ xs {ys} (p : Any P (xs ⋎ ys)) → ⋎⁺ xs (⋎⁻ xs p) ≡ pfrom∘to [] p = reflfrom∘to (x ∷ xs) (here px) = reflfrom∘to (x ∷ xs) {ys = ys} (there p) with ⋎⁻ ys p | from∘to ys pfrom∘to (x ∷ xs) {ys = ys} (there .(⋎⁺₁ q)) | inj₁ q | refl = reflfrom∘to (x ∷ xs) {ys = ys} (there .(⋎⁺₂ ys q)) | inj₂ q | refl = reflmutualto∘from₁ : ∀ {xs ys} (p : Any P xs) →⋎⁻ xs {ys = ys} (⋎⁺₁ p) ≡ inj₁ pto∘from₁ (here px) = reflto∘from₁ {ys = ys} (there p)rewrite to∘from₂ ys p = reflto∘from₂ : ∀ xs {ys} (p : Any P ys) →⋎⁻ xs (⋎⁺₂ xs p) ≡ inj₂ pto∘from₂ [] p = reflto∘from₂ (x ∷ xs) {ys = ys} prewrite to∘from₁ {xs = ys} {ys = ♭ xs} p = reflto∘from : ∀ xs {ys} (p : Any P xs ⊎ Any P ys) → ⋎⁻ xs (⋎⁺ xs p) ≡ pto∘from xs = [ to∘from₁ , to∘from₂ xs ]-------------------------------------------------------------------------- index-- The position returned by index is guaranteed to be within bounds.lookup-index : ∀ {xs} (p : Any P xs) → Is-just (lookup xs (index p))lookup-index (here px) = just _lookup-index (there p) = lookup-index p-- Any-resp preserves the index.index-Any-resp : ∀ {f : ∀ {x} → P x → Q x} {xs ys}(xs≈ys : xs ≈ ys) (p : Any P xs) →index (Any-resp f xs≈ys p) ≡ index pindex-Any-resp (x ∷ xs≈) (here px) = reflindex-Any-resp (x ∷ xs≈) (there p) =cong suc (index-Any-resp (♭ xs≈) p)-- The left-to-right direction of Any-⋎ returns a proof whose size is-- no larger than that of the input proof.index-Any-⋎ : ∀ xs {ys} (p : Any P (xs ⋎ ys)) →index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎ xs) p)index-Any-⋎ [] p = ≤′-reflindex-Any-⋎ (x ∷ xs) (here px) = ≤′-reflindex-Any-⋎ (x ∷ xs) {ys = ys} (there p)with Inverse.to (Any-⋎ ys) p | index-Any-⋎ ys p... | inj₁ q | q≤p = ≤′-step q≤p... | inj₂ q | q≤p = s≤′s q≤p
-------------------------------------------------------------------------- The Agda standard library---- Coinductive lists where all elements satisfy a predicate------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Relation.Unary.All whereopen import Codata.Musical.Colist.Baseopen import Codata.Musical.Notationopen import Level using (Level; _⊔_)open import Relation.Unary using (Pred)privatevariablea b p : LevelA : Set aB : Set bP : Pred A pdata All {A : Set a} (P : Pred A p) : Pred (Colist A) (a ⊔ p) where[] : All P []_∷_ : ∀ {x xs} (px : P x) (pxs : ∞ (All P (♭ xs))) → All P (x ∷ xs)infixr 5 _∷_
-------------------------------------------------------------------------- The Agda standard library---- Coinductive lists where all elements satisfy a predicate------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Relation.Unary.All.Properties whereopen import Codata.Musical.Colist.Baseopen import Codata.Musical.Colist.Relation.Unary.Allopen import Codata.Musical.Notationopen import Function.Base using (_∋_)open import Level using (Level; _⊔_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Unary using (Pred)privatevariablea b p : LevelA : Set aB : Set bP : Pred A p∷-injectiveˡ : ∀ {x xs px qx pxs qxs} →(All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → px ≡ qx∷-injectiveˡ refl = refl∷-injectiveʳ : ∀ {x xs px qx pxs qxs} →(All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → pxs ≡ qxs∷-injectiveʳ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Properties of coinductive lists and their operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Properties whereopen import Level using (Level)open import Codata.Musical.Notationopen import Codata.Musical.Colist.Baseopen import Function.Base using (_∋_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b : LevelA : Set aB : Set b∷-injectiveˡ : ∀ {x y xs ys} → (Colist A ∋ x ∷ xs) ≡ y ∷ ys → x ≡ y∷-injectiveˡ refl = refl∷-injectiveʳ : ∀ {x y xs ys} → (Colist A ∋ x ∷ xs) ≡ y ∷ ys → xs ≡ ys∷-injectiveʳ refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Infinite merge operation for coinductive lists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Infinite-merge whereopen import Codata.Musical.Notationopen import Codata.Musical.Colist as Colist hiding (_⋎_)open import Data.Nat.Baseopen import Data.Nat.Induction using (<′-wellFounded)open import Data.Nat.Propertiesopen import Data.Product.Base as Product using (_×_; _,_; ∃; ∃₂; proj₁; proj₂)open import Data.Sum.Baseopen import Data.Sum.Propertiesopen import Data.Sum.Function.Propositional using (_⊎-cong_)open import Function.Baseopen import Function.Bundlesopen import Function.Properties.Inverse using (↔-refl; ↔-sym; ↔⇒↣)import Function.Related.Propositional as Relatedopen import Function.Related.TypeIsomorphismsopen import Levelopen import Relation.Unary using (Pred)import Induction.WellFounded as WFopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)import Relation.Binary.Construct.On as Onprivatevariablea p : LevelA : Set aP : Pred A p-------------------------------------------------------------------------- Some code that is used to work around Agda's syntactic guardedness-- checker.privateinfixr 5 _∷_ _⋎_data ColistP (A : Set a) : Set a where[] : ColistP A_∷_ : A → ∞ (ColistP A) → ColistP A_⋎_ : ColistP A → ColistP A → ColistP Adata ColistW (A : Set a) : Set a where[] : ColistW A_∷_ : A → ColistP A → ColistW Aprogram : Colist A → ColistP Aprogram [] = []program (x ∷ xs) = x ∷ ♯ program (♭ xs)mutual_⋎W_ : ColistW A → ColistP A → ColistW A[] ⋎W ys = whnf ys(x ∷ xs) ⋎W ys = x ∷ (ys ⋎ xs)whnf : ColistP A → ColistW Awhnf [] = []whnf (x ∷ xs) = x ∷ ♭ xswhnf (xs ⋎ ys) = whnf xs ⋎W ysmutual⟦_⟧P : ColistP A → Colist A⟦ xs ⟧P = ⟦ whnf xs ⟧W⟦_⟧W : ColistW A → Colist A⟦ [] ⟧W = []⟦ x ∷ xs ⟧W = x ∷ ♯ ⟦ xs ⟧Pmutual⋎-homP : ∀ (xs : ColistP A) {ys} → ⟦ xs ⋎ ys ⟧P ≈ ⟦ xs ⟧P Colist.⋎ ⟦ ys ⟧P⋎-homP xs = ⋎-homW (whnf xs) _⋎-homW : ∀ (xs : ColistW A) ys → ⟦ xs ⋎W ys ⟧W ≈ ⟦ xs ⟧W Colist.⋎ ⟦ ys ⟧P⋎-homW (x ∷ xs) ys = x ∷ ♯ ⋎-homP ys⋎-homW [] ys = begin ⟦ ys ⟧P ∎where open ≈-Reasoning⟦program⟧P : ∀ (xs : Colist A) → ⟦ program xs ⟧P ≈ xs⟦program⟧P [] = []⟦program⟧P (x ∷ xs) = x ∷ ♯ ⟦program⟧P (♭ xs)Any-⋎P : ∀ xs {ys} →Any P ⟦ program xs ⋎ ys ⟧P ↔ (Any P xs ⊎ Any P ⟦ ys ⟧P)Any-⋎P {P = P} xs {ys} =Any P ⟦ program xs ⋎ ys ⟧P ↔⟨ Any-cong ↔-refl (⋎-homP (program xs)) ⟩Any P (⟦ program xs ⟧P Colist.⋎ ⟦ ys ⟧P) ↔⟨ Any-⋎ _ ⟩(Any P ⟦ program xs ⟧P ⊎ Any P ⟦ ys ⟧P) ↔⟨ Any-cong ↔-refl (⟦program⟧P _) ⊎-cong (_ ∎) ⟩(Any P xs ⊎ Any P ⟦ ys ⟧P) ∎where open Related.EquationalReasoningindex-Any-⋎P :∀ xs {ys} (p : Any P ⟦ program xs ⋎ ys ⟧P) →index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎P xs) p)index-Any-⋎P xs pwith Any-resp id (⋎-homW (whnf (program xs)) _) p| index-Any-resp {f = id} (⋎-homW (whnf (program xs)) _) pindex-Any-⋎P xs p | q | q≡pwith Inverse.to (Any-⋎ ⟦ program xs ⟧P) q| index-Any-⋎ ⟦ program xs ⟧P qindex-Any-⋎P xs p | q | q≡p | inj₂ r | r≤q rewrite q≡p = r≤qindex-Any-⋎P xs p | q | q≡p | inj₁ r | r≤qwith Any-resp id (⟦program⟧P xs) r| index-Any-resp {f = id} (⟦program⟧P xs) rindex-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q | s | s≡rrewrite s≡r | q≡p = r≤q-------------------------------------------------------------------------- Infinite variant of _⋎_.privatemerge′ : Colist (A × Colist A) → ColistP Amerge′ [] = []merge′ ((x , xs) ∷ xss) = x ∷ ♯ (program xs ⋎ merge′ (♭ xss))merge : Colist (A × Colist A) → Colist Amerge xss = ⟦ merge′ xss ⟧P-------------------------------------------------------------------------- Any lemma for merge.Any-merge : ∀ xss → Any P (merge xss) ↔ Any (λ { (x , xs) → P x ⊎ Any P xs }) xssAny-merge {P = P} xss = mk↔ₛ′ (proj₁ ∘ to xss) from to∘from (proj₂ ∘ to xss)whereopen ≡-Reasoning-- The from function.Q = λ { (x , xs) → P x ⊎ Any P xs }from : ∀ {xss} → Any Q xss → Any P (merge xss)from (here (inj₁ p)) = here pfrom (here (inj₂ p)) = there (Inverse.from (Any-⋎P _) (inj₁ p))from (there {x = _ , xs} p) = there (Inverse.from (Any-⋎P xs) (inj₂ (from p)))-- The from function is injective.from-injective : ∀ {xss} (p₁ p₂ : Any Q xss) →from p₁ ≡ from p₂ → p₁ ≡ p₂from-injective (here (inj₁ p)) (here (inj₁ .p)) refl = reflfrom-injective (here (inj₂ p₁)) (here (inj₂ p₂)) eq =cong (here ∘ inj₂) $inj₁-injective $Injection.injective (↔⇒↣ (↔-sym (Any-⋎P _))) $there-injective eqfrom-injective (here (inj₂ p₁)) (there p₂) eq withInjection.injective (↔⇒↣ (↔-sym (Any-⋎P _))){x = inj₁ p₁} {y = inj₂ (from p₂)}(there-injective eq)... | ()from-injective (there p₁) (here (inj₂ p₂)) eq withInjection.injective (↔⇒↣ (↔-sym (Any-⋎P _))){x = inj₂ (from p₁)} {y = inj₁ p₂}(there-injective eq)... | ()from-injective (there {x = _ , xs} p₁) (there p₂) eq =cong there $from-injective p₁ p₂ $inj₂-injective $Injection.injective (↔⇒↣ (↔-sym (Any-⋎P xs))) $there-injective eq-- The to function (defined as a right inverse of from).Input = ∃ λ xss → Any P (merge xss)InputPred : Input → Set _InputPred (xss , p) = ∃ λ (q : Any Q xss) → from q ≡ pto : ∀ xss p → InputPred (xss , p)to xss p =WF.All.wfRec (On.wellFounded size <′-wellFounded) _InputPred step (xss , p)wheresize : Input → ℕsize (_ , p) = index pstep : ∀ p → WF.WfRec (_<′_ on size) InputPred p → InputPred pstep ([] , ()) recstep ((x , xs) ∷ xss , here p) rec = here (inj₁ p) , reflstep ((x , xs) ∷ xss , there p) recwith Inverse.to (Any-⋎P xs) p| Inverse.strictlyInverseʳ (Any-⋎P xs) p| index-Any-⋎P xs p... | inj₁ q | refl | _ = here (inj₂ q) , refl... | inj₂ q | refl | q≤p =Product.map there(cong (there ∘ (Inverse.from (Any-⋎P xs)) ∘ inj₂))(rec (s≤′s q≤p))to∘from = λ p → from-injective _ _ (proj₂ (to xss (from p)))-- Every member of xss is a member of merge xss, and vice versa (with-- equal multiplicities).∈-merge : ∀ {y : A} xss → y ∈ merge xss ↔ ∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)∈-merge {y = y} xss =y ∈ merge xss ↔⟨ Any-merge _ ⟩Any (λ { (x , xs) → y ≡ x ⊎ y ∈ xs }) xss ↔⟨ Any-∈ ⟩(∃ λ { (x , xs) → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs) }) ↔⟨ Σ-assoc ⟩(∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)) ∎where open Related.EquationalReasoning
-------------------------------------------------------------------------- The Agda standard library---- Pointwise equality of colists------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Bisimilarity whereopen import Codata.Musical.Colist.Baseopen import Codata.Musical.Notationopen import Level using (Level)open import Relation.Binary.Core using (Rel; _=[_]⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)privatevariablea b : LevelA : Set aB : Set b-- xs ≈ ys means that xs and ys are equal.infix 4 _≈_data _≈_ {A : Set a} : Rel (Colist A) a where[] : [] ≈ []_∷_ : ∀ x {xs ys} (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ x ∷ ysinfixr 5 _∷_-- The equality relation forms a setoid.setoid : Set a → Setoid _ _setoid A = record{ Carrier = Colist A; _≈_ = _≈_; isEquivalence = record{ refl = refl; sym = sym; trans = trans}}whererefl : Reflexive _≈_refl {[]} = []refl {x ∷ xs} = x ∷ ♯ reflsym : Symmetric _≈_sym [] = []sym (x ∷ xs≈) = x ∷ ♯ sym (♭ xs≈)trans : Transitive _≈_trans [] [] = []trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)module ≈-Reasoning whereimport Relation.Binary.Reasoning.Setoid as EqRprivateopen module R {a} {A : Set a} = EqR (setoid A) public-- map preserves equality.map-cong : (f : A → B) → _≈_ =[ map f ]⇒ _≈_map-cong f [] = []map-cong f (x ∷ xs≈) = f x ∷ ♯ map-cong f (♭ xs≈)
-------------------------------------------------------------------------- The Agda standard library---- Coinductive lists: base type and functions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --guardedness #-}module Codata.Musical.Colist.Base whereopen import Level using (Level)open import Codata.Musical.Notationopen import Codata.Musical.Conat.Base using (Coℕ; zero; suc)open import Data.Bool.Base using (Bool; true; false)open import Data.List.Base using (List; []; _∷_)open import Data.List.NonEmpty.Base using (List⁺; _∷_)open import Data.Maybe.Base using (Maybe; nothing; just)open import Data.Nat.Base using (ℕ; zero; suc)privatevariablea b : LevelA : Set aB : Set b-------------------------------------------------------------------------- The typeinfixr 5 _∷_data Colist (A : Set a) : Set a where[] : Colist A_∷_ : (x : A) (xs : ∞ (Colist A)) → Colist A{-# FOREIGN GHCdata AgdaColist a = Nil | Cons a (MAlonzo.RTE.Inf (AgdaColist a))type AgdaColist' l a = AgdaColist a#-}{-# COMPILE GHC Colist = data AgdaColist' (Nil | Cons) #-}{-# COMPILE UHC Colist = data __LIST__ (__NIL__ | __CONS__) #-}-------------------------------------------------------------------------- Some operationsnull : Colist A → Boolnull [] = truenull (_ ∷ _) = falselength : Colist A → Coℕlength [] = zerolength (x ∷ xs) = suc (♯ length (♭ xs))map : (A → B) → Colist A → Colist Bmap f [] = []map f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)fromList : List A → Colist AfromList [] = []fromList (x ∷ xs) = x ∷ ♯ fromList xsreplicate : Coℕ → A → Colist Areplicate zero x = []replicate (suc n) x = x ∷ ♯ replicate (♭ n) xlookup : Colist A → ℕ → Maybe Alookup [] _ = nothinglookup (x ∷ _) zero = just xlookup (_ ∷ xs) (suc n) = lookup (♭ xs) ninfixr 5 _++__++_ : Colist A → Colist A → Colist A[] ++ ys = ys(x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)-- Interleaves the two colists (until the shorter one, if any, has-- been exhausted).infixr 5 _⋎__⋎_ : Colist A → Colist A → Colist A[] ⋎ ys = ys(x ∷ xs) ⋎ ys = x ∷ ♯ (ys ⋎ ♭ xs)concat : Colist (List⁺ A) → Colist Aconcat [] = []concat ((x ∷ []) ∷ xss) = x ∷ ♯ concat (♭ xss)concat ((x ∷ (y ∷ xs)) ∷ xss) = x ∷ ♯ concat ((y ∷ xs) ∷ xss)[_] : A → Colist A[ x ] = x ∷ ♯ []
-------------------------------------------------------------------------- The Agda standard library---- "Finite" sets indexed on coinductive "natural" numbers------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Musical.Cofin whereopen import Codata.Musical.Notationopen import Codata.Musical.Conat as Conat using (Coℕ; suc; ∞ℕ)open import Data.Nat.Base using (ℕ; zero; suc)open import Data.Fin.Base using (Fin; zero; suc)open import Relation.Binary.PropositionalEquality.Core using (_≡_ ; refl)open import Function.Base using (_∋_)-------------------------------------------------------------------------- The type-- Note that Cofin ∞ℕ is /not/ finite. Note also that this is not a-- coinductive type, but it is indexed on a coinductive type.data Cofin : Coℕ → Set wherezero : ∀ {n} → Cofin (suc n)suc : ∀ {n} (i : Cofin (♭ n)) → Cofin (suc n)suc-injective : ∀ {m} {p q : Cofin (♭ m)} → (Cofin (suc m) ∋ suc p) ≡ suc q → p ≡ qsuc-injective refl = refl-------------------------------------------------------------------------- Some operationsfromℕ : ℕ → Cofin ∞ℕfromℕ zero = zerofromℕ (suc n) = suc (fromℕ n)toℕ : ∀ {n} → Cofin n → ℕtoℕ zero = zerotoℕ (suc i) = suc (toℕ i)fromFin : ∀ {n} → Fin n → Cofin (Conat.fromℕ n)fromFin zero = zerofromFin (suc i) = suc (fromFin i)toFin : ∀ n → Cofin (Conat.fromℕ n) → Fin ntoFin (suc n) zero = zerotoFin (suc n) (suc i) = suc (toFin n i)
-------------------------------------------------------------------------- The Agda standard library---- Infinite streams defined as coinductive records------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Codata.Guarded.Stream whereopen import Level hiding (suc)open import Data.Nat.Baseopen import Function.Baseopen import Data.List.Base as List using (List; []; _∷_)open import Data.Product.Base hiding (map)open import Data.Vec.Base using (Vec; []; _∷_)open import Data.List.NonEmpty.Base as List⁺ using (List⁺; _∷_)open import Algebra.Coreopen import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)privatevariablea b c : LevelA : Set aB : Set bC : Set c-------------------------------------------------------------------------- Typeinfixr 5 _∷_record Stream (A : Set a) : Set a wherecoinductiveconstructor _∷_fieldhead : Atail : Stream Aopen Stream public-------------------------------------------------------------------------- Creating streamstabulate : (ℕ → A) → Stream Atabulate f .head = f 0tabulate f .tail = tabulate (f ∘′ suc)repeat : A → Stream Arepeat = tabulate ∘′ constinfixr 5 _++__++_ : List A → Stream A → Stream A[] ++ s = s(x ∷ xs) ++ s = x ∷ xs ++ sunfold : (A → A × B) → A → Stream Bunfold next seed .head = next seed .proj₂unfold next seed .tail = unfold next (next seed .proj₁)iterate : (A → A) → A → Stream Aiterate f = unfold < f , id >nats : Stream ℕnats = tabulate id-------------------------------------------------------------------------- Lookuplookup : Stream A → ℕ → Alookup xs zero = head xslookup xs (suc n) = lookup (tail xs) ninfix 4 _[_]_[_] : Stream A → ℕ → A_[_] = lookup-------------------------------------------------------------------------- Transforming streamsmap : (A → B) → Stream A → Stream Bmap f s .head = f (s .head)map f s .tail = map f (s .tail)ap : Stream (A → B) → Stream A → Stream Bap fs xs .head = fs .head (xs .head)ap fs xs .tail = ap (fs .tail) (xs .tail)scanl : (B → A → B) → B → Stream A → Stream Bscanl c n s .head = nscanl c n s .tail = scanl c (c n (s .head)) (s .tail)zipWith : (A → B → C) → Stream A → Stream B → Stream CzipWith f s t .head = f (s .head) (t .head)zipWith f s t .tail = zipWith f (s .tail) (t .tail)transpose : List (Stream A) → Stream (List A)transpose [] = repeat []transpose (s ∷ ss) = zipWith _∷_ s (transpose ss)tails : Stream A → Stream (Stream A)tails s .head = stails s .tail = tails (s .tail)evens : Stream A → Stream Aevens s .head = s .headevens s .tail = evens (s .tail .tail)odds : Stream A → Stream Aodds s = evens (s .tail)-------------------------------------------------------------------------- List⁺-related functionsinfixr 5 _⁺++__⁺++_ : List⁺ A → Stream A → Stream A(x ∷ xs) ⁺++ ys = x ∷ xs ++ ysconcat : Stream (List⁺ A) → Stream Aconcat {A = A} = ++-concat []module Concat where++-concat : List A → Stream (List⁺ A) → Stream A++-concat [] s .head = s .head .List⁺.head++-concat [] s .tail = ++-concat (s .head .List⁺.tail) (s .tail)++-concat (x ∷ xs) s .head = x++-concat (x ∷ xs) s .tail = ++-concat xs scycle : List⁺ A → Stream Acycle = concat ∘′ repeattranspose⁺ : List⁺ (Stream A) → Stream (List⁺ A)transpose⁺ (s ∷ ss) = zipWith _∷_ s (transpose ss)-------------------------------------------------------------------------- ChunkingsplitAt : ∀ n → Stream A → Vec A n × Stream AsplitAt zero s = [] ,′ ssplitAt (suc n) s = map₁ (s .head ∷_) (splitAt n (s .tail))take : ∀ n → Stream A → Vec A ntake = proj₁ ∘₂ splitAtdrop : ℕ → Stream A → Stream Adrop = proj₂ ∘₂ splitAtchunksOf : ∀ n → Stream A → Stream (Vec A n)chunksOf n s .head = take n schunksOf n s .tail = chunksOf n (drop n s)-------------------------------------------------------------------------- Interleaving streams-- Interleaving two streamsinterleave : Op₂ (Stream A)interleave xs ys .head = xs .headinterleave xs ys .tail = interleave ys (xs .tail)-- Interleaving multiple streamsinterleave⁺ : List⁺ (Stream A) → Stream Ainterleave⁺ = concat ∘′ transpose⁺-- Interleaving a stream of streams using Cantor's zig zag function-- (inverse of Cantor's pairing function)cantor : Stream (Stream A) → Stream Acantor s .head = s .head .headcantor s .tail = cantor (zipWith _∷_ (s .head .tail) (s .tail))-- A version of `bind` using the zig zag function that reaches any-- point of the plane in a finite amout of timeplane : {B : A → Set b} → Stream A → (∀ a → Stream (B a)) → Stream (Σ A B)plane xs fs = cantor (map (λ x → map (x ,_) (fs x)) xs)-- Here is the beginning of the path we are following:_ : take 21 (plane nats (const nats))≡ (0 , 0)∷ (0 , 1) ∷ (1 , 0)∷ (0 , 2) ∷ (1 , 1) ∷ (2 , 0)∷ (0 , 3) ∷ (1 , 2) ∷ (2 , 1) ∷ (3 , 0)∷ (0 , 4) ∷ (1 , 3) ∷ (2 , 2) ∷ (3 , 1) ∷ (4 , 0)∷ (0 , 5) ∷ (1 , 4) ∷ (2 , 3) ∷ (3 , 2) ∷ (4 , 1) ∷ (5 , 0)∷ []_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Streams where at least one element satisfies a given property------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Guarded.Stream.Relation.Unary.Any whereopen import Codata.Guarded.Stream as Stream using (Stream)open import Data.Emptyopen import Data.Nat.Base hiding (_⊔_)open import Level hiding (zero; suc)open import Relation.Nullaryopen import Relation.Unaryprivatevariablea p q : LevelA : Set aP Q : Pred A pxs : Stream Adata Any {A : Set a} (P : Pred A p) : Stream A → Set (a ⊔ p) wherehere : ∀ {xs} → P (Stream.head xs) → Any P xsthere : ∀ {xs} → Any P (Stream.tail xs) → Any P xshead : ¬ Any P (Stream.tail xs) → Any P xs → P (Stream.head xs)head ¬t (here h) = hhead ¬t (there t) = ⊥-elim (¬t t)tail : ¬ P (Stream.head xs) → Any P xs → Any P (Stream.tail xs)tail ¬h (here h) = ⊥-elim (¬h h)tail ¬h (there t) = tmap : P ⊆ Q → Any P ⊆ Any Qmap g (here px ) = here (g px)map g (there pxs) = there (map g pxs)index : Any P xs → ℕindex (here px ) = zeroindex (there pxs) = suc (index pxs)lookup : {P : Pred A p} → Any P xs → Alookup {xs = xs} p = Stream.lookup xs (index p)
-------------------------------------------------------------------------- The Agda standard library---- Streams where all elements satisfy a given property------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Guarded.Stream.Relation.Unary.All whereopen import Codata.Guarded.Stream using (Stream; head; tail)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Levelopen import Relation.Unaryprivatevariablea p ℓ : LevelA : Set aP Q R : Pred A pxs : Stream Ainfixr 5 _∷_record All (P : Pred A ℓ) (as : Stream A) : Set ℓ wherecoinductiveconstructor _∷_fieldhead : P (head as)tail : All P (tail as)open All publicmap : P ⊆ Q → All P ⊆ All Qhead (map f xs) = f (head xs)tail (map f xs) = map f (tail xs)zipWith : P ∩ Q ⊆ R → All P ∩ All Q ⊆ All Rhead (zipWith f (ps , qs)) = f (head ps , head qs)tail (zipWith f (ps , qs)) = zipWith f (tail ps , tail qs)unzipWith : R ⊆ P ∩ Q → All R ⊆ All P ∩ All Qhead (proj₁ (unzipWith f rs)) = proj₁ (f (head rs))tail (proj₁ (unzipWith f rs)) = proj₁ (unzipWith f (tail rs))head (proj₂ (unzipWith f rs)) = proj₂ (f (head rs))tail (proj₂ (unzipWith f rs)) = proj₂ (unzipWith f (tail rs))
-------------------------------------------------------------------------- The Agda standard library---- Coinductive pointwise lifting of relations to streams------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Guarded.Stream.Relation.Binary.Pointwise whereopen import Codata.Guarded.Stream as Stream using (Stream; head; tail)open import Data.Nat.Base using (ℕ; zero; suc)open import Function.Base using (_∘_; _on_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (REL; _⇒_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Reflexive; Sym; Trans; Antisym; Symmetric; Transitive)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Relation.Binary.PropositionalEquality.Properties as ≡privatevariablea ℓ : LevelA B C D : Set aR S T : REL A B ℓxs ys : Stream A-------------------------------------------------------------------------- Bisimilarityinfixr 5 _∷_record Pointwise (_∼_ : REL A B ℓ) (as : Stream A) (bs : Stream B) : Set ℓ wherecoinductiveconstructor _∷_fieldhead : head as ∼ head bstail : Pointwise _∼_ (tail as) (tail bs)open Pointwise publiclookup⁺ : ∀ {as bs} → Pointwise R as bs →∀ n → R (Stream.lookup as n) (Stream.lookup bs n)lookup⁺ rs zero = rs .headlookup⁺ rs (suc n) = lookup⁺ (rs .tail) nmap : R ⇒ S → Pointwise R ⇒ Pointwise Shead (map R⇒S xs) = R⇒S (head xs)tail (map R⇒S xs) = map R⇒S (tail xs)reflexive : Reflexive R → Reflexive (Pointwise R)head (reflexive R-refl) = R-refltail (reflexive R-refl) = reflexive R-reflsymmetric : Sym R S → Sym (Pointwise R) (Pointwise S)head (symmetric R-sym-S xsRys) = R-sym-S (head xsRys)tail (symmetric R-sym-S xsRys) = symmetric R-sym-S (tail xsRys)transitive : Trans R S T → Trans (Pointwise R) (Pointwise S) (Pointwise T)head (transitive RST-trans xsRys ysSzs) = RST-trans (head xsRys) (head ysSzs)tail (transitive RST-trans xsRys ysSzs) = transitive RST-trans (tail xsRys) (tail ysSzs)isEquivalence : IsEquivalence R → IsEquivalence (Pointwise R)isEquivalence equiv^R = record{ refl = reflexive equiv^R.refl; sym = symmetric equiv^R.sym; trans = transitive equiv^R.trans} where module equiv^R = IsEquivalence equiv^Rsetoid : Setoid a ℓ → Setoid a ℓsetoid S = record{ isEquivalence = isEquivalence (Setoid.isEquivalence S)}antisymmetric : Antisym R S T → Antisym (Pointwise R) (Pointwise S) (Pointwise T)head (antisymmetric RST-antisym xsRys ysSxs) = RST-antisym (head xsRys) (head ysSxs)tail (antisymmetric RST-antisym xsRys ysSxs) = antisymmetric RST-antisym (tail xsRys) (tail ysSxs)tabulate⁺ : ∀ {f : ℕ → A} {g : ℕ → B} →(∀ i → R (f i) (g i)) → Pointwise R (Stream.tabulate f) (Stream.tabulate g)head (tabulate⁺ f∼g) = f∼g 0tail (tabulate⁺ f∼g) = tabulate⁺ (f∼g ∘ suc)tabulate⁻ : ∀ {f : ℕ → A} {g : ℕ → B} →Pointwise R (Stream.tabulate f) (Stream.tabulate g) → (∀ i → R (f i) (g i))tabulate⁻ xsRys zero = head xsRystabulate⁻ xsRys (suc i) = tabulate⁻ (tail xsRys) imap⁺ : ∀ (f : A → C) (g : B → D) →Pointwise (λ a b → R (f a) (g b)) xs ys →Pointwise R (Stream.map f xs) (Stream.map g ys)head (map⁺ f g faRgb) = head faRgbtail (map⁺ f g faRgb) = map⁺ f g (tail faRgb)map⁻ : ∀ (f : A → C) (g : B → D) →Pointwise R (Stream.map f xs) (Stream.map g ys) →Pointwise (λ a b → R (f a) (g b)) xs yshead (map⁻ f g faRgb) = head faRgbtail (map⁻ f g faRgb) = map⁻ f g (tail faRgb)drop⁺ : ∀ n → Pointwise R ⇒ (Pointwise R on Stream.drop n)drop⁺ zero as≈bs = as≈bsdrop⁺ (suc n) as≈bs = drop⁺ n (as≈bs .tail)-------------------------------------------------------------------------- Pointwise Equality as a Bisimilaritymodule _ {A : Set a} whereinfix 1 _≈__≈_ : Stream A → Stream A → Set a_≈_ = Pointwise _≡_refl : Reflexive _≈_refl = reflexive ≡.reflsym : Symmetric _≈_sym = symmetric ≡.symtrans : Transitive _≈_trans = transitive ≡.trans≈-setoid : Setoid _ _≈-setoid = setoid (≡.setoid A)-------------------------------------------------------------------------- Pointwise DSL---- A guardedness check does not play well with compositional proofs.-- Luckily we can learn from Nils Anders Danielsson's-- Beating the Productivity Checker Using Embedded Languages-- and design a little compositional DSL to define such proofs---- NOTE: also because of the guardedness check we can't use the standard-- `Relation.Binary.Reasoning.Syntax` approach.module pw-Reasoning (S : Setoid a ℓ) whereprivate module S = Setoid Sopen S using (Carrier) renaming (_≈_ to _∼_)record `Pointwise∞ (as bs : Stream Carrier) : Set (a ⊔ ℓ)data `Pointwise (as bs : Stream Carrier) : Set (a ⊔ ℓ)record `Pointwise∞ as bs wherecoinductivefieldhead : (as .head) ∼ (bs .head)tail : `Pointwise (as .tail) (bs .tail)data `Pointwise as bs where`lift : Pointwise _∼_ as bs → `Pointwise as bs`step : `Pointwise∞ as bs → `Pointwise as bs`refl : as ≡ bs → `Pointwise as bs`bisim : as ≈ bs → `Pointwise as bs`sym : `Pointwise bs as → `Pointwise as bs`trans : ∀ {ms} → `Pointwise as ms → `Pointwise ms bs → `Pointwise as bsopen `Pointwise∞ public`head : ∀ {as bs} → `Pointwise as bs → as .head ∼ bs .head`head (`lift rs) = rs .head`head (`refl eq) = S.reflexive (≡.cong head eq)`head (`bisim rs) = S.reflexive (rs .head)`head (`step `rs) = `rs .head`head (`sym `rs) = S.sym (`head `rs)`head (`trans `rs₁ `rs₂) = S.trans (`head `rs₁) (`head `rs₂)`tail : ∀ {as bs} → `Pointwise as bs → `Pointwise (as .tail) (bs .tail)`tail (`lift rs) = `lift (rs .tail)`tail (`refl eq) = `refl (≡.cong tail eq)`tail (`bisim rs) = `bisim (rs .tail)`tail (`step `rs) = `rs .tail`tail (`sym `rs) = `sym (`tail `rs)`tail (`trans `rs₁ `rs₂) = `trans (`tail `rs₁) (`tail `rs₂)run : ∀ {as bs} → `Pointwise as bs → Pointwise _∼_ as bsrun `rs .head = `head `rsrun `rs .tail = run (`tail `rs)infix 1 begin_infixr 2 _↺⟨_⟩_ _↺⟨_⟨_ _∼⟨_⟩_ _∼⟨_⟨_ _≈⟨_⟩_ _≈⟨_⟨_ _≡⟨_⟩_ _≡⟨_⟨_ _≡⟨⟩_infix 3 _∎-- Beginning of a proofbegin_ : ∀ {as bs} → `Pointwise∞ as bs → Pointwise _∼_ as bs(begin `rs) .head = `rs .head(begin `rs) .tail = run (`rs .tail)pattern _↺⟨_⟩_ as as∼bs bs∼cs = `trans {as = as} (`step as∼bs) bs∼cspattern _↺⟨_⟨_ as bs∼as bs∼cs = `trans {as = as} (`sym (`step bs∼as)) bs∼cspattern _∼⟨_⟩_ as as∼bs bs∼cs = `trans {as = as} (`lift as∼bs) bs∼cspattern _∼⟨_⟨_ as bs∼as bs∼cs = `trans {as = as} (`sym (`lift bs∼as)) bs∼cspattern _≈⟨_⟩_ as as∼bs bs∼cs = `trans {as = as} (`bisim as∼bs) bs∼cspattern _≈⟨_⟨_ as bs∼as bs∼cs = `trans {as = as} (`sym (`bisim bs∼as)) bs∼cspattern _≡⟨_⟩_ as as∼bs bs∼cs = `trans {as = as} (`refl as∼bs) bs∼cspattern _≡⟨_⟨_ as bs∼as bs∼cs = `trans {as = as} (`sym (`refl bs∼as)) bs∼cspattern _≡⟨⟩_ as as∼bs = `trans {as = as} (`refl ≡.refl) as∼bspattern _∎ as = `refl {as = as} ≡.refl-- Deprecated v2.0infixr 2 _↺˘⟨_⟩_ _∼˘⟨_⟩_ _≈˘⟨_⟩_ _≡˘⟨_⟩_pattern _↺˘⟨_⟩_ as bs∼as bs∼cs = `trans {as = as} (`sym (`step bs∼as)) bs∼cspattern _∼˘⟨_⟩_ as bs∼as bs∼cs = `trans {as = as} (`sym (`lift bs∼as)) bs∼cspattern _≈˘⟨_⟩_ as bs∼as bs∼cs = `trans {as = as} (`sym (`bisim bs∼as)) bs∼cspattern _≡˘⟨_⟩_ as bs∼as bs∼cs = `trans {as = as} (`sym (`refl bs∼as)) bs∼cs{-# WARNING_ON_USAGE _↺˘⟨_⟩_"Warning: _↺˘⟨_⟩_ was deprecated in v2.0.Please use _↺⟨_⟨_ instead."#-}{-# WARNING_ON_USAGE _∼˘⟨_⟩_"Warning: _∼˘⟨_⟩_ was deprecated in v2.0.Please use _∼⟨_⟨_ instead."#-}{-# WARNING_ON_USAGE _≈˘⟨_⟩_"Warning: _≈˘⟨_⟩_ was deprecated in v2.0.Please use _≈⟨_⟨_ instead."#-}{-# WARNING_ON_USAGE _≡˘⟨_⟩_"Warning: _≡˘⟨_⟩_ was deprecated in v2.0.Please use _≡⟨_⟨_ instead."#-}module ≈-Reasoning {a} {A : Set a} whereopen pw-Reasoning (≡.setoid A) publicinfix 4 _≈∞__≈∞_ = `Pointwise∞
-------------------------------------------------------------------------- The Agda standard library---- Properties of infinite streams defined as coinductive records------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible --guardedness #-}module Codata.Guarded.Stream.Properties whereopen import Codata.Guarded.Streamopen import Codata.Guarded.Stream.Relation.Binary.Pointwiseas B using (_≈_; head; tail; module ≈-Reasoning)open import Data.List.Base as List using (List; []; _∷_)open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)open import Data.Nat.Base using (ℕ; zero; suc; _+_; _*_)import Data.Nat.GeneralisedArithmetic as ℕopen import Data.Product.Base as Prod using (_×_; _,_; proj₁; proj₂)open import Data.Vec.Base as Vec using (Vec; _∷_)open import Function.Base using (const; flip; id; _∘′_; _$′_; _⟨_⟩_; _∘₂′_)open import Level using (Level)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)privatevariablea b c d : LevelA : Set aB : Set bC : Set cD : Set d-------------------------------------------------------------------------- Congruencecong-lookup : ∀ {as bs : Stream A} → as ≈ bs → ∀ n → lookup as n ≡ lookup bs ncong-lookup = B.lookup⁺cong-take : ∀ n {as bs : Stream A} → as ≈ bs → take n as ≡ take n bscong-take zero as≈bs = reflcong-take (suc n) as≈bs = cong₂ _∷_ (as≈bs .head) (cong-take n (as≈bs .tail))cong-drop : ∀ n {as bs : Stream A} → as ≈ bs → drop n as ≈ drop n bscong-drop = B.drop⁺-- This is not map⁺ because the propositional equality relation is-- not the same on the input and outputcong-map : ∀ (f : A → B) {as bs} → as ≈ bs → map f as ≈ map f bscong-map f as≈bs .head = cong f (as≈bs .head)cong-map f as≈bs .tail = cong-map f (as≈bs .tail)cong-zipWith : ∀ (f : A → B → C) {as bs cs ds} → as ≈ bs → cs ≈ ds →zipWith f as cs ≈ zipWith f bs dscong-zipWith f as≈bs cs≈ds .head = cong₂ f (as≈bs .head) (cs≈ds .head)cong-zipWith f as≈bs cs≈ds .tail = cong-zipWith f (as≈bs .tail) (cs≈ds .tail)cong-concat : {ass bss : Stream (List⁺ A)} → ass ≈ bss → concat ass ≈ concat bsscong-concat ass≈bss = cong-++-concat [] ass≈bsswhereopen Concatcong-++-concat : ∀ (as : List A) {ass bss} → ass ≈ bss → ++-concat as ass ≈ ++-concat as bsscong-++-concat [] ass≈bss .head = cong List⁺.head (ass≈bss .head)cong-++-concat [] ass≈bss .tail rewrite ass≈bss .head = cong-++-concat _ (ass≈bss .tail)cong-++-concat (a ∷ as) ass≈bss .head = reflcong-++-concat (a ∷ as) ass≈bss .tail = cong-++-concat as ass≈bsscong-interleave : {as bs cs ds : Stream A} → as ≈ bs → cs ≈ ds →interleave as cs ≈ interleave bs dscong-interleave as≈bs cs≈ds .head = as≈bs .headcong-interleave as≈bs cs≈ds .tail = cong-interleave cs≈ds (as≈bs .tail)cong-chunksOf : ∀ n {as bs : Stream A} → as ≈ bs → chunksOf n as ≈ chunksOf n bscong-chunksOf n as≈bs .head = cong-take n as≈bscong-chunksOf n as≈bs .tail = cong-chunksOf n (cong-drop n as≈bs)-------------------------------------------------------------------------- Properties of repeatlookup-repeat : ∀ n (a : A) → lookup (repeat a) n ≡ alookup-repeat zero a = refllookup-repeat (suc n) a = lookup-repeat n asplitAt-repeat : ∀ n (a : A) → splitAt n (repeat a) ≡ (Vec.replicate n a , repeat a)splitAt-repeat zero a = reflsplitAt-repeat (suc n) a = cong (Prod.map₁ (a ∷_)) (splitAt-repeat n a)take-repeat : ∀ n (a : A) → take n (repeat a) ≡ Vec.replicate n atake-repeat n a = cong proj₁ (splitAt-repeat n a)drop-repeat : ∀ n (a : A) → drop n (repeat a) ≡ repeat adrop-repeat n a = cong proj₂ (splitAt-repeat n a)map-repeat : ∀ (f : A → B) a → map f (repeat a) ≈ repeat (f a)map-repeat f a .head = reflmap-repeat f a .tail = map-repeat f aap-repeat : ∀ (f : A → B) a → ap (repeat f) (repeat a) ≈ repeat (f a)ap-repeat f a .head = reflap-repeat f a .tail = ap-repeat f aap-repeatˡ : ∀ (f : A → B) as → ap (repeat f) as ≈ map f asap-repeatˡ f as .head = reflap-repeatˡ f as .tail = ap-repeatˡ f (as .tail)ap-repeatʳ : ∀ (fs : Stream (A → B)) a → ap fs (repeat a) ≈ map (_$′ a) fsap-repeatʳ fs a .head = reflap-repeatʳ fs a .tail = ap-repeatʳ (fs .tail) ainterleave-repeat : (a : A) → interleave (repeat a) (repeat a) ≈ repeat ainterleave-repeat a .head = reflinterleave-repeat a .tail = interleave-repeat azipWith-repeat : ∀ (f : A → B → C) a b →zipWith f (repeat a) (repeat b) ≈ repeat (f a b)zipWith-repeat f a b .head = reflzipWith-repeat f a b .tail = zipWith-repeat f a bchunksOf-repeat : ∀ n (a : A) → chunksOf n (repeat a) ≈ repeat (Vec.replicate n a)chunksOf-repeat n a = begin go whereopen ≈-Reasoninggo : chunksOf n (repeat a) ≈∞ repeat (Vec.replicate n a)go .head = take-repeat n ago .tail =chunksOf n (drop n (repeat a)) ≡⟨ cong (chunksOf n) (drop-repeat n a) ⟩chunksOf n (repeat a) ↺⟨ go ⟩repeat (Vec.replicate n a) ∎-------------------------------------------------------------------------- Properties of mapmap-const : (a : A) (bs : Stream B) → map (const a) bs ≈ repeat amap-const a bs .head = reflmap-const a bs .tail = map-const a (bs .tail)map-id : (as : Stream A) → map id as ≈ asmap-id as .head = reflmap-id as .tail = map-id (as .tail)map-∘ : ∀ (g : B → C) (f : A → B) as → map g (map f as) ≈ map (g ∘′ f) asmap-∘ g f as .head = reflmap-∘ g f as .tail = map-∘ g f (as .tail)map-unfold : ∀ (g : B → C) (f : A → A × B) a →map g (unfold f a) ≈ unfold (Prod.map₂ g ∘′ f) amap-unfold g f a .head = reflmap-unfold g f a .tail = map-unfold g f (proj₁ (f a))map-drop : ∀ (f : A → B) n as → map f (drop n as) ≡ drop n (map f as)map-drop f zero as = reflmap-drop f (suc n) as = map-drop f n (as .tail)map-zipWith : ∀ (g : C → D) (f : A → B → C) as bs →map g (zipWith f as bs) ≈ zipWith (g ∘₂′ f) as bsmap-zipWith g f as bs .head = reflmap-zipWith g f as bs .tail = map-zipWith g f (as .tail) (bs .tail)map-interleave : ∀ (f : A → B) as bs →map f (interleave as bs) ≈ interleave (map f as) (map f bs)map-interleave f as bs .head = reflmap-interleave f as bs .tail = map-interleave f bs (as .tail)map-concat : ∀ (f : A → B) ass → map f (concat ass) ≈ concat (map (List⁺.map f) ass)map-concat f ass = map-++-concat [] asswhereopen Concatmap-++-concat : ∀ acc ass → map f (++-concat acc ass) ≈ ++-concat (List.map f acc) (map (List⁺.map f) ass)map-++-concat [] ass .head = reflmap-++-concat [] ass .tail = map-++-concat (ass .head .List⁺.tail) (ass .tail)map-++-concat (a ∷ as) ass .head = reflmap-++-concat (a ∷ as) ass .tail = map-++-concat as assmap-cycle : ∀ (f : A → B) as → map f (cycle as) ≈ cycle (List⁺.map f as)map-cycle f as = run(map f (cycle as) ≡⟨⟩map f (concat (repeat as)) ≈⟨ map-concat f (repeat as) ⟩concat (map (List⁺.map f) (repeat as)) ≈⟨ cong-concat (map-repeat (List⁺.map f) as) ⟩concat (repeat (List⁺.map f as)) ≡⟨⟩cycle (List⁺.map f as) ∎)where open ≈-Reasoning-------------------------------------------------------------------------- Properties of lookuplookup-drop : ∀ m (as : Stream A) n → lookup (drop m as) n ≡ lookup as (m + n)lookup-drop zero as n = refllookup-drop (suc m) as n = lookup-drop m (as .tail) nlookup-map : ∀ n (f : A → B) as → lookup (map f as) n ≡ f (lookup as n)lookup-map zero f as = refllookup-map (suc n) f as = lookup-map n f (as . tail)lookup-iterate : ∀ n f (x : A) → lookup (iterate f x) n ≡ ℕ.iterate f x nlookup-iterate zero f x = refllookup-iterate (suc n) f x = lookup-iterate n f (f x)lookup-zipWith : ∀ n (f : A → B → C) as bs →lookup (zipWith f as bs) n ≡ f (lookup as n) (lookup bs n)lookup-zipWith zero f as bs = refllookup-zipWith (suc n) f as bs = lookup-zipWith n f (as .tail) (bs .tail)lookup-unfold : ∀ n (f : A → A × B) a →lookup (unfold f a) n ≡ proj₂ (f (ℕ.iterate (proj₁ ∘′ f) a n))lookup-unfold zero f a = refllookup-unfold (suc n) f a = lookup-unfold n f (proj₁ (f a))lookup-tabulate : ∀ n (f : ℕ → A) → lookup (tabulate f) n ≡ f nlookup-tabulate zero f = refllookup-tabulate (suc n) f = lookup-tabulate n (f ∘′ suc)lookup-transpose : ∀ n (ass : List (Stream A)) →lookup (transpose ass) n ≡ List.map (flip lookup n) asslookup-transpose n [] = lookup-repeat n []lookup-transpose n (as ∷ ass) = beginlookup (transpose (as ∷ ass)) n ≡⟨⟩lookup (zipWith _∷_ as (transpose ass)) n ≡⟨ lookup-zipWith n _∷_ as (transpose ass) ⟩lookup as n ∷ lookup (transpose ass) n ≡⟨ cong (lookup as n ∷_) (lookup-transpose n ass) ⟩lookup as n ∷ List.map (flip lookup n) ass ≡⟨⟩List.map (flip lookup n) (as ∷ ass) ∎where open ≡-Reasoninglookup-transpose⁺ : ∀ n (ass : List⁺ (Stream A)) →lookup (transpose⁺ ass) n ≡ List⁺.map (flip lookup n) asslookup-transpose⁺ n (as ∷ ass) = beginlookup (transpose⁺ (as ∷ ass)) n ≡⟨⟩lookup (zipWith _∷_ as (transpose ass)) n ≡⟨ lookup-zipWith n _∷_ as (transpose ass) ⟩lookup as n ∷ lookup (transpose ass) n ≡⟨ cong (lookup as n ∷_) (lookup-transpose n ass) ⟩lookup as n ∷ List.map (flip lookup n) ass ≡⟨⟩List⁺.map (flip lookup n) (as ∷ ass) ∎where open ≡-Reasoninglookup-tails : ∀ n (as : Stream A) → lookup (tails as) n ≈ ℕ.iterate tail as nlookup-tails zero as = B.refllookup-tails (suc n) as = lookup-tails n (as .tail)lookup-evens : ∀ n (as : Stream A) → lookup (evens as) n ≡ lookup as (n * 2)lookup-evens zero as = refllookup-evens (suc n) as = lookup-evens n (as .tail .tail)lookup-odds : ∀ n (as : Stream A) → lookup (odds as) n ≡ lookup as (suc (n * 2))lookup-odds zero as = refllookup-odds (suc n) as = lookup-odds n (as .tail .tail)lookup-interleave-even : ∀ n (as bs : Stream A) →lookup (interleave as bs) (n * 2) ≡ lookup as nlookup-interleave-even zero as bs = refllookup-interleave-even (suc n) as bs = lookup-interleave-even n (as .tail) (bs .tail)lookup-interleave-odd : ∀ n (as bs : Stream A) →lookup (interleave as bs) (suc (n * 2)) ≡ lookup bs nlookup-interleave-odd zero as bs = refllookup-interleave-odd (suc n) as bs = lookup-interleave-odd n (as .tail) (bs .tail)-------------------------------------------------------------------------- Properties of taketake-iterate : ∀ n f (x : A) → take n (iterate f x) ≡ Vec.iterate f x ntake-iterate zero f x = refltake-iterate (suc n) f x = cong (x ∷_) (take-iterate n f (f x))take-zipWith : ∀ n (f : A → B → C) as bs →take n (zipWith f as bs) ≡ Vec.zipWith f (take n as) (take n bs)take-zipWith zero f as bs = refltake-zipWith (suc n) f as bs =cong (f (as .head) (bs .head) ∷_) (take-zipWith n f (as .tail) (bs . tail))-------------------------------------------------------------------------- Properties of dropdrop-drop : ∀ m n (as : Stream A) → drop n (drop m as) ≡ drop (m + n) asdrop-drop zero n as = refldrop-drop (suc m) n as = drop-drop m n (as .tail)drop-zipWith : ∀ n (f : A → B → C) as bs →drop n (zipWith f as bs) ≡ zipWith f (drop n as) (drop n bs)drop-zipWith zero f as bs = refldrop-zipWith (suc n) f as bs = drop-zipWith n f (as .tail) (bs .tail)drop-ap : ∀ n (fs : Stream (A → B)) as →drop n (ap fs as) ≡ ap (drop n fs) (drop n as)drop-ap zero fs as = refldrop-ap (suc n) fs as = drop-ap n (fs .tail) (as .tail)drop-iterate : ∀ n f (x : A) → drop n (iterate f x) ≡ iterate f (ℕ.iterate f x n)drop-iterate zero f x = refldrop-iterate (suc n) f x = drop-iterate n f (f x)-------------------------------------------------------------------------- Properties of zipWithzipWith-defn : ∀ (f : A → B → C) as bs →zipWith f as bs ≈ (repeat f ⟨ ap ⟩ as ⟨ ap ⟩ bs)zipWith-defn f as bs .head = reflzipWith-defn f as bs .tail = zipWith-defn f (as .tail) (bs .tail)zipWith-const : (as : Stream A) (bs : Stream B) →zipWith const as bs ≈ aszipWith-const as bs .head = reflzipWith-const as bs .tail = zipWith-const (as .tail) (bs .tail)zipWith-flip : ∀ (f : A → B → C) as bs →zipWith (flip f) as bs ≈ zipWith f bs aszipWith-flip f as bs .head = reflzipWith-flip f as bs .tail = zipWith-flip f (as .tail) (bs. tail)-------------------------------------------------------------------------- Properties of interleaveinterleave-evens-odds : (as : Stream A) → interleave (evens as) (odds as) ≈ asinterleave-evens-odds as .head = reflinterleave-evens-odds as .tail .head = reflinterleave-evens-odds as .tail .tail = interleave-evens-odds (as .tail .tail)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0map-identity = map-id{-# WARNING_ON_USAGE map-identity"Warning: map-identity was deprecated in v2.0.Please use map-id instead."#-}map-fusion = map-∘{-# WARNING_ON_USAGE map-fusion"Warning: map-fusion was deprecated in v2.0.Please use map-∘ instead."#-}drop-fusion = drop-drop{-# WARNING_ON_USAGE drop-fusion"Warning: drop-fusion was deprecated in v2.0.Please use drop-drop instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- M-types (the dual of W-types)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module Codata.Guarded.M whereopen import Levelopen import Data.Container.Core hiding (map; Shape; Position)open import Function.Baseopen import Data.Product.Base hiding (map)-- The family of M-typesrecord M {s p} (C : Container s p) : Set (s ⊔ p) wherecoinductiveconstructor infopen Container Cfieldhead : Shapetail : Position head → M Copen M public-- mapmodule _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}(f : C₁ ⇒ C₂) wheremap : M C₁ → M C₂map m .head = f .shape (m .head)map m .tail p = map (m .tail (f .position p))-- unfoldmodule _ {s p ℓ} {C : Container s p} (open Container C){S : Set ℓ} (alg : S → ⟦ C ⟧ S) whereunfold : S → M Cunfold seed .head = alg seed .proj₁unfold seed .tail p = unfold (alg seed .proj₂ p)
-------------------------------------------------------------------------- The Agda standard library---- Results concerning uniqueness of identity proofs------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Axiom.UniquenessOfIdentityProofs whereopen import Level using (Level)open import Relation.Nullary.Decidable.Core using (recompute; recompute-constant)open import Relation.Binary.Coreopen import Relation.Binary.Definitionsopen import Relation.Binary.PropositionalEquality.Coreopen import Relation.Binary.PropositionalEquality.Propertiesprivatevariablea : LevelA : Set ax y : A-------------------------------------------------------------------------- Definition---- Uniqueness of Identity Proofs (UIP) states that all proofs of-- equality are themselves equal. In other words, the equality relation-- is irrelevant. Here we define UIP relative to a given type.UIP : (A : Set a) → Set aUIP A = Irrelevant {A = A} _≡_-------------------------------------------------------------------------- Properties-- UIP always holds when using axiom K-- (see `Axiom.UniquenessOfIdentityProofs.WithK`).-- The existence of a constant function over proofs of equality for-- elements in A is enough to prove UIP for A. Indeed, we can relate any-- proof to its image via this function which we then know is equal to-- the image of any other proof.module Constant⇒UIP(f : _≡_ {A = A} ⇒ _≡_)(f-constant : ∀ {x y} (p q : x ≡ y) → f p ≡ f q)where≡-canonical : (p : x ≡ y) → trans (sym (f refl)) (f p) ≡ p≡-canonical refl = trans-symˡ (f refl)≡-irrelevant : UIP A≡-irrelevant p q = beginp ≡⟨ sym (≡-canonical p) ⟩trans (sym (f refl)) (f p) ≡⟨ cong (trans _) (f-constant p q) ⟩trans (sym (f refl)) (f q) ≡⟨ ≡-canonical q ⟩q ∎where open ≡-Reasoning-- If equality is decidable for a given type, then we can prove UIP for-- that type. Indeed, the decision procedure allows us to define a-- function over proofs of equality which is constant: it returns the-- proof produced by the decision procedure.module Decidable⇒UIP (_≟_ : DecidableEquality A)where≡-normalise : _≡_ {A = A} ⇒ _≡_≡-normalise {x} {y} x≡y = recompute (x ≟ y) x≡y≡-normalise-constant : (p q : x ≡ y) → ≡-normalise p ≡ ≡-normalise q≡-normalise-constant {x = x} {y = y} = recompute-constant (x ≟ y)≡-irrelevant : UIP A≡-irrelevant = Constant⇒UIP.≡-irrelevant ≡-normalise ≡-normalise-constant
-------------------------------------------------------------------------- The Agda standard library---- Results concerning uniqueness of identity proofs, with axiom K------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Axiom.UniquenessOfIdentityProofs.WithK whereopen import Axiom.UniquenessOfIdentityProofsopen import Relation.Binary.PropositionalEquality.Core-- Axiom K implies UIP.uip : ∀ {a} {A : Set a} → UIP Auip refl refl = refl
-------------------------------------------------------------------------- The Agda standard library---- Results concerning function extensionality for propositional equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Axiom.Extensionality.Propositional whereopen import Function.Baseopen import Level using (Level; _⊔_; suc; lift)open import Relation.Binary.Coreopen import Relation.Binary.PropositionalEquality.Core-------------------------------------------------------------------------- Function extensionality states that if two functions are-- propositionally equal for every input, then the functions themselves-- must be propositionally equal.Extensionality : (a b : Level) → Set _Extensionality a b ={A : Set a} {B : A → Set b} {f g : (x : A) → B x} →(∀ x → f x ≡ g x) → f ≡ g-- A variant for implicit function spaces.ExtensionalityImplicit : (a b : Level) → Set _ExtensionalityImplicit a b ={A : Set a} {B : A → Set b} {f g : {x : A} → B x} →(∀ {x} → f {x} ≡ g {x}) → (λ {x} → f {x}) ≡ (λ {x} → g {x})-------------------------------------------------------------------------- Properties-- If extensionality holds for a given universe level, then it also-- holds for lower ones.lower-extensionality : ∀ {a₁ b₁} a₂ b₂ →Extensionality (a₁ ⊔ a₂) (b₁ ⊔ b₂) →Extensionality a₁ b₁lower-extensionality a₂ b₂ ext f≡g = cong (λ h → Level.lower ∘ h ∘ lift) $ext (cong (lift {ℓ = b₂}) ∘ f≡g ∘ Level.lower {ℓ = a₂})-- Functional extensionality implies a form of extensionality for-- Π-types.∀-extensionality : ∀ {a b} → Extensionality a (suc b) →{A : Set a} (B₁ B₂ : A → Set b) →(∀ x → B₁ x ≡ B₂ x) →(∀ x → B₁ x) ≡ (∀ x → B₂ x)∀-extensionality ext B₁ B₂ B₁≡B₂ with ext B₁≡B₂... | refl = refl-- Extensionality for explicit function spaces implies extensionality-- for implicit function spaces.implicit-extensionality : ∀ {a b} →Extensionality a b →ExtensionalityImplicit a bimplicit-extensionality ext f≡g = cong _$- (ext (λ x → f≡g))
-------------------------------------------------------------------------- The Agda standard library---- Results concerning function extensionality for propositional equality------------------------------------------------------------------------{-# OPTIONS --with-K --safe #-}module Axiom.Extensionality.Heterogeneous whereimport Axiom.Extensionality.Propositional as Popen import Function.Base using (_$_; _∘_)open import Levelopen import Relation.Binary.HeterogeneousEquality.Coreopen import Relation.Binary.PropositionalEquality.Core-------------------------------------------------------------------------- Function extensionality states that if two functions are-- propositionally equal for every input, then the functions themselves-- must be propositionally equal.Extensionality : (a b : Level) → Set _Extensionality a b ={A : Set a} {B₁ B₂ : A → Set b}{f₁ : (x : A) → B₁ x} {f₂ : (x : A) → B₂ x} →(∀ x → B₁ x ≡ B₂ x) → (∀ x → f₁ x ≅ f₂ x) → f₁ ≅ f₂-------------------------------------------------------------------------- Properties-- This form of extensionality follows from extensionality for _≡_.≡-ext⇒≅-ext : ∀ {ℓ₁ ℓ₂} →P.Extensionality ℓ₁ (suc ℓ₂) →Extensionality ℓ₁ ℓ₂≡-ext⇒≅-ext {ℓ₁} {ℓ₂} ext B₁≡B₂ f₁≅f₂ with ext B₁≡B₂... | refl = ≡-to-≅ $ ext′ (≅-to-≡ ∘ f₁≅f₂)whereext′ : P.Extensionality ℓ₁ ℓ₂ext′ = P.lower-extensionality ℓ₁ (suc ℓ₂) ext
-------------------------------------------------------------------------- The Agda standard library---- Results concerning the excluded middle axiom.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Axiom.ExcludedMiddle whereopen import Levelopen import Relation.Nullary-------------------------------------------------------------------------- Definition-- The classical statement of excluded middle says that every-- statement/set is decidable (i.e. it either holds or it doesn't hold).ExcludedMiddle : (ℓ : Level) → Set (suc ℓ)ExcludedMiddle ℓ = {P : Set ℓ} → Dec P
-------------------------------------------------------------------------- The Agda standard library---- Results concerning double negation elimination.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Axiom.DoubleNegationElimination whereopen import Axiom.ExcludedMiddleopen import Levelopen import Relation.Nullaryopen import Relation.Nullary.Negationopen import Relation.Nullary.Decidable-------------------------------------------------------------------------- Definition-- The classical statement of double negation elimination says that-- if a property is not not true then it is true.DoubleNegationElimination : (ℓ : Level) → Set (suc ℓ)DoubleNegationElimination ℓ = {P : Set ℓ} → ¬ ¬ P → P-------------------------------------------------------------------------- Properties-- Double negation elimination is equivalent to excluded middleem⇒dne : ∀ {ℓ} → ExcludedMiddle ℓ → DoubleNegationElimination ℓem⇒dne em = decidable-stable emdne⇒em : ∀ {ℓ} → DoubleNegationElimination ℓ → ExcludedMiddle ℓdne⇒em dne = dne ¬¬-excluded-middle
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structures like monoids and rings-- (packed in records together with sets, operations, etc.)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra whereopen import Algebra.Core publicopen import Algebra.Definitions publicopen import Algebra.Structures publicopen import Algebra.Structures.Biased publicopen import Algebra.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Some algebraic structures (not packed up with sets, operations, etc.)-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra`, unless-- you want to parameterise it via the equality relation.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Structures{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhere-- The file is divided into sections depending on the arities of the-- components of the algebraic structure.open import Algebra.Core using (Op₁; Op₂)open import Algebra.Definitions _≈_import Algebra.Consequences.Setoid as Consequencesopen import Data.Product.Base using (_,_; proj₁; proj₂)open import Level using (_⊔_)-------------------------------------------------------------------------- Structures with 1 unary operation & 1 element------------------------------------------------------------------------record IsSuccessorSet (suc# : Op₁ A) (zero# : A) : Set (a ⊔ ℓ) wherefieldisEquivalence : IsEquivalence _≈_suc#-cong : Congruent₁ suc#open IsEquivalence isEquivalence publicsetoid : Setoid a ℓsetoid = record { isEquivalence = isEquivalence }-------------------------------------------------------------------------- Structures with 1 binary operation------------------------------------------------------------------------record IsMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisEquivalence : IsEquivalence _≈_∙-cong : Congruent₂ ∙open IsEquivalence isEquivalence publicsetoid : Setoid a ℓsetoid = record { isEquivalence = isEquivalence }∙-congˡ : LeftCongruent ∙∙-congˡ y≈z = ∙-cong refl y≈z∙-congʳ : RightCongruent ∙∙-congʳ y≈z = ∙-cong y≈z reflrecord IsCommutativeMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙comm : Commutative ∙open IsMagma isMagma publicrecord IsIdempotentMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙idem : Idempotent ∙open IsMagma isMagma publicrecord IsAlternativeMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙alter : Alternative ∙open IsMagma isMagma publicalternativeˡ : LeftAlternative ∙alternativeˡ = proj₁ alteralternativeʳ : RightAlternative ∙alternativeʳ = proj₂ alterrecord IsFlexibleMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙flex : Flexible ∙open IsMagma isMagma publicrecord IsMedialMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙medial : Medial ∙open IsMagma isMagma publicrecord IsSemimedialMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙semiMedial : Semimedial ∙open IsMagma isMagma publicsemimedialˡ : LeftSemimedial ∙semimedialˡ = proj₁ semiMedialsemimedialʳ : RightSemimedial ∙semimedialʳ = proj₂ semiMedialrecord IsSelectiveMagma (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙sel : Selective ∙open IsMagma isMagma publicrecord IsSemigroup (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙assoc : Associative ∙open IsMagma isMagma publicrecord IsBand (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisSemigroup : IsSemigroup ∙idem : Idempotent ∙open IsSemigroup isSemigroup publicrecord IsCommutativeSemigroup (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisSemigroup : IsSemigroup ∙comm : Commutative ∙open IsSemigroup isSemigroup publicisCommutativeMagma : IsCommutativeMagma ∙isCommutativeMagma = record{ isMagma = isMagma; comm = comm}record IsCommutativeBand (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisBand : IsBand ∙comm : Commutative ∙open IsBand isBand publicisCommutativeSemigroup : IsCommutativeSemigroup ∙isCommutativeSemigroup = record { isSemigroup = isSemigroup ; comm = comm }open IsCommutativeSemigroup isCommutativeSemigroup publicusing (isCommutativeMagma)-------------------------------------------------------------------------- Structures with 1 binary operation & 1 element------------------------------------------------------------------------record IsUnitalMagma (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙identity : Identity ε ∙open IsMagma isMagma publicidentityˡ : LeftIdentity ε ∙identityˡ = proj₁ identityidentityʳ : RightIdentity ε ∙identityʳ = proj₂ identityrecord IsMonoid (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisSemigroup : IsSemigroup ∙identity : Identity ε ∙open IsSemigroup isSemigroup publicidentityˡ : LeftIdentity ε ∙identityˡ = proj₁ identityidentityʳ : RightIdentity ε ∙identityʳ = proj₂ identityisUnitalMagma : IsUnitalMagma ∙ εisUnitalMagma = record{ isMagma = isMagma; identity = identity}record IsCommutativeMonoid (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisMonoid : IsMonoid ∙ εcomm : Commutative ∙open IsMonoid isMonoid publicisCommutativeSemigroup : IsCommutativeSemigroup ∙isCommutativeSemigroup = record{ isSemigroup = isSemigroup; comm = comm}open IsCommutativeSemigroup isCommutativeSemigroup publicusing (isCommutativeMagma)record IsIdempotentMonoid (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisMonoid : IsMonoid ∙ εidem : Idempotent ∙open IsMonoid isMonoid publicisBand : IsBand ∙isBand = record { isSemigroup = isSemigroup ; idem = idem }record IsIdempotentCommutativeMonoid (∙ : Op₂ A)(ε : A) : Set (a ⊔ ℓ) wherefieldisCommutativeMonoid : IsCommutativeMonoid ∙ εidem : Idempotent ∙open IsCommutativeMonoid isCommutativeMonoid publicisIdempotentMonoid : IsIdempotentMonoid ∙ εisIdempotentMonoid = record { isMonoid = isMonoid ; idem = idem }open IsIdempotentMonoid isIdempotentMonoid publicusing (isBand)isCommutativeBand : IsCommutativeBand ∙isCommutativeBand = record { isBand = isBand ; comm = comm }-------------------------------------------------------------------------- Structures with 1 binary operation, 1 unary operation & 1 element------------------------------------------------------------------------record IsInvertibleMagma (_∙_ : Op₂ A) (ε : A) (_⁻¹ : Op₁ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma _∙_inverse : Inverse ε _⁻¹ _∙_⁻¹-cong : Congruent₁ _⁻¹open IsMagma isMagma publicinverseˡ : LeftInverse ε _⁻¹ _∙_inverseˡ = proj₁ inverseinverseʳ : RightInverse ε _⁻¹ _∙_inverseʳ = proj₂ inverserecord IsInvertibleUnitalMagma (_∙_ : Op₂ A) (ε : A) (⁻¹ : Op₁ A) : Set (a ⊔ ℓ) wherefieldisInvertibleMagma : IsInvertibleMagma _∙_ ε ⁻¹identity : Identity ε _∙_open IsInvertibleMagma isInvertibleMagma publicidentityˡ : LeftIdentity ε _∙_identityˡ = proj₁ identityidentityʳ : RightIdentity ε _∙_identityʳ = proj₂ identityisUnitalMagma : IsUnitalMagma _∙_ εisUnitalMagma = record{ isMagma = isMagma; identity = identity}record IsGroup (_∙_ : Op₂ A) (ε : A) (_⁻¹ : Op₁ A) : Set (a ⊔ ℓ) wherefieldisMonoid : IsMonoid _∙_ εinverse : Inverse ε _⁻¹ _∙_⁻¹-cong : Congruent₁ _⁻¹open IsMonoid isMonoid publicinfixr 6 _\\__\\_ : Op₂ Ax \\ y = (x ⁻¹) ∙ yinfixl 6 _//__//_ : Op₂ Ax // y = x ∙ (y ⁻¹)-- Deprecated.infixl 6 _-__-_ : Op₂ A_-_ = _//_{-# WARNING_ON_USAGE _-_"Warning: _-_ was deprecated in v2.1.Please use _//_ instead. "#-}inverseˡ : LeftInverse ε _⁻¹ _∙_inverseˡ = proj₁ inverseinverseʳ : RightInverse ε _⁻¹ _∙_inverseʳ = proj₂ inverseuniqueˡ-⁻¹ : ∀ x y → (x ∙ y) ≈ ε → x ≈ (y ⁻¹)uniqueˡ-⁻¹ = Consequences.assoc∧id∧invʳ⇒invˡ-uniquesetoid ∙-cong assoc identity inverseʳuniqueʳ-⁻¹ : ∀ x y → (x ∙ y) ≈ ε → y ≈ (x ⁻¹)uniqueʳ-⁻¹ = Consequences.assoc∧id∧invˡ⇒invʳ-uniquesetoid ∙-cong assoc identity inverseˡisInvertibleMagma : IsInvertibleMagma _∙_ ε _⁻¹isInvertibleMagma = record{ isMagma = isMagma; inverse = inverse; ⁻¹-cong = ⁻¹-cong}isInvertibleUnitalMagma : IsInvertibleUnitalMagma _∙_ ε _⁻¹isInvertibleUnitalMagma = record{ isInvertibleMagma = isInvertibleMagma; identity = identity}record IsAbelianGroup (∙ : Op₂ A)(ε : A) (⁻¹ : Op₁ A) : Set (a ⊔ ℓ) wherefieldisGroup : IsGroup ∙ ε ⁻¹comm : Commutative ∙open IsGroup isGroup public renaming (_//_ to _-_) hiding (_\\_; _-_)isCommutativeMonoid : IsCommutativeMonoid ∙ εisCommutativeMonoid = record{ isMonoid = isMonoid; comm = comm}open IsCommutativeMonoid isCommutativeMonoid publicusing (isCommutativeMagma; isCommutativeSemigroup)-------------------------------------------------------------------------- Structures with 2 binary operations & 1 element------------------------------------------------------------------------record IsNearSemiring (+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) wherefield+-isMonoid : IsMonoid + 0#*-cong : Congruent₂ **-assoc : Associative *distribʳ : * DistributesOverʳ +zeroˡ : LeftZero 0# *open IsMonoid +-isMonoid publicrenaming( assoc to +-assoc; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; isMagma to +-isMagma; isUnitalMagma to +-isUnitalMagma; isSemigroup to +-isSemigroup)*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup **-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}open IsMagma *-isMagma publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ)record IsSemiringWithoutOne (+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) wherefield+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-cong : Congruent₂ **-assoc : Associative *distrib : * DistributesOver +zero : Zero 0# *open IsCommutativeMonoid +-isCommutativeMonoid publicusing (setoid)renaming( comm to +-comm; isMonoid to +-isMonoid; isCommutativeMagma to +-isCommutativeMagma; isCommutativeSemigroup to +-isCommutativeSemigroup)open Setoid setoid public*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup **-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}open IsMagma *-isMagma publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ)zeroˡ : LeftZero 0# *zeroˡ = proj₁ zerozeroʳ : RightZero 0# *zeroʳ = proj₂ zeroisNearSemiring : IsNearSemiring + * 0#isNearSemiring = record{ +-isMonoid = +-isMonoid; *-cong = *-cong; *-assoc = *-assoc; distribʳ = proj₂ distrib; zeroˡ = zeroˡ}record IsCommutativeSemiringWithoutOne(+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) wherefieldisSemiringWithoutOne : IsSemiringWithoutOne + * 0#*-comm : Commutative *open IsSemiringWithoutOne isSemiringWithoutOne public*-isCommutativeSemigroup : IsCommutativeSemigroup **-isCommutativeSemigroup = record{ isSemigroup = *-isSemigroup; comm = *-comm}open IsCommutativeSemigroup *-isCommutativeSemigroup publicusing () renaming (isCommutativeMagma to *-isCommutativeMagma)-------------------------------------------------------------------------- Structures with 2 binary operations & 2 elements------------------------------------------------------------------------record IsSemiringWithoutAnnihilatingZero (+ * : Op₂ A)(0# 1# : A) : Set (a ⊔ ℓ) wherefield-- Note that these structures do have an additive unit, but this-- unit does not necessarily annihilate multiplication.+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-cong : Congruent₂ **-assoc : Associative **-identity : Identity 1# *distrib : * DistributesOver +distribˡ : * DistributesOverˡ +distribˡ = proj₁ distribdistribʳ : * DistributesOverʳ +distribʳ = proj₂ distribopen IsCommutativeMonoid +-isCommutativeMonoid publicrenaming( assoc to +-assoc; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; comm to +-comm; isMagma to +-isMagma; isSemigroup to +-isSemigroup; isMonoid to +-isMonoid; isUnitalMagma to +-isUnitalMagma; isCommutativeMagma to +-isCommutativeMagma; isCommutativeSemigroup to +-isCommutativeSemigroup)*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup **-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-isMonoid : IsMonoid * 1#*-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}open IsMonoid *-isMonoid publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ; identityˡ to *-identityˡ; identityʳ to *-identityʳ)record IsSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisSemiringWithoutAnnihilatingZero :IsSemiringWithoutAnnihilatingZero + * 0# 1#zero : Zero 0# *open IsSemiringWithoutAnnihilatingZeroisSemiringWithoutAnnihilatingZero publicisSemiringWithoutOne : IsSemiringWithoutOne + * 0#isSemiringWithoutOne = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = *-cong; *-assoc = *-assoc; distrib = distrib; zero = zero}open IsSemiringWithoutOne isSemiringWithoutOne publicusing( isNearSemiring; zeroˡ; zeroʳ)record IsCommutativeSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisSemiring : IsSemiring + * 0# 1#*-comm : Commutative *open IsSemiring isSemiring publicisCommutativeSemiringWithoutOne :IsCommutativeSemiringWithoutOne + * 0#isCommutativeSemiringWithoutOne = record{ isSemiringWithoutOne = isSemiringWithoutOne; *-comm = *-comm}open IsCommutativeSemiringWithoutOne isCommutativeSemiringWithoutOne publicusing( *-isCommutativeMagma; *-isCommutativeSemigroup)*-isCommutativeMonoid : IsCommutativeMonoid * 1#*-isCommutativeMonoid = record{ isMonoid = *-isMonoid; comm = *-comm}record IsCancellativeCommutativeSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisCommutativeSemiring : IsCommutativeSemiring + * 0# 1#*-cancelˡ-nonZero : AlmostLeftCancellative 0# *open IsCommutativeSemiring isCommutativeSemiring public*-cancelʳ-nonZero : AlmostRightCancellative 0# **-cancelʳ-nonZero = Consequences.comm∧almostCancelˡ⇒almostCancelʳ setoid*-comm *-cancelˡ-nonZerorecord IsIdempotentSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisSemiring : IsSemiring + * 0# 1#+-idem : Idempotent +open IsSemiring isSemiring public+-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid + 0#+-isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = +-isCommutativeMonoid; idem = +-idem}open IsIdempotentCommutativeMonoid +-isIdempotentCommutativeMonoid publicusing ()renaming ( isCommutativeBand to +-isCommutativeBand; isBand to +-isBand; isIdempotentMonoid to +-isIdempotentMonoid)record IsKleeneAlgebra (+ * : Op₂ A) (⋆ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisIdempotentSemiring : IsIdempotentSemiring + * 0# 1#starExpansive : StarExpansive 1# + * ⋆starDestructive : StarDestructive + * ⋆open IsIdempotentSemiring isIdempotentSemiring publicstarExpansiveˡ : StarLeftExpansive 1# + * ⋆starExpansiveˡ = proj₁ starExpansivestarExpansiveʳ : StarRightExpansive 1# + * ⋆starExpansiveʳ = proj₂ starExpansivestarDestructiveˡ : StarLeftDestructive + * ⋆starDestructiveˡ = proj₁ starDestructivestarDestructiveʳ : StarRightDestructive + * ⋆starDestructiveʳ = proj₂ starDestructiverecord IsQuasiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isMonoid : IsMonoid + 0#*-cong : Congruent₂ **-assoc : Associative **-identity : Identity 1# *distrib : * DistributesOver +zero : Zero 0# *open IsMonoid +-isMonoid publicrenaming( assoc to +-assoc; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; isMagma to +-isMagma; isUnitalMagma to +-isUnitalMagma; isSemigroup to +-isSemigroup)distribˡ : * DistributesOverˡ +distribˡ = proj₁ distribdistribʳ : * DistributesOverʳ +distribʳ = proj₂ distribzeroˡ : LeftZero 0# *zeroˡ = proj₁ zerozeroʳ : RightZero 0# *zeroʳ = proj₂ zeroidentityˡ : LeftIdentity 1# *identityˡ = proj₁ *-identityidentityʳ : RightIdentity 1# *identityʳ = proj₂ *-identity*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup **-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}*-isMonoid : IsMonoid * 1#*-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}open IsMonoid *-isMonoid publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ; identityˡ to *-identityˡ; identityʳ to *-identityʳ)-------------------------------------------------------------------------- Structures with 2 binary operations, 1 unary operation & 1 element------------------------------------------------------------------------record IsRingWithoutOne (+ * : Op₂ A) (-_ : Op₁ A) (0# : A) : Set (a ⊔ ℓ) wherefield+-isAbelianGroup : IsAbelianGroup + 0# -_*-cong : Congruent₂ **-assoc : Associative *distrib : * DistributesOver +open IsAbelianGroup +-isAbelianGroup publicrenaming( assoc to +-assoc; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; inverse to -‿inverse; inverseˡ to -‿inverseˡ; inverseʳ to -‿inverseʳ; ⁻¹-cong to -‿cong; comm to +-comm; isMagma to +-isMagma; isSemigroup to +-isSemigroup; isMonoid to +-isMonoid; isUnitalMagma to +-isUnitalMagma; isCommutativeMagma to +-isCommutativeMagma; isCommutativeMonoid to +-isCommutativeMonoid; isCommutativeSemigroup to +-isCommutativeSemigroup; isInvertibleMagma to +-isInvertibleMagma; isInvertibleUnitalMagma to +-isInvertibleUnitalMagma; isGroup to +-isGroup)distribˡ : * DistributesOverˡ +distribˡ = proj₁ distribdistribʳ : * DistributesOverʳ +distribʳ = proj₂ distribzeroˡ : LeftZero 0# *zeroˡ = Consequences.assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ setoid+-cong *-cong +-assoc distribʳ +-identityʳ -‿inverseʳzeroʳ : RightZero 0# *zeroʳ = Consequences.assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ setoid+-cong *-cong +-assoc distribˡ +-identityʳ -‿inverseʳzero : Zero 0# *zero = zeroˡ , zeroʳ*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-isSemigroup : IsSemigroup **-isSemigroup = record{ isMagma = *-isMagma; assoc = *-assoc}open IsSemigroup *-isSemigroup publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ)-------------------------------------------------------------------------- Structures with 2 binary operations, 1 unary operation & 2 elements------------------------------------------------------------------------record IsNonAssociativeRing (+ * : Op₂ A) (-_ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isAbelianGroup : IsAbelianGroup + 0# -_*-cong : Congruent₂ **-identity : Identity 1# *distrib : * DistributesOver +zero : Zero 0# *open IsAbelianGroup +-isAbelianGroup publicrenaming( assoc to +-assoc; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; inverse to -‿inverse; inverseˡ to -‿inverseˡ; inverseʳ to -‿inverseʳ; ⁻¹-cong to -‿cong; comm to +-comm; isMagma to +-isMagma; isSemigroup to +-isSemigroup; isMonoid to +-isMonoid; isUnitalMagma to +-isUnitalMagma; isCommutativeMagma to +-isCommutativeMagma; isCommutativeMonoid to +-isCommutativeMonoid; isCommutativeSemigroup to +-isCommutativeSemigroup; isInvertibleMagma to +-isInvertibleMagma; isInvertibleUnitalMagma to +-isInvertibleUnitalMagma; isGroup to +-isGroup)zeroˡ : LeftZero 0# *zeroˡ = proj₁ zerozeroʳ : RightZero 0# *zeroʳ = proj₂ zerodistribˡ : * DistributesOverˡ +distribˡ = proj₁ distribdistribʳ : * DistributesOverʳ +distribʳ = proj₂ distrib*-isMagma : IsMagma **-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = *-cong}*-identityˡ : LeftIdentity 1# **-identityˡ = proj₁ *-identity*-identityʳ : RightIdentity 1# **-identityʳ = proj₂ *-identity*-isUnitalMagma : IsUnitalMagma * 1#*-isUnitalMagma = record{ isMagma = *-isMagma; identity = *-identity}open IsUnitalMagma *-isUnitalMagma publicusing ()renaming( ∙-congˡ to *-congˡ; ∙-congʳ to *-congʳ)record IsNearring (+ * : Op₂ A) (0# 1# : A) (_⁻¹ : Op₁ A) : Set (a ⊔ ℓ) wherefieldisQuasiring : IsQuasiring + * 0# 1#+-inverse : Inverse 0# _⁻¹ +⁻¹-cong : Congruent₁ _⁻¹open IsQuasiring isQuasiring public+-inverseˡ : LeftInverse 0# _⁻¹ ++-inverseˡ = proj₁ +-inverse+-inverseʳ : RightInverse 0# _⁻¹ ++-inverseʳ = proj₂ +-inverserecord IsRing (+ * : Op₂ A) (-_ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isAbelianGroup : IsAbelianGroup + 0# -_*-cong : Congruent₂ **-assoc : Associative **-identity : Identity 1# *distrib : * DistributesOver +isRingWithoutOne : IsRingWithoutOne + * -_ 0#isRingWithoutOne = record{ +-isAbelianGroup = +-isAbelianGroup; *-cong = *-cong; *-assoc = *-assoc; distrib = distrib}open IsRingWithoutOne isRingWithoutOne publichiding (+-isAbelianGroup; *-cong; *-assoc; distrib)*-isMonoid : IsMonoid * 1#*-isMonoid = record{ isSemigroup = *-isSemigroup; identity = *-identity}open IsMonoid *-isMonoid publicusing ()renaming( identityˡ to *-identityˡ; identityʳ to *-identityʳ)isSemiringWithoutAnnihilatingZero: IsSemiringWithoutAnnihilatingZero + * 0# 1#isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = *-cong; *-assoc = *-assoc; *-identity = *-identity; distrib = distrib}isSemiring : IsSemiring + * 0# 1#isSemiring = record{ isSemiringWithoutAnnihilatingZero =isSemiringWithoutAnnihilatingZero; zero = zero}open IsSemiring isSemiring publicusing (isNearSemiring; isSemiringWithoutOne)record IsCommutativeRing(+ * : Op₂ A) (- : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefieldisRing : IsRing + * - 0# 1#*-comm : Commutative *open IsRing isRing publicisCommutativeSemiring : IsCommutativeSemiring + * 0# 1#isCommutativeSemiring = record{ isSemiring = isSemiring; *-comm = *-comm}open IsCommutativeSemiring isCommutativeSemiring publicusing( isCommutativeSemiringWithoutOne; *-isCommutativeMagma; *-isCommutativeSemigroup; *-isCommutativeMonoid)-------------------------------------------------------------------------- Structures with 3 binary operations------------------------------------------------------------------------record IsQuasigroup (∙ \\ // : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ∙\\-cong : Congruent₂ \\//-cong : Congruent₂ //leftDivides : LeftDivides ∙ \\rightDivides : RightDivides ∙ //open IsMagma isMagma public\\-congˡ : LeftCongruent \\\\-congˡ y≈z = \\-cong refl y≈z\\-congʳ : RightCongruent \\\\-congʳ y≈z = \\-cong y≈z refl//-congˡ : LeftCongruent ////-congˡ y≈z = //-cong refl y≈z//-congʳ : RightCongruent ////-congʳ y≈z = //-cong y≈z reflleftDividesˡ : LeftDividesˡ ∙ \\leftDividesˡ = proj₁ leftDividesleftDividesʳ : LeftDividesʳ ∙ \\leftDividesʳ = proj₂ leftDividesrightDividesˡ : RightDividesˡ ∙ //rightDividesˡ = proj₁ rightDividesrightDividesʳ : RightDividesʳ ∙ //rightDividesʳ = proj₂ rightDividesrecord IsLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisQuasigroup : IsQuasigroup ∙ \\ //identity : Identity ε ∙open IsQuasigroup isQuasigroup publicidentityˡ : LeftIdentity ε ∙identityˡ = proj₁ identityidentityʳ : RightIdentity ε ∙identityʳ = proj₂ identityrecord IsLeftBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisLoop : IsLoop ∙ \\ // εleftBol : LeftBol ∙open IsLoop isLoop publicrecord IsRightBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisLoop : IsLoop ∙ \\ // εrightBol : RightBol ∙open IsLoop isLoop publicrecord IsMoufangLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisLeftBolLoop : IsLeftBolLoop ∙ \\ // εrightBol : RightBol ∙identical : Identical ∙open IsLeftBolLoop isLeftBolLoop publicrecord IsMiddleBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisLoop : IsLoop ∙ \\ // εmiddleBol : MiddleBol ∙ \\ //open IsLoop isLoop public
-------------------------------------------------------------------------- The Agda standard library---- Ways to give instances of certain structures where some fields can-- be given in terms of others. Re-exported via `Algebra`.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Consequences.Setoidopen import Data.Product.Base using (_,_; proj₁; proj₂)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Structures.Biased{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhereopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_-------------------------------------------------------------------------- IsCommutativeMonoidrecord IsCommutativeMonoidˡ (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisSemigroup : IsSemigroup ∙identityˡ : LeftIdentity ε ∙comm : Commutative ∙isCommutativeMonoid : IsCommutativeMonoid ∙ εisCommutativeMonoid = record{ isMonoid = record{ isSemigroup = isSemigroup; identity = comm∧idˡ⇒id setoid comm identityˡ}; comm = comm} where open IsSemigroup isSemigroupopen IsCommutativeMonoidˡ publicusing () renaming (isCommutativeMonoid to isCommutativeMonoidˡ)record IsCommutativeMonoidʳ (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) wherefieldisSemigroup : IsSemigroup ∙identityʳ : RightIdentity ε ∙comm : Commutative ∙isCommutativeMonoid : IsCommutativeMonoid ∙ εisCommutativeMonoid = record{ isMonoid = record{ isSemigroup = isSemigroup; identity = comm∧idʳ⇒id setoid comm identityʳ}; comm = comm} where open IsSemigroup isSemigroupopen IsCommutativeMonoidʳ publicusing () renaming (isCommutativeMonoid to isCommutativeMonoidʳ)-------------------------------------------------------------------------- IsSemiringWithoutOnerecord IsSemiringWithoutOne* (+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) wherefield+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-isSemigroup : IsSemigroup *distrib : * DistributesOver +zero : Zero 0# *isSemiringWithoutOne : IsSemiringWithoutOne + * 0#isSemiringWithoutOne = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = ∙-cong; *-assoc = assoc; distrib = distrib; zero = zero} where open IsSemigroup *-isSemigroupopen IsSemiringWithoutOne* publicusing () renaming (isSemiringWithoutOne to isSemiringWithoutOne*)-------------------------------------------------------------------------- IsNearSemiringrecord IsNearSemiring* (+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) wherefield+-isMonoid : IsMonoid + 0#*-isSemigroup : IsSemigroup *distribʳ : * DistributesOverʳ +zeroˡ : LeftZero 0# *isNearSemiring : IsNearSemiring + * 0#isNearSemiring = record{ +-isMonoid = +-isMonoid; *-cong = ∙-cong; *-assoc = assoc; distribʳ = distribʳ; zeroˡ = zeroˡ} where open IsSemigroup *-isSemigroupopen IsNearSemiring* publicusing () renaming (isNearSemiring to isNearSemiring*)-------------------------------------------------------------------------- IsSemiringWithoutAnnihilatingZerorecord IsSemiringWithoutAnnihilatingZero* (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-isMonoid : IsMonoid * 1#distrib : * DistributesOver +isSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero + * 0# 1#isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = ∙-cong; *-assoc = assoc; *-identity = identity; distrib = distrib} where open IsMonoid *-isMonoidopen IsSemiringWithoutAnnihilatingZero* publicusing () renaming (isSemiringWithoutAnnihilatingZero to isSemiringWithoutAnnihilatingZero*)-------------------------------------------------------------------------- IsCommutativeSemiringrecord IsCommutativeSemiringˡ (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-isCommutativeMonoid : IsCommutativeMonoid * 1#distribʳ : * DistributesOverʳ +zeroˡ : LeftZero 0# *isCommutativeSemiring : IsCommutativeSemiring + * 0# 1#isCommutativeSemiring = record{ isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = *.∙-cong; *-assoc = *.assoc; *-identity = *.identity; distrib = comm∧distrʳ⇒distr +.setoid +.∙-cong *.comm distribʳ}; zero = comm∧zeˡ⇒ze +.setoid *.comm zeroˡ}; *-comm = *.comm}wheremodule + = IsCommutativeMonoid +-isCommutativeMonoidmodule * = IsCommutativeMonoid *-isCommutativeMonoidopen IsCommutativeSemiringˡ publicusing () renaming (isCommutativeSemiring to isCommutativeSemiringˡ)record IsCommutativeSemiringʳ (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isCommutativeMonoid : IsCommutativeMonoid + 0#*-isCommutativeMonoid : IsCommutativeMonoid * 1#distribˡ : * DistributesOverˡ +zeroʳ : RightZero 0# *isCommutativeSemiring : IsCommutativeSemiring + * 0# 1#isCommutativeSemiring = record{ isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = +-isCommutativeMonoid; *-cong = *.∙-cong; *-assoc = *.assoc; *-identity = *.identity; distrib = comm∧distrˡ⇒distr +.setoid +.∙-cong *.comm distribˡ}; zero = comm∧zeʳ⇒ze +.setoid *.comm zeroʳ}; *-comm = *.comm}wheremodule + = IsCommutativeMonoid +-isCommutativeMonoidmodule * = IsCommutativeMonoid *-isCommutativeMonoidopen IsCommutativeSemiringʳ publicusing () renaming (isCommutativeSemiring to isCommutativeSemiringʳ)-------------------------------------------------------------------------- IsRingrecord IsRing* (+ * : Op₂ A) (-_ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ) wherefield+-isAbelianGroup : IsAbelianGroup + 0# -_*-isMonoid : IsMonoid * 1#distrib : * DistributesOver +zero : Zero 0# *isRing : IsRing + * -_ 0# 1#isRing = record{ +-isAbelianGroup = +-isAbelianGroup; *-cong = ∙-cong; *-assoc = assoc; *-identity = identity; distrib = distrib} where open IsMonoid *-isMonoidopen IsRing* publicusing () renaming (isRing to isRing*)-------------------------------------------------------------------------- Deprecated-------------------------------------------------------------------------- Version 2.0-- We can recover a ring without proving that 0# annihilates *.record IsRingWithoutAnnihilatingZero (+ * : Op₂ A) (-_ : Op₁ A) (0# 1# : A): Set (a ⊔ ℓ) wherefield+-isAbelianGroup : IsAbelianGroup + 0# -_*-isMonoid : IsMonoid * 1#distrib : * DistributesOver +module + = IsAbelianGroup +-isAbelianGroupmodule * = IsMonoid *-isMonoidopen + using (setoid) renaming (∙-cong to +-cong)open * using () renaming (∙-cong to *-cong)zeroˡ : LeftZero 0# *zeroˡ = assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ setoid+-cong *-cong +.assoc (proj₂ distrib) +.identityʳ +.inverseʳzeroʳ : RightZero 0# *zeroʳ = assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ setoid+-cong *-cong +.assoc (proj₁ distrib) +.identityʳ +.inverseʳzero : Zero 0# *zero = (zeroˡ , zeroʳ)isRing : IsRing + * -_ 0# 1#isRing = record{ +-isAbelianGroup = +-isAbelianGroup; *-cong = *.∙-cong; *-assoc = *.assoc; *-identity = *.identity; distrib = distrib}open IsRingWithoutAnnihilatingZero publicusing () renaming (isRing to isRingWithoutAnnihilatingZero){-# WARNING_ON_USAGE IsRingWithoutAnnihilatingZero"Warning: IsRingWithoutAnnihilatingZero was deprecated in v2.0.Please use the standard `IsRing` instead."#-}{-# WARNING_ON_USAGE isRingWithoutAnnihilatingZero"Warning: isRingWithoutAnnihilatingZero was deprecated in v2.0.Please use the standard `isRing` instead."#-}-- Version 2.1-- issue #2253{-# WARNING_ON_USAGE IsRing*"Warning: IsRing* was deprecated in v2.1.Please use the standard `IsRing` instead."#-}{-# WARNING_ON_USAGE isRing*"Warning: isRing* was deprecated in v2.1.Please use the standard `isRing` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Old solver for commutative ring or semiring equalities-------------------------------------------------------------------------- Uses ideas from the Coq ring tactic. See "Proving Equalities in a-- Commutative Ring Done Right in Coq" by Grégoire and Mahboubi. The-- code below is not optimised like theirs, though (in particular, our-- Horner normal forms are not sparse).---- At first the `WeaklyDecidable` type may at first glance look useless-- as there is no guarantee that it doesn't always return `nothing`.-- However the implementation of it affects the power of the solver. The-- more equalities it returns, the more expressions the ring solver can-- solve.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesopen import Algebra.Solver.Ring.AlmostCommutativeRingopen import Relation.Binary.Definitions using (WeaklyDecidable)module Algebra.Solver.Ring{r₁ r₂ r₃ r₄}(Coeff : RawRing r₁ r₄) -- Coefficient "ring".(R : AlmostCommutativeRing r₂ r₃) -- Main "ring".(morphism : Coeff -Raw-AlmostCommutative⟶ R)(_coeff≟_ : WeaklyDecidable (Induced-equivalence morphism))whereopen import Algebra.Coreopen import Algebra.Solver.Ring.Lemmas Coeff R morphismprivate module C = RawRing Coeffopen AlmostCommutativeRing Rrenaming (zero to *-zero; zeroˡ to *-zeroˡ; zeroʳ to *-zeroʳ)open import Algebra.Definitions _≈_open import Algebra.Morphismopen _-Raw-AlmostCommutative⟶_ morphism renaming (⟦_⟧ to ⟦_⟧′)open import Algebra.Properties.Semiring.Exp semiringopen import Relation.Nullary.Decidable using (yes; no)open import Relation.Binary.Reasoning.Setoid setoidimport Relation.Binary.PropositionalEquality.Core as ≡import Relation.Binary.Reflection as Reflectionopen import Data.Nat.Base using (ℕ; suc; zero)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Vec.Base using (Vec; []; _∷_; lookup)open import Data.Maybe.Base using (just; nothing)open import Function.Base using (_⟨_⟩_; _$_)open import Level using (_⊔_)infix 9 :-_ -H_ -N_infixr 9 _:×_ _:^_ _^N_infix 8 _*x+_ _*x+HN_ _*x+H_infixl 8 _:*_ _*N_ _*H_ _*NH_ _*HN_infixl 7 _:+_ _:-_ _+H_ _+N_infix 4 _≈H_ _≈N_-------------------------------------------------------------------------- Polynomialsdata Op : Set where[+] : Op[*] : Op-- The polynomials are indexed by the number of variables.data Polynomial (m : ℕ) : Set r₁ whereop : (o : Op) (p₁ : Polynomial m) (p₂ : Polynomial m) → Polynomial mcon : (c : C.Carrier) → Polynomial mvar : (x : Fin m) → Polynomial m_:^_ : (p : Polynomial m) (n : ℕ) → Polynomial m:-_ : (p : Polynomial m) → Polynomial m-- Short-hand notation._:+_ : ∀ {n} → Polynomial n → Polynomial n → Polynomial n_:+_ = op [+]_:*_ : ∀ {n} → Polynomial n → Polynomial n → Polynomial n_:*_ = op [*]_:-_ : ∀ {n} → Polynomial n → Polynomial n → Polynomial nx :- y = x :+ :- y_:×_ : ∀ {n} → ℕ → Polynomial n → Polynomial nzero :× p = con C.0#suc m :× p = p :+ m :× p-- Semantics.sem : Op → Op₂ Carriersem [+] = _+_sem [*] = _*_⟦_⟧ : ∀ {n} → Polynomial n → Vec Carrier n → Carrier⟦ op o p₁ p₂ ⟧ ρ = ⟦ p₁ ⟧ ρ ⟨ sem o ⟩ ⟦ p₂ ⟧ ρ⟦ con c ⟧ ρ = ⟦ c ⟧′⟦ var x ⟧ ρ = lookup ρ x⟦ p :^ n ⟧ ρ = ⟦ p ⟧ ρ ^ n⟦ :- p ⟧ ρ = - ⟦ p ⟧ ρ-------------------------------------------------------------------------- Normal forms of polynomials-- A univariate polynomial of degree d,---- p = a_d x^d + a_{d-1}x^{d-1} + … + a_0,---- is represented in Horner normal form by---- p = ((a_d x + a_{d-1})x + …)x + a_0.---- Note that Horner normal forms can be represented as lists, with the-- empty list standing for the zero polynomial of degree "-1".---- Given this representation of univariate polynomials over an-- arbitrary ring, polynomials in any number of variables over the-- ring C can be represented via the isomorphisms---- C[] ≅ C---- and---- C[X_0,...X_{n+1}] ≅ C[X_0,...,X_n][X_{n+1}].mutual-- The polynomial representations are indexed by the polynomial's-- degree.data HNF : ℕ → Set r₁ where∅ : ∀ {n} → HNF (suc n)_*x+_ : ∀ {n} → HNF (suc n) → Normal n → HNF (suc n)data Normal : ℕ → Set r₁ wherecon : C.Carrier → Normal zeropoly : ∀ {n} → HNF (suc n) → Normal (suc n)-- Note that the data types above do /not/ ensure uniqueness of-- normal forms: the zero polynomial of degree one can be-- represented using both ∅ and ∅ *x+ con C.0#.mutual-- Semantics.⟦_⟧H : ∀ {n} → HNF (suc n) → Vec Carrier (suc n) → Carrier⟦ ∅ ⟧H _ = 0#⟦ p *x+ c ⟧H (x ∷ ρ) = ⟦ p ⟧H (x ∷ ρ) * x + ⟦ c ⟧N ρ⟦_⟧N : ∀ {n} → Normal n → Vec Carrier n → Carrier⟦ con c ⟧N _ = ⟦ c ⟧′⟦ poly p ⟧N ρ = ⟦ p ⟧H ρ-------------------------------------------------------------------------- Equality and decidabilitymutual-- Equality.data _≈H_ : ∀ {n} → HNF n → HNF n → Set (r₁ ⊔ r₃) where∅ : ∀ {n} → _≈H_ {suc n} ∅ ∅_*x+_ : ∀ {n} {p₁ p₂ : HNF (suc n)} {c₁ c₂ : Normal n} →p₁ ≈H p₂ → c₁ ≈N c₂ → (p₁ *x+ c₁) ≈H (p₂ *x+ c₂)data _≈N_ : ∀ {n} → Normal n → Normal n → Set (r₁ ⊔ r₃) wherecon : ∀ {c₁ c₂} → ⟦ c₁ ⟧′ ≈ ⟦ c₂ ⟧′ → con c₁ ≈N con c₂poly : ∀ {n} {p₁ p₂ : HNF (suc n)} → p₁ ≈H p₂ → poly p₁ ≈N poly p₂mutual-- Equality is weakly decidable.infix 4 _≟H_ _≟N__≟H_ : ∀ {n} → WeaklyDecidable (_≈H_ {n = n})∅ ≟H ∅ = just ∅∅ ≟H (_ *x+ _) = nothing(_ *x+ _) ≟H ∅ = nothing(p₁ *x+ c₁) ≟H (p₂ *x+ c₂) with p₁ ≟H p₂ | c₁ ≟N c₂... | just p₁≈p₂ | just c₁≈c₂ = just (p₁≈p₂ *x+ c₁≈c₂)... | _ | nothing = nothing... | nothing | _ = nothing_≟N_ : ∀ {n} → WeaklyDecidable (_≈N_ {n = n})con c₁ ≟N con c₂ with c₁ coeff≟ c₂... | just c₁≈c₂ = just (con c₁≈c₂)... | nothing = nothingpoly p₁ ≟N poly p₂ with p₁ ≟H p₂... | just p₁≈p₂ = just (poly p₁≈p₂)... | nothing = nothingmutual-- The semantics respect the equality relations defined above.⟦_⟧H-cong : ∀ {n} {p₁ p₂ : HNF (suc n)} →p₁ ≈H p₂ → ∀ ρ → ⟦ p₁ ⟧H ρ ≈ ⟦ p₂ ⟧H ρ⟦ ∅ ⟧H-cong _ = refl⟦ p₁≈p₂ *x+ c₁≈c₂ ⟧H-cong (x ∷ ρ) =(⟦ p₁≈p₂ ⟧H-cong (x ∷ ρ) ⟨ *-cong ⟩ refl)⟨ +-cong ⟩⟦ c₁≈c₂ ⟧N-cong ρ⟦_⟧N-cong :∀ {n} {p₁ p₂ : Normal n} →p₁ ≈N p₂ → ∀ ρ → ⟦ p₁ ⟧N ρ ≈ ⟦ p₂ ⟧N ρ⟦ con c₁≈c₂ ⟧N-cong _ = c₁≈c₂⟦ poly p₁≈p₂ ⟧N-cong ρ = ⟦ p₁≈p₂ ⟧H-cong ρ-------------------------------------------------------------------------- Ring operations on Horner normal forms-- Zero.0H : ∀ {n} → HNF (suc n)0H = ∅0N : ∀ {n} → Normal n0N {zero} = con C.0#0N {suc n} = poly 0Hmutual-- One.1H : ∀ {n} → HNF (suc n)1H {n} = ∅ *x+ 1N {n}1N : ∀ {n} → Normal n1N {zero} = con C.1#1N {suc n} = poly 1H-- A simplifying variant of _*x+_._*x+HN_ : ∀ {n} → HNF (suc n) → Normal n → HNF (suc n)(p *x+ c′) *x+HN c = (p *x+ c′) *x+ c∅ *x+HN c with c ≟N 0N... | just c≈0 = ∅... | nothing = ∅ *x+ cmutual-- Addition._+H_ : ∀ {n} → HNF (suc n) → HNF (suc n) → HNF (suc n)∅ +H p = pp +H ∅ = p(p₁ *x+ c₁) +H (p₂ *x+ c₂) = (p₁ +H p₂) *x+HN (c₁ +N c₂)_+N_ : ∀ {n} → Normal n → Normal n → Normal ncon c₁ +N con c₂ = con (c₁ C.+ c₂)poly p₁ +N poly p₂ = poly (p₁ +H p₂)-- Multiplication._*x+H_ : ∀ {n} → HNF (suc n) → HNF (suc n) → HNF (suc n)p₁ *x+H (p₂ *x+ c) = (p₁ +H p₂) *x+HN c∅ *x+H ∅ = ∅(p₁ *x+ c) *x+H ∅ = (p₁ *x+ c) *x+ 0Nmutual_*NH_ : ∀ {n} → Normal n → HNF (suc n) → HNF (suc n)c *NH ∅ = ∅c *NH (p *x+ c′) with c ≟N 0N... | just c≈0 = ∅... | nothing = (c *NH p) *x+ (c *N c′)_*HN_ : ∀ {n} → HNF (suc n) → Normal n → HNF (suc n)∅ *HN c = ∅(p *x+ c′) *HN c with c ≟N 0N... | just c≈0 = ∅... | nothing = (p *HN c) *x+ (c′ *N c)_*H_ : ∀ {n} → HNF (suc n) → HNF (suc n) → HNF (suc n)∅ *H _ = ∅(_ *x+ _) *H ∅ = ∅(p₁ *x+ c₁) *H (p₂ *x+ c₂) =((p₁ *H p₂) *x+H (p₁ *HN c₂ +H c₁ *NH p₂)) *x+HN (c₁ *N c₂)_*N_ : ∀ {n} → Normal n → Normal n → Normal ncon c₁ *N con c₂ = con (c₁ C.* c₂)poly p₁ *N poly p₂ = poly (p₁ *H p₂)-- Exponentiation._^N_ : ∀ {n} → Normal n → ℕ → Normal np ^N zero = 1Np ^N suc n = p *N (p ^N n)mutual-- Negation.-H_ : ∀ {n} → HNF (suc n) → HNF (suc n)-H p = (-N 1N) *NH p-N_ : ∀ {n} → Normal n → Normal n-N con c = con (C.- c)-N poly p = poly (-H p)-------------------------------------------------------------------------- Normalisationnormalise-con : ∀ {n} → C.Carrier → Normal nnormalise-con {zero} c = con cnormalise-con {suc n} c = poly (∅ *x+HN normalise-con c)normalise-var : ∀ {n} → Fin n → Normal nnormalise-var zero = poly ((∅ *x+ 1N) *x+ 0N)normalise-var (suc i) = poly (∅ *x+HN normalise-var i)normalise : ∀ {n} → Polynomial n → Normal nnormalise (op [+] t₁ t₂) = normalise t₁ +N normalise t₂normalise (op [*] t₁ t₂) = normalise t₁ *N normalise t₂normalise (con c) = normalise-con cnormalise (var i) = normalise-var inormalise (t :^ k) = normalise t ^N knormalise (:- t) = -N normalise t-- Evaluation after normalisation.⟦_⟧↓ : ∀ {n} → Polynomial n → Vec Carrier n → Carrier⟦ p ⟧↓ ρ = ⟦ normalise p ⟧N ρ-------------------------------------------------------------------------- Homomorphism lemmas0N-homo : ∀ {n} ρ → ⟦ 0N {n} ⟧N ρ ≈ 0#0N-homo [] = 0-homo0N-homo (x ∷ ρ) = refl-- If c is equal to 0N, then c is semantically equal to 0#.0≈⟦0⟧ : ∀ {n} {c : Normal n} → c ≈N 0N → ∀ ρ → 0# ≈ ⟦ c ⟧N ρ0≈⟦0⟧ {c = c} c≈0 ρ = sym (begin⟦ c ⟧N ρ ≈⟨ ⟦ c≈0 ⟧N-cong ρ ⟩⟦ 0N ⟧N ρ ≈⟨ 0N-homo ρ ⟩0# ∎)1N-homo : ∀ {n} ρ → ⟦ 1N {n} ⟧N ρ ≈ 1#1N-homo [] = 1-homo1N-homo (x ∷ ρ) = begin0# * x + ⟦ 1N ⟧N ρ ≈⟨ refl ⟨ +-cong ⟩ 1N-homo ρ ⟩0# * x + 1# ≈⟨ lemma₆ _ _ ⟩1# ∎-- _*x+HN_ is equal to _*x+_.*x+HN≈*x+ : ∀ {n} (p : HNF (suc n)) (c : Normal n) →∀ ρ → ⟦ p *x+HN c ⟧H ρ ≈ ⟦ p *x+ c ⟧H ρ*x+HN≈*x+ (p *x+ c′) c ρ = refl*x+HN≈*x+ ∅ c (x ∷ ρ) with c ≟N 0N... | just c≈0 = begin0# ≈⟨ 0≈⟦0⟧ c≈0 ρ ⟩⟦ c ⟧N ρ ≈⟨ sym $ lemma₆ _ _ ⟩0# * x + ⟦ c ⟧N ρ ∎... | nothing = refl∅*x+HN-homo : ∀ {n} (c : Normal n) x ρ →⟦ ∅ *x+HN c ⟧H (x ∷ ρ) ≈ ⟦ c ⟧N ρ∅*x+HN-homo c x ρ with c ≟N 0N... | just c≈0 = 0≈⟦0⟧ c≈0 ρ... | nothing = lemma₆ _ _mutual+H-homo : ∀ {n} (p₁ p₂ : HNF (suc n)) →∀ ρ → ⟦ p₁ +H p₂ ⟧H ρ ≈ ⟦ p₁ ⟧H ρ + ⟦ p₂ ⟧H ρ+H-homo ∅ p₂ ρ = sym (+-identityˡ _)+H-homo (p₁ *x+ x₁) ∅ ρ = sym (+-identityʳ _)+H-homo (p₁ *x+ c₁) (p₂ *x+ c₂) (x ∷ ρ) = begin⟦ (p₁ +H p₂) *x+HN (c₁ +N c₂) ⟧H (x ∷ ρ) ≈⟨ *x+HN≈*x+ (p₁ +H p₂) (c₁ +N c₂) (x ∷ ρ) ⟩⟦ p₁ +H p₂ ⟧H (x ∷ ρ) * x + ⟦ c₁ +N c₂ ⟧N ρ ≈⟨ (+H-homo p₁ p₂ (x ∷ ρ) ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ +N-homo c₁ c₂ ρ ⟩(⟦ p₁ ⟧H (x ∷ ρ) + ⟦ p₂ ⟧H (x ∷ ρ)) * x + (⟦ c₁ ⟧N ρ + ⟦ c₂ ⟧N ρ) ≈⟨ lemma₁ _ _ _ _ _ ⟩(⟦ p₁ ⟧H (x ∷ ρ) * x + ⟦ c₁ ⟧N ρ) +(⟦ p₂ ⟧H (x ∷ ρ) * x + ⟦ c₂ ⟧N ρ) ∎+N-homo : ∀ {n} (p₁ p₂ : Normal n) →∀ ρ → ⟦ p₁ +N p₂ ⟧N ρ ≈ ⟦ p₁ ⟧N ρ + ⟦ p₂ ⟧N ρ+N-homo (con c₁) (con c₂) _ = +-homo _ _+N-homo (poly p₁) (poly p₂) ρ = +H-homo p₁ p₂ ρ*x+H-homo :∀ {n} (p₁ p₂ : HNF (suc n)) x ρ →⟦ p₁ *x+H p₂ ⟧H (x ∷ ρ) ≈⟦ p₁ ⟧H (x ∷ ρ) * x + ⟦ p₂ ⟧H (x ∷ ρ)*x+H-homo ∅ ∅ _ _ = sym $ lemma₆ _ _*x+H-homo (p *x+ c) ∅ x ρ = begin⟦ p *x+ c ⟧H (x ∷ ρ) * x + ⟦ 0N ⟧N ρ ≈⟨ refl ⟨ +-cong ⟩ 0N-homo ρ ⟩⟦ p *x+ c ⟧H (x ∷ ρ) * x + 0# ∎*x+H-homo p₁ (p₂ *x+ c₂) x ρ = begin⟦ (p₁ +H p₂) *x+HN c₂ ⟧H (x ∷ ρ) ≈⟨ *x+HN≈*x+ (p₁ +H p₂) c₂ (x ∷ ρ) ⟩⟦ p₁ +H p₂ ⟧H (x ∷ ρ) * x + ⟦ c₂ ⟧N ρ ≈⟨ (+H-homo p₁ p₂ (x ∷ ρ) ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ refl ⟩(⟦ p₁ ⟧H (x ∷ ρ) + ⟦ p₂ ⟧H (x ∷ ρ)) * x + ⟦ c₂ ⟧N ρ ≈⟨ lemma₀ _ _ _ _ ⟩⟦ p₁ ⟧H (x ∷ ρ) * x + (⟦ p₂ ⟧H (x ∷ ρ) * x + ⟦ c₂ ⟧N ρ) ∎mutual*NH-homo :∀ {n} (c : Normal n) (p : HNF (suc n)) x ρ →⟦ c *NH p ⟧H (x ∷ ρ) ≈ ⟦ c ⟧N ρ * ⟦ p ⟧H (x ∷ ρ)*NH-homo c ∅ x ρ = sym (*-zeroʳ _)*NH-homo c (p *x+ c′) x ρ with c ≟N 0N... | just c≈0 = begin0# ≈⟨ sym (*-zeroˡ _) ⟩0# * (⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) ≈⟨ 0≈⟦0⟧ c≈0 ρ ⟨ *-cong ⟩ refl ⟩⟦ c ⟧N ρ * (⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) ∎... | nothing = begin⟦ c *NH p ⟧H (x ∷ ρ) * x + ⟦ c *N c′ ⟧N ρ ≈⟨ (*NH-homo c p x ρ ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ *N-homo c c′ ρ ⟩(⟦ c ⟧N ρ * ⟦ p ⟧H (x ∷ ρ)) * x + (⟦ c ⟧N ρ * ⟦ c′ ⟧N ρ) ≈⟨ lemma₃ _ _ _ _ ⟩⟦ c ⟧N ρ * (⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) ∎*HN-homo :∀ {n} (p : HNF (suc n)) (c : Normal n) x ρ →⟦ p *HN c ⟧H (x ∷ ρ) ≈ ⟦ p ⟧H (x ∷ ρ) * ⟦ c ⟧N ρ*HN-homo ∅ c x ρ = sym (*-zeroˡ _)*HN-homo (p *x+ c′) c x ρ with c ≟N 0N... | just c≈0 = begin0# ≈⟨ sym (*-zeroʳ _) ⟩(⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) * 0# ≈⟨ refl ⟨ *-cong ⟩ 0≈⟦0⟧ c≈0 ρ ⟩(⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) * ⟦ c ⟧N ρ ∎... | nothing = begin⟦ p *HN c ⟧H (x ∷ ρ) * x + ⟦ c′ *N c ⟧N ρ ≈⟨ (*HN-homo p c x ρ ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ *N-homo c′ c ρ ⟩(⟦ p ⟧H (x ∷ ρ) * ⟦ c ⟧N ρ) * x + (⟦ c′ ⟧N ρ * ⟦ c ⟧N ρ) ≈⟨ lemma₂ _ _ _ _ ⟩(⟦ p ⟧H (x ∷ ρ) * x + ⟦ c′ ⟧N ρ) * ⟦ c ⟧N ρ ∎*H-homo : ∀ {n} (p₁ p₂ : HNF (suc n)) →∀ ρ → ⟦ p₁ *H p₂ ⟧H ρ ≈ ⟦ p₁ ⟧H ρ * ⟦ p₂ ⟧H ρ*H-homo ∅ p₂ ρ = sym $ *-zeroˡ _*H-homo (p₁ *x+ c₁) ∅ ρ = sym $ *-zeroʳ _*H-homo (p₁ *x+ c₁) (p₂ *x+ c₂) (x ∷ ρ) = begin⟦ ((p₁ *H p₂) *x+H ((p₁ *HN c₂) +H (c₁ *NH p₂))) *x+HN(c₁ *N c₂) ⟧H (x ∷ ρ) ≈⟨ *x+HN≈*x+ ((p₁ *H p₂) *x+H ((p₁ *HN c₂) +H (c₁ *NH p₂)))(c₁ *N c₂) (x ∷ ρ) ⟩⟦ (p₁ *H p₂) *x+H((p₁ *HN c₂) +H (c₁ *NH p₂)) ⟧H (x ∷ ρ) * x +⟦ c₁ *N c₂ ⟧N ρ ≈⟨ (*x+H-homo (p₁ *H p₂) ((p₁ *HN c₂) +H (c₁ *NH p₂)) x ρ⟨ *-cong ⟩refl)⟨ +-cong ⟩*N-homo c₁ c₂ ρ ⟩(⟦ p₁ *H p₂ ⟧H (x ∷ ρ) * x +⟦ (p₁ *HN c₂) +H (c₁ *NH p₂) ⟧H (x ∷ ρ)) * x +⟦ c₁ ⟧N ρ * ⟦ c₂ ⟧N ρ ≈⟨ (((*H-homo p₁ p₂ (x ∷ ρ) ⟨ *-cong ⟩ refl)⟨ +-cong ⟩(+H-homo (p₁ *HN c₂) (c₁ *NH p₂) (x ∷ ρ)))⟨ *-cong ⟩refl)⟨ +-cong ⟩refl ⟩(⟦ p₁ ⟧H (x ∷ ρ) * ⟦ p₂ ⟧H (x ∷ ρ) * x +(⟦ p₁ *HN c₂ ⟧H (x ∷ ρ) + ⟦ c₁ *NH p₂ ⟧H (x ∷ ρ))) * x +⟦ c₁ ⟧N ρ * ⟦ c₂ ⟧N ρ ≈⟨ ((refl ⟨ +-cong ⟩ (*HN-homo p₁ c₂ x ρ ⟨ +-cong ⟩ *NH-homo c₁ p₂ x ρ))⟨ *-cong ⟩refl)⟨ +-cong ⟩refl ⟩(⟦ p₁ ⟧H (x ∷ ρ) * ⟦ p₂ ⟧H (x ∷ ρ) * x +(⟦ p₁ ⟧H (x ∷ ρ) * ⟦ c₂ ⟧N ρ + ⟦ c₁ ⟧N ρ * ⟦ p₂ ⟧H (x ∷ ρ))) * x +(⟦ c₁ ⟧N ρ * ⟦ c₂ ⟧N ρ) ≈⟨ lemma₄ _ _ _ _ _ ⟩(⟦ p₁ ⟧H (x ∷ ρ) * x + ⟦ c₁ ⟧N ρ) *(⟦ p₂ ⟧H (x ∷ ρ) * x + ⟦ c₂ ⟧N ρ) ∎*N-homo : ∀ {n} (p₁ p₂ : Normal n) →∀ ρ → ⟦ p₁ *N p₂ ⟧N ρ ≈ ⟦ p₁ ⟧N ρ * ⟦ p₂ ⟧N ρ*N-homo (con c₁) (con c₂) _ = *-homo _ _*N-homo (poly p₁) (poly p₂) ρ = *H-homo p₁ p₂ ρ^N-homo : ∀ {n} (p : Normal n) (k : ℕ) →∀ ρ → ⟦ p ^N k ⟧N ρ ≈ ⟦ p ⟧N ρ ^ k^N-homo p zero ρ = 1N-homo ρ^N-homo p (suc k) ρ = begin⟦ p *N (p ^N k) ⟧N ρ ≈⟨ *N-homo p (p ^N k) ρ ⟩⟦ p ⟧N ρ * ⟦ p ^N k ⟧N ρ ≈⟨ refl ⟨ *-cong ⟩ ^N-homo p k ρ ⟩⟦ p ⟧N ρ * (⟦ p ⟧N ρ ^ k) ∎mutual-H‿-homo : ∀ {n} (p : HNF (suc n)) →∀ ρ → ⟦ -H p ⟧H ρ ≈ - ⟦ p ⟧H ρ-H‿-homo p (x ∷ ρ) = begin⟦ (-N 1N) *NH p ⟧H (x ∷ ρ) ≈⟨ *NH-homo (-N 1N) p x ρ ⟩⟦ -N 1N ⟧N ρ * ⟦ p ⟧H (x ∷ ρ) ≈⟨ trans (-N‿-homo 1N ρ) (-‿cong (1N-homo ρ)) ⟨ *-cong ⟩ refl ⟩- 1# * ⟦ p ⟧H (x ∷ ρ) ≈⟨ lemma₇ _ ⟩- ⟦ p ⟧H (x ∷ ρ) ∎-N‿-homo : ∀ {n} (p : Normal n) →∀ ρ → ⟦ -N p ⟧N ρ ≈ - ⟦ p ⟧N ρ-N‿-homo (con c) _ = -‿homo _-N‿-homo (poly p) ρ = -H‿-homo p ρ-------------------------------------------------------------------------- Correctnesscorrect-con : ∀ {n} (c : C.Carrier) (ρ : Vec Carrier n) →⟦ normalise-con c ⟧N ρ ≈ ⟦ c ⟧′correct-con c [] = reflcorrect-con c (x ∷ ρ) = begin⟦ ∅ *x+HN normalise-con c ⟧H (x ∷ ρ) ≈⟨ ∅*x+HN-homo (normalise-con c) x ρ ⟩⟦ normalise-con c ⟧N ρ ≈⟨ correct-con c ρ ⟩⟦ c ⟧′ ∎correct-var : ∀ {n} (i : Fin n) →∀ ρ → ⟦ normalise-var i ⟧N ρ ≈ lookup ρ icorrect-var (suc i) (x ∷ ρ) = begin⟦ ∅ *x+HN normalise-var i ⟧H (x ∷ ρ) ≈⟨ ∅*x+HN-homo (normalise-var i) x ρ ⟩⟦ normalise-var i ⟧N ρ ≈⟨ correct-var i ρ ⟩lookup ρ i ∎correct-var zero (x ∷ ρ) = begin(0# * x + ⟦ 1N ⟧N ρ) * x + ⟦ 0N ⟧N ρ ≈⟨ ((refl ⟨ +-cong ⟩ 1N-homo ρ) ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ 0N-homo ρ ⟩(0# * x + 1#) * x + 0# ≈⟨ lemma₅ _ ⟩x ∎correct : ∀ {n} (p : Polynomial n) → ∀ ρ → ⟦ p ⟧↓ ρ ≈ ⟦ p ⟧ ρcorrect (op [+] p₁ p₂) ρ = begin⟦ normalise p₁ +N normalise p₂ ⟧N ρ ≈⟨ +N-homo (normalise p₁) (normalise p₂) ρ ⟩⟦ p₁ ⟧↓ ρ + ⟦ p₂ ⟧↓ ρ ≈⟨ correct p₁ ρ ⟨ +-cong ⟩ correct p₂ ρ ⟩⟦ p₁ ⟧ ρ + ⟦ p₂ ⟧ ρ ∎correct (op [*] p₁ p₂) ρ = begin⟦ normalise p₁ *N normalise p₂ ⟧N ρ ≈⟨ *N-homo (normalise p₁) (normalise p₂) ρ ⟩⟦ p₁ ⟧↓ ρ * ⟦ p₂ ⟧↓ ρ ≈⟨ correct p₁ ρ ⟨ *-cong ⟩ correct p₂ ρ ⟩⟦ p₁ ⟧ ρ * ⟦ p₂ ⟧ ρ ∎correct (con c) ρ = correct-con c ρcorrect (var i) ρ = correct-var i ρcorrect (p :^ k) ρ = begin⟦ normalise p ^N k ⟧N ρ ≈⟨ ^N-homo (normalise p) k ρ ⟩⟦ p ⟧↓ ρ ^ k ≈⟨ correct p ρ ⟨ ^-cong ⟩ ≡.refl {x = k} ⟩⟦ p ⟧ ρ ^ k ∎correct (:- p) ρ = begin⟦ -N normalise p ⟧N ρ ≈⟨ -N‿-homo (normalise p) ρ ⟩- ⟦ p ⟧↓ ρ ≈⟨ -‿cong (correct p ρ) ⟩- ⟦ p ⟧ ρ ∎-------------------------------------------------------------------------- "Tactic.open Reflection setoid var ⟦_⟧ ⟦_⟧↓ correct publicusing (prove; solve) renaming (_⊜_ to _:=_)-- For examples of how solve and _:=_ can be used to-- semi-automatically prove ring equalities, see, for instance,-- Data.Digit or Data.Nat.DivMod.
-------------------------------------------------------------------------- The Agda standard library---- Instantiates the ring solver with two copies of the same ring with-- decidable equality------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Solver.Ring.AlmostCommutativeRingopen import Relation.Binary.Definitions using (Decidable)open import Relation.Binary.Consequences using (dec⇒weaklyDec)module Algebra.Solver.Ring.Simple{r₁ r₂} (R : AlmostCommutativeRing r₁ r₂)(_≟_ : Decidable (AlmostCommutativeRing._≈_ R))whereopen AlmostCommutativeRing Rimport Algebra.Solver.Ring as RSopen RS rawRing R (-raw-almostCommutative⟶ R) (dec⇒weaklyDec _≟_) public
-------------------------------------------------------------------------- The Agda standard library---- Instantiates the ring solver, using the natural numbers as the-- coefficient "ring"------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraimport Algebra.Properties.Semiring.Mult as SemiringMultiplicationopen import Data.Maybe.Base using (Maybe; just; nothing; map)open import Algebra.Solver.Ring.AlmostCommutativeRingopen import Data.Nat.Base as ℕopen import Data.Product.Base using (module Σ)open import Function.Base using (id)open import Relation.Binary.PropositionalEquality.Core using (_≡_)module Algebra.Solver.Ring.NaturalCoefficients{r₁ r₂} (R : CommutativeSemiring r₁ r₂)(open CommutativeSemiring R)(open SemiringMultiplication semiring using () renaming (_×_ to _×ᵤ_))(dec : ∀ m n → Maybe (m ×ᵤ 1# ≈ n ×ᵤ 1#)) whereopen import Algebra.Properties.Semiring.Mult.TCOptimised semiringopen import Relation.Binary.Reasoning.Setoid setoidprivate-- The coefficient "ring".ℕ-ring : RawRing _ _ℕ-ring = record{ Carrier = ℕ; _≈_ = _≡_; _+_ = ℕ._+_; _*_ = ℕ._*_; -_ = id; 0# = 0; 1# = 1}-- There is a homomorphism from ℕ to R.---- Note that the optimised _×_ is used rather than unoptimised _×ᵤ_.-- If _×ᵤ_ were used, then Function.Related.TypeIsomorphisms.test-- would fail to type-check.homomorphism : ℕ-ring -Raw-AlmostCommutative⟶ fromCommutativeSemiring Rhomomorphism = record{ ⟦_⟧ = λ n → n × 1#; +-homo = ×-homo-+ 1#; *-homo = ×1-homo-*; -‿homo = λ _ → refl; 0-homo = refl; 1-homo = refl}-- Equality of certain expressions can be decided.dec′ : ∀ m n → Maybe (m × 1# ≈ n × 1#)dec′ m n = map to (dec m n)whereto : m ×ᵤ 1# ≈ n ×ᵤ 1# → m × 1# ≈ n × 1#to m≈n = beginm × 1# ≈⟨ ×ᵤ≈× m 1# ⟨m ×ᵤ 1# ≈⟨ m≈n ⟩n ×ᵤ 1# ≈⟨ ×ᵤ≈× n 1# ⟩n × 1# ∎-- The instantiation.open import Algebra.Solver.Ring _ _ homomorphism dec′ public
-------------------------------------------------------------------------- The Agda standard library---- Instantiates the natural coefficients ring solver, using coefficient-- equality induced by ℕ.---- This is sufficient for proving equalities that are independent of the-- characteristic. In particular, this is enough for equalities in-- rings of characteristic 0.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Solver.Ring.NaturalCoefficients.Default{r₁ r₂} (R : CommutativeSemiring r₁ r₂) whereimport Algebra.Properties.Semiring.Mult as SemiringMultiplicationopen import Data.Maybe.Base using (Maybe; map)open import Data.Nat using (_≟_)open import Relation.Binary.Consequences using (dec⇒weaklyDec)import Relation.Binary.PropositionalEquality.Core as ≡open CommutativeSemiring Ropen SemiringMultiplication semiringprivatedec : ∀ m n → Maybe (m × 1# ≈ n × 1#)dec m n = map (λ { ≡.refl → refl }) (dec⇒weaklyDec _≟_ m n)open import Algebra.Solver.Ring.NaturalCoefficients R dec public
-------------------------------------------------------------------------- The Agda standard library---- Some boring lemmas used by the ring solver-------------------------------------------------------------------------- Note that these proofs use all "almost commutative ring" properties.{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Algebra.Solver.Ring.AlmostCommutativeRingmodule Algebra.Solver.Ring.Lemmas{r₁ r₂ r₃ r₄}(coeff : RawRing r₁ r₄)(r : AlmostCommutativeRing r₂ r₃)(morphism : coeff -Raw-AlmostCommutative⟶ r)whereprivatemodule C = RawRing coeffopen AlmostCommutativeRing ropen import Algebra.Morphismopen _-Raw-AlmostCommutative⟶_ morphismopen import Relation.Binary.Reasoning.Setoid setoidopen import Function.Base using (_⟨_⟩_; _$_)lemma₀ : ∀ a b c x →(a + b) * x + c ≈ a * x + (b * x + c)lemma₀ a b c x = begin(a + b) * x + c ≈⟨ distribʳ _ _ _ ⟨ +-cong ⟩ refl ⟩(a * x + b * x) + c ≈⟨ +-assoc _ _ _ ⟩a * x + (b * x + c) ∎lemma₁ : ∀ a b c d x →(a + b) * x + (c + d) ≈ (a * x + c) + (b * x + d)lemma₁ a b c d x = begin(a + b) * x + (c + d) ≈⟨ lemma₀ _ _ _ _ ⟩a * x + (b * x + (c + d)) ≈⟨ refl ⟨ +-cong ⟩ sym (+-assoc _ _ _) ⟩a * x + ((b * x + c) + d) ≈⟨ refl ⟨ +-cong ⟩ (+-comm _ _ ⟨ +-cong ⟩ refl) ⟩a * x + ((c + b * x) + d) ≈⟨ refl ⟨ +-cong ⟩ +-assoc _ _ _ ⟩a * x + (c + (b * x + d)) ≈⟨ sym $ +-assoc _ _ _ ⟩(a * x + c) + (b * x + d) ∎lemma₂ : ∀ a b c x → a * c * x + b * c ≈ (a * x + b) * clemma₂ a b c x = begina * c * x + b * c ≈⟨ lem ⟨ +-cong ⟩ refl ⟩a * x * c + b * c ≈⟨ sym $ distribʳ _ _ _ ⟩(a * x + b) * c ∎wherelem = begina * c * x ≈⟨ *-assoc _ _ _ ⟩a * (c * x) ≈⟨ refl ⟨ *-cong ⟩ *-comm _ _ ⟩a * (x * c) ≈⟨ sym $ *-assoc _ _ _ ⟩a * x * c ∎lemma₃ : ∀ a b c x → a * b * x + a * c ≈ a * (b * x + c)lemma₃ a b c x = begina * b * x + a * c ≈⟨ *-assoc _ _ _ ⟨ +-cong ⟩ refl ⟩a * (b * x) + a * c ≈⟨ sym $ distribˡ _ _ _ ⟩a * (b * x + c) ∎lemma₄ : ∀ a b c d x →(a * c * x + (a * d + b * c)) * x + b * d ≈(a * x + b) * (c * x + d)lemma₄ a b c d x = begin(a * c * x + (a * d + b * c)) * x + b * d ≈⟨ distribʳ _ _ _ ⟨ +-cong ⟩ refl ⟩(a * c * x * x + (a * d + b * c) * x) + b * d ≈⟨ refl ⟨ +-cong ⟩ ((refl ⟨ +-cong ⟩ refl) ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ refl ⟩(a * c * x * x + (a * d + b * c) * x) + b * d ≈⟨ +-assoc _ _ _ ⟩a * c * x * x + ((a * d + b * c) * x + b * d) ≈⟨ lem₁ ⟨ +-cong ⟩ (lem₂ ⟨ +-cong ⟩ refl) ⟩a * x * (c * x) + (a * x * d + b * (c * x) + b * d) ≈⟨ refl ⟨ +-cong ⟩ +-assoc _ _ _ ⟩a * x * (c * x) + (a * x * d + (b * (c * x) + b * d)) ≈⟨ sym $ +-assoc _ _ _ ⟩a * x * (c * x) + a * x * d + (b * (c * x) + b * d) ≈⟨ sym $ distribˡ _ _ _ ⟨ +-cong ⟩ distribˡ _ _ _ ⟩a * x * (c * x + d) + b * (c * x + d) ≈⟨ sym $ distribʳ _ _ _ ⟩(a * x + b) * (c * x + d) ∎wherelem₁′ = begina * c * x ≈⟨ *-assoc _ _ _ ⟩a * (c * x) ≈⟨ refl ⟨ *-cong ⟩ *-comm _ _ ⟩a * (x * c) ≈⟨ sym $ *-assoc _ _ _ ⟩a * x * c ∎lem₁ = begina * c * x * x ≈⟨ lem₁′ ⟨ *-cong ⟩ refl ⟩a * x * c * x ≈⟨ *-assoc _ _ _ ⟩a * x * (c * x) ∎lem₂ = begin(a * d + b * c) * x ≈⟨ distribʳ _ _ _ ⟩a * d * x + b * c * x ≈⟨ *-assoc _ _ _ ⟨ +-cong ⟩ *-assoc _ _ _ ⟩a * (d * x) + b * (c * x) ≈⟨ (refl ⟨ *-cong ⟩ *-comm _ _) ⟨ +-cong ⟩ refl ⟩a * (x * d) + b * (c * x) ≈⟨ sym $ *-assoc _ _ _ ⟨ +-cong ⟩ refl ⟩a * x * d + b * (c * x) ∎lemma₅ : ∀ x → (0# * x + 1#) * x + 0# ≈ xlemma₅ x = begin(0# * x + 1#) * x + 0# ≈⟨ ((zeroˡ _ ⟨ +-cong ⟩ refl) ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ refl ⟩(0# + 1#) * x + 0# ≈⟨ (+-identityˡ _ ⟨ *-cong ⟩ refl) ⟨ +-cong ⟩ refl ⟩1# * x + 0# ≈⟨ +-identityʳ _ ⟩1# * x ≈⟨ *-identityˡ _ ⟩x ∎lemma₆ : ∀ a x → 0# * x + a ≈ alemma₆ a x = begin0# * x + a ≈⟨ zeroˡ _ ⟨ +-cong ⟩ refl ⟩0# + a ≈⟨ +-identityˡ _ ⟩a ∎lemma₇ : ∀ x → - 1# * x ≈ - xlemma₇ x = begin- 1# * x ≈⟨ -‿*-distribˡ _ _ ⟩- (1# * x) ≈⟨ -‿cong (*-identityˡ _) ⟩- x ∎
-------------------------------------------------------------------------- The Agda standard library---- Commutative semirings with some additional structure ("almost"-- commutative rings), used by the ring solver------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Solver.Ring.AlmostCommutativeRing whereopen import Algebraopen import Algebra.Structuresopen import Algebra.Definitionsimport Algebra.Morphism as Morphismimport Algebra.Morphism.Definitions as MorphismDefinitionsopen import Function.Base using (id)open import Levelopen import Relation.Binary.Core using (Rel)record IsAlmostCommutativeRing {a ℓ} {A : Set a} (_≈_ : Rel A ℓ)(_+_ _*_ : Op₂ A) (-_ : Op₁ A)(0# 1# : A) : Set (a ⊔ ℓ) wherefieldisCommutativeSemiring : IsCommutativeSemiring _≈_ _+_ _*_ 0# 1#-‿cong : Congruent₁ _≈_ -_-‿*-distribˡ : ∀ x y → ((- x) * y) ≈ (- (x * y))-‿+-comm : ∀ x y → ((- x) + (- y)) ≈ (- (x + y))open IsCommutativeSemiring isCommutativeSemiring publicrecord AlmostCommutativeRing c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisAlmostCommutativeRing : IsAlmostCommutativeRing _≈_ _+_ _*_ -_ 0# 1#open IsAlmostCommutativeRing isAlmostCommutativeRing publiccommutativeSemiring : CommutativeSemiring _ _commutativeSemiring = record{ isCommutativeSemiring = isCommutativeSemiring}open CommutativeSemiring commutativeSemiring publicusing( +-magma; +-semigroup; *-magma; *-semigroup; *-commutativeSemigroup; +-monoid; +-commutativeMonoid; *-monoid; *-commutativeMonoid; semiring)rawRing : RawRing _ _rawRing = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0#; 1# = 1#}-------------------------------------------------------------------------- Homomorphismsinfix 4 _-Raw-AlmostCommutative⟶_record _-Raw-AlmostCommutative⟶_{r₁ r₂ r₃ r₄}(From : RawRing r₁ r₄)(To : AlmostCommutativeRing r₂ r₃) : Set (r₁ ⊔ r₂ ⊔ r₃) whereprivatemodule F = RawRing Frommodule T = AlmostCommutativeRing Toopen MorphismDefinitions F.Carrier T.Carrier T._≈_field⟦_⟧ : Morphism+-homo : Homomorphic₂ ⟦_⟧ F._+_ T._+_*-homo : Homomorphic₂ ⟦_⟧ F._*_ T._*_-‿homo : Homomorphic₁ ⟦_⟧ F.-_ T.-_0-homo : Homomorphic₀ ⟦_⟧ F.0# T.0#1-homo : Homomorphic₀ ⟦_⟧ F.1# T.1#-raw-almostCommutative⟶ :∀ {r₁ r₂} (R : AlmostCommutativeRing r₁ r₂) →AlmostCommutativeRing.rawRing R -Raw-AlmostCommutative⟶ R-raw-almostCommutative⟶ R = record{ ⟦_⟧ = id; +-homo = λ _ _ → refl; *-homo = λ _ _ → refl; -‿homo = λ _ → refl; 0-homo = refl; 1-homo = refl}where open AlmostCommutativeRing RInduced-equivalence : ∀ {c₁ c₂ ℓ₁ ℓ₂} {Coeff : RawRing c₁ ℓ₁}{R : AlmostCommutativeRing c₂ ℓ₂} →Coeff -Raw-AlmostCommutative⟶ R →Rel (RawRing.Carrier Coeff) ℓ₂Induced-equivalence {R = R} morphism a b = ⟦ a ⟧ ≈ ⟦ b ⟧whereopen AlmostCommutativeRing Ropen _-Raw-AlmostCommutative⟶_ morphism-------------------------------------------------------------------------- Conversions-- Commutative rings are almost commutative rings.fromCommutativeRing : ∀ {r₁ r₂} → CommutativeRing r₁ r₂ → AlmostCommutativeRing r₁ r₂fromCommutativeRing CR = record{ isAlmostCommutativeRing = record{ isCommutativeSemiring = isCommutativeSemiring; -‿cong = -‿cong; -‿*-distribˡ = λ x y → sym (-‿distribˡ-* x y); -‿+-comm = ⁻¹-∙-comm}}whereopen CommutativeRing CRopen import Algebra.Properties.Ring ringopen import Algebra.Properties.AbelianGroup +-abelianGroup-- Commutative semirings can be viewed as almost commutative rings by-- using identity as the "almost negation".fromCommutativeSemiring : ∀ {r₁ r₂} → CommutativeSemiring r₁ r₂ → AlmostCommutativeRing _ _fromCommutativeSemiring CS = record{ -_ = id; isAlmostCommutativeRing = record{ isCommutativeSemiring = isCommutativeSemiring; -‿cong = id; -‿*-distribˡ = λ _ _ → refl; -‿+-comm = λ _ _ → refl}}where open CommutativeSemiring CS
-------------------------------------------------------------------------- The Agda standard library---- A solver for equations over monoids------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Solver.Monoid {m₁ m₂} (M : Monoid m₁ m₂) whereopen import Data.Fin.Base as Finimport Data.Fin.Properties as Finopen import Data.List.Base hiding (lookup)import Data.List.Relation.Binary.Equality.DecPropositional as ListEqopen import Data.Maybe.Base as Maybeusing (Maybe; From-just; from-just)open import Data.Nat.Base using (ℕ)open import Data.Product.Base using (_×_; uncurry)open import Data.Vec.Base using (Vec; lookup)open import Function.Base using (_∘_; _$_)open import Relation.Binary.Consequences using (dec⇒weaklyDec)open import Relation.Binary.Definitions using (DecidableEquality)open import Relation.Binary.PropositionalEquality.Core using (_≡_; cong)import Relation.Binary.Reflectionimport Relation.Nullary.Decidable.Core as Decopen Monoid Mopen import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Monoid expressions-- There is one constructor for every operation, plus one for-- variables; there may be at most n variables.infixr 5 _⊕_data Expr (n : ℕ) : Set wherevar : Fin n → Expr nid : Expr n_⊕_ : Expr n → Expr n → Expr n-- An environment contains one value for every variable.Env : ℕ → Set _Env n = Vec Carrier n-- The semantics of an expression is a function from an environment to-- a value.⟦_⟧ : ∀ {n} → Expr n → Env n → Carrier⟦ var x ⟧ ρ = lookup ρ x⟦ id ⟧ ρ = ε⟦ e₁ ⊕ e₂ ⟧ ρ = ⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ-------------------------------------------------------------------------- Normal forms-- A normal form is a list of variables.Normal : ℕ → SetNormal n = List (Fin n)-- The semantics of a normal form.⟦_⟧⇓ : ∀ {n} → Normal n → Env n → Carrier⟦ [] ⟧⇓ ρ = ε⟦ x ∷ nf ⟧⇓ ρ = lookup ρ x ∙ ⟦ nf ⟧⇓ ρ-- A normaliser.normalise : ∀ {n} → Expr n → Normal nnormalise (var x) = x ∷ []normalise id = []normalise (e₁ ⊕ e₂) = normalise e₁ ++ normalise e₂-- The normaliser is homomorphic with respect to _++_/_∙_.homomorphic : ∀ {n} (nf₁ nf₂ : Normal n) (ρ : Env n) →⟦ nf₁ ++ nf₂ ⟧⇓ ρ ≈ (⟦ nf₁ ⟧⇓ ρ ∙ ⟦ nf₂ ⟧⇓ ρ)homomorphic [] nf₂ ρ = begin⟦ nf₂ ⟧⇓ ρ ≈⟨ sym $ identityˡ _ ⟩ε ∙ ⟦ nf₂ ⟧⇓ ρ ∎homomorphic (x ∷ nf₁) nf₂ ρ = beginlookup ρ x ∙ ⟦ nf₁ ++ nf₂ ⟧⇓ ρ ≈⟨ ∙-congˡ (homomorphic nf₁ nf₂ ρ) ⟩lookup ρ x ∙ (⟦ nf₁ ⟧⇓ ρ ∙ ⟦ nf₂ ⟧⇓ ρ) ≈⟨ sym $ assoc _ _ _ ⟩lookup ρ x ∙ ⟦ nf₁ ⟧⇓ ρ ∙ ⟦ nf₂ ⟧⇓ ρ ∎-- The normaliser preserves the semantics of the expression.normalise-correct :∀ {n} (e : Expr n) (ρ : Env n) → ⟦ normalise e ⟧⇓ ρ ≈ ⟦ e ⟧ ρnormalise-correct (var x) ρ = beginlookup ρ x ∙ ε ≈⟨ identityʳ _ ⟩lookup ρ x ∎normalise-correct id ρ = beginε ∎normalise-correct (e₁ ⊕ e₂) ρ = begin⟦ normalise e₁ ++ normalise e₂ ⟧⇓ ρ ≈⟨ homomorphic (normalise e₁) (normalise e₂) ρ ⟩⟦ normalise e₁ ⟧⇓ ρ ∙ ⟦ normalise e₂ ⟧⇓ ρ ≈⟨ ∙-cong (normalise-correct e₁ ρ) (normalise-correct e₂ ρ) ⟩⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ ∎-------------------------------------------------------------------------- "Tactic.open module R = Relation.Binary.Reflectionsetoid var ⟦_⟧ (⟦_⟧⇓ ∘ normalise) normalise-correctpublic using (solve; _⊜_)-- We can decide if two normal forms are /syntactically/ equal.infix 5 _≟__≟_ : ∀ {n} → DecidableEquality (Normal n)nf₁ ≟ nf₂ = Dec.map′ ≋⇒≡ ≡⇒≋ (nf₁ ≋? nf₂)where open ListEq Fin._≟_-- We can also give a sound, but not necessarily complete, procedure-- for determining if two expressions have the same semantics.prove′ : ∀ {n} (e₁ e₂ : Expr n) → Maybe (∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρ)prove′ e₁ e₂ =Maybe.map lemma $ dec⇒weaklyDec _≟_ (normalise e₁) (normalise e₂)wherelemma : normalise e₁ ≡ normalise e₂ → ∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρlemma eq ρ =R.prove ρ e₁ e₂ (begin⟦ normalise e₁ ⟧⇓ ρ ≡⟨ cong (λ e → ⟦ e ⟧⇓ ρ) eq ⟩⟦ normalise e₂ ⟧⇓ ρ ∎)-- This procedure can be combined with from-just.prove : ∀ n (es : Expr n × Expr n) →From-just (uncurry prove′ es)prove _ = from-just ∘ uncurry prove′
-------------------------------------------------------------------------- The Agda standard library---- Solver for equations in idempotent commutative monoids---- Adapted from Algebra.Solver.CommutativeMonoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (IdempotentCommutativeMonoid)open import Data.Bool as Bool using (Bool; true; false; if_then_else_; _∨_)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Maybe.Base as Maybeusing (Maybe; From-just; from-just)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _+_)open import Data.Product.Base using (_×_; uncurry)open import Data.Vec.Base using (Vec; []; _∷_; lookup; replicate)open import Function.Base using (_∘_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Relation.Binary.Reflection as Reflectionimport Data.Vec.Relation.Binary.Pointwise.Inductive as Pointwiseopen import Relation.Binary.Consequences using (dec⇒weaklyDec)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.PropositionalEquality.Properties using (decSetoid)open import Relation.Nullary.Decidable as Dec using (Dec)module Algebra.Solver.IdempotentCommutativeMonoid{m₁ m₂} (M : IdempotentCommutativeMonoid m₁ m₂) whereopen IdempotentCommutativeMonoid Mopen ≈-Reasoning setoidprivatevariablen : ℕ-------------------------------------------------------------------------- Monoid expressions-- There is one constructor for every operation, plus one for-- variables; there may be at most n variables.infixr 5 _⊕_infixr 10 _•_data Expr (n : ℕ) : Set wherevar : Fin n → Expr nid : Expr n_⊕_ : Expr n → Expr n → Expr n-- An environment contains one value for every variable.Env : ℕ → Set _Env n = Vec Carrier n-- The semantics of an expression is a function from an environment to-- a value.⟦_⟧ : ∀ {n} → Expr n → Env n → Carrier⟦ var x ⟧ ρ = lookup ρ x⟦ id ⟧ ρ = ε⟦ e₁ ⊕ e₂ ⟧ ρ = ⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ-------------------------------------------------------------------------- Normal forms-- A normal form is a vector of bits (a set).Normal : ℕ → SetNormal n = Vec Bool n-- The semantics of a normal form.⟦_⟧⇓ : Normal n → Env n → Carrier⟦ [] ⟧⇓ _ = ε⟦ b ∷ v ⟧⇓ (a ∷ ρ) = if b then a ∙ (⟦ v ⟧⇓ ρ) else (⟦ v ⟧⇓ ρ)-------------------------------------------------------------------------- Constructions on normal forms-- The empty set.empty : Normal nempty = replicate _ false-- A singleton set.sg : (i : Fin n) → Normal nsg zero = true ∷ emptysg (suc i) = false ∷ sg i-- The composition of normal forms._•_ : (v w : Normal n) → Normal n[] • [] = [](l ∷ v) • (m ∷ w) = (l ∨ m) ∷ v • w-------------------------------------------------------------------------- Correctness of the constructions on normal forms-- The empty set stands for the unit ε.empty-correct : (ρ : Env n) → ⟦ empty ⟧⇓ ρ ≈ εempty-correct [] = reflempty-correct (a ∷ ρ) = empty-correct ρ-- The singleton set stands for a single variable.sg-correct : (x : Fin n) (ρ : Env n) → ⟦ sg x ⟧⇓ ρ ≈ lookup ρ xsg-correct zero (x ∷ ρ) = beginx ∙ ⟦ empty ⟧⇓ ρ ≈⟨ ∙-congˡ (empty-correct ρ) ⟩x ∙ ε ≈⟨ identityʳ _ ⟩x ∎sg-correct (suc x) (m ∷ ρ) = sg-correct x ρ-- Normal form composition corresponds to the composition of the monoid.flip12 : ∀ a b c → a ∙ (b ∙ c) ≈ b ∙ (a ∙ c)flip12 a b c = begina ∙ (b ∙ c) ≈⟨ sym (assoc _ _ _) ⟩(a ∙ b) ∙ c ≈⟨ ∙-congʳ (comm _ _) ⟩(b ∙ a) ∙ c ≈⟨ assoc _ _ _ ⟩b ∙ (a ∙ c) ∎distr : ∀ a b c → a ∙ (b ∙ c) ≈ (a ∙ b) ∙ (a ∙ c)distr a b c = begina ∙ (b ∙ c) ≈⟨ ∙-cong (sym (idem a)) refl ⟩(a ∙ a) ∙ (b ∙ c) ≈⟨ assoc _ _ _ ⟩a ∙ (a ∙ (b ∙ c)) ≈⟨ ∙-congˡ (sym (assoc _ _ _)) ⟩a ∙ ((a ∙ b) ∙ c) ≈⟨ ∙-congˡ (∙-congʳ (comm _ _)) ⟩a ∙ ((b ∙ a) ∙ c) ≈⟨ ∙-congˡ (assoc _ _ _) ⟩a ∙ (b ∙ (a ∙ c)) ≈⟨ sym (assoc _ _ _) ⟩(a ∙ b) ∙ (a ∙ c) ∎comp-correct : ∀ (v w : Normal n) (ρ : Env n) →⟦ v • w ⟧⇓ ρ ≈ (⟦ v ⟧⇓ ρ ∙ ⟦ w ⟧⇓ ρ)comp-correct [] [] ρ = sym (identityˡ _)comp-correct (true ∷ v) (true ∷ w) (a ∷ ρ) =trans (∙-congˡ (comp-correct v w ρ)) (distr _ _ _)comp-correct (true ∷ v) (false ∷ w) (a ∷ ρ) =trans (∙-congˡ (comp-correct v w ρ)) (sym (assoc _ _ _))comp-correct (false ∷ v) (true ∷ w) (a ∷ ρ) =trans (∙-congˡ (comp-correct v w ρ)) (flip12 _ _ _)comp-correct (false ∷ v) (false ∷ w) (a ∷ ρ) =comp-correct v w ρ-------------------------------------------------------------------------- Normalization-- A normaliser.normalise : Expr n → Normal nnormalise (var x) = sg xnormalise id = emptynormalise (e₁ ⊕ e₂) = normalise e₁ • normalise e₂-- The normaliser preserves the semantics of the expression.normalise-correct : (e : Expr n) (ρ : Env n) →⟦ normalise e ⟧⇓ ρ ≈ ⟦ e ⟧ ρnormalise-correct (var x) ρ = sg-correct x ρnormalise-correct id ρ = empty-correct ρnormalise-correct (e₁ ⊕ e₂) ρ = begin⟦ normalise e₁ • normalise e₂ ⟧⇓ ρ≈⟨ comp-correct (normalise e₁) (normalise e₂) ρ ⟩⟦ normalise e₁ ⟧⇓ ρ ∙ ⟦ normalise e₂ ⟧⇓ ρ≈⟨ ∙-cong (normalise-correct e₁ ρ) (normalise-correct e₂ ρ) ⟩⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ∎-------------------------------------------------------------------------- "Tactic.open module R = Reflectionsetoid var ⟦_⟧ (⟦_⟧⇓ ∘ normalise) normalise-correctpublic using (solve; _⊜_)-- We can decide if two normal forms are /syntactically/ equal.infix 5 _≟__≟_ : (nf₁ nf₂ : Normal n) → Dec (nf₁ ≡ nf₂)nf₁ ≟ nf₂ = Dec.map Pointwise-≡↔≡ (decidable Bool._≟_ nf₁ nf₂)where open Pointwise-- We can also give a sound, but not necessarily complete, procedure-- for determining if two expressions have the same semantics.prove′ : (e₁ e₂ : Expr n) → Maybe (∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρ)prove′ e₁ e₂ =Maybe.map lemma (dec⇒weaklyDec _≟_ (normalise e₁) (normalise e₂))wherelemma : normalise e₁ ≡ normalise e₂ → ∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρlemma eq ρ =R.prove ρ e₁ e₂ (begin⟦ normalise e₁ ⟧⇓ ρ ≡⟨ ≡.cong (λ e → ⟦ e ⟧⇓ ρ) eq ⟩⟦ normalise e₂ ⟧⇓ ρ ∎)-- This procedure can be combined with from-just.prove : ∀ n (e₁ e₂ : Expr n) → From-just (prove′ e₁ e₂)prove _ e₁ e₂ = from-just (prove′ e₁ e₂)-- prove : ∀ n (es : Expr n × Expr n) →-- From-just (uncurry prove′ es)-- prove _ = from-just ∘ uncurry prove′
-------------------------------------------------------------------------- The Agda standard library---- An example of how Algebra.IdempotentCommutativeMonoidSolver can be-- used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Solver.IdempotentCommutativeMonoid.Example whereimport Algebra.Solver.IdempotentCommutativeMonoid as ICM-Solveropen import Data.Bool.Base using (_∨_)open import Data.Bool.Properties using (∨-idempotentCommutativeMonoid)open import Data.Fin.Base using (zero; suc)open import Data.Vec.Base using ([]; _∷_)open import Relation.Binary.PropositionalEquality.Core using (_≡_)open ICM-Solver ∨-idempotentCommutativeMonoidtest : ∀ x y z → (x ∨ y) ∨ (x ∨ z) ≡ (z ∨ y) ∨ xtest a b c = let _∨_ = _⊕_ inprove 3 ((x ∨ y) ∨ (x ∨ z)) ((z ∨ y) ∨ x) (a ∷ b ∷ c ∷ [])wherex = var zeroy = var (suc zero)z = var (suc (suc zero))
-------------------------------------------------------------------------- The Agda standard library---- Solver for equations in commutative monoids---- Adapted from Algebra.Solver.Monoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Solver.CommutativeMonoid {m₁ m₂} (M : CommutativeMonoid m₁ m₂) whereopen import Data.Fin.Base using (Fin; zero; suc)open import Data.Maybe.Base as Maybeusing (Maybe; From-just; from-just)open import Data.Nat as ℕ using (ℕ; zero; suc; _+_)open import Data.Nat.GeneralisedArithmetic using (fold)open import Data.Product.Base using (_×_; uncurry)open import Data.Vec.Base using (Vec; []; _∷_; lookup; replicate)open import Function.Base using (_∘_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Relation.Binary.Reflection as Reflectionimport Relation.Nullary.Decidable as Decimport Data.Vec.Relation.Binary.Pointwise.Inductive as Pointwiseopen import Relation.Binary.Consequences using (dec⇒weaklyDec)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary.Decidable as Dec using (Dec)open CommutativeMonoid Mopen ≈-Reasoning setoidprivatevariablen : ℕ-------------------------------------------------------------------------- Monoid expressions-- There is one constructor for every operation, plus one for-- variables; there may be at most n variables.infixr 5 _⊕_infixr 10 _•_data Expr (n : ℕ) : Set wherevar : Fin n → Expr nid : Expr n_⊕_ : Expr n → Expr n → Expr n-- An environment contains one value for every variable.Env : ℕ → Set _Env n = Vec Carrier n-- The semantics of an expression is a function from an environment to-- a value.⟦_⟧ : Expr n → Env n → Carrier⟦ var x ⟧ ρ = lookup ρ x⟦ id ⟧ ρ = ε⟦ e₁ ⊕ e₂ ⟧ ρ = ⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ-------------------------------------------------------------------------- Normal forms-- A normal form is a vector of multiplicities (a bag).Normal : ℕ → SetNormal n = Vec ℕ n-- The semantics of a normal form.⟦_⟧⇓ : Normal n → Env n → Carrier⟦ [] ⟧⇓ _ = ε⟦ n ∷ v ⟧⇓ (a ∷ ρ) = fold (⟦ v ⟧⇓ ρ) (a ∙_) n-------------------------------------------------------------------------- Constructions on normal forms-- The empty bag.empty : Normal nempty = replicate _ 0-- A singleton bag.sg : (i : Fin n) → Normal nsg zero = 1 ∷ emptysg (suc i) = 0 ∷ sg i-- The composition of normal forms._•_ : (v w : Normal n) → Normal n[] • [] = [](l ∷ v) • (m ∷ w) = l + m ∷ v • w-------------------------------------------------------------------------- Correctness of the constructions on normal forms-- The empty bag stands for the unit ε.empty-correct : (ρ : Env n) → ⟦ empty ⟧⇓ ρ ≈ εempty-correct [] = reflempty-correct (a ∷ ρ) = empty-correct ρ-- The singleton bag stands for a single variable.sg-correct : (x : Fin n) (ρ : Env n) → ⟦ sg x ⟧⇓ ρ ≈ lookup ρ xsg-correct zero (x ∷ ρ) = beginx ∙ ⟦ empty ⟧⇓ ρ ≈⟨ ∙-congˡ (empty-correct ρ) ⟩x ∙ ε ≈⟨ identityʳ _ ⟩x ∎sg-correct (suc x) (m ∷ ρ) = sg-correct x ρ-- Normal form composition corresponds to the composition of the monoid.comp-correct : (v w : Normal n) (ρ : Env n) →⟦ v • w ⟧⇓ ρ ≈ (⟦ v ⟧⇓ ρ ∙ ⟦ w ⟧⇓ ρ)comp-correct [] [] ρ = sym (identityˡ _)comp-correct (l ∷ v) (m ∷ w) (a ∷ ρ) = lemma l m (comp-correct v w ρ)whereflip12 : ∀ a b c → a ∙ (b ∙ c) ≈ b ∙ (a ∙ c)flip12 a b c = begina ∙ (b ∙ c) ≈⟨ sym (assoc _ _ _) ⟩(a ∙ b) ∙ c ≈⟨ ∙-congʳ (comm _ _) ⟩(b ∙ a) ∙ c ≈⟨ assoc _ _ _ ⟩b ∙ (a ∙ c) ∎lemma : ∀ l m {d b c} (p : d ≈ b ∙ c) →fold d (a ∙_) (l + m) ≈ fold b (a ∙_) l ∙ fold c (a ∙_) mlemma zero zero p = plemma zero (suc m) p = trans (∙-congˡ (lemma zero m p)) (flip12 _ _ _)lemma (suc l) m p = trans (∙-congˡ (lemma l m p)) (sym (assoc a _ _))-------------------------------------------------------------------------- Normalization-- A normaliser.normalise : Expr n → Normal nnormalise (var x) = sg xnormalise id = emptynormalise (e₁ ⊕ e₂) = normalise e₁ • normalise e₂-- The normaliser preserves the semantics of the expression.normalise-correct : (e : Expr n) (ρ : Env n) →⟦ normalise e ⟧⇓ ρ ≈ ⟦ e ⟧ ρnormalise-correct (var x) ρ = sg-correct x ρnormalise-correct id ρ = empty-correct ρnormalise-correct (e₁ ⊕ e₂) ρ = begin⟦ normalise e₁ • normalise e₂ ⟧⇓ ρ≈⟨ comp-correct (normalise e₁) (normalise e₂) ρ ⟩⟦ normalise e₁ ⟧⇓ ρ ∙ ⟦ normalise e₂ ⟧⇓ ρ≈⟨ ∙-cong (normalise-correct e₁ ρ) (normalise-correct e₂ ρ) ⟩⟦ e₁ ⟧ ρ ∙ ⟦ e₂ ⟧ ρ∎-------------------------------------------------------------------------- "Tactic.open module R = Reflectionsetoid var ⟦_⟧ (⟦_⟧⇓ ∘ normalise) normalise-correctpublic using (solve; _⊜_)-- We can decide if two normal forms are /syntactically/ equal.infix 5 _≟__≟_ : (nf₁ nf₂ : Normal n) → Dec (nf₁ ≡ nf₂)nf₁ ≟ nf₂ = Dec.map Pointwise-≡↔≡ (decidable ℕ._≟_ nf₁ nf₂)where open Pointwise-- We can also give a sound, but not necessarily complete, procedure-- for determining if two expressions have the same semantics.prove′ : (e₁ e₂ : Expr n) → Maybe (∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρ)prove′ e₁ e₂ =Maybe.map lemma (dec⇒weaklyDec _≟_ (normalise e₁) (normalise e₂))wherelemma : normalise e₁ ≡ normalise e₂ → ∀ ρ → ⟦ e₁ ⟧ ρ ≈ ⟦ e₂ ⟧ ρlemma eq ρ =R.prove ρ e₁ e₂ (begin⟦ normalise e₁ ⟧⇓ ρ ≡⟨ ≡.cong (λ e → ⟦ e ⟧⇓ ρ) eq ⟩⟦ normalise e₂ ⟧⇓ ρ ∎)-- This procedure can be combined with from-just.prove : ∀ n (e₁ e₂ : Expr n) → From-just (prove′ e₁ e₂)prove _ e₁ e₂ = from-just (prove′ e₁ e₂)-- prove : ∀ n (es : Expr n × Expr n) →-- From-just (uncurry prove′ es)-- prove _ = from-just ∘ uncurry prove′
-------------------------------------------------------------------------- The Agda standard library---- An example of how Algebra.CommutativeMonoidSolver can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Solver.CommutativeMonoid.Example whereopen import Relation.Binary.PropositionalEquality.Core using (_≡_)open import Data.Bool.Base using (_∨_)open import Data.Bool.Properties using (∨-commutativeMonoid)open import Data.Fin.Base using (zero; suc)open import Data.Vec.Base using ([]; _∷_)open import Algebra.Solver.CommutativeMonoid ∨-commutativeMonoidtest : ∀ x y z → (x ∨ y) ∨ (x ∨ z) ≡ (z ∨ y) ∨ (x ∨ x)test a b c = let _∨_ = _⊕_ inprove 3 ((x ∨ y) ∨ (x ∨ z)) ((z ∨ y) ∨ (x ∨ x)) (a ∷ b ∷ c ∷ [])wherex = var zeroy = var (suc zero)z = var (suc (suc zero))
-------------------------------------------------------------------------- The Agda standard library---- Finite summations over a semiring------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Semiring)module Algebra.Properties.Semiring.Sum {c} {ℓ} (R : Semiring c ℓ) whereopen import Data.Nat.Base using (zero; suc)open import Data.Vec.Functionalopen Semiring R-------------------------------------------------------------------------- Re-export summation over monoidsopen import Algebra.Properties.CommutativeMonoid.Sum +-commutativeMonoid public-------------------------------------------------------------------------- Properties*-distribˡ-sum : ∀ {n} x (ys : Vector Carrier n) → x * sum ys ≈ sum (map (x *_) ys)*-distribˡ-sum {zero} x ys = zeroʳ x*-distribˡ-sum {suc n} x ys = trans (distribˡ x (head ys) (sum (tail ys))) (+-congˡ (*-distribˡ-sum x (tail ys)))*-distribʳ-sum : ∀ {n} x (ys : Vector Carrier n) → sum ys * x ≈ sum (map (_* x) ys)*-distribʳ-sum {zero} x ys = zeroˡ x*-distribʳ-sum {suc n} x ys = trans (distribʳ x (head ys) (sum (tail ys))) (+-congˡ (*-distribʳ-sum x (tail ys)))
-------------------------------------------------------------------------- The Agda standard library---- Some theory for CancellativeCommutativeSemiring.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Semiring)open import Data.Sum.Base using (reduce)open import Function.Base using (flip)open import Relation.Binary.Definitions using (Symmetric)module Algebra.Properties.Semiring.Primality{a ℓ} (R : Semiring a ℓ)whereopen Semiring R renaming (Carrier to A)open import Algebra.Properties.Semiring.Divisibility R-------------------------------------------------------------------------- Re-export primality definitionsopen import Algebra.Definitions.RawSemiring rawSemiring publicusing (Coprime; Prime; mkPrime; Irreducible; mkIrred)-------------------------------------------------------------------------- Properties of CoprimeCoprime-sym : Symmetric CoprimeCoprime-sym coprime = flip coprime∣1⇒Coprime : ∀ {x} y → x ∣ 1# → Coprime x y∣1⇒Coprime {x} y x∣1 z∣x _ = ∣-trans z∣x x∣1-------------------------------------------------------------------------- Properties of IrreducibleIrreducible⇒≉0 : 0# ≉ 1# → ∀ {p} → Irreducible p → p ≉ 0#Irreducible⇒≉0 0≉1 (mkIrred _ chooseInvertible) p≈0 =0∤1 0≉1 (reduce (chooseInvertible (trans p≈0 (sym (zeroˡ 0#)))))
-------------------------------------------------------------------------- The Agda standard library---- Multiplication by a natural number over a semiring------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Semiring)open import Data.Nat.Base as ℕ using (zero; suc)module Algebra.Properties.Semiring.Mult{a ℓ} (S : Semiring a ℓ) whereopen Semiring S renaming (zero to *-zero)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Definitions _≈_ using (_IdempotentOn_)-------------------------------------------------------------------------- Re-export definition from the monoidopen import Algebra.Properties.Monoid.Mult +-monoid public-------------------------------------------------------------------------- Properties of _×_-- (0 ×_) is (0# *_)×-homo-0# : ∀ x → 0 × x ≈ 0# * x×-homo-0# x = sym (zeroˡ x)-- (1 ×_) is (1# *_)×-homo-1# : ∀ x → 1 × x ≈ 1# * x×-homo-1# x = trans (×-homo-1 x) (sym (*-identityˡ x))-- (n ×_) commutes with _*_×-comm-* : ∀ n x y → x * (n × y) ≈ n × (x * y)×-comm-* zero x y = zeroʳ x×-comm-* (suc n) x y = beginx * (suc n × y) ≡⟨⟩x * (y + n × y) ≈⟨ distribˡ _ _ _ ⟩x * y + x * (n × y) ≈⟨ +-congˡ (×-comm-* n _ _) ⟩x * y + n × (x * y) ≡⟨⟩suc n × (x * y) ∎-- (n ×_) associates with _*_×-assoc-* : ∀ n x y → (n × x) * y ≈ n × (x * y)×-assoc-* zero x y = zeroˡ y×-assoc-* (suc n) x y = begin(suc n × x) * y ≡⟨⟩(x + n × x) * y ≈⟨ distribʳ _ _ _ ⟩x * y + (n × x) * y ≈⟨ +-congˡ (×-assoc-* n _ _) ⟩x * y + n × (x * y) ≡⟨⟩suc n × (x * y) ∎-- (_× x) is homomorphic with respect to _ℕ.*_/_*_ for idempotent x.idem-×-homo-* : ∀ m n {x} → (_*_ IdempotentOn x) → (m × x) * (n × x) ≈ (m ℕ.* n) × xidem-×-homo-* m n {x} idem = begin(m × x) * (n × x) ≈⟨ ×-assoc-* m x (n × x) ⟩m × (x * (n × x)) ≈⟨ ×-congʳ m (×-comm-* n x x) ⟩m × (n × (x * x)) ≈⟨ ×-assocˡ _ m n ⟩(m ℕ.* n) × (x * x) ≈⟨ ×-congʳ (m ℕ.* n) idem ⟩(m ℕ.* n) × x ∎-- (_× 1#) is homomorphic with respect to _ℕ.*_/_*_.×1-homo-* : ∀ m n → (m ℕ.* n) × 1# ≈ (m × 1#) * (n × 1#)×1-homo-* m n = sym (idem-×-homo-* m n (*-identityʳ 1#))-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.11×-identityʳ = ×-homo-1{-# WARNING_ON_USAGE 1×-identityʳ"Warning: 1×-identityʳ was deprecated in v2.1.Please use ×-homo-1 instead. "#-}
-------------------------------------------------------------------------- The Agda standard library---- Multiplication over a semiring optimised for type-checking.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Nat.Base as ℕ using (zero; suc)module Algebra.Properties.Semiring.Mult.TCOptimised{a ℓ} (S : Semiring a ℓ) whereopen Semiring S renaming (zero to *-zero)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Properties.Semiring.Mult S as Uusing () renaming (_×_ to _×ᵤ_)-------------------------------------------------------------------------- Re-export definition from the monoidopen import Algebra.Properties.Monoid.Mult.TCOptimised +-monoid public-------------------------------------------------------------------------- Properties of _×_-- (_×′ 1#) is homomorphic with respect to _ℕ.*_/_*_.×1-homo-* : ∀ m n → (m ℕ.* n) × 1# ≈ (m × 1#) * (n × 1#)×1-homo-* m n = begin(m ℕ.* n) × 1# ≈⟨ ×ᵤ≈× (m ℕ.* n) 1# ⟨(m ℕ.* n) ×ᵤ 1# ≈⟨ U.×1-homo-* m n ⟩(m ×ᵤ 1#) * (n ×ᵤ 1#) ≈⟨ *-cong (×ᵤ≈× m 1#) (×ᵤ≈× n 1#) ⟩(m × 1#) * (n × 1#) ∎
-------------------------------------------------------------------------- The Agda standard library---- Exponentiation defined over a semiring as repeated multiplication------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)import Data.Nat.Properties as ℕmodule Algebra.Properties.Semiring.Exp{a ℓ} (S : Semiring a ℓ) whereopen Semiring Sopen import Relation.Binary.Reasoning.Setoid setoidimport Algebra.Properties.Monoid.Mult *-monoid as Mult-------------------------------------------------------------------------- Definitionopen import Algebra.Definitions.RawSemiring rawSemiring publicusing (_^_)-------------------------------------------------------------------------- Properties^-congˡ : ∀ n → (_^ n) Preserves _≈_ ⟶ _≈_^-congˡ = Mult.×-congʳ^-cong : _^_ Preserves₂ _≈_ ⟶ _≡_ ⟶ _≈_^-cong x≈y u≡v = Mult.×-cong u≡v x≈y^-congʳ : ∀ x → (x ^_) Preserves _≡_ ⟶ _≈_^-congʳ x = Mult.×-congˡ-- xᵐ⁺ⁿ ≈ xᵐxⁿ^-homo-* : ∀ x m n → x ^ (m ℕ.+ n) ≈ (x ^ m) * (x ^ n)^-homo-* = Mult.×-homo-+-- (xᵐ)ⁿ≈xᵐ*ⁿ^-assocʳ : ∀ x m n → (x ^ m) ^ n ≈ x ^ (m ℕ.* n)^-assocʳ x m n rewrite ℕ.*-comm m n = Mult.×-assocˡ x n m-------------------------------------------------------------------------- A lemma using commutativity, needed for the Binomial Theoremy*x^m*y^n≈x^m*y^[n+1] : ∀ {x} {y} (x*y≈y*x : x * y ≈ y * x) →∀ m n → y * (x ^ m * y ^ n) ≈ x ^ m * y ^ suc ny*x^m*y^n≈x^m*y^[n+1] {x} {y} x*y≈y*x = helperwherehelper : ∀ m n → y * (x ^ m * y ^ n) ≈ x ^ m * y ^ suc nhelper zero n = beginy * (x ^ ℕ.zero * y ^ n) ≡⟨⟩y * (1# * y ^ n) ≈⟨ *-congˡ (*-identityˡ (y ^ n)) ⟩y * (y ^ n) ≡⟨⟩y ^ (suc n) ≈⟨ *-identityˡ (y ^ suc n) ⟨1# * y ^ (suc n) ≡⟨⟩x ^ ℕ.zero * y ^ (suc n) ∎helper (suc m) n = beginy * (x ^ suc m * y ^ n) ≡⟨⟩y * ((x * x ^ m) * y ^ n) ≈⟨ *-congˡ (*-assoc x (x ^ m) (y ^ n)) ⟩y * (x * (x ^ m * y ^ n)) ≈⟨ *-assoc y x (x ^ m * y ^ n) ⟨y * x * (x ^ m * y ^ n) ≈⟨ *-congʳ x*y≈y*x ⟨x * y * (x ^ m * y ^ n) ≈⟨ *-assoc x y _ ⟩x * (y * (x ^ m * y ^ n)) ≈⟨ *-congˡ (helper m n) ⟩x * (x ^ m * y ^ suc n) ≈⟨ *-assoc x (x ^ m) (y ^ suc n) ⟨(x * x ^ m) * y ^ suc n ≡⟨⟩x ^ suc m * y ^ suc n ∎
-------------------------------------------------------------------------- The Agda standard library---- Exponentiation over a semiring optimised for tail-recursion.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Nat.Base as ℕ using (zero; suc)import Data.Nat.Properties as ℕopen import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)module Algebra.Properties.Semiring.Exp.TailRecursiveOptimised{a ℓ} (S : Semiring a ℓ) whereopen Semiring S renaming (zero to *-zero)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Properties.Semiring.Exp S as Uusing () renaming (_^_ to _^ᵘ_)-------------------------------------------------------------------------- Re-export definition from the monoidopen import Algebra.Definitions.RawSemiring rawSemiring publicusing (_^[_]*_)renaming (_^ᵗ_ to _^_)-------------------------------------------------------------------------- Properties of _^[_]*_^[]*-cong : ∀ n → (_^[ n ]*_) Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_^[]*-cong zero x≈y u≈v = u≈v^[]*-cong (suc n) x≈y u≈v = ^[]*-cong n x≈y (*-cong x≈y u≈v)^[]*-congʳ : ∀ x n → (x ^[ n ]*_) Preserves _≈_ ⟶ _≈_^[]*-congʳ x n = ^[]*-cong n reflx^[m]*[x*y]≈x*x^[m]*y : ∀ x m y → x ^[ m ]* (x * y) ≈ x * x ^[ m ]* yx^[m]*[x*y]≈x*x^[m]*y x zero y = reflx^[m]*[x*y]≈x*x^[m]*y x (suc m) y = x^[m]*[x*y]≈x*x^[m]*y x m (x * y)x^[m]*y*z≈x^[m]*[y*z] : ∀ x m y z → x ^[ m ]* y * z ≈ x ^[ m ]* (y * z)x^[m]*y*z≈x^[m]*[y*z] x zero y z = reflx^[m]*y*z≈x^[m]*[y*z] x (suc m) y z = beginx ^[ suc m ]* y * z ≈⟨ x^[m]*y*z≈x^[m]*[y*z] x m (x * y) z ⟩x ^[ m ]* ((x * y) * z) ≈⟨ ^[]*-congʳ x m (*-assoc x y z) ⟩x ^[ m ]* (x * (y * z)) ∎x^[m+n]*y≈x^[m]*x^[n]*y : ∀ x m n y → x ^[ (m ℕ.+ n) ]* y ≈ x ^[ m ]* x ^[ n ]* yx^[m+n]*y≈x^[m]*x^[n]*y x zero n y = reflx^[m+n]*y≈x^[m]*x^[n]*y x (suc m) n y = beginx ^[ (m ℕ.+ n) ]* (x * y) ≈⟨ x^[m+n]*y≈x^[m]*x^[n]*y x m n (x * y) ⟩x ^[ m ]* x ^[ n ]* (x * y) ≈⟨ ^[]*-congʳ x m (x^[m]*[x*y]≈x*x^[m]*y x n y) ⟩x ^[ suc m ]* x ^[ n ]* y ∎x^m*y≈x^[m]*y : ∀ x m y → x ^ m * y ≈ x ^[ m ]* yx^m*y≈x^[m]*y x m y = beginx ^ m * y ≈⟨ x^[m]*y*z≈x^[m]*[y*z] x m 1# y ⟩x ^[ m ]* (1# * y) ≈⟨ ^[]*-congʳ x m (*-identityˡ y) ⟩x ^[ m ]* y ∎-------------------------------------------------------------------------- Properties of _^_x^0≈1 : ∀ x → x ^ zero ≈ 1#x^0≈1 x = reflx^[m+1]≈x*[x^m] : ∀ x m → x ^ (suc m) ≈ x * x ^ mx^[m+1]≈x*[x^m] x m = x^[m]*[x*y]≈x*x^[m]*y x m 1#x^[m+n]≈[x^m]*[x^n] : ∀ x m n → x ^ (m ℕ.+ n) ≈ x ^ m * x ^ nx^[m+n]≈[x^m]*[x^n] x m n = beginx ^ (m ℕ.+ n) ≈⟨ x^[m+n]*y≈x^[m]*x^[n]*y x m n 1# ⟩x ^[ m ]* (x ^ n) ≈⟨ x^m*y≈x^[m]*y x m (x ^ n) ⟨x ^ m * x ^ n ∎^≈^ᵘ : ∀ x m → x ^ m ≈ x ^ᵘ m^≈^ᵘ x zero = refl^≈^ᵘ x (suc m) = beginx ^ (suc m) ≈⟨ x^[m+1]≈x*[x^m] x m ⟩x * x ^ m ≈⟨ *-congˡ (^≈^ᵘ x m) ⟩x * x ^ᵘ m ∎
-------------------------------------------------------------------------- The Agda standard library---- Exponentiation over a semiring optimised for type-checking.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Nat.Base as ℕ using (zero; suc)import Data.Nat.Properties as ℕopen import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Core using (_≡_)module Algebra.Properties.Semiring.Exp.TCOptimised{a ℓ} (S : Semiring a ℓ) whereopen Semiring S renaming (zero to *-zero)open import Relation.Binary.Reasoning.Setoid setoidimport Algebra.Properties.Monoid.Mult.TCOptimised *-monoid as Multopen import Algebra.Properties.Semiring.Exp S as Uusing () renaming (_^_ to _^ᵤ_)-------------------------------------------------------------------------- Re-export definition from the monoidopen import Algebra.Definitions.RawSemiring rawSemiring publicusing () renaming (_^′_ to _^_)-------------------------------------------------------------------------- Properties of _^_^-congˡ : ∀ n → (_^ n) Preserves _≈_ ⟶ _≈_^-congˡ = Mult.×-congʳ^-cong : _^_ Preserves₂ _≈_ ⟶ _≡_ ⟶ _≈_^-cong x≈y u≡v = Mult.×-cong u≡v x≈y-- xᵐ⁺ⁿ ≈ xᵐxⁿ^-homo-* : ∀ x m n → x ^ (m ℕ.+ n) ≈ (x ^ m) * (x ^ n)^-homo-* = Mult.×-homo-+-- (xᵐ)ⁿ≈xᵐ*ⁿ^-assocʳ : ∀ x m n → (x ^ m) ^ n ≈ x ^ (m ℕ.* n)^-assocʳ x m n rewrite ℕ.*-comm m n = Mult.×-assocˡ x n m
-------------------------------------------------------------------------- The Agda standard library---- Properties of divisibility over semirings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Semiring)import Algebra.Properties.Monoid.Divisibility as MonoidDivisibilityopen import Data.Product.Base using (_,_)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)module Algebra.Properties.Semiring.Divisibility{a ℓ} (R : Semiring a ℓ) whereopen Semiring R-------------------------------------------------------------------------- Re-exporting divisibility over monoidsopen MonoidDivisibility *-monoid publicrenaming (ε∣_ to 1∣_)-------------------------------------------------------------------------- Divisibility properties specific to semirings.infixr 8 _∣0_∣0 : ∀ x → x ∣ 0#x ∣0 = 0# , zeroˡ x0∣x⇒x≈0 : ∀ {x} → 0# ∣ x → x ≈ 0#0∣x⇒x≈0 (q , q*0≈x) = trans (sym q*0≈x) (zeroʳ q)x∣y∧y≉0⇒x≉0 : ∀ {x y} → x ∣ y → y ≉ 0# → x ≉ 0#x∣y∧y≉0⇒x≉0 x∣y y≉0 x≈0 = y≉0 (0∣x⇒x≈0 (∣-respˡ x≈0 x∣y))0∤1 : 0# ≉ 1# → 0# ∤ 1#0∤1 0≉1 (q , q*0≈1) = 0≉1 (trans (sym (zeroʳ q)) q*0≈1)
-------------------------------------------------------------------------- The Agda standard library---- The Binomial Theorem for *-commuting elements in a Semiring---- Freely adapted from PR #1287 by Maciej Piechotka (@uzytkownik)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Semiring)open import Data.Bool.Base using (true)open import Data.Nat.Base as ℕ hiding (_+_; _*_; _^_)open import Data.Nat.Combinatoricsusing (_C_; nCn≡1; nC1≡n; nCk+nC[k+1]≡[n+1]C[k+1])open import Data.Nat.Properties as ℕusing (<⇒<ᵇ; n<1+n; n∸n≡0; +-∸-assoc)open import Data.Fin.Base as Finusing (Fin; zero; suc; toℕ; fromℕ; inject₁)open import Data.Fin.Patterns using (0F)open import Data.Fin.Properties as Finusing (toℕ<n; toℕ-fromℕ; toℕ-inject₁)open import Data.Fin.Relation.Unary.Topusing (view; ‵fromℕ; ‵inject₁; view-fromℕ; view-inject₁)open import Function.Base using (_∘_)open import Relation.Binary.PropositionalEquality.Core as ≡using (_≡_; _≢_; cong)module Algebra.Properties.Semiring.Binomial{a ℓ} (S : Semiring a ℓ)(open Semiring S)(x y : Carrier)whereopen import Algebra.Definitions _≈_open import Algebra.Properties.Semiring.Sum Sopen import Algebra.Properties.Semiring.Mult Sopen import Algebra.Properties.Semiring.Exp Sopen import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Definitions-- Note - `n` could be implicit in many of these definitions, but the-- code is more readable if left explicit.binomial : (n : ℕ) → Fin (suc n) → Carrierbinomial n k = (x ^ toℕ k) * (y ^ (n ∸ toℕ k))binomialTerm : (n : ℕ) → Fin (suc n) → CarrierbinomialTerm n k = (n C toℕ k) × binomial n kbinomialExpansion : ℕ → CarrierbinomialExpansion n = ∑[ k ≤ n ] (binomialTerm n k)term₁ : (n : ℕ) → Fin (suc (suc n)) → Carrierterm₁ n zero = 0#term₁ n (suc k) = x * (binomialTerm n k)term₂ : (n : ℕ) → Fin (suc (suc n)) → Carrierterm₂ n k with view k... | ‵fromℕ = 0#... | ‵inject₁ j = y * binomialTerm n jsum₁ : ℕ → Carriersum₁ n = ∑[ k ≤ suc n ] term₁ n ksum₂ : ℕ → Carriersum₂ n = ∑[ k ≤ suc n ] term₂ n k-------------------------------------------------------------------------- Propertiesterm₂[n,n+1]≈0# : ∀ n → term₂ n (fromℕ (suc n)) ≈ 0#term₂[n,n+1]≈0# n rewrite view-fromℕ (suc n) = refllemma₁ : ∀ n → x * binomialExpansion n ≈ sum₁ nlemma₁ n = beginx * binomialExpansion n ≈⟨ *-distribˡ-sum x (binomialTerm n) ⟩∑[ i ≤ n ] (x * binomialTerm n i) ≈⟨ +-identityˡ _ ⟨0# + ∑[ i ≤ n ] (x * binomialTerm n i) ≡⟨⟩0# + ∑[ i ≤ n ] term₁ n (suc i) ≡⟨⟩sum₁ n ∎lemma₂ : ∀ n → y * binomialExpansion n ≈ sum₂ nlemma₂ n = beginy * binomialExpansion n ≈⟨ *-distribˡ-sum y (binomialTerm n) ⟩∑[ i ≤ n ] (y * binomialTerm n i) ≈⟨ +-identityʳ _ ⟨∑[ i ≤ n ] (y * binomialTerm n i) + 0# ≈⟨ +-cong (sum-cong-≋ lemma₂-inject₁) (sym (term₂[n,n+1]≈0# n)) ⟩(∑[ i ≤ n ] term₂-inject₁ i) + term₂ n [n+1] ≈⟨ sum-init-last (term₂ n) ⟨sum (term₂ n) ≡⟨⟩sum₂ n ∎where[n+1] = fromℕ (suc n)term₂-inject₁ : (i : Fin (suc n)) → Carrierterm₂-inject₁ i = term₂ n (inject₁ i)lemma₂-inject₁ : ∀ i → y * binomialTerm n i ≈ term₂-inject₁ ilemma₂-inject₁ i rewrite view-inject₁ i = refl-------------------------------------------------------------------------- Next, a lemma which is independent of commutativityx*lemma : ∀ {n} (i : Fin (suc n)) →x * binomialTerm n i ≈ (n C toℕ i) × binomial (suc n) (suc i)x*lemma {n} i = beginx * binomialTerm n i ≡⟨⟩x * ((n C k) × (x ^ k * y ^ (n ∸ k))) ≈⟨ *-congˡ (×-assoc-* (n C k) _ _) ⟨x * ((n C k) × x ^ k * y ^ (n ∸ k)) ≈⟨ *-assoc x ((n C k) × x ^ k) _ ⟨(x * (n C k) × x ^ k) * y ^ (n ∸ k) ≈⟨ *-congʳ (×-comm-* (n C k) _ _) ⟩(n C k) × x ^ (suc k) * y ^ (n ∸ k) ≡⟨⟩(n C k) × x ^ (suc k) * y ^ (suc n ∸ suc k) ≈⟨ ×-assoc-* (n C k) _ _ ⟩(n C k) × binomial (suc n) (suc i) ∎where k = toℕ i-------------------------------------------------------------------------- Next, a lemma which does require commutativityy*lemma : x * y ≈ y * x → ∀ {n : ℕ} (j : Fin n) →y * binomialTerm n (suc j) ≈ (n C toℕ (suc j)) × binomial (suc n) (suc (inject₁ j))y*lemma x*y≈y*x {n} j = beginy * binomialTerm n (suc j)≈⟨ ×-comm-* nC[j+1] y (binomial n (suc j)) ⟩nC[j+1] × (y * binomial n (suc j))≈⟨ ×-congʳ nC[j+1] (y*x^m*y^n≈x^m*y^[n+1] x*y≈y*x [j+1] [n-j-1]) ⟩nC[j+1] × (x ^ [j+1] * y ^ [n-j])≈⟨ ×-congʳ nC[j+1] (*-congʳ (^-congʳ x (cong suc k≡j))) ⟨nC[j+1] × (x ^ [k+1] * y ^ [n-j])≈⟨ ×-congʳ nC[j+1] (*-congˡ (^-congʳ y [n-k]≡[n-j])) ⟨nC[j+1] × (x ^ [k+1] * y ^ [n-k])≡⟨⟩nC[j+1] × (x ^ [k+1] * y ^ [n+1]-[k+1])≡⟨⟩(n C toℕ (suc j)) × binomial (suc n) (suc i) ∎wherei = inject₁ jk = toℕ i[k+1] = ℕ.suc k[j+1] = toℕ (suc j)[n-k] = n ∸ k[n+1]-[k+1] = [n-k][n-j-1] = n ∸ [j+1][n-j] = ℕ.suc [n-j-1]nC[j+1] = n C [j+1]k≡j : k ≡ toℕ jk≡j = toℕ-inject₁ j[n-k]≡[n-j] : [n-k] ≡ [n-j][n-k]≡[n-j] = ≡.trans (cong (n ∸_) k≡j) (+-∸-assoc 1 (toℕ<n j))-------------------------------------------------------------------------- Now, a lemma characterising the sum of the term₁ and term₂ expressionsprivaten<ᵇ1+n : ∀ n → (n ℕ.<ᵇ suc n) ≡ truen<ᵇ1+n n with true ← n ℕ.<ᵇ suc n | _ ← <⇒<ᵇ (n<1+n n) = ≡.reflterm₁+term₂≈term : x * y ≈ y * x → ∀ n i → term₁ n i + term₂ n i ≈ binomialTerm (suc n) iterm₁+term₂≈term x*y≈y*x n 0F = beginterm₁ n 0F + term₂ n 0F ≡⟨⟩0# + y * (1 × (1# * y ^ n)) ≈⟨ +-identityˡ _ ⟩y * (1 × (1# * y ^ n)) ≈⟨ *-congˡ (+-identityʳ (1# * y ^ n)) ⟩y * (1# * y ^ n) ≈⟨ *-congˡ (*-identityˡ (y ^ n)) ⟩y * y ^ n ≡⟨⟩y ^ suc n ≈⟨ *-identityˡ (y ^ suc n) ⟨1# * y ^ suc n ≈⟨ +-identityʳ (1# * y ^ suc n) ⟨1 × (1# * y ^ suc n) ≡⟨⟩binomialTerm (suc n) 0F ∎term₁+term₂≈term x*y≈y*x n (suc i) with view i... | ‵fromℕ {n}{- remembering that i = fromℕ n, definitionally -}rewrite toℕ-fromℕ n| nCn≡1 n| n∸n≡0 n| n<ᵇ1+n n= beginx * ((x ^ n * 1#) + 0#) + 0# ≈⟨ +-identityʳ _ ⟩x * ((x ^ n * 1#) + 0#) ≈⟨ *-congˡ (+-identityʳ _) ⟩x * (x ^ n * 1#) ≈⟨ *-assoc _ _ _ ⟨x * x ^ n * 1# ≈⟨ +-identityʳ _ ⟨1 × (x * x ^ n * 1#) ∎... | ‵inject₁ j{- remembering that i = inject₁ j, definitionally -}= begin(x * binomialTerm n i) + (y * binomialTerm n (suc j))≈⟨ +-cong (x*lemma i) (y*lemma x*y≈y*x j) ⟩(nCk × [x^k+1]*[y^n-k]) + (nC[j+1] × [x^k+1]*[y^n-k])≈⟨ +-congˡ (×-congˡ nC[k+1]≡nC[j+1]) ⟨(nCk × [x^k+1]*[y^n-k]) + (nC[k+1] × [x^k+1]*[y^n-k])≈⟨ ×-homo-+ [x^k+1]*[y^n-k] nCk nC[k+1] ⟨(nCk ℕ.+ nC[k+1]) × [x^k+1]*[y^n-k]≡⟨ cong (_× [x^k+1]*[y^n-k]) (nCk+nC[k+1]≡[n+1]C[k+1] n k) ⟩((suc n) C (suc k)) × [x^k+1]*[y^n-k]≡⟨⟩binomialTerm (suc n) (suc i) ∎wherek = toℕ i[k+1] = ℕ.suc k[j+1] = toℕ (suc j)nCk = n C knC[k+1] = n C [k+1]nC[j+1] = n C [j+1][x^k+1]*[y^n-k] = binomial (suc n) (suc i)nC[k+1]≡nC[j+1] : nC[k+1] ≡ nC[j+1]nC[k+1]≡nC[j+1] = cong ((n C_) ∘ suc) (toℕ-inject₁ j)-------------------------------------------------------------------------- Finally, the main resulttheorem : x * y ≈ y * x → ∀ n → (x + y) ^ n ≈ binomialExpansion ntheorem x*y≈y*x zero = begin(x + y) ^ 0 ≡⟨⟩1# ≈⟨ ×-homo-1 1# ⟨1 × 1# ≈⟨ *-identityʳ (1 × 1#) ⟨(1 × 1#) * 1# ≈⟨ ×-assoc-* 1 1# 1# ⟩1 × (1# * 1#) ≡⟨⟩1 × (x ^ 0 * y ^ 0) ≈⟨ +-identityʳ _ ⟨1 × (x ^ 0 * y ^ 0) + 0# ≡⟨⟩(0 C 0) × (x ^ 0 * y ^ 0) + 0# ≡⟨⟩binomialExpansion 0 ∎theorem x*y≈y*x n+1@(suc n) = begin(x + y) ^ n+1 ≡⟨⟩(x + y) * (x + y) ^ n ≈⟨ *-congˡ (theorem x*y≈y*x n) ⟩(x + y) * binomialExpansion n ≈⟨ distribʳ _ _ _ ⟩x * binomialExpansion n + y * binomialExpansion n ≈⟨ +-cong (lemma₁ n) (lemma₂ n) ⟩sum₁ n + sum₂ n ≈⟨ ∑-distrib-+ (term₁ n) (term₂ n) ⟨∑[ i ≤ n+1 ] (term₁ n i + term₂ n i) ≈⟨ sum-cong-≋ (term₁+term₂≈term x*y≈y*x n) ⟩∑[ i ≤ n+1 ] binomialTerm n+1 i ≡⟨⟩binomialExpansion n+1 ∎
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Algebra.Lattice.Properties.Semilattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Latticemodule Algebra.Properties.Semilattice {c ℓ} (L : Semilattice c ℓ) whereopen import Algebra.Lattice.Properties.Semilattice L public{-# WARNING_ON_IMPORT"Algebra.Properties.Semilattice was deprecated in v2.0.Use Algebra.Lattice.Properties.Semilattice instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some theory for Semigroup------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Semigroup)module Algebra.Properties.Semigroup {a ℓ} (S : Semigroup a ℓ) whereopen Semigroup Sopen import Algebra.Definitions _≈_open import Data.Product.Base using (_,_)x∙yz≈xy∙z : ∀ x y z → x ∙ (y ∙ z) ≈ (x ∙ y) ∙ zx∙yz≈xy∙z x y z = sym (assoc x y z)alternativeˡ : LeftAlternative _∙_alternativeˡ x y = assoc x x yalternativeʳ : RightAlternative _∙_alternativeʳ x y = sym (assoc x y y)alternative : Alternative _∙_alternative = alternativeˡ , alternativeʳflexible : Flexible _∙_flexible x y = assoc x y x
-------------------------------------------------------------------------- The Agda standard library---- Properties of divisibility over semigroups------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Semigroup)open import Data.Product.Base using (_,_)open import Relation.Binary.Definitions using (Transitive)module Algebra.Properties.Semigroup.Divisibility{a ℓ} (S : Semigroup a ℓ) whereopen Semigroup S-------------------------------------------------------------------------- Re-export magma divisibilityopen import Algebra.Properties.Magma.Divisibility magma public-------------------------------------------------------------------------- Properties of _∣_∣-trans : Transitive _∣_∣-trans (p , px≈y) (q , qy≈z) =q ∙ p , trans (assoc q p _) (trans (∙-congˡ px≈y) qy≈z)-------------------------------------------------------------------------- Properties of _∣∣_∣∣-trans : Transitive _∣∣_∣∣-trans (x∣y , y∣x) (y∣z , z∣y) = ∣-trans x∣y y∣z , ∣-trans z∣y y∣x
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of RingWithoutOne------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Properties.RingWithoutOne {r₁ r₂} (R : RingWithoutOne r₁ r₂) whereopen RingWithoutOne Rimport Algebra.Properties.AbelianGroup as AbelianGroupPropertiesopen import Function.Base using (_$_)open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Export properties of abelian groupsopen AbelianGroupProperties +-abelianGroup publicrenaming( ε⁻¹≈ε to -0#≈0#; ∙-cancelˡ to +-cancelˡ; ∙-cancelʳ to +-cancelʳ; ∙-cancel to +-cancel; ⁻¹-involutive to -‿involutive; ⁻¹-injective to -‿injective; ⁻¹-anti-homo-∙ to -‿anti-homo-+; identityˡ-unique to +-identityˡ-unique; identityʳ-unique to +-identityʳ-unique; identity-unique to +-identity-unique; inverseˡ-unique to +-inverseˡ-unique; inverseʳ-unique to +-inverseʳ-unique; ⁻¹-∙-comm to -‿+-comm)-‿distribˡ-* : ∀ x y → - (x * y) ≈ - x * y-‿distribˡ-* x y = sym $ begin- x * y ≈⟨ +-identityʳ (- x * y) ⟨- x * y + 0# ≈⟨ +-congˡ $ -‿inverseʳ (x * y) ⟨- x * y + (x * y + - (x * y)) ≈⟨ +-assoc (- x * y) (x * y) (- (x * y)) ⟨- x * y + x * y + - (x * y) ≈⟨ +-congʳ $ distribʳ y (- x) x ⟨(- x + x) * y + - (x * y) ≈⟨ +-congʳ $ *-congʳ $ -‿inverseˡ x ⟩0# * y + - (x * y) ≈⟨ +-congʳ $ zeroˡ y ⟩0# + - (x * y) ≈⟨ +-identityˡ (- (x * y)) ⟩- (x * y) ∎-‿distribʳ-* : ∀ x y → - (x * y) ≈ x * - y-‿distribʳ-* x y = sym $ beginx * - y ≈⟨ +-identityˡ (x * - y) ⟨0# + x * - y ≈⟨ +-congʳ $ -‿inverseˡ (x * y) ⟨- (x * y) + x * y + x * - y ≈⟨ +-assoc (- (x * y)) (x * y) (x * - y) ⟩- (x * y) + (x * y + x * - y) ≈⟨ +-congˡ $ distribˡ x y (- y) ⟨- (x * y) + x * (y + - y) ≈⟨ +-congˡ $ *-congˡ $ -‿inverseʳ y ⟩- (x * y) + x * 0# ≈⟨ +-congˡ $ zeroʳ x ⟩- (x * y) + 0# ≈⟨ +-identityʳ (- (x * y)) ⟩- (x * y) ∎x+x≈x⇒x≈0 : ∀ x → x + x ≈ x → x ≈ 0#x+x≈x⇒x≈0 x eq = +-identityˡ-unique x x eqx[y-z]≈xy-xz : ∀ x y z → x * (y - z) ≈ x * y - x * zx[y-z]≈xy-xz x y z = beginx * (y - z) ≈⟨ distribˡ x y (- z) ⟩x * y + x * - z ≈⟨ +-congˡ (sym (-‿distribʳ-* x z)) ⟩x * y - x * z ∎[y-z]x≈yx-zx : ∀ x y z → (y - z) * x ≈ (y * x) - (z * x)[y-z]x≈yx-zx x y z = begin(y - z) * x ≈⟨ distribʳ x y (- z) ⟩y * x + - z * x ≈⟨ +-congˡ (sym (-‿distribˡ-* z x)) ⟩y * x - z * x ∎
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of Rings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Ring)module Algebra.Properties.Ring {r₁ r₂} (R : Ring r₁ r₂) whereopen Ring Rimport Algebra.Properties.RingWithoutOne as RingWithoutOnePropertiesopen import Function.Base using (_$_)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Definitions _≈_-------------------------------------------------------------------------- Export properties of rings without a 1#.open RingWithoutOneProperties ringWithoutOne public-------------------------------------------------------------------------- Extra properties of 1#-1*x≈-x : ∀ x → - 1# * x ≈ - x-1*x≈-x x = begin- 1# * x ≈⟨ -‿distribˡ-* 1# x ⟨- (1# * x) ≈⟨ -‿cong ( *-identityˡ x ) ⟩- x ∎
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of Quasigroup------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Quasigroup)module Algebra.Properties.Quasigroup {q₁ q₂} (Q : Quasigroup q₁ q₂) whereopen Quasigroup Qopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoidopen import Data.Product.Base using (_,_)cancelˡ : LeftCancellative _∙_cancelˡ x y z eq = beginy ≈⟨ leftDividesʳ x y ⟨x \\ (x ∙ y) ≈⟨ \\-congˡ eq ⟩x \\ (x ∙ z) ≈⟨ leftDividesʳ x z ⟩z ∎cancelʳ : RightCancellative _∙_cancelʳ x y z eq = beginy ≈⟨ rightDividesʳ x y ⟨(y ∙ x) // x ≈⟨ //-congʳ eq ⟩(z ∙ x) // x ≈⟨ rightDividesʳ x z ⟩z ∎cancel : Cancellative _∙_cancel = cancelˡ , cancelʳy≈x\\z : ∀ x y z → x ∙ y ≈ z → y ≈ x \\ zy≈x\\z x y z eq = beginy ≈⟨ leftDividesʳ x y ⟨x \\ (x ∙ y) ≈⟨ \\-congˡ eq ⟩x \\ z ∎x≈z//y : ∀ x y z → x ∙ y ≈ z → x ≈ z // yx≈z//y x y z eq = beginx ≈⟨ rightDividesʳ y x ⟨(x ∙ y) // y ≈⟨ //-congʳ eq ⟩z // y ∎
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (MoufangLoop)module Algebra.Properties.MoufangLoop {a ℓ} (M : MoufangLoop a ℓ) whereopen MoufangLoop Mopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoidopen import Data.Product.Base using (_,_)alternativeˡ : LeftAlternative _∙_alternativeˡ x y = begin(x ∙ x) ∙ y ≈⟨ ∙-congʳ (∙-congˡ (sym (identityˡ x))) ⟩(x ∙ (ε ∙ x)) ∙ y ≈⟨ sym (leftBol x ε y) ⟩x ∙ (ε ∙ (x ∙ y)) ≈⟨ ∙-congˡ (identityˡ ((x ∙ y))) ⟩x ∙ (x ∙ y) ∎alternativeʳ : RightAlternative _∙_alternativeʳ x y = beginx ∙ (y ∙ y) ≈⟨ ∙-congˡ(∙-congʳ(sym (identityʳ y))) ⟩x ∙ ((y ∙ ε) ∙ y) ≈⟨ sym (rightBol y ε x) ⟩((x ∙ y) ∙ ε ) ∙ y ≈⟨ ∙-congʳ (identityʳ ((x ∙ y))) ⟩(x ∙ y) ∙ y ∎alternative : Alternative _∙_alternative = alternativeˡ , alternativeʳflex : Flexible _∙_flex x y = begin(x ∙ y) ∙ x ≈⟨ ∙-congˡ (sym (identityˡ x)) ⟩(x ∙ y) ∙ (ε ∙ x) ≈⟨ identical y ε x ⟩x ∙ ((y ∙ ε) ∙ x) ≈⟨ ∙-congˡ (∙-congʳ (identityʳ y)) ⟩x ∙ (y ∙ x) ∎z∙xzy≈zxz∙y : ∀ x y z → (z ∙ (x ∙ (z ∙ y))) ≈ (((z ∙ x) ∙ z) ∙ y)z∙xzy≈zxz∙y x y z = sym (begin((z ∙ x) ∙ z) ∙ y ≈⟨ (∙-congʳ (flex z x )) ⟩(z ∙ (x ∙ z)) ∙ y ≈⟨ sym (leftBol z x y) ⟩z ∙ (x ∙ (z ∙ y)) ∎)x∙zyz≈xzy∙z : ∀ x y z → (x ∙ (z ∙ (y ∙ z))) ≈ (((x ∙ z) ∙ y) ∙ z)x∙zyz≈xzy∙z x y z = beginx ∙ (z ∙ (y ∙ z)) ≈⟨ (∙-congˡ (sym (flex z y ))) ⟩x ∙ ((z ∙ y) ∙ z) ≈⟨ sym (rightBol z y x) ⟩((x ∙ z) ∙ y) ∙ z ∎z∙xyz≈zxy∙z : ∀ x y z → (z ∙ ((x ∙ y) ∙ z)) ≈ ((z ∙ (x ∙ y)) ∙ z)z∙xyz≈zxy∙z x y z = sym (flex z (x ∙ y))
-------------------------------------------------------------------------- The Agda standard library---- Finite summations over a monoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Monoid)module Algebra.Properties.Monoid.Sum {a ℓ} (M : Monoid a ℓ) whereopen import Data.Nat.Base as ℕ using (ℕ; zero; suc; NonZero)open import Data.Vec.Functional as Vector using (Vector; replicate; init;last; head; tail)open import Data.Fin.Base using (zero; suc)open import Function.Base using (_∘_)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≗_; _≡_)open Monoid Mrenaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congˡ to +-congˡ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Data.Vec.Functional.Relation.Binary.Equality.Setoid setoidopen import Algebra.Properties.Monoid.Mult Mopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Definitionopen import Algebra.Definitions.RawMonoid rawMonoid publicusing (sum)-------------------------------------------------------------------------- An alternative mathematical-style syntax for sumₜinfixl 10 sum-syntax sum⁺-syntaxsum-syntax : ∀ n → Vector Carrier n → Carriersum-syntax _ = sumsyntax sum-syntax n (λ i → x) = ∑[ i < n ] xsum⁺-syntax = sum-syntax ∘ sucsyntax sum⁺-syntax n (λ i → x) = ∑[ i ≤ n ] x-------------------------------------------------------------------------- Propertiessum-cong-≋ : ∀ {n} → sum {n} Preserves _≋_ ⟶ _≈_sum-cong-≋ {zero} xs≋ys = reflsum-cong-≋ {suc n} xs≋ys = +-cong (xs≋ys zero) (sum-cong-≋ (xs≋ys ∘ suc))sum-cong-≗ : ∀ {n} → sum {n} Preserves _≗_ ⟶ _≡_sum-cong-≗ {zero} xs≗ys = ≡.reflsum-cong-≗ {suc n} xs≗ys = ≡.cong₂ _+_ (xs≗ys zero) (sum-cong-≗ (xs≗ys ∘ suc))sum-replicate : ∀ n {x} → sum (replicate n x) ≈ n × xsum-replicate zero = reflsum-replicate (suc n) = +-congˡ (sum-replicate n)sum-replicate-idem : ∀ {x} → _+_ IdempotentOn x →∀ n → .{{_ : NonZero n}} → sum (replicate n x) ≈ xsum-replicate-idem idem n = trans (sum-replicate n) (×-idem idem n)sum-replicate-zero : ∀ n → sum (replicate n 0#) ≈ 0#sum-replicate-zero zero = reflsum-replicate-zero (suc n) = sum-replicate-idem (+-identityˡ 0#) (suc n)-- When summing over a `Vector`, we can pull out last elementsum-init-last : ∀ {n} (t : Vector Carrier (suc n)) → sum t ≈ sum (init t) + last tsum-init-last {zero} t = begint₀ + 0# ≈⟨ +-identityʳ t₀ ⟩t₀ ≈⟨ +-identityˡ t₀ ⟨0# + t₀ ∎ where t₀ = t zerosum-init-last {suc n} t = begint₀ + ∑t ≈⟨ +-congˡ (sum-init-last (tail t)) ⟩t₀ + (∑t′ + tₗ) ≈⟨ +-assoc _ _ _ ⟨(t₀ + ∑t′) + tₗ ∎wheret₀ = head ttₗ = last t∑t = sum (tail t)∑t′ = sum (tail (init t))
-------------------------------------------------------------------------- The Agda standard library---- Multiplication over a monoid (i.e. repeated addition)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Monoid)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; NonZero)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)module Algebra.Properties.Monoid.Mult {a ℓ} (M : Monoid a ℓ) where-- View of the monoid operator as additionopen Monoid Mrenaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congʳ to +-congʳ; ∙-congˡ to +-congˡ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Definitions _≈_-------------------------------------------------------------------------- Definitionopen import Algebra.Definitions.RawMonoid rawMonoid publicusing (_×_)-------------------------------------------------------------------------- Properties of _×_×-congʳ : ∀ n → (n ×_) Preserves _≈_ ⟶ _≈_×-congʳ 0 x≈x′ = refl×-congʳ (suc n) x≈x′ = +-cong x≈x′ (×-congʳ n x≈x′)×-cong : _×_ Preserves₂ _≡_ ⟶ _≈_ ⟶ _≈_×-cong {n} ≡.refl x≈x′ = ×-congʳ n x≈x′×-congˡ : ∀ {x} → (_× x) Preserves _≡_ ⟶ _≈_×-congˡ m≡n = ×-cong m≡n refl-- _×_ is homomorphic with respect to _ℕ+_/_+_.×-homo-0 : ∀ x → 0 × x ≈ 0#×-homo-0 x = refl×-homo-1 : ∀ x → 1 × x ≈ x×-homo-1 = +-identityʳ×-homo-+ : ∀ x m n → (m ℕ.+ n) × x ≈ m × x + n × x×-homo-+ x 0 n = sym (+-identityˡ (n × x))×-homo-+ x (suc m) n = beginx + (m ℕ.+ n) × x ≈⟨ +-cong refl (×-homo-+ x m n) ⟩x + (m × x + n × x) ≈⟨ sym (+-assoc x (m × x) (n × x)) ⟩x + m × x + n × x ∎×-idem : ∀ {c} → _+_ IdempotentOn c →∀ n → .{{_ : NonZero n}} → n × c ≈ c×-idem {c} idem (suc zero) = +-identityʳ c×-idem {c} idem (suc n@(suc _)) = beginc + (n × c) ≈⟨ +-congˡ (×-idem idem n ) ⟩c + c ≈⟨ idem ⟩c ∎×-assocˡ : ∀ x m n → m × (n × x) ≈ (m ℕ.* n) × x×-assocˡ x zero n = refl×-assocˡ x (suc m) n = beginn × x + m × n × x ≈⟨ +-congˡ (×-assocˡ x m n) ⟩n × x + (m ℕ.* n) × x ≈⟨ ×-homo-+ x n (m ℕ.* n) ⟨(suc m ℕ.* n) × x ∎
-------------------------------------------------------------------------- The Agda standard library---- Multiplication over a monoid (i.e. repeated addition) optimised for-- type checking.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Monoid)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)module Algebra.Properties.Monoid.Mult.TCOptimised{a ℓ} (M : Monoid a ℓ) whereopen Monoid M renaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Algebra.Properties.Monoid.Mult M as Uusing () renaming (_×_ to _×ᵤ_)open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Definitionopen import Algebra.Definitions.RawMonoid rawMonoid publicusing () renaming (_×′_ to _×_)-------------------------------------------------------------------------- Properties1+× : ∀ n x → suc n × x ≈ x + n × x1+× 0 x = sym (+-identityʳ x)1+× 1 x = refl1+× (suc n@(suc _)) x = begin(suc n × x) + x ≈⟨ +-congʳ (1+× n x) ⟩(x + n × x) + x ≈⟨ +-assoc x (n × x) x ⟩x + (n × x + x) ∎-- The unoptimised (_×ᵤ_) and optimised (_×_) versions of multiplication-- are extensionally equal (up to the setoid equivalence).×ᵤ≈× : ∀ n x → n ×ᵤ x ≈ n × x×ᵤ≈× 0 x = refl×ᵤ≈× (suc n) x = beginx + n ×ᵤ x ≈⟨ +-congˡ (×ᵤ≈× n x) ⟩x + n × x ≈⟨ 1+× n x ⟨suc n × x ∎-- _×_ is homomorphic with respect to _ℕ.+_/_+_.×-homo-+ : ∀ c m n → (m ℕ.+ n) × c ≈ m × c + n × c×-homo-+ c m n = begin(m ℕ.+ n) × c ≈⟨ ×ᵤ≈× (m ℕ.+ n) c ⟨(m ℕ.+ n) ×ᵤ c ≈⟨ U.×-homo-+ c m n ⟩m ×ᵤ c + n ×ᵤ c ≈⟨ +-cong (×ᵤ≈× m c) (×ᵤ≈× n c) ⟩m × c + n × c ∎-- _×_ preserves equality.×-congʳ : ∀ n → (n ×_) Preserves _≈_ ⟶ _≈_×-congʳ 0 x≈y = refl×-congʳ 1 x≈y = x≈y×-congʳ (suc n@(suc _)) x≈y = +-cong (×-congʳ n x≈y) x≈y×-cong : _×_ Preserves₂ _≡_ ⟶ _≈_ ⟶ _≈_×-cong {n} ≡.refl x≈y = ×-congʳ n x≈y×-assocˡ : ∀ x m n → m × (n × x) ≈ (m ℕ.* n) × x×-assocˡ x m n = beginm × (n × x) ≈⟨ ×-congʳ m (×ᵤ≈× n x) ⟨m × (n ×ᵤ x) ≈⟨ ×ᵤ≈× m (n ×ᵤ x) ⟨m ×ᵤ (n ×ᵤ x) ≈⟨ U.×-assocˡ x m n ⟩(m ℕ.* n) ×ᵤ x ≈⟨ ×ᵤ≈× (m ℕ.* n) x ⟩(m ℕ.* n) × x ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties of divisibility over monoids------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Monoid)open import Data.Product.Base using (_,_)open import Relation.Binary.Core using (_⇒_)open import Relation.Binary.Bundles using (Preorder)open import Relation.Binary.Structures using (IsPreorder; IsEquivalence)open import Relation.Binary.Definitions using (Reflexive)module Algebra.Properties.Monoid.Divisibility{a ℓ} (M : Monoid a ℓ) whereopen Monoid M-------------------------------------------------------------------------- Re-export semigroup divisibilityopen import Algebra.Properties.Semigroup.Divisibility semigroup public-------------------------------------------------------------------------- Additional propertiesinfix 4 ε∣_ε∣_ : ∀ x → ε ∣ xε∣ x = x , identityʳ x∣-refl : Reflexive _∣_∣-refl {x} = ε , identityˡ x∣-reflexive : _≈_ ⇒ _∣_∣-reflexive x≈y = ε , trans (identityˡ _) x≈y∣-isPreorder : IsPreorder _≈_ _∣_∣-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ∣-reflexive; trans = ∣-trans}∣-preorder : Preorder a ℓ _∣-preorder = record{ isPreorder = ∣-isPreorder}-------------------------------------------------------------------------- Properties of mutual divisibiity∣∣-refl : Reflexive _∣∣_∣∣-refl = ∣-refl , ∣-refl∣∣-reflexive : _≈_ ⇒ _∣∣_∣∣-reflexive x≈y = ∣-reflexive x≈y , ∣-reflexive (sym x≈y)∣∣-isEquivalence : IsEquivalence _∣∣_∣∣-isEquivalence = record{ refl = λ {x} → ∣∣-refl {x}; sym = λ {x} {y} → ∣∣-sym {x} {y}; trans = λ {x} {y} {z} → ∣∣-trans {x} {y} {z}}
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of Quasigroup------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (MiddleBolLoop)module Algebra.Properties.MiddleBolLoop {m₁ m₂} (M : MiddleBolLoop m₁ m₂) whereopen MiddleBolLoop Mopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoidimport Algebra.Properties.Loop as LoopPropertiesopen LoopProperties loop publicxyx\\x≈y\\x : ∀ x y → x ∙ ((y ∙ x) \\ x) ≈ y \\ xxyx\\x≈y\\x x y = beginx ∙ ((y ∙ x) \\ x) ≈⟨ middleBol x y x ⟩(x // x) ∙ (y \\ x) ≈⟨ ∙-congʳ (x//x≈ε x) ⟩ε ∙ (y \\ x) ≈⟨ identityˡ ((y \\ x)) ⟩y \\ x ∎xxz\\x≈x//z : ∀ x z → x ∙ ((x ∙ z) \\ x) ≈ x // zxxz\\x≈x//z x z = beginx ∙ ((x ∙ z) \\ x) ≈⟨ middleBol x x z ⟩(x // z) ∙ (x \\ x) ≈⟨ ∙-congˡ (x\\x≈ε x) ⟩(x // z) ∙ ε ≈⟨ identityʳ ((x // z)) ⟩x // z ∎xz\\x≈x//zx : ∀ x z → x ∙ (z \\ x) ≈ (x // z) ∙ xxz\\x≈x//zx x z = beginx ∙ (z \\ x) ≈⟨ ∙-congˡ (\\-congʳ( sym (identityˡ z))) ⟩x ∙ ((ε ∙ z) \\ x) ≈⟨ middleBol x ε z ⟩x // z ∙ (ε \\ x) ≈⟨ ∙-congˡ (ε\\x≈x x) ⟩x // z ∙ x ∎x//yzx≈x//zy\\x : ∀ x y z → (x // (y ∙ z)) ∙ x ≈ (x // z) ∙ (y \\ x)x//yzx≈x//zy\\x x y z = begin(x // (y ∙ z)) ∙ x ≈⟨ sym (xz\\x≈x//zx x ((y ∙ z))) ⟩x ∙ ((y ∙ z) \\ x) ≈⟨ middleBol x y z ⟩(x // z) ∙ (y \\ x) ∎x//yxx≈y\\x : ∀ x y → (x // (y ∙ x)) ∙ x ≈ y \\ xx//yxx≈y\\x x y = begin(x // (y ∙ x)) ∙ x ≈⟨ x//yzx≈x//zy\\x x y x ⟩(x // x) ∙ (y \\ x) ≈⟨ ∙-congʳ (x//x≈ε x) ⟩ε ∙ (y \\ x) ≈⟨ identityˡ ((y \\ x)) ⟩y \\ x ∎x//xzx≈x//z : ∀ x z → (x // (x ∙ z)) ∙ x ≈ x // zx//xzx≈x//z x z = begin(x // (x ∙ z)) ∙ x ≈⟨ x//yzx≈x//zy\\x x x z ⟩(x // z) ∙ (x \\ x) ≈⟨ ∙-congˡ (x\\x≈ε x) ⟩(x // z) ∙ ε ≈⟨ identityʳ (x // z) ⟩x // z ∎
-------------------------------------------------------------------------- The Agda standard library---- Divisibility over magmas------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (Magma)open import Data.Product.Base using (_×_; _,_; ∃; map; swap)open import Relation.Binary.Definitionsmodule Algebra.Properties.Magma.Divisibility {a ℓ} (M : Magma a ℓ) whereopen Magma M-------------------------------------------------------------------------- Re-export divisibility relations publiclyopen import Algebra.Definitions.RawMagma rawMagma publicusing (_∣_; _∤_; _∣∣_; _∤∤_; _∣ˡ_; _∤ˡ_; _∣ʳ_; _∤ʳ_; _,_)-------------------------------------------------------------------------- Properties of divisibility∣-respʳ : _∣_ Respectsʳ _≈_∣-respʳ y≈z (q , qx≈y) = q , trans qx≈y y≈z∣-respˡ : _∣_ Respectsˡ _≈_∣-respˡ x≈z (q , qx≈y) = q , trans (∙-congˡ (sym x≈z)) qx≈y∣-resp : _∣_ Respects₂ _≈_∣-resp = ∣-respʳ , ∣-respˡx∣yx : ∀ x y → x ∣ y ∙ xx∣yx x y = y , reflxy≈z⇒y∣z : ∀ x y {z} → x ∙ y ≈ z → y ∣ zxy≈z⇒y∣z x y xy≈z = ∣-respʳ xy≈z (x∣yx y x)-------------------------------------------------------------------------- Properties of mutual divisibility _∣∣_∣∣-sym : Symmetric _∣∣_∣∣-sym = swap∣∣-respʳ-≈ : _∣∣_ Respectsʳ _≈_∣∣-respʳ-≈ y≈z (x∣y , y∣x) = ∣-respʳ y≈z x∣y , ∣-respˡ y≈z y∣x∣∣-respˡ-≈ : _∣∣_ Respectsˡ _≈_∣∣-respˡ-≈ x≈z (x∣y , y∣x) = ∣-respˡ x≈z x∣y , ∣-respʳ x≈z y∣x∣∣-resp-≈ : _∣∣_ Respects₂ _≈_∣∣-resp-≈ = ∣∣-respʳ-≈ , ∣∣-respˡ-≈
-------------------------------------------------------------------------- The Agda standard library---- Some basic properties of Loop------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Loop)module Algebra.Properties.Loop {l₁ l₂} (L : Loop l₁ l₂) whereopen Loop Lopen import Algebra.Definitions _≈_open import Algebra.Properties.Quasigroup quasigroupopen import Data.Product.Base using (proj₂)open import Relation.Binary.Reasoning.Setoid setoidx//x≈ε : ∀ x → x // x ≈ εx//x≈ε x = beginx // x ≈⟨ //-congʳ (identityˡ x) ⟨(ε ∙ x) // x ≈⟨ rightDividesʳ x ε ⟩ε ∎x\\x≈ε : ∀ x → x \\ x ≈ εx\\x≈ε x = beginx \\ x ≈⟨ \\-congˡ (identityʳ x ) ⟨x \\ (x ∙ ε) ≈⟨ leftDividesʳ x ε ⟩ε ∎ε\\x≈x : ∀ x → ε \\ x ≈ xε\\x≈x x = beginε \\ x ≈⟨ identityˡ (ε \\ x) ⟨ε ∙ (ε \\ x) ≈⟨ leftDividesˡ ε x ⟩x ∎x//ε≈x : ∀ x → x // ε ≈ xx//ε≈x x = beginx // ε ≈⟨ identityʳ (x // ε) ⟨(x // ε) ∙ ε ≈⟨ rightDividesˡ ε x ⟩x ∎identityˡ-unique : ∀ x y → x ∙ y ≈ y → x ≈ εidentityˡ-unique x y eq = beginx ≈⟨ x≈z//y x y y eq ⟩y // y ≈⟨ x//x≈ε y ⟩ε ∎identityʳ-unique : ∀ x y → x ∙ y ≈ x → y ≈ εidentityʳ-unique x y eq = beginy ≈⟨ y≈x\\z x y x eq ⟩x \\ x ≈⟨ x\\x≈ε x ⟩ε ∎identity-unique : ∀ {x} → Identity x _∙_ → x ≈ εidentity-unique {x} id = identityˡ-unique x x (proj₂ id x)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED. Please use-- `Algebra.Lattice.Properties.Lattice` instead.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundlesopen import Relation.Binary.Core using (Rel)open import Function.Baseopen import Function.Bundles using (module Equivalence; _⇔_)open import Data.Product.Base using (_,_; swap)module Algebra.Properties.Lattice {l₁ l₂} (L : Lattice l₁ l₂) whereopen import Algebra.Lattice.Properties.Lattice L public{-# WARNING_ON_IMPORT"Algebra.Properties.Lattice was deprecated in v2.0.Use Algebra.Lattice.Properties.Lattice instead."#-}-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.open Lattice L-- Version 1.4replace-equality : {_≈′_ : Rel Carrier l₂} →(∀ {x y} → x ≈ y ⇔ (x ≈′ y)) → Lattice _ _replace-equality {_≈′_} ≈⇔≈′ = record{ isLattice = record{ isEquivalence = record{ refl = to refl; sym = λ x≈y → to (sym (from x≈y)); trans = λ x≈y y≈z → to (trans (from x≈y) (from y≈z))}; ∨-comm = λ x y → to (∨-comm x y); ∨-assoc = λ x y z → to (∨-assoc x y z); ∨-cong = λ x≈y u≈v → to (∨-cong (from x≈y) (from u≈v)); ∧-comm = λ x y → to (∧-comm x y); ∧-assoc = λ x y z → to (∧-assoc x y z); ∧-cong = λ x≈y u≈v → to (∧-cong (from x≈y) (from u≈v)); absorptive = (λ x y → to (∨-absorbs-∧ x y)), (λ x y → to (∧-absorbs-∨ x y))}} where open module E {x y} = Equivalence (≈⇔≈′ {x} {y}){-# WARNING_ON_USAGE replace-equality"Warning: replace-equality was deprecated in v1.4.Please use isLattice from `Algebra.Construct.Subst.Equality` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesmodule Algebra.Properties.KleeneAlgebra {k₁ k₂} (K : KleeneAlgebra k₁ k₂) whereopen KleeneAlgebra Kopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoid0⋆≈1 : 0# ⋆ ≈ 1#0⋆≈1 = begin0# ⋆ ≈⟨ sym (starExpansiveˡ 0#) ⟩1# + 0# ⋆ * 0# ≈⟨ +-congˡ ( zeroʳ (0# ⋆)) ⟩1# + 0# ≈⟨ +-identityʳ 1# ⟩1# ∎1+x⋆≈x⋆ : ∀ x → 1# + x ⋆ ≈ x ⋆1+x⋆≈x⋆ x = sym (beginx ⋆ ≈⟨ sym (starExpansiveʳ x) ⟩1# + x * x ⋆ ≈⟨ +-congʳ (sym (+-idem 1#)) ⟩1# + 1# + x * x ⋆ ≈⟨ +-assoc 1# 1# ((x * x ⋆ )) ⟩1# + (1# + x * x ⋆) ≈⟨ +-congˡ (starExpansiveʳ x) ⟩1# + x ⋆ ∎)x⋆+xx⋆≈x⋆ : ∀ x → x ⋆ + x * x ⋆ ≈ x ⋆x⋆+xx⋆≈x⋆ x = beginx ⋆ + x * x ⋆ ≈⟨ +-congʳ (sym (1+x⋆≈x⋆ x)) ⟩1# + x ⋆ + x * x ⋆ ≈⟨ +-congʳ (+-comm 1# ((x ⋆))) ⟩x ⋆ + 1# + x * x ⋆ ≈⟨ +-assoc ((x ⋆)) 1# ((x * x ⋆ )) ⟩x ⋆ + (1# + x * x ⋆) ≈⟨ +-congˡ (starExpansiveʳ x) ⟩x ⋆ + x ⋆ ≈⟨ +-idem (x ⋆) ⟩x ⋆ ∎x⋆+x⋆x≈x⋆ : ∀ x → x ⋆ + x ⋆ * x ≈ x ⋆x⋆+x⋆x≈x⋆ x = beginx ⋆ + x ⋆ * x ≈⟨ +-congʳ (sym (1+x⋆≈x⋆ x)) ⟩1# + x ⋆ + x ⋆ * x ≈⟨ +-congʳ (+-comm 1# (x ⋆)) ⟩x ⋆ + 1# + x ⋆ * x ≈⟨ +-assoc (x ⋆) 1# (x ⋆ * x) ⟩x ⋆ + (1# + x ⋆ * x) ≈⟨ +-congˡ (starExpansiveˡ x) ⟩x ⋆ + x ⋆ ≈⟨ +-idem (x ⋆) ⟩x ⋆ ∎x+x⋆≈x⋆ : ∀ x → x + x ⋆ ≈ x ⋆x+x⋆≈x⋆ x = beginx + x ⋆ ≈⟨ +-congˡ (sym (starExpansiveʳ x)) ⟩x + (1# + x * x ⋆) ≈⟨ +-congʳ (sym (*-identityʳ x)) ⟩x * 1# + (1# + x * x ⋆) ≈⟨ sym (+-assoc (x * 1#) 1# (x * x ⋆)) ⟩x * 1# + 1# + x * x ⋆ ≈⟨ +-congʳ (+-comm (x * 1#) 1#) ⟩1# + x * 1# + x * x ⋆ ≈⟨ +-assoc 1# (x * 1#) (x * x ⋆) ⟩1# + (x * 1# + x * x ⋆) ≈⟨ +-congˡ (sym (distribˡ x 1# ((x ⋆)))) ⟩1# + x * (1# + x ⋆) ≈⟨ +-congˡ (*-congˡ (1+x⋆≈x⋆ x)) ⟩1# + x * x ⋆ ≈⟨ (starExpansiveʳ x) ⟩x ⋆ ∎1+x+x⋆≈x⋆ : ∀ x → 1# + x + x ⋆ ≈ x ⋆1+x+x⋆≈x⋆ x = begin1# + x + x ⋆ ≈⟨ +-assoc 1# x (x ⋆) ⟩1# + (x + x ⋆) ≈⟨ +-congˡ (x+x⋆≈x⋆ x) ⟩1# + x ⋆ ≈⟨ 1+x⋆≈x⋆ x ⟩x ⋆ ∎0+x+x⋆≈x⋆ : ∀ x → 0# + x + x ⋆ ≈ x ⋆0+x+x⋆≈x⋆ x = begin0# + x + x ⋆ ≈⟨ +-assoc 0# x (x ⋆) ⟩0# + (x + x ⋆) ≈⟨ +-identityˡ ((x + x ⋆)) ⟩(x + x ⋆) ≈⟨ x+x⋆≈x⋆ x ⟩x ⋆ ∎x⋆x⋆≈x⋆ : ∀ x → x ⋆ * x ⋆ ≈ x ⋆x⋆x⋆≈x⋆ x = starDestructiveˡ x (x ⋆) (x ⋆) (x⋆+xx⋆≈x⋆ x)1+x⋆x⋆≈x⋆ : ∀ x → 1# + x ⋆ * x ⋆ ≈ x ⋆1+x⋆x⋆≈x⋆ x = begin1# + x ⋆ * x ⋆ ≈⟨ +-congˡ (x⋆x⋆≈x⋆ x) ⟩1# + x ⋆ ≈⟨ 1+x⋆≈x⋆ x ⟩x ⋆ ∎x⋆⋆≈x⋆ : ∀ x → (x ⋆) ⋆ ≈ x ⋆x⋆⋆≈x⋆ x = begin(x ⋆) ⋆ ≈⟨ sym (*-identityʳ ((x ⋆) ⋆)) ⟩(x ⋆) ⋆ * 1# ≈⟨ starDestructiveˡ (x ⋆) 1# (x ⋆) (1+x⋆x⋆≈x⋆ x) ⟩x ⋆ ∎1+11≈1 : 1# + 1# * 1# ≈ 1#1+11≈1 = begin1# + 1# * 1# ≈⟨ +-congˡ ( *-identityʳ 1#) ⟩1# + 1# ≈⟨ +-idem 1# ⟩1# ∎1⋆≈1 : 1# ⋆ ≈ 1#1⋆≈1 = begin1# ⋆ ≈⟨ sym (*-identityʳ (1# ⋆)) ⟩1# ⋆ * 1# ≈⟨ starDestructiveˡ 1# 1# 1# 1+11≈1 ⟩1# ∎x≈y⇒1+xy⋆≈y⋆ : ∀ x y → x ≈ y → 1# + x * y ⋆ ≈ y ⋆x≈y⇒1+xy⋆≈y⋆ x y eq = begin1# + x * y ⋆ ≈⟨ +-congˡ (*-congʳ (eq)) ⟩1# + y * y ⋆ ≈⟨ starExpansiveʳ y ⟩y ⋆ ∎x≈y⇒x⋆≈y⋆ : ∀ x y → x ≈ y → x ⋆ ≈ y ⋆x≈y⇒x⋆≈y⋆ x y eq = beginx ⋆ ≈⟨ sym (*-identityʳ (x ⋆)) ⟩x ⋆ * 1# ≈⟨ (starDestructiveˡ x 1# (y ⋆) (x≈y⇒1+xy⋆≈y⋆ x y eq)) ⟩y ⋆ ∎ax≈xb⇒x+axb⋆≈xb⋆ : ∀ x a b → a * x ≈ x * b → x + a * (x * b ⋆) ≈ x * b ⋆ax≈xb⇒x+axb⋆≈xb⋆ x a b eq = beginx + a * (x * b ⋆) ≈⟨ +-congˡ (sym(*-assoc a x (b ⋆))) ⟩x + a * x * b ⋆ ≈⟨ +-congʳ (sym (*-identityʳ x)) ⟩x * 1# + a * x * b ⋆ ≈⟨ +-congˡ (*-congʳ (eq)) ⟩x * 1# + x * b * b ⋆ ≈⟨ +-congˡ (*-assoc x b (b ⋆) ) ⟩x * 1# + x * (b * b ⋆) ≈⟨ sym (distribˡ x 1# (b * b ⋆)) ⟩x * (1# + b * b ⋆) ≈⟨ *-congˡ (starExpansiveʳ b) ⟩x * b ⋆ ∎ax≈xb⇒a⋆x≈xb⋆ : ∀ x a b → a * x ≈ x * b → a ⋆ * x ≈ x * b ⋆ax≈xb⇒a⋆x≈xb⋆ x a b eq = starDestructiveˡ a x ((x * b ⋆)) (ax≈xb⇒x+axb⋆≈xb⋆ x a b eq)[xy]⋆x≈x[yx]⋆ : ∀ x y → (x * y) ⋆ * x ≈ x * (y * x) ⋆[xy]⋆x≈x[yx]⋆ x y = ax≈xb⇒a⋆x≈xb⋆ x (x * y) (y * x) (*-assoc x y x)
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesmodule Algebra.Properties.Group {g₁ g₂} (G : Group g₁ g₂) whereimport Algebra.Properties.Loop as LoopPropertiesimport Algebra.Properties.Quasigroup as QuasigroupPropertiesopen import Data.Product.Base using (_,_)open import Function.Base using (_$_)open import Function.Definitionsopen Group Gopen import Algebra.Consequences.Setoid setoidopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_ using (IsLoop; IsQuasigroup)open import Relation.Binary.Reasoning.Setoid setoid\\-cong₂ : Congruent₂ _\\_\\-cong₂ x≈y u≈v = ∙-cong (⁻¹-cong x≈y) u≈v//-cong₂ : Congruent₂ _//_//-cong₂ x≈y u≈v = ∙-cong x≈y (⁻¹-cong u≈v)-------------------------------------------------------------------------- Groups are quasi-groups\\-leftDividesˡ : LeftDividesˡ _∙_ _\\_\\-leftDividesˡ x y = beginx ∙ (x \\ y) ≈⟨ assoc x (x ⁻¹) y ⟨x ∙ x ⁻¹ ∙ y ≈⟨ ∙-congʳ (inverseʳ x) ⟩ε ∙ y ≈⟨ identityˡ y ⟩y ∎\\-leftDividesʳ : LeftDividesʳ _∙_ _\\_\\-leftDividesʳ x y = beginx \\ x ∙ y ≈⟨ assoc (x ⁻¹) x y ⟨x ⁻¹ ∙ x ∙ y ≈⟨ ∙-congʳ (inverseˡ x) ⟩ε ∙ y ≈⟨ identityˡ y ⟩y ∎\\-leftDivides : LeftDivides _∙_ _\\_\\-leftDivides = \\-leftDividesˡ , \\-leftDividesʳ//-rightDividesˡ : RightDividesˡ _∙_ _//_//-rightDividesˡ x y = begin(y // x) ∙ x ≈⟨ assoc y (x ⁻¹) x ⟩y ∙ (x ⁻¹ ∙ x) ≈⟨ ∙-congˡ (inverseˡ x) ⟩y ∙ ε ≈⟨ identityʳ y ⟩y ∎//-rightDividesʳ : RightDividesʳ _∙_ _//_//-rightDividesʳ x y = beginy ∙ x // x ≈⟨ assoc y x (x ⁻¹) ⟩y ∙ (x // x) ≈⟨ ∙-congˡ (inverseʳ x) ⟩y ∙ ε ≈⟨ identityʳ y ⟩y ∎//-rightDivides : RightDivides _∙_ _//_//-rightDivides = //-rightDividesˡ , //-rightDividesʳisQuasigroup : IsQuasigroup _∙_ _\\_ _//_isQuasigroup = record{ isMagma = isMagma; \\-cong = \\-cong₂; //-cong = //-cong₂; leftDivides = \\-leftDivides; rightDivides = //-rightDivides}quasigroup : Quasigroup _ _quasigroup = record { isQuasigroup = isQuasigroup }open QuasigroupProperties quasigroup publicusing (x≈z//y; y≈x\\z)renaming (cancelˡ to ∙-cancelˡ; cancelʳ to ∙-cancelʳ; cancel to ∙-cancel)-------------------------------------------------------------------------- Groups are loopsisLoop : IsLoop _∙_ _\\_ _//_ εisLoop = record { isQuasigroup = isQuasigroup ; identity = identity }loop : Loop _ _loop = record { isLoop = isLoop }open LoopProperties loop publicusing (identityˡ-unique; identityʳ-unique; identity-unique)-------------------------------------------------------------------------- Other propertiesinverseˡ-unique : ∀ x y → x ∙ y ≈ ε → x ≈ y ⁻¹inverseˡ-unique x y eq = trans (x≈z//y x y ε eq) (identityˡ _)inverseʳ-unique : ∀ x y → x ∙ y ≈ ε → y ≈ x ⁻¹inverseʳ-unique x y eq = trans (y≈x\\z x y ε eq) (identityʳ _)ε⁻¹≈ε : ε ⁻¹ ≈ εε⁻¹≈ε = sym $ inverseˡ-unique _ _ (identityˡ ε)⁻¹-selfInverse : SelfInverse _⁻¹⁻¹-selfInverse {x} {y} eq = sym $ inverseˡ-unique x y $ beginx ∙ y ≈⟨ ∙-congˡ eq ⟨x ∙ x ⁻¹ ≈⟨ inverseʳ x ⟩ε ∎⁻¹-involutive : Involutive _⁻¹⁻¹-involutive = selfInverse⇒involutive ⁻¹-selfInversex∙y⁻¹≈ε⇒x≈y : ∀ x y → (x ∙ y ⁻¹) ≈ ε → x ≈ yx∙y⁻¹≈ε⇒x≈y x y x∙y⁻¹≈ε = beginx ≈⟨ inverseˡ-unique x (y ⁻¹) x∙y⁻¹≈ε ⟩y ⁻¹ ⁻¹ ≈⟨ ⁻¹-involutive y ⟩y ∎x≈y⇒x∙y⁻¹≈ε : ∀ {x y} → x ≈ y → (x ∙ y ⁻¹) ≈ εx≈y⇒x∙y⁻¹≈ε {x} {y} x≈y = beginx ∙ y ⁻¹ ≈⟨ ∙-congʳ x≈y ⟩y ∙ y ⁻¹ ≈⟨ inverseʳ y ⟩ε ∎⁻¹-injective : Injective _≈_ _≈_ _⁻¹⁻¹-injective = selfInverse⇒injective ⁻¹-selfInverse⁻¹-anti-homo-∙ : ∀ x y → (x ∙ y) ⁻¹ ≈ y ⁻¹ ∙ x ⁻¹⁻¹-anti-homo-∙ x y = ∙-cancelˡ _ _ _ $ beginx ∙ y ∙ (x ∙ y) ⁻¹ ≈⟨ inverseʳ _ ⟩ε ≈⟨ inverseʳ _ ⟨x ∙ x ⁻¹ ≈⟨ ∙-congʳ (//-rightDividesʳ y x) ⟨(x ∙ y) ∙ y ⁻¹ ∙ x ⁻¹ ≈⟨ assoc (x ∙ y) (y ⁻¹) (x ⁻¹) ⟩x ∙ y ∙ (y ⁻¹ ∙ x ⁻¹) ∎⁻¹-anti-homo-// : ∀ x y → (x // y) ⁻¹ ≈ y // x⁻¹-anti-homo-// x y = begin(x // y) ⁻¹ ≡⟨⟩(x ∙ y ⁻¹) ⁻¹ ≈⟨ ⁻¹-anti-homo-∙ x (y ⁻¹) ⟩(y ⁻¹) ⁻¹ ∙ x ⁻¹ ≈⟨ ∙-congʳ (⁻¹-involutive y) ⟩y ∙ x ⁻¹ ≡⟨⟩y // x ∎⁻¹-anti-homo-\\ : ∀ x y → (x \\ y) ⁻¹ ≈ y \\ x⁻¹-anti-homo-\\ x y = begin(x \\ y) ⁻¹ ≡⟨⟩(x ⁻¹ ∙ y) ⁻¹ ≈⟨ ⁻¹-anti-homo-∙ (x ⁻¹) y ⟩y ⁻¹ ∙ (x ⁻¹) ⁻¹ ≈⟨ ∙-congˡ (⁻¹-involutive x) ⟩y ⁻¹ ∙ x ≡⟨⟩y \\ x ∎\\≗flip-//⇒comm : (∀ x y → x \\ y ≈ y // x) → Commutative _∙_\\≗flip-//⇒comm \\≗//ᵒ x y = beginx ∙ y ≈⟨ ∙-congˡ (//-rightDividesˡ x y) ⟨x ∙ ((y // x) ∙ x) ≈⟨ ∙-congˡ (∙-congʳ (\\≗//ᵒ x y)) ⟨x ∙ ((x \\ y) ∙ x) ≈⟨ assoc x (x \\ y) x ⟨x ∙ (x \\ y) ∙ x ≈⟨ ∙-congʳ (\\-leftDividesˡ x y) ⟩y ∙ x ∎comm⇒\\≗flip-// : Commutative _∙_ → ∀ x y → x \\ y ≈ y // xcomm⇒\\≗flip-// comm x y = beginx \\ y ≡⟨⟩x ⁻¹ ∙ y ≈⟨ comm _ _ ⟩y ∙ x ⁻¹ ≡⟨⟩y // x ∎
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- Disabled to prevent warnings from deprecated names{-# OPTIONS --warn=noUserWarning #-}open import Algebra.Lattice.Bundlesopen import Algebra.Lattice.Structures.Biasedopen import Relation.Binaryopen import Function.Bundles using (module Equivalence; _⇔_)import Algebra.Construct.Subst.Equality as SubstEqmodule Algebra.Properties.DistributiveLattice{ℓ₁ ℓ₂} (DL : DistributiveLattice ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Algebra.Properties.DistributiveLattice was deprecated in v2.0.Use Algebra.Lattice.Properties.DistributiveLattice instead."#-}open DistributiveLattice DLopen import Algebra.Lattice.Properties.DistributiveLattice DL publicimport Algebra.Properties.Lattice as LatticeProperties-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4replace-equality : {_≈′_ : Rel Carrier ℓ₂} →(∀ {x y} → x ≈ y ⇔ (x ≈′ y)) →DistributiveLattice _ _replace-equality {_≈′_} ≈⇔≈′ = record{ isDistributiveLattice = isDistributiveLatticeʳʲᵐ (record{ isLattice = Lattice.isLattice(LatticeProperties.replace-equality lattice ≈⇔≈′); ∨-distribʳ-∧ = λ x y z → to (∨-distribʳ-∧ x y z)})} where open module E {x y} = Equivalence (≈⇔≈′ {x} {y}){-# WARNING_ON_USAGE replace-equality"Warning: replace-equality was deprecated in v1.4.Please use isDistributiveLattice from `Algebra.Construct.Subst.Equality` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Exponentiation defined over a commutative semiring as repeated multiplication------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Properties.CommutativeSemiring.Exp{a ℓ} (S : CommutativeSemiring a ℓ) whereopen CommutativeSemiring Simport Algebra.Properties.CommutativeMonoid.Mult *-commutativeMonoid as Mult-------------------------------------------------------------------------- Definitionopen import Algebra.Properties.Semiring.Exp semiring public-------------------------------------------------------------------------- Properties^-distrib-* : ∀ x y n → (x * y) ^ n ≈ x ^ n * y ^ n^-distrib-* = Mult.×-distrib-+
-------------------------------------------------------------------------- The Agda standard library---- Exponentiation over a semiring optimised for type-checking.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Nat.Base as ℕ using (zero; suc)import Data.Nat.Properties as ℕopen import Relation.Binary.PropositionalEquality.Core using (_≡_)module Algebra.Properties.CommutativeSemiring.Exp.TCOptimised{a ℓ} (S : CommutativeSemiring a ℓ) whereopen CommutativeSemiring Sopen import Relation.Binary.Reasoning.Setoid setoidimport Algebra.Properties.CommutativeMonoid.Mult.TCOptimised *-commutativeMonoid as Mult-------------------------------------------------------------------------- Re-export definition and properties for semiringsopen import Algebra.Properties.Semiring.Exp.TCOptimised semiring public-------------------------------------------------------------------------- Properties^-distrib-* : ∀ x y n → (x * y) ^ n ≈ x ^ n * y ^ n^-distrib-* = Mult.×-distrib-+
-------------------------------------------------------------------------- The Agda standard library---- The Binomial Theorem for Commutative Semirings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesusing (CommutativeSemiring)module Algebra.Properties.CommutativeSemiring.Binomial {a ℓ} (S : CommutativeSemiring a ℓ) whereopen CommutativeSemiring Sopen import Algebra.Properties.Semiring.Exp semiring using (_^_)import Algebra.Properties.Semiring.Binomial semiring as Binomialopen Binomial public hiding (theorem)-------------------------------------------------------------------------- Here it istheorem : ∀ n x y → (x + y) ^ n ≈ binomialExpansion x y ntheorem n x y = Binomial.theorem x y (*-comm x y) n
-------------------------------------------------------------------------- The Agda standard library---- Some theory for commutative semigroup------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CommutativeSemigroup)module Algebra.Properties.CommutativeSemigroup{a ℓ} (CS : CommutativeSemigroup a ℓ)whereopen CommutativeSemigroup CSopen import Algebra.Definitions _≈_open import Relation.Binary.Reasoning.Setoid setoidopen import Data.Product.Base using (_,_)-------------------------------------------------------------------------- Re-export the contents of semigroupopen import Algebra.Properties.Semigroup semigroup public-------------------------------------------------------------------------- Propertiesinterchange : Interchangable _∙_ _∙_interchange a b c d = begin(a ∙ b) ∙ (c ∙ d) ≈⟨ assoc a b (c ∙ d) ⟩a ∙ (b ∙ (c ∙ d)) ≈⟨ ∙-congˡ (assoc b c d) ⟨a ∙ ((b ∙ c) ∙ d) ≈⟨ ∙-congˡ (∙-congʳ (comm b c)) ⟩a ∙ ((c ∙ b) ∙ d) ≈⟨ ∙-congˡ (assoc c b d) ⟩a ∙ (c ∙ (b ∙ d)) ≈⟨ assoc a c (b ∙ d) ⟨(a ∙ c) ∙ (b ∙ d) ∎-------------------------------------------------------------------------- Permutation laws for _∙_ for three factors.-- There are five nontrivial permutations.-------------------------------------------------------------------------- Partitions (1,1).x∙yz≈y∙xz : ∀ x y z → x ∙ (y ∙ z) ≈ y ∙ (x ∙ z)x∙yz≈y∙xz x y z = beginx ∙ (y ∙ z) ≈⟨ sym (assoc x y z) ⟩(x ∙ y) ∙ z ≈⟨ ∙-congʳ (comm x y) ⟩(y ∙ x) ∙ z ≈⟨ assoc y x z ⟩y ∙ (x ∙ z) ∎x∙yz≈z∙yx : ∀ x y z → x ∙ (y ∙ z) ≈ z ∙ (y ∙ x)x∙yz≈z∙yx x y z = beginx ∙ (y ∙ z) ≈⟨ ∙-congˡ (comm y z) ⟩x ∙ (z ∙ y) ≈⟨ x∙yz≈y∙xz x z y ⟩z ∙ (x ∙ y) ≈⟨ ∙-congˡ (comm x y) ⟩z ∙ (y ∙ x) ∎x∙yz≈x∙zy : ∀ x y z → x ∙ (y ∙ z) ≈ x ∙ (z ∙ y)x∙yz≈x∙zy _ y z = ∙-congˡ (comm y z)x∙yz≈y∙zx : ∀ x y z → x ∙ (y ∙ z) ≈ y ∙ (z ∙ x)x∙yz≈y∙zx x y z = beginx ∙ (y ∙ z) ≈⟨ comm x _ ⟩(y ∙ z) ∙ x ≈⟨ assoc y z x ⟩y ∙ (z ∙ x) ∎x∙yz≈z∙xy : ∀ x y z → x ∙ (y ∙ z) ≈ z ∙ (x ∙ y)x∙yz≈z∙xy x y z = beginx ∙ (y ∙ z) ≈⟨ sym (assoc x y z) ⟩(x ∙ y) ∙ z ≈⟨ comm _ z ⟩z ∙ (x ∙ y) ∎-------------------------------------------------------------------------- Partitions (1,2).-- These permutation laws are proved by composing the proofs for-- partitions (1,1) with \p → trans p (sym (assoc _ _ _)).x∙yz≈yx∙z : ∀ x y z → x ∙ (y ∙ z) ≈ (y ∙ x) ∙ zx∙yz≈yx∙z x y z = trans (x∙yz≈y∙xz x y z) (sym (assoc y x z))x∙yz≈zy∙x : ∀ x y z → x ∙ (y ∙ z) ≈ (z ∙ y) ∙ xx∙yz≈zy∙x x y z = trans (x∙yz≈z∙yx x y z) (sym (assoc z y x))x∙yz≈xz∙y : ∀ x y z → x ∙ (y ∙ z) ≈ (x ∙ z) ∙ yx∙yz≈xz∙y x y z = trans (x∙yz≈x∙zy x y z) (sym (assoc x z y))x∙yz≈yz∙x : ∀ x y z → x ∙ (y ∙ z) ≈ (y ∙ z) ∙ xx∙yz≈yz∙x x y z = trans (x∙yz≈y∙zx _ _ _) (sym (assoc y z x))x∙yz≈zx∙y : ∀ x y z → x ∙ (y ∙ z) ≈ (z ∙ x) ∙ yx∙yz≈zx∙y x y z = trans (x∙yz≈z∙xy x y z) (sym (assoc z x y))-------------------------------------------------------------------------- Partitions (2,1).-- Their laws are proved by composing proofs for partitions (1,1) with-- trans (assoc x y z).xy∙z≈y∙xz : ∀ x y z → (x ∙ y) ∙ z ≈ y ∙ (x ∙ z)xy∙z≈y∙xz x y z = trans (assoc x y z) (x∙yz≈y∙xz x y z)xy∙z≈z∙yx : ∀ x y z → (x ∙ y) ∙ z ≈ z ∙ (y ∙ x)xy∙z≈z∙yx x y z = trans (assoc x y z) (x∙yz≈z∙yx x y z)xy∙z≈x∙zy : ∀ x y z → (x ∙ y) ∙ z ≈ x ∙ (z ∙ y)xy∙z≈x∙zy x y z = trans (assoc x y z) (x∙yz≈x∙zy x y z)xy∙z≈y∙zx : ∀ x y z → (x ∙ y) ∙ z ≈ y ∙ (z ∙ x)xy∙z≈y∙zx x y z = trans (assoc x y z) (x∙yz≈y∙zx x y z)xy∙z≈z∙xy : ∀ x y z → (x ∙ y) ∙ z ≈ z ∙ (x ∙ y)xy∙z≈z∙xy x y z = trans (assoc x y z) (x∙yz≈z∙xy x y z)-------------------------------------------------------------------------- Partitions (2,2).-- These proofs are by composing with the proofs for (2,1).xy∙z≈yx∙z : ∀ x y z → (x ∙ y) ∙ z ≈ (y ∙ x) ∙ zxy∙z≈yx∙z x y z = trans (xy∙z≈y∙xz _ _ _) (sym (assoc y x z))xy∙z≈zy∙x : ∀ x y z → (x ∙ y) ∙ z ≈ (z ∙ y) ∙ xxy∙z≈zy∙x x y z = trans (xy∙z≈z∙yx x y z) (sym (assoc z y x))xy∙z≈xz∙y : ∀ x y z → (x ∙ y) ∙ z ≈ (x ∙ z) ∙ yxy∙z≈xz∙y x y z = trans (xy∙z≈x∙zy x y z) (sym (assoc x z y))xy∙z≈yz∙x : ∀ x y z → (x ∙ y) ∙ z ≈ (y ∙ z) ∙ xxy∙z≈yz∙x x y z = trans (xy∙z≈y∙zx x y z) (sym (assoc y z x))xy∙z≈zx∙y : ∀ x y z → (x ∙ y) ∙ z ≈ (z ∙ x) ∙ yxy∙z≈zx∙y x y z = trans (xy∙z≈z∙xy x y z) (sym (assoc z x y))-------------------------------------------------------------------------- commutative semigroup has Jordan identityxy∙xx≈x∙yxx : ∀ x y → (x ∙ y) ∙ (x ∙ x) ≈ x ∙ (y ∙ (x ∙ x))xy∙xx≈x∙yxx x y = assoc x y ((x ∙ x))-------------------------------------------------------------------------- commutative semigroup is left/right/middle semiMedialsemimedialˡ : LeftSemimedial _∙_semimedialˡ x y z = begin(x ∙ x) ∙ (y ∙ z) ≈⟨ assoc x x (y ∙ z) ⟩x ∙ (x ∙ (y ∙ z)) ≈⟨ ∙-congˡ (sym (assoc x y z)) ⟩x ∙ ((x ∙ y) ∙ z) ≈⟨ ∙-congˡ (∙-congʳ (comm x y)) ⟩x ∙ ((y ∙ x) ∙ z) ≈⟨ ∙-congˡ (assoc y x z) ⟩x ∙ (y ∙ (x ∙ z)) ≈⟨ sym (assoc x y ((x ∙ z))) ⟩(x ∙ y) ∙ (x ∙ z) ∎semimedialʳ : RightSemimedial _∙_semimedialʳ x y z = begin(y ∙ z) ∙ (x ∙ x) ≈⟨ assoc y z (x ∙ x) ⟩y ∙ (z ∙ (x ∙ x)) ≈⟨ ∙-congˡ (sym (assoc z x x)) ⟩y ∙ ((z ∙ x) ∙ x) ≈⟨ ∙-congˡ (∙-congʳ (comm z x)) ⟩y ∙ ((x ∙ z) ∙ x) ≈⟨ ∙-congˡ (assoc x z x) ⟩y ∙ (x ∙ (z ∙ x)) ≈⟨ sym (assoc y x ((z ∙ x))) ⟩(y ∙ x) ∙ (z ∙ x) ∎middleSemimedial : ∀ x y z → (x ∙ y) ∙ (z ∙ x) ≈ (x ∙ z) ∙ (y ∙ x)middleSemimedial x y z = begin(x ∙ y) ∙ (z ∙ x) ≈⟨ assoc x y ((z ∙ x)) ⟩x ∙ (y ∙ (z ∙ x)) ≈⟨ ∙-congˡ (sym (assoc y z x)) ⟩x ∙ ((y ∙ z) ∙ x) ≈⟨ ∙-congˡ (∙-congʳ (comm y z)) ⟩x ∙ ((z ∙ y) ∙ x) ≈⟨ ∙-congˡ ( assoc z y x) ⟩x ∙ (z ∙ (y ∙ x)) ≈⟨ sym (assoc x z ((y ∙ x))) ⟩(x ∙ z) ∙ (y ∙ x) ∎semimedial : Semimedial _∙_semimedial = semimedialˡ , semimedialʳ
-------------------------------------------------------------------------- The Agda standard library---- Properties of divisibility over commutative semigroups------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CommutativeSemigroup)open import Data.Product.Base using (_,_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningmodule Algebra.Properties.CommutativeSemigroup.Divisibility{a ℓ} (CS : CommutativeSemigroup a ℓ)whereopen CommutativeSemigroup CSopen import Algebra.Properties.CommutativeSemigroup CS using (x∙yz≈xz∙y; x∙yz≈y∙xz)open ≈-Reasoning setoid-------------------------------------------------------------------------- Re-export the contents of divisibility over semigroupsopen import Algebra.Properties.Semigroup.Divisibility semigroup public-------------------------------------------------------------------------- Re-export the contents of divisibility over commutative magmasopen import Algebra.Properties.CommutativeMagma.Divisibility commutativeMagma publicusing (x∣xy; xy≈z⇒x∣z; ∣-factors; ∣-factors-≈)-------------------------------------------------------------------------- New propertiesx∣y∧z∣x/y⇒xz∣y : ∀ {x y z} → ((x/y , _) : x ∣ y) → z ∣ x/y → x ∙ z ∣ yx∣y∧z∣x/y⇒xz∣y {x} {y} {z} (x/y , x/y∙x≈y) (p , pz≈x/y) = p , (beginp ∙ (x ∙ z) ≈⟨ x∙yz≈xz∙y p x z ⟩(p ∙ z) ∙ x ≈⟨ ∙-congʳ pz≈x/y ⟩x/y ∙ x ≈⟨ x/y∙x≈y ⟩y ∎)x∣y⇒zx∣zy : ∀ {x y} z → x ∣ y → z ∙ x ∣ z ∙ yx∣y⇒zx∣zy {x} {y} z (q , qx≈y) = q , (beginq ∙ (z ∙ x) ≈⟨ x∙yz≈y∙xz q z x ⟩z ∙ (q ∙ x) ≈⟨ ∙-congˡ qx≈y ⟩z ∙ y ∎)
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (CommutativeMonoid)open import Algebra.Definitions using (LeftInvertible; RightInvertible; Invertible)open import Data.Product.Base using (_,_; proj₂)module Algebra.Properties.CommutativeMonoid{g₁ g₂} (M : CommutativeMonoid g₁ g₂) whereopen CommutativeMonoid Mrenaming( ε to 0#; _∙_ to _+_; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; comm to +-comm)private variablex : Carrierinvertibleˡ⇒invertibleʳ : LeftInvertible _≈_ 0# _+_ x → RightInvertible _≈_ 0# _+_ xinvertibleˡ⇒invertibleʳ {x} (-x , -x+x≈1) = -x , trans (+-comm x -x) -x+x≈1invertibleʳ⇒invertibleˡ : RightInvertible _≈_ 0# _+_ x → LeftInvertible _≈_ 0# _+_ xinvertibleʳ⇒invertibleˡ {x} (-x , x+-x≈1) = -x , trans (+-comm -x x) x+-x≈1invertibleˡ⇒invertible : LeftInvertible _≈_ 0# _+_ x → Invertible _≈_ 0# _+_ xinvertibleˡ⇒invertible left@(-x , -x+x≈1) = -x , -x+x≈1 , invertibleˡ⇒invertibleʳ left .proj₂invertibleʳ⇒invertible : RightInvertible _≈_ 0# _+_ x → Invertible _≈_ 0# _+_ xinvertibleʳ⇒invertible right@(-x , x+-x≈1) = -x , invertibleʳ⇒invertibleˡ right .proj₂ , x+-x≈1
-------------------------------------------------------------------------- The Agda standard library---- Finite summations over a commutative monoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (CommutativeMonoid)open import Data.Bool.Base using (Bool; true; false)open import Data.Nat.Base as ℕ using (ℕ; zero; suc; NonZero)open import Data.Fin.Base using (Fin; zero; suc)open import Data.Fin.Permutation as Perm using (Permutation; _⟨$⟩ˡ_; _⟨$⟩ʳ_)open import Data.Fin.Patterns using (0F)open import Data.Vec.Functionalopen import Function.Base using (_∘_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Nullary.Negation using (contradiction)module Algebra.Properties.CommutativeMonoid.Sum{a ℓ} (M : CommutativeMonoid a ℓ) whereopen CommutativeMonoid Mrenaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congˡ to +-congˡ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Algebra.Definitions _≈_open import Algebra.Solver.CommutativeMonoid Mopen import Data.Vec.Functional.Relation.Binary.Equality.Setoid setoidopen import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Re-export summation over monoidsopen import Algebra.Properties.Monoid.Sum monoid public-------------------------------------------------------------------------- Properties-- When summing over a function from a finite set, we can pull out any-- value and move it to the front.sum-remove : ∀ {n} {i : Fin (suc n)} t → sum t ≈ t i + sum (removeAt t i)sum-remove {_} {zero} xs = reflsum-remove {suc n} {suc i} xs = begint₀ + ∑t ≈⟨ +-congˡ (sum-remove t) ⟩t₀ + (tᵢ + ∑t′) ≈⟨ solve 3 (λ x y z → x ⊕ (y ⊕ z) ⊜ y ⊕ (x ⊕ z)) refl t₀ tᵢ ∑t′ ⟩tᵢ + (t₀ + ∑t′) ∎wheret = tail xst₀ = head xstᵢ = t i∑t = sum t∑t′ = sum (removeAt t i)-- The '∑' operator distributes over addition.∑-distrib-+ : ∀ {n} (f g : Vector Carrier n) → ∑[ i < n ] (f i + g i) ≈ ∑[ i < n ] f i + ∑[ i < n ] g i∑-distrib-+ {zero} f g = sym (+-identityˡ _)∑-distrib-+ {suc n} f g = beginf₀ + g₀ + ∑fg ≈⟨ +-assoc _ _ _ ⟩f₀ + (g₀ + ∑fg) ≈⟨ +-congˡ (+-congˡ (∑-distrib-+ (f ∘ suc) (g ∘ suc))) ⟩f₀ + (g₀ + (∑f + ∑g)) ≈⟨ solve 4 (λ a b c d → a ⊕ (c ⊕ (b ⊕ d)) ⊜ (a ⊕ b) ⊕ (c ⊕ d)) refl f₀ ∑f g₀ ∑g ⟩(f₀ + ∑f) + (g₀ + ∑g) ∎wheref₀ = f 0Fg₀ = g 0F∑f = ∑[ i < n ] f (suc i)∑g = ∑[ i < n ] g (suc i)∑fg = ∑[ i < n ] (f (suc i) + g (suc i))-- The '∑' operator commutes with itself.∑-comm : ∀ {m n} (f : Fin m → Fin n → Carrier) →∑[ i < m ] ∑[ j < n ] f i j ≈ ∑[ j < n ] ∑[ i < m ] f i j∑-comm {zero} {n} f = sym (sum-replicate-zero n)∑-comm {suc m} {n} f = begin∑[ j < n ] f zero j + ∑[ i < m ] ∑[ j < n ] f (suc i) j ≈⟨ +-congˡ (∑-comm (f ∘ suc)) ⟩∑[ j < n ] f zero j + ∑[ j < n ] ∑[ i < m ] f (suc i) j ≈⟨ sym (∑-distrib-+ (f zero) _) ⟩∑[ j < n ] (f zero j + ∑[ i < m ] f (suc i) j) ∎-- Summation is insensitive to permutations of the inputsum-permute : ∀ {m n} f (π : Permutation m n) → sum f ≈ sum (rearrange (π ⟨$⟩ʳ_) f)sum-permute {zero} {zero} f π = reflsum-permute {zero} {suc n} f π = contradiction π (Perm.refute λ())sum-permute {suc m} {zero} f π = contradiction π (Perm.refute λ())sum-permute {suc m} {suc n} f π = beginsum f ≡⟨⟩f 0F + sum f/0 ≡⟨ ≡.cong (_+ sum f/0) (≡.cong f (Perm.inverseʳ π)) ⟨πf π₀ + sum f/0 ≈⟨ +-congˡ (sum-permute f/0 (Perm.remove π₀ π)) ⟩πf π₀ + sum (rearrange (π/0 ⟨$⟩ʳ_) f/0) ≡⟨ ≡.cong (πf π₀ +_) (sum-cong-≗ (≡.cong f ∘ Perm.punchIn-permute′ π 0F)) ⟨πf π₀ + sum (removeAt πf π₀) ≈⟨ sym (sum-remove πf) ⟩sum πf ∎wheref/0 = removeAt f 0Fπ₀ = π ⟨$⟩ˡ 0Fπ/0 = Perm.remove π₀ ππf = rearrange (π ⟨$⟩ʳ_) f∑-permute : ∀ {m n} (f : Vector Carrier n) (π : Permutation m n) →∑[ i < n ] f i ≈ ∑[ i < m ] f (π ⟨$⟩ʳ i)∑-permute f π = sum-permute f π
-------------------------------------------------------------------------- The Agda standard library---- Multiplication over a monoid (i.e. repeated addition)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (CommutativeMonoid)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)module Algebra.Properties.CommutativeMonoid.Mult{a ℓ} (M : CommutativeMonoid a ℓ) where-- View of the monoid operator as additionopen CommutativeMonoid Mrenaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congʳ to +-congʳ; ∙-congˡ to +-congˡ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Relation.Binary.Reasoning.Setoid setoidopen import Algebra.Properties.CommutativeSemigroup commutativeSemigroup-------------------------------------------------------------------------- Re-export definition and properties for monoidsopen import Algebra.Properties.Monoid.Mult monoid public-------------------------------------------------------------------------- Properties of _×_×-distrib-+ : ∀ x y n → n × (x + y) ≈ n × x + n × y×-distrib-+ x y zero = sym (+-identityˡ 0# )×-distrib-+ x y (suc n) = beginx + y + n × (x + y) ≈⟨ +-congˡ (×-distrib-+ x y n) ⟩x + y + (n × x + n × y) ≈⟨ +-assoc x y (n × x + n × y) ⟩x + (y + (n × x + n × y)) ≈⟨ +-congˡ (x∙yz≈y∙xz y (n × x) (n × y)) ⟩x + (n × x + suc n × y) ≈⟨ x∙yz≈xy∙z x (n × x) (suc n × y) ⟩suc n × x + suc n × y ∎
-------------------------------------------------------------------------- The Agda standard library---- Multiplication over a monoid (i.e. repeated addition) optimised for-- type checking.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (CommutativeMonoid)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)module Algebra.Properties.CommutativeMonoid.Mult.TCOptimised{a ℓ} (M : CommutativeMonoid a ℓ) whereopen CommutativeMonoid M renaming( _∙_ to _+_; ∙-cong to +-cong; ∙-congˡ to +-congˡ; ∙-congʳ to +-congʳ; identityˡ to +-identityˡ; identityʳ to +-identityʳ; assoc to +-assoc; ε to 0#)open import Algebra.Properties.CommutativeMonoid.Mult M as Uusing () renaming (_×_ to _×ᵤ_)open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Re-export definition and properties for monoidsopen import Algebra.Properties.Monoid.Mult.TCOptimised monoid public-------------------------------------------------------------------------- Properties×-distrib-+ : ∀ x y n → n × (x + y) ≈ n × x + n × y×-distrib-+ x y n = beginn × (x + y) ≈⟨ ×ᵤ≈× n (x + y) ⟨n ×ᵤ (x + y) ≈⟨ U.×-distrib-+ x y n ⟩n ×ᵤ x + n ×ᵤ y ≈⟨ +-cong (×ᵤ≈× n x) (×ᵤ≈× n y) ⟩n × x + n × y ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties of divisibility over commutative magmas------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CommutativeMagma)open import Data.Product.Base using (_×_; _,_; map)module Algebra.Properties.CommutativeMagma.Divisibility{a ℓ} (CM : CommutativeMagma a ℓ)whereopen CommutativeMagma CMopen import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Re-export the contents of magmasopen import Algebra.Properties.Magma.Divisibility magma public-------------------------------------------------------------------------- Further propertiesx∣xy : ∀ x y → x ∣ x ∙ yx∣xy x y = y , comm y xxy≈z⇒x∣z : ∀ x y {z} → x ∙ y ≈ z → x ∣ zxy≈z⇒x∣z x y xy≈z = ∣-respʳ xy≈z (x∣xy x y)∣-factors : ∀ x y → (x ∣ x ∙ y) × (y ∣ x ∙ y)∣-factors x y = x∣xy x y , x∣yx y x∣-factors-≈ : ∀ x y {z} → x ∙ y ≈ z → x ∣ z × y ∣ z∣-factors-≈ x y xy≈z = xy≈z⇒x∣z x y xy≈z , xy≈z⇒y∣z x y xy≈z
-------------------------------------------------------------------------- The Agda standard library---- Some properties of operations in CancellativeCommutativeSemiring.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CancellativeCommutativeSemiring)open import Algebra.Definitions using (AlmostRightCancellative)open import Data.Sum.Base using (_⊎_; inj₁; inj₂)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary.Decidable using (yes; no)open import Relation.Nullary.Negation using (contradiction)module Algebra.Properties.CancellativeCommutativeSemiring{a ℓ} (R : CancellativeCommutativeSemiring a ℓ)whereopen CancellativeCommutativeSemiring Ropen import Algebra.Consequences.Setoid setoidopen import Relation.Binary.Reasoning.Setoid setoid*-almostCancelʳ : AlmostRightCancellative _≈_ 0# _*_*-almostCancelʳ = comm+almostCancelˡ⇒almostCancelʳ *-comm *-cancelˡ-nonZeroxy≈0⇒x≈0∨y≈0 : Decidable _≈_ → ∀ {x y} → x * y ≈ 0# → x ≈ 0# ⊎ y ≈ 0#xy≈0⇒x≈0∨y≈0 _≟_ {x} {y} xy≈0 with x ≟ 0# | y ≟ 0#... | yes x≈0 | _ = inj₁ x≈0... | no _ | yes y≈0 = inj₂ y≈0... | no x≉0 | no y≉0 = contradiction y≈0 y≉0wherexy≈x*0 = trans xy≈0 (sym (zeroʳ x))y≈0 = *-cancelˡ-nonZero _ y 0# x≉0 xy≈x*0x≉0∧y≉0⇒xy≉0 : Decidable _≈_ → ∀ {x y} → x ≉ 0# → y ≉ 0# → x * y ≉ 0#x≉0∧y≉0⇒xy≉0 _≟_ x≉0 y≉0 xy≈0 with xy≈0⇒x≈0∨y≈0 _≟_ xy≈0... | inj₁ x≈0 = x≉0 x≈0... | inj₂ y≈0 = y≉0 y≈0
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- Disabled to prevent warnings from deprecated names{-# OPTIONS --warn=noUserWarning #-}open import Algebra.Lattice.Bundlesmodule Algebra.Properties.BooleanAlgebra{b₁ b₂} (B : BooleanAlgebra b₁ b₂)where{-# WARNING_ON_IMPORT"Algebra.Properties.BooleanAlgebra was deprecated in v2.0.Use Algebra.Lattice.Properties.BooleanAlgebra instead."#-}open import Algebra.Lattice.Properties.BooleanAlgebra B publicopen BooleanAlgebra Bimport Algebra.Properties.DistributiveLattice as DistribLatticePropertiesopen import Algebra.Structures _≈_open import Relation.Binaryopen import Function.Bundles using (module Equivalence; _⇔_)open import Data.Product.Base using (_,_)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.4replace-equality : {_≈′_ : Rel Carrier b₂} →(∀ {x y} → x ≈ y ⇔ (x ≈′ y)) →BooleanAlgebra _ _replace-equality {_≈′_} ≈⇔≈′ = record{ isBooleanAlgebra = record{ isDistributiveLattice = DistributiveLattice.isDistributiveLattice(DistribLatticeProperties.replace-equality distributiveLattice ≈⇔≈′); ∨-complement = ((λ x → to (∨-complementˡ x)) , λ x → to (∨-complementʳ x)); ∧-complement = ((λ x → to (∧-complementˡ x)) , λ x → to (∧-complementʳ x)); ¬-cong = λ i≈j → to (¬-cong (from i≈j))}} where open module E {x y} = Equivalence (≈⇔≈′ {x} {y}){-# WARNING_ON_USAGE replace-equality"Warning: replace-equality was deprecated in v1.4.Please use isBooleanAlgebra from `Algebra.Construct.Subst.Equality` instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Latticemodule Algebra.Properties.BooleanAlgebra.Expression{b} (B : BooleanAlgebra b b)where{-# WARNING_ON_IMPORT"Algebra.Properties.BooleanAlgebra.Expression was deprecated in v2.0.Use Algebra.Lattice.Properties.BooleanAlgebra.Expression instead."#-}open import Algebra.Lattice.Properties.BooleanAlgebra.Expression
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Properties.AbelianGroup{a ℓ} (G : AbelianGroup a ℓ) whereopen AbelianGroup Gopen import Function.Base using (_$_)open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Publicly re-export group propertiesopen import Algebra.Properties.Group group public-------------------------------------------------------------------------- Properties of abelian groups⁻¹-anti-homo‿- : ∀ x y → (x - y) ⁻¹ ≈ y - x⁻¹-anti-homo‿- = ⁻¹-anti-homo-//xyx⁻¹≈y : ∀ x y → x ∙ y ∙ x ⁻¹ ≈ yxyx⁻¹≈y x y = beginx ∙ y ∙ x ⁻¹ ≈⟨ ∙-congʳ $ comm _ _ ⟩y ∙ x ∙ x ⁻¹ ≈⟨ assoc _ _ _ ⟩y ∙ (x ∙ x ⁻¹) ≈⟨ ∙-congˡ $ inverseʳ _ ⟩y ∙ ε ≈⟨ identityʳ _ ⟩y ∎⁻¹-∙-comm : ∀ x y → x ⁻¹ ∙ y ⁻¹ ≈ (x ∙ y) ⁻¹⁻¹-∙-comm x y = beginx ⁻¹ ∙ y ⁻¹ ≈⟨ ⁻¹-anti-homo-∙ y x ⟨(y ∙ x) ⁻¹ ≈⟨ ⁻¹-cong $ comm y x ⟩(x ∙ y) ⁻¹ ∎
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- Disabled to prevent warnings from deprecated-- Algebra.Operations.CommutativeMonoid{-# OPTIONS --warn=noUserWarning #-}open import Algebraimport Algebra.Operations.CommutativeMonoid as MonoidOperationsmodule Algebra.Operations.Semiring {s₁ s₂} (S : Semiring s₁ s₂) where{-# WARNING_ON_IMPORT"Algebra.Operations.Semiring was deprecated in v1.5.Use Algebra.Properties.Semiring.(Mult/Exp) instead."#-}open Semiring S-------------------------------------------------------------------------- Re-exportsopen MonoidOperations +-commutativeMonoid publicopen import Algebra.Properties.Semiring.Exp S publicopen import Algebra.Properties.Semiring.Mult S publicusing (×1-homo-*)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Operations.Ring{ℓ₁ ℓ₂} (ring : RawRing ℓ₁ ℓ₂)where{-# WARNING_ON_IMPORT"Algebra.Operations.Ring was deprecated in v1.5.Use Algebra.Properties.Semiring.Exp(.TCOptimised) instead."#-}open import Data.Nat.Base as ℕ using (ℕ; suc; zero)open RawRing ringinfixr 8 _^_+1_^_+1 : Carrier → ℕ → Carrierx ^ zero +1 = xx ^ suc n +1 = (x ^ n +1) * xinfixr 8 _^__^_ : Carrier → ℕ → Carrierx ^ zero = 1#x ^ suc i = x ^ i +1{-# INLINE _^_ #-}
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.List.Base as List using (List; []; _∷_; _++_)open import Data.Fin.Base using (Fin; zero)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Function.Base using (_∘_)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)module Algebra.Operations.CommutativeMonoid{s₁ s₂} (CM : CommutativeMonoid s₁ s₂)where{-# WARNING_ON_IMPORT"Algebra.Operations.CommutativeMonoid was deprecated in v1.5.Use Algebra.Properties.CommutativeMonoid.(Sum/Mult/Exp)(.TCOptimised) instead."#-}open CommutativeMonoid CMrenaming( _∙_ to _+_; ε to 0#; identityʳ to +-identityʳ; identityˡ to +-identityˡ; ∙-cong to +-cong; ∙-congˡ to +-congˡ; assoc to +-assoc)open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Multiplicationinfixr 8 _×_ _×′__×_ : ℕ → Carrier → Carrier0 × x = 0#suc n × x = x + (n × x)_×′_ : ℕ → Carrier → Carrier0 ×′ x = 0#1 ×′ x = xsuc n ×′ x = x + n ×′ x-------------------------------------------------------------------------- Properties of _×_×-congʳ : ∀ n → (n ×_) Preserves _≈_ ⟶ _≈_×-congʳ 0 x≈x′ = refl×-congʳ (suc n) x≈x′ = +-cong x≈x′ (×-congʳ n x≈x′)×-cong : _×_ Preserves₂ _≡_ ⟶ _≈_ ⟶ _≈_×-cong {u} ≡.refl x≈x′ = ×-congʳ u x≈x′-- _×_ is homomorphic with respect to _ℕ+_/_+_.×-homo-+ : ∀ c m n → (m ℕ.+ n) × c ≈ m × c + n × c×-homo-+ c 0 n = sym (+-identityˡ (n × c))×-homo-+ c (suc m) n = beginc + (m ℕ.+ n) × c ≈⟨ +-cong refl (×-homo-+ c m n) ⟩c + (m × c + n × c) ≈⟨ sym (+-assoc c (m × c) (n × c)) ⟩c + m × c + n × c ∎-------------------------------------------------------------------------- Properties of _×′_1+×′ : ∀ n x → suc n ×′ x ≈ x + n ×′ x1+×′ 0 x = sym (+-identityʳ x)1+×′ (suc n) x = refl-- _×_ and _×′_ are extensionally equal (up to the setoid-- equivalence).×≈×′ : ∀ n x → n × x ≈ n ×′ x×≈×′ 0 x = refl×≈×′ (suc n) x = beginx + n × x ≈⟨ +-congˡ (×≈×′ n x) ⟩x + n ×′ x ≈⟨ sym (1+×′ n x) ⟩suc n ×′ x ∎-- _×′_ is homomorphic with respect to _ℕ+_/_+_.×′-homo-+ : ∀ c m n → (m ℕ.+ n) ×′ c ≈ m ×′ c + n ×′ c×′-homo-+ c m n = begin(m ℕ.+ n) ×′ c ≈⟨ sym (×≈×′ (m ℕ.+ n) c) ⟩(m ℕ.+ n) × c ≈⟨ ×-homo-+ c m n ⟩m × c + n × c ≈⟨ +-cong (×≈×′ m c) (×≈×′ n c) ⟩m ×′ c + n ×′ c ∎-- _×′_ preserves equality.×′-cong : _×′_ Preserves₂ _≡_ ⟶ _≈_ ⟶ _≈_×′-cong {n} {_} {x} {y} ≡.refl x≈y = beginn ×′ x ≈⟨ sym (×≈×′ n x) ⟩n × x ≈⟨ ×-congʳ n x≈y ⟩n × y ≈⟨ ×≈×′ n y ⟩n ×′ y ∎
-------------------------------------------------------------------------- The Agda standard library---- Morphisms between algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Morphism whereimport Algebra.Morphism.Definitions as MorphismDefinitionsopen import Algebraimport Algebra.Properties.Group as GroupPopen import Function.Baseopen import Levelopen import Relation.Binary.Core using (Rel; _Preserves_⟶_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatevariablea b ℓ₁ ℓ₂ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Re-exportmodule Definitions {a b ℓ₁} (A : Set a) (B : Set b) (_≈_ : Rel B ℓ₁) whereopen MorphismDefinitions A B _≈_ publicopen import Algebra.Morphism.Structures public-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new definitions re-exported from-- `Algebra.Morphism.Structures` as continuing support for the below is-- no guaranteed.-- Version 1.5module _ {c₁ ℓ₁ c₂ ℓ₂}(From : Semigroup c₁ ℓ₁)(To : Semigroup c₂ ℓ₂) whereprivatemodule F = Semigroup Frommodule T = Semigroup Toopen Definitions F.Carrier T.Carrier T._≈_record IsSemigroupMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefield⟦⟧-cong : ⟦_⟧ Preserves F._≈_ ⟶ T._≈_∙-homo : Homomorphic₂ ⟦_⟧ F._∙_ T._∙_IsSemigroupMorphism-syntax = IsSemigroupMorphismsyntax IsSemigroupMorphism-syntax From To F = F Is From -Semigroup⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : Monoid c₁ ℓ₁)(To : Monoid c₂ ℓ₂) whereprivatemodule F = Monoid Frommodule T = Monoid Toopen Definitions F.Carrier T.Carrier T._≈_record IsMonoidMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefieldsm-homo : IsSemigroupMorphism F.semigroup T.semigroup ⟦_⟧ε-homo : Homomorphic₀ ⟦_⟧ F.ε T.εopen IsSemigroupMorphism sm-homo publicIsMonoidMorphism-syntax = IsMonoidMorphismsyntax IsMonoidMorphism-syntax From To F = F Is From -Monoid⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : CommutativeMonoid c₁ ℓ₁)(To : CommutativeMonoid c₂ ℓ₂) whereprivatemodule F = CommutativeMonoid Frommodule T = CommutativeMonoid Toopen Definitions F.Carrier T.Carrier T._≈_record IsCommutativeMonoidMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefieldmn-homo : IsMonoidMorphism F.monoid T.monoid ⟦_⟧open IsMonoidMorphism mn-homo publicIsCommutativeMonoidMorphism-syntax = IsCommutativeMonoidMorphismsyntax IsCommutativeMonoidMorphism-syntax From To F = F Is From -CommutativeMonoid⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : IdempotentCommutativeMonoid c₁ ℓ₁)(To : IdempotentCommutativeMonoid c₂ ℓ₂) whereprivatemodule F = IdempotentCommutativeMonoid Frommodule T = IdempotentCommutativeMonoid Toopen Definitions F.Carrier T.Carrier T._≈_record IsIdempotentCommutativeMonoidMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefieldmn-homo : IsMonoidMorphism F.monoid T.monoid ⟦_⟧open IsMonoidMorphism mn-homo publicisCommutativeMonoidMorphism :IsCommutativeMonoidMorphism F.commutativeMonoid T.commutativeMonoid ⟦_⟧isCommutativeMonoidMorphism = record { mn-homo = mn-homo }IsIdempotentCommutativeMonoidMorphism-syntax = IsIdempotentCommutativeMonoidMorphismsyntax IsIdempotentCommutativeMonoidMorphism-syntax From To F = F Is From -IdempotentCommutativeMonoid⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : Group c₁ ℓ₁)(To : Group c₂ ℓ₂) whereprivatemodule F = Group Frommodule T = Group Toopen Definitions F.Carrier T.Carrier T._≈_record IsGroupMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefieldmn-homo : IsMonoidMorphism F.monoid T.monoid ⟦_⟧open IsMonoidMorphism mn-homo public⁻¹-homo : Homomorphic₁ ⟦_⟧ F._⁻¹ T._⁻¹⁻¹-homo x = let open ≈-Reasoning T.setoid in T.uniqueˡ-⁻¹ ⟦ x F.⁻¹ ⟧ ⟦ x ⟧ $ begin⟦ x F.⁻¹ ⟧ T.∙ ⟦ x ⟧ ≈⟨ T.sym (∙-homo (x F.⁻¹) x) ⟩⟦ x F.⁻¹ F.∙ x ⟧ ≈⟨ ⟦⟧-cong (F.inverseˡ x) ⟩⟦ F.ε ⟧ ≈⟨ ε-homo ⟩T.ε ∎IsGroupMorphism-syntax = IsGroupMorphismsyntax IsGroupMorphism-syntax From To F = F Is From -Group⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : AbelianGroup c₁ ℓ₁)(To : AbelianGroup c₂ ℓ₂) whereprivatemodule F = AbelianGroup Frommodule T = AbelianGroup Toopen Definitions F.Carrier T.Carrier T._≈_record IsAbelianGroupMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefieldgp-homo : IsGroupMorphism F.group T.group ⟦_⟧open IsGroupMorphism gp-homo publicIsAbelianGroupMorphism-syntax = IsAbelianGroupMorphismsyntax IsAbelianGroupMorphism-syntax From To F = F Is From -AbelianGroup⟶ Tomodule _ {c₁ ℓ₁ c₂ ℓ₂}(From : Ring c₁ ℓ₁)(To : Ring c₂ ℓ₂) whereprivatemodule F = Ring Frommodule T = Ring Toopen Definitions F.Carrier T.Carrier T._≈_record IsRingMorphism (⟦_⟧ : Morphism) :Set (c₁ ⊔ ℓ₁ ⊔ c₂ ⊔ ℓ₂) wherefield+-abgp-homo : ⟦_⟧ Is F.+-abelianGroup -AbelianGroup⟶ T.+-abelianGroup*-mn-homo : ⟦_⟧ Is F.*-monoid -Monoid⟶ T.*-monoidIsRingMorphism-syntax = IsRingMorphismsyntax IsRingMorphism-syntax From To F = F Is From -Ring⟶ To{-# WARNING_ON_USAGE IsSemigroupMorphism"Warning: IsSemigroupMorphism was deprecated in v1.5.Please use IsMagmaHomomorphism instead."#-}{-# WARNING_ON_USAGE IsMonoidMorphism"Warning: IsMonoidMorphism was deprecated in v1.5.Please use IsMonoidHomomorphism instead."#-}{-# WARNING_ON_USAGE IsCommutativeMonoidMorphism"Warning: IsCommutativeMonoidMorphism was deprecated in v1.5.Please use IsMonoidHomomorphism instead."#-}{-# WARNING_ON_USAGE IsIdempotentCommutativeMonoidMorphism"Warning: IsIdempotentCommutativeMonoidMorphism was deprecated in v1.5.Please use IsMonoidHomomorphism instead."#-}{-# WARNING_ON_USAGE IsGroupMorphism"Warning: IsGroupMorphism was deprecated in v1.5.Please use IsGroupHomomorphism instead."#-}{-# WARNING_ON_USAGE IsAbelianGroupMorphism"Warning: IsAbelianGroupMorphism was deprecated in v1.5.Please use IsGroupHomomorphism instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Morphisms between algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Morphism.Structures whereopen import Algebra.Coreopen import Algebra.Bundlesimport Algebra.Morphism.Definitions as MorphismDefinitionsopen import Level using (Level; _⊔_)open import Function.Definitionsopen import Relation.Binary.Coreopen import Relation.Binary.Morphism.Structuresprivatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Morphisms over SuccessorSet-like structures------------------------------------------------------------------------module SuccessorSetMorphisms(N₁ : RawSuccessorSet a ℓ₁) (N₂ : RawSuccessorSet b ℓ₂)whereopen RawSuccessorSet N₁renaming (Carrier to A; _≈_ to _≈₁_; suc# to suc#₁; zero# to zero#₁)open RawSuccessorSet N₂renaming (Carrier to B; _≈_ to _≈₂_; suc# to suc#₂; zero# to zero#₂)open MorphismDefinitions A B _≈₂_record IsSuccessorSetHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRelHomomorphism : IsRelHomomorphism _≈₁_ _≈₂_ ⟦_⟧suc#-homo : Homomorphic₁ ⟦_⟧ suc#₁ suc#₂zero#-homo : Homomorphic₀ ⟦_⟧ zero#₁ zero#₂record IsSuccessorSetMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSuccessorSetHomomorphism : IsSuccessorSetHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsSuccessorSetHomomorphism isSuccessorSetHomomorphism publicisRelMonomorphism : IsRelMonomorphism _≈₁_ _≈₂_ ⟦_⟧isRelMonomorphism = record{ isHomomorphism = isRelHomomorphism; injective = injective}record IsSuccessorSetIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSuccessorSetMonomorphism : IsSuccessorSetMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsSuccessorSetMonomorphism isSuccessorSetMonomorphism publicisRelIsomorphism : IsRelIsomorphism _≈₁_ _≈₂_ ⟦_⟧isRelIsomorphism = record{ isMonomorphism = isRelMonomorphism; surjective = surjective}-------------------------------------------------------------------------- Morphisms over magma-like structures------------------------------------------------------------------------module MagmaMorphisms (M₁ : RawMagma a ℓ₁) (M₂ : RawMagma b ℓ₂) whereopen RawMagma M₁ renaming (Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_)open RawMagma M₂ renaming (Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_)open MorphismDefinitions A B _≈₂_record IsMagmaHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRelHomomorphism : IsRelHomomorphism _≈₁_ _≈₂_ ⟦_⟧homo : Homomorphic₂ ⟦_⟧ _∙_ _◦_open IsRelHomomorphism isRelHomomorphism publicrenaming (cong to ⟦⟧-cong)record IsMagmaMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMagmaHomomorphism : IsMagmaHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsMagmaHomomorphism isMagmaHomomorphism publicisRelMonomorphism : IsRelMonomorphism _≈₁_ _≈₂_ ⟦_⟧isRelMonomorphism = record{ isHomomorphism = isRelHomomorphism; injective = injective}record IsMagmaIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMagmaMonomorphism : IsMagmaMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsMagmaMonomorphism isMagmaMonomorphism publicisRelIsomorphism : IsRelIsomorphism _≈₁_ _≈₂_ ⟦_⟧isRelIsomorphism = record{ isMonomorphism = isRelMonomorphism; surjective = surjective}-------------------------------------------------------------------------- Morphisms over monoid-like structures------------------------------------------------------------------------module MonoidMorphisms (M₁ : RawMonoid a ℓ₁) (M₂ : RawMonoid b ℓ₂) whereopen RawMonoid M₁ renaming (Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_; ε to ε₁)open RawMonoid M₂ renaming (Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_; ε to ε₂)open MorphismDefinitions A B _≈₂_open MagmaMorphisms (RawMonoid.rawMagma M₁) (RawMonoid.rawMagma M₂)record IsMonoidHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMagmaHomomorphism : IsMagmaHomomorphism ⟦_⟧ε-homo : Homomorphic₀ ⟦_⟧ ε₁ ε₂open IsMagmaHomomorphism isMagmaHomomorphism publicrecord IsMonoidMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMonoidHomomorphism : IsMonoidHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsMonoidHomomorphism isMonoidHomomorphism publicisMagmaMonomorphism : IsMagmaMonomorphism ⟦_⟧isMagmaMonomorphism = record{ isMagmaHomomorphism = isMagmaHomomorphism; injective = injective}open IsMagmaMonomorphism isMagmaMonomorphism publicusing (isRelMonomorphism)record IsMonoidIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMonoidMonomorphism : IsMonoidMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsMonoidMonomorphism isMonoidMonomorphism publicisMagmaIsomorphism : IsMagmaIsomorphism ⟦_⟧isMagmaIsomorphism = record{ isMagmaMonomorphism = isMagmaMonomorphism; surjective = surjective}open IsMagmaIsomorphism isMagmaIsomorphism publicusing (isRelIsomorphism)-------------------------------------------------------------------------- Morphisms over group-like structures------------------------------------------------------------------------module GroupMorphisms (G₁ : RawGroup a ℓ₁) (G₂ : RawGroup b ℓ₂) whereopen RawGroup G₁ renaming(Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_; _⁻¹ to _⁻¹₁; ε to ε₁)open RawGroup G₂ renaming(Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_; _⁻¹ to _⁻¹₂; ε to ε₂)open MorphismDefinitions A B _≈₂_open MagmaMorphisms (RawGroup.rawMagma G₁) (RawGroup.rawMagma G₂)open MonoidMorphisms (RawGroup.rawMonoid G₁) (RawGroup.rawMonoid G₂)record IsGroupHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisMonoidHomomorphism : IsMonoidHomomorphism ⟦_⟧⁻¹-homo : Homomorphic₁ ⟦_⟧ _⁻¹₁ _⁻¹₂open IsMonoidHomomorphism isMonoidHomomorphism publicrecord IsGroupMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisGroupHomomorphism : IsGroupHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsGroupHomomorphism isGroupHomomorphism publicrenaming (homo to ∙-homo)isMonoidMonomorphism : IsMonoidMonomorphism ⟦_⟧isMonoidMonomorphism = record{ isMonoidHomomorphism = isMonoidHomomorphism; injective = injective}open IsMonoidMonomorphism isMonoidMonomorphism publicusing (isRelMonomorphism; isMagmaMonomorphism)record IsGroupIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisGroupMonomorphism : IsGroupMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsGroupMonomorphism isGroupMonomorphism publicisMonoidIsomorphism : IsMonoidIsomorphism ⟦_⟧isMonoidIsomorphism = record{ isMonoidMonomorphism = isMonoidMonomorphism; surjective = surjective}open IsMonoidIsomorphism isMonoidIsomorphism publicusing (isRelIsomorphism; isMagmaIsomorphism)-------------------------------------------------------------------------- Morphisms over near-semiring-like structures------------------------------------------------------------------------module NearSemiringMorphisms (R₁ : RawNearSemiring a ℓ₁) (R₂ : RawNearSemiring b ℓ₂) whereopen RawNearSemiring R₁ renaming( Carrier to A; _≈_ to _≈₁_; +-rawMonoid to +-rawMonoid₁; _*_ to _*₁_; *-rawMagma to *-rawMagma₁)open RawNearSemiring R₂ renaming( Carrier to B; _≈_ to _≈₂_; +-rawMonoid to +-rawMonoid₂; _*_ to _*₂_; *-rawMagma to *-rawMagma₂)privatemodule + = MonoidMorphisms +-rawMonoid₁ +-rawMonoid₂module * = MagmaMorphisms *-rawMagma₁ *-rawMagma₂open MorphismDefinitions A B _≈₂_record IsNearSemiringHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefield+-isMonoidHomomorphism : +.IsMonoidHomomorphism ⟦_⟧*-homo : Homomorphic₂ ⟦_⟧ _*₁_ _*₂_open +.IsMonoidHomomorphism +-isMonoidHomomorphism publicrenaming (homo to +-homo; ε-homo to 0#-homo; isMagmaHomomorphism to +-isMagmaHomomorphism)*-isMagmaHomomorphism : *.IsMagmaHomomorphism ⟦_⟧*-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = *-homo}record IsNearSemiringMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisNearSemiringHomomorphism : IsNearSemiringHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsNearSemiringHomomorphism isNearSemiringHomomorphism public+-isMonoidMonomorphism : +.IsMonoidMonomorphism ⟦_⟧+-isMonoidMonomorphism = record{ isMonoidHomomorphism = +-isMonoidHomomorphism; injective = injective}open +.IsMonoidMonomorphism +-isMonoidMonomorphism publicusing (isRelMonomorphism)renaming (isMagmaMonomorphism to +-isMagmaMonomorphsm)*-isMagmaMonomorphism : *.IsMagmaMonomorphism ⟦_⟧*-isMagmaMonomorphism = record{ isMagmaHomomorphism = *-isMagmaHomomorphism; injective = injective}record IsNearSemiringIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisNearSemiringMonomorphism : IsNearSemiringMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsNearSemiringMonomorphism isNearSemiringMonomorphism public+-isMonoidIsomorphism : +.IsMonoidIsomorphism ⟦_⟧+-isMonoidIsomorphism = record{ isMonoidMonomorphism = +-isMonoidMonomorphism; surjective = surjective}open +.IsMonoidIsomorphism +-isMonoidIsomorphism publicusing (isRelIsomorphism)renaming (isMagmaIsomorphism to +-isMagmaIsomorphism)*-isMagmaIsomorphism : *.IsMagmaIsomorphism ⟦_⟧*-isMagmaIsomorphism = record{ isMagmaMonomorphism = *-isMagmaMonomorphism; surjective = surjective}-------------------------------------------------------------------------- Morphisms over semiring-like structures------------------------------------------------------------------------module SemiringMorphisms (R₁ : RawSemiring a ℓ₁) (R₂ : RawSemiring b ℓ₂) whereopen RawSemiring R₁ renaming( Carrier to A; _≈_ to _≈₁_; 1# to 1#₁; rawNearSemiring to rawNearSemiring₁; *-rawMonoid to *-rawMonoid₁)open RawSemiring R₂ renaming( Carrier to B; _≈_ to _≈₂_; 1# to 1#₂; rawNearSemiring to rawNearSemiring₂; *-rawMonoid to *-rawMonoid₂)privatemodule * = MonoidMorphisms *-rawMonoid₁ *-rawMonoid₂open MorphismDefinitions A B _≈₂_open NearSemiringMorphisms rawNearSemiring₁ rawNearSemiring₂record IsSemiringHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisNearSemiringHomomorphism : IsNearSemiringHomomorphism ⟦_⟧1#-homo : Homomorphic₀ ⟦_⟧ 1#₁ 1#₂open IsNearSemiringHomomorphism isNearSemiringHomomorphism public*-isMonoidHomomorphism : *.IsMonoidHomomorphism ⟦_⟧*-isMonoidHomomorphism = record{ isMagmaHomomorphism = *-isMagmaHomomorphism; ε-homo = 1#-homo}record IsSemiringMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSemiringHomomorphism : IsSemiringHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsSemiringHomomorphism isSemiringHomomorphism publicisNearSemiringMonomorphism : IsNearSemiringMonomorphism ⟦_⟧isNearSemiringMonomorphism = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism; injective = injective}open IsNearSemiringMonomorphism isNearSemiringMonomorphism publicusing (+-isMonoidMonomorphism; *-isMagmaMonomorphism)*-isMonoidMonomorphism : *.IsMonoidMonomorphism ⟦_⟧*-isMonoidMonomorphism = record{ isMonoidHomomorphism = *-isMonoidHomomorphism; injective = injective}record IsSemiringIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSemiringMonomorphism : IsSemiringMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsSemiringMonomorphism isSemiringMonomorphism publicisNearSemiringIsomorphism : IsNearSemiringIsomorphism ⟦_⟧isNearSemiringIsomorphism = record{ isNearSemiringMonomorphism = isNearSemiringMonomorphism; surjective = surjective}open IsNearSemiringIsomorphism isNearSemiringIsomorphism publicusing (+-isMonoidIsomorphism; *-isMagmaIsomorphism)*-isMonoidIsomorphism : *.IsMonoidIsomorphism ⟦_⟧*-isMonoidIsomorphism = record{ isMonoidMonomorphism = *-isMonoidMonomorphism; surjective = surjective}-------------------------------------------------------------------------- Morphisms over ringWithoutOne-like structures------------------------------------------------------------------------module RingWithoutOneMorphisms (R₁ : RawRingWithoutOne a ℓ₁) (R₂ : RawRingWithoutOne b ℓ₂) whereopen RawRingWithoutOne R₁ renaming( Carrier to A; _≈_ to _≈₁_; _*_ to _*₁_; *-rawMagma to *-rawMagma₁; +-rawGroup to +-rawGroup₁)open RawRingWithoutOne R₂ renaming( Carrier to B; _≈_ to _≈₂_; _*_ to _*₂_; *-rawMagma to *-rawMagma₂; +-rawGroup to +-rawGroup₂)privatemodule + = GroupMorphisms +-rawGroup₁ +-rawGroup₂module * = MagmaMorphisms *-rawMagma₁ *-rawMagma₂open MorphismDefinitions A B _≈₂_record IsRingWithoutOneHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefield+-isGroupHomomorphism : +.IsGroupHomomorphism ⟦_⟧*-homo : Homomorphic₂ ⟦_⟧ _*₁_ _*₂_open +.IsGroupHomomorphism +-isGroupHomomorphism publicrenaming (homo to +-homo; ε-homo to 0#-homo; isMagmaHomomorphism to +-isMagmaHomomorphism)*-isMagmaHomomorphism : *.IsMagmaHomomorphism ⟦_⟧*-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = *-homo}record IsRingWithoutOneMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRingWithoutOneHomomorphism : IsRingWithoutOneHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsRingWithoutOneHomomorphism isRingWithoutOneHomomorphism public+-isGroupMonomorphism : +.IsGroupMonomorphism ⟦_⟧+-isGroupMonomorphism = record{ isGroupHomomorphism = +-isGroupHomomorphism; injective = injective}open +.IsGroupMonomorphism +-isGroupMonomorphism publicusing (isRelMonomorphism)renaming (isMagmaMonomorphism to +-isMagmaMonomorphsm; isMonoidMonomorphism to +-isMonoidMonomorphism)*-isMagmaMonomorphism : *.IsMagmaMonomorphism ⟦_⟧*-isMagmaMonomorphism = record{ isMagmaHomomorphism = *-isMagmaHomomorphism; injective = injective}record IsRingWithoutOneIsoMorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRingWithoutOneMonomorphism : IsRingWithoutOneMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsRingWithoutOneMonomorphism isRingWithoutOneMonomorphism public+-isGroupIsomorphism : +.IsGroupIsomorphism ⟦_⟧+-isGroupIsomorphism = record{ isGroupMonomorphism = +-isGroupMonomorphism; surjective = surjective}open +.IsGroupIsomorphism +-isGroupIsomorphism publicusing (isRelIsomorphism)renaming (isMagmaIsomorphism to +-isMagmaIsomorphism; isMonoidIsomorphism to +-isMonoidIsomorphism)*-isMagmaIsomorphism : *.IsMagmaIsomorphism ⟦_⟧*-isMagmaIsomorphism = record{ isMagmaMonomorphism = *-isMagmaMonomorphism; surjective = surjective}-------------------------------------------------------------------------- Morphisms over ring-like structures------------------------------------------------------------------------module RingMorphisms (R₁ : RawRing a ℓ₁) (R₂ : RawRing b ℓ₂) whereopen RawRing R₁ renaming( Carrier to A; _≈_ to _≈₁_; -_ to -₁_; rawSemiring to rawSemiring₁; *-rawMonoid to *-rawMonoid₁; +-rawGroup to +-rawGroup₁)open RawRing R₂ renaming( Carrier to B; _≈_ to _≈₂_; -_ to -₂_; rawSemiring to rawSemiring₂; *-rawMonoid to *-rawMonoid₂; +-rawGroup to +-rawGroup₂)module + = GroupMorphisms +-rawGroup₁ +-rawGroup₂module * = MonoidMorphisms *-rawMonoid₁ *-rawMonoid₂open MorphismDefinitions A B _≈₂_open SemiringMorphisms rawSemiring₁ rawSemiring₂record IsRingHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSemiringHomomorphism : IsSemiringHomomorphism ⟦_⟧-‿homo : Homomorphic₁ ⟦_⟧ -₁_ -₂_open IsSemiringHomomorphism isSemiringHomomorphism public+-isGroupHomomorphism : +.IsGroupHomomorphism ⟦_⟧+-isGroupHomomorphism = record{ isMonoidHomomorphism = +-isMonoidHomomorphism; ⁻¹-homo = -‿homo}record IsRingMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRingHomomorphism : IsRingHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsRingHomomorphism isRingHomomorphism publicisSemiringMonomorphism : IsSemiringMonomorphism ⟦_⟧isSemiringMonomorphism = record{ isSemiringHomomorphism = isSemiringHomomorphism; injective = injective}+-isGroupMonomorphism : +.IsGroupMonomorphism ⟦_⟧+-isGroupMonomorphism = record{ isGroupHomomorphism = +-isGroupHomomorphism; injective = injective}open +.IsGroupMonomorphism +-isGroupMonomorphismusing (isRelMonomorphism)renaming ( isMagmaMonomorphism to +-isMagmaMonomorphism; isMonoidMonomorphism to +-isMonoidMonomorphism)*-isMonoidMonomorphism : *.IsMonoidMonomorphism ⟦_⟧*-isMonoidMonomorphism = record{ isMonoidHomomorphism = *-isMonoidHomomorphism; injective = injective}open *.IsMonoidMonomorphism *-isMonoidMonomorphism publicusing ()renaming (isMagmaMonomorphism to *-isMagmaMonomorphism)record IsRingIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRingMonomorphism : IsRingMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsRingMonomorphism isRingMonomorphism publicisSemiringIsomorphism : IsSemiringIsomorphism ⟦_⟧isSemiringIsomorphism = record{ isSemiringMonomorphism = isSemiringMonomorphism; surjective = surjective}+-isGroupIsomorphism : +.IsGroupIsomorphism ⟦_⟧+-isGroupIsomorphism = record{ isGroupMonomorphism = +-isGroupMonomorphism; surjective = surjective}open +.IsGroupIsomorphism +-isGroupIsomorphismusing (isRelIsomorphism)renaming ( isMagmaIsomorphism to +-isMagmaIsomorphism; isMonoidIsomorphism to +-isMonoidIsomorphisn)*-isMonoidIsomorphism : *.IsMonoidIsomorphism ⟦_⟧*-isMonoidIsomorphism = record{ isMonoidMonomorphism = *-isMonoidMonomorphism; surjective = surjective}open *.IsMonoidIsomorphism *-isMonoidIsomorphism publicusing ()renaming (isMagmaIsomorphism to *-isMagmaIsomorphisn)-------------------------------------------------------------------------- Morphisms over quasigroup-like structures------------------------------------------------------------------------module QuasigroupMorphisms (Q₁ : RawQuasigroup a ℓ₁) (Q₂ : RawQuasigroup b ℓ₂) whereopen RawQuasigroup Q₁ renaming (Carrier to A; ∙-rawMagma to ∙-rawMagma₁;\\-rawMagma to \\-rawMagma₁; //-rawMagma to //-rawMagma₁;_≈_ to _≈₁_; _∙_ to _∙₁_; _\\_ to _\\₁_; _//_ to _//₁_)open RawQuasigroup Q₂ renaming (Carrier to B; ∙-rawMagma to ∙-rawMagma₂;\\-rawMagma to \\-rawMagma₂; //-rawMagma to //-rawMagma₂;_≈_ to _≈₂_; _∙_ to _∙₂_; _\\_ to _\\₂_; _//_ to _//₂_)module ∙ = MagmaMorphisms ∙-rawMagma₁ ∙-rawMagma₂module \\ = MagmaMorphisms \\-rawMagma₁ \\-rawMagma₂module // = MagmaMorphisms //-rawMagma₁ //-rawMagma₂open MorphismDefinitions A B _≈₂_record IsQuasigroupHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRelHomomorphism : IsRelHomomorphism _≈₁_ _≈₂_ ⟦_⟧∙-homo : Homomorphic₂ ⟦_⟧ _∙₁_ _∙₂_\\-homo : Homomorphic₂ ⟦_⟧ _\\₁_ _\\₂_//-homo : Homomorphic₂ ⟦_⟧ _//₁_ _//₂_open IsRelHomomorphism isRelHomomorphism publicrenaming (cong to ⟦⟧-cong)∙-isMagmaHomomorphism : ∙.IsMagmaHomomorphism ⟦_⟧∙-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = ∙-homo}\\-isMagmaHomomorphism : \\.IsMagmaHomomorphism ⟦_⟧\\-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = \\-homo}//-isMagmaHomomorphism : //.IsMagmaHomomorphism ⟦_⟧//-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = //-homo}record IsQuasigroupMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisQuasigroupHomomorphism : IsQuasigroupHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsQuasigroupHomomorphism isQuasigroupHomomorphism public∙-isMagmaMonomorphism : ∙.IsMagmaMonomorphism ⟦_⟧∙-isMagmaMonomorphism = record{ isMagmaHomomorphism = ∙-isMagmaHomomorphism; injective = injective}\\-isMagmaMonomorphism : \\.IsMagmaMonomorphism ⟦_⟧\\-isMagmaMonomorphism = record{ isMagmaHomomorphism = \\-isMagmaHomomorphism; injective = injective}//-isMagmaMonomorphism : //.IsMagmaMonomorphism ⟦_⟧//-isMagmaMonomorphism = record{ isMagmaHomomorphism = //-isMagmaHomomorphism; injective = injective}open //.IsMagmaMonomorphism //-isMagmaMonomorphism publicusing (isRelMonomorphism)record IsQuasigroupIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisQuasigroupMonomorphism : IsQuasigroupMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsQuasigroupMonomorphism isQuasigroupMonomorphism public∙-isMagmaIsomorphism : ∙.IsMagmaIsomorphism ⟦_⟧∙-isMagmaIsomorphism = record{ isMagmaMonomorphism = ∙-isMagmaMonomorphism; surjective = surjective}\\-isMagmaIsomorphism : \\.IsMagmaIsomorphism ⟦_⟧\\-isMagmaIsomorphism = record{ isMagmaMonomorphism = \\-isMagmaMonomorphism; surjective = surjective}//-isMagmaIsomorphism : //.IsMagmaIsomorphism ⟦_⟧//-isMagmaIsomorphism = record{ isMagmaMonomorphism = //-isMagmaMonomorphism; surjective = surjective}open //.IsMagmaIsomorphism //-isMagmaIsomorphism publicusing (isRelIsomorphism)-------------------------------------------------------------------------- Morphisms over loop-like structures------------------------------------------------------------------------module LoopMorphisms (L₁ : RawLoop a ℓ₁) (L₂ : RawLoop b ℓ₂) whereopen RawLoop L₁ renaming (Carrier to A; ∙-rawMagma to ∙-rawMagma₁;\\-rawMagma to \\-rawMagma₁; //-rawMagma to //-rawMagma₁;_≈_ to _≈₁_; _∙_ to _∙₁_; _\\_ to _\\₁_; _//_ to _//₁_; ε to ε₁)open RawLoop L₂ renaming (Carrier to B; ∙-rawMagma to ∙-rawMagma₂;\\-rawMagma to \\-rawMagma₂; //-rawMagma to //-rawMagma₂;_≈_ to _≈₂_; _∙_ to _∙₂_; _\\_ to _\\₂_; _//_ to _//₂_ ; ε to ε₂)open MorphismDefinitions A B _≈₂_open QuasigroupMorphisms (RawLoop.rawQuasigroup L₁) (RawLoop.rawQuasigroup L₂)record IsLoopHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisQuasigroupHomomorphism : IsQuasigroupHomomorphism ⟦_⟧ε-homo : Homomorphic₀ ⟦_⟧ ε₁ ε₂open IsQuasigroupHomomorphism isQuasigroupHomomorphism publicrecord IsLoopMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLoopHomomorphism : IsLoopHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsLoopHomomorphism isLoopHomomorphism publicrecord IsLoopIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLoopMonomorphism : IsLoopMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsLoopMonomorphism isLoopMonomorphism public-------------------------------------------------------------------------- Morphisms over Kleene algebra structures------------------------------------------------------------------------module KleeneAlgebraMorphisms (R₁ : RawKleeneAlgebra a ℓ₁) (R₂ : RawKleeneAlgebra b ℓ₂) whereopen RawKleeneAlgebra R₁ renaming( Carrier to A; _≈_ to _≈₁_; _⋆ to _⋆₁; rawSemiring to rawSemiring₁)open RawKleeneAlgebra R₂ renaming( Carrier to B; _≈_ to _≈₂_; _⋆ to _⋆₂; rawSemiring to rawSemiring₂)open MorphismDefinitions A B _≈₂_open SemiringMorphisms rawSemiring₁ rawSemiring₂record IsKleeneAlgebraHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisSemiringHomomorphism : IsSemiringHomomorphism ⟦_⟧⋆-homo : Homomorphic₁ ⟦_⟧ _⋆₁ _⋆₂open IsSemiringHomomorphism isSemiringHomomorphism publicrecord IsKleeneAlgebraMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisKleeneAlgebraHomomorphism : IsKleeneAlgebraHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsKleeneAlgebraHomomorphism isKleeneAlgebraHomomorphism publicrecord IsKleeneAlgebraIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisKleeneAlgebraMonomorphism : IsKleeneAlgebraMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsKleeneAlgebraMonomorphism isKleeneAlgebraMonomorphism public-------------------------------------------------------------------------- Re-export contents of modules publiclyopen MagmaMorphisms publicopen MonoidMorphisms publicopen GroupMorphisms publicopen NearSemiringMorphisms publicopen SemiringMorphisms publicopen RingWithoutOneMorphisms publicopen RingMorphisms publicopen QuasigroupMorphisms publicopen LoopMorphisms publicopen KleeneAlgebraMorphisms public
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between ring-like structures-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesopen import Algebra.Morphism.Structuresimport Algebra.Morphism.GroupMonomorphism as GroupMonomorphismimport Algebra.Morphism.MonoidMonomorphism as MonoidMonomorphismopen import Relation.Binary.Coremodule Algebra.Morphism.RingMonomorphism{a b ℓ₁ ℓ₂} {R₁ : RawRing a ℓ₁} {R₂ : RawRing b ℓ₂} {⟦_⟧}(isRingMonomorphism : IsRingMonomorphism R₁ R₂ ⟦_⟧)whereopen IsRingMonomorphism isRingMonomorphismopen RawRing R₁ renaming (Carrier to A; _≈_ to _≈₁_)open RawRing R₂ renaming( Carrier to B; _≈_ to _≈₂_; _+_ to _⊕_; _*_ to _⊛_; 1# to 1#₂; 0# to 0#₂; -_ to ⊝_)open import Algebra.Definitionsopen import Algebra.Structuresopen import Data.Product.Base using (proj₁; proj₂; _,_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- Re-export all properties of group and monoid monomorphismsopen GroupMonomorphism +-isGroupMonomorphism publicrenaming( assoc to +-assoc; comm to +-comm; cong to +-cong; idem to +-idem; sel to +-sel; ⁻¹-cong to neg-cong; identity to +-identity; identityˡ to +-identityˡ; identityʳ to +-identityʳ; cancel to +-cancel; cancelˡ to +-cancelˡ; cancelʳ to +-cancelʳ; zero to +-zero; zeroˡ to +-zeroˡ; zeroʳ to +-zeroʳ; isMagma to +-isMagma; isSemigroup to +-isSemigroup; isMonoid to +-isMonoid; isSelectiveMagma to +-isSelectiveMagma; isBand to +-isBand; isCommutativeMonoid to +-isCommutativeMonoid)open MonoidMonomorphism *-isMonoidMonomorphism publicrenaming( assoc to *-assoc; comm to *-comm; cong to *-cong; idem to *-idem; sel to *-sel; identity to *-identity; identityˡ to *-identityˡ; identityʳ to *-identityʳ; cancel to *-cancel; cancelˡ to *-cancelˡ; cancelʳ to *-cancelʳ; zero to *-zero; zeroˡ to *-zeroˡ; zeroʳ to *-zeroʳ; isMagma to *-isMagma; isSemigroup to *-isSemigroup; isMonoid to *-isMonoid; isSelectiveMagma to *-isSelectiveMagma; isBand to *-isBand; isCommutativeMonoid to *-isCommutativeMonoid)-------------------------------------------------------------------------- Propertiesmodule _ (+-isGroup : IsGroup _≈₂_ _⊕_ 0#₂ ⊝_)(*-isMagma : IsMagma _≈₂_ _⊛_) whereopen IsGroup +-isGroup hiding (setoid; refl; sym)open IsMagma *-isMagma renaming (∙-cong to ◦-cong)open ≈-Reasoning setoiddistribˡ : _DistributesOverˡ_ _≈₂_ _⊛_ _⊕_ → _DistributesOverˡ_ _≈₁_ _*_ _+_distribˡ distribˡ x y z = injective (begin⟦ x * (y + z) ⟧ ≈⟨ *-homo x (y + z) ⟩⟦ x ⟧ ⊛ ⟦ y + z ⟧ ≈⟨ ◦-cong refl (+-homo y z) ⟩⟦ x ⟧ ⊛ (⟦ y ⟧ ⊕ ⟦ z ⟧) ≈⟨ distribˡ ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ ⟩⟦ x ⟧ ⊛ ⟦ y ⟧ ⊕ ⟦ x ⟧ ⊛ ⟦ z ⟧ ≈⟨ ∙-cong (*-homo x y) (*-homo x z) ⟨⟦ x * y ⟧ ⊕ ⟦ x * z ⟧ ≈⟨ +-homo (x * y) (x * z) ⟨⟦ x * y + x * z ⟧ ∎)distribʳ : _DistributesOverʳ_ _≈₂_ _⊛_ _⊕_ → _DistributesOverʳ_ _≈₁_ _*_ _+_distribʳ distribˡ x y z = injective (begin⟦ (y + z) * x ⟧ ≈⟨ *-homo (y + z) x ⟩⟦ y + z ⟧ ⊛ ⟦ x ⟧ ≈⟨ ◦-cong (+-homo y z) refl ⟩(⟦ y ⟧ ⊕ ⟦ z ⟧) ⊛ ⟦ x ⟧ ≈⟨ distribˡ ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ ⟩⟦ y ⟧ ⊛ ⟦ x ⟧ ⊕ ⟦ z ⟧ ⊛ ⟦ x ⟧ ≈⟨ ∙-cong (*-homo y x) (*-homo z x) ⟨⟦ y * x ⟧ ⊕ ⟦ z * x ⟧ ≈⟨ +-homo (y * x) (z * x) ⟨⟦ y * x + z * x ⟧ ∎)distrib : _DistributesOver_ _≈₂_ _⊛_ _⊕_ → _DistributesOver_ _≈₁_ _*_ _+_distrib distrib = distribˡ (proj₁ distrib) , distribʳ (proj₂ distrib)zeroˡ : LeftZero _≈₂_ 0#₂ _⊛_ → LeftZero _≈₁_ 0# _*_zeroˡ zeroˡ x = injective (begin⟦ 0# * x ⟧ ≈⟨ *-homo 0# x ⟩⟦ 0# ⟧ ⊛ ⟦ x ⟧ ≈⟨ ◦-cong 0#-homo refl ⟩0#₂ ⊛ ⟦ x ⟧ ≈⟨ zeroˡ ⟦ x ⟧ ⟩0#₂ ≈⟨ 0#-homo ⟨⟦ 0# ⟧ ∎)zeroʳ : RightZero _≈₂_ 0#₂ _⊛_ → RightZero _≈₁_ 0# _*_zeroʳ zeroʳ x = injective (begin⟦ x * 0# ⟧ ≈⟨ *-homo x 0# ⟩⟦ x ⟧ ⊛ ⟦ 0# ⟧ ≈⟨ ◦-cong refl 0#-homo ⟩⟦ x ⟧ ⊛ 0#₂ ≈⟨ zeroʳ ⟦ x ⟧ ⟩0#₂ ≈⟨ 0#-homo ⟨⟦ 0# ⟧ ∎)zero : Zero _≈₂_ 0#₂ _⊛_ → Zero _≈₁_ 0# _*_zero zero = zeroˡ (proj₁ zero) , zeroʳ (proj₂ zero)neg-distribˡ-* : (∀ x y → (⊝ (x ⊛ y)) ≈₂ ((⊝ x) ⊛ y)) → (∀ x y → (- (x * y)) ≈₁ ((- x) * y))neg-distribˡ-* neg-distribˡ-* x y = injective (begin⟦ - (x * y) ⟧ ≈⟨ -‿homo (x * y) ⟩⊝ ⟦ x * y ⟧ ≈⟨ ⁻¹-cong (*-homo x y) ⟩⊝ (⟦ x ⟧ ⊛ ⟦ y ⟧) ≈⟨ neg-distribˡ-* ⟦ x ⟧ ⟦ y ⟧ ⟩⊝ ⟦ x ⟧ ⊛ ⟦ y ⟧ ≈⟨ ◦-cong (sym (-‿homo x)) refl ⟩⟦ - x ⟧ ⊛ ⟦ y ⟧ ≈⟨ sym (*-homo (- x) y) ⟩⟦ - x * y ⟧ ∎)neg-distribʳ-* : (∀ x y → (⊝ (x ⊛ y)) ≈₂ (x ⊛ (⊝ y))) → (∀ x y → (- (x * y)) ≈₁ (x * (- y)))neg-distribʳ-* neg-distribʳ-* x y = injective (begin⟦ - (x * y) ⟧ ≈⟨ -‿homo (x * y) ⟩⊝ ⟦ x * y ⟧ ≈⟨ ⁻¹-cong (*-homo x y) ⟩⊝ (⟦ x ⟧ ⊛ ⟦ y ⟧) ≈⟨ neg-distribʳ-* ⟦ x ⟧ ⟦ y ⟧ ⟩⟦ x ⟧ ⊛ ⊝ ⟦ y ⟧ ≈⟨ ◦-cong refl (sym (-‿homo y)) ⟩⟦ x ⟧ ⊛ ⟦ - y ⟧ ≈⟨ sym (*-homo x (- y)) ⟩⟦ x * - y ⟧ ∎)isRing : IsRing _≈₂_ _⊕_ _⊛_ ⊝_ 0#₂ 1#₂ → IsRing _≈₁_ _+_ _*_ -_ 0# 1#isRing isRing = record{ +-isAbelianGroup = isAbelianGroup R.+-isAbelianGroup; *-cong = *-cong R.*-isMagma; *-assoc = *-assoc R.*-isMagma R.*-assoc; *-identity = *-identity R.*-isMagma R.*-identity; distrib = distrib R.+-isGroup R.*-isMagma R.distrib} where module R = IsRing isRingisCommutativeRing : IsCommutativeRing _≈₂_ _⊕_ _⊛_ ⊝_ 0#₂ 1#₂ →IsCommutativeRing _≈₁_ _+_ _*_ -_ 0# 1#isCommutativeRing isCommRing = record{ isRing = isRing C.isRing; *-comm = *-comm C.*-isMagma C.*-comm} where module C = IsCommutativeRing isCommRing
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between monoid-like structures-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesopen import Algebra.Morphism.Structuresopen import Relation.Binary.Coremodule Algebra.Morphism.MonoidMonomorphism{a b ℓ₁ ℓ₂} {M₁ : RawMonoid a ℓ₁} {M₂ : RawMonoid b ℓ₂} {⟦_⟧}(isMonoidMonomorphism : IsMonoidMonomorphism M₁ M₂ ⟦_⟧)whereopen IsMonoidMonomorphism isMonoidMonomorphismopen RawMonoid M₁ renaming (Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_; ε to ε₁)open RawMonoid M₂ renaming (Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_; ε to ε₂)open import Algebra.Definitionsopen import Algebra.Structuresopen import Data.Product.Base using (map)import Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- Re-export all properties of magma monomorphismsopen import Algebra.Morphism.MagmaMonomorphismisMagmaMonomorphism public-------------------------------------------------------------------------- Propertiesmodule _ (◦-isMagma : IsMagma _≈₂_ _◦_) whereopen IsMagma ◦-isMagma renaming (∙-cong to ◦-cong)open ≈-Reasoning setoididentityˡ : LeftIdentity _≈₂_ ε₂ _◦_ → LeftIdentity _≈₁_ ε₁ _∙_identityˡ idˡ x = injective (begin⟦ ε₁ ∙ x ⟧ ≈⟨ homo ε₁ x ⟩⟦ ε₁ ⟧ ◦ ⟦ x ⟧ ≈⟨ ◦-cong ε-homo refl ⟩ε₂ ◦ ⟦ x ⟧ ≈⟨ idˡ ⟦ x ⟧ ⟩⟦ x ⟧ ∎)identityʳ : RightIdentity _≈₂_ ε₂ _◦_ → RightIdentity _≈₁_ ε₁ _∙_identityʳ idʳ x = injective (begin⟦ x ∙ ε₁ ⟧ ≈⟨ homo x ε₁ ⟩⟦ x ⟧ ◦ ⟦ ε₁ ⟧ ≈⟨ ◦-cong refl ε-homo ⟩⟦ x ⟧ ◦ ε₂ ≈⟨ idʳ ⟦ x ⟧ ⟩⟦ x ⟧ ∎)identity : Identity _≈₂_ ε₂ _◦_ → Identity _≈₁_ ε₁ _∙_identity = map identityˡ identityʳzeroˡ : LeftZero _≈₂_ ε₂ _◦_ → LeftZero _≈₁_ ε₁ _∙_zeroˡ zeˡ x = injective (begin⟦ ε₁ ∙ x ⟧ ≈⟨ homo ε₁ x ⟩⟦ ε₁ ⟧ ◦ ⟦ x ⟧ ≈⟨ ◦-cong ε-homo refl ⟩ε₂ ◦ ⟦ x ⟧ ≈⟨ zeˡ ⟦ x ⟧ ⟩ε₂ ≈⟨ ε-homo ⟨⟦ ε₁ ⟧ ∎)zeroʳ : RightZero _≈₂_ ε₂ _◦_ → RightZero _≈₁_ ε₁ _∙_zeroʳ zeʳ x = injective (begin⟦ x ∙ ε₁ ⟧ ≈⟨ homo x ε₁ ⟩⟦ x ⟧ ◦ ⟦ ε₁ ⟧ ≈⟨ ◦-cong refl ε-homo ⟩⟦ x ⟧ ◦ ε₂ ≈⟨ zeʳ ⟦ x ⟧ ⟩ε₂ ≈⟨ ε-homo ⟨⟦ ε₁ ⟧ ∎)zero : Zero _≈₂_ ε₂ _◦_ → Zero _≈₁_ ε₁ _∙_zero = map zeroˡ zeroʳ-------------------------------------------------------------------------- StructuresisMonoid : IsMonoid _≈₂_ _◦_ ε₂ → IsMonoid _≈₁_ _∙_ ε₁isMonoid isMonoid = record{ isSemigroup = isSemigroup M.isSemigroup; identity = identity M.isMagma M.identity} where module M = IsMonoid isMonoidisCommutativeMonoid : IsCommutativeMonoid _≈₂_ _◦_ ε₂ →IsCommutativeMonoid _≈₁_ _∙_ ε₁isCommutativeMonoid isCommMonoid = record{ isMonoid = isMonoid C.isMonoid; comm = comm C.isMagma C.comm} where module C = IsCommutativeMonoid isCommMonoid
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between magma-like structures-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Morphism.Structuresopen import Relation.Binary.Coremodule Algebra.Morphism.MagmaMonomorphism{a b ℓ₁ ℓ₂} {M₁ : RawMagma a ℓ₁} {M₂ : RawMagma b ℓ₂} {⟦_⟧}(isMagmaMonomorphism : IsMagmaMonomorphism M₁ M₂ ⟦_⟧)whereopen IsMagmaMonomorphism isMagmaMonomorphismopen RawMagma M₁ renaming (Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_)open RawMagma M₂ renaming (Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_)open import Algebra.Structuresopen import Algebra.Definitionsopen import Data.Product.Base using (map)open import Data.Sum.Base using (inj₁; inj₂)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningimport Relation.Binary.Morphism.RelMonomorphism isRelMonomorphism as RelMorphism-------------------------------------------------------------------------- Propertiesmodule _ (◦-isMagma : IsMagma _≈₂_ _◦_) whereopen IsMagma ◦-isMagma renaming (∙-cong to ◦-cong)open ≈-Reasoning setoidcong : Congruent₂ _≈₁_ _∙_cong {x} {y} {u} {v} x≈y u≈v = injective (begin⟦ x ∙ u ⟧ ≈⟨ homo x u ⟩⟦ x ⟧ ◦ ⟦ u ⟧ ≈⟨ ◦-cong (⟦⟧-cong x≈y) (⟦⟧-cong u≈v) ⟩⟦ y ⟧ ◦ ⟦ v ⟧ ≈⟨ homo y v ⟨⟦ y ∙ v ⟧ ∎)assoc : Associative _≈₂_ _◦_ → Associative _≈₁_ _∙_assoc assoc x y z = injective (begin⟦ (x ∙ y) ∙ z ⟧ ≈⟨ homo (x ∙ y) z ⟩⟦ x ∙ y ⟧ ◦ ⟦ z ⟧ ≈⟨ ◦-cong (homo x y) refl ⟩(⟦ x ⟧ ◦ ⟦ y ⟧) ◦ ⟦ z ⟧ ≈⟨ assoc ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ ⟩⟦ x ⟧ ◦ (⟦ y ⟧ ◦ ⟦ z ⟧) ≈⟨ ◦-cong refl (homo y z) ⟨⟦ x ⟧ ◦ ⟦ y ∙ z ⟧ ≈⟨ homo x (y ∙ z) ⟨⟦ x ∙ (y ∙ z) ⟧ ∎)comm : Commutative _≈₂_ _◦_ → Commutative _≈₁_ _∙_comm comm x y = injective (begin⟦ x ∙ y ⟧ ≈⟨ homo x y ⟩⟦ x ⟧ ◦ ⟦ y ⟧ ≈⟨ comm ⟦ x ⟧ ⟦ y ⟧ ⟩⟦ y ⟧ ◦ ⟦ x ⟧ ≈⟨ homo y x ⟨⟦ y ∙ x ⟧ ∎)idem : Idempotent _≈₂_ _◦_ → Idempotent _≈₁_ _∙_idem idem x = injective (begin⟦ x ∙ x ⟧ ≈⟨ homo x x ⟩⟦ x ⟧ ◦ ⟦ x ⟧ ≈⟨ idem ⟦ x ⟧ ⟩⟦ x ⟧ ∎)sel : Selective _≈₂_ _◦_ → Selective _≈₁_ _∙_sel sel x y with sel ⟦ x ⟧ ⟦ y ⟧... | inj₁ x◦y≈x = inj₁ (injective (begin⟦ x ∙ y ⟧ ≈⟨ homo x y ⟩⟦ x ⟧ ◦ ⟦ y ⟧ ≈⟨ x◦y≈x ⟩⟦ x ⟧ ∎))... | inj₂ x◦y≈y = inj₂ (injective (begin⟦ x ∙ y ⟧ ≈⟨ homo x y ⟩⟦ x ⟧ ◦ ⟦ y ⟧ ≈⟨ x◦y≈y ⟩⟦ y ⟧ ∎))cancelˡ : LeftCancellative _≈₂_ _◦_ → LeftCancellative _≈₁_ _∙_cancelˡ cancelˡ x y z x∙y≈x∙z = injective (cancelˡ ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ (begin⟦ x ⟧ ◦ ⟦ y ⟧ ≈⟨ homo x y ⟨⟦ x ∙ y ⟧ ≈⟨ ⟦⟧-cong x∙y≈x∙z ⟩⟦ x ∙ z ⟧ ≈⟨ homo x z ⟩⟦ x ⟧ ◦ ⟦ z ⟧ ∎))cancelʳ : RightCancellative _≈₂_ _◦_ → RightCancellative _≈₁_ _∙_cancelʳ cancelʳ x y z y∙x≈z∙x = injective (cancelʳ ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ (begin⟦ y ⟧ ◦ ⟦ x ⟧ ≈⟨ homo y x ⟨⟦ y ∙ x ⟧ ≈⟨ ⟦⟧-cong y∙x≈z∙x ⟩⟦ z ∙ x ⟧ ≈⟨ homo z x ⟩⟦ z ⟧ ◦ ⟦ x ⟧ ∎))cancel : Cancellative _≈₂_ _◦_ → Cancellative _≈₁_ _∙_cancel = map cancelˡ cancelʳ-------------------------------------------------------------------------- StructuresisMagma : IsMagma _≈₂_ _◦_ → IsMagma _≈₁_ _∙_isMagma isMagma = record{ isEquivalence = RelMorphism.isEquivalence M.isEquivalence; ∙-cong = cong isMagma} where module M = IsMagma isMagmaisSemigroup : IsSemigroup _≈₂_ _◦_ → IsSemigroup _≈₁_ _∙_isSemigroup isSemigroup = record{ isMagma = isMagma S.isMagma; assoc = assoc S.isMagma S.assoc} where module S = IsSemigroup isSemigroupisBand : IsBand _≈₂_ _◦_ → IsBand _≈₁_ _∙_isBand isBand = record{ isSemigroup = isSemigroup B.isSemigroup; idem = idem B.isMagma B.idem} where module B = IsBand isBandisSelectiveMagma : IsSelectiveMagma _≈₂_ _◦_ → IsSelectiveMagma _≈₁_ _∙_isSelectiveMagma isSelMagma = record{ isMagma = isMagma S.isMagma; sel = sel S.isMagma S.sel} where module S = IsSelectiveMagma isSelMagma
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between group-like structures-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesopen import Algebra.Morphism.Structuresopen import Relation.Binary.Coremodule Algebra.Morphism.GroupMonomorphism{a b ℓ₁ ℓ₂} {G₁ : RawGroup a ℓ₁} {G₂ : RawGroup b ℓ₂} {⟦_⟧}(isGroupMonomorphism : IsGroupMonomorphism G₁ G₂ ⟦_⟧)whereopen IsGroupMonomorphism isGroupMonomorphismopen RawGroup G₁ renaming(Carrier to A; _≈_ to _≈₁_; _∙_ to _∙_; _⁻¹ to _⁻¹₁; ε to ε₁)open RawGroup G₂ renaming(Carrier to B; _≈_ to _≈₂_; _∙_ to _◦_; _⁻¹ to _⁻¹₂; ε to ε₂)open import Algebra.Definitionsopen import Algebra.Structuresopen import Data.Product.Base using (_,_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- Re-export all properties of monoid monomorphismsopen import Algebra.Morphism.MonoidMonomorphismisMonoidMonomorphism public-------------------------------------------------------------------------- Propertiesmodule _ (◦-isMagma : IsMagma _≈₂_ _◦_) whereopen IsMagma ◦-isMagma renaming (∙-cong to ◦-cong)open ≈-Reasoning setoidinverseˡ : LeftInverse _≈₂_ ε₂ _⁻¹₂ _◦_ → LeftInverse _≈₁_ ε₁ _⁻¹₁ _∙_inverseˡ invˡ x = injective (begin⟦ x ⁻¹₁ ∙ x ⟧ ≈⟨ ∙-homo (x ⁻¹₁ ) x ⟩⟦ x ⁻¹₁ ⟧ ◦ ⟦ x ⟧ ≈⟨ ◦-cong (⁻¹-homo x) refl ⟩⟦ x ⟧ ⁻¹₂ ◦ ⟦ x ⟧ ≈⟨ invˡ ⟦ x ⟧ ⟩ε₂ ≈⟨ ε-homo ⟨⟦ ε₁ ⟧ ∎)inverseʳ : RightInverse _≈₂_ ε₂ _⁻¹₂ _◦_ → RightInverse _≈₁_ ε₁ _⁻¹₁ _∙_inverseʳ invʳ x = injective (begin⟦ x ∙ x ⁻¹₁ ⟧ ≈⟨ ∙-homo x (x ⁻¹₁) ⟩⟦ x ⟧ ◦ ⟦ x ⁻¹₁ ⟧ ≈⟨ ◦-cong refl (⁻¹-homo x) ⟩⟦ x ⟧ ◦ ⟦ x ⟧ ⁻¹₂ ≈⟨ invʳ ⟦ x ⟧ ⟩ε₂ ≈⟨ ε-homo ⟨⟦ ε₁ ⟧ ∎)inverse : Inverse _≈₂_ ε₂ _⁻¹₂ _◦_ → Inverse _≈₁_ ε₁ _⁻¹₁ _∙_inverse (invˡ , invʳ) = inverseˡ invˡ , inverseʳ invʳ⁻¹-cong : Congruent₁ _≈₂_ _⁻¹₂ → Congruent₁ _≈₁_ _⁻¹₁⁻¹-cong ⁻¹-cong {x} {y} x≈y = injective (begin⟦ x ⁻¹₁ ⟧ ≈⟨ ⁻¹-homo x ⟩⟦ x ⟧ ⁻¹₂ ≈⟨ ⁻¹-cong (⟦⟧-cong x≈y) ⟩⟦ y ⟧ ⁻¹₂ ≈⟨ ⁻¹-homo y ⟨⟦ y ⁻¹₁ ⟧ ∎)module _ (◦-isAbelianGroup : IsAbelianGroup _≈₂_ _◦_ ε₂ _⁻¹₂) whereopen IsAbelianGroup ◦-isAbelianGroup renaming (∙-cong to ◦-cong; ⁻¹-cong to ⁻¹₂-cong)open ≈-Reasoning setoid⁻¹-distrib-∙ : (∀ x y → (x ◦ y) ⁻¹₂ ≈₂ (x ⁻¹₂) ◦ (y ⁻¹₂)) → (∀ x y → (x ∙ y) ⁻¹₁ ≈₁ (x ⁻¹₁) ∙ (y ⁻¹₁))⁻¹-distrib-∙ ⁻¹-distrib-∙ x y = injective (begin⟦ (x ∙ y) ⁻¹₁ ⟧ ≈⟨ ⁻¹-homo (x ∙ y) ⟩⟦ x ∙ y ⟧ ⁻¹₂ ≈⟨ ⁻¹₂-cong (∙-homo x y) ⟩(⟦ x ⟧ ◦ ⟦ y ⟧) ⁻¹₂ ≈⟨ ⁻¹-distrib-∙ ⟦ x ⟧ ⟦ y ⟧ ⟩⟦ x ⟧ ⁻¹₂ ◦ ⟦ y ⟧ ⁻¹₂ ≈⟨ sym (◦-cong (⁻¹-homo x) (⁻¹-homo y)) ⟩⟦ x ⁻¹₁ ⟧ ◦ ⟦ y ⁻¹₁ ⟧ ≈⟨ sym (∙-homo (x ⁻¹₁) (y ⁻¹₁)) ⟩⟦ (x ⁻¹₁) ∙ (y ⁻¹₁) ⟧ ∎)isGroup : IsGroup _≈₂_ _◦_ ε₂ _⁻¹₂ → IsGroup _≈₁_ _∙_ ε₁ _⁻¹₁isGroup isGroup = record{ isMonoid = isMonoid G.isMonoid; inverse = inverse G.isMagma G.inverse; ⁻¹-cong = ⁻¹-cong G.isMagma G.⁻¹-cong} where module G = IsGroup isGroupisAbelianGroup : IsAbelianGroup _≈₂_ _◦_ ε₂ _⁻¹₂ → IsAbelianGroup _≈₁_ _∙_ ε₁ _⁻¹₁isAbelianGroup isAbelianGroup = record{ isGroup = isGroup G.isGroup; comm = comm G.isMagma G.comm} where module G = IsAbelianGroup isAbelianGroup
-------------------------------------------------------------------------- The Agda standard library---- Basic definitions for morphisms between algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Algebra.Morphism.Definitions{a} (A : Set a) -- The domain of the morphism{b} (B : Set b) -- The codomain of the morphism{ℓ} (_≈_ : Rel B ℓ) -- The equality relation over the codomainwhereopen import Algebra.Coreusing (Op₁; Op₂)-------------------------------------------------------------------------- Basic definitionsHomomorphic₀ : (A → B) → A → B → Set _Homomorphic₀ ⟦_⟧ ∙ ∘ = ⟦ ∙ ⟧ ≈ ∘Homomorphic₁ : (A → B) → Op₁ A → Op₁ B → Set _Homomorphic₁ ⟦_⟧ ∙_ ∘_ = ∀ x → ⟦ ∙ x ⟧ ≈ (∘ ⟦ x ⟧)Homomorphic₂ : (A → B) → Op₂ A → Op₂ B → Set _Homomorphic₂ ⟦_⟧ _∙_ _∘_ = ∀ x y → ⟦ x ∙ y ⟧ ≈ (⟦ x ⟧ ∘ ⟦ y ⟧)-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 1.3Morphism : Set _Morphism = A → B{-# WARNING_ON_USAGE Morphism"Warning: Morphism was deprecated in v1.3.Please use the standard function notation (e.g. A → B) instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- The unique morphism to the terminal object,-- for each of the relevant categories. Since-- each terminal algebra builds on `Monoid`,-- possibly with additional (trivial) operations,-- satisfying additional properties, it suffices to-- define the morphism on the underlying `RawMonoid`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Morphism.Construct.Terminal {c ℓ : Level} whereopen import Algebra.Bundles.Rawusing (RawMagma; RawMonoid; RawGroup; RawNearSemiring; RawSemiring; RawRing)open import Algebra.Morphism.Structuresopen import Data.Product.Base using (_,_)open import Function.Definitions using (StrictlySurjective)import Relation.Binary.Morphism.Definitions as Relopen import Relation.Binary.Morphism.Structuresopen import Algebra.Construct.Terminal {c} {ℓ}privatevariablea ℓa : LevelA : Set a-------------------------------------------------------------------------- The unique morphismone : A → 𝕆ne.Carrierone _ = _-------------------------------------------------------------------------- Basic propertiesstrictlySurjective : A → StrictlySurjective 𝕆ne._≈_ onestrictlySurjective x _ = x , _-------------------------------------------------------------------------- HomomorphismsisMagmaHomomorphism : (M : RawMagma a ℓa) →IsMagmaHomomorphism M rawMagma oneisMagmaHomomorphism M = record{ isRelHomomorphism = record { cong = _ }; homo = _}isMonoidHomomorphism : (M : RawMonoid a ℓa) →IsMonoidHomomorphism M rawMonoid oneisMonoidHomomorphism M = record{ isMagmaHomomorphism = isMagmaHomomorphism (RawMonoid.rawMagma M); ε-homo = _}isGroupHomomorphism : (G : RawGroup a ℓa) →IsGroupHomomorphism G rawGroup oneisGroupHomomorphism G = record{ isMonoidHomomorphism = isMonoidHomomorphism (RawGroup.rawMonoid G); ⁻¹-homo = λ _ → _}isNearSemiringHomomorphism : (N : RawNearSemiring a ℓa) →IsNearSemiringHomomorphism N rawNearSemiring oneisNearSemiringHomomorphism N = record{ +-isMonoidHomomorphism = isMonoidHomomorphism (RawNearSemiring.+-rawMonoid N); *-homo = λ _ _ → _}isSemiringHomomorphism : (S : RawSemiring a ℓa) →IsSemiringHomomorphism S rawSemiring oneisSemiringHomomorphism S = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism (RawSemiring.rawNearSemiring S); 1#-homo = _}isRingHomomorphism : (R : RawRing a ℓa) → IsRingHomomorphism R rawRing oneisRingHomomorphism R = record{ isSemiringHomomorphism = isSemiringHomomorphism (RawRing.rawSemiring R); -‿homo = λ _ → _}
-------------------------------------------------------------------------- The Agda standard library---- The unique morphism from the initial object,-- for each of the relevant categories. Since-- `Semigroup` and `Band` are simply `Magma`s-- satisfying additional properties, it suffices to-- define the morphism on the underlying `RawMagma`.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Morphism.Construct.Initial {c ℓ : Level} whereopen import Algebra.Bundles.Raw using (RawMagma)open import Algebra.Morphism.Structuresopen import Function.Definitions using (Injective)import Relation.Binary.Morphism.Definitions as Relopen import Relation.Binary.Morphism.Structuresopen import Relation.Binary.Core using (Rel)open import Algebra.Construct.Initial {c} {ℓ}privatevariablea m ℓm : LevelA : Set a≈ : Rel A ℓm-------------------------------------------------------------------------- The unique morphismzero : ℤero.Carrier → Azero ()-------------------------------------------------------------------------- Basic propertiescong : (≈ : Rel A ℓm) → Rel.Homomorphic₂ ℤero.Carrier A ℤero._≈_ ≈ zerocong _ {x = ()}injective : (≈ : Rel A ℓm) → Injective ℤero._≈_ ≈ zeroinjective _ {x = ()}-------------------------------------------------------------------------- Morphism structuresisMagmaHomomorphism : (M : RawMagma m ℓm) →IsMagmaHomomorphism rawMagma M zeroisMagmaHomomorphism M = record{ isRelHomomorphism = record { cong = cong (RawMagma._≈_ M) }; homo = λ()}isMagmaMonomorphism : (M : RawMagma m ℓm) →IsMagmaMonomorphism rawMagma M zeroisMagmaMonomorphism M = record{ isMagmaHomomorphism = isMagmaHomomorphism M; injective = injective (RawMagma._≈_ M)}
-------------------------------------------------------------------------- The Agda standard library---- The identity morphism for algebraic structures------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Morphism.Construct.Identity whereopen import Algebra.Bundlesopen import Algebra.Morphism.Structuresusing ( module MagmaMorphisms; module MonoidMorphisms; module GroupMorphisms; module NearSemiringMorphisms; module SemiringMorphisms; module RingWithoutOneMorphisms; module RingMorphisms; module QuasigroupMorphisms; module LoopMorphisms; module KleeneAlgebraMorphisms)open import Data.Product.Base using (_,_)open import Function.Base using (id)import Function.Construct.Identity as Idopen import Level using (Level)open import Relation.Binary.Morphism.Construct.Identity using (isRelHomomorphism)open import Relation.Binary.Definitions using (Reflexive)privatevariablec ℓ : Level-------------------------------------------------------------------------- Magmasmodule _ (M : RawMagma c ℓ) (open RawMagma M) (refl : Reflexive _≈_) whereopen MagmaMorphisms M MisMagmaHomomorphism : IsMagmaHomomorphism idisMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism _; homo = λ _ _ → refl}isMagmaMonomorphism : IsMagmaMonomorphism idisMagmaMonomorphism = record{ isMagmaHomomorphism = isMagmaHomomorphism; injective = id}isMagmaIsomorphism : IsMagmaIsomorphism idisMagmaIsomorphism = record{ isMagmaMonomorphism = isMagmaMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Monoidsmodule _ (M : RawMonoid c ℓ) (open RawMonoid M) (refl : Reflexive _≈_) whereopen MonoidMorphisms M MisMonoidHomomorphism : IsMonoidHomomorphism idisMonoidHomomorphism = record{ isMagmaHomomorphism = isMagmaHomomorphism _ refl; ε-homo = refl}isMonoidMonomorphism : IsMonoidMonomorphism idisMonoidMonomorphism = record{ isMonoidHomomorphism = isMonoidHomomorphism; injective = id}isMonoidIsomorphism : IsMonoidIsomorphism idisMonoidIsomorphism = record{ isMonoidMonomorphism = isMonoidMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Groupsmodule _ (G : RawGroup c ℓ) (open RawGroup G) (refl : Reflexive _≈_) whereopen GroupMorphisms G GisGroupHomomorphism : IsGroupHomomorphism idisGroupHomomorphism = record{ isMonoidHomomorphism = isMonoidHomomorphism _ refl; ⁻¹-homo = λ _ → refl}isGroupMonomorphism : IsGroupMonomorphism idisGroupMonomorphism = record{ isGroupHomomorphism = isGroupHomomorphism; injective = id}isGroupIsomorphism : IsGroupIsomorphism idisGroupIsomorphism = record{ isGroupMonomorphism = isGroupMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Near semiringsmodule _ (R : RawNearSemiring c ℓ) (open RawNearSemiring R) (refl : Reflexive _≈_) whereopen NearSemiringMorphisms R RisNearSemiringHomomorphism : IsNearSemiringHomomorphism idisNearSemiringHomomorphism = record{ +-isMonoidHomomorphism = isMonoidHomomorphism _ refl; *-homo = λ _ _ → refl}isNearSemiringMonomorphism : IsNearSemiringMonomorphism idisNearSemiringMonomorphism = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism; injective = id}isNearSemiringIsomorphism : IsNearSemiringIsomorphism idisNearSemiringIsomorphism = record{ isNearSemiringMonomorphism = isNearSemiringMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Semiringsmodule _ (R : RawSemiring c ℓ) (open RawSemiring R) (refl : Reflexive _≈_) whereopen SemiringMorphisms R RisSemiringHomomorphism : IsSemiringHomomorphism idisSemiringHomomorphism = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism _ refl; 1#-homo = refl}isSemiringMonomorphism : IsSemiringMonomorphism idisSemiringMonomorphism = record{ isSemiringHomomorphism = isSemiringHomomorphism; injective = id}isSemiringIsomorphism : IsSemiringIsomorphism idisSemiringIsomorphism = record{ isSemiringMonomorphism = isSemiringMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- RingWithoutOnemodule _ (R : RawRingWithoutOne c ℓ) (open RawRingWithoutOne R) (refl : Reflexive _≈_) whereopen RingWithoutOneMorphisms R RisRingWithoutOneHomomorphism : IsRingWithoutOneHomomorphism idisRingWithoutOneHomomorphism = record{ +-isGroupHomomorphism = isGroupHomomorphism _ refl; *-homo = λ _ _ → refl}isRingWithoutOneMonomorphism : IsRingWithoutOneMonomorphism idisRingWithoutOneMonomorphism = record{ isRingWithoutOneHomomorphism = isRingWithoutOneHomomorphism; injective = id}isRingWithoutOneIsoMorphism : IsRingWithoutOneIsoMorphism idisRingWithoutOneIsoMorphism = record{ isRingWithoutOneMonomorphism = isRingWithoutOneMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Ringsmodule _ (R : RawRing c ℓ) (open RawRing R) (refl : Reflexive _≈_) whereopen RingMorphisms R RisRingHomomorphism : IsRingHomomorphism idisRingHomomorphism = record{ isSemiringHomomorphism = isSemiringHomomorphism _ refl; -‿homo = λ _ → refl}isRingMonomorphism : IsRingMonomorphism idisRingMonomorphism = record{ isRingHomomorphism = isRingHomomorphism; injective = id}isRingIsomorphism : IsRingIsomorphism idisRingIsomorphism = record{ isRingMonomorphism = isRingMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Quasigroupmodule _ (Q : RawQuasigroup c ℓ) (open RawQuasigroup Q) (refl : Reflexive _≈_) whereopen QuasigroupMorphisms Q QisQuasigroupHomomorphism : IsQuasigroupHomomorphism idisQuasigroupHomomorphism = record{ isRelHomomorphism = isRelHomomorphism _; ∙-homo = λ _ _ → refl; \\-homo = λ _ _ → refl; //-homo = λ _ _ → refl}isQuasigroupMonomorphism : IsQuasigroupMonomorphism idisQuasigroupMonomorphism = record{ isQuasigroupHomomorphism = isQuasigroupHomomorphism; injective = id}isQuasigroupIsomorphism : IsQuasigroupIsomorphism idisQuasigroupIsomorphism = record{ isQuasigroupMonomorphism = isQuasigroupMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- Loopmodule _ (L : RawLoop c ℓ) (open RawLoop L) (refl : Reflexive _≈_) whereopen LoopMorphisms L LisLoopHomomorphism : IsLoopHomomorphism idisLoopHomomorphism = record{ isQuasigroupHomomorphism = isQuasigroupHomomorphism _ refl; ε-homo = refl}isLoopMonomorphism : IsLoopMonomorphism idisLoopMonomorphism = record{ isLoopHomomorphism = isLoopHomomorphism; injective = id}isLoopIsomorphism : IsLoopIsomorphism idisLoopIsomorphism = record{ isLoopMonomorphism = isLoopMonomorphism; surjective = Id.surjective _}-------------------------------------------------------------------------- KleeneAlgebramodule _ (K : RawKleeneAlgebra c ℓ) (open RawKleeneAlgebra K) (refl : Reflexive _≈_) whereopen KleeneAlgebraMorphisms K KisKleeneAlgebraHomomorphism : IsKleeneAlgebraHomomorphism idisKleeneAlgebraHomomorphism = record{ isSemiringHomomorphism = isSemiringHomomorphism _ refl; ⋆-homo = λ _ → refl}isKleeneAlgebraMonomorphism : IsKleeneAlgebraMonomorphism idisKleeneAlgebraMonomorphism = record{ isKleeneAlgebraHomomorphism = isKleeneAlgebraHomomorphism; injective = id}isKleeneAlgebraIsomorphism : IsKleeneAlgebraIsomorphism idisKleeneAlgebraIsomorphism = record{ isKleeneAlgebraMonomorphism = isKleeneAlgebraMonomorphism; surjective = Id.surjective _}
-------------------------------------------------------------------------- The Agda standard library---- The composition of morphisms between algebraic structures.------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Morphism.Construct.Composition whereopen import Algebra.Bundlesopen import Algebra.Morphism.Structuresopen import Function.Base using (_∘_)import Function.Construct.Composition as Funcopen import Level using (Level)open import Relation.Binary.Morphism.Construct.Compositionopen import Relation.Binary.Definitions using (Transitive)privatevariablea b c ℓ₁ ℓ₂ ℓ₃ : Level-------------------------------------------------------------------------- Magmasmodule _ {M₁ : RawMagma a ℓ₁}{M₂ : RawMagma b ℓ₂}{M₃ : RawMagma c ℓ₃}(open RawMagma)(≈₃-trans : Transitive (_≈_ M₃)){f : Carrier M₁ → Carrier M₂}{g : Carrier M₂ → Carrier M₃}whereisMagmaHomomorphism: IsMagmaHomomorphism M₁ M₂ f→ IsMagmaHomomorphism M₂ M₃ g→ IsMagmaHomomorphism M₁ M₃ (g ∘ f)isMagmaHomomorphism f-homo g-homo = record{ isRelHomomorphism = isRelHomomorphism F.isRelHomomorphism G.isRelHomomorphism; homo = λ x y → ≈₃-trans (G.⟦⟧-cong (F.homo x y)) (G.homo (f x) (f y))} where module F = IsMagmaHomomorphism f-homo; module G = IsMagmaHomomorphism g-homoisMagmaMonomorphism: IsMagmaMonomorphism M₁ M₂ f→ IsMagmaMonomorphism M₂ M₃ g→ IsMagmaMonomorphism M₁ M₃ (g ∘ f)isMagmaMonomorphism f-mono g-mono = record{ isMagmaHomomorphism = isMagmaHomomorphism F.isMagmaHomomorphism G.isMagmaHomomorphism; injective = F.injective ∘ G.injective} where module F = IsMagmaMonomorphism f-mono; module G = IsMagmaMonomorphism g-monoisMagmaIsomorphism: IsMagmaIsomorphism M₁ M₂ f→ IsMagmaIsomorphism M₂ M₃ g→ IsMagmaIsomorphism M₁ M₃ (g ∘ f)isMagmaIsomorphism f-iso g-iso = record{ isMagmaMonomorphism = isMagmaMonomorphism F.isMagmaMonomorphism G.isMagmaMonomorphism; surjective = Func.surjective _ _ (_≈_ M₃) F.surjective G.surjective} where module F = IsMagmaIsomorphism f-iso; module G = IsMagmaIsomorphism g-iso-------------------------------------------------------------------------- Monoidsmodule _ {M₁ : RawMonoid a ℓ₁}{M₂ : RawMonoid b ℓ₂}{M₃ : RawMonoid c ℓ₃}(open RawMonoid)(≈₃-trans : Transitive (_≈_ M₃)){f : Carrier M₁ → Carrier M₂}{g : Carrier M₂ → Carrier M₃}whereisMonoidHomomorphism: IsMonoidHomomorphism M₁ M₂ f→ IsMonoidHomomorphism M₂ M₃ g→ IsMonoidHomomorphism M₁ M₃ (g ∘ f)isMonoidHomomorphism f-homo g-homo = record{ isMagmaHomomorphism = isMagmaHomomorphism ≈₃-trans F.isMagmaHomomorphism G.isMagmaHomomorphism; ε-homo = ≈₃-trans (G.⟦⟧-cong F.ε-homo) G.ε-homo} where module F = IsMonoidHomomorphism f-homo; module G = IsMonoidHomomorphism g-homoisMonoidMonomorphism: IsMonoidMonomorphism M₁ M₂ f→ IsMonoidMonomorphism M₂ M₃ g→ IsMonoidMonomorphism M₁ M₃ (g ∘ f)isMonoidMonomorphism f-mono g-mono = record{ isMonoidHomomorphism = isMonoidHomomorphism F.isMonoidHomomorphism G.isMonoidHomomorphism; injective = F.injective ∘ G.injective} where module F = IsMonoidMonomorphism f-mono; module G = IsMonoidMonomorphism g-monoisMonoidIsomorphism: IsMonoidIsomorphism M₁ M₂ f→ IsMonoidIsomorphism M₂ M₃ g→ IsMonoidIsomorphism M₁ M₃ (g ∘ f)isMonoidIsomorphism f-iso g-iso = record{ isMonoidMonomorphism = isMonoidMonomorphism F.isMonoidMonomorphism G.isMonoidMonomorphism; surjective = Func.surjective _ _(_≈_ M₃) F.surjective G.surjective} where module F = IsMonoidIsomorphism f-iso; module G = IsMonoidIsomorphism g-iso-------------------------------------------------------------------------- Groupsmodule _ {G₁ : RawGroup a ℓ₁}{G₂ : RawGroup b ℓ₂}{G₃ : RawGroup c ℓ₃}(open RawGroup)(≈₃-trans : Transitive (_≈_ G₃)){f : Carrier G₁ → Carrier G₂}{g : Carrier G₂ → Carrier G₃}whereisGroupHomomorphism: IsGroupHomomorphism G₁ G₂ f→ IsGroupHomomorphism G₂ G₃ g→ IsGroupHomomorphism G₁ G₃ (g ∘ f)isGroupHomomorphism f-homo g-homo = record{ isMonoidHomomorphism = isMonoidHomomorphism ≈₃-trans F.isMonoidHomomorphism G.isMonoidHomomorphism; ⁻¹-homo = λ x → ≈₃-trans (G.⟦⟧-cong (F.⁻¹-homo x)) (G.⁻¹-homo (f x))} where module F = IsGroupHomomorphism f-homo; module G = IsGroupHomomorphism g-homoisGroupMonomorphism: IsGroupMonomorphism G₁ G₂ f→ IsGroupMonomorphism G₂ G₃ g→ IsGroupMonomorphism G₁ G₃ (g ∘ f)isGroupMonomorphism f-mono g-mono = record{ isGroupHomomorphism = isGroupHomomorphism F.isGroupHomomorphism G.isGroupHomomorphism; injective = F.injective ∘ G.injective} where module F = IsGroupMonomorphism f-mono; module G = IsGroupMonomorphism g-monoisGroupIsomorphism: IsGroupIsomorphism G₁ G₂ f→ IsGroupIsomorphism G₂ G₃ g→ IsGroupIsomorphism G₁ G₃ (g ∘ f)isGroupIsomorphism f-iso g-iso = record{ isGroupMonomorphism = isGroupMonomorphism F.isGroupMonomorphism G.isGroupMonomorphism; surjective = Func.surjective _ _ (_≈_ G₃) F.surjective G.surjective} where module F = IsGroupIsomorphism f-iso; module G = IsGroupIsomorphism g-iso-------------------------------------------------------------------------- Near semiringsmodule _ {R₁ : RawNearSemiring a ℓ₁}{R₂ : RawNearSemiring b ℓ₂}{R₃ : RawNearSemiring c ℓ₃}(open RawNearSemiring)(≈₃-trans : Transitive (_≈_ R₃)){f : Carrier R₁ → Carrier R₂}{g : Carrier R₂ → Carrier R₃}whereisNearSemiringHomomorphism: IsNearSemiringHomomorphism R₁ R₂ f→ IsNearSemiringHomomorphism R₂ R₃ g→ IsNearSemiringHomomorphism R₁ R₃ (g ∘ f)isNearSemiringHomomorphism f-homo g-homo = record{ +-isMonoidHomomorphism = isMonoidHomomorphism ≈₃-trans F.+-isMonoidHomomorphism G.+-isMonoidHomomorphism; *-homo = λ x y → ≈₃-trans (G.⟦⟧-cong (F.*-homo x y)) (G.*-homo (f x) (f y))} where module F = IsNearSemiringHomomorphism f-homo; module G = IsNearSemiringHomomorphism g-homoisNearSemiringMonomorphism: IsNearSemiringMonomorphism R₁ R₂ f→ IsNearSemiringMonomorphism R₂ R₃ g→ IsNearSemiringMonomorphism R₁ R₃ (g ∘ f)isNearSemiringMonomorphism f-mono g-mono = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism F.isNearSemiringHomomorphism G.isNearSemiringHomomorphism; injective = F.injective ∘ G.injective} where module F = IsNearSemiringMonomorphism f-mono; module G = IsNearSemiringMonomorphism g-monoisNearSemiringIsomorphism: IsNearSemiringIsomorphism R₁ R₂ f→ IsNearSemiringIsomorphism R₂ R₃ g→ IsNearSemiringIsomorphism R₁ R₃ (g ∘ f)isNearSemiringIsomorphism f-iso g-iso = record{ isNearSemiringMonomorphism = isNearSemiringMonomorphism F.isNearSemiringMonomorphism G.isNearSemiringMonomorphism; surjective = Func.surjective _ _ (_≈_ R₃) F.surjective G.surjective} where module F = IsNearSemiringIsomorphism f-iso; module G = IsNearSemiringIsomorphism g-iso-------------------------------------------------------------------------- Semiringsmodule _{R₁ : RawSemiring a ℓ₁}{R₂ : RawSemiring b ℓ₂}{R₃ : RawSemiring c ℓ₃}(open RawSemiring)(≈₃-trans : Transitive (_≈_ R₃)){f : Carrier R₁ → Carrier R₂}{g : Carrier R₂ → Carrier R₃}whereisSemiringHomomorphism: IsSemiringHomomorphism R₁ R₂ f→ IsSemiringHomomorphism R₂ R₃ g→ IsSemiringHomomorphism R₁ R₃ (g ∘ f)isSemiringHomomorphism f-homo g-homo = record{ isNearSemiringHomomorphism = isNearSemiringHomomorphism ≈₃-trans F.isNearSemiringHomomorphism G.isNearSemiringHomomorphism; 1#-homo = ≈₃-trans (G.⟦⟧-cong F.1#-homo) G.1#-homo} where module F = IsSemiringHomomorphism f-homo; module G = IsSemiringHomomorphism g-homoisSemiringMonomorphism: IsSemiringMonomorphism R₁ R₂ f→ IsSemiringMonomorphism R₂ R₃ g→ IsSemiringMonomorphism R₁ R₃ (g ∘ f)isSemiringMonomorphism f-mono g-mono = record{ isSemiringHomomorphism = isSemiringHomomorphism F.isSemiringHomomorphism G.isSemiringHomomorphism; injective = F.injective ∘ G.injective} where module F = IsSemiringMonomorphism f-mono; module G = IsSemiringMonomorphism g-monoisSemiringIsomorphism: IsSemiringIsomorphism R₁ R₂ f→ IsSemiringIsomorphism R₂ R₃ g→ IsSemiringIsomorphism R₁ R₃ (g ∘ f)isSemiringIsomorphism f-iso g-iso = record{ isSemiringMonomorphism = isSemiringMonomorphism F.isSemiringMonomorphism G.isSemiringMonomorphism; surjective = Func.surjective _ _ (_≈_ R₃) F.surjective G.surjective} where module F = IsSemiringIsomorphism f-iso; module G = IsSemiringIsomorphism g-iso-------------------------------------------------------------------------- RingWithoutOnemodule _ {R₁ : RawRingWithoutOne a ℓ₁}{R₂ : RawRingWithoutOne b ℓ₂}{R₃ : RawRingWithoutOne c ℓ₃}(open RawRingWithoutOne)(≈₃-trans : Transitive (_≈_ R₃)){f : Carrier R₁ → Carrier R₂}{g : Carrier R₂ → Carrier R₃}whereisRingWithoutOneHomomorphism: IsRingWithoutOneHomomorphism R₁ R₂ f→ IsRingWithoutOneHomomorphism R₂ R₃ g→ IsRingWithoutOneHomomorphism R₁ R₃ (g ∘ f)isRingWithoutOneHomomorphism f-homo g-homo = record{ +-isGroupHomomorphism = isGroupHomomorphism ≈₃-trans F.+-isGroupHomomorphism G.+-isGroupHomomorphism; *-homo = λ x y → ≈₃-trans (G.⟦⟧-cong (F.*-homo x y)) (G.*-homo (f x) (f y))} where module F = IsRingWithoutOneHomomorphism f-homo; module G = IsRingWithoutOneHomomorphism g-homoisRingWithoutOneMonomorphism: IsRingWithoutOneMonomorphism R₁ R₂ f→ IsRingWithoutOneMonomorphism R₂ R₃ g→ IsRingWithoutOneMonomorphism R₁ R₃ (g ∘ f)isRingWithoutOneMonomorphism f-mono g-mono = record{ isRingWithoutOneHomomorphism = isRingWithoutOneHomomorphism F.isRingWithoutOneHomomorphism G.isRingWithoutOneHomomorphism; injective = F.injective ∘ G.injective} where module F = IsRingWithoutOneMonomorphism f-mono; module G = IsRingWithoutOneMonomorphism g-monoisRingWithoutOneIsoMorphism: IsRingWithoutOneIsoMorphism R₁ R₂ f→ IsRingWithoutOneIsoMorphism R₂ R₃ g→ IsRingWithoutOneIsoMorphism R₁ R₃ (g ∘ f)isRingWithoutOneIsoMorphism f-iso g-iso = record{ isRingWithoutOneMonomorphism = isRingWithoutOneMonomorphism F.isRingWithoutOneMonomorphism G.isRingWithoutOneMonomorphism; surjective = Func.surjective _ _ (_≈_ R₃) F.surjective G.surjective} where module F = IsRingWithoutOneIsoMorphism f-iso; module G = IsRingWithoutOneIsoMorphism g-iso-------------------------------------------------------------------------- Ringsmodule _ {R₁ : RawRing a ℓ₁}{R₂ : RawRing b ℓ₂}{R₃ : RawRing c ℓ₃}(open RawRing)(≈₃-trans : Transitive (_≈_ R₃)){f : Carrier R₁ → Carrier R₂}{g : Carrier R₂ → Carrier R₃}whereisRingHomomorphism: IsRingHomomorphism R₁ R₂ f→ IsRingHomomorphism R₂ R₃ g→ IsRingHomomorphism R₁ R₃ (g ∘ f)isRingHomomorphism f-homo g-homo = record{ isSemiringHomomorphism = isSemiringHomomorphism ≈₃-trans F.isSemiringHomomorphism G.isSemiringHomomorphism; -‿homo = λ x → ≈₃-trans (G.⟦⟧-cong (F.-‿homo x)) (G.-‿homo (f x))} where module F = IsRingHomomorphism f-homo; module G = IsRingHomomorphism g-homoisRingMonomorphism: IsRingMonomorphism R₁ R₂ f→ IsRingMonomorphism R₂ R₃ g→ IsRingMonomorphism R₁ R₃ (g ∘ f)isRingMonomorphism f-mono g-mono = record{ isRingHomomorphism = isRingHomomorphism F.isRingHomomorphism G.isRingHomomorphism; injective = F.injective ∘ G.injective} where module F = IsRingMonomorphism f-mono; module G = IsRingMonomorphism g-monoisRingIsomorphism: IsRingIsomorphism R₁ R₂ f→ IsRingIsomorphism R₂ R₃ g→ IsRingIsomorphism R₁ R₃ (g ∘ f)isRingIsomorphism f-iso g-iso = record{ isRingMonomorphism = isRingMonomorphism F.isRingMonomorphism G.isRingMonomorphism; surjective = Func.surjective _ _ (_≈_ R₃) F.surjective G.surjective} where module F = IsRingIsomorphism f-iso; module G = IsRingIsomorphism g-iso-------------------------------------------------------------------------- Quasigroupmodule _ {Q₁ : RawQuasigroup a ℓ₁}{Q₂ : RawQuasigroup b ℓ₂}{Q₃ : RawQuasigroup c ℓ₃}(open RawQuasigroup)(≈₃-trans : Transitive (_≈_ Q₃)){f : Carrier Q₁ → Carrier Q₂}{g : Carrier Q₂ → Carrier Q₃}whereisQuasigroupHomomorphism: IsQuasigroupHomomorphism Q₁ Q₂ f→ IsQuasigroupHomomorphism Q₂ Q₃ g→ IsQuasigroupHomomorphism Q₁ Q₃ (g ∘ f)isQuasigroupHomomorphism f-homo g-homo = record{ isRelHomomorphism = isRelHomomorphism F.isRelHomomorphism G.isRelHomomorphism; ∙-homo = λ x y → ≈₃-trans (G.⟦⟧-cong ( F.∙-homo x y )) ( G.∙-homo (f x) (f y) ); \\-homo = λ x y → ≈₃-trans (G.⟦⟧-cong ( F.\\-homo x y )) ( G.\\-homo (f x) (f y) ); //-homo = λ x y → ≈₃-trans (G.⟦⟧-cong ( F.//-homo x y )) ( G.//-homo (f x) (f y) )} where module F = IsQuasigroupHomomorphism f-homo; module G = IsQuasigroupHomomorphism g-homoisQuasigroupMonomorphism: IsQuasigroupMonomorphism Q₁ Q₂ f→ IsQuasigroupMonomorphism Q₂ Q₃ g→ IsQuasigroupMonomorphism Q₁ Q₃ (g ∘ f)isQuasigroupMonomorphism f-mono g-mono = record{ isQuasigroupHomomorphism = isQuasigroupHomomorphism F.isQuasigroupHomomorphism G.isQuasigroupHomomorphism; injective = F.injective ∘ G.injective} where module F = IsQuasigroupMonomorphism f-mono; module G = IsQuasigroupMonomorphism g-monoisQuasigroupIsomorphism: IsQuasigroupIsomorphism Q₁ Q₂ f→ IsQuasigroupIsomorphism Q₂ Q₃ g→ IsQuasigroupIsomorphism Q₁ Q₃ (g ∘ f)isQuasigroupIsomorphism f-iso g-iso = record{ isQuasigroupMonomorphism = isQuasigroupMonomorphism F.isQuasigroupMonomorphism G.isQuasigroupMonomorphism; surjective = Func.surjective _ _ (_≈_ Q₃) F.surjective G.surjective} where module F = IsQuasigroupIsomorphism f-iso; module G = IsQuasigroupIsomorphism g-iso-------------------------------------------------------------------------- Loopmodule _ {L₁ : RawLoop a ℓ₁}{L₂ : RawLoop b ℓ₂}{L₃ : RawLoop c ℓ₃}(open RawLoop)(≈₃-trans : Transitive (_≈_ L₃)){f : Carrier L₁ → Carrier L₂}{g : Carrier L₂ → Carrier L₃}whereisLoopHomomorphism: IsLoopHomomorphism L₁ L₂ f→ IsLoopHomomorphism L₂ L₃ g→ IsLoopHomomorphism L₁ L₃ (g ∘ f)isLoopHomomorphism f-homo g-homo = record{ isQuasigroupHomomorphism = isQuasigroupHomomorphism ≈₃-trans F.isQuasigroupHomomorphism G.isQuasigroupHomomorphism; ε-homo = ≈₃-trans (G.⟦⟧-cong F.ε-homo) G.ε-homo} where module F = IsLoopHomomorphism f-homo; module G = IsLoopHomomorphism g-homoisLoopMonomorphism: IsLoopMonomorphism L₁ L₂ f→ IsLoopMonomorphism L₂ L₃ g→ IsLoopMonomorphism L₁ L₃ (g ∘ f)isLoopMonomorphism f-mono g-mono = record{ isLoopHomomorphism = isLoopHomomorphism F.isLoopHomomorphism G.isLoopHomomorphism; injective = F.injective ∘ G.injective} where module F = IsLoopMonomorphism f-mono; module G = IsLoopMonomorphism g-monoisLoopIsomorphism: IsLoopIsomorphism L₁ L₂ f→ IsLoopIsomorphism L₂ L₃ g→ IsLoopIsomorphism L₁ L₃ (g ∘ f)isLoopIsomorphism f-iso g-iso = record{ isLoopMonomorphism = isLoopMonomorphism F.isLoopMonomorphism G.isLoopMonomorphism; surjective = Func.surjective _ _ (_≈_ L₃) F.surjective G.surjective} where module F = IsLoopIsomorphism f-iso; module G = IsLoopIsomorphism g-iso-------------------------------------------------------------------------- KleeneAlgebramodule _ {K₁ : RawKleeneAlgebra a ℓ₁}{K₂ : RawKleeneAlgebra b ℓ₂}{K₃ : RawKleeneAlgebra c ℓ₃}(open RawKleeneAlgebra)(≈₃-trans : Transitive (_≈_ K₃)){f : Carrier K₁ → Carrier K₂}{g : Carrier K₂ → Carrier K₃}whereisKleeneAlgebraHomomorphism: IsKleeneAlgebraHomomorphism K₁ K₂ f→ IsKleeneAlgebraHomomorphism K₂ K₃ g→ IsKleeneAlgebraHomomorphism K₁ K₃ (g ∘ f)isKleeneAlgebraHomomorphism f-homo g-homo = record{ isSemiringHomomorphism = isSemiringHomomorphism ≈₃-trans F.isSemiringHomomorphism G.isSemiringHomomorphism; ⋆-homo = λ x → ≈₃-trans (G.⟦⟧-cong (F.⋆-homo x)) (G.⋆-homo (f x))} where module F = IsKleeneAlgebraHomomorphism f-homo; module G = IsKleeneAlgebraHomomorphism g-homoisKleeneAlgebraMonomorphism: IsKleeneAlgebraMonomorphism K₁ K₂ f→ IsKleeneAlgebraMonomorphism K₂ K₃ g→ IsKleeneAlgebraMonomorphism K₁ K₃ (g ∘ f)isKleeneAlgebraMonomorphism f-mono g-mono = record{ isKleeneAlgebraHomomorphism = isKleeneAlgebraHomomorphism F.isKleeneAlgebraHomomorphism G.isKleeneAlgebraHomomorphism; injective = F.injective ∘ G.injective} where module F = IsKleeneAlgebraMonomorphism f-mono; module G = IsKleeneAlgebraMonomorphism g-monoisKleeneAlgebraIsomorphism: IsKleeneAlgebraIsomorphism K₁ K₂ f→ IsKleeneAlgebraIsomorphism K₂ K₃ g→ IsKleeneAlgebraIsomorphism K₁ K₃ (g ∘ f)isKleeneAlgebraIsomorphism f-iso g-iso = record{ isKleeneAlgebraMonomorphism = isKleeneAlgebraMonomorphism F.isKleeneAlgebraMonomorphism G.isKleeneAlgebraMonomorphism; surjective = Func.surjective (_≈_ K₁) (_≈_ K₂) (_≈_ K₃) F.surjective G.surjective} where module F = IsKleeneAlgebraIsomorphism f-iso; module G = IsKleeneAlgebraIsomorphism g-iso
-------------------------------------------------------------------------- The Agda standard library---- Some properties of Magma homomorphisms------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Morphism.Consequences whereopen import Algebra using (Magma)open import Algebra.Morphism.Definitionsopen import Data.Product.Base using (_,_)open import Function.Base using (id; _∘_)open import Function.Definitionsimport Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- If f and g are mutually inverse maps between A and B, g is congruent,-- f is a homomorphism, then g is a homomorphism.module _ {α α= β β=} (M₁ : Magma α α=) (M₂ : Magma β β=) whereprivateopen module M₁ = Magma M₁ using () renaming (_≈_ to _≈₁_; _∙_ to _∙₁_)open module M₂ = Magma M₂ using () renaming (_≈_ to _≈₂_; _∙_ to _∙₂_)homomorphic₂-inv : ∀ {f g} → Congruent _≈₂_ _≈₁_ g →Inverseᵇ _≈₁_ _≈₂_ f g →Homomorphic₂ _ _ _≈₂_ f _∙₁_ _∙₂_ →Homomorphic₂ _ _ _≈₁_ g _∙₂_ _∙₁_homomorphic₂-inv {f} {g} g-cong (invˡ , invʳ) homo x y = beging (x ∙₂ y) ≈⟨ g-cong (M₂.∙-cong (invˡ M₁.refl) (invˡ M₁.refl)) ⟨g (f (g x) ∙₂ f (g y)) ≈⟨ g-cong (homo (g x) (g y)) ⟨g (f (g x ∙₁ g y)) ≈⟨ invʳ M₂.refl ⟩g x ∙₁ g y ∎where open ≈-Reasoning M₁.setoidhomomorphic₂-inj : ∀ {f g} → Injective _≈₁_ _≈₂_ f →Inverseˡ _≈₁_ _≈₂_ f g →Homomorphic₂ _ _ _≈₂_ f _∙₁_ _∙₂_ →Homomorphic₂ _ _ _≈₁_ g _∙₂_ _∙₁_homomorphic₂-inj {f} {g} inj invˡ homo x y = inj (beginf (g (x ∙₂ y)) ≈⟨ invˡ M₁.refl ⟩x ∙₂ y ≈⟨ M₂.∙-cong (invˡ M₁.refl) (invˡ M₁.refl) ⟨f (g x) ∙₂ f (g y) ≈⟨ homo (g x) (g y) ⟨f (g x ∙₁ g y) ∎)where open ≈-Reasoning M₂.setoid
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structure module-- packed in records together with sets, operations, etc.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module whereopen import Algebra.Module.Core publicopen import Algebra.Module.Structures publicopen import Algebra.Module.Structures.Biased publicopen import Algebra.Module.Bundles publicopen import Algebra.Module.Definitions public
-------------------------------------------------------------------------- The Agda standard library---- Some algebraic structures defined over some other structure------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Module.Structures whereopen import Algebra.Bundlesopen import Algebra.Coreopen import Algebra.Module.Coreimport Algebra.Definitions as Defsopen import Algebra.Module.Definitionsopen import Algebra.Structuresopen import Data.Product.Base using (_,_; proj₁; proj₂)open import Level using (Level; _⊔_)privatevariablem ℓm r ℓr s ℓs : LevelM : Set mmodule _ (semiring : Semiring r ℓr) (≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M)whereopen Semiring semiring renaming (Carrier to R)record IsPreleftSemimodule (*ₗ : Opₗ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen LeftDefs R ≈ᴹfield*ₗ-cong : Congruent _≈_ *ₗ*ₗ-zeroˡ : LeftZero 0# 0ᴹ *ₗ*ₗ-distribʳ : *ₗ DistributesOverʳ _+_ ⟶ +ᴹ*ₗ-identityˡ : LeftIdentity 1# *ₗ*ₗ-assoc : Associative _*_ *ₗ*ₗ-zeroʳ : RightZero 0ᴹ *ₗ*ₗ-distribˡ : *ₗ DistributesOverˡ +ᴹrecord IsLeftSemimodule (*ₗ : Opₗ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen LeftDefs R ≈ᴹfield+ᴹ-isCommutativeMonoid : IsCommutativeMonoid ≈ᴹ +ᴹ 0ᴹisPreleftSemimodule : IsPreleftSemimodule *ₗopen IsPreleftSemimodule isPreleftSemimodule publicopen IsCommutativeMonoid +ᴹ-isCommutativeMonoid publicusing () renaming( assoc to +ᴹ-assoc; comm to +ᴹ-comm; identity to +ᴹ-identity; identityʳ to +ᴹ-identityʳ; identityˡ to +ᴹ-identityˡ; isEquivalence to ≈ᴹ-isEquivalence; isMagma to +ᴹ-isMagma; isMonoid to +ᴹ-isMonoid; isPartialEquivalence to ≈ᴹ-isPartialEquivalence; isSemigroup to +ᴹ-isSemigroup; refl to ≈ᴹ-refl; reflexive to ≈ᴹ-reflexive; setoid to ≈ᴹ-setoid; sym to ≈ᴹ-sym; trans to ≈ᴹ-trans; ∙-cong to +ᴹ-cong; ∙-congʳ to +ᴹ-congʳ; ∙-congˡ to +ᴹ-congˡ)*ₗ-congˡ : LeftCongruent *ₗ*ₗ-congˡ mm = *ₗ-cong refl mm*ₗ-congʳ : RightCongruent _≈_ *ₗ*ₗ-congʳ xx = *ₗ-cong xx ≈ᴹ-reflrecord IsPrerightSemimodule (*ᵣ : Opᵣ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen RightDefs R ≈ᴹfield*ᵣ-cong : Congruent _≈_ *ᵣ*ᵣ-zeroʳ : RightZero 0# 0ᴹ *ᵣ*ᵣ-distribˡ : *ᵣ DistributesOverˡ _+_ ⟶ +ᴹ*ᵣ-identityʳ : RightIdentity 1# *ᵣ*ᵣ-assoc : Associative _*_ *ᵣ*ᵣ-zeroˡ : LeftZero 0ᴹ *ᵣ*ᵣ-distribʳ : *ᵣ DistributesOverʳ +ᴹrecord IsRightSemimodule (*ᵣ : Opᵣ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen RightDefs R ≈ᴹfield+ᴹ-isCommutativeMonoid : IsCommutativeMonoid ≈ᴹ +ᴹ 0ᴹisPrerightSemimodule : IsPrerightSemimodule *ᵣopen IsPrerightSemimodule isPrerightSemimodule publicopen IsCommutativeMonoid +ᴹ-isCommutativeMonoid publicusing () renaming( assoc to +ᴹ-assoc; comm to +ᴹ-comm; identity to +ᴹ-identity; identityʳ to +ᴹ-identityʳ; identityˡ to +ᴹ-identityˡ; isEquivalence to ≈ᴹ-isEquivalence; isMagma to +ᴹ-isMagma; isMonoid to +ᴹ-isMonoid; isPartialEquivalence to ≈ᴹ-isPartialEquivalence; isSemigroup to +ᴹ-isSemigroup; refl to ≈ᴹ-refl; reflexive to ≈ᴹ-reflexive; setoid to ≈ᴹ-setoid; sym to ≈ᴹ-sym; trans to ≈ᴹ-trans; ∙-cong to +ᴹ-cong; ∙-congʳ to +ᴹ-congʳ; ∙-congˡ to +ᴹ-congˡ)*ᵣ-congˡ : LeftCongruent _≈_ *ᵣ*ᵣ-congˡ xx = *ᵣ-cong ≈ᴹ-refl xx*ᵣ-congʳ : RightCongruent *ᵣ*ᵣ-congʳ mm = *ᵣ-cong mm reflmodule _ (R-semiring : Semiring r ℓr) (S-semiring : Semiring s ℓs)(≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M)whereopen Semiring R-semiring using () renaming (Carrier to R)open Semiring S-semiring using () renaming (Carrier to S)record IsBisemimodule (*ₗ : Opₗ R M) (*ᵣ : Opᵣ S M): Set (r ⊔ s ⊔ m ⊔ ℓr ⊔ ℓs ⊔ ℓm) whereopen BiDefs R S ≈ᴹfield+ᴹ-isCommutativeMonoid : IsCommutativeMonoid ≈ᴹ +ᴹ 0ᴹisPreleftSemimodule : IsPreleftSemimodule R-semiring ≈ᴹ +ᴹ 0ᴹ *ₗisPrerightSemimodule : IsPrerightSemimodule S-semiring ≈ᴹ +ᴹ 0ᴹ *ᵣ*ₗ-*ᵣ-assoc : Associative *ₗ *ᵣisLeftSemimodule : IsLeftSemimodule R-semiring ≈ᴹ +ᴹ 0ᴹ *ₗisLeftSemimodule = record{ +ᴹ-isCommutativeMonoid = +ᴹ-isCommutativeMonoid; isPreleftSemimodule = isPreleftSemimodule}isRightSemimodule : IsRightSemimodule S-semiring ≈ᴹ +ᴹ 0ᴹ *ᵣisRightSemimodule = record{ +ᴹ-isCommutativeMonoid = +ᴹ-isCommutativeMonoid; isPrerightSemimodule = isPrerightSemimodule}open IsLeftSemimodule isLeftSemimodule publichiding (+ᴹ-isCommutativeMonoid; isPreleftSemimodule)open IsPrerightSemimodule isPrerightSemimodule publicopen IsRightSemimodule isRightSemimodule publicusing (*ᵣ-congˡ; *ᵣ-congʳ)module _ (commutativeSemiring : CommutativeSemiring r ℓr)(≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M)whereopen CommutativeSemiring commutativeSemiring renaming (Carrier to R)-- An R-semimodule is an R-R-bisemimodule where R is commutative.-- We enforce that *ₗ and *ᵣ coincide up to mathematical equality, though it-- may be that they do not coincide up to definitional equality.open SimultaneousBiDefs R ≈ᴹrecord IsSemimodule (*ₗ : Opₗ R M) (*ᵣ : Opᵣ R M): Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisBisemimodule : IsBisemimodule semiring semiring ≈ᴹ +ᴹ 0ᴹ *ₗ *ᵣ*ₗ-*ᵣ-coincident : Coincident *ₗ *ᵣopen IsBisemimodule isBisemimodule publicmodule _ (ring : Ring r ℓr)(≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M) (-ᴹ : Op₁ M)whereopen Ring ring renaming (Carrier to R)record IsLeftModule (*ₗ : Opₗ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen Defs ≈ᴹfieldisLeftSemimodule : IsLeftSemimodule semiring ≈ᴹ +ᴹ 0ᴹ *ₗ-ᴹ‿cong : Congruent₁ -ᴹ-ᴹ‿inverse : Inverse 0ᴹ -ᴹ +ᴹopen IsLeftSemimodule isLeftSemimodule public+ᴹ-isAbelianGroup : IsAbelianGroup ≈ᴹ +ᴹ 0ᴹ -ᴹ+ᴹ-isAbelianGroup = record{ isGroup = record{ isMonoid = +ᴹ-isMonoid; inverse = -ᴹ‿inverse; ⁻¹-cong = -ᴹ‿cong}; comm = +ᴹ-comm}open IsAbelianGroup +ᴹ-isAbelianGroup publicusing () renaming( isGroup to +ᴹ-isGroup; inverseˡ to -ᴹ‿inverseˡ; inverseʳ to -ᴹ‿inverseʳ; uniqueˡ-⁻¹ to uniqueˡ‿-ᴹ; uniqueʳ-⁻¹ to uniqueʳ‿-ᴹ)record IsRightModule (*ᵣ : Opᵣ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) whereopen Defs ≈ᴹfieldisRightSemimodule : IsRightSemimodule semiring ≈ᴹ +ᴹ 0ᴹ *ᵣ-ᴹ‿cong : Congruent₁ -ᴹ-ᴹ‿inverse : Inverse 0ᴹ -ᴹ +ᴹopen IsRightSemimodule isRightSemimodule public+ᴹ-isAbelianGroup : IsAbelianGroup ≈ᴹ +ᴹ 0ᴹ -ᴹ+ᴹ-isAbelianGroup = record{ isGroup = record{ isMonoid = +ᴹ-isMonoid; inverse = -ᴹ‿inverse; ⁻¹-cong = -ᴹ‿cong}; comm = +ᴹ-comm}open IsAbelianGroup +ᴹ-isAbelianGroup publicusing () renaming( isGroup to +ᴹ-isGroup; inverseˡ to -ᴹ‿inverseˡ; inverseʳ to -ᴹ‿inverseʳ; uniqueˡ-⁻¹ to uniqueˡ‿-ᴹ; uniqueʳ-⁻¹ to uniqueʳ‿-ᴹ)module _ (R-ring : Ring r ℓr) (S-ring : Ring s ℓs)(≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M) (-ᴹ : Op₁ M)whereopen Ring R-ring renaming (Carrier to R; semiring to R-semiring)open Ring S-ring renaming (Carrier to S; semiring to S-semiring)record IsBimodule (*ₗ : Opₗ R M) (*ᵣ : Opᵣ S M): Set (r ⊔ s ⊔ m ⊔ ℓr ⊔ ℓs ⊔ ℓm) whereopen Defs ≈ᴹfieldisBisemimodule : IsBisemimodule R-semiring S-semiring ≈ᴹ +ᴹ 0ᴹ *ₗ *ᵣ-ᴹ‿cong : Congruent₁ -ᴹ-ᴹ‿inverse : Inverse 0ᴹ -ᴹ +ᴹopen IsBisemimodule isBisemimodule publicisLeftModule : IsLeftModule R-ring ≈ᴹ +ᴹ 0ᴹ -ᴹ *ₗisLeftModule = record{ isLeftSemimodule = isLeftSemimodule; -ᴹ‿cong = -ᴹ‿cong; -ᴹ‿inverse = -ᴹ‿inverse}open IsLeftModule isLeftModule publicusing ( +ᴹ-isAbelianGroup; +ᴹ-isGroup; -ᴹ‿inverseˡ; -ᴹ‿inverseʳ; uniqueˡ‿-ᴹ; uniqueʳ‿-ᴹ)isRightModule : IsRightModule S-ring ≈ᴹ +ᴹ 0ᴹ -ᴹ *ᵣisRightModule = record{ isRightSemimodule = isRightSemimodule; -ᴹ‿cong = -ᴹ‿cong; -ᴹ‿inverse = -ᴹ‿inverse}module _ (commutativeRing : CommutativeRing r ℓr)(≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M) (-ᴹ : Op₁ M)whereopen CommutativeRing commutativeRing renaming (Carrier to R)-- An R-module is an R-R-bimodule where R is commutative.-- We enforce that *ₗ and *ᵣ coincide up to mathematical equality, though it-- may be that they do not coincide up to definitional equality.open SimultaneousBiDefs R ≈ᴹrecord IsModule (*ₗ : Opₗ R M) (*ᵣ : Opᵣ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisBimodule : IsBimodule ring ring ≈ᴹ +ᴹ 0ᴹ -ᴹ *ₗ *ᵣ*ₗ-*ᵣ-coincident : Coincident *ₗ *ᵣopen IsBimodule isBimodule publicisSemimodule : IsSemimodule commutativeSemiring ≈ᴹ +ᴹ 0ᴹ *ₗ *ᵣisSemimodule = record { isBisemimodule = isBisemimodule; *ₗ-*ᵣ-coincident = *ₗ-*ᵣ-coincident }
-------------------------------------------------------------------------- The Agda standard library---- This module provides alternative ways of providing instances of-- structures in the Algebra.Module hierarchy.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Module.Structures.Biased whereopen import Algebra.Bundlesopen import Algebra.Coreopen import Algebra.Module.Coreopen import Algebra.Module.Consequencesopen import Algebra.Module.Structuresopen import Function.Base using (flip)open import Level using (Level; _⊔_)privatevariablem ℓm r ℓr s ℓs : LevelM : Set mmodule _ (commutativeSemiring : CommutativeSemiring r ℓr) whereopen CommutativeSemiring commutativeSemiring renaming (Carrier to R)-- A left semimodule over a commutative semiring is already a semimodule.record IsSemimoduleFromLeft (≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M)(*ₗ : Opₗ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisLeftSemimodule : IsLeftSemimodule semiring ≈ᴹ +ᴹ 0ᴹ *ₗopen IsLeftSemimodule isLeftSemimoduleisBisemimodule : IsBisemimodule semiring semiring ≈ᴹ +ᴹ 0ᴹ *ₗ (flip *ₗ)isBisemimodule = record{ +ᴹ-isCommutativeMonoid = +ᴹ-isCommutativeMonoid; isPreleftSemimodule = isPreleftSemimodule; isPrerightSemimodule = record{ *ᵣ-cong = flip *ₗ-cong; *ᵣ-zeroʳ = *ₗ-zeroˡ; *ᵣ-distribˡ = *ₗ-distribʳ; *ᵣ-identityʳ = *ₗ-identityˡ; *ᵣ-assoc =*ₗ-assoc+comm⇒*ᵣ-assoc _≈_ ≈ᴹ-setoid *ₗ-congʳ *ₗ-assoc *-comm; *ᵣ-zeroˡ = *ₗ-zeroʳ; *ᵣ-distribʳ = *ₗ-distribˡ}; *ₗ-*ᵣ-assoc =*ₗ-assoc+comm⇒*ₗ-*ᵣ-assoc _≈_ ≈ᴹ-setoid *ₗ-congʳ *ₗ-assoc *-comm}isSemimodule : IsSemimodule commutativeSemiring ≈ᴹ +ᴹ 0ᴹ *ₗ (flip *ₗ)isSemimodule = record{ isBisemimodule = isBisemimodule; *ₗ-*ᵣ-coincident = λ _ _ → ≈ᴹ-refl}-- Similarly, a right semimodule over a commutative semiring-- is already a semimodule.record IsSemimoduleFromRight (≈ᴹ : Rel {m} M ℓm) (+ᴹ : Op₂ M) (0ᴹ : M)(*ᵣ : Opᵣ R M) : Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisRightSemimodule : IsRightSemimodule semiring ≈ᴹ +ᴹ 0ᴹ *ᵣopen IsRightSemimodule isRightSemimoduleisBisemimodule : IsBisemimodule semiring semiring ≈ᴹ +ᴹ 0ᴹ (flip *ᵣ) *ᵣisBisemimodule = record{ +ᴹ-isCommutativeMonoid = +ᴹ-isCommutativeMonoid; isPreleftSemimodule = record{ *ₗ-cong = flip *ᵣ-cong; *ₗ-zeroˡ = *ᵣ-zeroʳ; *ₗ-distribʳ = *ᵣ-distribˡ; *ₗ-identityˡ = *ᵣ-identityʳ; *ₗ-assoc =*ᵣ-assoc+comm⇒*ₗ-assoc _≈_ ≈ᴹ-setoid *ᵣ-congˡ *ᵣ-assoc *-comm; *ₗ-zeroʳ = *ᵣ-zeroˡ; *ₗ-distribˡ = *ᵣ-distribʳ}; isPrerightSemimodule = isPrerightSemimodule; *ₗ-*ᵣ-assoc =*ᵣ-assoc+comm⇒*ₗ-*ᵣ-assoc _≈_ ≈ᴹ-setoid *ᵣ-congˡ *ᵣ-assoc *-comm}isSemimodule : IsSemimodule commutativeSemiring ≈ᴹ +ᴹ 0ᴹ (flip *ᵣ) *ᵣisSemimodule = record{ isBisemimodule = isBisemimodule; *ₗ-*ᵣ-coincident = λ _ _ → ≈ᴹ-refl}module _ (commutativeRing : CommutativeRing r ℓr) whereopen CommutativeRing commutativeRing renaming (Carrier to R)-- A left module over a commutative ring is already a module.record IsModuleFromLeft (≈ᴹ : Rel {m} M ℓm)(+ᴹ : Op₂ M) (0ᴹ : M) (-ᴹ : Op₁ M) (*ₗ : Opₗ R M): Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisLeftModule : IsLeftModule ring ≈ᴹ +ᴹ 0ᴹ -ᴹ *ₗopen IsLeftModule isLeftModuleisModule : IsModule commutativeRing ≈ᴹ +ᴹ 0ᴹ -ᴹ *ₗ (flip *ₗ)isModule = record{ isBimodule = record{ isBisemimodule = IsSemimoduleFromLeft.isBisemimodule{commutativeSemiring = commutativeSemiring}(record { isLeftSemimodule = isLeftSemimodule }); -ᴹ‿cong = -ᴹ‿cong; -ᴹ‿inverse = -ᴹ‿inverse}; *ₗ-*ᵣ-coincident = λ _ _ → ≈ᴹ-refl}-- Similarly, a right module over a commutative ring is already a module.record IsModuleFromRight (≈ᴹ : Rel {m} M ℓm)(+ᴹ : Op₂ M) (0ᴹ : M) (-ᴹ : Op₁ M) (*ᵣ : Opᵣ R M): Set (r ⊔ m ⊔ ℓr ⊔ ℓm) wherefieldisRightModule : IsRightModule ring ≈ᴹ +ᴹ 0ᴹ -ᴹ *ᵣopen IsRightModule isRightModuleisModule : IsModule commutativeRing ≈ᴹ +ᴹ 0ᴹ -ᴹ (flip *ᵣ) *ᵣisModule = record{ isBimodule = record{ isBisemimodule = IsSemimoduleFromRight.isBisemimodule{commutativeSemiring = commutativeSemiring}(record { isRightSemimodule = isRightSemimodule }); -ᴹ‿cong = -ᴹ‿cong; -ᴹ‿inverse = -ᴹ‿inverse}; *ₗ-*ᵣ-coincident = λ _ _ → ≈ᴹ-refl}
-------------------------------------------------------------------------- The Agda standard library---- Properties of modules.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CommutativeRing; Involutive)open import Algebra.Module.Bundles using (Module)open import Level using (Level)module Algebra.Module.Properties{r ℓr m ℓm : Level}{ring : CommutativeRing r ℓr}(mod : Module ring m ℓm)whereopen Module modopen import Algebra.Module.Properties.Semimodule semimodule publicopen import Algebra.Properties.Group using (⁻¹-involutive)-ᴹ-involutive : Involutive _≈ᴹ_ -ᴹ_-ᴹ-involutive = ⁻¹-involutive +ᴹ-group
-------------------------------------------------------------------------- The Agda standard library---- Properties of semimodules.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra using (CommutativeSemiring)open import Algebra.Module.Bundles using (Semimodule)open import Level using (Level)module Algebra.Module.Properties.Semimodule{r ℓr m ℓm : Level}{semiring : CommutativeSemiring r ℓr}(semimod : Semimodule semiring m ℓm)whereopen CommutativeSemiring semiringopen Semimodule semimodopen import Relation.Nullary.Negation using (contraposition)open import Relation.Binary.Reasoning.Setoid ≈ᴹ-setoidx≈0⇒x*y≈0 : ∀ {x y} → x ≈ 0# → x *ₗ y ≈ᴹ 0ᴹx≈0⇒x*y≈0 {x} {y} x≈0 = beginx *ₗ y ≈⟨ *ₗ-congʳ x≈0 ⟩0# *ₗ y ≈⟨ *ₗ-zeroˡ y ⟩0ᴹ ∎y≈0⇒x*y≈0 : ∀ {x y} → y ≈ᴹ 0ᴹ → x *ₗ y ≈ᴹ 0ᴹy≈0⇒x*y≈0 {x} {y} y≈0 = beginx *ₗ y ≈⟨ *ₗ-congˡ y≈0 ⟩x *ₗ 0ᴹ ≈⟨ *ₗ-zeroʳ x ⟩0ᴹ ∎x*y≉0⇒x≉0 : ∀ {x y} → x *ₗ y ≉ᴹ 0ᴹ → x ≉ 0#x*y≉0⇒x≉0 = contraposition x≈0⇒x*y≈0x*y≉0⇒y≉0 : ∀ {x y} → x *ₗ y ≉ᴹ 0ᴹ → y ≉ᴹ 0ᴹx*y≉0⇒y≉0 = contraposition y≈0⇒x*y≈0
-------------------------------------------------------------------------- The Agda standard library---- Morphisms between module-like algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Morphism.Structures whereopen import Algebra.Module.Bundles.Rawimport Algebra.Module.Morphism.Definitions as MorphismDefinitionsimport Algebra.Morphism.Structures as MorphismStructuresopen import Function.Definitionsopen import Levelprivatevariabler s m₁ m₂ ℓm₁ ℓm₂ : Levelmodule LeftSemimoduleMorphisms{R : Set r}(M₁ : RawLeftSemimodule R m₁ ℓm₁)(M₂ : RawLeftSemimodule R m₂ ℓm₂)whereopen RawLeftSemimodule M₁ renaming (Carrierᴹ to A; _*ₗ_ to _*ₗ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawLeftSemimodule M₂ renaming (Carrierᴹ to B; _*ₗ_ to _*ₗ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_open MorphismStructures.MonoidMorphisms (RawLeftSemimodule.+ᴹ-rawMonoid M₁) (RawLeftSemimodule.+ᴹ-rawMonoid M₂)record IsLeftSemimoduleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isMonoidHomomorphism : IsMonoidHomomorphism ⟦_⟧*ₗ-homo : Homomorphicₗ ⟦_⟧ _*ₗ₁_ _*ₗ₂_open IsMonoidHomomorphism +ᴹ-isMonoidHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong)renaming (isMagmaHomomorphism to +ᴹ-isMagmaHomomorphism; homo to +ᴹ-homo; ε-homo to 0ᴹ-homo)record IsLeftSemimoduleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisLeftSemimoduleHomomorphism : IsLeftSemimoduleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsLeftSemimoduleHomomorphism isLeftSemimoduleHomomorphism public+ᴹ-isMonoidMonomorphism : IsMonoidMonomorphism ⟦_⟧+ᴹ-isMonoidMonomorphism = record{ isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; injective = injective}open IsMonoidMonomorphism +ᴹ-isMonoidMonomorphism publicusing (isRelMonomorphism)renaming (isMagmaMonomorphism to +ᴹ-isMagmaMonomorphism)record IsLeftSemimoduleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisLeftSemimoduleMonomorphism : IsLeftSemimoduleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsLeftSemimoduleMonomorphism isLeftSemimoduleMonomorphism public+ᴹ-isMonoidIsomorphism : IsMonoidIsomorphism ⟦_⟧+ᴹ-isMonoidIsomorphism = record{ isMonoidMonomorphism = +ᴹ-isMonoidMonomorphism; surjective = surjective}open IsMonoidIsomorphism +ᴹ-isMonoidIsomorphism publicusing (isRelIsomorphism)renaming (isMagmaIsomorphism to +ᴹ-isMagmaIsomorphism)module LeftModuleMorphisms{R : Set r}(M₁ : RawLeftModule R m₁ ℓm₁)(M₂ : RawLeftModule R m₂ ℓm₂)whereopen RawLeftModule M₁ renaming (Carrierᴹ to A; _*ₗ_ to _*ₗ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawLeftModule M₂ renaming (Carrierᴹ to B; _*ₗ_ to _*ₗ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_open MorphismStructures.GroupMorphisms (RawLeftModule.+ᴹ-rawGroup M₁) (RawLeftModule.+ᴹ-rawGroup M₂)open LeftSemimoduleMorphisms (RawLeftModule.rawLeftSemimodule M₁) (RawLeftModule.rawLeftSemimodule M₂)record IsLeftModuleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isGroupHomomorphism : IsGroupHomomorphism ⟦_⟧*ₗ-homo : Homomorphicₗ ⟦_⟧ _*ₗ₁_ _*ₗ₂_open IsGroupHomomorphism +ᴹ-isGroupHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong)renaming ( isMagmaHomomorphism to +ᴹ-isMagmaHomomorphism; isMonoidHomomorphism to +ᴹ-isMonoidHomomorphism; homo to +ᴹ-homo; ε-homo to 0ᴹ-homo; ⁻¹-homo to -ᴹ-homo)isLeftSemimoduleHomomorphism : IsLeftSemimoduleHomomorphism ⟦_⟧isLeftSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; *ₗ-homo = *ₗ-homo}record IsLeftModuleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisLeftModuleHomomorphism : IsLeftModuleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsLeftModuleHomomorphism isLeftModuleHomomorphism publicisLeftSemimoduleMonomorphism : IsLeftSemimoduleMonomorphism ⟦_⟧isLeftSemimoduleMonomorphism = record{ isLeftSemimoduleHomomorphism = isLeftSemimoduleHomomorphism; injective = injective}open IsLeftSemimoduleMonomorphism isLeftSemimoduleMonomorphism publicusing (isRelMonomorphism; +ᴹ-isMagmaMonomorphism; +ᴹ-isMonoidMonomorphism)+ᴹ-isGroupMonomorphism : IsGroupMonomorphism ⟦_⟧+ᴹ-isGroupMonomorphism = record{ isGroupHomomorphism = +ᴹ-isGroupHomomorphism; injective = injective}record IsLeftModuleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisLeftModuleMonomorphism : IsLeftModuleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsLeftModuleMonomorphism isLeftModuleMonomorphism publicisLeftSemimoduleIsomorphism : IsLeftSemimoduleIsomorphism ⟦_⟧isLeftSemimoduleIsomorphism = record{ isLeftSemimoduleMonomorphism = isLeftSemimoduleMonomorphism; surjective = surjective}open IsLeftSemimoduleIsomorphism isLeftSemimoduleIsomorphism publicusing (isRelIsomorphism; +ᴹ-isMagmaIsomorphism; +ᴹ-isMonoidIsomorphism)+ᴹ-isGroupIsomorphism : IsGroupIsomorphism ⟦_⟧+ᴹ-isGroupIsomorphism = record{ isGroupMonomorphism = +ᴹ-isGroupMonomorphism; surjective = surjective}module RightSemimoduleMorphisms{R : Set r}(M₁ : RawRightSemimodule R m₁ ℓm₁)(M₂ : RawRightSemimodule R m₂ ℓm₂)whereopen RawRightSemimodule M₁ renaming (Carrierᴹ to A; _*ᵣ_ to _*ᵣ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawRightSemimodule M₂ renaming (Carrierᴹ to B; _*ᵣ_ to _*ᵣ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_open MorphismStructures.MonoidMorphisms (RawRightSemimodule.+ᴹ-rawMonoid M₁) (RawRightSemimodule.+ᴹ-rawMonoid M₂)record IsRightSemimoduleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isMonoidHomomorphism : IsMonoidHomomorphism ⟦_⟧*ᵣ-homo : Homomorphicᵣ ⟦_⟧ _*ᵣ₁_ _*ᵣ₂_open IsMonoidHomomorphism +ᴹ-isMonoidHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong)renaming (isMagmaHomomorphism to +ᴹ-isMagmaHomomorphism; homo to +ᴹ-homo; ε-homo to 0ᴹ-homo)record IsRightSemimoduleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisRightSemimoduleHomomorphism : IsRightSemimoduleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsRightSemimoduleHomomorphism isRightSemimoduleHomomorphism public+ᴹ-isMonoidMonomorphism : IsMonoidMonomorphism ⟦_⟧+ᴹ-isMonoidMonomorphism = record{ isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; injective = injective}open IsMonoidMonomorphism +ᴹ-isMonoidMonomorphism publicusing (isRelMonomorphism)renaming (isMagmaMonomorphism to +ᴹ-isMagmaMonomorphism)record IsRightSemimoduleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisRightSemimoduleMonomorphism : IsRightSemimoduleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsRightSemimoduleMonomorphism isRightSemimoduleMonomorphism public+ᴹ-isMonoidIsomorphism : IsMonoidIsomorphism ⟦_⟧+ᴹ-isMonoidIsomorphism = record{ isMonoidMonomorphism = +ᴹ-isMonoidMonomorphism; surjective = surjective}open IsMonoidIsomorphism +ᴹ-isMonoidIsomorphism publicusing (isRelIsomorphism)renaming (isMagmaIsomorphism to +ᴹ-isMagmaIsomorphism)module RightModuleMorphisms{R : Set r}(M₁ : RawRightModule R m₁ ℓm₁)(M₂ : RawRightModule R m₂ ℓm₂)whereopen RawRightModule M₁ renaming (Carrierᴹ to A; _*ᵣ_ to _*ᵣ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawRightModule M₂ renaming (Carrierᴹ to B; _*ᵣ_ to _*ᵣ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_open MorphismStructures.GroupMorphisms (RawRightModule.+ᴹ-rawGroup M₁) (RawRightModule.+ᴹ-rawGroup M₂)open RightSemimoduleMorphisms (RawRightModule.rawRightSemimodule M₁) (RawRightModule.rawRightSemimodule M₂)record IsRightModuleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isGroupHomomorphism : IsGroupHomomorphism ⟦_⟧*ᵣ-homo : Homomorphicᵣ ⟦_⟧ _*ᵣ₁_ _*ᵣ₂_open IsGroupHomomorphism +ᴹ-isGroupHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong)renaming ( isMagmaHomomorphism to +ᴹ-isMagmaHomomorphism; isMonoidHomomorphism to +ᴹ-isMonoidHomomorphism; homo to +ᴹ-homo; ε-homo to 0ᴹ-homo; ⁻¹-homo to -ᴹ-homo)isRightSemimoduleHomomorphism : IsRightSemimoduleHomomorphism ⟦_⟧isRightSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; *ᵣ-homo = *ᵣ-homo}record IsRightModuleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisRightModuleHomomorphism : IsRightModuleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsRightModuleHomomorphism isRightModuleHomomorphism publicisRightSemimoduleMonomorphism : IsRightSemimoduleMonomorphism ⟦_⟧isRightSemimoduleMonomorphism = record{ isRightSemimoduleHomomorphism = isRightSemimoduleHomomorphism; injective = injective}open IsRightSemimoduleMonomorphism isRightSemimoduleMonomorphism publicusing (isRelMonomorphism; +ᴹ-isMagmaMonomorphism; +ᴹ-isMonoidMonomorphism)+ᴹ-isGroupMonomorphism : IsGroupMonomorphism ⟦_⟧+ᴹ-isGroupMonomorphism = record{ isGroupHomomorphism = +ᴹ-isGroupHomomorphism; injective = injective}record IsRightModuleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisRightModuleMonomorphism : IsRightModuleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsRightModuleMonomorphism isRightModuleMonomorphism publicisRightSemimoduleIsomorphism : IsRightSemimoduleIsomorphism ⟦_⟧isRightSemimoduleIsomorphism = record{ isRightSemimoduleMonomorphism = isRightSemimoduleMonomorphism; surjective = surjective}open IsRightSemimoduleIsomorphism isRightSemimoduleIsomorphism publicusing (isRelIsomorphism; +ᴹ-isMagmaIsomorphism; +ᴹ-isMonoidIsomorphism)+ᴹ-isGroupIsomorphism : IsGroupIsomorphism ⟦_⟧+ᴹ-isGroupIsomorphism = record{ isGroupMonomorphism = +ᴹ-isGroupMonomorphism; surjective = surjective}module BisemimoduleMorphisms{R : Set r}{S : Set s}(M₁ : RawBisemimodule R S m₁ ℓm₁)(M₂ : RawBisemimodule R S m₂ ℓm₂)whereopen RawBisemimodule M₁ renaming (Carrierᴹ to A; _*ₗ_ to _*ₗ₁_; _*ᵣ_ to _*ᵣ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawBisemimodule M₂ renaming (Carrierᴹ to B; _*ₗ_ to _*ₗ₂_; _*ᵣ_ to _*ᵣ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_ using (Homomorphicₗ)open MorphismDefinitions S A B _≈ᴹ₂_ using (Homomorphicᵣ)open MorphismStructures.MonoidMorphisms (RawBisemimodule.+ᴹ-rawMonoid M₁) (RawBisemimodule.+ᴹ-rawMonoid M₂)open LeftSemimoduleMorphisms (RawBisemimodule.rawLeftSemimodule M₁) (RawBisemimodule.rawLeftSemimodule M₂)open RightSemimoduleMorphisms (RawBisemimodule.rawRightSemimodule M₁) (RawBisemimodule.rawRightSemimodule M₂)record IsBisemimoduleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isMonoidHomomorphism : IsMonoidHomomorphism ⟦_⟧*ₗ-homo : Homomorphicₗ ⟦_⟧ _*ₗ₁_ _*ₗ₂_*ᵣ-homo : Homomorphicᵣ ⟦_⟧ _*ᵣ₁_ _*ᵣ₂_isLeftSemimoduleHomomorphism : IsLeftSemimoduleHomomorphism ⟦_⟧isLeftSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; *ₗ-homo = *ₗ-homo}open IsLeftSemimoduleHomomorphism isLeftSemimoduleHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong; +ᴹ-isMagmaHomomorphism; +ᴹ-homo; 0ᴹ-homo)isRightSemimoduleHomomorphism : IsRightSemimoduleHomomorphism ⟦_⟧isRightSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; *ᵣ-homo = *ᵣ-homo}record IsBisemimoduleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBisemimoduleHomomorphism : IsBisemimoduleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsBisemimoduleHomomorphism isBisemimoduleHomomorphism publicisLeftSemimoduleMonomorphism : IsLeftSemimoduleMonomorphism ⟦_⟧isLeftSemimoduleMonomorphism = record{ isLeftSemimoduleHomomorphism = isLeftSemimoduleHomomorphism; injective = injective}open IsLeftSemimoduleMonomorphism isLeftSemimoduleMonomorphism publicusing (isRelMonomorphism; +ᴹ-isMagmaMonomorphism; +ᴹ-isMonoidMonomorphism)isRightSemimoduleMonomorphism : IsRightSemimoduleMonomorphism ⟦_⟧isRightSemimoduleMonomorphism = record{ isRightSemimoduleHomomorphism = isRightSemimoduleHomomorphism; injective = injective}record IsBisemimoduleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBisemimoduleMonomorphism : IsBisemimoduleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsBisemimoduleMonomorphism isBisemimoduleMonomorphism publicisLeftSemimoduleIsomorphism : IsLeftSemimoduleIsomorphism ⟦_⟧isLeftSemimoduleIsomorphism = record{ isLeftSemimoduleMonomorphism = isLeftSemimoduleMonomorphism; surjective = surjective}open IsLeftSemimoduleIsomorphism isLeftSemimoduleIsomorphism publicusing (isRelIsomorphism; +ᴹ-isMagmaIsomorphism; +ᴹ-isMonoidIsomorphism)isRightSemimoduleIsomorphism : IsRightSemimoduleIsomorphism ⟦_⟧isRightSemimoduleIsomorphism = record{ isRightSemimoduleMonomorphism = isRightSemimoduleMonomorphism; surjective = surjective}module BimoduleMorphisms{R : Set r}{S : Set s}(M₁ : RawBimodule R S m₁ ℓm₁)(M₂ : RawBimodule R S m₂ ℓm₂)whereopen RawBimodule M₁ renaming (Carrierᴹ to A; _*ₗ_ to _*ₗ₁_; _*ᵣ_ to _*ᵣ₁_; _≈ᴹ_ to _≈ᴹ₁_)open RawBimodule M₂ renaming (Carrierᴹ to B; _*ₗ_ to _*ₗ₂_; _*ᵣ_ to _*ᵣ₂_; _≈ᴹ_ to _≈ᴹ₂_)open MorphismDefinitions R A B _≈ᴹ₂_ using (Homomorphicₗ)open MorphismDefinitions S A B _≈ᴹ₂_ using (Homomorphicᵣ)open MorphismStructures.GroupMorphisms (RawBimodule.+ᴹ-rawGroup M₁) (RawBimodule.+ᴹ-rawGroup M₂)open LeftModuleMorphisms (RawBimodule.rawLeftModule M₁) (RawBimodule.rawLeftModule M₂)open RightModuleMorphisms (RawBimodule.rawRightModule M₁) (RawBimodule.rawRightModule M₂)open BisemimoduleMorphisms (RawBimodule.rawBisemimodule M₁) (RawBimodule.rawBisemimodule M₂)record IsBimoduleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefield+ᴹ-isGroupHomomorphism : IsGroupHomomorphism ⟦_⟧*ₗ-homo : Homomorphicₗ ⟦_⟧ _*ₗ₁_ _*ₗ₂_*ᵣ-homo : Homomorphicᵣ ⟦_⟧ _*ᵣ₁_ _*ᵣ₂_open IsGroupHomomorphism +ᴹ-isGroupHomomorphism publicusing (isRelHomomorphism; ⟦⟧-cong)renaming ( isMagmaHomomorphism to +ᴹ-isMagmaHomomorphism; isMonoidHomomorphism to +ᴹ-isMonoidHomomorphism; homo to +ᴹ-homo; ε-homo to 0ᴹ-homo; ⁻¹-homo to -ᴹ-homo)isBisemimoduleHomomorphism : IsBisemimoduleHomomorphism ⟦_⟧isBisemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = +ᴹ-isMonoidHomomorphism; *ₗ-homo = *ₗ-homo; *ᵣ-homo = *ᵣ-homo}open IsBisemimoduleHomomorphism isBisemimoduleHomomorphism publicusing (isLeftSemimoduleHomomorphism; isRightSemimoduleHomomorphism)isLeftModuleHomomorphism : IsLeftModuleHomomorphism ⟦_⟧isLeftModuleHomomorphism = record{ +ᴹ-isGroupHomomorphism = +ᴹ-isGroupHomomorphism; *ₗ-homo = *ₗ-homo}isRightModuleHomomorphism : IsRightModuleHomomorphism ⟦_⟧isRightModuleHomomorphism = record{ +ᴹ-isGroupHomomorphism = +ᴹ-isGroupHomomorphism; *ᵣ-homo = *ᵣ-homo}record IsBimoduleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBimoduleHomomorphism : IsBimoduleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsBimoduleHomomorphism isBimoduleHomomorphism public+ᴹ-isGroupMonomorphism : IsGroupMonomorphism ⟦_⟧+ᴹ-isGroupMonomorphism = record{ isGroupHomomorphism = +ᴹ-isGroupHomomorphism; injective = injective}open IsGroupMonomorphism +ᴹ-isGroupMonomorphism publicusing (isRelMonomorphism)renaming (isMagmaMonomorphism to +ᴹ-isMagmaMonomorphism; isMonoidMonomorphism to +ᴹ-isMonoidMonomorphism)isLeftModuleMonomorphism : IsLeftModuleMonomorphism ⟦_⟧isLeftModuleMonomorphism = record{ isLeftModuleHomomorphism = isLeftModuleHomomorphism; injective = injective}open IsLeftModuleMonomorphism isLeftModuleMonomorphism publicusing (isLeftSemimoduleMonomorphism)isRightModuleMonomorphism : IsRightModuleMonomorphism ⟦_⟧isRightModuleMonomorphism = record{ isRightModuleHomomorphism = isRightModuleHomomorphism; injective = injective}open IsRightModuleMonomorphism isRightModuleMonomorphism publicusing (isRightSemimoduleMonomorphism)isBisemimoduleMonomorphism : IsBisemimoduleMonomorphism ⟦_⟧isBisemimoduleMonomorphism = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism; injective = injective}record IsBimoduleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ s ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBimoduleMonomorphism : IsBimoduleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsBimoduleMonomorphism isBimoduleMonomorphism public+ᴹ-isGroupIsomorphism : IsGroupIsomorphism ⟦_⟧+ᴹ-isGroupIsomorphism = record{ isGroupMonomorphism = +ᴹ-isGroupMonomorphism; surjective = surjective}open IsGroupIsomorphism +ᴹ-isGroupIsomorphism publicusing (isRelIsomorphism)renaming (isMagmaIsomorphism to +ᴹ-isMagmaIsomorphism; isMonoidIsomorphism to +ᴹ-isMonoidIsomorphism)isLeftModuleIsomorphism : IsLeftModuleIsomorphism ⟦_⟧isLeftModuleIsomorphism = record{ isLeftModuleMonomorphism = isLeftModuleMonomorphism; surjective = surjective}open IsLeftModuleIsomorphism isLeftModuleIsomorphism publicusing (isLeftSemimoduleIsomorphism)isRightModuleIsomorphism : IsRightModuleIsomorphism ⟦_⟧isRightModuleIsomorphism = record{ isRightModuleMonomorphism = isRightModuleMonomorphism; surjective = surjective}open IsRightModuleIsomorphism isRightModuleIsomorphism publicusing (isRightSemimoduleIsomorphism)isBisemimoduleIsomorphism : IsBisemimoduleIsomorphism ⟦_⟧isBisemimoduleIsomorphism = record{ isBisemimoduleMonomorphism = isBisemimoduleMonomorphism; surjective = surjective}module SemimoduleMorphisms{R : Set r}(M₁ : RawSemimodule R m₁ ℓm₁)(M₂ : RawSemimodule R m₂ ℓm₂)whereopen RawSemimodule M₁ renaming (Carrierᴹ to A; _≈ᴹ_ to _≈ᴹ₁_)open RawSemimodule M₂ renaming (Carrierᴹ to B; _≈ᴹ_ to _≈ᴹ₂_)open BisemimoduleMorphisms (RawSemimodule.rawBisemimodule M₁) (RawSemimodule.rawBisemimodule M₂)record IsSemimoduleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBisemimoduleHomomorphism : IsBisemimoduleHomomorphism ⟦_⟧open IsBisemimoduleHomomorphism isBisemimoduleHomomorphism publicrecord IsSemimoduleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisSemimoduleHomomorphism : IsSemimoduleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsSemimoduleHomomorphism isSemimoduleHomomorphism publicisBisemimoduleMonomorphism : IsBisemimoduleMonomorphism ⟦_⟧isBisemimoduleMonomorphism = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism; injective = injective}open IsBisemimoduleMonomorphism isBisemimoduleMonomorphism publicusing ( isRelMonomorphism; +ᴹ-isMagmaMonomorphism; +ᴹ-isMonoidMonomorphism; isLeftSemimoduleMonomorphism; isRightSemimoduleMonomorphism)record IsSemimoduleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisSemimoduleMonomorphism : IsSemimoduleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsSemimoduleMonomorphism isSemimoduleMonomorphism publicisBisemimoduleIsomorphism : IsBisemimoduleIsomorphism ⟦_⟧isBisemimoduleIsomorphism = record{ isBisemimoduleMonomorphism = isBisemimoduleMonomorphism; surjective = surjective}open IsBisemimoduleIsomorphism isBisemimoduleIsomorphism publicusing ( isRelIsomorphism; +ᴹ-isMagmaIsomorphism; +ᴹ-isMonoidIsomorphism; isLeftSemimoduleIsomorphism; isRightSemimoduleIsomorphism)module ModuleMorphisms{R : Set r}(M₁ : RawModule R m₁ ℓm₁)(M₂ : RawModule R m₂ ℓm₂)whereopen RawModule M₁ renaming (Carrierᴹ to A; _≈ᴹ_ to _≈ᴹ₁_)open RawModule M₂ renaming (Carrierᴹ to B; _≈ᴹ_ to _≈ᴹ₂_)open BimoduleMorphisms (RawModule.rawBimodule M₁) (RawModule.rawBimodule M₂)open SemimoduleMorphisms (RawModule.rawBisemimodule M₁) (RawModule.rawBisemimodule M₂)record IsModuleHomomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisBimoduleHomomorphism : IsBimoduleHomomorphism ⟦_⟧open IsBimoduleHomomorphism isBimoduleHomomorphism publicisSemimoduleHomomorphism : IsSemimoduleHomomorphism ⟦_⟧isSemimoduleHomomorphism = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism}record IsModuleMonomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisModuleHomomorphism : IsModuleHomomorphism ⟦_⟧injective : Injective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsModuleHomomorphism isModuleHomomorphism publicisBimoduleMonomorphism : IsBimoduleMonomorphism ⟦_⟧isBimoduleMonomorphism = record{ isBimoduleHomomorphism = isBimoduleHomomorphism; injective = injective}open IsBimoduleMonomorphism isBimoduleMonomorphism publicusing ( isRelMonomorphism; +ᴹ-isMagmaMonomorphism; +ᴹ-isMonoidMonomorphism; +ᴹ-isGroupMonomorphism; isLeftSemimoduleMonomorphism; isRightSemimoduleMonomorphism; isBisemimoduleMonomorphism; isLeftModuleMonomorphism; isRightModuleMonomorphism)isSemimoduleMonomorphism : IsSemimoduleMonomorphism ⟦_⟧isSemimoduleMonomorphism = record{ isSemimoduleHomomorphism = isSemimoduleHomomorphism; injective = injective}record IsModuleIsomorphism (⟦_⟧ : A → B) : Set (r ⊔ m₁ ⊔ m₂ ⊔ ℓm₁ ⊔ ℓm₂) wherefieldisModuleMonomorphism : IsModuleMonomorphism ⟦_⟧surjective : Surjective _≈ᴹ₁_ _≈ᴹ₂_ ⟦_⟧open IsModuleMonomorphism isModuleMonomorphism publicisBimoduleIsomorphism : IsBimoduleIsomorphism ⟦_⟧isBimoduleIsomorphism = record{ isBimoduleMonomorphism = isBimoduleMonomorphism; surjective = surjective}open IsBimoduleIsomorphism isBimoduleIsomorphism publicusing ( isRelIsomorphism; +ᴹ-isMagmaIsomorphism; +ᴹ-isMonoidIsomorphism; +ᴹ-isGroupIsomorphism; isLeftSemimoduleIsomorphism; isRightSemimoduleIsomorphism; isBisemimoduleIsomorphism; isLeftModuleIsomorphism; isRightModuleIsomorphism)isSemimoduleIsomorphism : IsSemimoduleIsomorphism ⟦_⟧isSemimoduleIsomorphism = record{ isSemimoduleMonomorphism = isSemimoduleMonomorphism; surjective = surjective}open LeftSemimoduleMorphisms publicopen LeftModuleMorphisms publicopen RightSemimoduleMorphisms publicopen RightModuleMorphisms publicopen BisemimoduleMorphisms publicopen BimoduleMorphisms publicopen SemimoduleMorphisms publicopen ModuleMorphisms public
-------------------------------------------------------------------------- The Agda standard library---- Properties of linear maps.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}import Algebra.Module.Properties as ModulePropertiesimport Algebra.Module.Morphism.Structures as MorphismStructuresopen import Algebra using (CommutativeRing)open import Algebra.Module using (Module)open import Level using (Level)module Algebra.Module.Morphism.ModuleHomomorphism{r ℓr m ℓm : Level}{ring : CommutativeRing r ℓr}(modA modB : Module ring m ℓm)(open Module modA using () renaming (Carrierᴹ to A; rawModule to rawModA))(open Module modB using () renaming (Carrierᴹ to B; rawModule to rawModB)){f : A → B}(open MorphismStructures.ModuleMorphisms rawModA rawModB)(isModuleHomomorphism : IsModuleHomomorphism f)whereopen import Axiom.DoubleNegationEliminationopen import Data.Product.Base using (∃₂; _×_; _,_)open import Relation.Binary.Reasoning.MultiSetoidopen import Relation.Nullary using (¬_)open import Relation.Nullary.Negation using (contraposition)module A = Module modAmodule B = Module modBmodule PA = ModuleProperties modAmodule PB = ModuleProperties modBopen CommutativeRing ring renaming (Carrier to S)open IsModuleHomomorphism isModuleHomomorphism-- Some of the lemmas below only hold for continously scalable,-- non-trivial functions, i.e., f x = f (s y) and f ≠ const 0.-- This is a handy abbreviation for that rather verbose term.NonTrivial : A → Set (r Level.⊔ m Level.⊔ ℓm)NonTrivial x = ∃₂ λ s y → (s A.*ₗ x A.≈ᴹ y) × (f y B.≉ᴹ B.0ᴹ)x≈0⇒fx≈0 : ∀ {x} → x A.≈ᴹ A.0ᴹ → f x B.≈ᴹ B.0ᴹx≈0⇒fx≈0 {x} x≈0 = begin⟨ B.≈ᴹ-setoid ⟩f x ≈⟨ ⟦⟧-cong x≈0 ⟩f A.0ᴹ ≈⟨ 0ᴹ-homo ⟩B.0ᴹ ∎fx≉0⇒x≉0 : ∀ {x} → f x B.≉ᴹ B.0ᴹ → x A.≉ᴹ A.0ᴹfx≉0⇒x≉0 = contraposition x≈0⇒fx≈0-- Zero is a unique output of non-trivial (i.e. - ≉ `const 0`) linear map.x≉0⇒f[x]≉0 : ∀ {x} → NonTrivial x → x A.≉ᴹ A.0ᴹ → f x B.≉ᴹ B.0ᴹx≉0⇒f[x]≉0 {x} (s , y , s·x≈y , fy≉0) x≉0 =PB.x*y≉0⇒y≉0 ( λ s·fx≈0 → fy≉0 ( begin⟨ B.≈ᴹ-setoid ⟩f y ≈⟨ ⟦⟧-cong (A.≈ᴹ-sym s·x≈y) ⟩f (s A.*ₗ x) ≈⟨ *ₗ-homo s x ⟩s B.*ₗ f x ≈⟨ s·fx≈0 ⟩B.0ᴹ ∎ ))-- f is odd (i.e. - f (-x) ≈ - (f x)).fx+f[-x]≈0 : (x : A) → f x B.+ᴹ f (A.-ᴹ x) B.≈ᴹ B.0ᴹfx+f[-x]≈0 x = begin⟨ B.≈ᴹ-setoid ⟩f x B.+ᴹ f (A.-ᴹ x) ≈⟨ B.≈ᴹ-sym (+ᴹ-homo x (A.-ᴹ x)) ⟩f (x A.+ᴹ (A.-ᴹ x)) ≈⟨ ⟦⟧-cong (A.-ᴹ‿inverseʳ x) ⟩f A.0ᴹ ≈⟨ 0ᴹ-homo ⟩B.0ᴹ ∎f[-x]≈-fx : (x : A) → f (A.-ᴹ x) B.≈ᴹ B.-ᴹ f xf[-x]≈-fx x = B.uniqueʳ‿-ᴹ (f x) (f (A.-ᴹ x)) (fx+f[-x]≈0 x)-- A non-trivial linear function is injective.fx≈fy⇒fx-fy≈0 : ∀ {x y} → f x B.≈ᴹ f y → f x B.+ᴹ (B.-ᴹ f y) B.≈ᴹ B.0ᴹfx≈fy⇒fx-fy≈0 {x} {y} fx≈fy = begin⟨ B.≈ᴹ-setoid ⟩f x B.+ᴹ (B.-ᴹ f y) ≈⟨ B.+ᴹ-congˡ (B.-ᴹ‿cong (B.≈ᴹ-sym fx≈fy)) ⟩f x B.+ᴹ (B.-ᴹ f x) ≈⟨ B.-ᴹ‿inverseʳ (f x) ⟩B.0ᴹ ∎fx≈fy⇒f[x-y]≈0 : ∀ {x y} → f x B.≈ᴹ f y → f (x A.+ᴹ (A.-ᴹ y)) B.≈ᴹ B.0ᴹfx≈fy⇒f[x-y]≈0 {x} {y} fx≈fy = begin⟨ B.≈ᴹ-setoid ⟩f (x A.+ᴹ (A.-ᴹ y)) ≈⟨ +ᴹ-homo x (A.-ᴹ y) ⟩f x B.+ᴹ f (A.-ᴹ y) ≈⟨ B.+ᴹ-congˡ (f[-x]≈-fx y) ⟩f x B.+ᴹ (B.-ᴹ f y) ≈⟨ fx≈fy⇒fx-fy≈0 fx≈fy ⟩B.0ᴹ ∎module _ {dne : DoubleNegationElimination _} wherefx≈0⇒x≈0 : ∀ {x} → NonTrivial x → f x B.≈ᴹ B.0ᴹ → x A.≈ᴹ A.0ᴹfx≈0⇒x≈0 {x} (s , y , s·x≈y , fy≉0) fx≈0 =dne ¬x≉0where¬x≉0 : ¬ (x A.≉ᴹ A.0ᴹ)¬x≉0 = λ x≉0 → x≉0⇒f[x]≉0 (s , y , s·x≈y , fy≉0) x≉0 fx≈0inj-lm : ∀ {x y} →(∃₂ λ s z → ((s A.*ₗ (x A.+ᴹ A.-ᴹ y) A.≈ᴹ z) × (f z B.≉ᴹ B.0ᴹ))) →f x B.≈ᴹ f y → x A.≈ᴹ yinj-lm {x} {y} (s , z , s·[x-y]≈z , fz≉0) fx≈fy =begin⟨ A.≈ᴹ-setoid ⟩x ≈⟨ x≈--y ⟩A.-ᴹ (A.-ᴹ y) ≈⟨ PA.-ᴹ-involutive y ⟩y ∎wherex-y≈0 : x A.+ᴹ (A.-ᴹ y) A.≈ᴹ A.0ᴹx-y≈0 = fx≈0⇒x≈0 (s , z , s·[x-y]≈z , fz≉0) (fx≈fy⇒f[x-y]≈0 fx≈fy)x≈--y : x A.≈ᴹ A.-ᴹ (A.-ᴹ y)x≈--y = A.uniqueʳ‿-ᴹ (A.-ᴹ y) x( begin⟨ A.≈ᴹ-setoid ⟩A.-ᴹ y A.+ᴹ x ≈⟨ A.+ᴹ-comm (A.-ᴹ y) x ⟩x A.+ᴹ A.-ᴹ y ≈⟨ x-y≈0 ⟩A.0ᴹ ∎)
-------------------------------------------------------------------------- The Agda standard library---- Basic definitions for morphisms between module-like algebraic-- structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coremodule Algebra.Module.Morphism.Definitions{r} (R : Set r) -- The underlying ring{a} (A : Set a) -- The domain of the morphism{b} (B : Set b) -- The codomain of the morphism{ℓ} (_≈_ : Rel B ℓ) -- The equality relation over the codomainwhereopen import Algebra.Module.Coreopen import Algebra.Morphism.Definitions A B _≈_ publicHomomorphicₗ : (A → B) → Opₗ R A → Opₗ R B → Set _Homomorphicₗ ⟦_⟧ _∙_ _∘_ = ∀ r x → ⟦ r ∙ x ⟧ ≈ (r ∘ ⟦ x ⟧)Homomorphicᵣ : (A → B) → Opᵣ R A → Opᵣ R B → Set _Homomorphicᵣ ⟦_⟧ _∙_ _∘_ = ∀ r x → ⟦ x ∙ r ⟧ ≈ (⟦ x ⟧ ∘ r)
-------------------------------------------------------------------------- The Agda standard library---- The identity morphism for module-like algebraic structures------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Module.Morphism.Construct.Identity whereopen import Algebra.Module.Bundles.Rawopen import Algebra.Module.Morphism.Structuresusing ( module LeftSemimoduleMorphisms; module LeftModuleMorphisms; module RightSemimoduleMorphisms; module RightModuleMorphisms; module BisemimoduleMorphisms; module BimoduleMorphisms; module SemimoduleMorphisms; module ModuleMorphisms)open import Algebra.Morphism.Construct.Identityopen import Data.Product.Base using (_,_)open import Function.Base using (id)import Function.Construct.Identity as Idopen import Level using (Level)open import Relation.Binary.Definitions using (Reflexive)privatevariabler s m ℓm : Levelmodule _ {R : Set r} (M : RawLeftSemimodule R m ℓm) (open RawLeftSemimodule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen LeftSemimoduleMorphisms M MisLeftSemimoduleHomomorphism : IsLeftSemimoduleHomomorphism idisLeftSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism _ ≈ᴹ-refl; *ₗ-homo = λ _ _ → ≈ᴹ-refl}isLeftSemimoduleMonomorphism : IsLeftSemimoduleMonomorphism idisLeftSemimoduleMonomorphism = record{ isLeftSemimoduleHomomorphism = isLeftSemimoduleHomomorphism; injective = id}isLeftSemimoduleIsomorphism : IsLeftSemimoduleIsomorphism idisLeftSemimoduleIsomorphism = record{ isLeftSemimoduleMonomorphism = isLeftSemimoduleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} (M : RawLeftModule R m ℓm) (open RawLeftModule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen LeftModuleMorphisms M MisLeftModuleHomomorphism : IsLeftModuleHomomorphism idisLeftModuleHomomorphism = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism _ ≈ᴹ-refl; *ₗ-homo = λ _ _ → ≈ᴹ-refl}isLeftModuleMonomorphism : IsLeftModuleMonomorphism idisLeftModuleMonomorphism = record{ isLeftModuleHomomorphism = isLeftModuleHomomorphism; injective = id}isLeftModuleIsomorphism : IsLeftModuleIsomorphism idisLeftModuleIsomorphism = record{ isLeftModuleMonomorphism = isLeftModuleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} (M : RawRightSemimodule R m ℓm) (open RawRightSemimodule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen RightSemimoduleMorphisms M MisRightSemimoduleHomomorphism : IsRightSemimoduleHomomorphism idisRightSemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism _ ≈ᴹ-refl; *ᵣ-homo = λ _ _ → ≈ᴹ-refl}isRightSemimoduleMonomorphism : IsRightSemimoduleMonomorphism idisRightSemimoduleMonomorphism = record{ isRightSemimoduleHomomorphism = isRightSemimoduleHomomorphism; injective = id}isRightSemimoduleIsomorphism : IsRightSemimoduleIsomorphism idisRightSemimoduleIsomorphism = record{ isRightSemimoduleMonomorphism = isRightSemimoduleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} (M : RawRightModule R m ℓm) (open RawRightModule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen RightModuleMorphisms M MisRightModuleHomomorphism : IsRightModuleHomomorphism idisRightModuleHomomorphism = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism _ ≈ᴹ-refl; *ᵣ-homo = λ _ _ → ≈ᴹ-refl}isRightModuleMonomorphism : IsRightModuleMonomorphism idisRightModuleMonomorphism = record{ isRightModuleHomomorphism = isRightModuleHomomorphism; injective = id}isRightModuleIsomorphism : IsRightModuleIsomorphism idisRightModuleIsomorphism = record{ isRightModuleMonomorphism = isRightModuleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} {S : Set s} (M : RawBisemimodule R S m ℓm) (open RawBisemimodule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen BisemimoduleMorphisms M MisBisemimoduleHomomorphism : IsBisemimoduleHomomorphism idisBisemimoduleHomomorphism = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism _ ≈ᴹ-refl; *ₗ-homo = λ _ _ → ≈ᴹ-refl; *ᵣ-homo = λ _ _ → ≈ᴹ-refl}isBisemimoduleMonomorphism : IsBisemimoduleMonomorphism idisBisemimoduleMonomorphism = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism; injective = id}isBisemimoduleIsomorphism : IsBisemimoduleIsomorphism idisBisemimoduleIsomorphism = record{ isBisemimoduleMonomorphism = isBisemimoduleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} {S : Set s} (M : RawBimodule R S m ℓm) (open RawBimodule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen BimoduleMorphisms M MisBimoduleHomomorphism : IsBimoduleHomomorphism idisBimoduleHomomorphism = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism _ ≈ᴹ-refl; *ₗ-homo = λ _ _ → ≈ᴹ-refl; *ᵣ-homo = λ _ _ → ≈ᴹ-refl}isBimoduleMonomorphism : IsBimoduleMonomorphism idisBimoduleMonomorphism = record{ isBimoduleHomomorphism = isBimoduleHomomorphism; injective = id}isBimoduleIsomorphism : IsBimoduleIsomorphism idisBimoduleIsomorphism = record{ isBimoduleMonomorphism = isBimoduleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} (M : RawSemimodule R m ℓm) (open RawSemimodule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen SemimoduleMorphisms M MisSemimoduleHomomorphism : IsSemimoduleHomomorphism idisSemimoduleHomomorphism = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism _ ≈ᴹ-refl}isSemimoduleMonomorphism : IsSemimoduleMonomorphism idisSemimoduleMonomorphism = record{ isSemimoduleHomomorphism = isSemimoduleHomomorphism; injective = id}isSemimoduleIsomorphism : IsSemimoduleIsomorphism idisSemimoduleIsomorphism = record{ isSemimoduleMonomorphism = isSemimoduleMonomorphism; surjective = Id.surjective _}module _ {R : Set r} (M : RawModule R m ℓm) (open RawModule M) (≈ᴹ-refl : Reflexive _≈ᴹ_) whereopen ModuleMorphisms M MisModuleHomomorphism : IsModuleHomomorphism idisModuleHomomorphism = record{ isBimoduleHomomorphism = isBimoduleHomomorphism _ ≈ᴹ-refl}isModuleMonomorphism : IsModuleMonomorphism idisModuleMonomorphism = record{ isModuleHomomorphism = isModuleHomomorphism; injective = id}isModuleIsomorphism : IsModuleIsomorphism idisModuleIsomorphism = record{ isModuleMonomorphism = isModuleMonomorphism; surjective = Id.surjective _}
-------------------------------------------------------------------------- The Agda standard library---- The composition of morphisms between module-like algebraic structures.------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Module.Morphism.Construct.Composition whereopen import Algebra.Module.Bundles.Rawopen import Algebra.Module.Morphism.Structuresopen import Algebra.Morphism.Construct.Compositionopen import Function.Base using (_∘_)import Function.Construct.Composition as Funcopen import Level using (Level)open import Relation.Binary.Definitions using (Transitive)privatevariabler s m₁ ℓm₁ m₂ ℓm₂ m₃ ℓm₃ : Levelmodule _{R : Set r}{M₁ : RawLeftSemimodule R m₁ ℓm₁}{M₂ : RawLeftSemimodule R m₂ ℓm₂}{M₃ : RawLeftSemimodule R m₃ ℓm₃}(open RawLeftSemimodule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisLeftSemimoduleHomomorphism : IsLeftSemimoduleHomomorphism M₁ M₂ f →IsLeftSemimoduleHomomorphism M₂ M₃ g →IsLeftSemimoduleHomomorphism M₁ M₃ (g ∘ f)isLeftSemimoduleHomomorphism f-homo g-homo = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism ≈ᴹ₃-trans F.+ᴹ-isMonoidHomomorphism G.+ᴹ-isMonoidHomomorphism; *ₗ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ₗ-homo r x)) (G.*ₗ-homo r (f x))} where module F = IsLeftSemimoduleHomomorphism f-homo; module G = IsLeftSemimoduleHomomorphism g-homoisLeftSemimoduleMonomorphism : IsLeftSemimoduleMonomorphism M₁ M₂ f →IsLeftSemimoduleMonomorphism M₂ M₃ g →IsLeftSemimoduleMonomorphism M₁ M₃ (g ∘ f)isLeftSemimoduleMonomorphism f-mono g-mono = record{ isLeftSemimoduleHomomorphism = isLeftSemimoduleHomomorphism F.isLeftSemimoduleHomomorphism G.isLeftSemimoduleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsLeftSemimoduleMonomorphism f-mono; module G = IsLeftSemimoduleMonomorphism g-monoisLeftSemimoduleIsomorphism : IsLeftSemimoduleIsomorphism M₁ M₂ f →IsLeftSemimoduleIsomorphism M₂ M₃ g →IsLeftSemimoduleIsomorphism M₁ M₃ (g ∘ f)isLeftSemimoduleIsomorphism f-iso g-iso = record{ isLeftSemimoduleMonomorphism = isLeftSemimoduleMonomorphism F.isLeftSemimoduleMonomorphism G.isLeftSemimoduleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsLeftSemimoduleIsomorphism f-iso; module G = IsLeftSemimoduleIsomorphism g-isomodule _{R : Set r}{M₁ : RawLeftModule R m₁ ℓm₁}{M₂ : RawLeftModule R m₂ ℓm₂}{M₃ : RawLeftModule R m₃ ℓm₃}(open RawLeftModule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisLeftModuleHomomorphism : IsLeftModuleHomomorphism M₁ M₂ f →IsLeftModuleHomomorphism M₂ M₃ g →IsLeftModuleHomomorphism M₁ M₃ (g ∘ f)isLeftModuleHomomorphism f-homo g-homo = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism ≈ᴹ₃-trans F.+ᴹ-isGroupHomomorphism G.+ᴹ-isGroupHomomorphism; *ₗ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ₗ-homo r x)) (G.*ₗ-homo r (f x))} where module F = IsLeftModuleHomomorphism f-homo; module G = IsLeftModuleHomomorphism g-homoisLeftModuleMonomorphism : IsLeftModuleMonomorphism M₁ M₂ f →IsLeftModuleMonomorphism M₂ M₃ g →IsLeftModuleMonomorphism M₁ M₃ (g ∘ f)isLeftModuleMonomorphism f-mono g-mono = record{ isLeftModuleHomomorphism = isLeftModuleHomomorphism F.isLeftModuleHomomorphism G.isLeftModuleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsLeftModuleMonomorphism f-mono; module G = IsLeftModuleMonomorphism g-monoisLeftModuleIsomorphism : IsLeftModuleIsomorphism M₁ M₂ f →IsLeftModuleIsomorphism M₂ M₃ g →IsLeftModuleIsomorphism M₁ M₃ (g ∘ f)isLeftModuleIsomorphism f-iso g-iso = record{ isLeftModuleMonomorphism = isLeftModuleMonomorphism F.isLeftModuleMonomorphism G.isLeftModuleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsLeftModuleIsomorphism f-iso; module G = IsLeftModuleIsomorphism g-isomodule _{R : Set r}{M₁ : RawRightSemimodule R m₁ ℓm₁}{M₂ : RawRightSemimodule R m₂ ℓm₂}{M₃ : RawRightSemimodule R m₃ ℓm₃}(open RawRightSemimodule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisRightSemimoduleHomomorphism : IsRightSemimoduleHomomorphism M₁ M₂ f →IsRightSemimoduleHomomorphism M₂ M₃ g →IsRightSemimoduleHomomorphism M₁ M₃ (g ∘ f)isRightSemimoduleHomomorphism f-homo g-homo = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism ≈ᴹ₃-trans F.+ᴹ-isMonoidHomomorphism G.+ᴹ-isMonoidHomomorphism; *ᵣ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ᵣ-homo r x)) (G.*ᵣ-homo r (f x))} where module F = IsRightSemimoduleHomomorphism f-homo; module G = IsRightSemimoduleHomomorphism g-homoisRightSemimoduleMonomorphism : IsRightSemimoduleMonomorphism M₁ M₂ f →IsRightSemimoduleMonomorphism M₂ M₃ g →IsRightSemimoduleMonomorphism M₁ M₃ (g ∘ f)isRightSemimoduleMonomorphism f-mono g-mono = record{ isRightSemimoduleHomomorphism = isRightSemimoduleHomomorphism F.isRightSemimoduleHomomorphism G.isRightSemimoduleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsRightSemimoduleMonomorphism f-mono; module G = IsRightSemimoduleMonomorphism g-monoisRightSemimoduleIsomorphism : IsRightSemimoduleIsomorphism M₁ M₂ f →IsRightSemimoduleIsomorphism M₂ M₃ g →IsRightSemimoduleIsomorphism M₁ M₃ (g ∘ f)isRightSemimoduleIsomorphism f-iso g-iso = record{ isRightSemimoduleMonomorphism = isRightSemimoduleMonomorphism F.isRightSemimoduleMonomorphism G.isRightSemimoduleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsRightSemimoduleIsomorphism f-iso; module G = IsRightSemimoduleIsomorphism g-isomodule _{R : Set r}{M₁ : RawRightModule R m₁ ℓm₁}{M₂ : RawRightModule R m₂ ℓm₂}{M₃ : RawRightModule R m₃ ℓm₃}(open RawRightModule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisRightModuleHomomorphism : IsRightModuleHomomorphism M₁ M₂ f →IsRightModuleHomomorphism M₂ M₃ g →IsRightModuleHomomorphism M₁ M₃ (g ∘ f)isRightModuleHomomorphism f-homo g-homo = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism ≈ᴹ₃-trans F.+ᴹ-isGroupHomomorphism G.+ᴹ-isGroupHomomorphism; *ᵣ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ᵣ-homo r x)) (G.*ᵣ-homo r (f x))} where module F = IsRightModuleHomomorphism f-homo; module G = IsRightModuleHomomorphism g-homoisRightModuleMonomorphism : IsRightModuleMonomorphism M₁ M₂ f →IsRightModuleMonomorphism M₂ M₃ g →IsRightModuleMonomorphism M₁ M₃ (g ∘ f)isRightModuleMonomorphism f-mono g-mono = record{ isRightModuleHomomorphism = isRightModuleHomomorphism F.isRightModuleHomomorphism G.isRightModuleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsRightModuleMonomorphism f-mono; module G = IsRightModuleMonomorphism g-monoisRightModuleIsomorphism : IsRightModuleIsomorphism M₁ M₂ f →IsRightModuleIsomorphism M₂ M₃ g →IsRightModuleIsomorphism M₁ M₃ (g ∘ f)isRightModuleIsomorphism f-iso g-iso = record{ isRightModuleMonomorphism = isRightModuleMonomorphism F.isRightModuleMonomorphism G.isRightModuleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsRightModuleIsomorphism f-iso; module G = IsRightModuleIsomorphism g-isomodule _{R : Set r}{S : Set s}{M₁ : RawBisemimodule R S m₁ ℓm₁}{M₂ : RawBisemimodule R S m₂ ℓm₂}{M₃ : RawBisemimodule R S m₃ ℓm₃}(open RawBisemimodule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisBisemimoduleHomomorphism : IsBisemimoduleHomomorphism M₁ M₂ f →IsBisemimoduleHomomorphism M₂ M₃ g →IsBisemimoduleHomomorphism M₁ M₃ (g ∘ f)isBisemimoduleHomomorphism f-homo g-homo = record{ +ᴹ-isMonoidHomomorphism = isMonoidHomomorphism ≈ᴹ₃-trans F.+ᴹ-isMonoidHomomorphism G.+ᴹ-isMonoidHomomorphism; *ₗ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ₗ-homo r x)) (G.*ₗ-homo r (f x)); *ᵣ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ᵣ-homo r x)) (G.*ᵣ-homo r (f x))} where module F = IsBisemimoduleHomomorphism f-homo; module G = IsBisemimoduleHomomorphism g-homoisBisemimoduleMonomorphism : IsBisemimoduleMonomorphism M₁ M₂ f →IsBisemimoduleMonomorphism M₂ M₃ g →IsBisemimoduleMonomorphism M₁ M₃ (g ∘ f)isBisemimoduleMonomorphism f-mono g-mono = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism F.isBisemimoduleHomomorphism G.isBisemimoduleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsBisemimoduleMonomorphism f-mono; module G = IsBisemimoduleMonomorphism g-monoisBisemimoduleIsomorphism : IsBisemimoduleIsomorphism M₁ M₂ f →IsBisemimoduleIsomorphism M₂ M₃ g →IsBisemimoduleIsomorphism M₁ M₃ (g ∘ f)isBisemimoduleIsomorphism f-iso g-iso = record{ isBisemimoduleMonomorphism = isBisemimoduleMonomorphism F.isBisemimoduleMonomorphism G.isBisemimoduleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsBisemimoduleIsomorphism f-iso; module G = IsBisemimoduleIsomorphism g-isomodule _{R : Set r}{S : Set s}{M₁ : RawBimodule R S m₁ ℓm₁}{M₂ : RawBimodule R S m₂ ℓm₂}{M₃ : RawBimodule R S m₃ ℓm₃}(open RawBimodule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisBimoduleHomomorphism : IsBimoduleHomomorphism M₁ M₂ f →IsBimoduleHomomorphism M₂ M₃ g →IsBimoduleHomomorphism M₁ M₃ (g ∘ f)isBimoduleHomomorphism f-homo g-homo = record{ +ᴹ-isGroupHomomorphism = isGroupHomomorphism ≈ᴹ₃-trans F.+ᴹ-isGroupHomomorphism G.+ᴹ-isGroupHomomorphism; *ₗ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ₗ-homo r x)) (G.*ₗ-homo r (f x)); *ᵣ-homo = λ r x → ≈ᴹ₃-trans (G.⟦⟧-cong (F.*ᵣ-homo r x)) (G.*ᵣ-homo r (f x))} where module F = IsBimoduleHomomorphism f-homo; module G = IsBimoduleHomomorphism g-homoisBimoduleMonomorphism : IsBimoduleMonomorphism M₁ M₂ f →IsBimoduleMonomorphism M₂ M₃ g →IsBimoduleMonomorphism M₁ M₃ (g ∘ f)isBimoduleMonomorphism f-mono g-mono = record{ isBimoduleHomomorphism = isBimoduleHomomorphism F.isBimoduleHomomorphism G.isBimoduleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsBimoduleMonomorphism f-mono; module G = IsBimoduleMonomorphism g-monoisBimoduleIsomorphism : IsBimoduleIsomorphism M₁ M₂ f →IsBimoduleIsomorphism M₂ M₃ g →IsBimoduleIsomorphism M₁ M₃ (g ∘ f)isBimoduleIsomorphism f-iso g-iso = record{ isBimoduleMonomorphism = isBimoduleMonomorphism F.isBimoduleMonomorphism G.isBimoduleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsBimoduleIsomorphism f-iso; module G = IsBimoduleIsomorphism g-isomodule _{R : Set r}{M₁ : RawSemimodule R m₁ ℓm₁}{M₂ : RawSemimodule R m₂ ℓm₂}{M₃ : RawSemimodule R m₃ ℓm₃}(open RawSemimodule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisSemimoduleHomomorphism : IsSemimoduleHomomorphism M₁ M₂ f →IsSemimoduleHomomorphism M₂ M₃ g →IsSemimoduleHomomorphism M₁ M₃ (g ∘ f)isSemimoduleHomomorphism f-homo g-homo = record{ isBisemimoduleHomomorphism = isBisemimoduleHomomorphism ≈ᴹ₃-trans F.isBisemimoduleHomomorphism G.isBisemimoduleHomomorphism} where module F = IsSemimoduleHomomorphism f-homo; module G = IsSemimoduleHomomorphism g-homoisSemimoduleMonomorphism : IsSemimoduleMonomorphism M₁ M₂ f →IsSemimoduleMonomorphism M₂ M₃ g →IsSemimoduleMonomorphism M₁ M₃ (g ∘ f)isSemimoduleMonomorphism f-mono g-mono = record{ isSemimoduleHomomorphism = isSemimoduleHomomorphism F.isSemimoduleHomomorphism G.isSemimoduleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsSemimoduleMonomorphism f-mono; module G = IsSemimoduleMonomorphism g-monoisSemimoduleIsomorphism : IsSemimoduleIsomorphism M₁ M₂ f →IsSemimoduleIsomorphism M₂ M₃ g →IsSemimoduleIsomorphism M₁ M₃ (g ∘ f)isSemimoduleIsomorphism f-iso g-iso = record{ isSemimoduleMonomorphism = isSemimoduleMonomorphism F.isSemimoduleMonomorphism G.isSemimoduleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsSemimoduleIsomorphism f-iso; module G = IsSemimoduleIsomorphism g-isomodule _{R : Set r}{M₁ : RawModule R m₁ ℓm₁}{M₂ : RawModule R m₂ ℓm₂}{M₃ : RawModule R m₃ ℓm₃}(open RawModule)(≈ᴹ₃-trans : Transitive (_≈ᴹ_ M₃)){f : Carrierᴹ M₁ → Carrierᴹ M₂}{g : Carrierᴹ M₂ → Carrierᴹ M₃}whereisModuleHomomorphism : IsModuleHomomorphism M₁ M₂ f →IsModuleHomomorphism M₂ M₃ g →IsModuleHomomorphism M₁ M₃ (g ∘ f)isModuleHomomorphism f-homo g-homo = record{ isBimoduleHomomorphism = isBimoduleHomomorphism ≈ᴹ₃-trans F.isBimoduleHomomorphism G.isBimoduleHomomorphism} where module F = IsModuleHomomorphism f-homo; module G = IsModuleHomomorphism g-homoisModuleMonomorphism : IsModuleMonomorphism M₁ M₂ f →IsModuleMonomorphism M₂ M₃ g →IsModuleMonomorphism M₁ M₃ (g ∘ f)isModuleMonomorphism f-mono g-mono = record{ isModuleHomomorphism = isModuleHomomorphism F.isModuleHomomorphism G.isModuleHomomorphism; injective = F.injective ∘ G.injective} where module F = IsModuleMonomorphism f-mono; module G = IsModuleMonomorphism g-monoisModuleIsomorphism : IsModuleIsomorphism M₁ M₂ f →IsModuleIsomorphism M₂ M₃ g →IsModuleIsomorphism M₁ M₃ (g ∘ f)isModuleIsomorphism f-iso g-iso = record{ isModuleMonomorphism = isModuleMonomorphism F.isModuleMonomorphism G.isModuleMonomorphism; surjective = Func.surjective _ _ (_≈ᴹ_ M₃) F.surjective G.surjective} where module F = IsModuleIsomorphism f-iso; module G = IsModuleIsomorphism g-iso
-------------------------------------------------------------------------- The Agda standard library---- This module collects the property definitions for left-scaling-- (LeftDefs), right-scaling (RightDefs), and both (BiDefs).------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Definitions whereimport Algebra.Module.Definitions.Left as Limport Algebra.Module.Definitions.Right as Rimport Algebra.Module.Definitions.Bi as Bimport Algebra.Module.Definitions.Bi.Simultaneous as BSmodule LeftDefs = Lmodule RightDefs = Rmodule BiDefs = Bmodule SimultaneousBiDefs = BS
-------------------------------------------------------------------------- The Agda standard library---- Properties of right-scaling------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coreusing (Rel; _Preserves_⟶_; _Preserves₂_⟶_⟶_)-- The properties are parameterised by the two carriers and-- the result equality.module Algebra.Module.Definitions.Right{a b ℓb} (A : Set a) {B : Set b} (_≈_ : Rel B ℓb)where-------------------------------------------------------------------------- Binary operationsopen import Algebra.Coreopen import Algebra.Module.Core-------------------------------------------------------------------------- Properties of operationsRightIdentity : A → Opᵣ A B → Set _RightIdentity a _∙ᴮ_ = ∀ m → (m ∙ᴮ a) ≈ mAssociative : Op₂ A → Opᵣ A B → Set _Associative _∙ᴬ_ _∙ᴮ_ = ∀ m x y → ((m ∙ᴮ x) ∙ᴮ y) ≈ (m ∙ᴮ (x ∙ᴬ y))infix 4 _DistributesOverʳ_ _DistributesOverˡ_⟶__DistributesOverˡ_⟶_ : Opᵣ A B → Op₂ A → Op₂ B → Set __*_ DistributesOverˡ _+ᴬ_ ⟶ _+ᴮ_ =∀ m x y → (m * (x +ᴬ y)) ≈ ((m * x) +ᴮ (m * y))_DistributesOverʳ_ : Opᵣ A B → Op₂ B → Set __*_ DistributesOverʳ _+_ =∀ x m n → ((m + n) * x) ≈ ((m * x) + (n * x))LeftZero : B → Opᵣ A B → Set _LeftZero z _∙_ = ∀ x → (z ∙ x) ≈ zRightZero : A → B → Opᵣ A B → Set _RightZero zᴬ zᴮ _∙_ = ∀ x → (x ∙ zᴬ) ≈ zᴮCommutative : Opᵣ A B → Set _Commutative _∙_ = ∀ m x y → ((m ∙ x) ∙ y) ≈ ((m ∙ y) ∙ x)LeftCongruent : ∀ {ℓa} → Rel A ℓa → Opᵣ A B → Set _LeftCongruent ≈ᴬ _∙_ = ∀ {m} → (m ∙_) Preserves ≈ᴬ ⟶ _≈_RightCongruent : Opᵣ A B → Set _RightCongruent _∙_ = ∀ {x} → (_∙ x) Preserves _≈_ ⟶ _≈_Congruent : ∀ {ℓa} → Rel A ℓa → Opᵣ A B → Set _Congruent ≈ᴬ ∙ = ∙ Preserves₂ _≈_ ⟶ ≈ᴬ ⟶ _≈_
-------------------------------------------------------------------------- The Agda standard library---- Properties of left-scaling------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Coreusing (Rel; _Preserves_⟶_; _Preserves₂_⟶_⟶_)-- The properties are parameterised by the two carriers and-- the result equality.module Algebra.Module.Definitions.Left{a b ℓb} (A : Set a) {B : Set b} (_≈_ : Rel B ℓb)where-------------------------------------------------------------------------- Binary operationsopen import Algebra.Coreopen import Algebra.Module.Core-------------------------------------------------------------------------- Properties of operationsLeftIdentity : A → Opₗ A B → Set _LeftIdentity a _∙ᴮ_ = ∀ m → (a ∙ᴮ m) ≈ mAssociative : Op₂ A → Opₗ A B → Set _Associative _∙ᴬ_ _∙ᴮ_ = ∀ x y m → ((x ∙ᴬ y) ∙ᴮ m) ≈ (x ∙ᴮ (y ∙ᴮ m))infix 4 _DistributesOverˡ_ _DistributesOverʳ_⟶__DistributesOverˡ_ : Opₗ A B → Op₂ B → Set __*_ DistributesOverˡ _+_ =∀ x m n → (x * (m + n)) ≈ ((x * m) + (x * n))_DistributesOverʳ_⟶_ : Opₗ A B → Op₂ A → Op₂ B → Set __*_ DistributesOverʳ _+ᴬ_ ⟶ _+ᴮ_ =∀ x m n → ((m +ᴬ n) * x) ≈ ((m * x) +ᴮ (n * x))LeftZero : A → B → Opₗ A B → Set _LeftZero zᴬ zᴮ _∙_ = ∀ x → (zᴬ ∙ x) ≈ zᴮRightZero : B → Opₗ A B → Set _RightZero z _∙_ = ∀ x → (x ∙ z) ≈ zCommutative : Opₗ A B → Set _Commutative _∙_ = ∀ x y m → (x ∙ (y ∙ m)) ≈ (y ∙ (x ∙ m))LeftCongruent : Opₗ A B → Set _LeftCongruent _∙_ = ∀ {x} → (x ∙_) Preserves _≈_ ⟶ _≈_RightCongruent : ∀ {ℓa} → Rel A ℓa → Opₗ A B → Set _RightCongruent ≈ᴬ _∙_ = ∀ {m} → (_∙ m) Preserves ≈ᴬ ⟶ _≈_Congruent : ∀ {ℓa} → Rel A ℓa → Opₗ A B → Set _Congruent ≈ᴬ ∙ = ∙ Preserves₂ ≈ᴬ ⟶ _≈_ ⟶ _≈_
-------------------------------------------------------------------------- The Agda standard library---- Properties connecting left-scaling and right-scaling------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)-- The properties are parameterised by the three carriers and-- the result equality.module Algebra.Module.Definitions.Bi{a a′ b ℓb} (A : Set a) (A′ : Set a′) {B : Set b} (_≈_ : Rel B ℓb)whereopen import Algebra.Module.CoreAssociative : Opₗ A B → Opᵣ A′ B → Set _Associative _∙ₗ_ _∙ᵣ_ = ∀ x m y → ((x ∙ₗ m) ∙ᵣ y) ≈ (x ∙ₗ (m ∙ᵣ y))
-------------------------------------------------------------------------- The Agda standard library---- Properties connecting left-scaling and right-scaling over the same scalars------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binarymodule Algebra.Module.Definitions.Bi.Simultaneous{a b ℓb} (A : Set a) {B : Set b} (_≈_ : Rel B ℓb)whereopen import Algebra.Module.CoreCoincident : Opₗ A B → Opᵣ A B → Set _Coincident _∙ₗ_ _∙ᵣ_ = ∀ x m → (x ∙ₗ m) ≈ (m ∙ᵣ x)
-------------------------------------------------------------------------- The Agda standard library---- Core algebraic definitions for module-like structures-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra.Module`{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Core whereopen import Level using (_⊔_)-------------------------------------------------------------------------- Left and right actionsOpₗ : ∀ {a b} → Set a → Set b → Set (a ⊔ b)Opₗ A B = A → B → BOpᵣ : ∀ {a b} → Set a → Set b → Set (a ⊔ b)Opᵣ A B = B → A → B
-------------------------------------------------------------------------- The Agda standard library---- This module constructs the zero R-module, and similar for weaker-- module-like structures.-- The intended universal property is that, given any R-module M, there-- is a unique map into and a unique map out of the zero R-module-- from/to M.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Levelmodule Algebra.Module.Construct.Zero {c ℓ : Level} whereopen import Algebra.Bundlesopen import Algebra.Module.Bundlesopen import Data.Unit.Polymorphicopen import Relation.Binary.Core using (Rel)privatevariabler s ℓr ℓs : Level-------------------------------------------------------------------------- gather all the functionality in one placemodule ℤero whereinfix 4 _≈ᴹ_Carrierᴹ : Set cCarrierᴹ = ⊤_≈ᴹ_ : Rel Carrierᴹ ℓ_ ≈ᴹ _ = ⊤-------------------------------------------------------------------------- Raw bundlesrawLeftSemimodule : {R : Set r} → RawLeftSemimodule R c ℓrawLeftSemimodule = record { ℤero }rawLeftModule : {R : Set r} → RawLeftModule R c ℓrawLeftModule = record { ℤero }rawRightSemimodule : {R : Set r} → RawRightSemimodule R c ℓrawRightSemimodule = record { ℤero }rawRightModule : {R : Set r} → RawRightModule R c ℓrawRightModule = record { ℤero }rawBisemimodule : {R : Set r} {S : Set s} → RawBisemimodule R S c ℓrawBisemimodule = record { ℤero }rawBimodule : {R : Set r} {S : Set s} → RawBimodule R S c ℓrawBimodule = record { ℤero }rawSemimodule : {R : Set r} → RawSemimodule R c ℓrawSemimodule = record { ℤero }rawModule : {R : Set r} → RawModule R c ℓrawModule = record { ℤero }-------------------------------------------------------------------------- BundlesleftSemimodule : {R : Semiring r ℓr} → LeftSemimodule R c ℓleftSemimodule = record { ℤero }rightSemimodule : {S : Semiring s ℓs} → RightSemimodule S c ℓrightSemimodule = record { ℤero }bisemimodule :{R : Semiring r ℓr} {S : Semiring s ℓs} → Bisemimodule R S c ℓbisemimodule = record { ℤero }semimodule : {R : CommutativeSemiring r ℓr} → Semimodule R c ℓsemimodule = record { ℤero }leftModule : {R : Ring r ℓr} → LeftModule R c ℓleftModule = record { ℤero }rightModule : {S : Ring s ℓs} → RightModule S c ℓrightModule = record { ℤero }bimodule : {R : Ring r ℓr} {S : Ring s ℓs} → Bimodule R S c ℓbimodule = record { ℤero }⟨module⟩ : {R : CommutativeRing r ℓr} → Module R c ℓ⟨module⟩ = record { ℤero }
-------------------------------------------------------------------------- The Agda standard library---- This module constructs the unit of the monoidal structure on-- R-modules, and similar for weaker module-like structures.-- The intended universal property is that the maps out of the tensor-- unit into M are isomorphic to the elements of M.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Construct.TensorUnit whereopen import Algebra.Bundlesopen import Algebra.Module.Bundlesopen import Levelprivatevariablec ℓ : Level-------------------------------------------------------------------------- Raw bundlesrawLeftSemimodule : {R : RawSemiring c ℓ} → RawLeftSemimodule _ c ℓrawLeftSemimodule {R = R} = record{ _≈ᴹ_ = _≈_; _+ᴹ_ = _+_; _*ₗ_ = _*_; 0ᴹ = 0#} where open RawSemiring RrawLeftModule : {R : RawRing c ℓ} → RawLeftModule _ c ℓrawLeftModule {R = R} = record{ RawLeftSemimodule (rawLeftSemimodule {R = rawSemiring}); -ᴹ_ = -_} where open RawRing RrawRightSemimodule : {R : RawSemiring c ℓ} → RawRightSemimodule _ c ℓrawRightSemimodule {R = R} = record{ _≈ᴹ_ = _≈_; _+ᴹ_ = _+_; _*ᵣ_ = _*_; 0ᴹ = 0#} where open RawSemiring RrawRightModule : {R : RawRing c ℓ} → RawRightModule _ c ℓrawRightModule {R = R} = record{ RawRightSemimodule (rawRightSemimodule {R = rawSemiring}); -ᴹ_ = -_} where open RawRing RrawBisemimodule : {R : RawSemiring c ℓ} → RawBisemimodule _ _ c ℓrawBisemimodule {R = R} = record{ _≈ᴹ_ = _≈_; _+ᴹ_ = _+_; _*ₗ_ = _*_; _*ᵣ_ = _*_; 0ᴹ = 0#} where open RawSemiring RrawBimodule : {R : RawRing c ℓ} → RawBimodule _ _ c ℓrawBimodule {R = R} = record{ RawBisemimodule (rawBisemimodule {R = rawSemiring}); -ᴹ_ = -_} where open RawRing RrawSemimodule : {R : RawSemiring c ℓ} → RawSemimodule _ c ℓrawSemimodule {R = R} = rawBisemimodule {R = R}rawModule : {R : RawRing c ℓ} → RawModule _ c ℓrawModule {R = R} = rawBimodule {R = R}-------------------------------------------------------------------------- BundlesleftSemimodule : {R : Semiring c ℓ} → LeftSemimodule R c ℓleftSemimodule {R = semiring} = record{ Carrierᴹ = Carrier; _≈ᴹ_ = _≈_; _+ᴹ_ = _+_; _*ₗ_ = _*_; 0ᴹ = 0#; isLeftSemimodule = record{ +ᴹ-isCommutativeMonoid = +-isCommutativeMonoid; isPreleftSemimodule = record{ *ₗ-cong = *-cong; *ₗ-zeroˡ = zeroˡ; *ₗ-distribʳ = distribʳ; *ₗ-identityˡ = *-identityˡ; *ₗ-assoc = *-assoc; *ₗ-zeroʳ = zeroʳ; *ₗ-distribˡ = distribˡ}}} where open Semiring semiringrightSemimodule : {R : Semiring c ℓ} → RightSemimodule R c ℓrightSemimodule {R = semiring} = record{ Carrierᴹ = Carrier; _≈ᴹ_ = _≈_; _+ᴹ_ = _+_; _*ᵣ_ = _*_; 0ᴹ = 0#; isRightSemimodule = record{ +ᴹ-isCommutativeMonoid = +-isCommutativeMonoid; isPrerightSemimodule = record{ *ᵣ-cong = *-cong; *ᵣ-zeroʳ = zeroʳ; *ᵣ-distribˡ = distribˡ; *ᵣ-identityʳ = *-identityʳ; *ᵣ-assoc = *-assoc; *ᵣ-zeroˡ = zeroˡ; *ᵣ-distribʳ = distribʳ}}} where open Semiring semiringbisemimodule : {R : Semiring c ℓ} → Bisemimodule R R c ℓbisemimodule {R = semiring} = record{ isBisemimodule = record{ +ᴹ-isCommutativeMonoid = +-isCommutativeMonoid; isPreleftSemimodule =LeftSemimodule.isPreleftSemimodule leftSemimodule; isPrerightSemimodule =RightSemimodule.isPrerightSemimodule rightSemimodule; *ₗ-*ᵣ-assoc = *-assoc}} where open Semiring semiringsemimodule : {R : CommutativeSemiring c ℓ} → Semimodule R c ℓsemimodule {R = commutativeSemiring} = record{ isSemimodule = record{ isBisemimodule = Bisemimodule.isBisemimodule bisemimodule; *ₗ-*ᵣ-coincident = *-comm}} where open CommutativeSemiring commutativeSemiringleftModule : {R : Ring c ℓ} → LeftModule R c ℓleftModule {R = ring} = record{ -ᴹ_ = -_; isLeftModule = record{ isLeftSemimodule = LeftSemimodule.isLeftSemimodule leftSemimodule; -ᴹ‿cong = -‿cong; -ᴹ‿inverse = -‿inverse}} where open Ring ringrightModule : {R : Ring c ℓ} → RightModule R c ℓrightModule {R = ring} = record{ -ᴹ_ = -_; isRightModule = record{ isRightSemimodule = RightSemimodule.isRightSemimodule rightSemimodule; -ᴹ‿cong = -‿cong; -ᴹ‿inverse = -‿inverse}} where open Ring ringbimodule : {R : Ring c ℓ} → Bimodule R R c ℓbimodule {R = ring} = record{ isBimodule = record{ isBisemimodule = Bisemimodule.isBisemimodule bisemimodule; -ᴹ‿cong = -‿cong; -ᴹ‿inverse = -‿inverse}} where open Ring ring⟨module⟩ : {R : CommutativeRing c ℓ} → Module R c ℓ⟨module⟩ {R = commutativeRing} = record{ isModule = record{ isBimodule = Bimodule.isBimodule bimodule; *ₗ-*ᵣ-coincident = *-comm}} where open CommutativeRing commutativeRing
-------------------------------------------------------------------------- The Agda standard library---- The non-commutative analogue of Nagata's construction of-- the "idealization of a module", (Local Rings, 1962; Wiley)-- defined here on R-R-*bi*modules M over a ring R, as used in-- "Forward- or reverse-mode automatic differentiation: What's the difference?"-- (Van den Berg, Schrijvers, McKinna, Vandenbroucke;-- Science of Computer Programming, Vol. 234, January 2024-- https://doi.org/10.1016/j.scico.2023.103010)---- The construction N =def R ⋉ M , for which there is unfortunately-- no consistent notation in the literature, consists of:-- * carrier: pairs |R| × |M|-- * with additive structure that of the direct sum R ⊕ M _of modules_-- * but with multiplication _*_ such that M forms an _ideal_ of N-- * moreover satisfying 'm * m ≈ 0' for every m ∈ M ⊆ N---- The fundamental lemma (proved here) is that N, in fact, defines a Ring:-- this ring is essentially the 'ring of dual numbers' construction R[M]-- (Clifford, 1874; generalised!) for an ideal M, and thus the synthetic/algebraic-- analogue of the tangent space of M (considered as a 'vector space' over R)-- in differential geometry, hence its application to Automatic Differentiation.---- Nagata's more fundamental insight (not yet shown here) is that-- the lattice of R-submodules of M is in order-isomorphism with-- the lattice of _ideals_ of R ⋉ M , and hence that the study of-- modules can be reduced to that of ideals of a ring, and vice versa.--------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (AbelianGroup; Ring)open import Algebra.Module.Bundles using (Bimodule)module Algebra.Module.Construct.Idealization{r ℓr m ℓm} (ring : Ring r ℓr) (bimodule : Bimodule ring ring m ℓm) whereopen import Algebra.Coreimport Algebra.Consequences.Setoid as Consequencesimport Algebra.Definitions as Definitionsimport Algebra.Module.Construct.DirectProduct as DirectProductimport Algebra.Module.Construct.TensorUnit as TensorUnitopen import Algebra.Structures using (IsAbelianGroup; IsRing)open import Data.Product.Base using (_,_; ∃-syntax)open import Level using (Level; _⊔_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence)import Relation.Binary.Reasoning.Setoid as ≈-Reasoning-------------------------------------------------------------------------- Definitionsprivateopen module R = Ring ringusing ()renaming (Carrier to R)open module M = Bimodule bimodulerenaming (Carrierᴹ to M)+ᴹ-middleFour = Consequences.comm∧assoc⇒middleFour ≈ᴹ-setoid +ᴹ-cong +ᴹ-comm +ᴹ-assocopen module N = Bimodule (DirectProduct.bimodule TensorUnit.bimodule bimodule)using ()renaming ( Carrierᴹ to N; _≈ᴹ_ to _≈_; _+ᴹ_ to _+_; 0ᴹ to 0#; -ᴹ_ to -_; +ᴹ-isAbelianGroup to +-isAbelianGroup)open AbelianGroup M.+ᴹ-abelianGroup hiding (_≈_)open ≈-Reasoning ≈ᴹ-setoidopen Definitions _≈_-- Injections ι from the components of the direct sum-- ιᴹ in fact exhibits M as an _ideal_ of R ⋉ M (see below)ιᴿ : R → Nιᴿ r = r , 0ᴹιᴹ : M → Nιᴹ m = R.0# , m-- Multiplicative unit1# : N1# = ιᴿ R.1#-- Multiplicationinfixl 7 _*__*_ : Op₂ N(r₁ , m₁) * (r₂ , m₂) = r₁ R.* r₂ , r₁ *ₗ m₂ +ᴹ m₁ *ᵣ r₂-- Properties: because we work in the direct sum, every proof has-- * an 'R'-component, which inherits directly from R, and-- * an 'M'-component, where the work happens*-cong : Congruent₂ _*_*-cong (r₁ , m₁) (r₂ , m₂) = R.*-cong r₁ r₂ , +ᴹ-cong (*ₗ-cong r₁ m₂) (*ᵣ-cong m₁ r₂)*-identityˡ : LeftIdentity 1# _*_*-identityˡ (r , m) = R.*-identityˡ r , (beginR.1# *ₗ m +ᴹ 0ᴹ *ᵣ r ≈⟨ +ᴹ-cong (*ₗ-identityˡ m) (*ᵣ-zeroˡ r) ⟩m +ᴹ 0ᴹ ≈⟨ +ᴹ-identityʳ m ⟩m ∎)*-identityʳ : RightIdentity 1# _*_*-identityʳ (r , m) = R.*-identityʳ r , (beginr *ₗ 0ᴹ +ᴹ m *ᵣ R.1# ≈⟨ +ᴹ-cong (*ₗ-zeroʳ r) (*ᵣ-identityʳ m) ⟩0ᴹ +ᴹ m ≈⟨ +ᴹ-identityˡ m ⟩m ∎)*-identity : Identity 1# _*_*-identity = *-identityˡ , *-identityʳ*-assoc : Associative _*_*-assoc (r₁ , m₁) (r₂ , m₂) (r₃ , m₃) = R.*-assoc r₁ r₂ r₃ , (begin(r₁ R.* r₂) *ₗ m₃ +ᴹ (r₁ *ₗ m₂ +ᴹ m₁ *ᵣ r₂) *ᵣ r₃≈⟨ +ᴹ-cong (*ₗ-assoc r₁ r₂ m₃) (*ᵣ-distribʳ r₃ (r₁ *ₗ m₂) (m₁ *ᵣ r₂)) ⟩r₁ *ₗ (r₂ *ₗ m₃) +ᴹ ((r₁ *ₗ m₂) *ᵣ r₃ +ᴹ (m₁ *ᵣ r₂) *ᵣ r₃)≈⟨ +ᴹ-congˡ (+ᴹ-congʳ (*ₗ-*ᵣ-assoc r₁ m₂ r₃)) ⟩r₁ *ₗ (r₂ *ₗ m₃) +ᴹ (r₁ *ₗ (m₂ *ᵣ r₃) +ᴹ (m₁ *ᵣ r₂) *ᵣ r₃)≈⟨ +ᴹ-assoc (r₁ *ₗ (r₂ *ₗ m₃)) (r₁ *ₗ (m₂ *ᵣ r₃)) ((m₁ *ᵣ r₂) *ᵣ r₃) ⟨(r₁ *ₗ (r₂ *ₗ m₃) +ᴹ r₁ *ₗ (m₂ *ᵣ r₃)) +ᴹ (m₁ *ᵣ r₂) *ᵣ r₃≈⟨ +ᴹ-cong (≈ᴹ-sym (*ₗ-distribˡ r₁ (r₂ *ₗ m₃) (m₂ *ᵣ r₃))) (*ᵣ-assoc m₁ r₂ r₃) ⟩r₁ *ₗ (r₂ *ₗ m₃ +ᴹ m₂ *ᵣ r₃) +ᴹ m₁ *ᵣ (r₂ R.* r₃) ∎)distribˡ : _*_ DistributesOverˡ _+_distribˡ (r₁ , m₁) (r₂ , m₂) (r₃ , m₃) = R.distribˡ r₁ r₂ r₃ , (beginr₁ *ₗ (m₂ +ᴹ m₃) +ᴹ m₁ *ᵣ (r₂ R.+ r₃)≈⟨ +ᴹ-cong (*ₗ-distribˡ r₁ m₂ m₃) (*ᵣ-distribˡ m₁ r₂ r₃) ⟩(r₁ *ₗ m₂ +ᴹ r₁ *ₗ m₃) +ᴹ (m₁ *ᵣ r₂ +ᴹ m₁ *ᵣ r₃)≈⟨ +ᴹ-middleFour (r₁ *ₗ m₂) (r₁ *ₗ m₃) (m₁ *ᵣ r₂) (m₁ *ᵣ r₃) ⟩(r₁ *ₗ m₂ +ᴹ m₁ *ᵣ r₂) +ᴹ (r₁ *ₗ m₃ +ᴹ m₁ *ᵣ r₃) ∎)distribʳ : _*_ DistributesOverʳ _+_distribʳ (r₁ , m₁) (r₂ , m₂) (r₃ , m₃) = R.distribʳ r₁ r₂ r₃ , (begin(r₂ R.+ r₃) *ₗ m₁ +ᴹ (m₂ +ᴹ m₃) *ᵣ r₁≈⟨ +ᴹ-cong (*ₗ-distribʳ m₁ r₂ r₃) (*ᵣ-distribʳ r₁ m₂ m₃) ⟩(r₂ *ₗ m₁ +ᴹ r₃ *ₗ m₁) +ᴹ (m₂ *ᵣ r₁ +ᴹ m₃ *ᵣ r₁)≈⟨ +ᴹ-middleFour (r₂ *ₗ m₁) (r₃ *ₗ m₁) (m₂ *ᵣ r₁) (m₃ *ᵣ r₁) ⟩(r₂ *ₗ m₁ +ᴹ m₂ *ᵣ r₁) +ᴹ (r₃ *ₗ m₁ +ᴹ m₃ *ᵣ r₁) ∎)distrib : _*_ DistributesOver _+_distrib = distribˡ , distribʳ-------------------------------------------------------------------------- The Fundamental Lemma-- StructureisRingᴺ : IsRing _≈_ _+_ _*_ -_ 0# 1#isRingᴺ = record{ +-isAbelianGroup = +-isAbelianGroup; *-cong = *-cong; *-assoc = *-assoc; *-identity = *-identity; distrib = distrib}-- Bundleringᴺ : Ring (r ⊔ m) (ℓr ⊔ ℓm)ringᴺ = record { isRing = isRingᴺ }-------------------------------------------------------------------------- M is an ideal of R ⋉ M satisfying m₁ * m₂ ≈ 0#ιᴹ-idealˡ : (n : N) (m : M) → ∃[ n*m ] n * ιᴹ m ≈ ιᴹ n*mιᴹ-idealˡ n@(r , _) m = _ , R.zeroʳ r , ≈ᴹ-reflιᴹ-idealʳ : (m : M) (n : N) → ∃[ m*n ] ιᴹ m * n ≈ ιᴹ m*nιᴹ-idealʳ m n@(r , _) = _ , R.zeroˡ r , ≈ᴹ-refl*-annihilates-ιᴹ : (m₁ m₂ : M) → ιᴹ m₁ * ιᴹ m₂ ≈ 0#*-annihilates-ιᴹ m₁ m₂ = R.zeroˡ R.0# , (beginR.0# *ₗ m₂ +ᴹ m₁ *ᵣ R.0# ≈⟨ +ᴹ-cong (*ₗ-zeroˡ m₂) (*ᵣ-zeroʳ m₁) ⟩0ᴹ +ᴹ 0ᴹ ≈⟨ +ᴹ-identityˡ 0ᴹ ⟩0ᴹ ∎)m*m≈0 : (m : M) → ιᴹ m * ιᴹ m ≈ 0#m*m≈0 m = *-annihilates-ιᴹ m m-------------------------------------------------------------------------- Infix notation for when opening the module unparameterisedinfixl 4 _⋉__⋉_ = ringᴺ
-------------------------------------------------------------------------- The Agda standard library---- This module constructs the biproduct of two R-modules, and similar-- for weaker module-like structures.-- The intended universal property is that the biproduct is both a-- product and a coproduct in the category of R-modules.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Construct.DirectProduct whereopen import Algebra.Bundlesopen import Algebra.Construct.DirectProductopen import Algebra.Module.Bundlesopen import Data.Product.Base using (map; zip; _,_; proj₁; proj₂)open import Data.Product.Relation.Binary.Pointwise.NonDependentopen import Levelprivatevariabler s ℓr ℓs m m′ ℓm ℓm′ : Level-------------------------------------------------------------------------- Raw bundlesrawLeftSemimodule : {R : Set r} →RawLeftSemimodule R m ℓm →RawLeftSemimodule R m′ ℓm′ →RawLeftSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawLeftSemimodule M N = record{ _≈ᴹ_ = Pointwise M._≈ᴹ_ N._≈ᴹ_; _+ᴹ_ = zip M._+ᴹ_ N._+ᴹ_; _*ₗ_ = λ r → map (r M.*ₗ_) (r N.*ₗ_); 0ᴹ = M.0ᴹ , N.0ᴹ} where module M = RawLeftSemimodule M; module N = RawLeftSemimodule NrawLeftModule : {R : Set r} →RawLeftModule R m ℓm →RawLeftModule R m′ ℓm′ →RawLeftModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawLeftModule M N = record{ RawLeftSemimodule (rawLeftSemimodule M.rawLeftSemimodule N.rawLeftSemimodule); -ᴹ_ = map M.-ᴹ_ N.-ᴹ_} where module M = RawLeftModule M; module N = RawLeftModule NrawRightSemimodule : {R : Set r} →RawRightSemimodule R m ℓm →RawRightSemimodule R m′ ℓm′ →RawRightSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawRightSemimodule M N = record{ _≈ᴹ_ = Pointwise M._≈ᴹ_ N._≈ᴹ_; _+ᴹ_ = zip M._+ᴹ_ N._+ᴹ_; _*ᵣ_ = λ mn r → map (M._*ᵣ r) (N._*ᵣ r) mn; 0ᴹ = M.0ᴹ , N.0ᴹ} where module M = RawRightSemimodule M; module N = RawRightSemimodule NrawRightModule : {R : Set r} →RawRightModule R m ℓm →RawRightModule R m′ ℓm′ →RawRightModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawRightModule M N = record{ RawRightSemimodule (rawRightSemimodule M.rawRightSemimodule N.rawRightSemimodule); -ᴹ_ = map M.-ᴹ_ N.-ᴹ_} where module M = RawRightModule M; module N = RawRightModule NrawBisemimodule : {R : Set r} {S : Set s} →RawBisemimodule R S m ℓm →RawBisemimodule R S m′ ℓm′ →RawBisemimodule R S (m ⊔ m′) (ℓm ⊔ ℓm′)rawBisemimodule M N = record{ _≈ᴹ_ = Pointwise M._≈ᴹ_ N._≈ᴹ_; _+ᴹ_ = zip M._+ᴹ_ N._+ᴹ_; _*ₗ_ = λ r → map (r M.*ₗ_) (r N.*ₗ_); _*ᵣ_ = λ mn r → map (M._*ᵣ r) (N._*ᵣ r) mn; 0ᴹ = M.0ᴹ , N.0ᴹ} where module M = RawBisemimodule M; module N = RawBisemimodule NrawBimodule : {R : Set r} {S : Set s} →RawBimodule R S m ℓm →RawBimodule R S m′ ℓm′ →RawBimodule R S (m ⊔ m′) (ℓm ⊔ ℓm′)rawBimodule M N = record{ RawBisemimodule (rawBisemimodule M.rawBisemimodule N.rawBisemimodule); -ᴹ_ = map M.-ᴹ_ N.-ᴹ_} where module M = RawBimodule M; module N = RawBimodule NrawSemimodule : {R : Set r} →RawSemimodule R m ℓm →RawSemimodule R m′ ℓm′ →RawSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawSemimodule M N = rawBisemimodule M NrawModule : {R : Set r} →RawModule R m ℓm →RawModule R m′ ℓm′ →RawModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawModule M N = rawBimodule M N-------------------------------------------------------------------------- BundlesleftSemimodule : {R : Semiring r ℓr} →LeftSemimodule R m ℓm →LeftSemimodule R m′ ℓm′ →LeftSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)leftSemimodule M N = record{ _*ₗ_ = λ r → map (r M.*ₗ_) (r N.*ₗ_); isLeftSemimodule = record{ +ᴹ-isCommutativeMonoid = CommutativeMonoid.isCommutativeMonoid(commutativeMonoid M.+ᴹ-commutativeMonoid N.+ᴹ-commutativeMonoid); isPreleftSemimodule = record{ *ₗ-cong = λ where rr (mm , nn) → M.*ₗ-cong rr mm , N.*ₗ-cong rr nn; *ₗ-zeroˡ = λ where (m , n) → M.*ₗ-zeroˡ m , N.*ₗ-zeroˡ n; *ₗ-distribʳ = λ where(m , n) x y → M.*ₗ-distribʳ m x y , N.*ₗ-distribʳ n x y; *ₗ-identityˡ = λ where (m , n) → M.*ₗ-identityˡ m , N.*ₗ-identityˡ n; *ₗ-assoc = λ where x y (m , n) → M.*ₗ-assoc x y m , N.*ₗ-assoc x y n; *ₗ-zeroʳ = λ x → M.*ₗ-zeroʳ x , N.*ₗ-zeroʳ x; *ₗ-distribˡ = λ wherex (m , n) (m′ , n′) → M.*ₗ-distribˡ x m m′ , N.*ₗ-distribˡ x n n′}}} where module M = LeftSemimodule M; module N = LeftSemimodule NrightSemimodule : {R : Semiring r ℓr} →RightSemimodule R m ℓm →RightSemimodule R m′ ℓm′ →RightSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rightSemimodule M N = record{ _*ᵣ_ = λ mn r → map (M._*ᵣ r) (N._*ᵣ r) mn; isRightSemimodule = record{ +ᴹ-isCommutativeMonoid = CommutativeMonoid.isCommutativeMonoid(commutativeMonoid M.+ᴹ-commutativeMonoid N.+ᴹ-commutativeMonoid); isPrerightSemimodule = record{ *ᵣ-cong = λ where (mm , nn) rr → M.*ᵣ-cong mm rr , N.*ᵣ-cong nn rr; *ᵣ-zeroʳ = λ where (m , n) → M.*ᵣ-zeroʳ m , N.*ᵣ-zeroʳ n; *ᵣ-distribˡ = λ where(m , n) x y → M.*ᵣ-distribˡ m x y , N.*ᵣ-distribˡ n x y; *ᵣ-identityʳ = λ where (m , n) → M.*ᵣ-identityʳ m , N.*ᵣ-identityʳ n; *ᵣ-assoc = λ where(m , n) x y → M.*ᵣ-assoc m x y , N.*ᵣ-assoc n x y; *ᵣ-zeroˡ = λ x → M.*ᵣ-zeroˡ x , N.*ᵣ-zeroˡ x; *ᵣ-distribʳ = λ wherex (m , n) (m′ , n′) → M.*ᵣ-distribʳ x m m′ , N.*ᵣ-distribʳ x n n′}}} where module M = RightSemimodule M; module N = RightSemimodule Nbisemimodule : {R : Semiring r ℓr} {S : Semiring s ℓs} →Bisemimodule R S m ℓm →Bisemimodule R S m′ ℓm′ →Bisemimodule R S (m ⊔ m′) (ℓm ⊔ ℓm′)bisemimodule M N = record{ isBisemimodule = record{ +ᴹ-isCommutativeMonoid = CommutativeMonoid.isCommutativeMonoid(commutativeMonoid M.+ᴹ-commutativeMonoid N.+ᴹ-commutativeMonoid); isPreleftSemimodule = LeftSemimodule.isPreleftSemimodule(leftSemimodule M.leftSemimodule N.leftSemimodule); isPrerightSemimodule = RightSemimodule.isPrerightSemimodule(rightSemimodule M.rightSemimodule N.rightSemimodule); *ₗ-*ᵣ-assoc = λ wherex (m , n) y → M.*ₗ-*ᵣ-assoc x m y , N.*ₗ-*ᵣ-assoc x n y}} where module M = Bisemimodule M; module N = Bisemimodule Nsemimodule : {R : CommutativeSemiring r ℓr} →Semimodule R m ℓm →Semimodule R m′ ℓm′ →Semimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)semimodule M N = record{ isSemimodule = record{ isBisemimodule = Bisemimodule.isBisemimodule(bisemimodule M.bisemimodule N.bisemimodule); *ₗ-*ᵣ-coincident = λ x m → M.*ₗ-*ᵣ-coincident x (proj₁ m) , N.*ₗ-*ᵣ-coincident x (proj₂ m)}} where module M = Semimodule M; module N = Semimodule NleftModule : {R : Ring r ℓr} →LeftModule R m ℓm →LeftModule R m′ ℓm′ →LeftModule R (m ⊔ m′) (ℓm ⊔ ℓm′)leftModule M N = record{ -ᴹ_ = map M.-ᴹ_ N.-ᴹ_; isLeftModule = record{ isLeftSemimodule = LeftSemimodule.isLeftSemimodule(leftSemimodule M.leftSemimodule N.leftSemimodule); -ᴹ‿cong = λ where (mm , nn) → M.-ᴹ‿cong mm , N.-ᴹ‿cong nn; -ᴹ‿inverse = λ where.proj₁ (m , n) → M.-ᴹ‿inverseˡ m , N.-ᴹ‿inverseˡ n.proj₂ (m , n) → M.-ᴹ‿inverseʳ m , N.-ᴹ‿inverseʳ n}} where module M = LeftModule M; module N = LeftModule NrightModule : {R : Ring r ℓr} →RightModule R m ℓm →RightModule R m′ ℓm′ →RightModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rightModule M N = record{ -ᴹ_ = map M.-ᴹ_ N.-ᴹ_; isRightModule = record{ isRightSemimodule = RightSemimodule.isRightSemimodule(rightSemimodule M.rightSemimodule N.rightSemimodule); -ᴹ‿cong = λ where (mm , nn) → M.-ᴹ‿cong mm , N.-ᴹ‿cong nn; -ᴹ‿inverse = λ where.proj₁ (m , n) → M.-ᴹ‿inverseˡ m , N.-ᴹ‿inverseˡ n.proj₂ (m , n) → M.-ᴹ‿inverseʳ m , N.-ᴹ‿inverseʳ n}} where module M = RightModule M; module N = RightModule Nbimodule : {R : Ring r ℓr} {S : Ring s ℓs} →Bimodule R S m ℓm →Bimodule R S m′ ℓm′ →Bimodule R S (m ⊔ m′) (ℓm ⊔ ℓm′)bimodule M N = record{ -ᴹ_ = map M.-ᴹ_ N.-ᴹ_; isBimodule = record{ isBisemimodule = Bisemimodule.isBisemimodule(bisemimodule M.bisemimodule N.bisemimodule); -ᴹ‿cong = λ where (mm , nn) → M.-ᴹ‿cong mm , N.-ᴹ‿cong nn; -ᴹ‿inverse = λ where.proj₁ (m , n) → M.-ᴹ‿inverseˡ m , N.-ᴹ‿inverseˡ n.proj₂ (m , n) → M.-ᴹ‿inverseʳ m , N.-ᴹ‿inverseʳ n}} where module M = Bimodule M; module N = Bimodule N⟨module⟩ : {R : CommutativeRing r ℓr} →Module R m ℓm →Module R m′ ℓm′ →Module R (m ⊔ m′) (ℓm ⊔ ℓm′)⟨module⟩ M N = record{ isModule = record{ isBimodule = Bimodule.isBimodule (bimodule M.bimodule N.bimodule); *ₗ-*ᵣ-coincident = λ x m → M.*ₗ-*ᵣ-coincident x (proj₁ m) , N.*ₗ-*ᵣ-coincident x (proj₂ m)}} where module M = Module M; module N = Module N
-------------------------------------------------------------------------- The Agda standard library---- Relations between properties of scaling and other operations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Consequences whereopen import Algebra.Core using (Op₂)import Algebra.Definitions as Defsopen import Algebra.Module.Core using (Opₗ; Opᵣ)open import Algebra.Module.Definitionsopen import Function.Base using (flip)open import Level using (Level)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatevariablea b c ℓ ℓa : LevelA : Set aB : Set bmodule _ (_≈ᴬ_ : Rel {a} A ℓa) (S : Setoid c ℓ) whereopen Setoid Sopen ≈-Reasoning Sopen Defs _≈ᴬ_privatemodule L = LeftDefs A _≈_module R = RightDefs A _≈_module B = BiDefs A A _≈_module _ {_*_ : Op₂ A} {_*ₗ_ : Opₗ A Carrier} whereprivate_*ᵣ_ = flip _*ₗ_*ₗ-assoc+comm⇒*ᵣ-assoc :L.RightCongruent _≈ᴬ_ _*ₗ_ →L.Associative _*_ _*ₗ_ → Commutative _*_ → R.Associative _*_ _*ᵣ_*ₗ-assoc+comm⇒*ᵣ-assoc *ₗ-congʳ *ₗ-assoc *-comm m x y = begin(m *ᵣ x) *ᵣ y ≈⟨ refl ⟩y *ₗ (x *ₗ m) ≈⟨ *ₗ-assoc _ _ _ ⟨(y * x) *ₗ m ≈⟨ *ₗ-congʳ (*-comm y x) ⟩(x * y) *ₗ m ≈⟨ refl ⟩m *ᵣ (x * y) ∎*ₗ-assoc+comm⇒*ₗ-*ᵣ-assoc :L.RightCongruent _≈ᴬ_ _*ₗ_ →L.Associative _*_ _*ₗ_ → Commutative _*_ → B.Associative _*ₗ_ _*ᵣ_*ₗ-assoc+comm⇒*ₗ-*ᵣ-assoc *ₗ-congʳ *ₗ-assoc *-comm x m y = begin((x *ₗ m) *ᵣ y) ≈⟨ refl ⟩(y *ₗ (x *ₗ m)) ≈⟨ *ₗ-assoc _ _ _ ⟨((y * x) *ₗ m) ≈⟨ *ₗ-congʳ (*-comm y x) ⟩((x * y) *ₗ m) ≈⟨ *ₗ-assoc _ _ _ ⟩(x *ₗ (y *ₗ m)) ≈⟨ refl ⟩(x *ₗ (m *ᵣ y)) ∎module _ {_*_ : Op₂ A} {_*ᵣ_ : Opᵣ A Carrier} whereprivate_*ₗ_ = flip _*ᵣ_*ᵣ-assoc+comm⇒*ₗ-assoc :R.LeftCongruent _≈ᴬ_ _*ᵣ_ →R.Associative _*_ _*ᵣ_ → Commutative _*_ → L.Associative _*_ _*ₗ_*ᵣ-assoc+comm⇒*ₗ-assoc *ᵣ-congˡ *ᵣ-assoc *-comm x y m = begin((x * y) *ₗ m) ≈⟨ refl ⟩(m *ᵣ (x * y)) ≈⟨ *ᵣ-congˡ (*-comm x y) ⟩(m *ᵣ (y * x)) ≈⟨ *ᵣ-assoc _ _ _ ⟨((m *ᵣ y) *ᵣ x) ≈⟨ refl ⟩(x *ₗ (y *ₗ m)) ∎*ᵣ-assoc+comm⇒*ₗ-*ᵣ-assoc :R.LeftCongruent _≈ᴬ_ _*ᵣ_ →R.Associative _*_ _*ᵣ_ → Commutative _*_ → B.Associative _*ₗ_ _*ᵣ_*ᵣ-assoc+comm⇒*ₗ-*ᵣ-assoc *ᵣ-congˡ *ᵣ-assoc *-comm x m y = begin((x *ₗ m) *ᵣ y) ≈⟨ refl ⟩((m *ᵣ x) *ᵣ y) ≈⟨ *ᵣ-assoc _ _ _ ⟩(m *ᵣ (x * y)) ≈⟨ *ᵣ-congˡ (*-comm x y) ⟩(m *ᵣ (y * x)) ≈⟨ *ᵣ-assoc _ _ _ ⟨((m *ᵣ y) *ᵣ x) ≈⟨ refl ⟩(x *ₗ (m *ᵣ y)) ∎
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structures defined over some other-- structure, like modules and vector spaces---- Terminology of bundles:-- * There are both *semimodules* and *modules*.-- - For M an R-semimodule, R is a semiring, and M forms a commutative-- monoid.-- - For M an R-module, R is a ring, and M forms an Abelian group.-- * There are all four of *left modules*, *right modules*, *bimodules*,-- and *modules*.-- - Left modules have a left-scaling operation.-- - Right modules have a right-scaling operation.-- - Bimodules have two sorts of scalars. Left-scaling handles one and-- right-scaling handles the other. Left-scaling and right-scaling-- are furthermore compatible.-- - Modules are bimodules with a single sort of scalars and scalar-- multiplication must also be commutative. Left-scaling and-- right-scaling coincide.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Bundles whereopen import Algebra.Bundlesopen import Algebra.Coreopen import Algebra.Definitions using (Involutive)import Algebra.Module.Bundles.Raw as Rawopen import Algebra.Module.Coreopen import Algebra.Module.Structuresopen import Algebra.Module.Definitionsopen import Algebra.Properties.Groupopen import Function.Baseopen import Levelopen import Relation.Binary.Core using (Rel)open import Relation.Nullary using (¬_)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatevariabler ℓr s ℓs : Level-------------------------------------------------------------------------- Re-export definitions of 'raw' bundlesopen Raw publicusing ( RawLeftSemimodule; RawLeftModule; RawRightSemimodule; RawRightModule; RawBisemimodule; RawBimodule; RawSemimodule; RawModule)-------------------------------------------------------------------------- Left modules------------------------------------------------------------------------record LeftSemimodule (semiring : Semiring r ℓr) m ℓm: Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen Semiring semiringinfixr 7 _*ₗ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ Carrier Carrierᴹ0ᴹ : CarrierᴹisLeftSemimodule : IsLeftSemimodule semiring _≈ᴹ_ _+ᴹ_ 0ᴹ _*ₗ_open IsLeftSemimodule isLeftSemimodule public+ᴹ-commutativeMonoid : CommutativeMonoid m ℓm+ᴹ-commutativeMonoid = record{ isCommutativeMonoid = +ᴹ-isCommutativeMonoid}open CommutativeMonoid +ᴹ-commutativeMonoid publicusing () renaming( monoid to +ᴹ-monoid; semigroup to +ᴹ-semigroup; magma to +ᴹ-magma; rawMagma to +ᴹ-rawMagma; rawMonoid to +ᴹ-rawMonoid; _≉_ to _≉ᴹ_)rawLeftSemimodule : RawLeftSemimodule Carrier m ℓmrawLeftSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; 0ᴹ = 0ᴹ}record LeftModule (ring : Ring r ℓr) m ℓm : Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen Ring ringinfixr 8 -ᴹ_infixr 7 _*ₗ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ Carrier Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹisLeftModule : IsLeftModule ring _≈ᴹ_ _+ᴹ_ 0ᴹ -ᴹ_ _*ₗ_open IsLeftModule isLeftModule publicleftSemimodule : LeftSemimodule semiring m ℓmleftSemimodule = record { isLeftSemimodule = isLeftSemimodule }open LeftSemimodule leftSemimodule publicusing ( +ᴹ-commutativeMonoid; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma; +ᴹ-rawMagma; +ᴹ-rawMonoid; rawLeftSemimodule; _≉ᴹ_)+ᴹ-abelianGroup : AbelianGroup m ℓm+ᴹ-abelianGroup = record { isAbelianGroup = +ᴹ-isAbelianGroup }open AbelianGroup +ᴹ-abelianGroup publicusing () renaming (group to +ᴹ-group; rawGroup to +ᴹ-rawGroup)rawLeftModule : RawLeftModule Carrier m ℓmrawLeftModule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; 0ᴹ = 0ᴹ; -ᴹ_ = -ᴹ_}-------------------------------------------------------------------------- Right modules------------------------------------------------------------------------record RightSemimodule (semiring : Semiring r ℓr) m ℓm: Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen Semiring semiringinfixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ᵣ_ : Opᵣ Carrier Carrierᴹ0ᴹ : CarrierᴹisRightSemimodule : IsRightSemimodule semiring _≈ᴹ_ _+ᴹ_ 0ᴹ _*ᵣ_open IsRightSemimodule isRightSemimodule public+ᴹ-commutativeMonoid : CommutativeMonoid m ℓm+ᴹ-commutativeMonoid = record{ isCommutativeMonoid = +ᴹ-isCommutativeMonoid}open CommutativeMonoid +ᴹ-commutativeMonoid publicusing () renaming( monoid to +ᴹ-monoid; semigroup to +ᴹ-semigroup; magma to +ᴹ-magma; rawMagma to +ᴹ-rawMagma; rawMonoid to +ᴹ-rawMonoid; _≉_ to _≉ᴹ_)rawRightSemimodule : RawRightSemimodule Carrier m ℓmrawRightSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ}record RightModule (ring : Ring r ℓr) m ℓm : Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen Ring ringinfixr 8 -ᴹ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ᵣ_ : Opᵣ Carrier Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹisRightModule : IsRightModule ring _≈ᴹ_ _+ᴹ_ 0ᴹ -ᴹ_ _*ᵣ_open IsRightModule isRightModule publicrightSemimodule : RightSemimodule semiring m ℓmrightSemimodule = record { isRightSemimodule = isRightSemimodule }open RightSemimodule rightSemimodule publicusing ( +ᴹ-commutativeMonoid; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma; +ᴹ-rawMagma; +ᴹ-rawMonoid; rawRightSemimodule; _≉ᴹ_)+ᴹ-abelianGroup : AbelianGroup m ℓm+ᴹ-abelianGroup = record { isAbelianGroup = +ᴹ-isAbelianGroup }open AbelianGroup +ᴹ-abelianGroup publicusing () renaming (group to +ᴹ-group; rawGroup to +ᴹ-rawGroup)rawRightModule : RawRightModule Carrier m ℓmrawRightModule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ; -ᴹ_ = -ᴹ_}-------------------------------------------------------------------------- Bimodules------------------------------------------------------------------------record Bisemimodule (R-semiring : Semiring r ℓr) (S-semiring : Semiring s ℓs)m ℓm : Set (r ⊔ s ⊔ ℓr ⊔ ℓs ⊔ suc (m ⊔ ℓm)) whereprivatemodule R = Semiring R-semiringmodule S = Semiring S-semiringinfixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R.Carrier Carrierᴹ_*ᵣ_ : Opᵣ S.Carrier Carrierᴹ0ᴹ : CarrierᴹisBisemimodule : IsBisemimodule R-semiring S-semiring _≈ᴹ_ _+ᴹ_ 0ᴹ _*ₗ_ _*ᵣ_open IsBisemimodule isBisemimodule publicleftSemimodule : LeftSemimodule R-semiring m ℓmleftSemimodule = record { isLeftSemimodule = isLeftSemimodule }rightSemimodule : RightSemimodule S-semiring m ℓmrightSemimodule = record { isRightSemimodule = isRightSemimodule }open LeftSemimodule leftSemimodule publicusing ( +ᴹ-commutativeMonoid; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma; +ᴹ-rawMagma; +ᴹ-rawMonoid; rawLeftSemimodule; _≉ᴹ_)open RightSemimodule rightSemimodule publicusing ( rawRightSemimodule )rawBisemimodule : RawBisemimodule R.Carrier S.Carrier m ℓmrawBisemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ}record Bimodule (R-ring : Ring r ℓr) (S-ring : Ring s ℓs) m ℓm: Set (r ⊔ s ⊔ ℓr ⊔ ℓs ⊔ suc (m ⊔ ℓm)) whereprivatemodule R = Ring R-ringmodule S = Ring S-ringinfix 8 -ᴹ_infixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R.Carrier Carrierᴹ_*ᵣ_ : Opᵣ S.Carrier Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹisBimodule : IsBimodule R-ring S-ring _≈ᴹ_ _+ᴹ_ 0ᴹ -ᴹ_ _*ₗ_ _*ᵣ_open IsBimodule isBimodule publicleftModule : LeftModule R-ring m ℓmleftModule = record { isLeftModule = isLeftModule }rightModule : RightModule S-ring m ℓmrightModule = record { isRightModule = isRightModule }open LeftModule leftModule publicusing ( +ᴹ-abelianGroup; +ᴹ-commutativeMonoid; +ᴹ-group; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma; +ᴹ-rawMagma; +ᴹ-rawMonoid; +ᴹ-rawGroup; rawLeftSemimodule; rawLeftModule; _≉ᴹ_)open RightModule rightModule publicusing ( rawRightSemimodule; rawRightModule )bisemimodule : Bisemimodule R.semiring S.semiring m ℓmbisemimodule = record { isBisemimodule = isBisemimodule }open Bisemimodule bisemimodule publicusing (leftSemimodule; rightSemimodule; rawBisemimodule)rawBimodule : RawBimodule R.Carrier S.Carrier m ℓmrawBimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ; -ᴹ_ = -ᴹ_}-------------------------------------------------------------------------- Modules over commutative structures------------------------------------------------------------------------record Semimodule (commutativeSemiring : CommutativeSemiring r ℓr) m ℓm: Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen CommutativeSemiring commutativeSemiringinfixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ Carrier Carrierᴹ_*ᵣ_ : Opᵣ Carrier Carrierᴹ0ᴹ : CarrierᴹisSemimodule : IsSemimodule commutativeSemiring _≈ᴹ_ _+ᴹ_ 0ᴹ _*ₗ_ _*ᵣ_open IsSemimodule isSemimodule publicprivatemodule L = LeftDefs Carrier _≈ᴹ_module R = RightDefs Carrier _≈ᴹ_bisemimodule : Bisemimodule semiring semiring m ℓmbisemimodule = record { isBisemimodule = isBisemimodule }open Bisemimodule bisemimodule publicusing ( leftSemimodule; rightSemimodule; +ᴹ-commutativeMonoid; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma; +ᴹ-rawMagma; +ᴹ-rawMonoid; rawLeftSemimodule; rawRightSemimodule; rawBisemimodule; _≉ᴹ_)open ≈-Reasoning ≈ᴹ-setoid*ₗ-comm : L.Commutative _*ₗ_*ₗ-comm x y m = beginx *ₗ y *ₗ m ≈⟨ ≈ᴹ-sym (*ₗ-assoc x y m) ⟩(x * y) *ₗ m ≈⟨ *ₗ-cong (*-comm _ _) ≈ᴹ-refl ⟩(y * x) *ₗ m ≈⟨ *ₗ-assoc y x m ⟩y *ₗ x *ₗ m ∎*ᵣ-comm : R.Commutative _*ᵣ_*ᵣ-comm m x y = beginm *ᵣ x *ᵣ y ≈⟨ *ᵣ-assoc m x y ⟩m *ᵣ (x * y) ≈⟨ *ᵣ-cong ≈ᴹ-refl (*-comm _ _) ⟩m *ᵣ (y * x) ≈⟨ ≈ᴹ-sym (*ᵣ-assoc m y x) ⟩m *ᵣ y *ᵣ x ∎rawSemimodule : RawSemimodule Carrier m ℓmrawSemimodule = rawBisemimodulerecord Module (commutativeRing : CommutativeRing r ℓr) m ℓm: Set (r ⊔ ℓr ⊔ suc (m ⊔ ℓm)) whereopen CommutativeRing commutativeRinginfixr 8 -ᴹ_infixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ Carrier Carrierᴹ_*ᵣ_ : Opᵣ Carrier Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹisModule : IsModule commutativeRing _≈ᴹ_ _+ᴹ_ 0ᴹ -ᴹ_ _*ₗ_ _*ᵣ_open IsModule isModule publicbimodule : Bimodule ring ring m ℓmbimodule = record { isBimodule = isBimodule }open Bimodule bimodule publicusing ( leftModule; rightModule; leftSemimodule; rightSemimodule; +ᴹ-abelianGroup; +ᴹ-group; +ᴹ-commutativeMonoid; +ᴹ-monoid; +ᴹ-semigroup; +ᴹ-magma ; +ᴹ-rawMonoid; +ᴹ-rawMagma; +ᴹ-rawGroup; rawLeftSemimodule; rawLeftModule; rawRightSemimodule; rawRightModule; rawBisemimodule; rawBimodule; _≉ᴹ_)semimodule : Semimodule commutativeSemiring m ℓmsemimodule = record { isSemimodule = isSemimodule }open Semimodule semimodule public using (*ₗ-comm; *ᵣ-comm; rawSemimodule)rawModule : RawModule Carrier m ℓmrawModule = rawBimodule
-------------------------------------------------------------------------- The Agda standard library---- Definitions of 'raw' bundles for module-like algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Module.Bundles.Raw whereopen import Algebra.Bundles.Rawopen import Algebra.Coreopen import Algebra.Module.Coreopen import Levelopen import Relation.Nullary.Negation.Core using (¬_)open import Relation.Binary.Core using (Rel)privatevariabler ℓr s ℓs : Level-------------------------------------------------------------------------- Raw left modules------------------------------------------------------------------------record RawLeftSemimodule (R : Set r) m ℓm : Set (r ⊔ suc (m ⊔ ℓm)) whereinfixr 7 _*ₗ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R Carrierᴹ0ᴹ : Carrierᴹ+ᴹ-rawMonoid : RawMonoid m ℓm+ᴹ-rawMonoid = record{ _≈_ = _≈ᴹ_; _∙_ = _+ᴹ_; ε = 0ᴹ}open RawMonoid +ᴹ-rawMonoid publicusing ()renaming (rawMagma to +ᴹ-rawMagma; _≉_ to _≉ᴹ_)record RawLeftModule (R : Set r) m ℓm : Set (r ⊔ suc (m ⊔ ℓm)) whereinfix 8 -ᴹ_infixr 7 _*ₗ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹrawLeftSemimodule : RawLeftSemimodule R m ℓmrawLeftSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; 0ᴹ = 0ᴹ}open RawLeftSemimodule rawLeftSemimodule publicusing (+ᴹ-rawMagma; +ᴹ-rawMonoid; _≉ᴹ_)+ᴹ-rawGroup : RawGroup m ℓm+ᴹ-rawGroup = record{ _≈_ = _≈ᴹ_; _∙_ = _+ᴹ_; ε = 0ᴹ; _⁻¹ = -ᴹ_}-------------------------------------------------------------------------- Raw right modules------------------------------------------------------------------------record RawRightSemimodule (R : Set r) m ℓm : Set (r ⊔ suc (m ⊔ ℓm)) whereinfixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ᵣ_ : Opᵣ R Carrierᴹ0ᴹ : Carrierᴹ+ᴹ-rawMonoid : RawMonoid m ℓm+ᴹ-rawMonoid = record{ _≈_ = _≈ᴹ_; _∙_ = _+ᴹ_; ε = 0ᴹ}open RawMonoid +ᴹ-rawMonoid publicusing ()renaming (rawMagma to +ᴹ-rawMagma; _≉_ to _≉ᴹ_)record RawRightModule (R : Set r) m ℓm : Set (r ⊔ suc (m ⊔ ℓm)) whereinfix 8 -ᴹ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ᵣ_ : Opᵣ R Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹrawRightSemimodule : RawRightSemimodule R m ℓmrawRightSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ}open RawRightSemimodule rawRightSemimodule publicusing (+ᴹ-rawMagma; +ᴹ-rawMonoid; _≉ᴹ_)+ᴹ-rawGroup : RawGroup m ℓm+ᴹ-rawGroup = record{ _≈_ = _≈ᴹ_; _∙_ = _+ᴹ_; ε = 0ᴹ; _⁻¹ = -ᴹ_}-------------------------------------------------------------------------- Bimodules------------------------------------------------------------------------record RawBisemimodule (R : Set r) (S : Set s) m ℓm : Set (r ⊔ s ⊔ suc (m ⊔ ℓm)) whereinfixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R Carrierᴹ_*ᵣ_ : Opᵣ S Carrierᴹ0ᴹ : CarrierᴹrawLeftSemimodule : RawLeftSemimodule R m ℓmrawLeftSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; 0ᴹ = 0ᴹ}rawRightSemimodule : RawRightSemimodule S m ℓmrawRightSemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ}open RawLeftSemimodule rawLeftSemimodule publicusing (+ᴹ-rawMagma; +ᴹ-rawMonoid; _≉ᴹ_)record RawBimodule (R : Set r) (S : Set s) m ℓm : Set (r ⊔ s ⊔ suc (m ⊔ ℓm)) whereinfix 8 -ᴹ_infixr 7 _*ₗ_infixl 7 _*ᵣ_infixl 6 _+ᴹ_infix 4 _≈ᴹ_fieldCarrierᴹ : Set m_≈ᴹ_ : Rel Carrierᴹ ℓm_+ᴹ_ : Op₂ Carrierᴹ_*ₗ_ : Opₗ R Carrierᴹ_*ᵣ_ : Opᵣ S Carrierᴹ0ᴹ : Carrierᴹ-ᴹ_ : Op₁ CarrierᴹrawLeftModule : RawLeftModule R m ℓmrawLeftModule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; 0ᴹ = 0ᴹ; -ᴹ_ = -ᴹ_}rawRightModule : RawRightModule S m ℓmrawRightModule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ; -ᴹ_ = -ᴹ_}rawBisemimodule : RawBisemimodule R S m ℓmrawBisemimodule = record{ _≈ᴹ_ = _≈ᴹ_; _+ᴹ_ = _+ᴹ_; _*ₗ_ = _*ₗ_; _*ᵣ_ = _*ᵣ_; 0ᴹ = 0ᴹ}open RawBisemimodule rawBisemimodule publicusing (+ᴹ-rawMagma; +ᴹ-rawMonoid; rawLeftSemimodule; rawRightSemimodule; _≉ᴹ_)open RawLeftModule rawLeftModule publicusing (+ᴹ-rawGroup)-------------------------------------------------------------------------- Modules over commutative structures------------------------------------------------------------------------RawSemimodule : ∀ (R : Set r) m ℓm → Set (r ⊔ suc (m ⊔ ℓm))RawSemimodule R = RawBisemimodule R Rmodule RawSemimodule {R : Set r} {m ℓm} (M : RawSemimodule R m ℓm) whereopen RawBisemimodule M publicrawBisemimodule : RawBisemimodule R R m ℓmrawBisemimodule = MRawModule : ∀ (R : Set r) m ℓm → Set (r ⊔ suc(m ⊔ ℓm))RawModule R = RawBimodule R Rmodule RawModule {R : Set r} {m ℓm} (M : RawModule R m ℓm) whereopen RawBimodule M publicrawBimodule : RawBimodule R R m ℓmrawBimodule = MrawSemimodule : RawSemimodule R m ℓmrawSemimodule = rawBisemimodule
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structures like semilattices and lattices-- (packed in records together with sets, operations, etc.), defined via-- meet/join operations and their properties---- For lattices defined via an order relation, see-- Relation.Binary.Lattice.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Lattice whereopen import Algebra.Lattice.Structures publicopen import Algebra.Lattice.Structures.Biased publicopen import Algebra.Lattice.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Some lattice-like structures defined by properties of _∧_ and _∨_-- (not packed up with sets, operations, etc.)---- For lattices defined via an order relation, see-- Relation.Binary.Lattice.-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra.Lattice`,-- unless you want to parameterise it via the equality relation.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Data.Product.Base using (proj₁; proj₂)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Lattice.Structures{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhereopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_-------------------------------------------------------------------------- Structures with 1 binary operationIsSemilattice = IsCommutativeBandmodule IsSemilattice {∙} (L : IsSemilattice ∙) whereopen IsCommutativeBand L publicusing (isBand; comm)open IsBand isBand public-- Used to bring names appropriate for a meet semilattice into scope.IsMeetSemilattice = IsSemilatticemodule IsMeetSemilattice {∧} (L : IsMeetSemilattice ∧) whereopen IsSemilattice L publicrenaming( ∙-cong to ∧-cong; ∙-congˡ to ∧-congˡ; ∙-congʳ to ∧-congʳ)-- Used to bring names appropriate for a join semilattice into scope.IsJoinSemilattice = IsSemilatticemodule IsJoinSemilattice {∨} (L : IsJoinSemilattice ∨) whereopen IsSemilattice L publicrenaming( ∙-cong to ∨-cong; ∙-congˡ to ∨-congˡ; ∙-congʳ to ∨-congʳ)-------------------------------------------------------------------------- Structures with 1 binary operation & 1 element-- A bounded semi-lattice is the same thing as an idempotent commutative-- monoid.IsBoundedSemilattice = IsIdempotentCommutativeMonoidmodule IsBoundedSemilattice {∙ ε} (L : IsBoundedSemilattice ∙ ε) whereopen IsIdempotentCommutativeMonoid L publicrenaming (isCommutativeBand to isSemilattice)-- Used to bring names appropriate for a bounded meet semilattice-- into scope.IsBoundedMeetSemilattice = IsBoundedSemilatticemodule IsBoundedMeetSemilattice {∧ ⊤} (L : IsBoundedMeetSemilattice ∧ ⊤)whereopen IsBoundedSemilattice L publicusing (identity; identityˡ; identityʳ)renaming (isSemilattice to isMeetSemilattice)open IsMeetSemilattice isMeetSemilattice public-- Used to bring names appropriate for a bounded join semilattice-- into scope.IsBoundedJoinSemilattice = IsBoundedSemilatticemodule IsBoundedJoinSemilattice {∨ ⊥} (L : IsBoundedJoinSemilattice ∨ ⊥)whereopen IsBoundedSemilattice L publicusing (identity; identityˡ; identityʳ)renaming (isSemilattice to isJoinSemilattice)open IsJoinSemilattice isJoinSemilattice public-------------------------------------------------------------------------- Structures with 2 binary operations-- Note that `IsLattice` is not defined in terms of `IsMeetSemilattice`-- and `IsJoinSemilattice` for two reasons:-- 1) it would result in a structure with two *different* proofs that-- the equality relation `≈` is an equivalence relation.-- 2) the idempotence laws of ∨ and ∧ can be derived from the-- absorption laws, which makes the corresponding "idem" fields-- redundant.---- It is possible to construct the `IsLattice` record from-- `IsMeetSemilattice` and `IsJoinSemilattice` via the `IsLattice₂`-- record found in `Algebra.Lattice.Structures.Biased`.---- The derived idempotence laws are stated and proved in-- `Algebra.Lattice.Properties.Lattice` along with the fact that every-- lattice consists of two semilattices.record IsLattice (∨ ∧ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisEquivalence : IsEquivalence _≈_∨-comm : Commutative ∨∨-assoc : Associative ∨∨-cong : Congruent₂ ∨∧-comm : Commutative ∧∧-assoc : Associative ∧∧-cong : Congruent₂ ∧absorptive : Absorptive ∨ ∧open IsEquivalence isEquivalence public∨-absorbs-∧ : ∨ Absorbs ∧∨-absorbs-∧ = proj₁ absorptive∧-absorbs-∨ : ∧ Absorbs ∨∧-absorbs-∨ = proj₂ absorptive∧-congˡ : LeftCongruent ∧∧-congˡ y≈z = ∧-cong refl y≈z∧-congʳ : RightCongruent ∧∧-congʳ y≈z = ∧-cong y≈z refl∨-congˡ : LeftCongruent ∨∨-congˡ y≈z = ∨-cong refl y≈z∨-congʳ : RightCongruent ∨∨-congʳ y≈z = ∨-cong y≈z reflrecord IsDistributiveLattice (∨ ∧ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisLattice : IsLattice ∨ ∧∨-distrib-∧ : ∨ DistributesOver ∧∧-distrib-∨ : ∧ DistributesOver ∨open IsLattice isLattice public∨-distribˡ-∧ : ∨ DistributesOverˡ ∧∨-distribˡ-∧ = proj₁ ∨-distrib-∧∨-distribʳ-∧ : ∨ DistributesOverʳ ∧∨-distribʳ-∧ = proj₂ ∨-distrib-∧∧-distribˡ-∨ : ∧ DistributesOverˡ ∨∧-distribˡ-∨ = proj₁ ∧-distrib-∨∧-distribʳ-∨ : ∧ DistributesOverʳ ∨∧-distribʳ-∨ = proj₂ ∧-distrib-∨-------------------------------------------------------------------------- Structures with 2 binary ops, 1 unary op and 2 elements.record IsBooleanAlgebra (∨ ∧ : Op₂ A) (¬ : Op₁ A) (⊤ ⊥ : A) : Set (a ⊔ ℓ)wherefieldisDistributiveLattice : IsDistributiveLattice ∨ ∧∨-complement : Inverse ⊤ ¬ ∨∧-complement : Inverse ⊥ ¬ ∧¬-cong : Congruent₁ ¬open IsDistributiveLattice isDistributiveLattice public∨-complementˡ : LeftInverse ⊤ ¬ ∨∨-complementˡ = proj₁ ∨-complement∨-complementʳ : RightInverse ⊤ ¬ ∨∨-complementʳ = proj₂ ∨-complement∧-complementˡ : LeftInverse ⊥ ¬ ∧∧-complementˡ = proj₁ ∧-complement∧-complementʳ : RightInverse ⊥ ¬ ∧∧-complementʳ = proj₂ ∧-complement
-------------------------------------------------------------------------- The Agda standard library---- Some biased records for lattice-like structures. Such records are-- often easier to construct, but are suboptimal to use more widely and-- should be converted to the standard record definitions immediately-- using the provided conversion functions.-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra.Lattice`,-- unless you want to parameterise it via the equality relation.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Consequences.Setoidopen import Data.Product.Base using (proj₁; proj₂)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)module Algebra.Lattice.Structures.Biased{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equality relationwhereopen import Algebra.Definitions _≈_open import Algebra.Lattice.Structures _≈_privatevariable∧ ∨ : Op₂ A¬ : Op₁ A⊤ ⊥ : A-------------------------------------------------------------------------- Lattice-- An alternative form of `IsLattice` defined in terms of-- `IsJoinSemilattice` and `IsMeetLattice`. This form may be desirable-- to use when constructing a lattice object as it requires fewer-- arguments, but is often a mistake to use as an argument as it-- contains two, *potentially different*, proofs that the equality-- relation _≈_ is an equivalence.record IsLattice₂ (∨ ∧ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisJoinSemilattice : IsJoinSemilattice ∨isMeetSemilattice : IsMeetSemilattice ∧absorptive : Absorptive ∨ ∧module ML = IsMeetSemilattice isMeetSemilatticemodule JL = IsJoinSemilattice isJoinSemilatticeisLattice₂ : IsLattice ∨ ∧isLattice₂ = record{ isEquivalence = ML.isEquivalence; ∨-comm = JL.comm; ∨-assoc = JL.assoc; ∨-cong = JL.∨-cong; ∧-comm = ML.comm; ∧-assoc = ML.assoc; ∧-cong = ML.∧-cong; absorptive = absorptive}open IsLattice₂ public using (isLattice₂)-------------------------------------------------------------------------- DistributiveLattice-- A version of distributive lattice that is biased towards the (r)ight-- distributivity law for (j)oin and (m)eet.record IsDistributiveLatticeʳʲᵐ (∨ ∧ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisLattice : IsLattice ∨ ∧∨-distribʳ-∧ : ∨ DistributesOverʳ ∧open IsLattice isLattice publicsetoid : Setoid a ℓsetoid = record { isEquivalence = isEquivalence }∨-distrib-∧ = comm∧distrʳ⇒distr setoid ∧-cong ∨-comm ∨-distribʳ-∧∧-distribˡ-∨ = distrib∧absorbs⇒distribˡ setoid ∧-cong ∧-assoc ∨-comm ∧-absorbs-∨ ∨-absorbs-∧ ∨-distrib-∧∧-distrib-∨ = comm∧distrˡ⇒distr setoid ∨-cong ∧-comm ∧-distribˡ-∨isDistributiveLatticeʳʲᵐ : IsDistributiveLattice ∨ ∧isDistributiveLatticeʳʲᵐ = record{ isLattice = isLattice; ∨-distrib-∧ = ∨-distrib-∧; ∧-distrib-∨ = ∧-distrib-∨}open IsDistributiveLatticeʳʲᵐ public using (isDistributiveLatticeʳʲᵐ)-------------------------------------------------------------------------- BooleanAlgebra-- A (r)ight biased version of a boolean algebra.record IsBooleanAlgebraʳ(∨ ∧ : Op₂ A) (¬ : Op₁ A) (⊤ ⊥ : A) : Set (a ⊔ ℓ) wherefieldisDistributiveLattice : IsDistributiveLattice ∨ ∧∨-complementʳ : RightInverse ⊤ ¬ ∨∧-complementʳ : RightInverse ⊥ ¬ ∧¬-cong : Congruent₁ ¬open IsDistributiveLattice isDistributiveLattice publicsetoid : Setoid a ℓsetoid = record { isEquivalence = isEquivalence }isBooleanAlgebraʳ : IsBooleanAlgebra ∨ ∧ ¬ ⊤ ⊥isBooleanAlgebraʳ = record{ isDistributiveLattice = isDistributiveLattice; ∨-complement = comm∧invʳ⇒inv setoid ∨-comm ∨-complementʳ; ∧-complement = comm∧invʳ⇒inv setoid ∧-comm ∧-complementʳ; ¬-cong = ¬-cong}open IsBooleanAlgebraʳ public using (isBooleanAlgebraʳ)
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties of semilattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundles using (Semilattice)open import Relation.Binary.Bundles using (Poset)import Relation.Binary.Lattice as Bimport Relation.Binary.Properties.Poset as PosetPropertiesmodule Algebra.Lattice.Properties.Semilattice{c ℓ} (L : Semilattice c ℓ) whereopen Semilattice L renaming (_∙_ to _∧_)open import Relation.Binary.Reasoning.Setoid setoidimport Relation.Binary.Construct.NaturalOrder.Left _≈_ _∧_as LeftNaturalOrder-------------------------------------------------------------------------- Every semilattice can be turned into a poset via the left natural-- order.poset : Poset c ℓ ℓposet = LeftNaturalOrder.poset isSemilatticeopen Poset poset using (_≤_; _≥_; isPartialOrder)open PosetProperties poset using (≥-isPartialOrder)-------------------------------------------------------------------------- Every algebraic semilattice can be turned into an order-theoretic one.∧-isOrderTheoreticMeetSemilattice : B.IsMeetSemilattice _≈_ _≤_ _∧_∧-isOrderTheoreticMeetSemilattice = record{ isPartialOrder = isPartialOrder; infimum = LeftNaturalOrder.infimum isSemilattice}∧-isOrderTheoreticJoinSemilattice : B.IsJoinSemilattice _≈_ _≥_ _∧_∧-isOrderTheoreticJoinSemilattice = record{ isPartialOrder = ≥-isPartialOrder; supremum = B.IsMeetSemilattice.infimum∧-isOrderTheoreticMeetSemilattice}∧-orderTheoreticMeetSemilattice : B.MeetSemilattice c ℓ ℓ∧-orderTheoreticMeetSemilattice = record{ isMeetSemilattice = ∧-isOrderTheoreticMeetSemilattice}∧-orderTheoreticJoinSemilattice : B.JoinSemilattice c ℓ ℓ∧-orderTheoreticJoinSemilattice = record{ isJoinSemilattice = ∧-isOrderTheoreticJoinSemilattice}
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties of lattices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundlesimport Algebra.Lattice.Properties.Semilattice as SemilatticePropertiesopen import Relation.Binary.Bundles using (Poset)import Relation.Binary.Lattice as Ropen import Function.Baseopen import Data.Product.Base using (_,_; swap)module Algebra.Lattice.Properties.Lattice{l₁ l₂} (L : Lattice l₁ l₂) whereopen Lattice Lopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_open import Algebra.Lattice.Structures _≈_open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- _∧_ is a semilattice∧-idem : Idempotent _∧_∧-idem x = beginx ∧ x ≈⟨ ∧-congˡ (∨-absorbs-∧ _ _) ⟨x ∧ (x ∨ x ∧ x) ≈⟨ ∧-absorbs-∨ _ _ ⟩x ∎∧-isMagma : IsMagma _∧_∧-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = ∧-cong}∧-isSemigroup : IsSemigroup _∧_∧-isSemigroup = record{ isMagma = ∧-isMagma; assoc = ∧-assoc}∧-isBand : IsBand _∧_∧-isBand = record{ isSemigroup = ∧-isSemigroup; idem = ∧-idem}∧-isSemilattice : IsSemilattice _∧_∧-isSemilattice = record{ isBand = ∧-isBand; comm = ∧-comm}∧-semilattice : Semilattice l₁ l₂∧-semilattice = record{ isSemilattice = ∧-isSemilattice}open SemilatticeProperties ∧-semilattice publicusing( ∧-isOrderTheoreticMeetSemilattice; ∧-isOrderTheoreticJoinSemilattice; ∧-orderTheoreticMeetSemilattice; ∧-orderTheoreticJoinSemilattice)-------------------------------------------------------------------------- _∨_ is a semilattice∨-idem : Idempotent _∨_∨-idem x = beginx ∨ x ≈⟨ ∨-congˡ (∧-idem _) ⟨x ∨ x ∧ x ≈⟨ ∨-absorbs-∧ _ _ ⟩x ∎∨-isMagma : IsMagma _∨_∨-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = ∨-cong}∨-isSemigroup : IsSemigroup _∨_∨-isSemigroup = record{ isMagma = ∨-isMagma; assoc = ∨-assoc}∨-isBand : IsBand _∨_∨-isBand = record{ isSemigroup = ∨-isSemigroup; idem = ∨-idem}∨-isSemilattice : IsSemilattice _∨_∨-isSemilattice = record{ isBand = ∨-isBand; comm = ∨-comm}∨-semilattice : Semilattice l₁ l₂∨-semilattice = record{ isSemilattice = ∨-isSemilattice}open SemilatticeProperties ∨-semilattice publicusing ()renaming( ∧-isOrderTheoreticMeetSemilattice to ∨-isOrderTheoreticMeetSemilattice; ∧-isOrderTheoreticJoinSemilattice to ∨-isOrderTheoreticJoinSemilattice; ∧-orderTheoreticMeetSemilattice to ∨-orderTheoreticMeetSemilattice; ∧-orderTheoreticJoinSemilattice to ∨-orderTheoreticJoinSemilattice)-------------------------------------------------------------------------- The dual construction is also a lattice.∧-∨-isLattice : IsLattice _∧_ _∨_∧-∨-isLattice = record{ isEquivalence = isEquivalence; ∨-comm = ∧-comm; ∨-assoc = ∧-assoc; ∨-cong = ∧-cong; ∧-comm = ∨-comm; ∧-assoc = ∨-assoc; ∧-cong = ∨-cong; absorptive = swap absorptive}∧-∨-lattice : Lattice _ _∧-∨-lattice = record{ isLattice = ∧-∨-isLattice}-------------------------------------------------------------------------- Every algebraic lattice can be turned into an order-theoretic one.open SemilatticeProperties ∧-semilattice public using (poset)open Poset poset using (_≤_; isPartialOrder)∨-∧-isOrderTheoreticLattice : R.IsLattice _≈_ _≤_ _∨_ _∧_∨-∧-isOrderTheoreticLattice = record{ isPartialOrder = isPartialOrder; supremum = supremum; infimum = infimum}whereopen R.MeetSemilattice ∧-orderTheoreticMeetSemilattice using (infimum)open R.JoinSemilattice ∨-orderTheoreticJoinSemilattice using (x≤x∨y; y≤x∨y; ∨-least)renaming (_≤_ to _≤′_)-- An alternative but equivalent interpretation of the order _≤_.sound : ∀ {x y} → x ≤′ y → x ≤ ysound {x} {y} y≈y∨x = sym $ beginx ∧ y ≈⟨ ∧-congˡ y≈y∨x ⟩x ∧ (y ∨ x) ≈⟨ ∧-congˡ (∨-comm y x) ⟩x ∧ (x ∨ y) ≈⟨ ∧-absorbs-∨ x y ⟩x ∎complete : ∀ {x y} → x ≤ y → x ≤′ ycomplete {x} {y} x≈x∧y = sym $ beginy ∨ x ≈⟨ ∨-congˡ x≈x∧y ⟩y ∨ (x ∧ y) ≈⟨ ∨-congˡ (∧-comm x y) ⟩y ∨ (y ∧ x) ≈⟨ ∨-absorbs-∧ y x ⟩y ∎supremum : R.Supremum _≤_ _∨_supremum x y =sound (x≤x∨y x y) ,sound (y≤x∨y x y) ,λ z x≤z y≤z → sound (∨-least (complete x≤z) (complete y≤z))∨-∧-orderTheoreticLattice : R.Lattice _ _ _∨-∧-orderTheoreticLattice = record{ isLattice = ∨-∧-isOrderTheoreticLattice}
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundlesimport Algebra.Lattice.Properties.Lattice as LatticePropertiesmodule Algebra.Lattice.Properties.DistributiveLattice{dl₁ dl₂} (DL : DistributiveLattice dl₁ dl₂)whereopen DistributiveLattice DLopen import Algebra.Definitions _≈_open import Algebra.Lattice.Structures _≈_open import Relation.Binary.Reasoning.Setoid setoid-------------------------------------------------------------------------- Export properties of latticesopen LatticeProperties lattice public-------------------------------------------------------------------------- The dual construction is also a distributive lattice.∧-∨-isDistributiveLattice : IsDistributiveLattice _∧_ _∨_∧-∨-isDistributiveLattice = record{ isLattice = ∧-∨-isLattice; ∨-distrib-∧ = ∧-distrib-∨; ∧-distrib-∨ = ∨-distrib-∧}∧-∨-distributiveLattice : DistributiveLattice _ _∧-∨-distributiveLattice = record{ isDistributiveLattice = ∧-∨-isDistributiveLattice}
-------------------------------------------------------------------------- The Agda standard library---- Some derivable properties of Boolean algebras------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundlesmodule Algebra.Lattice.Properties.BooleanAlgebra{b₁ b₂} (B : BooleanAlgebra b₁ b₂)whereopen BooleanAlgebra Bimport Algebra.Lattice.Properties.DistributiveLattice as DistribLatticePropertiesopen import Algebra.Coreopen import Algebra.Structures _≈_open import Algebra.Definitions _≈_open import Algebra.Consequences.Setoid setoidopen import Algebra.Bundlesopen import Algebra.Lattice.Structures _≈_open import Relation.Binary.Reasoning.Setoid setoidopen import Function.Base using (id; _$_; _⟨_⟩_)open import Function.Bundles using (_⇔_; module Equivalence)open import Data.Product.Base using (_,_)-------------------------------------------------------------------------- Export properties from distributive latticesopen DistribLatticeProperties distributiveLattice public-------------------------------------------------------------------------- The dual construction is also a boolean algebra∧-∨-isBooleanAlgebra : IsBooleanAlgebra _∧_ _∨_ ¬_ ⊥ ⊤∧-∨-isBooleanAlgebra = record{ isDistributiveLattice = ∧-∨-isDistributiveLattice; ∨-complement = ∧-complement; ∧-complement = ∨-complement; ¬-cong = ¬-cong}∧-∨-booleanAlgebra : BooleanAlgebra _ _∧-∨-booleanAlgebra = record{ isBooleanAlgebra = ∧-∨-isBooleanAlgebra}-------------------------------------------------------------------------- (∨, ∧, ⊥, ⊤) and (∧, ∨, ⊤, ⊥) are commutative semirings∧-identityʳ : RightIdentity ⊤ _∧_∧-identityʳ x = beginx ∧ ⊤ ≈⟨ ∧-congˡ (sym (∨-complementʳ _)) ⟩x ∧ (x ∨ ¬ x) ≈⟨ ∧-absorbs-∨ _ _ ⟩x ∎∧-identityˡ : LeftIdentity ⊤ _∧_∧-identityˡ = comm∧idʳ⇒idˡ ∧-comm ∧-identityʳ∧-identity : Identity ⊤ _∧_∧-identity = ∧-identityˡ , ∧-identityʳ∨-identityʳ : RightIdentity ⊥ _∨_∨-identityʳ x = beginx ∨ ⊥ ≈⟨ ∨-congˡ $ sym (∧-complementʳ _) ⟩x ∨ x ∧ ¬ x ≈⟨ ∨-absorbs-∧ _ _ ⟩x ∎∨-identityˡ : LeftIdentity ⊥ _∨_∨-identityˡ = comm∧idʳ⇒idˡ ∨-comm ∨-identityʳ∨-identity : Identity ⊥ _∨_∨-identity = ∨-identityˡ , ∨-identityʳ∧-zeroʳ : RightZero ⊥ _∧_∧-zeroʳ x = beginx ∧ ⊥ ≈⟨ ∧-congˡ (∧-complementʳ x) ⟨x ∧ x ∧ ¬ x ≈⟨ ∧-assoc x x (¬ x) ⟨(x ∧ x) ∧ ¬ x ≈⟨ ∧-congʳ (∧-idem x) ⟩x ∧ ¬ x ≈⟨ ∧-complementʳ x ⟩⊥ ∎∧-zeroˡ : LeftZero ⊥ _∧_∧-zeroˡ = comm∧zeʳ⇒zeˡ ∧-comm ∧-zeroʳ∧-zero : Zero ⊥ _∧_∧-zero = ∧-zeroˡ , ∧-zeroʳ∨-zeroʳ : ∀ x → x ∨ ⊤ ≈ ⊤∨-zeroʳ x = beginx ∨ ⊤ ≈⟨ ∨-congˡ (∨-complementʳ x) ⟨x ∨ x ∨ ¬ x ≈⟨ ∨-assoc x x (¬ x) ⟨(x ∨ x) ∨ ¬ x ≈⟨ ∨-congʳ (∨-idem x) ⟩x ∨ ¬ x ≈⟨ ∨-complementʳ x ⟩⊤ ∎∨-zeroˡ : LeftZero ⊤ _∨_∨-zeroˡ = comm∧zeʳ⇒zeˡ ∨-comm ∨-zeroʳ∨-zero : Zero ⊤ _∨_∨-zero = ∨-zeroˡ , ∨-zeroʳ∨-⊥-isMonoid : IsMonoid _∨_ ⊥∨-⊥-isMonoid = record{ isSemigroup = ∨-isSemigroup; identity = ∨-identity}∧-⊤-isMonoid : IsMonoid _∧_ ⊤∧-⊤-isMonoid = record{ isSemigroup = ∧-isSemigroup; identity = ∧-identity}∨-⊥-isCommutativeMonoid : IsCommutativeMonoid _∨_ ⊥∨-⊥-isCommutativeMonoid = record{ isMonoid = ∨-⊥-isMonoid; comm = ∨-comm}∧-⊤-isCommutativeMonoid : IsCommutativeMonoid _∧_ ⊤∧-⊤-isCommutativeMonoid = record{ isMonoid = ∧-⊤-isMonoid; comm = ∧-comm}∨-∧-isSemiring : IsSemiring _∨_ _∧_ ⊥ ⊤∨-∧-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∨-⊥-isCommutativeMonoid; *-cong = ∧-cong; *-assoc = ∧-assoc; *-identity = ∧-identity; distrib = ∧-distrib-∨}; zero = ∧-zero}∧-∨-isSemiring : IsSemiring _∧_ _∨_ ⊤ ⊥∧-∨-isSemiring = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = ∧-⊤-isCommutativeMonoid; *-cong = ∨-cong; *-assoc = ∨-assoc; *-identity = ∨-identity; distrib = ∨-distrib-∧}; zero = ∨-zero}∨-∧-isCommutativeSemiring : IsCommutativeSemiring _∨_ _∧_ ⊥ ⊤∨-∧-isCommutativeSemiring = record{ isSemiring = ∨-∧-isSemiring; *-comm = ∧-comm}∧-∨-isCommutativeSemiring : IsCommutativeSemiring _∧_ _∨_ ⊤ ⊥∧-∨-isCommutativeSemiring = record{ isSemiring = ∧-∨-isSemiring; *-comm = ∨-comm}∨-∧-commutativeSemiring : CommutativeSemiring _ _∨-∧-commutativeSemiring = record{ isCommutativeSemiring = ∨-∧-isCommutativeSemiring}∧-∨-commutativeSemiring : CommutativeSemiring _ _∧-∨-commutativeSemiring = record{ isCommutativeSemiring = ∧-∨-isCommutativeSemiring}-------------------------------------------------------------------------- Some other properties-- I took the statement of this lemma (called Uniqueness of-- Complements) from some course notes, "Boolean Algebra", written-- by Gert Smolka.privatelemma : ∀ x y → x ∧ y ≈ ⊥ → x ∨ y ≈ ⊤ → ¬ x ≈ ylemma x y x∧y=⊥ x∨y=⊤ = begin¬ x ≈⟨ ∧-identityʳ _ ⟨¬ x ∧ ⊤ ≈⟨ ∧-congˡ x∨y=⊤ ⟨¬ x ∧ (x ∨ y) ≈⟨ ∧-distribˡ-∨ _ _ _ ⟩¬ x ∧ x ∨ ¬ x ∧ y ≈⟨ ∨-congʳ $ ∧-complementˡ _ ⟩⊥ ∨ ¬ x ∧ y ≈⟨ ∨-congʳ x∧y=⊥ ⟨x ∧ y ∨ ¬ x ∧ y ≈⟨ ∧-distribʳ-∨ _ _ _ ⟨(x ∨ ¬ x) ∧ y ≈⟨ ∧-congʳ $ ∨-complementʳ _ ⟩⊤ ∧ y ≈⟨ ∧-identityˡ _ ⟩y ∎⊥≉⊤ : ¬ ⊥ ≈ ⊤⊥≉⊤ = lemma ⊥ ⊤ (∧-identityʳ _) (∨-zeroʳ _)⊤≉⊥ : ¬ ⊤ ≈ ⊥⊤≉⊥ = lemma ⊤ ⊥ (∧-zeroʳ _) (∨-identityʳ _)¬-involutive : Involutive ¬_¬-involutive x = lemma (¬ x) x (∧-complementˡ _) (∨-complementˡ _)deMorgan₁ : ∀ x y → ¬ (x ∧ y) ≈ ¬ x ∨ ¬ ydeMorgan₁ x y = lemma (x ∧ y) (¬ x ∨ ¬ y) lem₁ lem₂wherelem₁ = begin(x ∧ y) ∧ (¬ x ∨ ¬ y) ≈⟨ ∧-distribˡ-∨ _ _ _ ⟩(x ∧ y) ∧ ¬ x ∨ (x ∧ y) ∧ ¬ y ≈⟨ ∨-congʳ $ ∧-congʳ $ ∧-comm _ _ ⟩(y ∧ x) ∧ ¬ x ∨ (x ∧ y) ∧ ¬ y ≈⟨ ∧-assoc _ _ _ ⟨ ∨-cong ⟩ ∧-assoc _ _ _ ⟩y ∧ (x ∧ ¬ x) ∨ x ∧ (y ∧ ¬ y) ≈⟨ (∧-congˡ $ ∧-complementʳ _) ⟨ ∨-cong ⟩(∧-congˡ $ ∧-complementʳ _) ⟩(y ∧ ⊥) ∨ (x ∧ ⊥) ≈⟨ ∧-zeroʳ _ ⟨ ∨-cong ⟩ ∧-zeroʳ _ ⟩⊥ ∨ ⊥ ≈⟨ ∨-identityʳ _ ⟩⊥ ∎lem₃ = begin(x ∧ y) ∨ ¬ x ≈⟨ ∨-distribʳ-∧ _ _ _ ⟩(x ∨ ¬ x) ∧ (y ∨ ¬ x) ≈⟨ ∧-congʳ $ ∨-complementʳ _ ⟩⊤ ∧ (y ∨ ¬ x) ≈⟨ ∧-identityˡ _ ⟩y ∨ ¬ x ≈⟨ ∨-comm _ _ ⟩¬ x ∨ y ∎lem₂ = begin(x ∧ y) ∨ (¬ x ∨ ¬ y) ≈⟨ ∨-assoc _ _ _ ⟨((x ∧ y) ∨ ¬ x) ∨ ¬ y ≈⟨ ∨-congʳ lem₃ ⟩(¬ x ∨ y) ∨ ¬ y ≈⟨ ∨-assoc _ _ _ ⟩¬ x ∨ (y ∨ ¬ y) ≈⟨ ∨-congˡ $ ∨-complementʳ _ ⟩¬ x ∨ ⊤ ≈⟨ ∨-zeroʳ _ ⟩⊤ ∎deMorgan₂ : ∀ x y → ¬ (x ∨ y) ≈ ¬ x ∧ ¬ ydeMorgan₂ x y = begin¬ (x ∨ y) ≈⟨ ¬-cong $ ((¬-involutive _) ⟨ ∨-cong ⟩ (¬-involutive _)) ⟨¬ (¬ ¬ x ∨ ¬ ¬ y) ≈⟨ ¬-cong $ deMorgan₁ _ _ ⟨¬ ¬ (¬ x ∧ ¬ y) ≈⟨ ¬-involutive _ ⟩¬ x ∧ ¬ y ∎-------------------------------------------------------------------------- (⊕, ∧, id, ⊥, ⊤) is a commutative ring-- This construction is parameterised over the definition of xor.module XorRing(xor : Op₂ Carrier)(⊕-def : ∀ x y → xor x y ≈ (x ∨ y) ∧ ¬ (x ∧ y))whereprivateinfixl 6 _⊕__⊕_ : Op₂ Carrier_⊕_ = xorhelper : ∀ {x y u v} → x ≈ y → u ≈ v → x ∧ ¬ u ≈ y ∧ ¬ vhelper x≈y u≈v = x≈y ⟨ ∧-cong ⟩ ¬-cong u≈v⊕-cong : Congruent₂ _⊕_⊕-cong {x} {y} {u} {v} x≈y u≈v = beginx ⊕ u ≈⟨ ⊕-def _ _ ⟩(x ∨ u) ∧ ¬ (x ∧ u) ≈⟨ helper (x≈y ⟨ ∨-cong ⟩ u≈v)(x≈y ⟨ ∧-cong ⟩ u≈v) ⟩(y ∨ v) ∧ ¬ (y ∧ v) ≈⟨ ⊕-def _ _ ⟨y ⊕ v ∎⊕-comm : Commutative _⊕_⊕-comm x y = beginx ⊕ y ≈⟨ ⊕-def _ _ ⟩(x ∨ y) ∧ ¬ (x ∧ y) ≈⟨ helper (∨-comm _ _) (∧-comm _ _) ⟩(y ∨ x) ∧ ¬ (y ∧ x) ≈⟨ ⊕-def _ _ ⟨y ⊕ x ∎¬-distribˡ-⊕ : ∀ x y → ¬ (x ⊕ y) ≈ ¬ x ⊕ y¬-distribˡ-⊕ x y = begin¬ (x ⊕ y) ≈⟨ ¬-cong $ ⊕-def _ _ ⟩¬ ((x ∨ y) ∧ (¬ (x ∧ y))) ≈⟨ ¬-cong (∧-distribʳ-∨ _ _ _) ⟩¬ ((x ∧ ¬ (x ∧ y)) ∨ (y ∧ ¬ (x ∧ y))) ≈⟨ ¬-cong $ ∨-congˡ $ ∧-congˡ $ ¬-cong (∧-comm _ _) ⟩¬ ((x ∧ ¬ (x ∧ y)) ∨ (y ∧ ¬ (y ∧ x))) ≈⟨ ¬-cong $ lem _ _ ⟨ ∨-cong ⟩ lem _ _ ⟩¬ ((x ∧ ¬ y) ∨ (y ∧ ¬ x)) ≈⟨ deMorgan₂ _ _ ⟩¬ (x ∧ ¬ y) ∧ ¬ (y ∧ ¬ x) ≈⟨ ∧-congʳ $ deMorgan₁ _ _ ⟩(¬ x ∨ (¬ ¬ y)) ∧ ¬ (y ∧ ¬ x) ≈⟨ helper (∨-congˡ $ ¬-involutive _) (∧-comm _ _) ⟩(¬ x ∨ y) ∧ ¬ (¬ x ∧ y) ≈⟨ ⊕-def _ _ ⟨¬ x ⊕ y ∎wherelem : ∀ x y → x ∧ ¬ (x ∧ y) ≈ x ∧ ¬ ylem x y = beginx ∧ ¬ (x ∧ y) ≈⟨ ∧-congˡ $ deMorgan₁ _ _ ⟩x ∧ (¬ x ∨ ¬ y) ≈⟨ ∧-distribˡ-∨ _ _ _ ⟩(x ∧ ¬ x) ∨ (x ∧ ¬ y) ≈⟨ ∨-congʳ $ ∧-complementʳ _ ⟩⊥ ∨ (x ∧ ¬ y) ≈⟨ ∨-identityˡ _ ⟩x ∧ ¬ y ∎¬-distribʳ-⊕ : ∀ x y → ¬ (x ⊕ y) ≈ x ⊕ ¬ y¬-distribʳ-⊕ x y = begin¬ (x ⊕ y) ≈⟨ ¬-cong $ ⊕-comm _ _ ⟩¬ (y ⊕ x) ≈⟨ ¬-distribˡ-⊕ _ _ ⟩¬ y ⊕ x ≈⟨ ⊕-comm _ _ ⟩x ⊕ ¬ y ∎⊕-annihilates-¬ : ∀ x y → x ⊕ y ≈ ¬ x ⊕ ¬ y⊕-annihilates-¬ x y = beginx ⊕ y ≈⟨ ¬-involutive _ ⟨¬ ¬ (x ⊕ y) ≈⟨ ¬-cong $ ¬-distribˡ-⊕ _ _ ⟩¬ (¬ x ⊕ y) ≈⟨ ¬-distribʳ-⊕ _ _ ⟩¬ x ⊕ ¬ y ∎⊕-identityˡ : LeftIdentity ⊥ _⊕_⊕-identityˡ x = begin⊥ ⊕ x ≈⟨ ⊕-def _ _ ⟩(⊥ ∨ x) ∧ ¬ (⊥ ∧ x) ≈⟨ helper (∨-identityˡ _) (∧-zeroˡ _) ⟩x ∧ ¬ ⊥ ≈⟨ ∧-congˡ ⊥≉⊤ ⟩x ∧ ⊤ ≈⟨ ∧-identityʳ _ ⟩x ∎⊕-identityʳ : RightIdentity ⊥ _⊕_⊕-identityʳ _ = ⊕-comm _ _ ⟨ trans ⟩ ⊕-identityˡ _⊕-identity : Identity ⊥ _⊕_⊕-identity = ⊕-identityˡ , ⊕-identityʳ⊕-inverseˡ : LeftInverse ⊥ id _⊕_⊕-inverseˡ x = beginx ⊕ x ≈⟨ ⊕-def _ _ ⟩(x ∨ x) ∧ ¬ (x ∧ x) ≈⟨ helper (∨-idem _) (∧-idem _) ⟩x ∧ ¬ x ≈⟨ ∧-complementʳ _ ⟩⊥ ∎⊕-inverseʳ : RightInverse ⊥ id _⊕_⊕-inverseʳ _ = ⊕-comm _ _ ⟨ trans ⟩ ⊕-inverseˡ _⊕-inverse : Inverse ⊥ id _⊕_⊕-inverse = ⊕-inverseˡ , ⊕-inverseʳ∧-distribˡ-⊕ : _∧_ DistributesOverˡ _⊕_∧-distribˡ-⊕ x y z = beginx ∧ (y ⊕ z) ≈⟨ ∧-congˡ $ ⊕-def _ _ ⟩x ∧ ((y ∨ z) ∧ ¬ (y ∧ z)) ≈⟨ ∧-assoc _ _ _ ⟨(x ∧ (y ∨ z)) ∧ ¬ (y ∧ z) ≈⟨ ∧-congˡ $ deMorgan₁ _ _ ⟩(x ∧ (y ∨ z)) ∧(¬ y ∨ ¬ z) ≈⟨ ∨-identityˡ _ ⟨⊥ ∨((x ∧ (y ∨ z)) ∧(¬ y ∨ ¬ z)) ≈⟨ ∨-congʳ lem₃ ⟩((x ∧ (y ∨ z)) ∧ ¬ x) ∨((x ∧ (y ∨ z)) ∧(¬ y ∨ ¬ z)) ≈⟨ ∧-distribˡ-∨ _ _ _ ⟨(x ∧ (y ∨ z)) ∧(¬ x ∨ (¬ y ∨ ¬ z)) ≈⟨ ∧-congˡ $ ∨-congˡ (deMorgan₁ _ _) ⟨(x ∧ (y ∨ z)) ∧(¬ x ∨ ¬ (y ∧ z)) ≈⟨ ∧-congˡ (deMorgan₁ _ _) ⟨(x ∧ (y ∨ z)) ∧¬ (x ∧ (y ∧ z)) ≈⟨ helper refl lem₁ ⟩(x ∧ (y ∨ z)) ∧¬ ((x ∧ y) ∧ (x ∧ z)) ≈⟨ ∧-congʳ $ ∧-distribˡ-∨ _ _ _ ⟩((x ∧ y) ∨ (x ∧ z)) ∧¬ ((x ∧ y) ∧ (x ∧ z)) ≈⟨ ⊕-def _ _ ⟨(x ∧ y) ⊕ (x ∧ z) ∎wherelem₂ = beginx ∧ (y ∧ z) ≈⟨ ∧-assoc _ _ _ ⟨(x ∧ y) ∧ z ≈⟨ ∧-congʳ $ ∧-comm _ _ ⟩(y ∧ x) ∧ z ≈⟨ ∧-assoc _ _ _ ⟩y ∧ (x ∧ z) ∎lem₁ = beginx ∧ (y ∧ z) ≈⟨ ∧-congʳ (∧-idem _) ⟨(x ∧ x) ∧ (y ∧ z) ≈⟨ ∧-assoc _ _ _ ⟩x ∧ (x ∧ (y ∧ z)) ≈⟨ ∧-congˡ lem₂ ⟩x ∧ (y ∧ (x ∧ z)) ≈⟨ ∧-assoc _ _ _ ⟨(x ∧ y) ∧ (x ∧ z) ∎lem₃ = begin⊥ ≈⟨ ∧-zeroʳ _ ⟨(y ∨ z) ∧ ⊥ ≈⟨ ∧-congˡ (∧-complementʳ _) ⟨(y ∨ z) ∧ (x ∧ ¬ x) ≈⟨ ∧-assoc _ _ _ ⟨((y ∨ z) ∧ x) ∧ ¬ x ≈⟨ ∧-congʳ (∧-comm _ _) ⟩(x ∧ (y ∨ z)) ∧ ¬ x ∎∧-distribʳ-⊕ : _∧_ DistributesOverʳ _⊕_∧-distribʳ-⊕ = comm∧distrˡ⇒distrʳ ⊕-cong ∧-comm ∧-distribˡ-⊕∧-distrib-⊕ : _∧_ DistributesOver _⊕_∧-distrib-⊕ = ∧-distribˡ-⊕ , ∧-distribʳ-⊕privatelemma₂ : ∀ x y u v →(x ∧ y) ∨ (u ∧ v) ≈((x ∨ u) ∧ (y ∨ u)) ∧((x ∨ v) ∧ (y ∨ v))lemma₂ x y u v = begin(x ∧ y) ∨ (u ∧ v) ≈⟨ ∨-distribˡ-∧ _ _ _ ⟩((x ∧ y) ∨ u) ∧ ((x ∧ y) ∨ v) ≈⟨ ∨-distribʳ-∧ _ _ _⟨ ∧-cong ⟩∨-distribʳ-∧ _ _ _ ⟩((x ∨ u) ∧ (y ∨ u)) ∧((x ∨ v) ∧ (y ∨ v)) ∎⊕-assoc : Associative _⊕_⊕-assoc x y z = sym $ beginx ⊕ (y ⊕ z) ≈⟨ ⊕-cong refl (⊕-def _ _) ⟩x ⊕ ((y ∨ z) ∧ ¬ (y ∧ z)) ≈⟨ ⊕-def _ _ ⟩(x ∨ ((y ∨ z) ∧ ¬ (y ∧ z))) ∧¬ (x ∧ ((y ∨ z) ∧ ¬ (y ∧ z))) ≈⟨ ∧-cong lem₃ lem₄ ⟩(((x ∨ y) ∨ z) ∧ ((x ∨ ¬ y) ∨ ¬ z)) ∧(((¬ x ∨ ¬ y) ∨ z) ∧ ((¬ x ∨ y) ∨ ¬ z)) ≈⟨ ∧-assoc _ _ _ ⟩((x ∨ y) ∨ z) ∧(((x ∨ ¬ y) ∨ ¬ z) ∧(((¬ x ∨ ¬ y) ∨ z) ∧ ((¬ x ∨ y) ∨ ¬ z))) ≈⟨ ∧-congˡ lem₅ ⟩((x ∨ y) ∨ z) ∧(((¬ x ∨ ¬ y) ∨ z) ∧(((x ∨ ¬ y) ∨ ¬ z) ∧ ((¬ x ∨ y) ∨ ¬ z))) ≈⟨ ∧-assoc _ _ _ ⟨(((x ∨ y) ∨ z) ∧ ((¬ x ∨ ¬ y) ∨ z)) ∧(((x ∨ ¬ y) ∨ ¬ z) ∧ ((¬ x ∨ y) ∨ ¬ z)) ≈⟨ ∧-cong lem₁ lem₂ ⟩(((x ∨ y) ∧ ¬ (x ∧ y)) ∨ z) ∧¬ (((x ∨ y) ∧ ¬ (x ∧ y)) ∧ z) ≈⟨ ⊕-def _ _ ⟨((x ∨ y) ∧ ¬ (x ∧ y)) ⊕ z ≈⟨ ⊕-cong (⊕-def _ _) refl ⟨(x ⊕ y) ⊕ z ∎wherelem₁ = begin((x ∨ y) ∨ z) ∧ ((¬ x ∨ ¬ y) ∨ z) ≈⟨ ∨-distribʳ-∧ _ _ _ ⟨((x ∨ y) ∧ (¬ x ∨ ¬ y)) ∨ z ≈⟨ ∨-congʳ $ ∧-congˡ (deMorgan₁ _ _) ⟨((x ∨ y) ∧ ¬ (x ∧ y)) ∨ z ∎lem₂′ = begin(x ∨ ¬ y) ∧ (¬ x ∨ y) ≈⟨ ∧-cong (∧-identityˡ _) (∧-identityʳ _) ⟨(⊤ ∧ (x ∨ ¬ y)) ∧ ((¬ x ∨ y) ∧ ⊤) ≈⟨ ∧-cong(∧-cong (∨-complementˡ _) (∨-comm _ _))(∧-congˡ $ ∨-complementˡ _) ⟨((¬ x ∨ x) ∧ (¬ y ∨ x)) ∧((¬ x ∨ y) ∧ (¬ y ∨ y)) ≈⟨ lemma₂ _ _ _ _ ⟨(¬ x ∧ ¬ y) ∨ (x ∧ y) ≈⟨ ∨-cong (deMorgan₂ _ _) (¬-involutive _) ⟨¬ (x ∨ y) ∨ ¬ ¬ (x ∧ y) ≈⟨ deMorgan₁ _ _ ⟨¬ ((x ∨ y) ∧ ¬ (x ∧ y)) ∎lem₂ = begin((x ∨ ¬ y) ∨ ¬ z) ∧ ((¬ x ∨ y) ∨ ¬ z) ≈⟨ ∨-distribʳ-∧ _ _ _ ⟨((x ∨ ¬ y) ∧ (¬ x ∨ y)) ∨ ¬ z ≈⟨ ∨-congʳ lem₂′ ⟩¬ ((x ∨ y) ∧ ¬ (x ∧ y)) ∨ ¬ z ≈⟨ deMorgan₁ _ _ ⟨¬ (((x ∨ y) ∧ ¬ (x ∧ y)) ∧ z) ∎lem₃ = beginx ∨ ((y ∨ z) ∧ ¬ (y ∧ z)) ≈⟨ ∨-congˡ $ ∧-congˡ $ deMorgan₁ _ _ ⟩x ∨ ((y ∨ z) ∧ (¬ y ∨ ¬ z)) ≈⟨ ∨-distribˡ-∧ _ _ _ ⟩(x ∨ (y ∨ z)) ∧ (x ∨ (¬ y ∨ ¬ z)) ≈⟨ ∨-assoc _ _ _ ⟨ ∧-cong ⟩ ∨-assoc _ _ _ ⟨((x ∨ y) ∨ z) ∧ ((x ∨ ¬ y) ∨ ¬ z) ∎lem₄′ = begin¬ ((y ∨ z) ∧ ¬ (y ∧ z)) ≈⟨ deMorgan₁ _ _ ⟩¬ (y ∨ z) ∨ ¬ ¬ (y ∧ z) ≈⟨ deMorgan₂ _ _ ⟨ ∨-cong ⟩ ¬-involutive _ ⟩(¬ y ∧ ¬ z) ∨ (y ∧ z) ≈⟨ lemma₂ _ _ _ _ ⟩((¬ y ∨ y) ∧ (¬ z ∨ y)) ∧((¬ y ∨ z) ∧ (¬ z ∨ z)) ≈⟨ (∨-complementˡ _ ⟨ ∧-cong ⟩ ∨-comm _ _)⟨ ∧-cong ⟩(∧-congˡ $ ∨-complementˡ _) ⟩(⊤ ∧ (y ∨ ¬ z)) ∧((¬ y ∨ z) ∧ ⊤) ≈⟨ ∧-identityˡ _ ⟨ ∧-cong ⟩ ∧-identityʳ _ ⟩(y ∨ ¬ z) ∧ (¬ y ∨ z) ∎lem₄ = begin¬ (x ∧ ((y ∨ z) ∧ ¬ (y ∧ z))) ≈⟨ deMorgan₁ _ _ ⟩¬ x ∨ ¬ ((y ∨ z) ∧ ¬ (y ∧ z)) ≈⟨ ∨-congˡ lem₄′ ⟩¬ x ∨ ((y ∨ ¬ z) ∧ (¬ y ∨ z)) ≈⟨ ∨-distribˡ-∧ _ _ _ ⟩(¬ x ∨ (y ∨ ¬ z)) ∧(¬ x ∨ (¬ y ∨ z)) ≈⟨ ∨-assoc _ _ _ ⟨ ∧-cong ⟩ ∨-assoc _ _ _ ⟨((¬ x ∨ y) ∨ ¬ z) ∧((¬ x ∨ ¬ y) ∨ z) ≈⟨ ∧-comm _ _ ⟩((¬ x ∨ ¬ y) ∨ z) ∧((¬ x ∨ y) ∨ ¬ z) ∎lem₅ = begin((x ∨ ¬ y) ∨ ¬ z) ∧(((¬ x ∨ ¬ y) ∨ z) ∧ ((¬ x ∨ y) ∨ ¬ z)) ≈⟨ ∧-assoc _ _ _ ⟨(((x ∨ ¬ y) ∨ ¬ z) ∧ ((¬ x ∨ ¬ y) ∨ z)) ∧((¬ x ∨ y) ∨ ¬ z) ≈⟨ ∧-congʳ $ ∧-comm _ _ ⟩(((¬ x ∨ ¬ y) ∨ z) ∧ ((x ∨ ¬ y) ∨ ¬ z)) ∧((¬ x ∨ y) ∨ ¬ z) ≈⟨ ∧-assoc _ _ _ ⟩((¬ x ∨ ¬ y) ∨ z) ∧(((x ∨ ¬ y) ∨ ¬ z) ∧ ((¬ x ∨ y) ∨ ¬ z)) ∎⊕-isMagma : IsMagma _⊕_⊕-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = ⊕-cong}⊕-isSemigroup : IsSemigroup _⊕_⊕-isSemigroup = record{ isMagma = ⊕-isMagma; assoc = ⊕-assoc}⊕-⊥-isMonoid : IsMonoid _⊕_ ⊥⊕-⊥-isMonoid = record{ isSemigroup = ⊕-isSemigroup; identity = ⊕-identity}⊕-⊥-isGroup : IsGroup _⊕_ ⊥ id⊕-⊥-isGroup = record{ isMonoid = ⊕-⊥-isMonoid; inverse = ⊕-inverse; ⁻¹-cong = id}⊕-⊥-isAbelianGroup : IsAbelianGroup _⊕_ ⊥ id⊕-⊥-isAbelianGroup = record{ isGroup = ⊕-⊥-isGroup; comm = ⊕-comm}⊕-∧-isRing : IsRing _⊕_ _∧_ id ⊥ ⊤⊕-∧-isRing = record{ +-isAbelianGroup = ⊕-⊥-isAbelianGroup; *-cong = ∧-cong; *-assoc = ∧-assoc; *-identity = ∧-identity; distrib = ∧-distrib-⊕}⊕-∧-isCommutativeRing : IsCommutativeRing _⊕_ _∧_ id ⊥ ⊤⊕-∧-isCommutativeRing = record{ isRing = ⊕-∧-isRing; *-comm = ∧-comm}⊕-∧-commutativeRing : CommutativeRing _ _⊕-∧-commutativeRing = record{ isCommutativeRing = ⊕-∧-isCommutativeRing}infixl 6 _⊕__⊕_ : Op₂ Carrierx ⊕ y = (x ∨ y) ∧ ¬ (x ∧ y)module DefaultXorRing = XorRing _⊕_ (λ _ _ → refl)
-------------------------------------------------------------------------- The Agda standard library---- Boolean algebra expressions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice using (BooleanAlgebra; isBooleanAlgebraʳ;isDistributiveLatticeʳʲᵐ)module Algebra.Lattice.Properties.BooleanAlgebra.Expression{b} (B : BooleanAlgebra b b)whereopen BooleanAlgebra Bopen import Data.Fin.Base using (Fin)open import Data.Nat.Base using (ℕ)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Data.Vec.Base as Vec using (Vec)import Data.Vec.Effectful as Vecimport Function.Identity.Effectful as Identityopen import Data.Vec.Properties using (lookup-map)open import Data.Vec.Relation.Binary.Pointwise.Extensional as PWusing (Pointwise; ext)open import Effect.Applicative as Applicativeopen import Function.Base using (_∘_; _$_; flip)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≗_)open import Relation.Binary.PropositionalEquality.Propertiesusing (module ≡-Reasoning)import Relation.Binary.Reflection as Reflection-- Expressions made up of variables and the operations of a boolean-- algebra.infixr 7 _and_infixr 6 _or_data Expr n : Set b wherevar : (x : Fin n) → Expr n_or_ _and_ : (e₁ e₂ : Expr n) → Expr nnot : (e : Expr n) → Expr ntop bot : Expr n-- The semantics of an expression, parametrised by an applicative-- functor.module Semantics{F : Set b → Set b}(A : RawApplicative F)whereopen RawApplicative A⟦_⟧ : ∀ {n} → Expr n → Vec (F Carrier) n → F Carrier⟦ var x ⟧ ρ = Vec.lookup ρ x⟦ e₁ or e₂ ⟧ ρ = _∨_ <$> ⟦ e₁ ⟧ ρ ⊛ ⟦ e₂ ⟧ ρ⟦ e₁ and e₂ ⟧ ρ = _∧_ <$> ⟦ e₁ ⟧ ρ ⊛ ⟦ e₂ ⟧ ρ⟦ not e ⟧ ρ = ¬_ <$> ⟦ e ⟧ ρ⟦ top ⟧ ρ = pure ⊤⟦ bot ⟧ ρ = pure ⊥-- flip Semantics.⟦_⟧ e is natural.module Naturality{F₁ F₂ : Set b → Set b}{A₁ : RawApplicative F₁}{A₂ : RawApplicative F₂}(f : Applicative.Morphism A₁ A₂)whereopen ≡-Reasoningopen Applicative.Morphism fopen Semantics A₁ renaming (⟦_⟧ to ⟦_⟧₁)open Semantics A₂ renaming (⟦_⟧ to ⟦_⟧₂)open RawApplicative A₁ renaming (pure to pure₁; _<$>_ to _<$>₁_; _⊛_ to _⊛₁_)open RawApplicative A₂ renaming (pure to pure₂; _<$>_ to _<$>₂_; _⊛_ to _⊛₂_)natural : ∀ {n} (e : Expr n) → op ∘ ⟦ e ⟧₁ ≗ ⟦ e ⟧₂ ∘ Vec.map opnatural (var x) ρ = beginop (Vec.lookup ρ x) ≡⟨ ≡.sym $ lookup-map x op ρ ⟩Vec.lookup (Vec.map op ρ) x ∎natural (e₁ or e₂) ρ = beginop (_∨_ <$>₁ ⟦ e₁ ⟧₁ ρ ⊛₁ ⟦ e₂ ⟧₁ ρ) ≡⟨ op-⊛ _ _ ⟩op (_∨_ <$>₁ ⟦ e₁ ⟧₁ ρ) ⊛₂ op (⟦ e₂ ⟧₁ ρ) ≡⟨ ≡.cong₂ _⊛₂_ (op-<$> _ _) ≡.refl ⟩_∨_ <$>₂ op (⟦ e₁ ⟧₁ ρ) ⊛₂ op (⟦ e₂ ⟧₁ ρ) ≡⟨ ≡.cong₂ (λ e₁ e₂ → _∨_ <$>₂ e₁ ⊛₂ e₂) (natural e₁ ρ) (natural e₂ ρ) ⟩_∨_ <$>₂ ⟦ e₁ ⟧₂ (Vec.map op ρ) ⊛₂ ⟦ e₂ ⟧₂ (Vec.map op ρ) ∎natural (e₁ and e₂) ρ = beginop (_∧_ <$>₁ ⟦ e₁ ⟧₁ ρ ⊛₁ ⟦ e₂ ⟧₁ ρ) ≡⟨ op-⊛ _ _ ⟩op (_∧_ <$>₁ ⟦ e₁ ⟧₁ ρ) ⊛₂ op (⟦ e₂ ⟧₁ ρ) ≡⟨ ≡.cong₂ _⊛₂_ (op-<$> _ _) ≡.refl ⟩_∧_ <$>₂ op (⟦ e₁ ⟧₁ ρ) ⊛₂ op (⟦ e₂ ⟧₁ ρ) ≡⟨ ≡.cong₂ (λ e₁ e₂ → _∧_ <$>₂ e₁ ⊛₂ e₂) (natural e₁ ρ) (natural e₂ ρ) ⟩_∧_ <$>₂ ⟦ e₁ ⟧₂ (Vec.map op ρ) ⊛₂ ⟦ e₂ ⟧₂ (Vec.map op ρ) ∎natural (not e) ρ = beginop (¬_ <$>₁ ⟦ e ⟧₁ ρ) ≡⟨ op-<$> _ _ ⟩¬_ <$>₂ op (⟦ e ⟧₁ ρ) ≡⟨ ≡.cong (¬_ <$>₂_) (natural e ρ) ⟩¬_ <$>₂ ⟦ e ⟧₂ (Vec.map op ρ) ∎natural top ρ = beginop (pure₁ ⊤) ≡⟨ op-pure _ ⟩pure₂ ⊤ ∎natural bot ρ = beginop (pure₁ ⊥) ≡⟨ op-pure _ ⟩pure₂ ⊥ ∎-- An example of how naturality can be used: Any boolean algebra can-- be lifted, in a pointwise manner, to vectors of carrier elements.lift : ℕ → BooleanAlgebra b blift n = record{ Carrier = Vec Carrier n; _≈_ = Pointwise _≈_; _∨_ = zipWith _∨_; _∧_ = zipWith _∧_; ¬_ = map ¬_; ⊤ = pure ⊤; ⊥ = pure ⊥; isBooleanAlgebra = isBooleanAlgebraʳ $ record{ isDistributiveLattice = isDistributiveLatticeʳʲᵐ $ record{ isLattice = record{ isEquivalence = PW.isEquivalence isEquivalence; ∨-comm = λ xs ys → ext λ i →solve i 2 (λ x y → x or y , y or x)(∨-comm _ _) xs ys; ∨-assoc = λ xs ys _ → ext λ i →solve i 3(λ x y z → (x or y) or z , x or (y or z))(∨-assoc _ _ _) xs ys _; ∨-cong = λ {xs} {ys} {us} {vs} xs≈us ys≈vs → ext λ i →solve₁ i 4 (λ x y u v → x or y , u or v)xs us ys vs(∨-cong (Pointwise.app xs≈us i)(Pointwise.app ys≈vs i)); ∧-comm = λ xs ys → ext λ i →solve i 2 (λ x y → x and y , y and x)(∧-comm _ _) xs ys; ∧-assoc = λ xs ys _ → ext λ i →solve i 3(λ x y z → (x and y) and z ,x and (y and z))(∧-assoc _ _ _) xs ys _; ∧-cong = λ {xs} {ys} {us} {vs} xs≈ys us≈vs → ext λ i →solve₁ i 4 (λ x y u v → x and y , u and v)xs us ys vs(∧-cong (Pointwise.app xs≈ys i)(Pointwise.app us≈vs i)); absorptive =(λ xs ys → ext λ i →solve i 2 (λ x y → x or (x and y) , x) (∨-absorbs-∧ _ _) xs ys) ,(λ xs ys → ext λ i →solve i 2 (λ x y → x and (x or y) , x) (∧-absorbs-∨ _ _) xs ys)}; ∨-distribʳ-∧ = λ xs ys zs → ext λ i →solve i 3(λ x y z → (y and z) or x ,(y or x) and (z or x))(∨-distribʳ-∧ _ _ _) xs ys zs}; ∨-complementʳ = λ xs → ext λ i →solve i 1 (λ x → x or (not x) , top)(∨-complementʳ _) xs; ∧-complementʳ = λ xs → ext λ i →solve i 1 (λ x → x and (not x) , bot)(∧-complementʳ _) xs; ¬-cong = λ {xs} {ys} xs≈ys → ext λ i →solve₁ i 2 (λ x y → not x , not y) xs ys(¬-cong (Pointwise.app xs≈ys i))}}whereopen RawApplicative Vec.applicativeusing (pure; zipWith) renaming (_<$>_ to map)⟦_⟧Id : ∀ {n} → Expr n → Vec Carrier n → Carrier⟦_⟧Id = Semantics.⟦_⟧ Identity.applicative⟦_⟧Vec : ∀ {m n} → Expr n → Vec (Vec Carrier m) n → Vec Carrier m⟦_⟧Vec = Semantics.⟦_⟧ Vec.applicativeopen module R {n} (i : Fin n) =Reflection setoid var(λ e ρ → Vec.lookup (⟦ e ⟧Vec ρ) i)(λ e ρ → ⟦ e ⟧Id (Vec.map (flip Vec.lookup i) ρ))(λ e ρ → sym $ reflexive $Naturality.natural (Vec.lookup-morphism i) e ρ)
-------------------------------------------------------------------------- The Agda standard library---- Morphisms between algebraic lattice structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Lattice.Morphism where-------------------------------------------------------------------------- Re-exportopen import Algebra.Morphism.Definitions publicopen import Algebra.Lattice.Morphism.Structures public
-------------------------------------------------------------------------- The Agda standard library---- Morphisms between algebraic lattice structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Morphismopen import Algebra.Lattice.Bundlesimport Algebra.Morphism.Definitions as MorphismDefinitionsopen import Level using (Level; _⊔_)open import Function.Definitionsopen import Relation.Binary.Morphism.Structuresopen import Relation.Binary.Coremodule Algebra.Lattice.Morphism.Structures whereprivatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Morphisms over lattice-like structures------------------------------------------------------------------------module LatticeMorphisms (L₁ : RawLattice a ℓ₁) (L₂ : RawLattice b ℓ₂) whereopen RawLattice L₁ renaming( Carrier to A; _≈_ to _≈₁_; _∧_ to _∧₁_; _∨_ to _∨₁_; ∧-rawMagma to ∧-rawMagma₁; ∨-rawMagma to ∨-rawMagma₁)open RawLattice L₂ renaming( Carrier to B; _≈_ to _≈₂_; _∧_ to _∧₂_; _∨_ to _∨₂_; ∧-rawMagma to ∧-rawMagma₂; ∨-rawMagma to ∨-rawMagma₂)module ∨ = MagmaMorphisms ∨-rawMagma₁ ∨-rawMagma₂module ∧ = MagmaMorphisms ∧-rawMagma₁ ∧-rawMagma₂open MorphismDefinitions A B _≈₂_record IsLatticeHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisRelHomomorphism : IsRelHomomorphism _≈₁_ _≈₂_ ⟦_⟧∧-homo : Homomorphic₂ ⟦_⟧ _∧₁_ _∧₂_∨-homo : Homomorphic₂ ⟦_⟧ _∨₁_ _∨₂_open IsRelHomomorphism isRelHomomorphism publicrenaming (cong to ⟦⟧-cong)∧-isMagmaHomomorphism : ∧.IsMagmaHomomorphism ⟦_⟧∧-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = ∧-homo}∨-isMagmaHomomorphism : ∨.IsMagmaHomomorphism ⟦_⟧∨-isMagmaHomomorphism = record{ isRelHomomorphism = isRelHomomorphism; homo = ∨-homo}record IsLatticeMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLatticeHomomorphism : IsLatticeHomomorphism ⟦_⟧injective : Injective _≈₁_ _≈₂_ ⟦_⟧open IsLatticeHomomorphism isLatticeHomomorphism public∨-isMagmaMonomorphism : ∨.IsMagmaMonomorphism ⟦_⟧∨-isMagmaMonomorphism = record{ isMagmaHomomorphism = ∨-isMagmaHomomorphism; injective = injective}∧-isMagmaMonomorphism : ∧.IsMagmaMonomorphism ⟦_⟧∧-isMagmaMonomorphism = record{ isMagmaHomomorphism = ∧-isMagmaHomomorphism; injective = injective}open ∧.IsMagmaMonomorphism ∧-isMagmaMonomorphism publicusing (isRelMonomorphism)record IsLatticeIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisLatticeMonomorphism : IsLatticeMonomorphism ⟦_⟧surjective : Surjective _≈₁_ _≈₂_ ⟦_⟧open IsLatticeMonomorphism isLatticeMonomorphism public∨-isMagmaIsomorphism : ∨.IsMagmaIsomorphism ⟦_⟧∨-isMagmaIsomorphism = record{ isMagmaMonomorphism = ∨-isMagmaMonomorphism; surjective = surjective}∧-isMagmaIsomorphism : ∧.IsMagmaIsomorphism ⟦_⟧∧-isMagmaIsomorphism = record{ isMagmaMonomorphism = ∧-isMagmaMonomorphism; surjective = surjective}open ∧.IsMagmaIsomorphism ∧-isMagmaIsomorphism publicusing (isRelIsomorphism)-------------------------------------------------------------------------- Re-export contents of modules publiclyopen LatticeMorphisms public
-------------------------------------------------------------------------- The Agda standard library---- Consequences of a monomorphism between lattice-like structures-------------------------------------------------------------------------- See Data.Nat.Binary.Properties for examples of how this and similar-- modules can be used to easily translate properties between types.{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Algebra.Latticeopen import Algebra.Lattice.Morphism.Structuresimport Algebra.Consequences.Setoid as Consequencesimport Algebra.Morphism.MagmaMonomorphism as MagmaMonomorphismsimport Algebra.Lattice.Properties.Lattice as LatticePropertiesopen import Data.Product.Base using (_,_; map)open import Relation.Binary.Bundles using (Setoid)import Relation.Binary.Morphism.RelMonomorphism as RelMonomorphismsimport Relation.Binary.Reasoning.Setoid as ≈-Reasoningmodule Algebra.Lattice.Morphism.LatticeMonomorphism{a b ℓ₁ ℓ₂} {L₁ : RawLattice a ℓ₁} {L₂ : RawLattice b ℓ₂} {⟦_⟧}(isLatticeMonomorphism : IsLatticeMonomorphism L₁ L₂ ⟦_⟧)whereopen IsLatticeMonomorphism isLatticeMonomorphismopen RawLattice L₁ renaming (_≈_ to _≈₁_; _∨_ to _∨_; _∧_ to _∧_)open RawLattice L₂ renaming (_≈_ to _≈₂_; _∨_ to _⊔_; _∧_ to _⊓_)-------------------------------------------------------------------------- Re-export all properties of magma monomorphismsopen MagmaMonomorphisms ∨-isMagmaMonomorphism publicusing () renaming( cong to ∨-cong; assoc to ∨-assoc; comm to ∨-comm; idem to ∨-idem; sel to ∨-sel; cancelˡ to ∨-cancelˡ; cancelʳ to ∨-cancelʳ; cancel to ∨-cancel)open MagmaMonomorphisms ∧-isMagmaMonomorphism publicusing () renaming( cong to ∧-cong; assoc to ∧-assoc; comm to ∧-comm; idem to ∧-idem; sel to ∧-sel; cancelˡ to ∧-cancelˡ; cancelʳ to ∧-cancelʳ; cancel to ∧-cancel)-------------------------------------------------------------------------- Lattice-specific propertiesmodule _ (⊔-⊓-isLattice : IsLattice _≈₂_ _⊔_ _⊓_) whereopen IsLattice ⊔-⊓-isLattice using (isEquivalence) renaming( ∨-congˡ to ⊔-congˡ; ∨-congʳ to ⊔-congʳ; ∧-cong to ⊓-cong; ∧-congˡ to ⊓-congˡ; ∨-absorbs-∧ to ⊔-absorbs-⊓; ∧-absorbs-∨ to ⊓-absorbs-⊔)setoid : Setoid b ℓ₂setoid = record { isEquivalence = isEquivalence }open ≈-Reasoning setoid∨-absorbs-∧ : _Absorbs_ _≈₁_ _∨_ _∧_∨-absorbs-∧ x y = injective (begin⟦ x ∨ x ∧ y ⟧ ≈⟨ ∨-homo x (x ∧ y) ⟩⟦ x ⟧ ⊔ ⟦ x ∧ y ⟧ ≈⟨ ⊔-congˡ (∧-homo x y) ⟩⟦ x ⟧ ⊔ ⟦ x ⟧ ⊓ ⟦ y ⟧ ≈⟨ ⊔-absorbs-⊓ ⟦ x ⟧ ⟦ y ⟧ ⟩⟦ x ⟧ ∎)∧-absorbs-∨ : _Absorbs_ _≈₁_ _∧_ _∨_∧-absorbs-∨ x y = injective (begin⟦ x ∧ (x ∨ y) ⟧ ≈⟨ ∧-homo x (x ∨ y) ⟩⟦ x ⟧ ⊓ ⟦ x ∨ y ⟧ ≈⟨ ⊓-congˡ (∨-homo x y) ⟩⟦ x ⟧ ⊓ (⟦ x ⟧ ⊔ ⟦ y ⟧) ≈⟨ ⊓-absorbs-⊔ ⟦ x ⟧ ⟦ y ⟧ ⟩⟦ x ⟧ ∎)absorptive : Absorptive _≈₁_ _∨_ _∧_absorptive = ∨-absorbs-∧ , ∧-absorbs-∨distribʳ : _DistributesOverʳ_ _≈₂_ _⊔_ _⊓_ → _DistributesOverʳ_ _≈₁_ _∨_ _∧_distribʳ distribʳ x y z = injective (begin⟦ y ∧ z ∨ x ⟧ ≈⟨ ∨-homo (y ∧ z) x ⟩⟦ y ∧ z ⟧ ⊔ ⟦ x ⟧ ≈⟨ ⊔-congʳ (∧-homo y z) ⟩⟦ y ⟧ ⊓ ⟦ z ⟧ ⊔ ⟦ x ⟧ ≈⟨ distribʳ ⟦ x ⟧ ⟦ y ⟧ ⟦ z ⟧ ⟩(⟦ y ⟧ ⊔ ⟦ x ⟧) ⊓ (⟦ z ⟧ ⊔ ⟦ x ⟧) ≈⟨ ⊓-cong (∨-homo y x) (∨-homo z x) ⟨⟦ y ∨ x ⟧ ⊓ ⟦ z ∨ x ⟧ ≈⟨ ∧-homo (y ∨ x) (z ∨ x) ⟨⟦ (y ∨ x) ∧ (z ∨ x) ⟧ ∎)isLattice : IsLattice _≈₂_ _⊔_ _⊓_ → IsLattice _≈₁_ _∨_ _∧_isLattice isLattice = record{ isEquivalence = RelMonomorphisms.isEquivalence isRelMonomorphism L.isEquivalence; ∨-comm = ∨-comm LP.∨-isMagma L.∨-comm; ∨-assoc = ∨-assoc LP.∨-isMagma L.∨-assoc; ∨-cong = ∨-cong LP.∨-isMagma; ∧-comm = ∧-comm LP.∧-isMagma L.∧-comm; ∧-assoc = ∧-assoc LP.∧-isMagma L.∧-assoc; ∧-cong = ∧-cong LP.∧-isMagma; absorptive = absorptive isLattice} wheremodule L = IsLattice isLatticemodule LP = LatticeProperties (record { isLattice = isLattice })isDistributiveLattice : IsDistributiveLattice _≈₂_ _⊔_ _⊓_ →IsDistributiveLattice _≈₁_ _∨_ _∧_isDistributiveLattice isDL = isDistributiveLatticeʳʲᵐ (record{ isLattice = isLattice L.isLattice; ∨-distribʳ-∧ = distribʳ L.isLattice L.∨-distribʳ-∧}) where module L = IsDistributiveLattice isDL
-------------------------------------------------------------------------- The Agda standard library---- The identity morphism for algebraic lattice structures------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Lattice.Morphism.Construct.Identity whereopen import Algebra.Lattice.Bundlesopen import Algebra.Lattice.Morphism.Structuresusing ( module LatticeMorphisms )open import Data.Product.Base using (_,_)open import Function.Base using (id)import Function.Construct.Identity as Idopen import Level using (Level)open import Relation.Binary.Morphism.Construct.Identity using (isRelHomomorphism)open import Relation.Binary.Definitions using (Reflexive)privatevariablec ℓ : Levelmodule _ (L : RawLattice c ℓ) (open RawLattice L) (refl : Reflexive _≈_) whereopen LatticeMorphisms L LisLatticeHomomorphism : IsLatticeHomomorphism idisLatticeHomomorphism = record{ isRelHomomorphism = isRelHomomorphism _; ∧-homo = λ _ _ → refl; ∨-homo = λ _ _ → refl}isLatticeMonomorphism : IsLatticeMonomorphism idisLatticeMonomorphism = record{ isLatticeHomomorphism = isLatticeHomomorphism; injective = id}isLatticeIsomorphism : IsLatticeIsomorphism idisLatticeIsomorphism = record{ isLatticeMonomorphism = isLatticeMonomorphism; surjective = Id.surjective _}
-------------------------------------------------------------------------- The Agda standard library---- The composition of morphisms between algebraic lattice structures.------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module Algebra.Lattice.Morphism.Construct.Composition whereopen import Algebra.Lattice.Bundlesopen import Algebra.Lattice.Morphism.Structuresopen import Function.Base using (_∘_)import Function.Construct.Composition as Funcopen import Level using (Level)open import Relation.Binary.Morphism.Construct.Compositionopen import Relation.Binary.Definitions using (Transitive)privatevariablea b c ℓ₁ ℓ₂ ℓ₃ : Level-------------------------------------------------------------------------- Latticesmodule _ {L₁ : RawLattice a ℓ₁}{L₂ : RawLattice b ℓ₂}{L₃ : RawLattice c ℓ₃}(open RawLattice)(≈₃-trans : Transitive (_≈_ L₃)){f : Carrier L₁ → Carrier L₂}{g : Carrier L₂ → Carrier L₃}whereisLatticeHomomorphism: IsLatticeHomomorphism L₁ L₂ f→ IsLatticeHomomorphism L₂ L₃ g→ IsLatticeHomomorphism L₁ L₃ (g ∘ f)isLatticeHomomorphism f-homo g-homo = record{ isRelHomomorphism = isRelHomomorphism F.isRelHomomorphism G.isRelHomomorphism; ∧-homo = λ x y → ≈₃-trans (G.⟦⟧-cong (F.∧-homo x y)) (G.∧-homo (f x) (f y)); ∨-homo = λ x y → ≈₃-trans (G.⟦⟧-cong (F.∨-homo x y)) (G.∨-homo (f x) (f y))} where module F = IsLatticeHomomorphism f-homo; module G = IsLatticeHomomorphism g-homoisLatticeMonomorphism: IsLatticeMonomorphism L₁ L₂ f→ IsLatticeMonomorphism L₂ L₃ g→ IsLatticeMonomorphism L₁ L₃ (g ∘ f)isLatticeMonomorphism f-mono g-mono = record{ isLatticeHomomorphism = isLatticeHomomorphism F.isLatticeHomomorphism G.isLatticeHomomorphism; injective = F.injective ∘ G.injective} where module F = IsLatticeMonomorphism f-mono; module G = IsLatticeMonomorphism g-monoisLatticeIsomorphism: IsLatticeIsomorphism L₁ L₂ f→ IsLatticeIsomorphism L₂ L₃ g→ IsLatticeIsomorphism L₁ L₃ (g ∘ f)isLatticeIsomorphism f-iso g-iso = record{ isLatticeMonomorphism = isLatticeMonomorphism F.isLatticeMonomorphism G.isLatticeMonomorphism; surjective = Func.surjective _ _ (_≈_ L₃) F.surjective G.surjective} where module F = IsLatticeIsomorphism f-iso; module G = IsLatticeIsomorphism g-iso
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic lattice structures where the carrier is ⊤.-- In mathematics, this is usually called 0.---- From monoids up, these are are zero-objects – i.e, both the initial-- and the terminal object in the relevant category.-- For structures without an identity element, we can't necessarily-- produce a homomorphism out of 0, because there is an instance of such-- a structure with an empty Carrier.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Lattice.Construct.Zero {c ℓ : Level} whereopen import Algebra.Lattice.Bundlesopen import Data.Unit.Polymorphic-------------------------------------------------------------------------- Bundlessemilattice : Semilattice c ℓsemilattice = record { Carrier = ⊤ ; _≈_ = λ _ _ → ⊤ }
-------------------------------------------------------------------------- The Agda standard library---- Substituting equalities for binary relations-------------------------------------------------------------------------- For more general transformations between algebraic lattice structures-- see `Algebra.Lattice.Morphisms`.{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Core using (Op₂)open import Algebra.Definitionsopen import Algebra.Lattice.Structuresopen import Data.Product.Base using (_,_)open import Function.Baseopen import Relation.Binary.Coremodule Algebra.Lattice.Construct.Subst.Equality{a ℓ₁ ℓ₂} {A : Set a} {≈₁ : Rel A ℓ₁} {≈₂ : Rel A ℓ₂}(equiv@(to , from) : ≈₁ ⇔ ≈₂)whereopen import Algebra.Construct.Subst.Equality equivopen import Relation.Binary.Construct.Subst.Equality equivprivatevariable∧ ∨ : Op₂ A-------------------------------------------------------------------------- StructuresisSemilattice : IsSemilattice ≈₁ ∧ → IsSemilattice ≈₂ ∧isSemilattice S = record{ isBand = isBand S.isBand; comm = comm S.comm} where module S = IsSemilattice ≈₁ SisLattice : IsLattice ≈₁ ∨ ∧ → IsLattice ≈₂ ∨ ∧isLattice {∨} {∧} S = record{ isEquivalence = isEquivalence S.isEquivalence; ∨-comm = comm S.∨-comm; ∨-assoc = assoc {∨} S.∨-assoc; ∨-cong = cong₂ S.∨-cong; ∧-comm = comm S.∧-comm; ∧-assoc = assoc {∧} S.∧-assoc; ∧-cong = cong₂ S.∧-cong; absorptive = absorptive {∨} {∧} S.absorptive} where module S = IsLattice SisDistributiveLattice : IsDistributiveLattice ≈₁ ∨ ∧ →IsDistributiveLattice ≈₂ ∨ ∧isDistributiveLattice {∨} {∧} S = record{ isLattice = isLattice S.isLattice; ∨-distrib-∧ = distrib {∨} {∧} S.∨-distrib-∧; ∧-distrib-∨ = distrib {∧} {∨} S.∧-distrib-∨} where module S = IsDistributiveLattice SisBooleanAlgebra : ∀ {¬ ⊤ ⊥} →IsBooleanAlgebra ≈₁ ∨ ∧ ¬ ⊤ ⊥ →IsBooleanAlgebra ≈₂ ∨ ∧ ¬ ⊤ ⊥isBooleanAlgebra {∨} {∧} S = record{ isDistributiveLattice = isDistributiveLattice S.isDistributiveLattice; ∨-complement = inverse {_} {∨} S.∨-complement; ∧-complement = inverse {_} {∧} S.∧-complement; ¬-cong = cong₁ S.¬-cong} where module S = IsBooleanAlgebra S
-------------------------------------------------------------------------- The Agda standard library---- Properties of a min operator derived from a spec over a total-- preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundlesopen import Algebra.Lattice.Bundlesopen import Algebra.Construct.NaturalChoice.Baseopen import Relation.Binary.Bundles using (TotalPreorder)module Algebra.Lattice.Construct.NaturalChoice.MinOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂} (minOp : MinOperator O) whereopen TotalPreorder Oopen MinOperator minOpopen import Algebra.Lattice.Structures _≈_open import Algebra.Construct.NaturalChoice.MinOp minOp-------------------------------------------------------------------------- Structures⊓-isSemilattice : IsSemilattice _⊓_⊓-isSemilattice = record{ isBand = ⊓-isBand; comm = ⊓-comm}-------------------------------------------------------------------------- Bundles⊓-semilattice : Semilattice _ _⊓-semilattice = record{ isSemilattice = ⊓-isSemilattice}
-------------------------------------------------------------------------- The Agda standard library---- Properties of min and max operators specified over a total preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Lattice.Bundlesopen import Algebra.Construct.NaturalChoice.Baseopen import Relation.Binary.Bundles using (TotalPreorder)module Algebra.Lattice.Construct.NaturalChoice.MinMaxOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂}(minOp : MinOperator O)(maxOp : MaxOperator O)whereopen TotalPreorder Oopen MinOperator minOpopen MaxOperator maxOpopen import Algebra.Lattice.Structures _≈_open import Algebra.Construct.NaturalChoice.MinMaxOp minOp maxOpopen import Relation.Binary.Reasoning.Preorder preorder-------------------------------------------------------------------------- Re-export properties of individual operatorsopen import Algebra.Lattice.Construct.NaturalChoice.MinOp minOp publicopen import Algebra.Lattice.Construct.NaturalChoice.MaxOp maxOp public-------------------------------------------------------------------------- Structures⊔-⊓-isLattice : IsLattice _⊔_ _⊓_⊔-⊓-isLattice = record{ isEquivalence = isEquivalence; ∨-comm = ⊔-comm; ∨-assoc = ⊔-assoc; ∨-cong = ⊔-cong; ∧-comm = ⊓-comm; ∧-assoc = ⊓-assoc; ∧-cong = ⊓-cong; absorptive = ⊔-⊓-absorptive}⊓-⊔-isLattice : IsLattice _⊓_ _⊔_⊓-⊔-isLattice = record{ isEquivalence = isEquivalence; ∨-comm = ⊓-comm; ∨-assoc = ⊓-assoc; ∨-cong = ⊓-cong; ∧-comm = ⊔-comm; ∧-assoc = ⊔-assoc; ∧-cong = ⊔-cong; absorptive = ⊓-⊔-absorptive}⊓-⊔-isDistributiveLattice : IsDistributiveLattice _⊓_ _⊔_⊓-⊔-isDistributiveLattice = record{ isLattice = ⊓-⊔-isLattice; ∨-distrib-∧ = ⊓-distrib-⊔; ∧-distrib-∨ = ⊔-distrib-⊓}⊔-⊓-isDistributiveLattice : IsDistributiveLattice _⊔_ _⊓_⊔-⊓-isDistributiveLattice = record{ isLattice = ⊔-⊓-isLattice; ∨-distrib-∧ = ⊔-distrib-⊓; ∧-distrib-∨ = ⊓-distrib-⊔}-------------------------------------------------------------------------- Bundles⊔-⊓-lattice : Lattice _ _⊔-⊓-lattice = record{ isLattice = ⊔-⊓-isLattice}⊓-⊔-lattice : Lattice _ _⊓-⊔-lattice = record{ isLattice = ⊓-⊔-isLattice}⊔-⊓-distributiveLattice : DistributiveLattice _ _⊔-⊓-distributiveLattice = record{ isDistributiveLattice = ⊔-⊓-isDistributiveLattice}⊓-⊔-distributiveLattice : DistributiveLattice _ _⊓-⊔-distributiveLattice = record{ isDistributiveLattice = ⊓-⊔-isDistributiveLattice}
-------------------------------------------------------------------------- The Agda standard library---- Properties of a max operator derived from a spec over a total-- preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Construct.NaturalChoice.Baseimport Algebra.Lattice.Construct.NaturalChoice.MinOp as MinOpopen import Relation.Binary.Bundles using (TotalPreorder)module Algebra.Lattice.Construct.NaturalChoice.MaxOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂} (maxOp : MaxOperator O)whereprivatemodule Min = MinOp (MaxOp⇒MinOp maxOp)open Min publicusing ()renaming( ⊓-isSemilattice to ⊔-isSemilattice; ⊓-semilattice to ⊔-semilattice)
-------------------------------------------------------------------------- The Agda standard library---- Choosing between elements based on the result of applying a function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Algebra.Latticeopen import Algebra.Construct.LiftedChoiceopen import Relation.Binary.Core using (Rel; _Preserves_⟶_)open import Relation.Binary.Structures using (IsEquivalence)open import Level using (Level)module Algebra.Lattice.Construct.LiftedChoice whereprivatevariablea b p ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Structuresmodule _ {_≈_ : Rel B ℓ} {_∙_ : Op₂ B}(∙-isSelectiveMagma : IsSelectiveMagma _≈_ _∙_){_≈′_ : Rel A ℓ} {f : A → B}(f-injective : ∀ {x y} → f x ≈ f y → x ≈′ y)(f-cong : f Preserves _≈′_ ⟶ _≈_)(≈′-isEquivalence : IsEquivalence _≈′_)whereopen IsSelectiveMagma ∙-isSelectiveMagma renaming (sel to ∙-sel)private_◦_ = Lift _≈_ _∙_ ∙-sel fisSemilattice : Associative _≈_ _∙_ → Commutative _≈_ _∙_ →IsSemilattice _≈′_ _◦_isSemilattice ∙-assoc ∙-comm = record{ isBand = isBand ∙-isSelectiveMagma f-injective f-cong ≈′-isEquivalence ∙-assoc; comm = comm ∙-isSelectiveMagma (λ {x} → f-injective {x}) ∙-comm}
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic structures made by taking two other instances-- A and B, and having elements of the new instance be pairs |A| × |B|.-- In mathematics, this would usually be written A × B or A ⊕ B.---- From semigroups up, these new instances are products of the relevant-- category. For structures with commutative addition (commutative-- monoids, Abelian groups, semirings, rings), the direct product is-- also the coproduct, making it a biproduct.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Algebra.Latticeimport Algebra.Construct.DirectProduct as DirectProductopen import Data.Product.Base using (_,_; _<*>_)open import Data.Product.Relation.Binary.Pointwise.NonDependentopen import Level using (Level; _⊔_)module Algebra.Lattice.Construct.DirectProduct whereprivatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Bundlessemilattice : Semilattice a ℓ₁ → Semilattice b ℓ₂ →Semilattice (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semilattice L M = record{ isSemilattice = record{ isBand = Band.isBand (DirectProduct.band L.band M.band); comm = λ x y → (L.comm , M.comm) <*> x <*> y}} where module L = Semilattice L; module M = Semilattice M
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structures like semilattices and lattices-- (packed in records together with sets, operations, etc.), defined via-- meet/join operations and their properties---- For lattices defined via an order relation, see-- Relation.Binary.Lattice.-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra.Lattice`.{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Lattice.Bundles whereopen import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Structuresimport Algebra.Lattice.Bundles.Raw as Rawopen import Algebra.Lattice.Structuresopen import Level using (suc; _⊔_)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Core using (Rel)-------------------------------------------------------------------------- Re-export definitions of 'raw' bundlesopen Raw publicusing (RawLattice)-------------------------------------------------------------------------- Bundles------------------------------------------------------------------------record Semilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisSemilattice : IsSemilattice _≈_ _∙_open IsSemilattice _≈_ isSemilattice publicband : Band c ℓband = record { isBand = isBand }open Band band publicusing (_≉_; rawMagma; magma; isMagma; semigroup; isSemigroup; isBand)record MeetSemilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∧_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∧_ : Op₂ CarrierisMeetSemilattice : IsSemilattice _≈_ _∧_open IsMeetSemilattice _≈_ isMeetSemilattice publicsemilattice : Semilattice c ℓsemilattice = record { isSemilattice = isMeetSemilattice }open Semilattice semilattice publicusing (rawMagma; magma; semigroup; band)record JoinSemilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∨_ : Op₂ CarrierisJoinSemilattice : IsSemilattice _≈_ _∨_open IsJoinSemilattice _≈_ isJoinSemilattice publicsemilattice : Semilattice c ℓsemilattice = record { isSemilattice = isJoinSemilattice }open Semilattice semilattice publicusing (rawMagma; magma; semigroup; band)record BoundedSemilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisBoundedSemilattice : IsBoundedSemilattice _≈_ _∙_ εopen IsBoundedSemilattice _≈_ isBoundedSemilattice publicsemilattice : Semilattice c ℓsemilattice = record { isSemilattice = isSemilattice }open Semilattice semilattice public using (rawMagma; magma; semigroup; band)record BoundedMeetSemilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∧_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∧_ : Op₂ Carrier⊤ : CarrierisBoundedMeetSemilattice : IsBoundedSemilattice _≈_ _∧_ ⊤open IsBoundedMeetSemilattice _≈_ isBoundedMeetSemilattice publicboundedSemilattice : BoundedSemilattice c ℓboundedSemilattice = record{ isBoundedSemilattice = isBoundedMeetSemilattice }open BoundedSemilattice boundedSemilattice publicusing (rawMagma; magma; semigroup; band; semilattice)record BoundedJoinSemilattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∨_ : Op₂ Carrier⊥ : CarrierisBoundedJoinSemilattice : IsBoundedSemilattice _≈_ _∨_ ⊥open IsBoundedJoinSemilattice _≈_ isBoundedJoinSemilattice publicboundedSemilattice : BoundedSemilattice c ℓboundedSemilattice = record{ isBoundedSemilattice = isBoundedJoinSemilattice }open BoundedSemilattice boundedSemilattice publicusing (rawMagma; magma; semigroup; band; semilattice)record Lattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∧_infixr 6 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∨_ : Op₂ Carrier_∧_ : Op₂ CarrierisLattice : IsLattice _≈_ _∨_ _∧_open IsLattice isLattice publicrawLattice : RawLattice c ℓrawLattice = record{ _≈_ = _≈_; _∧_ = _∧_; _∨_ = _∨_}open RawLattice rawLattice publicusing (∨-rawMagma; ∧-rawMagma)setoid : Setoid c ℓsetoid = record { isEquivalence = isEquivalence }open Setoid setoid publicusing (_≉_)record DistributiveLattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∧_infixr 6 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∨_ : Op₂ Carrier_∧_ : Op₂ CarrierisDistributiveLattice : IsDistributiveLattice _≈_ _∨_ _∧_open IsDistributiveLattice isDistributiveLattice publiclattice : Lattice _ _lattice = record { isLattice = isLattice }open Lattice lattice publicusing( _≉_; setoid; rawLattice; ∨-rawMagma; ∧-rawMagma)record BooleanAlgebra c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 ¬_infixr 7 _∧_infixr 6 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∨_ : Op₂ Carrier_∧_ : Op₂ Carrier¬_ : Op₁ Carrier⊤ : Carrier⊥ : CarrierisBooleanAlgebra : IsBooleanAlgebra _≈_ _∨_ _∧_ ¬_ ⊤ ⊥open IsBooleanAlgebra isBooleanAlgebra publicdistributiveLattice : DistributiveLattice _ _distributiveLattice = record{ isDistributiveLattice = isDistributiveLattice}open DistributiveLattice distributiveLattice publicusing( _≉_; setoid; rawLattice; ∨-rawMagma; ∧-rawMagma; lattice)
-------------------------------------------------------------------------- The Agda standard library---- Definitions of 'raw' bundles------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Lattice.Bundles.Raw whereopen import Algebra.Coreopen import Algebra.Bundles.Raw using (RawMagma)open import Level using (suc; _⊔_)open import Relation.Binary.Core using (Rel)record RawLattice c ℓ : Set (suc (c ⊔ ℓ)) whereinfixr 7 _∧_infixr 6 _∨_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∧_ : Op₂ Carrier_∨_ : Op₂ Carrier∨-rawMagma : RawMagma c ℓ∨-rawMagma = record { _≈_ = _≈_; _∙_ = _∨_ }∧-rawMagma : RawMagma c ℓ∧-rawMagma = record { _≈_ = _≈_; _∙_ = _∧_ }open RawMagma ∨-rawMagma publicusing (_≉_)
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Substitutive; Symmetric; Total)module Algebra.FunctionProperties.Consequences{a ℓ} (S : Setoid a ℓ) where{-# WARNING_ON_IMPORT"Algebra.FunctionProperties.Consequences was deprecated in v1.3.Use Algebra.Consequences.Setoid instead."#-}open import Algebra.Consequences.Setoid S public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.FunctionProperties.Consequences.Propositional{a} {A : Set a} where{-# WARNING_ON_IMPORT"Algebra.FunctionProperties.Consequences.Propositional was deprecated in v1.3.Use Algebra.Consequences.Propositional instead."#-}open import Algebra.Consequences.Propositional {A = A} public
-------------------------------------------------------------------------- The Agda standard library---- This module is DEPRECATED.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.FunctionProperties.Consequences.Core{a} {A : Set a} where{-# WARNING_ON_IMPORT"Algebra.FunctionProperties.Consequences.Core was deprecated in v1.3.Use Algebra.Consequences.Base instead."#-}open import Algebra.Consequences.Base public
-------------------------------------------------------------------------- The Agda standard library---- Properties of functions, such as associativity and commutativity-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra`, unless-- you want to parameterise it via the equality relation.-- Note that very few of the element arguments are made implicit here,-- as we do not assume that the Agda can infer either the right or left-- argument of the binary operators. This is despite the fact that the-- library defines most of its concrete operators (e.g. in-- `Data.Nat.Base`) as being left-biased.{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel; _Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Nullary.Negation.Core using (¬_)module Algebra.Definitions{a ℓ} {A : Set a} -- The underlying set(_≈_ : Rel A ℓ) -- The underlying equalitywhereopen import Algebra.Core using (Op₁; Op₂)open import Data.Product.Base using (_×_; ∃-syntax)open import Data.Sum.Base using (_⊎_)-------------------------------------------------------------------------- Properties of operationsCongruent₁ : Op₁ A → Set _Congruent₁ f = f Preserves _≈_ ⟶ _≈_Congruent₂ : Op₂ A → Set _Congruent₂ ∙ = ∙ Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_LeftCongruent : Op₂ A → Set _LeftCongruent _∙_ = ∀ {x} → (x ∙_) Preserves _≈_ ⟶ _≈_RightCongruent : Op₂ A → Set _RightCongruent _∙_ = ∀ {x} → (_∙ x) Preserves _≈_ ⟶ _≈_Associative : Op₂ A → Set _Associative _∙_ = ∀ x y z → ((x ∙ y) ∙ z) ≈ (x ∙ (y ∙ z))Commutative : Op₂ A → Set _Commutative _∙_ = ∀ x y → (x ∙ y) ≈ (y ∙ x)LeftIdentity : A → Op₂ A → Set _LeftIdentity e _∙_ = ∀ x → (e ∙ x) ≈ xRightIdentity : A → Op₂ A → Set _RightIdentity e _∙_ = ∀ x → (x ∙ e) ≈ xIdentity : A → Op₂ A → Set _Identity e ∙ = (LeftIdentity e ∙) × (RightIdentity e ∙)LeftZero : A → Op₂ A → Set _LeftZero z _∙_ = ∀ x → (z ∙ x) ≈ zRightZero : A → Op₂ A → Set _RightZero z _∙_ = ∀ x → (x ∙ z) ≈ zZero : A → Op₂ A → Set _Zero z ∙ = (LeftZero z ∙) × (RightZero z ∙)LeftInverse : A → Op₁ A → Op₂ A → Set _LeftInverse e _⁻¹ _∙_ = ∀ x → ((x ⁻¹) ∙ x) ≈ eRightInverse : A → Op₁ A → Op₂ A → Set _RightInverse e _⁻¹ _∙_ = ∀ x → (x ∙ (x ⁻¹)) ≈ eInverse : A → Op₁ A → Op₂ A → Set _Inverse e ⁻¹ ∙ = (LeftInverse e ⁻¹) ∙ × (RightInverse e ⁻¹ ∙)-- For structures in which not every element has an inverse (e.g. Fields)LeftInvertible : A → Op₂ A → A → Set _LeftInvertible e _∙_ x = ∃[ x⁻¹ ] (x⁻¹ ∙ x) ≈ eRightInvertible : A → Op₂ A → A → Set _RightInvertible e _∙_ x = ∃[ x⁻¹ ] (x ∙ x⁻¹) ≈ e-- NB: this is not quite the same as-- LeftInvertible e ∙ x × RightInvertible e ∙ x-- since the left and right inverses have to coincide.Invertible : A → Op₂ A → A → Set _Invertible e _∙_ x = ∃[ x⁻¹ ] (x⁻¹ ∙ x) ≈ e × (x ∙ x⁻¹) ≈ eLeftConical : A → Op₂ A → Set _LeftConical e _∙_ = ∀ x y → (x ∙ y) ≈ e → x ≈ eRightConical : A → Op₂ A → Set _RightConical e _∙_ = ∀ x y → (x ∙ y) ≈ e → y ≈ eConical : A → Op₂ A → Set _Conical e ∙ = (LeftConical e ∙) × (RightConical e ∙)infix 4 _DistributesOverˡ_ _DistributesOverʳ_ _DistributesOver__DistributesOverˡ_ : Op₂ A → Op₂ A → Set __*_ DistributesOverˡ _+_ =∀ x y z → (x * (y + z)) ≈ ((x * y) + (x * z))_DistributesOverʳ_ : Op₂ A → Op₂ A → Set __*_ DistributesOverʳ _+_ =∀ x y z → ((y + z) * x) ≈ ((y * x) + (z * x))_DistributesOver_ : Op₂ A → Op₂ A → Set _* DistributesOver + = (* DistributesOverˡ +) × (* DistributesOverʳ +)infix 4 _MiddleFourExchange_ _IdempotentOn_ _Absorbs__MiddleFourExchange_ : Op₂ A → Op₂ A → Set __*_ MiddleFourExchange _+_ =∀ w x y z → ((w + x) * (y + z)) ≈ ((w + y) * (x + z))_IdempotentOn_ : Op₂ A → A → Set __∙_ IdempotentOn x = (x ∙ x) ≈ xIdempotent : Op₂ A → Set _Idempotent ∙ = ∀ x → ∙ IdempotentOn xIdempotentFun : Op₁ A → Set _IdempotentFun f = ∀ x → f (f x) ≈ f xSelective : Op₂ A → Set _Selective _∙_ = ∀ x y → (x ∙ y) ≈ x ⊎ (x ∙ y) ≈ y_Absorbs_ : Op₂ A → Op₂ A → Set __∙_ Absorbs _∘_ = ∀ x y → (x ∙ (x ∘ y)) ≈ xAbsorptive : Op₂ A → Op₂ A → Set _Absorptive ∙ ∘ = (∙ Absorbs ∘) × (∘ Absorbs ∙)SelfInverse : Op₁ A → Set _SelfInverse f = ∀ {x y} → f x ≈ y → f y ≈ xInvolutive : Op₁ A → Set _Involutive f = ∀ x → f (f x) ≈ xLeftCancellative : Op₂ A → Set _LeftCancellative _•_ = ∀ x y z → (x • y) ≈ (x • z) → y ≈ zRightCancellative : Op₂ A → Set _RightCancellative _•_ = ∀ x y z → (y • x) ≈ (z • x) → y ≈ zCancellative : Op₂ A → Set _Cancellative _•_ = (LeftCancellative _•_) × (RightCancellative _•_)AlmostLeftCancellative : A → Op₂ A → Set _AlmostLeftCancellative e _•_ = ∀ x y z → ¬ x ≈ e → (x • y) ≈ (x • z) → y ≈ zAlmostRightCancellative : A → Op₂ A → Set _AlmostRightCancellative e _•_ = ∀ x y z → ¬ x ≈ e → (y • x) ≈ (z • x) → y ≈ zAlmostCancellative : A → Op₂ A → Set _AlmostCancellative e _•_ = AlmostLeftCancellative e _•_ × AlmostRightCancellative e _•_Interchangable : Op₂ A → Op₂ A → Set _Interchangable _∘_ _∙_ = ∀ w x y z → ((w ∙ x) ∘ (y ∙ z)) ≈ ((w ∘ y) ∙ (x ∘ z))LeftDividesˡ : Op₂ A → Op₂ A → Set _LeftDividesˡ _∙_ _\\_ = ∀ x y → (x ∙ (x \\ y)) ≈ yLeftDividesʳ : Op₂ A → Op₂ A → Set _LeftDividesʳ _∙_ _\\_ = ∀ x y → (x \\ (x ∙ y)) ≈ yRightDividesˡ : Op₂ A → Op₂ A → Set _RightDividesˡ _∙_ _//_ = ∀ x y → ((y // x) ∙ x) ≈ yRightDividesʳ : Op₂ A → Op₂ A → Set _RightDividesʳ _∙_ _//_ = ∀ x y → ((y ∙ x) // x) ≈ yLeftDivides : Op₂ A → Op₂ A → Set _LeftDivides ∙ \\ = (LeftDividesˡ ∙ \\) × (LeftDividesʳ ∙ \\)RightDivides : Op₂ A → Op₂ A → Set _RightDivides ∙ // = (RightDividesˡ ∙ //) × (RightDividesʳ ∙ //)StarRightExpansive : A → Op₂ A → Op₂ A → Op₁ A → Set _StarRightExpansive e _+_ _∙_ _* = ∀ x → (e + (x ∙ (x *))) ≈ (x *)StarLeftExpansive : A → Op₂ A → Op₂ A → Op₁ A → Set _StarLeftExpansive e _+_ _∙_ _* = ∀ x → (e + ((x *) ∙ x)) ≈ (x *)StarExpansive : A → Op₂ A → Op₂ A → Op₁ A → Set _StarExpansive e _+_ _∙_ _* = (StarLeftExpansive e _+_ _∙_ _*) × (StarRightExpansive e _+_ _∙_ _*)StarLeftDestructive : Op₂ A → Op₂ A → Op₁ A → Set _StarLeftDestructive _+_ _∙_ _* = ∀ a b x → (b + (a ∙ x)) ≈ x → ((a *) ∙ b) ≈ xStarRightDestructive : Op₂ A → Op₂ A → Op₁ A → Set _StarRightDestructive _+_ _∙_ _* = ∀ a b x → (b + (x ∙ a)) ≈ x → (b ∙ (a *)) ≈ xStarDestructive : Op₂ A → Op₂ A → Op₁ A → Set _StarDestructive _+_ _∙_ _* = (StarLeftDestructive _+_ _∙_ _*) × (StarRightDestructive _+_ _∙_ _*)LeftAlternative : Op₂ A → Set _LeftAlternative _∙_ = ∀ x y → ((x ∙ x) ∙ y) ≈ (x ∙ (x ∙ y))RightAlternative : Op₂ A → Set _RightAlternative _∙_ = ∀ x y → (x ∙ (y ∙ y)) ≈ ((x ∙ y) ∙ y)Alternative : Op₂ A → Set _Alternative _∙_ = (LeftAlternative _∙_ ) × (RightAlternative _∙_)Flexible : Op₂ A → Set _Flexible _∙_ = ∀ x y → ((x ∙ y) ∙ x) ≈ (x ∙ (y ∙ x))Medial : Op₂ A → Set _Medial _∙_ = ∀ x y u z → ((x ∙ y) ∙ (u ∙ z)) ≈ ((x ∙ u) ∙ (y ∙ z))LeftSemimedial : Op₂ A → Set _LeftSemimedial _∙_ = ∀ x y z → ((x ∙ x) ∙ (y ∙ z)) ≈ ((x ∙ y) ∙ (x ∙ z))RightSemimedial : Op₂ A → Set _RightSemimedial _∙_ = ∀ x y z → ((y ∙ z) ∙ (x ∙ x)) ≈ ((y ∙ x) ∙ (z ∙ x))Semimedial : Op₂ A → Set _Semimedial _∙_ = (LeftSemimedial _∙_) × (RightSemimedial _∙_)LeftBol : Op₂ A → Set _LeftBol _∙_ = ∀ x y z → (x ∙ (y ∙ (x ∙ z))) ≈ ((x ∙ (y ∙ x)) ∙ z )RightBol : Op₂ A → Set _RightBol _∙_ = ∀ x y z → (((z ∙ x) ∙ y) ∙ x) ≈ (z ∙ ((x ∙ y) ∙ x))MiddleBol : Op₂ A → Op₂ A → Op₂ A → Set _MiddleBol _∙_ _\\_ _//_ = ∀ x y z → (x ∙ ((y ∙ z) \\ x)) ≈ ((x // z) ∙ (y \\ x))Identical : Op₂ A → Set _Identical _∙_ = ∀ x y z → ((z ∙ x) ∙ (y ∙ z)) ≈ (z ∙ ((x ∙ y) ∙ z))
-------------------------------------------------------------------------- The Agda standard library---- Basic auxiliary definitions for semiring-like structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (RawSemiring)open import Data.Sum.Base using (_⊎_)open import Data.Nat.Base using (ℕ; zero; suc)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)module Algebra.Definitions.RawSemiring {a ℓ} (M : RawSemiring a ℓ) whereopen RawSemiring M renaming (Carrier to A)-------------------------------------------------------------------------- Definitions over _+_open import Algebra.Definitions.RawMonoid +-rawMonoid publicusing( _×_ -- : ℕ → A → A; _×′_ -- : ℕ → A → A; sum -- : Vector A n → A)-------------------------------------------------------------------------- Definitions over _*_open import Algebra.Definitions.RawMonoid *-rawMonoid as Mult publicusing( _∣_; _∤_)renaming( sum to product)-- Unlike `sum` to `product`, can't simply rename multiplication to-- exponentation as the argument order is reversed.-- Standard exponentiationinfixr 8 _^__^_ : A → ℕ → Ax ^ n = n Mult.× x-- Exponentiation optimised for type-checkinginfixr 8 _^′__^′_ : A → ℕ → Ax ^′ n = n Mult.×′ x{-# INLINE _^′_ #-}-- Exponentiation optimised for tail-recursioninfixr 8 _^[_]*_ _^ᵗ__^[_]*_ : A → ℕ → A → Ax ^[ zero ]* y = yx ^[ suc n ]* y = x ^[ n ]* (x * y)_^ᵗ_ : A → ℕ → Ax ^ᵗ n = x ^[ n ]* 1#-------------------------------------------------------------------------- PrimalityCoprime : Rel A (a ⊔ ℓ)Coprime x y = ∀ {z} → z ∣ x → z ∣ y → z ∣ 1#record Irreducible (p : A) : Set (a ⊔ ℓ) whereconstructor mkIrredfieldp∤1 : p ∤ 1#split-∣1 : ∀ {x y} → p ≈ (x * y) → x ∣ 1# ⊎ y ∣ 1#record Prime (p : A) : Set (a ⊔ ℓ) whereconstructor mkPrimefieldp≉0 : p ≉ 0#p∤1 : p ∤ 1#split-∣ : ∀ {x y} → p ∣ x * y → p ∣ x ⊎ p ∣ y
-------------------------------------------------------------------------- The Agda standard library---- Basic auxiliary definitions for monoid-like structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (RawMonoid)open import Data.Nat.Base as ℕ using (ℕ; zero; suc)open import Data.Vec.Functional as Vector using (Vector)module Algebra.Definitions.RawMonoid {a ℓ} (M : RawMonoid a ℓ) whereopen RawMonoid M renaming ( _∙_ to _+_ ; ε to 0# )-------------------------------------------------------------------------- Re-export definitions over a magma------------------------------------------------------------------------open import Algebra.Definitions.RawMagma rawMagma public-------------------------------------------------------------------------- Multiplication by natural number-------------------------------------------------------------------------- Standard definition-- A simple definition, easy to use and prove properties about.infixr 8 _×__×_ : ℕ → Carrier → Carrier0 × x = 0#suc n × x = x + (n × x)-------------------------------------------------------------------------- Type-checking optimised definition-- For use in code where high performance at type-checking time is-- important, e.g. solvers and tactics. Firstly it avoids unnecessarily-- multiplying by the unit if possible, speeding up type-checking and-- makes for much more readable proofs:---- Standard definition: x * 2 = x + x + 0#-- Optimised definition: x * 2 = x + x---- Secondly, associates to the left which, counterintuitive as it may-- seem, also speeds up typechecking.---- Standard definition: x * 3 = x + (x + (x + 0#))-- Our definition: x * 3 = (x + x) + xinfixl 8 _×′__×′_ : ℕ → Carrier → Carrier0 ×′ x = 0#1 ×′ x = xsuc n ×′ x = n ×′ x + x{-# INLINE _×′_ #-}-------------------------------------------------------------------------- Summation------------------------------------------------------------------------sum : ∀ {n} → Vector Carrier n → Carriersum = Vector.foldr _+_ 0#
-------------------------------------------------------------------------- The Agda standard library---- Basic auxiliary definitions for magma-like structures-------------------------------------------------------------------------- You're unlikely to want to use this module directly. Instead you-- probably want to be importing the appropriate module from-- `Algebra.Properties.(Magma/Semigroup/...).Divisibility`{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles.Raw using (RawMagma)open import Data.Product.Base using (_×_; ∃)open import Level using (_⊔_)open import Relation.Binary.Core using (Rel)open import Relation.Nullary.Negation.Core using (¬_)module Algebra.Definitions.RawMagma{a ℓ} (M : RawMagma a ℓ)whereopen RawMagma M renaming (Carrier to A)-------------------------------------------------------------------------- Divisibilityinfix 5 _∣ˡ_ _∤ˡ_ _∣ʳ_ _∤ʳ_ _∣_ _∤_ _∣∣_ _∤∤_-- Divisibility from the left.---- This and, the definition of right divisibility below, are defined as-- records rather than in terms of the base product type in order to-- make the use of pattern synonyms more ergonomic (see #2216 for-- further details). The record field names are not designed to be-- used explicitly and indeed aren't re-exported publicly by-- `Algebra.X.Properties.Divisibility` modules.record _∣ˡ_ (x y : A) : Set (a ⊔ ℓ) whereconstructor _,_fieldquotient : Aequality : x ∙ quotient ≈ y_∤ˡ_ : Rel A (a ⊔ ℓ)x ∤ˡ y = ¬ x ∣ˡ y-- Divisibility from the rightrecord _∣ʳ_ (x y : A) : Set (a ⊔ ℓ) whereconstructor _,_fieldquotient : Aequality : quotient ∙ x ≈ y_∤ʳ_ : Rel A (a ⊔ ℓ)x ∤ʳ y = ¬ x ∣ʳ y-- General divisibility-- The relations _∣ˡ_ and _∣ʳ_ are only equivalent when _∙_ is-- commutative. When that is not the case we take `_∣ʳ_` to be the-- primary one._∣_ : Rel A (a ⊔ ℓ)_∣_ = _∣ʳ__∤_ : Rel A (a ⊔ ℓ)x ∤ y = ¬ x ∣ y-------------------------------------------------------------------------- Mutual divisibility.-- In a monoid, this is an equivalence relation extending _≈_.-- When in a cancellative monoid, elements related by _∣∣_ are called-- associated, and `x ∣∣ y` means that `x` and `y` differ by some-- invertible factor.-- Example: for ℕ this is equivalent to x ≡ y,-- for ℤ this is equivalent to (x ≡ y or x ≡ - y)._∣∣_ : Rel A (a ⊔ ℓ)x ∣∣ y = x ∣ y × y ∣ x_∤∤_ : Rel A (a ⊔ ℓ)x ∤∤ y = ¬ x ∣∣ y
-------------------------------------------------------------------------- The Agda standard library---- Core algebraic definitions-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra`.{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Core whereopen import Level using (_⊔_)-------------------------------------------------------------------------- Unary and binary operationsOp₁ : ∀ {ℓ} → Set ℓ → Set ℓOp₁ A = A → AOp₂ : ∀ {ℓ} → Set ℓ → Set ℓOp₂ A = A → A → A
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic structures where the carrier is ⊤. In-- mathematics, this is usually called 0 (1 in the case of Monoid, Group).---- From monoids up, these are are zero-objects – i.e, both the initial-- and the terminal object in the relevant category.---- For structures without an identity element, the terminal algebra is-- *not* initial, because there is an instance of such a structure-- with an empty Carrier. Accordingly, such definitions are now deprecated-- in favour of those defined in `Algebra.Construct.Terminal`.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Construct.Zero {c ℓ : Level} whereopen import Algebra.Bundles.Rawusing (RawMagma)open import Algebra.Bundlesusing (Magma; Semigroup; Band)-------------------------------------------------------------------------- Re-export those algebras which are both initial and terminalopen import Algebra.Construct.Terminal publichiding (rawMagma; magma; semigroup; band)-------------------------------------------------------------------------- DEPRECATED-------------------------------------------------------------------------- Please use the new definitions re-exported from-- `Algebra.Construct.Terminal` as continuing support for the below is-- not guaranteed.-- Version 2.0rawMagma : RawMagma c ℓrawMagma = Algebra.Construct.Terminal.rawMagma{-# WARNING_ON_USAGE rawMagma"Warning: rawMagma was deprecated in v2.0.Please use Algebra.Construct.Terminal.rawMagma instead."#-}magma : Magma c ℓmagma = Algebra.Construct.Terminal.magma{-# WARNING_ON_USAGE magma"Warning: magma was deprecated in v2.0.Please use Algebra.Construct.Terminal.magma instead."#-}semigroup : Semigroup c ℓsemigroup = Algebra.Construct.Terminal.semigroup{-# WARNING_ON_USAGE semigroup"Warning: semigroup was deprecated in v2.0.Please use Algebra.Construct.Terminal.semigroup instead."#-}band : Band c ℓband = Algebra.Construct.Terminal.band{-# WARNING_ON_USAGE semigroup"Warning: semigroup was deprecated in v2.0.Please use Algebra.Construct.Terminal.semigroup instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic structures where the carrier is ⊤. In-- mathematics, this is usually called 0 (1 in the case of Monoid, Group).---- From monoids up, these are zero-objects – i.e, both the initial-- and the terminal object in the relevant category.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Construct.Terminal {c ℓ : Level} whereopen import Algebra.Bundlesopen import Data.Unit.Polymorphicopen import Relation.Binary.Core using (Rel)-------------------------------------------------------------------------- Gather all the functionality in one placemodule 𝕆ne whereinfix 4 _≈_Carrier : Set cCarrier = ⊤_≈_ : Rel Carrier ℓ_ ≈ _ = ⊤-------------------------------------------------------------------------- Raw bundlesrawMagma : RawMagma c ℓrawMagma = record { 𝕆ne }rawMonoid : RawMonoid c ℓrawMonoid = record { 𝕆ne }rawGroup : RawGroup c ℓrawGroup = record { 𝕆ne }rawNearSemiring : RawNearSemiring c ℓrawNearSemiring = record { 𝕆ne }rawSemiring : RawSemiring c ℓrawSemiring = record { 𝕆ne }rawRing : RawRing c ℓrawRing = record { 𝕆ne }-------------------------------------------------------------------------- Bundlesmagma : Magma c ℓmagma = record { 𝕆ne }semigroup : Semigroup c ℓsemigroup = record { 𝕆ne }band : Band c ℓband = record { 𝕆ne }commutativeSemigroup : CommutativeSemigroup c ℓcommutativeSemigroup = record { 𝕆ne }monoid : Monoid c ℓmonoid = record { 𝕆ne }commutativeMonoid : CommutativeMonoid c ℓcommutativeMonoid = record { 𝕆ne }idempotentCommutativeMonoid : IdempotentCommutativeMonoid c ℓidempotentCommutativeMonoid = record { 𝕆ne }group : Group c ℓgroup = record { 𝕆ne }abelianGroup : AbelianGroup c ℓabelianGroup = record { 𝕆ne }nearSemiring : NearSemiring c ℓnearSemiring = record { 𝕆ne }semiring : Semiring c ℓsemiring = record { 𝕆ne }ring : Ring c ℓring = record { 𝕆ne }
-------------------------------------------------------------------------- The Agda standard library---- Substituting equalities for binary relations-------------------------------------------------------------------------- For more general transformations between algebraic structures see-- `Algebra.Morphisms`.{-# OPTIONS --cubical-compatible --safe #-}open import Data.Product.Base as Productopen import Relation.Binary.Coremodule Algebra.Construct.Subst.Equality{a ℓ₁ ℓ₂} {A : Set a} {≈₁ : Rel A ℓ₁} {≈₂ : Rel A ℓ₂}(equiv@(to , from) : ≈₁ ⇔ ≈₂)whereopen import Algebra.Definitionsopen import Algebra.Structuresimport Data.Sum.Base as Sumopen import Function.Baseopen import Relation.Binary.Construct.Subst.Equality equiv-------------------------------------------------------------------------- Definitionscong₁ : ∀ {⁻¹} → Congruent₁ ≈₁ ⁻¹ → Congruent₁ ≈₂ ⁻¹cong₁ cong x≈y = to (cong (from x≈y))cong₂ : ∀ {∙} → Congruent₂ ≈₁ ∙ → Congruent₂ ≈₂ ∙cong₂ cong u≈v x≈y = to (cong (from u≈v) (from x≈y))assoc : ∀ {∙} → Associative ≈₁ ∙ → Associative ≈₂ ∙assoc assoc x y z = to (assoc x y z)comm : ∀ {∙} → Commutative ≈₁ ∙ → Commutative ≈₂ ∙comm comm x y = to (comm x y)idem : ∀ {∙} → Idempotent ≈₁ ∙ → Idempotent ≈₂ ∙idem idem x = to (idem x)sel : ∀ {∙} → Selective ≈₁ ∙ → Selective ≈₂ ∙sel sel x y = Sum.map to to (sel x y)identity : ∀ {∙ e} → Identity ≈₁ e ∙ → Identity ≈₂ e ∙identity = Product.map (to ∘_) (to ∘_)inverse : ∀ {∙ e ⁻¹} → Inverse ≈₁ ⁻¹ ∙ e → Inverse ≈₂ ⁻¹ ∙ einverse = Product.map (to ∘_) (to ∘_)absorptive : ∀ {∙ ◦} → Absorptive ≈₁ ∙ ◦ → Absorptive ≈₂ ∙ ◦absorptive = Product.map (λ f x y → to (f x y)) (λ f x y → to (f x y))distribˡ : ∀ {∙ ◦} → _DistributesOverˡ_ ≈₁ ∙ ◦ → _DistributesOverˡ_ ≈₂ ∙ ◦distribˡ distribˡ x y z = to (distribˡ x y z)distribʳ : ∀ {∙ ◦} → _DistributesOverʳ_ ≈₁ ∙ ◦ → _DistributesOverʳ_ ≈₂ ∙ ◦distribʳ distribʳ x y z = to (distribʳ x y z)distrib : ∀ {∙ ◦} → _DistributesOver_ ≈₁ ∙ ◦ → _DistributesOver_ ≈₂ ∙ ◦distrib {∙} {◦} = Product.map (distribˡ {∙} {◦}) (distribʳ {∙} {◦})-------------------------------------------------------------------------- StructuresisMagma : ∀ {∙} → IsMagma ≈₁ ∙ → IsMagma ≈₂ ∙isMagma S = record{ isEquivalence = isEquivalence S.isEquivalence; ∙-cong = cong₂ S.∙-cong} where module S = IsMagma SisSemigroup : ∀ {∙} → IsSemigroup ≈₁ ∙ → IsSemigroup ≈₂ ∙isSemigroup {∙} S = record{ isMagma = isMagma S.isMagma; assoc = assoc {∙} S.assoc} where module S = IsSemigroup SisBand : ∀ {∙} → IsBand ≈₁ ∙ → IsBand ≈₂ ∙isBand {∙} S = record{ isSemigroup = isSemigroup S.isSemigroup; idem = idem {∙} S.idem} where module S = IsBand SisSelectiveMagma : ∀ {∙} → IsSelectiveMagma ≈₁ ∙ → IsSelectiveMagma ≈₂ ∙isSelectiveMagma S = record{ isMagma = isMagma S.isMagma; sel = sel S.sel} where module S = IsSelectiveMagma SisMonoid : ∀ {∙ ε} → IsMonoid ≈₁ ∙ ε → IsMonoid ≈₂ ∙ εisMonoid S = record{ isSemigroup = isSemigroup S.isSemigroup; identity = Product.map (to ∘_) (to ∘_) S.identity} where module S = IsMonoid SisCommutativeMonoid : ∀ {∙ ε} →IsCommutativeMonoid ≈₁ ∙ ε → IsCommutativeMonoid ≈₂ ∙ εisCommutativeMonoid S = record{ isMonoid = isMonoid S.isMonoid; comm = comm S.comm} where module S = IsCommutativeMonoid SisIdempotentCommutativeMonoid : ∀ {∙ ε} →IsIdempotentCommutativeMonoid ≈₁ ∙ ε →IsIdempotentCommutativeMonoid ≈₂ ∙ εisIdempotentCommutativeMonoid {∙} S = record{ isCommutativeMonoid = isCommutativeMonoid S.isCommutativeMonoid; idem = to ∘ S.idem} where module S = IsIdempotentCommutativeMonoid SisGroup : ∀ {∙ ε ⁻¹} → IsGroup ≈₁ ∙ ε ⁻¹ → IsGroup ≈₂ ∙ ε ⁻¹isGroup S = record{ isMonoid = isMonoid S.isMonoid; inverse = Product.map (to ∘_) (to ∘_) S.inverse; ⁻¹-cong = cong₁ S.⁻¹-cong} where module S = IsGroup SisAbelianGroup : ∀ {∙ ε ⁻¹} →IsAbelianGroup ≈₁ ∙ ε ⁻¹ → IsAbelianGroup ≈₂ ∙ ε ⁻¹isAbelianGroup S = record{ isGroup = isGroup S.isGroup; comm = comm S.comm} where module S = IsAbelianGroup SisNearSemiring : ∀ {+ * 0#} →IsNearSemiring ≈₁ + * 0# → IsNearSemiring ≈₂ + * 0#isNearSemiring {* = *} S = record{ +-isMonoid = isMonoid S.+-isMonoid; *-cong = cong₂ S.*-cong; *-assoc = assoc {*} S.*-assoc; distribʳ = λ x y z → to (S.distribʳ x y z); zeroˡ = to ∘ S.zeroˡ} where module S = IsNearSemiring SisSemiringWithoutOne : ∀ {+ * 0#} →IsSemiringWithoutOne ≈₁ + * 0# → IsSemiringWithoutOne ≈₂ + * 0#isSemiringWithoutOne {+} {*} S = record{ +-isCommutativeMonoid = isCommutativeMonoid S.+-isCommutativeMonoid; *-cong = cong₂ S.*-cong; *-assoc = assoc {*} S.*-assoc; distrib = distrib {*} {+} S.distrib; zero = Product.map (to ∘_) (to ∘_) S.zero} where module S = IsSemiringWithoutOne SisCommutativeSemiringWithoutOne : ∀ {+ * 0#} →IsCommutativeSemiringWithoutOne ≈₁ + * 0# →IsCommutativeSemiringWithoutOne ≈₂ + * 0#isCommutativeSemiringWithoutOne S = record{ isSemiringWithoutOne = isSemiringWithoutOne S.isSemiringWithoutOne; *-comm = comm S.*-comm} where module S = IsCommutativeSemiringWithoutOne S
-------------------------------------------------------------------------- The Agda standard library---- For each `IsX` algebraic structure `S`, lift the structure to the-- 'pointwise' function space `A → S`: categorically, this is the-- *power* object in the relevant category of `X` objects and morphisms---- NB the module is parametrised only wrt `A`------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Construct.Pointwise {a} (A : Set a) whereopen import Algebra.Bundlesopen import Algebra.Core using (Op₁; Op₂)open import Algebra.Structuresopen import Data.Product.Base using (_,_)open import Function.Base using (id; _∘′_; const)open import Levelopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Structures using (IsEquivalence)privatevariablec ℓ : LevelC : Set c_≈_ : Rel C ℓε 0# 1# : C_⁻¹ -_ : Op₁ C_∙_ _+_ _*_ : Op₂ Clift₀ : C → A → Clift₀ = constlift₁ : Op₁ C → Op₁ (A → C)lift₁ = _∘′_lift₂ : Op₂ C → Op₂ (A → C)lift₂ _∙_ g h x = (g x) ∙ (h x)liftRel : Rel C ℓ → Rel (A → C) (a ⊔ ℓ)liftRel _≈_ g h = ∀ x → (g x) ≈ (h x)-------------------------------------------------------------------------- Setoid structure: here rather than elsewhere? (could be imported?)isEquivalence : IsEquivalence _≈_ → IsEquivalence (liftRel _≈_)isEquivalence isEquivalence = record{ refl = λ {f} _ → refl {f _}; sym = λ f≈g _ → sym (f≈g _); trans = λ f≈g g≈h _ → trans (f≈g _) (g≈h _)}where open IsEquivalence isEquivalence-------------------------------------------------------------------------- StructuresisMagma : IsMagma _≈_ _∙_ → IsMagma (liftRel _≈_) (lift₂ _∙_)isMagma isMagma = record{ isEquivalence = isEquivalence M.isEquivalence; ∙-cong = λ g h _ → M.∙-cong (g _) (h _)}where module M = IsMagma isMagmaisSemigroup : IsSemigroup _≈_ _∙_ → IsSemigroup (liftRel _≈_) (lift₂ _∙_)isSemigroup isSemigroup = record{ isMagma = isMagma M.isMagma; assoc = λ f g h _ → M.assoc (f _) (g _) (h _)}where module M = IsSemigroup isSemigroupisBand : IsBand _≈_ _∙_ → IsBand (liftRel _≈_) (lift₂ _∙_)isBand isBand = record{ isSemigroup = isSemigroup M.isSemigroup; idem = λ f _ → M.idem (f _)}where module M = IsBand isBandisCommutativeSemigroup : IsCommutativeSemigroup _≈_ _∙_ →IsCommutativeSemigroup (liftRel _≈_) (lift₂ _∙_)isCommutativeSemigroup isCommutativeSemigroup = record{ isSemigroup = isSemigroup M.isSemigroup; comm = λ f g _ → M.comm (f _) (g _)}where module M = IsCommutativeSemigroup isCommutativeSemigroupisMonoid : IsMonoid _≈_ _∙_ ε → IsMonoid (liftRel _≈_) (lift₂ _∙_) (lift₀ ε)isMonoid isMonoid = record{ isSemigroup = isSemigroup M.isSemigroup; identity = (λ f _ → M.identityˡ (f _)) , λ f _ → M.identityʳ (f _)}where module M = IsMonoid isMonoidisCommutativeMonoid : IsCommutativeMonoid _≈_ _∙_ ε →IsCommutativeMonoid (liftRel _≈_) (lift₂ _∙_) (lift₀ ε)isCommutativeMonoid isCommutativeMonoid = record{ isMonoid = isMonoid M.isMonoid; comm = λ f g _ → M.comm (f _) (g _)}where module M = IsCommutativeMonoid isCommutativeMonoidisGroup : IsGroup _≈_ _∙_ ε _⁻¹ →IsGroup (liftRel _≈_) (lift₂ _∙_) (lift₀ ε) (lift₁ _⁻¹)isGroup isGroup = record{ isMonoid = isMonoid M.isMonoid; inverse = (λ f _ → M.inverseˡ (f _)) , λ f _ → M.inverseʳ (f _); ⁻¹-cong = λ f _ → M.⁻¹-cong (f _)}where module M = IsGroup isGroupisAbelianGroup : IsAbelianGroup _≈_ _∙_ ε _⁻¹ →IsAbelianGroup (liftRel _≈_) (lift₂ _∙_) (lift₀ ε) (lift₁ _⁻¹)isAbelianGroup isAbelianGroup = record{ isGroup = isGroup M.isGroup; comm = λ f g _ → M.comm (f _) (g _)}where module M = IsAbelianGroup isAbelianGroupisSemiringWithoutAnnihilatingZero : IsSemiringWithoutAnnihilatingZero _≈_ _+_ _*_ 0# 1# →IsSemiringWithoutAnnihilatingZero (liftRel _≈_) (lift₂ _+_) (lift₂ _*_) (lift₀ 0#) (lift₀ 1#)isSemiringWithoutAnnihilatingZero isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = isCommutativeMonoid M.+-isCommutativeMonoid; *-cong = λ g h _ → M.*-cong (g _) (h _); *-assoc = λ f g h _ → M.*-assoc (f _) (g _) (h _); *-identity = (λ f _ → M.*-identityˡ (f _)) , λ f _ → M.*-identityʳ (f _); distrib = (λ f g h _ → M.distribˡ (f _) (g _) (h _)) , λ f g h _ → M.distribʳ (f _) (g _) (h _)}where module M = IsSemiringWithoutAnnihilatingZero isSemiringWithoutAnnihilatingZeroisSemiring : IsSemiring _≈_ _+_ _*_ 0# 1# →IsSemiring (liftRel _≈_) (lift₂ _+_) (lift₂ _*_) (lift₀ 0#) (lift₀ 1#)isSemiring isSemiring = record{ isSemiringWithoutAnnihilatingZero = isSemiringWithoutAnnihilatingZero M.isSemiringWithoutAnnihilatingZero; zero = (λ f _ → M.zeroˡ (f _)) , λ f _ → M.zeroʳ (f _)}where module M = IsSemiring isSemiringisRing : IsRing _≈_ _+_ _*_ -_ 0# 1# →IsRing (liftRel _≈_) (lift₂ _+_) (lift₂ _*_) (lift₁ -_) (lift₀ 0#) (lift₀ 1#)isRing isRing = record{ +-isAbelianGroup = isAbelianGroup M.+-isAbelianGroup; *-cong = λ g h _ → M.*-cong (g _) (h _); *-assoc = λ f g h _ → M.*-assoc (f _) (g _) (h _); *-identity = (λ f _ → M.*-identityˡ (f _)) , λ f _ → M.*-identityʳ (f _); distrib = (λ f g h _ → M.distribˡ (f _) (g _) (h _)) , λ f g h _ → M.distribʳ (f _) (g _) (h _)}where module M = IsRing isRing-------------------------------------------------------------------------- Bundlesmagma : Magma c ℓ → Magma (a ⊔ c) (a ⊔ ℓ)magma m = record { isMagma = isMagma (Magma.isMagma m) }semigroup : Semigroup c ℓ → Semigroup (a ⊔ c) (a ⊔ ℓ)semigroup m = record { isSemigroup = isSemigroup (Semigroup.isSemigroup m) }band : Band c ℓ → Band (a ⊔ c) (a ⊔ ℓ)band m = record { isBand = isBand (Band.isBand m) }commutativeSemigroup : CommutativeSemigroup c ℓ → CommutativeSemigroup (a ⊔ c) (a ⊔ ℓ)commutativeSemigroup m = record { isCommutativeSemigroup = isCommutativeSemigroup (CommutativeSemigroup.isCommutativeSemigroup m) }monoid : Monoid c ℓ → Monoid (a ⊔ c) (a ⊔ ℓ)monoid m = record { isMonoid = isMonoid (Monoid.isMonoid m) }group : Group c ℓ → Group (a ⊔ c) (a ⊔ ℓ)group m = record { isGroup = isGroup (Group.isGroup m) }abelianGroup : AbelianGroup c ℓ → AbelianGroup (a ⊔ c) (a ⊔ ℓ)abelianGroup m = record { isAbelianGroup = isAbelianGroup (AbelianGroup.isAbelianGroup m) }semiring : Semiring c ℓ → Semiring (a ⊔ c) (a ⊔ ℓ)semiring m = record { isSemiring = isSemiring (Semiring.isSemiring m) }ring : Ring c ℓ → Ring (a ⊔ c) (a ⊔ ℓ)ring m = record { isRing = isRing (Ring.isRing m) }
-------------------------------------------------------------------------- The Agda standard library---- Properties of a min operator derived from a spec over a total-- preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Construct.NaturalChoice.Baseopen import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_])open import Data.Product.Base using (_,_)open import Function.Base using (id; _∘_)open import Relation.Binary.Core using (_Preserves_⟶_; _Preserves₂_⟶_⟶_)open import Relation.Binary.Bundles using (TotalPreorder)open import Relation.Binary.Definitions using (Maximum; Minimum)open import Relation.Binary.Consequencesmodule Algebra.Construct.NaturalChoice.MinOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂} (minOp : MinOperator O) whereopen TotalPreorder O renaming( Carrier to A; _≲_ to _≤_; ≲-resp-≈ to ≤-resp-≈; ≲-respʳ-≈ to ≤-respʳ-≈; ≲-respˡ-≈ to ≤-respˡ-≈)open MinOperator minOpopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_open import Relation.Binary.Reasoning.Preorder preorder-------------------------------------------------------------------------- Helpful propertiesx⊓y≤x : ∀ x y → x ⊓ y ≤ xx⊓y≤x x y with total x y... | inj₁ x≤y = reflexive (x≤y⇒x⊓y≈x x≤y)... | inj₂ y≤x = ≤-respˡ-≈ (Eq.sym (x≥y⇒x⊓y≈y y≤x)) y≤xx⊓y≤y : ∀ x y → x ⊓ y ≤ yx⊓y≤y x y with total x y... | inj₁ x≤y = ≤-respˡ-≈ (Eq.sym (x≤y⇒x⊓y≈x x≤y)) x≤y... | inj₂ y≤x = reflexive (x≥y⇒x⊓y≈y y≤x)-------------------------------------------------------------------------- Algebraic properties⊓-comm : Commutative _⊓_⊓-comm x y with total x y... | inj₁ x≤y = Eq.trans (x≤y⇒x⊓y≈x x≤y) (Eq.sym (x≥y⇒x⊓y≈y x≤y))... | inj₂ y≤x = Eq.trans (x≥y⇒x⊓y≈y y≤x) (Eq.sym (x≤y⇒x⊓y≈x y≤x))⊓-congˡ : ∀ x → Congruent₁ (x ⊓_)⊓-congˡ x {y} {r} y≈r with total x y... | inj₁ x≤y = begin-equalityx ⊓ y ≈⟨ x≤y⇒x⊓y≈x x≤y ⟩x ≈⟨ x≤y⇒x⊓y≈x (≤-respʳ-≈ y≈r x≤y) ⟨x ⊓ r ∎... | inj₂ y≤x = begin-equalityx ⊓ y ≈⟨ x≥y⇒x⊓y≈y y≤x ⟩y ≈⟨ y≈r ⟩r ≈⟨ x≥y⇒x⊓y≈y (≤-respˡ-≈ y≈r y≤x) ⟨x ⊓ r ∎⊓-congʳ : ∀ x → Congruent₁ (_⊓ x)⊓-congʳ x {y₁} {y₂} y₁≈y₂ = begin-equalityy₁ ⊓ x ≈⟨ ⊓-comm x y₁ ⟨x ⊓ y₁ ≈⟨ ⊓-congˡ x y₁≈y₂ ⟩x ⊓ y₂ ≈⟨ ⊓-comm x y₂ ⟩y₂ ⊓ x ∎⊓-cong : Congruent₂ _⊓_⊓-cong {x₁} {x₂} {y₁} {y₂} x₁≈x₂ y₁≈y₂ = Eq.trans (⊓-congˡ x₁ y₁≈y₂) (⊓-congʳ y₂ x₁≈x₂)⊓-assoc : Associative _⊓_⊓-assoc x y r with total x y | total y r⊓-assoc x y r | inj₁ x≤y | inj₁ y≤r = begin-equality(x ⊓ y) ⊓ r ≈⟨ ⊓-congʳ r (x≤y⇒x⊓y≈x x≤y) ⟩x ⊓ r ≈⟨ x≤y⇒x⊓y≈x (trans x≤y y≤r) ⟩x ≈⟨ x≤y⇒x⊓y≈x x≤y ⟨x ⊓ y ≈⟨ ⊓-congˡ x (x≤y⇒x⊓y≈x y≤r) ⟨x ⊓ (y ⊓ r) ∎⊓-assoc x y r | inj₁ x≤y | inj₂ r≤y = begin-equality(x ⊓ y) ⊓ r ≈⟨ ⊓-congʳ r (x≤y⇒x⊓y≈x x≤y) ⟩x ⊓ r ≈⟨ ⊓-congˡ x (x≥y⇒x⊓y≈y r≤y) ⟨x ⊓ (y ⊓ r) ∎⊓-assoc x y r | inj₂ y≤x | _ = begin-equality(x ⊓ y) ⊓ r ≈⟨ ⊓-congʳ r (x≥y⇒x⊓y≈y y≤x) ⟩y ⊓ r ≈⟨ x≥y⇒x⊓y≈y (trans (x⊓y≤x y r) y≤x) ⟨x ⊓ (y ⊓ r) ∎⊓-idem : Idempotent _⊓_⊓-idem x = x≤y⇒x⊓y≈x (refl {x})⊓-sel : Selective _⊓_⊓-sel x y = Sum.map x≤y⇒x⊓y≈x x≥y⇒x⊓y≈y (total x y)⊓-identityˡ : ∀ {⊤} → Maximum _≤_ ⊤ → LeftIdentity ⊤ _⊓_⊓-identityˡ max = x≥y⇒x⊓y≈y ∘ max⊓-identityʳ : ∀ {⊤} → Maximum _≤_ ⊤ → RightIdentity ⊤ _⊓_⊓-identityʳ max = x≤y⇒x⊓y≈x ∘ max⊓-identity : ∀ {⊤} → Maximum _≤_ ⊤ → Identity ⊤ _⊓_⊓-identity max = ⊓-identityˡ max , ⊓-identityʳ max⊓-zeroˡ : ∀ {⊥} → Minimum _≤_ ⊥ → LeftZero ⊥ _⊓_⊓-zeroˡ min = x≤y⇒x⊓y≈x ∘ min⊓-zeroʳ : ∀ {⊥} → Minimum _≤_ ⊥ → RightZero ⊥ _⊓_⊓-zeroʳ min = x≥y⇒x⊓y≈y ∘ min⊓-zero : ∀ {⊥} → Minimum _≤_ ⊥ → Zero ⊥ _⊓_⊓-zero min = ⊓-zeroˡ min , ⊓-zeroʳ min-------------------------------------------------------------------------- Structures⊓-isMagma : IsMagma _⊓_⊓-isMagma = record{ isEquivalence = isEquivalence; ∙-cong = ⊓-cong}⊓-isSemigroup : IsSemigroup _⊓_⊓-isSemigroup = record{ isMagma = ⊓-isMagma; assoc = ⊓-assoc}⊓-isBand : IsBand _⊓_⊓-isBand = record{ isSemigroup = ⊓-isSemigroup; idem = ⊓-idem}⊓-isCommutativeSemigroup : IsCommutativeSemigroup _⊓_⊓-isCommutativeSemigroup = record{ isSemigroup = ⊓-isSemigroup; comm = ⊓-comm}⊓-isSelectiveMagma : IsSelectiveMagma _⊓_⊓-isSelectiveMagma = record{ isMagma = ⊓-isMagma; sel = ⊓-sel}⊓-isMonoid : ∀ {⊤} → Maximum _≤_ ⊤ → IsMonoid _⊓_ ⊤⊓-isMonoid max = record{ isSemigroup = ⊓-isSemigroup; identity = ⊓-identity max}-------------------------------------------------------------------------- Raw bundles⊓-rawMagma : RawMagma _ _⊓-rawMagma = record { _≈_ = _≈_ ; _∙_ = _⊓_ }-------------------------------------------------------------------------- Bundles⊓-magma : Magma _ _⊓-magma = record{ isMagma = ⊓-isMagma}⊓-semigroup : Semigroup _ _⊓-semigroup = record{ isSemigroup = ⊓-isSemigroup}⊓-band : Band _ _⊓-band = record{ isBand = ⊓-isBand}⊓-commutativeSemigroup : CommutativeSemigroup _ _⊓-commutativeSemigroup = record{ isCommutativeSemigroup = ⊓-isCommutativeSemigroup}⊓-selectiveMagma : SelectiveMagma _ _⊓-selectiveMagma = record{ isSelectiveMagma = ⊓-isSelectiveMagma}⊓-monoid : ∀ {⊤} → Maximum _≤_ ⊤ → Monoid a ℓ₁⊓-monoid max = record{ isMonoid = ⊓-isMonoid max}-------------------------------------------------------------------------- Other propertiesx⊓y≈x⇒x≤y : ∀ {x y} → x ⊓ y ≈ x → x ≤ yx⊓y≈x⇒x≤y {x} {y} x⊓y≈x with total x y... | inj₁ x≤y = x≤y... | inj₂ y≤x = reflexive (Eq.trans (Eq.sym x⊓y≈x) (x≥y⇒x⊓y≈y y≤x))x⊓y≈y⇒y≤x : ∀ {x y} → x ⊓ y ≈ y → y ≤ xx⊓y≈y⇒y≤x {x} {y} x⊓y≈y = x⊓y≈x⇒x≤y (begin-equalityy ⊓ x ≈⟨ ⊓-comm y x ⟩x ⊓ y ≈⟨ x⊓y≈y ⟩y ∎)mono-≤-distrib-⊓ : ∀ {f} → f Preserves _≈_ ⟶ _≈_ → f Preserves _≤_ ⟶ _≤_ →∀ x y → f (x ⊓ y) ≈ f x ⊓ f ymono-≤-distrib-⊓ {f} cong mono x y with total x y... | inj₁ x≤y = begin-equalityf (x ⊓ y) ≈⟨ cong (x≤y⇒x⊓y≈x x≤y) ⟩f x ≈⟨ x≤y⇒x⊓y≈x (mono x≤y) ⟨f x ⊓ f y ∎... | inj₂ y≤x = begin-equalityf (x ⊓ y) ≈⟨ cong (x≥y⇒x⊓y≈y y≤x) ⟩f y ≈⟨ x≥y⇒x⊓y≈y (mono y≤x) ⟨f x ⊓ f y ∎x≤y⇒x⊓z≤y : ∀ {x y} z → x ≤ y → x ⊓ z ≤ yx≤y⇒x⊓z≤y z x≤y = trans (x⊓y≤x _ z) x≤yx≤y⇒z⊓x≤y : ∀ {x y} z → x ≤ y → z ⊓ x ≤ yx≤y⇒z⊓x≤y y x≤y = trans (x⊓y≤y y _) x≤yx≤y⊓z⇒x≤y : ∀ {x} y z → x ≤ y ⊓ z → x ≤ yx≤y⊓z⇒x≤y y z x≤y⊓z = trans x≤y⊓z (x⊓y≤x y z)x≤y⊓z⇒x≤z : ∀ {x} y z → x ≤ y ⊓ z → x ≤ zx≤y⊓z⇒x≤z y z x≤y⊓z = trans x≤y⊓z (x⊓y≤y y z)⊓-mono-≤ : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊓-mono-≤ {x} {y} {u} {v} x≤y u≤v with ⊓-sel y v... | inj₁ y⊓v≈y = ≤-respʳ-≈ (Eq.sym y⊓v≈y) (trans (x⊓y≤x x u) x≤y)... | inj₂ y⊓v≈v = ≤-respʳ-≈ (Eq.sym y⊓v≈v) (trans (x⊓y≤y x u) u≤v)⊓-monoˡ-≤ : ∀ x → (_⊓ x) Preserves _≤_ ⟶ _≤_⊓-monoˡ-≤ x y≤z = ⊓-mono-≤ y≤z (refl {x})⊓-monoʳ-≤ : ∀ x → (x ⊓_) Preserves _≤_ ⟶ _≤_⊓-monoʳ-≤ x y≤z = ⊓-mono-≤ (refl {x}) y≤z⊓-glb : ∀ {x y z} → x ≤ y → x ≤ z → x ≤ y ⊓ z⊓-glb {x} x≤y x≤z = ≤-respˡ-≈ (⊓-idem x) (⊓-mono-≤ x≤y x≤z)⊓-triangulate : ∀ x y z → x ⊓ y ⊓ z ≈ (x ⊓ y) ⊓ (y ⊓ z)⊓-triangulate x y z = begin-equalityx ⊓ y ⊓ z ≈⟨ ⊓-congʳ z (⊓-congˡ x (⊓-idem y)) ⟨x ⊓ (y ⊓ y) ⊓ z ≈⟨ ⊓-assoc x _ _ ⟩x ⊓ ((y ⊓ y) ⊓ z) ≈⟨ ⊓-congˡ x (⊓-assoc y y z) ⟩x ⊓ (y ⊓ (y ⊓ z)) ≈⟨ ⊓-assoc x y (y ⊓ z) ⟨(x ⊓ y) ⊓ (y ⊓ z) ∎
-------------------------------------------------------------------------- The Agda standard library---- Properties of min and max operators specified over a total-- preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Construct.NaturalChoice.Baseopen import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_])open import Data.Product.Base using (_,_)open import Function.Base using (id; _∘_; flip)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundles using (TotalPreorder)open import Relation.Binary.Consequencesmodule Algebra.Construct.NaturalChoice.MinMaxOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂}(minOp : MinOperator O)(maxOp : MaxOperator O)whereopen TotalPreorder O renaming( Carrier to A; _≲_ to _≤_; ≲-resp-≈ to ≤-resp-≈; ≲-respʳ-≈ to ≤-respʳ-≈; ≲-respˡ-≈ to ≤-respˡ-≈)open MinOperator minOpopen MaxOperator maxOpopen import Algebra.Definitions _≈_open import Algebra.Structures _≈_open import Algebra.Consequences.Setoid Eq.setoidopen import Relation.Binary.Reasoning.Preorder preorder-------------------------------------------------------------------------- Re-export properties of individual operatorsopen import Algebra.Construct.NaturalChoice.MinOp minOp publicopen import Algebra.Construct.NaturalChoice.MaxOp maxOp public-------------------------------------------------------------------------- Joint algebraic structures⊓-distribˡ-⊔ : _⊓_ DistributesOverˡ _⊔_⊓-distribˡ-⊔ x y z with total y z... | inj₁ y≤z = begin-equalityx ⊓ (y ⊔ z) ≈⟨ ⊓-congˡ x (x≤y⇒x⊔y≈y y≤z) ⟩x ⊓ z ≈⟨ x≤y⇒x⊔y≈y (⊓-monoʳ-≤ x y≤z) ⟨(x ⊓ y) ⊔ (x ⊓ z) ∎... | inj₂ y≥z = begin-equalityx ⊓ (y ⊔ z) ≈⟨ ⊓-congˡ x (x≥y⇒x⊔y≈x y≥z) ⟩x ⊓ y ≈⟨ x≥y⇒x⊔y≈x (⊓-monoʳ-≤ x y≥z) ⟨(x ⊓ y) ⊔ (x ⊓ z) ∎⊓-distribʳ-⊔ : _⊓_ DistributesOverʳ _⊔_⊓-distribʳ-⊔ = comm+distrˡ⇒distrʳ ⊔-cong ⊓-comm ⊓-distribˡ-⊔⊓-distrib-⊔ : _⊓_ DistributesOver _⊔_⊓-distrib-⊔ = ⊓-distribˡ-⊔ , ⊓-distribʳ-⊔⊔-distribˡ-⊓ : _⊔_ DistributesOverˡ _⊓_⊔-distribˡ-⊓ x y z with total y z... | inj₁ y≤z = begin-equalityx ⊔ (y ⊓ z) ≈⟨ ⊔-congˡ x (x≤y⇒x⊓y≈x y≤z) ⟩x ⊔ y ≈⟨ x≤y⇒x⊓y≈x (⊔-monoʳ-≤ x y≤z) ⟨(x ⊔ y) ⊓ (x ⊔ z) ∎... | inj₂ y≥z = begin-equalityx ⊔ (y ⊓ z) ≈⟨ ⊔-congˡ x (x≥y⇒x⊓y≈y y≥z) ⟩x ⊔ z ≈⟨ x≥y⇒x⊓y≈y (⊔-monoʳ-≤ x y≥z) ⟨(x ⊔ y) ⊓ (x ⊔ z) ∎⊔-distribʳ-⊓ : _⊔_ DistributesOverʳ _⊓_⊔-distribʳ-⊓ = comm+distrˡ⇒distrʳ ⊓-cong ⊔-comm ⊔-distribˡ-⊓⊔-distrib-⊓ : _⊔_ DistributesOver _⊓_⊔-distrib-⊓ = ⊔-distribˡ-⊓ , ⊔-distribʳ-⊓⊓-absorbs-⊔ : _⊓_ Absorbs _⊔_⊓-absorbs-⊔ x y with total x y... | inj₁ x≤y = begin-equalityx ⊓ (x ⊔ y) ≈⟨ ⊓-congˡ x (x≤y⇒x⊔y≈y x≤y) ⟩x ⊓ y ≈⟨ x≤y⇒x⊓y≈x x≤y ⟩x ∎... | inj₂ y≤x = begin-equalityx ⊓ (x ⊔ y) ≈⟨ ⊓-congˡ x (x≥y⇒x⊔y≈x y≤x) ⟩x ⊓ x ≈⟨ ⊓-idem x ⟩x ∎⊔-absorbs-⊓ : _⊔_ Absorbs _⊓_⊔-absorbs-⊓ x y with total x y... | inj₁ x≤y = begin-equalityx ⊔ (x ⊓ y) ≈⟨ ⊔-congˡ x (x≤y⇒x⊓y≈x x≤y) ⟩x ⊔ x ≈⟨ ⊔-idem x ⟩x ∎... | inj₂ y≤x = begin-equalityx ⊔ (x ⊓ y) ≈⟨ ⊔-congˡ x (x≥y⇒x⊓y≈y y≤x) ⟩x ⊔ y ≈⟨ x≥y⇒x⊔y≈x y≤x ⟩x ∎⊔-⊓-absorptive : Absorptive _⊔_ _⊓_⊔-⊓-absorptive = ⊔-absorbs-⊓ , ⊓-absorbs-⊔⊓-⊔-absorptive : Absorptive _⊓_ _⊔_⊓-⊔-absorptive = ⊓-absorbs-⊔ , ⊔-absorbs-⊓-------------------------------------------------------------------------- Other joint propertiesprivate _≥_ = flip _≤_antimono-≤-distrib-⊓ : ∀ {f} → f Preserves _≈_ ⟶ _≈_ → f Preserves _≤_ ⟶ _≥_ →∀ x y → f (x ⊓ y) ≈ f x ⊔ f yantimono-≤-distrib-⊓ {f} cong antimono x y with total x y... | inj₁ x≤y = begin-equalityf (x ⊓ y) ≈⟨ cong (x≤y⇒x⊓y≈x x≤y) ⟩f x ≈⟨ x≥y⇒x⊔y≈x (antimono x≤y) ⟨f x ⊔ f y ∎... | inj₂ y≤x = begin-equalityf (x ⊓ y) ≈⟨ cong (x≥y⇒x⊓y≈y y≤x) ⟩f y ≈⟨ x≤y⇒x⊔y≈y (antimono y≤x) ⟨f x ⊔ f y ∎antimono-≤-distrib-⊔ : ∀ {f} → f Preserves _≈_ ⟶ _≈_ → f Preserves _≤_ ⟶ _≥_ →∀ x y → f (x ⊔ y) ≈ f x ⊓ f yantimono-≤-distrib-⊔ {f} cong antimono x y with total x y... | inj₁ x≤y = begin-equalityf (x ⊔ y) ≈⟨ cong (x≤y⇒x⊔y≈y x≤y) ⟩f y ≈⟨ x≥y⇒x⊓y≈y (antimono x≤y) ⟨f x ⊓ f y ∎... | inj₂ y≤x = begin-equalityf (x ⊔ y) ≈⟨ cong (x≥y⇒x⊔y≈x y≤x) ⟩f x ≈⟨ x≤y⇒x⊓y≈x (antimono y≤x) ⟨f x ⊓ f y ∎x⊓y≤x⊔y : ∀ x y → x ⊓ y ≤ x ⊔ yx⊓y≤x⊔y x y = beginx ⊓ y ∼⟨ x⊓y≤x x y ⟩x ∼⟨ x≤x⊔y x y ⟩x ⊔ y ∎
-------------------------------------------------------------------------- The Agda standard library---- The min operator derived from an arbitrary total preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Bundlesopen import Algebra.Construct.NaturalChoice.Baseopen import Data.Sum.Base using (inj₁; inj₂; [_,_])open import Data.Product.Base using (_,_)open import Function.Base using (id)open import Relation.Binary.Bundles using (TotalOrder)import Algebra.Construct.NaturalChoice.MinOp as MinOpmodule Algebra.Construct.NaturalChoice.Min{a ℓ₁ ℓ₂} (O : TotalOrder a ℓ₁ ℓ₂)whereopen TotalOrder O renaming (Carrier to A)-------------------------------------------------------------------------- Definitioninfixl 7 _⊓__⊓_ : Op₂ Ax ⊓ y with total x y... | inj₁ x≤y = x... | inj₂ y≤x = y-------------------------------------------------------------------------- Propertiesx≤y⇒x⊓y≈x : ∀ {x y} → x ≤ y → x ⊓ y ≈ xx≤y⇒x⊓y≈x {x} {y} x≤y with total x y... | inj₁ _ = Eq.refl... | inj₂ y≤x = antisym y≤x x≤yx≤y⇒y⊓x≈x : ∀ {x y} → x ≤ y → y ⊓ x ≈ xx≤y⇒y⊓x≈x {x} {y} x≤y with total y x... | inj₁ y≤x = antisym y≤x x≤y... | inj₂ _ = Eq.reflminOperator : MinOperator totalPreorderminOperator = record{ x≤y⇒x⊓y≈x = x≤y⇒x⊓y≈x; x≥y⇒x⊓y≈y = x≤y⇒y⊓x≈x}open MinOp minOperator public
-------------------------------------------------------------------------- The Agda standard library---- Properties of a max operator derived from a spec over a total-- preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Algebra.Construct.NaturalChoice.Baseimport Algebra.Construct.NaturalChoice.MinOp as MinOpopen import Function.Base using (flip)open import Relation.Binary.Core using (_Preserves_⟶_)open import Relation.Binary.Bundles using (TotalPreorder)open import Relation.Binary.Construct.Flip.EqAndOrd using ()renaming (totalPreorder to flipOrder)module Algebra.Construct.NaturalChoice.MaxOp{a ℓ₁ ℓ₂} {O : TotalPreorder a ℓ₁ ℓ₂} (maxOp : MaxOperator O)whereopen TotalPreorder O renaming (Carrier to A; _≲_ to _≤_)open MaxOperator maxOp-- Max is just min with a flipped orderprivatemodule Min = MinOp (MaxOp⇒MinOp maxOp)open Min publicusing ()renaming( ⊓-cong to ⊔-cong; ⊓-congʳ to ⊔-congʳ; ⊓-congˡ to ⊔-congˡ; ⊓-idem to ⊔-idem; ⊓-sel to ⊔-sel; ⊓-assoc to ⊔-assoc; ⊓-comm to ⊔-comm; ⊓-identityˡ to ⊔-identityˡ; ⊓-identityʳ to ⊔-identityʳ; ⊓-identity to ⊔-identity; ⊓-zeroˡ to ⊔-zeroˡ; ⊓-zeroʳ to ⊔-zeroʳ; ⊓-zero to ⊔-zero; ⊓-isMagma to ⊔-isMagma; ⊓-isSemigroup to ⊔-isSemigroup; ⊓-isCommutativeSemigroup to ⊔-isCommutativeSemigroup; ⊓-isBand to ⊔-isBand; ⊓-isMonoid to ⊔-isMonoid; ⊓-isSelectiveMagma to ⊔-isSelectiveMagma; ⊓-magma to ⊔-magma; ⊓-semigroup to ⊔-semigroup; ⊓-commutativeSemigroup to ⊔-commutativeSemigroup; ⊓-band to ⊔-band; ⊓-monoid to ⊔-monoid; ⊓-selectiveMagma to ⊔-selectiveMagma; x⊓y≈y⇒y≤x to x⊔y≈y⇒x≤y; x⊓y≈x⇒x≤y to x⊔y≈x⇒y≤x; x⊓y≤x to x≤x⊔y; x⊓y≤y to x≤y⊔x; x≤y⇒x⊓z≤y to x≤y⇒x≤y⊔z; x≤y⇒z⊓x≤y to x≤y⇒x≤z⊔y; x≤y⊓z⇒x≤y to x⊔y≤z⇒x≤z; x≤y⊓z⇒x≤z to x⊔y≤z⇒y≤z; ⊓-glb to ⊔-lub; ⊓-triangulate to ⊔-triangulate; ⊓-mono-≤ to ⊔-mono-≤; ⊓-monoˡ-≤ to ⊔-monoˡ-≤; ⊓-monoʳ-≤ to ⊔-monoʳ-≤)mono-≤-distrib-⊔ : ∀ {f} → f Preserves _≈_ ⟶ _≈_ → f Preserves _≤_ ⟶ _≤_ →∀ x y → f (x ⊔ y) ≈ f x ⊔ f ymono-≤-distrib-⊔ cong pres = Min.mono-≤-distrib-⊓ cong pres
-------------------------------------------------------------------------- The Agda standard library---- The max operator derived from an arbitrary total preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Bundles using (TotalOrder)module Algebra.Construct.NaturalChoice.Max{a ℓ₁ ℓ₂} (totalOrder : TotalOrder a ℓ₁ ℓ₂) whereopen import Algebra.Coreopen import Algebra.Definitionsopen import Algebra.Construct.NaturalChoice.Baseopen import Relation.Binary.Construct.Flip.EqAndOrd using ()renaming (totalOrder to flip)open TotalOrder totalOrder renaming (Carrier to A)-------------------------------------------------------------------------- Max is just min with a flipped orderimport Algebra.Construct.NaturalChoice.Min (flip totalOrder) as Mininfixl 6 _⊔__⊔_ : Op₂ A_⊔_ = Min._⊓_-------------------------------------------------------------------------- Propertiesopen Min public using ()renaming( x≤y⇒x⊓y≈x to x≤y⇒y⊔x≈y; x≤y⇒y⊓x≈x to x≤y⇒x⊔y≈y)maxOperator : MaxOperator totalPreordermaxOperator = record{ x≤y⇒x⊔y≈y = x≤y⇒x⊔y≈y; x≥y⇒x⊔y≈x = x≤y⇒y⊔x≈y}open import Algebra.Construct.NaturalChoice.MaxOp maxOperator public
-------------------------------------------------------------------------- The Agda standard library---- Basic definition of an operator that computes the min/max value-- with respect to a total preorder.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Coreopen import Level as L hiding (_⊔_)open import Function.Base using (flip)open import Relation.Binary.Bundles using (TotalPreorder)open import Relation.Binary.Construct.Flip.EqAndOrd using ()renaming (totalPreorder to flipOrder)import Relation.Binary.Properties.TotalOrder as TotalOrderPropertiesmodule Algebra.Construct.NaturalChoice.Base whereprivatevariablea ℓ₁ ℓ₂ : LevelO : TotalPreorder a ℓ₁ ℓ₂-------------------------------------------------------------------------- Definitionmodule _ (O : TotalPreorder a ℓ₁ ℓ₂) whereopen TotalPreorder O renaming (_≲_ to _≤_)private _≥_ = flip _≤_record MinOperator : Set (a L.⊔ ℓ₁ L.⊔ ℓ₂) whereinfixl 7 _⊓_field_⊓_ : Op₂ Carrierx≤y⇒x⊓y≈x : ∀ {x y} → x ≤ y → x ⊓ y ≈ xx≥y⇒x⊓y≈y : ∀ {x y} → x ≥ y → x ⊓ y ≈ yrecord MaxOperator : Set (a L.⊔ ℓ₁ L.⊔ ℓ₂) whereinfixl 6 _⊔_field_⊔_ : Op₂ Carrierx≤y⇒x⊔y≈y : ∀ {x y} → x ≤ y → x ⊔ y ≈ yx≥y⇒x⊔y≈x : ∀ {x y} → x ≥ y → x ⊔ y ≈ x-------------------------------------------------------------------------- PropertiesMinOp⇒MaxOp : MinOperator O → MaxOperator (flipOrder O)MinOp⇒MaxOp minOp = record{ _⊔_ = _⊓_; x≤y⇒x⊔y≈y = x≥y⇒x⊓y≈y; x≥y⇒x⊔y≈x = x≤y⇒x⊓y≈x} where open MinOperator minOpMaxOp⇒MinOp : MaxOperator O → MinOperator (flipOrder O)MaxOp⇒MinOp maxOp = record{ _⊓_ = _⊔_; x≤y⇒x⊓y≈x = x≥y⇒x⊔y≈x; x≥y⇒x⊓y≈y = x≤y⇒x⊔y≈y} where open MaxOperator maxOp
-------------------------------------------------------------------------- The Agda standard library---- Choosing between elements based on the result of applying a function------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebramodule Algebra.Construct.LiftedChoice whereopen import Algebra.Consequences.Baseopen import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]; [_,_]′)open import Data.Product.Base using (_×_; _,_)open import Function.Base using (const; _$_)open import Level using (Level; _⊔_)open import Relation.Binary.Core using (Rel; _⇒_; _Preserves_⟶_)open import Relation.Nullary using (¬_; yes; no)open import Relation.Binary.PropositionalEquality.Core as ≡ using (_≡_)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Unary using (Pred)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningprivatevariablea b p ℓ : LevelA : Set aB : Set b-------------------------------------------------------------------------- Definitionmodule _ (_≈_ : Rel B ℓ) (_•_ : Op₂ B) whereLift : Selective _≈_ _•_ → (A → B) → Op₂ ALift ∙-sel f x y = [ const x , const y ]′ $ ∙-sel (f x) (f y)-------------------------------------------------------------------------- Algebraic propertiesmodule _ {_≈_ : Rel B ℓ} {_∙_ : Op₂ B}(∙-isSelectiveMagma : IsSelectiveMagma _≈_ _∙_) whereprivate module M = IsSelectiveMagma ∙-isSelectiveMagmaopen M hiding (sel; isMagma)open ≈-Reasoning setoidmodule _ (f : A → B) whereprivate_◦_ = Lift _≈_ _∙_ M.sel fsel-≡ : Selective _≡_ _◦_sel-≡ x y with M.sel (f x) (f y)... | inj₁ _ = inj₁ ≡.refl... | inj₂ _ = inj₂ ≡.refldistrib : ∀ x y → ((f x) ∙ (f y)) ≈ f (x ◦ y)distrib x y with M.sel (f x) (f y)... | inj₁ fx∙fy≈fx = fx∙fy≈fx... | inj₂ fx∙fy≈fy = fx∙fy≈fymodule _ (f : A → B) {_≈′_ : Rel A ℓ}(≈-reflexive : _≡_ ⇒ _≈′_) whereprivate_◦_ = Lift _≈_ _∙_ M.sel fsel : Selective _≈′_ _◦_sel x y = Sum.map ≈-reflexive ≈-reflexive (sel-≡ f x y)idem : Idempotent _≈′_ _◦_idem = sel⇒idem _≈′_ selmodule _ {f : A → B} {_≈′_ : Rel A ℓ}(f-injective : ∀ {x y} → f x ≈ f y → x ≈′ y)whereprivate_◦_ = Lift _≈_ _∙_ M.sel fcong : f Preserves _≈′_ ⟶ _≈_ → Congruent₂ _≈′_ _◦_cong f-cong {x} {y} {u} {v} x≈y u≈vwith M.sel (f x) (f u) | M.sel (f y) (f v)... | inj₁ fx∙fu≈fx | inj₁ fy∙fv≈fy = x≈y... | inj₂ fx∙fu≈fu | inj₂ fy∙fv≈fv = u≈v... | inj₁ fx∙fu≈fx | inj₂ fy∙fv≈fv = f-injective (beginf x ≈⟨ sym fx∙fu≈fx ⟩f x ∙ f u ≈⟨ ∙-cong (f-cong x≈y) (f-cong u≈v) ⟩f y ∙ f v ≈⟨ fy∙fv≈fv ⟩f v ∎)... | inj₂ fx∙fu≈fu | inj₁ fy∙fv≈fy = f-injective (beginf u ≈⟨ sym fx∙fu≈fu ⟩f x ∙ f u ≈⟨ ∙-cong (f-cong x≈y) (f-cong u≈v) ⟩f y ∙ f v ≈⟨ fy∙fv≈fy ⟩f y ∎)assoc : Associative _≈_ _∙_ → Associative _≈′_ _◦_assoc ∙-assoc x y z = f-injective (beginf ((x ◦ y) ◦ z) ≈⟨ distrib f (x ◦ y) z ⟨f (x ◦ y) ∙ f z ≈⟨ ∙-congʳ (distrib f x y) ⟨(f x ∙ f y) ∙ f z ≈⟨ ∙-assoc (f x) (f y) (f z) ⟩f x ∙ (f y ∙ f z) ≈⟨ ∙-congˡ (distrib f y z) ⟩f x ∙ f (y ◦ z) ≈⟨ distrib f x (y ◦ z) ⟩f (x ◦ (y ◦ z)) ∎)comm : Commutative _≈_ _∙_ → Commutative _≈′_ _◦_comm ∙-comm x y = f-injective (beginf (x ◦ y) ≈⟨ distrib f x y ⟨f x ∙ f y ≈⟨ ∙-comm (f x) (f y) ⟩f y ∙ f x ≈⟨ distrib f y x ⟩f (y ◦ x) ∎)-------------------------------------------------------------------------- Algebraic structuresmodule _ {_≈′_ : Rel A ℓ} {f : A → B}(f-injective : ∀ {x y} → f x ≈ f y → x ≈′ y)(f-cong : f Preserves _≈′_ ⟶ _≈_)(≈′-isEquivalence : IsEquivalence _≈′_)whereprivatemodule E = IsEquivalence ≈′-isEquivalence_◦_ = Lift _≈_ _∙_ M.sel fisMagma : IsMagma _≈′_ _◦_isMagma = record{ isEquivalence = ≈′-isEquivalence; ∙-cong = cong (λ {x} → f-injective {x}) f-cong}isSemigroup : Associative _≈_ _∙_ → IsSemigroup _≈′_ _◦_isSemigroup ∙-assoc = record{ isMagma = isMagma; assoc = assoc (λ {x} → f-injective {x}) ∙-assoc}isBand : Associative _≈_ _∙_ → IsBand _≈′_ _◦_isBand ∙-assoc = record{ isSemigroup = isSemigroup ∙-assoc; idem = idem f E.reflexive}isSelectiveMagma : IsSelectiveMagma _≈′_ _◦_isSelectiveMagma = record{ isMagma = isMagma; sel = sel f E.reflexive}-------------------------------------------------------------------------- Other propertiesmodule _ {P : Pred A p} (f : A → B) whereprivate_◦_ = Lift _≈_ _∙_ M.sel fpreservesᵒ : (∀ {x y} → P x → (f x ∙ f y) ≈ f y → P y) →(∀ {x y} → P y → (f x ∙ f y) ≈ f x → P x) →∀ x y → P x ⊎ P y → P (x ◦ y)preservesᵒ left right x y (inj₁ px) with M.sel (f x) (f y)... | inj₁ _ = px... | inj₂ fx∙fy≈fx = left px fx∙fy≈fxpreservesᵒ left right x y (inj₂ py) with M.sel (f x) (f y)... | inj₁ fx∙fy≈fy = right py fx∙fy≈fy... | inj₂ _ = pypreservesʳ : (∀ {x y} → P y → (f x ∙ f y) ≈ f x → P x) →∀ x {y} → P y → P (x ◦ y)preservesʳ right x {y} Py with M.sel (f x) (f y)... | inj₁ fx∙fy≈fx = right Py fx∙fy≈fx... | inj₂ fx∙fy≈fy = Pypreservesᵇ : ∀ {x y} → P x → P y → P (x ◦ y)preservesᵇ {x} {y} Px Py with M.sel (f x) (f y)... | inj₁ _ = Px... | inj₂ _ = Pyforcesᵇ : (∀ {x y} → P x → (f x ∙ f y) ≈ f x → P y) →(∀ {x y} → P y → (f x ∙ f y) ≈ f y → P x) →∀ x y → P (x ◦ y) → P x × P yforcesᵇ presˡ presʳ x y P[x∙y] with M.sel (f x) (f y)... | inj₁ fx∙fy≈fx = P[x∙y] , presˡ P[x∙y] fx∙fy≈fx... | inj₂ fx∙fy≈fy = presʳ P[x∙y] fx∙fy≈fy , P[x∙y]
-------------------------------------------------------------------------- The Agda standard library---- Definitions of the lexicographic product of two operators.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Bundles using (Magma)open import Algebra.Definitionsopen import Data.Bool.Base using (true; false)open import Data.Product.Base using (_×_; _,_)open import Data.Product.Relation.Binary.Pointwise.NonDependent using (Pointwise)open import Data.Sum.Base using (inj₁; inj₂; map)open import Function.Base using (_∘_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary.Decidable.Core using (does; yes; no)open import Relation.Nullary.Negation.Core using (¬_; contradiction; contradiction₂)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningmodule Algebra.Construct.LexProduct{ℓ₁ ℓ₂ ℓ₃ ℓ₄} (M : Magma ℓ₁ ℓ₂) (N : Magma ℓ₃ ℓ₄)(_≟₁_ : Decidable (Magma._≈_ M))whereopen Magma M using (_∙_ ; ∙-cong)renaming( Carrier to A; _≈_ to _≈₁_; _≉_ to _≉₁_)open Magma N using ()renaming( Carrier to B; _∙_ to _◦_; _≈_ to _≈₂_; refl to ≈₂-refl)import Algebra.Construct.LexProduct.Inner M N _≟₁_ as InnerLexprivateinfix 4 _≋__≋_ : Rel (A × B) __≋_ = Pointwise _≈₁_ _≈₂_variablea b : A-------------------------------------------------------------------------- Definition------------------------------------------------------------------------open import Algebra.Construct.LexProduct.Base _∙_ _◦_ _≟₁_ publicrenaming (lex to _⊕_)-------------------------------------------------------------------------- Properties-------------------------------------------------------------------------- Basic casescase₁ : ∀ {a b} → (a ∙ b) ≈₁ a → (a ∙ b) ≉₁ b →∀ x y → (a , x) ⊕ (b , y) ≋ (a , x)case₁ ab≈a ab≉b _ _ = ab≈a , InnerLex.case₁ ab≈a ab≉bcase₂ : ∀ {a b} → (a ∙ b) ≉₁ a → (a ∙ b) ≈₁ b →∀ x y → (a , x) ⊕ (b , y) ≋ (b , y)case₂ ab≉a ab≈b _ _ = ab≈b , InnerLex.case₂ ab≉a ab≈bcase₃ : ∀ {a b} → (a ∙ b) ≈₁ a → (a ∙ b) ≈₁ b →∀ x y → (a , x) ⊕ (b , y) ≋ (a , x ◦ y)case₃ ab≈a ab≈b _ _ = ab≈a , InnerLex.case₃ ab≈a ab≈b-------------------------------------------------------------------------- Algebraic propertiescong : Congruent₂ _≋_ _⊕_cong (a≈b , w≈x) (c≈d , y≈z) =∙-cong a≈b c≈d ,InnerLex.cong a≈b c≈d w≈x y≈zassoc : Associative _≈₁_ _∙_ → Commutative _≈₁_ _∙_ →Selective _≈₁_ _∙_ → Associative _≈₂_ _◦_ →Associative _≋_ _⊕_assoc ∙-assoc ∙-comm ∙-sel ◦-assoc (a , x) (b , y) (c , z) =∙-assoc a b c ,InnerLex.assoc ∙-assoc ∙-comm ∙-sel ◦-assoc a b c x y zcomm : Commutative _≈₁_ _∙_ → Commutative _≈₂_ _◦_ →Commutative _≋_ _⊕_comm ∙-comm ◦-comm (a , x) (b , y) =∙-comm a b ,InnerLex.comm ∙-comm ◦-comm a b x yzeroʳ : ∀ {e f} → RightZero _≈₁_ e _∙_ → RightZero _≈₂_ f _◦_ →RightZero _≋_ (e , f) _⊕_zeroʳ ze₁ ze₂ (x , a) = ze₁ x , InnerLex.zeroʳ ze₁ ze₂identityʳ : ∀ {e f} → RightIdentity _≈₁_ e _∙_ → RightIdentity _≈₂_ f _◦_ →RightIdentity _≋_ (e , f) _⊕_identityʳ id₁ id₂ (x , a) = id₁ x , InnerLex.identityʳ id₁ id₂sel : Selective _≈₁_ _∙_ → Selective _≈₂_ _◦_ → Selective _≋_ _⊕_sel ∙-sel ◦-sel (a , x) (b , y) with (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b... | no ab≉a | no ab≉b = contradiction₂ (∙-sel a b) ab≉a ab≉b... | yes ab≈a | no _ = inj₁ (ab≈a , ≈₂-refl)... | no _ | yes ab≈b = inj₂ (ab≈b , ≈₂-refl)... | yes ab≈a | yes ab≈b = map (ab≈a ,_) (ab≈b ,_) (◦-sel x y)
-------------------------------------------------------------------------- The Agda standard library---- Properties of the inner lexicographic product of two operators.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebraopen import Data.Bool.Base using (false; true)open import Data.Product.Base using (_×_; _,_; swap; map; uncurry′)open import Function.Base using (_∘_)open import Level using (Level; _⊔_)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary.Decidable using (does; yes; no)open import Relation.Nullary.Negationusing (contradiction; contradiction₂)import Relation.Binary.Reasoning.Setoid as SetoidReasoningimport Algebra.Construct.LexProduct.Base as Basemodule Algebra.Construct.LexProduct.Inner{ℓ₁ ℓ₂ ℓ₃ ℓ₄} (M : Magma ℓ₁ ℓ₂) (N : Magma ℓ₃ ℓ₄)(_≟₁_ : Decidable (Magma._≈_ M))whereopen module M = Magma Mrenaming( Carrier to A; _≈_ to _≈₁_; _≉_ to _≉₁_)open module N = Magma Nusing ()renaming( Carrier to B; _∙_ to _◦_; _≈_ to _≈₂_; ∙-cong to ◦-cong)privatevariablea b c d : Aw x y z : B-------------------------------------------------------------------------- Base definitionopen Base _∙_ _◦_ _≟₁_ publicusing (innerLex)-- Save ourselves some typing in this fileprivatelex = innerLex-------------------------------------------------------------------------- Propertiesmodule NaturalOrder where-- It would be really nice if we could use-- `Relation.Binary.Construct.NaturalOrder.Left/Right` to prove these-- properties but the equalities are defined the wrong way aroundopen SetoidReasoning M.setoid≤∙ˡ-resp-≈ : a ∙ b ≈₁ b → a ≈₁ c → b ≈₁ d → c ∙ d ≈₁ d≤∙ˡ-resp-≈ {a} {b} {c} {d} ab≈b a≈c b≈d = beginc ∙ d ≈⟨ ∙-cong (M.sym a≈c) (M.sym b≈d) ⟩a ∙ b ≈⟨ ab≈b ⟩b ≈⟨ b≈d ⟩d ∎≤∙ʳ-resp-≈ : a ∙ b ≈₁ a → a ≈₁ c → b ≈₁ d → c ∙ d ≈₁ c≤∙ʳ-resp-≈ {a} {b} {c} {d} ab≈b a≈c b≈d = beginc ∙ d ≈⟨ ∙-cong (M.sym a≈c) (M.sym b≈d) ⟩a ∙ b ≈⟨ ab≈b ⟩a ≈⟨ a≈c ⟩c ∎≤∙ˡ-trans : Associative _≈₁_ _∙_ → (a ∙ b) ≈₁ b → (b ∙ c) ≈₁ c → (a ∙ c) ≈₁ c≤∙ˡ-trans {a} {b} {c} ∙-assoc ab≈b bc≈c = begina ∙ c ≈⟨ ∙-congˡ bc≈c ⟨a ∙ (b ∙ c) ≈⟨ ∙-assoc a b c ⟨(a ∙ b) ∙ c ≈⟨ ∙-congʳ ab≈b ⟩b ∙ c ≈⟨ bc≈c ⟩c ∎≰∙ˡ-trans : Commutative _≈₁_ _∙_ → (a ∙ b) ≉₁ a → (a ∙ c) ≈₁ c → (b ∙ c) ≈₁ c → (a ∙ c) ≉₁ a≰∙ˡ-trans {a} {b} {c} ∙-comm ab≉a ac≈c bc≈c ac≈a = ab≉a (begina ∙ b ≈⟨ ∙-congʳ (M.trans (M.sym ac≈a) ac≈c) ⟩c ∙ b ≈⟨ ∙-comm c b ⟩b ∙ c ≈⟨ bc≈c ⟩c ≈⟨ M.trans (M.sym ac≈c) ac≈a ⟩a ∎)<∙ˡ-trans : Associative _≈₁_ _∙_ → Commutative _≈₁_ _∙_ →(a ∙ b) ≈₁ b → (a ∙ b) ≉₁ a → (b ∙ c) ≈₁ c →(a ∙ c) ≉₁ a × (a ∙ c) ≈₁ c<∙ˡ-trans {a} {b} {c} ∙-assoc ∙-comm ab≈b ab≉a bc≈c = ac≉a , ac≈cwhereac≈c = ≤∙ˡ-trans ∙-assoc ab≈b bc≈cac≉a = ≰∙ˡ-trans ∙-comm ab≉a ac≈c bc≈c<∙ʳ-trans : Associative _≈₁_ _∙_ → Commutative _≈₁_ _∙_ →(a ∙ b) ≈₁ a → (b ∙ c) ≈₁ b → (b ∙ c) ≉₁ c →(a ∙ c) ≈₁ a × (a ∙ c) ≉₁ c<∙ʳ-trans {a} {b} {c} assoc comm ab≈a bc≈b bc≉c = map(M.trans (comm a c))(_∘ M.trans (comm c a))(swap (<∙ˡ-trans assoc comm(M.trans (comm c b) bc≈b)(bc≉c ∘ M.trans (comm b c))(M.trans (comm b a) ab≈a)))-------------------------------------------------------------------------- Basic propertiesopen SetoidReasoning N.setoidopen NaturalOrdercase₁ : a ∙ b ≈₁ a → a ∙ b ≉₁ b → lex a b x y ≈₂ xcase₁ {a} {b} ab≈a ab≉b with (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b... | no ab≉a | _ = contradiction ab≈a ab≉a... | yes _ | yes ab≈b = contradiction ab≈b ab≉b... | yes _ | no _ = N.reflcase₂ : a ∙ b ≉₁ a → a ∙ b ≈₁ b → lex a b x y ≈₂ ycase₂ {a} {b} ab≉a ab≈b with (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b... | yes ab≈a | _ = contradiction ab≈a ab≉a... | no _ | no ab≉b = contradiction ab≈b ab≉b... | no _ | yes _ = N.reflcase₃ : a ∙ b ≈₁ a → a ∙ b ≈₁ b → lex a b x y ≈₂ (x ◦ y)case₃ {a} {b} ab≈a ab≈b with (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b... | no ab≉a | _ = contradiction ab≈a ab≉a... | yes _ | no ab≉b = contradiction ab≈b ab≉b... | yes _ | yes _ = N.refl-------------------------------------------------------------------------- Algebraic propertiescong : a ≈₁ b → c ≈₁ d → w ≈₂ x → y ≈₂ z → lex a c w y ≈₂ lex b d x zcong {a} {b} {c} {d} a≈b c≈d w≈x y≈zwith (a ∙ c) ≟₁ a | (a ∙ c) ≟₁ c | (b ∙ d) ≟₁ b | (b ∙ d) ≟₁ d... | yes _ | yes _ | yes _ | yes _ = ◦-cong w≈x y≈z... | yes _ | yes _ | no _ | no _ = ◦-cong w≈x y≈z... | no _ | no _ | yes _ | yes _ = ◦-cong w≈x y≈z... | no _ | no _ | no _ | no _ = ◦-cong w≈x y≈z... | yes _ | no _ | yes _ | no _ = w≈x... | no _ | yes _ | no _ | yes _ = y≈z... | _ | yes ac≈c | _ | no bd≉d = contradiction (≤∙ˡ-resp-≈ ac≈c a≈b c≈d) bd≉d... | yes ac≈a | _ | no bd≉b | _ = contradiction (≤∙ʳ-resp-≈ ac≈a a≈b c≈d) bd≉b... | _ | no ac≉c | _ | yes bd≈d = contradiction (≤∙ˡ-resp-≈ bd≈d (M.sym a≈b) (M.sym c≈d)) ac≉c... | no ac≉a | _ | yes bd≈b | _ = contradiction (≤∙ʳ-resp-≈ bd≈b (M.sym a≈b) (M.sym c≈d)) ac≉acong₁₂ : a ≈₁ b → c ≈₁ d → lex a c x y ≈₂ lex b d x ycong₁₂ a≈b c≈d = cong a≈b c≈d N.refl N.reflcong₁ : a ≈₁ b → lex a c x y ≈₂ lex b c x ycong₁ a≈b = cong₁₂ a≈b M.reflcong₂ : b ≈₁ c → lex a b x y ≈₂ lex a c x ycong₂ = cong₁₂ M.refl-- It is possible to relax this. Instead of ∙ being selective and ◦-- being associative it's also possible for _◦_ to return a single-- idempotent element.assoc : Associative _≈₁_ _∙_ → Commutative _≈₁_ _∙_ →Selective _≈₁_ _∙_ → Associative _≈₂_ _◦_ →∀ a b c x y z → lex (a ∙ b) c (lex a b x y) z ≈₂ lex a (b ∙ c) x (lex b c y z)assoc ∙-assoc ∙-comm ∙-sel ◦-assoc a b c x y zwith (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b | (b ∙ c) ≟₁ b | (b ∙ c) ≟₁ c... | _ | _ | no bc≉b | no bc≉c = contradiction₂ (∙-sel b c) bc≉b bc≉c... | no ab≉a | no ab≉b | _ | _ = contradiction₂ (∙-sel a b) ab≉a ab≉b... | yes ab≈a | no ab≉b | no bc≉b | yes bc≈c = cong₁₂ ab≈a (M.sym bc≈c)... | no ab≉a | yes ab≈b | yes bc≈b | yes bc≈c = beginlex (a ∙ b) c y z ≈⟨ cong₁ ab≈b ⟩lex b c y z ≈⟨ case₃ bc≈b bc≈c ⟩y ◦ z ≈⟨ case₂ ab≉a ab≈b ⟨lex a b x (y ◦ z) ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x (y ◦ z) ∎... | no ab≉a | yes ab≈b | yes bc≈b | no bc≉c = beginlex (a ∙ b) c y z ≈⟨ cong₁ ab≈b ⟩lex b c y z ≈⟨ case₁ bc≈b bc≉c ⟩y ≈⟨ case₂ ab≉a ab≈b ⟨lex a b x y ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x y ∎... | yes ab≈a | yes ab≈b | yes bc≈b | no bc≉c = beginlex (a ∙ b) c (x ◦ y) z ≈⟨ cong₁ ab≈b ⟩lex b c (x ◦ y) z ≈⟨ case₁ bc≈b bc≉c ⟩x ◦ y ≈⟨ case₃ ab≈a ab≈b ⟨lex a b x y ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x y ∎... | yes ab≈a | yes ab≈b | yes bc≈b | yes bc≈c = beginlex (a ∙ b) c (x ◦ y) z ≈⟨ cong₁ ab≈b ⟩lex b c (x ◦ y) z ≈⟨ case₃ bc≈b bc≈c ⟩(x ◦ y) ◦ z ≈⟨ ◦-assoc x y z ⟩x ◦ (y ◦ z) ≈⟨ case₃ ab≈a ab≈b ⟨lex a b x (y ◦ z) ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x (y ◦ z) ∎... | yes ab≈a | yes ab≈b | no bc≉b | yes bc≈c = beginlex (a ∙ b) c (x ◦ y) z ≈⟨ cong₁ ab≈b ⟩lex b c (x ◦ y) z ≈⟨ case₂ bc≉b bc≈c ⟩z ≈⟨ case₂ bc≉b bc≈c ⟨lex b c x z ≈⟨ cong₁₂ (M.trans (M.sym ab≈a) ab≈b) bc≈c ⟨lex a (b ∙ c) x z ∎... | yes ab≈a | no ab≉b | yes bc≈b | yes bc≈c = beginlex (a ∙ b) c x z ≈⟨ cong₁₂ ab≈a (M.trans (M.sym bc≈c) bc≈b) ⟩lex a b x z ≈⟨ case₁ ab≈a ab≉b ⟩x ≈⟨ case₁ ab≈a ab≉b ⟨lex a b x (y ◦ z) ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x (y ◦ z) ∎... | no ab≉a | yes ab≈b | no bc≉b | yes bc≈c = beginlex (a ∙ b) c y z ≈⟨ cong₁ ab≈b ⟩lex b c y z ≈⟨ case₂ bc≉b bc≈c ⟩z ≈⟨ uncurry′ case₂ (<∙ˡ-trans ∙-assoc ∙-comm ab≈b ab≉a bc≈c) ⟨lex a c x z ≈⟨ cong₂ bc≈c ⟨lex a (b ∙ c) x z ∎... | yes ab≈a | no ab≉b | yes bc≈b | no bc≉c = beginlex (a ∙ b) c x z ≈⟨ cong₁ ab≈a ⟩lex a c x z ≈⟨ uncurry′ case₁ (<∙ʳ-trans ∙-assoc ∙-comm ab≈a bc≈b bc≉c) ⟩x ≈⟨ case₁ ab≈a ab≉b ⟨lex a b x y ≈⟨ cong₂ bc≈b ⟨lex a (b ∙ c) x y ∎comm : Commutative _≈₁_ _∙_ → Commutative _≈₂_ _◦_ →∀ a b x y → lex a b x y ≈₂ lex b a y xcomm ∙-comm ◦-comm a b x ywith (a ∙ b) ≟₁ a | (a ∙ b) ≟₁ b | (b ∙ a) ≟₁ b | (b ∙ a) ≟₁ a... | yes ab≈a | _ | _ | no ba≉a = contradiction (M.trans (∙-comm b a) ab≈a) ba≉a... | no ab≉a | _ | _ | yes ba≈a = contradiction (M.trans (∙-comm a b) ba≈a) ab≉a... | _ | yes ab≈b | no ba≉b | _ = contradiction (M.trans (∙-comm b a) ab≈b) ba≉b... | _ | no ab≉b | yes ba≈b | _ = contradiction (M.trans (∙-comm a b) ba≈b) ab≉b... | yes _ | yes _ | yes _ | yes _ = ◦-comm x y... | yes _ | no _ | no _ | yes _ = N.refl... | no _ | yes _ | yes _ | no _ = N.refl... | no _ | no _ | no _ | no _ = ◦-comm x yidem : Idempotent _≈₂_ _◦_ → ∀ a b x → lex a b x x ≈₂ xidem ◦-idem a b x with does ((a ∙ b) ≟₁ a) | does ((a ∙ b) ≟₁ b)... | false | false = ◦-idem x... | false | true = N.refl... | true | false = N.refl... | true | true = ◦-idem xzeroʳ : ∀ {e f} → RightZero _≈₁_ e _∙_ → RightZero _≈₂_ f _◦_ →lex a e x f ≈₂ fzeroʳ {a} {x} {e} {f} ze₁ ze₂ with (a ∙ e) ≟₁ a | (a ∙ e) ≟₁ e... | _ | no a∙e≉e = contradiction (ze₁ a) a∙e≉e... | no _ | yes _ = N.refl... | yes _ | yes _ = ze₂ xidentityʳ : ∀ {e f} → RightIdentity _≈₁_ e _∙_ → RightIdentity _≈₂_ f _◦_ →lex a e x f ≈₂ xidentityʳ {a} {x} {e} {f} id₁ id₂ with (a ∙ e) ≟₁ a | (a ∙ e) ≟₁ e... | no a∙e≉a | _ = contradiction (id₁ a) a∙e≉a... | yes _ | no _ = N.refl... | yes _ | yes _ = id₂ x
-------------------------------------------------------------------------- The Agda standard library---- Definitions of the lexicographic product of two operators.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Core using (Op₂)open import Data.Bool.Base using (true; false)open import Data.Product.Base using (_×_; _,_)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Definitions using (Decidable)open import Relation.Nullary.Decidable.Core using (does; yes; no)module Algebra.Construct.LexProduct.Base{a b ℓ} {A : Set a} {B : Set b}(_∙_ : Op₂ A) (_◦_ : Op₂ B){_≈₁_ : Rel A ℓ} (_≟₁_ : Decidable _≈₁_)where-------------------------------------------------------------------------- Definition-- In order to get the first component to be definitionally equal to-- `a ∙ b` and to simplify some of the proofs we first define an inner-- operator that only calculates the second component of product.innerLex : A → A → B → B → BinnerLex a b x y with does ((a ∙ b) ≟₁ a) | does ((a ∙ b) ≟₁ b)... | true | false = x... | false | true = y... | _ | _ = x ◦ y-- The full lexicographic choice operator can then be simply defined-- in terms of the inner one.lex : Op₂ (A × B)lex (a , x) (b , y) = (a ∙ b , innerLex a b x y)
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic structures where the carrier is ⊥.-- In mathematics, this is usually called 0.---- From monoids up, these are zero-objects – i.e, the terminal-- object is *also* the initial object in the relevant category.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Level using (Level)module Algebra.Construct.Initial {c ℓ : Level} whereopen import Algebra.Bundlesusing (Magma; Semigroup; Band)open import Algebra.Bundles.Rawusing (RawMagma)open import Algebra.Core using (Op₂)open import Algebra.Definitions using (Congruent₂)open import Algebra.Structures using (IsMagma; IsSemigroup; IsBand)open import Data.Empty.Polymorphicopen import Relation.Binary.Core using (Rel)open import Relation.Binary.Structures using (IsEquivalence)open import Relation.Binary.Definitionsusing (Reflexive; Symmetric; Transitive)-------------------------------------------------------------------------- Re-export those algebras which are also terminalopen import Algebra.Construct.Terminal {c} {ℓ} publichiding (rawMagma; magma; semigroup; band)-------------------------------------------------------------------------- Gather all the functionality in one placemodule ℤero whereinfixl 7 _∙_infix 4 _≈_Carrier : Set cCarrier = ⊥_≈_ : Rel Carrier ℓ_≈_ ()_∙_ : Op₂ Carrier_∙_ ()refl : Reflexive _≈_refl {x = ()}sym : Symmetric _≈_sym {x = ()}trans : Transitive _≈_trans {i = ()}∙-cong : Congruent₂ _≈_ _∙_∙-cong {x = ()}open ℤero-------------------------------------------------------------------------- Raw bundlesrawMagma : RawMagma c ℓrawMagma = record { ℤero }-------------------------------------------------------------------------- StructuresisEquivalence : IsEquivalence _≈_isEquivalence = record { ℤero }isMagma : IsMagma _≈_ _∙_isMagma = record { isEquivalence = isEquivalence ; ∙-cong = ∙-cong }isSemigroup : IsSemigroup _≈_ _∙_isSemigroup = record { isMagma = isMagma ; assoc = λ () }isBand : IsBand _≈_ _∙_isBand = record { isSemigroup = isSemigroup ; idem = λ () }-------------------------------------------------------------------------- Bundlesmagma : Magma c ℓmagma = record { isMagma = isMagma }semigroup : Semigroup c ℓsemigroup = record { isSemigroup = isSemigroup }band : Band c ℓband = record { isBand = isBand }
-------------------------------------------------------------------------- The Agda standard library---- Flipping the arguments of a binary operation preserves many of its-- algebraic properties.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Construct.Flip.Op whereopen import Algebraimport Data.Product.Base as Productimport Data.Sum.Base as Sumopen import Function.Base using (flip)open import Level using (Level)open import Relation.Binary.Core using (Rel; _Preserves₂_⟶_⟶_)open import Relation.Binary.Definitions using (Symmetric)privatevariablea ℓ : LevelA : Set a≈ : Rel A ℓε : A⁻¹ : Op₁ A∙ : Op₂ A-------------------------------------------------------------------------- Propertiespreserves₂ : (∼ ≈ ≋ : Rel A ℓ) →∙ Preserves₂ ∼ ⟶ ≈ ⟶ ≋ → (flip ∙) Preserves₂ ≈ ⟶ ∼ ⟶ ≋preserves₂ _ _ _ pres = flip presmodule _ (≈ : Rel A ℓ) (∙ : Op₂ A) whereassociative : Symmetric ≈ → Associative ≈ ∙ → Associative ≈ (flip ∙)associative sym assoc x y z = sym (assoc z y x)identity : Identity ≈ ε ∙ → Identity ≈ ε (flip ∙)identity id = Product.swap idcommutative : Commutative ≈ ∙ → Commutative ≈ (flip ∙)commutative comm = flip commselective : Selective ≈ ∙ → Selective ≈ (flip ∙)selective sel x y = Sum.swap (sel y x)idempotent : Idempotent ≈ ∙ → Idempotent ≈ (flip ∙)idempotent idem = ideminverse : Inverse ≈ ε ⁻¹ ∙ → Inverse ≈ ε ⁻¹ (flip ∙)inverse inv = Product.swap inv-------------------------------------------------------------------------- Structuresmodule _ {≈ : Rel A ℓ} {∙ : Op₂ A} whereisMagma : IsMagma ≈ ∙ → IsMagma ≈ (flip ∙)isMagma m = record{ isEquivalence = isEquivalence; ∙-cong = preserves₂ ≈ ≈ ≈ ∙-cong}where open IsMagma misSelectiveMagma : IsSelectiveMagma ≈ ∙ → IsSelectiveMagma ≈ (flip ∙)isSelectiveMagma m = record{ isMagma = isMagma m.isMagma; sel = selective ≈ ∙ m.sel}where module m = IsSelectiveMagma misCommutativeMagma : IsCommutativeMagma ≈ ∙ → IsCommutativeMagma ≈ (flip ∙)isCommutativeMagma m = record{ isMagma = isMagma m.isMagma; comm = commutative ≈ ∙ m.comm}where module m = IsCommutativeMagma misSemigroup : IsSemigroup ≈ ∙ → IsSemigroup ≈ (flip ∙)isSemigroup s = record{ isMagma = isMagma s.isMagma; assoc = associative ≈ ∙ s.sym s.assoc}where module s = IsSemigroup sisBand : IsBand ≈ ∙ → IsBand ≈ (flip ∙)isBand b = record{ isSemigroup = isSemigroup b.isSemigroup; idem = b.idem}where module b = IsBand bisCommutativeSemigroup : IsCommutativeSemigroup ≈ ∙ →IsCommutativeSemigroup ≈ (flip ∙)isCommutativeSemigroup s = record{ isSemigroup = isSemigroup s.isSemigroup; comm = commutative ≈ ∙ s.comm}where module s = IsCommutativeSemigroup sisUnitalMagma : IsUnitalMagma ≈ ∙ ε → IsUnitalMagma ≈ (flip ∙) εisUnitalMagma m = record{ isMagma = isMagma m.isMagma; identity = identity ≈ ∙ m.identity}where module m = IsUnitalMagma misMonoid : IsMonoid ≈ ∙ ε → IsMonoid ≈ (flip ∙) εisMonoid m = record{ isSemigroup = isSemigroup m.isSemigroup; identity = identity ≈ ∙ m.identity}where module m = IsMonoid misCommutativeMonoid : IsCommutativeMonoid ≈ ∙ ε →IsCommutativeMonoid ≈ (flip ∙) εisCommutativeMonoid m = record{ isMonoid = isMonoid m.isMonoid; comm = commutative ≈ ∙ m.comm}where module m = IsCommutativeMonoid misIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid ≈ ∙ ε →IsIdempotentCommutativeMonoid ≈ (flip ∙) εisIdempotentCommutativeMonoid m = record{ isCommutativeMonoid = isCommutativeMonoid m.isCommutativeMonoid; idem = idempotent ≈ ∙ m.idem}where module m = IsIdempotentCommutativeMonoid misInvertibleMagma : IsInvertibleMagma ≈ ∙ ε ⁻¹ →IsInvertibleMagma ≈ (flip ∙) ε ⁻¹isInvertibleMagma m = record{ isMagma = isMagma m.isMagma; inverse = inverse ≈ ∙ m.inverse; ⁻¹-cong = m.⁻¹-cong}where module m = IsInvertibleMagma misInvertibleUnitalMagma : IsInvertibleUnitalMagma ≈ ∙ ε ⁻¹ →IsInvertibleUnitalMagma ≈ (flip ∙) ε ⁻¹isInvertibleUnitalMagma m = record{ isInvertibleMagma = isInvertibleMagma m.isInvertibleMagma; identity = identity ≈ ∙ m.identity}where module m = IsInvertibleUnitalMagma misGroup : IsGroup ≈ ∙ ε ⁻¹ → IsGroup ≈ (flip ∙) ε ⁻¹isGroup g = record{ isMonoid = isMonoid g.isMonoid; inverse = inverse ≈ ∙ g.inverse; ⁻¹-cong = g.⁻¹-cong}where module g = IsGroup gisAbelianGroup : IsAbelianGroup ≈ ∙ ε ⁻¹ → IsAbelianGroup ≈ (flip ∙) ε ⁻¹isAbelianGroup g = record{ isGroup = isGroup g.isGroup; comm = commutative ≈ ∙ g.comm}where module g = IsAbelianGroup g-------------------------------------------------------------------------- Bundlesmagma : Magma a ℓ → Magma a ℓmagma m = record { isMagma = isMagma m.isMagma }where module m = Magma mcommutativeMagma : CommutativeMagma a ℓ → CommutativeMagma a ℓcommutativeMagma m = record{ isCommutativeMagma = isCommutativeMagma m.isCommutativeMagma}where module m = CommutativeMagma mselectiveMagma : SelectiveMagma a ℓ → SelectiveMagma a ℓselectiveMagma m = record{ isSelectiveMagma = isSelectiveMagma m.isSelectiveMagma}where module m = SelectiveMagma msemigroup : Semigroup a ℓ → Semigroup a ℓsemigroup s = record { isSemigroup = isSemigroup s.isSemigroup }where module s = Semigroup sband : Band a ℓ → Band a ℓband b = record { isBand = isBand b.isBand }where module b = Band bcommutativeSemigroup : CommutativeSemigroup a ℓ → CommutativeSemigroup a ℓcommutativeSemigroup s = record{ isCommutativeSemigroup = isCommutativeSemigroup s.isCommutativeSemigroup}where module s = CommutativeSemigroup sunitalMagma : UnitalMagma a ℓ → UnitalMagma a ℓunitalMagma m = record{ isUnitalMagma = isUnitalMagma m.isUnitalMagma}where module m = UnitalMagma mmonoid : Monoid a ℓ → Monoid a ℓmonoid m = record { isMonoid = isMonoid m.isMonoid }where module m = Monoid mcommutativeMonoid : CommutativeMonoid a ℓ → CommutativeMonoid a ℓcommutativeMonoid m = record{ isCommutativeMonoid = isCommutativeMonoid m.isCommutativeMonoid}where module m = CommutativeMonoid midempotentCommutativeMonoid : IdempotentCommutativeMonoid a ℓ →IdempotentCommutativeMonoid a ℓidempotentCommutativeMonoid m = record{ isIdempotentCommutativeMonoid =isIdempotentCommutativeMonoid m.isIdempotentCommutativeMonoid}where module m = IdempotentCommutativeMonoid minvertibleMagma : InvertibleMagma a ℓ → InvertibleMagma a ℓinvertibleMagma m = record{ isInvertibleMagma = isInvertibleMagma m.isInvertibleMagma}where module m = InvertibleMagma minvertibleUnitalMagma : InvertibleUnitalMagma a ℓ → InvertibleUnitalMagma a ℓinvertibleUnitalMagma m = record{ isInvertibleUnitalMagma = isInvertibleUnitalMagma m.isInvertibleUnitalMagma}where module m = InvertibleUnitalMagma mgroup : Group a ℓ → Group a ℓgroup g = record { isGroup = isGroup g.isGroup }where module g = Group gabelianGroup : AbelianGroup a ℓ → AbelianGroup a ℓabelianGroup g = record { isAbelianGroup = isAbelianGroup g.isAbelianGroup }where module g = AbelianGroup g
-------------------------------------------------------------------------- The Agda standard library---- Instances of algebraic structures made by taking two other instances-- A and B, and having elements of the new instance be pairs |A| × |B|.-- In mathematics, this would usually be written A × B or A ⊕ B.---- From semigroups up, these new instances are products of the relevant-- category. For structures with commutative addition (commutative-- monoids, Abelian groups, semirings, rings), the direct product is-- also the coproduct, making it a biproduct.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Construct.DirectProduct whereopen import Algebraopen import Data.Product.Base using (_×_; zip; _,_; map; _<*>_; uncurry)open import Data.Product.Relation.Binary.Pointwise.NonDependentopen import Level using (Level; _⊔_)privatevariablea b ℓ₁ ℓ₂ : Level-------------------------------------------------------------------------- Raw bundlesrawMagma : RawMagma a ℓ₁ → RawMagma b ℓ₂ → RawMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawMagma M N = record{ Carrier = M.Carrier × N.Carrier; _≈_ = Pointwise M._≈_ N._≈_; _∙_ = zip M._∙_ N._∙_} where module M = RawMagma M; module N = RawMagma NrawMonoid : RawMonoid a ℓ₁ → RawMonoid b ℓ₂ → RawMonoid (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawMonoid M N = record{ Carrier = M.Carrier × N.Carrier; _≈_ = Pointwise M._≈_ N._≈_; _∙_ = zip M._∙_ N._∙_; ε = M.ε , N.ε} where module M = RawMonoid M; module N = RawMonoid NrawGroup : RawGroup a ℓ₁ → RawGroup b ℓ₂ → RawGroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawGroup G H = record{ Carrier = G.Carrier × H.Carrier; _≈_ = Pointwise G._≈_ H._≈_; _∙_ = zip G._∙_ H._∙_; ε = G.ε , H.ε; _⁻¹ = map G._⁻¹ H._⁻¹} where module G = RawGroup G; module H = RawGroup HrawSemiring : RawSemiring a ℓ₁ → RawSemiring b ℓ₂ → RawSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawSemiring R S = record{ Carrier = R.Carrier × S.Carrier; _≈_ = Pointwise R._≈_ S._≈_; _+_ = zip R._+_ S._+_; _*_ = zip R._*_ S._*_; 0# = R.0# , S.0#; 1# = R.1# , S.1#} where module R = RawSemiring R; module S = RawSemiring SrawRingWithoutOne : RawRingWithoutOne a ℓ₁ → RawRingWithoutOne b ℓ₂ → RawRingWithoutOne (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawRingWithoutOne R S = record{ Carrier = R.Carrier × S.Carrier; _≈_ = Pointwise R._≈_ S._≈_; _+_ = zip R._+_ S._+_; _*_ = zip R._*_ S._*_; -_ = map R.-_ S.-_; 0# = R.0# , S.0#} where module R = RawRingWithoutOne R; module S = RawRingWithoutOne SrawRing : RawRing a ℓ₁ → RawRing b ℓ₂ → RawRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawRing R S = record{ Carrier = R.Carrier × S.Carrier; _≈_ = Pointwise R._≈_ S._≈_; _+_ = zip R._+_ S._+_; _*_ = zip R._*_ S._*_; -_ = map R.-_ S.-_; 0# = R.0# , S.0#; 1# = R.1# , S.1#} where module R = RawRing R; module S = RawRing SrawQuasigroup : RawQuasigroup a ℓ₁ → RawQuasigroup b ℓ₂ → RawQuasigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawQuasigroup M N = record{ Carrier = M.Carrier × N.Carrier; _≈_ = Pointwise M._≈_ N._≈_; _∙_ = zip M._∙_ N._∙_; _\\_ = zip M._\\_ N._\\_; _//_ = zip M._//_ N._//_} where module M = RawQuasigroup M; module N = RawQuasigroup NrawLoop : RawLoop a ℓ₁ → RawLoop b ℓ₂ → RawLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawLoop M N = record{ Carrier = M.Carrier × N.Carrier; _≈_ = Pointwise M._≈_ N._≈_; _∙_ = zip M._∙_ N._∙_; _\\_ = zip M._\\_ N._\\_; _//_ = zip M._//_ N._//_; ε = M.ε , N.ε} where module M = RawLoop M; module N = RawLoop N-------------------------------------------------------------------------- Bundlesmagma : Magma a ℓ₁ → Magma b ℓ₂ → Magma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)magma M N = record{ Carrier = M.Carrier × N.Carrier; _≈_ = Pointwise M._≈_ N._≈_; _∙_ = zip M._∙_ N._∙_; isMagma = record{ isEquivalence = ×-isEquivalence M.isEquivalence N.isEquivalence; ∙-cong = zip M.∙-cong N.∙-cong}} where module M = Magma M; module N = Magma NidempotentMagma : IdempotentMagma a ℓ₁ → IdempotentMagma b ℓ₂ → IdempotentMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)idempotentMagma G H = record{ isIdempotentMagma = record{ isMagma = Magma.isMagma (magma G.magma H.magma); idem = λ x → (G.idem , H.idem) <*> x}} where module G = IdempotentMagma G; module H = IdempotentMagma HalternativeMagma : AlternativeMagma a ℓ₁ → AlternativeMagma b ℓ₂ → AlternativeMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)alternativeMagma G H = record{ isAlternativeMagma = record{ isMagma = Magma.isMagma (magma G.magma H.magma); alter = (λ x y → G.alternativeˡ , H.alternativeˡ <*> x <*> y), (λ x y → G.alternativeʳ , H.alternativeʳ <*> x <*> y)}} where module G = AlternativeMagma G; module H = AlternativeMagma HflexibleMagma : FlexibleMagma a ℓ₁ → FlexibleMagma b ℓ₂ → FlexibleMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)flexibleMagma G H = record{ isFlexibleMagma = record{ isMagma = Magma.isMagma (magma G.magma H.magma); flex = λ x y → (G.flex , H.flex) <*> x <*> y}} where module G = FlexibleMagma G; module H = FlexibleMagma HmedialMagma : MedialMagma a ℓ₁ → MedialMagma b ℓ₂ → MedialMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)medialMagma G H = record{ isMedialMagma = record{ isMagma = Magma.isMagma (magma G.magma H.magma); medial = λ x y u z → (G.medial , H.medial) <*> x <*> y <*> u <*> z}} where module G = MedialMagma G; module H = MedialMagma HsemimedialMagma : SemimedialMagma a ℓ₁ → SemimedialMagma b ℓ₂ → SemimedialMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semimedialMagma G H = record{ isSemimedialMagma = record{ isMagma = Magma.isMagma (magma G.magma H.magma); semiMedial = (λ x y z → G.semimedialˡ , H.semimedialˡ <*> x <*> y <*> z), ((λ x y z → G.semimedialʳ , H.semimedialʳ <*> x <*> y <*> z))}} where module G = SemimedialMagma G; module H = SemimedialMagma Hsemigroup : Semigroup a ℓ₁ → Semigroup b ℓ₂ → Semigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semigroup G H = record{ isSemigroup = record{ isMagma = Magma.isMagma (magma G.magma H.magma); assoc = λ x y z → (G.assoc , H.assoc) <*> x <*> y <*> z}} where module G = Semigroup G; module H = Semigroup Hband : Band a ℓ₁ → Band b ℓ₂ → Band (a ⊔ b) (ℓ₁ ⊔ ℓ₂)band B C = record{ isBand = record{ isSemigroup = Semigroup.isSemigroup (semigroup B.semigroup C.semigroup); idem = λ x → (B.idem , C.idem) <*> x}} where module B = Band B; module C = Band CcommutativeSemigroup : CommutativeSemigroup a ℓ₁ → CommutativeSemigroup b ℓ₂ →CommutativeSemigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeSemigroup G H = record{ isCommutativeSemigroup = record{ isSemigroup = Semigroup.isSemigroup (semigroup G.semigroup H.semigroup); comm = λ x y → (G.comm , H.comm) <*> x <*> y}} where module G = CommutativeSemigroup G; module H = CommutativeSemigroup HunitalMagma : UnitalMagma a ℓ₁ → UnitalMagma b ℓ₂ → UnitalMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)unitalMagma M N = record{ ε = M.ε , N.ε; isUnitalMagma = record{ isMagma = Magma.isMagma (magma M.magma N.magma); identity = (M.identityˡ , N.identityˡ <*>_), (M.identityʳ , N.identityʳ <*>_)}} where module M = UnitalMagma M; module N = UnitalMagma Nmonoid : Monoid a ℓ₁ → Monoid b ℓ₂ → Monoid (a ⊔ b) (ℓ₁ ⊔ ℓ₂)monoid M N = record{ ε = M.ε , N.ε; isMonoid = record{ isSemigroup = Semigroup.isSemigroup (semigroup M.semigroup N.semigroup); identity = (M.identityˡ , N.identityˡ <*>_), (M.identityʳ , N.identityʳ <*>_)}} where module M = Monoid M; module N = Monoid NcommutativeMonoid : CommutativeMonoid a ℓ₁ → CommutativeMonoid b ℓ₂ →CommutativeMonoid (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeMonoid M N = record{ isCommutativeMonoid = record{ isMonoid = Monoid.isMonoid (monoid M.monoid N.monoid); comm = λ x y → (M.comm , N.comm) <*> x <*> y}} where module M = CommutativeMonoid M; module N = CommutativeMonoid NidempotentCommutativeMonoid :IdempotentCommutativeMonoid a ℓ₁ → IdempotentCommutativeMonoid b ℓ₂ →IdempotentCommutativeMonoid (a ⊔ b) (ℓ₁ ⊔ ℓ₂)idempotentCommutativeMonoid M N = record{ isIdempotentCommutativeMonoid = record{ isCommutativeMonoid = CommutativeMonoid.isCommutativeMonoid(commutativeMonoid M.commutativeMonoid N.commutativeMonoid); idem = λ x → (M.idem , N.idem) <*> x}}wheremodule M = IdempotentCommutativeMonoid Mmodule N = IdempotentCommutativeMonoid NinvertibleMagma : InvertibleMagma a ℓ₁ → InvertibleMagma b ℓ₂ → InvertibleMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)invertibleMagma M N = record{ _⁻¹ = map M._⁻¹ N._⁻¹; isInvertibleMagma = record{ isMagma = Magma.isMagma (magma M.magma N.magma); inverse = (λ x → (M.inverseˡ , N.inverseˡ) <*> x), (λ x → (M.inverseʳ , N.inverseʳ) <*> x); ⁻¹-cong = map M.⁻¹-cong N.⁻¹-cong}} where module M = InvertibleMagma M; module N = InvertibleMagma NinvertibleUnitalMagma : InvertibleUnitalMagma a ℓ₁ → InvertibleUnitalMagma b ℓ₂ → InvertibleUnitalMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)invertibleUnitalMagma M N = record{ ε = M.ε , N.ε; isInvertibleUnitalMagma = record{ isInvertibleMagma = InvertibleMagma.isInvertibleMagma (invertibleMagma M.invertibleMagma N.invertibleMagma); identity = (M.identityˡ , N.identityˡ <*>_), (M.identityʳ , N.identityʳ <*>_)}} where module M = InvertibleUnitalMagma M; module N = InvertibleUnitalMagma Ngroup : Group a ℓ₁ → Group b ℓ₂ → Group (a ⊔ b) (ℓ₁ ⊔ ℓ₂)group G H = record{ _⁻¹ = map G._⁻¹ H._⁻¹; isGroup = record{ isMonoid = Monoid.isMonoid (monoid G.monoid H.monoid); inverse = (λ x → (G.inverseˡ , H.inverseˡ) <*> x), (λ x → (G.inverseʳ , H.inverseʳ) <*> x); ⁻¹-cong = map G.⁻¹-cong H.⁻¹-cong}} where module G = Group G; module H = Group HabelianGroup : AbelianGroup a ℓ₁ → AbelianGroup b ℓ₂ →AbelianGroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)abelianGroup G H = record{ isAbelianGroup = record{ isGroup = Group.isGroup (group G.group H.group); comm = λ x y → (G.comm , H.comm) <*> x <*> y}} where module G = AbelianGroup G; module H = AbelianGroup HsemiringWithoutAnnihilatingZero : SemiringWithoutAnnihilatingZero a ℓ₁ →SemiringWithoutAnnihilatingZero b ℓ₂ →SemiringWithoutAnnihilatingZero (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semiringWithoutAnnihilatingZero R S = record{ isSemiringWithoutAnnihilatingZero = record{ +-isCommutativeMonoid = CommutativeMonoid.isCommutativeMonoid(commutativeMonoid R.+-commutativeMonoidS.+-commutativeMonoid); *-cong = zip R.*-cong S.*-cong; *-assoc = λ x y z → (R.*-assoc , S.*-assoc) <*> x <*> y <*> z; *-identity = (R.*-identityˡ , S.*-identityˡ <*>_), (R.*-identityʳ , S.*-identityʳ <*>_); distrib = (λ x y z → (R.distribˡ , S.distribˡ) <*> x <*> y <*> z), (λ x y z → (R.distribʳ , S.distribʳ) <*> x <*> y <*> z)}} where module R = SemiringWithoutAnnihilatingZero Rmodule S = SemiringWithoutAnnihilatingZero Ssemiring : Semiring a ℓ₁ → Semiring b ℓ₂ → Semiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semiring R S = record{ isSemiring = record{ isSemiringWithoutAnnihilatingZero =SemiringWithoutAnnihilatingZero.isSemiringWithoutAnnihilatingZero U; zero = uncurry (λ x y → R.zeroˡ x , S.zeroˡ y), uncurry (λ x y → R.zeroʳ x , S.zeroʳ y)}}wheremodule R = Semiring Rmodule S = Semiring SU = semiringWithoutAnnihilatingZero R.semiringWithoutAnnihilatingZeroS.semiringWithoutAnnihilatingZerocommutativeSemiring : CommutativeSemiring a ℓ₁ → CommutativeSemiring b ℓ₂ →CommutativeSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeSemiring R S = record{ isCommutativeSemiring = record{ isSemiring = Semiring.isSemiring (semiring R.semiring S.semiring); *-comm = λ x y → (R.*-comm , S.*-comm) <*> x <*> y}} where module R = CommutativeSemiring R; module S = CommutativeSemiring SidempotentSemiring : IdempotentSemiring a ℓ₁ → IdempotentSemiring b ℓ₂ → IdempotentSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)idempotentSemiring K L = record{ isIdempotentSemiring = record{ isSemiring = Semiring.isSemiring (semiring K.semiring L.semiring); +-idem = λ x → (K.+-idem , L.+-idem) <*> x}} where module K = IdempotentSemiring K; module L = IdempotentSemiring LkleeneAlgebra : KleeneAlgebra a ℓ₁ → KleeneAlgebra b ℓ₂ → KleeneAlgebra (a ⊔ b) (ℓ₁ ⊔ ℓ₂)kleeneAlgebra K L = record{ isKleeneAlgebra = record{ isIdempotentSemiring = IdempotentSemiring.isIdempotentSemiring (idempotentSemiring K.idempotentSemiring L.idempotentSemiring); starExpansive = (λ x → (K.starExpansiveˡ , L.starExpansiveˡ) <*> x), (λ x → (K.starExpansiveʳ , L.starExpansiveʳ) <*> x); starDestructive = (λ a b x x₁ → (K.starDestructiveˡ , L.starDestructiveˡ) <*> a <*> b <*> x <*> x₁), (λ a b x x₁ → (K.starDestructiveʳ , L.starDestructiveʳ) <*> a <*> b <*> x <*> x₁)}} where module K = KleeneAlgebra K; module L = KleeneAlgebra LringWithoutOne : RingWithoutOne a ℓ₁ → RingWithoutOne b ℓ₂ → RingWithoutOne (a ⊔ b) (ℓ₁ ⊔ ℓ₂)ringWithoutOne R S = record{ isRingWithoutOne = record{ +-isAbelianGroup = AbelianGroup.isAbelianGroup ((abelianGroup R.+-abelianGroup S.+-abelianGroup)); *-cong = Semigroup.∙-cong (semigroup R.*-semigroup S.*-semigroup); *-assoc = Semigroup.assoc (semigroup R.*-semigroup S.*-semigroup); distrib = (λ x y z → (R.distribˡ , S.distribˡ) <*> x <*> y <*> z), (λ x y z → (R.distribʳ , S.distribʳ) <*> x <*> y <*> z)}} where module R = RingWithoutOne R; module S = RingWithoutOne SnonAssociativeRing : NonAssociativeRing a ℓ₁ → NonAssociativeRing b ℓ₂ → NonAssociativeRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)nonAssociativeRing R S = record{ isNonAssociativeRing = record{ +-isAbelianGroup = AbelianGroup.isAbelianGroup ((abelianGroup R.+-abelianGroup S.+-abelianGroup)); *-cong = UnitalMagma.∙-cong (unitalMagma R.*-unitalMagma S.*-unitalMagma); *-identity = UnitalMagma.identity (unitalMagma R.*-unitalMagma S.*-unitalMagma); distrib = (λ x y z → (R.distribˡ , S.distribˡ) <*> x <*> y <*> z), (λ x y z → (R.distribʳ , S.distribʳ) <*> x <*> y <*> z); zero = uncurry (λ x y → R.zeroˡ x , S.zeroˡ y), uncurry (λ x y → R.zeroʳ x , S.zeroʳ y)}} where module R = NonAssociativeRing R; module S = NonAssociativeRing Squasiring : Quasiring a ℓ₁ → Quasiring b ℓ₂ → Quasiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)quasiring R S = record{ isQuasiring = record{ +-isMonoid = Monoid.isMonoid ((monoid R.+-monoid S.+-monoid)); *-cong = Monoid.∙-cong (monoid R.*-monoid S.*-monoid); *-assoc = Monoid.assoc (monoid R.*-monoid S.*-monoid); *-identity = Monoid.identity ((monoid R.*-monoid S.*-monoid)); distrib = (λ x y z → (R.distribˡ , S.distribˡ) <*> x <*> y <*> z), (λ x y z → (R.distribʳ , S.distribʳ) <*> x <*> y <*> z); zero = uncurry (λ x y → R.zeroˡ x , S.zeroˡ y), uncurry (λ x y → R.zeroʳ x , S.zeroʳ y)}} where module R = Quasiring R; module S = Quasiring Snearring : Nearring a ℓ₁ → Nearring b ℓ₂ → Nearring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)nearring R S = record{ isNearring = record{ isQuasiring = Quasiring.isQuasiring (quasiring R.quasiring S.quasiring); +-inverse = (λ x → (R.+-inverseˡ , S.+-inverseˡ) <*> x), (λ x → (R.+-inverseʳ , S.+-inverseʳ) <*> x); ⁻¹-cong = map R.⁻¹-cong S.⁻¹-cong}} where module R = Nearring R; module S = Nearring Sring : Ring a ℓ₁ → Ring b ℓ₂ → Ring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)ring R S = record{ -_ = uncurry (λ x y → R.-_ x , S.-_ y); isRing = record{ +-isAbelianGroup = AbelianGroup.isAbelianGroup A; *-cong = Semiring.*-cong Semi; *-assoc = Semiring.*-assoc Semi; *-identity = Semiring.*-identity Semi; distrib = Semiring.distrib Semi}}wheremodule R = Ring Rmodule S = Ring SSemi = semiring R.semiring S.semiringA = abelianGroup R.+-abelianGroup S.+-abelianGroupcommutativeRing : CommutativeRing a ℓ₁ → CommutativeRing b ℓ₂ →CommutativeRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeRing R S = record{ isCommutativeRing = record{ isRing = Ring.isRing (ring R.ring S.ring); *-comm = λ x y → (R.*-comm , S.*-comm) <*> x <*> y}} where module R = CommutativeRing R; module S = CommutativeRing Squasigroup : Quasigroup a ℓ₁ → Quasigroup b ℓ₂ → Quasigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)quasigroup M N = record{ _\\_ = zip M._\\_ N._\\_; _//_ = zip M._//_ N._//_; isQuasigroup = record{ isMagma = Magma.isMagma (magma M.magma N.magma); \\-cong = zip M.\\-cong N.\\-cong; //-cong = zip M.//-cong N.//-cong; leftDivides = (λ x y → M.leftDividesˡ , N.leftDividesˡ <*> x <*> y) , (λ x y → M.leftDividesʳ , N.leftDividesʳ <*> x <*> y); rightDivides = (λ x y → M.rightDividesˡ , N.rightDividesˡ <*> x <*> y) , (λ x y → M.rightDividesʳ , N.rightDividesʳ <*> x <*> y)}} where module M = Quasigroup M; module N = Quasigroup Nloop : Loop a ℓ₁ → Loop b ℓ₂ → Loop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)loop M N = record{ ε = M.ε , N.ε; isLoop = record{ isQuasigroup = Quasigroup.isQuasigroup (quasigroup M.quasigroup N.quasigroup); identity = (M.identityˡ , N.identityˡ <*>_), (M.identityʳ , N.identityʳ <*>_)}} where module M = Loop M; module N = Loop NleftBolLoop : LeftBolLoop a ℓ₁ → LeftBolLoop b ℓ₂ → LeftBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)leftBolLoop M N = record{ isLeftBolLoop = record{ isLoop = Loop.isLoop (loop M.loop N.loop); leftBol = λ x y z → M.leftBol , N.leftBol <*> x <*> y <*> z}} where module M = LeftBolLoop M; module N = LeftBolLoop NrightBolLoop : RightBolLoop a ℓ₁ → RightBolLoop b ℓ₂ → RightBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rightBolLoop M N = record{ isRightBolLoop = record{ isLoop = Loop.isLoop (loop M.loop N.loop); rightBol = λ x y z → M.rightBol , N.rightBol <*> x <*> y <*> z}} where module M = RightBolLoop M; module N = RightBolLoop NmiddleBolLoop : MiddleBolLoop a ℓ₁ → MiddleBolLoop b ℓ₂ → MiddleBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)middleBolLoop M N = record{ isMiddleBolLoop = record{ isLoop = Loop.isLoop (loop M.loop N.loop); middleBol = λ x y z → M.middleBol , N.middleBol <*> x <*> y <*> z}} where module M = MiddleBolLoop M; module N = MiddleBolLoop NmoufangLoop : MoufangLoop a ℓ₁ → MoufangLoop b ℓ₂ → MoufangLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)moufangLoop M N = record{ isMoufangLoop = record{ isLeftBolLoop = LeftBolLoop.isLeftBolLoop (leftBolLoop M.leftBolLoop N.leftBolLoop); rightBol = λ x y z → M.rightBol , N.rightBol <*> x <*> y <*> z; identical = λ x y z → M.identical , N.identical <*> x <*> y <*> z}} where module M = MoufangLoop M; module N = MoufangLoop N
-------------------------------------------------------------------------- The Agda standard library---- Definition of algebraic structures we get from freely adding an-- identity element------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Construct.Add.Identity whereopen import Algebra.Bundlesopen import Algebra.Core using (Op₂)open import Algebra.Definitionsopen import Algebra.Structuresopen import Relation.Binary.Construct.Add.Point.Equality renaming (_≈∙_ to lift≈)open import Data.Product.Base using (_,_)open import Level using (Level; _⊔_)open import Relation.Binary.Coreopen import Relation.Binary.Definitionsopen import Relation.Binary.Structuresopen import Relation.Nullary.Construct.Add.Pointprivatevariablea ℓ : LevelA : Set aliftOp : Op₂ A → Op₂ (Pointed A)liftOp op [ p ] [ q ] = [ op p q ]liftOp _ [ p ] ∙ = [ p ]liftOp _ ∙ [ q ] = [ q ]liftOp _ ∙ ∙ = ∙module _ {_≈_ : Rel A ℓ} {op : Op₂ A} (refl-≈ : Reflexive _≈_) whereprivate_≈∙_ = lift≈ _≈_op∙ = liftOp oplift-≈ : ∀ {x y : A} → x ≈ y → [ x ] ≈∙ [ y ]lift-≈ = [_]cong₂ : Congruent₂ _≈_ op → Congruent₂ _≈∙_ (op∙)cong₂ R-cong [ eq-l ] [ eq-r ] = lift-≈ (R-cong eq-l eq-r)cong₂ R-cong [ eq ] ∙≈∙ = lift-≈ eqcong₂ R-cong ∙≈∙ [ eq ] = lift-≈ eqcong₂ R-cong ∙≈∙ ∙≈∙ = ≈∙-refl _≈_ refl-≈assoc : Associative _≈_ op → Associative _≈∙_ (op∙)assoc assoc [ p ] [ q ] [ r ] = lift-≈ (assoc p q r)assoc _ [ p ] [ q ] ∙ = ≈∙-refl _≈_ refl-≈assoc _ [ p ] ∙ [ r ] = ≈∙-refl _≈_ refl-≈assoc _ [ p ] ∙ ∙ = ≈∙-refl _≈_ refl-≈assoc _ ∙ [ r ] [ q ] = ≈∙-refl _≈_ refl-≈assoc _ ∙ [ q ] ∙ = ≈∙-refl _≈_ refl-≈assoc _ ∙ ∙ [ r ] = ≈∙-refl _≈_ refl-≈assoc _ ∙ ∙ ∙ = ≈∙-refl _≈_ refl-≈identityˡ : LeftIdentity _≈∙_ ∙ (op∙)identityˡ [ p ] = ≈∙-refl _≈_ refl-≈identityˡ ∙ = ≈∙-refl _≈_ refl-≈identityʳ : RightIdentity _≈∙_ ∙ (op∙)identityʳ [ p ] = ≈∙-refl _≈_ refl-≈identityʳ ∙ = ≈∙-refl _≈_ refl-≈identity : Identity _≈∙_ ∙ (op∙)identity = identityˡ , identityʳmodule _ {_≈_ : Rel A ℓ} {op : Op₂ A} whereprivate_≈∙_ = lift≈ _≈_op∙ = liftOp opisMagma : IsMagma _≈_ op → IsMagma _≈∙_ op∙isMagma M =record{ isEquivalence = ≈∙-isEquivalence _≈_ M.isEquivalence; ∙-cong = cong₂ M.refl M.∙-cong} where module M = IsMagma MisSemigroup : IsSemigroup _≈_ op → IsSemigroup _≈∙_ op∙isSemigroup S = record{ isMagma = isMagma S.isMagma; assoc = assoc S.refl S.assoc} where module S = IsSemigroup SisMonoid : IsSemigroup _≈_ op → IsMonoid _≈∙_ op∙ ∙isMonoid S = record{ isSemigroup = isSemigroup S; identity = identity S.refl} where module S = IsSemigroup Ssemigroup : Semigroup a (a ⊔ ℓ) → Semigroup a (a ⊔ ℓ)semigroup S = record{ Carrier = Pointed S.Carrier; isSemigroup = isSemigroup S.isSemigroup} where module S = Semigroup Smonoid : Semigroup a (a ⊔ ℓ) → Monoid a (a ⊔ ℓ)monoid S = record{ isMonoid = isMonoid S.isSemigroup} where module S = Semigroup S
-------------------------------------------------------------------------- The Agda standard library---- Relations between properties of functions, such as associativity and-- commutativity, when the underlying relation is a setoid------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitionsusing (Substitutive; Symmetric; Total)module Algebra.Consequences.Setoid {a ℓ} (S : Setoid a ℓ) whereopen Setoid S renaming (Carrier to A)open import Algebra.Coreopen import Algebra.Definitions _≈_open import Data.Sum.Base using (inj₁; inj₂)open import Data.Product.Base using (_,_)open import Function.Base using (_$_; id; _∘_)open import Function.Definitionsimport Relation.Binary.Consequences as Binopen import Relation.Binary.Reasoning.Setoid Sopen import Relation.Unary using (Pred)-------------------------------------------------------------------------- Re-exports-- Export base lemmas that don't require the setoidopen import Algebra.Consequences.Base public-------------------------------------------------------------------------- MiddleFourExchangemodule _ {_∙_ : Op₂ A} (cong : Congruent₂ _∙_) wherecomm∧assoc⇒middleFour : Commutative _∙_ → Associative _∙_ →_∙_ MiddleFourExchange _∙_comm∧assoc⇒middleFour comm assoc w x y z = begin(w ∙ x) ∙ (y ∙ z) ≈⟨ assoc w x (y ∙ z) ⟩w ∙ (x ∙ (y ∙ z)) ≈⟨ cong refl (sym (assoc x y z)) ⟩w ∙ ((x ∙ y) ∙ z) ≈⟨ cong refl (cong (comm x y) refl) ⟩w ∙ ((y ∙ x) ∙ z) ≈⟨ cong refl (assoc y x z) ⟩w ∙ (y ∙ (x ∙ z)) ≈⟨ sym (assoc w y (x ∙ z)) ⟩(w ∙ y) ∙ (x ∙ z) ∎identity∧middleFour⇒assoc : {e : A} → Identity e _∙_ →_∙_ MiddleFourExchange _∙_ →Associative _∙_identity∧middleFour⇒assoc {e} (identityˡ , identityʳ) middleFour x y z = begin(x ∙ y) ∙ z ≈⟨ cong refl (sym (identityˡ z)) ⟩(x ∙ y) ∙ (e ∙ z) ≈⟨ middleFour x y e z ⟩(x ∙ e) ∙ (y ∙ z) ≈⟨ cong (identityʳ x) refl ⟩x ∙ (y ∙ z) ∎identity∧middleFour⇒comm : {_+_ : Op₂ A} {e : A} → Identity e _+_ →_∙_ MiddleFourExchange _+_ →Commutative _∙_identity∧middleFour⇒comm {_+_} {e} (identityˡ , identityʳ) middleFour x y= beginx ∙ y ≈⟨ sym (cong (identityˡ x) (identityʳ y)) ⟩(e + x) ∙ (y + e) ≈⟨ middleFour e x y e ⟩(e + y) ∙ (x + e) ≈⟨ cong (identityˡ y) (identityʳ x) ⟩y ∙ x ∎-------------------------------------------------------------------------- SelfInversemodule _ {f : Op₁ A} (self : SelfInverse f) whereselfInverse⇒involutive : Involutive fselfInverse⇒involutive = reflexive∧selfInverse⇒involutive _≈_ refl selfselfInverse⇒congruent : Congruent _≈_ _≈_ fselfInverse⇒congruent {x} {y} x≈y = sym (self (beginf (f x) ≈⟨ selfInverse⇒involutive x ⟩x ≈⟨ x≈y ⟩y ∎))selfInverse⇒inverseᵇ : Inverseᵇ _≈_ _≈_ f fselfInverse⇒inverseᵇ = self ∘ sym , self ∘ symselfInverse⇒surjective : Surjective _≈_ _≈_ fselfInverse⇒surjective y = f y , self ∘ symselfInverse⇒injective : Injective _≈_ _≈_ fselfInverse⇒injective {x} {y} x≈y = beginx ≈⟨ self x≈y ⟨f (f y) ≈⟨ selfInverse⇒involutive y ⟩y ∎selfInverse⇒bijective : Bijective _≈_ _≈_ fselfInverse⇒bijective = selfInverse⇒injective , selfInverse⇒surjective-------------------------------------------------------------------------- Magma-like structuresmodule _ {_∙_ : Op₂ A} (comm : Commutative _∙_) wherecomm∧cancelˡ⇒cancelʳ : LeftCancellative _∙_ → RightCancellative _∙_comm∧cancelˡ⇒cancelʳ cancelˡ x y z eq = cancelˡ x y z $ beginx ∙ y ≈⟨ comm x y ⟩y ∙ x ≈⟨ eq ⟩z ∙ x ≈⟨ comm z x ⟩x ∙ z ∎comm∧cancelʳ⇒cancelˡ : RightCancellative _∙_ → LeftCancellative _∙_comm∧cancelʳ⇒cancelˡ cancelʳ x y z eq = cancelʳ x y z $ beginy ∙ x ≈⟨ comm y x ⟩x ∙ y ≈⟨ eq ⟩x ∙ z ≈⟨ comm x z ⟩z ∙ x ∎-------------------------------------------------------------------------- Monoid-like structuresmodule _ {_∙_ : Op₂ A} (comm : Commutative _∙_) {e : A} wherecomm∧idˡ⇒idʳ : LeftIdentity e _∙_ → RightIdentity e _∙_comm∧idˡ⇒idʳ idˡ x = beginx ∙ e ≈⟨ comm x e ⟩e ∙ x ≈⟨ idˡ x ⟩x ∎comm∧idʳ⇒idˡ : RightIdentity e _∙_ → LeftIdentity e _∙_comm∧idʳ⇒idˡ idʳ x = begine ∙ x ≈⟨ comm e x ⟩x ∙ e ≈⟨ idʳ x ⟩x ∎comm∧idˡ⇒id : LeftIdentity e _∙_ → Identity e _∙_comm∧idˡ⇒id idˡ = idˡ , comm∧idˡ⇒idʳ idˡcomm∧idʳ⇒id : RightIdentity e _∙_ → Identity e _∙_comm∧idʳ⇒id idʳ = comm∧idʳ⇒idˡ idʳ , idʳcomm∧zeˡ⇒zeʳ : LeftZero e _∙_ → RightZero e _∙_comm∧zeˡ⇒zeʳ zeˡ x = beginx ∙ e ≈⟨ comm x e ⟩e ∙ x ≈⟨ zeˡ x ⟩e ∎comm∧zeʳ⇒zeˡ : RightZero e _∙_ → LeftZero e _∙_comm∧zeʳ⇒zeˡ zeʳ x = begine ∙ x ≈⟨ comm e x ⟩x ∙ e ≈⟨ zeʳ x ⟩e ∎comm∧zeˡ⇒ze : LeftZero e _∙_ → Zero e _∙_comm∧zeˡ⇒ze zeˡ = zeˡ , comm∧zeˡ⇒zeʳ zeˡcomm∧zeʳ⇒ze : RightZero e _∙_ → Zero e _∙_comm∧zeʳ⇒ze zeʳ = comm∧zeʳ⇒zeˡ zeʳ , zeʳcomm∧almostCancelˡ⇒almostCancelʳ : AlmostLeftCancellative e _∙_ →AlmostRightCancellative e _∙_comm∧almostCancelˡ⇒almostCancelʳ cancelˡ-nonZero x y z x≉e yx≈zx =cancelˡ-nonZero x y z x≉e $ beginx ∙ y ≈⟨ comm x y ⟩y ∙ x ≈⟨ yx≈zx ⟩z ∙ x ≈⟨ comm z x ⟩x ∙ z ∎comm∧almostCancelʳ⇒almostCancelˡ : AlmostRightCancellative e _∙_ →AlmostLeftCancellative e _∙_comm∧almostCancelʳ⇒almostCancelˡ cancelʳ-nonZero x y z x≉e xy≈xz =cancelʳ-nonZero x y z x≉e $ beginy ∙ x ≈⟨ comm y x ⟩x ∙ y ≈⟨ xy≈xz ⟩x ∙ z ≈⟨ comm x z ⟩z ∙ x ∎-------------------------------------------------------------------------- Group-like structuresmodule _ {_∙_ : Op₂ A} {_⁻¹ : Op₁ A} {e} (comm : Commutative _∙_) wherecomm∧invˡ⇒invʳ : LeftInverse e _⁻¹ _∙_ → RightInverse e _⁻¹ _∙_comm∧invˡ⇒invʳ invˡ x = beginx ∙ (x ⁻¹) ≈⟨ comm x (x ⁻¹) ⟩(x ⁻¹) ∙ x ≈⟨ invˡ x ⟩e ∎comm∧invˡ⇒inv : LeftInverse e _⁻¹ _∙_ → Inverse e _⁻¹ _∙_comm∧invˡ⇒inv invˡ = invˡ , comm∧invˡ⇒invʳ invˡcomm∧invʳ⇒invˡ : RightInverse e _⁻¹ _∙_ → LeftInverse e _⁻¹ _∙_comm∧invʳ⇒invˡ invʳ x = begin(x ⁻¹) ∙ x ≈⟨ comm (x ⁻¹) x ⟩x ∙ (x ⁻¹) ≈⟨ invʳ x ⟩e ∎comm∧invʳ⇒inv : RightInverse e _⁻¹ _∙_ → Inverse e _⁻¹ _∙_comm∧invʳ⇒inv invʳ = comm∧invʳ⇒invˡ invʳ , invʳmodule _ {_∙_ : Op₂ A} {_⁻¹ : Op₁ A} {e} (cong : Congruent₂ _∙_) whereassoc∧id∧invʳ⇒invˡ-unique : Associative _∙_ →Identity e _∙_ → RightInverse e _⁻¹ _∙_ →∀ x y → (x ∙ y) ≈ e → x ≈ (y ⁻¹)assoc∧id∧invʳ⇒invˡ-unique assoc (idˡ , idʳ) invʳ x y eq = beginx ≈⟨ sym (idʳ x) ⟩x ∙ e ≈⟨ cong refl (sym (invʳ y)) ⟩x ∙ (y ∙ (y ⁻¹)) ≈⟨ sym (assoc x y (y ⁻¹)) ⟩(x ∙ y) ∙ (y ⁻¹) ≈⟨ cong eq refl ⟩e ∙ (y ⁻¹) ≈⟨ idˡ (y ⁻¹) ⟩y ⁻¹ ∎assoc∧id∧invˡ⇒invʳ-unique : Associative _∙_ →Identity e _∙_ → LeftInverse e _⁻¹ _∙_ →∀ x y → (x ∙ y) ≈ e → y ≈ (x ⁻¹)assoc∧id∧invˡ⇒invʳ-unique assoc (idˡ , idʳ) invˡ x y eq = beginy ≈⟨ sym (idˡ y) ⟩e ∙ y ≈⟨ cong (sym (invˡ x)) refl ⟩((x ⁻¹) ∙ x) ∙ y ≈⟨ assoc (x ⁻¹) x y ⟩(x ⁻¹) ∙ (x ∙ y) ≈⟨ cong refl eq ⟩(x ⁻¹) ∙ e ≈⟨ idʳ (x ⁻¹) ⟩x ⁻¹ ∎-------------------------------------------------------------------------- Bisemigroup-like structuresmodule _ {_∙_ _◦_ : Op₂ A}(◦-cong : Congruent₂ _◦_)(∙-comm : Commutative _∙_)wherecomm∧distrˡ⇒distrʳ : _∙_ DistributesOverˡ _◦_ → _∙_ DistributesOverʳ _◦_comm∧distrˡ⇒distrʳ distrˡ x y z = begin(y ◦ z) ∙ x ≈⟨ ∙-comm (y ◦ z) x ⟩x ∙ (y ◦ z) ≈⟨ distrˡ x y z ⟩(x ∙ y) ◦ (x ∙ z) ≈⟨ ◦-cong (∙-comm x y) (∙-comm x z) ⟩(y ∙ x) ◦ (z ∙ x) ∎comm∧distrʳ⇒distrˡ : _∙_ DistributesOverʳ _◦_ → _∙_ DistributesOverˡ _◦_comm∧distrʳ⇒distrˡ distrˡ x y z = beginx ∙ (y ◦ z) ≈⟨ ∙-comm x (y ◦ z) ⟩(y ◦ z) ∙ x ≈⟨ distrˡ x y z ⟩(y ∙ x) ◦ (z ∙ x) ≈⟨ ◦-cong (∙-comm y x) (∙-comm z x) ⟩(x ∙ y) ◦ (x ∙ z) ∎comm∧distrˡ⇒distr : _∙_ DistributesOverˡ _◦_ → _∙_ DistributesOver _◦_comm∧distrˡ⇒distr distrˡ = distrˡ , comm∧distrˡ⇒distrʳ distrˡcomm∧distrʳ⇒distr : _∙_ DistributesOverʳ _◦_ → _∙_ DistributesOver _◦_comm∧distrʳ⇒distr distrʳ = comm∧distrʳ⇒distrˡ distrʳ , distrʳcomm⇒sym[distribˡ] : ∀ x → Symmetric (λ y z → (x ◦ (y ∙ z)) ≈ ((x ◦ y) ∙ (x ◦ z)))comm⇒sym[distribˡ] x {y} {z} prf = beginx ◦ (z ∙ y) ≈⟨ ◦-cong refl (∙-comm z y) ⟩x ◦ (y ∙ z) ≈⟨ prf ⟩(x ◦ y) ∙ (x ◦ z) ≈⟨ ∙-comm (x ◦ y) (x ◦ z) ⟩(x ◦ z) ∙ (x ◦ y) ∎module _ {_∙_ _◦_ : Op₂ A}(∙-cong : Congruent₂ _∙_)(∙-assoc : Associative _∙_)(◦-comm : Commutative _◦_)wheredistrib∧absorbs⇒distribˡ : _∙_ Absorbs _◦_ →_◦_ Absorbs _∙_ →_◦_ DistributesOver _∙_ →_∙_ DistributesOverˡ _◦_distrib∧absorbs⇒distribˡ ∙-absorbs-◦ ◦-absorbs-∙ (◦-distribˡ-∙ , ◦-distribʳ-∙) x y z = beginx ∙ (y ◦ z) ≈⟨ ∙-cong (∙-absorbs-◦ _ _) refl ⟨(x ∙ (x ◦ y)) ∙ (y ◦ z) ≈⟨ ∙-cong (∙-cong refl (◦-comm _ _)) refl ⟩(x ∙ (y ◦ x)) ∙ (y ◦ z) ≈⟨ ∙-assoc _ _ _ ⟩x ∙ ((y ◦ x) ∙ (y ◦ z)) ≈⟨ ∙-cong refl (◦-distribˡ-∙ _ _ _) ⟨x ∙ (y ◦ (x ∙ z)) ≈⟨ ∙-cong (◦-absorbs-∙ _ _) refl ⟨(x ◦ (x ∙ z)) ∙ (y ◦ (x ∙ z)) ≈⟨ ◦-distribʳ-∙ _ _ _ ⟨(x ∙ y) ◦ (x ∙ z) ∎-------------------------------------------------------------------------- Ring-like structuresmodule _ {_+_ _*_ : Op₂ A}{_⁻¹ : Op₁ A} {0# : A}(+-cong : Congruent₂ _+_)(*-cong : Congruent₂ _*_)whereassoc∧distribʳ∧idʳ∧invʳ⇒zeˡ : Associative _+_ → _*_ DistributesOverʳ _+_ →RightIdentity 0# _+_ → RightInverse 0# _⁻¹ _+_ →LeftZero 0# _*_assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ +-assoc distribʳ idʳ invʳ x = begin0# * x ≈⟨ sym (idʳ _) ⟩(0# * x) + 0# ≈⟨ +-cong refl (sym (invʳ _)) ⟩(0# * x) + ((0# * x) + ((0# * x)⁻¹)) ≈⟨ sym (+-assoc _ _ _) ⟩((0# * x) + (0# * x)) + ((0# * x)⁻¹) ≈⟨ +-cong (sym (distribʳ _ _ _)) refl ⟩((0# + 0#) * x) + ((0# * x)⁻¹) ≈⟨ +-cong (*-cong (idʳ _) refl) refl ⟩(0# * x) + ((0# * x)⁻¹) ≈⟨ invʳ _ ⟩0# ∎assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ : Associative _+_ → _*_ DistributesOverˡ _+_ →RightIdentity 0# _+_ → RightInverse 0# _⁻¹ _+_ →RightZero 0# _*_assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ +-assoc distribˡ idʳ invʳ x = beginx * 0# ≈⟨ sym (idʳ _) ⟩(x * 0#) + 0# ≈⟨ +-cong refl (sym (invʳ _)) ⟩(x * 0#) + ((x * 0#) + ((x * 0#)⁻¹)) ≈⟨ sym (+-assoc _ _ _) ⟩((x * 0#) + (x * 0#)) + ((x * 0#)⁻¹) ≈⟨ +-cong (sym (distribˡ _ _ _)) refl ⟩(x * (0# + 0#)) + ((x * 0#)⁻¹) ≈⟨ +-cong (*-cong refl (idʳ _)) refl ⟩((x * 0#) + ((x * 0#)⁻¹)) ≈⟨ invʳ _ ⟩0# ∎-------------------------------------------------------------------------- Without Loss of Generalitymodule _ {p} {f : Op₂ A} {P : Pred A p}(≈-subst : Substitutive _≈_ p)(comm : Commutative f)wheresubst∧comm⇒sym : Symmetric (λ a b → P (f a b))subst∧comm⇒sym = ≈-subst P (comm _ _)wlog : ∀ {r} {_R_ : Rel _ r} → Total _R_ →(∀ a b → a R b → P (f a b)) →∀ a b → P (f a b)wlog r-total = Bin.wlog r-total subst∧comm⇒sym-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0comm+assoc⇒middleFour = comm∧assoc⇒middleFour{-# WARNING_ON_USAGE comm+assoc⇒middleFour"Warning: comm+assoc⇒middleFour was deprecated in v2.0.Please use comm∧assoc⇒middleFour instead."#-}identity+middleFour⇒assoc = identity∧middleFour⇒assoc{-# WARNING_ON_USAGE identity+middleFour⇒assoc"Warning: identity+middleFour⇒assoc was deprecated in v2.0.Please use identity∧middleFour⇒assoc instead."#-}identity+middleFour⇒comm = identity∧middleFour⇒comm{-# WARNING_ON_USAGE identity+middleFour⇒comm"Warning: identity+middleFour⇒comm was deprecated in v2.0.Please use identity∧middleFour⇒comm instead."#-}comm+cancelˡ⇒cancelʳ = comm∧cancelˡ⇒cancelʳ{-# WARNING_ON_USAGE comm+cancelˡ⇒cancelʳ"Warning: comm+cancelˡ⇒cancelʳ was deprecated in v2.0.Please use comm∧cancelˡ⇒cancelʳ instead."#-}comm+cancelʳ⇒cancelˡ = comm∧cancelʳ⇒cancelˡ{-# WARNING_ON_USAGE comm+cancelʳ⇒cancelˡ"Warning: comm+cancelʳ⇒cancelˡ was deprecated in v2.0.Please use comm∧cancelʳ⇒cancelˡ instead."#-}comm+idˡ⇒idʳ = comm∧idˡ⇒idʳ{-# WARNING_ON_USAGE comm+idˡ⇒idʳ"Warning: comm+idˡ⇒idʳ was deprecated in v2.0.Please use comm∧idˡ⇒idʳ instead."#-}comm+idʳ⇒idˡ = comm∧idʳ⇒idˡ{-# WARNING_ON_USAGE comm+idʳ⇒idˡ"Warning: comm+idʳ⇒idˡ was deprecated in v2.0.Please use comm∧idʳ⇒idˡ instead."#-}comm+zeˡ⇒zeʳ = comm∧zeˡ⇒zeʳ{-# WARNING_ON_USAGE comm+zeˡ⇒zeʳ"Warning: comm+zeˡ⇒zeʳ was deprecated in v2.0.Please use comm∧zeˡ⇒zeʳ instead."#-}comm+zeʳ⇒zeˡ = comm∧zeʳ⇒zeˡ{-# WARNING_ON_USAGE comm+zeʳ⇒zeˡ"Warning: comm+zeʳ⇒zeˡ was deprecated in v2.0.Please use comm∧zeʳ⇒zeˡ instead."#-}comm+almostCancelˡ⇒almostCancelʳ = comm∧almostCancelˡ⇒almostCancelʳ{-# WARNING_ON_USAGE comm+almostCancelˡ⇒almostCancelʳ"Warning: comm+almostCancelˡ⇒almostCancelʳ was deprecated in v2.0.Please use comm∧almostCancelˡ⇒almostCancelʳ instead."#-}comm+almostCancelʳ⇒almostCancelˡ = comm∧almostCancelʳ⇒almostCancelˡ{-# WARNING_ON_USAGE comm+almostCancelʳ⇒almostCancelˡ"Warning: comm+almostCancelʳ⇒almostCancelˡ was deprecated in v2.0.Please use comm∧almostCancelʳ⇒almostCancelˡ instead."#-}comm+invˡ⇒invʳ = comm∧invˡ⇒invʳ{-# WARNING_ON_USAGE comm+invˡ⇒invʳ"Warning: comm+invˡ⇒invʳ was deprecated in v2.0.Please use comm∧invˡ⇒invʳ instead."#-}comm+invʳ⇒invˡ = comm∧invʳ⇒invˡ{-# WARNING_ON_USAGE comm+invʳ⇒invˡ"Warning: comm+invʳ⇒invˡ was deprecated in v2.0.Please use comm∧invʳ⇒invˡ instead."#-}comm+invˡ⇒inv = comm∧invˡ⇒inv{-# WARNING_ON_USAGE comm+invˡ⇒inv"Warning: comm+invˡ⇒inv was deprecated in v2.0.Please use comm∧invˡ⇒inv instead."#-}comm+invʳ⇒inv = comm∧invʳ⇒inv{-# WARNING_ON_USAGE comm+invʳ⇒inv"Warning: comm+invʳ⇒inv was deprecated in v2.0.Please use comm∧invʳ⇒inv instead."#-}comm+distrˡ⇒distrʳ = comm∧distrˡ⇒distrʳ{-# WARNING_ON_USAGE comm+distrˡ⇒distrʳ"Warning: comm+distrˡ⇒distrʳ was deprecated in v2.0.Please use comm∧distrˡ⇒distrʳ instead."#-}comm+distrʳ⇒distrˡ = comm∧distrʳ⇒distrˡ{-# WARNING_ON_USAGE comm+distrʳ⇒distrˡ"Warning: comm+distrʳ⇒distrˡ was deprecated in v2.0.Please use comm∧distrʳ⇒distrˡ instead."#-}assoc+distribʳ+idʳ+invʳ⇒zeˡ = assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ{-# WARNING_ON_USAGE assoc+distribʳ+idʳ+invʳ⇒zeˡ"Warning: assoc+distribʳ+idʳ+invʳ⇒zeˡ was deprecated in v2.0.Please use assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ instead."#-}assoc+distribˡ+idʳ+invʳ⇒zeʳ = assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ{-# WARNING_ON_USAGE assoc+distribˡ+idʳ+invʳ⇒zeʳ"Warning: assoc+distribˡ+idʳ+invʳ⇒zeʳ was deprecated in v2.0.Please use assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ instead."#-}assoc+id+invʳ⇒invˡ-unique = assoc∧id∧invʳ⇒invˡ-unique{-# WARNING_ON_USAGE assoc+id+invʳ⇒invˡ-unique"Warning: assoc+id+invʳ⇒invˡ-unique was deprecated in v2.0.Please use assoc∧id∧invʳ⇒invˡ-unique instead."#-}assoc+id+invˡ⇒invʳ-unique = assoc∧id∧invˡ⇒invʳ-unique{-# WARNING_ON_USAGE assoc+id+invˡ⇒invʳ-unique"Warning: assoc+id+invˡ⇒invʳ-unique was deprecated in v2.0.Please use assoc∧id∧invˡ⇒invʳ-unique instead."#-}subst+comm⇒sym = subst∧comm⇒sym{-# WARNING_ON_USAGE subst+comm⇒sym"Warning: subst+comm⇒sym was deprecated in v2.0.Please use subst∧comm⇒sym instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Relations between properties of functions, such as associativity and-- commutativity (specialised to propositional equality)------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Consequences.Propositional{a} {A : Set a} whereopen import Data.Sum.Base using (inj₁; inj₂)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (Setoid)open import Relation.Binary.Definitions using (Symmetric; Total)open import Relation.Binary.PropositionalEquality.Coreusing (_≡_; cong₂; subst)open import Relation.Binary.PropositionalEquality.Propertiesusing (setoid)open import Relation.Unary using (Pred)open import Algebra.Coreopen import Algebra.Definitions {A = A} _≡_import Algebra.Consequences.Setoid (setoid A) as Base-------------------------------------------------------------------------- Re-export all proofs that don't require congruence or substitutivityopen Base publichiding( comm∧assoc⇒middleFour; identity∧middleFour⇒assoc; identity∧middleFour⇒comm; assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ; assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ; assoc∧id∧invʳ⇒invˡ-unique; assoc∧id∧invˡ⇒invʳ-unique; comm∧distrˡ⇒distrʳ; comm∧distrʳ⇒distrˡ; comm⇒sym[distribˡ]; subst∧comm⇒sym; wlog; sel⇒idem-- plus all the deprecated versions of the above; comm+assoc⇒middleFour; identity+middleFour⇒assoc; identity+middleFour⇒comm; assoc+distribʳ+idʳ+invʳ⇒zeˡ; assoc+distribˡ+idʳ+invʳ⇒zeʳ; assoc+id+invʳ⇒invˡ-unique; assoc+id+invˡ⇒invʳ-unique; comm+distrˡ⇒distrʳ; comm+distrʳ⇒distrˡ; subst+comm⇒sym)-------------------------------------------------------------------------- Group-like structuresmodule _ {_∙_ _⁻¹ ε} whereassoc∧id∧invʳ⇒invˡ-unique : Associative _∙_ → Identity ε _∙_ →RightInverse ε _⁻¹ _∙_ →∀ x y → (x ∙ y) ≡ ε → x ≡ (y ⁻¹)assoc∧id∧invʳ⇒invˡ-unique = Base.assoc∧id∧invʳ⇒invˡ-unique (cong₂ _)assoc∧id∧invˡ⇒invʳ-unique : Associative _∙_ → Identity ε _∙_ →LeftInverse ε _⁻¹ _∙_ →∀ x y → (x ∙ y) ≡ ε → y ≡ (x ⁻¹)assoc∧id∧invˡ⇒invʳ-unique = Base.assoc∧id∧invˡ⇒invʳ-unique (cong₂ _)-------------------------------------------------------------------------- Ring-like structuresmodule _ {_+_ _*_ -_ 0#} whereassoc∧distribʳ∧idʳ∧invʳ⇒zeˡ : Associative _+_ → _*_ DistributesOverʳ _+_ →RightIdentity 0# _+_ → RightInverse 0# -_ _+_ →LeftZero 0# _*_assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ =Base.assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ (cong₂ _+_) (cong₂ _*_)assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ : Associative _+_ → _*_ DistributesOverˡ _+_ →RightIdentity 0# _+_ → RightInverse 0# -_ _+_ →RightZero 0# _*_assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ =Base.assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ (cong₂ _+_) (cong₂ _*_)-------------------------------------------------------------------------- Bisemigroup-like structuresmodule _ {_∙_ _◦_ : Op₂ A} (∙-comm : Commutative _∙_) wherecomm∧distrˡ⇒distrʳ : _∙_ DistributesOverˡ _◦_ → _∙_ DistributesOverʳ _◦_comm∧distrˡ⇒distrʳ = Base.comm+distrˡ⇒distrʳ (cong₂ _) ∙-commcomm∧distrʳ⇒distrˡ : _∙_ DistributesOverʳ _◦_ → _∙_ DistributesOverˡ _◦_comm∧distrʳ⇒distrˡ = Base.comm∧distrʳ⇒distrˡ (cong₂ _) ∙-commcomm⇒sym[distribˡ] : ∀ x → Symmetric (λ y z → (x ◦ (y ∙ z)) ≡ ((x ◦ y) ∙ (x ◦ z)))comm⇒sym[distribˡ] = Base.comm⇒sym[distribˡ] (cong₂ _◦_) ∙-comm-------------------------------------------------------------------------- Selectivitymodule _ {_∙_ : Op₂ A} wheresel⇒idem : Selective _∙_ → Idempotent _∙_sel⇒idem = Base.sel⇒idem _≡_-------------------------------------------------------------------------- Middle-Four Exchangemodule _ {_∙_ : Op₂ A} wherecomm∧assoc⇒middleFour : Commutative _∙_ → Associative _∙_ →_∙_ MiddleFourExchange _∙_comm∧assoc⇒middleFour = Base.comm∧assoc⇒middleFour (cong₂ _∙_)identity∧middleFour⇒assoc : {e : A} → Identity e _∙_ →_∙_ MiddleFourExchange _∙_ →Associative _∙_identity∧middleFour⇒assoc = Base.identity∧middleFour⇒assoc (cong₂ _∙_)identity∧middleFour⇒comm : {_+_ : Op₂ A} {e : A} → Identity e _+_ →_∙_ MiddleFourExchange _+_ →Commutative _∙_identity∧middleFour⇒comm = Base.identity∧middleFour⇒comm (cong₂ _∙_)-------------------------------------------------------------------------- Without Loss of Generalitymodule _ {p} {P : Pred A p} wheresubst∧comm⇒sym : ∀ {f} (f-comm : Commutative f) →Symmetric (λ a b → P (f a b))subst∧comm⇒sym = Base.subst∧comm⇒sym {P = P} substwlog : ∀ {f} (f-comm : Commutative f) →∀ {r} {_R_ : Rel _ r} → Total _R_ →(∀ a b → a R b → P (f a b)) →∀ a b → P (f a b)wlog = Base.wlog {P = P} subst-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0comm+assoc⇒middleFour = comm∧assoc⇒middleFour{-# WARNING_ON_USAGE comm+assoc⇒middleFour"Warning: comm+assoc⇒middleFour was deprecated in v2.0.Please use comm∧assoc⇒middleFour instead."#-}identity+middleFour⇒assoc = identity∧middleFour⇒assoc{-# WARNING_ON_USAGE identity+middleFour⇒assoc"Warning: identity+middleFour⇒assoc was deprecated in v2.0.Please use identity∧middleFour⇒assoc instead."#-}identity+middleFour⇒comm = identity∧middleFour⇒comm{-# WARNING_ON_USAGE identity+middleFour⇒comm"Warning: identity+middleFour⇒comm was deprecated in v2.0.Please use identity∧middleFour⇒comm instead."#-}comm+distrˡ⇒distrʳ = comm∧distrˡ⇒distrʳ{-# WARNING_ON_USAGE comm+distrˡ⇒distrʳ"Warning: comm+distrˡ⇒distrʳ was deprecated in v2.0.Please use comm∧distrˡ⇒distrʳ instead."#-}comm+distrʳ⇒distrˡ = comm∧distrʳ⇒distrˡ{-# WARNING_ON_USAGE comm+distrʳ⇒distrˡ"Warning: comm+distrʳ⇒distrˡ was deprecated in v2.0.Please use comm∧distrʳ⇒distrˡ instead."#-}assoc+distribʳ+idʳ+invʳ⇒zeˡ = assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ{-# WARNING_ON_USAGE assoc+distribʳ+idʳ+invʳ⇒zeˡ"Warning: assoc+distribʳ+idʳ+invʳ⇒zeˡ was deprecated in v2.0.Please use assoc∧distribʳ∧idʳ∧invʳ⇒zeˡ instead."#-}assoc+distribˡ+idʳ+invʳ⇒zeʳ = assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ{-# WARNING_ON_USAGE assoc+distribˡ+idʳ+invʳ⇒zeʳ"Warning: assoc+distribˡ+idʳ+invʳ⇒zeʳ was deprecated in v2.0.Please use assoc∧distribˡ∧idʳ∧invʳ⇒zeʳ instead."#-}assoc+id+invʳ⇒invˡ-unique = assoc∧id∧invʳ⇒invˡ-unique{-# WARNING_ON_USAGE assoc+id+invʳ⇒invˡ-unique"Warning: assoc+id+invʳ⇒invˡ-unique was deprecated in v2.0.Please use assoc∧id∧invʳ⇒invˡ-unique instead."#-}assoc+id+invˡ⇒invʳ-unique = assoc∧id∧invˡ⇒invʳ-unique{-# WARNING_ON_USAGE assoc+id+invˡ⇒invʳ-unique"Warning: assoc+id+invˡ⇒invʳ-unique was deprecated in v2.0.Please use assoc∧id∧invˡ⇒invʳ-unique instead."#-}subst+comm⇒sym = subst∧comm⇒sym{-# WARNING_ON_USAGE subst+comm⇒sym"Warning: subst+comm⇒sym was deprecated in v2.0.Please use subst∧comm⇒sym instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Lemmas relating algebraic definitions (such as associativity and-- commutativity) that don't require the equality relation to be a setoid.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Consequences.Base{a} {A : Set a} whereopen import Algebra.Coreopen import Algebra.Definitionsopen import Data.Sum.Baseopen import Relation.Binary.Coreopen import Relation.Binary.Definitions using (Reflexive)module _ {ℓ} {_•_ : Op₂ A} (_≈_ : Rel A ℓ) wheresel⇒idem : Selective _≈_ _•_ → Idempotent _≈_ _•_sel⇒idem sel x = reduce (sel x x)module _ {ℓ} {f : Op₁ A} (_≈_ : Rel A ℓ) wherereflexive∧selfInverse⇒involutive : Reflexive _≈_ →SelfInverse _≈_ f →Involutive _≈_ freflexive∧selfInverse⇒involutive refl inv _ = inv refl-------------------------------------------------------------------------- DEPRECATED NAMES-------------------------------------------------------------------------- Please use the new names as continuing support for the old names is-- not guaranteed.-- Version 2.0reflexive+selfInverse⇒involutive = reflexive∧selfInverse⇒involutive{-# WARNING_ON_USAGE reflexive+selfInverse⇒involutive"Warning: reflexive+selfInverse⇒involutive was deprecated in v2.0.Please use reflexive∧selfInverse⇒involutive instead."#-}
-------------------------------------------------------------------------- The Agda standard library---- Definitions of algebraic structures like monoids and rings-- (packed in records together with sets, operations, etc.)-------------------------------------------------------------------------- The contents of this module should be accessed via `Algebra`.{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Bundles whereimport Algebra.Bundles.Raw as Rawopen import Algebra.Coreopen import Algebra.Structuresopen import Relation.Binary.Core using (Rel)open import Level-------------------------------------------------------------------------- Re-export definitions of 'raw' bundlesopen Raw publicusing ( RawSuccessorSet; RawMagma; RawMonoid; RawGroup; RawNearSemiring; RawSemiring; RawRingWithoutOne; RawRing; RawQuasigroup; RawLoop; RawKleeneAlgebra)-------------------------------------------------------------------------- Bundles with 1 unary operation & 1 element------------------------------------------------------------------------record SuccessorSet c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓsuc# : Op₁ Carrierzero# : CarrierisSuccessorSet : IsSuccessorSet _≈_ suc# zero#open IsSuccessorSet isSuccessorSet publicrawSuccessorSet : RawSuccessorSet _ _rawSuccessorSet = record { _≈_ = _≈_; suc# = suc#; zero# = zero# }open RawSuccessorSet rawSuccessorSet public-------------------------------------------------------------------------- Bundles with 1 binary operation------------------------------------------------------------------------record Magma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisMagma : IsMagma _≈_ _∙_open IsMagma isMagma publicrawMagma : RawMagma _ _rawMagma = record { _≈_ = _≈_; _∙_ = _∙_ }open RawMagma rawMagma publicusing (_≉_)record SelectiveMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisSelectiveMagma : IsSelectiveMagma _≈_ _∙_open IsSelectiveMagma isSelectiveMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma public using (rawMagma)record CommutativeMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisCommutativeMagma : IsCommutativeMagma _≈_ _∙_open IsCommutativeMagma isCommutativeMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma public using (rawMagma)record IdempotentMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisIdempotentMagma : IsIdempotentMagma _≈_ _∙_open IsIdempotentMagma isIdempotentMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (rawMagma)record AlternativeMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisAlternativeMagma : IsAlternativeMagma _≈_ _∙_open IsAlternativeMagma isAlternativeMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (rawMagma)record FlexibleMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisFlexibleMagma : IsFlexibleMagma _≈_ _∙_open IsFlexibleMagma isFlexibleMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (rawMagma)record MedialMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisMedialMagma : IsMedialMagma _≈_ _∙_open IsMedialMagma isMedialMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (rawMagma)record SemimedialMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisSemimedialMagma : IsSemimedialMagma _≈_ _∙_open IsSemimedialMagma isSemimedialMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (rawMagma)record Semigroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisSemigroup : IsSemigroup _≈_ _∙_open IsSemigroup isSemigroup publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (_≉_; rawMagma)record Band c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisBand : IsBand _≈_ _∙_open IsBand isBand publicsemigroup : Semigroup c ℓsemigroup = record { isSemigroup = isSemigroup }open Semigroup semigroup publicusing (_≉_; magma; rawMagma)record CommutativeSemigroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisCommutativeSemigroup : IsCommutativeSemigroup _≈_ _∙_open IsCommutativeSemigroup isCommutativeSemigroup publicsemigroup : Semigroup c ℓsemigroup = record { isSemigroup = isSemigroup }open Semigroup semigroup publicusing (_≉_; magma; rawMagma)commutativeMagma : CommutativeMagma c ℓcommutativeMagma = record { isCommutativeMagma = isCommutativeMagma }record CommutativeBand c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisCommutativeBand : IsCommutativeBand _≈_ _∙_open IsCommutativeBand isCommutativeBand publicband : Band _ _band = record { isBand = isBand }open Band band publicusing (_≉_; magma; rawMagma; semigroup)commutativeSemigroup : CommutativeSemigroup c ℓcommutativeSemigroup = record { isCommutativeSemigroup = isCommutativeSemigroup }open CommutativeSemigroup commutativeSemigroup publicusing (commutativeMagma)-------------------------------------------------------------------------- Bundles with 1 binary operation & 1 element------------------------------------------------------------------------record UnitalMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisUnitalMagma : IsUnitalMagma _≈_ _∙_ εopen IsUnitalMagma isUnitalMagma publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (_≉_; rawMagma)record Monoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisMonoid : IsMonoid _≈_ _∙_ εopen IsMonoid isMonoid publicsemigroup : Semigroup _ _semigroup = record { isSemigroup = isSemigroup }open Semigroup semigroup publicusing (_≉_; rawMagma; magma)rawMonoid : RawMonoid _ _rawMonoid = record { _≈_ = _≈_; _∙_ = _∙_; ε = ε}unitalMagma : UnitalMagma _ _unitalMagma = record { isUnitalMagma = isUnitalMagma }record CommutativeMonoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisCommutativeMonoid : IsCommutativeMonoid _≈_ _∙_ εopen IsCommutativeMonoid isCommutativeMonoid publicmonoid : Monoid _ _monoid = record { isMonoid = isMonoid }open Monoid monoid publicusing (_≉_; rawMagma; magma; semigroup; unitalMagma; rawMonoid)commutativeSemigroup : CommutativeSemigroup _ _commutativeSemigroup = record { isCommutativeSemigroup = isCommutativeSemigroup }open CommutativeSemigroup commutativeSemigroup publicusing (commutativeMagma)record IdempotentMonoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisIdempotentMonoid : IsIdempotentMonoid _≈_ _∙_ εopen IsIdempotentMonoid isIdempotentMonoid publicmonoid : Monoid _ _monoid = record { isMonoid = isMonoid }open Monoid monoid publicusing (_≉_; rawMagma; magma; semigroup; unitalMagma; rawMonoid)band : Band _ _band = record { isBand = isBand }record IdempotentCommutativeMonoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierisIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _≈_ _∙_ εopen IsIdempotentCommutativeMonoid isIdempotentCommutativeMonoid publiccommutativeMonoid : CommutativeMonoid _ _commutativeMonoid = record { isCommutativeMonoid = isCommutativeMonoid }idempotentMonoid : IdempotentMonoid _ _idempotentMonoid = record { isIdempotentMonoid = isIdempotentMonoid }commutativeBand : CommutativeBand _ _commutativeBand = record { isCommutativeBand = isCommutativeBand }open CommutativeMonoid commutativeMonoid publicusing( _≉_; rawMagma; magma; unitalMagma; commutativeMagma; semigroup; commutativeSemigroup; rawMonoid; monoid)open CommutativeBand commutativeBand publicusing (band)-- Idempotent commutative monoids are also known as bounded lattices.-- Note that the BoundedLattice necessarily uses the notation inherited-- from monoids rather than lattices.BoundedLattice = IdempotentCommutativeMonoidmodule BoundedLattice {c ℓ} (idemCommMonoid : IdempotentCommutativeMonoid c ℓ) =IdempotentCommutativeMonoid idemCommMonoid-------------------------------------------------------------------------- Bundles with 1 binary operation, 1 unary operation & 1 element------------------------------------------------------------------------record InvertibleMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⁻¹infixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier_⁻¹ : Op₁ CarrierisInvertibleMagma : IsInvertibleMagma _≈_ _∙_ ε _⁻¹open IsInvertibleMagma isInvertibleMagma publicmagma : Magma _ _magma = record { isMagma = isMagma }open Magma magma publicusing (_≉_; rawMagma)record InvertibleUnitalMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⁻¹infixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier_⁻¹ : Op₁ CarrierisInvertibleUnitalMagma : IsInvertibleUnitalMagma _≈_ _∙_ ε _⁻¹open IsInvertibleUnitalMagma isInvertibleUnitalMagma publicinvertibleMagma : InvertibleMagma _ _invertibleMagma = record { isInvertibleMagma = isInvertibleMagma }open InvertibleMagma invertibleMagma publicusing (_≉_; rawMagma; magma)record Group c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⁻¹infixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier_⁻¹ : Op₁ CarrierisGroup : IsGroup _≈_ _∙_ ε _⁻¹open IsGroup isGroup publicrawGroup : RawGroup _ _rawGroup = record { _≈_ = _≈_; _∙_ = _∙_; ε = ε; _⁻¹ = _⁻¹}monoid : Monoid _ _monoid = record { isMonoid = isMonoid }open Monoid monoid publicusing (_≉_; rawMagma; magma; semigroup; unitalMagma; rawMonoid)invertibleMagma : InvertibleMagma c ℓinvertibleMagma = record{ isInvertibleMagma = isInvertibleMagma}invertibleUnitalMagma : InvertibleUnitalMagma c ℓinvertibleUnitalMagma = record{ isInvertibleUnitalMagma = isInvertibleUnitalMagma}record AbelianGroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⁻¹infixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier_⁻¹ : Op₁ CarrierisAbelianGroup : IsAbelianGroup _≈_ _∙_ ε _⁻¹open IsAbelianGroup isAbelianGroup publicgroup : Group _ _group = record { isGroup = isGroup }open Group group public using(_≉_; rawMagma; magma; semigroup; rawMonoid; monoid; rawGroup; invertibleMagma; invertibleUnitalMagma)commutativeMonoid : CommutativeMonoid _ _commutativeMonoid = record { isCommutativeMonoid = isCommutativeMonoid }open CommutativeMonoid commutativeMonoid publicusing (commutativeMagma; commutativeSemigroup)-------------------------------------------------------------------------- Bundles with 2 binary operations & 1 element------------------------------------------------------------------------record NearSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : CarrierisNearSemiring : IsNearSemiring _≈_ _+_ _*_ 0#open IsNearSemiring isNearSemiring publicrawNearSemiring : RawNearSemiring _ _rawNearSemiring = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; 0# = 0#}+-monoid : Monoid _ _+-monoid = record { isMonoid = +-isMonoid }open Monoid +-monoid publicusing (_≉_) renaming( rawMagma to +-rawMagma; magma to +-magma; semigroup to +-semigroup; unitalMagma to +-unitalMagma; rawMonoid to +-rawMonoid)*-semigroup : Semigroup _ _*-semigroup = record { isSemigroup = *-isSemigroup }open Semigroup *-semigroup publicusing () renaming( rawMagma to *-rawMagma; magma to *-magma)record SemiringWithoutOne c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : CarrierisSemiringWithoutOne : IsSemiringWithoutOne _≈_ _+_ _*_ 0#open IsSemiringWithoutOne isSemiringWithoutOne publicnearSemiring : NearSemiring _ _nearSemiring = record { isNearSemiring = isNearSemiring }open NearSemiring nearSemiring publicusing( +-rawMagma; +-magma; +-unitalMagma; +-semigroup; +-rawMonoid; +-monoid; *-rawMagma; *-magma; *-semigroup; rawNearSemiring)+-commutativeMonoid : CommutativeMonoid _ _+-commutativeMonoid = record { isCommutativeMonoid = +-isCommutativeMonoid }open CommutativeMonoid +-commutativeMonoid publicusing () renaming( commutativeMagma to +-commutativeMagma; commutativeSemigroup to +-commutativeSemigroup)record CommutativeSemiringWithoutOne c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : CarrierisCommutativeSemiringWithoutOne :IsCommutativeSemiringWithoutOne _≈_ _+_ _*_ 0#open IsCommutativeSemiringWithoutOneisCommutativeSemiringWithoutOne publicsemiringWithoutOne : SemiringWithoutOne _ _semiringWithoutOne =record { isSemiringWithoutOne = isSemiringWithoutOne }open SemiringWithoutOne semiringWithoutOne publicusing( +-rawMagma; +-magma; +-unitalMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; nearSemiring; rawNearSemiring)-------------------------------------------------------------------------- Bundles with 2 binary operations & 2 elements------------------------------------------------------------------------record SemiringWithoutAnnihilatingZero c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisSemiringWithoutAnnihilatingZero :IsSemiringWithoutAnnihilatingZero _≈_ _+_ _*_ 0# 1#open IsSemiringWithoutAnnihilatingZeroisSemiringWithoutAnnihilatingZero publicrawSemiring : RawSemiring c ℓrawSemiring = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; 0# = 0#; 1# = 1#}open RawSemiring rawSemiring publicusing (rawNearSemiring)+-commutativeMonoid : CommutativeMonoid _ _+-commutativeMonoid =record { isCommutativeMonoid = +-isCommutativeMonoid }open CommutativeMonoid +-commutativeMonoid publicusing (_≉_) renaming( rawMagma to +-rawMagma; magma to +-magma; unitalMagma to +-unitalMagma; commutativeMagma to +-commutativeMagma; semigroup to +-semigroup; commutativeSemigroup to +-commutativeSemigroup; rawMonoid to +-rawMonoid; monoid to +-monoid)*-monoid : Monoid _ _*-monoid = record { isMonoid = *-isMonoid }open Monoid *-monoid publicusing () renaming( rawMagma to *-rawMagma; magma to *-magma; semigroup to *-semigroup; rawMonoid to *-rawMonoid)record Semiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisSemiring : IsSemiring _≈_ _+_ _*_ 0# 1#open IsSemiring isSemiring publicsemiringWithoutAnnihilatingZero : SemiringWithoutAnnihilatingZero _ _semiringWithoutAnnihilatingZero = record{ isSemiringWithoutAnnihilatingZero =isSemiringWithoutAnnihilatingZero}open SemiringWithoutAnnihilatingZerosemiringWithoutAnnihilatingZero publicusing( _≉_; +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; rawNearSemiring ; rawSemiring)semiringWithoutOne : SemiringWithoutOne _ _semiringWithoutOne =record { isSemiringWithoutOne = isSemiringWithoutOne }open SemiringWithoutOne semiringWithoutOne publicusing (nearSemiring)record CommutativeSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisCommutativeSemiring : IsCommutativeSemiring _≈_ _+_ _*_ 0# 1#open IsCommutativeSemiring isCommutativeSemiring publicsemiring : Semiring _ _semiring = record { isSemiring = isSemiring }open Semiring semiring publicusing( _≉_; +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero; rawSemiring)*-commutativeMonoid : CommutativeMonoid _ _*-commutativeMonoid = record{ isCommutativeMonoid = *-isCommutativeMonoid}open CommutativeMonoid *-commutativeMonoid publicusing () renaming( commutativeMagma to *-commutativeMagma; commutativeSemigroup to *-commutativeSemigroup)commutativeSemiringWithoutOne : CommutativeSemiringWithoutOne _ _commutativeSemiringWithoutOne = record{ isCommutativeSemiringWithoutOne = isCommutativeSemiringWithoutOne}record CancellativeCommutativeSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisCancellativeCommutativeSemiring : IsCancellativeCommutativeSemiring _≈_ _+_ _*_ 0# 1#open IsCancellativeCommutativeSemiring isCancellativeCommutativeSemiring publiccommutativeSemiring : CommutativeSemiring c ℓcommutativeSemiring = record{ isCommutativeSemiring = isCommutativeSemiring}open CommutativeSemiring commutativeSemiring publicusing( +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-commutativeMagma; *-semigroup; *-commutativeSemigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; *-commutativeMonoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero; rawSemiring; semiring; _≉_)record IdempotentSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisIdempotentSemiring : IsIdempotentSemiring _≈_ _+_ _*_ 0# 1#open IsIdempotentSemiring isIdempotentSemiring publicsemiring : Semiring _ _semiring = record { isSemiring = isSemiring }open Semiring semiring publicusing( _≉_; +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero; rawSemiring)+-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _+-idempotentCommutativeMonoid = record { isIdempotentCommutativeMonoid = +-isIdempotentCommutativeMonoid }open IdempotentCommutativeMonoid +-idempotentCommutativeMonoid publicusing ()renaming ( band to +-band; commutativeBand to +-commutativeBand; idempotentMonoid to +-idempotentMonoid)record KleeneAlgebra c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⋆infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier_⋆ : Op₁ Carrier0# : Carrier1# : CarrierisKleeneAlgebra : IsKleeneAlgebra _≈_ _+_ _*_ _⋆ 0# 1#open IsKleeneAlgebra isKleeneAlgebra publicidempotentSemiring : IdempotentSemiring _ _idempotentSemiring = record { isIdempotentSemiring = isIdempotentSemiring }open IdempotentSemiring idempotentSemiring publicusing( _≉_; +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero; rawSemiring; semiring)record Quasiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierisQuasiring : IsQuasiring _≈_ _+_ _*_ 0# 1#open IsQuasiring isQuasiring public+-monoid : Monoid _ _+-monoid = record { isMonoid = +-isMonoid }open Monoid +-monoid publicusing (_≉_) renaming( rawMagma to +-rawMagma; magma to +-magma; semigroup to +-semigroup; unitalMagma to +-unitalMagma; rawMonoid to +-rawMonoid)*-monoid : Monoid _ _*-monoid = record { isMonoid = *-isMonoid }open Monoid *-monoid publicusing () renaming( rawMagma to *-rawMagma; magma to *-magma; semigroup to *-semigroup; rawMonoid to *-rawMonoid)-------------------------------------------------------------------------- Bundles with 2 binary operations, 1 unary operation & 1 element------------------------------------------------------------------------record RingWithoutOne c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : CarrierisRingWithoutOne : IsRingWithoutOne _≈_ _+_ _*_ -_ 0#open IsRingWithoutOne isRingWithoutOne public+-abelianGroup : AbelianGroup _ _+-abelianGroup = record { isAbelianGroup = +-isAbelianGroup }*-semigroup : Semigroup _ _*-semigroup = record { isSemigroup = *-isSemigroup }open AbelianGroup +-abelianGroup publicusing () renaming (group to +-group; invertibleMagma to +-invertibleMagma; invertibleUnitalMagma to +-invertibleUnitalMagma)open Semigroup *-semigroup publicusing () renaming( rawMagma to *-rawMagma; magma to *-magma)-------------------------------------------------------------------------- Bundles with 2 binary operations, 1 unary operation & 2 elements------------------------------------------------------------------------record NonAssociativeRing c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisNonAssociativeRing : IsNonAssociativeRing _≈_ _+_ _*_ -_ 0# 1#open IsNonAssociativeRing isNonAssociativeRing public+-abelianGroup : AbelianGroup _ _+-abelianGroup = record { isAbelianGroup = +-isAbelianGroup }open AbelianGroup +-abelianGroup publicusing () renaming (group to +-group; invertibleMagma to +-invertibleMagma; invertibleUnitalMagma to +-invertibleUnitalMagma)*-unitalMagma : UnitalMagma _ _*-unitalMagma = record { isUnitalMagma = *-isUnitalMagma}open UnitalMagma *-unitalMagma publicusing () renaming (magma to *-magma; identity to *-identity)record Nearring c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisNearring : IsNearring _≈_ _+_ _*_ 0# 1# -_open IsNearring isNearring publicquasiring : Quasiring _ _quasiring = record { isQuasiring = isQuasiring }open Quasiring quasiring publicusing(_≉_; +-rawMagma; +-magma; +-unitalMagma; +-semigroup; +-monoid; +-rawMonoid;*-rawMagma; *-magma; *-semigroup; *-monoid)record Ring c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisRing : IsRing _≈_ _+_ _*_ -_ 0# 1#open IsRing isRing public+-abelianGroup : AbelianGroup _ _+-abelianGroup = record { isAbelianGroup = +-isAbelianGroup }ringWithoutOne : RingWithoutOne _ _ringWithoutOne = record { isRingWithoutOne = isRingWithoutOne }semiring : Semiring _ _semiring = record { isSemiring = isSemiring }open Semiring semiring publicusing( _≉_; +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-semigroup; +-rawMonoid; +-monoid ; +-commutativeMonoid; *-rawMonoid; *-monoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero)open NearSemiring nearSemiring publicusing (rawNearSemiring)open AbelianGroup +-abelianGroup publicusing () renaming (group to +-group; invertibleMagma to +-invertibleMagma; invertibleUnitalMagma to +-invertibleUnitalMagma)rawRing : RawRing _ _rawRing = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0#; 1# = 1#}open RawRing rawRing publicusing (rawRingWithoutOne; +-rawGroup)record CommutativeRing c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisCommutativeRing : IsCommutativeRing _≈_ _+_ _*_ -_ 0# 1#open IsCommutativeRing isCommutativeRing publicring : Ring _ _ring = record { isRing = isRing }open Ring ring public using (_≉_; rawRing; +-invertibleMagma; +-invertibleUnitalMagma; +-group; +-abelianGroup)commutativeSemiring : CommutativeSemiring _ _commutativeSemiring =record { isCommutativeSemiring = isCommutativeSemiring }open CommutativeSemiring commutativeSemiring publicusing( +-rawMagma; +-magma; +-unitalMagma; +-commutativeMagma; +-semigroup; +-commutativeSemigroup; *-rawMagma; *-magma; *-commutativeMagma; *-semigroup; *-commutativeSemigroup; +-rawMonoid; +-monoid; +-commutativeMonoid; *-rawMonoid; *-monoid; *-commutativeMonoid; nearSemiring; semiringWithoutOne; semiringWithoutAnnihilatingZero; semiring; commutativeSemiringWithoutOne)-------------------------------------------------------------------------- Bundles with 3 binary operations------------------------------------------------------------------------record Quasigroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ CarrierisQuasigroup : IsQuasigroup _≈_ _∙_ _\\_ _//_open IsQuasigroup isQuasigroup publicmagma : Magma c ℓmagma = record { isMagma = isMagma }open Magma magma publicusing (_≉_; rawMagma)rawQuasigroup : RawQuasigroup c ℓrawQuasigroup = record{ _≈_ = _≈_; _∙_ = _∙_; _\\_ = _\\_; _//_ = _//_}open RawQuasigroup rawQuasigroup publicusing (//-rawMagma; \\-rawMagma; ∙-rawMagma)record Loop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierisLoop : IsLoop _≈_ _∙_ _\\_ _//_ εopen IsLoop isLoop publicrawLoop : RawLoop c ℓrawLoop = record{ _≈_ = _≈_; _∙_ = _∙_; _\\_ = _\\_; _//_ = _//_; ε = ε}quasigroup : Quasigroup _ _quasigroup = record { isQuasigroup = isQuasigroup }open Quasigroup quasigroup publicusing (_≉_; ∙-rawMagma; \\-rawMagma; //-rawMagma)record LeftBolLoop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierisLeftBolLoop : IsLeftBolLoop _≈_ _∙_ _\\_ _//_ εopen IsLeftBolLoop isLeftBolLoop publicloop : Loop _ _loop = record { isLoop = isLoop }open Loop loop publicusing (quasigroup)record RightBolLoop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierisRightBolLoop : IsRightBolLoop _≈_ _∙_ _\\_ _//_ εopen IsRightBolLoop isRightBolLoop publicloop : Loop _ _loop = record { isLoop = isLoop }open Loop loop publicusing (quasigroup)record MoufangLoop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierisMoufangLoop : IsMoufangLoop _≈_ _∙_ _\\_ _//_ εopen IsMoufangLoop isMoufangLoop publicleftBolLoop : LeftBolLoop _ _leftBolLoop = record { isLeftBolLoop = isLeftBolLoop }open LeftBolLoop leftBolLoop publicusing (loop)record MiddleBolLoop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierisMiddleBolLoop : IsMiddleBolLoop _≈_ _∙_ _\\_ _//_ εopen IsMiddleBolLoop isMiddleBolLoop publicloop : Loop _ _loop = record { isLoop = isLoop }open Loop loop publicusing (quasigroup)
-------------------------------------------------------------------------- The Agda standard library---- Definitions of 'raw' bundles------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Bundles.Raw whereopen import Algebra.Coreopen import Relation.Binary.Core using (Rel)open import Level using (suc; _⊔_)open import Relation.Nullary.Negation.Core using (¬_)-------------------------------------------------------------------------- Raw bundles with 1 unary operation & 1 element-------------------------------------------------------------------------- A raw SuccessorSet is a SuccessorSet without any laws.record RawSuccessorSet c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓsuc# : Op₁ Carrierzero# : Carrier-------------------------------------------------------------------------- Raw bundles with 1 binary operation------------------------------------------------------------------------record RawMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierinfix 4 _≉__≉_ : Rel Carrier _x ≉ y = ¬ (x ≈ y)-------------------------------------------------------------------------- Raw bundles with 1 binary operation & 1 element-------------------------------------------------------------------------- A raw monoid is a monoid without any laws.record RawMonoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : CarrierrawMagma : RawMagma c ℓrawMagma = record{ _≈_ = _≈_; _∙_ = _∙_}open RawMagma rawMagma publicusing (_≉_)-------------------------------------------------------------------------- Raw bundles with 1 binary operation, 1 unary operation & 1 element------------------------------------------------------------------------record RawGroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⁻¹infixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier_⁻¹ : Op₁ CarrierrawMonoid : RawMonoid c ℓrawMonoid = record{ _≈_ = _≈_; _∙_ = _∙_; ε = ε}open RawMonoid rawMonoid publicusing (_≉_; rawMagma)-------------------------------------------------------------------------- Raw bundles with 2 binary operations & 1 element------------------------------------------------------------------------record RawNearSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier+-rawMonoid : RawMonoid c ℓ+-rawMonoid = record{ _≈_ = _≈_; _∙_ = _+_; ε = 0#}open RawMonoid +-rawMonoid publicusing (_≉_) renaming (rawMagma to +-rawMagma)*-rawMagma : RawMagma c ℓ*-rawMagma = record{ _≈_ = _≈_; _∙_ = _*_}-------------------------------------------------------------------------- Raw bundles with 2 binary operations & 2 elements------------------------------------------------------------------------record RawSemiring c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier0# : Carrier1# : CarrierrawNearSemiring : RawNearSemiring c ℓrawNearSemiring = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; 0# = 0#}open RawNearSemiring rawNearSemiring publicusing (_≉_; +-rawMonoid; +-rawMagma; *-rawMagma)*-rawMonoid : RawMonoid c ℓ*-rawMonoid = record{ _≈_ = _≈_; _∙_ = _*_; ε = 1#}-------------------------------------------------------------------------- Raw bundles with 2 binary operations, 1 unary operation & 1 element------------------------------------------------------------------------record RawRingWithoutOne c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier+-rawGroup : RawGroup c ℓ+-rawGroup = record{ _≈_ = _≈_; _∙_ = _+_; ε = 0#; _⁻¹ = -_}open RawGroup +-rawGroup publicusing (_≉_) renaming (rawMagma to +-rawMagma; rawMonoid to +-rawMonoid)*-rawMagma : RawMagma c ℓ*-rawMagma = record{ _≈_ = _≈_; _∙_ = _*_}-------------------------------------------------------------------------- Raw bundles with 2 binary operations, 1 unary operation & 2 elements-------------------------------------------------------------------------- A raw ring is a ring without any laws.record RawRing c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierrawSemiring : RawSemiring c ℓrawSemiring = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; 0# = 0#; 1# = 1#}open RawSemiring rawSemiring publicusing( _≉_; +-rawMagma; +-rawMonoid; *-rawMagma; *-rawMonoid)rawRingWithoutOne : RawRingWithoutOne c ℓrawRingWithoutOne = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; -_ = -_; 0# = 0#}open RawRingWithoutOne rawRingWithoutOne publicusing (+-rawGroup)-------------------------------------------------------------------------- Raw bundles with 3 binary operations------------------------------------------------------------------------record RawQuasigroup c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrier∙-rawMagma : RawMagma c ℓ∙-rawMagma = record{ _≈_ = _≈_; _∙_ = _∙_}\\-rawMagma : RawMagma c ℓ\\-rawMagma = record{ _≈_ = _≈_; _∙_ = _\\_}//-rawMagma : RawMagma c ℓ//-rawMagma = record{ _≈_ = _≈_; _∙_ = _//_}open RawMagma \\-rawMagma publicusing (_≉_)-------------------------------------------------------------------------- Raw bundles with 3 binary operations & 1 element------------------------------------------------------------------------record RawLoop c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infixl 7 _\\_infixl 7 _//_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrier_\\_ : Op₂ Carrier_//_ : Op₂ Carrierε : CarrierrawQuasigroup : RawQuasigroup c ℓrawQuasigroup = record{ _≈_ = _≈_; _∙_ = _∙_; _\\_ = _\\_; _//_ = _//_}open RawQuasigroup rawQuasigroup publicusing (_≉_ ; ∙-rawMagma; \\-rawMagma; //-rawMagma)record RawKleeneAlgebra c ℓ : Set (suc (c ⊔ ℓ)) whereinfix 8 _⋆infixl 7 _*_infixl 6 _+_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_+_ : Op₂ Carrier_*_ : Op₂ Carrier_⋆ : Op₁ Carrier0# : Carrier1# : CarrierrawSemiring : RawSemiring c ℓrawSemiring = record{ _≈_ = _≈_; _+_ = _+_; _*_ = _*_; 0# = 0#; 1# = 1#}open RawSemiring rawSemiring publicusing( _≉_; +-rawMagma; +-rawMonoid; *-rawMagma; *-rawMonoid)
-------------------------------------------------------------------------- The Agda standard library---- Algebraic objects with an apartness relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Apartness whereopen import Algebra.Apartness.Structures publicopen import Algebra.Apartness.Bundles public
-------------------------------------------------------------------------- The Agda standard library---- Algebraic structures with an apartness relation------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Core using (Op₁; Op₂)open import Relation.Binary.Core using (Rel)module Algebra.Apartness.Structures{c ℓ₁ ℓ₂} {Carrier : Set c}(_≈_ : Rel Carrier ℓ₁)(_#_ : Rel Carrier ℓ₂)(_+_ _*_ : Op₂ Carrier) (-_ : Op₁ Carrier) (0# 1# : Carrier)whereopen import Level using (_⊔_; suc)open import Data.Product.Base using (∃-syntax; _×_; _,_; proj₂)open import Algebra.Definitions _≈_ using (Invertible)open import Algebra.Structures _≈_ using (IsCommutativeRing)open import Relation.Binary.Structures using (IsEquivalence; IsApartnessRelation)open import Relation.Binary.Definitions using (Tight)open import Relation.Nullary.Negation using (¬_)import Relation.Binary.Properties.ApartnessRelation as ARrecord IsHeytingCommutativeRing : Set (c ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisCommutativeRing : IsCommutativeRing _+_ _*_ -_ 0# 1#isApartnessRelation : IsApartnessRelation _≈_ _#_open IsCommutativeRing isCommutativeRing publicopen IsApartnessRelation isApartnessRelation publicfield#⇒invertible : ∀ {x y} → x # y → Invertible 1# _*_ (x - y)invertible⇒# : ∀ {x y} → Invertible 1# _*_ (x - y) → x # y¬#-isEquivalence : IsEquivalence _¬#_¬#-isEquivalence = AR.¬#-isEquivalence refl isApartnessRelationrecord IsHeytingField : Set (c ⊔ ℓ₁ ⊔ ℓ₂) wherefieldisHeytingCommutativeRing : IsHeytingCommutativeRingtight : Tight _≈_ _#_open IsHeytingCommutativeRing isHeytingCommutativeRing public
-------------------------------------------------------------------------- The Agda standard library---- Properties of Heyting Commutative Rings------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}open import Algebra.Apartness.Bundles using (HeytingCommutativeRing)module Algebra.Apartness.Properties.HeytingCommutativeRing{c ℓ₁ ℓ₂} (HCR : HeytingCommutativeRing c ℓ₁ ℓ₂) whereopen import Function.Base using (_∘_)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Algebra using (CommutativeRing; RightIdentity; Invertible; LeftInvertible; RightInvertible)open HeytingCommutativeRing HCRopen CommutativeRing commutativeRing using (ring; *-commutativeMonoid)open import Algebra.Properties.Ring ringusing (-0#≈0#; -‿distribˡ-*; -‿distribʳ-*; -‿anti-homo-+; -‿involutive)open import Relation.Binary.Definitions using (Symmetric)import Relation.Binary.Reasoning.Setoid as ≈-Reasoningopen import Algebra.Properties.CommutativeMonoid *-commutativeMonoidprivate variablex y z : Carrierinvertibleˡ⇒# : LeftInvertible _≈_ 1# _*_ (x - y) → x # yinvertibleˡ⇒# = invertible⇒# ∘ invertibleˡ⇒invertibleinvertibleʳ⇒# : RightInvertible _≈_ 1# _*_ (x - y) → x # yinvertibleʳ⇒# = invertible⇒# ∘ invertibleʳ⇒invertiblex-0≈x : RightIdentity _≈_ 0# _-_x-0≈x x = trans (+-congˡ -0#≈0#) (+-identityʳ x)1#0 : 1# # 0#1#0 = invertibleˡ⇒# (1# , 1*[x-0]≈x)where1*[x-0]≈x : 1# * (x - 0#) ≈ x1*[x-0]≈x {x} = trans (*-identityˡ (x - 0#)) (x-0≈x x)x#0y#0→xy#0 : x # 0# → y # 0# → x * y # 0#x#0y#0→xy#0 {x} {y} x#0 y#0 = helper (#⇒invertible x#0) (#⇒invertible y#0)wherehelper : Invertible _≈_ 1# _*_ (x - 0#) → Invertible _≈_ 1# _*_ (y - 0#) → x * y # 0#helper (x⁻¹ , x⁻¹*x≈1 , x*x⁻¹≈1) (y⁻¹ , y⁻¹*y≈1 , y*y⁻¹≈1)= invertibleˡ⇒# (y⁻¹ * x⁻¹ , y⁻¹*x⁻¹*x*y≈1)whereopen ≈-Reasoning setoidy⁻¹*x⁻¹*x*y≈1 : y⁻¹ * x⁻¹ * (x * y - 0#) ≈ 1#y⁻¹*x⁻¹*x*y≈1 = beginy⁻¹ * x⁻¹ * (x * y - 0#) ≈⟨ *-congˡ (x-0≈x (x * y)) ⟩y⁻¹ * x⁻¹ * (x * y) ≈⟨ *-assoc y⁻¹ x⁻¹ (x * y) ⟩y⁻¹ * (x⁻¹ * (x * y)) ≈⟨ *-congˡ (*-assoc x⁻¹ x y) ⟨y⁻¹ * ((x⁻¹ * x) * y) ≈⟨ *-congˡ (*-congʳ (*-congˡ (x-0≈x x))) ⟨y⁻¹ * ((x⁻¹ * (x - 0#)) * y) ≈⟨ *-congˡ (*-congʳ x⁻¹*x≈1) ⟩y⁻¹ * (1# * y) ≈⟨ *-congˡ (*-identityˡ y) ⟩y⁻¹ * y ≈⟨ *-congˡ (x-0≈x y) ⟨y⁻¹ * (y - 0#) ≈⟨ y⁻¹*y≈1 ⟩1# ∎#-sym : Symmetric _#_#-sym {x} {y} x#y = invertibleˡ⇒# (- x-y⁻¹ , x-y⁻¹*y-x≈1)whereopen ≈-Reasoning setoidInvX-Y : Invertible _≈_ 1# _*_ (x - y)InvX-Y = #⇒invertible x#yx-y⁻¹ = InvX-Y .proj₁y-x≈-[x-y] : y - x ≈ - (x - y)y-x≈-[x-y] = beginy - x ≈⟨ +-congʳ (-‿involutive y) ⟨- - y - x ≈⟨ -‿anti-homo-+ x (- y) ⟨- (x - y) ∎x-y⁻¹*y-x≈1 : (- x-y⁻¹) * (y - x) ≈ 1#x-y⁻¹*y-x≈1 = begin(- x-y⁻¹) * (y - x) ≈⟨ -‿distribˡ-* x-y⁻¹ (y - x) ⟨- (x-y⁻¹ * (y - x)) ≈⟨ -‿cong (*-congˡ y-x≈-[x-y]) ⟩- (x-y⁻¹ * - (x - y)) ≈⟨ -‿cong (-‿distribʳ-* x-y⁻¹ (x - y)) ⟨- - (x-y⁻¹ * (x - y)) ≈⟨ -‿involutive (x-y⁻¹ * ((x - y))) ⟩x-y⁻¹ * (x - y) ≈⟨ InvX-Y .proj₂ .proj₁ ⟩1# ∎#-congʳ : x ≈ y → x # z → y # z#-congʳ {x} {y} {z} x≈y x#z = helper (#⇒invertible x#z)wherehelper : Invertible _≈_ 1# _*_ (x - z) → y # zhelper (x-z⁻¹ , x-z⁻¹*x-z≈1# , x-z*x-z⁻¹≈1#)= invertibleˡ⇒# (x-z⁻¹ , x-z⁻¹*y-z≈1)whereopen ≈-Reasoning setoidx-z⁻¹*y-z≈1 : x-z⁻¹ * (y - z) ≈ 1#x-z⁻¹*y-z≈1 = beginx-z⁻¹ * (y - z) ≈⟨ *-congˡ (+-congʳ x≈y) ⟨x-z⁻¹ * (x - z) ≈⟨ x-z⁻¹*x-z≈1# ⟩1# ∎#-congˡ : y ≈ z → x # y → x # z#-congˡ y≈z x#y = #-sym (#-congʳ y≈z (#-sym x#y))
-------------------------------------------------------------------------- The Agda standard library---- Bundles for local algebraic structures------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module Algebra.Apartness.Bundles whereopen import Level using (_⊔_; suc)open import Relation.Binary.Core using (Rel)open import Relation.Binary.Bundles using (ApartnessRelation)open import Algebra.Core using (Op₁; Op₂)open import Algebra.Bundles using (CommutativeRing)open import Algebra.Apartness.Structuresrecord HeytingCommutativeRing c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_ _#_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_#_ : Rel Carrier ℓ₂_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisHeytingCommutativeRing : IsHeytingCommutativeRing _≈_ _#_ _+_ _*_ -_ 0# 1#open IsHeytingCommutativeRing isHeytingCommutativeRing publiccommutativeRing : CommutativeRing c ℓ₁commutativeRing = record { isCommutativeRing = isCommutativeRing }apartnessRelation : ApartnessRelation c ℓ₁ ℓ₂apartnessRelation = record { isApartnessRelation = isApartnessRelation }record HeytingField c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whereinfix 8 -_infixl 7 _*_infixl 6 _+_infix 4 _≈_ _#_fieldCarrier : Set c_≈_ : Rel Carrier ℓ₁_#_ : Rel Carrier ℓ₂_+_ : Op₂ Carrier_*_ : Op₂ Carrier-_ : Op₁ Carrier0# : Carrier1# : CarrierisHeytingField : IsHeytingField _≈_ _#_ _+_ _*_ -_ 0# 1#open IsHeytingField isHeytingField publicheytingCommutativeRing : HeytingCommutativeRing c ℓ₁ ℓ₂heytingCommutativeRing = record { isHeytingCommutativeRing = isHeytingCommutativeRing }apartnessRelation : ApartnessRelation c ℓ₁ ℓ₂apartnessRelation = record { isApartnessRelation = isApartnessRelation }
#!/bin/bashcd /tmpgit clone git@github.com:agda/agda-stdlib.gitcd agda-stdlibgit checkout gh-pagesgit merge master -m "[auto] merge master into gh-pages"make listingsif [ "`git status --porcelain`" != "" ]; thenecho "Updates:"git status --porcelainchanged=`git status --porcelain | cut -c4-`git add --all -- $changedgit commit -m "[auto] updated html listings"git pushelseecho "No changes!"ficd ..rm -rf agda-stdlib
#!/bin/sh### You can call this script like so to generate a dependency graph### of the `Data.List.Base` module:### ./graph.sh src/Data/List/Base.agda### Allow users to pick the agda executable they want by prefixing### the call with `AGDA=agda-X.Y.Z` and default to agda in case### nothing was pickedAGDA=${AGDA:-"agda"}### Grab the directory and name of the target agda fileDIR=$(dirname $1)BASE=$(basename $1 ".agda")FILE=_build/${DIR}/${BASE}### Prepare the directory for the dot & tmp filesmkdir -p _build/$DIR### Generate the dot file for the target agda file${AGDA} -i. -isrc/ --dependency-graph=${FILE}.dot $1### Trim the graph to remove transitive dependencies. Without that the### graphs get too big too quickly and are impossible to rendertred ${FILE}.dot > ${FILE}2.dotmv ${FILE}2.dot ${FILE}.dot### Generate an svg representation of the graphdot -Tsvg ${FILE}.dot > ${FILE}.svg### Add a symlink to it in the base directoryln -is ${FILE}.svg ${BASE}.svg
included-dirs:- src- READMEincluded-files:- "*.agda"- "*.md"excluded-files:- "README/Text/Tabular.agda"
The `experimental` branch contains changes that are required foryet unreleased versions of Agda. These are kept separate from`master` so that the standard library releases can occur independentlyfrom Agda releases.To update `experimental` to the current version of `master` run thefollowing:```git checkout mastergit pullgit checkout experimentalgit merge mastergit push```
Style guide for the standard library====================================This is very much a work-in-progress and is not exhaustive. Furthermore, many ofthese are aspirations, and may be violated in certain parts of the library.It is hoped that at some point a linter will be developed for Agda which willautomate most of this.## File structure* The standard library uses a standard line length of 72 characters. Pleasetry to stay within this limit. Having said that this is the most violatedrule in the style-guide and it is recognised that it is not always possibleto achieve whilst using meaningful names.#### Indentation* The contents of a top-level module should have zero indentation.* Every subsequent nested scope should then be indented by an additionaltwo spaces.* `where` blocks should be indented by two spaces and their contentsshould be aligned with the `where`.* If the type of a term does not fit on one line then the subsequentlines of the type should all be aligned with the first characterof the first line of type, e.g.```agdamap-cong₂ : ∀ {a b} {A : Set a} {B : Set b} →∀ {f g : A → B} {xs} →All (λ x → f x ≡ g x) xs → map f xs ≡ map g xs```* As can be seen in the example above, function arrows at line breaksshould always go at the end of the line rather than the beginning of thenext line.#### Empty lines* All module headers and standard term definitions should have a singleempty line after them.* There should be _two_ empty lines between adjacent record or module definitionsin order to better distinguish the end of the record or module, as they willalready be using single empty lines between internal definitions.* For example:```agdamodule Test1 wheredef1 : ...def1 = ...def2 : ...def2 = ...module Test2 whererecord Record1 : Set wherefieldfield1 : ...aux1 : ...aux1 = ...aux2 : ...aux2 = ...record Record2 : Set wherefieldfield2 : ...record1 : Record1record1 = { field1 = ... }record2 : Record2record2 = { field2 = ... }```#### Modules* As a rule of thumb, there should only be one named module per file. Anonymousmodules are fine, but named internal modules should either be opened publiclyimmediately or split out into a separate file.* Module parameters should be put on a single line if they fit.* Otherwise, they should be spread out over multiple lines, each indented by twospaces. If they can be grouped logically by line, then it is fine to do so.Otherwise, a line each is probably clearest. The `where` keyword should be placedon an additional line of code at the end. For example:```agdamodule Relation.Binary.Reasoning.Base.Single{a ℓ} {A : Set a} (_∼_ : Rel A ℓ)(refl : Reflexive _∼_) (trans : Transitive _∼_)where```* There should always be a single blank line after a module declaration.#### Imports* All imports should be placed in a list at the top of the fileimmediately after the module declaration.* The list of imports should be declared in alphabetical order.* If the module takes parameters that require imports from other files,then those imports only may be placed above the module declaration, e.g.```agdaopen import Algebra using (Ring)module Algebra.Properties.Ring {a l} (ring : Ring a l) where... other imports```* If it is important that certain names only come into scope later inthe file then the module should still be imported at the top of thefile but it can be imported *qualified*, i.e. given a shorter nameusing the keyword `as` and then opened later on in the file when needed,e.g.```agdaimport Data.List.Relation.Binary.Equality.Setoid as SetoidEquality......open SetoidEquality S```* If importing a parametrised module, qualified or otherwise, with itsparameters instantiated, then such 'instantiated imports' should be placed*after* the main block of `import`s, and *before* any `variable` declarations.* Naming conventions for qualified `import`s: if importing a module undera root of the form `Data.X` (e.g. the `Base` module for basic operations,or `Properties` for lemmas about them etc.) then conventionally, thequalified name(s) for the import(s) should (all) share as qualified namethat of the name of the `X` datatype defined: i.e. `Data.Nat.Base`should be imported as `ℕ`, `Data.List.Properties` as `List`, etc.In this spirit, the convention applies also to (the datatype defined by)`Relation.Binary.PropositionalEquality.*` which should be imported qualifiedwith the name `≡`.Other modules should be given a 'suitable' qualified name based on its 'long'path-derived name (such as `SetoidEquality` in the example above); commonlyoccurring examples such as `Algebra.Structures` should be imported qualifiedas `Structures` etc.NB. Historical legacy means that these conventions have not always been observed!* Special case of the above for `*-Reasoning` (sub-)modules: by analogy with`Relation.Binary.PropositionalEquality.≡-Reasoning`, when importing qualifiedthe `-Reasoning` (sub-)module associated with a given (canonical) choice ofsymbol (eg. `≲` for `Preorder` reasoning), use the qualified name`<symbol>-Reasoning`, ie. `≲-Reasoning` for the example given.* Qualified `open import`s should, in general, avoid `renaming`identifiers, in favour of using the long(er) qualified name,although similar remarks about legacy failure to observe thisrecommendation apply!NB. `renaming` directives are, of course, permitted when a module isimported qualified, in order to be *subsequently* `open`ed for`public` export (see below).* When using only a few items (i.e. < 5) from a module, it is a good practice toenumerate the items that will be used by declaring the import statementwith the directive `using`. This makes the dependencies clearer, e.g.```agdaopen import Data.Nat.Properties using (+-assoc)```* Re-exporting terms from a module using the `public` modifiershould *not* be done in the list of imports as it is very hard to spot.Instead, the best approach is often to rename the import and then open itpublicly later in the file in a more obvious fashion, e.g.```agda-- Import list...import Data.Nat.Properties as NatProperties...-- Re-export ringopen NatProperties publicusing (+-*-ring)```* If multiple import modifiers are used, then they should occur in thefollowing order: `public`, `using` `renaming`, and if `public` is usedthen the `using` and `renaming` modifiers should occur on a separate line.For example:```agdaopen Monoid monoid publicusing (ε) renaming (_∙_ to _+_)```#### Layout of data declarations* The `:` for each constructor should be aligned.#### Layout of record declarations* The `:` for each field should be aligned.* If defining multiple records back-to-back then there should be a doubleempty line between each record.#### Layout of record instances* The `record` keyword should go on the same line as the rest of the proof.* The next line with the first record item should start with a single `{`.* Every subsequent item of the record should go on its own line starting witha `;`.* The final line should end with `}` on its own.* The `=` signs for each field should be aligned.* For example:```agda≤-isPreorder : IsPreorder _≡_ _≤_≤-isPreorder = record{ isEquivalence = isEquivalence; reflexive = ≤-reflexive; trans = ≤-trans}```#### Layout of initial `private` block* Since the introduction of generalizable `variable`s (see below),this block provides a very useful way to 'fix'/standardise notationfor the rest of the module, as well as introducing localinstantiations of parameterised `module` definitions, again for thesake of fixing notation via qualified names.* It should typically follow the `import` and `open` declarations, asabove, separated by one blankline, and be followed by *two* blanklines ahead of the main module body.* The current preferred layout is to use successive indentation by two spaces, eg.```agdaprivatevariablea : LevelA : Set a```rather than to use the more permissive 'stacked' style, availablesince [agda/agda#5319](https://github.com/agda/agda/pull/5319).* A possible exception to the above rule is when a *single* declarationis made, such as eg.```agdaprivate open module M = ...```#### Layout of `where` blocks* `where` blocks are preferred rather than the `let` construction.* The `where` keyword should be placed on the line below the main proof,indented by two spaces.* If the content of the block is non-trivial then types should beprovided alongside the terms, and all terms should be on lines afterthe `where`, e.g.```agdastatement : Statementstatement = proofwhereproof : Proofproof = some-very-long-proof```* If the content of the block is trivial or is an `open` statement thenit can be provided on the same line as the `where` and a type can beomitted, e.g.```agdastatement : Statementstatement = proofwhere proof = x```#### Layout of equational reasoning* The `begin` clause should go on the same line as the rest of the proof.* Every subsequent combinator `_≡⟨_⟩_` should be placed on an additionalline of code, indented by two spaces.* The relation sign (e.g. `≡`) for each line should be aligned if possible.* For example:```agda+-comm : Commutative _+_+-comm zero n = sym (+-identityʳ n)+-comm (suc m) n = beginsuc m + n ≡⟨⟩suc (m + n) ≡⟨ cong suc (+-comm m n) ⟩suc (n + m) ≡⟨ sym (+-suc n m) ⟩n + suc m ∎```* When multiple reasoning frameworks need to be used in the same file, the`open` statement should always come in a where clause local to thedefinition. This way users can easily see which reasoning toolkit isbeing used. For instance:```agdafoo m n p = begin(...) ∎where open ≤-Reasoning```#### Mutual and private blocks* Non-trivial proofs in `private` blocks are generally discouraged. If it isnon-trivial, then chances are that someone will want to reuse it at somepoint!* Instead, private blocks should only be used to prevent temporary terms andrecords that are defined for convenience from being exported by the module.* The mutual block is considered obsolete. Please use the standard approachof placing the type signatures of the mutually recursive functions beforetheir definitions.#### Function arguments* Function arguments should be aligned between cases where possible, e.g.```agda+-comm : Commutative _+_+-comm zero n = ...+-comm (suc m) n = ...```* If an argument is unused in a case, it may at the author'sdiscretion be replaced by an underscore, e.g.```agda+-assoc : Associative _+_+-assoc zero _ _ = refl+-assoc (suc m) n o = cong suc (+-assoc m n o)```* If it is necessary to refer to an implicit argument in one case thenthe implicit argument brackets must be included in every other case aswell, e.g.```agdam≤n⇒m∸n≡0 : ∀ {m n} → m ≤ n → m ∸ n ≡ 0m≤n⇒m∸n≡0 {n = n} z≤n = 0∸n≡0 nm≤n⇒m∸n≡0 {n = _} (s≤s m≤n) = m≤n⇒m∸n≡0 m≤n```* As of Agda 2.6.0 dot patterns are no longer necessary when unifyingfunction arguments and therefore should not be prepended to functionarguments.#### Comments* Comments should be placed above a term rather than on the same line, e.g.```agda-- Multiplication of two elements_*_ : A → A → A_*_ = ...```rather than:```agda_*_ : A → A → A -- Multiplication of two elements_*_ = ...```* Files can be separated into different logical parts using comments ofthe following style, where the header is 72 characters wide:```agda-------------------------------------------------------------------------- <Title>```Use sentence case in the title: `Rounding functions`, not `Rounding Functions` or `ROUNDING FUNCTIONS`.#### Other* The `with` syntax is preferred over the use of `case` from the `Function`module. The `|` should not be aligned with the `with` statement, i.e.```agdafilter p (x ∷ xs) with p x... | true = x ∷ filter p xs... | false = filter p xs```instead of```agdafilter p (x ∷ xs) with p x... | true = x ∷ filter p xs... | false = filter p xs```* Instance arguments, and their types, should use the vanilla ASCII/UTF-8 `{{_}}`syntax in preference to the Unicode `⦃_⦄` syntax (written using `\{{`/`\}}`),which moreover requires additional whitespace to parse correctly.NB. Even for irrelevant instances, such as typically for `NonZero` arguments,neverthelesss it is necessary to supply an underscore binding `{{_ : NonZero n}}`if subsequent terms occurring in the type rely on that argument to be well-formed:eg in `Data.Nat.DivMod`, in the use of `_/ n` and `_% n````agdam≡m%n+[m/n]*n : ∀ m n .{{_ : NonZero n}} → m ≡ m % n + (m / n) * n```## Types#### Implicit and explicit arguments* Function arguments should be implicit if they can "almost always"be inferred. If there are common cases where they cannot be inferredthen they should be left explicit.* If there are lots of implicit arguments that are common to a collectionof proofs they should be extracted by using an anonymous module.#### Variables* `Level` and `Set`s can always be generalised using the keyword `variable`.* A file may only declare variables of other types if those types are usedin the definition of the main type that the file concerns itself with.At the moment the policy is *not* to generalise over any other types tominimise the amount of information that users have to keep in their headconcurrently.* Example 1: the main type in `Data.List.Properties` is `List A` where `A : Set a`.Therefore it may declare variables over `Level`, `Set a`, `A`, `List A`. It maynot declare variables, for example, over predicates (e.g. `P : Pred A p`) aspredicates are not used in the definition of `List`, even though they are usedin many list functions such as `filter`.* Example 2: the main type in `Data.List.Relation.Unary.All` is `All P xs` where`A : Set a`, `P : Pred A p`, `xs : List A`. It therefore may declare variablesover `Level`, `Set a`, `A`, `List A`, `Pred A p`. It may not declare, for example,variables of type `Rel` or `Vec`.## Naming conventions* Names should be descriptive - i.e. given the name of a proof and themodule it lives in, then users should be able to make a reasonableguess at its meaning.* Terms from other modules should only be renamed to avoid name clashes,otherwise, all names should be used as defined.* Datatype names should be capitalized, being its first letter in uppercaseand the remaining letters in lowercase.* Function names should follow the camelCase naming convention, in which eachword within a compound word is capitalized except for the first word.#### Variables* Sets are named `A`, `B`, `C` etc.* Predicates are named `P`, `Q`, `R` etc.* Relations are named either `R`, `S`, `T` in the general caseor `_≈_`/`_∼_`/`_≤_`/`_<_` if they are known to be anequivalence/preorder/partial order/strict partial order.* Level variables are typically chosen to match the name of therelation, e.g. `a` for the level of a set `A`, `p` for a predicate`P`. By convention the name `0ℓ` is preferred over `zero` for thezeroth level.* Natural variables are named `m`, `n`, `o`, ... (default `n`)* Integer variables are named `i`, `j`, `k`, ... (default `i`)* Rational variables are named `p`, `q`, `r`, ... (default `p`)* All other variables should be named `x`, `y`, `z`.* Collections of elements are usually indicated by appending an `s`(e.g. if you are naming your variables `x` and `y` then listsshould be named `xs` and `ys`).#### Preconditions and postconditions* Preconditions should only be included in names of results if"important" (mostly a judgment call).* Preconditions of results should be prepended to a descriptionof the result by using the symbol `⇒` in names (e.g. `asym⇒antisym`)* Preconditions and postconditions should be combined using the symbols`∨` and `∧` (e.g. `m*n≡0⇒m≡0∨n≡0`)* Try to avoid the need for bracketing, but if necessary, use squarebrackets (e.g. `[m∸n]⊓[n∸m]≡0`)* When naming proofs, the variables should occur in alphabetical order,e.g. `m≤n+m` rather than `n≤m+n`.#### Operators and relations* Concrete operators and relations should be defined using[mixfix](https://agda.readthedocs.io/en/latest/language/mixfix-operators.html)notation where applicable (e.g. `_+_`, `_<_`)* Common properties such as those in rings/orders/equivalences etc.have defined abbreviations (e.g. commutativity is shortened to `comm`).`Data.Nat.Properties` is a good place to look for examples.* Properties should be prefixed by the relevant operator/relation andseparated from its name by a hyphen `-` (e.g. commutativity of sumresults in a compositional name `+-comm` where `-` acts as a separator).* If the relevant Unicode characters are available, negated forms ofrelations should be used over the `¬` symbol (e.g. `m+n≮n` should beused instead of `¬m+n<n`).#### Symbols for operators and relations* The stdlib aims to use a consistent set of notations, governed by aconsistent set of conventions, but sometimes, differentUnicode/emacs-input-method symbols nevertheless can be rendered byidentical-*seeming* symbols, so this is an attempt to document these.* The typical binary operator in the `Algebra` hierarchy, inheritingfrom the root `Structure`/`Bundle` `isMagma`/`Magma`, is written asinfix `∙`, obtained as `\.`, NOT as `\bu2`. Nevertheless, there isalso a 'generic' operator, written as infix `·`, obtained as`\cdot`. Do NOT attempt to use related, but typographicallyindistinguishable, symbols.* Similarly, 'primed' names and symbols, used to standardise namesapart, or to provide (more) simply-typed versions ofdependently-typed operations, should be written using `\'`, NOT theunmarked `'` character.* Likewise, standard infix symbols for eg, divisibility on numericdatatypes/algebraic structure, should be written `\|`, NOT theunmarked `|` character. An exception to this is the *strict*ordering relation, written using `<`, NOT `\<` as might be expected.* Since v2.0, the `Algebra` hierarchy systematically introducesconsistent symbolic notation for the negated versions of the usualbinary predicates for equality, ordering etc. These are obtainedfrom the corresponding input sequence by adding `n` to the symbolname, so that `≤`, obtained as `\le`, becomes `≰` obtained as`\len`, etc.* Correspondingly, the flipped symbols (and their negations) for theconverse relations are systematically introduced, eg `≥` as `\ge`and `≱` as `\gen`.* Any exceptions to these conventions should be flagged on the GitHub`agda-stdlib` issue tracker in the usual way.#### FixityAll functions and operators that are not purely prefix (typicallyanything that has a `_` in its name) should have an explicit fixitydeclared for it. The guidelines for these are as follows:General operations and relations:* binary relations of all kinds are `infix 4`* unary prefix relations `infix 4 ε∣_`* unary postfix relations `infixr 8 _∣0`* multiplication-like: `infixl 7 _*_`* addition-like `infixl 6 _+_`* arithmetic prefix minus-like `infix 8 -_`* arithmetic infix binary minus-like `infixl 6 _-_`* and-like `infixr 7 _∧_`* or-like `infixr 6 _∨_`* negation-like `infix 3 ¬_`* post-fix inverse `infix 8 _⁻¹`* bind `infixl 1 _>>=_`* list concat-like `infixr 5 _∷_`* ternary reasoning `infix 1 _⊢_≈_`* composition `infixr 9 _∘_`* application `infixr -1 _$_ _$!_`* combinatorics `infixl 6.5 _P_ _P′_ _C_ _C′_`* pair `infixr 4 _,_`Reasoning:* QED `infix 3 _∎`* stepping `infixr 2 _≡⟨⟩_ step-≡ step-≡˘`* begin `infix 1 begin_`Type formers:* product-like `infixr 2 _×_ _-×-_ _-,-_`* sum-like `infixr 1 _⊎_`* binary properties `infix 4 _Absorbs_`#### Functions and relations over specific datatypes* When defining a new relation `P` over a datatype `X` in a `Data.X.Relation` module,it is often common to define how to introduce and eliminate that relationwith respect to various functions. Suppose you have a function `f`, then- `f⁺` is a lemma of the form `Precondition -> P(f)`- `f⁻` is a lemma of the form `P(f) -> Postcondition`The logic behind the name is that `⁺` makes f appear in the conclusion while`⁻` makes it disappear from the hypothesis.For example, in `Data.List.Relation.Binary.Pointwise` we have `map⁺` to showhow the `map` function may be introduced and `map⁻` to show how it may beeliminated:```agdamap⁺ : Pointwise (λ a b → R (f a) (g b)) as bs → Pointwise R (map f as) (map g bs)map⁻ : Pointwise R (map f as) (map g bs) → Pointwise (λ a b → R (f a) (g b)) as bs```* When specifying a property over a container, there are usually two choices. Eitherassume the property holds for generally (e.g. `map id xs ≡ xs`) or a assume thatit only holds for the elements within the container (e.g. `All (λ x → f x ≡ x) xs → map f xs ≡ xs`).The naming convention is to add a `-local` suffix on to the name of the latter variety.e.g.```agdamap-id : map id xs ≡ xsmap-id-local : All (λ x → f x ≡ x) xs → map f xs ≡ xs```#### Keywords* If the name of something clashes with a keyword in Agda, then conventionis to place angular brackets around the name, e.g. `⟨set⟩` and `⟨module⟩`.#### Reflected syntax* When using reflection, the name of anything of type `Term` should be precededby a backtick. For example ```List : Term → Term`` would be the functionconstructing the reflection of the `List` type.* The names of patterns for reflected syntax are also *appended* with anadditional backtick.#### Specific pragmatics/idiomatic patterns## Use of `pattern` synonymsIn general, these are intended to be used to provide specialisedconstructors for `Data` types (and sometimes, inductivefamilies/binary relations such as `Data.Nat.Divisibility._∣_`), and assuch, their use should be restricted to `Base` or `Core` modules, andnot pollute the namespaces of `Properties` or other modules.## Use of `with` notationThinking on this has changed since the early days of the library, witha desire to avoid 'unnecessary' uses of `with`: see Issues[#1937](https://github.com/agda/agda-stdlib/issues/1937) and[#2123](https://github.com/agda/agda-stdlib/issues/2123).## Proving instances of `Decidable` for sets, predicates, relations, ...Issue [#803](https://github.com/agda/agda-stdlib/issues/803)articulates a programming pattern for writing proofs of decidability,used successfully in PR[#799](https://github.com/agda/agda-stdlib/pull/799) and madesystematic for `Nary` relations in PR[#811](https://github.com/agda/agda-stdlib/pull/811)
name: standard-library-docinclude: . ../srcflags:--warning=noUnsupportedIndexedMatch
When releasing a new version of Agda standard library, the followingprocedure should be followed:#### Pre-release changes* Update `doc/README.agda` by replacing 'development version' by 'version X.Y' in the title.* Update the version to `X.Y` in:- `agda-stdlib-utils.cabal`- `standard-library.agda-lib`- `CITATION.cff`- `CHANGELOG.md`- `README.md`- `doc/installation-guide.md`* Update the copyright year range in the LICENSE file, if necessary.#### Pre-release tests* Ensure that the library type-checks using Agda A.B.C:make test* Update submodule commit in the Agda repository:cd agdamake fast-forward-std-lib* Build the latest version of Agdamake quicker-install-bin* Run the tests involving the library:make test-using-std-lib* Commit the changes and push#### Release* Tag version X.Y (do not forget to record the changes above first):VERSION=X.Ygit tag -a v$VERSION -m "Agda standard library version $VERSION"* Push all the changes and the new tag (requires Git >= 1.8.3):git push --follow-tags* Make a new release on Github at https://github.com/agda/agda-stdlib/releases* Submit a pull request to update the version of standard library on Homebrew(https://github.com/Homebrew/homebrew-core/blob/master/Formula/agda.rb)* Update the Agda wiki:** The standard library page.** News section on the main page.* Announce the release of the new version on the Agda mailing lists(users and developers).* Generate and upload documentation for the released version:cp .github/tooling/* .cabal run GenerateEverything.hs./index.shagda -i. -idoc -isrc --html index.agdamv html v$VERSIONgit checkout gh-pagesgit add v$VERSION/*.html v$VERSION/*.cssgit commit -m "[ release ] doc for version $VERSION"git pushAfter that you can cleanup the generated files and copies of things taken from travis/from your agda-stdlib directory.#### Post-release* Move the CHANGELOG.md into the old CHANGELOG folders* Create new CHANGELOG.md file* Update `standard-library.agda-lib` to the new version/milestone on `master`
Installation instructions=========================Note: the full story on installing Agda libraries can be found at [readthedocs](http://agda.readthedocs.io/en/latest/tools/package-system.html).Use version v2.1 of the standard library with Agda 2.6.4 or 2.6.4.3.1. Navigate to a suitable directory `$HERE` (replace appropriately) whereyou would like to install the library.2. Download the tarball of v2.1 of the standard library. This can either bedone manually by visiting the Github repository for the library, or via thecommand line as follows:```wget -O agda-stdlib.tar https://github.com/agda/agda-stdlib/archive/v2.1.tar.gz```Note that you can replace `wget` with other popular tools such as `curl` and thatyou can replace `2.1` with any other version of the library you desire.3. Extract the standard library from the tarball. Again this can either bedone manually or via the command line as follows:```tar -zxvf agda-stdlib.tar```4. [ OPTIONAL ] If using [cabal](https://www.haskell.org/cabal/) then runthe commands to install via cabal:```cd agda-stdlib-2.1cabal install```5. Locate the file `$HOME/.agda/libraries` where `$HOME` on Ubuntu/MacOSis an environment variable that points to your home directory. Thevalue of the environment variable can be found by running `echo $HOME`.Note that the `.agda` directory and the `libraries` file within it,may not exist and you may have to create them.6. Register the standard library with Agda's package system by addingthe following line to `$HOME/.agda/libraries`:```$HERE/agda-stdlib-2.1/standard-library.agda-lib```Now, the standard library is ready to be used either:- in your project `$PROJECT`, by creating a file`$PROJECT.agda-lib` in the project's root containing:```depend: standard-libraryinclude: $DIRS```where `$DIRS` is a list of directories where Agdasearches for modules, for instance `.` (just the project's root).- in all your projects, by adding the following line to`$HOME/.agda/defaults````standard-library```
{-# OPTIONS --rewriting --guardedness --sized-types #-}module README where-------------------------------------------------------------------------- The Agda standard library, version 2.1---- Authors: Nils Anders Danielsson, Matthew Daggitt, Guillaume Allais-- with contributions from Andreas Abel, Stevan Andjelkovic,-- Jean-Philippe Bernardy, Peter Berry, Bradley Hardy, Joachim Breitner,-- Samuel Bronson, Daniel Brown, Jacques Carette, James Chapman,-- Liang-Ting Chen, Dominique Devriese, Dan Doel, Érdi Gergő,-- Zack Grannan, Helmut Grohne, Simon Foster, Liyang Hu, Jason Hu,-- Patrik Jansson, Alan Jeffrey, Wen Kokke, Evgeny Kotelnikov,-- James McKinna, Sergei Meshveliani, Eric Mertens, Darin Morrison,-- Guilhem Moulin, Shin-Cheng Mu, Ulf Norell, Noriyuki Ohkawa,-- Nicolas Pouillard, Andrés Sicard-Ramírez, Lex van der Stoep,-- Sandro Stucki, Milo Turner, Noam Zeilberger, Shu-Hung You-- and other anonymous contributors.-------------------------------------------------------------------------- This version of the library has been tested using Agda 2.6.4.X-- The library comes with a .agda-lib file, for use with the library-- management system.-- Currently the library does not support the JavaScript compiler-- backend.-------------------------------------------------------------------------- Stability guarantees-------------------------------------------------------------------------- We do our best to adhere to the spirit of semantic versioning in that-- minor versions should not break people's code. This applies to the-- the entire library with one exception: modules with names that end in-- either ".Core" or ".Primitive".-- The former have (mostly) been created to avoid mutual recursion-- between modules and the latter to bind primitive operations to the-- more efficient operations supplied by the relevant backend.-- These modules may undergo backwards incompatible changes between-- minor versions and therefore are imported directly at your own risk.-- Instead their contents should be accessed by their parent module,-- whose interface will remain stable.-------------------------------------------------------------------------- High-level overview of contents-------------------------------------------------------------------------- The top-level module names of the library are currently allocated-- as follows:---- • Algebra-- Abstract algebra (monoids, groups, rings etc.), along with-- properties needed to specify these structures (associativity,-- commutativity, etc.), and operations on and proofs about the-- structures.-- • Axiom-- Types and consequences of various additional axioms not-- necessarily included in Agda, e.g. uniqueness of identity-- proofs, function extensionality and excluded middle.import README.Axiom-- • Codata-- Coinductive data types and properties. There are two different-- approaches taken. The `Codata.Sized` folder contains the new more-- standard approach using sized types. The `Codata.Musical`-- folder contains modules using the old musical notation.-- • Data-- Data types and properties.-- • Effect-- Category theory-inspired idioms used to structure functional-- programs (functors and monads, for instance).import README.Data-- • Function-- Combinators and properties related to functions.-- • Foreign-- Related to the foreign function interface.-- • Induction-- A general framework for induction (includes lexicographic and-- well-founded induction).-- • IO-- Input/output-related functions.import README.IO-- • Level-- Universe levels.-- • Reflection-- Support for reflection.-- • Relation-- Properties of and proofs about relations.-- • Size-- Sizes used by the sized types mechanism.-- • Strict-- Provides access to the builtins relating to strictness.-- • Tactic-- Tactics for automatic proof generation-- ∙ Text-- Format-based printing, Pretty-printing, and regular expressions-------------------------------------------------------------------------- Library design-------------------------------------------------------------------------- The following modules contain a discussion of some of the choices-- that have been made whilst designing the library.-- • How mathematical hierarchies (e.g. preorder, partial order, total-- order) are handled in the library.import README.Design.Hierarchies-- • How decidability is handled in the library.import README.Design.Decidability-------------------------------------------------------------------------- A selection of useful library modules-------------------------------------------------------------------------- Note that module names in source code are often hyperlinked to the-- corresponding module. In the Emacs mode you can follow these-- hyperlinks by typing M-. or clicking with the middle mouse button.-- • Some data typesimport Data.Bool -- Booleans.import Data.Char -- Characters.import Data.Empty -- The empty type.import Data.Fin -- Finite sets.import Data.List -- Lists.import Data.Maybe -- The maybe type.import Data.Nat -- Natural numbers.import Data.Product -- Products.import Data.String -- Strings.import Data.Sum -- Disjoint sums.import Data.Unit -- The unit type.import Data.Vec -- Fixed-length vectors.-- • Some co-inductive data typesimport Codata.Sized.Stream -- Streams.import Codata.Sized.Colist -- Colists.-- • Some types used to structure computationsimport Effect.Functor -- Functors.import Effect.Applicative -- Applicative functors.import Effect.Monad -- Monads.-- • Equality-- Propositional equality:import Relation.Binary.PropositionalEquality-- Convenient syntax for "equational reasoning" using a preorder:import Relation.Binary.Reasoning.Preorder-- Solver for commutative ring or semiring equalities:import Algebra.Solver.Ring-- • Properties of functions, sets and relations-- Monoids, rings and similar algebraic structures:import Algebra-- Negation, decidability, and similar operations on sets:import Relation.Nullary-- Properties of homogeneous binary relations:import Relation.Binary-- • Induction-- An abstraction of various forms of recursion/induction:import Induction-- Well-founded induction:import Induction.WellFounded-- Various forms of induction for natural numbers:import Data.Nat.Induction-- • Support for coinductionimport Codata.Musical.Notationimport Codata.Sized.Thunk-- • IOimport IO-- ∙ Text-- Dependently typed formatted printingimport Text.Printf-------------------------------------------------------------------------- More documentation-------------------------------------------------------------------------- Some examples showing how the case expression can be used.import README.Case-- Showcasing the framework for well-scoped substitutionsimport README.Data.Fin.Substitution.UntypedLambda-- Some examples showing how combinators can be used to emulate-- "functional reasoning"import README.Function.Reasoning-- An example showing how to use the debug tracing mechanism to inspect-- the behaviour of compiled Agda programs.import README.Debug.Trace-- An exploration of the generic programs acting on n-ary functions and-- n-ary heterogeneous productsimport README.Nary-- Explaining the inspect idiom: use case, equivalent handwritten-- auxiliary definitions, and implementation details.import README.Inspect-- Explaining how to use the automatic solversimport README.Tactic.MonoidSolverimport README.Tactic.RingSolver-- Explaining how the Haskell FFI worksimport README.Foreign.Haskell-- Explaining string formats and the behaviour of printfimport README.Text.Printf-- Showcasing the pretty printing moduleimport README.Text.Pretty-- Demonstrating the regular expression matchingimport README.Text.Regex-- Explaining how to display tables of strings:import README.Text.Tabular-------------------------------------------------------------------------- All library modules-------------------------------------------------------------------------- For short descriptions of every library module, see Everything;-- to exclude unsafe modules, see EverythingSafe:import Everythingimport EverythingSafe-- Note that the Everything* modules are generated automatically. If-- you have downloaded the library from its Git repository and want-- to type check README then you can (try to) construct Everything by-- running "cabal install && GenerateEverything".-- Note that all library sources are located under src or ffi. The-- modules README, README.* and Everything are not really part of the-- library, so these modules are located in the top-level directory-- instead.
-------------------------------------------------------------------------- The Agda standard library---- Examples of printing list and vec-based tables------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module README.Text.Tabular whereopen import Function.Baseopen import Relation.Binary.PropositionalEqualityopen import Data.List.Baseopen import Data.String.Baseopen import Data.Vec.Baseopen import Text.Tabular.Baseimport Text.Tabular.List as Tabularˡimport Text.Tabular.Vec as Tabularᵛ-------------------------------------------------------------------------- VEC---- If you have a matrix of strings, you simply need to:-- * pick a configuration (see below)-- * pick an alignment for each column-- * pass the matrix---- The display function will then pad each string on the left, right,-- or both to respect the alignment constraints.-- It will return a list of strings corresponding to each line in the-- table. You may then:--- * use Data.String.Base's unlines to produce a String-- * use Text.Pretty's text and vcat to produce a Doc (i.e. indentable!)------------------------------------------------------------------------_ : unlines (Tabularᵛ.display unicode(Right ∷ Left ∷ Center ∷ [])( ("foo" ∷ "bar" ∷ "baz" ∷ [])∷ ("1" ∷ "2" ∷ "3" ∷ [])∷ ("6" ∷ "5" ∷ "4" ∷ [])∷ []))≡ "┌───┬───┬───┐\ \│foo│bar│baz│\ \├───┼───┼───┤\ \│ 1│2 │ 3 │\ \├───┼───┼───┤\ \│ 6│5 │ 4 │\ \└───┴───┴───┘"_ = refl-------------------------------------------------------------------------- CONFIG---- Configurations allow you to change the way the table is displayed.-------------------------------------------------------------------------- We will use the same example throughoutfoobar : Vec (Vec String 2) 3foobar = ("foo" ∷ "bar" ∷ [])∷ ("1" ∷ "2" ∷ [])∷ ("4" ∷ "3" ∷ [])∷ []-------------------------------------------------------------------------- Basic configurations: unicode, ascii, whitespace-- unicode_ : unlines (Tabularᵛ.display unicode(Right ∷ Left ∷ [])foobar)≡ "┌───┬───┐\ \│foo│bar│\ \├───┼───┤\ \│ 1│2 │\ \├───┼───┤\ \│ 4│3 │\ \└───┴───┘"_ = refl-- ascii_ : unlines (Tabularᵛ.display ascii(Right ∷ Left ∷ [])foobar)≡ "+-------+\ \|foo|bar|\ \|---+---|\ \| 1|2 |\ \|---+---|\ \| 4|3 |\ \+-------+"_ = refl-- whitespace_ : unlines (Tabularᵛ.display whitespace(Right ∷ Left ∷ [])foobar)≡ "foo bar\ \ 1 2\ \ 4 3 "_ = refl-------------------------------------------------------------------------- Modifiers: altering existing configurations-- In these examples we will be using unicode as the base configuration.-- However these modifiers apply to all configurations (and can even be-- combined)-- compact: drop the horizontal line between each row_ : unlines (Tabularᵛ.display (compact unicode)(Right ∷ Left ∷ [])foobar)≡ "┌───┬───┐\ \│foo│bar│\ \│ 1│2 │\ \│ 4│3 │\ \└───┴───┘"_ = refl-- noBorder: drop the outside borders_ : unlines (Tabularᵛ.display (noBorder unicode)(Right ∷ Left ∷ [])foobar)≡ "foo│bar\ \───┼───\ \ 1│2\ \───┼───\ \ 4│3 "_ = refl-- addSpace : add whitespace space inside cells_ : unlines (Tabularᵛ.display (addSpace unicode)(Right ∷ Left ∷ [])foobar)≡ "┌─────┬─────┐\ \│ foo │ bar │\ \├─────┼─────┤\ \│ 1 │ 2 │\ \├─────┼─────┤\ \│ 4 │ 3 │\ \└─────┴─────┘"_ = refl-- compact together with addSpace_ : unlines (Tabularᵛ.display (compact (addSpace unicode))(Right ∷ Left ∷ [])foobar)≡ "┌─────┬─────┐\ \│ foo │ bar │\ \│ 1 │ 2 │\ \│ 4 │ 3 │\ \└─────┴─────┘"_ = refl-------------------------------------------------------------------------- LIST---- Same thing as for vectors except that if the list of lists is not-- rectangular, it is padded with empty strings to make it so. If there-- are not enough alignment directives, we arbitrarily pick Left.------------------------------------------------------------------------_ : unlines (Tabularˡ.display unicode(Center ∷ Right ∷ [])( ("foo" ∷ "bar" ∷ [])∷ ("partial" ∷ "rows" ∷ "are" ∷ "ok" ∷ [])∷ ("3" ∷ "2" ∷ "1" ∷ "..." ∷ "surprise!" ∷ [])∷ []))≡ "┌───────┬────┬───┬───┬─────────┐\ \│ foo │ bar│ │ │ │\ \├───────┼────┼───┼───┼─────────┤\ \│partial│rows│are│ok │ │\ \├───────┼────┼───┼───┼─────────┤\ \│ 3 │ 2│1 │...│surprise!│\ \└───────┴────┴───┴───┴─────────┘"_ = refl-------------------------------------------------------------------------- LIST (UNSAFE)---- If you know *for sure* that your data is already perfectly rectangular-- i.e. all the rows of the list of lists have the same length-- in each column, all the strings have the same width-- then you can use the unsafeDisplay function defined Text.Tabular.Base.---- This is what gets used internally by `Text.Tabular.Vec` and-- `Text.Tabular.List` once the potentially unsafe data has been-- processed.------------------------------------------------------------------------_ : unlines (unsafeDisplay (compact unicode)( ("foo" ∷ "bar" ∷ [])∷ (" 1" ∷ " 2" ∷ [])∷ (" 4" ∷ " 3" ∷ [])∷ []))≡ "┌───┬───┐\ \│foo│bar│\ \│ 1│ 2│\ \│ 4│ 3│\ \└───┴───┘"_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Examples of regular expressions and matching------------------------------------------------------------------------{-# OPTIONS --with-K #-}module README.Text.Regex whereopen import Data.Bool using (true; false)open import Data.List.Base using (_∷_; [])open import Data.Stringopen import Function.Base using () renaming (_$′_ to _$_)open import Relation.Nullary.Decidable using (yes)open import Relation.Nullary.Decidable using (True; False; from-yes)-- Our library available via the Text.Regex module is safe but it works on-- lists of characters.-- To use it on strings we have to rely on unsafe theorems about the-- conversions between strings and lists of characters being inverses.-- For convenience we use the following unsafe module for this README.open import Text.Regex.String.Unsafe-------------------------------------------------------------------------- Defining regular expressions-- The type of regular expressions is Exp.-- Some examples of regular expressions using:-- [_] for the union of ranges it contains-- _─_ for a range-- singleton for an exact character-- _∙_ for the concatenation of two regular expressions-- _∣_ for the sum of two regular expressions-- _⋆ for the Kleene star (zero or more matches of the regular expression)-- _⁇ for an optional regular expressionℕ* : Expℕ* = [ '1' ─ '9' ∷ [] ] -- a non-zero digit∙ [ '0' ─ '9' ∷ [] ] ⋆ -- followed by zero or more digitsℕ : Expℕ = ℕ* ∣ singleton '0' -- ℕ* or exactly 0ℤ : Expℤ = ((singleton '-') ⁇ ∙ ℕ*) -- an optional minus sign followed by a ℕ*∣ singleton '0' -- or exactly 0-------------------------------------------------------------------------- An expression's semantics-- The semantics of these regular expression is defined in terms of the-- lists of characters they match. The type (str ∈ e) states that the-- string str matches the expression e.-- It is decidable, and the proof is called _∈?_.-- We can run it on a few examples to check that it matches our intuition:-- Valid: starts with a non-zero digit, followed by 3 digits_ : True ("1848" ∈? ℕ*)_ = _-- Valid: exactly 0_ : True ("0" ∈? ℕ)_ = _-- Invalid: starts with a leading 0_ : False ("007" ∈? ℕ)_ = _-- Invalid: no negative ℕ number_ : False ("-666" ∈? ℕ)_ = _-- Valid: a negative integer_ : True ("-666" ∈? ℤ)_ = _-- Invalid: no negative 0_ : False ("-0" ∈? ℤ)_ = _-------------------------------------------------------------------------- Matching algorithms-- The proof that _∈_ is decidable gives us the ability to check whether-- a whole string matches a regular expression. But we may want to use-- other matching algorithms detecting a prefix, infix, or suffix of the-- input string that matches the regular expression.-- This is what the Regex type gives us.-- For instance, the following value corresponds to finding an infix-- substring matching the string "agda" or "agdai"agda : Expagda = singleton 'a'∙ singleton 'g'∙ singleton 'd'∙ singleton 'a'∙ (singleton 'i' ⁇)infixAgda : RegexinfixAgda = record{ fromStart = false; tillEnd = false; expression = agda}-- The search function gives us the ability to look for matches-- Valid: agda in the middle_ : True (search "Maria Magdalena" infixAgda)_ = _-- By changing the value of fromStart and tillEnd we can control where the-- substring should be. We can insist on the match being at the end of the-- input for instance:suffixAgda : RegexsuffixAgda = record{ fromStart = false; tillEnd = true; expression = agda}-- Invalid: agda is in the middle_ : False (search "Maria Magdalena" suffixAgda)_ = _-- Valid: agda as a suffix_ : True (search "README.agda" suffixAgda)_ = _-- Valid: agdai as a suffix_ : True (search "README.agdai" suffixAgda)_ = _-------------------------------------------------------------------------- Advanced uses-- Search does not just return a boolean, it returns an informative answer.-- Infix matches are for instance represented using the `Infix` relation on-- list. Such a proof pinpoints the exact position of the match:open import Data.List.Relation.Binary.Infix.Heterogeneousopen import Data.List.Relation.Binary.Infix.Heterogeneous.Propertiesopen import Data.List.Relation.Binary.Pointwise using (≡⇒Pointwise-≡)open import Relation.Binary.PropositionalEquality-- Here is an example of a match: it gives back the substring, the inductive-- proof that it is accepted by the regular expression and its precise location-- inside the input stringmariamAGDAlena : Match "Maria Magdalena" infixAgdamariamAGDAlena = record{ string = "agda" -- we have found "agda"; match = from-yes ("agda" ∈? agda) -- a proof of the match; related = proof -- and its location}whereproof : Infix _≡_ (toList "agda") (toList "Maria Magdalena")proof = toList "Maria M"++ⁱ fromPointwise (≡⇒Pointwise-≡ refl)ⁱ++ toList "lena"-- And here is the proof that search returns such an object_ : search "Maria Magdalena" infixAgda ≡ yes mariamAGDAlena_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Examples of format strings and printf------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module README.Text.Printf whereopen import Data.Nat.Baseopen import Data.Char.Baseopen import Data.List.Baseopen import Data.String.Baseopen import Data.Sum.Baseopen import Relation.Binary.PropositionalEquality-------------------------------------------------------------------------- Format stringsopen import Text.Format-- We can specify a format by writing a string which will get interpreted-- by a lexer into a list of formatting directives.-- The specification types are always started with a '%' character:-- Integers (%d or %i)-- Naturals (%u)-- Floats (%f)-- Chars (%c)-- Strings (%s)-- Anything which is not a type specification is a raw string to be spliced-- in the output of printf.-- For instance the following format alternates types and raw strings_ : lexer "%s: %u + %u ≡ %u"≡ inj₂ (`String ∷ Raw ": " ∷ `ℕ ∷ Raw " + " ∷ `ℕ ∷ Raw " ≡ " ∷ `ℕ ∷ [])_ = refl-- Lexing can fail. There are two possible errors:-- If we start a specification type with a '%' but the string ends then-- we get an UnexpectedEndOfString error_ : lexer "%s: %u + %u ≡ %"≡ inj₁ (UnexpectedEndOfString "%s: %u + %u ≡ %")_ = refl-- If we start a specification type with a '%' and the following character-- does not correspond to an existing type, we get an InvalidType error-- together with a focus highlighting the position of the problematic type._ : lexer "%s: %u + %a ≡ %u"≡ inj₁ (InvalidType "%s: %u + %" 'a' " ≡ %u")_ = refl-------------------------------------------------------------------------- Printfopen import Text.Printf-- printf is a function which takes a format string as an argument and-- returns a function expecting a value for each type specification present-- in the format and returns a string splicing in these values into the-- format string.-- For instance `printf "%s: %u + %u ≡ %u"` is a-- `String → ℕ → ℕ → ℕ → String` function._ : String → ℕ → ℕ → ℕ → String_ = printf "%s: %u + %u ≡ %u"_ : printf "%s: %u + %u ≡ %u" "example" 3 2 5≡ "example: 3 + 2 ≡ 5"_ = refl-- If the format string str is invalid then `printf str` will have type-- `Error e` where `e` is the lexing error._ : Text.Printf.Error (UnexpectedEndOfString "%s: %u + %u ≡ %")_ = printf "%s: %u + %u ≡ %"_ : Text.Printf.Error (InvalidType "%s: %u + %" 'a' " ≡ %u")_ = printf "%s: %u + %a ≡ %u"-- Trying to pass arguments to such an ̀Error` type will lead to a-- unification error which hopefully makes the problem clear e.g.-- `printf "%s: %u + %a ≡ %u" "example" 3 2 5` fails with the error:-- Text.Printf.Error (InvalidType "%s: %u + %" 'a' " ≡ %u") should be-- a function type, but it isn't-- when checking that "example" 3 2 5 are valid arguments to a-- function of type Text.Printf.Printf (lexer "%s: %u + %a ≡ %u")
-------------------------------------------------------------------------- The Agda standard library---- Examples of pretty printing------------------------------------------------------------------------{-# OPTIONS --sized-types #-}module README.Text.Pretty whereopen import Sizeopen import Data.Bool.Baseopen import Data.List.Base as Listopen import Data.List.NonEmpty as List⁺open import Data.Nat.Baseopen import Data.Product.Base using (_×_; uncurry; _,_)open import Data.String.Base hiding (parens; _<+>_)open import Data.Vec.Base as Vecopen import Function.Base-- We import the pretty printer and pass 80 to say that we do not want to-- have lines longer than 80 charactersopen import Text.Pretty 80open import Relation.Binary.PropositionalEquality-------------------------------------------------------------------------- A small declarative programming language-------------------------------------------------------------------------- We define a small programming language where definitions are-- introduced by providing a non-empty list of equations with:-- * the same number of patterns on the LHS-- * a term on the RHS of each equation-- A pattern is either a variable or a constructor applied to a-- list of subpatternsdata Pattern (i : Size) : Set wherevar : String → Pattern icon : ∀ {j : Size< i} → String → List (Pattern j) → Pattern i-- A term is either a (bound) variable, the application of a-- named definition / constructor to a list of arguments or a-- lambda abstractiondata Term (i : Size) : Set wherevar : String → Term iapp : ∀ {j : Size< i} → String → List (Term j) → Term ilam : ∀ {j : Size< i} → String → Term j → Term i-- As explained before, a definitions is given by a list of equationsinfix 1 _by_record Def : Set whereconstructor _by_field name : String{arity} : ℕequations : List⁺ (Vec (Pattern _) arity × (Term _))-------------------------------------------------------------------------- A pretty printer for this language-------------------------------------------------------------------------- First we print patterns. We only wrap a pattern in parentheses if it-- is compound: i.e. if it is a constructor applied to a non-empty list-- of subpatterns-- Lists of patterns are printed separated by a single space.prettyPattern : ∀ {i} → Pattern i → DocprettyPatterns : ∀ {i} → List (Pattern i) → DocprettyPattern (var v) = text vprettyPattern (con c []) = text cprettyPattern (con c ps) = parens $ text c <+> prettyPatterns psprettyPatterns = hsep ∘ List.map prettyPattern-- Next we print terms. The Bool argument tells us whether we are on-- the RHS of an application (in which case it is sensible to wrap-- complex subterms in parentheses).prettyTerm : ∀ {i} → Bool → Term i → DocprettyTerm l (var v) = text vprettyTerm l (app f []) = text fprettyTerm l (app f es) = if l then parens else id$ text f <+> sep (List.map (prettyTerm true) es)prettyTerm l (lam x b) = if l then parens else id$ text "λ" <+> text x <> text "." <+> prettyTerm false b-- We now have all the pieces to print definitions.-- We print the equations below each other by using vcat.---- The LHS is printed as follows: the name of the function followed by-- the space-separated list of patterns (if any) and then an equal sign.---- The RHS is printed as a term which is *not* on the RHS of an application.---- Finally we can layout the definition in two different manners:-- * either LHS followed by RHS-- * or LHS followed and the RHS as a relative block (indented by 2 spaces)-- on the next lineprettyDef : Def → DocprettyDef (fun by eqs) =vcat $ List⁺.toList $ flip List⁺.map eqs $ uncurry $ λ ps e →let lhs = text fun <+> (case ps of λ where[] → text "="_ → prettyPatterns (Vec.toList ps) <+> text "=")rhs = prettyTerm false ein lhs <+> rhs <|> lhs $$ (spaces 2 <> rhs)-- The pretty printer is obtained by using the renderer.pretty : Def → Stringpretty = render ∘ prettyDef-------------------------------------------------------------------------- Some examples-------------------------------------------------------------------------- Our first example is the identity function defined as a λ-abstraction`id : Def`id = "id" by ([] , lam "x" (var "x")) ∷ []_ : pretty `id ≡ "id = λ x. x"_ = refl-- If we were to assume that this definition also takes a level (a) and-- a Set at that level (A) as arguments, we can have a slightly more complex-- definition like so.`explicitid : Def`explicitid = "id" by (var "a" ∷ var "A" ∷ [] , lam "x" (var "x")) ∷ []_ : pretty `explicitid ≡ "id a A = λ x. x"_ = refl-- A more complex example: boolFilter, a function that takes a boolean-- predicate and a list as arguments and returns a list containing only-- the values that satisfy the predicate.-- We use nil and con for [] and _∷_ as our little toy language does not-- support infix notations.`filter : Def`filter = "boolFilter"by ( var "P?" ∷ con "nil" [] ∷ [], app "nil" [])∷ ( var "P?" ∷ con "con" (var "x" ∷ var "xs" ∷ []) ∷ [], let rec = app "filter" (var "P?" ∷ var "xs" ∷ []) inapp "if" (app "P?" (var "x" ∷ [])∷ app "con" (var "x" ∷ rec ∷ [])∷ rec∷ []))∷ []_ : pretty `filter ≡"boolFilter P? nil = nil\ \boolFilter P? (con x xs) = if (P? x) (con x (filter P? xs)) (filter P? xs)"_ = refl-- We can once more revisit this example with its more complex counterpart:-- boolFilter taking its level and set arguments explicitly (idem for the-- list constructors nil and con).-- This time laying out the second equation on a single line would produce a-- string larger than 80 characters long. So the pretty printer decides to-- make the RHS a relative block indented by 2 spaces.`explicitfilter : Def`explicitfilter = "boolFilter"by ( var "a" ∷ var "A" ∷ var "P?" ∷ con "nil" [] ∷ [], app "nil" (var "a" ∷ var "A" ∷ []))∷ ( var "a" ∷ var "A" ∷ var "P?" ∷ con "con" (var "x" ∷ var "xs" ∷ []) ∷ [], let rec = app "filter" (var "a" ∷ var "A" ∷ var "P?" ∷ var "xs" ∷ []) inapp "if" (app "P?" (var "x" ∷ [])∷ app "con" (var "a" ∷ var "A" ∷ var "x" ∷ rec ∷ [])∷ rec∷ []))∷ []_ : pretty `explicitfilter≡ "boolFilter a A P? nil = nil a A\ \boolFilter a A P? (con x xs) =\ \ if (P? x) (con a A x (filter a A P? xs)) (filter a A P? xs)"_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Examples showing how the reflective ring solver may be used.------------------------------------------------------------------------module README.Tactic.RingSolver where-- You can ignore this bit! We're just overloading the literals Agda uses for-- numbers. This bit isn't necessary if you're just using Nats, or if you-- construct your type directly. We only really do it here so that we can use-- different numeric types in the same file.open import Agda.Builtin.FromNatopen import Data.Nat using (ℕ)open import Data.Integer using (ℤ)import Data.Nat.Literals as ℕimport Data.Integer.Literals as ℤinstancenumberNat : Number ℕnumberNat = ℕ.numberinstancenumberInt : Number ℤnumberInt = ℤ.number-------------------------------------------------------------------------------- Imports!open import Data.List.Base as List using (List; _∷_; [])open import Relation.Binary.PropositionalEqualityusing (subst; cong; _≡_; module ≡-Reasoning)open import Data.Bool as Bool using (Bool; true; false; if_then_else_)open import Data.Unit using (⊤; tt)open import Tactic.RingSolver.Core.AlmostCommutativeRingusing (AlmostCommutativeRing)-------------------------------------------------------------------------- Integer examples------------------------------------------------------------------------module IntegerExamples whereopen import Data.Integer hiding (_^_)open import Data.Integer.Tactic.RingSolveropen AlmostCommutativeRing ring using (_^_)-- Everything is automatic: you just ask Agda to solve it and it does!-- Additionlemma₁ : ∀ x y → x + y + 3 ≡ 2 + y + x + 1lemma₁ = solve-∀-- Multiplicationlemma₂ : ∀ x → x * 2 + 1 ≡ x + 1 + xlemma₂ = solve-∀-- Negationlemma₃ : ∀ x y → (- x) + (- y) ≡ - (x + y)lemma₃ = solve-∀-- Subtractionlemma₄ : ∀ x y → (x - y) * 2 - 2 ≡ (- 2) * y - 1 + 2 * x - 1lemma₄ = solve-∀-- Exponentiation by constant literalslemma₅ : ∀ x y → (x + y) ^ 2 ≡ x ^ 2 + 2 * x * y + y ^ 2lemma₅ = solve-∀-- It can be interleaved with manual proofs as well.lemma₆ : ∀ x y z → y ≡ z → x + y * 1 + 3 ≡ 2 + z + x + 1lemma₆ x y z y≡z = beginx + y * 1 + 3 ≡⟨ solve (x ∷ y ∷ []) ⟩2 + y + x + 1 ≡⟨ cong (λ v → 2 + v + x + 1) y≡z ⟩2 + z + x + 1 ∎where open ≡-Reasoning-------------------------------------------------------------------------- Natural examples------------------------------------------------------------------------module NaturalExamples whereopen import Data.Natopen import Data.Nat.Tactic.RingSolver-- The solver is flexible enough to work with ℕ (even though it asks-- for rings!)lemma₁ : ∀ x y → x + y * 1 + 3 ≡ 2 + 1 + y + xlemma₁ = solve-∀-------------------------------------------------------------------------- Checking invariants-------------------------------------------------------------------------- The solver makes it easy to prove invariants, without having to-- rewrite proof code every time something changes in the data-- structure.module _ {a} {A : Set a} (_≤_ : A → A → Bool) whereopen import Data.Nat hiding (_≤_)open import Data.Nat.Tactic.RingSolver-- A Skew Heap, indexed by its size.data Tree : ℕ → Set a whereleaf : Tree 0node : ∀ {n m} → A → Tree n → Tree m → Tree (1 + n + m)-- A substitution operator, to clean things up.infixr 1 _⇒__⇒_ : ∀ {n} → Tree n → ∀ {m} → n ≡ m → Tree mx ⇒ n≡m = subst Tree n≡m xopen ≡-Reasoning_∪_ : ∀ {n m} → Tree n → Tree m → Tree (n + m)leaf ∪ ys = ysnode {a} {b} x xl xr ∪ leaf =node x xl xr ⇒ solve (a ∷ b ∷ [])node {a} {b} x xl xr ∪ node {c} {d} y yl yr =if x ≤ ythen node x (node y yl yr ∪ xr) xl ⇒ begin1 + (1 + c + d + b) + a ≡⟨ solve (a ∷ b ∷ c ∷ d ∷ []) ⟩1 + a + b + (1 + c + d) ∎else node y (node x xl xr ∪ yr) yl ⇒ begin1 + (1 + a + b + d) + c ≡⟨ solve (a ∷ b ∷ c ∷ d ∷ []) ⟩1 + a + b + (1 + c + d) ∎
-------------------------------------------------------------------------- The Agda standard library---- An explanation about how to use the solver in Tactic.MonoidSolver.------------------------------------------------------------------------open import Algebramodule README.Tactic.MonoidSolver {a ℓ} (M : Monoid a ℓ) whereopen Monoid Mopen import Relation.Binary.Reasoning.Setoid setoidopen import Tactic.MonoidSolver using (solve)-- The monoid solver is capable to of solving equations without having-- to specify the equation itself in the proof.example₁ : ∀ x y z → (x ∙ y) ∙ z ≈ x ∙ (y ∙ z) ∙ εexample₁ x y z = solve M-- The solver can also be used in equational reasoning.example₂ : ∀ w x y z → w ≈ x → (w ∙ y) ∙ z ≈ x ∙ (y ∙ z) ∙ εexample₂ w x y z w≈x = begin(w ∙ y) ∙ z ≈⟨ ∙-congʳ (∙-congʳ w≈x) ⟩(x ∙ y) ∙ z ≈⟨ solve M ⟩x ∙ (y ∙ z) ∙ ε ∎
{-# OPTIONS --cubical-compatible --safe #-}module README.Tactic.Cong whereopen import Data.Natopen import Data.Nat.DivModopen import Data.Nat.Propertiesopen import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; module ≡-Reasoning)open import Tactic.Cong using (cong! ; ⌞_⌟)------------------------------------------------------------------------ Usage------------------------------------------------------------------------ When performing large equational reasoning proofs, it's quite-- common to have to construct sophisticated lambdas to pass-- into 'cong'. This can be extremely tedious, and can bog down-- large proofs in piles of boilerplate. The 'cong!' tactic-- simplifies this process by synthesizing the appropriate call-- to 'cong' by inspecting both sides of the goal.---- This is best demonstrated with a small example. Consider-- the following proof:verbose-example : ∀ m n → m ≡ n → suc (suc (m + 0)) + m ≡ suc (suc n) + (n + 0)verbose-example m n eq =let open ≡-Reasoning inbeginsuc (suc (m + 0)) + m≡⟨ cong (λ ϕ → suc (suc (ϕ + m))) (+-identityʳ m) ⟩suc (suc m) + m≡⟨ cong (λ ϕ → suc (suc (ϕ + ϕ))) eq ⟩suc (suc n) + n≡⟨ cong (λ ϕ → suc (suc (n + ϕ))) (+-identityʳ n) ⟨suc (suc n) + (n + 0)∎-- The calls to 'cong' add a lot of boilerplate, and also-- clutter up the proof, making it more difficult to read.-- We can simplify this by using 'cong!' to deduce those-- lambdas for us.succinct-example : ∀ m n → m ≡ n → suc (suc (m + 0)) + m ≡ suc (suc n) + (n + 0)succinct-example m n eq =let open ≡-Reasoning inbeginsuc (suc (m + 0)) + m≡⟨ cong! (+-identityʳ m) ⟩suc (suc m) + m≡⟨ cong! eq ⟩suc (suc n) + n≡⟨ cong! (+-identityʳ n) ⟨suc (suc n) + (n + 0)∎------------------------------------------------------------------------ Explicit markings------------------------------------------------------------------------ The 'cong!' tactic can handle simple cases, but will-- struggle when presented with equality proofs like-- 'm + n ≡ n + m' or 'm + (n + o) ≡ (m + n) + o'.---- The reason behind this is that this tactic operates by simple-- anti-unification; it examines both sides of the equality goal-- to deduce where to generalize. When presented with two sides-- of an equality like 'm + n ≡ n + m', it will anti-unify to-- 'ϕ + ϕ', which is too specific.---- In cases like these, you may explicitly mark the subterms to-- be generalized by wrapping them in the marker function, ⌞_⌟.marker-example₁ : ∀ m n o p → m + n + (o + p) ≡ n + m + (p + o)marker-example₁ m n o p =let open ≡-Reasoning inbegin⌞ m + n ⌟ + (o + p)≡⟨ cong! (+-comm m n) ⟩n + m + ⌞ o + p ⌟≡⟨ cong! (+-comm p o) ⟨n + m + (p + o)∎marker-example₂ : ∀ m n → m + n + (m + n) ≡ n + m + (n + m)marker-example₂ m n =let open ≤-Reasoning inbegin-equality⌞ m + n ⌟ + ⌞ m + n ⌟≡⟨ cong! (+-comm m n) ⟩n + m + (n + m)∎------------------------------------------------------------------------ Unit Tests----------------------------------------------------------------------module LiteralTests(assumption : 48 ≡ 42)(f : ℕ → ℕ → ℕ → ℕ)wheretest₁ : 40 + 2 ≡ 42test₁ = cong! refltest₂ : 48 ≡ 42 → 42 ≡ 48test₂ eq = cong! (sym eq)test₃ : (f : ℕ → ℕ) → f 48 ≡ f 42test₃ f = cong! assumptiontest₄ : (f : ℕ → ℕ → ℕ) → f 48 48 ≡ f 42 42test₄ f = cong! assumptiontest₅ : f 48 45 48 ≡ f 42 45 42test₅ = cong! assumptionmodule LambdaTests(assumption : 48 ≡ 42)wheretest₁ : (λ x → x + 48) ≡ (λ x → x + 42)test₁ = cong! assumptiontest₂ : (λ x y z → x + (y + 48 + z)) ≡ (λ x y z → x + (y + 42 + z))test₂ = cong! assumptionmodule HigherOrderTests(f g : ℕ → ℕ)wheretest₁ : f ≡ g → ∀ n → f n ≡ g ntest₁ eq n = cong! eqtest₂ : f ≡ g → ∀ n → f (f (f n)) ≡ g (g (g n))test₂ eq n = cong! eqmodule EquationalReasoningTests wheretest₁ : ∀ m n → m ≡ n → suc (suc (m + 0)) + m ≡ suc (suc n) + (n + 0)test₁ m n eq =let open ≡-Reasoning inbeginsuc (suc (m + 0)) + m≡⟨ cong! (+-identityʳ m) ⟩suc (suc m) + m≡⟨ cong! eq ⟩suc (suc n) + n≡⟨ cong! (+-identityʳ n) ⟨suc (suc n) + (n + 0)∎test₂ : ∀ m n → m ≡ n → suc (m + m) ≤ suc (suc (n + n))test₂ m n eq =let open ≤-Reasoning inbeginsuc (m + m)≡⟨ cong! eq ⟩suc (n + n)≤⟨ n≤1+n _ ⟩suc (suc (n + n))∎module MetaTests wheretest₁ : ∀ m n o → .⦃ _ : NonZero o ⦄ → (m + n) / o ≡ (n + m) / otest₁ m n o =let open ≤-Reasoning inbegin-equality⌞ m + n ⌟ / o≡⟨ cong! (+-comm m n) ⟩(n + m) / o∎test₂ : ∀ m n o p q r → .⦃ _ : NonZero o ⦄ → .⦃ _ : NonZero p ⦄ →.⦃ _ : NonZero q ⦄ → p ≡ q ^ r → (m + n) % o % p ≡ (n + m) % o % ptest₂ m n o p q r eq =letopen ≤-Reasoninginstance q^r≢0 = m^n≢0 q rinbegin-equality(m + n) % o % p≡⟨ %-congʳ eq ⟩⌞ m + n ⌟ % o % q ^ r≡⟨ cong! (+-comm m n) ⟩⌞ n + m ⌟ % o % q ^ r≡⟨ cong! (+-comm m n) ⟨⌞ m + n ⌟ % o % q ^ r≡⟨ cong! (+-comm m n) ⟩(n + m) % o % q ^ r≡⟨ %-congʳ eq ⟨(n + m) % o % p∎
-------------------------------------------------------------------------- The Agda standard library---- Usage examples of typeclasses for binary relations------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Relation.Binary.TypeClasses whereopen import Relation.Nullaryopen import Relation.Binary.PropositionalEqualityopen import Relation.Binary.TypeClassesopen import Data.Bool.Base renaming (_≤_ to _≤Bool)open import Data.Bool.Instancesopen import Data.List.Baseopen import Data.List.Instancesopen import Data.List.Relation.Binary.Lex.NonStrict using (Lex-≤)open import Data.Nat.Base renaming (_≤_ to _≤ℕ_)open import Data.Nat.Instancesopen import Data.Product.Base using (_×_; _,_; Σ)open import Data.Product.Instancesopen import Data.Unit.Base renaming (_≤_ to _≤⊤_)open import Data.Unit.Instancesopen import Data.Vec.Baseopen import Data.Vec.Instancestest-Dec≡-Bool : Dec (true ≡ true)test-Dec≡-Bool = true ≟ truetest-Dec≡-Nat : Dec (0 ≡ 1)test-Dec≡-Nat = 0 ≟ 1test-Dec≡-List : Dec (_≡_ {A = List ℕ} (1 ∷ 2 ∷ []) (1 ∷ 2 ∷ []))test-Dec≡-List = (1 ∷ 2 ∷ []) ≟ (1 ∷ 2 ∷ [])test-Dec≡-⊤ : Dec (tt ≡ tt)test-Dec≡-⊤ = _ ≟ _test-Dec≡-Pair : Dec (_≡_ {A = Bool × Bool} (true , false) (false , true))test-Dec≡-Pair = _ ≟ _test-Dec≡-Vec : Dec (_≡_ {A = Vec Bool 2} (true ∷ false ∷ []) (true ∷ false ∷ []))test-Dec≡-Vec = _ ≟ _test-Dec≡-Σ : Dec (_≡_ {A = Σ ℕ (Vec Bool)} (0 , []) (1 , true ∷ []))test-Dec≡-Σ = _ ≟ _test-Dec≤-Nat : Dec (0 ≤ℕ 1)test-Dec≤-Nat = 0 ≤? 1test-Dec≤-List : Dec (Lex-≤ _≡_ _≤ℕ_ (0 ∷ 1 ∷ []) (1 ∷ []))test-Dec≤-List = _ ≤? _
-------------------------------------------------------------------------- The Agda standard library---- How to use reflection to call external functions.---- IMPORTANT: In order for this file to type-check you will need to add-- a line `/usr/bin/expr` to your `~/.agda/executables` file. See the-- section on Reflection in the Agda user manual for more details.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --allow-exec #-}module README.Reflection.External whereopen import Data.List.Base using ([]; _∷_)open import Data.String.Base using (String; _++_)open import Relation.Binary.PropositionalEquality-- All the commands needed to make an external system call are included-- in `Reflection.External`.open import Reflection.Externalusing (CmdSpec; runCmd)-- The most important one is `CmdSpec` ("command specification")-- which allows ones to specify the external command being called, its-- arguments and the contents of stdin.-- Here we define a simple command spec that takes two numbers and-- uses the Unix `expr` command to add the two together.add : String → String → CmdSpecadd x y = record{ name = "expr"; args = x ∷ "+" ∷ y ∷ []; input = ""}-- The command can then be run using the `runCmd` macro. If no error-- occured then by default the macro returns the result of `stdout`.-- Otherwise the macro will terminate with a type error.test : runCmd (add "1" "2") ≡ "3\n"test = refl-- If you are running a command that you know might be ill-formed-- and result in an error then can use `unsafeRunCmd` instead that-- returns a `Result` object containing the exit code and the contents-- of both `stdout` and `stderr`.open import Reflection.Externalusing (unsafeRunCmd; result; exitFailure)error = "/usr/bin/expr: non-integer argument\n"test2 : unsafeRunCmd (add "a" "b") ≡ result (exitFailure 2) "" errortest2 = refl-- For a more advanced use-case where SMT solvers are invoked from-- Agda, see Schmitty (https://github.com/wenkokke/schmitty)
-------------------------------------------------------------------------- The Agda standard library---- Examples showing how the generic n-ary operations the stdlib provides-- can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Nary whereopen import Level using (Level)open import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Data.Fin using (Fin; fromℕ; #_; inject₁)open import Data.Listopen import Data.List.Propertiesopen import Data.Product.Base using (_×_; _,_)open import Data.Sum.Base using (inj₁; inj₂)open import Function.Base using (id; flip; _∘′_)open import Relation.Nullaryopen import Relation.Binary.Definitions using (module Tri); open Triopen import Relation.Binary.PropositionalEqualityprivatevariablea b c d e : LevelA : Set aB : Set bC : Set cD : Set dE : Set e-------------------------------------------------------------------------- Introduction-------------------------------------------------------------------------- Function.Nary.NonDependent and Data.Product.N-ary.Heterogeneous provide-- a generic representation of n-ary heterogeneous (non dependent) products-- and the corresponding types of (non-dependent) n-ary functions. The-- representation works well with inference thus allowing us to use generic-- combinators to manipulate such functions.open import Data.Product.Nary.NonDependentopen import Function.Nary.NonDependentopen import Relation.Nary-------------------------------------------------------------------------- Generalised equality-manipulating combinators-------------------------------------------------------------------------- By default the standard library provides users with (we are leaving out-- the implicit arguments here):---- cong : (f : A₁ → B) → a₁ ≡ b₁ → f a₁ ≡ f b₁-- cong₂ : (f : A₁ → A₂ → B) → a₁ ≡ b₁ → a₂ ≡ b₂ → f a₁ a₂ ≡ f b₁ b₂---- and---- subst : (P : A₁ → Set p) → a₁ ≡ b₁ → P a₁ → P b₁-- subst₂ : (P : A₁ → A₂ → Set p) → a₁ ≡ b₁ → a₂ ≡ b₂ → P a₁ a₂ → P b₁ b₂---- This pattern can be generalised to any natural number `n`. Thanks to our-- library for n-ary functions, we can write the types and implementations-- of `congₙ` and `substₙ`.-------------------------------------------------------------------------- congₙ : ∀ n (f : A₁ → ⋯ → Aₙ → B) →-- a₁ ≡ b₁ → ⋯ aₙ ≡ bₙ → f a₁ ⋯ aₙ ≡ f b₁ ⋯ bₙ-- It may be used directly to prove something:_ : ∀ (as bs cs : List ℕ) →zip (zip (as ++ []) (map id cs)) (reverse (reverse bs))≡ zip (zip as cs) bs_ = λ as bs cs → congₙ 3 (λ as bs → zip (zip as bs))(++-identityʳ as)(map-id cs)(reverse-involutive bs)-- Or as part of a longer derivation:_ : ∀ m n p q → suc (m + (p * n) + (q ^ (m + n)))≡ (m + 0) + (n * p) + (q ^ m * q ^ n) + 1_ = λ m n p q → beginsuc (m + (p * n) + (q ^ (m + n))) ≡⟨ +-comm 1 _ ⟩m + (p * n) + (q ^ (m + n)) + 1 ≡⟨ congₙ 3 (λ m n p → m + n + p + 1)(+-comm 0 m)(*-comm p n)(^-distribˡ-+-* q m n)⟩m + 0 + n * p + (q ^ m) * (q ^ n) + 1 ∎ where open ≡-Reasoning-- Partial application of the functional argument is fine: the number of arguments-- `congₙ` is going to take is determined by its first argument (a natural number)-- and not by the type of the function it works on._ : ∀ m → (m +_) ≡ ((m + 0) +_)_ = λ m → congₙ 1 _+_ (+-comm 0 m)-- We don't have to work on the function's first argument either: we can just as-- easily use `congₙ` to act on the second one by `flip`ping it. See `holeₙ` for-- a generalisation of this idea allowing to target *any* of the function's-- arguments and not just the first or second one._ : ∀ m → (_+ m) ≡ (_+ (m + 0))_ = λ m → congₙ 1 (flip _+_) (+-comm 0 m)-------------------------------------------------------------------------- substₙ : (P : A₁ → ⋯ → Aₙ → Set p) →-- a₁ ≡ b₁ → ⋯ aₙ ≡ bₙ → P a₁ ⋯ aₙ → P b₁ ⋯ bₙ-- We can play the same type of game with substopen import Agda.Builtin.Nat using (mod-helper)-- Because we know from the definition `mod-helper` that this equation holds:-- mod-helper k m (suc n) (suc j) = mod-helper (suc k) m n j-- we should be able to prove the slightly modified statement by transforming-- all the `x + 1` into `suc x`. We can do so using `substₙ`._ : ∀ k m n j → mod-helper k m (n + 1) (j + 1) ≡ mod-helper (k + 1) m n j_ = λ k m n j →let P sk sn sj = mod-helper k m sn sj ≡ mod-helper sk m n jin substₙ P (+-comm 1 k) (+-comm 1 n) (+-comm 1 j) refl------------------------------------------------------------------------- Generic programs working on n-ary products & functions------------------------------------------------------------------------------------------------------------------------------------------------ curryₙ : ∀ n → (A₁ × ⋯ × Aₙ → B) → A₁ → ⋯ → Aₙ → B-- uncurryₙ : ∀ n → (A₁ → ⋯ → Aₙ → B) → A₁ × ⋯ × Aₙ → B-- The first thing we may want to do generically is convert between-- curried function types and uncurried ones. We can do this by using:-- They both work the same way so we will focus on curryₙ only here.-- If we pass to `curryₙ` the arity of its argument then we obtain a-- fully curried function.curry₁ : (A × B × C × D → E) → A → B → C → D → Ecurry₁ = curryₙ 4-- Note that here we are not flattening arbitrary nestings: products have-- to be right nested. Which means that if you have a deeply-nested product-- then it won't be affected by the procedure.curry₁′ : (A × (B × C) × D → E) → A → (B × C) → D → Ecurry₁′ = curryₙ 3-- When we are currying a function, we have no obligation to pass its exact-- arity as the parameter: we can decide to only curry part of it like so:-- Indeed (A₁ × ⋯ × Aₙ → B) can also be seen as (A₁ × ⋯ × (Aₖ × ⋯ × Aₙ) → B)curry₂ : (A × B × C × D → E) → A → B → (C × D) → Ecurry₂ = curryₙ 3------------------------------------------------------------------------- projₙ : ∀ n (k : Fin n) → (A₁ × ⋯ × Aₙ) → Aₖ₊₁-- Another useful class of functions to manipulate n-ary product is a-- generic projection function. Note the (k + 1) in the return index:-- Fin counts from 0 up.-- It behaves as one expects (Data.Fin's #_ comes in handy to write down-- Fin literals):proj₃ : (A × B × C × D × E) → Cproj₃ = projₙ 5 (# 2)-- Of course we can once more project the "tail" of the n-ary product by-- passing `projₙ` a natural number which is smaller than the size of the-- n-ary product, seeing (A₁ × ⋯ × Aₙ) as (A₁ × ⋯ × (Aₖ × ⋯ × Aₙ)).proj₃′ : (A × B × C × D × E) → C × D × Eproj₃′ = projₙ 3 (# 2)------------------------------------------------------------------------- insertₙ : ∀ n (k : Fin (suc n)) →-- B → (A₁ × ⋯ Aₙ) → (A₁ × ⋯ × Aₖ × B × Aₖ₊₁ × ⋯ Aₙ)insert₁ : C → (A × B × D × E) → (A × B × C × D × E)insert₁ = insertₙ 4 (# 2)insert₁′ : C → (A × B × D × E) → (A × B × C × D × E)insert₁′ = insertₙ 3 (# 2)-- Note that `insertₙ` takes a `Fin (suc n)`. Indeed in an n-ary product-- there are (suc n) positions at which one may insert a value. We may-- insert at the front or the back of the product:insert-front : A → (B × C × D × E) → (A × B × C × D × E)insert-front = insertₙ 4 (# 0)insert-back : E → (A × B × C × D) → (A × B × C × D × E)insert-back = insertₙ 4 (# 4)------------------------------------------------------------------------- removeₙ : ∀ n (k : Fin n) → (A₁ × ⋯ Aₙ) → (A₁ × ⋯ × Aₖ × Aₖ₊₂ × ⋯ Aₙ)-- Dual to `insertₙ`, we may remove a value.remove₁ : (A × B × C × D × E) → (A × B × D × E)remove₁ = removeₙ 5 (# 2)-- Inserting at `k` and then removing at `inject₁ k` should yield the identityremove-insert : C → (A × B × D × E) → (A × B × D × E)remove-insert c = removeₙ 5 (inject₁ k) ∘′ insertₙ 4 k cwhere k = # 2------------------------------------------------------------------------- updateₙ : ∀ n (k : Fin n) (f : (a : Aₖ₊₁) → B a) →-- (p : A₁ × ⋯ Aₙ) → (A₁ × ⋯ × Aₖ × B (projₙ n k p) × Aₖ₊₂ × ⋯ Aₙ)-- We can not only project out, insert or remove values: we can update them-- in place. The type (and value) of the replacement at position k may depend-- upon the current value at position k.update₁ : (p : A × B × ℕ × C × D) → (A × B × Fin _ × C × D)update₁ = updateₙ 5 (# 2) fromℕ-- We can explicitly use the primed version of `updateₙ` to make it known to-- Agda that the update function is non dependent. This type of information-- is useful for inference: the tighter the constraints, the easier it is to-- find a solution (if possible).update₂ : (p : A × B × ℕ × C × D) → (A × B × List D × C × D)update₂ = λ p → updateₙ′ 5 (# 2) (λ n → replicate n (projₙ 5 (# 4) p)) p------------------------------------------------------------------------- _%=_⊢_ : ∀ n → (C → D) → (A₁ → ⋯ Aₙ → D → B) → A₁ → ⋯ → Aₙ → C → B-- Traditional composition (also known as the index update operator `_⊢_`-- in `Relation.Unary`) focuses solely on the first argument of an n-ary-- function. `_%=_⊢_` on the other hand allows us to touch any one of the-- arguments.-- In the following example we have a function `f : A → B` and `replicate`-- of type `ℕ → B → List B`. We want ̀f` to act on the second argument of-- replicate. Which we can do like so.compose₁ : (A → B) → ℕ → A → List Bcompose₁ f = 1 %= f ⊢ replicate-- Here we spell out the equivalent explicit variable-manipulation and-- prove the two functions equal.compose₁′ : (A → B) → ℕ → A → List Bcompose₁′ f n a = replicate n (f a)compose₁-eq : compose₁ {a} {A} {b} {B} ≡ compose₁′compose₁-eq = refl------------------------------------------------------------------------- _∷=_⊢_ : ∀ n → A → (A₁ → ⋯ Aₙ → A → B) → A₁ → ⋯ → Aₙ → B-- Partial application usually focuses on the first argument of a function.-- We can now partially apply a function in any of its arguments using-- `_∷=_⊢_`. Reusing our example involving replicate: we can specialise it-- to only output finite lists of `0`:apply₁ : ℕ → List ℕapply₁ = 1 ∷= 0 ⊢ replicateapply₁-eq : apply₁ 3 ≡ 0 ∷ 0 ∷ 0 ∷ []apply₁-eq = refl-------------------------------------------------------------------------- holeₙ : ∀ n → (A → (A₁ → ⋯ Aₙ → B)) → A₁ → ⋯ → Aₙ → (A → B)-- As we have seen earlier, `cong` acts on a function's first variable.-- If we want to access the second one, we can use `flip`. But what about-- the fourth one? We typically use an explicit λ-abstraction shuffling-- variables. Not anymore.-- Reusing mod-helper just because it takes a lot of arguments:hole₁ : ∀ k m n j → mod-helper k (m + 1) n j ≡ mod-helper k (suc m) n jhole₁ = λ k m n j → cong (holeₙ 2 (mod-helper k) n j) (+-comm m 1)------------------------------------------------------------------------- mapₙ : ∀ n → (B → C) → (A₁ → ⋯ Aₙ → B) → (A₁ → ⋯ → Aₙ → C)-- (R →_) gives us the reader monad (and, a fortiori, functor). That is to-- say that given a function (A → B) and an (R → A) we can get an (R → B)-- This generalises to n-ary functions.-- Reusing our `composeₙ` example: instead of applying `f` to the replicated-- element, we can map it on the resulting list. Giving us:map₁ : (A → B) → ℕ → A → List Bmap₁ f = mapₙ 2 (map f) replicate-------------------------------------------------------------------------- constₙ : ∀ n → B → A₁ → ⋯ → Aₙ → B-- `const` is basically `pure` for the reader monad discussed above. Just-- like we can generalise the functorial action corresponding to the reader-- functor to n-ary functions, we can do the same for `pure`.const₁ : A → B → C → D → E → Aconst₁ = constₙ 4-- Together with `holeₙ`, this means we can make a constant function out-- of any of the arguments. The fourth for instance:const₂ : A → B → C → D → E → Dconst₂ = holeₙ 3 (constₙ 4)-------------------------------------------------------------------------- Generalised quantifiers-------------------------------------------------------------------------- As we have seen multiple times already, one of the advantages of working-- with non-dependent products is that they can be easily inferred. This is-- a prime opportunity to define generic quantifiers.-- And because n-ary relations are Set-terminated, there is no ambiguity-- where to split between arguments & codomain. As a consequence Agda can-- infer even `n`, the number of arguments. We can use notations which are-- just like the ones defined in `Relation.Unary`.-------------------------------------------------------------------------- ∃⟨_⟩ : (A₁ → ⋯ → Aₙ → Set r) → Set _-- ∃⟨ P ⟩ = ∃ λ a₁ → ⋯ → ∃ λ aₙ → P a₁ ⋯ aₙ-- Returning to our favourite function taking a lot of arguments: we can-- find a set of input for which it evaluates to 666exist₁ : ∃⟨ (λ k m n j → mod-helper k m n j ≡ 666) ⟩exist₁ = 19 , 793 , 3059 , 10 , refl-------------------------------------------------------------------------- ∀[_] : (A₁ → ⋯ → Aₙ → Set r) → Set _-- ∀[_] P = ∀ {a₁} → ⋯ → ∀ {aₙ} → P a₁ ⋯ aₙall₁ : ∀[ (λ (a₁ a₂ : ℕ) → Dec (a₁ ≡ a₂)) ]all₁ {a₁} {a₂} = a₁ ≟ a₂-------------------------------------------------------------------------- Π : (A₁ → ⋯ → Aₙ → Set r) → Set _-- Π P = ∀ a₁ → ⋯ → ∀ aₙ → P a₁ ⋯ aₙall₂ : Π[ (λ (a₁ a₂ : ℕ) → Dec (a₁ ≡ a₂)) ]all₂ = _≟_-------------------------------------------------------------------------- _⇒_ : (A₁ → ⋯ → Aₙ → Set r) → (A₁ → ⋯ → Aₙ → Set s) → (A₁ → ⋯ → Aₙ → Set _)-- P ⇒ Q = λ a₁ → ⋯ → λ aₙ → P a₁ ⋯ aₙ → Q a₁ ⋯ aₙantisym : ∀[ _≤_ ⇒ _≥_ ⇒ _≡_ ]antisym = ≤-antisym-------------------------------------------------------------------------- _∪_ : (A₁ → ⋯ → Aₙ → Set r) → (A₁ → ⋯ → Aₙ → Set s) → (A₁ → ⋯ → Aₙ → Set _)-- P ∪ Q = λ a₁ → ⋯ → λ aₙ → P a₁ ⋯ aₙ ⊎ Q a₁ ⋯ aₙ≤->-connex : Π[ _≤_ ∪ _>_ ]≤->-connex m n with <-cmp m n... | tri< a ¬b ¬c = inj₁ (<⇒≤ a)... | tri≈ ¬a b ¬c = inj₁ (≤-reflexive b)... | tri> ¬a ¬b c = inj₂ c-------------------------------------------------------------------------- _∩_ : (A₁ → ⋯ → Aₙ → Set r) → (A₁ → ⋯ → Aₙ → Set s) → (A₁ → ⋯ → Aₙ → Set _)-- P ∩ Q = λ a₁ → ⋯ → λ aₙ → P a₁ ⋯ aₙ × Q a₁ ⋯ aₙ<-inversion : ∀[ _<_ ⇒ _≤_ ∩ _≢_ ]<-inversion m<n = <⇒≤ m<n , <⇒≢ m<n-------------------------------------------------------------------------- ∁ : (A₁ → ⋯ → Aₙ → Set r) → (A₁ → ⋯ → Aₙ → Set _)-- ∁ P = λ a₁ → ⋯ → λ aₙ → ¬ (P a₁ ⋯ aₙ)m<n⇒m≱n : ∀[ _>_ ⇒ ∁ _≤_ ]m<n⇒m≱n m>n m≤n = <⇒≱ m>n m≤n
-------------------------------------------------------------------------- The Agda standard library---- Explaining how to use the inspect idiom and elaborating on the way-- it is implemented in the standard library.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Inspect whereopen import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Data.Product.Base using (_×_; _,_)open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)open import Relation.Binary.PropositionalEquality using (inspect; [_])-------------------------------------------------------------------------- Using inspect-- We start with the definition of a (silly) predicate: `Plus m n p` states-- that `m + n` is equal to `p` in a rather convoluted way. Crucially, it-- distinguishes two cases: whether `p` is 0 or not.Plus-eq : (m n p : ℕ) → SetPlus-eq m n zero = m ≡ 0 × n ≡ 0Plus-eq m n p@(suc _) = m + n ≡ p-- A sensible lemma to prove of this predicate is that whenever `p` is literally-- `m + n` then `Plus m n p` holds. That is to say `∀ m n → Plus m n (m + n)`.-- To be able to prove `Plus-eq m n (m + n)`, we need `m + n` to have either-- the shape `zero` or `suc _` so that `Plus-eq` may reduce.-- We could follow the way `_+_` computes by mimicking the same splitting-- strategy, thus forcing `m + n` to reduce:plus-eq-+ : ∀ m n → Plus-eq m n (m + n)plus-eq-+ zero zero = refl , reflplus-eq-+ zero (suc n) = reflplus-eq-+ (suc m) n = refl-- Or we could attempt to compute `m + n` first and check whether the result-- is `zero` or `suc p`. By using `with m + n` and naming the result `p`,-- the goal will become `Plus-eq m n p`. We can further refine this definition-- by distinguishing two cases like so:-- plus-eq-with : ∀ m n → Plus-eq m n (m + n)-- plus-eq-with m n with m + n-- ... | zero = {!!}-- ... | suc p = {!!}-- The problem however is that we have abolutely lost the connection between the-- computation `m + n` and its result `p`. Which makes the two goals unprovable:-- 1. `m ≡ 0 × n ≡ 0`, with no assumption whatsoever-- 2. `m + n ≡ suc p`, with no assumption either-- By using the `with` construct, we have generated an auxiliary function that-- looks like this:-- `plus-eq-with-aux : ∀ m n p → Plus-eq m n p`-- when we would have wanted a more precise type of the form:-- `plus-eq-aux : ∀ m n p → m + n ≡ p → Plus-eq m n p`.-- This is where we can use `inspect`. By using `with f x | inspect f x`,-- we get both a `y` which is the result of `f x` and a proof that `f x ≡ y`.-- Splitting on the result of `m + n`, we get two cases:-- 1. `m ≡ 0 × n ≡ 0` under the assumption that `m + n ≡ zero`-- 2. `m + n ≡ suc p` under the assumption that `m + n ≡ suc p`-- The first one can be discharged using lemmas from Data.Nat.Properties and-- the second one is trivial.plus-eq-with : ∀ m n → Plus-eq m n (m + n)plus-eq-with m n with m + n | inspect (m +_) n... | zero | [ m+n≡0 ] = m+n≡0⇒m≡0 m m+n≡0 , m+n≡0⇒n≡0 m m+n≡0... | suc p | [ m+n≡1+p ] = m+n≡1+p-------------------------------------------------------------------------- Understanding the implementation of inspect-- So why is it that we have to go through the record type `Reveal_·_is_`-- and the ̀inspect` function? The fact is: we don't have to if we write-- our own auxiliary lemma:plus-eq-aux : ∀ m n → Plus-eq m n (m + n)plus-eq-aux m n = aux m n (m + n) refl whereaux : ∀ m n p → m + n ≡ p → Plus-eq m n paux m n zero m+n≡0 = m+n≡0⇒m≡0 m m+n≡0 , m+n≡0⇒n≡0 m m+n≡0aux m n (suc p) m+n≡1+p = m+n≡1+p-- The problem is that when we write ̀with f x | pr`, `with` decides to call `y`-- the result `f x` and to replace *all* of the occurences of `f x` in the type-- of `pr` with `y`. That is to say that if we were to write:-- plus-eq-naïve : ∀ m n → Plus-eq m n (m + n)-- plus-eq-naïve m n with m + n | refl {x = m + n}-- ... | p | eq = {!!}-- then `with` would abstract `m + n` as `p` on *both* sides of the equality-- proven by `refl` thus giving us the following goal with an extra, useless,-- assumption:-- 1. `Plus-eq m n p` under the assumption that `p ≡ p`-- So how does `inspect` work? The standard library uses a more general version-- of the following type and function:record MyReveal_·_is_ (f : ℕ → ℕ) (x y : ℕ) : Set whereconstructor [_]field eq : f x ≡ ymy-inspect : ∀ f n → MyReveal f · n is (f n)my-inspect f n = [ refl ]-- Given that `inspect` has the type `∀ f n → Reveal f · n is (f n)`, when we-- write `with f n | inspect f n`, the only `f n` that can be abstracted in the-- type of `inspect f n` is the third argument to `Reveal_·_is_`.-- That is to say that the auxiliary definition generated looks like this:plus-eq-reveal : ∀ m n → Plus-eq m n (m + n)plus-eq-reveal m n = aux m n (m + n) (my-inspect (m +_) n) whereaux : ∀ m n p → MyReveal (m +_) · n is p → Plus-eq m n paux m n zero [ m+n≡0 ] = m+n≡0⇒m≡0 m m+n≡0 , m+n≡0⇒n≡0 m m+n≡0aux m n (suc p) [ m+n≡1+p ] = m+n≡1+p-- At the cost of having to unwrap the constructor `[_]` around the equality-- we care about, we can keep relying on `with` and avoid having to roll out-- handwritten auxiliary definitions.
-------------------------------------------------------------------------- The Agda standard library---- Simple examples of programs using IO------------------------------------------------------------------------{-# OPTIONS --guardedness #-}module README.IO whereopen import Levelopen import Data.Nat.Baseopen import Data.Nat.Show using (show)open import Data.String.Base using (String; _++_; lines)open import Data.Unit.Polymorphicopen import Function.Base using (_$_)open import IO-------------------------------------------------------------------------- Basic programs-------------------------------------------------------------------------------------------------------------------------------------------------- Hello World!-- Minimal example of an IO program.-- * The entrypoint of the executable is given type `Main`-- * It is implemented using `run`, a function that converts a description-- of an IO-computation into a computation that actually invokes the magic-- primitives that will perform the side effects.helloWorld : MainhelloWorld = run (putStrLn "Hello World!")-------------------------------------------------------------------------- Hello {{name}}!-- We can of course write little auxiliary functions that may be used in-- larger IO programs. Here we are going to first write a function displaying-- "Hello {{name}}!" when {{name}} is passed as an argument.-- `IO` primitives whose sole purpose is generating side effects (e.g.-- printing a string on the screen) are typically given a level polymorphic-- type which means we may need to add explicit level annotations.-- Here we state that the `IO` computation will be at level zero (`0ℓ`).sayHello : String → IO {0ℓ} ⊤sayHello name = putStrLn ("Hello " ++ name ++ "!")-- Functions can be sequenced using monadic combinators or `do` notations.-- The two following definitions are equivalent. They start by asking the-- user what their name is, listen for an answer and respond by saying hello-- using the `sayHello` auxiliary function we just defined.helloName : MainhelloName = run (putStrLn "What is your name?" >> getLine >>= sayHello)doHelloName : MaindoHelloName = run doputStrLn "What is your name?"name ← getLinesayHello name-------------------------------------------------------------------------- (Co)Recursive programs-------------------------------------------------------------------------------------------------------------------------------------------------- NO GUARDEDNESS-- If you do not need to rely on guardedness for the function to be seen as-- terminating (for instance because it is structural in an inductive argument)-- then you can use `do` notations to write fairly readable programs.-- Countdown to explosioncountdown : ℕ → IO {0ℓ} _countdown zero = putStrLn "BOOM!"countdown m@(suc n) = dolet str = show mputStrLn strcountdown n-- cat the content of a finite filecat : String → IO _cat fp = docontent ← readFiniteFile fplet ls = lines contentList.mapM′ putStrLn ls-------------------------------------------------------------------------- TOP-LEVEL LOOP-- If you simply want to repeat the same action over and over again, you-- can use `forever` e.g. the following defines a REPL that echos whatever-- the user typesecho : IO ⊤echo = dohSetBuffering stdout noBufferingforever $ doputStr "echo< "str ← getLineputStrLn ("echo> " ++ str)-------------------------------------------------------------------------- GUARDEDNESS-- If you are performing coinduction on a potentially infinite piece of codata-- then you need to rely on guardedness. That is to say that the coinductive-- call needs to be obviously under a coinductive constructor and guarded by a-- sharp (♯_).-- In this case you cannot use the convenient combinators that make `do`-notations-- and have to revert back to the underlying coinductive constructors.open import Codata.Musical.Notationopen import Codata.Musical.Colist using (Colist; []; _∷_)open import Data.Boolopen import Data.Unit.Polymorphic.Base-- Whether a colist is finite is semi decidable: just let the user wait until-- you reach the end!isFinite : ∀ {a} {A : Set a} → Colist A → IO BoolisFinite [] = pure trueisFinite (x ∷ xs) = seq (♯ pure tt) (♯ isFinite (♭ xs))
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing how the Function.Reasoning module can be used-- to perform "functional reasoning" similar to what is being described-- in: https://stackoverflow.com/q/22676703/3168666------------------------------------------------------------------------{-# OPTIONS --with-K #-}module README.Function.Reasoning where-- Function.Reasoning exports a flipped application (_|>_) combinator-- as well as a type annotation (_∶_) combinator.open import Function.Reasoning-------------------------------------------------------------------------- A simple examplemodule _ {A B C : Set} {A→B : A → B} {B→C : B → C} where-- Using the combinators we can, starting from a value, chain various-- functions whilst tracking the types of the intermediate results.A→C : A → CA→C a =a ∶ A|> A→B ∶ B|> B→C ∶ C-------------------------------------------------------------------------- A more concrete exampleopen import Data.Natopen import Data.List.Baseopen import Data.Char.Baseopen import Data.String.Base as String using (String; toList; fromList)open import Data.String.Properties as String using (_==_)open import Function.Base using (_∘_)open import Data.Bool hiding (_≤?_)open import Data.Product.Base using (_×_; <_,_>; uncurry; proj₁)open import Agda.Builtin.Equality-- This can give us for instance this decomposition of a function-- collecting all of the substrings of the input which happen to be-- palindromes:subpalindromes : String → List Stringsubpalindromes str = let Chars = List Char instr ∶ String-- first generate the substrings|> toList ∶ Chars|> inits ∶ List Chars|> concatMap tails ∶ List Chars-- then only keeps the ones which are not singletons|> filter (λ cs → 2 ≤? length cs) ∶ List Chars-- only keep the ones that are palindromes|> map < fromList , fromList ∘ reverse > ∶ List (String × String)|> filter (uncurry String._≟_) ∶ List (String × String)|> map proj₁ ∶ List String-- Test cases_ : subpalindromes "doctoresreverse" ≡ "eve" ∷ "rever" ∷ "srevers" ∷ "esreverse" ∷ []_ = refl_ : subpalindromes "elle-meme" ≡ "ll" ∷ "elle" ∷ "mem" ∷ "eme" ∷ []_ = refl
-------------------------------------------------------------------------- The Agda standard library---- A simple example of a program using the foreign function interface------------------------------------------------------------------------{-# OPTIONS --guardedness #-}module README.Foreign.Haskell where-- In order to be considered safe by Agda, the standard library cannot-- add COMPILE pragmas binding the inductive types it defines to concrete-- Haskell types.-- To work around this limitation, we have defined FFI-friendly versions-- of these types together with a zero-cost coercion `coerce`.open import Level using (Level)open import Agda.Builtin.Intopen import Agda.Builtin.Natopen import Data.Bool.Base using (Bool; if_then_else_)open import Data.Char as Charopen import Data.List.Base as List using (List; _∷_; []; takeWhile; dropWhile)open import Data.Maybe.Base using (Maybe; just; nothing)open import Data.Product.Base using (_×_; _,_)open import Functionopen import Relation.Nullary.Decidableimport Foreign.Haskell as FFIopen import Foreign.Haskell.Coerceprivatevariablea : LevelA : Set a-- Here we use the FFI version of Pair.postulateprimUncons : List A → Maybe (FFI.Pair A (List A))primCatMaybes : List (Maybe A) → List AprimTestChar : Char → BoolprimIntEq : Int → Int → Bool{-# COMPILE GHC primUncons = \ _ _ xs -> case xs of{ [] -> Nothing; (x : xs) -> Just (x, xs)}#-}{-# FOREIGN GHC import Data.Maybe #-}{-# COMPILE GHC primCatMaybes = \ _ _ -> catMaybes #-}{-# COMPILE GHC primTestChar = ('-' /=) #-}{-# COMPILE GHC primIntEq = (==) #-}-- We however want to use the notion of Pair internal to the standard library.-- For this we use `coerce` to take use back to the types we are used to.-- The typeclass mechanism uses the coercion rules for Pair, as well as the-- knowledge that natural numbers are represented as integers.-- We additionally benefit from the congruence rules for List, Maybe, Char,-- Bool, and a reflexivity principle for variable A.uncons : List A → Maybe (A × List A)uncons = coerce primUnconscatMaybes : List (Maybe A) → List AcatMaybes = primCatMaybestestChar : Char → BooltestChar = coerce primTestChar-- note that coerce is useless here but the proof could come from-- either `coerce-fun coerce-refl coerce-refl` or `coerce-refl` alone-- We (and Agda) do not care which proof we got.eqNat : Nat → Nat → BooleqNat = coerce primIntEq-- We can coerce `Nat` to `Int` but not `Int` to `Nat`. This fundamentally-- relies on the fact that `Coercible` understands that functions are-- contravariant.open import IOopen import Codata.Musical.Notationopen import Data.String.Base using (toList; fromList; unlines; _++_)open import Relation.Nullary.Negation-- example program using uncons, catMaybes, and testCharmain = run $ docontent ← readFiniteFile "README/Foreign/Haskell.agda"let chars = toList contentlet cleanup = catMaybes ∘ List.map (λ c → if testChar c then just c else nothing)let cleaned = dropWhile ('\n' ≟_) $ cleanup charscase uncons cleaned of λ wherenothing → putStrLn "I cannot believe this file is filed with dashes only!"(just (c , cs)) → putStrLn $ unlines$ ("First (non dash) character: " ++ Char.show c)∷ ("Rest (dash free) of the line: " ++ fromList (takeWhile (¬? ∘ ('\n' ≟_)) cs))∷ []-- You can compile and run this test by writing:-- agda -c Haskell.agda-- ../../Haskell-- You should see the following text (without the indentation on the left):-- First (non dash) character: ' '-- Rest (dash free) of the line: The Agda standard library
------------------------------------------------------------------------- The Agda standard library---- Example showing the use of the partiality Monad------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe --guardedness #-}module README.Effect.Monad.Partiality whereopen import Codata.Musical.Notation using (♯_)open import Data.Bool.Base using (false; true)open import Data.Nat using (ℕ; _+_; _∸_; _≤?_)open import Effect.Monad.Partialityopen import Relation.Nullary.Decidable using (does)open Workaround-- McCarthy's f91:f91′ : ℕ → ℕ ⊥Pf91′ n with does (n ≤? 100)... | true = later (♯ (f91′ (11 + n) >>= f91′))... | false = now (n ∸ 10)f91 : ℕ → ℕ ⊥f91 n = ⟦ f91′ n ⟧P
* Level polymorphism`⊥` in `Data.Empty` and `⊤` in `Data.Unit` are not `Level`-polymorphic as thattends to lead to unsolved metas (see discussion at issue #312). This is understandableas very often the level of (say) `⊤` is under-determined by its surrounding context,leading to unsolved metas. This is frequent enough that it makes sense for the defaultversions to be monomorphic (at Level 0).But there are other cases where exactly the opposite is needed. for that purpose,there are level-polymorphic versions in `Data.Empty.Polymorphic` and`Data.Unit.Polymorphic` respectively.The same issue happens in `Relation.Unary` which defines `Ø` and `U` at `Level` 0, elsea lot of unsolved metas appear (for example in `Relation.Unary.Properties`). For thatpurpose, `Relation.Unary.Polymorphic` exists.
-------------------------------------------------------------------------- The Agda standard library---- An explanation about how mathematical hierarchies are laid out.------------------------------------------------------------------------{-# OPTIONS --allow-unsolved-metas #-}module README.Design.Hierarchies whereopen import Data.Sum.Base using (_⊎_)open import Level using (Level; _⊔_; suc)open import Relation.Binary.Core using (_Preserves₂_⟶_⟶_)privatevariablea b ℓ : LevelA : Set a-------------------------------------------------------------------------- Introduction-------------------------------------------------------------------------- One of the key design decisions facing the library is how to handle-- mathematical hierarchies, e.g.-- ∙ Binary relations: preorder → partial order → total order-- ↘ equivalence-- ∙ Algebraic structures: magma → semigroup → monoid → group-- ↘ band → semilattice---- Some of the hierarchies in the library are:-- ∙ Algebra-- ∙ Function-- ∙ Relation.Binary-- ∙ Relation.Binary.Indexed---- A given hierarchy `X` is always split into 4 seperate folders:-- ∙ X.Core-- ∙ X.Definitions-- ∙ X.Structures-- ∙ X.Bundles-- all four of which are publicly re-exported by `X` itself.---- Additionally a hierarchy `X` may contain additional files-- ∙ X.Bundles.Raw-- ∙ X.Consequences-- ∙ X.Constructs-- ∙ X.Properties-- ∙ X.Morphisms---- Descriptions of these modules are now described below using the-- running example of the `Relation.Binary` and `Algebra` hierarchies.-- Note that we redefine everything here for illustrative purposes,-- and that the definitions given below may be slightly simpler-- than the real definitions in order to focus on the points being-- discussed.-------------------------------------------------------------------------- Main hierarchy modules-------------------------------------------------------------------------------------------------------------------------------------------------- X.Core-- The Core module contains the basic units of the hierarchy.-- For example for binary relations these are homoegeneous and-- heterogeneous binary relations:REL : Set a → Set b → (ℓ : Level) → Set (a ⊔ b ⊔ suc ℓ)REL A B ℓ = A → B → Set ℓRel : Set a → (ℓ : Level) → Set (a ⊔ suc ℓ)Rel A ℓ = A → A → Set ℓ-- and in Algebra these are unary and binary operators, e.g.Op₁ : Set a → Set aOp₁ A = A → AOp₂ : Set a → Set aOp₂ A = A → A → A-------------------------------------------------------------------------- X.Definitions-- The Definitions module defines the various properties that the-- basic units of the hierarchy may have.-- For example in Relation.Binary this includes reflexivity,-- transitivity etc.Reflexive : Rel A ℓ → Set _Reflexive _∼_ = ∀ {x} → x ∼ xSymmetric : Rel A ℓ → Set _Symmetric _∼_ = ∀ {x y} → x ∼ y → y ∼ xTransitive : Rel A ℓ → Set _Transitive _∼_ = ∀ {x y z} → x ∼ y → y ∼ z → x ∼ zTotal : Rel A ℓ → Set _Total _∼_ = ∀ x y → x ∼ y ⊎ y ∼ x-- For example in Algebra these are associativity, commutativity.-- Note that all definitions for Algebra are based on some notion of-- underlying equality.Associative : Rel A ℓ → Op₂ A → Set _Associative _≈_ _∙_ = ∀ x y z → ((x ∙ y) ∙ z) ≈ (x ∙ (y ∙ z))Commutative : Rel A ℓ → Op₂ A → Set _Commutative _≈_ _∙_ = ∀ x y → (x ∙ y) ≈ (y ∙ x)LeftIdentity : Rel A ℓ → A → Op₂ A → Set _LeftIdentity _≈_ e _∙_ = ∀ x → (e ∙ x) ≈ xRightIdentity : Rel A ℓ → A → Op₂ A → Set _RightIdentity _≈_ e _∙_ = ∀ x → (x ∙ e) ≈ x-- Note that the types in `Definitions` modules are not meant to express-- the full concept on their own. For example the `Associative` type does-- not require the underlying relation to be an equivalence relation.-- Instead they are designed to aid the modular reuse of the core-- concepts. The complete concepts are captured in various-- structures/bundles where the definitions are correctly used in-- context.-------------------------------------------------------------------------- X.Structures-- When an abstract hierarchy of some sort (for instance semigroup →-- monoid → group) is included in the library the basic approach is to-- specify the properties of every concept in terms of a record-- containing just properties, parameterised on the underlying-- sets, relations and operations. For example:record IsEquivalence {A : Set a}(_≈_ : Rel A ℓ): Set (a ⊔ ℓ)wherefieldrefl : Reflexive _≈_sym : Symmetric _≈_trans : Transitive _≈_-- More specific concepts are then specified in terms of the simpler-- ones:record IsMagma {A : Set a} (≈ : Rel A ℓ) (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisEquivalence : IsEquivalence ≈∙-cong : ∙ Preserves₂ ≈ ⟶ ≈ ⟶ ≈record IsSemigroup {A : Set a} (≈ : Rel A ℓ) (∙ : Op₂ A) : Set (a ⊔ ℓ) wherefieldisMagma : IsMagma ≈ ∙associative : Associative ≈ ∙open IsMagma isMagma public-- Note here that `open IsMagma isMagma public` ensures that the-- fields of the `isMagma` record can be accessed directly; this-- technique enables the user of an `IsSemigroup` record to use underlying-- records without having to manually open an entire record hierarchy.-- This is not always possible, though. Consider the following definition-- of preorders:record IsPreorder {A : Set a}(_≈_ : Rel A ℓ) -- The underlying equality.(_∼_ : Rel A ℓ) -- The relation.: Set (a ⊔ ℓ) wherefieldisEquivalence : IsEquivalence _≈_refl : Reflexive _∼_trans : Transitive _∼_module Eq = IsEquivalence isEquivalence-- The IsEquivalence field in IsPreorder is not opened publicly because-- the `refl` and `trans` fields would clash with those in the-- `IsPreorder` record. Instead we provide an internal module and the-- equality fields can be accessed via `Eq.refl` and `Eq.trans`.-------------------------------------------------------------------------- X.Bundles-- Although structures are useful for describing the properties of a-- given set of operations/relations, sometimes you don't require the-- properties to hold for a given set of objects but only that such a-- set of objects exists. In this case bundles are what you're after.-- Each structure has a corresponding bundle that include the structure-- along with the corresponding sets, relations and operations as-- fields.record Setoid c ℓ : Set (suc (c ⊔ ℓ)) wherefieldCarrier : Set c_≈_ : Rel Carrier ℓisEquivalence : IsEquivalence _≈_open IsEquivalence isEquivalence public-- The contents of the structure is always re-exported publicly,-- providing access to its fields.record Magma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisMagma : IsMagma _≈_ _∙_open IsMagma isMagma publicrecord Semigroup : Set (suc (a ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set a_≈_ : Rel Carrier ℓ_∙_ : Op₂ CarrierisSemigroup : IsSemigroup _≈_ _∙_open IsSemigroup isSemigroup publicmagma : Magma a ℓmagma = record { isMagma = isMagma }-- Note that the Semigroup record does not include a Magma field.-- Instead the Semigroup record includes a "repackaging function"-- semigroup which converts a Magma to a Semigroup.-- The above setup may seem a bit complicated, but it has been arrived-- at after a lot of thought and is designed to both make the hierarchies-- easy to work with whilst also providing enough flexibility for the-- different applications of their concepts.-- NOTE: bundles for the function hierarchy are designed a little-- differently, as a function with an unknown domain an codomain is-- of little use.--------------------------- Bundle re-exporting ----------------------------- In general ensuring that bundles re-export everything in their-- sub-bundles can get a little tricky.-- Imagine we have the following general scenario where bundle A is a-- direct refinement of bundle C (i.e. the record `IsA` has a `IsC` field)-- but is also morally a refinement of bundles B and D.-- Structures Bundles-- ========== =======-- IsA A-- / || \ / || \-- IsB IsC IsD B C D-- The procedure for re-exports in the bundles is as follows:-- 1. `open IsA isA public using (IsC, M)` where `M` is everything-- exported by `IsA` that is not exported by `IsC`.-- 2. Construct `c : C` via the `isC` obtained in step 1.-- 3. `open C c public hiding (N)` where `N` is the list of fields-- shared by both `A` and `C`.-- 4. Construct `b : B` via the `isB` obtained in step 1.-- 5. `open B b public using (O)` where `O` is everything exported-- by `B` but not exported by `IsA`.-- 6. Construct `d : D` via the `isC` obtained in step 1.-- 7. `open D d public using (P)` where `P` is everything exported-- by `D` but not exported by `IsA`-------------------------------------------------------------------------- Other hierarchy modules-------------------------------------------------------------------------------------------------------------------------------------------------- X.Bundles.Raw-- Sometimes it is useful to have the bundles without any accompanying-- laws. These correspond more or less to what the definitions would-- be in non-dependently typed languages like Haskell.-- Each bundle thereofre has a corresponding raw bundle that only-- include the laws but not the operations.record RawMagma c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierrecord RawMonoid c ℓ : Set (suc (c ⊔ ℓ)) whereinfixl 7 _∙_infix 4 _≈_fieldCarrier : Set c_≈_ : Rel Carrier ℓ_∙_ : Op₂ Carrierε : Carrier-------------------------------------------------------------------------- X.Consequences-- The "consequences" modules contains proofs for how the different-- types in the `Definitions` module relate to each other. For example:-- that any total relation is reflexive or that commutativity allows-- one to translate between left and right identities.total⇒refl : ∀ {_∼_ : Rel A ℓ} → Total _∼_ → Reflexive _∼_total⇒refl = {!!}idˡ+comm⇒idʳ : ∀ {_≈_ : Rel A ℓ} {e _∙_} → Commutative _≈_ _∙_ →LeftIdentity _≈_ e _∙_ → RightIdentity _≈_ e _∙_idˡ+comm⇒idʳ = {!!}-------------------------------------------------------------------------- X.Construct-- The "construct" folder contains various generic ways of constructing-- new instances of the hierarchy. For exampleimport Relation.Binary.Construct.Intersection-- takes in two relations and forms the new relation that says two-- elements are only related if they are related via both of the-- original relations.-- These files are layed out in four parts, mimicking the main modules-- of the hierarchy itself. First they define the new relation, then-- subsequently how the definitions, then structures and finally-- bundles can be translated across to it.-------------------------------------------------------------------------- X.Morphisms-- The `Morphisms` folder is a sub-hierarchy containing relationships-- such homomorphisms, monomorphisms and isomorphisms between the-- structures and bundles in the hierarchy.-------------------------------------------------------------------------- X.Properties-- The `Properties` folder contains additional proofs about the theory-- of each bundle. They are usually designed so as a bundle's-- `Properties` file re-exports the contents of the `Properties` files-- above it in the hierarchy. For example-- `Algebra.Properties.AbelianGroup` re-exports the contents of-- `Algebra.Properties.Group`.
-------------------------------------------------------------------------- The Agda standard library---- Documentation describing some of the fixity choices------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}-- There is no actual code in here, just design note.module README.Design.Fixity where-- binary relations of all kinds are infix 4-- multiplication-like: infixl 7 _*_-- addition-like infixl 6 _+_-- negation-like infix 8 ¬_-- and-like infixr 7 _∧_-- or-like infixr 6 _∨_-- post-fix inverse infix 8 _⁻¹-- bind infixl 1 _>>=_-- list concat-like infixr 5 _∷_-- ternary reasoning infix 1 _⊢_≈_-- composition infixr 9 _∘_-- application infixr -1 _$_ _$!_-- combinatorics infixl 6.5 _P_ _P′_ _C_ _C′_-- pair infixr 4 _,_-- Reasoning:-- QED infix 3 _∎-- stepping infixr 2 _≡⟨⟩_ step-≡ step-≡˘-- begin infix 1 begin_-- type formers:-- product-like infixr 2 _×_ _-×-_ _-,-_-- sum-like infixr 1 _⊎_-- binary properties infix 4 _Absorbs_
-------------------------------------------------------------------------- The Agda standard library---- Examples of decision procedures and how to use them------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Design.Decidability whereopen import Data.Boolopen import Data.List.Base using (List; []; _∷_)open import Data.List.Properties using (∷-injective)open import Data.Natopen import Data.Nat.Properties using (suc-injective)open import Data.Product.Base using (uncurry)open import Data.Unitopen import Function.Base using (id; _∘_)open import Relation.Binary.PropositionalEqualityopen import Relation.Nary-------------------------------------------------------------------------- Reflectsopen import Relation.Nullary.Reflectsinfix 4 _≟₀_ _≟₁_ _≟₂_-- A proof of `Reflects P b` shows that a proposition `P` has the truth value of-- the boolean `b`. A proof of `Reflects P true` amounts to a proof of `P`, and-- a proof of `Reflects P false` amounts to a refutation of `P`.ex₀ : (n : ℕ) → Reflects (n ≡ n) trueex₀ n = ofʸ reflex₁ : (n : ℕ) → Reflects (zero ≡ suc n) falseex₁ n = ofⁿ λ ()ex₂ : (b : Bool) → Reflects (T b) bex₂ false = ofⁿ idex₂ true = ofʸ tt-------------------------------------------------------------------------- Decopen import Relation.Nullary.Decidable-- A proof of `Dec P` is a proof of `Reflects P b` for some `b`.-- `Dec P` is declared as a record, with fields:-- does : Bool-- proof : Reflects P doesex₃ : (b : Bool) → Dec (T b)does (ex₃ b) = bproof (ex₃ b) = ex₂ b-- We also have pattern synonyms `yes` and `no`, allowing both fields to be-- given at once.ex₄ : (n : ℕ) → Dec (zero ≡ suc n)ex₄ n = no λ ()-- It is possible, but not ideal, to define recursive decision procedures using-- only the `yes` and `no` patterns. The following procedure decides whether two-- given natural numbers are equal._≟₀_ : (m n : ℕ) → Dec (m ≡ n)zero ≟₀ zero = yes reflzero ≟₀ suc n = no λ ()suc m ≟₀ zero = no λ ()suc m ≟₀ suc n with m ≟₀ n... | yes p = yes (cong suc p)... | no ¬p = no (¬p ∘ suc-injective)-- In this case, we can see that `does (suc m ≟ suc n)` should be equal to-- `does (m ≟ n)`, because a `yes` from `m ≟ n` gives rise to a `yes` from the-- result, and similarly for `no`. However, in the above definition, this-- equality does not hold definitionally, because we always do a case split-- before returning a result. To avoid this, we can return the `does` part-- separately, before any pattern matching._≟₁_ : (m n : ℕ) → Dec (m ≡ n)zero ≟₁ zero = yes reflzero ≟₁ suc n = no λ ()suc m ≟₁ zero = no λ ()does (suc m ≟₁ suc n) = does (m ≟₁ n)proof (suc m ≟₁ suc n) with m ≟₁ n... | yes p = ofʸ (cong suc p)... | no ¬p = ofⁿ (¬p ∘ suc-injective)-- We now get definitional equalities such as the following._ : (m n : ℕ) → does (5 + m ≟₁ 3 + n) ≡ does (2 + m ≟₁ n)_ = λ m n → refl-- Even better, from a maintainability point of view, is to use `map` or `map′`,-- both of which capture the pattern of the `does` field remaining the same, but-- the `proof` field being updated._≟₂_ : (m n : ℕ) → Dec (m ≡ n)zero ≟₂ zero = yes reflzero ≟₂ suc n = no λ ()suc m ≟₂ zero = no λ ()suc m ≟₂ suc n = map′ (cong suc) suc-injective (m ≟₂ n)_ : (m n : ℕ) → does (5 + m ≟₂ 3 + n) ≡ does (2 + m ≟₂ n)_ = λ m n → refl-- `map′` can be used in conjunction with combinators such as `_⊎-dec_` and-- `_×-dec_` to build complex (simply typed) decision procedures.module ListDecEq₀ {a} {A : Set a} (_≟ᴬ_ : (x y : A) → Dec (x ≡ y)) where_≟ᴸᴬ_ : (xs ys : List A) → Dec (xs ≡ ys)[] ≟ᴸᴬ [] = yes refl[] ≟ᴸᴬ (y ∷ ys) = no λ ()(x ∷ xs) ≟ᴸᴬ [] = no λ ()(x ∷ xs) ≟ᴸᴬ (y ∷ ys) =map′ (uncurry (cong₂ _∷_)) ∷-injective (x ≟ᴬ y ×-dec xs ≟ᴸᴬ ys)-- The final case says that `x ∷ xs ≡ y ∷ ys` exactly when `x ≡ y` *and*-- `xs ≡ ys`. The proofs are updated by the first two arguments to `map′`.-- In the case of ≡-equality tests, the pattern-- `map′ (congₙ c) c-injective (x₀ ≟ y₀ ×-dec ... ×-dec xₙ₋₁ ≟ yₙ₋₁)`-- is captured by `≟-mapₙ n c c-injective (x₀ ≟ y₀) ... (xₙ₋₁ ≟ yₙ₋₁)`.module ListDecEq₁ {a} {A : Set a} (_≟ᴬ_ : (x y : A) → Dec (x ≡ y)) where_≟ᴸᴬ_ : (xs ys : List A) → Dec (xs ≡ ys)[] ≟ᴸᴬ [] = yes refl[] ≟ᴸᴬ (y ∷ ys) = no λ ()(x ∷ xs) ≟ᴸᴬ [] = no λ ()(x ∷ xs) ≟ᴸᴬ (y ∷ ys) = ≟-mapₙ 2 _∷_ ∷-injective (x ≟ᴬ y) (xs ≟ᴸᴬ ys)
-------------------------------------------------------------------------- The Agda standard library---- An example showing how the Debug.Trace module can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --rewriting --guardedness #-}module README.Debug.Trace where-------------------------------------------------------------------------- Sometimes compiled code can contain bugs.-- Whether caused by the compiler or present in the source code already, they-- can be hard to track. A primitive debugging technique is to strategically-- insert calls to tracing functions which will display their String argument-- upon evaluation.open import Data.String.Base using (_++_)open import Debug.Trace-- We can for instance add tracing messages to make sure an invariant is-- respected or check in which order evaluation takes place in the backend-- (which can inform our decision to use, or not, strictness primitives).-- In the following example, we define a division operation on natural numbers-- using the original dividend as the termination measure. We:-- 1. check in the base case that when the fuel runs out then the updated dividend-- is already zero.-- 2. wrap the calls to _∸_ and go in respective calls to trace to see when all-- of these thunks are forced: are we building a big thunk in go's second-- argument or evaluating it as we go?open import Data.Maybe.Baseopen import Data.Nat.Baseopen import Data.Nat.Show using (show)div : ℕ → ℕ → Maybe ℕdiv m zero = nothingdiv m n = just (go m m) where-- invariants: m ≤ fuel-- result : m / ngo : (fuel : ℕ) (m : ℕ) → ℕgo zero m = trace ("Invariant: " ++ show m ++ " should be zero.") zerogo (suc fuel) m =let m′ = trace ("Thunk for step " ++ show fuel ++ " forced") (m ∸ n) intrace ("Recursive call for step " ++ show fuel) (suc (go fuel m′))-- To observe the behaviour of this code, we need to compile it and run it.-- To run it, we need a main function. We define a very basic one: run div,-- and display its result if the run was successful.-- We add two calls to trace to see when div is evaluated and when the returned-- number is forced (by a call to show).open import Level using (0ℓ)open import IOmain : Mainmain =let r = trace "Call to div" (div 4 2)j = λ n → trace "Forcing the result wrapped in just." (putStrLn (show n)) inrun (maybe′ j (pure _) r)-- We get the following trace where we can see that checking that the-- maybe-solution is just-headed does not force the natural number. Once forced,-- we observe that we indeed build a big thunk on go's second argument (all the-- recursive calls happen first and then we force the thunks one by one).-- Call to div-- Forcing the result wrapped in just.-- Recursive call for step 3-- Recursive call for step 2-- Recursive call for step 1-- Recursive call for step 0-- Thunk for step 0 forced-- Thunk for step 1 forced-- Thunk for step 2 forced-- Thunk for step 3 forced-- Invariant: 0 should be zero.-- 4-- We also notice that the result is incorrect: 4/2 is 2 and not 4. We quickly-- notice that (div m (suc n)) will perform m recursive calls no matter what.-- And at each call it will put add 1. We can fix this bug by adding a new first-- equation to go:-- go fuel zero = zero-- Running the example again we observe that because we now need to check-- whether go's second argument is zero, the function is more strict: we see-- that recursive calls and thunk forcings are interleaved.-- Call to div-- Forcing the result wrapped in just.-- Recursive call for step 3-- Thunk for step 3 forced-- Recursive call for step 2-- Thunk for step 2 forced-- 2
-------------------------------------------------------------------------- The Agda standard library---- An explanation about how data types are laid out in the standard-- library.------------------------------------------------------------------------{-# OPTIONS --sized-types --guardedness #-}module README.Data where-- The top-level folder `Data` contains all the definitions of datatypes-- and their associated properties.-- Datatypes can broadly split into two categories-- i) "Basic" datatypes which do not take other datatypes as generic-- arguments (Nat, String, Fin, Bool, Char etc.)-- ii) "Container" datatypes which take other generic datatypes as-- arguments, (List, Vec, Sum, Product, Maybe, AVL trees etc.)-------------------------------------------------------------------------- Basic datatypes-------------------------------------------------------------------------- Basic datatypes are usually organised as follows:-- 1. A `Base` module which either contains the definition of the-- datatype or reimports it from the builtin modules, along with common-- functions, operations and relations over elements of the datatype.import Data.Nat.Baseimport Data.Integer.Baseimport Data.Char.Baseimport Data.String.Baseimport Data.Bool.Base-- Commonly these modules don't need to be imported directly as their-- contents is re-exported by the top level module (see below).-- 2. A `Properties` module which contains the basic properties of the-- functions, operations and relations contained in the base module.import Data.Nat.Propertiesimport Data.Integer.Propertiesimport Data.Char.Propertiesimport Data.String.Propertiesimport Data.Bool.Properties-- 3. A top-level module which re-exports the contents of the base-- module as well as various queries (i.e. decidability proofs) from the-- properties file.import Data.Natimport Data.Integerimport Data.Charimport Data.Stringimport Data.Bool-- 4. A `Solver` module (for those datatypes that have an algebraic solver)-- which can be used to automatically solve equalities over the basic datatype.import Data.Nat.Solverimport Data.Integer.Solverimport Data.Bool.Solver-- 5. More complex operations and relations are commonly found in their-- own module beneath the top-level directory. For example:import Data.Nat.DivModimport Data.Integer.Coprimality-- Note that eventually there is a plan to re-organise the library to-- have the top-level module export a far wider range of properties and-- additional operations in order to minimise the number of imports-- needed. Currently it is necessary to import each of these separately-- however.-------------------------------------------------------------------------- Container datatypes-------------------------------------------------------------------------- 1. As with basic datatypes, a `Base` module which contains the-- definition of the datatype, along with common functions and-- operations over that data. Unlike basic datatypes, the `Base` module-- for container datatypes does not export any relations or predicates-- over the datatype (see the `Relation` section below).import Data.List.Baseimport Data.Maybe.Baseimport Data.Sum.Base-- Commonly these modules don't need to be imported directly as their-- contents is re-exported by the top level module (see below).-- 2. As with basic datatypes, a `Properties` module which contains the-- basic properties of the functions, operations and contained in the-- base module.import Data.List.Propertiesimport Data.Maybe.Propertiesimport Data.Sum.Properties-- 3. As with basic datatypes, a top-level module which re-exports the-- contents of the base module. In some cases this may also contain-- additional functions which could not be placed into the corresponding-- Base module because of cyclic dependencies.import Data.Listimport Data.Maybeimport Data.Sum-- 4. A `Relation.Binary` folder where binary relations over the datatypes-- are stored. Because relations over container datatypes often depend on-- relations over the parameter datatype, this differs from basic datatypes-- where the binary relations are usually defined in the `Base` module, e.g.-- equality over the type `List A` depends on equality over type `A`.-- For example the `Pointwise` relation that takes a relation over the-- underlying type A and lifts it to the container parameterised can be found-- as follows:import Data.List.Relation.Binary.Pointwiseimport Data.Maybe.Relation.Binary.Pointwiseimport Data.Sum.Relation.Binary.Pointwise-- Another useful subfolder in the `Data.X.Relation.Binary` folders is the-- `Data.X.Relation.Binary.Equality` folder which contains various forms of-- equality over the datatype.-- 5. A `Relation.Unary` folder where unary relations, or predicates,-- over the datatypes are stored. These can be viewed as properties-- over a single list.-- For example a common, useful example is `Data.X.Relation.Unary.Any`-- that contains the types of proofs that at least one element in the-- container satisfies some predicate/property.import Data.List.Relation.Unary.Anyimport Data.Vec.Relation.Unary.Anyimport Data.Maybe.Relation.Unary.Any-- Alternatively the `Data.X.Relation.Unary.All` module contains the-- type of proofs that all elements in the container satisfy some-- property.import Data.List.Relation.Unary.Allimport Data.Vec.Relation.Unary.Allimport Data.Maybe.Relation.Unary.All-- 6. An `Effectful` module/folder that contains effectful-- interpretations of the datatype.import Data.List.Effectfulimport Data.Maybe.Effectfulimport Data.Sum.Effectful.Leftimport Data.Sum.Effectful.Right-- 7. A `Function` folder that contains lifting of various types of-- functions (e.g. injections, surjections, bijections, inverses) to-- the datatype.import Data.Sum.Function.Propositionalimport Data.Sum.Function.Setoidimport Data.Product.Function.Dependent.Propositionalimport Data.Product.Function.Dependent.Setoid-------------------------------------------------------------------------- Full list of documentation for the Data folder-------------------------------------------------------------------------- Some examples showing where the natural numbers/integers and some-- related operations and properties are defined, and how they can be-- used:import README.Data.Natimport README.Data.Nat.Inductionimport README.Data.Integer-- Some examples showing how the AVL tree module can be used.import README.Data.Tree.AVL-- Some examples showing how List module can be used.import README.Data.List-- Some examples showing how the Fresh list can be used.import README.Data.List.Fresh-- Example of an encoding of record types with manifest fields and "with".import README.Data.Record-- Example use case for a trie: a wee generic lexerimport README.Data.Trie.NonDependent-- Examples of equational reasoning about vectors of non-definitionally-- equal lengths.import README.Data.Vec.Relation.Binary.Equality.Cast-- Examples how (indexed) containers and constructions over them (free-- monad, least fixed point, etc.) can be usedimport README.Data.Container.FreeMonadimport README.Data.Container.Indexed.VectorExampleimport README.Data.Container.Indexed.MultiSortedAlgebraExample-- Wrapping n-ary relations into a record definition so type-inference-- remembers the things being related.import README.Data.Wrap-- Specifying the default value a function's argument should take if it-- is not passed explicitly.import README.Data.Default
-------------------------------------------------------------------------- The Agda standard library---- An example of how to use `Wrap` to help term inference.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Wrap whereopen import Data.Wrapopen import Algebraopen import Data.Natopen import Data.Nat.Propertiesopen import Data.Product.Base using (_,_; ∃; ∃₂; _×_)open import Level using (Level)privatevariablec ℓ : LevelA : Set cm n : ℕ-------------------------------------------------------------------------- `Wrap` for remembering instances------------------------------------------------------------------------module Instances where-- `Monoid.Carrier` gets the carrier set from a monoid, and thus has-- type `Monoid c ℓ → Set c`.-- Using `Wrap`, we can convert `Monoid.Carrier` into an equivalent-- “wrapped” version: `MonoidEl`.MonoidEl : Monoid c ℓ → Set cMonoidEl = Wrap Monoid.Carrier-- We can turn any monoid into the equivalent monoid where the elements-- and equations have been wrapped.-- The translation mainly consists of wrapping and unwrapping everything-- via the `Wrap` constructor, `[_]`.-- Notice that the equality field is wrapping the binary relation-- `_≈_ : (x y : Carrier) → Set ℓ`, giving an example of how `Wrap` works-- for arbitrary n-ary relations.Wrap-monoid : Monoid c ℓ → Monoid c ℓWrap-monoid M = record{ Carrier = MonoidEl M; _≈_ = λ ([ x ]) ([ y ]) → Wrap _≈_ x y; _∙_ = λ ([ x ]) ([ y ]) → [ x ∙ y ]; ε = [ ε ]; isMonoid = record{ isSemigroup = record{ isMagma = record{ isEquivalence = record{ refl = [ refl ]; sym = λ ([ xy ]) → [ sym xy ]; trans = λ ([ xy ]) ([ yz ]) → [ trans xy yz ]}; ∙-cong = λ ([ xx ]) ([ yy ]) → [ ∙-cong xx yy ]}; assoc = λ ([ x ]) ([ y ]) ([ z ]) → [ assoc x y z ]}; identity = (λ ([ x ]) → [ identityˡ x ]), (λ ([ x ]) → [ identityʳ x ])}}where open Monoid M-- Usually, we would only open one monoid at a time.-- If we were to open two monoids `M` and `N` simultaneously, Agda would-- get confused whenever it came across, for example, `_∙_`, not knowing-- whether it came from `M` or `N`.-- This is true whether or not `M` and `N` can be disambiguated by some-- other means (such as by their `Carrier`s).-- However, with wrapped monoids, we are going to remember the monoid-- while checking any monoid expressions, so we can afford to have just-- one, polymorphic, version of `_∙_` visible globally.open module Wrap-monoid {c ℓ} {M : Monoid c ℓ} = Monoid (Wrap-monoid M)-- Now we can test out this construct on some existing monoids.open import Data.Nat.Properties-- Notice that, while the following two definitions appear to be defined-- by the same expression, their types are genuinely different.-- Whereas `Carrier +-0-monoid = ℕ = Carrier *-1-monoid`, `MonoidEl M`-- does not compute, and thus-- `MonoidEl +-0-monoid ≠ MonoidEl *-1-monoid` definitionally.-- This lets us use the respective monoids when checking the respective-- definitions.test-+ : MonoidEl +-0-monoidtest-+ = ([ 3 ] ∙ ε) ∙ [ 2 ]test-* : MonoidEl *-1-monoidtest-* = ([ 3 ] ∙ ε) ∙ [ 2 ]-- The reader is invited to normalise these two definitions-- (`C-c C-n`, then type in the name).-- `test-+` is interpreted using (ℕ, +, 0), and thus computes to `[ 5 ]`.-- Meanwhile, `test-*` is interpreted using (ℕ, *, 1), and thus computes-- to `[ 6 ]`.-------------------------------------------------------------------------- `Wrap` for dealing with functions spoiling unification------------------------------------------------------------------------module Unification whereopen import Relation.Binary.PropositionalEqualitymodule Naïve where-- We want to work with factorisations of natural numbers in a-- “proof-relevant” style. We could draw out `Factor m n o` as-- m-- /*\-- n o.Factor : (m n o : ℕ) → SetFactor m n o = m ≡ n * o-- We can prove a basic lemma about `Factor`: the following tree rotation-- can be done, due to associativity of `_*_`.-- m m-- /*\ /*\-- no p ----> n op-- /*\ /*\-- n o o passoc-→ : ∀ {m n o p} →(∃ λ no → Factor m no p × Factor no n o) →(∃ λ op → Factor m n op × Factor op o p)assoc-→ {m} {n} {o} {p} (._ , refl , refl) = _ , *-assoc n o p , refl-- We must give at least some arguments to `*-assoc`, as Agda is unable to-- unify `? * ? * ?` with `n * o * p`, as `_*_` is a function and not-- necessarily injective (and indeed not injective when one of its-- arguments is 0).-- We now want to use this lemma in a more complex proof:-- m m-- /*\ /*\-- nop q n opq-- /*\ ----> /*\-- no p o pq-- /*\ /*\-- n o p qtest : ∀ {m n o p q} →(∃₂ λ no nop → Factor m nop q × Factor nop no p × Factor no n o) →(∃₂ λ pq opq → Factor m n opq × Factor opq o pq × Factor pq p q)test {n = n} (no , nop , fm , fnop , fno) =let _ , fm , fpq = assoc-→ {n = no} (_ , fm , fnop) inlet _ , fm , fopq = assoc-→ {n = n} (_ , fm , fno) in_ , _ , fm , fopq , fpq-- This works okay, but where we have written `{n = no}` and similar, we-- are being forced to deal with details we don't really care about. Agda-- should be able to fill in the vertices given part of a tree, but can't-- due to similar reasons as before: `Factor ? ? ?` doesn't unify against-- `Factor m no p`, because both instances of `Factor` compute and we're-- left trying to unify `? * ?` against `no * p`.module Wrapped where-- We can use `Wrap` to stop the computation of `Factor`.Factor : (m n o : ℕ) → SetFactor = Wrap λ m n o → m ≡ n * o-- Because `assoc-→` needs access to the implementation of `Factor`, the-- proof is exactly as before except for using `[_]` to wrap and unwrap.assoc-→ : ∀ {m n o p} →(∃ λ no → Factor m no p × Factor no n o) →(∃ λ op → Factor m n op × Factor op o p)assoc-→ {m} {n} {o} {p} (._ , [ refl ] , [ refl ]) =_ , [ *-assoc n o p ] , [ refl ]-- The difference is that now we have our basic lemma, the complex proof-- can work purely in terms of `Factor` trees. In particular,-- `Factor ? ? ?` now does unify with `Factor m no p`, so we don't have to-- give `no` explicitly again.test : ∀ {m n o p q} →(∃₂ λ no nop → Factor m nop q × Factor nop no p × Factor no n o) →(∃₂ λ pq opq → Factor m n opq × Factor opq o pq × Factor pq p q)test (_ , _ , fm , fnop , fno) =let _ , fm , fpq = assoc-→ (_ , fm , fnop) inlet _ , fm , fopq = assoc-→ (_ , fm , fno) in_ , _ , fm , fopq , fpq
-------------------------------------------------------------------------- The Agda standard library---- An equational reasoning library for propositional equality over-- vectors of different indices using cast.---- To see example usages of this library, scroll to the `Combinators`-- section.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Vec.Relation.Binary.Equality.Cast whereopen import Agda.Primitiveopen import Data.List.Base as List using (List)import Data.List.Properties as Listopen import Data.Nat.Baseopen import Data.Nat.Propertiesopen import Data.Vec.Baseopen import Data.Vec.Propertiesopen import Data.Vec.Relation.Binary.Equality.Castopen import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; module ≡-Reasoning)private variablea : LevelA : Set al m n o : ℕxs ys zs ws : Vec A n-------------------------------------------------------------------------- Motivation---- The `cast` function is the computational variant of `subst` for-- vectors. Since `cast` computes under vector constructors, it-- enables reasoning about vectors with non-definitionally equal indices-- by induction. See, e.g., Jacques Carette's comment in issue #1668.-- <https://github.com/agda/agda-stdlib/pull/1668#issuecomment-1003449509>---- Suppose we want to prove that ‘xs ++ [] ≡ xs’. Because `xs ++ []`-- has type `Vec A (n + 0)` while `xs` has type `Vec A n`, they cannot-- be directly related by homogeneous equality.-- To resolve the issue, `++-right-identity` uses `cast` to recast-- `xs ++ []` as a vector in `Vec A n`.--++-right-identity : ∀ .(eq : n + 0 ≡ n) (xs : Vec A n) → cast eq (xs ++ []) ≡ xs++-right-identity eq [] = refl++-right-identity eq (x ∷ xs) = cong (x ∷_) (++-right-identity (cong pred eq) xs)---- When the input is `x ∷ xs`, because `cast eq (x ∷ _)` equals-- `x ∷ cast (cong pred eq) _`, the proof obligation-- cast eq (x ∷ xs ++ []) ≡ x ∷ xs-- simplifies to-- x :: cast (cong pred eq) (xs ++ []) ≡ x ∷ xs-- Although `cast` makes it possible to prove vector identities by ind--- uction, the explicit type-casting nature poses a significant barrier-- to code reuse in larger proofs. For example, consider the identity-- ‘fromList (xs List.∷ʳ x) ≡ (fromList xs) ∷ʳ x’ where `List._∷ʳ_` is the-- snoc function of lists. We have---- fromList (xs List.∷ʳ x) : Vec A (List.length (xs List.∷ʳ x))-- = {- by definition -}-- fromList (xs List.++ List.[ x ]) : Vec A (List.length (xs List.++ List.[ x ]))-- = {- by fromList-++ -}-- fromList xs ++ fromList List.[ x ] : Vec A (List.length xs + List.length [ x ])-- = {- by definition -}-- fromList xs ++ [ x ] : Vec A (List.length xs + 1)-- = {- by unfold-∷ʳ -}-- fromList xs ∷ʳ x : Vec A (suc (List.length xs))-- where-- fromList-++ : cast _ (fromList (xs List.++ ys)) ≡ fromList xs ++ fromList ys-- unfold-∷ʳ : cast _ (xs ∷ʳ x) ≡ xs ++ [ x ]---- Although the identity itself is simple, the reasoning process changes-- the index in the type twice. Consequently, its Agda translation must-- insert two `cast`s in the proof. Moreover, the proof first has to-- rearrange (the Agda version of) the identity into one with two-- `cast`s, resulting in lots of boilerplate code as demonstrated by-- `example1a-fromList-∷ʳ`.example1a-fromList-∷ʳ : ∀ (x : A) xs →.(eq : List.length (xs List.∷ʳ x) ≡ suc (List.length xs)) →cast eq (fromList (xs List.∷ʳ x)) ≡ fromList xs ∷ʳ xexample1a-fromList-∷ʳ x xs eq = begincast eq (fromList (xs List.∷ʳ x))≡⟨⟩cast eq (fromList (xs List.++ List.[ x ]))≡⟨ cast-trans eq₁ eq₂ (fromList (xs List.++ List.[ x ])) ⟨cast eq₂ (cast eq₁ (fromList (xs List.++ List.[ x ])))≡⟨ cong (cast eq₂) (fromList-++ xs) ⟩cast eq₂ (fromList xs ++ [ x ])≡⟨ ≈-sym (unfold-∷ʳ (sym eq₂) x (fromList xs)) ⟩fromList xs ∷ʳ x∎whereopen ≡-Reasoningeq₁ = List.length-++ xs {List.[ x ]}eq₂ = +-comm (List.length xs) 1-- The `cast`s are irrelevant to core of the proof. At the same time,-- they can be inferred from the lemmas used during the reasoning steps-- (e.g. `fromList-++` and `unfold-∷ʳ`). To eliminate the boilerplate,-- this library provides a set of equational reasoning combinators for-- equality of the form `cast eq xs ≡ ys`.example1b-fromList-∷ʳ : ∀ (x : A) xs →.(eq : List.length (xs List.∷ʳ x) ≡ suc (List.length xs)) →cast eq (fromList (xs List.∷ʳ x)) ≡ fromList xs ∷ʳ xexample1b-fromList-∷ʳ x xs eq = beginfromList (xs List.∷ʳ x)≈⟨⟩fromList (xs List.++ List.[ x ])≈⟨ fromList-++ xs ⟩fromList xs ++ [ x ]≈⟨ unfold-∷ʳ (+-comm 1 (List.length xs)) x (fromList xs) ⟨fromList xs ∷ʳ x∎where open CastReasoning-------------------------------------------------------------------------- Combinators---- Let `xs ≈[ m≡n ] ys` denote `cast m≡n xs ≡ ys`. We have reflexivity,-- symmetry and transitivity:-- ≈-reflexive : xs ≈[ refl ] xs-- ≈-sym : xs ≈[ m≡n ] ys → ys ≈[ sym m≡n ] xs-- ≈-trans : xs ≈[ m≡n ] ys → ys ≈[ n≡o ] zs → xs ≈[ trans m≡n n≡o ] zs-- Accordingly, `_≈[_]_` admits the standard set of equational reasoning-- combinators. Suppose `≈-eqn : xs ≈[ m≡n ] ys`,-- xs ≈⟨ ≈-eqn ⟩ -- `_≈⟨_⟩_` takes a `_≈[_]_` step, adjusting-- ys -- the index at the same time---- ys ≈⟨ ≈-eqn ⟨ -- `_≈⟨_⟨_` takes a symmetric `_≈[_]_` step-- xsexample2a : ∀ .(eq : suc m + n ≡ m + suc n) (xs : Vec A m) a ys →cast eq ((reverse xs ∷ʳ a) ++ ys) ≡ reverse xs ++ (a ∷ ys)example2a eq xs a ys = begin(reverse xs ∷ʳ a) ++ ys ≈⟨ ∷ʳ-++ eq a (reverse xs) ⟩ -- index: suc m + nreverse xs ++ (a ∷ ys) ∎ -- index: m + suc nwhere open CastReasoning-- To interoperate with `_≡_`, this library provides `_≂⟨_⟩_` (\-~) for-- taking a `_≡_` step during equational reasoning.-- Let `≡-eqn : xs ≡ ys`, then-- xs ≂⟨ ≡-eqn ⟩ -- Takes a `_≡_` step; no change to the index-- ys---- ys ≂⟨ ≡-eqn ⟨ -- Takes a symmetric `_≡_` step-- xs-- Equivalently, `≈-reflexive` injects `_≡_` into `_≈[_]_`. That is,-- `xs ≂⟨ ≡-eqn ⟩ ys` is the same as `xs ≈⟨ ≈-reflexive ≡-eqn ⟩ ys`.-- Extending `example2a`, we have:example2b : ∀ .(eq : suc m + n ≡ m + suc n) (xs : Vec A m) a ys →cast eq ((a ∷ xs) ʳ++ ys) ≡ xs ʳ++ (a ∷ ys)example2b eq xs a ys = begin(a ∷ xs) ʳ++ ys ≂⟨ unfold-ʳ++ (a ∷ xs) ys ⟩ -- index: suc m + nreverse (a ∷ xs) ++ ys ≂⟨ cong (_++ ys) (reverse-∷ a xs) ⟩ -- index: suc m + n(reverse xs ∷ʳ a) ++ ys ≈⟨ ∷ʳ-++ eq a (reverse xs) ⟩ -- index: suc m + nreverse xs ++ (a ∷ ys) ≂⟨ unfold-ʳ++ xs (a ∷ ys) ⟨ -- index: m + suc nxs ʳ++ (a ∷ ys) ∎ -- index: m + suc nwhere open CastReasoning-- Oftentimes index-changing identities apply to only part of the proof-- term. When reasoning about `_≡_`, `cong` shifts the focus to the-- subterm of interest. In this library, `≈-cong` does a similar job.-- Suppose `f : A → B`, `xs : B`, `ys zs : A`, `ys≈zs : ys ≈[ _ ] zs`-- and `xs≈f⟨c·ys⟩ : xs ≈[ _ ] f (cast _ ys)`, we have-- xs ≈⟨ ≈-cong f xs≈f⟨c·ys⟩ ys≈zs ⟩-- f zs-- The reason for having the extra argument `xs≈f⟨c·ys⟩` is to expose-- `cast` in the subterm in order to apply the step `ys≈zs`. When using-- ordinary `cong` the proof has to explicitly push `cast` inside:-- xs ≈⟨ xs≈f⟨c·ys⟩ ⟩-- f (cast _ ys) ≂⟨ cong f ys≈zs ⟩-- f zs-- Note. Technically, `A` and `B` should be vectors of different length-- and that `ys`, `zs` are vectors of non-definitionally equal index.example3a-fromList-++-++ : {xs ys zs : List A} →.(eq : List.length (xs List.++ ys List.++ zs) ≡List.length xs + (List.length ys + List.length zs)) →cast eq (fromList (xs List.++ ys List.++ zs)) ≡fromList xs ++ fromList ys ++ fromList zsexample3a-fromList-++-++ {xs = xs} {ys} {zs} eq = beginfromList (xs List.++ ys List.++ zs)≈⟨ fromList-++ xs ⟩fromList xs ++ fromList (ys List.++ zs)≈⟨ ≈-cong (fromList xs ++_) (cast-++ʳ (List.length-++ ys) (fromList xs)) (fromList-++ ys) ⟩fromList xs ++ fromList ys ++ fromList zs∎where open CastReasoning-- As an alternative, one can manually apply `cast-++ʳ` to expose `cast`-- in the subterm. However, this unavoidably duplicates the proof term.example3b-fromList-++-++′ : {xs ys zs : List A} →.(eq : List.length (xs List.++ ys List.++ zs) ≡List.length xs + (List.length ys + List.length zs)) →cast eq (fromList (xs List.++ ys List.++ zs)) ≡fromList xs ++ fromList ys ++ fromList zsexample3b-fromList-++-++′ {xs = xs} {ys} {zs} eq = beginfromList (xs List.++ ys List.++ zs)≈⟨ fromList-++ xs ⟩fromList xs ++ fromList (ys List.++ zs)≈⟨ cast-++ʳ (List.length-++ ys) (fromList xs) ⟩fromList xs ++ cast _ (fromList (ys List.++ zs))≂⟨ cong (fromList xs ++_) (fromList-++ ys) ⟩fromList xs ++ fromList ys ++ fromList zs∎where open CastReasoning-- `≈-cong` can be chained together much like how `cong` can be nested.-- In this example, `unfold-∷ʳ` is applied to the term `xs ++ [ a ]`-- in `(_++ ys)` inside of `reverse`. Thus the proof employs two-- `≈-cong`.example4-cong² : ∀ .(eq : (m + 1) + n ≡ n + suc m) a (xs : Vec A m) ys →cast eq (reverse ((xs ++ [ a ]) ++ ys)) ≡ ys ʳ++ reverse (xs ∷ʳ a)example4-cong² {m = m} {n} eq a xs ys = beginreverse ((xs ++ [ a ]) ++ ys)≈⟨ ≈-cong reverse (cast-reverse (cong (_+ n) (+-comm 1 m)) ((xs ∷ʳ a) ++ ys))(≈-cong (_++ ys) (cast-++ˡ (+-comm 1 m) (xs ∷ʳ a))(unfold-∷ʳ _ a xs)) ⟨reverse ((xs ∷ʳ a) ++ ys)≈⟨ reverse-++ (+-comm (suc m) n) (xs ∷ʳ a) ys ⟩reverse ys ++ reverse (xs ∷ʳ a)≂⟨ unfold-ʳ++ ys (reverse (xs ∷ʳ a)) ⟨ys ʳ++ reverse (xs ∷ʳ a)∎where open CastReasoning-------------------------------------------------------------------------- Interoperation between `_≈[_]_` and `_≡_`---- This library is designed to interoperate with `_≡_`. Examples in the-- combinators section showed how to apply `_≂⟨_⟩_` to take an `_≡_`-- step during equational reasoning about `_≈[_]_`. Recall that-- `xs ≈[ m≡n ] ys` is a shorthand for `cast m≡n xs ≡ ys`, the-- combinator is essentially the composition of `_≡_` on the left-hand-- side of `_≈[_]_`. Dually, the combinator `_≃⟨_⟩_` composes `_≡_` on-- the right-hand side of `_≈[_]_`. Thus `_≃⟨_⟩_` intuitively ends the-- reasoning system of `_≈[_]_` and switches back to the reasoning-- system of `_≡_`.example5-fromList-++-++′ : {xs ys zs : List A} →.(eq : List.length (xs List.++ ys List.++ zs) ≡List.length xs + (List.length ys + List.length zs)) →cast eq (fromList (xs List.++ ys List.++ zs)) ≡fromList xs ++ fromList ys ++ fromList zsexample5-fromList-++-++′ {xs = xs} {ys} {zs} eq = beginfromList (xs List.++ ys List.++ zs)≈⟨ fromList-++ xs ⟩fromList xs ++ fromList (ys List.++ zs)≃⟨ cast-++ʳ (List.length-++ ys) (fromList xs) ⟩fromList xs ++ cast _ (fromList (ys List.++ zs))≡⟨ cong (fromList xs ++_) (fromList-++ ys) ⟩fromList xs ++ fromList ys ++ fromList zs≡-∎where open CastReasoning-- Of course, it is possible to start with the reasoning system of `_≡_`-- and then switch to the reasoning system of `_≈[_]_`.example6a-reverse-∷ʳ : ∀ x (xs : Vec A n) → reverse (xs ∷ʳ x) ≡ x ∷ reverse xsexample6a-reverse-∷ʳ {n = n} x xs = begin-≡reverse (xs ∷ʳ x)≡⟨ ≈-reflexive refl ⟨reverse (xs ∷ʳ x)≈⟨ ≈-cong reverse (cast-reverse _ _) (unfold-∷ʳ (+-comm 1 n) x xs) ⟩reverse (xs ++ [ x ])≈⟨ reverse-++ (+-comm n 1) xs [ x ] ⟩x ∷ reverse xs∎where open CastReasoningexample6b-reverse-∷ʳ-by-induction : ∀ x (xs : Vec A n) → reverse (xs ∷ʳ x) ≡ x ∷ reverse xsexample6b-reverse-∷ʳ-by-induction x [] = reflexample6b-reverse-∷ʳ-by-induction x (y ∷ xs) = beginreverse (y ∷ (xs ∷ʳ x)) ≡⟨ reverse-∷ y (xs ∷ʳ x) ⟩reverse (xs ∷ʳ x) ∷ʳ y ≡⟨ cong (_∷ʳ y) (example6b-reverse-∷ʳ-by-induction x xs) ⟩(x ∷ reverse xs) ∷ʳ y ≡⟨⟩x ∷ (reverse xs ∷ʳ y) ≡⟨ cong (x ∷_) (reverse-∷ y xs) ⟨x ∷ reverse (y ∷ xs) ∎where open ≡-Reasoning
-------------------------------------------------------------------------- The Agda standard library---- Example use case for a trie: a wee generic lexer------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module README.Data.Trie.NonDependent where-------------------------------------------------------------------------- Introduction-- A Trie is a tree of values indexed by words in a finite language. It-- allows users to quickly compute the Brzozowski derivative of that-- little mapping from words to values.-- In the most general case, values can depend upon the list of characters-- that constitutes the path leading to them. Here however we consider a-- non-dependent case (cf. README.Trie.Dependent for a dependent use case).-- We can recognize keywords by storing the list of characters they-- correspond to as paths in a Trie and the constructor they are decoded-- to as the tree's values.-- E.g.-- [ . ] is a root-- [ -- m --> ] is an m-labeled edge and is followed when reading 'm'-- [ (X) ] is a value leaf storing constructor X-- --> -- m --> -- m --> -- a --> (LEMMA)-- /-- -- l --> -- e --> -- t --> (LET)-- /-- / -- u --> -- t --> -- u --> -- a --> -- l --> (MUTUAL)-- / /-- .< -- m --> -- o --> -- d --> -- u --> -- l --> -- e --> (MODULE)-- \-- -- w --> -- h --> -- e --> -- r --> -- e --> (WHERE)-- \-- --> -- n --> (WHEN)-- after reading 'w', we get the derivative:-- . -- h --> -- e --> -- r --> -- e --> (WHERE)-- \-- --> -- n --> (WHEN)open import Levelopen import Data.Unitopen import Data.Boolopen import Data.Char as Charimport Data.Char.Properties as Charopen import Data.List.Base as List using (List; []; _∷_)open import Data.List.Fresh as List# using (List#; []; _∷#_)open import Data.Maybe as Maybeopen import Data.Product.Base as Product using (_×_; ∃; proj₁; _,_)open import Data.String.Base as String using (String)open import Data.String.Properties as String using (_≟_)open import Data.These as Theseopen import Function.Base using (case_of_; _$_; _∘′_; id; _on_)open import Relation.Naryopen import Relation.Binary.Core using (Rel)open import Relation.Nullary.Decidable using (¬?)open import Data.Trie Char.<-strictTotalOrderopen import Data.Tree.AVL.Value-------------------------------------------------------------------------- Generic lexerrecord Lexer t : Set (suc t) wherefield-- Our lexer is parametrised over the type of tokensTok : Set t-- Keywords are distinguished strings associated to tokensKeyword : Set tKeyword = String × Tok-- Two keywords are considered distinct if the strings are not equalDistinct : Rel Keyword 0ℓDistinct a b = ⌊ ¬? ((proj₁ a) String.≟ (proj₁ b)) ⌋field-- We ask users to provide us with a fresh list of keywords to guarantee-- that no two keywords share the same string representationkeywords : List# Keyword Distinct-- Some characters are special: they are separators, breaking a string-- into a list of tokens. Some are associated to a token value-- (e.g. parentheses) others are not (e.g. space)breaking : Char → ∃ λ b → if b then Maybe Tok else Lift _ ⊤-- Finally, strings which are not decoded as keywords are coerced-- using a function to token values.default : String → Tokmodule _ {t} (L : Lexer t) whereopen Lexer Ltokenize : String → List Toktokenize = start ∘′ String.toList wheremutual-- A Trie is defined for an alphabet of strictly ordered letters (here-- we have picked Char for letters and decided to use the strict total-- order induced by their injection into ℕ as witnessed by the statement-- open import Data.Trie Char.strictTotalOrder earlier in this file).-- It is parametrised by a set of Values indexed over list of letters.-- Because we focus on the non-dependent case, we pick the constant-- family of Value uniformly equal to Tok. It is trivially compatible-- with the notion of equality underlying the strict total order on Chars.Keywords : Set _Keywords = Trie (const _ Tok) _-- We build a trie from the association list so that we may easily-- compute the successive derivatives obtained by eating the-- characters one by oneinit : Keywordsinit = fromList $ List.map (Product.map₁ String.toList) $ proj₁ $ List#.toList keywords-- Kickstart the tokeniser with an empty accumulator and the initial-- trie.start : List Char → List Tokstart = loop [] init-- The main looploop : (acc : List Char) → -- chars read so far in this token(toks : Keywords) → -- keyword candidates left at this point(input : List Char) → -- list of chars to tokenizeList Tok-- Empty input: finish up, check whether we have a non-empty accumulatorloop acc toks [] = push acc []-- At least one characterloop acc toks (c ∷ cs) = case breaking c of λ where-- if we are supposed to break on this character, we do(true , m) → push acc $ maybe′ _∷_ id m $ start cs-- otherwise we see whether it leads to a recognized keyword(false , _) → case lookupValue toks (c ∷ []) of λ where-- if so we can forget about the current accumulator and-- restart the tokenizer on the rest of the input(just tok) → tok ∷ start cs-- otherwise we record the character we read in the accumulator,-- compute the derivative of the map of keyword candidates and-- keep going with the rest of the inputnothing → loop (c ∷ acc) (lookupTrie toks c) cs-- Grab the accumulator and, unless it is empty, push it on top of-- the decoded list of tokenspush : List Char → List Tok → List Tokpush [] ts = tspush cs ts = default (String.fromList (List.reverse cs)) ∷ ts-------------------------------------------------------------------------- Concrete instance-- A small set of keywords for a language with expressions of the form-- `let x = e in b`.module LetIn wheredata TOK : Set whereLET EQ IN : TOKLPAR RPAR : TOKID : String → TOKkeywords : List# (String × TOK) (λ a b → ⌊ ¬? ((proj₁ a) String.≟ (proj₁ b)) ⌋)keywords = ("let" , LET)∷# ("=" , EQ)∷# ("in" , IN)∷# []-- Breaking characters: spaces (thrown away) and parentheses (kept)breaking : Char → ∃ (λ b → if b then Maybe TOK else Lift 0ℓ ⊤)breaking c = if isSpace c then true , nothing else parens c whereparens : Char → _parens '(' = true , just LPARparens ')' = true , just RPARparens _ = false , _default : String → TOKdefault = IDletIn : Lexer 0ℓletIn = record { LetIn }open import Agda.Builtin.Equality-- A test case:open LetIn_ : tokenize letIn "fix f x = let b = fix f in (f b) x"≡ ID "fix"∷ ID "f"∷ ID "x"∷ EQ∷ LET∷ ID "b"∷ EQ∷ ID "fix"∷ ID "f"∷ IN∷ LPAR∷ ID "f"∷ ID "b"∷ RPAR∷ ID "x"∷ []_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing how the Rose tree module can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module README.Data.Tree.Rose whereopen import Data.List.Baseopen import Data.String.Base using (String; unlines)open import Data.Tree.Rose using (Rose; node)open import Function.Baseopen import Agda.Builtin.Equality-------------------------------------------------------------------------- Pretty-printingopen import Data.Tree.Rose.Show using (display)_ : unlines (display$ node [ "one" ](node [ "two" ] []∷ node ("three" ∷ "and" ∷ "four" ∷ [])(node [ "five" ] []∷ node [ "six" ] (node [ "seven" ] [] ∷ [])∷ node [ "eight" ] []∷ [])∷ node [ "nine" ](node [ "ten" ] []∷ node [ "eleven" ] [] ∷ [])∷ []))≡ "one\ \ ├ two\ \ ├ three\ \ │ and\ \ │ four\ \ │ ├ five\ \ │ ├ six\ \ │ │ └ seven\ \ │ └ eight\ \ └ nine\ \ ├ ten\ \ └ eleven"_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing how the Binary tree module can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module README.Data.Tree.Binary whereopen import Data.List.Baseopen import Data.String.Base using (String; unlines)open import Data.Tree.Binary using (Tree; leaf; node)open import Function.Baseopen import Agda.Builtin.Equality-------------------------------------------------------------------------- Pretty-printingopen import Data.Tree.Binary.Show using (display)_ : unlines (display$ node (node (leaf [ "plum" ])("apricot" ∷ "prune" ∷ [])(node (leaf [ "orange" ])("peach" ∷ [])(node (leaf [ "kiwi" ])("apple" ∷ "pear" ∷ [])(leaf [ "pineapple" ]))))("cherry" ∷ "lemon" ∷ "banana" ∷ [])(leaf [ "yuzu" ]))≡ "cherry\ \lemon\ \banana\ \ ├ apricot\ \ │ prune\ \ │ ├ plum\ \ │ └ peach\ \ │ ├ orange\ \ │ └ apple\ \ │ pear\ \ │ ├ kiwi\ \ │ └ pineapple\ \ └ yuzu"_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing how the AVL tree module can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Tree.AVL where-------------------------------------------------------------------------- Setup-- AVL trees are defined in Data.Tree.AVL.import Data.Tree.AVL-- This module is parametrised by keys, which have to form a (strict)-- total order, and values, which are indexed by keys. Let us use-- natural numbers as keys and vectors of strings as values.open import Data.Nat.Properties using (<-strictTotalOrder)open import Data.Product.Base as Product using (_,_; _,′_)open import Data.String.Base using (String)open import Data.Vec.Base using (Vec; _∷_; [])open import Relation.Binary.PropositionalEqualityopen Data.Tree.AVL <-strictTotalOrder renaming (Tree to Tree′)Tree = Tree′ (MkValue (Vec String) (subst (Vec String)))-------------------------------------------------------------------------- Construction of trees-- Some values.v₁ = "cepa" ∷ []v₁′ = "depa" ∷ []v₂ = "apa" ∷ "bepa" ∷ []-- Empty and singleton trees.t₀ : Treet₀ = emptyt₁ : Treet₁ = singleton 2 v₂-- Insertion of a key-value pair into a tree.t₂ = insert 1 v₁ t₁-- If you insert a key-value pair and the key already exists in the-- tree, then the old value is thrown away.t₂′ = insert 1 v₁′ t₂-- Deletion of the mapping for a certain key.t₃ = delete 2 t₂-- Conversion of a list of key-value mappings to a tree.open import Data.List.Base using (_∷_; [])t₄ : Treet₄ = fromList ((2 , v₂) ∷ (1 , v₁) ∷ [])-------------------------------------------------------------------------- Queries-- Let us formulate queries as unit tests.open import Relation.Binary.PropositionalEquality using (_≡_; refl)-- Searching for a key.open import Data.Bool.Base using (true; false)open import Data.Maybe.Base as Maybe using (just; nothing)q₀ : lookup t₂ 2 ≡ just v₂q₀ = reflq₁ : lookup t₃ 2 ≡ nothingq₁ = reflq₂ : (3 ∈? t₂) ≡ falseq₂ = reflq₃ : (1 ∈? t₄) ≡ trueq₃ = refl-- Turning a tree into a sorted list of key-value pairs.q₄ : toList t₁ ≡ (2 , v₂) ∷ []q₄ = reflq₅ : toList t₂ ≡ (1 , v₁) ∷ (2 , v₂) ∷ []q₅ = reflq₅′ : toList t₂′ ≡ (1 , v₁′) ∷ (2 , v₂) ∷ []q₅′ = refl-------------------------------------------------------------------------- Views-- Partitioning a tree into the smallest element plus the rest, or the-- largest element plus the rest.open import Function.Base using (id)v₆ : headTail t₀ ≡ nothingv₆ = reflv₇ : Maybe.map (Product.map₂ toList) (headTail t₂) ≡just ((1 , v₁) , ((2 , v₂) ∷ []))v₇ = reflv₈ : initLast t₀ ≡ nothingv₈ = reflv₉ : Maybe.map (Product.map₁ toList) (initLast t₄) ≡just (((1 , v₁) ∷ []) ,′ (2 , v₂))v₉ = refl-------------------------------------------------------------------------- Further reading-- Variations of the AVL tree module are available:-- • Finite maps with indexed keys and values.import Data.Tree.AVL.IndexedMap-- • Finite sets.import Data.Tree.AVL.Sets
-------------------------------------------------------------------------- The Agda standard library---- An example of how the Record module can be used-------------------------------------------------------------------------- Taken from Randy Pollack's paper "Dependently Typed Records in Type-- Theory".{-# OPTIONS --with-K #-}module README.Data.Record whereopen import Data.Product.Base using (_,_)open import Data.Stringopen import Function.Base using (flip)open import Levelopen import Relation.Binary.Definitions using (Symmetric; Transitive)import Data.Record as Record-- Let us use strings as labels.open Record String _≟_-- Partial equivalence relations.PER : Signature _PER = ∅ , "S" ∶ (λ _ → Set), "R" ∶ (λ r → r · "S" → r · "S" → Set), "sym" ∶ (λ r → Lift _ (Symmetric (r · "R"))), "trans" ∶ (λ r → Lift _ (Transitive (r · "R")))-- Given a PER the converse relation is also a PER.converse : (P : Record PER) →Record (PER With "S" ≔ (λ _ → P · "S")With "R" ≔ (λ _ → flip (P · "R")))converse P =rec (rec (_ ,lift λ {_} → lower (P · "sym")) ,lift λ {_} yRx zRy → lower (P · "trans") zRy yRx)
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing where the natural numbers and some related-- operations and properties are defined, and how they can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module README.Data.Nat where-- The natural numbers and various arithmetic operations are defined-- in Data.Nat.open import Data.Nat using (ℕ; _+_; _*_)-- _*_ has precedence 7 over precedence 6 of _+_-- precedence of both defined in module Agda.Builtin.Natex₁ : ℕex₁ = 1 + 3 * 4-- Propositional equality and some related properties can be found-- in Relation.Binary.PropositionalEquality.open import Relation.Binary.PropositionalEquality using (_≡_; refl)ex₂ : 3 + 5 ≡ 2 * 4ex₂ = refl-- Data.Nat.Properties contains a number of properties about natural-- numbers.open import Data.Nat.Properties using (*-comm; +-identityʳ)ex₃ : ∀ m n → m * n ≡ n * mex₃ m n = *-comm m n-- The module ≡-Reasoning in Relation.Binary.PropositionalEquality-- provides some combinators for equational reasoning.open Relation.Binary.PropositionalEquality using (cong; module ≡-Reasoning)ex₄ : ∀ m n → m * (n + 0) ≡ n * mex₄ m n = beginm * (n + 0) ≡⟨ cong (_*_ m) (+-identityʳ n) ⟩m * n ≡⟨ *-comm m n ⟩n * m ∎where open ≡-Reasoning-- The module SemiringSolver in Data.Nat.Solver contains a solver-- for natural number equalities involving variables, constants, _+_-- and _*_.open import Data.Nat.Solver using (module +-*-Solver)open +-*-Solver using (solve; _:*_; _:+_; con; _:=_)ex₅ : ∀ m n → m * (n + 0) ≡ n * mex₅ = solve 2 (λ m n → m :* (n :+ con 0) := n :* m) refl
-------------------------------------------------------------------------- The Agda standard library---- Some examples of how to use non-trivial induction over the natural-- numbers.------------------------------------------------------------------------module README.Data.Nat.Induction whereopen import Data.Natopen import Data.Nat.Inductionopen import Data.Product.Base using (_,_)open import Function.Base using (_∘_)open import Induction.WellFoundedopen import Relation.Binary.PropositionalEqualityprivaten<′1+n : ∀ {n} → n <′ suc nn<′1+n = ≤′-refln<′2+n : ∀ {n} → n <′ suc (suc n)n<′2+n = ≤′-step ≤′-refl-- Doubles its input.twice : ℕ → ℕtwice = rec _ λ{ zero _ → zero; (suc n) twice-n → suc (suc twice-n)}-- Halves its input (rounding downwards).---- The step function is mentioned in a proof below, so it has been-- given a name. (The mutual keyword is used to avoid having to give-- a type signature for the step function.)mutualhalf₁-step = λ{ zero _ → zero; (suc zero) _ → zero; (suc (suc n)) (_ , half₁n , _) → suc half₁n}half₁ : ℕ → ℕhalf₁ = cRec _ half₁-step-- An alternative implementation of half₁.mutualhalf₂-step = λ{ zero _ → zero; (suc zero) _ → zero; (suc (suc n)) rec → suc (rec n<′2+n)}half₂ : ℕ → ℕhalf₂ = <′-rec _ half₂-step-- The application half₁ (2 + n) is definitionally equal to-- 1 + half₁ n. Perhaps it is instructive to see why.half₁-2+ : ∀ n → half₁ (2 + n) ≡ 1 + half₁ nhalf₁-2+ n = beginhalf₁ (2 + n) ≡⟨⟩cRec _ half₁-step (2 + n) ≡⟨⟩half₁-step (2 + n) (cRecBuilder _ half₁-step (2 + n)) ≡⟨⟩half₁-step (2 + n)(let ih = cRecBuilder _ half₁-step (1 + n) inhalf₁-step (1 + n) ih , ih) ≡⟨⟩half₁-step (2 + n)(let ih = cRecBuilder _ half₁-step n inhalf₁-step (1 + n) (half₁-step n ih , ih) , half₁-step n ih , ih) ≡⟨⟩1 + half₁-step n (cRecBuilder _ half₁-step n) ≡⟨⟩1 + cRec _ half₁-step n ≡⟨⟩1 + half₁ n ∎where open ≡-Reasoning-- The application half₂ (2 + n) is definitionally equal to-- 1 + half₂ n. Perhaps it is instructive to see why.half₂-2+ : ∀ n → half₂ (2 + n) ≡ 1 + half₂ nhalf₂-2+ n = beginhalf₂ (2 + n) ≡⟨⟩<′-rec _ half₂-step (2 + n) ≡⟨⟩half₂-step (2 + n) (<′-recBuilder _ half₂-step (2 + n)) ≡⟨⟩1 + <′-recBuilder _ half₂-step (2 + n) n<′2+n ≡⟨⟩1 + Some.wfRecBuilder _ half₂-step (2 + n)(<′-wellFounded (2 + n)) n<′2+n ≡⟨⟩1 + Some.wfRecBuilder _ half₂-step (2 + n)(acc (<′-wellFounded′ (2 + n))) n<′2+n ≡⟨⟩1 + half₂-step n(Some.wfRecBuilder _ half₂-step n(<′-wellFounded′ (2 + n) n<′2+n)) ≡⟨⟩1 + half₂-step n(Some.wfRecBuilder _ half₂-step n(<′-wellFounded′ (1 + n) n<′1+n)) ≡⟨⟩1 + half₂-step n(Some.wfRecBuilder _ half₂-step n (<′-wellFounded n)) ≡⟨⟩1 + half₂-step n (<′-recBuilder _ half₂-step n) ≡⟨⟩1 + <′-rec _ half₂-step n ≡⟨⟩1 + half₂ n ∎where open ≡-Reasoning-- Some properties that the functions above satisfy, proved using-- cRec.half₁-+₁ : ∀ n → half₁ (twice n) ≡ nhalf₁-+₁ = cRec _ λ{ zero _ → refl; (suc zero) _ → refl; (suc (suc n)) (_ , half₁twice-n≡n , _) →cong (suc ∘ suc) half₁twice-n≡n}half₂-+₁ : ∀ n → half₂ (twice n) ≡ nhalf₂-+₁ = cRec _ λ{ zero _ → refl; (suc zero) _ → refl; (suc (suc n)) (_ , half₁twice-n≡n , _) →cong (suc ∘ suc) half₁twice-n≡n}-- Some properties that the functions above satisfy, proved using-- <′-rec.half₁-+₂ : ∀ n → half₁ (twice n) ≡ nhalf₁-+₂ = <′-rec _ λ{ zero _ → refl; (suc zero) _ → refl; (suc (suc n)) rec →cong (suc ∘ suc) (rec n<′2+n)}half₂-+₂ : ∀ n → half₂ (twice n) ≡ nhalf₂-+₂ = <′-rec _ λ{ zero _ → refl; (suc zero) _ → refl; (suc (suc n)) rec →cong (suc ∘ suc) (rec n<′2+n)}
-------------------------------------------------------------------------- The Agda standard library---- Documentation for the List type------------------------------------------------------------------------module README.Data.List whereopen import Data.Nat.Base using (ℕ; _+_)open import Relation.Binary.PropositionalEquality using (_≡_; refl)-------------------------------------------------------------------------- 1. Basics-------------------------------------------------------------------------- The `List` datatype is exported by the following file:open import Data.Listusing(List; []; _∷_; sum; map; take; reverse; _++_; drop)-- Lists are built using the "[]" and "_∷_" constructors.list₁ : List ℕlist₁ = 3 ∷ 1 ∷ 2 ∷ []-- Basic operations over lists are also exported by the same file.lem₁ : sum list₁ ≡ 6lem₁ = refllem₂ : map (_+ 2) list₁ ≡ 5 ∷ 3 ∷ 4 ∷ []lem₂ = refllem₃ : take 2 list₁ ≡ 3 ∷ 1 ∷ []lem₃ = refllem₄ : reverse list₁ ≡ 2 ∷ 1 ∷ 3 ∷ []lem₄ = refllem₅ : list₁ ++ list₁ ≡ 3 ∷ 1 ∷ 2 ∷ 3 ∷ 1 ∷ 2 ∷ []lem₅ = refl-- Various basic properties of these operations can be found in:open import Data.List.Propertieslem₆ : ∀ n (xs : List ℕ) → take n xs ++ drop n xs ≡ xslem₆ = take++drop≡idlem₇ : ∀ (xs : List ℕ) → reverse (reverse xs) ≡ xslem₇ = reverse-involutivelem₈ : ∀ (xs ys zs : List ℕ) → (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)lem₈ = ++-assoc-------------------------------------------------------------------------- 2. Unary relations over lists-------------------------------------------------------------------------- Unary relations in `Data.List.Relation.Unary` are used to reason-- about the properties of an individual list.-------------------------------------------------------------------------- Any-- The predicate `Any` encodes the idea of at least one element of a-- given list satisfying a given property (or more formally a-- predicate, see the `Pred` type in `Relation.Unary`).import README.Data.List.Relation.Unary.Any-------------------------------------------------------------------------- All-- The dual to `Any` is the predicate `All` which encodes the idea that-- every element in a given list satisfies a given property.import README.Data.List.Relation.Unary.All-------------------------------------------------------------------------- Other unary relations-- There exist many other unary relations in the-- `Data.List.Relation.Unary` folder, including:-- 1. lists with every pair of elements relatedimport Data.List.Relation.Unary.AllPairs-- 2. lists with only unique elementsimport Data.List.Relation.Unary.Unique.Setoid-- 3. lists with each pair of neighbouring elements relatedimport Data.List.Relation.Unary.Linked-------------------------------------------------------------------------- 3. Binary relations over lists-------------------------------------------------------------------------- Binary relations relate two different lists, and are found in the-- folder `Data.List.Relation.Binary`.-------------------------------------------------------------------------- Pointwise-- One of the most basic ways to form a binary relation between two-- lists of type `List A`, given a binary relation over `A`, is to say-- that two lists are related if they are the same length and:-- i) the first elements in the lists are related-- ii) the second elements in the lists are related-- iii) the third elements in the lists are related etc.-- etc.-- This is known as the pointwise lifting of a relationimport README.Data.List.Relation.Binary.Pointwise-------------------------------------------------------------------------- Equality-- There are many different options for what it means for two-- different lists of type `List A` to be "equal". We will initially-- consider notions of equality that require the list elements to be-- pointwise equal.import README.Data.List.Relation.Binary.Equality-------------------------------------------------------------------------- Permutations-- Alternatively you might consider two lists to be equal if they-- contain the same elements regardless of the order of the elements.-- This is known as either "set equality" or a "permutation".import README.Data.List.Relation.Binary.Permutation-------------------------------------------------------------------------- Subsets-- Instead one might want to order lists by the subset relation which-- forms a partial order over lists. One list is a subset of another if-- every element in the first list occurs at least once in the second.import README.Data.List.Relation.Binary.Subset-------------------------------------------------------------------------- Other binary relations-- There exist many other binary relations in the-- `Data.List.Relation.Binary` folder, including:-- 1. lexicographic orderingsimport Data.List.Relation.Binary.Lex.Strict-- 2. bag/multiset equalityimport Data.List.Relation.Binary.BagAndSetEquality-- 3. the sublist relationsimport Data.List.Relation.Binary.Sublist.Propositional-------------------------------------------------------------------------- 4. Ternary relations over lists-------------------------------------------------------------------------- Ternary relations relate three different lists, and are found in the-- folder `Data.List.Relation.Ternary`.-------------------------------------------------------------------------- Interleaving-- Given two lists, a third list is an `Interleaving` of them if there-- exists an order preserving partition of it that reconstructs the-- original two lists.import README.Data.List.Relation.Ternary.Interleaving-------------------------------------------------------------------------- 5. Membership-------------------------------------------------------------------------- Although simply a specialisation of the unary predicate `Any`,-- membership of a list is not strictly a unary or a binary relation-- over lists. Therefore it lives it it's own top-level folder.import README.Data.List.Membership
-------------------------------------------------------------------------- The Agda standard library---- Documentation for the `Any` predicate over `List`------------------------------------------------------------------------module README.Data.List.Relation.Unary.Any whereopen import Data.List.Base using ([]; _∷_)open import Data.Nat.Base using (ℕ; _+_; _<_; s≤s; z≤n; _*_; _∸_; _≤_)open import Data.Nat.Properties using (≤-trans; n≤1+n)-------------------------------------------------------------------------- Any-- The predicate `Any` encodes the idea of at least one element of a-- given list satisfying a given property (or more formally a-- predicate, see the `Pred` type in `Relation.Unary`).open import Data.List.Relation.Unary.Any as Any-- A proof of type Any consists of a sequence of the "there"-- constructors, which says that the element lies in the remainder of-- the list, followed by a single "here" constructor which indicates-- that the head of the list satisfies the predicate and takes a proof-- that it does so.-- For example a proof that a given list of natural numbers contains-- at least one number greater than or equal to 4 can be written as-- follows:lem₁ : Any (4 ≤_) (3 ∷ 5 ∷ 1 ∷ 6 ∷ [])lem₁ = there (here 4≤5)where4≤5 = s≤s (s≤s (s≤s (s≤s z≤n)))-- Note that nothing requires that the proof of `Any` points at the-- first such element in the list. There is therefore an alternative-- proof for the above lemma which points to 6 instead of 5.lem₂ : Any (4 ≤_) (3 ∷ 5 ∷ 1 ∷ 6 ∷ [])lem₂ = there (there (there (here 4≤6)))where4≤6 = s≤s (s≤s (s≤s (s≤s z≤n)))-- There also exist various operations over proofs of `Any` whose names-- shadow the corresponding list operation. The standard way of using-- these is to use `as` to name the module:import Data.List.Relation.Unary.Any as Any-- and then use the qualified name `Any.map`. For example, map can-- be used to change the predicate of `Any`:lem₃ : Any (3 ≤_) (3 ∷ 5 ∷ 1 ∷ 6 ∷ [])lem₃ = Any.map 4≤x⇒3≤x lem₂where4≤x⇒3≤x : ∀ {x} → 4 ≤ x → 3 ≤ x4≤x⇒3≤x = ≤-trans (n≤1+n 3)-- Properties of how list functions interact with `Any` can be-- found in:import Data.List.Relation.Unary.Any.Properties
-------------------------------------------------------------------------- The Agda standard library---- Documentation for the `All` predicate over `List`------------------------------------------------------------------------module README.Data.List.Relation.Unary.All whereopen import Data.List.Base using ([]; _∷_)open import Data.Nat using (ℕ; s≤s; z≤n; _≤_)open import Data.Nat.Properties using (≤-trans; n≤1+n)-------------------------------------------------------------------------- All-- The dual to `Any` is the predicate `All` which encodes the idea that-- every element in a given list satisfies a given property.open import Data.List.Relation.Unary.All-- Proofs for `All` are constructed using exactly the same syntax as-- is used to construct lists ("[]" & "_∷_"). For example to prove-- that every element in a list is less than or equal to one:lem₁ : All (_≤ 1) (1 ∷ 0 ∷ 1 ∷ [])lem₁ = 1≤1 ∷ 0≤1 ∷ 1≤1 ∷ []where0≤1 = z≤n1≤1 = s≤s z≤n-- As with `Any`, the module also provides the standard operators-- `map`, `zip` etc. to manipulate proofs for `All`.import Data.List.Relation.Unary.All as Alllem₂ : All (_≤ 2) (1 ∷ 0 ∷ 1 ∷ [])lem₂ = All.map ≤1⇒≤2 lem₁where≤1⇒≤2 : ∀ {x} → x ≤ 1 → x ≤ 2≤1⇒≤2 x≤1 = ≤-trans x≤1 (n≤1+n 1)-- Properties of how list functions interact with `All` can be-- found in:import Data.List.Relation.Unary.All.Properties
-------------------------------------------------------------------------- The Agda standard library---- Examples showing how the notion of Interleaving can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.List.Relation.Ternary.Interleaving whereopen import Levelopen import Data.List.Base hiding (filter)open import Data.List.Relation.Unary.Allopen import Functionopen import Relation.Nullaryopen import Relation.Unary-------------------------------------------------------------------------- Interleaving-- In its most general form, `Interleaving` is parametrised by two-- relations `L` (for Left) and `R` (for Right). Given three lists,-- `xs`, `ys` and `zs`, a proof of `Interleaving xs ys zs` is-- essentially a diagram explaining how `zs` can be pulled apart into-- `xs` and `ys` in a way compatible with `L` and `R`. For instance:-- xs zs ys---- x₁ -- L x₁ z₁ -- z₁-- x₂ -- L x₂ z₂ -- z₂-- z₃ -- R z₃ z₁ -- y₁-- x₃ -- L x₃ z₄ -- z₄-- z₅ -- R z₅ y₂ -- y₂open import Data.List.Relation.Ternary.Interleaving.Propositional-- The special case we will focus on here is the propositional case: both-- `L` and ̀R` are propositional equality. Rethinking our previous example,-- this gives us the proof that [z₁, ⋯, z₅] can be partitioned into-- [z₁, z₂, z₄] on the one hand and [z₃, z₅] in the other.-- One possible use case for such a relation is the definition of a very-- precise filter function. Provided a decidable predicate `P`, it will-- prove not only that the retained values satisfy `P` but that the ones-- that didn't make the cut satisfy the negation of P.-- We can make this formal by defining the following record type:infix 3 _≡_⊎_record Filter {a p} {A : Set a} (P : Pred A p) (xs : List A) : Set (a ⊔ p) whereconstructor _≡_⊎_field-- The result of running filter is two lists:-- * the elements we have kept-- * and the ones we have thrown away-- We leave these implicit: they can be inferred from the rest{kept} : List A{thrown} : List A-- There is a way for us to recover the original-- input by interleaving the two listscover : Interleaving kept thrown xs-- Finally, the partition was made according to the predicateallP : All P keptall¬P : All (∁ P) thrown-- Once we have this type written down, we can write the function.-- We use an anonymous module to clean up the function's type.module _ {a p} {A : Set a} {P : Pred A p} (P? : Decidable P) wherefilter : ∀ xs → Filter P xs-- If the list is empty, we are done.filter [] = [] ≡ [] ⊎ []filter (x ∷ xs) =-- otherwise we start by running filter on the taillet xs′ ≡ ps ⊎ ¬ps = filter xs in-- And depending on whether `P` holds of the head,-- we cons it to the `kept` or `thrown` list.case P? x of λ where -- [1](yes p) → consˡ xs′ ≡ p ∷ ps ⊎ ¬ps(no ¬p) → consʳ xs′ ≡ ps ⊎ ¬p ∷ ¬ps-- [1] See the following module for explanations of `case_of_` and-- pattern-matching lambdasimport README.Case
-------------------------------------------------------------------------- The Agda standard library---- Documentation for subset relations over `List`s------------------------------------------------------------------------open import Data.List.Base using (List; _∷_; [])open import Data.List.Membership.Propositional.Propertiesusing (∈-++⁺ˡ; ∈-insert)open import Data.List.Relation.Binary.Subset.Propositional using (_⊆_)open import Data.List.Relation.Unary.Any using (here; there)open import Relation.Binary.PropositionalEquality using (refl)module README.Data.List.Relation.Binary.Subset where-------------------------------------------------------------------------- Subset Relation-- The Subset relation is a wrapper over `Any` and so is parameterized-- over an equality relation. Thus to use the subset relation we must-- tell Agda which equality relation to use.-- Decidable equality over Stringsopen import Data.String.Base using (String)open import Data.String.Properties using (_≟_)-- Open the decidable membership module using Decidable ≡ over Stringsopen import Data.List.Membership.DecPropositional _≟_-- Simple cases are inductive proofslem₁ : ∀ {xs : List String} → xs ⊆ xslem₁ p = plem₂ : "A" ∷ [] ⊆ "B" ∷ "A" ∷ []lem₂ p = there p-- Or directly use the definition of subsetslem₃₀ : "E" ∷ "S" ∷ "B" ∷ [] ⊆ "S" ∷ "U" ∷ "B" ∷ "S" ∷ "E" ∷ "T" ∷ []lem₃₀ (here refl) = there (there (there (there (here refl)))) -- "E"lem₃₀ (there (here refl)) = here refl -- "S"lem₃₀ (there (there (here refl))) = there (there (here refl)) -- "B"-- Or use proofs from `Data.List.Membership.Propositional.Properties`lem₄ : "A" ∷ [] ⊆ "B" ∷ "A" ∷ "C" ∷ []lem₄ p = ∈-++⁺ˡ (there p)lem₅ : "B" ∷ "S" ∷ "E" ∷ [] ⊆ "S" ∷ "U" ∷ "B" ∷ "S" ∷ "E" ∷ "T" ∷ []lem₅ p = ∈-++⁺ˡ (there (there p))lem₃₁ : "E" ∷ "S" ∷ "B" ∷ [] ⊆ "S" ∷ "U" ∷ "B" ∷ "S" ∷ "E" ∷ "T" ∷ []lem₃₁ (here refl) = ∈-insert ("S" ∷ "U" ∷ "B" ∷ "S" ∷ [])lem₃₁ (there (here refl)) = here refllem₃₁ (there (there (here refl))) = ∈-insert ("S" ∷ "U" ∷ [])
-------------------------------------------------------------------------- The Agda standard library---- Documentation for pointwise lifting of relations over `List`s------------------------------------------------------------------------module README.Data.List.Relation.Binary.Pointwise whereopen import Data.Nat using (ℕ; _<_; s≤s; z≤n)open import Data.List.Base using (List; []; _∷_; length)open import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; setoid)open import Relation.Nullary.Negation using (¬_)-------------------------------------------------------------------------- Pointwise-- One of the most basic ways to form a binary relation between two-- lists of type `List A`, given a binary relation over `A`, is to say-- that two lists are related if they are the same length and:-- i) the first elements in the lists are related-- ii) the second elements in the lists are related-- iii) the third elements in the lists are related etc.-- etc.---- A formalisation of this "pointwise" lifting of a relation to lists-- is found in:open import Data.List.Relation.Binary.Pointwise-- The same syntax to construct a list (`[]` & `_∷_`) is used to-- construct proofs for the `Pointwise` relation. For example if you-- want to prove that one list is strictly less than another list:lem₁ : Pointwise _<_ (0 ∷ 2 ∷ 1 ∷ []) (1 ∷ 4 ∷ 2 ∷ [])lem₁ = 0<1 ∷ 2<4 ∷ 1<2 ∷ []where0<1 = s≤s z≤n2<4 = s≤s (s≤s (s≤s z≤n))1<2 = s≤s 0<1-- Lists that are related by `Pointwise` must be of the same length.-- For example:lem₂ : ¬ Pointwise _<_ (0 ∷ 2 ∷ []) (1 ∷ [])lem₂ (0<1 ∷ ())-- Proofs about pointwise, including that of the above fact are-- also included in the module:lem₃ : ∀ {xs ys} → Pointwise _<_ xs ys → length xs ≡ length yslem₃ = Pointwise-length
-------------------------------------------------------------------------- The Agda standard library---- Documentation for permutation over `List`s------------------------------------------------------------------------module README.Data.List.Relation.Binary.Permutation whereopen import Algebra.Structures using (IsCommutativeMonoid)open import Data.List.Baseopen import Data.Nat using (ℕ; _+_)open import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; setoid)-------------------------------------------------------------------------- Permutations-- As an alternative to pointwise equality you might consider two lists-- to be equal if they contain the same elements regardless of the order-- of the elements. This is known as either "set equality" or a-- "permutation".-- The easiest-to-use formalisation of this relation is found in the-- module:open import Data.List.Relation.Binary.Permutation.Propositional-- The permutation relation is written as `_↭_` and has four-- constructors. The first `refl` says that a list is always-- a permutation of itself, the second `prep` says that if the-- heads of the lists are the same they can be skipped, the third-- `swap` says that the first two elements of the lists can be-- swapped and the fourth `trans` says that permutation proofs-- can be chained transitively.-- For example a proof that two lists are a permutation of one-- another can be written as follows:lem₁ : 1 ∷ 2 ∷ 3 ∷ [] ↭ 3 ∷ 1 ∷ 2 ∷ []lem₁ = trans (prep 1 (swap 2 3 refl)) (swap 1 3 refl)-- In practice it is difficult to parse the constructors in the-- proof above and hence understand why it holds. The-- `PermutationReasoning` module can be used to write this proof-- in a much more readable form:open PermutationReasoninglem₂ : 1 ∷ 2 ∷ 3 ∷ [] ↭ 3 ∷ 1 ∷ 2 ∷ []lem₂ = begin1 ∷ 2 ∷ 3 ∷ [] ↭⟨ prep 1 (swap 2 3 refl) ⟩1 ∷ 3 ∷ 2 ∷ [] ↭⟨ swap 1 3 refl ⟩3 ∷ 1 ∷ 2 ∷ [] ∎-- As might be expected, properties of the permutation relation may be-- found in:open import Data.List.Relation.Binary.Permutation.Propositional.Propertiesusing (map⁺; ++-isCommutativeMonoid)lem₃ : ∀ (f : ℕ → ℕ) {xs ys : List ℕ} → xs ↭ ys → map f xs ↭ map f yslem₃ = map⁺lem₄ : IsCommutativeMonoid {A = List ℕ} _↭_ _++_ []lem₄ = ++-isCommutativeMonoid-- Alternatively permutations using non-propositional equality can be-- found in:import Data.List.Relation.Binary.Permutation.Setoid
-------------------------------------------------------------------------- The Agda standard library---- Documentation for pointwise equality over `List`s------------------------------------------------------------------------{-# OPTIONS --allow-unsolved-metas #-}module README.Data.List.Relation.Binary.Equality whereopen import Data.Nat using (ℕ; _+_; _<_; s≤s; z≤n; _*_; _∸_; _≤_)open import Data.Nat.Properties as ℕopen import Data.List.Base-------------------------------------------------------------------------- Pointwise equality-- There are many different options for what it means for two-- different lists of type `List A` to be "equal". Here we will-- consider "pointwise" equality that requires the lists to be the-- same length and every pair of elements to be "equal".-- The most basic option is simply to use propositional equality-- `_≡_` over lists:open import Relation.Binary.PropositionalEqualityusing (_≡_; sym; refl)lem₁ : 1 ∷ 2 ∷ 3 ∷ [] ≡ 1 ∷ 2 ∷ 3 ∷ []lem₁ = refl-- However propositional equality is only suitable when we want to-- use propositional equality to compare the individual elements.-- Although a contrived example, consider trying to prove the-- equality of two lists of the type `List (ℕ → ℕ)`:lem₂ : (λ x → 2 * x + 2) ∷ [] ≡ (λ x → 2 * (x + 1)) ∷ []lem₂ = {!!}-- In such a case it is impossible to prove the two lists equal with-- refl as the two functions are not propositionally equal. In the-- absence of postulating function extensionality (see README.Axioms),-- the most common definition of function equality is to say that two-- functions are equal if their outputs are always propositionally-- equal for any input. This notion of function equality `_≗_` is-- found in:open import Relation.Binary.PropositionalEquality using (_≗_)-- We now want to use the `Pointwise` relation to say that the two-- lists are equal if their elements are pointwise equal with resepct-- to `_≗_`. However instead of using the pointwise module directly-- to write:open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise)lem₃ : Pointwise _≗_ ((λ x → x + 1) ∷ []) ((λ x → x + 2 ∸ 1) ∷ [])lem₃ = {!!}-- the library provides some nicer wrappers and infix notation in the-- folder "Data.List.Relation.Binary.Equality".-- Within this folder there are four different modules.import Data.List.Relation.Binary.Equality.Setoid as SetoidEqimport Data.List.Relation.Binary.Equality.DecSetoid as DecSetoidEqimport Data.List.Relation.Binary.Equality.Propositional as PropEqimport Data.List.Relation.Binary.Equality.DecPropositional as DecPropEq-- Which one should be used depends on whether the underlying equality-- over "A" is:-- i) propositional or setoid-based-- ii) decidable.-- Each of the modules except `PropEq` are designed to be opened with a-- module parameter. This is to avoid having to specify the underlying-- equality relation or the decidability proofs every time you use the-- list equality.-- In our example function equality is not decidable and not propositional-- and so we want to use the `SetoidEq` module. This requires a proof that-- the `_≗_` relation forms a setoid over functions of the type `ℕ → ℕ`.-- This is found in:open import Relation.Binary.PropositionalEquality using (_→-setoid_)-- The `SetoidEq` module should therefore be opened as follows:open SetoidEq (ℕ →-setoid ℕ)-- All four equality modules provide an infix operator `_≋_` for the-- new equality relation over lists. The type of `lem₃` can therefore-- be rewritten as:lem₄ : (λ x → x + 1) ∷ [] ≋ (λ x → x + 2 ∸ 1) ∷ []lem₄ = 2x+2≗2[x+1] ∷ []where2x+2≗2[x+1] : (λ x → x + 1) ≗ (λ x → x + 2 ∸ 1)2x+2≗2[x+1] x = sym (+-∸-assoc x (s≤s z≤n))-- The modules also provide proofs that the `_≋_` relation is a-- setoid in its own right and therefore is reflexive, symmetric,-- transitive:lem₅ : (λ x → 2 * x + 2) ∷ [] ≋ (λ x → 2 * x + 2) ∷ []lem₅ = ≋-refl-- If we could prove that `_≗_` forms a `DecSetoid` then we could use-- the module `DecSetoidEq` instead. This exports everything from-- `SetoidEq` as well as the additional proof `_≋?_` that the list-- equality is decidable.-- This pattern of four modules for each of the four different types-- of equality is repeated throughout the library (e.g. see the-- `Membership`). Note that in this case the modules `PropEq` and-- `DecPropEq` are not very useful as if two lists are pointwise-- propositionally equal they are necessarily propositionally equal-- (and vice-versa). There are proofs of this fact exported by-- `PropEq` and `DecPropEq`. Although, these two types of list equality-- are not very useful in practice, they are included for completeness's-- sake.
-------------------------------------------------------------------------- The Agda standard library---- Documentation for List membership------------------------------------------------------------------------module README.Data.List.Membership whereopen import Data.Char.Base using (Char; fromℕ)open import Data.Char.Properties as Char hiding (setoid)open import Data.List.Base using (List; []; _∷_; map)open import Data.Nat as ℕ using (ℕ)open import Relation.Binary.PropositionalEqualityusing (_≡_; refl; cong; setoid)-------------------------------------------------------------------------- Membership-- Membership of a list is simply a special case of `Any` where-- `x ∈ xs` is defined as `Any (x ≈_) xs`.-- Just like pointwise equality of lists, the exact membership module-- that should be used depends on whether the equality on the-- underlying elements of the list is i) propositional or setoid-based-- and ii) decidable.import Data.List.Membership.Setoid as SetoidMembershipimport Data.List.Membership.DecSetoid as DecSetoidMembershipimport Data.List.Membership.Propositional as PropMembershipimport Data.List.Membership.DecPropositional as DecPropMembership-- For example if we want to reason about membership for `List ℕ`-- then you would use the `DecPropMembership` as we use-- propositional equality over `ℕ` and it is also decidable. Therefore-- the module `DecPropMembership` should be opened as follows:open DecPropMembership ℕ._≟_-- As membership is just an instance of `Any` we also need to import-- the constructors `here` and `there`. (See issue #553 on Github for-- why we're struggling to have `here` and `there` automatically-- re-exported by the membership modules).open import Data.List.Relation.Unary.Any using (here; there)-- These modules provide the infix notation `_∈_` which can be used-- as follows:lem₁ : 1 ∈ 2 ∷ 1 ∷ 3 ∷ []lem₁ = there (here refl)-- Properties of the membership relation can be found in the following-- two files:import Data.List.Membership.Setoid.Properties as SetoidPropertiesimport Data.List.Membership.Propositional.Properties as PropProperties-- As of yet there are no corresponding files for properties of-- membership for decidable versions of setoid and propositional-- equality as we have no properties that only hold when equality is-- decidable.-- These `Properties` modules are NOT parameterised in the same way as-- the main membership modules as some of the properties relate-- membership proofs for lists of different types. For example in the-- following the first `∈` refers to lists of type `List ℕ` whereas-- the second `∈` refers to lists of type `List Char`.open DecPropMembership Char._≟_ renaming (_∈_ to _∈ᶜ_)open SetoidProperties using (∈-map⁺)lem₂ : {v : ℕ} {xs : List ℕ} → v ∈ xs → fromℕ v ∈ᶜ map fromℕ xslem₂ = ∈-map⁺ (setoid ℕ) (setoid Char) (cong fromℕ)
-------------------------------------------------------------------------- The Agda standard library---- Example use case for a fresh list: sorted list------------------------------------------------------------------------{-# OPTIONS --sized-types #-}module README.Data.List.Fresh whereopen import Data.Natopen import Data.List.Baseopen import Data.List.Freshopen import Data.List.Relation.Unary.AllPairs as AllPairs using (AllPairs)open import Data.Product.Base using (_,_; proj₁; proj₂)open import Relation.Nary using (⌊_⌋; fromWitness)-- A sorted list of natural numbers can be seen as a fresh list-- where the notion of freshness is being smaller than all the-- existing entriesSortedList : SetSortedList = List# ℕ _<__ : SortedList_ = cons 0 (cons 1 (cons 3 (cons 10 [] _)(s≤s (s≤s (s≤s (s≤s z≤n))) , _))(s≤s (s≤s z≤n) , s≤s (s≤s z≤n) , _))(s≤s z≤n , s≤s z≤n , s≤s z≤n , _)-- Clearly, writing these by hand can pretty quickly become quite cumbersome-- Luckily, if the notion of freshness we are using is decidable, we can-- make most of the proofs inferrable by using the erasure of the relation-- rather than the relation itself!-- We call this new type *I*SortedList because all the proofs will be implicit.ISortedList : SetISortedList = List# ℕ ⌊ _<?_ ⌋-- The same example is now much shorter. It looks pretty much like a normal list-- except that we know for sure that it is well ordered.ins : ISortedListins = 0 ∷# 1 ∷# 3 ∷# 10 ∷# []-- Indeed we can extract the support list together with a proof that it-- is ordered thanks to the combined action of toList converting a fresh-- list to a pair of a list and a proof and fromWitness which "unerases"-- a proof.ns : List ℕns = proj₁ (toList ins)sorted : AllPairs _<_ nssorted = AllPairs.map (fromWitness _<_ _<?_) (proj₂ (toList ins))-- See the following module for an applied use-case of fresh listsopen import README.Data.Trie.NonDependent
-------------------------------------------------------------------------- The Agda standard library---- Some examples showing where the integers and some related-- operations and properties are defined, and how they can be used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible #-}module README.Data.Integer where-- The integers and various arithmetic operations are defined in-- Data.Integer.open import Data.Integer-- The +_ function converts natural numbers into integers.ex₁ : ℤex₁ = + 2-- The -_ function negates an integer.ex₂ : ℤex₂ = - + 4-- Some binary operators are also defined, including addition,-- subtraction and multiplication.ex₃ : ℤex₃ = + 1 + + 3 * - + 2 - + 4-- Propositional equality and some related properties can be found-- in Relation.Binary.PropositionalEquality.open import Relation.Binary.PropositionalEquality as ≡ using (_≡_)ex₄ : ex₃ ≡ - + 9ex₄ = ≡.refl-- Data.Integer.Properties contains a number of properties related to-- integers. Algebra defines what a commutative ring is, among other-- things.import Data.Integer.Properties as ℤex₅ : ∀ i j → i * j ≡ j * iex₅ i j = ℤ.*-comm i j-- The module ≡-Reasoning in Relation.Binary.PropositionalEquality-- provides some combinators for equational reasoning.open ≡.≡-Reasoningex₆ : ∀ i j → i * (j + + 0) ≡ j * iex₆ i j = begini * (j + + 0) ≡⟨ ≡.cong (i *_) (ℤ.+-identityʳ j) ⟩i * j ≡⟨ ℤ.*-comm i j ⟩j * i ∎-- The module RingSolver in Data.Integer.Solver contains a solver-- for integer equalities involving variables, constants, _+_, _*_, -_-- and _-_.open import Data.Integer.Solver using (module +-*-Solver)open +-*-Solverex₇ : ∀ i j → i * - j - j * i ≡ - + 2 * i * jex₇ = solve 2 (λ i j → i :* :- j :- j :* i := :- con (+ 2) :* i :* j)≡.refl
-------------------------------------------------------------------------- The Agda standard library---- An example of how Data.Fin.Substitution can be used: a definition-- of substitution for the untyped λ-calculus, along with some lemmas------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Fin.Substitution.UntypedLambda whereopen import Data.Fin.Substitutionopen import Data.Fin.Substitution.Lemmasopen import Data.Nat.Base hiding (_/_)open import Data.Fin.Base using (Fin)open import Data.Vec.Baseopen import Relation.Binary.PropositionalEqualityusing (_≡_; refl; sym; cong; cong₂; module ≡-Reasoning)open import Relation.Binary.Construct.Closure.ReflexiveTransitiveusing (Star; ε; _◅_)open ≡-Reasoningprivatevariablem n : ℕ-------------------------------------------------------------------------- A representation of the untyped λ-calculus. Uses de Bruijn indices.infixl 9 _·_data Lam (n : ℕ) : Set wherevar : (x : Fin n) → Lam nƛ : (t : Lam (suc n)) → Lam n_·_ : (t₁ t₂ : Lam n) → Lam n-------------------------------------------------------------------------- Code for applying substitutions.module LamApp {ℓ} {T : ℕ → Set ℓ} (l : Lift T Lam) whereopen Lift l hiding (var)-- Applies a substitution to a term.infixl 8 _/__/_ : Lam m → Sub T m n → Lam nvar x / ρ = lift (lookup ρ x)ƛ t / ρ = ƛ (t / ρ ↑)t₁ · t₂ / ρ = (t₁ / ρ) · (t₂ / ρ)open Application (record { _/_ = _/_ }) using (_/✶_)-- Some lemmas about _/_.ƛ-/✶-↑✶ : ∀ k {t} (ρs : Subs T m n) →ƛ t /✶ ρs ↑✶ k ≡ ƛ (t /✶ ρs ↑✶ suc k)ƛ-/✶-↑✶ k ε = reflƛ-/✶-↑✶ k (ρ ◅ ρs) = cong (_/ _) (ƛ-/✶-↑✶ k ρs)·-/✶-↑✶ : ∀ k {t₁ t₂} (ρs : Subs T m n) →t₁ · t₂ /✶ ρs ↑✶ k ≡ (t₁ /✶ ρs ↑✶ k) · (t₂ /✶ ρs ↑✶ k)·-/✶-↑✶ k ε = refl·-/✶-↑✶ k (ρ ◅ ρs) = cong (_/ _) (·-/✶-↑✶ k ρs)lamSubst : TermSubst LamlamSubst = record { var = var; app = LamApp._/_ }open TermSubst lamSubst hiding (var)-------------------------------------------------------------------------- Substitution lemmas.lamLemmas : TermLemmas LamlamLemmas = record{ termSubst = lamSubst; app-var = refl; /✶-↑✶ = Lemma./✶-↑✶}wheremodule Lemma {T₁ T₂} {lift₁ : Lift T₁ Lam} {lift₂ : Lift T₂ Lam} whereopen Lifted lift₁ using () renaming (_↑✶_ to _↑✶₁_; _/✶_ to _/✶₁_)open Lifted lift₂ using () renaming (_↑✶_ to _↑✶₂_; _/✶_ to _/✶₂_)/✶-↑✶ : (ρs₁ : Subs T₁ m n) (ρs₂ : Subs T₂ m n) →(∀ k x → var x /✶₁ ρs₁ ↑✶₁ k ≡ var x /✶₂ ρs₂ ↑✶₂ k) →∀ k t → t /✶₁ ρs₁ ↑✶₁ k ≡ t /✶₂ ρs₂ ↑✶₂ k/✶-↑✶ ρs₁ ρs₂ hyp k (var x) = hyp k x/✶-↑✶ ρs₁ ρs₂ hyp k (ƛ t) = beginƛ t /✶₁ ρs₁ ↑✶₁ k ≡⟨ LamApp.ƛ-/✶-↑✶ _ k ρs₁ ⟩ƛ (t /✶₁ ρs₁ ↑✶₁ suc k) ≡⟨ cong ƛ (/✶-↑✶ ρs₁ ρs₂ hyp (suc k) t) ⟩ƛ (t /✶₂ ρs₂ ↑✶₂ suc k) ≡⟨ sym (LamApp.ƛ-/✶-↑✶ _ k ρs₂) ⟩ƛ t /✶₂ ρs₂ ↑✶₂ k ∎/✶-↑✶ ρs₁ ρs₂ hyp k (t₁ · t₂) = begint₁ · t₂ /✶₁ ρs₁ ↑✶₁ k ≡⟨ LamApp.·-/✶-↑✶ _ k ρs₁ ⟩(t₁ /✶₁ ρs₁ ↑✶₁ k) · (t₂ /✶₁ ρs₁ ↑✶₁ k) ≡⟨ cong₂ _·_ (/✶-↑✶ ρs₁ ρs₂ hyp k t₁)(/✶-↑✶ ρs₁ ρs₂ hyp k t₂) ⟩(t₁ /✶₂ ρs₂ ↑✶₂ k) · (t₂ /✶₂ ρs₂ ↑✶₂ k) ≡⟨ sym (LamApp.·-/✶-↑✶ _ k ρs₂) ⟩t₁ · t₂ /✶₂ ρs₂ ↑✶₂ k ∎open TermLemmas lamLemmas public hiding (var)
-------------------------------------------------------------------------- The Agda standard library---- Example use of the 'top' view of Fin---- This is an example of a view of (elements of) a datatype,-- here i : Fin (suc n), which exhibits every such i as-- * either, i = fromℕ n-- * or, i = inject₁ j for a unique j : Fin n---- Using this view, we can redefine certain operations in `Data.Fin.Base`,-- together with their corresponding properties in `Data.Fin.Properties`.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Fin.Relation.Unary.Top whereopen import Data.Nat.Base using (ℕ; zero; suc; _∸_; _≤_)open import Data.Nat.Properties using (n∸n≡0; +-∸-assoc; ≤-reflexive)open import Data.Fin.Base using (Fin; zero; suc; toℕ; fromℕ; inject₁; _>_)open import Data.Fin.Properties using (toℕ-fromℕ; toℕ<n; toℕ-inject₁)open import Data.Fin.Induction hiding (>-weakInduction)open import Data.Fin.Relation.Unary.Topimport Induction.WellFounded as WFopen import Level using (Level)open import Relation.Binary.PropositionalEqualityopen import Relation.Unary using (Pred)privatevariableℓ : Leveln : ℕ-------------------------------------------------------------------------- Reimplementation of `Data.Fin.Base.opposite`, and its properties-- Definitionopposite : Fin n → Fin nopposite {suc n} i with view i... | ‵fromℕ = zero... | ‵inject₁ j = suc (opposite {n} j)-- Propertiesopposite-zero≡fromℕ : ∀ n → opposite {suc n} zero ≡ fromℕ nopposite-zero≡fromℕ zero = reflopposite-zero≡fromℕ (suc n) = cong suc (opposite-zero≡fromℕ n)opposite-fromℕ≡zero : ∀ n → opposite {suc n} (fromℕ n) ≡ zeroopposite-fromℕ≡zero n rewrite view-fromℕ n = reflopposite-suc≡inject₁-opposite : (j : Fin n) →opposite (suc j) ≡ inject₁ (opposite j)opposite-suc≡inject₁-opposite {suc n} i with view i... | ‵fromℕ = refl... | ‵inject₁ j = cong suc (opposite-suc≡inject₁-opposite {n} j)opposite-involutive : (j : Fin n) → opposite (opposite j) ≡ jopposite-involutive {suc n} zerorewrite opposite-zero≡fromℕ n| view-fromℕ n = reflopposite-involutive {suc n} (suc i)rewrite opposite-suc≡inject₁-opposite i| view-inject₁ (opposite i) = cong suc (opposite-involutive i)opposite-suc : (j : Fin n) → toℕ (opposite (suc j)) ≡ toℕ (opposite j)opposite-suc j = begintoℕ (opposite (suc j)) ≡⟨ cong toℕ (opposite-suc≡inject₁-opposite j) ⟩toℕ (inject₁ (opposite j)) ≡⟨ toℕ-inject₁ (opposite j) ⟩toℕ (opposite j) ∎ where open ≡-Reasoningopposite-prop : (j : Fin n) → toℕ (opposite j) ≡ n ∸ suc (toℕ j)opposite-prop {suc n} i with view i... | ‵fromℕ rewrite toℕ-fromℕ n | n∸n≡0 n = refl... | ‵inject₁ j = beginsuc (toℕ (opposite j)) ≡⟨ cong suc (opposite-prop j) ⟩suc (n ∸ suc (toℕ j)) ≡⟨ +-∸-assoc 1 (toℕ<n j) ⟨n ∸ toℕ j ≡⟨ cong (n ∸_) (toℕ-inject₁ j) ⟨n ∸ toℕ (inject₁ j) ∎ where open ≡-Reasoning-------------------------------------------------------------------------- Reimplementation of `Data.Fin.Induction.>-weakInduction`open WF using (Acc; acc)>-weakInduction : (P : Pred (Fin (suc n)) ℓ) →P (fromℕ n) →(∀ i → P (suc i) → P (inject₁ i)) →∀ i → P i>-weakInduction P Pₙ Pᵢ₊₁⇒Pᵢ i = induct (>-wellFounded i)whereinduct : ∀ {i} → Acc _>_ i → P iinduct {i} (acc rec) with view i... | ‵fromℕ = Pₙ... | ‵inject₁ j = Pᵢ₊₁⇒Pᵢ j (induct (rec _ inject₁[j]+1≤[j+1]))whereinject₁[j]+1≤[j+1] : suc (toℕ (inject₁ j)) ≤ toℕ (suc j)inject₁[j]+1≤[j+1] = ≤-reflexive (toℕ-inject₁ (suc j))
-------------------------------------------------------------------------- The Agda standard library---- An example showing how to define a function taking an optional-- argument that default to a specified value if none is passed.------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Data.Default whereopen import Data.Defaultopen import Data.Nat.Base hiding (_!)open import Relation.Binary.PropositionalEquality-- An argument of type `WithDefault {a} {A} x` is an argument of type-- `A` that happens to default to `x` if no other value is specified-- Note that you will only get this behaviour if the `default` instance-- is in scope so you should either import `Data.Default` in your client-- modules or publicly re-export the type and the instance!-- `inc` increments its argument by the value `step`, defaulting to 1inc : {{step : WithDefault 1}} → ℕ → ℕinc {{step}} n = step .value + n-- and indeed incrementing 2 gives you 3_ : inc 2 ≡ 3_ = refl-- but you can also insist that you want to use a bigger increment by-- passing the `step` argument explicitly_ : inc {{10 !}} 2 ≡ 12_ = refl
-------------------------------------------------------------------------- The Agda standard library---- Example showing how to define an indexed container------------------------------------------------------------------------{-# OPTIONS --with-K --safe --guardedness #-}module README.Data.Container.Indexed.VectorExample whereopen import Data.Unitopen import Data.Emptyopen import Data.Nat.Baseopen import Data.Product.Base using (_,_)open import Function.Base using (_∋_)open import Data.W.Indexedopen import Data.Container.Indexedopen import Data.Container.Indexed.WithKmodule _ {a} (A : Set a) where-------------------------------------------------------------------------- Vector as an indexed container-- An indexed container is defined by three things:-- 1. Commands the user can emit-- 2. Responses the indexed container returns to these commands-- 3. Update of the index based on the command and the response issued.-- For a vector, commands are constructors, responses are the number-- of subvectors (0 if the vector is empty, 1 otherwise) and the-- update corresponds to setting the size of the tail (if it exists).-- We can formalize these ideas like so:-- Depending on the size of the vector, we may have reached the end-- already (nil) or we may specify what the head should be (cons).-- This is the type of commands.data VecC : ℕ → Set a wherenil : VecC zerocons : ∀ n → A → VecC (suc n)Vec : Container ℕ ℕ a _Command Vec = VecC-- We then treat each command independently, specifying both the response and the-- next index based on that response.-- In the nil case, the response is the empty type: there won't be any tail. As-- a consequence, the next index won't be needed (and we can rely on the fact the-- user will never be able to call it).Response Vec nil = ⊥next Vec nil = λ ()-- In the cons case, the response is the unit type: there is exactly one tail. The-- next index is the predecessor of the current one. It is handily handed over to-- use by `cons`.-- consResponse Vec (cons n a) = ⊤next Vec (cons n a) = λ _ → n-- Finally we can define the type of Vector as the least fixed point of Vec.Vector : ℕ → Set aVector = μ Vecmodule _ {a} {A : Set a} where-- We can recover the usual constructors by using `sup` to enter the fixpoint-- and then using the appropriate pairing of a command & a handler for the-- response.-- For [], the response is ⊥ which makes it easy to conclude.[] : Vector A 0[] = sup (nil , λ ())-- For _∷_, the response is ⊤ so we need to pass a tail. We give the one we took-- as an argument.infixr 3 _∷__∷_ : ∀ {n} → A → Vector A n → Vector A (suc n)x ∷ xs = sup (cons _ x , λ _ → xs)-- We can now use these constructors to build up vectors:1⋯3 : Vector ℕ 31⋯3 = 1 ∷ 2 ∷ 3 ∷ []-- Horrible thing to check the definition of _∈_ is not buggy.-- Not sure whether we can say anything interesting about it in the case of Vector...open import Relation.Binary.HeterogeneousEquality_ : _∈_ {C = Vec ℕ} {X = Vector ℕ} 1⋯3 (⟦ Vec ℕ ⟧ (Vector ℕ) 4 ∋ cons _ 0 , λ _ → 1⋯3)_ = _ , refl
-------------------------------------------------------------------------- The Agda standard library---- Example of multi-sorted algebras as indexed containers------------------------------------------------------------------------{-# OPTIONS --safe --cubical-compatible #-}module README.Data.Container.Indexed.MultiSortedAlgebraExample where-------------------------------------------------------------------------- Preliminaries-------------------------------------------------------------------------- We import library content for indexed containers, standard types,-- and setoids.open import Levelopen import Data.Container.Indexed.Core using (Container; ⟦_⟧; _◃_/_)open import Data.Container.Indexed.FreeMonad using (_⋆C_)open import Data.W.Indexed using (W; sup)open import Data.Product using (Σ; _×_; _,_; Σ-syntax)open import Data.Sum using (_⊎_; inj₁; inj₂; [_,_])open import Data.Empty.Polymorphic using (⊥; ⊥-elim)open import Function using (_∘_)open import Function.Bundles using (Func)open import Relation.Binary using (Setoid; IsEquivalence)open import Relation.Binary.PropositionalEquality using (_≡_; refl)import Data.Container.Indexed.Relation.Binary.Equality.Setoid as ICSetoidimport Relation.Binary.Reasoning.Setoid as SetoidReasoningopen Setoid using (Carrier; _≈_; isEquivalence)open Func renaming (to to apply)-- Letter ℓ denotes universe levels.variableℓ ℓ' ℓˢ ℓᵒ ℓᵃ ℓᵐ ℓᵉ ℓⁱ : LevelI : Set ℓⁱS : Set ℓˢ-------------------------------------------------------------------------- The interpretation of a container (Op ◃ Ar / sort) is---- ⟦ Op ◃ Ar / sort ⟧ X s = Σ[ o ∈ Op s ] ((i : Ar o) → X (sort o i))---- which contains pairs consisting of an operator $o$ and its collection-- of arguments. The least fixed point of (X ↦ ⟦ C ⟧ X) is the indexed-- W-type given by C, and it contains closed first-order terms of the-- multi-sorted algebra C.-- We need to interpret indexed containers on Setoids.-- This definition is missing from the standard library v1.7.⟦_⟧s : (C : Container I S ℓᵒ ℓᵃ) (ξ : I → Setoid ℓᵐ ℓᵉ) → S → Setoid _ _⟦ C ⟧s ξ = ICSetoid.setoid ξ C-------------------------------------------------------------------------- Multi-sorted algebras---------------------------------------------------------------------------- A multi-sorted algebra is an indexed container.---- * Sorts are indexes.---- * Operators are commands/shapes.---- * Arities/argument are responses/positions.---- Closed terms (initial model) are given by the W type for a container,-- renamed to μ here (for least fixed-point).-- We assume a fixed signature (Sort, Ops).module _ (Sort : Set ℓˢ) (Ops : Container Sort Sort ℓᵒ ℓᵃ) whereopen Container Ops renaming( Command to Op; Response to Arity; next to sort)-- We let letter $s$ range over sorts and $\mathit{op}$ over operators.variables s' : Sortop op' : Op s-------------------------------------------------------------------------- Models-- A model is given by an interpretation (Den $s$) for each sort $s$-- plus an interpretation (den $o$) for each operator $o$.record SetModel ℓᵐ : Set (ℓˢ ⊔ ℓᵒ ⊔ ℓᵃ ⊔ suc ℓᵐ) wherefieldDen : Sort → Set ℓᵐden : {s : Sort} → ⟦ Ops ⟧ Den s → Den s-- The setoid model requires operators to respect equality.-- The Func record packs a function (apply) with a proof (cong)-- that the function maps equals to equals.record SetoidModel ℓᵐ ℓᵉ : Set (ℓˢ ⊔ ℓᵒ ⊔ ℓᵃ ⊔ suc (ℓᵐ ⊔ ℓᵉ)) wherefieldDen : Sort → Setoid ℓᵐ ℓᵉden : {s : Sort} → Func (⟦ Ops ⟧s Den s) (Den s)-------------------------------------------------------------------------- Terms-- To obtain terms with free variables, we add additional nullary-- operators, each representing a variable.---- These are covered in the standard library FreeMonad module,-- albeit with the restriction that the operator and variable sets-- have the same size.Cxt = Sort → Set ℓᵒvariableΓ Δ : Cxt-- Terms with free variables in Var.module _ (Var : Cxt) where-- We keep the same sorts, but add a nullary operator for each variable.Ops⁺ : Container Sort Sort ℓᵒ ℓᵃOps⁺ = Ops ⋆C Var-- Terms with variables are then given by the W-type for the extended container.Tm = W Ops⁺-- We define nice constructors for variables and operator application-- via pattern synonyms.-- Note that the $f$ in constructor var' is a function from the empty set,-- so it should be uniquely determined. However, Agda's equality is-- more intensional and will not identify all functions from the empty set.-- Since we do not make use of the axiom of function extensionality,-- we sometimes have to consult the extensional equality of the-- function setoid.pattern _∙_ op args = sup (inj₂ op , args)pattern var' x f = sup (inj₁ x , f )pattern var x = var' x _-- Letter $t$ ranges over terms, and $\mathit{ts}$ over argument vectors.variablet t' t₁ t₂ t₃ : Tm Γ sts ts' : (i : Arity op) → Tm Γ (sort _ i)-------------------------------------------------------------------------- Parallel substitutions-- A substitution from Δ to Γ holds a term in Γ for each variable in Δ.Sub : (Γ Δ : Cxt) → Set _Sub Γ Δ = ∀{s} (x : Δ s) → Tm Γ s-- Application of a substitution._[_] : (t : Tm Δ s) (σ : Sub Γ Δ) → Tm Γ s(var x ) [ σ ] = σ x(op ∙ ts) [ σ ] = op ∙ λ i → ts i [ σ ]-- Letter $σ$ ranges over substitutions.variableσ σ' : Sub Γ Δ-------------------------------------------------------------------------- Interpretation of terms in a model-------------------------------------------------------------------------- Given an algebra $M$ of set-size $ℓ^m$ and equality-size $ℓ^e$,-- we define the interpretation of an $s$-sorted term $t$ as element-- of $M(s)$ according to an environment $ρ$ that maps each variable-- of sort $s'$ to an element of $M(s')$.module _ {M : SetoidModel ℓᵐ ℓᵉ} whereopen SetoidModel M-- Equality in $M$'s interpretation of sort $s$._≃_ : Den s .Carrier → Den s .Carrier → Set __≃_ {s = s} = Den s ._≈_-- An environment for Γ maps each variable $x : Γ(s)$ to an element of $M(s)$.-- Equality of environments is defined pointwise.Env : Cxt → Setoid _ _Env Γ .Carrier = {s : Sort} (x : Γ s) → Den s .CarrierEnv Γ ._≈_ ρ ρ' = {s : Sort} (x : Γ s) → ρ x ≃ ρ' xEnv Γ .isEquivalence .IsEquivalence.refl {s = s} x = Den s .Setoid.reflEnv Γ .isEquivalence .IsEquivalence.sym h {s} x = Den s .Setoid.sym (h x)Env Γ .isEquivalence .IsEquivalence.trans g h {s} x = Den s .Setoid.trans (g x) (h x)-- Interpretation of terms is iteration on the W-type.-- The standard library offers `iter' (on sets), but we need this to be a Func (on setoids).⦅_⦆ : ∀{s} (t : Tm Γ s) → Func (Env Γ) (Den s)⦅ var x ⦆ .apply ρ = ρ x⦅ var x ⦆ .cong ρ=ρ' = ρ=ρ' x⦅ op ∙ args ⦆ .apply ρ = den .apply (op , λ i → ⦅ args i ⦆ .apply ρ)⦅ op ∙ args ⦆ .cong ρ=ρ' = den .cong (refl , λ i → ⦅ args i ⦆ .cong ρ=ρ')-- An equality between two terms holds in a model-- if the two terms are equal under all valuations of their free variables.Equal : ∀ {Γ s} (t t' : Tm Γ s) → Set _Equal {Γ} {s} t t' = ∀ (ρ : Env Γ .Carrier) → ⦅ t ⦆ .apply ρ ≃ ⦅ t' ⦆ .apply ρ-- This notion is an equivalence relation.isEquiv : IsEquivalence (Equal {Γ = Γ} {s = s})isEquiv {s = s} .IsEquivalence.refl ρ = Den s .Setoid.reflisEquiv {s = s} .IsEquivalence.sym e ρ = Den s .Setoid.sym (e ρ)isEquiv {s = s} .IsEquivalence.trans e e' ρ = Den s .Setoid.trans (e ρ) (e' ρ)-------------------------------------------------------------------------- Substitution lemma-- Evaluation of a substitution gives an environment.⦅_⦆s : Sub Γ Δ → Env Γ .Carrier → Env Δ .Carrier⦅ σ ⦆s ρ x = ⦅ σ x ⦆ .apply ρ-- Substitution lemma: ⦅t[σ]⦆ρ ≃ ⦅t⦆⦅σ⦆ρsubstitution : (t : Tm Δ s) (σ : Sub Γ Δ) (ρ : Env Γ .Carrier) →⦅ t [ σ ] ⦆ .apply ρ ≃ ⦅ t ⦆ .apply (⦅ σ ⦆s ρ)substitution (var x) σ ρ = Den _ .Setoid.reflsubstitution (op ∙ ts) σ ρ = den .cong (refl , λ i → substitution (ts i) σ ρ)-------------------------------------------------------------------------- Equations-- An equation is a pair $t ≐ t'$ of terms of the same sort in the same context.record Eq : Set (ℓˢ ⊔ suc ℓᵒ ⊔ ℓᵃ) whereconstructor _≐_field{cxt} : Sort → Set ℓᵒ{srt} : Sortlhs : Tm cxt srtrhs : Tm cxt srt-- Equation $t ≐ t'$ holding in model $M$._⊧_ : (M : SetoidModel ℓᵐ ℓᵉ) (eq : Eq) → Set _M ⊧ (t ≐ t') = Equal {M = M} t t'-- Sets of equations are presented as collection E : I → Eq-- for some index set I : Set ℓⁱ.-- An entailment/consequence $E ⊃ t ≐ t'$ is valid-- if $t ≐ t'$ holds in all models that satify equations $E$.module _ {ℓᵐ ℓᵉ} where_⊃_ : (E : I → Eq) (eq : Eq) → Set _E ⊃ eq = ∀ (M : SetoidModel ℓᵐ ℓᵉ) → (∀ i → M ⊧ E i) → M ⊧ eq-- Derivations---------------- Equalitional logic allows us to prove entailments via the-- inference rules for the judgment $E ⊢ Γ ▹ t ≡ t'$.-- This could be coined as equational theory over a given-- set of equations $E$.-- Relation $E ⊢ Γ ▹ \_ ≡ \_$ is the least congruence over the equations $E$.data _⊢_▹_≡_ {I : Set ℓⁱ}(E : I → Eq) : (Γ : Cxt) (t t' : Tm Γ s) → Set (ℓˢ ⊔ suc ℓᵒ ⊔ ℓᵃ ⊔ ℓⁱ) wherehyp : ∀ i → let t ≐ t' = E i inE ⊢ _ ▹ t ≡ t'base : ∀ (x : Γ s) {f f' : (i : ⊥) → Tm _ (⊥-elim i)} →E ⊢ Γ ▹ var' x f ≡ var' x f'app : (∀ i → E ⊢ Γ ▹ ts i ≡ ts' i) →E ⊢ Γ ▹ (op ∙ ts) ≡ (op ∙ ts')sub : E ⊢ Δ ▹ t ≡ t' →∀ (σ : Sub Γ Δ) →E ⊢ Γ ▹ (t [ σ ]) ≡ (t' [ σ ])refl : ∀ (t : Tm Γ s) →E ⊢ Γ ▹ t ≡ tsym : E ⊢ Γ ▹ t ≡ t' →E ⊢ Γ ▹ t' ≡ ttrans : E ⊢ Γ ▹ t₁ ≡ t₂ →E ⊢ Γ ▹ t₂ ≡ t₃ →E ⊢ Γ ▹ t₁ ≡ t₃-------------------------------------------------------------------------- Soundness of the inference rules-- We assume a model $M$ that validates all equations in $E$.module Soundness {I : Set ℓⁱ} (E : I → Eq) (M : SetoidModel ℓᵐ ℓᵉ)(V : ∀ i → M ⊧ E i) whereopen SetoidModel M-- In any model $M$ that satisfies the equations $E$,-- derived equality is actual equality.sound : E ⊢ Γ ▹ t ≡ t' → M ⊧ (t ≐ t')sound (hyp i) = V isound (app {op = op} es) ρ = den .cong (refl , λ i → sound (es i) ρ)sound (sub {t = t} {t' = t'} e σ) ρ = begin⦅ t [ σ ] ⦆ .apply ρ ≈⟨ substitution {M = M} t σ ρ ⟩⦅ t ⦆ .apply ρ' ≈⟨ sound e ρ' ⟩⦅ t' ⦆ .apply ρ' ≈⟨ substitution {M = M} t' σ ρ ⟨⦅ t' [ σ ] ⦆ .apply ρ ∎whereopen SetoidReasoning (Den _)ρ' = ⦅ σ ⦆s ρsound (base x {f} {f'}) = isEquiv {M = M} .IsEquivalence.refl {var' x λ()}sound (refl t) = isEquiv {M = M} .IsEquivalence.refl {t}sound (sym {t = t} {t' = t'} e) = isEquiv {M = M} .IsEquivalence.sym{x = t} {y = t'} (sound e)sound (trans {t₁ = t₁} {t₂ = t₂}{t₃ = t₃} e e') = isEquiv {M = M} .IsEquivalence.trans{i = t₁} {j = t₂} {k = t₃} (sound e) (sound e')-------------------------------------------------------------------------- Birkhoff's completeness theorem-------------------------------------------------------------------------- Birkhoff proved that any equation $t ≐ t'$ is derivable from $E$-- when it is valid in all models satisfying $E$. His proof (for-- single-sorted algebras) is a blue print for many more-- completeness proofs. They all proceed by constructing a-- universal model aka term model. In our case, it is terms-- quotiented by derivable equality $E ⊢ Γ ▹ \_ ≡ \_$. It then-- suffices to prove that this model satisfies all equations in $E$.-------------------------------------------------------------------------- Universal model-- A term model for $E$ and $Γ$ interprets sort $s$ by (Tm Γ s) quotiented by $E ⊢ Γ ▹ \_ ≡ \_$.module TermModel {I : Set ℓⁱ} (E : I → Eq) whereopen SetoidModel-- Tm Γ s quotiented by E⊢Γ▹·≡·.TmSetoid : Cxt → Sort → Setoid _ _TmSetoid Γ s .Carrier = Tm Γ sTmSetoid Γ s ._≈_ = E ⊢ Γ ▹_≡_TmSetoid Γ s .isEquivalence .IsEquivalence.refl = refl _TmSetoid Γ s .isEquivalence .IsEquivalence.sym = symTmSetoid Γ s .isEquivalence .IsEquivalence.trans = trans-- The interpretation of an operator is simply the operator.-- This works because $E⊢Γ▹\_≡\_$ is a congruence.tmInterp : ∀ {Γ s} → Func (⟦ Ops ⟧s (TmSetoid Γ) s) (TmSetoid Γ s)tmInterp .apply (op , ts) = op ∙ tstmInterp .cong (refl , h) = app h-- The term model per context Γ.M : Cxt → SetoidModel _ _M Γ .Den = TmSetoid ΓM Γ .den = tmInterp-- The identity substitution σ₀ maps variables to themselves.σ₀ : {Γ : Cxt} → Sub Γ Γσ₀ x = var' x λ()-- σ₀ acts indeed as identity.identity : (t : Tm Γ s) → E ⊢ Γ ▹ t [ σ₀ ] ≡ tidentity (var x) = base xidentity (op ∙ ts) = app λ i → identity (ts i)-- Evaluation in the term model is substitution $E ⊢ Γ ▹ ⦅t⦆σ ≡ t[σ]$.-- This would even hold "up to the nose" if we had function extensionality.evaluation : (t : Tm Δ s) (σ : Sub Γ Δ) → E ⊢ Γ ▹ (⦅_⦆ {M = M Γ} t .apply σ) ≡ (t [ σ ])evaluation (var x) σ = refl (σ x)evaluation (op ∙ ts) σ = app (λ i → evaluation (ts i) σ)-- The term model satisfies all the equations it started out with.satisfies : ∀ i → M Γ ⊧ E isatisfies i σ = begin⦅ tₗ ⦆ .apply σ ≈⟨ evaluation tₗ σ ⟩tₗ [ σ ] ≈⟨ sub (hyp i) σ ⟩tᵣ [ σ ] ≈⟨ evaluation tᵣ σ ⟨⦅ tᵣ ⦆ .apply σ ∎whereopen SetoidReasoning (TmSetoid _ _)tₗ = E i .Eq.lhstᵣ = E i .Eq.rhs-------------------------------------------------------------------------- Completeness-- Birkhoff's completeness theorem \citeyearpar{birkhoff:1935}:-- Any valid consequence is derivable in the equational theory.module Completeness {I : Set ℓⁱ} (E : I → Eq) {Γ s} {t t' : Tm Γ s} whereopen TermModel Ecompleteness : E ⊃ (t ≐ t') → E ⊢ Γ ▹ t ≡ t'completeness V = begint ≈˘⟨ identity t ⟩t [ σ₀ ] ≈˘⟨ evaluation t σ₀ ⟩⦅ t ⦆ .apply σ₀ ≈⟨ V (M Γ) satisfies σ₀ ⟩⦅ t' ⦆ .apply σ₀ ≈⟨ evaluation t' σ₀ ⟩t' [ σ₀ ] ≈⟨ identity t' ⟩t' ∎where open SetoidReasoning (TmSetoid Γ s)
-------------------------------------------------------------------------- The Agda standard library---- Example showing how the free monad construction on containers can be-- used------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --sized-types #-}module README.Data.Container.FreeMonad whereopen import Level using (0ℓ)open import Effect.Monadopen import Data.Emptyopen import Data.Unitopen import Data.Bool.Base using (Bool; true)open import Data.Natopen import Data.Sum.Base using (inj₁; inj₂)open import Data.Product.Baseopen import Data.Container using (Container; _▷_)open import Data.Container.Combinator hiding (_×_)open import Data.Container.FreeMonadopen import Data.Wopen import Relation.Binary.PropositionalEquality as ≡-------------------------------------------------------------------------- Defining the signature of an effect and building trees describing-- computations leveraging that effect.-- The signature of state and its (generic) operations.State : Set → Container _ _State S = ⊤ ⟶ S ⊎ S ⟶ ⊤where_⟶_ : Set → Set → Container _ _I ⟶ O = I ▷ λ _ → Oget : ∀ {S} → State S ⋆ Sget = impure (inj₁ _ , pure)put : ∀ {S} → S → State S ⋆ ⊤put s = impure (inj₂ s , pure)-- Using the above we can, for example, write a stateful program that-- delivers a boolean.prog : State ℕ ⋆ Boolprog =get >>= λ n →put (suc n) >>pure truewhereopen RawMonad monad using (_>>_)runState : {S X : Set} → State S ⋆ X → (S → X × S)runState (pure x) = λ s → x , srunState (impure ((inj₁ _) , k)) = λ s → runState (k s) srunState (impure ((inj₂ s) , k)) = λ _ → runState (k _) stest : runState prog 0 ≡ (true , 1)test = ≡.refl-- It should be noted that @State S ⋆ X@ is not the state monad. If we-- could quotient @State S ⋆ X@ by the seven axioms of state (see-- Plotkin and Power's "Notions of Computation Determine Monads", 2002)-- then we would get the state monad.-------------------------------------------------------------------------- Defining effectful inductive data structures-- The definition of `C ⋆ A` is strictly positive in `A`, meaning that we-- can use `C ⋆_` when defining (co)inductive datatypes.open import Sizeopen import Codata.Sized.Thunkopen import Data.Vec.Base using (Vec; []; _∷_)-- A `Tap C A` is a infinite source of `A`s provided that we can perform-- the effectful computations described by `C`.-- The first one can be accessed readily but the rest of them is hidden-- under layers of `C` computations.module _ (C : Container 0ℓ 0ℓ) (A : Set 0ℓ) wheredata Tap (i : Size) : Set 0ℓ where_∷_ : A → Thunk (λ i → C ⋆ Tap i) i → Tap i-- We can run a given tap for a set number of steps and collect the elements-- thus generated along the way. This gives us a `C ⋆_` computation of a vector.module _ {C : Container 0ℓ 0ℓ} {A : Set 0ℓ} wheretake : Tap C A _ → (n : ℕ) → C ⋆ Vec A ntake _ 0 = pure []take (x ∷ _) 1 = pure (x ∷ [])take (x ∷ mxs) (suc n) = doxs ← mxs .forcerest ← take xs npure (x ∷ rest)-- A stream of all the natural numbers starting from a given value is an-- example of a tap.natsFrom : ∀ {i} → State ℕ ⋆ Tap (State ℕ) ℕ inatsFrom = let open RawMonad monad using (_>>_) in don ← getput (suc n)pure (n ∷ λ where .force → natsFrom)-- We can use `take` to capture an initial segment of the `natsFrom` tap-- and, after running the state operations, observe that it does generate-- successive numbers._ : ∀ k →runState (natsFrom >>= λ ns → take ns 5) k≡ (k ∷ 1 + k ∷ 2 + k ∷ 3 + k ∷ 4 + k ∷ [] , 5 + k)_ = λ k → refl
-------------------------------------------------------------------------- The Agda standard library---- Examples showing how the case expressions can be used with anonymous-- pattern-matching lambda abstractions------------------------------------------------------------------------{-# OPTIONS --cubical-compatible --safe #-}module README.Case whereopen import Data.Fin hiding (pred)open import Data.Maybe hiding (from-just)open import Data.Nat hiding (pred)open import Function.Base using (case_of_; case_returning_of_)open import Relation.Nullary-------------------------------------------------------------------------- Different types of pattern-matching lambdas-- absurd patternempty : ∀ {a} {A : Set a} → Fin 0 → Aempty i = case i of λ ()-- {}-delimited and ;-separated list of clauses-- Note that they do not need to be on different linespred : ℕ → ℕpred n = case n of λ{ zero → zero; (suc n) → n}-- where-introduced and indentation-identified block of list of clausesfrom-just : ∀ {a} {A : Set a} (x : Maybe A) → From-just xfrom-just x = case x returning From-just of λ where(just x) → xnothing → _-------------------------------------------------------------------------- We can define some recursive functions with caseplus : ℕ → ℕ → ℕplus m n = case m of λ{ zero → n; (suc m) → suc (plus m n)}div2 : ℕ → ℕdiv2 zero = zerodiv2 (suc m) = case m of λ wherezero → zero(suc m′) → suc (div2 m′)-- Note that some natural uses of case are rejected by the termination-- checker:-- module _ {a} {A : Set a} (eq? : Decidable {A = A} _≡_) where-- pairBy : List A → List (A ⊎ (A × A))-- pairBy [] = []-- pairBy (x ∷ []) = inj₁ x ∷ []-- pairBy (x ∷ y ∷ xs) = case eq? x y of λ where-- (yes _) → inj₂ (x , y) ∷ pairBy xs-- (no _) → inj₁ x ∷ pairBy (y ∷ xs)
-------------------------------------------------------------------------- The Agda standard library---- An explanation about the `Axiom` modules.------------------------------------------------------------------------module README.Axiom whereopen import Level using (Level)private variable ℓ : Level-------------------------------------------------------------------------- Introduction-- Several rules that are used without thought in written mathematics-- cannot be proved in Agda. The modules in the `Axiom` folder-- provide types expressing some of these rules that users may want to-- use even when they're not provable in Agda.-------------------------------------------------------------------------- Example: law of excluded middle-- In classical logic the law of excluded middle states that for any-- proposition `P` either `P` or `¬P` must hold. This is impossible-- to prove in Agda because Agda is a constructive system and so any-- proof of the excluded middle would have to build a term of either-- type `P` or `¬P`. This is clearly impossible without any knowledge-- of what proposition `P` is.-- The types for which `P` or `¬P` holds is called `Dec P` in the-- standard library (short for `Decidable`).open import Relation.Nullary.Decidable using (Dec)-- The type of the proof of saying that excluded middle holds for-- all types at universe level ℓ is therefore:---- ExcludedMiddle ℓ = ∀ {P : Set ℓ} → Dec P---- and this type is exactly the one found in `Axiom.ExcludedMiddle`:open import Axiom.ExcludedMiddle-- There are two different ways that the axiom can be introduced into-- your Agda development. The first option is to postulate it:postulate excludedMiddle : ExcludedMiddle ℓ-- This has the advantage that it only needs to be postulated once-- and it can then be imported into many different modules as with any-- other proof. The downside is that the resulting Agda code will no-- longer type check under the --safe flag.-- The second approach is to pass it as a module parameter:module Proof (excludedMiddle : ExcludedMiddle ℓ) where-- The advantage of this approach is that the resulting Agda-- development can still be type checked under the --safe flag.-- Intuitively the reason for this is that when postulating it-- you are telling Agda that excluded middle does hold (which is clearly-- untrue as discussed above). In contrast when passing it as a module-- parameter you are telling Agda that **if** excluded middle was true-- then the following proofs would hold, which is logically valid.-- The disadvantage of this approach is that it is now necessary to-- include the excluded middle assumption as a parameter in every module-- that you want to use it in. Additionally the modules can never-- be fully instantiated (without postulating excluded middle).-------------------------------------------------------------------------- Other axioms-- Double negation elimination-- (∀ P → ¬ ¬ P → P)import Axiom.DoubleNegationElimination-- Function extensionality-- (∀ f g → (∀ x → f x ≡ g x) → f ≡ g)import Axiom.Extensionality.Propositionalimport Axiom.Extensionality.Heterogeneous-- Uniqueness of identity proofs (UIP)-- (∀ x y (p q : x ≡ y) → p ≡ q)import Axiom.UniquenessOfIdentityProofs
branches: master experimentalhaddock-components: allcabal-check: False
cabal-version: 2.4name: agda-stdlib-utilsversion: 2.1build-type: Simpledescription: Helper programs for setting up the Agda standard library.license: MITtested-with:GHC == 9.10.1GHC == 9.8.2GHC == 9.6.5GHC == 9.4.8GHC == 9.2.8GHC == 9.0.2GHC == 8.10.7GHC == 8.8.4GHC == 8.6.5common common-build-parametersdefault-language:Haskell2010default-extensions:PatternGuardsPatternSynonymsbuild-depends:base >= 4.12.0.0 && < 4.21, filemanip >= 0.3.6.2 && < 0.4executable GenerateEverythingimport: common-build-parametershs-source-dirs: .main-is: GenerateEverything.hsbuild-depends:directory >= 1.0.0.0 && < 1.4, filepath >= 1.4.1.0 && < 1.6, mtl >= 2.2.2 && < 2.4executable AllNonAsciiCharsimport: common-build-parametershs-source-dirs: .main-is: AllNonAsciiChars.hsbuild-depends:text >= 1.2.3.1 && < 2.2
import Distribution.Simplemain = defaultMain
[](https://github.com/agda/agda-stdlib/actions/workflows/ci-ubuntu.yml)[](https://github.com/agda/agda-stdlib/actions/workflows/ci-ubuntu.yml)The Agda standard library=========================The standard library aims to contain all the tools needed to write bothprograms and proofs easily. While we always try and write efficientcode, we prioritize ease of proof over type-checking and normalizationperformance. If computational performance is important to you, thenperhaps try [agda-prelude](https://github.com/UlfNorell/agda-prelude)instead.## Getting startedIf you're looking to find your way around the library, there are severaldifferent ways to get started:- The library's structure and the associated design choices are describedin the [README.agda](https://github.com/agda/agda-stdlib/tree/master/doc/README.agda).- The [README folder](https://github.com/agda/agda-stdlib/tree/master/doc/README),which mirrors the structure of the main library, contains examples of how touse some of the more common modules. Feel free to [open a new issue](https://github.com/agda/agda-stdlib/issues/new) if there's a particular module you feel could do withsome more documentation.- You can [browse the library's source code](https://agda.github.io/agda-stdlib/)in glorious clickable HTML.## Installation instructionsSee the [installation instructions](https://github.com/agda/agda-stdlib/blob/master/doc/installation-guide.md) for the latest version of the standard library.#### Old versions of AgdaIf you're using an old version of Agda, you can download the corresponding versionof the standard library on the [Agda wiki](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary).The module index for older versions of the library is also available. For example,version 1.7 can be found at https://agda.github.io/agda-stdlib/v1.7/, justreplace in the URL 1.7 with the version that you need.#### Development version of AgdaIf you're using a development version of Agda rather than the latest official release,you should use the `experimental` branch of the standard library rather than `master`.[Instructions for updating the `experimental` branch](https://github.com/agda/agda-stdlib/blob/master/doc/updating-experimental.txt).The `experimental` branch contains non-backward compatible patches for upcomingchanges to the language.## Type-checking with flags#### The `--safe` flagMost of the library can be type-checked using the `--safe` flag. Please consult[GenerateEverything.hs](https://github.com/agda/agda-stdlib/blob/master/GenerateEverything.hs#L32-L82)for a full list of modules that use unsafe features.#### The `--cubical-compatible` flagMost of the library can be type-checked using the `--cubical-compatible` flag, which since Agda v2.6.3 supersedes the former `--without-K` flag. Please consult[GenerateEverything.hs](https://github.com/agda/agda-stdlib/blob/master/GenerateEverything.hs#L91-L111)for a full list of modules that use axiom K, requiring the `--with-K` flag.## Contributing to the libraryIf you would like to suggest improvements, feel free to use the `Issues` tab.Even better, if you would like to make the improvements yourself, we have instructionsin [HACKING](https://github.com/agda/agda-stdlib/blob/master/HACKING.md) to helpyou get started. For those who would simply like to help out, issues marked withthe [low-hanging-fruit](https://github.com/agda/agda-stdlib/issues?q=is%3Aopen+is%3Aissue+label%3Alow-hanging-fruit) tag are a good starting point.
Copyright (c) 2007-2024 Nils Anders Danielsson, Ulf Norell, Shin-ChengMu, Bradley Hardy, Samuel Bronson, Dan Doel, Patrik Jansson,Liang-Ting Chen, Jean-Philippe Bernardy, Andrés Sicard-Ramírez,Nicolas Pouillard, Darin Morrison, Peter Berry, Daniel Brown,Simon Foster, Dominique Devriese, Andreas Abel, Alcatel-Lucent,Eric Mertens, Joachim Breitner, Liyang Hu, Noam Zeilberger, Érdi Gergő,Stevan Andjelkovic, Helmut Grohne, Guilhem Moulin, Noriyuki Ohkawa,Evgeny Kotelnikov, James Chapman, Wen Kokke, Matthew Daggitt, Jason Hu,Sandro Stucki, Milo Turner, Zack Grannan, Lex van der Stoep,Jacques Carette, James McKinna, Guillaume Allaisand some anonymous contributors.Permission is hereby granted, free of charge, to any person obtaining acopy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BELIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTIONWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------- The Agda standard library---- All library modules, along with short descriptions-------------------------------------------------------------------------- Note that core modules are not included.
Contributing to the library===========================Thank you for your interest in contributing to the Agda standard library.Hopefully this guide should make it easy to do so! Feel free to ask anyquestions on the Agda mailing list. Before you start please read the[style-guide](https://github.com/agda/agda-stdlib/blob/master/doc/style-guide.md).What is an acceptable contribution?===================================- The contribution should be useful in a diverse set of areas.- The bar for accepting contributions that use the FFI to depend on external(i.e. Haskell, JavaScript) packages is much higher.- If the same concept already exists in the library, there needs to be a *very* goodreason to add a different formalisation.- There should be evidence that the code works. Usually this will be proofs, but sometimesfor purely computational contributions this will involve adding tests.- It should use the minimal set of Agda features, i.e. it should normally usethe Agda option pragmas `--cubical-compatible` and `--safe`, with the occasional use of`--with-K`, `--sized`, `--guardedness` in certain situations.In general, if something is in a general undergraduate Computer Science or Mathematicstextbook it is probably (!) contributable.Note on contributions to related/'coupled' modules==================================================Before making changes to a `Data` module please have a look at related modulesand see if they have any content along similar lines. If so, then pleasefollow those conventions (e.g. naming, argument order).For example, if working on `Data.Rational`, please check `Data.Rational.Unnormalised`or if working on `Data.Vec` please check `Data.List` and vice versa.Likewise, if adding to such modules, please try to make companion additionsto the related ones, or at least to make a task-list in the comments on your PR,indicating what outstanding work may be left for subsequent contributions/contributors.Setup=====The typical workflow when contributing to the standard library's repositoryis to interact with two remote versions of the repository:1. agda/agda-stdlib, the official one from which you can pull updates so thatyour contributions end up on top of whatever the current state is.2. USER/agda-stdlib, your fork to which you can push branches with contributionsyou would like to mergeThis tutorial guides you to set up a local copy of agda-stdlib so that you canstart contributing. Once things are set up properly, you can stick to onlysteps 5., 6., 7., 8. and 9. for future contributions.1. Fork the agda-stdlib repository----------------------------------Go to https://github.com/agda/agda-stdlib/ and click the 'Fork' button in thetop right corner. This will create a copy of the repository under your username.We assume in the rest of this document that this username is 'USER'.2. Double check-line ending settings if not on Linux----------------------------------------------------If you are on a Mac, make sure that your git options has `autocrlf` set to `input`.This can be done by executing```git config --global core.autocrlf input```If you are on Windows, make sure that your editor can deal with Unix format files.3. Obtain a local copy of agda/agda-stdlib------------------------------------------Obtain a local copy of the agda-stdlib repository. Here we are going to retrieveit from the `agda/agda-stdlib` repository so that `master` always points to thestate the official library is in.```shellgit clone git@github.com:agda/agda-stdlib```**NB**:if you have not added a public key to your github profile to set upgit over ssh, you may need to use the https url instead of the git@ one(`https://github.com/agda/agda-stdlib`)4. Add your fork as a secondary remote--------------------------------------As we have mentioned earlier the idea is to pull updates from `agda/agda-stdlib`and to push branches to your fork. For that to work you will need to explain togit how to refer to your fork. This can be done by declaring a remote like so(again you may need to use the https url if you haven't configured git over ssh)```shellgit remote add USER git@github.com:USER/agda-stdlib```You can check that this operation succeeded by fetching this newly added remote.Git should respond with a list of branches that were found on your fork.```shellgit fetch USER```***End of initial setup. When creating a future PRs one should start here.***.5. Create a branch for your new feature---------------------------------------Now that we have a local copy, we can start working on our new feature.The first step is to make sure we start from an up-to-date version of therepo by synchronising `master` with its current state on `agda/agda-stdlib`.```shellgit checkout mastergit pull```The second step is to create a branch for that feature based off `master`.Make sure to pick a fresh name in place of `new_feature`. We promptly pushthis new branch to our fork using the `-u` option for `push`.```shellgit checkout -b new_featuregit push USER -u new_feature```6. Make your changes--------------------You can then proceed to make your changes. Please follow existingconventions in the library, see[style-guide](https://github.com/agda/agda-stdlib/blob/master/doc/style-guide.md).for details. Document your changes in `agda-stdlib-fork/CHANGELOG.md`.If you are creating new modules, please make sure you are having aproper header, and a brief description of what the module is for, e.g.```-------------------------------------------------------------------------- The Agda standard library---- {PLACE YOUR BRIEF DESCRIPTION HERE}------------------------------------------------------------------------```If possible, each module should use the options `--safe` and`--cubical-compatible`. You can achieve this by placing the followingpragma under the header and before any other line of code (includingthe module name):```{-# OPTIONS --cubical-compatible --safe #-}```If a module cannot be made safe or needs the `--with-K` option then it should besplit into a module which is compatible with these options and an auxiliaryone which will either be called `SOME/PATH/Unsafe.agda` or `SOME/PATH/WithK.agda`or explicitly declared as either unsafe or needing K in `GenerateEverything.hs`7. [ Optional ] Run test suite locally--------------------------------------**NB** this step is optional as these tests will be run automaticallyby our CI infrastructure when you open a pull request on Github, but itcan be useful to run it locally to get a faster turn around time when findingproblems.Ensure your changes are compatible with the rest of the library by runningthe commands```make cleanmake test```inside the `agda-stdlib-fork` folder. Continue to correct any bugsthrown up until the tests are passed. Note that the testsrequire the use of a tool called `fix-whitespace`. See theinstructions at the end of this file for how to install this.8. Add, commit and push your changes to your fork-------------------------------------------------Use the `git add X` command to add changes to file `X` to the commit,or `git add .` to add all the changed files.Run the command `git commit` and enter a meaningful description foryour changes.Upload your changes to your fork by running `git push`.9. Open a PR------------Once you're satisfied with your additions, you can make sure they have beenpushed to the feature branch by running```shellgit status```and making sure there is nothing left to commit or no local commits to push.You should get something like:```On branch new_featureYour branch is up-to-date with 'USER/new_feature'.nothing to commit, working tree clean```You can then go to `https://github.com/agda/agda-stdlib/pulls`, click onthe green 'New pull request' button and then the 'compare across forks' link.You can then select your fork as the 'head repository' and the correspondingfeature branch and click on the big green 'Create pull request' button. Thelibrary maintainers will then be made aware of your requested changes andshould be in touch soon.10. Update the PR------------------If after opening a PR you realise you have forgotten something, or have receiveda review asking you to change something, you can simply push more commits to thebranch and they will automatically be added to the PR.How to enforce whitespace policies----------------------------------### Installing fix-whitespaceThis tool is kept in the main agda organization. It can be installed byfollowing these instructions:```git clone https://github.com/agda/fix-whitespace --depth 1cd fix-whitespace/cabal install```### Adding fix-whitespace as a pre-commit hookYou can add the following code to the file `.git/hooks/pre-commit` toget git to run fix-whitespace before each `git commit` and ensureyou are never committing anything with a whitespace violation:```#!/bin/shfix-whitespace --check```Type-checking the README directory----------------------------------* By default the README files are not exported in the`standard-library.agda-lib` file in order to avoidclashing with other people's README files.* If you wish to type-check a README file, then you willneed to change the present working directory to `doc/`where an appropriate `standard-library-doc.agda-lib`file is present.Continuous Integration (CI)===========================Updating the Haskell-CI workflow--------------------------------The file `.github/workflows/haskell-ci.yml` tests building the helpers specified in `agda-stdlib-utils.cabal`.It is autogenerated by the tool [haskell-ci]but has some custom modification which need to be restored after each regeneration of this workflow.[haskell-ci] creates the workflow file from settings in the `cabal.haskell-ci` fileand from the contents of the `tested-with` field in the `agda-stdlib-utils.cabal` file.After updating this field, run the following:```haskell-ci regeneratepatch --input=.github/haskell-ci.patch .github/workflows/haskell-ci.yml```[haskell-ci]: https://github.com/haskell-CI/haskell-ci
{-# LANGUAGE PatternGuards #-}{-# LANGUAGE PatternSynonyms #-}{-# LANGUAGE RecordWildCards #-}{-# LANGUAGE MultiWayIf #-}import Control.Applicativeimport Control.Monadimport Control.Monad.Exceptimport qualified Data.List as Listimport qualified Data.List.NonEmpty as List1import Data.List.NonEmpty ( pattern (:|) )import Data.Maybeimport System.Directoryimport System.Environmentimport System.Exitimport System.FilePathimport System.FilePath.Findimport System.IOheaderFile = "Header"allOutputFile = "Everything"safeOutputFile = "EverythingSafe"srcDir = "src"----------------------------------------------------------------------------- Files with a special status-- | Checks whether a module is declared (un)safeunsafeModules :: [FilePath]unsafeModules = map modToFile[ "Codata.Musical.Colist", "Codata.Musical.Colist.Base", "Codata.Musical.Colist.Properties", "Codata.Musical.Colist.Bisimilarity", "Codata.Musical.Colist.Relation.Unary.All", "Codata.Musical.Colist.Relation.Unary.All.Properties", "Codata.Musical.Colist.Relation.Unary.Any", "Codata.Musical.Colist.Relation.Unary.Any.Properties", "Codata.Musical.Colist.Infinite-merge", "Codata.Musical.Costring", "Codata.Musical.Covec", "Codata.Musical.Conversion", "Codata.Musical.Stream", "Data.Bytestring.Base", "Data.Bytestring.Builder.Base", "Data.Bytestring.Builder.Primitive", "Data.Bytestring.IO", "Data.Bytestring.IO.Primitive", "Data.Bytestring.Primitive", "Data.Word8.Base", "Data.Word8.Literals", "Data.Word8.Primitive", "Data.Word64.Primitive", "Data.Word8.Show", "Data.Word64.Show", "Debug.Trace", "Effect.Monad.IO", "Effect.Monad.IO.Instances", "Foreign.Haskell", "Foreign.Haskell.Coerce", "Foreign.Haskell.Either", "Foreign.Haskell.Maybe", "Foreign.Haskell.List.NonEmpty", "Foreign.Haskell.Pair", "IO", "IO.Base", "IO.Categorical", "IO.Handle", "IO.Infinite", "IO.Instances", "IO.Effectful", "IO.Finite", "IO.Primitive", "IO.Primitive.Core", "IO.Primitive.Handle", "IO.Primitive.Infinite", "IO.Primitive.Finite", "Relation.Binary.PropositionalEquality.TrustMe", "System.Clock", "System.Clock.Primitive", "System.Directory", "System.Directory.Primitive", "System.Environment", "System.Environment.Primitive", "System.Exit", "System.Exit.Primitive", "System.FilePath.Posix", "System.FilePath.Posix.Primitive", "System.Process", "System.Process.Primitive", "System.Random", "System.Random.Primitive", "Test.Golden", "Text.Pretty.Core", "Text.Pretty"] ++ sizedTypesModulesisUnsafeModule :: FilePath -> BoolisUnsafeModule fp =unqualifiedModuleName fp == "Unsafe"|| fp `elem` unsafeModules-- | Checks whether a module is declared as using KwithKModules :: [FilePath]withKModules = map modToFile[ "Axiom.Extensionality.Heterogeneous", "Data.Star.BoundedVec", "Data.Star.Decoration", "Data.Star.Environment", "Data.Star.Fin", "Data.Star.Pointer", "Data.Star.Vec", "Data.String.Unsafe", "Reflection.AnnotatedAST", "Reflection.AnnotatedAST.Free", "Relation.Binary.HeterogeneousEquality", "Relation.Binary.HeterogeneousEquality.Core", "Relation.Binary.HeterogeneousEquality.Quotients.Examples", "Relation.Binary.HeterogeneousEquality.Quotients", "Relation.Binary.PropositionalEquality.TrustMe", "Text.Pretty.Core", "Text.Pretty", "Text.Regex.String.Unsafe"]isWithKModule :: FilePath -> BoolisWithKModule =-- GA 2019-02-24: it is crucial to use an anonymous lambda-- here so that `withKModules` is shared between all calls-- to `isWithKModule`.\ fp -> unqualifiedModuleName fp == "WithK"|| fp `elem` withKModulessizedTypesModules :: [FilePath]sizedTypesModules = map modToFile[ "Codata.Sized.Cofin", "Codata.Sized.Cofin.Literals", "Codata.Sized.Colist", "Codata.Sized.Colist.Bisimilarity", "Codata.Sized.Colist.Categorical", "Codata.Sized.Colist.Effectful", "Codata.Sized.Colist.Properties", "Codata.Sized.Conat", "Codata.Sized.Conat.Bisimilarity", "Codata.Sized.Conat.Literals", "Codata.Sized.Conat.Properties", "Codata.Sized.Covec", "Codata.Sized.Covec.Bisimilarity", "Codata.Sized.Covec.Categorical", "Codata.Sized.Covec.Effectful", "Codata.Sized.Covec.Instances", "Codata.Sized.Covec.Properties", "Codata.Sized.Cowriter", "Codata.Sized.Cowriter.Bisimilarity", "Codata.Sized.Delay", "Codata.Sized.Delay.Bisimilarity", "Codata.Sized.Delay.Categorical", "Codata.Sized.Delay.Effectful", "Codata.Sized.Delay.Properties", "Codata.Sized.M", "Codata.Sized.M.Bisimilarity", "Codata.Sized.M.Properties", "Codata.Sized.Stream", "Codata.Sized.Stream.Bisimilarity", "Codata.Sized.Stream.Categorical", "Codata.Sized.Stream.Effectful", "Codata.Sized.Stream.Instances", "Codata.Sized.Stream.Properties", "Codata.Sized.Thunk", "Data.Container.Fixpoints.Sized", "Data.W.Sized", "Data.Nat.PseudoRandom.LCG.Unsafe", "Data.Tree.Binary.Show", "Data.Tree.Rose", "Data.Tree.Rose.Properties", "Data.Tree.Rose.Show", "Data.Trie", "Data.Trie.NonEmpty", "Relation.Unary.Sized", "Size", "Text.Tree.Linear"]isSizedTypesModule :: FilePath -> BoolisSizedTypesModule =\ fp -> fp `elem` sizedTypesModulesunqualifiedModuleName :: FilePath -> StringunqualifiedModuleName = dropExtension . takeFileName-- | Returns 'True' for all Agda files except for core modules.isLibraryModule :: FilePath -> BoolisLibraryModule f =takeExtension f `elem` [".agda", ".lagda"]&& unqualifiedModuleName f /= "Core"----------------------------------------------------------------------------- Analysing library filestype Exc = Except String-- | Extracting the header.-- It needs to have the form:-- -------------------------------------------------------------------------- -- The Agda standard library-- ---- -- Description of the module-- ------------------------------------------------------------------------extractHeader :: FilePath -> [String] -> Exc [String]extractHeader mod = extractwheredelimiter = all (== '-')extract :: [String] -> Exc [String]extract (d1 : "-- The Agda standard library" : "--" : ss)| delimiter d1, (info, d2 : rest) <- span ("-- " `List.isPrefixOf`) ss, delimiter d2= pure $ infoextract (d1@(c:cs) : _)| not (delimiter d1)-- Andreas, issue #1510: there is a haunting of Prelude.last, so use List1.last instead.-- See https://gitlab.haskell.org/ghc/ghc/-/issues/19917.-- Update: The haunting is also resolved by 'throwError' instead of 'error',-- but still I dislike Prelude.last., List1.last (c :| cs) == '\r'= throwError $ unwords[ mod, "contains \\r, probably due to git misconfiguration;", "maybe set autocrf to input?"]extract _ = throwError $ unwords[ mod, "is malformed.", "It needs to have a module header.", "Please see other existing files or consult HACKING.md."]-- | A crude classifier looking for lines containing optionsdata Safety = Unsafe | Safe deriving (Eq)data Status = Deprecated | Active deriving (Eq)classify :: FilePath -> [String] -> [String] -> Exc (Safety, Status)classify fp hd ls-- We start with sanity checks| isUnsafe && safe = throwError $ fp ++ contradiction "unsafe" "safe"| not (isUnsafe || safe) = throwError $ fp ++ uncategorized "unsafe" "safe"| isWithK && cubicalC = throwError $ fp ++ contradiction "as relying on K" "cubical-compatible"| isWithK && not withK = throwError $ fp ++ missingWithK| not (isWithK || cubicalC) = throwError $ fp ++ uncategorized "as relying on K" "cubical-compatible"-- And then perform the actual classification| otherwise = dolet safety = if | safe -> Safe| isUnsafe -> Unsafe| otherwise -> error "IMPOSSIBLE"let status = if deprecated then Deprecated else Activepure (safety, status)where-- based on declarationsisWithK = isWithKModule fpisUnsafe = isUnsafeModule fp-- based on detected OPTIONSsafe = option "--safe"withK = option "--with-K"cubicalC = option "--cubical-compatible"-- based on detected comment in headerdeprecated = let detect = List.isSubsequenceOf "This module is DEPRECATED."in any detect hd-- GA 2019-02-24: note that we do not reprocess the whole module for every-- option check: the shared @options@ definition ensures we only inspect a-- handful of lines (at most one, ideally)option str = let detect = List.isSubsequenceOf ["{-#", "OPTIONS", str, "#-}"]in any detect optionsoptions = words <$> filter (List.isInfixOf "OPTIONS") ls-- formatting error messagescontradiction d o = unwords[ " is declared", d, "but uses the", "--" ++ o, "option." ]uncategorized d o = unwords[ " is not declared", d, "but not using the", "--" ++ o, "option either." ]missingWithK = " is declared as relying on K but not using the --with-K option."-- | Analyse a file: extracting header and classifying it.data LibraryFile = LibraryFile{ filepath :: FilePath -- ^ FilePath of the source file, header :: [String] -- ^ All lines in the headers are already prefixed with \"-- \"., safety :: Safety, status :: Status -- ^ Deprecation status options used by the module}analyse :: FilePath -> IO LibraryFileanalyse fp = dols <- lines <$> readFileUTF8 fphd <- runExc $ extractHeader fp ls(sf, st) <- runExc $ classify fp hd lsreturn $ LibraryFile{ filepath = fp, header = hd, safety = sf, status = st}checkFilePaths :: String -> [FilePath] -> IO ()checkFilePaths cat fps = forM_ fps $ \ fp -> dob <- doesFileExist fpunless b $die $ fp ++ " is listed as " ++ cat ++ " but does not exist."data Options = Options{ includeDeprecated :: Bool, outputDirectory :: FilePath}initOptions :: OptionsinitOptions = Options{ includeDeprecated = False, outputDirectory = "."}parseOptions :: [String] -> Options -> Maybe OptionsparseOptions [] opts = pure optsparseOptions ("--include-deprecated" : rest) opts= parseOptions rest (opts { includeDeprecated = True })parseOptions ("--out-dir" : dir : rest) opts= parseOptions rest (opts { outputDirectory = dir })parseOptions _ _ = Nothing----------------------------------------------------------------------------- Collecting all non-Core library files, analysing them and generating-- 2 files:-- Everything.agda all the modules-- EverythingSafe.agda all the safe modulesmain :: IO ()main = doargs <- getArgsOptions{..} <- case parseOptions args initOptions ofJust opts -> pure optsNothing -> hPutStr stderr usage >> exitFailurecheckFilePaths "unsafe" unsafeModulescheckFilePaths "using K" withKModulesheader <- readFileUTF8 headerFilemodules <- filter isLibraryModule . List.sort <$>find always(extension ==? ".agda" ||? extension ==? ".lagda")srcDirlibraryfiles <- (if includeDeprecated then idelse (filter ((Deprecated /=) . status) <$>)) (mapM analyse modules)let mkModule str = "module " ++ str ++ " where"writeFileUTF8 (outputDirectory ++ "/" ++ allOutputFile ++ ".agda") $unlines [ header, "{-# OPTIONS --rewriting --guardedness --sized-types #-}\n", mkModule allOutputFile, format libraryfiles]writeFileUTF8 (outputDirectory ++ "/" ++ safeOutputFile ++ ".agda") $unlines [ header, "{-# OPTIONS --safe --guardedness #-}\n", mkModule safeOutputFile, format $ filter ((Unsafe /=) . safety) libraryfiles]-- | Usage info.usage :: Stringusage = unlines[ "GenerateEverything: A utility program for Agda's standard library.", "", "Usage: GenerateEverything", "", "This program should be run in the base directory of a clean checkout of", "the library.", "", "The program generates documentation for the library by extracting", "headers from library modules. The output is written to " ++ allOutputFile, "with the file " ++ headerFile ++ " inserted verbatim at the beginning.", "", "If the option --out-dir is used then the output is placed in the", "subdirectory thus selected."]-- | Formats the extracted module information.format :: [LibraryFile] -> Stringformat = unlines . concatMap fmtwherefmt lf = "" : header lf ++ ["import " ++ fileToMod (filepath lf)]-- | Translates back and forth between a file name and the corresponding module-- name. We assume that the file name corresponds to an Agda module under-- 'srcDir'.fileToMod :: FilePath -> StringfileToMod = map slashToDot . dropExtension . makeRelative srcDirwhereslashToDot c | isPathSeparator c = '.'| otherwise = cmodToFile :: String -> FilePathmodToFile name = concat [ srcDir, [pathSeparator], map dotToSlash name, ".agda" ]wheredotToSlash c | c == '.' = pathSeparator| otherwise = c-- | A variant of 'readFile' which uses the 'utf8' encoding.readFileUTF8 :: FilePath -> IO StringreadFileUTF8 f = doh <- openFile f ReadModehSetEncoding h utf8s <- hGetContents hlength s `seq` return s-- | A variant of 'writeFile' which uses the 'utf8' encoding.writeFileUTF8 :: FilePath -> String -> IO ()writeFileUTF8 f s = withFile f WriteMode $ \h -> dohSetEncoding h utf8hPutStr h s-- | Turning exceptions into fatal errors.runExc :: Exc a -> IO arunExc = either die return . runExcept
AGDA_EXEC ?= agdaAGDA_OPTIONS=-WerrorAGDA_RTS_OPTIONS=+RTS -M4.0G -H3.5G -A128M -RTSAGDA=$(AGDA_EXEC) $(AGDA_OPTIONS) $(AGDA_RTS_OPTIONS)# Before running `make test` the `fix-whitespace` program should# be installed:## cabal install fix-whitespacetest: Everything.agda check-whitespacecd doc && $(AGDA) README.agdatestsuite:$(MAKE) -C tests test AGDA="$(AGDA)" AGDA_EXEC="$(AGDA_EXEC)" only=$(only)fix-whitespace:cabal exec -- fix-whitespacecheck-whitespace:cabal exec -- fix-whitespace --checksetup: Everything.agda.PHONY: Everything.agdaEverything.agda:cabal run GenerateEverything -- --out-dir doc.PHONY: listingslistings: Everything.agdacd doc && $(AGDA) --html README.agda -v0clean :find . -type f -name '*.agdai' -deleterm -f Everything.agda EverythingSafe.agda
cff-version: 1.2.0message: "If you use this software, please cite it as below."authors:- name: "The Agda Community"title: "Agda Standard Library"version: 2.1date-released: 2024-07-27url: "https://github.com/agda/agda-stdlib"
Version 2.1===========The library has been tested using Agda 2.6.4.3.Highlights----------* The size of the dependency graph for many modules has beenreduced. This may lead to speed ups for first-time loading of somemodules.* Added bindings for file handles in `IO.Handle`.* Added bindings for random number generation in `System.Random`* Added support for 8-bit words and bytestrings in `Data.Word8` and `Data.ByteString`.Bug-fixes---------* Fixed type of `toList-replicate` in `Data.Vec.Properties`, where `replicate`was mistakenly applied to the level of the type `A` instead of thevariable `x` of type `A`.* Module `Data.List.Relation.Ternary.Appending.Setoid.Properties` no longerincorrectly publicly exports the `Setoid` module under the alias `S`.* Removed unbound parameter from `length-alignWith`,`alignWith-map` and `map-alignWith` in `Data.List.Properties`.Non-backwards compatible changes--------------------------------* The recently added modules and (therefore their contents) in:```agdaAlgebra.Module.Morphism.StructuresAlgebra.Module.Morphism.Construct.CompositionAlgebra.Module.Morphism.Construct.Identity```have been changed so they are now parametrized by _raw_ bundles ratherthan lawful bundles.This is in line with other modules that define morphisms.As a result many of the `Composition` lemmas now take a proof oftransitivity and the `Identity` lemmas now take a proof of reflexivity.* The module `IO.Primitive` was moved to `IO.Primitive.Core`.Minor improvements------------------* The definition of the `Pointwise` relational combinator in`Data.Product.Relation.Binary.Pointwise.NonDependent.Pointwise`has been generalised to take heterogeneous arguments in `REL`.* The structures `IsSemilattice` and `IsBoundedSemilattice` in`Algebra.Lattice.Structures` have been redefined as aliases of`IsCommutativeBand` and `IsIdempotentMonoid` in `Algebra.Structures`.Deprecated modules------------------* All modules in the `Data.Word` hierarchy have been deprecated in favourof their newly introduced counterparts in `Data.Word64`.* The module `Data.List.Relation.Binary.Sublist.Propositional.Disjoint`has been deprecated in favour of `Data.List.Relation.Binary.Sublist.Propositional.Slice`.* The modules```Function.Endomorphism.PropositionalFunction.Endomorphism.Setoid```that used the old `Function` hierarchy have been deprecated in favour of:```Function.Endo.PropositionalFunction.Endo.Setoid```Deprecated names----------------* In `Algebra.Properties.Semiring.Mult`:```agda1×-identityʳ ↦ ×-homo-1```* In `Algebra.Structures.IsGroup`:```agda_-_ ↦ _//_```* In `Algebra.Structures.Biased`:```agdaIsRing* ↦ Algebra.Structures.IsRingisRing* ↦ Algebra.Structures.isRing```* In `Data.Float.Base`:```agdatoWord ↦ toWord64```* In `Data.Float.Properties`:```agdatoWord-injective ↦ toWord64-injective```* In `Data.List.Base`:```agdascanr ↦ Data.List.Scans.Base.scanrscanl ↦ Data.List.Scans.Base.scanl```* In `Data.List.Properties`:```agdascanr-defn ↦ Data.List.Scans.Properties.scanr-defnscanl-defn ↦ Data.List.Scans.Properties.scanl-defn```* In `Data.List.Relation.Unary.All.Properties`:```agdamap-compose ↦ map-∘```* In `Data.Maybe.Base`:```agdadecToMaybe ↦ Relation.Nullary.Decidable.Core.dec⇒maybe```* In `Data.Nat.Base`: the following pattern synonyms and definitions are alldeprecated in favour of direct pattern matching on `Algebra.Definitions.RawMagma._∣ˡ_._,_````agdapattern less-than-or-equal {k} eq = k , eqpattern ≤″-offset k = k , reflpattern <″-offset k = k , refls≤″s⁻¹```* In `Data.Nat.Divisibility.Core`:```agda*-pres-∣ ↦ Data.Nat.Divisibility.*-pres-∣```* In `Data.Sum`:```agdafromDec ↦ Relation.Nullary.Decidable.Core.toSumtoDec ↦ Relation.Nullary.Decidable.Core.fromSum```* In `IO.Base`:```agdauntilRight ↦ untilInj₂```New modules-----------* Pointwise lifting of algebraic structures `IsX` and bundles `X` fromcarrier set `C` to function space `A → C`:```Algebra.Construct.Pointwise```* Raw bundles for module-like algebraic structures:```Algebra.Module.Bundles.Raw```* Nagata's construction of the "idealization of a module":```agdaAlgebra.Module.Construct.Idealization```* The unique morphism from the initial, resp. terminal, algebra:```agdaAlgebra.Morphism.Construct.InitialAlgebra.Morphism.Construct.Terminal```* Bytestrings and builders:```agdaData.Bytestring.BaseData.Bytestring.Builder.BaseData.Bytestring.Builder.PrimitiveData.Bytestring.IOData.Bytestring.IO.PrimitiveData.Bytestring.Primitive```* Pointwise and equality relations over indexed containers:```agdaData.Container.Indexed.Relation.Binary.PointwiseData.Container.Indexed.Relation.Binary.Pointwise.PropertiesData.Container.Indexed.Relation.Binary.Equality.Setoid```* Refactoring of `Data.List.Base.{scanr|scanl}` and their properties:```Data.List.Scans.BaseData.List.Scans.Properties```* Various show modules for lists and vector types:```agdaData.List.ShowData.Vec.ShowData.Vec.Bounded.Show```* Properties of `List` modulo `Setoid` equality (currently only the ([],++) monoid):```Data.List.Relation.Binary.Equality.Setoid.Properties```* Decidability for the subset relation on lists:```agdaData.List.Relation.Binary.Subset.DecSetoid (_⊆?_)Data.List.Relation.Binary.Subset.DecPropositional```* Decidability for the disjoint relation on lists:```agdaData.List.Relation.Binary.Disjoint.DecSetoid (disjoint?)Data.List.Relation.Binary.Disjoint.DecPropositional```* Prime factorisation of natural numbers.```agdaData.Nat.Primality.Factorisation```* Permutations of vectors as functions:```agdaData.Vec.Functional.Relation.Binary.PermutationData.Vec.Functional.Relation.Binary.Permutation.Properties```* A type of bytes:```agdaData.Word8.PrimitiveData.Word8.BaseData.Word8.LiteralsData.Word8.Show```* Word64 literals and bit-based functions:```agdaData.Word64.LiteralsData.Word64.UnsafeData.Word64.Show```* Pointwise equality over functions```Function.Relation.Binary.Equality````* Consequences of 'infinite descent' for (accessible elements of) well-founded relations:```agdaInduction.InfiniteDescent```* New IO primitives to handle buffering```agdaIO.Primitive.HandleIO.Handle```* Symmetric interior of a binary relation```Relation.Binary.Construct.Interior.Symmetric```* Properties of `Setoid`s with decidable equality relation:```Relation.Binary.Properties.DecSetoid```* Collection of results about recomputability in```agdaRelation.Nullary.Recomputable```with the main definition `Recomputable` exported publicly from `Relation.Nullary`.* New bindings to random numbers:```agdaSystem.Random.PrimitiveSystem.Random```Additions to existing modules-----------------------------* Added new definitions in `Algebra.Bundles`:```agdarecord SuccessorSet c ℓ : Set (suc (c ⊔ ℓ))record CommutativeBand c ℓ : Set (suc (c ⊔ ℓ))record IdempotentMonoid c ℓ : Set (suc (c ⊔ ℓ))```and additional manifest fields for sub-bundles arising from these in:```agdaIdempotentCommutativeMonoidIdempotentSemiring```* Added new definition in `Algebra.Bundles.Raw````agdarecord RawSuccessorSet c ℓ : Set (suc (c ⊔ ℓ))```* Added new proofs in `Algebra.Construct.Terminal`:```agdarawNearSemiring : RawNearSemiring c ℓnearSemiring : NearSemiring c ℓ```* In `Algebra.Module.Bundles`, raw bundles are now re-exported and bundlesconsistently expose their raw counterparts.* Added proofs in `Algebra.Module.Construct.DirectProduct`:```agdarawLeftSemimodule : RawLeftSemimodule R m ℓm → RawLeftSemimodule m′ ℓm′ → RawLeftSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawLeftModule : RawLeftModule R m ℓm → RawLeftModule m′ ℓm′ → RawLeftModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawRightSemimodule : RawRightSemimodule R m ℓm → RawRightSemimodule m′ ℓm′ → RawRightSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawRightModule : RawRightModule R m ℓm → RawRightModule m′ ℓm′ → RawRightModule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawBisemimodule : RawBisemimodule R m ℓm → RawBisemimodule m′ ℓm′ → RawBisemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawBimodule : RawBimodule R m ℓm → RawBimodule m′ ℓm′ → RawBimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawSemimodule : RawSemimodule R m ℓm → RawSemimodule m′ ℓm′ → RawSemimodule R (m ⊔ m′) (ℓm ⊔ ℓm′)rawModule : RawModule R m ℓm → RawModule m′ ℓm′ → RawModule R (m ⊔ m′) (ℓm ⊔ ℓm′)```* Added proofs in `Algebra.Module.Construct.TensorUnit`:```agdarawLeftSemimodule : RawLeftSemimodule _ c ℓrawLeftModule : RawLeftModule _ c ℓrawRightSemimodule : RawRightSemimodule _ c ℓrawRightModule : RawRightModule _ c ℓrawBisemimodule : RawBisemimodule _ _ c ℓrawBimodule : RawBimodule _ _ c ℓrawSemimodule : RawSemimodule _ c ℓrawModule : RawModule _ c ℓ```* Added proofs in `Algebra.Module.Construct.Zero`:```agdarawLeftSemimodule : RawLeftSemimodule R c ℓrawLeftModule : RawLeftModule R c ℓrawRightSemimodule : RawRightSemimodule R c ℓrawRightModule : RawRightModule R c ℓrawBisemimodule : RawBisemimodule R c ℓrawBimodule : RawBimodule R c ℓrawSemimodule : RawSemimodule R c ℓrawModule : RawModule R c ℓ```* Added definitions in `Algebra.Morphism.Structures`:```agdarecord IsSuccessorSetHomomorphism (⟦_⟧ : N₁.Carrier → N₂.Carrier) : Set _record IsSuccessorSetMonomorphism (⟦_⟧ : N₁.Carrier → N₂.Carrier) : Set _record IsSuccessorSetIsomorphism (⟦_⟧ : N₁.Carrier → N₂.Carrier) : Set _IsSemigroupHomomorphism : (A → B) → Set _IsSemigroupMonomorphism : (A → B) → Set _IsSemigroupIsomorphism : (A → B) → Set _```* Added proof in `Algebra.Properties.AbelianGroup`:```⁻¹-anti-homo‿- : (x - y) ⁻¹ ≈ y - x```* Added proofs in `Algebra.Properties.Group`:```agdaisQuasigroup : IsQuasigroup _∙_ _\\_ _//_quasigroup : Quasigroup _ _isLoop : IsLoop _∙_ _\\_ _//_ εloop : Loop _ _\\-leftDividesˡ : LeftDividesˡ _∙_ _\\_\\-leftDividesʳ : LeftDividesʳ _∙_ _\\_\\-leftDivides : LeftDivides _∙_ _\\_//-rightDividesˡ : RightDividesˡ _∙_ _//_//-rightDividesʳ : RightDividesʳ _∙_ _//_//-rightDivides : RightDivides _∙_ _//_⁻¹-selfInverse : SelfInverse _⁻¹x∙y⁻¹≈ε⇒x≈y : ∀ x y → (x ∙ y ⁻¹) ≈ ε → x ≈ yx≈y⇒x∙y⁻¹≈ε : ∀ {x y} → x ≈ y → (x ∙ y ⁻¹) ≈ ε\\≗flip-//⇒comm : (∀ x y → x \\ y ≈ y // x) → Commutative _∙_comm⇒\\≗flip-// : Commutative _∙_ → ∀ x y → x \\ y ≈ y // x⁻¹-anti-homo-// : (x // y) ⁻¹ ≈ y // x⁻¹-anti-homo-\\ : (x \\ y) ⁻¹ ≈ y \\ x```* Added new proofs in `Algebra.Properties.Loop`:```agdaidentityˡ-unique : x ∙ y ≈ y → x ≈ εidentityʳ-unique : x ∙ y ≈ x → y ≈ εidentity-unique : Identity x _∙_ → x ≈ ε```* Added new proofs in `Algebra.Properties.Monoid.Mult`:```agda×-homo-0 : 0 × x ≈ 0#×-homo-1 : 1 × x ≈ x```* Added new proofs in `Algebra.Properties.Semiring.Mult`:```agda×-homo-0# : 0 × x ≈ 0# * x×-homo-1# : 1 × x ≈ 1# * xidem-×-homo-* : (_*_ IdempotentOn x) → (m × x) * (n × x) ≈ (m ℕ.* n) × x```* Added new definitions to `Algebra.Structures`:```agdarecord IsSuccessorSet (suc# : Op₁ A) (zero# : A) : Set _record IsCommutativeBand (∙ : Op₂ A) : Set _record IsIdempotentMonoid (∙ : Op₂ A) (ε : A) : Set _```* Added new definitions in `IsGroup` record in `Algebra.Structures`:```agdax // y = x ∙ (y ⁻¹)x \\ y = (x ⁻¹) ∙ y```* In `Algebra.Structures` added new proof to `IsCancellativeCommutativeSemiring` record:```agda*-cancelʳ-nonZero : AlmostRightCancellative 0# *```* In `Data.Bool.Show`:```agdashowBit : Bool → Char```* In `Data.Container.Indexed.Core`:```agdaSubtrees o c = (r : Response c) → X (next c r)```* In `Data.Empty`:```agda⊥-elim-irr : .⊥ → Whatever```* In `Data.Fin.Properties`:```agdanonZeroIndex : Fin n → ℕ.NonZero n```* In `Data.Float.Base`:```agda_≤_ : Rel Float _```* In `Data.Integer.Divisibility` introduced `divides` as an explicit pattern synonym```agdapattern divides k eq = Data.Nat.Divisibility.divides k eq```* In `Data.Integer.Properties`:```agda◃-nonZero : .{{_ : ℕ.NonZero n}} → NonZero (s ◃ n)sign-* : .{{NonZero (i * j)}} → sign (i * j) ≡ sign i Sign.* sign ji*j≢0 : .{{_ : NonZero i}} .{{_ : NonZero j}} → NonZero (i * j)```* In `Data.List.Base` added two new functions:```agdaInits.tail : List A → List (List A)Tails.tail : List A → List (List A)```and redefined `inits` and `tails` in terms of them.* In `Data.List.Membership.Propositional.Properties.Core`:```agdafind∘∃∈-Any : (p : ∃ λ x → x ∈ xs × P x) → find (∃∈-Any p) ≡ p∃∈-Any∘find : (p : Any P xs) → ∃∈-Any (find p) ≡ p```* In `Data.List.Membership.Setoid.Properties`:```agdareverse⁺ : x ∈ xs → x ∈ reverse xsreverse⁻ : x ∈ reverse xs → x ∈ xs```* In `Data.List.Properties`:```agdalength-catMaybes : length (catMaybes xs) ≤ length xsapplyUpTo-∷ʳ : applyUpTo f n ∷ʳ f n ≡ applyUpTo f (suc n)applyDownFrom-∷ʳ : applyDownFrom (f ∘ suc) n ∷ʳ f 0 ≡ applyDownFrom f (suc n)upTo-∷ʳ : upTo n ∷ʳ n ≡ upTo (suc n)downFrom-∷ʳ : applyDownFrom suc n ∷ʳ 0 ≡ downFrom (suc n)reverse-selfInverse : SelfInverse {A = List A} _≡_ reversereverse-applyUpTo : reverse (applyUpTo f n) ≡ applyDownFrom f nreverse-upTo : reverse (upTo n) ≡ downFrom nreverse-applyDownFrom : reverse (applyDownFrom f n) ≡ applyUpTo f nreverse-downFrom : reverse (downFrom n) ≡ upTo nmapMaybe-map : mapMaybe f ∘ map g ≗ mapMaybe (f ∘ g)map-mapMaybe : map g ∘ mapMaybe f ≗ mapMaybe (Maybe.map g ∘ f)align-map : align (map f xs) (map g ys) ≡ map (map f g) (align xs ys)zip-map : zip (map f xs) (map g ys) ≡ map (map f g) (zip xs ys)unzipWith-map : unzipWith f ∘ map g ≗ unzipWith (f ∘ g)map-unzipWith : map (map g) (map h) ∘ unzipWith f ≗ unzipWith (map g h ∘ f)unzip-map : unzip ∘ map (map f g) ≗ map (map f) (map g) ∘ unzipsplitAt-map : splitAt n ∘ map f ≗ map (map f) (map f) ∘ splitAt nuncons-map : uncons ∘ map f ≗ map (map f (map f)) ∘ unconslast-map : last ∘ map f ≗ map f ∘ lasttail-map : tail ∘ map f ≗ map (map f) ∘ tailmapMaybe-cong : f ≗ g → mapMaybe f ≗ mapMaybe gzipWith-cong : (∀ a b → f a b ≡ g a b) → ∀ as → zipWith f as ≗ zipWith g asunzipWith-cong : f ≗ g → unzipWith f ≗ unzipWith gfoldl-cong : (∀ x y → f x y ≡ g x y) → ∀ x → foldl f x ≗ foldl g xalignWith-flip : alignWith f xs ys ≡ alignWith (f ∘ swap) ys xsalignWith-comm : f ∘ swap ≗ f → alignWith f xs ys ≡ alignWith f ys xsalign-flip : align xs ys ≡ map swap (align ys xs)zip-flip : zip xs ys ≡ map swap (zip ys xs)unzipWith-swap : unzipWith (swap ∘ f) ≗ swap ∘ unzipWith funzip-swap : unzip ∘ map swap ≗ swap ∘ unziptake-take : take n (take m xs) ≡ take (n ⊓ m) xstake-drop : take n (drop m xs) ≡ drop m (take (m + n) xs)zip-unzip : uncurry′ zip ∘ unzip ≗ idunzipWith-zipWith : f ∘ uncurry′ g ≗ id →length xs ≡ length ys →unzipWith f (zipWith g xs ys) ≡ (xs , ys)unzip-zip : length xs ≡ length ys → unzip (zip xs ys) ≡ (xs , ys)mapMaybe-++ : mapMaybe f (xs ++ ys) ≡ mapMaybe f xs ++ mapMaybe f ysunzipWith-++ : unzipWith f (xs ++ ys) ≡zip _++_ _++_ (unzipWith f xs) (unzipWith f ys)catMaybes-concatMap : catMaybes ≗ concatMap fromMaybecatMaybes-++ : catMaybes (xs ++ ys) ≡ catMaybes xs ++ catMaybes ysmap-catMaybes : map f ∘ catMaybes ≗ catMaybes ∘ map (Maybe.map f)Any-catMaybes⁺ : Any (M.Any P) xs → Any P (catMaybes xs)mapMaybeIsInj₁∘mapInj₁ : mapMaybe isInj₁ (map inj₁ xs) ≡ xsmapMaybeIsInj₁∘mapInj₂ : mapMaybe isInj₁ (map inj₂ xs) ≡ []mapMaybeIsInj₂∘mapInj₂ : mapMaybe isInj₂ (map inj₂ xs) ≡ xsmapMaybeIsInj₂∘mapInj₁ : mapMaybe isInj₂ (map inj₁ xs) ≡ []```* In `Data.List.Relation.Binary.Pointwise.Base`:```agdaunzip : Pointwise (R ; S) ⇒ (Pointwise R ; Pointwise S)```* In `Data.List.Relation.Binary.Sublist.Setoid`:```agda⊆-upper-bound : ∀ {xs ys zs} (τ : xs ⊆ zs) (σ : ys ⊆ zs) → UpperBound τ σ```* In `Data.List.Relation.Binary.Sublist.Setoid.Properties`:```agda⊆-trans-idˡ : (trans-reflˡ : ∀ {x y} (p : x ≈ y) → trans ≈-refl p ≡ p) →(pxs : xs ⊆ ys) → ⊆-trans ⊆-refl pxs ≡ pxs⊆-trans-idʳ : (trans-reflʳ : ∀ {x y} (p : x ≈ y) → trans p ≈-refl ≡ p) →(pxs : xs ⊆ ys) → ⊆-trans pxs ⊆-refl ≡ pxs⊆-trans-assoc : (≈-assoc : ∀ {w x y z} (p : w ≈ x) (q : x ≈ y) (r : y ≈ z) →trans p (trans q r) ≡ trans (trans p q) r) →(ps : as ⊆ bs) (qs : bs ⊆ cs) (rs : cs ⊆ ds) →⊆-trans ps (⊆-trans qs rs) ≡ ⊆-trans (⊆-trans ps qs) rs```* In `Data.List.Relation.Unary.All`:```agdauniversal-U : Universal (All U)```* In `Data.List.Relation.Unary.All.Properties`:```agdaAll-catMaybes⁺ : All (Maybe.All P) xs → All P (catMaybes xs)Any-catMaybes⁺ : All (Maybe.Any P) xs → All P (catMaybes xs)```* In `Data.List.Relation.Unary.AllPairs.Properties`:```agdacatMaybes⁺ : AllPairs (Pointwise R) xs → AllPairs R (catMaybes xs)tabulate⁺-< : (i < j → R (f i) (f j)) → AllPairs R (tabulate f)```* In `Data.List.Relation.Unary.Any.Properties`:```agdamap-cong : (f g : P ⋐ Q) → (∀ {x} (p : P x) → f p ≡ g p) →(p : Any P xs) → Any.map f p ≡ Any.map g p```* Added new proofs to `Data.List.Relation.Binary.Permutation.Propositional.Properties`:```agdaproduct-↭ : product Preserves _↭_ ⟶ _≡_catMaybes-↭ : xs ↭ ys → catMaybes xs ↭ catMaybes ysmapMaybe-↭ : xs ↭ ys → mapMaybe f xs ↭ mapMaybe f ys```* Added new proofs to `Data.List.Relation.Binary.Permutation.Setoid.Properties.Maybe`:```agdacatMaybes-↭ : xs ↭ ys → catMaybes xs ↭ catMaybes ysmapMaybe-↭ : xs ↭ ys → mapMaybe f xs ↭ mapMaybe f ys```* In `Data.List.Relation.Binary.Subset.Setoid.Properties`:```agdamap⁺ : f Preserves _≈_ ⟶ _≈′_ → as ⊆ bs → map f as ⊆′ map f bsreverse-selfAdjoint : as ⊆ reverse bs → reverse as ⊆ bsreverse⁺ : as ⊆ bs → reverse as ⊆ reverse bsreverse⁻ : reverse as ⊆ reverse bs → as ⊆ bs```* Added new proofs to `Data.List.Relation.Binary.Sublist.Propositional.Slice`:```agda⊆-upper-bound-is-cospan : (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → IsCospan (⊆-upper-bound τ₁ τ₂)⊆-upper-bound-cospan : (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → Cospan τ₁ τ₂```* In `Data.List.Relation.Ternary.Appending.Setoid.Properties`:```agdathrough→ : ∃[ xs ] Pointwise _≈_ as xs × Appending xs bs cs →∃[ ys ] Appending as bs ys × Pointwise _≈_ ys csthrough← : ∃[ ys ] Appending as bs ys × Pointwise _≈_ ys cs →∃[ xs ] Pointwise _≈_ as xs × Appending xs bs csassoc→ : ∃[ xs ] Appending as bs xs × Appending xs cs ds →∃[ ys ] Appending bs cs ys × Appending as ys ds```* In `Data.List.Relation.Ternary.Appending.Properties`:```agdathrough→ : (R ⇒ (S ; T)) → ((U ; V) ⇒ (W ; T)) →∃[ xs ] Pointwise U as xs × Appending V R xs bs cs →∃[ ys ] Appending W S as bs ys × Pointwise T ys csthrough← : ((R ; S) ⇒ T) → ((U ; S) ⇒ (V ; W)) →∃[ ys ] Appending U R as bs ys × Pointwise S ys cs →∃[ xs ] Pointwise V as xs × Appending W T xs bs csassoc→ : (R ⇒ (S ; T)) → ((U ; V) ⇒ (W ; T)) → ((Y ; V) ⇒ X) →∃[ xs ] Appending Y U as bs xs × Appending V R xs cs ds →∃[ ys ] Appending W S bs cs ys × Appending X T as ys dsassoc← : ((S ; T) ⇒ R) → ((W ; T) ⇒ (U ; V)) → (X ⇒ (Y ; V)) →∃[ ys ] Appending W S bs cs ys × Appending X T as ys ds →∃[ xs ] Appending Y U as bs xs × Appending V R xs cs ds```* In `Data.List.NonEmpty.Base`:```agdainits : List A → List⁺ (List A)tails : List A → List⁺ (List A)```* In `Data.List.NonEmpty.Properties`:```agdatoList-inits : toList ∘ List⁺.inits ≗ List.initstoList-tails : toList ∘ List⁺.tails ≗ List.tails```* In `Data.Maybe.Relation.Binary.Pointwise`:```agdapointwise⊆any : Pointwise R (just x) ⊆ Any (R x)```* In `Data.Nat.Divisibility`:```agdaquotient≢0 : m ∣ n → .{{NonZero n}} → NonZero quotientm∣n⇒n≡quotient*m : m ∣ n → n ≡ quotient * mm∣n⇒n≡m*quotient : m ∣ n → n ≡ m * quotientquotient-∣ : m ∣ n → quotient ∣ nquotient>1 : m ∣ n → m < n → 1 < quotientquotient-< : m ∣ n → .{{NonTrivial m}} → .{{NonZero n}} → quotient < nn/m≡quotient : m ∣ n → .{{_ : NonZero m}} → n / m ≡ quotientm/n≡0⇒m<n : .{{_ : NonZero n}} → m / n ≡ 0 → m < nm/n≢0⇒n≤m : .{{_ : NonZero n}} → m / n ≢ 0 → n ≤ mnonZeroDivisor : DivMod dividend divisor → NonZero divisor```* Added new proofs to `Data.Nat.Primality`:```agdarough∧square>⇒prime : .{{NonTrivial n}} → m Rough n → m * m > n → Prime nproductOfPrimes≢0 : All Prime as → NonZero (product as)productOfPrimes≥1 : All Prime as → product as ≥ 1```* Added new proofs in `Data.Nat.Properties`:```agdam≤n+o⇒m∸n≤o : m ≤ n + o → m ∸ n ≤ om<n+o⇒m∸n<o : .{{NonZero o}} → m < n + o → m ∸ n < opred-cancel-≤ : pred m ≤ pred n → (m ≡ 1 × n ≡ 0) ⊎ m ≤ npred-cancel-< : pred m < pred n → m < npred-injective : .{{NonZero m}} → .{{NonZero n}} → pred m ≡ pred n → m ≡ npred-cancel-≡ : pred m ≡ pred n → ((m ≡ 0 × n ≡ 1) ⊎ (m ≡ 1 × n ≡ 0)) ⊎ m ≡ n<⇒<″ : _<_ ⇒ _<″_m≤n⇒∃[o]m+o≡n : .(m ≤ n) → ∃ λ k → m + k ≡ nguarded-∸≗∸ : .(m≤n : m ≤ n) → let k , _ = m≤n⇒∃[o]m+o≡n m≤n in k ≡ n ∸ m```* Added some very-dependent map and zipWith to `Data.Product`.```agdamap-Σ : {B : A → Set b} {P : A → Set p} {Q : {x : A} → P x → B x → Set q} →(f : (x : A) → B x) → (∀ {x} → (y : P x) → Q y (f x)) →((x , y) : Σ A P) → Σ (B x) (Q y)map-Σ′ : {B : A → Set b} {P : Set p} {Q : P → Set q} →(f : (x : A) → B x) → ((x : P) → Q x) → ((x , y) : A × P) → B x × Q yzipWith : {P : A → Set p} {Q : B → Set q} {R : C → Set r} {S : (x : C) → R x → Set s}(_∙_ : A → B → C) → (_∘_ : ∀ {x y} → P x → Q y → R (x ∙ y)) →(_*_ : (x : C) → (y : R x) → S x y) →((a , p) : Σ A P) → ((b , q) : Σ B Q) →S (a ∙ b) (p ∘ q)```* In `Data.Rational.Properties`:```agda1≢0 : 1ℚ ≢ 0ℚ#⇒invertible : p ≢ q → Invertible 1ℚ _*_ (p - q)invertible⇒# : Invertible 1ℚ _*_ (p - q) → p ≢ qisHeytingCommutativeRing : IsHeytingCommutativeRing _≡_ _≢_ _+_ _*_ -_ 0ℚ 1ℚisHeytingField : IsHeytingField _≡_ _≢_ _+_ _*_ -_ 0ℚ 1ℚheytingCommutativeRing : HeytingCommutativeRing 0ℓ 0ℓ 0ℓheytingField : HeytingField 0ℓ 0ℓ 0ℓ```* Added new functions in `Data.String.Base`:```agdamap : (Char → Char) → String → Stringbetween : String → String → String → String```* Added new functions in `Data.Vec.Bounded.Base`:```agdaisBounded : (as : Vec≤ A n) → Vec≤.length as ≤ ntoVec : (as : Vec≤ A n) → Vec A (Vec≤.length as)```* In `Data.Word64.Base`:```agda_≤_ : Rel Word64 zeroshow : Word64 → String```* In `Function.Bundles`, added `_⟶ₛ_` as a synonym for `Func` that canbe used infix.* Re-exported new types and functions in `IO`:```agdaBufferMode : SetnoBuffering : BufferModelineBuffering : BufferModeblockBuffering : Maybe ℕ → BufferModeHandle : Setstdin : Handlestdout : Handlestderr : HandlehSetBuffering : Handle → BufferMode → IO ⊤hGetBuffering : Handle → IO BufferModehFlush : Handle → IO ⊤```* Added new functions in `IO.Base`:```agdawhenInj₂ : E ⊎ A → (A → IO ⊤) → IO ⊤forever : IO ⊤ → IO ⊤```* In `IO.Primitive.Core`:```agda_>>_ : IO A → IO B → IO B```* Added new definition in `Relation.Binary.Construct.Closure.Transitive````agdatransitive⁻ : Transitive _∼_ → TransClosure _∼_ ⇒ _∼_```* Added new proofs in `Relation.Binary.Construct.Composition`:```agdatransitive⇒≈;≈⊆≈ : Transitive ≈ → (≈ ; ≈) ⇒ ≈```* Added new definitions in `Relation.Binary.Definitions````agdaStable _∼_ = ∀ x y → Nullary.Stable (x ∼ y)Empty _∼_ = ∀ {x y} → ¬ (x ∼ y)```* Added new proofs in `Relation.Binary.Properties.Setoid`:```agda≉-irrefl : Irreflexive _≈_ _≉_≈;≈⇒≈ : _≈_ ; _≈_ ⇒ _≈_≈⇒≈;≈ : _≈_ ⇒ _≈_ ; _≈_```* Added new definitions in `Relation.Nullary````agdaRecomputable : Set _WeaklyDecidable : Set _```* Added new proof in `Relation.Nullary.Decidable`:```agda⌊⌋-map′ : (a? : Dec A) → ⌊ map′ t f a? ⌋ ≡ ⌊ a? ⌋```* Added new definitions and proofs in `Relation.Nullary.Decidable.Core`:```agdadec⇒maybe : Dec A → Maybe Arecompute-constant : (a? : Dec A) (p q : A) → recompute a? p ≡ recompute a? qtoSum : Dec A → A ⊎ ¬ AfromSum : A ⊎ ¬ A → Dec A```* Added new definitions in `Relation.Nullary.Negation.Core`:```agdacontradiction-irr : .A → ¬ A → Whatever```* Added new definitions in `Relation.Nullary.Reflects`:```agdarecompute : Reflects A b → Recomputable Arecompute-constant : (r : Reflects A b) (p q : A) → recompute r p ≡ recompute r q```* Added new definitions in `Relation.Unary`:```agdaStable : Pred A ℓ → Set _WeaklyDecidable : Pred A ℓ → Set _```* Enhancements to `Tactic.Cong` - see `README.Tactic.Cong` for details.- Provide a marker function, `⌞_⌟`, for user-guided anti-unification.- Improved support for equalities between terms with instance arguments,such as terms that contain `_/_` or `_%_`.
Version 2.0===========The library has been tested using Agda 2.6.4 and 2.6.4.1.NOTE: Version `2.0` contains various breaking changes and is not backwardscompatible with code written with version `1.X` of the library.Highlights----------* A new tactic `cong!` available from `Tactic.Cong` which automaticallyinfers the argument to `cong` for you via anti-unification.* Improved the `solve` tactic in `Tactic.RingSolver` to work in a muchwider range of situations.* A massive refactoring of the unindexed `Functor`/`Applicative`/`Monad` hierarchyand the `MonadReader` / `MonadState` type classes. These are now usable withinstance arguments as demonstrated in the tests/monad examples.* Significant tightening of `import` statements internally in the library,drastically decreasing the dependencies and hence load time of many keymodules.* A golden testing library in `Test.Golden`. This allows you to run a setof tests and make sure their output matches an expected `golden` value.The test runner has many options: filtering tests by name, dumping thelist of failures to a file, timing the runs, coloured output, etc.Cf. the comments in `Test.Golden` and the standard library's own testsin `tests/` for documentation on how to use the library.Bug-fixes---------* In `Algebra.Structures` the records `IsRing` and `IsRingWithoutOne` contained an unnecessary field`zero : RightZero 0# *`, which could be derived from the other ring axioms.Consequently this field has been removed from the record, and the record`IsRingWithoutAnnihilatingZero` in `Algebra.Structures.Biased` has beendeprecated as it is now identical to is `IsRing`.* In `Algebra.Definitions.RawSemiring` the record `Prime` did notenforce that the number was not divisible by `1#`. To fix this`p∤1 : p ∤ 1#` has been added as a field.* In `Data.Container.FreeMonad`, we give a direct definition of `_⋆_` as an inductivetype rather than encoding it as an instance of `μ`. This ensures Agda notices that`C ⋆ X` is strictly positive in `X` which in turn allows us to use the free monadwhen defining auxiliary (co)inductive types (cf. the `Tap` example in`README.Data.Container.FreeMonad`).* In `Data.Fin.Properties` the `i` argument to `opposite-suc` was implicitbut could not be inferred in general. It has been made explicit.* In `Data.List.Membership.Setoid` the operations `_∷=_` and `_─_`had an extraneous `{A : Set a}` parameter. This has been removed.* In `Data.List.Relation.Ternary.Appending.Setoid` the constructorswere re-exported in their full generality which lead to unsolved metavariables at their use sites. Now versions of the constructors specialisedto use the setoid's carrier set are re-exported.* In `Data.Nat.DivMod` the parameter `o` in the proof `/-monoˡ-≤` wasimplicit but not inferrable. It has been changed to be explicit.* In `Data.Nat.DivMod` the parameter `m` in the proof `+-distrib-/-∣ʳ` wasimplicit but not inferrable, while `n` is explicit but inferrable.They have been to explicit and implicit respectively.* In `Data.Nat.GeneralisedArithmetic` the `s` and `z` arguments to thefollowing functions were implicit but not inferrable:`fold-+`, `fold-k`, `fold-*`, `fold-pull`. They have been made explicit.* In `Data.Rational(.Unnormalised).Properties` the module `≤-Reasoning`exported equality combinators using the generic setoid symbol `_≈_`. Theyhave been renamed to use the same `_≃_` symbol used for non-propositionalequality over `Rational`s, i.e.```agdastep-≈ ↦ step-≃step-≈˘ ↦ step-≃˘```with corresponding associated syntax:```agda_≈⟨_⟩_ ↦ _≃⟨_⟩__≈⟨_⟨_ ↦ _≃⟨_⟨_```* In `Function.Construct.Composition` the combinators`_⟶-∘_`, `_↣-∘_`, `_↠-∘_`, `_⤖-∘_`, `_⇔-∘_`, `_↩-∘_`, `_↪-∘_`, `_↔-∘_`had their arguments in the wrong order. They have been flipped so they canactually be used as a composition operator.* In `Function.Definitions` the definitions of `Surjection`, `Inverseˡ`,`Inverseʳ` were not being re-exported correctly and therefore had an unsolvedmeta-variable whenever this module was explicitly parameterised. This hasbeen fixed.* In `System.Exit` the `ExitFailure` constructor is now carrying an integerrather than a natural. The previous binding was incorrectly assuming thatall exit codes where non-negative.Non-backwards compatible changes--------------------------------### Removed deprecated names* All modules and names that were deprecated in `v1.2` and before havebeen removed.### Changes to `LeftCancellative` and `RightCancellative` in `Algebra.Definitions`* The definitions of the types for cancellativity in `Algebra.Definitions` previouslymade some of their arguments implicit. This was under the assumption that the operators weredefined by pattern matching on the left argument so that Agda could always infer theargument on the RHS.* Although many of the operators defined in the library follow this convention, this is notalways true and cannot be assumed in user's code.* Therefore the definitions have been changed as follows to make all their arguments explicit:- `LeftCancellative _∙_`- From: `∀ x {y z} → (x ∙ y) ≈ (x ∙ z) → y ≈ z`- To: `∀ x y z → (x ∙ y) ≈ (x ∙ z) → y ≈ z`- `RightCancellative _∙_`- From: `∀ {x} y z → (y ∙ x) ≈ (z ∙ x) → y ≈ z`- To: `∀ x y z → (y ∙ x) ≈ (z ∙ x) → y ≈ z`- `AlmostLeftCancellative e _∙_`- From: `∀ {x} y z → ¬ x ≈ e → (x ∙ y) ≈ (x ∙ z) → y ≈ z`- To: `∀ x y z → ¬ x ≈ e → (x ∙ y) ≈ (x ∙ z) → y ≈ z`- `AlmostRightCancellative e _∙_`- From: `∀ {x} y z → ¬ x ≈ e → (y ∙ x) ≈ (z ∙ x) → y ≈ z`- To: `∀ x y z → ¬ x ≈ e → (y ∙ x) ≈ (z ∙ x) → y ≈ z`* Correspondingly some proofs of the above types will need additional arguments passed explicitly.Instances can easily be fixed by adding additional underscores, e.g.- `∙-cancelˡ x` to `∙-cancelˡ x _ _`- `∙-cancelʳ y z` to `∙-cancelʳ _ y z`### Changes to ring structures in `Algebra`* Several ring-like structures now have the multiplicative structure defined byits laws rather than as a substructure, to avoid repeated proofs that theunderlying relation is an equivalence. These are:* `IsNearSemiring`* `IsSemiringWithoutOne`* `IsSemiringWithoutAnnihilatingZero`* `IsRing`* To aid with migration, structures matching the old style ones have been addedto `Algebra.Structures.Biased`, with conversion functions:* `IsNearSemiring*` and `isNearSemiring*`* `IsSemiringWithoutOne*` and `isSemiringWithoutOne*`* `IsSemiringWithoutAnnihilatingZero*` and `isSemiringWithoutAnnihilatingZero*`* `IsRing*` and `isRing*`### Refactoring of lattices in `Algebra.Structures/Bundles` hierarchy* In order to improve modularity and consistency with `Relation.Binary.Lattice`,the structures & bundles for `Semilattice`, `Lattice`, `DistributiveLattice`& `BooleanAlgebra` have been moved out of the `Algebra` modules and into theirown hierarchy in `Algebra.Lattice`.* All submodules, (e.g. `Algebra.Properties.Semilattice` or `Algebra.Morphism.Lattice`)have been moved to the corresponding place under `Algebra.Lattice` (e.g.`Algebra.Lattice.Properties.Semilattice` or `Algebra.Lattice.Morphism.Lattice`). Seethe `Deprecated modules` section below for full details.* The definition of `IsDistributiveLattice` and `IsBooleanAlgebra` have changed sothat they are no longer right-biased which hindered compositionality.More concretely, `IsDistributiveLattice` now has fields:```agda∨-distrib-∧ : ∨ DistributesOver ∧∧-distrib-∨ : ∧ DistributesOver ∨```instead of```agda∨-distribʳ-∧ : ∨ DistributesOverʳ ∧```and `IsBooleanAlgebra` now has fields:```agda∨-complement : Inverse ⊤ ¬ ∨∧-complement : Inverse ⊥ ¬ ∧```instead of:```agda∨-complementʳ : RightInverse ⊤ ¬ ∨∧-complementʳ : RightInverse ⊥ ¬ ∧```* To allow construction of these structures via their old form, smart constructorshave been added to a new module `Algebra.Lattice.Structures.Biased`, which are byre-exported automatically by `Algebra.Lattice`. For example, if before you wrote:```agda∧-∨-isDistributiveLattice = record{ isLattice = ∧-∨-isLattice; ∨-distribʳ-∧ = ∨-distribʳ-∧}```you can use the smart constructor `isDistributiveLatticeʳʲᵐ` to write:```agda∧-∨-isDistributiveLattice = isDistributiveLatticeʳʲᵐ (record{ isLattice = ∧-∨-isLattice; ∨-distribʳ-∧ = ∨-distribʳ-∧})```without having to prove full distributivity.* Added new `IsBoundedSemilattice`/`BoundedSemilattice` records.* Added new aliases `Is(Meet/Join)(Bounded)Semilattice` for `Is(Bounded)Semilattice`which can be used to indicate meet/join-ness of the original structures, andthe field names in `IsSemilattice` and `Semilattice` have been renamed from`∧-cong` to `∙-cong`to indicate their undirected nature.* Finally, the following auxiliary files have been moved:```agdaAlgebra.Properties.Semilattice ↦ Algebra.Lattice.Properties.SemilatticeAlgebra.Properties.Lattice ↦ Algebra.Lattice.Properties.LatticeAlgebra.Properties.DistributiveLattice ↦ Algebra.Lattice.Properties.DistributiveLatticeAlgebra.Properties.BooleanAlgebra ↦ Algebra.Lattice.Properties.BooleanAlgebraAlgebra.Properties.BooleanAlgebra.Expression ↦ Algebra.Lattice.Properties.BooleanAlgebra.ExpressionAlgebra.Morphism.LatticeMonomorphism ↦ Algebra.Lattice.Morphism.LatticeMonomorphism```#### Changes to `Algebra.Morphism.Structures`* Previously the record definitions:```IsNearSemiringHomomorphismIsSemiringHomomorphismIsRingHomomorphism```all had two separate proofs of `IsRelHomomorphism` within them.* To fix this they have all been redefined to build up from `IsMonoidHomomorphism`,`IsNearSemiringHomomorphism`, and `IsSemiringHomomorphism` respectively,adding a single property at each step.* Similarly, `IsLatticeHomomorphism` is now built as`IsRelHomomorphism` along with proofs that `_∧_` and `_∨_` are homomorphic.* Finally `⁻¹-homo` in `IsRingHomomorphism` has been renamed to `-‿homo`.#### Renamed `Category` modules to `Effect`* As observed by Wen Kokke in issue #1636, it no longer really makes senseto group the modules which correspond to the variety of concepts of(effectful) type constructor arising in functional programming (esp. in Haskell)such as `Monad`, `Applicative`, `Functor`, etc, under `Category.*`,as this obstructs the importing of the `agda-categories` development intothe Standard Library, and moreover needlessly restricts the applicability ofcategorical concepts to this (highly specific) mode of use.* Correspondingly, client modules grouped under `*.Categorical.*` whichexploit such structure for effectful programming have been renamed`*.Effectful`, with the originals being deprecated.* Full list of moved modules:```agdaCodata.Sized.Colist.Categorical ↦ Codata.Sized.Colist.EffectfulCodata.Sized.Covec.Categorical ↦ Codata.Sized.Covec.EffectfulCodata.Sized.Delay.Categorical ↦ Codata.Sized.Delay.EffectfulCodata.Sized.Stream.Categorical ↦ Codata.Sized.Stream.EffectfulData.List.Categorical ↦ Data.List.EffectfulData.List.Categorical.Transformer ↦ Data.List.Effectful.TransformerData.List.NonEmpty.Categorical ↦ Data.List.NonEmpty.EffectfulData.List.NonEmpty.Categorical.Transformer ↦ Data.List.NonEmpty.Effectful.TransformerData.Maybe.Categorical ↦ Data.Maybe.EffectfulData.Maybe.Categorical.Transformer ↦ Data.Maybe.Effectful.TransformerData.Product.Categorical.Examples ↦ Data.Product.Effectful.ExamplesData.Product.Categorical.Left ↦ Data.Product.Effectful.LeftData.Product.Categorical.Left.Base ↦ Data.Product.Effectful.Left.BaseData.Product.Categorical.Right ↦ Data.Product.Effectful.RightData.Product.Categorical.Right.Base ↦ Data.Product.Effectful.Right.BaseData.Sum.Categorical.Examples ↦ Data.Sum.Effectful.ExamplesData.Sum.Categorical.Left ↦ Data.Sum.Effectful.LeftData.Sum.Categorical.Left.Transformer ↦ Data.Sum.Effectful.Left.TransformerData.Sum.Categorical.Right ↦ Data.Sum.Effectful.RightData.Sum.Categorical.Right.Transformer ↦ Data.Sum.Effectful.Right.TransformerData.These.Categorical.Examples ↦ Data.These.Effectful.ExamplesData.These.Categorical.Left ↦ Data.These.Effectful.LeftData.These.Categorical.Left.Base ↦ Data.These.Effectful.Left.BaseData.These.Categorical.Right ↦ Data.These.Effectful.RightData.These.Categorical.Right.Base ↦ Data.These.Effectful.Right.BaseData.Vec.Categorical ↦ Data.Vec.EffectfulData.Vec.Categorical.Transformer ↦ Data.Vec.Effectful.TransformerData.Vec.Recursive.Categorical ↦ Data.Vec.Recursive.EffectfulFunction.Identity.Categorical ↦ Function.Identity.EffectfulIO.Categorical ↦ IO.EffectfulReflection.TCM.Categorical ↦ Reflection.TCM.Effectful```* Full list of new modules:```Algebra.Construct.InitialAlgebra.Construct.TerminalData.List.Effectful.TransformerData.List.NonEmpty.Effectful.TransformerData.Maybe.Effectful.TransformerData.Sum.Effectful.Left.TransformerData.Sum.Effectful.Right.TransformerData.Vec.Effectful.TransformerEffect.EmptyEffect.ChoiceEffect.Monad.Error.TransformerEffect.Monad.IdentityEffect.Monad.IOEffect.Monad.IO.InstancesEffect.Monad.Reader.IndexedEffect.Monad.Reader.InstancesEffect.Monad.Reader.TransformerEffect.Monad.Reader.Transformer.BaseEffect.Monad.State.IndexedEffect.Monad.State.InstancesEffect.Monad.State.TransformerEffect.Monad.State.Transformer.BaseEffect.Monad.WriterEffect.Monad.Writer.IndexedEffect.Monad.Writer.InstancesEffect.Monad.Writer.TransformerEffect.Monad.Writer.Transformer.BaseIO.EffectfulIO.Instances```### Refactoring of the unindexed Functor/Applicative/Monad hierarchy in `Effect`* The unindexed versions are not defined in terms of the named versions anymore.* The `RawApplicative` and `RawMonad` type classes have been relaxed so that the underlyingfunctors do not need their domain and codomain to live at the same Set level.This is needed for level-increasing functors like `IO : Set l → Set (suc l)`.* `RawApplicative` is now `RawFunctor + pure + _<*>_` and `RawMonad` is now`RawApplicative` + `_>>=_`.This reorganisation means in particular that the functor/applicative of a monadare not computed using `_>>=_`. This may break proofs.* When `F : Set f → Set f` we moreover have a definable join/μ operator`join : (M : RawMonad F) → F (F A) → F A`.* We now have `RawEmpty` and `RawChoice` respectively packing `empty : M A` and`(<|>) : M A → M A → M A`. `RawApplicativeZero`, `RawAlternative`, `RawMonadZero`,`RawMonadPlus` are all defined in terms of these.* `MonadT T` now returns a `MonadTd` record that packs both a proof that the`Monad M` transformed by `T` is a monad and that we can `lift` a computation`M A` to a transformed computation `T M A`.* The monad transformer are not mere aliases anymore, they are record-wrappedwhich allows constraints such as `MonadIO (StateT S (ReaderT R IO))` to bedischarged by instance arguments.* The mtl-style type classes (`MonadState`, `MonadReader`) do not contain a proofthat the underlying functor is a `Monad` anymore. This ensures we do not haveconflicting `Monad M` instances from a pair of `MonadState S M` & `MonadReader R M`constraints.* `MonadState S M` is now defined in terms of```agdagets : (S → A) → M Amodify : (S → S) → M ⊤```with `get` and `put` defined as derived notions.This is needed because `MonadState S M` does not pack a `Monad M` instance anymoreand so we cannot define `modify f` as `get >>= λ s → put (f s)`.* `MonadWriter 𝕎 M` is defined similarly:```agdawriter : W × A → M Alisten : M A → M (W × A)pass : M ((W → W) × A) → M A```with `tell` defined as a derived notion.Note that `𝕎` is a `RawMonoid`, not a `Set` and `W` is the carrier of the monoid.#### Moved `Codata` modules to `Codata.Sized`* Due to the change in Agda 2.6.2 where sized types are no longer compatiblewith the `--safe` flag, it has become clear that a third variant of codatawill be needed using coinductive records.* Therefore all existing modules in `Codata` which used sized types have beenmoved inside a new folder named `Codata.Sized`, e.g. `Codata.Stream`has become `Codata.Sized.Stream`.### New proof-irrelevant for empty type in `Data.Empty`* The definition of `⊥` has been changed to```agdaprivatedata Empty : Set where⊥ : Set⊥ = Irrelevant Empty```in order to make ⊥ proof irrelevant. Any two proofs of `⊥` or of a negatedstatements are now *judgmentally* equal to each other.* Consequently the following two definitions have been modified:+ In `Relation.Nullary.Decidable.Core`, the type of `dec-no` has changed```agdadec-no : (p? : Dec P) → ¬ P → ∃ λ ¬p′ → p? ≡ no ¬p′↦dec-no : (p? : Dec P) (¬p : ¬ P) → p? ≡ no ¬p```+ In `Relation.Binary.PropositionalEquality`, the type of `≢-≟-identity` has changed```agda≢-≟-identity : x ≢ y → ∃ λ ¬eq → x ≟ y ≡ no ¬eq↦≢-≟-identity : (x≢y : x ≢ y) → x ≟ y ≡ no x≢y```### Deprecation of `_≺_` in `Data.Fin.Base`* In `Data.Fin.Base` the relation `_≺_` and its single constructor `_≻toℕ_`have been deprecated in favour of their extensional equivalent `_<_`but omitting the inversion principle which pattern matching on `_≻toℕ_`would achieve; this instead is proxied by the property `Data.Fin.Properties.toℕ<`.* Consequently in `Data.Fin.Induction`:```≺-Rec≺-wellFounded≺-recBuilder≺-rec```these functions are also deprecated.* Likewise in `Data.Fin.Properties` the proofs `≺⇒<′` and `<′⇒≺` have been deprecatedin favour of their proxy counterparts `<⇒<′` and `<′⇒<`.### Standardisation of `insertAt`/`updateAt`/`removeAt` in `Data.List`/`Data.Vec`* Previously, the names and argument order of index-based insertion, update and removal functions forvarious types of lists and vectors were inconsistent.* To fix this the names have all been standardised to `insertAt`/`updateAt`/`removeAt`.* Correspondingly the following changes have occurred:* In `Data.List.Base` the following have been added:```agdainsertAt : (xs : List A) → Fin (suc (length xs)) → A → List AupdateAt : (xs : List A) → Fin (length xs) → (A → A) → List AremoveAt : (xs : List A) → Fin (length xs) → List A```and the following has been deprecated```_─_ ↦ removeAt```* In `Data.Vec.Base`:```agdainsert ↦ insertAtremove ↦ removeAtupdateAt : Fin n → (A → A) → Vec A n → Vec A n↦updateAt : Vec A n → Fin n → (A → A) → Vec A n```* In `Data.Vec.Functional`:```agdaremove : Fin (suc n) → Vector A (suc n) → Vector A n↦removeAt : Vector A (suc n) → Fin (suc n) → Vector A nupdateAt : Fin n → (A → A) → Vector A n → Vector A n↦updateAt : Vector A n → Fin n → (A → A) → Vector A n```* The old names (and the names of all proofs about these functions) have been deprecated appropriately.#### Standardisation of `lookup` in `Data.(List/Vec/...)`* All the types of `lookup` functions (and variants) in the following moduleshave been changed to match the argument convention adopted in the `List` module (i.e.`lookup` takes its container first and the index, whose type may depend on thecontainer value, second):```Codata.Guarded.StreamCodata.Guarded.Stream.Relation.Binary.PointwiseCodata.Musical.Colist.BaseCodata.Musical.Colist.Relation.Unary.Any.PropertiesCodata.Musical.CovecCodata.Musical.StreamCodata.Sized.ColistCodata.Sized.CovecCodata.Sized.StreamData.Vec.Relation.Unary.AllData.Star.EnvironmentData.Star.PointerData.Star.VecData.TrieData.Trie.NonEmptyData.Tree.AVLData.Tree.AVL.IndexedData.Tree.AVL.MapData.Tree.AVL.NonEmptyData.Vec.Recursive```* To accommodate this in in `Data.Vec.Relation.Unary.Linked.Properties`and `Codata.Guarded.Stream.Relation.Binary.Pointwise`, the proofscalled `lookup` have been renamed `lookup⁺`.#### Changes to `Data.(Nat/Integer/Rational)` proofs of `NonZero`/`Positive`/`Negative` to use instance arguments* Many numeric operations in the library require their arguments to be non-zero,and various proofs require their arguments to be non-zero/positive/negative etc.As discussed on the [mailing list](https://lists.chalmers.se/pipermail/agda/2021/012693.html),the previous way of constructing and passing round these proofs was extremelyclunky and lead to messy and difficult to read code.* We have therefore changed every occurrence where we need a proof ofnon-zeroness/positivity/etc. to take it as an irrelevant[instance argument](https://agda.readthedocs.io/en/latest/language/instance-arguments.html).See the mailing list discussion for a fuller explanation of the motivation and implementation.* For example, whereas the type of division over `ℕ` used to be:```agda_/_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → ℕ```it is now:```agda_/_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → ℕ```* This means that as long as an instance of `NonZero n` is in scope then you can write`m / n` without having to explicitly provide a proof, as instance search will fill it infor you. The full list of such operations changed is as follows:- In `Data.Nat.DivMod`: `_/_`, `_%_`, `_div_`, `_mod_`- In `Data.Nat.Pseudorandom.LCG`: `Generator`- In `Data.Integer.DivMod`: `_divℕ_`, `_div_`, `_modℕ_`, `_mod_`- In `Data.Rational`: `mkℚ+`, `normalize`, `_/_`, `1/_`- In `Data.Rational.Unnormalised`: `_/_`, `1/_`, `_÷_`* At the moment, there are 4 different ways such instance arguments can be provided,listed in order of convenience and clarity:1. *Automatic basic instances* - the standard library provides instances based onthe constructors of each numeric type in `Data.X.Base`. For example,`Data.Nat.Base` constrains an instance of `NonZero (suc n)` for any `n`and `Data.Integer.Base` contains an instance of `NonNegative (+ n)` for any `n`.Consequently, if the argument is of the required form, these instances will alwaysbe filled in by instance search automatically, e.g.```agda0/n≡0 : 0 / suc n ≡ 0```2. *Add an instance argument parameter* - You can provide the instance argument asa parameter to your function and Agda's instance search will automatically use itin the correct place without you having to explicitly pass it, e.g.```agda0/n≡0 : .{{_ : NonZero n}} → 0 / n ≡ 0```3. *Define the instance locally* - You can define an instance argument in scope(e.g. in a `where` clause) and Agda's instance search will again find it automatically,e.g.```agdainstancen≢0 : NonZero nn≢0 = ...0/n≡0 : 0 / n ≡ 0```4. *Pass the instance argument explicitly* - Finally, if all else fails you can pass theinstance argument explicitly into the function using `{{ }}`, e.g.```0/n≡0 : ∀ n (n≢0 : NonZero n) → ((0 / n) {{n≢0}}) ≡ 0```* Suitable constructors for `NonZero`/`Positive` etc. can be found in `Data.X.Base`.* A full list of proofs that have changed to use instance arguments is availableat the end of this file. Notable changes to proofs are now discussed below.* Previously one of the hacks used in proofs was to explicitly refer to everythingin the correct form, e.g. if the argument `n` had to be non-zero then you wouldrefer to the argument as `suc n` everywhere instead of `n`, e.g.```n/n≡1 : ∀ n → suc n / suc n ≡ 1```This made the proofs extremely difficult to use if your term wasn't in the form `suc n`.After being updated to use instance arguments instead, the proof above becomes:```n/n≡1 : ∀ n {{_ : NonZero n}} → n / n ≡ 1```However, note that this means that if you passed in the value `x` to these proofsbefore, then you will now have to pass in `suc x`. The proofs for which thearguments have changed form in this way are highlighted in the list at the bottomof the file.* Finally, in `Data.Rational.Unnormalised.Base` the definition of `_≢0` is nowredundant and so has been removed. Additionally the following proofs about it havealso been removed from `Data.Rational.Unnormalised.Properties`:```p≄0⇒∣↥p∣≢0 : ∀ p → p ≠ 0ℚᵘ → ℤ.∣ (↥ p) ∣ ≢0∣↥p∣≢0⇒p≄0 : ∀ p → ℤ.∣ (↥ p) ∣ ≢0 → p ≠ 0ℚᵘ```### Changes to the definition of `_≤″_` in `Data.Nat.Base` (issue #1919)* The definition of `_≤″_` was previously:```agdarecord _≤″_ (m n : ℕ) : Set whereconstructor less-than-or-equalfield{k} : ℕproof : m + k ≡ n```which introduced a spurious additional definition, when this is in fact, modulofield names and implicit/explicit qualifiers, equivalent to the definition of left-divisibility, `_∣ˡ_` for the `RawMagma` structure of `_+_`.* Since the addition of raw bundles to `Data.X.Base`, this definition can now bemade directly. Accordingly, the definition has been changed to:```agda_≤″_ : (m n : ℕ) → Set_≤″_ = _∣ˡ_ +-rawMagmapattern less-than-or-equal {k} prf = k , prf```* Knock-on consequences include the need to retain the old constructorname, now introduced as a pattern synonym, and introduction of (a functionequivalent to) the former field name/projection function `proof` as`≤″-proof` in `Data.Nat.Properties`.### Changes to definition of `Prime` in `Data.Nat.Primality`* The definition of `Prime` was:```agdaPrime 0 = ⊥Prime 1 = ⊥Prime (suc (suc n)) = (i : Fin n) → 2 + toℕ i ∤ 2 + n```which was very hard to reason about as, not only did it involve conversionto and from the `Fin` type, it also required that the divisor was of the form`2 + toℕ i`, which has exactly the same problem as the `suc n` hack describedabove used for non-zeroness.* To make it easier to use, reason about and read, the definition has beenchanged to:```agdarecord Prime (p : ℕ) : Set whereconstructor primefield.{{nontrivial}} : NonTrivial pnotComposite : ¬ Composite p```where `Composite` is now defined as the diagonal of the new relation`_HasNonTrivialDivisorLessThan_` in `Data.Nat.Divisibility.Core`.### Changes to operation reduction behaviour in `Data.Rational(.Unnormalised)`* Currently arithmetic expressions involving rationals (both normalised andunnormalised) undergo disastrous exponential normalisation. For example,`p + q` would often be normalised by Agda to`(↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)`. While the normalised formof `p + q + r + s + t + u + v` would be ~700 lines long. This behaviouroften chokes both type-checking and the display of the expressions in the IDE.* To avoid this expansion and make non-trivial reasoning about rationals actually feasible:1. the records `ℚᵘ` and `ℚ` have both had the `no-eta-equality` flag enabled2. definition of arithmetic operations have trivial pattern matching added toprevent them reducing, e.g.```agdap + q = (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)```has been changed to```p@record{} + q@record{} = (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)```* As a consequence of this, some proofs that relied either on this reduction behaviouror on eta-equality may no longer type-check.* There are several ways to fix this:1. The principled way is to not rely on this reduction behaviour in the first place.The `Properties` files for rational numbers have been greatly expanded in `v1.7`and `v2.0`, and we believe most proofs should be able to be built up from existingproofs contained within these files.2. Alternatively, annotating any rational arguments to a proof with either`@record{}` or `@(mkℚ _ _ _)` should restore the old reduction behaviour for anyterms involving those parameters.3. Finally, if the above approaches are not viable then you may be forced to explicitlyuse `cong` combined with a lemma that proves the old reduction behaviour.* Similarly, in order to prevent reduction, the equality `_≃_` in `Data.Rational.Base`has been made into a data type with the single constructor `*≡*`. The destructor`drop-*≡*` has been added to `Data.Rational.Properties`.#### Deprecation of old `Function` hierarchy* The new `Function` hierarchy was introduced in `v1.2` which followsthe same `Core`/`Definitions`/`Bundles`/`Structures` as all the otherhierarchies in the library.* At the time the old function hierarchy in:```Function.EqualityFunction.InjectionFunction.SurjectionFunction.BijectionFunction.LeftInverseFunction.InverseFunction.HalfAdjointEquivalenceFunction.Related```was unofficially deprecated, but could not be officially deprecated becauseof it's widespread use in the rest of the library.* Now, the old hierarchy modules have all been officially deprecated. Alluses of them in the rest of the library have been switched to use thenew hierarchy.* The latter is unfortunately a relatively big breaking change, but was judgedto be unavoidable given how widely used the old hierarchy was.#### Changes to the new `Function` hierarchy* In `Function.Bundles` the names of the fields in the records have beenchanged from `f`, `g`, `cong₁` and `cong₂` to `to`, `from`, `to-cong`, `from-cong`.* In `Function.Definitions`, the module no longer has two equalities asmodule arguments, as they did not interact as intended with the re-exportsfrom `Function.Definitions.(Core1/Core2)`. The latter two modules havebeen removed and their definitions folded into `Function.Definitions`.* In `Function.Definitions` the following definitions have been changed from:```Surjective f = ∀ y → ∃ λ x → f x ≈₂ yInverseˡ f g = ∀ y → f (g y) ≈₂ yInverseʳ f g = ∀ x → g (f x) ≈₁ x```to:```Surjective f = ∀ y → ∃ λ x → ∀ {z} → z ≈₁ x → f z ≈₂ yInverseˡ f g = ∀ {x y} → y ≈₁ g x → f y ≈₂ xInverseʳ f g = ∀ {x y} → y ≈₂ f x → g y ≈₁ x```This is for several reasons:i) the new definitions compose much more easily,ii) Agda can better infer the equalities used.* To ease backwards compatibility:- the old definitions have been moved to the new names `StrictlySurjective`,`StrictlyInverseˡ` and `StrictlyInverseʳ`.- The records in `Function.Structures` and `Function.Bundles` export proofsof these under the names `strictlySurjective`, `strictlyInverseˡ` and`strictlyInverseʳ`,- Conversion functions for the definitions have been added in both directionsto `Function.Consequences(.Propositional/Setoid)`.- Conversion functions for structures have been added in`Function.Structures.Biased`.### New `Function.Strict`* The module `Strict` has been deprecated in favour of `Function.Strict`and the definitions of strict application, `_$!_` and `_$!′_`, have beenmoved from `Function.Base` to `Function.Strict`.* The contents of `Function.Strict` is now re-exported by `Function`.### Change to the definition of `WfRec` in `Induction.WellFounded` (issue #2083)* Previously, the definition of `WfRec` was:```agdaWfRec : Rel A r → ∀ {ℓ} → RecStruct A ℓ _WfRec _<_ P x = ∀ y → y < x → P y```which meant that all arguments involving accessibility and wellfoundedness proofswere polluted by almost-always-inferrable explicit arguments for the `y` position.* The definition has now been changed to make that argument *implicit*, as```agdaWfRec : Rel A r → ∀ {ℓ} → RecStruct A ℓ _WfRec _<_ P x = ∀ {y} → y < x → P y```### Reorganisation of `Reflection` modules* Under the `Reflection` module, there were various impending name clashesbetween the core AST as exposed by Agda and the annotated AST defined inthe library.* While the content of the modules remain the same, the modules themselveshave therefore been renamed as follows:```Reflection.Annotated ↦ Reflection.AnnotatedASTReflection.Annotated.Free ↦ Reflection.AnnotatedAST.FreeReflection.Abstraction ↦ Reflection.AST.AbstractionReflection.Argument ↦ Reflection.AST.ArgumentReflection.Argument.Information ↦ Reflection.AST.Argument.InformationReflection.Argument.Quantity ↦ Reflection.AST.Argument.QuantityReflection.Argument.Relevance ↦ Reflection.AST.Argument.RelevanceReflection.Argument.Modality ↦ Reflection.AST.Argument.ModalityReflection.Argument.Visibility ↦ Reflection.AST.Argument.VisibilityReflection.DeBruijn ↦ Reflection.AST.DeBruijnReflection.Definition ↦ Reflection.AST.DefinitionReflection.Instances ↦ Reflection.AST.InstancesReflection.Literal ↦ Reflection.AST.LiteralReflection.Meta ↦ Reflection.AST.MetaReflection.Name ↦ Reflection.AST.NameReflection.Pattern ↦ Reflection.AST.PatternReflection.Show ↦ Reflection.AST.ShowReflection.Traversal ↦ Reflection.AST.TraversalReflection.Universe ↦ Reflection.AST.UniverseReflection.TypeChecking.Monad ↦ Reflection.TCMReflection.TypeChecking.Monad.Categorical ↦ Reflection.TCM.CategoricalReflection.TypeChecking.Monad.Format ↦ Reflection.TCM.FormatReflection.TypeChecking.Monad.Syntax ↦ Reflection.TCM.InstancesReflection.TypeChecking.Monad.Instances ↦ Reflection.TCM.Syntax```* A new module `Reflection.AST` that re-exports the contents of thesubmodules has been added.### Reorganisation of the `Relation.Nullary` hierarchy* It was very difficult to use the `Relation.Nullary` modules, as`Relation.Nullary` contained the basic definitions of negation, decidability etc.,and the operations and proofs about these definitions were spread over`Relation.Nullary.(Negation/Product/Sum/Implication etc.)`.* To fix this all the contents of the latter is now exported by `Relation.Nullary`.* In order to achieve this the following backwards compatible changes have been made:1. the definition of `Dec` and `recompute` have been moved to `Relation.Nullary.Decidable.Core`2. the definition of `Reflects` has been moved to `Relation.Nullary.Reflects`3. the definition of `¬_` has been moved to `Relation.Nullary.Negation.Core`4. The modules `Relation.Nullary.(Product/Sum/Implication)` have been deprecatedand their contents moved to `Relation.Nullary.(Negation/Reflects/Decidable)`.5. The proof `T?` has been moved from `Data.Bool.Properties` to `Relation.Nullary.Decidable.Core`(but is still re-exported by the former).as well as the following breaking changes:1. `¬?` has been moved from `Relation.Nullary.Negation.Core` to`Relation.Nullary.Decidable.Core`2. `¬-reflects` has been moved from `Relation.Nullary.Negation.Core` to`Relation.Nullary.Reflects`.3. `decidable-stable`, `excluded-middle` and `¬-drop-Dec` have been movedfrom `Relation.Nullary.Negation` to `Relation.Nullary.Decidable`.4. `fromDec` and `toDec` have been moved from `Data.Sum.Base` to `Data.Sum`.### (Issue #2096) Introduction of flipped and negated relation symbols to bundles in `Relation.Binary.Bundles`* Previously, bundles such as `Preorder`, `Poset`, `TotalOrder` etc. did not have the flippedand negated versions of the operators exposed. In some cases they could obtained by opening therelevant `Relation.Binary.Properties.X` file but usually they had to be redefined every time.* To fix this, these bundles now all export all 4 versions of the operator: normal, converse, negated,converse-negated. Accordingly they are no longer exported from the corresponding `Properties` file.* To make this work for `Preorder`, it was necessary to change the name of the relation symbol.Previously, the symbol was `_∼_` which is (notationally) symmetric, so that itsconverse relation could only be discussed *semantically* in terms of `flip _∼_`.* Now, the `Preorder` record field `_∼_` has been renamed to `_≲_`, with `_≳_`introduced as a definition in `Relation.Binary.Bundles.Preorder`.Partial backwards compatible has been achieved by redeclaring a deprecated versionof the old symbol in the record. Therefore, only _declarations_ of `PartialOrder` records willneed their field names updating.### Changes to definition of `IsStrictTotalOrder` in `Relation.Binary.Structures`* The previous definition of the record `IsStrictTotalOrder` did notbuild upon `IsStrictPartialOrder` as would be expected.Instead it omitted several fields like irreflexivity as they were derivable from theproof of trichotomy. However, this led to problems further up the hierarchy wherebundles such as `StrictTotalOrder` which contained multiple distinct proofs of`IsStrictPartialOrder`.* To remedy this the definition of `IsStrictTotalOrder` has been changed to sothat it builds upon `IsStrictPartialOrder` as would be expected.* To aid migration, the old record definition has been moved to`Relation.Binary.Structures.Biased` which contains the `isStrictTotalOrderᶜ`smart constructor (which is re-exported by `Relation.Binary`) . Therefore the old code:```agda<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isEquivalence = isEquivalence; trans = <-trans; compare = <-cmp}```can be migrated either by updating to the new record fields if you have a proof of `IsStrictPartialOrder`available:```agda<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = record{ isStrictPartialOrder = <-isStrictPartialOrder; compare = <-cmp}```or simply applying the smart constructor to the record definition as follows:```agda<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-isStrictTotalOrder = isStrictTotalOrderᶜ record{ isEquivalence = isEquivalence; trans = <-trans; compare = <-cmp}```### Changes to the interface of `Relation.Binary.Reasoning.Triple`* The module `Relation.Binary.Reasoning.Base.Triple` now takes an extra proofthat the strict relation is irreflexive.* This allows the addition of the following new proof combinator:```agdabegin-contradiction : (r : x IsRelatedTo x) → {s : True (IsStrict? r)} → A```that takes a proof that a value is strictly less than itself and then applies theprinciple of explosion to derive anything.* Specialised versions of this combinator are available in the `Reasoning` modulesexported by the following modules:```Data.Nat.PropertiesData.Nat.Binary.PropertiesData.Integer.PropertiesData.Rational.Unnormalised.PropertiesData.Rational.PropertiesData.Vec.Relation.Binary.Lex.StrictData.Vec.Relation.Binary.Lex.NonStrictRelation.Binary.Reasoning.StrictPartialOrderRelation.Binary.Reasoning.PartialOrder```### A more modular design for `Relation.Binary.Reasoning`* Previously, every `Reasoning` module in the library tended to roll it's own setof syntax for the combinators. This hindered consistency and maintainability.* To improve the situation, a new module `Relation.Binary.Reasoning.Syntax`has been introduced which exports a wide range of sub-modules containingpre-existing reasoning combinator syntax.* This makes it possible to add new or rename existing reasoning combinators to apre-existing `Reasoning` module in just a couple of lines(e.g. see `∣-Reasoning` in `Data.Nat.Divisibility`)* One pre-requisite for that is that `≡-Reasoning` has been moved from`Relation.Binary.PropositionalEquality.Core` (which shouldn't beimported anyway as it's a `Core` module) to`Relation.Binary.PropositionalEquality.Properties`.It is still exported by `Relation.Binary.PropositionalEquality`.### Renaming of symmetric combinators in `Reasoning` modules* We've had various complaints about the symmetric version of reasoning combinatorsthat use the syntax `_R˘⟨_⟩_` for some relation `R`, (e.g. `_≡˘⟨_⟩_` and `_≃˘⟨_⟩_`)introduced in `v1.0`. In particular:1. The symbol `˘` is hard to type.2. The symbol `˘` doesn't convey the direction of the equality3. The left brackets aren't vertically aligned with the left brackets of the non-symmetric version.* To address these problems we have renamed all the symmetric versions of thecombinators from `_R˘⟨_⟩_` to `_R⟨_⟨_` (the direction of the last bracket is flippedto indicate the quality goes from right to left).* The old combinators still exist but have been deprecated. However due to[Agda issue #5617](https://github.com/agda/agda/issues/5617), the deprecation warningsdon't fire correctly. We will not remove the old combinators before the above issue isaddressed. However, we still encourage migrating to the new combinators!* On a Linux-based system, the following command was used to globally migrate all uses of theold combinators to the new ones in the standard library itself.It *may* be useful when trying to migrate your own code:```bashfind . -type f -name "*.agda" -print0 | xargs -0 sed -i -e 's/˘⟨\(.*\)⟩/⟨\1⟨/g'```USUAL CAVEATS: It has not been widely tested and the standard library developers are notresponsible for the results of this command. It is strongly recommended you back up yourwork before you attempt to run it.* NOTE: this refactoring may require some extra bracketing around the operator `_⟨_⟩_` from`Function.Base` if the `_⟨_⟩_` operator is used within the reasoning proof. The symptomfor this is a `Don't know how to parse` error.### Improvements to `Text.Pretty` and `Text.Regex`* In `Text.Pretty`, `Doc` is now a record rather than a type alias. Thishelps Agda reconstruct the `width` parameter when the module is openedwithout it being applied. In particular this allows users to writewidth-generic pretty printers and only pick a width when calling therenderer by using this import style:```open import Text.Pretty using (Doc; render)-- ^-- no width parameter for Doc & renderopen module Pretty {w} = Text.Pretty w hiding (Doc; render)-- ^-- implicit width parameter for the combinatorspretty : Doc wpretty = ? -- you can use the combinators here and there won't be any-- issues related to the fact that `w` cannot be reconstructed-- anymoremain = do-- you can now use the same pretty with different widths:putStrLn $ render 40 prettyputStrLn $ render 80 pretty```* In `Text.Regex.Search` the `searchND` function finding infix matches hasbeen tweaked to make sure the returned solution is a local maximum in termsof length. It used to be that we would make the match start as late aspossible and finish as early as possible. It's now the reverse.So `[a-zA-Z]+.agdai?` run on "the path _build/Main.agdai corresponds to"will return "Main.agdai" when it used to be happy to just return "n.agda".### Other* In accordance with changes to the flags in Agda 2.6.3, all modules that previously usedthe `--without-K` flag now use the `--cubical-compatible` flag instead.* In `Algebra.Core` the operations `Opₗ` and `Opᵣ` have moved to `Algebra.Module.Core`.* In `Algebra.Definitions.RawMagma.Divisibility` the definitions for `_∣ˡ_` and `_∣ʳ_`have been changed from being defined as raw products to being defined as records. However,the record constructors are called `_,_` so the changes required are minimal.* In `Codata.Guarded.Stream` the following functions have been modified to have simpler definitions:* `cycle`* `interleave⁺`* `cantor`Furthermore, the direction of interleaving of `cantor` has changed. Precisely,suppose `pair` is the cantor pairing function, then `lookup (pair i j) (cantor xss)`according to the old definition corresponds to `lookup (pair j i) (cantor xss)`according to the new definition.For a concrete example see the one included at the end of the module.* In `Data.Fin.Base` the relations `_≤_` `_≥_` `_<_` `_>_` have beengeneralised so they can now relate `Fin` terms with different indices.Should be mostly backwards compatible, but very occasionally when provingproperties about the orderings themselves the second index must be providedexplicitly.* In `Data.Fin.Properties` the proof `inj⇒≟` that an injection from a type`A` into `Fin n` induces a decision procedure for `_≡_` on `A` has beengeneralised to other equivalences over `A` (i.e. to arbitrary setoids), andrenamed from `eq?` to the more descriptive and `inj⇒decSetoid`.* In `Data.Fin.Properties` the proof `pigeonhole` has been strengthenedso that the a proof that `i < j` rather than a mere `i ≢ j` is returned.* In `Data.Fin.Substitution.TermSubst` the fixity of `_/Var_` has been changedfrom `infix 8` to `infixl 8`.* In `Data.Integer.DivMod` the previous implementations of`_divℕ_`, `_div_`, `_modℕ_`, `_mod_` internally converted to the unary`Fin` datatype resulting in poor performance. The implementation has beenupdated to use the corresponding operations from `Data.Nat.DivMod` which areefficiently implemented using the Haskell backend.* In `Data.Integer.Properties` the first two arguments of `m≡n⇒m-n≡0`(now renamed `i≡j⇒i-j≡0`) have been made implicit.* In `Data.(List|Vec).Relation.Binary.Lex.Strict` the argument `xs` in`xs≮[]` in introduced in PRs #1648 and #1672 has now been made implicit.* In `Data.List.NonEmpty` the functions `split`, `flatten` and `flatten-split`have been removed from. In their place `groupSeqs` and `ungroupSeqs`have been added to `Data.List.NonEmpty.Base` which morally perform the sameoperations but without computing the accompanying proofs. The proofs can befound in `Data.List.NonEmpty.Properties` under the names `groupSeqs-groups`and `ungroupSeqs` and `groupSeqs`.* In `Data.List.Relation.Unary.Grouped.Properties` the proofs `map⁺` and `map⁻`have had their preconditions weakened so the equivalences no longer require congruenceproofs.* In `Data.Nat.Divisibility` the proof `m/n/o≡m/[n*o]` has been removed. In it'splace a new more general proof `m/n/o≡m/[n*o]` has been added to `Data.Nat.DivMod`that doesn't require the `n * o ∣ m` pre-condition.* In `Data.Product.Relation.Binary.Lex.Strict` the proof of wellfoundednessof the lexicographic ordering on products, no longerrequires the assumption of symmetry for the first equality relation `_≈₁_`.* In `Data.Rational.Base` the constructors `+0` and `+[1+_]` from `Data.Integer.Base`are no longer re-exported by `Data.Rational.Base`. You will have to open `Data.Integer(.Base)`directly to use them.* In `Data.Rational(.Unnormalised).Properties` the types of the proofs`pos⇒1/pos`/`1/pos⇒pos` and `neg⇒1/neg`/`1/neg⇒neg` have been switched,as the previous naming scheme didn't correctly generalise to e.g. `pos+pos⇒pos`.For example the types of `pos⇒1/pos`/`1/pos⇒pos` were:```agdapos⇒1/pos : ∀ p .{{_ : NonZero p}} .{{Positive (1/ p)}} → Positive p1/pos⇒pos : ∀ p .{{_ : Positive p}} → Positive (1/ p)```but are now:```agdapos⇒1/pos : ∀ p .{{_ : Positive p}} → Positive (1/ p)1/pos⇒pos : ∀ p .{{_ : NonZero p}} .{{Positive (1/ p)}} → Positive p```* In `Data.Sum.Base` the definitions `fromDec` and `toDec` have been moved to `Data.Sum`.* In `Data.Vec.Base` the definition of `_>>=_` under `Data.Vec.Base` has beenmoved to the submodule `CartesianBind` in order to avoid clashing with thenew, alternative definition of `_>>=_`, located in the second new submodule`DiagonalBind`.* In `Data.Vec.Base` the definitions `init` and `last` have been changed from the `initLast`view-derived implementation to direct recursive definitions.* In `Data.Vec.Properties` the type of the proof `zipWith-comm` has been generalised from:```agdazipWith-comm : ∀ {f : A → A → B} (comm : ∀ x y → f x y ≡ f y x) (xs ys : Vec A n) →zipWith f xs ys ≡ zipWith f ys xs```to```agdazipWith-comm : ∀ {f : A → B → C} {g : B → A → C} (comm : ∀ x y → f x y ≡ g y x) (xs : Vec A n) ys →zipWith f xs ys ≡ zipWith g ys xs```* In `Data.Vec.Relation.Unary.All` the functions `lookup` and `tabulate` havebeen moved to `Data.Vec.Relation.Unary.All.Properties` and renamed`lookup⁺` and `lookup⁻` respectively.* In `Data.Vec.Base` and `Data.Vec.Functional` the functions `iterate` and `replicate`now take the length of vector, `n`, as an explicit rather than an implicit argument, i.e.the new types are:```agdaiterate : (A → A) → A → ∀ n → Vec A nreplicate : ∀ n → A → Vec A n```* In `Relation.Binary.Construct.Closure.Symmetric` the operation`SymClosure` on relations in has been reimplementedas a data type `SymClosure _⟶_ a b` that is parameterized by theinput relation `_⟶_` (as well as the elements `a` and `b` of thedomain) so that `_⟶_` can be inferred, which it could not from theprevious implementation using the sum type `a ⟶ b ⊎ b ⟶ a`.* In `Relation.Nullary.Decidable.Core` the name `excluded-middle` has beenrenamed to `¬¬-excluded-middle`.Other major improvements------------------------### Improvements to ring solver tactic* The ring solver tactic has been greatly improved. In particular:1. When the solver is used for concrete ring types, e.g. ℤ, the equality can now useall the ring operations defined natively for that type, rather than havingto use the operations defined in `AlmostCommutativeRing`. For examplepreviously you could not use `Data.Integer.Base._*_` but instead had touse `AlmostCommutativeRing._*_`.2. The solver now supports use of the subtraction operator `_-_` wheneverit is defined immediately in terms of `_+_` and `-_`. This is the case for`Data.Integer` and `Data.Rational`.### Moved `_%_` and `_/_` operators to `Data.Nat.Base`* Previously the division and modulus operators were defined in `Data.Nat.DivMod`which in turn meant that using them required importing `Data.Nat.Properties`which is a very heavy dependency.* To fix this, these operators have been moved to `Data.Nat.Base`. The propertiesfor them still live in `Data.Nat.DivMod` (which also publicly re-exports themto provide backwards compatibility).* Beneficiaries of this change include `Data.Rational.Unnormalised.Base` whosedependencies are now significantly smaller.### Moved raw bundles from `Data.X.Properties` to `Data.X.Base`* Raw bundles by design don't contain any proofs so should in theory be able to livein `Data.X.Base` rather than `Data.X.Bundles`.* To achieve this while keeping the dependency footprint small, the definitions ofraw bundles (`RawMagma`, `RawMonoid` etc.) have been moved from `Algebra(.Lattice)Bundles` toa new module `Algebra(.Lattice).Bundles.Raw` which can be imported at much lower costfrom `Data.X.Base`.* We have then moved raw bundles defined in `Data.X.Properties` to `Data.X.Base` for`X` = `Nat`/`Nat.Binary`/`Integer`/`Rational`/`Rational.Unnormalised`.### Upgrades to `README` sub-library* The `README` sub-library has been moved to `doc/README` and a new `doc/standard-library-doc.agda-lib` has been added.* The first consequence is that `README` files now can be type-checked in Emacsusing an out-of-the-box standard Agda installation without altering the main`standard-library.agda-lib` file.* The second is that the `README` files are now their own first-class libraryand can be imported like an other library.Deprecated modules------------------### Moving `Data.Erased` to `Data.Irrelevant`* This fixes the fact we had picked the wrong name originally. The erased modalitycorresponds to `@0` whereas the irrelevance one corresponds to `.`.### Deprecation of `Data.Fin.Substitution.Example`* The module `Data.Fin.Substitution.Example` has been deprecated, and moved to `README.Data.Fin.Substitution.UntypedLambda`### Deprecation of `Data.Nat.Properties.Core`* The module `Data.Nat.Properties.Core` has been deprecated, and its one lemma moved to `Data.Nat.Base`, renamed as `s≤s⁻¹`### Deprecation of `Data.Product.Function.Dependent.Setoid.WithK`* This module has been deprecated, as none of its contents actually depended on axiom K.The contents has been moved to `Data.Product.Function.Dependent.Setoid`.### Moving `Function.Related`* The module `Function.Related` has been deprecated in favour of `Function.Related.Propositional`whose code uses the new function hierarchy. This also opens up the possibility of a moregeneral `Function.Related.Setoid` at a later date. Several of the names have been changedin this process to bring them into line with the camelcase naming convention usedin the rest of the library:```agdareverse-implication ↦ reverseImplicationreverse-injection ↦ reverseInjectionleft-inverse ↦ leftInverseSymmetric-kind ↦ SymmetricKindForward-kind ↦ ForwardKindBackward-kind ↦ BackwardKindEquivalence-kind ↦ EquivalenceKind```### Moving `Relation.Binary.Construct.(Converse/Flip)`* The following files have been moved:```agdaRelation.Binary.Construct.Converse ↦ Relation.Binary.Construct.Flip.EqAndOrdRelation.Binary.Construct.Flip ↦ Relation.Binary.Construct.Flip.Ord```### Moving `Relation.Binary.Properties.XLattice`* The following files have been moved:```agdaRelation.Binary.Properties.BoundedJoinSemilattice.agda ↦ Relation.Binary.Lattice.Properties.BoundedJoinSemilattice.agdaRelation.Binary.Properties.BoundedLattice.agda ↦ Relation.Binary.Lattice.Properties.BoundedLattice.agdaRelation.Binary.Properties.BoundedMeetSemilattice.agda ↦ Relation.Binary.Lattice.Properties.BoundedMeetSemilattice.agdaRelation.Binary.Properties.DistributiveLattice.agda ↦ Relation.Binary.Lattice.Properties.DistributiveLattice.agdaRelation.Binary.Properties.HeytingAlgebra.agda ↦ Relation.Binary.Lattice.Properties.HeytingAlgebra.agdaRelation.Binary.Properties.JoinSemilattice.agda ↦ Relation.Binary.Lattice.Properties.JoinSemilattice.agdaRelation.Binary.Properties.Lattice.agda ↦ Relation.Binary.Lattice.Properties.Lattice.agdaRelation.Binary.Properties.MeetSemilattice.agda ↦ Relation.Binary.Lattice.Properties.MeetSemilattice.agda```Deprecated names----------------* In `Algebra.Consequences.Propositional`:```agdacomm+assoc⇒middleFour ↦ comm∧assoc⇒middleFouridentity+middleFour⇒assoc ↦ identity∧middleFour⇒associdentity+middleFour⇒comm ↦ identity∧middleFour⇒commcomm+distrˡ⇒distrʳ ↦ comm∧distrˡ⇒distrʳcomm+distrʳ⇒distrˡ ↦ comm∧distrʳ⇒distrˡassoc+distribʳ+idʳ+invʳ⇒zeˡ ↦ assoc∧distribʳ∧idʳ∧invʳ⇒zeˡassoc+distribˡ+idʳ+invʳ⇒zeʳ ↦ assoc∧distribˡ∧idʳ∧invʳ⇒zeʳassoc+id+invʳ⇒invˡ-unique ↦ assoc∧id∧invʳ⇒invˡ-uniqueassoc+id+invˡ⇒invʳ-unique ↦ assoc∧id∧invˡ⇒invʳ-uniquesubst+comm⇒sym ↦ subst∧comm⇒sym```* In `Algebra.Consequences.Setoid`:```agdacomm+assoc⇒middleFour ↦ comm∧assoc⇒middleFouridentity+middleFour⇒assoc ↦ identity∧middleFour⇒associdentity+middleFour⇒comm ↦ identity∧middleFour⇒commcomm+cancelˡ⇒cancelʳ ↦ comm∧cancelˡ⇒cancelʳcomm+cancelʳ⇒cancelˡ ↦ comm∧cancelʳ⇒cancelˡcomm+almostCancelˡ⇒almostCancelʳ ↦ comm∧almostCancelˡ⇒almostCancelʳcomm+almostCancelʳ⇒almostCancelˡ ↦ comm∧almostCancelʳ⇒almostCancelˡcomm+idˡ⇒idʳ ↦ comm∧idˡ⇒idʳcomm+idʳ⇒idˡ ↦ comm∧idʳ⇒idˡcomm+zeˡ⇒zeʳ ↦ comm∧zeˡ⇒zeʳcomm+zeʳ⇒zeˡ ↦ comm∧zeʳ⇒zeˡcomm+invˡ⇒invʳ ↦ comm∧invˡ⇒invʳcomm+invʳ⇒invˡ ↦ comm∧invʳ⇒invˡcomm+distrˡ⇒distrʳ ↦ comm∧distrˡ⇒distrʳcomm+distrʳ⇒distrˡ ↦ comm∧distrʳ⇒distrˡassoc+distribʳ+idʳ+invʳ⇒zeˡ ↦ assoc∧distribʳ∧idʳ∧invʳ⇒zeˡassoc+distribˡ+idʳ+invʳ⇒zeʳ ↦ assoc∧distribˡ∧idʳ∧invʳ⇒zeʳassoc+id+invʳ⇒invˡ-unique ↦ assoc∧id∧invʳ⇒invˡ-uniqueassoc+id+invˡ⇒invʳ-unique ↦ assoc∧id∧invˡ⇒invʳ-uniquesubst+comm⇒sym ↦ subst∧comm⇒sym```* In `Algebra.Construct.Zero`:```agdarawMagma ↦ Algebra.Construct.Terminal.rawMagmamagma ↦ Algebra.Construct.Terminal.magmasemigroup ↦ Algebra.Construct.Terminal.semigroupband ↦ Algebra.Construct.Terminal.band```* In `Codata.Guarded.Stream.Properties`:```agdamap-identity ↦ map-idmap-fusion ↦ map-∘drop-fusion ↦ drop-drop```* In `Codata.Sized.Colist.Properties`:```agdamap-identity ↦ map-idmap-map-fusion ↦ map-∘drop-drop-fusion ↦ drop-drop```* In `Codata.Sized.Covec.Properties`:```agdamap-identity ↦ map-idmap-map-fusion ↦ map-∘```* In `Codata.Sized.Delay.Properties`:```agdamap-identity ↦ map-idmap-map-fusion ↦ map-∘map-unfold-fusion ↦ map-unfold```* In `Codata.Sized.M.Properties`:```agdamap-compose ↦ map-∘```* In `Codata.Sized.Stream.Properties`:```agdamap-identity ↦ map-idmap-map-fusion ↦ map-∘```* In `Data.Container.Related`:```agda_∼[_]_ ↦ _≲[_]_```* In `Data.Bool.Properties` (Issue #2046):```agdapush-function-into-if ↦ if-float```* In `Data.Fin.Base`: two new, hopefully more memorable, names `↑ˡ` `↑ʳ`for the 'left', resp. 'right' injection of a Fin m into a 'larger' type,`Fin (m + n)`, resp. `Fin (n + m)`, with argument order to reflect theposition of the `Fin m` argument.```inject+ ↦ flip _↑ˡ_raise ↦ _↑ʳ_```* In `Data.Fin.Properties`:```toℕ-raise ↦ toℕ-↑ʳtoℕ-inject+ ↦ toℕ-↑ˡsplitAt-inject+ ↦ splitAt-↑ˡ m i nsplitAt-raise ↦ splitAt-↑ʳFin0↔⊥ ↦ 0↔⊥eq? ↦ inj⇒≟```* In `Data.Fin.Permutation.Components`:```reverse ↦ Data.Fin.Base.oppositereverse-prop ↦ Data.Fin.Properties.opposite-propreverse-involutive ↦ Data.Fin.Properties.opposite-involutivereverse-suc ↦ Data.Fin.Properties.opposite-suc```* In `Data.Integer.DivMod` the operator names have been renamed tobe consistent with those in `Data.Nat.DivMod`:```_divℕ_ ↦ _/ℕ__div_ ↦ _/__modℕ_ ↦ _%ℕ__mod_ ↦ _%_```* In `Data.Integer.Properties` references to variables in names havebeen made consistent so that `m`, `n` always refer to naturals and`i` and `j` always refer to integers:```≤-steps ↦ i≤j⇒i≤k+j≤-step ↦ i≤j⇒i≤1+j≤-steps-neg ↦ i≤j⇒i-k≤j≤-step-neg ↦ i≤j⇒pred[i]≤jn≮n ↦ i≮i∣n∣≡0⇒n≡0 ↦ ∣i∣≡0⇒i≡0∣-n∣≡∣n∣ ↦ ∣-i∣≡∣i∣0≤n⇒+∣n∣≡n ↦ 0≤i⇒+∣i∣≡i+∣n∣≡n⇒0≤n ↦ +∣i∣≡i⇒0≤i+∣n∣≡n⊎+∣n∣≡-n ↦ +∣i∣≡i⊎+∣i∣≡-i∣m+n∣≤∣m∣+∣n∣ ↦ ∣i+j∣≤∣i∣+∣j∣∣m-n∣≤∣m∣+∣n∣ ↦ ∣i-j∣≤∣i∣+∣j∣signₙ◃∣n∣≡n ↦ signᵢ◃∣i∣≡i◃-≡ ↦ ◃-cong∣m-n∣≡∣n-m∣ ↦ ∣i-j∣≡∣j-i∣m≡n⇒m-n≡0 ↦ i≡j⇒i-j≡0m-n≡0⇒m≡n ↦ i-j≡0⇒i≡jm≤n⇒m-n≤0 ↦ i≤j⇒i-j≤0m-n≤0⇒m≤n ↦ i-j≤0⇒i≤jm≤n⇒0≤n-m ↦ i≤j⇒0≤j-i0≤n-m⇒m≤n ↦ 0≤i-j⇒j≤in≤1+n ↦ i≤suc[i]n≢1+n ↦ i≢suc[i]m≤pred[n]⇒m<n ↦ i≤pred[j]⇒i<jm<n⇒m≤pred[n] ↦ i<j⇒i≤pred[j]-1*n≡-n ↦ -1*i≡-im*n≡0⇒m≡0∨n≡0 ↦ i*j≡0⇒i≡0∨j≡0∣m*n∣≡∣m∣*∣n∣ ↦ ∣i*j∣≡∣i∣*∣j∣m≤m+n ↦ i≤i+jn≤m+n ↦ i≤j+im-n≤m ↦ i≤i-j+-pos-monoʳ-≤ ↦ +-monoʳ-≤+-neg-monoʳ-≤ ↦ +-monoʳ-≤*-monoʳ-≤-pos ↦ *-monoʳ-≤-nonNeg*-monoˡ-≤-pos ↦ *-monoˡ-≤-nonNeg*-monoʳ-≤-neg ↦ *-monoʳ-≤-nonPos*-monoˡ-≤-neg ↦ *-monoˡ-≤-nonPos*-cancelˡ-<-neg ↦ *-cancelˡ-<-nonPos*-cancelʳ-<-neg ↦ *-cancelʳ-<-nonPos^-semigroup-morphism ↦ ^-isMagmaHomomorphism^-monoid-morphism ↦ ^-isMonoidHomomorphismpos-distrib-* ↦ pos-*pos-+-commute ↦ pos-+abs-*-commute ↦ abs-*+-isAbelianGroup ↦ +-0-isAbelianGroup```* In `Data.List.Base`:```agda_─_ ↦ removeAt```* In `Data.List.Properties`:```agdamap-id₂ ↦ map-id-localmap-cong₂ ↦ map-cong-localmap-compose ↦ map-∘map-++-commute ↦ map-++sum-++-commute ↦ sum-++reverse-map-commute ↦ reverse-mapreverse-++-commute ↦ reverse-++zipWith-identityˡ ↦ zipWith-zeroˡzipWith-identityʳ ↦ zipWith-zeroʳʳ++-++ ↦ ++-ʳ++take++drop ↦ take++drop≡idlength-─ ↦ length-removeAtmap-─ ↦ map-removeAt```* In `Data.List.NonEmpty.Properties`:```agdamap-compose ↦ map-∘map-++⁺-commute ↦ map-++⁺```* In `Data.List.Relation.Unary.All.Properties`:```agdagmap ↦ gmap⁺updateAt-id-relative ↦ updateAt-id-localupdateAt-compose-relative ↦ updateAt-updateAt-localupdateAt-compose ↦ updateAt-updateAtupdateAt-cong-relative ↦ updateAt-cong-local```* In `Data.List.Relation.Unary.Any.Properties`:```agdamap-with-∈⁺ ↦ mapWith∈⁺map-with-∈⁻ ↦ mapWith∈⁻map-with-∈↔ ↦ mapWith∈↔```* In `Data.List.Relation.Binary.Subset.Propositional.Properties`:```agdamap-with-∈⁺ ↦ mapWith∈⁺```* In `Data.List.Zipper.Properties`:```agdatoList-reverse-commute ↦ toList-reversetoList-ˡ++-commute ↦ toList-ˡ++toList-++ʳ-commute ↦ toList-++ʳtoList-map-commute ↦ toList-maptoList-foldr-commute ↦ toList-foldr```* In `Data.Maybe.Properties`:```agdamap-id₂ ↦ map-id-localmap-cong₂ ↦ map-cong-localmap-compose ↦ map-∘map-<∣>-commute ↦ map-<∣>```* In `Data.Nat.Properties`:```agdasuc[pred[n]]≡n ↦ suc-pred≤-step ↦ m≤n⇒m≤1+n≤-stepsˡ ↦ m≤n⇒m≤o+n≤-stepsʳ ↦ m≤n⇒m≤n+o<-step ↦ m<n⇒m<1+npred-mono ↦ pred-mono-≤<-transʳ ↦ ≤-<-trans<-transˡ ↦ <-≤-trans```* In `Data.Rational.Unnormalised.Base`:```agda_≠_ ↦ _≄_+-rawMonoid ↦ +-0-rawMonoid*-rawMonoid ↦ *-1-rawMonoid```* In `Data.Rational.Unnormalised.Properties`:```agda↥[p/q]≡p ↦ ↥[n/d]≡n↧[p/q]≡q ↦ ↧[n/d]≡d*-monoˡ-≤-pos ↦ *-monoˡ-≤-nonNeg*-monoʳ-≤-pos ↦ *-monoʳ-≤-nonNeg≤-steps ↦ p≤q⇒p≤r+q*-monoˡ-≤-neg ↦ *-monoˡ-≤-nonPos*-monoʳ-≤-neg ↦ *-monoʳ-≤-nonPos*-cancelˡ-<-pos ↦ *-cancelˡ-<-nonNeg*-cancelʳ-<-pos ↦ *-cancelʳ-<-nonNegpositive⇒nonNegative ↦ pos⇒nonNegnegative⇒nonPositive ↦ neg⇒nonPosnegative<positive ↦ neg<pos```* In `Data.Rational.Base`:```agda+-rawMonoid ↦ +-0-rawMonoid*-rawMonoid ↦ *-1-rawMonoid```* In `Data.Rational.Properties`:```agda*-monoʳ-≤-neg ↦ *-monoʳ-≤-nonPos*-monoˡ-≤-neg ↦ *-monoˡ-≤-nonPos*-monoʳ-≤-pos ↦ *-monoʳ-≤-nonNeg*-monoˡ-≤-pos ↦ *-monoˡ-≤-nonNeg*-cancelˡ-<-pos ↦ *-cancelˡ-<-nonNeg*-cancelʳ-<-pos ↦ *-cancelʳ-<-nonNeg*-cancelˡ-<-neg ↦ *-cancelˡ-<-nonPos*-cancelʳ-<-neg ↦ *-cancelʳ-<-nonPosnegative<positive ↦ neg<pos```* In `Data.Rational.Unnormalised.Base`:```agda+-rawMonoid ↦ +-0-rawMonoid*-rawMonoid ↦ *-1-rawMonoid```* In `Data.Rational.Unnormalised.Properties`:```agda≤-steps ↦ p≤q⇒p≤r+q```* In `Data.Sum.Properties`:```agda[,]-∘-distr ↦ [,]-∘[,]-map-commute ↦ [,]-mapmap-commute ↦ map-mapmap₁₂-commute ↦ map₁₂-map₂₁```* In `Data.Tree.AVL`:```agda_∈?_ ↦ member```* In `Data.Tree.AVL.IndexedMap`:```agda_∈?_ ↦ member```* In `Data.Tree.AVL.Map`:```agda_∈?_ ↦ member```* In `Data.Tree.AVL.Sets`:```agda_∈?_ ↦ member```* In `Data.Tree.Binary.Zipper.Properties`:```agdatoTree-#nodes-commute ↦ toTree-#nodestoTree-#leaves-commute ↦ toTree-#leavestoTree-map-commute ↦ toTree-maptoTree-foldr-commute ↦ toTree-foldrtoTree-⟪⟫ˡ-commute ↦ toTree--⟪⟫ˡtoTree-⟪⟫ʳ-commute ↦ toTree-⟪⟫ʳ```* In `Data.Tree.Rose.Properties`:```agdamap-compose ↦ map-∘```* In `Data.Vec.Base`:```agdaremove ↦ removeAtinsert ↦ insertAt```* In `Data.Vec.Properties`:```agdatake-distr-zipWith ↦ take-zipWithtake-distr-map ↦ take-mapdrop-distr-zipWith ↦ drop-zipWithdrop-distr-map ↦ drop-mapupdateAt-id-relative ↦ updateAt-id-localupdateAt-compose-relative ↦ updateAt-updateAt-localupdateAt-compose ↦ updateAt-updateAtupdateAt-cong-relative ↦ updateAt-cong-local[]%=-compose ↦ []%=-∘[]≔-++-inject+ ↦ []≔-++-↑ˡ[]≔-++-raise ↦ []≔-++-↑ʳidIsFold ↦ id-is-foldrsum-++-commute ↦ sum-++take-drop-id ↦ take++drop≡idmap-insert ↦ map-insertAtinsert-lookup ↦ insertAt-lookupinsert-punchIn ↦ insertAt-punchInremove-PunchOut ↦ removeAt-punchOutremove-insert ↦ removeAt-insertAtinsert-remove ↦ insertAt-removeAtlookup-inject≤-take ↦ lookup-take-inject≤```* In `Data.Vec.Functional.Properties`:```agdaupdateAt-id-relative ↦ updateAt-id-localupdateAt-compose-relative ↦ updateAt-updateAt-localupdateAt-compose ↦ updateAt-updateAtupdateAt-cong-relative ↦ updateAt-cong-localmap-updateAt ↦ map-updateAt-localinsert-lookup ↦ insertAt-lookupinsert-punchIn ↦ insertAt-punchInremove-punchOut ↦ removeAt-punchOutremove-insert ↦ removeAt-insertAtinsert-remove ↦ insertAt-removeAt```NB. This last one is complicated by the *addition* of a 'global' property `map-updateAt`* In `Data.Vec.Recursive.Properties`:```agdaappend-cons-commute ↦ append-cons```* In `Data.Vec.Relation.Binary.Equality.Setoid`:```agdamap-++-commute ↦ map-++```* In `Function.Base`:```agdacase_return_of_ ↦ case_returning_of_```* In `Function.Construct.Composition`:```agda_∘-⟶_ ↦ _⟶-∘__∘-↣_ ↦ _↣-∘__∘-↠_ ↦ _↠-∘__∘-⤖_ ↦ _⤖-∘__∘-⇔_ ↦ _⇔-∘__∘-↩_ ↦ _↩-∘__∘-↪_ ↦ _↪-∘__∘-↔_ ↦ _↔-∘_```* In `Function.Construct.Identity`:```agdaid-⟶ ↦ ⟶-idid-↣ ↦ ↣-idid-↠ ↦ ↠-idid-⤖ ↦ ⤖-idid-⇔ ↦ ⇔-idid-↩ ↦ ↩-idid-↪ ↦ ↪-idid-↔ ↦ ↔-id```* In `Function.Construct.Symmetry`:```agdasym-⤖ ↦ ⤖-symsym-⇔ ↦ ⇔-symsym-↩ ↦ ↩-symsym-↪ ↦ ↪-symsym-↔ ↦ ↔-sym```* In `Function.Related.Propositional.Reasoning`:```agda_↔⟨⟩_ ↦ _≡⟨⟩_```* In `Foreign.Haskell.Either` and `Foreign.Haskell.Pair`:```agdatoForeign ↦ Foreign.Haskell.Coerce.coercefromForeign ↦ Foreign.Haskell.Coerce.coerce```* In `Relation.Binary.Properties.Preorder`:```agdainvIsPreorder ↦ converse-isPreorderinvPreorder ↦ converse-preorder```* In `Relation.Binary.PropositionalEquality`:```agdaisPropositional ↦ Relation.Nullary.Irrelevant```* In `Relation.Unary.Consequences`:```agdadec⟶recomputable ↦ dec⇒recomputable```## Missing fixity declarations added* An effort has been made to add sensible fixities for many declarations:```infix 4 _≟H_ _≟N_ (Algebra.Solver.Ring)infixr 5 _∷_ (Codata.Guarded.Stream)infix 4 _[_] (Codata.Guarded.Stream)infixr 5 _∷_ (Codata.Guarded.Stream.Relation.Binary.Pointwise)infix 4 _≈∞_ (Codata.Guarded.Stream.Relation.Binary.Pointwise)infixr 5 _∷_ (Codata.Guarded.Stream.Relation.Unary.All)infixr 5 _∷_ (Codata.Musical.Colist)infix 4 _≈_ (Codata.Musical.Conat)infixr 5 _∷_ (Codata.Musical.Colist.Bisimilarity)infixr 5 _∷_ (Codata.Musical.Colist.Relation.Unary.All)infixr 5 _∷_ (Codata.Sized.Colist)infixr 5 _∷_ (Codata.Sized.Covec)infixr 5 _∷_ (Codata.Sized.Cowriter)infixl 1 _>>=_ (Codata.Sized.Cowriter)infixr 5 _∷_ (Codata.Sized.Stream)infixr 5 _∷_ (Codata.Sized.Colist.Bisimilarity)infix 4 _ℕ≤?_ (Codata.Sized.Conat.Properties)infixr 5 _∷_ (Codata.Sized.Covec.Bisimilarity)infixr 5 _∷_ (Codata.Sized.Cowriter.Bisimilarity)infixr 5 _∷_ (Codata.Sized.Stream.Bisimilarity)infix 4 _ℕ<_ _ℕ≤infinity _ℕ≤_ (Codata.Sized.Conat)infix 6 _ℕ+_ _+ℕ_ (Codata.Sized.Conat)infixr 8 _⇒_ _⊸_ (Data.Container.Core)infixr -1 _<$>_ _<*>_ (Data.Container.FreeMonad)infixl 1 _>>=_ (Data.Container.FreeMonad)infix 5 _▷_ (Data.Container.Indexed)infixr 4 _,_ (Data.Container.Relation.Binary.Pointwise)infix 4 _≈_ (Data.Float.Base)infixl 4 _+ _* (Data.List.Kleene.Base)infixr 4 _++++_ _+++*_ _*+++_ _*++*_ (Data.List.Kleene.Base)infix 4 _[_]* _[_]+ (Data.List.Kleene.Base)infix 4 _≢∈_ (Data.List.Membership.Propositional)infixr 5 _`∷_ (Data.List.Reflection)infix 4 _≡?_ (Data.List.Relation.Binary.Equality.DecPropositional)infixr 5 _++ᵖ_ (Data.List.Relation.Binary.Prefix.Heterogeneous)infixr 5 _++ˢ_ (Data.List.Relation.Binary.Suffix.Heterogeneous)infixr 5 _++_ _++[] (Data.List.Relation.Ternary.Appending.Propositional)infixr 5 _∷=_ (Data.List.Relation.Unary.Any)infixr 5 _++_ (Data.List.Ternary.Appending)infixl 7 _⊓′_ (Data.Nat.Base)infixl 6 _⊔′_ (Data.Nat.Base)infixr 8 _^_ (Data.Nat.Base)infix 4 _!≢0 _!*_!≢0 (Data.Nat.Properties)infixl 6.5 _P′_ _P_ _C′_ _C_ (Data.Nat.Combinatorics.Base)infix 8 _⁻¹ (Data.Parity.Base)infixr 2 _×-⇔_ _×-↣_ _×-↞_ _×-↠_ _×-↔_ _×-cong_ (Data.Product.Function.NonDependent.Propositional)infixr 2 _×-⟶_ (Data.Product.Function.NonDependent.Setoid)infixr 2 _×-equivalence_ _×-injection_ _×-left-inverse_ (Data.Product.Function.NonDependent.Setoid)infixr 2 _×-surjection_ _×-inverse_ (Data.Product.Function.NonDependent.Setoid)infix 4 _≃?_ (Data.Rational.Unnormalised.Properties)infixr 4 _,_ (Data.Refinement)infixr 1 _⊎-⇔_ _⊎-↣_ _⊎-↞_ _⊎-↠_ _⊎-↔_ _⊎-cong_ (Data.Sum.Function.Propositional)infixr 1 _⊎-⟶_ (Data.Sum.Function.Setoid)infixr 1 _⊎-equivalence_ _⊎-injection_ _⊎-left-inverse_ (Data.Sum.Function.Setoid)infixr 1 _⊎-surjection_ _⊎-inverse_ (Data.Sum.Function.Setoid)infixr 4 _,_ (Data.Tree.AVL.Value)infix 4 _≈ₖᵥ_ (Data.Tree.AVL.Map.Membership.Propositional)infixr 5 _`∷_ (Data.Vec.Reflection)infixr 5 _∷=_ (Data.Vec.Membership.Setoid)infix -1 _$ⁿ_ (Data.Vec.N-ary)infix 4 _≋_ (Data.Vec.Functional.Relation.Binary.Equality.Setoid)infixl 1 _>>=-cong_ _≡->>=-cong_ (Effect.Monad.Partiality)infixl 1 _?>=′_ (Effect.Monad.Predicate)infixl 1 _>>=-cong_ _>>=-congP_ (Effect.Monad.Partiality.All)infixr 5 _∷_ (Foreign.Haskell.List.NonEmpty)infixr 4 _,_ (Foreign.Haskell.Pair)infixr 8 _^_ (Function.Endomorphism.Propositional)infixr 8 _^_ (Function.Endomorphism.Setoid)infix 4 _≃_ (Function.HalfAdjointEquivalence)infix 4 _≈_ _≈ᵢ_ _≤_ (Function.Metric.Bundles)infixl 6 _∙_ (Function.Metric.Bundles)infix 4 _≈_ (Function.Metric.Nat.Bundles)infix 4 _≈_ (Function.Metric.Rational.Bundles)infix 3 _←_ _↢_ (Function.Related)infix 4 _<_ (Induction.WellFounded)infixl 6 _ℕ+_ (Level.Literals)infixr 4 _,_ (Reflection.AnnotatedAST)infix 4 _≟_ (Reflection.AST.Definition)infix 4 _≡ᵇ_ (Reflection.AST.Literal)infix 4 _≈?_ _≟_ _≈_ (Reflection.AST.Meta)infix 4 _≈?_ _≟_ _≈_ (Reflection.AST.Name)infix 4 _≟-Telescope_ (Reflection.AST.Term)infix 4 _≟_ (Reflection.AST.Argument.Information)infix 4 _≟_ (Reflection.AST.Argument.Modality)infix 4 _≟_ (Reflection.AST.Argument.Quantity)infix 4 _≟_ (Reflection.AST.Argument.Relevance)infix 4 _≟_ (Reflection.AST.Argument.Visibility)infixr 4 _,_ (Reflection.AST.Traversal)infix 4 _∈FV_ (Reflection.AST.DeBruijn)infixr 9 _;_ (Relation.Binary.Construct.Composition)infixl 6 _+²_ (Relation.Binary.HeterogeneousEquality.Quotients.Examples)infixr -1 _atₛ_ (Relation.Binary.Indexed.Heterogeneous.Construct.At)infixr -1 _atₛ_ (Relation.Binary.Indexed.Homogeneous.Construct.At)infix 4 _∈_ _∉_ (Relation.Unary.Indexed)infix 4 _≈_ (Relation.Binary.Bundles)infixl 6 _∩_ (Relation.Binary.Construct.Intersection)infix 4 _<₋_ (Relation.Binary.Construct.Add.Infimum.Strict)infix 4 _≈∙_ (Relation.Binary.Construct.Add.Point.Equality)infix 4 _≤⁺_ _≤⊤⁺ (Relation.Binary.Construct.Add.Supremum.NonStrict)infixr 5 _∷ʳ_ (Relation.Binary.Construct.Closure.Transitive)infixr 6 _∪_ (Relation.Binary.Construct.Union)infixl 6 _+ℤ_ (Relation.Binary.HeterogeneousEquality.Quotients.Examples)infix 4 _≉_ _≈ᵢ_ _≤ᵢ_ (Relation.Binary.Indexed.Homogeneous.Bundles)infixr 9 _⍮_ (Relation.Unary.PredicateTransformer)infix 8 ∼_ (Relation.Unary.PredicateTransformer)infix 2 _×?_ _⊙?_ (Relation.Unary.Properties)infix 10 _~? (Relation.Unary.Properties)infixr 1 _⊎?_ (Relation.Unary.Properties)infixr 7 _∩?_ (Relation.Unary.Properties)infixr 6 _∪?_ (Relation.Unary.Properties)infixr 5 _∷ᴹ_ _∷⁻¹ᴹ_ (Text.Regex.Search)infixl 6 _`⊜_ (Tactic.RingSolver)infix 8 ⊝_ (Tactic.RingSolver.Core.Expression)infix 4 _∈ᴿ?_ _∉ᴿ?_ _∈?ε _∈?[_] _∈?[^_] (Text.Regex.Properties)infix 4 _∈?_ _∉?_ (Text.Regex.Derivative.Brzozowski)infix 4 _∈_ _∉_ _∈?_ _∉?_ (Text.Regex.String.Unsafe)```New modules-----------* Constructive algebraic structures with apartness relations:```Algebra.ApartnessAlgebra.Apartness.BundlesAlgebra.Apartness.StructuresAlgebra.Apartness.Properties.CommutativeHeytingAlgebraRelation.Binary.Properties.ApartnessRelation```* Algebraic structures obtained by flipping their binary operations:```Algebra.Construct.Flip.Op```* Algebraic structures when freely adding an identity element:```Algebra.Construct.Add.Identity```* Definitions for algebraic modules:```Algebra.ModuleAlgebra.Module.CoreAlgebra.Module.Definitions.Bi.SimultaneousAlgebra.Module.Morphism.Construct.CompositionAlgebra.Module.Morphism.Construct.IdentityAlgebra.Module.Morphism.DefinitionsAlgebra.Module.Morphism.ModuleHomomorphismAlgebra.Module.Morphism.StructuresAlgebra.Module.Properties```* Identity morphisms and composition of morphisms between algebraic structures:```Algebra.Morphism.Construct.CompositionAlgebra.Morphism.Construct.Identity```* Properties of various new algebraic structures:```Algebra.Properties.MoufangLoopAlgebra.Properties.QuasigroupAlgebra.Properties.MiddleBolLoopAlgebra.Properties.LoopAlgebra.Properties.KleeneAlgebra```* Properties of rings without a unit```Algebra.Properties.RingWithoutOne````* Proof of the Binomial Theorem for semirings```Algebra.Properties.Semiring.BinomialAlgebra.Properties.CommutativeSemiring.Binomial```* 'Optimised' tail-recursive exponentiation properties:```Algebra.Properties.Semiring.Exp.TailRecursiveOptimised```* An implementation of M-types with `--guardedness` flag:```Codata.Guarded.M```* A definition of infinite streams using coinductive records:```Codata.Guarded.StreamCodata.Guarded.Stream.PropertiesCodata.Guarded.Stream.Relation.Binary.PointwiseCodata.Guarded.Stream.Relation.Unary.AllCodata.Guarded.Stream.Relation.Unary.Any```* A small library for function arguments with default values:```Data.Default```* A small library defining a structurally recursive view of `Fin n`:```Data.Fin.Relation.Unary.Top```* A small library for a non-empty fresh list:```Data.List.Fresh.NonEmpty```* A small library defining a structurally inductive view of lists:```Data.List.Relation.Unary.Sufficient```* Combinations and permutations for ℕ.```Data.Nat.CombinatoricsData.Nat.Combinatorics.BaseData.Nat.Combinatorics.Spec```* A small library defining parity and its algebra:```Data.ParityData.Parity.BaseData.Parity.InstancesData.Parity.Properties```* New base module for `Data.Product` containing only the basic definitions.```Data.Product.Base```* Reflection utilities for some specific types:```Data.List.ReflectionData.Vec.Reflection```* The `All` predicate over non-empty lists:```Data.List.NonEmpty.Relation.Unary.All```* Some n-ary functions manipulating lists```Data.List.Nary.NonDependent```* Added Logarithm base 2 on natural numbers:```Data.Nat.Logarithm.CoreData.Nat.Logarithm```* Show module for unnormalised rationals:```Data.Rational.Unnormalised.Show```* Membership relations for maps and sets```Data.Tree.AVL.Map.Membership.PropositionalData.Tree.AVL.Map.Membership.Propositional.PropertiesData.Tree.AVL.Sets.MembershipData.Tree.AVL.Sets.Membership.Properties```* Port of `Linked` to `Vec`:```Data.Vec.Relation.Unary.LinkedData.Vec.Relation.Unary.Linked.Properties```* Combinators for propositional equational reasoning on vectors with different indices```Data.Vec.Relation.Binary.Equality.Cast```* Relations on indexed sets```Function.Indexed.Bundles```* Properties of various types of functions:```Function.ConsequencesFunction.Consequences.SetoidFunction.Consequences.PropositionalFunction.Properties.BijectionFunction.Properties.RightInverseFunction.Properties.SurjectionFunction.Construct.Constant```* New interface for `NonEmpty` Haskell lists:```Foreign.Haskell.List.NonEmpty```* In order to improve modularity, the contents of `Relation.Binary.Lattice` has beensplit out into the standard:```Relation.Binary.Lattice.DefinitionsRelation.Binary.Lattice.StructuresRelation.Binary.Lattice.Bundles```All contents is re-exported by `Relation.Binary.Lattice` as before.* Added relational reasoning over apartness relations:```Relation.Binary.Reasoning.Base.Apartness````* Algebraic properties of `_∩_` and `_∪_` for predicates```Relation.Unary.Algebra```* Both versions of equality on predicates are equivalences```Relation.Unary.Relation.Binary.Equality```* The subset relations on predicates define an order```Relation.Unary.Relation.Binary.Subset```* Polymorphic versions of some unary relations and their properties```Relation.Unary.PolymorphicRelation.Unary.Polymorphic.Properties```* Alpha equality over reflected terms```Reflection.AST.AlphaEquality```* Various system types and primitives:```System.Clock.PrimitiveSystem.ClockSystem.Console.ANSISystem.Directory.PrimitiveSystem.DirectorySystem.FilePath.Posix.PrimitiveSystem.FilePath.PosixSystem.Process.PrimitiveSystem.Process```* A new `cong!` tactic for automatically deriving arguments to `cong````Tactic.Cong```* A golden testing library with test pools, an options parser, a runner:```Test.Golden```Additions to existing modules-----------------------------* The module `Algebra` now publicly re-exports the contents of`Algebra.Structures.Biased`.* Added new definitions to `Algebra.Bundles`:```agdarecord UnitalMagma c ℓ : Set (suc (c ⊔ ℓ))record InvertibleMagma c ℓ : Set (suc (c ⊔ ℓ))record InvertibleUnitalMagma c ℓ : Set (suc (c ⊔ ℓ))record Quasigroup c ℓ : Set (suc (c ⊔ ℓ))record Loop c ℓ : Set (suc (c ⊔ ℓ))record RingWithoutOne c ℓ : Set (suc (c ⊔ ℓ))record IdempotentSemiring c ℓ : Set (suc (c ⊔ ℓ))record KleeneAlgebra c ℓ : Set (suc (c ⊔ ℓ))record Quasiring c ℓ : Set (suc (c ⊔ ℓ))record Nearring c ℓ : Set (suc (c ⊔ ℓ))record IdempotentMagma c ℓ : Set (suc (c ⊔ ℓ))record AlternateMagma c ℓ : Set (suc (c ⊔ ℓ))record FlexibleMagma c ℓ : Set (suc (c ⊔ ℓ))record MedialMagma c ℓ : Set (suc (c ⊔ ℓ))record SemimedialMagma c ℓ : Set (suc (c ⊔ ℓ))record LeftBolLoop c ℓ : Set (suc (c ⊔ ℓ))record RightBolLoop c ℓ : Set (suc (c ⊔ ℓ))record MoufangLoop c ℓ : Set (suc (c ⊔ ℓ))record NonAssociativeRing c ℓ : Set (suc (c ⊔ ℓ))record MiddleBolLoop c ℓ : Set (suc (c ⊔ ℓ))```* Added new definitions to `Algebra.Bundles.Raw`:```agdarecord RawLoop c ℓ : Set (suc (c ⊔ ℓ))record RawQuasiGroup c ℓ : Set (suc (c ⊔ ℓ))record RawRingWithoutOne c ℓ : Set (suc (c ⊔ ℓ))```* Added new definitions to `Algebra.Structures`:```agdarecord IsUnitalMagma (_∙_ : Op₂ A) (ε : A) : Set (a ⊔ ℓ)record IsInvertibleMagma (_∙_ : Op₂ A) (ε : A) (_⁻¹ : Op₁ A) : Set (a ⊔ ℓ)record IsInvertibleUnitalMagma (_∙_ : Op₂ A) (ε : A) (⁻¹ : Op₁ A) : Set (a ⊔ ℓ)record IsQuasigroup (∙ \\ // : Op₂ A) : Set (a ⊔ ℓ)record IsLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ)record IsRingWithoutOne (+ * : Op₂ A) (-_ : Op₁ A) (0# : A) : Set (a ⊔ ℓ)record IsIdempotentSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ)record IsKleeneAlgebra (+ * : Op₂ A) (⋆ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ)record IsQuasiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ) whererecord IsNearring (+ * : Op₂ A) (0# 1# : A) (_⁻¹ : Op₁ A) : Set (a ⊔ ℓ) whererecord IsIdempotentMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)record IsAlternativeMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)record IsFlexibleMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)record IsMedialMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)record IsSemimedialMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)record IsLeftBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ)record IsRightBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ)record IsMoufangLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ)record IsNonAssociativeRing (+ * : Op₂ A) (-_ : Op₁ A) (0# 1# : A) : Set (a ⊔ ℓ)record IsMiddleBolLoop (∙ \\ // : Op₂ A) (ε : A) : Set (a ⊔ ℓ)```* Added new proof to `Algebra.Consequences.Base`:```agdareflexive∧selfInverse⇒involutive : Reflexive _≈_ → SelfInverse _≈_ f → Involutive _≈_ f```* Added new proofs to `Algebra.Consequences.Propositional`:```agdacomm∧assoc⇒middleFour : Commutative _∙_ → Associative _∙_ → _∙_ MiddleFourExchange _∙_identity∧middleFour⇒assoc : Identity e _∙_ → _∙_ MiddleFourExchange _∙_ → Associative _∙_identity∧middleFour⇒comm : Identity e _+_ → _∙_ MiddleFourExchange _+_ → Commutative _∙_```* Added new proofs to `Algebra.Consequences.Setoid`:```agdacomm∧assoc⇒middleFour : Congruent₂ _∙_ → Commutative _∙_ → Associative _∙_ → _∙_ MiddleFourExchange _∙_identity∧middleFour⇒assoc : Congruent₂ _∙_ → Identity e _∙_ → _∙_ MiddleFourExchange _∙_ → Associative _∙_identity∧middleFour⇒comm : Congruent₂ _∙_ → Identity e _+_ → _∙_ MiddleFourExchange _+_ → Commutative _∙_involutive⇒surjective : Involutive f → Surjective fselfInverse⇒involutive : SelfInverse f → Involutive fselfInverse⇒congruent : SelfInverse f → Congruent fselfInverse⇒inverseᵇ : SelfInverse f → Inverseᵇ f fselfInverse⇒surjective : SelfInverse f → Surjective fselfInverse⇒injective : SelfInverse f → Injective fselfInverse⇒bijective : SelfInverse f → Bijective fcomm∧idˡ⇒id : Commutative _∙_ → LeftIdentity e _∙_ → Identity e _∙_comm∧idʳ⇒id : Commutative _∙_ → RightIdentity e _∙_ → Identity e _∙_comm∧zeˡ⇒ze : Commutative _∙_ → LeftZero e _∙_ → Zero e _∙_comm∧zeʳ⇒ze : Commutative _∙_ → RightZero e _∙_ → Zero e _∙_comm∧invˡ⇒inv : Commutative _∙_ → LeftInverse e _⁻¹ _∙_ → Inverse e _⁻¹ _∙_comm∧invʳ⇒inv : Commutative _∙_ → RightInverse e _⁻¹ _∙_ → Inverse e _⁻¹ _∙_comm∧distrˡ⇒distr : Commutative _∙_ → _∙_ DistributesOverˡ _◦_ → _∙_ DistributesOver _◦_comm∧distrʳ⇒distr : Commutative _∙_ → _∙_ DistributesOverʳ _◦_ → _∙_ DistributesOver _◦_distrib∧absorbs⇒distribˡ : Associative _∙_ → Commutative _◦_ → _∙_ Absorbs _◦_ → _◦_ Absorbs _∙_ → _◦_ DistributesOver _∙_ → _∙_ DistributesOverˡ _◦_```* Added new functions to `Algebra.Construct.DirectProduct`:```agdarawSemiring : RawSemiring a ℓ₁ → RawSemiring b ℓ₂ → RawSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawRing : RawRing a ℓ₁ → RawRing b ℓ₂ → RawRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semiringWithoutAnnihilatingZero : SemiringWithoutAnnihilatingZero a ℓ₁ →SemiringWithoutAnnihilatingZero b ℓ₂ →SemiringWithoutAnnihilatingZero (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semiring : Semiring a ℓ₁ → Semiring b ℓ₂ → Semiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeSemiring : CommutativeSemiring a ℓ₁ →CommutativeSemiring b ℓ₂ →CommutativeSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)ring : Ring a ℓ₁ → Ring b ℓ₂ → Ring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)commutativeRing : CommutativeRing a ℓ₁ → CommutativeRing b ℓ₂ → CommutativeRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawQuasigroup : RawQuasigroup a ℓ₁ → RawQuasigroup b ℓ₂ → RawQuasigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawLoop : RawLoop a ℓ₁ → RawLoop b ℓ₂ → RawLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)unitalMagma : UnitalMagma a ℓ₁ → UnitalMagma b ℓ₂ → UnitalMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)invertibleMagma : InvertibleMagma a ℓ₁ → InvertibleMagma b ℓ₂ → InvertibleMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)invertibleUnitalMagma : InvertibleUnitalMagma a ℓ₁ →InvertibleUnitalMagma b ℓ₂ →InvertibleUnitalMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)quasigroup : Quasigroup a ℓ₁ → Quasigroup b ℓ₂ → Quasigroup (a ⊔ b) (ℓ₁ ⊔ ℓ₂)loop : Loop a ℓ₁ → Loop b ℓ₂ → Loop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)idempotentSemiring : IdempotentSemiring a ℓ₁ →IdempotentSemiring b ℓ₂ →IdempotentSemiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)idempotentMagma : IdempotentMagma a ℓ₁ → IdempotentMagma b ℓ₂ → IdempotentMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)alternativeMagma : AlternativeMagma a ℓ₁ → AlternativeMagma b ℓ₂ → AlternativeMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)flexibleMagma : FlexibleMagma a ℓ₁ → FlexibleMagma b ℓ₂ → FlexibleMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)medialMagma : MedialMagma a ℓ₁ → MedialMagma b ℓ₂ → MedialMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)semimedialMagma : SemimedialMagma a ℓ₁ → SemimedialMagma b ℓ₂ → SemimedialMagma (a ⊔ b) (ℓ₁ ⊔ ℓ₂)kleeneAlgebra : KleeneAlgebra a ℓ₁ → KleeneAlgebra b ℓ₂ → KleeneAlgebra (a ⊔ b) (ℓ₁ ⊔ ℓ₂)leftBolLoop : LeftBolLoop a ℓ₁ → LeftBolLoop b ℓ₂ → LeftBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rightBolLoop : RightBolLoop a ℓ₁ → RightBolLoop b ℓ₂ → RightBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)middleBolLoop : MiddleBolLoop a ℓ₁ → MiddleBolLoop b ℓ₂ → MiddleBolLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)moufangLoop : MoufangLoop a ℓ₁ → MoufangLoop b ℓ₂ → MoufangLoop (a ⊔ b) (ℓ₁ ⊔ ℓ₂)rawRingWithoutOne : RawRingWithoutOne a ℓ₁ → RawRingWithoutOne b ℓ₂ → RawRingWithoutOne (a ⊔ b) (ℓ₁ ⊔ ℓ₂)ringWithoutOne : RingWithoutOne a ℓ₁ → RingWithoutOne b ℓ₂ → RingWithoutOne (a ⊔ b) (ℓ₁ ⊔ ℓ₂)nonAssociativeRing : NonAssociativeRing a ℓ₁ →NonAssociativeRing b ℓ₂ →NonAssociativeRing (a ⊔ b) (ℓ₁ ⊔ ℓ₂)quasiring : Quasiring a ℓ₁ → Quasiring b ℓ₂ → Quasiring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)nearring : Nearring a ℓ₁ → Nearring b ℓ₂ → Nearring (a ⊔ b) (ℓ₁ ⊔ ℓ₂)```* Added new definition to `Algebra.Definitions`:```agda_*_ MiddleFourExchange _+_ = ∀ w x y z → ((w + x) * (y + z)) ≈ ((w + y) * (x + z))SelfInverse f = ∀ {x y} → f x ≈ y → f y ≈ xLeftDividesˡ _∙_ _\\_ = ∀ x y → (x ∙ (x \\ y)) ≈ yLeftDividesʳ _∙_ _\\_ = ∀ x y → (x \\ (x ∙ y)) ≈ yRightDividesˡ _∙_ _//_ = ∀ x y → ((y // x) ∙ x) ≈ yRightDividesʳ _∙_ _//_ = ∀ x y → ((y ∙ x) // x) ≈ yLeftDivides ∙ \\ = (LeftDividesˡ ∙ \\) × (LeftDividesʳ ∙ \\)RightDivides ∙ // = (RightDividesˡ ∙ //) × (RightDividesʳ ∙ //)LeftInvertible e _∙_ x = ∃[ x⁻¹ ] (x⁻¹ ∙ x) ≈ eRightInvertible e _∙_ x = ∃[ x⁻¹ ] (x ∙ x⁻¹) ≈ eInvertible e _∙_ x = ∃[ x⁻¹ ] ((x⁻¹ ∙ x) ≈ e) × ((x ∙ x⁻¹) ≈ e)StarRightExpansive e _+_ _∙_ _⁻* = ∀ x → (e + (x ∙ (x ⁻*))) ≈ (x ⁻*)StarLeftExpansive e _+_ _∙_ _⁻* = ∀ x → (e + ((x ⁻*) ∙ x)) ≈ (x ⁻*)StarExpansive e _+_ _∙_ _* = (StarLeftExpansive e _+_ _∙_ _*) × (StarRightExpansive e _+_ _∙_ _*)StarLeftDestructive _+_ _∙_ _* = ∀ a b x → (b + (a ∙ x)) ≈ x → ((a *) ∙ b) ≈ xStarRightDestructive _+_ _∙_ _* = ∀ a b x → (b + (x ∙ a)) ≈ x → (b ∙ (a *)) ≈ xStarDestructive _+_ _∙_ _* = (StarLeftDestructive _+_ _∙_ _*) × (StarRightDestructive _+_ _∙_ _*)LeftAlternative _∙_ = ∀ x y → ((x ∙ x) ∙ y) ≈ (x ∙ (y ∙ y))RightAlternative _∙_ = ∀ x y → (x ∙ (y ∙ y)) ≈ ((x ∙ y) ∙ y)Alternative _∙_ = (LeftAlternative _∙_ ) × (RightAlternative _∙_)Flexible _∙_ = ∀ x y → ((x ∙ y) ∙ x) ≈ (x ∙ (y ∙ x))Medial _∙_ = ∀ x y u z → ((x ∙ y) ∙ (u ∙ z)) ≈ ((x ∙ u) ∙ (y ∙ z))LeftSemimedial _∙_ = ∀ x y z → ((x ∙ x) ∙ (y ∙ z)) ≈ ((x ∙ y) ∙ (x ∙ z))RightSemimedial _∙_ = ∀ x y z → ((y ∙ z) ∙ (x ∙ x)) ≈ ((y ∙ x) ∙ (z ∙ x))Semimedial _∙_ = (LeftSemimedial _∙_) × (RightSemimedial _∙_)LeftBol _∙_ = ∀ x y z → (x ∙ (y ∙ (x ∙ z))) ≈ ((x ∙ (y ∙ z)) ∙ z )RightBol _∙_ = ∀ x y z → (((z ∙ x) ∙ y) ∙ x) ≈ (z ∙ ((x ∙ y) ∙ x))MiddleBol _∙_ _\\_ _//_ = ∀ x y z → (x ∙ ((y ∙ z) \\ x)) ≈ ((x // z) ∙ (y \\ x))```* Added new functions to `Algebra.Definitions.RawSemiring`:```agda_^[_]*_ : A → ℕ → A → A_^ᵗ_ : A → ℕ → A```* In `Algebra.Bundles.Lattice` the existing record `Lattice` now provides```agda∨-commutativeSemigroup : CommutativeSemigroup c ℓ∧-commutativeSemigroup : CommutativeSemigroup c ℓ```and their corresponding algebraic sub-bundles.* In `Algebra.Lattice.Structures` the record `IsLattice` now provides```∨-isCommutativeSemigroup : IsCommutativeSemigroup ∨∧-isCommutativeSemigroup : IsCommutativeSemigroup ∧```and their corresponding algebraic substructures.* The module `Algebra.Properties.Magma.Divisibility` now re-exports operations`_∣ˡ_`, `_∤ˡ_`, `_∣ʳ_`, `_∤ʳ_` from `Algebra.Definitions.Magma`.* Added new records to `Algebra.Morphism.Structures`:```agdarecord IsQuasigroupHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsQuasigroupMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsQuasigroupIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)record IsLoopHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsLoopMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsLoopIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)record IsRingWithoutOneHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsRingWithoutOneMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsRingWithoutOneIsoMorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)record IsKleeneAlgebraHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsKleeneAlgebraMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)record IsKleeneAlgebraIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)```* Added new proofs to `Algebra.Properties.CommutativeSemigroup`:```agdaxy∙xx≈x∙yxx : (x ∙ y) ∙ (x ∙ x) ≈ x ∙ (y ∙ (x ∙ x))interchange : Interchangable _∙_ _∙_leftSemimedial : LeftSemimedial _∙_rightSemimedial : RightSemimedial _∙_middleSemimedial : (x ∙ y) ∙ (z ∙ x) ≈ (x ∙ z) ∙ (y ∙ x)semimedial : Semimedial _∙_```* Added new functions to `Algebra.Properties.CommutativeMonoid````agdainvertibleˡ⇒invertibleʳ : LeftInvertible _≈_ 0# _+_ x → RightInvertible _≈_ 0# _+_ xinvertibleʳ⇒invertibleˡ : RightInvertible _≈_ 0# _+_ x → LeftInvertible _≈_ 0# _+_ xinvertibleˡ⇒invertible : LeftInvertible _≈_ 0# _+_ x → Invertible _≈_ 0# _+_ xinvertibleʳ⇒invertible : RightInvertible _≈_ 0# _+_ x → Invertible _≈_ 0# _+_ x```* Added new proof to `Algebra.Properties.Monoid.Mult`:```agda×-congˡ : (_× x) Preserves _≡_ ⟶ _≈_```* Added new proof to `Algebra.Properties.Monoid.Sum`:```agdasum-init-last : (t : Vector _ (suc n)) → sum t ≈ sum (init t) + last t```* Added new proofs to `Algebra.Properties.Semigroup`:```agdaleftAlternative : LeftAlternative _∙_rightAlternative : RightAlternative _∙_alternative : Alternative _∙_flexible : Flexible _∙_```* Added new proofs to `Algebra.Properties.Semiring.Exp`:```agda^-congʳ : (x ^_) Preserves _≡_ ⟶ _≈_y*x^m*y^n≈x^m*y^[n+1] : x * y ≈ y * x → y * (x ^ m * y ^ n) ≈ x ^ m * y ^ suc n```* Added new proofs to `Algebra.Properties.Semiring.Mult`:```agda1×-identityʳ : 1 × x ≈ x×-comm-* : x * (n × y) ≈ n × (x * y)×-assoc-* : (n × x) * y ≈ n × (x * y)```* Added new proofs to `Algebra.Properties.Ring`:```agda-1*x≈-x : - 1# * x ≈ - xx+x≈x⇒x≈0 : x + x ≈ x → x ≈ 0#x[y-z]≈xy-xz : x * (y - z) ≈ x * y - x * z[y-z]x≈yx-zx : (y - z) * x ≈ (y * x) - (z * x)```* Added new functions in `Codata.Guarded.Stream`:```transpose : List (Stream A) → Stream (List A)transpose⁺ : List⁺ (Stream A) → Stream (List⁺ A)concat : Stream (List⁺ A) → Stream A```* Added new proofs in `Codata.Guarded.Stream.Properties`:```cong-concat : ass ≈ bss → concat ass ≈ concat bssmap-concat : map f (concat ass) ≈ concat (map (List⁺.map f) ass)lookup-transpose : lookup n (transpose ass) ≡ List.map (lookup n) asslookup-transpose⁺ : lookup n (transpose⁺ ass) ≡ List⁺.map (lookup n) ass```* Added new proofs in `Data.Bool.Properties`:```agda<-wellFounded : WellFounded _<_∨-conicalˡ : LeftConical false _∨_∨-conicalʳ : RightConical false _∨_∨-conical : Conical false _∨_∧-conicalˡ : LeftConical true _∧_∧-conicalʳ : RightConical true _∧_∧-conical : Conical true _∧_true-xor : true xor x ≡ not xxor-same : x xor x ≡ falsenot-distribˡ-xor : not (x xor y) ≡ (not x) xor ynot-distribʳ-xor : not (x xor y) ≡ x xor (not y)xor-assoc : Associative _xor_xor-comm : Commutative _xor_xor-identityˡ : LeftIdentity false _xor_xor-identityʳ : RightIdentity false _xor_xor-identity : Identity false _xor_xor-inverseˡ : LeftInverse true not _xor_xor-inverseʳ : RightInverse true not _xor_xor-inverse : Inverse true not _xor_∧-distribˡ-xor : _∧_ DistributesOverˡ _xor_∧-distribʳ-xor : _∧_ DistributesOverʳ _xor_∧-distrib-xor : _∧_ DistributesOver _xor_xor-annihilates-not : (not x) xor (not y) ≡ x xor y```* Exposed container combinator conversion functions from `Data.Container.Combinator.Properties`separately from their correctness proofs in `Data.Container.Combinator`:```to-id : F.id A → ⟦ id ⟧ Afrom-id : ⟦ id ⟧ A → F.id Ato-const : A → ⟦ const A ⟧ Bfrom-const : ⟦ const A ⟧ B → Ato-∘ : ⟦ C₁ ⟧ (⟦ C₂ ⟧ A) → ⟦ C₁ ∘ C₂ ⟧ Afrom-∘ : ⟦ C₁ ∘ C₂ ⟧ A → ⟦ C₁ ⟧ (⟦ C₂ ⟧ A)to-× : ⟦ C₁ ⟧ A P.× ⟦ C₂ ⟧ A → ⟦ C₁ × C₂ ⟧ Afrom-× : ⟦ C₁ × C₂ ⟧ A → ⟦ C₁ ⟧ A P.× ⟦ C₂ ⟧ Ato-Π : (∀ i → ⟦ Cᵢ i ⟧ A) → ⟦ Π I Cᵢ ⟧ Afrom-Π : ⟦ Π I Cᵢ ⟧ A → ∀ i → ⟦ Cᵢ i ⟧ Ato-⊎ : ⟦ C₁ ⟧ A S.⊎ ⟦ C₂ ⟧ A → ⟦ C₁ ⊎ C₂ ⟧ Afrom-⊎ : ⟦ C₁ ⊎ C₂ ⟧ A → ⟦ C₁ ⟧ A S.⊎ ⟦ C₂ ⟧ Ato-Σ : (∃ λ i → ⟦ C i ⟧ A) → ⟦ Σ I C ⟧ Afrom-Σ : ⟦ Σ I C ⟧ A → ∃ λ i → ⟦ C i ⟧ A```* Added new functions in `Data.Fin.Base`:```finToFun : Fin (m ^ n) → (Fin n → Fin m)funToFin : (Fin m → Fin n) → Fin (n ^ m)quotient : Fin (m * n) → Fin mremainder : Fin (m * n) → Fin n```* Added new proofs in `Data.Fin.Induction`:```agdaspo-wellFounded : IsStrictPartialOrder _≈_ _⊏_ → WellFounded _⊏_spo-noetherian : IsStrictPartialOrder _≈_ _⊏_ → WellFounded (flip _⊏_)<-weakInduction-startingFrom : P i → (∀ j → P (inject₁ j) → P (suc j)) → ∀ {j} → j ≥ i → P j```* Added new definitions and proofs in `Data.Fin.Permutation`:```agdainsert : Fin (suc m) → Fin (suc n) → Permutation m n → Permutation (suc m) (suc n)insert-punchIn : insert i j π ⟨$⟩ʳ punchIn i k ≡ punchIn j (π ⟨$⟩ʳ k)insert-remove : insert i (π ⟨$⟩ʳ i) (remove i π) ≈ πremove-insert : remove i (insert i j π) ≈ π```* Added new proofs in `Data.Fin.Properties`:```1↔⊤ : Fin 1 ↔ ⊤2↔Bool : Fin 2 ↔ Bool0≢1+n : zero ≢ suc i↑ˡ-injective : i ↑ˡ n ≡ j ↑ˡ n → i ≡ j↑ʳ-injective : n ↑ʳ i ≡ n ↑ʳ j → i ≡ jfinTofun-funToFin : funToFin ∘ finToFun ≗ idfunTofin-funToFun : finToFun (funToFin f) ≗ f^↔→ : Extensionality _ _ → Fin (m ^ n) ↔ (Fin n → Fin m)toℕ-mono-< : i < j → toℕ i ℕ.< toℕ jtoℕ-mono-≤ : i ≤ j → toℕ i ℕ.≤ toℕ jtoℕ-cancel-≤ : toℕ i ℕ.≤ toℕ j → i ≤ jtoℕ-cancel-< : toℕ i ℕ.< toℕ j → i < jsplitAt⁻¹-↑ˡ : splitAt m {n} i ≡ inj₁ j → j ↑ˡ n ≡ isplitAt⁻¹-↑ʳ : splitAt m {n} i ≡ inj₂ j → m ↑ʳ j ≡ itoℕ-combine : toℕ (combine i j) ≡ k ℕ.* toℕ i ℕ.+ toℕ jcombine-injectiveˡ : combine i j ≡ combine k l → i ≡ kcombine-injectiveʳ : combine i j ≡ combine k l → j ≡ lcombine-injective : combine i j ≡ combine k l → i ≡ k × j ≡ lcombine-surjective : ∀ i → ∃₂ λ j k → combine j k ≡ icombine-monoˡ-< : i < j → combine i k < combine j lℕ-ℕ≡toℕ‿ℕ- : n ℕ-ℕ i ≡ toℕ (n ℕ- i)lower₁-injective : lower₁ i n≢i ≡ lower₁ j n≢j → i ≡ jpinch-injective : suc i ≢ j → suc i ≢ k → pinch i j ≡ pinch i k → j ≡ ki<1+i : i < suc iinjective⇒≤ : ∀ {f : Fin m → Fin n} → Injective f → m ℕ.≤ n<⇒notInjective : ∀ {f : Fin m → Fin n} → n ℕ.< m → ¬ (Injective f)ℕ→Fin-notInjective : ∀ (f : ℕ → Fin n) → ¬ (Injective f)cantor-schröder-bernstein : ∀ {f : Fin m → Fin n} {g : Fin n → Fin m} → Injective f → Injective g → m ≡ ncast-is-id : cast eq k ≡ ksubst-is-cast : subst Fin eq k ≡ cast eq kcast-trans : cast eq₂ (cast eq₁ k) ≡ cast (trans eq₁ eq₂) kfromℕ≢inject₁ : {i : Fin n} → fromℕ n ≢ inject₁ iinject≤-trans : inject≤ (inject≤ i m≤n) n≤o ≡ inject≤ i (≤-trans m≤n n≤o)inject≤-irrelevant : inject≤ i m≤n ≡ inject≤ i m≤n′i≤inject₁[j]⇒i≤1+j : i ≤ inject₁ j → i ≤ suc j```* Added new lemmas in `Data.Fin.Substitution.Lemmas.TermLemmas`:```map-var≡ : (∀ x → lookup ρ₁ x ≡ f x) → (∀ x → lookup ρ₂ x ≡ T.var (f x)) → map var ρ₁ ≡ ρ₂wk≡wk : map var VarSubst.wk ≡ T.wk {n = n}id≡id : map var VarSubst.id ≡ T.id {n = n}sub≡sub : map var (VarSubst.sub x) ≡ T.sub (T.var x)↑≡↑ : map var (ρ VarSubst.↑) ≡ map T.var ρ T.↑/Var≡/ : t /Var ρ ≡ t T./ map T.var ρsub-renaming-commutes : t /Var VarSubst.sub x T./ ρ ≡ t T./ ρ T.↑ T./ T.sub (lookup ρ x)sub-commutes-with-renaming : t T./ T.sub t′ /Var ρ ≡ t /Var ρ VarSubst.↑ T./ T.sub (t′ /Var ρ)```* Added new functions and definitions in `Data.Integer.Base`:```agda_^_ : ℤ → ℕ → ℤ+-0-rawGroup : Rawgroup 0ℓ 0ℓ*-rawMagma : RawMagma 0ℓ 0ℓ*-1-rawMonoid : RawMonoid 0ℓ 0ℓ```* Added new proofs in `Data.Integer.Properties`:```agdasign-cong′ : s₁ ◃ n₁ ≡ s₂ ◃ n₂ → s₁ ≡ s₂ ⊎ (n₁ ≡ 0 × n₂ ≡ 0)≤-⊖ : m ℕ.≤ n → n ⊖ m ≡ + (n ∸ m)∣⊖∣-≤ : m ℕ.≤ n → ∣ m ⊖ n ∣ ≡ n ∸ m∣-∣-≤ : i ≤ j → + ∣ i - j ∣ ≡ j - ii^n≡0⇒i≡0 : i ^ n ≡ 0ℤ → i ≡ 0ℤ^-identityʳ : i ^ 1 ≡ i^-zeroˡ : 1 ^ n ≡ 1^-*-assoc : (i ^ m) ^ n ≡ i ^ (m ℕ.* n)^-distribˡ-+-* : i ^ (m ℕ.+ n) ≡ i ^ m * i ^ n^-isMagmaHomomorphism : IsMagmaHomomorphism ℕ.+-rawMagma *-rawMagma (i ^_)^-isMonoidHomomorphism : IsMonoidHomomorphism ℕ.+-0-rawMonoid *-1-rawMonoid (i ^_)```* Added new proofs in `Data.Integer.GCD`:```agdagcd-assoc : Associative gcdgcd-zeroˡ : LeftZero 1ℤ gcdgcd-zeroʳ : RightZero 1ℤ gcdgcd-zero : Zero 1ℤ gcd```* Added new functions and definitions to `Data.List.Base`:```agdatakeWhileᵇ : (A → Bool) → List A → List AdropWhileᵇ : (A → Bool) → List A → List Afilterᵇ : (A → Bool) → List A → List Apartitionᵇ : (A → Bool) → List A → List A × List Aspanᵇ : (A → Bool) → List A → List A × List Abreakᵇ : (A → Bool) → List A → List A × List AlinesByᵇ : (A → Bool) → List A → List (List A)wordsByᵇ : (A → Bool) → List A → List (List A)derunᵇ : (A → A → Bool) → List A → List Adeduplicateᵇ : (A → A → Bool) → List A → List Afindᵇ : (A → Bool) → List A -> Maybe AfindIndexᵇ : (A → Bool) → (xs : List A) → Maybe $ Fin (length xs)findIndicesᵇ : (A → Bool) → (xs : List A) → List $ Fin (length xs)find : Decidable P → List A → Maybe AfindIndex : Decidable P → (xs : List A) → Maybe $ Fin (length xs)findIndices : Decidable P → (xs : List A) → List $ Fin (length xs)catMaybes : List (Maybe A) → List Aap : List (A → B) → List A → List B++-rawMagma : Set a → RawMagma a _++-[]-rawMonoid : Set a → RawMonoid a _iterate : (A → A) → A → ℕ → List AinsertAt : (xs : List A) → Fin (suc (length xs)) → A → List AupdateAt : (xs : List A) → Fin (length xs) → (A → A) → List A```* Added new proofs in `Data.List.Relation.Binary.Lex.Strict`:```agdaxs≮[] : ¬ xs < []```* Added new proofs to `Data.List.Relation.Binary.Permutation.Propositional.Properties`:```agdaAny-resp-[σ⁻¹∘σ] : (σ : xs ↭ ys) → (ix : Any P xs) → Any-resp-↭ (trans σ (↭-sym σ)) ix ≡ ix∈-resp-[σ⁻¹∘σ] : (σ : xs ↭ ys) → (ix : x ∈ xs) → ∈-resp-↭ (trans σ (↭-sym σ)) ix ≡ ix```* In `Data.List.Relation.Binary.Permutation.Setoid.Properties`:```agdafoldr-commMonoid : xs ↭ ys → foldr _∙_ ε xs ≈ foldr _∙_ ε ys```* Added new function to `Data.List.Relation.Binary.Permutation.Propositional.Properties````agda↭-reverse : reverse xs ↭ xs```* Added new proofs to `Data.List.Relation.Binary.Sublist.Setoid.Properties`:```⊆-mergeˡ : xs ⊆ merge _≤?_ xs ys⊆-mergeʳ : ys ⊆ merge _≤?_ xs ys```* Added new functions in `Data.List.Relation.Unary.All`:```decide : Π[ P ∪ Q ] → Π[ All P ∪ Any Q ]```* Added new proof to `Data.List.Relation.Unary.All.Properties`:```agdagmap⁻ : Q ∘ f ⋐ P → All Q ∘ map f ⋐ All P```* Added new functions in `Data.List.Fresh.Relation.Unary.All`:```decide : Π[ P ∪ Q ] → Π[ All {R = R} P ∪ Any Q ]```* Added new proofs to `Data.List.Membership.Propositional.Properties`:```agdamapWith∈-id : mapWith∈ xs (λ {x} _ → x) ≡ xsmap-mapWith∈ : map g (mapWith∈ xs f) ≡ mapWith∈ xs (g ∘′ f)```* Added new proofs to `Data.List.Membership.Setoid.Properties`:```agdamapWith∈-id : mapWith∈ xs (λ {x} _ → x) ≡ xsmap-mapWith∈ : map g (mapWith∈ xs f) ≡ mapWith∈ xs (g ∘′ f)index-injective : index x₁∈xs ≡ index x₂∈xs → x₁ ≈ x₂∈-++⁺∘++⁻ : (p : v ∈ xs ++ ys) → [ ∈-++⁺ˡ , ∈-++⁺ʳ xs ]′ (∈-++⁻ xs p) ≡ p∈-++⁻∘++⁺ : (p : v ∈ xs ⊎ v ∈ ys) → ∈-++⁻ xs ([ ∈-++⁺ˡ , ∈-++⁺ʳ xs ]′ p) ≡ p∈-++↔ : (v ∈ xs ⊎ v ∈ ys) ↔ v ∈ xs ++ ys∈-++-comm : v ∈ xs ++ ys → v ∈ ys ++ xs∈-++-comm∘++-comm : (p : v ∈ xs ++ ys) → ∈-++-comm ys xs (∈-++-comm xs ys p) ≡ p∈-++↔++ : v ∈ xs ++ ys ↔ v ∈ ys ++ xs```* Add new proofs in `Data.List.Properties`:```agda∈⇒∣product : n ∈ ns → n ∣ product ns∷ʳ-++ : xs ∷ʳ a ++ ys ≡ xs ++ a ∷ ysconcatMap-cong : f ≗ g → concatMap f ≗ concatMap gconcatMap-pure : concatMap [_] ≗ idconcatMap-map : concatMap g (map f xs) ≡ concatMap (g ∘′ f) xsmap-concatMap : map f ∘′ concatMap g ≗ concatMap (map f ∘′ g)length-isMagmaHomomorphism : (A : Set a) → IsMagmaHomomorphism (++-rawMagma A) +-rawMagma lengthlength-isMonoidHomomorphism : (A : Set a) → IsMonoidHomomorphism (++-[]-rawMonoid A) +-0-rawMonoid lengthtake-map : take n (map f xs) ≡ map f (take n xs)drop-map : drop n (map f xs) ≡ map f (drop n xs)head-map : head (map f xs) ≡ Maybe.map f (head xs)take-suc : take (suc m) xs ≡ take m xs ∷ʳ lookup xs itake-suc-tabulate : take (suc m) (tabulate f) ≡ take m (tabulate f) ∷ʳ f idrop-take-suc : drop m (take (suc m) xs) ≡ [ lookup xs i ]drop-take-suc-tabulate : drop m (take (suc m) (tabulate f)) ≡ [ f i ]take-all : n ≥ length xs → take n xs ≡ xsdrop-all : n ≥ length xs → drop n xs ≡ []take-[] : take m [] ≡ []drop-[] : drop m [] ≡ []drop-drop : drop n (drop m xs) ≡ drop (m + n) xslookup-replicate : lookup (replicate n x) i ≡ xmap-replicate : map f (replicate n x) ≡ replicate n (f x)zipWith-replicate : zipWith _⊕_ (replicate n x) (replicate n y) ≡ replicate n (x ⊕ y)length-iterate : length (iterate f x n) ≡ niterate-id : iterate id x n ≡ replicate n xlookup-iterate : lookup (iterate f x n) (cast (sym (length-iterate f x n)) i) ≡ ℕ.iterate f x (toℕ i)length-insertAt : length (insertAt xs i v) ≡ suc (length xs)length-removeAt′ : length xs ≡ suc (length (removeAt xs k))removeAt-insertAt : removeAt (insertAt xs i v) ((cast (sym (length-insertAt xs i v)) i)) ≡ xsinsertAt-removeAt : insertAt (removeAt xs i) (cast (sym (lengthAt-removeAt xs i)) i) (lookup xs i) ≡ xscartesianProductWith-zeroˡ : cartesianProductWith f [] ys ≡ []cartesianProductWith-zeroʳ : cartesianProductWith f xs [] ≡ []cartesianProductWith-distribʳ-++ : cartesianProductWith f (xs ++ ys) zs ≡cartesianProductWith f xs zs ++ cartesianProductWith f ys zsfoldr-map : foldr f x (map g xs) ≡ foldr (g -⟨ f ∣) x xsfoldl-map : foldl f x (map g xs) ≡ foldl (∣ f ⟩- g) x xs```* In `Data.List.NonEmpty.Base`:```agdadrop+ : ℕ → List⁺ A → List⁺ A```* Added new proofs in `Data.List.NonEmpty.Properties`:```agdalength-++⁺ : length (xs ++⁺ ys) ≡ length xs + length yslength-++⁺-tail : length (xs ++⁺ ys) ≡ suc (length xs + length (tail ys))++-++⁺ : (xs ++ ys) ++⁺ zs ≡ xs ++⁺ ys ++⁺ zs++⁺-cancelˡ′ : xs ++⁺ zs ≡ ys ++⁺ zs′ → List.length xs ≡ List.length ys → zs ≡ zs′++⁺-cancelˡ : xs ++⁺ ys ≡ xs ++⁺ zs → ys ≡ zsdrop+-++⁺ : drop+ (length xs) (xs ++⁺ ys) ≡ ysmap-++⁺-commute : map f (xs ++⁺ ys) ≡ map f xs ++⁺ map f yslength-map : length (map f xs) ≡ length xsmap-cong : f ≗ g → map f ≗ map gmap-compose : map (g ∘ f) ≗ map g ∘ map f```* Added new proof to `Data.Maybe.Properties````agda<∣>-idem : Idempotent _<∣>_```* Added new patterns and definitions to `Data.Nat.Base`:```agdapattern z<s {n} = s≤s (z≤n {n})pattern s<s {m} {n} m<n = s≤s {m} {n} m<ns≤s⁻¹ : suc m ≤ suc n → m ≤ ns<s⁻¹ : suc m < suc n → m < npattern <′-base = ≤′-reflpattern <′-step {n} m<′n = ≤′-step {n} m<′npattern ≤″-offset k = less-than-or-equal {k} reflpattern <″-offset k = ≤″-offset ks≤″s⁻¹ : suc m ≤″ suc n → m ≤″ ns<″s⁻¹ : suc m <″ suc n → m <″ npattern 2+ n = suc (suc n)pattern 1<2+n {n} = s<s (z<s {n})NonTrivial : Pred ℕ 0ℓinstance nonTrivial : NonTrivial (2+ n)n>1⇒nonTrivial : 1 < n → NonTrivial nnonZero⇒≢1⇒nonTrivial : .{{NonZero n}} → n ≢ 1 → NonTrivial nrecompute-nonTrivial : .{{NonTrivial n}} → NonTrivial nnonTrivial⇒nonZero : .{{NonTrivial n}} → NonZero nnonTrivial⇒n>1 : .{{NonTrivial n}} → 1 < nnonTrivial⇒≢1 : .{{NonTrivial n}} → n ≢ 1_⊔′_ : ℕ → ℕ → ℕ_⊓′_ : ℕ → ℕ → ℕ∣_-_∣′ : ℕ → ℕ → ℕ_! : ℕ → ℕparity : ℕ → Parity+-rawMagma : RawMagma 0ℓ 0ℓ+-0-rawMonoid : RawMonoid 0ℓ 0ℓ*-rawMagma : RawMagma 0ℓ 0ℓ*-1-rawMonoid : RawMonoid 0ℓ 0ℓ+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawSemiring : RawSemiring 0ℓ 0ℓ```* Added a new proof to `Data.Nat.Binary.Properties`:```agdasuc-injective : Injective _≡_ _≡_ suctoℕ-inverseˡ : Inverseˡ _≡_ _≡_ toℕ fromℕtoℕ-inverseʳ : Inverseʳ _≡_ _≡_ toℕ fromℕtoℕ-inverseᵇ : Inverseᵇ _≡_ _≡_ toℕ fromℕ<-asym : Asymmetric _<_```* Added a new pattern synonym and a new definition to `Data.Nat.Divisibility.Core`:```agdapattern divides-refl q = divides q reflrecord _HasNonTrivialDivisorLessThan_ (m n : ℕ) : Set where```* Added new proofs to `Data.Nat.Divisibility`:```agdahasNonTrivialDivisor-≢ : .{{NonTrivial d}} → .{{NonZero n}} → d ≢ n → d ∣ n → n HasNonTrivialDivisorLessThan nhasNonTrivialDivisor-∣ : m HasNonTrivialDivisorLessThan n → m ∣ o → o HasNonTrivialDivisorLessThan nhasNonTrivialDivisor-≤ : m HasNonTrivialDivisorLessThan n → n ≤ o → m HasNonTrivialDivisorLessThan o```* Added new definitions, smart constructors and proofs to `Data.Nat.Primality`:```agdainfix 10 _Rough__Rough_ : ℕ → Pred ℕ _0-rough : 0 Rough n1-rough : 1 Rough n2-rough : 2 Rough nrough⇒≤ : .{{NonTrivial n}} → m Rough n → m ≤ n∤⇒rough-suc : m ∤ n → m Rough n → (suc m) Rough nrough∧∣⇒rough : m Rough o → n ∣ o → m Rough nComposite : ℕ → Setcomposite-≢ : .{{NonTrivial d}} → .{{NonZero n}} → d ≢ n → d ∣ n → Composite ncomposite-∣ : .{{NonZero n}} → Composite m → m ∣ n → Composite ncomposite? : Decidable CompositeIrreducible : ℕ → Setirreducible? : Decidable Irreduciblecomposite⇒¬prime : Composite n → ¬ Prime n¬composite⇒prime : .{{NonTrivial n} → ¬ Composite n → Prime nprime⇒¬composite : Prime n → ¬ Composite n¬prime⇒composite : .{{NonTrivial n} → ¬ Prime n → Composite nprime⇒irreducible : Prime p → Irreducible pirreducible⇒prime : .{{NonTrivial p}} → Irreducible p → Prime peuclidsLemma : Prime p → p ∣ m * n → p ∣ m ⊎ p ∣ n```* Added new proofs in `Data.Nat.Properties`:```agdanonZero? : Decidable NonZeron≮0 : n ≮ 0n+1+m≢m : n + suc m ≢ mm*n≡0⇒m≡0 : .{{_ : NonZero n}} → m * n ≡ 0 → m ≡ 0n>0⇒n≢0 : n > 0 → n ≢ 0m*n≢0 : .{{_ : NonZero m}} .{{_ : NonZero n}} → NonZero (m * n)m*n≢0⇒m≢0 : .{{NonZero (m * n)}} → NonZero mm*n≢0⇒n≢0 : .{{NonZero (m * n)}} → NonZero nm≢0∧n>1⇒m*n>1 : .{{_ : NonZero m}} .{{_ : NonTrivial n}} → NonTrivial (m * n)n≢0∧m>1⇒m*n>1 : .{{_ : NonZero n}} .{{_ : NonTrivial m}} → NonTrivial (m * n)m^n≢0 : .{{_ : NonZero m}} → NonZero (m ^ n)m≤n⇒n∸m≤n : m ≤ n → n ∸ m ≤ ns<s-injective : s<s p ≡ s<s q → p ≡ q<-step : m < n → m < 1 + nm<1+n⇒m<n∨m≡n : m < suc n → m < n ⊎ m ≡ npred-mono-≤ : m ≤ n → pred m ≤ pred npred-mono-< : .{{_ : NonZero m}} → m < n → pred m < pred nz<′s : zero <′ suc ns<′s : m <′ n → suc m <′ suc n<⇒<′ : m < n → m <′ n<′⇒< : m <′ n → m < n≤″-proof : (le : m ≤″ n) → let less-than-or-equal {k} _ = le in m + k ≡ nm+n≤p⇒m≤p∸n : m + n ≤ p → m ≤ p ∸ nm≤p∸n⇒m+n≤p : n ≤ p → m ≤ p ∸ n → m + n ≤ p1≤n! : 1 ≤ n !_!≢0 : NonZero (n !)_!*_!≢0 : NonZero (m ! * n !)anyUpTo? : ∀ (P? : U.Decidable P) (v : ℕ) → Dec (∃ λ n → n < v × P n)allUpTo? : ∀ (P? : U.Decidable P) (v : ℕ) → Dec (∀ {n} → n < v → P n)n≤1⇒n≡0∨n≡1 : n ≤ 1 → n ≡ 0 ⊎ n ≡ 1m^n>0 : .{{_ : NonZero m}} n → m ^ n > 0^-monoˡ-≤ : (_^ n) Preserves _≤_ ⟶ _≤_^-monoʳ-≤ : .{{_ : NonZero m}} → (m ^_) Preserves _≤_ ⟶ _≤_^-monoˡ-< : .{{_ : NonZero n}} → (_^ n) Preserves _<_ ⟶ _<_^-monoʳ-< : 1 < m → (m ^_) Preserves _<_ ⟶ _<_n≡⌊n+n/2⌋ : n ≡ ⌊ n + n /2⌋n≡⌈n+n/2⌉ : n ≡ ⌈ n + n /2⌉m<n⇒m<n*o : .{{_ : NonZero o}} → m < n → m < n * om<n⇒m<o*n : .{{_ : NonZero o}} → m < n → m < o * n∸-monoˡ-< : m < o → n ≤ m → m ∸ n < o ∸ nm≤n⇒∣m-n∣≡n∸m : m ≤ n → ∣ m - n ∣ ≡ n ∸ m⊔≡⊔′ : m ⊔ n ≡ m ⊔′ n⊓≡⊓′ : m ⊓ n ≡ m ⊓′ n∣-∣≡∣-∣′ : ∣ m - n ∣ ≡ ∣ m - n ∣′nonTrivial? : Decidable NonTrivialeq? : A ↣ ℕ → DecidableEquality A≤-<-connex : Connex _≤_ _<_≥->-connex : Connex _≥_ _>_<-≤-connex : Connex _<_ _≤_>-≥-connex : Connex _>_ _≥_<-cmp : Trichotomous _≡_ _<_anyUpTo? : (P? : Decidable P) → ∀ v → Dec (∃ λ n → n < v × P n)allUpTo? : (P? : Decidable P) → ∀ v → Dec (∀ {n} → n < v → P n)```* Added new proofs in `Data.Nat.Combinatorics`:```agda[n-k]*[n-k-1]!≡[n-k]! : k < n → (n ∸ k) * (n ∸ suc k) ! ≡ (n ∸ k) ![n-k]*d[k+1]≡[k+1]*d[k] : k < n → (n ∸ k) * ((suc k) ! * (n ∸ suc k) !) ≡ (suc k) * (k ! * (n ∸ k) !)k![n∸k]!∣n! : k ≤ n → k ! * (n ∸ k) ! ∣ n !nP1≡n : n P 1 ≡ nnC1≡n : n C 1 ≡ nnCk+nC[k+1]≡[n+1]C[k+1] : n C k + n C (suc k) ≡ suc n C suc k```* Added new proofs in `Data.Nat.DivMod`:```agdam%n≤n : .{{_ : NonZero n}} → m % n ≤ nm*n/m!≡n/[m∸1]! : .{{_ : NonZero m}} → m * n / m ! ≡ n / (pred m) !%-congˡ : .{{_ : NonZero o}} → m ≡ n → m % o ≡ n % o%-congʳ : .{{_ : NonZero m}} .{{_ : NonZero n}} → m ≡ n → o % m ≡ o % nm≤n⇒[n∸m]%m≡n%m : .{{_ : NonZero m}} → m ≤ n → (n ∸ m) % m ≡ n % mm*n≤o⇒[o∸m*n]%n≡o%n : .{{_ : NonZero n}} → m * n ≤ o → (o ∸ m * n) % n ≡ o % nm∣n⇒o%n%m≡o%m : .{{_ : NonZero m}} .{{_ : NonZero n}} → m ∣ n → o % n % m ≡ o % mm<n⇒m%n≡m : .{{_ : NonZero n}} → m < n → m % n ≡ mm*n/o*n≡m/o : .{{_ : NonZero o}} {{_ : NonZero (o * n)}} → m * n / (o * n) ≡ m / om<n*o⇒m/o<n : .{{_ : NonZero o}} → m < n * o → m / o < n[m∸n]/n≡m/n∸1 : .{{_ : NonZero n}} → (m ∸ n) / n ≡ pred (m / n)[m∸n*o]/o≡m/o∸n : .{{_ : NonZero o}} → (m ∸ n * o) / o ≡ m / o ∸ nm/n/o≡m/[n*o] : .{{_ : NonZero n}} .{{_ : NonZero o}} .{{_ : NonZero (n * o)}} → m / n / o ≡ m / (n * o)m%[n*o]/o≡m/o%n : .{{_ : NonZero n}} .{{_ : NonZero o}} {{_ : NonZero (n * o)}} → m % (n * o) / o ≡ m / o % nm%n*o≡m*o%[n*o] : .{{_ : NonZero n}} {{_ : NonZero (n * o)}} → m % n * o ≡ m * o % (n * o)[m*n+o]%[p*n]≡[m*n]%[p*n]+o : {{_ : NonZero (p * n)}} → o < n → (m * n + o) % (p * n) ≡ (m * n) % (p * n) + o```* Added new proofs in `Data.Nat.Divisibility`:```agdan∣m*n*o : n ∣ m * n * om*n∣⇒m∣ : m * n ∣ i → m ∣ im*n∣⇒n∣ : m * n ∣ i → n ∣ im≤n⇒m!∣n! : m ≤ n → m ! ∣ n !m/n/o≡m/[n*o] : .{{NonZero n}} .{{NonZero o}} → n * o ∣ m → (m / n) / o ≡ m / (n * o)```* Added new proofs in `Data.Nat.GCD`:```agdagcd-assoc : Associative gcdgcd-identityˡ : LeftIdentity 0 gcdgcd-identityʳ : RightIdentity 0 gcdgcd-identity : Identity 0 gcdgcd-zeroˡ : LeftZero 1 gcdgcd-zeroʳ : RightZero 1 gcdgcd-zero : Zero 1 gcd```* Added new patterns in `Data.Nat.Reflection`:```agdapattern `ℕ = def (quote ℕ) []pattern `zero = con (quote ℕ.zero) []pattern `suc x = con (quote ℕ.suc) (x ⟨∷⟩ [])```* Added new functions and proofs in `Data.Nat.GeneralisedArithmetic`:```agdaiterate : (A → A) → A → ℕ → Aiterate-is-fold : fold z s m ≡ iterate s z m```* Added new proofs in `Data.Parity.Properties`:```agdasuc-homo-⁻¹ : (parity (suc n)) ⁻¹ ≡ parity n+-homo-+ : parity (m ℕ.+ n) ≡ parity m ℙ.+ parity n*-homo-* : parity (m ℕ.* n) ≡ parity m ℙ.* parity nparity-isMagmaHomomorphism : IsMagmaHomomorphism ℕ.+-rawMagma ℙ.+-rawMagma parityparity-isMonoidHomomorphism : IsMonoidHomomorphism ℕ.+-0-rawMonoid ℙ.+-0-rawMonoid parityparity-isNearSemiringHomomorphism : IsNearSemiringHomomorphism ℕ.+-*-rawNearSemiring ℙ.+-*-rawNearSemiring parityparity-isSemiringHomomorphism : IsSemiringHomomorphism ℕ.+-*-rawSemiring ℙ.+-*-rawSemiring parity```* Added new rounding functions in `Data.Rational.Base`:```agdafloor ceiling truncate round ⌊_⌋ ⌈_⌉ [_] : ℚ → ℤfracPart : ℚ → ℚ```* Added new definitions and proofs in `Data.Rational.Properties`:```agda↥ᵘ-toℚᵘ : ↥ᵘ (toℚᵘ p) ≡ ↥ p↧ᵘ-toℚᵘ : ↧ᵘ (toℚᵘ p) ≡ ↧ p↥p≡↥q≡0⇒p≡q : ↥ p ≡ 0ℤ → ↥ q ≡ 0ℤ → p ≡ q_≥?_ : Decidable _≥__>?_ : Decidable _>_+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawSemiring : RawSemiring 0ℓ 0ℓtoℚᵘ-isNearSemiringHomomorphism-+-* : IsNearSemiringHomomorphism +-*-rawNearSemiring ℚᵘ.+-*-rawNearSemiring toℚᵘtoℚᵘ-isNearSemiringMonomorphism-+-* : IsNearSemiringMonomorphism +-*-rawNearSemiring ℚᵘ.+-*-rawNearSemiring toℚᵘtoℚᵘ-isSemiringHomomorphism-+-* : IsSemiringHomomorphism +-*-rawSemiring ℚᵘ.+-*-rawSemiring toℚᵘtoℚᵘ-isSemiringMonomorphism-+-* : IsSemiringMonomorphism +-*-rawSemiring ℚᵘ.+-*-rawSemiring toℚᵘpos⇒nonZero : .{{Positive p}} → NonZero pneg⇒nonZero : .{{Negative p}} → NonZero pnonZero⇒1/nonZero : .{{_ : NonZero p}} → NonZero (1/ p)<-dense : Dense _<_<-isDenseLinearOrder : IsDenseLinearOrder _≡_ _<_<-denseLinearOrder : DenseLinearOrder 0ℓ 0ℓ 0ℓ```* Added new rounding functions in `Data.Rational.Unnormalised.Base`:```agdafloor ceiling truncate round ⌊_⌋ ⌈_⌉ [_] : ℚᵘ → ℤfracPart : ℚᵘ → ℚᵘ```* Added new definitions in `Data.Rational.Unnormalised.Properties`:```agda↥p≡0⇒p≃0 : ↥ p ≡ 0ℤ → p ≃ 0ℚᵘp≃0⇒↥p≡0 : p ≃ 0ℚᵘ → ↥ p ≡ 0ℤ↥p≡↥q≡0⇒p≃q : ↥ p ≡ 0ℤ → ↥ q ≡ 0ℤ → p ≃ q+-*-rawNearSemiring : RawNearSemiring 0ℓ 0ℓ+-*-rawSemiring : RawSemiring 0ℓ 0ℓ≰⇒≥ : _≰_ ⇒ _≥__≥?_ : Decidable _≥__>?_ : Decidable _>_*-mono-≤-nonNeg : .{{_ : NonNegative p}} .{{_ : NonNegative r}} → p ≤ q → r ≤ s → p * r ≤ q * s*-mono-<-nonNeg : .{{_ : NonNegative p}} .{{_ : NonNegative r}} → p < q → r < s → p * r < q * s1/-antimono-≤-pos : .{{_ : Positive p}} .{{_ : Positive q}} → p ≤ q → 1/ q ≤ 1/ p⊓-mono-< : _⊓_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊔-mono-< : _⊔_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_pos⇒nonZero : .{{_ : Positive p}} → NonZero pneg⇒nonZero : .{{_ : Negative p}} → NonZero ppos+pos⇒pos : .{{_ : Positive p}} .{{_ : Positive q}} → Positive (p + q)nonNeg+nonNeg⇒nonNeg : .{{_ : NonNegative p}} .{{_ : NonNegative q}} → NonNegative (p + q)pos*pos⇒pos : .{{_ : Positive p}} .{{_ : Positive q}} → Positive (p * q)nonNeg*nonNeg⇒nonNeg : .{{_ : NonNegative p}} .{{_ : NonNegative q}} → NonNegative (p * q)pos⊓pos⇒pos : .{{_ : Positive p}} .{{_ : Positive q}} → Positive (p ⊓ q)pos⊔pos⇒pos : .{{_ : Positive p}} .{{_ : Positive q}} → Positive (p ⊔ q)1/nonZero⇒nonZero : .{{_ : NonZero p}} → NonZero (1/ p)0≄1 : 0ℚᵘ ≄ 1ℚᵘ≃-≄-irreflexive : Irreflexive _≃_ _≄_≄-symmetric : Symmetric _≄_≄-cotransitive : Cotransitive _≄_≄⇒invertible : p ≄ q → Invertible _≃_ 1ℚᵘ _*_ (p - q)<-dense : Dense _<_<-isDenseLinearOrder : IsDenseLinearOrder _≃_ _<_+-*-isHeytingCommutativeRing : IsHeytingCommutativeRing _≃_ _≄_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-isHeytingField : IsHeytingField _≃_ _≄_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ<-denseLinearOrder : DenseLinearOrder 0ℓ 0ℓ 0ℓ+-*-heytingCommutativeRing : HeytingCommutativeRing 0ℓ 0ℓ 0ℓ+-*-heytingField : HeytingField 0ℓ 0ℓ 0ℓmodule ≃-Reasoning = SetoidReasoning ≃-setoid```* Added new functions to `Data.Product.Nary.NonDependent`:```agdazipWith : (∀ k → Projₙ as k → Projₙ bs k → Projₙ cs k) → Product n as → Product n bs → Product n cs```* Added new proof to `Data.Product.Properties`:```agdamap-cong : f ≗ g → h ≗ i → map f h ≗ map g i```* Added new definitions to `Data.Product.Properties`:```Σ-≡,≡→≡ : (∃ λ (p : proj₁ p₁ ≡ proj₁ p₂) → subst B p (proj₂ p₁) ≡ proj₂ p₂) → p₁ ≡ p₂Σ-≡,≡←≡ : p₁ ≡ p₂ → (∃ λ (p : proj₁ p₁ ≡ proj₁ p₂) → subst B p (proj₂ p₁) ≡ proj₂ p₂)×-≡,≡→≡ : (proj₁ p₁ ≡ proj₁ p₂ × proj₂ p₁ ≡ proj₂ p₂) → p₁ ≡ p₂×-≡,≡←≡ : p₁ ≡ p₂ → (proj₁ p₁ ≡ proj₁ p₂ × proj₂ p₁ ≡ proj₂ p₂)```* Added new proofs to `Data.Product.Relation.Binary.Lex.Strict````agda×-respectsʳ : Transitive _≈₁_ → _<₁_ Respectsʳ _≈₁_ → _<₂_ Respectsʳ _≈₂_ → _<ₗₑₓ_ Respectsʳ _≋_×-respectsˡ : Symmetric _≈₁_ → Transitive _≈₁_ → _<₁_ Respectsˡ _≈₁_ → _<₂_ Respectsˡ _≈₂_ → _<ₗₑₓ_ Respectsˡ _≋_×-wellFounded' : Transitive _≈₁_ → _<₁_ Respectsʳ _≈₁_ → WellFounded _<₁_ → WellFounded _<₂_ → WellFounded _<ₗₑₓ_```* Added new definitions to `Data.Sign.Base`:```agda*-rawMagma : RawMagma 0ℓ 0ℓ*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawGroup : RawGroup 0ℓ 0ℓ```* Added new proofs to `Data.Sign.Properties`:```agda*-inverse : Inverse + id _*_*-isCommutativeSemigroup : IsCommutativeSemigroup _*_*-isCommutativeMonoid : IsCommutativeMonoid _*_ +*-isGroup : IsGroup _*_ + id*-isAbelianGroup : IsAbelianGroup _*_ + id*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ*-group : Group 0ℓ 0ℓ*-abelianGroup : AbelianGroup 0ℓ 0ℓ≡-isDecEquivalence : IsDecEquivalence _≡_```* Added new functions in `Data.String.Base`:```agdawordsByᵇ : (Char → Bool) → String → List StringlinesByᵇ : (Char → Bool) → String → List String```* Added new proofs in `Data.String.Properties`:```agda≤-isDecTotalOrder-≈ : IsDecTotalOrder _≈_ _≤_≤-decTotalOrder-≈ : DecTotalOrder _ _ _```* Added new definitions in `Data.Sum.Properties`:```agdaswap-↔ : (A ⊎ B) ↔ (B ⊎ A)```* Added new proofs in `Data.Sum.Properties`:```agdamap-assocˡ : map (map f g) h ∘ assocˡ ≗ assocˡ ∘ map f (map g h)map-assocʳ : map f (map g h) ∘ assocʳ ≗ assocʳ ∘ map (map f g) h```* Made `Map` public in `Data.Tree.AVL.IndexedMap`* Added new definitions in `Data.Vec.Base`:```agdatruncate : m ≤ n → Vec A n → Vec A mpad : m ≤ n → A → Vec A m → Vec A nFoldrOp A B = A → B n → B (suc n)FoldlOp A B = B n → A → B (suc n)foldr′ : (A → B → B) → B → Vec A n → Bfoldl′ : (B → A → B) → B → Vec A n → Bcountᵇ : (A → Bool) → Vec A n → ℕiterate : (A → A) → A → Vec A ndiagonal : Vec (Vec A n) n → Vec A nDiagonalBind._>>=_ : Vec A n → (A → Vec B n) → Vec B n_ʳ++_ : Vec A m → Vec A n → Vec A (m + n)cast : .(eq : m ≡ n) → Vec A m → Vec A n```* Added new instance in `Data.Vec.Effectful`:```agdamonad : RawMonad (λ (A : Set a) → Vec A n)```* Added new proofs in `Data.Vec.Properties`:```agdapadRight-refl : padRight ≤-refl a xs ≡ xspadRight-replicate : replicate a ≡ padRight le a (replicate a)padRight-trans : padRight (≤-trans m≤n n≤p) a xs ≡ padRight n≤p a (padRight m≤n a xs)truncate-refl : truncate ≤-refl xs ≡ xstruncate-trans : truncate (≤-trans m≤n n≤p) xs ≡ truncate m≤n (truncate n≤p xs)truncate-padRight : truncate m≤n (padRight m≤n a xs) ≡ xsmap-const : map (const x) xs ≡ replicate xmap-⊛ : map f xs ⊛ map g xs ≡ map (f ˢ g) xsmap-++ : map f (xs ++ ys) ≡ map f xs ++ map f ysmap-is-foldr : map f ≗ foldr (Vec B) (λ x ys → f x ∷ ys) []map-∷ʳ : map f (xs ∷ʳ x) ≡ (map f xs) ∷ʳ (f x)map-reverse : map f (reverse xs) ≡ reverse (map f xs)map-ʳ++ : map f (xs ʳ++ ys) ≡ map f xs ʳ++ map f ysmap-insert : map f (insert xs i x) ≡ insert (map f xs) i (f x)toList-map : toList (map f xs) ≡ List.map f (toList xs)lookup-concat : lookup (concat xss) (combine i j) ≡ lookup (lookup xss i) j⊛-is->>= : fs ⊛ xs ≡ fs >>= flip map xslookup-⊛* : lookup (fs ⊛* xs) (combine i j) ≡ (lookup fs i $ lookup xs j)++-is-foldr : xs ++ ys ≡ foldr ((Vec A) ∘ (_+ n)) _∷_ ys xs[]≔-++-↑ʳ : (xs ++ ys) [ m ↑ʳ i ]≔ y ≡ xs ++ (ys [ i ]≔ y)unfold-ʳ++ : xs ʳ++ ys ≡ reverse xs ++ ysfoldl-universal : (e : C zero) → ∀ {n} → Vec A n → C n) →(∀ ... → h C g e [] ≡ e) →(∀ ... → h C g e ∘ (x ∷_) ≗ h (C ∘ suc) g (g e x)) →h B f e ≗ foldl B f efoldl-fusion : h d ≡ e → (∀ ... → h (f b x) ≡ g (h b) x) → h ∘ foldl B f d ≗ foldl C g efoldl-∷ʳ : foldl B f e (ys ∷ʳ y) ≡ f (foldl B f e ys) yfoldl-[] : foldl B f e [] ≡ efoldl-reverse : foldl B {n} f e ∘ reverse ≗ foldr B (flip f) efoldr-[] : foldr B f e [] ≡ efoldr-++ : foldr B f e (xs ++ ys) ≡ foldr (B ∘ (_+ n)) f (foldr B f e ys) xsfoldr-∷ʳ : foldr B f e (ys ∷ʳ y) ≡ foldr (B ∘ suc) f (f y e) ysfoldr-ʳ++ : foldr B f e (xs ʳ++ ys) ≡ foldl (B ∘ (_+ n)) (flip f) (foldr B f e ys) xsfoldr-reverse : foldr B f e ∘ reverse ≗ foldl B (flip f) e∷ʳ-injective : xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y∷ʳ-injectiveˡ : xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys∷ʳ-injectiveʳ : xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ yunfold-∷ʳ : cast eq (xs ∷ʳ x) ≡ xs ++ [ x ]init-∷ʳ : init (xs ∷ʳ x) ≡ xslast-∷ʳ : last (xs ∷ʳ x) ≡ xcast-∷ʳ : cast eq (xs ∷ʳ x) ≡ (cast (cong pred eq) xs) ∷ʳ x++-∷ʳ : cast eq ((xs ++ ys) ∷ʳ z) ≡ xs ++ (ys ∷ʳ z)∷ʳ-++ : cast eq ((xs ∷ʳ a) ++ ys) ≡ xs ++ (a ∷ ys)reverse-∷ : reverse (x ∷ xs) ≡ reverse xs ∷ʳ xreverse-involutive : Involutive _≡_ reversereverse-reverse : reverse xs ≡ ys → reverse ys ≡ xsreverse-injective : reverse xs ≡ reverse ys → xs ≡ ystranspose-replicate : transpose (replicate xs) ≡ map replicate xstoList-replicate : toList (replicate {n = n} a) ≡ List.replicate n atoList-++ : toList (xs ++ ys) ≡ toList xs List.++ toList yscast-is-id : cast eq xs ≡ xssubst-is-cast : subst (Vec A) eq xs ≡ cast eq xscast-sym : cast eq xs ≡ ys → cast (sym eq) ys ≡ xscast-trans : cast eq₂ (cast eq₁ xs) ≡ cast (trans eq₁ eq₂) xsmap-cast : map f (cast eq xs) ≡ cast eq (map f xs)lookup-cast : lookup (cast eq xs) (Fin.cast eq i) ≡ lookup xs ilookup-cast₁ : lookup (cast eq xs) i ≡ lookup xs (Fin.cast (sym eq) i)lookup-cast₂ : lookup xs (Fin.cast eq i) ≡ lookup (cast (sym eq) xs) icast-reverse : cast eq ∘ reverse ≗ reverse ∘ cast eqcast-++ˡ : cast (cong (_+ n) eq) (xs ++ ys) ≡ cast eq xs ++ yscast-++ʳ : cast (cong (m +_) eq) (xs ++ ys) ≡ xs ++ cast eq ysiterate-id : iterate id x n ≡ replicate xtake-iterate : take n (iterate f x (n + m)) ≡ iterate f x ndrop-iterate : drop n (iterate f x n) ≡ []lookup-iterate : lookup (iterate f x n) i ≡ ℕ.iterate f x (toℕ i)toList-iterate : toList (iterate f x n) ≡ List.iterate f x nzipwith-++ : zipWith f (xs ++ ys) (xs' ++ ys') ≡ zipWith f xs xs' ++ zipWith f ys ys'++-assoc : cast eq ((xs ++ ys) ++ zs) ≡ xs ++ (ys ++ zs)++-identityʳ : cast eq (xs ++ []) ≡ xsinit-reverse : init ∘ reverse ≗ reverse ∘ taillast-reverse : last ∘ reverse ≗ headreverse-++ : cast eq (reverse (xs ++ ys)) ≡ reverse ys ++ reverse xstoList-cast : toList (cast eq xs) ≡ toList xscast-fromList : cast _ (fromList xs) ≡ fromList ysfromList-map : cast _ (fromList (List.map f xs)) ≡ map f (fromList xs)fromList-++ : cast _ (fromList (xs List.++ ys)) ≡ fromList xs ++ fromList ysfromList-reverse : cast (Listₚ.length-reverse xs) (fromList (List.reverse xs)) ≡ reverse (fromList xs)∷-ʳ++ : cast eq ((a ∷ xs) ʳ++ ys) ≡ xs ʳ++ (a ∷ ys)++-ʳ++ : cast eq ((xs ++ ys) ʳ++ zs) ≡ ys ʳ++ (xs ʳ++ zs)ʳ++-ʳ++ : cast eq ((xs ʳ++ ys) ʳ++ zs) ≡ ys ʳ++ (xs ++ zs)length-toList : List.length (toList xs) ≡ length xstoList-insertAt : toList (insertAt xs i v) ≡ List.insertAt (toList xs) (Fin.cast (cong suc (sym (length-toList xs))) i) vtruncate≡take : .(eq : n ≡ m + o) → truncate m≤n xs ≡ take m (cast eq xs)take≡truncate : take m xs ≡ truncate (m≤m+n m n) xslookup-truncate : lookup (truncate m≤n xs) i ≡ lookup xs (Fin.inject≤ i m≤n)lookup-take-inject≤ : lookup (take m xs) i ≡ lookup xs (Fin.inject≤ i (m≤m+n m n))```* Added new proofs in `Data.Vec.Membership.Propositional.Properties`:```agdaindex-∈-fromList⁺ : Any.index (∈-fromList⁺ v∈xs) ≡ indexₗ v∈xs```* Added new isomorphisms to `Data.Unit.Polymorphic.Properties`:```agda⊤↔⊤* : ⊤ ↔ ⊤*```* Added new proofs in `Data.Vec.Functional.Properties`:```map-updateAt : f ∘ g ≗ h ∘ f → map f (updateAt i g xs) ≗ updateAt i h (map f xs)```* Added new proofs in `Data.Vec.Relation.Binary.Lex.Strict`:```agdaxs≮[] : ¬ xs < []<-respectsˡ : IsPartialEquivalence _≈_ → _≺_ Respectsˡ _≈_ → _<_ Respectsˡ _≋_<-respectsʳ : IsPartialEquivalence _≈_ → _≺_ Respectsʳ _≈_ → _<_ _Respectsʳ _≋_<-wellFounded : Transitive _≈_ → _≺_ Respectsʳ _≈_ → WellFounded _≺_ → WellFounded _<_```* Added new function to `Data.Vec.Relation.Binary.Pointwise.Inductive````agdacong-[_]≔ : Pointwise _∼_ xs ys → Pointwise _∼_ (xs [ i ]≔ p) (ys [ i ]≔ p)```* Added new function to `Data.Vec.Relation.Binary.Equality.Setoid````agdamap-[]≔ : map f (xs [ i ]≔ p) ≋ map f xs [ i ]≔ f p```* Added new functions in `Data.Vec.Relation.Unary.Any`:```lookup : Any P xs → A```* Added new functions in `Data.Vec.Relation.Unary.All`:```decide : Π[ P ∪ Q ] → Π[ All P ∪ Any Q ]lookupAny : All P xs → (i : Any Q xs) → (P ∩ Q) (Any.lookup i)lookupWith : ∀[ P ⇒ Q ⇒ R ] → All P xs → (i : Any Q xs) → R (Any.lookup i)lookup : All P xs → (∀ {x} → x ∈ₚ xs → P x)lookupₛ : P Respects _≈_ → All P xs → (∀ {x} → x ∈ xs → P x)```* Added vector associativity proof to `Data.Vec.Relation.Binary.Equality.Setoid`:```++-assoc : (xs ++ ys) ++ zs ≋ xs ++ (ys ++ zs)```* Added new isomorphisms to `Data.Vec.N-ary`:```agdaVec↔N-ary : ∀ n → (Vec A n → B) ↔ N-ary n A B```* Added new isomorphisms to `Data.Vec.Recursive`:```agdalift↔ : A ↔ B → A ^ n ↔ B ^ nFin[m^n]↔Fin[m]^n : Fin (m ^ n) ↔ Fin m Vec.^ n```* Added new functions in `Effect.Monad.State`:```runState : State s a → s → a × sevalState : State s a → s → aexecState : State s a → s → s```* Added a non-dependent version of `flip` in `Function.Base`:```agdaflip′ : (A → B → C) → (B → A → C)```* Added new proofs and definitions in `Function.Bundles`:```agdaLeftInverse.isSplitSurjection : LeftInverse → IsSplitSurjection toLeftInverse.surjection : LeftInverse → SurjectionSplitSurjection = LeftInverse_⟨$⟩_ = Func.to```* Added new proofs to `Function.Properties.Inverse`:```agda↔-refl : Reflexive _↔_↔-sym : Symmetric _↔_↔-trans : Transitive _↔_↔⇒↣ : A ↔ B → A ↣ B↔-fun : A ↔ B → C ↔ D → (A → C) ↔ (B → D)Inverse⇒Injection : Inverse S T → Injection S T```* Added new proofs in `Function.Construct.Symmetry`:```bijective : Bijective ≈₁ ≈₂ f → Symmetric ≈₂ → Transitive ≈₂ → Congruent ≈₁ ≈₂ f → Bijective ≈₂ ≈₁ f⁻¹isBijection : IsBijection ≈₁ ≈₂ f → Congruent ≈₂ ≈₁ f⁻¹ → IsBijection ≈₂ ≈₁ f⁻¹isBijection-≡ : IsBijection ≈₁ _≡_ f → IsBijection _≡_ ≈₁ f⁻¹bijection : Bijection R S → Congruent IB.Eq₂._≈_ IB.Eq₁._≈_ f⁻¹ → Bijection S Rbijection-≡ : Bijection R (setoid B) → Bijection (setoid B) Rsym-⤖ : A ⤖ B → B ⤖ A```* Added new operations in `Function.Strict`:```_!|>_ : (a : A) → (∀ a → B a) → B a_!|>′_ : A → (A → B) → B```* Added new proof and record in `Function.Structures`:```agdarecord IsSplitSurjection (f : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)```* Added new definition to the `Surjection` module in `Function.Related.Surjection`:```f⁻ = proj₁ ∘ surjective```* Added new proof to `Induction.WellFounded````agdaAcc-resp-flip-≈ : _<_ Respectsʳ (flip _≈_) → (Acc _<_) Respects _≈_acc⇒asym : Acc _<_ x → x < y → ¬ (y < x)wf⇒asym : WellFounded _<_ → Asymmetric _<_wf⇒irrefl : _<_ Respects₂ _≈_ → Symmetric _≈_ → WellFounded _<_ → Irreflexive _≈_ _<_```* Added new operations in `IO`:```Colist.forM : Colist A → (A → IO B) → IO (Colist B)Colist.forM′ : Colist A → (A → IO B) → IO ⊤List.forM : List A → (A → IO B) → IO (List B)List.forM′ : List A → (A → IO B) → IO ⊤```* Added new operations in `IO.Base`:```lift! : IO A → IO (Lift b A)_<$_ : B → IO A → IO B_=<<_ : (A → IO B) → IO A → IO B_<<_ : IO B → IO A → IO Blift′ : Prim.IO ⊤ → IO {a} ⊤when : Bool → IO ⊤ → IO ⊤unless : Bool → IO ⊤ → IO ⊤whenJust : Maybe A → (A → IO ⊤) → IO ⊤untilJust : IO (Maybe A) → IO AuntilRight : (A → IO (A ⊎ B)) → A → IO B```* Added new functions in `Reflection.AST.Term`:```stripPis : Term → List (String × Arg Type) × TermprependLams : List (String × Visibility) → Term → TermprependHLams : List String → Term → TermprependVLams : List String → Term → Term```* Added new types and operations to `Reflection.TCM`:```Blocker : SetblockerMeta : Meta → BlockerblockerAny : List Blocker → BlockerblockerAll : List Blocker → BlockerblockTC : Blocker → TC A```* Added new operations in `Relation.Binary.Construct.Closure.Equivalence`:```fold : IsEquivalence _∼_ → _⟶_ ⇒ _∼_ → EqClosure _⟶_ ⇒ _∼_gfold : IsEquivalence _∼_ → _⟶_ =[ f ]⇒ _∼_ → EqClosure _⟶_ =[ f ]⇒ _∼_return : _⟶_ ⇒ EqClosure _⟶_join : EqClosure (EqClosure _⟶_) ⇒ EqClosure _⟶__⋆ : _⟶₁_ ⇒ EqClosure _⟶₂_ → EqClosure _⟶₁_ ⇒ EqClosure _⟶₂_```* Added new operations in `Relation.Binary.Construct.Closure.Symmetric`:```fold : Symmetric _∼_ → _⟶_ ⇒ _∼_ → SymClosure _⟶_ ⇒ _∼_gfold : Symmetric _∼_ → _⟶_ =[ f ]⇒ _∼_ → SymClosure _⟶_ =[ f ]⇒ _∼_return : _⟶_ ⇒ SymClosure _⟶_join : SymClosure (SymClosure _⟶_) ⇒ SymClosure _⟶__⋆ : _⟶₁_ ⇒ SymClosure _⟶₂_ → SymClosure _⟶₁_ ⇒ SymClosure _⟶₂_```* Added new proofs to `Relation.Binary.Lattice.Properties.{Join,Meet}Semilattice`:```agdaisPosemigroup : IsPosemigroup _≈_ _≤_ _∨_posemigroup : Posemigroup c ℓ₁ ℓ₂≈-dec⇒≤-dec : Decidable _≈_ → Decidable _≤_≈-dec⇒isDecPartialOrder : Decidable _≈_ → IsDecPartialOrder _≈_ _≤_```* Added new proofs to `Relation.Binary.Lattice.Properties.Bounded{Join,Meet}Semilattice`:```agdaisCommutativePomonoid : IsCommutativePomonoid _≈_ _≤_ _∨_ ⊥commutativePomonoid : CommutativePomonoid c ℓ₁ ℓ₂```* Added new proofs to `Relation.Binary.Properties.Poset`:```agda≤-dec⇒≈-dec : Decidable _≤_ → Decidable _≈_≤-dec⇒isDecPartialOrder : Decidable _≤_ → IsDecPartialOrder _≈_ _≤_```* Added new proofs in `Relation.Binary.Properties.StrictPartialOrder`:```agda>-strictPartialOrder : StrictPartialOrder s₁ s₂ s₃```* Added new proofs in `Relation.Binary.PropositionalEquality.Properties`:```subst-application′ : subst Q eq (f x p) ≡ f y (subst P eq p)sym-cong : sym (cong f p) ≡ cong f (sym p)```* Added new proofs in `Relation.Binary.HeterogeneousEquality`:```subst₂-removable : subst₂ _∼_ eq₁ eq₂ p ≅ p```* Added new definitions in `Relation.Unary`:```_≐_ : Pred A ℓ₁ → Pred A ℓ₂ → Set __≐′_ : Pred A ℓ₁ → Pred A ℓ₂ → Set __∖_ : Pred A ℓ₁ → Pred A ℓ₂ → Pred A _```* Added new proofs in `Relation.Unary.Properties`:```⊆-reflexive : _≐_ ⇒ _⊆_⊆-antisym : Antisymmetric _≐_ _⊆_⊆-min : Min _⊆_ ∅⊆-max : Max _⊆_ U⊂⇒⊆ : _⊂_ ⇒ _⊆_⊂-trans : Trans _⊂_ _⊂_ _⊂_⊂-⊆-trans : Trans _⊂_ _⊆_ _⊂_⊆-⊂-trans : Trans _⊆_ _⊂_ _⊂_⊂-respʳ-≐ : _⊂_ Respectsʳ _≐_⊂-respˡ-≐ : _⊂_ Respectsˡ _≐_⊂-resp-≐ : _⊂_ Respects₂ _≐_⊂-irrefl : Irreflexive _≐_ _⊂_⊂-antisym : Antisymmetric _≐_ _⊂_∅-⊆′ : (P : Pred A ℓ) → ∅ ⊆′ P⊆′-U : (P : Pred A ℓ) → P ⊆′ U⊆′-refl : Reflexive {A = Pred A ℓ} _⊆′_⊆′-reflexive : _≐′_ ⇒ _⊆′_⊆′-trans : Trans _⊆′_ _⊆′_ _⊆′_⊆′-antisym : Antisymmetric _≐′_ _⊆′_⊆′-min : Min _⊆′_ ∅⊆′-max : Max _⊆′_ U⊂′-trans : Trans _⊂′_ _⊂′_ _⊂′_⊂′-⊆′-trans : Trans _⊂′_ _⊆′_ _⊂′_⊆′-⊂′-trans : Trans _⊆′_ _⊂′_ _⊂′_⊂′-respʳ-≐′ : _⊂′_ Respectsʳ _≐′_⊂′-respˡ-≐′ : _⊂′_ Respectsˡ _≐′_⊂′-resp-≐′ : _⊂′_ Respects₂ _≐′_⊂′-irrefl : Irreflexive _≐′_ _⊂′_⊂′-antisym : Antisymmetric _≐′_ _⊂′_⊂′⇒⊆′ : _⊂′_ ⇒ _⊆′_⊆⇒⊆′ : _⊆_ ⇒ _⊆′_⊆′⇒⊆ : _⊆′_ ⇒ _⊆_⊂⇒⊂′ : _⊂_ ⇒ _⊂′_⊂′⇒⊂ : _⊂′_ ⇒ _⊂_≐-refl : Reflexive _≐_≐-sym : Sym _≐_ _≐_≐-trans : Trans _≐_ _≐_ _≐_≐′-refl : Reflexive _≐′_≐′-sym : Sym _≐′_ _≐′_≐′-trans : Trans _≐′_ _≐′_ _≐′_≐⇒≐′ : _≐_ ⇒ _≐′_≐′⇒≐ : _≐′_ ⇒ _≐_U-irrelevant : Irrelevant U∁-irrelevant : (P : Pred A ℓ) → Irrelevant (∁ P)```* Generalised proofs in `Relation.Unary.Properties`:```⊆-trans : Trans _⊆_ _⊆_ _⊆_```* Added new proofs in `Relation.Binary.Properties.Setoid`:```≈-isPreorder : IsPreorder _≈_ _≈_≈-isPartialOrder : IsPartialOrder _≈_ _≈_≈-preorder : Preorder a ℓ ℓ≈-poset : Poset a ℓ ℓ```* Added new definitions in `Relation.Binary.Definitions`:```RightTrans R S = Trans R S RLeftTrans S R = Trans S R RDense _<_ = x < y → ∃[ z ] x < z × z < yCotransitive _#_ = x # y → ∀ z → (x # z) ⊎ (z # y)Tight _≈_ _#_ = (¬ x # y → x ≈ y) × (x ≈ y → ¬ x # y)Monotonic₁ _≤_ _⊑_ f = f Preserves _≤_ ⟶ _⊑_Antitonic₁ _≤_ _⊑_ f = f Preserves (flip _≤_) ⟶ _⊑_Monotonic₂ _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ _≤_ ⟶ _⊑_ ⟶ _≼_MonotonicAntitonic _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ _≤_ ⟶ (flip _⊑_) ⟶ _≼_AntitonicMonotonic _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ (flip _≤_) ⟶ _⊑_ ⟶ _≼_Antitonic₂ _≤_ _⊑_ _≼_ ∙ = ∙ Preserves₂ (flip _≤_) ⟶ (flip _⊑_) ⟶ _≼_Adjoint _≤_ _⊑_ f g = (f x ⊑ y → x ≤ g y) × (x ≤ g y → f x ⊑ y)```* Added new definitions in `Relation.Binary.Bundles`:```record DenseLinearOrder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) whererecord ApartnessRelation c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂)) where```* Added new definitions in `Relation.Binary.Structures`:```record IsDenseLinearOrder (_<_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) whererecord IsApartnessRelation (_#_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂) where```* Added new proofs to `Relation.Binary.Consequences`:```sym⇒¬-sym : Symmetric _∼_ → Symmetric (¬_ ∘₂ _∼_)cotrans⇒¬-trans : Cotransitive _∼_ → Transitive (¬_ ∘₂ _∼_)irrefl⇒¬-refl : Reflexive _≈_ → Irreflexive _≈_ _∼_ → Reflexive (¬_ ∘₂ _∼_)mono₂⇒cong₂ : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ → ∀ {f} →f Preserves₂ ≤₁ ⟶ ≤₁ ⟶ ≤₂ →f Preserves₂ ≈₁ ⟶ ≈₁ ⟶ ≈₂```* Added new proofs to `Relation.Binary.Construct.Closure.Transitive`:```accessible⁻ : Acc _∼⁺_ x → Acc _∼_ xwellFounded⁻ : WellFounded _∼⁺_ → WellFounded _∼_accessible : Acc _∼_ x → Acc _∼⁺_ x```* Added new operations in `Relation.Binary.PropositionalEquality.Properties`:```J : (B : (y : A) → x ≡ y → Set b) (p : x ≡ y) → B x refl → B y pdcong : (p : x ≡ y) → subst B p (f x) ≡ f ydcong₂ : (p : x₁ ≡ x₂) → subst B p y₁ ≡ y₂ → f x₁ y₁ ≡ f x₂ y₂dsubst₂ : (p : x₁ ≡ x₂) → subst B p y₁ ≡ y₂ → C x₁ y₁ → C x₂ y₂ddcong₂ : (p : x₁ ≡ x₂) (q : subst B p y₁ ≡ y₂) → dsubst₂ C p q (f x₁ y₁) ≡ f x₂ y₂isPartialOrder : IsPartialOrder _≡_ _≡_poset : Set a → Poset _ _ _```* Added new proof in `Relation.Nullary.Reflects`:```agdaT-reflects : Reflects (T b) bT-reflects-elim : Reflects (T a) b → b ≡ a```* Added new operations in `System.Exit`:```isSuccess : ExitCode → BoolisFailure : ExitCode → Bool```NonZero/Positive/Negative changes---------------------------------This is a full list of proofs that have changed form to use irrelevant instance arguments:* In `Data.Nat.Base`:```≢-nonZero⁻¹ : ∀ {n} → .(NonZero n) → n ≢ 0>-nonZero⁻¹ : ∀ {n} → .(NonZero n) → n > 0```* In `Data.Nat.Properties`:```*-cancelʳ-≡ : ∀ m n {o} → m * suc o ≡ n * suc o → m ≡ n*-cancelˡ-≡ : ∀ {m n} o → suc o * m ≡ suc o * n → m ≡ n*-cancelʳ-≤ : ∀ m n o → m * suc o ≤ n * suc o → m ≤ n*-cancelˡ-≤ : ∀ {m n} o → suc o * m ≤ suc o * n → m ≤ n*-monoˡ-< : ∀ n → (_* suc n) Preserves _<_ ⟶ _<_*-monoʳ-< : ∀ n → (suc n *_) Preserves _<_ ⟶ _<_m≤m*n : ∀ m {n} → 0 < n → m ≤ m * nm≤n*m : ∀ m {n} → 0 < n → m ≤ n * mm<m*n : ∀ {m n} → 0 < m → 1 < n → m < m * nsuc[pred[n]]≡n : ∀ {n} → n ≢ 0 → suc (pred n) ≡ n```* In `Data.Nat.Coprimality`:```¬0-coprimeTo-2+ : ∀ {n} → ¬ Coprime 0 (2 + n)Bézout-coprime : ∀ {i j d} → Bézout.Identity (suc d) (i * suc d) (j * suc d) → Coprime i jprime⇒coprime : ∀ m → Prime m → ∀ n → 0 < n → n < m → Coprime m n```* In `Data.Nat.Divisibility````agdam%n≡0⇒n∣m : ∀ m n → m % suc n ≡ 0 → suc n ∣ mn∣m⇒m%n≡0 : ∀ m n → suc n ∣ m → m % suc n ≡ 0m%n≡0⇔n∣m : ∀ m n → m % suc n ≡ 0 ⇔ suc n ∣ m∣⇒≤ : ∀ {m n} → m ∣ suc n → m ≤ suc n>⇒∤ : ∀ {m n} → m > suc n → m ∤ suc n*-cancelˡ-∣ : ∀ {i j} k → suc k * i ∣ suc k * j → i ∣ j```* In `Data.Nat.DivMod`:```m≡m%n+[m/n]*n : ∀ m n → m ≡ m % suc n + (m / suc n) * suc nm%n≡m∸m/n*n : ∀ m n → m % suc n ≡ m ∸ (m / suc n) * suc nn%n≡0 : ∀ n → suc n % suc n ≡ 0m%n%n≡m%n : ∀ m n → m % suc n % suc n ≡ m % suc n[m+n]%n≡m%n : ∀ m n → (m + suc n) % suc n ≡ m % suc n[m+kn]%n≡m%n : ∀ m k n → (m + k * (suc n)) % suc n ≡ m % suc nm*n%n≡0 : ∀ m n → (m * suc n) % suc n ≡ 0m%n<n : ∀ m n → m % suc n < suc nm%n≤m : ∀ m n → m % suc n ≤ mm≤n⇒m%n≡m : ∀ {m n} → m ≤ n → m % suc n ≡ mm/n<m : ∀ m n {≢0} → m ≥ 1 → n ≥ 2 → (m / n) {≢0} < m```* In `Data.Nat.GCD````GCD-* : ∀ {m n d c} → GCD (m * suc c) (n * suc c) (d * suc c) → GCD m n dgcd[m,n]≤n : ∀ m n → gcd m (suc n) ≤ suc n```* In `Data.Integer.Properties`:```positive⁻¹ : ∀ {i} → Positive i → i > 0ℤnegative⁻¹ : ∀ {i} → Negative i → i < 0ℤnonPositive⁻¹ : ∀ {i} → NonPositive i → i ≤ 0ℤnonNegative⁻¹ : ∀ {i} → NonNegative i → i ≥ 0ℤnegative<positive : ∀ {i j} → Negative i → Positive j → i < jsign-◃ : ∀ s n → sign (s ◃ suc n) ≡ ssign-cong : ∀ {s₁ s₂ n₁ n₂} → s₁ ◃ suc n₁ ≡ s₂ ◃ suc n₂ → s₁ ≡ s₂-◃<+◃ : ∀ m n → Sign.- ◃ (suc m) < Sign.+ ◃ nm⊖1+n<m : ∀ m n → m ⊖ suc n < + m*-cancelʳ-≡ : ∀ i j k → k ≢ + 0 → i * k ≡ j * k → i ≡ j*-cancelˡ-≡ : ∀ i j k → i ≢ + 0 → i * j ≡ i * k → j ≡ k*-cancelʳ-≤-pos : ∀ m n o → m * + suc o ≤ n * + suc o → m ≤ n≤-steps : ∀ n → i ≤ j → i ≤ + n + j≤-steps-neg : ∀ n → i ≤ j → i - + n ≤ jn≤m+n : ∀ n → i ≤ + n + im≤m+n : ∀ n → i ≤ i + + nm-n≤m : ∀ i n → i - + n ≤ i*-cancelʳ-≤-pos : ∀ m n o → m * + suc o ≤ n * + suc o → m ≤ n*-cancelˡ-≤-pos : ∀ m j k → + suc m * j ≤ + suc m * k → j ≤ k*-cancelˡ-≤-neg : ∀ m {j k} → -[1+ m ] * j ≤ -[1+ m ] * k → j ≥ k*-cancelʳ-≤-neg : ∀ {n o} m → n * -[1+ m ] ≤ o * -[1+ m ] → n ≥ o*-cancelˡ-<-nonNeg : ∀ n → + n * i < + n * j → i < j*-cancelʳ-<-nonNeg : ∀ n → i * + n < j * + n → i < j*-monoʳ-≤-nonNeg : ∀ n → (_* + n) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg : ∀ n → (+ n *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonPos : ∀ i → NonPositive i → (i *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos : ∀ i → NonPositive i → (_* i) Preserves _≤_ ⟶ _≥_*-monoˡ-<-pos : ∀ n → (+[1+ n ] *_) Preserves _<_ ⟶ _<_*-monoʳ-<-pos : ∀ n → (_* +[1+ n ]) Preserves _<_ ⟶ _<_*-monoˡ-<-neg : ∀ n → (-[1+ n ] *_) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : ∀ n → (_* -[1+ n ]) Preserves _<_ ⟶ _>_*-cancelˡ-<-nonPos : ∀ n → NonPositive n → n * i < n * j → i > j*-cancelʳ-<-nonPos : ∀ n → NonPositive n → i * n < j * n → i > j*-distribˡ-⊓-nonNeg : ∀ m j k → + m * (j ⊓ k) ≡ (+ m * j) ⊓ (+ m * k)*-distribʳ-⊓-nonNeg : ∀ m j k → (j ⊓ k) * + m ≡ (j * + m) ⊓ (k * + m)*-distribˡ-⊓-nonPos : ∀ i → NonPositive i → ∀ j k → i * (j ⊓ k) ≡ (i * j) ⊔ (i * k)*-distribʳ-⊓-nonPos : ∀ i → NonPositive i → ∀ j k → (j ⊓ k) * i ≡ (j * i) ⊔ (k * i)*-distribˡ-⊔-nonNeg : ∀ m j k → + m * (j ⊔ k) ≡ (+ m * j) ⊔ (+ m * k)*-distribʳ-⊔-nonNeg : ∀ m j k → (j ⊔ k) * + m ≡ (j * + m) ⊔ (k * + m)*-distribˡ-⊔-nonPos : ∀ i → NonPositive i → ∀ j k → i * (j ⊔ k) ≡ (i * j) ⊓ (i * k)*-distribʳ-⊔-nonPos : ∀ i → NonPositive i → ∀ j k → (j ⊔ k) * i ≡ (j * i) ⊓ (k * i)```* In `Data.Integer.Divisibility`:```*-cancelˡ-∣ : ∀ k {i j} → k ≢ + 0 → k * i ∣ k * j → i ∣ j*-cancelʳ-∣ : ∀ k {i j} → k ≢ + 0 → i * k ∣ j * k → i ∣ j```* In `Data.Integer.Divisibility.Signed`:```*-cancelˡ-∣ : ∀ k {i j} → k ≢ + 0 → k * i ∣ k * j → i ∣ j*-cancelʳ-∣ : ∀ k {i j} → k ≢ + 0 → i * k ∣ j * k → i ∣ j```* In `Data.Rational.Unnormalised.Properties`:```agdapositive⁻¹ : ∀ {q} → .(Positive q) → q > 0ℚᵘnonNegative⁻¹ : ∀ {q} → .(NonNegative q) → q ≥ 0ℚᵘnegative⁻¹ : ∀ {q} → .(Negative q) → q < 0ℚᵘnonPositive⁻¹ : ∀ {q} → .(NonPositive q) → q ≤ 0ℚᵘpositive⇒nonNegative : ∀ {p} → Positive p → NonNegative pnegative⇒nonPositive : ∀ {p} → Negative p → NonPositive pnegative<positive : ∀ {p q} → .(Negative p) → .(Positive q) → p < qnonNeg∧nonPos⇒0 : ∀ {p} → .(NonNegative p) → .(NonPositive p) → p ≃ 0ℚᵘp≤p+q : ∀ {p q} → NonNegative q → p ≤ p + qp≤q+p : ∀ {p} → NonNegative p → ∀ {q} → q ≤ p + q*-cancelʳ-≤-pos : ∀ {r} → Positive r → ∀ {p q} → p * r ≤ q * r → p ≤ q*-cancelˡ-≤-pos : ∀ {r} → Positive r → ∀ {p q} → r * p ≤ r * q → p ≤ q*-cancelʳ-≤-neg : ∀ r → Negative r → ∀ {p q} → p * r ≤ q * r → q ≤ p*-cancelˡ-≤-neg : ∀ r → Negative r → ∀ {p q} → r * p ≤ r * q → q ≤ p*-cancelˡ-<-nonNeg : ∀ {r} → NonNegative r → ∀ {p q} → r * p < r * q → p < q*-cancelʳ-<-nonNeg : ∀ {r} → NonNegative r → ∀ {p q} → p * r < q * r → p < q*-cancelˡ-<-nonPos : ∀ r → NonPositive r → ∀ {p q} → r * p < r * q → q < p*-cancelʳ-<-nonPos : ∀ r → NonPositive r → ∀ {p q} → p * r < q * r → q < p*-monoˡ-≤-nonNeg : ∀ {r} → NonNegative r → (_* r) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonNeg : ∀ {r} → NonNegative r → (r *_) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonPos : ∀ r → NonPositive r → (_* r) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos : ∀ r → NonPositive r → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-<-pos : ∀ {r} → Positive r → (_* r) Preserves _<_ ⟶ _<_*-monoʳ-<-pos : ∀ {r} → Positive r → (r *_) Preserves _<_ ⟶ _<_*-monoˡ-<-neg : ∀ r → Negative r → (_* r) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : ∀ r → Negative r → (r *_) Preserves _<_ ⟶ _>_pos⇒1/pos : ∀ p (p>0 : Positive p) → Positive ((1/ p) {{pos⇒≢0 p p>0}})neg⇒1/neg : ∀ p (p<0 : Negative p) → Negative ((1/ p) {{neg⇒≢0 p p<0}})*-distribʳ-⊓-nonNeg : ∀ p → NonNegative p → ∀ q r → (q ⊓ r) * p ≃ (q * p) ⊓ (r * p)*-distribˡ-⊓-nonNeg : ∀ p → NonNegative p → ∀ q r → p * (q ⊓ r) ≃ (p * q) ⊓ (p * r)*-distribˡ-⊔-nonNeg : ∀ p → NonNegative p → ∀ q r → p * (q ⊔ r) ≃ (p * q) ⊔ (p * r)*-distribʳ-⊔-nonNeg : ∀ p → NonNegative p → ∀ q r → (q ⊔ r) * p ≃ (q * p) ⊔ (r * p)*-distribˡ-⊔-nonPos : ∀ p → NonPositive p → ∀ q r → p * (q ⊔ r) ≃ (p * q) ⊓ (p * r)*-distribʳ-⊔-nonPos : ∀ p → NonPositive p → ∀ q r → (q ⊔ r) * p ≃ (q * p) ⊓ (r * p)*-distribˡ-⊓-nonPos : ∀ p → NonPositive p → ∀ q r → p * (q ⊓ r) ≃ (p * q) ⊔ (p * r)*-distribʳ-⊓-nonPos : ∀ p → NonPositive p → ∀ q r → (q ⊓ r) * p ≃ (q * p) ⊔ (r * p)```* In `Data.Rational.Properties`:```positive⁻¹ : Positive p → p > 0ℚnonNegative⁻¹ : NonNegative p → p ≥ 0ℚnegative⁻¹ : Negative p → p < 0ℚnonPositive⁻¹ : NonPositive p → p ≤ 0ℚnegative<positive : Negative p → Positive q → p < qnonNeg≢neg : ∀ p q → NonNegative p → Negative q → p ≢ qpos⇒nonNeg : ∀ p → Positive p → NonNegative pneg⇒nonPos : ∀ p → Negative p → NonPositive pnonNeg∧nonZero⇒pos : ∀ p → NonNegative p → NonZero p → Positive p*-cancelʳ-≤-pos : ∀ r → Positive r → ∀ {p q} → p * r ≤ q * r → p ≤ q*-cancelˡ-≤-pos : ∀ r → Positive r → ∀ {p q} → r * p ≤ r * q → p ≤ q*-cancelʳ-≤-neg : ∀ r → Negative r → ∀ {p q} → p * r ≤ q * r → p ≥ q*-cancelˡ-≤-neg : ∀ r → Negative r → ∀ {p q} → r * p ≤ r * q → p ≥ q*-cancelˡ-<-nonNeg : ∀ r → NonNegative r → ∀ {p q} → r * p < r * q → p < q*-cancelʳ-<-nonNeg : ∀ r → NonNegative r → ∀ {p q} → p * r < q * r → p < q*-cancelˡ-<-nonPos : ∀ r → NonPositive r → ∀ {p q} → r * p < r * q → p > q*-cancelʳ-<-nonPos : ∀ r → NonPositive r → ∀ {p q} → p * r < q * r → p > q*-monoʳ-≤-nonNeg : ∀ r → NonNegative r → (_* r) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg : ∀ r → NonNegative r → (r *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonPos : ∀ r → NonPositive r → (_* r) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-nonPos : ∀ r → NonPositive r → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-<-pos : ∀ r → Positive r → (_* r) Preserves _<_ ⟶ _<_*-monoʳ-<-pos : ∀ r → Positive r → (r *_) Preserves _<_ ⟶ _<_*-monoˡ-<-neg : ∀ r → Negative r → (_* r) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : ∀ r → Negative r → (r *_) Preserves _<_ ⟶ _>_*-distribˡ-⊓-nonNeg : ∀ p → NonNegative p → ∀ q r → p * (q ⊓ r) ≡ (p * q) ⊓ (p * r)*-distribʳ-⊓-nonNeg : ∀ p → NonNegative p → ∀ q r → (q ⊓ r) * p ≡ (q * p) ⊓ (r * p)*-distribˡ-⊔-nonNeg : ∀ p → NonNegative p → ∀ q r → p * (q ⊔ r) ≡ (p * q) ⊔ (p * r)*-distribʳ-⊔-nonNeg : ∀ p → NonNegative p → ∀ q r → (q ⊔ r) * p ≡ (q * p) ⊔ (r * p)*-distribˡ-⊔-nonPos : ∀ p → NonPositive p → ∀ q r → p * (q ⊔ r) ≡ (p * q) ⊓ (p * r)*-distribʳ-⊔-nonPos : ∀ p → NonPositive p → ∀ q r → (q ⊔ r) * p ≡ (q * p) ⊓ (r * p)*-distribˡ-⊓-nonPos : ∀ p → NonPositive p → ∀ q r → p * (q ⊓ r) ≡ (p * q) ⊔ (p * r)*-distribʳ-⊓-nonPos : ∀ p → NonPositive p → ∀ q r → (q ⊓ r) * p ≡ (q * p) ⊔ (r * p)pos⇒1/pos : ∀ p (p>0 : Positive p) → Positive ((1/ p) {{pos⇒≢0 p p>0}})neg⇒1/neg : ∀ p (p<0 : Negative p) → Negative ((1/ p) {{neg⇒≢0 p p<0}})1/pos⇒pos : ∀ p .{{_ : NonZero p}} → (1/p : Positive (1/ p)) → Positive p1/neg⇒neg : ∀ p .{{_ : NonZero p}} → (1/p : Negative (1/ p)) → Negative p```
Version 1.7===========The library has been tested using Agda 2.6.2.Highlights----------* New module for making system calls during type checking, `Reflection.External`,which re-exports `Agda.Builtin.Reflection.External`.* New predicate for lists that are enumerations their type in`Data.List.Relation.Unary.Enumerates`.* New weak induction schemes in `Data.Fin.Induction` that allows one to avoidthe complicated use of `Acc`/`inject`/`raise` when proving inductive propertiesover finite sets.Bug-fixes---------* Added missing module `Function.Metric` which re-exports`Function.Metric.(Core/Definitions/Structures/Bundles)`. This module was referredto in the documentation of its children but until now was not present.* Added missing fixity declaration to `_<_` in`Relation.Binary.Construct.NonStrictToStrict`.Non-backwards compatible changes--------------------------------#### Floating-point arithmetic* The functions in `Data.Float.Base` were updated following changes upstream,in `Agda.Builtin.Float`, see <https://github.com/agda/agda/pull/4885>.* The bitwise binary relations on floating-point numbers (`_<_`, `_≈ᵇ_`, `_==_`)have been removed without replacement, as they were deeply unintuitive,e.g., `∀ x → x < -x`.#### Reflection* The representation of reflected syntax in `Reflection.Term`,`Reflection.Pattern`, `Reflection.Argument` and`Reflection.Argument.Information` has been updated to match the newrepresentation used in Agda 2.6.2. Specifically, the followingchanges were made:* The type of the `var` constructor of the `Pattern` datatype hasbeen changed from `(x : String) → Pattern` to `(x : Int) →Pattern`.* The type of the `dot` constructor of the `Pattern` datatype hasbeen changed from `Pattern` to `(t : Term) → Pattern`.* The types of the `clause` and `absurd-clause` constructors of the`Clause` datatype now take an extra argument `(tel : Telescope)`,where `Telescope = List (String × Arg Type)`.* The following constructors have been added to the `Sort` datatype:`prop : (t : Term) → Sort`, `propLit : (n : Nat) → Sort`, and`inf : (n : Nat) → Sort`.* In `Reflection.Argument.Information` the function `relevance` wasreplaced by `modality`.* The type of the `arg-info` constructor is now`(v : Visibility) (m : Modality) → ArgInfo`.* In `Reflection.Argument` (as well as `Reflection`) there is a newpattern synonym `defaultModality`, and the pattern synonyms`vArg`, `hArg` and `iArg` have been changed.* Two new modules have been added, `Reflection.Argument.Modality`and `Reflection.Argument.Quantity`. The constructors of the types`Modality` and `Quantity` are reexported from `Reflection`.#### Sized types* Sized types are no longer considered safe in Agda 2.6.2. As aresult, all modules that use `--sized-types` no longer have the`--safe` flag. For a full list of affected modules, refer to therelevant [commit](https://github.com/agda/agda-stdlib/pull/1465/files#diff-e1c0e3196e4cea6ff808f5d2906031a7657130e10181516206647b83c7014584R91-R131.)* In order to maintain the safety of `Data.Nat.Pseudorandom.LCG`, the function`stream` that relies on the newly unsafe `Codata` modules hasbeen moved to the new module `Data.Nat.Pseudorandom.LCG.Unsafe`.* In order to maintain the safety of the modules in the `Codata.Musical` directory,the functions `fromMusical` and `toMusical` defined in:```Codata.Musical.ColistCodata.Musical.ConatCodata.Musical.CofinCodata.Musical.MCodata.Musical.Stream```have been moved to a new module `Codata.Musical.Conversion` and renamed to`X.fromMusical` and `X.toMusical` for each of `Codata.Musical.X`.* In order to maintain the safety of `Data.Container(.Indexed)`, the greatest fixpointof containers, `ν`, has been moved from `Data.Container(.Indexed)` to a new module`Data.Container(.Indexed).Fixpoints.Guarded` which also re-exports the least fixpoint.#### Other* Replaced existing O(n) implementation of `Data.Nat.Binary.fromℕ` with a new O(log n)implementation. The old implementation is maintained under `Data.Nat.Binary.fromℕ'`and proven to be equivalent to the new one.* `Data.Maybe.Base` now re-exports the definition of `Maybe` given by`Agda.Builtin.Maybe`. The `Foreign.Haskell` modules and definitionscorresponding to `Maybe` have been removed. See the release notes ofAgda 2.6.2 for more information.Deprecated modules------------------Deprecated names----------------New modules-----------* New module for making system calls during type checking:```agdaReflection.External```* New modules for universes and annotations of reflected syntax:```Reflection.UniverseReflection.AnnotatedReflection.Annotated.Free```* Added new module for unary relations over sized types now that `Size`lives in it's own universe since Agda 2.6.2.```agdaRelation.Unary.Sized```* Metrics specialised to co-domains with rational numbers:```Function.Metric.RationalFunction.Metric.Rational.DefinitionsFunction.Metric.Rational.StructuresFunction.Metric.Rational.Bundles```* Lists that contain every element of a type:```Data.List.Relation.Unary.Enumerates.SetoidData.List.Relation.Unary.Enumerates.Setoid.Properties```* (Unsafe) sized W type:```Data.W.Sized```* (Unsafe) container fixpoints:```Data.Container.Fixpoints.Sized```Other minor additions---------------------* Added new relations to `Data.Fin.Base`:```agda_≥_ = ℕ._≥_ on toℕ_>_ = ℕ._>_ on toℕ```* Added new proofs to `Data.Fin.Induction`:```agda>-wellFounded : WellFounded {A = Fin n} _>_<-weakInduction : P zero → (∀ i → P (inject₁ i) → P (suc i)) → ∀ i → P i>-weakInduction : P (fromℕ n) → (∀ i → P (suc i) → P (inject₁ i)) → ∀ i → P i```* Added new proofs to `Relation.Binary.Properties.Setoid`:```agdarespʳ-flip : _≈_ Respectsʳ (flip _≈_)respˡ-flip : _≈_ Respectsˡ (flip _≈_)```* Added new function to `Data.Fin.Base`:```agdapinch : Fin n → Fin (suc n) → Fin n```* Added new proofs to `Data.Fin.Properties`:```agdapinch-surjective : Surjective _≡_ (pinch i)pinch-mono-≤ : (pinch i) Preserves _≤_ ⟶ _≤_```* Added new proofs to `Data.Nat.Binary.Properties`:```agdafromℕ≡fromℕ' : fromℕ ≗ fromℕ'toℕ-fromℕ' : toℕ ∘ fromℕ' ≗ idfromℕ'-homo-+ : fromℕ' (m ℕ.+ n) ≡ fromℕ' m + fromℕ' n```* Rewrote proofs in `Data.Nat.Binary.Properties` for new implementation of `fromℕ`:```agdatoℕ-fromℕ : toℕ ∘ fromℕ ≗ idfromℕ-homo-+ : fromℕ (m ℕ.+ n) ≡ fromℕ m + fromℕ n```* Added new proof to `Data.Nat.DivMod`:```agdam/n≤m : (m / n) {≢0} ≤ m```* Added new type in `Size`:```agdaSizedSet ℓ = Size → Set ℓ```
Version 1.7.3=============The library has been tested using Agda 2.6.3 & 2.6.4.* To avoid _large indices_ that are by default no longer allowed in Agda 2.6.4,universe levels have been increased in the following definitions:- `Data.Star.Decoration.DecoratedWith`- `Data.Star.Pointer.Pointer`- `Reflection.AnnotatedAST.Typeₐ`- `Reflection.AnnotatedAST.AnnotationFun`* The following aliases have been added:- `IO.Primitive.pure` as alias for `IO.Primitive.return`- modules `Effect.*` as aliases for modules `Category.*`These allow to address said objects with the new name they will have in v2.0 of the library,to ease the transition from v1.7.3 to v2.0.
Version 1.7.2=============The library has been tested using Agda 2.6.3.* In accordance with changes to the flags in Agda 2.6.3, all modules that previously usedthe `--without-K` flag now use the `--cubical-compatible` flag instead.* Updated the code using `primFloatToWord64` - the library API has remained unchanged.
Version 1.7.1=============The library has been tested using Agda 2.6.2.* The only change over v1.7 is that the library's Cabal file is now compatible with GHC 9.2.
Version 1.6===========The library has been tested using Agda 2.6.1 and 2.6.1.3.Highlights----------* Reorganised module hierarchy in the dependency graph ofthe `IO` module so that a program as simple as "Hello world" may becompiled without pulling upwards of 130 modules.* First verified implementation of a sorting algorithm (available from `Data.List.Sort`).* Pseudo random generators for ℕ (available from `Data.Nat.Pseudorandom.LCG`)* Drastic increase in performance of normalised rational numbers.* Large number of additional proofs about both normalised and unnormalised rational numbers.Bug-fixes---------* The sum operator `_⊎_` in `Data.Container.Indexed.Combinator` was not as universepolymorphic as it should have been. This has been fixed. The old, less universepolymorphic variant is still available under the new name `_⊎′_`.* The performance of the `gcd` operator over naturals and hence all operations in`Data.Rational.Base` has been drastically increased by using the new `<-wellFounded-fast`operation in `Data.Nat.Induction`.* The proof `isEquivalence` in `Function.Properties.(Equivalence/Inverse)` used to bedefined in an anonymous module that took two unneccessary `Setoid` arguments:```agdamodule _ (R : Setoid a ℓ₁) (S : Setoid b ℓ₂) whereisEquivalence : IsEquivalence (Equivalence {a} {b})```Their definitions have now been moved out of the anonymous modules so that they nolonger require these unnecessary arguments.* Despite being designed for use with non-reflexive relations, the combinatorsin `Relation.Binary.Reasoning.Base.Partial` required users to provide a proofof reflexivity of the relation over the last element in the chain:```agdabeginx ⟨ x∼y ⟩y ∎⟨ y∼y ⟩```The combinators have been redefined so that this proof is no longer needed:```agdabeginx ⟨ x∼y ⟩y ∎```This is a backwards compatible change when using the`Relation.Binary.Reasoning.PartialSetoid` API directly as the old `_∎⟨_⟩`combinator has simply been deprecated. For users who were building theirown reasoning combinators on top of `Relation.Binary.Reasoning.Base.Partial`,they will need to adjust their additional combinators to use the new`singleStep`/`multiStep` constructors of `_IsRelatedTo_`.* In `Relation.Binary.Reasoning.StrictPartialOrder` filled a missing argument to there-exported `Relation.Binary.Reasoning.Base.Triple`.Non-backwards compatible changes--------------------------------* `Data.String.Base` has been thinned to minimise its dependencies. The morecomplex functions (`parensIfSpace`, `wordsBy`, `words`, `linesBy`, `lines`,`rectangle`, `rectangleˡ`, `rectangleʳ`, `rectangleᶜ`) have been moved to`Data.String`.* In `Data.Tree.AVL.Indexed` the type alias `K&_` defined in terms of `Σ` has been changedinto a standalone record to help with parameter inference. The record constructor remainsthe same so you will only observe the change if you are using functions explicitly expectinga pair (e.g. `(un)curry`). In this case you can use `Data.Tree.AVL.Value`'s `(to/from)Pair`to convert back and forth.* The new modules `Relation.Binary.Morphism.(Constant/Identity/Composition)` thatwere added in the last release no longer have module-level arguments. This is in orderto allow proofs about newly added morphism bundles to be added to these files. This isonly a breaking change if you were supplying the module arguments upon import, in whichcase you will have to change to supplying them upon application of the proofs.Deprecated modules------------------* The module `Text.Tree.Linear` has been deprecated, and its contentshas been moved to `Data.Tree.Rose.Show`.Deprecated names----------------* In `Data.Nat.Properties`:```agdam≤n⇒n⊔m≡n ↦ m≥n⇒m⊔n≡mm≤n⇒n⊓m≡m ↦ m≥n⇒m⊓n≡nn⊔m≡m⇒n≤m ↦ m⊔n≡n⇒m≤nn⊔m≡n⇒m≤n ↦ m⊔n≡m⇒n≤mn≤m⊔n ↦ m≤n⊔m⊔-least ↦ ⊔-lub⊓-greatest ↦ ⊓-glb⊔-pres-≤m ↦ ⊔-lub⊓-pres-m≤ ↦ ⊓-glb⊔-abs-⊓ ↦ ⊔-absorbs-⊓⊓-abs-⊔ ↦ ⊓-absorbs-⊔∣m+n-m+o∣≡∣n-o| ↦ ∣m+n-m+o∣≡∣n-o∣ -- note final character is a \| rather than a |```* In `Data.Integer.Properties`:```agdam≤n⇒m⊓n≡m ↦ i≤j⇒i⊓j≡im⊓n≡m⇒m≤n ↦ i⊓j≡i⇒i≤jm≥n⇒m⊓n≡n ↦ i≥j⇒i⊓j≡jm⊓n≡n⇒m≥n ↦ i⊓j≡j⇒j≤im⊓n≤n ↦ i⊓j≤jm⊓n≤m ↦ i⊓j≤im≤n⇒m⊔n≡n ↦ i≤j⇒i⊔j≡jm⊔n≡n⇒m≤n ↦ i⊔j≡j⇒i≤jm≥n⇒m⊔n≡m ↦ i≥j⇒i⊔j≡im⊔n≡m⇒m≥n ↦ i⊔j≡i⇒j≤im≤m⊔n ↦ i≤i⊔jn≤m⊔n ↦ i≤j⊔i```* In `Relation.Binary.Consequences`:```agdasubst⟶respˡ ↦ subst⇒respˡsubst⟶respʳ ↦ subst⇒respʳsubst⟶resp₂ ↦ subst⇒resp₂P-resp⟶¬P-resp ↦ resp⇒¬-resptotal⟶refl ↦ total⇒refltotal+dec⟶dec ↦ total∧dec⇒dectrans∧irr⟶asym ↦ trans∧irr⇒asymirr∧antisym⟶asym ↦ irr∧antisym⇒asymasym⟶antisym ↦ asym⇒antisymasym⟶irr ↦ asym⇒irrtri⟶asym ↦ tri⇒asymtri⟶irr ↦ tri⇒irrtri⟶dec≈ ↦ tri⇒dec≈tri⟶dec< ↦ tri⇒dec<trans∧tri⟶respʳ≈ ↦ trans∧tri⇒respʳtrans∧tri⟶respˡ≈ ↦ trans∧tri⇒respˡtrans∧tri⟶resp≈ ↦ trans∧tri⇒respdec⟶weaklyDec ↦ dec⇒weaklyDecdec⟶recomputable ↦ dec⇒recomputable```* In `Data.Rational.Properties`:```agdaneg-mono-<-> ↦ neg-mono-<neg-mono-≤-≥ ↦ neg-mono-≤```New modules-----------* Properties of cancellative commutative semirings:```Algebra.Properties.CancellativeCommutativeSemiring```* Specifications for min and max operators:```Algebra.Construct.NaturalChoice.MinOpAlgebra.Construct.NaturalChoice.MaxOpAlgebra.Construct.NaturalChoice.MinMaxOp```* Lexicographic product over algebraic structures:```Algebra.Construct.LexProductAlgebra.Construct.LexProduct.BaseAlgebra.Construct.LexProduct.Inner```* Properties of sums over semirings:```Algebra.Properties.Semiring.Sum```* Broke up `Codata.Musical.Colist` into a multitude of modulesin order to simply module dependency graph:```Codata.Musical.Colist.BaseCodata.Musical.Colist.PropertiesCodata.Musical.Colist.BisimilarityCodata.Musical.Colist.Relation.Unary.AllCodata.Musical.Colist.Relation.Unary.All.PropertiesCodata.Musical.Colist.Relation.Unary.AnyCodata.Musical.Colist.Relation.Unary.Any.Properties```* Broke up `Data.List.Relation.Binary.Pointwise` into several modulesin order to simply module dependency graph:```Data.List.Relation.Binary.Pointwise.BaseData.List.Relation.Binary.Pointwise.Properties```* Sorting algorithms over lists:```Data.List.SortData.List.Sort.BaseData.List.Sort.MergeSort```* A variant of the `Pointwise` relation over `Maybe` where `nothing` is alsorelated to `just`:```Data.Maybe.Relation.Binary.Connected```* Linear congruential pseudo random generators for ℕ:```Data.Nat.PseudoRandom.LCG```/!\ NB: LCGs must not be used for cryptographic applications/!\ NB: the example parameters provided are not claimed to be good* Heterogeneous `All` predicate for disjoint sums:```Data.Sum.Relation.Unary.All```* Functions for printing trees:```Data.Tree.Rose.ShowData.Tree.Binary.Show```* Basic unary predicates for AVL trees:```Data.Tree.AVL.Indexed.Relation.Unary.AllData.Tree.AVL.Indexed.Relation.Unary.AnyData.Tree.AVL.Indexed.Relation.Unary.Any.PropertiesData.Tree.AVL.Relation.Unary.AnyData.Tree.AVL.Map.Relation.Unary.Any```* Wrapping n-ary relations into a record definition so type-inferenceremembers the things being related:```Data.Wrap```(see `README.Data.Wrap` for an explanation)* Broke up `IO` into a many smaller modules:```IO.BaseIO.FiniteIO.Infinite```* Instantiate a homogeneously indexed bundle at a particular index:```Relation.Binary.Indexed.Homogeneous.Construct.At```* Bundles for binary relation morphisms:```Relation.Binary.Morphism.Bundles```Other minor additions---------------------* Added new proofs to `Algebra.Consequences.Setoid`:```agdacomm+almostCancelˡ⇒almostCancelʳ : AlmostLeftCancellative e _•_ → AlmostRightCancellative e _•_comm+almostCancelʳ⇒almostCancelˡ : AlmostRightCancellative e _•_ → AlmostLeftCancellative e _•_```* Added new proofs in `Algebra.Morphism.GroupMonomorphism`:```agda⁻¹-distrib-∙ : ((x ◦ y) ⁻¹₂ ≈₂ (x ⁻¹₂) ◦ (y ⁻¹₂)) → ((x ∙ y) ⁻¹₁ ≈₁ (x ⁻¹₁) ∙ (y ⁻¹₁))```* Added new proofs in `Algebra.Morphism.RingMonomorphism`:```agdaneg-distribˡ-* : ((⊝ (x ⊛ y)) ≈₂ ((⊝ x) ⊛ y)) → ((- (x * y)) ≈₁ ((- x) * y))neg-distribʳ-* : ((⊝ (x ⊛ y)) ≈₂ (x ⊛ (⊝ y))) → ((- (x * y)) ≈₁ (x * (- y)))```* Added new proofs in `Algebra.Properties.Magma.Divisibility`:```agda∣∣-sym : Symmetric _∣∣_∣∣-respʳ-≈ : _∣∣_ Respectsʳ _≈_∣∣-respˡ-≈ : _∣∣_ Respectsˡ _≈_∣∣-resp-≈ : _∣∣_ Respects₂ _≈_```* Added new proofs in `Algebra.Properties.Semigroup.Divisibility`:```agda∣∣-trans : Transitive _∣∣_```* Added new proofs in `Algebra.Properties.CommutativeSemigroup.Divisibility`:```agdax∣y∧z∣x/y⇒xz∣y : ((x/y , _) : x ∣ y) → z ∣ x/y → x ∙ z ∣ yx∣y⇒zx∣zy : x ∣ y → z ∙ x ∣ z ∙ y```* Added new proofs in `Algebra.Properties.Monoid.Divisibility`:```agda∣∣-refl : Reflexive _∣∣_∣∣-reflexive : _≈_ ⇒ _∣∣_∣∣-isEquivalence : IsEquivalence _∣∣_```* Added new proofs in `Algebra.Properties.CancellativeCommutativeSemiring`:```agdaxy≈0⇒x≈0∨y≈0 : Decidable _≈_ → x * y ≈ 0# → x ≈ 0# ⊎ y ≈ 0#x≉0∧y≉0⇒xy≉0 : Decidable _≈_ → x ≉ 0# → y ≉ 0# → x * y ≉ 0#xy∣x⇒y∣1 : x ≉ 0# → x * y ∣ x → y ∣ 1#```* Added new functions to `Codata.Stream`:```agdanats : Stream ℕ ∞interleave⁺ : List⁺ (Stream A i) → Stream A icantor : Stream (Stream A ∞) ∞ → Stream A ∞plane : Stream A ∞ → ((a : A) → Stream (B a) ∞) → Stream (Σ A B) ∞```* Added new function in `Data.Char.Base`:```agda_≈ᵇ_ : (c d : Char) → Bool```* Added new operations to `Data.Fin.Base`:```agdaremQuot : remQuot : ∀ k → Fin (n * k) → Fin n × Fin kcombine : Fin n → Fin k → Fin (n * k)```* Added new proofs to `Data.Fin.Properties`:```agdaremQuot-combine : ∀ x y → remQuot k (combine x y) ≡ (x , y)combine-remQuot : ∀ k i → uncurry combine (remQuot k i) ≡ i*↔× : Fin (m * n) ↔ (Fin m × Fin n)```* Added new operations to `Data.Fin.Subset`:```agda_─_ : Op₂ (Subset n)_-_ : Subset n → Fin n → Subset n```* Added new proofs to `Data.Fin.Subset.Properties`:```agdas⊂s : p ⊂ q → s ∷ p ⊂ s ∷ q∣p∣≤∣x∷p∣ : ∣ p ∣ ≤ ∣ x ∷ p ∣p─⊥≡p : p ─ ⊥ ≡ pp─⊤≡⊥ : p ─ ⊤ ≡ ⊥p─q─r≡p─q∪r : p ─ q ─ r ≡ p ─ (q ∪ r)p─q─r≡p─r─q : p ─ q ─ r ≡ p ─ r ─ qp─q─q≡p─q : p ─ q ─ q ≡ p ─ qp─q⊆p : p ─ q ⊆ p∣p─q∣≤∣p∣ : ∣ p ─ q ∣ ≤ ∣ p ∣p∩q≢∅⇒p─q⊂p : Nonempty (p ∩ q) → p ─ q ⊂ pp∩q≢∅⇒∣p─q∣<∣p∣ : Nonempty (p ∩ q) → ∣ p ─ q ∣ < ∣ p ∣x∈p∧x∉q⇒x∈p─q : x ∈ p → x ∉ q → x ∈ p ─ qp─x─y≡p─y─x : p - x - y ≡ p - y - xx∈p⇒p-x⊂p : x ∈ p → p - x ⊂ px∈p⇒∣p-x∣<∣p∣ : x ∈ p → ∣ p - x ∣ < ∣ p ∣x∈p∧x≢y⇒x∈p-y : x ∈ p → x ≢ y → x ∈ p - y```* Added new relation to `Data.Integer.Base`:```agda_≤ᵇ_ : ℤ → ℤ → Bool```* Added new proofs to `Data.Integer.Properties`:```agda≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤ᵇ⇒≤ : T (i ≤ᵇ j) → i ≤ j≤⇒≤ᵇ : i ≤ j → T (i ≤ᵇ j)m*n≡0⇒m≡0∨n≡0 : m * n ≡ 0ℤ → m ≡ 0ℤ ⊎ n ≡ 0ℤ⊓-distribˡ-⊔ : _⊓_ DistributesOverˡ _⊔_⊓-distribʳ-⊔ : _⊓_ DistributesOverʳ _⊔_⊓-distrib-⊔ : _⊓_ DistributesOver _⊔_⊔-distribˡ-⊓ : _⊔_ DistributesOverˡ _⊓_⊔-distribʳ-⊓ : _⊔_ DistributesOverʳ _⊓_⊔-distrib-⊓ : _⊔_ DistributesOver _⊓_⊔-⊓-isDistributiveLattice : IsDistributiveLattice _⊔_ _⊓_⊓-⊔-isDistributiveLattice : IsDistributiveLattice _⊓_ _⊔_⊔-⊓-distributiveLattice : DistributiveLattice _ _⊓-⊔-distributiveLattice : DistributiveLattice _ _⊓-glb : m ≥ o → n ≥ o → m ⊓ n ≥ o⊓-triangulate : m ⊓ n ⊓ o ≡ (m ⊓ n) ⊓ (n ⊓ o)⊓-mono-≤ : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊓-monoˡ-≤ : (_⊓ n) Preserves _≤_ ⟶ _≤_⊓-monoʳ-≤ : (n ⊓_) Preserves _≤_ ⟶ _≤_⊔-lub : m ≤ o → n ≤ o → m ⊔ n ≤ o⊔-triangulate : m ⊔ n ⊔ o ≡ (m ⊔ n) ⊔ (n ⊔ o)⊔-mono-≤ : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊔-monoˡ-≤ : (_⊔ n) Preserves _≤_ ⟶ _≤_⊔-monoʳ-≤ : (n ⊔_) Preserves _≤_ ⟶ _≤_i≤j⇒i⊓k≤j : i ≤ j → i ⊓ k ≤ ji≤j⇒k⊓i≤j : i ≤ j → k ⊓ i ≤ ji≤j⊓k⇒i≤j : i ≤ j ⊓ k → i ≤ ji≤j⊓k⇒i≤k : i ≤ j ⊓ k → i ≤ ki≤j⇒i≤j⊔k : i ≤ j → i ≤ j ⊔ ki≤j⇒i≤k⊔j : i ≤ j → i ≤ k ⊔ ji⊔j≤k⇒i≤k : i ⊔ j ≤ k → i ≤ ki⊔j≤k⇒j≤k : i ⊔ j ≤ k → j ≤ ki⊓j≤i⊔j : i ⊓ j ≤ i ⊔ j+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ```* Added new functions in `Data.List.Base`:```agdalast : List A → Maybe Amerge : Decidable R → List A → List A → List A```* Added new proof in `Data.List.Properties`:```agdalength-partition : (let (ys , zs) = partition P? xs) → length ys ≤ length xs × length zs ≤ length xs```* Added new proofs in `Data.List.Relation.Unary.All.Properties`:```agdahead⁺ : All P xs → Maybe.All P (head xs)tail⁺ : All P xs → Maybe.All (All P) (tail xs)last⁺ : All P xs → Maybe.All P (last xs)uncons⁺ : All P xs → Maybe.All (P ⟨×⟩ All P) (uncons xs)uncons⁻ : Maybe.All (P ⟨×⟩ All P) (uncons xs) → All P xsunsnoc⁺ : All P xs → Maybe.All (All P ⟨×⟩ P) (unsnoc xs)unsnoc⁻ : Maybe.All (All P ⟨×⟩ P) (unsnoc xs) → All P xsdropWhile⁺ : (Q? : Decidable Q) → All P xs → All P (dropWhile Q? xs)dropWhile⁻ : (P? : Decidable P) → dropWhile P? xs ≡ [] → All P xstakeWhile⁺ : (Q? : Decidable Q) → All P xs → All P (takeWhile Q? xs)takeWhile⁻ : (P? : Decidable P) → takeWhile P? xs ≡ xs → All P xsall-head-dropWhile : (P? : Decidable P) → ∀ xs → Maybe.All (∁ P) (head (dropWhile P? xs))all-takeWhile : (P? : Decidable P) → ∀ xs → All P (takeWhile P? xs)all-upTo : All (_< n) (upTo n)```* Added new proof in `Data.List.Relation.Unary.First.Properties`:```agdacofirst? : Decidable P → Decidable (First (∁ P) P)```* Added new operations in `Data.List.Relation.Unary.Linked`:```agdahead′ : Linked R (x ∷ xs) → Connected R (just x) (head xs)_∷′_ : Connected R (just x) (head xs) → Linked R xs → Linked R (x ∷ xs)```* Generalised the type of operation `tail` in `Data.List.Relation.Unary.Linked`from `Linked R (x ∷ y ∷ xs) → Linked R (y ∷ xs)` to `Linked R (x ∷ xs) → Linked R xs`.* Added new proof in `Data.List.Relation.Unary.Linked.Properties`:```agda++⁺ : Linked R xs → Connected R (last xs) (head ys) → Linked R ys → Linked R (xs ++ ys)```* Added new proof in `Data.List.Relation.Unary.Sorted.TotalOrder.Properties`:```agda++⁺ : Sorted O xs → Connected _≤_ (last xs) (head ys) → Sorted O ys → Sorted O (xs ++ ys)merge⁺ : Sorted O xs → Sorted O ys → Sorted O (merge _≤?_ xs ys)```* Added new proof to `Data.List.Relation.Binary.Equality.Setoid`:```agdafoldr⁺ : (w ≈ x → y ≈ z → (w • y) ≈ (x ◦ z)) →e ≈ f → xs ≋ ys → foldr _•_ e xs ≈ foldr _◦_ f ys```* Added new proof in `Data.List.Relation.Binary.Permutation.Setoid.Properties`:```agda↭-shift : xs ++ [ v ] ++ ys ↭ v ∷ xs ++ ys↭-merge : merge R? xs ys ↭ xs ++ ys↭-partition : (let ys , zs = partition P? xs) → xs ↭ ys ++ zs```* Added new proofs to `Data.List.Relation.Binary.Pointwise.Properties`:```agdafoldr⁺ : (R w x → R y z → R (w • y) (x ◦ z)) →R e f → Pointwise R xs ys → R (foldr _•_ e xs) (foldr _◦_ f ys)lookup⁻ : length xs ≡ length ys →(toℕ i ≡ toℕ j → R (lookup xs i) (lookup ys j)) →Pointwise R xs yslookup⁺ : (Rxys : Pointwise R xs ys) →∀ i → (let j = cast (Pointwise-length Rxys) i) →R (lookup xs i) (lookup ys j)```* Added new proof to `Data.List.Relation.Binary.Subset.(Setoid/Propositional).Properties`:```agdaxs⊆x∷xs : xs ⊆ x ∷ xs∷⁺ʳ : xs ⊆ ys → x ∷ xs ⊆ x ∷ ys∈-∷⁺ʳ : x ∈ ys → xs ⊆ ys → x ∷ xs ⊆ ysapplyUpTo⁺ : m ≤ n → applyUpTo f m ⊆ applyUpTo f n```* Added new proofs in `Data.Maybe.Relation.Unary.All.Properties`:```agdaAll⇒Connectedˡ : All (R x) y → Connected R (just x) yAll⇒Connectedʳ : All (λ v → R v y) x → Connected R x (just y```* Added new definition in `Data.Nat.Base`:```agda_≤ᵇ_ : (m n : ℕ) → Bool```* Added new proofs to `Data.Nat.DivMod`:```agdam<n⇒m/n≡0 : m < n → m / n ≡ 0m/n≡1+[m∸n]/n : m ≥ n → m / n ≡ 1 + (m ∸ n) / nm*n/m*o≡n/o : (m * n) / (m * o) ≡ n / o/-cancelʳ-≡ : o ∣ m → o ∣ n → m / o ≡ n / o → m ≡ n/-*-interchange : o ∣ m → p ∣ n → (m * n) / (o * p) ≡ m / o * n / p```* Added new proofs to `Data.Nat.Divisibility`:```agda*-pres-∣ : o ∣ m → p ∣ n → o * p ∣ m * n```* Added new proofs to `Data.Nat.GCD`:```agdam/gcd[m,n]≢0 : {m≢0 : Dec.False (m ≟ 0)} → m / gcd m n ≢ 0```* Added new proof to `Data.Nat.Induction`:```agda<-wellFounded-fast : WellFounded _<_```* Added new proofs to `Data.Nat.Properties`:```agda>⇒≢ : _>_ ⇒ _≢_pred[n]≤n : pred n ≤ nn<1⇒n≡0 : n < 1 → n ≡ 0m<n⇒0<n : m < n → 0 < nm≤n*m : 0 < n → m ≤ n * m≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ⊔-⊓-absorptive : Absorptive _⊓_ _⊔-⊓-isLattice : IsLattice _⊔_ _⊓_⊔-⊓-isDistributiveLattice : IsDistributiveLattice _⊔_ _⊓_⊓-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ⊔-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ⊔-0-monoid : Monoid 0ℓ 0ℓ⊔-⊓-lattice : Lattice 0ℓ 0ℓ⊔-⊓-distributiveLattice : DistributiveLattice 0ℓ 0ℓmono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≤_ → f (x ⊔ y) ≈ f x ⊔ f ymono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≤_ → f (x ⊓ y) ≈ f x ⊓ f yantimono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≥_ → f (x ⊓ y) ≈ f x ⊔ f yantimono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≥_ → f (x ⊔ y) ≈ f x ⊓ f y[m*n]*[o*p]≡[m*o]*[n*p] : (m * n) * (o * p) ≡ (m * o) * (n * p)```* Add new functions to `Data.Rational.Base`:```agda_≤ᵇ_ : ℚ → ℚ → Bool_⊔_ : (p q : ℚ) → ℚ_⊓_ : (p q : ℚ) → ℚ∣_∣ : ℚ → ℚ```* Add new proofs to `Data.Rational.Properties`:```agdamkℚ-cong : n₁ ≡ n₂ → d₁ ≡ d₂ → mkℚ n₁ d₁ c₁ ≡ mkℚ n₂ d₂ c₂mkℚ+-injective : mkℚ+ n₁ d₁ c₁ ≡ mkℚ+ n₂ d₂ c₂ → n₁ ≡ n₂ × d₁ ≡ d₂mkℚ+-nonNeg : NonNegative (mkℚ+ n d c)mkℚ+-pos : NonZero n → Positive (mkℚ+ n d c)nonNeg≢neg : NonNegative p → Negative q → p ≢ qpos⇒nonNeg : Positive p → NonNegative pneg⇒nonPos : Negative p → NonPositive pnonNeg∧nonZero⇒pos : NonNegative p → NonZero p → Positive pneg-injective : - p ≡ - q → p ≡ qneg-antimono-< : -_ Preserves _<_ ⟶ _>_neg-antimono-≤ : -_ Preserves _≤_ ⟶ _≥_neg-pos : Positive p → Negative (- p)normalize-cong : m₁ ≡ m₂ → n₁ ≡ n₂ → normalize m₁ n₁ ≡ normalize m₂ n₂normalize-nonNeg : NonNegative (normalize m n)normalize-pos : NonZero m → Positive (normalize m n)normalize-injective-≃ : normalize m c ≡ normalize n d → m ℕ.* d ≡ n ℕ.* c/-injective-≃ : ↥ᵘ p / ↧ₙᵘ p ≡ ↥ᵘ q / ↧ₙᵘ q → p ≃ᵘ qfromℚᵘ-injective : Injective _≃ᵘ_ _≡_ fromℚᵘtoℚᵘ-fromℚᵘ : toℚᵘ (fromℚᵘ p) ≃ᵘ pfromℚᵘ-cong : fromℚᵘ Preserves _≃ᵘ_ ⟶ _≡_≤-isTotalPreorder : IsTotalPreorder _≡_ _≤_≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓtoℚᵘ-mono-< : p < q → toℚᵘ p <ᵘ toℚᵘ qtoℚᵘ-cancel-< : toℚᵘ p <ᵘ toℚᵘ q → p < qtoℚᵘ-isOrderHomomorphism-< : IsOrderHomomorphism _≡_ _≃ᵘ_ _<_ _<ᵘ_ toℚᵘtoℚᵘ-isOrderMonomorphism-< : IsOrderMonomorphism _≡_ _≃ᵘ_ _<_ _<ᵘ_ toℚᵘ≤ᵇ⇒≤ : T (p ≤ᵇ q) → p ≤ q≤⇒≤ᵇ : p ≤ q → T (p ≤ᵇ q)+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-monoˡ-≤ : (_+ r) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ : (_+_ r) Preserves _≤_ ⟶ _≤_+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-monoˡ-< : (_+ r) Preserves _<_ ⟶ _<_+-monoʳ-< : (_+_ r) Preserves _<_ ⟶ _<_neg-distrib-+ : - (p + q) ≡ (- p) + (- q)*-inverseʳ : p * (1/ p) ≡ 1ℚ*-inverseˡ : (1/ p) * p ≡ 1ℚ*-monoʳ-≤-pos : Positive r → (_* r) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-pos : Positive r → (r *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-neg : Negative r → (_* r) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg : Negative r → (r *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonNeg : NonNegative r → (_* r) Preserves _≤_ ⟶ _≤_*-monoˡ-≤-nonNeg : NonNegative r → (r *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-nonPos : NonPositive r → (_* r) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-nonPos : NonPositive r → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-<-pos : Positive r → (_* r) Preserves _<_ ⟶ _<_*-monoʳ-<-pos : Positive r → (r *_) Preserves _<_ ⟶ _<_*-monoˡ-<-neg : Negative r → (_* r) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : Negative r → (r *_) Preserves _<_ ⟶ _>_*-cancelʳ-≤-pos : Positive r → p * r ≤ q * r → p ≤ q*-cancelˡ-≤-pos : Positive r → r * p ≤ r * q → p ≤ q*-cancelʳ-≤-neg : Negative r → p * r ≤ q * r → p ≥ q*-cancelˡ-≤-neg : Negative r → r * p ≤ r * q → p ≥ q*-cancelˡ-<-pos : Positive r → r * p < r * q → p < q*-cancelʳ-<-pos : Positive r → p * r < q * r → p < q*-cancelˡ-<-neg : Negative r → r * p < r * q → p > q*-cancelʳ-<-neg : Negative r → p * r < q * r → p > q*-cancelˡ-<-nonPos : NonPositive r → r * p < r * q → p > q*-cancelʳ-<-nonPos : NonPositive r → p * r < q * r → p > q*-cancelˡ-<-nonNeg : NonNegative r → r * p < r * q → p < q*-cancelʳ-<-nonNeg : NonNegative r → p * r < q * r → p < qneg-distribˡ-* : - (p * q) ≡ - p * qneg-distribʳ-* : - (p * q) ≡ p * - qp≤q⇒p⊔q≡q : p ≤ q → p ⊔ q ≡ qp≥q⇒p⊔q≡p : p ≥ q → p ⊔ q ≡ pp≤q⇒p⊓q≡p : p ≤ q → p ⊓ q ≡ pp≥q⇒p⊓q≡q : p ≥ q → p ⊓ q ≡ q⊓-idem : Idempotent _⊓_⊓-sel : Selective _⊓_⊓-assoc : Associative _⊓_⊓-comm : Commutative _⊓_⊔-idem : Idempotent _⊔_⊔-sel : Selective _⊔_⊔-assoc : Associative _⊔_⊔-comm : Commutative _⊔_⊓-distribˡ-⊔ : _⊓_ DistributesOverˡ _⊔_⊓-distribʳ-⊔ : _⊓_ DistributesOverʳ _⊔_⊓-distrib-⊔ : _⊓_ DistributesOver _⊔_⊔-distribˡ-⊓ : _⊔_ DistributesOverˡ _⊓_⊔-distribʳ-⊓ : _⊔_ DistributesOverʳ _⊓_⊔-distrib-⊓ : _⊔_ DistributesOver _⊓_⊓-absorbs-⊔ : _⊓_ Absorbs _⊔_⊔-absorbs-⊓ : _⊔_ Absorbs _⊓_⊔-⊓-absorptive : Absorptive _⊔_ _⊓_⊓-⊔-absorptive : Absorptive _⊓_ _⊔_⊓-isMagma : IsMagma _⊓_⊓-isSemigroup : IsSemigroup _⊓_⊓-isCommutativeSemigroup : IsCommutativeSemigroup _⊓_⊓-isBand : IsBand _⊓_⊓-isSemilattice : IsSemilattice _⊓_⊓-isSelectiveMagma : IsSelectiveMagma _⊓_⊔-isMagma : IsMagma _⊔_⊔-isSemigroup : IsSemigroup _⊔_⊔-isCommutativeSemigroup : IsCommutativeSemigroup _⊔_⊔-isBand : IsBand _⊔_⊔-isSemilattice : IsSemilattice _⊔_⊔-isSelectiveMagma : IsSelectiveMagma _⊔_⊔-⊓-isLattice : IsLattice _⊔_ _⊓_⊓-⊔-isLattice : IsLattice _⊓_ _⊔_⊔-⊓-isDistributiveLattice : IsDistributiveLattice _⊔_ _⊓_⊓-⊔-isDistributiveLattice : IsDistributiveLattice _⊓_ _⊔_⊓-magma : Magma _ _⊓-semigroup : Semigroup _ _⊓-band : Band _ _⊓-commutativeSemigroup : CommutativeSemigroup _ _⊓-semilattice : Semilattice _ _⊓-selectiveMagma : SelectiveMagma _ _⊔-magma : Magma _ _⊔-semigroup : Semigroup _ _⊔-band : Band _ _⊔-commutativeSemigroup : CommutativeSemigroup _ _⊔-semilattice : Semilattice _ _⊔-selectiveMagma : SelectiveMagma _ _⊔-⊓-lattice : Lattice _ _⊓-⊔-lattice : Lattice _ _⊔-⊓-distributiveLattice : DistributiveLattice _ _⊓-⊔-distributiveLattice : DistributiveLattice _ _⊓-glb : p ≥ r → q ≥ r → p ⊓ q ≥ r⊓-triangulate : p ⊓ q ⊓ r ≡ (p ⊓ q) ⊓ (q ⊓ r)⊓-mono-≤ : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊓-monoˡ-≤ : (_⊓ p) Preserves _≤_ ⟶ _≤_⊓-monoʳ-≤ : (p ⊓_) Preserves _≤_ ⟶ _≤_⊔-lub : p ≤ r → q ≤ r → p ⊔ q ≤ r⊔-triangulate : p ⊔ q ⊔ r ≡ (p ⊔ q) ⊔ (q ⊔ r)⊔-mono-≤ : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊔-monoˡ-≤ : (_⊔ p) Preserves _≤_ ⟶ _≤_⊔-monoʳ-≤ : (p ⊔_) Preserves _≤_ ⟶ _≤_p⊓q≡q⇒q≤p : p ⊓ q ≡ q → q ≤ pp⊓q≡p⇒p≤q : p ⊓ q ≡ p → p ≤ qp⊓q≤p : p ⊓ q ≤ pp⊓q≤q : p ⊓ q ≤ qp≤q⇒p⊓r≤q : p ≤ q → p ⊓ r ≤ qp≤q⇒r⊓p≤q : p ≤ q → r ⊓ p ≤ qp≤q⊓r⇒p≤q : p ≤ q ⊓ r → p ≤ qp≤q⊓r⇒p≤r : p ≤ q ⊓ r → p ≤ rp⊔q≡q⇒p≤q : p ⊔ q ≡ q → p ≤ qp⊔q≡p⇒q≤p : p ⊔ q ≡ p → q ≤ pp≤p⊔q : p ≤ p ⊔ qp≤q⊔p : p ≤ q ⊔ pp≤q⇒p≤q⊔r : p ≤ q → p ≤ q ⊔ rp≤q⇒p≤r⊔q : p ≤ q → p ≤ r ⊔ qp⊔q≤r⇒p≤r : p ⊔ q ≤ r → p ≤ rp⊔q≤r⇒q≤r : p ⊔ q ≤ r → q ≤ rp⊓q≤p⊔q : p ⊓ q ≤ p ⊔ qmono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≤_ → f (p ⊔ q) ≡ f p ⊔ f qmono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≤_ → f (p ⊓ q) ≡ f p ⊓ f qmono-<-distrib-⊓ : f Preserves _<_ ⟶ _<_ → f (p ⊓ q) ≡ f p ⊓ f qmono-<-distrib-⊔ : f Preserves _<_ ⟶ _<_ → f (p ⊔ q) ≡ f p ⊔ f qantimono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≥_ → f (p ⊓ q) ≡ f p ⊔ f qantimono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≥_ → f (p ⊔ q) ≡ f p ⊓ f q*-distribˡ-⊓-nonNeg : NonNegative p → p * (q ⊓ r) ≡ (p * q) ⊓ (p * r)*-distribʳ-⊓-nonNeg : NonNegative p → (q ⊓ r) * p ≡ (q * p) ⊓ (r * p)*-distribˡ-⊔-nonNeg : NonNegative p → p * (q ⊔ r) ≡ (p * q) ⊔ (p * r)*-distribʳ-⊔-nonNeg : NonNegative p → (q ⊔ r) * p ≡ (q * p) ⊔ (r * p)*-distribˡ-⊔-nonPos : NonPositive p → p * (q ⊔ r) ≡ (p * q) ⊓ (p * r)*-distribʳ-⊔-nonPos : NonPositive p → (q ⊔ r) * p ≡ (q * p) ⊓ (r * p)*-distribˡ-⊓-nonPos : NonPositive p → p * (q ⊓ r) ≡ (p * q) ⊔ (p * r)*-distribʳ-⊓-nonPos : NonPositive p → (q ⊓ r) * p ≡ (q * p) ⊔ (r * p)1/-involutive : 1/ (1/ p) ≡ ppos⇒1/pos : Positive p → Positive (1/ p)neg⇒1/neg : Negative p → Negative (1/ p)1/pos⇒pos : Positive (1/ p) → Positive p1/neg⇒neg : Negative (1/ p) → Negative ptoℚᵘ-homo-∣_∣ : Homomorphic₁ toℚᵘ ∣_∣ ℚᵘ.∣_∣∣-∣-nonNeg : NonNegative ∣ p ∣0≤∣p∣ : 0ℚ ≤ ∣ p ∣0≤p⇒∣p∣≡p : 0ℚ ≤ p → ∣ p ∣ ≡ p∣p∣≡p⇒0≤p : ∣ p ∣ ≡ p → 0ℚ ≤ p∣-p∣≡∣p∣ : ∣ - p ∣ ≡ ∣ p ∣∣p∣≡0⇒p≡0 : ∣ p ∣ ≡ 0ℚ → p ≡ 0ℚ∣p∣≡p∨∣p∣≡-p : ∣ p ∣ ≡ p ⊎ ∣ p ∣ ≡ - p∣p+q∣≤∣p∣+∣q∣ : ∣ p + q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p-q∣≤∣p∣+∣q∣ : ∣ p - q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p*q∣≡∣p∣*∣q∣ : ∣ p * q ∣ ≡ ∣ p ∣ * ∣ q ∣∣∣p∣∣≡∣p∣ : ∣ ∣ p ∣ ∣ ≡ ∣ p ∣```* Add new relations and functions to `Data.Rational.Unnormalised.Base`:```agda_≤ᵇ_ : ℤ → ℤ → Bool_⊔_ : (p q : ℚᵘ) → ℚᵘ_⊓_ : (p q : ℚᵘ) → ℚᵘ∣_∣ : ℚᵘ → ℚᵘ```* Add new proofs to `Data.Rational.Unnormalised.Properties`:```agda/-cong : p₁ ≡ p₂ → q₁ ≡ q₂ → p₁ / q₁ ≡ p₂ / q₂↥[p/q]≡p : ↥ (p / q) ≡ p↧[p/q]≡q : ↧ (p / q) ≡ ℤ.+ q≤-respˡ-≃ : _≤_ Respectsˡ _≃_≤-respʳ-≃ : _≤_ Respectsʳ _≃_≤-resp₂-≃ : _≤_ Respects₂ _≃_≤-isPreorder : IsPreorder _≃_ _≤_≤-isPreorder-≡ : IsPreorder _≡_ _≤_≤-isTotalPreorder : IsTotalPreorder _≃_ _≤_≤-isTotalPreorder-≡ : IsTotalPreorder _≡_ _≤_≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-preorder-≡ : Preorder 0ℓ 0ℓ 0ℓ≤-totalPreorder : TotalPreorder 0ℓ 0ℓ 0ℓ≤-totalPreorder-≡ : TotalPreorder 0ℓ 0ℓ 0ℓ≤ᵇ⇒≤ : T (p ≤ᵇ q) → p ≤ q≤⇒≤ᵇ : p ≤ q → T (p ≤ᵇ q)p+p≃0⇒p≃0 : p + p ≃ 0ℚᵘ → p ≃ 0ℚᵘp≃-p⇒p≃0 : p ≃ - p → p ≃ 0ℚᵘneg-cancel-< : - p < - q → q < pneg-cancel-≤-≥ : - p ≤ - q → q ≤ pmono⇒cong : f Preserves _≤_ ⟶ _≤_ → f Preserves _≃_ ⟶ _≃_antimono⇒cong : f Preserves _≤_ ⟶ _≥_ → f Preserves _≃_ ⟶ _≃_*-congˡ : LeftCongruent _≃_ _*_*-congʳ : RightCongruent _≃_ _*_*-cancelˡ-/ : (ℤ.+ p ℤ.* q) / (p ℕ.* r) ≃ q / r*-cancelʳ-/ : (q ℤ.* ℤ.+ p) / (r ℕ.* p) ≃ q / r*-cancelʳ-≤-neg : Negative r → p * r ≤ q * r → q ≤ p*-cancelˡ-≤-neg : Negative r → r * p ≤ r * q → q ≤ p*-monoˡ-≤-nonPos : NonPositive r → (_* r) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos : NonPositive r → (r *_) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg : Negative r → (_* r) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-neg : Negative r → (r *_) Preserves _≤_ ⟶ _≥_*-cancelˡ-<-pos : Positive r → r * p < r * q → p < q*-cancelʳ-<-pos : Positive r → p * r < q * r → p < q*-monoˡ-<-neg : Negative r → (_* r) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : Negative r → (r *_) Preserves _<_ ⟶ _>_*-cancelˡ-<-nonPos : NonPositive r → r * p < r * q → q < p*-cancelʳ-<-nonPos : NonPositive r → p * r < q * r → q < p*-cancelˡ-<-neg : Negative r → r * p < r * q → q < p*-cancelʳ-<-neg : Negative r → p * r < q * r → q < ppos⇒1/pos : Positive q → Positive (1/ q)neg⇒1/neg : Negative q → Negative (1/ q)1/-involutive-≡ : 1/ (1/ q) ≡ q1/-involutive : 1/ (1/ q) ≃ qp>1⇒1/p<1 : p > 1ℚᵘ → (1/ p) < 1ℚᵘ⊓-congˡ : LeftCongruent _≃_ _⊓_⊓-congʳ : RightCongruent _≃_ _⊓_⊓-cong : Congruent₂ _≃_ _⊓_⊓-idem : Idempotent _≃_ _⊓_⊓-sel : Selective _≃_ _⊓_⊓-assoc : Associative _≃_ _⊓_⊓-comm : Commutative _≃_ _⊓_⊔-congˡ : LeftCongruent _≃_ _⊔_⊔-congʳ : RightCongruent _≃_ _⊔_⊔-cong : Congruent₂ _≃_ _⊔_⊔-idem : Idempotent _≃_ _⊔_⊔-sel : Selective _≃_ _⊔_⊔-assoc : Associative _≃_ _⊔_⊔-comm : Commutative _≃_ _⊔_⊓-distribˡ-⊔ : _DistributesOverˡ_ _≃_ _⊓_ _⊔_⊓-distribʳ-⊔ : _DistributesOverʳ_ _≃_ _⊓_ _⊔_⊓-distrib-⊔ : _DistributesOver_ _≃_ _⊓_ _⊔_⊔-distribˡ-⊓ : _DistributesOverˡ_ _≃_ _⊔_ _⊓_⊔-distribʳ-⊓ : _DistributesOverʳ_ _≃_ _⊔_ _⊓_⊔-distrib-⊓ : _DistributesOver_ _≃_ _⊔_ _⊓_⊓-absorbs-⊔ : _Absorbs_ _≃_ _⊓_ _⊔_⊔-absorbs-⊓ : _Absorbs_ _≃_ _⊔_ _⊓_⊔-⊓-absorptive : Absorptive _≃_ _⊔_ _⊓_⊓-⊔-absorptive : Absorptive _≃_ _⊓_ _⊔_⊓-isMagma : IsMagma _≃_ _⊓_⊓-isSemigroup : IsSemigroup _≃_ _⊓_⊓-isCommutativeSemigroup : IsCommutativeSemigroup _≃_ _⊓_⊓-isBand : IsBand _≃_ _⊓_⊓-isSemilattice : IsSemilattice _≃_ _⊓_⊓-isSelectiveMagma : IsSelectiveMagma _≃_ _⊓_⊔-isMagma : IsMagma _≃_ _⊔_⊔-isSemigroup : IsSemigroup _≃_ _⊔_⊔-isCommutativeSemigroup : IsCommutativeSemigroup _≃_ _⊔_⊔-isBand : IsBand _≃_ _⊔_⊔-isSemilattice : IsSemilattice _≃_ _⊔_⊔-isSelectiveMagma : IsSelectiveMagma _≃_ _⊔_⊔-⊓-isLattice : IsLattice _≃_ _⊔_ _⊓_⊓-⊔-isLattice : IsLattice _≃_ _⊓_ _⊔_⊔-⊓-isDistributiveLattice : IsDistributiveLattice _≃_ _⊔_ _⊓_⊓-⊔-isDistributiveLattice : IsDistributiveLattice _≃_ _⊓_ _⊔_⊓-rawMagma : RawMagma _ _⊔-rawMagma : RawMagma _ _⊔-⊓-rawLattice : RawLattice _ _⊓-magma : Magma _ _⊓-semigroup : Semigroup _ _⊓-band : Band _ _⊓-commutativeSemigroup : CommutativeSemigroup _ _⊓-semilattice : Semilattice _ _⊓-selectiveMagma : SelectiveMagma _ _⊔-magma : Magma _ _⊔-semigroup : Semigroup _ _⊔-band : Band _ _⊔-commutativeSemigroup : CommutativeSemigroup _ _⊔-semilattice : Semilattice _ _⊔-selectiveMagma : SelectiveMagma _ _⊔-⊓-lattice : Lattice _ _⊓-⊔-lattice : Lattice _ _⊔-⊓-distributiveLattice : DistributiveLattice _ _⊓-⊔-distributiveLattice : DistributiveLattice _ _⊓-triangulate : p ⊓ q ⊓ r ≃ (p ⊓ q) ⊓ (q ⊓ r)⊔-triangulate : p ⊔ q ⊔ r ≃ (p ⊔ q) ⊔ (q ⊔ r)⊓-glb : p ≥ r → q ≥ r → p ⊓ q ≥ r⊓-mono-≤ : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊓-monoˡ-≤ : (_⊓ p) Preserves _≤_ ⟶ _≤_⊓-monoʳ-≤ : (p ⊓_) Preserves _≤_ ⟶ _≤_⊔-lub : p ≤ r → q ≤ r → p ⊔ q ≤ r⊔-mono-≤ : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊔-monoˡ-≤ : (_⊔ p) Preserves _≤_ ⟶ _≤_⊔-monoʳ-≤ : (p ⊔_) Preserves _≤_ ⟶ _≤_p⊓q≃q⇒q≤p : p ⊓ q ≃ q → q ≤ pp⊓q≃p⇒p≤q : p ⊓ q ≃ p → p ≤ qp⊔q≃q⇒p≤q : p ⊔ q ≃ q → p ≤ qp⊔q≃p⇒q≤p : p ⊔ q ≃ p → q ≤ pp⊓q≤p : p ⊓ q ≤ pp⊓q≤q : p ⊓ q ≤ qp≤q⇒p⊓r≤q : p ≤ q → p ⊓ r ≤ qp≤q⇒r⊓p≤q : p ≤ q → r ⊓ p ≤ qp≤q⊓r⇒p≤q : p ≤ q ⊓ r → p ≤ qp≤q⊓r⇒p≤r : p ≤ q ⊓ r → p ≤ rp≤p⊔q : p ≤ p ⊔ qp≤q⊔p : p ≤ q ⊔ pp≤q⇒p≤q⊔r : p ≤ q → p ≤ q ⊔ rp≤q⇒p≤r⊔q : p ≤ q → p ≤ r ⊔ qp⊔q≤r⇒p≤r : p ⊔ q ≤ r → p ≤ rp⊔q≤r⇒q≤r : p ⊔ q ≤ r → q ≤ rp≤q⇒p⊔q≃q : p ≤ q → p ⊔ q ≃ qp≥q⇒p⊔q≃p : p ≥ q → p ⊔ q ≃ pp≤q⇒p⊓q≃p : p ≤ q → p ⊓ q ≃ pp≥q⇒p⊓q≃q : p ≥ q → p ⊓ q ≃ qp⊓q≤p⊔q : p ⊓ q ≤ p ⊔ qmono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≤_ → f (m ⊔ n) ≃ f m ⊔ f nmono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≤_ → f (m ⊓ n) ≃ f m ⊓ f nantimono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≥_ → f (m ⊓ n) ≃ f m ⊔ f nantimono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≥_ → f (m ⊔ n) ≃ f m ⊓ f nneg-distrib-⊔-⊓ : - (p ⊔ q) ≃ - p ⊓ - qneg-distrib-⊓-⊔ : - (p ⊓ q) ≃ - p ⊔ - q*-distribˡ-⊓-nonNeg : NonNegative p → p * (q ⊓ r) ≃ (p * q) ⊓ (p * r)*-distribʳ-⊓-nonNeg : NonNegative p → (q ⊓ r) * p ≃ (q * p) ⊓ (r * p)*-distribˡ-⊔-nonNeg : NonNegative p → p * (q ⊔ r) ≃ (p * q) ⊔ (p * r)*-distribʳ-⊔-nonNeg : NonNegative p → (q ⊔ r) * p ≃ (q * p) ⊔ (r * p)*-distribˡ-⊔-nonPos : NonPositive p → p * (q ⊔ r) ≃ (p * q) ⊓ (p * r)*-distribʳ-⊔-nonPos : NonPositive p → (q ⊔ r) * p ≃ (q * p) ⊓ (r * p)*-distribˡ-⊓-nonPos : NonPositive p → p * (q ⊓ r) ≃ (p * q) ⊔ (p * r)*-distribʳ-⊓-nonPos : NonPositive p → (q ⊓ r) * p ≃ (q * p) ⊔ (r * p)∣-∣-cong : p ≃ q → ∣ p ∣ ≃ ∣ q ∣∣-∣-nonNeg : NonNegative ∣ p ∣0≤∣p∣ : 0 ≤ ∣ p ∣∣p∣≃0⇒p≃0 : ∣ p ∣ ≃ 0ℚᵘ → p ≃ 0ℚᵘ∣-p∣≡∣p∣ : ∣ - p ∣ ≡ ∣ p ∣∣-p∣≃∣p∣ : ∣ - p ∣ ≃ ∣ p ∣0≤p⇒∣p∣≡p : 0ℚᵘ ≤ p → ∣ p ∣ ≡ p0≤p⇒∣p∣≃p : 0ℚᵘ ≤ p → ∣ p ∣ ≃ p∣p∣≡p⇒0≤p : ∣ p ∣ ≡ p → 0ℚᵘ ≤ p∣p∣≃p⇒0≤p : ∣ p ∣ ≃ p → 0ℚᵘ ≤ p∣p∣≡p∨∣p∣≡-p : (∣ p ∣ ≡ p) ⊎ (∣ p ∣ ≡ - p)∣p+q∣≤∣p∣+∣q∣ : ∣ p + q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p-q∣≤∣p∣+∣q∣ : ∣ p - q ∣ ≤ ∣ p ∣ + ∣ q ∣∣p*q∣≡∣p∣*∣q∣ : ∣ p * q ∣ ≡ ∣ p ∣ * ∣ q ∣∣p*q∣≃∣p∣*∣q∣ : ∣ p * q ∣ ≃ ∣ p ∣ * ∣ q ∣∣∣p∣∣≡∣p∣ : ∣ ∣ p ∣ ∣ ≡ ∣ p ∣∣∣p∣∣≃∣p∣ : ∣ ∣ p ∣ ∣ ≃ ∣ p ∣```* Added new functions and pattern synonyms to `Data.Tree.AVL.Indexed`:```agdafoldr : (∀ {k} → Val k → A → A) → A → Tree V l u h → Asize : Tree V → ℕpattern node⁺ k₁ t₁ k₂ t₂ t₃ bal = node k₁ t₁ (node k₂ t₂ t₃ bal) ∼+pattern node⁻ k₁ k₂ t₁ t₂ bal t₃ = node k₁ (node k₂ t₁ t₂ bal) t₃ ∼-ordered : Tree V l u n → l <⁺ u```* Re-exported and defined new functions in `Data.Tree.AVL.Key`:```agda_≈⁺_ : Rel Key _[_]ᴱ : x ≈ y → [ x ] ≈⁺ [ y ]refl⁺ : Reflexive _≈⁺_sym⁺ : l ≈⁺ u → u ≈⁺ lirrefl⁺ : ∀ k → ¬ (k <⁺ k)strictPartialOrder : StrictPartialOrder _ _ _strictTotalOrder : StrictTotalOrder _ _ _```* Added new function to `Data.Tree.Rose`:```agdafromBinary : (A → C) → (B → C) → Tree.Binary A B → Rose C ∞```* Added new definitions to `IO`:```agdagetLine : IO StringMain : Set```* Added new definitions to `Relation.Binary.Bundles`:```agdarecord TotalPreorder c ℓ₁ ℓ₂ : Set (suc (c ⊔ ℓ₁ ⊔ ℓ₂))```* Added new definitions to `Relation.Binary.Structures`:```agdarecord IsTotalPreorder (_≲_ : Rel A ℓ₂) : Set (a ⊔ ℓ ⊔ ℓ₂)```* Added new proofs to `Relation.Binary.Properties.Poset`:```agdamono⇒cong : f Preserves _≤_ ⟶ _≤_ → f Preserves _≈_ ⟶ _≈_antimono⇒cong : f Preserves _≤_ ⟶ _≥_ → f Preserves _≈_ ⟶ _≈_```* Added new definitions and proofs to `Relation.Binary.Properties.(Poset/TotalOrder/DecTotalOrder)`:```agda_≰_ : Rel A p₃≰-respˡ-≈ : _≰_ Respectsˡ _≈_≰-respʳ-≈ : _≰_ Respectsʳ _≈_```* Added new proofs to `Relation.Binary.Consequences`:```agdamono⇒cong : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ → ∀ {f} → f Preserves ≤₁ ⟶ ≤₂ → f Preserves ≈₁ ⟶ ≈₂antimono⇒cong : Symmetric ≈₁ → ≈₁ ⇒ ≤₁ → Antisymmetric ≈₂ ≤₂ → ∀ {f} → f Preserves ≤₁ ⟶ (flip ≤₂) → f Preserves ≈₁ ⟶ ≈₂```* Added new proofs to `Relation.Binary.Construct.Converse`:```agdatotalPreorder : TotalPreorder a ℓ₁ ℓ₂ → TotalPreorder a ℓ₁ ℓ₂isTotalPreorder : IsTotalPreorder ≈ ∼ → IsTotalPreorder ≈ (flip ∼)```* Added new proofs to `Relation.Binary.Morphism.Construct.Constant`:```agdasetoidHomomorphism : (S : Setoid a ℓ₁) (T : Setoid b ℓ₂) → ∀ x → SetoidHomomorphism S TpreorderHomomorphism : (P : Preorder a ℓ₁ ℓ₂) (Q : Preorder b ℓ₃ ℓ₄) → ∀ x → PreorderHomomorphism P Q```* Added new proofs to `Relation.Binary.Morphism.Construct.Composition`:```agdasetoidHomomorphism : SetoidHomomorphism S T → SetoidHomomorphism T U → SetoidHomomorphism S UsetoidMonomorphism : SetoidMonomorphism S T → SetoidMonomorphism T U → SetoidMonomorphism S UsetoidIsomorphism : SetoidIsomorphism S T → SetoidIsomorphism T U → SetoidIsomorphism S UpreorderHomomorphism : PreorderHomomorphism P Q → PreorderHomomorphism Q R → PreorderHomomorphism P RposetHomomorphism : PosetHomomorphism P Q → PosetHomomorphism Q R → PosetHomomorphism P R```* Added new proofs to `Relation.Binary.Morphism.Construct.Identity`:```agdasetoidHomomorphism : (S : Setoid a ℓ₁) → SetoidHomomorphism S SsetoidMonomorphism : (S : Setoid a ℓ₁) → SetoidMonomorphism S SsetoidIsomorphism : (S : Setoid a ℓ₁) → SetoidIsomorphism S SpreorderHomomorphism : (P : Preorder a ℓ₁ ℓ₂) → PreorderHomomorphism P PposetHomomorphism : (P : Poset a ℓ₁ ℓ₂) → PosetHomomorphism P P```* Added new proofs to `Relation.Nullary.Negation`:```agdacontradiction₂ : P ⊎ Q → ¬ P → ¬ Q → Whatever```
Version 1.5===========The library has been tested using Agda 2.6.1 and 2.6.1.1.Highlights----------* Regular expressions which work over both arbitrary types and `String`s.* Instance declarations for `IsDecEquivalence` and `IsDecTotalOrder` over various data types.* Bindings for Haskell's `System.Environment` and `System.Exit`.Bug-fixes---------* Added the version number to the official library name, i.e. name is now `standard-library-1.5` ratherthan `standard-library`, allowing other libraries to require a specific versionas a dependency. See the [library management docs](https://agda.readthedocs.io/en/v2.6.1.1/tools/package-system.html#version-numbers) for more details.* In `Data.List.Relation.Unary.All.Properties`: fixed the type of the proof `map-id`which was incorrectly abstracted over unused module parameters.* In `Data.List.Relation.Binary.Subset.(Propositional/Setoid).Properties`: fixed thefixity of the reasoning combinators in so that they compose properly.* In `Relation.Binary.Construct.Closure.Reflexive`: the example module `Maybe` wasaccidentally exposed publicly. It has been made private.* In `Relation.Binary.Morphism.Structures`: fixed bug where `IsRelIsomorphism` did notpublicly re-export the contents of `IsRelMonomorphism`.* In `Relation.Binary.Bundles`: the binary relation `_≉_` exposed by records now hasthe correct infix precedence.Non-backwards compatible changes--------------------------------* The internal build utilities package `lib.cabal` has been renamed`agda-stdlib-utils.cabal` to avoid potential conflict or confusion.Please note that the package is not intended for external use.* The modules `Algebra.Construct.Zero` and `Algebra.Module.Construct.Zero`are now level-polymorphic, each taking two implicit level parameters.* The definition of `_⊖_` in `Data.Integer.Base` has changed. Previously itwas defined inductively as:```agda_⊖_ : ℕ → ℕ → ℤm ⊖ ℕ.zero = + mℕ.zero ⊖ ℕ.suc n = -[1+ n ]ℕ.suc m ⊖ ℕ.suc n = m ⊖ n```which meant that it had to recursively evaluate its unary arguments.The definition has been changed as follows to use operations on `ℕ` that are backedby builtin operations, greatly improving its performance:```agda_⊖_ : ℕ → ℕ → ℤm ⊖ n with m ℕ.<ᵇ n... | true = - + (n ℕ.∸ m)... | false = + (m ℕ.∸ n)```* The proofs `↭⇒∼bag` and `∼bag⇒↭` have been moved from`Data.List.Relation.Binary.Permutation.Setoid.Properties`to `Data.List.Relation.Binary.BagAndSetEquality` as their current locationwere causing cyclic import dependencies.* In `Data.String`, orders on `String` now use propositional equality as the notionof equivalence on characters rather than the equivalent, but less inference-friendly,variant defined by conversion of characters to natural numbers.This is in line with our effort to deprecate this badly-behaved equivalencerelation on characters.* In `Data.Vec.Relation.Unary.AllPairs`: generalised the types of `head`, `tail`, `uncons`so that the vector talked about does not need to be cons-headed.* Cleaned up `IO` to make it more friendly:+ Renamed `_>>=_` and `_>>_` to `bind` and `seq` respectively to free up the namesfor `do`-notation friendly combinators.+ Introduced `Colist` and `List` modules for the various `sequence` and `mapM` functions.This breaks code that relied on the `Colist`-specific function being exported as part of `IO`.+ `⊤`-returning functions (such as `putStrLn`) have been made level polymorphic.This may force you to add more type or level annotations to your programs.Deprecated modules------------------* The inner module `TransitiveClosure` in `Induction.WellFounded` has been deprecated.You should instead use the standard definition of transitive closure and theaccompanying proof of well-foundness defined in `Relation.Binary.Construct.Closure.Transitive`.* The module `Relation.Binary.OrderMorphism` has been deprecated, as the new`(Homo/Mono/Iso)morphism` infrastructure in `Algebra.Morphism.Structures` is nowcomplete. The new definitions are parameterised by raw bundles instead of bundlesmeaning they are much more flexible to work with.* All modules in the folder `Algebra.Operations` have been deprecated, as their designa) was inconsistent, with some of the modules parameterised over the raw bundle and some over the stanard bundleb) prevented definitions from being neatly inherited by super-bundles.These problems have been fixed with a redesign: definitions of the operations can be found in`Algebra.Definitions.(RawMagma/RawMonoid/RawSemiring)` and their properties can be found in`Algebra.Properties.(Magma/Semigroup/Monoid/CommutativeMonoid/Semiring).(Sum/Mult/Exp)`.The latter also export the definition, and so most users will only need to import the latter.Deprecated names----------------* The immediate contents of `Algebra.Morphism` have been deprecated, as the new`(Homo/Mono/Iso)morphism` infrastructure in `Algebra.Morphism.Structures` is nowcomplete. The new definitions are parameterised by raw bundles instead of bundlesmeaning they are much more flexible to work with. The replacements are as following:```agdaIsSemigroupMorphism ↦ IsSemigroupHomomorphismIsMonoidMorphism ↦ IsMonoidHomomorphismIsCommutativeMonoidMorphism ↦ IsMonoidHomomorphismIsIdempotentCommutativeMonoidMorphism ↦ IsMonoidHomomorphismIsGroupMorphism ↦ IsGroupHomomorphismIsAbelianGroupMorphism ↦ IsGroupHomomorphism```* In `Data.Char.Properties`, deprecated all of the `_≈_`-related content: thisrelation is equivalent to propositional equality but has worse inference.* In `Data.Fin.Properties`:```agdainject+-raise-splitAt ↦ join-splitAt```* In `Data.Integer`, the `show` function has been deprecated. Please use `show`from `Data.Integer.Show` instead.* In `Data.Integer.Properties`:```agdaneg-mono-<-> ↦ neg-mono-<neg-mono-≤-≥ ↦ neg-mono-≤*-monoʳ-≤-non-neg ↦ *-monoʳ-≤-nonNeg*-monoˡ-≤-non-neg ↦ *-monoˡ-≤-nonNeg*-cancelˡ-<-non-neg ↦ *-cancelˡ-<-nonNeg*-cancelʳ-<-non-neg ↦ *-cancelʳ-<-nonNeg```* In `Data.List.Relation.Binary.Subset.Propositional.Properties`:```agdamono ↦ Any-resp-⊆map-mono ↦ map⁺concat-mono ↦ concat⁺>>=-mono ↦ >>=⁺_⊛-mono_ ↦ ⊛⁺_⊗-mono_ ↦ ⊗⁺any-mono ↦ any⁺map-with-∈-mono ↦ map-with-∈⁺filter⁺ ↦ filter-⊆```* In `Data.List.Relation.Binary.Subset.Setoid.Properties`:```agdafilter⁺ ↦ filter-⊆```* In `Data.Rational`, the `show` function has been deprecated. Please use `show`from `Data.Rational.Show` instead.* In `Relation.Binary.Construct.Closure.Reflexive`:```agdaRefl ↦ ReflClosure```* In `Relation.Binary.Construct.Closure.Transitive`:```agdaPlus′ ↦ TransClosure```New modules-----------* Generic definitions over algebraic structures (divisibility, multiplication etc.):```Algebra.Definitions.RawMagmaAlgebra.Definitions.RawMonoidAlgebra.Definitions.RawSemiring```* Properties of generic definitions over algebraic structures (divisibility, multiplication etc.):```Algebra.Properties.Magma.DivisibilityAlgebra.Properties.Semigroup.DivisibilityAlgebra.Properties.CommutativeSemigroup.DivisibilityAlgebra.Properties.Monoid.SumAlgebra.Properties.Monoid.MultAlgebra.Properties.Monoid.DivisibilityAlgebra.Properties.CommutativeMonoid.SumAlgebra.Properties.CommutativeMonoid.MultAlgebra.Properties.Semiring.DivisibilityAlgebra.Properties.Semiring.ExpAlgebra.Properties.Semiring.Exp.TCOptimisedAlgebra.Properties.Semiring.MultAlgebra.Properties.Semiring.Mult.TCOptimisedAlgebra.Properties.CommutativeSemiring.ExpAlgebra.Properties.CommutativeSemiring.Exp.TCOptimised```* Properties of monomorphisms over lattice structures:```Algebra.Morphism.LatticeMonomorphism```* Various modules containing `instance` declarations for`IsDecEquivalence` and `IsDecTotalOrder` records:```Data.Bool.InstancesData.Char.InstancesData.Fin.InstancesData.Float.InstancesData.Integer.InstancesData.List.InstancesData.Nat.InstancesData.Nat.Binary.InstancesData.Product.InstancesData.Rational.InstancesData.Sign.InstancesData.String.InstancesData.Sum.InstancesData.These.InstancesData.Unit.InstancesData.Unit.Polymorphic.InstancesData.Vec.InstancesData.Word.InstancesReflection.Instances```* Various modules for converting numeric data to `String`s:```agdaData.Fin.ShowData.Integer.ShowData.Rational.Show```* Permutations over finite sets represented as a list of transpositions:```Data.Fin.Permutation.Transposition.List```* Heterogeneous relation characterising a list as an infix segment of another:```Data.List.Relation.Binary.Infix.HeterogeneousData.List.Relation.Binary.Infix.Heterogeneous.Properties```and added `Properties` file for the homogeneous variants of (pre/in/suf)fix:```Data.List.Relation.Binary.Prefix.Homogeneous.PropertiesData.List.Relation.Binary.Infix.Homogeneous.PropertiesData.List.Relation.Binary.Suffix.Homogeneous.Properties```* Properties of lists with decidably unique elements:```Data.List.Relation.Unary.Unique.DecSetoidData.List.Relation.Unary.Unique.DecSetoid.PropertiesData.List.Relation.Unary.Unique.DecPropositionalData.List.Relation.Unary.Unique.DecPropositional.Properties```* New ternary relation for two lists that are appended to form a third list:```Data.List.Relation.Ternary.AppendingData.List.Relation.Ternary.Appending.PropertiesData.List.Relation.Ternary.Appending.PropositionalData.List.Relation.Ternary.Appending.Propositional.PropertiesData.List.Relation.Ternary.Appending.SetoidData.List.Relation.Ternary.Appending.Setoid.Properties```* Solvers for rationals:```Data.Rational.SolverData.Rational.Unnormalised.Solver```* Setoid equality over vectors:```Data.Vec.Functional.Relation.Binary.Equality.Setoid```* Bindings for Haskell's `System.Environment`:```System.EnvironmentSystem.Environment.Primitive```* Bindings for Haskell's `System.Exit`:```System.ExitSystem.Exit.Primitive```* Added `Reflection.Traversal` for generic de Bruijn-aware traversals of reflected terms.* Added `Reflection.DeBruijn` with weakening, strengthening and free variable operationson reflected terms.* Added `Relation.Binary.TypeClasses` for type classes to be used with instance search.This module re-exports `_≟_` from `IsDecEquivalence` and `_≤?_` from `IsDecTotalOrder`where the principal argument has been made into an instance argument. Thisenables automatic resolution if the corresponding module`Data.*.Instances` (or `Reflection.Instances`) is imported as well.For example, if `Relation.Binary.TypeClasses`, `Data.Nat.Instances`,and `Data.Bool.Instances` have been imported, then `true ≟ true` hastype `Dec (true ≡ true)`, while `0 ≟ 1` has type `Dec (0 ≡ 1)`. Moreexamples can be found in `README.Relation.Binary.TypeClasses`.* Added various constructions for morphisms over binary relations:```agdaRelation.Binary.Morphism.Construct.CompositionRelation.Binary.Morphism.Construct.ConstantRelation.Binary.Morphism.Construct.Identity```* New modules formalising regular expressions:```Text.RegexText.Regex.BaseText.Regex.Derivative.BrzozowskiText.Regex.Properties.CoreText.Regex.PropertiesText.Regex.SearchText.Regex.SmartConstructorsText.Regex.StringText.Regex.String.Unsafe```Other minor additions---------------------* All bundles in `Algebra.Bundles` now re-export the binary relation `_≉_`from the underlying `Setoid`.* Added new records to `Algebra.Bundles`:```agdaCommutativeMagma c ℓ : Set (suc (c ⊔ ℓ))RawNearSemiring c ℓ : Set (suc (c ⊔ ℓ))RawLattice c ℓ : Set (suc (c ⊔ ℓ))CancellativeCommutativeSemiring c ℓ : Set (suc (c ⊔ ℓ))```* Added new definitions to `Algebra.Definitions`:```agdaAlmostLeftCancellative e _•_ = ¬ x ≈ e → (x • y) ≈ (x • z) → y ≈ zAlmostRightCancellative e _•_ = ¬ x ≈ e → (y • x) ≈ (z • x) → y ≈ zAlmostCancellative e _•_ = AlmostLeftCancellative e _•_ × AlmostRightCancellative e _•_```* Added new records to `Algebra.Morphism.Structures`:```agdaIsNearSemiringHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsNearSemiringMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsNearSemiringIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)IsSemiringHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsSemiringMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsSemiringIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)IsLatticeHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsLatticeMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsLatticeIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)```* Added new definitions to `Algebra.Structures`:```agdaIsCommutativeMagma (• : Op₂ A) : Set (a ⊔ ℓ)IsCancellativeCommutativeSemiring (+ * : Op₂ A) (0# 1# : A) : Set (a ⊔ ℓ)```* Added new proofs to `Codata.Delay.Properties`:```agda⇓-unique : (d⇓₁ : d ⇓) (d⇓₂ : d ⇓) → d⇓₁ ≡ d⇓₂bind̅₁ : bind d f ⇓ → d ⇓bind̅₂ : (bind⇓ : bind d f ⇓) → f (extract (bind̅₁ bind⇓)) ⇓extract-bind-⇓ : (d⇓ : d ⇓) (f⇓ : f (extract d⇓) ⇓) → extract (bind-⇓ d⇓ f⇓) ≡ extract f⇓extract-bind̅₂-bind⇓ : (bind⇓ : bind d f ⇓) → extract (bind̅₂ d bind⇓) ≡ extract bind⇓bind⇓-length : (bind⇓ : bind d f ⇓) (d⇓ : d ⇓) (f⇓ : f (extract d⇓) ⇓) → toℕ (length-⇓ bind⇓) ≡ toℕ (length-⇓ d⇓) ℕ.+ toℕ (length-⇓ f⇓)```* Added new definition to `Data.Char.Base`:```agda_≉_ : Rel Char zero_≤_ : Rel Char zero```* Added proofs to `Data.Char.Properties`:```agda≉⇒≢ : x ≉ y → x ≢ y<-trans : Transitive _<_<-asym : Asymmetric _<_<-cmp : Trichotomous _≡_ _<__≤?_ : Decidable _≤_≤-reflexive : _≡_ ⇒ _≤_≤-trans : Transitive _≤_≤-antisym : Antisymmetric _≡_ _≤_≤-isPreorder : IsPreorder _≡_ _≤_≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isDecPartialOrder : IsDecPartialOrder _≡_ _≤_≤-preorder : Preorder _ _ _≤-poset : Poset _ _ _≤-decPoset : DecPoset _ _ _```* Added new function to `Data.Fin`:```agdajoin : Fin m ⊎ Fin n → Fin (m ℕ.+ n)```* Added new properties to `Data.Fin.Properties`:```agdasplitAt-join : splitAt m (join m n i) ≡ i+↔⊎ : Fin (m ℕ.+ n) ↔ (Fin m ⊎ Fin n)Fin0↔⊥ : Fin 0 ↔ ⊥```* Added new relations, functions and proofs to `Data.Fin.Permutation`:```_≈_ : Rel (Permutation m n) 0ℓlift₀ : Permutation m n → Permutation (suc m) (suc n)lift₀-remove : π ⟨$⟩ʳ 0F ≡ 0F → ∀ i → lift₀ (remove 0F π) ≈ πlift₀-id : lift₀ id ⟨$⟩ʳ i ≡ ilift₀-comp : lift₀ π ∘ₚ lift₀ ρ ≈ lift₀ (π ∘ₚ ρ)lift₀-cong : π ≈ ρ → lift₀ π ≈ lift₀ ρlift₀-transpose : transpose (suc i) (suc j)≈ lift₀ (transpose i j)```* Added new proofs in `Data.Integer.Properties`:```agda[1+m]⊖[1+n]≡m⊖n : suc m ⊖ suc n ≡ m ⊖ n⊖-≤ : m ≤ n → m ⊖ n ≡ - + (n ∸ m)-m+n≡n⊖m : - (+ m) + + n ≡ n ⊖ mm-n≡m⊖n : + m + (- + n) ≡ m ⊖ n≤∧≢⇒< : x ≤ y → x ≢ y → x < y≤∧≮⇒≡ : x ≤ y → x ≮ y → x ≡ ypositive⁻¹ : Positive n → n > 0ℤnonNegative⁻¹ : NonNegative n → n ≥ 0ℤnegative⁻¹ : Negative n → n < 0ℤnonPositive⁻¹ : NonPositive q → q ≤ 0ℤnegative<positive : Negative m → Positive n → m < nneg-mono-< : -_ Preserves _<_ ⟶ _>_neg-mono-≤ : -_ Preserves _≤_ ⟶ _≥_neg-cancel-< : - m < - n → m > nneg-cancel-≤ : - m ≤ - n → m ≥ n+∣n∣≡n⊎+∣n∣≡-n : + ∣ n ∣ ≡ n ⊎ + ∣ n ∣ ≡ - n∣m⊝n∣≤m⊔n : ∣ m ⊖ n ∣ ℕ.≤ m ℕ.⊔ n∣m+n∣≤∣m∣+∣n∣ : ∣ m + n ∣ ℕ.≤ ∣ m ∣ ℕ.+ ∣ n ∣∣m-n∣≤∣m∣+∣n∣ : ∣ m - n ∣ ℕ.≤ ∣ m ∣ ℕ.+ ∣ n ∣*-cancelˡ-≤-neg : -[1+ m ] * n ≤ -[1+ m ] * o → n ≥ o*-cancelʳ-≤-neg : n * -[1+ m ] ≤ o * -[1+ m ] → n ≥ o*-monoˡ-≤-nonPos : NonPositive m → (m *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-nonPos : ∀ m → NonPositive m → (_* m) Preserves _≤_ ⟶ _≥_*-monoˡ-≤-neg : (-[1+ m ] *_) Preserves _≤_ ⟶ _≥_*-monoʳ-≤-neg : (_* -[1+ m ]) Preserves _≤_ ⟶ _≥_*-monoˡ-<-neg : (-[1+ n ] *_) Preserves _<_ ⟶ _>_*-monoʳ-<-neg : (_* -[1+ n ]) Preserves _<_ ⟶ _>_*-cancelˡ-<-neg : -[1+ n ] * i < -[1+ n ] * j → i > j*-cancelˡ-<-nonPos : NonPositive n → n * i < n * j → i > j*-cancelʳ-<-neg : i * -[1+ n ] < j * -[1+ n ] → i > j*-cancelʳ-<-nonPos : NonPositive n → i * n < j * n → i > j∣m*n∣≡∣m∣*∣n∣ : ∣ m * n ∣ ≡ ∣ m ∣ ℕ.* ∣ n ∣+-*-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓmono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≤_ → f (m ⊓ n) ≡ f m ⊓ f nmono-<-distrib-⊓ : f Preserves _<_ ⟶ _<_ → f (m ⊓ n) ≡ f m ⊓ f nmono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≤_ → f (m ⊔ n) ≡ f m ⊔ f nmono-<-distrib-⊔ : f Preserves _<_ ⟶ _<_ → f (m ⊔ n) ≡ f m ⊔ f nantimono-≤-distrib-⊔ : f Preserves _≤_ ⟶ _≥_ → f (m ⊔ n) ≡ f m ⊓ f nantimono-<-distrib-⊔ : f Preserves _<_ ⟶ _>_ → f (m ⊔ n) ≡ f m ⊓ f nantimono-≤-distrib-⊓ : f Preserves _≤_ ⟶ _≥_ → f (m ⊓ n) ≡ f m ⊔ f nantimono-<-distrib-⊓ : f Preserves _<_ ⟶ _>_ → f (m ⊓ n) ≡ f m ⊔ f n*-distribˡ-⊓-nonNeg : + m * (n ⊓ o) ≡ (+ m * n) ⊓ (+ m * o)*-distribʳ-⊓-nonNeg : (n ⊓ o) * + m ≡ (n * + m) ⊓ (o * + m)*-distribˡ-⊔-nonNeg : + m * (n ⊔ o) ≡ (+ m * n) ⊔ (+ m * o)*-distribʳ-⊔-nonNeg : (n ⊔ o) * + m ≡ (n * + m) ⊔ (o * + m)*-distribˡ-⊓-nonPos : NonPositive m → m * (n ⊓ o) ≡ (m * n) ⊔ (m * o)*-distribʳ-⊓-nonPos : NonPositive m → (n ⊓ o) * m ≡ (n * m) ⊔ (o * m)*-distribˡ-⊔-nonPos : NonPositive m → m * (n ⊔ o) ≡ (m * n) ⊓ (m * o)*-distribʳ-⊔-nonPos : NonPositive m → (n ⊔ o) * m ≡ (n * m) ⊓ (o * m)⊓-absorbs-⊔ : _⊓_ Absorbs _⊔_⊔-absorbs-⊓ : _⊔_ Absorbs _⊓_⊔-⊓-absorptive : Absorptive _⊔_ _⊓_⊓-⊔-absorptive : Absorptive _⊓_ _⊔_⊓-isMagma : IsMagma _⊓_⊓-isSemigroup : IsSemigroup _⊓_⊓-isBand : IsBand _⊓_⊓-isCommutativeSemigroup : IsCommutativeSemigroup _⊓_⊓-isSemilattice : IsSemilattice _⊓_⊓-isSelectiveMagma : IsSelectiveMagma _⊓_⊔-isMagma : IsMagma _⊔_⊔-isSemigroup : IsSemigroup _⊔_⊔-isBand : IsBand _⊔_⊔-isCommutativeSemigroup : IsCommutativeSemigroup _⊔_⊔-isSemilattice : IsSemilattice _⊔_⊔-isSelectiveMagma : IsSelectiveMagma _⊔_⊔-⊓-isLattice : IsLattice _⊔_ _⊓_⊓-⊔-isLattice : IsLattice _⊓_ _⊔_⊓-magma : Magma _ _⊓-semigroup : Semigroup _ _⊓-band : Band _ _⊓-commutativeSemigroup : CommutativeSemigroup _ _⊓-semilattice : Semilattice _ _⊓-selectiveMagma : SelectiveMagma _ _⊔-magma : Magma _ _⊔-semigroup : Semigroup _ _⊔-band : Band _ _⊔-commutativeSemigroup : CommutativeSemigroup _ _⊔-semilattice : Semilattice _ _⊔-selectiveMagma : SelectiveMagma _ _⊔-⊓-lattice : Lattice _ _⊓-⊔-lattice : Lattice _ _```* Added new functions to `Data.List.Base`:```agdalinesBy : Decidable P → List A → List (List A)unsnoc : List A → Maybe (List A × A)```* Added new relations in `Data.List.Relation.Binary.Subset.(Propositional/Setoid)`:```agdaxs ⊇ ys = ys ⊆ xsxs ⊉ ys = ¬ xs ⊇ ys```* Added new proofs in `Data.List.Relation.Binary.Subset.Setoid.Properties`:```agda⊆-respʳ-≋ : _⊆_ Respectsʳ _≋_⊆-respˡ-≋ : _⊆_ Respectsˡ _≋_⊆-reflexive-↭ : _↭_ ⇒ _⊆_⊆-respʳ-↭ : _⊆_ Respectsʳ _↭_⊆-respˡ-↭ : _⊆_ Respectsˡ _↭_⊆-↭-isPreorder : IsPreorder _↭_ _⊆_⊆-↭-preorder : Preorder _ _ _Any-resp-⊆ : P Respects _≈_ → (Any P) Respects _⊆_All-resp-⊇ : P Respects _≈_ → (All P) Respects _⊇_xs⊆xs++ys : xs ⊆ xs ++ ysxs⊆ys++xs : xs ⊆ ys ++ xs++⁺ʳ : xs ⊆ ys → zs ++ xs ⊆ zs ++ ys++⁺ˡ : xs ⊆ ys → xs ++ zs ⊆ ys ++ zs++⁺ : ws ⊆ xs → ys ⊆ zs → ws ++ ys ⊆ xs ++ zsfilter⁺′ : P ⋐ Q → xs ⊆ ys → filter P? xs ⊆ filter Q? ys```* Added new proofs in `Data.List.Relation.Binary.Subset.Propositional.Properties`:```agda⊆-reflexive-↭ : _↭_ ⇒ _⊆_⊆-respʳ-↭ : _⊆_ Respectsʳ _↭_⊆-respˡ-↭ : _⊆_ Respectsˡ _↭_⊆-↭-isPreorder : IsPreorder _↭_ _⊆_⊆-↭-preorder : Preorder _ _ _Any-resp-⊆ : (Any P) Respects _⊆_All-resp-⊇ : (All P) Respects _⊇_Sublist⇒Subset : xs ⊑ ys → xs ⊆ ysxs⊆xs++ys : xs ⊆ xs ++ ysxs⊆ys++xs : xs ⊆ ys ++ xs++⁺ʳ : xs ⊆ ys → zs ++ xs ⊆ zs ++ ys++⁺ˡ : xs ⊆ ys → xs ++ zs ⊆ ys ++ zsfilter⁺′ : P ⋐ Q → xs ⊆ ys → filter P? xs ⊆ filter Q? ys```* Added new properties to `Data.List.Properties`:```agdaconcat-++ : concat xss ++ concat yss ≡ concat (xss ++ yss)concat-concat : concat ∘ map concat ≗ concat ∘ concatconcat-[-] : concat ∘ map [_] ≗ id```* Added new relations to `Data.List.Relation.Binary.Sublist.(Setoid/Propositional)`:```agdaxs ⊂ ys = xs ⊆ ys × ¬ (xs ≋ ys)xs ⊃ ys = ys ⊂ xsxs ⊄ ys = ¬ (xs ⊂ ys)xs ⊅ ys = ¬ (xs ⊃ ys)```* Added new proof to `Data.List.Relation.Binary.Permutation.Propositional.Properties`:```agda++↭ʳ++ : xs ++ ys ↭ xs ʳ++ ys```* Added new proof to `Data.List.Relation.Binary.Permutation.Setoi.Properties`:```agda++↭ʳ++ : xs ++ ys ↭ xs ʳ++ ys```* Added new proofs to `Data.List.Extrema`:```agdamin-mono-⊆ : ⊥₁ ≤ ⊥₂ → xs ⊇ ys → min ⊥₁ xs ≤ min ⊥₂ ysmax-mono-⊆ : ⊥₁ ≤ ⊥₂ → xs ⊆ ys → max ⊥₁ xs ≤ max ⊥₂ ys```* Added new operator to `Data.List.Membership.DecSetoid`:```agda_∉?_ : Decidable _∉_```* Added new proofs to `Data.List.Relation.Unary.Any.Properties`:```agdalookup-index : (p : Any P xs) → P (lookup xs (index p))applyDownFrom⁺ : P (f i) → i < n → Any P (applyDownFrom f n)applyDownFrom⁻ : Any P (applyDownFrom f n) → ∃ λ i → i < n × P (f i)```* Added new proofs to `Data.List.Membership.Setoid.Properties`:```agda∈-applyDownFrom⁺ : i < n → f i ∈ applyDownFrom f n∈-applyDownFrom⁻ : v ∈ applyDownFrom f n → ∃ λ i → i < n × v ≈ f i```* Added new proofs to `Data.List.Membership.Propositional.Properties`:```agda∈-applyDownFrom⁺ : i < n → f i ∈ applyDownFrom f n∈-applyDownFrom⁻ : v ∈ applyDownFrom f n → ∃ λ i → i < n × v ≡ f i∈-upTo⁺ : i < n → i ∈ upTo n∈-upTo⁻ : i ∈ upTo n → i < n∈-downFrom⁺ : i < n → i ∈ downFrom n∈-downFrom⁻ : i ∈ downFrom n → i < n```* Added new proofs to `Data.List.Relation.Binary.Lex.Strict`:```agda≤-isDecPartialOrder : IsStrictTotalOrder _≈_ _≺_ → IsDecPartialOrder _≋_ _≤_≤-decPoset : StrictTotalOrder a ℓ₁ ℓ₂ → DecPoset _ _ _```* Added new function to `Data.List.Relation.Binary.Prefix.Heterogeneous`:```agda_++ᵖ_ : Prefix R as bs → ∀ suf → Prefix R as (bs ++ suf)```* Added new function to `Data.List.Relation.Binary.Suffix.Heterogeneous`:```agda_++ˢ_ : ∀ pre → Suffix R as bs → Suffix R as (pre ++ bs)```* Added new function to `Data.Maybe.Base`:```agdawhen : Bool → A → Maybe A```* Added new definition to `Data.Nat.Base`:```agda_≤ᵇ_ : (m n : ℕ) → Bool```* Added new proofs to `Data.Nat.Properties`:```agda≤∧≮⇒≡ : m ≤ n → m ≮ n → m ≡ n≤ᵇ⇒≤ : T (m ≤ᵇ n) → m ≤ n≤⇒≤ᵇ : m ≤ n → T (m ≤ᵇ n)<ᵇ-reflects-< : Reflects (m < n) (m <ᵇ n)≤ᵇ-reflects-≤ : Reflects (m ≤ n) (m ≤ᵇ n)*-distribˡ-⊔ : _*_ DistributesOverˡ _⊔_*-distribʳ-⊔ : _*_ DistributesOverʳ _⊔_*-distrib-⊔ : _*_ DistributesOver _⊔_*-distribˡ-⊓ : _*_ DistributesOverˡ _⊓_*-distribʳ-⊓ : _*_ DistributesOverʳ _⊓_*-distrib-⊓ : _*_ DistributesOver _⊓_```* Added new function to `Data.Nat.Show`:```agdareadMaybe : (base : ℕ) → {base≤16 : True (base ≤? 16)} → String → Maybe ℕ```* Added new functions and relation to `Data.String.Base`:```agdalinesBy : Decidable P → String → List Stringlines : String → List String_≤_ : Rel String zero```* Added new proofs to `Data.Sign.Properties`:```agdas*opposite[s]≡- : s * opposite s ≡ -opposite[s]*s≡- : opposite s * s ≡ -```* Added new operation to `Data.Sum.Base`:```agdareduce : A ⊎ A → A```* Added new proofs to `Data.String.Properties`:```agda≤-isDecPartialOrder-≈ : IsDecPartialOrder _≈_ _≤_≤-decPoset-≈ : DecPoset _ _ _```* Added new functions to `Data.Tree.AVL`:```agdafoldr : (∀ {k} → Val k → A → A) → A → Tree V → Asize : Tree V → ℕintersectionWith : (∀ {k} → Val k → Wal k → Xal k) → Tree V → Tree W → Tree Xintersection : Tree V → Tree V → Tree VintersectionsWith : (∀ {k} → Val k → Val k → Val k) → List (Tree V) → Tree Vintersections : List (Tree V) → Tree V```* Added new functions to `Data.Tree.AVL.Indexed`:```agdafoldr : (∀ {k} → Val k → A → A) → A → Tree V l u h → Asize : Tree V → ℕ```* Added new functions to `Data.Tree.AVL.IndexedMap` module:```agdafoldr : (∀ {k} → Value k → A → A) → A → Map → Asize : Map → ℕ```* Added new functions to `Data.Tree.AVL.Map`:```agdafoldr : (Key → V → A → A) → A → Map V → Asize : Map V → ℕintersectionWith : (V → W → X) → Map V → Map W → Map Xintersection : Map V → Map V → Map VintersectionsWith : (V → V → V) → List (Map V) → Map Vintersections : List (Map V) → Map V```* Added new functions to `Data.Tree.AVL.Sets`:```agdafoldr : (A → B → B) → B → ⟨Set⟩ → Bsize : ⟨Set⟩ → ℕunion : ⟨Set⟩ → ⟨Set⟩ → ⟨Set⟩unions : List ⟨Set⟩ → ⟨Set⟩intersection : ⟨Set⟩ → ⟨Set⟩ → ⟨Set⟩intersections : List ⟨Set⟩ → ⟨Set⟩```* Add new properties to `Data.Vec.Properties`:```agdatake-distr-zipWith : take m (zipWith f u v) ≡ zipWith f (take m u) (take m v)take-distr-map : take m (map f v) ≡ map f (take m v)drop-distr-zipWith : drop m (zipWith f u v) ≡ zipWith f (drop m u) (drop m v)drop-distr-map : drop m (map f v) ≡ map f (drop m v)take-drop-id : take m v ++ drop m v ≡ vzipWith-replicate : zipWith _⊕_ (replicate x) (replicate y) ≡ replicate (x ⊕ y)```* Added infix declarations to `∃-syntax` and `∄-syntax` to `Data.Product`.* Added new definitions to `Function.Bundles`:```agdarecord Func : Set __⟶_ : Set a → Set b → Set _mk⟶ : (A → B) → A ⟶ B```* Added new proofs to `Function.Construct.Composition`:```agdafunction : Func R S → Func S T → Func R T_∘-⟶_ : (A ⟶ B) → (B ⟶ C) → (A ⟶ C)```* Added new proofs to `Function.Construct.Identity`:```agdafunction : Func S Sid-⟶ : A ⟶ A```* Added new function `Reflection.TypeChecking.Format`:```agdaerrorPartFmt : (fmt : String) → Printf (lexer fmt) (List ErrorPart)```* Added new proofs to `Relation.Binary.Construct.Closure.Transitive`:```agdareflexive : Reflexive _∼_ → Reflexive _∼⁺_symmetric : Symmetric _∼_ → Symmetric _∼⁺_transitive : Transitive _∼⁺_wellFounded : WellFounded _∼_ → WellFounded _∼⁺_```* Added new proof to `Relation.Binary.PropositionalEquality`:```agdaresp : (P : Pred A ℓ) → P Respects _≡_```* Added new proof to `Relation.Nullary.Reflects`:```agdafromEquivalence : (T b → P) → (P → T b) → Reflects P b```
Version 1.4===========The library has been tested using Agda 2.6.1 and 2.6.1.1.Highlights----------* First instance modules, which provide `Functor`, `Monad`, `Applicative`instances for various datatypes. Found under `Data.X.Instances`.* New standardised numeric predicates `NonZero`, `Positive`, `Negative`,`NonPositive`, `NonNegative`, especially designed to work as instancearguments.* A general hierarachy of metric functions/spaces, including a specialisation to ℕ.Bug-fixes---------* Fixed various algebraic bundles not correctly re-exporting`commutativeSemigroup` proofs.* Fixed bug in `Induction.WellFounded.FixPoint`, where the well-founded relation `_<_` andthe predicate `P` were required to live at the same universe level.Non-backwards compatible changes--------------------------------#### Changes to the `Relation.Unary.Closure` hierarchy* Following the study of the closure operator `◇` dual to the `□` operatororiginally provided, the `Relation.Unary.Closure` modules have been reorganised.We have+ Added the `◇` closure operator to `.Base`+ Moved all of the `□`-related functions into submodules called `□` (e.g. `reindex` → `□.reindex`)+ Added all of the corresponding `◇`-related functions into submodules called `◇` (e.g. `◇-reindex`)* Added functions converting back and forth between `□`-based and `◇`-based statements in `.Base`:```agdacurry : (∀ {x} → ◇ T x → P x) → (∀ {x} → T x → □ P x)uncurry : (∀ {x} → T x → □ P x) → (∀ {x} → ◇ T x → P x)```#### Other* The `n` argument to `_⊜_` in `Tactic.RingSolver.NonReflective` has been made implict rather than explicit.* Made the first argument of `[,]-∘-distr` in `Data.Sum.Properties` explicit rather than implicit.* `Data.Empty.Polymorphic` and `Data.Unit.Polymorphic` have been redefined using`Lift` and the original non-polymorphic versions, rather than being defined as new types. This meansthat these are now compatible with `⊥` and `⊤` from the rest of the library,allowing them to be used where previously `Lift` was used explicitly.Deprecated modules------------------* The module `Induction.WellFounded.InverseImage` has been deprecated. The proofs`accessible` and `wellFounded` have been moved to `Relation.Binary.Construct.On`.* The module `Data.AVL` and all of its submodules have been renamed to `Data.Tree.AVL`.* The module `Reflection.TypeChecking.MonadSyntax` has been renamed to`Reflection.TypeChecking.Monad.Syntax`.Deprecated names----------------* The proofs `replace-equality` from `Algebra.Properties.(Lattice/DistributiveLattice/BooleanAlgebra)`have been deprecated in favour of the proofs in the new `Algebra.Construct.Subst.Equality` module.* In order to be consistent in usage of \prime character and apostrophe in identifiers,the following three names were deprecated in favor of their replacement that ends with a `\prime` character.* `Data.List.Base.InitLast._∷ʳ'_` ↦ `Data.List.Base.InitLast._∷ʳ′_`* `Data.List.NonEmpty.SnocView._∷ʳ'_` ↦ `Data.List.NonEmpty.SnocView._∷ʳ′_`* `Relation.Binary.Construct.StrictToNonStrict.decidable'` ↦ `Relation.Binary.Construct.StrictToNonStrict.decidable′`* In `Algebra.Morphism.Definitions` and `Relation.Binary.Morphism.Definitions`the type `Morphism A B` were recovered by publicly importing itsdefinition from `Function.Core`. See discussion in issue #1206.* In `Data.Nat.Properties`:```*-+-isSemiring ↦ +-*-isSemiring*-+-isCommutativeSemiring ↦ +-*-isCommutativeSemiring*-+-semiring ↦ +-*-semiring*-+-commutativeSemiring ↦ +-*-commutativeSemiring```* In `Data.Nat.Binary.Properties`:```*-+-isSemiring ↦ +-*-isSemiring*-+-isCommutativeSemiring ↦ +-*-isCommutativeSemiring*-+-semiring ↦ +-*-semiring*-+-commutativeSemiring ↦ +-*-commutativeSemiring*-+-isSemiringWithoutAnnihilatingZero ↦ +-*-isSemiringWithoutAnnihilatingZero```* In `Function.Base`:```*_-[_]-_ ↦ _-⟪_⟫-_```* In `Data.List.Relation.Unary.Any`: `any ↦ any?`* In `Data.List.Relation.Unary.All`: `all ↦ all?`* In `Data.Vec.Relation.Unary.Any` `any ↦ any?`* In `Data.Vec.Relation.Unary.All` `all ↦ all?`New modules-----------* The direct products and zeros over algebraic structures and bundles:```Algebra.Construct.ZeroAlgebra.Construct.DirectProductAlgebra.Module.Construct.DirectProduct.agda```* Substituting the notion of equality for various structures:```Algebra.Construct.Subst.EqualityRelation.Binary.Construct.Subst.Equality```* Instance modules:```agdaCategory.Monad.Partiality.InstancesCodata.Stream.InstancesCodata.Covec.InstancesData.List.InstancesData.List.NonEmpty.InstancesData.Maybe.InstancesData.Vec.InstancesFunction.Identity.Instances```* Predicate for lists that are sorted with respect to a total order:```Data.List.Relation.Unary.Sorted.TotalOrderData.List.Relation.Unary.Sorted.TotalOrder.Properties```* Subtraction for binary naturals:```Data.Nat.Binary.Subtraction```* A predicate for vectors in which every pair of elements is related:```Data.Vec.Relation.Unary.AllPairsData.Vec.Relation.Unary.AllPairs.Properties```* A predicate for vectors in which every element is unique:```Data.Vec.Relation.Unary.Unique.PropositionalData.Vec.Relation.Unary.Unique.Propositional.PropertiesData.Vec.Relation.Unary.Unique.SetoidData.Vec.Relation.Unary.Unique.Setoid.Properties```* Lexicographic relations over vectors:```Data.Vec.Relation.Binary.Lex.CoreData.Vec.Relation.Binary.Lex.NonStrictData.Vec.Relation.Binary.Lex.Strict```* Properties for functional vectors:```Data.Vec.Functional.Properties```* Modules replacing `Function.Related.TypeIsomorphisms` using the new`Inverse` definitions:```Data.Sum.AlgebraData.Product.Algebra```* Basic properties of the function type `A → B`:```agdaFunction.Properties```* Symmetry for various functional properties:```agdaFunction.Construct.Symmetry```* A hierarchy for metric spaces:```Function.MetricFunction.Metric.CoreFunction.Metric.DefinitionsFunction.Metric.StructuresFunction.Metric.Bundles```The distance functions above are defined over an arbitrary type for the image.Specialisations to the natural numbers are provided in the following modules:```Function.Metric.NatFunction.Metric.Nat.CoreFunction.Metric.Nat.DefinitionsFunction.Metric.Nat.StructuresFunction.Metric.Nat.Bundles```and other specialisations can be created in a similar fashion.* The type-checking monads:```Reflection.TypeChecking.MonadReflection.TypeChecking.Monad.CategoricalReflection.TypeChecking.Monad.InstancesReflection.TypeChecking.Format```* Indexed nullary relations/sets:```Relation.Nullary.IndexedRelation.Nullary.Indexed.Negation```* Symmetric transitive closures of binary relations:```Relation.Binary.Construct.Closure.SymmetricTransitive```* Composition of binary relations:```Relation.Binary.Construct.Composition```* Generic `printf` method:```Text.Format.GenericText.Printf.Generic```Other major changes-------------------* The module `Relation.Binary.PropositionalEquality` has recently grown in size andnow depends on a lot of other parts of the library, e.g. the `Algebra` hierarchy,even though its basic functionality does not. To allow users the options of avoidingspecific dependencies, some parts of `Relation.Binary.PropositionalEquality` havebeen refactored out into:```agdaRelation.Binary.PropositionalEquality.PropertiesRelation.Binary.PropositionalEquality.Algebra```These new modules are re-exported by `Relation.Binary.PropositionalEquality`and so these changes should be invisble to current users.Other minor additions---------------------* Add proof to `Algebra.Morphism.RingMonomorphism`:```agdaisCommutativeRing : IsCommutativeRing _≈₂_ _⊕_ _⊛_ ⊝_ 0#₂ 1#₂ → IsCommutativeRing _≈₁_ _+_ _*_ -_ 0# 1#```* Added new proof to `Data.Fin.Induction`:```agda<-wellFounded : WellFounded _<_```* Added new properties to `Data.Fin.Properties`:```agdatoℕ≤n : (i : Fin n) → toℕ i ≤ n≤fromℕ : (i : Fin (suc n)) → i ≤ fromℕ nfromℕ<-cong : m ≡ n → fromℕ< m<o ≡ fromℕ< n<ofromℕ<-injective : fromℕ< m<o ≡ fromℕ< n<o → m ≡ ninject₁ℕ< : (i : Fin n) → toℕ (inject₁ i) < ninject₁ℕ≤ : (i : Fin n) → toℕ (inject₁ i) ≤ n≤̄⇒inject₁< : i' ≤ i → inject₁ i' < suc iℕ<⇒inject₁< : toℕ i' < toℕ i → inject₁ i' < itoℕ-lower₁ : (≢p : m ≢ toℕ x) → toℕ (lower₁ x ≢p) ≡ toℕ xinject₁≡⇒lower₁≡ : (≢p : n ≢ toℕ i') → inject₁ i ≡ i' → lower₁ i' ≢p ≡ ipred< : pred i < isplitAt-< : splitAt m {n} i ≡ inj₁ (fromℕ< i<m)splitAt-≥ : splitAt m {n} i ≡ inj₂ (reduce≥ i i≥m)inject≤-injective : inject≤ x n≤m ≡ inject≤ y n≤m′ → x ≡ y```* Added new functions to `Data.Fin.Base`:```agdaquotRem : Fin (n * k) → Fin k × Fin nopposite : Fin n → Fin n```* Added new types and constructors to `Data.Integer.Base`:```agdaNonZero : Pred ℤ 0ℓPositive : Pred ℤ 0ℓNegative : Pred ℤ 0ℓNonPositive : Pred ℤ 0ℓNonNegative : Pred ℤ 0ℓ≢-nonZero : p ≢ 0ℤ → NonZero p>-nonZero : p > 0ℤ → NonZero p<-nonZero : p < 0ℤ → NonZero ppositive : p > 0ℤ → Positive pnegative : p < 0ℤ → Negative pnonPositive : p ≤ 0ℤ → NonPositive pnonNegative : p ≥ 0ℤ → NonNegative p```* Added new functions to `Data.List.Base`:```agdawordsBy : Decidable P → List A → List (List A)cartesianProductWith : (A → B → C) → List A → List B → List CcartesianProduct : List A → List B → List (A × B)```* Added new proofs to `Data.List.Properties`:```agdareverse-injective : reverse xs ≡ reverse ys → xs ≡ ysmap-injective : Injective _≡_ _≡_ f → Injective _≡_ _≡_ (map f)```* Added new proofs to `Data.List.Membership.Propositional.Properties`:```agda∈-cartesianProductWith⁺ : a ∈ xs → b ∈ ys → f a b ∈ cartesianProductWith f xs ys∈-cartesianProductWith⁻ : v ∈ cartesianProductWith f xs ys → ∃₂ λ a b → a ∈ xs × b ∈ ys × v ≡ f a b∈-cartesianProduct⁺ : x ∈ xs → y ∈ ys → (x , y) ∈ cartesianProduct xs ys∈-cartesianProduct⁻ : xy ∈ cartesianProduct xs ys → x ∈ xs × y ∈ ys```* Added new proofs to `Data.List.Membership.Setoid.Properties`:```agda∈-cartesianProductWith⁺ : a ∈₁ xs → b ∈₂ ys → f a b ∈₃ cartesianProductWith f xs ys∈-cartesianProductWith⁻ : v ∈₃ cartesianProductWith f xs ys → ∃₂ λ a b → a ∈₁ xs × b ∈₂ ys × v ≈₃ f a b∈-cartesianProduct⁺ : x ∈₁ xs → y ∈₂ ys → (x , y) ∈₁₂ cartesianProduct xs ys∈-cartesianProduct⁻ : (x , y) ∈₁₂ cartesianProduct xs ys → x ∈₁ xs```* Added new operations to `Data.List.Relation.Unary.All`:```agdatabulateₛ : (∀ {x} → x ∈ xs → P x) → All P xs```* Added new proofs to `Data.List.Relation.Unary.All.Properties`:```agdacartesianProductWith⁺ : (∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (f x y)) → All P (cartesianProductWith f xs ys)cartesianProduct⁺ : (∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (x , y)) → All P (cartesianProduct xs ys)```* Added new proofs to `Data.List.Relation.Unary.Any.Properties`:```agdacartesianProductWith⁺ : (∀ {x y} → P x → Q y → R (f x y)) → Any P xs → Any Q ys → Any R (cartesianProductWith f xs ys)cartesianProductWith⁻ : (∀ {x y} → R (f x y) → P x × Q y) → Any R (cartesianProductWith f xs ys) → Any P xs × Any Q yscartesianProduct⁺ : Any P xs → Any Q ys → Any (P ⟨×⟩ Q) (cartesianProduct xs ys)cartesianProduct⁻ : Any (P ⟨×⟩ Q) (cartesianProduct xs ys) → Any P xs × Any Q ysreverseAcc⁺ : Any P acc ⊎ Any P xs → Any P (reverseAcc acc xs)reverseAcc⁻ : Any P (reverseAcc acc xs) -> Any P acc ⊎ Any P xsreverse⁺ : Any P xs → Any P (reverse xs)reverse⁻ : Any P (reverse xs) → Any P xs```* Added new proofs to `Data.List.Relation.Unary.Unique.Propositional.Properties`:```agdacartesianProductWith⁺ : (∀ {w x y z} → f w y ≡ f x z → w ≡ x × y ≡ z) → Unique xs → Unique ys → Unique (cartesianProductWith f xs ys)cartesianProduct⁺ : Unique xs → Unique ys → Unique (cartesianProduct xs ys)```* Added new proofs to `Data.List.Relation.Unary.Unique.Setoid.Properties`:```agdacartesianProductWith⁺ : (∀ {w x y z} → f w y ≈₃ f x z → w ≈₁ x × y ≈₂ z) → Unique S xs → Unique T ys → Unique U (cartesianProductWith f xs ys)cartesianProduct⁺ : Unique S xs → Unique T ys → Unique (S ×ₛ T) (cartesianProduct xs ys)```* Added new properties to ` Data.List.Relation.Binary.Permutation.Propositional.Properties`:```agda↭-empty-inv : xs ↭ [] → xs ≡ []¬x∷xs↭[] : ¬ (x ∷ xs ↭ [])↭-singleton-inv : xs ↭ [ x ] → xs ≡ [ x ]↭-map-inv : map f xs ↭ ys → ∃ λ ys′ → ys ≡ map f ys′ × xs ↭ ys′↭-length : xs ↭ ys → length xs ≡ length ys```* Added new proofs to `Data.List.Relation.Unary.Linked.Properties`:```agdamap⁻ : Linked R (map f xs) → Linked (λ x y → R (f x) (f y)) xsfilter⁺ : Transitive R → Linked R xs → Linked R (filter P? xs)```* Add new properties to `Data.Maybe.Properties`:```agdamap-injective : Injective _≡_ _≡_ f → Injective _≡_ _≡_ (map f)```* Added new proofs to `Data.Maybe.Relation.Binary.Pointwise`:```agdanothing-inv : Pointwise R nothing x → x ≡ nothingjust-inv : Pointwise R (just x) y → ∃ λ z → y ≡ just z × R x z```* `Data.Nat.Binary.Induction` now re-exports `Acc` and `acc` from `Induction.WellFounded`.* Added new properties to `Data.Nat.Binary.Properties`:```agda+-isSemigroup : IsSemigroup _+_+-semigroup : Semigroup 0ℓ 0ℓ+-isCommutativeSemigroup : IsCommutativeSemigroup _+_+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓx≡0⇒double[x]≡0 : x ≡ 0ᵇ → double x ≡ 0ᵇdouble-suc : double (suc x) ≡ 2ᵇ + double xpred[x]+y≡x+pred[y] : x ≢ 0ᵇ → y ≢ 0ᵇ → (pred x) + y ≡ x + pred yx+suc[y]≡suc[x]+y : x + suc y ≡ suc x + y```* Added new types and constructors to `Data.Nat.Base`:```agdaNonZero : ℕ → Set≢-nonZero : n ≢ 0 → NonZero n>-nonZero : n > 0 → NonZero n```* The function `pred` in `Data.Nat.Base` has been redefined as `pred n = n ∸ 1`.Consequently proofs about `pred` are now just special cases of proofs for `_∸_`.The change is fully backwards compatible.* Added new proofs to `Data.Nat.Properties`:```agdapred[m∸n]≡m∸[1+n] : pred (m ∸ n) ≡ m ∸ suc n∣-∣-isProtoMetric : IsProtoMetric _≡_ ∣_-_∣∣-∣-isPreMetric : IsPreMetric _≡_ ∣_-_∣∣-∣-isQuasiSemiMetric : IsQuasiSemiMetric _≡_ ∣_-_∣∣-∣-isSemiMetric : IsSemiMetric _≡_ ∣_-_∣∣-∣-isMetric : IsMetric _≡_ ∣_-_∣∸-magma : Magma 0ℓ 0ℓ∣-∣-quasiSemiMetric : QuasiSemiMetric 0ℓ 0ℓ∣-∣-semiMetric : SemiMetric 0ℓ 0ℓ∣-∣-preMetric : PreMetric 0ℓ 0ℓ∣-∣-metric : Metric 0ℓ 0ℓ```* Added new proof to `Data.Nat.Coprimality`:```agda¬0-coprimeTo-2+ : ¬ Coprime 0 (2 + n)recompute : .(Coprime n d) → Coprime n d```* Add new functions to `Data.Product`:```agdaassocʳ-curried : Σ (Σ A B) C → Σ A (λ a → Σ (B a) (curry C a))assocˡ-curried : Σ A (λ a → Σ (B a) (curry C a)) → Σ (Σ A B) Cassocʳ : Σ (Σ A B) (uncurry C) → Σ A (λ a → Σ (B a) (C a))assocˡ : Σ A (λ a → Σ (B a) (C a)) → Σ (Σ A B) (uncurry C)assocʳ′ : (A × B) × C → A × (B × C)assocˡ′ : A × (B × C) → (A × B) × Cdmap : (f : (a : A) → B a) → (∀ {a} (b : P a) → Q b (f a)) → ((a , b) : Σ A P) → Σ (B a) (Q b)dmap′ : ((a : A) → X a) → ((b : B) → Y b) → ((a , b) : A × B) → X a × Y b_<*>_ : ((a : A) → X a) × ((b : B) → Y b) → ((a , b) : A × B) → X a × Y b```* Added new proofs to `Data.Product.Properties`:```agdaΣ-≡,≡↔≡ : {p₁@(a₁ , b₁) p₂@(a₂ , b₂) : Σ A B} → (∃ λ (p : a₁ ≡ a₂) → subst B p b₁ ≡ b₂) ↔ (p₁ ≡ p₂)×-≡,≡↔≡ : {p₁@(a₁ , b₁) p₂@(a₂ , b₂) : A × B} → (a₁ ≡ a₂ × b₁ ≡ b₂) ↔ p₁ ≡ p₂∃∃↔∃∃ : (R : A → B → Set ℓ) → (∃₂ λ x y → R x y) ↔ (∃₂ λ y x → R x y)```* Add new functions to `Data.Sum.Base`:```agdaassocʳ : (A ⊎ B) ⊎ C → A ⊎ B ⊎ Cassocˡ : A ⊎ B ⊎ C → (A ⊎ B) ⊎ C```* Added new proofs to `Data.Sum.Properties`:```agdamap-id : map id id ≗ idmap₁₂-commute : map₁ f ∘ map₂ g ≗ map₂ g ∘ map₁ f[,]-cong : f ≗ f′ → g ≗ g′ → [ f , g ] ≗ [ f′ , g′ ][-,]-cong : f ≗ f′ → [ f , g ] ≗ [ f′ , g ][,-]-cong : g ≗ g′ → [ f , g ] ≗ [ f , g′ ]map-cong : f ≗ f′ → g ≗ g′ → map f g ≗ map f′ g′map₁-cong : f ≗ f′ → map₁ f ≗ map₁ f′map₂-cong : g ≗ g′ → map₂ g ≗ map₂ g′```* Added new types and constructors to `Data.Rational`:```agdaNonZero : Pred ℚ 0ℓPositive : Pred ℚ 0ℓNegative : Pred ℚ 0ℓNonPositive : Pred ℚ 0ℓNonNegative : Pred ℚ 0ℓ≢-nonZero : p ≢ 0ℚ → NonZero p>-nonZero : p > 0ℚ → NonZero p<-nonZero : p < 0ℚ → NonZero ppositive : p > 0ℚ → Positive pnegative : p < 0ℚ → Negative pnonPositive : p ≤ 0ℚ → NonPositive pnonNegative : p ≥ 0ℚ → NonNegative p```* Added new proofs to `Data.Rational.Properties`:```agda+-*-isCommutativeRing : IsCommutativeRing _+_ _*_ -_ 0ℚ 1ℚ+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ*-zeroˡ : LeftZero 0ℚ _*_*-zeroʳ : RightZero 0ℚ _*_*-zero : Zero 0ℚ _*_```* Added new types and constructors to `Data.Rational.Unnormalised`:```agda_≠_ : Rel ℚᵘ 0ℓNonZero : Pred ℚᵘ 0ℓPositive : Pred ℚᵘ 0ℓNegative : Pred ℚᵘ 0ℓNonPositive : Pred ℚᵘ 0ℓNonNegative : Pred ℚᵘ 0ℓ≢-nonZero : p ≠ 0ℚᵘ → NonZero p>-nonZero : p > 0ℚᵘ → NonZero p<-nonZero : p < 0ℚᵘ → NonZero ppositive : p > 0ℚᵘ → Positive pnegative : p < 0ℚᵘ → Negative pnonPositive : p ≤ 0ℚᵘ → NonPositive pnonNegative : p ≥ 0ℚᵘ → NonNegative p```* Added new functions to `Data.String.Base`:```agdawordsBy : Decidable P → String → List Stringwords : String → List String```* Added new proofs to `Data.Tree.Binary.Properties`:```agdamap-compose : map (f₁ ∘ f₂) (g₁ ∘ g₂) ≗ map f₁ g₁ ∘ map f₂ g₂map-cong : f₁ ≗ f₂ → g₁ ≗ g₂ → map f₁ g₁ ≗ map f₂ g₂```* Added new proofs to `Data.Unit.Properties`:```agda⊤-irrelevant : Irrelevant ⊤```* Added new proofs to `Data.Vec.Properties`:```agdaunfold-take : take (suc n) (x ∷ xs) ≡ x ∷ take n xsunfold-drop : drop (suc n) (x ∷ xs) ≡ drop n xslookup-inject≤-take : lookup xs (inject≤ i m≤m+n) ≡ lookup (take m xs) i```* Added new functions to `Data.Vec.Functional`:```agdalength : Vector A n → ℕinsert : Vector A n → Fin (suc n) → A → Vector A (suc n)updateAt : Fin n → (A → A) → Vector A n → Vector A n_++_ : Vector A m → Vector A n → Vector A (m + n)concat : Vector (Vector A m) n → Vector A (n * m)_>>=_ : Vector A m → (A → Vector B n) → Vector B (m * n)unzipWith : (A → B × C) → Vector A n → Vector B n × Vector C nunzip : Vector (A × B) n → Vector A n × Vector B ntake : Vector A (m + n) → Vector A mdrop : Vector A (m + n) → Vector A nreverse : Vector A n → Vector A ninit : Vector A (suc n) → Vector A nlast : Vector A (suc n) → Atranspose : Vector (Vector A n) m → Vector (Vector A m) n```* Added new functions to `Data.Vec.Relation.Unary.All`:```agdareduce : (f : ∀ {x} → P x → B) → All P xs → Vec B n```* Added new proofs to `Data.Vec.Relation.Unary.All.Properties`:```agdaAll-swap : All (λ x → All (x ~_) ys) xs → All (λ y → All (_~ y) xs) ystabulate⁺ : (∀ i → P (f i)) → All P (tabulate f)tabulate⁻ : All P (tabulate f) → (∀ i → P (f i))drop⁺ : All P xs → All P (drop m xs)take⁺ : All P xs → All P (take m xs)```* Added new proofs to `Data.Vec.Membership.Propositional.Properties`:```agdaindex-∈-lookup : index (∈-lookup i xs) ≡ i```* Added new functions to `Function.Base`:```agda_∘₂_ : (f : {x : A₁} → {y : A₂ x} → (z : B x y) → C z) →(g : (x : A₁) → (y : A₂ x) → B x y) →((x : A₁) → (y : A₂ x) → C (g x y))_∘₂′_ : (C → D) → (A → B → C) → (A → B → D)constᵣ : A → B → B_-⟪_∣ : (A → B → C) → (C → B → D) → (A → B → D)∣_⟫-_ : (A → C → D) → (A → B → C) → (A → B → D)_-⟨_∣ : (A → C) → (C → B → D) → (A → B → D)∣_⟩-_ : (A → C → D) → (B → C) → (A → B → D)_-⟪_⟩-_ : (A → B → C) → (C → D → E) → (B → D) → (A → B → E)_-⟨_⟫-_ : (A → C) → (C → D → E) → (A → B → D) → (A → B → E)_-⟨_⟩-_ : (A → C) → (C → D → E) → (B → D) → (A → B → E)_on₂_ : (C → C → D) → (A → B → C) → (A → B → D)```* Added new proofs to `Function.Bundles`:```agdamk↔′ : ∀ (f : A → B) (f⁻¹ : B → A) → Inverseˡ f f⁻¹ → Inverseʳ f f⁻¹ → A ↔ B```* Added new operators to `Relation.Binary`:```agda_⇔_ : REL A B ℓ₁ → REL A B ℓ₂ → Set _```* Added new proofs to `Relation.Binary.PropositionalEquality`:```agdatrans-cong : trans (cong f p) (cong f q) ≡ cong f (trans p q)cong₂-reflˡ : cong₂ _∙_ refl p ≡ cong (x ∙_) pcong₂-reflʳ : cong₂ _∙_ p refl ≡ cong (_∙ u) p```* Added new combinators to `Relation.Binary.PropositionalEquality.Core`:```agdapattern erefl x = refl {x = x}cong′ : {f : A → B} x → f x ≡ f xicong : {f : A → B} {x y} → x ≡ y → f x ≡ f yicong′ : {f : A → B} x → f x ≡ f x```* Added new proofs to `Relation.Nullary.Decidable`:```agdaTrue-↔ : (dec : Dec P) → Irrelevant P → True dec ↔ P```* Added new proofs to `Relation.Binary.Construct.NonStrictToStrict`:```agda<-isDecStrictPartialOrder : IsDecPartialOrder _≈_ _≤_ → IsDecStrictPartialOrder _≈_ _<_```* The following operators have had fixities assigned:```infix 4 _[_] (Data.Graph.Acyclic)infix 4 _∣?_ (Data.Integer.Divisibility.Signed)infix 4 _∈_ _∉_ (Data.List.Fresh.Membership.Setoid)infixr 5 _∷_ (Data.List.Fresh.Relation.Unary.All)infixr 5 _∷_ _++_ (Data.List.Relation.Binary.Prefix.Heterogeneous)infix 4 _⊆?_ (Data.List.Relation.Binary.Sublist.DecSetoid)infix 4 _⊆I_ _⊆R_ _⊆T_ (Data.List.Relation.Binary.Sublist.Heterogeneous.Solver)infixr 8 _⇒_ (Data.List.Relation.Binary.Sublist.Propositional.Example.UniqueBoundVariables)infix 1 _⊢_~_▷_ (Data.List.Relation.Binary.Sublist.Propositional.Example.UniqueBoundVariables)infix 4 _++-mono_ (Data.List.Relation.Binary.Subset.Propositional.Properties)infix 4 _⊛-mono_ (Data.List.Relation.Binary.Subset.Propositional.Properties)infix 4 _⊗-mono_ (Data.List.Relation.Binary.Subset.Propositional.Properties)infixr 5 _++_ (Data.List.Relation.Binary.Suffix.Heterogeneous)infixr 5 _∷ˡ_ _∷ʳ_ (Data.List.Relation.Ternary.Interleaving)infix 1 _++_∷_ (Data.List.Relation.Unary.First)infixr 5 _∷_ (Data.List.Relation.Unary.First)infix 4 _≥_ (Data.Nat.Binary.Base)infix 4 _<?_ _≟_ _≤?_ (Data.Nat.Binary.Properties)infixr 1 _∪-Fin_ (Data.Nat.InfinitelyOften)infixr -1 _<$>_ (Function.Nary.NonDependent.Base)infix 1 _%=_⊢_ (Function.Nary.NonDependent.Base)infix 1 _∷=_⊢_ (Function.Nary.NonDependent.Base)infixr 2 _⊗_ (Induction.Lexicographic)infix 10 _⋆ (Relation.Binary.Construct.Closure.ReflexiveTransitive)infix 4 _≤_ (Relation.Binary.Construct.StrictToNonStrict)infixr 6 _$ʳ_ (Tactic.RingSolver)infix -1 _$ᵉ_ (Tactic.RingSolver)infix 4 _⇓≟_ (Tactic.RingSolver)infixl 6 _⊜_ (Tactic.RingSolver.NonReflective)```
Version 1.3===========The library has been tested using Agda version 2.6.1.Highlights----------* Monoid and ring tactics that are capable of solving equalitieswithout having to restate the equation.* Binary and rose trees.* Warnings when importing deprecated modules.Bug-fixes---------* In `Data.Fin.Subset.Properties` the incorrectly named proof`p⊆q⇒∣p∣<∣q∣ : p ⊆ q → ∣ p ∣ ≤ ∣ q ∣` has been renamed to `p⊆q⇒∣p∣≤∣q∣`.* In `Data.Nat.Properties` the incorrectly named proofs`∀[m≤n⇒m≢o]⇒o<n : (∀ {m} → m ≤ n → m ≢ o) → n < o`and `∀[m<n⇒m≢o]⇒o≤n : (∀ {m} → m < n → m ≢ o) → n ≤ o`have been renamed to `∀[m≤n⇒m≢o]⇒n<o` and `∀[m<n⇒m≢o]⇒n≤o` respectively.* Fixed the definition of `_⊓_` for `Codata.Conat`; it was mistakenly using`_⊔_` in a recursive call.* Fixed the type of `max≈v⁺` in `Data.List.Extrema`; it was mistakenly talkingabout `min` rather than `max`.* The module `⊆-Reasoning` in `Data.List.Relation.Binary.BagAndSetEquality`now exports the correct set of combinators.* The record `DecStrictPartialOrder` now correctly re-exports the contentsof its `IsDecStrictPartialOrder` field.Non-backwards compatible changes--------------------------------#### Changes to how equational reasoning is implemented* NOTE: __Uses__ of equational reasoning remains unchanged. These changes should onlyaffect users who are renaming/hiding the library's equational reasoning combinators.* Previously all equational reasoning combinators (e.g. `_≈⟨_⟩_`, `_≡⟨_⟩_`, `_≤⟨_⟩_`)were defined in the following style:```agdainfixr 2 _≡⟨_⟩__≡⟨_⟩_ : ∀ x {y z : A} → x ≡ y → y ≡ z → x ≡ z_ ≡⟨ x≡y ⟩ y≡z = trans x≡y y≡z```The type checker therefore infers the RHS of the equational step from the LHS + thetype of the proof. For example for `x ≈⟨ x≈y ⟩ y ∎` it is inferred that `y ∎`must have type `y IsRelatedTo y` from `x : A` and `x≈y : x ≈ y`.* There are two problems with this. Firstly, it means that the reasoning combinators arenot compatible with macros (i.e. tactics) that attempt to automatically generate proofsfor `x≈y`. This is because the reflection machinary does not have access to the type of RHSas it cannot be inferred. In practice this meant that the new reflective solvers`Tactic.RingSolver` and `Tactic.MonoidSolver` could not be used inside the equationalreasoning. Secondly the inference procedure itself is slower as described in this[exchange](https://lists.chalmers.se/pipermail/agda/2016/009090.html)on the Agda mailing list.* Therefore, as suggested on the mailing list, the order of arguments to the combinatorshave been reversed so that instead the type of the proof is inferred from the LHS + RHS.```agdainfixr -2 step-≡step-≡ : ∀ x {y z : A} → y ≡ z → x ≡ y → x ≡ zstep-≡ y≡z x≡y = trans x≡y y≡zsyntax step-≡ x y≡z x≡y = x ≡⟨ x≡y ⟩ y≡z```where the `syntax` declaration is then used to recover the original order of the arguments.This change enables the use of macros and anecdotally speeds up type checking by afactor of 5.* No changes are needed when defining new combinators, as the old and new styles arecompatible. Having said that you may want to switch to the new style for the benefitsdescribed above.* **Changes required**: The only drawback to this change is that hiding and renaming thecombinators no longer works as before, as `_≡⟨_⟩_` etc. are now syntax instead of names.For example instead of:```agdaopen SetoidReasoning setoid publichiding (_≈⟨_⟩_) renaming (_≡⟨_⟩_ to _↭⟨_⟩_)```one must now write :```agdaprivatemodule Base = SetoidReasoning setoidopen Base public hiding (step-≈; step-≡)infixr 2 step-↭step-↭ = Base.step-≡syntax step-↭ x y≡z x≡y = x ↭⟨ x≡y ⟩ y≡z```This is more verbose than before, but we hope that the advantages outlined aboveoutweigh this minor inconvenience. (As an aside, it is hoped that at some point Agda mightprovide the ability to rename syntax that automatically generates the above boilerplate).#### Changes to the algebra hierarchy* The following record definitions in `Algebra.Structures` have been changed.- `IsCommutativeMonoid`- `IsCommutativeSemiring`- `IsRing`In each case, the structure now requires fields for all the required properties,rather than just an (arbitrary) minimal set of properties.* For example, whereas the old definition of `IsCommutativeMonoid` requiredthe following fields:- Associativity- Left identity- Commutativitythe new definition also requires:- Right identity.* Previously, the justification for not including a right identity proof was that,given left identity and commutativity, right identity can be proven. However,omitting the right identity proof caused problems:1. It made the definition longer and more complex, as less code was reused.2. The forgetful map turning a commutative monoid into a monoid was not aretraction of all maps which augment a monoid with commutativity. To seethat the forgetful map was not a retraction, notice that the augmentationmust have discarded the right identity proof as there was no field for itin `IsCommutativeMonoid`.3. There was no easy way to give only the right identity proof, and havethe left identity proof be generically derived.Point 2, and in particular the fact that it did not hold definitionally,causes problems when indexing over monoids and commutative monoids andrequires some compatibility between the two indexings.* **Changes required**: We recover the old behaviour by introducing *biased*structures, found in `Algebra.Structures.Biased`. In particular, one canconvert old instances of `IsCommutativeMonoid` to new instances using the`isCommutativeMonoidˡ` function. For example:```agdaisCommutativeMonoid = record{ isSemigroup = ...; identityˡ = ...; comm = ...}```becomes:```agdaopen import Algebra.Structures.BiasedisCommutativeMonoid = isCommutativeMonoidˡ record{ isSemigroup = ...; identityˡ = ...; comm = ...}```* For `IsCommutativeSemiring`, we have `isCommutativeSemiringˡ`, and for`IsRing`, we have `isRingWithoutAnnihilatingZero`.#### Tweak to definition of `Permutation.refl`* The definition of `refl` in `Data.List.Relation.Binary.Permutation.Homogeneous/Setoid`has been changed from```agdarefl : ∀ {xs} → Permutation R xs xs```to:```agdarefl : ∀ {xs ys} → Pointwise R xs ys → Permutation R xs ys```The old definition did not allow for size preserving transformations of permutationsvia pointwise equalities and hence made it difficult to prove termination of complicatedproofs and functions over permutations.* Correspondingly the proofs `isEquivalence` and `setoid` in `Permutation.Homogeneous`now require that the base relation `R` is reflexive.#### Improved safety for `Word` and `Float`* Decidable equality over floating point numbers has been made safe andso `_≟_` has been moved from `Data.Float.Unsafe` to `Data.Float.Properties`.* Decidable equality over words has been made safe and so `_≟_` has beenmoved from `Data.Word.Unsafe` to `Data.Word.Properties`.* The modules `Data.Word.Unsafe` and `Data.Float.Unsafe` have been removedas there are no longer any unsafe operations.#### Other* The following lemmas may have breaking changes in their computationalbehaviour.- `transpose-inverse` in `Data.Fin.Permutation.Components`- `decFinSubset` & `all?` in `Data.Fin.Properties`Definitions that are sensitive to the behaviour of these lemmas, rather thanjust their existence, may need to be revised.* The fixity level of `Data.List.Base`'s `_∷ʳ_` has been changed from 5 to 6.This means that `x ∷ xs ∷ʳ y` and `x ++ xs ∷ʳ y` are not ambiguousanymore: they both are parenthesised to the right (the more efficientvariant).* In `Codata.Cowriter` and `Codata.Musical.Colist` the functions `splitAt`, `take`and `take-⊑` have been changed to use bounded vectors as defined in`Data.Vec.Bounded` instead of the deprecated `Data.BoundedVec`. The old proofsstill exist under the names `splitAt′`, `take′` and `take′-⊑` but have beendeprecated.* In `Codata.Colist`, uses of `Data.BoundedVec` have been replaced with the moreup to date `Data.Vec.Bounded`.Deprecated modules------------------* A warning is now raised whenever you import a deprecated module. This shouldaid the transition to the new modules. These warnings can be disabled locallyby adding the pragma `{-# OPTIONS --warn=noUserWarning #-}` to the top of a module.The following modules have been renamed as part of a drive to improveconsistency across the library. The deprecated modules still exist andtherefore all existing code should still work, however use of the new namesis encouraged.* In `Algebra`:```Algebra.FunctionProperties.Consequences.Core ↦ Algebra.Consequences.BaseAlgebra.FunctionProperties.Consequences.Propositional ↦ Algebra.Consequences.PropositionalAlgebra.FunctionProperties.Consequences ↦ Algebra.Conseqeunces.Setoid```* The sub-module `Lexicographic` in `Data.Induction.WellFounded` has been deprecated,instead the new proofs of well-foundedness in `Data.Product.Relation.Binary.Lex.Strict`should be used.Deprecated names----------------The following deprecations have occurred as part of a drive to improveconsistency across the library. The deprecated names still exist andtherefore all existing code should still work, however use of the new namesis encouraged. Although not anticipated any time soon, they may eventuallybe removed in some future release of the library. Automated warnings areattached to all deprecated names to discourage their use.* In `Data.Fin`:```agdafromℕ≤ ↦ fromℕ<fromℕ≤″ ↦ fromℕ<″```* In `Data.Fin.Properties````agdafromℕ≤-toℕ ↦ fromℕ<-toℕtoℕ-fromℕ≤ ↦ toℕ-fromℕ<fromℕ≤≡fromℕ≤″ ↦ fromℕ<≡fromℕ<″toℕ-fromℕ≤″ ↦ toℕ-fromℕ<″isDecEquivalence ↦ ≡-isDecEquivalencepreorder ↦ ≡-preordersetoid ↦ ≡-setoiddecSetoid ↦ ≡-decSetoid```* In `Data.List.Relation.Unary.All.Properties`:```agdaAny¬→¬All ↦ Any¬⇒¬All```* In `Data.Nat.Properties`:```agda∀[m≤n⇒m≢o]⇒o<n ↦ ∀[m≤n⇒m≢o]⇒n<o∀[m<n⇒m≢o]⇒o≤n ↦ ∀[m<n⇒m≢o]⇒n≤o```* In `Algebra.Morphism.Definitions` and `Relation.Binary.Morphism.Definitions`the type `Morphism A B` has been deprecated in favour of the standardfunction notation `A → B`.New modules-----------* A hierarchy for algebraic modules:```Algebra.ModuleAlgebra.Module.BundlesAlgebra.Module.ConsequencesAlgebra.Module.Construct.BiproductAlgebra.Module.Construct.TensorUnitAlgebra.Module.Construct.ZeroAlgebra.Module.DefinitionsAlgebra.Module.Definitions.BiAlgebra.Module.Definitions.LeftAlgebra.Module.Definitions.RightAlgebra.Module.StructuresAlgebra.Module.Structures.Biased```Supported are all of {left, right, bi} {semi} modules.* Morphisms over group and ring-like algebraic structures:```agdaAlgebra.Morphism.GroupMonomorphismAlgebra.Morphism.RingMonomorphism```* Bisimilarity relation for `Cowriter`.```agdaCodata.Cowriter.Bisimilarity```* Wrapper for the erased modality, allows the storage of erased proofsin a record and the use of projections to manipulate them without havingto turn on the unsafe option `--irrelevant-projections`.```agdaData.Erased```* Induction over finite subsets:```agdaData.Fin.Subset.Induction```* Unary predicate for lists in which all related elements are grouped together.```agdaData.List.Relation.Unary.GroupedData.List.Relation.Unary.Grouped.Properties```* Unary predicate for products in which the components both satisfy individualunary predicates.```agdaData.Product.Relation.Unary.All```* New data type for dependent products in which the second component is irrelevant.```agdaData.RefinementData.Refinement.Relation.Unary.All```* New data type for binary and rose trees:```agdaData.Tree.BinaryData.Tree.Binary.PropertiesData.Tree.Binary.Relation.Unary.AllData.Tree.Binary.Relation.Unary.All.PropertiesData.Tree.RoseData.Tree.Rose.Properties```* New properties and functions over floats and words.```agdaData.Float.BaseData.Float.PropertiesData.Word.BaseData.Word.Properties```* Helper methods for using reflection with numeric data.```agdaData.Nat.ReflectionData.Fin.Reflection```* Finer-grained breakdown of the reflection primitives, alongsidenew utility functions for writing macros.```agdaReflection.AbstractionReflection.ArgumentReflection.Argument.InformationReflection.Argument.RelevanceReflection.Argument.VisibilityReflection.DefinitionReflection.LiteralReflection.MetaReflection.NameReflection.PatternReflection.TermReflection.TypeChecking.MonadSyntax```* New tactics for monoid and ring solvers. See `README.Tactic.MonoidSolver/RingSolver` for details```agdaTactic.MonoidSolverTactic.RingSolverTactic.RingSolver.NonReflective```Other major changes-------------------#### Improved performance of decision processes* All definitions branching on a `Dec` value have been rewritten, wherever possible,to branch only on the boolean `does` field. Furthermore, branching onthe `proof` field has been made as late as possible, using the `invert` lemma from`Relation.Nullary.Reflects`.* For example, the old definition of `filter` in `Data.List.Base` used the`yes` and `no` patterns, which desugared to the following:```agdafilter : ∀ {P : Pred A p} → Decidable P → List A → List Afilter P? [] = []filter P? (x ∷ xs) with P? x... | false because ofⁿ _ = filter P? xs... | true because ofʸ _ = x ∷ filter P? xs```Because the proofs (`ofⁿ _` and `ofʸ _`) are not giving us any information,we do not need to match on them. We end up with the following definition,where the `proof` field has been projected away.```agdafilter : ∀ {P : Pred A p} → Decidable P → List A → List Afilter P? [] = []filter P? (x ∷ xs) with does (P? x)... | false = filter P? xs... | true = x ∷ filter P? xs```Correspondingly, when proving a property of `filter`, we can often make asimilar change, but sometimes need the proof eventually. The followingexample is adapted from `Data.List.Membership.Setoid.Properties`.```agdaopen Membership S using (_∈_)∈-filter⁺ : ∀ {v xs} → v ∈ xs → P v → v ∈ filter P? xs∈-filter⁺ {xs = x ∷ _} (here v≈x) Pv with P? x-- There is no matching on the proof, so we can emit the result without-- computing the proof at all.... | true because _ = here v≈x-- `invert` is used to get the proof just when it is needed.... | false because [¬Px] = contradiction (resp v≈x Pv) (invert [¬Px])-- In the remaining cases, we make no use of the proof.∈-filter⁺ {xs = x ∷ _} (there v∈xs) Pv with does (P? x)... | true = there (∈-filter⁺ v∈xs Pv)... | false = ∈-filter⁺ v∈xs Pv```#### Other* The module `Reflection` is no longer `--unsafe`.* Standardised the `Eq` modules in structures and bundles in `Relation.Binary` hierarchy.- `IsDecTotalOrder.Eq` now exports `isDecPartialOrder`.- `DecSetoid.Eq` now exports `partialSetoid` and `_≉_`.- `Poset.Eq` and `TotalOrder.Eq` now export `setoid`.- `DecTotalOrder.Eq` and `StrictTotalOrder.Eq` now export `decSetoid`.- `DecTotalOrder.decSetoid` is now deprecated in favour of the above `DecTotalOrder.Eq.decSetoid`.Other minor additions---------------------* Added new record to `Algebra.Bundles`:```agda+-rawGroup : RawGroup c ℓ```and the `CommutativeMonoid` record now exports `commutativeSemigroup`.* Added new definition to `Algebra.Definitions`:```agdaInterchangable _∘_ _∙_ = ∀ w x y z → ((w ∙ x) ∘ (y ∙ z)) ≈ ((w ∘ y) ∙ (x ∘ z))```* Added new records to `Algebra.Morphism.Structures`:```agdaIsGroupHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsGroupMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsGroupIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)IsRingHomomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsRingMonomorphism (⟦_⟧ : A → B) : Set (a ⊔ ℓ₁ ⊔ ℓ₂)IsRingIsomorphism (⟦_⟧ : A → B) : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂)```* Added new proofs to `Algebra.Properties.Group`:```agda⁻¹-injective : x ⁻¹ ≈ y ⁻¹ → x ≈ y⁻¹-anti-homo-∙ : (x ∙ y) ⁻¹ ≈ y ⁻¹ ∙ x ⁻¹```* In `Algebra.Structures` the record `IsCommutativeSemiring` nowexports `*-isCommutativeSemigroup`.* Made `RawFunctor`, `RawApplicative` and `IFun` more level polymorphicin `Category.Functor`, `Category.Applicative` and `Category.Applicative.Indexed`respectively.* Added new functions to `Codata.Colist`:```agdadrop : ℕ → Colist A ∞ → Colist A ∞concat : Colist (List⁺ A) i → Colist A i```* Added new definitions to `Codata.Colist.Bisimilarity`:```agdafromEq : as ≡ bs → i ⊢ as ≈ bsisEquivalence : IsEquivalence R → IsEquivalence (Bisim R i)setoid : Setoid a r → Size → Setoid a (a ⊔ r)module ≈-Reasoning++⁺ : Pointwise R as bs → Bisim R i xs ys → Bisim R i (fromList as ++ xs) (fromList bs ++ ys)⁺++⁺ : Pointwise R (toList as) (toList bs) → Thunk^R (Bisim R) i xs ys → Bisim R i (as ⁺++ xs) (bs ⁺++ ys)```* Added new proofs to `Codata.Colist.Properties`:```agdafromCowriter∘toCowriter≗id : i ⊢ fromCowriter (toCowriter as) ≈ aslength-∷ : i ⊢ length (a ∷ as) ≈ 1 ℕ+ length (as .force)length-replicate : i ⊢ length (replicate n a) ≈ nlength-++ : i ⊢ length (as ++ bs) ≈ length as + length bslength-map : i ⊢ length (map f as) ≈ length aslength-scanl : i ⊢ length (scanl c n as) ≈ 1 ℕ+ length asreplicate-+ : i ⊢ replicate (m + n) a ≈ replicate m a ++ replicate n amap-replicate : i ⊢ map f (replicate n a) ≈ replicate n (f a)lookup-replicate : All (a ≡_) (lookup k (replicate n a))map-unfold : i ⊢ map f (unfold alg a) ≈ unfold (Maybe.map (Prod.map₂ f) ∘ alg) aunfold-nothing : alg a ≡ nothing → unfold alg a ≡ []unfold-just : alg a ≡ just (a′ , b) → i ⊢ unfold alg a ≈ b ∷ λ where .force → unfold alg a′scanl-unfold : i ⊢ scanl cons nil (unfold alg a) ≈ nil ∷ (λ where .force → unfold alg′ (a , nil))map-alignWith : i ⊢ map f (alignWith al as bs) ≈ alignWith (f ∘ al) as bslength-alignWith : i ⊢ length (alignWith al as bs) ≈ length as ⊔ length bsmap-zipWith : i ⊢ map f (zipWith zp as bs) ≈ zipWith (λ a → f ∘ zp a) as bslength-zipWith : i ⊢ length (zipWith zp as bs) ≈ length as ⊓ length bsdrop-nil : i ⊢ drop {A = A} m [] ≈ []drop-drop-fusion : i ⊢ drop n (drop m as) ≈ drop (m ℕ.+ n) asmap-drop : i ⊢ map f (drop m as) ≈ drop m (map f as)length-drop : i ⊢ length (drop m as) ≈ length as ∸ mlength-cotake : i ⊢ length (cotake n as) ≈ nmap-cotake : i ⊢ map f (cotake n as) ≈ cotake n (Stream.map f as)drop-fromList-++-identity : drop (length as) (fromList as ++ bs) ≡ bsdrop-fromList-++-≤ : m ≤ length as → drop m (fromList as ++ bs) ≡ fromList (drop m as) ++ bsdrop-fromList-++-≥ : m ≥ length as → drop m (fromList as ++ bs) ≡ drop (m ∸ length as) bsdrop-⁺++-identity : drop (length as) (as ⁺++ bs) ≡ bs .forcemap-chunksOf : i ⊢ map (map f) (map f) (chunksOf n as) ≈ chunksOf n (map f as)fromList-++ : i ⊢ fromList (as ++ bs) ≈ fromList as ++ fromList bsfromList-scanl : i ⊢ scanl c n (fromList as) ≈ fromList (scanl c n as)map-fromList : i ⊢ map f (fromList as) ≈ fromList (map f as)length-fromList : i co⊢ length (fromList as) ≈ fromℕ (length as)fromStream-++ : i ⊢ fromStream (as ++ bs) ≈ fromList as ++ fromStream bsfromStream-⁺++ : i ⊢ fromStream (as ⁺++ bs) ≈ fromList⁺ as ++ fromStream (bs .force)fromStream-concat : i ⊢ concat (fromStream ass) ≈ fromStream (concat ass)fromStream-scanl : i ⊢ scanl c n (fromStream as) ≈ fromStream (scanl c n as)map-fromStream : i ⊢ map f (fromStream as) ≈ fromStream (map f as)```* Added new definitions to `Codata.Conat.Bisimilarity`:```agdaisEquivalence : IsEquivalence (i ⊢_≈_)setoid : Size → Setoid 0ℓ 0ℓmodule ≈-Reasoning```* Added new proof to `Codata.Conat.Properties`:```agda0∸m≈0 : ∀ m → i ⊢ zero ∸ m ≈ zero```* Added new proofs to `Data.Bool`:```agdanot-injective : not x ≡ not y → x ≡ y```* Added new function to `Data.Difference.List`:```agda_∷ʳ_ : DiffList A → A → DiffList A```* Added new properties to `Data.Fin.Properties`:```agdalift-injective : (∀ {x y} → f x ≡ f y → x ≡ y) → ∀ k {x y} → lift k f x ≡ lift k f y → x ≡ yinject+-raise-splitAt : [ inject+ n , raise {n} m ] (splitAt m i) ≡ i```* Added new properties to `Data.Fin.Subset`:```agda_⊂_ : Subset n → Subset n → Set_⊄_ : Subset n → Subset n → Set```* Added new proofs to `Data.Fin.Subset.Properties`:```agdas⊆s : p ⊆ q → s ∷ p ⊆ s ∷ q∣p∣≡n⇒p≡⊤ : ∣ p ∣ ≡ n → p ≡ ⊤p∪∁p≡⊤ : p ∪ ∁ p ≡ ⊤∣∁p∣≡n∸∣p∣ : ∣ ∁ p ∣ ≡ n ∸ ∣ p ∣x∈p⇒x∉∁p : x ∈ p → x ∉ ∁ px∈∁p⇒x∉p : x ∈ ∁ p → x ∉ px∉∁p⇒x∈p : x ∉ ∁ p → x ∈ px∉p⇒x∈∁p : x ∉ p → x ∈ ∁ px≢y⇒x∉⁅y⁆ : x ≢ y → x ∉ ⁅ y ⁆x∉⁅y⁆⇒x≢y : x ∉ ⁅ y ⁆ → x ≢ y∣p∩q∣≤∣p∣ : ∣ p ∩ q ∣ ≤ ∣ p ∣∣p∩q∣≤∣q∣ : ∣ p ∩ q ∣ ≤ ∣ q ∣∣p∩q∣≤∣p∣⊓∣q∣ : ∣ p ∩ q ∣ ≤ ∣ p ∣ ⊓ ∣ q ∣∣p∣≤∣p∪q∣ : ∣ p ∣ ≤ ∣ p ∪ q ∣∣q∣≤∣p∪q∣ : ∣ q ∣ ≤ ∣ p ∪ q ∣∣p∣⊔∣q∣≤∣p∪q∣ : ∣ p ∣ ⊔ ∣ q ∣ ≤ ∣ p ∪ q ∣```* Added new proofs to `Data.Integer.Properties`:```agdasuc[i]≤j⇒i<j : sucℤ i ≤ j → i < ji<j⇒suc[i]≤j : i < j → sucℤ i ≤ j```* Added new functions to `Data.List`:```agdaderun : B.Decidable R → List A → List Adeduplicate : Decidable _R_ → List A → List A```* Added new proofs to `Data.List.Relation.Binary.Equality.Setoid`:```agdaAny-resp-≋ : P Respects _≈_ → (Any P) Respects _≋_All-resp-≋ : P Respects _≈_ → (All P) Respects _≋_AllPairs-resp-≋ : R Respects₂ _≈_ → (AllPairs R) Respects _≋_Unique-resp-≋ : Unique Respects _≋_```* Added new functions to `Data.List.Base`:```agda_?∷_ : Maybe A → List A → List A_∷ʳ?_ : List A → Maybe A → List A```* Added new proofs to `Data.List.Membership.Propositional.Properties`:```agda∈-derun⁺ : z ∈ xs → z ∈ derun R? xs∈-deduplicate⁺ : z ∈ xs → z ∈ deduplicate _≟_ xs∈-derun⁻ : z ∈ derun R? xs → z ∈ xs∈-deduplicate⁻ : z ∈ deduplicate R? xs → z ∈ xs```* Added new proofs to `Data.List.Membership.Setoid.Properties`:```agda∈-derun⁺ : _≈_ Respectsʳ R → z ∈ xs → z ∈ derun R? xs∈-deduplicate⁺ : _≈_ Respectsʳ (flip R) → z ∈ xs → z ∈ deduplicate R? xs∈-derun⁻ : z ∈ derun R? xs → z ∈ xs∈-deduplicate⁻ : z ∈ deduplicate R? xs → z ∈ xs```* Added new proofs to `Data.List.Relation.Unary.All.Properties`:```agdaderun⁺ : All P xs → All P (derun Q? xs)deduplicate⁺ : All P xs → All P (deduplicate Q? xs)filter⁻ : All Q (filter P? xs) → All Q (filter (¬? ∘ P?) xs) → All Q xsderun⁻ : All P (derun Q? xs) → All P xsdeduplicate⁻ : All P (deduplicate Q? xs) → All P xs```* Added new proofs to `Data.List.Relation.Unary.Any.Properties`:```agdalookup-result : (p : Any P xs) → P (lookup p)filter⁺ : (p : Any P xs) → Any P (filter Q? xs) ⊎ ¬ Q (Any.lookup p)derun⁺ : P Respects Q → Any P xs → Any P (derun Q? xs)deduplicate⁺ : P Respects (flip Q) → Any P xs → Any P (deduplicate Q? xs)filter⁻ : Any P (filter Q? xs) → Any P xsderun⁻ : Any P (derun Q? xs) → Any P xsdeduplicate⁻ : Any P (deduplicate Q? xs) → Any P xs```* The implementation of `↭-trans` has been altered in`Data.List.Relation.Binary.Permutation.Inductive` to avoidadding unnecessary `refl`s, hence improving it's performance.* Added new functions to `Data.List.Relation.Binary.Permutation.Setoid`:```agda↭-prep : xs ↭ ys → x ∷ xs ↭ x ∷ ys↭-swap : xs ↭ ys → x ∷ y ∷ xs ↭ y ∷ x ∷ yssteps : xs ↭ ys → ℕ```* Added new combinators to `PermutationReasoning` in `Data.List.Relation.Binary.Permutation.Setoid`:```agda_≋⟨_⟩_ : x ≋ y → y IsRelatedTo z → x IsRelatedTo z_≋˘⟨_⟩_ : y ≋ x → y IsRelatedTo z → x IsRelatedTo z```* Added new functions to ` Data.List.Relation.Binary.Permutation.Setoid.Properties`:```agda0<steps : (xs↭ys : xs ↭ ys) → 0 < steps xs↭yssteps-respˡ : (ys≋xs : ys ≋ xs) (ys↭zs : ys ↭ zs) → steps (↭-respˡ-≋ ys≋xs ys↭zs) ≡ steps ys↭zssteps-respʳ : (xs≋ys : xs ≋ ys) (zs↭xs : zs ↭ xs) → steps (↭-respʳ-≋ xs≋ys zs↭xs) ≡ steps zs↭xssplit : xs ↭ as ++ [ v ] ++ bs → ∃₂ λ ps qs → xs ≋ ps ++ [ v ] ++ qsdropMiddle : ws ++ vs ++ ys ↭ xs ++ vs ++ zs → ws ++ ys ↭ xs ++ zsdropMiddleElement : ws ++ [ v ] ++ ys ↭ xs ++ [ v ] ++ zs → ws ++ ys ↭ xs ++ zsdropMiddleElement-≋ : ws ++ [ v ] ++ ys ≋ xs ++ [ v ] ++ zs → ws ++ ys ↭ xs ++ zsfilter⁺ : xs ↭ ys → filter P? xs ↭ filter P? ys```* Added new proofs to `Data.List.Relation.Binary.Pointwise`:```agdaAny-resp-Pointwise : P Respects _∼_ → (Any P) Respects (Pointwise _∼_)All-resp-Pointwise : P Respects _∼_ → (All P) Respects (Pointwise _∼_)AllPairs-resp-Pointwise : R Respects₂ _∼_ → (AllPairs R) Respects (Pointwise _∼_)```* Added new proofs to `Data.Maybe.Properties`:```agdamap-nothing : ma ≡ nothing → map f ma ≡ nothingmap-just : ma ≡ just a → map f ma ≡ just (f a)```* Added new proofs to `Data.Nat.DivMod`:```agda%-distribˡ-* : (m * n) % d ≡ ((m % d) * (n % d)) % d```* Added new proofs to `Data.Nat.Properties`:```agdam<n+m : n > 0 → m < n + m∸-cancelʳ-≡ : o ≤ m → o ≤ n → m ∸ o ≡ n ∸ o → m ≡ n⌊n/2⌋+⌈n/2⌉≡n : ⌊ n /2⌋ + ⌈ n /2⌉ ≡ n⌊n/2⌋≤n : ⌊ n /2⌋ ≤ n⌊n/2⌋<n : ⌊ suc n /2⌋ < suc n⌈n/2⌉≤n : ⌈ n /2⌉ ≤ n⌈n/2⌉<n : ⌈ suc (suc n) /2⌉ < suc (suc n)⌊n/2⌋≤⌈n/2⌉ : ⌊ n /2⌋ ≤ ⌈ n /2⌉⊔-pres-≤m : n ≤ m → o ≤ m → n ⊔ o ≤ m⊔-pres-<m : n < m → o < m → n ⊔ o < m⊓-pres-m≤ : m ≤ n → m ≤ o → m ≤ n ⊓ o⊓-pres-m< : m < n → m < o → m < n ⊓ o*-isCommutativeSemigroup : IsCommutativeSemigroup _*_*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ```* Added new data and functions to `Data.String.Base`:```agdadata Alignment : SetfromAlignment : Alignment → ℕ → String → Stringparens : String → StringparensIfSpace : String → Stringbraces : String → Stringintersperse : String → List String → Stringunwords : List String → String_<+>_ : String → String → StringpadLeft : Char → ℕ → String → StringpadRight : Char → ℕ → String → StringpadBoth : Char → Char → ℕ → String → Stringrectangle : Vec (ℕ → String → String) n → Vec String n → Vec String nrectangleˡ : Char → Vec String n → Vec String nrectangleʳ : Char → Vec String n → Vec String nrectangleᶜ : Char → Char → Vec String n → Vec String n```* Added new proofs to `Data.String.Unsafe`:```agdatoList-++ : toList (s ++ t) ≡ toList s ++ toList tlength-++ : length (s ++ t) ≡ length s + length tlength-replicate : length (replicate n c) ≡ n```* Added new proof to `Data.Sum.Properties`:```agda[,]-∘-distr : f ∘ [ g , h ] ≗ [ f ∘ g , f ∘ h ][,]-map-commute : [ f′ , g′ ] ∘ (map f g) ≗ [ f′ ∘ f , g′ ∘ g ]map-commute : ((map f′ g′) ∘ (map f g)) ≗ map (f′ ∘ f) (g′ ∘ g)```* Improved the universe polymorphism of`Data.Product.Relation.Binary.Lex.Strict/NonStrict`so that the equality and order relations need not live at thesame universe level.* Added new proofs to `Data.Product.Relation.Binary.Lex.Strict`:```×-wellFounded : WellFounded _<₁_ → WellFounded _<₂_ → WellFounded _<ₗₑₓ_```* Added new proofs to `Data.Rational.Properties`:```agda↥-* : ↥ (p * q) ℤ.* *-nf p q ≡ ↥ p ℤ.* ↥ q↧-* : ↧ (p * q) ℤ.* *-nf p q ≡ ↧ p ℤ.* ↧ qtoℚᵘ-homo-* : Homomorphic₂ toℚᵘ _*_ ℚᵘ._*_toℚᵘ-isMagmaHomomorphism-* : IsMagmaHomomorphism *-rawMagma ℚᵘ.*-rawMagma toℚᵘtoℚᵘ-isMonoidHomomorphism-* : IsMonoidHomomorphism *-rawMonoid ℚᵘ.*-rawMonoid toℚᵘtoℚᵘ-isMonoidMonomorphism-* : IsMonoidMonomorphism *-rawMonoid ℚᵘ.*-rawMonoid toℚᵘtoℚᵘ-homo‿- : Homomorphic₁ toℚᵘ (-_) (ℚᵘ.-_)toℚᵘ-isGroupHomomorphism-+ : IsGroupHomomorphism +-0-rawGroup ℚᵘ.+-0-rawGroup toℚᵘtoℚᵘ-isGroupMonomorphism-+ : IsGroupMonomorphism +-0-rawGroup ℚᵘ.+-0-rawGroup toℚᵘtoℚᵘ-isRingHomomorphism-|-* : IsRingHomomorphism +-*-rawRing ℚᵘ.+-*-rawRing toℚᵘtoℚᵘ-isRingMonomorphism-|-* : IsRingMonomorphism +-*-rawRing ℚᵘ.+-*-rawRing toℚᵘ*-assoc : Associative _*_*-comm : Commutative _*_*-identityˡ : LeftIdentity 1ℚ _*_*-identityʳ : RightIdentity 1ℚ _*_*-identity : Identity 1ℚ _*_+-inverseˡ : LeftInverse 0ℚ -_ _+_+-inverseʳ : RightInverse 0ℚ -_ _+_+-inverse : Inverse 0ℚ -_ _+_-‿cong : Congruent₁ (-_)*-isMagma : IsMagma _*_*-isSemigroup : IsSemigroup _**-1-isMonoid : IsMonoid _*_ 1ℚ*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1ℚ*-rawMagma : RawMagma 0ℓ 0ℓ*-rawMonoid : RawMonoid 0ℓ 0ℓ+-0-rawGroup : RawGroup 0ℓ 0ℓ+-*-rawRing : RawRing 0ℓ 0ℓ+-0-isGroup : IsGroup _+_ 0ℚ (-_)+-0-isAbelianGroup : IsAbelianGroup _+_ 0ℚ (-_)+-0-isRing : IsRing _+_ _*_ -_ 0ℚ 1ℚ+-0-group : Group 0ℓ 0ℓ+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distribʳ-+ : _*_ DistributesOverʳ _+_*-distrib-+ : _*_ DistributesOver _+_*-magma : Magma 0ℓ 0ℓ*-semigroup : Semigroup 0ℓ 0ℓ*-1-monoid : Monoid 0ℓ 0ℓ*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ+-*-isRing : IsRing _+_ _*_ -_ 0ℚ 1ℚ+-*-ring : Ring 0ℓ 0ℓ```* Added new proofs to `Data.Rational.Unnormalised.Properties`:```agda+-inverseˡ : LeftInverse _≃_ 0ℚᵘ -_ _+_+-inverseʳ : RightInverse _≃_ 0ℚᵘ -_ _+_+-inverse : Inverse _≃_ 0ℚᵘ -_ _+_-‿cong : Congruent₁ _≃_ (-_)+-0-isGroup : IsGroup _≃_ _+_ 0ℚᵘ (-_)+-0-group : Group 0ℓ 0ℓ+-0-isAbelianGroup : IsAbelianGroup _≃_ _+_ 0ℚᵘ (-_)+-0-abelianGroup : AbelianGroup 0ℓ 0ℓ*-zeroˡ : LeftZero _≃_ 0ℚᵘ _*_*-zeroʳ : RightZero _≃_ 0ℚᵘ _*_*-zero : Zero _≃_ 0ℚᵘ _*_*-distribˡ-+ : _DistributesOverˡ_ _≃_ _*_ _+_*-distribʳ-+ : _DistributesOverʳ_ _≃_ _*_ _+_*-distrib-+ : _DistributesOver_ _≃_ _*_ _+_+-*-isRing : IsRing _≃_ _+_ _*_ -_ 0ℚᵘ 1ℚ+-*-ring : Ring 0ℓ 0ℓ+-0-rawGroup : RawGroup 0ℓ 0ℓ+-*-rawRing : RawRing 0ℓ 0ℓ+-*-isCommutativeRing : IsCommutativeRing _≃_ _+_ _*_ -_ 0ℚᵘ 1ℚᵘ+-*-commutativeRing : CommutativeRing 0ℓ 0ℓ```* Added new functions to `Data.Vec.Base`:```agdauncons : Vec A (suc n) → A × Vec A nlength : Vec A n → ℕtranspose : Vec (Vec A n) m → Vec (Vec A m) n```* Added new functions to `Data.Vec.Bounded.Base`:```agdatake : n → Vec≤ A m → Vec≤ A (n ⊓ m)drop : n → Vec≤ A m → Vec≤ A (m ∸ n)padLeft : A → Vec≤ A n → Vec A npadRight : A → Vec≤ A n → Vec A npadBoth : ∀ {n} → A → A → Vec≤ A n → Vec A nrectangle : List (∃ (Vec≤ A)) → ∃ (List ∘ Vec≤ A)```* Added new definitions to `Data.Word.Base`:```agda_≈_ : Rel Word64 zero_<_ : Rel Word64 zero```* Added utility function to `Function.Base`:```agdait : {A : Set a} → {{A}} → A```* Added new definitions to `Function.Bundles`:```agdarecord BiInverserecord BiEquivalence_↩↪_ : Set a → Set b → Set _mk↩↪ : Inverseˡ f g₁ → Inverseʳ f g₂ → A ↩↪ B```* Added new definitions to `Function.Structures`:```agdarecord IsBiEquivalence (f : A → B) (g₁ : B → A) (g₂ : B → A)record IsBiInverse (f : A → B) (g₁ : B → A) (g₂ : B → A)```* Added new proofs to `Induction.WellFounded`:```agdaAcc-resp-≈ : Symmetric _≈_ → _<_ Respectsʳ _≈_ → (Acc _<_) Respects _≈_some-wfRec-irrelevant : Some.wfRec P f x q ≡ Some.wfRec P f x q'wfRecBuilder-wfRec : All.wfRecBuilder P f x y y<x ≡ All.wfRec P f yunfold-wfRec : All.wfRec P f x ≡ f x λ y _ → All.wfRec P f y```* Added new definition in `Relation.Binary.Core`:```agdaDecidableEquality A = Decidable {A = A} _≡_```* Added new proofs to `Relation.Binary.Construct.Union`:```agdarespˡ : L Respectsˡ ≈ → R Respectsˡ ≈ → (L ∪ R) Respectsˡ ≈respʳ : L Respectsʳ ≈ → R Respectsʳ ≈ → (L ∪ R) Respectsʳ ≈resp₂ : L Respects₂ ≈ → R Respects₂ ≈ → (L ∪ R) Respects₂ ≈```* Added new proof to `Relation.Binary.Setoid.Properties`:```agda≉-resp₂ : _≉_ Respects₂ _≈_```* Added a new proof to `Relation.Nullary.Decidable`:```agdaisYes≗does : (P? : Dec P) → isYes P? ≡ does P?```
Version 1.2===========The library has been tested using Agda version 2.6.0.1.Highlights----------* New function hierarchy.* New (homo/mono/iso)morphism infrastructure for algebraic and relational structures.* Fresh lists.* First proofs of algebraic properties for operations over ℚ.* Improved reduction behaviour for all decidability proofs.Bug-fixes---------* The record `RawRing` from `Algebra` now includes an equality relation tomake it consistent with the othor `Raw` bundles.* In `Relation.Binary`:- `IsStrictTotalOrder` now exports `isDecStrictPartialOrder`- `IsDecStrictPartialOrder` now re-exports the contents of `IsStrictPartialOrder`.* Due to bug #3879 in Agda, the pattern synonyms `0F`, `1F`, ... added to`Data.Fin.Base` in version 1.1 resulted in unavoidable and undesirable behaviourwhen case splitting on `ℕ` when `Data.Fin` has been imported. These patternsynonyms have therefore been moved to the new module `Data.Fin.Patterns`.Non-backwards compatible changes--------------------------------### Standardisation of record hierarchies* The modules containing the record hierarchies for algebra, binary relations,and functions are currently inconsistently structured. For example:- in the binary relation record hierarchy the module `Relation.Binary`exports all parts of the hierarchy, e.g. `Reflexive`, `IsPreorder` and`Preorder`.- in contrast the algebra record hierarchy `Associative` is exportedfrom `Algebra.FunctionProperties`, `IsSemigroup` from `Algebra.Structures`and `Semigroup` from `Algebra`.- the function hiearchy doesn't have a notion of `Injective` and `IsInjective`at all, and `Injection` is exported from `Function.Injection`.* Consequently all hierarchies have been re-organised to follow thesame standard pattern:```agdaX.Core -- Contains: Rel, Op₂, Fun etc.X.Definitions -- Contains: Reflexive, Associative, Injective etc.X.Structures -- Contains: IsEquivalence, IsSemigroup, IsInjection etc.X.Bundles -- Contains: Setoid, Semigroup, Injection etc.X -- Publicly re-exports all of the above```* In `Relation.Binary` this means:* New module `Relation.Binary.Bundles`* New module `Relation.Binary.Definitions`* Fully backwards compatible.* In `Algebra` this means:* `Algebra.FunctionProperties.Core` has been deprecated in favour of `Algebra.Core`.* `Algebra.FunctionProperties` has been deprecated in favour of `Algebra.Definitions`.* The contents of `Algebra` has been moved to `Algebra.Bundles`.* `Algebra` now re-exports the contents of `Algebra.Definitions` and `Algebra.Structures`,not just that of `Algebra.Bundles`.* **Compatibility:** Modules which previously imported both `Algebra` and`Algebra.FunctionProperties` and/or `Algebra.Structures` will need small changes.- If either of `FunctionProperties` or `Structures` are explicitly parameterised by anequality relation then import `Algebra.Bundles` instead of `Algebra`.- Otherwise just remove the `FunctionProperties` and `Structures` imports entirely.### New function hierarchy* The problems with the current function hierarchy run deeper problems than the other two:1. The raw functions are wrapped in the equality-preservingtype `_⟶_` from `Function.Equality`. As the rest of the libraryrarely uses such wrapped functions, it is very difficultto write code that interfaces neatly between the `Function` hierarchyand, for example, the `Algebra` hierarchy.2. The hierarchy doesn't follow the same pattern as the other recordhierarchies in the standard library, e.g. `Injective`, `IsInjection`and `Injection`. Coupled with point 1., anecdotally this means thatpeople find it difficult to understand and use.3. There is no way of specifying a function has a specific property(e.g. injectivity) without specifying all the properties requiredof the equality relation as well. This is in contrast to the`Relation.Binary` and `Algebra` hierarchies where it is perfectlypossible to specify that for example an operation is commutativewithout providing all the proofs associated with the equality relation.4. In many fonts the symbol `_⟶_` used for equality preserving functionsis almost indistinguishable from the symbol for ordinary functions `_→_`,leading to confusion when reading code.* To address these problems a new standardised function hierarchy has beencreated that follows the same structure found in `Relation.Binary` and `Algebra`.In particular:- The `Fun1` and `Fun2` from `Function` have been moved to `Function.Core`.- The rest of the old contents of `Function` have been moved to `Function.Base`.- Added a new module `Function.Definitions` containing definitions like`Injective`, `Surjective` which are parameterised by the equality relationsover the domain and codomain.- Added a new module `Function.Structures` containing definitions like`IsInjection`, `IsSurjection`, once again parameterised the equality relations.- New module `Function.Bundles` containing definitions like `Injection`, `Surjection`which provide essentially the same top-level interface as currently exists,i.e. parameterised by setoids but hiding the function.- The module `Function` now re-exports all of the above.* For the moment the existing modules containing the old hierarchy still exist,as not all existing functionality has been reimplemented using the new hierarchy.However it is expected that they will be deprecated at some point in the futurewhen contents this transfer is complete.```agdaFunction.EquivalenceFunction.EqualityFunction.BijectionFunction.InjectionFunction.SurjectionFunction.LeftInverse```* **Compatibility:** As most of changes involve adding new modules, the only problemthat occurs is when importing both `Function` and e.g. `Function.Injection`. In thiscase the old and new definitions of `Injection` will clash. In the short term thiscan be fixed immediately by importing `Function.Base` instead of `Function`.However in the longer term it is encouraged to migrate away from `Function.Injection`and to use the new hierarchy instead.* Finally the propositional bundle for left inverses in `Function.Bundles` has beenrenamed in the new hierarchy from `_↞_` to `_↩_`. This is in order to make room forthe new bundle for right inverse `_↪_`.#### Harmonizing `List.All` and `Vec` in their role as finite maps.* The function `updateAt` in `Data.List.Relation.Unary.All` is analogousto `updateAt` in `Data.Vec.Base` and hence the API for the former hasbeen refactored to match the latter.* Added a new "points-to" relation `_[_]=_` in `Data.List.Relation.Unary.All`:```agda_[_]=_ : All P xs → x ∈ xs → P x → Set _```* In `Data.List.Relation.Unary.All.Properties` the proofs `updateAt-cong`and `updateAt-updates` are now formulated in terms of the new `_[_]=_`relation rather than the function `lookup`. The old proofs are available withminor variations under the names `lookup∘updateAt` and `updateAt-cong-relative`.#### Other* Version 1.1 in the library added irrelevance to various places in the library.Unfortunately this exposed the library to several irrelevance-related bugs.The decision has therefore been taken to roll-back these additions untilirrelevance is more stable. In particular it has been removed from`_%_`, `_/_`, `_div_`, `_mod_` in `Data.Nat.DivMod` and from `fromℕ≤`, `inject≤`in `Data.Fin.Base`.* The proofs `isPreorder` and `preorder` have been moved from the `Setoid`record to the module `Relation.Binary.Properties.Setoid`.* The function `normalize` in `Data.Rational.Base` has been reimplementedin terms of a direct division of the numerator and denominator by theirGCD. Although less elegant than the previous implementation, it'sreduction behaviour is much easier to reason about.Re-implementations and deprecations-------------------------------### `Data.Bin` → `Data.Nat.Binary`* The current implementation of binary naturals in Agda has proven hard to work with.Therefore a new, simpler implementation which avoids using `List` has been addedas `Data.Nat.Binary`.```agdaData.Nat.BinaryData.Nat.Binary.BaseData.Nat.Binary.InductionData.Nat.Binary.Properties```* The old modules still exist but have been deprecated and may be removed insome future release of the library.```agdaData.BinData.Bin.Properties```### `Data.Table` → `Data.Vec.Functional`* As well as having a non-standard name, the definition of `Table` in `Data.Table`has proved very difficult to work with due to the wrapping of the type in a record.It has therefore been renamed and reimplemented without the record wrapper as the`Vector` type in the new module `Data.Vec.Functional`,```agdaData.Vec.FunctionalData.Vec.Functional.Relation.Binary.PointwiseData.Vec.Functional.Relation.Unary.AllData.Vec.Functional.Relation.Unary.Any```* The old modules still exist but have been deprecated and may be removed insome future release of the library.```agdaData.TableData.Table.BaseData.Table.PropertiesData.Table.Relation.Equality```### `Data.BoundedVec(.Inefficient)` → `Data.Vec.Bounded`* `Data.BoundedVec` and `Data.BoundedVec.Inefficient` have been deprecatedin favour of `Data.Vec.Bounded` introduced in version 1.1.```agdaData.Vec.BoundedData.Vec.Bounded.Base```* The old modules still exist but have been deprecated and may be removed insome future release of the library.```agdaData.BoundedVecData.BoundedVec.Inefficient```Other major additions---------------------### `Reflects` idiom for decidability proofs* A version of the `Reflects` idiom, as seen in SSReflect, has been introducedin `Relation.Nullary`. Some properties of it have been added in the new module`Relation.Nullary.Reflects`. The definition is as follows```agdadata Reflects {p} (P : Set p) : Bool → Set p whereofʸ : ( p : P) → Reflects P trueofⁿ : (¬p : ¬ P) → Reflects P false```* `Dec` has been redefined in terms of `Reflects`.```agdarecord Dec {p} (P : Set p) : Set p whereconstructor _because_fielddoes : Boolproof : Reflects P doesopen Dec public```which is entirely backwards compatible thanks to the introduction ofthe pattern synonyms in `Relation.Nullary`:```agdapattern yes p = true because ofʸ ppattern no ¬p = false because ofⁿ ¬p```* These changes mean that decision procedures can be defined so as to provide aboolean result that is independent of the proof that it is the correct decision.For example, a proof of decidability of `_≤_` on natural numbers:```agda_≤?_ : (m n : ℕ) → Dec (m ≤ n)zero ≤? n = yes z≤nsuc m ≤? zero = no λ ()suc m ≤? suc n with m ≤? n... | yes p = yes (s≤s p)... | no ¬p = no (¬p ∘ ≤-pred)```can now be rewritten as:```agda_≤?_ : (m n : ℕ) → Dec (m ≤ n)zero ≤? n = yes z≤nsuc m ≤? zero = no λ ()does (suc m ≤? suc n) = does (m ≤? n)proof (suc m ≤? suc n) with m ≤? n... | yes p = ofʸ (s≤s p)... | no ¬p = ofⁿ (¬p ∘ ≤-pred)```Notice that projecting the `does` field, returns a function whose reductionbehaviour is identically to what we would expect of a boolean test. This hassignificant advantages for both performance and reasoning in situations whereonly a decision is required and the proof itself is not needed.* Functions and lemmas about `Dec` have been rewritten to reflect these changes.- The lemmas `map′` and `map` in `Relation.Nullary.Decidable` produce their`does` result without any pattern matching, and `isYes` matches only on the`does` field, and not the `proof` field. For example this means that`does (map f X?)` is definitionally equal to `does X?`.- All of the connective lemmas like `_×-dec_` have a `does`field written in terms of boolean functions like `_∧_`. As well as beingless strict than the previous definitions, this should improve readabilitywhen only the `does` field is involved.* The function `⌊_⌋` still exists to be used in conjunction with `toWitness`and similar (e.g. in proof automation), but doesn't require the immediateevaluation of the `proof` part.* The rest of the `Relation.Nullary` subtree has been updated to reflect thechanges to `Dec`.### Other new modules* Properties for `Semigroup` and `CommutativeSemigroup`. Contains all thenon-trivial 3 element permutations. Useful for equational reasoning.```agdaAlgebra.Properties.SemigroupAlgebra.Properties.CommutativeSemigroup```* A map interface for AVL trees.```agdaData.AVL.Map```* Level polymorphic versions for the bottom and top types. Useful ingetting rid of the need to use `Lift`.```agdaData.Unit.PolymorphicData.Unit.Polymorphic.PropertiesData.Empty.Polymorphic```* Greatest common divisor and least common multiples for integers:```agdaData.Integer.GCDData.Integer.LCM```* Fresh lists.```agdaData.List.FreshData.List.Fresh.PropertiesData.List.Fresh.Relation.Unary.AllData.List.Fresh.Relation.Unary.All.PropertiesData.List.Fresh.Relation.Unary.AnyData.List.Fresh.Relation.Unary.Any.PropertiesData.List.Fresh.MembershipData.List.Fresh.Membership.Properties```* Kleene lists. Useful when needing to distinguish between empty and non-empty lists.```agdaData.List.KleeneData.List.Kleene.AsListData.List.Kleene.Base```* Predicate over lists in which every neighbouring pair of elements is related.Useful for implementing paths in graphs.```agdaData.List.Relation.Unary.LinkedData.List.Relation.Unary.Linked.Properties```* Disjoint sublists.```agdaData.List.Relation.Binary.Sublist.Propositional.Disjoint```* Rationals whose numerator and denominator are not necessarily normalised (i.e. coprime).```Data.Rational.UnnormalisedData.Rational.Unnormalised.Properties```In this formalisation every number has an infinite number of multiple representationsand that evaluation is inefficient as the top and the bottom will inevitablyblow up. However they are significantly easier to reason about then the existingnormalised implementation in `Data.Rational`. The new monomorphism infrastructure(see below) is used to transfer proofs from these new unnormalised rationalsto the existing normalised implementation.* Basic constructions for the new funciton hierarchy.```agdaFunction.Construct.IdentityFunction.Construct.Composition```* New interfaces for using Haskell datatypes:```Foreign.Haskell.CoerceForeign.Haskell.Either```* Properties of setoids.```agdaRelation.Binary.Properties.Setoid```* Reasoning over partial setoids.```Relation.Binary.Reasoning.Base.PartialRelation.Binary.Reasoning.PartialSetoid```* Morphisms between algebraic and relational structures. See`Data.Rational.Properties` for how these can be used to easily transferalgebraic properties from unnormalised to normalised rationals.```agdaAlgebra.Morphism.DefinitionsAlgebra.Morphism.StructuresAlgebra.Morphism.MagmaMonomorphismAlgebra.Morphism.MonoidMonomorphismRelation.Binary.MorphismRelation.Binary.Morphism.DefinitionsRelation.Binary.Morphism.StructuresRelation.Binary.Morphism.RelMonomorphismRelation.Binary.Morphism.OrderMonomorphism```Deprecated names----------------The following deprecations have occurred as part of a drive to improveconsistency across the library. The deprecated names still exist andtherefore all existing code should still work, however use of the new namesis encouraged. Although not anticipated any time soon, they may eventuallybe removed in some future release of the library. Automated warnings areattached to all deprecated names to discourage their use.* In `Data.Fin`:```agdafromℕ≤ ↦ fromℕ<fromℕ≤″ ↦ fromℕ<″```* In `Data.Fin.Properties````agdafromℕ≤-toℕ ↦ fromℕ<-toℕtoℕ-fromℕ≤ ↦ toℕ-fromℕ<fromℕ≤≡fromℕ≤″ ↦ fromℕ<≡fromℕ<″toℕ-fromℕ≤″ ↦ toℕ-fromℕ<″isDecEquivalence ↦ ≡-isDecEquivalencepreorder ↦ ≡-preordersetoid ↦ ≡-setoiddecSetoid ↦ ≡-decSetoid```* In `Data.Integer.Properties`:```agda[1+m]*n≡n+m*n ↦ suc-*```* In `Data.Nat.Coprimality`:```agdacoprime-gcd ↦ coprime⇒GCD≡1gcd-coprime ↦ GCD≡1⇒coprime```* In `Data.Nat.Properties`:```agda+-*-suc ↦ *-sucn∸m≤n ↦ m∸n≤m```(Note that the latter will require the arguments to be reversed)* In `Data.Unit` the definition `_≤_` is unnecessary as it is isomorphic to `_≡_`and has therefore been deprecated.* In `Data.Unit.Properties` the associated proofs have therefore been renamed as follows:```agda≤-total ↦ ≡-total_≤?_ ↦ _≟_≤-isPreorder ↦ ≡-isPreorder≤-isPartialOrder ↦ ≡-isPartialOrder≤-isTotalOrder ↦ ≡-isTotalOrder≤-isDecTotalOrder ↦ ≡-isDecTotalOrder≤-poset ↦ ≡-poset≤-decTotalOrder ↦ ≡-decTotalOrder```* In `Relation.Binary.Properties.Poset`:```agdainvIsPartialOrder ↦ ≥-isPartialOrderinvPoset ↦ ≥-posetstrictPartialOrder ↦ <-strictPartialOrder```* In `Relation.Binary.Properties.DecTotalOrder`:```agdastrictTotalOrder ↦ <-strictTotalOrder```Other minor additions---------------------* Added new definition to `Algebra.Bundles`:```agdarecord CommutativeSemigroup c ℓ : Set (suc (c ⊔ ℓ))```* Added new definition to `Algebra.Structures`:```agdarecord IsCommutativeSemigroup (∙ : Op₂ A) : Set (a ⊔ ℓ)```* The function `tail` in `Codata.Stream` has a new, more general type:```agdatail : ∀ {i} {j : Size< i} → Stream A i → Stream A j```* Added new proofs to `Data.Char.Properties`:```agda<-isStrictPartialOrder-≈ : IsStrictPartialOrder _≈_ _<_<-isStrictTotalOrder-≈ : IsStrictTotalOrder _≈_ _<_<-strictPartialOrder-≈ : StrictPartialOrder 0ℓ 0ℓ 0ℓ```* Added new proofs to `Data.Fin.Properties`:```agda∀-cons-⇔ : (P zero × Π[ P ∘ suc ]) ⇔ Π[ P ]∃-here : P zero → ∃⟨ P ⟩∃-there : ∃⟨ P ∘ suc ⟩ → ∃⟨ P ⟩∃-toSum : ∃⟨ P ⟩ → P zero ⊎ ∃⟨ P ∘ suc ⟩⊎⇔∃ : (P zero ⊎ ∃⟨ P ∘ suc ⟩) ⇔ ∃⟨ P ⟩```* Added new proofs to `Data.Fin.Subset.Properties`:```agdaout⊆ : p ⊆ q → outside ∷ p ⊆ y ∷ qout⊆-⇔ : p ⊆ q ⇔ outside ∷ p ⊆ y ∷ qin⊆in : p ⊆ q → inside ∷ p ⊆ inside ∷ qin⊆in-⇔ : p ⊆ q ⇔ inside ∷ p ⊆ inside ∷ q∃-Subset-zero : ∃⟨ P ⟩ → P []∃-Subset-[]-⇔ : P [] ⇔ ∃⟨ P ⟩∃-Subset-suc : ∃⟨ P ⟩ → ∃⟨ P ∘ (inside ∷_) ⟩ ⊎ ∃⟨ P ∘ (outside ∷_) ⟩∃-Subset-∷-⇔ : (∃⟨ P ∘ (inside ∷_) ⟩ ⊎ ∃⟨ P ∘ (outside ∷_) ⟩) ⇔ ∃⟨ P ⟩```* Added new constants to `Data.Integer.Base`:```agda-1ℤ = -[1+ 0 ]0ℤ = +01ℤ = +[1+ 0 ]```* Added new proofs to `Data.Integer.Properties`:```agda*-suc : m * sucℤ n ≡ m + m * n+-isCommutativeSemigroup : IsCommutativeSemigroup _+_*-isCommutativeSemigroup : IsCommutativeSemigroup _*_+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ*-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ```* Added new function to `Data.List.Base`:```agda_ʳ++_ = flip reverseAcc```* Added new proofs to `Data.List.Properties`:```agdafilter-accept : P x → filter P? (x ∷ xs) ≡ x ∷ (filter P? xs)filter-reject : ¬ P x → filter P? (x ∷ xs) ≡ filter P? xsfilter-idem : filter P? ∘ filter P? ≗ filter P?filter-++ : filter P? (xs ++ ys) ≡ filter P? xs ++ filter P? ysʳ++-defn : xs ʳ++ ys ≡ reverse xs ++ ysʳ++-++ : (xs ++ ys) ʳ++ zs ≡ ys ʳ++ xs ʳ++ zsʳ++-ʳ++ : (xs ʳ++ ys) ʳ++ zs ≡ ys ʳ++ xs ++ zslength-ʳ++ : length (xs ʳ++ ys) ≡ length xs + length ysmap-ʳ++ : map f (xs ʳ++ ys) ≡ map f xs ʳ++ map f ysfoldr-ʳ++ : foldr f b (xs ʳ++ ys) ≡ foldl (flip f) (foldr f b ys) xsfoldl-ʳ++ : foldl f b (xs ʳ++ ys) ≡ foldl f (foldr (flip f) b xs) ys```* Added new definitions to `Data.List.Relation.Binary.Lex.Core`:```agda[]<[]-⇔ : P ⇔ [] < []toSum : (x ∷ xs) < (y ∷ ys) → (x ≺ y ⊎ (x ≈ y × xs < ys))∷<∷-⇔ : (x ≺ y ⊎ (x ≈ y × xs < ys)) ⇔ (x ∷ xs) < (y ∷ ys)```* The proof `toAny` in `Data.List.Relation.Binary.Sublist.Heterogeneous` has a new more general type:```agdatoAny : Sublist R (a ∷ as) bs → Any (R a) bs```* Added new relations to `Data.List.Relation.Binary.Sublist.Heterogeneous`:```agdaDisjoint (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs)DisjointUnion (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) (τ : xys ⊆ zs)```* Added new relations and definitions to `Data.List.Relation.Binary.Sublist.Setoid`:```agdaxs ⊇ ys = ys ⊆ xsxs ⊈ ys = ¬ (xs ⊆ ys)xs ⊉ ys = ¬ (xs ⊇ ys)UpperBound (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs)⊆-disjoint-union : Disjoint τ σ → UpperBound τ σ```* Added new proofs to `Data.List.Relation.Binary.Sublist.Setoid.Properties`:```agdashrinkDisjointˡ : Disjoint τ₁ τ₂ → Disjoint (⊆-trans σ τ₁) τ₂shrinkDisjointʳ : Disjoint τ₁ τ₂ → Disjoint τ₁ (⊆-trans σ τ₂)```* Added new definitions to `Data.List.Relation.Binary.Sublist.Propositional`:```agdaseparateˡ : (τ₁ : xs ⊆ zs) (τ₂ : ys ⊆ zs) → Separation τ₁ τ₂```* Added new proofs to `Data.List.Relation.Binary.Sublist.Propositional.Properties`:```agda⊆-trans-idˡ : ⊆-trans ⊆-refl τ ≡ τ⊆-trans-idʳ : ⊆-trans τ ⊆-refl ≡ τ⊆-trans-assoc : ⊆-trans τ₁ (⊆-trans τ₂ τ₃) ≡ ⊆-trans (⊆-trans τ₁ τ₂) τ₃All-resp-⊆ : (All P) Respects _⊇_Any-resp-⊆ : (Any P) Respects _⊆_All-resp-⊆-refl : All-resp-⊆ ⊆-refl ≗ idAll-resp-⊆-trans : All-resp-⊆ (⊆-trans τ τ′) ≗ All-resp-⊆ τ ∘ All-resp-⊆ τ′Any-resp-⊆-refl : Any-resp-⊆ ⊆-refl ≗ idAny-resp-⊆-trans : Any-resp-⊆ (⊆-trans τ τ′) ≗ Any-resp-⊆ τ′ ∘ Any-resp-⊆ τlookup-injective : lookup τ i ≡ lookup τ j → i ≡ j```* Added new definition to `Data.List.Relation.Binary.Pointwise`:```agdauncons : Pointwise _∼_ (x ∷ xs) (y ∷ ys) → x ∼ y × Pointwise _∼_ xs ys```* Added new definitions to `Data.List.Relation.Unary.All`:```agdaNull = All (λ _ → ⊥)```* Added new proofs to `Data.List.Relation.Unary.All.Properties`:```agdaNull⇒null : Null xs → T (null xs)null⇒Null : T (null xs) → Null xs[]=-injective : pxs [ i ]= px → pxs [ i ]= qx → px ≡ qx[]=lookup : (i : x ∈ xs) → pxs [ i ]= lookup pxs i[]=⇒lookup : pxs [ i ]= px → lookup pxs i ≡ pxlookup⇒[]= : lookup pxs i ≡ px → pxs [ i ]= pxupdateAt-minimal : i ≢∈ j → pxs [ i ]= px → updateAt j f pxs [ i ]= pxupdateAt-id-relative : f (lookup pxs i) ≡ lookup pxs i → updateAt i f pxs ≡ pxsupdateAt-compose-relative : f (g (lookup pxs i)) ≡ h (lookup pxs i) → updateAt i f (updateAt i g pxs) ≡ updateAt i h pxsupdateAt-commutes : i ≢∈ j → updateAt i f ∘ updateAt j g ≗ updateAt j g ∘ updateAt i f```* The proof `All-swap` in `Data.List.Relation.Unary.All.Properties` has been generalised to work over `_~_ : REL A B ℓ` instead of just `_~_ : REL (List A) B ℓ`.* Added new definition to `Data.List.Relation.Unary.AllPairs`:```agdauncons : AllPairs R (x ∷ xs) → All (R x) xs × AllPairs R xs```* Added new proofs to `Data.Nat.Coprimality`:```agdacoprime⇒gcd≡1 : Coprime m n → gcd m n ≡ 1gcd≡1⇒coprime : gcd m n ≡ 1 → Coprime m ncoprime-/gcd : Coprime (m / gcd m n) (n / gcd m n)```* Added new proof to `Data.Nat.Divisibility`:```agda>⇒∤ : m > suc n → m ∤ suc n```* Added new proofs to `Data.Nat.DivMod`:```agda/-congˡ : m ≡ n → m / o ≡ n / o/-congʳ : n ≡ o → m / n ≡ m / o/-mono-≤ : m ≤ n → o ≥ p → m / o ≤ n / p/-monoˡ-≤ : m ≤ n → m / o ≤ n / o/-monoʳ-≤ : n ≥ o → m / n ≤ m / om≥n⇒m/n>0 : m ≥ n → m / n > 0```* Added new proofs to `Data.Nat.GCD`:```agdagcd[m,n]≡0⇒m≡0 : gcd m n ≡ 0 → m ≡ 0gcd[m,n]≡0⇒n≡0 : gcd m n ≡ 0 → n ≡ 0gcd[m,n]≤n : gcd m (suc n) ≤ suc nn/gcd[m,n]≢0 : {n≢0 gcd≢0} → n / gcd m n ≢ 0GCD-* : GCD (m * suc c) (n * suc c) (d * suc c) → GCD m n dGCD-/ : c ∣ m → c ∣ n → c ∣ d → GCD m n d → GCD (m / c) (n / c) (d / c)GCD-/gcd : GCD (m / gcd m n) (n / gcd m n) 1```* Added new proofs to `Data.Nat.Properties`:```agda0≢1+n : 0 ≢ suc n1+n≢n : suc n ≢ neven≢odd : 2 * m ≢ suc (2 * n)0<1+n : 0 < suc nn<1+n : n < suc nm<m+n : n > 0 → m < m + nm<n⇒n≢0 : m < n → n ≢ 0m<n⇒m≤1+n : m < n → m ≤ suc nm≤n⇒m<n∨m≡n : m ≤ n → m < n ⊎ m ≡ n∀[m≤n⇒m≢o]⇒o<n : (∀ {m} → m ≤ n → m ≢ o) → n < o∀[m<n⇒m≢o]⇒o≤n : (∀ {m} → m < n → m ≢ o) → n ≤ o+-rawMagma : RawMagma 0ℓ 0ℓ*-rawMagma : RawMagma 0ℓ 0ℓ+-0-rawMonoid : RawMonoid 0ℓ 0ℓ*-1-rawMonoid : RawMonoid 0ℓ 0ℓ*-cancelˡ-≤ : suc o * m ≤ suc o * n → m ≤ n1+m≢m∸n : suc m ≢ m ∸ n∸-monoʳ-< : o < n → n ≤ m → m ∸ n < m ∸ o∸-cancelʳ-≤ : m ≤ o → o ∸ n ≤ o ∸ m → m ≤ n∸-cancelʳ-< : o ∸ m < o ∸ n → n < m∸-cancelˡ-≡ : n ≤ m → o ≤ m → m ∸ n ≡ m ∸ o → n ≡ om<n⇒0<n∸m : m < n → 0 < n ∸ mm>n⇒m∸n≢0 : m > n → m ∸ n ≢ 0∣-∣-identityˡ : LeftIdentity 0 ∣_-_∣∣-∣-identityʳ : RightIdentity 0 ∣_-_∣∣-∣-identity : Identity 0 ∣_-_∣m≤n+∣n-m∣ : m ≤ n + ∣ n - m ∣m≤n+∣m-n∣ : m ≤ n + ∣ m - n ∣m≤∣m-n∣+n : m ≤ ∣ m - n ∣ + n+-isCommutativeSemigroup : IsCommutativeSemigroup _+_+-commutativeSemigroup : CommutativeSemigroup 0ℓ 0ℓ```* Added new bundles to `Data.String.Properties`:```agda<-isStrictPartialOrder-≈ : IsStrictPartialOrder _≈_ _<_<-isStrictTotalOrder-≈ : IsStrictTotalOrder _≈_ _<_<-strictPartialOrder-≈ : StrictPartialOrder 0ℓ 0ℓ 0ℓ```* Added new functions to `Data.Rational.Base`:```agdamkℚ+ : ∀ n d → .{d≢0 : d ≢0} → .(Coprime n d) → ℚtoℚᵘ : ℚ → ℚᵘfromℚᵘ : ℚᵘ → ℚ```* Added new proofs to `Data.Rational.Properties`:```agdamkℚ-cong : n₁ ≡ n₂ → d₁ ≡ d₂ → mkℚ n₁ d₁ c₁ ≡ mkℚ n₂ d₂ c₂mkℚ+-cong : n₁ ≡ n₂ → d₁ ≡ d₂ → mkℚ+ n₁ d₁ c₁ ≡ mkℚ+ n₂ d₂ c₂normalize-coprime : .(c : Coprime n (suc d-1)) → normalize n (suc d-1) ≡ mkℚ (+ n) d-1 c↥-mkℚ+ : ↥ (mkℚ+ n d c) ≡ + n↧-mkℚ+ : ↧ (mkℚ+ n d c) ≡ + d↥-neg : ↥ (- p) ≡ - (↥ p)↧-neg : ↧ (- p) ≡ ↧ p↥-normalise : ↥ (normalize i n) * gcd (+ i) (+ n) ≡ + i↧-normalise : ↧ (normalize i n) * gcd (+ i) (+ n) ≡ + n↥-/ : ↥ (i / n) * gcd i (+ n) ≡ i↧-/ : ↧ (i / n) * gcd i (+ n) ≡ + n↥-+ : ↥ (p + q) * gcd (...) (...) ≡ ↥ p * ↧ q ℤ.+ ↥ q * ↧ p↧-+ : ↧ (p + q) * gcd (...) (...) ≡ ↧ p * ↧ q↥p/↧p≡p : ↥ p / ↧ₙ p ≡ p0/n≡0 : 0ℤ / n ≡ 0ℚtoℚᵘ-cong : toℚᵘ Preserves _≡_ ⟶ _≃ᵘ_toℚᵘ-injective : Injective _≡_ _≃ᵘ_ toℚᵘfromℚᵘ-toℚᵘ : fromℚᵘ (toℚᵘ p) ≡ ptoℚᵘ-homo-+ : Homomorphic₂ toℚᵘ _+_ ℚᵘ._+_toℚᵘ-+-isRawMagmaMorphism : IsRawMagmaMorphism +-rawMagma ℚᵘ.+-rawMagma toℚᵘtoℚᵘ-+-isRawMonoidMorphism : IsRawMonoidMorphism +-rawMonoid ℚᵘ.+-rawMonoid toℚᵘ+-assoc : Associative _+_+-comm : Commutative _+_+-identityˡ : LeftIdentity 0ℚ _+_+-identityʳ : RightIdentity 0ℚ _+_+-identity : Identity 0ℚ _+_+-isMagma : IsMagma _+_+-isSemigroup : IsSemigroup _+_+-0-isMonoid : IsMonoid _+_ 0ℚ+-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0ℚ+-rawMagma : RawMagma 0ℓ 0ℓ+-rawMonoid : RawMonoid 0ℓ 0ℓ+-magma : Magma 0ℓ 0ℓ+-semigroup : Semigroup 0ℓ 0ℓ+-0-monoid : Monoid 0ℓ 0ℓ+-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ```* Added new functions to `Data.Sum.Base`:```agdafromInj₁ : (B → A) → A ⊎ B → AfromInj₂ : (A → B) → A ⊎ B → B```* Added new definition to `Data.These.Properties`:```agdathese-injective : these x a ≡ these y b → x ≡ y × a ≡ b```* Added new definition to `Data.Vec.Relation.Binary.Pointwise.Inductive`:```agdauncons : Pointwise _∼_ (x ∷ xs) (y ∷ ys) → x ∼ y × Pointwise _∼_ xs ys```* Added new definition to `Data.Vec.Relation.Unary.All`:```agdauncons : All P (x ∷ xs) → P x × All P xs```* Added new functions to `Level`.```agdalevelOfType : ∀ {a} → Set a → LevellevelOfTerm : ∀ {a} {A : Set a} → A → Level```* Added new proofs to `Relation.Binary.PropositionalEquality`:```agdaisMagma : (_∙_ : Op₂ A) → IsMagma _≡_ _∙_magma : (_∙_ : Op₂ A) → Magma a a```* Added new definition to `Relation.Binary.Structures`:```agdarecord IsPartialEquivalence (_≈_ : Rel A ℓ) : Set (a ⊔ ℓ)```* Added new definition to `Relation.Binary.Bundles`:```agdarecord PartialSetoid a ℓ : Set (suc (a ⊔ ℓ))```* Added new proofs to `Relation.Binary.Construct.NonStrictToStrict`:```agda<⇒≉ : x < y → x ≉ y≤∧≉⇒< : x ≤ y → x ≉ y → x < y<⇒≱ : Antisymmetric _≈_ _≤_ → ∀ {x y} → x < y → ¬ (y ≤ x)≤⇒≯ : Antisymmetric _≈_ _≤_ → ∀ {x y} → x ≤ y → ¬ (y < x)≰⇒> : Symmetric _≈_ → (_≈_ ⇒ _≤_) → Total _≤_ → ∀ {x y} → ¬ (x ≤ y) → y < x≮⇒≥ : Symmetric _≈_ → Decidable _≈_ → _≈_ ⇒ _≤_ → Total _≤_ → ∀ {x y} → ¬ (x < y) → y ≤ x```* Each of the following modules now re-export relevant proofs and relations from the previous modules in the list.```Relation.Binary.Properties.PreorderRelation.Binary.Properties.PosetRelation.Binary.Properties.TotalOrderRelation.Binary.Properties.DecTotalOrder```* Added new relations and proofs to `Relation.Binary.Properties.Poset`:```agdax ≥ y = y ≤ xx < y = ¬ (y ≈ x)<⇒≉ : x < y → x ≉ y≤∧≉⇒< : x ≤ y → x ≉ y → x < y<⇒≱ : x < y → ¬ (y ≤ x)≤⇒≯ : x ≤ y → ¬ (y < x)```* Added new proof to `Relation.Binary.Properties.TotalOrder`:```agda≰⇒> : ¬ (x ≤ y) → y < x```* Added new proof to `Relation.Binary.Properties.DecTotalOrder`:```agda≮⇒≥ : ¬ (x < y) → y ≤ x```* Added new proof to `Relation.Binary.PropositionalEquality`:```agdaisDecEquivalence : Decidable _≡_ → IsDecEquivalence _≡_```* Added new definitions to `Relation.Nary`:```agdaapply⊤ₙ : Π[ R ] → (vs : Product⊤ n as) → uncurry⊤ₙ n R vsapplyₙ : Π[ R ] → (vs : Product n as) → uncurry⊤ₙ n R (toProduct⊤ n vs)iapply⊤ₙ : ∀[ R ] → {vs : Product⊤ n as} → uncurry⊤ₙ n R vsiapplyₙ : ∀[ R ] → {vs : Product n as} → uncurry⊤ₙ n R (toProduct⊤ n vs)Decidable : as ⇉ Set r → Set (r ⊔ ⨆ n ls)⌊_⌋ : Decidable R → as ⇉ Set rfromWitness : (R : as ⇉ Set r) (R? : Decidable R) → ∀[ ⌊ R? ⌋ ⇒ R ]toWitness : (R : as ⇉ Set r) (R? : Decidable R) → ∀[ R ⇒ ⌊ R? ⌋ ]```* Added new definitions to `Relation.Unary`:```agda⌊_⌋ : {P : Pred A ℓ} → Decidable P → Pred A ℓ```* Added new definitions to `Relation.Binary.Construct.Closure.Reflexive.Properties`:```agdafromSum : a ≡ b ⊎ a ~ b → Refl _~_ a btoSum : Refl _~_ a b → a ≡ b ⊎ a ~ b⊎⇔Refl : (a ≡ b ⊎ a ~ b) ⇔ Refl _~_ a b```* Added new definitions to `Relation.Nullary.Decidable`:```agdadec-true : (p? : Dec P) → P → does p? ≡ truedec-false : (p? : Dec P) → ¬ P → does p? ≡ false```* Added new definition to `Relation.Nullary.Implication`:```agda_→-reflects_ : Reflects P bp → Reflects Q bq → Reflects (P → Q) (not bp ∨ bq)```* Added new definition to `Relation.Nullary.Negation`:```agda¬-reflects : Reflects P b → Reflects (¬ P) (not b)```* Added new definition to `Relation.Nullary.Product`:```agda_×-reflects_ : Reflects P bp → Reflects Q bq → Reflects (P × Q) (bp ∧ bq)```* Added new definition to `Relation.Nullary.Sum`:```agda_⊎-reflects_ : Reflects P bp → Reflects Q bq → Reflects (P ⊎ Q) (bp ∨ bq)```* The module `Size` now re-exports the built-in function:```agda_⊔ˢ_ : Size → Size → Size```
Version 1.1===========The library has been tested using Agda version 2.6.0.1.Changes since 1.0.1:Highlights----------* Large increases in performance for `Nat`, `Integer` and `Rational` datatypes,particularly in compiled code.* Generic n-ary programming (`projₙ`, `congₙ`, `substₙ` etc.)* General argmin/argmax/min/max over `List`.* New `Trie` datatypeBug-fixes---------#### `_<_` in `Data.Integer`* The definition of `_<_` in `Data.Integer` often resulted in unsolved metaswhen Agda had to infer the first argument. This was because it waspreviously implemented in terms of `suc` -> `_+_` -> `_⊖_`.* To fix this problem the implementation has therefore changed to:```agdadata _<_ : ℤ → ℤ → Set where-<+ : ∀ {m n} → -[1+ m ] < + n-<- : ∀ {m n} → (n<m : n ℕ.< m) → -[1+ m ] < -[1+ n ]+<+ : ∀ {m n} → (m<n : m ℕ.< n) → + m < + n```which should allow many implicit parameters which previously hadto be given explicitly to be removed.* All proofs involving `_<_` have been updated correspondingly* For backwards compatibility the old relations still exist as primed versions`_<′_` as do all the old proofs, e.g. `+-monoˡ-<` has become `+-monoˡ-<′`,but these have all been deprecated and may be removed in some future version.* Migrating code might require lemmas relating `m < n` and `m <′ n`/`suc m ≤ n`;such lemmas have unfortunately only been added in 1.3.#### Fixed wrong queries being exported by `Data.Rational`* `Data.Rational` previously accidently exported queries from `Data.Nat.Base`instead of `Data.Rational.Base`. This has now been fixed.#### Fixed inaccurate name in `Data.Nat.Properties`* The proof `m+n∸m≡n` in `Data.Nat.Properties` was incorrectly named asit proved `m + (n ∸ m) ≡ n` rather than `m + n ∸ m ≡ n`. It hastherefore been renamed `m+[n∸m]≡n` and the old name now refers to a newproof of the correct type.#### Fixed operator precedents in `Ring`-like structures* The infix precedence of `_-_` in the record `Group` from `Algebra.Structures`was previously set such that when it was inherited by the records `Ring`,`CommutativeRing` etc. it had the same predence as `_*_` rather than `_+_`.This lead to `x - x * x` being ambigous instead of being parsed as `x - (x * x)`.To fix this, the precedence of `_-_` has been reduced from 7 to 6.#### Fixed operator precedents in `Reasoning` modules* The infix precedence of the generic order reasoning combinators (`_∼⟨_⟩_`,`_≈⟨_⟩_`, etc.) in `Relation.Binary.Reasoning.Base.Double/Triple` wereaccidentally lowered when implementing new style reasoning in `v1.0`.This lead to inconsistencies in modules that add custom combinators (e.g.`StarReasoning` from `Relation.Binary.Construct.Closure.ReflexiveTransitive.Properties`)using the original fixity. The old fixity has now been restored.Other non-backwards compatible changes--------------------------------------#### Improved performance of arithmetic decision procedures & operations* The functions `_≤?_` and `<-cmp` in `Data.Nat.Properties` have beenreimplemented uses only built-in primitives. Consequently this shouldresult in a significant performance increase when these functions arecompiled or when the generated proof is ignored.* The function `show` in `Data.Nat.Show` has been reimplemented and,when compiled, now runs in time `O(log₁₀(n))` rather than `O(n)`.* The functions `gcd` and `lcm` in `Data.Nat.GCD` and `Data.Nat.LCM`have been reimplemented via the built-ins `_/_` and `mod` so thatthey run much faster when compiled and normalised. Their types have alsobeen changed to `ℕ → ℕ → ℕ` instead of `(m n : ℕ) → ∃ λ d → GCD/LCM m n d`.The old functions still exist and have been renamed `mkGCD`/`mkLCM`.The alternative `gcd′` in `Data.Nat.Coprimality` has been deprecated.* As a consequence of the above, the performance of all decidability proceduresin `Data.Integer` and `Data.Rational` should also have improved. Normalisationspeed in `Data.Rational` should receive a significant boost.#### Better reduction behaviour for conversion functions in `Data.Fin`* The implementation of the functions `fromℕ≤` and `inject≤` in `Data.Fin.Base`has been changed so as to avoid pattern matching on the `m ≤ n` proof. Thismakes them significantly easier to use, as often it is inconvenient topattern match on the `m ≤ n` proof directly.#### Consistent field names in `IsDistributiveLattice`* In order to match the conventions found elsewhere in the library, the module`IsDistributiveLattice` in `Algebra.Structures` has had its field renamedfrom `∨-∧-distribʳ` to `∨-distribʳ-∧` . To maximise backwards compatability,the record still exports `∨-∧-distribʳ` but the name is deprecated.#### Making categorical traversal functions easier to use* Previously the functions `sequenceA`, `mapA`, `forA`, `sequenceM`,`mapM` and `forM` in the `Data.X.Categorical` modules required the`Applicative`/`Monad` to be passed each time they were used. To avoid thisthey have now been placed in parameterised modules named `TraversableA` and`TraversableM`. To recover the old behaviour simply write `open TraversableA`.However you may now, for example, avoid passing the applicative every timeby writing `open TraversableA app`. The change has occured in the followingmodules:```adgaData.Maybe.CategoricalData.List.CategoricalData.List.NonEmpty.CategoricalData.Product.Categorical.(Left/Right)Data.Sum.Categorical.(Left/Right)Data.Vec.Categorical```#### Moved `#_` within `Data.Fin`.* The function `#_` has been moved from `Data.Fin.Base` to `Data.Fin`to break dependency cycles following the introduction of the module`Data.Product.N-ary.Heterogeneous`.New modules-----------The following new modules have been added to the library:* An algebraic construction for choosing between `x` and `y` based on acomparison of `f x` and `f y`.```Algebra.Constructs.LiftedChoice```* The reader monad.```Category.Monad.Reader```* Non-empty AVL trees.```Data.AVL.NonEmptyData.AVL.NonEmpty.Propositional```* Implementations of `argmin`, `argmax`, `min` and `max` for lists overarbitrary `TotalOrder`s.```Data.List.ExtremaData.List.Extrema.NatData.List.Extrema.Core```* Additional properties of membership with the `--with-k` option enabled.```Data.List.Membership.Propositional.Properties.WithK```* A relation for lists that share no elements in common.```Data.List.Relation.Binary.Disjoint.PropositionalData.List.Relation.Binary.Disjoint.SetoidData.List.Relation.Binary.Disjoint.Setoid.Properties```* A relation for lists that are permutations of one another with respect to a `Setoid`.```Data.List.Relation.Binary.Permutation.HomogeneousData.List.Relation.Binary.Permutation.SetoidData.List.Relation.Binary.Permutation.Setoid.Properties```* A predicate for lists in which every pair of elements is related.```Data.List.Relation.Unary.AllPairsData.List.Relation.Unary.AllPairs.Properties```* A predicate for lists in which every element is unique.```Data.List.Relation.Unary.Unique.PropositionalData.List.Relation.Unary.Unique.Propositional.PropertiesData.List.Relation.Unary.Unique.SetoidData.List.Relation.Unary.Unique.Setoid.Properties```* New generic n-ary programming primitives.```Data.Product.Nary.NonDependentFunction.Nary.NonDependentFunction.Nary.NonDependent.BaseRelation.Nary```* Properties of the unit type.```Data.Unit.Properties```* Implementation of tries.```Data.TrieData.Trie.NonEmpty```* New implementation of vectors of no more than length `n`.```Data.Vec.Bounded.BaseData.Vec.Bounded```* Data types that are compiled to their Haskell equivalents.```Foreign.Haskell.PairForeign.Haskell.Maybe```* Properties of closures over binary relations.```Relation.Binary.Construct.Closure.Reflexive.PropertiesRelation.Binary.Construct.Closure.Reflexive.Properties.WithKRelation.Binary.Construct.Closure.Equivalence.Properties```* A formalisation of rewriting theory/transition systems.```Relation.Binary.Rewriting```* Utilities for formatting and printing strings.```Text.FormatText.Printf```Relocated modules-----------------The following modules have been moved as part of a drive to improveusability and consistency across the library. The old modules still exist andtherefore all existing code should still work, however they have been deprecatedand, although not anticipated any time soon, they may eventuallybe removed in some future release of the library. After the next release of Agdaautomated warnings will be attached to these modules to discourage their use.* The induction machinery for `Nat` was commonly held to be one of the hardestmodules to find in the library. Therefore the module `Induction.Nat` has beensplit into two new modules: `Data.Nat.Induction` and `Data.Fin.Induction`.This should improve findability and better matches the design of the rest ofthe library. The new modules also publicly re-export `Acc` and `acc`, meaningthat users no longer need to import `Data.Induction.WellFounded` as well.* The module `Record` has been moved to `Data.Record`.* The module `Universe` has been split into `Data.Universe` and`Data.Universe.Indexed`. In the latter `Indexed-universe` has beenrenamed to `IndexedUniverse` to better follow the library conventions.* The `Data.Product.N-ary` modules and their content have been moved to`Data.Vec.Recursive` to make place for properly heterogeneous n-ary productsin `Data.Product.Nary`.* The modules `Data.List.Relation.Binary.Permutation.Inductive(.Properties)`have been renamed `Data.List.Relation.Binary.Permutation.Propositional(.Properties)`to match the rest of the library.Deprecated names----------------The following deprecations have occurred as part of a drive to improveconsistency across the library. The deprecated names still exist andtherefore all existing code should still work, however use of the new namesis encouraged. Although not anticipated any time soon, they may eventuallybe removed in some future release of the library. Automated warnings areattached to all deprecated names to discourage their use.* In `Algebra.Properties.BooleanAlgebra`:```agda¬⊥=⊤ ↦ ⊥≉⊤¬⊤=⊥ ↦ ⊤≉⊥⊕-¬-distribˡ ↦ ¬-distribˡ-⊕⊕-¬-distribʳ ↦ ¬-distribʳ-⊕isCommutativeRing ↦ ⊕-∧-isCommutativeRingcommutativeRing ↦ ⊕-∧-commutativeRing```* In `Algebra.Properties.DistributiveLattice`:```agda∨-∧-distribˡ ↦ ∨-distribˡ-∧∨-∧-distrib ↦ ∨-distrib-∧∧-∨-distribˡ ↦ ∧-distribˡ-∨∧-∨-distribʳ ↦ ∧-distribʳ-∨∧-∨-distrib ↦ ∧-distrib-∨```* In `Algebra.Properties.Group`:```agdaleft-identity-unique ↦ identityˡ-uniqueright-identity-unique ↦ identityʳ-uniqueleft-inverse-unique ↦ inverseˡ-uniqueright-inverse-unique ↦ inverseʳ-unique```* In `Algebra.Properties.Lattice`:```agda∧-idempotent ↦ ∧-idem∨-idempotent ↦ ∨-idemisOrderTheoreticLattice ↦ ∨-∧-isOrderTheoreticLatticeorderTheoreticLattice ↦ ∨-∧-orderTheoreticLattice```* In `Algebra.Properties.Ring`:```agda-‿*-distribˡ ↦ -‿distribˡ-*-‿*-distribʳ ↦ -‿distribʳ-*```NOTE: the direction of the equality is flipped for the new names andso you will need to replace `-‿*-distribˡ ...` with `sym (-‿distribˡ-* ...)`.* In `Algebra.Properties.Semilattice`:```agdaisOrderTheoreticMeetSemilattice ↦ ∧-isOrderTheoreticMeetSemilatticeisOrderTheoreticJoinSemilattice ↦ ∧-isOrderTheoreticJoinSemilatticeorderTheoreticMeetSemilattice ↦ ∧-orderTheoreticMeetSemilatticeorderTheoreticJoinSemilattice ↦ ∧-orderTheoreticJoinSemilattice```* In `Relation.Binary.Core`:```agdaConn ↦ Connex```* In `Codata.Stream.Properties`:```agdarepeat-ap-identity ↦ ap-repeatˡap-repeat-identity ↦ ap-repeatʳap-repeat-commute ↦ ap-repeatmap-repeat-commute ↦ map-repeat```* In `Data.Bool` (with the new name in `Data.Bool.Properties`):```agdadecSetoid ↦ ≡-decSetoid```* In `Data.Fin.Properties` the operator `_+′_` has been deprecated entirelyas it was difficult to use, had unpredictable reduction behaviour andwas very rarely used.* In `Data.Nat.Divisibility`:```agdaposet ↦ ∣-poset*-cong ↦ *-monoʳ-∣/-cong ↦ *-cancelˡ-∣```* In `Data.Nat.DivMod`:```agdaa≡a%n+[a/n]*n ↦ m≡m%n+[m/n]*na%1≡0 ↦ n%1≡0a%n%n≡a%n ↦ m%n%n≡m%n[a+n]%n≡a%n ↦ [m+n]%n≡m%n[a+kn]%n≡a%n ↦ [m+kn]%n≡m%nkn%n≡0 ↦ m*n%n≡0a%n<n ↦ m%n<n```* In `Data.Nat.Properties`:```agdam≢0⇒suc[pred[m]]≡m ↦ suc[pred[n]]≡ni+1+j≢i ↦ m+1+n≢mi+j≡0⇒i≡0 ↦ m+n≡0⇒m≡0i+j≡0⇒j≡0 ↦ m+n≡0⇒n≡0i+1+j≰i ↦ m+1+n≰mi*j≡0⇒i≡0∨j≡0 ↦ m*n≡0⇒m≡0∨n≡0i*j≡1⇒i≡1 ↦ m*n≡1⇒m≡1i*j≡1⇒j≡1 ↦ m*n≡1⇒n≡1i^j≡0⇒i≡0 ↦ m^n≡0⇒m≡0i^j≡1⇒j≡0∨i≡1 ↦ m^n≡1⇒n≡0∨m≡1[i+j]∸[i+k]≡j∸k ↦ [m+n]∸[m+o]≡n∸on≡m⇒∣n-m∣≡0 ↦ m≡n⇒∣m-n∣≡0∣n-m∣≡0⇒n≡m ↦ ∣m-n∣≡0⇒m≡n∣n-m∣≡n∸m⇒m≤n ↦ ∣m-n∣≡m∸n⇒n≤m∣n-n+m∣≡m ↦ ∣m-m+n∣≡n∣n+m-n+o∣≡∣m-o| ↦ ∣m+n-m+o∣≡∣n-o|n∸m≤∣n-m∣ ↦ m∸n≤∣m-n∣∣n-m∣≤n⊔m ↦ ∣m-n∣≤m⊔nn≤m+n ↦ m≤n+mn≤m+n∸m ↦ m≤n+m∸n∣n-m∣≡[n∸m]∨[m∸n] ↦ ∣m-n∣≡[m∸n]∨[n∸m]```Note that in the case of the last three proofs, the order of thearguments will need to be swapped.* In `Data.Unit` (with the new names in `Data.Unit.Properties`):```agdasetoid ↦ ≡-setoiddecSetoid ↦ ≡-decSetoidtotal ↦ ≤-totalposet ↦ ≤-posetdecTotalOrder ↦ ≤-decTotalOrder```* In `Data.Unit` the proof `preorder` has also been deprecated, butas it erroneously proved that `_≡_` rather than `_≤_` is a preorderwith respect to `_≡_` it does not have a new name in `Data.Unit.Properties`.* In `Foreign.Haskell` the terms `Unit` and `unit` have been deprecated infavour of `⊤` and `tt` from `Data.Unit`, as it turns out that the latterhave been automatically mapped to the Haskell equivalent for quite some time.* In `Reflection`:```agdareturnTC ↦ return```* Renamed functions in `Data.Char.Base`:```agdafromNat ↦ fromℕtoNat ↦ toℕ```* In `Data.(Char/String).Properties`:```agdasetoid ↦ ≡-setoiddecSetoid ↦ ≡-decSetoidstrictTotalOrder ↦ <-strictTotalOrder-≈toNat-injective ↦ toℕ-injective```* In `Data.Vec.Properties`:```agdalookup-++-inject+ ↦ lookup-++ˡlookup-++-+′ ↦ lookup-++ʳ```* In `Data.Product.Relation.Binary.Pointwise.NonDependent` (with thenew name in `Data.Product.Properties`).:```agda≡?×≡?⇒≡? ↦ ≡-dec```Other minor additions---------------------* Added new proofs in Data.Fin.Substitution.Lemmas:```agdaweaken-↑ : weaken t / (ρ ↑) ≡ weaken (t / ρ)weaken-∷ : weaken t₁ / (t₂ ∷ ρ) ≡ t₁ / ρweaken-sub : weaken t₁ / sub t₂ ≡ t₁wk-⊙-∷ : wk ⊙ (t ∷ ρ) ≡ ρ```* Added new record to `Algebra`:```agdaSelectiveMagma c ℓ : Set (suc (c ⊔ ℓ))```* Added new record to `Algebra.Structure`:```agdaIsSelectiveMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)```* Added new proof to `Algebra.Properties.AbelianGroup`:```agdaxyx⁻¹≈y : x ∙ y ∙ x ⁻¹ ≈ y```* Added new proofs to `Algebra.Properties.Group`:```agdaε⁻¹≈ε : ε ⁻¹ ≈ ε∙-cancelˡ : LeftCancellative _∙_∙-cancelʳ : RightCancellative _∙_∙-cancel : Cancellative _∙_```* Added new proofs to `Algebra.Properties.Lattice`:```agda∧-isMagma : IsMagma _∧_∧-isSemigroup : IsSemigroup _∧_∧-isBand : IsBand _∧_∨-isMagma : IsMagma _∨_∨-isSemigroup : IsSemigroup _∨_∨-isBand : IsBand _∨_```* Added new proofs to `Codata.Stream.Properties`:```agdasplitAt-repeat-identity : splitAt n (repeat a) ≡ (Vec.replicate a , repeat a)replicate-repeat : i ⊢ List.replicate n a ++ repeat a ≈ repeat acycle-replicate : i ⊢ cycle (List⁺.replicate n n≢0 a) ≈ repeat amap-cycle : i ⊢ map f (cycle as) ≈ cycle (List⁺.map f as)map-⁺++ : i ⊢ map f (as ⁺++ xs) ≈ List⁺.map f as ⁺++ Thunk.map (map f) xsmap-++ : i ⊢ map f (as ++ xs) ≈ List.map f as ++ map f xs```* Added new function to `Data.AVL.Indexed`:```agdatoList : Tree V l u h → List (K& V)```* Added new relations to `Data.Bool`:```agda_≤_ : Rel Bool 0ℓ_<_ : Rel Bool 0ℓ```* Added new proofs to `Data.Bool.Properties`:```agda≡-setoid : Setoid 0ℓ 0ℓ≤-reflexive : _≡_ ⇒ _≤_≤-refl : Reflexive _≤_≤-antisym : Antisymmetric _≡_ _≤_≤-trans : Transitive _≤_≤-total : Total _≤__≤?_ : Decidable _≤_≤-minimum : Minimum _≤_ false≤-maximum : Maximum _≤_ true≤-irrelevant : B.Irrelevant _≤_≤-isPreorder : IsPreorder _≡_ _≤_≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-poset : Poset 0ℓ 0ℓ 0ℓ≤-preorder : Preorder 0ℓ 0ℓ 0ℓ≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ<-irrefl : Irreflexive _≡_ _<_<-asym : Asymmetric _<_<-trans : Transitive _<_<-transʳ : Trans _≤_ _<_ _<_<-transˡ : Trans _<_ _≤_ _<_<-cmp : Trichotomous _≡_ _<__<?_ : Decidable _<_<-resp₂-≡ : _<_ Respects₂ _≡_<-irrelevant : B.Irrelevant _<_<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ```* Added new definitions to `Data.Char.Base`:```agda_≈_ : Rel Char 0ℓ_<_ : Rel Char 0ℓ```* Added new properties to `Data.Char.Properties`:```agda≈⇒≡ : _≈_ ⇒ _≡_≈-reflexive : _≡_ ⇒ _≈_≈-refl : Reflexive _≈_≈-sym : Symmetric _≈_≈-trans : Transitive _≈_≈-subst : Substitutive _≈_ ℓ_≈?_ : Decidable _≈_≈-isEquivalence : IsEquivalence _≈_≈-setoid : Setoid _ _≈-isDecEquivalence : IsDecEquivalence _≈_≈-decSetoid : DecSetoid _ __<?_ : Decidable _<_```* Added new function to `Data.Digit`:```agdatoNatDigits : (base : ℕ) {base≤16 : True (1 ≤? base)} → ℕ → List ℕ```* Added new patterns to `Data.Fin.Base`:```agdapattern 0F = zeropattern 1F = suc 0Fpattern 2F = suc 1Fpattern 3F = suc 2Fpattern 4F = suc 3Fpattern 5F = suc 4Fpattern 6F = suc 5Fpattern 7F = suc 6Fpattern 8F = suc 7Fpattern 9F = suc 8F```* Added new proof to `Data.Fin.Properties`:```agdainject≤-idempotent : inject≤ (inject≤ i m≤n) n≤k ≡ inject≤ i m≤k```* Added new pattern synonyms to `Data.Integer`:```agdapattern +0 = + 0pattern +[1+_] n = + (suc n)```* Added new proofs to `Data.Integer.Properties`:```agda≡-setoid : Setoid 0ℓ 0ℓ≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ_<?_ : Decidable _<_+[1+-injective : +[1+ m ] ≡ +[1+ n ] → m ≡ ndrop‿+<+ : + m < + n → m ℕ.< ndrop‿-<- : -[1+ m ] < -[1+ n ] → n ℕ.< m-◃<+◃ : 0 < m → Sign.- ◃ m < Sign.+ ◃ n+◃≮- : Sign.+ ◃ m ≮ -[1+ n ]+◃-mono-< : m ℕ.< n → Sign.+ ◃ m < Sign.+ ◃ n+◃-cancel-< : Sign.+ ◃ m < Sign.+ ◃ n → m ℕ.< nneg◃-cancel-< : Sign.- ◃ m < Sign.- ◃ n → n ℕ.< mm⊖n≤m : m ⊖ n ≤ + mm⊖n<1+m : m ⊖ n < +[1+ m ]m⊖1+n<m : m ⊖ suc n < + m-[1+m]≤n⊖m+1 : -[1+ m ] ≤ n ⊖ suc m⊖-monoʳ->-< : (p ⊖_) Preserves ℕ._>_ ⟶ _<_⊖-monoˡ-< : (_⊖ p) Preserves ℕ._<_ ⟶ _<_*-distrib-+ : _*_ DistributesOver _+_*-monoˡ-<-pos : (+[1+ n ] *_) Preserves _<_ ⟶ _<_*-monoʳ-<-pos : (_* +[1+ n ]) Preserves _<_ ⟶ _<_*-cancelˡ-<-non-neg : + m * n < + m * o → n < o*-cancelʳ-<-non-neg : m * + o < n * + o → m < n```* Added new proofs to `Data.List.Properties`:```agdafoldr-forcesᵇ : (P (f x y) → P x × P y) → P (foldr f e xs) → All P xsfoldr-preservesᵇ : (P x → P y → P (f x y)) → P e → All P xs → P (foldr f e xs)foldr-preservesʳ : (P y → P (f x y)) → P e → P (foldr f e xs)foldr-preservesᵒ : (P x ⊎ P y → P (f x y)) → P e ⊎ Any P xs → P (foldr f e xs)```* Added a new proof in `Data.List.Relation.Binary.Permutation.Propositional.Properties`:```agdashifts : xs ++ ys ++ zs ↭ ys ++ xs ++ zs```* Added new proofs to `Data.List.Relation.Binary.Pointwise`:```agda++-cancelˡ : Pointwise _∼_ (xs ++ ys) (xs ++ zs) → Pointwise _∼_ ys zs++-cancelʳ : Pointwise _∼_ (ys ++ xs) (zs ++ xs) → Pointwise _∼_ ys zs```* Added new proof to `Data.List.Relation.Binary.Sublist.Heterogeneous.Properties`:```agdaconcat⁺ : Sublist (Sublist R) ass bss → Sublist R (concat ass) (concat bss)```* Added new proof to `Data.List.Membership.Setoid.Properties`:```agdaunique⇒irrelevant : Irrelevant _≈_ → Unique xs → Irrelevant (_∈ xs)```* Added new proofs to `Data.List.Relation.Binary.Sublist.Propositional.Properties`:```agdaAll-resp-⊆ : (All P) Respects (flip _⊆_)Any-resp-⊆ : (Any P) Respects _⊆_```* Added new operations to `Data.List.Relation.Unary.All`:```agdalookupAny : All P xs → (i : Any Q xs) → (P ∩ Q) (lookup i)lookupWith : ∀[ P ⇒ Q ⇒ R ] → All P xs → (i : Any Q xs) → R (lookup i)uncons : All P (x ∷ xs) → P x × All P xsreduce : (f : ∀ {x} → P x → B) → ∀ {xs} → All P xs → List Bconstruct : (f : B → ∃ P) (xs : List B) → ∃ (All P)fromList : (xs : List (∃ P)) → All P (List.map proj₁ xs)toList : All P xs → List (∃ P)self : All (const A) xs```* Added new proofs to `Data.List.Relation.Unary.All.Properties`:```agdaAll-swap : All (λ xs → All (xs ~_) ys) xss → All (λ y → All (_~ y) xss) ysapplyDownFrom⁺₁ : (∀ {i} → i < n → P (f i)) → All P (applyDownFrom f n)applyDownFrom⁺₂ : (∀ i → P (f i)) → All P (applyDownFrom f n)```* Added new proofs to `Data.List.Relation.Unary.Any.Properties`:```agdaAny-Σ⁺ʳ : (∃ λ x → Any (_~ x) xs) → Any (∃ ∘ _~_) xsAny-Σ⁻ʳ : Any (∃ ∘ _~_) xs → ∃ λ x → Any (_~ x) xsgmap : P ⋐ Q ∘ f → Any P ⋐ Any Q ∘ map f```* Added new functions to `Data.Maybe.Base`:```agdaap : Maybe (A → B) → Maybe A → Maybe B_>>=_ : Maybe A → (A → Maybe B) → Maybe B```* Added new proofs to `Data.Nat.Divisibility`:```agda∣m∸n∣n⇒∣m : n ≤ m → i ∣ m ∸ n → i ∣ n → i ∣ m∣n∣m%n⇒∣m : d ∣ n → d ∣ (m % n) → d ∣ m*-monoˡ-∣ : i ∣ j → i * k ∣ j * k%-presˡ-∣ : d ∣ m → d ∣ n → d ∣ (m % n)m/n∣m : n ∣ m → m / n ∣ mm*n∣o⇒m∣o/n : m * n ∣ o → m ∣ o / nm*n∣o⇒n∣o/m : m * n ∣ o → n ∣ o / mm∣n/o⇒m*o∣n : o ∣ n → m ∣ n / o → m * o ∣ nm∣n/o⇒o*m∣n : o ∣ n → m ∣ n / o → o * m ∣ nm/n∣o⇒m∣o*n : n ∣ m → m / n ∣ o → m ∣ o * nm∣n*o⇒m/n∣o : n ∣ m → m ∣ o * n → m / n ∣ o```* Added new operator and proofs to `Data.Nat.DivMod`:```agda_/_ = _div_m%n≤m : m % n ≤ mm≤n⇒m%n≡m : m ≤ n → m % n ≡ m%-remove-+ˡ : d ∣ m → (m + n) % d ≡ n % d%-remove-+ʳ : d ∣ n → (m + n) % d ≡ m % d%-pred-≡0 : suc m % n ≡ 0 → m % n ≡ n ∸ 1m<[1+n%d]⇒m≤[n%d] : m < suc n % d → m ≤ n % d[1+m%d]≤1+n⇒[m%d]≤n : 0 < suc m % d → suc m % d ≤ suc n → m % d ≤ n0/n≡0 : 0 / n ≡ 0n/1≡n : n / 1 ≡ nn/n≡1 : n / n ≡ 1m*n/n≡m : m * n / n ≡ mm/n*n≡m : n ∣ m → m / n * n ≡ mm*[n/m]≡n : m ∣ n → m * (n / m) ≡ nm/n*n≤m : m / n * n ≤ mm/n<m : m ≥ 1 → n ≥ 2 → m / n < m*-/-assoc : d ∣ n → (m * n) / d ≡ m * (n / d)+-distrib-/ : m % d + n % d < d → (m + n) / d ≡ m / d + n / d+-distrib-/-∣ˡ : d ∣ m → (m + n) / d ≡ m / d + n / d+-distrib-/-∣ʳ : d ∣ n → (m + n) / d ≡ m / d + n / d```Additionally the `{≢0 : False (divisor ℕ.≟ 0)}` argument to all thedivision and modulus functions has been marked irrelevant. One useful consequenceof this is that the operations `_%_`, `_/_` etc. can now be used with `cong`.* Added new proofs to `Data.Nat.GCD`:```agdagcd[m,n]∣m : gcd m n ∣ mgcd[m,n]∣n : gcd m n ∣ ngcd-greatest : c ∣ m → c ∣ n → c ∣ gcd m ngcd[0,0]≡0 : gcd 0 0 ≡ 0gcd[m,n]≢0 : m ≢ 0 ⊎ n ≢ 0 → gcd m n ≢ 0gcd-comm : gcd m n ≡ gcd n mgcd-universality : (∀ {d} → d ∣ m × d ∣ n → d ∣ g) → (∀ {d} → d ∣ g → d ∣ m × d ∣ n) → g ≡ gcd m ngcd[cm,cn]/c≡gcd[m,n] : gcd (c * m) (c * n) / c ≡ gcd m nc*gcd[m,n]≡gcd[cm,cn] : c * gcd m n ≡ gcd (c * m) (c * n)```* Added new proofs to `Data.Nat.LCM`:```agdam∣lcm[m,n] : m ∣ lcm m nn∣lcm[m,n] : n ∣ lcm m nlcm-least : m ∣ c → n ∣ c → lcm m n ∣ clcm[0,n]≡0 : lcm 0 n ≡ 0lcm[n,0]≡0 : lcm n 0 ≡ 0lcm-comm : lcm m n ≡ lcm n mgcd*lcm : gcd m n * lcm m n ≡ m * n```* Added new proofs to `Data.Nat.Properties`:```agda≤-<-connex : Connex _≤_ _<_≥->-connex : Connex _≥_ _>_<-≤-connex : Connex _<_ _≤_>-≥-connex : Connex _>_ _≥_1+n≢0 : suc n ≢ 0<ᵇ⇒< : T (m <ᵇ n) → m < n<⇒<ᵇ : m < n → T (m <ᵇ n)n≢0⇒n>0 : n ≢ 0 → n > 0m≤m*n : 0 < n → m ≤ m * nm<m*n : 0 < m → 1 < n → m < m * nm∸n≢0⇒n<m : m ∸ n ≢ 0 → n < m*-cancelʳ-< : RightCancellative _<_ _*_*-cancelˡ-< : LeftCancellative _<_ _*_*-cancel-< : Cancellative _<_ _*_⊔-least : m ≤ o → n ≤ o → m ⊔ n ≤ o⊓-greatest : m ≥ o → n ≥ o → m ⊓ n ≥ o```* Added new function to `Data.Product`:```agdazip′ : (A → B → C) → (D → E → F) → A × D → B × E → C × F```* Added new proofs to `Data.Product.Properties`:```agda,-injectiveʳ : (a , b) ≡ (c , d) → b ≡ d,-injective : (a , b) ≡ (c , d) → a ≡ c × b ≡ d≡-dec : Decidable {A} _≡_ → Decidable {B} _≡_ → Decidable {A × B} _≡_```* Added new relations to `Data.Rational.Base`:```agda_<_ : Rel ℚ 0ℓ_≥_ : Rel ℚ 0ℓ_>_ : Rel ℚ 0ℓ_≰_ : Rel ℚ 0ℓ_≱_ : Rel ℚ 0ℓ_≮_ : Rel ℚ 0ℓ_≯_ : Rel ℚ 0ℓ```* Added new proofs and modules to `Data.Rational.Properties`:```agda≡-setoid : Setoid 0ℓ 0ℓ≡-decSetoid : DecSetoid 0ℓ 0ℓdrop-*<* : p < q → (↥ p ℤ.* ↧ q) ℤ.< (↥ q ℤ.* ↧ p)<⇒≤ : _<_ ⇒ _≤_<-irrefl : Irreflexive _≡_ _<_<-asym : Asymmetric _<_<-≤-trans : Trans _<_ _≤_ _<_≤-<-trans : Trans _≤_ _<_ _<_<-trans : Transitive _<__<?_ : Decidable _<_<-cmp : Trichotomous _≡_ _<_<-irrelevant : Irrelevant _<_<-respʳ-≡ : _<_ Respectsʳ _≡_<-respˡ-≡ : _<_ Respectsˡ _≡_<-resp-≡ : _<_ Respects₂ _≡_<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓmodule ≤-Reasoning```* Added new proofs to `Data.Sign.Properties`:```agda≡-setoid : Setoid 0ℓ 0ℓ≡-decSetoid : DecSetoid 0ℓ 0ℓ```* Added new definitions and functions to `Data.String.Base`:```agda_≈_ : Rel String 0ℓ_<_ : Rel String 0ℓfromChar : Char → String```* Added new properties to `Data.String.Properties`:```agda≈⇒≡ : _≈_ ⇒ _≡_≈-reflexive : _≡_ ⇒ _≈_≈-refl : Reflexive _≈_≈-sym : Symmetric _≈_≈-trans : Transitive _≈_≈-subst : Substitutive _≈_ ℓ_≈?_ : Decidable _≈_≈-isEquivalence : IsEquivalence _≈_≈-setoid : Setoid _ _≈-isDecEquivalence : IsDecEquivalence _≈_≈-decSetoid : DecSetoid _ __<?_ : Decidable _<_```* Added new functions to `Data.Vec.Base`:```agdarestrictWith : (A → B → C) → Vec A m → Vec B n → Vec C (m ⊓ n)restrict : Vec A m → Vec B n → Vec (A × B) (m ⊓ n)```* Added new functions to `Data.Vec`:```agdafilter : Decidable P → Vec A n → Vec≤ A ntakeWhile : Decidable P → Vec A n → Vec≤ A ndropWhile : Decidable P → Vec A n → Vec≤ A n```* The special term `Setω` is now exported by `Level`.* Added new types, functions and proofs to `Reflection`:```agdaNames = List NameArgs A = List (Arg A)map-Arg : (A → B) → Arg A → Arg Bmap-Args : (A → B) → Args A → Args Bmap-Abs : (A → B) → Abs A → Abs Breduce : Term → TC TermdeclarePostulate : Arg Name → Type → TC ⊤commitTC : TC ⊤isMacro : Name → TC BoolwithNormalisation : Bool → TC A → TC A_>>=_ : TC A → (A → TC B) → TC B_>>_ : TC A → TC B → TC Bassocˡ : Associativityassocʳ : Associativitynon-assoc : Associativityunrelated : Precedencerelated : Int → Precedencefixity : Associativity → Precedence → FixitygetFixity : Name → FixityvArg ty = arg (arg-info visible relevant) tyhArg ty = arg (arg-info hidden relevant) tyiArg ty = arg (arg-info instance′ relevant) tyvLam s t = lam visible (abs s t)hLam s t = lam hidden (abs s t)iLam s t = lam instance′ (abs s t)Π[_∶_]_ s a ty = pi a (abs s ty)vΠ[_∶_]_ s a ty = Π[ s ∶ (vArg a) ] tyhΠ[_∶_]_ s a ty = Π[ s ∶ (hArg a) ] tyiΠ[_∶_]_ s a ty = Π[ s ∶ (iArg a) ] ty```* Added new definition to `Setoid` in `Relation.Binary`:```agdax ≉ y = ¬ (x ≈ y)```* Added new definitions in `Relation.Binary.Core`:```agdaUniversal _∼_ = ∀ x y → x ∼ yRecomputable _~_ = ∀ {x y} → .(x ~ y) → x ~ y```* Added new proof to `Relation.Binary.Consequences`:```agdadec⟶recomputable : Decidable R → Recomputable Rflip-Connex : Connex P Q → Connex Q P```* Added new proofs to `Relation.Binary.Construct.Add.(Infimum/Supremum/Extrema).NonStrict`:```agda≤±-reflexive-≡ : (_≡_ ⇒ _≤_) → (_≡_ ⇒ _≤±_)≤±-antisym-≡ : Antisymmetric _≡_ _≤_ → Antisymmetric _≡_ _≤±_≤±-isPreorder-≡ : IsPreorder _≡_ _≤_ → IsPreorder _≡_ _≤±_≤±-isPartialOrder-≡ : IsPartialOrder _≡_ _≤_ → IsPartialOrder _≡_ _≤±_≤±-isDecPartialOrder-≡ : IsDecPartialOrder _≡_ _≤_ → IsDecPartialOrder _≡_ _≤±_≤±-isTotalOrder-≡ : IsTotalOrder _≡_ _≤_ → IsTotalOrder _≡_ _≤±_≤±-isDecTotalOrder-≡ : IsDecTotalOrder _≡_ _≤_ → IsDecTotalOrder _≡_ _≤±_```* Added new proofs to `Relation.Binary.Construct.Add.(Infimum/Supremum/Extrema).Strict`:```agda<±-respˡ-≡ : _<±_ Respectsˡ _≡_<±-respʳ-≡ : _<±_ Respectsʳ _≡_<±-resp-≡ : _<±_ Respects₂ _≡_<±-cmp-≡ : Trichotomous _≡_ _<_ → Trichotomous _≡_ _<±_<±-irrefl-≡ : Irreflexive _≡_ _<_ → Irreflexive _≡_ _<±_<±-isStrictPartialOrder-≡ : IsStrictPartialOrder _≡_ _<_ → IsStrictPartialOrder _≡_ _<±_<±-isDecStrictPartialOrder-≡ : IsDecStrictPartialOrder _≡_ _<_ → IsDecStrictPartialOrder _≡_ _<±_<±-isStrictTotalOrder-≡ : IsStrictTotalOrder _≡_ _<_ → IsStrictTotalOrder _≡_ _<±_```* In `Relation.Binary.HeterogeneousEquality` the relation `_≅_` hasbeen generalised so that the types of the two equal elements need notbe at the same universe level.* Added new proof to `Relation.Binary.PropositionalEquality.Core`:```agda≢-sym : Symmetric _≢_```* Added new proofs to `Relation.Nullary.Construct.Add.Point`:```agda≡-dec : Decidable {A = A} _≡_ → Decidable {A = Pointed A} _≡_[]-injective : [ x ] ≡ [ y ] → x ≡ y```* Added new type and syntax to `Relation.Unary`:```agdaRecomputable P = ∀ {x} → .(P x) → P xsyntax Satisfiable P = ∃⟨ P ⟩```* Added new proof to `Relation.Unary.Consequences`:```agdadec⟶recomputable : Decidable R → Recomputable R```* Added new aliases for `IdempotentCommutativeMonoid` in `Algebra`:```agdaBoundedLattice = IdempotentCommutativeMonoidIsBoundedLattice = IsIdempotentCommutativeMonoid```* Added new functions to `Function`:```agda_$- : ((x : A) → B x) → ({x : A} → B x)λ- : ({x : A} → B x) → ((x : A) → B x)```* Added new definition and proof to `Axiom.Extensionality.Propositional`:```agdaExtensionalityImplicit = (∀ {x} → f {x} ≡ g {x}) → (λ {x} → f {x}) ≡ (λ {x} → g {x})implicit-extensionality : Extensionality a b → ExtensionalityImplicit a b```* Added new definition in `Relation.Nullary`:```agdaIrrelevant P = ∀ (p₁ p₂ : P) → p₁ ≡ p₂```* Added new proofs to `Relation.Nullary.Decidable.Core`:```agdadec-yes : (p? : Dec P) → P → ∃ λ p′ → p? ≡ yes p′dec-no : (p? : Dec P) → ¬ P → ∃ λ ¬p′ → p? ≡ no ¬p′dec-yes-irr : (p? : Dec P) → Irrelevant P → (p : P) → p? ≡ yes p```
Version 1.0===========The library has been tested using Agda version 2.6.0.Important changes since 0.17:Highlights----------* The library has been refactored to make clear where axiom K is used andwhere it is not. Hence it can now be used in conjunction with the`--without-k` option.* Equational and inequality reasoning has been revamped. Several newprimitives have been added and the inequality reasoning modules can nowprove equalities and strict inequalities in addition to basic inequalities.* AVL trees now work with arbitrary equalities rather than only propositionalequality.* New top level `Axiom` directory which contains statements of variousadditional axioms such as excluded middle and function extensionality whichusers may want to postulate.* The proofs `_≟_` of decidable equality for `String`s and `Char`s have beenmade safe.New modules-----------* The following list contains all the new modules that have been added in v1.0:```Algebra.Construct.NaturalChoice.MinAlgebra.Construct.NaturalChoice.MaxAlgebra.Properties.SemilatticeAlgebra.FunctionProperties.Consequences.PropositionalAxiom.UniquenessOfIdentityProofsAxiom.UniquenessOfIdentityProofs.WithKAxiom.ExcludedMiddleAxiom.DoubleNegationEliminationAxiom.Extensionality.PropositionalAxiom.Extensionality.HeterogeneousCodata.CowriterCodata.M.PropertiesCodata.M.BisimilarityData.Container.Combinator.PropertiesData.Container.MembershipData.Container.MorphismData.Container.Morphism.PropertiesData.Container.PropertiesData.Container.RelatedData.Container.Relation.Unary.AllData.Container.Relation.Unary.AnyData.Container.Relation.Unary.Any.PropertiesData.Container.Relation.Binary.Equality.SetoidData.Container.Relation.Binary.PointwiseData.Container.Relation.Binary.Pointwise.PropertiesData.Char.PropertiesData.Integer.Divisibility.PropertiesData.Integer.Divisibility.SignedData.Integer.DivModData.List.Relation.Unary.FirstData.List.Relation.Unary.First.PropertiesData.List.Relation.Binary.Suffix.HeterogeneousData.List.Relation.Binary.Suffix.Heterogeneous.PropertiesData.List.Relation.Binary.Prefix.HeterogeneousData.List.Relation.Binary.Prefix.Heterogeneous.PropertiesData.List.Relation.Binary.Sublist.HeterogeneousData.List.Relation.Binary.Sublist.Heterogeneous.PropertiesData.List.Relation.Binary.Sublist.Heterogeneous.SolverData.List.Relation.Binary.Sublist.SetoidData.List.Relation.Binary.Sublist.Setoid.PropertiesData.List.Relation.Binary.Sublist.DecSetoidData.List.Relation.Binary.Sublist.DecSetoid.SolverData.List.Relation.Binary.Sublist.PropositionalData.List.Relation.Binary.Sublist.Propositional.PropertiesData.List.Relation.Binary.Sublist.DecPropositionalData.List.Relation.Binary.Sublist.DecPropositional.SolverData.List.Relation.Ternary.Interleaving.SetoidData.List.Relation.Ternary.Interleaving.Setoid.PropertiesData.List.Relation.Ternary.Interleaving.PropositionalData.List.Relation.Ternary.Interleaving.Propositional.PropertiesData.Maybe.Relation.Unary.All.PropertiesData.String.PropertiesData.These.PropertiesData.Vec.Any.PropertiesData.Vec.Membership.SetoidData.Vec.Membership.DecSetoidData.Vec.Membership.DecPropositionalData.Vec.Relation.Unary.Any.PropertiesDebug.TraceFunction.Endomophism.SetoidFunction.Endomophism.PropositionalFunction.HalfAdjointEquivalenceRelation.Binary.Construct.Add.Extrema.EqualityRelation.Binary.Construct.Add.Extrema.StrictRelation.Binary.Construct.Add.Extrema.NonStrictRelation.Binary.Construct.Add.Infimum.EqualityRelation.Binary.Construct.Add.Infimum.StrictRelation.Binary.Construct.Add.Infimum.NonStrictRelation.Binary.Construct.Add.Supremum.EqualityRelation.Binary.Construct.Add.Supremum.StrictRelation.Binary.Construct.Add.Supremum.NonStrictRelation.Binary.Construct.Add.Point.EqualityRelation.Binary.Construct.IntersectionRelation.Binary.Construct.UnionRelation.Binary.Construct.NaturalOrder.LeftRelation.Binary.Construct.NaturalOrder.RightRelation.Binary.Properties.BoundedLatticeRelation.Nullary.Construct.Add.ExtremaRelation.Nullary.Construct.Add.InfimumRelation.Nullary.Construct.Add.SupremumRelation.Nullary.Construct.Add.Point```Non-backwards compatible changes--------------------------------#### Extending the relation hierarchy for container datatypes* This release has added many new relations over `List` (e.g. `First`,`Suffix`, `Prefix`, `Interleaving`) and it has become clear that thecurrent hierarchy for relations in `List`,`Product`,`Sum`, `Table`and `Vec`is not deep enough.* To address this, the contents of `Data.X.Relation` have been moved to`Data.X.Relation.Binary` and new folders `Data.X.Relation.(Unary/Ternary)`have been created. `Data.X.(All/Any)` have been moved to`Data.X.Relation.Unary.(All/Any)`.* The old modules still exist for backwards compatability but are deprecated.#### Support for `--without-K`* The `--without-K` flag has been enabled in as many files as possible. Anattempt has been made to only do this in files that do not depend onany file in which this flag is not enabled.* Agda uses different rules for the target universe of data types whenthe `--without-K` flag is used, and because of this a number of typefamilies now target a possibly larger universe:- Codata.Delay.Bisimilarity : `Bisim`- Codata.Musical.Covec : `_≈_`, `_∈_`, `_⊑_`- Codata.Stream.Bisimilarity : `Bisim`- Data.List.Relation.Binary.Equality.Setoid : `_≋_`- Data.List.Relation.Binary.Lex.NonStrict : `Lex-<`, `Lex-≤`- Data.List.Relation.Binary.Lex.Strict : `Lex-<`, `Lex-≤`- Data.List.Relation.Binary.Pointwise : `Pointwise`- Data.List.Relation.Unary.All : `All`- Data.Maybe : `Is-just`, `Is-nothing`- Data.Maybe.Relation.Unary.Any : `Any`- Data.Maybe.Relation.Unary.All : `All`- Data.Maybe.Relation.Binary.Pointwise : `Pointwise`* Because of this change the texts of some type signatures were changed(some inferred parts of other type signatures may also have changed):- Data.List.Relation.Binary.Equality.DecSetoid : `≋-decSetoid`- Data.Maybe.Relation.Binary.Pointwise : `setoid`, `decSetoid`* Some code that relies on the K rule or uses heterogeneous equality hasbeen moved from the existing file `X` to a new file `X.WithK` file(e.g. from `Data.AVL.Indexed` to `Data.AVL.Indexed.WithK`). These are as follows:- `Data.AVL.Indexed` : `node-injective-bal, node-injectiveʳ, node-injectiveˡ`- `Data.Container.Indexed` : `Eq, Map.composition, Map.identity, PlainMorphism.NT, PlainMorphism.Natural, PlainMorphism.complete, PlainMorphism.natural, PlainMorphism.∘-correct, setoid, _∈_`- `Data.Product.Properties` : `,-injectiveʳ`- `Data.Product.Relation.Binary.Pointwise.Dependent` : `Pointwise-≡⇒≡, ≡⇒Pointwise-≡, inverse, ↣`- `Data.Vec.Properties` : `++-assoc, []=-irrelevance, foldl-cong, foldr-cong`- `Data.Vec.Relation.Binary.Equality.Propositional` : `≋⇒≅`- `Data.W` : `sup-injective₂`- `Relation.Binary.Construct.Closure.Transitive` : `∼⁺⟨⟩-injectiveʳ, ∼⁺⟨⟩-injectiveˡ`- `Relation.Binary.Construct.Closure.ReflexiveTransitive.Properties` : `◅-injectiveʳ, ◅-injectiveˡ`- `Relation.Binary.PropositionalEquality` : `≡-irrelevance`(The name `↣` in `Data.Product.Relation.Binary.Pointwise.Dependent` now refers to a newdefinition with another type signature.)* Other code has been changed to avoid use of the K rule. As part ofsuch changes the texts of the following type signatures have beenchanged:- `Data.AVL.Indexed` : `node-injective-key`- `Data.List.Relation.Binary.Sublist.Propositional.Properties` : `∷⁻`- `Data.Product.Relation.Binary.Pointwise.Dependent` : `↣`- `Relation.Binary.PropositionalEquality` : `≡-≟-identity`(The old definition of `↣` was moved to `Data.Product.Relation.Binary.Pointwise.Dependent.WithK`.)* The definition `_≅⟨_⟩_` has been removed from `Relation.Binary.PropositionalEquality`.* The following previously deprecated names have also been removed:- `Data.Product.Relation.Binary.Pointwise.Dependent` : `Rel↔≡`- `Data.Vec.Properties` : `proof-irrelevance-[]=`- `Relation.Binary.PropositionalEquality` : `proof-irrelevance`#### Changes to the algebra hierarchy* Over time the algebra inheritance hierarchy has become a tangleddue to poorly structured additions. The following changes attemptto straighten the hierarchy out and new policies have been put inplace so that the need for additional such changes will be minimisedin the future.* Added `Magma` and `IsMagma` to the algebra hierarchy.* The name `RawSemigroup` in `Algebra` has been deprecated in favourof `RawMagma`.* The fields `isEquivalence` and `∙-cong` in `IsSemigroup` have beenreplaced with `isMagma`.* The field `∙-cong` in `IsSemilattice`/`Semilattice` has been renamed`∧-cong`.* The record `BooleanAlgebra` now exports `∨-isSemigroup`, `∧-isSemigroup`directly so `Algebra.Properties.BooleanAlgebra` no longer does so.* The proof that every algebraic lattice induces a partial order has beenmoved from `Algebra.Properties.Lattice` to`Algebra.Properties.Semilattice`. The corresponding `poset` instance isre-exported in `Algebra.Properties.Lattice`.* All algebraic structures now export left and right congruence properties.For example this means `∙-cong refl x≈y` can be replaced with `∙-congˡ y≈z`#### Upgrade of equational and inequality reasoning* The core Reasoning modules have been renamed as follows:```Relation.Binary.EqReasoning ↦ Relation.Binary.Reasoning.SetoidRelation.Binary.SetoidReasoning ↦ Relation.Binary.Reasoning.MultiSetoidRelation.Binary.PreorderReasoning ↦ Relation.Binary.Reasoning.PreorderRelation.Binary.PartialOrderReasoning ↦ Relation.Binary.Reasoning.PartialOrderRelation.Binary.StrictPartialOrderReasoning ↦ Relation.Binary.Reasoning.StrictPartialOrder```The old modules have been deprecated but still exist for backwards compatibility reasons.* The way reasoning is implemented has been changed. In particular all of the abovemodules are specialised instances of the three modules`Relation.Binary.Reasoning.Base.(Single/Double/Triple)`. This means that if you haveextended the reasoning modules yourself you may need to update the extensions.However all *uses* of the reasoning modules are fully backwards compatible.* The new implementation allows the interleaving of both strict and non-strict linksin proofs. For example where as before the following:```agdabegina ≤⟨ x≤y ⟩b <⟨ y<z ⟩c ≤⟨ x≤y ⟩d ∎```was not a valid proof that `a ≤ d` due to the `<` link in the middle, it is now accepted.* The new implementation can now be used to prove both equalities and strict inequalities aswell as basic inequalities. To do so use the new `begin-equality` and `begin-strict` combinators.For instance replacing `begin` with `begin-strict` in the example above:```agdabegin-stricta ≤⟨ x≤y ⟩b <⟨ y<z ⟩c ≤⟨ x≤y ⟩d ∎```proves that `a < d` rather than `a ≤ d`.* New symmetric equality combinators `_≈˘⟨_⟩_` and `_≡˘⟨_⟩_` have been added. Consequentlyexpressions of the form `x ≈⟨ sym y≈x ⟩ y` can be replaced with `x ≈˘⟨ y≈x ⟩ y`.#### New `Axiom` modules* A new top level `Axiom` directory has been created that contains modulesfor various additional axioms that users may want to postulate.* `Excluded-Middle` and associated proofs have been moved out of `Relation.Nullary.Negation`and into `Axiom.ExcludedMiddle`.* `Extensionality` and associated proofs have been moved out of`Relation.Binary.PropositionalEquality` and into `Axiom.Extensionality.Propositional`.* `Extensionality` and associated proofs have been moved out of`Relation.Binary.HeterogeneousEquality` and into `Axiom.Extensionality.Heterogeneous`.* The old names still exist for backwards compatability but have been deprecated.* Changed the type of `≡-≟-identity` in `Relation.Binary.PropositionalEquality`to make use of the fact that equality being decidable implies uniqueness of identity proofs.#### Relaxation of ring solvers requirements* In the ring solvers the assumption that equality is `Decidable`has been replaced by a strictly weaker assumption that it is `WeaklyDecidable`.This allows the solvers to be used when equality is not fully decidable.```Algebra.Solver.RingAlgebra.Solver.Ring.NaturalCoefficients```* Created a module `Algebra.Solver.Ring.NaturalCoefficients.Default` thatinstantiates the solver for any `CommutativeSemiring`.#### New `Data.Sum/Product.Function` directories* Various combinators for types of functions (injections, surjections, inverses etc.)over `Sum` and `Product` currently live in the `Data.(Product/Sum).Relation.Binary.Pointwise`modules. These are poorly placed as the properties a) do not directly reference `Pointwise`and b) are very hard to locate.* They have therefore been moved into the new `Data.(Product/Sum).Function` directoryas follows:```Data.Product.Relation.Binary.Pointwise.Dependent ↦ Data.Product.Function.Dependent.Setoid↘ Data.Product.Function.Dependent.PropositionalData.Product.Relation.Binary.Pointwise.NonDependent ↦ Data.Product.Function.NonDependent.Setoid↘ Data.Product.Function.NonDependent.PropositionalData.Sum.Relation.Binary.Pointwise.Dependent ↦ Data.Sum.Function.Setoid↘ Data.Sum.Function.Propositional```All the proofs about `Pointwise` remain untouched.#### Overhaul of `Data.AVL`* AVL trees now work over arbitrary equalities, rather than justpropositional equality.* Consequently the family of `Value`s stored in the tree now needto respect the `Key` equivalence* The module parameter for `Data.AVL`, `Data.AVL.Indexed`, `Data.AVL.Key`,`Data.AVL.Sets` is now a `StrictTotalOrder` rather than a`IsStrictTotalOrder`, and the module parameter for `Data.AVL.Value` isnow takes a `Setoid` rather than an `IsEquivalence`.* It was noticed that `Data.AVL.Indexed`'s lookup & delete didn't usea range to guarantee that the recursive calls were performed in theright subtree. The types have been made more precise.* The functions `(insert/union)With` now take a function of type`Maybe Val -> Val` rather than a value together with a merging function`Val -> Val -> Val` to handle the case where a value is already presentat that key.* Various functions have been made polymorphic which makes their biases& limitations clearer. e.g. we have:`unionWith : (V -> Maybe W -> W) -> Tree V -> Tree W -> Tree W`but ideally we would like to have:`unionWith : (These V W -> X) -> Tree V -> Tree W -> Tree X`* Keys are now implemented via the new `Relation.(Binary/Nullary).Construct.AddExtrema`modules.#### Overhaul of `Data.Container`* `Data.Container` has been split up into the standard hierarchy.* Moved `Data.Container`'s `All` and `Any` into their own`Data.Container.Relation.Unary.X` module. Made them record typesto improve type inference.* Moved morphisms to `Data.Container.Morphism` and their propertiesto `Data.Container.Morphism.Properties`.* Made the index set explicit in `Data.Container.Combinator`'s `Π` and `Σ`.* Moved `Eq` to `Data.Container.Relation.Binary.Pointwise`(and renamed it to `Pointwise`) and its properties to`Data.Container.Relation.Binary.Pointwise.Properties`.* The type family `Data.Container.ν` is now defined using `Codata.M.M`rather than Codata.Musical.M.M`.#### Overhaul of `Data.Maybe`* `Data.Maybe` has been split up into the standard hierarchy forcontainer datatypes.* Moved `Data.Maybe.Base`'s `Is-just`, `Is-nothing`, `to-witness`,and `to-witness-T` to `Data.Maybe` (they rely on `All` and `Any`which are now outside of `Data.Maybe.Base`).* Moved `Data.Maybe.Base`'s `All` and `Data.Maybe`'s `allDec` to`Data.Maybe.Relation.Unary.All` and renamed the proof `allDec` to `dec`.* Moved `Data.Maybe.Base`'s `Any` and `Data.Maybe`'s `anyDec` to`Data.Maybe.Relation.Unary.Any` and renamed the proof `anyDec` to `dec`.* Created `Data.Maybe.Properties` and moved `Data.Maybe.Base`'s `just-injective`into it and added new results.* Moved `Data.Maybe`'s `Eq` to `Data.Maybe.Relation.Binary.Pointwise`, made therelation heterogeneously typed and renamed the following proofs:```agdaEq ↦ PointwiseEq-refl ↦ reflEq-sym ↦ symEq-trans ↦ transEq-dec ↦ decEq-isEquivalence ↦ isEquivalenceEq-isDecEquivalence ↦ isDecEquivalence```#### Overhaul of `Data.Sum.Relation.Binary`* The implementations of `Data.Sum.Relation.Binary.(Pointwise/LeftOrder)` have been alteredto bring them in line with implementations of similar orders for other datatypes.Namely they are no longer specialised instances of some `Core` module.* The constructor `₁∼₂` for `LeftOrder` no longer takes an argument of type `⊤`.* The constructor `₁∼₁` and `₂∼₂` in `Pointwise` have been renamed `inj₁` and `inj₂`respectively. The old names still exist but have been deprecated.#### Overhaul of `MonadZero` and `MonadPlus`* Introduce `RawIApplicativeZero` for an indexed applicative with a zeroand `RawAlternative` for an indexed applicative with a zero and a sum.* `RawIMonadZero` is now packing a `RawIApplicativeZero` rather than a `∅` directly* Similarly `RawIMonadPlus` is defined in terms of `RawIAlternative` rather thandirectly packing a _∣_.* Instances will be broken but usages should still work thanks to re-exports strivingto maintain backwards compatibility.#### Overhaul of `Data.Char` and `Data.String`* Moved `setoid` and `strictTotalOrder` from `Data.(Char/String)` into the newmodule `Data.(Char/String).Properties`.* Used the new builtins from `Agda.Builtin.(Char/String).Properties` to implementdecidable equality (`_≟_`) in a safe manner. This has allowed `_≟_`,`decSetoid` and `_==_` to be moved from `Data.(Char/String).Unsafe` to`Data.(Char/String).Properties`.#### Overhaul of `Data.Rational`* Many new operators have been added to `Data.Rational` includingaddition, substraction, multiplication, inverse etc.* The existing operator `_÷_` has been renamed `_/_` and is now more liberalas it now accepts non-coprime arguments (e.g. `+ 2 / 4`) which are thennormalised.* The old name `_÷_` has been repurposed to represent division between tworationals.* The proofs `drop-*≤*`, `≃⇒≡` and `≡⇒≃` have been moved from `Data.Rational`to `Data.Rational.Properties`.#### Changes in `Data.List`* In `Data.List.Membership.Propositional.Properties`:- the `Set` argument has been made implicit in `∈-++⁺ˡ`, `∈-++⁺ʳ`, `∈-++⁻`, `∈-insert`, `∈-∃++`.- the `A → B` argument has been made explicit in `∈-map⁺`, `∈-map⁻`, `map-∈↔`.* The module `Data.List.Relation.Binary.Sublist.Propositional.Solver` has been removedand replaced by `Data.List.Relation.Binary.Sublist.DecPropositional.Solver`.* The functions `_∷=_` and `_─_` have been removed from `Data.List.Membership.Setoid`as they are subsumed by the more general versions now part of `Data.List.Any`.#### Changes in `Data.Nat`* Changed the implementation of `_≟_` and `_≤″?_` for natural numbersto use a (fast) boolean test. Compiled code that uses these shouldnow run faster.* Made the contents of the modules `Data.Nat.Unsafe` and `Data.Nat.DivMod.Unsafe`safe by using the new safe equality erasure primitive instead of theunsafe one defined in `Relation.Binary.PropositionalEquality.TrustMe`. As thesafe erasure primitive requires the K axiom the two files are now named`Data.Nat.WithK` and `Data.Nat.DivMod.WithK`.* Fixed a bug in `Data.Nat.Properties` where the type of `m⊓n≤m⊔n` was`∀ m n → m ⊔ n ≤ m ⊔ n`. The type has been corrected to `∀ m n → m ⊓ n ≤ m ⊔ n`.#### Changes in `Data.Vec`* The argument order for `lookup`, `insert` and `remove` in `Data.Vec` has been alteredso that the `Vec` argument always come first, e.g. what was written as `lookup i v xs` isnow `lookup xs i v`. The argument order for the corresponding proofs has also changed.This makes the operations more consistent with those in `Data.List`.* The proofs `toList⁺` and `toList⁻` in `Data.Vec.Relation.Unary.All.Properties` have been swappedas they were the opposite way round to similar properties in the rest of the library.#### Other changes* The proof `sel⇒idem` in `Algebra.FunctionProperties.Consequences` nowonly takes the equality relation as an argument instead of a full `Setoid`.* The proof `_≟_` that equality is decidable for `Bool` has been movedfrom `Data.Bool.Base` to `Data.Bool.Properties`. Backwards compatibilityhas been (nearly completely) preserved by having `Data.Bool` publicly re-export `_≟_`.* The type `Coprime` and proof `coprime-divisor` have been moved from`Data.Integer.Divisibility` to `Data.Integer.Coprimality`.* The functions `fromMusical` and `toMusical` were moved from the `Codata` modulesto the corresponding `Codata.Musical` modules.Removed features----------------* The following modules that were deprecated in v0.14 and v0.15 have been removed.```agdaData.Nat.Properties.SimpleData.Integer.Multiplication.PropertiesData.Integer.Addition.PropertiesRelation.Binary.Sigma.PointwiseRelation.Binary.SumRelation.Binary.List.NonStrictLexRelation.Binary.List.PointwiseRelation.Binary.List.StrictLexRelation.Binary.Product.NonStrictLexRelation.Binary.Product.PointwiseRelation.Binary.Product.StrictLexRelation.Binary.Vec.Pointwise```Deprecated features-------------------The following renaming has occurred as part of a drive to improveconsistency across the library. The old names still exist and thereforeall existing code should still work, however they have been deprecatedand use of the new names is encouraged. Although not anticipated anytime soon, they may eventually be removed in some future release of the library.* In `Data.Bool.Properties`:```agdaT-irrelevance ↦ T-irrelevant```* In `Data.Fin.Properties`:```agda≤-irrelevance ↦ ≤-irrelevant<-irrelevance ↦ <-irrelevant```* In `Data.Integer.Properties`:```agda≰→> ↦ ≰⇒>≤-irrelevance ↦ ≤-irrelevant<-irrelevance ↦ <-irrelevant```* In `Data.List.Relation.Binary.Permutation.Inductive.Properties`:```agda↭⇒~bag ↦ ↭⇒∼bag~bag⇒↭ ↦ ∼bag⇒↭```(now typed with "\sim" rather than "~")* In `Data.List.Relation.Binary.Pointwise`:```agdadecidable-≡ ↦ Data.List.Properties.≡-dec```* In `Data.List.Relation.Unary.All.Properties`:```agdafilter⁺₁ ↦ all-filterfilter⁺₂ ↦ filter⁺```* In `Data.Nat.Properties`:```agda≤-irrelevance ↦ ≤-irrelevant<-irrelevance ↦ <-irrelevant```* In `Data.Rational`:```agdadrop-*≤*≃⇒≡≡⇒≃```(moved to `Data.Rational.Properties`)* In `Data.Rational.Properties`:```agda≤-irrelevance ↦ ≤-irrelevant```* In `Data.Vec.Properties.WithK`:```agda[]=-irrelevance ↦ []=-irrelevant```* In `Relation.Binary.HeterogeneousEquality`:```agda≅-irrelevance ↦ ≅-irrelevant≅-heterogeneous-irrelevance ↦ ≅-heterogeneous-irrelevant≅-heterogeneous-irrelevanceˡ ↦ ≅-heterogeneous-irrelevantˡ≅-heterogeneous-irrelevanceʳ ↦ ≅-heterogeneous-irrelevantʳ```* In `Induction.WellFounded`:```agdamodule Inverse-image ↦ InverseImagemodule Transitive-closure ↦ TransitiveClosure```* In `Relation.Binary.PropositionalEquality.WithK`:```agda≡-irrelevance ↦ ≡-irrelevant```Other minor additions---------------------* Added new records to `Algebra`:```agdarecord RawMagma c ℓ : Set (suc (c ⊔ ℓ))record Magma c ℓ : Set (suc (c ⊔ ℓ))```* Added new types to `Algebra.FunctionProperties`:```agdaLeftConical e _∙_ = ∀ x y → (x ∙ y) ≈ e → x ≈ eRightConical e _∙_ = ∀ x y → (x ∙ y) ≈ e → y ≈ eConical e ∙ = LeftConical e ∙ × RightConical e ∙LeftCongruent _∙_ = ∀ {x} → (x ∙_) Preserves _≈_ ⟶ _≈_RightCongruent _∙_ = ∀ {x} → (_∙ x) Preserves _≈_ ⟶ _≈_```* Added new proof to `Algebra.FunctionProperties.Consequences`:```agdawlog : Commutative f → Total _R_ → (∀ a b → a R b → P (f a b)) → ∀ a b → P (f a b)```* Added new proofs to `Algebra.Properties.Lattice`:```agda∧-isSemilattice : IsSemilattice _≈_ _∧_∧-semilattice : Semilattice l₁ l₂∨-isSemilattice : IsSemilattice _≈_ _∨_∨-semilattice : Semilattice l₁ l₂```* Added new operator to `Algebra.Solver.Ring`.```agda_:×_```* Added new records to `Algebra.Structures`:```agdarecord IsMagma (∙ : Op₂ A) : Set (a ⊔ ℓ)```* Added new proofs to `Category.Monad.State`:```agdaStateTIApplicative : RawMonad M → RawIApplicative (IStateT S M)StateTIApplicativeZero : RawMonadZero M → RawIApplicativeZero (IStateT S M)StateTIAlternative : RawMonadPlus M → RawIAlternative (IStateT S M)```* Added new functions to `Codata.Colist`:```agdafromCowriter : Cowriter W A i → Colist W itoCowriter : Colist A i → Cowriter A ⊤ i[_] : A → Colist A ∞chunksOf : (n : ℕ) → Colist A ∞ → Cowriter (Vec A n) (BoundedVec A n) ∞```* Added new proofs to `Codata.Delay.Categorical`:```agdaSequential.applicativeZero : RawApplicativeZero (λ A → Delay A i)Zippy.applicativeZero : RawApplicativeZero (λ A → Delay A i)Zippy.alternative : RawAlternative (λ A → Delay A i)```* Added new functions to `Codata.Stream`:```agdasplitAt : (n : ℕ) → Stream A ∞ → Vec A n × Stream A ∞drop : ℕ → Stream A ∞ → Stream A ∞interleave : Stream A i → Thunk (Stream A) i → Stream A ichunksOf : (n : ℕ) → Stream A ∞ → Stream (Vec A n) ∞```* Added new proofs to `Codata.Stream.Properties`:```agdasplitAt-map : splitAt n (map f xs) ≡ map (map f) (map f) (splitAt n xs)lookup-iterate-identity : lookup n (iterate f a) ≡ fold a f n```* Added new proofs to `Data.Bool.Properties`:```agda∧-isMagma : IsMagma _∧_∨-isMagma : IsMagma _∨_∨-isBand : IsBand _∨_∨-isSemilattice : IsSemilattice _∨_∧-isBand : IsBand _∧_∧-isSemilattice : IsSemilattice _∧_∧-magma : Magma 0ℓ 0ℓ∨-magma : Magma 0ℓ 0ℓ∨-band : Band 0ℓ 0ℓ∧-band : Band 0ℓ 0ℓ∨-semilattice : Semilattice 0ℓ 0ℓ∧-semilattice : Semilattice 0ℓ 0ℓT? : Decidable TT?-diag : T b → True (T? b)```* Added new functions to `Data.Char`:```agdatoUpper : Char → ChartoLower : Char → Char```* Added new functions to `Data.Fin.Base`:```agdacast : m ≡ n → Fin m → Fin nlower₁ : (i : Fin (suc n)) → (n ≢ toℕ i) → Fin n```* Added new proof to `Data.Fin.Properties`:```agdatoℕ-cast : toℕ (cast eq k) ≡ toℕ ktoℕ-inject₁-≢ : n ≢ toℕ (inject₁ i)inject₁-lower₁ : inject₁ (lower₁ i n≢i) ≡ ilower₁-inject₁′ : lower₁ (inject₁ i) n≢i ≡ ilower₁-inject₁ : lower₁ (inject₁ i) (toℕ-inject₁-≢ i) ≡ ilower₁-irrelevant : lower₁ i n≢i₁ ≡ lower₁ i n≢i₂```* Added new proofs to `Data.Fin.Subset.Properties`:```agda∩-isMagma : IsMagma _∩_∪-isMagma : IsMagma _∪_∩-isBand : IsBand _∩_∪-isBand : IsBand _∪_∩-isSemilattice : IsSemilattice _∩_∪-isSemilattice : IsSemilattice _∪_∩-magma : Magma _ _∪-magma : Magma _ _∩-band : Band _ _∪-band : Band _ _∩-semilattice : Semilattice _ _∪-semilattice : Semilattice _ _```* Added new proofs to `Data.Integer.Properties`:```agdasuc-pred : sucℤ (pred m) ≡ mpred-suc : pred (sucℤ m) ≡ mneg-suc : - + suc m ≡ pred (- + m)suc-+ : + suc m + n ≡ sucℤ (+ m + n)+-pred : m + pred n ≡ pred (m + n)pred-+ : pred m + n ≡ pred (m + n)minus-suc : m - + suc n ≡ pred (m - + n)[1+m]*n≡n+m*n : sucℤ m * n ≡ n + m * n⊓-comm : Commutative _⊓_⊓-assoc : Associative _⊓_⊓-idem : Idempotent _⊓_⊓-sel : Selective _⊓_m≤n⇒m⊓n≡m : m ≤ n → m ⊓ n ≡ mm⊓n≡m⇒m≤n : m ⊓ n ≡ m → m ≤ nm≥n⇒m⊓n≡n : m ≥ n → m ⊓ n ≡ nm⊓n≡n⇒m≥n : m ⊓ n ≡ n → m ≥ nm⊓n≤n : m ⊓ n ≤ nm⊓n≤m : m ⊓ n ≤ m⊔-comm : Commutative _⊔_⊔-assoc : Associative _⊔_⊔-idem : Idempotent _⊔_⊔-sel : Selective _⊔_m≤n⇒m⊔n≡n : m ≤ n → m ⊔ n ≡ nm⊔n≡n⇒m≤n : m ⊔ n ≡ n → m ≤ nm≥n⇒m⊔n≡m : m ≥ n → m ⊔ n ≡ mm⊔n≡m⇒m≥n : m ⊔ n ≡ m → m ≥ nm≤m⊔n : m ≤ m ⊔ nn≤m⊔n : n ≤ m ⊔ nneg-distrib-⊔-⊓ : - (m ⊔ n) ≡ - m ⊓ - nneg-distrib-⊓-⊔ : - (m ⊓ n) ≡ - m ⊔ - npred-mono : pred Preserves _≤_ ⟶ _≤_suc-mono : sucℤ Preserves _≤_ ⟶ _≤_⊖-monoʳ-≥-≤ : (p ⊖_) Preserves ℕ._≥_ ⟶ _≤_⊖-monoˡ-≤ : (_⊖ p) Preserves ℕ._≤_ ⟶ _≤_+-monoʳ-≤ : (_+_ n) Preserves _≤_ ⟶ _≤_+-monoˡ-≤ : (_+ n) Preserves _≤_ ⟶ _≤_+-monoˡ-< : (_+ n) Preserves _<_ ⟶ _<_+-monoʳ-< : (_+_ n) Preserves _<_ ⟶ _<_*-monoˡ-≤-pos : (+ suc n *_) Preserves _≤_ ⟶ _≤_*-monoʳ-≤-non-neg : (_* + n) Preserves _≤_ ⟶ _≤*-monoˡ-≤-non-neg : (+ n *_) Preserves _≤_ ⟶ _≤_+-mono-≤ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_neg-mono-≤-≥ : -_ Preserves _≤_ ⟶ _≥_neg-mono-<-> : -_ Preserves _<_ ⟶ _>_*-cancelˡ-≡ : i ≢ + 0 → i * j ≡ i * k → j ≡ k*-cancelˡ-≤-pos : + suc m * n ≤ + suc m * o → n ≤ oneg-≤-pos : - (+ m) ≤ + n0⊖m≤+ : 0 ⊖ m ≤ + nm≤n⇒m-n≤0 : m ≤ n → m - n ≤ + 0m-n≤0⇒m≤n : m - n ≤ + 0 → m ≤ nm≤n⇒0≤n-m : m ≤ n → + 0 ≤ n - m0≤n-m⇒m≤n : + 0 ≤ n - m → m ≤ nm≤pred[n]⇒m<n : m ≤ pred n → m < nm<n⇒m≤pred[n] : m < n → m ≤ pred nm≤m+n : m ≤ m + + nn≤m+n : n ≤ + m + nm-n≤m : m - + n ≤ m≤-<-trans : Trans _≤_ _<_ _<_<-≤-trans : Trans _<_ _≤_ _<_>→≰ : x > y → x ≰ y>-irrefl : Irreflexive _≡_ _>_pos-+-commute : Homomorphic₂ +_ ℕ._+_ _+_neg-distribˡ-* : - (x * y) ≡ (- x) * yneg-distribʳ-* : - (x * y) ≡ x * (- y)*-distribˡ-+ : _*_ DistributesOverˡ _+_≤-steps : m ≤ n → m ≤ + p + n≤-step-neg : m ≤ n → pred m ≤ n≤-steps-neg : m ≤ n → m - + p ≤ nm≡n⇒m-n≡0 : m ≡ n → m - n ≡ + 0m-n≡0⇒m≡n : m - n ≡ + 0 → m ≡ n0≤n⇒+∣n∣≡n : + 0 ≤ n → + ∣ n ∣ ≡ n+∣n∣≡n⇒0≤n : + ∣ n ∣ ≡ n → + 0 ≤ n◃-≡ : sign m ≡ sign n → ∣ m ∣ ≡ ∣ n ∣ → m ≡ n+-isMagma : IsMagma _+_*-isMagma : IsMagma _*_+-magma : Magma 0ℓ 0ℓ*-magma : Magma 0ℓ 0ℓ+-semigroup : Semigroup 0ℓ 0ℓ*-semigroup : Semigroup 0ℓ 0ℓ+-0-monoid : Monoid 0ℓ 0ℓ*-1-monoid : Monoid 0ℓ 0ℓ+-*-ring : Ring 0ℓ 0ℓ<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-strictPartialOrder : StrictPartialOrder _ _ _```* Added new proofs to `Data.List.Categorical`:```agdaapplicativeZero : RawApplicativeZero Listalternative : RawAlternative List```* Added new operations to `Data.List.Relation.Unary.All`:```agdazipWith : P ∩ Q ⊆ R → All P ∩ All Q ⊆ All RunzipWith : R ⊆ P ∩ Q → All R ⊆ All P ∩ All QsequenceA : All (F ∘′ P) ⊆ F ∘′ All PsequenceM : All (M ∘′ P) ⊆ M ∘′ All PmapA : (Q ⊆ F ∘′ P) → All Q ⊆ (F ∘′ All P)mapM : (Q ⊆ M ∘′ P) → All Q ⊆ (M ∘′ All P)forA : All Q xs → (Q ⊆ F ∘′ P) → F (All P xs)forM : All Q xs → (Q ⊆ M ∘′ P) → M (All P xs)updateAt : x ∈ xs → (P x → P x) → All P xs → All P xs_[_]%=_ : All P xs → x ∈ xs → (P x → P x) → All P xs_[_]≔_ : All P xs → x ∈ xs → P x → All P xs```* Added new proofs to `Data.List.Relation.Unary.All.Properties`:```agdarespects : P Respects _≈_ → (All P) Respects _≋_─⁺ : All Q xs → All Q (xs Any.─ p)─⁻ : Q (Any.lookup p) → All Q (xs Any.─ p) → All Q xsmap-cong : f ≗ g → map f ps ≡ map g psmap-id : map id ps ≡ psmap-compose : map g (map f ps) ≡ map (g ∘ f) pslookup-map : lookup (map f ps) i ≡ f (lookup ps i)∷ʳ⁺ : All P xs → P x → All P (xs ∷ʳ x)∷ʳ⁻ : All P (xs ∷ʳ x) → All P xs × P x```* Added new proofs to `Data.List.Relation.Binary.Equality.DecPropositional`:```agda_≡?_ : Decidable (_≡_ {A = List A})```* Added new functions to `Data.List.Relation.Unary.Any`:```agdalookup : Any P xs → A_∷=_ : Any P xs → A → List A_─_ : ∀ xs → Any P xs → List A```* Added new functions to `Data.List.Base`:```agdaintercalate : List A → List (List A) → List ApartitionSumsWith : (A → B ⊎ C) → List A → List B × List CpartitionSums : List (A ⊎ B) → List A × List B_[_]%=_ : (xs : List A) → Fin (length xs) → (A → A) → List A_[_]∷=_ : (xs : List A) → Fin (length xs) → A → List A_─_ : (xs : List A) → Fin (length xs) → List AreverseAcc : List A → List A → List A```* Added new proofs to `Data.List.Membership.Propositional.Properties`:```agda∈-allFin : (k : Fin n) → k ∈ allFin n[]∈inits : [] ∈ inits as```* Added new function to `Data.List.Membership.(Setoid/Propositional)`:```agda_∷=_ : x ∈ xs → A → List A_─_ : (xs : List A) → x ∈ xs → List A```Added laws for `updateAt`. The laws that previously existed for `_[_]≔_` are nowspecial instances of these.* Added new proofs to `Data.List.Membership.Setoid.Properties`:```agdalength-mapWith∈ : length (mapWith∈ xs f) ≡ length xs∈-∷=⁺-updated : v ∈ (x∈xs ∷= v)∈-∷=⁺-untouched : x ≉ y → y ∈ xs → y ∈ (x∈xs ∷= v)∈-∷=⁻ : y ≉ v → y ∈ (x∈xs ∷= v) → y ∈ xsmap-∷= : map f (x∈xs ∷= v) ≡ ∈-map⁺ f≈ pr ∷= f v```* Added new proofs to `Data.List.Properties`:```agda≡-dec : Decidable _≡_ → Decidable {A = List A} _≡_++-cancelˡ : xs ++ ys ≡ xs ++ zs → ys ≡ zs++-cancelʳ : ys ++ xs ≡ zs ++ xs → ys ≡ zs++-cancel : Cancellative _++_++-conicalˡ : xs ++ ys ≡ [] → xs ≡ []++-conicalʳ : xs ++ ys ≡ [] → ys ≡ []++-conical : Conical [] _++_++-isMagma : IsMagma _++_length-%= : length (xs [ k ]%= f) ≡ length xslength-∷= : length (xs [ k ]∷= v) ≡ length xslength-─ : length (xs ─ k) ≡ pred (length xs)map-∷= : map f (xs [ k ]∷= v) ≡ map f xs [ cast eq k ]∷= f vmap-─ : map f (xs ─ k) ≡ map f xs ─ cast eq klength-applyUpTo : length (applyUpTo f n) ≡ nlength-applyDownFrom : length (applyDownFrom f n) ≡ nlength-upTo : length (upTo n) ≡ nlength-downFrom : length (downFrom n) ≡ nlength-tabulate : length (tabulate f ) ≡ nlookup-applyUpTo : lookup (applyUpTo f n) i ≡ f (toℕ i)lookup-applyDownFrom : lookup (applyDownFrom f n) i ≡ f (n ∸ (suc (toℕ i)))lookup-upTo : lookup (upTo n) i ≡ toℕ ilookup-downFrom : lookup (downFrom n) i ≡ n ∸ (suc (toℕ i))lookup-tabulate : lookup (tabulate f) i′ ≡ f imap-tabulate : map f (tabulate g) ≡ tabulate (f ∘ g)```* Added new proofs to `Data.List.Relation.Binary.Permutation.Inductive.Properties`:```agda++-isMagma : IsMagma _↭_ _++_++-magma : Magma _ _```* Added new proofs to `Data.List.Relation.Binary.Pointwise`:```agdareverseAcc⁺ : Pointwise R a x → Pointwise R b y → Pointwise R (reverseAcc a b) (reverseAcc x y)reverse⁺ : Pointwise R as bs → Pointwise R (reverse as) (reverse bs)map⁺ : Pointwise (λ a b → R (f a) (g b)) as bs → Pointwise R (map f as) (map g bs)map⁻ : Pointwise R (map f as) (map g bs) → Pointwise (λ a b → R (f a) (g b)) as bsfilter⁺ : Pointwise R as bs → Pointwise R (filter P? as) (filter Q? bs)replicate⁺ : R a b → Pointwise R (replicate n a) (replicate n b)irrelevant : Irrelevant R → Irrelevant (Pointwise R)```* Added new function to `Data.Maybe.Base`:```agda_<∣>_ : Maybe A → Maybe A → Maybe A```* Added new proofs to `Data.Maybe.Categorical`:```agdaapplicativeZero : RawApplicativeZero Maybealternative : RawAlternative Maybe```* Added new proof to `Data.Maybe.Properties`:```agda≡-dec : Decidable _≡_ → Decidable {A = Maybe A} _≡_```* Added new proof to `Data.Maybe.Relation.Binary.Pointwise`:```agdareflexive : _≡_ ⇒ R → _≡_ ⇒ Pointwise R```* Added new proofs to `Data.Maybe.Relation.Unary.All`:```agdadrop-just : All P (just x) → P xjust-equivalence : P x ⇔ All P (just x)map : P ⊆ Q → All P ⊆ All QfromAny : Any P ⊆ All PzipWith : P ∩ Q ⊆ R → All P ∩ All Q ⊆ All RunzipWith : P ⊆ Q ∩ R → All P ⊆ All Q ∩ All Rzip : All P ∩ All Q ⊆ All (P ∩ Q)unzip : All (P ∩ Q) ⊆ All P ∩ All QsequenceA : RawApplicative F → All (F ∘′ P) ⊆ F ∘′ All PmapA : RawApplicative F → (Q ⊆ F ∘′ P) → All Q ⊆ (F ∘′ All P)forA : RawApplicative F → All Q xs → (Q ⊆ F ∘′ P) → F (All P xs)sequenceM : RawMonad M → All (M ∘′ P) ⊆ M ∘′ All PmapM : RawMonad M → (Q ⊆ M ∘′ P) → All Q ⊆ (M ∘′ All P)forM : RawMonad M → All Q xs → (Q ⊆ M ∘′ P) → M (All P xs)universal : Universal P → Universal (All P)irrelevant : Irrelevant P → Irrelevant (All P)satisfiable : Satisfiable (All P)```* Added new proofs to `Data.Maybe.Relation.Unary.Any`:```agdadrop-just : Any P (just x) → P xjust-equivalence : P x ⇔ Any P (just x)map : P ⊆ Q → Any P ⊆ Any Qsatisfied : Any P x → ∃ PzipWith : P ∩ Q ⊆ R → Any P ∩ Any Q ⊆ Any RunzipWith : P ⊆ Q ∩ R → Any P ⊆ Any Q ∩ Any Rzip : Any P ∩ Any Q ⊆ Any (P ∩ Q)unzip : Any (P ∩ Q) ⊆ Any P ∩ Any Qirrelevant : Irrelevant P → Irrelevant (Any P)satisfiable : Satisfiable P → Satisfiable (Any P)```* Added a third alternative definition of "less than" to `Data.Nat.Base`:```agda_≤‴_ : Rel ℕ 0ℓ_<‴_ : Rel ℕ 0ℓ_≥‴_ : Rel ℕ 0ℓ_>‴_ : Rel ℕ 0ℓ```* Added new proofs to `Data.Nat.Properties`:```agda+-isMagma : IsMagma _+_*-isMagma : IsMagma _*_⊔-isMagma : IsMagma _⊔_⊓-isMagma : IsMagma _⊓_⊔-isBand : IsBand _⊔_⊓-isBand : IsBand _⊓_⊔-isSemilattice : IsSemilattice _⊔_⊓-isSemilattice : IsSemilattice _⊓_+-magma : Magma 0ℓ 0ℓ*-magma : Magma 0ℓ 0ℓ⊔-magma : Magma 0ℓ 0ℓ⊓-magma : Magma 0ℓ 0ℓ⊔-band : Band 0ℓ 0ℓ⊓-band : Band 0ℓ 0ℓ⊔-semilattice : Semilattice 0ℓ 0ℓ⊓-semilattice : Semilattice 0ℓ 0ℓ+-cancelˡ-< : LeftCancellative _<_ _+_+-cancelʳ-< : RightCancellative _<_ _+_+-cancel-< : Cancellative _<_ _+_m≤n⇒m⊓o≤n : m ≤ n → m ⊓ o ≤ nm≤n⇒o⊓m≤n : m ≤ n → o ⊓ m ≤ nm<n⇒m⊓o<n : m < n → m ⊓ o < nm<n⇒o⊓m<n : m < n → o ⊓ m < nm≤n⊓o⇒m≤n : m ≤ n ⊓ o → m ≤ nm≤n⊓o⇒m≤o : m ≤ n ⊓ o → m ≤ om<n⊓o⇒m<n : m < n ⊓ o → m < nm<n⊓o⇒m<o : m < n ⊓ o → m < om≤n⇒m≤n⊔o : m ≤ n → m ≤ n ⊔ om≤n⇒m≤o⊔n : m ≤ n → m ≤ o ⊔ nm<n⇒m<n⊔o : m < n → m < n ⊔ om<n⇒m<o⊔n : m < n → m < o ⊔ nm⊔n≤o⇒m≤o : m ⊔ n ≤ o → m ≤ om⊔n≤o⇒n≤o : m ⊔ n ≤ o → n ≤ om⊔n<o⇒m<o : m ⊔ n < o → m < om⊔n<o⇒n<o : m ⊔ n < o → n < om≢0⇒suc[pred[m]]≡m : m ≢ 0 → suc (pred m) ≡ mm≢1+n+m : m ≢ suc (n + m)≡ᵇ⇒≡ : T (m ≡ᵇ n) → m ≡ n≡⇒≡ᵇ : m ≡ n → T (m ≡ᵇ n)≡-irrelevant : Irrelevant {A = ℕ} _≡_≟-diag : (eq : m ≡ n) → (m ≟ n) ≡ yes eq≤′-trans : Transitive _≤′_m<ᵇn⇒1+m+[n-1+m]≡n : T (m <ᵇ n) → suc m + (n ∸ suc m) ≡ nm<ᵇ1+m+n : T (m <ᵇ suc (m + n))<ᵇ⇒<″ : T (m <ᵇ n) → m <″ n<″⇒<ᵇ : m <″ n → T (m <ᵇ n)≤‴⇒≤″ : ∀{m n} → m ≤‴ n → m ≤″ n≤″⇒≤‴ : ∀{m n} → m ≤″ n → m ≤‴ n≤″-irrelevant : Irrelevant _≤″_≥″-irrelevant : Irrelevant _≥″_<″-irrelevant : Irrelevant _<″_>″-irrelevant : Irrelevant _>″_m≤‴m+k : m + k ≡ n → m ≤‴ n```* Added new proof to `Data.Product.Properties.WithK`:```agda,-injective : (a , b) ≡ (c , d) → a ≡ c × b ≡ d≡-dec : Decidable _≡_ → (∀ {a} → Decidable {A = B a} _≡_) → Decidable {A = Σ A B} _≡_```* Added new functions to `Data.Product.Relation.Binary.Pointwise.NonDependent`:```agda<_,_>ₛ : A ⟶ B → A ⟶ C → A ⟶ (B ×ₛ C)proj₁ₛ : (A ×ₛ B) ⟶ Aproj₂ₛ : (A ×ₛ B) ⟶ Bswapₛ : (A ×ₛ B) ⟶ (B ×ₛ A)```* Added new functions to `Data.Rational`:```agda-_ : ℚ → ℚ1/_ : (p : ℚ) → .{n≢0 : ∣ ℚ.numerator p ∣ ≢0} → ℚ_*_ : ℚ → ℚ → ℚ_+_ : ℚ → ℚ → ℚ_-_ : ℚ → ℚ → ℚ_/_ : (p₁ p₂ : ℚ) → {n≢0 : ∣ ℚ.numerator p₂ ∣ ≢0} → ℚshow : ℚ → String```* Added new proofs to `Data.Sign.Properties`:```agda*-isMagma : IsMagma _*_*-magma : Magma 0ℓ 0ℓ```* Added new functions to `Data.Sum.Base`:```agdafromDec : Dec P → P ⊎ ¬ PtoDec : P ⊎ ¬ P → Dec P```* Added new proof to `Data.Sum.Properties`:```agda≡-dec : Decidable _≡_ → Decidable _≡_ → Decidable {A = A ⊎ B} _≡_```* Added new functions to `Data.Sum.Relation.Binary.Pointwise`:```agdainj₁ₛ : A ⟶ (A ⊎ₛ B)inj₂ₛ : B ⟶ (A ⊎ₛ B)[_,_]ₛ : (A ⟶ C) → (B ⟶ C) → (A ⊎ₛ B) ⟶ Cswapₛ : (A ⊎ₛ B) ⟶ (B ⊎ₛ A)```* Added new function to `Data.These`:```agdafromSum : A ⊎ B → These A B```* Added to `Data.Vec` a generalization of single point overwrite `_[_]≔_` tosingle-point modification `_[_]%=_` (with an alias `updateAt` with differentargument order):```agda_[_]%=_ : Vec A n → Fin n → (A → A) → Vec A nupdateAt : Fin n → (A → A) → Vec A n → Vec A n```* Added proofs for `updateAt` to `Data.Vec.Properties`. Previously existing proofs for`_[_]≔_` are now special instances of these.* Added new proofs to `Data.Vec.Relation.Unary.Any.Properties`:```agdalookup-index : (p : Any P xs) → P (lookup (index p) xs)lift-resp : P Respects _≈_ → (Any P) Respects (Pointwise _≈_)here-injective : here p ≡ here q → p ≡ qthere-injective : there p ≡ there q → p ≡ q¬Any[] : ¬ Any P []⊥↔Any⊥ : ⊥ ↔ Any (const ⊥) xs⊥↔Any[] : ⊥ ↔ Any P []map-id : ∀ f → (∀ p → f p ≡ p) → ∀ p → Any.map f p ≡ pmap-∘ : Any.map (f ∘ g) p ≡ Any.map f (Any.map g p)swap : Any (λ x → Any (x ∼_) ys) xs → Any (λ y → Any (_∼ y) xs) ysswap-there : swap (Any.map there p) ≡ there (swap p)swap-invol : swap (swap p) ≡ pswap↔ : Any (λ x → Any (x ∼_) ys) xs ↔ Any (λ y → Any (_∼ y) xs) ysAny-⊎⁺ : Any P xs ⊎ Any Q xs → Any (λ x → P x ⊎ Q x) xsAny-⊎⁻ : Any (λ x → P x ⊎ Q x) xs → Any P xs ⊎ Any Q xs⊎↔ : (Any P xs ⊎ Any Q xs) ↔ Any (λ x → P x ⊎ Q x) xsAny-×⁺ : Any P xs × Any Q ys → Any (λ x → Any (λ y → P x × Q y) ys) xsAny-×⁻ : Any (λ x → Any (λ y → P x × Q y) ys) xs → Any P xs × Any Q yssingleton⁺ : P x → Any P [ x ]singleton⁻ : Any P [ x ] → P xsingleton⁺∘singleton⁻ : singleton⁺ (singleton⁻ p) ≡ psingleton⁻∘singleton⁺ : singleton⁻ (singleton⁺ p) ≡ psingleton↔ : P x ↔ Any P [ x ]map⁺ : Any (P ∘ f) xs → Any P (map f xs)map⁻ : Any P (map f xs) → Any (P ∘ f) xsmap⁺∘map⁻ : map⁺ (map⁻ p) ≡ pmap⁻∘map⁺ : map⁻ (map⁺ p) ≡ pmap↔ : Any (P ∘ f) xs ↔ Any P (map f xs)++⁺ˡ : Any P xs → Any P (xs ++ ys)++⁺ʳ : Any P ys → Any P (xs ++ ys)++⁻ : Any P (xs ++ ys) → Any P xs ⊎ Any P ys++⁺∘++⁻ : ∀ p → [ ++⁺ˡ , ++⁺ʳ xs ]′ (++⁻ xs p) ≡ p++⁻∘++⁺ : ∀ p → ++⁻ xs ([ ++⁺ˡ , ++⁺ʳ xs ]′ p) ≡ p++-comm : ∀ xs ys → Any P (xs ++ ys) → Any P (ys ++ xs)++-comm∘++-comm : ∀ p → ++-comm ys xs (++-comm xs ys p) ≡ p++-insert : ∀ xs → P x → Any P (xs ++ [ x ] ++ ys)++↔ : (Any P xs ⊎ Any P ys) ↔ Any P (xs ++ ys)++↔++ : ∀ xs ys → Any P (xs ++ ys) ↔ Any P (ys ++ xs)concat⁺ : Any (Any P) xss → Any P (concat xss)concat⁻ : Any P (concat xss) → Any (Any P) xssconcat⁻∘++⁺ˡ : ∀ xss p → concat⁻ (xs ∷ xss) (++⁺ˡ p) ≡ here pconcat⁻∘++⁺ʳ : ∀ xs xss p → concat⁻ (xs ∷ xss) (++⁺ʳ xs p) ≡ there (concat⁻ xss p)concat⁺∘concat⁻ : ∀ xss p → concat⁺ (concat⁻ xss p) ≡ pconcat⁻∘concat⁺ : ∀ p → concat⁻ xss (concat⁺ p) ≡ pconcat↔ : Any (Any P) xss ↔ Any P (concat xss)tabulate⁺ : ∀ i → P (f i) → Any P (tabulate f)tabulate⁻ : Any P (tabulate f) → ∃ λ i → P (f i)mapWith∈⁺ : ∀ f → (∃₂ λ x p → P (f p)) → Any P (mapWith∈ xs f)mapWith∈⁻ : ∀ xs f → Any P (mapWith∈ xs f) → ∃₂ λ x p → P (f p)mapWith∈↔ : (∃₂ λ x p → P (f p)) ↔ Any P (mapWith∈ xs f)toList⁺ : Any P xs → List.Any P (toList xs)toList⁻ : List.Any P (toList xs) → Any P xsfromList⁺ : List.Any P xs → Any P (fromList xs)fromList⁻ : Any P (fromList xs) → List.Any P xs∷↔ : ∀ P → (P x ⊎ Any P xs) ↔ Any P (x ∷ xs)>>=↔ : Any (Any P ∘ f) xs ↔ Any P (xs >>= f)```* Added new functions to `Data.Vec.Membership.Propositional.Properties`:```agdafromAny : Any P xs → ∃ λ x → x ∈ xs × P xtoAny : x ∈ xs → P x → Any P xs```* Added new proof to `Data.Vec.Properties`:```agda≡-dec : Decidable _≡_ → ∀ {n} → Decidable {A = Vec A n} _≡_```* Added new proofs to `Function.Related.TypeIsomorphisms`:```agda×-isMagma : ∀ k ℓ → IsMagma (Related ⌊ k ⌋) _×_⊎-isMagma : ∀ k ℓ → IsMagma (Related ⌊ k ⌋) _⊎_×-magma : Symmetric-kind → (ℓ : Level) → Magma _ _⊎-magma : Symmetric-kind → (ℓ : Level) → Semigroup _ _```* Added new proofs to `Relation.Binary.Consequences`:```agdawlog : Total _R_ → Symmetric Q → (∀ a b → a R b → Q a b) → ∀ a b → Q a b```* Added new definitions to `Relation.Binary.Core`:```agdaAntisym R S E = ∀ {i j} → R i j → S j i → E i jMax : REL A B ℓ → B → Set _Min : REL A B ℓ → A → Set _Conn P Q = ∀ x y → P x y ⊎ Q y xP ⟶ Q Respects _∼_ = ∀ {x y} → x ∼ y → P x → Q y```Additionally the definition of the types `_Respectsʳ_`/`_Respectsˡ_` has beengeneralised as follows in order to support heterogenous relations:```agda_Respectsʳ_ : REL A B ℓ₁ → Rel B ℓ₂ → Set __Respectsˡ_ : REL A B ℓ₁ → Rel A ℓ₂ → Set _```* Added new proofs to `Relation.Binary.Lattice`:```agdaLattice.setoid : Setoid c ℓBoundedLattice.setoid : Setoid c ℓ```* Added new operations and proofs to `Relation.Binary.Properties.HeytingAlgebra`:```agday≤x⇨y : y ≤ x ⇨ y⇨-unit : x ⇨ x ≈ ⊤⇨-drop : (x ⇨ y) ∧ y ≈ y⇨-app : (x ⇨ y) ∧ x ≈ y ∧ x⇨-relax : _⇨_ Preserves₂ (flip _≤_) ⟶ _≤_ ⟶ _≤_⇨-cong : _⇨_ Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_⇨-applyˡ : w ≤ x → (x ⇨ y) ∧ w ≤ y⇨-applyʳ : w ≤ x → w ∧ (x ⇨ y) ≤ y⇨-curry : x ∧ y ⇨ z ≈ x ⇨ y ⇨ z⇨ʳ-covariant : (x ⇨_) Preserves _≤_ ⟶ _≤_⇨ˡ-contravariant : (_⇨ x) Preserves (flip _≤_) ⟶ _≤_¬_ : Op₁ Carrierx≤¬¬x : x ≤ ¬ ¬ xde-morgan₁ : ¬ (x ∨ y) ≈ ¬ x ∧ ¬ yde-morgan₂-≤ : ¬ (x ∧ y) ≤ ¬ ¬ (¬ x ∨ ¬ y)de-morgan₂-≥ : ¬ ¬ (¬ x ∨ ¬ y) ≤ ¬ (x ∧ y)de-morgan₂ : ¬ (x ∧ y) ≈ ¬ ¬ (¬ x ∨ ¬ y)weak-lem : ¬ ¬ (¬ x ∨ x) ≈ ⊤```* Added new proofs to `Relation.Binary.Properties.JoinSemilattice`:```agdax≤y⇒x∨y≈y : x ≤ y → x ∨ y ≈ y```* Added new proofs to `Relation.Binary.Properties.Lattice`:```agda∧≤∨ : x ∧ y ≤ x ∨ yquadrilateral₁ : x ∨ y ≈ x → x ∧ y ≈ yquadrilateral₂ : x ∧ y ≈ y → x ∨ y ≈ xcollapse₁ : x ≈ y → x ∧ y ≈ x ∨ ycollapse₂ : x ∨ y ≤ x ∧ y → x ≈ y```* Added new proofs to `Relation.Binary.Properties.MeetSemilattice`:```agday≤x⇒x∧y≈y : y ≤ x → x ∧ y ≈ y```* Added new definitions to `Relation.Binary.PropositionalEquality`:```agdatrans-injectiveˡ : trans p₁ q ≡ trans p₂ q → p₁ ≡ p₂trans-injectiveʳ : trans p q₁ ≡ trans p q₂ → q₁ ≡ q₂subst-injective : subst P x≡y p ≡ subst P x≡y q → p ≡ qcong-id : cong id p ≡ pcong-∘ : cong (f ∘ g) p ≡ cong f (cong g p)cong-≡id : (f≡id : ∀ x → f x ≡ x) → cong f (f≡id x) ≡ f≡id (f x)naturality : trans (cong f x≡y) (f≡g y) ≡ trans (f≡g x) (cong g x≡y)subst-application : (eq : x₁ ≡ x₂) → subst B₂ eq (g x₁ y) ≡ g x₂ (subst B₁ (cong f eq) y)subst-subst : subst P y≡z (subst P x≡y p) ≡ subst P (trans x≡y y≡z) psubst-subst-sym : subst P x≡y (subst P (sym x≡y) p) ≡ psubst-sym-subst : subst P (sym x≡y) (subst P x≡y p) ≡ psubst-∘ : subst (P ∘ f) x≡y p ≡ subst P (cong f x≡y) ptrans-assoc : trans (trans p q) r ≡ trans p (trans q r)trans-reflʳ : trans p refl ≡ ptrans-symʳ : trans p (sym p) ≡ refltrans-symˡ : trans (sym p) p ≡ refl```
Version 1.0.1=============The library has been tested using Agda version 2.6.0.Important changes since 1.0:* Fixed unsolved metas in `Relation.Binary.Reasoning.MultiSetoid` andadded missing combinator `_≈˘⟨_⟩_`.
Version 0.17============The library has been tested using Agda version 2.5.4.1.Important changes since 0.16:Non-backwards compatible changes--------------------------------#### Overhaul of safety of the library* Currently the library is very difficult to type check with the `--safe`flag as there are unsafe functions scattered throughout the key modules.This means that it is almost impossible to verify the safety of any codedepending on the standard library. The following reorganisation will fixthis problem after the **next** full release of Agda. (Agda 2.5.4.1 uses`postulate`s in the `Agda.Builtin.X` that will be removed in the next release).* The following new `Unsafe` modules have been created. Nearly all of theseare all marked as unsafe as they use the `trustMe` functionality, either forperformance reasons or for informative decidable equality tests.```Data.Char.UnsafeData.Float.UnsafeData.Nat.UnsafeData.Nat.DivMod.UnsafeData.String.UnsafeData.Word.Unsafe```* The other modules affected are `Relation.Binary.HeterogeneousEquality.Quotients(.Examples)`which previously postulated function extensionality. The relevant submodulesnow take extensionality as a module parameter instead of postulating it. If youwant to use these results then you should postulate it yourself.* The full list of unsafe modules is:```Data.Char.UnsafeData.Float.UnsafeData.Nat.UnsafeData.Nat.DivMod.UnsafeData.String.UnsafeData.Word.UnsafeIOIO.PrimitiveReflectionRelation.Binary.PropositionalEquality.TrustMe```#### New codata library* A new `Codata` library has been added that is based on copatterns and sizedtypes rather than musical notation . The library is built around a genericnotion of coinductive `Thunk` and provides the basic data types:```agdaCodata.ThunkCodata.ColistCodata.ConatCodata.CofinCodata.CovecCodata.DelayCodata.MCodata.Stream```Each coinductive type comes with a notion of bisimilarity in the corresponding`Codata.X.Bisimilarity` module and at least a couple of proofs demonstratinghow they can be used in `Codata.X.Properties`. This library is somewhatexperimental and may undergo minor changes in later versions.* To avoid confusion, the old codata modules that previously lived in the `Data`directory have been moved to the folder `Codata.Musical````agdaCoinduction ↦ Codata.Musical.NotationData.Cofin ↦ Codata.Musical.CofinData.Colist ↦ Codata.Musical.ColistData.Conat ↦ Codata.Musical.ConatData.Covec ↦ Codata.Musical.CovecData.M ↦ Codata.Musical.MData.Stream ↦ Codata.Musical.Stream```* Each new-style coinduction type comes with two functions (`fromMusical` and`toMusical`) converting back and forth between old-style coinduction valuesand new-style ones.* The type `Costring` and method `toCostring` have been moved from `Data.String`to a new module `Codata.Musical.Costring`.* The `Rec` construction has been dropped from `Codata.Musical.Notation` as the`--guardedness-preserving-type-constructors` flag which made it useful has beenremoved from Agda.#### Improved consistency between `Data.(List/Vec).(Any/All/Membership)`* Added new module `Data.Vec.Any`.* The type `_∈_` has been moved from `Data.Vec` to the new module`Data.Vec.Membership.Propositional` and has been reimplemented using`Any` from `Data.Vec.Any`. In particular this means that you must nowpass a `refl` proof to the `here` constructor.* The proofs associated with `_∈_` have been moved from `Data.Vec.Properties`to the new module `Data.Vec.Membership.Propositional.Properties`and have been renamed as follows:```agda∈-++ₗ ↦ ∈-++⁺ˡ∈-++ᵣ ↦ ∈-++⁺ʳ∈-map ↦ ∈-map⁺∈-tabulate ↦ ∈-tabulate⁺∈-allFin ↦ ∈-allFin⁺∈-allPairs ↦ ∈-allPairs⁺∈⇒List-∈ ↦ ∈-toList⁺List-∈⇒∈ ↦ ∈-fromList⁺```* The proofs `All-universal` and `All-irrelevance` have been moved from`Data.(List/Vec).All.Properties` and renamed `universal` and `irrelevant` in`Data.(List/Vec).All`.* The existing function `tabulate` in `Data.Vec.All` has been renamed`universal`. The name `tabulate` now refers to a function with following type:```agdatabulate : (∀ i → P (lookup i xs)) → All P xs```#### Deprecating `Data.Fin.Dec`:* This module has been deprecated as its non-standard positionwas causing dependency cycles. The move also makes findingsubset properties easier.* The following proofs have been moved to `Data.Fin.Properties`:```decFinSubset, any?, all?, ¬∀⟶∃¬-smallest, ¬∀⟶∃¬```* The following proofs have been moved to `Data.Fin.Subset.Properties`:```_∈?_, _⊆?_, nonempty?, anySubset?, decLift```The latter has been renamed to `Lift?`.* The file `Data.Fin.Dec` still exists for backwards compatibilityand exports all the old names, but may be removed in somefuture version.#### Rearrangement of algebraic solvers* Standardised and moved the generic solver modules as follows:```agdaAlgebra.RingSolver ↦ Algebra.Solver.RingAlgebra.Monoid-solver ↦ Algebra.Solver.MonoidAlgebra.CommutativeMonoidSolver ↦ Algebra.Solver.CommutativeMonoidAlgebra.IdempotentCommutativeMonoidSolver ↦ Algebra.Solver.IdempotentCommutativeMonoid```* In order to avoid dependency cycles, special instances of solvers for the followingdata types have been moved from `Data.X.Properties` to new modules `Data.X.Solver`.The naming conventions for these solver modules have also been standardised.```agdaData.Bool.Properties.RingSolver ↦ Data.Bool.Solver.∨-∧-SolverData.Bool.Properties.XorRingSolver ↦ Data.Bool.Solver.xor-∧-SolverData.Integer.Properties.RingSolver ↦ Data.Integer.Solver.+-*-SolverData.List.Properties.List-solver ↦ Data.List.Solver.++-SolverData.Nat.Properties.SemiringSolver ↦ Data.Nat.Solver.+-*-SolverFunction.Related.TypeIsomorphisms.Solver ↦ Function.Related.TypeIsomorphisms.Solver.×-⊎-Solver```* Renamed `Algebra.Solver.Ring.Natural-coefficients` to `Algebra.Solver.Ring.NaturalCoefficients`.#### Overhaul of `Data.X.Categorical`* Added new modules:```Category.ComonadData.List.NonEmpty.CategoricalData.Maybe.CategoricalData.Product.Categorical.LeftData.Product.Categorical.RightData.Product.N-ary.CategoricalData.Sum.Categorical.LeftData.Sum.Categorical.RightData.These.Categorical.LeftData.These.Categorical.RightCodata.Colist.CategoricalCodata.Covec.CategoricalCodata.Delay.CategoricalCodata.Stream.Categorical```* In `Data.List.Categorical` renamed:```agdasequence ↦ sequenceM```* Moved `monad` from `Data.List.NonEmpty` to `Data.List.NonEmpty.Categorical`.* Moved `functor`, `monadT`, `monad`, `monadZero` and `monadPlus` from `Data.Maybe`to `Data.Maybe.Categorical`.* Created new module `Function.Identity.Categorical` and merged the existing modules`Category.Functor.Identity` and `Category.Monad.Identity` into it.#### Overhaul of `Data.Container`, `Data.W` and `Codata.(Musical.)M`* Made `Data.Container` (and associated modules) more level-polymorphic* Created `Data.Container.Core` for the core definition of `Container`,container morphisms `_⇒_`, `All` and `Any`. This breaks the dependency cyclewith `Data.W` and `Codata.Musical.M`.* Refactored `Data.W` and `Codata.Musical.M` to use `Container`.#### Rearrangement of constructed relations in `Relation.Binary`* In order to improve the organisation and general searchability of`Relation.Binary`, modules that construct specific binary relations havebeen moved from `Relation.Binary` to `Relation.Binary.Construct`.* The module `Relation.Binary.Simple` has been split into `Constant`,`Always` and `Never`.* The module `Relation.Binary.InducedPreorders` has been split into`Relation.Binary.Construct.FromPred` and `Relation.Binary.Construct.FromRel`.* The full list of changes is as follows:```agdaRelation.Binary.Closure ↦ Relation.Binary.Construct.ClosureRelation.Binary.Flip ↦ Relation.Binary.Construct.FlipRelation.Binary.InducedPreorders ↦ Relation.Binary.Construct.FromPred↘ Relation.Binary.Construct.FromRelRelation.Binary.On ↦ Relation.Binary.Construct.OnRelation.Binary.Simple ↦ Relation.Binary.Construct.Always↘ Relation.Binary.Construct.Never↘ Relation.Binary.Construct.ConstantRelation.Binary.NonStrictToStrict ↦ Relation.Binary.Construct.NonStrictToStrictRelation.Binary.StrictToNonStrict ↦ Relation.Binary.Construct.StrictToNonStrict```#### Overhaul of `Relation.Binary.Indexed` subtree* The module `Relation.Binary.Indexed` has been renamed`Relation.Binary.Indexed.Heterogeneous`.* The names `REL`, `Rel`, `IsEquivalence` and `Setoid` in`Relation.Binary.Indexed.Heterogeneous` and `Relation.Binary.Indexed.Homogeneous`have been deprecated in favour of `IREL`, `IRel`, `IsIndexedEquivalence` and`IndexedSetoid`. This should significantly improves code readability and avoidconfusion with the contents of `Relation.Binary`. The old names still existbut have been deprecated.* The record `IsIndexedEquivalence` in `Relation.Binary.Indexed.Homogeneous`is now implemented as a record encapsulating indexed versions of the requiredproperties, unlike the old version which directly indexed equivalences.* In order to avoid dependency cycles, the `Setoid` record in `Relation.Binary`no longer exports `indexedSetoid`. Instead the corresponding indexed setoid canbe constructed using the `setoid` function in`Relation.Binary.Indexed.Heterogeneous.Construct.Trivial`.* The function `_at_` in `Relation.Binary.Indexed.Heterogeneous` has been moved to`Relation.Binary.Indexed.Heterogeneous.Construct.At` and renamed to `_atₛ_`.#### Overhaul of decidability proofs in numeric base modules* Several numeric datatypes such as `Nat/Integer/Fin` had decidability proofs in`Data.X.Base`. This required several proofs to live in `Data.X.Base` that shouldreally have been living in `Data.X.Properties` . For example `≤-pred`in `Data.Nat.Base`. This problem has been growing as more decidability proofs areadded.* To fix this all decidability proofs in `Data.X.Base` for `Nat`/`Integer`/`Fin`have been moved to `Data.X.Properties` from `Data.X.Base`. Backwards compatibilityhas been (nearly completely) preserved by having `Data.X` publicly re-export thedecidability proofs. If you were using the `Data.X.Base` module directlyand were using decidability queries you should probably switch to use `Data.X`.* The following proofs have therefore been moved to the `Properties` files.The old versions remain in the original files but have been deprecated andmay be removed at some future version.```agdaData.Nat.≤-pred ↦ Data.Nat.Properties.≤-predData.Integer.◃-cong ↦ Data.Integer.Properties.◃-congData.Integer.drop‿+≤+ ↦ Data.Integer.Properties.drop‿+≤+Data.Integer.drop‿-≤- ↦ Data.Integer.Properties.drop‿-≤-Data.Integer.◃-left-inverse ↦ Data.Integer.Properties.◃-inverse```#### Other* The `Data.List.Relation.Sublist` module was misnamed as it contained a subsetrather than a sublist relation. It has been correctly renamed to`Data.List.Relation.Subset`. In its place a new module `Data.List.Relation.Sublist`has been added that correctly implements the sublist relation.* The types `IrrelevantPred` and `IrrelevantRel` in`Relation.Binary.PropositionalEquality` have both been renamed to`Irrelevant` and have been moved to `Relation.Unary` and`Relation.Binary` respectively.* Removed `Data.Char.Core` which was doing nothing of interest.* In `Data.Maybe.Base` the `Set` argument to `From-just` has been made implicitto be consistent with the definition of `Data.Sum`'s `From-injₙ`.* In `Data.Product` the function `,_` has been renamed to `-,_` to avoidconflict with the right section of `_,_`.* Made `Data.Star.Decoration`, `Data.Star.Environment` and `Data.Star.Pointer`more level polymorphic. In particular `EdgePred` now takes an extra explicitlevel parameter.* In `Level` the target level of `Lift` is now explicit.* In `Function` the precedence level of `_$_` (and variants) has been changed to `-1`in order to improve its interaction with `_∋_` (e.g. `f $ Maybe A ∋ do (...)`).* `Relation.Binary` now no longer exports `_≡_`, `_≢_` and `refl`. The standardway of accessing them remains `Relation.Binary.PropositionalEquality`.* The syntax `∀[_]` in `Relation.Unary` has been renamed to `Π[_]`. The originalname is now used for for implicit universal quantifiers.Other major changes-------------------* Added new module `Algebra.Properties.CommutativeMonoid`. This contains proofsof lots of properties of summation, including 'big summation'.* Added new modules `Data.List.Relation.Permutation.Inductive(.Properties)`,which give an inductive definition of permutations over lists.* Added a new module `Data.These` for the classic either-or-both Haskell datatype.* Added new module `Data.List.Relation.Sublist.Inductive` which givesan inductive definition of the sublist relation (i.e. order-preserving embeddings).We also provide a solver for this order in `Data.List.Relation.Sublist.Inductive.Solver`.* Added new module `Relation.Binary.Construct.Converse`. This is very similarto the existing module `Relation.Binary.Construct.Flip` in that it flips the relation.However unlike the existing module, the new module leaves the underlying equality unchanged.* Added new modules `Relation.Unary.Closure.(Preorder/StrictPartialOrder)` providingclosures of a predicate with respect to either a preorder or a strict partial order.* Added new modules `Relation.Binary.Properties.(DistributiveLattice/HeytingAlgebra)`.Deprecated features-------------------* All deprecated names now give warnings at point-of-use when type-checked.The following deprecations have occurred as part of a drive to improve consistency acrossthe library. The deprecated names still exist and therefore all existing code should stillwork, however they have been deprecated and use of any new names is encouraged. Although notanticipated any time soon, they may eventually be removed in some future release of the library.* In `Data.Fin.Properties`:```agda≤+≢⇒< ↦ ≤∧≢⇒<```* In `Data.List.Properties`:```agdaidIsFold ↦ id-is-foldr++IsFold ↦ ++-is-foldrmapIsFold ↦ map-is-foldr```* In `Data.Nat.Properties`:```agda≤+≢⇒< ↦ ≤∧≢⇒<```* In `Function.Related`:```agdapreorder ↦ R-preordersetoid ↦ SR-setoidEquationReasoning.sym ↦ SR-sym```* In `Function.Related.TypeIsomorphisms`:```agda×-CommutativeMonoid ↦ ×-commutativeMonoid⊎-CommutativeMonoid ↦ ⊎-commutativeMonoid×⊎-CommutativeSemiring ↦ ×-⊎-commutativeSemiring```* In `Relation.Binary.Lattice`:```agdaBoundedJoinSemilattice.joinSemiLattice ↦ BoundedJoinSemilattice.joinSemilatticeBoundedMeetSemilattice.meetSemiLattice ↦ BoundedMeetSemilattice.meetSemilattice```The following have been deprecated without replacement:* In `Data.Nat.Divisibility`:```nonZeroDivisor-lemma```* In `Data.Nat.Properties`:```agdai∸k∸j+j∸k≡i+j∸kim≡jm+n⇒[i∸j]m≡n```* In `Relation.Binary.Construct.Always````agdaAlways-setoid ↦ setoid```Other minor additions---------------------* Added new records to `Algebra`:```agdarecord RawSemigroup c ℓ : Set (suc (c ⊔ ℓ))record RawGroup c ℓ : Set (suc (c ⊔ ℓ))record RawSemiring c ℓ : Set (suc (c ⊔ ℓ))```* Added new function `Category.Functor`'s `RawFunctor`:```agda_<&>_ : F A → (A → B) → F B```* Added new function to `Category.Monad.Indexed`:```agdaRawIMonadT : (T : IFun I f → IFun I f) → Set (i ⊔ suc f)```* Added new function to `Category.Monad`:```agdaRawMonadT : (T : (Set f → Set f) → (Set f → Set f)) → Set _```* Added new functions to `Codata.Delay`:```agdaalignWith : (These A B → C) → Delay A i → Delay B i → Delay C izip : Delay A i → Delay B i → Delay (A × B) ialign : Delay A i → Delay B i → Delay (These A B) i```* Added new functions to `Codata.Musical.M`:```agdamap : (C₁ ⇒ C₂) → M C₁ → M C₂unfold : (S → ⟦ C ⟧ S) → S → M C```* Added new proof to `Data.Fin.Permutation`:```agdarefute : m ≢ n → ¬ Permutation m n```Additionally the definitions `punchIn-permute` and `punchIn-permute′`have been generalised to work with heterogeneous permutations.* Added new proof to `Data.Fin.Properties`:```agdatoℕ-fromℕ≤″ : toℕ (fromℕ≤″ m m<n) ≡ mpigeonhole : m < n → (f : Fin n → Fin m) → ∃₂ λ i j → i ≢ j × f i ≡ f j```* Added new function to `Data.List.Any`:```agdahead : ¬ Any P xs → Any P (x ∷ xs) → P xtoSum : Any P (x ∷ xs) → P x ⊎ Any P xsfromSum : P x ⊎ Any P xs → Any P (x ∷ xs)```* Added new proofs to `Data.List.Any.Properties`:```agdahere-injective : here p ≡ here q → p ≡ qthere-injective : there p ≡ there q → p ≡ qsingleton⁺ : P x → Any P [ x ]singleton⁻ : Any P [ x ] → P x++-insert : P x → Any P (xs ++ [ x ] ++ ys)```* Added new functions to `Data.List.Base`:```agdauncons : List A → Maybe (A × List A)head : List A → Maybe Atail : List A → Maybe (List A)alignWith : (These A B → C) → List A → List B → List CunalignWith : (A → These B C) → List A → List B × List Calign : List A → List B → List (These A B)unalign : List (These A B) → List A × List B```* Added new functions to `Data.List.Categorical`:```agdafunctor : RawFunctor Listapplicative : RawApplicative ListmonadT : RawMonadT (_∘′ List)sequenceA : RawApplicative F → List (F A) → F (List A)mapA : RawApplicative F → (A → F B) → List A → F (List B)forA : RawApplicative F → List A → (A → F B) → F (List B)forM : RawMonad M → List A → (A → M B) → M (List B)```* Added new proofs to `Data.List.Membership.(Setoid/Propositional).Properties`:```agda∈-insert : v ≈ v′ → v ∈ xs ++ [ v′ ] ++ ys∈-∃++ : v ∈ xs → ∃₂ λ ys zs → ∃ λ w → v ≈ w × xs ≋ ys ++ [ w ] ++ zs```* Added new functions to `Data.List.NonEmpty`:```agdauncons : List⁺ A → A × List AconcatMap : (A → List⁺ B) → List⁺ A → List⁺ BalignWith : (These A B → C) → List⁺ A → List⁺ B → List⁺ CzipWith : (A → B → C) → List⁺ A → List⁺ B → List⁺ CunalignWith : (A → These B C) → List⁺ A → These (List⁺ B) (List⁺ C)unzipWith : (A → B × C) → List⁺ A → List⁺ B × List⁺ Calign : List⁺ A → List⁺ B → List⁺ (These A B)zip : List⁺ A → List⁺ B → List⁺ (A × B)unalign : List⁺ (These A B) → These (List⁺ A) (List⁺ B)unzip : List⁺ (A × B) → List⁺ A × List⁺ B```* Added new functions to `Data.List.Properties`:```agdaalignWith-cong : f ≗ g → alignWith f as ≗ alignWith g aslength-alignWith : length (alignWith f xs ys) ≡ length xs ⊔ length ysalignWith-map : alignWith f (map g xs) (map h ys) ≡ alignWith (f ∘′ These.map g h) xs ysmap-alignWith : map g (alignWith f xs ys) ≡ alignWith (g ∘′ f) xs ysunalignWith-this : unalignWith this ≗ (_, [])unalignWith-that : unalignWith that ≗ ([] ,_)unalignWith-cong : f ≗ g → unalignWith f ≗ unalignWith gunalignWith-map : unalignWith f (map g ds) ≡ unalignWith (f ∘′ g) dsmap-unalignWith : Prod.map (map g) (map h) ∘′ unalignWith f ≗ unalignWith (These.map g h ∘′ f)unalignWith-alignWith : f ∘′ g ≗ id → unalignWith f (alignWith g as bs) ≡ (as , bs)```* Added new function to `Data.Maybe.Base`:```agdafromMaybe : A → Maybe A → AalignWith : (These A B → C) → Maybe A → Maybe B → Maybe CzipWith : (A → B → C) → Maybe A → Maybe B → Maybe Calign : Maybe A → Maybe B → Maybe (These A B)zip : Maybe A → Maybe B → Maybe (A × B)```* Added new operator to `Data.Nat.Base`:```agda∣_-_∣ : ℕ → ℕ → ℕ```* Added new proofs to `Data.Nat.Divisibility`:```agdan∣m⇒m%n≡0 : suc n ∣ m → m % (suc n) ≡ 0m%n≡0⇒n∣m : m % (suc n) ≡ 0 → suc n ∣ mm%n≡0⇔n∣m : m % (suc n) ≡ 0 ⇔ suc n ∣ m```* Added new operations and proofs to `Data.Nat.DivMod`:```agda_%_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → ℕa≡a%n+[a/n]*n : a ≡ a % suc n + (a div (suc n)) * suc na%1≡0 : a % 1 ≡ 0a%n<n : a % suc n < suc nn%n≡0 : suc n % suc n ≡ 0a%n%n≡a%n : a % suc n % suc n ≡ a % suc n[a+n]%n≡a%n : (a + suc n) % suc n ≡ a % suc n[a+kn]%n≡a%n : (a + k * (suc n)) % suc n ≡ a % suc nkn%n≡0 : k * (suc n) % suc n ≡ 0%-distribˡ-+ : (a + b) % suc n ≡ (a % suc n + b % suc n) % suc n```* Added new proofs to `Data.Nat.Properties`:```agda_≥?_ : Decidable _≥__>?_ : Decidable _>__≤′?_ : Decidable _≤′__<′?_ : Decidable _<′__≤″?_ : Decidable _≤″__<″?_ : Decidable _<″__≥″?_ : Decidable _≥″__>″?_ : Decidable _>″_n≤0⇒n≡0 : n ≤ 0 → n ≡ 0m<n⇒n≢0 : m < n → n ≢ 0m⊓n≡m⇒m≤n : m ⊓ n ≡ m → m ≤ nm⊓n≡n⇒n≤m : m ⊓ n ≡ n → n ≤ mn⊔m≡m⇒n≤m : n ⊔ m ≡ m → n ≤ mn⊔m≡n⇒m≤n : n ⊔ m ≡ n → m ≤ n*-distribˡ-∸ : _*_ DistributesOverˡ _∸_*-distrib-∸ : _*_ DistributesOver _∸_^-*-assoc : (m ^ n) ^ p ≡ m ^ (n * p)≤-poset : Poset 0ℓ 0ℓ 0ℓ<-resp₂-≡ : _<_ Respects₂ _≡_<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ*-+-isSemiring : IsSemiring _+_ _*_ 0 1⊓-semigroup : Semigroup 0ℓ 0ℓ⊔-semigroup : Semigroup 0ℓ 0ℓ⊔-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ⊓-⊔-lattice : Lattice 0ℓ 0ℓn≡m⇒∣n-m∣≡0 : n ≡ m → ∣ n - m ∣ ≡ 0m≤n⇒∣n-m∣≡n∸m : m ≤ n → ∣ n - m ∣ ≡ n ∸ m∣n-m∣≡0⇒n≡m : ∣ n - m ∣ ≡ 0 → n ≡ m∣n-m∣≡n∸m⇒m≤n : ∣ n - m ∣ ≡ n ∸ m → m ≤ n∣n-n∣≡0 : ∣ n - n ∣ ≡ 0∣n-n+m∣≡m : ∣ n - n + m ∣ ≡ m∣n+m-n+o∣≡∣m-o| : ∣ n + m - n + o ∣ ≡ ∣ m - o ∣n∸m≤∣n-m∣ : n ∸ m ≤ ∣ n - m ∣∣n-m∣≤n⊔m : ∣ n - m ∣ ≤ n ⊔ m∣-∣-comm : Commutative ∣_-_∣∣n-m∣≡[n∸m]∨[m∸n] : (∣ n - m ∣ ≡ n ∸ m) ⊎ (∣ n - m ∣ ≡ m ∸ n)*-distribˡ-∣-∣ : _*_ DistributesOverˡ ∣_-_∣*-distribʳ-∣-∣ : _*_ DistributesOverʳ ∣_-_∣*-distrib-∣-∣ : _*_ DistributesOver ∣_-_∣```* Added new function to `Data.String.Base`:```agdafromList⁺ : List⁺ Char → String```* Added new functions to `Data.Sum`:```agdamap₁ : (A → B) → A ⊎ C → B ⊎ Cmap₂ : (B → C) → A ⊎ B → A ⊎ C```* Added new functions in `Data.Table.Base`:```agdaremove : Fin (suc n) → Table A (suc n) → Table A nfromVec : Vec A n → Table A ntoVec : Table A n → Vec A n```* Added new proofs in `Data.Table.Properties`:```agdaselect-lookup : lookup (select x i t) i ≡ lookup t iselect-remove : remove i (select x i t) ≗ replicate {n} xremove-permute : remove (π ⟨$⟩ˡ i) (permute π t) ≗ permute (Perm.remove (π ⟨$⟩ˡ i) π) (remove i t)```* Added new functions to `Data.Vec`:```agdaalignWith : (These A B → C) → Vec A m → Vec B n → Vec C (m ⊔ n)align : Vec A m → Vec B n → Vec (These A B) (m ⊔ n)unzipWith : (A → B × C) → Vec A n → Vec B n × Vec C n```* Added new proofs to `Data.Vec.All.Properties`:```agdatoList⁺ : All P (toList xs) → All P xstoList⁻ : All P xs → All P (toList xs)fromList⁺ : All P xs → All P (fromList xs)fromList⁻ : All P (fromList xs) → All P xs```* Added new functions to `Data.Vec.Any`:```agdahead : ¬ Any P xs → Any P (x ∷ xs) → P xtoSum : Any P (x ∷ xs) → P x ⊎ Any P xsfromSum : P x ⊎ Any P xs → Any P (x ∷ xs)```* Added new functions to `Data.Vec.Categorical`:```agdasequenceA : RawApplicative F → Vec (F A) n → F (Vec A n)mapA : RawApplicative F → (A → F B) → Vec A n → F (Vec B n)forA : RawApplicative F → Vec A n → (A → F B) → F (Vec B n)sequenceM : RawMonad M → Vec (M A) n → M (Vec A n)mapM : RawMonad M → (A → M B) → Vec A n → M (Vec B n)forM : RawMonad M → Vec A n → (A → M B) → M (Vec B n)```* Added new proofs to `Data.Vec.Membership.Propositional.Properties`:```agda∈-lookup : lookup i xs ∈ xs∈-toList⁻ : v ∈ toList xs → v ∈ xs∈-fromList⁻ : v ∈ fromList xs → v ∈ xs```* Added new proof to `Data.Vec.Properties`:```agdalookup-zipWith : lookup i (zipWith f xs ys) ≡ f (lookup i xs) (lookup i ys)```* Added new proofs to `Data.Vec.Relation.Pointwise.Inductive`:```agdatabulate⁺ : (∀ i → f i ~ g i) → Pointwise _~_ (tabulate f) (tabulate g)tabulate⁻ : Pointwise _~_ (tabulate f) (tabulate g) → (∀ i → f i ~ g i)```* Added new type to `Foreign.Haskell`:```agdaPair : (A : Set ℓ) (B : Set ℓ′) : Set (ℓ ⊔ ℓ′)```* Added new function to `Function`:```agdatypeOf : {A : Set a} → A → Set a```* Added new functions to `Function.Related`:```agdaisEquivalence : IsEquivalence (Related ⌊ k ⌋)↔-isPreorder : IsPreorder _↔_ (Related k)```* Added new result to `Function.Related.TypeIsomorphisms`:```agda×-comm : (A × B) ↔ (B × A)×-identityˡ : LeftIdentity _↔_ (Lift ℓ ⊤) _×_×-identityʳ : RightIdentity _↔_ (Lift ℓ ⊤) _×_×-identity : Identity _↔_ (Lift ℓ ⊤) _×_×-zeroˡ : LeftZero _↔_ (Lift ℓ ⊥) _×_×-zeroʳ : RightZero _↔_ (Lift ℓ ⊥) _×_×-zero : Zero _↔_ (Lift ℓ ⊥) _×_⊎-assoc : Associative _↔_ _⊎_⊎-comm : (A ⊎ B) ↔ (B ⊎ A)⊎-identityˡ : LeftIdentity _↔_ (Lift ℓ ⊥) _⊎_⊎-identityʳ : RightIdentity _↔_ (Lift ℓ ⊥) _⊎_⊎-identity : Identity _↔_ (Lift ℓ ⊥) _⊎_×-distribˡ-⊎ : _DistributesOverˡ_ _↔_ _×_ _⊎_×-distribʳ-⊎ : _DistributesOverʳ_ _↔_ _×_ _⊎_×-distrib-⊎ : _DistributesOver_ _↔_ _×_ _⊎_×-isSemigroup : IsSemigroup (Related ⌊ k ⌋) _×_×-semigroup : Symmetric-kind → Level → Semigroup _ _×-isMonoid : IsMonoid (Related ⌊ k ⌋) _×_ (Lift ℓ ⊤)×-monoid : Symmetric-kind → Level → Monoid _ _×-isCommutativeMonoid : IsCommutativeMonoid (Related ⌊ k ⌋) _×_ (Lift ℓ ⊤)×-commutativeMonoid : Symmetric-kind → Level → CommutativeMonoid _ _⊎-isSemigroup : IsSemigroup (Related ⌊ k ⌋) _⊎_⊎-semigroup : Symmetric-kind → Level → Semigroup _ _⊎-isMonoid : IsMonoid (Related ⌊ k ⌋) _⊎_ (Lift ℓ ⊥)⊎-monoid : Symmetric-kind → Level → Monoid _ _⊎-isCommutativeMonoid : IsCommutativeMonoid (Related ⌊ k ⌋) _⊎_ (Lift ℓ ⊥)⊎-commutativeMonoid : Symmetric-kind → Level → CommutativeMonoid _ _×-⊎-isCommutativeSemiring : IsCommutativeSemiring (Related ⌊ k ⌋) _⊎_ _×_ (Lift ℓ ⊥) (Lift ℓ ⊤)```* Added new type and function to `Function.Bijection`:```agdaFrom ⤖ To = Bijection (P.setoid From) (P.setoid To)bijection : (∀ {x y} → to x ≡ to y → x ≡ y) → (∀ x → to (from x) ≡ x) → From ⤖ To```* Added new function to `Function.Injection`:```agdainjection : (∀ {x y} → to x ≡ to y → x ≡ y) → From ↣ To```* Added new function to `Function.Inverse`:```agdainverse : (∀ x → from (to x) ≡ x) → (∀ x → to (from x) ≡ x) → From ↔ To```* Added new function to `Function.LeftInverse`:```agdaleftInverse : (∀ x → from (to x) ≡ x) → From ↞ To```* Added new proofs to `Function.Related`:```agdaK-refl : Reflexive (Related k)K-reflexive : _≡_ ⇒ Related kK-trans : Trans (Related k) (Related k) (Related k)K-isPreorder : IsPreorder _↔_ (Related k)SK-sym : Sym (Related ⌊ k ⌋) (Related ⌊ k ⌋)SK-isEquivalence : IsEquivalence (Related ⌊ k ⌋)```* Added new proofs to `Function.Related.TypeIsomorphisms`:```agda×-≡×≡↔≡,≡ : (x ≡ proj₁ p × y ≡ proj₂ p) ↔ (x , y) ≡ p×-comm : (A × B) ↔ (B × A)```* Added new function to `Function.Surjection`:```agdasurjection : (∀ x → to (from x) ≡ x) → From ↠ To```* Added new synonym to `Level`:```agda0ℓ = zero```* Added new module `Level.Literals` with functions:```agda_ℕ+_ : Nat → Level → Level#_ : Nat → LevelLevelℕ : Number Level```* Added new proofs to record `IsStrictPartialOrder` in `Relation.Binary`:```agda<-respʳ-≈ : _<_ Respectsʳ _≈_<-respˡ-≈ : _<_ Respectsˡ _≈_```* Added new functions and records to `Relation.Binary.Indexed.Heterogeneous`:```agdarecord IsIndexedPreorder (_≈_ : Rel A ℓ₁) (_∼_ : Rel A ℓ₂) : Set (i ⊔ a ⊔ ℓ₁ ⊔ ℓ₂)record IndexedPreorder {i} (I : Set i) c ℓ₁ ℓ₂ : Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂))```* Added new proofs to `Relation.Binary.Indexed.Heterogeneous.Construct.At`:```agdaisEquivalence : IsIndexedEquivalence A _≈_ → (i : I) → B.IsEquivalence (_≈_ {i})isPreorder : IsIndexedPreorder A _≈_ _∼_ → (i : I) → B.IsPreorder (_≈_ {i}) _∼_setoid : IndexedSetoid I a ℓ → I → B.Setoid a ℓpreorder : IndexedPreorder I a ℓ₁ ℓ₂ → I → B.Preorder a ℓ₁ ℓ₂```* Added new proofs to `Relation.Binary.Indexed.Heterogeneous.Construct.Trivial`:```agdaisIndexedEquivalence : IsEquivalence _≈_ → IsIndexedEquivalence (λ (_ : I) → A) _≈_isIndexedPreorder : IsPreorder _≈_ _∼_ → IsIndexedPreorder (λ (_ : I) → A) _≈_ _∼_indexedSetoid : Setoid a ℓ → ∀ {I} → IndexedSetoid I a ℓindexedPreorder : Preorder a ℓ₁ ℓ₂ → ∀ {I} → IndexedPreorder I a ℓ₁ ℓ₂```* Added new types, functions and records to `Relation.Binary.Indexed.Homogeneous`:```agdaImplies _∼₁_ _∼₂_ = ∀ {i} → _∼₁_ B.⇒ (_∼₂_ {i})Antisymmetric _≈_ _∼_ = ∀ {i} → B.Antisymmetric _≈_ (_∼_ {i})Decidable _∼_ = ∀ {i} → B.Decidable (_∼_ {i})Respects P _∼_ = ∀ {i} {x y : A i} → x ∼ y → P x → P yRespectsˡ P _∼_ = ∀ {i} {x y z : A i} → x ∼ y → P x z → P y zRespectsʳ P _∼_ = ∀ {i} {x y z : A i} → x ∼ y → P z x → P z yRespects₂ P _∼_ = (Respectsʳ P _∼_) × (Respectsˡ P _∼_)Lift _∼_ x y = ∀ i → x i ∼ y irecord IsIndexedEquivalence (_≈ᵢ_ : Rel A ℓ) : Set (i ⊔ a ⊔ ℓ)record IsIndexedDecEquivalence (_≈ᵢ_ : Rel A ℓ) : Set (i ⊔ a ⊔ ℓ)record IsIndexedPreorder (_≈ᵢ_ : Rel A ℓ₁) (_∼ᵢ_ : Rel A ℓ₂) : Set (i ⊔ a ⊔ ℓ₁ ⊔ ℓ₂)record IsIndexedPartialOrder (_≈ᵢ_ : Rel A ℓ₁) (_≤ᵢ_ : Rel A ℓ₂) : Set (i ⊔ a ⊔ ℓ₁ ⊔ ℓ₂)record IndexedSetoid {i} (I : Set i) c ℓ : Set (suc (i ⊔ c ⊔ ℓ))record IndexedDecSetoid {i} (I : Set i) c ℓ : Set (suc (i ⊔ c ⊔ ℓ))record IndexedPreorder {i} (I : Set i) c ℓ₁ ℓ₂ : Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂))record IndexedPoset {i} (I : Set i) c ℓ₁ ℓ₂ : Set (suc (i ⊔ c ⊔ ℓ₁ ⊔ ℓ₂))```* Added new types, records and proofs to `Relation.Binary.Lattice`:```agdaExponential _≤_ _∧_ _⇨_ = ∀ w x y → ((w ∧ x) ≤ y → w ≤ (x ⇨ y)) × (w ≤ (x ⇨ y) → (w ∧ x) ≤ y)IsJoinSemilattice.x≤x∨y : x ≤ x ∨ yIsJoinSemilattice.y≤x∨y : y ≤ x ∨ yIsJoinSemilattice.∨-least : x ≤ z → y ≤ z → x ∨ y ≤ zIsMeetSemilattice.x∧y≤x : x ∧ y ≤ xIsMeetSemilattice.x∧y≤y : x ∧ y ≤ yIsMeetSemilattice.∧-greatest : x ≤ y → x ≤ z → x ≤ y ∧ zrecord IsDistributiveLattice _≈_ _≤_ _∨_ _∧_record IsHeytingAlgebra _≈_ _≤_ _∨_ _∧_ _⇨_ ⊤ ⊥record IsBooleanAlgebra _≈_ _≤_ _∨_ _∧_ ¬_ ⊤ ⊥record DistributiveLattice c ℓ₁ ℓ₂record HeytingAlgebra c ℓ₁ ℓ₂record BooleanAlgebra c ℓ₁ ℓ₂```* Added new proofs to `Relation.Binary.NonStrictToStrict`:```agda<⇒≤ : _<_ ⇒ _≤_```* Added new proofs to `Relation.Binary.PropositionalEquality`:```agdarespˡ : ∼ Respectsˡ _≡_respʳ : ∼ Respectsʳ _≡_```* Added new proofs to `Relation.Binary.Construct.Always`:```agdarefl : Reflexive Alwayssym : Symmetric Alwaystrans : Transitive AlwaysisEquivalence : IsEquivalence Always```* Added new proofs to `Relation.Binary.Construct.Constant`:```agdarefl : C → Reflexive (Const C)sym : Symmetric (Const C)trans : Transitive (Const C)isEquivalence : C → IsEquivalence (Const C)setoid : C → Setoid a c```* Added new definitions and proofs to `Relation.Binary.Construct.FromPred`:```agdaResp x y = P x → P yreflexive : P Respects _≈_ → _≈_ ⇒ Resprefl : P Respects _≈_ → Reflexive Resptrans : Transitive RespisPreorder : P Respects _≈_ → IsPreorder _≈_ Resppreorder : P Respects _≈_ → Preorder _ _ _```* Added new definitions and proofs to `Relation.Binary.Construct.FromRel`:```agdaResp x y = ∀ {a} → a R x → a R yreflexive : (∀ {a} → (a R_) Respects _≈_) → _≈_ ⇒ Resptrans : Transitive RespisPreorder : (∀ {a} → (a R_) Respects _≈_) → IsPreorder _≈_ Resppreorder : (∀ {a} → (a R_) Respects _≈_) → Preorder _ _ _```* Added new proofs to `Relation.Binary.Construct.StrictToNonStrict`:```agda<⇒≤ : _<_ ⇒ _≤_≤-respʳ-≈ : Transitive _≈_ → _<_ Respectsʳ _≈_ → _≤_ Respectsʳ _≈_≤-respˡ-≈ : Symmetric _≈_ → Transitive _≈_ → _<_ Respectsˡ _≈_ → _≤_ Respectsˡ _≈_<-≤-trans : Transitive _<_ → _<_ Respectsʳ _≈_ → Trans _<_ _≤_ _<_≤-<-trans : Symmetric _≈_ → Transitive _<_ → _<_ Respectsˡ _≈_ → Trans _≤_ _<_ _<_```* Added new types in `Relation.Unary`:```agdaSatisfiable P = ∃ λ x → x ∈ PIUniversal P = ∀ {x} → x ∈ P```* Added new proofs in `Relation.Unary.Properties`:```agda∅? : Decidable ∅U? : Decidable U```
Version 0.16============The library has been tested using Agda version 2.5.4.Important changes since 0.15:Non-backwards compatible changes--------------------------------#### Final overhaul of list membership* The aim of this final rearrangement of list membership is to create a better interface forthe different varieties of membership, and make it easier to predict where certainproofs are found. Each of the new membership modules are parameterised by the relevant typesso as to allow easy access to the infix `_∈_` and `_∈?_` operators. It also increasesthe discoverability of the modules by new users of the library.* The following re-organisation of list membership modules has occurred:```agdaData.List.Any.BagAndSetEquality ↦ Data.List.Relation.BagAndSetEqualityData.List.Any.Membership ↦ Data.List.Membership.Setoid↘ Data.List.Membership.DecSetoid↘ Data.List.Relation.Sublist.SetoidData.List.Any.Membership.Propositional ↦ Data.List.Membership.Propositional↘ Data.List.Membership.DecPropositional↘ Data.List.Relation.Sublist.Propositional```* The `_⊆_` relation has been moved out of the `Membership` modules to newmodules `Data.List.Relation.Sublist.(Setoid/Propositional)`. Consequently the `mono`proofs that were in `Data.List.Membership.Propositional.Properties` have been moved to`Data.List.Relation.Sublist.Propositional.Properties`.* The following proofs have been moved from `Data.List.Any.Properties` to`Data.List.Membership.Propositional.Properties.Core`:```agdamap∘find, find∘map, find-∈, lose∘find, find∘lose, ∃∈-Any, Any↔```* The following types and terms have been moved from `Data.List.Membership.Propositional` into`Relation.BagAndSetEquality`:```agdaKind, Symmetric-kindset, subset, superset, bag, subbag, superbag[_]-Order, [_]-Equality, _∼[_]_```* The type of the proof of `∈-resp-≈` in `Data.List.Membership.Setoid.Properties` has changed from`∀ {x} → (x ≈_) Respects _≈_` to `∀ {xs} → (_∈ xs) Respects _≈_`.#### Upgrade of `Algebra.Operations`* Previously `Algebra.Operations` was parameterised by a semiring, however several of theoperators it defined depended only on the additive component. Therefore the modules have beenrearranged to allow more fine-grained use depending on the current position in the algebraheirarchy. Currently there exist two modules:```Algebra.Operations.CommutativeMonoidAlgebra.Operations.Semiring```where `Algebra.Operations.Semiring` exports all the definitions previously exportedby `Algebra.Operations`. More modules may be added in future as required.Also the fixity of `_×_`, `_×′_` and `_^_` have all been increased by 1.#### Upgrade of `takeWhile`, `dropWhile`, `span` and `break` in `Data.List`* These functions in `Data.List.Base` now use decidablepredicates instead of boolean-valued functions. The boolean versions discardedtype information, and hence were difficult to use and proveproperties about. The proofs have been updated and renamed accordingly.The old boolean versions still exist as `boolTakeWhile`, `boolSpan` etc. forbackwards compatibility reasons, but are deprecated and may be removed in somefuture release. The old versions can be implemented via the new versionsby passing the decidability proof `λ v → f v ≟ true` with `_≟_` from `Data.Bool`.#### Other* `Relation.Binary.Consequences` no longer exports `Total`. The standard way of accessing itthrough `Relation.Binary` remains unchanged.* `_⇒_` in `Relation.Unary` is now right associative instead of left associative.* Added new module `Relation.Unary.Properties`. The following proofs have been movedto the new module from `Relation.Unary`: `∅-Empty`, `∁∅-Universal`, `U-Universal`,`∁U-Empty`, `∅-⊆`, `⊆-U` and `∁?`.* The set operations `_∩/∪_` in `Data.Fin.Subset` are now implemented more efficientlyusing `zipWith _∧/∨_ p q` rather than `replicate _∧/∨_ ⊛ p ⊛ q`. The proof`booleanAlgebra` has been moved to `∩-∪-booleanAlgebra` in `Data.Fin.Subset.Properties`.* The decidability proofs `_≟_` and `_<?_` are now exported by `Data.Fin` as well as`Data.Fin.Properties` to improve consistency across the library. They may conflict with`_≟_` and `_<?_` in `Data.Nat` or others. If so then it may be necessary to qualify importswith either `using` or `hiding`.* Refactored and moved `↔Vec` from `Data.Product.N-ary` to `Data.Product.N-ary.Properties`.* Moved the function `reverse` and related proofs `reverse-prop``reverse-involutive` and `reverse-suc` from `Data.Fin.Properties` to the newmodule `Data.Fin.Permutation.Components`.* Refactored `reverseView` in `Data.List.Reverse` to use a direct style insteadof the well-founded induction on the list's length that was used previously.* The function `filter` as implemented in `Data.List` has the semantics of _filter through_ ratherthan _filter out_. The naming of proofs in `Data.List.Properties` used the latter rather thanthe former and therefore the names of the proofs have been switched as follows:```agdafilter-none ↦ filter-allfilter-some ↦ filter-notAllfilter-notAll ↦ filter-somefilter-all ↦ filter-none```Other major changes-------------------* The module `Algebra.Structures` can now be parameterised by equality in the same wayas `Algebra.FunctionProperties`. The structures within also now export a greater selectionof "left" and "right" properties. For example (where applicable):```agdaidentityˡ : LeftIdentity ε _∙_identityʳ : RightIdentity ε _∙_inverseˡ : LeftInverse ε _⁻¹ _∙_inverseʳ : RightInverse ε _⁻¹ _∙_zeroˡ : LeftZero 0# _*_zeroʳ : RightZero 0# _*_distribˡ : _*_ DistributesOverˡ _+_distribʳ : _*_ DistributesOverʳ _+_```* Added new modules `Data.Fin.Permutation` and `Data.Fin.Permutation.Components` forreasoning about permutations. Permutations are implemented as bijections`Fin m → Fin n`. `Permutation.Components` contains functions and proofs used toimplement these bijections.* Added new modules `Data.List.Zipper` and `Data.List.Zipper.Properties`.* Added a new module `Function.Reasoning` for creating multi-stage function pipelines.See `README.Function.Reasoning` for examples.* Added new module `Relation.Binary.Indexed.Homogeneous`. This module defineshomogeneously-indexed binary relations, as opposed to theheterogeneously-indexed binary relations found in `Relation.Binary.Indexed`.* Closures of binary relations have been centralised as follows:```agdaData.ReflexiveClosure ↦ Relation.Binary.Closure.ReflexiveRelation.Binary.SymmetricClosure ↦ Relation.Binary.Closure.SymmetricData.Plus ↦ Relation.Binary.Closure.TransitiveData.Star ↦ Relation.Binary.Closure.ReflexiveTransitiveData.Star.Properties ↦ Relation.Binary.Closure.ReflexiveTransitive.PropertiesRelation.Binary.EquivalenceClosure ↦ Relation.Binary.Closure.Equivalence```The old files still exist and re-export the contents of the new modules.Deprecated features-------------------The following renaming has occurred as part of a drive to improve consistency acrossthe library. The old names still exist and therefore all existing code should stillwork, however they have been deprecated and use of the new names is encouraged. Although notanticipated any time soon, they may eventually be removed in some future release of the library.* In `Data.Fin.Properties`:```agdato-from ↦ toℕ-fromℕfrom-to ↦ fromℕ-toℕbounded ↦ toℕ<nprop-toℕ-≤ ↦ toℕ≤pred[n]prop-toℕ-≤′ ↦ toℕ≤pred[n]′inject-lemma ↦ toℕ-injectinject+-lemma ↦ toℕ-inject+inject₁-lemma ↦ toℕ-inject₁inject≤-lemma ↦ toℕ-inject≤```* In `Data.List.All.Properties`:```agdaAll-all ↦ all⁻all-All ↦ all⁺All-map ↦ map⁺map-All ↦ map⁻```* In `Data.List.Membership.Propositional`:```agdafilter-∈ ↦ ∈-filter⁺```* In `Data.List.Membership.Setoid`:```agdamap-with-∈ ↦ mapWith∈```* In `Data.Vec.All.Properties`:```agdaAll-map ↦ map⁺map-All ↦ map⁻All-++⁺ ↦ ++⁺All-++ˡ⁻ ↦ ++ˡ⁻All-++ʳ⁻ ↦ ++ʳ⁻All-++⁻ ↦ ++⁻All-++⁺∘++⁻ ↦ ++⁺∘++⁻All-++⁻∘++⁺ ↦ ++⁻∘++⁺All-concat⁺ ↦ concat⁺All-concat⁻ ↦ concat⁻```* In `Relation.Binary.NonStrictToStrict`:```agdairrefl ↦ <-irrefltrans ↦ <-transantisym⟶asym ↦ <-asymdecidable ↦ <-decidabletrichotomous ↦ <-trichotomousisPartialOrder⟶isStrictPartialOrder ↦ <-isStrictPartialOrderisTotalOrder⟶isStrictTotalOrder ↦ <-isStrictTotalOrder₁isDecTotalOrder⟶isStrictTotalOrder ↦ <-isStrictTotalOrder₂```* In `IsStrictPartialOrder` record in `Relation.Binary`:```agdaasymmetric ↦ asym```Other minor additions---------------------* Added new records to `Algebra`:```agdarecord Band c ℓ : Set (suc (c ⊔ ℓ))record Semilattice c ℓ : Set (suc (c ⊔ ℓ))```* Added new records to `Algebra.Structures`:```agdarecord IsBand (• : Op₂ A) : Set (a ⊔ ℓ)record IsSemilattice (∧ : Op₂ A) : Set (a ⊔ ℓ)```* Added new functions to `Algebra.Operations.CommutativeMonoid`:```agdasumₗ = List.foldr _+_ 0#sumₜ = Table.foldr _+_ 0#```* Added new proofs to `Data.Bool.Properties`:```agda∧-semigroup : Semigroup _ _∧-commutativeMonoid : CommutativeMonoid _∧-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∧-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∧_ true∨-semigroup : Semigroup _ _∨-commutativeMonoid : CommutativeMonoid _ _∨-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∨-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∨_ false∨-∧-lattice : Lattice _ _∨-∧-distributiveLattice : DistributiveLattice _ _```* Added new proofs to `Data.Fin.Properties`:```agda¬Fin0 : ¬ Fin 0≤-preorder : ℕ → Preorder _ _ _≤-poset : ℕ → Poset _ _ _≤-totalOrder : ℕ → TotalOrder _ _ _≤-decTotalOrder : ℕ → DecTotalOrder _ _ _<-respˡ-≡ : _<_ Respectsˡ _≡_<-respʳ-≡ : _<_ Respectsʳ _≡_<-resp₂-≡ : _<_ Respects₂ _≡_<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_<-strictPartialOrder : ℕ → StrictPartialOrder _ _ _<⇒≢ : i < j → i ≢ j≤+≢⇒< : i ≤ j → i ≢ j → i < j<⇒≤pred : j < i → j ≤ pred itoℕ‿ℕ- : toℕ (n ℕ- i) ≡ n ∸ toℕ iinject₁-injective : inject₁ i ≡ inject₁ j → i ≡ jpunchOut-cong : j ≡ k → punchOut i≢j ≡ punchOut i≢kpunchOut-cong′ : punchOut i≢j ≡ punchOut (i≢j ∘ sym ∘ trans j≡k ∘ sym)punchOut-punchIn : punchOut (punchInᵢ≢i i j ∘ sym) ≡ j∀-cons : P zero → (∀ i → P (suc i)) → (∀ i → P i)sequence⁻¹ : RawFunctor F → F (∀ i → P i) → (∀ i → F (P i))```* Added new functions to `Data.Fin.Subset`:```agda∣ p ∣ = count (_≟ inside) p```* Added new proofs to `Data.Fin.Subset.Properties`:```agda∣p∣≤n : ∣ p ∣ ≤ n∣⊥∣≡0 : ∣ ⊥ ∣ ≡ 0∣⊤∣≡n : ∣ ⊤ ∣ ≡ n∣⁅x⁆∣≡1 : ∣ ⁅ i ⁆ ∣ ≡ 1⊆-refl : Reflexive _⊆_⊆-reflexive : _≡_ ⇒ _⊆_⊆-trans : Transitive _⊆_⊆-antisym : Antisymmetric _≡_ _⊆_⊆-min : Minimum _⊆_ ⊥⊆-max : Maximum _⊆_ ⊤⊆-isPreorder : IsPreorder _≡_ _⊆_⊆-preorder : Preorder _ _ _⊆-isPartialOrder : IsPartialOrder _≡_ _⊆_p⊆q⇒∣p∣<∣q∣ : ∀ {n} {p q : Subset n} → p ⊆ q → ∣ p ∣ ≤ ∣ q ∣∩-idem : Idempotent _∩_∩-identityˡ : LeftIdentity ⊤ _∩_∩-identityʳ : RightIdentity ⊤ _∩_∩-identity : Identity ⊤ _∩_∩-zeroˡ : LeftZero ⊥ _∩_∩-zeroʳ : RightZero ⊥ _∩_∩-zero : Zero ⊥ _∩_∩-inverseˡ : LeftInverse ⊥ ∁ _∩_∩-inverseʳ : RightInverse ⊥ ∁ _∩_∩-inverse : Inverse ⊥ ∁ _∩_∪-idem : Idempotent _∪_∪-identityˡ : LeftIdentity ⊥ _∪_∪-identityʳ : RightIdentity ⊥ _∪_∪-identity : Identity ⊥ _∪_∪-zeroˡ : LeftZero ⊤ _∪_∪-zeroʳ : RightZero ⊤ _∪_∪-zero : Zero ⊤ _∪_∪-inverseˡ : LeftInverse ⊤ ∁ _∪_∪-inverseʳ : RightInverse ⊤ ∁ _∪_∪-inverse : Inverse ⊤ ∁ _∪_∪-distribˡ-∩ : _∪_ DistributesOverˡ _∩_∪-distribʳ-∩ : _∪_ DistributesOverʳ _∩_∪-distrib-∩ : _∪_ DistributesOver _∩_∩-distribˡ-∪ : _∩_ DistributesOverˡ _∪_∩-distribʳ-∪ : _∩_ DistributesOverʳ _∪_∩-distrib-∪ : _∩_ DistributesOver _∪_∪-abs-∩ : _∪_ Absorbs _∩_∩-abs-∪ : _∩_ Absorbs _∪_∩-isSemigroup : IsSemigroup _∩_∩-semigroup : Semigroup _ _∩-isMonoid : IsMonoid _∩_ ⊤∩-monoid : Monoid _ _∩-isCommutativeMonoid : IsCommutativeMonoid _∩_ ⊤∩-commutativeMonoid : CommutativeMonoid _ _∩-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∩_ ⊤∩-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∪-isSemigroup : IsSemigroup _∪_∪-semigroup : Semigroup _ _∪-isMonoid : IsMonoid _∪_ ⊥∪-monoid : Monoid _ _∪-isCommutativeMonoid : IsCommutativeMonoid _∪_ ⊥∪-commutativeMonoid : CommutativeMonoid _ _∪-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _∪_ ⊥∪-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _∪-∩-isLattice : IsLattice _∪_ _∩_∪-∩-lattice : Lattice _ _∪-∩-isDistributiveLattice : IsDistributiveLattice _∪_ _∩_∪-∩-distributiveLattice : DistributiveLattice _ _∪-∩-isBooleanAlgebra : IsBooleanAlgebra _∪_ _∩_ ∁ ⊤ ⊥∪-∩-booleanAlgebra : BooleanAlgebra _ _∩-∪-isLattice : IsLattice _∩_ _∪_∩-∪-lattice : Lattice _ _∩-∪-isDistributiveLattice : IsDistributiveLattice _∩_ _∪_∩-∪-distributiveLattice : DistributiveLattice _ _∩-∪-isBooleanAlgebra : IsBooleanAlgebra _∩_ _∪_ ∁ ⊥ ⊤∩-∪-booleanAlgebra : BooleanAlgebra _ _```* Added new functions to `Data.List.All`:```agdazip : All P ∩ All Q ⊆ All (P ∩ Q)unzip : All (P ∩ Q) ⊆ All P ∩ All Q```* Added new proofs to `Data.List.All.Properties`:```agdasingleton⁻ : All P [ x ] → P xfromMaybe⁺ : Maybe.All P mx → All P (fromMaybe mx)fromMaybe⁻ : All P (fromMaybe mx) → Maybe.All P mxreplicate⁺ : P x → All P (replicate n x)replicate⁻ : All P (replicate (suc n) x) → P xinits⁺ : All P xs → All (All P) (inits xs)inits⁻ : All (All P) (inits xs) → All P xstails⁺ : All P xs → All (All P) (tails xs)tails⁻ : All (All P) (tails xs) → All P xs```* Added new proofs to `Data.List.Membership.(Setoid/Propositional).Properties`:```agda∉-resp-≈ : ∀ {xs} → (_∉ xs) Respects _≈_∉-resp-≋ : ∀ {x} → (x ∉_) Respects _≋_mapWith∈≗map : mapWith∈ xs (λ {x} _ → f x) ≡ map f xsmapWith∈-cong : (∀ x∈xs → f x∈xs ≡ g x∈xs) → mapWith∈ xs f ≡ map-with-∈ xs g∈-++⁺ˡ : v ∈ xs → v ∈ xs ++ ys∈-++⁺ʳ : v ∈ ys → v ∈ xs ++ ys∈-++⁻ : v ∈ xs ++ ys → (v ∈ xs) ⊎ (v ∈ ys)∈-concat⁺ : Any (v ∈_) xss → v ∈ concat xss∈-concat⁻ : v ∈ concat xss → Any (v ∈_) xss∈-concat⁺′ : v ∈ vs → vs ∈ xss → v ∈ concat xss∈-concat⁻′ : v ∈ concat xss → ∃ λ xs → v ∈ xs × xs ∈ xss∈-applyUpTo⁺ : i < n → f i ∈ applyUpTo f n∈-applyUpTo⁻ : v ∈ applyUpTo f n → ∃ λ i → i < n × v ≈ f i∈-tabulate⁺ : f i ∈ tabulate f∈-tabulate⁻ : v ∈ tabulate f → ∃ λ i → v ≈ f i∈-filter⁺ : P v → v ∈ xs → v ∈ filter P? xs∈-filter⁻ : v ∈ filter P? xs → v ∈ xs × P v∈-length : x ∈ xs → 1 ≤ length xs∈-lookup : lookup xs i ∈ xsfoldr-selective : Selective _≈_ _•_ → (foldr _•_ e xs ≈ e) ⊎ (foldr _•_ e xs ∈ xs)```* Added new function to `Data.List.NonEmpty`:```agdafromList : List A → Maybe (List⁺ A)```* Added new proofs to `Data.List.Properties`:```agdatabulate-cong : f ≗ g → tabulate f ≡ tabulate gtabulate-lookup : tabulate (lookup xs) ≡ xslength-drop : length (drop n xs) ≡ length xs ∸ nlength-take : length (take n xs) ≡ n ⊓ (length xs)```* Added new proof to `Data.List.Relation.Pointwise````agdaPointwise-length : Pointwise _∼_ xs ys → length xs ≡ length ys```* Added new proofs to `Data.List.Relation.Sublist.(Setoid/Propositional).Properties`:```agda⊆-reflexive : _≋_ ⇒ _⊆_⊆-refl : Reflexive _⊆_⊆-trans : Transitive _⊆_⊆-isPreorder : IsPreorder _≋_ _⊆_filter⁺ : ∀ xs → filter P? xs ⊆ xs```* Added new proofs to `Data.Nat.Properties`:```agdam+n≮m : m + n ≮ mm≮m∸n : m ≮ m ∸ n+-0-isMonoid : IsMonoid _+_ 0*-1-isMonoid : IsMonoid _*_ 1⊓-triangulate : x ⊓ y ⊓ z ≡ (x ⊓ y) ⊓ (y ⊓ z)⊔-triangulate : x ⊔ y ⊔ z ≡ (x ⊔ y) ⊔ (y ⊔ z)m∸n≡0⇒m≤n : m ∸ n ≡ 0 → m ≤ nm≤n⇒m∸n≡0 : m ≤ n → m ∸ n ≡ 0∸-monoˡ-≤ : m ≤ n → m ∸ o ≤ n ∸ o∸-monoʳ-≤ : m ≤ n → o ∸ m ≥ o ∸ n∸-distribˡ-⊓-⊔ : x ∸ (y ⊓ z) ≡ (x ∸ y) ⊔ (x ∸ z)∸-distribˡ-⊔-⊓ : x ∸ (y ⊔ z) ≡ (x ∸ y) ⊓ (x ∸ z)```* Added new functions to `Data.Product`:```agdamap₁ : (A → B) → A × C → B × Cmap₂ : (∀ {x} → B x → C x) → Σ A B → Σ A C```* Added new functions to `Data.Product.N-ary`:```agda_∈[_]_ : A → ∀ n → A ^ n → Set acons : ∀ n → A → A ^ n → A ^ suc nuncons : ∀ n → A ^ suc n → A × A ^ nhead : ∀ n → A ^ suc n → Atail : ∀ n → A ^ suc n → A ^ nlookup : ∀ (k : Fin n) → A ^ n → Areplicate : ∀ n → A → A ^ ntabulate : ∀ n → (Fin n → A) → A ^ nappend : ∀ m n → A ^ m → A ^ n → A ^ (m + n)splitAt : ∀ m n → A ^ (m + n) → A ^ m × A ^ nmap : (A → B) → ∀ n → A ^ n → B ^ nap : ∀ n → (A → B) ^ n → A ^ n → B ^ nfoldr : P 0 → (A → P 1) → (∀ n → A → P (suc n) → P (2+ n)) → ∀ n → A ^ n → P nfoldl : P 0 → (A → P 1) → (∀ n → A → P (suc n) → P (2+ n)) → ∀ n → A ^ n → P nreverse : ∀ n → A ^ n → A ^ nzipWith : (A → B → C) → ∀ n → A ^ n → B ^ n → C ^ nunzipWith : (A → B × C) → ∀ n → A ^ n → B ^ n × C ^ nzip : ∀ n → A ^ n → B ^ n → (A × B) ^ nunzip : ∀ n → (A × B) ^ n → A ^ n × B ^ n```* Added new proofs to `Data.Product.N-ary.Properties`:```agdacons-head-tail-identity : cons n (head n as) (tail n as) ≡ ashead-cons-identity : head n (cons n a as) ≡ atail-cons-identity : tail n (cons n a as) ≡ asappend-cons-commute : append (suc m) n (cons m a xs) ys ≡ cons (m + n) a (append m n xs ys)append-splitAt-identity : uncurry (append m n) (splitAt m n as) ≡ as```* Added new functions to `Data.String.Base`:```agdalength : String → ℕreplicate : ℕ → Char → Stringconcat : List String → String```* Added operator to `Data.Sum`:```agdaswap : A ⊎ B → B ⊎ A```This may conflict with `swap` in `Data.Product`. If so then it may be necessary toqualify imports with either `using` or `hiding`.* Added new proof to `Data.Sum.Properties`:```agdaswap-involutive : swap ∘ swap ≗ id```* Added new function to `Data.Vec`:```agdacount : Decidable P → Vec A n → ℕinsert : Fin (suc n) → A → Vec A n → Vec A (suc n)remove : Fin (suc n) → Vec A (suc n) → Vec A n```* Added new proofs to `Data.Vec.Properties`:```agda[]=-injective : xs [ i ]= x → xs [ i ]= y → x ≡ ycount≤n : ∀ {n} (xs : Vec A n) → count P? xs ≤ n++-injectiveˡ : (xs xs' : Vec A n) → xs ++ ys ≡ xs' ++ ys' → xs ≡ xs'++-injectiveʳ : (xs xs' : Vec A n) → xs ++ ys ≡ xs' ++ ys' → ys ≡ ys'++-injective : (xs xs' : Vec A n) → xs ++ ys ≡ xs' ++ ys' → xs ≡ xs' × ys ≡ ys'++-assoc : (xs ++ ys) ++ zs ≅ xs ++ (ys ++ zs)insert-lookup : lookup i (insert i x xs) ≡ xinsert-punchIn : lookup (punchIn i j) (insert i x xs) ≡ lookup j xsremove-punchOut : (i≢j : i ≢ j) → lookup (punchOut i≢j) (remove i xs) ≡ lookup j xsremove-insert : remove i (insert i x xs) ≡ xsinsert-remove : insert i (lookup i xs) (remove i xs) ≡ xszipWith-assoc : Associative _≡_ f → Associative _≡_ (zipWith f)zipWith-comm : (∀ x y → f x y ≡ f y x) → zipWith f xs ys ≡ zipWith f ys xszipWith-idem : Idempotent _≡_ f → Idempotent _≡_ (zipWith f)zipWith-identityˡ : LeftIdentity _≡_ 1# f → LeftIdentity _≡_ (replicate 1#) (zipWith f)zipWith-identityʳ : RightIdentity _≡_ 1# f → RightIdentity _≡_ (replicate 1#) (zipWith f)zipWith-zeroˡ : LeftZero _≡_ 0# f → LeftZero _≡_ (replicate 0#) (zipWith f)zipWith-zeroʳ : RightZero _≡_ 0# f → RightZero _≡_ (replicate 0#) (zipWith f)zipWith-inverseˡ : LeftInverse _≡_ 0# ⁻¹ f → LeftInverse _≡_ (replicate 0#) (map ⁻¹) (zipWith f)zipWith-inverseʳ : RightInverse _≡_ 0# ⁻¹ f → RightInverse _≡_ (replicate 0#) (map ⁻¹) (zipWith f)zipWith-distribˡ : _DistributesOverˡ_ _≡_ f g → _DistributesOverˡ_ _≡_ (zipWith f) (zipWith g)zipWith-distribʳ : _DistributesOverʳ_ _≡_ f g → _DistributesOverʳ_ _≡_ (zipWith f) (zipWith g)zipWith-absorbs : _Absorbs_ _≡_ f g → _Absorbs_ _≡_ (zipWith f) (zipWith g)toList∘fromList : toList (fromList xs) ≡ xs```* Added new types to `Relation.Binary.Core`:```agdaP Respectsʳ _∼_ = ∀ {x} → (P x) Respects _∼_P Respectsˡ _∼_ = ∀ {y} → (flip P y) Respects _∼_```Records in `Relation.Binary` now export these in addition to the standard `Respects₂` proofs.e.g. `IsStrictPartialOrder` exports:```agda<-respˡ-≈ : _<_ Respectsˡ _≈_<-respʳ-≈ : _<_ Respectsʳ _≈_```* Added new proof to `IsStrictTotalOrder` and `StrictTotalOrder` in `Relation.Binary`:```agdaasym : Asymmetric _<_```* Added `_≡⟨_⟩_` combinator to `Relation.Binary.PreorderReasoning`.* Added new proofs to `Relation.Binary.NonStrictToStrict`:```agda<-respˡ-≈ : _≤_ Respectsˡ _≈_ → _<_ Respectsˡ _≈_<-respʳ-≈ : _≤_ Respectsʳ _≈_ → _<_ Respectsʳ _≈_<-≤-trans : Transitive _≤_ → Antisymmetric _≈_ _≤_ → _≤_ Respectsʳ _≈_ → Trans _<_ _≤_ _<_≤-<-trans : Transitive _≤_ → Antisymmetric _≈_ _≤_ → _≤_ Respectsˡ _≈_ → Trans _≤_ _<_ _<_```* Added new proofs to `Relation.Binary.Consequences`:```agdasubst⟶respˡ : Substitutive _∼_ p → P Respectsˡ _∼_subst⟶respʳ : Substitutive _∼_ p → P Respectsʳ _∼_trans∧tri⟶respʳ≈ : Transitive _<_ → Trichotomous _≈_ _<_ → _<_ Respectsʳ _≈_trans∧tri⟶respˡ≈ : Transitive _<_ → Trichotomous _≈_ _<_ → _<_ Respectsˡ _≈_```* Added new proof to `Relation.Binary.PropositionalEquality`:```agda≡-≟-identity : (eq : a ≡ b) → a ≟ b ≡ yes eq≢-≟-identity : a ≢ b → ∃ λ ¬eq → a ≟ b ≡ no ¬eq```* The types `Maximum` and `Minimum` are now exported by `Relation.Binary` as wellas `Relation.Binary.Lattice`.* Added new proofs to `Relation.Unary.Properties`:```agda⊆-refl : Reflexive _⊆_⊆-trans : Transitive _⊆_⊂-asym : Asymmetric _⊂__∪?_ : Decidable P → Decidable Q → Decidable (P ∪ Q)_∩?_ : Decidable P → Decidable Q → Decidable (P ∩ Q)_×?_ : Decidable P → Decidable Q → Decidable (P ⟨×⟩ Q)_⊙?_ : Decidable P → Decidable Q → Decidable (P ⟨⊙⟩ Q)_⊎?_ : Decidable P → Decidable Q → Decidable (P ⟨⊎⟩ Q)_~? : Decidable P → Decidable (P ~)```* Added indexed variants of functions to `Relation.Binary.HeterogeneousEquality`:```agdaicong : i ≡ j → (f : {k : I} → (z : A k) → B z) →x ≅ y → f x ≅ f yicong₂ : i ≡ j → (f : {k : I} → (z : A k) → (w : B z) → C z w) →x ≅ y → u ≅ v → f x u ≅ f y vicong-subst-removable : (eq : i ≅ j) (f : {k : I} → (z : A k) → B z) (x : A i) →f (subst A eq x) ≅ f xicong-≡-subst-removable : (eq : i ≡ j) (f : {k : I} → (z : A k) → B z) (x : A i) →f (P.subst A eq x) ≅ f x```
Version 0.15============The library has been tested using Agda version 2.5.3.Non-backwards compatible changes--------------------------------#### Upgrade and overhaul of organisation of relations over data* Relations over data have been moved from the `Relation` subtree to the `Data`subtree. This increases the usability of the library by:1. keeping all the definitions concerning a given datatype in the same directory2. providing a location to reason about how operations on the data affect therelations (e.g. how `Pointwise` is affected by `map`)3. increasing the discoverability of the relations. There is anecdotal evidence that manyusers were not aware of the existence of the relations in the old location.In general the files have been moved from `Relation.Binary.X` to`Data.X.Relation`. The full list of moves is as follows:````Relation.Binary.List.Pointwise` ↦ `Data.List.Relation.Pointwise``Relation.Binary.List.StrictLex` ↦ `Data.List.Relation.Lex.Strict``Relation.Binary.List.NonStrictLex` ↦ `Data.List.Relation.Lex.NonStrict``Relation.Binary.Sum` ↦ `Data.Sum.Relation.Pointwise`↘ `Data.Sum.Relation.LeftOrder``Relation.Binary.Sigma.Pointwise` ↦ `Data.Product.Relation.Pointwise.Dependent'`Relation.Binary.Product.Pointwise` ↦ `Data.Product.Relation.Pointwise.NonDependent``Relation.Binary.Product.StrictLex` ↦ `Data.Product.Relation.Lex.Strict``Relation.Binary.Product.NonStrictLex` ↦ `Data.Product.Relation.Lex.NonStrict``Relation.Binary.Vec.Pointwise` ↦ `Data.Vec.Relation.Pointwise.Inductive`↘ `Data.Vec.Relation.Pointwise.Extensional````The old files in `Relation.Binary.X` still exist for backwards compatability reasons andre-export the contents of files' new location in `Data.X.Relation` but may be removed in somefuture release.* The contents of `Relation.Binary.Sum` has been split into two modules`Data.Sum.Relation.Pointwise` and `Data.Sum.Relation.LeftOrder`* The contents of `Relation.Binary.Vec.Pointwise` has been split into two modules`Data.Vec.Relation.Pointwise.Inductive` and `Data.Vec.Relation.Pointwise.Extensional`.The inductive form of `Pointwise` has been generalised so that technically it can apply to twovectors with different lengths (although in practice the lengths must turn out to be equal). Thisallows a much wider range of proofs such as the fact that `[]` is a right identity for `_++_`which previously did not type check using the old definition. In order to ensurecompatability with the `--without-K` option, the universe level of `Inductive.Pointwise`has been increased from `ℓ` to `a ⊔ b ⊔ ℓ`.* `Data.Vec.Equality` has been almost entirely reworked into four separate modulesinside `Data.Vec.Relation.Equality` (namely `Setoid`, `DecSetoid`, `Propositional`and `DecPropositional`). All four of them now use `Data.Vec.Relation.Pointwise.Inductive`as a base.The proofs from the submodule `UsingVecEquality` in `Data.Vec.Properties` have been movedto these four new modules.* The datatype `All₂` has been removed from `Data.Vec.All`, along with associated proofsas it duplicates existing functionality in `Data.Vec.Relation.Pointwise.Inductive`.Unfortunately it is not possible to maintain backwards compatability due to dependencycycles.* Added new modules`Data.List.Relation.Equality.(Setoid/DecSetoid/Propositional/DecPropositional)`.#### Upgrade of `Data.AVL`* `Data.AVL.Key` and `Data.AVL.Height` have been split out of `Data.AVL`therefore ensuring they are independent on the type of `Value` the tree contains.* `Indexed` has been put into its own core module `Data.AVL.Indexed`, following theexample of `Category.Monad.Indexed` and `Data.Container.Indexed`.* These changes allow `map` to have a polymorphic type and so it is now possibleto change the type of values contained in a tree when mapping over it.#### Upgrade of `Algebra.Morphism`* Previously `Algebra.Morphism` only provides an example of a `Ring` homomorphism whichpacks the homomorphism and the proofs that it behaves the right way.Instead we have adopted and `Algebra.Structures`-like approach with proof-onlyrecords parametrised by the homomorphism and the structures it acts on. This makeit possible to define the proof requirement for e.g. a ring in terms of the proofrequirements for its additive abelian group and multiplicative monoid.#### Upgrade of `filter` and `partition` in `Data.List`* The functions `filter` and `partition` in `Data.List.Base` now use decidablepredicates instead of boolean-valued functions. The boolean versions discardedtype information, and hence were difficult to use and proveproperties about. The proofs have been updated and renamed accordingly.The old boolean versions still exist as `boolFilter` and `boolPartition` forbackwards compatibility reasons, but are deprecated and may be removed in somefuture release. The old versions can be implemented via the new versionsby passing the decidability proof `λ v → f v ≟ true` with `_≟_` from `Data.Bool`.#### Overhaul of categorical interpretations of List and Vec* New modules `Data.List.Categorical` and `Data.Vec.Categorical` have been addedfor the categorical interpretations of `List` and `Vec`.The following have been moved to `Data.List.Categorical`:- The module `Monad` from `Data.List.Properties` (renamed to `MonadProperties`)- The module `Applicative` from `Data.List.Properties`- `monad`, `monadZero`, `monadPlus` and monadic operators from `Data.List`The following has been moved to `Data.Vec.Categorical`:- `applicative` and `functor` from `Data.Vec`- `lookup-morphism` and `lookup-functor-morphism` from `Data.Vec.Properties`#### Other* Removed support for GHC 7.8.4.* Renamed `Data.Container.FreeMonad.do` and `Data.Container.Indexed.FreeMonad.do`to `inn` as Agda 2.5.4 now supports proper 'do' notation.* Changed the fixity of `⋃` and `⋂` in `Relation.Unary` to make space for `_⊢_`.* Changed `_|_` from `Data.Nat.Divisibility` from data to a record. Consequently,the two parameters are no longer implicit arguments of the constructor (butsuch values can be destructed using a let-binding rather than a with-clause).* Names in `Data.Nat.Divisibility` now use the `divides` symbol (typed \\|) consistently.Previously a mixture of \\| and | was used.* Moved the proof `eq?` from `Data.Nat` to `Data.Nat.Properties`* The proofs that were called `+-monoˡ-<` and `+-monoʳ-<` in `Data.Nat.Properties`have been renamed `+-mono-<-≤` and `+-mono-≤-<` respectively. The originalnames are now used for proofs of left and right monotonicity of `_+_`.* Moved the proof `monoid` from `Data.List` to `++-monoid` in `Data.List.Properties`.* Names in Data.Nat.Divisibility now use the `divides` symbol (typed \\|) consistently.Previously a mixture of \\| and | was used.* Starting from Agda 2.5.4 the GHC backend compiles `Coinduction.∞` ina different way, and for this reason the GHC backend pragmas for`Data.Colist.Colist` and `Data.Stream.Stream` have been modified.Deprecated features-------------------The following renaming has occurred as part of a drive to improve consistency acrossthe library. The old names still exist and therefore all existing code should stillwork, however they have been deprecated and use of the new names is encouraged. Although notanticipated any time soon, they may eventually be removed in some future release of the library.* In `Data.Bool.Properties`:```agda∧-∨-distˡ ↦ ∧-distribˡ-∨∧-∨-distʳ ↦ ∧-distribʳ-∨distrib-∧-∨ ↦ ∧-distrib-∨∨-∧-distˡ ↦ ∨-distribˡ-∧∨-∧-distʳ ↦ ∨-distribʳ-∧∨-∧-distrib ↦ ∨-distrib-∧∨-∧-abs ↦ ∨-abs-∧∧-∨-abs ↦ ∧-abs-∨not-∧-inverseˡ ↦ ∧-inverseˡnot-∧-inverseʳ ↦ ∧-inverseʳnot-∧-inverse ↦ ∧-inversenot-∨-inverseˡ ↦ ∨-inverseˡnot-∨-inverseʳ ↦ ∨-inverseʳnot-∨-inverse ↦ ∨-inverseisCommutativeSemiring-∨-∧ ↦ ∨-∧-isCommutativeSemiringcommutativeSemiring-∨-∧ ↦ ∨-∧-commutativeSemiringisCommutativeSemiring-∧-∨ ↦ ∧-∨-isCommutativeSemiringcommutativeSemiring-∧-∨ ↦ ∧-∨-commutativeSemiringisBooleanAlgebra ↦ ∨-∧-isBooleanAlgebrabooleanAlgebra ↦ ∨-∧-booleanAlgebracommutativeRing-xor-∧ ↦ xor-∧-commutativeRingproof-irrelevance ↦ T-irrelevance```* In `Data.Fin.Properties`:```agdacmp ↦ <-cmpstrictTotalOrder ↦ <-strictTotalOrder```* In `Data.Integer.Properties`:```agdainverseˡ ↦ +-inverseˡinverseʳ ↦ +-inverseʳdistribʳ ↦ *-distribʳ-+isCommutativeSemiring ↦ +-*-isCommutativeSemiringcommutativeRing ↦ +-*-commutativeRing*-+-right-mono ↦ *-monoʳ-≤-poscancel-*-+-right-≤ ↦ *-cancelʳ-≤-poscancel-*-right ↦ *-cancelʳ-≡doubleNeg ↦ neg-involutive-‿involutive ↦ neg-involutive+-⊖-left-cancel ↦ +-cancelˡ-⊖```* In `Data.List.Base`:```agdagfilter ↦ mapMaybe```* In `Data.List.Properties`:```agdaright-identity-unique ↦ ++-identityʳ-uniqueleft-identity-unique ↦ ++-identityˡ-unique```* In `Data.List.Relation.Pointwise`:```agdaRel ↦ PointwiseRel≡⇒≡ ↦ Pointwise-≡⇒≡≡⇒Rel≡ ↦ ≡⇒Pointwise-≡Rel↔≡ ↦ Pointwise-≡↔≡```* In `Data.Nat.Properties`:```agda¬i+1+j≤i ↦ i+1+j≰i≤-steps ↦ ≤-stepsˡ```* In all modules in the `Data.(Product/Sum).Relation` folders, all proofs withnames using infix notation have been deprecated in favour of identicalnon-infix names, e.g.```_×-isPreorder_ ↦ ×-isPreorder```* In `Data.Product.Relation.Lex.(Non)Strict`:```agda×-≈-respects₂ ↦ ×-respects₂```* In `Data.Product.Relation.Pointwise.Dependent`:```agdaRel ↦ PointwiseRel↔≡ ↦ Pointwise-≡↔≡```* In `Data.Product.Relation.Pointwise.NonDependent`:```agda_×-Rel_ ↦ PointwiseRel↔≡ ↦ Pointwise-≡↔≡_×-≈-respects₂_ ↦ ×-respects₂```* In `Data.Sign.Properties`:```agdaopposite-not-equal ↦ s≢opposite[s]opposite-cong ↦ opposite-injectivecancel-*-left ↦ *-cancelˡ-≡cancel-*-right ↦ *-cancelʳ-≡*-cancellative ↦ *-cancel-≡```* In `Data.Vec.Properties`:```agdaproof-irrelevance-[]= ↦ []=-irrelevance```* In `Data.Vec.Relation.Pointwise.Inductive`:```agdaPointwise-≡ ↦ Pointwise-≡↔≡```* In `Data.Vec.Relation.Pointwise.Extensional`:```agdaPointwise-≡ ↦ Pointwise-≡↔≡```* In `Induction.Nat`:```agdarec-builder ↦ recBuildercRec-builder ↦ cRecBuilder<′-rec-builder ↦ <′-recBuilder<-rec-builder ↦ <-recBuilder≺-rec-builder ↦ ≺-recBuilder<′-well-founded ↦ <′-wellFounded<′-well-founded′ ↦ <′-wellFounded′<-well-founded ↦ <-wellFounded≺-well-founded ↦ ≺-wellFounded```* In `Induction.WellFounded`:```agdaWell-founded ↦ WellFoundedSome.wfRec-builder ↦ Some.wfRecBuilderAll.wfRec-builder ↦ All.wfRecBuilderSubrelation.well-founded ↦ Subrelation.wellFoundedInverseImage.well-founded ↦ InverseImage.wellFoundedTransitiveClosure.downwards-closed ↦ TransitiveClosure.downwardsClosedTransitiveClosure.well-founded ↦ TransitiveClosure.wellFoundedLexicographic.well-founded ↦ Lexicographic.wellFounded```* In `Relation.Binary.PropositionalEquality`:```agdaproof-irrelevance ↦ ≡-irrelevance```Removed features----------------#### Deprecated in version 0.10* Modules `Deprecated-inspect` and `Deprecated-inspect-on-steroids` in `Relation.Binary.PropositionalEquality`.* Module `Deprecated-inspect-on-steroids` in `Relation.Binary.HeterogeneousEquality`.Backwards compatible changes----------------------------* Added support for GHC 8.2.2.* New module `Data.Word` for new builtin type `Agda.Builtin.Word.Word64`.* New modules `Data.Table`, `Data.Table.Base`,`Data.Table.Relation.Equality` and `Data.Table.Properties`. A `Table` is afixed-length collection of objects similar to a `Vec` from `Data.Vec`, butimplemented as a function `Fin n → A`. This prioritises ease of lookup as opposedto `Vec` which prioritises the ease of adding and removing elements.* The contents of the following modules are now more polymorphic with respect to levels:```agdaData.CovecData.List.Relation.Lex.StrictData.List.Relation.Lex.NonStrictData.Vec.PropertiesData.Vec.Relation.Pointwise.InductiveData.Vec.Relation.Pointwise.Extensional```* Added new proof to `asymmetric : Asymmetric _<_` to the `IsStrictPartialOrder` record.* Added new proofs to `Data.AVL`:```agdaleaf-injective : leaf p ≡ leaf q → p ≡ qnode-injective-key : node k₁ lk₁ ku₁ bal₁ ≡ node k₂ lk₂ ku₂ bal₂ → k₁ ≡ k₂node-injectiveˡ : node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → lk₁ ≡ lk₂node-injectiveʳ : node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → ku₁ ≡ ku₂node-injective-bal : node k lk₁ ku₁ bal₁ ≡ node k lk₂ ku₂ bal₂ → bal₁ ≡ bal₂```* Added new proofs to `Data.Bin`:```agdaless-injective : (b₁ < b₂ ∋ less lt₁) ≡ less lt₂ → lt₁ ≡ lt₂```* Added new proofs to `Data.Bool.Properties`:```agda∨-identityˡ : LeftIdentity false _∨_∨-identityʳ : RightIdentity false _∨_∨-identity : Identity false _∨_∨-zeroˡ : LeftZero true _∨_∨-zeroʳ : RightZero true _∨_∨-zero : Zero true _∨_∨-idem : Idempotent _∨_∨-sel : Selective _∨_∨-isSemigroup : IsSemigroup _≡_ _∨_∨-isCommutativeMonoid : IsCommutativeMonoid _≡_ _∨_ false∧-identityˡ : LeftIdentity true _∧_∧-identityʳ : RightIdentity true _∧_∧-identity : Identity true _∧_∧-zeroˡ : LeftZero false _∧_∧-zeroʳ : RightZero false _∧_∧-zero : Zero false _∧_∧-idem : Idempotent _∧_∧-sel : Selective _∧_∧-isSemigroup : IsSemigroup _≡_ _∧_∧-isCommutativeMonoid : IsCommutativeMonoid _≡_ _∧_ true∨-∧-isLattice : IsLattice _≡_ _∨_ _∧_∨-∧-isDistributiveLattice : IsDistributiveLattice _≡_ _∨_ _∧_```* Added missing bindings to functions on `Data.Char.Base`:```agdaisLower : Char → BoolisDigit : Char → BoolisAlpha : Char → BoolisSpace : Char → BoolisAscii : Char → BoolisLatin1 : Char → BoolisPrint : Char → BoolisHexDigit : Char → BooltoNat : Char → ℕfromNat : ℕ → Char```* Added new proofs to `Data.Cofin`:```agdasuc-injective : (Cofin (suc m) ∋ suc p) ≡ suc q → p ≡ q```* Added new proofs to `Data.Colist`:```agda∷-injectiveˡ : (Colist A ∋ x ∷ xs) ≡ y ∷ ys → x ≡ y∷-injectiveʳ : (Colist A ∋ x ∷ xs) ≡ y ∷ ys → xs ≡ yshere-injective : (Any P (x ∷ xs) ∋ here p) ≡ here q → p ≡ qthere-injective : (Any P (x ∷ xs) ∋ there p) ≡ there q → p ≡ q∷-injectiveˡ : (All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → px ≡ qx∷-injectiveʳ : (All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → pxs ≡ qxs∷-injective : (Finite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q∷-injective : (Infinite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q```* Added new operations and proofs to `Data.Conat`:```agdapred : Coℕ → Coℕsuc-injective : (Coℕ ∋ suc m) ≡ suc n → m ≡ nfromℕ-injective : fromℕ m ≡ fromℕ n → m ≡ nsuc-injective : (suc m ≈ suc n ∋ suc p) ≡ suc q → p ≡ q```* Added new proofs to `Data.Covec`:```agda∷-injectiveˡ : (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → a ≡ b∷-injectiveʳ : (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → as ≡ bs```* Added new proofs to `Data.Fin.Properties`:```agda≤-isDecTotalOrder : ∀ {n} → IsDecTotalOrder _≡_ (_≤_ {n})≤-irrelevance : ∀ {n} → IrrelevantRel (_≤_ {n})<-asym : ∀ {n} → Asymmetric (_<_ {n})<-irrefl : ∀ {n} → Irreflexive _≡_ (_<_ {n})<-irrelevance : ∀ {n} → IrrelevantRel (_<_ {n})```* Added new proofs to `Data.Integer.Properties`:```agda+-cancelˡ-⊖ : (a + b) ⊖ (a + c) ≡ b ⊖ cneg-minus-pos : -[1+ m ] - (+ n) ≡ -[1+ (m + n) ][+m]-[+n]≡m⊖n : (+ m) - (+ n) ≡ m ⊖ n∣m-n∣≡∣n-m∣ : ∣ m - n ∣ ≡ ∣ n - m ∣+-minus-telescope : (m - n) + (n - o) ≡ m - opos-distrib-* : ∀ x y → (+ x) * (+ y) ≡ + (x * y)≤-irrelevance : IrrelevantRel _≤_<-irrelevance : IrrelevantRel _<_```* Added new combinators to `Data.List.Base`:```agdalookup : (xs : List A) → Fin (length xs) → AunzipWith : (A → B × C) → List A → List B × List Cunzip : List (A × B) → List A × List B```* Added new proofs to `Data.List.Properties`:```agda∷-injectiveˡ : x ∷ xs ≡ y List.∷ ys → x ≡ y∷-injectiveʳ : x ∷ xs ≡ y List.∷ ys → xs ≡ ys∷ʳ-injectiveˡ : xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys∷ʳ-injectiveʳ : xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y++-assoc : Associative {A = List A} _≡_ _++_++-identityˡ : LeftIdentity _≡_ [] _++_++-identityʳ : RightIdentity _≡_ [] _++_++-identity : Identity _≡_ [] _++_++-isSemigroup : IsSemigroup {A = List A} _≡_ _++_++-isMonoid : IsMonoid {A = List A} _≡_ _++_ []++-semigroup : ∀ {a} (A : Set a) → Semigroup _ _++-monoid : ∀ {a} (A : Set a) → Monoid _ _filter-none : All P xs → dfilter P? xs ≡ xsfilter-some : Any (∁ P) xs → length (filter P? xs) < length xsfilter-notAll : Any P xs → 0 < length (filter P? xs)filter-all : All (∁ P) xs → dfilter P? xs ≡ []filter-complete : length (filter P? xs) ≡ length xs → filter P? xs ≡ xstabulate-cong : f ≗ g → tabulate f ≡ tabulate gtabulate-lookup : tabulate (lookup xs) ≡ xszipWith-identityˡ : ∀ xs → zipWith f [] xs ≡ []zipWith-identityʳ : ∀ xs → zipWith f xs [] ≡ []zipWith-comm : (∀ x y → f x y ≡ f y x) → zipWith f xs ys ≡ zipWith f ys xszipWith-unzipWith : uncurry′ g ∘ f ≗ id → uncurry′ (zipWith g) ∘ (unzipWith f) ≗ idzipWith-map : zipWith f (map g xs) (map h ys) ≡ zipWith (λ x y → f (g x) (h y)) xs ysmap-zipWith : map g (zipWith f xs ys) ≡ zipWith (λ x y → g (f x y)) xs yslength-zipWith : length (zipWith f xs ys) ≡ length xs ⊓ length yslength-unzipWith₁ : length (proj₁ (unzipWith f xys)) ≡ length xyslength-unzipWith₂ : length (proj₂ (unzipWith f xys)) ≡ length xys```* Added new proofs to `Data.List.All.Properties`:```agdaAll-irrelevance : IrrelevantPred P → IrrelevantPred (All P)filter⁺₁ : All P (filter P? xs)filter⁺₂ : All Q xs → All Q (filter P? xs)mapMaybe⁺ : All (Maybe.All P) (map f xs) → All P (mapMaybe f xs)zipWith⁺ : Pointwise (λ x y → P (f x y)) xs ys → All P (zipWith f xs ys)```* Added new proofs to `Data.List.Any.Properties`:```agdamapMaybe⁺ : Any (Maybe.Any P) (map f xs) → Any P (mapMaybe f xs)```* Added new proofs to `Data.List.Relation.Lex.NonStrict`:```agda<-antisymmetric : Symmetric _≈_ → Antisymmetric _≈_ _≼_ → Antisymmetric _≋_ _<_<-transitive : IsPartialOrder _≈_ _≼_ → Transitive _<_<-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ → _<_ Respects₂ _≋_≤-antisymmetric : Symmetric _≈_ → Antisymmetric _≈_ _≼_ → Antisymmetric _≋_ _≤_≤-transitive : IsPartialOrder _≈_ _≼_ → Transitive _≤_≤-resp₂ : IsEquivalence _≈_ → _≼_ Respects₂ _≈_ → _≤_ Respects₂ _≋_```* Added new proofs to `Data.List.Relation.Pointwise`:```agdatabulate⁺ : (∀ i → f i ∼ g i) → Pointwise _∼_ (tabulate f) (tabulate g)tabulate⁻ : Pointwise _∼_ (tabulate f) (tabulate g) → (∀ i → f i ∼ g i)++⁺ : Pointwise _∼_ ws xs → Pointwise _∼_ ys zs → Pointwise _∼_ (ws ++ ys) (xs ++ zs)concat⁺ : Pointwise (Pointwise _∼_) xss yss → Pointwise _∼_ (concat xss) (concat yss)```* Added new proofs to `Data.List.Relation.Lex.Strict`:```agda<-antisymmetric : Symmetric _≈_ → Irreflexive _≈_ _≺_ → Asymmetric _≺_ → Antisymmetric _≋_ _<_<-transitive : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ → Transitive _<_<-respects₂ : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → _<_ Respects₂ _≋_≤-antisymmetric : Symmetric _≈_ → Irreflexive _≈_ _≺_ → Asymmetric _≺_ → Antisymmetric _≋_ _≤_≤-transitive : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → Transitive _≺_ → Transitive _≤_≤-respects₂ : IsEquivalence _≈_ → _≺_ Respects₂ _≈_ → _≤_ Respects₂ _≋_```* Added new proofs to `Data.Maybe.Base`:```agdajust-injective : (Maybe A ∋ just a) ≡ just b → a ≡ b```* Added new proofs to `Data.Nat.Divisibility`:```agdam|m*n : m ∣ m * n∣m⇒∣m*n : i ∣ m → i ∣ m * n∣n⇒∣m*n : i ∣ n → i ∣ m * n```* Added new proofs to `Data.Nat.Properties`:```agda≤⇒≯ : _≤_ ⇒ _≯_n≮n : ∀ n → n ≮ n≤-stepsʳ : ∀ m ≤ n → m ≤ n + o≤-irrelevance : IrrelevantRel _≤_<-irrelevance : IrrelevantRel _<_+-monoˡ-≤ : ∀ n → (_+ n) Preserves _≤_ ⟶ _≤_+-monoʳ-≤ : ∀ n → (n +_) Preserves _≤_ ⟶ _≤_+-monoˡ-< : ∀ n → (_+ n) Preserves _<_ ⟶ _<_+-monoʳ-< : ∀ n → (n +_) Preserves _<_ ⟶ _<_+-semigroup : Semigroup _ _+-0-monoid : Monoid _ _+-0-commutativeMonoid : CommutativeMonoid _ _*-monoˡ-≤ : ∀ n → (_* n) Preserves _≤_ ⟶ _≤_*-monoʳ-≤ : ∀ n → (n *_) Preserves _≤_ ⟶ _≤_*-semigroup : Semigroup _ _*-1-monoid : Monoid _ _*-1-commutativeMonoid : CommutativeMonoid _ _*-+-semiring : Semiring _ _^-identityʳ : RightIdentity 1 _^_^-zeroˡ : LeftZero 1 _^_^-semigroup-morphism : (x ^_) Is +-semigroup -Semigroup⟶ *-semigroup^-monoid-morphism : (x ^_) Is +-0-monoid -Monoid⟶ *-1-monoidm≤n⇒m⊓n≡m : m ≤ n → m ⊓ n ≡ mm≤n⇒n⊓m≡m : m ≤ n → n ⊓ m ≡ mm≤n⇒n⊔m≡n : m ≤ n → n ⊔ m ≡ nm≤n⇒m⊔n≡n : m ≤ n → m ⊔ n ≡ n⊔-monoˡ-≤ : ∀ n → (_⊔ n) Preserves _≤_ ⟶ _≤_⊔-monoʳ-≤ : ∀ n → (n ⊔_) Preserves _≤_ ⟶ _≤_⊓-monoˡ-≤ : ∀ n → (_⊓ n) Preserves _≤_ ⟶ _≤_⊓-monoʳ-≤ : ∀ n → (n ⊓_) Preserves _≤_ ⟶ _≤_m∸n+n≡m : n ≤ m → (m ∸ n) + n ≡ mm∸[m∸n]≡n : n ≤ m → m ∸ (m ∸ n) ≡ ns≤s-injective : s≤s p ≡ s≤s q → p ≡ q≤′-step-injective : ≤′-step p ≡ ≤′-step q → p ≡ q```* Added new proofs to `Data.Plus`:```agda[]-injective : (x [ _∼_ ]⁺ y ∋ [ p ]) ≡ [ q ] → p ≡ q∼⁺⟨⟩-injectiveˡ : (x [ _∼_ ]⁺ z ∋ x ∼⁺⟨ p ⟩ q) ≡ (x ∼⁺⟨ r ⟩ s) → p ≡ r∼⁺⟨⟩-injectiveʳ : (x [ _∼_ ]⁺ z ∋ x ∼⁺⟨ p ⟩ q) ≡ (x ∼⁺⟨ r ⟩ s) → q ≡ s```* Added new combinator to `Data.Product`:```agdacurry′ : (A × B → C) → (A → B → C)```* Added new proofs to `Data.Product.Properties`:```agda,-injectiveˡ : (a , b) ≡ (c , d) → a ≡ c,-injectiveʳ : (Σ A B ∋ (a , b)) ≡ (a , c) → b ≡ c```* Added new operator in `Data.Product.Relation.Pointwise.NonDependent`:```agda_×ₛ_ : Setoid ℓ₁ ℓ₂ → Setoid ℓ₃ ℓ₄ → Setoid _ _```* Added new proofs to `Data.Rational.Properties`:```agda≤-irrelevance : IrrelevantRel _≤_```* Added new proofs to `Data.ReflexiveClosure`:```agda[]-injective : (Refl _∼_ x y ∋ [ p ]) ≡ [ q ] → p ≡ q```* Added new proofs to `Data.Sign`:```agda*-isSemigroup : IsSemigroup _≡_ _*_*-semigroup : Semigroup _ _*-isMonoid : IsMonoid _≡_ _*_ +*-monoid : Monoid _ _```* Added new proofs to `Data.Star.Properties`:```agda◅-injectiveˡ : (Star T i k ∋ x ◅ xs) ≡ y ◅ ys → x ≡ y◅-injectiveʳ : (Star T i k ∋ x ◅ xs) ≡ y ◅ ys → xs ≡ ys```* Added new proofs to `Data.Sum.Properties`:```agdainj₁-injective : (A ⊎ B ∋ inj₁ x) ≡ inj₁ y → x ≡ yinj₂-injective : (A ⊎ B ∋ inj₂ x) ≡ inj₂ y → x ≡ y```* Added new operator in `Data.Sum.Relation.Pointwise`:```agda_⊎ₛ_ : Setoid ℓ₁ ℓ₂ → Setoid ℓ₃ ℓ₄ → Setoid _ _```* Added new proofs to `Data.Vec.Properties`:```agda∷-injectiveˡ : x ∷ xs ≡ y ∷ ys → x ≡ y∷-injectiveʳ : x ∷ xs ≡ y ∷ ys → xs ≡ ys[]=⇒lookup : xs [ i ]= x → lookup i xs ≡ xlookup⇒[]= : lookup i xs ≡ x → xs [ i ]= xlookup-replicate : lookup i (replicate x) ≡ xlookup-⊛ : lookup i (fs ⊛ xs) ≡ (lookup i fs $ lookup i xs)tabulate-cong : f ≗ g → tabulate f ≡ tabulate g```* Added new proofs to `Data.Vec.All.Properties````agdaAll-irrelevance : IrrelevantPred P → ∀ {n} → IrrelevantPred (All P {n})```* Added new proofs to `Data.Vec.Relation.Pointwise.Extensional`:```agdaisDecEquivalence : IsDecEquivalence _~_ → IsDecEquivalence (Pointwise _~_)extensional⇒inductive : Pointwise _~_ xs ys → IPointwise _~_ xs ysinductive⇒extensional : IPointwise _~_ xs ys → Pointwise _~_ xs ys≡⇒Pointwise-≡ : Pointwise _≡_ xs ys → xs ≡ ysPointwise-≡⇒≡ : xs ≡ ys → Pointwise _≡_ xs ys```* Added new proofs to `Data.Vec.Relation.Pointwise.Inductive`:```agda++⁺ : Pointwise P xs → Pointwise P ys → Pointwise P (xs ++ ys)++⁻ˡ : Pointwise P (xs ++ ys) → Pointwise P xs++⁻ʳ : Pointwise P (xs ++ ys) → Pointwise P ys++⁻ : Pointwise P (xs ++ ys) → Pointwise P xs × Pointwise P ysconcat⁺ : Pointwise (Pointwise P) xss → Pointwise P (concat xss)concat⁻ : Pointwise P (concat xss) → Pointwise (Pointwise P) xsslookup : Pointwise _~_ xs ys → ∀ i → lookup i xs ~ lookup i ysisDecEquivalence : IsDecEquivalence _~_ → IsDecEquivalence (Pointwise _~_)≡⇒Pointwise-≡ : Pointwise _≡_ xs ys → xs ≡ ysPointwise-≡⇒≡ : xs ≡ ys → Pointwise _≡_ xs ysPointwiseˡ⇒All : Pointwise (λ x y → P x) xs ys → All P xsPointwiseʳ⇒All : Pointwise (λ x y → P y) xs ys → All P ysAll⇒Pointwiseˡ : All P xs → Pointwise (λ x y → P x) xs ysAll⇒Pointwiseʳ : All P ys → Pointwise (λ x y → P y) xs ys```* Added new functions and proofs to `Data.W`:```agdamap : (f : A → C) → ∀[ D ∘ f ⇒ B ] → W A B → W C Dinduction : (∀ a {f} (hf : ∀ (b : B a) → P (f b)) → (w : W A B) → P wfoldr : (∀ a → (B a → P) → P) → W A B → Psup-injective₁ : sup x f ≡ sup y g → x ≡ ysup-injective₂ : sup x f ≡ sup x g → f ≡ g```* Added new properties to `Relation.Binary.PropositionalEquality````agdaisPropositional A = (a b : A) → a ≡ bIrrelevantPred P = ∀ {x} → isPropositional (P x)IrrelevantRel _~_ = ∀ {x y} → isPropositional (x ~ y)```* Added new combinator to ` Relation.Binary.PropositionalEquality.TrustMe`:```agdapostulate[_↦_] : (t : A) → B t → (x : A) → B x```* Added new proofs to `Relation.Binary.StrictToNonStrict`:```agdaisPreorder₁ : IsPreorder _≈_ _<_ → IsPreorder _≈_ _≤_isPreorder₂ : IsStrictPartialOrder _≈_ _<_ → IsPreorder _≈_ _≤_isPartialOrder : IsStrictPartialOrder _≈_ _<_ → IsPartialOrder _≈_ _≤_isTotalOrder : IsStrictTotalOrder _≈_ _<_ → IsTotalOrder _≈_ _≤_isDecTotalOrder : IsStrictTotalOrder _≈_ _<_ → IsDecTotalOrder _≈_ _≤_```* Added new syntax, relations and proofs to `Relation.Unary`:```agdasyntax Universal P = ∀[ P ]P ⊈ Q = ¬ (P ⊆ Q)P ⊉ Q = ¬ (P ⊇ Q)P ⊂ Q = P ⊆ Q × Q ⊈ PP ⊃ Q = Q ⊂ PP ⊄ Q = ¬ (P ⊂ Q)P ⊅ Q = ¬ (P ⊃ Q)P ⊈′ Q = ¬ (P ⊆′ Q)P ⊉′ Q = ¬ (P ⊇′ Q)P ⊂′ Q = P ⊆′ Q × Q ⊈′ PP ⊃′ Q = Q ⊂′ PP ⊄′ Q = ¬ (P ⊂′ Q)P ⊅′ Q = ¬ (P ⊃′ Q)f ⊢ P = λ x → P (f x)∁? : Decidable P → Decidable (∁ P)```* Added `recompute` to `Relation.Nullary`:```agdarecompute : ∀ {a} {A : Set a} → Dec A → .A → A```
Version 0.14============The library has been tested using Agda version 2.5.3.Non-backwards compatible changes--------------------------------#### 1st stage of overhaul of list membership* The current setup for list membership is difficult to work with as both setoid membershipand propositional membership exist as internal modules of `Data.Any`. Furthermore thetop-level module `Data.List.Any.Membership` actually contains properties of propositionalmembership rather than the membership relation itself as its name would suggest.Consequently this leaves no place to reason about the properties of setoid membership.Therefore the two internal modules `Membership` and `Membership-≡` have been moved outof `Data.List.Any` into top-level `Data.List.Any.Membership` and`Data.List.Any.Membership.Propositional` respectively. The previous module`Data.List.Any.Membership` has been renamed`Data.List.Any.Membership.Propositional.Properties`.Accordingly some lemmas have been moved to more logical locations:- `lift-resp` has been moved from `Data.List.Any.Membership` to `Data.List.Any.Properties`- `∈-resp-≈`, `⊆-preorder` and `⊆-Reasoning` have been moved from `Data.List.Any.Membership`to `Data.List.Any.Membership.Properties`.- `∈-resp-list-≈` has been moved from `Data.List.Any.Membership` to`Data.List.Any.Membership.Properties` and renamed `∈-resp-≋`.- `swap` in `Data.List.Any.Properties` has been renamed `swap↔` and made more generic withrespect to levels.#### Moving `decTotalOrder` and `decSetoid` from `Data.X` to `Data.X.Properties`* Currently the library does not directly expose proofs of basic properties such as reflexivity,transitivity etc. for `_≤_` in numeric datatypes such as `Nat`, `Integer` etc. In order to use theseproperties it was necessary to first import the `decTotalOrder` proof from `Data.X` and thenseparately open it, often having to rename the proofs as well. This adds unneccessary lines ofcode to the import statements for what are very commonly used properties.These basic proofs have now been added in `Data.X.Properties` along with proofs that they formpre-orders, partial orders and total orders. This should make them considerably easier to work withand simplify files' import preambles. However consequently the records `decTotalOrder` and`decSetoid` have been moved from `Data.X` to `≤-decTotalOrder` and `≡-decSetoid` in`Data.X.Properties`.The numeric datatypes for which this has been done are `Nat`, `Integer`, `Rational` and `Bin`.As a consequence the module `≤-Reasoning` has also had to have been moved from `Data.Nat` to`Data.Nat.Properties`.#### New well-founded induction proofs for `Data.Nat`* Currently `Induction.Nat` only proves that the non-standard `_<′_`relation over `ℕ` iswell-founded. Unfortunately these existing proofs are named `<-Rec` and `<-well-founded`which clash with the sensible names for new proofs over the standard `_<_` relation.Therefore `<-Rec` and `<-well-founded` have been renamed to `<′-Rec` and `<′-well-founded`respectively. The original names `<-Rec` and `<-well-founded` now refer to newcorresponding proofs for `_<_`.#### Other* Changed the implementation of `map` and `zipWith` in `Data.Vec` to use native(pattern-matching) definitions. Previously they were defined using the`applicative` operations of `Vec`. The new definitions can be converted backto the old using the new proofs `⊛-is-zipWith`, `map-is-⊛` and `zipWith-is-⊛`in `Data.Vec.Properties`. It has been argued that `zipWith` is fundamental than `_⊛_`and this change allows better printing of goals involving `map` or `zipWith`.* Changed the implementation of `All₂` in `Data.Vec.All` to a native datatype. Thisimproved improves pattern matching on terms and allows the new datatype to be moregeneric with respect to types and levels.* Changed the implementation of `downFrom` in `Data.List` to a native(pattern-matching) definition. Previously it was defined using a privateinternal module which made pattern matching difficult.* The arguments of `≤pred⇒≤` and `≤⇒pred≤` in `Data.Nat.Properties` are now implicitrather than explicit (was `∀ m n → m ≤ pred n → m ≤ n` and is now`∀ {m n} → m ≤ pred n → m ≤ n`). This makes it consistent with `<⇒≤pred` whichalready used implicit arguments, and shouldn't introduce any significant problemsas both parameters can be inferred by Agda.* Moved `¬∀⟶∃¬` from `Relation.Nullary.Negation` to `Data.Fin.Dec`. Its oldlocation was causing dependency cyles to form between `Data.Fin.Dec`,`Relation.Nullary.Negation` and `Data.Fin`.* Moved `fold`, `add` and `mul` from `Data.Nat` to new module `Data.Nat.GeneralisedArithmetic`.* Changed type of second parameter of `Relation.Binary.StrictPartialOrderReasoning._<⟨_⟩_`from `x < y ⊎ x ≈ y` to `x < y`. `_≈⟨_⟩_` is left unchanged to take a value with type `x ≈ y`.Old code may be fixed by prefixing the contents of `_<⟨_⟩_` with `inj₁`.Deprecated features-------------------Deprecated features still exist and therefore existing code should still workbut they may be removed in some future release of the library.* The module `Data.Nat.Properties.Simple` is now deprecated. All proofshave been moved to `Data.Nat.Properties` where they should be used directly.The `Simple` file still exists for backwards compatability reasons andre-exports the proofs from `Data.Nat.Properties` but will be removed in somefuture release.* The modules `Data.Integer.Addition.Properties` and`Data.Integer.Multiplication.Properties` are now deprecated. All proofshave been moved to `Data.Integer.Properties` where they should be useddirectly. The `Addition.Properties` and `Multiplication.Properties` filesstill exist for backwards compatability reasons and re-exports the proofs from`Data.Integer.Properties` but will be removed in some future release.* The following renaming has occured in `Data.Nat.Properties````agda_+-mono_ ↦ +-mono-≤_*-mono_ ↦ *-mono-≤+-right-identity ↦ +-identityʳ*-right-zero ↦ *-zeroʳdistribʳ-*-+ ↦ *-distribʳ-+*-distrib-∸ʳ ↦ *-distribʳ-∸cancel-+-left ↦ +-cancelˡ-≡cancel-+-left-≤ ↦ +-cancelˡ-≤cancel-*-right ↦ *-cancelʳ-≡cancel-*-right-≤ ↦ *-cancelʳ-≤strictTotalOrder ↦ <-strictTotalOrderisCommutativeSemiring ↦ *-+-isCommutativeSemiringcommutativeSemiring ↦ *-+-commutativeSemiringisDistributiveLattice ↦ ⊓-⊔-isDistributiveLatticedistributiveLattice ↦ ⊓-⊔-distributiveLattice⊔-⊓-0-isSemiringWithoutOne ↦ ⊔-⊓-isSemiringWithoutOne⊔-⊓-0-isCommutativeSemiringWithoutOne ↦ ⊔-⊓-isCommutativeSemiringWithoutOne⊔-⊓-0-commutativeSemiringWithoutOne ↦ ⊔-⊓-commutativeSemiringWithoutOne```* The following renaming has occurred in `Data.Nat.Divisibility`:```agda∣-* ↦ n|m*n∣-+ ↦ ∣m∣n⇒∣m+n∣-∸ ↦ ∣m+n|m⇒|n```Backwards compatible changes----------------------------* Added support for GHC 8.0.2 and 8.2.1.* Removed the empty `Irrelevance` module* Added `Category.Functor.Morphism` and module `Category.Functor.Identity`.* `Data.Container` and `Data.Container.Indexed` now allow for differentlevels in the container and in the data it contains.* Made `Data.BoundedVec` polymorphic with respect to levels.* Access to `primForce` and `primForceLemma` has been provided via the newtop-level module `Strict`.* New call-by-value application combinator `_$!_` in `Function`.* Added properties to `Algebra.FunctionProperties`:```agdaLeftCancellative _•_ = ∀ x {y z} → (x • y) ≈ (x • z) → y ≈ zRightCancellative _•_ = ∀ {x} y z → (y • x) ≈ (z • x) → y ≈ zCancellative _•_ = LeftCancellative _•_ × RightCancellative _•_```* Added new module `Algebra.FunctionProperties.Consequences` for basic causal relationships betweenproperties, containing:```agdacomm+idˡ⇒idʳ : Commutative _•_ → LeftIdentity e _•_ → RightIdentity e _•_comm+idʳ⇒idˡ : Commutative _•_ → RightIdentity e _•_ → LeftIdentity e _•_comm+zeˡ⇒zeʳ : Commutative _•_ → LeftZero e _•_ → RightZero e _•_comm+zeʳ⇒zeˡ : Commutative _•_ → RightZero e _•_ → LeftZero e _•_comm+invˡ⇒invʳ : Commutative _•_ → LeftInverse e _⁻¹ _•_ → RightInverse e _⁻¹ _•_comm+invʳ⇒invˡ : Commutative _•_ → RightInverse e _⁻¹ _•_ → LeftInverse e _⁻¹ _•_comm+distrˡ⇒distrʳ : Commutative _•_ → _•_ DistributesOverˡ _◦_ → _•_ DistributesOverʳ _◦_comm+distrʳ⇒distrˡ : Commutative _•_ → _•_ DistributesOverʳ _◦_ → _•_ DistributesOverˡ _◦_comm+cancelˡ⇒cancelʳ : Commutative _•_ → LeftCancellative _•_ → RightCancellative _•_comm+cancelˡ⇒cancelʳ : Commutative _•_ → LeftCancellative _•_ → RightCancellative _•_sel⇒idem : Selective _•_ → Idempotent _•_```* Added proofs to `Algebra.Properties.BooleanAlgebra`:```agda∨-complementˡ : LeftInverse ⊤ ¬_ _∨_∧-complementˡ : LeftInverse ⊥ ¬_ _∧_∧-identityʳ : RightIdentity ⊤ _∧_∧-identityˡ : LeftIdentity ⊤ _∧_∧-identity : Identity ⊤ _∧_∨-identityʳ : RightIdentity ⊥ _∨_∨-identityˡ : LeftIdentity ⊥ _∨_∨-identity : Identity ⊥ _∨_∧-zeroʳ : RightZero ⊥ _∧_∧-zeroˡ : LeftZero ⊥ _∧_∧-zero : Zero ⊥ _∧_∨-zeroʳ : RightZero ⊤ _∨_∨-zeroˡ : LeftZero ⊤ _∨_∨-zero : Zero ⊤ _∨_⊕-identityˡ : LeftIdentity ⊥ _⊕_⊕-identityʳ : RightIdentity ⊥ _⊕_⊕-identity : Identity ⊥ _⊕_⊕-inverseˡ : LeftInverse ⊥ id _⊕_⊕-inverseʳ : RightInverse ⊥ id _⊕_⊕-inverse : Inverse ⊥ id _⊕_⊕-cong : Congruent₂ _⊕_⊕-comm : Commutative _⊕_⊕-assoc : Associative _⊕_∧-distribˡ-⊕ : _∧_ DistributesOverˡ _⊕_∧-distribʳ-⊕ : _∧_ DistributesOverʳ _⊕_∧-distrib-⊕ : _∧_ DistributesOver _⊕_∨-isSemigroup : IsSemigroup _≈_ _∨_∧-isSemigroup : IsSemigroup _≈_ _∧_∨-⊥-isMonoid : IsMonoid _≈_ _∨_ ⊥∧-⊤-isMonoid : IsMonoid _≈_ _∧_ ⊤∨-⊥-isCommutativeMonoid : IsCommutativeMonoid _≈_ _∨_ ⊥∧-⊤-isCommutativeMonoid : IsCommutativeMonoid _≈_ _∧_ ⊤⊕-isSemigroup : IsSemigroup _≈_ _⊕_⊕-⊥-isMonoid : IsMonoid _≈_ _⊕_ ⊥⊕-⊥-isGroup : IsGroup _≈_ _⊕_ ⊥ id⊕-⊥-isAbelianGroup : IsAbelianGroup _≈_ _⊕_ ⊥ id⊕-∧-isRing : IsRing _≈_ _⊕_ _∧_ id ⊥ ⊤```* Added proofs to `Algebra.Properties.DistributiveLattice`:```agda∨-∧-distribˡ : _∨_ DistributesOverˡ _∧_∧-∨-distribˡ : _∧_ DistributesOverˡ _∨_∧-∨-distribʳ : _∧_ DistributesOverʳ _∨_```* Added pattern synonyms to `Data.Bin` to improve readability:```agdapattern 0b = zeropattern 1b = 1+ zeropattern ⊥b = 1+ 1+ ()```* A new module `Data.Bin.Properties` has been added, containing proofs:```agda1#-injective : as 1# ≡ bs 1# → as ≡ bs_≟_ : Decidable {A = Bin} _≡_≡-isDecEquivalence : IsDecEquivalence _≡_≡-decSetoid : DecSetoid _ _<-trans : Transitive _<_<-asym : Asymmetric _<_<-irrefl : Irreflexive _≡_ _<_<-cmp : Trichotomous _≡_ _<_<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<⇒≢ : a < b → a ≢ b1<[23] : [] 1# < (b ∷ []) 1#1<2+ : [] 1# < (b ∷ bs) 1#0<1+ : 0# < bs 1#```* Added functions to `Data.BoundedVec`:```agdatoInefficient : BoundedVec A n → Ineff.BoundedVec A nfromInefficient : Ineff.BoundedVec A n → BoundedVec A n```* Added the following to `Data.Digit`:```agdaExpansion : ℕ → SetExpansion base = List (Fin base)```* Added new module `Data.Empty.Irrelevant` containing an irrelevant version of `⊥-elim`.* Added functions to `Data.Fin`:```agdapunchIn i j ≈ if j≥i then j+1 else jpunchOut i j ≈ if j>i then j-1 else j```* Added proofs to `Data.Fin.Properties`:```agdaisDecEquivalence : ∀ {n} → IsDecEquivalence (_≡_ {A = Fin n})≤-reflexive : ∀ {n} → _≡_ ⇒ (_≤_ {n})≤-refl : ∀ {n} → Reflexive (_≤_ {n})≤-trans : ∀ {n} → Transitive (_≤_ {n})≤-antisymmetric : ∀ {n} → Antisymmetric _≡_ (_≤_ {n})≤-total : ∀ {n} → Total (_≤_ {n})≤-isPreorder : ∀ {n} → IsPreorder _≡_ (_≤_ {n})≤-isPartialOrder : ∀ {n} → IsPartialOrder _≡_ (_≤_ {n})≤-isTotalOrder : ∀ {n} → IsTotalOrder _≡_ (_≤_ {n})_<?_ : ∀ {n} → Decidable (_<_ {n})<-trans : ∀ {n} → Transitive (_<_ {n})<-isStrictTotalOrder : ∀ {n} → IsStrictTotalOrder _≡_ (_<_ {n})punchOut-injective : punchOut i≢j ≡ punchOut i≢k → j ≡ kpunchIn-injective : punchIn i j ≡ punchIn i k → j ≡ kpunchIn-punchOut : punchIn i (punchOut i≢j) ≡ jpunchInᵢ≢i : punchIn i j ≢ i```* Added proofs to `Data.Fin.Subset.Properties`:```agdax∈⁅x⁆ : x ∈ ⁅ x ⁆x∈⁅y⁆⇒x≡y : x ∈ ⁅ y ⁆ → x ≡ y∪-assoc : Associative _≡_ _∪_∩-assoc : Associative _≡_ _∩_∪-comm : Commutative _≡_ _∪_∩-comm : Commutative _≡_ _∩_p⊆p∪q : p ⊆ p ∪ qq⊆p∪q : q ⊆ p ∪ qx∈p∪q⁻ : x ∈ p ∪ q → x ∈ p ⊎ x ∈ qx∈p∪q⁺ : x ∈ p ⊎ x ∈ q → x ∈ p ∪ qp∩q⊆p : p ∩ q ⊆ pp∩q⊆q : p ∩ q ⊆ qx∈p∩q⁺ : x ∈ p × x ∈ q → x ∈ p ∩ qx∈p∩q⁻ : x ∈ p ∩ q → x ∈ p × x ∈ q∩⇔× : x ∈ p ∩ q ⇔ (x ∈ p × x ∈ q)```* Added relations to `Data.Integer````agda_≥_ : Rel ℤ __<_ : Rel ℤ __>_ : Rel ℤ __≰_ : Rel ℤ __≱_ : Rel ℤ __≮_ : Rel ℤ __≯_ : Rel ℤ _```* Added proofs to `Data.Integer.Properties````agda+-injective : + m ≡ + n → m ≡ n-[1+-injective : -[1+ m ] ≡ -[1+ n ] → m ≡ ndoubleNeg : - - n ≡ nneg-injective : - m ≡ - n → m ≡ n∣n∣≡0⇒n≡0 : ∣ n ∣ ≡ 0 → n ≡ + 0∣-n∣≡∣n∣ : ∣ - n ∣ ≡ ∣ n ∣+◃n≡+n : Sign.+ ◃ n ≡ + n-◃n≡-n : Sign.- ◃ n ≡ - + nsignₙ◃∣n∣≡n : sign n ◃ ∣ n ∣ ≡ n∣s◃m∣*∣t◃n∣≡m*n : ∣ s ◃ m ∣ ℕ* ∣ t ◃ n ∣ ≡ m ℕ* n⊖-≰ : n ≰ m → m ⊖ n ≡ - + (n ∸ m)∣⊖∣-≰ : n ≰ m → ∣ m ⊖ n ∣ ≡ n ∸ msign-⊖-≰ : n ≰ m → sign (m ⊖ n) ≡ Sign.--[n⊖m]≡-m+n : - (m ⊖ n) ≡ (- (+ m)) + (+ n)+-identity : Identity (+ 0) _+_+-inverse : Inverse (+ 0) -_ _+_+-0-isMonoid : IsMonoid _≡_ _+_ (+ 0)+-0-isGroup : IsGroup _≡_ _+_ (+ 0) (-_)+-0-abelianGroup : AbelianGroup _ _n≢1+n : n ≢ suc n1-[1+n]≡-n : suc -[1+ n ] ≡ - (+ n)neg-distrib-+ : - (m + n) ≡ (- m) + (- n)◃-distrib-+ : s ◃ (m + n) ≡ (s ◃ m) + (s ◃ n)*-identityʳ : RightIdentity (+ 1) _*_*-identity : Identity (+ 1) _*_*-zeroˡ : LeftZero (+ 0) _*_*-zeroʳ : RightZero (+ 0) _*_*-zero : Zero (+ 0) _*_*-1-isMonoid : IsMonoid _≡_ _*_ (+ 1)-1*n≡-n : -[1+ 0 ] * n ≡ - n◃-distrib-* : (s 𝕊* t) ◃ (m ℕ* n) ≡ (s ◃ m) * (t ◃ n)+-*-isRing : IsRing _≡_ _+_ _*_ -_ (+ 0) (+ 1)+-*-isCommutativeRing : IsCommutativeRing _≡_ _+_ _*_ -_ (+ 0) (+ 1)≤-reflexive : _≡_ ⇒ _≤_≤-refl : Reflexive _≤_≤-trans : Transitive _≤_≤-antisym : Antisymmetric _≡_ _≤_≤-total : Total _≤_≤-isPreorder : IsPreorder _≡_ _≤_≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_≤-step : n ≤ m → n ≤ suc mn≤1+n : n ≤ + 1 + n<-irrefl : Irreflexive _≡_ _<_<-asym : Asymmetric _<_<-trans : Transitive _<_<-cmp : Trichotomous _≡_ _<_<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_n≮n : n ≮ n-<+ : -[1+ m ] < + n<⇒≤ : m < n → m ≤ n≰→> : x ≰ y → x > y```* Added functions to `Data.List````agdaapplyUpTo f n ≈ f[0] ∷ f[1] ∷ ... ∷ f[n-1] ∷ []upTo n ≈ 0 ∷ 1 ∷ ... ∷ n-1 ∷ []applyDownFrom f n ≈ f[n-1] ∷ f[n-2] ∷ ... ∷ f[0] ∷ []tabulate f ≈ f[0] ∷ f[1] ∷ ... ∷ f[n-1] ∷ []allFin n ≈ 0f ∷ 1f ∷ ... ∷ n-1f ∷ []```* Added proofs to `Data.List.Properties````agdamap-id₂ : All (λ x → f x ≡ x) xs → map f xs ≡ xsmap-cong₂ : All (λ x → f x ≡ g x) xs → map f xs ≡ map g xsfoldr-++ : foldr f x (ys ++ zs) ≡ foldr f (foldr f x zs) ysfoldl-++ : foldl f x (ys ++ zs) ≡ foldl f (foldl f x ys) zsfoldr-∷ʳ : foldr f x (ys ∷ʳ y) ≡ foldr f (f y x) ysfoldl-∷ʳ : foldl f x (ys ∷ʳ y) ≡ f (foldl f x ys) yreverse-foldr : foldr f x (reverse ys) ≡ foldl (flip f) x ysreverse-foldr : foldl f x (reverse ys) ≡ foldr (flip f) x yslength-reverse : length (reverse xs) ≡ length xs```* Added proofs to `Data.List.All.Properties````agdaAll-universal : Universal P → All P xs¬Any⇒All¬ : ¬ Any P xs → All (¬_ ∘ P) xsAll¬⇒¬Any : All (¬_ ∘ P) xs → ¬ Any P xs¬All⇒Any¬ : Decidable P → ¬ All P xs → Any (¬_ ∘ P) xs++⁺ : All P xs → All P ys → All P (xs ++ ys)++⁻ˡ : All P (xs ++ ys) → All P xs++⁻ʳ : All P (xs ++ ys) → All P ys++⁻ : All P (xs ++ ys) → All P xs × All P ysconcat⁺ : All (All P) xss → All P (concat xss)concat⁻ : All P (concat xss) → All (All P) xssdrop⁺ : All P xs → All P (drop n xs)take⁺ : All P xs → All P (take n xs)tabulate⁺ : (∀ i → P (f i)) → All P (tabulate f)tabulate⁻ : All P (tabulate f) → (∀ i → P (f i))applyUpTo⁺₁ : (∀ {i} → i < n → P (f i)) → All P (applyUpTo f n)applyUpTo⁺₂ : (∀ i → P (f i)) → All P (applyUpTo f n)applyUpTo⁻ : All P (applyUpTo f n) → ∀ {i} → i < n → P (f i)```* Added proofs to `Data.List.Any.Properties````agdalose∘find : uncurry′ lose (proj₂ (find p)) ≡ pfind∘lose : find (lose x∈xs pp) ≡ (x , x∈xs , pp)swap : Any (λ x → Any (P x) ys) xs → Any (λ y → Any (flip P y) xs) ysswap-invol : swap (swap any) ≡ any∃∈-Any : (∃ λ x → x ∈ xs × P x) → Any P xsAny-⊎⁺ : Any P xs ⊎ Any Q xs → Any (λ x → P x ⊎ Q x) xsAny-⊎⁻ : Any (λ x → P x ⊎ Q x) xs → Any P xs ⊎ Any Q xsAny-×⁺ : Any P xs × Any Q ys → Any (λ x → Any (λ y → P x × Q y) ys) xsAny-×⁻ : Any (λ x → Any (λ y → P x × Q y) ys) xs → Any P xs × Any Q ysmap⁺ : Any (P ∘ f) xs → Any P (map f xs)map⁻ : Any P (map f xs) → Any (P ∘ f) xs++⁺ˡ : Any P xs → Any P (xs ++ ys)++⁺ʳ : Any P ys → Any P (xs ++ ys)++⁻ : Any P (xs ++ ys) → Any P xs ⊎ Any P ysconcat⁺ : Any (Any P) xss → Any P (concat xss)concat⁻ : Any P (concat xss) → Any (Any P) xssapplyUpTo⁺ : P (f i) → i < n → Any P (applyUpTo f n)applyUpTo⁻ : Any P (applyUpTo f n) → ∃ λ i → i < n × P (f i)tabulate⁺ : P (f i) → Any P (tabulate f)tabulate⁻ : Any P (tabulate f) → ∃ λ i → P (f i)map-with-∈⁺ : (∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)) → Any P (map-with-∈ xs f)map-with-∈⁻ : Any P (map-with-∈ xs f) → ∃₂ λ x (x∈xs : x ∈ xs) → P (f x∈xs)return⁺ : P x → Any P (return x)return⁻ : Any P (return x) → P x```* Added proofs to `Data.List.Any.Membership.Properties````agda∈-map⁺ : x ∈ xs → f x ∈ map f xs∈-map⁻ : y ∈ map f xs → ∃ λ x → x ∈ xs × y ≈ f x```* Added proofs to `Data.List.Any.Membership.Propositional.Properties````agda∈-map⁺ : x ∈ xs → f x ∈ map f xs∈-map⁻ : y ∈ map f xs → ∃ λ x → x ∈ xs × y ≈ f x```* Added proofs to `Data.Maybe`:```agdaEq-refl : Reflexive _≈_ → Reflexive (Eq _≈_)Eq-sym : Symmetric _≈_ → Symmetric (Eq _≈_)Eq-trans : Transitive _≈_ → Transitive (Eq _≈_)Eq-dec : Decidable _≈_ → Decidable (Eq _≈_)Eq-isEquivalence : IsEquivalence _≈_ → IsEquivalence (Eq _≈_)Eq-isDecEquivalence : IsDecEquivalence _≈_ → IsDecEquivalence (Eq _≈_)```* Added exponentiation operator `_^_` to `Data.Nat.Base`* Added proofs to `Data.Nat.Properties`:```agdasuc-injective : suc m ≡ suc n → m ≡ n≡-isDecEquivalence : IsDecEquivalence (_≡_ {A = ℕ})≡-decSetoid : DecSetoid _ _≤-reflexive : _≡_ ⇒ _≤_≤-refl : Reflexive _≤_≤-trans : Antisymmetric _≡_ _≤_≤-antisymmetric : Transitive _≤_≤-total : Total _≤_≤-isPreorder : IsPreorder _≡_ _≤_≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤__<?_ : Decidable _<_<-irrefl : Irreflexive _≡_ _<_<-asym : Asymmetric _<_<-transʳ : Trans _≤_ _<_ _<_<-transˡ : Trans _<_ _≤_ _<_<-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_<⇒≤ : _<_ ⇒ _≤_<⇒≢ : _<_ ⇒ _≢_<⇒≱ : _<_ ⇒ _≱_<⇒≯ : _<_ ⇒ _≯_≰⇒≮ : _≰_ ⇒ _≮_≰⇒≥ : _≰_ ⇒ _≥_≮⇒≥ : _≮_ ⇒ _≥_≤+≢⇒< : m ≤ n → m ≢ n → m < n+-identityˡ : LeftIdentity 0 _+_+-identity : Identity 0 _+_+-cancelʳ-≡ : RightCancellative _≡_ _+_+-cancel-≡ : Cancellative _≡_ _+_+-cancelʳ-≤ : RightCancellative _≤_ _+_+-cancel-≤ : Cancellative _≤_ _+_+-isSemigroup : IsSemigroup _≡_ _+_+-monoˡ-< : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_+-monoʳ-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_+-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_m+n≤o⇒m≤o : m + n ≤ o → m ≤ om+n≤o⇒n≤o : m + n ≤ o → n ≤ om+n≮n : m + n ≮ n*-zeroˡ : LeftZero 0 _*_*-zero : Zero 0 _*_*-identityˡ : LeftIdentity 1 _*_*-identityʳ : RightIdentity 1 _*_*-identity : Identity 1 _*_*-distribˡ-+ : _*_ DistributesOverˡ _+_*-distrib-+ : _*_ DistributesOver _+_*-isSemigroup : IsSemigroup _≡_ _*_*-mono-< : _*_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_*-monoˡ-< : (_* suc n) Preserves _<_ ⟶ _<_*-monoʳ-< : (suc n *_) Preserves _<_ ⟶ _<_*-cancelˡ-≡ : suc k * i ≡ suc k * j → i ≡ j^-distribˡ-+-* : m ^ (n + p) ≡ m ^ n * m ^ pi^j≡0⇒i≡0 : i ^ j ≡ 0 → i ≡ 0i^j≡1⇒j≡0∨i≡1 : i ^ j ≡ 1 → j ≡ 0 ⊎ i ≡ 1⊔-assoc : Associative _⊔_⊔-comm : Commutative _⊔_⊔-idem : Idempotent _⊔_⊔-identityˡ : LeftIdentity 0 _⊔_⊔-identityʳ : RightIdentity 0 _⊔_⊔-identity : Identity 0 _⊔_⊓-assoc : Associative _⊓_⊓-comm : Commutative _⊓_⊓-idem : Idempotent _⊓_⊓-zeroˡ : LeftZero 0 _⊓_⊓-zeroʳ : RightZero 0 _⊓_⊓-zero : Zero 0 _⊓_⊓-distribʳ-⊔ : _⊓_ DistributesOverʳ _⊔_⊓-distribˡ-⊔ : _⊓_ DistributesOverˡ _⊔_⊔-abs-⊓ : _⊔_ Absorbs _⊓_⊓-abs-⊔ : _⊓_ Absorbs _⊔_m⊓n≤n : m ⊓ n ≤ nm≤m⊔n : m ≤ m ⊔ nm⊔n≤m+n : m ⊔ n ≤ m + nm⊓n≤m+n : m ⊓ n ≤ m + nm⊓n≤m⊔n : m ⊔ n ≤ m ⊔ n⊔-mono-≤ : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊔-mono-< : _⊔_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_⊓-mono-≤ : _⊓_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_⊓-mono-< : _⊓_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_+-distribˡ-⊔ : _+_ DistributesOverˡ _⊔_+-distribʳ-⊔ : _+_ DistributesOverʳ _⊔_+-distrib-⊔ : _+_ DistributesOver _⊔_+-distribˡ-⊓ : _+_ DistributesOverˡ _⊓_+-distribʳ-⊓ : _+_ DistributesOverʳ _⊓_+-distrib-⊓ : _+_ DistributesOver _⊓_⊔-isSemigroup : IsSemigroup _≡_ _⊔_⊓-isSemigroup : IsSemigroup _≡_ _⊓_⊓-⊔-isLattice : IsLattice _≡_ _⊓_ _⊔_∸-distribʳ-⊔ : _∸_ DistributesOverʳ _⊔_∸-distribʳ-⊓ : _∸_ DistributesOverʳ _⊓_+-∸-comm : o ≤ m → (m + n) ∸ o ≡ (m ∸ o) + n```* Added decidability relation to `Data.Nat.GCD````agdagcd? : (m n d : ℕ) → Dec (GCD m n d)```* Added "not-divisible-by" relation to `Data.Nat.Divisibility````agdam ∤ n = ¬ (m ∣ n)```* Added proofs to `Data.Nat.Divisibility````agda∣-reflexive : _≡_ ⇒ _∣_∣-refl : Reflexive _∣_∣-trans : Transitive _∣_∣-antisym : Antisymmetric _≡_ _∣_∣-isPreorder : IsPreorder _≡_ _∣_∣-isPartialOrder : IsPartialOrder _≡_ _∣_n∣n : n ∣ n∣m∸n∣n⇒∣m : n ≤ m → i ∣ m ∸ n → i ∣ n → i ∣ m```* Added proofs to `Data.Nat.GeneralisedArithmetic`:```agdafold-+ : fold z s (m + n) ≡ fold (fold z s n) s mfold-k : fold k (s ∘′_) m z ≡ fold (k z) s mfold-* : fold z s (m * n) ≡ fold z (fold id (s ∘_) n) mfold-pull : fold p s m ≡ g (fold z s m) pid-is-fold : fold zero suc m ≡ m+-is-fold : fold n suc m ≡ m + n*-is-fold : fold zero (n +_) m ≡ m * n^-is-fold : fold 1 (m *_) n ≡ m ^ n*+-is-fold : fold p (n +_) m ≡ m * n + p^*-is-fold : fold p (m *_) n ≡ m ^ n * p```* Added syntax for existential quantifiers in `Data.Product`:```agda∃-syntax (λ x → B) = ∃[ x ] B∄-syntax (λ x → B) = ∄[ x ] B```* A new module `Data.Rational.Properties` has been added, containing proofs:```agda≤-reflexive : _≡_ ⇒ _≤_≤-refl : Reflexive _≤_≤-trans : Transitive _≤_≤-antisym : Antisymmetric _≡_ _≤_≤-total : Total _≤_≤-isPreorder : IsPreorder _≡_ _≤_≤-isPartialOrder : IsPartialOrder _≡_ _≤_≤-isTotalOrder : IsTotalOrder _≡_ _≤_≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_```* Added proofs to `Data.Sign.Properties`:```agdaopposite-cong : opposite s ≡ opposite t → s ≡ t*-identityˡ : LeftIdentity + _*_*-identityʳ : RightIdentity + _*_*-identity : Identity + _*_*-comm : Commutative _*_*-assoc : Associative _*_cancel-*-left : LeftCancellative _*_*-cancellative : Cancellative _*_s*s≡+ : s * s ≡ +```* Added definitions to `Data.Sum`:```agdaFrom-inj₁ : ∀ {a b} {A : Set a} {B : Set b} → A ⊎ B → Set afrom-inj₁ : ∀ {a b} {A : Set a} {B : Set b} (x : A ⊎ B) → From-inj₁ xFrom-inj₂ : ∀ {a b} {A : Set a} {B : Set b} → A ⊎ B → Set bfrom-inj₂ : ∀ {a b} {A : Set a} {B : Set b} (x : A ⊎ B) → From-inj₂ x```* Added a functor encapsulating `map` in `Data.Vec`:```agdafunctor = record { _<$>_ = map}```* Added proofs to `Data.Vec.Equality````agdato-≅ : xs ≈ ys → xs ≅ ysxs++[]≈xs : xs ++ [] ≈ xsxs++[]≅xs : xs ++ [] ≅ xs```* Added proofs to `Data.Vec.Properties````agdalookup-map : lookup i (map f xs) ≡ f (lookup i xs)lookup-functor-morphism : Morphism functor IdentityFunctormap-replicate : map f (replicate x) ≡ replicate (f x)⊛-is-zipWith : fs ⊛ xs ≡ zipWith _$_ fs xsmap-is-⊛ : map f xs ≡ replicate f ⊛ xszipWith-is-⊛ : zipWith f xs ys ≡ replicate f ⊛ xs ⊛ yszipWith-replicate₁ : zipWith _⊕_ (replicate x) ys ≡ map (x ⊕_) yszipWith-replicate₂ : zipWith _⊕_ xs (replicate y) ≡ map (_⊕ y) xszipWith-map₁ : zipWith _⊕_ (map f xs) ys ≡ zipWith (λ x y → f x ⊕ y) xs yszipWith-map₂ : zipWith _⊕_ xs (map f ys) ≡ zipWith (λ x y → x ⊕ f y) xs ys```* Added proofs to `Data.Vec.All.Properties````agdaAll-++⁺ : All P xs → All P ys → All P (xs ++ ys)All-++ˡ⁻ : All P (xs ++ ys) → All P xsAll-++ʳ⁻ : All P (xs ++ ys) → All P ysAll-++⁻ : All P (xs ++ ys) → All P xs × All P ysAll₂-++⁺ : All₂ _~_ ws xs → All₂ _~_ ys zs → All₂ _~_ (ws ++ ys) (xs ++ zs)All₂-++ˡ⁻ : All₂ _~_ (ws ++ ys) (xs ++ zs) → All₂ _~_ ws xsAll₂-++ʳ⁻ : All₂ _~_ (ws ++ ys) (xs ++ zs) → All₂ _~_ ys zsAll₂-++⁻ : All₂ _~_ (ws ++ ys) (xs ++ zs) → All₂ _~_ ws xs × All₂ _~_ ys zsAll-concat⁺ : All (All P) xss → All P (concat xss)All-concat⁻ : All P (concat xss) → All (All P) xssAll₂-concat⁺ : All₂ (All₂ _~_) xss yss → All₂ _~_ (concat xss) (concat yss)All₂-concat⁻ : All₂ _~_ (concat xss) (concat yss) → All₂ (All₂ _~_) xss yss```* Added non-dependant versions of the application combinators in `Function` for usecases where the most general one leads to unsolved meta variables:```agda_$′_ : (A → B) → (A → B)_$!′_ : (A → B) → (A → B)```* Added proofs to `Relation.Binary.Consequences````agdaP-resp⟶¬P-resp : Symmetric _≈_ → P Respects _≈_ → (¬_ ∘ P) Respects _≈_```* Added conversion lemmas to `Relation.Binary.HeterogeneousEquality````agda≅-to-type-≡ : {x : A} {y : B} → x ≅ y → A ≡ B≅-to-subst-≡ : (p : x ≅ y) → subst (λ x → x) (≅-to-type-≡ p) x ≡ y```
Version 0.13============The library has been tested using Agda version 2.5.2.Important changes since 0.12:* Added the `Selective` property in `Algebra.FunctionProperties` aswell as proofs of the selectivity of `min` and `max` in`Data.Nat.Properties`.* Added `Relation.Binary.Product.StrictLex.×-total₂`, an alternative(non-degenerative) proof for totality, and renamed `×-total` to`x-total₁` in that module.* Added the `length-filter` property to `Data.List.Properties` (the`filter` equivalent to the pre-existing `length-gfilter`).* Added `_≤?_` decision procedure for `Data.Fin`.* Added `allPairs` function to `Data.Vec`.* Added additional properties of `_∈_` to `Data.Vec.Properties`:`∈-map`, `∈-++ₗ`, `∈-++ᵣ`, `∈-allPairs`.* Added some `zip`/`unzip`-related properties to`Data.Vec.Properties`.* Added an `All` predicate and related properties for `Data.Vec` (see`Data.Vec.All` and `Data.Vec.All.Properties`).* Added order-theoretic lattices and some related properties in`Relation.Binary.Lattice` and `Relation.Binary.Properties`.* Added symmetric and equivalence closures of binary relations in`Relation.Binary.SymmetricClosure` and`Relation.Binary.EquivalenceClosure`.* Added `Congruent₁` and `Congruent₂` to `Algebra.FunctionProperties`.These are aliases for `_Preserves _≈_ ⟶ _≈_` and`_Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_` from `Relation.Binary.Core`.* Useful lemmas and properties that were previously in private scope,either explicitly or within records, have been made public in several`Properties.agda` files. These include:```agdaData.Bool.PropertiesData.Fin.PropertiesData.Integer.PropertiesData.Integer.Addition.PropertiesData.Integer.Multiplication.Properties```
Version 0.12============The library has been tested using Agda version 2.5.1.Important changes since 0.11:* Added support for GHC 8.0.1.
Version 0.11============The library has been tested using Agda version 2.4.2.4.Important changes since 0.10:* `Relation.Binary.PropositionalEquality.TrustMe.erase` was added.* Added `Data.Nat.Base.{_≤″_,_≥″_,_<″_,_>″_,erase}`,`Data.Nat.Properties.{≤⇒≤″,≤″⇒≤}`, `Data.Fin.fromℕ≤″`, and`Data.Fin.Properties.fromℕ≤≡fromℕ≤″`.* The functions in `Data.Nat.DivMod` have been optimised.* Turned on η-equality for `Record.Record`, removed`Record.Signature′` and `Record.Record′`.* Renamed `Data.AVL.agda._⊕_sub1` to `pred[_⊕_]`.
Version 0.10============The library has been tested using Agda version 2.4.2.3.Important changes since 0.9:* Renamed `Data.Unit.Core` to `Data.Unit.NonEta`.* Removed `Data.String.Core`. The module `Data.String.Base` nowcontains these definitions.* Removed `Relation.Nullary.Core`. The module `Relation.Nullary` nowcontains these definitions directly.* Inspect on steroids has been simplified (see`Relation.Binary.PropositionalEquality` and`Relation.Binary.HeterogeneousEquality`).The old version has been deprecated (see the above modules) and itwill be removed in the next release.* Using `Data.X.Base` modules.The `Data.X.Base` modules are used for cheaply importing a data typeand the most common definitions. The use of these modules reducetype-checking and compilation times.At the moment, the modules added are:```agdaData.Bool.BaseData.Char.BaseData.Integer.BaseData.List.BaseData.Maybe.BaseData.Nat.BaseData.String.BaseData.Unit.Base```These modules are also cheap to import and can be considered basic:```agdaData.BoundedVec.InefficientData.EmptyData.ProductData.SignData.SumFunctionLevelRelation.BinaryRelation.Binary.PropositionalEquality.TrustMeRelation.Nullary```* Added singleton sets to `Relation.Unary`.There used to be an isomorphic definition of singleton sets in`Monad.Predicate`, this has been removed and the module has beencleaned up accordingly.The singleton set is also used to define generic operations (Plotkinand Power's terminology) in `Data.Container.Indexed.FreeMonad`.* Proved properties of `Data.List.gfilter`. The following definitionshave been added to Data.List.Properties:```agdagfilter-just : ... → gfilter just xs ≡ xsgfilter-nothing : ... → gfilter (λ _ → nothing) xs ≡ []gfilter-concatMap : ... → gfilter f ≗ concatMap (fromMaybe ∘ f)```* New in `Data.Nat.Properties`:```agda<⇒≤pred : ∀ {m n} → m < n → m ≤ pred n```* New in `Data.Fin`:```agdastrengthen : ∀ {n} (i : Fin n) → Fin′ (suc i)```* New in `Data.Fin.Properties`:```agdafrom-to : ∀ {n} (i : Fin n) → fromℕ (toℕ i) ≡ strengthen itoℕ-strengthen : ∀ {n} (i : Fin n) → toℕ (strengthen i) ≡ toℕ ifromℕ-def : ∀ n → fromℕ n ≡ fromℕ≤ ℕ≤-reflreverse-suc : ∀{n}{i : Fin n} → toℕ (reverse (suc i)) ≡ toℕ (reverse i)inject≤-refl : ∀ {n} (i : Fin n) (n≤n : n ℕ≤ n) → inject≤ i n≤n ≡ i```* New in `Data.List.NonEmpty`:```agdafoldr₁ : ∀ {a} {A : Set a} → (A → A → A) → List⁺ A → Afoldl₁ : ∀ {a} {A : Set a} → (A → A → A) → List⁺ A → A```* `Data.AVL.Height-invariants._∼_` was replaced by `_∼_⊔_`, followingConor McBride's principle of pushing information into indices ratherthan pulling information out.Some lemmas in `Data.AVL.Height-invariants` (`1+`, `max∼max` and`max-lemma`) were removed.The implementations of some functions in `Data.AVL` were simplified.This could mean that they, and other functions depending on them (in`Data.AVL`, `Data.AVL.IndexedMap` and `Data.AVL.Sets`), reduce in adifferent way than they used to.* The fixity of all `_∎` and `finally` operators, as well as`Category.Monad.Partiality.All._⟨_⟩P`, was changed from `infix 2` to`infix 3`.* The fixity of `Category.Monad.Partiality._≟-Kind_`, `Data.AVL._∈?_`,`Data.AVL.IndexedMap._∈?_`, `Data.AVL.Sets._∈?_`, `Data.Bool._≟_`,`Data.Char._≟_`, `Data.Float._≟_`, `Data.Nat._≤?_`,`Data.Nat.Divisibility._∣?_`, `Data.Sign._≟_`, `Data.String._≟_`,`Data.Unit._≟_`, `Data.Unit._≤?_` and`Data.Vec.Equality.DecidableEquality._≟_` was changed from thedefault to `infix 4`.* The fixity of all `_≟<something>_` operators in `Reflection` is now`infix 4` (some of them already had this fixity).* The fixity of `Algebra.Operations._×′_` was changed from the defaultto `infixr 7`.* The fixity of `Data.Fin.#_` was changed from the default to`infix 10`.* The fixity of `Data.Nat.Divisibility.1∣_` and `_∣0` was changed fromthe default to `infix 10`.* The fixity of `Data.Nat.DivMod._divMod_`, `_div_` and `_mod_` waschanged from the default to `infixl 7`.* The fixity of `Data.Product.Σ-syntax` was changed from the defaultto `infix 2`.* The fixity of `Relation.Unary._~` was changed from the default to`infix 10`.
Version 0.9===========The library has been tested using Agda version 2.4.2.1.Important changes since 0.8.1:* `Data.List.NonEmpty`Non-empty lists are no longer defined in terms of`Data.Product._×_`, instead, now they are defined as record withfields head and tail.* Reflection API+ Quoting levels was fixed. This fix could break some code (see AgdaIssue [#1207](https://github.com/agda/agda/issues/1269)).+ The `Reflection.type` function returns a normalised`Reflection.Type` and `quoteTerm` returns an η-contracted`Reflection.Term` now. These changes could break some code (seeAgda Issue [#1269](https://github.com/agda/agda/issues/1269)).+ The primitive function for showing names, `primShowQName`, is nowexposed as `Reflection.showName`.* Removed compatibility modules for `Props -> Properties` renameUse `Foo.Properties.Bar` instead of `Foo.Props.Bar`.
Version 0.8===========Version 0.8 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.4.0.
Version 0.8.1=============The library has been tested using Agda version 2.4.2.Important changes since 0.8:* Reflection APIAgda 2.4.2 added support for literals, function definitions, patternmatching lambdas and absurd clause/patterns (see Agda releasenotes). The new supported entities were added to the`Reflection.agda` module.* Modules renamed`Foo.Props.Bar` -> `Foo.Properties.Bar`The current compatibility modules `Foo.Props.Bar` will be removed inthe next release.
Version 0.7===========Version 0.7 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.3.2.
Version 0.6===========Version 0.6 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.3.0.
Version 0.5===========Version 0.5 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.2.10.
Version 0.4===========Version 0.4 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.2.8.
Version 0.3===========Version 0.3 of the[standard library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.2.6.
Version 0.2===========Version 0.2 of the["standard" library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.2.4.Note that the library sources are now located in the sub-directory`lib-<version>/src` of the installation tarball.
Version 0.1===========Version 0.1 of the["standard" library](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary)has now been released.The library has been tested using Agda version 2.2.2.
{-# LANGUAGE OverloadedStrings #-}-- | This module extracts all the non-ASCII characters used by the-- library code (along with how many times they are used).module Main whereimport qualified Data.List as List (sortBy, sort)import qualified Data.List.NonEmpty as List1 (group, head)import Data.Char (isAscii, ord)import Data.Function (on)import Numeric (showHex)import System.FilePath.Find (find, always, extension, (||?), (==?))import System.IO (openFile, hSetEncoding, utf8, IOMode(ReadMode))import qualified Data.Text as T (Text, pack, unpack, concat)import qualified Data.Text.IO as T (putStrLn, hGetContents)readUTF8File :: FilePath -> IO T.TextreadUTF8File f = doh <- openFile f ReadModehSetEncoding h utf8T.hGetContents hmain :: IO ()main = doagdaFiles <- find always(extension ==? ".agda" ||? extension ==? ".lagda")"src"nonAsciiChars <-filter (not . isAscii) . T.unpack . T.concat <$> mapM readUTF8File agdaFileslet table :: [(Char, Int)]table = List.sortBy (flip compare `on` snd) $map (\cs -> (List1.head cs, length cs)) $List1.group $ List.sort $ nonAsciiCharslet codePoint :: Char -> T.TextcodePoint c = T.pack $ showHex (ord c) ""uPlus :: Char -> T.TextuPlus c = T.concat ["(U+", codePoint c, ")"]mapM_ (\(c, count) -> T.putStrLn $ T.concat [T.pack [c], " ", uPlus c, ": ", T.pack $ show count])table
# The information from some Git commands, e.g. git shortlog -nse, is# better by using this file.# Please keep this file in alphabetic order!##############################################################################Alan Jeffrey <ajeffrey@bell-labs.com> ajeffreyAndreas Abel <andreas.abel@ifi.lmu.de> andreas.abel<asr@eafit.edu.co> <andres.sicard.ramirez@gmail.com>Darin Morrison <dwm@cs.nott.ac.uk> dwmDominique Devriese <dominique.devriese@cs.kuleuven.be> <dominique.devriese@gmail.com>Evgeny Kotelnikov <evgeny.kotelnikov@gmail.com> aztekGergő Érdi <gergo@erdi.hu> gergoJean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com> jeanphilippe.bernardy<nils.anders.danielsson@gmail.com> <nad@cs.chalmers.se>Noam Zeilberger <noam.zeilberger@gmail.com> noam.zeilbergerPatrik Jansson <patrikj@chalmers.se> patrikjShin-Cheng Mu <scm@iis.sinica.edu.tw> scmUlf Norell <ulfn@chalmers.se> ulf.norell <ulf.norell@gmail.com>Ulf Norell <ulfn@chalmers.se> ulfnUlf Norell <ulfn@chalmers.se> ulfn <ulfn@cs.chalmers.se><ulfn@chalmers.se> <ulf.norell@gmail.com>
# Keep this file in alphabetic order please!# Sort with the command `sort -uf`*.agda.el*.agdai*.hi*.lagda.el*.o.stack-work*.svg*.tix*.vim*~.*.swp.#*\#*_build.DS_Store.vscode/*distdist-newstyleEverything.agdaEverythingSafe.agdaEverythingSafeGuardedness.agdaEverythingSafeSizedTypes.agdafailuresGenerateEverythingHaskellhtmllogMAlonzooutputruntests
name: Check whitespaceon:push:branches:- master- experimentalpull_request:branches:- master- experimentalmerge_group:jobs:check-whitespace:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: andreasabel/fix-whitespace-action@v1
# This GitHub workflow config has been generated by a script via## haskell-ci 'github' '--no-cabal-check' 'agda-stdlib-utils.cabal'## To regenerate the script (for example after adjusting tested-with) run## haskell-ci regenerate## For more information, see https://github.com/haskell-CI/haskell-ci## version: 0.19.20240514## REGENDATA ("0.19.20240514",["github","--no-cabal-check","agda-stdlib-utils.cabal"])#name: Haskell-CIon:push:branches:- master- experimentalpaths:- .github/workflows/haskell-ci.yml- agda-stdlib-utils.cabal- cabal.haskell-ci- "*.hs"pull_request:branches:- master- experimentalpaths:- .github/workflows/haskell-ci.yml- agda-stdlib-utils.cabal- cabal.haskell-ci- "*.hs"merge_group:jobs:linux:name: Haskell-CI - Linux - ${{ matrix.compiler }}runs-on: ubuntu-20.04timeout-minutes:60container:image: buildpack-deps:jammycontinue-on-error: ${{ matrix.allow-failure }}strategy:matrix:include:- compiler: ghc-9.10.1compilerKind: ghccompilerVersion: 9.10.1setup-method: ghcupallow-failure: false- compiler: ghc-9.8.2compilerKind: ghccompilerVersion: 9.8.2setup-method: ghcupallow-failure: false- compiler: ghc-9.6.5compilerKind: ghccompilerVersion: 9.6.5setup-method: ghcupallow-failure: false- compiler: ghc-9.4.8compilerKind: ghccompilerVersion: 9.4.8setup-method: ghcupallow-failure: false- compiler: ghc-9.2.8compilerKind: ghccompilerVersion: 9.2.8setup-method: ghcupallow-failure: false- compiler: ghc-9.0.2compilerKind: ghccompilerVersion: 9.0.2setup-method: ghcupallow-failure: false- compiler: ghc-8.10.7compilerKind: ghccompilerVersion: 8.10.7setup-method: ghcupallow-failure: false- compiler: ghc-8.8.4compilerKind: ghccompilerVersion: 8.8.4setup-method: ghcupallow-failure: false- compiler: ghc-8.6.5compilerKind: ghccompilerVersion: 8.6.5setup-method: ghcupallow-failure: falsefail-fast: falsesteps:- name: aptrun: |apt-get updateapt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5mkdir -p "$HOME/.ghcup/bin"curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"chmod a+x "$HOME/.ghcup/bin/ghcup""$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)"$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)env:HCKIND: ${{ matrix.compilerKind }}HCNAME: ${{ matrix.compiler }}HCVER: ${{ matrix.compilerVersion }}- name: Set PATH and environment variablesrun: |echo "$HOME/.cabal/bin" >> $GITHUB_PATHecho "LANG=C.UTF-8" >> "$GITHUB_ENV"echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"HCDIR=/opt/$HCKIND/$HCVERHC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')echo "HC=$HC" >> "$GITHUB_ENV"echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"echo "HEADHACKAGE=false" >> "$GITHUB_ENV"echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"echo "GHCJSARITH=0" >> "$GITHUB_ENV"env:HCKIND: ${{ matrix.compilerKind }}HCNAME: ${{ matrix.compiler }}HCVER: ${{ matrix.compilerVersion }}- name: envrun: |env- name: write cabal configrun: |mkdir -p $CABAL_DIRcat >> $CABAL_CONFIG <<EOFremote-build-reporting: anonymouswrite-ghc-environment-files: neverremote-repo-cache: $CABAL_DIR/packageslogs-dir: $CABAL_DIR/logsworld-file: $CABAL_DIR/worldextra-prog-path: $CABAL_DIR/binsymlink-bindir: $CABAL_DIR/bininstalldir: $CABAL_DIR/binbuild-summary: $CABAL_DIR/logs/build.logstore-dir: $CABAL_DIR/storeinstall-dirs userprefix: $CABAL_DIRrepository hackage.haskell.orgurl: http://hackage.haskell.org/EOFcat >> $CABAL_CONFIG <<EOFprogram-default-optionsghc-options: $GHCJOBS +RTS -M3G -RTSEOFcat $CABAL_CONFIG- name: versionsrun: |$HC --version || true$HC --print-project-git-commit-id || true$CABAL --version || true- name: update cabal indexrun: |$CABAL v2-update -v- name: install cabal-planrun: |mkdir -p $HOME/.cabal/bincurl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xzecho 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-planrm -f cabal-plan.xzchmod a+x $HOME/.cabal/bin/cabal-plancabal-plan --version- name: checkoutuses: actions/checkout@v4with:path: source- name: initial cabal.project for sdistrun: |touch cabal.projectecho "packages: $GITHUB_WORKSPACE/source/." >> cabal.projectcat cabal.project- name: sdistrun: |mkdir -p sdist$CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist- name: unpackrun: |mkdir -p unpackedfind sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \;- name: generate cabal.projectrun: |PKGDIR_agda_stdlib_utils="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/agda-stdlib-utils-[0-9.]*')"echo "PKGDIR_agda_stdlib_utils=${PKGDIR_agda_stdlib_utils}" >> "$GITHUB_ENV"rm -f cabal.project cabal.project.localtouch cabal.projecttouch cabal.project.localecho "packages: ${PKGDIR_agda_stdlib_utils}" >> cabal.projectecho "package agda-stdlib-utils" >> cabal.projectecho " ghc-options: -Werror=missing-methods" >> cabal.projectcat >> cabal.project <<EOFEOF$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: any.$_ installed\n" unless /^(agda-stdlib-utils)$/; }' >> cabal.project.localcat cabal.projectcat cabal.project.local- name: dump install planrun: |$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run allcabal-plan- name: restore cacheuses: actions/cache/restore@v4with:key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}path: ~/.cabal/storerestore-keys: ${{ runner.os }}-${{ matrix.compiler }}-- name: install dependenciesrun: |$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all- name: build w/o testsrun: |$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all- name: buildrun: |$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always- name: haddockrun: |$CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all- name: unconstrained buildrun: |rm -f cabal.project.local$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all- name: save cacheuses: actions/cache/save@v4if: always()with:key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}path: ~/.cabal/store
name: Ubuntu buildon:push:branches:- master- experimentalpull_request:branches:- master- experimentalmerge_group:########################################################################## CONFIGURATION#### See SETTINGS for the most important configuration variable: AGDA_COMMIT.## It has to be defined as a build step because it is potentially branch## dependent.#### As for the rest:#### Basically do not touch GHC_VERSION and CABAL_VERSION as long as## they aren't a problem in the build. If you have time to waste, it## could be worth investigating whether newer versions of ghc produce## more efficient Agda executable and could cut down the build time.## Just be aware that actions are flaky and small variations are to be## expected.#### The CABAL_INSTALL variable only passes `-O1` optimisations to ghc## because github actions cannot currently handle a build using `-O2`.## To be experimented with again in the future to see if things have## gotten better.#### We use `v1-install` rather than `install` as Agda as a community## hasn't figured out how to manage dependencies with the new local## style builds (see agda/agda#4627 for details). Once this is resolved## we should upgrade to `install`.#### The AGDA variable specifies the command to use to build the library.## It currently passes the flag `-Werror` to ensure maximal compliance## with e.g. not relying on deprecated definitions.## The rest are some arbitrary runtime arguments that shape the way Agda## allocates and garbage collects memory. It should make things faster.## Limits can be bumped if the builds start erroring with out of memory## errors.##########################################################################env:GHC_VERSION: 9.8.2CABAL_VERSION: 3.10.3.0CABAL_INSTALL: cabal v1-install --ghc-options='-O1 +RTS -M6G -RTS'# CABAL_INSTALL: cabal install --overwrite-policy=always --ghc-options='-O1 +RTS -M6G -RTS'AGDA: agda -Werror +RTS -M5G -H3.5G -A128M -RTS -i. -isrc -idocjobs:test-stdlib:runs-on: ubuntu-lateststeps:########################################################################## SETTINGS#### AGDA_COMMIT picks the version of Agda to use to build the library.## It can either be a hash of a specific commit (to target a bugfix for## instance) or a tag e.g. tags/v2.6.1.3 (to target a released version).#### AGDA_HTML_DIR picks the html/ subdir in which to publish the docs.## The content of the html/ directory will be deployed so we put the## master version at the root and the experimental in a subdirectory.########################################################################- name: Initialise variablesrun: |if [[ '${{ github.ref }}' == 'refs/heads/experimental' \|| '${{ github.base_ref }}' == 'experimental' ]]; then# Pick Agda version for experimentalecho "AGDA_COMMIT=4d36cb37f8bfb765339b808b13356d760aa6f0ec" >> "${GITHUB_ENV}";echo "AGDA_HTML_DIR=html/experimental" >> "${GITHUB_ENV}"else# Pick Agda version for masterecho "AGDA_COMMIT=tags/v2.6.4.3" >> "${GITHUB_ENV}";echo "AGDA_HTML_DIR=html/master" >> "${GITHUB_ENV}"fiif [[ '${{ github.ref }}' == 'refs/heads/master' \|| '${{ github.ref }}' == 'refs/heads/experimental' ]]; thenecho "AGDA_DEPLOY=true" >> "${GITHUB_ENV}"fi########################################################################## CACHING######################################################################### This caching step allows us to save a lot of building time by only# downloading ghc and cabal and rebuilding Agda if absolutely necessary# i.e. if we change either the version of Agda, ghc, or cabal that we want# to use for the build.- name: Cache ~/.cabal directoriesuses: actions/cache@v4id: cache-cabalwith:path: |~/.cabal/packages~/.cabal/store~/.cabal/bin~/.cabal/sharekey: ${{ runner.os }}-${{ env.GHC_VERSION }}-${{ env.CABAL_VERSION }}-${{ env.AGDA_COMMIT }}-cache########################################################################## INSTALLATION STEPS########################################################################- name: Install ghc & cabaluses: haskell-actions/setup@v2with:ghc-version: ${{ env.GHC_VERSION }}cabal-version: ${{ env.CABAL_VERSION }}cabal-update: true- name: Put cabal programs in PATHrun: echo "~/.cabal/bin" >> "${GITHUB_PATH}"- name: Install alex & happyif: steps.cache-cabal.outputs.cache-hit != 'true'run: |${{ env.CABAL_INSTALL }} alex${{ env.CABAL_INSTALL }} happy- name: Download and install Agda from githubif: steps.cache-cabal.outputs.cache-hit != 'true'run: |git clone https://github.com/agda/agdacd agdagit checkout ${{ env.AGDA_COMMIT }}mkdir -p doctouch doc/user-manual.pdf${{ env.CABAL_INSTALL }}cd ..########################################################################## TESTING######################################################################### By default github actions do not pull the repo- name: Checkout stdlibuses: actions/checkout@v4- name: Test stdlibrun: |# Including deprecated modules purely for testingcabal run GenerateEverything -- --include-deprecated${{ env.AGDA }} -WnoUserWarning --safe EverythingSafe.agda${{ env.AGDA }} -WnoUserWarning Everything.agda- name: Prepare HTML indexrun: |# Regenerating the Everything files without the deprecated modulescabal run GenerateEverythingcp .github/tooling/* ../index.sh${{ env.AGDA }} --safe EverythingSafe.agda${{ env.AGDA }} Everything.agda${{ env.AGDA }} index.agda- name: Golden testingrun: |${{ env.CABAL_INSTALL }} clockmake testsuite INTERACTIVE='' AGDA_EXEC='~/.cabal/bin/agda'########################################################################## DOC DEPLOYMENT######################################################################### We start by retrieving the currently deployed docs# We remove the content that is in the directory we are going to populate# so that stale files corresponding to deleted modules do not accumulate.# We then generate the docs in the AGDA_HTML_DIR subdirectory- name: Generate HTMLrun: |git clone --depth 1 --single-branch --branch gh-pages https://github.com/agda/agda-stdlib htmlrm -f '${{ env.AGDA_HTML_DIR }}'/*.htmlrm -f '${{ env.AGDA_HTML_DIR }}'/*.css${{ env.AGDA }} --html --html-dir ${{ env.AGDA_HTML_DIR }} index.agdacp .github/tooling/* ../landing.sh- name: Deploy HTMLuses: JamesIves/github-pages-deploy-action@4.1.3if: success() && env.AGDA_DEPLOYwith:branch: gh-pagesfolder: htmlgit-config-name: Github Actions
set -euset -o pipefailrm html/index.htmlcat landing-top.html >> landing.htmlfind html/ -name "index.html" \| grep -v "master\|experimental" \| sed 's|html/\([^\/]*\)/index.html|\1|g' \| sort -r \| sed 's|^\(.*\)$| <li><a href="\1">\1</a></li>|g' \>> landing.htmlcat landing-bottom.html >> landing.htmlmv landing.html html/index.htmlmv agda-logo.svg html/
<html><head><title>Documention for the Agda standard library</title></head><body><div id="container" style="width:50%;min-width:500px;margin:auto"><img src="agda-logo.svg" style="width:80px;float:right" /><h1>Documention for the Agda standard library</h1><hr /><h2>Development versions</h2><ul><li><a href="master">master</a></li><li><a href="experimental">experimental</a></li></ul><h2>Released versions</h2><ul>
</ul></div></body></html>
set -euset -o pipefailfor file in $( find src -name "*.agda" | sort ); doif [[ ! $( head -n 10 $file | grep -m 1 "This module is DEPRECATED" ) ]]; theni=$( echo $file | sed 's/src\/\(.*\)\.agda/\1/' | sed 's/\//\./g' )echo "import $i" >> index.agda;fidone
{-# OPTIONS --rewriting --sized-types --guardedness #-}module index where-- You probably want to start with this module:import README-- For a brief presentation of every single module, head over toimport Everything-- Otherwise, here is an exhaustive, stern list of all the available modules:
--- .github/workflows/haskell-ci.yml 2023-02-22 18:05:26.000000000 +0100+++ .github/workflows/haskell-ci.yml-patched 2023-02-22 18:04:31.000000000 +0100@@ -18,10 +18,20 @@branches:- master- experimental+ paths:+ - .github/workflows/haskell-ci.yml+ - agda-stdlib-utils.cabal+ - cabal.haskell-ci+ - "*.hs"pull_request:branches:- master- experimental+ paths:+ - .github/workflows/haskell-ci.yml+ - agda-stdlib-utils.cabal+ - cabal.haskell-ci+ - "*.hs"jobs:linux:name: Haskell-CI - Linux - ${{ matrix.compiler }}
.travis.yml merge=ours
\.l?agda\.el$\.agdai$(^|/)MAlonzo($|/)^dist($|/)^html($|/)^Everything\.agda$