From sweirich at cis.upenn.edu Wed Aug 17 17:14:13 2005 From: sweirich at cis.upenn.edu (Stephanie Weirich) Date: Wed, 17 Aug 2005 17:14:13 -0400 Subject: [POPLmark] Experience report with Twelf Message-ID: This list has been a bit quiet lately, so I thought I'd get some discussion going again. As part of our experimentation with proof assistants and logical frameworks, I (with the assistance of Geoff Washburn) have coded up the type soundness of Featherweight Java (FJ) in Twelf. As I coded this same proof up in Coq seven months ago, it provides a comparison between Twelf and Coq. However, note that this isn't really a fair fight: alpha-conversion is not an issue in the semantics of FJ, so there isn't much chance for Twelf to shine. I used HOAS because I wanted experience with it, but I don't think it was particularly called for. (In fact, if I did it again, I would probably drop the HOAS---more about this below.) In this message, I'd like to report about my recent Twelf experiences, and ask a few questions of the Twelf experts. I'm going to concentrate on Twelf because that is what I most recently had experience with. In particular, I have some critical things to say about Twelf below. I also had some problems with Coq, but I won't go into detail about those in this message. For reference, you can download the Twelf and Coq proofs from the poplmark web site: http://www.cis.upenn.edu/proj/plclub/mmm/. (To check the Twelf proof you need to use the CVS version of Twelf.) Overall, I was more pleased with Coq than I was with Twelf for this exercise. The Twelf version was about twice as long as the Coq version. Bear in mind that both versions were created by novices---I've never used either tool for this sort of proof before now. However, I think that with experience (and much better use of tactics), I could make the Coq version shorter. I don't think there is much I could do to simplify the Twelf version. (Please tell me if I am mistaken!) I think my troubles with Twelf stemmed from the four reasons that I discuss below. For each of these reasons, I would like to know: (a) am I just missing something? Perhaps there is a better way to this that I don't know about. Please correct me if I am confused. (b) if not, is this a known problem with Twelf that can be fixed or is this something fundamental? Again, this wasn't a fair fight---there is nothing in FJ to really take advantage of HOAS. But it is typical of some of the work I would like to do using Twelf. 1) No polymorphism for logical operators The lack of polymorphism in Twelf is a common riff, and I wouldn't mention it if my troubles were limited to just data structures (such as lists). In fact, the lack of polymorphism in Twelf was much more annoying than I thought it would be. Twelf is a logical framework, not a logic. That means that many logical operators, like disjunction, conjunction, false, and equality, must be explicitly added. However, as Twelf lacks polymorphism, they cannot be added generically (as they can in Coq). Each type needs its own definition of equality. Each disjunction of two types must be declared. More importantly, each time I'd like to use the fact that false implies anything, I have to prove it as a separate lemma. (In my preservation proof, this was 6 times). Each time I used Leibniz equality, I also had to prove that (13 times). What is a simple tactic in Coq ("subst") is 5 tedious lines of Twelf. For example, refineMTEQ : methodTable_eq MT1 MT2 -> lookupMethod MT1 M MD -> lookupMethod MT2 M MD -> type. %mode refineMTEQ +MTEQ +LM1 -LM2. -: refineMTEQ methodTable_refl LM LM. %worlds (b_bind | var) (refineMTEQ M N O). %total M (refineMTEQ M N O). 2) Constructive logic and logic programming In Twelf, a theorem is a total logic program. So, the only way to prove something is to write a logic program that the metatheory of Twelf can show is total. That means that we can only use constructive logic. The proof of the progress theorem includes a case analysis of whether A is a subtype of B or not. In constructive logic, we have to show that subtyping is decidable. In Coq, I used "apply Classic." In Twelf, Geoff wrote 300 lines of code. Granted, these extra lines actually proved more: we got a proof that subtyping is decidable in FJ. But, as I was just interested in the type soundness of FJ, so being forced to prove more properties was annoying. Furthermore, even sticking to constructive logic, I was still slightly hampered by the logic programming aspect of it. For example, in the specification of when class tables are wellformed, I wanted to say something like : for all C. if you look up C in the class table CT, then C is well formed ----------------------------------------------------------------- the class table CT is well formed. (this is how my Coq specification reads, in Coq syntax of course) I couldn't figure out how to say that in Twelf. Instead, I had to write the logic program that folds over the class table, checking the well-formedness of each class. class_table_typing_help : classTable -> classTable -> type. ctt_nil : class_table_typing_help CT0 crnil. ctt_cons : class_table_typing_help CT0 CT -> class_typing CT0 C CD -> className_neq C object % ---------------------------------------------------------------- -> class_table_typing_help CT0 (crcons (CD : classDef C) CT CTI). class_table_typing : classTable -> type. - : class_table_typing_help CT CT -> class_table_typing CT. Perhaps I'm being too critical, as the code I had to write is only a bit longer, but it isn't exactly what I wanted to write. In Coq, I had the choice, but in Twelf, I was forced to do it this way. 3) HOAS, non-modularity and strengthening I used HOAS for method arguments in FJ, and I think I stumbled on two disadvantages for HOAS. (Again, alpha-equality is not much of an issue in FJ, so the advantages of HOAS wouldn't show up so much.) Both of these issues showed up in my proof of narrowing which reads: If G, X <:C0, G' |- e : D0 and C1 <: C0 then G, X<:C1, G' |- e : D1 and D1 <: D0. (Luckily, the proof for narrowing in FJ was not nearly as tricky as for F-sub in the POPLmark challenge. It is a fairly straightforward paper proof.) However, I had a problem with adding assumptions to the LF context. During this proof, as I traversed under a binder, I needed to add the "variable case" to the context. This was fun, I created a block that assumed the variable, its bound, and the proof of the narrowing theorem when the expression is exactly that variable: (For the curious, it looks like: %block b_bind : some {CT: classTable} {C0 : className} block {x: exp} {q: typing CT x C0} {N: ({WCT : class_table_typing CT} {C1 : className} {C2 : className} {SB0: subtyping CT C1 C2} narrowing_exp WCT ([y][qy] q) SB0 ([y][qy] q) s_refl)}. ) However, this block means that all of the lemmas that narrowing uses must be shown in a world that contains blocks that look like the above. The full dependence tree contains 27 lemmas that I had to modify the worlds declaration for, so that I could use them in the proof of narrowing. Furthermore, I had to put the statement of the narrowing lemma before these 27 lemmas because I need it to describe the block. But I needed to put the proof of the narrowing lemma after these 27 lemmas, because it depends on them. This seems bad to me, a theorem with a different LF context that needed to use narrowing in its proof would have to sandwich all of this code: the statement of the theorem above so that the world definitions could refer to it, all of the world definitions modified, and then the proof below. I don't see how this can scale. My second issue had to do with assumptions in the LF context. Twelf would assume that parts of my proof could depend on variables in the context, even though they couldn't really. So I had to prove to twelf that there was no dependence. For example, if I looked up a class definition from the class table (which can't depend on x), but the method table could have, it was the case that the method table actually didn't depend on x, and I could have replaced that x with something else. lookupClass_strengthen : ({x:exp} lookupClass CT C (class C D FS (MT x))) -> lookupClass CT C (class C D FS (MT unit)) -> type. For some parts of my proof, it didn't matter whether there was a dependence or not. So I added a new block (called "var") to 24 lemmas so Twelf could show that they were ok even with a variable "x" in the context. 4) Bottom-up vs. top-down In Twelf, my proof development was very bottom up. This was particularly true, because I couldn't make assertions in Twelf. I couldn't tell Twelf that something was a total logic program (assert that it is a theorem) without proving it (I was using the CVS version of Twelf, so the "feature" described on the Twelf wiki didn't work. I imagine that it would be trivial to add this to Twelf, so perhaps it is already there and I just don't know how to do it.). Separate from this is the difference between using an induction tactic in Coq and the coverage checker in Twelf. In Coq, after I define an inductive datatype, it tells me what the induction principal is, and in fact interactively guides me through the steps of using it. In Twelf, I have to guess that principal myself. And according to Twelf's coverage checker, I'm not very good at guessing it. I imagine with more experience with Twelf, I will get better at it. This may be more of an issue for the novice, but it does make Twelf's learning curve all the more steep. ---- That's it. In many ways that have been previously described by others, Twelf was a fine tool. I won't go into detail here, but in particular, I greatly appreciated Twelf's type inference and wished that Coq could do more of that for me. It also goes without saying that in both systems, dependent types are essential. I would really like to hear from Twelf users and experts, to help me refine my understanding of these issues. Thanks, Stephanie From drl+ at cs.cmu.edu Wed Aug 17 22:58:32 2005 From: drl+ at cs.cmu.edu (Dan Licata) Date: Wed, 17 Aug 2005 22:58:32 -0400 Subject: [POPLmark] Experience report with Twelf Message-ID: <20050818025832.GA22380@cs.cmu.edu> Hi Stephanie and everyone, I'm a second-year grad student at CMU; I've been using Twelf in a class and in my research for almost a year now. I'm writing this response to explain some of my experience with Twelf, in the hopes that you will better understand why I find it useful. In particular, I've never used another proof assistant, so I don't have anything to compare Twelf to, and I'm not trying to argue that Twelf is better than, say, Coq. > More importantly, each time I'd like to use the fact that false > implies anything, I have to prove it as a separate lemma. (In my > preservation proof, this was 6 times). Each time I used Leibniz > equality, I also had to prove that (13 times). What is a simple tactic > in Coq ("subst") is 5 tedious lines of Twelf. I've had to do this too. However, I find the (tacticless) style of Twelf proofs useful. Because object-language derivations are isomorphic to canonical LF terms and meta-proofs proceed by induction over canonical forms, the meta-proofs have a close correspondence to the rule inductions over derivations that we do on paper. When writing a Twelf proof, I more or less just write out the rule induction proof that I'd do on paper and Twelf checks it. Also, it makes it easy to translate a Twelf proof, case by case, into a traditional paper proof. Kevin Watkins has pointed this out on this list before. > The proof of the progress theorem includes a case analysis of whether > A is a subtype of B or not. In constructive logic, we have to show > that subtyping is decidable. In Coq, I used "apply Classic." In Twelf, > Geoff wrote 300 lines of code. Granted, these extra lines actually > proved more: we got a proof that subtyping is decidable in FJ. But, as > I was just interested in the type soundness of FJ, so being forced to > prove more properties was annoying. Intuitionistically, what you're proving when you don't actually do the decidability proof is "the law of the excluded middle (for subtyping) implies progress". You could do this in Twelf by leaving an unproven meta-theorem stating decidability: lem-for-subtyping : {a : tp} {b : tp} sub-or-not a b -> type. (where sub-or-not is essentially a sum of subtyping and not, however you define them). If you're happy with "apply Classic", then you should be fine with leaving this meta-theorem unproven, since it is "obviously" true. =) Or, you could state progress with an extra premise of type ({a : tp} {b : tp} sub-or-not a b), though I don't immediately see that it would be easy to satisfy this premise once you've proven decidability as a meta-theorem. > 3) HOAS, non-modularity and strengthening The issues with variable cases are in some sense the price for higher-order syntax and judgements. In my research, I've found the complications with variables a small price to pay for the ease that higher-order syntax and judgements provide. I never think about alpha-conversion or capture-avoiding substitution for syntax, even though it's present in everything I do. When I write an auxiliary hypothetical judgement, I don't have to prove substitution for it---I just apply the hypothetical to derivations satisfying its premises. Then again, I can always just ask Karl what to do when things go wrong. =) Cartsen Schurmann's forthcoming Delphin system is supposed to address these problems. As I understand it, it will allow you to write meta-proofs as total functional programs over the canonical LF terms; you'll be able to supply the cases for variables directly and locally, rather than in the context. Sometimes strengthening does come up. More than once, though, I've thought I needed strengthening when really I had corrupted my subordination relation (i.e., Twelf thought types were subordinate when they shouldn't have been). The subordination relation tells you when objects of one type can appear in another. You can use the command (in the Twelf server directly) Print.subord to print the subordination relation and inspect it. I'm not sure that it shows the transitive closure, so you may have to compute that yourself. > 4) Bottom-up vs. top-down > > In Twelf, my proof development was very bottom up. This was > particularly true, because I couldn't make assertions in Twelf. I > couldn't tell Twelf that something was a total logic program (assert > that it is a theorem) without proving it (I was using the CVS version > of Twelf, so the "feature" described on the Twelf wiki didn't work. I > imagine that it would be trivial to add this to Twelf, so perhaps it > is already there and I just don't know how to do it.). I just checked out the latest version from CVS, and it is still Twelf 1.5R2, Mar 13, 2005. This version definitely still has the %total bug that lets you leave a hole for an unproven metatheorem; I'm using it fairly heavily in a proof I'm doing right now. Note that to exploit the bug you have to actually get to the totality check: it doesn't work if Twelf trips over one of the cases of the theorem or the %worlds declaration. I believe that future versions will have a %trustme declaration that, in unsafe mode, will let you assert unproven metatheorems. > Separate from this is the difference between using an induction tactic > in Coq and the coverage checker in Twelf. In Coq, after I define an > inductive datatype, it tells me what the induction principal is, and > in fact interactively guides me through the steps of using it. In > Twelf, I have to guess that principal myself. And according to Twelf's > coverage checker, I'm not very good at guessing it. I imagine with > more experience with Twelf, I will get better at it. This may be more > of an issue for the novice, but it does make Twelf's learning curve > all the more steep. In my experience, the totality checker gets much easier to understand after a while. I've never had problems understanding the termination checker. Most of the time, the argument to the inductive call has to be a syntactic subterm of the input, so when you get an error, it's pretty easy to look and see that it isn't. (This gets a little more complicated if you use a %reduces declaration, since then the inductive argument might be the output of another call, but even then I haven't found it hard to keep track of). It took me a little while to get used to the input coverage checker. In part, this is because the coverage checker is using the magic of pattern matching with dependent types to rule out a bunch of cases for you (for example, when proving progress for simple languages, the coverage checker can essentially do canonical forms for you). Sometimes I have to pause for a moment to understand what contradiction ruled out a particular case, but I don't really mind when Twelf makes less work for me! There are a couple of insidious cases, though. The first is when you think you've covered a particular case, but Twelf isn't convinced. In my experience, this has always occurred when I accidentally unified two unification variables that, in the general case, should be distinct. Thus, the case I wrote down really didn't cover what I thought it did, since I assumed in that case that two distinct things were equal. I have two ways of figuring out what I did wrong: (1) inspect the type that Twelf infers for the case. For example, when I see an equality judgement relating a thing to itself, it's usually the problem. That is, %% definitional equality deq : tm -> tm -> tp -> type. when I see something like deq M M A in a type, it's often a bug. Comparing the inferred type to the required type is sometimes helpful, too, but I usually get discouraged by the alpha-renaming and go right on to the second technique and... (2) add type annotations that give names to the implicit arguments. If you write down two different variables, Twelf won't unify them, and instead you'll get a type error *when you type check the case*. For instance, say we are proving that definitional equality is symmetric deq-sym : deq M1 M2 A -> deq M2 M1 A -> type. %mode deq-sym +X1 -X2. and we thought we covered the case for application with a case like - : deq-sym (deq-app ...) _ ... If we accidentally unified the indices in the premise, we'd get a coverage error, since we'd only have covered the case for (deq (app M N) (app M N) A). If we add a type annotation - : deq-sym ((deq-app ...) : deq (app M N) (app M' N') A) _ ... forcing the two input terms to be distinct, we'll get a type error, and we can then trace it through. The second insidious case is when the coverage checker splits the wrong variable, and that prevents it from splitting what it needs to split to verify your proof. You can see what Twelf is splitting by using the (Twelf server buffer) command 'set chatter 6' (or higher to see more--the default is I think 3). Twelf seems to split from the inside out. One time I got Twelf to accept a proof by permuting the arguments in the theorem declaration so that the type family I wanted it to split was at the end of the inputs. I.e. thm : A -> B -> C -> D -> type %mode thm +X1 +X2 +X3 -X4. to thm : B -> C -> A -> D -> type %mode thm +X1 +X2 +X3 -X4. Hope that helps, -Dan From geoffw at cis.upenn.edu Thu Aug 18 09:43:03 2005 From: geoffw at cis.upenn.edu (Geoffrey Alan Washburn) Date: Thu, 18 Aug 2005 09:43:03 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <20050818025832.GA22380@cs.cmu.edu> References: <20050818025832.GA22380@cs.cmu.edu> Message-ID: <43049067.7070402@cis.upenn.edu> Dan Licata wrote: >>More importantly, each time I'd like to use the fact that false >>implies anything, I have to prove it as a separate lemma. (In my >>preservation proof, this was 6 times). Each time I used Leibniz >>equality, I also had to prove that (13 times). What is a simple tactic >>in Coq ("subst") is 5 tedious lines of Twelf. >> >> > >I've had to do this too. However, I find the (tacticless) style of >Twelf proofs useful. Because object-language derivations are isomorphic >to canonical LF terms and meta-proofs proceed by induction over >canonical forms, the meta-proofs have a close correspondence to the rule >inductions over derivations that we do on paper. When writing a Twelf >proof, I more or less just write out the rule induction proof that I'd >do on paper and Twelf checks it. Also, it makes it easy to translate a >Twelf proof, case by case, into a traditional paper proof. Kevin >Watkins has pointed this out on this list before. > > I would agree that I prefer the direct proof term style to tactics, though maybe I just need more experience to see how to write tactics that behave well under extension. However, the problem we had is orthogonal to writing tactics versus proof terms, what we are asking is why would we want to be writing false_imp_nat_eq : {N1:nat} {N2:nat} false -> nat_eq N1 N2 -> type. %mode false_imp_nat_eq +N1 +N2 +FALSE -NEQ. %worlds () (false_imp_nat_eq N1 N2 F NEQ). %total F (false_imp_nat_eq N1 N2 F NEQ). false_imp_eq : false -> methodDef_eq MD1 MD2 -> type. %mode +{MN1:methodName} +{MD1:methodDef MN1} +{MD2:methodDef MN1} +{F:false} -{EQ:methodDef_eq MD1 MD2} (false_imp_eq F EQ). %worlds (b_bind | var ) (false_imp_eq F EQ). %total F (false_imp_eq F EQ). false_imp_eq_class : false -> classDef_eq MD1 MD2 -> type. %mode +{MN1:className} +{MD1:classDef MN1} +{MD2:classDef MN1} +{F:false} -{EQ:classDef_eq MD1 MD2} (false_imp_eq_class F EQ). %worlds (b_bind | var ) (false_imp_eq_class F EQ). %total F (false_imp_eq_class F EQ). false_imp_eq_className : false -> className_eq MD1 MD2 -> type. %mode +{MD1:className} +{MD2:className} +{F:false} -{EQ:className_eq MD1 MD2} (false_imp_eq_className F EQ). %worlds () (false_imp_eq_className F EQ). %total F (false_imp_eq_className F EQ). false_imp_TBE : false -> typing_bexp CT (BE: bexp CS1) C0 object -> subtyping CT object R1 -> cnlist_eq CS1 DS -> type. %mode +{N1:nat} +{CS1:cnlist N1} +{CT:classTable} +{BE:bexp CS1} +{C0:className} +{R1:className} +{N2:nat} +{DS: cnlist N2} +{F:false} -{TBE:typing_bexp CT BE C0 object} -{SB:subtyping CT object C0} -{EQ:cnlist_eq CS1 DS} (false_imp_TBE F TBE SB EQ). %worlds () (false_imp_TBE F TBE SB EQ). %total F (false_imp_TBE F TBE SB EQ). false_imp_lookupMethod : false -> lookupMethod MR1 M (method D0 M (BE2: bexp DS)) -> lookupMethod MR1 M (method C0 M (BE3: bexp CS)) -> type. %mode +{MR1:methodTable} +{M:methodName} +{N1:nat} +{DS:cnlist N1} +{D0:className} +{BE2:bexp DS} +{N2:nat} +{CS:cnlist N2} +{C0:className} -{BE3:bexp CS} +{F:false} +{LM1:lookupMethod MR1 M (method D0 M BE2)} -{LM2:lookupMethod MR1 M (method C0 M BE3)} (false_imp_lookupMethod F LM1 LM2). %worlds (b_bind | var ) (false_imp_lookupMethod F L M). %total F (false_imp_lookupMethod F L M). false_imp_really : false -> cnlist_eq CS1 CS2 -> type. %mode +{N1:nat} +{N2:nat} +{CS1:cnlist N1} +{CS2:cnlist N2} +{F:false} -{CN2:cnlist_eq CS1 CS2} (false_imp_really F CN2). %worlds () (false_imp_really F CN2). %total F (false_imp_really F CN2). when if Twelf hypothetically had polymorphism we could have just written something like false_imp_any : {T:type} false -> T -> type. %mode false_imp_any +T +F -TOBJ. %worlds () (false_imp_any T F TOBJ). %total F (false_imp_any T F TOBJ). However, even this is not entirely what we want because some of the above lemmas need to be proven under a world with some assumptions. We can rewrite our lemma as false_imp_any : {T:type} false -> T -> type. %mode false_imp_any +T +F -TOBJ. %worlds (b_bind_var | var) (false_imp_any T F TOBJ). %total F (false_imp_any T F TOBJ). but again the non-modularity of worlds penalize us. We will need to keep adding new blocks to the worlds declaration as we use the lemma in more and more contexts. Perhaps if it were a possible to specify a "greatest" world, the world subsumption would work out and we could define just one lemma once and for all. More than once Stephanie and I thought of breaking down and writing m4 macros to deal with this but decided against it. Manipulating untyped strings kind of defeats the purpose of using a logical framework to begin with. Furthermore, as far as I know, the forthcoming Twelf module system will not be able to address these sorts of reuse problems. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050818/6c8d799f/attachment-0001.html From sweirich at cis.upenn.edu Thu Aug 18 10:18:35 2005 From: sweirich at cis.upenn.edu (Stephanie Weirich) Date: Thu, 18 Aug 2005 10:18:35 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <20050818023554.GA21550@cs.cmu.edu> References: <20050818023554.GA21550@cs.cmu.edu> Message-ID: Hi Dan, Thanks for your reply! You've written a lot of nice clarifications here, that I think will be useful for others learning Twelf. I just want to address a few of the points that you made. > >> The proof of the progress theorem includes a case analysis of whether >> A is a subtype of B or not. In constructive logic, we have to show >> that subtyping is decidable. In Coq, I used "apply Classic." In >> Twelf, >> Geoff wrote 300 lines of code. Granted, these extra lines actually >> proved more: we got a proof that subtyping is decidable in FJ. >> But, as >> I was just interested in the type soundness of FJ, so being forced to >> prove more properties was annoying. >> > > Intuitionistically, what you're proving when you don't actually do the > decidability proof is "the law of the excluded middle (for subtyping) > implies progress". > > You could do this in Twelf by leaving an unproven meta-theorem stating > decidability: > > lem-for-subtyping : {a : tp} {b : tp} sub-or-not a b -> type. > > (where sub-or-not is essentially a sum of subtyping and not, > however you > define them). Yes, the "lem-for-subtyping" lemma is exactly the lemma we proved. We didn't see how to assert it so that it could be used by the coverage checker in the progress lemma, though. A side note: I don't think that this is exactly the law of the excluded middle. I think it says something like "at least one of the 'subtyping' and 'notsubtyping' judgments are derivable. For true classical reasoning, I found that I also needed the related lemma, that asserts that "at most one of the judgements is derivable". subtyping-exclusive: subtyping A B -> not-subtyping A B -> false -> type. (For progress, we didn't need the subtyping-exclusive lemma, but we did need a related version of this lemma elsewhere in the proof.) Is it possible to combine these two together into one lemma? I couldn't think how to do that. > > Or, you could state progress with an extra premise of type ({a : > tp} {b > : tp} sub-or-not a b), though I don't immediately see that it would be > easy to satisfy this premise once you've proven decidability as a > meta-theorem. > I agree, I don't think you can manipulate proofs like that in Twelf. Things like this get me too. As I understand it, a Twelf proof of the decidability of subtyping is not an LF element of type ({a : tp} {b: tp} sub-or-not a b) it is some meta reasoning that the Twelf logic program is a total function. > >> 3) HOAS, non-modularity and strengthening >> > > > Cartsen Schurmann's forthcoming Delphin system is supposed to address > these problems. As I understand it, it will allow you to write > meta-proofs as total functional programs over the canonical LF terms; > you'll be able to supply the cases for variables directly and locally, > rather than in the context. Great! I hope that Delphin can address these issues. > > Sometimes strengthening does come up. More than once, though, I've > thought I needed strengthening when really I had corrupted my > subordination relation (i.e., Twelf thought types were subordinate > when > they shouldn't have been). The subordination relation tells you when > objects of one type can appear in another. You can use the command > (in > the Twelf server directly) Print.subord to print the subordination > relation and inspect it. I'm not sure that it shows the transitive > closure, so you may have to compute that yourself. Thanks for the hint about Print.subord. lookupClass_strengthen : ({x:exp} lookupClass CT C (class C D FS (MT x))) -> lookupClass CT C (class C D FS (MT unit)) -> type. However, I think this is a case where strengthening is unavoidable. The type exp is subordinate to the type methodTable, but since the methodTable MT comes from the classTable CT (which does not depend on x) in this case, it can't depend on x. > > It took me a little while to get used to the input coverage checker. I agree entirely. This is exactly what I was talking about, it's an issue of learning curve. After a while, I was going through roughly the same processes that you describe (alpha renaming the error message so that I could understand them, adding type annotations to make sure that variables are not unified). However, even when I had taught myself these practices, I found writing proofs a little backwards....Coq tells me what to prove, but in Twelf, I have to guess, and then interpret the error messages when I guess wrong. Thanks for writing a careful description of how to go about addressing coverage errors---this is something that should appear in the Twelf wiki. --Stephanie From drl+ at cs.cmu.edu Thu Aug 18 14:01:49 2005 From: drl+ at cs.cmu.edu (Dan Licata) Date: Thu, 18 Aug 2005 14:01:49 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <20050818023554.GA21550@cs.cmu.edu> Message-ID: <20050818180149.GB10750@cs.cmu.edu> > A side note: I don't think that this is exactly the law of the > excluded middle. I think it says something like "at least one of the > 'subtyping' and 'notsubtyping' judgments are derivable." The law of the excluded middle is usually phrased as (A or not(A)), which corresponds in this instance to the phrase in quotes above. > For true classical reasoning, I found that I also needed the related > lemma, that asserts that "at most one of the judgements is derivable". > > subtyping-exclusive: subtyping A B -> not-subtyping A B -> false -> > type. subtyping-exclusive is a different lemma, which asserts that (for this particular A) (A and not(A) implies false). This statement is true for all A in intuitionistic logic, where not(A) is usually taken as sugar for (A implies false). So, if not-subtyping is really not(subtyping), then this lemma should be provable easily using the standard proof (apply the second premise to the first). I don't know FJ, so I don't know what you're trying to encode. If not-subtyping is really not(subtyping), then you could encode it with with the single rule not-subtyping-contra : not-subtyping A B <- (subtyping A B -> false) and the metatheorem in this instance is easy to prove. If your object language definition of not-subtyping isn't really not(subtyping), then you'd have to prove this metatheorem on paper as well. Otherwise, what tells you that the two are actually exclusive? If you made a mistake in one of the definitions they wouldn't be. > Things like this get me too. As I understand it, a Twelf proof of the > decidability of subtyping is not an LF element of type ({a : tp} {b: > tp} sub-or-not a b) it is some meta reasoning that the Twelf logic > program is a total function. Right, a Twelf meta-proof isn't just a single LF term. The metatheorem apparatus lets you state Pi_2 sentences as type families with modes. The type family A : B -> C -> D -> type. %mode A +B +C -D. represents the sentence "for all b:B, for all c:C, there exists a d:D" A total relation from the universally quantified things to the existentially quantified things is a proof of a Pi_2 sentence (for all inputs, it constructs the witnesses to the existentials). So, the meta-theorem language needs to give us a way to write down a relation and check that it is total. The traditional way of thinking about Twelf is that the relation is given by a logic program from the universally-quantified things to the existentially-quantified things. That is, you inhabit the type family representing the metatheorem with cases that, in Elf, constitute a logic program. Then the meta-theorem checker proves that the cases you've written down actually implement a total program. To some degree, you can also understand what you're doing without mentioning logic programming at all (though this is of course just another way of looking at the same thing). I sometimes find this abstraction helpful. You think of the type family A : B -> C -> D -> type. %mode A +B +C -D. as directly representing a relation where b,c,d are related iff (A b c d) is inhabited. Then, your job in writing cases is to provide enough constants in the signature such that for all canonical LF terms of type B and all canonical LF terms of type C, there exists a canonical LF term of type (A b c d) for some canonical d:D. The meta-theorem checker proves by induction over canonical forms that this is actually the case. In particular, let's verify something like case1 : A (b-constructor Subderiv) DerivationOfC InductiveResult <- A Subderiv DerivationOfC InductiveResult (note that this case is a tail call, in the sense that we just return the inductive result). If you look at the canonical forms judgements for LF, you'll see that when the application of a constant ('b-constructor' in this case) to something is canonical, the something must itself be canonical. Since the meta-theorem checker works by induction on canonical forms, it can *assume* that for Subderiv and DerivationOfC there exists a canonical LF term InductiveResult:D for which there exists a canonical LF term of type (A Subderiv DerivationOfC InductiveResult). Then applying the constant case1 to this assumed term yields a canonical term of type A (b-constructor Subderiv) DerivationOfC InductiveResult. This means that this case can be used to produce inhabitants of some of the (A b c d) space. I find this way of thinking helpful for understanding why a "by induction" in the paper proof turns into a "<-" in the type of a constant in the Twelf proof. The induction in the paper proof turns into an induction over canonical forms in the meta-theorem checker that proves that the premises of the case are actually inhabited (if the premises aren't inhabited, the constant doesn't help show that the type family is inhabited). Disclaimer: I came up with this second way of thinking about what's going on myself, but I haven't checked to see if it's in any of the existing work (e.g., Carsten's thesis). Also, I haven't really thought it through, so it might not actually work. > >Or, you could state progress with an extra premise of type ({a : tp} > >{b : tp} sub-or-not a b), though I don't immediately see that it > >would be easy to satisfy this premise once you've proven decidability > >as a meta-theorem. > > > > I agree, I don't think you can manipulate proofs like that in Twelf. You sometimes can. In this particular example, say we prove progress' : ({a : tp} {b : tp} sub-or-not a b) -> -> type. %mode progress' +X1 ... . and then prove decide-sub : {a : tp} {b : tp} sub-or-not a b -> type. %mode decide-sub +X1 +X2 -X3. Can we use this to prove progress : -> type. in terms of progress'? Maybe. We can write a case like - : progress ... <- ({a : tp} {b : tp} decide-sub a b (D a b)) %% D : {a : tp} {b : tp} (sub-or-not a b) <- progress' D ... That is, we call decide-sub in an extended context, so that the result it returns has the abstracted type. The catch is that decide-sub has to be true in the context dictated by the hypothetical (the {a} {b} in the context for the call comes from the premise to progress'!). If it is, then you can do this. If it's not, you could reprove decide-sub in the context you need to call it in. However, this could be tricky. In this example, if you didn't already have variables of LF type tp in the worlds for decide-sub, then to prove decide-sub in a context containing them, you'd have to figure out how to decide subtyping for the variables. > >Sometimes strengthening does come up. More than once, though, I've > >thought I needed strengthening when really I had corrupted my > >subordination relation (i.e., Twelf thought types were subordinate > >when they shouldn't have been). The subordination relation tells you > >when objects of one type can appear in another. You can use the > >command (in the Twelf server directly) Print.subord to print the > >subordination relation and inspect it. I'm not sure that it shows > >the transitive closure, so you may have to compute that yourself. > > Thanks for the hint about Print.subord. > > lookupClass_strengthen : > ({x:exp} lookupClass CT C (class C D FS (MT x))) > -> lookupClass CT C (class C D FS (MT unit)) -> type. > > However, I think this is a case where strengthening is unavoidable. > The type exp is subordinate to the type methodTable, but since the > methodTable MT comes from the classTable CT (which does not depend on > x) in this case, it can't depend on x. This could be a property of the system you're formalizing, not just the LF encoding. That is, on paper, how do you *know* that the class you get back doesn't mention some variable in the context? Sometimes I've glossed over things like this on paper only to have Twelf point them out to me. > Thanks for writing a careful description of how to go about addressing > coverage errors---this is something that should appear in the Twelf > wiki. Agreed--I'll make a post. -Dan From drl+ at cs.cmu.edu Thu Aug 18 15:04:09 2005 From: drl+ at cs.cmu.edu (Dan Licata) Date: Thu, 18 Aug 2005 15:04:09 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <43049067.7070402@cis.upenn.edu> References: <20050818025832.GA22380@cs.cmu.edu> <43049067.7070402@cis.upenn.edu> Message-ID: <20050818190409.GA10965@cs.cmu.edu> > when if Twelf hypothetically had polymorphism we could have just written > something like I meant to address this in response to the original message. If LF had sums or polymorphism, then Twelf wouldn't be very much like what it is. That is, you cannot simply add sums or polymorphism to LF without compromising the LF methodology. Why not? To represent an object-language judgement (for example--the same is true for syntax or anything else) in LF, you establish a bijection between the derivations of the judgement and the canonical terms of a particular LF type in contexts of a particular form. The theorem establishing this bijection is called "adequacy". In the dependent function type and base type fragment, the canonical terms of the type representing your object-language judgement are roughly constants and variables applied to canonical arguments. Thus, it's fairly easy to set these up so they correspond to the "on paper" object-language syntax and derivations. If we added sums, then given a constant or a variable in the signature of sum type, the canonical forms of any type C would include a CASE on that constant or variable (as long as both branches are inhabited). We would have to account for this when giving adequate encodings of an object language, and we would have to account for it when doing induction over canonical forms (which is what the meta-theorem apparatus is based on). In most cases, this would make adequate encodings and meta-proofs difficult or impossible. The same is true for polymorphism. For example, the following signature: nat : type. z : nat. s : nat -> nat. b : type. something : b. c : all alpha . b -> alpha . no longer contains an adequate encoding of the natural numbers as the canonical LF terms of type nat. That is, there is no natural number corresponding to (c[nat] something), even though this term is canonical. Note that, from their types, the bs and cs seem to have nothing at all to do with the nats, however. Put another way, the lack of more powerful connectives is a feature, in that it enables adequate encodings of an object language as canonical forms of an LF type. Using canonical forms seems important for proving meta-theorems, as higher-order syntax and judgements aren't inductively defined in the usual sense (they contain negative occurrences). Now, I know of two ways for adding more connectives that are compatible with the adequacy methodology. The first is to only add well-behaved connectives (essentially, limits). Along these lines, Susmit Sarkar has done the meta-theory of LF extended with dependent pairs and unit. Linear LF includes connectives from the multiplicative fragment of linear logic. The second is to somehow prevent the misbehaved types from influencing adequacy. In Concurrent LF, the colimit types are restricted to a monad partly for this reason. I don't know if the monadic approach could be usefully applied to sums or polymorphism. Another consideration, aside from adequacy, is that the equational theory and canonical forms of a type added to the framework must be tractable, or the type must be isolated so that these properties are not needed. That is, adequacy constrains which types we'd want to add, but even of the types we want, we have to actually be able to work with one to add it. I think that part of the motivation for the monad in CLF was to avoid dealing with commuting conversions. That said, I'm not arguing in favor of writing all these trivial lemmas that you mentioned. I just don't know a way around them that is compatible with the LF methodology. And, in my experience, writing a few trivial equality/falsehood lemmas has been less of a pain than manually implementing alpha-conversion and capture-avoiding substitution. -Dan From sweirich at cis.upenn.edu Thu Aug 18 20:07:06 2005 From: sweirich at cis.upenn.edu (Stephanie Weirich) Date: Thu, 18 Aug 2005 20:07:06 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <20050818180149.GB10750@cs.cmu.edu> References: <20050818023554.GA21550@cs.cmu.edu> <20050818180149.GB10750@cs.cmu.edu> Message-ID: <430522AA.5000104@cis.upenn.edu> Dan Licata wrote: >>A side note: I don't think that this is exactly the law of the >>excluded middle. I think it says something like "at least one of the >>'subtyping' and 'notsubtyping' judgments are derivable." >> >> > >The law of the excluded middle is usually phrased as (A or not(A)), >which corresponds in this instance to the phrase in quotes above. > > > I think we dis agree on what the definition of not-subtype should be, and that makes all of the difference. You propose the following definition: > not-subtyping-contra : not-subtyping A B > <- (subtyping A B -> false). where I define non-subtyping without relation to the subtyping judgement. (Technically, a judgments that holds when two types aren't subtypes of one another.) That's why the subtyping-exclusive lemma >>subtyping-exclusive: subtyping A B -> not-subtyping A B -> false -> >>type. >> >> is necessary to make it clear that both of these judgments can't hold. (It is true by definition for your version.). However, I prefer my definition of not-subtyping because with your definition, the excluded middle lemma is not provable in Twelf---there is no LF canonical form of type (subtyping A B -> false). Even though I originally wanted to assert the decidablity of subtyping, since subtyping *is* in fact decidable, it makes sense for me to assert it in a way that could eventually be proven in Twelf. >> >>lookupClass_strengthen : >> ({x:exp} lookupClass CT C (class C D FS (MT x))) >> -> lookupClass CT C (class C D FS (MT unit)) -> type. >> >>However, I think this is a case where strengthening is unavoidable. >>The type exp is subordinate to the type methodTable, but since the >>methodTable MT comes from the classTable CT (which does not depend on >>x) in this case, it can't depend on x. >> >> > >This could be a property of the system you're formalizing, not just >the LF encoding. That is, on paper, how do you *know* that the class >you get back doesn't mention some variable in the context? Sometimes >I've glossed over things like this on paper only to have Twelf point >them out to me. > > This issue didn't come up in either the Coq version of the proof (that I did) or the Isabelle/HOL version (that two grad students here at Penn did). --Stephanie From mpa at andrew.cmu.edu Fri Aug 19 00:51:00 2005 From: mpa at andrew.cmu.edu (Michael Philip Ashley-Rollman) Date: Fri, 19 Aug 2005 00:51:00 -0400 (EDT) Subject: [POPLmark] Experience report with Twelf In-Reply-To: <430522AA.5000104@cis.upenn.edu> References: <20050818023554.GA21550@cs.cmu.edu> <20050818180149.GB10750@cs.cmu.edu> <430522AA.5000104@cis.upenn.edu> Message-ID: >>> lookupClass_strengthen : >>> ({x:exp} lookupClass CT C (class C D FS (MT x))) >>> -> lookupClass CT C (class C D FS (MT unit)) -> type. >>> >>> However, I think this is a case where strengthening is unavoidable. >>> The type exp is subordinate to the type methodTable, but since the >>> methodTable MT comes from the classTable CT (which does not depend on >>> x) in this case, it can't depend on x. >>> >>> >> >> This could be a property of the system you're formalizing, not just >> the LF encoding. That is, on paper, how do you *know* that the class >> you get back doesn't mention some variable in the context? Sometimes >> I've glossed over things like this on paper only to have Twelf point >> them out to me. >> >> > This issue didn't come up in either the Coq version of the proof (that I > did) or the Isabelle/HOL version > (that two grad students here at Penn did). This issue does not really come up in the twelf proof either. Rather than proving the lookupClass_strengthen or sub_strengthen lemmas, you can simply substitute unit in for exp for lookupClass_strengthen and any expression at all into sub_strengthen. A term with type (exp -> subtyping CT C D) is saying that for any expression, I can provide you with a proof of (subtyping CT C D). Thus, by providing any term with type exp, we may immediately get a derivation of (subtyping CT C D). Sometimes substituting in terms that don't matter can confuses twelf a little bit and it will give you an error like this: Typing ambiguous -- unresolved constraints C1 unit = C1 x; CT1 unit = CT1 x; CT1 unit = CT1 x; CT1 unit = CT1 x. In this case, providing the type of the term after substition usually resolves the issue. Thus we may change the last rule of narrowing_explist to this: -: narrowing_explist WCT TL1 SB TL2 -> sub_trans SB2 (SB1 unit : subtyping CT C D) SB4 -> %% sub_strengthen SB1 SB3 -> narrowing_exp WCT T1 SB T2 SB2 -> narrowing_explist WCT ([x][q] tl_cons (SB1 x) (TL1 x q) (T1 x q)) SB ([x][q] tl_cons SB4 (TL2 x q) (T2 x q)). Othertimes Twelf is able to understand the substitution as in the narrowing_bexp cases. -Michael From sweirich at cis.upenn.edu Fri Aug 19 09:11:55 2005 From: sweirich at cis.upenn.edu (Stephanie Weirich) Date: Fri, 19 Aug 2005 09:11:55 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <20050818023554.GA21550@cs.cmu.edu> <20050818180149.GB10750@cs.cmu.edu> <430522AA.5000104@cis.upenn.edu> Message-ID: Thanks Michael, that clears up that issue. I don't need sub_strengthen or lookupClass_strengthen anymore. Thanks, Stephanie On Aug 19, 2005, at 12:51 AM, Michael Philip Ashley-Rollman wrote: >>>> lookupClass_strengthen : >>>> ({x:exp} lookupClass CT C (class C D FS (MT x))) >>>> -> lookupClass CT C (class C D FS (MT unit)) -> type. >>>> >>>> However, I think this is a case where strengthening is unavoidable. >>>> The type exp is subordinate to the type methodTable, but since the >>>> methodTable MT comes from the classTable CT (which does not >>>> depend on >>>> x) in this case, it can't depend on x. >>>> >>>> >>>> >>> >>> This could be a property of the system you're formalizing, not just >>> the LF encoding. That is, on paper, how do you *know* that the >>> class >>> you get back doesn't mention some variable in the context? >>> Sometimes >>> I've glossed over things like this on paper only to have Twelf point >>> them out to me. >>> >>> >>> >> This issue didn't come up in either the Coq version of the proof >> (that I >> did) or the Isabelle/HOL version >> (that two grad students here at Penn did). >> > > This issue does not really come up in the twelf proof either. > Rather than proving the lookupClass_strengthen or sub_strengthen > lemmas, you can simply substitute unit in for exp for > lookupClass_strengthen and any expression at all into > sub_strengthen. A term with type (exp -> subtyping CT C D) is > saying that for any expression, I can provide you with a proof of > (subtyping CT C D). Thus, by providing any term with type exp, we > may immediately get a derivation of (subtyping CT C D). Sometimes > substituting in terms that don't matter can confuses twelf a little > bit and it will give you an error like this: > > Typing ambiguous -- unresolved constraints > C1 unit = C1 x; > CT1 unit = CT1 x; > CT1 unit = CT1 x; > CT1 unit = CT1 x. > > In this case, providing the type of the term after substition > usually resolves the issue. Thus we may change the last rule of > narrowing_explist to this: > > -: narrowing_explist WCT TL1 SB TL2 -> > sub_trans SB2 (SB1 unit : subtyping CT C D) SB4 -> > %% sub_strengthen SB1 SB3 -> > narrowing_exp WCT T1 SB T2 SB2 -> > narrowing_explist WCT > ([x][q] tl_cons (SB1 x) (TL1 x q) (T1 x q)) SB > ([x][q] tl_cons SB4 (TL2 x q) (T2 x q)). > > Othertimes Twelf is able to understand the substitution as in the > narrowing_bexp cases. > -Michael > From drl+ at cs.cmu.edu Fri Aug 19 09:27:36 2005 From: drl+ at cs.cmu.edu (Dan Licata) Date: Fri, 19 Aug 2005 09:27:36 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <430522AA.5000104@cis.upenn.edu> References: <20050818023554.GA21550@cs.cmu.edu> <20050818180149.GB10750@cs.cmu.edu> <430522AA.5000104@cis.upenn.edu> Message-ID: <20050819132736.GA12796@cs.cmu.edu> Sorry, I was unclear. All I was suggesting was that the implies-false-premised rule was a quick solution under the assumptions that (a) you want decidability of subtyping as an extra premise or as an unproven metatheorem and (b) all you ever want to do with a not-subtyping derivation is contradict a subtyping one. I didn't mean to suggest that it was a better solution than coding up the negation and proving exclusivity. Whenever I've run into these sorts of things, I've defined the not-X judgement directly. So, we agree. -Dan On Aug18, Stephanie Weirich wrote: > Dan Licata wrote: > > >>A side note: I don't think that this is exactly the law of the > >>excluded middle. I think it says something like "at least one of the > >>'subtyping' and 'notsubtyping' judgments are derivable." > >> > >> > > > >The law of the excluded middle is usually phrased as (A or not(A)), > >which corresponds in this instance to the phrase in quotes above. > > > > > > > > > I think we dis agree on what the definition of not-subtype should be, > and that makes all of the difference. > You propose the following definition: > > >not-subtyping-contra : not-subtyping A B > > <- (subtyping A B -> false). > > where I define non-subtyping without relation to the subtyping > judgement. (Technically, a judgments that > holds when two types aren't subtypes of one another.) That's why the > subtyping-exclusive lemma > > >>subtyping-exclusive: subtyping A B -> not-subtyping A B -> false -> > >>type. > >> > >> > is necessary to make it clear that both of these judgments can't hold. > (It is true by definition for your version.). > > However, I prefer my definition of not-subtyping because with your > definition, the excluded middle lemma > is not provable in Twelf---there is no LF canonical form of type > (subtyping A B -> false). Even though I > originally wanted to assert the decidablity of subtyping, since > subtyping *is* in fact decidable, it makes sense for me to > assert it in a way that could eventually be proven in Twelf. > > >> > >>lookupClass_strengthen : > >> ({x:exp} lookupClass CT C (class C D FS (MT x))) > >> -> lookupClass CT C (class C D FS (MT unit)) -> type. > >> > >>However, I think this is a case where strengthening is unavoidable. > >>The type exp is subordinate to the type methodTable, but since the > >>methodTable MT comes from the classTable CT (which does not depend on > >>x) in this case, it can't depend on x. > >> > >> > > > >This could be a property of the system you're formalizing, not just > >the LF encoding. That is, on paper, how do you *know* that the class > >you get back doesn't mention some variable in the context? Sometimes > >I've glossed over things like this on paper only to have Twelf point > >them out to me. > > > > > This issue didn't come up in either the Coq version of the proof (that I > did) or the Isabelle/HOL version > (that two grad students here at Penn did). > > --Stephanie > From greg at eecs.harvard.edu Fri Aug 19 10:30:11 2005 From: greg at eecs.harvard.edu (Greg Morrisett) Date: Fri, 19 Aug 2005 10:30:11 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: Message-ID: <4305ECF3.9000804@eecs.harvard.edu> Stephanie Weirich wrote: > This list has been a bit quiet lately, so I thought I'd get some > discussion going again. Thanks for cranking up the discussion again. Matthew Fluet and I have shared many of your frustrations in trying to formalize some work on L-cubed and regions in Twelf. One thing that we did find is that, although you end up writing out a lot more in Twelf, it seems to scale well. That is, we started from a very little language, proved soundness for that, and then started adding features, and relatively speaking, had an easy time getting the proofs to go through. It felt a lot like programming in ML, where you add some new constructors to a datatype, and the compiler tells you where you need to add some new cases. That is, the changes we had to make were largely proportional to the complexity of the feature we were adding. (Easy for me to say --- Matthew did all the hard work :-)). What are people's experience with scaling in other settings (e.g., Coq, Isabelle, etc.)? And how re-usable were the core proofs when extending a language? -Greg From nipkow at in.tum.de Fri Aug 19 11:50:31 2005 From: nipkow at in.tum.de (nipkow@in.tum.de) Date: Fri, 19 Aug 2005 17:50:31 +0200 (MEST) Subject: [POPLmark] Experience report with Twelf In-Reply-To: <4305ECF3.9000804@eecs.harvard.edu> (message from Greg Morrisett on Fri, 19 Aug 2005 10:30:11 -0400) References: <4305ECF3.9000804@eecs.harvard.edu> Message-ID: <20050819155031.06C982EE4@sunbroy2.informatik.tu-muenchen.de> > What are people's experience with scaling in other settings > (e.g., Coq, Isabelle, etc.)? And how re-usable were the core > proofs when extending a language? I have found that proofs scale quite well in Isabelle, not just when adding features but even when moving to a related language. Eg when moving from (subsets of) Java to C++ we could reuse more than 50% of the proofs, even if we needed to do lots of editing. Proofs written in Isabelle's structured proof language scale even better. Tobias From jevgenijs at dva.lv Thu Aug 25 14:22:59 2005 From: jevgenijs at dva.lv (jevgenijs@dva.lv) Date: Thu, 25 Aug 2005 11:22:59 -0700 Subject: [POPLmark] Submission Message-ID: <1124994179.430e0c831cdf9@webmail.dva.lv> Here attached submission for PoplMark challenges 1A, 2A with explicit (directly computable) evaluation relation and progress operator, so providing basis also for challenge 3 (without records). Coq solution with de Bruijn nameless representation is based on previous submission of Jerome Vouillon with numerous simplifications. The role of natural numbers clarified by providing interface (see module type T_Nat in sub_def.v) of all their properties used outside implementation module (no induction principles, additional recursion operators and even no order relation required). This could help with modifications and translations to others representations. Among most interesting findings there could be mentioned the usage of functions t_semi_P, t_semi_S and their properties t_semi_S_P, t_semi_S_2, which allows removing case analysis on order relation for natural numbers. Also some parts of paper proofs were simplified. For example lemmas on inversions of typing rules (T_Abs_inversion and T_Tabs_inversion) allows avoiding rather complicated reasoning for lemmas A.12, A.13, where existence of some types should be established by induction. All additional inductive definitions used in Jerome Vouillon's solution were removed, by introducing explicit operators. This results in somehow more lengthy proofs, but to my mind justified, since any inductive definitions with their properties are just extra assumptions (proven metatheoreticaly to be consistent). It could became especially important for abstract solutions (which I am planning to work on), where we are explicitly indicate all required assumptions and any extra assumptions are diminishing quality of such solutions. Evaluation relation (red) and reduction step (progr) are defined explicitly as Coq fixpoint operators, so basically providing solution for challenge 3 (without records). One can easily extract them as Ocaml/Haskell programs or use 'eval compute in' statement directly within Coq environment. For the latest case slight modification of development required, since Coq canonic natural numbers are hidden within module M_T_Nat (see sub_def.v). One can change opaque definition 'Module M_T_Nat:T_Nat' to transparent 'Module M_T_Nat<:T_Nat', but some proofs will also require changes since Coq will do more automatic reductions for transparent definitions. There could be also added verification of entered terms and verification programs extracted, similar to development of Bruno Barras for Calculus of Construction (see http://pauillac.inria.fr/~barras). Same development could be used as example of technique to translate name-carrying terms and to define their alpha-equivalence. In case there will be time (also need and response), I am planning to do something also with name-caring syntax, at least to show its correspondence with de Bruijn syntax and to provide explicit operators for alpha-equivalence (especially waiting for more details of Urban's and Tasson's approach (http://www.mathematik.uni-muenchen.de/~urban/nominal), possible will try to implement it with Coq). Any cooperation is desirable; there is lot to do, but not having sufficient time.For immediate contribution one can try to improve implementation of module M_T_Nat by exposing all used properties of natural numbers, removing usage of omega and reducing compilation time (which now is too high, probably tactics used are proving same things many times). Suggestion for future work or comments are welcome. Also, if there are some possibilities to host separate web site devoted to Coq solutions, I will be glad to contribute by either maintaining it or just by providing information. Best Regards. Jevgenijs Sallinens (PhD in mathematics, currently programmer) ------------------------------------------------- This mail sent through IMP: http://webmail.dva.lv/ -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: compile.txt Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/compile-0001.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tactics.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/tactics-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: sub_defs.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/sub_defs-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: sub.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/sub-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: typ_defs.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/typ_defs-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: typ.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/typ-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: red_defs.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/red_defs-0001.ksh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: red.v Url: http://lists.seas.upenn.edu/pipermail/poplmark/attachments/20050825/09db451c/red-0001.ksh From crary at cs.cmu.edu Mon Aug 29 11:56:37 2005 From: crary at cs.cmu.edu (Karl Crary) Date: Mon, 29 Aug 2005 11:56:37 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: Message-ID: <43133035.9010704@cs.cmu.edu> Hi Stephanie and others, I'm coming into this discussion late, but I wanted to make some remarks about this: Stephanie Weirich wrote: >1) No polymorphism for logical operators > > > I really don't think this is a serious issue, at least once one gets used to Twelf. The sort of equality-utilization lemma you refer to is quite typical, and I don't find it troubling at all. With the help of an emacs macro, I can define and prove those lemmas in just a few seconds; not much more time than it would take to run a tactic. Of course, that's only the first time; after that you have the lemma available. The upcoming module system is supposed to eliminate the need for this, but frankly, I find polymorphism to be such a non-issue that I'm not in any special hurry for it. >2) Constructive logic and logic programming > > > I'm fairly suspicious about this point. Classical logic really shouldn't be helping you in any significant way, and if it is, I suspect you're proving the wrong thing. In this case, I think that either your operational semantics is mis-specified or your safety proof is incomplete, depending on what viewpoint you want to take. Type safety means that a well-typed program will execute successfully until it terminates. This means that if the program has not terminated, then a transitition exists and a machine can find it. Usually the specification of the operational semantics makes it obvious that a machine can find whatever transition that exists, so we focus exclusively on the former. However, if the operational semantics requires the machine to decide an undecidable problem, than that language is *not* type safe. So I claim that either your operational semantics should explicitly give an algorithm for deciding subtyping, or you need to prove that subtyping is decidable. Either way, classical logic won't be of any help. (As an aside, I'm also suspicious of the semantic foundations of classical Coq. The semantics of the Calculus of Constructions are completely well understood. For Inductive Constructions they are a lot less accessible, but I believe they are also well established. Of Induction Constructions + excluded middle I know nothing -- but perhaps someone will give me a reference.) >3) HOAS, non-modularity and strengthening > > > I think Michael has already shown how to make this issue go away in your proof, but I wanted to make a larger point. I believe that issue arose at all only because you made the class table (which includes all the code) a parameter to everything, thereby making exp subordinate to other types that it shouldn't be subordinate to. A better design would be to make the subtyping relation the general parameter, and then check that the subtyping relation is compatible with the class table. If you did that, you wouldn't have had the problematic subordination edge in the first place. That's not the point. The point is that a language design that seemed perfectly reasonable on paper turned out to be subtly flawed once we went to formalize the metatheory. This underlines something a point I've made before: it's a mistake to take the paper design as written in stone when we start formalization. If we do that, we can fail to observe significant possibilities for improvement that we would have discovered in the course of formalization. >4) Bottom-up vs. top-down > > > The %trustme directive is implemented in the latest CVS version. That should give you what you want. -- Karl From bcpierce at cis.upenn.edu Tue Aug 30 10:48:46 2005 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Tue, 30 Aug 2005 10:48:46 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <43133035.9010704@cs.cmu.edu> References: <43133035.9010704@cs.cmu.edu> Message-ID: Hi Karl, > Type safety means that a well-typed program will execute successfully > until it terminates. This means that if the program has not > terminated, > then a transitition exists and a machine can find it. Usually the > specification of the operational semantics makes it obvious that a > machine can find whatever transition that exists, so we focus > exclusively on the former. However, if the operational semantics > requires the machine to decide an undecidable problem, than that > language is *not* type safe. Seems to me this is confusing type safety with implementability. Suppose that the FJ subtyping relation were *not* decidable. The evaluation of a program would still be perfectly determinate (since, mathematically, either S References: <43133035.9010704@cs.cmu.edu> Message-ID: <4314996A.10509@cs.cmu.edu> I don't think I'm confusing anything. My point is that the excluded middle arises solely because the operational semantics is required, primitively, to decide a question that formally is not known to be decidable. I wouldn't really call the language safe if you can't execute it, but it's not my point to argue about the terminology. If "unsafe" is too loaded of a term, shall we settle for a simpler term, such as "broken"? :-) -- Karl Benjamin Pierce wrote: > Hi Karl, > >> Type safety means that a well-typed program will execute successfully >> until it terminates. This means that if the program has not >> terminated, >> then a transitition exists and a machine can find it. Usually the >> specification of the operational semantics makes it obvious that a >> machine can find whatever transition that exists, so we focus >> exclusively on the former. However, if the operational semantics >> requires the machine to decide an undecidable problem, than that >> language is *not* type safe. > > > Seems to me this is confusing type safety with implementability. > > Suppose that the FJ subtyping relation were *not* decidable. The > evaluation of a program would still be perfectly determinate (since, > mathematically, either S still want to argue that this notion of evaluation was sound, in the > sense that every well-typed term either is a value or is related, by > the single-step evaluation relation, to some other well-typed term. > > Indeed, this would be exactly the case if we extended Fsub with some > kind of downcasting. Such an extension might or might not be a good > idea, but I think it is muddling words to claim that it would be > *unsafe*. > > - Benjamin > > > From stevez at cis.upenn.edu Tue Aug 30 13:50:01 2005 From: stevez at cis.upenn.edu (Steve Zdancewic) Date: Tue, 30 Aug 2005 13:50:01 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <4314996A.10509@cs.cmu.edu> References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> Message-ID: <43149C49.9030204@cis.upenn.edu> Karl Crary wrote: > I don't think I'm confusing anything. My point is that the excluded > middle arises solely because the operational semantics is required, > primitively, to decide a question that formally is not known to be > decidable. > > I wouldn't really call the language safe if you can't execute it, but > it's not my point to argue about the terminology. If "unsafe" is too > loaded of a term, shall we settle for a simpler term, such as "broken"? :-) "Broken" As though that isn't loaded. :-) I think Benjamin's point is that the definition of soundness makes no reference to the computability of the transition relation -- that is something that you're imposing on the definitions with the added condition that "a machine can find" the transition. If I take the definition of soundness literally, I don't see any "machine" mentioned anywhere. Soundness makes perfect sense for languages that can't be implemented on a Turing machine. Whether or not such a thing is useful is another matter... --Steve From naumann at cs.stevens.edu Tue Aug 30 14:25:51 2005 From: naumann at cs.stevens.edu (David Naumann) Date: Tue, 30 Aug 2005 14:25:51 -0400 (EDT) Subject: [POPLmark] Experience report with Twelf In-Reply-To: <43149C49.9030204@cis.upenn.edu> References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> Message-ID: > Soundness makes perfect sense for languages that can't be implemented on > a Turing machine. Whether or not such a thing is useful is another > matter... Languages used for specification and for modular verification are often not computable in this sense. Typing may or may not be decidable. Usefulness seems clear. From sweirich at cis.upenn.edu Tue Aug 30 14:30:15 2005 From: sweirich at cis.upenn.edu (Stephanie Weirich) Date: Tue, 30 Aug 2005 14:30:15 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <43133035.9010704@cs.cmu.edu> References: <43133035.9010704@cs.cmu.edu> Message-ID: Hi Karl, thanks for the reply! > >> 3) HOAS, non-modularity and strengthening >> >> >> > > I think Michael has already shown how to make this issue go away in > your proof, but I wanted to make a larger point. I believe that > issue arose at all only because you made the class table (which > includes all the code) a parameter to everything, thereby making > exp subordinate to other types that it shouldn't be subordinate > to. A better design would be to make the subtyping relation the > general parameter, and then check that the subtyping relation is > compatible with the class table. If you did that, you wouldn't > have had the problematic subordination edge in the first place. > > That's not the point. The point is that a language design that > seemed perfectly reasonable on paper turned out to be subtly flawed > once we went to formalize the metatheory. This underlines > something a point I've made before: it's a mistake to take the > paper design as written in stone when we start formalization. If > we do that, we can fail to observe significant possibilities for > improvement that we would have discovered in the course of > formalization. > Certainly, I'm willing to change a language design to better suit my proof assistant. In fact, I made several small modifications to the specification to make things easier to prove. But, if a *particular* proof assistant (and language representation) is going to require me to modify my specification, I'd like to know about it ahead of time. My Coq proof did not require as significant a modification to the specification of FJ as you propose. (Nor do I think your modification would significantly improve my Coq proof.) In my original email, I was listing the reasons why I preferred Coq to Twelf in this particular instance---the fact that I didn't have to deal with subordination, either by modifying my specification, or by carefully crafting my proof, is one of them. --Stephanie From crary at cs.cmu.edu Tue Aug 30 14:30:31 2005 From: crary at cs.cmu.edu (Karl Crary) Date: Tue, 30 Aug 2005 14:30:31 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <43149C49.9030204@cis.upenn.edu> References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> Message-ID: <4314A5C7.9010000@cs.cmu.edu> Sure, we could stipulate that a program runs on an oracle machine that is capable of deciding undecidable problems. We could work out the metatheory for the oracle version and it's easy to see how classical logic would arise in such an account. However, I never thought the downcasting check in FJ was intended to require an oracle machine. Rather, I took it as a technical shorthand for a dynamic check that really could be implemented. (I am fairly certain that Benjamin intended it that way as well.) If so, then proving that it actually can be is an essential part of the metatheory. Whether you prefer to call it part of "safety," I don't really care. The only other option is to lay out the operational semantics in such a way that it shows how to do the downcasting check (presumably, using some sort of tagging regime). If you do that, you're off the hook for the proof, but I don't see it as an option to do neither, unless you're embracing the oracle-machine interpretation. -- Karl Steve Zdancewic wrote: > I think Benjamin's point is that the definition of soundness makes no > >reference to the computability of the transition relation -- that is >something that you're imposing on the definitions with the added >condition that "a machine can find" the transition. If I take the >definition of soundness literally, I don't see any "machine" mentioned >anywhere. > >Soundness makes perfect sense for languages that can't be implemented on >a Turing machine. Whether or not such a thing is useful is another >matter... > > > From crary at cs.cmu.edu Tue Aug 30 14:54:31 2005 From: crary at cs.cmu.edu (Karl Crary) Date: Tue, 30 Aug 2005 14:54:31 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <43133035.9010704@cs.cmu.edu> Message-ID: <4314AB67.4070308@cs.cmu.edu> Aren't you turning the matter entirely on its head? Coq gives you no *benefit* to thinking about subordination, whereas Twelf does. (To be fair, I don't think Coq can. Starting from the Calculus of Constructions, I don't think you can define a reasonable notion of subordination. But perhaps I'll be proven wrong.) Setting that aside, now that you have some experience using Twelf, I'll bet that you will think about subordination ahead of time in the future. -- Karl Stephanie Weirich wrote: > But, if a *particular* proof assistant (and language representation) > is going to require me to modify my specification, I'd like to know > about it ahead of time. My Coq proof did not require as significant a > modification to the specification of FJ as you propose. (Nor do I > think your modification would significantly improve my Coq proof.) In > my original email, I was listing the reasons why I preferred Coq to > Twelf in this particular instance---the fact that I didn't have to > deal with subordination, either by modifying my specification, or by > carefully crafting my proof, is one of them. > > --Stephanie > From dpw at CS.Princeton.EDU Tue Aug 30 15:04:05 2005 From: dpw at CS.Princeton.EDU (David Walker) Date: Tue, 30 Aug 2005 15:04:05 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: Message-ID: <200508301904.j7UJ4DB4012224@bluebox.CS.Princeton.EDU> > > This underlines > > something a point I've made before: it's a mistake to take the > > paper design as written in stone when we start formalization. If > > we do that, we can fail to observe significant possibilities for > > improvement that we would have discovered in the course of > > formalization. As we are language designers, it is often the case that we are designing the language at the same time as we are formalizing it. In this case, allowing the logical framework to help guide the specification of the semantics is a great idea. (I like the specification of the pi-calculus that emerges from Concurrent LF much better than most of the other specifications of the pi-calculus I have seen...though that is another story...) On the other hand, there are certainly situations in which the on-paper formalization really is set in stone. For instance, if a language already has a specification and that specification is the basis for a variety of implementations, you really cannot rewrite the spec as you verify it. More concretely, imagine the Department of Defense gives you the spec for their weapon systems. You are going to have to prove the adequacy of your formalization with respect to the spec you are given, not some other improved spec, no matter how much more elegant the new spec is. In other words, there can be a "legacy spec" issue. Dave From rwh at cs.cmu.edu Tue Aug 30 15:18:57 2005 From: rwh at cs.cmu.edu (Robert Harper) Date: Tue, 30 Aug 2005 15:18:57 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <200508301904.j7UJ4DB4012224@bluebox.CS.Princeton.EDU> References: <200508301904.j7UJ4DB4012224@bluebox.CS.Princeton.EDU> Message-ID: <95ceefcb1ece6db18a5e38c1b1665849@cs.cmu.edu> I think it would be a grave error to attempt to take on such a job. I don't believe that the "throw it over the wall" model can ever be an effective way to proceed; you're just setting yourself up for failure. Bob On Aug 30, 2005, at 3:04 PM, David Walker wrote: >>> This underlines >>> something a point I've made before: it's a mistake to take the >>> paper design as written in stone when we start formalization. If >>> we do that, we can fail to observe significant possibilities for >>> improvement that we would have discovered in the course of >>> formalization. > > As we are language designers, it is often the case that we are > designing the > language at the same time as we are formalizing it. In this case, > allowing > the logical framework to help guide the specification of the semantics > is a > great idea. (I like the specification of the pi-calculus that emerges > from > Concurrent LF much better than most of the other specifications of the > pi-calculus I have seen...though that is another story...) > > On the other hand, there are certainly situations in which the on-paper > formalization really is set in stone. For instance, if a language > already > has a specification and that specification is the basis for a variety > of > implementations, you really cannot rewrite the spec as you verify it. > More > concretely, imagine the Department of Defense gives you the spec for > their > weapon systems. You are going to have to prove the adequacy of your > formalization with respect to the spec you are given, not some other > improved spec, no matter how much more elegant the new spec is. In > other > words, there can be a "legacy spec" issue. > > Dave > > _______________________________________________ > Poplmark mailing list > Poplmark at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/poplmark From jevgenijs at dva.lv Tue Aug 30 15:52:19 2005 From: jevgenijs at dva.lv (Jevgenijs Sallinens) Date: Tue, 30 Aug 2005 12:52:19 -0700 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <4314A5C7.9010000@cs.cmu.edu> References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> <4314A5C7.9010000@cs.cmu.edu> Message-ID: <1125431539.4314b8f36335f@webmail.dva.lv> Quoting Karl Crary : > Sure, we could stipulate that a program runs on an oracle machine that > is capable of deciding undecidable problems. We could work out the > metatheory for the oracle version and it's easy to see how classical > logic would arise in such an account. > > However, I never thought the downcasting check in FJ was intended to > require an oracle machine. Rather, I took it as a technical shorthand > for a dynamic check that really could be implemented. (I am fairly > certain that Benjamin intended it that way as well.) If so, then > proving that it actually can be is an essential part of the metatheory. > Whether you prefer to call it part of "safety," I don't really care. > > The only other option is to lay out the operational semantics in such a > way that it shows how to do the downcasting check (presumably, using > some sort of tagging regime). If you do that, you're off the hook for > the proof, but I don't see it as an option to do neither, unless you're > embracing the oracle-machine interpretation. Being newcomer in the field (and knowing nothing about FJ and down-casting), I will try just to formulate my understanding of decidability problems in context of PoplMark challenge. Writing it more as a questions to be confirmed by experts, since understanding of these problems could be helpful also for others challenge contibutors/users. Sorry for trouble, if these things lloks to be so trivial for experts. As I suspect (nobody answered my previous e-mail in that respect), F-sub described in the challenge is exactly the same proven by Benjamin to be undesidable (for subtyping (and therefore for typing) relation). This lloks basicly making impossible to present solution for problem 2 of challenge 3 (at least with Coq), since reflexive-transitive closure of evaluation relation could not be given as always terminating total computable function (to be presented in Coq with fixpoint definitions). But all this doesn't prevent us from reasoning about subtyping/typing relations or reflexive-transitive closure of evaluation relation and such reasoning could be performed (for challanges in question) by intuitionistic resoning (without excluded middle assumptions). Within logical enviroment, we can interpret results about undecidable relations as something like: if we are able to prove relation valid for some specific objects, then we can use general results about this relation to derive some other results about same objects. Possible similar we can do for computation: if we are so lucky that computations terminates for some objects, then we can use general results to establish their properties. This was stated in Hongwei Xi's submission letter, but I am not sure if we have safe basis to reason about (possible) unterminating algorithms. Looks, such algorithms and relations provided by Coq inductive definitions are not the same thing and not clear what then means such 'algorithm' for Coq. I am not familiar with Twelf, but interested (hope also many others readers) on information about how Twelf submission is related to undecidabilty of F-sub. Are they somehow affecting assumption made to belief proofs (or typechecking of proof scripts)?. Best regards, Jevgenijs Sallinens. PS: undecidable means no the same as not realizable with Turing machine,as could be interpreted from one of previous e-mails. ------------------------------------------------- This mail sent through IMP: http://webmail.dva.lv/ From naumann at cs.stevens.edu Tue Aug 30 23:26:55 2005 From: naumann at cs.stevens.edu (David Naumann) Date: Tue, 30 Aug 2005 23:26:55 -0400 (EDT) Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <43133035.9010704@cs.cmu.edu> Message-ID: I appreciate Benjamin's comment and am puzzled by the ensuing discussion. Karl (and Bob) have eloquently made the important point that doing a machine-checkable formalization can lead to design improvements in one's metatheory. In theoretical work, separation of concerns is usually a design improvement, and that seems to be Benjamin's point. On Tue, 30 Aug 2005, Benjamin Pierce wrote: > Date: Tue, 30 Aug 2005 10:48:46 -0400 > From: Benjamin Pierce > To: Karl Crary > Cc: poplmark at lists.seas.upenn.edu > Subject: Re: [POPLmark] Experience report with Twelf > > Hi Karl, > >> Type safety means that a well-typed program will execute successfully >> until it terminates. This means that if the program has not >> terminated, >> then a transitition exists and a machine can find it. Usually the >> specification of the operational semantics makes it obvious that a >> machine can find whatever transition that exists, so we focus >> exclusively on the former. However, if the operational semantics >> requires the machine to decide an undecidable problem, than that >> language is *not* type safe. > > Seems to me this is confusing type safety with implementability. > > Suppose that the FJ subtyping relation were *not* decidable. The > evaluation of a program would still be perfectly determinate (since, > mathematically, either S still want to argue that this notion of evaluation was sound, in the > sense that every well-typed term either is a value or is related, by > the single-step evaluation relation, to some other well-typed term. > > Indeed, this would be exactly the case if we extended Fsub with some > kind of downcasting. Such an extension might or might not be a good > idea, but I think it is muddling words to claim that it would be > *unsafe*. > > - Benjamin > > > _______________________________________________ > Poplmark mailing list > Poplmark at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/poplmark > From rap at inf.ed.ac.uk Wed Aug 31 11:31:45 2005 From: rap at inf.ed.ac.uk (Randy Pollack) Date: Wed, 31 Aug 2005 16:31:45 +0100 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <95ceefcb1ece6db18a5e38c1b1665849@cs.cmu.edu> References: <200508301904.j7UJ4DB4012224@bluebox.CS.Princeton.EDU> <95ceefcb1ece6db18a5e38c1b1665849@cs.cmu.edu> Message-ID: <17173.52577.495290.915214@slim.inf.ed.ac.uk> > >>> This underlines > >>> something a point I've made before: it's a mistake to take the > >>> paper design as written in stone when we start formalization. If > >>> we do that, we can fail to observe significant possibilities for > >>> improvement that we would have discovered in the course of > >>> formalization. Bob, David and Karl all seem to agree on this, and I do too. The interesting new question in the present POPLmark discussion is how the particular logic/checking tool chosen for the formalisation effects the "significant possibilities for improvement" that we observe. Randy From rap at inf.ed.ac.uk Wed Aug 31 12:29:14 2005 From: rap at inf.ed.ac.uk (Randy Pollack) Date: Wed, 31 Aug 2005 17:29:14 +0100 Subject: [POPLmark] Experience report with Twelf Message-ID: <17173.56026.331401.913292@slim.inf.ed.ac.uk> Jevgenijs Sallinens writes: > Sorry for trouble, if these things lloks to be so trivial for experts. > As I suspect (nobody answered my previous e-mail in that respect), F-sub > described > in the challenge is exactly the same proven by Benjamin to be undesidable > (for subtyping (and therefore for typing) relation). > This lloks basicly making impossible to present solution for problem 2 of > challenge 3 > (at least with Coq), since reflexive-transitive closure of evaluation relation > could not be given as always terminating total computable function > (to be presented in Coq with fixpoint definitions). One can write a wrapper function that takes a natural number, n, and executes evaluation n steps. In practice this is no different from being able to execute non-total functions. And this point has nothing to do with constructivity: classical HOL also has only total functions. In Isabelle/HOL one could use the simplifier to iteratively apply an evaluation relation. Randy From baydemir at cis.upenn.edu Wed Aug 31 15:14:34 2005 From: baydemir at cis.upenn.edu (Brian E. Aydemir) Date: Wed, 31 Aug 2005 15:14:34 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: <1125431539.4314b8f36335f@webmail.dva.lv> References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> <4314A5C7.9010000@cs.cmu.edu> <1125431539.4314b8f36335f@webmail.dva.lv> Message-ID: On 30 Aug 2005, at 15:52, Jevgenijs Sallinens wrote: > As I suspect (nobody answered my previous e-mail in that respect), > F-sub described in the challenge is exactly the same proven by > Benjamin to be undesidable (for subtyping (and therefore for > typing) relation). Right. Benjamin proved that the subtyping and typing relations of pure F-sub (without records) are undecidable, and the result carries over to F-sub extended with records. > This lloks basicly making impossible to present solution for > problem 2 of challenge 3 (at least with Coq), since reflexive- > transitive closure of evaluation relation could not be given as > always terminating total computable function (to be presented in > Coq with fixpoint definitions). Unlike in Featherweight Java, a derivation of "t1 --> t2" in F-sub does not require the construction of any subtyping derivations. Thus, the undecidability of the subtyping and typing relations does not necessarily imply that the evaluation relation is also undecidable. -Brian From jevgenijs at dva.lv Wed Aug 31 15:54:56 2005 From: jevgenijs at dva.lv (Jevgenijs Sallinens) Date: Wed, 31 Aug 2005 12:54:56 -0700 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> <4314A5C7.9010000@cs.cmu.edu> <1125431539.4314b8f36335f@webmail.dva.lv> Message-ID: <1125518096.43160b10ad164@webmail.dva.lv> Quoting "Brian E. Aydemir" : > > Unlike in Featherweight Java, a derivation of "t1 --> t2" in F-sub > does not require the construction of any subtyping derivations. > Thus, the undecidability of the subtyping and typing relations does > not necessarily imply that the evaluation relation is also undecidable. > Brian, Thank you for confirmation on undecidabilty of F-sub. I think it could be important aspect for 'challengers'. As per evaluation relation : if we consider only one step of reduction then it is decidable (and presented as explicit operator to bool in my submission), but it should be imposible to decide in general if t1 could be reduced to t2 with some unknown number of steps, since otherwise we would have something like strong normalization and usually it implies decidability of typing relation. Best Regards, Jevgenijs Sallinens. ------------------------------------------------- This mail sent through IMP: http://webmail.dva.lv/ From crary at cs.cmu.edu Wed Aug 31 16:55:43 2005 From: crary at cs.cmu.edu (Karl Crary) Date: Wed, 31 Aug 2005 16:55:43 -0400 Subject: [POPLmark] Experience report with Twelf In-Reply-To: References: <43133035.9010704@cs.cmu.edu> <4314996A.10509@cs.cmu.edu> <43149C49.9030204@cis.upenn.edu> <4314A5C7.9010000@cs.cmu.edu> <1125431539.4314b8f36335f@webmail.dva.lv> Message-ID: <4316194F.6040903@cs.cmu.edu> I believe this misses the point entirely. The downcasting check in FJ is--in fact--decidable; I don't believe anyone has contested that. However, Stephanie's opening claim was that it is too hard to *prove* that it is decidable. If that is so, then to be honest we should look at the downcasting check as if it were undecidable, regardless of the facts of the matter. -- Karl Brian E. Aydemir wrote: > Unlike in Featherweight Java, a derivation of "t1 --> t2" in F-sub > >does not require the construction of any subtyping derivations. >Thus, the undecidability of the subtyping and typing relations does >not necessarily imply that the evaluation relation is also undecidable. > > >