Coq:使用子目录管理项目中的LoadPath

时间:2015-08-05 11:29:59

标签: coq

我有一个Coq项目,其库被组织到子目录中,如:

…/MyProj/Auxiliary/Aux.v
…/MyProj/Main/Main.v  (imports Auxiliary/Aux.v)

当我编译文件时,我希望从工作目录MyProj(通过makefile)这样做。但我也想使用Proof General / Coqtop来处理文件,在这种情况下,工作目录默认是文件所在的目录。

但这意味着两个上下文之间的LoadPath是不同的,因此库导入所需的逻辑路径是不同的。 如何设置coqc调用,LoadPath和导入声明,以便它们在两种情况下都能正常工作?

我尝试过的每种方法都出错了。例如,如果我通过调用

编译Aux.v
coqc -R "." "MyProj" Auxiliary/Aux.v

并将其导入Main.v

Require Import MyProj.Auxiliary.Aux.

然后当我使用

编译Main.v时,这是有效的
coqc -R "." "MyProj" Main/Main.v

但Coqtop失败,Error: Cannot find library MyProj.Auxiliary.Aux in loadpath。另一方面,如果在Require Import我添加

之前
Add LoadPath ".." as MyProj.

然后这适用于Coqtop,但在coqc -R "." "MyProj" Main/Main.v下使用

失败
Error: The file […]/MyProj/Auxiliary/Aux.vo contains library

MyProj.Auxiliary.Aux而不是库MyProj.MyProj.Auxiliary.Aux

我正在寻找一种对于与协作者共享的库(并希望最终与用户共享)的强大解决方案,因此特别是它不能使用绝对文件路径。我现在发现的最好的方法是在Proof General调用Coqtop时添加emacs局部变量来设置LoadPath:

((coq-mode . ((coq-prog-args . ("-R" ".." "MyProj" "-emacs")))))

但是这个(a)似乎有点hacky,并且(b)仅适用于Proof General,而不适用于Coqide或普通的Coqtop。有更好的解决方案吗?

3 个答案:

答案 0 :(得分:5)

请允许我通过建议蒂亚戈暗示的替代流程来支持你的问题。

假设您的项目树看起来像这样:

MyProj/Auxiliary/Aux.v
MyProj/Main/Main.v

MyProj中,写一个列出所有Coq文件的_CoqProject文件

-R . ProjectName
Auxiliary/Aux.v
Main/Main.v

当您打开其中一个Coq文件时,emacs将查找_CoqProject并执行正确的操作(tm)。

如Tiago所示,coq_makefile也会免费为您提供Makefile。

答案 1 :(得分:4)

我知道您明确要求提供适用于不同平台的功能,但已经有一个特定于Proof-General的解决方案,而不是您拥有的解决方案。名为has a special variable的证明coq-load-path,您可以使用本地变量进行设置,就像您对coq-prog-args所做的那样。优点是您不必担心需要传递给coqtop的任何其他参数(例如示例中的-emacs)。因此,您的.dir-locals.el文件可能有这样一行:

((coq-mode . ((coq-load-path . ((".." "MyProj"))))))

不幸的是,我不知道任何可以跨平台工作的东西,虽然我很确定必须存在特定于CoqIDE的东西。如果是这种情况,也许你可以设置一个脚本来保持这些配置文件在不同平台上的更新?

答案 2 :(得分:3)

如果您使用#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package File; use Moose; has '_text' => (is => 'rw', isa => 'Str', required => 1); sub text { my ($self) = @_; tie my $text, 'FileText', $self; return $text; } } { package FileText; use Tie::Scalar; sub TIESCALAR { my ($class, $obj) = @_; return bless \$obj, $class; } sub FETCH { my ($self) = @_; return $$self->_text(); } sub STORE { die "READ ONLY"; } } my $file = 'File'->new('_text' => 'hello'); my $text = $file->text(); say $text; $file->_text('goodbye'); say $text; ,则可以在系统中安装库。

没有OPAM

初始化您的项目:

coq_makefile

与其他项目共享您的图书馆:

coq_makefile -f _CoqProject -o Makefile

使用OPAM

假设您已安装OPAM,您可以使用make install 来帮助您处理依赖关系。

设置项目:

coq-shell

更新库时,您应该:

coq_shell_url="https://raw.githubusercontent.com/gares/opam-coq-shell/master/src/opam-coq"
curl -s "${coq_shell_url}" | bash /dev/stdin init 8.4 # Install Coq and its dependencies
eval `opam config env --switch=coq-shell-8.4`         # Setup the environment
coq_makefile -f _CoqProject -o Makefile               # Generates the makefile
opam pin add coq:YOURLIBRARY .                        # Add your library to OPAM

以下是使用OPAM方法的项目示例:

https://bitbucket.org/cogumbreiro/aniceto-coq/src