0

I am attempting to generate a nice syntax for mapping a function over the values of an associative list, i.e. I want to write [x ↦ f y | (x ↦ y) ∈ l] for mapAList f l. I came up with

syntax
 "_alist_map" :: "['b, pttrn, ('a × 'b) list] ⇒ ('a × 'b) list"
 ("[x ↦ _ | '(x ↦ _') ∈ _]")

which works, but causes term "(x,y)#[]" to tell me Inner syntax error at "(x , y ) # []" and the (x is shaded slightly different.

The reason seems that once x appears in a mixfix annotation, it now always a literal token to the grammer (a delimiter according to §7.4.1 of isar-ref) and no longer an identifier – just like the syntax for if ... then ... else ... prevents if from being a variable name

Can I somehow work around this problem?

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
  • Just out of curiosity, does `mapAList` only map `f` over the *values* of `l` (i.e., the 2nd components of pairs)? It seems that the syntax is more cumbersome to type than just writing the function application ;) Do you have an example where readability is actually improved (I'm aware that this is highly subjective). – chris Apr 25 '14 at 12:49
  • The function `f` in my application is written with special sytnax itself, i.e. `[| x |]`, and `map (λx. [| x |])` is not as readable as `[x ↦ [| y |] | (x ↦ y) ∈ l]` – Joachim Breitner Apr 25 '14 at 13:29

2 Answers2

2

Identifier names used in mixfix annotations cannot be used as identifiers any longer, and I don't know any way around that. Therefore, instead of using x as a variable name, you can pick a non-identifier symbol like \<xX> or \<mapAListvariable> and setup the LaTeX output to print this as x by adding \newcommand{\isasymmapAListvariable}{x} to your root.tex.

You can also add \<xX> or \<mapAListvariable> to the symbols file of Isabelle/JEdit (preferably in $ISABELLE_HOME_USER/etc/symbols) and assign it some Unicode point that will be used for display in Isabelle/JEdit.

Andreas Lochbihler
  • 4,998
  • 12
  • 10
1

I just made a small experiment with a function map_alist that hopefully corresponds to your mapAList and which is defined as follows:

fun map_alist :: "('b ⇒ 'c) ⇒ ('a × 'b) list ⇒ ('a × 'c) list"
where
  "map_alist f [] = []" |
  "map_alist f ((x, y) # xs) = (x, f y) # map_alist f xs"

Then existing syntax can be used which looks a little bit as you intended. Maybe this is an option?

lemma "map_alist f xs = [(x, f y). (x, y) ← xs]"
  by (induct xs) auto
chris
  • 4,988
  • 20
  • 36