-3

In chapter 5th of Thinking Functionally with Haskell by Richard Bird, there's an equation:

filter (all p) . cp = cp . map (filter p)

I wonder how to prove it? (fusion law)?

I try to prove with fusion law. but how to prove the fusion law?

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Welcome to stackoverflow. Please checkout the [tour], [editing help](https://stackoverflow.com/editing-help) and [ask] – Marcelo Paco Apr 04 '23 at 03:56
  • 1
    What is `cp` in this context? – chi Apr 04 '23 at 07:30
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Apr 04 '23 at 18:22
  • cp is ‘cartesian product’:cp :: [[a]] -> [[a]] cp [] = [[]] cp (xs:xss) = [x:ys | x <- xs, ys <- yss] where yss = cp xss – user21561520 Apr 06 '23 at 12:47
  • all p = and . map p – user21561520 Apr 06 '23 at 12:49
  • I think the fusion law is the right approach. In particular you can rewrite `cp` as an application of `foldr` (which is an exercise in the book, I believe). Can you do that and add your progress to the question? Even if you can't completely finish the whole proof it is good to show where you are stuck. – Noughtmare Apr 15 '23 at 18:04
  • Finally, the following procedure could make sense to prove the equation: – user21561520 May 04 '23 at 13:11

1 Answers1

0

rewrite cp with foldr

cp = folder g [[]]
        where g xs xss = [x:ys|x<-xs,ys<-xss]

Assumption: (a) filter (all p) (cp xss) = cp (map (filter p) xs) = folder g [[]] (map (filter p) xs)

should prove equation (b) holds

(b)    filter (all p) (cp (xs:xss)) = cp (map (filter p) (xs:xss)) 

{# definition of map and cp #}
cp (map (filter p) (xs:xss)) = foldr g [[]] (map (filter p) (xs:xss))
{# definition of folder #}
g (filter p xs) (foldr g [[]] (map (filter p)) xss)

{# based on assumption (a)#) g (filter p xs) (filter (all p) (cp xss))

{# definition of g #}
[x:ys|x<-filter p xs, ys<-filter (all p) (cp xss)]
{# definition of filter 
[x:ys|x<-[x' <- xs,p x'], ys <- [ys' <- (cp xss), (all p) ys']]

{# condiontial cp means cp after filter #}

filter (all p) (cp (xs:xss))

In conclusion,
cp (map (filter p) (xs:xss)) = filter (all p) (cp (xs:xss))