在 SWI-Prolog 中填写列表 [英] Fill list in SWI-Prolog

查看:19
本文介绍了在 SWI-Prolog 中填写列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用数字 1、2、3、...、N 填充给定长度 N 的列表.

I am trying to fill a list of given length N with numbers 1,2,3,...,N.

我认为可以这样做:

create_list(N,L) :-
    length(L,N),
    forall(between(1,N,X), nth1(X,L,X)).

但是,这似乎不起作用.谁能说我做错了什么?

However, this does not seem to work. Can anyone say what I am doing wrong?

推荐答案

首先:使用 !

First things first: Use clpfd!

:- use_module(library(clpfd)).

在下面我介绍 zs_between_and/3,它(与我之前的答案相比)提供了更多功能.

In the following I present zs_between_and/3, which (in comparison to my previous answer) offers some more features.

首先,让我们先定义一些辅助谓词!

For a start, let's define some auxiliary predicates first!

equidistant_stride([]    ,_).
equidistant_stride([Z|Zs],D) :-
   equidistant_prev_stride(Zs,Z,D).

equidistant_prev_stride([]     ,_ ,_).     % internal predicate
equidistant_prev_stride([Z1|Zs],Z0,D) :-
   Z1 #= Z0+D,
   equidistant_prev_stride(Zs,Z1,D).

让我们运行几个查询来获取 equidistant_stride/2 的图片:

Let's run a few queries to get a picture of equidistant_stride/2:

?- Zs = [_,_,_], equidistant_stride(Zs,D).
Zs = [_A,_B,_C], _A+D#=_B, _B+D#=_C.

?- Zs = [1,_,_], equidistant_stride(Zs,D).
Zs = [1,_B,_C], _B+D#=_C, 1+D#=_B.

?- Zs = [1,_,_], equidistant_stride(Zs,10).
Zs = [1,11,21].

到目前为止,一切都很好...继续实际的填充列表"谓词zs_between_and/3:

So far, so good... moving on to the actual "fill list" predicate zs_between_and/3:

zs_between_and([Z0|Zs],Z0,Z1) :-
   Step in -1..1,
   Z0 #= Z1 #<==> Step #=  0,
   Z0 #< Z1 #<==> Step #=  1,
   Z0 #> Z1 #<==> Step #= -1,
   N #= abs(Z1-Z0),    
   (  fd_size(N,sup)
   -> true
   ;  labeling([enum,up],[N])
   ),
   length(Zs,N),
   labeling([enum,down],[Step]),
   equidistant_prev_stride(Zs,Z0,Step).

有点巴洛克风格,我必须承认...

A bit baroque, I must confess...

让我们看看获得了哪些功能——与我的上一个答案相比!

Let's see what features were gained---in comparison to my previous answer!

?- zs_between_and(Zs,1,4).      % ascending  consecutive integers
Zs = [1,2,3,4].                 % (succeeds deterministically)

?- zs_between_and(Zs,3,1).      % descending consecutive integers (NEW)
Zs = [3,2,1].                   % (succeeds deterministically)

?- zs_between_and(Zs,L,10).     % enumerates fairly
  L = 10, Zs =       [10]       % both ascending and descenting (NEW)
; L =  9, Zs =     [9,10]
; L = 11, Zs =    [11,10]
; L =  8, Zs =   [8,9,10]
; L = 12, Zs = [12,11,10]
; L =  7, Zs = [7,8,9,10]
...

?- L in 1..3, zs_between_and(Zs,L,6).
  L = 3, Zs =     [3,4,5,6]
; L = 2, Zs =   [2,3,4,5,6]
; L = 1, Zs = [1,2,3,4,5,6].

想要更多?我们开始吧!

Want some more? Here we go!

?- zs_between_and([1,2,3],From,To).
  From = 1, To = 3
; false.

?- zs_between_and([A,2,C],From,To).
  A = 1, From = 1, C = 3, To = 3    % ascending
; A = 3, From = 3, C = 1, To = 1.   % descending

这篇关于在 SWI-Prolog 中填写列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆