[isabelle-dev] Constructors and the predicate compiler
Andreas Lochbihler
andreas.lochbihler at inf.ethz.ch
Mon Feb 16 10:53:59 CET 2015
Dear Florian,
I myself have never looked in detail through the implementation of the predicate compiler,
but I have been a major user. I previously noticed that it does not go well together with
code_datatype. Here are my 50 cents.
On the one hand, the predicate compiler generates code equations, so it should work
together with the code generator. On the other hand, it operates inside Isabelle/HOL, so
it does not have access to the extra-logical features of the code generator such as data
refinement. This is probably the source of the confusion. To me, it seems more sensible to
do everything as in the logic and ignore the code generator setup as much as possible.
The compilation requires that the constructors are invertible inside the logic
(code_datatype's pseudo-constructors are invertible in the generated code, but not
necessarily in the logic). Therefore, IMHO, mode inference has to use Ctr_Sugar, not
Code.is_constr. Otherwise, the compiler will later try to construct a case expression for
a code_datatype pseudo-constructur and raise an "Error in case expression: Not a datatype
constructor".
In predicate_compile_proof.ML, the generated equations are proven. The is_constructor
function is used to check whether the constructor should be inverted (using a case
expression). Since this happens inside the logic and has to be coupled with the mode
inference, it should use the same criterion as the mode inference, namely Ctr_Sugar.
I am not familiar with the flatten function in predicate_compile_fun and what exactly it
is good for. My educated guess is that this determines which of the function constants in
an (inductive) definition should be replaced with predicates and which not. If this is
right, then it should also be Ctr_Sugar there.
In summary, I'd say that code_pred should only use Ctr_Sugar and ignore code_datatype
declarations. If a user does use code_datatype, then he is responsible for providing
appropriate code equations for the existing functions, i.e., the constructors and the case
operator, or set up the code preprocessor to eliminate them (cf. the Suc eliminiation in
Code_Target_Nat and friends). Otherwise, users will have a hard time to follow what is
actually going on in code_pred.
Andreas
On 14/02/15 11:25, Florian Haftmann wrote:
> Hi all,
>
> while reviewing some technical details of code generation, I stumbled
> over a confusion in the predicate compiler regarding what a
> »constructor« is supposed to be.
>
> The presumably fundamental notions are given in predicate_compile_aux.ML
> (c3ca292c1484) as:
>
> (* check if a term contains only constructor functions *)
> (* TODO: another copy in the core! *)
> (* FIXME: constructor terms are supposed to be seen in the way the code
> generator
> sees constructors.*)
> fun is_constrt thy = … (* relying on Ctr_Sugar *)
>
> val is_constr = Code.is_constr o Proof_Context.theory_of (* relying on
> Code *)
>
> is_constrt is actually only used in predicate_compile_fun.ML:
>
> … Predicate_Compile_Aux.is_constrt …
>
> guarding whether a given term is supposed to stay »as it is«, suggesting
> that the postulating comment for is_constrt reflects actually the
> intended behaviour, leaving open the question why it has not ever been
> implemented like this.
>
> On the other hand is_constr is used in mode_inference.ML:
>
> fun is_invertible_function ctxt (Const (f, _)) = is_constr ctxt f
> | is_invertible_function ctxt _ = false
>
> and this seems odd, since a constructor in the sense of the code
> generator is by now means invertible, suggesting that here a fundamental
> misconception occurs.
>
> From such a superficial analysis it seems to follow that the two
> implementations should be actually swapped: is_constrt relying on
> Code.is_constr, is_constr relying ont Ctr_Sugar.
>
> To make the confusion perfect, in predicate_compile_proof.ML there is a
> third variant:
>
> (* returns true if t is an application of a datatype constructor *)
> (* which then consequently would be splitted *)
> fun is_constructor ctxt t =
> (case fastype_of t of
> Type (s, _) => s <> @{type_name fun} andalso can
> (Ctr_Sugar.dest_ctr ctxt s) t
> | _ => false)
>
> Can anybody acquainted with the predicate compiler shed some light on this?
>
> Cheers,
> Florian
>
>
>
> _______________________________________________
> isabelle-dev mailing list
> isabelle-dev at in.tum.de
> https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
>
More information about the isabelle-dev
mailing list