首页 > 解决方案 > 序言 | 获取一个列表,其中元素与其他列表和常量值一起计算

问题描述

我有一个关于电影和系列发行企业的作业。我必须做一个谓词,在其中我将传递一个值和月份,它将返回一个排序列表,其中包含合同号,其为月份支付的总金额应该大于值。

我把总额的公式放在下面

Total amount = minimum amount + royalty amount
Royalty amount = (monthly net - minimum amount)*royalty percent
Monthly net = monthly income - distribution spending - cost percent
Cost percent = (monthly net - minimum amount)*cost percent

我为版税金额和每月净额做了谓词,代码是这样的:

contract('A255', 'Distributor A', 'CSI Las Vegas', '3M3520', '2', ['DVD', 'Streaming'], 30.000).
contract('A566', 'Distributor B', 'Ghost Hunters', '1Q2010', 1, ['Cinema'], 50.000).
contract('A897', 'Distributor A', 'Sherlock Holmes', '1M2020', 2, ['DVD', 'BlueRay', 'TVP', 'Streaming'], 75.000).
contract('A123', 'Distributor C', 'Lion King', '2Q3015', 1, ['DVD', 'BlueRay', 'TVP', 'Streaming'], 65.000).
contract('A453', 'Distributor B', 'La odisea de los giles', '1M2020', 1, ['Cinema'], 35.000).
contract('A690', 'Distributor C', 'El Robo del Siglo', '1Q2010', 1, ['Cinema'], 45.000).

%Contract number, income date(day, month, year), income amount, spendings amount, country.
monthlyIncomes('A123', date(15, 03, 2020), 45000, 17500, 1).
monthlyIncomes('A123', date(31, 03, 2020), 20000, 16500, 1).
monthlyIncomes('A123', date(30, 06, 2020), 50000, 22500, 3).
monthlyIncomes('A453', date(12, 06, 2020), 30000, 15000, 2).
monthlyIncomes('A453', date(28, 06, 2020), 25000, 15000, 2).
monthlyIncomes('A690', date(02, 02, 2020), 12000, 13500, 3).
monthlyIncomes('A690', date(29, 02, 2020), 95500, 13500, 3).
monthlyIncomes('A690', date(31, 03, 2020), 80000, 12500, 1).
monthlyIncomes('A897', date(16, 03, 2020), 40000, 17000, 2).
monthlyIncomes('A897', date(31, 03, 2020), 15000, 17000, 2).
monthlyIncomes('A897', date(02, 29, 2020), 50000, 17000, 1).
monthlyIncomes('A566', date(30, 04, 2020), 50000, 16500, 3).
monthlyIncomes('A255', date(10, 04, 2020), 72000, 14500, 3).
monthlyIncomes('A255', date(30, 04, 2020), 90000, 14500, 3).
monthlyIncomes('A540', date(12, 06, 2020), 30000, 10800, 2).
monthlyIncomes('A540', date(30, 06, 2020), 30800, 10700, 2).
monthlyIncomes('A540', date(31, 07, 2020), 30500, 10600, 1).
monthlyIncomes('A120', date(31, 07, 2020), 25500, 23400, 1).
monthlyIncomes('A234', date(15, 05, 2020), 75600, 12800, 1).
monthlyIncomes('A234', date(31, 05, 2020), 75600, 12800, 1).

%Royalty, name, percentage to pay, cost percentage, country.
royalties('1Q2010', 'Royalty 1', 0.20, 0.10, 1).
royalties('1M2020', 'Royalty 2', 0.20, 0.20, 2).
royalties('2Q3015', 'Royalty 3', 0.30, 0.15, 1).
royalties('2M2515', 'Royalty 4', 0.25, 0.15, 2).
royalties('3M3520', 'Royalty 5', 0.35, 0.20, 3).

%id, name
product_type(1, 'Film').
product_type(2, 'Serie').

country(1, 'Argentina').
country(2, 'New Zeland').
country(3, 'Albania').

get_net_value(Contract, Month, Net) :-  
    findall(Incomes, monthlyIncomes(Contract, date(_, Month, _), Incomes, _, _), Incomes),                  
    findall(Spendings, monthlyIncomes(Contract, date(_, Month, _), _, Spendings, _), Spendings), 
    sumlist(Incomes, SumIncomes), sumlist(Spendings, SumSpendings), 
    Net1 is SumIncomes - SumSpendings,
    contract(Contract, _, _, Royalty, _, _, MinimumAmount), royalties(Royalty, _, _, PctCost, _),
    Net is Net1 - Net1*PctCost.

royalty_amount(Contract, Month, RoyaltyAmount) :-
    get_net_value(Contract, Month, Net),
    contract(Contract, _, _, Royalty, _, _, MinimumAmount),
    royalties(Royalty, _, _, PctCost, _),
    RoyaltyAmount is (Net - MinimumAmount)*PctCost.

amount_by_value(Value, Month, Contract) :- 
    findall(Contract, monthlyIncomes(Contract, date(_, Month, _), _, _, _), Contract),
    findall(MinimumAmount, monthlyIncomes(_, date(_, Month, _), MinimumAmount, _, _), MinimumAmount).

amount_by_value 这是我遇到麻烦的谓词。使用当前代码,我得到一个包含合同数量的合同列表和另一个列表 MinimumAmount,其中包含总金额计算的最低金额,但我不知道如何获得每个合同的特许权使用费金额。我试着用这条线maplist(royalty_amount, Contract, [Month], Royalties).。这就是问题标题的原因,常量值是月份,列表是合同,但这会返回一个布尔值 false。有人可以给我一些建议吗?将不胜感激

标签: prolog

解决方案


让我试着帮助你。您必须阅读 findall/3 预定义谓词。它在 get_net_value/3 和 amount_by_value/3 中的使用永远不会成功。

findall(Var目标ListOfVars)。 Var要么是一个单一的变量(X),要么是一个模板(例如,一个列表或带有一个或多个变量的函子)。单个或多个变量出现在Goal中。只要Goal成功,Var的当前值就会被收集到ListOfVars中。

所以ListOfVars是一个强制列表,它永远不能等于Var,就像你在 get_net_value/3 和 amount_by_value/3 谓词中使用的那样。

希望能帮助到你!或者进一步解释你的问题。


推荐阅读