rules.tex 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. In this section we present the type checking algorithm for {\Core} with meta-variables.
  2. First we extend
  3. the syntax of signatures to include guarded constants and add a new syntactic
  4. category for user expressions:
  5. {\small
  6. \[\begin{array}{lcll}
  7. C & ::= & \TypeConstr A B \Or \TermConstr M N A \Or
  8. \TermConstr {\bar M} {\bar N} \Delta \\
  9. \Sigma & ::= & \ldots \Or
  10. \Ext \Sigma \ConstDecl p A M \Cs \\
  11. e & ::= & \LAM xe \Or x\,\bar e \Or c\,\bar e \Or \SET \Or \PI xee \Or ? \\
  12. \end{array}\]
  13. }
  14. The input to the type checking algorithm is a user expression which could
  15. represent either a type or a term. Apart from the usual constructions user
  16. expressions can also contain $?$ representing a meta-variable. During type
  17. checking user expressions are translated into {\Core} terms where
  18. meta-variables are represented as fresh constants. Note that since we have
  19. domain free lambda abstractions we cannot type check $\beta$-redexes. Hence the
  20. syntax of user expressions disallows them.
  21. A constraint $C$ is an equality constraint that has been postponed
  22. because not enough information was available about the meta-variables. Since
  23. our conversion checking algorithm is typed the constraints must also be typed. The
  24. constraints show up in the signature as guards to guarded constants. We write
  25. $\ConstDecl p A M \Cs$ for a guarded constant $p$ of type $A$ and value $M$
  26. guarded by the set of constraints $\Cs$. We have the computation rule that $p$
  27. computes to $M$ when $\Cs$ is the empty set.
  28. We use the naming convention that lowercase greek letters $\alpha, \beta,
  29. \ldots$ stand for constants representing meta-variables and $p$ and $q$ for
  30. guarded constants.
  31. \subsection{Operations on the signature}
  32. All rules work on a signature $\Sigma$, containing previously defined
  33. constants, meta-variables, and guarded constants.
  34. %
  35. In other words we can write all judgements on the form
  36. \(\ExplicitJudgement \Sigma J {\Sigma'}\).
  37. %
  38. To make the rules easier to read we first define a set of operations reading
  39. and modifying the signature and when presenting the algorithm simply write $J$
  40. for the judgement above. In rules with multiple premisses the signature is
  41. threaded top-down, left-to-right. % For instance,
  42. % \[\begin{array}{ccc}
  43. % {\small\begin{array}[c]{l}
  44. % \infer{J}
  45. % {\begin{array}[b]{l}
  46. % P_1
  47. % \\ P_2
  48. % \end{array}
  49. % & P_3
  50. % }
  51. % \end{array}}
  52. % & ~\mbox{is short-hand for}~
  53. % &
  54. % {\small\begin{array}[c]{l}
  55. % \infer{\ExplicitJudgement {\Sigma_1} J {\Sigma_4}}
  56. % {\begin{array}[b]{l}
  57. % \ExplicitJudgement {\Sigma_1} {P_1} {\Sigma_2}
  58. % \\ \ExplicitJudgement {\Sigma_2} {P_2} {\Sigma_3}
  59. % \end{array}
  60. % & \ExplicitJudgement {\Sigma_3} {P_3} {\Sigma_4}
  61. % }
  62. % \end{array}}
  63. % \end{array}\]
  64. \begin{figure}
  65. \begin{tabular}{llll}
  66. % \multicolumn2l{Operations on meta-variables} \\
  67. & $\ExplicitJudgement \Sigma
  68. {\AddMeta \alpha A}
  69. {\Ext \Sigma \MetaDecl \alpha A}
  70. $ & if & $\alpha \notin \Sigma$
  71. \\
  72. & $\ExplicitJudgement
  73. \Sigma
  74. {\InstMeta \alpha M}
  75. {\Ext {\Sigma_1} \Ext {\IMetaDecl \alpha A M} \Sigma_2}
  76. $ & if & $\Sigma ~=~ \Ext {\Sigma_1} \Ext {\MetaDecl \alpha A} \Sigma_2$
  77. % \\
  78. % & $\ExplicitJudgement
  79. % \Sigma
  80. % {\LookupMeta \alpha M}
  81. % \Sigma
  82. % $ & if & $\IMetaDecl \alpha A M ~\in~ \Sigma$
  83. % \\
  84. % & $\ExplicitJudgement
  85. % \Sigma
  86. % {\Uninstantiated \alpha}
  87. % \Sigma
  88. % $ & if & $\MetaDecl \alpha A ~\in~ \Sigma$
  89. \\ {} \\
  90. % \multicolumn2l{Operations on guarded constants} \\
  91. & \multicolumn3l{$\ExplicitJudgement
  92. \Sigma
  93. {\AddConst p A M \Cs}
  94. {\Ext \Sigma \ConstDecl p A M \Cs}
  95. $} \\
  96. & & if & $p \notin \Sigma$
  97. % \\
  98. % & \multicolumn3l{$\ExplicitJudgement
  99. % \Sigma
  100. % {\UpdateGuard p \Cs}
  101. % {\Ext {\Sigma_1} \Ext {\ConstDecl p A M \Cs} \Sigma_2}
  102. % $} \\
  103. % & & if & $\Sigma ~=~ \Ext {\Sigma_1} \Ext {\ConstDecl p A M \Cs^\prime} \Sigma_2$
  104. % \\
  105. % & $\ExplicitJudgement
  106. % \Sigma
  107. % {\LookupConst p M}
  108. % \Sigma
  109. % $ & if & $\ConstDecl p A M \emptyset ~\in~ \Sigma$
  110. % \\
  111. % & $\ExplicitJudgement
  112. % \Sigma
  113. % {\Guarded p}
  114. % \Sigma
  115. % $ & if & $\ConstDecl p A M \Cs ~\in~ \Sigma$ and $\Cs \neq \emptyset$
  116. \\ {} \\
  117. % \multicolumn2l{General operations} \\
  118. % & $\ExplicitJudgement
  119. % \Sigma
  120. % {\LookupType c A}
  121. % \Sigma
  122. % $ & if & $c : A \in \Sigma$
  123. % \\
  124. & $\ExplicitJudgement
  125. \Sigma
  126. {\InScope \alpha M}
  127. \Sigma
  128. $ & if & $\begin{array}[t]{ll}
  129. \Sigma ~=~ \Ext {\Sigma_1} \Ext {\MetaDecl \alpha A} \Sigma_2 ~~ \mbox{and}
  130. \\ c \in M ~~ \mbox{implies} ~~ c \in \Sigma_1
  131. % \\ \IsTypeCS {\Sigma_1} {} A ~~ \mbox{and} ~~ \HasTypeCS \Sigma {} M A ~~ \mbox{implies}
  132. % \\ \HasTypeCS {\Sigma_1} {} M A
  133. \end{array}$
  134. \\
  135. % & $\ExplicitJudgement
  136. % \Sigma
  137. % {\WithSig {\Sigma'} J}
  138. % {\Sigma''}
  139. % $ & if & $\ExplicitJudgement
  140. % {\Sigma'}
  141. % J
  142. % {\Sigma''}
  143. % $ \\
  144. \end{tabular}
  145. \caption{Operations on the signature}
  146. \label{figOperations}
  147. \end{figure}
  148. We introduce two operations to manipulate meta-variables: \\ $\AddMeta \alpha A$
  149. adds a new meta-variable $\alpha$ of type $A$ to the signature, and $\InstMeta
  150. \alpha M$ instantiates $\alpha$ to $M$.
  151. %
  152. %% Never used
  153. % $\LookupMeta \alpha M$ looks up the
  154. % value of an instantiated meta-variable, and $\Uninstantiated \alpha$ verifies
  155. % that $\alpha$ is uninstantiated.
  156. %
  157. For guarded constants we just add the operation $\AddConst p A M \Cs$ to add a
  158. new guarded constant to the signature. In Section~\ref{secAlgorithm} we
  159. explain the rules for solving the constraints of a guarded constant.
  160. %
  161. % , $\UpdateGuard p \Cs$ to update the guard of $p$,
  162. % $\LookupConst p M$ to get the value of a guarded constant whose guard has been
  163. % solved, and $\Guarded p$ to verify that the guard of $p$ has not been solved.
  164. %
  165. We also introduce an operation $\InScope \alpha M$ to check that $M$ is in
  166. scope at the definition site of $\alpha$ (to ensure that $\alpha$ can be
  167. instantiated to $M$).
  168. %
  169. %, and $\WithSig \Sigma J$ which checks $J$ in the signature $\Sigma$.
  170. %
  171. Detailed definitions of the operations can be found in
  172. Figure~\ref{figOperations}.
  173. \subsection{The algorithm} \label{secAlgorithm}
  174. Next we present the type checking algorithm. We use a bidirectional algorithm,
  175. consisting of the following main judgement forms.
  176. {\small
  177. \[\begin{array}{lcl}
  178. \IsType e A && \mbox{well-formed types} \\
  179. \CheckType e A M && \mbox{type checking} \\
  180. \InferType e A M && \mbox{type inference} \\
  181. \EqualType A B \Cs && \mbox{type conversion} \\
  182. \Equal M N A \Cs &~& \mbox{term conversion} \\
  183. \end{array}\]
  184. }
  185. The rules for well-formed types and type checking and inference take a user
  186. expression and produce a type or term in {\Core} which is a
  187. well-typed approximation of the user expression. Conversion checking produces
  188. a set of unsolved constraints which needs to be solved for the judgement to be
  189. true in {\Core}.
  190. We use typed conversion for two reasons: it is a nice way to implement
  191. $\eta$-equality, and perhaps more importantly to prove the correctness of the
  192. algorithm we need the invariant that when checking $\Equal M N A \Cs$ we have
  193. $\HasTypeC \Gamma M A$ and $\HasTypeC \Gamma N A$, so we need to record the
  194. type to make sure the invariant is preserved.
  195. When checking conversion we also need the following judgement forms.
  196. {\small
  197. \[\begin{array}{lcl}
  198. \EqualWhnf M N A \Cs &~& \mbox{conversion of weak head normal forms} \\
  199. \Equal {\bar M} {\bar N} \Delta \Cs &~& \mbox{conversion of sequences of terms} \\
  200. \end{array}\]
  201. }
  202. Type checking with dependent types involves normalising arbitrary (type
  203. correct) terms, so we need to know how to normalise terms in a signature
  204. containing meta-variables and guarded constants. We do this by translating the
  205. signature to {\Core} and performing the normalisation in {\Core}.
  206. \begin{definition}
  207. Given a signature $\Sigma$ containing meta-variables and guarded constants
  208. we define its {\Core} restriction $\CoreSig \Sigma$ by replacing
  209. guarded constants with normal constants, replacing $\ConstDecl p A M \Cs$
  210. by $p : A = M$ if $\Cs$ is empty, and $p : A$ otherwise.
  211. \end{definition}
  212. The correctness of the type checking algorithm relies on the invariant that
  213. when $\ExplicitJudgement \Sigma {\CheckType e A M} {\Sigma'}$, we have
  214. $\HasTypeCS {\CoreSig {\Sigma'}} \Gamma M A$ (see Theorem~\ref{thmSoundNoCs}).
  215. We write $\ExplicitJudgement \Sigma {\whnf M {M'}} \Sigma$ if $M'$ is the weak
  216. head normal form of $M$ in $\CoreSig \Sigma$. Similarly $\Normalise M {M'}$
  217. means that $M'$ is the normal form of $M$.
  218. \subsubsection{Type checking rules}
  219. To save some space we omit the rules for checking well-formed types and most of
  220. the rules for type checking and inference. The rules are simple extensions of
  221. standard type checking algorithms to produce well-typed terms. The interesting
  222. type checking rules are the rule for type checking meta-variables and the
  223. conversion rules.
  224. \URules{
  225. \infer{ \CheckType {?} A {\alpha \, \Gamma }}
  226. {\begin{array}{l}
  227. \AddMeta \alpha {\Gamma \to A}
  228. \end{array}}
  229. \quad
  230. \infer{
  231. \CheckType e A M
  232. }{\begin{array}{l}
  233. \InferType e B M
  234. \\ \EqualType A B \emptyset
  235. \end{array}}
  236. \quad
  237. \infer{
  238. \CheckType e A {p\,\Gamma}
  239. }{\begin{array}{l}
  240. \InferType e B M
  241. \\ \EqualType A B \Cs \neq \emptyset
  242. \\ \AddConst p {\Gamma \to A} {\LAM \Gamma M} \Cs
  243. \end{array}}
  244. }
  245. When type checking a user meta-variable we create a fresh meta-variable, add it
  246. to the signature and return it. Since meta-variables are part of the signature
  247. they have to be lifted to the top-level.
  248. We have two versions of the conversion rule. The first corresponds to the
  249. normal conversion rule and applies when no constraints are generated. The
  250. interesting case is when we cannot safely conclude that $A = B$, in which case
  251. we introduce a fresh guarded constant. As meta-variables, guarded constants
  252. are lifted to the top-level.
  253. \subsubsection{Conversion rules}
  254. When checking conversion of two function types, an interesting question is what
  255. to do when comparing the domains gives rise to constraints. The rule in question is
  256. \URules{
  257. % (x : A) -> B = (x : A') -> B'
  258. \infer{
  259. \EqualType {\PI x {A_1} {B_1}} {\PI x {A_2} {B_2}} {\Cs \cup \Cs^\prime}
  260. }{\begin{array}{l}
  261. \EqualType {A_1} {A_2} \Cs, ~~ \Cs \neq \emptyset
  262. \\ \AddConst p {\Gamma \to A_1 \to A_2} {\LAM {\Gamma\,x} x} \Cs
  263. \\ \EqualTypeCtx {\Ext \Gamma x : A_1} {B_1} {\SubstD {B_2} {p ~ \Gamma \, x}} {\Cs^\prime}
  264. \end{array}}
  265. }
  266. To ensure the correctness of the algorithm we need to maintain the invariant
  267. that when we check $\EqualTypeCtx {} A B \Cs$ we have $\IsTypeC {} A$ and
  268. $\IsTypeC {} B$. Thus if we do not know whether $A_1 = A_2$ it is not
  269. correct to check $\EqualTypeCtx {x : A_1} {B_1} {B_2} {\Cs^\prime}$
  270. since $B_2$ is not well-formed in the context $x : A_1$. To solve the problem
  271. we substitute a guarded constant $p \, x$ for $x$ in $B_2$, where $p \, x$
  272. reduces to $x$ when $A_1$ and $A_2$ are convertible.
  273. % \quad
  274. %
  275. % \infer{
  276. % \EqualType {\PI x {A_1} {B_1}} {\PI x {A_2} {B_2}} \Cs
  277. % }{\begin{array}{l}
  278. % \EqualType {A_1} {A_2} \emptyset
  279. % \\ \EqualTypeCtx {\Ext \Gamma x : A_1} {B_1} {B_2} \Cs
  280. % \end{array}}
  281. %
  282. % \\{}\\
  283. %
  284. % % El M = El N
  285. %
  286. % \infer{
  287. % \EqualType {\EL M} {\EL N} \Cs
  288. % }{\begin{array}{l}
  289. % \Equal M N \SET \Cs
  290. % \end{array}}
  291. %
  292. % \end{array}\]}
  293. \subsubsection{Term conversion rules}
  294. Checking conversion of terms is done on weak head normal forms. The only rule
  295. that is applied before weak head normalisation is the $\eta$-rule.
  296. \URules{
  297. % Eta
  298. \infer{
  299. \Equal M N {\PI x A B} \Cs
  300. }{\begin{array}{l}
  301. \EqualCtx {\Ext \Gamma x : A} {M \, x} {N \, x} B \Cs
  302. \end{array}}
  303. \qquad
  304. % Weak head normalisation
  305. \infer{
  306. \Equal M N A \Cs
  307. }{\begin{array}[b]{lcl}
  308. \whnf M {M'}
  309. \\ \whnf N {N'}
  310. && \EqualWhnf {M'} {N'} A \Cs
  311. \end{array}
  312. }
  313. }
  314. In {\Core} function types are not terms so a meta-variable can never be
  315. instantiated to a function type. If this was the case we would have to check if
  316. the type was a meta-variable, and if so postpone the constraint, since we would
  317. not know whether or not the $\eta$-rule should be applied.
  318. The weak head normal forms we compare will be of atomic type and so they are of
  319. the form $h\,\bar M$ where the head $h$ is a variable, constant, meta-variable,
  320. or guarded constant. If both terms have the same variable or constant head $h :
  321. \Delta \to A$ we compare the arguments in $\Delta$.
  322. \URules{
  323. \infer{
  324. \EqualWhnf {h ~ \bar M} {h ~ \bar N} A \Cs
  325. }{\begin{array}{lcl}
  326. h : \Delta \to B
  327. && \Equal {\bar M} {\bar N} \Delta \Cs
  328. \end{array}}
  329. }
  330. If the heads are different constants or variables conversion checking fails.
  331. If one of the heads is a guarded constant we give up and return the problem as
  332. a constraint.
  333. \URules{
  334. \infer{
  335. \EqualWhnf {p ~ \bar M} N A {\left\{\TermConstr {p ~ \bar M} N A\right\}}
  336. }{}
  337. }
  338. If one of the heads is a meta variable we use a restricted form of pattern
  339. unification, but we believe that our correctness proof can be extended to more
  340. powerful unification algorithms, for example
  341. \cite{dowek:matching,dowek:unification,miller:pattern,Nipkow-LICS-93,pfenning:unification}. The crucial step is
  342. to prove that meta-variable instantiations are well-typed.
  343. In the examples we have studied, using meta-variables for
  344. implicit arguments, this simpler form of unification seems to be sufficient.
  345. The rule for meta-variable instantiation is
  346. \URules{
  347. % Instantiation
  348. \infer{
  349. \EqualWhnf {\alpha ~ \bar x} M A \emptyset
  350. }{
  351. \begin{array}[b]{l}
  352. \bar x~\mathit{distinct}
  353. \\ \Normalise M {M'}
  354. \\ \FV {M'} \subseteq \bar x
  355. \end{array}
  356. & \begin{array}[b]{l}
  357. \InScope \alpha {\LAM {\bar x} M'}
  358. \\ \InstMeta \alpha {\LAM {\bar x} M'}
  359. \end{array}
  360. }
  361. }
  362. Given the problem $\alpha \, \bar x = M$ we would like to instantiate $\alpha$ to
  363. $\LAM {\bar x} M$. This is only correct if $\bar x$ are distinct variables, $M$
  364. does not contain any variables other than $\bar x$, and any constants refered
  365. to by $M$ are in scope at the declaration site of $\alpha$\footnote{Note that
  366. scope checking subsumes the usual occurs check, since constants are non-recursive.}.
  367. Now $M$ might refer to meta-variables introduced after $\alpha$ but which have
  368. been instantiated. For this reason we normalise $M$ to $M'$ and try to
  369. instantiate $\alpha$ to $\LAM {\bar x} M'$. A possible optimisation might be to
  370. only normalise if $M$ contains out-of-scope constants or variables.
  371. If any of the premisses in this rule fail or $\alpha$ is not applied only to
  372. variables, we return the constraint as it is.
  373. When checking conversion of argument lists, the interesting case is when
  374. comparing the first arguments results in some unsolved constraints.
  375. \URules{
  376. % No constraints
  377. % \infer{
  378. % \Equal {M, \, \bar M} {N, \, \bar N} {(x : A) \Delta} \Cs
  379. % }{\begin{array}{l}
  380. % \Equal M N A \emptyset
  381. % \\ \Equal {\bar M} {\bar N} {\SubstD \Delta M} \Cs
  382. % \end{array}}
  383. %
  384. % \\{}\\
  385. % Some constraints
  386. \Rule{
  387. \Equal {M, \, \bar M} {N, \, \bar N} {(x : A) \Delta} {~~} \\
  388. \hfill \left\{ \TermConstr {M, \, \bar M} {N, \, \bar N} {(x : A) \Delta} \right\}
  389. }{\begin{array}{lcl}
  390. \Equal M N A \Cs \neq \emptyset
  391. && x \in \FV \Delta
  392. \end{array}}
  393. \quad
  394. \Rule{
  395. \Equal {M, \, \bar M} {N, \, \bar N} {(x : A) \Delta} {\Cs_1 \cup \Cs_2}
  396. }{\begin{array}{lcl}
  397. \Equal M N A {\Cs_1} \neq \emptyset
  398. \\ \Equal {\bar M} {\bar N} \Delta {\Cs_2}
  399. && x \notin \FV \Delta
  400. \end{array}}
  401. }
  402. If the value of the first argument is used in the types of later arguments ($x
  403. \in \FV \Delta$) we have to stop and produce a constraint since the types of
  404. $\bar M$ and $\bar N$ differ. If on the other hand the types of later arguments
  405. are independent of the value of the first argument, we can proceed and compare
  406. them without knowing whether the first arguments are convertible.
  407. % There is a possible inefficiency in that the constraint produced in the first
  408. % case does not remember the result of comparing $M$ and $N$. This could be
  409. % remedied by giving more structure to the constraint sets, requiring that the
  410. % constraints in $\Cs$ are solved before comparing $\bar M$ and $\bar N$.
  411. \subsubsection{Constraint Solving}
  412. So far, we have not looked at when or how the guards of a constant are
  413. simplified or solved. In principle this can be done at any time, for instance
  414. as a separate phase after type checking. In practise, however, it might be a
  415. better idea to interleave constraint solving and type checking. In
  416. Section~\ref{secProof} we prove that this can be done safely.
  417. Constraint solving amounts to rechecking the guard of a constant and replacing
  418. it by the resulting constraints.
  419. % The notation
  420. % $\CheckConstr \Cs {\Cs^\prime}$ means checking each of the constraints in $\Cs$
  421. % and taking $\Cs^\prime$ to be the union of the results.
  422. %
  423. % % Constraint solving
  424. % \URules{
  425. % \infer{
  426. % \ExplicitJudgement
  427. % \Sigma
  428. % \Simplify
  429. % {\Ext {\Sigma^\prime_1} \Ext {\ConstDecl p A M {\Cs^\prime}} \Sigma_2}
  430. % }{\begin{array}{ll}
  431. % \multicolumn2l{\Sigma ~ = ~ \Ext {\Sigma_1} \Ext {\ConstDecl p A M \Cs} {\Sigma_2}} \\
  432. % \ExplicitJudgement {\Sigma_1} {\CheckConstr \Cs {\Cs^\prime}} {\Sigma^\prime_1}
  433. % % & \Cs \neq {\Cs^\prime} \\
  434. % \end{array}
  435. % }
  436. % }
  437. % Not used
  438. % \begin{definition}[Normal signature]
  439. % A signature $\Sigma$ is in {\em normal form} if it is not the case that
  440. % $\ExplicitJudgement \Sigma \Simplify {\Sigma^\prime}$ for some $\Sigma^\prime$.
  441. % \end{definition}
  442. \if \NoteOnPatternMatching 1
  443. \subsection{Adding pattern matching} \label{secAddPatternMatching}
  444. If we have definitions by pattern matching reduction to weak head normal form
  445. might be blocked by an uninstantiated meta variable. For instance $\neg ~
  446. \alpha$ cannot be reduced to weak head normal form if $\neg$ is defined by
  447. $\neg ~\mathit{true} = \mathit{false}$ and $\neg ~\mathit{false} =
  448. \mathit{true}$. Since conversion checking is done on weak head normal forms we
  449. generate a constraint when encountering a blocked term.
  450. % Blocked terms
  451. % \URules{
  452. % \infer{
  453. % \Blocked {c \, \bar M}
  454. % }{\begin{array}{l}
  455. % c ~ \mbox{pattern matches on its $i^\mathrm{th}$ argument}
  456. % \\ M_i = \alpha \, \bar N ~ or ~ M_i = p \, \bar N ~ or ~ \Blocked {M_i}
  457. % \end{array}}
  458. %
  459. % \qquad
  460. %
  461. % \infer{
  462. % \Equal M N A {\left\{ \TermConstr {M'} {N'} A \right\}}
  463. % }{\begin{array}[b]{l}
  464. % \whnf M {M'}
  465. % \\ \whnf N {N'}
  466. % \\ \Blocked {M'} ~ \mathit{or} ~ \Blocked {N'}
  467. % \end{array}
  468. % }
  469. % }
  470. \fi