How does one prove there is a Natural number equal to 1 in Mizar (mathematical theorem proving language)? - theorem-proving

I wanted to write the simplest proof in Mizar mathematical theorem prover language I could think of. So I thought of the following:
there exists x \in Nat : x = 1
there isn't anything simpler that I could think of. I gave it the following attempt:
:: example of a comment
environ
vocabularies MY_MIZAR;
:: adding Natural Numbers
requirments SUBSET, NUMERALS, ARITHM;
::> *210
begin
theorem Th1:
ex x being Nat st x=1
proof
::consider x = 1
:: proof is done
x = 1;
thus Th1;
end;
::>
::> 210: Wrong item in environment declaration
but as you can see Mizar doesn't like my proof. What am I missing?
This still doesn't work:
::: example of a comment
environ
vocabularies MY_MIZAR;
::: adding Natural Numbers
requirements SUBSET, NUMERALS, ARITHM;
::> *856 *825
begin
theorem Th1:
ex x being Nat st x=1
proof
:::consider x = 1
::: proof is done
set x=1;
take x;
thus thesis;
end;
::>
::> 825: Cannot find constructors name on constructor list
::> 856: Inaccessible requirements directive

You can try the following:
1) Fix the 210: error:
x requirments (wrong spelling)
o requirements
2) There will probably be some new errors
about the contents of that line now, so when
you are starting out, it is usually good to
"borrow" an environ that already works, e.g.,
you can use the environ lines from one of the
Mizar articles on natural numbers like
NAT_1.miz:
environ
:: adding Natural Numbers
vocabularies NUMBERS, ORDINAL1, REAL_1, SUBSET_1, CARD_1, ARYTM_3, TARSKI,
RELAT_1, XXREAL_0, XCMPLX_0, ARYTM_1, XBOOLE_0, FINSET_1, FUNCT_1, NAT_1,
FUNCOP_1, PBOOLE, PARTFUN1, FUNCT_7, SETFAM_1, ZFMISC_1;
notations TARSKI, XBOOLE_0, ENUMSET1, ZFMISC_1, SUBSET_1, SETFAM_1, ORDINAL1,
FINSET_1, CARD_1, PBOOLE, NUMBERS, XCMPLX_0, XREAL_0, XXREAL_0, RELAT_1,
FUNCT_1, PARTFUN1, FUNCOP_1, FUNCT_2, BINOP_1;
constructors NUMBERS, XCMPLX_0, XXREAL_0, XREAL_0, CARD_1, WELLORD2, FUNCT_2,
PARTFUN1, FUNCOP_1, FUNCT_4, ENUMSET1, RELSET_1, PBOOLE, ORDINAL1,
SETFAM_1, ZFMISC_1, BINOP_1;
registrations SUBSET_1, ORDINAL1, NUMBERS, XXREAL_0, XREAL_0, CARD_1,
RELSET_1, FUNCT_2, PBOOLE;
requirements REAL, NUMERALS, SUBSET, BOOLE, ARITHM;
definitions SETFAM_1, TARSKI, XBOOLE_0, RELAT_1;
equalities ORDINAL1, XBOOLE_0, CARD_1;
expansions SETFAM_1, ORDINAL1, TARSKI, XBOOLE_0;
theorems AXIOMS, ORDINAL1, XCMPLX_1, XREAL_1, XXREAL_0, TARSKI, ORDINAL2,
XBOOLE_0, CARD_1, FUNCT_2, FUNCT_1, FUNCOP_1, PBOOLE, RELSET_1, RELAT_1,
PARTFUN1, SUBSET_1, NUMBERS, ENUMSET1, XBOOLE_1;
schemes SUBSET_1, ORDINAL2, FUNCT_2, PBOOLE, BINOP_1;
3) To use "1" as your example, you can use "set", "take":
proof
set x=1;
take x;
thus thesis;
end;
Hope this helps.

There are several ways to do this:
Although it is not quite your statement here is an example (It is not quite your statement because you use a "Nat" type).
environ
vocabularies NUMBERS;
constructors ARYTM_0;
notations NUMBERS;
registrations ORDINAL1;
requirements NUMERALS, SUBSET, BOOLE;
begin
1 in NAT;
ex x be object st x = 1;
ex x be object st x in NAT & x = 1;
The 3 statements are verified by mizar as valid, true, demonstrate.
If this is not demonstrated (in the mizar sense), it would indicate the *4 error or even sometimes the *1 error.
In the case of the 3 statements here, the evidence is not explicitly stated. It is contained in the environment because Mizar does not require you to indicate all the steps, some of them are automatic.
It is possible to present in this way, acceptable also to Mizar.
environ
vocabularies NUMBERS;
constructors ARYTM_0;
notations NUMBERS;
registrations ORDINAL1;
requirements NUMERALS, SUBSET, BOOLE;
begin
1 in NAT
proof
thus thesis;
end;
ex x be object st x = 1
proof
thus thesis;
end;
ex x be object st x in NAT & x = 1
proof
thus thesis;
end;
But in this situation, the full expression
proof
thus thesis;
end;
is redundant.
To return to the initial problem, and using the suggestion (user10715283 & user10715216). "can we take an environ that is smaller [...]": yes with a specific tool (clearenv.pl, provide with Mizar-System)
environ
vocabularies NAT_1;
constructors NUMBERS, XCMPLX_0, XREAL_0, BINOP_1;
notations ORDINAL1;
registrations ORDINAL1;
requirements NUMERALS, SUBSET;
begin
theorem Th1:
ex x being Nat st x=1
proof
set x=1;
take x;
thus thesis;
end;

Related

How can I prevent Coq notations in closed scopes interfering with notations in open ones?

I'm fairly new to Coq, and I'm trying to use ListNotations in Coq so that I can write lists like [ 1 ; 2 ] rather than cons 1 (cons 2 nil). However, I'm using a library that defines its own notation for the ; character. I was thinking that I could simply close the right scopes so that the notation I want is visible, but it's not working as I expected.
As a simple example, if I create a file test.v:
Declare Scope example_scope.
Notation "a ; b" := (or a b) (at level 50) : example_scope.
Close Scope example_scope.
Require Import List.
Import ListNotations.
Locate ";".
Compute [ 1 ; 2 ].
...then the output of coqc test.v is:
Notation
"a ; b" := or a b : example_scope
"[ x ; y ; .. ; z ]" := cons x (cons y .. (cons z nil) ..) : list_scope
(default interpretation)
File "./test.v", line 8, characters 10-15:
Error: Unknown interpretation for notation "_ ; _".
If the top three lines are removed from test.v, then it works fine.
Two questions:
Why does this happen? It seems to recognize that the notation I want exists and marks it as the "default interpretation." So then why does it become an "unknown notation" when I try to use it?
What can I do in my code (without altering the top three lines of test.v, for example) to get the notation I want?
Why does this happen? It seems to recognize that the notation I want exists and marks it as the "default interpretation." So then why does it become an "unknown notation" when I try to use it?
There are three points to be aware in this case:
Even if the notations definitions (a.k.a. interpretations) are indeed attached to a scope (or to the default scope), their syntactic definition "goes beyond a given scope" (namely, there is a Reserved Notation vernacular that defines the precedence level and associativity for a notation, independently of the scope).
Here is a related remark in the "Reserving notations" section of Coq refman:
Coq expects all uses of the notation to be defined at the same precedence and with the same associativity. [emphasis mine] To avoid giving the precedence and associativity every time, this command declares a parsing rule (string) in advance without giving its interpretation.
So, your example does not satisfy this rule, as the two occurrences of the ; operands have a different precedence level:
Print Grammar constr. (* tested using Coq 8.11.1 *)
…
| "50" LEFTA
[ SELF; ";"; NEXT
| …
| "0" LEFTA
[ "["; "]"
| "["; constr:operconstr LEVEL "200"; ";"; constr:operconstr LEVEL "200";
";"; LIST1 (constr:operconstr LEVEL "200") SEP ";"; "]"
| "["; constr:operconstr LEVEL "200"; ";"; constr:operconstr LEVEL "200";
"]"
| "["; constr:operconstr LEVEL "200"; "]"
| …
(200 being the default precedence level for inner expressions)
Sometimes, it happens we want to define two notations which share some tokens, typically x < y and x < y < z, to borrow the example from the "Simple factorization rules" section of Coq refman:
Coq extensible parsing is performed by Camlp5 which is essentially a LL1 parser: it decides which notation to parse by looking at tokens from left to right. Hence, some care has to be taken not to hide already existing rules by new rules. Some simple left factorization work has to be done. Here is an example.
Notation "x < y" := (lt x y) (at level 70).
Fail Notation "x < y < z" := (x < y /\ y < z) (at level 70).
(*…*)
Notation "x < y < z" := (x < y /\ y < z) (at level 70, y at next level).
Even if this remark is loosely related to your example, it highlights the fact that defining several notations that share several tokens (a common prefix) can be feasible by tuning the precedence level of the inner sub-expressions.
Last but not least, it appears that combining the notations a ; b and [x ; y ; .. ; z] leads to an ambiguous syntax, because (assuming the precedence-level issue mentioned in point 1. were solved), if both scopes are opened, how do you distinguish between cons True (cons True nil) and cons (or True True) nil? both would be a possible interpretation of [True; True].
What can I do in my code (without altering the top three lines of test.v, for example) to get the notation I want?
I guess you can't.
Adding
Notation "a ; b" := (or a b) (at level 50) : example_scope.
at the beginning of your module has an (unintended) side-effect that cannot be workarounded afterwards.
If you really need a semicolon-like notation for or, maybe you could try using ;;, for example:
Notation "a ;; b" := (or a b) (at level 50) : example_scope.
More generally, it seems quite risky to use a mere "separator" (semicolon or comma) as a binary operator: usually, a single ; or , will only be used within (square) brackets.
Finally as an aside, using square brackets in notations (even if ListNotations do so) might confuse the parser in some cases. So regarding lists in particular, if ever you are a math-comp user, you may want to rely on the seq theory instead, which is fully compatible with the Coq standard library (Notation seq := list.), has a comprehensive set of lemmas, and introduce this alternative notation which doesn't rely on a leading single square bracket:
Notation "[ :: x1 ; x2 ; .. ; xn ]" := (x1 :: x2 :: .. [:: xn] ..)
(at level 0, format "[ :: '[' x1 ; '/' x2 ; '/' .. ; '/' xn ']' ]"
) : seq_scope.

Coercion within data structures

The following code gives me an error:
Require Import Reals.
Require Import List.
Import ListNotations.
Open Scope R_scope.
Definition C := (R * R)%type.
Definition RtoC (r : R) : C := (r,0).
Coercion RtoC : R >-> C.
Definition lC : list C := [0;0;0;1].
Error: The term "[0; 0; 0; 1]" has type "list R" while it is expected to have type "list C".
But I've defined RtoC as a coercion and I don't see any problems when I use
Definition myC : C := 4.
How do I get Coq to apply the coercion within the list?
Related question: If I enter Check [0;0;0;1] it returns list R, inserting an implicit IZR before every number. Why does Coq think I want Rs rather than Zs?
I'm unsure there is a fully satisfying solution to your question.
Indeed, as recalled in the Coq refman:
Given a term, possibly not typable, we are interested in the problem of determining if it can be well typed modulo insertion of appropriate coercions.
and it turns out that in your example, the term [0;0;0;1] itself is typable as a list R and it is type-checked "in one go"; thereby when the [0;0;0;1] : list C type mismatch occurs, as there's no "backtracking", a coercion can't be inserted within the list elements.
So maybe you could adapt your formalization in a different way, or just use one of these workarounds:
Rewriting your term into a β-redex:
Definition lC := (fun z o => [z;z;z;o] : list C) 0 1.
Or inserting a few more typecasts around each element:
Definition lC := [0:C; 0:C; 0:C; 1:C].
Regarding your last question
Why does Coq think I want Rs rather than Zs?
this comes from your line Open Scope R_scope., which implies numeral litterals are recognized by default as belonging to R (which deals with the classical axiomatization of the real numbers formalized in the standard library Reals). More specifically, the implementation has changed in Coq 8.7, as from coq/coq#a4a76c2 (discussed in PR coq/coq#415). To sum up, a literal such as 5%R is now parsed as IZR 5, that is, IZR (Zpos (xI (xO xH))), while it used to be parsed to a much less concise term in Coq 8.6:
Rplus R1 (Rmult (Rplus R1 R1) (Rplus R1 R1)).

Does IEC-61131 Structured Text allow comparison of boolean operands?

I'm building a parser and type checker for Structured Text. ST is a derivative of Pascal.
It is clear that ST allows equality comparison of two declared real variables X and Y as
X = Y
It is also clear you can write
X <> Y
and
X > Y
If I have two declared boolean variables A and B, is
A = B
legal? Pascal would certainly say so. The reference documents I have for ST (including an Australian version of the 2004 standard, and several vendors implementations) are unclear.
Can I write:
A > B
and what does it mean?
[In the abstract, I'm interested in the same questions for comparing strings. Brownie points for addressing that issue too].
[No, I can't just try it on a real controller; I don't actually have one and the nearest one is effectively two days away from me.]
What's the answer, and what's the reference document you consulted that shows the answer?
The answer to this question really depends on IDE. Although there is a standard for ST, every vendor implement it little bit differently.
In general this is valid statement.
VAR
a, b: BOOL;
END_VAR
IF a = b THEN
// Do something
END_IF
Here is what is in IEC 61131-3 draft. Unfortunately it is not open document and costs money that is why I cannot post it here or provide a link.
https://webstore.iec.ch/publication/4552
GT > Decreasing sequence: OUT := (IN1>IN2) & (IN2>IN3) & ... & (INn-1 > INn)
GE >= Monotonic sequence: OUT := (IN1>=IN2)&(IN2>=IN3)& ... & (INn-1 >= INn)
EQ = Equality: OUT := (IN1=IN2) & (IN2=IN3) & ... & (INn-1 = INn)
LE <= Monotonic sequence: OUT := (IN1<=IN2)&(IN2<=IN3)& ... & (INn-1 <= INn)
LT < Increasing sequence: OUT := (IN1<IN2) & (IN2<IN3) & ... & (INn-1 < INn)
NE <> Inequality (non-extensible) OUT := (IN1 <> IN2)
This also means that in some IDEs you can use
IF EQ(a, b) THEN
// Do something
END_IF
And this should be valid as well.
Can I write:
A > B
and what does it mean?
If A greater than B this expression will return TRUE otherwise FALSE.

New Scope in Coq

I'd like my own scope, to play around with long distfixes.
Declare Scope my_scope.
Delimit Scope my_scope with my.
Open Scope my_scope.
Definition f (x y a b : nat) : nat := x+y+a+b.
Notation "x < y * a = b" := (f x y a b)
(at level 100, no associativity) : my_scope.
Check (1 < 2 * 3 = 4)%my.
How do you make a new scope?
EDIT: I chose "x < y * a = b" to override Coq's operators (each with a different precedence).
The command Declare Scope does not exist. The various commands about scopes are described in section 12.2 of the Coq manual.
Your choice of an example notation has inherent problems, because it clashes with pre-defined notations, which seem to be used before your notation.
When looking at the first components the parser sees _ < _ and thinks that you are actually talking about comparison of integers, then it sees the second part as being an instance of the notation _ * _, then it sees that all that is the left hand side of an equality. And all along the parser is happy, it constructs an expression of the form:
(1 < (2 * 3)) = 4
This is constructed by the parser, and the type system has not been solicited yet. The type checker sees a natural number as the first child of (_ < _) and is happy. It sees (_ * _) as the second child and it is happy, it now knows that the first child of that product should be a nat number and it is still happy; in the end it has an equality, and the first component of this equality is in type Prop, but the second component is in type nat.
If you type Locate "_ < _ * _ = _". the answer tells you that you did define a new notation. The problem is that this notation never gets used, because the parser always finds another notation it can use before. Understanding why a notation is preferred to another one requires more knowledge of parsing technology, as alluded to in Coq's manual, chapter 12, in the sentence (obscure to me):
Coq extensible parsing is performed by Camlp5 which is essentially a LL1 parser.
You have to choose the levels of the various variables, x, y, a, and b so that none of these variables will be able to match too much of the text. For instance, I tried defining a notation close to yours, but with a starting and an ending bracket (and I guess this simplifies the task greatly).
Notation "<< x < y * a = b >>" := (f x y a b)
(x at level 59, y at level 39, a at level 59) : my_scope.
The level of x is chosen to be lower than the level of =, the level of y is chosen to be lower than the level of *, the level of a is chosen to be lower than =. The levels were obtained by reading the answer of the command Print Grammar constr. It seems to work, as the following command is accepted.
Check << 1 < 2 * 3 = 4 >>.
But you may need to include a little more engineering to have a really good notation.
To answer the actual question in your title:
The new scope gets created when you declare a notation that uses it. That is, you don’t declare a new scope my_scope separately. You just write
Notation "x <<< y" := (f x y) (at level 100, no associativity) : my_scope.
and that declares a new scope my_scope.
The answers for this question only apply to older versions of Coq. I'm not sure when it started but in at least Coq 8.13.2, Coq prefers the user to first use Declare Scope create a new scope. What the OP has in their code is Coq's preferred way to declare scopes now.
See the current manual

Performance difference between functions and pattern matching in Mathematica

So Mathematica is different from other dialects of lisp because it blurs the lines between functions and macros. In Mathematica if a user wanted to write a mathematical function they would likely use pattern matching like f[x_]:= x*x instead of f=Function[{x},x*x] though both would return the same result when called with f[x]. My understanding is that the first approach is something equivalent to a lisp macro and in my experience is favored because of the more concise syntax.
So I have two questions, is there a performance difference between executing functions versus the pattern matching/macro approach? Though part of me wouldn't be surprised if functions were actually transformed into some version of macros to allow features like Listable to be implemented.
The reason I care about this question is because of the recent set of questions (1) (2) about trying to catch Mathematica errors in large programs. If most of the computations were defined in terms of Functions, it seems to me that keeping track of the order of evaluation and where the error originated would be easier than trying to catch the error after the input has been rewritten by the successive application of macros/patterns.
The way I understand Mathematica is that it is one giant search replace engine. All functions, variables, and other assignments are essentially stored as rules and during evaluation Mathematica goes through this global rule base and applies them until the resulting expression stops changing.
It follows that the fewer times you have to go through the list of rules the faster the evaluation. Looking at what happens using Trace (using gdelfino's function g and h)
In[1]:= Trace#(#*#)&#x
Out[1]= {x x,x^2}
In[2]:= Trace#g#x
Out[2]= {g[x],x x,x^2}
In[3]:= Trace#h#x
Out[3]= {{h,Function[{x},x x]},Function[{x},x x][x],x x,x^2}
it becomes clear why anonymous functions are fastest and why using Function introduces additional overhead over a simple SetDelayed. I recommend looking at the introduction of Leonid Shifrin's excellent book, where these concepts are explained in some detail.
I have on occasion constructed a Dispatch table of all the functions I need and manually applied it to my starting expression. This provides a significant speed increase over normal evaluation as none of Mathematica's inbuilt functions need to be matched against my expression.
My understanding is that the first approach is something equivalent to a lisp macro and in my experience is favored because of the more concise syntax.
Not really. Mathematica is a term rewriter, as are Lisp macros.
So I have two questions, is there a performance difference between executing functions versus the pattern matching/macro approach?
Yes. Note that you are never really "executing functions" in Mathematica. You are just applying rewrite rules to change one expression into another.
Consider mapping the Sqrt function over a packed array of floating point numbers. The fastest solution in Mathematica is to apply the Sqrt function directly to the packed array because it happens to implement exactly what we want and is optimized for this special case:
In[1] := N#Range[100000];
In[2] := Sqrt[xs]; // AbsoluteTiming
Out[2] = {0.0060000, Null}
We might define a global rewrite rule that has terms of the form sqrt[x] rewritten to Sqrt[x] such that the square root will be calculated:
In[3] := Clear[sqrt];
sqrt[x_] := Sqrt[x];
Map[sqrt, xs]; // AbsoluteTiming
Out[3] = {0.4800007, Null}
Note that this is ~100× slower than the previous solution.
Alternatively, we might define a global rewrite rule that replaces the symbol sqrt with a lambda function that invokes Sqrt:
In[4] := Clear[sqrt];
sqrt = Function[{x}, Sqrt[x]];
Map[sqrt, xs]; // AbsoluteTiming
Out[4] = {0.0500000, Null}
Note that this is ~10× faster than the previous solution.
Why? Because the slow second solution is looking up the rewrite rule sqrt[x_] :> Sqrt[x] in the inner loop (for each element of the array) whereas the fast third solution looks up the value Function[...] of the symbol sqrt once and then applies that lambda function repeatedly. In contrast, the fastest first solution is a loop calling sqrt written in C. So searching the global rewrite rules is extremely expensive and term rewriting is expensive.
If so, why is Sqrt ever fast? You might expect a 2× slowdown instead of 10× because we've replaced one lookup for Sqrt with two lookups for sqrt and Sqrt in the inner loop but this is not so because Sqrt has the special status of being a built-in function that will be matched in the core of the Mathematica term rewriter itself rather than via the general-purpose global rewrite table.
Other people have described much smaller performance differences between similar functions. I believe the performance differences in those cases are just minor differences in the exact implementation of Mathematica's internals. The biggest issue with Mathematica is the global rewrite table. In particular, this is where Mathematica diverges from traditional term-level interpreters.
You can learn a lot about Mathematica's performance by writing mini Mathematica implementations. In this case, the above solutions might be compiled to (for example) F#. The array may be created like this:
> let xs = [|1.0..100000.0|];;
...
The built-in sqrt function can be converted into a closure and given to the map function like this:
> Array.map sqrt xs;;
Real: 00:00:00.006, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
...
This takes 6ms just like Sqrt[xs] in Mathematica. But that is to be expected because this code has been JIT compiled down to machine code by .NET for fast evaluation.
Looking up rewrite rules in Mathematica's global rewrite table is similar to looking up the closure in a dictionary keyed on its function name. Such a dictionary can be constructed like this in F#:
> open System.Collections.Generic;;
> let fns = Dictionary<string, (obj -> obj)>(dict["sqrt", unbox >> sqrt >> box]);;
This is similar to the DownValues data structure in Mathematica, except that we aren't searching multiple resulting rules for the first to match on the function arguments.
The program then becomes:
> Array.map (fun x -> fns.["sqrt"] (box x)) xs;;
Real: 00:00:00.044, CPU: 00:00:00.031, GC gen0: 0, gen1: 0, gen2: 0
...
Note that we get a similar 10× performance degradation due to the hash table lookup in the inner loop.
An alternative would be to store the DownValues associated with a symbol in the symbol itself in order to avoid the hash table lookup.
We can even write a complete term rewriter in just a few lines of code. Terms may be expressed as values of the following type:
> type expr =
| Float of float
| Symbol of string
| Packed of float []
| Apply of expr * expr [];;
Note that Packed implements Mathematica's packed lists, i.e. unboxed arrays.
The following init function constructs a List with n elements using the function f, returning a Packed if every return value was a Float or a more general Apply(Symbol "List", ...) otherwise:
> let init n f =
let rec packed ys i =
if i=n then Packed ys else
match f i with
| Float y ->
ys.[i] <- y
packed ys (i+1)
| y ->
Apply(Symbol "List", Array.init n (fun j ->
if j<i then Float ys.[i]
elif j=i then y
else f j))
packed (Array.zeroCreate n) 0;;
val init : int -> (int -> expr) -> expr
The following rule function uses pattern matching to identify expressions that it can understand and replaces them with other expressions:
> let rec rule = function
| Apply(Symbol "Sqrt", [|Float x|]) ->
Float(sqrt x)
| Apply(Symbol "Map", [|f; Packed xs|]) ->
init xs.Length (fun i -> rule(Apply(f, [|Float xs.[i]|])))
| f -> f;;
val rule : expr -> expr
Note that the type of this function expr -> expr is characteristic of term rewriting: rewriting replaces expressions with other expressions rather than reducing them to values.
Our program can now be defined and executed by our custom term rewriter:
> rule (Apply(Symbol "Map", [|Symbol "Sqrt"; Packed xs|]));;
Real: 00:00:00.049, CPU: 00:00:00.046, GC gen0: 24, gen1: 0, gen2: 0
We've recovered the performance of Map[Sqrt, xs] in Mathematica!
We can even recover the performance of Sqrt[xs] by adding an appropriate rule:
| Apply(Symbol "Sqrt", [|Packed xs|]) ->
Packed(Array.map sqrt xs)
I wrote an article on term rewriting in F#.
Some measurements
Based on #gdelfino answer and comments by #rcollyer I made this small program:
j = # # + # # &;
g[x_] := x x + x x ;
h = Function[{x}, x x + x x ];
anon = Table[Timing[Do[ # # + # # &[i], {i, k}]][[1]], {k, 10^5, 10^6, 10^5}];
jj = Table[Timing[Do[ j[i], {i, k}]][[1]], {k, 10^5, 10^6, 10^5}];
gg = Table[Timing[Do[ g[i], {i, k}]][[1]], {k, 10^5, 10^6, 10^5}];
hh = Table[Timing[Do[ h[i], {i, k}]][[1]], {k, 10^5, 10^6, 10^5}];
ListLinePlot[ {anon, jj, gg, hh},
PlotStyle -> {Black, Red, Green, Blue},
PlotRange -> All]
The results are, at least for me, very surprising:
Any explanations? Please feel free to edit this answer (comments are a mess for long text)
Edit
Tested with the identity function f[x] = x to isolate the parsing from the actual evaluation. Results (same colors):
Note: results are very similar to this Plot for constant functions (f[x]:=1);
Pattern matching seems faster:
In[1]:= g[x_] := x*x
In[2]:= h = Function[{x}, x*x];
In[3]:= Do[h[RandomInteger[100]], {1000000}] // Timing
Out[3]= {1.53927, Null}
In[4]:= Do[g[RandomInteger[100]], {1000000}] // Timing
Out[4]= {1.15919, Null}
Pattern matching is also more flexible as it allows you to overload a definition:
In[5]:= g[x_] := x * x
In[6]:= g[x_,y_] := x * y
For simple functions you can compile to get the best performance:
In[7]:= k[x_] = Compile[{x}, x*x]
In[8]:= Do[k[RandomInteger[100]], {100000}] // Timing
Out[8]= {0.083517, Null}
You can use function recordSteps in previous answer to see what Mathematica actually does with Functions. It treats it just like any other Head. IE, suppose you have the following
f = Function[{x}, x + 2];
f[2]
It first transforms f[2] into
Function[{x}, x + 2][2]
At the next step, x+2 is transformed into 2+2. Essentially, "Function" evaluation behaves like an application of pattern matching rules, so it shouldn't be surprising that it's not faster.
You can think of everything in Mathematica as an expression, where evaluation is the process of rewriting parts of the expression in a predefined sequence, this applies to Function like to any other head