使用本地模块时 Mercury "undefined reference"编译错误

标签 mercury

我有一个模块导出 nat/1 来测试/生成自然数:

:- module nat.

:- interface.

:- import_module int.

:- pred nat(int).
:- mode nat(in) is det.
:- mode nat(out) is multi.

:- implementation.

:- pragma promise_pure(nat/1).
nat(_::in).
nat(0::out).
nat(X::out) :- nat(Y), X = Y + 1.

和同一目录中的主模块来试用:

:- module main.

:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is cc_multi.

:- implementation.
:- import_module nat.

main(!IO) :- nat(X), print(X, !IO).

我运行 mmc --make-int nat.m 成功生成了接口(interface)文件,但是当我运行 mmc main.m 时出现以下错误:

/usr/bin/ld: main.o: in function `<predicate 'main'/2 mode 0>':
main.c:(.text+0x45): undefined reference to `<predicate 'nat.nat'/1 mode 1>'
collect2: error: ld returned 1 exit status

我在 x86_64-pc-linux-gnu 上使用 MMC 版本 20.06.1

我是否遗漏了一些明显的东西?代码改进也非常受欢迎。

最佳答案

在“mmc --make-int nat.m”之后,你需要运行的命令不是“mmc main.m”, 但是“mmc main.m nat.m”。前者编译main.m,后者还编译nat.m。两者都尝试从生成的结果构建可执行文件 目标文件,但前者会失败,因为“nat”谓词的定义将在它不生成的目标文件中。

一般来说,与其尝试手动管理接口(interface)文件、目标文件和可执行文件的创建,不如使用自动化工具更容易 构建系统:mmake 脚本或 mmc --make。

至于代码改进,我建议将 io__state 替换为简单的 io,这样会短很多。我们添加了“io”作为“state”的同义词 专门输入 io.m 以使其成为可能。

关于使用本地模块时 Mercury "undefined reference"编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66944992/

相关文章:

mercury - 如何检查变量是否在 Mercury 中实例化

prolog - 还有什么更有趣或更强大的功能: curry , Mercurial 或Lambda-序言?

functional-programming - 什么是 "strongly moded"编程语言?

types - 类型为 Mercury 等逻辑编程语言带来什么好处?

list - 如何为导入或输出列表的谓词声明 pred?

mercury - 表示任意二进制数据的良好数据类型是什么?

haskell - 除了 Monads 之外,还有哪些其他方式可以在纯函数式语言中处理状态?

rust - Rust 的所有权语义如何与 Clean 和 Mercury 中发现的唯一性类型相关?

pattern-matching - Mercury:确定性和模式匹配