Pull to refresh

Пролог: База фактов из CSV файла

Reading time 4 min
Views 7.2K

Импорт фактов в базу пролога из файла в формате CSV



Для того чтобы работать с фактами базы данных в прологе их (факты) необходимо импортировать из внешнего источника.


На схеме условно показаны три области активностей:
Желтая — подготовка промежуточного файла. Для простого импорта это может быть просто сохранение документа в формате CSV. Для работы по регламенту возможна настройка компонентов БД (например MS SQL Server Integration Services) для периодической выгрузки. Данная активность в статье не рассматривается.
Красная — импорт данных из CSV файла в базу фактов.
Зеленая — работа с базой фактов в Прологе.
Примечание. Стрелками показаны потоки данных.

Реализация SWI-Prolog имеет в своем составе предикаты, которые упрощают работу с файлом в формате CSV. Привожу основные моменты по созданию программы:
1. Ввод данных из файла CSV

csv_read_file(File, RowList, [ separator(0';)])
File — имя файла в специальном формате.
RowList — список строк после импорта
На вход функции указывается имя файл, из которого будет осуществляться импорт, а также задается параметр, который определяет разделитель между полями. На выходе получаем (переменная RowList ) список вида:
[row(…, …, …), row(…, …, …), …]


2. Определение имени файла фактами

Это сделано чтобы впоследствии удобно было на него ссылаться.
file(base1, csv, 'c:/pl/prj1/file.csv').
file(base1, base, 'c:/pl/prj1/file.pl').


3. Определение базы фактов

:- dynamic(base1/3).

В эту базу мы будем добавлять факты.

4. Обнуление базы

abolish(base1/3).


5. Генерация базы из списка

Здесь также можно сделать предварительную обработку данных. Например выбрать только те поля, которые нужны. Предикат assert добавляет факт к базе.
perform_cl([]).
perform_cl([row(N1, N2, _, N3,_)|T]):-
       assert(base1(N1,N2,N3)),
       !,
       perform_cl(T).

Или
forall(member(row(N1,N2,N3),RowList), assert(base1(N1,N2,N3)).

Предикат forall является очень мощным. Для всех альтернатив поиска решения (1 параметр) он выполняет действие указанное вторым параметром.

6. Сохранение базы во внешний файл

  file(base1, base, F),
  tell(F),
  forall( base1(N1,N2,N3), (writeq( base1(N1,N2,N3)), write('.'), nl) ),
  told.


7. Загрузка базы фактов из файла

file(base1, base, F), Consult(F).

или
file(base1, base, F), [F].


Программа полностью:



% тестовая база фактов
%
:- dynamic(base1/3).

% соответствия файлов
%
% входной файл в формате CSV
file(base1, csv, 'c:/pl/prj1/file1.csv').
% база фактов
file(base1, base, 'c:/pl/prj1/file1.pl').

% импорт из csv файла и обработка
%
import_base:-
    % найти имя файла
    file(base1, csv, File),
    % импорт из файла c разделителем ";" в список [row(..., ..., ...), ...]
    csv_read_file(File, RowList, [ separator(0';)]),
    % очистить базу
    abolish(base1/3),
    % обработать и добавить факты
    perform_row1(RowList),!.

% обработка списка и добавление фактов
%
% список пуст - закончить поиск.
perform_row([]).
% выбрать голову списка
perform_row([row(N1, N2, _, N3,_)|T]):-
    % добавить факт, только нужные поля
    assert(base1(N1,N2,N3)),
    !,
    % обработать хвост списка
    perform_row(T).

% альтернативный вариант обработки списков
%
perform_row1(RowList):-
    % выполнить для всех альтернатив поиска: найти все элементы списка
    forall(member(row(N1, N2, _, N3,_),RowList),
          % добавить факт
          assert(base1(N1,N2,N3))).

% сохранить базу в файле
%
save_base:-
    % найти имя файла
    file(base1, base, F),
    % открыть файл, установить стандартный поток вывода в файл
    tell(F),
    % выполнить для всех альтернатив поиска: найти все факты
    forall( base1(N1,N2,N3),
        % печать факта
        (writeq( base1(N1,N2,N3)), write('.'), nl)
        ),
    told.

% загрузить базу фактов
%
load_base:-
    % найти файл
    file(base1, base, File),
    % загрузить
    consult(File).


Исходные данные

содержимое файла file1.csv
Петров Петр; 12; н/а; Лансер; каждый день
Сидоров Александр; 13; н/а; Ниссан; иногда
Тимофеев Игорь; 14; н/а; Лансер; каждый день


Протокол работы:

4 ?- import_base.
true.

5 ?- forall(base1(N1,N2,N3),writeln(base1(N1,N2,N3))).
base1(Петров Петр, 12, Лансер)
base1(Сидоров Александр, 13, Ниссан)
base1(Тимофеев Игорь, 14, Лансер)
true.

6 ?- save_base.
true.

7 ?- abolish(base1/3).
true.

8 ?- forall(base1(N1,N2,N3),writeln(base1(N1,N2,N3))).
ERROR: toplevel: Undefined procedure: base1/3 (DWIM could not correct goal)

9 ?- load_base.
% c:/pl/prj1/file1.pl compiled 0.00 sec, 492 bytes
true.

10 ?- forall(base1(N1,N2,N3),writeln(base1(N1,N2,N3))).
base1(Петров Петр, 12, Лансер)
base1(Сидоров Александр, 13, Ниссан)
base1(Тимофеев Игорь, 14, Лансер)
true.



Файл базы фактов file1.pl

base1('Петров Петр',' 12',' Лансер').
base1('Сидоров Александр',' 13',' Ниссан').
base1('Тимофеев Игорь',' 14',' Лансер').

Заключение

В данной статье приведена программа, которая демонстрирует некоторые подготовительные работы по созданию базы фактов не показывает настоящую мощь Пролога. Однако после импорта в базу фактов могут быть применены изящные методы обработки данных. Например контроль и визуализация иерархических структур (организационно — штатная структура), подготовка данных для биллинга, очистка (трансформация) данных в таблицах и другие.
Tags:
Hubs:
+2
Comments 4
Comments Comments 4

Articles