【问题标题】:Open .pl file and close current one in SWI - Prolog在 SWI 中打开 .pl 文件并关闭当前文件 - Prolog
【发布时间】:2013-11-07 09:57:08
【问题描述】:

我在 SWI-Prolog 中为文本冒险游戏创建了两个不同的 .pl 文件。他们是两个不同的任务。

有什么办法在第一个任务结束时打开第二个任务(第二个.pl文件)并关闭第一个?

另外,还有什么更好的方法:为我的 N 个任务创建 N 个 .pl 文件还是一个大的 .pl 文件?

【问题讨论】:

    标签: prolog swi-prolog


    【解决方案1】:

    我同意您最初的想法,即最好使用多个模块文件。我想使用不同文件的一个原因是为事实和规则提供不同的名称空间,这些事实和规则最好使用相同的谓词来表达。例如,Description 在任务 1 中的 room(1, Description) 与在任务 2 中的不同。

    实现这一点的一种方法是在每个不同的任务模块中访问私有的、非导出的谓词。 (旁白:我在某处读到 Jan Wielemaker 对这种做法的警告,但我不知道为什么,也不确定我确实读过这篇文章。)

    这是我总结的一个可能的模式:

    给定一个主文件“game.pl”,包含以下程序,

    :- use_module([mission1, mission2]).
    
    start :-
        playing(mission1).
    
    playing(CurrentMission) :-
        read(Command),
        command(CurrentMission, Command),
        playing(CurrentMission).
    
    command(_, quit) :- write('Good bye.'), halt.
    command(CurrentMission, Command) :-
        ( current_predicate(CurrentMission:Command/_)  % Makes sure Command is defined in the module.
        ->  CurrentMission:Command                     % Call Command in the current mission-module
        ;   write('You can\'t do that.'),              % In case Command isn't defined in the mission.
        ).
    

    还有这些任务模块,

    在文件“mission1.pl”中:

    :- module(mission1, []).
    
    turn_left :-
        write('You see a left-over turnip').
    
    eat_turnip :-
        write('You are transported to mission2'),
        playing(mission2).                         % Return to the prompt in `game` module, but with the next module.
    

    在文件“mission2.pl”中:

    :- module(mission2, []).
    
    turn_left :-
        write('You see a left-leaning turncoat.').
    

    那我们就可以玩这个烂游戏了:

    ?- start.
    |: turn_left.
    You see a left-over turnip
    |: eat_turnip.
    You are transported to mission2
    |: turn_left.
    You see a left-leaning turncoat.
    |: quit
    |: .
    Good bye.
    

    由于多种原因,该计划的细节存在问题。例如,我希望我们可能宁愿有一个单一的谓词来处理通过地点导航,并且我们宁愿描述对我们任务中的不同命令做出反应的地点和对象,而不是考虑每个可能的命令。但是使用不同文件的一般原则仍然有效。

    另一种方法是使用consult/1unload_file/1 加载和卸载模块,在这种情况下,您应该能够使用它们的公共导出谓词,而不是按模块调用它们。这些和相关谓词的文档可以在"Loading Prolog Source Files"部分的手册中找到。

    【讨论】:

    • module 是做什么的?
    • 我不想创建一个大文件的主要原因是因为它会是 10000 行代码,因此很难阅读/编辑/无论如何
    • @NickShev 啊! module/2 将当前文件声明为一个模块!第二个参数(在这种情况下为空列表)是您放置导出谓词的位置。例如,如果您使用我提到的其他方法(conulst/1unload_file/1),那么您可能想要导出,例如,每个任务中的地点::- module(mission1, [place/3])(假设每个地点由一个 3 元谓词,例如,可能是 place(,,) )。文档 SWI 模块是 here
    • 所以你建议创建一个大文件?
    • @NickShev 不——抱歉:有一些误会。我使用模块系统,以便每个任务都保存在自己的模块文件中(如上所述)。将文件声明为模块的原因是:您可以将谓词引用到特定模块(如我的回答中所示)。例如,如果您最终在游戏中使用了动态谓词,您可以通过使用 mission1:assertz(completed) 来断言在一个任务中为真但在另一个任务中为假的事实。那么mission1:completed 为真,但mission2:completed 仍可能为假。
    猜你喜欢
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    相关资源
    最近更新 更多