Is there some Coq tactic to prevent the generation of several identical subgoals? If not, is it possible to write some tactic for eliminating the duplicate subgoals just after its generation? In Isabelle you can do it with:
apply (tactic {* distinct_subgoals_tac *})
It is not possible to eliminate duplicates after the fact without writing OCaml code, but you can create an evar which is the conjunction of all subgoals, deduplicated. Something like this:
Ltac distinct_subgoals_tactical tac :=
let H := fresh in
unshelve epose proof _ as H;
[ |
| tac;
[ (* first split apart the hypothesis containing the conjunction of all previous subgoals *)
repeat match type of H with prod _ _ => destruct H as [? H] end;
(* see if any of them solve the goal *)
try assumption;
(* otherwise, add another conjunct to the hypothesis and use the first part of it to solve the current goal *)
refine (fst H) .. ] ];
[ exact True (* fill the final conjunct with True *)
| repeat apply pair; try exact I .. ].
Then you can invoke it as distinct_subgoals_tactical ltac:(<apply tactic here>)
Related
I'm new to functional programming and I'm trying to implement a basic algorithm using OCAML for course that I'm following currently.
I'm trying to implement the following algorithm :
Entries :
- E : a non-empty set of integers
- s : an integer
- d : a positive float different of 0
Output :
- T : a set of integers included into E
m <- min(E)
T <- {m}
FOR EACH e ∈ sort_ascending(E \ {m}) DO
IF e > (1+d)m AND e <= s THEN
T <- T U {e}
m <- e
RETURN T
let f = fun (l: int list) (s: int) (d: float) ->
List.fold_left (fun acc x -> if ... then (list_union acc [x]) else acc)
[(list_min l)] (list_sort_ascending l) ;;
So far, this is what I have, but I don't know how to handle the modification of the "m" variable mentioned in the algorithm... So I need help to understand what is the best way to implement the algorithm, maybe I'm not gone in the right direction.
Thanks by advance to anyone who will take time to help me !
The basic trick of functional programming is that although you can't modify the values of any variables, you can call a function with different arguments. In the initial stages of switching away from imperative ways of thinking, you can imagine making every variable you want to modify into the parameters of your function. To modify the variables, you call the function recursively with the desired new values.
This technique will work for "modifying" the variable m. Think of m as a function parameter instead.
You are already using this technique with acc. Each call inside the fold gets the old value of acc and returns the new value, which is then passed to the function again. You might imagine having both acc and m as parameters of this inner function.
Assuming list_min is defined you should think the problem methodically. Let's say you represent a set with a list. Your function takes this set and some arguments and returns a subset of the original set, given the elements meet certain conditions.
Now, when I read this for the first time, List.filter automatically came to my mind.
List.filter : ('a -> bool) -> 'a list -> 'a list
But you wanted to modify the m so this wouldn't be useful. It's important to know when you can use library functions and when you really need to create your own functions from scratch. You could clearly use filter while handling m as a reference but it wouldn't be the functional way.
First let's focus on your predicate:
fun s d m e -> (float e) > (1. +. d)*.(float m) && (e <= s)
Note that +. and *. are the plus and product functions for floats, and float is a function that casts an int to float.
Let's say the function predicate is that predicate I just mentioned.
Now, this is also a matter of opinion. In my experience I wouldn't use fold_left just because it's just complicated and not necessary.
So let's begin with my idea of the code:
let m = list_min l;;
So this is the initial m
Then I will define an auxiliary function that reads the m as an argument, with l as your original set, and s, d and m the variables you used in your original imperative code.
let rec f' l s d m =
match l with
| [] -> []
| x :: xs -> if (predicate s d m x) then begin
x :: (f' xs s d x)
end
else
f' xs s d m in
f' l s d m
Then for each element of your set, you check if it satisfies the predicate, and if it does, you call the function again but you replace the value of m with x.
Finally you could just call f' from a function f:
let f (l: int list) (s: int) (d: float) =
let m = list_min l in
f' l s d m
Be careful when creating a function like your list_min, what would happen if the list was empty? Normally you would use the Option type to handle those cases but you assumed you're dealing with a non-empty set so that's great.
When doing functional programming it's important to think functional. Pattern matching is super recommended, while pointers/references should be minimal. I hope this is useful. Contact me if you any other doubt or recommendation.
As I was typing up some code in OCaml, I wanted to match two cases at once (since the function I'm writing is commutative):
type something =
| Two of int * int
| One of int
let my_function p q =
match p, q with
| Two (_, _) as two, One (x)
| One (x), Two (_, _) as two -> (* some value *)
| _ -> (* some other value *)
;;
I'm getting the following error:
Error: Variable two must occur on both sides of this | pattern
The problem doesn't occur when I remove the as statement, but I need it for the logic purposes. Why can't I do it like this? Will I have to resort to rewriting the logic twice?
as has lower precedence than ,. Hence you should put parenthesis around Two (_,_) as two.
I am making a game solver and while using a matrix in OCaml, I need to check whenever it's complete, with A's or V's, to do so I attempeted to see if there is a '.' in at least one of the cells because that symbolizes an empty cell. Here goes the code:
let is_solved m n =
for i=0 to n do
for j=0 to n do
if(m.(i).(j)='.') then false
done
done;;
So my is_solved function has to return false when it finds a '.' at any position or true if it doesn't. But OCaml is giving me a:
Error: The variant type unit has no constructor false
I am new to OCaml but can someone tell me what I need to fix or even why is it giving me that error message?
First, note that the value of any OCaml construct of the form for ... done is (), the single value of type unit. You can't give a value to the loop as you seem to be trying to do.
Your immediate problem is that when you use if without else in OCaml, the value of the expression has to be of type unit. This is necessary because the type has to be the same in both cases. However, it's not really worth fixing this due to the above problem.
If you want to use for loops to solve your problem, you'll need to use an imperative approach. That is, you'll need to keep a mutable value to hold what you want to return at the end.
(Since you're new to OCaml it might be useful to try coding this function in a more functional style just to see how it looks.)
You can write this function in a recursive way as Jeffrey has suggested, just to give you a starting kick, I will provide a general template letting you to fill the gaps:
let todo = failwith
(* [is_solved field m n] true if exists '.' in the [field], where
[field] is a matrix of size [m] x [n] *)
let is_solved field m n =
let rec outer = function
| 0 -> todo "outer loop ends"
| m -> inner m n
and inner m = function
| 0 -> todo "inner loop ends"
| n -> todo "inner loop workload" in
outer m
Here is what I have and the error that I am getting sadly is
Error: This function has type 'a * 'a list -> 'a list
It is applied to too many arguments; maybe you forgot a `;'.
Why is that the case? I plan on passing two lists to the deleteDuplicates function, a sorted list, and an empty list, and expect the duplicates to be removed in the list r, which will be returned once the original list reaches [] condition.
will be back with updated code
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
I don't know how useful this might be, but here is some code that does what you want, written in a fairly standard OCaml style. Spend some time making sure you understand how and why it works. Maybe you should start with something simpler (eg how would you sum the elements of a list of integers ?). Actually, you should probably start with an OCaml tutorial, reading carefully and making sure you aunderstand the code examples.
let deleteDuplicates u =
(*
u : the sorted list
v : the result so far
last : the last element we read from u
*)
let rec aux u v last =
match u with
[] -> v
| x::xs when x = last -> aux xs v last
| x::xs -> aux u (x::v) x
in
(* the first element is a special case *)
match u with
[] -> []
| x::xs -> List.rev (aux xs [x] x)
This is not a direct answer to your question.
The standard way of defining an "n-ary" function is
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
See examples here:
https://github.com/ocaml/ocaml/blob/trunk/stdlib/complex.ml
By switching from myfunc_java_way to myfunc_caml_way, you will be benefited from what's called "Currying"
What is 'Currying'?
However please note that you sometimes need to enclose the whole invocation by parenthesis
myfunc_caml_way (otherfunc_caml_way "foo" "bar") 123
in order to tell the compiler not to interpret your code as
((myfunc_caml_way otherfunc_caml_way "foo") "bar" 123)
You seem to be thinking that OCaml uses tuples (a, b) to indicate arguments of function calls. This isn't the case. Whenever some expressions stand next to each other, that's a function call. The first expression is the function, and the rest of the expressions are the arguments to the function.
So, these two lines:
append(first,r)
deleteDuplicates(remaining, r)
Represent a function call with three arguments. The function is append. The first argument is (first ,r). The second argument is deleteDuplicates. The third argument is (remaining, r).
Since append has just one argument (a tuple), you're passing it too many arguments. This is what the compiler is telling you.
You also seem to be thinking that append(first, r) will change the value of r. This is not the case. Variables in OCaml are immutable. You can't do anything that will change the value of r.
Update
I think you have too many questions for SO to help you effectively at this point. You might try reading some OCaml tutorials. It will be much faster than asking a question here for every error you see :-)
Nonetheless, here's what "match failure" means. It means that somewhere you have a match that you're applying to an expression, but none of the patterns of the match matches the expression. Your deleteDuplicates code clearly has a pattern coverage error; i.e., it has a pattern that doesn't cover all cases. Your first match only works for empty lists or for lists of 2 or more elements. It doesn't work for lists of 1 element.
I want to evaluate f below by passing a list to some function:
f = {z[1] z[2], z[2]^2};
a = % /. {z[1]-> #1,z[2]-> #2};
F[Z_] := Evaluate[a] & ## Z ;
So now if I try F[{1,2}] I get {2, 4} as expected. But looking closer ?F returns the definition
F[Z_] := (Evaluate[a] &) ## Z
which depends on the value of a, so if we set a=3 and then evaluate F[{1,2}], we get 3. I know that adding the last & makes the Evaluate[a] hold, but what is an elegant work around? Essentially I need to force the evaluation of Evaluate[a], mainly to improve efficiency, as a is in fact quite complicated.
Can someone please help out, and take into consideration that f has to contain an Array[z,2] given by some unknown calculation. So writing
F[Z_] := {Z[[1]]Z[[2]],Z[[2]]^2}
would not be enough, I need this to be generated automatically from our f.
Many thanks for any contribution.
Please consider asking your future questions at the dedicated StackExchange site for Mathematica.
Your questions will be much less likely to become tumbleweeds and may be viewed by many experts.
You can inject the value of a into the body of both Function and SetDelayed using With:
With[{body = a},
F[Z_] := body & ## Z
]
Check the definition:
Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) ## Z$
You'll notice Z has become Z$ due to automatic renaming within nested scoping constructs but the behavior is the same.
In the comments you said:
And again it bothers me that if the values of z[i] were changed, then this workaround would fail.
While this should not be a problem after F[Z_] is defined as above, if you wish to protect the replacement done for a you could use Formal Symbols instead of z. These are entered with e.g. Esc$zEsc for Formal z. Formal Symbols have the attribute Protected and exist specifically to avoid such conflicts as this.
This looks much better in a Notebook than it does here:
f = {\[FormalZ][1] \[FormalZ][2], \[FormalZ][2]^2};
a = f /. {\[FormalZ][1] -> #1, \[FormalZ][2] -> #2};
Another approach is to do the replacements inside a Hold expression, and protect the rules themselves from evaluation by using Unevaluated:
ClearAll[f, z, a, F, Z]
z[2] = "Fail!";
f = Hold[{z[1] z[2], z[2]^2}];
a = f /. Unevaluated[{z[1] -> #1, z[2] -> #2}] // ReleaseHold;
With[{body = a},
F[Z_] := body & ## Z
]
Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) ## Z$