Prolog:将数字拆分为递增整数的序列

2023-12-05

在大学里做了一些 Prolog 并做了一些练习之后,我决定进一步深入,尽管我必须承认我不太了解递归,我明白了概念和想法,但如何编码它对我来说仍然是一个问题。所以这就是为什么我很好奇是否有人知道如何帮助解决这个问题。

这个想法有一个数字,例如45、检查是否可以创建一个从1开始的列表,将n+1放入列表中,以及列表的总和是否与给定的数字相同。

所以对于 45 岁来说,[1,2,3,4,5,6,7,8,9]是正确的。

到目前为止,我尝试查看[sum_list/2][1]在 Prolog 本身中实现,但仅检查列表是否与其后面的数字相同。

所以给定一个谓词lijstSom(L,S)(荷兰语为listSum),给定

?- lijstSom(L, 45)
L = [1,2,3,4,5,6,7,8,9];
False

我的想法是这样的,例如,如果 S = 45,执行数字的步骤(增加 1)并减去 S,如果余数为 0,则返回列表,否则返回false.

但为此你需要计数器,我发现在递归中很难掌握这一点。

EDIT:

递归的步骤。

基本情况空列表,0(计数器nr,即负S),45(S,余数)

[1], 1, 44

[1,2], 2, 42

[1,2,3], 3, 39

我不知道如何阅读这个例子

?- lijstSom(L, 45)

L = [1,2,3,4,5,6,7,8,9],

False

...但是想想谓词lijstSom(List, Sum)将某些整数列表与其总和相关联,而不是计算整数列表的总和。为什么要“某些清单”?因为我们有这样的约束:整数列表中的整数必须从 1 开始以 1 为增量单调递增。

因此,您可以向 Prolog 处理器询问以下问题:

“说一下第一个参数之间的关系lijstSom/2和第二个参数lijstSom/2(假设第一个是单调递增整数的列表,第二个是整数):

lijstSom([1,2,3], Sum)

... 应该返回真(因为是的,至少有一个解决方案)并且give Sum = 6(因为它也构建了解决方案......我们是某个角落建构主义 here.

lijstSom(L, 6)

... 应该返回真(因为是的,至少有一个解决方案)并且给出解决方案 [1,2,3].

lijstSom([1,2,3], 6)

... 应该返回真(因为就是这样,[1,2,3]总和为 6);不需要更多信息。

lijstSom(L, S)

...应该是无限级数true和成对的解决方案(“生成解决方案”)。

L = [1], S = 1;
L = [1,2], S = 3;
L = [1,2,3], S = 6;
...

lijstSom([1,2,3], 7)

...应该返回错误(“失败”)因为 7 不存在关系lijstSom with [1,2,3]如 7 =/= 1+2+3。

人们甚至可能希望 Prolog 处理器说一些有趣的事情:

lijstSom([1,2,X], 6)

X = 3

or even

lijstSom([1,2,X], S)

X = 3
S = 6

实际上,lijstSom/2尽可能接近数学上的神奇,也就是说:

  • 可以不受限制地访问漂浮在柏拉图数学空间中某处的列表求和关系的完整表格。
  • 能够以少于无限的步骤找到正确的条目。
  • 并输出它。

当然,出于显着的实际原因,我们仅限于低指数和有限数量的可区分符号的多项式算法。糟透了!

所以,首先定义lijstSom(L,S)使用归纳定义:

  • lijstSom([a list with final value N],S)... 为真,如果 ...lijstSom([a list],S-N and
  • lijstSom([],0)因为空列表的总和为 0。

这很好,因为它给出了最终将任意长度的列表减少到大小为 0 的列表的方法,同时保持完整的知识其总和!

Prolog 不擅长处理列表的尾部,但擅长处理头部,所以我们作弊并更改我们的定义lijstSom/2说明列表是按相反顺序给出的:

lijstSom([3,2,1], 6)

现在一些代码。

#=是“包含等于”运算符图书馆(clpfd)。要使用它,我们需要发出use_module(library(clpfd)).先指挥。

lijstSom([],0).
lijstSom([K|Rest],N) :- lijstSom([Rest],T), T+K #= N.

以上遵循数学要求lijstSom并允许 Prolog 处理器执行其计算:在第二个子句中,它可以根据大小为 A-1 的列表的值计算大小为 A 的列表的值,“落下”列表长度始终减小的楼梯,直到它达到了终止情况lijstSom([],0)..

但我们还没有提到单调递减 1 列表。 让我们更准确地说:

lijstSom([],0) :- !.
lijstSom([1],1) :- ! .
lijstSom([K,V|Rest],N) :- K #= V+1, T+K #= N, lijstSom([V|Rest],T).

Better!

(我们还添加了“!”来告诉 Prolog 处理器不要寻找超过这一点的替代解决方案,因为我们对算法的了解比以往任何时候都多。此外,第三行有效,但只是因为我做对了运行下面的测试并让它们通过后。)

如果检查失败,Prolog 处理器将显示“false”——对于您的输入没有解决方案。这正是我们想要的。

但这有效吗?我们在这台卓越的物理机器的“数学性”方面能走多远?

Load library(clpfd)用于约束和使用library(plunit)对于单元测试:

将其放入文件中x.pl你可以加载[x] alias consult('x')或重新加载make在 Prolog REPL 上:

:- use_module(library(clpfd)).

lijstSom([],0) :- 
   format("Hit case ([],0)\n"),!.
lijstSom([1],1) :-
   format("Hit case ([1],1)\n"),!.
lijstSom([K,V|Rest],N) :- 
   format("Called with K=~w, V=~w, Rest=~w, N=~w\n", [K,V,Rest,N]),
   K #= V+1, 
   T+K #= N,   
   T #> 0, V #> 0, % needed to avoid infinite descent
   lijstSom([V|Rest],T).

:- begin_tests(listsom).

test("0 verify") :- lijstSom([],0).
test("1 verify") :- lijstSom([1],1).
test("3 verify") :- lijstSom([2,1],3).
test("6 verify") :- lijstSom([3,2,1],6).

test("0 construct") :- lijstSom(L,0) , L = [].
test("1 construct") :- lijstSom(L,1) , L = [1].
test("3 construct") :- lijstSom(L,3) , L = [2,1].
test("6 construct") :- lijstSom(L,6) , L = [3,2,1]. 

test("0 sum") :- lijstSom([],S) , S = 0.
test("1 sum") :- lijstSom([1],S) , S = 1.
test("3 sum") :- lijstSom([2,1],S) , S = 3.
test("6 sum") :- lijstSom([3,2,1],S) , S = 6.

test("1 partial") :- lijstSom([X],1) , X = 1. 
test("3 partial") :- lijstSom([X,1],3) , X = 2. 
test("6 partial") :- lijstSom([X,2,1],6) , X = 3. 

test("1 extreme partial") :- lijstSom([X],S) , X = 1, S = 1.
test("3 extreme partial") :- lijstSom([X,1],S) , X = 2, S = 3.
test("6 extreme partial") :- lijstSom([X,2,1],S) , X = 3, S = 6.

test("6 partial list") :- lijstSom([X|L],6) , X = 3, L = [2,1]. 

% Important to test the NOPES

test("bad list", fail) :- lijstSom([3,1],_).
test("bad sum", fail) :- lijstSom([3,2,1],5).
test("reversed list", fail) :- lijstSom([1,2,3],6).
test("infinite descent from 2", fail) :- lijstSom(_,2).
test("infinite descent from 9", fail) :- lijstSom(_,9).

:- end_tests(listsom).

Then

?- run_tests(listsom).
% PL-Unit: listsom ...................... done
% All 22 tests passed

什么会Dijkstra说?是的,他可能会抱怨一些事情。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Prolog:将数字拆分为递增整数的序列 的相关文章

随机推荐

  • Android:以编程方式更改按钮背景

    我有这个颜色资源文件
  • matplotlib 中使用 Latex 的无衬线数学

    以下脚本 import matplotlib matplotlib use Agg import matplotlib pyplot as mpl mpl rc font family sans serif mpl rc text uset
  • 300 000 000 000 的质因数?

    我需要找出超过3000亿的素因数 我有一个函数正在添加到它们的列表中 非常缓慢 现在它已经运行了大约一个小时 我认为它还有相当长的距离要静止 我这样做是完全错误的还是这是预期的 编辑 我试图找到数字 600851475143 的最大质因数
  • Jquery 移动后退按钮

    我有一个应用程序 在其中以编程方式向页面添加后退按钮 这意味着第一页上不会有后退按钮 然而 应用程序本身有多种进入应用程序的方式 换句话说 我可以收到通知 并且在触摸该通知时 它会转到应用程序中的特定区域 该区域不会有返回主页的后退按钮 如
  • 动态改变UITable单元格高度?

    我需要根据内容大小 长度调整单元格高度 尝试了几种方法 哪一种给出了准确的高度而不重叠 请参阅本教程进行更改UITableViewCell动态高度 调整 A UITableViewCell 大小 并使用本教程 uitableviewcell
  • 在keras中对合并层进行训练

    我正在实施以下this穆罕默德 哈瓦伊 Mohammad Havaei 的论文 它使用以下架构 我修改了一些代码here这样做 print Compiling two path model local pathway modle l Seq
  • 使用FJCore编码Silverlight WriteableBitmap

    我试图找出如何使用 FJCore 将 WriteableBitmap 编码为 jpeg 我知道 WriteableBitmap 提供原始像素 但我不确定如何将其转换为 FJCore 为其 JpegEncoder 方法期望的格式 JpegEn
  • 页脚位于页面底部或内容底部(以较低者为准)

    我有以下结构 div div
  • 在 javascript 中使用 webkit-playsinline

    如何在 javascript 中而不是 html5 视频标签中使用 webkit playsinline 我想像在 javascript 中使用视频标签控制 自动播放属性一样使用它 或者你们有其他有效的方法吗 我正在开发一个用于传输视频的
  • 即使手机处于锁定模式,活动也会显示

    我的问题与此类似如何让 Android 设备启动并跳过屏幕锁定 我想从广播接收器显示一个对话框 但 Android API 不允许我这样做 因此我正在使用从那里启动一个活动并将该活动的主题更改为 Theme 现在 即使手机处于锁定模式 睡眠
  • 当我的主选择使用 AJAX 更改时,如何刷新详细选择列表

    我正在寻找一些指示 我有一个包含主题列表的选择列表
  • Haskell:如何将多个实例放在同一个模块中?

    假设我有以下代码 import Data List Ordered data Person Person String String deriving Show Eq main IO main print show sort Person
  • CSS 伪类与 jQuery

    我刚刚学了一点 jQuery 并尝试用它来实现简单的变色效果 假设我有两个 div s foo 和 bar foo 有很多 URL 并且定义了以下 CSS foo a color blue border bottom 1px dashed
  • 使用 PDO 发送空值会导致错误

    我们有类似以下 PDO 语句 用于与 PostgreSQL 8 4 DB 进行通信 st db gt prepare INSERT INTO Saba Betriebskosten personalkosten VALUES kd pers
  • 捆绑已关闭,但我仍然想要版本控制

    我在 MVC4 中使用捆绑 或者更确切地说我was使用捆绑但不得不将其关闭 这意味着脚本和样式链接仅呈现在单独的行上 并且没有版本字符串以确保浏览器在有更新时下载最新文件 我尝试在捆绑代码中添加版本字符串 但随后收到一条错误消息 指出路径无
  • 如何在 Swift 中检查 Documents 目录中是否存在文件?

    如何检查文件是否存在于Documents目录中Swift 我在用 writeFilePath 方法将图像保存到文档目录中 我想在每次启动应用程序时加载它 但如果没有保存的图像 我有一个默认图像 但我就是不知道如何使用 func fileEx
  • 在单个数组对象上重写 toString() Javascript

    我有以下内容 var version 0 3 0 Override the version toString method version proto toString function return this join 哪个执行以下操作
  • Ruby on Rails:在哪里定义全局常量?

    我刚刚开始使用我的第一个 Ruby on Rails Web 应用程序 我有很多不同的模型 视图 控制器等等 我想找到一个好地方来保存真正全局常量的定义 这些常量适用于我的整个应用程序 特别是 它们既适用于我的模型的逻辑 也适用于我的观点所
  • Android:如何在双卡手机中使用特定 SIM 卡发送短信?

    我找到了一些code这样做 但它给了我一个异常 尝试在空对象引用上调用虚拟方法 java lang Class java lang Object getClass 我正在使用我的 Moto G 第三代进行测试 以下是代码 如果我遗漏了任何内
  • Prolog:将数字拆分为递增整数的序列

    在大学里做了一些 Prolog 并做了一些练习之后 我决定进一步深入 尽管我必须承认我不太了解递归 我明白了概念和想法 但如何编码它对我来说仍然是一个问题 所以这就是为什么我很好奇是否有人知道如何帮助解决这个问题 这个想法有一个数字 例如4