Checking if the difference between consecutive elements is the same

前端 未结 2 1733
后悔当初
后悔当初 2021-01-24 09:30

I am new to using arithmetic in Prolog.

I’ve done a few small programs, but mostly involving logic. I am trying to implement a function that will return true

2条回答
  •  囚心锁ツ
    2021-01-24 09:45

    Prolog's syntax

    The syntax is a bit off: normally a clause has a head like foo(X, Y, Z), then an arrow (:-), followed by a body. That body normally does not contain any arrows :-. So the second arrow :- makes not much sense.

    Predicates and unification

    Secondly in Prolog predicates have no input or output, a predicate is true or false (well it can also error, or got stuck into an infinite loop, but that is typically behavior we want to avoid). It communicates answers by unifying variables. For example a call sameSeqDiffs([3, 5, 7, 9], X). can succeed by unifying X with 2, and then the predicate - given it is implemented correctly - will return true..

    Inductive definitions

    In order to design a predicate, on typically first aims to come up with an inductive definition: a definition that consists out of one or more base cases, and one or more "recursive" cases (where the predicate is defined by parts of itself).

    For example here we can say:

    (base case) For a list of exactly two elements [X, Y], the predicate sameSeqDiffs([X, Y], D) holds, given D is the difference between Y and X.

    In Prolog this will look like:

    sameSeqDiffs([X, Y], D) :-
        ___.
    

    (with the ___ to be filled in).

    Now for the inductive case we can define a sameSeqDiffs/2 in terms of itself, although not with the same parameters of course. In mathematics, one sometimes defines a function f such that for example f(i) = 2×f(i-1); with for example f(0) = 1 as base. We can in a similar way define an inductive case for sameSeqDiffs/2:

    (inductive case) For a list of more than two elements, all elements in the list have the same difference, given the first two elements have a difference D, and in the list of elements except the first element, all elements have that difference D as well.

    In Prolog this will look like:

    sameSeqDiffs([X, Y, Z|T], D) :-
        ___,
        sameSeqDiffs(___, ___).
    

    Arithmetic in Prolog

    A common mistake people who start programming in Prolog make is they think that, like it is common in many programming languages, Prolog add semantics to certain functors.

    For example one can think that A - 1 will decrement A. For Prolog this is however just -(A, 1), it is not minus, or anything else, just a functor. As a result Prolog will not evaluate such expressions. So if you write X = A - 1, then X is just X = -(A,1).

    Then how can we perform numerical operations? Prolog systems have a predicate is/2, that evaluates the right hand side by attaching semantics to the right hand side. So the is/2 predicate will interpret this (+)/2, (-)/2, etc. functors ((+)/2 as plus, (-)/2 as minus, etc.).

    So we can evaluate an expression like:

    A = 4, is(X, A - 1).
    

    and then X will be set to 3, not 4-1. Prolog also allows to write the is infix, like:

    A = 4, X is A - 1.
    

    Here you will need this to calculate the difference between two elements.

提交回复
热议问题