我正在研究一个事件处理框架,如果我有一种有效的方法来使用序数进行计算,那么可以对其进行改进。
在Java语法中,我正在寻找:
class Ordinal {
static int compare(Ordinal o1, Ordinal o2) { }
static Ordinal suc(Ordinal o) { }
static Ordinal add(Ordinal o1, Ordinal o2) { }
static Ordinal mul(Ordinal o1, Ordinal o2) { }
static Ordinal pow(Ordinal o1, Ordinal o2) { }
static Ordinal omega() { }
static Ordinal zero() { }
}
到目前为止,我所考虑的唯一方法是将可能的操作表示为数据,这很像将整数表示为链表,因此感觉不太好。
有谁知道这样的事情?
更多信息:
Ordinal numbers是一个数学概念,通常关注有序集合的概念,但我希望用它们来产生“不断变大”的数字
例如,1,2,3 ......都小于ω。那么ω+ 1,ω+ 2,....都小于2ω,小于3ω,......都小于ω²,小于ω³......都小于ω^ω,所以上。这就是为什么有效地表示它们似乎很棘手......简单的地方价值表示很快就会耗尽,并且又一次又一次又一次地耗尽。
我认为我希望在我的代码中有序数的原因是它们可以作为一种限制递归计算深度的方法,其中递归计算可以变得非常深,无限深,并且“超出“(如,超过ω)。考虑一个递归函数列表,其中第i个函数具有深度i,然后是在列表上进行折叠的函数...其深度是ω,但是我们可以再添加一个步骤,再一次,得到ω+ k,因此另一个倍数给出2ω,我们可以将这个过程推广到所需的ω²,依此类推。
现在,我想用序数计算的原因是,如果你用一个尊重拓扑排序和深度的序数标记DAG的节点,你可能想要做的一件事是执行一种图形搜索,按照其序号标记的递增顺序访问节点。我不是100%确定这是我希望我的代码工作的方式,但这是我正在考虑的一种方法,所以我想看看走这条路是否合理。它看起来越来越像我应该重新考虑我的方法,在这种情况下这个问题可能没有实际意义,但仍然有趣的好奇心。
答案 0 :(得分:0)
虽然这与语言无关,但我可以自由地展示如何在Java中执行此操作的建议,应该可以轻松转移到任何具有对象标识概念的语言。
class Ordinal {
private BigInteger value; // invariant: value is positive
// this is only used to construct omega once
private Ordinal() { value = BigInteger.ONE.negate(); }
public final static Ordinal omega = new Ordinal();
public Omega(BigInteger v) {
if (v.compareTo(BigInteger.ZERO) < 0) throw new IllegalArgumentException();
value = v;
}
public BigInteger value() {
if (this == omega) // .... throw exception?
else return value;
}
// example implementation of suc
// note that it'll never equal omega
// because omega is initialized with (-1)
// In addition, there is one and only one, non copyable omega.
public static Ordinal suc(Ordinal o) {
if (o==omega) then return omega;
else return new Ordinal(BigInteger.ONE.plus(o.value));
}
}
我们的想法是拥有一个不可复制的单例对象omega
,其值不能与任何其他值相等。
函数的实现需要标识omega
,这与引用相等检查一样简单。例如,在suc
中,我们suc omega
为omega
,否则加1。
答案 1 :(得分:0)
看起来像some work has been done on this topic in Agda。
我看起来不够深入,看它是否实际可用或主要是理论上的。