如何在prolog中创建全局变量

Fri*_*ike 5 variables global list prolog reusability

我有一个列表,我创建如下:

tab([(top,left),(top,middle),(top,right),(center,left),(center,middle),
     (center,right),(bottom,left),(bottom,middle),(bottom,right)]).
Run Code Online (Sandbox Code Playgroud)

我希望创建一个全局变量AllPosition,它是一个选项卡.所以我做了以下事情:

tab(AllPos).
Run Code Online (Sandbox Code Playgroud)

这是正确的吗?

然后我必须遵循问题:我有一个函数,在选项卡中接收其中一个.我希望删除.所以我这样做了:

place(Line, Column, Tab) :-
AllPos \== [_,_] /*while AllPos isn't empty - not sur if this is done this way*/ -> (member((Line,Column), AllPos) -> (erase(AllPos, (Line,Column), AllPos)).
Run Code Online (Sandbox Code Playgroud)

erase(List, Element, NewList)从List 中删除元素Element并创建一个新列表NewList等于List但没有Element.这两个函数membererase正在工作.

事情是......你可能已经注意到我AllPos到处都用.这是因为我想,我想修改它,以便我可以在以后使用它(在从中移除一些元素之后),在另一个函数中.我的逻辑是对的吗?我能在另一个函数中使用修改过的AllPos吗?谢谢

Yet*_*eti 5

在 SWI-Prolog 中,您可以使用:b_setval(name, value)b_getval(name, value). 如果您不希望在回溯的情况下更改值,您可以使用:nb_setval(name, value)和使它们成为实际的全局变量nb_getval(name, value)

因此,例如,如果您有一个程序并且您想检查它通过某个路径的频率,您可以使用:

recursive(100).
recursive(X) :- add, Y is X + 1, recursive(Y).

add :- nb_getval(counter, C), CNew is C + 1, nb_setval(counter, CNew).

testRecursion
:-
    % Set counter to zero
    nb_setval(counter, 0),

    % Run some code with 'add'
    recursive(0), !,

    % Print the results
    nb_getval(counter, CounterValue),
    write('Steps: '), writeln(CounterValue).
Run Code Online (Sandbox Code Playgroud)

这对于一些实验案例来说是好的,但通常你会想要避免 Prolog 中的全局变量,因为 Prolog 意味着逻辑编程。


Ian*_*son 1

简而言之:不,你的逻辑不正确。您的代码存在各种小问题和错误,但更大的问题是基本前提。听起来你似乎以错误的方式思考这个问题。一般来说,如果您尝试更新 Prolog 程序中的全局状态,您需要重新考虑您的设计。状态通常由谓词的参数携带,因此我希望将 current 集合作为参数传入,而不是AllTabs在 的主体中统一。如果您确实想更新程序的全局状态,那么您需要查看和谓词。place/4Tabsassertretract

一些具体点:

tab(AllPos).
Run Code Online (Sandbox Code Playgroud)

这声明了一个谓词,其头部有一个未绑定的变量。它或多或少是没有意义的(你可以读到“某件事确实如此tab,但我们没有关于它的真实情况的信息”)。

AllPos \== [_,_]
Run Code Online (Sandbox Code Playgroud)

的这种使用与 的AllPos作用域不同tab/1,因此除了在变量名中共享相同的字符序列之外, 的两种使用AllPos完全没有关系。