Theory MkTermAntiquote_Tests
text ‹
‹mk_term›: ML antiquotation for building and splicing terms.
›
theory MkTermAntiquote_Tests
imports
MkTermAntiquote
Main
begin
text ‹
Basic usage: ‹@{mk_term "pattern..." (vars, ...)} (args, ...)›
The vars should match schematic vars in the pattern, and they
are substituted with the given arguments.
Template vars can include type vars, and they should be applied
to type arguments.
›
ML_val ‹
@{assert} (@{mk_term "?x" (x)} @{term "x::'a"}
= @{term "x::'a"});
@{assert} (@{mk_term "0::'a::zero" ('a)} @{typ "nat"}
= @{term "0::nat"});
@{assert} (@{mk_term "?xs @ ?ys" (ys, xs)} (@{term "[True]"}, @{term "[False]"})
= @{term "[False] @ [True]"});
›
text ‹
Note that ‹mk_term› does not perform full type inference automatically.
If some argument types are mismatched or too general, the output may
be inconsistent. This may change in future versions.
›
ML_val ‹
@{assert} (@{mk_term "?x = ?y" (x, y)} (@{term "0::'a::zero"}, @{term "Suc 0"})
= (Const (@{const_name HOL.eq}, @{typ "'a::zero ⇒ 'a ⇒ bool"}) $
@{term "0::'a::zero"} $ @{term "Suc 0"}))
›
text ‹
Besides static checking, using ‹mk_term› also gives a reusable template:
›
ML_val ‹
let
val mk_pair: term*term -> term = @{mk_term "(?a, ?b)" (a, b)};
in
@{assert} (mk_pair (@{term "()"}, @{term "True"}) = @{term "((), True)"});
@{assert} (mk_pair (@{term "int 1"}, @{term "int 2"})
= @{term "(int 1, int 2)"})
end;
›
end