Шаг 53.
Основы логического программирования.
Запись и чтение

    На этом шаге мы рассмотрим стандартные предикаты ввода/вывода.

    Рассмотрим стандартные предикаты, предназначенные для ввода и вывода информации.

Запись

    В Пролог включены три стандартных предиката для вывода. Это:

    Предикат write может быть вызван с произвольным числом аргументов:

   write(Param1,Param2,Param3,...,ParamN) % (i,i,i,...,i)

    Эти аргументы могут быть либо константами из стандартных доменов, либо переменными. Если это переменные, то они должны быть входными параметрами.

    Стандартный предикат nl (от англ. new line - новая строка) всегда используется вместе с предикатом write. Он обеспечивает переход на новую строку на экране дисплея. Например, следующие подцели:

  pupil(PUPIL,CL),
  write(PUPIL,"is in the",CL,"class"),
  nl,
  write("----------------------------").
могут привести к выводу на экран такого результата:
   Helen Smith is in the fourth class
   ------------------------------,
а цель:
   ....,
   write("List1=  ",L1,",List2=  ",L2)
может дать:
   Listl=[cow,pig,rooster],List2=[1,2,3].
    В свою очередь, если My_sentence связана с записью
   sentence(subject(john),sentence_verb(sleeps)) 
то, выполняя следующую программу:
   domains
      sentence=sentence(subject,sentence_verb)
      subject=subject(symbol); .....	
      sentence_verb=sentence_verb(verb); ...... 
      verb=symbol	
  clauses
      ......
      write( " SENTENCE= ",My_sentence).
вы сможете увидеть на дисплее:
   SENTENCE=sentence(subject(john),sentence_verb(sleeps))

    Обратите внимание на наличие в строках обратного слэша (\). Это управляющий символ. Чтобы напечатать непосредственно символ \ (обратный слэш), вы должны ввести два обратных слэша подряд. Например, для порождения строки пути к файлу в DOS A:\PROLOG\MYPROJS\MYFILE.PRO в программе на Прологе нужно ввести a:\\prolog\\myprojs\\myfile.pro.

    За обратным слэшем может следовать какой-либо из специальных символов управления печатью:

    Также за обратным слэшем могут следовать до трех десятичных цифр, задающих специальный код ASCII. Однако не следует вставлять последовательность \0 в строку, если в этом нет необходимости. Пролог использует те же соглашения относительно строк, завершающихся нулем, что и язык С.

    Предикат write сам по себе не предоставляет всю полноту функций управления печатью для таких сложных объектов, как, например, списки, но написать программы, которые вам их предоставят, просто. Следующие три небольших примера демонстрируют эти возможности.

Примеры использования предиката write

    Эти примеры показывают, как можно использовать предикат write для того, чтобы получить возможность выводить на печать такие объекты, как списки и сложные структуры данных.

  1. Следующая программа печатает список без открывающей [ и закрывающей ] квадратных скобок.
       domains
          integerlist=integer*
          namelist=symbol*
       predicates
          writelist(integerlist) 
          writelist(namelist).
       clauses
          writelist([]).
          writelist([H|T]):-
             write(H,"   "),
             writelist(T).
    
        Текст этой программы можно взять здесь.

        Обратите внимание, как эта программа использует рекурсию для обработки списка. Попробуйте ввести в программу и исполнить такую цель:

       writelist([1,2,3,4]).
    
  2. В следующем примере программа выводит элементы списка не более чем по пять элементов на строке.
       domains
          integerlist=integer*
       predicates
          writelist(integerlist) 
          write5(integerlist,integer).
       clauses
          writelist(NL):-
             nl, 
             write5(NL,0),nl.
          write5(TL,5) :-!,
             nl,
             write5(TL,0).
          write5([H|T],N):-!,
             write(H,"   "),
             N1=N+1,
             write5(T,N1).
          write5([],_).
    
        Текст этой программы можно взять здесь.

        Если вы дадите программе такую цель

       writelist([2,4,6,8,10,12,14,16,18,20,22]).
    
    Пролог ответит
    2   4   6  8   10
    12   14   16  18  20
    22
    
  3. Пример предиката, который выводит сложные структуры данных в более удобном для чтения виде, приведен в программе, расположенной ниже. Программа выводит объекты типа
       plus(mult(x,number(99)),mult(number(3),x))
    
    в виде

        x*99+3*x

    Это называется инфиксной записью.
       domains
          expr=number(integer); x; log(expr);
          plus(expr, expr); mult(expr, expr)
       predicates
          writeExp(expr)
       clauses
          writeExp(x):-
             write(x1).
          writeExp(number(No)):-
             write(No). 
          writeExp(log(Expr)). -
              write("log ("),
              writeExp(Expr),
              write (')').
          writeExp(plus(U1, U2)):-
              writeExp(Ul),
              write('+'),
              writeExp(U2).
         writeExp(mult(U1,U2)):-
              writeExp(U1),
              write('*'),
              writeExp(U2).
       goal
          writeExp(plus(mult(x,number(99)),mult(number(3),x))),nl.
    
        Текст этой программы можно взять здесь.

    На следующем шаге мы рассмотрим предикат writef.




Предыдущий шаг Содержание Следующий шаг