۱. رخدادِ حسگر با مقدارِ قرائت یکی نیست

مقادیر برابر می‌توانند رخدادهای جداگانه باشند
تصویر مفهومی: مقادیر برابر می‌توانند رخدادهای جداگانه باشند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

فرض کنید برای بازبینی یک آزمایش، فقط چند قرائت از توالی حسگر را نگه می‌داریم. انتخاب دو مقدارِ متفاوت با انتخاب دو رخدادِ متفاوت یکسان نیست: ممکن است حسگر چند بار همان ولتاژ را ثبت کرده باشد. در مثال کاملاً ساختگی ما، قرائت‌ها بر حسب میلی‌ولت هستند و هر رخداد یک موقعیتِ صفرمبنا دارد. موضوع درس، انتخاب تصادفی از موقعیت‌هاست؛ هیچ ادعایی دربارهٔ کیفیت حسگر، پوششِ حالت‌های نادر یا نماینده‌بودن نمونه برای یک پدیدهٔ واقعی نداریم.

وقتی ورودی فقط به ترتیب در دسترس باشد، نگهداری یک مخزنِ کوچک راهی برای انتخاب بدون دانستن طولِ نهایی است. مدخل رسمی نمونه‌گیری مخزنی در NIST الگوریتم پایه و یکنواختیِ انتخاب‌های آن را توضیح می‌دهد. اینجا مسئله را کوچک و قابل شمارش می‌کنیم: ورودیِ عمومی یک تاپل با حداکثر شش قرائتِ صحیح، ظرفیت حداکثر سه و بذرِ صحیحِ محدود است. این محدودیت، قرارداد آموزشیِ خودمان است و محدودیتِ عمومیِ الگوریتم محسوب نمی‌شود.

درسِ پردازش دسته‌ای با مولد دربارهٔ مصرف کاملِ توالی و دستهٔ پایانی بود. این بار قرار نیست همهٔ رخدادها در خروجی بمانند؛ می‌خواهیم قانونِ انتخابِ زیرمجموعه را بیازماییم. احتمال و شمارهٔ موقعیت بی‌بعدند، اما مقدارِ همراه هر موقعیت همچنان میلی‌ولت است. مخلوط‌کردن این دو نوع داده، تشخیصِ انتخاب تکراری یا حذفِ اشتباهِ قرائت‌های برابر را دشوار می‌کند.

۲. تصمیمِ جایگزینی در مخزن چگونه گرفته می‌شود؟

جایگزینیِ یک خانه با نگه‌داشتنِ همهٔ ورودی تفاوت دارد
تصویر مفهومی: جایگزینیِ یک خانه با نگه‌داشتنِ همهٔ ورودی تفاوت دارد؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

ابتدا خانه‌های مخزن را با نخستین رخدادها پر می‌کنیم. پس از پرشدن ظرفیت، برای رخدادِ شمارهٔ یک‌مبنای j یک عدد صحیح از صفر تا j−1 می‌گیریم. اگر عدد از ظرفیت کوچک‌تر باشد، همان خانه جایگزین می‌شود؛ در غیر این صورت رخداد تازه وارد مخزن نمی‌شود. این صورتِ صفرمبنای الگوریتم R است. افزایشِ دامنهٔ قرعه با تعدادِ دیده‌شده ضروری است؛ احتمالِ ثابتِ جایگزینی، به‌طور کلی همان قانون را تولید نمی‌کند.

برای مقادیر ۱۰، ۲۰، ۳۰ و ۴۰ و ظرفیت دو، قرعه‌های ازپیش‌تعیین‌شدهٔ صفر و سه را دنبال کنید. رخدادِ سوم، خانهٔ نخست را می‌گیرد؛ رخدادِ چهارم کنار گذاشته می‌شود. خروجیِ خانه‌ها برابرِ جفت‌های «موقعیت ۲، مقدار ۳۰» و «موقعیت ۱، مقدار ۲۰» است. ترتیبِ خانه‌ها با ترتیب زمانیِ ورودی یکی نیست. مرتب‌کردنِ موقعیت‌ها برای مقایسهٔ زیرمجموعه مجاز است، ولی آن را یک درهم‌ریزی تصادفیِ یکنواخت معرفی نمی‌کنیم.

در اجرای واقعی، یک نمونهٔ محلی از Random می‌سازیم و از قرارداد randrange برای دامنهٔ نیمه‌باز استفاده می‌کنیم. گزارشِ همین اجرا با بذر ۲۰۲۶۱۰۱۹، از شش مقدارِ ۱۲۰، ۱۲۰، ۱۴۰، ۱۰۰، ۱۶۰ و ۱۲۰، موقعیت‌های ۴ و ۵ را با مقادیرِ ۱۶۰ و ۱۲۰ نگه داشته است. این یک خروجیِ ثبت‌شده در CPython 3.14.5 است، نه شاهدِ کافی برای یکنواختیِ توزیع.

بذر را برای تکرارِ یک آزمایش در همان محیط ثبت می‌کنیم. مستنداتِ بررسی‌شده نسخهٔ 3.14.8 هستند و تضمین عمومیِ یکسان‌بودن تمامِ خروجی‌های randrange در نسخه‌های آینده نمی‌دهند. رابطهٔ بذر و گزارش را پیش‌تر در تکرارپذیری آزمایش سیگنال بررسی کردیم؛ نوآوریِ این مثال، شمارشِ دقیقِ قانونِ زیرمجموعه است.

۳. یکنواختی را با تمامِ تاریخچه‌ها بررسی کنیم

مرجعِ ترکیب‌ها از اجرای انتخاب جدا ساخته می‌شود
تصویر مفهومی: مرجعِ ترکیب‌ها از اجرای انتخاب جدا ساخته می‌شود؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

مدلِ مرجع فرض می‌کند هر قرعه در دامنهٔ خودش یکنواخت و از قرعه‌های دیگر مستقل است. برای شش رخداد و ظرفیت دو، دامنه‌ها اندازه‌های ۳، ۴، ۵ و ۶ دارند؛ بنابراین ۳۶۰ تاریخچهٔ هم‌احتمال داریم. همهٔ آن‌ها را اجرا می‌کنیم و خروجی را به موقعیت‌های مرتب‌شده تبدیل می‌کنیم. هر یک از پانزده زیرمجموعه، دقیقاً ۲۴ بار ظاهر می‌شود؛ احتمالِ هر زیرمجموعه در این مدل ۱/۱۵ است.

مرجعِ مستقل، تصمیم‌های جایگزینی را دوباره پیاده نمی‌کند. فضایِ هدف را با combinations مستقیماً از موقعیت‌ها می‌سازد و فراوانیِ مورد انتظار را از تعدادِ تاریخچه‌ها تقسیم بر تعدادِ ترکیب‌ها به دست می‌آورد. همان صفحه، هویتِ عناصر را بر اساس موقعیت توضیح می‌دهد. product نیز فقط برای ساختن تمامِ دنباله‌های محدودِ قرعه استفاده می‌شود؛ هیچ ورودیِ نامتناهی به آن نمی‌دهیم.

این بررسی برای تمامِ ۲۸ جفتِ مجازِ طول و ظرفیت انجام می‌شود، اما یک خانوادهٔ آزمون است. سناریوی ظرفیتِ صفر یا بزرگ‌تر از طول، تنها یک انتخابِ قطعی دارد. شمارشِ محدود، تمامِ حالت‌های همین دامنه را پوشش می‌دهد؛ جای اثباتِ عمومی برای طول‌های دلخواه یا ارزیابیِ کیفیتِ مولدِ شبه‌تصادفی را نمی‌گیرد. به‌ویژه اجرای چند بذر و دیدنِ فراوانی‌های نزدیک، معادلِ این شمارشِ شرطی نیست.

۴. کد کامل و قراردادِ ورودیِ محدود

قرارداد محدود، اجرای واقعی و بررسیِ مرزها را روشن می‌کند
تصویر مفهومی: قرارداد محدود، اجرای واقعی و بررسیِ مرزها را روشن می‌کند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

تابع عمومی فقط تاپلِ دقیق با صفر تا شش عددِ صحیحِ دقیق در بازهٔ منفی هزار تا مثبت هزار میلی‌ولت را می‌پذیرد؛ مقدارِ بولی، اعشاری، Enum و زیرکلاسِ عدد صحیح پذیرفته نیست. ظرفیت باید صحیحِ دقیقِ صفر تا سه و بذر صحیحِ دقیقِ صفر تا ۲ به توان ۳۲ منهای یک باشد. این سخت‌گیری سیاستِ نمونه است، نه تضمینِ امنیت یا الزامِ کتابخانهٔ random. مقادیر برابر کاملاً مجازند.

اعتبارسنجی یک پیمایشِ جداگانهٔ تاپل دارد؛ پس کلِ برنامه را تک‌گذر نمی‌نامیم. فقط هستهٔ انتخاب، تکرارگرِ تازه را یک بار مصرف می‌کند و طول یا دسترسیِ اندیسی از آن نمی‌خواهد. قراردادِ خودمان برای ظرفیتِ صفر، مصرفِ همهٔ ورودی بدون قرعه است. ظرفیتِ بزرگ‌تر از طول، همهٔ رخدادها را نگه می‌دارد و ورودیِ خالی خروجیِ خالی می‌دهد. برنامهٔ شمارش، خودِ داده و جدولِ حالت‌ها را نیز نگه می‌دارد؛ ادعای حافظهٔ کلِ ثابت نداریم.

"""Bounded Algorithm R: occurrence subsets, ideal histories, actual seeded demo.

The public tuple is validated in a separate scan. Only _reservoir's selection
over its already validated, finite source is one pass. Internal underscore
helpers are authored fixtures, not a general public callback/stream API.
"""
from collections import Counter
from enum import IntEnum
from fractions import Fraction
from itertools import combinations, permutations, product
from math import comb, prod
import json
import platform
import random

MAX_ROWS = 6
MAX_K = 3
MAX_MV = 1000


def _validate(readings, k, seed):
    if type(readings) is not tuple:
        raise TypeError('readings must be an exact tuple')
    if len(readings) > MAX_ROWS:
        raise ValueError('at most six readings')
    for value in readings:
        if type(value) is not int:
            raise TypeError('readings must be exact integer millivolts')
        if not -MAX_MV <= value <= MAX_MV:
            raise ValueError('reading outside authored range')
    if type(k) is not int:
        raise TypeError('k must be an exact integer')
    if not 0 <= k <= MAX_K:
        raise ValueError('k outside authored range')
    if type(seed) is not int:
        raise TypeError('seed must be an exact integer')
    if not 0 <= seed <= 2**32 - 1:
        raise ValueError('seed outside authored range')


def _reservoir(source, k, draw):
    """Internal: trusted finite values and k; validate every draw response.

    Returns (zero-based occurrence position, original value) in reservoir-slot
    order, not sorted or uniformly shuffled order. k=0 still consumes source.
    """
    slots = []
    for seen, value in enumerate(source, 1):
        item = (seen - 1, value)
        if len(slots) < k:
            slots.append(item)
        elif k:
            choice = draw(seen)
            if type(choice) is not int:
                raise TypeError('draw must return an exact integer')
            if not 0 <= choice < seen:
                raise ValueError('draw outside requested half-open range')
            if choice < k:
                slots[choice] = item
    return tuple(slots)


def sample_readings(readings, k, seed):
    """Own bounded public policy; no external-source or memory-byte guarantee."""
    _validate(readings, k, seed)
    rng = random.Random(seed)
    return _reservoir(iter(readings), k, rng.randrange)


def _subset(slots):
    return tuple(sorted(position for position, value in slots))


class _Tape:
    """Trusted exact draw-history fixture; verifies requests and exhaustion."""
    def __init__(self, stops, values):
        self.expected = tuple(zip(stops, values, strict=True))
        self.at = 0

    def __call__(self, stop):
        expected_stop, value = self.expected[self.at]
        assert stop == expected_stop
        self.at += 1
        return value

    def complete(self):
        return self.at == len(self.expected)


def _histogram(n, k, readings=None):
    """Enumerate every IDEAL draw history, not seeds or random trials."""
    values = tuple(range(n)) if readings is None else readings
    stops = tuple(range(k + 1, n + 1)) if k else ()
    histogram = Counter()
    ordered = Counter()
    for history in product(*(range(stop) for stop in stops)):
        tape = _Tape(stops, history)
        slots = _reservoir(iter(values), k, tape)
        assert tape.complete()
        assert len(slots) == min(k, n)
        assert len({position for position, value in slots}) == len(slots)
        assert all(value == values[position] for position, value in slots)
        histogram[_subset(slots)] += 1
        ordered[tuple(position for position, value in slots)] += 1
    return histogram, ordered


def _expected_combinations(n, k):
    """Independent target law: no reservoir updates or draw-history replay."""
    size = min(k, n)
    history_count = prod(range(k + 1, n + 1)) if k else 1
    subsets = tuple(combinations(range(n), size))
    assert len(subsets) == comb(n, size)
    assert history_count % len(subsets) == 0
    return {subset: history_count // len(subsets) for subset in subsets}


class _OnePass:
    def __init__(self, values):
        self.values = values
        self.position = 0
        self.iter_calls = 0
        self.successes = 0

    def __iter__(self):
        self.iter_calls += 1
        if self.iter_calls != 1:
            raise AssertionError('source restarted')
        return self

    def __next__(self):
        if self.position == len(self.values):
            raise StopIteration
        value = self.values[self.position]
        self.position += 1
        self.successes += 1
        return value

    def __len__(self):
        raise AssertionError('selection asked source length')

    def __getitem__(self, index):
        raise AssertionError('selection indexed source')


def _raises(kind, call):
    try:
        call()
    except kind:
        return True
    return False


def main():
    checks = {}
    tape = _Tape((3, 4), (0, 3))
    literal = _reservoir(iter((10, 20, 30, 40)), 2, tape)
    tape_last_slot = _Tape((3,), (1,))
    checks['literal_replace_discard_and_slot_boundary'] = (
        literal == ((2, 30), (1, 20)) and tape.complete()
        and _reservoir(iter((10, 20, 30)), 2, tape_last_slot)
        == ((0, 10), (2, 30)) and tape_last_slot.complete())

    profile_counts = []
    for n in range(MAX_ROWS + 1):
        for k in range(MAX_K + 1):
            actual, ordered = _histogram(n, k)
            target = _expected_combinations(n, k)
            profile_counts.append(actual == target)
    checks['all_28_ideal_history_laws_match_independent_combinations'] = all(profile_counts)
    main_histogram, main_ordered = _histogram(6, 2)

    biased = Counter()
    for first, second in product(range(2), repeat=2):
        chosen = 0
        if first == 0:
            chosen = 1
        if second == 0:
            chosen = 2
        biased[chosen] += 1
    checks['constant_draw_range_counterexample_is_biased'] = (
        biased == {0: 1, 1: 1, 2: 2}
        and len(set(biased.values())) != 1)

    duplicate_histogram, duplicate_order = _histogram(3, 2, (7, 7, 7))
    checks['equal_values_remain_distinct_occurrences'] = (
        duplicate_histogram == {(0, 1): 1, (0, 2): 1, (1, 2): 1}
        and all(tuple(value for position, value in sample_readings((7, 7, 7), 2, seed))
                == (7, 7) for seed in range(8)))

    hist3, order3 = _histogram(3, 2)
    checks['uniform_subset_does_not_mean_uniform_slot_permutation'] = (
        order3 == {(2, 1): 1, (0, 2): 1, (0, 1): 1}
        and set(hist3) == set(combinations(range(3), 2))
        and len(order3) < len(tuple(permutations(range(3), 2))))

    zero_source = _OnePass((4, 4, 9))
    zero_draws = []
    checks['zero_capacity_consumes_source_without_draws'] = (
        _reservoir(zero_source, 0, lambda stop: zero_draws.append(stop)) == ()
        and zero_source.successes == 3 and zero_source.iter_calls == 1
        and zero_draws == [])

    covering = []
    for n in range(4):
        values = tuple(range(n))
        for k in range(n, 4):
            draws = []
            slots = _reservoir(iter(values), k, lambda stop: draws.append(stop))
            covering.append(slots == tuple(enumerate(values)) and draws == [])
    checks['empty_and_capacity_covering_input_keep_all_without_draws'] = all(covering)

    one_pass = _OnePass((2, 5, 2, 8, 1, 9))
    one_tape = _Tape((3, 4, 5, 6), (2, 0, 4, 1))
    checks['selection_never_restarts_indexes_or_counts_source_length'] = (
        _reservoir(one_pass, 2, one_tape) == ((3, 8), (5, 9))
        and one_pass.successes == 6 and one_pass.iter_calls == 1 and one_tape.complete())

    rows = (120, 120, 140, 100, 160, 120)
    global_before = random.getstate()
    seeded = sample_readings(rows, 2, 20261019)
    checks['fixed_seed_local_instance_repeat_preserves_global_rng_state'] = (
        seeded == sample_readings(rows, 2, 20261019)
        and random.getstate() == global_before)

    seeded_valid = []
    for n in range(7):
        values = tuple(range(n))
        for k in range(4):
            universe = set(combinations(range(n), min(k, n)))
            for seed in (0, 1, 17, 20261019, 2**32 - 1):
                sample = sample_readings(values, k, seed)
                seeded_valid.append(_subset(sample) in universe
                    and len(sample) == min(k, n)
                    and all(value == values[position] for position, value in sample))
    checks['actual_random_integration_140_results_obey_feasible_subset_contract'] = all(seeded_valid)

    class Foreign(IntEnum):
        ONE = 1

    class IntegerChild(int):
        pass

    class TupleChild(tuple):
        pass

    bad_public = []
    for readings in ([], None, '12', TupleChild((1,))):
        bad_public.append(_raises(TypeError, lambda readings=readings: sample_readings(readings, 1, 0)))
    for value in (True, 1.0, float('nan'), float('inf'), '1', Foreign.ONE, IntegerChild(1), None):
        bad_public.append(_raises(TypeError, lambda value=value: sample_readings((value,), 1, 0)))
    for readings in ((0,) * 7, (1001,), (-1001,)):
        bad_public.append(_raises(ValueError, lambda readings=readings: sample_readings(readings, 1, 0)))
    for k in (True, 1.0, Foreign.ONE, IntegerChild(1), None):
        bad_public.append(_raises(TypeError, lambda k=k: sample_readings((1,), k, 0)))
    for k in (-1, 4):
        bad_public.append(_raises(ValueError, lambda k=k: sample_readings((1,), k, 0)))
    for seed in (True, 1.0, Foreign.ONE, IntegerChild(1), None):
        bad_public.append(_raises(TypeError, lambda seed=seed: sample_readings((1,), 1, seed)))
    for seed in (-1, 2**32):
        bad_public.append(_raises(ValueError, lambda seed=seed: sample_readings((1,), 1, seed)))
    checks['public_exact_type_value_and_size_boundaries'] = all(bad_public)

    bad_draws = []
    for value in (True, 0.0, Foreign.ONE, IntegerChild(0), None, '0'):
        bad_draws.append(_raises(TypeError, lambda value=value:
            _reservoir(iter((1, 2)), 1, lambda stop: value)))
    for value in (-1, 2, 100):
        bad_draws.append(_raises(ValueError, lambda value=value:
            _reservoir(iter((1, 2)), 1, lambda stop: value)))
    checks['internal_draw_response_exact_type_and_half_open_range'] = all(bad_draws)

    relabelled = []
    for values in permutations((-7, 2, 9)):
        histogram, ordered = _histogram(3, 2, values)
        by_values = {tuple(sorted(values[position] for position in subset)): count
                     for subset, count in histogram.items()}
        relabelled.append(by_values == {subset: 1 for subset in combinations(sorted(values), 2)})
    checks['six_value_relabellings_preserve_unordered_selection_law'] = all(relabelled)

    assert len(checks) == 13
    assert all(type(value) is bool and value for value in checks.values()), checks
    output = {
        'python': platform.python_version(), 'implementation': platform.python_implementation(),
        'units': {'readings': 'mV', 'positions_counts_probabilities': 'dimensionless'},
        'profile': {'max_rows': 6, 'k_range': [0, 3], 'reading_range_mV': [-1000, 1000],
            'separate_prevalidation_scan': True, 'selection_core_one_pass': True,
            'zero_k_consumes_source_without_draws': True},
        'literal_replacement_slots': literal,
        'main_ideal_example': {'n': 6, 'k': 2, 'equiprobable_histories': sum(main_histogram.values()),
            'unordered_subsets': len(main_histogram), 'histories_per_subset': sorted(set(main_histogram.values())),
            'probability_of_each_subset': str(Fraction(1, comb(6, 2))),
            'law_scope': 'Independent ideal uniform integer draws, NOT seed frequencies.'},
        'duplicate_value_positions': {','.join(map(str, key)): value for key, value in duplicate_histogram.items()},
        'biased_constant_bound_counts': dict(sorted(biased.items())),
        'nonuniform_ordered_slot_outcomes_n3_k2': [list(key) for key in order3],
        'actual_seeded_demo': {'readings_mV': rows, 'seed': 20261019, 'slot_order': seeded,
            'canonical_positions': _subset(seeded), 'execution_not_uniformity_proof': True},
        'cases_within_groups': {'ideal_profiles': len(profile_counts), 'actual_seeded_results': len(seeded_valid),
            'public_rejections': len(bad_public), 'draw_rejections': len(bad_draws), 'relabelings': len(relabelled)},
        'checks': checks,
    }
    print(json.dumps(output, ensure_ascii=True, indent=2))


if __name__ == '__main__':
    main()

کد کامل در یک فرایند واقعی با کتابخانهٔ استاندارد اجرا شده است. سیزده خانوادهٔ نام‌دار، مثالِ دستی، قانونِ تمامِ زیرمجموعه‌ها، ضدنمونهٔ قرعهٔ ثابت، قرائت‌های برابر، ترتیبِ خانه‌ها، مرزهای ظرفیت، تکرارگرِ غیرقابل‌بازشروع، بذرِ محلی، اتصالِ واقعیِ مولد، ورودی‌های نامعتبر، پاسخِ قرعهٔ نامعتبر و بازنام‌گذاریِ مقادیر را بررسی می‌کنند. تعدادِ حالت‌های داخلِ هر خانواده، آزمون یا مقالهٔ تازه شمرده نشده است.

{
  "python": "3.14.5",
  "implementation": "CPython",
  "units": {
    "readings": "mV",
    "positions_counts_probabilities": "dimensionless"
  },
  "profile": {
    "max_rows": 6,
    "k_range": [
      0,
      3
    ],
    "reading_range_mV": [
      -1000,
      1000
    ],
    "separate_prevalidation_scan": true,
    "selection_core_one_pass": true,
    "zero_k_consumes_source_without_draws": true
  },
  "literal_replacement_slots": [
    [
      2,
      30
    ],
    [
      1,
      20
    ]
  ],
  "main_ideal_example": {
    "n": 6,
    "k": 2,
    "equiprobable_histories": 360,
    "unordered_subsets": 15,
    "histories_per_subset": [
      24
    ],
    "probability_of_each_subset": "1/15",
    "law_scope": "Independent ideal uniform integer draws, NOT seed frequencies."
  },
  "duplicate_value_positions": {
    "1,2": 1,
    "0,2": 1,
    "0,1": 1
  },
  "biased_constant_bound_counts": {
    "0": 1,
    "1": 1,
    "2": 2
  },
  "nonuniform_ordered_slot_outcomes_n3_k2": [
    [
      2,
      1
    ],
    [
      0,
      2
    ],
    [
      0,
      1
    ]
  ],
  "actual_seeded_demo": {
    "readings_mV": [
      120,
      120,
      140,
      100,
      160,
      120
    ],
    "seed": 20261019,
    "slot_order": [
      [
        4,
        160
      ],
      [
        5,
        120
      ]
    ],
    "canonical_positions": [
      4,
      5
    ],
    "execution_not_uniformity_proof": true
  },
  "cases_within_groups": {
    "ideal_profiles": 28,
    "actual_seeded_results": 140,
    "public_rejections": 29,
    "draw_rejections": 9,
    "relabelings": 6
  },
  "checks": {
    "literal_replace_discard_and_slot_boundary": true,
    "all_28_ideal_history_laws_match_independent_combinations": true,
    "constant_draw_range_counterexample_is_biased": true,
    "equal_values_remain_distinct_occurrences": true,
    "uniform_subset_does_not_mean_uniform_slot_permutation": true,
    "zero_capacity_consumes_source_without_draws": true,
    "empty_and_capacity_covering_input_keep_all_without_draws": true,
    "selection_never_restarts_indexes_or_counts_source_length": true,
    "fixed_seed_local_instance_repeat_preserves_global_rng_state": true,
    "actual_random_integration_140_results_obey_feasible_subset_contract": true,
    "public_exact_type_value_and_size_boundaries": true,
    "internal_draw_response_exact_type_and_half_open_range": true,
    "six_value_relabellings_preserve_unordered_selection_law": true
  }
}

۵. چهار پرسش دربارهٔ ترتیب، بذر و دامنه

ترتیبِ خانه‌های مخزن با خودِ زیرمجموعه یکی نیست
تصویر مفهومی: ترتیبِ خانه‌های مخزن با خودِ زیرمجموعه یکی نیست؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

پرسش اول: اگر سه قرائت همگی ۷ باشند، انتخاب دو رخداد چند حالت دارد؟ پاسخ: سه زیرمجموعهٔ موقعیتیِ ۰ و ۱، ۰ و ۲، و ۱ و ۲ داریم. مقادیرِ خروجی در همهٔ آن‌ها ۷ و ۷ است. ادغامِ این رخدادها بر اساس مقدار، فضایِ انتخاب را عوض می‌کند؛ یکسان‌بودنِ مقادیرِ نمایش‌داده‌شده نشانهٔ خطای یکنواختی نیست.

پرسش دوم: ظرفیتِ صفر و ظرفیتِ سه برای ورودیِ دوتایی چه می‌کنند؟ پاسخ: اولی ورودی را کامل مصرف و خروجی را خالی می‌کند؛ دومی هر دو رخداد را در ترتیبِ ورود نگه می‌دارد. در هیچ‌کدام قرعه لازم نیست. ظرفیتِ چهار حتی برای ورودی کوتاه در قراردادِ عمومیِ ما رد می‌شود، چون سقفِ آموزشی سه است.

پرسش سوم: چرا برای ظرفیتِ یک نمی‌توان همیشه از دو عدد قرعه گرفت؟ پاسخ: با سه رخداد و دو تصمیمِ دودویی، چهار تاریخچه داریم. رخدادهای صفر، یک و دو به‌ترتیب یک، یک و دو بار برنده می‌شوند؛ احتمال‌ها یک‌چهارم، یک‌چهارم و یک‌دوم است. الگوریتمِ درست دامنهٔ تصمیم دوم را سه‌تایی می‌کند تا این سوگیری از بین برود.

پرسش چهارم: آیا مرتب‌کردنِ خروجی یا ثبتِ بذر، نمونه را نمایندهٔ رفتارِ واقعی می‌کند؟ پاسخ: خیر؛ مرتب‌سازی فقط نمایشِ مجموعه را معیار می‌کند و بذر فقط به بازتولیدِ اجرای ثبت‌شده کمک می‌کند. نه ترتیبِ مخزن الزاماً یک جایگشتِ یکنواخت است و نه نمونهٔ کوچک تضمینِ پوششِ رخدادِ نادر می‌دهد. مولدِ random برای رمزنگاری مناسب نیست؛ این درس نیز دربارهٔ احراز هویت، سنجشِ عملکرد یا تصمیمِ ایمنی نیست.

منابع و مطالعهٔ بیشتر

بررسی منابع: ۲۷ مهر ۱۴۰۵. تحلیل‌ها و پیشنهادهای اجرایی، جمع‌بندی نویسنده‌اند.