I'm trying to prove the following theorem.
Theorem subseq_trans : forall (l1 l2 l3 : list nat),
subseq l1 l2 -> subseq l2 l3 -> subseq l1 l3.
Proof.
intros l1 l2 l3 H12 H23. generalize dependent l1. (* here l2 l3 *) induction H23.
- intros. inversion H12. apply empty.
- (* here l1 l2 *) rename l2 into l3. rename l1 into l2. ...
In line 3 after generalize dependent l1. I have the following context:
l2, l3 : list nat
H23 : subseq l2 l3
But in line 5 before renames I have
l1, l2 : list nat
H23 : subseq l1 l2
IHsubseq : ...
So l2 and l3 became l1 and l2. Why did it happen? How can I prevent this from happening?
I don't think it's important, but subseq is defined like this:
Inductive subseq : list nat -> list nat -> Prop :=
| empty l : subseq [] l
| first x l1 l2 (H : subseq l1 l2) : subseq (x :: l1) (x :: l2)
| skip x l1 l2 (H : subseq l1 l2) : subseq l1 (x :: l2).
My Coq version:
The Coq Proof Assistant, version 8.8.2 (January 2019)
It's renamed to l1 and l2 because that's the name given in the definition of subseq. To fix this you can name the variables explicitly when doing the induction:
induction H23 as [ | ? l2 l3 | ].
Here there are 3 cases for subseq, so you need 3 branches. I've only named the lists for the first case, so I've left the names blank for the other cases and used ? once, both of which which tell Coq to use the default naming.
Related
I wrote the following function to find the Nth element on a given Snoc list (reverse cons) but I think it's not the most optimal solution to the problem. I was wondering if you would please share some insights, code or advice to see a different solution; one that you might consider does the job more efficiently:
Here's my function:
data ListS a = NilS
|Snoc (ListS a) a deriving Show
len :: ListS a -> Int
len NilS = 0
len (Snoc a b) = 1 + len(a)
nthElementS :: Int -> ListS a -> a
nthElementS _ NilS = error "Empty List"
nthElementS n s = if n < 0 || n >= len(s) then error "Invalid Index"
else nthAux ((len(s)-1)-n) s where
nthAux 0 (Snoc a b) = b
nthAux m (Snoc a b) = nthAux (m-1) a
Some examples:
Main> nthElementS 0 (Snoc (Snoc (Snoc (Snoc (Snoc NilS 1) 2) 3) 4) 5)
1
Main> nthElementS 2 (Snoc (Snoc (Snoc (Snoc (Snoc NilS 1) 2) 3) 4) 5)
3
As an additional inquiry: What would be the best way to implement a function that concatenates 2 Snoc lists? I am already thinking of a solution but it would require an auxiliary function to keep track of the Nth position, and again, I feel that's not going to make full use of Haskell's advantages over other languages.
Thanks in advance.
We can use a "try-and-error" approach where we first try to find that element in the "prefix list", and if that is not sufficient (since the index is larger), we then try the current element. If that still is not enough, it is up to the "parent call" to handle the situation. We can do this by first defining a function with a slightly different output type:
nthShelp :: Int -> ListS a -> Either a Int
So it returns Left x in case it has found the element (x being the element), or Rightn, withn` the "remaining" elements it needs to walk through.
So we can define this with:
nthShelp :: Int -> ListS a -> Either a Int
nthShelp n NilS = Right n
nthShelp n (Snoc hs t) = progress nhs
where nhs = nthElementS n hs
progress lx#(Left _) = lx
progress (Right 0) = Left t
progress (Right n) = Right (n-1)
So we first call recursively on the head of the list, and then the recursive calls are resolved by decrementing the index until it hits zero, in which case we return the corresponding Left t, and that Left t is than passed back out of the recursive calls.
We can make use of the fact that Either a is a Monad istance, and write this more effective like:
nthShelp :: Int -> ListS a -> Either a Int
nthShelp n NilS = Right n
nthShelp n (Snoc hs t) = nthElementS n hs >>= progress
where progress 0 = Left t
progress n = Right (n-1)
Then we can write nthElementS in terms of nthShelp with:
nthElementS :: Int -> ListS a -> a
nthElementS n l | n < 0 = error "Index too small"
| Left a <- nthShelp n l = a
| otherwise = error "Index too large"
In terms of time complexity, it is still O(n) (with n the length of the list, not the index we want to obtain). There is no way to do it better with this data structure, since we need to know the number of elements in the prefix, before we know what element to return.
As an additional inquiry: What would be the best way to implement a function that concatenates 2 Cons lists? I am already thinking of a solution but it would require an auxiliary function to keep track of the Nth position, and again, I feel that's not going to make full use of Haskell's advantages over other languages.
Well you can see a concatenation here as replacing the (usally deeply) nested NlS of the second list, by the first list. So if we concatenate concatS l1 NilS, then it is l1, if we concatenate concatS l1 (Snoc NilS x), then it is Snic l1 x). So we can define this recursively as:
concatS :: ListS a -> ListS a -> ListS a
concatS l1 NilS = l1
concatS l1 (Snoc l2 x) = Snoc (concatS l1 l2) x
A disadvantage of the above approach is that it still will work in O(n) if the first list is NilS (so empty). We can add a guard for this, to handle that case:
concatS :: ListS a -> ListS a -> ListS a
concatS NilS = id
concatS l1 = go
where go NilS = l1
go (Snoc l2 x) = Snoc (go l2) x
My Argument/Answer is if y is aregular set then there exits a DFA which accepts y. In the L1 there is a condition that y=x^n, that x will belong to L1,as y is accepted by DFA. So is x^n and so is x so L1 is regular. Now L2 --> here the condition is x=y^n. Here y is accepted by DFA so is y^n so which is equal to x so x can be accepted by DFA. This makes both L1,L2 regular
Is my argument right?
This question seems like it's poorly-posed. For example, if we take A = {a}, then L1 is the language {a} and L2 is the language a*, both of which are regular. If we pick A = a*b, then L1 = a *b (which is regular) and L2 = { (anb)m | m, n ≥ 0 }, which is not regular (using the pumping lemma). In other words, the answer depends on the choice of A.
This function I made returns a parse error on input ‘=’
checkappend :: Maybe [a] -> Maybe [a] -> (a -> Bool) -> Maybe [a]
checkappend ml1 ml2 test =
if all test l1
then (Just (l1 ++ l2))
else Nothing
where l1 = fromJust(ml1)
l2 = fromJust(ml2)
The where needs to be indented less than the function body, any consistently:
checkappend ml1 ml2 test =
if all test l1
then Just (l1 ++ l2)
else Nothing
where l1 = fromJust ml1
l2 = fromJust ml2
BTW, using partial functions like head or fromJust is bad style. Better use pattern matching on Maybe arguments! Also, if then else is somewhat unpopular in Haskell – guards tend to look nicer:
checkappend (Just l1) (Just l2) test
| all test l1 = Just $ l1 ++ l2
| otherwise = Nothing
Of course, the pattern match is still incomplete... what to do if one of the arguments is Nothing? I reckon you want to result to be Nothing then, too; that's possible with a catch-all pattern:
checkappend (Just l1) (Just l2) test
| all test l1 = Just $ l1 ++ l2
checkappend _ _ _ = Nothing
Note that this already includes the | otherwise guard: if no guard for a given pattern clause matches, Haskell just continues with the next clause.
A really slick way to write it:
import Control.Monad (guard)
checkAppend m1 m2 test =
do
l1 <- m1
l2 <- m2
guard $ all test l1
return $ l1 ++ l2
This uses the fact that Maybe is a monad with a notion of failure. If either of the arguments is nothing, it fails to extract l1 or l2 and gives Nothing. If the guard argument is false, it gives Nothing. Finally, if all goes well, it gives Just (l1 ++ l2).
For fun, try writing the function I just gave and applying it to two lists of lists, instead of two maybe lists. What does it do? Can you figure out why?
Hi I was wondering whether there was a way to use do if in haskell in this kind of way
doIfFunction :: Eq a => [a]->[a] ->[a]
doIfFunction l1 l2 = do
if l /= something then (l2++something) else l2
if l /= something2 then (l2++something2) else l2
l2
Basically if this something function returns a different value I want it to add it to l2 then return l2. I keep getting l2 as being empty at the end and it shouldn't be, is this because of the else l2 does it reset the value of l2 to what it was at the start?
If so could I do something like this?
doIfFunction :: Eq a => [a]->[a] ->[a]
doIfFunction l1 l2 = do
if l /= something then (let l2 = l2++something) else l2
if l /= something2 then (let l2 = l2++something2) else l2
l2
This gives errors, but I was wondering if this is on the right lines.
When the doIfFunction is being called it will always be doIfFunction l [] where l contains values and [] is empty
Generally, you should avoid to think about modifying anything in Haskell. In fact, you can't, the language doesn't allow it. At all†!
Instead of modifying the list l2 itself, you think about creating additional lists which are modified versions of l2. (The immediate benefit is that you can still use the original l2 anywhere else; in particular it's fine if some other function / thread still needs this old version and you weren't aware of it.)
I.e., instead of
do
modify_something_about_l2
modify_something_else_about_l2
yield_some_result
you want to just evaluate the result of a function-application chain, like
f l2 = some_other_modification (some_modification (l2))
or, as we prefer to write it,
f = some_other_modification . some_modification
In your particular case:
doIfFunction l1
= (\l2 -> if l /= something2 then (l2++something2) else l2)
. (\l2 -> if l /= something then (l2++something) else l2)
If you don't like the “backwards style“ you can also replace the composition operator . with its flipped version:
import Control.Arrow
doIfFunction l1
= (\l2 -> if l /= something then (l2++something) else l2)
>>> (\l2 -> if l /= something2 then (l2++something2) else l2)
Also, you can, via eta-reduction, avoid mentioning the intermediate lists at all:
doIfFunction l1
= (if l /= something then (++something) else id)
>>> (if l /= something2 then (++something2) else id)
That said...
You're probably thinking: it's mighty inefficient to always create new modified versions of everything, instead of just modifying in-place. Well, sometimes it is, often it is actually no problem at all.
You example is in fact one where it is a problem: to append something to l2, a copy of the entire list needs to be made. Maybe you can avoid this problem very easily: if instead of appending, you prepend:
doIfFunction l1
= (if l /= something then (something++) else id)
>>> (if l /= something2 then (something2++) else id)
then there's no performance penalty. The reason being: a list is just a chain of elements (heads), each with references to the rest of the list. Pre-pending an element is just a matter of making a new head and linking it to the already existing list!
†Even with clever lazy prepending, sometimes the pure-functional style is significantly more time-expensive. Don't worry: although Haskell does not allow modifying values, there are types which encapsulate the concept of destructive modifications, namely the ST monad. So you can still implement algorithms that need destructive updates efficiently, but basically you don't do it in Haskell but in an embedded “domain-specific imperative language”, that integrates seamlessly with Haskell.
Just put the if clause in the let statement:
doIfFunction :: Eq a => [a] -> [a] -> [a]
doIfFunction l1 l2 = do
let l2' = if l /= something then l2 ++ something else l2
let l2'' = if l /= something2 then l2' ++ something2 else l2'
l2''
But in this case you don't really need the do notation since you don't use any monadic operation. I believe you want to use the do notation to simulate imperative-style programming. Consider using a where if you think it's more readable:
doIfFunction :: Eq a => [a] -> [a] -> [a]
doIfFunction l1 l2 = result
where newL2 = if l /= something then l2 ++ something else l2
result = if l /= something2 then newL2 ++ something2 else newL2
Alternatively, when you will be more familiar with Haskell, you could use leftaroundabout's answer (that would be the most idiomatic way to write what you want to do).
Let there be two languages L1 and L2 with the property that L1 ⊆ L2 and L2 ∈ REG then L1 ∈ REG. I have searched everywhere and I can't find anything, how do you solve this ? Can you please provide ample explanation, thank you,
I'm taking this as the question:
If L1 is a subset of L2, and L2 is regular, does it follow that L1 is regular also?
The answer is no. The proof is by counterexample. Let L2 be the following regular language: all strings over the alphabet. Let L1 be the following subset of L2: any non-regular language of the alphabet. Then L1 is a subset of L2, L2 is regular, and L1 is non-regular.