equal
deleted
inserted
replaced
3738 where |
3738 where |
3739 "map_filter f P [] = []" |
3739 "map_filter f P [] = []" |
3740 | "map_filter f P (x#xs) = |
3740 | "map_filter f P (x#xs) = |
3741 (if P x then f x # map_filter f P xs else map_filter f P xs)" |
3741 (if P x then f x # map_filter f P xs else map_filter f P xs)" |
3742 |
3742 |
|
3743 primrec |
|
3744 length_unique :: "'a list \<Rightarrow> nat" |
|
3745 where |
|
3746 "length_unique [] = 0" |
|
3747 | "length_unique (x#xs) = |
|
3748 (if x \<in> set xs then length_unique xs else Suc (length_unique xs))" |
|
3749 |
3743 text {* |
3750 text {* |
3744 Only use @{text mem} for generating executable code. Otherwise use |
3751 Only use @{text mem} for generating executable code. Otherwise use |
3745 @{prop "x : set xs"} instead --- it is much easier to reason about. |
3752 @{prop "x : set xs"} instead --- it is much easier to reason about. |
3746 The same is true for @{const list_all} and @{const list_ex}: write |
3753 The same is true for @{const list_all} and @{const list_ex}: write |
3747 @{text "\<forall>x\<in>set xs"} and @{text "\<exists>x\<in>set xs"} instead because the HOL |
3754 @{text "\<forall>x\<in>set xs"} and @{text "\<exists>x\<in>set xs"} instead because the HOL |
3825 |
3832 |
3826 lemma map_filter_conv [simp]: |
3833 lemma map_filter_conv [simp]: |
3827 "map_filter f P xs = map f (filter P xs)" |
3834 "map_filter f P xs = map f (filter P xs)" |
3828 by (induct xs) auto |
3835 by (induct xs) auto |
3829 |
3836 |
|
3837 lemma lenght_remdups_length_unique [code inline]: |
|
3838 "length (remdups xs) = length_unique xs" |
|
3839 by (induct xs) simp_all |
|
3840 |
|
3841 hide (open) const length_unique |
|
3842 |
3830 |
3843 |
3831 text {* Code for bounded quantification and summation over nats. *} |
3844 text {* Code for bounded quantification and summation over nats. *} |
3832 |
3845 |
3833 lemma atMost_upto [code unfold]: |
3846 lemma atMost_upto [code unfold]: |
3834 "{..n} = set [0..<Suc n]" |
3847 "{..n} = set [0..<Suc n]" |