<div class="notebook"> <div class="nb-cell program" data-singleline="true" name="p1"> % Original code click arrow to open -----------> % % 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 -----------> % % 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. /** <examples> ?- 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>