I want to prove 'reflexivity' property on strings. Please if you can help me how to proceed with the proof. Here is my code:
Fixpoint beq_str (sa sb : String.string) {struct sb}: bool :=
match sa, sb with
| EmptyString, EmptyString => true
| EmptyString, String b sb' => false
| String a sa', EmptyString => false
| String a sa', String b sb'=> match (ascii_dec a b) with
| left _ => beq_str sa' sb'
| right _ => false
end
end.
(* compares two string names [n1] and [n2] of type [id'] - returs bool. *)
Definition beq_names n1 n2 :=
match (n1, n2) with
(name s1, name s2) => beq_str s1 s2
end.
Theorem reflexivty : forall i,
true = beq_str i i.
Proof.
intros. induction i.
auto. simpl. Admitted.
Not sure if homework or independent studies...
Theorem beq_str_refl : forall i,
true = beq_str i i.
Proof.
induction 0; simpl; try (rewrite <- IHi; case (ascii_dec a a));
try reflexivity; intro C; elimtype False; apply C; reflexivity.
Qed.
This should work.
If this is homework and you're lazy, your tutor will hopefully reject this. If you want to understand and prove it yourself, the building blocks you need are in there, just take it apart and throw pieces at your current proof state.
There are two icky things in this proof. First one is getting rid of the (ascii_dec a a). (case-analysis on a won't work.) Do case-analysis on the whole thing (i.e. (ascii_dec a a)) to get two subgoals, one with the added hypothesis a = a, the other with a <> a.
The second problem may be working with contradictions, unless you've done that before.
a <> a is equivalent to a = a -> False. a = a is true by definition, which allows constructing a value of type False (a contradiction -- False has no constructors). This allows you to just throw away your current goal (true = false is impossible to prove anyway), and just construct that impossible False value.
Do elimtype False to tell Coq that you want to proceed by case-analysis on False. As False has no constructors, this leaves you with a single goal of constructing a value of False. Normally that would be impossible, but you've got a contradiction among your hypotheses. apply this contradiction (named C in my proof script above) and all you've left to do is show a = a, which follows from reflexivity.
Here is a more readable version that you can step through:
Theorem beq_str_refl : forall i, true = beq_str i i.
intro i. induction i as [ | a i IHi ].
(* base case: Empty String *) reflexivity.
(* inductive case: *) simpl. rewrite <- IHi.
(* do case analysis on ascii_dec (or {a=a}+{a<>a}) *)
destruct (ascii_dec a a) as [ Heq | C ].
(* {a = a} *) reflexivity.
(* {a <> a} *) unfold not in C. elimtype False. apply C. reflexivity.
Another way to handle contradictions:
(* just a quick nonsensical goal *)
Theorem foo: forall i, i <> i -> 2 + 2 = 5.
intros i C.
(* explicitly construct a 'False' value *)
assert False as H.
apply C. reflexivity.
(* 'inversion' generates one goal per possible constructor *)
(* as False has no constructors, this gives 0 subgoals, finishing the proof *)
inversion H.
Qed.
Related
I have the following Coq implementation of integer division with remainder.
When I extract it to Haskell everything works fine. I compared the Coq version to the generated Haskell version and tried to understand what's going on. It seems that rewrite is simply removed here,
and what actually steers the extraction here are induction, destruct, exists and specialize. Is there any scenario where rewrite is used during extraction? Also, some variables names are kept (like q0 and m0'') but others change (r0 to h) is there any reason to change names? Here is the Coq code followed by the extracted code:
(***********)
(* IMPORTS *)
(***********)
Require Import Coq.Arith.PeanoNat.
Require Import Coq.Structures.OrdersFacts.
Lemma Sn_eq_Sm: forall n m,
(n = m) -> ((S n) = (S m)).
Proof.
intros n m H.
rewrite H.
reflexivity.
Qed.
Lemma Sn_lt_Sm: forall n m,
(n < m) -> ((S n) < (S m)).
Proof.
intros n0 m0 H.
unfold lt in H.
apply Nat.lt_succ_r.
apply H.
Qed.
Lemma add_nSm : forall (n m : nat),
(n + (S m)) = S (n + m).
Proof.
intros n m.
induction n.
- reflexivity.
- simpl.
apply Sn_eq_Sm.
apply IHn.
Qed.
Lemma n_lt_m: forall n m,
((n <? m) = false) -> (m <= n).
Proof.
Admitted.
Lemma n_le_m_le_n: forall n m,
(n <= m) -> ((m <= n) -> (m = n)).
Proof.
Admitted.
Lemma Sn_ge_0: forall n,
0 <= (S n).
Proof.
induction n as [|n' IHn'].
- apply le_S. apply le_n.
- apply le_S. apply IHn'.
Qed.
Lemma n_ge_0: forall n,
0 <= n.
Proof.
induction n as [|n' IHn'].
- apply le_n.
- apply le_S. apply IHn'.
Qed.
Lemma Sn_gt_0: forall n,
0 < (S n).
Proof.
induction n as [|n' IHn'].
- apply le_n.
- apply le_S. apply IHn'.
Qed.
Lemma n_le_m_implies_Sn_le_Sm: forall n m,
(n <= m) -> ((S n) <= (S m)).
Proof.
induction n as [|n' IHn'].
- induction m as [|m' IHm'].
+ intros H1. apply le_n.
+ intros H1. apply le_S.
apply IHm'. apply n_ge_0.
- induction m as [|m' IHm'].
+ intros H1. inversion H1.
+ intros H1. inversion H1.
apply le_n. apply IHm' in H0 as H2.
apply le_S in H2. apply H2.
Qed.
(****************************************)
(* division with quotient and remainder *)
(****************************************)
Definition div_q_r: forall n m : nat,
{ q:nat & { r:nat | (n = q * (S m) + r) /\ (r < (S m))}}.
Proof.
induction n as [|n' IHn'].
- exists 0. exists 0. split. reflexivity. apply Sn_gt_0.
- intros m0.
destruct m0 as [|m0''] eqn:E1.
+ exists (S n'). exists 0. split.
* rewrite Nat.add_0_r with (n:=(S n') * 1).
rewrite Nat.mul_1_r with (n:=(S n')). reflexivity.
* specialize Sn_gt_0 with (n:=0). intros H. apply H.
+ specialize IHn' with (m:=(S m0'')).
destruct IHn' as [q0 H]. destruct H as [r0 H].
destruct (r0 <? (S m0'')) eqn:E2.
* exists q0. exists (S r0). split.
-- rewrite add_nSm with (n:=q0 * S (S m0'')).
apply Sn_eq_Sm. apply proj1 in H as H1. apply H1.
-- apply Nat.ltb_lt in E2. apply Sn_lt_Sm. apply E2.
* exists (S q0). exists 0. split.
-- apply proj2 in H as H2. rewrite Nat.lt_succ_r in H2.
apply n_lt_m in E2. apply n_le_m_le_n in H2.
apply proj1 in H as H1. rewrite H2 in H1. rewrite H1.
rewrite <- add_nSm with (n:=q0 * S (S m0'')) (m:=S m0'').
rewrite Nat.add_0_r.
rewrite Nat.mul_succ_l with (n:=q0) (m:=S (S m0'')).
reflexivity. apply E2.
-- unfold "<". apply n_le_m_implies_Sn_le_Sm. apply Sn_ge_0.
Qed.
(********************************)
(* Extraction Language: Haskell *)
(********************************)
Extraction Language Haskell.
(***************************)
(* Use Haskell basic types *)
(***************************)
Require Import ExtrHaskellBasic.
(****************************************)
(* Use Haskell support for Nat handling *)
(****************************************)
Require Import ExtrHaskellNatNum.
Extract Inductive Datatypes.nat => "Prelude.Integer" ["0" "Prelude.succ"]
"(\fO fS n -> if n Prelude.== 0 then fO () else fS (n Prelude.- 1))".
(***************************)
(* Extract to Haskell file *)
(***************************)
Extraction "/home/oren/GIT/some_file_Haskell.hs" div_q_r.
And here is the extracted Haskell code:
div_q_r :: Prelude.Integer -> Prelude.Integer -> SigT Prelude.Integer
Prelude.Integer
div_q_r n =
nat_rec (\_ -> ExistT 0 0) (\n' iHn' m0 ->
(\fO fS n -> if n Prelude.== 0 then fO () else fS (n Prelude.- 1))
(\_ -> ExistT (Prelude.succ n')
0)
(\m0'' ->
let {iHn'0 = iHn' (Prelude.succ m0'')} in
case iHn'0 of {
ExistT q0 h ->
let {b = ltb h (Prelude.succ m0'')} in
case b of {
Prelude.True -> ExistT q0 (Prelude.succ h);
Prelude.False -> ExistT (Prelude.succ q0) 0}})
m0) n
When you use rewrite, the goal is actually a type (a formula) and the type of this type is often Prop. When this happens, as in your example, the effect of the rewrite tactic is discarded because the part of the term where it took place was discarded.
the extraction tool does not look at tactics: it remove expressions whose type has type Prop from the term that will be executed. The whole system is designed in such a way that these expressions should not have an effect on computation.
In a sense, it is a distinction between compile-time verification and run-time verification. All the proofs that you do in Coq are compile-time verifications, at run-time they don't need to be redone, so they are removed from the code. The Prop sort is used to mark computations that happen only at compile-time and won't have an effect on the execution at run-time.
You can somehow predict the content of the Haskell extracted program by looking at the result of Print div_q_r.
The result contains instances of existT and instance of exist. The type of existT is :
forall (A : Type) (P : A -> Type) (x : A), P x -> {x : A & P x}
The notation {x : A & P x} is for #sigT A P. In turn the type of sigT is
forall A : Type, (A -> Type) -> Type
The type of existT P xx pp is #sigT A P and the type of the latter is Type. In consequence, the extraction tool decides that this term contains data that is important at run time. Moreover, the second component of sigT A P, has type P xx which itself has type Type, so this also is important at run time: it won't be discarded.
Now let's turn our attention to expression of the form exist _ _. Such an expression has type #sig A P and sig has type :
forall A: Type, (A -> Prop) -> Type
So an expression exist Q y qq contains y whose type has type Type and qq whose type is Q y and has type Prop. Information on how to compute y will be kept at run time, but information on how to compute qq is discarded.
If you want to know where rewrite had an effect in the proof, you only need to look for instances of eq_ind and eq_ind_r in the result of Print div_q_r. You will see that these instances are subterms of the third argument of exist statements. This is the reason why they don't appear in the final result. It is not because the extraction has special treatement of rewrites, it is because it has a special behavior on the type of types Prop (we also call it the sort Prop).
It is possible to construct functions where rewrite leaves a trace in the extraction result, but I am not sure that these functions behave correctly in Haskell. This when, the formula where the rewrite occur is not in sort Prop.
Definition nat_type n :=
match n with O => nat | S p => bool end.
Definition strange n : nat_type (n * 0).
rewrite Nat.mul_0_r.
exact n.
Defined.
I'm still trying to grasp an intuition of pullbacks (from category theory), limits, and universal properties, and I'm not quite catching their usefulness, so maybe you could help shed some insight on that as well as verifying my trivial example?
The following is intentionally verbose, the pullback should be (p, p1, p2), and (q, q1, q2) is one example of a non-universal object to "test" the pullback against to see if things commute properly.
-- MY DIAGRAM, A -> B <- C
type A = Int
type C = Bool
type B = (A, C)
f :: A -> B
f x = (x, True)
g :: C -> B
g x = (1, x)
-- PULLBACK, (p, p1, p2)
type PL = Int
type PR = Bool
type P = (PL, PR)
p = (1, True) :: P
p1 = fst
p2 = snd
-- (g . p2) p == (f . p1) p
-- TEST CASE
type QL = Int
type QR = Bool
type Q = (QL, QR)
q = (152, False) :: Q
q1 :: Q -> A
q1 = ((+) 1) . fst
q2 :: Q -> C
q2 = ((||) True) . snd
u :: Q -> P
u (_, _) = (1, True)
-- (p2 . u == q2) && (p1 . u = q1)
I was just trying to come up with an example that fit the definition, but it doesn't seem particularly useful. When would I "look for" a pull back, or use one?
I'm not sure Haskell functions are the best context
in which to talk about pull-backs.
The pull-back of A -> B and C -> B can be identified with a subset of A x C,
and subset relationships are not directly expressible in Haskell's
type system. In your specific example the pull-back would be
the single element (1, True) because x = 1 and b = True are
the only values for which f(x) = g(b).
Some good "practical" examples of pull-backs may be found
starting on page 41 of Category Theory for Scientists
by David I. Spivak.
Relational joins are the archetypal example of pull-backs
which occur in computer science. The query:
SELECT ...
FROM A, B
WHERE A.x = B.y
selects pairs of rows (a,b) where a is a row from table A
and b is a row from table B and where some function of a
equals some other function of b. In this case the functions
being pulled back are f(a) = a.x and g(b) = b.y.
Another interesting example of a pullback is type unification in type inference. You get type constraints from several places where a variable is used, and you want to find the tightest unifying constraint. I mention this example in my blog.
Apologies for my poor wording of the question. I've tried searching for an answer but not knowing what to search is making it very difficult to find one.
Here is a simple function which calculates the area of a triangle.
triangleArea :: Float -> Float -> Float -> Float
triangleArea a b c
| (a + b) <= c = error "Not a triangle!"
| (a + c) <= b = error "Not a triangle!"
| (b + c) <= a = error "Not a triangle!"
| otherwise = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Three lines of the function have been taken up for the purposes of error checking. I was wondering if these three lines could be condensed into one generic line.
I was wondering if something similar to the following would be possible
(arg1 + arg2) == arg3
where Haskell knows to check each possible combination of the three arguments.
I think #behzad.nouri's comment is the best. Sometimes doing a little math is the best way to program. Here's a somewhat overdone expansion on #melpomene's solution, which I thought would be fun to share. Let's write a function similar to permutations but that computes combinations:
import Control.Arrow (first, second)
-- choose n xs returns a list of tuples, the first component of each having
-- n elements and the second component having the rest, in all combinations
-- (ignoring order within the lists). N.B. this would be faster if implemented
-- using a DList.
choose :: Int -> [a] -> [([a],[a])]
choose 0 xs = [([], xs)]
choose _ [] = []
choose n (x:xs) =
map (first (x:)) (choose (n-1) xs) ++
map (second (x:)) (choose n xs)
So..
ghci> choose 2 [1,2,3]
[([1,2],[3]),([1,3],[2]),([2,3],[1])]
Now you can write
triangleArea a b c
| or [ x + y <= z | ([x,y], [z]) <- choose 2 [a,b,c] ] = error ...
This doesn't address the question of how to shorten your error checking code, but you may be able to limit how often you repeat it by defining some new types with invariants. This function needs error checking because you can't trust the user to supply Float triples that make a reasonable triangle, and if you continue to define functions this way then every triangle-related function you write would need similar error checks.
However, if you define a Triangle type, you can check your invariants only once, when a triangle is created, and then all other functions will be guaranteed to receive valid triangles:
module Triangle (Triangle(), mkTriangle, area) where
data Triangle a = Triangle a a a deriving Show
mkTriangle :: (Num a, Ord a) => a -> a -> a -> Either String (Triangle a)
mkTriangle a b c
| a + b <= c = wrong
| a + c <= b = wrong
| b + c <= a = wrong
| otherwise = Right $ Triangle a b c
where wrong = Left "Not a triangle!"
area :: Floating a => Triangle a -> a
area (Triangle a b c) = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Here we export the Triangle type, but not its constructor, so that the client must use mkTriangle instead, which can do the required error checking. Then area, and any other triangle functions you write, can omit the checks that they are receiving a valid triangle. This general pattern is called "smart constructors".
Here are two ideas.
Using existing tools, you can generate all the permutations of the arguments and check that they all satisfy a condition. Thus:
import Data.List
triangleArea a b c
| any (\[x, y, z] -> x + y <= z) (permutations [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}
This doesn't require writing very much additional code; however, it will search some permutations you don't care about.
Use the usual trick for choosing an element from a list and the left-overs. The zippers function is one I use frequently:
zippers :: [a] -> [([a], a, [a])]
zippers = go [] where
go b [] = []
go b (v:e) = (b, v, e) : go (v:b) e
We can use it to build a function which chooses only appropriate triples of elements:
triples :: [a] -> [(a, a, a)]
triples xs = do
(b1, v1, e1) <- zippers xs
(b2, v2, e2) <- zippers e1
v3 <- b1 ++ b2 ++ e2
return (v1, v2, v3)
Now we can write our guard like in part (1), but it will only consider unique pairings for the addition.
triangleArea a b c
| any (\(x, y, z) -> x + y <= z) (triples [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}
Let's say I have :
f :: Double -> Double
f x = 3*x^2 + 5*x + 9
I would like to compute the derivative of this function and write
derivate f
so that
derivate f == \x -> 6*x + 5
but how to define derivate?
derivate :: (a -> a) -> (a -> a)
derivate f = f' -- how to compute f'?
I'm aware there is no native way to do this, but is there a library that can?
Do we have to rely on "meta"-datatypes to achieve this?
data Computation = Add Exp Expr | Mult Expr Expr | Power Expr Expr -- etc
Then, is it not a pain to make a corresponding constructor for each function ? However, datatypes should not represent functions (except for parsers).
Is Pure a good alternative because of its term-rewriting feature? Doesn't it have its drawbacks as well?
Are lists affordable?
f :: [Double]
f = [3, 5, 9]
derivate :: (a -> [a])
derivate f = (*) <$> f <*> (getNs f)
compute f x = sum $
((*) . (^) x) <$> (getNs f) <*> f
getNs f = (reverse (iterate (length f) [0..]))
Haskell now looks like it depends on LISP with a less appropriate syntax. Function and arguments waiting to be used together are quite stored in datatypes.
Plus, it's not very natural.
They don't seem to be "flexible" enough to be able my derivate function other than polynomials, such as homographic functions.
Right now, for example, I would like to use derivatives for a game. The character runs on a floor made using a function, and I would like him to slide if the floor is steep enough.
I also need to solve equations for various purposes. Some examples:
I'm a spaceship and I want to take a nap. During my sleep, if I don't place myself carefully, I might crash on a planet because of gravity. I don't have enough gas to go far away from celestial objects and I don't have a map either.
So I must place myself between the objects in this area so that the sum of their gravitationnal influence on me is canceled.
x and y are my coordinates. gravity is a function that takes two objects and return the vector of the gravitationnal force between them.
If there are two objects, say the Earth and the Moon, besides me, all I need to do to find where to go is to solve:
gravity earth spaceship + gravity moon spaceship == (0, 0)
It's much simpler and faster, etc., than to create a new function from scratch equigravityPoint :: Object -> Object -> Object -> Point.
If there are 3 objects besides me, it's still simple.
gravity earth spaceship + gravity moon spaceship + gravity sun spaceship == (0, 0)
Same for 4, and n. Handling a list of objects is much simpler this way than with equigravityPoint.
Other example.
I want to code an ennemy bot that shoots me.
If he just shoots targeting my current position, he will get me if I run towards me, but he'll miss me if I jump and fall on him.
A smarter bot thinks like that: "Well, he jumped from a wall. If I shoot targeting where he is now the bullet won't get him, because he will have moved until then. So I'm gonna anticipate where he'll be in a few seconds and shoot there so that the bullet and him reach this point at the same time".
Basically, I need the ability to compute trajectories. For example, for this case, I need the solution to trajectoryBullet == trajectoryCharacter, which gives a point where the line and the parabola meet.
A similar and simpler example not involving speed.
I'm a fireman bot and there's a building in fire. Another team of firemen is fighting the fire with their water guns. I am and there are people jumping from . While my friends are shooting water, I hold the trampoline.
I need to go where the people will fall before they do. So I need trajectories and equation-solving.
One way of doing this is to do automatic differentiation instead of symbolic differentiation; this is an approach where you simultaneously compute both f(x) and f′(x) in one computation. There's a really cool way of doing this using dual numbers that I learned about from Dan "sigfpe" Piponi's excellent blog post on automatic differentiation. You should probably just go read that, but here's the basic idea. Instead of working with the real numbers (or Double, our favorite (?) facsimile of them), you define a new set, which I'm going to call D, by adjoining a new element ε to ℝ such that ε2 = 0. This is much like the way we define the complex numbers ℂ by adjoining a new element i to ℝ such that i2 = -1. (If you like algebra, this is the same as saying D = ℝ[x]/⟨x2⟩.) Thus, every element of D is of the form a + bε, where a and b are real. Arithmetic over the dual numbers works like you expect:
(a + bε) ± (c + dε) = (a + c) ± (b + d)ε; and
(a + bε)(c + dε) = ac + bcε + adε + bdε2 = ac + (bc + ad)ε.
(Since ε2 = 0, division is more complicated, although the multiply-by-the-conjugate trick you use with the complex numbers still works; see Wikipedia's explanation for more.)
Now, why are these useful? Intuitively, the ε acts like an infinitesimal, allowing you to compute derivatives with it. Indeed, if we rewrite the rule for multiplication using different names, it becomes
(f + f′ε)(g + g′ε) = fg + (f′g + fg′)ε
And the coefficient of ε there looks a lot like the product rule for differentiating products of functions!
So, then, let's work out what happens for one large class of functions. Since we've ignored division above, suppose we have some function f : ℝ → ℝ defined by a power series (possibly finite, so any polynomial is OK, as are things like sin(x), cos(x), and ex). Then we can define a new function fD : D → D in the obvious way: instead of adding real numbers, we add dual numbers, etc., etc. Then I claim that fD(x + ε) = f(x) + f′(x)ε. First, we can show by induction that for any natural number i, it's the case that (x + ε)i = xi + ixi-1ε; this will establish our derivative result for the case where f(x) = xk. In the base case, this equality clearly holds when i = 0. Then supposing it holds for i, we have
(x + ε)i+1 = (x + ε)(x + ε)i by factoring out one copy of (x + ε)
= (x + ε)(xi + ixi-1ε) by the inductive hypothesis
= xi+1 + (xi + x(ixi-1))ε by the definition of dual-number multiplication
= xi+1 + (i+1)xiε by simple algebra.
And indeed, this is what we wanted. Now, considering our power series f, we know that
f(x) = a0 + a1x + a2x2 + … + aixi + …
Then we have
fD(x + ε) = a0 + a1(x + ε) + a2(x + ε)2 + … + ai(x + ε)i + …
= a0 + (a1x + a1ε) + (a2x2 + 2a2xε) + … + (aixi + iaixi-1ε) + … by the above lemma
= (a0 + a1x + a2x2 + … + aixi + …) + (a1ε + 2a2xε + … + iaixi-1ε + …) by commutativity
= (a0 + a1x + a2x2 + … + aixi + …) + (a1 + 2a2x + … + iaixi-1 + …)ε by factoring out the ε
= f(x) + f′(x)ε by definition.
Great! So dual numbers (at least for this case, but the result is generally true) can do differentiation for us. All we have to do is apply our original function to, not the real number x, but the dual number x + ε, and then extract the resulting coefficient of ε. And I bet you can see how one could implement this in Haskell:
data Dual a = !a :+? !a deriving (Eq, Read, Show)
infix 6 :+?
instance Num a => Num (Dual a) where
(a :+? b) + (c :+? d) = (a+c) :+? (b+d)
(a :+? b) - (c :+? d) = (a-c) :+? (b-d)
(a :+? b) * (c :+? d) = (a*c) :+? (b*c + a*d)
negate (a :+? b) = (-a) :+? (-b)
fromInteger n = fromInteger n :+? 0
-- abs and signum might actually exist, but I'm not sure what they are.
abs _ = error "No abs for dual numbers."
signum _ = error "No signum for dual numbers."
-- Instances for Fractional, Floating, etc., are all possible too.
differentiate :: Num a => (Dual a -> Dual a) -> (a -> a)
differentiate f x = case f (x :+? 1) of _ :+? f'x -> f'x
-- Your original f, but with a more general type signature. This polymorphism is
-- essential! Otherwise, we can't pass f to differentiate.
f :: Num a => a -> a
f x = 3*x^2 + 5*x + 9
f' :: Num a => a -> a
f' = differentiate f
And then, lo and behold:
*Main> f 42
5511
*Main> f' 42
257
Which, as Wolfram Alpha can confirm, is exactly the right answer.
More information about this stuff is definitely available. I'm not any kind of expert on this; I just think the idea is really cool, so I'm taking this chance to parrot what I've read and work out a simple proof or two. Dan Piponi has written more about dual numbers/automatic differentiation, including a post where, among other things, he shows a more general construction which allows for partial derivatives. Conal Elliott has a post where he shows how to compute derivative towers (f(x), f′(x), f″(x), …) in an analogous way. The Wikipedia article on automatic differentiation linked above goes into some more detail, including some other approaches. (This is apparently a form of "forward mode automatic differentiation", but "reverse mode" also exists, and can apparently be faster.)
Finally, there's a Haskell wiki page on automatic differentiation, which links to some articles—and, importantly, some Hackage packages! I've never used these, but it appears that the ad package, by Edward Kmett is the most complete, handling multiple different ways of doing automatic differentiation—and it turns out that he uploaded that package after writing a package to properly answer another Stack Overflow question.
I do want to add one other thing. You say "However, datatypes should not represent functions (except for parsers)." I'd have to disagree there—reifying your functions into data types is great for all sorts of things in this vein. (And what makes parsers special, anyway?) Any time you have a function you want to introspect, reifying it as a data type can be a great option. For instance, here's an encoding of symbolic differentiation, much like the encoding of automatic differentiation above:
data Symbolic a = Const a
| Var String
| Symbolic a :+: Symbolic a
| Symbolic a :-: Symbolic a
| Symbolic a :*: Symbolic a
deriving (Eq, Read, Show)
infixl 6 :+:
infixl 6 :-:
infixl 7 :*:
eval :: Num a => (String -> a) -> Symbolic a -> a
eval env = go
where go (Const a) = a
go (Var x) = env x
go (e :+: f) = go e + go f
go (e :-: f) = go e - go f
go (e :*: f) = go e * go f
instance Num a => Num (Symbolic a) where
(+) = (:+:)
(-) = (:-:)
(*) = (:*:)
negate = (0 -)
fromInteger = Const . fromInteger
-- Ignoring abs and signum again
abs = error "No abs for symbolic numbers."
signum = error "No signum for symbolic numbers."
-- Instances for Fractional, Floating, etc., are all possible too.
differentiate :: Num a => Symbolic a -> String -> Symbolic a
differentiate f x = go f
where go (Const a) = 0
go (Var y) | x == y = 1
| otherwise = 0
go (e :+: f) = go e + go f
go (e :-: f) = go e - go f
go (e :*: f) = go e * f + e * go f
f :: Num a => a -> a
f x = 3*x^2 + 5*x + 9
f' :: Num a => a -> a
f' x = eval (const x) $ differentiate (f $ Var "x") "x"
And once again:
*Main> f 42
5511
*Main> f' 42
257
The beauty of both of these solutions (or one piece of it, anyway) is that as long as your original f is polymorphic (of type Num a => a -> a or similar), you never have to modify f! The only place you need to put derivative-related code is in the definition of your new data type and in your differentiation function; you get the derivatives of your existing functions for free.
Numerical derivative can be done easily:
derive f x = (f (x + dx) - f (x - dx)) / (2 * dx) where dx = 0.00001
However, for symbolic derivatives, you need to create an AST, then implement the derivation rules through matching and rewriting the AST.
I don't understand your problem with using a custom data type
data Expr = Plus Expr Expr
| Times Expr Expr
| Negate Expr
| Exp Expr Expr
| Abs Expr
| Signum Expr
| FromInteger Integer
| Var
instance Num Expr where
fromInteger = FromInteger
(+) = Plus
(*) = Times
negate = Negate
abs = Abs
signum = Signum
toNumF :: Num a => Expr -> a -> a
toNumF e x = go e where
go Var = x
go (FromInteger i) = fromInteger i
go (Plus a b) = (go a) + (go b)
...
you can then use this just like you would Int or Double and all will just work! You can define a function
deriveExpr :: Expr -> Expr
which would then let you define the following (RankN) function
derivate :: Num b => (forall a. Num a => a -> a) -> b -> b
derivate f = toNumF $ deriveExpr (f Var)
you can extend this to work with other parts of the numerical hierarchy.
So I'm writing a program which returns a procedure for some given arithmetic problem, so I wanted to instance a couple of functions to Show so that I can print the same expression I evaluate when I test. The trouble is that the given code matches (-) to the first line when it should fall to the second.
{-# OPTIONS_GHC -XFlexibleInstances #-}
instance Show (t -> t-> t) where
show (+) = "plus"
show (-) = "minus"
main = print [(+),(-)]
returns
[plus,plus]
Am I just committing a mortal sin printing functions in the first place or is there some way I can get it to match properly?
edit:I realise I am getting the following warning:
Warning: Pattern match(es) are overlapped
In the definition of `show': show - = ...
I still don't know why it overlaps, or how to stop it.
As sepp2k and MtnViewMark said, you can't pattern match on the value of identifiers, only on constructors and, in some cases, implicit equality checks. So, your instance is binding any argument to the identifier, in the process shadowing the external definition of (+). Unfortunately, this means that what you're trying to do won't and can't ever work.
A typical solution to what you want to accomplish is to define an "arithmetic expression" algebraic data type, with an appropriate show instance. Note that you can make your expression type itself an instance of Num, with numeric literals wrapped in a "Literal" constructor, and operations like (+) returning their arguments combined with a constructor for the operation. Here's a quick, incomplete example:
data Expression a = Literal a
| Sum (Expression a) (Expression a)
| Product (Expression a) (Expression a)
deriving (Eq, Ord, Show)
instance (Num a) => Num (Expression a) where
x + y = Sum x y
x * y = Product x y
fromInteger x = Literal (fromInteger x)
evaluate (Literal x) = x
evaluate (Sum x y) = evaluate x + evaluate y
evaluate (Product x y) = evaluate x * evaluate y
integer :: Integer
integer = (1 + 2) * 3 + 4
expr :: Expression Integer
expr = (1 + 2) * 3 + 4
Trying it out in GHCi:
> integer
13
> evaluate expr
13
> expr
Sum (Product (Sum (Literal 1) (Literal 2)) (Literal 3)) (Literal 4)
Here's a way to think about this. Consider:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
Can you see why this won't work? answer in the pattern match is a variable, distinct from answer at the outer scope. So instead, you'd have to write this like:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
In fact, this is just what is going on when you write constants in a pattern. That is:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
gets converted by the compiler to something equivalent to:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
Since you want to match against the function bound to (+) rather than just bind anything to the symbol (+), you'd need to write your code as:
instance Show (t -> t-> t) where
show f | f == (+) = "plus"
show f | f == (-) = "minus"
But, this would require that functions were comparable for equality. And that is an undecidable problem in general.
You might counter that you are just asking the run-time system to compare function pointers, but at the language level, the Haskell programmer doesn't have access to pointers. In other words, you can't manipulate references to values in Haskell(*), only values themselves. This is the purity of Haskell, and gains referential transparency.
(*) MVars and other such objects in the IO monad are another matter, but their existence doesn't invalidate the point.
It overlaps because it treats (+) simply as a variable, meaning on the RHS the identifier + will be bound to the function you called show on.
There is no way to pattern match on functions the way you want.
Solved it myself with a mega hack.
instance (Num t) => Show (t -> t-> t) where
show op =
case (op 6 2) of
8 -> "plus"
4 -> "minus"
12 -> "times"
3 -> "divided"