Represent Accounting Equation Using SWI-Prolog

Here is the some proof of concept code that reads the sample XBLR data and checks that the formula

Assets = Liabilities + Equity

is true.

I originally tried to read the data with the SGML parser but it expected end tags instead of tags that ended with /> which was causing more problems than it was worth. As this is the first time I have used either the SGML or XML parser with SWI-Prolog, probably something I need to learn, I could not find an option for allowing tags ending with />.

Note: Click triangle below to expand section.

Proof of concept code
xbrl(Xbrl,Assets,Liabilities,Equity) :-
    Xbrl = element(xbrl,_,Elements),
    elements(Elements,Assets,Liabilities,Equity), !.

elements([],0,0,0).
elements([element('ae:Assets',_,Value_list)|Elements],Assets,Liabilities,Equity) :-
    Value_list = [Value_atom],
    atom_number(Value_atom,Value),
    elements(Elements,Assets0,Liabilities,Equity),
    Assets is Assets0 + Value.
elements([element('ae:Liabilities',_,Value_list)|Elements],Assets,Liabilities,Equity) :-
    Value_list = [Value_atom],
    atom_number(Value_atom,Value),
    elements(Elements,Assets,Liabilities0,Equity),
    Liabilities is Liabilities0 + Value.
elements([element('ae:Equity',_,Value_list)|Elements],Assets,Liabilities,Equity) :-
    Value_list = [Value_atom],
    atom_number(Value_atom,Value),
    elements(Elements,Assets,Liabilities,Equity0),
    Equity is Equity0 + Value.
elements([_|T],Assets,Liabilities,Equity) :-
    elements(T,Assets,Liabilities,Equity).

does_balance_sheet_balance(Assets,Liabilities,Equity) :-
    Assets is Liabilities + Equity.

:- begin_tests(xblr).

test(01) :-
    Xblr_string =
        "<!--  Created by Charles Hoffman, CPA: 2019-11-02  -->\n\c
        <xbrl xmlns=\"http://www.xbrl.org/2003/instance\" xmlns:xbrll=\"http://www.xbrl.org/2003/linkbase\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:iso4217=\"http://www.xbrl.org/2003/iso4217\" xmlns:xbrldi=\"http://xbrl.org/2006/xbrldi\" xmlns:xbrldt=\"http://xbrl.org/2005/xbrldt\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ae=\"http://www.xbrlsite.com/financialreporting/ae\" xsi:schemaLocation=\"http://xbrl.org/2006/xbrldi http://www.xbrl.org/2006/xbrldi-2006.xsd\">\n\c
        <xbrll:schemaRef xlink:href=\"ae.xsd\" xlink:type=\"simple\" xlink:arcrole=\"http://www.xbrl.org/2003/linkbase\"/>\n\c
        <xbrll:linkbaseRef xlink:type=\"simple\" xlink:arcrole=\"http://www.w3.org/1999/xlink/properties/linkbase\" xlink:href=\"ae-formula.xml\"/>\n\c
        <context id=\"I-2020\">\n\c
        <entity>\n\c
        <identifier scheme=\"http://standards.iso.org/iso/17442\">GH259400TOMPUOLS65II</identifier>\n\c
        </entity>\n\c
        <period>\n\c
        <instant>2020-12-31</instant>\n\c
        </period>\n\c
        </context>\n\c
        <unit id=\"U-Monetary\">\n\c
        <measure>iso4217:USD</measure>\n\c
        </unit>\n\c
        <ae:Assets contextRef=\"I-2020\" unitRef=\"U-Monetary\" decimals=\"INF\">5000</ae:Assets>\n\c
        <ae:Liabilities contextRef=\"I-2020\" unitRef=\"U-Monetary\" decimals=\"INF\">1000</ae:Liabilities>\n\c
        <ae:Equity contextRef=\"I-2020\" unitRef=\"U-Monetary\" decimals=\"INF\">4000</ae:Equity>\n\c
        </xbrl>",
    open_string(Xblr_string,Stream),
    load_xml(Stream,[Xbrl],[]),
    xbrl(Xbrl,Assets,Liabilities,Equity),
    does_balance_sheet_balance(Assets,Liabilities,Equity).

:- end_tests(xblr).

Example run.

You will need to change to the appropriate directory on your system.

?- working_directory(_,'c:/users/eric/documents/Projects/Prolog/xbrl').
true.

?- consult("xbrl.pl").
true.

?- run_tests.
% PL-Unit: xblr . done
% test passed
true.