Did you know ... | Search Documentation: |
Packs (add-ons) for SWI-Prolog |
Title: | Object system that allows easy and efficient access to term arguments by name. |
---|---|
Rating: | Not rated. Create the first rating! |
Latest version: | 1.2.2 |
SHA1 sum: | 2eb76ccb61d47acbb72f4d0828bef1692f21e24c |
Author: | Neil Hoskins https://github.com/da-poodle |
Maintainer: | Neil Hoskins https://github.com/da-poodle |
Packager: | Neil Hoskins https://github.com/da-poodle |
Home page: | https://github.com/da-poodle/fld |
Download URL: | https://github.com/da-poodle/fld.git |
No reviews. Create the first review!.
Version | SHA1 | #Downloads | URL |
---|---|---|---|
0.0.1 | 6be0b0a7dac510b7d3f74c49fd003796e2d89e38 | 1 | https://github.com/da-poodle/fld.git |
0.1.0 | 58ac3a293df766eb03870cfd32e377cc2f6cc9d7 | 1 | https://github.com/da-poodle/fld.git |
726cadf057207bc715cdb1d14d3e68e4403e9bc3 | 41 | https://github.com/da-poodle/fld.git | |
90b060433b6890669f7d78b8fca81d218e1a1f13 | 2 | https://github.com/da-poodle/fld.git | |
1.0.2 | 136434d34bcf3cc4ff53857c5533aaff1d104a03 | 1 | https://github.com/da-poodle/fld.git |
46d3c82d17d126f8a73d6c899d134feef9bd6542 | 6 | https://github.com/da-poodle/fld.git | |
1.2.2 | 2eb76ccb61d47acbb72f4d0828bef1692f21e24c | 3 | https://github.com/da-poodle/fld.git |
A library for accessing and updating term arguments in Prolog in a position independent way.
To install the fld library, type the following in the SWI-Prolog shell:
?- pack_install('https://github.com/da-poodle/fld.git'). true.
The library allows the definition of data that will be used in a program. To define a 'type' then use fld_object/2.
eg: To create a person object, the following could be added to prolog.
:- fld_object(person, [name, age, gender]).
fld uses the concept of 'business types' so in this case there are four types:
Note that this is similar to library(record) except that specific names are not used for each object type. There are a few reasons for this:
Define a term and the named fields that can be used with the fld library.
:- fld_object(person, [name, age, gender]).
Further calls to fld_object/2 with the same parameters will unify with an existing fld_object. eg:
?- fld_object(person, F). F = [name, age, gender].
Attempting to call fld_object/2 with a name and different parameters fails. eg:
?- fld_object(person, [name,age,sex]). false.
Access the value of terms argument by name.
?- fld(name(N), person(greg, 32, male)). N = greg.
fld/2 (and flds/2) can be used to set the values of an object as well if the object is uninstantiated. eg:
?- fld_template(person, P), fld(name(henry), P). P = person(henry, _, _).
Access several arguments by name in one call.
:- fld([name(N),gender(G)], person(greg, 32, male)). N = greg. G = male.
Replace the value of a terms argument by name.
:- fld_set(name(frank), person(greg, 32, male), P). P = person(frank, 32, male).
Replace several term arguments by name.
:- flds_set([name(frank), age(25)], person(greg, 32, male), P). P = person(frank,25,male).
This predicate has two uses.
Use 1: generate a blank version of a term by name:
?- fld_template(person, P). F = person(_944, _950, _956).
Use 2: test if a term matches the template for a named type:
?- fld_template(person, person(mary, 25, female)). true.
When creating a new template a default mechanism is used to set values based on name. By defaul the fld_default/2 predicate is used. For example
?- assert(fld:fld_default(gender, unspecified)). true. ?- fld_template(person, P). P = person(_944, _950, unspecified).
This is the same call as <code>fld_template(person, P, fld:fld_default)
.</code>
As per fld_template/2 but you can specify a goal that will be used for defaults. The goal has two parameters:
Note: If multiple defaults are specified for a field, then only the first will be used.
Destroy and fld object so it can no longer be used. Not highly useful as objects should be created for the duration of a program, however it is needed for unit testing and maybe specific scenarios.
?- fld(name(N), person(greg, 35, male)). N = greg. ?- fld_destroy(person). true. ?- fld(name(N), person(greg, 35, male)). false.
fld_destroy/1 will always succeed.
A CSV file for bank records needs to be read which has the following headings:
transaction_id,date,description,amount,balance
The task is to find any transactions that are over $1000
In this case fld can be used to map the incoming data more easily, especially if the number or order of the data changes.
:- use_module(library(fld)). % Create an fld_object for the headers :- fld_object(transaction, [transaction_id, date, description, amount, balance]). % Read in the CSV file with the functor name as the fld_object name and arity of 5. % This will get a list of data which matches the % fld_object(transaction,_). read_bank_records(Data) :- csv_read_file('bank_records.csv', Data, [functor(transaction), arity(5)]). % create a filter that can get the records over $1000 over_one_thousand(Tran) :- fld(amount(Amount), Tran), Amount > 1000. % load and filter the data load_and_filter :- read_bank_records(Data), include(over_one_thousand, Data, ExpensiveRecords), maplist(print_record, ExpensiveRecords). print_record(Tran) :- flds([date(Date), description(Desc), amount(Amount)], Tran), format('~w $~w - ~w~n', [Date, Amount, Desc]).
It is possible to use multiple object types in the same code if they share fields.
:- use_module(library(fld)). :- fld_object(car, [owner, model, registration, expires, year_of_make, body_type]). :- fld_object(bus, [company, model, registration, expires, year_of_make]). registration_valid(RoadUser) :- flds([registration(Rego), expires(Expires)], RoadUser), get_time(Time), ( Time < Expires -> true ; format('Rego ~p is expired~n', Rego)). test :- fld_template(car, C), flds([registration('ABC-123'), expires(1544947900.570324)], C), registration_valid(C). test :- fld_template(bus, B), flds([registration('DA-BUS01'), expires(1544947900.570324)], B), registration_valid(B).
Pack contains 13 files holding a total of 18.2K bytes.