? users online
  • Logout
    • Open hangout
    • Open chat for current file
<div class="notebook">

<div class="nb-cell program" data-singleline="true" name="p1">
% Original code   click arrow to open -----------&gt;
% % The Accounting Equation in Prolog %
% https://en.wikipedia.org/wiki/Accounting_equation %
% Created by Charles Hoffman, CPA (charles.hoffman@me.com). %
% Public domain: https://creativecommons.org/publicdomain/zero/1.0/ %
% Run SWI-Prolog using https://swish.swi-prolog.org/ %

term(asset).
term(liability).
term(equity).
structure(balanceSheet).
entity(microsoft).
period(2017).
assertion(does_balance_sheet_balance).

fact(term(asset), entity(microsoft), period(2017), 241086000000).
fact(term(liabilities), entity(microsoft), period(2017),168692000000).
fact(term(equity), entity(microsoft), period(2017),72394000000).

% rule Assets = Liabilities + Equity %
does_balance_sheet_balance(Entity, Period) :-
    fact(term(asset),entity(Entity),period(Period),Asset),
    fact(term(liabilities),entity(Entity),period(Period),Liabilities),
    fact(term(equity),entity(Entity),period(Period),Equity),
    Asset is Liabilities + Equity.

% QUESTION   fact(Term, Entity, Period, Value). %
% QUESTION   does_balance_sheet_balance(microsoft, 2017). %
</div>

<div class="nb-cell markdown" name="md1">
Some comments
-------------
1. `%` is not needed at the end of the code comments
2. The facts `term(asset), term(liability)` up until `assertion(does_balance_sheet_balance)` are not needed since they are not used as goals in any clause. You use `fact/4` as a goal, so that is needed.

Making those changes we get this:
</div>

<div class="nb-cell program" data-singleline="true" name="p2">
% With some fixes  click arrow to open -----------&gt;
% % FASB SFAC 6, Elements of Financial Statements, in Prolog
% https://www.fasb.org/pdf/con6.pdf
% Created by Charles Hoffman, CPA (charles.hoffman@me.com).
% Public domain: https://creativecommons.org/publicdomain/zero/1.0/
% Run SWI-Prolog using https://swish.swi-prolog.org/

fact(term(asset), entity(microsoft), period(2017), 241086000000).
fact(term(liabilities), entity(microsoft), period(2017),168692000000).
fact(term(equity), entity(microsoft), period(2017),72394000000).
fact(term(equity), entity(microsoft), period(2016),71997000000).

fact(term(distributionsToOwners), entity(microsoft), period(2017),19701000000).

fact(term(revenues), entity(microsoft), period(2017),89950000000).
fact(term(expenses), entity(microsoft), period(2017),69569000000).
fact(term(gains), entity(microsoft), period(2017),823000000).
fact(term(losses), entity(microsoft), period(2017),1106000000).
fact(term(comprehensiveIncome), entity(microsoft), period(2017),20098000000).

% rule Assets = Liabilities + Equity
does_balance_sheet_balance(Entity, Period) :-
    fact(term(asset),entity(Entity),period(Period),Asset),
    fact(term(liabilities),entity(Entity),period(Period),Liabilities),
    fact(term(equity),entity(Entity),period(Period),Equity),
    Asset is Liabilities + Equity.

% rule ComprehensiveIncome = Revenues - Expenses + Gains - Losses
does_income_statement_foot(Entity, Period) :-
    fact(term(comprehensiveIncome),entity(Entity),period(Period),ComprehensiveIncome),
    fact(term(revenues),entity(Entity),period(Period),Revenues),
    fact(term(expenses),entity(Entity),period(Period),Expenses),
    fact(term(gains),entity(Entity),period(Period),Gains),
    fact(term(losses),entity(Entity),period(Period),Losses),
    ComprehensiveIncome is Revenues - Expenses + Gains - Losses.

% rule EndingEquity = BeginningEquity + ComprehensiveIncome + InvestmentsByOwners - DistributionsToOwners
does_equity_roll_forward_old(Entity, Period) :-
   fact(term(equity),entity(Entity),period(2016),BeginningEquity),
   fact(term(comprehensiveIncome),entity(Entity),period(Period),ComprehensiveIncome),
   fact(term(equity),entity(Entity),period(Period),EndingEquity),
   fact(term(distributionsToOwners),entity(Entity),period(Period),DistributionsToOwners),
   EndingEquity is BeginningEquity + ComprehensiveIncome - DistributionsToOwners.
</div>

<div class="nb-cell markdown" name="md2">
Using variables for `does_equity_roll_forward`
----------------------------------------------
1. All you need to do is add `BeginningPeriod` and `EndPeriod` as you were thinking
here is the program:
</div>

<div class="nb-cell program" name="p3">
% FASB SFAC 6, Elements of Financial Statements, in Prolog
% https://www.fasb.org/pdf/con6.pdf
% Created by Charles Hoffman, CPA (charles.hoffman@me.com).
% Public domain: https://creativecommons.org/publicdomain/zero/1.0/
% Run SWI-Prolog using https://swish.swi-prolog.org/

fact(term(asset), entity(microsoft), period(2017), 241086000000).
fact(term(liabilities), entity(microsoft), period(2017),168692000000).
fact(term(equity), entity(microsoft), period(2017),72394000000).
fact(term(equity), entity(microsoft), period(2016),71997000000).

fact(term(distributionsToOwners), entity(microsoft), period(2017),19701000000).

fact(term(revenues), entity(microsoft), period(2017),89950000000).
fact(term(expenses), entity(microsoft), period(2017),69569000000).
fact(term(gains), entity(microsoft), period(2017),823000000).
fact(term(losses), entity(microsoft), period(2017),1106000000).
fact(term(comprehensiveIncome), entity(microsoft), period(2017),20098000000).

% rule Assets = Liabilities + Equity
does_balance_sheet_balance(Entity, Period) :-
    fact(term(asset),entity(Entity),period(Period),Asset),
    fact(term(liabilities),entity(Entity),period(Period),Liabilities),
    fact(term(equity),entity(Entity),period(Period),Equity),
    Asset is Liabilities + Equity.

% rule ComprehensiveIncome = Revenues - Expenses + Gains - Losses
does_income_statement_foot(Entity, Period) :-
    fact(term(comprehensiveIncome),entity(Entity),period(Period),ComprehensiveIncome),
    fact(term(revenues),entity(Entity),period(Period),Revenues),
    fact(term(expenses),entity(Entity),period(Period),Expenses),
    fact(term(gains),entity(Entity),period(Period),Gains),
    fact(term(losses),entity(Entity),period(Period),Losses),
    ComprehensiveIncome is Revenues - Expenses + Gains - Losses.

% rule EndingEquity = BeginningEquity + ComprehensiveIncome + InvestmentsByOwners - DistributionsToOwners
does_equity_roll_forward(Entity, period_range(BeginningPeriod,EndPeriod)) :-
   fact(term(equity),entity(Entity),period(BeginningPeriod),BeginningEquity),
   fact(term(comprehensiveIncome),entity(Entity),period(EndPeriod),ComprehensiveIncome),
   fact(term(equity),entity(Entity),period(EndPeriod),EndingEquity),
   fact(term(distributionsToOwners),entity(Entity),period(EndPeriod),DistributionsToOwners),
   EndingEquity is BeginningEquity + ComprehensiveIncome - DistributionsToOwners.


/** &lt;examples&gt;

?- fact(Term, Entity, Period, Value).
?- does_balance_sheet_balance(microsoft, 2017).
?- does_income_statement_foot(microsoft, 2017).
?- does_equity_roll_forward(microsoft, period_range(2016, 2017)).
?- does_equity_roll_forward(microsoft, period_range(2015, 2017)).

*/
</div>

<div class="nb-cell markdown" name="md3">
### Now, let's see if equity rolls forward from 2016 to 2017:
</div>

<div class="nb-cell query" name="q1">
does_equity_roll_forward(microsoft, period_range(2016, 2017)).
</div>

<div class="nb-cell markdown" name="md4">
### Let's try from 2015 to 2017:
</div>

<div class="nb-cell query" name="q2">
does_equity_roll_forward(microsoft, period_range(2015, 2017)).
</div>

<div class="nb-cell markdown" name="md5">
It is `false` because there are no facts available for 2015.

## How about asking for companies or periods in which equity rolls forward?
Now, let's ask prolog to find the period(s) in which equity rolls forward:
</div>

<div class="nb-cell query" name="q3">
does_equity_roll_forward(microsoft, RollsForwardPeriod).
</div>

<div class="nb-cell markdown" name="md6">
Isn't that great? It found the period for you. The `false` at the end means that *it could not find* another `period_range/2` in which `does_equity_roll_forward/2` was `true`.

In SWISH, you get the `false` when you click the "next" button to find the next answer. In the SWI-Prolog console you can use the semi-colon `;` to do the same.

Now let's ask prolog for which companies does equity roll forward from 2016 to 2017:
</div>

<div class="nb-cell query" name="q4">
does_equity_roll_forward(Company, period_range(2016, 2017)).
</div>

<div class="nb-cell markdown" name="md7">
Let's try the most generic query are there any companies for wich the equity rolls forward? If so, what is the period range in which it rolls forward?
</div>

<div class="nb-cell query" name="q5">
does_equity_roll_forward(Company, Range).
</div>

<div class="nb-cell markdown" name="md8">
Again, the `false` means there are no more companies/ranges for which the equity rolls forward.

Isn't prolog great?
</div>

</div>