3

Доброго дня.
Мне нужно написать программу на прологе, которая меняла бы участки выражения на эквивалентные по правилу де Моргана.
Сложность в том, что программа получает в качестве аргумента темр состоящий из функторов, которые в свою очередь содержат еще функторы.
Т.е. выражение вида ~(A v B) & (~(A & C) v D & B) подается в программу как
&(~(v(A,B)),v(~(&(A,C)),&(D,B))).
Однако у меня не выходит получить результат.

transform( ~ (XX & YY), ~XX v ~YY).
transform( ~ (XX v YY), ~XX & ~YY).

exp_transform(Term, Result_Term):-
  var(Term), var(Result_Term).

exp_transform(Term, Result_Term):-
  arg(_, Term, Value_Basic),
  arg(_, Result_Term, Value_of_ResTerm),
  exp_transform(Value_Basic, Value_of_ResTerm).

exp_transform(Term, Result_Term):-
  transform(Term, Result_Term),
  exp_transform(Term, Result_Term).

Перебирал различные варианты. Можете подсказать в чем заключается проблема? Как подавать и обрабатывать выражение?

Volv58
  • 45

1 Answers1

1

Как подавать и обрабатывать выражение?

Я, пожалуй, упроcтил бы синтаксис, заменив операторы обычными функторами

~ -> not,

& -> and,

v -> or.

 % Упростить булеву функцию    
reduce( X, Y ) :-
     transform( X, Y ), !.
 % Не упрощается, остаётся сама собой
reduce( X, X ).


% Двойное отрицание
transform( not( not( X )), X ).
% De Morgan 
transform( not( and( X, Y )), or( not( X ), not( Y ))).
% De Morgan 
transform( not( or( X, Y )), and( not( X ), not( Y ))).
% ......

Я использую SWI-Prolog. 
  • 1
    Благодарю за ответ.
    Однако программа изменяет в небольшие выражения, если ввести
    ~((x v z) & (x v y)) & (~(x & y) v t & u) как
    and(not((and(or(A,C), or(A,B)))), or(not(and(A,B)),and(D, E)), то программа выведет исходный терм т.к. не видит подвыражения.
    Я пытался решить эту проблему с помощью arg(), увы не вышло
    – Volv58 May 20 '17 at 02:52
  • @Volv58 если моё упрощение создает проблемы, то используйте Вашу нотацию, и всё! :) – Anton Danilov May 20 '17 at 11:05
  • Выражения можно также перекодировать на лету ( и обратно, если надо ), но, думаю, это лишнее. Если Вас всё-таки это заинтересовало, дайте знать. – Anton Danilov May 20 '17 at 19:38
  • Я справился с задачей, взяв за основу предложенное вами решение. transform( XX & YY v ZZ, (XX v ZZ) & (YY v ZZ)). transform( XX v YY & ZZ, (XX v YY) & (XX v ZZ)). transform( XX v YY, XX1 v YY):- transform( XX, XX1). transform( XX v YY, XX v YY1):- transform( YY, YY1). transform( XX & YY, XX1 & YY):- transform( XX, XX1). transform( XX & YY, XX & YY1):- transform( YY, YY1). – Volv58 May 21 '17 at 15:12
  • Хорошо, только мне казалось что представление transform в виде фактов удобнее - не надо копировать одни и те же тела правил. Может быть я ошибся с reduce ? – Anton Danilov May 21 '17 at 18:48
  • btw arg(_, Term, Value_Basic), arg(_, Result_Term, Value_of_ResTerm), некорректно. Я не помню - arg(-,+,+) валидный режим для arg/3. В любом случае _ - это не имя, а обозначение анонимной переменной . Они разные и не передают значений. т.е. их надо заменить на норм. переменные. – Anton Danilov May 21 '17 at 19:12