Printing of dummy terms in syntax translations
Lukas Stevens
lukas.stevens+isabelle-users at in.tum.de
Tue Jul 7 13:09:51 CEST 2026
Dear Isabelle developers,
I am working on the type annotation algorithm in
~~/src/HOL/Tools/Sledgehammer/sledgehammer_isar_annotate.ML that is used
by some interactive tools, e.g., Sledgehammer and Sketch and Explore.
The algorithm places type annotations in terms such that printing and
then parsing them again yields a term with the same type as the original
term. This is crucial when trying to output well-formed Isar proofs.
While testing the algorithm, I ran into some unfortunate behavior that
results from the interaction of Syntax_Trans.atomic_abs_tr' and the
syntax translation case_prod_tr'/case_prod_guess_names_tr' in
Product_Type.thy. You can observe this behavior in
Isabelle/333ffbe82f5f, where
term "λ_. 1 :: nat"
yields "λ_. 1" :: "'a ⇒ nat" while
term "λ(x, _). 1 :: nat"
gives "λ(x, uu_). 1" :: "'a × 'b ⇒ nat", which contains an internal
variable uu_. The latter term cannot be parsed after printing it due to
the internal variable. Note that the same behavior surfaces for other
users of Syntax_Trans.atomic_abs_tr' such as the translations for SOME
and set comprehensions.
The reason for the first term being printed without internal variables
is the changeset Isabelle/41986849fee0 that adds support for the syntax
constant _idtdummy (printed as _) to Syntax_Trans.abs_tr'/mk_binder_tr';
however, case_prod_tr'/case_prod_guess_names_tr' internally uses
Syntax_Trans.atomic_abs_tr', which has no support for _idtdummy. This
could be changed by a 4-line modification of Syntax_Trans.atomic_abs_tr'
(see attached diff), which produces the right result on the surface,
although I am not sure if there is any collateral.
Anecdotally, I know that users of Sketch and Explore have stumbled over
this behavior.
Cheers,
Lukas
-------------- next part --------------
diff -r 2300745395fc src/Pure/Syntax/syntax_trans.ML
--- a/src/Pure/Syntax/syntax_trans.ML Wed Jul 01 12:27:01 2026 +0100
+++ b/src/Pure/Syntax/syntax_trans.ML Tue Jul 07 11:43:26 2026 +0200
@@ -345,8 +345,11 @@
(strip_abss ctxt strip_abs_vars strip_abs_body (eta_contr ctxt tm));
fun atomic_abs_tr' ctxt (x, T, t) =
- let val xT = singleton (variant_bounds ctxt t) (x, T)
- in (mark_bound_abs xT, subst_bound (mark_bound_body xT, t)) end;
+ if Name.is_internal x andalso not (Term.is_dependent t) then
+ (Const ("_idtdummy", T), incr_boundvars ~1 t)
+ else
+ let val xT = singleton (variant_bounds ctxt t) (x, T)
+ in (mark_bound_abs xT, subst_bound (mark_bound_body xT, t)) end;
fun abs_ast_tr' asts =
(case Ast.unfold_ast_p "_abs" (Ast.Appl (Ast.Constant "_abs" :: asts)) of
More information about the isabelle-dev
mailing list