You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从命令行带参数调用Prolog谓词并输出求解结果

在命令行调用SWI-Prolog谓词并输出结果

我实际应用的谓词比示例复杂,但示例涵盖了我需要处理的各类特性。尝试用initialization和SWI-Prolog的部分属性实现需求未成功,也未找到合适的文档。

假设代码存储在app.pl文件中:

t([X1, X2|[]], X3, Y) :- 
    Y1 is X1 + X2, 
    Y2 is 2 * X3, 
    Y = [Y1, Y2]
.

我希望实现类似这样的命令调用:

swipl -f app.pl -c 't([1,2],3,Y)'

并在标准输出得到结果Y = [3,6],方便后续处理。我不想引入main过程,但也想了解该方式的实现。最终目标是从Python或Bash中调用单个谓词做测试——简单来说,就是在Linux命令行模拟SWI-Prolog REPL里的单次调用。

另外我发现pyswip这个Python包维护状态不错,可能能实现需求,但还是更关注命令行方案,因为适用场景更广。


命令行解决方案(无需main过程)

可以用SWI-Prolog的-g(指定启动目标)和-t(指定终止动作)选项实现,无需添加main谓词:

swipl -f app.pl -g "t([1,2],3,Y), write_term(Y = Y, [quoted(true), portray(true)]), nl" -t halt

各参数作用:

  • -f app.pl:加载指定的Prolog文件
  • -g <目标>:启动时执行指定逻辑——先调用t/3,再用write_term输出和REPL格式一致的结果
  • -t halt:目标执行完成后立即退出Prolog环境,避免进入交互模式

如果谓词有多个解,可用findall收集所有结果:

swipl -f app.pl -g "findall(Y, t([1,2],3,Y), Results), writeln(Results)" -t halt

引入main过程的实现方式

若愿意添加main谓词,可在app.pl末尾补充:

main :-
    current_prolog_flag(argv, Argv),
    maplist(atom_term, Argv, Args),
    Args = [X1,X2,X3],
    t([X1,X2], X3, Y),
    writeln(Y = Y),
    halt.
main :- halt(1).

调用命令:

swipl -f app.pl -g main -- 1 2 3

其中--用来分隔Prolog自身参数和传递给main的自定义参数,current_prolog_flag(argv, Argv)会获取--后的参数,转成Prolog项后调用t/3。

Python调用方案(pyswip)

用pyswip可直接在Python代码中调用Prolog谓词,示例:

from pyswip import Prolog

prolog = Prolog()
prolog.consult("app.pl")

result = list(prolog.query("t([1,2],3,Y)"))
print(f"Y = {result[0]['Y']}")  # 输出 Y = [3,6]

该方式适合Python项目直接集成,无需额外解析命令行输出。


内容的提问来源于stack exchange,提问作者Raffael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:25:11