:- expects_dialect(lps).
% Examples from https://nakamotoinstitute.org/contract-language/
% Use for compliance: we'll be checking these events occur properly
events to(_Agent,_Right).
simulatedRealTimeBeginning('2002-06-01').
simulatedRealTimePerCycle(RTPC) :- minCycleTime(RTPC).
maxTime(200).
maxRealTime(M) :- M is 24*3600*90. % 90 days NOT WORKING???
minCycleTime(Min) :- Min is 3600*12. % just 2 LPS cycles per calendar day
% System primitives used next
:- include(system('date_utils.pl')).
% withinPeriod(Period): Period is StartDate-EndDate, where each of these dates is Year/Month/Day, with integers
% TODO: try to "cut" alternatives after Today>@>Last ...??
withinPeriod(First-Last) at T if
real_date(Today) at T, Today @>= First, Last @>= Today.
% also needed: LPS engine must be cleverer detecting failures due to time never going back
/* First Example - Futures Contract
Original:
future(rightA="1 round lot pork bellies",
rightB="$1,500.00",
p = "for delivery in July 2002") =
when withinPeriod(p)
to Holder rightA with to Counterparty rightB
then terminate */
future(RightA,RightB,Period) if
withinPeriod(Period) at T,
to(holder,RightA) from T, to(counterParty,RightB) from T.
if true then
future("1 round lot pork bellies", usd(1500), 2002/7/1 - 2002/7/31).
observe to(holder,"1 round lot pork bellies") at '2002-07-15T11:00'.
%observe to(counterParty,usd(1500)) at '2002-07-15T11:00'.
% System primitives used next
beforeTime(TimeExpression) if
convert(TimeExpression,Instant), real_time(Now) at T, Now @> Instant.
afterTime(TimeExpression) if
convert(TimeExpression,Instant), real_time(Now) at T, Now @< Instant.
/* Second Example - Option Contract
Original:
callOptionAmerican (rightA="1 round lot XYZ Corp.",
rightB="$2,000/lot",
time="end of trading on last trading day of August") =
when beforeTime(time)
when choiceOf(Holder)
to Holder rightA with to Counterparty rightB
when afterTime(time)
terminate */
callOptionAmerican(RightA,RightB,Time) if
beforeTime(Time) at T,
choiceOf(holder) from T to End,
to(holder,RightA) from T to End, to(counterParty,RightB) from T to End.
callOptionAmerican(RightA,RightB,Time) if
afterTime(Time) at T,
lps_terminate from T.
if true then
callOptionAmerican("1 round lot XYZ Corp.","$2,000/lot","end of trading on last trading day of August").
observe to(holder,"1 round lot XYZ Corp.") at '2019-08-30T16:00'.
observe to(counterParty,usd(2000)) at '2019-08-30T16:00'.
% System primitives used next
schedule(StringExpression,Intervals) if ...
% Generate list of Moment1-Moment2 intervals
% Introducing schedule in a bond
bond(Coupon, Principal, Schedule) if
schedule(Expression,Intervals),
bond(Coupon, Principal, Intervals).
bond(Coupon, Principal, [Next|More]) if
More \== [],
withinPeriod(Next) at T1,
to(holder,Coupon) from T1 to T2,
bond(Coupon, Principal, More) from T2.
bond(Coupon, Principal, [LastInterval]) if
withinPeriod(LastInterval) at T,
to(holder,Principal) from T.
% System primitives used next
..., Event until FluentCondition otherwise Action, ...
means:
...initiate must_123, Event to T, terminate must_123 from T, ...
plus:
if FluentCondition at T, must_123 at T then
MacroAction from T, terminate must_123 from T.
% or perhaps better...:
... , if Condition then Then else Else,...
means:
... , initiate if_123, if_then_else(Condition,Then,Else),...
plus:
if_then_else(Condition,Then,Else) if Condition, terminate if_123, Then.
if_then_else(Condition,Then,Else) if if_123, Else.
% Insurance
/* Original:
loan(goods, principal, penalty, t1, t2) =
counterpartySecurity = pledge(allGoods(Counterparty))
with to Counterparty getTitle(goods)
loanPayment(principal, t1, t2)
with when breachedPerformance(loanPayment)
to Holder foreclose(counterpartySecurity, penalty)
loanPayment(principal, t1, t2) =
when withinPeriod(t1,t2)
when choiceOf(Holder)
to Holder principal */
/* loan(Goods, Principal, Penalty, T1-T2) if
pledge(allGoods(counterparty),CounterpartySecurity) from M1 to M2,
to(counterParty,getTitle(Goods)) from M1 to M2,
loanPayment(Principal, T1-T2) until real_date(T2)
otherwise to(holder,foreclose(counterpartySecurity, Penalty)).
using if then else instead:*/
loan(Goods, Principal, Penalty, T1-T2) if
pledge(allGoods(counterparty),CounterpartySecurity) from M1 to M2,
to(counterParty,getTitle(Goods)) from M1 to M2,
if ( loanPayment(Principal, T1-T2) to T, real_date(T3) at T )
then T3 @=< T2
else to(holder,foreclose(counterpartySecurity, Penalty)).
loanPayment(Principal, T1-T2) if
withinPeriod(T1-T2) at T,
choiceOf(holder) from T to End,
to(holder,Principal) from T to End.
if true then
loan("some house",usd(300000), usd(10000), 2018/10/1-2018/12/31).
/* Original:
insureGoods(goodsPremium, principal, penalty, t1, t2, goodsInsured) =
counterpartySecurity = pledge(allGoods(Counterparty))
with to Counterparty getTitle(goodsPremium)
insurancePayment(goodsInsured, principal, t1, t2)
with when breachedPerformance(insurancePayment)
to Holder foreclose(counterpartySecurity, penalty)
insurancePayment(goodsInsured, principal, t1, t2) =
when safeArrival(goodsInsured) terminate % buggy, IMHO: should check dates
when withinPeriod(t1,t2)
when choiceOf(Holder)
to Holder principal
*/
/* insureGoods(GoodsPremium, Principal, Penalty, T1-T2, GoodsInsured) if
pledge(allGoods(counterparty),CounterpartySecurity) from M1 to M2,
to(counterParty,getTitle(GoodsPremium)) from M1 to M2,
insurancePayment(GoodsInsured,Principal,T1-T2) until real_date(T2)
otherwise to(holder,foreclose(counterpartySecurity, Penalty)).
using if then else instead: */
insureGoods(GoodsPremium, Principal, Penalty, T1-T2, GoodsInsured) if
pledge(allGoods(counterparty),CounterpartySecurity) from M1 to M2,
to(counterParty,getTitle(GoodsPremium)) from M1 to M2,
if (insurancePayment(GoodsInsured,Principal,T1-T2) to T, real_date(T3) at T)
then T3@=
?- go(Timeline).
*/