Related
I am having a look at first order logic theorem provers such as Vampire and E-Prover, and the TPTP syntax seems to be the way to go. I am more familiar with Logic Programming syntaxes such as Answer Set Programming and Prolog, and although I try refering to a detailed description of the TPTP syntax I still don't seem to grasp how to properly distinguish between interpreted and non interpreted functor (and I might be using the terminology wrong).
Essentially, I am trying to prove a theorem by showing that no model acts as a counter-example. My first difficulty was that I did not expect the following logic program to be satisfiable.
fof(all_foo, axiom, ![X] : (pred(X) => (X = foo))).
fof(exists_bar, axiom, pred(bar)).
It is indeed satisfiable because nothing prevents bar from being equal to foo. So a first solution would be to insist that these two terms are distinct and we obtain the following unsatisfiable program.
fof(all_foo, axiom, ![X] : pred(X) => (X = foo)).
fof(exists_bar, axiom, pred(bar)).
fof(foo_not_bar, axiom, foo != bar).
The Techinal Report clarifies that different double quoted strings are different objects indeed, so another solution is to put quotes here and there, so as to obtain the following unsatisfiable program.
fof(all_foo, axiom, ![X] : (pred(X) => (X = "foo"))).
fof(exists_bar, axiom, pred("bar")).
I am happy not to have manually specify the inequality as that would obviously not scale to a more realistic scenario. Moving closer to my real situation, I actually have to handle composed terms, and the following program is unfortunately satisfiable.
fof(all_foo, axiom, ![X] : (pred(X) => (X = f("foo")))).
fof(exists_bar, axiom, pred(g("bar"))).
I guess f("foo") is not a term but the function f applied to the object "foo". So it could potentially coincide with function g. Although a manual specification that f and g never coincide does the trick, the following program is unsatisfiable, I feel like I'm doing it wrong. And it probably wouldn't scale to my real setting with plenty of terms all to be interpreted as distinct when they are syntactically distinct.
fof(all_foo, axiom, ![X] : (pred(X) => (X = f("foo")))).
fof(exists_bar, axiom, pred(g("bar"))).
fof(f_not_g, axiom, ![X, Y] : f(X) != g(Y)).
I have tried throwing single quotes around, but I didn't find the proper way to do it.
How do I make syntactically different (composed) terms and test for syntactical equality?
Subsidiary question: the following program is satisfiable, because the automated-theorem prover understands f as a function rather than a uninterpreted functor.
fof(exists_f_g, axiom, (?[I] : ((f(foo) = f(I)) & pred(g(I))))).
fof(not_g_foo, axiom, ~pred(g(foo))).
To make it unsatisfiable, I need to manually specify that f is injective. What would be the natural way to obtain this behaviour without specifying injectivity of all functors that occur in my program?
fof(exists_f_g, axiom, (?[I] : ((f(foo) = f(I)) & pred(g(I))))).
fof(not_g_foo, axiom, ~pred(g(foo))).
fof(f_injective, axiom, ![X,Y] : (f(X) = f(Y) => (X = Y))).
First of all let me point you to the Syntax BNF of TPTP. In principle, you have Prolog terms with some predefined infix/prefix operators of appropriate precedences. This means, variables are written in upper case and constants are written in lower case. Also like Prolog, escaping with single quotes allows us to write a constant starting with a capital letter i.e. 'X'. I have never seen double quoted atoms so far, so you might want look up the instructions of the prover on how to interpret them.
But even though the syntax is Prolog-ish, automated theorem proving is a different kind of beast. There is no closed world assumption nor are different constants assumed to be different - that's why you cannot find a proof for:
fof(c1, conjecture, a=b ).
and neither for:
fof(c1, conjecture, ~(a=b) ).
So if you want to have syntactic dis-equality, you need to axiomatize it. Now, assuming a different from b trivially shows that they are different, so I at least claimed: "Suppose there are two different constants a and b, then there exists some variable which is not b."
fof(a1, axiom, ~(a=b)).
fof(c1, conjecture, ?[X]: ~(X=b)).
Since functions in first-order logic are not necessarily injective, you also don't get around of adding your assumption in there.
Please also note the different roles of input formulas: so far you only stated axioms and no conjectures i.e. you ask the prover to show your axiom set to be inconsistent. Some provers might even give up because they use some resolution refinements (e.g. set of support) which restricts resolution between axioms[1]. In any case, you need to be aware that the formula you are trying to prove is of the form A1 ∧ ... ∧ An → C1 ∨ ... Cm where the A are axioms and the C are conjectures.[2]
I hope that at least the syntax is a bit clearer now - unfortunately the answer to the questions is more that atomated theorem provers don't make the same assumptions as you expect, so you have to axiomatize them. These axiomatizations are also often ineffective and you might get better perfomance from specialized tools.
[1] As you already notice, advanced provers like Vampire or E Prover tell you about (counter-)satisfyability instead.
[2] A resolution based theorem prover will first negate that formula and perform a CNF transformation, but even though most TPTP accepting provers are resolution based, that's not a requirement.
In general, mathematica always assumes the most general case, that is, if I set a function
a[s_]:={a1[s],a2[s],a3[s]}
and want to compute its norm Norm[a[s]], for example, it will return:
Sqrt[Abs[a1[s]]^2 + Abs[a2[s]]^2 + Abs[a3[s]]^2]
However, if I know that all ai[s] are real, I can invoke:
Assuming[{a1[s], a2[s], a3[s]} \[Element] Reals, Simplify[Norm[a[s]]]]
which will return:
Sqrt[a1[s]^2 + a2[s]^2 + a3[s]^2]
Which is what I expect.
Problem happens when trying to, for example, derive a[s] and then (note the D):
Assuming[{a1[s], a2[s], a3[s]} \[Element] Reals, Simplify[Norm[D[a[s],s]]]]
Returns again a result involving absolute values - coming from the assumption that the numbers may be imaginary.
What is the way to overcome this problem? I want to define a real-valued function, and work with it as such. That is, for instance, I want its derivatives to be real.
I would use a custom function instead, e.g.
vecNorm[vec_?VectorQ] := Sqrt[ vec.vec ]
Then
In[20]:= vecNorm[D[{a1[s], a2[s], a3[s]}, s]]
Out[20]= Sqrt[
Derivative[1][a1][s]^2 + Derivative[1][a2][s]^2 +
Derivative[1][a3][s]^2]
Warning: I don't have much practical experience with this, so the examples below are not thoroughly tested (i.e. I don't know if too general assumptions can break anything I haven't thought of).
You can use $Assumptions to define permanent assumptions:
We could say that all of a1[s], a2[s], a3[s] are reals:
$Assumptions = {(a1[s] | a2[s] | a3[s]) \[Element] Reals}
But if you have e.g. a1[x] (not a1[s]), then it won't work. So we can improve it a bit using patterns:
$Assumptions = {(a1[_] | a2[_] | a3[_]) \[Element] Reals}
Or just say that all values of a[_] are real:
$Assumptions = {a[_] \[Element] Reals}
Or even be bold and say that everything is real:
$Assumptions = {_ \[Element] Reals}
(I wonder what this breaks)
AppendTo is useful for adding to $Assumptions and keeping previous assumptions.
Just like Assuming, this will only work for functions like Simplify or Integrate that have an Assumtpions option. D is not such a function.
Some functions like Reduce, FindInstance, etc. have an option to work only on the domain of Reals, Integers, etc., which assumes that all expressions and subexpressions they work with are real.
ComplexExpand[] and sometimes FunctionExpand[] may also be useful in similar situations (but not really here). Examples: ComplexExpand[Abs[z]^2, TargetFunctions -> {Sign}] and FunctionExpand[Abs'[x], Assumptions -> {x \[Element] Reals}].
Generally, as far as I know, there is no mathematical way to tell Mathematica that a variable is real. It is only possible to do this in a formal way, using patterns, and only for certain functions that have the Assumptions option. By "formal" I mean that if you tell it that a[x] is real, it will not know automatically that a'[x] is also real.
You could use ComplexExpand in this case albeit with a workaround. For example
ComplexExpand[Norm[a'[s], t]] /. t -> 2
returns
Sqrt[Derivative[1][a1][s]^2 + Derivative[1][a2][s]^2 + Derivative[1][a3][s]^2]
Note that doing something like ComplexExpand[Norm[a'[s], 2]] (or indeed ComplexExpand[Norm[a'[s], p]] where p is a rational number) doesn't work for some reason.
For older Mathematica versions there used to be an add-on package RealOnly that put Mathematica in a reals-only mode. There is a version available in later versions and online with minimal compatibility upgrades. It reduces many situations to a real-only solution, but doesn't work for your Norm case:
I am experimenting with syntax mods in Mathematica, using the Notation package.
I am not interested in mathematical notation for a specific field, but general purpose syntax modifications and extensions, especially notations that reduce the verbosity of Mathematica's VeryLongFunctionNames, clean up unwieldy constructs, or extend the language in a pleasing way.
An example modification is defining Fold[f, x] to evaluate as Fold[f, First#x, Rest#x]
This works well, and is quite convenient.
Another would be defining *{1,2} to evaluate as Sequence ## {1,2} as inspired by Python; this may or may not work in Mathematica.
Please provide information or links addressing:
Limits of notation and syntax modification
Tips and tricks for implementation
Existing packages, examples or experiments
Why this is a good or bad idea
Not a really constructive answer, just a couple of thoughts. First, a disclaimer - I don't suggest any of the methods described below as good practices (perhaps generally they are not), they are just some possibilities which seem to address your specific question. Regarding the stated goal - I support the idea very much, being able to reduce verbosity is great (for personal needs of a solo developer, at least). As for the tools: I have very little experience with Notation package, but, whether or not one uses it or writes some custom box-manipulation preprocessor, my feeling is that the whole fact that the input expression must be parsed into boxes by Mathematica parser severely limits a number of things that can be done. Additionally, there will likely be difficulties with using it in packages, as was mentioned in the other reply already.
It would be easiest if there would be some hook like $PreRead, which would allow the user to intercept the input string and process it into another string before it is fed to the parser. That would allow one to write a custom preprocessor which operates on the string level - or you can call it a compiler if you wish - which will take a string of whatever syntax you design and generate Mathematica code from it. I am not aware of such hook (it may be my ignorance of course). Lacking that, one can use for example the program style cells and perhaps program some buttons which read the string from those cells and call such preprocessor to generate the Mathematica code and paste it into the cell next to the one where the original code is.
Such preprocessor approach would work best if the language you want is some simple language (in terms of its syntax and grammar, at least), so that it is easy to lexically analyze and parse. If you want the Mathematica language (with its full syntax modulo just a few elements that you want to change), in this approach you are out of luck in the sense that, regardless of how few and "lightweight" your changes are, you'd need to re-implement pretty much completely the Mathematica parser, just to make those changes, if you want them to work reliably. In other words, what I am saying is that IMO it is much easier to write a preprocessor that would generate Mathematica code from some Lisp-like language with little or no syntax, than try to implement a few syntactic modifications to otherwise the standard mma.
Technically, one way to write such a preprocessor is to use standard tools like Lex(Flex) and Yacc(Bison) to define your grammar and generate the parser (say in C). Such parser can be plugged back to Mathematica either through MathLink or LibraryLink (in the case of C). Its end result would be a string, which, when parsed, would become a valid Mathematica expression. This expression would represent the abstract syntax tree of your parsed code. For example, code like this (new syntax for Fold is introduced here)
"((1|+|{2,3,4,5}))"
could be parsed into something like
"functionCall[fold,{plus,1,{2,3,4,5}}]"
The second component for such a preprocessor would be written in Mathematica, perhaps in a rule-based style, to generate Mathematica code from the AST. The resulting code must be somehow held unevaluated. For the above code, the result might look like
Hold[Fold[Plus,1,{2,3,4,5}]]
It would be best if analogs of tools like Lex(Flex)/Yacc(Bison) were available within Mathematica ( I mean bindings, which would require one to only write code in Mathematica, and generate say C parser from that automatically, plugging it back to the kernel either through MathLink or LibraryLink). I may only hope that they will become available in some future versions. Lacking that, the approach I described would require a lot of low-level work (C, or Java if your prefer). I think it is still doable however. If you can write C (or Java), you may try to do some fairly simple (in terms of the syntax / grammar) language - this may be an interesting project and will give an idea of what it will be like for a more complex one. I'd start with a very basic calculator example, and perhaps change the standard arithmetic operators there to some more weird ones that Mathematica can not parse properly itself, to make it more interesting. To avoid MathLink / LibraryLink complexity at first and just test, you can call the resulting executable from Mathematica with Run, passing the code as one of the command line arguments, and write the result to a temporary file, that you will then import into Mathematica. For the calculator example, the entire thing can be done in a few hours.
Of course, if you only want to abbreviate certain long function names, there is a much simpler alternative - you can use With to do that. Here is a practical example of that - my port of Peter Norvig's spelling corrector, where I cheated in this way to reduce the line count:
Clear[makeCorrector];
makeCorrector[corrector_Symbol, trainingText_String] :=
Module[{model, listOr, keys, words, edits1, train, max, known, knownEdits2},
(* Proxies for some commands - just to play with syntax a bit*)
With[{fn = Function, join = StringJoin, lower = ToLowerCase,
rev = Reverse, smatches = StringCases, seq = Sequence, chars = Characters,
inter = Intersection, dv = DownValues, len = Length, ins = Insert,
flat = Flatten, clr = Clear, rep = ReplacePart, hp = HoldPattern},
(* body *)
listOr = fn[Null, Scan[If[# =!= {}, Return[#]] &, Hold[##]], HoldAll];
keys[hash_] := keys[hash] = Union[Most[dv[hash][[All, 1, 1, 1]]]];
words[text_] := lower[smatches[text, LetterCharacter ..]];
With[{m = model},
train[feats_] := (clr[m]; m[_] = 1; m[#]++ & /# feats; m)];
With[{nwords = train[words[trainingText]],
alphabet = CharacterRange["a", "z"]},
edits1[word_] := With[{c = chars[word]}, join ### Join[
Table[
rep[c, c, #, rev[#]] &#{{i}, {i + 1}}, {i, len[c] - 1}],
Table[Delete[c, i], {i, len[c]}],
flat[Outer[#1[c, ##2] &, {ins[#1, #2, #3 + 1] &, rep},
alphabet, Range[len[c]], 1], 2]]];
max[set_] := Sort[Map[{nwords[#], #} &, set]][[-1, -1]];
known[words_] := inter[words, keys[nwords]]];
knownEdits2[word_] := known[flat[Nest[Map[edits1, #, {-1}] &, word, 2]]];
corrector[word_] := max[listOr[known[{word}], known[edits1[word]],
knownEdits2[word], {word}]];]];
You need some training text with a large number of words as a string to pass as a second argument, and the first argument is the function name for a corrector. Here is the one that Norvig used:
text = Import["http://norvig.com/big.txt", "Text"];
You call it once, say
In[7]:= makeCorrector[correct, text]
And then use it any number of times on some words
In[8]:= correct["coputer"] // Timing
Out[8]= {0.125, "computer"}
You can make your custom With-like control structure, where you hard-code the short names for some long mma names that annoy you the most, and then wrap that around your piece of code ( you'll lose the code highlighting however). Note, that I don't generally advocate this method - I did it just for fun and to reduce the line count a bit. But at least, this is universal in the sense that it will work both interactively and in packages. Can not do infix operators, can not change precedences, etc, etc, but almost zero work.
(my first reply/post.... be gentle)
From my experience, the functionality appears to be a bit of a programming cul-de-sac. The ability to define custom notations seems heavily dependent on using the 'notation palette' to define and clear each custom notation. ('everything is an expression'... well, except for some obscure cases, like Notations, where you have to use a palette.) Bummer.
The Notation package documentation mentions this explicitly, so I can't complain too much.
If you just want to define custom notations in a particular notebook, Notations might be useful to you. On the other hand, if your goal is to implement custom notations in YourOwnPackage.m and distribute them to others, you are likely to encounter issues. (unless you're extremely fluent in Box structures?)
If someone can correct my ignorance on this, you'd make my month!! :)
(I was hoping to use Notations to force MMA to treat subscripted variables as symbols.)
Not a full answer, but just to show a trick I learned here (more related to symbol redefinition than to Notation, I reckon):
Unprotect[Fold];
Fold[f_, x_] :=
Block[{$inMsg = True, result},
result = Fold[f, First#x, Rest#x];
result] /; ! TrueQ[$inMsg];
Protect[Fold];
Fold[f, {a, b, c, d}]
(*
--> f[f[f[a, b], c], d]
*)
Edit
Thanks to #rcollyer for the following (see comments below).
You can switch the definition on or off as you please by using the $inMsg variable:
$inMsg = False;
Fold[f, {a, b, c, d}]
(*
->f[f[f[a,b],c],d]
*)
$inMsg = True;
Fold[f, {a, b, c, d}]
(*
->Fold::argrx: (Fold called with 2 arguments; 3 arguments are expected.
*)
Fold[f, {a, b, c, d}]
That's invaluable while testing
Suppose I want to construct something like
Array[#1^#2 == 3 &, {3, 3}]
And now I want to replace the "3" with a variable. I can do, for example:
f[x_] := Array[#1^#2 == x &, {x, x}]
The question is: Is there a way using only slots and & as the functional notation?
Not really the answer to the original question, but I noticed that many people got interested in #0 stuff, so here I put a couple of non-trivial examples, hope they will be useful.
Regarding the statement that for nested functions one should use functions with named arguments: while this is generally true, one should always keep in mind that lexical scoping for pure functions (and generally) is emulated in Mathematica, and can be broken. Example:
In[71]:=
Clear[f,g];
f[fun_,val_]:=val/.x_:>fun[x];
g[fn_,val_]:=f[Function[{x},fn[#1^#2==x&,{x,x}]],val];
g[Array,3]
During evaluation of In[71]:= Function::flpar: Parameter specification {3} in
Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>
During evaluation of In[71]:= Function::flpar: Parameter specification {3} in
Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>
Out[74]= Function[{3},Array[#1^#2==3&,{3,3}]][3]
This behavior has to do with the intrusive nature of rule substitutions - that is, with the fact that Rule and RuleDelayed don't care about possible name collisions between names in scoping constructs which may be present in expressions subject to rule applications, and names of pattern variables in rules. What makes things worse is that g and f work completely fine when taken separately. It is when they are mixed together, that this entanglement happens, and only because we were unlucky to use the same pattern variable x in the body of f, as in a pure function. This makes such bugs very hard to catch, while such situations do happen sometimes in practice, so I'd recommend against passing pure functions with named arguments as parameters into higher-order functions defined through patterns.
Edit:
Expanding a bit on emulation of the lexical scoping. What I mean is that, for example, when I create a pure function (which is a lexical scoping construct that binds the variable names in its body to the values of passed parameters), I expect that I should not be able to alter this binding after I have created a function. This means that, no matter where I use Function[x,body-that-depends-on-x], I should be able to treat it as a black box with input parameters and resulting outputs. But, in Mathematica, Function[x,x^2] (for instance) is also an expression, and as such, can be modified like any other expression. For example:
In[75]:=
x = 5;
Function[Evaluate[x],x^2]
During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] should
be a symbol or a list of symbols. >>
Out[76]= Function[5,x^2]
or, even simpler (the essence of my previous warning):
In[79]:= 1/.x_:>Function[x,x^2]
During evaluation of In[79]:= Function::flpar: Parameter specification 1 in Function[1,1^2] should
be a symbol or a list of symbols. >>
Out[79]= Function[1,1^2]
I was bitten by this last behavior a few times pretty painfully. This behavior was also noted by #WReach at the bottom of his post on this page - obviously he had similar experiences. There are other ways of breaking the scope, based on exact knowledge of how Mathematica renames variables during the conflicts, but those are comparatively less harmful in practice. Generally, I don't think these sorts of things can be avoided if one insists on the level of transparency represented by Mathematica expressions. It just seems to be "over-transparent" for pure functions (and lexical scoping constructs generally), but on the other hand this has its uses as well, for example we can forge a pure function at run-time like this:
In[82]:= Block[{x},Function##{x,Integrate[HermiteH[10,y],{y,0,x}]}]
Out[82]= Function[x,-30240 x+100800 x^3-80640 x^5+23040 x^7-2560 x^9+(1024 x^11)/11]
Where the integral is computed only once, at definition-time (could use Evaluate as well). So, this looks like a tradeoff. In this way, the functional abstraction is better integrated into Mathematica, but is leaky, as #WReach noted. Alternatively, it could have been "waterproof", but perhaps for the price of being less exposed. This was clearly a design decision.
How about
Map[Last, #] & /# Array[#1^#2 == #3 &, {#, #, #}] &[3]
Horrendously ugly element extraction, and very interestingly Map[Last, #]& gives me a different result than Last /#. Is this due to the fact that Map has different attributes than &?
I guess you know what the documentation says about nested pure functions.
Use explicit names to set up nested
pure functions (for example):
Function[u, Function[v, f[u, v]]][x]
Anyway, here's the best I could come up with without following the above advice:
f[x_] := Array[#1^#2 == x &, {x, x}]
g = Array[With[{x = #}, #1^#2 == x &], {#, #}] &
g is functionally identical to your original f, but is not really better than the recommended
h = Function[x, Array[#1^#2 == x &, {x, x}]]
How about With[{x = #1}, Array[#1^#2 == x &, {x, x}]] &?
Perhaps
Array[#1^#2 &, {#, #}] /. i_Integer :> i == # &[3]
Or
Thread /# Thread[# == Array[#1^#2 &, {#, #}]] &[3]
When I write out a proof or derivation on paper I frequently make sign errors or drop terms as I move from one step to the next. I'd like to use Mathematica to save myself from these silly mistakes. I don't want Mathematica to solve the expression, I just want to use it carry out and display a series of algebraic manipulations. For a (trivial) example
In[111]:= MultBothSides[Equal[a_, b_], c_] := Equal[c a, c b];
In[112]:= expression = 2 a == a b
Out[112]= 2 a == a b
In[113]:= MultBothSides[expression, 1/a]
Out[113]= 2 == b
Can anyone point me to a package that would support this kind of manipulation?
Edit
Thanks for the input, not quite what I'm looking for though. The symbol manipulation isn't really the problem. I'm really looking for something that will make explicit the algebraic or mathematical justification of each step of a derivation. My goal here is really pedagogical.
Mathematica also provides a number of high-level functions for manipulating algebraic. Among these are Expand, Apart and Together, and Cancel, though there are quite a few more.
Also, for your specific example of applying the same transformation to both sides of an equation (that is, and expression with the head Equal), you can use the Thread function, which works just like your MultBothSides function, but with a great deal more generality.
In[1]:= expression = 2 a == a b
Out[1]:= 2 a == a b
In[2]:= Thread[expression /a, Equal]
Out[2]:= 2 == b
In[3]:= Thread[expression - c, Equal]
Out[3]:= 2 a - c == a b - c
In either of the presented solutions, it should be relatively easy to see what the step entailed. If you want something a little more explicit, you can write your own function like so:
In[4]:= ApplyToBothSides[f_, eq_Equal] := Map[f, eq]
In[5]:= ApplyToBothSides[4 * #&, expression]
Out[5]:= 8 a == 4 a b
It's a generalization of your MultBothSides function that takes advantage of the fact that Map works on expressions with any head, not just head List. If you're trying to communicate with an audience that is unfamiliar with Mathematica, using these sorts of names can help you communicate more clearly. In a related vein, if you want to use replacement rules as suggested by Ira Baxter, it may be helpful to write out Replace or ReplaceAll instead of using the /. syntactic sugar.
In[6]:= ReplaceAll[expression, a -> (x + y)]
Out[6]:= 2 (x + y) == b (x + y)
If you think it would be clearer to have the actual equation, instead of the variable name expression, in your input, and you're using the notebook interface, highlight the word expression with your mouse, call up the contextual menu, and select "Evaluate in Place".
The notebook interface is also a very pleasant environment for doing "literate programming", so you can also explain any steps that are not immediately obvious in words. I believe this is a good practice when writing mathematical proofs regardless of the medium.
I don't think you need a package. What you want to do is to manipulate each formula according to an inference rule. In MMa, you can model inference rules on a formula using transformations. So, if you have a formula f, you can apply an inference rule I by executing (my MMa syntax is 15 years rusty)
f ./ I
to produce the next formula in your sequence.
MMa will of course try to simplify your formulas if they contain standard algebraic operators and terms, such as constant numbers and arithmetic operators. You can prevent MMa from applying its own "inference" rules by enclosing your formula in a Hold[...] form.