How to find the source file for an identifier in Coq - coq

I was staring at an error for quite a while before I realized that there's both Rsqrt and sqrt defined somewhere in Coq:
Unable to unify "0 < Rsqrt ?M2352 \/ 0 = Rsqrt ?M2352" with "0 < sqrt r12 \/ 0 = sqrt r12".
Rather than asking specifically how to find where these two specific items (Rsqrt and sqrt) are defined, is there a general way to find the .v file from the standard library in which a name such as sqrt is defined?
BTW, I know Check and Print. But I need to find the relevant source files or documentation to see what lemmas are available about the object.

I am not aware of such a feature, but I think you could use Locate (or sometimes SearchAbout sqrt) to get the full path of the term, and then easily guess the corresponding .v file.

Using Emacs + ProofGeneral, after following the instructions in the Installation notes:
Install coqtags in a standard place or add /coq to your PATH.
NB: You may need to change the path to perl at the top of the file.
Generate a TAGS file for the library by running
coqtags find . -name \*.v -print
in the root directory of the library, $COQTOP/theories.
you can use M-. for going to the .v file where the identifier under the cursor was defined and you can use M-* to go back.

The emacs addon company-coq has this very convenient feature.
https://github.com/cpitclaudel/company-coq

Related

How can I find what file a value is defined in?

When I work on a Coq proof I often want to find which file a definition comes from.
E.g. I had a goal which contains list_norepet (map fst (PTree.elements ta)), and I wanted to find the file that defined list_norepet. Doing Print list_norepet. shows lots of helpful information, but not the file name. Is there any way to get Coq to print that?
You can use Locate to get the full module name. Usually this is enough to find the file, but then you can use Locate File to try to find it:
Locate eq_rect.
(* Constant Coq.Init.Logic.eq_rect *)
Locate File "Init/Logic.v".
(* /Users/tchajed/code/sw/coq-master/theories/Init/Logic.v *)
I say "try to find it" because you do need to know the remappings (with -R) to be able to translate module paths to file paths - for example, Coq's standard library is in theories but is mapped to Coq.

How to make Merlin (OCaml) ignore some lines?

I use Merlin with Emacs to edit OCaml code. It normally works perfectly fine, but I wound the following problem:
I'm need to use a package, built by someone else, that adds to OCaml some keywords not native to the language. Since I use the package to compile the code, compilation works great. On the other hand Merlin goes crazy and thinks that the new keywords are an error. Luckily the new keywords only appear at the beginning of a line, so my code looks something like this:
let square x = x * x;;
let rec fact x =
if x <= 1 then 1 else x * fact (x - 1);;
FOO "This syntax is not standard Ocaml" square fact;;
Where FOO is the new keyword. Merlin will complain and say Unbound constructor FOO. So the question is, can I make Marlin ignore that line? OR can you think of a hack to wrap the syntax in something Merlin won't complain about?
Merlin doesn't and will not (afaik) support arbitrary syntax extensions, but they do have parsing hacks for most commonly used camlp4 extensions like pa_lwt, pa_macro, etc. Also newest merlin versions will skip unknown lines and recover parsing, so that 'go-to-definition' and type throwback work on other parts of the file not modified by syntax extensions.
An alternative, although quite different, but that offers a subset of the functionalities of Merlin (completion and documentation from libraries, navigating around files), is ocp-index.
Ocp-index doesn't interpret or type your current file (it only scans it for opens and the like), so it won't be troubled by arbitrary extensions.

GNU Global and GTAGS can't find class definitions

I'm having trouble getting global to find class/struct definitions.
I can find them with exuberant ctags and with cscope.
All tag files are built from the same source file list.
I configured and built global, et.al., only specifying --prefix.
configure did find exhuberant and is using it.
I've been trying global periodically over the years and it's always had this problem.
Any ideas?
thanks,
davep
I've found out what I did wrong. Maybe this will help someone.
Just because configure finds exuberant ctags does not means that it makes it the default parser. My ex ctags doesn't support --gtags and maybe that's why. The default parser in my case was native/builtin.
The native parser treats .h as C only and does not look for C++ constructs. Oddly, it also does not find structs.
I found 2 fixes:
1) The best, if you have exuberant ctags, is to make it the default. The exuberant default configuration processes .h files properly. If it does not, use method 2. In .globalrc, change
default:\
:tc=native:
to
default:\
:tc=ctags:
2) If you do not have exuberant ctags, edit .globalrc and change the langmap line for the builtin-parser from
builtin-parser:\
:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
to
builtin-parser:\
:langmap=c\:.c,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.h.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
I.e. remove the association of .h with C and associate it with C++.
This may cause problems with C .h files. If so, you may need rename ALL C++ .h files to .hh, .hpp, .hxx, etc, as given in the langmap.
Based on my experience with C++, it looks like most people still use .h for their header files.
Just export this variable and that should pretty much do. From the man page for gtags -
GTAGSFORCECPP
If this variable is set, each file whose suffix is 'h' is treated as a C++ source file.

Determining the mime type of a file

How can I determine the mime-type of a file (in OCaml)?
I am trying to set the language for a GtkSourceView control, but to do that, I need to first determine the language. The only way I can see of doing this is using the mime-type - there is a function that will return the correct language as follows:
GSourceView.source_languages_manager#get_language_from_mime_type : string -> source_language option
I really don't want to hard code the language into my source. If it isn't possible to determine the mime-type in OCaml (and I haven't yet found a way, after searching through the documentation), is there perhaps another way I can determine the source language?
After studying the source code of gedit, which includes this functionality, I have discovered a method in glib which will do this for me. This answer provides an example use of the g_file_info_get_content_type() method. There is also the g_content_type_get_mime_type() method, which is also available in glib.
Unfortunately, there is no wrapping available for these functions yet, which means I may have to generate my own wrapping for them.
Most languages lack this, so I would be very surprised to find it in OCaml. Apache does it with a mime.types file - you can look there for hints. This is the most usual way - a huge table which maps extensions into mimetypes. You can implement it in OCaml easily:
let mimetype_of_extension = function
| "txt" | "log" -> "text/plain"
| "html" | "htm" -> "text/html"
| "zip" | "application/zip"
...
Another way is to look at the file contents, but then you basically need to know about the various file formats.
That said, it does not help you much, since source files of all languages are normally treated as text/plain. They are not distinguishable by mimetype; and thus I really have no idea what your get_language_from_mime_type function does.
However, filename extensions of various source files are more-or-less standardised, so if you know the extension, you will know the language. Getting the extension is as simple as ripping whatever follows the last period from the filename.
let extension_of_filename filename =
let pos = (String.rindex filename '.') + 1 in
let len = String.length filename in
let ext = String.create (len - pos) in
String.blit filename pos ext 0 (len - pos);
ext;;
Well, okay, simple in any language except Brainfuck and OCaml, at least. After that, it's easy - "c" is a C program, as is "h"; "ml" is OCaml; etc.
In GTK, you can wrap the functions you have already found.
It is also not hard to parse /etc/mime.types - it's a simple whitespace-separated file. I believe both Ocsigen and Ocamlnet contain code to do this, but I don't know off-hand if they make it easy to access (e.g. a function exposed by the Ocamlnet netstring library).
This is probably not the best method for determining the type of source code (using /etc/mime.types is best for that IMO), but there are also OCaml bindings for libmagic that you could use.

Emacs recursive project search

I am switching to Emacs from TextMate. One feature of TextMate that I would really like to have in Emacs is the "Find in Project" search box that uses fuzzy matching. Emacs sort of has this with ido, but ido does not search recursively through child directories. It searches only within one directory.
Is there a way to give ido a root directory and to search everything under it?
Update:
The questions below pertain to find-file-in-project.el from MichaƂ Marczyk's answer.
If anything in this message sounds obvious it's because I have used Emacs for less than one week. :-)
As I understand it, project-local-variables lets me define things in a .emacs-project file that I keep in my project root.
How do I point find-file-in-project to my project root?
I am not familiar with regex syntax in Emacs Lisp. The default value for ffip-regexp is:
".*\\.\\(rb\\|js\\|css\\|yml\\|yaml\\|rhtml\\|erb\\|html\\|el\\)"
I presume that I can just switch the extensions to the ones appropriate for my project.
Could you explain the ffip-find-options? From the file:
(defvar ffip-find-options
""
"Extra options to pass to `find' when using find-file-in-project.
Use this to exclude portions of your project: \"-not -regex \\".vendor.\\"\"")
What does this mean exactly and how do I use it to exclude files/directories?
Could you share an example .emacs-project file?
I use M-x rgrep for this. It automatically skips a lot of things you don't want, like .svn directories.
(Updated primarily in order to include actual setup instructions for use with the below mentioned find-file-in-project.el from the RINARI distribution. Original answer left intact; the new bits come after the second horizontal rule.)
Have a look at the TextMate page of the EmacsWiki. The most promising thing they mention is probably this Emacs Lisp script, which provides recursive search under a "project directory" guided by some variables. That file begins with an extensive comments section describing how to use it.
What makes it particularly promising is the following bit:
;; If `ido-mode' is enabled, the menu will use `ido-completing-read'
;; instead of `completing-read'.
Note I haven't used it myself... Though I may very well give it a try now that I've found it! :-)
HTH.
(BTW, that script is part of -- to quote the description from GitHub -- "Rinari Is Not A Rails IDE (it is an Emacs minor mode for Rails)". If you're doing any Rails development, you might want to check out the whole thing.)
Before proceeding any further, configure ido.el. Seriously, it's a must-have on its own and it will improve your experience with find-file-in-project. See this screencast by Stuart Halloway (which I've already mentioned in a comment on this answer) to learn why you need to use it. Also, Stu demonstrates how flexible ido is by emulating TextMate's project-scoped file-finding facility in his own way; if his function suits your needs, read no further.
Ok, so here's how to set up RINARI's find-file-in-project.el:
Obtain find-file-in-project.el and project-local-variables.el from the RINARI distribution and put someplace where Emacs can find them (which means in one of the directories in the load-path variable; you can use (add-to-list 'load-path "/path/to/some/directory") to add new directories to it).
Add (require 'find-file-in-project) to your .emacs file. Also add the following to have the C-x C-M-f sequence bring up the find-file-in-project prompt: (global-set-key (kbd "C-x C-M-f") 'find-file-in-project).
Create a file called .emacs-project in your projects root directory. At a minimum it should contain something like this: (setl ffip-regexp ".*\\.\\(clj\\|py\\)$"). This will make it so that only files whose names and in clj or py will be searched for; please adjust the regex to match your needs. (Note that this regular expression will be passed to the Unix find utility and should use find's preferred regular expression syntax. You still have to double every backslash in regexes as is usual in Emacs; whether you also have to put backslashes before parens / pipes (|) if you want to use their 'magic' regex meaning depends on your find's expectations. The example given above works for me on an Ubuntu box. Look up additional info on regexes in case of doubt.) (Note: this paragraph has been revised in the last edit to fix some confusion w.r.t. regular expression syntax.)
C-x C-M-f away.
There's a number of possible customisations; in particular, you can use (setl ffip-find-options "...") to pass additional options to the Unix find command, which is what find-file-in-project.el calls out to under the hood.
If things appear not to work, please check and double check your spelling -- I did something like (setl ffip-regex ...) once (note the lack of the final 'p' in the variable name) and were initially quite puzzled to discover that no files were being found.
Surprised nobody mentioned https://github.com/defunkt/textmate.el (now gotta make it work on Windows...)
eproject has eproject-grep, which does exactly what you want.
With the right project definition, it will only search project files; it will ignore version control, build artifacts, generated files, whatever. The only downside is that it requires a grep command on your system; this dependency will be eliminated soon.
You can get the effect you want by using GNU Global or IDUtils. They are not Emacs specific, but they has Emacs scripts that integrate that effect. (I don't know too much about them myself.)
You could also opt to use CEDET and the EDE project system. EDE is probably a bit heavy weight, but it has a way to just mark the top of a project. If you also keep GNU Global or IDUtils index files with your project, EDE can use it to find a file by name anywhere, or you can use `semantic-symref' to find references to symbols in your source files. CEDET is at http://cedet.sf.net
For pure, unadulterated speed, I highly recommend a combination of the command-line tool The Silver Searcher (a.k.a. 'ag') with ag.el. The ag-project interactive function will make an educated guess of your project root if you are using git, hg or svn and search the entire project.
FileCache may also be an option. However you would need to add your project directory manually with file-cache-add-directory-recursively.
See these links for info about how Icicles can help here:
find files anywhere, matching any parts of their name (including directory parts)
projects: create, organize, manage, search them
Icicles completion matching can be substring, regexp, fuzzy (various kinds), or combinations of these. You can also combine simple patterns, intersecting the matches or complementing (subtracting) a subset of them