The following code gives me an error:
Require Import Reals.
Require Import List.
Import ListNotations.
Open Scope R_scope.
Definition C := (R * R)%type.
Definition RtoC (r : R) : C := (r,0).
Coercion RtoC : R >-> C.
Definition lC : list C := [0;0;0;1].
Error: The term "[0; 0; 0; 1]" has type "list R" while it is expected to have type "list C".
But I've defined RtoC as a coercion and I don't see any problems when I use
Definition myC : C := 4.
How do I get Coq to apply the coercion within the list?
Related question: If I enter Check [0;0;0;1] it returns list R, inserting an implicit IZR before every number. Why does Coq think I want Rs rather than Zs?
I'm unsure there is a fully satisfying solution to your question.
Indeed, as recalled in the Coq refman:
Given a term, possibly not typable, we are interested in the problem of determining if it can be well typed modulo insertion of appropriate coercions.
and it turns out that in your example, the term [0;0;0;1] itself is typable as a list R and it is type-checked "in one go"; thereby when the [0;0;0;1] : list C type mismatch occurs, as there's no "backtracking", a coercion can't be inserted within the list elements.
So maybe you could adapt your formalization in a different way, or just use one of these workarounds:
Rewriting your term into a β-redex:
Definition lC := (fun z o => [z;z;z;o] : list C) 0 1.
Or inserting a few more typecasts around each element:
Definition lC := [0:C; 0:C; 0:C; 1:C].
Regarding your last question
Why does Coq think I want Rs rather than Zs?
this comes from your line Open Scope R_scope., which implies numeral litterals are recognized by default as belonging to R (which deals with the classical axiomatization of the real numbers formalized in the standard library Reals). More specifically, the implementation has changed in Coq 8.7, as from coq/coq#a4a76c2 (discussed in PR coq/coq#415). To sum up, a literal such as 5%R is now parsed as IZR 5, that is, IZR (Zpos (xI (xO xH))), while it used to be parsed to a much less concise term in Coq 8.6:
Rplus R1 (Rmult (Rplus R1 R1) (Rplus R1 R1)).
I wanted to write the simplest proof in Mizar mathematical theorem prover language I could think of. So I thought of the following:
there exists x \in Nat : x = 1
there isn't anything simpler that I could think of. I gave it the following attempt:
:: example of a comment
environ
vocabularies MY_MIZAR;
:: adding Natural Numbers
requirments SUBSET, NUMERALS, ARITHM;
::> *210
begin
theorem Th1:
ex x being Nat st x=1
proof
::consider x = 1
:: proof is done
x = 1;
thus Th1;
end;
::>
::> 210: Wrong item in environment declaration
but as you can see Mizar doesn't like my proof. What am I missing?
This still doesn't work:
::: example of a comment
environ
vocabularies MY_MIZAR;
::: adding Natural Numbers
requirements SUBSET, NUMERALS, ARITHM;
::> *856 *825
begin
theorem Th1:
ex x being Nat st x=1
proof
:::consider x = 1
::: proof is done
set x=1;
take x;
thus thesis;
end;
::>
::> 825: Cannot find constructors name on constructor list
::> 856: Inaccessible requirements directive
You can try the following:
1) Fix the 210: error:
x requirments (wrong spelling)
o requirements
2) There will probably be some new errors
about the contents of that line now, so when
you are starting out, it is usually good to
"borrow" an environ that already works, e.g.,
you can use the environ lines from one of the
Mizar articles on natural numbers like
NAT_1.miz:
environ
:: adding Natural Numbers
vocabularies NUMBERS, ORDINAL1, REAL_1, SUBSET_1, CARD_1, ARYTM_3, TARSKI,
RELAT_1, XXREAL_0, XCMPLX_0, ARYTM_1, XBOOLE_0, FINSET_1, FUNCT_1, NAT_1,
FUNCOP_1, PBOOLE, PARTFUN1, FUNCT_7, SETFAM_1, ZFMISC_1;
notations TARSKI, XBOOLE_0, ENUMSET1, ZFMISC_1, SUBSET_1, SETFAM_1, ORDINAL1,
FINSET_1, CARD_1, PBOOLE, NUMBERS, XCMPLX_0, XREAL_0, XXREAL_0, RELAT_1,
FUNCT_1, PARTFUN1, FUNCOP_1, FUNCT_2, BINOP_1;
constructors NUMBERS, XCMPLX_0, XXREAL_0, XREAL_0, CARD_1, WELLORD2, FUNCT_2,
PARTFUN1, FUNCOP_1, FUNCT_4, ENUMSET1, RELSET_1, PBOOLE, ORDINAL1,
SETFAM_1, ZFMISC_1, BINOP_1;
registrations SUBSET_1, ORDINAL1, NUMBERS, XXREAL_0, XREAL_0, CARD_1,
RELSET_1, FUNCT_2, PBOOLE;
requirements REAL, NUMERALS, SUBSET, BOOLE, ARITHM;
definitions SETFAM_1, TARSKI, XBOOLE_0, RELAT_1;
equalities ORDINAL1, XBOOLE_0, CARD_1;
expansions SETFAM_1, ORDINAL1, TARSKI, XBOOLE_0;
theorems AXIOMS, ORDINAL1, XCMPLX_1, XREAL_1, XXREAL_0, TARSKI, ORDINAL2,
XBOOLE_0, CARD_1, FUNCT_2, FUNCT_1, FUNCOP_1, PBOOLE, RELSET_1, RELAT_1,
PARTFUN1, SUBSET_1, NUMBERS, ENUMSET1, XBOOLE_1;
schemes SUBSET_1, ORDINAL2, FUNCT_2, PBOOLE, BINOP_1;
3) To use "1" as your example, you can use "set", "take":
proof
set x=1;
take x;
thus thesis;
end;
Hope this helps.
There are several ways to do this:
Although it is not quite your statement here is an example (It is not quite your statement because you use a "Nat" type).
environ
vocabularies NUMBERS;
constructors ARYTM_0;
notations NUMBERS;
registrations ORDINAL1;
requirements NUMERALS, SUBSET, BOOLE;
begin
1 in NAT;
ex x be object st x = 1;
ex x be object st x in NAT & x = 1;
The 3 statements are verified by mizar as valid, true, demonstrate.
If this is not demonstrated (in the mizar sense), it would indicate the *4 error or even sometimes the *1 error.
In the case of the 3 statements here, the evidence is not explicitly stated. It is contained in the environment because Mizar does not require you to indicate all the steps, some of them are automatic.
It is possible to present in this way, acceptable also to Mizar.
environ
vocabularies NUMBERS;
constructors ARYTM_0;
notations NUMBERS;
registrations ORDINAL1;
requirements NUMERALS, SUBSET, BOOLE;
begin
1 in NAT
proof
thus thesis;
end;
ex x be object st x = 1
proof
thus thesis;
end;
ex x be object st x in NAT & x = 1
proof
thus thesis;
end;
But in this situation, the full expression
proof
thus thesis;
end;
is redundant.
To return to the initial problem, and using the suggestion (user10715283 & user10715216). "can we take an environ that is smaller [...]": yes with a specific tool (clearenv.pl, provide with Mizar-System)
environ
vocabularies NAT_1;
constructors NUMBERS, XCMPLX_0, XREAL_0, BINOP_1;
notations ORDINAL1;
registrations ORDINAL1;
requirements NUMERALS, SUBSET;
begin
theorem Th1:
ex x being Nat st x=1
proof
set x=1;
take x;
thus thesis;
end;
How can one see the exact implementation of an in-built tactic in Coq ? More specifically is there an alternative to Print Ltac <user-defined-tactics> which works for locating the exact definition of in-built Tactics in Coq ?
No, there is no alternative to Print Ltac. In part, this is because the built-in tactics are implemented in OCaml, and the parts they are made of aren't always expressible in terms of more primitive tactics in Ltac (and almost never would such a translation be exact). The only way I know to find the definitions is to go source-diving. If you search for, e.g., "destruct", you will find in plugins/ltac/g_tactic.ml4 the lines
| IDENT "destruct"; icl = induction_clause_list ->
TacAtom (Loc.tag ~loc:!#loc ## TacInductionDestruct(false,false,icl))
which says that destruct gets parsed as the atomic tactic node TacInductionDestruct. Searching for TacInductionDestruct gives an implementation in plugins/ltac/tacinterp.ml:
(* Derived basic tactics *)
| TacInductionDestruct (isrec,ev,(l,el)) ->
(* spiwack: some unknown part of destruct needs the goal to be
prenormalised. *)
Proofview.Goal.nf_enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = project gl in
let sigma,l =
List.fold_left_map begin fun sigma (c,(ipato,ipats),cls) ->
(* TODO: move sigma as a side-effect *)
(* spiwack: the [*p] variants are for printing *)
let cp = c in
let c = interp_destruction_arg ist gl c in
let ipato = interp_intro_pattern_naming_option ist env sigma ipato in
let ipatsp = ipats in
let sigma,ipats = interp_or_and_intro_pattern_option ist env sigma ipats in
let cls = Option.map (interp_clause ist env sigma) cls in
sigma,((c,(ipato,ipats),cls),(cp,(ipato,ipatsp),cls))
end sigma l
in
let l,lp = List.split l in
let sigma,el =
Option.fold_left_map (interp_open_constr_with_bindings ist env) sigma el in
Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(name_atomic ~env
(TacInductionDestruct(isrec,ev,(lp,el)))
(Tactics.induction_destruct isrec ev (l,el)))
end
You can find the implementation of Tactics.induction_destruct in tactics/tactics.ml.
Most primitive tactics start in one of two ways: either there is an entry in g_tactic.ml4 which says how to parse that tactic as an atomic tactic node, or there is a TACTIC EXTEND somewhere, e.g., for revert, we have in plugins/ltac/coretactics.ml4
TACTIC EXTEND revert
[ "revert" ne_hyp_list(hl) ] -> [ Tactics.revert hl ]
END
If the definition is as a node in the Ltac AST, then the place to look is tacinterp.ml, which describes how to interpret those tactics. Either way, you can continue chasing down OCaml definitions to see how tactics are implemented.
I'm trying to prove that following language is not context free:
{a^n b^m a^n b^m : n,m >= 0}
I know that I need to use the pumping lemma. So I have to use w = uvxyz where |vy| > 0 and |xyz| > p (pumping length). I know that I need to show that when pumped a string for each case is outside the language.
I know the cases for when v^i or y^i is contains something and the other is empty but I don't know what to pick for my string.
I need to simplify this Boolean expression with De Morgan's laws.
¬c xor (¬b ∨ c)
Could someone help me?
(accidentally made two accounts, so just responding with this one)
Ive found the best way to visualize a logic formula you do not understand is to make a table for it.
In the case of XOR, it represents One variable or another, but not both. So, lets make a table for A XOR B
A | B | Result
T | T | F *1
T | F | T *2
F | T | T *3
F | F | F *4
To generate the smallest possible result from the above table we can first take the most complex result that takes into account each option. Converting each line into a logical statement is fairly easy.
First, throw out anything that results in a False, Then take those that result in true, and convert them into a logical statement separated by 'OR's. In this case, 1 and 4 are false, and 2 and 3 are true. This means we only need to create logical statements for 2 and 3. I think how to do so would be best explained by example
Lets say X, Y, and Z are our variables, and the table gave us the following rows as true:
T | T | F - X & Y & ¬Z
F | T | F - ¬X & Y & ¬Z
F | F | F - ¬X & ¬Y & ¬Z
then to complete, we simply 'OR' them together
(X & Y & ¬Z) V (¬X & Y & ¬Z) V (¬X & ¬Y & ¬Z)
as you can see, where the variable is true, you put the variable directly in, and where it is false, you put a '¬' before the variable. The statement above basically says...
(True when X=T,Y=T,Z=F: False otherwise) OR (True when X=F,Y=T,Z=F: False otherwise) OR (True when X=F,Y=F,Z=F: False otherwise)
So finally bringing it back to our XOR the table rows are...
*2 A & ¬B
*3 ¬A & B
and are combined to be...
(A & ¬B) V (¬A & B)
So, now that you have an explanation of what to do with xor, you can apply this example to your problem, and come up with a logical statement you can use De Morgan's laws on to simplify.
first you have to split up xor into its basic form.
XOR represents A or B where A != B. If you can do that you should have more luck using demorgans on the whole equation