Advertisement
Guest User

Untitled

a guest
Mar 29th, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.10 KB | None | 0 0
  1. import system.io
  2.  
  3. universes u v
  4.  
  5. namespace hide
  6.  
  7. inductive format.color
  8. | red | green | orange | blue | pink | cyan | grey
  9.  
  10. inductive format : Type
  11. | nil : format
  12. | text : string → format
  13. | choice : format → format → format
  14. | compose : format → format → format
  15. | flat_compose : format → format → format
  16. | line : format
  17. | nest : nat → format → format
  18. | color_begin : color → format
  19. | color_end : format
  20.  
  21. def format.of_string : string → format := format.text
  22. def format.of_nat (n : nat) : format := format.text n^.to_string
  23.  
  24. class has_to_format (α : Type u) :=
  25. (to_format : α → format)
  26.  
  27. instance : has_to_format format :=
  28. ⟨id⟩
  29.  
  30. def to_fmt {α : Type u} [has_to_format α] : α → format :=
  31. has_to_format.to_format
  32.  
  33. instance has_to_format_string : has_to_format string :=
  34. ⟨λ s, format.of_string s⟩
  35.  
  36. instance has_to_format_nat : has_to_format nat :=
  37. ⟨λ n, format.of_nat n⟩
  38.  
  39. instance has_to_format_char : has_to_format char :=
  40. ⟨λ c : char, format.of_string [c]⟩
  41.  
  42. namespace format
  43.  
  44. def color.code : color → string
  45. | color.red := "1"
  46. | color.green := "2"
  47. | color.orange := "3"
  48. | color.blue := "4"
  49. | color.pink := "5"
  50. | color.cyan := "6"
  51. | color.grey := "7"
  52.  
  53. instance : has_coe string format := ⟨text⟩
  54.  
  55. def space : format := " "
  56.  
  57. instance : inhabited format :=
  58. ⟨format.space⟩
  59.  
  60. instance : has_append format :=
  61. ⟨format.compose⟩
  62.  
  63. def concat (x y : format) : format :=
  64. x ++ " " ++ y
  65. infixr ^ := concat
  66.  
  67. def highlight (c : color) (f : format) : format :=
  68. color_begin c ++ f ++ color_end
  69.  
  70. def above (x y : format) : format :=
  71. x ++ line ++ y
  72.  
  73. instance nat_to_format : has_coe nat format :=
  74. ⟨format.of_nat⟩
  75.  
  76. instance string_to_format : has_coe string format :=
  77. ⟨format.of_string⟩
  78.  
  79. def is_nil : format → bool
  80. | nil := tt
  81. | _ := ff
  82.  
  83. def flatten_core : format → format × bool
  84. | (nest i x) := ((flatten_core x).1, tt)
  85. | (compose x y) := let (fx, hx) := flatten_core x, (fy, hy) := flatten_core y in
  86. (flat_compose fx fy, hx || hy)
  87. | (choice x y) := ((flatten_core x).1, tt)
  88. | line := (" ", tt)
  89. | x := (x, ff)
  90.  
  91. def flatten (f : format) : format := (flatten_core f).1
  92.  
  93. def group (f : format) : format :=
  94. let (flat_f, diff) := flatten_core f in
  95. if diff then choice flat_f f else flat_f
  96.  
  97. def bracket (l : string) (x : format) (r : string) : format :=
  98. group (nest (utf8_length l) (l ++ x ++ r))
  99.  
  100. def paren (f : format) : format :=
  101. bracket "(" f ")"
  102.  
  103. def cbrace (f : format) : format :=
  104. bracket "{" f "}"
  105.  
  106. def sbracket (f : format) : format :=
  107. bracket "[" f "]"
  108.  
  109. def dcbrace (f : format) : format :=
  110. bracket "⦃" f "⦄"
  111.  
  112. def wrap (x y : format) : format :=
  113. x ++ (choice " " line) ++ y
  114.  
  115. def space_upto_line_break (avail : nat) : format → nat → option (nat × bool)
  116. | nil len := some (len, ff)
  117. | (color_begin c) len := some (len, ff)
  118. | color_end len := some (len, ff)
  119. | (nest i x) len := space_upto_line_break x len
  120. | line len := some (len, tt)
  121. | (text t) len := some (len + t^.length, ff)
  122. | (choice x y) len := space_upto_line_break y len
  123. | (compose x y) len :=
  124. do a ← space_upto_line_break x 0,
  125. let len' := len + a.1 in
  126. if len' > avail then none else
  127. if a.2 then some (len', a.2) else
  128. space_upto_line_break y len'
  129. | (flat_compose x y) len :=
  130. do a ← space_upto_line_break x 0,
  131. let len' := len + a.1 in
  132. if len' > avail then none else
  133. if a.2 then some (len', a.2) else
  134. space_upto_line_break y len'
  135.  
  136. def space_upto_line_break_list_exceeded : list format → nat → bool
  137. | [] avail := ff
  138. | (f :: fs) avail :=
  139. match space_upto_line_break avail f 0 with
  140. | none := tt
  141. | some (len, found) :=
  142. if len > avail then tt else
  143. if found then ff else
  144. space_upto_line_break_list_exceeded fs (avail - len)
  145. end
  146.  
  147. def pretty_core {α : Type u} (app : α → string → α) (w : nat) (colors : bool) :
  148. format → list format → α → nat → nat → (α × nat)
  149. | nil todo s pos indent := (s, pos)
  150. | (color_begin c) todo s pos indent := (if colors then app s ("\x1B[" ++ c^.code ++ "m") else s, pos)
  151. | color_end todo s pos indent := (if colors then app s "\x1B[0m" else s, pos)
  152. | (compose x y) todo s pos indent :=
  153. let (s', pos') := pretty_core x (y :: todo) s pos indent in pretty_core y todo s' pos' indent
  154. | (flat_compose x y) todo s pos indent :=
  155. let (s', pos') := pretty_core x (y :: todo) s pos indent in pretty_core y todo s' pos' indent
  156. | (nest i x) todo s pos indent := pretty_core x todo s pos (indent + i)
  157. | line todo s pos indent :=
  158. (nat.rec_on indent (app s "\n") (λ_ s', app s " "), indent)
  159. | (text t) todo s pos indent := (app s t, pos + t^.length)
  160. | (choice x y) todo s pos indent :=
  161. if space_upto_line_break_list_exceeded (x::todo) (w - pos)
  162. then pretty_core y todo s pos indent
  163. else pretty_core x todo s pos indent
  164.  
  165. def pretty {α} (f : format) (app : α → string → α) (w : nat) (colors : bool) (out : α) : α :=
  166. (pretty_core app w colors f [] out 0 0).1
  167.  
  168. meta def get_option : tactic unit :=
  169. tactic.get_nat_option `pp.width 120 >>= (tactic.to_expr ∘ quote) >>= tactic.exact
  170. meta def get_pp_width : tactic unit :=
  171. tactic.get_nat_option `pp.width 120 >>= (tactic.to_expr ∘ quote) >>= tactic.exact
  172. meta def get_pp_colors : tactic unit :=
  173. tactic.get_bool_option `pp.colors ff >>= (tactic.to_expr ∘ quote) >>= tactic.exact
  174.  
  175. def print [io.interface] (f : format) (w : auto_param nat ``get_pp_width)
  176. (colors : auto_param bool ``get_pp_colors) : io unit :=
  177. pretty f (λm s, m >> io.put_str s) w colors (return ())
  178.  
  179. def to_string (f : format) (w : auto_param nat ``get_pp_width)
  180. (colors : auto_param bool ``get_pp_colors) : string :=
  181. pretty f string.concat w colors ""
  182.  
  183. instance : has_to_string format :=
  184. ⟨λf, format.to_string f⟩
  185.  
  186. def trace_fmt {α : Type u} (f : format) (fn : unit → α) : α :=
  187. trace (to_string f) (fn ())
  188.  
  189. def indent (f : format) (n : nat) : format :=
  190. nest n (line ++ f)
  191.  
  192. def when {α : Type u} [has_to_format α] : bool → α → format
  193. | tt a := to_fmt a
  194. | ff a := nil
  195.  
  196. def join (xs : list format) : format :=
  197. xs^.foldl compose (of_string "")
  198. end format
  199.  
  200. open hide.format list
  201.  
  202. instance has_to_format_bool : has_to_format bool :=
  203. ⟨λ b, if b then of_string "tt" else of_string "ff"⟩
  204.  
  205. instance has_to_format_decidable {p : Prop} : has_to_format (decidable p) :=
  206. ⟨λ b : decidable p, @ite p b _ (of_string "tt") (of_string "ff")⟩
  207.  
  208. def list.to_format {α : Type u} [has_to_format α] : list α → format
  209. | [] := to_fmt "[]"
  210. | xs := to_fmt "[" ++ group (nest 1 $ join $ list.intersperse ("," ++ line) $ xs^.map to_fmt) ++ to_fmt "]"
  211.  
  212. instance has_to_format_list {α : Type u} [has_to_format α] : has_to_format (list α) :=
  213. ⟨list.to_format⟩
  214.  
  215. attribute [instance] string.has_to_format
  216.  
  217. instance has_to_format_name : has_to_format name :=
  218. ⟨λ n, to_fmt (name.to_string n)⟩
  219.  
  220. instance has_to_format_unit : has_to_format unit :=
  221. ⟨λ u, to_fmt "()"⟩
  222.  
  223. instance has_to_format_option {α : Type u} [has_to_format α] : has_to_format (option α) :=
  224. ⟨λ o, option.cases_on o
  225. (to_fmt "none")
  226. (λ a, to_fmt "(some " ++ nest 6 (to_fmt a) ++ to_fmt ")")⟩
  227.  
  228. instance sum_has_to_format {α : Type u} {β : Type v} [has_to_format α] [has_to_format β] : has_to_format (sum α β) :=
  229. ⟨λ s, sum.cases_on s
  230. (λ a, to_fmt "(inl " ++ nest 5 (to_fmt a) ++ to_fmt ")")
  231. (λ b, to_fmt "(inr " ++ nest 5 (to_fmt b) ++ to_fmt ")")⟩
  232.  
  233. open prod
  234.  
  235. instance has_to_format_prod {α : Type u} {β : Type v} [has_to_format α] [has_to_format β] : has_to_format (prod α β) :=
  236. ⟨λ ⟨a, b⟩, group (nest 1 (to_fmt "(" ++ to_fmt a ++ to_fmt "," ++ line ++ to_fmt b ++ to_fmt ")"))⟩
  237.  
  238. open sigma
  239.  
  240. instance has_to_format_sigma {α : Type u} {β : α → Type v} [has_to_format α] [s : ∀ x, has_to_format (β x)]
  241. : has_to_format (sigma β) :=
  242. ⟨λ ⟨a, b⟩, group (nest 1 (to_fmt "⟨" ++ to_fmt a ++ to_fmt "," ++ line ++ to_fmt b ++ to_fmt "⟩"))⟩
  243.  
  244. open subtype
  245.  
  246. instance has_to_format_subtype {α : Type u} {p : α → Prop} [has_to_format α] : has_to_format (subtype p) :=
  247. ⟨λ s, to_fmt (val s)⟩
  248.  
  249. end hide
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement