:- use_module(library(lists)). :- use_module(library('http/http_client')). :- use_module(library('http/json')). %! find_chains(+MaxLength) is semidet % % Prints possible profitable conversion chains. find_chains(MaxLength) :- http_get('http://fx.priceonomics.com/v1/rates/', Json, ), atom_json_term(Json, json(Prices), ), % convert the json atom to a prolog term and extract the list of prices abolish(price/3), % clear any old price facts from the database assert_prices(Prices), % update the database with current prices % now get the set of all solutions for the predicate % build_chain/3, and build a list of the results setof(chain(Symbols, Profit), build_chain(MaxLength, Symbols, Profit), Chains), % print the results write(Chains). %! assert_prices(+List) is det % % Adds the list of prices to the dynamic database. % assert_prices(). assert_prices([SymbolPair = Price | Rest]) :- atomic_list_concat([From, To], '_', SymbolPair), atom_number(Price, Num), assertz(price(From, To, Num)), assert_prices(Rest). %! build_chain(+MaxLength, -Symbols, -Profit) is nondet % % Finds a profitable chain build_chain(MaxLength, Symbols, Profit) :- price(Dest, Next, _), Dest \= Next, % pick a starting symbol (ignore repeats), with backtracking build_chain(MaxLength, Dest, [Dest], 1.0, Symbols, Profit). %! build_chain(+Count, Dest, SymbolsIn, ProfitIn, SymbolsOut, ProfitOut) % % Finds a possible next link in the chain, checks to see if it's a loop, otherwise recurses. build_chain(0, _, _, _, _, _) :- !, fail. % stop backtracking when we hit our maximum length build_chain(Count, Dest, SymbolsIn, ProfitIn, SymbolsOut, ProfitOut) :- price(A, B, P), % find a price record (backtracking over all of them) append(_, [A], SymbolsIn), % make sure the chain connects Profit is ProfitIn * P, % calculate our profit (B = Dest % do we have a loop? -> Profit > 1.0, % is it profitable? append(SymbolsIn, [B], SymbolsOut), % if so, then we're done ProfitOut = Profit ; \+ member(B, SymbolsIn), % if not a loop, make sure we don't repeat interior symbols append(SymbolsIn, [B], SymbolsNext), % add B to a temp list NextCount is Count - 1, % and recurse, decrementing our counter build_chain(NextCount, Dest, SymbolsNext, Profit, SymbolsOut, ProfitOut)).
For when you have a gigabyte of JSON data to process:
Continue reading “Reflection and Lazy Evaluation FTW”
Released NeuroLab 1.2.1: http://neurolab.bitbucket.org
Neurocognitive Linguistics is an approach to linguistics developed by Sydney Lamb (http://www.ruf.rice.edu/~lamb/) which uses relational networks to model what the brain actually does when it handles language. You can read more about it at the LangBrain site (http://www.ruf.rice.edu/~lngbrain/main.htm) and Glottopedia (http://www.glottopedia.de/index.php/Neurocognitive_linguistics).
Neurocognitive Linguistics Lab (“NeuroLab” for short) is a program for Windows, Mac OS X and Linux that allows you to experiment with relational networks using a convenient GUI, and record the results of your experiments in tabular form.