Reordering parentheses using associative property in Racket - racket

I am having trouble implementing a function that given something like this:
'((+(d + e) + f) + (a + (a + c))
Returns this:
'(d + (e + (f + (a + (a + c)))))
Now the catch is that I have to use associativity to get the answer so I only want to use this property:
'((a + b) + c) = '(a + (b + c))
To get the correct output. I know how to implement the function for this case:
'((a + b) + c) -> '(a + (b + c))
However I cannot seem to figure out how to implement it for the first case above (or any other case larger than three items). I am not looking for answers only some guidance. If you would like to see code snippets let me know and I can post some. Also, I created a function that stripped the '+ from the list to make it easier to process.
I think this defines the grammar:
var ::= a | b | c | d | e | f | g
fpip ::= var | (fpip + fpip)
Where a valid fpip can be:
fpip = '((a + b) + c)
or
fpip = '((a + b) + (c + d))
and at it's most atomic level:
fpip = '(a + b)
edit: yes the initial '+ should be erased. Regardless of how many plus signs there are in the initial input there should only be (amount-of-vars - 1) '+ in the output. For example:
'(+ + + + (a + b) + + c) -> '(a + (b + c)

I think these are the cases to consider. Let's call the the recursive rewriter REWRITE.
var -> var
(var + var) -> (var + var)
(var + (fip1 + fpip2)) -> (var + (REWRITE (fip1 + fpip2))
((fip1 + fpip2) + var) -> (REWRITE (fip1 + (fip2 + var))
((fip1 + fpip2) + (fip3 + fpip4)) -> (REWRITE (fip1 + (fip2 + (fip3 + fip4))))

Related

Teach Coq that associative law of natural numbers holds

I have a simple question.
I want to teach Coq that there is vec_assoc.
Require Import Coq.Vectors.Vector.
Lemma vec_assoc (A:Type)(a b c:nat): t A ((a+b)+c) = t A (a+(b+c)).
Proof.
f_equal. symmetry. apply Nat.add_assoc. Qed.
Variable a b c:nat.
Variable A B:Type.
Variable I : (t A ((a+b)+c) -> B).
Variable p:t A (a+(b+c)).
Coq returns an error
`The term "p" has type "vector A (a + (b + c))"
while it is expected to have type "vector A (a + b + c)".`
When I execute Compute I p.
How do I teach Coq that associative law of natural number holds?
Well, associativity does not hold with respect to convertibility of Coq terms, it only holds propositionally. What that means is that in a context where a, b c : nat you can build a term pf : a + (b + c) = (a + b) + c but it is not the case that the specific proof eq_refl can be given the type a + (b + c) = (a + b) + c.
In your case, since you already have a proof that t A (a + (b + c)) = t A ((a + b) + c) you could do the application by first transporting p along this equality using eq_rect or the rew vec_assoc A a b c in p syntax from the module EqNotations of the standard library (just add Import EqNotations.).
In any case nothing will compute since both I and p are variables (and the proof vec_assoc is opaque thanks to Qed).

Can't use PeanoNat.Nat.add_assoc in proof

Require Import PeanoNat.
Check PeanoNat.Nat.add_assoc.
Output:
Nat.add_assoc
: forall n m p : nat, n + (m + p) = n + m + p
So, the theorem is defined.
But when I create a theorem and try to use it, it gives an error:
Theorem a : forall a b c d e f,
a + b + c + d + e = f.
Proof.
intros.
PeanoNat.Nat.add_assoc a (b + c) d.
Error: The reference PeanoNat.Nat.add_assoc was not found in the
current environment.
Why can't it find the theorem?
What comes after Proof. is not the proof itself. It's a series of instructions, called tactics, that tells Coq how to build a proof. add_assoc is a proof, not a tactic that builds a proof. You would use the tactic rewrite (Nat.add_assoc a (b + c) d) to rewrite (any part of) the goal according to the equality
Nat.add_assoc a (b + c) d
: a + (b + c + d) = a + (b + c) + d
However, your goal a + b + c + d + e = f does not contain either of those terms—+ is left associative and your goal is actually (((a + b) + c) + d) + e = f—so this tactic will fail. In fact, your goal is unprovable, but I assume that it's just for example. You may also be interested in the tactic apply [prf]. It takes the conclusion (thing on the right side of all the ->s and foralls) of prf, matches it against the goal, and gives you subgoals for all of its hypotheses. See also: the Coq tactic reference.

Simplifying the boolean expression: A ^ B * C

I've been trying to simplify the
Boolean expression: A ^ B * C for some time now. I'm able to first simplify it down to: A * ~B + ~A * B * C but after that I can't seem to simplify it further. Using an online simplifies, it says that it simplifies to (A + B) * (A + C) * (~A + ~B) but why is that? And what laws are used to simplify it to that?
It depends on the precedence of the operators. Normally AND comes before XOR and it is A XOR (B AND C). Some programming languages evaluate expressions strictly from left to right when not using parentheses, resulting in (A XOR B) AND C, assuming you are using ^ for XOR and * for AND.
Your simplification seems to be going for the latter variant but normally in boolean algebra you'd evaluate the AND first:
A * ~(B*C) + ~A * B * C
= A * (~B + ~C) + ~A * B * C
= A * ~B + A * ~C + ~A * B * C
It's been a while that I've worked with boolean expressions like this, so I don't know if there can be made any further simplifications (or even if mine are correct).
And are you sure, you wrote down the result of the online simplifier correctly? Because the term (A + B) * (~A * ~B) evaluates to A * ~A * ~B + B * ~A * ~B = 0 + 0 and therefore the whole term evaluates to false. This is all assuming that there is the following precedence of operators: NOT > AND > OR. If the last term in their solution is (~A + ~B) it would make more sense and evaluate to your term A * ~B + ~A * B * C, it just is its conjunctive normal form.

Rotate the first argument to a function to become nth

Given a function with at least n arguments, I want to rotate the first argument so that it becomes the nth argument. For example (in untyped lambda calculus):
r(λa. a) = λa. a
r(λa. λb. a b) = λb. λa. a b
r(λa. λb. λc. a b c) = λb. λc. λa. a b c
r(λa. λb. λc. λd. a b c d) = λb. λc. λd. λa. a b c d
And so on.
Can you write r in a generic way? What if you know that n >= 2?
Here's the problem stated in Scala:
trait E
case class Lam(i: E => E) extends E
case class Lit(i: Int) extends E
case class Ap(e: E, e: E) extends E
The rotation should take Lam(a => Lam(b => Lam(c => Ap(Ap(a, b), c)))) and return Lam(b => Lam(c => Lam(a => Ap(Ap(a, b), c)))), for example.
The trick is to tag the "final" value of the functions involved, since to normal haskell, both a -> b and a -> (b->c) are just functions of a single variable.
If we do that, though, we can do this.
{-# LANGUAGE TypeFamilies,FlexibleInstances,FlexibleContexts #-}
module Rotate where
data Result a = Result a
class Rotate f where
type After f
rotate :: f -> After f
instance Rotate (a -> Result b) where
type After (a -> Result b) = a -> Result b
rotate = id
instance Rotate (a -> c) => Rotate (a -> b -> c) where
type After (a -> b -> c) = b -> After (a -> c)
rotate = (rotate .) . flip
Then, to see it in action:
f0 :: Result a
f0 = Result undefined
f1 :: Int -> Result a
f1 = const f0
f2 :: Char -> Int -> Result a
f2 = const f1
f3 :: Float -> Char -> Int -> Result a
f3 = const f2
f1' :: Int -> Result a
f1' = rotate f1
f2' :: Int -> Char -> Result a
f2' = rotate f2
f3' :: Char -> Int -> Float -> Result a
f3' = rotate f3
It's probably impossible without violating the ‘legitimacy’ of HOAS, in the sense that the E => E must be used not just for binding in the object language, but for computation in the meta language. That said, here's a solution in Haskell. It abuses a Literal node to drop in a unique ID for later substitution. Enjoy!
import Control.Monad.State
-- HOAS representation
data Expr = Lam (Expr -> Expr)
| App Expr Expr
| Lit Integer
-- Rotate transformation
rot :: Expr -> Expr
rot e = case e of
Lam f -> descend uniqueID (f (Lit uniqueID))
_ -> e
where uniqueID = 1 + maxLit e
descend :: Integer -> Expr -> Expr
descend i (Lam f) = Lam $ descend i . f
descend i e = Lam $ \a -> replace i a e
replace :: Integer -> Expr -> Expr -> Expr
replace i e (Lam f) = Lam $ replace i e . f
replace i e (App e1 e2) = App (replace i e e1) (replace i e e2)
replace i e (Lit j)
| i == j = e
| otherwise = Lit j
maxLit :: Expr -> Integer
maxLit e = execState (maxLit' e) (-2)
where maxLit' (Lam f) = maxLit' (f (Lit 0))
maxLit' (App e1 e2) = maxLit' e1 >> maxLit' e2
maxLit' (Lit i) = get >>= \k -> when (i > k) (put i)
-- Output
toStr :: Integer -> Expr -> State Integer String
toStr k e = toStr' e
where toStr' (Lit i)
| i >= k = return $ 'x':show i -- variable
| otherwise = return $ show i -- literal
toStr' (App e1 e2) = do
s1 <- toStr' e1
s2 <- toStr' e2
return $ "(" ++ s1 ++ " " ++ s2 ++ ")"
toStr' (Lam f) = do
i <- get
modify (+ 1)
s <- toStr' (f (Lit i))
return $ "\\x" ++ show i ++ " " ++ s
instance Show Expr where
show e = evalState (toStr m e) m
where m = 2 + maxLit e
-- Examples
ex2, ex3, ex4 :: Expr
ex2 = Lam(\a -> Lam(\b -> App a (App b (Lit 3))))
ex3 = Lam(\a -> Lam(\b -> Lam(\c -> App a (App b c))))
ex4 = Lam(\a -> Lam(\b -> Lam(\c -> Lam(\d -> App (App a b) (App c d)))))
check :: Expr -> IO ()
check e = putStrLn(show e ++ " ===> \n" ++ show (rot e) ++ "\n")
main = check ex2 >> check ex3 >> check ex4
with the following result:
\x5 \x6 (x5 (x6 3)) ===>
\x5 \x6 (x6 (x5 3))
\x2 \x3 \x4 (x2 (x3 x4)) ===>
\x2 \x3 \x4 (x4 (x2 x3))
\x2 \x3 \x4 \x5 ((x2 x3) (x4 x5)) ===>
\x2 \x3 \x4 \x5 ((x5 x2) (x3 x4))
(Don't be fooled by the similar-looking variable names. This is the rotation you seek, modulo alpha-conversion.)
Yes, I'm posting another answer. And it still might not be exactly what you're looking for. But I think it might be of use nonetheless. It's in Haskell.
data LExpr = Lambda Char LExpr
| Atom Char
| App LExpr LExpr
instance Show LExpr where
show (Atom c) = [c]
show (App l r) = "(" ++ show l ++ " " ++ show r ++ ")"
show (Lambda c expr) = "(λ" ++ [c] ++ ". " ++ show expr ++ ")"
So here I cooked up a basic algebraic data type for expressing lambda calculus. I added a simple, but effective, custom Show instance.
ghci> App (Lambda 'a' (Atom 'a')) (Atom 'b')
((λa. a) b)
For fun, I threw in a simple reduce method, with helper replace. Warning: not carefully thought out or tested. Do not use for industrial purposes. Cannot handle certain nasty expressions. :P
reduce (App (Lambda c target) expr) = reduce $ replace c (reduce expr) target
reduce v = v
replace c expr av#(Atom v)
| v == c = expr
| otherwise = av
replace c expr ap#(App l r)
= App (replace c expr l) (replace c expr r)
replace c expr lv#(Lambda v e)
| v == c = lv
| otherwise = (Lambda v (replace c expr e))
It seems to work, though that's really just me getting sidetracked. (it in ghci refers to the last value evaluated at the prompt)
ghci> reduce it
b
So now for the fun part, rotate. So I figure I can just peel off the first layer, and if it's a Lambda, great, I'll save the identifier and keep drilling down until I hit a non-Lambda. Then I'll just put the Lambda and identifier right back in at the "last" spot. If it wasn't a Lambda in the first place, then do nothing.
rotate (Lambda c e) = drill e
where drill (Lambda c' e') = Lambda c' (drill e') -- keep drilling
drill e' = Lambda c e' -- hit a non-Lambda, put c back
rotate e = e
Forgive the unimaginative variable names. Sending this through ghci shows good signs:
ghci> Lambda 'a' (Atom 'a')
(λa. a)
ghci> rotate it
(λa. a)
ghci> Lambda 'a' (Lambda 'b' (App (Atom 'a') (Atom 'b')))
(λa. (λb. (a b)))
ghci> rotate it
(λb. (λa. (a b)))
ghci> Lambda 'a' (Lambda 'b' (Lambda 'c' (App (App (Atom 'a') (Atom 'b')) (Atom 'c'))))
(λa. (λb. (λc. ((a b) c))))
ghci> rotate it
(λb. (λc. (λa. ((a b) c))))
One way to do it with template haskell would be like this:
With these two functions:
import Language.Haskell.TH
rotateFunc :: Int -> Exp
rotateFunc n = LamE (map VarP vars) $ foldl1 AppE $ map VarE $ (f:vs) ++ [v]
where vars#(f:v:vs) = map (\i -> mkName $ "x" ++ (show i)) [1..n]
getNumOfParams :: Info -> Int
getNumOfParams (VarI _ (ForallT xs _ _) _ _) = length xs + 1
Then for a function myF with a variable number of parameters you could rotate them this way:
$(return $ rotateFunc $ read $(stringE . show =<< (reify 'myF >>= return . getNumOfParams))) myF
There most certainly are neater ways of doing this with TH, I am very new to it.
OK, thanks to everyone who provided an answer. Here is the solution I ended up going with. Taking advantage of the fact that I know n:
rot :: Int -> [Expr] -> Expr
rot 0 xs = Lam $ \x -> foldl App x (reverse xs)
rot n xs = Lam $ \x -> rot (n - 1) (x : xs)
rot1 n = rot n []
I don't think this can be solved without giving n, since in the lambda calculus, a term's arity can depend on its argument. I.e. there is no definite "last" argument. Changed the question accordingly.
I think you could use the techniques described int the paper An n-ary zipWith in Haskell for this.
Can you write r in a generic way?
What if you know n?
Haskell
Not in plain vanilla Haskell. You'd have to use some deep templating magic that someone else (much wiser than I) will probably post.
In plain Haskell, let's try writing a class.
class Rotatable a where
rotate :: a -> ???
What on earth is the type for rotate? If you can't write its type signature, then you probably need templates to program at the level of generality you are looking for (in Haskell, anyways).
It's easy enough to translate the idea into Haskell functions, though.
r1 f = \a -> f a
r2 f = \b -> \a -> f a b
r3 f = \b -> \c -> \a -> f a b c
etc.
Lisp(s)
Some Lispy languages have the apply function (linked: r5rs), which takes a function and a list, and applies the elements of the list as arguments to the function. I imagine in that case it wouldn't be so hard to just un-rotate the list and send it on its way. I again defer to the gurus for deeper answers.

help with multiplying polynomials in lisp

for example: (3x2 - 5x + 2)(7x + 1) and you simplify it like this:
((3 2)(-5 1)(2 0))((7 1)(1 0))
((21 3)(3 2)(-35 2)(-5 1)(14 1)(2 0))
(21 3)(32 2)(9 1)(2 0)
and you get this answer: 21x3 + 32x2 + 9x + 2
i need this solution in lisp please help
For the first stage, you need to pair up every LHS component with every RHS component; a cartesian product of the two sets. This requires a two-level map followed by a concatenation of the second-level lists of pairs into a single top level list (think (apply #'append ...).
The second stage can be done with a reduce that builds up an association list, keyed on the exponent.
EDIT: Let me solve a different problem for you, and let you figure out how to translate it into the solution for your problem:
Compute (a + b + ... + k) * (l + m + ... + z) by first expanding into pairs and then summing the products:
(defun mul-sums (aa bb)
(reduce #'+
(apply #'append
(map 'list
#'(lambda (a)
(map 'list
#'(lambda (b)
(* a b))
bb))
aa))))
; Compute (1 + 2 + 3) * (3 + 4).
> (mul-sums '(1 2 3) '(3 4))
42