gpt4 book ai didi

prolog - 如何使用成员谓词在序言中指定约束

转载 作者:行者123 更新时间:2023-12-01 15:43:00 25 4
gpt4 key购买 nike

我正在尝试编写执行以下操作的Prolog程序:
我在“关系”列表中定义了一些关系。 (例如:[f1,s1]表示f1需要s1)根据在TargetFeat列表中选择的功能(f1,f2,f3),我想使用约束编程来创建结果列表。
这是一个示例代码:

Relations =[[f1, s1], [f2, s2], [f3, s3], [f3, s4]],
TargetFeat = [f3, f1],
Result = [],
member(f3,TargetFeat) #= member(s3,Result), %One of the constraints
labeling(Result).

这是行不通的,因为#=仅适用于算术表达式作为操作数。实现这样的目标有哪些选择?

最佳答案

有许多可能的方法可以用约束对这种依赖关系进行建模。我在本文中考虑CLP(FD)和CLP(B)约束,因为它们最常用于解决组合任务。

首先考虑CLP(FD),它在许多方面都更常用且更方便。当使用CLP(FD)约束时,您还有几个选项可以代表您的任务。但是,无论最终选择哪种模型,都必须首先将表示形式中的所有项目切换到约束求解器可以实际推理的适当实体。对于CLP(FD),这意味着将您的实体切换为整数

将实体转换为相应的整数非常简单,这也是CLP(FD)约束也足以在实际上不包含整数但可以映射为整数的域上对任务进行建模的原因之一。因此,让我们假设您不是在考虑功能f1f2f3,而是关于整数 012或其他适合您的整数集。

您可以将需求直接转换到这个新域。例如,代替:

[f1,s1]的意思是:f1需要s1
我们可以说例如:

0 -> 3的意思是:0需要3
这使我们已经非常接近CLP(FD)约束,可以让我们对整个问题进行建模。我们只需要再做一次精神上的飞跃就可以获得一个可以对所有需求进行建模的表示。现在,我们使用 CLP(FD)变量代替具体的整数,以指示是否必须满足特定要求才能获得所需的功能。我们将使用R1R2R3,...变量来表示需要哪些需求,对每种可能的需求使用0(不需要)或1(需要)。

此时,您必须针对实际要描述的内容建立清晰的思维模型。我解释一下我的想法:我想描述三件事之间的关系:

  • 功能的列表Fs
  • 功能和需求之间的依赖性列表Ds列表
  • 要求的列表Rs

  • 我们已经考虑了如何表示所有这些实体:(1)是 整数的列表,这些整数表示我们想要获得的功能。 (2)是表示“功能 F -> R需要需求 F”的 R对的列表,(3)是指示最终是否需要每个需求的布尔变量列表。

    现在,让我们尝试将所有这些实体相互关联。

    首先,第一件事:如果不需要任何功能,那一切都是微不足道的:
    features_dependencies_requirements([], _, _).

    但是,如果实际上需要某个功能,该怎么办?好吧,这很简单:我们只需要考虑该功能的依赖性:
    features_dependencies_requirements([F|Fs], Ds, Rs) :-
    member(F->R, Ds),

    因此我们在 R中具有功能 F的要求。现在我们只需要在 Rs中找到表示需求 R的合适变量即可。但是,我们如何找到合适的变量?毕竟,Prolog变量“没有领结”,或者(对外国人而言)缺少标记,我们可以通过该标记将其与其他人区分开。因此,在这一点上,实际上我们发现可以方便地从 Rs中选择给定其需求名称的变量。因此,让我们假设将 Rs表示为 I=R形式的 对的列表,其中 I是定义需求的整数,而 R是表示是否需要该需求的布尔值指示符。有了这种表示形式,我们可以按如下方式完整定义上面的子句:
    features_dependencies_requirements([F|Fs], Ds, Rs) :-
    member(F->I, Ds),
    member(I=1, Rs),
    features_dependencies_requirements(Fs, Ds, Rs).

    而已。这完全与功能,依赖项和需求的列表相关联,以使第三个参数指示获得这些功能所必需的要求。

    此时,细心的读者会发现上面的代码中实际上没有使用任何CLP(FD)约束,并且实际上完全不需要将特征转换为整数。我们也可以使用原子,使用与上面显示的完全相同的代码表示功能和需求。

    示例查询和答案:

    ?-features_dependencies_requirements([f3,f1],
    [f1-> s1,f2-> s2,f3-> s3,f3-> s4],
    [s1 = S1,s2 = S2,s3 = S3,s4 = S4])。
    S1 = S3,S3 = 1;
    S1 = S4,S4 = 1;
    假。

    显然,我做出了以下假设:依赖关系是分离的,这意味着只要满足至少一项要求,就可以实现该功能。如果要将其转换为合取词,则显然必须更改它。您可以先将依赖关系表示为 F -> [R1,R2,...R_n]

    除此之外,将实体转换为整数是否仍然有用? ,因为您的许多约束很可能也可以用CLP(FD)约束来表述,并且您需要整数才能起作用。

    为了帮助您入门,以下两种方法可能适用于您的情况:
  • 使用约束修正来表示什么意味着什么。例如:F #==> R
  • 使用诸如table/2之类的全局约束来表达关系。

  • 特别是在第一种情况下,CLP(B)约束也可能有用。您始终可以使用布尔变量来表示是否必须满足要求。

    关于prolog - 如何使用成员谓词在序言中指定约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38479214/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com