I'm trying to prove the following Lemma in coq --
Lemma less_than_two_equivalent: forall x, less_than_two x = true -> x < 2.
based on the definition below.
Fixpoint less_than (a b:nat): bool:=
match a, b with
|0, 0 => false
|0, _ => true
|S a', 0 => false
|S a', S b' => less_than a' b'
end.
Fixpoint less_than_two (x:nat) : bool := if less_than x 2 then true else false.
Mathematically, there are only 2 cases, 0 or 1. And destructionshould be the hammer, but there won't be enough information about the S x for further reasoning.
Should I modify the less_than into inductive datatypes? If not, how to resolve it?
Let me begin by redefining less_than_two. First, it's not recursive, so there is no point in defining it as a Fixpoint. Next, if less_than x 2 then true else false is essentially the same thing as less_than x 2. And at this point I wouldn't bother with introducing a new definition, so your lemma becomes
Lemma less_than_two_equivalent x: less_than x 2 = true -> x < 2.
Proof.
do 2 (destruct x; auto); simpl.
destruct x; discriminate.
Qed.
I don't know what went wrong with your proof exactly, but you might have forgotten to destruct x one more time. When you see less_than x 0 = true -> S (S x) < 2 you can't still use discriminate to finish your goal, because evaluation is blocked on the variable -- less_than first pattern-matches on the a parameter and only then checks b. Destruction of x unblocks computation and lets Coq see that you have false = true as your premise, hence the goal becomes provable.
Note that this depends on the particular implementation of the comparison function. Had you chose this one
(* (!) the [struct] annotation is important here, as well as as
the order of the parameters [b, a] in the match expression *)
Fixpoint less_than' (a b : nat) {struct b} : bool :=
match b, a with
| 0, _ => false
| _, 0 => true
| S b', S a' => less_than' a' b'
end.
you would have a bit simpler proof (one less destruct):
Lemma less_than_two_equivalent x: less_than' x 2 = true -> x < 2.
Proof.
do 2 (destruct x; auto).
discriminate.
Qed.
Related
I'm trying to prove that generator functions produce certain, still very simple, patterns.
pattern_0_1 generates a list of alternating 0s and 1s. I've succeeded to prove that the first item is zero for any list whose length is greater than 0. Applying the same technique, however, failed to prove the 2nd element is always 1. My guess is induction is not at all required here. I'd appreciate any help on the right approach to complete the second lemma.
fun pattern_0_1 :: "nat ⇒ nat ⇒ nat list" where
"pattern_0_1 0 item = []" |
"pattern_0_1 len item = item # (pattern_0_1 (len - 1) (if item = 0 then 1 else 0))"
lemma item_0_is_0 : "lng ≥ 1 ⟹ pattern_0_1 lng 0 ! 0 = 0"
apply(induction lng)
apply(simp)
by auto
lemma item_1_is_1 : "lng ≥ 2 ⟹ pattern_0_1 lng 0 ! 1 = 1"
apply(induction lng)
apply(simp)
sorry
Induction is not required (it would be, would you show something about all even or all odd positions). Here, case analysis is enough, so that you get the cases 0, 1, and >= 2. So, your proof can be done via
apply(cases lng; cases "lng - 1"; auto)
where the first cases will be on being 0 or >= 1, and the second cases will distinguish between 1 and >= 2.
In functional programming, what is the name (or name of the concept) of the following functional operator P?:
Given two functions f and g, and predicate function p, P(p, f, g) is the function
x → if (p(x)) f(x) else g(x)
I am wondering whether this operator has an established name, so that I can use that name in my code. (That is, I want to give P a conventional name.)
I would say it's the if operator lifted into the function monad.
For example in Haskell, you can literally do
import Control.Monad
let if' c t f = if c then t else f -- another common name is `ite`
let ifM = liftM3 if' -- admittedly the type of this is too generic
-- ^^^^^^^^^^
let example = ifM even (\x -> "t "++show x) (\x -> "f "++show x)
example 1 -- "f 1"
example 2 -- "t 2"
Another haskell example Point-wise conditional in Boolean library
cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
it takes Applicative that holds bool, two another Applicatives with values for True and False cases and produces Applicative result.
There are different types that are Applicative and function is just one of them.
> f = cond (\x -> x > 1) (\x -> x / 10) (\x -> x * 10)
> f 2.0
# 0.2
> f 0.13
#1.3
Optional value Maybe is another useful example
> cond (Just True) (Just 10) (Just 20)
# Just 10
> cond (Just True) (Just 10) Nothing
# Nothing
List is also Applicative
> cond [True, False, True] [10] [1, 2]
# [10,10,1,2,10,10]
> cond [True, False, True] [10] [1]
# [10, 1, 10]
> cond [True, False, True] [10] []
# []
I'm trying to prove the following lemma:
lemma if_assumption: "(if a = 1 then 2 else 3) = 2 ⟹ a = 1"
apply (cases "a = 1")
apply simp_all
After simplification I get the following formula:
3 = 2 ⟹ a ≠ 1 ⟹ False
The result of if-expression equals 2 iff a equals 1. So, I guess that I can deduce this fact somehow.
How to prove this lemma?
Your statement is not correct as you wrote it down. Numbers in Isabelle are polymorphic by default (you can check that by hovering over the numbers while pressing Ctrl). There might be a number type for which 3 = 2 holds (e.g. the finite field {0,1,2}). In that case, a may not be equal to 1.
If instead you fix the number type:
lemma if_assumption: "(if a = 1 then 2 else 3) = (2::nat) ⟹ a = 1"
the proof script you wrote goes through. Or shorter:
apply (auto split: if_splits)
... which tells the system to split the if _ then _ else _ into two subgoals.
I have the following code in OCaml.I have defined all necesar functions and tested them step by step the evalution should work good but I didn't succed to manipulate the variables inside of while.How can I make x,vn,v to change their value?I think I should rewrite the while like a rec loop but can't figure out exactly:
Here is the rest of code: http://pastebin.com/Ash3xw6y
Pseudocode:
input : f formula
output: yes if f valid
else not
begin:
V =set of prop variables
eliminate from f => and <=>
while (V is not empty)
choose x from V
V =V -{x}
replace f with f[x->true]&&f[x->false]
simplify as much as possible f
if f is evaluated with true then return true
else if (not f) is evaluated true then return false
end if
end while
return false
end
type bexp = V of
| string
| B of bool
| Neg of bexp
| And of bexp * bexp
| Or of bexp * bexp
| Impl of bexp * bexp
| Eqv of bexp * bexp
module StringSet=Set.make(String)
let is_valide f=
let v= stringset_of_list (ens f []) in (*set of all variables of f *)
let g= elim f in (*eliminate => and <=> *)
let quit_loop=ref false in
while not !quit_loop
do
let x=StringSet.choose v in
let vn=StringSet.remove x v in
if StringSet.is_empty vn=true then quit_loop:=true;
let h= And( replace x (B true) g ,replace x (B false) g)in
let j=simplify h in
if (only_bools j) then
if (eval j) then print_string "yes"
else print_string "not"
done
(New form)
let tautology f =
let rec tautology1 x v g =
let h= And( remplace x (B true) g ,remplace x (B false) g)in
let j= simplify h in
if not (only_bools j) then tautology (StringSet.choose (StringSet.remove x v) (StringSet.remove x v) j
else
if (eval1 j) then print_string "yes \n " else
if (eval1 (Neg (j))) then print_string "not \n";
in tautology1 (StringSet.choose (stringset_of_list (ens f [])) (stringset_of_list (ens f [])) (elim f);;
while loop belongs to imperative programming part in OCaml.
Basically, you can't modify immutable variables in while or for loops or anywhere.
To let a variable to be mutable, you need to define it like let var = ref .... ref is the keyword for mutables.
Read these two chapters:
https://realworldocaml.org/v1/en/html/a-guided-tour.html#imperative-programming
https://realworldocaml.org/v1/en/html/imperative-programming-1.html
You can define x,vn,v as refs, but I guess it will be ugly.
I suggest you think your code in a functional way.
Since you haven't placed functions ens etc here, I can't produce an example refine for u.
val compare : bool array array -> 'a list -> 'a list -> int
compare m generates the lexicographical order on list. I don't know how to fill ???
let rec compare m c c' =
match c with
| [] -> (match c' with
| [] -> 0
| _ :: _ -> -1)
| hd1 :: tl1 -> (match c' with
| [] -> 1
| hd2 :: tl2 -> ???
This is a function that I was trying to do by in a list of ints. but this function was not satisfy, it still missing to check in the rest of a list.
let cmp_classes m c c' =
match c, c' with
| i :: _, j :: _ ->
begin
match m.(i).(j), m.(j).(i) with
(* same class: there is a path between i and j, and between j and i *)
| true, true -> 0
(* there is a path between i and j *)
| true, false -> 1
(* there is a path between j and i *)
| false, true -> -1
(* i and j are not compareable *)
| false, false -> 0
end
| _ -> assert false
Could you please help me? Because when I tried with this function in int
let cmp_classes m i j =
match m.(i).(j), m.(j).(i) with
(* same class: there is a path between i and j, and between j and i *)
| true, true -> 0
(* there is a path between i and j *)
| true, false -> 1
(* there is a path between j and i *)
| false, true -> -1
(* i and j are not compareable *)
| false, false -> 0
it still not return the right order in data I test.
I have been doing this function many times, it is really stuck when I have to try again and again but not find out what is wrong. Please I need your help. Thank you
(* i and j are not compareable *)
| false, false -> 0
This is completely wrong if you are trying to make a topologic sort of your elements. You are saying that incomparable elements are equals which is complete nonsense and WILL confuse the sort algorithm.
If you want to have a real topological order you should follow these steps:
build an input list as the list containing only one representant per class; the output list is empty
until the input list is empty:
pick a random root (with no input edge) in the input list and remove it from the list
append (in any order) all elements the root representants in the output list
return the output list
Depending on the data-structures you are using, this algorithm can be more or less efficient, but your question is not enough precise for me to tell you more.