Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 32 из 135)

BitWise := proc(BO::symbol, n::nbinary) local a b c d k h, , , , , ; assign(a = length( )n , c = "", h = 0);

if not member(BO, {AND ADD OR NOR XOR NOT IMPL, , , , , , }) then error

"operation <%1> is different from {ADD, AND, OR, XOR, NOR, NOT, &bsol;

IMPL}", BO elif BO = NOT then

parse(cat(seq(`if`(k = "0" "1" "0", , ), k = convert(n, 'string'))))

else if 2 < nargs and type(args 3[ ], 'nbinary') then assign(b = length args[3]( ))

else error "3rd argument is absent or has a type different from nbinary" end if;

if a = b then assign(' 'a = "" || n, ' 'b = "" || args 3[ ]) elif a < b then assign(' 'b = "" || args 3[ ], ' 'a = cat(seq "0",( k = 1 .. b − a), n)) else assign(' 'a = "" || n, ' 'b = cat(seq "0",( k = 1 .. a − b), args 3[ ])) end if;

if BO = ADD then for k from length( )a by -1 to 1 do d := map(parse, {b k[ ], a k[ ]}); if d = {0, 1} then if h = 1 then c := cat("0", c) else assign(' 'c = cat "1",( c), ' 'h = 0) end if elif d = {1} then if h = 1 then c := cat "1",( c) else assign('c' = cat("0", c), 'h' = 1) end if else assign(' 'c = cat "",( parse(a k[ ]) + h c, ), ' 'h = 0) end if

end do; parse(c) elif BO = OR then parse( cat(seq(`if`([a k[ ], b k[ ]] = ["0" "0", ], "0" "1", ), k = 1 .. length(a)))) elif BO = NOR then parse( cat(seq(`if`([a k[ ], b k[ ]] = ["0" "0", ], "1" "0", ), k = 1 .. length(a))))

elif BO = XOR then parse(cat(seq( `if`([a k[ ], b k[ ]] = ["0" "0", ] or [a k[ ], b k[ ]] = ["1" "1", ], "0" "1" ,, ) k = 1 .. length(a)))) elif BO = AND then parse( cat(seq(`if`([a k[ ], b k[ ]] = ["1" "1", ], "1" "0", ), k = 1 .. length(a)))) else parse( cat(seq(`if`([a k[ ], b k[ ]] = ["1" "0", ], "0" "1", ), k = 1 .. length(a))))

end if

end if

end proc

> BitWise(ADD, 1001, 100101101), BitWise(NOT, 1001), BitWise(AND, 1001, 100101101),

BitWise(XOR, 100101101, 1001), BitWise(OR, 100101101, 1001), BitWise(IMPL, 1001, 1001); 100110110, 110, 1001, 100100100, 100101101, 1111

Вызов процедуры BitWise(BO, n {, m}) возвращает результат поразрядной операции ВО над бинарными числами n {и m}. При этом в качестве ВО выступают традиционные булевы операции {AND, OR, XOR, NOR, NOT, IMPL}, где IMPL обозначает implies-операцию; тогда как ADD – операция поразрядного сложения по mod 2.

Так модуль boolop [109] экспортирует ряд полезных функций/операторов, обеспечивающих базовые операции булевой алгебры, а именно:

&andB, &orB, &xorB, &notB, &impB

где, в частности, &andB – n-арная логическая функция/оператор and:

boolop:-&andB := proc(x::{0, 1}, y::{0, 1}) local a k, ; if nargs = 0 or nargs = 1 then error "actual arguments in single number or are absent"

elif nargs = 2 then if [x y, ] = [1, 1] then 1 else 0 end if else if type {( args 3 .. -1[ ]}, set {( 0, 1})) then a := procname(x y, ); for k from 3 to nargs do a := procname(a, args[ ]k ) end do; a

else error "arguments starting with 3rd should have binary type but had re&bsol; ceived %1" [, args 3 .. -1[ ]]

end if

end if

end proc

> with(boolop): 0 &andB 0, 1 &andB 1, 0 &andB 1, 1 &andB 0, `&andB`(1, 0, 1, 0, 1, 0);

0, 1, 0, 0, 0

Следующая процедура logbytes обеспечивает поддержку базовых логических операций {xor, and, or, not, implies} над последовательностями байтов типа {string, symbol}.

logbytes := proc(O::symbol) local a k j, , ; if nargs = 1 then error "number of arguments must be > 1" elif not member O, {( `and` `not` `or` `xor` `implies`, , , , }) then error "1st argu&bsol; ment must be {`and`,`or`,`xor`,`not`,`implies`} but has received <%1>O",

else a := { };

for k from 2 to nargs do if (proc( )x try type(x, {'symbol', 'string'}) and type(x, 'byte') catch : return false end try end proc ) args[ ]( k ) then next else a := {k, op( )a }

end if

end do end if; if a ≠ { } then error "arguments with numbers %1 must be bytes of type {string, symbol}", a

else a := map(Bit, [args 2 .. -1[ ]], [' 'k $ (' 'k = 1 .. 8)])

end if;

if O = `and` then xbyte1( [seq(boolop[boolop `&andB`:- ](seq(a k[ ][ ]j , k = 1 .. nops( )a )), j = 1 .. 8)]) elif O = `or` then xbyte1( [seq(boolop[boolop `&orB`:- ](seq(a k[ ][ ]j , k = 1 .. nops(a))), j = 1 .. 8)]) elif O = `xor` then xbyte1( [seq(boolop[boolop `&xorB`:- ](seq(a k[ ][ ]j , k = 1 .. nops(a))), j = 1 .. 8)]) elif O = `not` then xbyte1 [( seq(boolop[boolop `&notB`:- ](a[ ]1 [ ]j ), j = 1 .. 8)]) elif O = `implies` and 2 < nargs then xbyte1( [seq(boolop[boolop `&impB` :- ](seq(a k[ ][ ]j , k = 1 .. 2)), j = 1 .. 8)]) else 'procname(args)'

end if

end proc > logbytes(`and`, A,v,z, A,G,N, V,S,V), logbytes(`or`, A,v,z, A,G,N, V,S,V), logbytes(`xor`, A,v,z, A,G,N, V,S,V); ⇒ "@", "", "V"

Логические операции производятся над соответствующими битами байтов, определенных последовательностью аргументов, начиная со второго. Тогда как в качестве первого О-аргумента выступают указанные логические операции. Результат возвращается в виде байта в string-формате. При этом, предполагаются n-арные операции {`xor`,`and`,`or`}, бинарная операция `implies` и унарная `not`.

Рассмотренные в настоящем разделе средства Maple-языка по обеспечению решения задач математической логики и ее прикладных аспектов будут в различных контекстах использоваться при решении разнообразных иллюстративных и прикладных математических задач, в первую очередь при программировании логических компонент конструкций, управляющих вычислительным процессом в Maple-документах и программах (условные переходы, циклы и другие управляющие структуры).

Тестирующие функции, значительная часть которых рассмотрена выше, возвращают значение {true|false} в зависимости от {истинности|ложности} того или иного проверяемого логического условия (теста). И в этом смысле они могут входить в состав булевых выражений. Выше был рассмотрен целый ряд тестирующих функций, обеспечиваемых языком пакета. В дальнейшем оставшиеся функции данного типа будут представлены при обсуждении соответствующих приложений Maple-языка.

Здесь мы несколько расширим наше представление о концепции типов, поддерживаемой пакетом. Как уже отмечалось выше, базовыми тестирующими средствами являются функции type и typematch, а также процедура whattype. Третья из них возвращает поддерживаемый Maple тип указанного своим фактическим аргументом Maple-выражения, тогда как две первые возвращают {true|false}-значение в зависимости от {истинности| ложности} факта эквивалентности типа, указанного их первым фактическим аргументом (выражение) и их вторым фактическим аргументом – идентификатором типа, распознаваемого Maple-языком.

Все распознаваемые Maple-языком типы можно классифицировать на две группы: внешние (поверхностные) и вложенные. К первой группе относятся типы, для тестирования которых вполне достаточно информации о самом верхнем уровне структурного дерева тестируемого выражения. В качестве внешних Maple-язык расматривает следующие 66 типов выражений:

algebraic anything applied array boolean equation even float fraction function list

indexed integer laurent linear listlist logical mathfunc matrix moduledefinition odd monomial name negative nonnegative numeric point positive procedure radical

range rational relation RootOf rtable scalar SDMPolynom SERIES series set sqrt

string table taylor trig type uneval vector zppoly `!` `*` `+` `..` `.` `<=` `<>`

`<` `=` `and` `intersect` `minus` `module` `not` `or` `union` `^`

Большинство тестируемых вышеупомянутыми средствами Maple-языка типов относятся именно к первой группе – внешним типам. Типы, требующие для своего тестирования анализа (возможно рекурсивного) всего структурного дерева выражений, относятся ко второй группе – вложенным типам. В качестве вложенных Maple-язык рассматривает следующие 13 типов выражений, а именно:

algfun algnum appliable constant cubic expanded linear polynom quadratic quartic radfun radnum ratpoly

Все вышеперечисленные типы относятся к пакету Maple 10. Следует отметить, что константный тип относится ко второй группе, т.к. для его тестирования требуется анализ всего структурного дерева выражений на предмет отсутствия вхождения в него переменных компонент, т.е. х-компонент, для которых имеет место определяющее соотношение type(x,name) ⇒ true. В приводимых ниже примерах будут детализированы многие практические аспекты работы с типами при организации различных вычислительных конструкций, использующих функциональные средства Maple-языка.

По testeq-процедуре, имеющей формат кодирования testeq(A { {,|=} B}), производится стохастическое тестирование эквивалентности двух Maple-выражений либо эквивалентность заданного единственным фактическим аргументом выражения нулю. В случае установления факта эквивалентности возвращается true-значение, в противном случае – false-значение. При этом, false-значение является достоверным, тогда как значение true возвращается корректно с очень высокой степенью достоверности. В процессе тестирования процедура не только производит вычисления выражений-аргументов, но и их алгебраические преобразования и упрощения. При невозможности произвести тестирование возвращается FAIL-значение. Простой пример иллюстрирует вышесказанное:

> [testeq(sin(x)/cos(x), tan(x)), testeq(sin(x)^2 + cos(x)^2 - 1)]; ⇒ [true, true]

> [testeq(sqrt(-1) - I), testeq(x^2 + 4*x + 4, (x + 2)^2)]; ⇒ [true, true]

Весьма важной для задач формального анализа Maple-выражений представляется тестирующая match-процедура, имеющая следующий формат кодирования: match(<Выражение> = <Шаблон>, <Id>, '<Id_1>')

и возвращающая true-значение, если устанавливается соответствие структуры тестируемого, заданного первым аргументом, выражения указанному вторым аргументом функции шаблону по указанной ведущей Id-переменной. Шаблон представляет собой выражение по ведущей Id-переменной с формальными параметрами, на соответствие структуре которого и производится проверка выражения. Например, выражение z+a*x^2+b*x+c определяет шаблон квадратного трехчлена по ведущей х-переменной. В случае успешного тестирования в невычисленную Id_1-переменную помещается множество значений параметров шаблона, на которых он структурно эквивалентен тестируемому выражению. Следующий простой фрагмент иллюстрирует вышесказанное:

> [match(ln(Pi)/ln(x) + x^y = a/ln(x) + x^b, x, 'h'), h]; ⇒ [true, {b = y, a = ln(π)}] > [match(1942*sqrt(x) + 64^x - 10*y = a*x^d + b^x + c, x, 'h'), h];

[true, {a = 1942, d = 1/2, c = -10 y, b = 64}]

> [match(ln(z)*sqrt(x) + z^x - 10*y = a*x^b + c^x + d, x, ‘h’), h];

[true, {a = ln(z), c = z, d = -10 y, b = 1/2}]

> [match(ln(3*z/(1 + G(x)))*z + z^x - exp(y) = ln(a*z)*z + z^b + c, z, 'h'), h];

true, {c = −ey, a = 1 + G( )3 x , b = x}

> [match(sqrt(3 + 32/G(x))*z + z^ln(x) - z/exp(y) + 10 = a*z + z^b + c, z, 'p'), p];

true, c = 10, a = − − 3 GG( )x( )ex + y 32 ey + 1, b = ln( )x  

Механизм шаблонов, поддерживаемый match-процедурой, позволяет устанавливать точную структуру Maple-выражений на основе заданного структурного шаблона с формальными параметрами, вычисляя значения последних (если установлено соответствие тестируемого выражения шаблону) по принципу функционального уравнения. Между тем, успешное применение match-процедуры для структурного тестирования выражений предполагает представление их в алгебраическом виде. В противном случае match-процедура может необоснованно возвращать false-значение, например: