ArrowLift.v 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. (* SPDX-License-Identifier: GPL-2.0 or GPL-3.0
  2. Copyright © 2019 Ariadne Devos *)
  3. Require Import S.Lucid.Arrow.
  4. (* Well-behaved lifting from arrows to other arrows. *)
  5. (* Lift an arrow to another arrow *)
  6. Record arrow_lift_ops (from : arrow_basic) (to : arrow_basic) := {
  7. (* Different arrows may have different data types *)
  8. dwarpA : D from -> D to;
  9. (* Split the warp of a type product.
  10. Sequencing with this may ensure type-checking,
  11. but it may also have computational value:
  12. `D2 t A B` may map to `(t, A, B)`
  13. and `dwarpA t A` to `(t, A)`. *)
  14. dwarpAsplit : forall A B, Arr to (dwarpA (D2 _ A B)) (D2 to (dwarpA A) (dwarpA B));
  15. (* Merge the product of a warp into the warp of the product *)
  16. dwarpAmerge : forall A B, Arr to (D2 to (dwarpA A) (dwarpA B)) (dwarpA (D2 _ A B));
  17. (* change the arrow type, warping the data types *)
  18. arrA : forall A B, Arr from A B -> Arr to (dwarpA A) (dwarpA B);
  19. }.
  20. Arguments dwarpA { _ _ } a _.
  21. Arguments dwarpAsplit { _ _ } a { _ _ }.
  22. Arguments dwarpAmerge { _ _ } a { _ _ }.
  23. Arguments arrA { _ _ } a { _ _ } _.
  24. (* Simplification rules for lifts
  25. We try to move idA, assocA_r and assocA_l to the
  26. outer `to` arrow, such that they can fuse with `to`
  27. arrows.
  28. Lifts are also moved *into* compositions,
  29. for they probably cannot directly fuse with
  30. `to` arrows, but might with `from` arrows
  31. which are probably more lightweight as well.
  32. (The rules were taken from Haskell base-4.9.0.0 Control.Arrow). *)
  33. Record arrow_lift_lawful (from : arrow_basic) (to : arrow_basic) (lift : arrow_lift_ops from to) := {
  34. (* Warp splitting / merging artifacts can be deletedd *)
  35. dwarpAsplit_merge : forall A B, eqvA to (seqA to (dwarpAsplit (A := A) (B := B) lift) (dwarpAmerge lift)) (idA to);
  36. dwarpAmerge_split : forall A B, eqvA to (seqA to (dwarpAmerge (A := A) (B := B) lift) (dwarpAsplit lift)) (idA to);
  37. (* The lift of the identity arrow
  38. This can be rewritten out by seqA_idA_l and seqA_idA_r. *)
  39. arrAid : forall A, eqvA to (arrA lift (idA (A := A) from)) (idA to);
  40. (* Sequential composition of lifts *)
  41. arrAseq : forall A B C (f : Arr from A B) (g : Arr from B C),
  42. eqvA to (seqA to (arrA lift f) (arrA lift g))
  43. (arrA lift (seqA from f g));
  44. (* Parallel composition of lifts *)
  45. arrApar : forall A B C D (f : Arr from A B) (g : Arr from C D),
  46. eqvA to
  47. (parA to (arrA lift f) (arrA lift g))
  48. (* The input and output require some pre- and
  49. post-processing, due to the change in type system *)
  50. (seqA3 to
  51. (dwarpAmerge lift (A := A) (B := C))
  52. (arrA lift (parA from f g))
  53. (dwarpAsplit lift));
  54. }.
  55. Arguments dwarpAsplit_merge { _ _ _ } a _ _.
  56. Arguments dwarpAmerge_split { _ _ _ } a _ _.
  57. Arguments arrAid { _ _ _ } a _.
  58. Arguments arrAseq { _ _ _ } a { _ _ _ } f g.
  59. Arguments arrApar { _ _ _ } a { _ _ _ _ } f g.
  60. Record arrow_lift := {
  61. liftA_from : arrow_basic;
  62. liftA_to : arrow_basic;
  63. liftA_ops : arrow_lift_ops liftA_from liftA_to;
  64. liftA_laws : arrow_lift_lawful liftA_from liftA_to liftA_ops;
  65. }.
  66. Coercion liftA_to : arrow_lift >-> arrow_basic.
  67. Coercion liftA_ops : arrow_lift >-> arrow_lift_ops.
  68. Coercion liftA_laws : arrow_lift >-> arrow_lift_lawful.