2018年9月3日Qubic开发状态更新

2018年9月3日Qubic开发状态更新

八月份的任务是整理Qubic编程语言Abra的细节。我们最终敲定了许多与语言语法相关的细节,并开始研究项目用户体验的设计。研究结果很有希望并巩固了我们的信念,即我们应该可以在2018年年底前后展示Qubic实现的概念验证。

我们还开始编写Qubic计算模型的文档。文档深入介绍了如何将Abra程序转换为我们称之为Handy的中间三进制数位代码(trit-code)表示。文档还将详细的说明代码如何与Qubic Dispatcher交互,Qubic Dispatcher是支持Qubic的节点上的Qubic任务和事件的调度程序。

Handy将Abra程序编码为一种紧凑的三进制表示,这样就可以轻松地将其打包到Qubic交易中并发布到Tangle上。Handy会在打包之前对Abra程序中的所有错误进行语法检查和标记,这意味着任何后期处理工具(比如Qubic Dispatcher)都不再需要重复这个操作。

Qubic Dispatcher在支持qubic的节点上运行,并将Qubic trit-code转换为它的目标架构。Dispatcher还将侦听触发qubics的事件,并将其传递给这些qubics以进行进一步处理。Qubic代码的处理与dispatcher紧密的交织在一起,文档会对此进行详细说明。

完成Qubic计算模型文档的编写是规划中的下一个目标。Abra语法以及与dispatcher的交互是它的两个主要部分。

另一个应该同时准备好的文档是与Qubic背后的数学有关的论文。初始布局已经完成,我们现在正在填充各部分的内容。

与此同时,Abra编译器的工作进展顺利。我们目前正在将最新修订纳入到语言中,并将在下一个版本中完成LLVM代码生成。完成后,我们就可以运行和测试简单、直接的Abra代码。之后将创建dispatcher,代码和dispatcher之间的整体交互应该可以支持创建和测试更复杂的程序。

同时还在对FPGA实现展开研究,以便我们的设计过程始终牢记这一点:我们的关注重点是物联网的节能分布式计算。

出于这个关注重点,我们决定在可以完整的运行qubics之前,推迟对gateway概念(用于使用Qubic转移资金)的进一步研究。这样的gateway首先需要一个可完整运行的系统,然后才能实现和测试它们。

我们还开始为Qubic开发团队寻找新的成员,因为我们认为团队的总体规划已经足够稳定了。我们认识到:人们可以同时致力于项目的不同部分,且不会相互妨碍。

总之,这是一个激动人心的月份,充满了各种见解,我们对Qubic项目的热情与日俱增。

一些Abra示例:

// sample Abra type definitions
// define some standard trit lengths we will use in our examples
// note that you can define the optimal size for any type's range
// to reduce energy requirements accordingly
Trit [1]; // -1 to +1
Tryte [3]; // -13 to +13
Short [9]; // -9,841 to +9,841
Int [27]; // -3,812,798,742,493 to +3,812,798,742,493
Long [81]; // -2.217...e+38 to +2.217...e+38
Hash [243];
State [729];
// convenience type to make code more clear
// supposed to always contain a binary boolean value 0 (false) or 1 (true)
// should never be null or have the value - (convention not enforced by Abra)
Bool [Trit];
// here's how to define a named structured trit vector
// it consists of the concatenation of all sub-vectors
// its size is the sum of all sub-vector sizes
// IOTA transaction layout
Transaction {
signature [27 * Hash]
, extradatadigest [Hash]
, address [Hash]
, value [Long]
, issuancetimestamp [Int]
, timelocklowerbound [Int]
, timelockupperbound [Int]
, bundle [Long]
, trunk [Hash]
, branch [Hash]
, tag [Long]
, attachmenttimestamp [Int]
, attachmenttimestamplowerbound [Int]
, attachmenttimestampupperbound [Int]
, nonce [Long]
};
// sample Abra look-up tables
// these are a look-up tables, or LUTs
// a LUT describes for each combination of input trits what the resulting output trits will be
// any missing explicitly defined combinations will cause the resulting output to be null
// if any input to a LUT is null, the result will be null as well,
// so we only need to specify combinations of non-null input values
// ************* BINARY OPERATORS *************
// LUT logic: binary NOT
// return !trit1;
not [
0 = 1;
1 = 0;
];
// LUT logic: binary AND
// return (trit1 & trit2);
and [
0,0 = 0;
0,1 = 0;
1,0 = 0;
1,1 = 1;
];
// LUT logic: binary OR
// return (trit1 | trit2);
or [
0,0 = 0;
0,1 = 1;
1,0 = 1;
1,1 = 1;
];
// LUT logic: binary XOR
// return (trit1 ^ trit2);
xor [
0,0 = 0;
0,1 = 1;
1,0 = 1;
1,1 = 0;
];
// LUT logic: binary NAND
// return !(trit1 & trit2);
nand [
0,0 = 1;
0,1 = 1;
1,0 = 1;
1,1 = 0;
];
// LUT logic: binary NOR
// return !(trit1 | trit2);
nor [
0,0 = 1;
0,1 = 0;
1,0 = 0;
1,1 = 0;
];
// LUT logic: binary XNOR
// return !(trit1 ^ trit2);
xnor [
0,0 = 1;
0,1 = 0;
1,0 = 0;
1,1 = 1;
];
// ************* TERNARY OPERATORS *************
// LUT logic: return the negative value of the input trit
// return -trit1;
/ note that making an entire trit-vector value negative
// can be done by simply negating every trit in the vector
neg [
- = 1;
0 = 0;
1 = -;
];
// LUT logic: return a boolean indicating whether the two input trits are equal
// return (trit1 == trit2);
equal [
-,- = 1;
-,0 = 0;
-,1 = 0;
0,- = 0;
0,0 = 1;
0,1 = 0;
1,- = 0;
1,0 = 0;
1,1 = 1;
];
// LUT logic: return a boolean indicating whether the two input trits are unequal
// return (trit1 != trit2);
unequal [
-,- = 0;
-,0 = 1;
-,1 = 1;
0,- = 1;
0,0 = 0;
0,1 = 1;
1,- = 1;
1,0 = 1;
1,1 = 0;
];
// LUT logic: when (boolean) trit1 equals 1 return trit2 else return trit3
// return trit1 ? trit2 : trit3;
unequal [
0,-,- = -;
0,-,0 = 0;
0,-,1 = 1;
0,0,- = -;
0,0,0 = 0;
0,0,1 = 1;
0,1,- = -;
0,1,0 = 0;
0,1,1 = 1;
1,-,- = -;
1,-,0 = -;
1,-,1 = -;
1,0,- = 0;
1,0,0 = 0;
1,0,1 = 0;
1,1,- = 1;
1,1,0 = 1;
1,1,1 = 1;
];
// LUT logic: return the 2rd input trit only when 1st input trit equals 1 (true)
// return (trit1 == 1) ? trit1 : null;
nullOrTrit [
1,0 = 0;
1,1 = 1;
1,- = -;
];
// sample Abra functions
// this is a function that takes a trit vector of State [729],
// but we don't need to constantly repeat that size since we
// already established the size at the top of the file
digest(state [State]) =
// a function returns the value of its last statement,
// which in this case is a concatenation (comma operator)
// of the input state and the result of the transform() function
state, transform(state, 81);
// note that this function does not need curly braces around its single statement
// curly braces are only necessary when grouping multiple statements
// construct functions for all predefined types that perform
// a similar task to the nullOrTrit LUT for those larger types
// note that we have defined each successive type a factor 3 times bigger
// which means we can easily define each successive type in terms of the previous one
// every nullOrXxx function returns <val> when <t> equals 1 (true), and null otherwise
// note that it may seem wasteful to define it this way, but when mapped to FPGA
// these can be translated into parallel circuitry that executes them simultaneously.
// for other architectures, Abra will allow the Abra functions to be replaced with
// a dll function that uses optimal architecture-specific instructions.
// we expect a library of common functions to be developed over time
nullOrTryte(t [Bool], val [Tryte]) = {
// concatenate the 3 separate trits via the LUT
nullOrTrit[t, val[0]],
nullOrTrit[t, val[1]],
nullOrTrit[t, val[2]];
};
nullOrShort(t [Bool], val [Short]) = {
// concatenate the 3 separate trytes via the previous function

// note the notation to easily specify a subrange of a trit vector
// we will start at N times the size of Tryte and have an open ended range
// which specifies to take whatever amount necessary to pass to the underlying parameter
nullOrTryte(t, val[0 * Tryte..]),
nullOrTryte(t, val[1 * Tryte..]),
nullOrTryte(t, val[2 * Tryte..]);
};
nullOrInt(t [Bool], val [Int]) = {
// concatenate the 3 separate shorts via the previous function
nullOrShort(t, val[0 * Short..]),
nullOrShort(t, val[1 * Short..]),
nullOrShort(t, val[2 * Short..]);
};
nullOrLong(t [Bool], val [Long]) = {
// concatenate the 3 separate ints via the previous function
nullOrInt(t, val[0 * Int..]),
nullOrInt(t, val[1 * Int..]),
nullOrInt(t, val[2 * Int..]);
};
nullOrHash(t [Bool], val [Hash]) = {
// concatenate the 3 separate longs via the previous function
nullOrLong(t, val[0 * Long..]),
nullOrLong(t, val[1 * Long..]),
nullOrLong(t, val[2 * Long..]);
};
nullOrState(t [Bool], val [State]) = {
// concatenate the 3 separate hashes via the previous function
nullOrHash(t, val[0 * Hash..]),
nullOrHash(t, val[1 * Hash..]),
nullOrHash(t, val[2 * Hash..]);
};
// sample old Curl implementation in Abra, just for fun
transform(state [State], round [Short]) = {
// assume subXxx() is a function that performs subtraction on trit vectors of size X
// and also returns a trit vector size X
roundMinusOne = sub9(round, 1);
// assume equalXxx() is a function that performs comparison on trit vectors of size X
// and returns a trit containing a binary boolean value of 0 (false) or 1 (true)
roundZero = equal9(roundMinusOne, 0);
// calculate the new state for this round
newState = curlRound(state);

// here comes the interesting part, we're going to use a merger operation,
// which is an operation that returns the single operand that is non-null
// note that a merger will fail when multiple operands are non-null
// this line will return newState when roundMinusOne was determined to be zero
// and null otherwise
stateOut = nullOrState(roundZero, newState);
// this line will return newState when roundMinusOne was determined to be non-zero
// and null otherwise
stateNext = nullOrState(not[roundZero], newState);
// this line will only return roundMinusone when it was non-zero and otherwise returns null
roundNext = nullOrShort(not[roundZero], roundMinusOne);
// recursively call transform to execute the next round
// note that this will only execute if either of stateNext and roundNext are non-null
// otherwise it will not execute and a null return value is assumed
// so this is essentially a conditional execution
stateFinal = transform(stateNext, roundNext);
// merge the two branches by returning the one that is non-null
// so this is kind of an implied if-then-else, because it will
// either return stateOut or stateFinal
stateOut \ stateFinal;
};
// now follows the actual implementation of a single Curl round
// LUT logic: curl the 2 input trits onto an output trit
curl [
-,- = 1;
-,0 = 0;
-,1 = -;
0,- = 1;
0,0 = -;
0,1 = 0;
1,- = -;
1,0 = 1;
1,1 = 0;
];
// a very dumb and straightforward implementation that curls all 729 state trits
curlRound(s [State]) = {
// we use the curl LUT for each of the 729 individual pairs of trits,
// and concatenate the resulting trits into a 729 trit return value
curl[s[ 0], s[364]],
curl[s[364], s[728]],
curl[s[728], s[363]],

// ... snipped 723 more lines like this ...

curl[s[366], s[ 1]],
curl[s[ 1], s[365]],
curl[s[365], s[ 0]];
};

 

原文链接:https://blog.iota.org/qubic-status-update-september-3rd-2018-f981bdfd8f26

inhuman

专栏作者:inhuman

个人简介:我共发表了 189 篇文章,总计被阅读了107,847 次,共获得了 1,584 个赞。

作者邮箱 作者主页 Ta的文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注