You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Idris中congruentialMethod函数优化:免传证明与非零Nat验证

Solutions for Your Idris Congruential Method Woes

Let's walk through how to fix those annoying proof and performance issues step by step:

1. Stop Passing Proofs to congruentialMethod

The key here is to encapsulate your fixed modulus m and its non-zero proof inside the function, so callers never have to deal with them. Here's a clean implementation:

congruentialMethod : Nat -> Nat
congruentialMethod x = modNatNZ (a * x + c) m mNonZero
  where
    -- Your LCG parameters
    a : Nat
    a = 16807
    c : Nat
    c = 0
    m : Nat
    m = 2147483647

    -- Proof that m is non-zero, hidden internally
    mNonZero : NonZero m
    mNonZero = IsSucc (rewrite plusCommutative 2147483646 1 in Refl)

Now your function signature stays clean—no proof parameters required. The proof is only used behind the scenes.

2. Simplify the Non-Zero Proof for m

That rewrite trick works, but there are even cleaner options since m is a known positive constant:

Option A: Use believe_me (Safe for Fixed Values)

Since we know 2147483647 is a positive natural number, we can safely use believe_me to skip tedious proof construction. This is totally acceptable here because the value is fixed and can't be negative:

mNonZero : NonZero m
mNonZero = believe_me IsSucc

If you prefer a slightly more formal approach without the rewrite, define a global hint so Idris can automatically find the proof when needed:

%hint
mNonZero : NonZero 2147483647
mNonZero = IsSucc (rewrite plusCommutative 2147483646 1 in Refl)

-- Then reference the hint with %search in your function
congruentialMethod : Nat -> Nat
congruentialMethod x = modNatNZ (a * x + c) 2147483647 %search
  where
    a = 16807
    c = 0

3. Fix Nat's Slow Performance Without partial

Nat's arbitrary-precision design makes it slow for numerical computations. Instead, use Integer (unbounded) or Int (fixed-size) with assert_total to keep your function total while boosting speed:

congruentialMethod : Int -> Int
congruentialMethod x = assert_total $ (a * x + c) `mod` m
  where
    a = 16807
    c = 0
    m = 2147483647

assert_total tells Idris you guarantee this function will terminate and avoid undefined behavior (which is true here because m is non-zero, and your LCG operations are well-behaved for valid inputs). This lets you ditch partial entirely while keeping performance snappy.


内容的提问来源于stack exchange,提问作者user483036

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:29