Infix relation transformer syntax in Isabelle


  rtranclp  ("(_^**)" [1000] 1000)

I can write, given an infix op ⇒

"op ⇒⇧*⇧* x x'"

but not the much more readable and prettier

"x ⇒⇧*⇧* x'"

I know that for every concrete relation (⇒ in this case), I can set up an abbreviation for this. But can I also solve this generally, i.e. for any infix relation?

If yes, can I extend that to multiple relations and other arguments? For example, given two infix relations ⇒ and ▹, and another term y I want to set it up so that I can write

x (⇒;▹)⇗y⇖ x'

(note the infix use) instead of

foo op ⇒ op ▹ y x x'

(where, in my case, has type foo :: ('a ⇒ 'a ⇒ bool) ⇒ ('a ⇒ 'b ⇒ bool) ⇒ 'b ⇒ 'a ⇒ 'a).


I believe that a general solution for all infix relations is not possible, because the parser does not know about the relation symbols in isolation. As can be seen from the implementation in mixfix.ML, an infix declaration with relation symbol < is equivalent to two mixfix declarations, namely "op <" and "(_ < _)" with appropriate precedences.

However, there is a more generic and elegant solution than to introduce abbreviations for all combinations of predicates and predicate transformers. First, introduce a syntactic category for relational symbols. To also get the right output, add a syntactic marker _infix

nonterminal rel
syntax (output) "_infix" :: "rel ⇒ logic" ("_")

Then, declare a syntax constant _rtranclp_rel for infix use with infix relations.

syntax "_rtranclp_rel" :: "logic ⇒ rel ⇒ logic ⇒ logic" ("(_ _⇧*⇧* _)")
translations "_rtranclp_rel x R y" ⇀ "CONST rtranclp R x y"
translations "_rtranclp_rel x (_infix R) y" ↽ "CONST rtranclp R x y"

Now, add a syntax translation to your relation rel that you want to use with _rtranclp_rel:

consts rel :: "nat ⇒ nat ⇒ bool" (infix "⇒" 100)

syntax "_rel_infix" :: rel ("⇒")
translations "_rel_infix" ⇀ "CONST rel"
translations "_rel_infix" ↽ "_infix (CONST rel)"

Then, Isabelle should be able to correctly parse and pretty-print x ⇒⇧*⇧* z. Note, however, that all fully applied instances of rtranclp are pretty-printed infix (e.g., rtranclp R x y, independent of whether the relation is an infix symbol.

This mechanism then also works for your function foo:

consts foo :: "('a ⇒ 'a ⇒ bool) ⇒ ('b ⇒ 'b ⇒ bool) ⇒ 'b ⇒ 'a ⇒ 'a ⇒ bool"

syntax "_foo_rel" :: "logic ⇒ rel ⇒ rel ⇒ logic ⇒ logic ⇒ logic" ("_ '(_;_')⇗_⇖ _")
translations "_foo_rel x R S y z" ⇀ "CONST foo R S x y z"
translations "_foo_rel x (_infix R) (_infix S) y z" ↽ "CONST foo R S x y z"

Of course, the precedences in the mixfix annotations should be adjusted to sensible ones. It is even possible to do this recursively. For example:

syntax "_rtranclp_rel2" :: "rel ⇒ rel" ("_⇧*⇧*")
translations "_rtranclp_rel2 R" ⇀ "CONST rtranclp R"
translations "_rtranclp_rel2 (_infix R)" ↽ "_infix (CONST rtranclp R)"

term "x (⇒⇧*⇧*;⇒)⇗y⇖ z"

Need Your Help

Custom ordering in Rails query

ruby-on-rails ruby-on-rails-3 postgresql activerecord

I have a Post model with some has_many associations.

How to put arguments in a function at run time?

c++ linux runtime exec argument-passing

So I am using execlp in my c++ program. execlp is of the form " int execlp(const char *file, const char *arg0,...,const char *argn)" meaning that it can take arbitrary amount of arguments. I just w...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.