3 <!-- Copyright (C) 2000, HELM Team -->
5 <!-- This file is part of HELM, an Hypertextual, Electronic -->
6 <!-- Library of Mathematics, developed at the Computer Science -->
7 <!-- Department, University of Bologna, Italy. -->
9 <!-- HELM is free software; you can redistribute it and/or -->
10 <!-- modify it under the terms of the GNU General Public License -->
11 <!-- as published by the Free Software Foundation; either version 2 -->
12 <!-- of the License, or (at your option) any later version. -->
14 <!-- HELM is distributed in the hope that it will be useful, -->
15 <!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
16 <!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
17 <!-- GNU General Public License for more details. -->
19 <!-- You should have received a copy of the GNU General Public License -->
20 <!-- along with HELM; if not, write to the Free Software -->
21 <!-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, -->
22 <!-- MA 02111-1307, USA. -->
24 <!-- For details, see the HELM World-Wide-Web page, -->
25 <!-- http://cs.unibo.it/helm/. -->
27 <!--******************************************************************-->
28 <!-- XSLT version 0.1 of CIC inductive objects to MathML content: -->
29 <!-- First draft: March 2001, Andrea asperti -->
30 <!--******************************************************************-->
33 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
34 xmlns:m="http://www.w3.org/1998/Math/MathML"
35 xmlns:helm="http://www.cs.unibo.it/helm">
38 <xsl:template mode="inductive" match="APPLY">
39 <xsl:param name="inductive_def_uri" select="''"/>
40 <xsl:param name="inductive_def" select="/.."/>
41 <xsl:param name="inductive_def_index" select="1"/>
42 <xsl:param name="inductive_def_name" select="''"/>
43 <xsl:param name="section_params" select="0"/>
44 <!-- expected_args_type contains the types of the arguments expected by
45 the induction principle -->
46 <xsl:variable name="expected_args_types"
47 select="document(concat(string($absPath),*[1]/@uri))/Definition/type//PROD[not(ancestor::source)]/source/*[1]"/>
48 <xsl:variable name="no_expected_args" select="count($expected_args_types)"/>
49 <xsl:variable name="actual_arguments" select="*[position()>(1+$section_params)]"/>
50 <!-- First check that the induction principle is applied to the
51 expected number of arguments -->
53 <xsl:when test="$no_expected_args = count($actual_arguments)">
54 <!-- Now check that each actual argument starts with the
55 expected number of lambda abstractions -->
56 <xsl:variable name="argsOK">
57 <xsl:call-template name="check_args">
58 <xsl:with-param name="arg_types" select="$expected_args_types"/>
59 <xsl:with-param name="actual_args" select="$actual_arguments"/>
63 <!-- il semplice test $argsOK non funziona -->
64 <xsl:when test="string($argsOK) = 'true'">
65 <!-- arguments are in the expected form: we create a
66 "by_induction" content element -->
67 <!-- no_params is the number of paramters in square brackets -->
68 <xsl:variable name="no_params"
69 select="$inductive_def/@noParams"/>
70 <!-- the inductive property is the first argument following
72 <xsl:variable name="inductive_property"
73 select="$actual_arguments[1 + $no_params]"/>
74 <xsl:variable name="tail_args"
75 select="$actual_arguments[position()> (1 + $no_params)]"/>
76 <!-- inductive_type contains the right inductive type in the
77 mutual inductive definition -->
78 <xsl:variable name="inductive_type"
79 select="$inductive_def/InductiveType[position()=$inductive_def_index]"/>
80 <xsl:variable name="no_constructors"
81 select="count($inductive_type/Constructor)"/>
82 <!-- each case has a single argument -->
83 <xsl:variable name="args_for_cases"
84 select="$tail_args[($no_constructors + 1) > position()]"/>
85 <!-- extra_args contains the remaining arguments; the LAST one
86 of them is the argument we are inductively arguing on -->
87 <xsl:variable name="extra_args"
88 select="$tail_args[position()> $no_constructors]"/>
90 <m:csymbol>by_induction</m:csymbol>
91 <!-- the first (i.e. second) argument of by_induction
92 is the uri of the inductive definition -->
93 <m:ci><xsl:value-of select="$inductive_def_uri"/></m:ci>
94 <!-- next, we have the inductive property, currently not
95 used for rendering (it could be omitted??) -->
96 <xsl:apply-templates mode="pure" select="$inductive_property"/>
97 <!-- each case has its own "inductive_case" element -->
98 <!-- the inductive case element is composed by:
99 * "case_lhs" element, containing the constructor name applied
100 to its arguments. The arguments are abstraction variables
101 (with types) got form the initial lambdas of the argument
103 * "induction_hypothesis" element, containg the induction
104 hypothesis. Again, these are abstraction variables
105 (with types) got form the initial lambdas of the argument
107 * body of the case, without specific markup.
109 <xsl:for-each select="$inductive_type/Constructor">
110 <xsl:variable name="pos" select="position()"/>
111 <xsl:variable name="current_arg"
112 select="$args_for_cases[position()=$pos]"/>
114 <m:csymbol>inductive_case</m:csymbol>
116 <m:csymbol>case_lhs</m:csymbol>
117 <m:ci definitionURL="{$inductive_def_uri}">
118 <xsl:value-of select="@name"/>
120 <xsl:call-template name="get_constructor_args">
121 <xsl:with-param name="no_params"
122 select="$no_params"/>
123 <xsl:with-param name="constructor_arity"
125 <xsl:with-param name="actual_arg"
126 select="$current_arg"/>
127 <xsl:with-param name="inductive_def_name"
128 select="$inductive_def_name"/>
132 <m:csymbol>induction_hypothesis</m:csymbol>
133 <xsl:call-template name="get_induction_hypothesis">
134 <xsl:with-param name="no_params"
135 select="$no_params"/>
136 <xsl:with-param name="constructor_arity"
138 <xsl:with-param name="actual_arg"
139 select="$current_arg"/>
140 <xsl:with-param name="inductive_def_name"
141 select="$inductive_def_name"/>
144 <xsl:call-template name="get_body">
145 <xsl:with-param name="no_params"
146 select="$no_params"/>
147 <xsl:with-param name="constructor_arity"
149 <xsl:with-param name="actual_arg" select="$current_arg"/>
150 <xsl:with-param name="inductive_def_name"
151 select="$inductive_def_name"/>
155 <!-- the inductive argument is the last argument of extra-args -->
157 <m:csymbol>extra_args</m:csymbol>
158 <xsl:apply-templates mode="pure" select="$extra_args"/>
163 <xsl:apply-templates mode="letin" select="."/>
168 <xsl:apply-templates mode="letin" select="."/>
173 <!-- check_args checks that the number of lambda abstractions
174 of each actual parameter is GREATER OR EQUAL to the number
175 or products of the corresponding formal parameter of the
176 induction principles. That is, that each argument is
177 sufficiently eta-expanded.
178 If this is not the case, not good rendering looks possible.
179 Check_args returns a boolean.
181 <xsl:template name="check_args">
182 <xsl:param name="arg_types" select="/.."/>
183 <xsl:param name="actual_args" select="/.."/>
184 <xsl:param name="bool_var" select="true()"/>
186 <xsl:when test="count($arg_types) = 0">
187 <xsl:value-of select="$bool_var"/>
190 <xsl:variable name="no_expected_arg_of_arg">
191 <xsl:apply-templates mode="count_arity" select="$arg_types[1]">
192 <xsl:with-param name="what" select="'PROD'"/>
193 </xsl:apply-templates>
195 <xsl:variable name="no_actual_abst_of_arg">
196 <xsl:apply-templates mode="count_arity" select="$actual_args[1]">
197 <xsl:with-param name="what" select="'LAMBDA'"/>
198 </xsl:apply-templates>
200 <!-- REPLACE WITH EQUALITY ???? -->
201 <xsl:variable name="test_arg"
202 select="$no_actual_abst_of_arg >= $no_expected_arg_of_arg"/>
203 <xsl:call-template name="check_args">
204 <xsl:with-param name="arg_types" select="$arg_types[position()>1]"/>
205 <xsl:with-param name="actual_args" select="$actual_args[position()>1]"/>
206 <xsl:with-param name="bool_var" select="($bool_var and $test_arg)"/>
212 <!-- count_arity counts the number of head lambda (or prod) -->
213 <xsl:template mode="count_arity" match="*">
214 <xsl:param name="what" select="'LAMBDA'"/>
215 <xsl:param name="num" select="0"/>
216 <!-- MANCANO I CAST ??? -->
218 <xsl:when test="name(.) = $what">
219 <xsl:apply-templates mode="count_arity" select="target/*[1]">
220 <xsl:with-param name="what" select="$what"/>
221 <xsl:with-param name="num" select="$num+1"/>
222 </xsl:apply-templates>
225 <xsl:value-of select="$num"/>
230 <!-- The following three functions are essentially identical
231 in their recursive structure.
232 The problem is that of decomposing an actual argument for
233 a case in three parts:
234 * constructor variables
235 * induction hypothesis
237 To this aim we must proceed in parallel with the type of
238 the constructor: if the type contains a prod, then the
239 the corresponding lambda of the argument provides the
240 constructor variable. Moreover, if the source type of the
241 prod contains a reference to the inductive type, it is a
242 recursive argument and the NEXT lambda of the argument
243 provides an induction hypothesis.
244 Unfortunately the three functions cannot be merged into a
245 single one without a conversion from document tree fragments
248 <xsl:template name="get_constructor_args">
249 <xsl:param name="no_params" select="0"/>
250 <xsl:param name="constructor_arity" select="/.."/>
251 <xsl:param name="actual_arg" select="/.."/>
252 <xsl:param name="inductive_def_name" select="''"/>
254 <xsl:when test="$no_params = 0">
255 <xsl:if test="name($constructor_arity)='PROD'">
257 <m:ci><xsl:value-of select="$actual_arg/target/@binder"/></m:ci>
259 <xsl:apply-templates mode="pure" select="$actual_arg/source/*[1]"/>
263 <xsl:when test="$constructor_arity/source//REL[@binder=$inductive_def_name]">
264 <xsl:call-template name="get_constructor_args">
265 <xsl:with-param name="constructor_arity"
266 select="$constructor_arity/target/*[1]"/>
267 <xsl:with-param name="actual_arg"
268 select="$actual_arg/target/LAMBDA/target/*[1]"/>
269 <xsl:with-param name="inductive_def_name"
270 select="$inductive_def_name"/>
274 <xsl:call-template name="get_constructor_args">
275 <xsl:with-param name="constructor_arity"
276 select="$constructor_arity/target/*[1]"/>
277 <xsl:with-param name="actual_arg"
278 select="$actual_arg/target/*[1]"/>
279 <xsl:with-param name="inductive_def_name"
280 select="$inductive_def_name"/>
287 <xsl:call-template name="get_constructor_args">
288 <xsl:with-param name="no_params" select="$no_params - 1"/>
289 <xsl:with-param name="constructor_arity"
290 select="$constructor_arity/target/*[1]"/>
291 <xsl:with-param name="actual_arg"
292 select="$actual_arg"/>
293 <xsl:with-param name="inductive_def_name"
294 select="$inductive_def_name"/>
300 <xsl:template name="get_induction_hypothesis">
301 <xsl:param name="no_params" select="0"/>
302 <xsl:param name="constructor_arity" select="/.."/>
303 <xsl:param name="actual_arg" select="/.."/>
304 <xsl:param name="inductive_def_name" select="''"/>
306 <xsl:when test="$no_params = 0">
307 <xsl:if test="name($constructor_arity)='PROD'">
309 <xsl:when test="$constructor_arity/source//REL[@binder=$inductive_def_name]">
312 <xsl:value-of select="$actual_arg/target/LAMBDA/target/@binder"/>
315 <xsl:apply-templates mode="pure"
316 select="$actual_arg/target/LAMBDA/source"/>
319 <xsl:call-template name="get_induction_hypothesis">
320 <xsl:with-param name="constructor_arity"
321 select="$constructor_arity/target/*[1]"/>
322 <xsl:with-param name="actual_arg"
323 select="$actual_arg/target/LAMBDA/target/*[1]"/>
324 <xsl:with-param name="inductive_def_name"
325 select="$inductive_def_name"/>
329 <xsl:call-template name="get_induction_hypothesis">
330 <xsl:with-param name="constructor_arity"
331 select="$constructor_arity/target/*[1]"/>
332 <xsl:with-param name="actual_arg"
333 select="$actual_arg/target/*[1]"/>
334 <xsl:with-param name="inductive_def_name"
335 select="$inductive_def_name"/>
342 <xsl:call-template name="get_induction_hypothesis">
343 <xsl:with-param name="no_params" select="$no_params - 1"/>
344 <xsl:with-param name="constructor_arity"
345 select="$constructor_arity/target/*[1]"/>
346 <xsl:with-param name="actual_arg"
347 select="$actual_arg"/>
348 <xsl:with-param name="inductive_def_name"
349 select="$inductive_def_name"/>
355 <xsl:template name="get_body">
356 <xsl:param name="no_params" select="0"/>
357 <xsl:param name="constructor_arity" select="/.."/>
358 <xsl:param name="actual_arg" select="/.."/>
359 <xsl:param name="inductive_def_name" select="''"/>
361 <xsl:when test="$no_params = 0">
363 <xsl:when test="name($constructor_arity)='PROD'">
365 <xsl:when test="$constructor_arity/source//REL[@binder=$inductive_def_name]">
366 <xsl:call-template name="get_body">
367 <xsl:with-param name="constructor_arity"
368 select="$constructor_arity/target/*[1]"/>
369 <xsl:with-param name="actual_arg"
370 select="$actual_arg/target/LAMBDA/target/*[1]"/>
371 <xsl:with-param name="inductive_def_name"
372 select="$inductive_def_name"/>
376 <xsl:call-template name="get_body">
377 <xsl:with-param name="constructor_arity"
378 select="$constructor_arity/target/*[1]"/>
379 <xsl:with-param name="actual_arg"
380 select="$actual_arg/target/*[1]"/>
381 <xsl:with-param name="inductive_def_name"
382 select="$inductive_def_name"/>
388 <xsl:apply-templates mode="noannot" select="$actual_arg"/>
393 <xsl:call-template name="get_body">
394 <xsl:with-param name="no_params" select="$no_params - 1"/>
395 <xsl:with-param name="constructor_arity"
396 select="$constructor_arity/target/*[1]"/>
397 <xsl:with-param name="actual_arg"
398 select="$actual_arg"/>
399 <xsl:with-param name="inductive_def_name"
400 select="$inductive_def_name"/>