FlowStandard now works with HashPoints

This commit is contained in:
AF 2022-07-14 15:20:58 +03:00
parent 31284ca4b4
commit 9a53ce5234
15 changed files with 327 additions and 146 deletions

View File

@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="plot" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="rainbowadn" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/plot.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="trace_flow" type="PythonConfigurationType" factoryName="Python" singleton="false">
<module name="rainbowadn" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/trace_flow.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

View File

@ -18,13 +18,17 @@ def plot(fn: str):
plt.rcParams['figure.figsize'] = [16, 9] plt.rcParams['figure.figsize'] = [16, 9]
plt.style.use('dark_background') plt.style.use('dark_background')
plt.subplots_adjust(left=0.05, right=0.99, top=0.95, bottom=0.05) plt.subplots_adjust(left=0.05, right=0.99, top=0.95, bottom=0.05)
plt.title(fn)
plt.xlabel('time (s)') plt.xlabel('time (s)')
plt.ylabel('concurrency (1)') plt.ylabel('concurrency (1)')
with open(fn) as file: with open(fn) as file:
jsonified: dict[str] = json.load(file) jsonified: dict[str] = json.load(file)
title = fn
if (params := jsonified.pop('params', None)) is not None:
title += f' {":".join(map(str, params))}'
plt.title(title)
def logplot(plot_function, metric: str, **kwargs): def logplot(plot_function, metric: str, **kwargs):
if (log := jsonified.pop(metric, None)) is not None: if (log := jsonified.pop(metric, None)) is not None:
plot_function(*plottable(log), label=f'{metric} ({len(log)})', **kwargs) plot_function(*plottable(log), label=f'{metric} ({len(log)})', **kwargs)

View File

@ -61,10 +61,6 @@ def gather(
) -> Awaitable[tuple[T0, T1, T2, T3, T4]]: ... ) -> Awaitable[tuple[T0, T1, T2, T3, T4]]: ...
@overload
def gather(*args): ...
def gather(*args): def gather(*args):
return _gather(*args) return _gather(*args)

View File

@ -2,6 +2,7 @@ from typing import TypeAlias
from rainbowadn.collection.pair import * from rainbowadn.collection.pair import *
from rainbowadn.core import * from rainbowadn.core import *
from rainbowadn.flow.core import *
from rainbowadn.flow.verification.core import * from rainbowadn.flow.verification.core import *
from rainbowadn.nullability import * from rainbowadn.nullability import *
from ._bankflow import * from ._bankflow import *
@ -47,17 +48,63 @@ class BankBlock:
async def add(self, cheque: FlowCheque) -> 'BankBlock': async def add(self, cheque: FlowCheque) -> 'BankBlock':
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
previous_link: Nullable[Pair[FlowCheque, FlowBank]] = await FlowBlock.link_of(self.reference) return await AddCheque(cheque).map(self)
assert isinstance(previous_link, Nullable)
previous_bank: Nullable[FlowBank]
if previous_link.null(): class AddCheque(
previous_bank = Null() Mapper[BankBlock, BankBlock]
else: ):
previous_bank = NotNull(await (previous_link.resolve()).element1.resolve()) def __init__(self, cheque: FlowCheque):
assert isinstance(previous_link, Nullable) assert isinstance(cheque, FlowCheque)
bank: FlowBank = await self.flow().add(previous_bank, cheque) self.cheque = cheque
@classmethod
async def _bank_for_link(cls, link: Nullable[Pair[FlowCheque, FlowBank]]) -> Nullable[FlowBank]:
assert isinstance(link, Nullable)
return Null() if link.null() else NotNull(await (link.resolve()).element1.resolve())
async def _next_bank_for_bank(self, bank: Nullable[FlowBank]) -> FlowBank:
return await BankBlock.flow().add(bank, self.cheque)
async def _link_for_bank(self, bank: FlowBank) -> HashPoint[Pair[FlowCheque, FlowBank]]:
assert isinstance(bank, FlowBank) assert isinstance(bank, FlowBank)
link: Pair[FlowCheque, FlowBank] = Pair(HashPoint.of(cheque), HashPoint.of(bank)) return HashPoint.of(Pair(HashPoint.of(self.cheque), HashPoint.of(bank)))
block: FlowBlock[Pair[FlowCheque, FlowBank]] = await FlowBlock.add_to(self.reference, HashPoint.of(link))
assert isinstance(block, FlowBlock) async def _next_link_for_link(
return BankBlock(NullableReference.off(block)) self, link: Nullable[Pair[FlowCheque, FlowBank]]
) -> HashPoint[Pair[FlowCheque, FlowBank]]:
assert isinstance(link, Nullable)
return await self._link_for_bank(
await self._next_bank_for_bank(
await self._bank_for_link(link)
)
)
@classmethod
async def _add_link_to_reference(
cls,
link: HashPoint[Pair[FlowCheque, FlowBank]],
reference: NullableReference[FlowBlock[Pair[FlowCheque, FlowBank]]],
) -> BankBlock:
assert isinstance(link, HashPoint)
assert isinstance(reference, NullableReference)
return BankBlock(NullableReference.off(await FlowBlock.add_to(reference, link)))
async def _add_to_link(
self,
previous: Nullable[Pair[FlowCheque, FlowBank]],
reference: NullableReference[FlowBlock[Pair[FlowCheque, FlowBank]]],
) -> BankBlock:
assert isinstance(previous, Nullable)
assert isinstance(reference, NullableReference)
return await self._add_link_to_reference(await self._next_link_for_link(previous), reference)
async def _add_to_reference(
self,
reference: NullableReference[FlowBlock[Pair[FlowCheque, FlowBank]]],
) -> BankBlock:
assert isinstance(reference, NullableReference)
return await self._add_to_link(await FlowBlock.link_of(reference), reference)
async def map(self, element: BankBlock) -> BankBlock:
return await self._add_to_reference(element.reference)

View File

@ -16,7 +16,9 @@ __all__ = ('BankFlow',)
class BankFlow( class BankFlow(
Verification[tuple[Nullable[FlowBank], FlowCheque, FlowBank]], Verification[
tuple[Nullable[HashPoint[FlowBank]], HashPoint[FlowCheque], HashPoint[FlowBank]]
],
): ):
def __init__(self, initial: FlowBank): def __init__(self, initial: FlowBank):
assert isinstance(initial, FlowBank) assert isinstance(initial, FlowBank)
@ -134,15 +136,18 @@ class BankFlow(
return FlowBank(minted, used) return FlowBank(minted, used)
def link_verification(self) -> Verification[ def link_verification(self) -> Verification[
tuple[Nullable[Pair[FlowCheque, FlowBank]], Pair[FlowCheque, FlowBank]] tuple[Nullable[HashPoint[Pair[FlowCheque, FlowBank]]], HashPoint[Pair[FlowCheque, FlowBank]]]
]: ]:
class Decomposition(Mapper[Pair[FlowCheque, FlowBank], tuple[FlowCheque, FlowBank]]): class Decomposition(Mapper[HashPoint[Pair[FlowCheque, FlowBank]], tuple[FlowCheque, FlowBank]]):
async def map(self, element: Pair[FlowCheque, FlowBank]) -> tuple[FlowCheque, FlowBank]: async def map(self, element: HashPoint[Pair[FlowCheque, FlowBank]]) -> tuple[FlowCheque, FlowBank]:
assert isinstance(element, HashPoint)
pair: Pair[FlowCheque, FlowBank] = await element.resolve()
assert isinstance(pair, Pair)
cheque: FlowCheque cheque: FlowCheque
bank: FlowBank bank: FlowBank
cheque, bank = await gather( cheque, bank = await gather(
element.element0.resolve(), pair.element0.resolve(),
element.element1.resolve(), pair.element1.resolve(),
) )
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
assert isinstance(bank, FlowBank) assert isinstance(bank, FlowBank)
@ -150,5 +155,10 @@ class BankFlow(
return StateVerification( return StateVerification(
Decomposition(), Decomposition(),
self self.loose()
) ).loose()
def loose(self) -> Verification[
tuple[Nullable[HashPoint[FlowBank]], HashPoint[FlowCheque], HashPoint[FlowBank]]
]:
return self

View File

@ -19,18 +19,18 @@ PBS: TypeAlias = ProtocolizedBinarySplit[KeyT, MetadataT, TreeT]
class BinaryReducer( class BinaryReducer(
Reducer[KeyT, Out], Reducer[HashPoint[KeyT], Out],
Generic[Out, KeyT, MetadataT, TreeT] Generic[Out, KeyT, MetadataT, TreeT]
): ):
def __init__(self, protocolized: BP): def __init__(self, protocolized: BP):
assert isinstance(protocolized, BinaryProtocolized) assert isinstance(protocolized, BinaryProtocolized)
self.protocolized = protocolized self.protocolized = protocolized
async def reduce(self, reduce: Reduce[KeyT, Out]) -> Out: async def reduce(self, reduce: Reduce[HashPoint[KeyT], Out]) -> Out:
assert isinstance(reduce, Reduce) assert isinstance(reduce, Reduce)
return await BinaryReducerAction(reduce).on(self.protocolized) return await BinaryReducerAction(reduce).on(self.protocolized)
def loose(self) -> Reducer[KeyT, Out]: def loose(self) -> Reducer[HashPoint[KeyT], Out]:
return self return self
@ -51,16 +51,15 @@ class BinaryReducerAction(
left: Out left: Out
key: KeyT key: KeyT
right: Out right: Out
left, key, right = await gather( left, right = await gather(
self.on(case.protocolizedl()), self.on(case.protocolizedl()),
case.split.key.resolve(),
self.on(case.protocolizedr()), self.on(case.protocolizedr()),
) )
return await self.reduce.merge( return await self.reduce.merge(
await self.reduce.reduce( await self.reduce.reduce(
left, left,
key case.split.key
), ),
right, right,
) )

View File

@ -44,6 +44,10 @@ class FlowBlock(Generic[LinkT], RecursiveMentionable):
).protocolized() ).protocolized()
) )
async def verify_outer_matches(self, index: Index) -> bool:
assert_eq(await self.outer(), index)
return True
@classmethod @classmethod
async def outer_of(cls, factory: RainbowFactory[LinkT], reference: NullableReference[FBL]) -> Index: async def outer_of(cls, factory: RainbowFactory[LinkT], reference: NullableReference[FBL]) -> Index:
if reference.null(): if reference.null():
@ -107,53 +111,75 @@ class FlowBlockFactory(RainbowFactory[FBL], Generic[LinkT]):
class FlowBlockIndexedVerification( class FlowBlockIndexedVerification(
Verification[FBL], Verification[HashPoint[FBL]],
Generic[LinkT] Generic[LinkT]
): ):
def __init__( def __init__(
self, self,
index: Index, index: Index,
verification: Verification[tuple[Nullable[LinkT], LinkT]], verification: Verification[tuple[Nullable[HashPoint[LinkT]], HashPoint[LinkT]]],
): ):
assert isinstance(index, FlowStandard) assert isinstance(index, FlowStandard)
assert isinstance(verification, Verification) assert isinstance(verification, Verification)
self.index = index self.index = index
self.verification = verification self.verification = verification
async def verify(self, element: FBL) -> bool: async def _verify_empty_block(self, block: FBL) -> bool:
link = await element.link.resolve() assert isinstance(block, FlowBlock)
if element.previous.null(): assert_trues(
assert_trues( await gather(
await gather( self.verification.verify(
self.verification.verify((Null(), link)), (Null(), block.link)
element.index.verify_empty(), ),
) block.index.verify_empty(),
)
else:
previous: FBL = await element.previous.resolve()
async def verify_link() -> bool:
assert_true(await self.verification.verify((NotNull(await previous.link.resolve()), link)))
return True
async def verify_contains() -> bool:
assert_true(await self.index.contains(previous))
return True
async def verify_index() -> bool:
assert_eq(element.index, await previous.outer())
return True
assert_trues(
await gather(
verify_link(),
verify_contains(),
verify_index(),
)
) )
)
return True return True
def loose(self) -> Verification[FBL]: async def _verify_previous_block(self, previous: FBL, block: FBL) -> bool:
assert isinstance(previous, FlowBlock)
assert isinstance(block, FlowBlock)
assert_trues(
await gather(
self.verification.verify(
(NotNull(previous.link), block.link)
),
previous.verify_outer_matches(block.index),
)
)
return True
async def _verify_previous(self, previous: HashPoint[FBL], block: FBL) -> bool:
async def verify_previous_contained() -> bool:
assert_true(await self.index.contains(previous))
return True
async def verify_previous_block() -> bool:
assert_true(await self._verify_previous_block(await previous.resolve(), block))
return True
assert_trues(
await gather(
verify_previous_block(),
verify_previous_contained(),
)
)
return True
async def _verify(self, block: FBL) -> bool:
assert isinstance(block, FlowBlock)
if block.previous.null():
assert_true(await self._verify_empty_block(block))
else:
assert_true(await self._verify_previous(block.previous.hashpoint(), block))
return True
async def verify(self, element: HashPoint[FBL]) -> bool:
assert isinstance(element, HashPoint)
assert_true(await self._verify(await element.resolve()))
return True
def loose(self) -> Verification[HashPoint[FBL]]:
return self return self
@ -163,7 +189,7 @@ class FlowBlockVerification(
): ):
def __init__( def __init__(
self, self,
verification: Verification[tuple[Nullable[LinkT], LinkT]], verification: Verification[tuple[Nullable[HashPoint[LinkT]], HashPoint[LinkT]]],
): ):
assert isinstance(verification, Verification) assert isinstance(verification, Verification)
self.verification = verification self.verification = verification
@ -171,7 +197,7 @@ class FlowBlockVerification(
async def verify(self, element: Index) -> bool: async def verify(self, element: Index) -> bool:
assert_true( assert_true(
await ReduceVerification( await ReduceVerification(
FlowBlockIndexedVerification(element, self.verification) FlowBlockIndexedVerification(element, self.verification).loose()
).verify( ).verify(
await element.reducer() await element.reducer()
) )

View File

@ -9,6 +9,7 @@ from rainbowadn.v13 import *
from ._flowiterate import * from ._flowiterate import *
from ._flowstandard import * from ._flowstandard import *
from ._flowtransaction import * from ._flowtransaction import *
from ._resolvemapper import *
__all__ = ('FlowCheque',) __all__ = ('FlowCheque',)
@ -18,10 +19,10 @@ class SumReduce(PureReduce[int]):
return left + right return left + right
class ValueMapper(Mapper[FlowCoin, int]): class ValueMapper(Mapper[HashPoint[FlowCoin], int]):
async def map(self, element: FlowCoin) -> int: async def map(self, element: HashPoint[FlowCoin]) -> int:
assert isinstance(element, FlowCoin) assert isinstance(element, HashPoint)
return await element.int_value() return await (await element.resolve()).int_value()
class FlowCheque(StaticMentionable, RecursiveMentionable): class FlowCheque(StaticMentionable, RecursiveMentionable):
@ -71,7 +72,7 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
@classmethod @classmethod
async def total_of(cls, tree: FlowStandard[FlowCoin]) -> int: async def total_of(cls, tree: FlowStandard[FlowCoin]) -> int:
assert isinstance(tree, FlowStandard) assert isinstance(tree, FlowStandard)
reducer: Reducer[FlowCoin] = await tree.reducer() reducer: Reducer[HashPoint[FlowCoin]] = await tree.reducer()
assert isinstance(reducer, Reducer) assert isinstance(reducer, Reducer)
total: int = await reducer.reduce(MapReduce(ValueMapper(), SumReduce(0))) total: int = await reducer.reduce(MapReduce(ValueMapper(), SumReduce(0)))
assert isinstance(total, int) assert isinstance(total, int)
@ -140,12 +141,12 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
@classmethod @classmethod
async def _transaction_minted(cls, transaction: FlowTransaction) -> Iterable[FlowCoin]: async def _transaction_minted(cls, transaction: FlowTransaction) -> Iterable[FlowCoin]:
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, FlowTransaction)
return await (await transaction.minted_reducer()).reduce(FlowIterate([])) return await FlowIterate.iterate(ResolveMapper.wrap_reducer(await transaction.minted_reducer()), [])
@classmethod @classmethod
async def _transaction_used(cls, transaction: FlowTransaction) -> Iterable[FlowCoin]: async def _transaction_used(cls, transaction: FlowTransaction) -> Iterable[FlowCoin]:
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, FlowTransaction)
return await (await transaction.used_reducer()).reduce(FlowIterate([])) return await FlowIterate.iterate(ResolveMapper.wrap_reducer(await transaction.used_reducer()), [])
@classmethod @classmethod
async def _transaction_usedx(cls, transaction: FlowTransaction) -> Iterable[KeyValue[FlowCoin, FlowTransaction]]: async def _transaction_usedx(cls, transaction: FlowTransaction) -> Iterable[KeyValue[FlowCoin, FlowTransaction]]:
@ -220,25 +221,31 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
class TransactionVerification( class TransactionVerification(
Verification[FlowTransaction] Verification[HashPoint[FlowTransaction]]
): ):
def __init__(self, cheque: FlowCheque): def __init__(self, cheque: FlowCheque):
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
self.cheque = cheque self.cheque = cheque
@classmethod @classmethod
def usedx_reducer(cls, reducer: Reducer[FlowCoin, bool], transaction: FlowTransaction): def _usedx_reducer(
cls,
reducer: Reducer[HashPoint[FlowCoin], bool],
transaction: HashPoint[FlowTransaction]
) -> Reducer[HashPoint[KeyValue[FlowCoin, FlowTransaction]], bool]:
assert isinstance(reducer, Reducer) assert isinstance(reducer, Reducer)
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, HashPoint)
def usedx(coin: FlowCoin) -> KeyValue[FlowCoin, FlowTransaction]: def usedx(coin: HashPoint[FlowCoin]) -> HashPoint[KeyValue[FlowCoin, FlowTransaction]]:
assert isinstance(coin, FlowCoin) assert isinstance(coin, HashPoint)
return KeyValue( return HashPoint.of(
HashPoint.of(coin), KeyValue(
HashPoint.of(transaction) coin,
transaction
)
) )
usedx_reducer: Reducer[KeyValue[FlowCoin, FlowTransaction], bool] = MapReducer( usedx_reducer: Reducer[HashPoint[KeyValue[FlowCoin, FlowTransaction]], bool] = MapReducer(
CallableMapper(usedx), CallableMapper(usedx),
reducer reducer
) )
@ -267,75 +274,78 @@ class TransactionVerification(
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, FlowTransaction)
assert_true( assert_true(
await self.cheque.usedx.verify_contains_all( await self.cheque.usedx.verify_contains_all(
self.usedx_reducer(await transaction.used_reducer(), transaction) self._usedx_reducer(await transaction.used_reducer(), HashPoint.of(transaction))
) )
) )
return True return True
async def verify(self, element: FlowTransaction) -> bool: async def verify(self, element: HashPoint[FlowTransaction]) -> bool:
assert isinstance(element, FlowTransaction) assert isinstance(element, HashPoint)
transaction: FlowTransaction = await element.resolve()
assert isinstance(transaction, FlowTransaction)
assert_trues( assert_trues(
await gather( await gather(
self._verify_transaction_minted(element), self._verify_transaction_minted(transaction),
self._verify_transaction_used(element), self._verify_transaction_used(transaction),
self._verify_transaction_usedx(element), self._verify_transaction_usedx(transaction),
transaction.verify(),
) )
) )
return True return True
def loose(self) -> Verification[FlowTransaction]: def loose(self) -> Verification[HashPoint[FlowTransaction]]:
return self return self
class MintedVerification( class MintedVerification(
Verification[FlowCoin] Verification[HashPoint[FlowCoin]]
): ):
def __init__(self, cheque: FlowCheque): def __init__(self, cheque: FlowCheque):
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
self.cheque = cheque self.cheque = cheque
async def verify(self, element: FlowCoin) -> bool: async def verify(self, element: HashPoint[FlowCoin]) -> bool:
assert isinstance(element, FlowCoin) assert isinstance(element, HashPoint)
assert_true( assert_true(
await self.cheque.transactions.contains( await self.cheque.transactions.contains(
await element.transaction.resolve() (await element.resolve()).transaction
) )
) )
return True return True
def loose(self) -> Verification[FlowCoin]: def loose(self) -> Verification[HashPoint[FlowCoin]]:
return self return self
class UsedVerification( class UsedVerification(
Verification[FlowCoin] Verification[HashPoint[FlowCoin]]
): ):
def __init__(self, cheque: FlowCheque): def __init__(self, cheque: FlowCheque):
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
self.cheque = cheque self.cheque = cheque
async def verify(self, element: FlowCoin) -> bool: async def verify(self, element: HashPoint[FlowCoin]) -> bool:
assert isinstance(element, FlowCoin) assert isinstance(element, HashPoint)
assert_true( assert_true(
await self.cheque.usedx.contains( await self.cheque.usedx.contains(
KeyValue(HashPoint.of(element), HashPoint.of(FlowTransaction.empty())) HashPoint.of(KeyValue(element, HashPoint.of(FlowTransaction.empty())))
) )
) )
return True return True
def loose(self) -> Verification[FlowCoin]: def loose(self) -> Verification[HashPoint[FlowCoin]]:
return self return self
class UsedXVerification( class UsedXVerification(
Verification[KeyValue[FlowCoin, FlowTransaction]] Verification[HashPoint[KeyValue[FlowCoin, FlowTransaction]]]
): ):
def __init__(self, cheque: FlowCheque): def __init__(self, cheque: FlowCheque):
assert isinstance(cheque, FlowCheque) assert isinstance(cheque, FlowCheque)
self.cheque = cheque self.cheque = cheque
async def _verify_transaction_registred(self, transaction: FlowTransaction) -> bool: async def _verify_transaction_registred(self, transaction: HashPoint[FlowTransaction]) -> bool:
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, HashPoint)
assert_true( assert_true(
await self.cheque.transactions.contains( await self.cheque.transactions.contains(
transaction transaction
@ -345,35 +355,35 @@ class UsedXVerification(
@classmethod @classmethod
async def _verify_coin_contained_in_transaction( async def _verify_coin_contained_in_transaction(
cls, transaction: FlowTransaction, coin: HashPoint[FlowCoin] cls, transaction: HashPoint[FlowTransaction], coin: HashPoint[FlowCoin]
) -> bool: ) -> bool:
assert isinstance(transaction, FlowTransaction) assert isinstance(transaction, HashPoint)
assert isinstance(coin, HashPoint) assert isinstance(coin, HashPoint)
data_resolved: FlowTransactionData data_resolved: FlowTransactionData = await (await transaction.resolve()).data_resolved()
coin_resoled: FlowCoin assert isinstance(data_resolved, FlowTransactionData)
data_resolved, coin_resoled = await gather( assert_true(await data_resolved.in_coins.contains(coin))
transaction.data_resolved(),
coin.resolve(),
)
assert_true(await data_resolved.in_coins.contains(coin_resoled))
return True return True
async def _verify_coin_registred_as_used(self, coin: HashPoint[FlowCoin]) -> bool: async def _verify_coin_registred_as_used(self, coin: HashPoint[FlowCoin]) -> bool:
assert_true(await self.cheque.used.contains(await coin.resolve())) assert isinstance(coin, HashPoint)
assert_true(await self.cheque.used.contains(coin))
return True return True
async def verify(self, element: KeyValue[FlowCoin, FlowTransaction]) -> bool: async def _verify(self, pair: KeyValue[FlowCoin, FlowTransaction]):
assert isinstance(element, KeyValue) assert isinstance(pair, KeyValue)
transaction: FlowTransaction = await element.value.resolve()
assert isinstance(transaction, FlowTransaction)
assert_trues( assert_trues(
await gather( await gather(
self._verify_transaction_registred(transaction), self._verify_transaction_registred(pair.value),
self._verify_coin_contained_in_transaction(transaction, element.key), self._verify_coin_contained_in_transaction(pair.value, pair.key),
self._verify_coin_registred_as_used(element.key), self._verify_coin_registred_as_used(pair.key),
) )
) )
return True return True
def loose(self) -> Verification[KeyValue[FlowCoin, FlowTransaction]]: async def verify(self, element: HashPoint[KeyValue[FlowCoin, FlowTransaction]]) -> bool:
assert isinstance(element, HashPoint)
assert_true(await self._verify(await element.resolve()))
return True
def loose(self) -> Verification[HashPoint[KeyValue[FlowCoin, FlowTransaction]]]:
return self return self

View File

@ -27,3 +27,11 @@ class FlowIterate(
def loose(self) -> Reduce[Element, Iterable[Element]]: def loose(self) -> Reduce[Element, Iterable[Element]]:
return self return self
@classmethod
async def iterate(
cls,
reducer: Reducer[Element, Iterable[Element]],
initial: Iterable[Element]
) -> Iterable[Element]:
return await reducer.reduce(cls(initial))

View File

@ -23,7 +23,7 @@ BP: TypeAlias = 'BinaryProtocolized[KeyT, Integer, ABT]'
class FlowStandard( class FlowStandard(
RecursiveMentionable, RecursiveMentionable,
FlowTree[KeyT, FS], FlowTree[HashPoint[KeyT], FS],
Generic[KeyT] Generic[KeyT]
): ):
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
@ -41,8 +41,8 @@ class FlowStandard(
assert isinstance(protocolized, BinaryProtocolized) assert isinstance(protocolized, BinaryProtocolized)
self.protocolized = protocolized self.protocolized = protocolized
async def contains(self, key: KeyT) -> bool: async def contains(self, key: HashPoint[KeyT]) -> bool:
return await self.protocolized.tree.contains(HashPoint.of(key)) return await self.protocolized.tree.contains(key)
def _protocolized(self: FS) -> BP: def _protocolized(self: FS) -> BP:
return self.protocolized return self.protocolized
@ -67,7 +67,7 @@ class FlowStandard(
) )
return True return True
async def reducer(self) -> Reducer[KeyT, Any]: async def reducer(self) -> Reducer[HashPoint[KeyT], Any]:
return BinaryReducer(self.protocolized).loose() return BinaryReducer(self.protocolized).loose()
def __eq__(self, other): def __eq__(self, other):

View File

@ -9,6 +9,7 @@ from rainbowadn.flow.core import *
from rainbowadn.flow.verification.core import * from rainbowadn.flow.verification.core import *
from rainbowadn.v13 import * from rainbowadn.v13 import *
from ._flowstandard import * from ._flowstandard import *
from ._resolvemapper import *
__all__ = ('FlowCoinData', 'FlowCoin', 'FlowTransactionData', 'FlowTransaction',) __all__ = ('FlowCoinData', 'FlowCoin', 'FlowTransactionData', 'FlowTransaction',)
@ -151,17 +152,17 @@ class FlowTransactionData(RecursiveMentionable, StaticMentionable):
cls, cls,
signatures: FlowStandard[KeyValue[Subject, Signature]], signatures: FlowStandard[KeyValue[Subject, Signature]],
) -> Mapper[ ) -> Mapper[
FlowCoin, HashPoint[FlowCoin],
bool bool
]: ]:
assert isinstance(signatures, FlowStandard) assert isinstance(signatures, FlowStandard)
return CVMapper(signatures) return ResolveMapper.wrap_mapper(CVMapper(signatures).loose())
def _signature_pair_verification_mapper(self) -> Mapper[ def _signature_pair_verification_mapper(self) -> Mapper[
KeyValue[Subject, Signature], HashPoint[KeyValue[Subject, Signature]],
bool bool
]: ]:
return SPVMapper(self.hash_point) return ResolveMapper.wrap_mapper(SPVMapper(self.hash_point).loose())
async def _verify_coin_signatures( async def _verify_coin_signatures(
self, self,
@ -242,11 +243,14 @@ class CVMapper(Mapper[FlowCoin, bool]):
assert isinstance(element, FlowCoin) assert isinstance(element, FlowCoin)
assert_true( assert_true(
await self.signatures.contains( await self.signatures.contains(
KeyValue((await element.data.resolve()).owner, HashPoint.of(Signature.empty())) HashPoint.of(KeyValue((await element.data.resolve()).owner, HashPoint.of(Signature.empty())))
) )
) )
return True return True
def loose(self) -> Mapper[FlowCoin, bool]:
return self
class SPVMapper(Mapper[KeyValue[Subject, Signature], bool]): class SPVMapper(Mapper[KeyValue[Subject, Signature], bool]):
def __init__(self, hashpoint: HashPoint): def __init__(self, hashpoint: HashPoint):
@ -258,14 +262,17 @@ class SPVMapper(Mapper[KeyValue[Subject, Signature], bool]):
subject: Subject subject: Subject
signature: Signature signature: Signature
subject, signature = await gather( subject, signature = await gather(
element.key, element.key.resolve(),
element.value, element.value.resolve(),
) )
assert isinstance(subject, Subject) assert isinstance(subject, Subject)
assert isinstance(signature, Signature) assert isinstance(signature, Signature)
assert_true(signature.verify(subject, self.hashpoint)) assert_true(signature.verify(subject, self.hashpoint))
return True return True
def loose(self) -> Mapper[KeyValue[Subject, Signature], bool]:
return self
class FlowTransaction(RecursiveMentionable, StaticMentionable): class FlowTransaction(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
@ -300,15 +307,16 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
), ),
) )
def _coin(self, data: FlowCoinData) -> FlowCoin: def _coin(self, data: HashPoint[FlowCoinData]) -> HashPoint[FlowCoin]:
return FlowCoin(HashPoint.of(data), self.hash_point) assert isinstance(data, HashPoint)
return HashPoint.of(FlowCoin(data, self.hash_point))
async def used_reducer(self) -> Reducer[FlowCoin, Any]: async def used_reducer(self) -> Reducer[HashPoint[FlowCoin], Any]:
transaction_data: FlowTransactionData = await self.data_resolved() transaction_data: FlowTransactionData = await self.data_resolved()
assert isinstance(transaction_data, FlowTransactionData) assert isinstance(transaction_data, FlowTransactionData)
return await transaction_data.in_coins.reducer() return await transaction_data.in_coins.reducer()
async def minted_reducer(self) -> Reducer[FlowCoin, Any]: async def minted_reducer(self) -> Reducer[HashPoint[FlowCoin], Any]:
transaction_data: FlowTransactionData = await self.data_resolved() transaction_data: FlowTransactionData = await self.data_resolved()
assert isinstance(transaction_data, FlowTransactionData) assert isinstance(transaction_data, FlowTransactionData)
return MapReducer(CallableMapper(self._coin), await transaction_data.out_coins.reducer()) return MapReducer(CallableMapper(self._coin), await transaction_data.out_coins.reducer())

View File

@ -0,0 +1,25 @@
from typing import Generic, TypeVar
from rainbowadn.core import *
from rainbowadn.flow.core import *
__all__ = ('ResolveMapper',)
MentionedT = TypeVar('MentionedT')
Out = TypeVar('Out')
class ResolveMapper(Mapper[HashPoint[MentionedT], MentionedT], Generic[MentionedT]):
async def map(self, element: HashPoint[MentionedT]) -> MentionedT:
return await element.resolve()
def loose(self) -> Mapper[HashPoint[MentionedT], MentionedT]:
return self
@classmethod
def wrap_mapper(cls, mapper: Mapper[MentionedT, Out]) -> Mapper[HashPoint[MentionedT], Out]:
return Composition(cls().loose(), mapper)
@classmethod
def wrap_reducer(cls, reducer: Reducer[HashPoint[MentionedT], Out]) -> Reducer[MentionedT, Out]:
return MapReducer(cls().loose(), reducer)

View File

@ -159,7 +159,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
formatted += ''.join( formatted += ''.join(
f'{tabulate(tab + 1)}{child_formatted}' for child_formatted in ( f'{tabulate(tab + 1)}{child_formatted}' for child_formatted in (
await gather( await gather(
hash_point_format(self.child_no(child_index), tab + 1) for child_index in range(self.children) *(hash_point_format(self.child_no(child_index), tab + 1) for child_index in range(self.children))
) )
) )
) )

View File

@ -69,18 +69,18 @@ async def _instrument(bank: BankBlock) -> list[Instrumentation]:
return instrumentations return instrumentations
params = (
16,
8, 16,
8, 16,
)
async def _trace(): async def _trace():
set_gather_linear() set_gather_linear()
bank = await _generate( bank = await _generate(
16, *params
32, 63,
8, 15,
) )
# bank = await _generate(
# 8,
# 8, 8,
# 8, 8,
# )
bank = await _migrate(bank) bank = await _migrate(bank)
set_gather_asyncio() set_gather_asyncio()
with DeintrumentationSize(Instrumentation, 'deinstrument'): with DeintrumentationSize(Instrumentation, 'deinstrument'):
@ -95,7 +95,7 @@ async def main():
instrumentations = await _trace() instrumentations = await _trace()
fn = get_fn() fn = get_fn()
jsonified = jsonify_list(instrumentations) jsonified = jsonify_list(instrumentations)
dump(fn, jsonified) dump(fn, jsonified | {'params': params})
copy(fn) copy(fn)
plot(fn) plot(fn)
print('plotted') print('plotted')