Parse.overload_on : string * term -> unit
Finally, when printing, this call causes tm to be seen as the operator name. The string name may prompt further pretty-printing if it is involved in any of the relevant grammar's rules for concrete syntax.
- val inter = new_definition("inter", Term`inter p q x = p x /\ q x`);
<<HOL message: inventing new type variable names: 'a.>>
> val inter = |- !p q x. inter p q x = p x /\ q x : thm
We overload on our new intersection constant, and can
be sure that in ambiguous situations, it will be preferred:
- overload_on ("/\\", Term`inter`);
<<HOL message: inventing new type variable names: 'a.>>
> val it = () : unit
- Term`p /\ q`;
<<HOL message: more than one resolution of overloading was possible.>>
<<HOL message: inventing new type variable names: 'a.>>
> val it = `p /\ q` : term
- type_of it;
> val it = `:'a -> bool` : hol_type
Note that the original constant is considered overloaded to
itself, so that our one call to overload_on now allows for two
possibilities whenever the identifier /\ is seen. In order to make
normal conjunction the preferred choice, we can call overload_on
with the original constant:
- overload_on ("/\\", Term`bool$/\`);
> val it = () : unit
- Term`p /\ q`;
<<HOL message: more than one resolution of overloading was possible.>>
> val it = `p /\ q` : term
- type_of it;
> val it = `:bool` : hol_type
Note that in order to specify the original conjunction
constant, we used the qualified identifier syntax, with the $. If
we'd used just /\, the overloading would have ensured that this was
parsed as inter. Instead of the qualified identifier syntax, we
could have also constrained the type of conjunction explicitly so that
the original constant would be the only possibility. Thus:
- overload_on ("/\\", Term`/\ :bool->bool->bool`);
> val it = () : unit