《编程原本 》一2.1 变换

    xiaoxiao2022-05-25  203

    2.1 变换

    虽然从任意一组类型到任意类型的函数都存在,但是有些具有特殊签名的函数类更为常用.本书中经常用的是两类函数:同源谓词和同源运算.同源谓词在形式上都是Tו••× T → bool;同源运算都是形如Tו••× T → T的函数.一般而言存在着任意的n元谓词和n元运算,但实际中遇到最多的还是一元和二元的同源谓词,一元和二元的同源运算.谓词是返回真值的函数:

    Predicate(P).FunctionalProcedure(P)∧Codomain(P)=bool

    同源谓词也是同源函数:

    HomogeneousPredicate(P). Predicate(P)∧HomogeneousFunction(P)

    一元谓词只有一个参数:

    UnaryPredicate(P).Predicate(P)∧UnaryFunction(P)

    运算是同源函数,其值域与作用域相同:

    Operation(Op).HomogeneousFunction(Op)∧Codomain(Op)=Domain(Op)

    下面是几个同源运算的实例:

    int abs(int x) { if (x < 0) return -x; else return x; } //一元运算 double euclidean norm(double x, double y) { return sqrt(x * x + y * y); } //二元运算 double euclidean norm(double x, double y, double z) { return sqrt(x * x + y * y + z * z); } //三元运算

    引理2.1euclidean_norm(x,y,z)=euclidean_norm(euclidean_norm(x,y),z)这一引理说明上面的三元运算可以从相应的二元版本得到.但是,由于效率,表达方便,或者准确性等原因,这样的三元运算也可以纳入处理三维空间的程序的计算基.

    如果一个过程的定义空间是其输入类型的直积的子集,就称该过程为部分的(partial);如果其定义空间等于其输入类型的直积,则说它是全的.按标准的

    数学习惯,我们也认为部分过程包括全过程,并称那些不是全的部分过程为非全的(nontotal).由于计算机表示的有穷性,有些全函数在计算机里的实现却是非全的.例如,有符号的32位整数加法就是非全的.

    一个非全过程需要有一个描述其定义空间的前条件.要验证对这个过程的一个调用是正确的,必须确定所给的实参满足这一前条件.有时我们会把部分过程作为参数传给一个算法,因此需要在运行时确定这种过程参数的定义空间问题.为了处理这类情况,我们将定义一个定义空间谓词(de.nitionspacepredicate),它与这一过程参数的输入相同,当且仅当实际输入在这个过程的定义空间里时,让这个谓词返回真.在调用一个非全过程之前,或者其前条件必须满足,或者该调用是用这个过程的定义空间谓词保护的.

    练习2.1请为32位有符号整数的加法实现一个定义空间谓词.本章研究一元运算,我们称其为变换(transformation):

    Transformation(F). Operation(F) ∧UnaryFunction(F) ∧DistanceType:TransformationInteger →

    这里的DistanceType将在下一节讨论.变换可以自组合(selfcomposable),例如可以写f(x),f(f(x)),f(f(f(x))),等等.f(f(x))的定义空间是f的定义空间和结果空间的交.这种自组合能力和检查相等能力的结合,使我们可以定义许多有趣的算法.设f是一个变换,它的幂(power)定义如下:

    . .x if n = 0, fn(x)=. .fn.1(f(x))ifn>0 .

    要实现计算fn(x)的算法,就要描述对一个整数类型的需求.第5章将研究描述与整数有关的一些概念,现在我们暂时依靠对整数的一些直观理解.有符号和无符号的整数类型都是整数的模型,还有任意精度的整数等,它们都包含下面的运算和文字量:18 第2 章变换及其轨道

    其中的I是一个整数类型. 这样就可以写出下面算法:

    template requires(Transformation(F) && Integer(N)) Domain(F) power unary(Domain(F) x, N n, F f) { // 前条件: n . 0 ∧ (.i ∈ N) 0 while (n != N(0)) {n = n -N(1);x = f(x);} return x; }

    相关资源:编程原本(中文版)

    最新回复(0)