Q. HOL is failing to complete the build process. It stops when trying to create the HolBdd theory. Why is this, and what should I do? (5) -- The problem is almost certainly that your copy of MoscowML hasn't been built with dynamic linking correctly enabled. This in turn means that the Muddy BDD package that HolBdd uses can't load. You can test that this is the problem by running hol, and then trying - load "HolBdd"; This should fail with an error message about not being able to load muddy.so. If you decide you do want HolBdd (there is nothing else in HOL that depends on dynamic linking) you will probably need to build Moscow ML yourself. Binaries from the central site in Denmark don't seem to work. However the install.txt file in the distribution does talk about things you need to do to binaries in order to get dynamic linking to work for them, and it would be interesting to hear that someone had got this to work. In any case, to build from sources, you must make sure that you alter the src/Makefile.inc in the MoscowML distribution in line with the instructions in the comments there. This advice seems to solve this problem for 90% of the people reporting it. If it doesn't in your case, please get back to us. Q. How do I antiquote types? (3) -- Antiquoting types works as you would expect when parsing types, so that it is fine to write: - val ty = Type`:bool`; and then - Type`:num -> ^ty`; However, you may wish to also introduce type antiquotations into term parses (as a type constraint on a variable for example). The problem is that you can't just write ^ty in this context, because the parsing function's type insists that all antiquotes be of type term. You must use the ty_antiq function, which magically makes a type appear as a term: - val antity = ty_antiq ty; > val antity = `(ty_antiq(`:bool`))` : Term.term Then: - val x = Term`x:^antity`; It's quite easy to figure out when and why ty_antiq is required if one understands the type of the parsing functions. For example, Term and (fn q => -- q --) have type term frag list -> term While Type and (fn q => == q ==) have type hol_type frag list -> hol_type The frag list refers to the fact that there is a quotation being consumed. A quotation is something that appears between back-quotes. A quotation consists of strings and antiquotations. A term frag list must have antiquotations that are of type term. A hol_type frag list must have antiquotations that are of type hol_type. So, if you use Term to parse a term, you can't directly antiquote in types, because this would violate the typing rules (you can only antiquote in terms if you call Term, because it requires a term frag list). So, in order to accomplish this there is a bit of magic called ty_antiq, which if you look at its type (hol_type -> term) turns a type into a term. The term formed is completely bogus in a logical sense (it's actually a var with a special name and the given type), but can be pushed into the parsing function Term so as to give the effect of antiquoting a type. The function Hol_datatype takes a hol_type frag list, so if you want to antiquote a type into the quotations it takes, you will not need to ty_antiq it. Q. Are error messages during the build like the following a source for concern? (2) > File "Term.sml", line 1328, characters 10-42: > ! let val {const=Const(r1,_),theory,place} = const_decl name > ! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > ! Warning: pattern matching is not exhaustive -- No. Nor is the following sort of output, when configuring the system before building: > /local/scratch/kxs/144/bin/mosmlyac: 4 shift/reduce conflicts. Q. What's the syntax to make a real number like 1.23 ? (1) -- You will need to write 1 + 23/100 (or 123/100, or ...). There's no support currently for decimal constants. To make it explicit that you mean a real (and not an integer), you can write 123r/100, where the "r" suffix forces the numeral to be a real. (This will likely only be an issue if you have both integerTheory and realTheory loaded.) Q. What's the integer and real versions of num's DECIDE and arith_ss? (1) -- For the integers, you can use intLib.COOPER_{CONV,PROVE,TAC} The performance of this is not very good at present, but it decides small goals with small coefficients quickly enough. It's complete for Presburger arithmetic over both :num and :int (so you can mix your quantifiers, and it also proves !x:num. ~(2 * x = 5) which ARITH_CONV and DECIDE both fail to prove.) For the reals, realLib.REAL_ARITH proves universal goals. Q. Is there a nice way to print an arbitrary theory, or list its axioms etc? (print_theory, axioms, theorems, etc only work on current theory) (1) -- You can use DB.theorems "thyname" to get a list of theorems in a theory. Often, the nicest presentation is the theory file's signature itself. For example, listTheory.sig, in /src/list/src/. Q. Why can't I write ``MAP ~ x``? (1) -- When you attempt this, you will get the error message No rule for [~] meaning that the parser wants to do a reduction involving just the special symbol ~, and it can't find a rule that allows this. The rule in the grammar is TM ::= ~ TM. ~ is treated specially, and not just as a function that you'd apply to arguments normally, for two reasons: * it can have precedence weaker than just function application. This means that when you write ~f x, this is parsed as ~(f x). * it can group without needing extra parentheses, so you can write ~~b; you don't need to write ~(~b). To make ~ lose its special status, you should prefix it with a $. ``MAP $~ x`` will work in the example, assuming that x has type :bool list. Q. How do I prove strings equal or inequal? (1) -- Use stringLib.string_EQ_CONV, which reduces equalities over string literals to either T or F. For example, to demonstrate that ``(if "foo" = "bar" then 3 else 1) = 1``, you could write: - val t = ``(if "foo" = "bar" then 3 else 1)``; > val t = ``(if "foo" = "bar" then 3 else 1)`` : Term.term - (DEPTH_CONV stringLib.string_EQ_CONV THENC REWRITE_CONV []) t; > val it = |- (if "foo" = "bar" then 3 else 1) = 1 : Thm.thm Q. I'd like to use MEM as an infix, not a Prefix. Can I do this? (1) -- Yes! Use grammar manipulation functions such as set_fixity to alter its parsing information. These changes can be made to persist when the current theory is exported. For example: - load "listTheory"; - set_fixity "MEM" (Infixr 450); > val it = () : unit - listTheory.MEM; > val it = |- (!x. x MEM [] = F) /\ !x h t. x MEM (h::t) = (x = h) \/ x MEM t : Thm.thm Q. How do I get a datatype's axiom after using Hol_datatype? (1) -- Use TypeBase.axiom_of (valOf (TypeBase.read "mytypename")). Hopefully you won't need to do this very much because many of the contexts in which you previously needed the axiom will be dealt with more smoothly. For example, cases, induction, one-one and distinctness theorems are now proved automatically, and are available from the TypeBase. For example, TypeBase.one_one_of (valOf (TypeBase.read "mytypename")) Q. How to rewrite with a theorem the other way round? (0) -- Use GSYM Q. What's with all this "cut looping" stuff? (0) -- It's the simplifier, and it's turned off in Taupo releases onwards unless you set the trace level to one or higher. Q. How can I find out more information about a HOL_ERR exception? (0) -- If expression e is causing the grief, then write (e) handle E => Raise E (Often the parentheses around e will not be required.)