Управление файловым потоком PROLOG; срок извлечения для обработки

Управление файловым потоком PROLOG

Я работаю над подсистемой рассуждений на основе прецедентов для академического консультирования, которая может взять новый профиль студента (стенограмму) и сравнить его с базой данных student_profiles, чтобы найти наилучшее соответствие, если не точное совпадение.

Я все еще не очень хорошо знаком с языком, и я пытаюсь открыть файл и извлечь определенный предикат, скажем

student_profile/4 : student_profile(L1, name, L2, L3)

который находится в student.pl.

После того, как я извлек предикат из файла .pl, я хочу иметь возможность присвоить его переменной и разделить его, чтобы я мог извлечь первый аргумент (в данном случае L1) для выполнения некоторых вычислений.

Вот что у меня есть на данный момент:
Я открыл файл и могу увидеть весь список предикатов, найденных в профиле учащегося или стенограмме.

load :- open('h:/AAS/Novel_Profiles/vivian.pl', read, Stream),
        read(Stream, X),
        read_data(Stream, X, StudentP),
        write(StudentP),
        close(Stream).

read_data(_Stream, end_of_file, []) :- !.

read_data(Stream, X, [X|StudentP]) :-
    read(Stream, Y),
    read_data(Stream, Y, StudentP).

Я искал примеры того, как извлечь термин и использовать его для дальнейшей обработки, но мне не повезло (или, может быть, я использую неправильную терминологию).

Любая помощь будет принята с благодарностью.


person user1308665    schedule 02.04.2012    source источник


Ответы (1)


Ваш предикат load должен "возвращать" прочитанный список или кэшировать его с помощью assertz для последующего использования...

load(StudentData) :- open('h:/AAS/Novel_Profiles/vivian.pl', read, Stream),
        read(Stream, X),
        read_data(Stream, X, StudentData),
        write(StudentP),
        close(Stream).

затем вы можете использовать member/2 для сопоставления некоторой записи в загруженном списке...

?- load(L),
   member(student_profile(Student, vivian, L2, L3), L),
   writeln(vivian(Student, L2, L3)).

Но есть более простой способ: consult файл и напрямую запрашивать данные.

load :- consult('h:/AAS/Novel_Profiles/vivian.pl').

Оба метода (чтение или консультация) требуют, чтобы ваш файл был синтаксически правильным. Ваш Пролог сообщит вам о любой проблеме, которая может возникнуть в файле.

После успешного консультирования каждый факт (или правило) готов к использованию...

?- student_profile(Student, vivian, L2, L3),
   writeln(vivian(Student, L2, L3)).
person CapelliC    schedule 02.04.2012
comment
Спасибо за ваш быстрый ответ, будет ли применяться та же процедура, если я хочу запросить данные из программы? Например, добавить что-то подобное перед закрытием потока member_sp(StudentPred,StudentData) и, конечно же, определить его внизу? - person user1308665; 03.04.2012
comment
Да, такие интерпретаторы, как Prolog, используют REPL (Read, Eval, Print, Loop) как общий метод разработки программ. - person CapelliC; 03.04.2012
comment
Спасибо за помощь, еще кое-что, что я хотел бы спросить. Это может показаться очень простым, но я не совсем понимаю. Как только я прочитал файл; данные, которые мне нужны, имеют форму составного термина: [student_predicate([2d vector],vivian,[пройдено(курсы),...],[])|_A]. Есть ли способ, которым структура термина может быть сокращена и назначена отдельным переменным для обработки, например: V = [Вектор], Имя = vivian, Курсы = [взятые (курсы),...], Рекомендации = [] ? Я хочу сделать это из скрипта. Я смотрел на (unvi) =../2 и functor/3 - person user1308665; 04.04.2012
comment
univ это более простой способ дизассемблировать термины, но много раз такая «дизассемблирование» выполняется на уровне предложений. Сопоставление с образцом (т. е. выбор условия для применения) управляется данными и позволяет вам управлять тем, как вы используете свои данные. Извините, я не совсем понял ваш последний вопрос... Что вы будете делать после того, как разберете student_profile? Вы теряете контекст... - person CapelliC; 04.04.2012
comment
Мой план после того, как я разобрал student_profile, состоит в том, чтобы использовать первый аргумент для вычисления евклидова расстояния и сравнить его с базой данных профилей учащихся (еще один файл, содержащий 47 похожих предикатов), чтобы найти наиболее близкое совпадение и получить такие похожие профили учащихся. . У меня возникли проблемы с тем, что после того, как я прочитал файл, я не знаю, как извлечь конкретный предикат (student_profile/4) из такого файла. Я буду повторять эту процедуру с несколькими другими профилями, помимо Вивиан, и я работаю над процедурой, чтобы сделать это. Я почти уверен, что это что-то действительно простое .. - person user1308665; 06.04.2012