BitContradiction and DETAILED_LOG fixes

This commit is contained in:
mlemanczyk committed 2026-01-18 16:10:17 +01:00
1 parent 1a97cdf754
commit 778a36d2eb
3 files changed
+35 -23

No files matched your search

@@ -96,6 +96,19 @@ internal static class BitContradictionSolverWithAMultiplier
[ThreadStatic] [ThreadStatic]
private static TopDownPruneFailure? _lastTopDownFailure; private static TopDownPruneFailure? _lastTopDownFailure;
internal static TopDownPruneFailure? LastTopDownFailure => _lastTopDownFailure; internal static TopDownPruneFailure? LastTopDownFailure => _lastTopDownFailure;
private static void PrintStats()
{
Console.WriteLine(
$"[STATS] stableCalls={_statStableAdvanceCalls} stableCols={_statStableAdvanceColsBatched} " +
$"scalarCols={_statScalarCols} bigShift={_statStableAdvanceBigShift} " +
$"deltaReq={_statDeltaRequests} deltaHits={_statDeltaHits} deltaBuilds={_statDeltaBuilds}");
Console.WriteLine(
$"[CLEAN] checks={_statCleanChecks} false={_statCleanFalse} " +
$"firstDirtyCol={_statFirstDirtyColumn} word={_statFirstDirtyWord} " +
$"qWord=0x{_statFirstDirtyQ:X16} knownWord=0x{_statFirstDirtyKnown:X16}");
}
#else #else
[ThreadStatic] [ThreadStatic]
private static Dictionary<TopDownCacheKey, bool>? _topDownCache; private static Dictionary<TopDownCacheKey, bool>? _topDownCache;
@@ -1388,7 +1401,7 @@ internal static class BitContradictionSolverWithAMultiplier
#if DETAILED_LOG #if DETAILED_LOG
reason = ContradictionReason.ParityUnreachable; reason = ContradictionReason.ParityUnreachable;
#endif #endif
return false; return true;
} }
// Compute inv = q^{-1} mod 2^1024 using Hensel/Newton iteration in Z/2^kZ. // Compute inv = q^{-1} mod 2^1024 using Hensel/Newton iteration in Z/2^kZ.
@@ -1423,7 +1436,7 @@ internal static class BitContradictionSolverWithAMultiplier
Console.WriteLine("Pruned by knownZero1[word] & mask64"); Console.WriteLine("Pruned by knownZero1[word] & mask64");
reason = ContradictionReason.ParityUnreachable; reason = ContradictionReason.ParityUnreachable;
#endif #endif
return false; return true;
} }
knownOne0[word] |= mask64; knownOne0[word] |= mask64;
@@ -1437,7 +1450,7 @@ internal static class BitContradictionSolverWithAMultiplier
Console.WriteLine("Pruned by knownOne1[word] & mask64"); Console.WriteLine("Pruned by knownOne1[word] & mask64");
reason = ContradictionReason.ParityUnreachable; reason = ContradictionReason.ParityUnreachable;
#endif #endif
return false; return true;
} }
knownZero0[word] |= mask64; knownZero0[word] |= mask64;
@@ -1539,7 +1552,7 @@ internal static class BitContradictionSolverWithAMultiplier
Console.WriteLine("Pruned with TryHighBitTopCarryPrefilter"); Console.WriteLine("Pruned with TryHighBitTopCarryPrefilter");
reason = ContradictionReason.ParityUnreachable; reason = ContradictionReason.ParityUnreachable;
#endif #endif
return false; return true;
} }
// var cacheKey = new TopDownCacheKey(qHash, qOneOffsetsLength, maxAllowedA, pLong); // var cacheKey = new TopDownCacheKey(qHash, qOneOffsetsLength, maxAllowedA, pLong);
@@ -1591,7 +1604,7 @@ internal static class BitContradictionSolverWithAMultiplier
#if DETAILED_LOG #if DETAILED_LOG
reason = ContradictionReason.ParityUnreachable; reason = ContradictionReason.ParityUnreachable;
#endif #endif
return false; return true;
} }
} }
@@ -1728,7 +1741,7 @@ internal static class BitContradictionSolverWithAMultiplier
PrintStats(); PrintStats();
#endif #endif
return false; return true;
} }
lowColumn += blockSize; lowColumn += blockSize;
@@ -1985,7 +1998,7 @@ internal static class BitContradictionSolverWithAMultiplier
int remaining = columnCount; int remaining = columnCount;
int[] delta = GetStableUnknownDelta(unknown); int[] delta = GetStableUnknownDelta(unknown);
const int CarryDecimalMask = (1 << ColumnsAtOnce) - 1; const long CarryDecimalMask = (1L << ColumnsAtOnce) - 1L;
while (remaining >= ColumnsAtOnce) while (remaining >= ColumnsAtOnce)
{ {
int low = (int)(carryMax & CarryDecimalMask); int low = (int)(carryMax & CarryDecimalMask);
@@ -2968,8 +2981,8 @@ internal static class BitContradictionSolverWithAMultiplier
private static bool TryProcessTopDownBlock( private static bool TryProcessTopDownBlock(
ReadOnlySpan<int> qOneOffsets, ReadOnlySpan<int> qOneOffsets,
int qOneOffsetsLength, int qOneOffsetsLength,
long maxAllowedA, int maxAllowedA,
long startHighColumn, int startHighColumn,
int columnCount, int columnCount,
CarryRange carryOut, CarryRange carryOut,
ref int windowStart, ref int windowStart,
@@ -3256,8 +3269,8 @@ internal static class BitContradictionSolverWithAMultiplier
private static bool TryTopDownBorrowPrefilter( private static bool TryTopDownBorrowPrefilter(
ReadOnlySpan<int> qOneOffsets, ReadOnlySpan<int> qOneOffsets,
int qOneOffsetsLength, int qOneOffsetsLength,
long pLong, int pLong,
long maxAllowedA, int maxAllowedA,
out TopDownPruneFailure? failure) out TopDownPruneFailure? failure)
#else #else
private static bool TryTopDownBorrowPrefilter( private static bool TryTopDownBorrowPrefilter(
@@ -39,11 +39,11 @@ internal static class BitContradictionSolverWithQMultiplier
private const int TopDownCacheCapacity = 16; private const int TopDownCacheCapacity = 16;
#if DETAILED_LOG #if DETAILED_LOG
public readonly struct TopDownPruneFailure(int column, int carryMin, int carryMax, int unknown) public readonly struct TopDownPruneFailure(int column, long carryMin, long carryMax, int unknown)
{ {
public readonly int Column = column; public readonly int Column = column;
public readonly int CarryMin = carryMin; public readonly long CarryMin = carryMin;
public readonly int CarryMax = carryMax; public readonly long CarryMax = carryMax;
public readonly int Unknown = unknown; public readonly int Unknown = unknown;
} }
@@ -53,11 +53,11 @@ internal static class BitContradictionSolverWithQMultiplier
public readonly TopDownPruneFailure? Failure = failure; public readonly TopDownPruneFailure? Failure = failure;
} }
internal readonly struct BottomUpFailure(int column, int carryMin, int carryMax, int forced, int unknown) internal readonly struct BottomUpFailure(int column, long carryMin, long carryMax, int forced, int unknown)
{ {
public readonly int Column = column; public readonly int Column = column;
public readonly int CarryMin = carryMin; public readonly long CarryMin = carryMin;
public readonly int CarryMax = carryMax; public readonly long CarryMax = carryMax;
public readonly int Forced = forced; public readonly int Forced = forced;
public readonly int Unknown = unknown; public readonly int Unknown = unknown;
} }
@@ -647,8 +647,8 @@ internal static class BitContradictionSolverWithQMultiplier
private static bool TryProcessTopDownBlock( private static bool TryProcessTopDownBlock(
ReadOnlySpan<int> qOneOffsets, ReadOnlySpan<int> qOneOffsets,
int qOneOffsetsLength, int qOneOffsetsLength,
long maxAllowedA, int maxAllowedA,
long startHighColumn, int startHighColumn,
int columnCount, int columnCount,
CarryRange carryOut, CarryRange carryOut,
ref int windowStart, ref int windowStart,
@@ -795,8 +795,8 @@ internal static class BitContradictionSolverWithQMultiplier
private static bool TryTopDownCarryPrune( private static bool TryTopDownCarryPrune(
ReadOnlySpan<int> qOneOffsets, ReadOnlySpan<int> qOneOffsets,
int qOneOffsetsLength, int qOneOffsetsLength,
long pLong, int pLong,
long maxAllowedA, int maxAllowedA,
out TopDownPruneFailure? failure) out TopDownPruneFailure? failure)
#else #else
private static bool TryTopDownCarryPrune( private static bool TryTopDownCarryPrune(
@@ -4799,7 +4799,6 @@ public struct MersenneNumberDivisorByDivisorCpuTesterWithTemplate() : IMersenneN
#endif #endif
// BitContradictionSolverWithQMultiplier.SetDebugEnabled(false); // BitContradictionSolverWithQMultiplier.SetDebugEnabled(false);
// bool decided = BitContradictionSolverBaseline.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, exponent, out divides, out var reason); // bool decided = BitContradictionSolverBaseline.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, exponent, out divides, out var reason);
ArgumentOutOfRangeException.ThrowIfNotEqual(decided, divides);
if (decided && divides) if (decided && divides)
{ {
// Verify to avoid false positives on structurally admissible but non-dividing q. // Verify to avoid false positives on structurally admissible but non-dividing q.
@@ -4838,7 +4837,7 @@ public struct MersenneNumberDivisorByDivisorCpuTesterWithTemplate() : IMersenneN
} }
#if DETAILED_LOG #if DETAILED_LOG
Console.WriteLine($"[bitcontradiction ({sw.Elapsed})] Prime={prime}, Divisor={divisor} Decided={decided} Divides={divides} Reason={reason}"); Console.WriteLine($"[bitcontradiction] Prime={prime}, Divisor={divisor} Decided={decided} Divides={divides} Reason={reason}");
#endif #endif
return decided; return decided;
} }