【问题标题】:Implementation of Stack in SWI-PrologSWI-Prolog中堆栈的实现
【发布时间】:2020-05-09 02:13:35
【问题描述】:

所以我必须实现一个 ADT,在本例中是 SWI-Prolog 中的一个堆栈。我需要帮助,因为我是这种编程语言的新手,不知道如何开始。

这开始是在 python(3) 中的一个实现,我在其中定义了一个类并添加了要使用的函数(push、is_empty?、pop、peak)。但是现在,我需要在 prolog 中做一些类似的事情。

我访问过其他一些与我类似的stackoverflow问题,但我仍然无能为力。

我认为这不仅仅是在SWI-Prolog中定义一个列表,请帮助。

【问题讨论】:

    标签: prolog abstract-data-type


    【解决方案1】:

    既然你提到了 ADT,我将使用 Logtalk(你可以在大多数 Prolog 系统上运行)首先定义一个堆栈协议/接口:

    :- protocol(stack_protocol).
    
        :- public(new/1).
        :- mode(new(--stack), one).
        :- info(new/1, [
            comment is 'Creates a new empty stack.',
            argnames is ['Stack']
        ]).
    
        :- public(empty/1).
        :- mode(empty(@stack), one).
        :- info(empty/1, [
            comment is 'True if the stack is empty.',
            argnames is ['Stack']
        ]).
    
        :- public(top/2).
        :- mode(top(?stack, ?element), zero_or_one).
        :- info(top/2, [
            comment is 'True if Top is the top element of the stack.',
            argnames is ['Stack', 'Top']
        ]).
    
        :- public(push/3).
        :- mode(push(?stack, ?element, ?stack), zero_or_one).
        :- info(push/3, [
            comment is 'Adds an element to the stack.',
            argnames is ['Stack0', 'Element', 'Stack']
        ]).
    
        :- public(pop/3).
        :- mode(pop(?stack, ?element, ?stack), zero_or_one).
        :- info(pop/3, [
            comment is 'Removes an element from the stack.',
            argnames is ['Stack0', 'Element', 'Stack']
        ]).
    
    :- end_protocol.
    

    我们现在可以定义堆栈 ADT 的实现。显而易见的选择就是使用列表:

    :- object(stack,
        implements(stack_protocol)).
    
        new([]).
    
        empty(Stack) :-
            Stack == [].
    
        top([Top| _], Top).
    
        push(Stack, Element, [Element| Stack]).
    
        pop([Element| Stack], Element, Stack).
    
    :- end_object.
    

    假设在stack.lgt 源文件中定义了协议和对象,示例调用将是:

    | ?- {stack}.
    ...
    % (0 warnings)
    
    (4 ms) yes
    | ?- stack::(
             new(S0),
             push(S0, 1, S1),
             push(S1, 2, S2),
             push(S2, 3, S3),
             top(S3, T),
             pop(S3, E, S)
         ).
    
    E = 3
    S = [2,1]
    S0 = []
    S1 = [1]
    S2 = [2,1]
    S3 = [3,2,1]
    T = 3
    
    yes
    

    是否值得定义协议?当需要几种不同的实现(例如字典或随机数生成器)时,协议特别有用。但是,在这种情况下,列表是实现堆栈的自然候选者,以至于定义协议的用处主要在于它的教育价值。在大多数情况下,当需要堆栈时,程序员只需直接使用列表即可。

    【讨论】:

      猜你喜欢
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      相关资源
      最近更新 更多